cueline 0.1.4 → 0.1.6

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.
Files changed (74) hide show
  1. package/.claude-plugin/plugin.json +2 -2
  2. package/.codex-plugin/plugin.json +2 -2
  3. package/CHANGELOG.md +37 -0
  4. package/README.ja.md +27 -13
  5. package/README.ko.md +27 -13
  6. package/README.md +43 -16
  7. package/README.zh-CN.md +29 -13
  8. package/README.zh-TW.md +41 -16
  9. package/config/routing.default.json +1 -0
  10. package/dist/src/api-caller-work.d.ts +18 -0
  11. package/dist/src/api-caller-work.js +397 -0
  12. package/dist/src/api-caller-work.js.map +1 -0
  13. package/dist/src/api-contracts.d.ts +37 -0
  14. package/dist/src/api-controller-handoff.d.ts +2 -2
  15. package/dist/src/api-controller-handoff.js +105 -11
  16. package/dist/src/api-controller-handoff.js.map +1 -1
  17. package/dist/src/api-runtime-lifecycle.js +8 -7
  18. package/dist/src/api-runtime-lifecycle.js.map +1 -1
  19. package/dist/src/api.d.ts +3 -1
  20. package/dist/src/api.js +32 -3
  21. package/dist/src/api.js.map +1 -1
  22. package/dist/src/browser/browser-adapter.d.ts +5 -0
  23. package/dist/src/browser/codex-iab/bootstrap.d.ts +1 -0
  24. package/dist/src/browser/codex-iab/bootstrap.js +43 -2
  25. package/dist/src/browser/codex-iab/bootstrap.js.map +1 -1
  26. package/dist/src/browser/codex-iab/chatgpt-client.js +7 -49
  27. package/dist/src/browser/codex-iab/chatgpt-client.js.map +1 -1
  28. package/dist/src/browser/codex-iab/submission-url.js +5 -1
  29. package/dist/src/browser/codex-iab/submission-url.js.map +1 -1
  30. package/dist/src/browser/codex-iab/tab-discovery.d.ts +3 -0
  31. package/dist/src/browser/codex-iab/tab-discovery.js +61 -0
  32. package/dist/src/browser/codex-iab/tab-discovery.js.map +1 -0
  33. package/dist/src/cli/main.js +27 -4
  34. package/dist/src/cli/main.js.map +1 -1
  35. package/dist/src/core/controller-command-execution.js +26 -2
  36. package/dist/src/core/controller-command-execution.js.map +1 -1
  37. package/dist/src/core/controller-loop.js +66 -23
  38. package/dist/src/core/controller-loop.js.map +1 -1
  39. package/dist/src/core/controller-turn.js +11 -0
  40. package/dist/src/core/controller-turn.js.map +1 -1
  41. package/dist/src/core/controller-types.d.ts +3 -1
  42. package/dist/src/core/ids.d.ts +1 -0
  43. package/dist/src/core/ids.js +3 -0
  44. package/dist/src/core/ids.js.map +1 -1
  45. package/dist/src/core/run-status.d.ts +31 -4
  46. package/dist/src/core/run-status.js +142 -4
  47. package/dist/src/core/run-status.js.map +1 -1
  48. package/dist/src/core/state-machine.d.ts +31 -1
  49. package/dist/src/core/state-machine.js +214 -2
  50. package/dist/src/core/state-machine.js.map +1 -1
  51. package/dist/src/jobs/status.d.ts +5 -0
  52. package/dist/src/jobs/status.js.map +1 -1
  53. package/dist/src/jobs/supervisor.js +32 -6
  54. package/dist/src/jobs/supervisor.js.map +1 -1
  55. package/dist/src/router/materialize.js +1 -0
  56. package/dist/src/router/materialize.js.map +1 -1
  57. package/dist/src/runners/process-runner.js +54 -0
  58. package/dist/src/runners/process-runner.js.map +1 -1
  59. package/dist/src/runners/runner-adapter.d.ts +9 -0
  60. package/dist/src/runners/runner-adapter.js.map +1 -1
  61. package/dist/src/version.d.ts +1 -1
  62. package/dist/src/version.js +1 -1
  63. package/docs/architecture.md +8 -7
  64. package/docs/assets/cueline-loop-en.svg +1 -1
  65. package/docs/assets/cueline-loop-ja.svg +1 -1
  66. package/docs/assets/cueline-loop-ko.svg +1 -1
  67. package/docs/assets/cueline-loop-zh-CN.svg +1 -1
  68. package/docs/assets/cueline-loop-zh-TW.svg +1 -1
  69. package/docs/compatibility.md +8 -8
  70. package/docs/controller-protocol.md +4 -4
  71. package/docs/runner-contract.md +20 -7
  72. package/docs/state-and-recovery.md +19 -12
  73. package/package.json +2 -2
  74. package/skills/cueline/SKILL.md +51 -10
package/README.zh-CN.md CHANGED
@@ -13,7 +13,7 @@
13
13
 
14
14
  **CueLine 把方向盘交给一个已经打开的 ChatGPT 网页会话:由它规划运行、发出每一步文本指令;CueLine 负责校验,当前 Codex 才在本机执行获准的工作。**
15
15
 
16
- 那个网页碰不到你的机器,也没有本地工具。CueLine 默认把 `advise` 作业持久化并交回当前 Codex 执行;只有显式选择 `process` executor,才会启动已注册的本地 worker。
16
+ 那个网页碰不到你的机器,也没有本地工具。CueLine 默认把 caller 作业持久化:`advise` 是协调式交接;`work` 必须先获得持久 claim 并正式 start。只有双重显式授权 `process` executor,才会启动已注册的本地 worker。
17
17
 
18
18
  CueLine 是独立实现,**没有任何运行时 npm 依赖**,也不是 Omnilane 或 GPT Relay 的包装层。
19
19
 
@@ -25,9 +25,9 @@ CueLine 是独立实现,**没有任何运行时 npm 依赖**,也不是 Omnil
25
25
 
26
26
  非默认的 `maxRounds` 会在创建 run 时固定,并跨所有无 owner 的暂停累计控制器总轮次。后续继续通常省略它并复用持久值;传入不同数值会被拒绝,不会暗中重置或放宽预算。
27
27
 
28
- `startCueLineRun` 与 `runCueLine` 都默认使用 `caller`。使用内置浏览器时,CueLine 只发送一次、保存精确会话 URL,然后返回 `awaiting_controller` 并释放 runtime lease,不会让单次工具调用一直等待 Pro。之后的 `continueCueLineRun` 只做一次只读观测;若尚未完成,会再次返回 `awaiting_controller`,绝不重发。`dispatch` 才返回 `awaiting_caller`;当前 Codex 执行各个 `advise` 任务、调用 `submitCueLineCallerJobResult`,再继续同一 run。Pro 控制器只下文本命令,不能使用本地工具。Caller advice 没有 execution claim,请协调由单一 session 执行;两个 session 可能都做同一项检查,但只有第一份提交的终态证据生效。Caller 模式明确拒绝 `work`。
28
+ `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 只提出和审查文本指令,不会使用本地工具。
29
29
 
30
- 控制器决定*应该发生什么*;本地这一侧决定*是否允许发生、以何种方式发生*:通道(lane)必须启用、候选必须在任何进程启动**之前**确认可用、`argv[0]` 必须早已由你的路由配置注册。没有任何内容会经过 shell。worker 一旦启动,就不会悄悄退回到第二个候选——失败以证据的形式返回,而不是自动重试。
30
+ Process 模式必须同时指定 `executor: "process"` 与 `allowProcessExecution: true`,非终态继续也要再次传入第二道授权。内置 route 还使用 `--ignore-user-config`,不会让隐藏 worker 加载用户配置的 MCP server 或其命令参数。通道必须启用、候选必须在任何进程启动**之前**确认可用、`argv[0]` 必须已注册。没有内容经过 shell,也不会在启动后自动换候选。
31
31
 
32
32
  控制器协议有意区分路由层级:`lane` 填的是通道名称 `default`;`codex-default` 是该通道内的候选执行器,不是通道。CueLine 会在注册任何作业之前先验证整份 `dispatch`;只要包含无效通道或执行器,整份派工就会被退回修复,不会先执行其中一部分。
33
33
 
@@ -48,15 +48,15 @@ ChatGPT Pro 订阅套餐与“选定的 Pro 模型”是两回事。账号或个
48
48
  从 npm registry 安装:
49
49
 
50
50
  ```bash
51
- npm install -g cueline@0.1.4
51
+ npm install -g cueline@0.1.6
52
52
  cueline install
53
53
  cueline doctor
54
54
  ```
55
55
 
56
- 作为后备,也可以安装 [v0.1.4 release](https://github.com/Seraphim0916/cueline/releases/tag/v0.1.4) 上的打包 tarball,该 release 同时附带它的 `.sha256` 校验值:
56
+ 作为后备,也可以安装 [v0.1.6 release](https://github.com/Seraphim0916/cueline/releases/tag/v0.1.6) 上的打包 tarball,该 release 同时附带它的 `.sha256` 校验值:
57
57
 
58
58
  ```bash
59
- npm install -g https://github.com/Seraphim0916/cueline/releases/download/v0.1.4/cueline-0.1.4.tgz
59
+ npm install -g https://github.com/Seraphim0916/cueline/releases/download/v0.1.6/cueline-0.1.6.tgz
60
60
  cueline install
61
61
  cueline doctor
62
62
  ```
@@ -89,23 +89,26 @@ cueline doctor
89
89
 
90
90
  ```js
91
91
  import {
92
+ claimCueLineCallerJob,
92
93
  continueCueLineRun,
93
94
  createCodexIabAdapter,
95
+ heartbeatCueLineCallerJob,
94
96
  runCueLine,
97
+ startCueLineCallerJob,
95
98
  submitCueLineCallerJobResult,
96
99
  } from "cueline";
97
100
 
98
101
  let result = await runCueLine({
99
102
  request: "Inspect the repository, delegate an implementation plan, and report the evidence.",
100
- browser: createCodexIabAdapter(),
103
+ browser: createCodexIabAdapter({ browser: globalThis.browser }),
101
104
  // 可选:conversationUrl、routingConfig / routingConfigPath、home、cwd、
102
105
  // runTimeoutMs、signal,以及作业/默认期限。
103
106
  }); // 默认 executor: "caller"
104
107
 
105
- while (result.status === "awaiting_controller" || result.status === "awaiting_caller") {
108
+ while (["awaiting_controller", "awaiting_caller", "awaiting_caller_work"].includes(result.status)) {
106
109
  if (result.status === "awaiting_controller") {
107
110
  await waitBeforeNextObservation(); // 有界退避;绝不重发
108
- } else {
111
+ } else if (result.status === "awaiting_caller") {
109
112
  for (const job of result.pendingJobs ?? []) {
110
113
  const stdout = await executeExactLocalAdvice(job.spec.task);
111
114
  await submitCueLineCallerJobResult(result.runId, job.jobId, {
@@ -113,6 +116,19 @@ while (result.status === "awaiting_controller" || result.status === "awaiting_ca
113
116
  stdout,
114
117
  });
115
118
  }
119
+ } else {
120
+ for (const job of result.pendingJobs ?? []) {
121
+ if (job.spec.mode !== "work") continue;
122
+ const claim = await claimCueLineCallerJob(result.runId, job.jobId, {
123
+ callerId: "stable-codex-task-identity",
124
+ });
125
+ const proof = { claimId: claim.claimId, callerId: claim.callerId, fencingToken: claim.fencingToken };
126
+ await startCueLineCallerJob(result.runId, job.jobId, proof);
127
+ const stdout = await executeExactLocalWork(job.spec.task, claim.workdir, {
128
+ heartbeat: () => heartbeatCueLineCallerJob(result.runId, job.jobId, proof),
129
+ });
130
+ await submitCueLineCallerJobResult(result.runId, job.jobId, { status: "succeeded", stdout }, { claim: proof });
131
+ }
116
132
  }
117
133
  result = await continueCueLineRun({ runId: result.runId });
118
134
  }
@@ -122,7 +138,7 @@ if (result.status === "complete") {
122
138
  }
123
139
  ```
124
140
 
125
- 若返回 `awaiting_controller`,表示同一个精确 request 已发送、但 Pro 回复尚未被观测;稍后继续只会执行只读观测,不会重发。若返回 `awaiting_caller`,由当前 Codex 执行 `result.pendingJobs` 中的每个 `advise`,用 `submitCueLineCallerJobResult` 提交真实结果,再调用 `continueCueLineRun`。这不是 Pro 网页直接使用本地工具。
141
+ `awaiting_controller` 只读观测且不重发;`awaiting_caller` 交接 `advise`;`awaiting_caller_work` 必须依次 claim、start、执行、heartbeat 并带 claim proof 提交。Pro 网页从不直接使用本地工具。
126
142
 
127
143
  在 Codex 的 runtime 里,import `cueline api path` 打印出的那个绝对路径模块——那就是你安装的那份包构建出来的 API。
128
144
 
@@ -137,7 +153,7 @@ $ cueline install
137
153
  CueLine skill installed: /Users/you/.codex/skills/cueline
138
154
 
139
155
  $ cueline doctor
140
- CueLine 0.1.4
156
+ CueLine 0.1.6
141
157
  status ok
142
158
  node 22.14.0 ok
143
159
  config /usr/local/lib/node_modules/cueline/config/routing.default.json valid
@@ -179,7 +195,7 @@ CueLine skill removed: /Users/you/.codex/skills/cueline
179
195
 
180
196
  `CUELINE_CONFIG` 用于指定路由配置文件;`CUELINE_HOME` 用于迁移本地状态(默认 `~/.cueline`)。
181
197
 
182
- Caller 模式不会启动路由进程。只有显式选择 `process` executor 时,内置 `default` 通道才以 `codex-default` 运行 `codex exec`;独立 `advise` 默认全局/每 lane 并发上限均为 2,包含 `work` 的批次保持串行。
198
+ Caller 模式不会启动路由进程。只有同时选择 `executor: "process"` `allowProcessExecution: true` 时,内置 `default` 通道才以 `codex-default` 运行隔离的 `codex exec --ignore-user-config`;独立 `advise` 默认全局/每 lane 并发上限均为 2,包含 `work` 的批次保持串行。
183
199
 
184
200
  状态位于 `CUELINE_HOME` 之下:
185
201
 
@@ -212,7 +228,7 @@ npm pack --dry-run
212
228
 
213
229
  ## 0.1 的限制
214
230
 
215
- 仅支持文本控制命令。一次运行只对应一个会话。支持 ChatGPT 自动将长文本转为附件,但不支持主动文件上传、图片、Deep Research、Projects 或 Apps。Caller 模式只允许 `advise`;`work` 必须显式选择 process executor。模糊发送和已启动工作都不会被自动重试。
231
+ 仅支持文本控制命令。一次运行只对应一个会话。支持 ChatGPT 自动将长文本转为附件,但不支持主动文件上传、图片、Deep Research、Projects 或 Apps。Caller `work` 必须显式 claim/start;process 执行必须双重授权。模糊发送和已启动工作都不会被自动重试。
216
232
 
217
233
  完整矩阵见 [compatibility](docs/compatibility.md)。
218
234
 
package/README.zh-TW.md CHANGED
@@ -13,7 +13,7 @@
13
13
 
14
14
  **CueLine 把方向盤交給一個已經開著的 ChatGPT 網頁對話:由它規劃整趟執行、喊出每一步;CueLine 檢查每一道文字指令,現在這個 Codex 才在本機執行獲准的工作。**
15
15
 
16
- 那個網頁碰不到你的機器,也沒有本機工具。它每一輪只吐出文字控制指令。CueLine 預設把 `advise` 工作保存成待辦,交給現在這個 Codex 執行並提交結果;只有明確指定 `process` executor 時,才會啟動已註冊的本機工作行程。
16
+ 那個網頁碰不到你的機器,也沒有本機工具。它每一輪只吐出文字控制指令。CueLine 預設把 caller 工作保存成待辦:`advise` 是協調式交接;`work` 則必須先建立持久 claim 並正式 start,才能開始修改。只有雙重明確授權 `process` executor 時,才會啟動已註冊的本機工作行程。
17
17
 
18
18
  CueLine 是獨立實作,**沒有任何 runtime npm 相依套件**,也不是 Omnilane 或 GPT Relay 的包裝層。
19
19
 
@@ -25,9 +25,9 @@ CueLine 是獨立實作,**沒有任何 runtime npm 相依套件**,也不是
25
25
 
26
26
  非預設的 `maxRounds` 會在建立 run 時固定,並跨所有無 owner 的暫停累計主控總輪數。之後續跑通常省略它、沿用持久值;若傳入不同數字,CueLine 會拒絕,不會偷偷重設或放寬預算。
27
27
 
28
- `startCueLineRun` 與 `runCueLine` 都預設使用 `caller` executor。使用內建瀏覽器時,CueLine 只送一次、保存精確對話 URL,然後回傳 `awaiting_controller` 並釋放 runtime lease,不會讓單一工具呼叫卡著等 Pro 思考。之後的 `continueCueLineRun` 只做一次唯讀觀測;若仍未完成,就再次回傳 `awaiting_controller`,絕不重送。`dispatch` 才會回傳 `awaiting_caller` 與持久化的 `advise` 工作;目前的 Codex 執行各項工作、呼叫 `submitCueLineCallerJobResult`,再沿用同一個 run 續跑。Pro 主控只負責下文字命令,沒有親自查 repo。Caller advise 沒有 execution claim,請協調由單一 session 執行;兩個 session 可能都做同一項查驗,但只有第一份送出的終態證據生效。Caller 模式會明確拒絕 `work`。
28
+ `startCueLineRun` 與 `runCueLine` 都預設使用 `caller` executor。使用內建瀏覽器時,CueLine 只送一次、保存精確對話 URL,然後回傳 `awaiting_controller` 並釋放 runtime lease,不會讓單一工具呼叫卡著等 Pro 思考。之後的 `continueCueLineRun` 只做一次唯讀觀測;若仍未完成,就再次回傳 `awaiting_controller`,絕不重送。`advise` 派工回傳 `awaiting_caller`,沒有副作用 claim,需協調單一 session。`work` 派工回傳 `awaiting_caller_work`,在目前 Codex 呼叫 `claimCueLineCallerJob` `startCueLineCallerJob` 前,絕對尚未開始本機修改。claim 綁定 run、job、task hash、絕對 workdir、caller identity fencing token;已開始的工作不會自動重試,claim 逾期則成為 `ambiguous`。Pro 只提出與審查文字指令,沒有親自使用本機工具。
29
29
 
30
- 若明確選擇 `executor: "process"`,通道(lane)必須啟用、候選項必須在任何程序啟動**之前**就確認可用、`argv[0]` 必須早已由你的路由設定註冊過。沒有任何東西會經過 shell。唯讀工作預設全域與每 lane 最多同時 2 個;只要批次包含 `work` 就維持串行。
30
+ Process 模式必須同時指定 `executor: "process"` 與 `allowProcessExecution: true`,非終態續跑也要再次傳入第二道授權。內建 route 另加 `--ignore-user-config`,不讓隱藏 worker 載入使用者設定的 MCP server 或其命令參數。通道(lane)必須啟用、候選項必須在任何程序啟動**之前**就確認可用、`argv[0]` 必須早已由路由設定註冊。沒有任何東西會經過 shell。唯讀工作預設全域與每 lane 最多同時 2 個;只要批次包含 `work` 就維持串行。狀態會顯示解析後 runner、PID、phase、最後進度時間,以及安全辨識到的 model/provider。
31
31
 
32
32
  主控協定刻意區分路由層級:`lane` 填的是通道名稱 `default`;`codex-default` 是該通道內的候選執行器,不是通道。CueLine 會在註冊任何工作前先驗證整份 `dispatch`;只要包含無效通道或執行器,整份派工就會被退回修正,不會先執行其中一部分。
33
33
 
@@ -48,15 +48,15 @@ ChatGPT Pro 訂閱方案與「選定的 Pro 模型」是兩回事。帳號或個
48
48
  從 npm registry 安裝:
49
49
 
50
50
  ```bash
51
- npm install -g cueline@0.1.4
51
+ npm install -g cueline@0.1.6
52
52
  cueline install
53
53
  cueline doctor
54
54
  ```
55
55
 
56
- 作為備援,也可以安裝 [v0.1.4 release](https://github.com/Seraphim0916/cueline/releases/tag/v0.1.4) 上的打包 tarball,該 release 同時附上它的 `.sha256` 校驗碼:
56
+ 作為備援,也可以安裝 [v0.1.6 release](https://github.com/Seraphim0916/cueline/releases/tag/v0.1.6) 上的打包 tarball,該 release 同時附上它的 `.sha256` 校驗碼:
57
57
 
58
58
  ```bash
59
- npm install -g https://github.com/Seraphim0916/cueline/releases/download/v0.1.4/cueline-0.1.4.tgz
59
+ npm install -g https://github.com/Seraphim0916/cueline/releases/download/v0.1.6/cueline-0.1.6.tgz
60
60
  cueline install
61
61
  cueline doctor
62
62
  ```
@@ -89,23 +89,26 @@ cueline doctor
89
89
 
90
90
  ```js
91
91
  import {
92
+ claimCueLineCallerJob,
92
93
  continueCueLineRun,
93
94
  createCodexIabAdapter,
95
+ heartbeatCueLineCallerJob,
94
96
  runCueLine,
97
+ startCueLineCallerJob,
95
98
  submitCueLineCallerJobResult,
96
99
  } from "cueline";
97
100
 
98
101
  let result = await runCueLine({
99
102
  request: "Inspect the repository, delegate an implementation plan, and report the evidence.",
100
- browser: createCodexIabAdapter(),
103
+ browser: createCodexIabAdapter({ browser: globalThis.browser }),
101
104
  // 選填:conversationUrl、routingConfig / routingConfigPath、home、cwd、
102
105
  // runTimeoutMs、signal,以及各工作/預設期限。
103
106
  }); // 預設 executor: "caller"
104
107
 
105
- while (result.status === "awaiting_controller" || result.status === "awaiting_caller") {
108
+ while (["awaiting_controller", "awaiting_caller", "awaiting_caller_work"].includes(result.status)) {
106
109
  if (result.status === "awaiting_controller") {
107
110
  await waitBeforeNextObservation(); // 有界退避;絕不重送
108
- } else {
111
+ } else if (result.status === "awaiting_caller") {
109
112
  for (const job of result.pendingJobs ?? []) {
110
113
  const stdout = await executeExactLocalAdvice(job.spec.task);
111
114
  await submitCueLineCallerJobResult(result.runId, job.jobId, {
@@ -113,6 +116,28 @@ while (result.status === "awaiting_controller" || result.status === "awaiting_ca
113
116
  stdout,
114
117
  });
115
118
  }
119
+ } else {
120
+ for (const job of result.pendingJobs ?? []) {
121
+ if (job.spec.mode !== "work") continue;
122
+ const claim = await claimCueLineCallerJob(result.runId, job.jobId, {
123
+ callerId: "stable-codex-task-identity",
124
+ });
125
+ const proof = {
126
+ claimId: claim.claimId,
127
+ callerId: claim.callerId,
128
+ fencingToken: claim.fencingToken,
129
+ };
130
+ await startCueLineCallerJob(result.runId, job.jobId, proof);
131
+ const stdout = await executeExactLocalWork(job.spec.task, claim.workdir, {
132
+ heartbeat: () => heartbeatCueLineCallerJob(result.runId, job.jobId, proof),
133
+ });
134
+ await submitCueLineCallerJobResult(
135
+ result.runId,
136
+ job.jobId,
137
+ { status: "succeeded", stdout },
138
+ { claim: proof },
139
+ );
140
+ }
116
141
  }
117
142
  result = await continueCueLineRun({ runId: result.runId });
118
143
  }
@@ -122,11 +147,11 @@ if (result.status === "complete") {
122
147
  }
123
148
  ```
124
149
 
125
- 若回傳 `awaiting_controller`,代表同一個精確 request 已送出、但 Pro 回覆尚未被觀測;稍後續跑只會唯讀觀測,不會重送。若回傳 `awaiting_caller`,請由目前的 Codex 執行 `result.pendingJobs` 內每一項 `advise`,用 `submitCueLineCallerJobResult` 提交真實結果,再呼叫 `continueCueLineRun`。這不是 Pro 網頁直接使用本機工具。
150
+ 若回傳 `awaiting_controller`,代表同一個精確 request 已送出、但 Pro 回覆尚未被觀測;稍後續跑只會唯讀觀測,不會重送。`awaiting_caller` 交接 `advise`;`awaiting_caller_work` 則必須依序 claim、start、執行、heartbeat 與帶 claim proof 提交結果。Pro 網頁從未直接使用本機工具。
126
151
 
127
152
  在 Codex 的 runtime 裡,import `cueline api path` 印出的那個絕對路徑模組——那就是你安裝的那份套件建置出來的 API。
128
153
 
129
- `startCueLineRun` 只建立持久 run 並回傳 `ready`;`runCueLine` 會建立並推進到持久 controller 觀測暫停、caller 交接或終態。`continueCueLineRun({ runId })` 沿用同一個對話。續跑前先執行 `cueline run status <run-id> --json`;缺少 owner `controller_response_pending` 若只有一個正常送出的回合且顯示 `safeNextAction: observe`,代表同一個 Pro 回覆尚待唯讀觀測,稍後續跑即可且不得重送。`safeNextAction: reconcile` 只保留給模糊、人工送出或多個待對帳回合。缺少 owner `caller_jobs_pending` 是正常本機交接,不是 orphan,也不是還在等 ChatGPT。
154
+ `startCueLineRun` 只建立持久 run 並回傳 `ready`;`runCueLine` 會建立並推進到持久 controller 觀測暫停、caller 交接或終態。續跑前先執行 `cueline run status <run-id> --json`。單一正常送出、非人工、具精確 URL、無 job/pending command/取消的 stale caller observer 可被 fencing 後唯讀恢復;其他 stale 狀態仍須正式接管。`caller_work_pending`、`caller_work_claimed`、`caller_work_running` 分別只允許 `claim_caller_work`、`start_caller_work`、`continue_caller_work`,主控的 `dispatch` 本身不代表本機工作已開始。
130
155
 
131
156
  ## CLI
132
157
 
@@ -137,7 +162,7 @@ $ cueline install
137
162
  CueLine skill installed: /Users/you/.codex/skills/cueline
138
163
 
139
164
  $ cueline doctor
140
- CueLine 0.1.4
165
+ CueLine 0.1.6
141
166
  status ok
142
167
  node 22.14.0 ok
143
168
  config /usr/local/lib/node_modules/cueline/config/routing.default.json valid
@@ -179,7 +204,7 @@ Node 版本太舊、或沒有任何已啟用的 caller 通道時,`cueline doct
179
204
 
180
205
  `CUELINE_CONFIG` 用來指定路由設定檔;`CUELINE_HOME` 用來搬動本機狀態(預設 `~/.cueline`)。
181
206
 
182
- Caller 模式不會啟動路由行程。只有明確選擇 `process` executor 時,內建的 `default` 通道才會以 `codex-default` 執行 `codex exec`;`advise` 用 `read-only`、`work` 用 `workspace-write`。
207
+ Caller 模式不會啟動路由行程。只有同時選擇 `executor: "process"` `allowProcessExecution: true` 時,內建的 `default` 通道才會以 `codex-default` 執行隔離的 `codex exec --ignore-user-config`;`advise` 用 `read-only`、`work` 用 `workspace-write`。
183
208
 
184
209
  狀態放在 `CUELINE_HOME` 底下:
185
210
 
@@ -195,9 +220,9 @@ jobs/<job-id>.json 每個工作的執行證據
195
220
 
196
221
  事件日誌才是紀錄本身:主控端的這一輪在送出之前就先寫下、工作在行程啟動之前就先註冊,所以「意圖」與「副作用」之間若被中斷,會留下痕跡。壞掉的快照會被忽略、從第 1 號事件重建,而不是硬信它。
197
222
 
198
- 續跑只會接回完全相同的對話網址。ChatGPT 把長文字自動轉成附件時,CueLine 會辨識 `attachment_ready`,且最多只點一次;模糊點擊一律記為 `possibly_sent`,絕不補點或重送。若操作者手動送出附件,用 `cueline run reconcile RUN_ID --request-id REQUEST_ID --manual-send-confirmed` 寫入正式確認;之後仍須通過完全相同的 conversation、Pro 證據與 protocol/run/round/request identity 才能唯讀接回。
223
+ 續跑只會接回完全相同的對話網址。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 才能唯讀接回。
199
224
 
200
- 送給主控的工作證據優先採用成功且非空的 stdout,全體共用 12,000 字元上限;完整 stdout/stderr 仍保留在本機 job status
225
+ 送給主控的工作證據優先採用成功且非空的 stdout,全體共用 12,000 字元上限;完整 stdout/stderr 仍保留在本機 job status。若 Pro 接受 `inspect(job_ids)`,下一輪會先替指定 job 保留證據預算,再處理無關工作。
201
226
 
202
227
  ## 驗證
203
228
 
@@ -214,7 +239,7 @@ npm pack --dry-run
214
239
 
215
240
  ## 0.1 的限制
216
241
 
217
- 只支援文字控制命令。一次執行只對應一個對話。選成 `Pro` 是 CueLine 唯一會做的模型切換。支援 ChatGPT 自動把長文字轉成附件,但不支援主動上傳檔案、圖片、Deep Research、Projects 或 Apps。Caller 模式只允許 `advise`;`work` 必須明確選用 process executor。任何模糊送出或已啟動工作都不會被自動重試。
242
+ 只支援文字控制命令。一次執行只對應一個對話。選成 `Pro` 是 CueLine 唯一會做的模型切換。支援 ChatGPT 自動把長文字轉成附件,但不支援主動上傳檔案、圖片、Deep Research、Projects 或 Apps。Caller `work` 必須經過明確 claim/start,長工作需 heartbeat;process 執行則要雙重明確授權。任何模糊送出或已啟動工作都不會被自動重試。
218
243
 
219
244
  完整矩陣見 [compatibility](docs/compatibility.md)。
220
245
 
@@ -10,6 +10,7 @@
10
10
  "argv": [
11
11
  "codex",
12
12
  "exec",
13
+ "--ignore-user-config",
13
14
  "--skip-git-repo-check",
14
15
  "--ephemeral",
15
16
  "--color",
@@ -0,0 +1,18 @@
1
+ import type { CueLineCallerWorkClaimOptions, CueLineCallerWorkClaimProof, CueLineCallerWorkClaimResult, CueLineCallerWorkMutationOptions, CueLineCallerWorkMutationResult } from "./api-contracts.js";
2
+ import type { CallerWorkClaim, CueLineRunState, StoredJob } from "./core/state-machine.js";
3
+ import type { RunStore } from "./state/store.js";
4
+ type CallerWorkMutationOptions = CueLineCallerWorkMutationOptions;
5
+ export declare function claimCueLineCallerJob(runId: string, jobId: string, options: CueLineCallerWorkClaimOptions): Promise<CueLineCallerWorkClaimResult>;
6
+ export declare function startCueLineCallerJob(runId: string, jobId: string, proof: CueLineCallerWorkClaimProof, options?: CallerWorkMutationOptions): Promise<CueLineCallerWorkMutationResult>;
7
+ export declare function heartbeatCueLineCallerJob(runId: string, jobId: string, proof: CueLineCallerWorkClaimProof, options?: CallerWorkMutationOptions): Promise<CueLineCallerWorkMutationResult>;
8
+ export declare function releaseCueLineCallerJob(runId: string, jobId: string, proof: CueLineCallerWorkClaimProof, options?: CallerWorkMutationOptions): Promise<CueLineCallerWorkMutationResult>;
9
+ /** Internal continuation repair: settle only claims whose durable TTL has elapsed. */
10
+ export declare function reconcileExpiredCallerWorkClaims(runId: string, options?: CallerWorkMutationOptions): Promise<number>;
11
+ /** Internal validation used while submitCueLineCallerJobResult owns the run lease. */
12
+ export declare function validateCallerWorkResultClaim(store: RunStore<CueLineRunState>, job: StoredJob, proof: CueLineCallerWorkClaimProof, home: string, now: Date, options?: {
13
+ durableTerminalIntent?: boolean;
14
+ }): Promise<{
15
+ claim: CallerWorkClaim;
16
+ alreadyTerminal: boolean;
17
+ }>;
18
+ export {};