@scotthuang/agent-knock-knock 0.13.14 → 0.13.16
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.
- package/CHANGELOG.md +12 -0
- package/README.md +2 -1
- package/dist/src/cli-core.js +6 -3
- package/dist/src/cli-core.js.map +1 -1
- package/dist/src/codex-app-server-read-client.d.ts +17 -1
- package/dist/src/codex-app-server-read-client.js +81 -37
- package/dist/src/codex-app-server-read-client.js.map +1 -1
- package/dist/src/codex-fullscreen-composer-proof.d.ts +3 -1
- package/dist/src/codex-fullscreen-composer-proof.js +11 -3
- package/dist/src/codex-fullscreen-composer-proof.js.map +1 -1
- package/dist/src/codex-lifecycle-compatibility.d.ts +9 -0
- package/dist/src/codex-lifecycle-compatibility.js +27 -0
- package/dist/src/codex-lifecycle-compatibility.js.map +1 -1
- package/dist/src/codex-paginated-observation.d.ts +1 -0
- package/dist/src/codex-paginated-observation.js +13 -4
- package/dist/src/codex-paginated-observation.js.map +1 -1
- package/dist/src/codex-paginated-task.d.ts +7 -5
- package/dist/src/codex-paginated-task.js +41 -17
- package/dist/src/codex-paginated-task.js.map +1 -1
- package/dist/src/codex-paginated-thread-binding.d.ts +5 -0
- package/dist/src/codex-paginated-thread-binding.js +52 -35
- package/dist/src/codex-paginated-thread-binding.js.map +1 -1
- package/dist/src/codex-paginated-thread-facts.d.ts +2 -3
- package/dist/src/codex-paginated-watch.d.ts +1 -1
- package/dist/src/codex-paginated-watch.js +19 -2
- package/dist/src/codex-paginated-watch.js.map +1 -1
- package/dist/src/codex-permission-surface.d.ts +23 -0
- package/dist/src/codex-permission-surface.js +211 -0
- package/dist/src/codex-permission-surface.js.map +1 -0
- package/dist/src/codex-status-history-navigation.js +4 -3
- package/dist/src/codex-status-history-navigation.js.map +1 -1
- package/dist/src/codex-terminal-agent-adapter.js +28 -12
- package/dist/src/codex-terminal-agent-adapter.js.map +1 -1
- package/dist/src/native-thread-lifecycle-cli-adapter.d.ts +5 -4
- package/dist/src/native-thread-lifecycle-cli-adapter.js +20 -0
- package/dist/src/native-thread-lifecycle-cli-adapter.js.map +1 -1
- package/dist/src/semantic-permission-control.d.ts +19 -0
- package/dist/src/semantic-permission-control.js +174 -0
- package/dist/src/semantic-permission-control.js.map +1 -0
- package/dist/src/semantic-tool-command-helpers.d.ts +7 -0
- package/dist/src/semantic-tool-command-helpers.js +29 -1
- package/dist/src/semantic-tool-command-helpers.js.map +1 -1
- package/dist/src/semantic-tool-list-projection.js +4 -0
- package/dist/src/semantic-tool-list-projection.js.map +1 -1
- package/dist/src/semantic-tool-presentation.js +5 -2
- package/dist/src/semantic-tool-presentation.js.map +1 -1
- package/dist/src/semantic-tool-runtime.js +7 -1
- package/dist/src/semantic-tool-runtime.js.map +1 -1
- package/dist/src/semantic-tool-schemas.d.ts +33 -0
- package/dist/src/semantic-tool-schemas.js +33 -0
- package/dist/src/semantic-tool-schemas.js.map +1 -1
- package/dist/src/store.d.ts +1 -1
- package/dist/src/store.js +2 -2
- package/dist/src/store.js.map +1 -1
- package/dist/src/terminal-action-projection.d.ts +1 -1
- package/dist/src/terminal-action-projection.js.map +1 -1
- package/dist/src/terminal-agent-bridge.d.ts +3 -0
- package/dist/src/terminal-agent-bridge.js +45 -6
- package/dist/src/terminal-agent-bridge.js.map +1 -1
- package/dist/src/terminal-composer-classifier.js +31 -5
- package/dist/src/terminal-composer-classifier.js.map +1 -1
- package/dist/src/terminal-human-explicit-send-cli-adapter.js +11 -0
- package/dist/src/terminal-human-explicit-send-cli-adapter.js.map +1 -1
- package/dist/src/terminal-list-cli-adapter.js +7 -12
- package/dist/src/terminal-list-cli-adapter.js.map +1 -1
- package/dist/src/terminal-list-renderer.d.ts +7 -0
- package/dist/src/terminal-list-renderer.js +53 -0
- package/dist/src/terminal-list-renderer.js.map +1 -1
- package/dist/src/terminal-monitor-decision-policy.d.ts +1 -1
- package/dist/src/terminal-native-control-cli-contract.d.ts +16 -0
- package/dist/src/terminal-native-control-cli-contract.js +2 -0
- package/dist/src/terminal-native-control-cli-contract.js.map +1 -0
- package/dist/src/terminal-native-inspection-bridge.js +34 -25
- package/dist/src/terminal-native-inspection-bridge.js.map +1 -1
- package/dist/src/terminal-permission-control-availability.d.ts +31 -0
- package/dist/src/terminal-permission-control-availability.js +50 -0
- package/dist/src/terminal-permission-control-availability.js.map +1 -0
- package/dist/src/terminal-permission-control-bridge.d.ts +16 -0
- package/dist/src/terminal-permission-control-bridge.js +93 -0
- package/dist/src/terminal-permission-control-bridge.js.map +1 -0
- package/dist/src/terminal-permission-control-cli-adapter.d.ts +31 -0
- package/dist/src/terminal-permission-control-cli-adapter.js +152 -0
- package/dist/src/terminal-permission-control-cli-adapter.js.map +1 -0
- package/dist/src/terminal-permission-control-list-projection.d.ts +23 -0
- package/dist/src/terminal-permission-control-list-projection.js +47 -0
- package/dist/src/terminal-permission-control-list-projection.js.map +1 -0
- package/dist/src/terminal-permission-control-runtime.d.ts +28 -0
- package/dist/src/terminal-permission-control-runtime.js +88 -0
- package/dist/src/terminal-permission-control-runtime.js.map +1 -0
- package/dist/src/terminal-permission-control.d.ts +69 -0
- package/dist/src/terminal-permission-control.js +217 -0
- package/dist/src/terminal-permission-control.js.map +1 -0
- package/dist/src/terminal-send-watch-policy.js +9 -12
- package/dist/src/terminal-send-watch-policy.js.map +1 -1
- package/dist/src/terminal-watch-cli-adapter.d.ts +5 -10
- package/dist/src/terminal-watch-cli-adapter.js +51 -32
- package/dist/src/terminal-watch-cli-adapter.js.map +1 -1
- package/dist/src/terminal-watch-codec.js +11 -2
- package/dist/src/terminal-watch-codec.js.map +1 -1
- package/dist/src/terminal-watch-record.d.ts +8 -1
- package/dist/src/terminal-watch-record.js +16 -2
- package/dist/src/terminal-watch-record.js.map +1 -1
- package/dist/src/terminal-watch-send-activity.d.ts +28 -0
- package/dist/src/terminal-watch-send-activity.js +65 -0
- package/dist/src/terminal-watch-send-activity.js.map +1 -0
- package/dist/src/terminal-watch-service.d.ts +5 -0
- package/dist/src/terminal-watch-service.js +53 -6
- package/dist/src/terminal-watch-service.js.map +1 -1
- package/docs/callback-compatibility.md +84 -0
- package/docs/codex-permissions.md +95 -0
- package/openclaw.plugin.json +9 -1
- package/package.json +4 -2
- package/templates/openclaw-skills/agent-knock-knock/SKILL.md +21 -16
|
@@ -0,0 +1,217 @@
|
|
|
1
|
+
import { createHash } from "node:crypto";
|
|
2
|
+
import { terminalPhysicalBindingToken } from "./terminal-control-ref.js";
|
|
3
|
+
/** Permission writes have their own reviewed UI contract, separate from reads/model control. */
|
|
4
|
+
export function terminalPermissionControlProfileFor(version) {
|
|
5
|
+
return ["0.159.2", "0.159.3"].includes(version)
|
|
6
|
+
? { agentVersion: version, behaviorProfile: "codex-permissions-fullscreen-v1", scope: "current_session" }
|
|
7
|
+
: undefined;
|
|
8
|
+
}
|
|
9
|
+
export function terminalPermissionControlBindingToken(value) {
|
|
10
|
+
const profile = terminalPermissionControlProfileFor(value.agentVersion);
|
|
11
|
+
if (!profile || profile.behaviorProfile !== value.behaviorProfile) {
|
|
12
|
+
throw new Error("unsupported native permission-control profile");
|
|
13
|
+
}
|
|
14
|
+
return digest({
|
|
15
|
+
authority: "terminal_permission_control", version: 1,
|
|
16
|
+
physical: terminalPhysicalBindingToken({ ...value, agent: "codex" }),
|
|
17
|
+
agentVersion: value.agentVersion, behaviorProfile: value.behaviorProfile
|
|
18
|
+
});
|
|
19
|
+
}
|
|
20
|
+
/** A transport failure may have delivered input; no cleanup or retry follows it. */
|
|
21
|
+
export class TerminalPermissionInputUncertainError extends Error {
|
|
22
|
+
doNotRetry = true;
|
|
23
|
+
}
|
|
24
|
+
export function permissionModeFromStatus(value) {
|
|
25
|
+
if (value === "Full Access")
|
|
26
|
+
return "full_access";
|
|
27
|
+
if (value === "Workspace (Ask for approval)")
|
|
28
|
+
return "ask_for_approval";
|
|
29
|
+
if (value === "Workspace (Approve for me)")
|
|
30
|
+
return "approve_for_me";
|
|
31
|
+
if (value === "Read Only (Ask for approval)" || value === "Read Only")
|
|
32
|
+
return "read_only";
|
|
33
|
+
return undefined;
|
|
34
|
+
}
|
|
35
|
+
async function waitFor(ports, state) {
|
|
36
|
+
for (let attempt = 0; attempt < 35; attempt += 1) {
|
|
37
|
+
const captured = await ports.capture();
|
|
38
|
+
if (captured.state === state)
|
|
39
|
+
return captured;
|
|
40
|
+
await ports.sleep(100);
|
|
41
|
+
}
|
|
42
|
+
throw new Error(`Codex permission control did not prove its ${state} postcondition`);
|
|
43
|
+
}
|
|
44
|
+
async function openPicker(ports) {
|
|
45
|
+
const empty = await ports.capture();
|
|
46
|
+
if (empty.state !== "idle")
|
|
47
|
+
throw new Error("permission control requires an idle, exactly empty Codex Composer");
|
|
48
|
+
await ports.input("command", empty);
|
|
49
|
+
await ports.input("C-m", await waitFor(ports, "command"));
|
|
50
|
+
return await waitFor(ports, "picker");
|
|
51
|
+
}
|
|
52
|
+
async function dismiss(ports, picker) {
|
|
53
|
+
await ports.input("Escape", picker);
|
|
54
|
+
await waitFor(ports, "idle");
|
|
55
|
+
}
|
|
56
|
+
function catalog(profile, status, picker) {
|
|
57
|
+
const current = picker.rows.filter((row) => row.current);
|
|
58
|
+
if (current.length > 1 || current.length === 1 && current[0].id !== status.mode ||
|
|
59
|
+
current.length === 0 && picker.rows.some((row) => row.id === status.mode)) {
|
|
60
|
+
throw new Error("native permission menu and fresh /status disagree about current permissions");
|
|
61
|
+
}
|
|
62
|
+
const choices = picker.rows.map(({ id, label, description }) => ({
|
|
63
|
+
id, label, description
|
|
64
|
+
}));
|
|
65
|
+
return {
|
|
66
|
+
agent: "codex", ...profile, current: status.mode, choices,
|
|
67
|
+
catalogFingerprint: digest({ ...profile, threadId: status.threadId, current: status.mode, choices })
|
|
68
|
+
};
|
|
69
|
+
}
|
|
70
|
+
/** Only clean up a freshly re-proven surface owned by this operation. */
|
|
71
|
+
async function cleanup(ports) {
|
|
72
|
+
const frame = await ports.capture();
|
|
73
|
+
if (frame.state === "picker")
|
|
74
|
+
return dismiss(ports, frame);
|
|
75
|
+
if (frame.state === "command") {
|
|
76
|
+
await ports.input("Escape", frame);
|
|
77
|
+
const bare = await waitFor(ports, "bare_command");
|
|
78
|
+
await ports.input("C-u", bare);
|
|
79
|
+
await waitFor(ports, "idle");
|
|
80
|
+
}
|
|
81
|
+
else if (frame.state === "bare_command") {
|
|
82
|
+
await ports.input("C-u", frame);
|
|
83
|
+
await waitFor(ports, "idle");
|
|
84
|
+
}
|
|
85
|
+
else if (frame.state !== "idle") {
|
|
86
|
+
throw new TerminalPermissionInputUncertainError("permission cleanup cannot prove an empty Composer; do not retry automatically");
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
export async function discoverTerminalPermissionOptions(profile, ports) {
|
|
90
|
+
// Fresh status binds the catalog to a native thread, including paginated sessions
|
|
91
|
+
// with no open rollout. No app-server write or persistent AKK Session is needed.
|
|
92
|
+
const status = await ports.inspectStatus();
|
|
93
|
+
try {
|
|
94
|
+
const picker = await openPicker(ports);
|
|
95
|
+
const result = catalog(profile, status, picker);
|
|
96
|
+
await dismiss(ports, picker);
|
|
97
|
+
return result;
|
|
98
|
+
}
|
|
99
|
+
catch (error) {
|
|
100
|
+
if (!(error instanceof TerminalPermissionInputUncertainError)) {
|
|
101
|
+
try {
|
|
102
|
+
await cleanup(ports);
|
|
103
|
+
}
|
|
104
|
+
catch (cause) {
|
|
105
|
+
throw new TerminalPermissionInputUncertainError("native permission cleanup is uncertain; do not retry automatically", { cause });
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
throw error;
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
export async function switchTerminalPermissions(profile, mode, expectedCatalogFingerprint, ports) {
|
|
112
|
+
if (!["ask_for_approval", "approve_for_me", "full_access", "read_only"].includes(mode)) {
|
|
113
|
+
throw new Error("permission mode must come from the current native permission catalog");
|
|
114
|
+
}
|
|
115
|
+
let status;
|
|
116
|
+
try {
|
|
117
|
+
status = await ports.inspectStatus();
|
|
118
|
+
}
|
|
119
|
+
catch (error) {
|
|
120
|
+
if (error instanceof TerminalPermissionInputUncertainError)
|
|
121
|
+
return uncertain(mode);
|
|
122
|
+
throw error;
|
|
123
|
+
}
|
|
124
|
+
let selectionAttempted = false;
|
|
125
|
+
try {
|
|
126
|
+
let picker = await openPicker(ports);
|
|
127
|
+
const offered = catalog(profile, status, picker);
|
|
128
|
+
if (offered.catalogFingerprint !== expectedCatalogFingerprint) {
|
|
129
|
+
throw new Error("native thread or permission catalog changed; refresh permission-options");
|
|
130
|
+
}
|
|
131
|
+
const target = picker.rows.find((row) => row.id === mode);
|
|
132
|
+
if (!target)
|
|
133
|
+
throw new Error("requested permission mode is not available in this native menu");
|
|
134
|
+
if (mode === offered.current) {
|
|
135
|
+
await dismiss(ports, picker);
|
|
136
|
+
return success("already_effective", mode);
|
|
137
|
+
}
|
|
138
|
+
picker = await selectPermissionRow(profile, status, picker, target.index, offered.catalogFingerprint, ports);
|
|
139
|
+
selectionAttempted = true;
|
|
140
|
+
await ports.input("C-m", picker);
|
|
141
|
+
if (mode === "full_access")
|
|
142
|
+
await confirmFullAccess(ports);
|
|
143
|
+
await verifyPermissionSelection(profile, status, mode, ports);
|
|
144
|
+
return success("changed", mode);
|
|
145
|
+
}
|
|
146
|
+
catch (error) {
|
|
147
|
+
if (selectionAttempted || error instanceof TerminalPermissionInputUncertainError) {
|
|
148
|
+
return uncertain(mode);
|
|
149
|
+
}
|
|
150
|
+
try {
|
|
151
|
+
await cleanup(ports);
|
|
152
|
+
}
|
|
153
|
+
catch {
|
|
154
|
+
return uncertain(mode);
|
|
155
|
+
}
|
|
156
|
+
throw error;
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
async function selectPermissionRow(profile, status, initial, targetIndex, fingerprint, ports) {
|
|
160
|
+
let picker = initial;
|
|
161
|
+
for (let moves = 0; picker.selectedIndex !== targetIndex; moves += 1) {
|
|
162
|
+
if (moves >= picker.rows.length)
|
|
163
|
+
throw new Error("native permission selection did not converge");
|
|
164
|
+
const expectedIndex = picker.selectedIndex + (picker.selectedIndex < targetIndex ? 1 : -1);
|
|
165
|
+
await ports.input(picker.selectedIndex < targetIndex ? "Down" : "Up", picker);
|
|
166
|
+
picker = await waitForSelection(ports, "picker", expectedIndex);
|
|
167
|
+
if (catalog(profile, status, picker).catalogFingerprint !== fingerprint) {
|
|
168
|
+
throw new Error("native permission catalog changed during selection");
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
return picker;
|
|
172
|
+
}
|
|
173
|
+
async function confirmFullAccess(ports) {
|
|
174
|
+
let confirmation = await waitFor(ports, "full_access_confirmation");
|
|
175
|
+
if (confirmation.state !== "full_access_confirmation")
|
|
176
|
+
throw new Error("full-access confirmation is unavailable");
|
|
177
|
+
if (confirmation.selectedIndex !== 0) {
|
|
178
|
+
await ports.input("Up", confirmation);
|
|
179
|
+
confirmation = await waitForSelection(ports, "full_access_confirmation", 0);
|
|
180
|
+
}
|
|
181
|
+
await ports.input("C-m", confirmation);
|
|
182
|
+
}
|
|
183
|
+
async function verifyPermissionSelection(profile, previous, mode, ports) {
|
|
184
|
+
await waitFor(ports, "idle");
|
|
185
|
+
// A request echo is not completion. Fresh /status plus a reopened current
|
|
186
|
+
// menu marker must independently agree about this same native thread.
|
|
187
|
+
const effective = await ports.inspectStatus();
|
|
188
|
+
if (effective.threadId !== previous.threadId || effective.mode !== mode) {
|
|
189
|
+
throw new Error("native permission update was not proven on the original thread");
|
|
190
|
+
}
|
|
191
|
+
const verified = await openPicker(ports);
|
|
192
|
+
if (catalog(profile, effective, verified).current !== mode ||
|
|
193
|
+
!verified.rows.some((row) => row.id === mode && row.current)) {
|
|
194
|
+
throw new Error("native permission menu did not confirm the requested current mode");
|
|
195
|
+
}
|
|
196
|
+
await dismiss(ports, verified);
|
|
197
|
+
}
|
|
198
|
+
async function waitForSelection(ports, state, index) {
|
|
199
|
+
for (let attempt = 0; attempt < 35; attempt += 1) {
|
|
200
|
+
const frame = await ports.capture();
|
|
201
|
+
if (frame.state === state && frame.selectedIndex === index)
|
|
202
|
+
return frame;
|
|
203
|
+
await ports.sleep(100);
|
|
204
|
+
}
|
|
205
|
+
throw new Error("Codex permission selection did not match its expected row");
|
|
206
|
+
}
|
|
207
|
+
function success(outcome, mode) {
|
|
208
|
+
return { outcome, requested: { mode }, effective: { mode }, scope: "current_session", defaultsChanged: false, doNotRetry: false };
|
|
209
|
+
}
|
|
210
|
+
function uncertain(mode) {
|
|
211
|
+
return { outcome: "uncertain", requested: { mode }, scope: "current_session", defaultsChanged: false,
|
|
212
|
+
doNotRetry: true, reason: "Native permission input or its postcondition is uncertain; inspect the terminal and refresh permissions before another deliberate action." };
|
|
213
|
+
}
|
|
214
|
+
function digest(value) {
|
|
215
|
+
return createHash("sha256").update(JSON.stringify(value)).digest("hex");
|
|
216
|
+
}
|
|
217
|
+
//# sourceMappingURL=terminal-permission-control.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"terminal-permission-control.js","sourceRoot":"","sources":["../../src/terminal-permission-control.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,17 +1,12 @@
|
|
|
1
|
-
import {
|
|
2
|
-
const
|
|
3
|
-
"0.157.0",
|
|
4
|
-
"0.157.1",
|
|
5
|
-
"0.158.0",
|
|
6
|
-
"0.159.0",
|
|
7
|
-
"0.159.2"
|
|
8
|
-
]);
|
|
1
|
+
import { isCodexPaginatedReadCandidate } from "./codex-lifecycle-compatibility.js";
|
|
2
|
+
const CODEX_PRE_READ_CONTRACT_PAGINATED_VERSIONS = new Set(["0.157.0", "0.157.1"]);
|
|
9
3
|
/** New physical Sends can acquire a paginated task anchor before task input. */
|
|
10
4
|
export function codexPhysicalSendUsesPaginatedWatch(agentVersion) {
|
|
11
|
-
return
|
|
5
|
+
return isCodexPaginatedReadCandidate(agentVersion);
|
|
12
6
|
}
|
|
13
7
|
export function codexManagedSendRequiresLegacyHistory(agentVersion) {
|
|
14
|
-
return
|
|
8
|
+
return isCodexPaginatedReadCandidate(agentVersion) ||
|
|
9
|
+
CODEX_PRE_READ_CONTRACT_PAGINATED_VERSIONS.has(agentVersion ?? "");
|
|
15
10
|
}
|
|
16
11
|
/** Managed Monitor still consumes legacy rollouts, never paginated thread data. */
|
|
17
12
|
export function assertCodexManagedSendHasLegacyHistory(input) {
|
|
@@ -29,7 +24,7 @@ export function assertCodexManagedSendHasLegacyHistory(input) {
|
|
|
29
24
|
export function selectCodexUserExplicitSendWatchSource(input) {
|
|
30
25
|
if (input.paginatedAnchorAvailable)
|
|
31
26
|
return { source: "codex_paginated" };
|
|
32
|
-
if (
|
|
27
|
+
if (codexManagedSendRequiresLegacyHistory(input.agentVersion) &&
|
|
33
28
|
!(Number.isSafeInteger(input.legacyRootCount) &&
|
|
34
29
|
Number(input.legacyRootCount) > 0)) {
|
|
35
30
|
return {
|
|
@@ -37,7 +32,9 @@ export function selectCodexUserExplicitSendWatchSource(input) {
|
|
|
37
32
|
reasonCode: "codex_paginated_history_anchor_unavailable",
|
|
38
33
|
warning: `Codex ${input.agentVersion} has no verified legacy root ` +
|
|
39
34
|
"rollout or exact paginated history anchor. The message can still be " +
|
|
40
|
-
"sent, but no
|
|
35
|
+
"sent, but no exact-task completion callback can be established. " +
|
|
36
|
+
"A best-effort terminal-activity Watch may still be attached after " +
|
|
37
|
+
"physical identity and screen-status validation."
|
|
41
38
|
};
|
|
42
39
|
}
|
|
43
40
|
return { source: "codex_rollout" };
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"terminal-send-watch-policy.js","sourceRoot":"","sources":["../../src/terminal-send-watch-policy.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"terminal-send-watch-policy.js","sourceRoot":"","sources":["../../src/terminal-send-watch-policy.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,6BAA6B,EAAE,MAAM,oCAAoC,CAAC;AACnF,MAAM,0CAA0C,GAAG,IAAI,GAAG,CAAC,CAAC,SAAS,EAAE,SAAS,CAAC,CAAC,CAAC;AAEnF,gFAAgF;AAChF,MAAM,UAAU,mCAAmC,CAAC,YAAqB;IACvE,OAAO,6BAA6B,CAAC,YAAY,CAAC,CAAC;AACrD,CAAC;AAED,MAAM,UAAU,qCAAqC,CAAC,YAAqB;IACzE,OAAO,6BAA6B,CAAC,YAAY,CAAC;QAChD,0CAA0C,CAAC,GAAG,CAAC,YAAY,IAAI,EAAE,CAAC,CAAC;AACvE,CAAC;AAED,mFAAmF;AACnF,MAAM,UAAU,sCAAsC,CAAC,KAGtD;IACC,IAAI,CAAC,qCAAqC,CAAC,KAAK,CAAC,YAAY,CAAC;QAAE,OAAO;IACvE,IAAI,MAAM,CAAC,aAAa,CAAC,KAAK,CAAC,uBAAuB,CAAC;QACnD,KAAK,CAAC,uBAAuB,GAAG,CAAC;QAAE,OAAO;IAC9C,MAAM,IAAI,KAAK,CACb,QAAQ,GAAG,KAAK,CAAC,YAAY,GAAG,sCAAsC;QACtE,wEAAwE;QACxE,yEAAyE;QACzE,iDAAiD,CAClD,CAAC;AACJ,CAAC;AAWD,8EAA8E;AAC9E,MAAM,UAAU,sCAAsC,CAAC,KAMtD;IACC,IAAI,KAAK,CAAC,wBAAwB;QAAE,OAAO,EAAE,MAAM,EAAE,iBAAiB,EAAE,CAAC;IACzE,IACE,qCAAqC,CAAC,KAAK,CAAC,YAAY,CAAC;QACzD,CAAC,CAAC,MAAM,CAAC,aAAa,CAAC,KAAK,CAAC,eAAe,CAAC;YAC3C,MAAM,CAAC,KAAK,CAAC,eAAe,CAAC,GAAG,CAAC,CAAC,EACpC,CAAC;QACD,OAAO;YACL,MAAM,EAAE,MAAM;YACd,UAAU,EAAE,4CAA4C;YACxD,OAAO,EAAE,SAAS,KAAK,CAAC,YAAY,+BAA+B;gBACjE,sEAAsE;gBACtE,kEAAkE;gBAClE,oEAAoE;gBACpE,iDAAiD;SACpD,CAAC;IACJ,CAAC;IACD,OAAO,EAAE,MAAM,EAAE,eAAe,EAAE,CAAC;AACrC,CAAC;AAUD,MAAM,UAAU,qCAAqC,CACnD,OAAqD;IAOrD,IAAI,CAAC,OAAO,EAAE,iBAAiB,EAAE,CAAC;QAChC,OAAO;YACL,iBAAiB,EAAE,KAAK;YACxB,aAAa,EAAE,EAAE,iBAAiB,EAAE,KAAK,EAAE;YAC3C,OAAO,EAAE,sCAAsC;YAC/C,UAAU,EAAE,oDAAoD;gBAC9D,qCAAqC;SACxC,CAAC;IACJ,CAAC;IACD,uEAAuE;IACvE,wEAAwE;IACxE,MAAM,QAAQ,GAAG,OAAO,CAAC,UAAU,KAAK,mBAAmB;QACzD,OAAO,CAAC,UAAU,KAAK,aAAa,CAAC;IACvC,OAAO;QACL,iBAAiB,EAAE,IAAI;QACvB,aAAa,EAAE;YACb,GAAG,OAAO;YACV,UAAU,EAAE,QAAQ,CAAC,CAAC,CAAC,mBAAmB,CAAC,CAAC,CAAC,YAAY;YACzD,UAAU,EAAE,QAAQ,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,OAAO;SAC/C;QACD,OAAO,EAAE,QAAQ;YACf,CAAC,CAAC,kBAAkB,OAAO,CAAC,QAAQ,iCAAiC;gBACnE,qEAAqE;gBACrE,4DAA4D;YAC9D,CAAC,CAAC,kBAAkB,OAAO,CAAC,QAAQ,kCAAkC;gBACpE,yDAAyD;QAC7D,UAAU,EAAE,QAAQ;YAClB,CAAC,CAAC,yBAAyB,OAAO,CAAC,QAAQ,6BAA6B;gBACtE,kEAAkE;gBAClE,sBAAsB;YACxB,CAAC,CAAC,2BAA2B,OAAO,CAAC,QAAQ,aAAa;gBACxD,6CAA6C;KAClD,CAAC;AACJ,CAAC"}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { type UserExplicitFallbackWatchReceipt } from "./terminal-watch-send-activity.js";
|
|
1
2
|
import { readCodexPaginatedTaskSnapshot } from "./codex-paginated-observation.js";
|
|
2
3
|
import { type CodexPaginatedTaskAnchor } from "./codex-paginated-task.js";
|
|
3
4
|
import { capturePaginatedWatchAnchor as capturePaginatedAnchor } from "./codex-paginated-watch.js";
|
|
@@ -9,7 +10,7 @@ import { type Conversation } from "./protocol.js";
|
|
|
9
10
|
import { type TerminalDispatchOwnership } from "./terminal-action-projection.js";
|
|
10
11
|
import type { TerminalControlEvidence, TerminalControlRef } from "./terminal-control-ref.js";
|
|
11
12
|
import { type TerminalWatchCallbackCliAdapter } from "./terminal-watch-callback-cli-adapter.js";
|
|
12
|
-
import { type TerminalWatchTerminalIdentity, type UserExplicitFallbackWatchAnchor } from "./terminal-watch-store.js";
|
|
13
|
+
import { type TerminalWatchTerminalIdentity, type TerminalActivityWatchAnchor, type UserExplicitFallbackWatchAnchor } from "./terminal-watch-store.js";
|
|
13
14
|
export interface TerminalWatchCliOptions {
|
|
14
15
|
callbackRoute?: CallbackRouteV1;
|
|
15
16
|
/** Private Host-adapter authority describing how a route template is bound. */
|
|
@@ -42,15 +43,10 @@ export interface PreparedUserExplicitFallbackWatch {
|
|
|
42
43
|
openclawSession: string;
|
|
43
44
|
openclawBin: string;
|
|
44
45
|
timeoutMs: number;
|
|
45
|
-
anchor: UserExplicitFallbackWatchAnchor | CodexPaginatedTaskAnchor;
|
|
46
|
-
|
|
47
|
-
export interface UserExplicitFallbackWatchReceipt {
|
|
48
|
-
callback_expected: true;
|
|
49
|
-
callback_mode: "terminal_watch";
|
|
50
|
-
watch_id: string;
|
|
51
|
-
watch_mode?: "exact_task" | "terminal_activity";
|
|
52
|
-
confidence?: "exact" | "best_effort";
|
|
46
|
+
anchor: UserExplicitFallbackWatchAnchor | CodexPaginatedTaskAnchor | TerminalActivityWatchAnchor;
|
|
47
|
+
warnings?: string[];
|
|
53
48
|
}
|
|
49
|
+
export type { UserExplicitFallbackWatchReceipt } from "./terminal-watch-send-activity.js";
|
|
54
50
|
type ExactTerminalWatchObservation = {
|
|
55
51
|
state: "available";
|
|
56
52
|
rawTerminal: Record<string, unknown>;
|
|
@@ -120,4 +116,3 @@ export interface TerminalWatchCliFacade {
|
|
|
120
116
|
};
|
|
121
117
|
}
|
|
122
118
|
export declare function createTerminalWatchCliAdapter(dependencies: TerminalWatchCliDependencies): TerminalWatchCliFacade;
|
|
123
|
-
export {};
|
|
@@ -1,10 +1,11 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { assertAutomaticActivityWatchIdentity, automaticSendWatchReceipt, createAutomaticActivityWatchAnchor, isAutomaticSendWatch, unsafeFallbackWatchPreparation } from "./terminal-watch-send-activity.js";
|
|
2
|
+
import { isCodexPaginatedReadCandidate } from "./codex-lifecycle-compatibility.js";
|
|
2
3
|
import { respondCodexPaginatedAsyncQuestion } from "./codex-paginated-async-response.js";
|
|
3
4
|
import { publicTerminalWatch, terminalWatchCapturedAgentVersion } from "./terminal-watch-presentation.js";
|
|
4
5
|
import { createHash } from "node:crypto";
|
|
5
6
|
import path from "node:path";
|
|
6
7
|
import { CodexLegacyThreadHistoryError } from "./codex-paginated-observation.js";
|
|
7
|
-
import { capturePaginatedWatchAnchor as capturePaginatedAnchor,
|
|
8
|
+
import { capturePaginatedWatchAnchor as capturePaginatedAnchor, paginatedWatchProcessMatches, observePaginatedWatch, refreshPaginatedResponseForeground } from "./codex-paginated-watch.js";
|
|
8
9
|
import { observeCodexPaginatedBlockingQuestion, respondCodexPaginatedBlockingQuestion } from "./codex-paginated-questionnaire-runtime.js";
|
|
9
10
|
import { selectCodexUserExplicitSendWatchSource } from "./terminal-send-watch-policy.js";
|
|
10
11
|
import { callbackRouteFingerprint } from "./callback-route-authority.js";
|
|
@@ -117,17 +118,39 @@ export function createTerminalWatchCliAdapter(dependencies) {
|
|
|
117
118
|
});
|
|
118
119
|
}
|
|
119
120
|
async function prepareUserExplicitFallbackWatch(input) {
|
|
120
|
-
|
|
121
|
+
let callbackRoute = callbackRouteForUserExplicitFallback(input.options);
|
|
121
122
|
if (!callbackRoute)
|
|
122
123
|
return undefined;
|
|
123
124
|
await bestEffortStabilizePriorFallbackWatch(input.options, input.terminal.conversationId, input.requestHash);
|
|
124
125
|
const observed = await exactTerminalForWatch(input.terminal.conversationId, input.options, dependencies);
|
|
125
126
|
const rawTerminal = observed.rawTerminal;
|
|
126
127
|
assertSameUserExplicitFallbackTerminal(input.terminal, rawTerminal);
|
|
127
|
-
const
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
128
|
+
const warnings = [];
|
|
129
|
+
let anchor;
|
|
130
|
+
try {
|
|
131
|
+
const agentVersion = requiredString(rawTerminal.agent_version, "running coding-agent version");
|
|
132
|
+
anchor = input.terminal.agent === "codex"
|
|
133
|
+
? await captureCodexFallbackWatchAnchor(input, rawTerminal, agentVersion, dependencies)
|
|
134
|
+
: captureClaudeFallbackWatchAnchor(input, rawTerminal, agentVersion, dependencies);
|
|
135
|
+
}
|
|
136
|
+
catch (error) {
|
|
137
|
+
// A failed/uncertain native-input transaction is not an observation
|
|
138
|
+
// failure. Never turn it into permission to dispatch the user's task.
|
|
139
|
+
if (unsafeFallbackWatchPreparation(error))
|
|
140
|
+
throw error;
|
|
141
|
+
const current = await exactTerminalForWatch(input.terminal.conversationId, input.options, dependencies);
|
|
142
|
+
assertSameUserExplicitFallbackTerminal(input.terminal, current.rawTerminal);
|
|
143
|
+
anchor = createAutomaticActivityWatchAnchor({
|
|
144
|
+
capturedAt: dependencies.now(), terminalId: input.terminal.conversationId,
|
|
145
|
+
pid: input.terminal.pid, requestHash: input.requestHash,
|
|
146
|
+
before: rawTerminal, current: current.rawTerminal,
|
|
147
|
+
previousWorkspace: terminalWorkspace(rawTerminal),
|
|
148
|
+
currentWorkspace: terminalWorkspace(current.rawTerminal),
|
|
149
|
+
control: terminalControlForWatch(current.rawTerminal)
|
|
150
|
+
});
|
|
151
|
+
callbackRoute = terminalWatchNotificationOnlyRoute(callbackRoute);
|
|
152
|
+
warnings.push(`exact_task_anchor_unavailable: ${safeDiagnostic(error)}`, "terminal_activity_fallback: observing post-Send terminal/process activity; stable idle is not exact task completion");
|
|
153
|
+
}
|
|
131
154
|
return {
|
|
132
155
|
watchId: terminalUserExplicitFallbackWatchId({
|
|
133
156
|
messageId: input.messageId,
|
|
@@ -144,6 +167,7 @@ export function createTerminalWatchCliAdapter(dependencies) {
|
|
|
144
167
|
callbackRoute,
|
|
145
168
|
openclawSession: callbackRoute.controller_session_id,
|
|
146
169
|
openclawBin: stringValue(input.options.openclawBin) ?? "openclaw",
|
|
170
|
+
...(warnings.length > 0 ? { warnings } : {}),
|
|
147
171
|
timeoutMs: positiveMinutes(input.options.hardTimeoutMinutes ??
|
|
148
172
|
input.options.agentHardTimeoutMinutes, DEFAULT_TERMINAL_WATCH_HARD_TIMEOUT_MINUTES) * 60_000,
|
|
149
173
|
anchor
|
|
@@ -159,15 +183,16 @@ export function createTerminalWatchCliAdapter(dependencies) {
|
|
|
159
183
|
}
|
|
160
184
|
catch {
|
|
161
185
|
// Observation itself is best effort after the user's physical Send.
|
|
162
|
-
// Persist the exact pre-Send identity
|
|
163
|
-
//
|
|
186
|
+
// Persist the exact pre-Send identity: native evidence may recover a
|
|
187
|
+
// result; activity Watches must wait for a matching live observation.
|
|
164
188
|
}
|
|
165
189
|
if (observed?.state === "available") {
|
|
166
190
|
assertPreparedFallbackTerminal(input.prepared, observed.rawTerminal);
|
|
167
191
|
}
|
|
168
192
|
// An absent or temporarily unavailable terminal after Enter is not a
|
|
169
|
-
// callback veto.
|
|
170
|
-
//
|
|
193
|
+
// callback veto. Exact anchors may recover an on-disk completion;
|
|
194
|
+
// activity anchors preserve their process fence and can only report loss
|
|
195
|
+
// or resume observation, never infer completion from disappearance.
|
|
171
196
|
const service = serviceFor(input.options);
|
|
172
197
|
let watch;
|
|
173
198
|
try {
|
|
@@ -176,6 +201,7 @@ export function createTerminalWatchCliAdapter(dependencies) {
|
|
|
176
201
|
agent: input.prepared.agent,
|
|
177
202
|
terminal: input.prepared.terminalIdentity,
|
|
178
203
|
anchor: input.prepared.anchor,
|
|
204
|
+
warnings: input.prepared.warnings,
|
|
179
205
|
callback_route: input.prepared.callbackRoute,
|
|
180
206
|
openclaw_session: input.prepared.openclawSession,
|
|
181
207
|
openclaw_bin: input.prepared.openclawBin,
|
|
@@ -185,20 +211,14 @@ export function createTerminalWatchCliAdapter(dependencies) {
|
|
|
185
211
|
catch (error) {
|
|
186
212
|
const existing = service.list().find((candidate) => candidate.watch_id === input.prepared.watchId);
|
|
187
213
|
if (!existing ||
|
|
188
|
-
!(
|
|
214
|
+
!isAutomaticSendWatch(existing) ||
|
|
189
215
|
existing.anchor.anchor_fingerprint !==
|
|
190
216
|
input.prepared.anchor.anchor_fingerprint) {
|
|
191
217
|
throw error;
|
|
192
218
|
}
|
|
193
219
|
watch = existing;
|
|
194
220
|
}
|
|
195
|
-
return
|
|
196
|
-
callback_expected: true,
|
|
197
|
-
callback_mode: "terminal_watch",
|
|
198
|
-
watch_id: watch.watch_id,
|
|
199
|
-
watch_mode: "exact_task",
|
|
200
|
-
confidence: "exact"
|
|
201
|
-
};
|
|
221
|
+
return automaticSendWatchReceipt(watch);
|
|
202
222
|
}
|
|
203
223
|
async function bestEffortStabilizePriorFallbackWatch(options, terminalId, requestHash) {
|
|
204
224
|
try {
|
|
@@ -224,16 +244,10 @@ export function createTerminalWatchCliAdapter(dependencies) {
|
|
|
224
244
|
function userExplicitFallbackWatchReceipt(input) {
|
|
225
245
|
try {
|
|
226
246
|
const watch = serviceFor(input.options).get(input.watchId);
|
|
227
|
-
if (!(
|
|
247
|
+
if (!isAutomaticSendWatch(watch) || !watch.callback_route) {
|
|
228
248
|
return undefined;
|
|
229
249
|
}
|
|
230
|
-
return
|
|
231
|
-
callback_expected: true,
|
|
232
|
-
callback_mode: "terminal_watch",
|
|
233
|
-
watch_id: watch.watch_id,
|
|
234
|
-
watch_mode: "exact_task",
|
|
235
|
-
confidence: "exact"
|
|
236
|
-
};
|
|
250
|
+
return automaticSendWatchReceipt(watch);
|
|
237
251
|
}
|
|
238
252
|
catch {
|
|
239
253
|
return undefined;
|
|
@@ -257,7 +271,7 @@ export function createTerminalWatchCliAdapter(dependencies) {
|
|
|
257
271
|
const warnings = [];
|
|
258
272
|
let anchor;
|
|
259
273
|
try {
|
|
260
|
-
anchor = agent === "codex" &&
|
|
274
|
+
anchor = agent === "codex" && isCodexPaginatedReadCandidate(rawTerminal.agent_version)
|
|
261
275
|
? await capturePaginatedWatchAnchorWithLock(rawTerminal, options, dependencies)
|
|
262
276
|
: captureTerminalWatchAnchor(agent, rawTerminal, options, dependencies);
|
|
263
277
|
}
|
|
@@ -697,6 +711,9 @@ function assertPreparedFallbackTerminal(prepared, observed) {
|
|
|
697
711
|
!sameTerminalControlEvidenceIncarnation(prepared.terminalEndpoint, observed.terminal_control)) {
|
|
698
712
|
throw new Error("terminal changed before the user-explicit fallback Watch was attached");
|
|
699
713
|
}
|
|
714
|
+
if (isTerminalActivityWatch(prepared)) {
|
|
715
|
+
assertAutomaticActivityWatchIdentity(prepared.anchor, observed, terminalWorkspace(observed), prepared.terminalIdentity.workspace);
|
|
716
|
+
}
|
|
700
717
|
}
|
|
701
718
|
async function exactTerminalForWatch(terminalId, options, dependencies) {
|
|
702
719
|
const observation = await dependencies.observeExactTerminal({
|
|
@@ -773,7 +790,9 @@ function sameManualWatchAnchorTarget(left, right) {
|
|
|
773
790
|
}
|
|
774
791
|
if (left.schema === "agent-knock-knock/terminal-activity-watch-anchor" &&
|
|
775
792
|
right.schema === left.schema) {
|
|
776
|
-
return left.
|
|
793
|
+
return left.origin === right.origin &&
|
|
794
|
+
left.request_hash === right.request_hash &&
|
|
795
|
+
left.pid === right.pid &&
|
|
777
796
|
optionalIdentityCompatible(left.native_process_uuid, right.native_process_uuid) &&
|
|
778
797
|
optionalIdentityCompatible(left.native_process_birth, right.native_process_birth);
|
|
779
798
|
}
|
|
@@ -819,7 +838,7 @@ function terminalControlForWatch(terminal) {
|
|
|
819
838
|
async function captureCodexFallbackWatchAnchor(input, rawTerminal, agentVersion, dependencies) {
|
|
820
839
|
let inventory = rawTerminal._codex_open_root_rollout_inventory;
|
|
821
840
|
let paginated;
|
|
822
|
-
if (
|
|
841
|
+
if (isCodexPaginatedReadCandidate(agentVersion)) {
|
|
823
842
|
try {
|
|
824
843
|
paginated = await capturePaginatedWatchAnchor(rawTerminal, input.options, dependencies, input.requestText === undefined ? input.requestHash
|
|
825
844
|
: createHash("sha256").update(input.requestText.replace(/\r\n?/gu, "\n").trim()).digest("hex"));
|
|
@@ -936,8 +955,8 @@ async function observeTerminalWatch(watch, options, dependencies) {
|
|
|
936
955
|
? terminalWatchResponseDecision({ ...watch, observation_checkpoint: checkpoint }, rawTerminal, surfaceId, fingerprint, options, dependencies)
|
|
937
956
|
: { executable: false, suppress: false }
|
|
938
957
|
}),
|
|
939
|
-
questionnaire: (checkpoint, questions) => exactTerminal.state === "available"
|
|
940
|
-
? terminalWatchQuestionnaireObservation({ watch, observedAt, options, dependencies,
|
|
958
|
+
questionnaire: (checkpoint, questions, allowResponses) => exactTerminal.state === "available"
|
|
959
|
+
? terminalWatchQuestionnaireObservation({ watch: allowResponses ? watch : { ...watch, interaction_policy: "notify_only" }, observedAt, options, dependencies,
|
|
941
960
|
rawTerminal, projectedTerminal: exactTerminal.terminal, terminalMatches,
|
|
942
961
|
observationCheckpoint: checkpoint, codexAsyncQuestionEvidence: questions })
|
|
943
962
|
: undefined });
|