cueline 0.1.2 → 0.1.4
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/.claude-plugin/plugin.json +2 -2
- package/.codex-plugin/plugin.json +3 -3
- package/CHANGELOG.md +38 -0
- package/README.ja.md +65 -21
- package/README.ko.md +65 -21
- package/README.md +70 -23
- package/README.zh-CN.md +65 -21
- package/README.zh-TW.md +68 -22
- package/dist/src/api-contracts.d.ts +77 -0
- package/dist/src/api-contracts.js +2 -0
- package/dist/src/api-contracts.js.map +1 -0
- package/dist/src/api-controller-handoff.d.ts +6 -0
- package/dist/src/api-controller-handoff.js +253 -0
- package/dist/src/api-controller-handoff.js.map +1 -0
- package/dist/src/api-runtime-lifecycle.d.ts +22 -0
- package/dist/src/api-runtime-lifecycle.js +568 -0
- package/dist/src/api-runtime-lifecycle.js.map +1 -0
- package/dist/src/api.d.ts +9 -27
- package/dist/src/api.js +138 -42
- package/dist/src/api.js.map +1 -1
- package/dist/src/browser/browser-adapter.d.ts +11 -1
- package/dist/src/browser/codex-iab/bootstrap.d.ts +16 -0
- package/dist/src/browser/codex-iab/bootstrap.js +49 -0
- package/dist/src/browser/codex-iab/bootstrap.js.map +1 -1
- package/dist/src/browser/codex-iab/chatgpt-client.js +346 -120
- package/dist/src/browser/codex-iab/chatgpt-client.js.map +1 -1
- package/dist/src/browser/codex-iab/recovery-evidence.d.ts +6 -0
- package/dist/src/browser/codex-iab/recovery-evidence.js +37 -0
- package/dist/src/browser/codex-iab/recovery-evidence.js.map +1 -0
- package/dist/src/browser/codex-iab/submission-url.d.ts +2 -0
- package/dist/src/browser/codex-iab/submission-url.js +53 -0
- package/dist/src/browser/codex-iab/submission-url.js.map +1 -0
- package/dist/src/cli/main.js +305 -20
- package/dist/src/cli/main.js.map +1 -1
- package/dist/src/core/controller-abort.d.ts +1 -0
- package/dist/src/core/controller-abort.js +11 -0
- package/dist/src/core/controller-abort.js.map +1 -0
- package/dist/src/core/controller-command-execution.d.ts +9 -0
- package/dist/src/core/controller-command-execution.js +299 -0
- package/dist/src/core/controller-command-execution.js.map +1 -0
- package/dist/src/core/controller-loop.d.ts +3 -37
- package/dist/src/core/controller-loop.js +386 -291
- package/dist/src/core/controller-loop.js.map +1 -1
- package/dist/src/core/controller-turn.d.ts +16 -0
- package/dist/src/core/controller-turn.js +309 -0
- package/dist/src/core/controller-turn.js.map +1 -0
- package/dist/src/core/controller-types.d.ts +58 -0
- package/dist/src/core/controller-types.js +2 -0
- package/dist/src/core/controller-types.js.map +1 -0
- package/dist/src/core/persisted-run.d.ts +4 -0
- package/dist/src/core/persisted-run.js +19 -0
- package/dist/src/core/persisted-run.js.map +1 -0
- package/dist/src/core/process-liveness.d.ts +2 -0
- package/dist/src/core/process-liveness.js +44 -0
- package/dist/src/core/process-liveness.js.map +1 -0
- package/dist/src/core/run-status.d.ts +53 -0
- package/dist/src/core/run-status.js +224 -0
- package/dist/src/core/run-status.js.map +1 -0
- package/dist/src/core/state-machine.d.ts +17 -4
- package/dist/src/core/state-machine.js +170 -16
- package/dist/src/core/state-machine.js.map +1 -1
- package/dist/src/jobs/status.d.ts +7 -1
- package/dist/src/jobs/status.js.map +1 -1
- package/dist/src/jobs/supervisor.d.ts +2 -0
- package/dist/src/jobs/supervisor.js +47 -13
- package/dist/src/jobs/supervisor.js.map +1 -1
- package/dist/src/protocol/types.d.ts +1 -1
- package/dist/src/protocol/validate-command.js +18 -0
- package/dist/src/protocol/validate-command.js.map +1 -1
- package/dist/src/router/resolver.d.ts +2 -1
- package/dist/src/router/resolver.js +31 -13
- package/dist/src/router/resolver.js.map +1 -1
- package/dist/src/runners/process-runner.d.ts +2 -2
- package/dist/src/runners/process-runner.js +113 -9
- package/dist/src/runners/process-runner.js.map +1 -1
- package/dist/src/runners/runner-adapter.d.ts +9 -2
- package/dist/src/runners/runner-adapter.js.map +1 -1
- package/dist/src/state/atomic-write.js +17 -2
- package/dist/src/state/atomic-write.js.map +1 -1
- package/dist/src/state/cancellation.d.ts +42 -0
- package/dist/src/state/cancellation.js +168 -0
- package/dist/src/state/cancellation.js.map +1 -0
- package/dist/src/state/event-log.d.ts +17 -1
- package/dist/src/state/event-log.js +328 -18
- package/dist/src/state/event-log.js.map +1 -1
- package/dist/src/state/paths.d.ts +4 -0
- package/dist/src/state/paths.js +4 -0
- package/dist/src/state/paths.js.map +1 -1
- package/dist/src/state/runtime-lease.d.ts +53 -0
- package/dist/src/state/runtime-lease.js +727 -0
- package/dist/src/state/runtime-lease.js.map +1 -0
- package/dist/src/state/runtime-retirement.d.ts +16 -0
- package/dist/src/state/runtime-retirement.js +95 -0
- package/dist/src/state/runtime-retirement.js.map +1 -0
- package/dist/src/state/runtime-takeover-intent.d.ts +1 -0
- package/dist/src/state/runtime-takeover-intent.js +18 -0
- package/dist/src/state/runtime-takeover-intent.js.map +1 -0
- package/dist/src/state/store.d.ts +12 -1
- package/dist/src/state/store.js +246 -40
- package/dist/src/state/store.js.map +1 -1
- package/dist/src/version.d.ts +1 -1
- package/dist/src/version.js +1 -1
- package/docs/architecture.md +16 -11
- package/docs/assets/cueline-loop-en.svg +11 -10
- package/docs/assets/cueline-loop-ja.svg +11 -10
- package/docs/assets/cueline-loop-ko.svg +11 -10
- package/docs/assets/cueline-loop-zh-CN.svg +11 -10
- package/docs/assets/cueline-loop-zh-TW.svg +11 -10
- package/docs/compatibility.md +16 -8
- package/docs/controller-protocol.md +8 -4
- package/docs/runner-contract.md +26 -6
- package/docs/state-and-recovery.md +69 -16
- package/package.json +4 -3
- package/schemas/controller-observation.schema.json +1 -1
- package/scripts/validate-plugin.mjs +66 -0
- package/skills/cueline/SKILL.md +89 -13
package/docs/architecture.md
CHANGED
|
@@ -23,7 +23,9 @@ CueLine is standalone. Its runtime does not import Omnilane or GPT Relay, and it
|
|
|
23
23
|
|
|
24
24
|
### Browser adapter
|
|
25
25
|
|
|
26
|
-
`src/browser/codex-iab/` implements a text-only adapter over Codex's IAB client. It claims an existing ChatGPT tab when possible, otherwise opens the requested ChatGPT URL. It fills the composer, emits durable
|
|
26
|
+
`src/browser/codex-iab/` implements a text-only adapter over Codex's IAB client. It claims an existing ChatGPT tab when possible, otherwise opens the requested ChatGPT URL. It fills the composer, waits for the DOM to settle as either `inline_ready` or `attachment_ready`, emits durable submission checkpoints, makes at most one send attempt, waits for a stable completed assistant message, and records the resulting conversation URL. ChatGPT may automatically convert a long text prompt into an attachment; this is supported without treating an empty composer as proof that nothing is ready.
|
|
27
|
+
|
|
28
|
+
Recovery is read-only. Inline turns normally require the exact last user prompt. A manually submitted attachment turn may instead be recovered only after an append-only operator confirmation and exact conversation, Pro model, and protocol/run/round/request envelope checks. Response text and the conversation URL are captured in the same DOM evaluation so navigation cannot mix evidence from two pages. Ambiguous clicks remain `possibly_sent`; CueLine never retries or coordinate-clicks after a possibly accepted send.
|
|
27
29
|
|
|
28
30
|
The adapter can receive an injected browser or resolve `globalThis.iab` / `agent.browsers.get("iab")` from Codex's runtime. Plain Node does not provide these globals.
|
|
29
31
|
|
|
@@ -33,26 +35,28 @@ The adapter can receive an injected browser or resolve `globalThis.iab` / `agent
|
|
|
33
35
|
|
|
34
36
|
### Controller loop
|
|
35
37
|
|
|
36
|
-
`src/core/controller-loop.ts`
|
|
38
|
+
`src/core/controller-loop.ts` advances the run:
|
|
37
39
|
|
|
38
40
|
1. Persist the intended controller turn.
|
|
39
41
|
2. Persist browser submission checkpoints around the send boundary.
|
|
40
|
-
3.
|
|
41
|
-
4.
|
|
42
|
+
3. With the built-in browser in caller mode, submit once, capture the exact `/c/...` URL, persist `submitted`, return `awaiting_controller`, and release the runtime lease. CueLine does not create a detached Node daemon because Codex's injected IAB object does not exist there.
|
|
43
|
+
4. A later continuation performs one read-only `observeTurn`. An unfinished Pro response returns `awaiting_controller` immediately without another send; an exact completed response is persisted.
|
|
42
44
|
5. Validate protocol identity and every pre-spawn route, then persist the accepted command.
|
|
43
|
-
6.
|
|
45
|
+
6. In the default `caller` executor, persist `advise` jobs and return them to the current Codex. In explicit `process` execution, run registered workers through the local supervisor.
|
|
44
46
|
7. Snapshot the derived state.
|
|
45
|
-
8. Repeat until `complete`, `blocked`, or the round limit is reached.
|
|
47
|
+
8. Repeat through ownerless controller/caller pauses until `complete`, `blocked`, or the round limit is reached. Neither terminal action is accepted while any required or optional job remains pending/running.
|
|
48
|
+
|
|
49
|
+
The default limits are 12 controller rounds and two repair attempts per pending command. An explicit `maxRounds` is persisted with run creation and remains the total budget across split caller continuations; omitting it later reuses the persisted value, while a different value is rejected.
|
|
46
50
|
|
|
47
|
-
|
|
51
|
+
### Execution modes, routing, and runners
|
|
48
52
|
|
|
49
|
-
|
|
53
|
+
`caller` is the default for both `startCueLineRun` and `runCueLine`. A controller turn first returns `awaiting_controller` after its one durable submission; each continuation observes the same URL/request once and never resends. A controller `dispatch` then creates durable pending jobs and returns `awaiting_caller`; the current Codex performs each exact local inspection and calls `submitCueLineCallerJobResult`, then continues the same run. ChatGPT only issued the text command—it did not use local tools. Caller mode accepts `advise` only; `work` is rejected until CueLine can issue a duplicate-safe execution claim.
|
|
50
54
|
|
|
51
|
-
`src/router/` chooses an enabled, available candidate before any process starts. `src/runners/` requires an explicitly registered `argv[0]`, uses `spawn` with `shell: false`, and never performs post-spawn fallback. `src/jobs/` coordinates foreground/background execution and persists job status.
|
|
55
|
+
`process` is opt-in. `src/router/` chooses an enabled, available candidate before any process starts. `src/runners/` requires an explicitly registered `argv[0]`, uses `spawn` with `shell: false`, and never performs post-spawn fallback. `src/jobs/` coordinates foreground/background execution and persists job status. Process execution defaults to two concurrent jobs globally and two per lane; an accepted batch containing any `work` job is serial. Owned process groups are settled on success, cancellation, and timeout so descendants are not left behind.
|
|
52
56
|
|
|
53
57
|
### Durable state
|
|
54
58
|
|
|
55
|
-
`src/state/` writes a per-run
|
|
59
|
+
`src/state/` writes a per-run logical event log and an atomic disposable snapshot. The event log is authoritative and is replayed on load. Immutable fsynced sequence segments avoid a shared-host append lock; a durable legacy-prefix fence isolates still-loaded older writers. Runtime-authored events carry owner identity. Exact takeover intent is durable before replacement; the successful atomic lease replacement embeds the retired owner's sequence cutoff, so a failed replacement leaves the old owner authoritative while a committed cutoff keeps later writes visible for audit but unable to change replayed state. The cutoff is mirrored to immutable retirement evidence before the replacement lease is removed. Pending and recoverably abandoned controller turns, composer state, manual confirmation, and request-correlated browser failure evidence survive replay. A prompt is retried only when the exact sole pending request is proven `definitely_not_sent`; ambiguous submissions require read-only reconciliation. Job status files are atomically replaced, but authoritative terminal run events win if a retired owner writes a conflicting file later. Runtime leases serialize continuation and caller result submission; ownerless `controller_response_pending` and `caller_jobs_pending` phases are intentional healthy boundaries.
|
|
56
60
|
|
|
57
61
|
## Authority and trust
|
|
58
62
|
|
|
@@ -64,6 +68,7 @@ The controller can request local work, but a request is not equivalent to proces
|
|
|
64
68
|
- config-derived registered executable allow-list
|
|
65
69
|
- no shell interpolation
|
|
66
70
|
- deterministic job identity and duplicate-dispatch suppression
|
|
71
|
+
- caller-mode `advise`-only enforcement
|
|
67
72
|
- no nested CueLine routing (`CUELINE_DEPTH`)
|
|
68
73
|
- no retry after a worker has started
|
|
69
74
|
|
|
@@ -72,7 +77,7 @@ These gates reduce accidental execution ambiguity; they do not make an allowed w
|
|
|
72
77
|
## Data flow
|
|
73
78
|
|
|
74
79
|
1. The original user request becomes part of every controller observation.
|
|
75
|
-
2.
|
|
80
|
+
2. Full job stdout and stderr remain in local status. Successful non-empty stdout is preferred for controller evidence, and all controller job evidence shares one 12,000-character budget with an explicit truncation notice.
|
|
76
81
|
3. ChatGPT returns a command; only the control envelope is machine-executed.
|
|
77
82
|
4. On `complete`, CueLine returns `final_delivery_text` to Codex.
|
|
78
83
|
5. On `blocked`, CueLine preserves the controller's reason and optional delivery text.
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1000
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1000 612" width="1000" height="612" role="img" aria-label="A caller-first CueLine run: ChatGPT emits text commands, the current Codex performs local advice, and CueLine returns bounded evidence until complete.">
|
|
2
2
|
<title>A CueLine run, read as a promptbook</title>
|
|
3
3
|
<style>
|
|
4
4
|
text { font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, "Liberation Mono", monospace }
|
|
@@ -28,8 +28,8 @@
|
|
|
28
28
|
|
|
29
29
|
<text x="505" y="44" class="hd" text-anchor="end">ChatGPT web conversation</text>
|
|
30
30
|
<text x="505" y="64" class="sub" text-anchor="end">the controller — plans, calls, judges</text>
|
|
31
|
-
<text x="555" y="44" class="hd">
|
|
32
|
-
<text x="555" y="64" class="sub">
|
|
31
|
+
<text x="555" y="44" class="hd">current Codex + CueLine</text>
|
|
32
|
+
<text x="555" y="64" class="sub">validates, persists, hands off, records</text>
|
|
33
33
|
|
|
34
34
|
<path d="M40 84H505" class="rule"/>
|
|
35
35
|
<path d="M555 84H960" class="rule"/>
|
|
@@ -45,23 +45,23 @@
|
|
|
45
45
|
<path d="M545 162H565" class="tick"/>
|
|
46
46
|
<text x="575" y="166" class="note">routed before anything starts</text>
|
|
47
47
|
|
|
48
|
-
<text x="555" y="200" class="note">
|
|
48
|
+
<text x="555" y="200" class="note">current Codex (caller advise) → result submitted</text>
|
|
49
49
|
|
|
50
50
|
<text x="40" y="264" class="rnd">ROUND 2</text>
|
|
51
51
|
<path d="M505 260H524" class="tick"/>
|
|
52
|
-
<text x="555" y="264" class="obs">observation ·
|
|
52
|
+
<text x="555" y="264" class="obs">observation · bounded evidence · stdout preferred</text>
|
|
53
53
|
<path d="M524 256 517 260 524 264z" class="cue"/>
|
|
54
54
|
|
|
55
55
|
<path d="M536 296 545 300 536 304z" class="cue"/>
|
|
56
|
-
<text x="505" y="304" class="say" text-anchor="end">dispatch ·
|
|
56
|
+
<text x="505" y="304" class="say" text-anchor="end">dispatch · follow-up · mode advise</text>
|
|
57
57
|
<path d="M545 300H565" class="tick"/>
|
|
58
|
-
<text x="575" y="304" class="note">
|
|
58
|
+
<text x="575" y="304" class="note">durable caller handoff</text>
|
|
59
59
|
|
|
60
|
-
<text x="555" y="338" class="note">
|
|
60
|
+
<text x="555" y="338" class="note">current Codex → second result submitted</text>
|
|
61
61
|
|
|
62
62
|
<text x="40" y="402" class="rnd">ROUND 3</text>
|
|
63
63
|
<path d="M505 398H524" class="tick"/>
|
|
64
|
-
<text x="555" y="402" class="obs">observation · updated evidence</text>
|
|
64
|
+
<text x="555" y="402" class="obs">observation · updated bounded evidence</text>
|
|
65
65
|
<path d="M524 394 517 398 524 402z" class="cue"/>
|
|
66
66
|
|
|
67
67
|
<path d="M536 434 545 438 536 442z" class="cue"/>
|
|
@@ -73,5 +73,6 @@
|
|
|
73
73
|
|
|
74
74
|
<path d="M40 520H960" class="rule"/>
|
|
75
75
|
<text x="40" y="546" class="foot">Five actions only — dispatch · wait · inspect · complete · blocked.</text>
|
|
76
|
-
<text x="40" y="568" class="foot">
|
|
76
|
+
<text x="40" y="568" class="foot">One send → awaiting_controller → one-shot observe; never resend.</text>
|
|
77
|
+
<text x="40" y="590" class="foot">Caller accepts advise only. Process execution is explicit and never silently retried.</text>
|
|
77
78
|
</svg>
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1000
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1000 612" width="1000" height="612" role="img" aria-label="CueLine の 1 回の実行をプロンプトブックとして読む:マシンが観測を送り、コントローラーがコマンドを 1 つ出し、登録済みの runner が実行し、complete が出るまで続く。">
|
|
2
2
|
<title>CueLine の実行を、プロンプトブックとして読む</title>
|
|
3
3
|
<style>
|
|
4
4
|
text { font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, "Hiragino Sans", "Noto Sans CJK JP", "Yu Gothic", monospace }
|
|
@@ -28,8 +28,8 @@
|
|
|
28
28
|
|
|
29
29
|
<text x="505" y="44" class="hd" text-anchor="end">ChatGPT ウェブ会話</text>
|
|
30
30
|
<text x="505" y="64" class="sub" text-anchor="end">コントローラー — 計画し、指示し、判断する</text>
|
|
31
|
-
<text x="555" y="44" class="hd"
|
|
32
|
-
<text x="555" y="64" class="sub"
|
|
31
|
+
<text x="555" y="44" class="hd">現在の Codex + CueLine</text>
|
|
32
|
+
<text x="555" y="64" class="sub">検証・永続化・引き渡し・記録</text>
|
|
33
33
|
|
|
34
34
|
<path d="M40 84H505" class="rule"/>
|
|
35
35
|
<path d="M555 84H960" class="rule"/>
|
|
@@ -45,23 +45,23 @@
|
|
|
45
45
|
<path d="M545 162H565" class="tick"/>
|
|
46
46
|
<text x="575" y="166" class="note">プロセス起動の前にルートが決まる</text>
|
|
47
47
|
|
|
48
|
-
<text x="555" y="200" class="note"
|
|
48
|
+
<text x="555" y="200" class="note">現在の Codex(caller advise)→ 結果提出済み</text>
|
|
49
49
|
|
|
50
50
|
<text x="40" y="264" class="rnd">ラウンド 2</text>
|
|
51
51
|
<path d="M505 260H524" class="tick"/>
|
|
52
|
-
<text x="555" y="264" class="obs">observation ·
|
|
52
|
+
<text x="555" y="264" class="obs">observation · 有界な証拠 · stdout 優先</text>
|
|
53
53
|
<path d="M524 256 517 260 524 264z" class="cue"/>
|
|
54
54
|
|
|
55
55
|
<path d="M536 296 545 300 536 304z" class="cue"/>
|
|
56
|
-
<text x="505" y="304" class="say" text-anchor="end">dispatch ·
|
|
56
|
+
<text x="505" y="304" class="say" text-anchor="end">dispatch · 追加確認 · mode advise</text>
|
|
57
57
|
<path d="M545 300H565" class="tick"/>
|
|
58
|
-
<text x="575" y="304" class="note"
|
|
58
|
+
<text x="575" y="304" class="note">永続 caller 引き渡し</text>
|
|
59
59
|
|
|
60
|
-
<text x="555" y="338" class="note"
|
|
60
|
+
<text x="555" y="338" class="note">現在の Codex → 2 件目の結果提出済み</text>
|
|
61
61
|
|
|
62
62
|
<text x="40" y="402" class="rnd">ラウンド 3</text>
|
|
63
63
|
<path d="M505 398H524" class="tick"/>
|
|
64
|
-
<text x="555" y="402" class="obs">observation ·
|
|
64
|
+
<text x="555" y="402" class="obs">observation · 更新済みの有界な証拠</text>
|
|
65
65
|
<path d="M524 394 517 398 524 402z" class="cue"/>
|
|
66
66
|
|
|
67
67
|
<path d="M536 434 545 438 536 442z" class="cue"/>
|
|
@@ -73,5 +73,6 @@
|
|
|
73
73
|
|
|
74
74
|
<path d="M40 520H960" class="rule"/>
|
|
75
75
|
<text x="40" y="546" class="foot">アクションは 5 つだけ — dispatch · wait · inspect · complete · blocked。</text>
|
|
76
|
-
<text x="40" y="568" class="foot"
|
|
76
|
+
<text x="40" y="568" class="foot">1 回送信 → awaiting_controller → 1 回の読み取り観測。再送しません。</text>
|
|
77
|
+
<text x="40" y="590" class="foot">Caller は advise のみ。process は明示的で、暗黙の再試行はしません。</text>
|
|
77
78
|
</svg>
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1000
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1000 612" width="1000" height="612" role="img" aria-label="CueLine 실행 한 번을 프롬프트북처럼 읽기: 머신이 관측을 보내고, 컨트롤러가 명령 하나를 내리고, 등록된 runner가 실행하며, complete가 나올 때까지 이어집니다.">
|
|
2
2
|
<title>CueLine 실행을 프롬프트북처럼 읽기</title>
|
|
3
3
|
<style>
|
|
4
4
|
text { font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, "Apple SD Gothic Neo", "Noto Sans CJK KR", "Malgun Gothic", monospace }
|
|
@@ -28,8 +28,8 @@
|
|
|
28
28
|
|
|
29
29
|
<text x="505" y="44" class="hd" text-anchor="end">ChatGPT 웹 대화</text>
|
|
30
30
|
<text x="505" y="64" class="sub" text-anchor="end">컨트롤러 — 계획하고, 지시하고, 판단합니다</text>
|
|
31
|
-
<text x="555" y="44" class="hd"
|
|
32
|
-
<text x="555" y="64" class="sub"
|
|
31
|
+
<text x="555" y="44" class="hd">현재 Codex + CueLine</text>
|
|
32
|
+
<text x="555" y="64" class="sub">검증 · 지속화 · 인계 · 기록</text>
|
|
33
33
|
|
|
34
34
|
<path d="M40 84H505" class="rule"/>
|
|
35
35
|
<path d="M555 84H960" class="rule"/>
|
|
@@ -45,23 +45,23 @@
|
|
|
45
45
|
<path d="M545 162H565" class="tick"/>
|
|
46
46
|
<text x="575" y="166" class="note">프로세스가 뜨기 전에 경로가 정해집니다</text>
|
|
47
47
|
|
|
48
|
-
<text x="555" y="200" class="note"
|
|
48
|
+
<text x="555" y="200" class="note">현재 Codex (caller advise) → 결과 제출 완료</text>
|
|
49
49
|
|
|
50
50
|
<text x="40" y="264" class="rnd">라운드 2</text>
|
|
51
51
|
<path d="M505 260H524" class="tick"/>
|
|
52
|
-
<text x="555" y="264" class="obs">observation ·
|
|
52
|
+
<text x="555" y="264" class="obs">observation · 제한된 증거 · stdout 우선</text>
|
|
53
53
|
<path d="M524 256 517 260 524 264z" class="cue"/>
|
|
54
54
|
|
|
55
55
|
<path d="M536 296 545 300 536 304z" class="cue"/>
|
|
56
|
-
<text x="505" y="304" class="say" text-anchor="end">dispatch ·
|
|
56
|
+
<text x="505" y="304" class="say" text-anchor="end">dispatch · 후속 점검 · mode advise</text>
|
|
57
57
|
<path d="M545 300H565" class="tick"/>
|
|
58
|
-
<text x="575" y="304" class="note"
|
|
58
|
+
<text x="575" y="304" class="note">지속 caller 인계</text>
|
|
59
59
|
|
|
60
|
-
<text x="555" y="338" class="note"
|
|
60
|
+
<text x="555" y="338" class="note">현재 Codex → 두 번째 결과 제출 완료</text>
|
|
61
61
|
|
|
62
62
|
<text x="40" y="402" class="rnd">라운드 3</text>
|
|
63
63
|
<path d="M505 398H524" class="tick"/>
|
|
64
|
-
<text x="555" y="402" class="obs">observation · 갱신된 증거</text>
|
|
64
|
+
<text x="555" y="402" class="obs">observation · 갱신된 제한 증거</text>
|
|
65
65
|
<path d="M524 394 517 398 524 402z" class="cue"/>
|
|
66
66
|
|
|
67
67
|
<path d="M536 434 545 438 536 442z" class="cue"/>
|
|
@@ -73,5 +73,6 @@
|
|
|
73
73
|
|
|
74
74
|
<path d="M40 520H960" class="rule"/>
|
|
75
75
|
<text x="40" y="546" class="foot">동작은 다섯 개뿐 — dispatch · wait · inspect · complete · blocked.</text>
|
|
76
|
-
<text x="40" y="568" class="foot"
|
|
76
|
+
<text x="40" y="568" class="foot">한 번 전송 → awaiting_controller → 한 번 읽기 관측. 재전송 금지.</text>
|
|
77
|
+
<text x="40" y="590" class="foot">Caller는 advise만 허용. process는 명시적이며 자동 재시도하지 않음.</text>
|
|
77
78
|
</svg>
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1000
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1000 612" width="1000" height="612" role="img" aria-label="一次 CueLine 运行像一本提示本:机器发出观测,控制器发出一条指令,已注册的 runner 执行它,直到控制器发出 complete。">
|
|
2
2
|
<title>一次 CueLine 运行,像读一本提示本</title>
|
|
3
3
|
<style>
|
|
4
4
|
text { font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, "Noto Sans CJK SC", "PingFang SC", "Microsoft YaHei", monospace }
|
|
@@ -28,8 +28,8 @@
|
|
|
28
28
|
|
|
29
29
|
<text x="505" y="44" class="hd" text-anchor="end">ChatGPT 网页会话</text>
|
|
30
30
|
<text x="505" y="64" class="sub" text-anchor="end">控制器 — 规划、发令、审阅证据</text>
|
|
31
|
-
<text x="555" y="44" class="hd"
|
|
32
|
-
<text x="555" y="64" class="sub"
|
|
31
|
+
<text x="555" y="44" class="hd">当前 Codex + CueLine</text>
|
|
32
|
+
<text x="555" y="64" class="sub">校验、持久化、交接、记录</text>
|
|
33
33
|
|
|
34
34
|
<path d="M40 84H505" class="rule"/>
|
|
35
35
|
<path d="M555 84H960" class="rule"/>
|
|
@@ -45,23 +45,23 @@
|
|
|
45
45
|
<path d="M545 162H565" class="tick"/>
|
|
46
46
|
<text x="575" y="166" class="note">任何进程启动之前就先确定路由</text>
|
|
47
47
|
|
|
48
|
-
<text x="555" y="200" class="note"
|
|
48
|
+
<text x="555" y="200" class="note">当前 Codex(caller advise)→ 结果已提交</text>
|
|
49
49
|
|
|
50
50
|
<text x="40" y="264" class="rnd">第 2 轮</text>
|
|
51
51
|
<path d="M505 260H524" class="tick"/>
|
|
52
|
-
<text x="555" y="264" class="obs">observation ·
|
|
52
|
+
<text x="555" y="264" class="obs">observation · 有界证据 · stdout 优先</text>
|
|
53
53
|
<path d="M524 256 517 260 524 264z" class="cue"/>
|
|
54
54
|
|
|
55
55
|
<path d="M536 296 545 300 536 304z" class="cue"/>
|
|
56
|
-
<text x="505" y="304" class="say" text-anchor="end">dispatch ·
|
|
56
|
+
<text x="505" y="304" class="say" text-anchor="end">dispatch · 后续检查 · mode advise</text>
|
|
57
57
|
<path d="M545 300H565" class="tick"/>
|
|
58
|
-
<text x="575" y="304" class="note"
|
|
58
|
+
<text x="575" y="304" class="note">持久 caller 交接</text>
|
|
59
59
|
|
|
60
|
-
<text x="555" y="338" class="note"
|
|
60
|
+
<text x="555" y="338" class="note">当前 Codex → 第二份结果已提交</text>
|
|
61
61
|
|
|
62
62
|
<text x="40" y="402" class="rnd">第 3 轮</text>
|
|
63
63
|
<path d="M505 398H524" class="tick"/>
|
|
64
|
-
<text x="555" y="402" class="obs">observation ·
|
|
64
|
+
<text x="555" y="402" class="obs">observation · 更新后的有界证据</text>
|
|
65
65
|
<path d="M524 394 517 398 524 402z" class="cue"/>
|
|
66
66
|
|
|
67
67
|
<path d="M536 434 545 438 536 442z" class="cue"/>
|
|
@@ -73,5 +73,6 @@
|
|
|
73
73
|
|
|
74
74
|
<path d="M40 520H960" class="rule"/>
|
|
75
75
|
<text x="40" y="546" class="foot">只有五个动作 — dispatch · wait · inspect · complete · blocked。</text>
|
|
76
|
-
<text x="40" y="568" class="foot"
|
|
76
|
+
<text x="40" y="568" class="foot">只发送一次 → awaiting_controller → 单次只读观测;绝不重发。</text>
|
|
77
|
+
<text x="40" y="590" class="foot">Caller 只允许 advise;process 必须显式选择,并且不会静默重试。</text>
|
|
77
78
|
</svg>
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1000
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1000 612" width="1000" height="612" role="img" aria-label="一次 CueLine 執行像一本提示本:機器送出觀測,主控端喊出一道指令,已註冊的 runner 執行它,直到主控端喊 complete。">
|
|
2
2
|
<title>一次 CueLine 執行,像讀一本提示本</title>
|
|
3
3
|
<style>
|
|
4
4
|
text { font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, "Noto Sans CJK TC", "PingFang TC", "Microsoft JhengHei", monospace }
|
|
@@ -28,8 +28,8 @@
|
|
|
28
28
|
|
|
29
29
|
<text x="505" y="44" class="hd" text-anchor="end">ChatGPT 網頁對話</text>
|
|
30
30
|
<text x="505" y="64" class="sub" text-anchor="end">主控端 — 規劃、喊 cue、審查證據</text>
|
|
31
|
-
<text x="555" y="44" class="hd"
|
|
32
|
-
<text x="555" y="64" class="sub"
|
|
31
|
+
<text x="555" y="44" class="hd">目前的 Codex + CueLine</text>
|
|
32
|
+
<text x="555" y="64" class="sub">驗證、保存、交接、記錄</text>
|
|
33
33
|
|
|
34
34
|
<path d="M40 84H505" class="rule"/>
|
|
35
35
|
<path d="M555 84H960" class="rule"/>
|
|
@@ -45,23 +45,23 @@
|
|
|
45
45
|
<path d="M545 162H565" class="tick"/>
|
|
46
46
|
<text x="575" y="166" class="note">任何程序啟動之前就先決定路由</text>
|
|
47
47
|
|
|
48
|
-
<text x="555" y="200" class="note"
|
|
48
|
+
<text x="555" y="200" class="note">目前的 Codex(caller advise)→ 結果已提交</text>
|
|
49
49
|
|
|
50
50
|
<text x="40" y="264" class="rnd">第 2 輪</text>
|
|
51
51
|
<path d="M505 260H524" class="tick"/>
|
|
52
|
-
<text x="555" y="264" class="obs">observation ·
|
|
52
|
+
<text x="555" y="264" class="obs">observation · 有界證據 · stdout 優先</text>
|
|
53
53
|
<path d="M524 256 517 260 524 264z" class="cue"/>
|
|
54
54
|
|
|
55
55
|
<path d="M536 296 545 300 536 304z" class="cue"/>
|
|
56
|
-
<text x="505" y="304" class="say" text-anchor="end">dispatch ·
|
|
56
|
+
<text x="505" y="304" class="say" text-anchor="end">dispatch · 後續查驗 · mode advise</text>
|
|
57
57
|
<path d="M545 300H565" class="tick"/>
|
|
58
|
-
<text x="575" y="304" class="note"
|
|
58
|
+
<text x="575" y="304" class="note">持久 caller 交接</text>
|
|
59
59
|
|
|
60
|
-
<text x="555" y="338" class="note"
|
|
60
|
+
<text x="555" y="338" class="note">目前的 Codex → 第二份結果已提交</text>
|
|
61
61
|
|
|
62
62
|
<text x="40" y="402" class="rnd">第 3 輪</text>
|
|
63
63
|
<path d="M505 398H524" class="tick"/>
|
|
64
|
-
<text x="555" y="402" class="obs">observation ·
|
|
64
|
+
<text x="555" y="402" class="obs">observation · 更新後的有界證據</text>
|
|
65
65
|
<path d="M524 394 517 398 524 402z" class="cue"/>
|
|
66
66
|
|
|
67
67
|
<path d="M536 434 545 438 536 442z" class="cue"/>
|
|
@@ -73,5 +73,6 @@
|
|
|
73
73
|
|
|
74
74
|
<path d="M40 520H960" class="rule"/>
|
|
75
75
|
<text x="40" y="546" class="foot">只有五個動作 — dispatch · wait · inspect · complete · blocked。</text>
|
|
76
|
-
<text x="40" y="568" class="foot"
|
|
76
|
+
<text x="40" y="568" class="foot">只送一次 → awaiting_controller → 單次唯讀觀測;絕不重送。</text>
|
|
77
|
+
<text x="40" y="590" class="foot">Caller 只允許 advise;process 必須明確選用,而且不會偷偷重試。</text>
|
|
77
78
|
</svg>
|
package/docs/compatibility.md
CHANGED
|
@@ -6,8 +6,9 @@
|
|
|
6
6
|
|---|---|---|
|
|
7
7
|
| Node.js 22+ ESM | Supported | Core protocol, state, router, runners, fake browser tests |
|
|
8
8
|
| Codex Node REPL + built-in Browser (IAB) | Required for live control | Provides the imported API with the authenticated ChatGPT tab/browser client |
|
|
9
|
-
|
|
|
10
|
-
|
|
|
9
|
+
| Current Codex caller | Default local executor | Performs durable caller-mode `advise` jobs and submits their results |
|
|
10
|
+
| `codex` CLI | Required only by bundled process route | `executor: "process"` is explicit; custom routing may register a different executable |
|
|
11
|
+
| ChatGPT web conversation | Supported, text commands | Controller has no direct local tools; CueLine requires a Pro composer and Pro response slug |
|
|
11
12
|
| macOS | Primary supported desktop | Codex desktop + symlink installer target |
|
|
12
13
|
| Linux | Core/CI target | Live Codex IAB availability depends on the host product |
|
|
13
14
|
| Windows | Not verified | `install.sh` and symlink layout are not a Windows installer |
|
|
@@ -16,9 +17,9 @@ The npm package has no runtime dependencies. Development requires TypeScript and
|
|
|
16
17
|
|
|
17
18
|
## ChatGPT requirements
|
|
18
19
|
|
|
19
|
-
CueLine is designed for a conversation already authenticated by the user at `chatgpt.com
|
|
20
|
+
CueLine is designed for a conversation already authenticated by the user at `chatgpt.com`. CueLine neither handles credentials nor verifies plan entitlement. Before each controller turn it may switch the composer to `Pro`; that is its only automatic model switch. It also requires Pro evidence on the completed response.
|
|
20
21
|
|
|
21
|
-
The v0.1 adapter relies on accessible textbox/button roles and assistant-message markup in the current ChatGPT web UI. UI changes can cause explicit `COMPOSER_MISSING`, `SEND_BUTTON_MISSING`, or response-timeout errors. A fake adapter test cannot prove that the current live page still matches.
|
|
22
|
+
The v0.1 adapter relies on accessible textbox/button roles, attachment chips, and assistant-message markup in the current ChatGPT web UI. ChatGPT's automatic conversion of a long filled prompt into an attachment is supported. Deliberate file upload is not. UI changes can cause explicit `COMPOSER_MISSING`, `SEND_BUTTON_MISSING`, or response-timeout errors. A fake adapter test cannot prove that the current live page still matches.
|
|
22
23
|
|
|
23
24
|
## Supported in v0.1
|
|
24
25
|
|
|
@@ -26,27 +27,34 @@ The v0.1 adapter relies on accessible textbox/button roles and assistant-message
|
|
|
26
27
|
- text controller observations and commands
|
|
27
28
|
- `dispatch`, `wait`, `inspect`, `complete`, and `blocked`
|
|
28
29
|
- foreground and background local jobs
|
|
30
|
+
- caller-first execution: durable pending `advise` jobs are performed by the current Codex and submitted through the API
|
|
31
|
+
- durable built-in-IAB submit/one-shot-observe pauses that let Pro think beyond one outer tool waiter without resending
|
|
32
|
+
- explicit process execution with default global/per-lane concurrency of two and serialized batches containing `work`
|
|
29
33
|
- deterministic routing before spawn
|
|
30
34
|
- append-only run recovery and atomic snapshots
|
|
31
35
|
- continuation by run ID and stored conversation URL
|
|
32
36
|
- read-only persisted-state loading through `loadCueLineRunState`
|
|
37
|
+
- cross-session run status, runtime ownership, run/job cancellation, and optional run deadlines
|
|
38
|
+
- automatic long-text attachment recognition, one-click ambiguous-send safety, and operator-confirmed manual reconciliation
|
|
39
|
+
- bounded controller evidence (successful stdout preferred; full stdout/stderr retained locally)
|
|
33
40
|
- injected fake browser/runner for offline tests
|
|
34
41
|
|
|
35
42
|
## Not supported in v0.1
|
|
36
43
|
|
|
37
|
-
-
|
|
44
|
+
- model switching other than CueLine selecting `Pro`
|
|
38
45
|
- images, screenshots as controller input, audio, or binary payloads
|
|
39
46
|
- file upload/download through the ChatGPT page
|
|
40
47
|
- Deep Research, Projects, Apps, or custom GPT UI flows
|
|
41
48
|
- multiple simultaneous controller conversations for one run
|
|
42
49
|
- direct browser-to-local tool calls
|
|
50
|
+
- caller-mode `work` execution (explicit process execution is required)
|
|
43
51
|
- automatic retry/fallback after a worker starts
|
|
44
52
|
- cross-host transfer of browser sessions, credentials, child processes, or local runtime state
|
|
45
53
|
- unattended guarantee across ChatGPT UI or authentication changes
|
|
46
54
|
|
|
47
55
|
## CLI boundary
|
|
48
56
|
|
|
49
|
-
`cueline doctor`, `routing`, `jobs`, and `config path`
|
|
57
|
+
`cueline doctor`, `routing`, `jobs`, `run status`, `api path`, and `config path` are read-only. `install`/`uninstall` change only the package-owned skill link. `run reconcile`, `run takeover`, `run reconcile-runtime`, `run cancel` / `run stop`, and `job cancel` append audit evidence or change local durable state; `cueline help` lists their exact positional syntax and options. None drives the ChatGPT page. `run reconcile --manual-send-confirmed` records an operator's exact manual send; the imported API still performs identity/Pro reconciliation through Codex's IAB browser object. `run takeover` retires only an exact stale owner/heartbeat and refuses a fresh active owner.
|
|
50
58
|
|
|
51
59
|
## Live readiness checklist
|
|
52
60
|
|
|
@@ -54,7 +62,7 @@ The v0.1 adapter relies on accessible textbox/button roles and assistant-message
|
|
|
54
62
|
2. `npm run build` succeeds for a checkout, or the installed package contains `dist/`.
|
|
55
63
|
3. Codex exposes its built-in Browser runtime.
|
|
56
64
|
4. A logged-in `https://chatgpt.com/` tab is open and the intended model/conversation is selected.
|
|
57
|
-
5. `cueline doctor` reports
|
|
58
|
-
6. A
|
|
65
|
+
5. `cueline doctor` reports `caller_ready yes` and at least one enabled caller lane. `process_available_lanes` may be zero without degrading caller mode; explicit process mode additionally requires `codex-default` (or a configured alternative) to be available.
|
|
66
|
+
6. A live smoke completes one harmless controller round and one caller `advise` result handoff before explicit process `work` is considered.
|
|
59
67
|
|
|
60
68
|
Readiness does not prove a worker will succeed. Preserve the run evidence and report the exact missing prerequisite when a step fails.
|
|
@@ -35,7 +35,7 @@ A stale or mismatched value is rejected. CueLine parses only the **last complete
|
|
|
35
35
|
}
|
|
36
36
|
```
|
|
37
37
|
|
|
38
|
-
Job states are `pending`, `running`, `succeeded`, `failed`, `timed_out`, or `ambiguous`.
|
|
38
|
+
Job states are `pending`, `running`, `succeeded`, `failed`, `timed_out`, `cancelled`, or `ambiguous`. Successful jobs with non-empty stdout use stdout as controller evidence instead of a combined stdout/stderr stream. Failed and timed-out jobs retain bounded diagnostic error evidence. All job evidence in one controller observation shares a global 12,000-character budget; omitted content is reported once with the exact omitted count. Full stdout/stderr remain in local job status, and only the most recent 20 notices are sent. The local event log remains the recovery record.
|
|
39
39
|
|
|
40
40
|
## Command envelope
|
|
41
41
|
|
|
@@ -81,7 +81,11 @@ Schedules one or more local jobs.
|
|
|
81
81
|
}
|
|
82
82
|
```
|
|
83
83
|
|
|
84
|
-
`job_key` must be unique inside the command and match the supported identifier form. `mode` is `advise` or `work`. Optional fields are `required`, `timeout_ms`, `runner`, `workdir`, and `background`. The local runtime—not ChatGPT—resolves the configured executable. `lane` must be a listed available lane; a runner ID is not a lane name. When `runner` is supplied, it must name an enabled, available candidate in the selected lane. CueLine validates every new route in the dispatch before registering or starting any job. One invalid route rejects the whole command and requests a corrected envelope with the same pending identity. Repeating an already persisted deterministic job is ignored rather than
|
|
84
|
+
`job_key` must be unique inside the command and match the supported identifier form. `mode` is `advise` or `work`. Optional fields are `required`, `timeout_ms`, `runner`, `workdir`, and `background`. `runner_id` is invalid and produces an explicit correction to use `runner`. The local runtime—not ChatGPT—resolves the configured executable. `lane` must be a listed available lane; a runner ID is not a lane name. When `runner` is supplied, it must name an enabled, available candidate in the selected lane. CueLine validates every new route in the dispatch before registering or starting any job. One invalid route rejects the whole command and requests a corrected envelope with the same pending identity. Repeating an already persisted deterministic job is ignored rather than executed again.
|
|
85
|
+
|
|
86
|
+
The default executor is `caller`. It persists pending `advise` jobs and returns them to the current Codex, which executes the exact local inspections and submits terminal results. The web controller has no local tool access. Caller-mode `work` is rejected with `CALLER_WORK_REQUIRES_CLAIM` because CueLine cannot yet issue a duplicate-safe side-effect claim.
|
|
87
|
+
|
|
88
|
+
The `process` executor must be selected explicitly. Independent `advise` jobs run with a default global concurrency of two and a default per-lane limit of two (both configurable). If any job is `work`, the entire batch remains serial in command order.
|
|
85
89
|
|
|
86
90
|
### `wait`
|
|
87
91
|
|
|
@@ -93,11 +97,11 @@ Asks CueLine to present the currently persisted job state on the next round. It
|
|
|
93
97
|
|
|
94
98
|
### `complete`
|
|
95
99
|
|
|
96
|
-
Ends the run with non-empty `final_delivery_text`. Completion is rejected while any required job remains `pending` or `running`; the controller receives a notice and must
|
|
100
|
+
Ends the run with non-empty `final_delivery_text`. Completion is rejected while any required or optional job remains `pending` or `running`; the controller receives a notice and must wait, inspect, cancel, or otherwise settle every job before deciding again. Terminal jobs may have failed—the controller is responsible for judging that evidence.
|
|
97
101
|
|
|
98
102
|
### `blocked`
|
|
99
103
|
|
|
100
|
-
Ends the run with a non-empty `reason` and optional `final_delivery_text`.
|
|
104
|
+
Ends the run with a non-empty `reason` and optional `final_delivery_text`. Like `complete`, it is rejected while any required or optional job remains active so terminalization cannot orphan background work. Once jobs are settled, it is an explicit statement that the controller cannot responsibly proceed with the available evidence or authority.
|
|
101
105
|
|
|
102
106
|
## Validation and repair
|
|
103
107
|
|
package/docs/runner-contract.md
CHANGED
|
@@ -1,6 +1,12 @@
|
|
|
1
1
|
# Runner contract
|
|
2
2
|
|
|
3
|
-
##
|
|
3
|
+
## Caller execution is the default
|
|
4
|
+
|
|
5
|
+
`startCueLineRun` and `runCueLine` default to `executor: "caller"`. With the built-in browser, one durable submission returns `awaiting_controller`; later continuations observe the same URL/request once without resending. A validated dispatch then persists pending jobs and returns them to the current Codex; it does not spawn `codex exec`. The caller executes each exact `advise` task with its own permitted local tools, submits one terminal result through `submitCueLineCallerJobResult`, and continues the same run. Duplicate terminal submissions return `already_terminal`.
|
|
6
|
+
|
|
7
|
+
The ChatGPT web controller only emits a text command. It does not inspect the repository, call tools, or run the job itself. Caller execution rejects `work` with `CALLER_WORK_REQUIRES_CLAIM`; use caller `advise`, or explicitly opt into the process executor after the user has authorized local mutation.
|
|
8
|
+
|
|
9
|
+
## Process routing happens before spawn
|
|
4
10
|
|
|
5
11
|
A controller job names a lane, not arbitrary shell text. CueLine loads an enabled lane and examines candidates in configured order. Disabled or unavailable candidates are skipped before execution. The first available candidate becomes the resolved route.
|
|
6
12
|
|
|
@@ -13,6 +19,8 @@ Every process uses a `RunnerSpec`:
|
|
|
13
19
|
```ts
|
|
14
20
|
interface RunnerSpec {
|
|
15
21
|
jobId: string;
|
|
22
|
+
runId?: string;
|
|
23
|
+
jobKey?: string;
|
|
16
24
|
argv: readonly string[];
|
|
17
25
|
stdin?: string;
|
|
18
26
|
mode: "advise" | "work";
|
|
@@ -22,6 +30,7 @@ interface RunnerSpec {
|
|
|
22
30
|
task?: string;
|
|
23
31
|
cwd?: string;
|
|
24
32
|
env?: NodeJS.ProcessEnv;
|
|
33
|
+
signal?: AbortSignal;
|
|
25
34
|
}
|
|
26
35
|
```
|
|
27
36
|
|
|
@@ -32,9 +41,12 @@ interface RunnerSpec {
|
|
|
32
41
|
- `CUELINE_DEPTH=1` is injected into the child.
|
|
33
42
|
- A pre-existing `CUELINE_DEPTH` in the process or job environment rejects nested routing.
|
|
34
43
|
- Standard input is closed unless the route explicitly selects stdin task input; stdout and stderr are captured as UTF-8 text.
|
|
35
|
-
-
|
|
44
|
+
- Full stdout and stderr are persisted separately. Successful non-empty stdout is the preferred controller evidence; combined output remains diagnostic status only.
|
|
36
45
|
- Exit code 0 is `succeeded`; a non-zero exit or spawn error is `failed`.
|
|
37
46
|
- At timeout CueLine sends `SIGTERM`, then schedules `SIGKILL` after 250 ms if needed; the result is `timed_out`.
|
|
47
|
+
- Cancellation uses the same owned-process termination path. `advise` becomes `cancelled`; started `work` becomes `ambiguous`.
|
|
48
|
+
- The owned POSIX process group is checked and settled on normal leader exit, cancellation, and timeout so surviving descendants cannot make a dead leader look terminal.
|
|
49
|
+
- Any non-normal owned process-loop exit, including controller repair or round-limit exhaustion, cancels and settles every active job before releasing runtime ownership. `advise` becomes `cancelled` when termination is proven; started `work` remains `ambiguous` when side effects cannot be disproved.
|
|
38
50
|
- Empty output is explicitly recorded instead of being replaced with invented content.
|
|
39
51
|
- Results are never marked retryable by the process runner.
|
|
40
52
|
|
|
@@ -42,9 +54,17 @@ For an unsuccessful `work` job, `ambiguousSideEffects` is true because CueLine c
|
|
|
42
54
|
|
|
43
55
|
## Foreground and background
|
|
44
56
|
|
|
45
|
-
A foreground `start` waits for the single execution and persists its terminal status. A background `start` persists and returns `running` immediately while the same completion promise continues. `waitForCompletion(jobId)` returns that completion or the last persisted status.
|
|
57
|
+
A foreground `start` waits for the single execution and persists its terminal status. A background `start` persists and returns `running` immediately while the same completion promise continues. `waitForCompletion(jobId)` returns that completion or the last persisted status. The supervisor persists run ID, job key, lane, mode, and child PID after spawn. PID is observability, not stand-alone cancellation authority.
|
|
58
|
+
|
|
59
|
+
`cancel(jobId)` and `cancelAll()` operate only on executions owned by the current supervisor. Cross-session CLI cancellation is a durable request consumed by that owner. CueLine does not kill an unverified process merely because a stale status file contains a PID.
|
|
60
|
+
|
|
61
|
+
The controller loop derives deterministic job IDs from the run, `job_key`, and job specification. A duplicate dispatch already present in run state is recorded as a notice and skipped. Caller result submission and continuation are runtime-lease serialized, so the first terminal evidence committed for a job wins and later submissions return `already_terminal`.
|
|
62
|
+
|
|
63
|
+
That lease is **not** an execution claim. Two sessions can both perform the same caller `advise` task before either one submits a result. Coordinate a single caller executor when resuming a handoff. This is why caller mode is restricted to non-mutating `advise`; `work` is rejected until CueLine has a duplicate-safe execution claim.
|
|
64
|
+
|
|
65
|
+
## Process concurrency
|
|
46
66
|
|
|
47
|
-
|
|
67
|
+
Explicit process execution defaults to at most two active jobs globally and two active jobs per lane. `maxConcurrency` and `laneConcurrency` may reduce or increase those limits. An all-`advise` batch uses the bounded scheduler; a batch containing any `work` job is always serial in command order.
|
|
48
68
|
|
|
49
69
|
## Availability
|
|
50
70
|
|
|
@@ -56,6 +76,6 @@ Use `advise` for analysis that should not mutate the target. Use `work` only whe
|
|
|
56
76
|
|
|
57
77
|
The controller chooses the intent; Codex and local runtime policy remain responsible for whether that intent is authorized and executable.
|
|
58
78
|
|
|
59
|
-
## Bundled
|
|
79
|
+
## Bundled process route
|
|
60
80
|
|
|
61
|
-
|
|
81
|
+
When `executor: "process"` is selected, the `default` lane contains one candidate, `codex-default`. It runs `codex exec` without a shell, sends the task over stdin, uses the requested work directory, and maps `advise` to `read-only` and `work` to `workspace-write`. The route is unavailable when the `codex` executable is not on `PATH`; CueLine reports that fact instead of selecting an unrelated worker.
|