@scotthuang/agent-knock-knock 0.13.12 → 0.13.14
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 +25 -0
- package/README.md +4 -4
- package/dist/src/claude-lifecycle-compatibility.js +25 -4
- package/dist/src/claude-lifecycle-compatibility.js.map +1 -1
- package/dist/src/claude-local-transcript-provider.js +12 -19
- package/dist/src/claude-local-transcript-provider.js.map +1 -1
- package/dist/src/claude-terminal-agent-adapter.js +27 -11
- package/dist/src/claude-terminal-agent-adapter.js.map +1 -1
- package/dist/src/claude-transcript-record-order.d.ts +17 -0
- package/dist/src/claude-transcript-record-order.js +81 -0
- package/dist/src/claude-transcript-record-order.js.map +1 -0
- package/dist/src/codex-app-server-interaction-client.js +5 -3
- package/dist/src/codex-app-server-interaction-client.js.map +1 -1
- package/dist/src/codex-app-server-read-client.d.ts +2 -0
- package/dist/src/codex-app-server-read-client.js +4 -1
- package/dist/src/codex-app-server-read-client.js.map +1 -1
- package/dist/src/codex-async-question-adapter.d.ts +2 -2
- package/dist/src/codex-async-question-adapter.js +8 -3
- package/dist/src/codex-async-question-adapter.js.map +1 -1
- package/dist/src/codex-fullscreen-composer-proof.d.ts +3 -3
- package/dist/src/codex-fullscreen-composer-proof.js +109 -20
- package/dist/src/codex-fullscreen-composer-proof.js.map +1 -1
- package/dist/src/codex-lifecycle-compatibility.d.ts +6 -0
- package/dist/src/codex-lifecycle-compatibility.js +16 -3
- package/dist/src/codex-lifecycle-compatibility.js.map +1 -1
- package/dist/src/codex-paginated-async-answer.js +24 -13
- package/dist/src/codex-paginated-async-answer.js.map +1 -1
- package/dist/src/codex-paginated-async-response.js +4 -1
- package/dist/src/codex-paginated-async-response.js.map +1 -1
- package/dist/src/codex-paginated-observation.js +4 -1
- package/dist/src/codex-paginated-observation.js.map +1 -1
- package/dist/src/codex-paginated-questionnaire-runtime.js +2 -1
- package/dist/src/codex-paginated-questionnaire-runtime.js.map +1 -1
- package/dist/src/codex-paginated-task.d.ts +5 -1
- package/dist/src/codex-paginated-task.js +8 -3
- package/dist/src/codex-paginated-task.js.map +1 -1
- package/dist/src/codex-paginated-thread-binding.d.ts +4 -0
- package/dist/src/codex-paginated-thread-binding.js +29 -6
- package/dist/src/codex-paginated-thread-binding.js.map +1 -1
- package/dist/src/codex-paginated-thread-facts.d.ts +5 -1
- package/dist/src/codex-paginated-watch.js +5 -3
- package/dist/src/codex-paginated-watch.js.map +1 -1
- package/dist/src/codex-status-history-navigation.d.ts +17 -0
- package/dist/src/codex-status-history-navigation.js +260 -0
- package/dist/src/codex-status-history-navigation.js.map +1 -0
- package/dist/src/codex-terminal-agent-adapter.d.ts +2 -0
- package/dist/src/codex-terminal-agent-adapter.js +126 -5
- package/dist/src/codex-terminal-agent-adapter.js.map +1 -1
- package/dist/src/herdr-terminal-control-provider.d.ts +2 -0
- package/dist/src/herdr-terminal-control-provider.js +35 -8
- package/dist/src/herdr-terminal-control-provider.js.map +1 -1
- package/dist/src/semantic-tool-schemas.js +1 -1
- package/dist/src/semantic-tool-schemas.js.map +1 -1
- package/dist/src/terminal-agent-bridge.d.ts +2 -1
- package/dist/src/terminal-agent-bridge.js +50 -7
- package/dist/src/terminal-agent-bridge.js.map +1 -1
- package/dist/src/terminal-composer-classifier.js +17 -10
- package/dist/src/terminal-composer-classifier.js.map +1 -1
- package/dist/src/terminal-control-provider.d.ts +4 -0
- package/dist/src/terminal-control-provider.js +57 -6
- package/dist/src/terminal-control-provider.js.map +1 -1
- package/dist/src/terminal-human-explicit-send-cli-adapter.js +1 -1
- package/dist/src/terminal-human-explicit-send-cli-adapter.js.map +1 -1
- package/dist/src/terminal-interaction-core.js +2 -1
- package/dist/src/terminal-interaction-core.js.map +1 -1
- package/dist/src/terminal-interaction-response-bridge.js +8 -7
- package/dist/src/terminal-interaction-response-bridge.js.map +1 -1
- package/dist/src/terminal-model-control-profile.d.ts +4 -1
- package/dist/src/terminal-model-control-profile.js +68 -2
- package/dist/src/terminal-model-control-profile.js.map +1 -1
- package/dist/src/terminal-model-control.js +5 -3
- package/dist/src/terminal-model-control.js.map +1 -1
- package/dist/src/terminal-monitor-decision-policy.d.ts +1 -1
- package/dist/src/terminal-native-inspection-bridge.d.ts +1 -1
- package/dist/src/terminal-native-inspection-bridge.js +42 -10
- package/dist/src/terminal-native-inspection-bridge.js.map +1 -1
- package/dist/src/terminal-questionnaire-adapter.js +25 -4
- package/dist/src/terminal-questionnaire-adapter.js.map +1 -1
- package/dist/src/terminal-runtime-cli-adapter.js +3 -2
- package/dist/src/terminal-runtime-cli-adapter.js.map +1 -1
- package/dist/src/terminal-send-watch-policy.js +5 -2
- package/dist/src/terminal-send-watch-policy.js.map +1 -1
- package/dist/src/terminal-watch-cli-adapter.js +3 -2
- package/dist/src/terminal-watch-cli-adapter.js.map +1 -1
- package/dist/src/terminal-watch-interaction-runtime.js +3 -1
- package/dist/src/terminal-watch-interaction-runtime.js.map +1 -1
- package/docs/claude-2.1.285-compatibility.md +133 -0
- package/docs/codex-0.159.0-compatibility.md +232 -0
- package/docs/codex-0.159.2-compatibility.md +226 -0
- package/docs/quickstart-herdr.md +2 -2
- package/docs/quickstart-tmux.md +3 -3
- package/package.json +5 -2
- package/templates/openclaw-skills/agent-knock-knock/SKILL.md +10 -10
|
@@ -0,0 +1,260 @@
|
|
|
1
|
+
import { createHash } from "node:crypto";
|
|
2
|
+
import { captureCodexFullscreenComposerFrame } from "./codex-fullscreen-composer-proof.js";
|
|
3
|
+
import { closedCodex159StatusSuffix, observeCodexNativeInspection } from "./codex-terminal-agent-adapter.js";
|
|
4
|
+
import { exactCodexReadyStyledComposerCapture, stripTerminalEscapeSequences } from "./terminal-native-inspection-bridge.js";
|
|
5
|
+
/** Only the observed 0.159 owned-screen navigation protocol, never a generic pager. */
|
|
6
|
+
const PAUSED_FOOTER = /^ {2}(?:New activity · )?enter\/esc latest · \? shortcuts(?: {2,}⚠ [1-9]\d? warnings? · f2 to view)?$/u;
|
|
7
|
+
const HISTORY_GAP = /^ +(?:New activity · )?↓ Back to bottom · esc *$/u;
|
|
8
|
+
const SESSION = /^ {2}Session: {2,}[0-9a-f]{8}(?:-[0-9a-f]{4}){3}-[0-9a-f]{12}$/u;
|
|
9
|
+
const FIELD = /^ {2}[A-Za-z][^:│]{0,63}: {2,}\S.*$/u;
|
|
10
|
+
const INFO = new Set([
|
|
11
|
+
" Visit https://chatgpt.com/codex/settings/usage for up-to-date",
|
|
12
|
+
" information on rate limits and credits"
|
|
13
|
+
]);
|
|
14
|
+
class MissingStatusOverlap extends Error {
|
|
15
|
+
}
|
|
16
|
+
function lines(screen) {
|
|
17
|
+
return screen.replace(/\r\n?/gu, "\n").split("\n");
|
|
18
|
+
}
|
|
19
|
+
function plainRows(rows) {
|
|
20
|
+
return rows.map((row) => stripTerminalEscapeSequences(row).trimEnd());
|
|
21
|
+
}
|
|
22
|
+
function trimEmptyEnd(rows) {
|
|
23
|
+
while (rows.length && !stripTerminalEscapeSequences(rows.at(-1)).trim())
|
|
24
|
+
rows.pop();
|
|
25
|
+
return rows;
|
|
26
|
+
}
|
|
27
|
+
function completeStatus(screen, version) {
|
|
28
|
+
return observeCodexNativeInspection({
|
|
29
|
+
operation: { kind: "status" }, expectedAgentVersion: version,
|
|
30
|
+
screen: stripTerminalEscapeSequences(screen)
|
|
31
|
+
}).status === "observed";
|
|
32
|
+
}
|
|
33
|
+
/** A clipped card tail is navigation eligibility, never independent identity evidence. */
|
|
34
|
+
function clippedTail(screen, version) {
|
|
35
|
+
if (!exactCodexReadyStyledComposerCapture(screen, version))
|
|
36
|
+
return undefined;
|
|
37
|
+
const frame = captureCodexFullscreenComposerFrame(screen, version);
|
|
38
|
+
const start = /^[›»](?:\s|$)/u.test(frame.plainLines[0] ?? "") ? 1 : 0;
|
|
39
|
+
let end = frame.composerIndex;
|
|
40
|
+
const session = frame.plainLines.findIndex((row, index) => index >= start && index < end && SESSION.test(row.trimEnd()));
|
|
41
|
+
if (session < 0)
|
|
42
|
+
return undefined;
|
|
43
|
+
for (let index = start; index < end; index += 1) {
|
|
44
|
+
const row = frame.plainLines[index].trimEnd();
|
|
45
|
+
if (!row.trim() || FIELD.test(row) || INFO.has(row) || /^ {4,}\S/u.test(row) ||
|
|
46
|
+
index === start && row === ` >_ OpenAI Codex (v${version})`)
|
|
47
|
+
continue;
|
|
48
|
+
if (index <= session)
|
|
49
|
+
return undefined;
|
|
50
|
+
end = index; // Native working/queue chrome is validated by the complete-card parser later.
|
|
51
|
+
break;
|
|
52
|
+
}
|
|
53
|
+
const liveChrome = frame.plainLines.slice(end, frame.composerIndex).filter((row) => row.trim()).map((row) => row.trimEnd());
|
|
54
|
+
if (!closedCodex159StatusSuffix(liveChrome))
|
|
55
|
+
return undefined;
|
|
56
|
+
const rows = trimEmptyEnd(frame.styledLines.slice(start, end));
|
|
57
|
+
const plain = plainRows(rows);
|
|
58
|
+
if (!plain.some((row) => /^ {2}Directory: {2,}\S/u.test(row)) ||
|
|
59
|
+
!plain.some((row) => /^ {2}Permissions: {2,}\S/u.test(row)) ||
|
|
60
|
+
!plain.some((row) => /^ {2}Agents\.md: {2,}\S/u.test(row)))
|
|
61
|
+
return undefined;
|
|
62
|
+
return {
|
|
63
|
+
rows, plain,
|
|
64
|
+
liveChrome,
|
|
65
|
+
footer: frame.plainLines[frame.footerIndex].trimEnd()
|
|
66
|
+
};
|
|
67
|
+
}
|
|
68
|
+
function normalizedChrome(rows) {
|
|
69
|
+
return JSON.stringify(rows.map((row) => row
|
|
70
|
+
.replace(/^[•◦] /u, "• ")
|
|
71
|
+
.replace(/\((?:(?:\d+h )?\d+m )?\d+s • esc to interrupt\)/u, "(elapsed • esc to interrupt)")
|
|
72
|
+
.replace(/^( {2}\? [1-9]\d{0,2} questions?) · (?:[1-9]|1\d|20)s$/u, "$1")));
|
|
73
|
+
}
|
|
74
|
+
function currentChromeBoundary(rows, end) {
|
|
75
|
+
const tail = plainRows(rows.slice(0, end)).flatMap((row, index) => row.trim() ? [{ row, index }] : []).slice(-8);
|
|
76
|
+
const start = tail.findIndex(({ row }) => row === "• Queued follow-up inputs" ||
|
|
77
|
+
closedCodex159StatusSuffix([row]) || / to interrupt/u.test(row));
|
|
78
|
+
if (start < 0)
|
|
79
|
+
return end; // The task may have finished and removed its entire live bottom pane.
|
|
80
|
+
return closedCodex159StatusSuffix(tail.slice(start).map(({ row }) => row)) ? tail[start].index : undefined;
|
|
81
|
+
}
|
|
82
|
+
function historyBeforeChrome(rows, end, tail, restoreOnly) {
|
|
83
|
+
if (restoreOnly) {
|
|
84
|
+
const boundary = currentChromeBoundary(rows, end);
|
|
85
|
+
return boundary === undefined ? undefined : {
|
|
86
|
+
rows: trimEmptyEnd(rows.slice(0, boundary)), transcriptBottom: boundary, screenRows: rows.length
|
|
87
|
+
};
|
|
88
|
+
}
|
|
89
|
+
const indexed = plainRows(rows.slice(0, end)).flatMap((row, index) => row.trim() ? [{ row, index }] : []);
|
|
90
|
+
if (tail.liveChrome.length > 0) {
|
|
91
|
+
const suffix = indexed.slice(-tail.liveChrome.length);
|
|
92
|
+
const chrome = suffix.map(({ row }) => row);
|
|
93
|
+
if (!closedCodex159StatusSuffix(chrome) || normalizedChrome(chrome) !== normalizedChrome(tail.liveChrome))
|
|
94
|
+
return undefined;
|
|
95
|
+
end = suffix[0].index;
|
|
96
|
+
}
|
|
97
|
+
return { rows: trimEmptyEnd(rows.slice(0, end)), transcriptBottom: end, screenRows: rows.length };
|
|
98
|
+
}
|
|
99
|
+
/** Normalize only the exact native paused footer for the existing styled Composer proof. */
|
|
100
|
+
function pausedHistory(screen, version, tail, restoreOnly = false) {
|
|
101
|
+
const rows = trimEmptyEnd(lines(screen));
|
|
102
|
+
const plain = plainRows(rows);
|
|
103
|
+
if (!PAUSED_FOOTER.test(plain.at(-1) ?? ""))
|
|
104
|
+
return undefined;
|
|
105
|
+
const normalized = [...rows.slice(0, -1), " ← for agents · ? for shortcuts"].join("\n");
|
|
106
|
+
if (!exactCodexReadyStyledComposerCapture(normalized, version))
|
|
107
|
+
return undefined;
|
|
108
|
+
const frame = captureCodexFullscreenComposerFrame(normalized, version);
|
|
109
|
+
if (frame.plainLines[frame.footerIndex].trimEnd() !== tail.footer)
|
|
110
|
+
return undefined;
|
|
111
|
+
const gaps = plain.flatMap((row, index) => HISTORY_GAP.test(row) ? [index] : []);
|
|
112
|
+
if (gaps.length !== 1 || gaps[0] >= frame.composerIndex ||
|
|
113
|
+
plain.slice(gaps[0] + 1, frame.composerIndex).some((row) => row.trim()))
|
|
114
|
+
return undefined;
|
|
115
|
+
return historyBeforeChrome(rows, gaps[0], tail, restoreOnly);
|
|
116
|
+
}
|
|
117
|
+
function reconstruct(previous, screen, tail, version) {
|
|
118
|
+
const plain = plainRows(previous);
|
|
119
|
+
const command = plain.lastIndexOf("/status");
|
|
120
|
+
if (command < 0)
|
|
121
|
+
throw new Error("Codex history did not expose the latest /status command");
|
|
122
|
+
const prefix = previous.slice(command);
|
|
123
|
+
const prefixPlain = plain.slice(command);
|
|
124
|
+
const overlaps = [];
|
|
125
|
+
for (let size = 1; size <= Math.min(prefix.length, tail.rows.length); size += 1) {
|
|
126
|
+
const overlap = tail.plain.slice(0, size);
|
|
127
|
+
if (overlap.some((row) => row.trim().length >= 12) &&
|
|
128
|
+
JSON.stringify(prefixPlain.slice(-size)) === JSON.stringify(overlap))
|
|
129
|
+
overlaps.push(size);
|
|
130
|
+
}
|
|
131
|
+
if (overlaps.length === 0)
|
|
132
|
+
throw new MissingStatusOverlap("Codex status history overlap is missing or ambiguous");
|
|
133
|
+
if (overlaps.length !== 1)
|
|
134
|
+
throw new Error("Codex status history overlap is ambiguous");
|
|
135
|
+
const size = overlaps[0];
|
|
136
|
+
const anchor = tail.plain.slice(0, size).find((row) => row.trim().length >= 12);
|
|
137
|
+
if (prefixPlain.filter((row) => row === anchor).length !== 1 ||
|
|
138
|
+
tail.plain.filter((row) => row === anchor).length !== 1) {
|
|
139
|
+
throw new Error("Codex status history overlap is not unique");
|
|
140
|
+
}
|
|
141
|
+
const frame = captureCodexFullscreenComposerFrame(screen, version);
|
|
142
|
+
const start = /^[›»](?:\s|$)/u.test(frame.plainLines[0] ?? "") ? 1 : 0;
|
|
143
|
+
// All header/identity characters come from captured frames. The original live
|
|
144
|
+
// suffix and Composer close the reconstructed card; pager chrome never does.
|
|
145
|
+
const result = [...prefix.slice(0, -size), ...frame.styledLines.slice(start)].join("\n");
|
|
146
|
+
if (!completeStatus(result, version))
|
|
147
|
+
throw new Error("Codex reconstructed status card is incomplete or ambiguous");
|
|
148
|
+
return result;
|
|
149
|
+
}
|
|
150
|
+
function sameTail(screen, version, expected) {
|
|
151
|
+
const tail = clippedTail(screen, version);
|
|
152
|
+
return tail !== undefined && JSON.stringify(tail.plain) === JSON.stringify(expected.plain) &&
|
|
153
|
+
tail.footer === expected.footer;
|
|
154
|
+
}
|
|
155
|
+
function compatibleStatusPrefix(paused, screen, version) {
|
|
156
|
+
const plain = plainRows(paused.rows);
|
|
157
|
+
const command = plain.lastIndexOf("/status");
|
|
158
|
+
if (command < 0)
|
|
159
|
+
return false;
|
|
160
|
+
const frame = captureCodexFullscreenComposerFrame(screen, version);
|
|
161
|
+
if (!frame)
|
|
162
|
+
return false;
|
|
163
|
+
const start = /^[›»](?:\s|$)/u.test(frame.plainLines[0] ?? "") ? 1 : 0;
|
|
164
|
+
// This adjacency is ONLY eligibility for one read-only wheel event, never
|
|
165
|
+
// identity evidence. Reuse the strict card grammar to reject contradictory
|
|
166
|
+
// headers/fields/prose, including a command-only stub whose header is below
|
|
167
|
+
// the paused viewport. Returning identity still requires observed overlap.
|
|
168
|
+
return completeStatus([...paused.rows.slice(command), ...frame.styledLines.slice(start)].join("\n"), version);
|
|
169
|
+
}
|
|
170
|
+
async function reconstructWithBoundaryBridge(paused, screen, tail, version, ports) {
|
|
171
|
+
try {
|
|
172
|
+
return reconstruct(paused.rows, screen, tail, version);
|
|
173
|
+
}
|
|
174
|
+
catch (error) {
|
|
175
|
+
if (!(error instanceof MissingStatusOverlap) || !compatibleStatusPrefix(paused, screen, version) ||
|
|
176
|
+
!ports.inspectViewport || !ports.scrollHistoryDown)
|
|
177
|
+
throw error;
|
|
178
|
+
}
|
|
179
|
+
const viewport = await ports.inspectViewport();
|
|
180
|
+
const fresh = pausedHistory(await ports.capture(), version, tail);
|
|
181
|
+
if (!viewport || viewport.columns < 80 || viewport.rows < 12 || !fresh ||
|
|
182
|
+
fresh.screenRows !== viewport.rows || fresh.transcriptBottom < 3 ||
|
|
183
|
+
JSON.stringify(plainRows(fresh.rows)) !== JSON.stringify(plainRows(paused.rows))) {
|
|
184
|
+
throw new Error("Codex status-boundary history scroll lacks an exact paused transcript viewport");
|
|
185
|
+
}
|
|
186
|
+
// Codex 0.159 transcript_view/input.rs: ScrollDown inside self.area advances
|
|
187
|
+
// exactly three rows. The closed provider event targets (2,2), below the
|
|
188
|
+
// one-row sticky prompt and above proven bottom-pane chrome. Never repeat it.
|
|
189
|
+
await ports.scrollHistoryDown(viewport);
|
|
190
|
+
for (let attempt = 0; attempt < 8; attempt += 1) {
|
|
191
|
+
await ports.sleep(50);
|
|
192
|
+
const after = pausedHistory(await ports.capture(), version, tail);
|
|
193
|
+
if (!after || after.screenRows !== viewport.rows)
|
|
194
|
+
throw new Error("Codex history scroll lost its exact paused viewport");
|
|
195
|
+
if (JSON.stringify(plainRows(after.rows)) !== JSON.stringify(plainRows(paused.rows))) {
|
|
196
|
+
return reconstruct(after.rows, screen, tail, version);
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
throw new Error("Codex history scroll did not provide a unique nonblank status overlap");
|
|
200
|
+
}
|
|
201
|
+
async function restoreLatest(ports, version, tail) {
|
|
202
|
+
// Recapture before restoration: a user draft, modal, selection, or changed
|
|
203
|
+
// model/path footer forbids further input, even a navigation key.
|
|
204
|
+
if (!pausedHistory(await ports.capture(), version, tail, true)) {
|
|
205
|
+
throw new Error("Codex status history changed before restoring latest");
|
|
206
|
+
}
|
|
207
|
+
await ports.sendKey("C-End");
|
|
208
|
+
for (let attempt = 0; attempt < 8; attempt += 1) {
|
|
209
|
+
await ports.sleep(50);
|
|
210
|
+
const capture = await ports.capture();
|
|
211
|
+
if (sameTail(capture, version, tail))
|
|
212
|
+
return;
|
|
213
|
+
if (!pausedHistory(capture, version, tail, true))
|
|
214
|
+
break;
|
|
215
|
+
}
|
|
216
|
+
throw new Error("Codex status history did not restore its exact latest card tail");
|
|
217
|
+
}
|
|
218
|
+
/** One reversible page, only after our proven closed /status Enter cleared its Composer. */
|
|
219
|
+
export async function captureCodexStatusHistory(input) {
|
|
220
|
+
const { screen, version, submission, ports } = input;
|
|
221
|
+
if (!["0.159.0", "0.159.2"].includes(version) || completeStatus(screen, version))
|
|
222
|
+
return screen;
|
|
223
|
+
const tail = clippedTail(screen, version);
|
|
224
|
+
if (!tail || !submission || submission.stage !== "enter_dispatched" || submission.enterCount !== 1 ||
|
|
225
|
+
submission.agent !== "codex" || submission.command !== "/status" ||
|
|
226
|
+
submission.behaviorProfile !== `codex-tui-${version}` ||
|
|
227
|
+
!/^[0-9a-f]{64}$/u.test(submission.observationBaselineDigest) ||
|
|
228
|
+
createHash("sha256").update(screen).digest("hex") === submission.observationBaselineDigest)
|
|
229
|
+
return screen;
|
|
230
|
+
// The original transaction's styled command -> cleared Composer transition
|
|
231
|
+
// provides freshness. Fullscreen clipping cannot preserve occurrence counts
|
|
232
|
+
// in preEnterEvidenceInventory, including repeated identical /status cards.
|
|
233
|
+
if (!sameTail(await ports.capture(), version, tail))
|
|
234
|
+
throw new Error("Codex status tail changed before history navigation");
|
|
235
|
+
let paused;
|
|
236
|
+
let restoreNeeded = false;
|
|
237
|
+
let candidate;
|
|
238
|
+
try {
|
|
239
|
+
await ports.sendKey("PageUp");
|
|
240
|
+
for (let attempt = 0; attempt < 8; attempt += 1) {
|
|
241
|
+
await ports.sleep(50);
|
|
242
|
+
const capture = await ports.capture();
|
|
243
|
+
paused = pausedHistory(capture, version, tail);
|
|
244
|
+
restoreNeeded = paused !== undefined || pausedHistory(capture, version, tail, true) !== undefined;
|
|
245
|
+
if (paused)
|
|
246
|
+
break;
|
|
247
|
+
if (!sameTail(capture, version, tail))
|
|
248
|
+
throw new Error("Codex history navigation lost its exact Composer or native footer");
|
|
249
|
+
}
|
|
250
|
+
if (!paused)
|
|
251
|
+
throw new Error("Codex history navigation did not expose a proven paused viewport");
|
|
252
|
+
candidate = await reconstructWithBoundaryBridge(paused, screen, tail, version, ports);
|
|
253
|
+
}
|
|
254
|
+
finally {
|
|
255
|
+
if (restoreNeeded)
|
|
256
|
+
await restoreLatest(ports, version, tail);
|
|
257
|
+
}
|
|
258
|
+
return candidate;
|
|
259
|
+
}
|
|
260
|
+
//# sourceMappingURL=codex-status-history-navigation.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"codex-status-history-navigation.js","sourceRoot":"","sources":["../../src/codex-status-history-navigation.ts"],"names":[],"mappings":"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"}
|
|
@@ -29,6 +29,8 @@ export declare function planCodexThreadLifecycle(operation: TerminalThreadLifecy
|
|
|
29
29
|
export declare function observeCodexThreadLifecycle(request: TerminalThreadLifecycleObservationRequest): TerminalThreadLifecycleObservation;
|
|
30
30
|
/** @deprecated Pass a typed observation request. */
|
|
31
31
|
export declare function observeCodexThreadLifecycle(screen: string, operation: TerminalThreadLifecycleOperation): TerminalThreadLifecycleObservation;
|
|
32
|
+
/** Native activity/details stay outside identity evidence, before the Composer. */
|
|
33
|
+
export declare function closedCodex159StatusSuffix(lines: readonly string[]): boolean;
|
|
32
34
|
export declare const codexTerminalAgentAdapter: TerminalAgentAdapter<"codex_cli">;
|
|
33
35
|
export declare function inspectCodexScreen(options: TerminalScreenInspectionOptions): TerminalScreenInspection;
|
|
34
36
|
export declare function detectCodexApprovalPrompt(screen: string): CodexApprovalPromptDetection;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { createHash } from "node:crypto";
|
|
2
|
-
import { CODEX_FULLSCREEN_SHORTCUT_FOOTER as
|
|
2
|
+
import { captureCodexFullscreenComposerFrame, CODEX_FULLSCREEN_SHORTCUT_FOOTER as CODEX_PAGINATED_SHORTCUT_FOOTER } from "./codex-fullscreen-composer-proof.js";
|
|
3
3
|
import { classifyCodexProcess } from "./codex-session-provider.js";
|
|
4
|
-
import { codexRuntimeCompatibilityProfile, codexThreadLifecycleHistoryWarning, codexUnsupportedDurableHistoryWarning } from "./codex-lifecycle-compatibility.js";
|
|
4
|
+
import { isCodexPaginatedVersion, codexRuntimeCompatibilityProfile, codexThreadLifecycleHistoryWarning, codexUnsupportedDurableHistoryWarning } from "./codex-lifecycle-compatibility.js";
|
|
5
5
|
import { redactString } from "./runtime-log.js";
|
|
6
6
|
import { normalizeTerminalApprovalPromptRegion, terminalApprovalPromptEvidence } from "./terminal-agent-adapter.js";
|
|
7
7
|
import { isExactNativeThreadId } from "./managed-session.js";
|
|
@@ -20,7 +20,7 @@ const CODEX_SKILLS_HINT = /^[›»]\s+Use \/skills\b/u;
|
|
|
20
20
|
const CODEX_FOOTER_LINE = /^(?:gpt-[\w.-]+(?:\s|$)|[-\w.]+ default ·)/u;
|
|
21
21
|
// Diagnostic activity only. These fullscreen rows do not prove a task identity,
|
|
22
22
|
// an empty styled Composer, or permission to use a version-bound native action.
|
|
23
|
-
const CODEX_FULLSCREEN_ACTIVITY_VERSIONS = new Set(["0.157.0", "0.157.1", "0.158.0"]);
|
|
23
|
+
const CODEX_FULLSCREEN_ACTIVITY_VERSIONS = new Set(["0.157.0", "0.157.1", "0.158.0", "0.159.0", "0.159.2"]);
|
|
24
24
|
const CODEX_FULLSCREEN_MODEL_FOOTER = /^ {2}(?:GPT-[\w.-]+|gpt-[\w.-]+) (?:low|medium|high|xhigh|max|ultra)(?: fast)? · (?:~\/|\/)[^·\r\n]+(?: · [^·\r\n]+)*$/u;
|
|
25
25
|
const CODEX_FULLSCREEN_SHORTCUT_FOOTER = /^ {2}← for agents · \? for shortcuts(?: {2,}⚠ [1-9]\d? warnings? · f2 to view)?$/u;
|
|
26
26
|
// Verified Codex releases can animate the otherwise empty Astra Composer by replacing
|
|
@@ -44,6 +44,9 @@ const CODEX_STATUS_HEADER_PATTERN = /\bOpenAI Codex \(v([0-9]+\.[0-9]+\.[0-9]+(?
|
|
|
44
44
|
const CODEX_STATUS_TOP_BORDER = /^\s*╭[─-]+╮\s*$/u;
|
|
45
45
|
const CODEX_STATUS_BOTTOM_BORDER = /^\s*╰[─-]+╯\s*$/u;
|
|
46
46
|
const CODEX_STATUS_FIELD = /^\s*│\s*([^:│]{1,64}):\s+(.+?)\s*│\s*$/u;
|
|
47
|
+
// Native status_indicator_widget.rs + motion.rs: the title is untrusted
|
|
48
|
+
// display text. Only the complete timed interrupt chrome delimits fields.
|
|
49
|
+
const CODEX_159_ACTIVITY_ROW = /^(?:[•◦] )?[^\s•◦][^\r\n]{0,255} \((?:[0-5]?\ds|[1-5]?\dm [0-5]\ds|[1-9]\d*h [0-5]\dm [0-5]\ds) • esc to interrupt\)(?: · \S[^\r\n]{0,255})?$/u;
|
|
47
50
|
const CODEX_STATUS_MAX_LINES = 64;
|
|
48
51
|
const CODEX_STATUS_MAX_REGION_LENGTH = 8_192;
|
|
49
52
|
const CODEX_STATUS_MAX_FIELDS = 24;
|
|
@@ -469,6 +472,11 @@ function parseCodexStatusCardAfterCommand(lines, commandIndex) {
|
|
|
469
472
|
while (topBorderIndex < lines.length && !lines[topBorderIndex].trim()) {
|
|
470
473
|
topBorderIndex += 1;
|
|
471
474
|
}
|
|
475
|
+
const borderlessVersion = /^>_ OpenAI Codex \(v(0\.159\.(?:0|2))\)$/u
|
|
476
|
+
.exec(lines[topBorderIndex]?.trim() ?? "")?.[1];
|
|
477
|
+
if (borderlessVersion === "0.159.0" || borderlessVersion === "0.159.2") {
|
|
478
|
+
return parseCodex159StatusCard(lines, topBorderIndex, borderlessVersion);
|
|
479
|
+
}
|
|
472
480
|
if (topBorderIndex >= lines.length ||
|
|
473
481
|
!CODEX_STATUS_TOP_BORDER.test(lines[topBorderIndex])) {
|
|
474
482
|
return {
|
|
@@ -550,6 +558,118 @@ function parseCodexStatusCardAfterCommand(lines, commandIndex) {
|
|
|
550
558
|
fields
|
|
551
559
|
};
|
|
552
560
|
}
|
|
561
|
+
/** 0.159 removes borders. Close fields before the exact native live suffix. */
|
|
562
|
+
function parseCodex159StatusCard(lines, start, agentVersion) {
|
|
563
|
+
const uncertain = (reason) => ({ status: "ambiguous", reason });
|
|
564
|
+
const limit = Math.min(lines.length, start + CODEX_STATUS_MAX_LINES);
|
|
565
|
+
let end = start + 1;
|
|
566
|
+
while (end < limit && !/^[›»](?:\s|$)/u.test(lines[end]) &&
|
|
567
|
+
codexNativeCommandLine(lines[end]) === undefined)
|
|
568
|
+
end += 1;
|
|
569
|
+
if (end === limit)
|
|
570
|
+
return { status: "missing", reason: "Codex 0.159 /status has no visible closing Composer or command" };
|
|
571
|
+
// A live main Composer must have its complete footer; a following native
|
|
572
|
+
// command may close an earlier card in the pre-Enter occurrence inventory.
|
|
573
|
+
if (/^[›»](?:\s|$)/u.test(lines[end]) &&
|
|
574
|
+
codexNativeCommandLine(lines[end]) === undefined &&
|
|
575
|
+
captureCodexFullscreenComposerFrame(lines.slice(end).join("\n"), agentVersion)?.composerIndex !== 0) {
|
|
576
|
+
return uncertain("Codex 0.159 /status closing Composer is incomplete");
|
|
577
|
+
}
|
|
578
|
+
const suffixStart = lines.findIndex((line, index) => index > start && index < end &&
|
|
579
|
+
(isCodex159ActivityRow(line.trimEnd()) || line === "• Queued follow-up inputs"));
|
|
580
|
+
const fieldEnd = suffixStart < 0 ? end : suffixStart;
|
|
581
|
+
if (suffixStart >= 0 && !closedCodex159StatusSuffix(lines.slice(suffixStart, end))) {
|
|
582
|
+
return uncertain("Codex 0.159 /status contains an unproven live activity suffix");
|
|
583
|
+
}
|
|
584
|
+
const region = lines.slice(start, fieldEnd).join("\n").trimEnd();
|
|
585
|
+
if (region.length > CODEX_STATUS_MAX_REGION_LENGTH) {
|
|
586
|
+
return uncertain("Codex 0.159 /status exceeds the bounded inspection size");
|
|
587
|
+
}
|
|
588
|
+
const fields = [];
|
|
589
|
+
const names = new Set();
|
|
590
|
+
let valueColumn;
|
|
591
|
+
for (const line of lines.slice(start + 1, fieldEnd)) {
|
|
592
|
+
if (!line.trim())
|
|
593
|
+
continue;
|
|
594
|
+
if (fields.length === 0 && [
|
|
595
|
+
" Visit https://chatgpt.com/codex/settings/usage for up-to-date",
|
|
596
|
+
" information on rate limits and credits"
|
|
597
|
+
].includes(line.trimEnd()))
|
|
598
|
+
continue;
|
|
599
|
+
const match = /^ {2}([A-Za-z][^:│]{0,63}): {2,}(\S.*)$/u.exec(line.trimEnd());
|
|
600
|
+
if (match) {
|
|
601
|
+
const name = match[1].trim();
|
|
602
|
+
const column = line.indexOf(":") + 1 + /^ +/u.exec(line.slice(line.indexOf(":") + 1))[0].length;
|
|
603
|
+
if (names.has(name.toLowerCase()) || fields.length >= CODEX_STATUS_MAX_FIELDS ||
|
|
604
|
+
valueColumn !== undefined && column !== valueColumn) {
|
|
605
|
+
return uncertain("Codex 0.159 /status fields are duplicated, misaligned, or oversized");
|
|
606
|
+
}
|
|
607
|
+
names.add(name.toLowerCase());
|
|
608
|
+
valueColumn = column;
|
|
609
|
+
fields.push({ name, value: match[2] });
|
|
610
|
+
}
|
|
611
|
+
else {
|
|
612
|
+
const previous = fields.at(-1);
|
|
613
|
+
if (!previous || valueColumn === undefined ||
|
|
614
|
+
!line.startsWith(" ".repeat(valueColumn)) ||
|
|
615
|
+
!line.slice(valueColumn).trim() || /^(?:Session|Server)$/u.test(previous.name)) {
|
|
616
|
+
return uncertain("Codex 0.159 /status contains unproven or wrapped identity text");
|
|
617
|
+
}
|
|
618
|
+
previous.value += ` ${line.slice(valueColumn).trim()}`;
|
|
619
|
+
}
|
|
620
|
+
if (fields.at(-1).value.length > CODEX_STATUS_MAX_FIELD_VALUE_LENGTH) {
|
|
621
|
+
return uncertain("Codex 0.159 /status field exceeds the bounded inspection size");
|
|
622
|
+
}
|
|
623
|
+
}
|
|
624
|
+
const nativeThreadId = fields.find((field) => field.name === "Session")?.value;
|
|
625
|
+
if (!nativeThreadId || !isExactNativeThreadId(nativeThreadId) ||
|
|
626
|
+
!["Model", "Directory", "Permissions", "Agents.md"].every((name) => fields.some((field) => field.name === name))) {
|
|
627
|
+
return { status: "missing", reason: "Codex 0.159 /status lacks complete required fields or its exact Session UUID" };
|
|
628
|
+
}
|
|
629
|
+
return {
|
|
630
|
+
status: "observed", region, nativeThreadId: nativeThreadId.toLowerCase(), agentVersion,
|
|
631
|
+
fields: fields.map(({ name, value }) => ({
|
|
632
|
+
name: redactCodexNativeStatusText(name),
|
|
633
|
+
value: /^account$/iu.test(name) ? "[REDACTED]" : redactCodexNativeStatusText(value)
|
|
634
|
+
}))
|
|
635
|
+
};
|
|
636
|
+
}
|
|
637
|
+
/** A shape fence only; never independent identity or input authorization. */
|
|
638
|
+
function isCodex159ActivityRow(line) {
|
|
639
|
+
return CODEX_159_ACTIVITY_ROW.test(line) && safeCodex159StatusDisplayText(line);
|
|
640
|
+
}
|
|
641
|
+
function safeCodex159StatusDisplayText(line) {
|
|
642
|
+
return line.length <= 512 && !/[\x00-\x1f\x7f]/u.test(line) &&
|
|
643
|
+
!/(?:\b(?:Session|Server):|OpenAI Codex|(?:^|\s)\/status(?:\s|$))/iu.test(line);
|
|
644
|
+
}
|
|
645
|
+
/** Native activity/details stay outside identity evidence, before the Composer. */
|
|
646
|
+
export function closedCodex159StatusSuffix(lines) {
|
|
647
|
+
const rows = lines.filter((line) => line.trim()).map((line) => line.trimEnd());
|
|
648
|
+
if (isCodex159ActivityRow(rows[0] ?? "")) {
|
|
649
|
+
rows.shift();
|
|
650
|
+
let details = 0;
|
|
651
|
+
// A hook overflow plus up to three details rows. Continuations require a
|
|
652
|
+
// preceding native branch prefix; arbitrary queued user prose is excluded.
|
|
653
|
+
while (/^(?: {2}└ (?!Tip: )| {4}\S)/u.test(rows[0] ?? "")) {
|
|
654
|
+
const row = rows.shift();
|
|
655
|
+
if (details >= 4 || details === 0 && !row.startsWith(" └ ") ||
|
|
656
|
+
!safeCodex159StatusDisplayText(row))
|
|
657
|
+
return false;
|
|
658
|
+
details += 1;
|
|
659
|
+
}
|
|
660
|
+
if (/^ {2}└ Tip: \S.{0,255}$/u.test(rows[0] ?? "")) {
|
|
661
|
+
// bottom_pane renders the working tip only without inline previews.
|
|
662
|
+
return rows.length === 1 && safeCodex159StatusDisplayText(rows[0]);
|
|
663
|
+
}
|
|
664
|
+
}
|
|
665
|
+
if (rows.length === 0)
|
|
666
|
+
return true;
|
|
667
|
+
if (rows.length !== 3 || rows[0] !== "• Queued follow-up inputs")
|
|
668
|
+
return false;
|
|
669
|
+
const summary = /^ {2}\? ([1-9]\d{0,2}) (question|questions)(?: · (?:[1-9]|1\d|20)s)?$/u.exec(rows[1]);
|
|
670
|
+
return summary !== null && (Number(summary[1]) === 1) === (summary[2] === "question") &&
|
|
671
|
+
/^ {4}(?:shift\+←|⌥\+↑) to answer$/u.test(rows[2]);
|
|
672
|
+
}
|
|
553
673
|
function codexStatusEvidenceInventory(screen) {
|
|
554
674
|
const allLines = screen.split(/\r?\n/u);
|
|
555
675
|
const lines = allLines.slice(-CODEX_STATUS_EVIDENCE_SCAN_MAX_LINES);
|
|
@@ -785,7 +905,8 @@ export function detectCodexActivityState(screen, approval = detectCodexApprovalP
|
|
|
785
905
|
};
|
|
786
906
|
}
|
|
787
907
|
const tailLines = screen.trimEnd().split(/\r?\n/).slice(-30);
|
|
788
|
-
const workingLine = tailLines.find((line) => isCodexWorkingLine(line)
|
|
908
|
+
const workingLine = tailLines.find((line) => isCodexWorkingLine(line) ||
|
|
909
|
+
(agentVersion === "0.159.0" || agentVersion === "0.159.2") && isCodex159ActivityRow(line.trimEnd()));
|
|
789
910
|
if (workingLine) {
|
|
790
911
|
return {
|
|
791
912
|
state: "working",
|
|
@@ -1152,7 +1273,7 @@ function codexFullscreenIdlePromptLine(lines, agentVersion) {
|
|
|
1152
1273
|
.filter((line) => line.trim()).map((line) => line.trimEnd());
|
|
1153
1274
|
return footer.length === 2 &&
|
|
1154
1275
|
CODEX_FULLSCREEN_MODEL_FOOTER.test(footer[0]) &&
|
|
1155
|
-
(agentVersion
|
|
1276
|
+
(isCodexPaginatedVersion(agentVersion) ? CODEX_PAGINATED_SHORTCUT_FOOTER : CODEX_FULLSCREEN_SHORTCUT_FOOTER).test(footer[1])
|
|
1156
1277
|
? lines[composerIndex]
|
|
1157
1278
|
: undefined;
|
|
1158
1279
|
}
|