otacon 0.1.2 → 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.
- package/README.md +18 -5
- package/dist/cli/browser.js +1 -1
- package/dist/cli/browser.js.map +1 -1
- package/dist/cli/client.js +13 -2
- package/dist/cli/client.js.map +1 -1
- package/dist/cli/commands/answer.js +1 -1
- package/dist/cli/commands/answer.js.map +1 -1
- package/dist/cli/commands/ask.js +3 -3
- package/dist/cli/commands/ask.js.map +1 -1
- package/dist/cli/commands/clean.js +14 -16
- package/dist/cli/commands/clean.js.map +1 -1
- package/dist/cli/commands/config.js +1 -1
- package/dist/cli/commands/config.js.map +1 -1
- package/dist/cli/commands/doctor.js +4 -4
- package/dist/cli/commands/doctor.js.map +1 -1
- package/dist/cli/commands/expose.js +7 -7
- package/dist/cli/commands/expose.js.map +1 -1
- package/dist/cli/commands/implement-done.js +1 -1
- package/dist/cli/commands/implement-done.js.map +1 -1
- package/dist/cli/commands/install.js +16 -10
- package/dist/cli/commands/install.js.map +1 -1
- package/dist/cli/commands/open.js +31 -7
- package/dist/cli/commands/open.js.map +1 -1
- package/dist/cli/commands/progress.js +1 -1
- package/dist/cli/commands/progress.js.map +1 -1
- package/dist/cli/commands/resume.js +67 -0
- package/dist/cli/commands/resume.js.map +1 -0
- package/dist/cli/commands/start.js +24 -3
- package/dist/cli/commands/start.js.map +1 -1
- package/dist/cli/commands/status.js +15 -4
- package/dist/cli/commands/status.js.map +1 -1
- package/dist/cli/commands/submit.js +5 -5
- package/dist/cli/commands/submit.js.map +1 -1
- package/dist/cli/commands/update.js +83 -0
- package/dist/cli/commands/update.js.map +1 -0
- package/dist/cli/commands/wait.js +1 -1
- package/dist/cli/commands/wait.js.map +1 -1
- package/dist/cli/install/assets.js +123 -48
- package/dist/cli/install/assets.js.map +1 -1
- package/dist/cli/install/locations.js +1 -1
- package/dist/cli/install/locations.js.map +1 -1
- package/dist/cli/install/tailscale.js +2 -2
- package/dist/cli/install/tailscale.js.map +1 -1
- package/dist/cli/install/wrapper.js +202 -0
- package/dist/cli/install/wrapper.js.map +1 -0
- package/dist/cli/main.js +10 -3
- package/dist/cli/main.js.map +1 -1
- package/dist/cli/output.js +2 -2
- package/dist/cli/output.js.map +1 -1
- package/dist/cli/session.js +18 -7
- package/dist/cli/session.js.map +1 -1
- package/dist/cli/update.js +236 -0
- package/dist/cli/update.js.map +1 -0
- package/dist/daemon/activity.js +1 -1
- package/dist/daemon/activity.js.map +1 -1
- package/dist/daemon/anchor.js +1 -1
- package/dist/daemon/anchor.js.map +1 -1
- package/dist/daemon/app.js +370 -82
- package/dist/daemon/app.js.map +1 -1
- package/dist/daemon/approve.js +3 -3
- package/dist/daemon/approve.js.map +1 -1
- package/dist/daemon/capture/adapter.js +23 -0
- package/dist/daemon/capture/adapter.js.map +1 -0
- package/dist/daemon/capture/claude.js +274 -0
- package/dist/daemon/capture/claude.js.map +1 -0
- package/dist/daemon/capture/codex.js +413 -0
- package/dist/daemon/capture/codex.js.map +1 -0
- package/dist/daemon/capture/normalize.js +89 -0
- package/dist/daemon/capture/normalize.js.map +1 -0
- package/dist/daemon/capture/opencode.js +330 -0
- package/dist/daemon/capture/opencode.js.map +1 -0
- package/dist/daemon/capture/registry.js +33 -0
- package/dist/daemon/capture/registry.js.map +1 -0
- package/dist/daemon/capture/stream-store.js +121 -0
- package/dist/daemon/capture/stream-store.js.map +1 -0
- package/dist/daemon/capture/tailer.js +108 -0
- package/dist/daemon/capture/tailer.js.map +1 -0
- package/dist/daemon/desktop-notify.js +11 -5
- package/dist/daemon/desktop-notify.js.map +1 -1
- package/dist/daemon/diagrams.js +90 -0
- package/dist/daemon/diagrams.js.map +1 -0
- package/dist/daemon/diff.js +1 -2
- package/dist/daemon/diff.js.map +1 -1
- package/dist/daemon/linter/parse.js +45 -12
- package/dist/daemon/linter/parse.js.map +1 -1
- package/dist/daemon/linter/rules.js +20 -17
- package/dist/daemon/linter/rules.js.map +1 -1
- package/dist/daemon/main.js +1 -1
- package/dist/daemon/main.js.map +1 -1
- package/dist/daemon/notify.js +1 -1
- package/dist/daemon/notify.js.map +1 -1
- package/dist/daemon/presence.js +1 -1
- package/dist/daemon/presence.js.map +1 -1
- package/dist/daemon/queue.js +7 -7
- package/dist/daemon/queue.js.map +1 -1
- package/dist/daemon/store.js +66 -79
- package/dist/daemon/store.js.map +1 -1
- package/dist/daemon/threads.js +111 -25
- package/dist/daemon/threads.js.map +1 -1
- package/dist/daemon/transcript.js +1 -1
- package/dist/daemon/transcript.js.map +1 -1
- package/dist/daemon/ui.js +13 -6
- package/dist/daemon/ui.js.map +1 -1
- package/dist/daemon/viewers.js +37 -0
- package/dist/daemon/viewers.js.map +1 -0
- package/dist/shared/config.js +52 -7
- package/dist/shared/config.js.map +1 -1
- package/dist/shared/gwt.js +1 -1
- package/dist/shared/gwt.js.map +1 -1
- package/dist/shared/paths.js +68 -33
- package/dist/shared/paths.js.map +1 -1
- package/dist/shared/question-spec.js +1 -1
- package/dist/shared/question-spec.js.map +1 -1
- package/dist/shared/types.js +7 -3
- package/dist/shared/types.js.map +1 -1
- package/dist/shared/version.js +1 -1
- package/dist/skills/otacon/SKILL.md +250 -0
- package/dist/ui/assets/{arc-KT3ZnaMp.js → arc-BUR2DxNA.js} +1 -1
- package/dist/ui/assets/architecture-7EHR7CIX-TTokq2IO.js +1 -0
- package/dist/ui/assets/{architectureDiagram-3BPJPVTR-DLu0UM7N.js → architectureDiagram-3BPJPVTR-unLnkDyM.js} +1 -1
- package/dist/ui/assets/{blockDiagram-GPEHLZMM-B8wApEWC.js → blockDiagram-GPEHLZMM-DHx8lNeL.js} +1 -1
- package/dist/ui/assets/{c4Diagram-AAUBKEIU-BNS5gmQS.js → c4Diagram-AAUBKEIU-BU9T562l.js} +1 -1
- package/dist/ui/assets/channel-BA6ChrT3.js +1 -0
- package/dist/ui/assets/{chunk-2J33WTMH-CTY2etwY.js → chunk-2J33WTMH-BEb0myVl.js} +1 -1
- package/dist/ui/assets/{chunk-3OPIFGDE-DZM4Sz84.js → chunk-3OPIFGDE-DESBG_RB.js} +1 -1
- package/dist/ui/assets/{chunk-4BX2VUAB-sGwrrXIO.js → chunk-4BX2VUAB-dt3F_E_5.js} +1 -1
- package/dist/ui/assets/{chunk-55IACEB6-CGlNp76o.js → chunk-55IACEB6-BcyuZM7U.js} +1 -1
- package/dist/ui/assets/{chunk-5ZQYHXKU-5zebJ3jW.js → chunk-5ZQYHXKU-DqdwSJlO.js} +1 -1
- package/dist/ui/assets/{chunk-727SXJPM-DelmUpvy.js → chunk-727SXJPM-B04SqNWj.js} +1 -1
- package/dist/ui/assets/{chunk-AQP2D5EJ-DMVzBf3M.js → chunk-AQP2D5EJ-DpjCPBWN.js} +1 -1
- package/dist/ui/assets/{chunk-BSJP7CBP-CZHrcpSu.js → chunk-BSJP7CBP-BNOU3k5G.js} +1 -1
- package/dist/ui/assets/{chunk-CSCIHK7Q-C1efTp0O.js → chunk-CSCIHK7Q-iWOtNZm_.js} +1 -1
- package/dist/ui/assets/{chunk-FMBD7UC4-B6axGwgn.js → chunk-FMBD7UC4-BHH_etky.js} +1 -1
- package/dist/ui/assets/{chunk-KSCS5N6A-DSaxbrm0.js → chunk-KSCS5N6A-DbRuazP3.js} +1 -1
- package/dist/ui/assets/{chunk-L5ZTLDWV-D9ZKdVGx.js → chunk-L5ZTLDWV-B2ZZFONi.js} +1 -1
- package/dist/ui/assets/{chunk-LZXEDZCA-DI5_1s00.js → chunk-LZXEDZCA-DryVpwAh.js} +2 -2
- package/dist/ui/assets/{chunk-ND2GUHAM-DQQ4RVLE.js → chunk-ND2GUHAM-2Bb1izqg.js} +1 -1
- package/dist/ui/assets/{chunk-NZK2D7GU-9zJJaDpb.js → chunk-NZK2D7GU-2DhvLbqL.js} +1 -1
- package/dist/ui/assets/{chunk-O5CBEL6O-DUOshAt2.js → chunk-O5CBEL6O-B5oigO7D.js} +1 -1
- package/dist/ui/assets/chunk-QZHKN3VN-BDHgdxoT.js +1 -0
- package/dist/ui/assets/chunk-WU5MYG2G-FDJTP_wT.js +1 -0
- package/dist/ui/assets/{chunk-XPW4576I-DQVL_GAl.js → chunk-XPW4576I-Dmq-O7bc.js} +1 -1
- package/dist/ui/assets/classDiagram-4FO5ZUOK-B5kZsiIt.js +1 -0
- package/dist/ui/assets/classDiagram-v2-Q7XG4LA2-B5kZsiIt.js +1 -0
- package/dist/ui/assets/{cose-bilkent-S5V4N54A-C7m3VlSW.js → cose-bilkent-S5V4N54A-oTsqU1DY.js} +1 -1
- package/dist/ui/assets/{dagre-BM42HDAG-CoU_T6EY.js → dagre-BM42HDAG-CZykCU6B.js} +1 -1
- package/dist/ui/assets/{diagram-2AECGRRQ-C_R7oNKE.js → diagram-2AECGRRQ-BY7clIlO.js} +1 -1
- package/dist/ui/assets/{diagram-5GNKFQAL-UhE2W3Yi.js → diagram-5GNKFQAL-BWdq4hV0.js} +1 -1
- package/dist/ui/assets/{diagram-KO2AKTUF-D4KZCRld.js → diagram-KO2AKTUF-CCGEaiZg.js} +1 -1
- package/dist/ui/assets/{diagram-LMA3HP47-CsOe8-S6.js → diagram-LMA3HP47-CVkepFYU.js} +1 -1
- package/dist/ui/assets/{diagram-OG6HWLK6-Bkbs2V54.js → diagram-OG6HWLK6-f-NjsfLG.js} +1 -1
- package/dist/ui/assets/{dist-BcowSnUl.js → dist-ZqsueX9_.js} +1 -1
- package/dist/ui/assets/{erDiagram-TEJ5UH35-DJXsykZz.js → erDiagram-TEJ5UH35-D8Wn6QP3.js} +1 -1
- package/dist/ui/assets/eventmodeling-FCH6USID-BODDoY6e.js +1 -0
- package/dist/ui/assets/{flowDiagram-I6XJVG4X-Chguj9Xz.js → flowDiagram-I6XJVG4X-BYnhla9k.js} +1 -1
- package/dist/ui/assets/{ganttDiagram-6RSMTGT7-DXdpFesp.js → ganttDiagram-6RSMTGT7-Dpu52ZRF.js} +1 -1
- package/dist/ui/assets/{gitGraph-WXDBUCRP-Doq1CcxB.js → gitGraph-WXDBUCRP-ou8xzQe1.js} +1 -1
- package/dist/ui/assets/{gitGraphDiagram-PVQCEYII-uxGwHEPv.js → gitGraphDiagram-PVQCEYII-BnTuFH7F.js} +1 -1
- package/dist/ui/assets/index-B2mL0c61.js +11 -0
- package/dist/ui/assets/index-sZ1TgAvb.css +1 -0
- package/dist/ui/assets/{info-J43DQDTF-CgWT_d3M.js → info-J43DQDTF-xgUHa7k0.js} +1 -1
- package/dist/ui/assets/{infoDiagram-5YYISTIA-B3oDA2Ct.js → infoDiagram-5YYISTIA-DJBudrwD.js} +1 -1
- package/dist/ui/assets/{ishikawaDiagram-YF4QCWOH-C6l0lvC3.js → ishikawaDiagram-YF4QCWOH-DpFHgERI.js} +1 -1
- package/dist/ui/assets/{journeyDiagram-JHISSGLW-COf53NwC.js → journeyDiagram-JHISSGLW-Cd32hdpY.js} +1 -1
- package/dist/ui/assets/{kanban-definition-UN3LZRKU-DaOPRBld.js → kanban-definition-UN3LZRKU-Dm1V8lr0.js} +1 -1
- package/dist/ui/assets/{line-new3jLu3.js → line-CZu6_PMX.js} +1 -1
- package/dist/ui/assets/{linear-yA22knFB.js → linear-2tkTX_U2.js} +1 -1
- package/dist/ui/assets/{mermaid-parser.core-D8JVCOKU.js → mermaid-parser.core-C4m04cRe.js} +2 -2
- package/dist/ui/assets/{mermaid.core-BCrPyVBK.js → mermaid.core-BPeg1ewg.js} +3 -3
- package/dist/ui/assets/{mindmap-definition-RKZ34NQL-CVcJTWsW.js → mindmap-definition-RKZ34NQL-BENqEkIK.js} +1 -1
- package/dist/ui/assets/{packet-YPE3B663-DlSwpK-G.js → packet-YPE3B663-DNO0oBLH.js} +1 -1
- package/dist/ui/assets/{pie-LRSECV5Y-CyMpbo4C.js → pie-LRSECV5Y-CWoz31oB.js} +1 -1
- package/dist/ui/assets/{pieDiagram-4H26LBE5-Dy7day5R.js → pieDiagram-4H26LBE5-CtmxhUGI.js} +1 -1
- package/dist/ui/assets/{plan-view-CE2ha0qY.js → plan-view-bZtdFbit.js} +4 -4
- package/dist/ui/assets/{quadrantDiagram-W4KKPZXB-CVjVgbaQ.js → quadrantDiagram-W4KKPZXB-BO3IZNbx.js} +1 -1
- package/dist/ui/assets/{radar-GUYGQ44K-DLPfv0jT.js → radar-GUYGQ44K-AEfROz99.js} +1 -1
- package/dist/ui/assets/{requirementDiagram-4Y6WPE33-y_0KOdN8.js → requirementDiagram-4Y6WPE33-D-wQ1szT.js} +1 -1
- package/dist/ui/assets/{sankeyDiagram-5OEKKPKP-8T3b7meL.js → sankeyDiagram-5OEKKPKP-Bj4kD_AJ.js} +1 -1
- package/dist/ui/assets/{sequenceDiagram-3UESZ5HK-Cn8DZiEr.js → sequenceDiagram-3UESZ5HK-M8QVVH74.js} +1 -1
- package/dist/ui/assets/{src-BieOuieI.js → src-DvptJAGq.js} +1 -1
- package/dist/ui/assets/{stateDiagram-AJRCARHV-nPEVGd3E.js → stateDiagram-AJRCARHV-BiPRs9rN.js} +1 -1
- package/dist/ui/assets/stateDiagram-v2-BHNVJYJU-BYjicZlC.js +1 -0
- package/dist/ui/assets/{timeline-definition-PNZ67QCA-Dj_qK0VJ.js → timeline-definition-PNZ67QCA-DS0AGRKw.js} +1 -1
- package/dist/ui/assets/{treeView-BLDUP644-G5Bsebqu.js → treeView-BLDUP644-DJakvUbF.js} +1 -1
- package/dist/ui/assets/{treemap-LRROVOQU-anUEJzTb.js → treemap-LRROVOQU-QXfc2Vwr.js} +1 -1
- package/dist/ui/assets/{vennDiagram-CIIHVFJN-D71ne3dS.js → vennDiagram-CIIHVFJN-CBdJA0hv.js} +1 -1
- package/dist/ui/assets/{wardley-L42UT6IY-DrJilmE_.js → wardley-L42UT6IY-DI9SdW45.js} +1 -1
- package/dist/ui/assets/{wardleyDiagram-YWT4CUSO-B66G4ayp.js → wardleyDiagram-YWT4CUSO-RMmsKLRe.js} +1 -1
- package/dist/ui/assets/{xychartDiagram-2RQKCTM6-CReSRxNG.js → xychartDiagram-2RQKCTM6-DFXccP8B.js} +1 -1
- package/dist/ui/index.html +2 -2
- package/package.json +7 -5
- package/dist/ui/assets/architecture-7EHR7CIX-Cw3I1lil.js +0 -1
- package/dist/ui/assets/channel-CkOta24Z.js +0 -1
- package/dist/ui/assets/chunk-QZHKN3VN-DqRxzBM_.js +0 -1
- package/dist/ui/assets/chunk-WU5MYG2G-B1Mk3aBp.js +0 -1
- package/dist/ui/assets/classDiagram-4FO5ZUOK-BH-5P4jH.js +0 -1
- package/dist/ui/assets/classDiagram-v2-Q7XG4LA2-BH-5P4jH.js +0 -1
- package/dist/ui/assets/eventmodeling-FCH6USID-DSDI1f5T.js +0 -1
- package/dist/ui/assets/index-BsTJ9Ul_.css +0 -1
- package/dist/ui/assets/index-D-TSanrw.js +0 -11
- package/dist/ui/assets/stateDiagram-v2-BHNVJYJU-CKrff-KJ.js +0 -1
|
@@ -1,15 +1,15 @@
|
|
|
1
|
-
// The wrapper content `otacon install` writes
|
|
2
|
-
//
|
|
3
|
-
//
|
|
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
|
|
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 —
|
|
12
|
-
*
|
|
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
|
|
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
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
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
|
|
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}
|
|
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
|
|
91
|
-
(\`${cmd} progress\` at
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
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
|
|
113
|
-
(PR body = the plan summary + the per-phase log; fall back to the
|
|
114
|
-
path when there is no remote)
|
|
115
|
-
|
|
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
|
|
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
|
|
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
|
|
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
|
-
* (
|
|
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
|
|
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
|
|
229
|
-
|
|
230
|
-
|
|
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
|
-
|
|
239
|
-
failure habits
|
|
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
|
|
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
|
|
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
|
|
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,
|
|
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 (
|
|
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":"AAAA,
|
|
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 (
|
|
2
|
-
//
|
|
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
|
|
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":"AAAA,iFAAiF;AACjF,mFAAmF;AACnF,mFAAmF;AACnF,oFAAoF;AACpF,oFAAoF;AACpF,uFAAuF;AACvF,oFAAoF;AACpF,+EAA+E;AAE/E,OAAO,EACL,UAAU,EACV,SAAS,EACT,SAAS,EACT,YAAY,EACZ,YAAY,EACZ,MAAM,EACN,WAAW,EACX,aAAa,GACd,MAAM,SAAS,CAAC;AACjB,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AACzC,OAAO,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAC3C,OAAO,EAAE,MAAM,EAAE,MAAM,cAAc,CAAC;AACtC,OAAO,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AAC7C,OAAO,EAAE,cAAc,EAAE,OAAO,EAAE,MAAM,aAAa,CAAC;AACtD,OAAO,EACL,eAAe,EACf,cAAc,EACd,iBAAiB,GAClB,MAAM,gBAAgB,CAAC;AAExB;;;;;;;;;;;;;GAaG;AACH,MAAM,UAAU,iBAAiB;IAC/B,IAAI,CAAC;QACH,MAAM,IAAI,GAAG,aAAa,CACxB,IAAI,GAAG,CAAC,8BAA8B,EAAE,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CACzD,CAAC;QACF,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC;YAAE,OAAO,SAAS,CAAC;QACxC,IAAI,gBAAgB,CAAC,IAAI,CAAC,IAAI,CAAC;YAAE,OAAO,SAAS,CAAC;QAClD,OAAO,IAAI,CAAC;IACd,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,SAAS,CAAC;IACnB,CAAC;AACH,CAAC;AAKD;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,MAAM,UAAU,aAAa,CAC3B,IAAY,EACZ,KAAyB,EACzB,UAA8B,iBAAiB,EAAE;AACjD,2EAA2E;AAC3E,UAAsD,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,WAAW,CAAC,CAAC,EAAE,CAAC,CAAC;IAEjF,SAAS,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IAE9C,qFAAqF;IACrF,IAAI,KAAK,KAAK,MAAM,IAAI,OAAO,KAAK,SAAS,EAAE,CAAC;QAC9C,MAAM,IAAI,GAAG,SAAS,CAAC,IAAI,EAAE,EAAE,cAAc,EAAE,KAAK,EAAE,CAAC,CAAC;QACxD,IAAI,IAAI,EAAE,cAAc,EAAE,EAAE,CAAC;YAC3B,6EAA6E;YAC7E,iDAAiD;YACjD,IAAI,CAAC;gBACH,IAAI,YAAY,CAAC,IAAI,CAAC,KAAK,YAAY,CAAC,OAAO,CAAC,EAAE,CAAC;oBACjD,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,OAAO,EAAE,KAAK,EAAE,CAAC;gBAC7C,CAAC;YACH,CAAC;YAAC,MAAM,CAAC;gBACP,iFAAiF;YACnF,CAAC;QACH,CAAC;QACD,IAAI,CAAC;YACH,MAAM,CAAC,IAAI,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,sDAAsD;YACrF,OAAO,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC;YACvB,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC;QAC5C,CAAC;QAAC,MAAM,CAAC;YACP,6EAA6E;QAC/E,CAAC;IACH,CAAC;IAED,4EAA4E;IAC5E,MAAM,OAAO,GAAG,OAAO,EAAE,CAAC;IAC1B,MAAM,IAAI,GAAG,SAAS,CAAC,IAAI,EAAE,EAAE,cAAc,EAAE,KAAK,EAAE,CAAC,CAAC;IACxD,IAAI,IAAI,EAAE,MAAM,EAAE,IAAI,YAAY,CAAC,IAAI,EAAE,MAAM,CAAC,KAAK,OAAO,EAAE,CAAC;QAC7D,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,KAAK,EAAE,CAAC;IAC1C,CAAC;IACD,MAAM,CAAC,IAAI,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,+CAA+C;IAC9E,aAAa,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;IAC7B,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC;AACzC,CAAC;AAYD;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AACH,MAAM,UAAU,wBAAwB,CACtC,OAAoB,EAAE;IAEtB,MAAM,SAAS,GAA0C,EAAE,CAAC;IAC5D,IAAI,CAAC;QACH,MAAM,SAAS,GAAG,IAAI,CAAC,SAAS,IAAI,WAAW,CAAC;QAChD,6DAA6D;QAC7D,IAAI,SAAS,EAAE;YAAE,OAAO,EAAE,CAAC;QAE3B,MAAM,OAAO,GAAG,SAAS,IAAI,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,iBAAiB,EAAE,CAAC;QACvE,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,IAAI,OAAO,CAAC,GAAG,EAAE,CAAC;QAEtC,kFAAkF;QAClF,oFAAoF;QACpF,4EAA4E;QAC5E,MAAM,UAAU,GAAkD;YAChE,EAAE,IAAI,EAAE,eAAe,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE;YAC1C,EAAE,IAAI,EAAE,cAAc,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE;YACzC,EAAE,IAAI,EAAE,iBAAiB,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE;SAC7C,CAAC;QACF,MAAM,IAAI,GAAG,YAAY,CAAC,GAAG,CAAC,CAAC;QAC/B,IAAI,IAAI,KAAK,SAAS,EAAE,CAAC;YACvB,MAAM,OAAO,GAAG,EAAE,IAAI,EAAE,SAAS,EAAE,IAAI,EAAW,CAAC;YACnD,UAAU,CAAC,IAAI,CACb,EAAE,IAAI,EAAE,eAAe,CAAC,OAAO,CAAC,EAAE,KAAK,EAAE,SAAS,EAAE,EACpD,EAAE,IAAI,EAAE,cAAc,CAAC,OAAO,CAAC,EAAE,KAAK,EAAE,SAAS,EAAE,EACnD,EAAE,IAAI,EAAE,iBAAiB,CAAC,OAAO,CAAC,EAAE,KAAK,EAAE,SAAS,EAAE,CACvD,CAAC;QACJ,CAAC;QAED,KAAK,MAAM,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,UAAU,EAAE,CAAC;YACzC,IAAI,CAAC,gBAAgB,CAAC,IAAI,CAAC;gBAAE,SAAS,CAAC,sCAAsC;YAC7E,IAAI,CAAC;gBACH,MAAM,MAAM,GAAG,aAAa,CAAC,IAAI,EAAE,KAAK,EAAE,OAAO,CAAC,CAAC;gBACnD,IAAI,MAAM,CAAC,OAAO,EAAE,CAAC;oBACnB,MAAM,CAAC,6BAA6B,IAAI,KAAK,MAAM,CAAC,IAAI,GAAG,CAAC,CAAC;oBAC7D,SAAS,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,IAAI,EAAE,MAAM,CAAC,IAAI,EAAE,CAAC,CAAC;gBAC9C,CAAC;YACH,CAAC;YAAC,MAAM,CAAC;gBACP,2EAA2E;gBAC3E,8DAA8D;YAChE,CAAC;QACH,CAAC;IACH,CAAC;IAAC,MAAM,CAAC;QACP,8EAA8E;QAC9E,0EAA0E;IAC5E,CAAC;IACD,OAAO,SAAS,CAAC;AACnB,CAAC;AAED;;;;;;;;GAQG;AACH,SAAS,gBAAgB,CAAC,IAAY;IACpC,MAAM,IAAI,GAAG,SAAS,CAAC,IAAI,EAAE,EAAE,cAAc,EAAE,KAAK,EAAE,CAAC,CAAC;IACxD,IAAI,IAAI,KAAK,SAAS;QAAE,OAAO,KAAK,CAAC;IACrC,IAAI,IAAI,CAAC,cAAc,EAAE;QAAE,OAAO,IAAI,CAAC;IACvC,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE;QAAE,OAAO,KAAK,CAAC;IACjC,IAAI,CAAC;QACH,OAAO,YAAY,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC,QAAQ,CAAC,cAAc,CAAC,CAAC;IAC7D,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,KAAK,CAAC;IACf,CAAC;AACH,CAAC"}
|
package/dist/cli/main.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
// otacon CLI dispatch (
|
|
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,14 +12,17 @@ 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";
|
|
19
|
+
import { updateCommand } from "./commands/update.js";
|
|
18
20
|
import { waitCommand } from "./commands/wait.js";
|
|
19
21
|
import { CliError, printJson } from "./output.js";
|
|
20
|
-
const USAGE = "usage: otacon <start|submit|wait|ask|answer|progress|implement-done|status|open|config|clean|install|doctor|expose> [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" +
|
|
21
23
|
" otacon config [open] open the Settings web UI in the browser\n" +
|
|
22
|
-
" otacon config get <key> print the merged value of one config key"
|
|
24
|
+
" otacon config get <key> print the merged value of one config key\n" +
|
|
25
|
+
" otacon update [--check] update the global install to the latest published version";
|
|
23
26
|
async function dispatch(command, argv) {
|
|
24
27
|
switch (command) {
|
|
25
28
|
case "start":
|
|
@@ -36,6 +39,8 @@ async function dispatch(command, argv) {
|
|
|
36
39
|
return progressCommand(argv);
|
|
37
40
|
case "implement-done":
|
|
38
41
|
return implementDoneCommand(argv);
|
|
42
|
+
case "resume":
|
|
43
|
+
return resumeCommand(argv);
|
|
39
44
|
case "status":
|
|
40
45
|
return statusCommand(argv);
|
|
41
46
|
case "open":
|
|
@@ -50,6 +55,8 @@ async function dispatch(command, argv) {
|
|
|
50
55
|
return doctorCommand(argv);
|
|
51
56
|
case "expose":
|
|
52
57
|
return exposeCommand(argv);
|
|
58
|
+
case "update":
|
|
59
|
+
return updateCommand(argv);
|
|
53
60
|
default:
|
|
54
61
|
throw new CliError("E_USAGE", USAGE, 2);
|
|
55
62
|
}
|
package/dist/cli/main.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"main.js","sourceRoot":"","sources":["../../src/cli/main.ts"],"names":[],"mappings":";AACA
|
|
1
|
+
{"version":3,"file":"main.js","sourceRoot":"","sources":["../../src/cli/main.ts"],"names":[],"mappings":";AACA,6FAA6F;AAC7F,0EAA0E;AAC1E,iDAAiD;AAEjD,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AACrD,OAAO,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAC/C,OAAO,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AACnD,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AACrD,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AACrD,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AACrD,OAAO,EAAE,oBAAoB,EAAE,MAAM,8BAA8B,CAAC;AACpE,OAAO,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AACvD,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AACjD,OAAO,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AACzD,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AACrD,OAAO,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AACnD,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AACrD,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AACrD,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AACrD,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AACjD,OAAO,EAAE,QAAQ,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAElD,MAAM,KAAK,GACT,+IAA+I;IAC/I,4EAA4E;IAC5E,6EAA6E;IAC7E,4FAA4F,CAAC;AAE/F,KAAK,UAAU,QAAQ,CAAC,OAA2B,EAAE,IAAc;IACjE,QAAQ,OAAO,EAAE,CAAC;QAChB,KAAK,OAAO;YACV,OAAO,YAAY,CAAC,IAAI,CAAC,CAAC;QAC5B,KAAK,QAAQ;YACX,OAAO,aAAa,CAAC,IAAI,CAAC,CAAC;QAC7B,KAAK,MAAM;YACT,OAAO,WAAW,CAAC,IAAI,CAAC,CAAC;QAC3B,KAAK,KAAK;YACR,OAAO,UAAU,CAAC,IAAI,CAAC,CAAC;QAC1B,KAAK,QAAQ;YACX,OAAO,aAAa,CAAC,IAAI,CAAC,CAAC;QAC7B,KAAK,UAAU;YACb,OAAO,eAAe,CAAC,IAAI,CAAC,CAAC;QAC/B,KAAK,gBAAgB;YACnB,OAAO,oBAAoB,CAAC,IAAI,CAAC,CAAC;QACpC,KAAK,QAAQ;YACX,OAAO,aAAa,CAAC,IAAI,CAAC,CAAC;QAC7B,KAAK,QAAQ;YACX,OAAO,aAAa,CAAC,IAAI,CAAC,CAAC;QAC7B,KAAK,MAAM;YACT,OAAO,WAAW,CAAC,IAAI,CAAC,CAAC;QAC3B,KAAK,QAAQ;YACX,OAAO,aAAa,CAAC,IAAI,CAAC,CAAC;QAC7B,KAAK,OAAO;YACV,OAAO,YAAY,CAAC,IAAI,CAAC,CAAC;QAC5B,KAAK,SAAS;YACZ,OAAO,cAAc,CAAC,IAAI,CAAC,CAAC;QAC9B,KAAK,QAAQ;YACX,OAAO,aAAa,CAAC,IAAI,CAAC,CAAC;QAC7B,KAAK,QAAQ;YACX,OAAO,aAAa,CAAC,IAAI,CAAC,CAAC;QAC7B,KAAK,QAAQ;YACX,OAAO,aAAa,CAAC,IAAI,CAAC,CAAC;QAC7B;YACE,MAAM,IAAI,QAAQ,CAAC,SAAS,EAAE,KAAK,EAAE,CAAC,CAAC,CAAC;IAC5C,CAAC;AACH,CAAC;AAED,MAAM,gBAAgB,GAAG,CAAC,KAAc,EAAkB,EAAE,CAC1D,KAAK,YAAY,KAAK;IACtB,CAAE,KAA+B,CAAC,IAAI,EAAE,UAAU,CAAC,gBAAgB,CAAC,IAAI,KAAK,CAAC,CAAC;AAEjF,yEAAyE;AACzE,SAAS,IAAI,CAAC,IAAY;IACxB,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,EAAE,GAAG,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC;AACrD,CAAC;AAED,QAAQ,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CACnD,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,EACpB,CAAC,KAAc,EAAE,EAAE;IACjB,IAAI,KAAK,YAAY,QAAQ,EAAE,CAAC;QAC9B,SAAS,CAAC,KAAK,CAAC,SAAS,EAAE,CAAC,CAAC;QAC7B,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC;IACvB,CAAC;SAAM,IAAI,gBAAgB,CAAC,KAAK,CAAC,EAAE,CAAC;QACnC,SAAS,CAAC,EAAE,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,EAAE,IAAI,EAAE,SAAS,EAAE,OAAO,EAAE,GAAG,KAAK,CAAC,OAAO,KAAK,KAAK,EAAE,EAAE,EAAE,CAAC,CAAC;QAC5F,IAAI,CAAC,CAAC,CAAC,CAAC;IACV,CAAC;SAAM,CAAC;QACN,MAAM,OAAO,GAAG,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;QACvE,SAAS,CAAC,EAAE,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,EAAE,IAAI,EAAE,YAAY,EAAE,OAAO,EAAE,EAAE,CAAC,CAAC;QACjE,IAAI,CAAC,CAAC,CAAC,CAAC;IACV,CAAC;AACH,CAAC,CACF,CAAC"}
|