cueline 0.1.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 +8 -0
- package/.codex-plugin/plugin.json +18 -0
- package/LICENSE +21 -0
- package/README.ja.md +144 -0
- package/README.ko.md +144 -0
- package/README.md +144 -0
- package/README.zh-CN.md +144 -0
- package/README.zh-TW.md +144 -0
- package/THIRD_PARTY_NOTICES.md +11 -0
- package/bin/cueline +14 -0
- package/config/routing.default.json +28 -0
- package/config/routing.schema.json +58 -0
- package/dist/src/api.d.ts +34 -0
- package/dist/src/api.js +153 -0
- package/dist/src/api.js.map +1 -0
- package/dist/src/browser/browser-adapter.d.ts +15 -0
- package/dist/src/browser/browser-adapter.js +2 -0
- package/dist/src/browser/browser-adapter.js.map +1 -0
- package/dist/src/browser/codex-iab/bootstrap.d.ts +66 -0
- package/dist/src/browser/codex-iab/bootstrap.js +41 -0
- package/dist/src/browser/codex-iab/bootstrap.js.map +1 -0
- package/dist/src/browser/codex-iab/chatgpt-client.d.ts +10 -0
- package/dist/src/browser/codex-iab/chatgpt-client.js +180 -0
- package/dist/src/browser/codex-iab/chatgpt-client.js.map +1 -0
- package/dist/src/browser/codex-iab/selectors.d.ts +3 -0
- package/dist/src/browser/codex-iab/selectors.js +17 -0
- package/dist/src/browser/codex-iab/selectors.js.map +1 -0
- package/dist/src/cli/main.d.ts +7 -0
- package/dist/src/cli/main.js +196 -0
- package/dist/src/cli/main.js.map +1 -0
- package/dist/src/cli/skill-links.d.ts +2 -0
- package/dist/src/cli/skill-links.js +64 -0
- package/dist/src/cli/skill-links.js.map +1 -0
- package/dist/src/core/controller-loop.d.ts +36 -0
- package/dist/src/core/controller-loop.js +292 -0
- package/dist/src/core/controller-loop.js.map +1 -0
- package/dist/src/core/errors.d.ts +10 -0
- package/dist/src/core/errors.js +18 -0
- package/dist/src/core/errors.js.map +1 -0
- package/dist/src/core/ids.d.ts +5 -0
- package/dist/src/core/ids.js +51 -0
- package/dist/src/core/ids.js.map +1 -0
- package/dist/src/core/runtime.d.ts +12 -0
- package/dist/src/core/runtime.js +35 -0
- package/dist/src/core/runtime.js.map +1 -0
- package/dist/src/core/state-machine.d.ts +28 -0
- package/dist/src/core/state-machine.js +99 -0
- package/dist/src/core/state-machine.js.map +1 -0
- package/dist/src/jobs/locks.d.ts +8 -0
- package/dist/src/jobs/locks.js +24 -0
- package/dist/src/jobs/locks.js.map +1 -0
- package/dist/src/jobs/status.d.ts +22 -0
- package/dist/src/jobs/status.js +53 -0
- package/dist/src/jobs/status.js.map +1 -0
- package/dist/src/jobs/supervisor.d.ts +22 -0
- package/dist/src/jobs/supervisor.js +96 -0
- package/dist/src/jobs/supervisor.js.map +1 -0
- package/dist/src/protocol/parse-command.d.ts +2 -0
- package/dist/src/protocol/parse-command.js +23 -0
- package/dist/src/protocol/parse-command.js.map +1 -0
- package/dist/src/protocol/types.d.ts +67 -0
- package/dist/src/protocol/types.js +2 -0
- package/dist/src/protocol/types.js.map +1 -0
- package/dist/src/protocol/validate-command.d.ts +2 -0
- package/dist/src/protocol/validate-command.js +181 -0
- package/dist/src/protocol/validate-command.js.map +1 -0
- package/dist/src/router/availability.d.ts +3 -0
- package/dist/src/router/availability.js +55 -0
- package/dist/src/router/availability.js.map +1 -0
- package/dist/src/router/config-loader.d.ts +3 -0
- package/dist/src/router/config-loader.js +92 -0
- package/dist/src/router/config-loader.js.map +1 -0
- package/dist/src/router/materialize.d.ts +8 -0
- package/dist/src/router/materialize.js +39 -0
- package/dist/src/router/materialize.js.map +1 -0
- package/dist/src/router/resolver.d.ts +6 -0
- package/dist/src/router/resolver.js +55 -0
- package/dist/src/router/resolver.js.map +1 -0
- package/dist/src/router/types.d.ts +24 -0
- package/dist/src/router/types.js +2 -0
- package/dist/src/router/types.js.map +1 -0
- package/dist/src/runners/process-runner.d.ts +15 -0
- package/dist/src/runners/process-runner.js +124 -0
- package/dist/src/runners/process-runner.js.map +1 -0
- package/dist/src/runners/registry.d.ts +17 -0
- package/dist/src/runners/registry.js +57 -0
- package/dist/src/runners/registry.js.map +1 -0
- package/dist/src/runners/runner-adapter.d.ts +32 -0
- package/dist/src/runners/runner-adapter.js +4 -0
- package/dist/src/runners/runner-adapter.js.map +1 -0
- package/dist/src/state/atomic-write.d.ts +1 -0
- package/dist/src/state/atomic-write.js +27 -0
- package/dist/src/state/atomic-write.js.map +1 -0
- package/dist/src/state/event-log.d.ts +8 -0
- package/dist/src/state/event-log.js +56 -0
- package/dist/src/state/event-log.js.map +1 -0
- package/dist/src/state/paths.d.ts +9 -0
- package/dist/src/state/paths.js +37 -0
- package/dist/src/state/paths.js.map +1 -0
- package/dist/src/state/store.d.ts +23 -0
- package/dist/src/state/store.js +108 -0
- package/dist/src/state/store.js.map +1 -0
- package/dist/src/version.d.ts +1 -0
- package/dist/src/version.js +2 -0
- package/dist/src/version.js.map +1 -0
- package/docs/architecture.md +83 -0
- package/docs/assets/README.md +51 -0
- package/docs/assets/cueline-banner-dark.svg +41 -0
- package/docs/assets/cueline-banner-light.svg +41 -0
- package/docs/assets/cueline-loop-en.svg +77 -0
- package/docs/assets/cueline-loop-ja.svg +77 -0
- package/docs/assets/cueline-loop-ko.svg +77 -0
- package/docs/assets/cueline-loop-zh-CN.svg +77 -0
- package/docs/assets/cueline-loop-zh-TW.svg +77 -0
- package/docs/assets/cueline-mark-dark.svg +10 -0
- package/docs/assets/cueline-mark-light.svg +10 -0
- package/docs/assets/cueline-wordmark-dark.svg +19 -0
- package/docs/assets/cueline-wordmark-light.svg +19 -0
- package/docs/compatibility.md +60 -0
- package/docs/controller-protocol.md +106 -0
- package/docs/provenance.md +10 -0
- package/docs/runner-contract.md +61 -0
- package/docs/state-and-recovery.md +67 -0
- package/evals/evals.json +41 -0
- package/install.sh +70 -0
- package/package.json +73 -0
- package/schemas/controller-command.schema.json +53 -0
- package/schemas/controller-observation.schema.json +32 -0
- package/skills/cueline/SKILL.md +80 -0
- package/skills/cueline/agents/openai.yaml +4 -0
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "cueline",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "Use a ChatGPT web conversation as the controller for durable local agent work.",
|
|
5
|
+
"author": {
|
|
6
|
+
"name": "CueLine contributors"
|
|
7
|
+
},
|
|
8
|
+
"skills": "./skills/",
|
|
9
|
+
"interface": {
|
|
10
|
+
"displayName": "CueLine",
|
|
11
|
+
"shortDescription": "Let ChatGPT Pro direct durable local agent runs.",
|
|
12
|
+
"longDescription": "CueLine lets a ChatGPT web conversation plan, dispatch, inspect, and complete local agent work while Codex validates commands, executes registered workers, and persists the run.",
|
|
13
|
+
"developerName": "CueLine contributors",
|
|
14
|
+
"category": "Productivity",
|
|
15
|
+
"capabilities": [],
|
|
16
|
+
"defaultPrompt": "Use $cueline to let the open ChatGPT conversation direct this task."
|
|
17
|
+
}
|
|
18
|
+
}
|
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 CueLine contributors
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.ja.md
ADDED
|
@@ -0,0 +1,144 @@
|
|
|
1
|
+
<picture>
|
|
2
|
+
<source media="(prefers-color-scheme: dark)" srcset="docs/assets/cueline-banner-dark.svg">
|
|
3
|
+
<img alt="CueLine — ChatGPT が指示し、あなたのマシンが実行する。" src="docs/assets/cueline-banner-light.svg" width="100%">
|
|
4
|
+
</picture>
|
|
5
|
+
|
|
6
|
+
<p align="center">
|
|
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
|
+
</p>
|
|
9
|
+
|
|
10
|
+
<p align="center">
|
|
11
|
+
<a href="README.md">English</a> · <a href="README.zh-TW.md">繁體中文</a> · <a href="README.zh-CN.md">简体中文</a> · <b>日本語</b> · <a href="README.ko.md">한국어</a>
|
|
12
|
+
</p>
|
|
13
|
+
|
|
14
|
+
**CueLine は、開いている ChatGPT のウェブ会話にハンドルを渡します。会話側が実行全体を計画し、次の一手を出す。CueLine はそのコマンドを一つずつ検証し、実際の作業をここ、あなたのマシンで行います。**
|
|
15
|
+
|
|
16
|
+
ウェブページがあなたのマシンに触れることはありません。ページが出せるのは、1 ラウンドにつき小さなテキストコマンドが一つだけです。CueLine はそのコマンドが正しい形式か、この実行(run)に属するものか、どのローカルワーカーに対応するかを判断し、そのうえで実行し、証拠を保存し、証拠を返します。
|
|
17
|
+
|
|
18
|
+
CueLine は独立した実装で、**ランタイムの npm 依存はゼロ**です。Omnilane や GPT Relay のラッパーではありません。
|
|
19
|
+
|
|
20
|
+
## 1 回の実行は実際にどう進むか
|
|
21
|
+
|
|
22
|
+
<img alt="CueLine の 1 回の実行をプロンプトブックとして読む:マシンが観測を送り、コントローラーがコマンドを 1 つ出し、登録済みの runner が実行し、complete が出るまで続く。" src="docs/assets/cueline-loop-ja.svg" width="100%">
|
|
23
|
+
|
|
24
|
+
各ラウンドで CueLine は、これから何を尋ねるのかをまず記録し、観測(observation)を 1 件だけ会話に送り、`<CueLineControl>` エンベロープを**ちょうど 1 つだけ**読み戻します。コントローラーは 5 つのアクション——`dispatch`、`wait`、`inspect`、`complete`、`blocked`——から 1 つを選び、エンベロープの外にあるテキストが実行されることは一切ありません。誤った run、誤ったラウンド、あるいは不正なジョブ定義を指すコマンドは、推測で補われることなく、回数制限つきの修復のために差し戻されます。ループは `complete` または `blocked` で停止し、ラウンド上限(既定 12 回)に達した場合も停止します。
|
|
25
|
+
|
|
26
|
+
コントローラーは*何が起こるべきか*を選びます。ローカル側は*それを許すか、どう許すか*を選びます。レーンが有効であること、候補がプロセス起動の**前に**利用可能だと確認されていること、`argv[0]` があなたのルーティング設定によってすでに登録されていること。シェルを経由するものは何もありません。ワーカーがいったん起動したら、黙って 2 番目の候補にフォールバックすることはありません。失敗は再試行ではなく、証拠として返ります。
|
|
27
|
+
|
|
28
|
+
これは許可リスト(allow-list)であって、サンドボックスではありません。登録されたワーカーは CueLine プロセス自身と同じ権限で動きます。`advise` は Codex の読み取り専用サンドボックスに、`work` は `workspace-write` に対応しますが、登録したものが、そのまま許可したものになります。
|
|
29
|
+
|
|
30
|
+
## クイックスタート
|
|
31
|
+
|
|
32
|
+
必要なもの:Node.js 22 以上、組み込みブラウザーを備えた Codex、そして——同梱の既定レーンを使う場合は——`PATH` 上の `codex` CLI。
|
|
33
|
+
|
|
34
|
+
```bash
|
|
35
|
+
git clone https://github.com/Seraphim0916/cueline.git
|
|
36
|
+
cd cueline
|
|
37
|
+
npm ci
|
|
38
|
+
npm run build
|
|
39
|
+
./install.sh # ~/.codex/skills/cueline と ~/.local/bin/cueline のシンボリックリンクを作成
|
|
40
|
+
cueline doctor
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
`install.sh` が作るのはこの 2 つのシンボリックリンクだけです。自分が所有していないパスの上書きは拒否し、`./install.sh --uninstall` も自分が作ったリンクだけを削除します。
|
|
44
|
+
|
|
45
|
+
次に、Codex で:
|
|
46
|
+
|
|
47
|
+
1. Codex の組み込みブラウザーで `https://chatgpt.com` を開き、サインインします。
|
|
48
|
+
2. 主導させたい会話を選択したままにします。そのページで現在選ばれているモデルがコントローラーです。CueLine はモデルを切り替えませんし、プランの確認もしません。
|
|
49
|
+
3. Codex にこう頼みます:*「CueLine を使って、このリポジトリをレビューし、次の変更を証拠つきで提案して。」*
|
|
50
|
+
4. 返ってきた `runId` を控えておきます。中断した実行を再開する手がかりになります。
|
|
51
|
+
|
|
52
|
+
同梱の `cueline` スキルは、Codex 自身の Node ランタイムからこのパッケージを駆動します。組み込みブラウザーのオブジェクトはそこに存在するためです。別に起動したプレーンな `node` プロセスはそれを継承しません。
|
|
53
|
+
|
|
54
|
+
## コードから駆動する
|
|
55
|
+
|
|
56
|
+
```js
|
|
57
|
+
import { createCodexIabAdapter, runCueLine } from "cueline";
|
|
58
|
+
|
|
59
|
+
const result = await runCueLine({
|
|
60
|
+
request: "Inspect the repository, delegate an implementation plan, and report the evidence.",
|
|
61
|
+
browser: createCodexIabAdapter(),
|
|
62
|
+
// 任意:conversationUrl、routingConfig / routingConfigPath、home、cwd、limits。
|
|
63
|
+
});
|
|
64
|
+
|
|
65
|
+
if (result.status === "complete") {
|
|
66
|
+
console.log(result.finalDeliveryText);
|
|
67
|
+
}
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
`startCueLineRun` が明示的な開始点です(`runCueLine` はその別名)。`continueCueLineRun({ runId })` は中断した実行を同じ会話で再開し、新しいアダプターを渡さないかぎり保存済みの会話 URL を再利用します。`loadCueLineRunState(runId)` は永続化された状態を読むだけで、何も駆動しません。すでに `complete` または `blocked` に達した実行はそのまま返され、二度とディスパッチされません。
|
|
71
|
+
|
|
72
|
+
## CLI
|
|
73
|
+
|
|
74
|
+
CLI はブラウザーを駆動しません。ローカル側が健全かどうかを教えるだけです。
|
|
75
|
+
|
|
76
|
+
```console
|
|
77
|
+
$ cueline doctor
|
|
78
|
+
CueLine 0.1.0
|
|
79
|
+
status ok
|
|
80
|
+
node 22.14.0 ok
|
|
81
|
+
config /Users/you/cueline/config/routing.default.json valid
|
|
82
|
+
home /Users/you/.cueline
|
|
83
|
+
available_lanes 1
|
|
84
|
+
|
|
85
|
+
$ cueline routing
|
|
86
|
+
default codex-default available
|
|
87
|
+
|
|
88
|
+
$ cueline jobs
|
|
89
|
+
No jobs.
|
|
90
|
+
|
|
91
|
+
$ cueline config path
|
|
92
|
+
/Users/you/cueline/config/routing.default.json
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
Node が古すぎる場合、あるいは解決できるレーンが一つもない場合、`cueline doctor` は非ゼロで終了します。そのため事前チェックとしてそのまま使えます。`cueline routing` は、黙って別のものを選ぶのではなく、そのレーンがなぜ使えないのかを示します。`cueline help` ですべて一覧できます。
|
|
96
|
+
|
|
97
|
+
## 設定
|
|
98
|
+
|
|
99
|
+
`CUELINE_CONFIG` はルーティング設定ファイルを選び、`CUELINE_HOME` はローカル状態の置き場所を移します(既定は `~/.cueline`)。
|
|
100
|
+
|
|
101
|
+
同梱の `default` レーンには候補が 1 つ、`codex-default` があります。タスクを stdin で渡して `codex exec` を実行し、`advise` は `read-only`、`work` は `workspace-write` を使います。別のワーカーを登録するには、[`config/routing.default.json`](config/routing.default.json) をコピーして候補を追加し、`CUELINE_CONFIG` をそこに向けます。`argv[0]` の実行ファイルはその行為によって登録され、レーンが解決するにはそれが `PATH` 上にある必要もあります。
|
|
102
|
+
|
|
103
|
+
状態は `CUELINE_HOME` の下に置かれます:
|
|
104
|
+
|
|
105
|
+
```text
|
|
106
|
+
runs/<run-id>/events.jsonl 追記のみ、正本
|
|
107
|
+
runs/<run-id>/snapshot.json リプレイの最適化、破棄可能
|
|
108
|
+
jobs/<job-id>.json ジョブごとの実行証拠
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
記録そのものはイベントログです。コントローラーのターンは送信する前に書かれ、ジョブはプロセスが起動する前に登録されます。だからこそ、意図と副作用のあいだで中断が起きても痕跡が残ります。壊れたスナップショットは信用されず、無視されてイベント 1 番から再構築されます。
|
|
112
|
+
|
|
113
|
+
## 検証
|
|
114
|
+
|
|
115
|
+
```bash
|
|
116
|
+
npm ci
|
|
117
|
+
npm run typecheck
|
|
118
|
+
npm test
|
|
119
|
+
npm run smoke:fake
|
|
120
|
+
bash test/shell/install.test.sh
|
|
121
|
+
npm pack --dry-run
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
`npm run smoke:fake` は、偽のブラウザーと偽の runner を相手に、コントローラーループ全体をオフラインで走らせます。証明できるのはループであって、ライブのページではありません。後者を証明できるのは、組み込みブラウザーを通じて実際に完了した 1 ラウンドだけです。
|
|
125
|
+
|
|
126
|
+
## 0.1 の制限
|
|
127
|
+
|
|
128
|
+
テキストのみ。1 回の実行につき会話は 1 つ。モデル切り替え、画像、ファイルアップロード、Deep Research、Projects、Apps には対応しません。ワーカーが起動したあとの自動リトライやフォールバックはありません。失敗した `work` ジョブは、どこまで進んだか CueLine には証明できないため、副作用が不確定であるという印つきで報告されます。主なデスクトップ対象は macOS、CI 対象は Linux です。Windows は未検証で、`install.sh` は Windows 用インストーラーではありません。アダプターは現行の ChatGPT ウェブ UI に依存するため、UI が変わった場合は `COMPOSER_MISSING`、`SEND_BUTTON_MISSING`、あるいは応答タイムアウトとして明示的に表面化します——でっち上げの回答になることは決してありません。
|
|
129
|
+
|
|
130
|
+
完全な対応表は [compatibility](docs/compatibility.md) を参照してください。
|
|
131
|
+
|
|
132
|
+
## ドキュメント
|
|
133
|
+
|
|
134
|
+
[architecture](docs/architecture.md) · [controller protocol](docs/controller-protocol.md) · [runner contract](docs/runner-contract.md) · [state and recovery](docs/state-and-recovery.md) · [compatibility](docs/compatibility.md) · [provenance](docs/provenance.md)(いずれも英語)
|
|
135
|
+
|
|
136
|
+
## 開発
|
|
137
|
+
|
|
138
|
+
TypeScript、ESM、Node の組み込みモジュールのみ。`npm run build` は `dist/` へコンパイルし、テストは `node --test` でコンパイル済みの成果物に対して実行します。CI は Ubuntu と macOS 上の Node 22 / 24 を対象とします。
|
|
139
|
+
|
|
140
|
+
CueLine は独立したプロジェクトであり、OpenAI やその他いかなる企業とも提携しておらず、推奨・後援も受けていません。[provenance](docs/provenance.md) と [third-party notices](THIRD_PARTY_NOTICES.md) を参照してください。
|
|
141
|
+
|
|
142
|
+
## ライセンス
|
|
143
|
+
|
|
144
|
+
MIT。[LICENSE](LICENSE) を参照してください。
|
package/README.ko.md
ADDED
|
@@ -0,0 +1,144 @@
|
|
|
1
|
+
<picture>
|
|
2
|
+
<source media="(prefers-color-scheme: dark)" srcset="docs/assets/cueline-banner-dark.svg">
|
|
3
|
+
<img alt="CueLine — ChatGPT가 지시하고, 당신의 머신이 실행합니다." src="docs/assets/cueline-banner-light.svg" width="100%">
|
|
4
|
+
</picture>
|
|
5
|
+
|
|
6
|
+
<p align="center">
|
|
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
|
+
</p>
|
|
9
|
+
|
|
10
|
+
<p align="center">
|
|
11
|
+
<a href="README.md">English</a> · <a href="README.zh-TW.md">繁體中文</a> · <a href="README.zh-CN.md">简体中文</a> · <a href="README.ja.md">日本語</a> · <b>한국어</b>
|
|
12
|
+
</p>
|
|
13
|
+
|
|
14
|
+
**CueLine은 이미 열려 있는 ChatGPT 웹 대화에 운전대를 넘깁니다. 대화가 실행 전체를 계획하고 다음 단계를 지시하면, CueLine은 모든 명령을 검증하고 실제 작업은 바로 이곳, 당신의 머신에서 수행합니다.**
|
|
15
|
+
|
|
16
|
+
웹 페이지는 당신의 머신을 건드리지 않습니다. 페이지가 내보내는 것은 라운드당 작은 텍스트 명령 하나뿐입니다. CueLine은 그 명령의 형식이 올바른지, 이번 실행(run)에 속하는지, 어떤 로컬 워커에 대응하는지를 판단한 뒤에야 실행하고, 증거를 보관하고, 그 증거를 돌려줍니다.
|
|
17
|
+
|
|
18
|
+
CueLine은 독립적인 구현이며 **런타임 npm 의존성이 전혀 없습니다**. Omnilane이나 GPT Relay를 감싼 래퍼가 아닙니다.
|
|
19
|
+
|
|
20
|
+
## 실행 한 번은 실제로 이렇게 흘러갑니다
|
|
21
|
+
|
|
22
|
+
<img alt="CueLine 실행 한 번을 프롬프트북처럼 읽기: 머신이 관측을 보내고, 컨트롤러가 명령 하나를 내리고, 등록된 runner가 실행하며, complete가 나올 때까지 이어집니다." src="docs/assets/cueline-loop-ko.svg" width="100%">
|
|
23
|
+
|
|
24
|
+
매 라운드마다 CueLine은 무엇을 물으려 하는지 먼저 기록하고, 관측(observation) 하나를 대화에 보낸 뒤, `<CueLineControl>` 엔벨로프를 **정확히 하나만** 읽어 옵니다. 컨트롤러는 다섯 가지 동작 — `dispatch`, `wait`, `inspect`, `complete`, `blocked` — 중 하나를 고르며, 엔벨로프 바깥의 텍스트는 절대 실행되지 않습니다. 잘못된 run이나 잘못된 라운드를 가리키거나 작업 정의가 잘못된 명령은 추측으로 메워지지 않고, 횟수가 제한된 복구 시도를 위해 되돌려 보내집니다. 루프는 `complete` 또는 `blocked`에서 멈추며, 라운드 한도(기본 12회)를 소진해도 멈춥니다.
|
|
25
|
+
|
|
26
|
+
컨트롤러는 *무엇이 일어나야 하는지*를 고릅니다. 로컬 쪽은 *그것이 허용되는지, 어떻게 허용되는지*를 고릅니다. 레인이 활성화되어 있어야 하고, 후보는 어떤 프로세스가 뜨기 **전에** 사용 가능함이 확인되어야 하며, `argv[0]`은 당신의 라우팅 설정에 이미 등록되어 있어야 합니다. 셸을 거치는 것은 아무것도 없습니다. 워커가 일단 시작되면 두 번째 후보로 조용히 넘어가는 폴백은 없습니다. 실패는 재시도가 아니라 증거로 돌아옵니다.
|
|
27
|
+
|
|
28
|
+
이것은 허용 목록(allow-list)이지 샌드박스가 아닙니다. 등록된 워커는 CueLine 프로세스 자신과 동일한 권한으로 실행됩니다. `advise`는 Codex의 읽기 전용 샌드박스에, `work`는 `workspace-write`에 대응하지만, 당신이 등록한 것이 곧 당신이 승인한 것입니다.
|
|
29
|
+
|
|
30
|
+
## 빠른 시작
|
|
31
|
+
|
|
32
|
+
필요한 것: Node.js 22 이상, 내장 브라우저를 갖춘 Codex, 그리고 — 기본 제공 레인을 쓴다면 — `PATH` 위의 `codex` CLI.
|
|
33
|
+
|
|
34
|
+
```bash
|
|
35
|
+
git clone https://github.com/Seraphim0916/cueline.git
|
|
36
|
+
cd cueline
|
|
37
|
+
npm ci
|
|
38
|
+
npm run build
|
|
39
|
+
./install.sh # ~/.codex/skills/cueline 과 ~/.local/bin/cueline 심볼릭 링크 생성
|
|
40
|
+
cueline doctor
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
`install.sh`는 이 두 개의 심볼릭 링크만 만듭니다. 자신이 소유하지 않은 경로는 덮어쓰기를 거부하며, `./install.sh --uninstall` 역시 자신이 만든 링크만 제거합니다.
|
|
44
|
+
|
|
45
|
+
그다음 Codex에서:
|
|
46
|
+
|
|
47
|
+
1. Codex의 내장 브라우저로 `https://chatgpt.com`을 열고 로그인합니다.
|
|
48
|
+
2. 지휘를 맡길 대화를 선택한 상태로 둡니다. 그 페이지에서 현재 선택된 모델이 컨트롤러입니다. CueLine은 모델을 바꾸지 않고, 요금제를 확인하지도 않습니다.
|
|
49
|
+
3. Codex에게 CueLine으로 처리해 달라고 요청합니다: *"CueLine으로: 이 저장소를 검토하고 다음 변경을 증거와 함께 제안해 줘."*
|
|
50
|
+
4. 반환된 `runId`를 보관하세요. 중단된 실행을 이어서 진행하는 열쇠입니다.
|
|
51
|
+
|
|
52
|
+
기본 제공 `cueline` 스킬은 Codex 자체의 Node 런타임에서 이 패키지를 구동합니다. 내장 브라우저 객체가 바로 그곳에 있기 때문입니다. 옆에서 따로 띄운 평범한 `node` 프로세스는 그것을 물려받지 못합니다.
|
|
53
|
+
|
|
54
|
+
## 코드에서 구동하기
|
|
55
|
+
|
|
56
|
+
```js
|
|
57
|
+
import { createCodexIabAdapter, runCueLine } from "cueline";
|
|
58
|
+
|
|
59
|
+
const result = await runCueLine({
|
|
60
|
+
request: "Inspect the repository, delegate an implementation plan, and report the evidence.",
|
|
61
|
+
browser: createCodexIabAdapter(),
|
|
62
|
+
// 선택: conversationUrl, routingConfig / routingConfigPath, home, cwd, limits.
|
|
63
|
+
});
|
|
64
|
+
|
|
65
|
+
if (result.status === "complete") {
|
|
66
|
+
console.log(result.finalDeliveryText);
|
|
67
|
+
}
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
`startCueLineRun`이 명시적인 시작점입니다(`runCueLine`은 그 별칭). `continueCueLineRun({ runId })`은 중단된 실행을 같은 대화에서 재개하며, 새 어댑터를 넘기지 않는 한 저장된 대화 URL을 재사용합니다. `loadCueLineRunState(runId)`는 저장된 상태를 읽기만 하고 아무것도 구동하지 않습니다. 이미 `complete`나 `blocked`에 도달한 실행은 그대로 반환되며, 두 번 디스패치되지 않습니다.
|
|
71
|
+
|
|
72
|
+
## CLI
|
|
73
|
+
|
|
74
|
+
CLI는 브라우저를 구동하지 않습니다. 로컬 쪽이 멀쩡한지 알려줄 뿐입니다.
|
|
75
|
+
|
|
76
|
+
```console
|
|
77
|
+
$ cueline doctor
|
|
78
|
+
CueLine 0.1.0
|
|
79
|
+
status ok
|
|
80
|
+
node 22.14.0 ok
|
|
81
|
+
config /Users/you/cueline/config/routing.default.json valid
|
|
82
|
+
home /Users/you/.cueline
|
|
83
|
+
available_lanes 1
|
|
84
|
+
|
|
85
|
+
$ cueline routing
|
|
86
|
+
default codex-default available
|
|
87
|
+
|
|
88
|
+
$ cueline jobs
|
|
89
|
+
No jobs.
|
|
90
|
+
|
|
91
|
+
$ cueline config path
|
|
92
|
+
/Users/you/cueline/config/routing.default.json
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
Node 버전이 너무 낮거나 해석 가능한 레인이 하나도 없으면 `cueline doctor`는 0이 아닌 코드로 종료합니다. 그래서 사전 점검용으로 그대로 쓸 수 있습니다. `cueline routing`은 조용히 다른 것을 고르는 대신, 그 레인이 왜 사용 불가인지 보여줍니다. `cueline help`가 전부를 나열합니다.
|
|
96
|
+
|
|
97
|
+
## 설정
|
|
98
|
+
|
|
99
|
+
`CUELINE_CONFIG`는 라우팅 설정 파일을 고르고, `CUELINE_HOME`은 로컬 상태의 위치를 옮깁니다(기본값 `~/.cueline`).
|
|
100
|
+
|
|
101
|
+
기본 제공 `default` 레인에는 후보가 하나, `codex-default`가 있습니다. 작업을 stdin으로 넘겨 `codex exec`를 실행하며, `advise`에는 `read-only`, `work`에는 `workspace-write`를 씁니다. 다른 워커를 등록하려면 [`config/routing.default.json`](config/routing.default.json)을 복사해 후보를 추가하고 `CUELINE_CONFIG`를 그쪽으로 가리키면 됩니다. `argv[0]`의 실행 파일은 바로 그 행위로 등록되며, 레인이 해석되려면 그것이 `PATH` 위에도 있어야 합니다.
|
|
102
|
+
|
|
103
|
+
상태는 `CUELINE_HOME` 아래에 놓입니다:
|
|
104
|
+
|
|
105
|
+
```text
|
|
106
|
+
runs/<run-id>/events.jsonl 추가 전용, 정본
|
|
107
|
+
runs/<run-id>/snapshot.json 재생 최적화용, 버려도 무방
|
|
108
|
+
jobs/<job-id>.json 작업별 실행 증거
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
기록 그 자체는 이벤트 로그입니다. 컨트롤러의 턴은 보내기 전에 기록되고, 작업은 프로세스가 시작되기 전에 등록됩니다. 그래서 의도와 부작용 사이에서 중단이 일어나도 흔적이 남습니다. 손상된 스냅샷은 신뢰되지 않고, 무시된 뒤 이벤트 1번부터 다시 만들어집니다.
|
|
112
|
+
|
|
113
|
+
## 검증
|
|
114
|
+
|
|
115
|
+
```bash
|
|
116
|
+
npm ci
|
|
117
|
+
npm run typecheck
|
|
118
|
+
npm test
|
|
119
|
+
npm run smoke:fake
|
|
120
|
+
bash test/shell/install.test.sh
|
|
121
|
+
npm pack --dry-run
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
`npm run smoke:fake`는 가짜 브라우저와 가짜 runner를 상대로 컨트롤러 루프 전체를 오프라인으로 돌립니다. 이것이 증명하는 것은 루프이지 실제 페이지가 아닙니다. 후자는 내장 브라우저를 통해 실제로 완료된 한 라운드만이 증명할 수 있습니다.
|
|
125
|
+
|
|
126
|
+
## 0.1의 한계
|
|
127
|
+
|
|
128
|
+
텍스트 전용. 실행 하나당 대화 하나. 모델 전환, 이미지, 파일 업로드, Deep Research, Projects, Apps는 지원하지 않습니다. 워커가 시작된 뒤의 자동 재시도나 폴백도 없습니다. 실패한 `work` 작업은 어디까지 진행됐는지 CueLine이 증명할 수 없으므로, 부작용이 불확실하다는 표시와 함께 보고됩니다. 주력 데스크톱 대상은 macOS이고 CI 대상은 Linux입니다. Windows는 검증되지 않았으며 `install.sh`는 Windows용 설치 프로그램이 아닙니다. 어댑터는 현재의 ChatGPT 웹 UI에 의존하므로, UI가 바뀌면 `COMPOSER_MISSING`, `SEND_BUTTON_MISSING`, 또는 응답 타임아웃으로 명시적으로 드러납니다 — 지어낸 답으로 둔갑하는 일은 결코 없습니다.
|
|
129
|
+
|
|
130
|
+
전체 표는 [compatibility](docs/compatibility.md)를 보세요.
|
|
131
|
+
|
|
132
|
+
## 문서
|
|
133
|
+
|
|
134
|
+
[architecture](docs/architecture.md) · [controller protocol](docs/controller-protocol.md) · [runner contract](docs/runner-contract.md) · [state and recovery](docs/state-and-recovery.md) · [compatibility](docs/compatibility.md) · [provenance](docs/provenance.md) (모두 영어)
|
|
135
|
+
|
|
136
|
+
## 개발
|
|
137
|
+
|
|
138
|
+
TypeScript, ESM, Node 내장 모듈만 사용합니다. `npm run build`는 `dist/`로 컴파일하고, 테스트는 `node --test`로 컴파일된 결과물을 대상으로 실행합니다. CI는 Ubuntu와 macOS의 Node 22와 24를 다룹니다.
|
|
139
|
+
|
|
140
|
+
CueLine은 독립 프로젝트이며 OpenAI를 비롯한 어떤 회사와도 제휴하거나 보증·후원을 받지 않았습니다. [provenance](docs/provenance.md)와 [third-party notices](THIRD_PARTY_NOTICES.md)를 참고하세요.
|
|
141
|
+
|
|
142
|
+
## 라이선스
|
|
143
|
+
|
|
144
|
+
MIT. [LICENSE](LICENSE)를 참고하세요.
|
package/README.md
ADDED
|
@@ -0,0 +1,144 @@
|
|
|
1
|
+
<picture>
|
|
2
|
+
<source media="(prefers-color-scheme: dark)" srcset="docs/assets/cueline-banner-dark.svg">
|
|
3
|
+
<img alt="CueLine — ChatGPT directs. Your machine executes." src="docs/assets/cueline-banner-light.svg" width="100%">
|
|
4
|
+
</picture>
|
|
5
|
+
|
|
6
|
+
<p align="center">
|
|
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
|
+
</p>
|
|
9
|
+
|
|
10
|
+
<p align="center">
|
|
11
|
+
<b>English</b> · <a href="README.zh-TW.md">繁體中文</a> · <a href="README.zh-CN.md">简体中文</a> · <a href="README.ja.md">日本語</a> · <a href="README.ko.md">한국어</a>
|
|
12
|
+
</p>
|
|
13
|
+
|
|
14
|
+
**CueLine hands the wheel to an open ChatGPT web conversation: it plans the run and calls each next step, while CueLine checks every command and does the actual work here, on your machine.**
|
|
15
|
+
|
|
16
|
+
The web page never touches your machine. It only ever emits one small text command per round. CueLine decides whether that command is well-formed, whether it belongs to this run, which local worker it maps to — and then runs it, keeps the evidence, and hands the evidence back.
|
|
17
|
+
|
|
18
|
+
CueLine is a standalone implementation with **no runtime npm dependencies**. It is not a wrapper around Omnilane or GPT Relay.
|
|
19
|
+
|
|
20
|
+
## How a run actually goes
|
|
21
|
+
|
|
22
|
+
<img alt="A CueLine run read as a promptbook: the machine reports an observation, the controller calls one command, the registered runner executes it, until the controller calls complete." src="docs/assets/cueline-loop-en.svg" width="100%">
|
|
23
|
+
|
|
24
|
+
Each round: CueLine writes down what it is about to ask, sends one observation into the conversation, and 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 stops at `complete` or `blocked`, or when it runs out of rounds (12 by default).
|
|
25
|
+
|
|
26
|
+
The controller chooses *what should happen*. 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. Once a worker starts, there is no silent fallback to a second candidate — a failure comes back as evidence, not as a retry.
|
|
27
|
+
|
|
28
|
+
That 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.
|
|
29
|
+
|
|
30
|
+
## Quick start
|
|
31
|
+
|
|
32
|
+
You need Node.js 22+, Codex with its built-in Browser, and — for the bundled default lane — the `codex` CLI on `PATH`.
|
|
33
|
+
|
|
34
|
+
```bash
|
|
35
|
+
git clone https://github.com/Seraphim0916/cueline.git
|
|
36
|
+
cd cueline
|
|
37
|
+
npm ci
|
|
38
|
+
npm run build
|
|
39
|
+
./install.sh # symlinks ~/.codex/skills/cueline and ~/.local/bin/cueline
|
|
40
|
+
cueline doctor
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
`install.sh` creates those two symlinks and nothing else; it refuses to overwrite a path it does not own, and `./install.sh --uninstall` removes only its own links.
|
|
44
|
+
|
|
45
|
+
Then, in Codex:
|
|
46
|
+
|
|
47
|
+
1. Open `https://chatgpt.com` in Codex's built-in Browser and sign in.
|
|
48
|
+
2. Leave the conversation you want to be in charge selected — that page's current model is the controller. CueLine does not switch models and does not check your plan.
|
|
49
|
+
3. Ask Codex to use CueLine for the task: *"Use CueLine: review this repository and propose the next change, with evidence."*
|
|
50
|
+
4. Keep the returned `runId`. It is how an interrupted run is resumed.
|
|
51
|
+
|
|
52
|
+
The bundled `cueline` skill drives the package from Codex's own Node runtime, which is where the in-app Browser object lives. A plain `node` process started on the side does not inherit it.
|
|
53
|
+
|
|
54
|
+
## Driving it from code
|
|
55
|
+
|
|
56
|
+
```js
|
|
57
|
+
import { createCodexIabAdapter, runCueLine } from "cueline";
|
|
58
|
+
|
|
59
|
+
const result = await runCueLine({
|
|
60
|
+
request: "Inspect the repository, delegate an implementation plan, and report the evidence.",
|
|
61
|
+
browser: createCodexIabAdapter(),
|
|
62
|
+
// Optional: conversationUrl, routingConfig / routingConfigPath, home, cwd, limits.
|
|
63
|
+
});
|
|
64
|
+
|
|
65
|
+
if (result.status === "complete") {
|
|
66
|
+
console.log(result.finalDeliveryText);
|
|
67
|
+
}
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
`startCueLineRun` is the explicit start (`runCueLine` is its alias). `continueCueLineRun({ runId })` resumes an interrupted run in the same conversation, and reuses the stored conversation URL unless you hand it a new adapter. `loadCueLineRunState(runId)` reads persisted state without driving anything. A run that already reached `complete` or `blocked` is returned as-is, never dispatched twice.
|
|
71
|
+
|
|
72
|
+
## The CLI
|
|
73
|
+
|
|
74
|
+
The CLI does not drive the browser. It tells you whether the local half is sound.
|
|
75
|
+
|
|
76
|
+
```console
|
|
77
|
+
$ cueline doctor
|
|
78
|
+
CueLine 0.1.0
|
|
79
|
+
status ok
|
|
80
|
+
node 22.14.0 ok
|
|
81
|
+
config /Users/you/cueline/config/routing.default.json valid
|
|
82
|
+
home /Users/you/.cueline
|
|
83
|
+
available_lanes 1
|
|
84
|
+
|
|
85
|
+
$ cueline routing
|
|
86
|
+
default codex-default available
|
|
87
|
+
|
|
88
|
+
$ cueline jobs
|
|
89
|
+
No jobs.
|
|
90
|
+
|
|
91
|
+
$ cueline config path
|
|
92
|
+
/Users/you/cueline/config/routing.default.json
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
`cueline doctor` exits non-zero when Node is too old or no lane can resolve, which makes it usable as a preflight check. `cueline routing` shows why a lane is unavailable instead of quietly selecting something else. `cueline help` lists everything.
|
|
96
|
+
|
|
97
|
+
## Configuration
|
|
98
|
+
|
|
99
|
+
`CUELINE_CONFIG` selects a routing file; `CUELINE_HOME` moves local state (default `~/.cueline`).
|
|
100
|
+
|
|
101
|
+
The bundled `default` lane holds one candidate, `codex-default`: `codex exec` with the task on stdin, `read-only` for `advise`, `workspace-write` for `work`. To register a different worker, copy [`config/routing.default.json`](config/routing.default.json), add your candidate, and point `CUELINE_CONFIG` at it — the executable in `argv[0]` becomes registered by that act, and must also be on `PATH` before a lane resolves.
|
|
102
|
+
|
|
103
|
+
State lives under `CUELINE_HOME`:
|
|
104
|
+
|
|
105
|
+
```text
|
|
106
|
+
runs/<run-id>/events.jsonl append-only, authoritative
|
|
107
|
+
runs/<run-id>/snapshot.json a replay optimization, disposable
|
|
108
|
+
jobs/<job-id>.json per-job execution evidence
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
The event log is the record: the controller turn is written before it is sent, and a job is registered before its process starts, so an interruption between intent and side effect leaves a trace. A corrupt snapshot is ignored and rebuilt from event 1 rather than trusted.
|
|
112
|
+
|
|
113
|
+
## Verify
|
|
114
|
+
|
|
115
|
+
```bash
|
|
116
|
+
npm ci
|
|
117
|
+
npm run typecheck
|
|
118
|
+
npm test
|
|
119
|
+
npm run smoke:fake
|
|
120
|
+
bash test/shell/install.test.sh
|
|
121
|
+
npm pack --dry-run
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
`npm run smoke:fake` exercises the whole controller loop against a fake browser and fake runner, offline. It proves the loop, not the live page — only a real completed turn through the in-app Browser proves that.
|
|
125
|
+
|
|
126
|
+
## Limits in 0.1
|
|
127
|
+
|
|
128
|
+
Text only. One conversation per run. No model switching, no images, no file upload, no Deep Research, Projects, or Apps. No automatic retry or fallback once a worker has started — a failed `work` job is reported with its side effects flagged as ambiguous, because CueLine cannot prove how far it got. macOS is the primary desktop target and Linux is the CI target; Windows is unverified, and `install.sh` is not a Windows installer. The adapter depends on the current ChatGPT web UI, so a UI change surfaces as an explicit `COMPOSER_MISSING`, `SEND_BUTTON_MISSING`, or response timeout — never as a fabricated answer.
|
|
129
|
+
|
|
130
|
+
See [compatibility](docs/compatibility.md) for the full matrix.
|
|
131
|
+
|
|
132
|
+
## Docs
|
|
133
|
+
|
|
134
|
+
[architecture](docs/architecture.md) · [controller protocol](docs/controller-protocol.md) · [runner contract](docs/runner-contract.md) · [state and recovery](docs/state-and-recovery.md) · [compatibility](docs/compatibility.md) · [provenance](docs/provenance.md)
|
|
135
|
+
|
|
136
|
+
## Development
|
|
137
|
+
|
|
138
|
+
TypeScript, ESM, Node built-ins only. `npm run build` compiles to `dist/`; tests run on the compiled output with `node --test`. CI covers Node 22 and 24 on Ubuntu and macOS.
|
|
139
|
+
|
|
140
|
+
CueLine is an independent project and is not affiliated with, endorsed by, or sponsored by OpenAI or any other company. See [provenance](docs/provenance.md) and [third-party notices](THIRD_PARTY_NOTICES.md).
|
|
141
|
+
|
|
142
|
+
## License
|
|
143
|
+
|
|
144
|
+
MIT. See [LICENSE](LICENSE).
|
package/README.zh-CN.md
ADDED
|
@@ -0,0 +1,144 @@
|
|
|
1
|
+
<picture>
|
|
2
|
+
<source media="(prefers-color-scheme: dark)" srcset="docs/assets/cueline-banner-dark.svg">
|
|
3
|
+
<img alt="CueLine — ChatGPT 下指令,你的机器执行。" src="docs/assets/cueline-banner-light.svg" width="100%">
|
|
4
|
+
</picture>
|
|
5
|
+
|
|
6
|
+
<p align="center">
|
|
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
|
+
</p>
|
|
9
|
+
|
|
10
|
+
<p align="center">
|
|
11
|
+
<a href="README.md">English</a> · <a href="README.zh-TW.md">繁體中文</a> · <b>简体中文</b> · <a href="README.ja.md">日本語</a> · <a href="README.ko.md">한국어</a>
|
|
12
|
+
</p>
|
|
13
|
+
|
|
14
|
+
**CueLine 把方向盘交给一个已经打开的 ChatGPT 网页会话:由它规划整轮运行、发出每一步指令;而 CueLine 负责校验每一条指令,并在你这台机器上把活儿真正干完。**
|
|
15
|
+
|
|
16
|
+
那个网页碰不到你的机器。它每一轮只输出一小段文本指令。CueLine 判断这条指令格式是否合法、是否属于本次运行、对应到哪个本地 worker——然后才执行它、保留证据,再把证据交回去。
|
|
17
|
+
|
|
18
|
+
CueLine 是独立实现,**没有任何运行时 npm 依赖**,也不是 Omnilane 或 GPT Relay 的包装层。
|
|
19
|
+
|
|
20
|
+
## 一次运行实际是怎么走的
|
|
21
|
+
|
|
22
|
+
<img alt="一次 CueLine 运行像一本提示本:机器发出观测,控制器发出一条指令,已注册的 runner 执行它,直到控制器发出 complete。" src="docs/assets/cueline-loop-zh-CN.svg" width="100%">
|
|
23
|
+
|
|
24
|
+
每一轮:CueLine 先把“接下来要问什么”写入记录,向会话发送一份观测(observation),再读回**恰好一个** `<CueLineControl>` 信封。控制器从五个动作中选一个——`dispatch`、`wait`、`inspect`、`complete`、`blocked`——信封之外的任何文本都不会被执行。指令若指向错误的 run、错误的轮次,或作业定义有误,会被退回做次数有上限的修复,而不是靠猜。循环停在 `complete` 或 `blocked`,或轮次耗尽(默认 12 轮)。
|
|
25
|
+
|
|
26
|
+
控制器决定*应该发生什么*;本地这一侧决定*是否允许发生、以何种方式发生*:通道(lane)必须启用、候选必须在任何进程启动**之前**确认可用、`argv[0]` 必须早已由你的路由配置注册。没有任何内容会经过 shell。worker 一旦启动,就不会悄悄退回到第二个候选——失败以证据的形式返回,而不是自动重试。
|
|
27
|
+
|
|
28
|
+
这是白名单(allow-list),不是沙箱。已注册的 worker 拥有与 CueLine 进程本身相同的权限;`advise` 对应 Codex 的只读沙箱、`work` 对应 `workspace-write`,但你注册了什么,就等于你授权了什么。
|
|
29
|
+
|
|
30
|
+
## 五分钟上手
|
|
31
|
+
|
|
32
|
+
你需要 Node.js 22 以上、带内置浏览器的 Codex,以及——若使用内置的默认通道——`PATH` 上有 `codex` CLI。
|
|
33
|
+
|
|
34
|
+
```bash
|
|
35
|
+
git clone https://github.com/Seraphim0916/cueline.git
|
|
36
|
+
cd cueline
|
|
37
|
+
npm ci
|
|
38
|
+
npm run build
|
|
39
|
+
./install.sh # 创建 ~/.codex/skills/cueline 与 ~/.local/bin/cueline 两个软链接
|
|
40
|
+
cueline doctor
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
`install.sh` 只创建这两个软链接,不做别的;它拒绝覆盖不属于自己的路径,而 `./install.sh --uninstall` 也只移除自己创建的链接。
|
|
44
|
+
|
|
45
|
+
然后,在 Codex 里:
|
|
46
|
+
|
|
47
|
+
1. 用 Codex 的内置浏览器打开 `https://chatgpt.com` 并登录。
|
|
48
|
+
2. 让你想让它当控制器的那个会话保持选中——该页面当前选定的模型就是控制器。CueLine 不会替你切换模型,也不会检查你的订阅套餐。
|
|
49
|
+
3. 让 Codex 用 CueLine 处理任务:*“用 CueLine:审查这个仓库,提出下一步改动,并附上证据。”*
|
|
50
|
+
4. 保留返回的 `runId`。被中断的运行要续跑,就靠它。
|
|
51
|
+
|
|
52
|
+
内置的 `cueline` skill 是从 Codex 自身的 Node runtime 驱动这个包的——内置浏览器对象就存在于那里。另外单独启动的 `node` 进程不会继承它。
|
|
53
|
+
|
|
54
|
+
## 从代码驱动
|
|
55
|
+
|
|
56
|
+
```js
|
|
57
|
+
import { createCodexIabAdapter, runCueLine } from "cueline";
|
|
58
|
+
|
|
59
|
+
const result = await runCueLine({
|
|
60
|
+
request: "Inspect the repository, delegate an implementation plan, and report the evidence.",
|
|
61
|
+
browser: createCodexIabAdapter(),
|
|
62
|
+
// 可选:conversationUrl、routingConfig / routingConfigPath、home、cwd、limits。
|
|
63
|
+
});
|
|
64
|
+
|
|
65
|
+
if (result.status === "complete") {
|
|
66
|
+
console.log(result.finalDeliveryText);
|
|
67
|
+
}
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
`startCueLineRun` 是显式的启动入口(`runCueLine` 是它的别名)。`continueCueLineRun({ runId })` 会在同一个会话中续跑被中断的运行,并复用已保存的会话链接,除非你传入新的 adapter。`loadCueLineRunState(runId)` 只读取已持久化的状态,不驱动任何东西。已经到达 `complete` 或 `blocked` 的运行会原样返回,绝不会被再次派发。
|
|
71
|
+
|
|
72
|
+
## CLI
|
|
73
|
+
|
|
74
|
+
CLI 不驱动浏览器。它只告诉你本地这一半是否健康。
|
|
75
|
+
|
|
76
|
+
```console
|
|
77
|
+
$ cueline doctor
|
|
78
|
+
CueLine 0.1.0
|
|
79
|
+
status ok
|
|
80
|
+
node 22.14.0 ok
|
|
81
|
+
config /Users/you/cueline/config/routing.default.json valid
|
|
82
|
+
home /Users/you/.cueline
|
|
83
|
+
available_lanes 1
|
|
84
|
+
|
|
85
|
+
$ cueline routing
|
|
86
|
+
default codex-default available
|
|
87
|
+
|
|
88
|
+
$ cueline jobs
|
|
89
|
+
No jobs.
|
|
90
|
+
|
|
91
|
+
$ cueline config path
|
|
92
|
+
/Users/you/cueline/config/routing.default.json
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
当 Node 版本过旧、或没有任何通道可解析时,`cueline doctor` 会以非零状态退出,因此可直接用作预检。`cueline routing` 会说明某个通道为何不可用,而不是悄悄改选别的。`cueline help` 会列出全部。
|
|
96
|
+
|
|
97
|
+
## 配置
|
|
98
|
+
|
|
99
|
+
`CUELINE_CONFIG` 用于指定路由配置文件;`CUELINE_HOME` 用于迁移本地状态(默认 `~/.cueline`)。
|
|
100
|
+
|
|
101
|
+
内置的 `default` 通道只有一个候选 `codex-default`:通过 stdin 传入任务运行 `codex exec`,`advise` 用 `read-only`、`work` 用 `workspace-write`。要注册别的 worker,复制一份 [`config/routing.default.json`](config/routing.default.json)、加入你的候选,再把 `CUELINE_CONFIG` 指过去——`argv[0]` 中的可执行文件正是通过这个动作被注册的,并且它也必须在 `PATH` 上,通道才能解析成功。
|
|
102
|
+
|
|
103
|
+
状态位于 `CUELINE_HOME` 之下:
|
|
104
|
+
|
|
105
|
+
```text
|
|
106
|
+
runs/<run-id>/events.jsonl 仅追加、具权威性
|
|
107
|
+
runs/<run-id>/snapshot.json 重放优化产物,可丢弃
|
|
108
|
+
jobs/<job-id>.json 每个作业的执行证据
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
事件日志才是记录本身:控制器这一轮在发送之前先写入、作业在进程启动之前先注册,因此“意图”与“副作用”之间若被中断,会留下痕迹。损坏的快照会被忽略并从第 1 号事件重建,而不是被信任。
|
|
112
|
+
|
|
113
|
+
## 验证
|
|
114
|
+
|
|
115
|
+
```bash
|
|
116
|
+
npm ci
|
|
117
|
+
npm run typecheck
|
|
118
|
+
npm test
|
|
119
|
+
npm run smoke:fake
|
|
120
|
+
bash test/shell/install.test.sh
|
|
121
|
+
npm pack --dry-run
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
`npm run smoke:fake` 用假的浏览器与假的 runner,离线跑完整个控制循环。它证明的是循环,而不是线上页面——只有通过内置浏览器真正完成一轮,才能证明后者。
|
|
125
|
+
|
|
126
|
+
## 0.1 的限制
|
|
127
|
+
|
|
128
|
+
仅支持纯文本。一次运行只对应一个会话。不切换模型、不支持图片、不支持文件上传,也不支持 Deep Research、Projects 或 Apps。worker 一旦启动便没有自动重试或回退——失败的 `work` 作业会在副作用被标记为不确定后回报,因为 CueLine 无法证明它执行到了哪一步。macOS 是主要的桌面目标、Linux 是 CI 目标;Windows 未经验证,且 `install.sh` 不是 Windows 安装程序。adapter 依赖 ChatGPT 网页当前的界面,因此界面变更会以明确的 `COMPOSER_MISSING`、`SEND_BUTTON_MISSING` 或响应超时暴露出来——绝不会变成编造的答案。
|
|
129
|
+
|
|
130
|
+
完整矩阵见 [compatibility](docs/compatibility.md)。
|
|
131
|
+
|
|
132
|
+
## 文档
|
|
133
|
+
|
|
134
|
+
[architecture](docs/architecture.md) · [controller protocol](docs/controller-protocol.md) · [runner contract](docs/runner-contract.md) · [state and recovery](docs/state-and-recovery.md) · [compatibility](docs/compatibility.md) · [provenance](docs/provenance.md)(均为英文)
|
|
135
|
+
|
|
136
|
+
## 开发
|
|
137
|
+
|
|
138
|
+
TypeScript、ESM,仅使用 Node 内置模块。`npm run build` 编译到 `dist/`;测试以 `node --test` 运行编译产物。CI 覆盖 Ubuntu 与 macOS 上的 Node 22 与 24。
|
|
139
|
+
|
|
140
|
+
CueLine 是独立项目,与 OpenAI 或任何其他公司均无隶属关系,也未获其背书或赞助。见 [provenance](docs/provenance.md) 与 [third-party notices](THIRD_PARTY_NOTICES.md)。
|
|
141
|
+
|
|
142
|
+
## 许可证
|
|
143
|
+
|
|
144
|
+
MIT。见 [LICENSE](LICENSE)。
|