cueline 0.1.6 → 0.2.0
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 +1 -1
- package/.codex-plugin/plugin.json +1 -1
- package/CHANGELOG.md +50 -0
- package/README.ja.md +77 -30
- package/README.ko.md +77 -30
- package/README.md +71 -29
- package/README.zh-CN.md +77 -30
- package/README.zh-TW.md +74 -29
- package/config/routing.schema.json +3 -0
- package/dist/src/api-caller-work.js +58 -14
- package/dist/src/api-caller-work.js.map +1 -1
- package/dist/src/api-contracts.d.ts +56 -0
- package/dist/src/api-controller-handoff.d.ts +5 -1
- package/dist/src/api-controller-handoff.js +178 -38
- package/dist/src/api-controller-handoff.js.map +1 -1
- package/dist/src/api-run-verification.d.ts +3 -0
- package/dist/src/api-run-verification.js +174 -0
- package/dist/src/api-run-verification.js.map +1 -0
- package/dist/src/api-runtime-lifecycle.d.ts +6 -1
- package/dist/src/api-runtime-lifecycle.js +97 -8
- package/dist/src/api-runtime-lifecycle.js.map +1 -1
- package/dist/src/api.d.ts +26 -4
- package/dist/src/api.js +111 -40
- package/dist/src/api.js.map +1 -1
- package/dist/src/browser/browser-adapter.d.ts +41 -0
- package/dist/src/browser/codex-iab/bootstrap.d.ts +21 -0
- package/dist/src/browser/codex-iab/bootstrap.js +174 -9
- package/dist/src/browser/codex-iab/bootstrap.js.map +1 -1
- package/dist/src/browser/codex-iab/chatgpt-client.d.ts +3 -0
- package/dist/src/browser/codex-iab/chatgpt-client.js +216 -70
- package/dist/src/browser/codex-iab/chatgpt-client.js.map +1 -1
- package/dist/src/browser/codex-iab/probe.d.ts +36 -0
- package/dist/src/browser/codex-iab/probe.js +217 -0
- package/dist/src/browser/codex-iab/probe.js.map +1 -0
- package/dist/src/browser/codex-iab/recovery-evidence.d.ts +1 -1
- package/dist/src/browser/codex-iab/recovery-evidence.js +7 -10
- package/dist/src/browser/codex-iab/recovery-evidence.js.map +1 -1
- package/dist/src/browser/codex-iab/selectors.d.ts +1 -0
- package/dist/src/browser/codex-iab/selectors.js +1 -0
- package/dist/src/browser/codex-iab/selectors.js.map +1 -1
- package/dist/src/browser/codex-iab/send-button.d.ts +5 -0
- package/dist/src/browser/codex-iab/send-button.js +62 -0
- package/dist/src/browser/codex-iab/send-button.js.map +1 -0
- package/dist/src/browser/codex-iab/submission-url.js +6 -15
- package/dist/src/browser/codex-iab/submission-url.js.map +1 -1
- package/dist/src/browser/codex-iab/tab-discovery.js +45 -12
- package/dist/src/browser/codex-iab/tab-discovery.js.map +1 -1
- package/dist/src/browser/codex-iab/timing-options.d.ts +1 -0
- package/dist/src/browser/codex-iab/timing-options.js +5 -0
- package/dist/src/browser/codex-iab/timing-options.js.map +1 -0
- package/dist/src/cli/health-commands.d.ts +2 -0
- package/dist/src/cli/health-commands.js +265 -0
- package/dist/src/cli/health-commands.js.map +1 -0
- package/dist/src/cli/io.d.ts +4 -0
- package/dist/src/cli/io.js +2 -0
- package/dist/src/cli/io.js.map +1 -0
- package/dist/src/cli/main.d.ts +1 -5
- package/dist/src/cli/main.js +187 -84
- package/dist/src/cli/main.js.map +1 -1
- package/dist/src/cli/observation-commands.d.ts +2 -0
- package/dist/src/cli/observation-commands.js +350 -0
- package/dist/src/cli/observation-commands.js.map +1 -0
- package/dist/src/cli/run-status-view.d.ts +87 -0
- package/dist/src/cli/run-status-view.js +121 -0
- package/dist/src/cli/run-status-view.js.map +1 -0
- package/dist/src/core/controller-command-execution.d.ts +2 -2
- package/dist/src/core/controller-command-execution.js +82 -16
- package/dist/src/core/controller-command-execution.js.map +1 -1
- package/dist/src/core/controller-conversation-archive.d.ts +11 -0
- package/dist/src/core/controller-conversation-archive.js +109 -0
- package/dist/src/core/controller-conversation-archive.js.map +1 -0
- package/dist/src/core/controller-loop.d.ts +7 -1
- package/dist/src/core/controller-loop.js +136 -23
- package/dist/src/core/controller-loop.js.map +1 -1
- package/dist/src/core/controller-turn.d.ts +21 -3
- package/dist/src/core/controller-turn.js +182 -41
- package/dist/src/core/controller-turn.js.map +1 -1
- package/dist/src/core/controller-types.d.ts +2 -0
- package/dist/src/core/conversation-url.d.ts +3 -0
- package/dist/src/core/conversation-url.js +34 -0
- package/dist/src/core/conversation-url.js.map +1 -0
- package/dist/src/core/run-status.d.ts +17 -2
- package/dist/src/core/run-status.js +64 -25
- package/dist/src/core/run-status.js.map +1 -1
- package/dist/src/core/state-machine.d.ts +36 -1
- package/dist/src/core/state-machine.js +242 -13
- package/dist/src/core/state-machine.js.map +1 -1
- package/dist/src/core/timing.d.ts +9 -0
- package/dist/src/core/timing.js +22 -0
- package/dist/src/core/timing.js.map +1 -0
- package/dist/src/diagnostics/run-doctor.d.ts +22 -0
- package/dist/src/diagnostics/run-doctor.js +197 -0
- package/dist/src/diagnostics/run-doctor.js.map +1 -0
- package/dist/src/jobs/status.d.ts +5 -2
- package/dist/src/jobs/status.js +172 -12
- package/dist/src/jobs/status.js.map +1 -1
- package/dist/src/jobs/supervisor.js +57 -8
- package/dist/src/jobs/supervisor.js.map +1 -1
- package/dist/src/observation/run-diff.d.ts +39 -0
- package/dist/src/observation/run-diff.js +67 -0
- package/dist/src/observation/run-diff.js.map +1 -0
- package/dist/src/observation/run-graph.d.ts +17 -0
- package/dist/src/observation/run-graph.js +77 -0
- package/dist/src/observation/run-graph.js.map +1 -0
- package/dist/src/observation/run-handoff.d.ts +86 -0
- package/dist/src/observation/run-handoff.js +309 -0
- package/dist/src/observation/run-handoff.js.map +1 -0
- package/dist/src/observation/run-status-at.d.ts +41 -0
- package/dist/src/observation/run-status-at.js +65 -0
- package/dist/src/observation/run-status-at.js.map +1 -0
- package/dist/src/observation/run-timeline.d.ts +32 -0
- package/dist/src/observation/run-timeline.js +279 -0
- package/dist/src/observation/run-timeline.js.map +1 -0
- package/dist/src/observation/run-watch.d.ts +15 -0
- package/dist/src/observation/run-watch.js +82 -0
- package/dist/src/observation/run-watch.js.map +1 -0
- package/dist/src/protocol/limits.d.ts +3 -0
- package/dist/src/protocol/limits.js +4 -0
- package/dist/src/protocol/limits.js.map +1 -0
- package/dist/src/protocol/lint-command.d.ts +24 -0
- package/dist/src/protocol/lint-command.js +210 -0
- package/dist/src/protocol/lint-command.js.map +1 -0
- package/dist/src/protocol/parse-command.js +4 -0
- package/dist/src/protocol/parse-command.js.map +1 -1
- package/dist/src/protocol/types.d.ts +12 -0
- package/dist/src/protocol/validate-command.js +76 -3
- package/dist/src/protocol/validate-command.js.map +1 -1
- package/dist/src/router/config-loader.js +23 -2
- package/dist/src/router/config-loader.js.map +1 -1
- package/dist/src/router/explain.d.ts +28 -0
- package/dist/src/router/explain.js +86 -0
- package/dist/src/router/explain.js.map +1 -0
- package/dist/src/router/resolver.d.ts +2 -1
- package/dist/src/router/resolver.js +11 -6
- package/dist/src/router/resolver.js.map +1 -1
- package/dist/src/runners/process-runner.js +55 -12
- package/dist/src/runners/process-runner.js.map +1 -1
- package/dist/src/runners/runner-adapter.d.ts +2 -0
- package/dist/src/runners/runner-adapter.js.map +1 -1
- package/dist/src/state/atomic-write.d.ts +6 -0
- package/dist/src/state/atomic-write.js +43 -2
- package/dist/src/state/atomic-write.js.map +1 -1
- package/dist/src/state/cancellation.js +38 -4
- package/dist/src/state/cancellation.js.map +1 -1
- package/dist/src/state/event-log.js +5 -4
- package/dist/src/state/event-log.js.map +1 -1
- package/dist/src/state/private-directory.d.ts +5 -0
- package/dist/src/state/private-directory.js +37 -0
- package/dist/src/state/private-directory.js.map +1 -0
- package/dist/src/state/runtime-lease.js +19 -39
- package/dist/src/state/runtime-lease.js.map +1 -1
- package/dist/src/state/runtime-record-validation.d.ts +6 -0
- package/dist/src/state/runtime-record-validation.js +44 -0
- package/dist/src/state/runtime-record-validation.js.map +1 -0
- package/dist/src/state/runtime-retirement.js +58 -18
- package/dist/src/state/runtime-retirement.js.map +1 -1
- package/dist/src/state/runtime-takeover-intent.js +2 -2
- package/dist/src/state/runtime-takeover-intent.js.map +1 -1
- package/dist/src/state/store.d.ts +1 -0
- package/dist/src/state/store.js +12 -6
- 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 +4 -4
- package/docs/assets/README.md +3 -1
- package/docs/assets/cueline-architecture-en.svg +63 -0
- package/docs/assets/cueline-architecture-ja.svg +63 -0
- package/docs/assets/cueline-architecture-ko.svg +63 -0
- package/docs/assets/cueline-architecture-zh-CN.svg +63 -0
- package/docs/assets/cueline-architecture-zh-TW.svg +63 -0
- package/docs/assets/cueline-states-en.svg +50 -0
- package/docs/assets/cueline-states-ja.svg +48 -0
- package/docs/assets/cueline-states-ko.svg +48 -0
- package/docs/assets/cueline-states-zh-CN.svg +48 -0
- package/docs/assets/cueline-states-zh-TW.svg +48 -0
- package/docs/compatibility.md +1 -1
- package/docs/controller-protocol.md +44 -7
- package/docs/experiments/protocol-lint.md +40 -0
- package/docs/experiments/run-doctor.md +39 -0
- package/docs/experiments/run-handoff.md +39 -0
- package/docs/experiments/run-timeline.md +35 -0
- package/docs/experiments/run-watch.md +31 -0
- package/docs/multi-model-routing.md +256 -0
- package/docs/runner-contract.md +4 -3
- package/docs/state-and-recovery.md +45 -5
- package/package.json +1 -1
- package/schemas/controller-command.schema.json +89 -4
- package/skills/cueline/SKILL.md +13 -7
package/README.md
CHANGED
|
@@ -5,6 +5,9 @@
|
|
|
5
5
|
|
|
6
6
|
<p align="center">
|
|
7
7
|
<a href="https://github.com/Seraphim0916/cueline/actions/workflows/ci.yml"><img alt="ci" src="https://github.com/Seraphim0916/cueline/actions/workflows/ci.yml/badge.svg"></a>
|
|
8
|
+
<a href="https://www.npmjs.com/package/cueline"><img alt="npm" src="https://img.shields.io/npm/v/cueline"></a>
|
|
9
|
+
<a href="package.json"><img alt="node" src="https://img.shields.io/node/v/cueline"></a>
|
|
10
|
+
<a href="LICENSE"><img alt="license" src="https://img.shields.io/npm/l/cueline"></a>
|
|
8
11
|
</p>
|
|
9
12
|
|
|
10
13
|
<p align="center">
|
|
@@ -15,24 +18,46 @@
|
|
|
15
18
|
|
|
16
19
|
The web page never touches your machine and has no local tools. It only emits one text command per round. CueLine decides whether that command is well-formed and belongs to this run. By default, it persists caller jobs for the current Codex: `advise` is a coordination-only handoff, while `work` requires a durable claim and start before any mutation. An explicitly double-authorized process executor can instead run registered local workers. CueLine keeps bounded controller evidence and the full local record.
|
|
17
20
|
|
|
21
|
+
<img alt="CueLine architecture: a ChatGPT web conversation issues one text command per round, CueLine validates and records it, and the current Codex performs the permitted local work." src="docs/assets/cueline-architecture-en.svg" width="100%">
|
|
22
|
+
|
|
18
23
|
CueLine is a standalone implementation with **no runtime npm dependencies**. It is not a wrapper around Omnilane or GPT Relay.
|
|
19
24
|
|
|
25
|
+
## Latest release: 0.2.0
|
|
26
|
+
|
|
27
|
+
- Add four read-only observability commands and strengthen confirmed-not-sent submission recovery, with fail-closed redaction and pre-spawn routing explanations.
|
|
28
|
+
- Added safe run inventory, doctor, watch, timeline, handoff, verification, protocol lint, browser diagnostics, and deterministic inspected-evidence pagination.
|
|
29
|
+
- Hardened browser tab/control evidence, command/routing bounds, atomic job status, private durable state, workdir identity, runtime/cancellation records, and redacted CLI output.
|
|
30
|
+
- Added opt-in exact-conversation archiving after durable `complete`, with a one-click write-ahead fence, Pro-active/navigation checks, and no retry after ambiguity.
|
|
31
|
+
- Verified 479/479 tests and a disposable real ChatGPT Web Pro run that completed and archived exactly once without interrupting Pro or touching the existing user conversation.
|
|
32
|
+
|
|
33
|
+
Read the complete [changelog](CHANGELOG.md#020---2026-07-16) or the versioned [v0.2.0 release](https://github.com/Seraphim0916/cueline/releases/tag/v0.2.0).
|
|
34
|
+
|
|
20
35
|
## How a run actually goes
|
|
21
36
|
|
|
22
37
|
<img alt="A caller-first CueLine run: ChatGPT emits text commands, the current Codex performs local advice, and CueLine returns bounded evidence until complete." src="docs/assets/cueline-loop-en.svg" width="100%">
|
|
23
38
|
|
|
24
39
|
Each round: CueLine writes down what it is about to ask, sends one observation into the conversation, and later reads back exactly one `<CueLineControl>` envelope. The controller picks one of five actions — `dispatch`, `wait`, `inspect`, `complete`, `blocked` — and nothing outside that envelope is ever executed. A command that names the wrong run, the wrong round, or a malformed job is sent back for a bounded repair attempt rather than guessed at. The loop pauses at `awaiting_controller` after one durable send, at a caller handoff, or stops at `complete`, `blocked`, or the round limit (12 by default).
|
|
25
40
|
|
|
41
|
+
Controller commands also have fail-closed resource bounds: 131,072 characters
|
|
42
|
+
per envelope, 64 jobs per dispatch, and 256 explicit job IDs per wait or
|
|
43
|
+
inspect. These checks happen before job registration or process execution.
|
|
44
|
+
|
|
26
45
|
A non-default `maxRounds` is fixed when the run is created and counts total controller rounds across every ownerless pause. Later continuations normally omit it and reuse the durable value; supplying a different value is rejected rather than silently resetting or widening the budget.
|
|
27
46
|
|
|
28
|
-
`caller` is the default executor for both `startCueLineRun` and `runCueLine`. With the built-in browser, CueLine submits once, captures the exact conversation URL, returns `awaiting_controller`, and releases the runtime lease instead of holding one tool call open while Pro thinks. A later `continueCueLineRun` performs one read-only observation: unfinished work returns `awaiting_controller` again without resending. A dispatch produces durable pending jobs. `advise` returns `awaiting_caller`; it has no side-effect claim, so coordinate one session. `work` returns `awaiting_caller_work` and remains unstarted until the current Codex calls `claimCueLineCallerJob` and `startCueLineCallerJob`. The claim is bound to run, job, task hash, absolute workdir, caller identity, and a fencing token
|
|
47
|
+
`caller` is the default executor for both `startCueLineRun` and `runCueLine`. With the built-in browser, CueLine submits once, captures the exact conversation URL, returns `awaiting_controller`, and releases the runtime lease instead of holding one tool call open while Pro thinks. A later `continueCueLineRun` performs one read-only observation: unfinished work returns `awaiting_controller` again without resending. A dispatch produces durable pending jobs. `advise` returns `awaiting_caller`; it has no side-effect claim, so coordinate one session. `work` returns `awaiting_caller_work` and remains unstarted until the current Codex calls `claimCueLineCallerJob` and `startCueLineCallerJob`. The claim is bound to run, job, task hash, absolute workdir, canonical directory identity, caller identity, and a fencing token; callers execute only in its returned `resolvedWorkdir`. Started work is never automatically retried; an expired started claim becomes `ambiguous`. ChatGPT proposed and reviewed the work—it did not use local tools or perform the work itself.
|
|
29
48
|
|
|
30
|
-
Process execution requires both `executor: "process"` and `allowProcessExecution: true`; a non-terminal continuation must pass the second authorization again. The bundled route also uses `--ignore-user-config`, preventing hidden workers from loading user-configured MCP servers or their command arguments. The controller chooses *what should happen* and the local side chooses *whether and how it may happen*: the lane must be enabled, the candidate must be available **before** anything spawns, and `argv[0]` must already be registered by your routing config. Nothing is passed through a shell. Independent advice defaults to two concurrent jobs globally and per lane; a batch containing `work` is serial. Once a worker starts, there is no silent fallback to a second candidate. Status exposes the resolved runner, PID, phase, last progress time, and safely observed model/provider metadata.
|
|
49
|
+
Process execution requires both `executor: "process"` and `allowProcessExecution: true`; a non-terminal continuation must pass the second authorization again. The bundled route also uses `--ignore-user-config`, preventing hidden workers from loading user-configured MCP servers or their command arguments. The controller chooses *what should happen* and the local side chooses *whether and how it may happen*: the lane must be enabled, the candidate must be available **before** anything spawns, and `argv[0]` must already be registered by your routing config. Nothing is passed through a shell. A process `workdir` must be absolute; when omitted, CueLine binds the accepted job to the runtime's resolved absolute workspace so recovery cannot silently move it to another checkout. Independent advice defaults to two concurrent jobs globally and per lane; a batch containing `work` is serial. Once a worker starts, there is no silent fallback to a second candidate. Status exposes the resolved runner, PID, phase, last progress time, and safely observed model/provider metadata.
|
|
31
50
|
|
|
32
51
|
The controller protocol keeps routing levels explicit: `lane` names the lane (`default`), while `codex-default` is a candidate runner inside that lane, not a lane. CueLine validates the entire `dispatch` before registering any job; an invalid lane or runner rejects the whole dispatch for repair, so no valid-looking subset starts early.
|
|
33
52
|
|
|
34
53
|
That process route is an allow-list, not a sandbox. A registered worker runs with the same permissions as the CueLine process itself; `advise` maps to a read-only Codex sandbox and `work` to `workspace-write`, but what you register is what you have authorized.
|
|
35
54
|
|
|
55
|
+
## Run states
|
|
56
|
+
|
|
57
|
+
<img alt="CueLine run states: ready, awaiting_controller, awaiting_caller, awaiting_caller_work, complete, blocked, cancelled — and what each one means." src="docs/assets/cueline-states-en.svg" width="100%">
|
|
58
|
+
|
|
59
|
+
`cueline run status <run-id> --json` reports the durable state plus a `safeNextAction`; `cueline run doctor <run-id> --json` turns the same snapshot into stable finding codes and one safe next step. When anything is ambiguous — a possibly-sent click, an expired started claim, a manual attachment send — CueLine stops and asks for an explicit reconcile instead of resending. The full recovery contract lives in [state and recovery](docs/state-and-recovery.md).
|
|
60
|
+
|
|
36
61
|
## The controller must be a Pro model
|
|
37
62
|
|
|
38
63
|
CueLine refuses to send unless the composer's model selector reads `Pro`. If the conversation sits on another model, CueLine switches the composer to `Pro` first — that is the only model switch it is allowed to make. In a verified live run it switched Instant to Pro and the reply came back as `gpt-5-6-pro`.
|
|
@@ -48,15 +73,15 @@ You need Node.js 22+, Codex with its built-in Browser, and — for the bundled d
|
|
|
48
73
|
Install from the npm registry:
|
|
49
74
|
|
|
50
75
|
```bash
|
|
51
|
-
npm install -g cueline@0.
|
|
76
|
+
npm install -g cueline@0.2.0
|
|
52
77
|
cueline install
|
|
53
78
|
cueline doctor
|
|
54
79
|
```
|
|
55
80
|
|
|
56
|
-
As a fallback, install the packaged tarball from the [v0.
|
|
81
|
+
As a fallback, install the packaged tarball from the [v0.2.0 release](https://github.com/Seraphim0916/cueline/releases/tag/v0.2.0), which also carries its `.sha256` checksum:
|
|
57
82
|
|
|
58
83
|
```bash
|
|
59
|
-
npm install -g https://github.com/Seraphim0916/cueline/releases/download/v0.
|
|
84
|
+
npm install -g https://github.com/Seraphim0916/cueline/releases/download/v0.2.0/cueline-0.2.0.tgz
|
|
60
85
|
cueline install
|
|
61
86
|
cueline doctor
|
|
62
87
|
```
|
|
@@ -79,7 +104,7 @@ cueline doctor
|
|
|
79
104
|
Then, in Codex:
|
|
80
105
|
|
|
81
106
|
1. Open `https://chatgpt.com` in Codex's built-in Browser and sign in.
|
|
82
|
-
2. Leave the conversation you want to be in charge selected — that page is the controller. Its composer must be on a `Pro` model; CueLine selects `Pro` for you if it is not, and refuses to send otherwise.
|
|
107
|
+
2. Leave the conversation you want to be in charge selected — that page is the controller. If no selected tab is available and several matching ChatGPT tabs exist, CueLine returns `IAB_CHATGPT_TAB_AMBIGUOUS` instead of choosing the first one. Its composer must be on a `Pro` model; CueLine selects `Pro` for you if it is not, and refuses to send otherwise.
|
|
83
108
|
3. Ask Codex to use CueLine for the task: *"Use CueLine and let the open ChatGPT Pro conversation direct this task."*
|
|
84
109
|
4. Keep the returned `runId`. It is how an interrupted run is resumed.
|
|
85
110
|
|
|
@@ -101,6 +126,7 @@ import {
|
|
|
101
126
|
let result = await runCueLine({
|
|
102
127
|
request: "Inspect the repository, delegate an implementation plan, and report the evidence.",
|
|
103
128
|
browser: createCodexIabAdapter({ browser: globalThis.browser }),
|
|
129
|
+
// Optional opt-in: archiveControllerConversationOnComplete: true,
|
|
104
130
|
// Optional: conversationUrl, routingConfig / routingConfigPath, home, cwd,
|
|
105
131
|
// runTimeoutMs, signal, and per-job/default limits.
|
|
106
132
|
}); // defaults to executor: "caller"
|
|
@@ -128,7 +154,7 @@ while (["awaiting_controller", "awaiting_caller", "awaiting_caller_work"].includ
|
|
|
128
154
|
fencingToken: claim.fencingToken,
|
|
129
155
|
};
|
|
130
156
|
await startCueLineCallerJob(result.runId, job.jobId, proof);
|
|
131
|
-
const stdout = await executeExactLocalWork(job.spec.task, claim.
|
|
157
|
+
const stdout = await executeExactLocalWork(job.spec.task, claim.resolvedWorkdir, {
|
|
132
158
|
heartbeat: () => heartbeatCueLineCallerJob(result.runId, job.jobId, proof),
|
|
133
159
|
});
|
|
134
160
|
await submitCueLineCallerJobResult(
|
|
@@ -147,20 +173,29 @@ if (result.status === "complete") {
|
|
|
147
173
|
}
|
|
148
174
|
```
|
|
149
175
|
|
|
150
|
-
`
|
|
176
|
+
`archiveControllerConversationOnComplete` defaults to `false` and is fixed when the run is created. When enabled, CueLine first persists `complete`, then archives only the exact bound conversation while Pro is idle. A proven failure before the durable click checkpoint can be retried; after that checkpoint, any timeout, restart, navigation race, or missing proof becomes `ambiguous` and CueLine never clicks Archive again. `blocked` and `cancelled` runs are left open.
|
|
177
|
+
|
|
178
|
+
`startCueLineRun` creates the durable run and returns `ready` without driving the browser. `runCueLine` creates and advances it to a durable controller-observation pause, caller handoff, or terminal state. `continueCueLineRun({ runId })` advances the same conversation and reuses its stored URL. `loadCueLineRunState(runId)` is read-only. A terminal run is returned as-is. Before continuation, run `cueline run status <run-id> --json`: `controller_response_pending` with exactly one normally submitted turn and `safeNextAction: observe` means Pro's response has not yet been observed; wait briefly and continue it without resend. That exact read-only observer can be safely fenced even after its lease becomes stale, but ambiguous/manual submissions, jobs, pending commands, cancellation, or a missing/mismatched URL still require explicit recovery. `phase: prompt_not_sent` with `safeNextAction: retry` is used only with write-ahead or request-correlated `definitely_not_sent` evidence. Caller work phases report `claim_caller_work`, `start_caller_work`, or `continue_caller_work`; a dispatch alone is not local execution. An accepted response plus `jobs_running` means a double-authorized process executor is active. CLI status output is an explicit metadata allowlist: it omits task bodies, caller identities, task hashes, workdirs, and runtime owner IDs. The formal caller claim API returns the exact task and workdir to the authorized caller; the detailed read-only API remains available for trusted local diagnostics.
|
|
179
|
+
|
|
180
|
+
`listCueLineRuns()` is a read-only, sanitized inventory for discovering persisted run IDs. It omits controller text, conversation URLs, job tasks, and worker output.
|
|
181
|
+
|
|
182
|
+
`verifyCueLineRun(runId)` is a read-only integrity check for the creation marker, event replay and authority fences, optional snapshot, runtime lease, and job status evidence. It returns stable findings without returning durable run content.
|
|
151
183
|
|
|
152
184
|
Inside Codex's runtime, import the absolute module that `cueline api path` prints — that is the built API of the package you installed.
|
|
153
185
|
|
|
154
186
|
## The CLI
|
|
155
187
|
|
|
156
|
-
The CLI does not drive the browser.
|
|
188
|
+
The CLI does not drive the browser. Run `cueline help` for every positional argument and option before using a state-changing command.
|
|
157
189
|
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
190
|
+
| Group | Commands | Effect |
|
|
191
|
+
| --- | --- | --- |
|
|
192
|
+
| Inspect | `doctor` · `routing` · `jobs` · `runs` · `run status` · `run doctor` · `run watch` · `run timeline` · `run verify` · `run handoff` · `protocol lint` · `api path` · `config path` | Read-only |
|
|
193
|
+
| Install | `install` · `uninstall` | Create or remove only the package-owned skill link |
|
|
194
|
+
| Recover | `run reconcile` · `run takeover` · `run reconcile-runtime` · `run cancel` / `run stop` · `job cancel` | Append evidence or change durable local run/job state |
|
|
161
195
|
|
|
196
|
+
```console
|
|
162
197
|
$ cueline doctor
|
|
163
|
-
CueLine 0.
|
|
198
|
+
CueLine 0.2.0
|
|
164
199
|
status ok
|
|
165
200
|
node 22.14.0 ok
|
|
166
201
|
config /usr/local/lib/node_modules/cueline/config/routing.default.json valid
|
|
@@ -169,35 +204,33 @@ caller_ready yes
|
|
|
169
204
|
caller_lanes 1
|
|
170
205
|
process_available_lanes 1
|
|
171
206
|
|
|
172
|
-
$ cueline api path
|
|
173
|
-
/usr/local/lib/node_modules/cueline/dist/src/api.js
|
|
174
|
-
|
|
175
207
|
$ cueline routing
|
|
176
208
|
default codex-default available
|
|
177
209
|
|
|
178
|
-
$ cueline jobs
|
|
179
|
-
No jobs.
|
|
180
|
-
|
|
181
210
|
$ cueline run status run_... --json
|
|
182
211
|
{"status":"running","executor":"caller","phase":"caller_jobs_pending","runtime":{"ownership":"missing"},...}
|
|
183
212
|
|
|
184
|
-
$ cueline run
|
|
185
|
-
{"
|
|
213
|
+
$ cueline run doctor run_... --json
|
|
214
|
+
{"outcome":"action_required","phase":"caller_jobs_pending","nextAction":"execute_caller_jobs",...}
|
|
186
215
|
|
|
187
216
|
$ cueline run reconcile run_... --request-id msg_... --manual-send-confirmed --conversation-url https://chatgpt.com/c/...
|
|
188
217
|
run_...\tmsg_...\tconfirmed
|
|
189
218
|
|
|
190
219
|
$ cueline run cancel run_...
|
|
191
220
|
run_... requested affected_jobs=0
|
|
221
|
+
```
|
|
192
222
|
|
|
193
|
-
|
|
194
|
-
/usr/local/lib/node_modules/cueline/config/routing.default.json
|
|
223
|
+
`cueline doctor` exits non-zero when Node is too old or no enabled caller lane exists. `process_available_lanes` may be zero without degrading caller mode; use `cueline routing` to inspect process availability before explicitly selecting that executor. `cueline api path` is what the skill imports, so a packaged install needs no repository checkout. Every command supports `--json` where shown by `cueline help`.
|
|
195
224
|
|
|
196
|
-
|
|
197
|
-
CueLine skill removed: /Users/you/.codex/skills/cueline
|
|
198
|
-
```
|
|
225
|
+
The experimental diagnosis commands each have a focused doc:
|
|
199
226
|
|
|
200
|
-
|
|
227
|
+
| Command | What it does | Doc |
|
|
228
|
+
| --- | --- | --- |
|
|
229
|
+
| `run doctor` | Converts a run snapshot into stable finding codes, bounded evidence, and a safe next action without writing state | [run-doctor](docs/experiments/run-doctor.md) |
|
|
230
|
+
| `run watch` | Bounded, lease-free observation using the durable event sequence as its cursor | [run-watch](docs/experiments/run-watch.md) |
|
|
231
|
+
| `protocol lint` | Validates a Pro envelope offline and reports all known contract corrections in one pass | [protocol-lint](docs/experiments/protocol-lint.md) |
|
|
232
|
+
| `run handoff` | Produces a safe restart packet with exact identities and absolute paths | [run-handoff](docs/experiments/run-handoff.md) |
|
|
233
|
+
| `run timeline` | Sanitized, cursor-paginated audit view without raw event payloads | [run-timeline](docs/experiments/run-timeline.md) |
|
|
201
234
|
|
|
202
235
|
Use `run takeover` only when `run status` reports an exact stale owner. It refuses a fresh active heartbeat and returns `next: continue` or `next: reconcile_runtime`; follow that value instead of guessing.
|
|
203
236
|
|
|
@@ -207,6 +240,8 @@ Use `run takeover` only when `run status` reports an exact stale owner. It refus
|
|
|
207
240
|
|
|
208
241
|
Caller execution needs no spawned route. When `executor: "process"` and `allowProcessExecution: true` are both selected, the bundled `default` lane holds one candidate, `codex-default`: isolated `codex exec --ignore-user-config` with the task on stdin, `read-only` for `advise`, and `workspace-write` for `work`. To register a different process worker, copy [`config/routing.default.json`](config/routing.default.json), add your candidate, and point `CUELINE_CONFIG` at it.
|
|
209
242
|
|
|
243
|
+
For multiple model-specific candidates and advise-only wrapper examples, see [Multi-model routing](docs/multi-model-routing.md).
|
|
244
|
+
|
|
210
245
|
State lives under `CUELINE_HOME`:
|
|
211
246
|
|
|
212
247
|
```text
|
|
@@ -225,7 +260,7 @@ Recovery reattaches only to the exact recorded conversation URL. CueLine recogni
|
|
|
225
260
|
|
|
226
261
|
Never interrupt Pro or use `Answer now`, `Respond now`, `Stop`, or an equivalent acceleration control while it is answering. Pro has no local tools and no default knowledge of repository layout or local paths. Caller evidence must include exact code/error identifiers, relevant code excerpts, and absolute local paths, then explicitly ask whether Pro needs more local evidence.
|
|
227
262
|
|
|
228
|
-
Controller observations prefer successful non-empty stdout, retain full stdout/stderr in local job status, and share one 12,000-character evidence budget with an explicit truncation marker. An accepted `inspect(job_ids)` reserves that budget for the named jobs before unrelated evidence, so the next Pro turn receives the requested output instead of only its terminal status.
|
|
263
|
+
Controller observations prefer successful non-empty stdout, retain full stdout/stderr in local job status, and share one 12,000-character evidence budget with an explicit truncation marker. Every preferred output/error field includes a raw-character `evidence_window` and SHA-256 `content_hash`. When `next_offset` is non-null, Pro can inspect exactly one job by copying it as `evidence_offset` and the hash as `evidence_hash`; CueLine returns the next bounded window without rerunning the job. Changed evidence invalidates the cursor instead of mixing versions. An accepted `inspect(job_ids)` reserves that budget for the named jobs before unrelated evidence, so the next Pro turn receives the requested output instead of only its terminal status. `wait` and `inspect` targets must be exact job IDs from the current observation; one unknown target rejects the entire command for repair before any partial wait or inspection. Controller commands are exact per action: unknown top-level fields, fields belonging to another action, empty/duplicate/malformed `job_ids`, `prompt` in place of `task`, and `runner_id` in place of `runner` are rejected with a repair error instead of silently ignored.
|
|
229
264
|
|
|
230
265
|
## Verify
|
|
231
266
|
|
|
@@ -248,7 +283,14 @@ See [compatibility](docs/compatibility.md) for the full matrix.
|
|
|
248
283
|
|
|
249
284
|
## Docs
|
|
250
285
|
|
|
251
|
-
|
|
286
|
+
| Doc | What it covers |
|
|
287
|
+
| --- | --- |
|
|
288
|
+
| [architecture](docs/architecture.md) | How the pieces fit and where the trust boundaries sit |
|
|
289
|
+
| [controller protocol](docs/controller-protocol.md) | The `<CueLineControl>` envelope, the five actions, and repair rules |
|
|
290
|
+
| [runner contract](docs/runner-contract.md) | What a registered process worker must and must not do |
|
|
291
|
+
| [state and recovery](docs/state-and-recovery.md) | Durable state layout, ownership, and every recovery path |
|
|
292
|
+
| [compatibility](docs/compatibility.md) | Supported platforms, runtimes, and UI assumptions |
|
|
293
|
+
| [provenance](docs/provenance.md) | Where the design comes from and what it is not |
|
|
252
294
|
|
|
253
295
|
## Development
|
|
254
296
|
|
package/README.zh-CN.md
CHANGED
|
@@ -5,6 +5,9 @@
|
|
|
5
5
|
|
|
6
6
|
<p align="center">
|
|
7
7
|
<a href="https://github.com/Seraphim0916/cueline/actions/workflows/ci.yml"><img alt="ci" src="https://github.com/Seraphim0916/cueline/actions/workflows/ci.yml/badge.svg"></a>
|
|
8
|
+
<a href="https://www.npmjs.com/package/cueline"><img alt="npm" src="https://img.shields.io/npm/v/cueline"></a>
|
|
9
|
+
<a href="package.json"><img alt="node" src="https://img.shields.io/node/v/cueline"></a>
|
|
10
|
+
<a href="LICENSE"><img alt="license" src="https://img.shields.io/npm/l/cueline"></a>
|
|
8
11
|
</p>
|
|
9
12
|
|
|
10
13
|
<p align="center">
|
|
@@ -13,16 +16,30 @@
|
|
|
13
16
|
|
|
14
17
|
**CueLine 把方向盘交给一个已经打开的 ChatGPT 网页会话:由它规划运行、发出每一步文本指令;CueLine 负责校验,当前 Codex 才在本机执行获准的工作。**
|
|
15
18
|
|
|
16
|
-
|
|
19
|
+
那个网页碰不到你的机器,也没有本地工具。它每一轮只发出一条文本控制指令。CueLine 默认把 caller 作业持久化:`advise` 是协调式交接;`work` 必须先获得持久 claim 并正式 start。只有双重显式授权 `process` executor,才会启动已注册的本地 worker。
|
|
20
|
+
|
|
21
|
+
<img alt="CueLine 架构:ChatGPT 网页会话每轮发出一条文本指令,CueLine 校验并记录,当前 Codex 执行获准的本地工作。" src="docs/assets/cueline-architecture-zh-CN.svg" width="100%">
|
|
17
22
|
|
|
18
23
|
CueLine 是独立实现,**没有任何运行时 npm 依赖**,也不是 Omnilane 或 GPT Relay 的包装层。
|
|
19
24
|
|
|
25
|
+
## 最新版本:0.2.0
|
|
26
|
+
|
|
27
|
+
- 新增四个只读可观测性命令,并强化“确认未发送”的提交恢复;输出保持 fail-closed 脱敏,路由解释也只发生在进程启动前。
|
|
28
|
+
- 新增安全的 run 清单、doctor、watch、timeline、handoff、完整性验证、协议 lint、浏览器诊断与 inspect 证据分页。
|
|
29
|
+
- 强化标签页/按钮证据、命令与路由上限、原子 job 状态、私有持久数据、workdir 身份、runtime/取消记录和 CLI 脱敏。
|
|
30
|
+
- 新增可选的 `complete` 后精确会话归档:点击前有持久 fence,Pro 再次回答或页面切换时拒绝,进入模糊状态后绝不重复点击。
|
|
31
|
+
- 完成 479/479 测试和一次可丢弃的真实 ChatGPT Web Pro 验收;控制器自然完成、只归档一次,原有用户会话未被触碰。
|
|
32
|
+
|
|
33
|
+
完整内容请查看 [changelog](CHANGELOG.md#020---2026-07-16) 或版本化的 [v0.2.0 release](https://github.com/Seraphim0916/cueline/releases/tag/v0.2.0)。
|
|
34
|
+
|
|
20
35
|
## 一次运行实际是怎么走的
|
|
21
36
|
|
|
22
37
|
<img alt="Caller-first CueLine 运行:ChatGPT 发出文本命令,当前 Codex 执行本地只读检查,CueLine 回传有界证据直至 complete。" src="docs/assets/cueline-loop-zh-CN.svg" width="100%">
|
|
23
38
|
|
|
24
39
|
每一轮:CueLine 先把“接下来要问什么”写入记录,向会话发送一份观测(observation),之后再读回**恰好一个** `<CueLineControl>` 信封。控制器从五个动作中选一个——`dispatch`、`wait`、`inspect`、`complete`、`blocked`——信封之外的任何文本都不会被执行。循环会在一次可靠发送后以 `awaiting_controller` 暂停,也会停在 caller 交接、`complete`、`blocked` 或轮次上限(默认 12 轮)。
|
|
25
40
|
|
|
41
|
+
控制器命令还有 fail-closed 资源上限:每个信封 131,072 字符、每次 dispatch 最多 64 个作业、每次 wait 或 inspect 最多 256 个显式 job ID。这些检查发生在注册作业或启动进程之前。
|
|
42
|
+
|
|
26
43
|
非默认的 `maxRounds` 会在创建 run 时固定,并跨所有无 owner 的暂停累计控制器总轮次。后续继续通常省略它并复用持久值;传入不同数值会被拒绝,不会暗中重置或放宽预算。
|
|
27
44
|
|
|
28
45
|
`startCueLineRun` 与 `runCueLine` 都默认使用 `caller`。CueLine 发送一次后返回 `awaiting_controller` 并释放 lease;继续只做一次只读观测,绝不重发。`advise` 返回 `awaiting_caller`,没有副作用 claim;`work` 返回 `awaiting_caller_work`,必须由当前 Codex 调用 `claimCueLineCallerJob` 与 `startCueLineCallerJob` 后才能修改。claim 绑定 run、job、task hash、绝对 workdir、caller identity 与 fencing token;已开始的工作不会自动重试,过期后成为 `ambiguous`。Pro 只提出和审查文本指令,不会使用本地工具。
|
|
@@ -33,6 +50,12 @@ Process 模式必须同时指定 `executor: "process"` 与 `allowProcessExecutio
|
|
|
33
50
|
|
|
34
51
|
这是白名单(allow-list),不是沙箱。已注册的 worker 拥有与 CueLine 进程本身相同的权限;`advise` 对应 Codex 的只读沙箱、`work` 对应 `workspace-write`,但你注册了什么,就等于你授权了什么。
|
|
35
52
|
|
|
53
|
+
## 运行状态
|
|
54
|
+
|
|
55
|
+
<img alt="CueLine 运行状态:ready、awaiting_controller、awaiting_caller、awaiting_caller_work、complete、blocked、cancelled,以及每个状态的含义。" src="docs/assets/cueline-states-zh-CN.svg" width="100%">
|
|
56
|
+
|
|
57
|
+
`cueline run status <run-id> --json` 报告持久状态和 `safeNextAction`;`cueline run doctor <run-id> --json` 把同一份快照转成稳定的 finding 代码和一个安全的下一步。任何模糊情形——可能已发送的点击、过期的已启动 claim、人工附件发送——CueLine 都会停下来要求显式 reconcile,而不是重发。完整恢复契约见 [state and recovery](docs/state-and-recovery.md)。
|
|
58
|
+
|
|
36
59
|
## 控制器必须是 Pro 模型
|
|
37
60
|
|
|
38
61
|
除非输入框的模型选择器显示 `Pro`,否则 CueLine 拒绝发送。会话若停在别的模型,CueLine 会先把输入框切换到 `Pro`——这是它唯一被允许做的模型切换。在一次已验证的实机运行中,它把 Instant 切换为 Pro,返回的响应是 `gpt-5-6-pro`。
|
|
@@ -48,15 +71,15 @@ ChatGPT Pro 订阅套餐与“选定的 Pro 模型”是两回事。账号或个
|
|
|
48
71
|
从 npm registry 安装:
|
|
49
72
|
|
|
50
73
|
```bash
|
|
51
|
-
npm install -g cueline@0.
|
|
74
|
+
npm install -g cueline@0.2.0
|
|
52
75
|
cueline install
|
|
53
76
|
cueline doctor
|
|
54
77
|
```
|
|
55
78
|
|
|
56
|
-
作为后备,也可以安装 [v0.
|
|
79
|
+
作为后备,也可以安装 [v0.2.0 release](https://github.com/Seraphim0916/cueline/releases/tag/v0.2.0) 上的打包 tarball,该 release 同时附带它的 `.sha256` 校验值:
|
|
57
80
|
|
|
58
81
|
```bash
|
|
59
|
-
npm install -g https://github.com/Seraphim0916/cueline/releases/download/v0.
|
|
82
|
+
npm install -g https://github.com/Seraphim0916/cueline/releases/download/v0.2.0/cueline-0.2.0.tgz
|
|
60
83
|
cueline install
|
|
61
84
|
cueline doctor
|
|
62
85
|
```
|
|
@@ -79,7 +102,7 @@ cueline doctor
|
|
|
79
102
|
然后,在 Codex 里:
|
|
80
103
|
|
|
81
104
|
1. 用 Codex 的内置浏览器打开 `https://chatgpt.com` 并登录。
|
|
82
|
-
2.
|
|
105
|
+
2. 让你想让它当控制器的那个会话保持选中——该页面就是控制器。若没有已选中的标签页、且同时存在多个匹配的 ChatGPT 标签页,CueLine 会返回 `IAB_CHATGPT_TAB_AMBIGUOUS`,而不是擅自挑第一个。它的输入框必须停在 `Pro` 模型;若不是,CueLine 会替你选成 `Pro`,否则就拒绝发送。
|
|
83
106
|
3. 让 Codex 用 CueLine 处理任务:*“用 CueLine,让那个打开的 ChatGPT Pro 会话来指挥这项任务。”*
|
|
84
107
|
4. 保留返回的 `runId`。被中断的运行要续跑,就靠它。
|
|
85
108
|
|
|
@@ -101,6 +124,7 @@ import {
|
|
|
101
124
|
let result = await runCueLine({
|
|
102
125
|
request: "Inspect the repository, delegate an implementation plan, and report the evidence.",
|
|
103
126
|
browser: createCodexIabAdapter({ browser: globalThis.browser }),
|
|
127
|
+
// 可选并显式启用:archiveControllerConversationOnComplete: true,
|
|
104
128
|
// 可选:conversationUrl、routingConfig / routingConfigPath、home、cwd、
|
|
105
129
|
// runTimeoutMs、signal,以及作业/默认期限。
|
|
106
130
|
}); // 默认 executor: "caller"
|
|
@@ -124,7 +148,7 @@ while (["awaiting_controller", "awaiting_caller", "awaiting_caller_work"].includ
|
|
|
124
148
|
});
|
|
125
149
|
const proof = { claimId: claim.claimId, callerId: claim.callerId, fencingToken: claim.fencingToken };
|
|
126
150
|
await startCueLineCallerJob(result.runId, job.jobId, proof);
|
|
127
|
-
const stdout = await executeExactLocalWork(job.spec.task, claim.
|
|
151
|
+
const stdout = await executeExactLocalWork(job.spec.task, claim.resolvedWorkdir, {
|
|
128
152
|
heartbeat: () => heartbeatCueLineCallerJob(result.runId, job.jobId, proof),
|
|
129
153
|
});
|
|
130
154
|
await submitCueLineCallerJobResult(result.runId, job.jobId, { status: "succeeded", stdout }, { claim: proof });
|
|
@@ -138,22 +162,31 @@ if (result.status === "complete") {
|
|
|
138
162
|
}
|
|
139
163
|
```
|
|
140
164
|
|
|
165
|
+
`archiveControllerConversationOnComplete` 默认为 `false`,并在创建 run 时固定。启用后,CueLine 会先把 `complete` 写入持久记录,再在 Pro 空闲时只归档那一个精确绑定的会话。点击 fence 前能证明尚未点击的失败可以重试;fence 之后只要超时、重启、页面切换或缺少完成证据,就标为 `ambiguous` 且永不再点。`blocked` 与 `cancelled` 一律保留原会话。
|
|
166
|
+
|
|
141
167
|
`awaiting_controller` 只读观测且不重发;`awaiting_caller` 交接 `advise`;`awaiting_caller_work` 必须依次 claim、start、执行、heartbeat 并带 claim proof 提交。Pro 网页从不直接使用本地工具。
|
|
142
168
|
|
|
169
|
+
`listCueLineRuns()` 是只读且已脱敏的 run 清单,可用来找回持久化的 run ID;它不包含控制器文本、会话 URL、作业内容或 worker 输出。
|
|
170
|
+
|
|
171
|
+
`verifyCueLineRun(runId)` 是只读完整性检查,会核对创建 marker、event replay 与 authority fence、可选 snapshot、runtime lease 和 job status 证据;只返回稳定 finding,不返回持久 run 内容。
|
|
172
|
+
|
|
143
173
|
在 Codex 的 runtime 里,import `cueline api path` 打印出的那个绝对路径模块——那就是你安装的那份包构建出来的 API。
|
|
144
174
|
|
|
145
|
-
`startCueLineRun` 只创建持久 run 并返回 `ready`;`runCueLine` 创建并推进到持久 controller 观测暂停、caller 交接或终态。缺少 owner 的 `controller_response_pending` 若只有一个正常发送的回合且显示 `safeNextAction: observe`,表示同一个 Pro 回复仍待只读观测;稍后继续即可且不得重发。`safeNextAction: reconcile` 只用于模糊、人工发送或多个待对账回合。缺少 owner 的 `caller_jobs_pending` 是正常本地交接,并非 orphan,也不是仍在等 ChatGPT。
|
|
175
|
+
`startCueLineRun` 只创建持久 run 并返回 `ready`;`runCueLine` 创建并推进到持久 controller 观测暂停、caller 交接或终态。缺少 owner 的 `controller_response_pending` 若只有一个正常发送的回合且显示 `safeNextAction: observe`,表示同一个 Pro 回复仍待只读观测;稍后继续即可且不得重发。`safeNextAction: reconcile` 只用于模糊、人工发送或多个待对账回合。缺少 owner 的 `caller_jobs_pending` 是正常本地交接,并非 orphan,也不是仍在等 ChatGPT。CLI 的 `run status` 只输出交接所需元数据,不包含 task 正文、caller 身份、task hash、workdir 或 runtime owner ID;正式 claim 后,API 才把精确 task 与 workdir 交给获授权的 caller。
|
|
146
176
|
|
|
147
177
|
## CLI
|
|
148
178
|
|
|
149
|
-
CLI
|
|
179
|
+
CLI 不驱动浏览器。执行写入状态的命令前,先用 `cueline help` 核对完整参数。
|
|
150
180
|
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
181
|
+
| 分组 | 命令 | 效果 |
|
|
182
|
+
| --- | --- | --- |
|
|
183
|
+
| 查看 | `doctor` · `routing` · `jobs` · `runs` · `run status` · `run doctor` · `run watch` · `run timeline` · `run verify` · `run handoff` · `protocol lint` · `api path` · `config path` | 只读 |
|
|
184
|
+
| 安装 | `install` · `uninstall` | 只创建或移除包所拥有的 skill 链接 |
|
|
185
|
+
| 恢复 | `run reconcile` · `run takeover` · `run reconcile-runtime` · `run cancel` / `run stop` · `job cancel` | 追加审计证据或修改持久 run/job 状态 |
|
|
154
186
|
|
|
187
|
+
```console
|
|
155
188
|
$ cueline doctor
|
|
156
|
-
CueLine 0.
|
|
189
|
+
CueLine 0.2.0
|
|
157
190
|
status ok
|
|
158
191
|
node 22.14.0 ok
|
|
159
192
|
config /usr/local/lib/node_modules/cueline/config/routing.default.json valid
|
|
@@ -162,40 +195,41 @@ caller_ready yes
|
|
|
162
195
|
caller_lanes 1
|
|
163
196
|
process_available_lanes 1
|
|
164
197
|
|
|
165
|
-
$ cueline api path
|
|
166
|
-
/usr/local/lib/node_modules/cueline/dist/src/api.js
|
|
167
|
-
|
|
168
198
|
$ cueline routing
|
|
169
199
|
default codex-default available
|
|
170
200
|
|
|
171
|
-
$ cueline jobs
|
|
172
|
-
No jobs.
|
|
173
|
-
|
|
174
201
|
$ cueline run status run_... --json
|
|
175
202
|
{"status":"running","executor":"caller","phase":"caller_jobs_pending","runtime":{"ownership":"missing"},...}
|
|
176
203
|
|
|
177
|
-
$ cueline run
|
|
178
|
-
{"
|
|
204
|
+
$ cueline run doctor run_... --json
|
|
205
|
+
{"outcome":"action_required","phase":"caller_jobs_pending","nextAction":"execute_caller_jobs",...}
|
|
206
|
+
|
|
207
|
+
$ cueline run reconcile run_... --request-id msg_... --manual-send-confirmed --conversation-url https://chatgpt.com/c/...
|
|
208
|
+
run_...\tmsg_...\tconfirmed
|
|
179
209
|
|
|
180
210
|
$ cueline run cancel run_...
|
|
181
211
|
run_... requested affected_jobs=0
|
|
182
|
-
|
|
183
|
-
$ cueline config path
|
|
184
|
-
/usr/local/lib/node_modules/cueline/config/routing.default.json
|
|
185
|
-
|
|
186
|
-
$ cueline uninstall
|
|
187
|
-
CueLine skill removed: /Users/you/.codex/skills/cueline
|
|
188
212
|
```
|
|
189
213
|
|
|
190
214
|
当 Node 版本过旧、或没有任何已启用的 caller 通道时,`cueline doctor` 会以非零状态退出。`process_available_lanes` 可以为 0 而不影响 caller 模式;只有显式选择 process executor 前才需要用 `cueline routing` 检查 process 可用性。`cueline api path` 打印的就是 skill 会 import 的模块,所以使用打包安装时完全不需要 clone 源码。`cueline help` 会列出每个命令的精确语法,包括 `--json` 和人工 reconcile 的必需确认参数。
|
|
191
215
|
|
|
216
|
+
实验性的诊断命令各有专属文档:
|
|
217
|
+
|
|
218
|
+
| 命令 | 用途 | 文档 |
|
|
219
|
+
| --- | --- | --- |
|
|
220
|
+
| `run doctor` | 把 run 快照转成稳定 finding 代码、有界证据与一个安全下一步,不写入任何状态 | [run-doctor](docs/experiments/run-doctor.md) |
|
|
221
|
+
| `run watch` | 以持久事件序号为游标,做有界、不占 lease 的观察 | [run-watch](docs/experiments/run-watch.md) |
|
|
222
|
+
| `protocol lint` | 离线校验 Pro 信封,一次报告所有已知的契约修正 | [protocol-lint](docs/experiments/protocol-lint.md) |
|
|
223
|
+
| `run handoff` | 产出带精确身份与绝对路径的安全重启包 | [run-handoff](docs/experiments/run-handoff.md) |
|
|
224
|
+
| `run timeline` | 脱敏、游标分页的审计视图,不含原始事件内容 | [run-timeline](docs/experiments/run-timeline.md) |
|
|
225
|
+
|
|
192
226
|
只有 `run status` 明确显示 stale owner 时才能使用 `run takeover`。新鲜的 active heartbeat 会被拒绝;命令返回 `next: continue` 或 `next: reconcile_runtime`,请按该值行动,不要自行猜测。
|
|
193
227
|
|
|
194
228
|
## 配置
|
|
195
229
|
|
|
196
230
|
`CUELINE_CONFIG` 用于指定路由配置文件;`CUELINE_HOME` 用于迁移本地状态(默认 `~/.cueline`)。
|
|
197
231
|
|
|
198
|
-
Caller 模式不会启动路由进程。只有同时选择 `executor: "process"` 与 `allowProcessExecution: true` 时,内置 `default` 通道才以 `codex-default` 运行隔离的 `codex exec --ignore-user-config`;独立 `advise` 默认全局/每 lane 并发上限均为 2,包含 `work`
|
|
232
|
+
Caller 模式不会启动路由进程。只有同时选择 `executor: "process"` 与 `allowProcessExecution: true` 时,内置 `default` 通道才以 `codex-default` 运行隔离的 `codex exec --ignore-user-config`;独立 `advise` 默认全局/每 lane 并发上限均为 2,包含 `work` 的批次保持串行。要注册不同的 process worker,复制 [`config/routing.default.json`](config/routing.default.json)、加入你的候选项,再把 `CUELINE_CONFIG` 指过去。
|
|
199
233
|
|
|
200
234
|
状态位于 `CUELINE_HOME` 之下:
|
|
201
235
|
|
|
@@ -211,7 +245,11 @@ jobs/<job-id>.json 每个作业的执行证据
|
|
|
211
245
|
|
|
212
246
|
事件日志才是记录本身:控制器这一轮在发送之前先写入、作业在进程启动之前先注册,因此“意图”与“副作用”之间若被中断,会留下痕迹。损坏的快照会被忽略并从第 1 号事件重建,而不是被信任。
|
|
213
247
|
|
|
214
|
-
续跑只接回完全相同的会话 URL。ChatGPT 自动把长文本转换成附件时,CueLine 识别 `attachment_ready` 且最多点击一次;模糊点击记为 `possibly_sent
|
|
248
|
+
续跑只接回完全相同的会话 URL。ChatGPT 自动把长文本转换成附件时,CueLine 识别 `attachment_ready` 且最多点击一次;模糊点击记为 `possibly_sent`,绝不补点或重发。只有实际可见、启用且可操作的 Stop 按钮才表示 Pro 仍在回答;隐藏残留按钮不会挡住已完成的回复。人工发送附件后,使用 `cueline run reconcile RUN_ID --request-id REQUEST_ID --manual-send-confirmed` 写入正式确认;仍须通过完全一致的 conversation、Pro 证据与 protocol/run/round/request identity。
|
|
249
|
+
|
|
250
|
+
Pro 回答时绝不要打断它,也不要用 `Answer now`、`Respond now`、`Stop` 或任何等效的加速控制。Pro 没有本地工具,也不默认了解 repository 布局或本地路径。Caller 证据必须包含精确的代码/错误标识、相关代码摘录与绝对本地路径,并明确询问 Pro 是否还需要更多本地证据。
|
|
251
|
+
|
|
252
|
+
控制器证据优先使用成功且非空的 stdout,全局上限 12,000 字符;完整 stdout/stderr 保留在本地。若 Pro 接受 `inspect(job_ids)`,下一轮会先为指定 job 保留证据预算,再处理无关作业。
|
|
215
253
|
|
|
216
254
|
## 验证
|
|
217
255
|
|
|
@@ -228,13 +266,22 @@ npm pack --dry-run
|
|
|
228
266
|
|
|
229
267
|
## 0.1 的限制
|
|
230
268
|
|
|
231
|
-
|
|
269
|
+
仅支持文本控制命令。一次运行只对应一个会话。选成 `Pro` 是 CueLine 唯一会做的模型切换。支持 ChatGPT 自动将长文本转为附件,但不支持主动文件上传、图片、Deep Research、Projects 或 Apps。Caller `work` 必须显式 claim/start,长工作需要 heartbeat;process 执行必须双重授权。模糊发送和已启动工作都不会被自动重试。macOS 是主要桌面目标、Linux 是 CI 目标;Windows 未验证。adapter 依赖当前 ChatGPT 网页 UI,UI 改版会被显式暴露,绝不会变成捏造的答案。
|
|
232
270
|
|
|
233
271
|
完整矩阵见 [compatibility](docs/compatibility.md)。
|
|
234
272
|
|
|
235
273
|
## 文档
|
|
236
274
|
|
|
237
|
-
|
|
275
|
+
| 文档 | 内容 |
|
|
276
|
+
| --- | --- |
|
|
277
|
+
| [architecture](docs/architecture.md) | 各组件如何组合、信任边界在哪里 |
|
|
278
|
+
| [controller protocol](docs/controller-protocol.md) | `<CueLineControl>` 信封、五个动作与修复规则 |
|
|
279
|
+
| [runner contract](docs/runner-contract.md) | 已注册的 process worker 必须做与不得做的事 |
|
|
280
|
+
| [state and recovery](docs/state-and-recovery.md) | 持久状态布局、ownership 与每一条恢复路径 |
|
|
281
|
+
| [compatibility](docs/compatibility.md) | 支持的平台、runtime 与 UI 假设 |
|
|
282
|
+
| [provenance](docs/provenance.md) | 设计从哪里来、它不是什么 |
|
|
283
|
+
|
|
284
|
+
(以上均为英文)
|
|
238
285
|
|
|
239
286
|
## 开发
|
|
240
287
|
|