codexteer 0.18.1 → 0.19.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.
@@ -0,0 +1,492 @@
1
+ import { DUPLICATE_INTERVENTION, OPTIONS_INVALID, STORE_UNSAFE, SUPERVISOR_PAUSED, SUPERVISOR_STOPPED } from "./help-errors.mjs";
2
+ const C_UNKNOWN_DELIVERY = "delivery_status:unknownは受付未確認。自動再送せず、history check <THREAD> <MESSAGE-ID>で照合する。";
3
+ const C_NOT_PROOF = "history checkのnot_observedは未配送の証明ではない。storedもCodexが理解・反映した証明ではない。";
4
+ const C_SUPERVISED_SEND = "--supervisor付きの送信は--based-onと--findingが必須(SUPERVISOR_OBSERVATION_REQUIRED/SUPERVISOR_FINDING_REQUIRED)。instructions retractは--finding不要。";
5
+ const C_EVIDENCE_FILES = "--evidenceのファイルは指定時にsha256を記録し、送信直前に再照合する。変更・消失はSTALE_EVIDENCEで送信しない。ディレクトリは指定できない。";
6
+ const C_EVIDENCE_URLS = "http(s)・codexのURL根拠は参照として記録するだけで、内容の正しさや変更を認定しない。認証情報を含むURLは拒否する。";
7
+ const C_BASED_ON = "--based-onには読み切ったread/statusのcursorを渡す。has_more:trueのcursor、または観測後の新しいユーザー入力・ターン変更はSTALE_OBSERVATIONで送信しない。";
8
+ const C_JOURNAL_SCOPE = "UI方式以外の送信(Cloud・Desktop Cloud・instructions retractを含む)は送信前にCODEX_HOME/codex-steer/messages/へ記録する。";
9
+ const C_LOCAL_FOR_CLOUD = "CloudタスクIDを指定してもローカルの入力・コマンドだけを扱い、Cloud側のファイルは見ない(結果のexecution_environment:local)。";
10
+ const C_PAIRED_SHELL = "pairedで--exec-backend thread-shell --shell powershell|posixを明示した場合だけ、idleの対象チャットでfull accessのホストシェルを使う。";
11
+ const C_NO_AUTO_SWITCH = "pairedでcommand/execが拒否されてもthread-shellへ自動で切り替えない。";
12
+ const C_SUPERVISED_SHELL = "--supervisor付きのthread-shellは送信と同じく監督の状態を確認し、pause中はSUPERVISOR_PAUSEDで実行しない。受付後のコマンドはpause・stopでは止まらない。";
13
+ const C_REMOTE_DOC = "pairedの実行・監視の詳細はhelp remoteとdocs/remote-operations.md。";
14
+ const C_INTERRUPTED_RUN = "ローカルのrunがSIGINT/SIGTERMで止まると、結果のerror_codeがCANCELLEDになりvalid:false・終了コード1になる。";
15
+ const C_OUTPUT_TAIL = "出力は末尾32768文字までローカルに保存し、--include-output指定時だけ表示する。";
16
+
17
+ const C_OPT_DRY_RUN = { name: "--dry-run", text: "送信予定(方式・文字数・メタデータ)だけ返す。根拠ファイルの読取りと入力検証は行うが、接続・鮮度確認・記録・送信はしない。" };
18
+ const C_OPT_NEW_TURN = { name: "--new-turn", text: "idleのタスクで新しいターンを始める。実行中のタスクには使えない。停止中タスクの再開をユーザーが依頼した場合だけ使う。" };
19
+ const C_OPT_SOURCE = { name: "--source NAME", default: "external", text: "送信者名。1行・80文字以内。監督ではClaude Codeならclaude-code。" };
20
+ const C_OPT_BASED_ON = { name: "--based-on CURSOR", text: "読み切ったread/statusのcursor。送信直前に、その後の新しいユーザー入力・ターン変更を検査する。" };
21
+ const C_OPT_EVIDENCE = { name: "--evidence FILE-OR-URL ...", text: "根拠。繰り返し指定可。ファイルはsha256を記録して送信直前に再照合し、URLは参照のみ。" };
22
+ const C_OPT_AFTER_DASH = { name: "-- <COMMAND> [ARGS...]", text: "最初の -- 以降をそのままコマンドの引数にし、シェル展開しない。--jsonを含むcodexteerのオプションはすべて -- より前に置く(後ろに書くとコマンドへ渡る)。" };
23
+ const C_OPT_EXEC_BACKEND = { name: "--exec-backend app-server|thread-shell", default: "app-server", text: "paired専用。thread-shellはidleの対象チャットのホストシェル(full access)を明示的に使う。ローカルでは指定できない。" };
24
+ const C_OPT_SHELL = { name: "--shell powershell|posix", text: "thread-shellで必須。接続先のシェルを明示する。" };
25
+
26
+ const C_E_STALE_OBSERVATION = { code: "STALE_OBSERVATION", when: "--based-onのcursorがhas_more:trueのまま、観測後に新しいユーザー入力・ターン変更があった、または送信直前の読み取り中にタスク状態が変わった(Desktop Cloudではアクティブターンの不一致もこのcode)", action: "read --since <CURSOR>で読み切り、最新の状況で再判断してから新しいcursorで送る。" };
27
+ const C_E_STALE_CURSOR = { code: "STALE_CURSOR", when: "cursorが壊れている、別タスク・別hostのもの、または履歴が変わった", action: "--sinceなしでreadし直し、新しいcursorを使う。" };
28
+ const C_E_SUPERVISOR_OBSERVATION = { code: "SUPERVISOR_OBSERVATION_REQUIRED", when: "--supervisor付きの送信に--based-onがない", action: "readで差分を読み切り、そのcursorを--based-onに付ける。" };
29
+ const C_E_DESKTOP_READ_ONLY = { code: "DESKTOP_READ_ONLY", when: "--connection desktopで送信・撤回しようとした(観測専用)", action: "接続を自動で切り替えず、監督中に--connectionを外して回避しない。送信はshared接続を明示して別途行う(help connection)。" };
30
+ const C_E_DUPLICATE = DUPLICATE_INTERVENTION;
31
+ const C_E_FINDING_CLOSED = { code: "FINDING_CLOSED", when: "send --findingの指摘がresolvedまたはdismissed", action: "新しい根拠か要件の変更があるときだけfindings reopenしてから送る。" };
32
+ const C_E_STALE_FINDING = { code: "STALE_FINDING", when: "送信直前に指摘のrevisionが変わった、または閉じられた", action: "findings showで現状を確認し、再評価してから送る。" };
33
+ const C_E_RECORD_BUSY = { code: "RECORD_BUSY", when: "同じ記録(同じタスクの送信・履歴・指摘、同じcheckpoint、同じ資源)を別のプロセスが使用中。この操作は実行していない", action: "その操作が終わってから再実行する。" };
34
+ const C_E_REMOTE_SHELL_TASK_BUSY = { code: "REMOTE_SHELL_TASK_BUSY", when: "thread-shellの対象チャットがidleでない", action: "対象タスクがidleになってから実行する。" };
35
+ const C_E_MESSAGE_NOT_FOUND = { code: "MESSAGE_NOT_FOUND", when: "指定したMESSAGE-ID(--supersedes・retractの対象を含む)がこのタスクの送信記録にない", action: "history list <THREAD>で同じタスクのmessage_idを確かめて指定し直す。" };
36
+ const C_E_INSTRUCTION_NOT_REPLACEABLE = { code: "INSTRUCTION_NOT_REPLACEABLE", when: "--supersedes・retractの対象がactive/expiredでない、または配送未確認の置換・撤回が残っている。未送信", action: "instructions list <THREAD> --allで状態を確かめる。pending_changesがあればhistory checkで照合してから判断する。" };
37
+ const C_E_CHECKPOINT_NOT_FOUND = { code: "CHECKPOINT_NOT_FOUND", when: "指定したcheckpoint IDがこのタスクの記録にない", action: "checkpoint list <THREAD>でIDを確かめて指定し直す。" };
38
+ const C_E_DESKTOP_CLOUD_DELIVERY_PENDING = { code: "DESKTOP_CLOUD_DELIVERY_PENDING", when: "Desktop Cloudの同じチャットに、受付不明(unknown)で未解除の前回送信がある。error.existing_message_idがその送信", action: "自動再送しない。history check <TARGET> <existing_message_id>で照合する。照合できなければ介入を止めてユーザーに報告する。解除はユーザーだけがhistory mark --resolve-unknownで行う(help history)。" };
39
+
40
+ export const topics = {
41
+ send: {
42
+ title: "実行中のCodexタスクへ指示・レビューを送り、受付を記録する",
43
+ when: "ユーザーに宛先と内容を指定されたとき、または委任された監督範囲で軌道修正が必要と判断したとき。停止中タスクの再開はユーザーが依頼した場合だけ--new-turn。送った指示の訂正・撤回はinstructions。",
44
+ usage: [
45
+ "send <THREAD> <MESSAGE...>|- [--new-turn] [--dry-run] [--no-sound] [--backend app-server|ui]",
46
+ "send <THREAD> <MESSAGE...>|- [--source NAME] [--kind decision|review|hypothesis|suggestion] [--evidence FILE-OR-URL ...] [--based-on CURSOR] [--supersedes MESSAGE-ID] [--expires-at ISO-TIMESTAMP] [--checkpoint ID] [--finding ID]",
47
+ "send <THREAD> <MESSAGE...>|- --backend ui [--keep-focus] [--wait-ms N] [--new-turn] [--dry-run]",
48
+ "<THREAD> <MESSAGE...>|- [sendと同じオプション]",
49
+ ],
50
+ options: [
51
+ { name: "THREAD", text: "ローカルのタスクUUIDかcodex://threads/リンク、CloudのタスクIDかURL、Desktop CloudのIDかリンク。接続はIDから自動判定する(help connection)。" },
52
+ { name: "MESSAGE...|-", text: "残りの引数を空白でつないで本文にする。- だけなら標準入力を読む。本文は引用して1つの引数で渡す。--で始まる語が独立した引数になる本文は、オプションを前に置き、THREADの直後に -- を置いてから書く。" },
53
+ C_OPT_NEW_TURN,
54
+ C_OPT_DRY_RUN,
55
+ { name: "--no-sound", text: "今回だけ送信音を鳴らさない(sound.reason:disabled)。" },
56
+ { name: "--sound", text: "互換用。app-server方式専用で、--no-soundと併用できない。" },
57
+ { name: "--backend app-server|ui", default: "app-server", text: "uiはDesktop画面を操作する明示方式。配送確認・履歴記録・メタデータ・監督送信・リモートに対応しない。" },
58
+ { name: "--keep-focus", text: "UI方式専用。送信後に元のアプリへフォーカスを戻さない。" },
59
+ { name: "--wait-ms N", default: "1500", text: "UI方式専用。画面操作の待ち時間(0〜30000)。" },
60
+ C_OPT_SOURCE,
61
+ { name: "--kind decision|review|hypothesis|suggestion", default: "review", text: "decision=ユーザー決定の伝達、review=レビュー、hypothesis=未確定の仮説、suggestion=任意提案。" },
62
+ C_OPT_EVIDENCE,
63
+ C_OPT_BASED_ON,
64
+ { name: "--supersedes MESSAGE-ID", text: "同じタスクのactive/expiredの指示を置き換える新しい指示として送る(help instructions)。" },
65
+ { name: "--expires-at ISO-TIMESTAMP", text: "未来の時差付きISO日時(末尾Zか±hh:mm)。期限後はinstructions listでexpiredになる。" },
66
+ { name: "--checkpoint ID", text: "送信直前にcheckpointを照合し、無効ならSTALE_CHECKPOINTで送信しない。" },
67
+ { name: "--finding ID", text: "指摘IDと現在のrevisionを配送記録に結び付け、同じrevisionへの重複介入を拒否する(help findings)。" },
68
+ ],
69
+ returns: "成功時はdelivery_status:accepted・sent:true・message_id(=client_message_id)・turn_id・delivery_action(steer/new-turn)・soundを返す。acceptedはサーバーの受付で、処理完了や画面表示を保証しない。Cloudはcloud_attempt_idを返しturn_idはnull。失敗時はok:false、error.code・error.delivery_status(not_sent/unknown)・error.message_id、終了コード1。dry-runはdelivery_status:not_sent。",
70
+ errors: [
71
+ C_E_SUPERVISOR_OBSERVATION,
72
+ { code: "SUPERVISOR_FINDING_REQUIRED", when: "--supervisor付きの送信に--findingがない", action: "findings createで指摘を登録し(同じkeyなら既存IDが返る)、そのIDを--findingに付ける。" },
73
+ C_E_DUPLICATE,
74
+ C_E_FINDING_CLOSED,
75
+ C_E_STALE_FINDING,
76
+ C_E_STALE_OBSERVATION,
77
+ C_E_STALE_CURSOR,
78
+ { code: "STALE_EVIDENCE", when: "根拠ファイル(--evidenceまたは指摘の根拠)が記録後または読取り中に変わった・消えた", action: "編集が終わってからファイルを読み直して判断し直す。指摘の根拠ならfindings reopen <THREAD> <ID> --reason TEXT --evidence FILEで更新してから送る。" },
79
+ { code: "STALE_CHECKPOINT", when: "--checkpointが送信直前の照合でvalidでない", action: "checkpoint verifyで原因を確認し、必要ならcaptureかrunをやり直す。" },
80
+ { code: "EXPIRED_DIRECTIVE", when: "--expires-atの期限が送信前に過ぎた", action: "必要なら新しい期限で送り直すか判断する。" },
81
+ SUPERVISOR_PAUSED,
82
+ SUPERVISOR_STOPPED,
83
+ { code: "TASK_IDLE", when: "通常sendで、送れる実行中ターンがない(タスクがidle・停止中など)。未送信", action: "readで状態を読み直す。idleのタスクの再開はユーザーの依頼がある場合だけ--new-turnで送る。" },
84
+ { code: "TASK_BUSY", when: "--new-turnで、タスクがidleでない、または再開処理中に実行中になった。未送信", action: "--new-turnを外す。readで実行中のターンを確かめてから通常sendで送るか判断する。" },
85
+ { code: "NOT_SENT", when: "他のコードのない送信前の失敗(同じタスクの送信ロックが残っている等)。未送信", action: "error.messageの理由を確認し、readで状態を読み直してから判断する。送信ロックが残るなら、配送をhistory checkで確かめてからユーザーに報告する。" },
86
+ OPTIONS_INVALID,
87
+ C_E_MESSAGE_NOT_FOUND,
88
+ C_E_INSTRUCTION_NOT_REPLACEABLE,
89
+ C_E_CHECKPOINT_NOT_FOUND,
90
+ { code: "TIMEOUT", when: "App Serverの応答待ちが時間切れ(PROTOCOL_ERROR・CONNECTION_FAILEDなどの通信異常も同じ扱い)。送信要求(turn/steer・turn/start)中ならdelivery_status:unknown、それより前ならnot_sent", action: "error.delivery_statusを見る。unknownなら自動再送せずhistory check <THREAD> <MESSAGE-ID>で照合する。" },
91
+ { code: "RUNTIME_CHANGED", when: "送信直前にApp Serverの実行環境が入れ替わった(未送信)", action: "readで対象を読み直してから判断する。" },
92
+ { code: "CAPABILITY_UNVERIFIED", when: "接続先が送信に必要な機能を確認できない(CAPABILITY_UNSUPPORTED、RUNTIME_PROTOCOL_UNSUPPORTED/UNVERIFIEDも同じ扱い)。未送信", action: "doctor --jsonのruntime_compatibilityを確認する。互換のあるCLIかwrapperで実行する。" },
93
+ C_E_DESKTOP_READ_ONLY,
94
+ { code: "CLOUD_DUPLICATE_SEND", when: "Cloudタスクに受付済みか受付不明の前回送信がある", action: "再送しない。history check <TASK> --attempt <error.existing_attempt_id>で照合する(help cloud)。" },
95
+ C_E_DESKTOP_CLOUD_DELIVERY_PENDING,
96
+ { code: "DESKTOP_UI_NOT_READY", when: "--backend uiで、UI送信の前提(macOS・ChatGPT.app・同梱AppleScript・Accessibility権限)が欠けている。未送信", action: "doctor --backend uiで欠けている項目を確かめ、ユーザーに対応を依頼する。app-server方式へ自動で切り替えない。" },
97
+ { code: "DESKTOP_UI_FAILED", when: "--backend uiで、Desktopを開く・画面を操作する・入力を送る処理が失敗した", action: "UI送信は配送を確認できない。再送する前にreadで反映を確かめる。" },
98
+ C_E_RECORD_BUSY,
99
+ STORE_UNSAFE,
100
+ ],
101
+ examples: [
102
+ "codexteer send <THREAD> '失敗したテストの原因を先に確認してください' --dry-run --json",
103
+ "codexteer send <THREAD> '競合が原因か確認してください' --source claude --kind hypothesis --evidence results.xml --based-on <CURSOR> --json",
104
+ "codexteer send <THREAD> '続けてください' --new-turn --no-sound --json",
105
+ "printf '%s\\n' '理由' '変更方針' | codexteer send <THREAD> -",
106
+ ],
107
+ notes: [
108
+ "-- 以降はオプションとして解釈しない。--dry-runや--jsonも本文として送られる。本文の途中に置いた -- は本文に残る。",
109
+ "-- より前の未知の--オプションや値のないオプションはOPTIONS_INVALID(Cloud・Desktop CloudはCLOUD_OPTIONS_INVALID)で拒否し、何も送らない。",
110
+ "--source・--kind・--evidence・--based-on・--supersedes・--expires-at・--checkpoint・--findingか--supervisorがあると本文の前に見出し行を付け、どれもなければ本文だけを送る。",
111
+ "見出しは[codexteer <message_id>]・送信者(既定external)・種類(既定review)と、指定に応じた根拠・観測ターン・置換/撤回対象・期限・checkpoint・指摘と解決条件の行。",
112
+ "decisionは送信者による分類で、新しいユーザー承認を作らない。元のユーザー指示を根拠として示す。",
113
+ C_BASED_ON,
114
+ "Codexの通常の進捗出力だけではSTALE_OBSERVATIONにならない。",
115
+ "鮮度確認から送信までの間の変更は原子的には防げない。",
116
+ C_EVIDENCE_FILES,
117
+ C_EVIDENCE_URLS,
118
+ C_SUPERVISED_SEND,
119
+ "通常sendは対象の実行中ターンIDをexpectedTurnIdとして送り、一致はサーバーが確認する。不一致でも別のターンIDへ再送しない。",
120
+ "ページ単位の履歴(historyMode:paginated)で古いターンが実行中のまま残っていても、最新ターンが進行中なら通常sendを使える。Codexの終了や履歴修復は要らない。",
121
+ "sendは古いターンの表示・保存状態を修復しない。修復はhelp threadのthread repair。",
122
+ "dry-runでも監督の状態、--supersedesの対象、--findingの重複、cursorの形式は検査する。",
123
+ C_JOURNAL_SCOPE,
124
+ "journal_update_required:trueは受付後に配送記録を更新できなかった状態。再送せずhistory checkで照合する。",
125
+ C_UNKNOWN_DELIVERY,
126
+ "送信音は既定でオン。受付(accepted)時だけmacOSのafplayで同梱の短い音「プルッ」(約0.3秒)を鳴らす。",
127
+ "dry-run・送信失敗・unknown・UI方式・macOS以外では鳴らない。結果はJSONのsound.played/sound.reasonで分かる。",
128
+ "再生に失敗しても送信結果は成功のまま。テキスト出力では標準エラーに警告を出す。",
129
+ "通知設定は変更しない。音量・ミュートはMacの出力設定に従う。",
130
+ "Cloudの通常sendは実行中の親ターンを指定し、中断して同じタスクの後続ターンを始める(help cloud)。",
131
+ "リモートhostへの送信経路はhelp remoteとhelp remote-control。",
132
+ ],
133
+ see: ["findings", "history", "instructions", "checkpoint", "supervise", "read", "connection", "cloud", "thread"],
134
+ },
135
+
136
+ findings: {
137
+ title: "指摘ごとに解決条件・根拠・介入・解決と評価を記録し、重複介入を防ぐ",
138
+ when: "監督で介入する前に指摘を登録するとき。同じ指摘の重複送信を避け、対応の申告(history mark)と検証済みの解決(checkpoint)を分けて追うとき。",
139
+ usage: [
140
+ "findings create <THREAD> --key KEY --title TEXT --condition TEXT [--evidence FILE-OR-URL ...] [--based-on CURSOR]",
141
+ "findings list <THREAD> [--all] [--limit N]",
142
+ "findings show <THREAD> <ID>",
143
+ "findings resolve <THREAD> <ID> --checkpoint ID --note TEXT",
144
+ "findings dismiss <THREAD> <ID> --reason TEXT",
145
+ "findings reopen <THREAD> <ID> --reason TEXT [--condition TEXT] [--evidence FILE-OR-URL ...] [--based-on CURSOR]",
146
+ "findings evaluate <THREAD> <ID> --rating useful|unnecessary|incorrect --reason TEXT",
147
+ "findings stats <THREAD>",
148
+ ],
149
+ options: [
150
+ { name: "--key KEY", text: "指摘ごとの安定した識別子。英数字で始まり英数字と._-、最大151文字。" },
151
+ { name: "--title TEXT", text: "指摘の要点(240文字以内)。" },
152
+ { name: "--condition TEXT", text: "解決条件(8000文字以内)。新しいユーザー要件はここへ反映する。" },
153
+ { name: "--evidence FILE-OR-URL ...", text: "根拠。ファイルはsha256を記録し、send --findingの直前に再照合する。reopenで指定すると根拠一覧を置き換える。" },
154
+ { name: "--based-on CURSOR", text: "観測位置の記録。revisionや再介入の可否には影響しない。" },
155
+ { name: "--checkpoint ID", text: "resolveで必須。現在validなcheckpointだけ受け付ける。" },
156
+ { name: "--note TEXT", text: "resolveで必須。checkpointの結果が解決条件を満たすと判断した根拠。" },
157
+ { name: "--reason TEXT", text: "dismiss・reopen・evaluateで必須(8000文字以内)。" },
158
+ { name: "--rating useful|unnecessary|incorrect", text: "evaluateの評価。未評価はunratedのまま残す。" },
159
+ { name: "--all", text: "listでresolved・dismissedも含める。" },
160
+ { name: "--limit N", default: "50", text: "listの件数(1〜1000)。" },
161
+ ],
162
+ returns: "create・show・resolve・dismiss・reopen・evaluateは指摘(id・key・title・condition・evidence・revision・disposition・resolution・evaluation・revisions)にstatus・messages(現revisionの送信)・verificationを付けて返す。createは既存keyならreused:true。listはfindings・total・has_more。statsは評価件数・未評価・母数。",
163
+ errors: [
164
+ { code: "FINDING_INVALID", when: "keyの形式、必須テキストの欠落・長さ超過、--rating・--limitの値、resolveの--checkpoint欠落", action: "引数を直して再実行する。" },
165
+ { code: "FINDING_NOT_FOUND", when: "IDがこのタスクの指摘ではない", action: "findings list <THREAD> --allでIDを確認する。" },
166
+ { code: "FINDING_UNCHANGED", when: "reopenで根拠も解決条件も変わっていない", action: "新しい根拠か変更した解決条件を指定する。cursorやreasonだけでは再介入できない。" },
167
+ { code: "FINDING_DELIVERY_UNKNOWN", when: "現revisionに受付不明(unknown)の送信が残ったままresolve・dismiss・reopenした", action: "history check <THREAD> <MESSAGE-ID>で照合してから再実行する。Desktop Cloudで照合できなければ、ユーザーがhistory mark --resolve-unknownで解除する。" },
168
+ { code: "STALE_CHECKPOINT", when: "resolveに指定したcheckpointが現在validでない", action: "checkpoint verifyで原因を確認し、必要ならrunし直してからresolveする。" },
169
+ C_E_DUPLICATE,
170
+ C_E_FINDING_CLOSED,
171
+ C_E_STALE_FINDING,
172
+ { code: "STALE_EVIDENCE", when: "create・reopenで、--evidenceのファイルが読取り中に変わった", action: "編集が終わってから同じコマンドを実行し直す。" },
173
+ C_E_CHECKPOINT_NOT_FOUND,
174
+ OPTIONS_INVALID,
175
+ C_E_RECORD_BUSY,
176
+ STORE_UNSAFE,
177
+ ],
178
+ examples: [
179
+ "codexteer findings create <THREAD> --key timeout --title '待機の終了条件' --condition '指定時間で終了する回帰テストが通る' --evidence src/monitor.mjs --json",
180
+ "codexteer send <THREAD> '終了条件を確認してください' --finding <ID> --based-on <CURSOR> --json",
181
+ "codexteer findings resolve <THREAD> <ID> --checkpoint <CHECKPOINT-ID> --note '指定時間で終了することをテストで確認' --json",
182
+ "codexteer findings stats <THREAD> --json",
183
+ ],
184
+ notes: [
185
+ "keyは本文の意味を自動分類しない。同じ指摘には同じkeyを使い、重複回避のために別keyを作らない。keyを変えると別の指摘になる。",
186
+ "既存keyでcreateすると既存の指摘をそのまま返し、title・condition・evidenceは更新しない。変更はreopenで行う。",
187
+ "statusはopen・awaiting_response・delivery_unknown・awaiting_verification・needs_review・resolved・dismissedのいずれか。",
188
+ "send --finding <ID>は指摘IDと現在のrevisionを配送記録に結び付ける。同じrevisionにnot_sent以外の送信があればDUPLICATE_INTERVENTION。",
189
+ "再送できるのは、明確なnot_sentと、ユーザーが--resolve-unknownで解除した送信だけ。dry-runは重複を判定するが予約はしない。",
190
+ C_SUPERVISED_SEND,
191
+ "reopenはreasonに加えて根拠か解決条件の変更が必要。成功するとrevisionが1増え、openに戻り、評価はunratedに戻る。",
192
+ "過去revisionの解決条件・根拠・解決・評価・reopenの理由はrevisionsに残る。",
193
+ "send --findingは指摘の根拠ファイルも送信直前に再照合し、作成後に変わっていればSTALE_EVIDENCEで送信しない。",
194
+ C_EVIDENCE_URLS,
195
+ "listは既定で、resolved・dismissed以外を更新が新しい順に返す。",
196
+ "解決後に入力・最新run・成果物が変わるとverification.validがfalseになり、needs_reviewとして既定のlistに戻る。",
197
+ "history markのappliedは対応の申告で、statusがawaiting_verificationになるだけ。解決はresolveで記録する。",
198
+ "resolveは現在validなcheckpointと、条件を満たすと判断したnoteを要求し、そのrun IDと入力ハッシュを固定する。",
199
+ "テスト成功だけで解決条件の妥当性や指摘の有用性は認定しない。noteとevaluateは明示的な申告として記録する。",
200
+ "statsは各指摘の現在revisionを1件として未送信候補も含める。useful_fractionの母数は評価済み件数で、0件ならnull。",
201
+ "statsの値は介入の因果効果を証明しない。",
202
+ C_NOT_PROOF,
203
+ ],
204
+ see: ["send", "history", "checkpoint", "supervise"],
205
+ },
206
+
207
+ history: {
208
+ title: "送った指示の配送・受信履歴との照合・対応状況を確認し記録する",
209
+ when: "送信結果がunknownのとき、送った指示が受信履歴に残ったか確かめるとき、対応結果を記録するとき、未対応の送信を洗い出すとき。Desktop Cloudの受付不明を照合で確かめられず、ユーザーが送信の保留を解除するとき(--resolve-unknown)。未解決の指摘一覧はfindings list。",
210
+ usage: [
211
+ "history list <THREAD> [--pending] [--include-text]",
212
+ "history show <THREAD> <MESSAGE-ID> [--include-text]",
213
+ "history check <THREAD> [MESSAGE-ID] [--include-text]",
214
+ "history show|check <CLOUD_TASK_ID|URL> --attempt <ATTEMPT_ID>",
215
+ "history mark <THREAD> <MESSAGE-ID> --status acknowledged|applied|dismissed --note TEXT [--evidence REF ...] [--by NAME]",
216
+ "history mark <DURABLE_ID|HOST_LINK> <MESSAGE-ID> --resolve-unknown --note TEXT",
217
+ ],
218
+ options: [
219
+ { name: "MESSAGE-ID", text: "send結果のmessage_id(=client_message_id)。unknownや失敗でも記録される。同じタスクの記録だけ指定できる。checkで省略するとそのタスクの全記録を照合する。" },
220
+ { name: "--pending", text: "listでresponse.statusがapplied・dismissed以外の記録(not_sentも含む)だけ返す。" },
221
+ { name: "--include-text", text: "本文(body)と実際に送った文(wire_text)も返す。" },
222
+ { name: "--status acknowledged|applied|dismissed", text: "markで記録する対応状況。" },
223
+ { name: "--note TEXT", text: "markで必須。--resolve-unknownでは解除の理由として記録する。" },
224
+ { name: "--resolve-unknown", text: "Desktop Cloud専用・ユーザー専用。受付不明の送信の配送予約を解除し、同じチャットへの次の送信を許す。--status・--evidence・--byとは併用できない。" },
225
+ { name: "--evidence REF ...", text: "markの根拠参照。文字列のまま記録し、内容は照合しない。appliedでは必須。" },
226
+ { name: "--by NAME", default: "local", text: "markの記録者名。" },
227
+ { name: "--attempt ATTEMPT_ID", text: "Cloud専用。send結果のcloud_attempt_id(失敗時はerror.attempt_id)。MESSAGE-IDとは併用しない。Desktop Cloudでは使えない。" },
228
+ ],
229
+ returns: "list・check(MESSAGE-ID指定でも)は配列、show・mark・--attempt付きのshow/checkは1件。各記録はdelivery_status(accepted/unknown/not_sent=受付)、verification.status(stored/conflict/not_observed=受信履歴との照合)、response.status(unreported/acknowledged/applied/dismissed=記録者の申告)を別々に返す。--attemptのshowはローカルの試行記録、checkはそれにdelivery_verificationとretry_safeを付けて返す。--resolve-unknownは更新した1件を返し、resolution(by:user・at・note)が付きdelivery_statusはunknownのまま。",
230
+ errors: [
231
+ { code: "CAPABILITY_UNSUPPORTED", when: "接続先がcheckに必要な読み取り機能に対応しない(RUNTIME_PROTOCOL_UNSUPPORTEDも同じ扱い)", action: "doctor --jsonのruntime_compatibilityを確認する。照合できないまま再送しない。" },
232
+ { code: "CLOUD_RECEIPT_NOT_FOUND", when: "--attemptの試行記録がない", action: "send結果のcloud_attempt_idかerror.attempt_idを確認する。" },
233
+ { code: "CLOUD_TARGET_CONFLICT", when: "--attemptの試行が別のCloudタスクのもの、または--connectionがタスクIDと合わない", action: "error.expected_connectionと対象タスクIDを確認して指定し直す。" },
234
+ { code: "CLOUD_OPTIONS_INVALID", when: "--attemptがUUIDでない、list・markやDesktop Cloudに--attemptを付けた。Cloud経路で引数の数や組み合わせが不正なときも出る", action: "show/checkとCloudタスクIDだけで使う。Desktop CloudはMESSAGE-IDでcheckする。" },
235
+ C_E_MESSAGE_NOT_FOUND,
236
+ { code: "SUPERVISOR_CONTROL_FORBIDDEN", when: "--supervisor付きでhistory mark --resolve-unknownを実行した", action: "監督は自分の送信の保留を解除しない。介入を止めてユーザーに報告し、解除はユーザーが端末から--supervisorなしで行う。" },
237
+ { code: "DESKTOP_CLOUD_OPTIONS_INVALID", when: "--resolve-unknownで--noteが空、またはその送信が未解除の受付不明(unknown)でない", action: "history show <TARGET> <MESSAGE-ID>でdelivery_statusとresolutionを確かめる。acceptedや解除済みなら解除は不要。" },
238
+ OPTIONS_INVALID,
239
+ C_E_RECORD_BUSY,
240
+ STORE_UNSAFE,
241
+ ],
242
+ examples: [
243
+ "codexteer history list <THREAD> --pending --json",
244
+ "codexteer history check <THREAD> <MESSAGE-ID> --json",
245
+ "codexteer history check task_example --attempt <ATTEMPT_ID> --json",
246
+ "codexteer history mark <THREAD> <MESSAGE-ID> --status applied --note '対象の回帰テストが通過' --evidence test-results.xml --by reviewer --json",
247
+ "codexteer history mark durable_<UUID> <MESSAGE-ID> --resolve-unknown --note 'Desktopで未着を確認した' --json",
248
+ ],
249
+ notes: [
250
+ C_JOURNAL_SCOPE,
251
+ "本文は0600のローカルファイルに保存し、--include-text指定時だけ表示する。",
252
+ "記録は送信前にunknownとして作り、結果で更新する。そのためunknownでもmessage_idが残る。dry-runは記録しない。",
253
+ C_UNKNOWN_DELIVERY,
254
+ "checkは受信履歴と照合するだけで再送しない。ローカルではclientIdと本文が一致すればstoredとし、delivery_statusをacceptedに更新する。",
255
+ "checkで同じclientIdがあっても本文が一致しなければconflict。",
256
+ C_NOT_PROOF,
257
+ "重複拒否で返るexisting_attempt_idは前回の試行の照合用で、今回の配送IDではない。",
258
+ "--attemptのcheckは親ターンと本文ダイジェストでCloud履歴を照合する。showはローカルの試行記録を読むだけ。",
259
+ "POST前の未送信が試行記録で明示的に確かめられた場合だけ、--attemptのcheckはretry_safe:trueを返し配送予約を解除する。",
260
+ "Cloudでhistory check <TASK> <MESSAGE-ID>を使うと、記録の本文ダイジェスト・親ターンを試行記録と照合し、不一致ならconflict。",
261
+ "Cloudのcheckはnot_sentの記録を前回の配送を根拠にacceptedへ更新しない。",
262
+ "markのappliedには--evidenceが必須。根拠の妥当性は自動で認定しない。",
263
+ "markのappliedを記録すると、その送信に結び付いた指摘のstatusはawaiting_verificationになる(help findings)。",
264
+ "Desktop Cloudの受付不明の送信は、history checkでstoredになるか、ユーザーが--resolve-unknownで解除するまで同じチャットへの次の送信を止める。",
265
+ "checkで見つからない(not_observed)ことでは送信の保留は解除されない。",
266
+ "--resolve-unknownは--supervisorなしでユーザーが実行する。監督は実行しない。",
267
+ "--resolve-unknownは配送の有無を確定しない。delivery_statusはunknownのままで、履歴の記録とDesktop Cloudの送信記録にresolutionを付ける。",
268
+ "--resolve-unknownで解除した送信は、結び付いた指摘でも受付不明として扱わない。その指摘は送り直し・resolve・dismiss・reopenできる。",
269
+ ],
270
+ see: ["send", "instructions", "findings", "cloud", "desktop-cloud"],
271
+ },
272
+
273
+ instructions: {
274
+ title: "現在有効な指示を一覧し、送った指示を置き換え・撤回する",
275
+ when: "自分の診断を訂正・撤回するとき、方針が変わったとき、長い会話で今有効な指示を確認するとき。新しい指示を送るだけならsend。",
276
+ usage: [
277
+ "instructions list <THREAD> [--all]",
278
+ "send <THREAD> <NEW-MESSAGE> --supersedes <MESSAGE-ID> [--expires-at ISO-TIMESTAMP]",
279
+ "instructions retract <THREAD> <MESSAGE-ID> --reason TEXT [--source NAME] [--based-on CURSOR] [--new-turn] [--dry-run]",
280
+ ],
281
+ options: [
282
+ { name: "MESSAGE-ID", text: "置き換え・撤回する元の指示のID(history listで確認)。同じタスクのactiveかexpiredの指示だけ指定できる。" },
283
+ { name: "--all", text: "listでactive以外(expired・superseded・retracted・withdrawal_notice・pending_delivery・released・not_sent)も含める。" },
284
+ { name: "--supersedes MESSAGE-ID", text: "sendのオプション。新しい指示を送り、受付後に元の指示をsupersededにする。" },
285
+ { name: "--expires-at ISO-TIMESTAMP", text: "未来の時差付きISO日時(末尾Zか±hh:mm)。期限後はexpiredになる。" },
286
+ { name: "--reason TEXT", text: "retractで必須。撤回の理由がそのまま送信本文になる。" },
287
+ C_OPT_SOURCE,
288
+ { name: "--based-on CURSOR", text: "読み切ったread/statusのcursor。--supervisor付きのretractでは必須。" },
289
+ C_OPT_NEW_TURN,
290
+ { name: "--dry-run", text: "送信予定だけ返す。送信も記録もしない。" },
291
+ ],
292
+ returns: "listはthread_id、instructions(既定はactiveのみ。本文・instruction_status・replaced_by・pending_change_idsを含む)、pending_changes(受付未確認の送信)を返す。retractはsendと同じ送信結果を返す。",
293
+ errors: [
294
+ C_E_SUPERVISOR_OBSERVATION,
295
+ C_E_STALE_OBSERVATION,
296
+ C_E_MESSAGE_NOT_FOUND,
297
+ C_E_INSTRUCTION_NOT_REPLACEABLE,
298
+ C_E_DESKTOP_READ_ONLY,
299
+ ],
300
+ examples: [
301
+ "codexteer instructions list <THREAD> --json",
302
+ "codexteer send <THREAD> '先ほどの診断を訂正します。原因は復帰処理です' --supersedes <MESSAGE-ID> --kind review --source claude-code --json",
303
+ "codexteer instructions retract <THREAD> <MESSAGE-ID> --reason '再計測で仮説を否定できた' --json",
304
+ ],
305
+ notes: [
306
+ "このタスクへ記録付きで送ったすべての送信が指示として扱われる。受付済みで、置換・撤回・期限切れでなければactive。",
307
+ "instruction_statusのwithdrawal_noticeは撤回を伝えた送信自体、pending_deliveryは受付未確認の送信。",
308
+ "releasedは、ユーザーがhistory mark --resolve-unknownで解除した受付不明の送信。元の指示を保留させず、置き換え・撤回をやり直せる。",
309
+ "置換・撤回もCodexへメッセージを送り、見出しに対象の指示IDを示す。元の記録は削除しない。",
310
+ "置換・撤回の送信がacceptedになって初めて、元の指示がsuperseded・retractedになる。",
311
+ "置換・撤回の配送がunknownの間、元の指示はactiveのままpending_changesに出る。history checkでstoredになると確定する。",
312
+ "置換・撤回の対象にできるのは、activeかexpiredで、配送未確認の置換・撤回が残っていない指示だけ。",
313
+ "--expires-atの期限はこの一覧のexpired判定に使うだけで、Codexの処理を自動停止しない。",
314
+ "受付やstoredの確認は、Codexが方針変更を理解した証明ではない。必要ならhistory markで明示的な応答を記録する。",
315
+ C_SUPERVISED_SEND,
316
+ "retractのその他の送信エラーと対処はhelp sendと同じ。",
317
+ ],
318
+ see: ["send", "history", "findings"],
319
+ },
320
+
321
+ checkpoint: {
322
+ title: "検証に使う入力ファイルを固定し、コマンド結果と成果物をその入力に結び付ける",
323
+ when: "テスト結果が最終ソースのものか確かめるとき、ビルドや送信の前に検証がまだ有効か確かめるとき、findings resolveやsend --checkpointに使う検証記録を作るとき。",
324
+ usage: [
325
+ "checkpoint capture <THREAD> <NAME> --path PATH [--path PATH ...] [--exclude PATH ...]",
326
+ "checkpoint run <THREAD> <ID> [--timeout-ms N] [--include-output] [--exec-backend app-server|thread-shell] [--shell powershell|posix] -- <COMMAND> [ARGS...]",
327
+ "checkpoint attach <THREAD> <ID> --artifact FILE [--artifact FILE ...]",
328
+ "checkpoint verify <THREAD> <ID>",
329
+ "checkpoint list <THREAD>",
330
+ "checkpoint show <THREAD> <ID> [--include-output]",
331
+ ],
332
+ options: [
333
+ { name: "NAME", text: "captureの表示名。IDは自動で振られるUUID。" },
334
+ { name: "--path PATH", text: "captureで必須・繰り返し可。ファイルかディレクトリ(現在のディレクトリ基準)。配下の追加・削除・変更も検知する。" },
335
+ { name: "--exclude PATH", text: "そのパス以下を入力から除く。実パスの前方一致でglobではない。出力先・キャッシュを除外する。.gitは常に除外。" },
336
+ { name: "--timeout-ms N", default: "0", text: "runの実行時間上限(0〜86400000)。0は無制限。pairedではapp-server方式が86400000ms、thread-shellが1時間として扱う。" },
337
+ { name: "--include-output", text: "run・showで出力末尾を表示する。" },
338
+ C_OPT_EXEC_BACKEND,
339
+ C_OPT_SHELL,
340
+ { name: "--artifact FILE", text: "attachで必須・繰り返し可。ローカルのファイルだけ(URL・ディレクトリ不可)。" },
341
+ C_OPT_AFTER_DASH,
342
+ ],
343
+ returns: "captureはid・入力のdigest・file_count・directory_count。runはexit_code・timed_out・inputs_unchanged・touched_paths・differences・valid。verifyはinputs_current・differences・artifacts(各current)・latest_run・valid。valid:falseならrun・verifyの終了コードは1。list・showは記録の要約。",
344
+ errors: [
345
+ { code: "REMOTE_SHELL_REQUIRED", when: "thread-shellで--shellがない", action: "--shell powershell|posixを明示する。" },
346
+ C_E_REMOTE_SHELL_TASK_BUSY,
347
+ { code: "REMOTE_COMMAND_UNKNOWN", when: "pairedのrunで完了を確認できない(runのstatus:unknown)", action: "同じコマンドを自動で再実行しない。接続先で結果を確かめてから判断する。" },
348
+ C_E_CHECKPOINT_NOT_FOUND,
349
+ { code: "STALE_CHECKPOINT", when: "runの開始時に入力がcapture時と違う(コマンドは実行していない)、またはattach時に最新runがvalidでない", action: "runならcheckpoint captureし直してから新しいIDでrunする。attachならcheckpoint verifyで原因を確かめ、runし直してからattachする。" },
350
+ OPTIONS_INVALID,
351
+ C_E_RECORD_BUSY,
352
+ STORE_UNSAFE,
353
+ ],
354
+ examples: [
355
+ "codexteer checkpoint capture <THREAD> tests --path src --path test --path package.json --path package-lock.json --json",
356
+ "codexteer checkpoint run <THREAD> <ID> --json -- npm test",
357
+ "codexteer checkpoint attach <THREAD> <ID> --artifact test-results.xml --json",
358
+ "codexteer checkpoint verify <THREAD> <ID> --json",
359
+ "codexteer send <THREAD> 'この検証結果で次へ進んでください' --checkpoint <ID> --json",
360
+ ],
361
+ notes: [
362
+ "入力はファイルとディレクトリだけ。ファイルのシンボリックリンクはリンク先の内容で記録し、ディレクトリのリンクは拒否する(実体を--pathに指定)。",
363
+ "runはcapture時の作業ディレクトリで、argvをシェル展開せずそのまま実行する。",
364
+ "run開始時に入力がcapture時と違えばSTALE_CHECKPOINTで実行しない。captureし直す。",
365
+ "実行前後のハッシュと実行中のファイル監視を記録する。途中の編集や監視エラーがあればinputs_unchanged:falseで、validにならない。",
366
+ "runのvalidは終了コード0・エラーなし・timeoutなし・入力不変。verifyはさらに現在の入力の一致と、最新runに付けた成果物の一致を求める。",
367
+ "割り込み・timeout時は自分が起動したプロセスグループを終了する(SIGTERM、1秒後にSIGKILL)。",
368
+ C_INTERRUPTED_RUN,
369
+ "厳密に固定するには、実行中に他から編集されない隔離した入力を使う。",
370
+ "attachは最新runがvalidなときだけでき(それ以外はSTALE_CHECKPOINT)、成果物をそのrunに結び付ける。runし直したら成果物もattachし直す。",
371
+ "attachは成果物の生成元を自動では証明しない。アプリはZIP等のファイルで指定する。",
372
+ "validは選んだ入力とコマンド結果の整合性だけを示し、テスト範囲の十分性や配布許可は認定しない。",
373
+ C_OUTPUT_TAIL,
374
+ "send --checkpoint <ID>は送信直前にも照合し、validでなければSTALE_CHECKPOINTで送信しない。",
375
+ C_LOCAL_FOR_CLOUD,
376
+ "pairedでは接続先のファイルAPIで入力・成果物・監視を扱い、コマンドは接続先で実行する。",
377
+ C_PAIRED_SHELL,
378
+ C_NO_AUTO_SWITCH,
379
+ C_SUPERVISED_SHELL,
380
+ "thread-shellは保存された実行項目の完了マーカーと終了コードを照合して結果とする。",
381
+ C_REMOTE_DOC,
382
+ ],
383
+ see: ["findings", "send", "resource", "remote"],
384
+ },
385
+
386
+ resource: {
387
+ title: "画面・Unity・Gitなどの共有資源の利用予約(リース)をAI間で調整する",
388
+ when: "複数のAIが画面操作・ビルド・コミットなどを同時に行わないよう、同じCODEX_HOMEを使う参加者間で順番を取るとき。",
389
+ usage: [
390
+ "resource acquire <NAME> --owner NAME [--ttl-ms N] [--thread THREAD] [--reason TEXT] [--condition TEXT]",
391
+ "resource status <NAME> [--thread THREAD]",
392
+ "resource list [--thread THREAD]",
393
+ "resource renew <NAME> --token TOKEN [--ttl-ms N] [--thread THREAD]",
394
+ "resource release <NAME> --token TOKEN [--thread THREAD]",
395
+ "resource run <NAME> --owner NAME [--ttl-ms N] [--timeout-ms N] [--include-output] [--condition TEXT] [--reason TEXT] [--thread THREAD] [--cwd PATH] [--exec-backend app-server|thread-shell] [--shell powershell|posix] -- <COMMAND> [ARGS...]",
396
+ ],
397
+ options: [
398
+ { name: "NAME", text: "資源名(1行・200文字以内)。同じ名前を使う参加者の間でだけ排他になる。" },
399
+ { name: "--owner NAME", text: "acquire・runで必須。所有者名(例: claude-code、codex)。" },
400
+ { name: "--ttl-ms N", default: "600000", text: "リースの期間(1000〜86400000)。renewでは今からの新しい期間。" },
401
+ { name: "--thread THREAD", text: "関連タスク。--supervisor付きでは全サブコマンドで必須(ないとSUPERVISOR_CONTROL_FORBIDDEN)。thread-shellでも必須。サブコマンドの前にも置ける。" },
402
+ { name: "--reason TEXT", text: "利用理由のメモ。" },
403
+ { name: "--condition TEXT", text: "許可済みの利用条件のメモ。" },
404
+ { name: "--token TOKEN", text: "renew・releaseで必須。acquire結果のtoken。" },
405
+ { name: "--timeout-ms N", default: "0", text: "runの実行時間上限(0〜86400000)。0は無制限。pairedではapp-server方式が86400000ms、thread-shellが1時間として扱う。" },
406
+ { name: "--include-output", text: "runの出力末尾を表示する。" },
407
+ { name: "--cwd PATH", text: "runの作業ディレクトリ。既定は現在のディレクトリ。pairedでは接続先のパス。" },
408
+ C_OPT_EXEC_BACKEND,
409
+ C_OPT_SHELL,
410
+ C_OPT_AFTER_DASH,
411
+ ],
412
+ returns: "acquire・renew・releaseはリース(name・owner・token・thread_id・reason・condition・claimed_at・expires_at・released_at)。status・listはstate(available/held/expired/released)とlease。runはexit_code・timed_out・lease_error・released・valid。valid:falseならrunの終了コードは1。",
413
+ errors: [
414
+ { code: "RESOURCE_BUSY", when: "別の所有者が期限内に保持している", action: "コマンドは実行されていない。statusで所有者と期限を確認し、待つか所有者と調整する。" },
415
+ { code: "REMOTE_SHELL_REQUIRED", when: "thread-shellで--shellか--threadがない", action: "--shell powershell|posixと--thread <THREAD>を明示する。" },
416
+ C_E_REMOTE_SHELL_TASK_BUSY,
417
+ { code: "REMOTE_COMMAND_UNKNOWN", when: "pairedのrunで完了を確認できない(error.lease_retained:true)", action: "リースは期限まで保持される。同じコマンドを再実行・競合実行せず、接続先で結果を確かめる。" },
418
+ { code: "CANCELLED", when: "pairedのrunで、コマンドを接続先へ送る前にリースの自動更新が失敗して取り消された。コマンドは実行していない", action: "statusでリースを確かめ、acquireできる状態になってから実行し直す。" },
419
+ { code: "RESOURCE_NOT_OWNED", when: "renew・releaseのtokenがリースを所有していない(期限切れ・解放済み・別の所有者・tokenの誤り)", action: "他の所有者のリースは消えていない。statusで現状を確かめ、必要ならacquireし直す。" },
420
+ { code: "SUPERVISOR_CONTROL_FORBIDDEN", when: "--supervisor付きで--threadを指定しなかった", action: "生成された本文のとおり、担当タスクを--threadで指定する。" },
421
+ { ...SUPERVISOR_PAUSED, when: "pause中の監督がacquire・renew・runを実行した。", action: "実行しない。status・list・releaseは使える。resumeはユーザーだけが行い、監督は自分で解除しない。" },
422
+ SUPERVISOR_STOPPED,
423
+ OPTIONS_INVALID,
424
+ C_E_RECORD_BUSY,
425
+ STORE_UNSAFE,
426
+ ],
427
+ examples: [
428
+ "codexteer resource acquire screen --owner claude-code --ttl-ms 120000 --condition 'ユーザーが今回の2分間の画面利用を許可済み' --json",
429
+ "codexteer resource run unity-project-a --owner codex --ttl-ms 600000 --json -- npm test",
430
+ "codexteer resource release screen --token <TOKEN> --json",
431
+ ],
432
+ notes: [
433
+ "同じCODEX_HOMEで同じ資源名を使う参加者間だけの協調用リース。OSの画面やUnity自体はロックしない。",
434
+ "tokenはstatus・listにも表示される。所有の取り違え防止用で、秘密や認可ではない。",
435
+ "acquireしたリースはプロセス終了後も期限まで残る。tokenでrenew・releaseする。",
436
+ "tokenが一致しないrenew・releaseはRESOURCE_NOT_OWNEDで失敗し、新しい所有者のリースを消さない。期限切れのリースはrenewできず、acquireし直す。",
437
+ "runは取得してからttlの1/3ごとに自動更新し、コマンド終了時に解放する。",
438
+ "runの自動更新に失敗したら、自分が起動したコマンドを終了してlease_errorを返す。",
439
+ "runのコマンドはシェル展開せず引数どおりに実行する。",
440
+ "runを実行したcodexteerが異常終了するとリースは期限まで残る。期限後に再取得できる。",
441
+ "--conditionは許可済み条件の記録。入力アイドルや取得成功だけで画面利用の許可を作らない。",
442
+ C_OUTPUT_TAIL,
443
+ C_LOCAL_FOR_CLOUD,
444
+ "pairedのrunは接続先で実行する。",
445
+ C_PAIRED_SHELL,
446
+ "resourceのthread-shellでは--threadで対象チャットを指定する。",
447
+ C_NO_AUTO_SWITCH,
448
+ "--supervisor付きでは全サブコマンドで監督の登録を確認し、SUPERVISOR_STOPPED・SUPERVISOR_MISMATCH・SUPERVISOR_NOT_REGISTEREDなどで拒否する。",
449
+ "pause中の監督はacquire・renew・runをSUPERVISOR_PAUSEDで拒否される(--exec-backendによらない)。status・list・releaseはできる。",
450
+ "実行を始めたrunのコマンドはpause・stopでは止まらない。",
451
+ C_INTERRUPTED_RUN,
452
+ C_REMOTE_DOC,
453
+ ],
454
+ see: ["checkpoint", "remote", "supervise"],
455
+ },
456
+
457
+ diff: {
458
+ title: "Codex Cloudタスクのサーバー記録済み差分(パッチ)を表示する",
459
+ when: "Cloudタスクの成果を差分で確認するとき。ローカルへは適用しない。Desktop Cloud(durable_)は未対応で、read --include-outputのファイル変更イベントを見る。",
460
+ usage: [
461
+ "diff <CLOUD_TASK_ID|URL> [--attempt 1..4] [--timeout-ms N]",
462
+ ],
463
+ options: [
464
+ { name: "CLOUD_TASK_ID|URL", text: "task_で始まるIDか、https://chatgpt.com/codex/tasks/のリンク。" },
465
+ { name: "--attempt 1..4", default: "公式CLIの既定の試行", text: "表示する試行。失敗しても他の試行へ切り替えない。" },
466
+ { name: "--timeout-ms N", default: "120000", text: "1000〜600000。" },
467
+ ],
468
+ returns: "--jsonはdiff(パッチ文字列かnull)・diff_available・attempt・attempt_selection(official-cli-default/explicit)・task_id・url。パッチがなければdiff:null・diff_available:false・reason:no-server-recorded-patch・local_changes:unknown。テキストは公式CLIの差分をそのまま標準出力へ出す(パッチなしは標準エラーに案内を出して終了コード0)。",
469
+ errors: [
470
+ { code: "CLOUD_CLI_UNAVAILABLE", when: "PATHのcodexを起動できない", action: "公式Codex CLIをインストールする。代替手段への自動切替はしない。" },
471
+ { code: "CLOUD_CLI_UNSUPPORTED", when: "公式CLIが0.157.1未満、またはcodex cloud diff --attemptを持たない", action: "公式Codex CLIを更新する。" },
472
+ { code: "CLOUD_CLI_FAILED", when: "公式CLIが失敗した(--attempt指定時はパッチがない場合もこれになり得る)。生の診断は出さない", action: "公式CLIのログインと環境へのアクセスを確認する。--attemptを外すとパッチなしかを判定できる。" },
473
+ { code: "CLOUD_TIMEOUT", when: "--timeout-ms内に終わらなかった", action: "--timeout-msを延ばして再実行する(最大600000)。" },
474
+ { code: "CLOUD_OUTPUT_LIMIT", when: "出力が16 MiBを超えた", action: "openでブラウザから確認する。" },
475
+ { code: "CLOUD_OPTIONS_INVALID", when: "タスクID、--attempt、--timeout-msの形式・範囲が不正", action: "値を直して再実行する。" },
476
+ { code: "CAPABILITY_UNVERIFIED", when: "Desktop CloudのID・リンクを指定した", action: "read <THREAD> --include-outputのファイル変更イベントで確認する。" },
477
+ { code: "OPTIONS_INVALID", when: "ローカルUUID・codex://threadsリンク・リモートDesktopのタスクを指定した(--host・--connection desktopを含む)。接続も送信もしていない", action: "diffは使わない。read <THREAD> --include-outputのコマンド結果とファイル変更イベントで確かめる。" },
478
+ ],
479
+ examples: [
480
+ "codexteer diff task_example --json",
481
+ "codexteer diff task_example --attempt 1 --json",
482
+ ],
483
+ notes: [
484
+ "diff_available:falseは変更ゼロの証明ではない。作業コピーの変更はread --include-outputのコマンド結果で確かめる。",
485
+ "diff_available:falseになるのは、--attempt省略時に公式CLIがパッチなしで終わり、終了済みタスクに差分・PRの出力がないと確認できた場合だけ。",
486
+ "公式codex cloud diffを非公開の一時ディレクトリで実行し、生の診断や標準エラーは表示しない。",
487
+ "ChatGPTログインなどCloud共通の前提と認証エラーはhelp cloud。",
488
+ "Web Cloud以外のタスク(ローカル・リモートDesktop)はOPTIONS_INVALIDで拒否し、接続も送信もしない。",
489
+ ],
490
+ see: ["cloud", "read", "open"],
491
+ },
492
+ };