otacon 0.1.3 → 0.1.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 (201) hide show
  1. package/README.md +18 -5
  2. package/dist/cli/browser.js +1 -1
  3. package/dist/cli/browser.js.map +1 -1
  4. package/dist/cli/client.js +3 -3
  5. package/dist/cli/client.js.map +1 -1
  6. package/dist/cli/commands/answer.js +1 -1
  7. package/dist/cli/commands/answer.js.map +1 -1
  8. package/dist/cli/commands/ask.js +3 -3
  9. package/dist/cli/commands/ask.js.map +1 -1
  10. package/dist/cli/commands/clean.js +14 -16
  11. package/dist/cli/commands/clean.js.map +1 -1
  12. package/dist/cli/commands/config.js +1 -1
  13. package/dist/cli/commands/config.js.map +1 -1
  14. package/dist/cli/commands/doctor.js +4 -4
  15. package/dist/cli/commands/doctor.js.map +1 -1
  16. package/dist/cli/commands/expose.js +7 -7
  17. package/dist/cli/commands/expose.js.map +1 -1
  18. package/dist/cli/commands/implement-done.js +1 -1
  19. package/dist/cli/commands/implement-done.js.map +1 -1
  20. package/dist/cli/commands/install.js +16 -10
  21. package/dist/cli/commands/install.js.map +1 -1
  22. package/dist/cli/commands/open.js +31 -7
  23. package/dist/cli/commands/open.js.map +1 -1
  24. package/dist/cli/commands/progress.js +1 -1
  25. package/dist/cli/commands/progress.js.map +1 -1
  26. package/dist/cli/commands/resume.js +67 -0
  27. package/dist/cli/commands/resume.js.map +1 -0
  28. package/dist/cli/commands/start.js +18 -4
  29. package/dist/cli/commands/start.js.map +1 -1
  30. package/dist/cli/commands/status.js +15 -4
  31. package/dist/cli/commands/status.js.map +1 -1
  32. package/dist/cli/commands/submit.js +5 -5
  33. package/dist/cli/commands/submit.js.map +1 -1
  34. package/dist/cli/commands/update.js +24 -17
  35. package/dist/cli/commands/update.js.map +1 -1
  36. package/dist/cli/commands/wait.js +1 -1
  37. package/dist/cli/commands/wait.js.map +1 -1
  38. package/dist/cli/install/assets.js +123 -48
  39. package/dist/cli/install/assets.js.map +1 -1
  40. package/dist/cli/install/locations.js +1 -1
  41. package/dist/cli/install/locations.js.map +1 -1
  42. package/dist/cli/install/tailscale.js +2 -2
  43. package/dist/cli/install/tailscale.js.map +1 -1
  44. package/dist/cli/install/wrapper.js +202 -0
  45. package/dist/cli/install/wrapper.js.map +1 -0
  46. package/dist/cli/main.js +5 -2
  47. package/dist/cli/main.js.map +1 -1
  48. package/dist/cli/output.js +2 -2
  49. package/dist/cli/output.js.map +1 -1
  50. package/dist/cli/session.js +18 -7
  51. package/dist/cli/session.js.map +1 -1
  52. package/dist/cli/update.js +79 -38
  53. package/dist/cli/update.js.map +1 -1
  54. package/dist/daemon/activity.js +1 -1
  55. package/dist/daemon/activity.js.map +1 -1
  56. package/dist/daemon/anchor.js +1 -1
  57. package/dist/daemon/anchor.js.map +1 -1
  58. package/dist/daemon/app.js +370 -82
  59. package/dist/daemon/app.js.map +1 -1
  60. package/dist/daemon/approve.js +3 -3
  61. package/dist/daemon/approve.js.map +1 -1
  62. package/dist/daemon/capture/adapter.js +23 -0
  63. package/dist/daemon/capture/adapter.js.map +1 -0
  64. package/dist/daemon/capture/claude.js +274 -0
  65. package/dist/daemon/capture/claude.js.map +1 -0
  66. package/dist/daemon/capture/codex.js +413 -0
  67. package/dist/daemon/capture/codex.js.map +1 -0
  68. package/dist/daemon/capture/normalize.js +89 -0
  69. package/dist/daemon/capture/normalize.js.map +1 -0
  70. package/dist/daemon/capture/opencode.js +330 -0
  71. package/dist/daemon/capture/opencode.js.map +1 -0
  72. package/dist/daemon/capture/registry.js +33 -0
  73. package/dist/daemon/capture/registry.js.map +1 -0
  74. package/dist/daemon/capture/stream-store.js +121 -0
  75. package/dist/daemon/capture/stream-store.js.map +1 -0
  76. package/dist/daemon/capture/tailer.js +108 -0
  77. package/dist/daemon/capture/tailer.js.map +1 -0
  78. package/dist/daemon/desktop-notify.js +11 -5
  79. package/dist/daemon/desktop-notify.js.map +1 -1
  80. package/dist/daemon/diagrams.js +90 -0
  81. package/dist/daemon/diagrams.js.map +1 -0
  82. package/dist/daemon/diff.js +1 -2
  83. package/dist/daemon/diff.js.map +1 -1
  84. package/dist/daemon/linter/parse.js +45 -12
  85. package/dist/daemon/linter/parse.js.map +1 -1
  86. package/dist/daemon/linter/rules.js +20 -17
  87. package/dist/daemon/linter/rules.js.map +1 -1
  88. package/dist/daemon/main.js +1 -1
  89. package/dist/daemon/main.js.map +1 -1
  90. package/dist/daemon/notify.js +1 -1
  91. package/dist/daemon/notify.js.map +1 -1
  92. package/dist/daemon/presence.js +1 -1
  93. package/dist/daemon/presence.js.map +1 -1
  94. package/dist/daemon/queue.js +7 -7
  95. package/dist/daemon/queue.js.map +1 -1
  96. package/dist/daemon/store.js +66 -79
  97. package/dist/daemon/store.js.map +1 -1
  98. package/dist/daemon/threads.js +111 -25
  99. package/dist/daemon/threads.js.map +1 -1
  100. package/dist/daemon/transcript.js +1 -1
  101. package/dist/daemon/transcript.js.map +1 -1
  102. package/dist/daemon/ui.js +8 -6
  103. package/dist/daemon/ui.js.map +1 -1
  104. package/dist/daemon/viewers.js +37 -0
  105. package/dist/daemon/viewers.js.map +1 -0
  106. package/dist/shared/config.js +42 -8
  107. package/dist/shared/config.js.map +1 -1
  108. package/dist/shared/gwt.js +1 -1
  109. package/dist/shared/gwt.js.map +1 -1
  110. package/dist/shared/paths.js +63 -36
  111. package/dist/shared/paths.js.map +1 -1
  112. package/dist/shared/question-spec.js +1 -1
  113. package/dist/shared/question-spec.js.map +1 -1
  114. package/dist/shared/types.js +7 -3
  115. package/dist/shared/types.js.map +1 -1
  116. package/dist/shared/version.js +1 -1
  117. package/dist/skills/otacon/SKILL.md +250 -0
  118. package/dist/ui/assets/{arc-Cp3sPd_U.js → arc-BUR2DxNA.js} +1 -1
  119. package/dist/ui/assets/architecture-7EHR7CIX-TTokq2IO.js +1 -0
  120. package/dist/ui/assets/{architectureDiagram-3BPJPVTR-C4F3heWP.js → architectureDiagram-3BPJPVTR-unLnkDyM.js} +1 -1
  121. package/dist/ui/assets/{blockDiagram-GPEHLZMM-DmJoG8ky.js → blockDiagram-GPEHLZMM-DHx8lNeL.js} +1 -1
  122. package/dist/ui/assets/{c4Diagram-AAUBKEIU-BDEf52Jp.js → c4Diagram-AAUBKEIU-BU9T562l.js} +1 -1
  123. package/dist/ui/assets/channel-BA6ChrT3.js +1 -0
  124. package/dist/ui/assets/{chunk-2J33WTMH-Dh_UFriv.js → chunk-2J33WTMH-BEb0myVl.js} +1 -1
  125. package/dist/ui/assets/{chunk-3OPIFGDE-c66RlAN8.js → chunk-3OPIFGDE-DESBG_RB.js} +1 -1
  126. package/dist/ui/assets/{chunk-4BX2VUAB-CrGJaCCg.js → chunk-4BX2VUAB-dt3F_E_5.js} +1 -1
  127. package/dist/ui/assets/{chunk-55IACEB6-BvwqEeyq.js → chunk-55IACEB6-BcyuZM7U.js} +1 -1
  128. package/dist/ui/assets/{chunk-5ZQYHXKU-BfF2IfQe.js → chunk-5ZQYHXKU-DqdwSJlO.js} +1 -1
  129. package/dist/ui/assets/{chunk-727SXJPM-DOEUwc9I.js → chunk-727SXJPM-B04SqNWj.js} +1 -1
  130. package/dist/ui/assets/{chunk-AQP2D5EJ-CVf2xV2Z.js → chunk-AQP2D5EJ-DpjCPBWN.js} +1 -1
  131. package/dist/ui/assets/{chunk-BSJP7CBP-D_EbTWTC.js → chunk-BSJP7CBP-BNOU3k5G.js} +1 -1
  132. package/dist/ui/assets/{chunk-CSCIHK7Q-CkxTSMAM.js → chunk-CSCIHK7Q-iWOtNZm_.js} +1 -1
  133. package/dist/ui/assets/{chunk-FMBD7UC4-DVShhFc7.js → chunk-FMBD7UC4-BHH_etky.js} +1 -1
  134. package/dist/ui/assets/{chunk-KSCS5N6A-DnHEEYpq.js → chunk-KSCS5N6A-DbRuazP3.js} +1 -1
  135. package/dist/ui/assets/{chunk-L5ZTLDWV-B_gjyajS.js → chunk-L5ZTLDWV-B2ZZFONi.js} +1 -1
  136. package/dist/ui/assets/{chunk-LZXEDZCA-Bsf7basG.js → chunk-LZXEDZCA-DryVpwAh.js} +2 -2
  137. package/dist/ui/assets/{chunk-ND2GUHAM-DGepGb8_.js → chunk-ND2GUHAM-2Bb1izqg.js} +1 -1
  138. package/dist/ui/assets/{chunk-NZK2D7GU-BJIlh-gB.js → chunk-NZK2D7GU-2DhvLbqL.js} +1 -1
  139. package/dist/ui/assets/{chunk-O5CBEL6O-cdVbOOCs.js → chunk-O5CBEL6O-B5oigO7D.js} +1 -1
  140. package/dist/ui/assets/chunk-QZHKN3VN-BDHgdxoT.js +1 -0
  141. package/dist/ui/assets/chunk-WU5MYG2G-FDJTP_wT.js +1 -0
  142. package/dist/ui/assets/{chunk-XPW4576I-DPW39hNO.js → chunk-XPW4576I-Dmq-O7bc.js} +1 -1
  143. package/dist/ui/assets/classDiagram-4FO5ZUOK-B5kZsiIt.js +1 -0
  144. package/dist/ui/assets/classDiagram-v2-Q7XG4LA2-B5kZsiIt.js +1 -0
  145. package/dist/ui/assets/{cose-bilkent-S5V4N54A-DmMsC6om.js → cose-bilkent-S5V4N54A-oTsqU1DY.js} +1 -1
  146. package/dist/ui/assets/{dagre-BM42HDAG-BmVr7T7Z.js → dagre-BM42HDAG-CZykCU6B.js} +1 -1
  147. package/dist/ui/assets/{diagram-2AECGRRQ-e0VnXEyj.js → diagram-2AECGRRQ-BY7clIlO.js} +1 -1
  148. package/dist/ui/assets/{diagram-5GNKFQAL-SCJGYE6m.js → diagram-5GNKFQAL-BWdq4hV0.js} +1 -1
  149. package/dist/ui/assets/{diagram-KO2AKTUF-DDUZO1Mj.js → diagram-KO2AKTUF-CCGEaiZg.js} +1 -1
  150. package/dist/ui/assets/{diagram-LMA3HP47-5x1ypf6a.js → diagram-LMA3HP47-CVkepFYU.js} +1 -1
  151. package/dist/ui/assets/{diagram-OG6HWLK6-3nDhrQ20.js → diagram-OG6HWLK6-f-NjsfLG.js} +1 -1
  152. package/dist/ui/assets/{dist-NEinnePC.js → dist-ZqsueX9_.js} +1 -1
  153. package/dist/ui/assets/{erDiagram-TEJ5UH35-BNvwSDNZ.js → erDiagram-TEJ5UH35-D8Wn6QP3.js} +1 -1
  154. package/dist/ui/assets/eventmodeling-FCH6USID-BODDoY6e.js +1 -0
  155. package/dist/ui/assets/{flowDiagram-I6XJVG4X-Bt_wDUhb.js → flowDiagram-I6XJVG4X-BYnhla9k.js} +1 -1
  156. package/dist/ui/assets/{ganttDiagram-6RSMTGT7-DVcJ0rNX.js → ganttDiagram-6RSMTGT7-Dpu52ZRF.js} +1 -1
  157. package/dist/ui/assets/{gitGraph-WXDBUCRP-CO_SyAgP.js → gitGraph-WXDBUCRP-ou8xzQe1.js} +1 -1
  158. package/dist/ui/assets/{gitGraphDiagram-PVQCEYII-oDyO3lWI.js → gitGraphDiagram-PVQCEYII-BnTuFH7F.js} +1 -1
  159. package/dist/ui/assets/index-B2mL0c61.js +11 -0
  160. package/dist/ui/assets/index-sZ1TgAvb.css +1 -0
  161. package/dist/ui/assets/{info-J43DQDTF-Bn17NS7h.js → info-J43DQDTF-xgUHa7k0.js} +1 -1
  162. package/dist/ui/assets/{infoDiagram-5YYISTIA-HG1opLLT.js → infoDiagram-5YYISTIA-DJBudrwD.js} +1 -1
  163. package/dist/ui/assets/{ishikawaDiagram-YF4QCWOH-Di_yQwi8.js → ishikawaDiagram-YF4QCWOH-DpFHgERI.js} +1 -1
  164. package/dist/ui/assets/{journeyDiagram-JHISSGLW-DZtHvLeE.js → journeyDiagram-JHISSGLW-Cd32hdpY.js} +1 -1
  165. package/dist/ui/assets/{kanban-definition-UN3LZRKU-B_RCx3Km.js → kanban-definition-UN3LZRKU-Dm1V8lr0.js} +1 -1
  166. package/dist/ui/assets/{line-DenX-zXQ.js → line-CZu6_PMX.js} +1 -1
  167. package/dist/ui/assets/{linear-dly_ngoq.js → linear-2tkTX_U2.js} +1 -1
  168. package/dist/ui/assets/{mermaid-parser.core-CRmtm0s9.js → mermaid-parser.core-C4m04cRe.js} +2 -2
  169. package/dist/ui/assets/{mermaid.core-C_3KVfpx.js → mermaid.core-BPeg1ewg.js} +3 -3
  170. package/dist/ui/assets/{mindmap-definition-RKZ34NQL-wdzSyYO6.js → mindmap-definition-RKZ34NQL-BENqEkIK.js} +1 -1
  171. package/dist/ui/assets/{packet-YPE3B663-tUyFmR11.js → packet-YPE3B663-DNO0oBLH.js} +1 -1
  172. package/dist/ui/assets/{pie-LRSECV5Y-Cel48VVp.js → pie-LRSECV5Y-CWoz31oB.js} +1 -1
  173. package/dist/ui/assets/{pieDiagram-4H26LBE5-B55ypWtu.js → pieDiagram-4H26LBE5-CtmxhUGI.js} +1 -1
  174. package/dist/ui/assets/{plan-view-CMoo3_gE.js → plan-view-bZtdFbit.js} +4 -4
  175. package/dist/ui/assets/{quadrantDiagram-W4KKPZXB-9WcKQV0a.js → quadrantDiagram-W4KKPZXB-BO3IZNbx.js} +1 -1
  176. package/dist/ui/assets/{radar-GUYGQ44K-w5pk53Vr.js → radar-GUYGQ44K-AEfROz99.js} +1 -1
  177. package/dist/ui/assets/{requirementDiagram-4Y6WPE33-CzE82fXz.js → requirementDiagram-4Y6WPE33-D-wQ1szT.js} +1 -1
  178. package/dist/ui/assets/{sankeyDiagram-5OEKKPKP-DSGO39je.js → sankeyDiagram-5OEKKPKP-Bj4kD_AJ.js} +1 -1
  179. package/dist/ui/assets/{sequenceDiagram-3UESZ5HK-BKSDDr0S.js → sequenceDiagram-3UESZ5HK-M8QVVH74.js} +1 -1
  180. package/dist/ui/assets/{src-JXBGgRt-.js → src-DvptJAGq.js} +1 -1
  181. package/dist/ui/assets/{stateDiagram-AJRCARHV-DZHYA9aj.js → stateDiagram-AJRCARHV-BiPRs9rN.js} +1 -1
  182. package/dist/ui/assets/stateDiagram-v2-BHNVJYJU-BYjicZlC.js +1 -0
  183. package/dist/ui/assets/{timeline-definition-PNZ67QCA-WqJFw7aE.js → timeline-definition-PNZ67QCA-DS0AGRKw.js} +1 -1
  184. package/dist/ui/assets/{treeView-BLDUP644-DoIQYMiz.js → treeView-BLDUP644-DJakvUbF.js} +1 -1
  185. package/dist/ui/assets/{treemap-LRROVOQU-BA9si_Mo.js → treemap-LRROVOQU-QXfc2Vwr.js} +1 -1
  186. package/dist/ui/assets/{vennDiagram-CIIHVFJN-BvWRUfFr.js → vennDiagram-CIIHVFJN-CBdJA0hv.js} +1 -1
  187. package/dist/ui/assets/{wardley-L42UT6IY-Cf9PU44t.js → wardley-L42UT6IY-DI9SdW45.js} +1 -1
  188. package/dist/ui/assets/{wardleyDiagram-YWT4CUSO-CGuxl7AU.js → wardleyDiagram-YWT4CUSO-RMmsKLRe.js} +1 -1
  189. package/dist/ui/assets/{xychartDiagram-2RQKCTM6-CNteNXpe.js → xychartDiagram-2RQKCTM6-DFXccP8B.js} +1 -1
  190. package/dist/ui/index.html +2 -2
  191. package/package.json +7 -5
  192. package/dist/ui/assets/architecture-7EHR7CIX-BbwstElO.js +0 -1
  193. package/dist/ui/assets/channel-BMK3JFRf.js +0 -1
  194. package/dist/ui/assets/chunk-QZHKN3VN-DLNUTn7U.js +0 -1
  195. package/dist/ui/assets/chunk-WU5MYG2G-ipH3YPcA.js +0 -1
  196. package/dist/ui/assets/classDiagram-4FO5ZUOK-CvIMLlSD.js +0 -1
  197. package/dist/ui/assets/classDiagram-v2-Q7XG4LA2-CvIMLlSD.js +0 -1
  198. package/dist/ui/assets/eventmodeling-FCH6USID-BeFWDbla.js +0 -1
  199. package/dist/ui/assets/index-CJJIQ0dr.css +0 -1
  200. package/dist/ui/assets/index-Dh5CsH24.js +0 -11
  201. package/dist/ui/assets/stateDiagram-v2-BHNVJYJU-DnAfDlvZ.js +0 -1
@@ -1,15 +1,15 @@
1
- // The wrapper content `otacon install` writes (DESIGN.md §16) — this is the
2
- // product-critical text that teaches an agent the whole protocol: the §6 full
3
- // loop, §8 grill discipline, and §13 "never end your turn". One protocol card,
1
+ // The wrapper content `otacon install` writes — this is the product-critical
2
+ // text that teaches an agent the whole protocol: the full review loop, grill
3
+ // discipline, and "never end your turn" rule. One protocol card,
4
4
  // three destinations — Claude Code, Codex, and OpenCode each get it as a
5
- // SKILL.md in their own skills dir. Plus the Stop hook shell script (§13).
5
+ // SKILL.md in their own skills dir. Plus the Stop hook shell script.
6
6
  // Wrappers are managed files: reinstall overwrites them wholesale (DECISIONS.md
7
7
  // "Wrappers are managed files").
8
8
  /** Present in every wrapper this tool owns; doctor greps for it. */
9
9
  export const MANAGED_MARKER = 'managed by `otacon install`';
10
10
  /**
11
- * The protocol card — §6 full loop (start-first) + §8 grill discipline + §13
12
- * failure habits — parametrized by the command prefix so one source feeds both
11
+ * The protocol card — start-first full loop + grill discipline + failure habits
12
+ * — parametrized by the command prefix so one source feeds both
13
13
  * wrappers (D7): `otacon` for what `otacon install` writes into any repo,
14
14
  * `./bin/otacon` for this repo's dogfood (run-from-source). The only thing that
15
15
  * varies between the two is `cmd`; the protocol text is identical, so a change
@@ -21,18 +21,60 @@ user reviews in a browser. Every \`${cmd}\`
21
21
  command prints exactly one JSON line on stdout. Exit 0 = proceed; exit 1 = a
22
22
  machine-readable error you can fix (read the JSON); exit 2 = you invoked it wrong.
23
23
 
24
+ ## Hard implementation gate
25
+
26
+ When this skill is triggered, you MUST NOT create, edit, delete, or format project
27
+ files, run code-modifying commands, or implement the requested change until a
28
+ \`${cmd} wait\` event returns \`{"event":"approved",...,"implement":true}\`.
29
+
30
+ Before that event, allowed actions are only:
31
+ - \`${cmd} start\` / \`${cmd} status\` / \`${cmd} open\` / \`${cmd} progress\` /
32
+ \`${cmd} ask\` / \`${cmd} wait\` / \`${cmd} submit\` / \`${cmd} answer\`.
33
+ - Read-only research commands.
34
+ - Writing the plan and resolutions files under the session's home dir (\`~/.otacon/sessions/<id>/\`, the \`plan\` path \`start\` prints).
35
+
36
+ A user request phrased as "can you make/fix/implement..." is still a plan-review
37
+ request when this skill is active. Approval is not implied by the original request.
38
+
39
+ ## Starting: resume an amendment, or plan fresh
40
+
41
+ Before \`${cmd} start\`, check where you are: run \`${cmd} status\`. If its output
42
+ carries a \`resumeCandidate\`, you are standing inside a build worktree otacon
43
+ created for a finished plan: a chance to AMEND that plan in place instead of
44
+ spawning a second worktree.
45
+
46
+ - Read the candidate plan at \`resumeCandidate.plan\` and judge whether the user's
47
+ request is about THAT feature.
48
+ - **Clearly unrelated** (a different feature) → just \`${cmd} start\` a fresh
49
+ session and ignore the candidate.
50
+ - **Related, or you are unsure** → ask the user, here in the terminal, whether to
51
+ resume and amend the existing plan or start new. This is the ONE question that
52
+ does not go through \`${cmd} ask\` (no session is open yet); wait for the answer
53
+ before acting.
54
+ - On **resume**: \`${cmd} resume\` (it auto-detects the session from this worktree,
55
+ reopens it to \`revising\`, and prints the \`plan\` path). SKIP research and grill,
56
+ since the plan exists. Edit that \`plan\` file into revision N+1 directly from the user's
57
+ request (grill only if it is genuinely ambiguous), \`${cmd} submit\`, then go to
58
+ the **Review loop** (step 5). The review diffs against the approved revision.
59
+ - No \`resumeCandidate\` → the normal flow below.
60
+
24
61
  ## The loop
25
62
 
26
63
  1. \`${cmd} start --title <kebab-title>\` **first, before you research** — it mints
27
- the session and prints the review URL. Tell the user to open it (\`${cmd} open\`
64
+ the session and prints the review URL plus the \`plan\` draft path (under
65
+ \`~/.otacon/sessions/<id>/\`). Tell the user to open the URL (\`${cmd} open\`
28
66
  launches it in their browser) so they can watch the whole thing from the first second.
29
67
  \`--quick\` skips the interview — only when the user explicitly asks.
30
- 2. **Research the codebase**, narrating as you go with
31
- \`${cmd} progress "<what you're doing>"\` call it whenever you start a chunk of
32
- work the user can't otherwise see (reading a module, drafting, revising). It is
33
- a non-blocking one-liner that feeds the live activity log and the draft chip; no
34
- answer comes back, so never park on it. Read enough to propose answers, not
35
- collect questions.
68
+ 2. **Research the codebase.** On supported agents the daemon now auto-streams your
69
+ tool calls, text, and thinking to the reviewer's now-playing console, so it
70
+ already sees the routine work. Use \`${cmd} progress "<what you're doing>"\` for
71
+ OCCASIONAL highlights and chapter markers (a milestone, a phase boundary, "what
72
+ I'm about to do next"), not per-step narration. It is the universal floor: on an
73
+ agent with no auto-capture those notes are the ONLY thing keeping the now-playing
74
+ bar alive, so still drop one whenever you start a chunk of work the user can't
75
+ otherwise see. It is a non-blocking one-liner that feeds the live stream and the
76
+ draft chip; no answer comes back, so never park on it. Read enough to propose
77
+ answers, not collect questions.
36
78
  3. **Grill** (mandatory unless --quick): Interview me relentlessly about every
37
79
  aspect of this plan until we reach a shared understanding. Walk down each branch
38
80
  of the design tree, resolving dependencies between decisions one-by-one. For
@@ -49,9 +91,11 @@ machine-readable error you can fix (read the JSON); exit 2 = you invoked it wron
49
91
  still go one at a time.
50
92
  - Park for the answer: \`${cmd} wait --timeout 540\` (set the Bash tool timeout
51
93
  to 600000 ms). The answer arrives as \`{"event":"answer","question":"q<n>",...}\`.
52
- 4. **Draft** the plan at \`.otacon/<session>/plan.md\` in the schema below, then
94
+ 4. **Draft** the plan at the \`plan\` path \`start\` printed (\`~/.otacon/sessions/<id>/plan.md\`) in the schema below, then
53
95
  \`${cmd} submit\`. On exit 1, fix every reported lint issue and resubmit until
54
- accepted.
96
+ accepted. After a clean submit, stop all implementation work and park in
97
+ \`${cmd} wait\`; only an \`approved\` event with \`implement:true\` enters the
98
+ Implement loop.
55
99
  5. **Review loop** — park in \`${cmd} wait --timeout 540\` (Bash timeout 600000 ms)
56
100
  and handle the one event it prints:
57
101
  - \`comments\` → revise plan.md; write \`resolutions.json\` as
@@ -80,26 +124,38 @@ machine-readable error you can fix (read the JSON); exit 2 = you invoked it wron
80
124
 
81
125
  ## CLI quick reference
82
126
 
83
- - \`${cmd} start --title <t> [--quick]\` · \`${cmd} progress "<note>"\` ·
127
+ - \`${cmd} start --title <t> [--quick]\` · \`${cmd} resume [--session <id>]\` ·
128
+ \`${cmd} progress "<note>"\` (occasional highlights / chapter markers; the activity
129
+ floor on agents without auto-capture) ·
84
130
  \`${cmd} ask ...\` · \`${cmd} wait --timeout 540\` · \`${cmd} submit [--resolutions f]\` ·
85
131
  \`${cmd} answer <q> --body "..."\` · \`${cmd} implement-done [--pr <url>] [--failed]\` ·
86
132
  \`${cmd} status\` · \`${cmd} open\` · \`${cmd} config [get <key>]\`
87
133
 
88
134
  ## Implement loop (on \`approved\` with \`implement:true\`)
89
135
 
90
- You are the **orchestrator**: you only coordinate and narrate
91
- (\`${cmd} progress\` at each checkpoint) every phase's real work runs in a fresh
92
- native subagent (Task tool) so your own context stays lean.
93
-
94
- 1. **Setup.** On Implement the plan lives only in the home archive at the event
95
- \`path\` (read the phases from there). Branch off the repo's current default branch
96
- HEAD: create the
97
- worktree under the configured \`worktree.dir\`
98
- (\`${cmd} config get worktree.dir\` default \`~/.otacon/worktrees\`, outside the repo):
99
- \`git worktree add <worktree.dir>/<slug> -b otacon/impl-<slug>\` (off the default
100
- branch). \`${cmd} progress\` each checkpoint throughout.
101
- 2. **Per phase, in order** (read the phases from the home plan at the event \`path\`):
102
- - \`${cmd} progress "phase N — implementing"\`; spawn an **implement+test**
136
+ You are the **orchestrator**: you only coordinate and mark progress
137
+ (\`${cmd} progress\` at phase boundaries, an occasional chapter marker rather than
138
+ every action; on supported agents the now-playing console already streams the work).
139
+ Every phase's real work runs in a fresh native subagent (Task tool) so your own
140
+ context stays lean.
141
+
142
+ 1. **Setup.** Read the plan from the home archive at the event \`path\`.
143
+ - **Amending** (you resumed this session, so its build worktree already exists
144
+ and you are standing in it): do NOT create a worktree. \`cd\` into
145
+ \`<worktree.dir>/<slug>\`, make sure you are on \`otacon/impl-<slug>\`, and build
146
+ on top of the existing commits. Pushing later updates the SAME PR.
147
+ - **Fresh** (no existing worktree): branch off the repo's default-branch HEAD and
148
+ create the worktree under \`worktree.dir\` (\`${cmd} config get worktree.dir\`,
149
+ default \`~/.otacon/worktrees\`, outside the repo):
150
+ \`git worktree add <worktree.dir>/<slug> -b otacon/impl-<slug>\` (off the default
151
+ branch).
152
+ Drop a \`${cmd} progress\` highlight at each phase boundary throughout, not at
153
+ every step.
154
+ 2. **Per phase, in order** (read the phases from the home plan at the event \`path\`;
155
+ on an amendment, implement only the phases this revision changed, using the
156
+ changelog and the diff to scope):
157
+ - \`${cmd} progress "phase N — implementing"\` (one marker per phase); spawn an
158
+ **implement+test**
103
159
  subagent (Task tool) scoped to that phase's Goal/Files/Verification — it
104
160
  implements and runs the phase Verification plus the repo gates.
105
161
  - spawn a **separate** \`/code-review --fix\` subagent on the phase's working
@@ -109,10 +165,12 @@ native subagent (Task tool) so your own context stays lean.
109
165
  review still flags, or a subagent is stuck) → on the FIRST blocker,
110
166
  \`${cmd} ask\` with options \`retry|skip|abort|guidance\`, park in \`${cmd} wait\`,
111
167
  and act on the answer. No auto-retry.
112
- 3. **Finish.** On success, open a PR against the default branch with \`gh pr create\`
113
- (PR body = the plan summary + the per-phase log; fall back to the local branch +
114
- path when there is no remote), then \`${cmd} implement-done --pr <url>\`. On abort,
115
- run \`${cmd} implement-done --failed\`.
168
+ 3. **Finish.** On a **fresh** build, open a PR against the default branch with
169
+ \`gh pr create\` (PR body = the plan summary + the per-phase log; fall back to the
170
+ local branch + path when there is no remote). On an **amendment**, the PR already
171
+ exists: push the branch and it updates, so reuse its URL (it is on the session;
172
+ \`${cmd} status\` reports \`prUrl\`). Either way finish with
173
+ \`${cmd} implement-done --pr <url>\`. On abort, run \`${cmd} implement-done --failed\`.
116
174
 
117
175
  While \`implementing\` the Stop hook still keeps you on the line — never end the turn
118
176
  until \`implement-done\`.
@@ -175,6 +233,16 @@ or callout.
175
233
  \`\`\`
176
234
  Capped at 6 scenarios per block; must sit under \`Verification\`.
177
235
 
236
+ When plan content is shaped as a hierarchy or tree (a taxonomy, a doc or file
237
+ structure, a nested option space, a state hierarchy, a decision tree), draw it as a
238
+ \`\`\`mermaid diagram, not as a monospace nested outline in a \`\`\`text fence: an outline
239
+ forces the reviewer to reconstruct the shape line by line, while a diagram shows it at a
240
+ glance. \`graph TD\` (a top-down flowchart) is the natural default; pick whatever shape
241
+ reads best (a mindmap, a state diagram, etc. when they fit). Put the tree diagram in the
242
+ section that owns that structure (Contract, Impact, or a phase's Details); \`mermaid\`
243
+ diagrams no longer count toward the per-section fence cap, so a lead diagram and a
244
+ structural one can coexist.
245
+
178
246
  Callouts and matrices are budget-exempt but capped (default 2 per read-path
179
247
  section); pills are free. Reach for a visual when it carries the point better
180
248
  than a sentence — never as decoration.
@@ -182,7 +250,11 @@ than a sentence — never as decoration.
182
250
  ## Rules
183
251
 
184
252
  - Never use native plan mode, AskUserQuestion, or any built-in question UI while
185
- the session is open every question goes through \`${cmd} ask\`.
253
+ the session is open: every question goes through \`${cmd} ask\`. The sole exception
254
+ is the resume-vs-new question at the very start, before any session exists.
255
+ - If you notice you edited project files before \`approved implement:true\`, stop
256
+ immediately, disclose the mistake, and ask whether to revert or keep the
257
+ uncommitted changes.
186
258
  - Long review or build ahead? Remind the user to keep the Mac awake: \`caffeinate -i\`
187
259
  while the session runs.
188
260
  `;
@@ -191,18 +263,21 @@ than a sentence — never as decoration.
191
263
  export function skillMd() {
192
264
  return `---
193
265
  name: otacon
194
- description: Plan a feature through an otacon review session grill interview, schema'd plan, phone review with anchored comments, approved plan saved to a home archive (and your project on Save). Use when the user asks to plan something with otacon, types /otacon, or wants a reviewed implementation plan before coding. Replaces native plan mode.
266
+ description: Plan a feature through an otacon review session: grill interview, schema'd plan, phone review with anchored comments, approved plan saved to a home archive (and your project on Save). Use when the user asks to plan something with otacon, types /otacon, or wants a reviewed implementation plan before coding. Replaces native plan mode. Also resumes and amends an implemented plan when run from inside its build worktree.
195
267
  ---
196
268
 
197
- <!-- ${MANAGED_MARKER} — reinstall overwrites this file; the spec lives in otacon's DESIGN.md -->
269
+ <!-- ${MANAGED_MARKER} — reinstall overwrites this file. -->
198
270
 
199
271
  # Otacon plan session protocol
200
272
 
201
273
  ${protocolCard('otacon')}`;
202
274
  }
203
275
  /**
204
- * THIS repo's dogfood wrapper — the committed \`.claude/skills/otacon/SKILL.md\`
205
- * (DESIGN.md §16). It is the same protocol card as \`skillMd()\`, but with the
276
+ * THIS repo's dogfood wrapper — the committed \`.claude/skills/otacon-dev/SKILL.md\`.
277
+ * Named \`otacon-dev\` (not \`otacon\`) so it never collides with the installed
278
+ * product skill (\`otacon\`) when developing otacon itself: \`/otacon\` stays the
279
+ * real product, \`/otacon-dev\` is this source-mode wrapper.
280
+ * It is the same protocol card as \`skillMd()\`, but with the
206
281
  * \`./bin/otacon\` run-from-source command prefix and a repo preamble (run from
207
282
  * source, restart after daemon edits). Generated from this function and never
208
283
  * hand-edited; \`assets.test.ts\` asserts the committed file equals this output,
@@ -211,8 +286,8 @@ ${protocolCard('otacon')}`;
211
286
  */
212
287
  export function dogfoodSkillMd() {
213
288
  return `---
214
- name: otacon
215
- description: Plan a feature for THIS repo through an otacon review session grill interview, schema'd plan, browser/phone review with anchored comments, approved plan saved to a home archive (and your project on Save). Use when the user asks to plan something with otacon, types /otacon, or wants a reviewed implementation plan before coding. Replaces native plan mode. Dogfoods otacon on its own development.
289
+ name: otacon-dev
290
+ description: Plan a feature for THIS repo through an otacon review session: grill interview, schema'd plan, browser/phone review with anchored comments, approved plan saved to a home archive (and your project on Save). Use when the user asks to plan something with otacon, types /otacon, or wants a reviewed implementation plan before coding. Replaces native plan mode. Dogfoods otacon on its own development. Also resumes and amends an implemented plan when run from inside its build worktree.
216
291
  ---
217
292
 
218
293
  <!-- Generated from src/cli/install/assets.ts (dogfoodSkillMd) — do NOT hand-edit;
@@ -225,9 +300,9 @@ This repo **is** otacon. You plan features for it by running otacon's own CLI fr
225
300
  source via the \`./bin/otacon\` shim, so every command below exercises the code in
226
301
  this checkout. That shim runs the CLI from \`src/\` via bun — no build needed; it
227
302
  always reflects current source. The daemon auto-spawns from source on the first
228
- command. Working state lives in \`.otacon/\`; the approved plan is archived in the
229
- home store (\`~/.otacon/sessions/<id>/\`) and, on Save, copied into the repo under
230
- \`plans.dir\` (default \`.otacon/plans\`).
303
+ command. Working state lives in the home store (\`~/.otacon/sessions/<id>/\`); on
304
+ Save the approved plan is also copied into the repo under \`plans.dir\` (default
305
+ \`.otacon/plans\`). \`<repo>/.otacon/\` itself holds only config and those Save copies.
231
306
 
232
307
  After editing **daemon** source (\`src/daemon/**\`) mid-session, restart the running
233
308
  daemon so your change loads: \`./bin/otacon restart\` (the next command respawns it
@@ -235,26 +310,26 @@ from current source). Use \`./bin/otacon restart\`, not a raw curl to a fixed po
235
310
  in a git worktree the shim runs the daemon on a derived port, and \`restart\` always
236
311
  targets the one this checkout talks to. CLI/linter/parser edits need no restart.
237
312
 
238
- The spec these commands implement is otacon's own DESIGN.md (§6 loop, §8 grill, §13
239
- failure habits); the canonical wrapper text lives in \`src/cli/install/assets.ts\`.
313
+ These commands implement otacon's full review loop, grill discipline, and
314
+ failure habits; the canonical wrapper text lives in \`src/cli/install/assets.ts\`.
240
315
 
241
316
  ---
242
317
 
243
318
  ${protocolCard('./bin/otacon')}`;
244
319
  }
245
320
  /**
246
- * The Claude Code Stop hook (DESIGN.md §13): blocks ending the turn while an
321
+ * The Claude Code Stop hook: blocks ending the turn while an
247
322
  * open otacon session exists in the cwd's repo. Plain sh, fast, fail-open —
248
323
  * any failure (daemon down, curl missing, no match) allows the stop. With no
249
324
  * local pointer, the open session is found by scanning the daemon registry for
250
- * a non-terminal session whose repo equals the cwd's git root (DESIGN.md §7)
325
+ * a non-terminal session whose repo equals the cwd's git root —
251
326
  * `implementing` still blocks (the build is live); only the terminal states
252
327
  * (approved/implemented/implement_failed) let the agent end its turn.
253
328
  */
254
329
  export const STOP_HOOK_SCRIPT = `#!/bin/sh
255
330
  # otacon Stop hook — ${MANAGED_MARKER}; reinstall overwrites this file.
256
331
  # Blocks Claude Code from ending its turn while the cwd's repo has an open
257
- # otacon plan session (DESIGN.md §13). Fail-open by design: when anything here
332
+ # otacon plan session. Fail-open by design: when anything here
258
333
  # fails (daemon unreachable, curl missing, no match), the stop is allowed.
259
334
  input=$(cat 2>/dev/null) || input=""
260
335
  cwd=$(printf '%s' "$input" | sed -n 's/.*"cwd"[[:space:]]*:[[:space:]]*"\\([^"]*\\)".*/\\1/p')
@@ -1 +1 @@
1
- {"version":3,"file":"assets.js","sourceRoot":"","sources":["../../../src/cli/install/assets.ts"],"names":[],"mappings":"AAAA,4EAA4E;AAC5E,8EAA8E;AAC9E,+EAA+E;AAC/E,yEAAyE;AACzE,2EAA2E;AAC3E,gFAAgF;AAChF,iCAAiC;AAEjC,oEAAoE;AACpE,MAAM,CAAC,MAAM,cAAc,GAAG,6BAA6B,CAAC;AAE5D;;;;;;;GAOG;AACH,SAAS,YAAY,CAAC,GAAW;IAC/B,OAAO;qCAC4B,GAAG;;;;;;OAMjC,GAAG;wEAC8D,GAAG;;;;OAIpE,GAAG;;;;;;;;;;SAUD,GAAG;;;;;eAKG,GAAG;;;;8BAIY,GAAG;;;OAG1B,GAAG;;iCAEuB,GAAG;;;;uCAIG,GAAG;;;;;;wBAMlB,GAAG;;;;;;;;;;;;;OAapB,GAAG,qDAAqD,GAAG;;;;;MAK5D,GAAG,sCAAsC,GAAG;MAC5C,GAAG,kBAAkB,GAAG,6BAA6B,GAAG;MACxD,GAAG,kCAAkC,GAAG;MACxC,GAAG,iBAAiB,GAAG,eAAe,GAAG;;;;;KAK1C,GAAG;;;;;;;QAOA,GAAG;;gBAEK,GAAG;;SAEV,GAAG;;;;;;;;SAQH,GAAG,gEAAgE,GAAG;;;;2CAIpC,GAAG;WACnC,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;wDAsE0C,GAAG;;;CAG1D,CAAC;AACF,CAAC;AAED,0FAA0F;AAC1F,MAAM,UAAU,OAAO;IACrB,OAAO;;;;;OAKF,cAAc;;;;EAInB,YAAY,CAAC,QAAQ,CAAC,EAAE,CAAC;AAC3B,CAAC;AAED;;;;;;;;GAQG;AACH,MAAM,UAAU,cAAc;IAC5B,OAAO;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EA8BP,YAAY,CAAC,cAAc,CAAC,EAAE,CAAC;AACjC,CAAC;AAED;;;;;;;;GAQG;AACH,MAAM,CAAC,MAAM,gBAAgB,GAAG;uBACT,cAAc;;;;;;;;;;;;;;;;;;;;;CAqBpC,CAAC"}
1
+ {"version":3,"file":"assets.js","sourceRoot":"","sources":["../../../src/cli/install/assets.ts"],"names":[],"mappings":"AAAA,6EAA6E;AAC7E,6EAA6E;AAC7E,iEAAiE;AACjE,yEAAyE;AACzE,qEAAqE;AACrE,gFAAgF;AAChF,iCAAiC;AAEjC,oEAAoE;AACpE,MAAM,CAAC,MAAM,cAAc,GAAG,6BAA6B,CAAC;AAE5D;;;;;;;GAOG;AACH,SAAS,YAAY,CAAC,GAAW;IAC/B,OAAO;qCAC4B,GAAG;;;;;;;;IAQpC,GAAG;;;MAGD,GAAG,gBAAgB,GAAG,iBAAiB,GAAG,eAAe,GAAG;MAC5D,GAAG,cAAc,GAAG,eAAe,GAAG,iBAAiB,GAAG;;;;;;;;;WASrD,GAAG,wCAAwC,GAAG;;;;;;;2DAOE,GAAG;;;;4BAIlC,GAAG;;qBAEV,GAAG;;;yDAGiC,GAAG;;;;;;OAMrD,GAAG;;qEAE2D,GAAG;;;;;0CAK9B,GAAG;;;;;;;;;;;;;SAapC,GAAG;;;;;eAKG,GAAG;;;;8BAIY,GAAG;;;OAG1B,GAAG;;OAEH,GAAG;;iCAEuB,GAAG;;;;uCAIG,GAAG;;;;;;wBAMlB,GAAG;;;;;;;;;;;;;OAapB,GAAG,qDAAqD,GAAG;;;;;MAK5D,GAAG,sCAAsC,GAAG;MAC5C,GAAG;;MAEH,GAAG,kBAAkB,GAAG,6BAA6B,GAAG;MACxD,GAAG,kCAAkC,GAAG;MACxC,GAAG,iBAAiB,GAAG,eAAe,GAAG;;;;;KAK1C,GAAG;;;;;;;;;;;qDAW6C,GAAG;;;;cAI1C,GAAG;;;;;SAKR,GAAG;;;;;;;;;SASH,GAAG,gEAAgE,GAAG;;;;;;OAMxE,GAAG;OACH,GAAG,iDAAiD,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;uDAgFP,GAAG;;;;;;;CAOzD,CAAC;AACF,CAAC;AAED,0FAA0F;AAC1F,MAAM,UAAU,OAAO;IACrB,OAAO;;;;;OAKF,cAAc;;;;EAInB,YAAY,CAAC,QAAQ,CAAC,EAAE,CAAC;AAC3B,CAAC;AAED;;;;;;;;;;;GAWG;AACH,MAAM,UAAU,cAAc;IAC5B,OAAO;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EA8BP,YAAY,CAAC,cAAc,CAAC,EAAE,CAAC;AACjC,CAAC;AAED;;;;;;;;GAQG;AACH,MAAM,CAAC,MAAM,gBAAgB,GAAG;uBACT,cAAc;;;;;;;;;;;;;;;;;;;;;CAqBpC,CAAC"}
@@ -1,4 +1,4 @@
1
- // Where each agent reads its wrapper from (DESIGN.md §16; DECISIONS.md
1
+ // Where each agent reads its wrapper from (install/update; DECISIONS.md
2
2
  // "Wrapper destinations per agent"), plus the merge/registration helpers
3
3
  // install and doctor share. homedir() honors $HOME, which is what keeps the
4
4
  // install e2e hermetic under a temp HOME.
@@ -1 +1 @@
1
- {"version":3,"file":"locations.js","sourceRoot":"","sources":["../../../src/cli/install/locations.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"locations.js","sourceRoot":"","sources":["../../../src/cli/install/locations.ts"],"names":[],"mappings":"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"}
@@ -1,5 +1,5 @@
1
- // Best-effort Tailscale discovery shared by doctor and expose (DESIGN.md §11,
2
- // §16). OTACON_TAILSCALE pins the binary (hermetic tests; nonstandard
1
+ // Best-effort Tailscale discovery shared by doctor and expose (install/expose,
2
+ // install/update). OTACON_TAILSCALE pins the binary (hermetic tests; nonstandard
3
3
  // installs) and is authoritative when set; otherwise PATH, then the macOS app
4
4
  // bundle's embedded CLI (DECISIONS.md "doctor/expose automation boundary").
5
5
  import { execFileSync } from "node:child_process";
@@ -1 +1 @@
1
- {"version":3,"file":"tailscale.js","sourceRoot":"","sources":["../../../src/cli/install/tailscale.ts"],"names":[],"mappings":"AAAA,8EAA8E;AAC9E,sEAAsE;AACtE,8EAA8E;AAC9E,4EAA4E;AAE5E,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAElD,MAAM,WAAW,GAAG,sDAAsD,CAAC;AAE3E,MAAM,UAAU,aAAa;IAC3B,MAAM,QAAQ,GAAG,OAAO,CAAC,GAAG,CAAC,gBAAgB,CAAC;IAC9C,MAAM,UAAU,GAAG,QAAQ,KAAK,SAAS,IAAI,QAAQ,KAAK,EAAE,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,WAAW,EAAE,WAAW,CAAC,CAAC;IACvG,KAAK,MAAM,GAAG,IAAI,UAAU,EAAE,CAAC;QAC7B,IAAI,CAAC;YACH,YAAY,CAAC,GAAG,EAAE,CAAC,SAAS,CAAC,EAAE,EAAE,KAAK,EAAE,CAAC,QAAQ,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,CAAC,CAAC;YACxE,OAAO,GAAG,CAAC;QACb,CAAC;QAAC,MAAM,CAAC;YACP,eAAe;QACjB,CAAC;IACH,CAAC;IACD,OAAO,SAAS,CAAC;AACnB,CAAC;AASD,MAAM,UAAU,eAAe,CAAC,GAAW;IACzC,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CACpB,YAAY,CAAC,GAAG,EAAE,CAAC,QAAQ,EAAE,QAAQ,CAAC,EAAE;YACtC,QAAQ,EAAE,MAAM;YAChB,KAAK,EAAE,CAAC,QAAQ,EAAE,MAAM,EAAE,MAAM,CAAC;SAClC,CAAC,CACyD,CAAC;QAC9D,MAAM,GAAG,GAAG,GAAG,EAAE,IAAI,EAAE,OAAO,CAAC;QAC/B,OAAO;YACL,YAAY,EAAE,OAAO,GAAG,EAAE,YAAY,KAAK,QAAQ,CAAC,CAAC,CAAC,GAAG,CAAC,YAAY,CAAC,CAAC,CAAC,SAAS;YAClF,GAAG,CAAC,OAAO,GAAG,KAAK,QAAQ,IAAI,GAAG,KAAK,EAAE;gBACvC,CAAC,CAAC,EAAE,OAAO,EAAE,GAAG,CAAC,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC,EAAE;gBACrC,CAAC,CAAC,EAAE,CAAC;SACR,CAAC;IACJ,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,SAAS,CAAC;IACnB,CAAC;AACH,CAAC"}
1
+ {"version":3,"file":"tailscale.js","sourceRoot":"","sources":["../../../src/cli/install/tailscale.ts"],"names":[],"mappings":"AAAA,+EAA+E;AAC/E,iFAAiF;AACjF,8EAA8E;AAC9E,4EAA4E;AAE5E,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAElD,MAAM,WAAW,GAAG,sDAAsD,CAAC;AAE3E,MAAM,UAAU,aAAa;IAC3B,MAAM,QAAQ,GAAG,OAAO,CAAC,GAAG,CAAC,gBAAgB,CAAC;IAC9C,MAAM,UAAU,GAAG,QAAQ,KAAK,SAAS,IAAI,QAAQ,KAAK,EAAE,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,WAAW,EAAE,WAAW,CAAC,CAAC;IACvG,KAAK,MAAM,GAAG,IAAI,UAAU,EAAE,CAAC;QAC7B,IAAI,CAAC;YACH,YAAY,CAAC,GAAG,EAAE,CAAC,SAAS,CAAC,EAAE,EAAE,KAAK,EAAE,CAAC,QAAQ,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,CAAC,CAAC;YACxE,OAAO,GAAG,CAAC;QACb,CAAC;QAAC,MAAM,CAAC;YACP,eAAe;QACjB,CAAC;IACH,CAAC;IACD,OAAO,SAAS,CAAC;AACnB,CAAC;AASD,MAAM,UAAU,eAAe,CAAC,GAAW;IACzC,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CACpB,YAAY,CAAC,GAAG,EAAE,CAAC,QAAQ,EAAE,QAAQ,CAAC,EAAE;YACtC,QAAQ,EAAE,MAAM;YAChB,KAAK,EAAE,CAAC,QAAQ,EAAE,MAAM,EAAE,MAAM,CAAC;SAClC,CAAC,CACyD,CAAC;QAC9D,MAAM,GAAG,GAAG,GAAG,EAAE,IAAI,EAAE,OAAO,CAAC;QAC/B,OAAO;YACL,YAAY,EAAE,OAAO,GAAG,EAAE,YAAY,KAAK,QAAQ,CAAC,CAAC,CAAC,GAAG,CAAC,YAAY,CAAC,CAAC,CAAC,SAAS;YAClF,GAAG,CAAC,OAAO,GAAG,KAAK,QAAQ,IAAI,GAAG,KAAK,EAAE;gBACvC,CAAC,CAAC,EAAE,OAAO,EAAE,GAAG,CAAC,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC,EAAE;gBACrC,CAAC,CAAC,EAAE,CAAC;SACR,CAAC;IACJ,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,SAAS,CAAC;IACnB,CAAC;AACH,CAAC"}
@@ -0,0 +1,202 @@
1
+ // Resolves the in-package SKILL.md asset that the installed wrapper symlinks to.
2
+ // `otacon install` copies the wrapper text today, so it goes stale when the binary
3
+ // auto-updates; the fix is to SYMLINK the installed wrapper to a real file shipped
4
+ // inside the npm package (`dist/skills/otacon/SKILL.md`, generated from `skillMd()`
5
+ // by scripts/gen-skill-asset.ts), so a binary upgrade refreshes the skill for free.
6
+ // A symlink target must be a STABLE on-disk path, so only the packaged file qualifies;
7
+ // when there is no such file (running from source, or an ephemeral npx cache that a
8
+ // later invocation may have wiped), callers must fall back to COPYING instead.
9
+ import { existsSync, lstatSync, mkdirSync, readFileSync, realpathSync, rmSync, symlinkSync, writeFileSync, } from "node:fs";
10
+ import { dirname } from "node:path";
11
+ import { fileURLToPath } from "node:url";
12
+ import { isSourceRun } from "../client.js";
13
+ import { notice } from "../output.js";
14
+ import { findRepoRoot } from "../session.js";
15
+ import { MANAGED_MARKER, skillMd } from "./assets.js";
16
+ import { claudeSkillPath, codexSkillPath, opencodeSkillPath, } from "./locations.js";
17
+ /**
18
+ * The absolute path of the packaged `SKILL.md` asset, or `undefined` when no stable
19
+ * packaged copy exists (so callers copy `skillMd()` instead of symlinking).
20
+ *
21
+ * Resolution is relative to THIS module's compiled location: from the installed
22
+ * `dist/cli/install/wrapper.js` `../../skills/otacon/SKILL.md` is
23
+ * `dist/skills/otacon/SKILL.md` (the file the build emits); from source
24
+ * `src/cli/install/wrapper.ts` it is `src/skills/otacon/SKILL.md`, which never exists,
25
+ * so a source run correctly returns `undefined`. Returns `undefined` when:
26
+ * - the resolved path does not exist (source run, or asset not built); or
27
+ * - the path lives under an ephemeral npx cache (an `_npx` segment): that dir is
28
+ * transient, so a symlink into it would dangle once npx prunes it; copy instead.
29
+ * Never throws: any error resolves to `undefined`, the copy-fallback signal.
30
+ */
31
+ export function packagedSkillPath() {
32
+ try {
33
+ const path = fileURLToPath(new URL("../../skills/otacon/SKILL.md", import.meta.url));
34
+ if (!existsSync(path))
35
+ return undefined;
36
+ if (/[/\\]_npx[/\\]/.test(path))
37
+ return undefined;
38
+ return path;
39
+ }
40
+ catch {
41
+ return undefined;
42
+ }
43
+ }
44
+ /**
45
+ * Converge the wrapper at `path` to its desired state and report how (idempotent).
46
+ *
47
+ * User-scope wrappers SYMLINK to the packaged `SKILL.md` so a binary upgrade
48
+ * refreshes the protocol text for free (the file the symlink points at is the one
49
+ * the new build emits). Two cases fall back to a COPY of `skillMd()` instead:
50
+ * - **Project scope** always copies. A `--project` wrapper is committed/shared, so it
51
+ * must be machine-independent: it cannot point at a machine-local global path that
52
+ * a teammate (or CI) does not have.
53
+ * - **No stable packaged path** (`pkgPath` undefined: a source run, or an ephemeral
54
+ * npx cache `packagedSkillPath()` already rejected): there is nothing durable to
55
+ * link to, so copy the current text.
56
+ * - **Symlinks unsupported here** (the `symlink` call throws EPERM/EXDEV/ENOSYS/etc.,
57
+ * e.g. Windows without privilege, or a cross-device link): fall through to a copy.
58
+ * The `symlink` parameter is a testability seam that also lets a test force this path.
59
+ *
60
+ * Convergence is idempotent: an already-correct symlink (same resolved target) or an
61
+ * already-correct copy (same contents, a regular file not a symlink) is a no-op
62
+ * (`changed: false`); anything else is removed and rewritten. A scope/availability
63
+ * change between runs self-heals (a stale symlink becomes a copy, and vice versa)
64
+ * because each branch first `rmSync`s whatever is in the way. `lstatSync` (not `stat`)
65
+ * inspects the link itself, so a symlink is never mistaken for a regular file, and
66
+ * `{ throwIfNoEntry: false }` makes a missing path a plain `undefined`, never a throw.
67
+ */
68
+ export function ensureWrapper(path, scope, pkgPath = packagedSkillPath(),
69
+ // testability seam: inject a throwing linker to exercise the copy fallback
70
+ symlink = (t, l) => symlinkSync(t, l)) {
71
+ mkdirSync(dirname(path), { recursive: true });
72
+ // Symlink branch: user scope only, and only when there is a stable file to point at.
73
+ if (scope === "user" && pkgPath !== undefined) {
74
+ const info = lstatSync(path, { throwIfNoEntry: false });
75
+ if (info?.isSymbolicLink()) {
76
+ // realpathSync resolves both sides so a correct link (even via a differently
77
+ // spelled but equivalent path) reads as a no-op.
78
+ try {
79
+ if (realpathSync(path) === realpathSync(pkgPath)) {
80
+ return { mode: "symlink", changed: false };
81
+ }
82
+ }
83
+ catch {
84
+ // A dangling link (target gone) cannot be compared; fall through to recreate it.
85
+ }
86
+ }
87
+ try {
88
+ rmSync(path, { force: true }); // clear a stale link, an old copy, or a dangling link
89
+ symlink(pkgPath, path);
90
+ return { mode: "symlink", changed: true };
91
+ }
92
+ catch {
93
+ // Symlinks are unsupported on this filesystem/privilege level; copy instead.
94
+ }
95
+ }
96
+ // Copy branch: project scope, no packaged path, or the symlink above threw.
97
+ const content = skillMd();
98
+ const info = lstatSync(path, { throwIfNoEntry: false });
99
+ if (info?.isFile() && readFileSync(path, "utf8") === content) {
100
+ return { mode: "copy", changed: false };
101
+ }
102
+ rmSync(path, { force: true }); // clear a stale symlink or an out-of-date copy
103
+ writeFileSync(path, content);
104
+ return { mode: "copy", changed: true };
105
+ }
106
+ /**
107
+ * The fallback/migration mechanism: on every `otacon start`, re-assert each
108
+ * ALREADY-INSTALLED managed wrapper to its desired state (`ensureWrapper`), so an
109
+ * install done before the symlink era (or one that could not symlink at all)
110
+ * heals itself the next time the tool runs.
111
+ *
112
+ * For a correct symlink this is entirely INERT: `ensureWrapper` no-ops a link that
113
+ * already resolves to the packaged file, so symlink installs (the common case) cost
114
+ * nothing and emit no notice. It only does work on real drift:
115
+ * - a user-scope COPY left by a copy-fallback install (Windows/npx) is promoted to a
116
+ * symlink to the packaged file (so future binary upgrades refresh it for free);
117
+ * - a dangling or wrong-target user symlink is repaired;
118
+ * - a committed/legacy PROJECT-scope copy whose text drifted is rewritten to the
119
+ * current `skillMd()` (still a copy, never a machine-local symlink).
120
+ *
121
+ * It NEVER creates a wrapper that does not already exist: this is a heal-what's-there
122
+ * pass, not an installer. A path absent on disk is skipped, and a regular file is
123
+ * touched only when it carries `MANAGED_MARKER` (so a foreign SKILL.md a user wrote by
124
+ * hand is never clobbered); a symlink at one of our locations is always ours to repair.
125
+ *
126
+ * Skipped wholesale on a SOURCE run: this checkout's committed `otacon-dev` dogfood
127
+ * wrapper is generated and guarded by a test, so a source-mode `start` must never
128
+ * rewrite it (`sourceRun()` true returns `[]` before touching anything).
129
+ *
130
+ * Fail-open throughout: each wrapper is converged inside its own try/catch so one
131
+ * failure cannot abort the rest, and the function itself never throws (a refresh is
132
+ * best-effort and must never block `start`).
133
+ */
134
+ export function refreshInstalledWrappers(deps = {}) {
135
+ const refreshed = [];
136
+ try {
137
+ const sourceRun = deps.sourceRun ?? isSourceRun;
138
+ // Never touch a source checkout's committed dogfood wrapper.
139
+ if (sourceRun())
140
+ return [];
141
+ const pkgPath = "pkgPath" in deps ? deps.pkgPath : packagedSkillPath();
142
+ const cwd = deps.cwd ?? process.cwd();
143
+ // The candidate locations to heal: the three user-scope wrappers always, plus the
144
+ // three project-scope wrappers when cwd sits inside a git repo. Presence is decided
145
+ // per-candidate below, so listing one here never implies it exists on disk.
146
+ const candidates = [
147
+ { path: claudeSkillPath(), scope: "user" },
148
+ { path: codexSkillPath(), scope: "user" },
149
+ { path: opencodeSkillPath(), scope: "user" },
150
+ ];
151
+ const root = findRepoRoot(cwd);
152
+ if (root !== undefined) {
153
+ const project = { kind: "project", root };
154
+ candidates.push({ path: claudeSkillPath(project), scope: "project" }, { path: codexSkillPath(project), scope: "project" }, { path: opencodeSkillPath(project), scope: "project" });
155
+ }
156
+ for (const { path, scope } of candidates) {
157
+ if (!isManagedWrapper(path))
158
+ continue; // only heal what is already installed
159
+ try {
160
+ const result = ensureWrapper(path, scope, pkgPath);
161
+ if (result.changed) {
162
+ notice(`refreshed otacon skill at ${path} (${result.mode})`);
163
+ refreshed.push({ path, mode: result.mode });
164
+ }
165
+ }
166
+ catch {
167
+ // Best-effort: a single wrapper's failure must not abort the rest, and the
168
+ // whole pass is fail-open, never blocking start on a refresh.
169
+ }
170
+ }
171
+ }
172
+ catch {
173
+ // Belt-and-suspenders: the candidate-list setup (cwd lookup, repo-root probe)
174
+ // is unlikely to throw, but the whole pass must never throw out of start.
175
+ }
176
+ return refreshed;
177
+ }
178
+ /**
179
+ * Whether `path` already holds an otacon-owned wrapper this pass may re-assert.
180
+ * A SYMLINK at one of our skill locations is ours (created by a prior symlink
181
+ * install), so it counts even when the link dangles (`ensureWrapper` repairs it).
182
+ * A regular FILE counts only when it carries `MANAGED_MARKER`, so a foreign SKILL.md
183
+ * a user wrote by hand is left alone. Anything else (no entry, a dir) is not present.
184
+ * `lstatSync` inspects the link itself (a symlink is never read as a file), and
185
+ * `{ throwIfNoEntry: false }` turns a missing path into `undefined`, never a throw.
186
+ */
187
+ function isManagedWrapper(path) {
188
+ const info = lstatSync(path, { throwIfNoEntry: false });
189
+ if (info === undefined)
190
+ return false;
191
+ if (info.isSymbolicLink())
192
+ return true;
193
+ if (!info.isFile())
194
+ return false;
195
+ try {
196
+ return readFileSync(path, "utf8").includes(MANAGED_MARKER);
197
+ }
198
+ catch {
199
+ return false;
200
+ }
201
+ }
202
+ //# sourceMappingURL=wrapper.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"wrapper.js","sourceRoot":"","sources":["../../../src/cli/install/wrapper.ts"],"names":[],"mappings":"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"}
package/dist/cli/main.js CHANGED
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env node
2
- // otacon CLI dispatch (DESIGN.md §6). stdout carries exactly one JSON line per
2
+ // otacon CLI dispatch (review loop and daemon API). stdout carries exactly one JSON line per
3
3
  // invocation; notices go to stderr; exit 0 success / 1 expected failure /
4
4
  // 2 usage or internal error (src/cli/output.ts).
5
5
  import { answerCommand } from "./commands/answer.js";
@@ -12,13 +12,14 @@ import { implementDoneCommand } from "./commands/implement-done.js";
12
12
  import { installCommand } from "./commands/install.js";
13
13
  import { openCommand } from "./commands/open.js";
14
14
  import { progressCommand } from "./commands/progress.js";
15
+ import { resumeCommand } from "./commands/resume.js";
15
16
  import { startCommand } from "./commands/start.js";
16
17
  import { statusCommand } from "./commands/status.js";
17
18
  import { submitCommand } from "./commands/submit.js";
18
19
  import { updateCommand } from "./commands/update.js";
19
20
  import { waitCommand } from "./commands/wait.js";
20
21
  import { CliError, printJson } from "./output.js";
21
- const USAGE = "usage: otacon <start|submit|wait|ask|answer|progress|implement-done|status|open|config|clean|install|doctor|expose|update> [options]\n" +
22
+ const USAGE = "usage: otacon <start|submit|wait|ask|answer|progress|implement-done|resume|status|open|config|clean|install|doctor|expose|update> [options]\n" +
22
23
  " otacon config [open] open the Settings web UI in the browser\n" +
23
24
  " otacon config get <key> print the merged value of one config key\n" +
24
25
  " otacon update [--check] update the global install to the latest published version";
@@ -38,6 +39,8 @@ async function dispatch(command, argv) {
38
39
  return progressCommand(argv);
39
40
  case "implement-done":
40
41
  return implementDoneCommand(argv);
42
+ case "resume":
43
+ return resumeCommand(argv);
41
44
  case "status":
42
45
  return statusCommand(argv);
43
46
  case "open":
@@ -1 +1 @@
1
- {"version":3,"file":"main.js","sourceRoot":"","sources":["../../src/cli/main.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"main.js","sourceRoot":"","sources":["../../src/cli/main.ts"],"names":[],"mappings":"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"}
@@ -1,8 +1,8 @@
1
- // JSON-only stdout discipline for the otacon CLI (DESIGN.md §6): every command
1
+ // JSON-only stdout discipline for the otacon CLI (review loop and daemon API): every command
2
2
  // prints exactly one JSON line on stdout — the machine-readable result a coding
3
3
  // agent parses as its Bash tool output — and human-facing notices go to stderr.
4
4
  //
5
- // Exit codes: 0 success (including {"event":"timeout"}, DESIGN.md §6), 1
5
+ // Exit codes: 0 success (including {"event":"timeout"}, review loop and daemon API), 1
6
6
  // expected failure the agent can act on (lint reject, ambiguous session, port
7
7
  // conflict), 2 usage or internal error.
8
8
  /** A machine-readable command failure; main.ts prints the payload and exits. */