Public Access
Merge branch 'claude/groups-vault-sharing-e4b154'
# Conflicts: # src/DodoSSH.Client.Shell/ViewModels/VaultViewModel.cs
This commit is contained in:
@@ -307,7 +307,7 @@ caption buttons and window title drawn on top of the application's own — two s
|
||||
| Tag chips (`nginx`, `eu`, `pg16`) | client-domain | A tag item type, and a way to put one on a host. | **Shipped.** `Tag = 5` is a live item kind and `HostSecret.TagIds` names them, merged per tag so two people tagging one host both keep theirs — which is what `HostTag = 6` was going to buy, so it stays reserved and unused. Chips are drawn on host rows on both heads and toggled in the host editor, which also creates one inline; renaming and deleting are a TAGS category on the keychain screen. The filter box still searches name, address and notes only — a chip is read rather than typed. |
|
||||
| Groups `PRODUCTION` / `STAGING` / `PERSONAL` | client-domain | A host-group item type (`HostGroup = 4`, reserved) or a group field on `HostSecret`. | **Shipped**, as both: `VaultHostGroup` is a synced item kind and `HostSecret.GroupId` names one. A group carries a `ParentId` and the defaults its hosts inherit, and the two heads draw the nesting differently on purpose. The desktop is a grid of cards holding one level at a time, the way a directory pane holds one directory; the phone has no room for a row of cards, so it flattens the whole tree into one heading per group in label order with no indentation. A keychain with no groups renders exactly as it did before on both — one flat list, no headings and no cards. |
|
||||
| Group badge `TEAM·PLATFORM` | server | **Built in M3.** | The vault's name on each row, and the personal vault ordered first. Not the team's name: two of a team's vaults would then carry the same badge and the badge would be naming the wrong thing. Distinct from the groups above, and deliberately so — a group is a shelf the user chose, a vault is who can read the item. |
|
||||
| Groups on a **team's** hosts | client-domain | A vault id on each group row for rename and delete, and a way to tell two vaults' identically-named groups apart in a list with one heading per group. | **Half shipped, and the half that shipped had to.** Every readable vault's groups are now read into the resolution map, because a group lends a port, a username and a binding — so a host whose group went unread would silently dial 22 as nobody while the machine is on 2222 as `deploy`. A missing heading is cosmetic; a missing port is a connection to the wrong place. The editable list is still the active vault's alone, so a group a teammate made has no card and no heading and cannot be renamed from here. A host filed into one is drawn at the outermost level of the desktop's grid and under UNGROUPED on the phone — reachable either way, which is the point — with the chip on its card still naming the group, because the label is resolved through the wide map while the level is decided from the narrow list. |
|
||||
| Groups on a **team's** hosts | client-domain | A vault id on each group row for rename and delete, and a way to tell two vaults' identically-named groups apart in a list with one heading per group. | **Shipped, and it is what makes a shared vault an arrangement rather than a heap.** Both halves are paid for: the row carries the vault it came out of, so rename and delete go back to it, and the vault's name is drawn beside the group's on the desktop's cards and the phone's headings wherever the session holds more than one — which is what lets two `production` groups sit side by side. The group editor asks which vault a new group goes into, on the terms the host editor's picker set: while adding only, hidden at one writable vault, and never offered afterwards, because the two are encrypted under different keys. The parent picker is that vault's alone, for the reason the host editor's group picker is — a parent in another vault is a level half the key holders cannot resolve. Dragging a host card onto a group card in another vault is refused with the reason, rather than filing it under an id nobody in its own vault can read. The resolution map stays wider than the list and still spans hidden vaults: a group lends a port, a username and a binding, so a host whose group went unread would silently dial 22 as nobody while the machine is on 2222 as `deploy`. |
|
||||
| Per-host status dot, three colours | client-ssh | The amber state would mean "reachable but not connected", and nothing here ever probes a host. | Two states, both real: green when a terminal is open on that host, grey when not. |
|
||||
| `· ⤷ bastion-eu` in the host subtitle | client-ssh | **Jump hosts are data-only.** `HostSecret.JumpHostIds` is a `JumpChain` that is stored, encrypted, synced and three-way merged — and nothing reads it at connect time. `SshConnectionRequest` carries one host. | Omitted. The stored chain is preserved untouched by every edit. |
|
||||
| `SPLIT ⌘D` and side-by-side panes | client-ssh + ui | The renderer stacks panes and shows one (`terminal.css`: `.pane { position:absolute; inset:0; display:none }`). Tiling needs a real pane geometry and a splitter. | Omitted. Tabs ship instead, over the same one-WebView multiplexing. |
|
||||
|
||||
Reference in New Issue
Block a user