fix: CLI sessions that end, and items that reach lists #143

Merged
nalum merged 2 commits from fix/cli-defects into main 2026-08-18 16:43:16 +00:00
Owner

Closes #114, #118, #119. PR 5 of the #137 stack, based on #142. Two commits, one per concern.

#114 — a logout that ends the session, plus session commands

The CLI could mint sessions it could never end. login now opts into a device chain (remember_device with a cli:<hostname> label) and stores the refresh token beside the access token; logout presents it to UserService/Logout, revoking the chain — which orphans the sid-bound access token instantly (ADR-0033). An install carrying only an old chainless token still logs out locally, with a note that the server side expires on its own. New session list (one row per chain, current chain marked — the web sessions card's view) and session revoke <chain-uid>. New pkg/client wrappers: LoginDevice, Logout, ListSessions, RevokeSession.

#118 + #119 — item fixes

item update --complete/--incomplete no longer sends an empty audited Update before CompleteItem — a pure flip is now one mutation in the trail, and a flagless item update errors instead of round-tripping a no-op. item create gains --list, and the new item set-list <uid> [list-uid] moves an item onto a list or (with no list uid) back out as a standalone job — the web's convert door, and the SetList client wrapper's first caller.

Live-verified against the deployed cluster: login stores both tokens (0600), session list renders the chain table with the CLI chain marked current, session revoke kills another chain, item create --list / set-list round-trip, a completion flip leaves exactly one audited UPDATE, and after logout the old access token gets 401 on its next request. Verify data cleaned up.

🤖 Generated with Claude Code

Closes #114, #118, #119. PR 5 of the #137 stack, based on #142. Two commits, one per concern. **#114 — a logout that ends the session, plus session commands** The CLI could mint sessions it could never end. `login` now opts into a device chain (`remember_device` with a `cli:<hostname>` label) and stores the refresh token beside the access token; `logout` presents it to `UserService/Logout`, revoking the chain — which orphans the sid-bound access token instantly (ADR-0033). An install carrying only an old chainless token still logs out locally, with a note that the server side expires on its own. New `session list` (one row per chain, current chain marked — the web sessions card's view) and `session revoke <chain-uid>`. New `pkg/client` wrappers: `LoginDevice`, `Logout`, `ListSessions`, `RevokeSession`. **#118 + #119 — item fixes** `item update --complete`/`--incomplete` no longer sends an empty audited `Update` before `CompleteItem` — a pure flip is now one mutation in the trail, and a flagless `item update` errors instead of round-tripping a no-op. `item create` gains `--list`, and the new `item set-list <uid> [list-uid]` moves an item onto a list or (with no list uid) back out as a standalone job — the web's convert door, and the `SetList` client wrapper's first caller. Live-verified against the deployed cluster: login stores both tokens (0600), `session list` renders the chain table with the CLI chain marked current, `session revoke` kills another chain, `item create --list` / `set-list` round-trip, a completion flip leaves exactly one audited UPDATE, and after `logout` the old access token gets 401 on its next request. Verify data cleaned up. 🤖 Generated with [Claude Code](https://claude.com/claude-code)
The CLI could mint sessions it could never end (#114): logout deleted
the local token file and nothing else, and no session verbs existed.
Login now opts into a device chain (remember_device with a cli:<host>
label) and stores the refresh token beside the access token, so logout
can present it to UserService/Logout — revoking the chain orphans the
sid-bound access token instantly (ADR-0033). An install carrying only
the old chainless token still logs out locally with a note that the
server side expires on its own. session list / session revoke complete
the maintenance tier: the same honest list the web sessions card shows,
current chain marked, and revocation by chain uid.
fix(cli): list membership for items, no empty audited updates
Some checks failed
check / commits (pull_request) Successful in 6s
check / web (pull_request) Successful in 1m31s
check / go (pull_request) Successful in 2m28s
check / report (pull_request) Successful in 2s
check / commits (push) Has been cancelled
check / go (push) Has been cancelled
check / report (push) Has been cancelled
check / web (push) Has been cancelled
tag / tag (push) Has been cancelled
f53b101082
Two parity defects under cmd/ (#118, #119). item update sent an empty
audited Update before every completion flip — a wasted no-op mutation
in the trail; the Update call now runs only when an editable field flag
is set. And the CLI had no path to list membership at all: item create
gains --list, and item set-list moves an item onto a list or (with no
list uid) back out as a standalone job — the web's convert door, the
SetList wrapper's first caller.

Test report

Suite Tests Result Skipped
Unit 1370 ✅ pass 1
Integration 86 ✅ pass —

Coverage: 28.0%

Updated by the check workflow · commit f53b101082

<!-- ci-test-report --> ## Test report | Suite | Tests | Result | Skipped | | --- | --: | --- | --: | | Unit | 1370 | ✅ pass | 1 | | Integration | 86 | ✅ pass | — | **Coverage:** 28.0% <sub>Updated by the check workflow · commit f53b10108223fda7e6fed581602bda4431abe319</sub>
nalum changed target branch from fix/mcp-defects to main 2026-08-18 16:43:10 +00:00
nalum merged commit f53b101082 into main 2026-08-18 16:43:16 +00:00
nalum deleted branch fix/cli-defects 2026-08-18 16:43:16 +00:00
Sign in to join this conversation.
No reviewers
No milestone
No project
No assignees
2 participants
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
eagraiclainne/app!143
No description provided.