codexteer 0.17.0 → 0.18.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/CHANGELOG.md +28 -1
- package/README.md +127 -14
- package/assets/remote-device-key.swift +94 -0
- package/bin/codexteer-update.mjs +3 -0
- package/bin/codexteer.mjs +6 -2
- package/docs/cloud.md +113 -0
- package/docs/desktop-cloud.md +36 -0
- package/docs/distribution.md +11 -19
- package/docs/orchestration.md +120 -0
- package/docs/remote-cli-validation.json +139 -0
- package/docs/remote-control.md +65 -0
- package/docs/remote-device-enrollment.md +91 -0
- package/docs/remote-observation.md +57 -0
- package/docs/remote-operations.md +89 -0
- package/docs/thread-create.md +20 -45
- package/package.json +11 -2
- package/scripts/update-desktop.applescript +51 -0
- package/src/agent-launch.mjs +27 -0
- package/src/app-server.mjs +34 -10
- package/src/checkpoint.mjs +52 -16
- package/src/cli.mjs +201 -23
- package/src/cloud-api.mjs +118 -0
- package/src/cloud-cli.mjs +319 -0
- package/src/cloud-connection.mjs +64 -0
- package/src/cloud-id.mjs +16 -0
- package/src/cloud-observe.mjs +178 -0
- package/src/cloud-send.mjs +33 -0
- package/src/cloud.mjs +172 -0
- package/src/connection.mjs +12 -1
- package/src/creation-verification.mjs +30 -10
- package/src/desktop-cloud-api.mjs +119 -0
- package/src/desktop-cloud-id.mjs +18 -0
- package/src/desktop-cloud-project.mjs +148 -0
- package/src/desktop-cloud.mjs +98 -0
- package/src/desktop.mjs +3 -1
- package/src/directive.mjs +5 -2
- package/src/distribution.mjs +2 -2
- package/src/evidence.mjs +3 -0
- package/src/findings.mjs +7 -7
- package/src/help.mjs +140 -28
- package/src/journal.mjs +37 -9
- package/src/launcher.mjs +16 -9
- package/src/monitor.mjs +18 -6
- package/src/native-command.mjs +10 -2
- package/src/native-rpc.mjs +15 -2
- package/src/observe.mjs +21 -7
- package/src/orchestrate-prompt.mjs +96 -0
- package/src/orchestrate.mjs +29 -0
- package/src/paged-read.mjs +7 -1
- package/src/projects.mjs +27 -2
- package/src/prompt-command.mjs +25 -0
- package/src/prompt.mjs +25 -8
- package/src/remote-client-info.mjs +16 -0
- package/src/remote-control-auth.mjs +109 -0
- package/src/remote-control-socket.mjs +137 -0
- package/src/remote-control.mjs +134 -0
- package/src/remote-device-key.mjs +41 -0
- package/src/remote-device-login.mjs +76 -0
- package/src/remote-device-protocol.mjs +72 -0
- package/src/remote-device-store.mjs +71 -0
- package/src/remote-device-worker.mjs +48 -0
- package/src/remote-device.mjs +202 -0
- package/src/remote-io.mjs +163 -0
- package/src/remote-key-access.mjs +76 -0
- package/src/remote-key-worker.mjs +38 -0
- package/src/remote-keychain.mjs +72 -0
- package/src/remote-management.mjs +234 -0
- package/src/remote.mjs +132 -0
- package/src/resource.mjs +8 -6
- package/src/runner.mjs +6 -1
- package/src/standalone-create.mjs +4 -3
- package/src/store.mjs +6 -3
- package/src/supervise.mjs +25 -53
- package/src/supervision.mjs +41 -19
- package/src/target.mjs +25 -0
- package/src/task-id.mjs +23 -0
- package/src/thread-create.mjs +4 -3
- package/src/thread-id.mjs +21 -6
- package/src/thread-verify.mjs +108 -0
- package/src/turn-repair.mjs +228 -0
- package/src/update.mjs +158 -0
- package/docs/thread-create-native-investigation.md +0 -136
package/CHANGELOG.md
CHANGED
|
@@ -1,6 +1,33 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
-
##
|
|
3
|
+
## Unreleased
|
|
4
|
+
|
|
5
|
+
- `thread repair <THREAD>`で古いターンの終了記録欠落を検出します。明示的な`--apply`はCodexの完全終了・検証済みバージョンを必須とし、バックアップ後に対象IDの中断記録だけを追記・照合します。既存の会話やDBは書き換えず、最新の未完了ターンは修復しません。
|
|
6
|
+
- macOS向けに`desktop update`と`desktop update-status`を追加しました。独立したworkerが公式更新UI(英語・日本語)を操作し、新ビルドと再起動を確認してから共有wrapperを再適用・検証します。外部NodeとターミナルのAccessibility・Automation権限が必要です。
|
|
7
|
+
|
|
8
|
+
- native/control/pairedのリモート経路、専用端末鍵の登録・ペアリング、ホストを保持する観測・監督に対応しました。
|
|
9
|
+
- リモートのプロジェクト・タスク一覧、指定ターンへの送信、Desktopによる作成・new-turn、checkpoint/resource実行とorchestrationを追加しました。
|
|
10
|
+
- 配送・実行結果が不明な場合は自動再送せず、pause/stopと指摘の重複防止を維持します。full-accessのthread-shellは明示選択が必要です。
|
|
11
|
+
- 準備後の監督付きシェル送信をpause/stopと排他し、RPC応答後に制御ロックを解放します。help・文書も実装に揃えました。
|
|
12
|
+
- リモート操作の手順と検証の集計を追加しました。リモートのUI送信・ホストのプロセス管理・履歴修復は未対応です。
|
|
13
|
+
- POSIXパスの大文字小文字を保持し、CLIの宛先はオプション値ではなく位置引数から選択します。監督の制御は登録時のtransportと一致する場合だけ受け付けます。
|
|
14
|
+
- リモート作成の再照合失敗時は古い認定フラグを除去してreceiptへ記録します。実行RPCの内部エラーでは実行済みの可能性を保持し、resource leaseを解放しません。
|
|
15
|
+
|
|
16
|
+
## 0.18.0 — 未公開
|
|
17
|
+
|
|
18
|
+
- Cloud監督の登録前診断と、初回配送の受付不明を共通履歴から照合・回復できるよう修正しました。本文・client IDが一致する保存証拠だけを採用し、自動再送は行いません。
|
|
19
|
+
|
|
20
|
+
- Desktop Cloudの所属確認をdoctorへ追加し、プロジェクト一覧と環境一覧を分離しました。署名付きのthread assignは実環境・nonce・署名・保存結果を照合します。そのDesktop実行環境への結合が必要で、通常のCloud環境の拒否を成功扱いしたり別環境へ置き換えたりしません。作成後のタイトル設定・初回配送失敗時にも通常表示へ作成済みIDと復旧情報を残します。
|
|
21
|
+
|
|
22
|
+
- Desktop Cloudの環境構成一覧・新規作成・継続送信・共通監視を追加しました。初回送信にも選択済み環境と遅延起動指定を保持します。環境選択とDesktopプロジェクト所属を区別し、所属登録が確認できない`--project`作成は事前拒否します。受付不明の自動再送は行いません。
|
|
23
|
+
|
|
24
|
+
- Cloudの重複拒否で前回の試行IDを今回の配送履歴へ結び付けないよう修正しました。回復用IDを分離し、history checkは今回の本文・親ターンも照合して、拒否した指示の誤有効化を防ぎます。未公開の作成用--env別名も削除し、環境指定は--projectに統一しました。新規作成の本文がCloud ID/URLで始まっても、それを宛先と誤判定しません。
|
|
25
|
+
|
|
26
|
+
- 共通Cloud観測で公開commentaryの途中経過を保持し、途中経過だけの更新でもMonitorへ通知します。reasoning等の非公開内容は除外し、`--backend app-server`を宛先より前に置く場合のCloud振り分けも修正しました。
|
|
27
|
+
|
|
28
|
+
- Cloudタスクも共通の`supervise`・`read/watch`・`send`・`history/instructions/findings`で扱えます。監督の登録・pause/resume/stop・保存済みCLI・Monitorのdigestと復帰待ちを既存基盤へ接続し、実行中の指定ターンの中断と同一タスク内での継続、配送照合を追加しました。旧Desktop CLIとの記録互換性を保つCloud専用監督名前空間を使います。
|
|
29
|
+
|
|
30
|
+
- Cloud環境・タスクの一覧と新規作成は`--connection cloud projects list`・`threads list`・`thread create`で扱います。作成試行は`thread receipt`、配送照合・予約回復は`history show/check --attempt`、試行を選ぶ差分取得は`diff --attempt`に統一しました。未公開の重複サブコマンドと専用のカーソル・watch処理を削除し、結果不明時の自動再送は行いません。公式CLIの診断は私有一時領域で処理し、ローカル差分を暗黙に送信・適用しません。
|
|
4
31
|
|
|
5
32
|
- `projects list`と`thread create --project`を追加しました。プロジェクト名と初回指示だけで作成でき、既存チャット・`CODEX_THREAD_ID`・中継AIは不要です。App Serverで作成・Desktop購読・初回配送を行い、新規チャット自身の実在IDからnative RPCで所属登録し、全フォルダと初回指示を照合します。明示的な`--context-thread`は任意で、従来のnative直接作成を使います。配送不明・部分成功を保持し、自動再作成・再送を行いません。
|
|
6
33
|
|
package/README.md
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
# codexteer
|
|
2
2
|
|
|
3
|
-
登録済みプロジェクトへの初回指示付きチャット作成は、`projects list`と`thread create --project`で行えます。プロジェクト名と指示だけで使え、既存チャットや中継AIは不要です。Desktopのnative RPC
|
|
3
|
+
登録済みプロジェクトへの初回指示付きチャット作成は、`projects list`と`thread create --project`で行えます。プロジェクト名と指示だけで使え、既存チャットや中継AIは不要です。Desktopのnative RPCで所属を登録し、複数フォルダや重複フォルダを持つ「サンプル」も、所属・全フォルダ・初回指示を照合します。作成済み・初回受付済みで照合だけ失敗した場合は、`thread verify <ATTEMPT-ID> --json`で再作成・再送せずに再照合できます。[使い方と実機検証](docs/thread-create.md)
|
|
4
4
|
|
|
5
5
|
```bash
|
|
6
6
|
codexteer projects list --json
|
|
7
|
-
codexteer thread create --project '
|
|
7
|
+
codexteer thread create --project 'サンプル' \
|
|
8
8
|
--title '関連リポジトリの調査' '関連リポジトリを読み、結果を報告してください' --json
|
|
9
9
|
```
|
|
10
10
|
|
|
@@ -12,13 +12,13 @@ codexteer thread create --project '競馬' \
|
|
|
12
12
|
|
|
13
13
|
## 導入
|
|
14
14
|
|
|
15
|
-
macOS、Node.js 20以降とnpm、`/Applications/ChatGPT.app`にインストールされたCodex Desktopが必要です。監督役に使うClaude CodeまたはCodex CLIを、PATH上の`claude`または`codex
|
|
15
|
+
Desktop操作にはmacOS、Node.js 20以降とnpm、`/Applications/ChatGPT.app`にインストールされたCodex Desktopが必要です。監督役に使うClaude CodeまたはCodex CLIを、PATH上の`claude`または`codex`で起動できる状態にします。クラウド操作はDesktopが不要で、上記の公式Codex CLIを別途使用します。
|
|
16
16
|
|
|
17
17
|
### npxで使う
|
|
18
18
|
|
|
19
19
|
リポジトリのcloneやグローバルインストールなしで実行できます。npmパッケージ名とCLI名は`codexteer`です。
|
|
20
20
|
|
|
21
|
-
npm公開済みの最新版は`0.
|
|
21
|
+
npm公開済みの最新版は`0.17.0`です。このブランチは、リモート操作・Cloud対応などをまとめたマイナー更新`0.18.0`を準備します。公開前に使う場合は「ソースから導入する」の手順で導入してください。変更点は[CHANGELOG](CHANGELOG.md)を参照してください。
|
|
22
22
|
|
|
23
23
|
```bash
|
|
24
24
|
npx -y codexteer --version
|
|
@@ -36,14 +36,22 @@ npx -y codexteer doctor --json
|
|
|
36
36
|
<details>
|
|
37
37
|
<summary>特定のバージョンで実行する場合(任意)</summary>
|
|
38
38
|
|
|
39
|
-
不具合の切り分けや、同じ版で監督を開始し直したい場合は、パッケージ名に`@バージョン`を付けられます。`0.
|
|
39
|
+
不具合の切り分けや、同じ版で監督を開始し直したい場合は、パッケージ名に`@バージョン`を付けられます。`0.18.0`の公開後にその版を選ぶ場合は、次のように指定します。
|
|
40
40
|
|
|
41
41
|
```bash
|
|
42
|
-
npx -y codexteer@0.
|
|
42
|
+
npx -y codexteer@0.18.0 supervise <thread-id>
|
|
43
43
|
```
|
|
44
44
|
|
|
45
45
|
</details>
|
|
46
46
|
|
|
47
|
+
### DesktopのCloud環境を使う
|
|
48
|
+
|
|
49
|
+
DesktopのCloud環境構成は、`codexteer --connection desktop-cloud environments list --json`で取得します。新規作成は`thread create --environment <ID_OR_EXACT_NAME>`、継続・監視・監督は`durable_`付きIDまたは`hostId=durable`付きリンクで共通コマンドを使います。所属情報と登録APIの可否は`doctor --thread ... --project ...`で区別します。公式の署名付き`thread assign`は対象がそのDesktopの実行環境を使う場合に限り利用でき、通常のCloud環境では`--project`付き作成を現在も事前拒否します。[操作・確認済み範囲と制限](docs/desktop-cloud.md)
|
|
50
|
+
|
|
51
|
+
### Codex Cloudを使う
|
|
52
|
+
|
|
53
|
+
CloudタスクのID・公式リンクで、同じ`supervise`・`read/watch`・`send`・`history/instructions/findings`を使えます。監督の`pause/resume/stop`や保存済みCLIも共通です。接続先をまだ選んでいない一覧と作成は`--connection cloud projects list`・`threads list`・`thread create --project <ENV_ID>`を使います。実行中のCloud送信は同じタスクの元ターンを中断して後続ターンを開始する方式です。[操作とサービス上の違い](docs/cloud.md)
|
|
54
|
+
|
|
47
55
|
### ソースから導入する
|
|
48
56
|
|
|
49
57
|
こちらの方法ではGitとmakeも必要です。
|
|
@@ -90,6 +98,32 @@ Codex同梱CLI 0.155系列の保護ソケット形式にも対応します。従
|
|
|
90
98
|
以下の`<thread-id>`は対象のタスクIDに置き換えてください。`codex://threads/...`形式のタスクURLも使えます。
|
|
91
99
|
コマンド一覧では`codexteer`と略記します。npxで手動実行する場合は、その部分を`npx -y codexteer`に置き換えてください。
|
|
92
100
|
|
|
101
|
+
### プロジェクトと目標から担当編成と進行を任せる
|
|
102
|
+
|
|
103
|
+
既存のスレッドを指定せず、目的に合わせてCodexの担当を作成・監督する対話CLIを起動できます。`prompt`を付けると本文だけを生成します。
|
|
104
|
+
|
|
105
|
+
```bash
|
|
106
|
+
codexteer orchestrate --project 'Example Project' '達成したい目標' --use-path-cli
|
|
107
|
+
codexteer orchestrate --project 'Example Project' '達成したい目標' --agent codex
|
|
108
|
+
codexteer orchestrate --project 'My Project' '達成したい目標' --agent claude -- --model <MODEL>
|
|
109
|
+
|
|
110
|
+
codexteer orchestrate prompt --project 'Example Project' \
|
|
111
|
+
'モーション図鑑で現状の動作を確認し、変更を指示できる状態にする'
|
|
112
|
+
|
|
113
|
+
codexteer orchestrate prompt --project 'My Project' '達成したい目標' --use-path-cli --json
|
|
114
|
+
codexteer orchestrate prompt --project 'My Project' '達成したい目標' --agent codex
|
|
115
|
+
codexteer orchestrate prompt --project 'My Project' - < goal.txt
|
|
116
|
+
codexteer help orchestrate prompt
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
直接起動は`supervise`と同じく、既定で`claude`、`--agent codex`ならCodex CLIを起動します。入出力・cwd・環境と終了コードを引き継ぎ、最初の`--`以降はエージェント引数です。`--use-path-cli`は本文内のcodexteerコマンドをPATH方式にします。`prompt`なしの`--json`は非対応です。
|
|
120
|
+
|
|
121
|
+
生成専用の場合は本文を同じPCのオーケストレーターへ依頼として渡します。役割はモデルに依存せず、Codex自身も担当できます。オーケストレーターは目的・作業分担・共有資源・検収と統合を担当し、Codex担当は調査・設計判断・実装・検証に加え、依頼の前提への異論や改善案を出します。開始時と重要な節目に、高度(作業の先の成果)・深さ(一次資料と専門的手法・外部検証)・範囲(隣接分野の有効な技法)から目的と計画を再評価します。
|
|
122
|
+
|
|
123
|
+
`orchestrate prompt`では`--agent`は子の監督IDと送信元のCLI識別を明示する任意指定です。省略時は特定の実行役に固定せず、受け取ったオーケストレーターが自分のCLIを選びます。この生成専用モードではエージェントを起動しません。
|
|
124
|
+
|
|
125
|
+
生成時はDesktopへ接続せず、チャット作成や監視を開始しません。既定は保存済みCLIを使い、`--use-path-cli`は実行環境のPATHとCODEX_HOMEを使います。作成後は各子に監督IDを付けて登録・観測し、同じ目的の未完了作業の継続まで追います。[使い方・委任と制御の範囲](docs/orchestration.md)も参照してください。
|
|
126
|
+
|
|
93
127
|
### Claude Code・Codex CLIに監視とステアリングを任せる
|
|
94
128
|
|
|
95
129
|
上の導入を済ませ、監視したいCodexタスクのIDまたはURLをコピーします。別のターミナルの対象プロジェクトのディレクトリから、導入方法に合う方を実行してください。
|
|
@@ -174,6 +208,28 @@ codexteer supervise prompt <thread-id> "セキュリティの問題だけを私
|
|
|
174
208
|
|
|
175
209
|
IDのコピーを省く場合は、Claudeに`codexteer threads list --desktop-only --json`で候補を表示してもらい、対象を選ぶこともできます。同じプロジェクトに複数のタスクがある場合、Claudeの起動場所だけでは監視対象を特定できません。
|
|
176
210
|
|
|
211
|
+
### 古いターンの実行中状態が残る場合
|
|
212
|
+
|
|
213
|
+
送信だけが止まる場合は、修正版の通常の`send`を使ってください。下記のオフライン修復は送信の前提条件ではありません。
|
|
214
|
+
|
|
215
|
+
`supervise stop`は監督の停止であり、Codexのターン履歴を修復しません。古いターンの終了記録が欠けている場合は、次のコマンドで検出できます。既定は読み取り専用です。
|
|
216
|
+
|
|
217
|
+
```bash
|
|
218
|
+
codexteer thread repair <thread-id> --json
|
|
219
|
+
```
|
|
220
|
+
|
|
221
|
+
後続ターンが始まっているのに終了記録がない古いターンを`candidates`へ表示します。APIが停止中に`interrupted`を返していても、保存済みの状態が修復されたとは限らないため、ローカル履歴を検査します。最新の未完了ターンや未終了の入れ子ターンは自動修復しません。
|
|
222
|
+
|
|
223
|
+
適用する場合は、作業とバックグラウンド処理を適切に停止し、**Codex/ChatGPTと全Codex CLI・app-serverを完全終了した後、外部ターミナル**で実行してください。完了までCodexを起動しないでください。
|
|
224
|
+
|
|
225
|
+
```bash
|
|
226
|
+
codexteer thread repair <thread-id> --apply --json
|
|
227
|
+
```
|
|
228
|
+
|
|
229
|
+
履歴全体を所有者専用のバックアップへ保存・照合してから、対象IDの中断記録だけを末尾へ追記します。既存の会話・ordinal・DBの直接書き換え、プロセス終了、ターン再開、メッセージ送信は行いません。実際の停止時刻は不明なので、完了日時や所要時間を推定しません。履歴が変わった場合や、稼働プロセスを確認できない場合は拒否します。
|
|
230
|
+
|
|
231
|
+
現在の適用対象は、隔離したCodexで再読込みを検証したCLI **0.162.0-alpha.17.2 / 0.164.0-alpha.11.1**、macOS、連続ordinalを持つpaginated履歴です。別バージョンは検証なしに適用しません。バックアップ分の空き容量を確保してください。`repaired`は保存履歴の追記とSHA256照合が成功した状態で、Codexの画面確認とは区別します。再起動後は状態を再確認し、read/watchのcursorを新しく取得してください。バックアップと修復記録は`CODEX_HOME/codex-steer/turn-repairs/`に残ります。失敗時は`history_changed`と`backup_path`/`receipt_path`を確認し、原本への上書きや再実行を盲目的に行わないでください。
|
|
232
|
+
|
|
177
233
|
### 監督状態の確認・一時停止・停止
|
|
178
234
|
|
|
179
235
|
ユーザーの端末から、生成元と同じ`CODEX_HOME`で実行します。
|
|
@@ -228,6 +284,39 @@ codexteer findings dismiss <thread-id> <finding-id> --reason "既存の実装が
|
|
|
228
284
|
|
|
229
285
|
評価は`useful`(有益)・`unnecessary`(不要)・`incorrect`(誤り)、未評価は`unrated`です。`stats`は現在のrevisionを1件として未送信候補も含め、評価済み件数と未評価件数を分けます。`useful_fraction`の母数は評価済み件数で、0件なら`null`です。介入の因果効果を証明する数値ではありません。詳細は`help findings`を参照してください。
|
|
230
286
|
|
|
287
|
+
### リモートプロジェクトとチャットを観測する
|
|
288
|
+
|
|
289
|
+
`hostId`付きリンクで、Desktopが接続中のリモートチャットを読み取り・監視・観測専用の監督に使えます。
|
|
290
|
+
|
|
291
|
+
```bash
|
|
292
|
+
codexteer projects list --remote --json
|
|
293
|
+
codexteer projects list --all --json
|
|
294
|
+
codexteer read 'codex://threads/<UUID>?hostId=remote-control%3Aenv_example' --json
|
|
295
|
+
codexteer supervise 'codex://threads/<UUID>?hostId=remote-control%3Aenv_example' --agent codex
|
|
296
|
+
```
|
|
297
|
+
|
|
298
|
+
既定native経路を通常の端末で使う場合は`--context-thread <LOCAL-CALLER-UUID>`を指定します。Codex内では実在する呼出し元の`CODEX_THREAD_ID`を使えます。プロジェクト一覧はDesktopの登録情報で、接続状態は`unverified`です。既定native経路のリモート監督は観測専用です。`--remote-transport control`を明示すると、既存activeターンへの指定ターン送信を伴う監督を生成・起動できます。controlは既存端末鍵へのアクセスが必要で、利用できない環境では接続前に停止します。利用環境で互換性を確認してください。[指定ターン送信の実装と検証範囲](docs/remote-control.md)も参照してください。[前提・制約・記録と実機確認](docs/remote-observation.md)
|
|
299
|
+
|
|
300
|
+
controlは接続前に公開鍵を照合し、失敗すれば`REMOTE_DEVICE_KEY_UNAVAILABLE`で停止します。`doctor`の`remote_control_auth`で、鍵取得の失敗段階・Desktop本体とNodeの公開entitlement差・同梱schemaの操作一覧を確認できます。鍵を利用できない環境では停止します。[認証の前提と制約](docs/remote-control.md)を参照してください。
|
|
301
|
+
|
|
302
|
+
pairedではCLI単体からリモートの新規チャット作成、タスク一覧・ID取得、new-turn、checkpoint/resource、orchestrateを使えます。正式project IDとDesktop登録IDを出し分け、作成/new-turn/openには実在ローカルcallerによるDesktop公式APIを使います。通常の端末では`--context-thread`を指定してください。Windowsで使える明示的なthread-shell実行とMac固有操作の制限を含め、[リモートCLIの対応範囲と手順](docs/remote-operations.md)を参照してください。
|
|
303
|
+
|
|
304
|
+
専用鍵を使う場合は、利用者がセットアップを許可して`paired`経路を明示します。登録・ペアリングは、チャットの作成・送信とは別の操作です。対象ホストとチャットを照合し、許可された範囲だけで実行してください。動作確認には専用のテスト用チャットを使い、他のタスクに試験送信しないでください。代理承認やDesktop画面への表示は受付結果と区別します。
|
|
305
|
+
|
|
306
|
+
```sh
|
|
307
|
+
codexteer remote prepare --key-provider keychain --json
|
|
308
|
+
codexteer remote enroll --json
|
|
309
|
+
# 対象ホストのDesktop設定 → Connections → Control this PC → Addで取得したコードを入力
|
|
310
|
+
codexteer --host 'remote-control:env_example' remote pair --code-stdin --json
|
|
311
|
+
codexteer remote verify --json
|
|
312
|
+
codexteer remote identity --json
|
|
313
|
+
codexteer --remote-transport paired doctor --thread '<hostId付きリンク>' --json
|
|
314
|
+
```
|
|
315
|
+
|
|
316
|
+
keychain方式はXcode command-line toolsが必要で、codexteer自身のhelperとOSの非抽出P-256鍵を使います。既存Desktop鍵やその権限は変更しません。コードのTTY入力は非表示で、登録やペアリングの自動再試行はしません。[専用鍵の公式登録・ペアリング手順](docs/remote-device-enrollment.md)と`help remote-device`を参照してください。
|
|
317
|
+
|
|
318
|
+
端末情報にはcodexteerの製品名・実OS・CPUを含めます。`remote status`の識別名は`codexteer_mac_os_arm64`など、`remote identity`の`server_display_name`はサーバーに保存された表示名です。任意のサーバー表示名の更新には対応していないため、`name_matches: false`として区別します。
|
|
319
|
+
|
|
231
320
|
### 通常起動したDesktopを再起動せずに観測する
|
|
232
321
|
|
|
233
322
|
Desktopが共有ローカルdaemonを使っていて、`CODEX_HOME/app-server-control/app-server-control.sock`が存在する環境では、観測専用の直接接続を選べます。
|
|
@@ -283,7 +372,7 @@ codexteer watch <thread-id> --until idle --timeout-ms 60000 --json
|
|
|
283
372
|
変化するたびに1行のJSONを受け取るには、次のコマンドを使います。Ctrl-Cで停止します。
|
|
284
373
|
|
|
285
374
|
```bash
|
|
286
|
-
codexteer watch <thread-id> --stream --json
|
|
375
|
+
codexteer watch <thread-id> --stream --notify all --json
|
|
287
376
|
```
|
|
288
377
|
|
|
289
378
|
### 詳細な使い方
|
|
@@ -367,14 +456,14 @@ codexteer help supervise prompt
|
|
|
367
456
|
"ok": true,
|
|
368
457
|
"command": "supervise.prompt",
|
|
369
458
|
"data": {
|
|
370
|
-
"thread_id": "
|
|
459
|
+
"thread_id": "aaaaaaaa-aaaa-4aaa-8aaa-000000000001",
|
|
371
460
|
"prompt": "対象IDと保存したCLIの実行コマンドを含む監督プロンプト本文…",
|
|
372
461
|
"cli_mode": "saved",
|
|
373
462
|
"deployment": {
|
|
374
463
|
"codex_home": "/Users/me/.codex",
|
|
375
|
-
"directory": "/Users/me/.codex/codex-steer/runtimes/0.
|
|
376
|
-
"wrapper_path": "/Users/me/.codex/codex-steer/runtimes/0.
|
|
377
|
-
"version": "0.
|
|
464
|
+
"directory": "/Users/me/.codex/codex-steer/runtimes/0.18.0-<sha256>",
|
|
465
|
+
"wrapper_path": "/Users/me/.codex/codex-steer/runtimes/0.18.0-<sha256>/bin/codexteer-wrapper.mjs",
|
|
466
|
+
"version": "0.18.0",
|
|
378
467
|
"sha256": "<sha256>",
|
|
379
468
|
"reused": false
|
|
380
469
|
},
|
|
@@ -423,13 +512,19 @@ codexteer open <thread-id>
|
|
|
423
512
|
`ready`は接続条件と今回指定した検証の結果です。新規ターンだけが使えなくても、観測に成功すれば`ready: true`になります。操作別の仕様対応は`runtime_compatibility.operations`、新規ターン用ソケットの状態は`desktop_subscription`を確認してください。`supported`は仕様上の対応、`verified`は実際に行った観測の検証で、履歴全体、送信、画面表示、承認往復は保証しません。未検証の機能は`unverified_features`に明示します。例えば、従来の履歴形式を読み取った場合の結果は次の形です(主要項目のみ)。
|
|
424
513
|
|
|
425
514
|
```json
|
|
426
|
-
{"ready":true,"connection":{"status":"connected"},"compatibility":{"status":"verified","scope":"target-observation","thread_id":"
|
|
515
|
+
{"ready":true,"connection":{"status":"connected"},"compatibility":{"status":"verified","scope":"target-observation","thread_id":"aaaaaaaa-aaaa-4aaa-8aaa-000000000001","api_checks":{"initialize":"verified","thread/loaded/list":"verified","thread/read":"verified","thread/turns/list":"unverified","thread/items/list":"unverified"},"unverified_features":["steering","desktop_ui","approval_roundtrip"]},"failure":null}
|
|
427
516
|
```
|
|
428
517
|
|
|
429
518
|
`threads list`は`--desktop-only`を外すとDesktop以外のローカルタスクも含みます。`--limit`は1〜500件、既定は20件です。タスクや各種記録の保存先は`CODEX_HOME`に従い、未指定時は`~/.codex`を使います。
|
|
430
519
|
|
|
431
520
|
#### メッセージ送信・ステアリング
|
|
432
521
|
|
|
522
|
+
古いターンが実行中のまま履歴に残っていても、ページ形式の履歴では通常の`send`を使えます。チャットが稼働中で、最新ターンも進行中の場合だけそのIDを指定し、サーバー側で現在の実行中IDとの一致を確認します。不一致・受付不明時に別のターンへ自動再送しません。この対応にCodexの終了や保存履歴の修復は不要です。Codex本体の表示や保存履歴の修復とは別で、観測上の`active_turn_id`は複数候補なら`null`のままです。
|
|
523
|
+
|
|
524
|
+
`--based-on`は残留状態があっても最新ターンの変更を検出します。古い全履歴cursorで最新ターンを特定できない場合は、改めて`read`して取得したcursorを使ってください。修正版CLIは既存の共有wrapperで利用できます。保存済みCLIを使う監督には、監督の起動・プロンプト生成をやり直して反映します。`--use-path-cli`では次のコマンド実行から反映されます。
|
|
525
|
+
|
|
526
|
+
Codexが古いターンの表示を`interrupted`から`inProgress`へ戻すと、既存の`watch`や`--since`が`STALE_CURSOR`になる場合があります。その場合は`read`を`--since`なしで実行し、必要な履歴を確認してから新しいcursorで監視を再開してください。
|
|
527
|
+
|
|
433
528
|
```bash
|
|
434
529
|
# 実行中タスクへ追加入力
|
|
435
530
|
codexteer send <thread-id> "今の要件に必要な変更へ絞ってください" --json
|
|
@@ -499,7 +594,7 @@ codexteer watch <thread-id> --until idle --timeout-ms 60000 --json
|
|
|
499
594
|
codexteer watch <thread-id> --until attention --json
|
|
500
595
|
|
|
501
596
|
# 変化するたびにJSONを1行ずつ出力し続ける
|
|
502
|
-
codexteer watch <thread-id> --stream --since <cursor> --include-output --json
|
|
597
|
+
codexteer watch <thread-id> --stream --notify all --since <cursor> --include-output --json
|
|
503
598
|
```
|
|
504
599
|
|
|
505
600
|
| オプション | 対象・用途 |
|
|
@@ -539,7 +634,7 @@ codexteer watch <thread-id> --stream --since <cursor> --include-output --json
|
|
|
539
634
|
接続状態の通知例です。`<cursor>`は実際の値に置き換わります。
|
|
540
635
|
|
|
541
636
|
```json
|
|
542
|
-
{"ok":true,"command":"watch","data":{"type":"connection","thread_id":"
|
|
637
|
+
{"ok":true,"command":"watch","data":{"type":"connection","thread_id":"aaaaaaaa-aaaa-4aaa-8aaa-000000000001","state":"reconnecting","resume_cursor":"<cursor>","last_observed_at":"2026-09-12T10:00:00.000Z","observed_at":"2026-09-12T10:00:08.000Z","reconnect_attempts":0,"cause_code":"CONNECTION_FAILED","retry_timeout_ms":60000}}
|
|
543
638
|
```
|
|
544
639
|
|
|
545
640
|
監視の接続・読み取りで停止を伴うエラーは`ok:false`、`data.type:connection`、`data.state:needs_review|failed`、`error.code`と理由を返し、終了コード1です。復帰待ちの上限は`WATCH_RECONNECT_TIMEOUT`、無効cursorは`STALE_CURSOR`です。Ctrl-Cは接続・初期化・復帰待ちの途中でも監視だけを停止します。
|
|
@@ -650,3 +745,21 @@ codexteer debug-ui <thread-id> --wait-ms 1500
|
|
|
650
745
|
```
|
|
651
746
|
|
|
652
747
|
UI方式は画面フォーカスに依存し、サイドチャットが開いている場合の宛先保証はありません。結果の`submitted_unverified`はキー入力の実行を表し、対象タスクへの配送確認ではありません。
|
|
748
|
+
|
|
749
|
+
### Desktopを更新してwrapperを再適用する(macOS)
|
|
750
|
+
|
|
751
|
+
作業を終えてから、アプリ外のNodeを使うターミナルで実行します。
|
|
752
|
+
|
|
753
|
+
```bash
|
|
754
|
+
codexteer desktop update --dry-run --json
|
|
755
|
+
codexteer desktop update
|
|
756
|
+
codexteer desktop update-status --json
|
|
757
|
+
```
|
|
758
|
+
|
|
759
|
+
`update`は独立したバックグラウンドプロセスを起動し、Codexアプリの「更新を確認…」メニューと既知の更新ボタン名を照合して操作します。アプリ内の全ウィンドウを調べるため、Sparkle固有のウィンドウ識別を保証するものではありません。更新以外のダイアログは閉じてから実行してください。英語・日本語のUIに対応し、ターミナルへのAccessibility・Automation権限が必要です。OSの権限ダイアログには自動応答しません。Codexは起動済みである必要があります。アプリ同梱Nodeと`--supervisor`付きの呼出しでは実行できません。
|
|
760
|
+
|
|
761
|
+
更新によるビルド番号の変更と新しいアプリプロセスを確認してから、Codexを正常終了し、保存済みcodexteerの`desktop start`でwrapper付きで再起動します。公式更新とwrapper再適用で複数回再起動する場合があります。進行中のタスクの自動再開は行いません。
|
|
762
|
+
|
|
763
|
+
起動受付は更新成功ではありません。`update-status`の`phase: complete`と`wrapper_verified: true`が完了条件です。更新不要の場合は`up_to_date`で終了し、再起動しません。状態は`CODEX_HOME/codex-steer/desktop-update/status.json`に保存されます。既定の更新待機時間は10分で、`--timeout-ms`で10秒〜1時間に変更できます。正常終了の待機には別途最大30秒、wrapper起動と診断にも時間がかかります。
|
|
764
|
+
|
|
765
|
+
既知のラベルに一致しない画面や、更新失敗・再起動未完了では停止またはタイムアウトします。アプリを強制終了したり別の更新元へ切り替えたりはしません。`failed`の場合は記録された理由と公式更新画面を確認してください。更新が完了してから正常終了し、`codexteer desktop start`と`codexteer doctor --json`で復旧できます。workerが異常終了してlockが残った場合は自動で奪いません。workerと更新処理が停止したことを確認してからエラーに表示された空のlockディレクトリを手動で除去します。
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
import Foundation
|
|
2
|
+
import Security
|
|
3
|
+
|
|
4
|
+
// A codexteer-owned, nonextractable login-Keychain key. This helper has no
|
|
5
|
+
// network access code and never requests a private key's external representation.
|
|
6
|
+
enum Failure: Error { case invalid }
|
|
7
|
+
var stage = "input"
|
|
8
|
+
func fail(_ status: OSStatus) throws -> Never { throw NSError(domain: NSOSStatusErrorDomain, code: Int(status)) }
|
|
9
|
+
func query(_ id: String) throws -> [String: Any] {
|
|
10
|
+
guard id.range(of: "^codexteer_[a-f0-9-]{36}$", options: .regularExpression) != nil else { throw Failure.invalid }
|
|
11
|
+
return [kSecClass as String: kSecClassKey, kSecAttrKeyClass as String: kSecAttrKeyClassPrivate,
|
|
12
|
+
kSecAttrKeyType as String: kSecAttrKeyTypeECSECPrimeRandom,
|
|
13
|
+
kSecAttrApplicationTag as String: Data(("dev.codexteer.device-key." + id).utf8),
|
|
14
|
+
kSecUseDataProtectionKeychain as String: false]
|
|
15
|
+
}
|
|
16
|
+
func metadata(_ key: SecKey, _ id: String) throws -> [String: Any] {
|
|
17
|
+
guard let attrs = SecKeyCopyAttributes(key) as? [String: Any],
|
|
18
|
+
(attrs[kSecAttrIsExtractable as String] as? NSNumber)?.boolValue == false,
|
|
19
|
+
(attrs[kSecAttrKeySizeInBits as String] as? NSNumber)?.intValue == 256,
|
|
20
|
+
let pub = SecKeyCopyPublicKey(key) else { throw Failure.invalid }
|
|
21
|
+
var error: Unmanaged<CFError>?
|
|
22
|
+
guard let bytes = SecKeyCopyExternalRepresentation(pub, &error) as Data?, bytes.count == 65, bytes.first == 4 else { throw Failure.invalid }
|
|
23
|
+
let header: [UInt8] = [0x30,0x59,0x30,0x13,0x06,0x07,0x2a,0x86,0x48,0xce,0x3d,0x02,0x01,0x06,0x08,0x2a,0x86,0x48,0xce,0x3d,0x03,0x01,0x07,0x03,0x42,0x00]
|
|
24
|
+
return ["keyId": id, "algorithm": "ecdsa_p256_sha256", "protectionClass": "os_protected_nonextractable",
|
|
25
|
+
"publicKeySpkiDerBase64": (Data(header) + bytes).base64EncodedString()]
|
|
26
|
+
}
|
|
27
|
+
func supportedPayload(_ bytes: Data) throws {
|
|
28
|
+
guard let outer = try JSONSerialization.jsonObject(with: bytes) as? [String: Any], outer.count == 2,
|
|
29
|
+
outer["domain"] as? String == "codex-device-key-sign-payload/v1", let p = outer["payload"] as? [String: Any],
|
|
30
|
+
p["targetOrigin"] as? String == "https://chatgpt.com",
|
|
31
|
+
let account = p["accountUserId"] as? String, !account.isEmpty,
|
|
32
|
+
let client = p["clientId"] as? String, !client.isEmpty,
|
|
33
|
+
let nonce = p["nonce"] as? String, nonce.range(of: "^[A-Za-z0-9_-]{43,512}$", options: .regularExpression) != nil else { throw Failure.invalid }
|
|
34
|
+
switch p["type"] as? String {
|
|
35
|
+
case "remoteControlClientConnection":
|
|
36
|
+
guard p.count == 11, p["targetPath"] as? String == "/backend-api/codex/remote/control/client",
|
|
37
|
+
p["audience"] as? String == "remote_control_client_websocket",
|
|
38
|
+
p["scopes"] as? [String] == ["remote_control_controller_websocket"],
|
|
39
|
+
let expiry = p["tokenExpiresAt"] as? NSNumber, expiry.doubleValue > Date().timeIntervalSince1970 else { throw Failure.invalid }
|
|
40
|
+
case "remoteControlClientEnrollment":
|
|
41
|
+
guard p.count == 10, p["audience"] as? String == "remote_control_client_enrollment",
|
|
42
|
+
["/backend-api/codex/remote/control/client/enroll/finish", "/backend-api/codex/remote/control/client/refresh/finish"].contains(p["targetPath"] as? String ?? "") else { throw Failure.invalid }
|
|
43
|
+
default: throw Failure.invalid
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
func output(_ object: [String: Any]) {
|
|
47
|
+
if let data = try? JSONSerialization.data(withJSONObject: object, options: [.sortedKeys]) { FileHandle.standardOutput.write(data) }
|
|
48
|
+
}
|
|
49
|
+
do {
|
|
50
|
+
guard CommandLine.arguments.count == 2 else { throw Failure.invalid }
|
|
51
|
+
let data = try Data(contentsOf: URL(fileURLWithPath: CommandLine.arguments[1]))
|
|
52
|
+
guard data.count <= 32768, let input = try JSONSerialization.jsonObject(with: data) as? [String: Any], let op = input["operation"] as? String else { throw Failure.invalid }
|
|
53
|
+
if op == "create" {
|
|
54
|
+
stage = "create"
|
|
55
|
+
guard let id = input["keyId"] as? String else { throw Failure.invalid }
|
|
56
|
+
let lookup = try query(id)
|
|
57
|
+
let existing = SecItemCopyMatching(lookup as CFDictionary, nil)
|
|
58
|
+
guard existing == errSecItemNotFound else { try fail(existing == errSecSuccess ? errSecDuplicateItem : existing) }
|
|
59
|
+
let attrs: [String: Any] = [kSecAttrKeyType as String: kSecAttrKeyTypeECSECPrimeRandom, kSecAttrKeySizeInBits as String: 256,
|
|
60
|
+
kSecUseDataProtectionKeychain as String: false, kSecAttrIsExtractable as String: false, kSecAttrIsSensitive as String: true,
|
|
61
|
+
kSecPrivateKeyAttrs as String: [kSecAttrIsPermanent as String: true, kSecAttrIsExtractable as String: false,
|
|
62
|
+
kSecAttrApplicationTag as String: Data(("dev.codexteer.device-key." + id).utf8), kSecAttrLabel as String: "codexteer Remote Control"]]
|
|
63
|
+
var error: Unmanaged<CFError>?
|
|
64
|
+
guard let key = SecKeyCreateRandomKey(attrs as CFDictionary, &error) else {
|
|
65
|
+
if let error = error?.takeRetainedValue() { throw error }; throw Failure.invalid
|
|
66
|
+
}
|
|
67
|
+
stage = "validate"
|
|
68
|
+
output(["ok": true, "key": try metadata(key, id)])
|
|
69
|
+
} else {
|
|
70
|
+
guard ["inspect", "sign"].contains(op), let id = input["keyId"] as? String else { throw Failure.invalid }
|
|
71
|
+
stage = "public-key"
|
|
72
|
+
var q = try query(id); q[kSecReturnRef as String] = true
|
|
73
|
+
var item: CFTypeRef?
|
|
74
|
+
let status = SecItemCopyMatching(q as CFDictionary, &item)
|
|
75
|
+
guard status == errSecSuccess else { try fail(status) }
|
|
76
|
+
guard let item = item, CFGetTypeID(item) == SecKeyGetTypeID() else { throw Failure.invalid }
|
|
77
|
+
let key = item as! SecKey
|
|
78
|
+
let info = try metadata(key, id)
|
|
79
|
+
if op == "inspect" { output(["ok": true, "key": info]) }
|
|
80
|
+
else {
|
|
81
|
+
stage = "payload"
|
|
82
|
+
guard let encoded = input["signedPayloadBase64"] as? String, let payload = Data(base64Encoded: encoded) else { throw Failure.invalid }
|
|
83
|
+
try supportedPayload(payload)
|
|
84
|
+
stage = "sign"
|
|
85
|
+
var error: Unmanaged<CFError>?
|
|
86
|
+
guard let signature = SecKeyCreateSignature(key, .ecdsaSignatureMessageX962SHA256, payload as CFData, &error) as Data? else {
|
|
87
|
+
if let error = error?.takeRetainedValue() { throw error }; throw Failure.invalid
|
|
88
|
+
}
|
|
89
|
+
output(["ok": true, "signatureDerBase64": signature.base64EncodedString(), "key": info])
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
} catch {
|
|
93
|
+
output(["ok": false, "stage": stage, "os_status": (error as NSError).code])
|
|
94
|
+
}
|
package/bin/codexteer.mjs
CHANGED
|
@@ -1,5 +1,9 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
|
|
3
|
-
import { main } from "../src/cli.mjs";
|
|
3
|
+
import { main, fail } from "../src/cli.mjs";
|
|
4
|
+
import { cloudInvocation, mainCloud } from "../src/cloud-cli.mjs";
|
|
4
5
|
|
|
5
|
-
|
|
6
|
+
const args = process.argv.slice(2);
|
|
7
|
+
if (cloudInvocation(args)) {
|
|
8
|
+
try { await mainCloud(args); } catch (failure) { fail(failure, args.includes("--json")); }
|
|
9
|
+
} else await main(args);
|
package/docs/cloud.md
ADDED
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
# Codex Cloudを既存の操作体系で使う
|
|
2
|
+
|
|
3
|
+
CloudのタスクIDまたは公式リンクを指定すると、通常の`read`・`watch`・`send`・`supervise`・`history`・`instructions`・`findings`を使えます。Desktopには接続・フォールバックしません。タスクをまだ選んでいない環境一覧・タスク一覧・新規作成では`--connection cloud`で接続先を指定します。
|
|
4
|
+
|
|
5
|
+
```bash
|
|
6
|
+
codexteer --connection cloud projects list --json
|
|
7
|
+
codexteer --connection cloud threads list --limit 20 --json
|
|
8
|
+
codexteer --connection cloud thread create --project env_example --branch main \
|
|
9
|
+
'テストを追加してください' --json
|
|
10
|
+
codexteer read task_example --include-output --json
|
|
11
|
+
codexteer watch task_example --stream --notify digest --since <CURSOR> --json
|
|
12
|
+
codexteer supervise task_example --agent claude
|
|
13
|
+
codexteer supervise task_example --agent codex -- exec
|
|
14
|
+
codexteer supervise prompt task_example --use-path-cli --json
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
IDはすべて架空の例です。作成時の環境指定は`--project`に統一し、環境IDまたは一意の正確な名前を指定します。`--branch`を省略したときは、一つのリポジトリの既定ブランチを環境が明示している場合だけ使い、`branch_source: environment-default`を返します。不明・複数リポジトリの場合は明示指定が必要です。ローカルの現在ブランチや未コミット差分を暗黙に送信しません。
|
|
18
|
+
|
|
19
|
+
Node.js 20以降、PATH上の公式Codex CLI 0.157.1以降、ChatGPTログインとCloud利用権限が必要です。Desktopの起動は不要です。対象は従来型Cloudタスク用環境であり、新世代Cloud環境設定や別サービスを含む一覧ではありません。環境一覧にはID・名前・リポジトリ名・既定ブランチだけを返し、環境変数・secrets・セットアップ内容は出しません。掲載は実行成功の保証ではありません。タスク一覧は最大500件を公式CLIのページに分けて取得し、続きのcursorを返します。
|
|
20
|
+
|
|
21
|
+
## 共通の監督と介入
|
|
22
|
+
|
|
23
|
+
```bash
|
|
24
|
+
codexteer --supervisor <SESSION_ID> --connection cloud supervise register task_example
|
|
25
|
+
codexteer --supervisor <SESSION_ID> --connection cloud read task_example --include-output --json
|
|
26
|
+
codexteer --supervisor <SESSION_ID> --connection cloud findings create task_example \
|
|
27
|
+
--key timeout-contract --title '期限処理' --condition '期限の検証が通る' --based-on <CURSOR> --json
|
|
28
|
+
codexteer --supervisor <SESSION_ID> --connection cloud send task_example \
|
|
29
|
+
'期限処理を確認してください' --finding <FINDING_ID> --based-on <CURSOR> --json
|
|
30
|
+
codexteer --supervisor <SESSION_ID> --connection cloud history check task_example <MESSAGE_ID> --json
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
監督プロンプトが返した実際のSESSION_ID・保存済みCLI・Node・CODEX_HOMEをそのまま使います。PATHモードも共通です。監督エージェントの起動前に登録し、終了時にその登録を停止します。自分の状態を解除したり、IDを外して介入したりしないでください。
|
|
34
|
+
|
|
35
|
+
監督AIのsandboxがCLIのランチャー照会等を拒否する場合は、利用者が選んだ通常のコマンド承認レビューに、同じ固定CLIコマンドと必要理由を提示します。審査で拒否されたら停止し、許可範囲や書込み先を広げません。公式Codex CLI 0.157.1の`--approve-for-me`はworkspace-writeを選んで自動審査へ送るため、`--sandbox`と同時指定しません。監督CLIの終了コードだけを成功の証拠にせず、doctor・read・watch等の実行結果を確認します。
|
|
36
|
+
|
|
37
|
+
ユーザーは通常の制御を使えます。
|
|
38
|
+
|
|
39
|
+
```bash
|
|
40
|
+
codexteer supervise status task_example --json
|
|
41
|
+
codexteer supervise pause task_example --json
|
|
42
|
+
codexteer supervise resume task_example --json
|
|
43
|
+
codexteer supervise stop task_example --json
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
pauseはその監督の送信・撤回を拒否し、観測は許可します。stopはその監督の観測・送信を拒否し、watchも終了します。Cloud作業自体を取り消す操作ではありません。送信とpause/stopは同じローカル排他を使い、送信中の競合は`RECORD_BUSY`です。監督IDのない明示的な手動送信や旧CLIは、この制御の対象外です。
|
|
47
|
+
|
|
48
|
+
Cloud監督レコードは所有者専用の`CODEX_HOME/codex-steer/cloud-supervisors`へ保存します。旧Desktop CLIが新しいレコードを誤読しないようDesktopの登録と分け、新CLIの`supervise list`では両方を扱います。CLIと保存済みランタイムを更新しても、使用中の旧ランタイムは変更しません。
|
|
49
|
+
|
|
50
|
+
`findings`の安定したkey・revision、対応待ちの重複介入拒否、`history mark`、指示の置換・撤回・有効期限、明示的な根拠、checkpointによる解決・再検証も共通です。登録は継続監視やモデルの読了の証明ではなく、最後の観測時刻と接続状態を区別します。
|
|
51
|
+
|
|
52
|
+
## 実行中と停止中のsend
|
|
53
|
+
|
|
54
|
+
- 通常の`send`は、実行中の現在のターンを再確認し、その親IDを指定してCloudのfollow-upを一度送ります。実機では元ターンがキャンセルされ、**同じタスク内の後続ターン**が開始する方式を確認しました。結果は`delivery_action: interrupt-and-follow-up`です。同じターンIDを保持するローカルのsteerとは内部動作が異なります。
|
|
55
|
+
- 停止中の継続は`send --new-turn`です。ユーザーが再開を委任している場合だけ使います。対象が実行中なら拒否します。
|
|
56
|
+
- タスク・親ターン・ユーザー入力の鮮度を確認しますが、Cloud APIには読取りと送信を原子的に固定することを確認した契約がなく、`freshness_atomic: false`を返します。別の最新ターンを推測して宛先を変更しません。
|
|
57
|
+
- `accepted`は受付です。新しいターンIDは即時に推測せず、`read`と`history check`で親ターン・本文SHA256を照合します。`stored`も要求の達成の証明ではありません。
|
|
58
|
+
- 結果不明時は`unknown`を維持し、自動再送しません。未解決の配送予約は次のCloud送信も止めます。`not_observed`は未配送の証明ではなく、再送を許可しません。
|
|
59
|
+
- 前回の配送が次の送信を拒否した場合は、`existing_attempt_id`・`existing_receipt_path`を回復用に返します。これは今回の配送試行ではありません。拒否した指示は`not_sent`のままとし、前回の受付や保存を根拠に有効化しません。
|
|
60
|
+
- POST前の保存失敗では未送信を記録して予約を戻します。予約の復元も失敗した場合は`reservation_cleanup_required: true`で止め、`history check <TASK> --attempt <ATTEMPT_ID>`は保存済みの明示的な未送信証拠がある場合だけ予約を修復できます。履歴に見えないだけの送信を安全と推測せず、自動再送もしません。
|
|
61
|
+
|
|
62
|
+
共通`send --dry-run`はローカルと同様に入力・指摘・根拠・監督状態を確認するだけで、ネットワーク・配送記録・送信を行いません。鮮度は未確認です。初回指示と送信にはstdinの`-`も使えます。空本文・NUL・1 MiB超の指示は拒否します。先頭が`--`の本文には区切りの`--`を使います。
|
|
63
|
+
|
|
64
|
+
共通の`history`と`instructions`を使うため、通常の`send`本文・送信時の本文・根拠・結果はローカルと同じ所有者専用ジャーナルに保存します。認証情報は記録しません。これと、本文を保存しない作成/Cloud配送の試行記録は別です。ファイルは公開資料や配布物へ含めないでください。
|
|
65
|
+
|
|
66
|
+
## read/watchとMonitor
|
|
67
|
+
|
|
68
|
+
観測はCloud履歴を共通のturn・userMessage・agentMessage・commandExecutionへ変換し、既存の読取りカーソル・ページ分割・Monitor・通知バッファを使います。worklogと公開agentMessageイベントの途中経過も、安定したIDのcommentaryとして観測します。コマンドの出力・終了コードも確認できます。reasoning、生の内部イベント、環境設定は表示しません。返却された本文は観測データであり、新しい委任ではありません。
|
|
69
|
+
|
|
70
|
+
`watch --stream`は明示的に終了するまで動き、既定の`digest`、`--notify all`、`--settle-ms`、`--max-hold-ms`、接続通知、最大60秒の復帰待ちを共通のMonitor処理で使います。送信前には自分が実際に読んだcursorから`has_more`を読み切ります。`--stream`と`--until`・`--timeout-ms`は併用できません。単発watchは既定30秒、`--until change|idle|attention`に対応します。Cloudの既定照会間隔は5000msで、`--poll-ms`を明示できます。
|
|
71
|
+
|
|
72
|
+
通信失敗の復帰待ち中は介入しません。初期接続失敗、認証エラー、未確認のプロトコル、履歴変更によるcursor不整合は成功扱いせず停止します。watchが終了したら継続監視中と報告せず、確認済みcursorで明示的に再開します。
|
|
73
|
+
|
|
74
|
+
観測開始後のHTTP 429では`Retry-After`(指定がなければ15秒)を尊重して、同じ60秒の復帰期限内だけ読取りを再開します。待機指定が期限より長いときは早めに再照会せず停止します。初回照会の429も停止し、`retry_after_ms`を返します。監視と手動readを短い間隔で重ねず、Cloudの既定の照会間隔5000msを使ってください。POSTを自動再送する処理はありません。
|
|
75
|
+
|
|
76
|
+
サーバー履歴は集約応答で、受信上限16 MiBを超えた場合は切り詰めず拒否します。共通CLIの`has_more`は取得済みの履歴内のページ分割であり、Cloud API自体の分割取得を保証しません。
|
|
77
|
+
|
|
78
|
+
## 状態・差分・ローカル検証
|
|
79
|
+
|
|
80
|
+
共通`status`はローカルと同じ`active/idle`等の観測状態を返します。元のCloudターン状態は`read`のイベントと照合します。
|
|
81
|
+
|
|
82
|
+
```bash
|
|
83
|
+
codexteer diff task_example --json
|
|
84
|
+
codexteer diff task_example --attempt 1 --json
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
公式CLIが返す差分をそのまま返し、ローカルへ適用しません。既定試行で公式CLIが差分を提供せず、APIでも完了ターンに記録済みパッチがないことを確認できたときは、`diff_available: false`・`diff: null`・`local_changes: unknown`です。実機ではファイルの実差分があっても記録済みパッチが提供されない場合がありました。変更ゼロと解釈せず、`read --include-output`のコマンド証拠と区別します。特定の`--attempt 1..4`では他の試行から推測しません。
|
|
88
|
+
|
|
89
|
+
checkpoint・resourceは同じローカル記録/コマンド機能で、Cloudタスクにも関連付けられます。明示したローカル入力・成果物・コマンドが対象であり、Cloud作業コピーがローカルにあるとは仮定しません。出力に`execution_environment: local`を示します。ローカルのテスト成功をCloud側の検証と取り違えないでください。
|
|
90
|
+
|
|
91
|
+
Cloud作成時のタイトル・モデル/推論設定・ローカルの権限上書きは、現在の作成経路で適用を確認できていないため、無視せず送信前に拒否します。監督エージェント自身のモデルなどは、従来どおり`supervise --agent ... -- <AGENT_ARGS>`でそのエージェントへ渡します。承認/質問の代理回答、環境登録、Desktop UI操作はこのCloud接続の対象外です。
|
|
92
|
+
|
|
93
|
+
## 認証と失敗時の保護
|
|
94
|
+
|
|
95
|
+
一覧・観測・配送照合・継続指示は、公式`codex app-server --listen stdio://`へ初期化と`getAuthStatus`を送り、既存のChatGPT認証とそのアカウントをメモリ内で使います。認証ファイルを直接読まず、トークン・アカウントIDは表示/保存せず、認証取得のためのモデルターンやDesktop接続も作りません。APIキーや未確認の認証形式は拒否します。
|
|
96
|
+
|
|
97
|
+
HTTP APIは安定した公開SDK契約ではありません。送信先は公式HTTPSオリジンに固定し、リダイレクト・任意URL・自動ログイン・自動再送を使いません。作成・タスク一覧・差分は公式Cloud CLIを使い、必要なhelpと版を確認します。公式CLIは私有の一時作業ディレクトリで動かして診断ログを終了時に削除し、`CODEX_STARTING_DIFF`を引き継ぎません。未確認の入力や認証/通信エラーを、空の正常結果に置き換えません。
|
|
98
|
+
|
|
99
|
+
## 試行の確認と回復
|
|
100
|
+
|
|
101
|
+
```bash
|
|
102
|
+
codexteer --connection cloud thread receipt <ATTEMPT_ID> --json
|
|
103
|
+
codexteer history show task_example --attempt <ATTEMPT_ID> --json
|
|
104
|
+
codexteer history check task_example --attempt <ATTEMPT_ID> --json
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
`thread receipt`は作成時のローカル試行記録を表示します。タスクIDを取得できなかった結果不明の場合も、エラーの`attempt_id`で確認できます。作成や配送を再実行せず、外部照会もしません。作成記録に送信済み本文は保存せずダイジェストを持ち、受付後に記録更新だけ失敗した場合は確認できた実IDと`receipt_update_required: true`を保持します。監督ID付きでは他の作成試行の閲覧を拒否します。
|
|
108
|
+
|
|
109
|
+
通常の送信は`history show/check <TASK> <MESSAGE_ID>`を使います。ジャーナル更新も失敗した場合は、エラーや送信結果の`attempt_id`/`cloud_attempt_id`を`--attempt`に指定します。`history show --attempt`はローカル配送記録、`history check --attempt`は親ターンと本文SHA256の照合および明示的な未送信記録による予約回復です。通常の`history check <TASK> <MESSAGE_ID>`は試行記録と今回の送信本文SHA256・親ターンの一致も検査し、不一致は`conflict`のまま配送済みへ更新しません。どちらの--attempt操作も指定タスクとの一致と監督の有効状態を確認し、別タスクへの記録アクセスを拒否します。MESSAGE_IDと--attemptは併用しません。照合は再送せず、`not_observed`から未配送を推測しません。
|
|
110
|
+
|
|
111
|
+
一次資料: [公式CLIリファレンス](https://developers.openai.com/codex/cli/reference)、[公式Cloud CLI実装](https://github.com/openai/codex/blob/rust-v0.157.1/codex-rs/cloud-tasks/src/lib.rs)。実機検証は専用タスクに限定し、実ID・環境名・認証情報・生ログを公開資料に含めません。
|
|
112
|
+
|
|
113
|
+
Desktop's Cloud environment configurations are available separately through `--connection desktop-cloud environments list`. Their IDs, creation contract and project-membership limits differ from the Web task service described here. See [Desktop Cloud](desktop-cloud.md).
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
# Desktop Cloud
|
|
2
|
+
|
|
3
|
+
Desktop Cloud environment configurations use a different service from Web Cloud tasks. Use the same observation, sending, supervision, findings and instruction commands with a `durable_` task identifier or a `codex://threads/<UUID>?hostId=durable` link. A bare UUID continues to mean a local Desktop task; it never silently selects Cloud.
|
|
4
|
+
|
|
5
|
+
```sh
|
|
6
|
+
codexteer --connection desktop-cloud environments list --json
|
|
7
|
+
codexteer --connection desktop-cloud thread create --environment example-config 'Verify the connection without changing files' --json
|
|
8
|
+
codexteer read 'codex://threads/aaaaaaaa-aaaa-4aaa-8aaa-000000000001?hostId=durable' --include-output --json
|
|
9
|
+
codexteer send durable_aaaaaaaa-aaaa-4aaa-8aaa-000000000001 'Continue the verification' --new-turn --json
|
|
10
|
+
```
|
|
11
|
+
|
|
12
|
+
Authentication comes from the official CLI getAuthStatus API into memory. No credential files are read, no token is printed or persisted, no Desktop UI bridge is used, and no alternate endpoint is selected after failure. WebSocket authentication uses the service's bearer subprotocol; transport exceptions must not expose that subprotocol. Reads and writes are bounded. No approval requests are answered automatically.
|
|
13
|
+
|
|
14
|
+
Creation selects exactly one accessible configuration by ID or exact name and uses the server's default model. The first turn and later continuations carry the thread's selected environment and its deferred allocation flag. Omitting that flag can produce a server internal error despite successful thread creation. Internal errors, timeouts and disconnections after mutation dispatch remain unknown; they are never automatically retried. Creation receipts survive partial success. JSON and human-readable errors expose the created thread ID, attempt ID, receipt path and creation/delivery status even if setting a title or delivering the initial instruction fails. Inspect these identifiers rather than creating a replacement.
|
|
15
|
+
|
|
16
|
+
A configuration is not a Desktop project. The tested remote Cloud thread/start rejects project assignment, while the general Desktop move tool cannot safely establish the source project of a directly created Cloud task. The separate signed assignment endpoint described below is restricted to Desktop execution. `--project` therefore fails before creation. Environment-only creation explicitly returns `project_membership: not_requested`. This implementation does not claim that such a task appears inside a local Desktop project. It does not edit Desktop's membership database or forge a caller context to work around the rejection.
|
|
17
|
+
|
|
18
|
+
Read/watch/Monitor use the shared event model, cursor validation, reconnect reporting and supervisor controls. The service can return null backwards cursors for nonempty histories, so the adapter fetches complete turn pages and uses the shared aggregate cursor rather than synthesizing server bookmarks. The adapter permits at most 100 pages and a bounded receive size per response. This costs more than Desktop's fast paged path on long histories.
|
|
19
|
+
|
|
20
|
+
The journal stores private message text as it does locally. A known accepted turn can be checked using its exact turn ID and message digest. A missing server clientId prevents positive reconciliation of an unknown turn; absence is not non-delivery. Unknown deliveries reserve the target against further sends. Pause and stop control the supervisor, not the Cloud worker. Generated commands retain `--connection desktop-cloud`; no local connection fallback is allowed. Dedicated diff retrieval and approval roundtrips are unverified. Inspect file-change/command events rather than claiming a missing patch means a clean working copy.
|
|
21
|
+
|
|
22
|
+
## Project membership diagnostics and assignment
|
|
23
|
+
|
|
24
|
+
```sh
|
|
25
|
+
codexteer --connection desktop-cloud projects list --json
|
|
26
|
+
codexteer --connection desktop-cloud doctor --thread durable_aaaaaaaa-aaaa-4aaa-8aaa-000000000001 --project example-project --json
|
|
27
|
+
codexteer --connection desktop-cloud thread assign durable_aaaaaaaa-aaaa-4aaa-8aaa-000000000001 --project example-project --json
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
Use `doctor --thread` to inspect a target. The project catalog comes from the existing Desktop App Server, uses its actual Desktop project IDs and does not list Cloud environment configurations. Desktop must be running with its existing codexteer connection for this project catalog. Cloud observation and delivery remain independent of that Desktop connection.
|
|
31
|
+
|
|
32
|
+
Doctor distinguishes membership already recorded in the current Desktop profile from permission to register it. A missing assignment is `source_unknown`, not proof that the task is projectless. A recorded assignment without a durable host binding is `recorded_host_unverified`. This inspection reads the owner-validated profile state; it never edits that state and is not represented as a remote Cloud API result.
|
|
33
|
+
|
|
34
|
+
The official signed project API requires the task to use that Desktop's own ready executor. `thread assign` calls its read-only catalog with the **actual** environment from the Cloud task, validates the signed domain, nonce and request, resolves exactly one project, and rechecks both endpoints before mutation. The assignment acknowledgement must match the same environment, thread and project. Desktop flushes its own state; codexteer reads it back to verify membership. No caller thread/turn identity is fabricated. Public verification keys remain in memory. Unknown mutations reserve the target and are not automatically retried; inspect `thread receipt ATTEMPT_ID` and `doctor --thread TARGET --project PROJECT`.
|
|
35
|
+
|
|
36
|
+
This endpoint does not authorize arbitrary remote Cloud environments. The remote Cloud configuration used in validation was rejected by its read-only catalog; no assignment was attempted on that path. A local executor ID must never be substituted, and a local executor must never be attached just to satisfy this check. Remote `thread/start`/`thread/metadata/update` reject project assignment and remote `project/list` is unavailable in the tested service. Therefore new remote Cloud creation with `--project` still fails before creation. This is a service boundary, not a successful project registration.
|