@scotthuang/agent-knock-knock 0.14.11 → 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 (89) hide show
  1. package/CHANGELOG.md +13 -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-presentation.d.ts +1 -1
  18. package/dist/src/conversation-list-presentation.js +28 -6
  19. package/dist/src/conversation-list-presentation.js.map +1 -1
  20. package/dist/src/conversation-list.d.ts +2 -0
  21. package/dist/src/conversation-list.js +19 -0
  22. package/dist/src/conversation-list.js.map +1 -1
  23. package/dist/src/desktop-list.d.ts +0 -2
  24. package/dist/src/desktop-list.js +3 -11
  25. package/dist/src/desktop-list.js.map +1 -1
  26. package/dist/src/desktop-state-store.js +4 -0
  27. package/dist/src/desktop-state-store.js.map +1 -1
  28. package/dist/src/host-monitor-reconciliation.js +20 -0
  29. package/dist/src/host-monitor-reconciliation.js.map +1 -1
  30. package/dist/src/live-lifecycle-smoke.js +56 -37
  31. package/dist/src/live-lifecycle-smoke.js.map +1 -1
  32. package/dist/src/managed-monitoring-list.d.ts +4 -0
  33. package/dist/src/managed-monitoring-list.js +17 -0
  34. package/dist/src/managed-monitoring-list.js.map +1 -0
  35. package/dist/src/semantic-tool-command-helpers.d.ts +4 -0
  36. package/dist/src/semantic-tool-command-helpers.js +28 -3
  37. package/dist/src/semantic-tool-command-helpers.js.map +1 -1
  38. package/dist/src/semantic-tool-descriptions.d.ts +1 -0
  39. package/dist/src/semantic-tool-descriptions.js +7 -5
  40. package/dist/src/semantic-tool-descriptions.js.map +1 -1
  41. package/dist/src/semantic-tool-list-budget.d.ts +1 -2
  42. package/dist/src/semantic-tool-list-budget.js +19 -89
  43. package/dist/src/semantic-tool-list-budget.js.map +1 -1
  44. package/dist/src/semantic-tool-list-projection.d.ts +1 -1
  45. package/dist/src/semantic-tool-list-projection.js +5 -80
  46. package/dist/src/semantic-tool-list-projection.js.map +1 -1
  47. package/dist/src/semantic-tool-runtime.js +27 -5
  48. package/dist/src/semantic-tool-runtime.js.map +1 -1
  49. package/dist/src/semantic-tool-schemas.d.ts +36 -0
  50. package/dist/src/semantic-tool-schemas.js +11 -1
  51. package/dist/src/semantic-tool-schemas.js.map +1 -1
  52. package/dist/src/store.d.ts +1 -1
  53. package/dist/src/store.js +4 -3
  54. package/dist/src/store.js.map +1 -1
  55. package/dist/src/terminal-action-contracts.js +1 -1
  56. package/dist/src/terminal-list-cli-adapter.d.ts +1 -0
  57. package/dist/src/terminal-list-cli-adapter.js +9 -34
  58. package/dist/src/terminal-list-cli-adapter.js.map +1 -1
  59. package/dist/src/terminal-permission-control-list-projection.d.ts +1 -1
  60. package/dist/src/terminal-watch-store.d.ts +1 -1
  61. package/dist/src/terminal-watch-store.js +6 -2
  62. package/dist/src/terminal-watch-store.js.map +1 -1
  63. package/dist/src/watch-history-maintenance-cli-adapter.d.ts +2 -0
  64. package/dist/src/watch-history-maintenance-cli-adapter.js +13 -0
  65. package/dist/src/watch-history-maintenance-cli-adapter.js.map +1 -0
  66. package/dist/src/watch-history-policy.d.ts +9 -0
  67. package/dist/src/watch-history-policy.js +64 -0
  68. package/dist/src/watch-history-policy.js.map +1 -0
  69. package/dist/src/watch-history-receipt.d.ts +27 -0
  70. package/dist/src/watch-history-receipt.js +71 -0
  71. package/dist/src/watch-history-receipt.js.map +1 -0
  72. package/dist/src/watch-history-retention.d.ts +16 -0
  73. package/dist/src/watch-history-retention.js +143 -0
  74. package/dist/src/watch-history-retention.js.map +1 -0
  75. package/dist/src/watch-list-cli-adapter.d.ts +6 -0
  76. package/dist/src/watch-list-cli-adapter.js +62 -0
  77. package/dist/src/watch-list-cli-adapter.js.map +1 -0
  78. package/dist/src/watch-list-projection.d.ts +18 -0
  79. package/dist/src/watch-list-projection.js +158 -0
  80. package/dist/src/watch-list-projection.js.map +1 -0
  81. package/docs/callback-compatibility.md +4 -2
  82. package/docs/codex-cli-native-compatibility.md +9 -9
  83. package/docs/list-output.md +66 -60
  84. package/docs/operator-guide.md +20 -15
  85. package/docs/storage-and-logging.md +8 -5
  86. package/docs/testing.md +2 -2
  87. package/openclaw.plugin.json +4 -0
  88. package/package.json +1 -1
  89. package/templates/openclaw-skills/agent-knock-knock/SKILL.md +12 -8
@@ -0,0 +1,143 @@
1
+ import { createHash } from "node:crypto";
2
+ import fs from "node:fs";
3
+ import path from "node:path";
4
+ import { assertCodexNativeTaskRecord } from "./codex-native-state-store.js";
5
+ import { assertClaudeNativeTaskRecord } from "./claude-native-state-store.js";
6
+ import { assertDesktopTaskRecord } from "./desktop-state-store.js";
7
+ import { assertTerminalWatch } from "./terminal-watch-codec.js";
8
+ import { TERMINAL_WATCHES_DIRECTORY, TERMINAL_WATCH_VERSION } from "./terminal-watch-record.js";
9
+ import { atomicSaveJsonFile, isNodeError, readJsonFileNoFollow } from "./durable-json-file.js";
10
+ import { assertStoreReadable, ensureDir, withStoreWriterLease } from "./store.js";
11
+ import { createFileLockCliAdapter } from "./file-lock-cli-adapter.js";
12
+ import { recordValue } from "./value-guards.js";
13
+ import { WATCH_HISTORY_MAINTENANCE_BATCH, WATCH_HISTORY_MAINTENANCE_INTERVAL_MS, watchHistoryExpired, watchHistorySettledAt } from "./watch-history-policy.js";
14
+ import { assertPrivateHistoryPath, loadWatchHistoryReceipt, saveWatchHistoryReceipt, WATCH_HISTORY_RECEIPTS_DIRECTORY } from "./watch-history-receipt.js";
15
+ const PROVIDERS = [
16
+ { name: "codex", directory: "codex-native-tasks", assert: assertCodexNativeTaskRecord },
17
+ { name: "claude", directory: "claude-native-tasks", assert: assertClaudeNativeTaskRecord },
18
+ { name: "desktop", directory: "desktop-tasks", assert: assertDesktopTaskRecord },
19
+ { name: "terminal", directory: TERMINAL_WATCHES_DIRECTORY, assert: value => {
20
+ if (recordValue(value)?.version !== TERMINAL_WATCH_VERSION)
21
+ throw new Error("Legacy Watch history is retained");
22
+ assertTerminalWatch(value);
23
+ } }
24
+ ];
25
+ function maintenancePath(storeDir) {
26
+ return path.join(storeDir, WATCH_HISTORY_RECEIPTS_DIRECTORY, "maintenance.json");
27
+ }
28
+ function loadMaintenance(storeDir) {
29
+ const file = maintenancePath(storeDir);
30
+ try {
31
+ assertPrivateHistoryPath(path.dirname(file), true);
32
+ assertPrivateHistoryPath(file, false);
33
+ const value = readJsonFileNoFollow(file, "Watch history maintenance");
34
+ if (value?.schema !== "agent-knock-knock/watch-history-maintenance" || value.version !== 1 ||
35
+ !Number.isFinite(Date.parse(value.last_run_at)) || value.cursor !== undefined &&
36
+ (typeof value.cursor !== "string" || value.cursor.length > 512))
37
+ throw new Error("Invalid Watch history maintenance state");
38
+ return value;
39
+ }
40
+ catch (error) {
41
+ if (isNodeError(error, "ENOENT"))
42
+ return undefined;
43
+ throw error;
44
+ }
45
+ }
46
+ function entries(storeDir) {
47
+ return PROVIDERS.flatMap(provider => {
48
+ const directory = path.join(storeDir, provider.directory);
49
+ try {
50
+ assertPrivateHistoryPath(directory, true);
51
+ }
52
+ catch (error) {
53
+ if (isNodeError(error, "ENOENT"))
54
+ return [];
55
+ throw error;
56
+ }
57
+ return fs.readdirSync(directory).filter(name => !name.startsWith(".") && name.endsWith(".json"))
58
+ .map(name => ({ provider, name, key: `${provider.name}:${name}`, file: path.join(directory, name) }));
59
+ }).sort((a, b) => a.key.localeCompare(b.key));
60
+ }
61
+ /** Bounded maintenance of AKK-owned healthy history. Never reads or mutates a native agent. */
62
+ export function collectExpiredWatchHistory(options) {
63
+ const result = { checked: 0, deleted: 0, skipped: 0, errors: 0, throttled: false };
64
+ const now = options.now ?? new Date(), limit = options.limit ?? WATCH_HISTORY_MAINTENANCE_BATCH;
65
+ if (!Number.isFinite(now.getTime()) || !Number.isSafeInteger(limit) || limit < 1 || limit > 1000)
66
+ throw new Error("Invalid Watch maintenance bound");
67
+ if (!fs.existsSync(options.storeDir))
68
+ return result;
69
+ assertStoreReadable(options.storeDir);
70
+ const previous = loadMaintenance(options.storeDir);
71
+ if (previous && now.getTime() - Date.parse(previous.last_run_at) < WATCH_HISTORY_MAINTENANCE_INTERVAL_MS) {
72
+ result.throttled = true;
73
+ return result;
74
+ }
75
+ const adapter = createFileLockCliAdapter({ now: () => new Date(), nowMs: Date.now, pid: () => process.pid,
76
+ sleepSync: () => { throw new Error("Watch maintenance never waits for an occupied record lock"); } });
77
+ const locks = options.locks ?? { acquire: (file) => adapter.acquire(file, { timeoutMs: 0 }) };
78
+ return withStoreWriterLease(options.storeDir, () => {
79
+ // Persisted throttling and cursor also coordinate old/new plugin generations and independent processes.
80
+ const state = loadMaintenance(options.storeDir);
81
+ if (state && now.getTime() - Date.parse(state.last_run_at) < WATCH_HISTORY_MAINTENANCE_INTERVAL_MS) {
82
+ result.throttled = true;
83
+ return result;
84
+ }
85
+ const inventory = entries(options.storeDir);
86
+ let remaining = state?.cursor ? inventory.filter(entry => entry.key.localeCompare(state.cursor) > 0) : inventory;
87
+ if (!remaining.length)
88
+ remaining = inventory;
89
+ const selected = remaining.slice(0, limit);
90
+ for (const entry of selected) {
91
+ result.checked++;
92
+ let release;
93
+ try {
94
+ assertPrivateHistoryPath(entry.file, false);
95
+ release = locks.acquire(`${entry.file}.lock`);
96
+ // Re-read only after the same record lock used by observers and callback settlement.
97
+ assertPrivateHistoryPath(entry.file, false);
98
+ const record = readJsonFileNoFollow(entry.file, "Watch history");
99
+ entry.provider.assert(record);
100
+ const raw = recordValue(record);
101
+ const id = String(raw.watch_id);
102
+ if (entry.name !== `${id}.json`)
103
+ throw new Error("Watch history filename identity mismatch");
104
+ const fingerprint = createHash("sha256").update(JSON.stringify(record)).digest("hex");
105
+ const existing = loadWatchHistoryReceipt(options.storeDir, entry.provider.name, id);
106
+ if (existing && existing.record_sha256 !== fingerprint)
107
+ throw new Error("Expired Watch body changed");
108
+ if (!watchHistoryExpired(record, now)) {
109
+ result.skipped++;
110
+ continue;
111
+ }
112
+ saveWatchHistoryReceipt(options.storeDir, { schema: "agent-knock-knock/watch-history-receipt", version: 1,
113
+ provider: entry.provider.name, watch_id: id, status: "completed", settled_at: watchHistorySettledAt(record),
114
+ deleted_at: now.toISOString(), record_sha256: fingerprint });
115
+ fs.unlinkSync(entry.file);
116
+ const directoryFd = fs.openSync(path.dirname(entry.file), fs.constants.O_RDONLY);
117
+ try {
118
+ fs.fsyncSync(directoryFd);
119
+ }
120
+ finally {
121
+ fs.closeSync(directoryFd);
122
+ }
123
+ result.deleted++;
124
+ }
125
+ catch (error) {
126
+ if (isNodeError(error, "ENOENT") || isNodeError(error, "LOCK_TIMEOUT"))
127
+ result.skipped++;
128
+ else
129
+ result.errors++;
130
+ }
131
+ finally {
132
+ release?.();
133
+ }
134
+ }
135
+ const cursor = selected.length && selected.length < remaining.length ? selected.at(-1).key : undefined;
136
+ atomicSaveJsonFile(maintenancePath(options.storeDir), {
137
+ schema: "agent-knock-knock/watch-history-maintenance", version: 1, last_run_at: now.toISOString(), ...(cursor ? { cursor } : {})
138
+ }, { rootLabel: "AKK Store", directoryLabel: "Watch history receipts", fileLabel: "Watch history maintenance",
139
+ ensureDirectory: ensureDir, fsyncNewDirectoryParent: true });
140
+ return result;
141
+ });
142
+ }
143
+ //# sourceMappingURL=watch-history-retention.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"watch-history-retention.js","sourceRoot":"","sources":["../../src/watch-history-retention.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,6 @@
1
+ import { type WatchListInventory } from "./watch-list-projection.js";
2
+ type Row = Record<string, unknown>;
3
+ /** Pure retained-record inventory: no native clients, monitors, reconciliation or callback attempts. */
4
+ export declare function readWatchListInventory(storeDir: string, readManagedTurns: () => Row[]): WatchListInventory;
5
+ export declare function runWatchList(options: Row, readManagedTurns: () => Row[]): void;
6
+ export {};
@@ -0,0 +1,62 @@
1
+ import { createCodexNativeStateStore } from "./codex-native-state-store.js";
2
+ import { createClaudeNativeStateStore } from "./claude-native-state-store.js";
3
+ import { createDesktopStateStore } from "./desktop-state-store.js";
4
+ import { createTerminalWatchStore } from "./terminal-watch-store.js";
5
+ import { codexNativeTaskProjection } from "./codex-native-public-projection.js";
6
+ import { claudeNativeTaskProjection } from "./claude-native-public-projection.js";
7
+ import { desktopTaskProjection } from "./desktop-public-projection.js";
8
+ import { publicTerminalWatch } from "./terminal-watch-presentation.js";
9
+ import { defaultStoreDir } from "./store.js";
10
+ import { expandHome } from "./cli-command-runtime.js";
11
+ import { cliCwd, cliNowMs, writeCliStdout } from "./cli-runtime-context.js";
12
+ import { parseWatchListOptions, projectWatchList } from "./watch-list-projection.js";
13
+ const readOnlyLocks = { acquire() { throw new Error("Watches listing must not mutate Store"); } };
14
+ /** Pure retained-record inventory: no native clients, monitors, reconciliation or callback attempts. */
15
+ export function readWatchListInventory(storeDir, readManagedTurns) {
16
+ const inventory = { watches: [], managed_turns: [], diagnostics: [] };
17
+ const providers = [
18
+ ["codex_cli", () => {
19
+ const scan = createCodexNativeStateStore(storeDir, readOnlyLocks).scanForReconciliation();
20
+ return { rows: scan.tasks.map(task => ({ ...codexNativeTaskProjection(task), agent: "codex" })), errors: scan.errors.length };
21
+ }],
22
+ ["claude_cli", () => {
23
+ const scan = createClaudeNativeStateStore(storeDir, readOnlyLocks).scanForReconciliation();
24
+ return { rows: scan.tasks.map(task => ({ ...claudeNativeTaskProjection(task), agent: "claude" })), errors: scan.errors.length };
25
+ }],
26
+ ["codex_desktop", () => {
27
+ const scan = createDesktopStateStore(storeDir, readOnlyLocks).scanForReconciliation();
28
+ return { rows: scan.tasks.map(task => ({ ...desktopTaskProjection(task, false), agent: "codex" })), errors: scan.errors.length };
29
+ }],
30
+ ["terminal", () => {
31
+ const scan = createTerminalWatchStore(storeDir, readOnlyLocks).scanForReconciliation();
32
+ return { rows: scan.watches.map(watch => publicTerminalWatch(watch)), errors: scan.errors.length };
33
+ }]
34
+ ];
35
+ for (const [provider, scan] of providers) {
36
+ try {
37
+ const result = scan();
38
+ inventory.watches.push(...result.rows);
39
+ inventory.diagnostics.push({ provider, status: result.errors ? "partial" : "ok", invalid_records: result.errors });
40
+ }
41
+ catch {
42
+ inventory.diagnostics.push({ provider, status: "unavailable" });
43
+ }
44
+ }
45
+ try {
46
+ inventory.managed_turns = readManagedTurns();
47
+ inventory.diagnostics.push({ provider: "managed_turns", status: "ok" });
48
+ }
49
+ catch {
50
+ inventory.diagnostics.push({ provider: "managed_turns", status: "unavailable" });
51
+ }
52
+ return inventory;
53
+ }
54
+ export function runWatchList(options, readManagedTurns) {
55
+ const params = { hours: options.hours, limit: options.limit, cursor: options.cursor, agent: options.agent,
56
+ status: options.status, conversation_id: options.conversation ?? options.conversationId };
57
+ parseWatchListOptions(params, cliNowMs());
58
+ const supplied = options.storeDir ?? options.logDir;
59
+ const storeDir = expandHome(typeof supplied === "string" ? supplied : defaultStoreDir(cliCwd()));
60
+ writeCliStdout(JSON.stringify(projectWatchList(readWatchListInventory(storeDir, readManagedTurns), params, cliNowMs())) + "\n");
61
+ }
62
+ //# sourceMappingURL=watch-list-cli-adapter.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"watch-list-cli-adapter.js","sourceRoot":"","sources":["../../src/watch-list-cli-adapter.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,18 @@
1
+ type Row = Record<string, unknown>;
2
+ export interface WatchListInventory {
3
+ watches: Row[];
4
+ managed_turns: Row[];
5
+ diagnostics?: Row[];
6
+ }
7
+ export declare function parseWatchListOptions(params?: Row, nowMs?: number): {
8
+ hours: number;
9
+ limit: number;
10
+ filters: Row;
11
+ scope: string;
12
+ asOf: number;
13
+ after: string;
14
+ since: number;
15
+ };
16
+ /** Only public summaries cross this boundary; request text, output and authority never do. */
17
+ export declare function projectWatchList(inventory: WatchListInventory, params?: Row, nowMs?: number): Row;
18
+ export {};
@@ -0,0 +1,158 @@
1
+ import { createHash } from "node:crypto";
2
+ import { DEFAULT_WATCH_HISTORY_HOURS, WATCH_HISTORY_RETENTION_HOURS } from "./watch-history-policy.js";
3
+ import { HOST_LIST_MAX_BYTES, HOST_LIST_MAX_WEIGHTED_CHARS, hostListWatchNeedsAttention, hostListWeightedChars } from "./semantic-tool-list-budget.js";
4
+ import { recordValue } from "./value-guards.js";
5
+ const scalarFields = ["watch_id", "turn_id", "id", "short_ref", "conversation_id", "terminal_id", "session_id", "native_thread_id", "native_turn_id", "native_input_id", "native_receipt_turn_id",
6
+ "source", "agent", "workspace", "status", "observation_status", "observation_state", "renewal_count", "renewed_at", "recovered_at", "observation_mode", "watch_mode", "confidence", "anchor_state", "task_kind", "management_state",
7
+ "created_at", "updated_at", "observed_at", "last_activity_at", "deadline_at", "hard_timeout_at", "closed_at", "unwatched_at",
8
+ "callback_configured", "callback_expected", "callback_in_flight", "callback_state", "callback_delivery_scope", "channel_delivery_state",
9
+ "pending_manual_count", "pending_async_count", "pending_interaction_count", "observation_error", "observation_active", "send_state", "submission_state"];
10
+ export function parseWatchListOptions(params = {}, nowMs = Date.now()) {
11
+ const hours = integer(params.hours, DEFAULT_WATCH_HISTORY_HOURS, 1, WATCH_HISTORY_RETENTION_HOURS, "hours");
12
+ const limit = integer(params.limit, 40, 1, 100, "limit");
13
+ const filters = { hours };
14
+ for (const key of ["agent", "status", "conversation_id"]) {
15
+ if (params[key] === undefined)
16
+ continue;
17
+ if (typeof params[key] !== "string" || !params[key].trim() || params[key].length > 2048)
18
+ throw new Error(`Invalid Watches ${key}`);
19
+ filters[key] = params[key];
20
+ }
21
+ if (filters.agent !== undefined && !["codex", "claude"].includes(String(filters.agent)))
22
+ throw new Error("Watches agent must be codex or claude");
23
+ const scope = digest(JSON.stringify(filters));
24
+ const { asOf, after } = parseWatchListCursor(params.cursor, scope, nowMs);
25
+ return { hours, limit, filters, scope, asOf, after, since: asOf - hours * 3_600_000 };
26
+ }
27
+ /** Bind pagination to the original time window and exact normalized filters. */
28
+ function parseWatchListCursor(value, scope, nowMs) {
29
+ if (value === undefined)
30
+ return { asOf: nowMs, after: "" };
31
+ try {
32
+ if (typeof value !== "string" || value.length > 512 || !/^[A-Za-z0-9_-]+$/u.test(value))
33
+ throw new Error();
34
+ const parsed = JSON.parse(Buffer.from(value, "base64url").toString("utf8"));
35
+ if (parsed.version !== 1 || parsed.scope !== scope || !Number.isSafeInteger(parsed.as_of) || parsed.as_of < 0 || parsed.as_of > nowMs ||
36
+ typeof parsed.after !== "string" || !/^[a-f0-9]{64}$/u.test(parsed.after))
37
+ throw new Error();
38
+ return { asOf: parsed.as_of, after: parsed.after };
39
+ }
40
+ catch {
41
+ throw new Error("Invalid Watches cursor or changed filters; restart watches without cursor");
42
+ }
43
+ }
44
+ /** Only public summaries cross this boundary; request text, output and authority never do. */
45
+ export function projectWatchList(inventory, params = {}, nowMs = Date.now()) {
46
+ const options = parseWatchListOptions(params, nowMs);
47
+ const entries = ([...inventory.watches.map(row => ({ row, kind: "watch" })),
48
+ ...inventory.managed_turns.map(row => ({ row, kind: "managed_turn" }))]).flatMap(({ row, kind }) => {
49
+ if (options.filters.agent && row.agent !== options.filters.agent || options.filters.status && row.status !== options.filters.status ||
50
+ options.filters.conversation_id && ![row.conversation_id, row.terminal_id, row.session_id].includes(options.filters.conversation_id))
51
+ return [];
52
+ const attention = hostListWatchNeedsAttention(row);
53
+ const time = latestTime(row);
54
+ const within = time !== undefined && time >= options.since && time <= options.asOf;
55
+ if (!within && !attention)
56
+ return [];
57
+ const id = row.watch_id ?? row.turn_id;
58
+ if (typeof id !== "string" || !id)
59
+ return [];
60
+ return [{ row, kind, attention, within, time, key: digest(`${kind}:${id}`) }];
61
+ }).sort((a, b) => Number(b.attention) - Number(a.attention) || (b.time ?? 0) - (a.time ?? 0) || a.key.localeCompare(b.key));
62
+ const index = options.after ? entries.findIndex(entry => entry.key === options.after) : -1;
63
+ if (options.after && index < 0)
64
+ throw new Error("Watches changed since this cursor; restart watches without cursor");
65
+ const remaining = entries.slice(index + 1);
66
+ const output = {
67
+ projection: { schema: "agent-knock-knock/watch-list", version: 1 },
68
+ watches: [], managed_turns: [],
69
+ window: { hours: options.hours, since: new Date(options.since).toISOString(), as_of: new Date(options.asOf).toISOString(),
70
+ includes_older_attention: true, note: "Active or unresolved records remain visible outside the history window. Managed Turns are not Watches." },
71
+ read_at: new Date(nowMs).toISOString(),
72
+ diagnostics: (inventory.diagnostics ?? []).map(row => ({ provider: row.provider, status: row.status, invalid_records: row.invalid_records })),
73
+ pagination: { limit: options.limit, total_available: entries.length, attention: entries.filter(entry => entry.attention).length,
74
+ max_output_bytes: HOST_LIST_MAX_BYTES, max_output_weighted_chars: HOST_LIST_MAX_WEIGHTED_CHARS,
75
+ live_snapshot: true, note: "Window boundaries stay fixed across pages; record states may change. Exact Status returns current details and recovery actions." }
76
+ };
77
+ let returned = 0;
78
+ update();
79
+ for (const entry of remaining) {
80
+ if (returned >= options.limit)
81
+ break;
82
+ const target = output[entry.kind === "watch" ? "watches" : "managed_turns"];
83
+ target.push(compactWatch(entry.row, entry.kind, entry.attention, entry.within));
84
+ returned++;
85
+ update();
86
+ if (overBudget(output)) {
87
+ target.pop();
88
+ returned--;
89
+ update();
90
+ break;
91
+ }
92
+ }
93
+ if (!returned && remaining.length)
94
+ throw new Error("Watch identity exceeds the response budget; use exact Status");
95
+ if (overBudget(output))
96
+ throw new Error("Watches metadata exceeds the response budget");
97
+ return output;
98
+ function update() {
99
+ const more = returned < remaining.length;
100
+ const last = remaining[returned - 1]?.key;
101
+ const cursor = more && last ? Buffer.from(JSON.stringify({ version: 1, scope: options.scope, as_of: options.asOf, after: last })).toString("base64url") : null;
102
+ Object.assign(output.pagination, { returned, has_more: more, remaining: remaining.length - returned, next_cursor: cursor,
103
+ next_args: cursor ? { ...options.filters, limit: options.limit, cursor } : null });
104
+ }
105
+ }
106
+ function compactWatch(row, kind, attention, within) {
107
+ const output = { kind, attention_required: attention, outside_window: !within };
108
+ for (const key of scalarFields)
109
+ if (["string", "number", "boolean"].includes(typeof row[key]) || row[key] === null)
110
+ output[key] = row[key];
111
+ const delivery = recordValue(row.callback_delivery);
112
+ if (delivery)
113
+ output.callback_delivery = pick(delivery, ["status", "attempts", "attempt_state", "next_attempt_at"]);
114
+ const callback = recordValue(row.callback);
115
+ if (callback)
116
+ output.callback = pick(callback, ["pending", "delivered", "failed", "superseded", "last_error_code"]);
117
+ const notifications = Array.isArray(row.callback_notifications) ? row.callback_notifications : [];
118
+ if (notifications.length) {
119
+ const statuses = {};
120
+ for (const note of notifications) {
121
+ const status = recordValue(note)?.status;
122
+ if (typeof status === "string" && ["accepted", "uncertain", "failed", "ready", "leased", "retry_wait"].includes(status))
123
+ statuses[status] = (statuses[status] ?? 0) + 1;
124
+ }
125
+ output.callback_notifications = { total: notifications.length, statuses };
126
+ }
127
+ const input = kind === "watch" ? { watch_id: row.watch_id } : { turn_id: row.turn_id };
128
+ const actions = recordValue(row.available_actions) ?? {};
129
+ output.available_actions = kind === "managed_turn"
130
+ ? Object.fromEntries(["status", "retry_callback", "close"].filter(name => recordValue(actions[name])).map(name => [name, actions[name]]))
131
+ : { status: true };
132
+ if (kind !== "managed_turn" || !Object.keys(output.available_actions).length) {
133
+ output.available_actions = { status: true };
134
+ output.action_inputs = { status: { arguments: input } };
135
+ }
136
+ output.detail_tool = "agent_knock_knock_status";
137
+ return output;
138
+ }
139
+ function pick(row, keys) { return Object.fromEntries(keys.filter(key => row[key] !== undefined).map(key => [key, row[key]])); }
140
+ function latestTime(row) {
141
+ const times = ["updated_at", "observed_at", "last_activity_at", "closed_at", "unwatched_at", "created_at"].map(key => typeof row[key] === "string" ? Date.parse(row[key]) : NaN).filter(Number.isFinite);
142
+ const settlement = recordValue(row.settlement);
143
+ if (typeof settlement?.observed_at === "string" && Number.isFinite(Date.parse(settlement.observed_at)))
144
+ times.push(Date.parse(settlement.observed_at));
145
+ return times.length ? Math.max(...times) : undefined;
146
+ }
147
+ function integer(value, fallback, min, max, name) {
148
+ const number = value === undefined ? fallback : typeof value === "string" && /^\d+$/u.test(value) ? Number(value) : value;
149
+ if (!Number.isSafeInteger(number) || Number(number) < min || Number(number) > max)
150
+ throw new Error(`Watches ${name} must be between ${min} and ${max}`);
151
+ return Number(number);
152
+ }
153
+ function digest(value) { return createHash("sha256").update(value).digest("hex"); }
154
+ function overBudget(value) {
155
+ const json = JSON.stringify(value);
156
+ return Buffer.byteLength(json, "utf8") > HOST_LIST_MAX_BYTES || hostListWeightedChars(json) > HOST_LIST_MAX_WEIGHTED_CHARS;
157
+ }
158
+ //# sourceMappingURL=watch-list-projection.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"watch-list-projection.js","sourceRoot":"","sources":["../../src/watch-list-projection.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACzC,OAAO,EAAE,2BAA2B,EAAE,6BAA6B,EAAE,MAAM,2BAA2B,CAAC;AACvG,OAAO,EAAE,mBAAmB,EAAE,4BAA4B,EAAE,2BAA2B,EAAE,qBAAqB,EAAE,MAAM,gCAAgC,CAAC;AACvJ,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAIhD,MAAM,YAAY,GAAG,CAAC,UAAU,EAAE,SAAS,EAAE,IAAI,EAAE,WAAW,EAAE,iBAAiB,EAAE,aAAa,EAAE,YAAY,EAAE,kBAAkB,EAAE,gBAAgB,EAAE,iBAAiB,EAAE,wBAAwB;IAC/L,QAAQ,EAAE,OAAO,EAAE,WAAW,EAAE,QAAQ,EAAE,oBAAoB,EAAE,mBAAmB,EAAE,eAAe,EAAE,YAAY,EAAE,cAAc,EAAE,kBAAkB,EAAE,YAAY,EAAE,YAAY,EAAE,cAAc,EAAE,WAAW,EAAE,kBAAkB;IACnO,YAAY,EAAE,YAAY,EAAE,aAAa,EAAE,kBAAkB,EAAE,aAAa,EAAE,iBAAiB,EAAE,WAAW,EAAE,cAAc;IAC5H,qBAAqB,EAAE,mBAAmB,EAAE,oBAAoB,EAAE,gBAAgB,EAAE,yBAAyB,EAAE,wBAAwB;IACvI,sBAAsB,EAAE,qBAAqB,EAAE,2BAA2B,EAAE,mBAAmB,EAAE,oBAAoB,EAAE,YAAY,EAAE,kBAAkB,CAAC,CAAC;AAE3J,MAAM,UAAU,qBAAqB,CAAC,MAAM,GAAQ,EAAE,EAAE,KAAK,GAAG,IAAI,CAAC,GAAG,EAAE;IACxE,MAAM,KAAK,GAAG,OAAO,CAAC,MAAM,CAAC,KAAK,EAAE,2BAA2B,EAAE,CAAC,EAAE,6BAA6B,EAAE,OAAO,CAAC,CAAC;IAC5G,MAAM,KAAK,GAAG,OAAO,CAAC,MAAM,CAAC,KAAK,EAAE,EAAE,EAAE,CAAC,EAAE,GAAG,EAAE,OAAO,CAAC,CAAC;IACzD,MAAM,OAAO,GAAQ,EAAE,KAAK,EAAE,CAAC;IAC/B,KAAK,MAAM,GAAG,IAAI,CAAC,OAAO,EAAE,QAAQ,EAAE,iBAAiB,CAAC,EAAE,CAAC;QACzD,IAAI,MAAM,CAAC,GAAG,CAAC,KAAK,SAAS;YAAE,SAAS;QACxC,IAAI,OAAO,MAAM,CAAC,GAAG,CAAC,KAAK,QAAQ,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,IAAI,MAAM,CAAC,GAAG,CAAC,CAAC,MAAM,GAAG,IAAI;YAAE,MAAM,IAAI,KAAK,CAAC,mBAAmB,GAAG,EAAE,CAAC,CAAC;QACnI,OAAO,CAAC,GAAG,CAAC,GAAG,MAAM,CAAC,GAAG,CAAC,CAAC;IAC7B,CAAC;IACD,IAAI,OAAO,CAAC,KAAK,KAAK,SAAS,IAAI,CAAC,CAAC,OAAO,EAAE,QAAQ,CAAC,CAAC,QAAQ,CAAC,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;QAAE,MAAM,IAAI,KAAK,CAAC,uCAAuC,CAAC,CAAC;IAClJ,MAAM,KAAK,GAAG,MAAM,CAAC,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC,CAAC;IAC9C,MAAM,EAAE,IAAI,EAAE,KAAK,EAAE,GAAG,oBAAoB,CAAC,MAAM,CAAC,MAAM,EAAE,KAAK,EAAE,KAAK,CAAC,CAAC;IAC1E,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,KAAK,EAAE,KAAK,EAAE,IAAI,GAAG,KAAK,GAAG,SAAS,EAAE,CAAC;AACxF,CAAC;AAED,gFAAgF;AAChF,SAAS,oBAAoB,CAAC,KAAc,EAAE,KAAa,EAAE,KAAa;IACxE,IAAI,KAAK,KAAK,SAAS;QAAE,OAAO,EAAE,IAAI,EAAE,KAAK,EAAE,KAAK,EAAE,EAAE,EAAE,CAAC;IAC3D,IAAI,CAAC;QACH,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,CAAC,MAAM,GAAG,GAAG,IAAI,CAAC,mBAAmB,CAAC,IAAI,CAAC,KAAK,CAAC;YAAE,MAAM,IAAI,KAAK,EAAE,CAAC;QAC3G,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,IAAI,CAAC,KAAK,EAAE,WAAW,CAAC,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC;QAC5E,IAAI,MAAM,CAAC,OAAO,KAAK,CAAC,IAAI,MAAM,CAAC,KAAK,KAAK,KAAK,IAAI,CAAC,MAAM,CAAC,aAAa,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,MAAM,CAAC,KAAK,GAAG,CAAC,IAAI,MAAM,CAAC,KAAK,GAAG,KAAK;YACnI,OAAO,MAAM,CAAC,KAAK,KAAK,QAAQ,IAAI,CAAC,iBAAiB,CAAC,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC;YAAE,MAAM,IAAI,KAAK,EAAE,CAAC;QAC/F,OAAO,EAAE,IAAI,EAAE,MAAM,CAAC,KAAK,EAAE,KAAK,EAAE,MAAM,CAAC,KAAK,EAAE,CAAC;IACrD,CAAC;IAAC,MAAM,CAAC;QAAC,MAAM,IAAI,KAAK,CAAC,2EAA2E,CAAC,CAAC;IAAC,CAAC;AAC3G,CAAC;AAED,8FAA8F;AAC9F,MAAM,UAAU,gBAAgB,CAAC,SAA6B,EAAE,MAAM,GAAQ,EAAE,EAAE,KAAK,GAAG,IAAI,CAAC,GAAG,EAAE;IAClG,MAAM,OAAO,GAAG,qBAAqB,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC;IACrD,MAAM,OAAO,GAAG,CAAC,CAAC,GAAG,SAAS,CAAC,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,EAAE,GAAG,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC,CAAC;QACzE,GAAG,SAAS,CAAC,aAAa,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,EAAE,GAAG,EAAE,IAAI,EAAE,cAAc,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,EAAE,GAAG,EAAE,IAAI,EAAE,EAAE,EAAE;QACnG,IAAI,OAAO,CAAC,OAAO,CAAC,KAAK,IAAI,GAAG,CAAC,KAAK,KAAK,OAAO,CAAC,OAAO,CAAC,KAAK,IAAI,OAAO,CAAC,OAAO,CAAC,MAAM,IAAI,GAAG,CAAC,MAAM,KAAK,OAAO,CAAC,OAAO,CAAC,MAAM;YACjI,OAAO,CAAC,OAAO,CAAC,eAAe,IAAI,CAAC,CAAC,GAAG,CAAC,eAAe,EAAE,GAAG,CAAC,WAAW,EAAE,GAAG,CAAC,UAAU,CAAC,CAAC,QAAQ,CAAC,OAAO,CAAC,OAAO,CAAC,eAAe,CAAC;YAAE,OAAO,EAAE,CAAC;QAClJ,MAAM,SAAS,GAAG,2BAA2B,CAAC,GAAG,CAAC,CAAC;QACnD,MAAM,IAAI,GAAG,UAAU,CAAC,GAAG,CAAC,CAAC;QAC7B,MAAM,MAAM,GAAG,IAAI,KAAK,SAAS,IAAI,IAAI,IAAI,OAAO,CAAC,KAAK,IAAI,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;QACnF,IAAI,CAAC,MAAM,IAAI,CAAC,SAAS;YAAE,OAAO,EAAE,CAAC;QACrC,MAAM,EAAE,GAAG,GAAG,CAAC,QAAQ,IAAI,GAAG,CAAC,OAAO,CAAC;QACvC,IAAI,OAAO,EAAE,KAAK,QAAQ,IAAI,CAAC,EAAE;YAAE,OAAO,EAAE,CAAC;QAC7C,OAAO,CAAC,EAAE,GAAG,EAAE,IAAI,EAAE,SAAS,EAAE,MAAM,EAAE,IAAI,EAAE,GAAG,EAAE,MAAM,CAAC,GAAG,IAAI,IAAI,EAAE,EAAE,CAAC,EAAE,CAAC,CAAC;IAChF,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC,SAAS,CAAC,GAAG,MAAM,CAAC,CAAC,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,aAAa,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;IAC5H,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,OAAO,CAAC,SAAS,CAAC,KAAK,CAAC,EAAE,CAAC,KAAK,CAAC,GAAG,KAAK,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IAC3F,IAAI,OAAO,CAAC,KAAK,IAAI,KAAK,GAAG,CAAC;QAAE,MAAM,IAAI,KAAK,CAAC,mEAAmE,CAAC,CAAC;IACrH,MAAM,SAAS,GAAG,OAAO,CAAC,KAAK,CAAC,KAAK,GAAG,CAAC,CAAC,CAAC;IAC3C,MAAM,MAAM,GAAQ;QAClB,UAAU,EAAE,EAAE,MAAM,EAAE,8BAA8B,EAAE,OAAO,EAAE,CAAC,EAAE;QAClE,OAAO,EAAE,EAAE,EAAE,aAAa,EAAE,EAAE;QAC9B,MAAM,EAAE,EAAE,KAAK,EAAE,OAAO,CAAC,KAAK,EAAE,KAAK,EAAE,IAAI,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,WAAW,EAAE,EAAE,KAAK,EAAE,IAAI,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,WAAW,EAAE;YACvH,wBAAwB,EAAE,IAAI,EAAE,IAAI,EAAE,wGAAwG,EAAE;QAClJ,OAAO,EAAE,IAAI,IAAI,CAAC,KAAK,CAAC,CAAC,WAAW,EAAE;QACtC,WAAW,EAAE,CAAC,SAAS,CAAC,WAAW,IAAI,EAAE,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,EAAE,QAAQ,EAAE,GAAG,CAAC,QAAQ,EAAE,MAAM,EAAE,GAAG,CAAC,MAAM,EAAE,eAAe,EAAE,GAAG,CAAC,eAAe,EAAE,CAAC,CAAC;QAC7I,UAAU,EAAE,EAAE,KAAK,EAAE,OAAO,CAAC,KAAK,EAAE,eAAe,EAAE,OAAO,CAAC,MAAM,EAAE,SAAS,EAAE,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC,MAAM;YAC7H,gBAAgB,EAAE,mBAAmB,EAAE,yBAAyB,EAAE,4BAA4B;YAC9F,aAAa,EAAE,IAAI,EAAE,IAAI,EAAE,iIAAiI,EAAE;KACjK,CAAC;IACF,IAAI,QAAQ,GAAG,CAAC,CAAC;IACjB,MAAM,EAAE,CAAC;IACT,KAAK,MAAM,KAAK,IAAI,SAAS,EAAE,CAAC;QAC9B,IAAI,QAAQ,IAAI,OAAO,CAAC,KAAK;YAAE,MAAM;QACrC,MAAM,MAAM,GAAG,MAAM,CAAC,KAAK,CAAC,IAAI,KAAK,OAAO,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,eAAe,CAAU,CAAC;QACrF,MAAM,CAAC,IAAI,CAAC,YAAY,CAAC,KAAK,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,EAAE,KAAK,CAAC,SAAS,EAAE,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC;QAChF,QAAQ,EAAE,CAAC;QAAC,MAAM,EAAE,CAAC;QACrB,IAAI,UAAU,CAAC,MAAM,CAAC,EAAE,CAAC;YAAC,MAAM,CAAC,GAAG,EAAE,CAAC;YAAC,QAAQ,EAAE,CAAC;YAAC,MAAM,EAAE,CAAC;YAAC,MAAM;QAAC,CAAC;IACxE,CAAC;IACD,IAAI,CAAC,QAAQ,IAAI,SAAS,CAAC,MAAM;QAAE,MAAM,IAAI,KAAK,CAAC,8DAA8D,CAAC,CAAC;IACnH,IAAI,UAAU,CAAC,MAAM,CAAC;QAAE,MAAM,IAAI,KAAK,CAAC,8CAA8C,CAAC,CAAC;IACxF,OAAO,MAAM,CAAC;IACd,SAAS,MAAM;QACb,MAAM,IAAI,GAAG,QAAQ,GAAG,SAAS,CAAC,MAAM,CAAC;QACzC,MAAM,IAAI,GAAG,SAAS,CAAC,QAAQ,GAAG,CAAC,CAAC,EAAE,GAAG,CAAC;QAC1C,MAAM,MAAM,GAAG,IAAI,IAAI,IAAI,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE,OAAO,EAAE,CAAC,EAAE,KAAK,EAAE,OAAO,CAAC,KAAK,EAAE,KAAK,EAAE,OAAO,CAAC,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;QAC/J,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,UAAiB,EAAE,EAAE,QAAQ,EAAE,QAAQ,EAAE,IAAI,EAAE,SAAS,EAAE,SAAS,CAAC,MAAM,GAAG,QAAQ,EAAE,WAAW,EAAE,MAAM;YAC7H,SAAS,EAAE,MAAM,CAAC,CAAC,CAAC,EAAE,GAAG,OAAO,CAAC,OAAO,EAAE,KAAK,EAAE,OAAO,CAAC,KAAK,EAAE,MAAM,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC;IACvF,CAAC;AACH,CAAC;AAED,SAAS,YAAY,CAAC,GAAQ,EAAE,IAAY,EAAE,SAAkB,EAAE,MAAe;IAC/E,MAAM,MAAM,GAAQ,EAAE,IAAI,EAAE,kBAAkB,EAAE,SAAS,EAAE,cAAc,EAAE,CAAC,MAAM,EAAE,CAAC;IACrF,KAAK,MAAM,GAAG,IAAI,YAAY;QAAE,IAAI,CAAC,QAAQ,EAAE,QAAQ,EAAE,SAAS,CAAC,CAAC,QAAQ,CAAC,OAAO,GAAG,CAAC,GAAG,CAAC,CAAC,IAAI,GAAG,CAAC,GAAG,CAAC,KAAK,IAAI;YAAE,MAAM,CAAC,GAAG,CAAC,GAAG,GAAG,CAAC,GAAG,CAAC,CAAC;IAC3I,MAAM,QAAQ,GAAG,WAAW,CAAC,GAAG,CAAC,iBAAiB,CAAC,CAAC;IACpD,IAAI,QAAQ;QAAE,MAAM,CAAC,iBAAiB,GAAG,IAAI,CAAC,QAAQ,EAAE,CAAC,QAAQ,EAAE,UAAU,EAAE,eAAe,EAAE,iBAAiB,CAAC,CAAC,CAAC;IACpH,MAAM,QAAQ,GAAG,WAAW,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;IAC3C,IAAI,QAAQ;QAAE,MAAM,CAAC,QAAQ,GAAG,IAAI,CAAC,QAAQ,EAAE,CAAC,SAAS,EAAE,WAAW,EAAE,QAAQ,EAAE,YAAY,EAAE,iBAAiB,CAAC,CAAC,CAAC;IACpH,MAAM,aAAa,GAAG,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,sBAAsB,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,sBAAsB,CAAC,CAAC,CAAC,EAAE,CAAC;IAClG,IAAI,aAAa,CAAC,MAAM,EAAE,CAAC;QACzB,MAAM,QAAQ,GAA2B,EAAE,CAAC;QAC5C,KAAK,MAAM,IAAI,IAAI,aAAa,EAAE,CAAC;YACjC,MAAM,MAAM,GAAG,WAAW,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC;YACzC,IAAI,OAAO,MAAM,KAAK,QAAQ,IAAI,CAAC,UAAU,EAAE,WAAW,EAAE,QAAQ,EAAE,OAAO,EAAE,QAAQ,EAAE,YAAY,CAAC,CAAC,QAAQ,CAAC,MAAM,CAAC;gBAAE,QAAQ,CAAC,MAAM,CAAC,GAAG,CAAC,QAAQ,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC;QAC1K,CAAC;QACD,MAAM,CAAC,sBAAsB,GAAG,EAAE,KAAK,EAAE,aAAa,CAAC,MAAM,EAAE,QAAQ,EAAE,CAAC;IAC5E,CAAC;IACD,MAAM,KAAK,GAAG,IAAI,KAAK,OAAO,CAAC,CAAC,CAAC,EAAE,QAAQ,EAAE,GAAG,CAAC,QAAQ,EAAE,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,GAAG,CAAC,OAAO,EAAE,CAAC;IACvF,MAAM,OAAO,GAAG,WAAW,CAAC,GAAG,CAAC,iBAAiB,CAAC,IAAI,EAAE,CAAC;IACzD,MAAM,CAAC,iBAAiB,GAAG,IAAI,KAAK,cAAc;QAChD,CAAC,CAAC,MAAM,CAAC,WAAW,CAAC,CAAC,QAAQ,EAAE,gBAAgB,EAAE,OAAO,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC,WAAW,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,IAAI,EAAE,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QACzI,CAAC,CAAC,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC;IACrB,IAAI,IAAI,KAAK,cAAc,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,iBAAwB,CAAC,CAAC,MAAM,EAAE,CAAC;QACpF,MAAM,CAAC,iBAAiB,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC;QAC5C,MAAM,CAAC,aAAa,GAAG,EAAE,MAAM,EAAE,EAAE,SAAS,EAAE,KAAK,EAAE,EAAE,CAAC;IAC1D,CAAC;IACD,MAAM,CAAC,WAAW,GAAG,0BAA0B,CAAC;IAChD,OAAO,MAAM,CAAC;AAChB,CAAC;AACD,SAAS,IAAI,CAAC,GAAQ,EAAE,IAAc,IAAS,OAAO,MAAM,CAAC,WAAW,CAAC,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,KAAK,SAAS,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,GAAG,EAAE,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;AACnJ,SAAS,UAAU,CAAC,GAAQ;IAC1B,MAAM,KAAK,GAAG,CAAC,YAAY,EAAE,aAAa,EAAE,kBAAkB,EAAE,WAAW,EAAE,cAAc,EAAE,YAAY,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CACnH,OAAO,GAAG,CAAC,GAAG,CAAC,KAAK,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;IACrF,MAAM,UAAU,GAAG,WAAW,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC;IAC/C,IAAI,OAAO,UAAU,EAAE,WAAW,KAAK,QAAQ,IAAI,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,KAAK,CAAC,UAAU,CAAC,WAAW,CAAC,CAAC;QAAE,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,UAAU,CAAC,WAAW,CAAC,CAAC,CAAC;IACvJ,OAAO,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;AACvD,CAAC;AACD,SAAS,OAAO,CAAC,KAAc,EAAE,QAAgB,EAAE,GAAW,EAAE,GAAW,EAAE,IAAY;IACvF,MAAM,MAAM,GAAG,KAAK,KAAK,SAAS,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,OAAO,KAAK,KAAK,QAAQ,IAAI,QAAQ,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC;IAC1H,IAAI,CAAC,MAAM,CAAC,aAAa,CAAC,MAAM,CAAC,IAAI,MAAM,CAAC,MAAM,CAAC,GAAG,GAAG,IAAI,MAAM,CAAC,MAAM,CAAC,GAAG,GAAG;QAAE,MAAM,IAAI,KAAK,CAAC,WAAW,IAAI,oBAAoB,GAAG,QAAQ,GAAG,EAAE,CAAC,CAAC;IACxJ,OAAO,MAAM,CAAC,MAAM,CAAC,CAAC;AACxB,CAAC;AACD,SAAS,MAAM,CAAC,KAAa,IAAY,OAAO,UAAU,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;AACnG,SAAS,UAAU,CAAC,KAAc;IAChC,MAAM,IAAI,GAAG,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC;IACnC,OAAO,MAAM,CAAC,UAAU,CAAC,IAAI,EAAE,MAAM,CAAC,GAAG,mBAAmB,IAAI,qBAAqB,CAAC,IAAI,CAAC,GAAG,4BAA4B,CAAC;AAC7H,CAAC"}
@@ -42,11 +42,13 @@ they are not converted into a permissive activity fallback.
42
42
  Ordinary List/Status remains observation-only and does not create either Watch.
43
43
  Existing managed tasks and user terminals are not restarted by this policy.
44
44
 
45
- The store writer protocol is 9. Outer Terminal Watch schema remains 3; new
45
+ The store writer protocol is 10. Outer Terminal Watch schema remains 3; new
46
46
  paginated anchors and request-correlated activity anchors use version 2. Earlier
47
47
  anchors remain readable. The store upgrade changes the writer fence without
48
48
  rewriting existing private Watch records, and older writers cannot mutate the
49
- upgraded store.
49
+ upgraded store. Protocol 10 also fences Watch deletion receipts: a pruned
50
+ completed request cannot be recreated by an older writer. Uncertain or pending
51
+ notifications are never eligible for history cleanup.
50
52
 
51
53
  Read errors expose only the operation stage and parsed actual/expected backend
52
54
  versions. Full server responses, task text and raw RPC errors are not copied into
@@ -89,15 +89,15 @@ proves that backend thread is the selected live conversation. Existing opaque
89
89
  accept a terminal ID as `conversation_id` for these operations.
90
90
 
91
91
  The default List presents CLI and Desktop, with Codex/Claude as the agent type.
92
- In AKK 0.14.6, one unresolved terminal and one loaded direct candidate with the
93
- same agent and normalized absolute project path share the original terminal's
94
- display row. This presentation grouping does not copy the candidate's native ID,
95
- status, permissions or actions, and does not establish a routing association.
96
- Known thread/home/process conflicts or multiple candidates remain separate.
97
- A direct-only CLI remains listed. If an embedded CLI and an independent direct
98
- CLI have the same directory and unknown identities, this default grouping can
99
- also fold those records; `terminalDebug: true` / `list --terminal-debug` expands
100
- all unassociated records. Raw CLI discovery arrays remain available for diagnosis.
92
+ In AKK 0.14.12, a one-to-one same-agent/project discovery pair uses the verified
93
+ loaded backend as its default CLI entry. Its original exact ID, title, status
94
+ and actions stay unchanged; the terminal candidate is omitted from this view.
95
+ This does not establish an alias, copy terminal capabilities or redirect old
96
+ terminal selectors. Multiple candidates, known thread/home/process conflicts,
97
+ and terminal records needing attention or management recovery remain visible.
98
+ Direct-only and terminal-only CLIs remain listed. `terminalDebug: true` /
99
+ `list --terminal-debug` expands all connections. Raw CLI discovery arrays also
100
+ remain available for diagnosis.
101
101
 
102
102
  Actual routing association still requires the exact current thread, verified
103
103
  Codex home and physical process incarnation. A configured home, matching cwd,