@design-ai/cli 4.56.0 → 4.57.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (264) hide show
  1. package/.claude-plugin/plugin.json +109 -25
  2. package/CHANGELOG.md +36 -0
  3. package/README.ko.md +9 -26
  4. package/README.md +10 -23
  5. package/cli/bin/design-ai.mjs +1 -0
  6. package/cli/commands/help.mjs +7 -4
  7. package/cli/commands/index.mjs +292 -0
  8. package/cli/commands/learn-help.mjs +149 -0
  9. package/cli/commands/learn-print-profile.mjs +373 -0
  10. package/cli/commands/learn-print-restore.mjs +349 -0
  11. package/cli/commands/learn-print-signals.mjs +453 -0
  12. package/cli/commands/learn.mjs +60 -1281
  13. package/cli/commands/pack.mjs +7 -3
  14. package/cli/commands/prompt.mjs +7 -3
  15. package/cli/commands/search.mjs +94 -1
  16. package/cli/lib/dispatch.mjs +3 -0
  17. package/cli/lib/embedding-index.mjs +199 -0
  18. package/cli/lib/embedding-provider.mjs +121 -0
  19. package/cli/lib/embedding-rerank.mjs +52 -0
  20. package/cli/lib/learn-args.mjs +490 -0
  21. package/cli/lib/learn-backup.mjs +748 -0
  22. package/cli/lib/learn-curation.mjs +612 -0
  23. package/cli/lib/learn-eval.mjs +459 -0
  24. package/cli/lib/learn-profile.mjs +763 -0
  25. package/cli/lib/learn-select.mjs +223 -0
  26. package/cli/lib/learn-shared.mjs +158 -0
  27. package/cli/lib/learn-test-support.mjs +218 -0
  28. package/cli/lib/learn-usage.mjs +360 -0
  29. package/cli/lib/learn.mjs +83 -3694
  30. package/cli/lib/lexical.mjs +137 -0
  31. package/cli/lib/local-config.mjs +110 -0
  32. package/cli/lib/mcp-server.mjs +13 -3
  33. package/cli/lib/pack.mjs +31 -4
  34. package/cli/lib/prompt.mjs +42 -4
  35. package/cli/lib/recall.mjs +193 -0
  36. package/cli/lib/retrieval-index.mjs +0 -0
  37. package/cli/lib/search-ranked.mjs +170 -0
  38. package/cli/lib/search.mjs +11 -1
  39. package/cli/lib/signals-backlog-commands.mjs +673 -0
  40. package/cli/lib/signals-backlog.mjs +361 -0
  41. package/cli/lib/signals-eval.mjs +176 -0
  42. package/cli/lib/signals-readiness.mjs +247 -0
  43. package/cli/lib/signals-registry.mjs +377 -0
  44. package/cli/lib/signals-render.mjs +478 -0
  45. package/cli/lib/signals-shared.mjs +75 -0
  46. package/cli/lib/signals.mjs +16 -2337
  47. package/cli/lib/site-bundle-handoff-expected.mjs +173 -0
  48. package/cli/lib/site-bundle-handoff-runbook-action-summary.mjs +332 -0
  49. package/cli/lib/site-bundle-handoff-runbook-human-lines.mjs +167 -0
  50. package/cli/lib/site-bundle-handoff-runbook-maps.mjs +238 -0
  51. package/cli/lib/site-bundle-handoff-runbook-next-step.mjs +278 -0
  52. package/cli/lib/site-bundle-handoff-runbook.mjs +44 -931
  53. package/cli/lib/site-test-support.mjs +68 -0
  54. package/cli/lib/skill-proposals-apply-commands.mjs +135 -0
  55. package/cli/lib/skill-proposals-apply-contract.mjs +750 -0
  56. package/cli/lib/skill-proposals-apply-plan.mjs +118 -0
  57. package/cli/lib/skill-proposals-generate.mjs +298 -0
  58. package/cli/lib/skill-proposals-render.mjs +532 -0
  59. package/cli/lib/skill-proposals-review.mjs +262 -0
  60. package/cli/lib/skill-proposals.mjs +15 -2046
  61. package/cli/lib/workspace-args.mjs +83 -0
  62. package/cli/lib/workspace-git.mjs +169 -0
  63. package/cli/lib/workspace-learning.mjs +483 -0
  64. package/cli/lib/workspace-repo.mjs +139 -0
  65. package/cli/lib/workspace-report.mjs +283 -0
  66. package/cli/lib/workspace-test-support.mjs +99 -0
  67. package/cli/lib/workspace.mjs +30 -1056
  68. package/docs/AI-LEARNING-PHASE2.md +215 -0
  69. package/docs/DISTRIBUTION.ko.md +2 -2
  70. package/docs/DISTRIBUTION.md +2 -2
  71. package/docs/NEXT-SURFACE-DECISION.md +125 -0
  72. package/docs/PRODUCT-READINESS.md +3 -3
  73. package/docs/RELEASE-GATES.ko.md +35 -0
  74. package/docs/RELEASE-GATES.md +234 -0
  75. package/docs/ROADMAP.md +53 -8
  76. package/docs/external-status.md +6 -8
  77. package/docs/inspection-20260630.md +169 -0
  78. package/docs/integrations/design-ai-mcp-server.md +4 -4
  79. package/docs/reference/ant-design.md +413 -0
  80. package/docs/reference/awesome-design-md.md +439 -0
  81. package/docs/reference/mui.md +783 -0
  82. package/docs/reference/shadcn-ui.md +298 -0
  83. package/examples/component-accordion-actions.md +5 -5
  84. package/examples/component-accordion-details.md +5 -5
  85. package/examples/component-accordion-summary.md +5 -5
  86. package/examples/component-accordion.md +3 -3
  87. package/examples/component-affix.md +1 -1
  88. package/examples/component-alert-dialog.md +1 -1
  89. package/examples/component-alert-title.md +1 -1
  90. package/examples/component-alert.md +3 -3
  91. package/examples/component-anchor.md +1 -1
  92. package/examples/component-app-bar.md +1 -1
  93. package/examples/component-aspect-ratio.md +1 -1
  94. package/examples/component-auto-complete.md +2 -2
  95. package/examples/component-avatar-group.md +5 -5
  96. package/examples/component-avatar.md +3 -3
  97. package/examples/component-back-top.md +1 -1
  98. package/examples/component-backdrop.md +1 -1
  99. package/examples/component-badge.md +3 -3
  100. package/examples/component-border-beam.md +3 -3
  101. package/examples/component-bottom-navigation.md +1 -1
  102. package/examples/component-box.md +1 -1
  103. package/examples/component-breadcrumb.md +3 -3
  104. package/examples/component-button-base.md +3 -3
  105. package/examples/component-button-group.md +2 -2
  106. package/examples/component-button.md +3 -3
  107. package/examples/component-calendar.md +2 -2
  108. package/examples/component-card-actions.md +1 -1
  109. package/examples/component-card-content.md +1 -1
  110. package/examples/component-card-header.md +1 -1
  111. package/examples/component-card-media.md +1 -1
  112. package/examples/component-card.md +3 -3
  113. package/examples/component-carousel.md +2 -2
  114. package/examples/component-cascader.md +1 -1
  115. package/examples/component-chart.md +1 -1
  116. package/examples/component-checkbox.md +3 -3
  117. package/examples/component-click-away-listener.md +1 -1
  118. package/examples/component-code.md +1 -1
  119. package/examples/component-collapsible.md +1 -1
  120. package/examples/component-color-picker.md +1 -1
  121. package/examples/component-combobox.md +1 -1
  122. package/examples/component-command.md +1 -1
  123. package/examples/component-config-provider.md +3 -3
  124. package/examples/component-context-menu.md +1 -1
  125. package/examples/component-css-baseline.md +3 -3
  126. package/examples/component-date-picker.md +2 -2
  127. package/examples/component-descriptions.md +1 -1
  128. package/examples/component-dialog-actions.md +1 -1
  129. package/examples/component-dialog-content-text.md +1 -1
  130. package/examples/component-dialog-content.md +1 -1
  131. package/examples/component-dialog-title.md +1 -1
  132. package/examples/component-dialog.md +2 -2
  133. package/examples/component-divider.md +3 -3
  134. package/examples/component-drawer.md +3 -3
  135. package/examples/component-dropdown.md +3 -3
  136. package/examples/component-empty.md +2 -2
  137. package/examples/component-fade.md +1 -1
  138. package/examples/component-field.md +1 -1
  139. package/examples/component-filled-input.md +1 -1
  140. package/examples/component-flex.md +1 -1
  141. package/examples/component-float-button.md +2 -2
  142. package/examples/component-form-control-label.md +1 -1
  143. package/examples/component-form-control.md +1 -1
  144. package/examples/component-form-controls.md +1 -1
  145. package/examples/component-form-group.md +1 -1
  146. package/examples/component-form-helper-text.md +1 -1
  147. package/examples/component-form-label.md +1 -1
  148. package/examples/component-form.md +2 -2
  149. package/examples/component-grid.md +2 -2
  150. package/examples/component-grow.md +1 -1
  151. package/examples/component-hover-card.md +1 -1
  152. package/examples/component-icon-button.md +1 -1
  153. package/examples/component-icon.md +1 -1
  154. package/examples/component-image-list.md +1 -1
  155. package/examples/component-image.md +1 -1
  156. package/examples/component-input-adornment.md +1 -1
  157. package/examples/component-input-base.md +1 -1
  158. package/examples/component-input-number.md +1 -1
  159. package/examples/component-input-otp.md +2 -2
  160. package/examples/component-input.md +3 -3
  161. package/examples/component-item.md +1 -1
  162. package/examples/component-label.md +1 -1
  163. package/examples/component-layout.md +1 -1
  164. package/examples/component-link.md +1 -1
  165. package/examples/component-list-item-avatar.md +1 -1
  166. package/examples/component-list-item-button.md +1 -1
  167. package/examples/component-list-item-icon.md +1 -1
  168. package/examples/component-list-item-text.md +1 -1
  169. package/examples/component-list-item.md +1 -1
  170. package/examples/component-list-subheader.md +1 -1
  171. package/examples/component-list.md +2 -2
  172. package/examples/component-masonry.md +1 -1
  173. package/examples/component-mentions.md +1 -1
  174. package/examples/component-menu-item.md +1 -1
  175. package/examples/component-menu-list.md +1 -1
  176. package/examples/component-menu.md +1 -1
  177. package/examples/component-menubar.md +1 -1
  178. package/examples/component-message.md +1 -1
  179. package/examples/component-mobile-stepper.md +1 -1
  180. package/examples/component-modal.md +5 -5
  181. package/examples/component-navigation-menu.md +1 -1
  182. package/examples/component-notification.md +1 -1
  183. package/examples/component-outlined-input.md +1 -1
  184. package/examples/component-pagination.md +3 -3
  185. package/examples/component-paper.md +1 -1
  186. package/examples/component-popconfirm.md +1 -1
  187. package/examples/component-popover.md +3 -3
  188. package/examples/component-popper.md +1 -1
  189. package/examples/component-progress.md +2 -2
  190. package/examples/component-qr-code.md +1 -1
  191. package/examples/component-radio.md +3 -3
  192. package/examples/component-rate.md +2 -2
  193. package/examples/component-resizable.md +1 -1
  194. package/examples/component-result.md +1 -1
  195. package/examples/component-scroll-area.md +1 -1
  196. package/examples/component-segmented.md +3 -3
  197. package/examples/component-select.md +3 -3
  198. package/examples/component-separator.md +1 -1
  199. package/examples/component-sheet.md +1 -1
  200. package/examples/component-sidebar.md +1 -1
  201. package/examples/component-skeleton.md +3 -3
  202. package/examples/component-slide.md +1 -1
  203. package/examples/component-slider.md +3 -3
  204. package/examples/component-snackbar-content.md +1 -1
  205. package/examples/component-snackbar.md +1 -1
  206. package/examples/component-sonner.md +1 -1
  207. package/examples/component-space.md +1 -1
  208. package/examples/component-speed-dial-action.md +1 -1
  209. package/examples/component-speed-dial.md +1 -1
  210. package/examples/component-spin.md +2 -2
  211. package/examples/component-spinner.md +1 -1
  212. package/examples/component-splitter.md +2 -2
  213. package/examples/component-stack.md +1 -1
  214. package/examples/component-statistic.md +1 -1
  215. package/examples/component-step-button.md +4 -4
  216. package/examples/component-step-connector.md +4 -4
  217. package/examples/component-step-content.md +1 -1
  218. package/examples/component-step-icon.md +1 -1
  219. package/examples/component-step-label.md +1 -1
  220. package/examples/component-step.md +2 -2
  221. package/examples/component-steps.md +2 -2
  222. package/examples/component-swipeable-drawer.md +1 -1
  223. package/examples/component-switch.md +3 -3
  224. package/examples/component-tab-scroll-button.md +5 -5
  225. package/examples/component-tab.md +1 -1
  226. package/examples/component-table-body.md +1 -1
  227. package/examples/component-table-cell.md +1 -1
  228. package/examples/component-table-container.md +1 -1
  229. package/examples/component-table-footer.md +1 -1
  230. package/examples/component-table-head.md +1 -1
  231. package/examples/component-table-pagination.md +1 -1
  232. package/examples/component-table-row.md +1 -1
  233. package/examples/component-table-sort-label.md +1 -1
  234. package/examples/component-table.md +2 -2
  235. package/examples/component-tabs.md +3 -3
  236. package/examples/component-tag-badge.md +2 -2
  237. package/examples/component-tag.md +1 -1
  238. package/examples/component-textarea-autosize.md +1 -1
  239. package/examples/component-textarea.md +1 -1
  240. package/examples/component-time-picker.md +1 -1
  241. package/examples/component-timeline.md +1 -1
  242. package/examples/component-toast.md +4 -4
  243. package/examples/component-toggle-button.md +1 -1
  244. package/examples/component-toggle.md +1 -1
  245. package/examples/component-toolbar.md +1 -1
  246. package/examples/component-tooltip.md +3 -3
  247. package/examples/component-tour.md +1 -1
  248. package/examples/component-transfer.md +1 -1
  249. package/examples/component-tree-select.md +1 -1
  250. package/examples/component-tree.md +1 -1
  251. package/examples/component-typography.md +2 -2
  252. package/examples/component-upload.md +1 -1
  253. package/examples/component-watermark.md +1 -1
  254. package/examples/component-zoom.md +1 -1
  255. package/knowledge/COVERAGE.md +4 -3
  256. package/knowledge/components/INDEX.md +202 -202
  257. package/knowledge/patterns/brand-references.md +72 -72
  258. package/package.json +1 -1
  259. package/tools/audit/local-ci.py +16 -1
  260. package/tools/audit/package-smoke.py +611 -9
  261. package/tools/audit/registry-smoke.py +534 -0
  262. package/tools/audit/release-metadata.py +47 -1
  263. package/tools/audit/smoke_assertions.py +915 -13
  264. package/tools/migrations/refs-links-to-reference-pages.py +179 -0
@@ -0,0 +1,490 @@
1
+ // CLI argument parsing for `design-ai learn`.
2
+
3
+ import path from "node:path";
4
+
5
+ import { parseBriefSourceFlag } from "./brief.mjs";
6
+ import {
7
+ defaultLearningFile,
8
+ defaultLearningUsageFile,
9
+ } from "./learn-shared.mjs";
10
+ import { parseOutputFlags } from "./output.mjs";
11
+ import { expectedValueMessage, unknownOptionMessage } from "./suggest.mjs";
12
+
13
+ const LEARN_OPTIONS = [
14
+ "-h",
15
+ "--help",
16
+ "--json",
17
+ "--init",
18
+ "--remember",
19
+ "--feedback",
20
+ "--from-file",
21
+ "--stdin",
22
+ "--out",
23
+ "--output",
24
+ "--force",
25
+ "--query",
26
+ "--explain",
27
+ "--recall",
28
+ "--list",
29
+ "--export",
30
+ "--import",
31
+ "--backup",
32
+ "--verify",
33
+ "--diff",
34
+ "--restore",
35
+ "--restore-backups",
36
+ "--prune",
37
+ "--redact",
38
+ "--audit",
39
+ "--stats",
40
+ "--usage",
41
+ "--signals",
42
+ "--agent-backlog",
43
+ "--propose-skills",
44
+ "--apply-plan",
45
+ "--patch",
46
+ "--review-check",
47
+ "--eval",
48
+ "--eval-template",
49
+ "--strict",
50
+ "--curate",
51
+ "--report",
52
+ "--fix",
53
+ "--dry-run",
54
+ "--outcome",
55
+ "--forget",
56
+ "--clear",
57
+ "--category",
58
+ "--limit",
59
+ "--min-evidence",
60
+ "--keep",
61
+ "--file",
62
+ "--usage-file",
63
+ "--review-file",
64
+ "--review-template",
65
+ "--backup-file",
66
+ "--yes",
67
+ ];
68
+ export const LEARNING_CATEGORIES = [
69
+ "preference",
70
+ "brand",
71
+ "workflow",
72
+ "constraint",
73
+ "accessibility",
74
+ "korean",
75
+ "other",
76
+ ];
77
+ export const LEARNING_FEEDBACK_OUTCOMES = [
78
+ "keep",
79
+ "improve",
80
+ "avoid",
81
+ ];
82
+
83
+ function setAction(out, action) {
84
+ if (out.action && out.action !== action) {
85
+ throw new Error(`Choose only one learning action: --${out.action} or --${action}`);
86
+ }
87
+ out.action = action;
88
+ }
89
+
90
+ export function normalizeCategory(rawCategory = "preference") {
91
+ const category = String(rawCategory || "preference").trim().toLowerCase();
92
+ if (!LEARNING_CATEGORIES.includes(category)) {
93
+ throw new Error(expectedValueMessage("category", category, LEARNING_CATEGORIES));
94
+ }
95
+ return category;
96
+ }
97
+
98
+ export function normalizeFeedbackOutcome(rawOutcome = "improve") {
99
+ const outcome = String(rawOutcome || "improve").trim().toLowerCase();
100
+ if (!LEARNING_FEEDBACK_OUTCOMES.includes(outcome)) {
101
+ throw new Error(expectedValueMessage("outcome", outcome, LEARNING_FEEDBACK_OUTCOMES));
102
+ }
103
+ return outcome;
104
+ }
105
+
106
+ export function parseLearningLimit(rawLimit) {
107
+ const limit = Number(rawLimit);
108
+ if (!Number.isInteger(limit) || limit < 1 || limit > 100) {
109
+ throw new Error("--limit expects an integer from 1 to 100");
110
+ }
111
+ return limit;
112
+ }
113
+
114
+ export function parseLearningKeep(rawKeep) {
115
+ const keep = Number(rawKeep);
116
+ if (!Number.isInteger(keep) || keep < 1 || keep > 100) {
117
+ throw new Error("--keep expects an integer from 1 to 100");
118
+ }
119
+ return keep;
120
+ }
121
+
122
+ export function parseLearningMinEvidence(rawMinEvidence) {
123
+ const minEvidence = Number(rawMinEvidence);
124
+ if (!Number.isInteger(minEvidence) || minEvidence < 1 || minEvidence > 100) {
125
+ throw new Error("--min-evidence expects an integer from 1 to 100");
126
+ }
127
+ return minEvidence;
128
+ }
129
+
130
+ export const LEARN_SUBCOMMANDS = Object.freeze([
131
+ "agent-backlog",
132
+ "audit",
133
+ "backup",
134
+ "clear",
135
+ "curate",
136
+ "diff",
137
+ "eval",
138
+ "eval-template",
139
+ "export",
140
+ "feedback",
141
+ "forget",
142
+ "import",
143
+ "init",
144
+ "list",
145
+ "propose-skills",
146
+ "recall",
147
+ "redact",
148
+ "remember",
149
+ "restore",
150
+ "restore-backups",
151
+ "signals",
152
+ "stats",
153
+ "usage",
154
+ "verify",
155
+ ]);
156
+
157
+ export function parseLearnArgs(rawArgs) {
158
+ const args = rawArgs.length > 0 && LEARN_SUBCOMMANDS.includes(rawArgs[0])
159
+ ? [`--${rawArgs[0]}`, ...rawArgs.slice(1)]
160
+ : rawArgs;
161
+ const out = {
162
+ action: "",
163
+ noteParts: [],
164
+ fromFile: "",
165
+ stdin: false,
166
+ category: "preference",
167
+ categorySpecified: false,
168
+ feedbackOutcome: "improve",
169
+ outcomeSpecified: false,
170
+ filePath: "",
171
+ usageFilePath: "",
172
+ reviewFilePath: "",
173
+ backupFilePath: "",
174
+ outPath: "",
175
+ force: false,
176
+ query: "",
177
+ explain: false,
178
+ forgetTarget: "",
179
+ limit: 0,
180
+ minEvidenceCount: 0,
181
+ keep: 0,
182
+ fix: false,
183
+ prune: false,
184
+ dryRun: false,
185
+ strict: false,
186
+ report: false,
187
+ applyPlan: false,
188
+ patch: false,
189
+ reviewCheck: false,
190
+ reviewTemplate: false,
191
+ yes: false,
192
+ json: false,
193
+ help: false,
194
+ };
195
+
196
+ for (let i = 0; i < args.length; i += 1) {
197
+ const arg = args[i];
198
+ out.index = i;
199
+
200
+ if (arg === "-h" || arg === "--help") {
201
+ out.help = true;
202
+ } else if (arg === "--json") {
203
+ out.json = true;
204
+ } else if (arg === "--init") {
205
+ setAction(out, "init");
206
+ } else if (arg === "--remember") {
207
+ setAction(out, "remember");
208
+ } else if (arg === "--feedback") {
209
+ setAction(out, "feedback");
210
+ } else if (arg === "--recall") {
211
+ setAction(out, "recall");
212
+ } else if (arg === "--list") {
213
+ setAction(out, "list");
214
+ } else if (arg === "--export") {
215
+ setAction(out, "export");
216
+ } else if (arg === "--import") {
217
+ setAction(out, "import");
218
+ } else if (arg === "--backup") {
219
+ setAction(out, "backup");
220
+ } else if (arg === "--verify") {
221
+ setAction(out, "verify");
222
+ } else if (arg === "--diff") {
223
+ setAction(out, "diff");
224
+ } else if (arg === "--restore") {
225
+ setAction(out, "restore");
226
+ } else if (arg === "--restore-backups") {
227
+ setAction(out, "restore-backups");
228
+ } else if (arg === "--prune") {
229
+ out.prune = true;
230
+ } else if (arg === "--redact") {
231
+ setAction(out, "redact");
232
+ } else if (arg === "--audit") {
233
+ setAction(out, "audit");
234
+ } else if (arg === "--stats") {
235
+ setAction(out, "stats");
236
+ } else if (arg === "--usage") {
237
+ setAction(out, "usage");
238
+ } else if (arg === "--signals") {
239
+ setAction(out, "signals");
240
+ } else if (arg === "--agent-backlog") {
241
+ setAction(out, "agent-backlog");
242
+ } else if (arg === "--propose-skills") {
243
+ setAction(out, "propose-skills");
244
+ } else if (arg === "--eval") {
245
+ setAction(out, "eval");
246
+ } else if (arg === "--eval-template") {
247
+ setAction(out, "eval-template");
248
+ } else if (arg === "--curate") {
249
+ setAction(out, "curate");
250
+ } else if (arg === "--report") {
251
+ out.report = true;
252
+ } else if (arg === "--apply-plan") {
253
+ out.applyPlan = true;
254
+ } else if (arg === "--patch") {
255
+ out.patch = true;
256
+ } else if (arg === "--review-check") {
257
+ out.reviewCheck = true;
258
+ } else if (arg === "--review-template") {
259
+ out.reviewTemplate = true;
260
+ } else if (arg === "--fix") {
261
+ out.fix = true;
262
+ } else if (arg === "--dry-run") {
263
+ out.dryRun = true;
264
+ } else if (arg === "--strict") {
265
+ out.strict = true;
266
+ } else if (arg === "--query") {
267
+ const query = args[i + 1];
268
+ if (!query || query.startsWith("--")) throw new Error("--query expects search text");
269
+ out.query = String(query).trim();
270
+ i += 1;
271
+ } else if (arg === "--explain") {
272
+ out.explain = true;
273
+ } else if (arg === "--outcome") {
274
+ const outcome = args[i + 1];
275
+ if (!outcome || outcome.startsWith("--")) throw new Error("--outcome expects keep, improve, or avoid");
276
+ out.feedbackOutcome = normalizeFeedbackOutcome(outcome);
277
+ out.outcomeSpecified = true;
278
+ i += 1;
279
+ } else if (arg === "--forget") {
280
+ setAction(out, "forget");
281
+ const target = args[i + 1];
282
+ if (!target || target.startsWith("--")) throw new Error("--forget expects an entry id or list number");
283
+ out.forgetTarget = target;
284
+ i += 1;
285
+ } else if (arg === "--clear") {
286
+ setAction(out, "clear");
287
+ } else if (arg === "--yes") {
288
+ out.yes = true;
289
+ } else if (arg === "--category") {
290
+ const category = args[i + 1];
291
+ if (!category || category.startsWith("--")) throw new Error("--category expects a category");
292
+ out.category = normalizeCategory(category);
293
+ out.categorySpecified = true;
294
+ i += 1;
295
+ } else if (arg === "--limit") {
296
+ const limit = args[i + 1];
297
+ if (!limit || limit.startsWith("--")) throw new Error("--limit expects an integer from 1 to 100");
298
+ out.limit = parseLearningLimit(limit);
299
+ i += 1;
300
+ } else if (arg === "--min-evidence") {
301
+ const minEvidence = args[i + 1];
302
+ if (!minEvidence || minEvidence.startsWith("--")) throw new Error("--min-evidence expects an integer from 1 to 100");
303
+ out.minEvidenceCount = parseLearningMinEvidence(minEvidence);
304
+ i += 1;
305
+ } else if (arg === "--keep") {
306
+ const keep = args[i + 1];
307
+ if (!keep || keep.startsWith("--")) throw new Error("--keep expects an integer from 1 to 100");
308
+ out.keep = parseLearningKeep(keep);
309
+ i += 1;
310
+ } else if (arg === "--file") {
311
+ const filePath = args[i + 1];
312
+ if (!filePath || filePath.startsWith("--")) throw new Error("--file expects a path");
313
+ out.filePath = filePath;
314
+ i += 1;
315
+ } else if (arg === "--usage-file") {
316
+ const usageFilePath = args[i + 1];
317
+ if (!usageFilePath || usageFilePath.startsWith("--")) throw new Error("--usage-file expects a path");
318
+ out.usageFilePath = usageFilePath;
319
+ i += 1;
320
+ } else if (arg === "--review-file") {
321
+ const reviewFilePath = args[i + 1];
322
+ if (!reviewFilePath || reviewFilePath.startsWith("--")) throw new Error("--review-file expects a path");
323
+ out.reviewFilePath = reviewFilePath;
324
+ i += 1;
325
+ } else if (arg === "--backup-file") {
326
+ const backupFilePath = args[i + 1];
327
+ if (!backupFilePath || backupFilePath.startsWith("--")) throw new Error("--backup-file expects a path");
328
+ out.backupFilePath = backupFilePath;
329
+ i += 1;
330
+ } else if (parseBriefSourceFlag(args, out)) {
331
+ if (!out.action) {
332
+ setAction(out, "remember");
333
+ } else if (!["remember", "feedback", "import", "verify", "diff", "restore", "redact", "eval", "signals", "agent-backlog", "propose-skills"].includes(out.action)) {
334
+ setAction(out, "remember");
335
+ }
336
+ i = out.index;
337
+ } else if (parseOutputFlags(args, out)) {
338
+ i = out.index;
339
+ } else if (arg.startsWith("--")) {
340
+ throw new Error(unknownOptionMessage("learn", arg, LEARN_OPTIONS));
341
+ } else {
342
+ out.noteParts.push(arg);
343
+ }
344
+ }
345
+
346
+ if (!out.action) {
347
+ out.action = out.noteParts.length > 0 ? "remember" : "list";
348
+ }
349
+
350
+ if (!["remember", "feedback", "recall"].includes(out.action) && out.noteParts.length > 0) {
351
+ throw new Error(`Unexpected learn argument for --${out.action}: ${out.noteParts[0]}`);
352
+ }
353
+ if (out.outcomeSpecified && out.action !== "feedback") {
354
+ throw new Error("--outcome can only be used with --feedback");
355
+ }
356
+ if (out.fix && out.action !== "audit") {
357
+ throw new Error("--fix can only be used with --audit");
358
+ }
359
+ if (out.prune && out.action !== "restore-backups") {
360
+ throw new Error("--prune can only be used with --restore-backups");
361
+ }
362
+ if (out.keep && !(out.action === "restore-backups" && out.prune)) {
363
+ throw new Error("--keep can only be used with --restore-backups --prune");
364
+ }
365
+ if (out.dryRun && !out.fix && !["import", "init", "curate", "restore"].includes(out.action) && !(out.action === "restore-backups" && out.prune)) {
366
+ throw new Error("--dry-run requires --fix, --init, --import, --restore, --curate, or --restore-backups --prune");
367
+ }
368
+ if (out.fix && out.dryRun && out.yes) {
369
+ throw new Error("Choose either --dry-run or --yes for --audit --fix");
370
+ }
371
+ if (out.action === "import" && out.dryRun && out.yes) {
372
+ throw new Error("Choose either --dry-run or --yes for --import");
373
+ }
374
+ if (out.action === "restore" && out.dryRun && out.yes) {
375
+ throw new Error("Choose either --dry-run or --yes for --restore");
376
+ }
377
+ if (out.action === "init" && out.dryRun && out.yes) {
378
+ throw new Error("Choose either --dry-run or --yes for --init");
379
+ }
380
+ if (out.action === "curate" && out.dryRun && out.yes) {
381
+ throw new Error("Choose either --dry-run or --yes for --curate");
382
+ }
383
+ if (out.action === "restore-backups" && out.prune && out.dryRun && out.yes) {
384
+ throw new Error("Choose either --dry-run or --yes for --restore-backups --prune");
385
+ }
386
+ if (out.action === "restore-backups" && out.yes && !out.prune) {
387
+ throw new Error("--yes can only be used with --restore-backups --prune");
388
+ }
389
+ if (out.action === "feedback" && !out.categorySpecified) {
390
+ out.category = "workflow";
391
+ }
392
+ if (out.query && !["list", "export", "eval-template"].includes(out.action)) {
393
+ throw new Error("--query can only be used with --list, --export, or --eval-template");
394
+ }
395
+ if (out.explain && out.action !== "list") {
396
+ throw new Error("--explain can only be used with --list");
397
+ }
398
+ if (out.usageFilePath && !["usage", "curate", "signals", "agent-backlog", "propose-skills"].includes(out.action)) {
399
+ throw new Error("--usage-file can only be used with --usage, --curate, --signals, --agent-backlog, or --propose-skills");
400
+ }
401
+ if (out.reviewFilePath && out.action !== "propose-skills") {
402
+ throw new Error("--review-file can only be used with --propose-skills");
403
+ }
404
+ if (out.reviewTemplate && out.action !== "propose-skills") {
405
+ throw new Error("--review-template can only be used with --propose-skills");
406
+ }
407
+ if (out.reviewCheck && out.action !== "propose-skills") {
408
+ throw new Error("--review-check can only be used with --propose-skills");
409
+ }
410
+ if (out.applyPlan && out.action !== "propose-skills") {
411
+ throw new Error("--apply-plan can only be used with --propose-skills");
412
+ }
413
+ if (out.minEvidenceCount && out.action !== "propose-skills") {
414
+ throw new Error("--min-evidence can only be used with --propose-skills");
415
+ }
416
+ if (out.backupFilePath && out.action !== "restore") {
417
+ throw new Error("--backup-file can only be used with --restore");
418
+ }
419
+ if (out.report && !["curate", "signals", "agent-backlog", "propose-skills"].includes(out.action)) {
420
+ throw new Error("--report can only be used with --curate, --signals, --agent-backlog, or --propose-skills");
421
+ }
422
+ if (out.patch && out.action !== "propose-skills") {
423
+ throw new Error("--patch can only be used with --propose-skills");
424
+ }
425
+ if (out.reviewCheck && (out.patch || out.reviewTemplate)) {
426
+ throw new Error("--review-check cannot be combined with --patch or --review-template");
427
+ }
428
+ if (out.reviewCheck && !out.reviewFilePath) {
429
+ throw new Error("--review-check requires --review-file");
430
+ }
431
+ if (out.applyPlan && (out.patch || out.reviewTemplate || out.reviewCheck)) {
432
+ throw new Error("--apply-plan cannot be combined with --patch, --review-template, or --review-check");
433
+ }
434
+ if (out.applyPlan && !out.reviewFilePath) {
435
+ throw new Error("--apply-plan requires --review-file");
436
+ }
437
+ if ([out.json, out.report, out.patch, out.reviewTemplate].filter(Boolean).length > 1) {
438
+ throw new Error("Choose only one output mode: --json, --report, --patch, or --review-template");
439
+ }
440
+ if (out.strict && !["eval", "signals", "agent-backlog", "propose-skills"].includes(out.action)) {
441
+ throw new Error("--strict can only be used with --eval, --signals, --agent-backlog, or --propose-skills");
442
+ }
443
+ if (out.action === "eval" && !out.fromFile && !out.stdin) {
444
+ throw new Error("--eval requires --from-file or --stdin");
445
+ }
446
+ if (out.action === "signals" && out.stdin) {
447
+ throw new Error("--signals does not support --stdin; use --from-file for a signal file or directory");
448
+ }
449
+ if (out.action === "agent-backlog" && out.stdin) {
450
+ throw new Error("--agent-backlog does not support --stdin; use --from-file for a signal file or directory");
451
+ }
452
+ if (out.action === "agent-backlog" && out.yes) {
453
+ throw new Error("--agent-backlog is read-only and does not accept --yes");
454
+ }
455
+ if (out.action === "propose-skills" && out.stdin) {
456
+ throw new Error("--propose-skills does not support --stdin; use --from-file for a signal file or directory");
457
+ }
458
+ if (out.action === "propose-skills" && out.yes) {
459
+ throw new Error("--propose-skills is preview-only and does not accept --yes");
460
+ }
461
+ if (out.action === "diff" && !out.fromFile && !out.stdin) {
462
+ throw new Error("--diff requires --from-file or --stdin");
463
+ }
464
+ if (out.action === "restore" && !out.fromFile && !out.stdin) {
465
+ throw new Error("--restore requires --from-file or --stdin");
466
+ }
467
+ const allowsMarkdownOut = ["export", "eval-template"].includes(out.action)
468
+ || (out.action === "curate" && out.report)
469
+ || (out.action === "signals" && out.report)
470
+ || (out.action === "agent-backlog" && out.report)
471
+ || (out.action === "propose-skills" && (out.report || out.patch || out.reviewTemplate));
472
+ if (!out.help && out.outPath && !allowsMarkdownOut && !out.json) {
473
+ throw new Error("--out requires --json for learn actions other than --export, --eval-template, --curate --report, --signals --report, --agent-backlog --report, --propose-skills --report, --propose-skills --patch, or --propose-skills --review-template");
474
+ }
475
+
476
+ const resolvedFilePath = path.resolve(out.filePath || defaultLearningFile());
477
+ return {
478
+ ...out,
479
+ index: undefined,
480
+ briefParts: out.noteParts,
481
+ filePath: resolvedFilePath,
482
+ usageFilePath: path.resolve(out.usageFilePath || defaultLearningUsageFile(resolvedFilePath)),
483
+ reviewFilePath: out.reviewFilePath ? path.resolve(out.reviewFilePath) : "",
484
+ backupFilePath: out.backupFilePath ? path.resolve(out.backupFilePath) : "",
485
+ category: normalizeCategory(out.category),
486
+ feedbackOutcome: normalizeFeedbackOutcome(out.feedbackOutcome),
487
+ query: out.query,
488
+ brief: out.noteParts.join(" ").trim(),
489
+ };
490
+ }