otacon 0.1.0 → 0.1.2
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 +101 -64
- package/dist/cli/browser.js +55 -0
- package/dist/cli/browser.js.map +1 -0
- package/dist/cli/commands/clean.js +3 -2
- package/dist/cli/commands/clean.js.map +1 -1
- package/dist/cli/commands/config.js +62 -0
- package/dist/cli/commands/config.js.map +1 -0
- package/dist/cli/commands/doctor.js +41 -21
- package/dist/cli/commands/doctor.js.map +1 -1
- package/dist/cli/commands/install.js +53 -30
- package/dist/cli/commands/install.js.map +1 -1
- package/dist/cli/commands/open.js +14 -14
- package/dist/cli/commands/open.js.map +1 -1
- package/dist/cli/commands/start.js +1 -22
- package/dist/cli/commands/start.js.map +1 -1
- package/dist/cli/install/assets.js +35 -43
- package/dist/cli/install/assets.js.map +1 -1
- package/dist/cli/install/locations.js +15 -25
- package/dist/cli/install/locations.js.map +1 -1
- package/dist/cli/main.js +6 -1
- package/dist/cli/main.js.map +1 -1
- package/dist/daemon/app.js +281 -54
- package/dist/daemon/app.js.map +1 -1
- package/dist/daemon/approve.js +49 -11
- package/dist/daemon/approve.js.map +1 -1
- package/dist/daemon/store.js +39 -2
- package/dist/daemon/store.js.map +1 -1
- package/dist/daemon/threads.js +11 -0
- package/dist/daemon/threads.js.map +1 -1
- package/dist/daemon/ui.js +3 -0
- package/dist/daemon/ui.js.map +1 -1
- package/dist/shared/config.js +290 -45
- package/dist/shared/config.js.map +1 -1
- package/dist/shared/paths.js +33 -5
- package/dist/shared/paths.js.map +1 -1
- package/dist/shared/types.js +6 -2
- package/dist/shared/types.js.map +1 -1
- package/dist/shared/version.js +1 -1
- package/dist/ui/assets/{arc-HhPfdCPZ.js → arc-KT3ZnaMp.js} +1 -1
- package/dist/ui/assets/architecture-7EHR7CIX-Cw3I1lil.js +1 -0
- package/dist/ui/assets/{architectureDiagram-3BPJPVTR-D2PIxGOb.js → architectureDiagram-3BPJPVTR-DLu0UM7N.js} +1 -1
- package/dist/ui/assets/{blockDiagram-GPEHLZMM-DQ3Dn17h.js → blockDiagram-GPEHLZMM-B8wApEWC.js} +1 -1
- package/dist/ui/assets/{c4Diagram-AAUBKEIU-DxITrQgS.js → c4Diagram-AAUBKEIU-BNS5gmQS.js} +1 -1
- package/dist/ui/assets/channel-CkOta24Z.js +1 -0
- package/dist/ui/assets/{chunk-2J33WTMH-Du1JoPx5.js → chunk-2J33WTMH-CTY2etwY.js} +1 -1
- package/dist/ui/assets/{chunk-3OPIFGDE-Dn7x2Yqf.js → chunk-3OPIFGDE-DZM4Sz84.js} +1 -1
- package/dist/ui/assets/{chunk-4BX2VUAB-DVnrE-4n.js → chunk-4BX2VUAB-sGwrrXIO.js} +1 -1
- package/dist/ui/assets/{chunk-55IACEB6-BAhFAimA.js → chunk-55IACEB6-CGlNp76o.js} +1 -1
- package/dist/ui/assets/{chunk-5ZQYHXKU-0hEZptem.js → chunk-5ZQYHXKU-5zebJ3jW.js} +1 -1
- package/dist/ui/assets/{chunk-727SXJPM-C1FN_cI3.js → chunk-727SXJPM-DelmUpvy.js} +1 -1
- package/dist/ui/assets/{chunk-AQP2D5EJ-A656OBd4.js → chunk-AQP2D5EJ-DMVzBf3M.js} +1 -1
- package/dist/ui/assets/{chunk-BSJP7CBP-D8oMbjm8.js → chunk-BSJP7CBP-CZHrcpSu.js} +1 -1
- package/dist/ui/assets/{chunk-CSCIHK7Q-DjIL8GLi.js → chunk-CSCIHK7Q-C1efTp0O.js} +1 -1
- package/dist/ui/assets/{chunk-FMBD7UC4-Otblfqvz.js → chunk-FMBD7UC4-B6axGwgn.js} +1 -1
- package/dist/ui/assets/{chunk-KSCS5N6A-BOjTvm3H.js → chunk-KSCS5N6A-DSaxbrm0.js} +1 -1
- package/dist/ui/assets/{chunk-L5ZTLDWV-CaTLaw6L.js → chunk-L5ZTLDWV-D9ZKdVGx.js} +1 -1
- package/dist/ui/assets/{chunk-LZXEDZCA-Dq5p7qrD.js → chunk-LZXEDZCA-DI5_1s00.js} +2 -2
- package/dist/ui/assets/{chunk-ND2GUHAM-jZ_NNnWi.js → chunk-ND2GUHAM-DQQ4RVLE.js} +1 -1
- package/dist/ui/assets/{chunk-NZK2D7GU-U_7l_sCh.js → chunk-NZK2D7GU-9zJJaDpb.js} +1 -1
- package/dist/ui/assets/{chunk-O5CBEL6O-MewqqNB7.js → chunk-O5CBEL6O-DUOshAt2.js} +1 -1
- package/dist/ui/assets/chunk-QZHKN3VN-DqRxzBM_.js +1 -0
- package/dist/ui/assets/chunk-WU5MYG2G-B1Mk3aBp.js +1 -0
- package/dist/ui/assets/{chunk-XPW4576I-D5ArxNEF.js → chunk-XPW4576I-DQVL_GAl.js} +1 -1
- package/dist/ui/assets/classDiagram-4FO5ZUOK-BH-5P4jH.js +1 -0
- package/dist/ui/assets/classDiagram-v2-Q7XG4LA2-BH-5P4jH.js +1 -0
- package/dist/ui/assets/{cose-bilkent-S5V4N54A-PFXzf7WV.js → cose-bilkent-S5V4N54A-C7m3VlSW.js} +1 -1
- package/dist/ui/assets/{dagre-BM42HDAG-xrCfjZuZ.js → dagre-BM42HDAG-CoU_T6EY.js} +1 -1
- package/dist/ui/assets/{diagram-2AECGRRQ-BFf-cyKY.js → diagram-2AECGRRQ-C_R7oNKE.js} +1 -1
- package/dist/ui/assets/{diagram-5GNKFQAL-kNPV4NfV.js → diagram-5GNKFQAL-UhE2W3Yi.js} +1 -1
- package/dist/ui/assets/{diagram-KO2AKTUF-ByC1IUwG.js → diagram-KO2AKTUF-D4KZCRld.js} +1 -1
- package/dist/ui/assets/{diagram-LMA3HP47-DZIJMPK0.js → diagram-LMA3HP47-CsOe8-S6.js} +1 -1
- package/dist/ui/assets/{diagram-OG6HWLK6-CSDED9A-.js → diagram-OG6HWLK6-Bkbs2V54.js} +1 -1
- package/dist/ui/assets/{dist-YwjsDswi.js → dist-BcowSnUl.js} +1 -1
- package/dist/ui/assets/{erDiagram-TEJ5UH35-yuzvjE6J.js → erDiagram-TEJ5UH35-DJXsykZz.js} +1 -1
- package/dist/ui/assets/eventmodeling-FCH6USID-DSDI1f5T.js +1 -0
- package/dist/ui/assets/{flowDiagram-I6XJVG4X-ApPtVyYM.js → flowDiagram-I6XJVG4X-Chguj9Xz.js} +1 -1
- package/dist/ui/assets/{ganttDiagram-6RSMTGT7-BeMLXtAr.js → ganttDiagram-6RSMTGT7-DXdpFesp.js} +1 -1
- package/dist/ui/assets/{gitGraph-WXDBUCRP-JmTTBa7j.js → gitGraph-WXDBUCRP-Doq1CcxB.js} +1 -1
- package/dist/ui/assets/{gitGraphDiagram-PVQCEYII-Cjjnjs71.js → gitGraphDiagram-PVQCEYII-uxGwHEPv.js} +1 -1
- package/dist/ui/assets/index-BsTJ9Ul_.css +1 -0
- package/dist/ui/assets/index-D-TSanrw.js +11 -0
- package/dist/ui/assets/{info-J43DQDTF-8vZ3gome.js → info-J43DQDTF-CgWT_d3M.js} +1 -1
- package/dist/ui/assets/{infoDiagram-5YYISTIA-CnMk1cA-.js → infoDiagram-5YYISTIA-B3oDA2Ct.js} +1 -1
- package/dist/ui/assets/{ishikawaDiagram-YF4QCWOH-Bl8z6huD.js → ishikawaDiagram-YF4QCWOH-C6l0lvC3.js} +1 -1
- package/dist/ui/assets/{journeyDiagram-JHISSGLW-DYIVfMpS.js → journeyDiagram-JHISSGLW-COf53NwC.js} +1 -1
- package/dist/ui/assets/{kanban-definition-UN3LZRKU-BnR0ZzOz.js → kanban-definition-UN3LZRKU-DaOPRBld.js} +1 -1
- package/dist/ui/assets/{line-DcBdQit6.js → line-new3jLu3.js} +1 -1
- package/dist/ui/assets/{linear-HKjRHFAO.js → linear-yA22knFB.js} +1 -1
- package/dist/ui/assets/{mermaid-parser.core-DkYXrPlA.js → mermaid-parser.core-D8JVCOKU.js} +2 -2
- package/dist/ui/assets/{mermaid.core-BmkfCI3b.js → mermaid.core-BCrPyVBK.js} +3 -3
- package/dist/ui/assets/{mindmap-definition-RKZ34NQL-sIAd4nDi.js → mindmap-definition-RKZ34NQL-CVcJTWsW.js} +1 -1
- package/dist/ui/assets/{packet-YPE3B663-BxbxcfXN.js → packet-YPE3B663-DlSwpK-G.js} +1 -1
- package/dist/ui/assets/{pie-LRSECV5Y-BJxazjNs.js → pie-LRSECV5Y-CyMpbo4C.js} +1 -1
- package/dist/ui/assets/{pieDiagram-4H26LBE5-BiOhc9GR.js → pieDiagram-4H26LBE5-Dy7day5R.js} +1 -1
- package/dist/ui/assets/{plan-view-CH6NzUDb.js → plan-view-CE2ha0qY.js} +3 -3
- package/dist/ui/assets/{quadrantDiagram-W4KKPZXB-CVyHbWgo.js → quadrantDiagram-W4KKPZXB-CVjVgbaQ.js} +1 -1
- package/dist/ui/assets/{radar-GUYGQ44K-D9ohbnbV.js → radar-GUYGQ44K-DLPfv0jT.js} +1 -1
- package/dist/ui/assets/{requirementDiagram-4Y6WPE33-Ba24_hqc.js → requirementDiagram-4Y6WPE33-y_0KOdN8.js} +1 -1
- package/dist/ui/assets/{sankeyDiagram-5OEKKPKP-CxD4wiPL.js → sankeyDiagram-5OEKKPKP-8T3b7meL.js} +1 -1
- package/dist/ui/assets/{sequenceDiagram-3UESZ5HK-7qA7lD61.js → sequenceDiagram-3UESZ5HK-Cn8DZiEr.js} +1 -1
- package/dist/ui/assets/{src-IM8AE8MK.js → src-BieOuieI.js} +1 -1
- package/dist/ui/assets/{stateDiagram-AJRCARHV-DNElRCuH.js → stateDiagram-AJRCARHV-nPEVGd3E.js} +1 -1
- package/dist/ui/assets/stateDiagram-v2-BHNVJYJU-CKrff-KJ.js +1 -0
- package/dist/ui/assets/{timeline-definition-PNZ67QCA-ChYC4Grd.js → timeline-definition-PNZ67QCA-Dj_qK0VJ.js} +1 -1
- package/dist/ui/assets/{treeView-BLDUP644-Il0KnMi_.js → treeView-BLDUP644-G5Bsebqu.js} +1 -1
- package/dist/ui/assets/{treemap-LRROVOQU-CIiKcdRo.js → treemap-LRROVOQU-anUEJzTb.js} +1 -1
- package/dist/ui/assets/{vennDiagram-CIIHVFJN-Ulhkum9i.js → vennDiagram-CIIHVFJN-D71ne3dS.js} +1 -1
- package/dist/ui/assets/{wardley-L42UT6IY-BNd4ljz7.js → wardley-L42UT6IY-DrJilmE_.js} +1 -1
- package/dist/ui/assets/{wardleyDiagram-YWT4CUSO-BicXxh84.js → wardleyDiagram-YWT4CUSO-B66G4ayp.js} +1 -1
- package/dist/ui/assets/{xychartDiagram-2RQKCTM6-Duf-m_th.js → xychartDiagram-2RQKCTM6-CReSRxNG.js} +1 -1
- package/dist/ui/index.html +2 -2
- package/package.json +1 -1
- package/dist/ui/assets/architecture-7EHR7CIX-BPLblcyi.js +0 -1
- package/dist/ui/assets/channel-ipcU8ZNI.js +0 -1
- package/dist/ui/assets/chunk-QZHKN3VN-DzGPH44B.js +0 -1
- package/dist/ui/assets/chunk-WU5MYG2G-DyEIVjoo.js +0 -1
- package/dist/ui/assets/classDiagram-4FO5ZUOK-Byg2Hl9D.js +0 -1
- package/dist/ui/assets/classDiagram-v2-Q7XG4LA2-Byg2Hl9D.js +0 -1
- package/dist/ui/assets/eventmodeling-FCH6USID-CZR4eNG-.js +0 -1
- package/dist/ui/assets/index-BFQVRcSI.js +0 -11
- package/dist/ui/assets/index-Bj_kTrwP.css +0 -1
- package/dist/ui/assets/stateDiagram-v2-BHNVJYJU-D6qTYpY3.js +0 -1
package/dist/shared/config.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { readFileSync } from "node:fs";
|
|
2
|
-
import { globalConfigPath, repoConfigPath } from "./paths.js";
|
|
2
|
+
import { globalConfigPath, repoConfigPath, repoLocalConfigPath } from "./paths.js";
|
|
3
3
|
export const DEFAULT_CONFIG = {
|
|
4
4
|
budgets: {
|
|
5
5
|
summaryLines: 5,
|
|
@@ -20,7 +20,209 @@ export const DEFAULT_CONFIG = {
|
|
|
20
20
|
noteMaxChars: 200,
|
|
21
21
|
},
|
|
22
22
|
notifications: { desktop: true },
|
|
23
|
+
worktree: { dir: "~/.otacon/worktrees" },
|
|
24
|
+
plans: { dir: ".otacon/plans" },
|
|
23
25
|
};
|
|
26
|
+
/**
|
|
27
|
+
* One entry per leaf config key. The guard test asserts this enumerates exactly
|
|
28
|
+
* the leaves of DEFAULT_CONFIG, so config can never grow without a schema entry.
|
|
29
|
+
*/
|
|
30
|
+
export const CONFIG_SCHEMA = [
|
|
31
|
+
// budgets — read-path line caps (DESIGN.md §4, §5)
|
|
32
|
+
{
|
|
33
|
+
section: "budgets",
|
|
34
|
+
key: "summaryLines",
|
|
35
|
+
label: "Summary lines",
|
|
36
|
+
description: "Max lines in a plan's summary block.",
|
|
37
|
+
type: "int",
|
|
38
|
+
default: DEFAULT_CONFIG.budgets.summaryLines,
|
|
39
|
+
min: 1,
|
|
40
|
+
},
|
|
41
|
+
{
|
|
42
|
+
section: "budgets",
|
|
43
|
+
key: "contractLines",
|
|
44
|
+
label: "Contract lines",
|
|
45
|
+
description: "Max lines in the optional ## Contract section.",
|
|
46
|
+
type: "int",
|
|
47
|
+
default: DEFAULT_CONFIG.budgets.contractLines,
|
|
48
|
+
min: 1,
|
|
49
|
+
},
|
|
50
|
+
{
|
|
51
|
+
section: "budgets",
|
|
52
|
+
key: "impactLines",
|
|
53
|
+
label: "Impact lines",
|
|
54
|
+
description: "Max lines in the optional ## Impact (blast-radius) section.",
|
|
55
|
+
type: "int",
|
|
56
|
+
default: DEFAULT_CONFIG.budgets.impactLines,
|
|
57
|
+
min: 1,
|
|
58
|
+
},
|
|
59
|
+
{
|
|
60
|
+
section: "budgets",
|
|
61
|
+
key: "decisionEntryLines",
|
|
62
|
+
label: "Decision entry lines",
|
|
63
|
+
description: "Max lines per decision-record entry.",
|
|
64
|
+
type: "int",
|
|
65
|
+
default: DEFAULT_CONFIG.budgets.decisionEntryLines,
|
|
66
|
+
min: 1,
|
|
67
|
+
},
|
|
68
|
+
{
|
|
69
|
+
section: "budgets",
|
|
70
|
+
key: "phaseGoalLines",
|
|
71
|
+
label: "Phase goal lines",
|
|
72
|
+
description: "Max lines in a phase's goal block.",
|
|
73
|
+
type: "int",
|
|
74
|
+
default: DEFAULT_CONFIG.budgets.phaseGoalLines,
|
|
75
|
+
min: 1,
|
|
76
|
+
},
|
|
77
|
+
{
|
|
78
|
+
section: "budgets",
|
|
79
|
+
key: "phaseVerificationLines",
|
|
80
|
+
label: "Phase verification lines",
|
|
81
|
+
description: "Max lines in a phase's verification block.",
|
|
82
|
+
type: "int",
|
|
83
|
+
default: DEFAULT_CONFIG.budgets.phaseVerificationLines,
|
|
84
|
+
min: 1,
|
|
85
|
+
},
|
|
86
|
+
{
|
|
87
|
+
section: "budgets",
|
|
88
|
+
key: "gwtMaxScenarios",
|
|
89
|
+
label: "Max GWT scenarios",
|
|
90
|
+
description: "Max Given/When/Then scenarios in one phase's gwt block.",
|
|
91
|
+
type: "int",
|
|
92
|
+
default: DEFAULT_CONFIG.budgets.gwtMaxScenarios,
|
|
93
|
+
min: 1,
|
|
94
|
+
},
|
|
95
|
+
{
|
|
96
|
+
section: "budgets",
|
|
97
|
+
key: "risksMaxItems",
|
|
98
|
+
label: "Max risk items",
|
|
99
|
+
description: "Max entries in the risks list.",
|
|
100
|
+
type: "int",
|
|
101
|
+
default: DEFAULT_CONFIG.budgets.risksMaxItems,
|
|
102
|
+
min: 1,
|
|
103
|
+
},
|
|
104
|
+
{
|
|
105
|
+
section: "budgets",
|
|
106
|
+
key: "riskEntryLines",
|
|
107
|
+
label: "Risk entry lines",
|
|
108
|
+
description: "Max lines per risk entry.",
|
|
109
|
+
type: "int",
|
|
110
|
+
default: DEFAULT_CONFIG.budgets.riskEntryLines,
|
|
111
|
+
min: 1,
|
|
112
|
+
},
|
|
113
|
+
{
|
|
114
|
+
section: "budgets",
|
|
115
|
+
key: "maxFencesPerReadSection",
|
|
116
|
+
label: "Max fences per section",
|
|
117
|
+
description: "Max fenced blocks in one read-path section.",
|
|
118
|
+
type: "int",
|
|
119
|
+
default: DEFAULT_CONFIG.budgets.maxFencesPerReadSection,
|
|
120
|
+
min: 1,
|
|
121
|
+
},
|
|
122
|
+
{
|
|
123
|
+
section: "budgets",
|
|
124
|
+
key: "maxVisualsPerReadSection",
|
|
125
|
+
label: "Max visuals per section",
|
|
126
|
+
description: "Max markdown-native visuals (callouts, matrices) per read-path section.",
|
|
127
|
+
type: "int",
|
|
128
|
+
default: DEFAULT_CONFIG.budgets.maxVisualsPerReadSection,
|
|
129
|
+
min: 1,
|
|
130
|
+
},
|
|
131
|
+
{
|
|
132
|
+
section: "budgets",
|
|
133
|
+
key: "detailsSoftCapLines",
|
|
134
|
+
label: "Details soft cap",
|
|
135
|
+
description: "Soft cap on raw lines inside a details block.",
|
|
136
|
+
type: "int",
|
|
137
|
+
default: DEFAULT_CONFIG.budgets.detailsSoftCapLines,
|
|
138
|
+
min: 1,
|
|
139
|
+
},
|
|
140
|
+
// activity — live feed tuning (DESIGN.md §6, §15)
|
|
141
|
+
{
|
|
142
|
+
section: "activity",
|
|
143
|
+
key: "cap",
|
|
144
|
+
label: "Activity feed cap",
|
|
145
|
+
description: "How many newest progress notes the feed keeps.",
|
|
146
|
+
type: "int",
|
|
147
|
+
default: DEFAULT_CONFIG.activity.cap,
|
|
148
|
+
min: 1,
|
|
149
|
+
},
|
|
150
|
+
{
|
|
151
|
+
section: "activity",
|
|
152
|
+
key: "noteMaxChars",
|
|
153
|
+
label: "Note max characters",
|
|
154
|
+
description: "Server-side trim length for an over-long progress note.",
|
|
155
|
+
type: "int",
|
|
156
|
+
default: DEFAULT_CONFIG.activity.noteMaxChars,
|
|
157
|
+
min: 1,
|
|
158
|
+
},
|
|
159
|
+
// notifications — attention banners (DESIGN.md §6)
|
|
160
|
+
{
|
|
161
|
+
section: "notifications",
|
|
162
|
+
key: "desktop",
|
|
163
|
+
label: "Desktop notifications",
|
|
164
|
+
description: "Native macOS banner when a session needs your attention.",
|
|
165
|
+
type: "bool",
|
|
166
|
+
default: DEFAULT_CONFIG.notifications.desktop,
|
|
167
|
+
},
|
|
168
|
+
// worktree — Approve & Implement build location (DESIGN.md §12)
|
|
169
|
+
{
|
|
170
|
+
section: "worktree",
|
|
171
|
+
key: "dir",
|
|
172
|
+
label: "Worktree directory",
|
|
173
|
+
description: "Base dir for Approve & Implement build worktrees (default ~/.otacon/worktrees, outside the repo).",
|
|
174
|
+
type: "path",
|
|
175
|
+
default: DEFAULT_CONFIG.worktree.dir,
|
|
176
|
+
},
|
|
177
|
+
// plans — where Save writes the approved plan's project copy (DESIGN.md §12)
|
|
178
|
+
{
|
|
179
|
+
section: "plans",
|
|
180
|
+
key: "dir",
|
|
181
|
+
label: "Plans directory",
|
|
182
|
+
description: "Where Save writes the approved plan copy in the project (repo-relative).",
|
|
183
|
+
type: "path",
|
|
184
|
+
default: DEFAULT_CONFIG.plans.dir,
|
|
185
|
+
},
|
|
186
|
+
];
|
|
187
|
+
/**
|
|
188
|
+
* Validate one raw value against a field's type rule, shared by loadConfig's
|
|
189
|
+
* overlay and the config API validator:
|
|
190
|
+
* int → finite number, > 0 (and >= field.min if set)
|
|
191
|
+
* bool → boolean
|
|
192
|
+
* path → non-empty string (trimmed)
|
|
193
|
+
*/
|
|
194
|
+
export function coerceFieldValue(field, raw) {
|
|
195
|
+
switch (field.type) {
|
|
196
|
+
case "int": {
|
|
197
|
+
if (typeof raw !== "number" || !Number.isFinite(raw))
|
|
198
|
+
return { ok: false };
|
|
199
|
+
if (raw <= 0)
|
|
200
|
+
return { ok: false };
|
|
201
|
+
if (field.min !== undefined && raw < field.min)
|
|
202
|
+
return { ok: false };
|
|
203
|
+
return { ok: true, value: raw };
|
|
204
|
+
}
|
|
205
|
+
case "bool": {
|
|
206
|
+
if (typeof raw !== "boolean")
|
|
207
|
+
return { ok: false };
|
|
208
|
+
return { ok: true, value: raw };
|
|
209
|
+
}
|
|
210
|
+
case "path": {
|
|
211
|
+
if (typeof raw !== "string")
|
|
212
|
+
return { ok: false };
|
|
213
|
+
const trimmed = raw.trim();
|
|
214
|
+
if (trimmed.length === 0)
|
|
215
|
+
return { ok: false };
|
|
216
|
+
return { ok: true, value: trimmed };
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
}
|
|
220
|
+
const SCHEMA_BY_SECTION = new Map();
|
|
221
|
+
for (const field of CONFIG_SCHEMA) {
|
|
222
|
+
const list = SCHEMA_BY_SECTION.get(field.section) ?? [];
|
|
223
|
+
list.push(field);
|
|
224
|
+
SCHEMA_BY_SECTION.set(field.section, list);
|
|
225
|
+
}
|
|
24
226
|
function readJsonFile(path) {
|
|
25
227
|
try {
|
|
26
228
|
return JSON.parse(readFileSync(path, "utf8"));
|
|
@@ -30,64 +232,107 @@ function readJsonFile(path) {
|
|
|
30
232
|
}
|
|
31
233
|
}
|
|
32
234
|
/**
|
|
33
|
-
*
|
|
34
|
-
*
|
|
35
|
-
*
|
|
235
|
+
* Walk every schema field that `raw` provides (a nested `{ section: { key } }`
|
|
236
|
+
* object), coercing each against its type rule. `onResult` fires once per
|
|
237
|
+
* provided known key with the field, its section, and the coercion result —
|
|
238
|
+
* the single iteration shared by the file overlay, the API validator, and the
|
|
239
|
+
* scope reader. A non-object `raw` (or section) is treated as "provides
|
|
240
|
+
* nothing".
|
|
36
241
|
*/
|
|
37
|
-
function
|
|
242
|
+
function walkProvidedFields(raw, onResult) {
|
|
38
243
|
if (typeof raw !== "object" || raw === null)
|
|
39
|
-
return
|
|
40
|
-
const
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
const
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
process.stderr.write(`otacon: ignoring invalid ${section}.${String(key)} in ${source}\n`);
|
|
244
|
+
return;
|
|
245
|
+
const root = raw;
|
|
246
|
+
for (const [section, fields] of SCHEMA_BY_SECTION) {
|
|
247
|
+
const obj = root[section];
|
|
248
|
+
if (typeof obj !== "object" || obj === null)
|
|
249
|
+
continue;
|
|
250
|
+
const sectionObj = obj;
|
|
251
|
+
for (const field of fields) {
|
|
252
|
+
if (!(field.key in sectionObj))
|
|
253
|
+
continue;
|
|
254
|
+
onResult(section, field, coerceFieldValue(field, sectionObj[field.key]));
|
|
51
255
|
}
|
|
52
256
|
}
|
|
53
|
-
return merged;
|
|
54
257
|
}
|
|
55
|
-
/**
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
const merged = {
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
258
|
+
/**
|
|
259
|
+
* Overlay one config file onto `base`, schema-driven: for every known field,
|
|
260
|
+
* a provided value that passes `coerceFieldValue` wins; an invalid provided
|
|
261
|
+
* value is ignored with a notice (same wording/behavior as before). Unknown
|
|
262
|
+
* keys are silently ignored.
|
|
263
|
+
*/
|
|
264
|
+
function overlayConfig(base, raw, source) {
|
|
265
|
+
const merged = {
|
|
266
|
+
budgets: { ...base.budgets },
|
|
267
|
+
activity: { ...base.activity },
|
|
268
|
+
notifications: { ...base.notifications },
|
|
269
|
+
worktree: { ...base.worktree },
|
|
270
|
+
plans: { ...base.plans },
|
|
271
|
+
};
|
|
272
|
+
const mergedSections = merged;
|
|
273
|
+
walkProvidedFields(raw, (section, field, result) => {
|
|
274
|
+
if (result.ok) {
|
|
275
|
+
// section always names a key of OtaconConfig (it came from CONFIG_SCHEMA),
|
|
276
|
+
// so the merged section object is always present.
|
|
277
|
+
mergedSections[section][field.key] = result.value;
|
|
67
278
|
}
|
|
68
|
-
else
|
|
69
|
-
process.stderr.write(`otacon: ignoring invalid
|
|
279
|
+
else {
|
|
280
|
+
process.stderr.write(`otacon: ignoring invalid ${section}.${field.key} in ${source}\n`);
|
|
70
281
|
}
|
|
71
|
-
}
|
|
282
|
+
});
|
|
72
283
|
return merged;
|
|
73
284
|
}
|
|
74
285
|
/**
|
|
75
|
-
* defaults ←
|
|
76
|
-
*
|
|
77
|
-
*
|
|
286
|
+
* defaults ← user (`$OTACON_HOME/config.json`) ← project
|
|
287
|
+
* (`<repo>/.otacon/config.json`, team-shared) ← project.local
|
|
288
|
+
* (`<repo>/.otacon/config.local.json`, personal). Closest wins. Loaded fresh
|
|
289
|
+
* on every use so tuning takes effect immediately. Each file is overlaid field
|
|
290
|
+
* by field against CONFIG_SCHEMA (budgets, activity, notifications, worktree,
|
|
291
|
+
* plans).
|
|
78
292
|
*/
|
|
79
293
|
export function loadConfig(repoRoot) {
|
|
80
|
-
const overlay = (source, into) =>
|
|
81
|
-
const raw = readJsonFile(source);
|
|
82
|
-
return {
|
|
83
|
-
budgets: mergeSection(into.budgets, raw, "budgets", source),
|
|
84
|
-
activity: mergeSection(into.activity, raw, "activity", source),
|
|
85
|
-
notifications: mergeNotifications(into.notifications, raw, source),
|
|
86
|
-
};
|
|
87
|
-
};
|
|
294
|
+
const overlay = (source, into) => overlayConfig(into, readJsonFile(source), source);
|
|
88
295
|
let config = overlay(globalConfigPath(), DEFAULT_CONFIG);
|
|
89
|
-
if (repoRoot)
|
|
296
|
+
if (repoRoot) {
|
|
90
297
|
config = overlay(repoConfigPath(repoRoot), config);
|
|
298
|
+
config = overlay(repoLocalConfigPath(repoRoot), config);
|
|
299
|
+
}
|
|
91
300
|
return config;
|
|
92
301
|
}
|
|
302
|
+
/**
|
|
303
|
+
* Read+parse a scope JSON file and return ONLY schema-known keys whose values
|
|
304
|
+
* pass `coerceFieldValue` (sparse; missing/garbage file → `{}`). This is what
|
|
305
|
+
* GET shows as a scope's current values.
|
|
306
|
+
*/
|
|
307
|
+
export function readScopeValues(path) {
|
|
308
|
+
const out = {};
|
|
309
|
+
walkProvidedFields(readJsonFile(path), (section, field, result) => {
|
|
310
|
+
if (result.ok)
|
|
311
|
+
(out[section] ??= {})[field.key] = result.value;
|
|
312
|
+
});
|
|
313
|
+
return out;
|
|
314
|
+
}
|
|
315
|
+
/**
|
|
316
|
+
* Validate a nested `{ section: { key: value } }` partial against the schema:
|
|
317
|
+
* unknown sections/keys are ignored, each known provided key is coerced; on
|
|
318
|
+
* failure a field error is recorded. Returns the sanitized sparse `values`
|
|
319
|
+
* (only valid, provided keys). This is what POST validates + persists.
|
|
320
|
+
*/
|
|
321
|
+
export function validateScopeInput(input) {
|
|
322
|
+
const values = {};
|
|
323
|
+
const errors = [];
|
|
324
|
+
walkProvidedFields(input, (section, field, result) => {
|
|
325
|
+
if (result.ok) {
|
|
326
|
+
(values[section] ??= {})[field.key] = result.value;
|
|
327
|
+
}
|
|
328
|
+
else {
|
|
329
|
+
errors.push({
|
|
330
|
+
section,
|
|
331
|
+
key: field.key,
|
|
332
|
+
message: `invalid value for ${section}.${field.key}`,
|
|
333
|
+
});
|
|
334
|
+
}
|
|
335
|
+
});
|
|
336
|
+
return { values: values, errors };
|
|
337
|
+
}
|
|
93
338
|
//# sourceMappingURL=config.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"config.js","sourceRoot":"","sources":["../../src/shared/config.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AACvC,OAAO,EAAE,gBAAgB,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;
|
|
1
|
+
{"version":3,"file":"config.js","sourceRoot":"","sources":["../../src/shared/config.ts"],"names":[],"mappings":"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"}
|
package/dist/shared/paths.js
CHANGED
|
@@ -19,8 +19,40 @@ export function daemonLogPath() {
|
|
|
19
19
|
export function globalConfigPath() {
|
|
20
20
|
return join(otaconHome(), "config.json");
|
|
21
21
|
}
|
|
22
|
+
/**
|
|
23
|
+
* The canonical home plan archive root (`<OTACON_HOME>/sessions`, DESIGN.md
|
|
24
|
+
* §12): every approved plan lands here keyed by its session id, regardless of
|
|
25
|
+
* the repo. This store is permanent — `otacon clean` never touches it — so a
|
|
26
|
+
* plan is always recoverable even after its repo working state is archived.
|
|
27
|
+
*/
|
|
28
|
+
export function homeSessionsDir() {
|
|
29
|
+
return join(otaconHome(), "sessions");
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* One session's home archive dir (`<OTACON_HOME>/sessions/<id>`). The session
|
|
33
|
+
* id is a globally-unique hash, so this never collides across repos — mirroring
|
|
34
|
+
* the repo-local `.otacon/<id>/` layout. The approved plan lands here as
|
|
35
|
+
* `<date>-<slug>.md`.
|
|
36
|
+
*/
|
|
37
|
+
export function homeSessionDir(id) {
|
|
38
|
+
return join(homeSessionsDir(), id);
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* The team-shared project config (`<repo>/.otacon/config.json`), mirroring
|
|
42
|
+
* Claude Code's `settings.json`. It overrides the global (user) config for this
|
|
43
|
+
* repo and is in turn overridden by the local override below.
|
|
44
|
+
*/
|
|
22
45
|
export function repoConfigPath(repoRoot) {
|
|
23
|
-
return join(repoRoot, "
|
|
46
|
+
return join(otaconDir(repoRoot), "config.json");
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* The personal, per-developer project override
|
|
50
|
+
* (`<repo>/.otacon/config.local.json`), mirroring Claude Code's
|
|
51
|
+
* `settings.local.json`. The Settings UI writes it for a one-off override that
|
|
52
|
+
* wins over both the user and the team project config.
|
|
53
|
+
*/
|
|
54
|
+
export function repoLocalConfigPath(repoRoot) {
|
|
55
|
+
return join(otaconDir(repoRoot), "config.local.json");
|
|
24
56
|
}
|
|
25
57
|
export function otaconDir(repoRoot) {
|
|
26
58
|
return join(repoRoot, ".otacon");
|
|
@@ -49,10 +81,6 @@ export function transcriptPath(repoRoot, id) {
|
|
|
49
81
|
export function activityPath(repoRoot, id) {
|
|
50
82
|
return join(sessionDir(repoRoot, id), "activity.json");
|
|
51
83
|
}
|
|
52
|
-
/** Where approved plan artifacts land (DESIGN.md §12). */
|
|
53
|
-
export function plansDir(repoRoot) {
|
|
54
|
-
return join(repoRoot, "docs", "plans");
|
|
55
|
-
}
|
|
56
84
|
export function revisionPath(repoRoot, id, n) {
|
|
57
85
|
return join(sessionDir(repoRoot, id), `r${n}.md`);
|
|
58
86
|
}
|
package/dist/shared/paths.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"paths.js","sourceRoot":"","sources":["../../src/shared/paths.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAClC,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAEjC,8EAA8E;AAC9E,6EAA6E;AAC7E,wCAAwC;AAExC,MAAM,UAAU,UAAU;IACxB,OAAO,OAAO,CAAC,GAAG,CAAC,WAAW,IAAI,IAAI,CAAC,OAAO,EAAE,EAAE,SAAS,CAAC,CAAC;AAC/D,CAAC;AAED,MAAM,UAAU,UAAU;IACxB,MAAM,CAAC,GAAG,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,WAAW,CAAC,CAAC;IAC1C,OAAO,MAAM,CAAC,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;AAC9D,CAAC;AAED,MAAM,UAAU,YAAY;IAC1B,OAAO,IAAI,CAAC,UAAU,EAAE,EAAE,eAAe,CAAC,CAAC;AAC7C,CAAC;AAED,MAAM,UAAU,aAAa;IAC3B,OAAO,IAAI,CAAC,UAAU,EAAE,EAAE,YAAY,CAAC,CAAC;AAC1C,CAAC;AAED,MAAM,UAAU,gBAAgB;IAC9B,OAAO,IAAI,CAAC,UAAU,EAAE,EAAE,aAAa,CAAC,CAAC;AAC3C,CAAC;AAED,MAAM,UAAU,cAAc,CAAC,QAAgB;IAC7C,OAAO,IAAI,CAAC,QAAQ,EAAE,
|
|
1
|
+
{"version":3,"file":"paths.js","sourceRoot":"","sources":["../../src/shared/paths.ts"],"names":[],"mappings":"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"}
|
package/dist/shared/types.js
CHANGED
|
@@ -4,6 +4,7 @@ export const SESSION_STATUSES = [
|
|
|
4
4
|
"draft",
|
|
5
5
|
"in_review",
|
|
6
6
|
"revising",
|
|
7
|
+
"finalizing",
|
|
7
8
|
"approved",
|
|
8
9
|
"implementing",
|
|
9
10
|
"implemented",
|
|
@@ -14,8 +15,11 @@ export const SESSION_STATUSES = [
|
|
|
14
15
|
* every mutating verb refuses (app.ts `sessionEnded`), and the CLI's pointer
|
|
15
16
|
* rules stop resolving it implicitly. `implementing` is deliberately NOT here:
|
|
16
17
|
* it re-opens progress/ask/wait/answer while the agent builds the approved plan.
|
|
17
|
-
*
|
|
18
|
-
*
|
|
18
|
+
* `finalizing` is likewise NOT here: a send-to-agent approve (comment & approve)
|
|
19
|
+
* defers the finalize while the agent folds the open comments in, so its next
|
|
20
|
+
* `submit` must still mutate the session. The single source of truth — the app
|
|
21
|
+
* guard and the CLI resolver both derive from this, so they can never disagree
|
|
22
|
+
* about what "over" means.
|
|
19
23
|
*/
|
|
20
24
|
export const TERMINAL_STATUSES = [
|
|
21
25
|
"approved",
|
package/dist/shared/types.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/shared/types.ts"],"names":[],"mappings":"AAAA,sDAAsD;AACtD,0DAA0D;
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/shared/types.ts"],"names":[],"mappings":"AAAA,sDAAsD;AACtD,0DAA0D;AAgB1D,MAAM,CAAC,MAAM,gBAAgB,GAA6B;IACxD,OAAO;IACP,WAAW;IACX,UAAU;IACV,YAAY;IACZ,UAAU;IACV,cAAc;IACd,aAAa;IACb,kBAAkB;CACnB,CAAC;AAEF;;;;;;;;;;GAUG;AACH,MAAM,CAAC,MAAM,iBAAiB,GAA6B;IACzD,UAAU;IACV,aAAa;IACb,kBAAkB;CACnB,CAAC;AA0MF;;;;;;;;GAQG;AACH,MAAM,CAAC,MAAM,WAAW,GAAG,oCAAoC,CAAC"}
|
package/dist/shared/version.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
// Generated from package.json by scripts/gen-version.ts — do NOT hand-edit.
|
|
2
2
|
// version.test.ts guards that this equals package.json's version. Bump the
|
|
3
3
|
// version in package.json, then run `bun run gen:version` to regenerate.
|
|
4
|
-
export const VERSION = "0.1.
|
|
4
|
+
export const VERSION = "0.1.2";
|
|
5
5
|
//# sourceMappingURL=version.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{n as e,t}from"./path-BWPyau1x.js";import{a as n,c as r,d as i,f as a,i as o,l as s,m as c,n as l,o as u,p as d,r as f,u as p}from"./dist-
|
|
1
|
+
import{n as e,t}from"./path-BWPyau1x.js";import{a as n,c as r,d as i,f as a,i as o,l as s,m as c,n as l,o as u,p as d,r as f,u as p}from"./dist-BcowSnUl.js";function m(e){return e.innerRadius}function h(e){return e.outerRadius}function g(e){return e.startAngle}function _(e){return e.endAngle}function v(e){return e&&e.padAngle}function y(e,t,n,r,i,a,o,s){var c=n-e,l=r-t,u=o-i,d=s-a,f=d*c-u*l;if(!(f*f<1e-12))return f=(u*(t-a)-d*(e-i))/f,[e+f*c,t+f*l]}function b(e,t,n,r,i,a,o){var c=e-n,l=t-r,u=(o?a:-a)/d(c*c+l*l),f=u*l,p=-u*c,m=e+f,h=t+p,g=n+f,_=r+p,v=(m+g)/2,y=(h+_)/2,b=g-m,x=_-h,S=b*b+x*x,C=i-a,w=m*_-g*h,T=(x<0?-1:1)*d(s(0,C*C*S-w*w)),E=(w*x-b*T)/S,D=(-w*b-x*T)/S,O=(w*x+b*T)/S,k=(-w*b+x*T)/S,A=E-v,j=D-y,M=O-v,N=k-y;return A*A+j*j>M*M+N*N&&(E=O,D=k),{cx:E,cy:D,x01:-f,y01:-p,x11:E*(i/C-1),y11:D*(i/C-1)}}function x(){var s=m,x=h,S=e(0),C=null,w=g,T=_,E=v,D=null,O=t(k);function k(){var e,t,m=+s.apply(this,arguments),h=+x.apply(this,arguments),g=w.apply(this,arguments)-r,_=T.apply(this,arguments)-r,v=l(_-g),k=_>g;if(D||=e=O(),h<m&&(t=h,h=m,m=t),!(h>1e-12))D.moveTo(0,0);else if(v>c-1e-12)D.moveTo(h*u(g),h*a(g)),D.arc(0,0,h,g,_,!k),m>1e-12&&(D.moveTo(m*u(_),m*a(_)),D.arc(0,0,m,_,g,k));else{var A=g,j=_,M=g,N=_,P=v,F=v,I=E.apply(this,arguments)/2,L=I>1e-12&&(C?+C.apply(this,arguments):d(m*m+h*h)),R=p(l(h-m)/2,+S.apply(this,arguments)),z=R,B=R,V,H;if(L>1e-12){var U=o(L/m*a(I)),W=o(L/h*a(I));(P-=U*2)>1e-12?(U*=k?1:-1,M+=U,N-=U):(P=0,M=N=(g+_)/2),(F-=W*2)>1e-12?(W*=k?1:-1,A+=W,j-=W):(F=0,A=j=(g+_)/2)}var G=h*u(A),K=h*a(A),q=m*u(N),J=m*a(N);if(R>1e-12){var Y=h*u(j),X=h*a(j),Z=m*u(M),Q=m*a(M),$;if(v<i)if($=y(G,K,Z,Q,Y,X,q,J)){var ee=G-$[0],te=K-$[1],ne=Y-$[0],re=X-$[1],ie=1/a(f((ee*ne+te*re)/(d(ee*ee+te*te)*d(ne*ne+re*re)))/2),ae=d($[0]*$[0]+$[1]*$[1]);z=p(R,(m-ae)/(ie-1)),B=p(R,(h-ae)/(ie+1))}else z=B=0}F>1e-12?B>1e-12?(V=b(Z,Q,G,K,h,B,k),H=b(Y,X,q,J,h,B,k),D.moveTo(V.cx+V.x01,V.cy+V.y01),B<R?D.arc(V.cx,V.cy,B,n(V.y01,V.x01),n(H.y01,H.x01),!k):(D.arc(V.cx,V.cy,B,n(V.y01,V.x01),n(V.y11,V.x11),!k),D.arc(0,0,h,n(V.cy+V.y11,V.cx+V.x11),n(H.cy+H.y11,H.cx+H.x11),!k),D.arc(H.cx,H.cy,B,n(H.y11,H.x11),n(H.y01,H.x01),!k))):(D.moveTo(G,K),D.arc(0,0,h,A,j,!k)):D.moveTo(G,K),!(m>1e-12)||!(P>1e-12)?D.lineTo(q,J):z>1e-12?(V=b(q,J,Y,X,m,-z,k),H=b(G,K,Z,Q,m,-z,k),D.lineTo(V.cx+V.x01,V.cy+V.y01),z<R?D.arc(V.cx,V.cy,z,n(V.y01,V.x01),n(H.y01,H.x01),!k):(D.arc(V.cx,V.cy,z,n(V.y01,V.x01),n(V.y11,V.x11),!k),D.arc(0,0,m,n(V.cy+V.y11,V.cx+V.x11),n(H.cy+H.y11,H.cx+H.x11),k),D.arc(H.cx,H.cy,z,n(H.y11,H.x11),n(H.y01,H.x01),!k))):D.arc(0,0,m,N,M,k)}if(D.closePath(),e)return D=null,e+``||null}return k.centroid=function(){var e=(+s.apply(this,arguments)+ +x.apply(this,arguments))/2,t=(+w.apply(this,arguments)+ +T.apply(this,arguments))/2-i/2;return[u(t)*e,a(t)*e]},k.innerRadius=function(t){return arguments.length?(s=typeof t==`function`?t:e(+t),k):s},k.outerRadius=function(t){return arguments.length?(x=typeof t==`function`?t:e(+t),k):x},k.cornerRadius=function(t){return arguments.length?(S=typeof t==`function`?t:e(+t),k):S},k.padRadius=function(t){return arguments.length?(C=t==null?null:typeof t==`function`?t:e(+t),k):C},k.startAngle=function(t){return arguments.length?(w=typeof t==`function`?t:e(+t),k):w},k.endAngle=function(t){return arguments.length?(T=typeof t==`function`?t:e(+t),k):T},k.padAngle=function(t){return arguments.length?(E=typeof t==`function`?t:e(+t),k):E},k.context=function(e){return arguments.length?(D=e??null,k):D},k}export{x as t};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import"./chunk-NNHCCRGN-DlpIbxXb.js";import{x as e}from"./mermaid-parser.core-D8JVCOKU.js";export{e as createArchitectureServices};
|