@quolu/lattice 0.52.2 → 0.52.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (134) hide show
  1. package/package.json +1 -1
  2. package/src/artifact-contracts-v2.mjs +325 -325
  3. package/src/artifact-contracts.mjs +895 -895
  4. package/src/boundary-compiler.mjs +712 -712
  5. package/src/boundary-observation-compiler-v2.mjs +344 -344
  6. package/src/bounded-seam.mjs +230 -230
  7. package/src/bridge-address.mjs +107 -107
  8. package/src/bridge-cli.mjs +297 -297
  9. package/src/bridge-config.mjs +346 -346
  10. package/src/bridge-daemon.mjs +378 -378
  11. package/src/bridge-hub-protocol.mjs +198 -0
  12. package/src/bridge-launch-agent.mjs +323 -323
  13. package/src/bridge-registrar.mjs +102 -102
  14. package/src/bridge-server.mjs +376 -376
  15. package/src/cli-help.mjs +308 -308
  16. package/src/cli-stdio.mjs +40 -40
  17. package/src/control-compiler.mjs +532 -532
  18. package/src/dag-chain.mjs +261 -261
  19. package/src/factory-diagnostics.mjs +188 -188
  20. package/src/git-process.mjs +72 -0
  21. package/src/hash-chain.mjs +76 -76
  22. package/src/hooks-cli.mjs +1057 -1057
  23. package/src/isolation-runner.mjs +409 -409
  24. package/src/node-version-guard.mjs +44 -44
  25. package/src/project-cli.mjs +699 -697
  26. package/src/project-identity.mjs +130 -130
  27. package/src/rc1-black-box-oracle.mjs +906 -906
  28. package/src/rc1-comparison.mjs +154 -154
  29. package/src/rc1-evidence-bundle.mjs +456 -456
  30. package/src/rc1-v4-campaign.mjs +708 -708
  31. package/src/rc1-v4-transform.mjs +467 -467
  32. package/src/rc1-v5-artifact-set.mjs +855 -855
  33. package/src/rc1-v5-behavior-evidence.mjs +594 -594
  34. package/src/rc1-v5-campaign.mjs +797 -797
  35. package/src/rc1-v5-transform.mjs +421 -421
  36. package/src/rc1-v6-artifact-set.mjs +807 -807
  37. package/src/rc1-v6-behavior-evidence.mjs +273 -273
  38. package/src/rc1-v6-campaign.mjs +623 -623
  39. package/src/rc1-v6-causal-binding.mjs +473 -473
  40. package/src/rc1-v6-measurement.mjs +313 -313
  41. package/src/rc2-artifact-set.mjs +1584 -1584
  42. package/src/rc2-campaign.mjs +1506 -1506
  43. package/src/rc2-delivery-policy-front-end.mjs +1079 -1079
  44. package/src/rc2-delivery-policy-oracle.mjs +134 -134
  45. package/src/rc2-delivery-policy-transform.mjs +1127 -1127
  46. package/src/rc2-rc1-transfer-front-end.mjs +511 -511
  47. package/src/rc3-actual-dogfood.mjs +652 -652
  48. package/src/rc3-dogfood-scaffold.mjs +315 -315
  49. package/src/rc3-scripted-campaign.mjs +1383 -1383
  50. package/src/rc4-stage1-dogfood.mjs +673 -673
  51. package/src/runtime-adapter-registry.mjs +524 -524
  52. package/src/runtime-cli.mjs +4588 -4588
  53. package/src/runtime-contracts.mjs +824 -824
  54. package/src/runtime-control-store.mjs +604 -604
  55. package/src/runtime-controller-protocol.mjs +587 -587
  56. package/src/runtime-decision-verifier.mjs +701 -701
  57. package/src/runtime-diff-observer.mjs +361 -361
  58. package/src/runtime-direct-os-observer.mjs +301 -301
  59. package/src/runtime-driver-state.mjs +166 -166
  60. package/src/runtime-engine.mjs +779 -779
  61. package/src/runtime-errors.mjs +356 -356
  62. package/src/runtime-event-store.mjs +189 -189
  63. package/src/runtime-front-end.mjs +925 -925
  64. package/src/runtime-gate-store.mjs +481 -481
  65. package/src/runtime-hold-recompile.mjs +916 -916
  66. package/src/runtime-io-sentinel.mjs +391 -391
  67. package/src/runtime-lifecycle-lock.mjs +294 -294
  68. package/src/runtime-managed-supervisor.mjs +1490 -1490
  69. package/src/runtime-multi-epoch-store.mjs +838 -838
  70. package/src/runtime-projection.mjs +269 -269
  71. package/src/runtime-pull-intake.mjs +1192 -1192
  72. package/src/runtime-scripted-adapter-controller.mjs +1160 -1160
  73. package/src/runtime-scripted-executor.mjs +163 -163
  74. package/src/runtime-scripted-worktree.mjs +104 -104
  75. package/src/runtime-seam-resolve.mjs +428 -428
  76. package/src/runtime-seam-treatment.mjs +173 -173
  77. package/src/runtime-socket-owner.mjs +125 -125
  78. package/src/runtime-work-order-contracts.mjs +91 -91
  79. package/src/runtime-work-order-controller.mjs +1171 -1171
  80. package/src/runtime-worktree-executor.mjs +199 -199
  81. package/src/schedulability-compiler-v2.mjs +303 -303
  82. package/src/schedulability-verifier-v2.mjs +317 -317
  83. package/src/seam-apply.mjs +549 -549
  84. package/src/seam-commit-shared.mjs +22 -22
  85. package/src/seam-commit-transform.mjs +81 -81
  86. package/src/seam-commit.mjs +18 -18
  87. package/src/seam-cost.mjs +322 -322
  88. package/src/seam-derivation.mjs +188 -188
  89. package/src/seam-gate.mjs +146 -146
  90. package/src/seam-proposal-contracts.mjs +446 -446
  91. package/src/seam-proposal-queries.mjs +521 -521
  92. package/src/seam-proposal.mjs +2011 -2011
  93. package/src/seam-ref.mjs +33 -33
  94. package/src/seam-rewrite.mjs +286 -286
  95. package/src/seam-transform.mjs +554 -554
  96. package/src/seam-verification.mjs +260 -260
  97. package/src/sensor-adapter.mjs +432 -432
  98. package/src/sensor-cli.mjs +139 -139
  99. package/src/sensor-diff.mjs +661 -661
  100. package/src/sensor-node-runtime.mjs +53 -53
  101. package/src/sensor-runtime.mjs +52 -52
  102. package/src/timestamp-contract.mjs +8 -8
  103. package/src/todo-audit-pending.mjs +91 -91
  104. package/src/todo-chain.mjs +178 -178
  105. package/src/todo-cli.mjs +3143 -3141
  106. package/src/todo-contracts.mjs +728 -728
  107. package/src/todo-dashboard-registry.mjs +573 -573
  108. package/src/todo-dispatch-shape.mjs +190 -190
  109. package/src/todo-gantt-html-independence.mjs +239 -239
  110. package/src/todo-gantt-html-shared.mjs +226 -226
  111. package/src/todo-gantt-html-style.mjs +131 -131
  112. package/src/todo-gantt-html.mjs +248 -248
  113. package/src/todo-gantt-layout.mjs +974 -974
  114. package/src/todo-gantt-live.mjs +361 -361
  115. package/src/todo-gantt-nested.mjs +263 -263
  116. package/src/todo-gantt-presentation.mjs +217 -217
  117. package/src/todo-gantt-scope.mjs +123 -123
  118. package/src/todo-gantt-svg.mjs +353 -353
  119. package/src/todo-independence-contracts.mjs +595 -595
  120. package/src/todo-independence-guidance.mjs +322 -322
  121. package/src/todo-independence.mjs +640 -640
  122. package/src/todo-markdown-renderer.mjs +260 -260
  123. package/src/todo-migration.mjs +448 -448
  124. package/src/todo-narrative-anchor.mjs +130 -130
  125. package/src/todo-note-store.mjs +629 -629
  126. package/src/todo-parallel-candidates.mjs +114 -114
  127. package/src/todo-revision.mjs +995 -995
  128. package/src/todo-split.mjs +472 -472
  129. package/src/todo-status.mjs +690 -690
  130. package/src/todo-store-git-transaction.mjs +418 -418
  131. package/src/todo-store.mjs +4360 -4322
  132. package/src/treatment-compiler.mjs +728 -728
  133. package/src/treatment-runner.mjs +656 -656
  134. package/src/witness-scaffold.mjs +180 -180
package/src/cli-help.mjs CHANGED
@@ -1,308 +1,308 @@
1
- import { TODO_INDEPENDENCE_WORKFLOW } from './todo-independence-guidance.mjs';
2
-
3
- const ROOT_HELP = `Usage: lattice <command> [options]
4
-
5
- Commands:
6
- status --json Discover the current project and next action
7
- session-context --json Session開始時の現在地を1プロセスで返す(工程状態+並列可否)
8
- plan <command> Create, compile, or verify plans
9
- run <command> Start or observe compiled runs
10
- event verify Verify a runtime event log
11
- todo <command> Read and update the canonical TODO store
12
- sensor <command> Initialize or synchronize the bundled sensor
13
- factory-diagnostics --json Check native factory integration
14
- runtime-errors <command> Inspect the local runtime error store
15
- bridge <command> Configure the optional network bridge
16
- hooks <command> Install and run sensor-awareness hooks
17
-
18
- Options:
19
- -h, --help Show help
20
- --version Show the installed version
21
- `;
22
-
23
- const NAMESPACE_HELP = Object.freeze({
24
- plan: `Usage: lattice plan <command> [options]
25
-
26
- Commands:
27
- create --input <file> [--serialization-reviewed]
28
- # 依存グラフがほぼ一直線(serialization_ratioが閾値超)なら一度突き返す。
29
- # 再考した上でなお直列でよいなら --serialization-reviewed を付けて再実行する
30
- create --schema --json # 既定は最新版(v4)のJSON Schemaを返す
31
- create --schema-version <1|2|3|4> --json
32
- show <plan_key> --json # task・依存・phase・状態をplan本体から1コマンドで投影する
33
- compile --request <request.json>
34
- compile --schema --json # lattice.run_request.v1 の JSON Schema を出す
35
- verify --request <request.json> --plan <plan.json>
36
- `,
37
- run: `Usage: lattice run <command> [options]
38
-
39
- Commands:
40
- start --request <request.json> --executor <adapter>
41
- start --selection pull --id <id> --plan <key> --equipment detached-worktree
42
- start --schema --json # lattice.run_request.v1 の JSON Schema を出す
43
- intake --run .lattice/runs/<id> --task <task_id>
44
- intake release --run .lattice/runs/<id> --task <task_id>
45
- intake attach --run .lattice/runs/<id> --task <task_id> --input <worker.json>
46
- intake intervention --run .lattice/runs/<id> --task <task_id>
47
- intake accept --run .lattice/runs/<id> --task <task_id>
48
- adapter register --input <descriptor.json>
49
- adapter register --schema --json # 登録入力の JSON Schema を出す
50
- adapter list --json
51
- activate --run .lattice/runs/<id>
52
- # 全waveが完了するまで戻らないforeground driver。別processのobserve/statusは
53
- # driver_stateとwaiting_onで、駆動中か・何を待っているかを投影する。
54
- observe --run .lattice/runs/<id>
55
- status --run .lattice/runs/<id>
56
- landing --run .lattice/runs/<id>
57
- resume --run .lattice/runs/<id>
58
- close --run .lattice/runs/<id>
59
- abandon --run .lattice/runs/<id> --reason <reason>
60
- list --json
61
- seam profile --run .lattice/runs/<id> --finding <digest> --input <symbols.json>
62
- # 記録済みfindingの切断コスト内訳を投影する(read-only)。変換を試す前の安い観測で、
63
- # 入力は {"concern_symbols": {"T1": ["symbol"], ...}}。閾値も可否判定も返さない。
64
- seam resolve --run .lattice/runs/<id> --finding <digest> --input <request.json>
65
- # 記録済み競合を隔離worktreeで実際に変換し、五条件を通ればseam splitと後継baseを返す。
66
- # 入力(lattice.runtime_seam_request.v1)へ書くのは、係争fileの中で各TODOが触るsymbolと
67
- # 新しい面の名前だけ。branchは動かさないので、後継baseへ進めるかは呼び出し側が決める。
68
- `,
69
- event: `Usage: lattice event verify --run .lattice/runs/<id>
70
- `,
71
- todo: `Usage: lattice todo <command> [options]
72
-
73
- Read commands:
74
- status [--json]
75
- show --plan <key> --task <id> --json # 個別ToDoと最新bounded note contextを追加操作なしで返す
76
- note list --plan <key> [--task <id>] --json # note全履歴の診断面(通常read/startでは不要)
77
- bindings [--plan <key>] [--json] # compile_binding付きTaskをTODO identityつきで投影する
78
- independence [--plan <key>] [--json] # readyを検証済み並列・要直列・未検査へ分けて投影する
79
- seam-profile --plan <key> --file <path> [--json] # 係争fileの切断コスト内訳を投影する(read-only)
80
- seam-proposal [--plan <key>] [--json] # 記録済みseam提案をsensor無しで投影する
81
- verify [--plan <key>] [--json]
82
- snapshot --rebuild --plan <key>
83
- gantt serve --port <port> [--scope live|all] # 動的表示。静的HTML生成とstatusは廃止
84
- phase status --plan <key>
85
-
86
- Write commands:
87
- dashboard adopt --json # 衝突したproject_idの配信元rootを現在repoへ明示的に移す
88
- dashboard remove <project_id> --json # 登録簿から1件外す(対象repoの外からも叩ける)
89
- note --plan <key> [--task <id>] (--message <text>|--input <file>)
90
- # ToDoへ作業継続に必要な方針・調査結果・注意をappend-onlyで追記する
91
- migrate --input <extraction.json> [--serialization-reviewed]
92
- migrate --input <extraction.json> --dry-run --json [--serialization-reviewed]
93
- # 既存storeへplanを追加する(plan createは空store初期化専用)。
94
- # 依存グラフがほぼ一直線なら一度突き返し、再考後の --serialization-reviewed で通す
95
- start --plan <key> --task <id> [--parallel-frontier|--override-reason <text> [--serial-confirmed]]
96
- # 既定は全ready同時dispatch。直列にするには理由の申告後、再考を経て --serial-confirmed が要る
97
- block --plan <key> --task <id> --reason <text>
98
- unblock --plan <key> --task <id>
99
- done --plan <key> --task <id> --evidence <file>
100
- reopen --plan <key> --task <id> --reason <text> [--override-reason <text>]
101
- evidence promote --plan <key> --task <id> --evidence <file>
102
- dependency connect --from-plan <key> --from-task <id> --to-plan <key> --to-task <id> --reason <text>
103
- # 開発中に発見したplan跨ぎ依存を明示接続する。依存の自動推定は行わない
104
- independence compile --plan <key> --input <file> # witness setとsensorから並列可否を記録する
105
- independence witness migrate --plan <key> # revision後の宣言をtask migrationで写す
106
- independence witness scaffold --plan <key> --input <draft> # 下書きとfresh観測から宣言を書き出す
107
- seam-proposal compile --plan <key> # 並列可否記録と実sensorからseam提案を記録する
108
- seam-proposal apply --plan <key> # 記録済み提案を隔離worktreeで適用し五条件で採否を決める
109
- seam-proposal land --plan <key> --names <file> # 採用された変換を本ツリーへ着地させる
110
- split --plan <key> --input <file> # in-progress ToDoを抽出群とpending残差へrevisionする
111
- revise --plan <key> --input <file>
112
- revise-phase --plan <key> --input <file>
113
- revise-set --input <file>
114
- <revise|revise-phase|revise-set|migrate> --schema --json
115
- # 実際に受理する最新契約のJSON Schemaを返す(storeを読まない)。
116
- # 入力が契約に合わないときは、違反フィールドのpathがerror detailへ載る
117
- phase review --plan <key> --phase <id> --reason <text>
118
- phase <accept|reject> --plan <key> --phase <id> --input <file>
119
- phase reopen --plan <key> --phase <id> --reason <text> [--override-reason <text>]
120
- phase close-unaudited --plan <key> --phase <id> --reason <text>
121
- # 監査せず「監査なしで閉じた」として明示的に閉じる(ADR 0148)。前提はgate_readyで、
122
- # acceptedへは化けない(phase_accept_dependenciesを解錠しない)
123
- phase baseline --reason <text> [--except <plan_key>]...
124
- # 現在gate_readyかつphase eventを1つも持たないPhaseを一括でclosed_unauditedへ宣言する。
125
- # 自動実行はしない(明示コマンドのみ)。--exceptで指定したplanは対象から除外する
126
-
127
- Write commands require LATTICE_TODO_ACTOR_HOST, LATTICE_TODO_ACTOR_SESSION,
128
- and LATTICE_TODO_ACTOR_AGENT.
129
-
130
- storeだけを書き換えるcommandの末尾へ--commit-storeを付けると、共有Git lockを取得し、
131
- 生じた.lattice/todoの変更だけをcommitしてreceiptを返す。
132
- dirtyなsourceとstore外の既存stageは保持し、store自身がdirtyなら拒否する。
133
- ignoredな再生成artifactだけを作るindependence/seam-proposal compileは対象外。
134
-
135
- 並列可否(依存線の不在は、書き込み境界が干渉しないことを意味しない):
136
- ${TODO_INDEPENDENCE_WORKFLOW.join('\n')}
137
-
138
- 判定していない工程は「競合が無い」ではなく「未検査」として扱われ、
139
- todo startのadvisoryとtodo independenceの投影が、その状況と次の一歩を返す。
140
- `,
141
- sensor: `Usage: lattice sensor <init|sync> [path] --json
142
- lattice sensor diff <rootA> <rootB> [options] --json
143
-
144
- diff options:
145
- --subtree-a <rel> # A側をこの部分木だけに絞り、prefixを剥がしてから突き合わせる
146
- --subtree-b <rel> # B側の同上(例: Latticeのsensor/とupstreamのrootを揃える)
147
- --map-a <from>=<to> # A側のpath改名写像。繰り返し可(最長prefix一致で1回だけ適用)
148
- --map-b <from>=<to> # B側の同上
149
- --limit <n> # 明細1覧あたりの上限(既定200・0で無制限)。切った量はtruncationへ出る
150
-
151
- 突き合わせは行番号を含まない自然キー(kind|path|qualified_name|name)で行う。node idは
152
- 行番号を含むので、idで比べると数行のズレが全て偽の追加+削除になる。辺も端点を自然キーへ
153
- 解決してから比べる。比較できなかった辺(端点がsubtree外・index不整合)はexcludedへ件数で出る。
154
- 両側のextraction versionが違う時はcomparability.statusがdegradedになる——その差分は
155
- codeの変化だけを意味しない。
156
- `,
157
- 'factory-diagnostics': `Usage: lattice factory-diagnostics --json
158
- `,
159
- 'runtime-errors': `Usage: lattice runtime-errors <command> --json
160
-
161
- Commands:
162
- snapshot [--after-cursor <n>] [--limit <n>]
163
- ack <cursor>
164
- diagnostics
165
- resolve <fingerprint>
166
- reopen <fingerprint>
167
- compact
168
- `,
169
- bridge: `Usage: lattice bridge <command> [options] --json
170
-
171
- Commands:
172
- setup --listen <IP> [--port <49152..65535|auto>] [--dashboard|--upstream <URL>] [--allow-host <host>...]
173
- reconfigure [--listen <IP>] [--port <49152..65535|auto>] [--dashboard|--upstream <URL>] [--allow-host <host>...]
174
- status
175
- disable
176
- register # 現在のlisten portをreverse proxy hostへ自己登録する
177
-
178
- registerはLATTICE_BRIDGE_REGISTRAR_SSH_HOSTとLATTICE_BRIDGE_REGISTRAR_SCRIPTが
179
- 両方設定されている時だけ動く。アドレスは送らず、remote側がssh送信元から決める。
180
- `,
181
- hooks: `Usage: lattice hooks <install|status|uninstall|emit> --host <claude|codex>
182
- `,
183
- });
184
-
185
- const SUBCOMMAND_USAGE = Object.freeze({
186
- status: 'status --json',
187
- 'session-context': 'session-context --json',
188
- 'plan create': 'plan create --input <file> [--serialization-reviewed] | --schema --json | --schema-version <1|2|3|4> --json',
189
- 'plan show': 'plan show <plan_key> --json',
190
- 'plan compile': 'plan compile --request <request.json> | --schema --json',
191
- 'plan verify': 'plan verify --request <request.json> --plan <plan.json>',
192
- 'run start': 'run start --request <request.json> --executor <adapter>'
193
- + ' | --selection pull --id <id> --plan <key> --equipment detached-worktree | --schema --json',
194
- 'run intake': 'run intake --run .lattice/runs/<id> --task <task_id>',
195
- 'run intake release': 'run intake release --run .lattice/runs/<id> --task <task_id>',
196
- 'run intake attach': 'run intake attach --run .lattice/runs/<id> --task <task_id> --input <worker.json>',
197
- 'run intake intervention': 'run intake intervention --run .lattice/runs/<id> --task <task_id>',
198
- 'run intake accept': 'run intake accept --run .lattice/runs/<id> --task <task_id>',
199
- 'run adapter register': 'run adapter register --input <descriptor.json> | --schema --json',
200
- 'run adapter list': 'run adapter list --json',
201
- 'run observe': 'run observe --run .lattice/runs/<id>',
202
- 'run status': 'run status --run .lattice/runs/<id>',
203
- 'run resume': 'run resume --run .lattice/runs/<id>',
204
- 'run landing': 'run landing --run .lattice/runs/<id>',
205
- 'run close': 'run close --run .lattice/runs/<id>',
206
- 'run abandon': 'run abandon --run .lattice/runs/<id> --reason <reason>',
207
- 'run list': 'run list --json',
208
- 'run activate': 'run activate --run .lattice/runs/<id>\n\n'
209
- + '全waveが完了するまで戻らないforeground driver。別processのrun observe/statusは\n'
210
- + 'driver_stateとwaiting_onで、駆動中か・何を待っているかを投影する。',
211
- 'run conflict': 'run conflict --run .lattice/runs/<id> --finding <digest>',
212
- 'run hold': 'run hold --run .lattice/runs/<id> --finding <digest>',
213
- 'run recompile': 'run recompile --run .lattice/runs/<id> --input <recompile-request.json>',
214
- 'run reprocess': 'run reprocess --run .lattice/runs/<id>',
215
- 'run finding record': 'run finding record --run .lattice/runs/<id> --checkpoint <digest> --input <candidate.json>',
216
- 'run seam profile': 'run seam profile --run .lattice/runs/<id> --finding <digest> --input <symbols.json>',
217
- 'run seam resolve': 'run seam resolve --run .lattice/runs/<id> --finding <digest> --input <seam-request.json>',
218
- 'event verify': 'event verify --run .lattice/runs/<id>',
219
- 'todo status': 'todo status [--json]',
220
- 'todo show': 'todo show --plan <key> --task <id> --json',
221
- 'todo note': 'todo note --plan <key> [--task <id>] (--message <text>|--input <file>) | list --plan <key> [--task <id>] --json',
222
- 'todo note list': 'todo note list --plan <key> [--task <id>] --json',
223
- 'todo bindings': 'todo bindings [--plan <key>] [--json]',
224
- 'todo independence': 'todo independence [--plan <key>] [--json] | compile --plan <key> --input <file> | witness migrate --plan <key>',
225
- 'todo seam-profile': 'todo seam-profile --plan <key> --file <path> [--json]',
226
- 'todo seam-proposal': 'todo seam-proposal [--plan <key>] [--json] | compile --plan <key>',
227
- 'todo verify': 'todo verify [--plan <key>] [--json]',
228
- 'todo snapshot': 'todo snapshot --rebuild --plan <key>',
229
- 'todo gantt': 'todo gantt serve --port <port> [--scope live|all] # 動的表示のみ。静的HTML生成は廃止',
230
- 'todo gantt serve': 'todo gantt serve --port <0..65535> [--scope live|all] # loopback動的viewer',
231
- 'todo dashboard': 'todo dashboard adopt --json | remove <project_id> --json'
232
- + ' # 配信元rootの衝突を明示的に解消/登録簿から1件外す',
233
- 'todo dashboard adopt': 'todo dashboard adopt --json # 現在repoをproject_idの配信元として明示採用',
234
- 'todo dashboard remove': 'todo dashboard remove <project_id> --json # 登録簿から1件外す(対象repo不在でも可)',
235
- 'todo phase': 'todo phase <status|review|accept|reject|reopen|close-unaudited> --plan <key> [options]'
236
- + ' | baseline --reason <text> [--except <plan_key>]...',
237
- 'todo phase status': 'todo phase status --plan <key>',
238
- 'todo phase review': 'todo phase review --plan <key> --phase <id> --reason <text>',
239
- 'todo phase accept': 'todo phase accept --plan <key> --phase <id> --input <file>',
240
- 'todo phase reject': 'todo phase reject --plan <key> --phase <id> --input <file>',
241
- 'todo phase reopen': 'todo phase reopen --plan <key> --phase <id> --reason <text> [--override-reason <text>]',
242
- 'todo phase close-unaudited': 'todo phase close-unaudited --plan <key> --phase <id> --reason <text>',
243
- 'todo phase baseline': 'todo phase baseline --reason <text> [--except <plan_key>]...',
244
- 'todo start': 'todo start --plan <key> --task <id> [--parallel-frontier|--override-reason <text>]',
245
- 'todo retract': 'todo retract --plan <key> --task <id> --reason <text>',
246
- 'todo block': 'todo block --plan <key> --task <id> --reason <text>',
247
- 'todo unblock': 'todo unblock --plan <key> --task <id>',
248
- 'todo done': 'todo done --plan <key> --task <id> --evidence <file>',
249
- 'todo reopen': 'todo reopen --plan <key> --task <id> --reason <text> [--override-reason <text>]',
250
- 'todo evidence': 'todo evidence promote --plan <key> --task <id> --evidence <file>',
251
- 'todo evidence promote': 'todo evidence promote --plan <key> --task <id> --evidence <file>',
252
- 'todo dependency': 'todo dependency connect --from-plan <key> --from-task <id> --to-plan <key> --to-task <id> --reason <text>',
253
- 'todo dependency connect': 'todo dependency connect --from-plan <key> --from-task <id> --to-plan <key> --to-task <id> --reason <text>',
254
- 'todo split': 'todo split --plan <key> --input <file>',
255
- 'todo revise': 'todo revise --plan <key> --input <file> | --schema --json',
256
- 'todo revise-phase': 'todo revise-phase --plan <key> --input <file> | --schema --json',
257
- 'todo revise-set': 'todo revise-set --input <file> | --schema --json',
258
- 'todo migrate': 'todo migrate --input <extraction.json> [--serialization-reviewed] | --input <extraction.json> --dry-run --json [--serialization-reviewed] | --schema --json',
259
- 'sensor init': 'sensor init [path] --json',
260
- 'sensor sync': 'sensor sync [path] --json',
261
- 'sensor diff': 'sensor diff <rootA> <rootB> [--subtree-a <rel>] [--subtree-b <rel>]'
262
- + ' [--map-a <from>=<to>] [--map-b <from>=<to>] [--limit <n>] --json',
263
- 'runtime-errors snapshot': 'runtime-errors snapshot [--after-cursor <n>] [--limit <n>] --json',
264
- 'runtime-errors ack': 'runtime-errors ack <cursor> --json',
265
- 'runtime-errors diagnostics': 'runtime-errors diagnostics --json',
266
- 'runtime-errors resolve': 'runtime-errors resolve <fingerprint> --json',
267
- 'runtime-errors reopen': 'runtime-errors reopen <fingerprint> --json',
268
- 'runtime-errors compact': 'runtime-errors compact --json',
269
- 'bridge setup': 'bridge setup --listen <IP> [--port <49152..65535|auto>] [--dashboard|--upstream <URL>] [--allow-host <host>...] --json',
270
- 'bridge reconfigure': 'bridge reconfigure [--listen <IP>] [--port <49152..65535|auto>] [--dashboard|--upstream <URL>] [--allow-host <host>...] --json',
271
- 'bridge status': 'bridge status --json',
272
- 'bridge disable': 'bridge disable --json',
273
- 'bridge register': 'bridge register --json',
274
- 'hooks install': 'hooks install --host <claude|codex>',
275
- 'hooks status': 'hooks status --host <claude|codex>',
276
- 'hooks uninstall': 'hooks uninstall --host <claude|codex>',
277
- 'hooks emit': 'hooks emit --host <claude|codex>',
278
- });
279
-
280
- function requestedNamespace(argv) {
281
- if (argv.length === 2 && ['-h', '--help'].includes(argv[1])) return argv[0];
282
- if (argv.length === 2 && argv[0] === 'help') return argv[1];
283
- return null;
284
- }
285
-
286
- function requestedSubcommand(argv) {
287
- if (argv.length >= 3 && ['-h', '--help'].includes(argv.at(-1))) {
288
- return argv.slice(0, -1).join(' ');
289
- }
290
- if (argv.length >= 3 && argv[0] === 'help') return argv.slice(1).join(' ');
291
- return null;
292
- }
293
-
294
- export function renderCliHelp(argv) {
295
- if (argv.length === 1 && ['-h', '--help', 'help'].includes(argv[0])) return ROOT_HELP;
296
- const subcommand = requestedSubcommand(argv);
297
- if (subcommand !== null) {
298
- const usage = SUBCOMMAND_USAGE[subcommand];
299
- return usage === undefined ? null : `Usage: lattice ${usage}\n`;
300
- }
301
- const namespace = requestedNamespace(argv);
302
- if (namespace === null) return null;
303
- // namespaceを持たない1語コマンド(status等)は、SUBCOMMAND_USAGEへ落ちる。
304
- // 落とさないと「存在するのに使い方を知る手段が無い」コマンドになる。
305
- if (NAMESPACE_HELP[namespace] !== undefined) return NAMESPACE_HELP[namespace];
306
- const usage = SUBCOMMAND_USAGE[namespace];
307
- return usage === undefined ? null : `Usage: lattice ${usage}\n`;
308
- }
1
+ import { TODO_INDEPENDENCE_WORKFLOW } from './todo-independence-guidance.mjs';
2
+
3
+ const ROOT_HELP = `Usage: lattice <command> [options]
4
+
5
+ Commands:
6
+ status --json Discover the current project and next action
7
+ session-context --json Session開始時の現在地を1プロセスで返す(工程状態+並列可否)
8
+ plan <command> Create, compile, or verify plans
9
+ run <command> Start or observe compiled runs
10
+ event verify Verify a runtime event log
11
+ todo <command> Read and update the canonical TODO store
12
+ sensor <command> Initialize or synchronize the bundled sensor
13
+ factory-diagnostics --json Check native factory integration
14
+ runtime-errors <command> Inspect the local runtime error store
15
+ bridge <command> Configure the optional network bridge
16
+ hooks <command> Install and run sensor-awareness hooks
17
+
18
+ Options:
19
+ -h, --help Show help
20
+ --version Show the installed version
21
+ `;
22
+
23
+ const NAMESPACE_HELP = Object.freeze({
24
+ plan: `Usage: lattice plan <command> [options]
25
+
26
+ Commands:
27
+ create --input <file> [--serialization-reviewed]
28
+ # 依存グラフがほぼ一直線(serialization_ratioが閾値超)なら一度突き返す。
29
+ # 再考した上でなお直列でよいなら --serialization-reviewed を付けて再実行する
30
+ create --schema --json # 既定は最新版(v4)のJSON Schemaを返す
31
+ create --schema-version <1|2|3|4> --json
32
+ show <plan_key> --json # task・依存・phase・状態をplan本体から1コマンドで投影する
33
+ compile --request <request.json>
34
+ compile --schema --json # lattice.run_request.v1 の JSON Schema を出す
35
+ verify --request <request.json> --plan <plan.json>
36
+ `,
37
+ run: `Usage: lattice run <command> [options]
38
+
39
+ Commands:
40
+ start --request <request.json> --executor <adapter>
41
+ start --selection pull --id <id> --plan <key> --equipment detached-worktree
42
+ start --schema --json # lattice.run_request.v1 の JSON Schema を出す
43
+ intake --run .lattice/runs/<id> --task <task_id>
44
+ intake release --run .lattice/runs/<id> --task <task_id>
45
+ intake attach --run .lattice/runs/<id> --task <task_id> --input <worker.json>
46
+ intake intervention --run .lattice/runs/<id> --task <task_id>
47
+ intake accept --run .lattice/runs/<id> --task <task_id>
48
+ adapter register --input <descriptor.json>
49
+ adapter register --schema --json # 登録入力の JSON Schema を出す
50
+ adapter list --json
51
+ activate --run .lattice/runs/<id>
52
+ # 全waveが完了するまで戻らないforeground driver。別processのobserve/statusは
53
+ # driver_stateとwaiting_onで、駆動中か・何を待っているかを投影する。
54
+ observe --run .lattice/runs/<id>
55
+ status --run .lattice/runs/<id>
56
+ landing --run .lattice/runs/<id>
57
+ resume --run .lattice/runs/<id>
58
+ close --run .lattice/runs/<id>
59
+ abandon --run .lattice/runs/<id> --reason <reason>
60
+ list --json
61
+ seam profile --run .lattice/runs/<id> --finding <digest> --input <symbols.json>
62
+ # 記録済みfindingの切断コスト内訳を投影する(read-only)。変換を試す前の安い観測で、
63
+ # 入力は {"concern_symbols": {"T1": ["symbol"], ...}}。閾値も可否判定も返さない。
64
+ seam resolve --run .lattice/runs/<id> --finding <digest> --input <request.json>
65
+ # 記録済み競合を隔離worktreeで実際に変換し、五条件を通ればseam splitと後継baseを返す。
66
+ # 入力(lattice.runtime_seam_request.v1)へ書くのは、係争fileの中で各TODOが触るsymbolと
67
+ # 新しい面の名前だけ。branchは動かさないので、後継baseへ進めるかは呼び出し側が決める。
68
+ `,
69
+ event: `Usage: lattice event verify --run .lattice/runs/<id>
70
+ `,
71
+ todo: `Usage: lattice todo <command> [options]
72
+
73
+ Read commands:
74
+ status [--json]
75
+ show --plan <key> --task <id> --json # 個別ToDoと最新bounded note contextを追加操作なしで返す
76
+ note list --plan <key> [--task <id>] --json # note全履歴の診断面(通常read/startでは不要)
77
+ bindings [--plan <key>] [--json] # compile_binding付きTaskをTODO identityつきで投影する
78
+ independence [--plan <key>] [--json] # readyを検証済み並列・要直列・未検査へ分けて投影する
79
+ seam-profile --plan <key> --file <path> [--json] # 係争fileの切断コスト内訳を投影する(read-only)
80
+ seam-proposal [--plan <key>] [--json] # 記録済みseam提案をsensor無しで投影する
81
+ verify [--plan <key>] [--json]
82
+ snapshot --rebuild --plan <key>
83
+ gantt serve --port <port> [--scope live|all] # 動的表示。静的HTML生成とstatusは廃止
84
+ phase status --plan <key>
85
+
86
+ Write commands:
87
+ dashboard adopt --json # 衝突したproject_idの配信元rootを現在repoへ明示的に移す
88
+ dashboard remove <project_id> --json # 登録簿から1件外す(対象repoの外からも叩ける)
89
+ note --plan <key> [--task <id>] (--message <text>|--input <file>)
90
+ # ToDoへ作業継続に必要な方針・調査結果・注意をappend-onlyで追記する
91
+ migrate --input <extraction.json> [--serialization-reviewed]
92
+ migrate --input <extraction.json> --dry-run --json [--serialization-reviewed]
93
+ # 既存storeへplanを追加する(plan createは空store初期化専用)。
94
+ # 依存グラフがほぼ一直線なら一度突き返し、再考後の --serialization-reviewed で通す
95
+ start --plan <key> --task <id> [--parallel-frontier|--override-reason <text> [--serial-confirmed]]
96
+ # 既定は全ready同時dispatch。直列にするには理由の申告後、再考を経て --serial-confirmed が要る
97
+ block --plan <key> --task <id> --reason <text>
98
+ unblock --plan <key> --task <id>
99
+ done --plan <key> --task <id> --evidence <file>
100
+ reopen --plan <key> --task <id> --reason <text> [--override-reason <text>]
101
+ evidence promote --plan <key> --task <id> --evidence <file>
102
+ dependency connect --from-plan <key> --from-task <id> --to-plan <key> --to-task <id> --reason <text>
103
+ # 開発中に発見したplan跨ぎ依存を明示接続する。依存の自動推定は行わない
104
+ independence compile --plan <key> --input <file> # witness setとsensorから並列可否を記録する
105
+ independence witness migrate --plan <key> # revision後の宣言をtask migrationで写す
106
+ independence witness scaffold --plan <key> --input <draft> # 下書きとfresh観測から宣言を書き出す
107
+ seam-proposal compile --plan <key> # 並列可否記録と実sensorからseam提案を記録する
108
+ seam-proposal apply --plan <key> # 記録済み提案を隔離worktreeで適用し五条件で採否を決める
109
+ seam-proposal land --plan <key> --names <file> # 採用された変換を本ツリーへ着地させる
110
+ split --plan <key> --input <file> # in-progress ToDoを抽出群とpending残差へrevisionする
111
+ revise --plan <key> --input <file>
112
+ revise-phase --plan <key> --input <file>
113
+ revise-set --input <file>
114
+ <revise|revise-phase|revise-set|migrate> --schema --json
115
+ # 実際に受理する最新契約のJSON Schemaを返す(storeを読まない)。
116
+ # 入力が契約に合わないときは、違反フィールドのpathがerror detailへ載る
117
+ phase review --plan <key> --phase <id> --reason <text>
118
+ phase <accept|reject> --plan <key> --phase <id> --input <file>
119
+ phase reopen --plan <key> --phase <id> --reason <text> [--override-reason <text>]
120
+ phase close-unaudited --plan <key> --phase <id> --reason <text>
121
+ # 監査せず「監査なしで閉じた」として明示的に閉じる(ADR 0148)。前提はgate_readyで、
122
+ # acceptedへは化けない(phase_accept_dependenciesを解錠しない)
123
+ phase baseline --reason <text> [--except <plan_key>]...
124
+ # 現在gate_readyかつphase eventを1つも持たないPhaseを一括でclosed_unauditedへ宣言する。
125
+ # 自動実行はしない(明示コマンドのみ)。--exceptで指定したplanは対象から除外する
126
+
127
+ Write commands require LATTICE_TODO_ACTOR_HOST, LATTICE_TODO_ACTOR_SESSION,
128
+ and LATTICE_TODO_ACTOR_AGENT.
129
+
130
+ storeだけを書き換えるcommandの末尾へ--commit-storeを付けると、共有Git lockを取得し、
131
+ 生じた.lattice/todoの変更だけをcommitしてreceiptを返す。
132
+ dirtyなsourceとstore外の既存stageは保持し、store自身がdirtyなら拒否する。
133
+ ignoredな再生成artifactだけを作るindependence/seam-proposal compileは対象外。
134
+
135
+ 並列可否(依存線の不在は、書き込み境界が干渉しないことを意味しない):
136
+ ${TODO_INDEPENDENCE_WORKFLOW.join('\n')}
137
+
138
+ 判定していない工程は「競合が無い」ではなく「未検査」として扱われ、
139
+ todo startのadvisoryとtodo independenceの投影が、その状況と次の一歩を返す。
140
+ `,
141
+ sensor: `Usage: lattice sensor <init|sync> [path] --json
142
+ lattice sensor diff <rootA> <rootB> [options] --json
143
+
144
+ diff options:
145
+ --subtree-a <rel> # A側をこの部分木だけに絞り、prefixを剥がしてから突き合わせる
146
+ --subtree-b <rel> # B側の同上(例: Latticeのsensor/とupstreamのrootを揃える)
147
+ --map-a <from>=<to> # A側のpath改名写像。繰り返し可(最長prefix一致で1回だけ適用)
148
+ --map-b <from>=<to> # B側の同上
149
+ --limit <n> # 明細1覧あたりの上限(既定200・0で無制限)。切った量はtruncationへ出る
150
+
151
+ 突き合わせは行番号を含まない自然キー(kind|path|qualified_name|name)で行う。node idは
152
+ 行番号を含むので、idで比べると数行のズレが全て偽の追加+削除になる。辺も端点を自然キーへ
153
+ 解決してから比べる。比較できなかった辺(端点がsubtree外・index不整合)はexcludedへ件数で出る。
154
+ 両側のextraction versionが違う時はcomparability.statusがdegradedになる——その差分は
155
+ codeの変化だけを意味しない。
156
+ `,
157
+ 'factory-diagnostics': `Usage: lattice factory-diagnostics --json
158
+ `,
159
+ 'runtime-errors': `Usage: lattice runtime-errors <command> --json
160
+
161
+ Commands:
162
+ snapshot [--after-cursor <n>] [--limit <n>]
163
+ ack <cursor>
164
+ diagnostics
165
+ resolve <fingerprint>
166
+ reopen <fingerprint>
167
+ compact
168
+ `,
169
+ bridge: `Usage: lattice bridge <command> [options] --json
170
+
171
+ Commands:
172
+ setup --listen <IP> [--port <49152..65535|auto>] [--dashboard|--upstream <URL>] [--allow-host <host>...]
173
+ reconfigure [--listen <IP>] [--port <49152..65535|auto>] [--dashboard|--upstream <URL>] [--allow-host <host>...]
174
+ status
175
+ disable
176
+ register # 現在のlisten portをreverse proxy hostへ自己登録する
177
+
178
+ registerはLATTICE_BRIDGE_REGISTRAR_SSH_HOSTとLATTICE_BRIDGE_REGISTRAR_SCRIPTが
179
+ 両方設定されている時だけ動く。アドレスは送らず、remote側がssh送信元から決める。
180
+ `,
181
+ hooks: `Usage: lattice hooks <install|status|uninstall|emit> --host <claude|codex>
182
+ `,
183
+ });
184
+
185
+ const SUBCOMMAND_USAGE = Object.freeze({
186
+ status: 'status --json',
187
+ 'session-context': 'session-context --json',
188
+ 'plan create': 'plan create --input <file> [--serialization-reviewed] | --schema --json | --schema-version <1|2|3|4> --json',
189
+ 'plan show': 'plan show <plan_key> --json',
190
+ 'plan compile': 'plan compile --request <request.json> | --schema --json',
191
+ 'plan verify': 'plan verify --request <request.json> --plan <plan.json>',
192
+ 'run start': 'run start --request <request.json> --executor <adapter>'
193
+ + ' | --selection pull --id <id> --plan <key> --equipment detached-worktree | --schema --json',
194
+ 'run intake': 'run intake --run .lattice/runs/<id> --task <task_id>',
195
+ 'run intake release': 'run intake release --run .lattice/runs/<id> --task <task_id>',
196
+ 'run intake attach': 'run intake attach --run .lattice/runs/<id> --task <task_id> --input <worker.json>',
197
+ 'run intake intervention': 'run intake intervention --run .lattice/runs/<id> --task <task_id>',
198
+ 'run intake accept': 'run intake accept --run .lattice/runs/<id> --task <task_id>',
199
+ 'run adapter register': 'run adapter register --input <descriptor.json> | --schema --json',
200
+ 'run adapter list': 'run adapter list --json',
201
+ 'run observe': 'run observe --run .lattice/runs/<id>',
202
+ 'run status': 'run status --run .lattice/runs/<id>',
203
+ 'run resume': 'run resume --run .lattice/runs/<id>',
204
+ 'run landing': 'run landing --run .lattice/runs/<id>',
205
+ 'run close': 'run close --run .lattice/runs/<id>',
206
+ 'run abandon': 'run abandon --run .lattice/runs/<id> --reason <reason>',
207
+ 'run list': 'run list --json',
208
+ 'run activate': 'run activate --run .lattice/runs/<id>\n\n'
209
+ + '全waveが完了するまで戻らないforeground driver。別processのrun observe/statusは\n'
210
+ + 'driver_stateとwaiting_onで、駆動中か・何を待っているかを投影する。',
211
+ 'run conflict': 'run conflict --run .lattice/runs/<id> --finding <digest>',
212
+ 'run hold': 'run hold --run .lattice/runs/<id> --finding <digest>',
213
+ 'run recompile': 'run recompile --run .lattice/runs/<id> --input <recompile-request.json>',
214
+ 'run reprocess': 'run reprocess --run .lattice/runs/<id>',
215
+ 'run finding record': 'run finding record --run .lattice/runs/<id> --checkpoint <digest> --input <candidate.json>',
216
+ 'run seam profile': 'run seam profile --run .lattice/runs/<id> --finding <digest> --input <symbols.json>',
217
+ 'run seam resolve': 'run seam resolve --run .lattice/runs/<id> --finding <digest> --input <seam-request.json>',
218
+ 'event verify': 'event verify --run .lattice/runs/<id>',
219
+ 'todo status': 'todo status [--json]',
220
+ 'todo show': 'todo show --plan <key> --task <id> --json',
221
+ 'todo note': 'todo note --plan <key> [--task <id>] (--message <text>|--input <file>) | list --plan <key> [--task <id>] --json',
222
+ 'todo note list': 'todo note list --plan <key> [--task <id>] --json',
223
+ 'todo bindings': 'todo bindings [--plan <key>] [--json]',
224
+ 'todo independence': 'todo independence [--plan <key>] [--json] | compile --plan <key> --input <file> | witness migrate --plan <key>',
225
+ 'todo seam-profile': 'todo seam-profile --plan <key> --file <path> [--json]',
226
+ 'todo seam-proposal': 'todo seam-proposal [--plan <key>] [--json] | compile --plan <key>',
227
+ 'todo verify': 'todo verify [--plan <key>] [--json]',
228
+ 'todo snapshot': 'todo snapshot --rebuild --plan <key>',
229
+ 'todo gantt': 'todo gantt serve --port <port> [--scope live|all] # 動的表示のみ。静的HTML生成は廃止',
230
+ 'todo gantt serve': 'todo gantt serve --port <0..65535> [--scope live|all] # loopback動的viewer',
231
+ 'todo dashboard': 'todo dashboard adopt --json | remove <project_id> --json'
232
+ + ' # 配信元rootの衝突を明示的に解消/登録簿から1件外す',
233
+ 'todo dashboard adopt': 'todo dashboard adopt --json # 現在repoをproject_idの配信元として明示採用',
234
+ 'todo dashboard remove': 'todo dashboard remove <project_id> --json # 登録簿から1件外す(対象repo不在でも可)',
235
+ 'todo phase': 'todo phase <status|review|accept|reject|reopen|close-unaudited> --plan <key> [options]'
236
+ + ' | baseline --reason <text> [--except <plan_key>]...',
237
+ 'todo phase status': 'todo phase status --plan <key>',
238
+ 'todo phase review': 'todo phase review --plan <key> --phase <id> --reason <text>',
239
+ 'todo phase accept': 'todo phase accept --plan <key> --phase <id> --input <file>',
240
+ 'todo phase reject': 'todo phase reject --plan <key> --phase <id> --input <file>',
241
+ 'todo phase reopen': 'todo phase reopen --plan <key> --phase <id> --reason <text> [--override-reason <text>]',
242
+ 'todo phase close-unaudited': 'todo phase close-unaudited --plan <key> --phase <id> --reason <text>',
243
+ 'todo phase baseline': 'todo phase baseline --reason <text> [--except <plan_key>]...',
244
+ 'todo start': 'todo start --plan <key> --task <id> [--parallel-frontier|--override-reason <text>]',
245
+ 'todo retract': 'todo retract --plan <key> --task <id> --reason <text>',
246
+ 'todo block': 'todo block --plan <key> --task <id> --reason <text>',
247
+ 'todo unblock': 'todo unblock --plan <key> --task <id>',
248
+ 'todo done': 'todo done --plan <key> --task <id> --evidence <file>',
249
+ 'todo reopen': 'todo reopen --plan <key> --task <id> --reason <text> [--override-reason <text>]',
250
+ 'todo evidence': 'todo evidence promote --plan <key> --task <id> --evidence <file>',
251
+ 'todo evidence promote': 'todo evidence promote --plan <key> --task <id> --evidence <file>',
252
+ 'todo dependency': 'todo dependency connect --from-plan <key> --from-task <id> --to-plan <key> --to-task <id> --reason <text>',
253
+ 'todo dependency connect': 'todo dependency connect --from-plan <key> --from-task <id> --to-plan <key> --to-task <id> --reason <text>',
254
+ 'todo split': 'todo split --plan <key> --input <file>',
255
+ 'todo revise': 'todo revise --plan <key> --input <file> | --schema --json',
256
+ 'todo revise-phase': 'todo revise-phase --plan <key> --input <file> | --schema --json',
257
+ 'todo revise-set': 'todo revise-set --input <file> | --schema --json',
258
+ 'todo migrate': 'todo migrate --input <extraction.json> [--serialization-reviewed] | --input <extraction.json> --dry-run --json [--serialization-reviewed] | --schema --json',
259
+ 'sensor init': 'sensor init [path] --json',
260
+ 'sensor sync': 'sensor sync [path] --json',
261
+ 'sensor diff': 'sensor diff <rootA> <rootB> [--subtree-a <rel>] [--subtree-b <rel>]'
262
+ + ' [--map-a <from>=<to>] [--map-b <from>=<to>] [--limit <n>] --json',
263
+ 'runtime-errors snapshot': 'runtime-errors snapshot [--after-cursor <n>] [--limit <n>] --json',
264
+ 'runtime-errors ack': 'runtime-errors ack <cursor> --json',
265
+ 'runtime-errors diagnostics': 'runtime-errors diagnostics --json',
266
+ 'runtime-errors resolve': 'runtime-errors resolve <fingerprint> --json',
267
+ 'runtime-errors reopen': 'runtime-errors reopen <fingerprint> --json',
268
+ 'runtime-errors compact': 'runtime-errors compact --json',
269
+ 'bridge setup': 'bridge setup --listen <IP> [--port <49152..65535|auto>] [--dashboard|--upstream <URL>] [--allow-host <host>...] --json',
270
+ 'bridge reconfigure': 'bridge reconfigure [--listen <IP>] [--port <49152..65535|auto>] [--dashboard|--upstream <URL>] [--allow-host <host>...] --json',
271
+ 'bridge status': 'bridge status --json',
272
+ 'bridge disable': 'bridge disable --json',
273
+ 'bridge register': 'bridge register --json',
274
+ 'hooks install': 'hooks install --host <claude|codex>',
275
+ 'hooks status': 'hooks status --host <claude|codex>',
276
+ 'hooks uninstall': 'hooks uninstall --host <claude|codex>',
277
+ 'hooks emit': 'hooks emit --host <claude|codex>',
278
+ });
279
+
280
+ function requestedNamespace(argv) {
281
+ if (argv.length === 2 && ['-h', '--help'].includes(argv[1])) return argv[0];
282
+ if (argv.length === 2 && argv[0] === 'help') return argv[1];
283
+ return null;
284
+ }
285
+
286
+ function requestedSubcommand(argv) {
287
+ if (argv.length >= 3 && ['-h', '--help'].includes(argv.at(-1))) {
288
+ return argv.slice(0, -1).join(' ');
289
+ }
290
+ if (argv.length >= 3 && argv[0] === 'help') return argv.slice(1).join(' ');
291
+ return null;
292
+ }
293
+
294
+ export function renderCliHelp(argv) {
295
+ if (argv.length === 1 && ['-h', '--help', 'help'].includes(argv[0])) return ROOT_HELP;
296
+ const subcommand = requestedSubcommand(argv);
297
+ if (subcommand !== null) {
298
+ const usage = SUBCOMMAND_USAGE[subcommand];
299
+ return usage === undefined ? null : `Usage: lattice ${usage}\n`;
300
+ }
301
+ const namespace = requestedNamespace(argv);
302
+ if (namespace === null) return null;
303
+ // namespaceを持たない1語コマンド(status等)は、SUBCOMMAND_USAGEへ落ちる。
304
+ // 落とさないと「存在するのに使い方を知る手段が無い」コマンドになる。
305
+ if (NAMESPACE_HELP[namespace] !== undefined) return NAMESPACE_HELP[namespace];
306
+ const usage = SUBCOMMAND_USAGE[namespace];
307
+ return usage === undefined ? null : `Usage: lattice ${usage}\n`;
308
+ }