@scotthuang/agent-knock-knock 0.14.12 → 0.14.13

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (85) hide show
  1. package/CHANGELOG.md +7 -0
  2. package/dist/src/claude-native-cli-adapter.js +3 -10
  3. package/dist/src/claude-native-cli-adapter.js.map +1 -1
  4. package/dist/src/claude-native-state-store.js +1 -1
  5. package/dist/src/claude-native-state-store.js.map +1 -1
  6. package/dist/src/cli-core.js +21 -4
  7. package/dist/src/cli-core.js.map +1 -1
  8. package/dist/src/cli-usage.js +2 -1
  9. package/dist/src/cli-usage.js.map +1 -1
  10. package/dist/src/codex-native-cli-adapter.js +3 -11
  11. package/dist/src/codex-native-cli-adapter.js.map +1 -1
  12. package/dist/src/codex-native-record-store.d.ts +2 -0
  13. package/dist/src/codex-native-record-store.js +5 -0
  14. package/dist/src/codex-native-record-store.js.map +1 -1
  15. package/dist/src/codex-native-state-store.js +1 -1
  16. package/dist/src/codex-native-state-store.js.map +1 -1
  17. package/dist/src/conversation-list.d.ts +2 -0
  18. package/dist/src/conversation-list.js +19 -0
  19. package/dist/src/conversation-list.js.map +1 -1
  20. package/dist/src/desktop-list.d.ts +0 -2
  21. package/dist/src/desktop-list.js +3 -11
  22. package/dist/src/desktop-list.js.map +1 -1
  23. package/dist/src/desktop-state-store.js +4 -0
  24. package/dist/src/desktop-state-store.js.map +1 -1
  25. package/dist/src/host-monitor-reconciliation.js +20 -0
  26. package/dist/src/host-monitor-reconciliation.js.map +1 -1
  27. package/dist/src/live-lifecycle-smoke.js +56 -37
  28. package/dist/src/live-lifecycle-smoke.js.map +1 -1
  29. package/dist/src/managed-monitoring-list.d.ts +4 -0
  30. package/dist/src/managed-monitoring-list.js +17 -0
  31. package/dist/src/managed-monitoring-list.js.map +1 -0
  32. package/dist/src/semantic-tool-command-helpers.d.ts +4 -0
  33. package/dist/src/semantic-tool-command-helpers.js +28 -3
  34. package/dist/src/semantic-tool-command-helpers.js.map +1 -1
  35. package/dist/src/semantic-tool-descriptions.d.ts +1 -0
  36. package/dist/src/semantic-tool-descriptions.js +7 -5
  37. package/dist/src/semantic-tool-descriptions.js.map +1 -1
  38. package/dist/src/semantic-tool-list-budget.d.ts +2 -3
  39. package/dist/src/semantic-tool-list-budget.js +20 -93
  40. package/dist/src/semantic-tool-list-budget.js.map +1 -1
  41. package/dist/src/semantic-tool-list-projection.d.ts +1 -1
  42. package/dist/src/semantic-tool-list-projection.js +6 -90
  43. package/dist/src/semantic-tool-list-projection.js.map +1 -1
  44. package/dist/src/semantic-tool-runtime.js +27 -5
  45. package/dist/src/semantic-tool-runtime.js.map +1 -1
  46. package/dist/src/semantic-tool-schemas.d.ts +36 -0
  47. package/dist/src/semantic-tool-schemas.js +11 -1
  48. package/dist/src/semantic-tool-schemas.js.map +1 -1
  49. package/dist/src/store.d.ts +1 -1
  50. package/dist/src/store.js +4 -3
  51. package/dist/src/store.js.map +1 -1
  52. package/dist/src/terminal-action-contracts.js +1 -1
  53. package/dist/src/terminal-list-cli-adapter.d.ts +1 -0
  54. package/dist/src/terminal-list-cli-adapter.js +9 -34
  55. package/dist/src/terminal-list-cli-adapter.js.map +1 -1
  56. package/dist/src/terminal-permission-control-list-projection.d.ts +1 -1
  57. package/dist/src/terminal-watch-store.d.ts +1 -1
  58. package/dist/src/terminal-watch-store.js +6 -2
  59. package/dist/src/terminal-watch-store.js.map +1 -1
  60. package/dist/src/watch-history-maintenance-cli-adapter.d.ts +2 -0
  61. package/dist/src/watch-history-maintenance-cli-adapter.js +13 -0
  62. package/dist/src/watch-history-maintenance-cli-adapter.js.map +1 -0
  63. package/dist/src/watch-history-policy.d.ts +9 -0
  64. package/dist/src/watch-history-policy.js +64 -0
  65. package/dist/src/watch-history-policy.js.map +1 -0
  66. package/dist/src/watch-history-receipt.d.ts +27 -0
  67. package/dist/src/watch-history-receipt.js +71 -0
  68. package/dist/src/watch-history-receipt.js.map +1 -0
  69. package/dist/src/watch-history-retention.d.ts +16 -0
  70. package/dist/src/watch-history-retention.js +143 -0
  71. package/dist/src/watch-history-retention.js.map +1 -0
  72. package/dist/src/watch-list-cli-adapter.d.ts +6 -0
  73. package/dist/src/watch-list-cli-adapter.js +62 -0
  74. package/dist/src/watch-list-cli-adapter.js.map +1 -0
  75. package/dist/src/watch-list-projection.d.ts +18 -0
  76. package/dist/src/watch-list-projection.js +158 -0
  77. package/dist/src/watch-list-projection.js.map +1 -0
  78. package/docs/callback-compatibility.md +4 -2
  79. package/docs/list-output.md +65 -67
  80. package/docs/operator-guide.md +11 -8
  81. package/docs/storage-and-logging.md +8 -5
  82. package/docs/testing.md +2 -2
  83. package/openclaw.plugin.json +4 -0
  84. package/package.json +1 -1
  85. package/templates/openclaw-skills/agent-knock-knock/SKILL.md +11 -7
@@ -29,10 +29,12 @@ its equivalent `turn_id` for follow-up. A project path or title alone is never
29
29
  task identity. [Backend task recovery](backend-task-recovery.md) explains how
30
30
  to resume observation or release management for that exact task.
31
31
 
32
- Host List returns bounded pages with current conversations first. Follow
33
- `pagination.next_args` for the rest; use `listView: "history"` for ended
34
- observations. See [List output and history](list-output.md) for attention
35
- counts, compatibility and the separate Desktop catalog cursor.
32
+ Host List returns bounded pages of currently discoverable conversations. Follow
33
+ `pagination.next_args` for remaining conversations. Use `agent_knock_knock_watches`
34
+ or `/akk watches` for recent monitoring and unresolved callbacks; absence of Watch
35
+ fields in List does not mean Send had no monitoring. See
36
+ [List and Watch inventory](list-output.md) for the 24-hour query window,
37
+ 48-hour eligible-history retention and separate Desktop catalog cursor.
36
38
 
37
39
  ## Command reference
38
40
 
@@ -42,7 +44,8 @@ Direct slash commands are available in every first-party Host integration:
42
44
  | --- | --- |
43
45
  | `/akk <task>` | Send a task when AKK can prove one unique send-ready terminal. |
44
46
  | `/akk <selector>: <message>` | Send to the exact selector returned by the current list. |
45
- | `/akk list` | Discover conversations, managed work, Watches, and supported actions. |
47
+ | `/akk list` | Discover conversations and their supported actions. |
48
+ | `/akk watches` | Read recent monitoring and unresolved records; follow pagination for more. |
46
49
  | `/akk watch <terminal-id>` | Observe one exact terminal task. |
47
50
  | `/akk unwatch <watch-id>` | Stop observation of one terminal or backend Watch without stopping its native task. |
48
51
  | `/akk threads <terminal-id>` | List resumable native threads for one terminal. |
@@ -78,9 +81,9 @@ The terminal-specific commands in the table require a physical terminal;
78
81
  Desktop interaction, model, permission, and cancellation controls use their
79
82
  advertised semantic tools. Backend and terminal capabilities are distinct.
80
83
  Raw CLI output retains provider arrays, including `terminals[]`, for diagnostics.
81
- Within a terminal row, the optional `managed.current_turn` is active work; `managed.recent_turn` is
82
- retained history and does not occupy the terminal. Attention-needed records
83
- whose pane is unavailable appear in `unavailable_managed_turns[]`.
84
+ Within a terminal row, `managed.current_turn` is current managed work. Retained
85
+ managed Turn history, including records whose pane is unavailable, is queried
86
+ separately through `watches` and exact Status.
84
87
 
85
88
  Terminal status has three independent evidence axes. `screen_state` describes
86
89
  the bounded live TUI (`idle`, `working`, `awaiting_approval`, or `unknown`);
@@ -21,17 +21,17 @@ remain private.
21
21
  ## Compatibility manifest
22
22
 
23
23
  The manifest checks storage format and writer behavior separately. An unknown
24
- `format_version` is not read. The current writer protocol is 9; writer
25
- protocols 1 through 8 are supported predecessors and inspection reports them
24
+ `format_version` is not read. The current writer protocol is 10; writer
25
+ protocols 1 through 9 are supported predecessors and inspection reports them
26
26
  as `upgradeable`.
27
27
 
28
28
  Upgrading protocol 1 or 2 validates predecessor Turn records,
29
29
  deterministically derives and durably materializes authoritative Session
30
30
  records, quarantines ambiguous Session bindings, and finishes by atomically
31
- publishing protocol 9. Existing Turn state, event logs, and the original
31
+ publishing protocol 10. Existing Turn state, event logs, and the original
32
32
  manifest `created_at` remain unchanged.
33
33
 
34
- Protocols 3 through 8 already have Session authority, so their upgrade is an
34
+ Protocols 3 through 9 already have Session authority, so their upgrade is an
35
35
  atomic manifest-only writer fence with no data migration. Protocol 6 prevents
36
36
  older writers from rejecting or damaging schema-v2 Terminal Watch records.
37
37
  Protocol 7 fences the `interaction_manual_required` notification kind from
@@ -41,7 +41,10 @@ policy, subject-aware projection, one-shot reservation, and callback-outbox
41
41
  state; its version fence makes older strict Watch decoders reject the record
42
42
  instead of rewriting unknown authority. Legacy schema-v1/v2 Watches are
43
43
  normalized to `notify_only`; they never silently acquire terminal response
44
- authority. Downgrading after v3 records exist is not supported. Core
44
+ authority. Downgrading after v3 records exist is not supported. Protocol 10 additionally requires deletion receipts before pruning completed Watch
45
+ bodies, preventing older writers from recreating an expired Send. Do not manually
46
+ lower the manifest for rollback: restore a coherent pre-upgrade backup instead.
47
+ Core
45
48
  Session/Turn data remains readable across a writer-protocol mismatch, while
46
49
  explicit reconciliation reports `skipped` and managed mutations fail before
47
50
  terminal or Host side effects. This does not prohibit an independently
package/docs/testing.md CHANGED
@@ -233,8 +233,8 @@ replays terminal input while resolving that identity.
233
233
  The semantic
234
234
  `native_thread_id` remains public for resume. The plugin/CLI still derives and
235
235
  revalidates those private fences under lock. Store format remains 1 and the
236
- Terminal Watch schema is 3; writer protocol 9 fences capability-checked paginated task
237
- bindings and private native-question checkpoints from older writers. It retains
236
+ Terminal Watch schema is 3; writer protocol 10 fences capability-checked paginated task
237
+ bindings, private native-question checkpoints and Watch deletion receipts from older writers. It retains
238
238
  the manual-interaction notification state and bounded callback metadata introduced
239
239
  in writer protocol 7. The Watch schema version fences the response aggregate.
240
240
 
@@ -16,6 +16,7 @@
16
16
  "contracts": {
17
17
  "tools": [
18
18
  "agent_knock_knock_list",
19
+ "agent_knock_knock_watches",
19
20
  "agent_knock_knock_watch",
20
21
  "agent_knock_knock_unwatch",
21
22
  "agent_knock_knock_list_resumable_threads",
@@ -47,6 +48,9 @@
47
48
  "agent_knock_knock_list": {
48
49
  "optional": true
49
50
  },
51
+ "agent_knock_knock_watches": {
52
+ "optional": true
53
+ },
50
54
  "agent_knock_knock_watch": {
51
55
  "optional": true
52
56
  },
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@scotthuang/agent-knock-knock",
3
- "version": "0.14.12",
3
+ "version": "0.14.13",
4
4
  "description": "Delegate to existing Codex CLI, Codex Desktop, and Claude Code sessions from OpenClaw or compatible controller Hosts, with native direct control and supported terminal fallbacks.",
5
5
  "license": "MIT",
6
6
  "type": "module",
@@ -158,7 +158,7 @@ For ordinary send or an in-flight answer:
158
158
 
159
159
  1. Reuse an AKK session only when the user's reference uniquely identifies its verified native session and terminal incarnation.
160
160
  2. If no ID is supplied and more than one eligible pane may exist, call `agent_knock_knock_list`.
161
- 3. Treat `conversations[]` as the primary resource list; older raw CLI output may expose `terminals[]` instead. For a terminal-backed row, its managed context exposes `session_id`; `managed.current_turn` is the only current AKK owner, while `managed.recent_turn` and `managed.history` are retained Turn history. Records in `unavailable_managed_turns[]` have no live pane in this snapshot.
161
+ 3. Treat `conversations[]` as the primary resource list; older raw CLI output may expose `terminals[]` instead. For a terminal-backed row, its managed context exposes `session_id`; `managed.current_turn` is the current AKK owner. Query `watches` for retained monitoring and managed Turn history, including unavailable-pane recovery.
162
162
  4. Read the selected resource's `available_actions`. In the compact Host projection its keys are the exact current action names and each value is `true`; `action_inputs`, when present, carries only dynamic semantic arguments, `missing_required`, and scope. For every mutation, use only an advertised action, start with those semantic inputs, supply every `missing_required` field, and follow this skill's action rules. User-selected Watch is the exception: explicit user intent plus one complete exact `terminal_id` is sufficient even when `available_actions.watch` is absent. The only additional mutation sources are a terminal row's `handoff_decision.choices.take_over_current.action` and an exact `blocking_turns[].recovery_action`: use either only after explicit user confirmation and refresh the list immediately afterward.
163
163
  5. If an existing managed Session advertises send with `session_id`, call `agent_knock_knock_send({session_id,request})`; it creates a new Turn strictly in that Session's native context and may require exact empty before input. For an ordinary selected conversation, call `agent_knock_knock_send({conversation_id,request})`; terminal-scoped rows also accept legacy `terminal_id`. The following physical-input rules apply only if AKK selects terminal delivery. `terminal_follow_current` may adopt a safe human-driven handoff or send once within an exact, complete Codex rollout-candidate inventory before binding the uniquely accepting native thread. `terminal_user_explicit` instead preserves the user's Send when internal AKK state is broken: Codex replaces the current Composer with `C-u`; Claude Code uses a sentinel-backed native `C-s` stash-clear transaction that is independent of the cursor position and does not interrupt an active turn, then proves the main Composer empty. Each injects the new request and submits exactly once without a post-text Composer veto. For source-less Codex sends, zero exact acceptors remains pending for monitor recovery, one promotes the provisional Session/Turn, and multiple acceptors or identity drift becomes uncertain without replay. Managed delivery is attempted where eligible, but a proven zero-input failure falls back to one unmanaged delivery with no managed callback Turn. AKK prepares the strongest safe Watch before dispatch and best-effort attaches it after Enter; Watch persistence failure never changes the successful Send. Once clear or request input may have occurred, an uncertain result must not be retried automatically. Wait for an attached Watch callback or use its status as recovery. The status-card-only first-task path remains the zero-rollout special case. `send({turn_id})` is never an ordinary target: use it only for a fresh `retry_submission` action after explicit confirmation, with no other field. Never construct or pass an opaque fence or composer authority. Use `respond` with its `turn_id` only when that Turn is explicitly `waiting_for_openclaw`; the answer stays in the same Turn. Do not add timeout fields for ordinary use; `timeoutSeconds` is unsupported.
164
164
  6. If multiple terminals match, show their `short_ref`, agent, provider, and terminal target, then ask the user to choose. If a human switch has an unresolved Turn, ambiguous ownership, or unverifiable identity and no follow-current send is advertised, report that blocker and ask the user which context to resolve; never guess, supersede active work, or bypass the fence.
@@ -183,7 +183,7 @@ Hard creation failure includes an absent exact terminal, inability to identify i
183
183
 
184
184
  Approval attention is notification-only for every Watch: never call an approval tool for a `watch_id`, send approval keys, or apply `autoApprove`. Native-interaction attention is different. An automatic exact request-bound Watch created by `terminal_user_explicit` unmanaged fallback can, after exact request acceptance and attribution, emit `interaction_required`; call Status with its exact `watch_id`, show the projected question to the user, and use `respond_interaction({watch_id,...})` only when that fresh owner-bound projection advertises `capabilities.respond=true`. A terminal-activity Watch or `interaction_manual_required` callback remains notify-only: tell the user to inspect and answer in the live TUI, and send no interaction input. Each new exact attention fingerprint is notified once while the Watch remains active. Terminal outcomes settle once. The durable outbox uses deterministic notification IDs/idempotency and leased retry, so startup and periodic supervision can safely recover callback delivery after AKK, OpenClaw, or Gateway restart.
185
185
 
186
- The current integrations register the complete capability-handshake-verified semantic AKK tool catalog and list action-contract v31. Structured OpenClaw, Pi, and DeepSeek Harness Lists use compact projection v3 and point here for the static contract; the CLI keeps the complete operator/debug action contract. Every structured model action carries semantic IDs only; opaque fences, Composer digests, and draft text are derived or retained privately. Watch uses `agent_knock_knock_watch({terminal_id})`, `agent_knock_knock_status({watch_id})`, and `agent_knock_knock_unwatch({watch_id})`; its internal CLI boundary is `watch-terminal`, `watch-status`, `unwatch-terminal`, and `reconcile-watches`.
186
+ The current integrations register the complete capability-handshake-verified semantic AKK tool catalog and list action-contract v32. Structured OpenClaw, Pi, and DeepSeek Harness Lists use compact projection v4 and point here for the static contract; the CLI keeps the complete operator/debug action contract. Every structured model action carries semantic IDs only; opaque fences, Composer digests, and draft text are derived or retained privately. Watch uses `agent_knock_knock_watch({terminal_id})`, `agent_knock_knock_status({watch_id})`, and `agent_knock_knock_unwatch({watch_id})`; its internal CLI boundary is `watch-terminal`, `watch-status`, `unwatch-terminal`, and `reconcile-watches`.
187
187
 
188
188
  For Codex permission changes, first call `agent_knock_knock_permission_options({terminal_id})` from the current row’s advertised action. This sends closed `/status` and `/permissions` inspection input but leaves permissions unchanged; the terminal must be idle, its Composer empty, and its physical and native thread identities verifiable. Use `current`, `scope`, and the returned choice descriptions to select the requested or authorized mode. Then call `agent_knock_knock_set_permissions({terminal_id,mode})` using its exact returned semantic ID in the same controller conversation. Full Access is an ordinary option and needs no additional user confirmation. AKK automatically handles its exact native confirmation inside this permission transaction; do not pause to ask the user to confirm Full Access or call generic `approve` for that dialog. Ordinary Send does not change permissions. Codex 0.160 may report `current="workspace_granular"`; this is a current-only native default, not a selectable mode. Select only an ID actually returned in `choices`. Only currently displayed built-in modes are supported: do not invent `read_only` when the picker omits it, supply a named/custom profile, or pass commands, labels, menu indexes, keys, tokens, or scope overrides. Changes affect the current session/thread, may be retained on Resume, and leave global defaults unchanged. Send the intended task only after `outcome="changed"` or `"already_effective"` with matching `effective.mode`; `"uncertain"` means stop and do not retry automatically. Refresh the catalog after any change or consumed attempt.
189
189
 
@@ -292,15 +292,19 @@ A trusted, default-disabled plugin `autoApprove` policy may independently approv
292
292
 
293
293
  ## Terminal Sessions
294
294
 
295
- The model-facing `agent_knock_knock_list` presents `conversations[]` once. Exact matched Codex terminal/backend representations are coalesced. A unique nonconflicting project pair prefers its backend entry without claiming an exact alias; ambiguous or attention-needed terminal records and unconnected Desktop candidates stay visible. Raw CLI output retains the provider arrays for diagnostics. Terminal-backed rows still include retained managed context without duplicating the pane. The terminal resource chain is terminal → verified native session → managed AKK `session_id` → Turns; independent terminal observation records appear in `terminal_watches[]` and are addressed only by `watch_id`. `process_state` reports process liveness. Read `screen_state` as bounded live-TUI evidence, `native_identity_state` as foreground native-session resolution, and `durable_activity_state` as exact artifact-backed task activity. The legacy `activity_state` is a conservative compatibility projection and may remain `unknown` while `screen_state="idle"`; none of these diagnostic fields replaces `available_actions` authority. `managed.current_turn` is the authoritative active Turn for that terminal; otherwise `managed.recent_turn` shows the newest retained context. A human-driven thread mismatch remains `management_state="conflict"`; `handoff_state="external_handoff_adoptable"` authorizes only the exact fenced `send` advertised on that row, while `external_handoff_blocked` means do not send or guess a recovery. Listing itself never adopts the new context. Request `all=true` only when older `managed.history`, settled Watches, or retained unavailable history is needed; Host results remain paginated, not an unlimited dump. By default, `unavailable_managed_turns[]` contains attention-needed records whose terminal is unavailable.
295
+ The model-facing `agent_knock_knock_list` presents `conversations[]` once. Exact matched Codex terminal/backend representations are coalesced. A unique nonconflicting project pair prefers its backend entry without claiming an exact alias; ambiguous or attention-needed terminal records and unconnected Desktop candidates stay visible. Raw CLI output retains provider arrays for diagnostics. The terminal resource chain is terminal → verified native session → managed AKK `session_id` → Turns. Independent observations are queried through `watches` and addressed by `watch_id`. `process_state` reports process liveness; `screen_state` is bounded TUI evidence, `native_identity_state` is foreground identity resolution, and `durable_activity_state` is exact artifact-backed activity. `activity_state` can remain unknown even if the screen looks idle; none replaces advertised action authority. `managed.current_turn` is the current Turn. Historical contexts are absent from List. A human-driven thread mismatch remains `management_state="conflict"`; `external_handoff_adoptable` authorizes only the exact fenced Send advertised on the row, while `external_handoff_blocked` means do not send or guess recovery. Listing never adopts a new context.
296
296
 
297
297
  ### Compact controller-Host List projection
298
298
 
299
- The structured OpenClaw, Pi, and DeepSeek Harness tools return `projection.schema="agent-knock-knock/host-list-compact"`, `projection.version=3`, `projection.skill="agent-knock-knock"`, and the CLI action-contract version. They deliberately omit the repeated 30KB static `action_contracts`, explanatory `reason`/`use` text, Store paths, terminal diagnostics, native evidence, callback envelopes, full historical requests, completion text, screens, and event/file paths. Use Status for one selected Turn or Watch and `/akk doctor` or the CLI for operator diagnostics. A bounded dynamic failure `message` or scan `error` may still appear because it cannot be documented statically.
299
+ The structured OpenClaw, Pi, and DeepSeek Harness tools return `projection.schema="agent-knock-knock/host-list-compact"`, `projection.version=4`, `projection.skill="agent-knock-knock"`, and the CLI action-contract version. They deliberately omit the repeated 30KB static `action_contracts`, explanatory `reason`/`use` text, Store paths, terminal diagnostics, native evidence, callback envelopes, full historical requests, completion text, screens, and event/file paths. Use Status for one selected Turn or Watch and `/akk doctor` or the CLI for operator diagnostics. A bounded dynamic failure `message` or scan `error` may still appear because it cannot be documented statically.
300
300
 
301
- **Bounded List pages:** default `listView="current"` puts conversations first, followed by active observations and unresolved attention (including failed/uncertain/pending callbacks and pending interactions). Healthy ended Watches are counted in `watch_summary`, not repeated inline. Older managed terminal Turns are paged separately in `managed_turns`; unresolved delivery remains in the current view and safe callback state stays visible. `callback_expected=false` does not by itself remove an unresolved callback, and omitted healthy history does not mean that Send had no Watch. Use `listView="history"` for healthy ended Watches or `listView="all"`/`all=true` for both. An explicit `listView` overrides the default selected by `all`.
301
+ **Conversation-only List:** List returns currently discoverable conversations, including Desktop sidebar entries with unconfirmed live owners. It never includes Watch inventories or retained managed history. Keep current ownership, blockers and advertised approvals; do not interpret missing Watch fields as missing Send monitoring. Use `agent_knock_knock_watches` or `/akk watches` to inspect observations. Legacy `listView="history"/"all"`, `all=true` and CLI `list --all` return a migration error.
302
302
 
303
- Every Host page has a total row limit (`listLimit`, default 40, maximum 100) and a 24 KiB UTF-8 serialized JSON ceiling plus a conservative 12,000 weighted-character budget (ASCII 1, other Unicode code points 16), including metadata. These are output bounds, not token counts. Follow `pagination.next_args` unchanged while `has_more=true`; the count of omitted rows is explicit. This cursor is independent of `desktopCursor`: first finish Host pages for one Desktop catalog page, then follow `desktop_scan.next_cursor` with the same Desktop filters and a fresh Host cursor. Pages are fresh discovery snapshots, not frozen history: if membership changes and a cursor is invalid, restart List. Never treat a partial page as the complete inventory. No progress body is added to List; use exact conversation/Watch Status. Very large individual records retain exact IDs and attention state with `details_omitted=true` and a Status entry point; their omitted actions are **not** proof of unsupported capabilities. Full current action/interaction details must be refreshed with Status before acting. Raw CLI `list --json` remains the complete operator/debug contract; `--all` retains its existing history behavior. These bounds reduce Host output, not native discovery/read cost.
303
+ Every Host List page has a total row limit (`listLimit`, default 40, maximum 100), a 24 KiB UTF-8 JSON ceiling and a conservative 12,000 weighted-character budget (ASCII 1, other code points 16), including metadata. Follow `pagination.next_args` unchanged while `has_more=true`. Desktop catalog pagination is separate: finish the Host pages, then use `desktop_scan.next_cursor` with the same Desktop filters and a fresh Host cursor. Discovery pages are live snapshots; restart if membership changes invalidate the cursor. No progress body is added to List. Oversized rows retain exact IDs and a Status entry point; omitted actions do not mean unsupported capabilities. Refresh exact Status before acting.
304
+
305
+ **Watch inventory:** `agent_knock_knock_watches` / `/akk watches` / CLI `watches` is a read-only Store query, defaulting to the most recent 24 hours, 40 rows per page (maximum 100), with a whole-response budget. `hours` accepts 1–48. Active or unresolved observations older than the window remain visible as `outside_window`; terminal managed Turns are a distinct section. Follow the returned pagination arguments. The query does not create/renew monitoring, reconcile or resend notifications. Use exact Status for actionable questions, approvals, callback recovery or full results. Native completion, controller acceptance and chat delivery are separate; `callback_expected=false` alone is neither failure nor delivery proof.
306
+
307
+ Healthy completed Watch bodies are eligible for bounded background cleanup after 48 hours. Active, pending-interaction and unresolved callback records are retained. Cleanup preserves minimal deduplication tombstones; an exact expired record reports `watch_history_expired` and forbids replay. Never resend an old task because its body was pruned. Managed Turns, Sessions and native history are not deleted. See `docs/list-output.md` for retention and migration details.
304
308
 
305
309
  For every resource, `available_actions` is an object whose keys are the exact current semantic action names and whose values are `true`. `action_inputs` contains only dynamic semantic values that cannot be derived from the parent resource, plus scope, permitted decision values, and fields listed by `missing_required`; it does not repeat the same terminal/Session/Turn/Watch ID for every action. The parent `conversation_id` is the target for Send, Status, Watch and supported conversation settings; AKK chooses the operation route. For capability-specific terminal actions, the terminal `id` remains the full `terminal_id`; managed and Watch records expose their own `session_id`, `turn_id`, or `watch_id`. `features` is only a compact capability-status summary and never authorizes an action. Never infer an absent action. The compact display is not the enforcement boundary: the plugin caches the complete private offer before projection, and the CLI re-observes and revalidates the live pane under its action lock before every mutation.
306
310
 
@@ -326,7 +330,7 @@ Action-name glossary:
326
330
 
327
331
  The tool name is normally `agent_knock_knock_<action-name>`. The sole List alias is `retry_submission`, which invokes `agent_knock_knock_send` with its listed `turn_id` only after explicit confirmation. Nested `handoff_decision.choices.take_over_current.action` and `blocking_turns[].recovery_action` carry their explicit tool/action name and semantic arguments; the explanatory choice and recovery text is defined here rather than repeated in every List row.
328
332
 
329
- `available_actions` is the authoritative current-action source for mutations after listing except for the explicitly modeled nested handoff decision and `blocking_turns[].recovery_action`; user-selected `watch({terminal_id})` deliberately honors an exact user-selected terminal even without advertisement. A native interaction response instead requires the current `interaction_state` returned by Status in the same controller conversation. Approval, native interaction response, handoff takeover, and `reconcile_binding` require explicit user intent and fresh source state. Model-facing shapes include `permission_options({terminal_id})` and `set_permissions({terminal_id,mode})`; `model_options({terminal_id})`, the separately advertised Codex-only `repair_model_control({terminal_id})`, and `set_model({terminal_id,model,reasoning_effort})`; `watch({terminal_id})`; `send({session_id|terminal_id,request})`, with the targets mutually exclusive; `identify_foreground({terminal_id})`; `identify_and_send({terminal_id,request})`; `respond_interaction({turn_id|watch_id,interaction_id,answers,delivery_mode?})`, with exactly one subject id, only projected question/option ids, and `delivery_mode` present only for `async_question`; managed `approve({turn_id,decision})` or approve-once-only terminal-scoped `approve({terminal_id})`; `native_inspect({terminal_id,inspection})`; `new_thread({terminal_id})`; `resume_thread({terminal_id,native_thread_id})`; and `reconcile_binding({terminal_id,conflicting_session_id})`. A top-level `previous` block, when present, is the only authority for a “previous/刚才那个” request; human-facing numbers and short IDs remain slash-navigation aids and are never structured tool arguments. The model never carries terminal, binding, catalog, candidate, composer, handoff, approval, interaction-fingerprint, revision, binding ID/generation, or handoff-only live-native-UUID fences; it never receives draft text or composer digests. `native_thread_id` remains the semantic resume identity. AKK derives those private fences and revalidates them before side effects. Orphan-close `expected_message_id` and `expected_transition_id` remain because they are entity IDs. Store format remains 1 and writer protocol is 9; Terminal Watch schema remains 3.
333
+ `available_actions` is the authoritative current-action source for mutations after listing except for the explicitly modeled nested handoff decision and `blocking_turns[].recovery_action`; user-selected `watch({terminal_id})` deliberately honors an exact user-selected terminal even without advertisement. A native interaction response instead requires the current `interaction_state` returned by Status in the same controller conversation. Approval, native interaction response, handoff takeover, and `reconcile_binding` require explicit user intent and fresh source state. Model-facing shapes include `permission_options({terminal_id})` and `set_permissions({terminal_id,mode})`; `model_options({terminal_id})`, the separately advertised Codex-only `repair_model_control({terminal_id})`, and `set_model({terminal_id,model,reasoning_effort})`; `watch({terminal_id})`; `send({session_id|terminal_id,request})`, with the targets mutually exclusive; `identify_foreground({terminal_id})`; `identify_and_send({terminal_id,request})`; `respond_interaction({turn_id|watch_id,interaction_id,answers,delivery_mode?})`, with exactly one subject id, only projected question/option ids, and `delivery_mode` present only for `async_question`; managed `approve({turn_id,decision})` or approve-once-only terminal-scoped `approve({terminal_id})`; `native_inspect({terminal_id,inspection})`; `new_thread({terminal_id})`; `resume_thread({terminal_id,native_thread_id})`; and `reconcile_binding({terminal_id,conflicting_session_id})`. A top-level `previous` block, when present, is the only authority for a “previous/刚才那个” request; human-facing numbers and short IDs remain slash-navigation aids and are never structured tool arguments. The model never carries terminal, binding, catalog, candidate, composer, handoff, approval, interaction-fingerprint, revision, binding ID/generation, or handoff-only live-native-UUID fences; it never receives draft text or composer digests. `native_thread_id` remains the semantic resume identity. AKK derives those private fences and revalidates them before side effects. Orphan-close `expected_message_id` and `expected_transition_id` remain because they are entity IDs. Store format remains 1 and writer protocol is 10; Terminal Watch schema remains 3.
330
334
 
331
335
  Before every terminal operation, AKK revalidates the expected agent PID and provider-owned terminal identity. Native inspection and lifecycle input require an exactly empty Composer; managed Send may require exact empty before input. Codex and Claude Code `terminal_user_explicit` instead require a scanned non-blocked approval state and no proven input-owning questionnaire, editor, menu, or read-only viewer. Reviewed physical Send paths do not require ordinary main-Composer visibility, stability, or exactness. Unreviewed Codex frontends require a recognized styled Composer before clearing and a fresh empty styled Composer before task text. Existing drafts and parsed working activity do not themselves veto the user-priority path, and after text injection no Composer observation may veto Enter. Once clear or request input may have occurred, an uncertain result must not be retried automatically. Humans can attach to the same tmux or Herdr session and continue directly at any time.
332
336