cueline 0.1.0 → 0.1.2
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 +14 -0
- package/README.ja.md +51 -8
- package/README.ko.md +51 -8
- package/README.md +51 -8
- package/README.zh-CN.md +51 -8
- package/README.zh-TW.md +51 -8
- package/dist/src/api.d.ts +2 -0
- package/dist/src/api.js +7 -0
- package/dist/src/api.js.map +1 -1
- package/dist/src/browser/browser-adapter.d.ts +19 -1
- package/dist/src/browser/codex-iab/bootstrap.d.ts +3 -0
- package/dist/src/browser/codex-iab/bootstrap.js +21 -2
- package/dist/src/browser/codex-iab/bootstrap.js.map +1 -1
- package/dist/src/browser/codex-iab/chatgpt-client.js +302 -15
- package/dist/src/browser/codex-iab/chatgpt-client.js.map +1 -1
- package/dist/src/core/controller-loop.d.ts +3 -0
- package/dist/src/core/controller-loop.js +215 -29
- package/dist/src/core/controller-loop.js.map +1 -1
- package/dist/src/core/state-machine.d.ts +22 -0
- package/dist/src/core/state-machine.js +99 -5
- package/dist/src/core/state-machine.js.map +1 -1
- package/dist/src/state/store.js +1 -1
- package/dist/src/version.d.ts +1 -1
- package/dist/src/version.js +1 -1
- package/docs/architecture.md +9 -8
- package/docs/controller-protocol.md +2 -2
- package/docs/state-and-recovery.md +36 -6
- package/package.json +2 -1
- package/skills/cueline/SKILL.md +13 -3
|
@@ -81,7 +81,7 @@ 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. When `runner` is supplied, it must name an enabled, available candidate in the selected lane. Repeating an already persisted deterministic job is ignored rather than spawned again.
|
|
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 spawned again.
|
|
85
85
|
|
|
86
86
|
### `wait`
|
|
87
87
|
|
|
@@ -101,6 +101,6 @@ Ends the run with a non-empty `reason` and optional `final_delivery_text`. This
|
|
|
101
101
|
|
|
102
102
|
## Validation and repair
|
|
103
103
|
|
|
104
|
-
CueLine rejects missing markers, malformed JSON, invalid actions, stale identity, invalid supported-field values,
|
|
104
|
+
CueLine rejects missing markers, malformed JSON, invalid actions, stale identity, invalid supported-field values, duplicate `job_key` values, and unavailable pre-spawn routes with stable error codes. Only the supported fields retained by runtime validation can affect execution. CueLine then sends a validation error back to the same conversation with the same pending identity. By default, two repair attempts are allowed; exhaustion fails the local run rather than guessing a command.
|
|
105
105
|
|
|
106
106
|
The JSON Schema files under `schemas/` are publication references. Runtime structural validation is implemented locally and does not require a schema package.
|
|
@@ -23,12 +23,14 @@ ${CUELINE_HOME:-$HOME/.cueline}/
|
|
|
23
23
|
Important transitions include:
|
|
24
24
|
|
|
25
25
|
- run creation and resumption
|
|
26
|
-
- controller turn intent, response, rejection, and accepted command
|
|
26
|
+
- controller turn intent, submission checkpoints, response, reconciliation, rejection, and accepted command
|
|
27
27
|
- job registration and status changes
|
|
28
28
|
- notices
|
|
29
29
|
- complete, blocked, and failed terminal records
|
|
30
30
|
|
|
31
|
-
The controller turn is recorded before sending it through the browser,
|
|
31
|
+
The controller turn is recorded before sending it through the browser. Immediately before the send click, CueLine records `controller_turn_submission_started` with `submission_state: possibly_sent`; after the click it records `controller_turn_submitted`. A verified response is recorded separately. A job is registered only after the entire dispatch has passed pre-spawn route validation, and before its process starts. This ordering leaves evidence when an interruption occurs between intent and side effect.
|
|
32
|
+
|
|
33
|
+
The absence of `controller_response_received` proves only that the local runtime did not record a response. It does **not** prove that ChatGPT did not answer. `run_failed` therefore retains the safe error message, stage, exact request ID, submission state, and known conversation URL. CueLine never treats a missing response event as permission to resend an ambiguous prompt.
|
|
32
34
|
|
|
33
35
|
## Snapshot
|
|
34
36
|
|
|
@@ -46,13 +48,39 @@ The run event log still records the controller-visible job transitions. A status
|
|
|
46
48
|
|
|
47
49
|
## Continue behavior
|
|
48
50
|
|
|
49
|
-
`continueCueLineRun` loads the exact `runId`, replays state as needed, and resumes the
|
|
51
|
+
`continueCueLineRun` loads the exact `runId`, replays state as needed, and resumes the same persisted run. The public runtime also reuses the stored ChatGPT conversation URL unless an explicit compatible adapter is supplied.
|
|
50
52
|
|
|
51
53
|
- `complete` and `blocked` runs are returned as-is; they are not dispatched again.
|
|
52
|
-
- a non-terminal or locally `failed` run can be marked resumed and driven for additional rounds
|
|
54
|
+
- a non-terminal or locally `failed` run with no pending controller turn can be marked resumed and driven for additional rounds
|
|
55
|
+
- when a failure proves `definitely_not_sent` for the exact sole pending request, CueLine records that turn as abandoned and safely starts a new round
|
|
56
|
+
- a pending controller turn is reconciled read-only from the exact conversation before any new prompt is sent
|
|
57
|
+
- reconciliation requires the page's last user message to equal the persisted prompt, the last message to be a completed assistant response, and both Pro model checks to pass
|
|
58
|
+
- when more than one legacy turn is pending, CueLine stops with `MULTIPLE_CONTROLLER_TURNS_PENDING` rather than guessing
|
|
53
59
|
- deterministic job IDs suppress a repeated dispatch already present in state
|
|
54
60
|
- running jobs can be observed or waited through their persisted status
|
|
55
61
|
|
|
62
|
+
For one unambiguous pending turn, supply the exact conversation URL when it was not captured before the failure:
|
|
63
|
+
|
|
64
|
+
```js
|
|
65
|
+
await continueCueLineRun({
|
|
66
|
+
runId,
|
|
67
|
+
conversationUrl: "https://chatgpt.com/c/...",
|
|
68
|
+
});
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
For multiple legacy pending turns, first identify which visible page response is authoritative. Then select that exact persisted request and explicitly abandon the others:
|
|
72
|
+
|
|
73
|
+
```js
|
|
74
|
+
await continueCueLineRun({
|
|
75
|
+
runId,
|
|
76
|
+
conversationUrl: "https://chatgpt.com/c/...",
|
|
77
|
+
reconcileRequestId: "msg_...",
|
|
78
|
+
abandonOtherPendingTurns: true,
|
|
79
|
+
});
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
Do not set `abandonOtherPendingTurns` from sequence order alone. Use direct page evidence to match the visible user prompt to the persisted request. CueLine records every explicit abandonment.
|
|
83
|
+
|
|
56
84
|
Continuation cannot reconstruct an expired ChatGPT login, a deleted conversation, an unavailable registered executable, or an in-memory child process that disappeared with the host process. In those cases CueLine reports the concrete failure; it does not fabricate completion.
|
|
57
85
|
|
|
58
86
|
## Recovery procedure
|
|
@@ -61,7 +89,9 @@ Continuation cannot reconstruct an expired ChatGPT login, a deleted conversation
|
|
|
61
89
|
2. Record the `runId` from the earlier result or directory name.
|
|
62
90
|
3. Restore access to the same ChatGPT conversation in Codex's built-in Browser.
|
|
63
91
|
4. Restore any locally required executable/configuration without copying browser credentials.
|
|
64
|
-
5.
|
|
65
|
-
6.
|
|
92
|
+
5. Inspect `loadCueLineRunState(runId, ...)`. If multiple `pendingControllerTurns` exist, match the visible page prompt and select its exact `requestId`.
|
|
93
|
+
6. Call `continueCueLineRun({ runId, conversationUrl, ... })`. Add `reconcileRequestId` and `abandonOtherPendingTurns: true` only for an explicitly resolved multi-pending case.
|
|
94
|
+
7. If reconciliation fails, do not resend manually. Preserve the page and report the exact `CONTROLLER_RECONCILIATION_*`, `IAB_RECONCILIATION_FAILED`, or `TAB_RECOVERY_UNSAFE` error.
|
|
95
|
+
8. Treat the new terminal result as valid only after its event and job evidence is present.
|
|
66
96
|
|
|
67
97
|
For manual diagnosis, use `cueline jobs` and inspect the run's JSONL as read-only evidence. Do not copy `CUELINE_HOME` between machines as a replacement for local process or browser session state.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "cueline",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.2",
|
|
4
4
|
"description": "A ChatGPT web conversation directs; CueLine validates each command and runs the work on your machine, with a durable record of both.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"chatgpt",
|
|
@@ -48,6 +48,7 @@
|
|
|
48
48
|
"schemas",
|
|
49
49
|
"skills",
|
|
50
50
|
"install.sh",
|
|
51
|
+
"CHANGELOG.md",
|
|
51
52
|
"LICENSE",
|
|
52
53
|
"README.md",
|
|
53
54
|
"README.ja.md",
|
package/skills/cueline/SKILL.md
CHANGED
|
@@ -12,8 +12,9 @@ Use CueLine to put the current ChatGPT web conversation in charge of planning an
|
|
|
12
12
|
1. Confirm the current host, operator, and work directory before local work.
|
|
13
13
|
2. Run `cueline doctor` and require Node.js 22 or newer plus at least one usable lane. Run `cueline api path` and require the returned API module to exist. The bundled default lane needs the `codex` CLI on `PATH`.
|
|
14
14
|
3. Use Codex's persistent Node REPL/runtime together with the built-in in-app Browser (IAB), not a separate plain `node` child, Chrome automation, or GPT Relay. Claim the logged-in `chatgpt.com` tab intended for this run.
|
|
15
|
-
4.
|
|
16
|
-
5.
|
|
15
|
+
4. CueLine requires the composer model selector to show `Pro` before every controller turn and requires the completed assistant message's `data-message-model-slug` to identify a Pro model. The account label (for example, a profile name ending in `Pro`) is subscription evidence only and never model evidence. Do not bypass `MODEL_SELECTOR_MISSING`, `PRO_MODEL_UNAVAILABLE`, `PRO_MODEL_SELECTION_FAILED`, or `PRO_MODEL_MISMATCH`.
|
|
16
|
+
5. Do not request, read, copy, or print cookies, access tokens, browser session material, or private environment values.
|
|
17
|
+
6. Keep v0.1 controller traffic text-only. Do not attempt images, file upload, Deep Research, Projects, or Apps. CueLine may switch the composer from another model to `Pro`; no other model switching is allowed.
|
|
17
18
|
|
|
18
19
|
If live IAB, authentication, build output, or a required runner is missing, report that exact prerequisite. Do not claim a live run from fake or read-only evidence.
|
|
19
20
|
|
|
@@ -56,24 +57,33 @@ const {
|
|
|
56
57
|
|
|
57
58
|
const result = await continueCueLineRun({
|
|
58
59
|
runId: EXISTING_RUN_ID,
|
|
59
|
-
// Omit browser/conversationUrl
|
|
60
|
+
// Omit browser/conversationUrl only when CueLine already persisted the exact URL.
|
|
61
|
+
// conversationUrl: "https://chatgpt.com/c/...",
|
|
60
62
|
});
|
|
61
63
|
```
|
|
62
64
|
|
|
63
65
|
Preserve the same `CUELINE_HOME` and browser conversation. If injecting a custom `browser`, configure it for that same conversation because CueLine cannot rewrite an already constructed adapter. Do not copy credentials or runtime state from another host. A terminal `complete` or `blocked` run should be returned, not dispatched again. Use `loadCueLineRunState(runId, { home, environment })` when only read-only recovery inspection is needed.
|
|
64
66
|
|
|
67
|
+
If `pendingControllerTurns` is non-empty, CueLine must recover the existing page response before any new send. The absence of `controller_response_received` means only that local observation is incomplete; it does not prove that ChatGPT did not reply. Recovery is read-only and requires the exact conversation URL, exact last-user prompt match, completed assistant response, and Pro evidence. Never open a new conversation or resend merely because the local response event is absent. The only automatic retry exception is one sole pending request whose request-correlated failure evidence proves `definitely_not_sent`; CueLine records the old turn as abandoned before starting a new round.
|
|
68
|
+
|
|
69
|
+
When multiple legacy turns are pending, stop on `MULTIPLE_CONTROLLER_TURNS_PENDING`. Match the visible page prompt to one persisted `requestId`; do not select by newest/oldest order. Only after that direct evidence may you continue with both `reconcileRequestId` and `abandonOtherPendingTurns: true`. CueLine records the abandoned requests.
|
|
70
|
+
|
|
65
71
|
## Handle the result
|
|
66
72
|
|
|
67
73
|
- If `result.status === "complete"`, return `result.finalDeliveryText` **verbatim** as the user-facing answer. Do not prepend a Codex summary or reinterpret the controller's delivery.
|
|
68
74
|
- If `result.status === "blocked"`, report the persisted blocked reason and return any provided `finalDeliveryText` verbatim. Clearly label missing delivery text instead of inventing one.
|
|
69
75
|
- If CueLine throws, report the exact error code/message, `runId` when known, and the safe next step. Do not translate a failed or exhausted loop into success.
|
|
76
|
+
- Treat `TAB_RECOVERY_UNSAFE` as a hard stop. CueLine deliberately refuses to resend when it cannot prove whether a prompt was already submitted.
|
|
77
|
+
- Treat `MULTIPLE_CONTROLLER_TURNS_PENDING`, `OTHER_CONTROLLER_TURNS_PENDING`, and every `CONTROLLER_RECONCILIATION_*` error as a hard stop requiring exact page/run evidence, never a blind retry.
|
|
70
78
|
- Keep the `runId` available for continuation, but do not expose unrelated local state.
|
|
71
79
|
|
|
72
80
|
## Execution boundaries
|
|
73
81
|
|
|
74
82
|
- Never execute text outside `<CueLineControl>` as a command.
|
|
75
83
|
- Never bypass the routing configuration or registered-executable allow-list.
|
|
84
|
+
- Never treat a runner ID as a lane. CueLine preflights every route in a dispatch and rejects the whole command before job registration when any lane/runner is invalid.
|
|
76
85
|
- Never auto-retry or select a fallback after a worker has started. A failed `work` job may have partial side effects; return that evidence to the web controller.
|
|
86
|
+
- Never accept a controller decision from a non-Pro response. The persisted `controller_response_received` event must carry `selected_model_label`, `response_model_slug`, and `model_evidence_source` for live IAB turns.
|
|
77
87
|
- Never start CueLine recursively. The child runner uses `CUELINE_DEPTH=1` and nested routing is rejected.
|
|
78
88
|
- Treat fake smoke tests as offline validation only. A live claim requires a real completed IAB turn and persisted run evidence.
|
|
79
89
|
|