mdkg 0.0.2 → 0.0.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (50) hide show
  1. package/README.md +171 -151
  2. package/dist/cli.js +920 -422
  3. package/dist/commands/checkpoint.js +17 -6
  4. package/dist/commands/doctor.js +156 -0
  5. package/dist/commands/event.js +46 -0
  6. package/dist/commands/event_support.js +146 -0
  7. package/dist/commands/format.js +6 -7
  8. package/dist/commands/index.js +10 -4
  9. package/dist/commands/init.js +202 -11
  10. package/dist/commands/list.js +18 -1
  11. package/dist/commands/new.js +30 -5
  12. package/dist/commands/pack.js +332 -10
  13. package/dist/commands/query_output.js +84 -0
  14. package/dist/commands/search.js +22 -5
  15. package/dist/commands/show.js +26 -11
  16. package/dist/commands/skill.js +359 -0
  17. package/dist/commands/skill_support.js +121 -0
  18. package/dist/commands/task.js +270 -0
  19. package/dist/commands/validate.js +104 -7
  20. package/dist/graph/edges.js +2 -2
  21. package/dist/graph/frontmatter.js +1 -0
  22. package/dist/graph/indexer.js +21 -0
  23. package/dist/graph/node.js +20 -4
  24. package/dist/graph/skills_index_cache.js +94 -0
  25. package/dist/graph/skills_indexer.js +160 -0
  26. package/dist/init/README.md +43 -0
  27. package/dist/init/core/rule-1-mdkg-conventions.md +9 -2
  28. package/dist/init/core/rule-3-cli-contract.md +73 -14
  29. package/dist/init/core/rule-4-repo-safety-and-ignores.md +9 -3
  30. package/dist/init/core/rule-6-templates-and-schemas.md +6 -2
  31. package/dist/init/skills/SKILL.md.example +41 -0
  32. package/dist/init/templates/default/bug.md +1 -0
  33. package/dist/init/templates/default/chk.md +1 -0
  34. package/dist/init/templates/default/epic.md +1 -0
  35. package/dist/init/templates/default/feat.md +1 -0
  36. package/dist/init/templates/default/task.md +1 -0
  37. package/dist/init/templates/default/test.md +1 -0
  38. package/dist/pack/budget.js +186 -0
  39. package/dist/pack/export_md.js +17 -1
  40. package/dist/pack/export_xml.js +15 -0
  41. package/dist/pack/metrics.js +66 -0
  42. package/dist/pack/pack.js +35 -0
  43. package/dist/pack/profile.js +222 -0
  44. package/dist/pack/stats.js +37 -0
  45. package/dist/templates/headings.js +34 -0
  46. package/dist/util/argparse.js +47 -1
  47. package/dist/util/filter.js +18 -0
  48. package/dist/util/id.js +23 -0
  49. package/dist/util/output.js +2 -2
  50. package/package.json +6 -2
package/dist/cli.js CHANGED
@@ -4,6 +4,8 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
4
4
  return (mod && mod.__esModule) ? mod : { "default": mod };
5
5
  };
6
6
  Object.defineProperty(exports, "__esModule", { value: true });
7
+ exports.runCli = runCli;
8
+ exports.main = main;
7
9
  const fs_1 = __importDefault(require("fs"));
8
10
  const path_1 = __importDefault(require("path"));
9
11
  const argparse_1 = require("./util/argparse");
@@ -15,205 +17,426 @@ const pack_1 = require("./commands/pack");
15
17
  const next_1 = require("./commands/next");
16
18
  const validate_1 = require("./commands/validate");
17
19
  const format_1 = require("./commands/format");
20
+ const doctor_1 = require("./commands/doctor");
18
21
  const checkpoint_1 = require("./commands/checkpoint");
19
22
  const init_1 = require("./commands/init");
20
23
  const new_1 = require("./commands/new");
21
24
  const guide_1 = require("./commands/guide");
25
+ const event_1 = require("./commands/event");
26
+ const skill_1 = require("./commands/skill");
27
+ const task_1 = require("./commands/task");
22
28
  const workspace_1 = require("./commands/workspace");
29
+ const profile_1 = require("./pack/profile");
23
30
  const errors_1 = require("./util/errors");
24
- function printGlobalOptions() {
25
- console.log("\nGlobal options:");
26
- console.log(" --root, -r <path> Run against a specific repo root");
27
- console.log(" --help, -h Show help");
28
- console.log(" --no-cache Bypass reading the index cache");
29
- console.log(" --no-reindex Do not auto rebuild when cache is stale");
30
- }
31
- function printUsage() {
32
- console.log("mdkg - Markdown Knowledge Graph");
33
- console.log("\nUsage:");
34
- console.log(" mdkg <command> [options]");
35
- console.log("\nCommands:");
36
- console.log(" init Initialize .mdkg scaffolding");
37
- console.log(" guide Show the mdkg guide");
38
- console.log(" new Create a node from templates");
39
- console.log(" workspace Manage workspaces (ls/add/rm)");
40
- console.log(" index Build the global index");
41
- console.log(" show Show a node by id or qid");
42
- console.log(" list List nodes with filters");
43
- console.log(" search Search nodes by query");
44
- console.log(" pack Generate a context pack");
45
- console.log(" next Suggest the next work item");
46
- console.log(" checkpoint Create a checkpoint node");
47
- console.log(" validate Validate frontmatter + graph");
48
- console.log(" format Normalize frontmatter");
49
- console.log("\nQuickstart:");
50
- console.log(" mdkg init --llm");
51
- console.log(" mdkg index");
52
- console.log(' mdkg new task "..." --status todo --priority 1');
53
- console.log(" mdkg list --status todo");
54
- console.log(" mdkg pack <id> --verbose");
55
- console.log(" mdkg validate");
56
- console.log("\nRun `mdkg help <command>` or `mdkg <command> --help` for details.");
57
- printGlobalOptions();
58
- }
59
- function printInitHelp() {
60
- console.log("Usage:");
61
- console.log(" mdkg init [options]");
62
- console.log("\nOptions:");
63
- console.log(" --force Overwrite existing mdkg files");
64
- console.log(" --agents Create AGENTS.md");
65
- console.log(" --claude Create CLAUDE.md");
66
- console.log(" --llm Create AGENTS.md and CLAUDE.md");
67
- console.log(" --update-gitignore Append mdkg ignore entries");
68
- console.log(" --update-npmignore Append mdkg ignore entries");
69
- console.log(" --update-dockerignore Append mdkg ignore entries");
70
- printGlobalOptions();
71
- }
72
- function printNewHelp() {
73
- console.log("Usage:");
74
- console.log(' mdkg new <type> "<title>" [options]');
75
- console.log("\nTypes:");
76
- console.log(" rule prd edd dec prop epic feat task bug checkpoint test");
77
- console.log("\nOptions:");
78
- console.log(" --ws <alias> Workspace alias (default root)");
79
- console.log(" --status <status> Work item or decision status");
80
- console.log(" --priority <0..9> Work item priority");
81
- console.log(" --epic <id> Epic id");
82
- console.log(" --parent <id> Parent id");
83
- console.log(" --prev <id> Previous id");
84
- console.log(" --next <id> Next id");
85
- console.log(" --relates <id,id,...> Related ids");
86
- console.log(" --blocked-by <id,id,...> Blockers");
87
- console.log(" --blocks <id,id,...> Blocked items");
88
- console.log(" --links <ref,ref,...> Link refs");
89
- console.log(" --artifacts <ref,ref,...> Artifact refs");
90
- console.log(" --refs <id,id,...> Non-edge refs");
91
- console.log(" --aliases <text,text,...> Search aliases");
92
- console.log(" --cases <id,id,...> Test case ids");
93
- console.log(" --tags <tag,tag,...> Tags");
94
- console.log(" --owners <owner,owner,...> Owners");
95
- console.log(" --supersedes <dec-id> Decision supersedes");
96
- console.log(" --template <set> Template set");
97
- printGlobalOptions();
98
- }
99
- function printGuideHelp() {
100
- console.log("Usage:");
101
- console.log(" mdkg guide");
102
- printGlobalOptions();
103
- }
104
- function printWorkspaceHelp() {
105
- console.log("Usage:");
106
- console.log(" mdkg workspace ls");
107
- console.log(" mdkg workspace add <alias> <path> [--mdkg-dir <dir>]");
108
- console.log(" mdkg workspace rm <alias>");
109
- printGlobalOptions();
110
- }
111
- function printIndexHelp() {
112
- console.log("Usage:");
113
- console.log(" mdkg index [--tolerant]");
114
- printGlobalOptions();
115
- }
116
- function printShowHelp() {
117
- console.log("Usage:");
118
- console.log(" mdkg show <id-or-qid> [--ws <alias>] [--body]");
119
- printGlobalOptions();
120
- }
121
- function printListHelp() {
122
- console.log("Usage:");
123
- console.log(" mdkg list [--type <type>] [--status <status>] [--ws <alias>] [--epic <id>]");
124
- console.log(" [--priority <n>] [--blocked]");
125
- printGlobalOptions();
126
- }
127
- function printSearchHelp() {
128
- console.log("Usage:");
129
- console.log(' mdkg search "<query>" [--type <type>] [--status <status>] [--ws <alias>]');
130
- printGlobalOptions();
131
- }
132
- function printPackHelp() {
133
- console.log("Usage:");
134
- console.log(" mdkg pack <id-or-qid> [-d <n>] [-e <keys>] [-v]");
135
- console.log(" [-f md|json|toon|xml] [-o <path>] [-w <alias>]");
136
- printGlobalOptions();
137
- }
138
- function printNextHelp() {
139
- console.log("Usage:");
140
- console.log(" mdkg next [<id-or-qid>] [--ws <alias>]");
141
- printGlobalOptions();
142
- }
143
- function printCheckpointHelp() {
144
- console.log("Usage:");
145
- console.log(" mdkg checkpoint new <title> [--ws <alias>]");
146
- console.log(" [--relates <id,id,...>] [--scope <id,id,...>]");
147
- printGlobalOptions();
148
- }
149
- function printValidateHelp() {
150
- console.log("Usage:");
151
- console.log(" mdkg validate [--out <path>] [--quiet]");
152
- printGlobalOptions();
153
- }
154
- function printFormatHelp() {
155
- console.log("Usage:");
156
- console.log(" mdkg format");
157
- printGlobalOptions();
158
- }
159
- function printCommandHelp(command) {
31
+ function resolveRuntime(runtime = {}) {
32
+ return {
33
+ log: runtime.log ?? console.log,
34
+ error: runtime.error ?? console.error,
35
+ cwd: runtime.cwd ?? (() => process.cwd()),
36
+ };
37
+ }
38
+ function printGlobalOptions(log) {
39
+ log("\nGlobal options:");
40
+ log(" --root, -r <path> Run against a specific repo root");
41
+ log(" --help, -h Show help");
42
+ log(" --version, -V Show version");
43
+ }
44
+ function printUsage(log) {
45
+ log("mdkg - Markdown Knowledge Graph");
46
+ log("\nUsage:");
47
+ log(" mdkg <command> [options]");
48
+ log("\nPrimary commands:");
49
+ log(" init Initialize .mdkg scaffolding");
50
+ log(" new Create a node from templates");
51
+ log(" show Show a node by id or qid");
52
+ log(" list List nodes with filters");
53
+ log(" search Search nodes by query");
54
+ log(" pack Generate a context pack");
55
+ log(" skill Create, list, show, search, and validate skills");
56
+ log(" task Start, update, and complete task-like nodes");
57
+ log(" next Suggest the next work item");
58
+ log(" validate Validate frontmatter + graph");
59
+ log("\nAdvanced / maintenance commands:");
60
+ log(" event Enable or append episodic event logs");
61
+ log(" checkpoint Create a checkpoint node");
62
+ log(" index Build the global index");
63
+ log(" guide Show the mdkg guide");
64
+ log(" format Normalize frontmatter");
65
+ log(" doctor Run install and workspace diagnostics");
66
+ log(" workspace Manage workspaces (ls/add/rm)");
67
+ log("\nQuickstart:");
68
+ log(" mdkg init --llm");
69
+ log(' mdkg new task "..." --status todo --priority 1');
70
+ log(' mdkg search "..."');
71
+ log(" mdkg show <id>");
72
+ log(" mdkg next");
73
+ log(" mdkg pack <id>");
74
+ log(" mdkg pack <id> --profile concise --dry-run --stats");
75
+ log(" mdkg task start <id>");
76
+ log(' mdkg skill new release-readiness "release readiness audit" --description "use when preparing a release"');
77
+ log(" mdkg skill list --tags stage:plan --json");
78
+ log(" mdkg validate");
79
+ log("\nOptional agent-ready bootstrap:");
80
+ log(" mdkg init --omni");
81
+ log("\nRun `mdkg help <command>` or `mdkg <command> --help` for details.");
82
+ printGlobalOptions(log);
83
+ }
84
+ function printInitHelp(log) {
85
+ log("Usage:");
86
+ log(" mdkg init [options]");
87
+ log("\nOptions:");
88
+ log(" --force Overwrite existing mdkg files");
89
+ log(" --llm Create AGENTS.md and CLAUDE.md");
90
+ log(" --omni Add SOUL/HUMAN/skills/events scaffolding");
91
+ log(" --no-update-ignores Skip default .gitignore/.npmignore updates");
92
+ log(" --update-gitignore Append mdkg ignore entries");
93
+ log(" --update-npmignore Append mdkg ignore entries");
94
+ log(" --update-dockerignore Append mdkg ignore entries");
95
+ log("\nCompatibility flags still supported but not shown in the primary onboarding story.");
96
+ printGlobalOptions(log);
97
+ }
98
+ function printNewHelp(log) {
99
+ log("Usage:");
100
+ log(' mdkg new <type> "<title>" [options]');
101
+ log("\nTypes:");
102
+ log(" rule prd edd dec prop epic feat task bug checkpoint test");
103
+ log("\nOptions:");
104
+ log(" --ws <alias> Workspace alias (default root)");
105
+ log(" --status <status> Work item or decision status");
106
+ log(" --priority <0..9> Work item priority");
107
+ log(" --epic <id> Epic id");
108
+ log(" --tags <tag,tag,...> Tags");
109
+ log(" --skills <slug,slug,...> Skill slugs for work items");
110
+ log(" --template <set> Template set");
111
+ log(" --run-id <id> Optional event run id when event logging is enabled");
112
+ log("\nAdvanced metadata flags:");
113
+ log(" --parent --prev --next --relates --blocked-by --blocks");
114
+ log(" --links --artifacts --refs --aliases --owners --cases --supersedes");
115
+ log(" --owners <owner,owner,...> Owners");
116
+ printGlobalOptions(log);
117
+ }
118
+ function printGuideHelp(log) {
119
+ log("Usage:");
120
+ log(" mdkg guide");
121
+ printGlobalOptions(log);
122
+ }
123
+ function printWorkspaceHelp(log) {
124
+ log("Usage:");
125
+ log(" mdkg workspace ls");
126
+ log(" mdkg workspace add <alias> <path> [--mdkg-dir <dir>]");
127
+ log(" mdkg workspace rm <alias>");
128
+ printGlobalOptions(log);
129
+ }
130
+ function printIndexHelp(log) {
131
+ log("Usage:");
132
+ log(" mdkg index [--tolerant]");
133
+ printGlobalOptions(log);
134
+ }
135
+ function printShowHelp(log) {
136
+ log("Usage:");
137
+ log(" mdkg show <id-or-qid> [--ws <alias>] [--meta] [--json]");
138
+ log("\nWhen to use:");
139
+ log(" Inspect one mdkg node exactly. Use `mdkg skill show <slug>` for skills.");
140
+ log("\nDefault behavior:");
141
+ log(" Shows full body content. Use --meta for card + metadata only.");
142
+ printGlobalOptions(log);
143
+ }
144
+ function printListHelp(log) {
145
+ log("Usage:");
146
+ log(" mdkg list [--type <type>] [--status <status>] [--ws <alias>] [--epic <id>]");
147
+ log(" [--priority <n>] [--blocked] [--tags <tag,tag,...>] [--tags-mode any|all] [--json]");
148
+ log("\nWhen to use:");
149
+ log(" List mdkg nodes. Use `mdkg skill list` for skills.");
150
+ printGlobalOptions(log);
151
+ }
152
+ function printSearchHelp(log) {
153
+ log("Usage:");
154
+ log(' mdkg search "<query>" [--type <type>] [--status <status>] [--ws <alias>]');
155
+ log(" [--tags <tag,tag,...>] [--tags-mode any|all] [--json]");
156
+ log("\nWhen to use:");
157
+ log(" Search mdkg nodes by metadata. Use `mdkg skill search` for skills.");
158
+ printGlobalOptions(log);
159
+ }
160
+ function printPackHelp(log) {
161
+ log("Usage:");
162
+ log(" mdkg pack <id-or-qid> [options]");
163
+ log(" mdkg pack --list-profiles");
164
+ log("\nOptions:");
165
+ log(" -w, --ws <alias> Workspace hint when resolving ambiguous ids");
166
+ log(" -v, --verbose Include pinned core docs from .mdkg/core/core.md");
167
+ log(" -f, --format <fmt> Output format: md|json|toon|xml (default md)");
168
+ log(" -o, --out <path> Output file path");
169
+ log(" --profile <name> Body profile: standard|concise|headers (default standard)");
170
+ log(" --skills <mode> Skill inclusion: none|auto|<slug,slug,...> (default auto)");
171
+ log(" --skills-depth <mode> Skill body mode: meta|full (default meta)");
172
+ log(" --dry-run Preview selection/order/stats without writing files");
173
+ log(" --stats Print per-node + total pack stats and write stats sidecar JSON");
174
+ log(" --list-profiles List built-in pack profiles and exit");
175
+ log("\nAdvanced shaping / debug flags:");
176
+ log(" --depth --edges --strip-code --max-code-lines --max-chars --max-lines --max-tokens");
177
+ log(" --truncation-report --stats-out");
178
+ log("\nExamples:");
179
+ log(" mdkg pack --list-profiles");
180
+ log(" mdkg pack task-1");
181
+ log(" mdkg pack task-1 --profile concise --dry-run --stats");
182
+ log(" mdkg pack task-1 --skills auto --skills-depth full");
183
+ log(" mdkg pack epic-2 --format json --profile headers");
184
+ printGlobalOptions(log);
185
+ }
186
+ function printPackProfiles(log) {
187
+ const profiles = (0, profile_1.listPackProfiles)();
188
+ log("Built-in pack profiles:");
189
+ for (const entry of profiles) {
190
+ log(`- ${entry.profile} (body=${entry.bodyMode})`);
191
+ log(` ${entry.description}`);
192
+ if (entry.defaults.length > 0) {
193
+ log(` defaults: ${entry.defaults.join(", ")}`);
194
+ }
195
+ }
196
+ }
197
+ function printSkillHelp(log, subcommand) {
198
+ switch ((subcommand ?? "").toLowerCase()) {
199
+ case "new":
200
+ log("Usage:");
201
+ log(' mdkg skill new <slug> "<name>" --description "<description>" [options]');
202
+ log("\nOptions:");
203
+ log(" --tags <tag,tag,...> Optional skill tags");
204
+ log(" --authors <name,name,...> Optional authors list");
205
+ log(" --links <url,url,...> Optional links list");
206
+ log(" --run-id <id> Optional event run id when event logging is enabled");
207
+ log(" --with-scripts Create scripts/ in the scaffold");
208
+ log(" --force Overwrite existing SKILL.md");
209
+ printGlobalOptions(log);
210
+ return;
211
+ case "list":
212
+ log("Usage:");
213
+ log(" mdkg skill list [--tags <tag,tag,...>] [--tags-mode any|all] [--json]");
214
+ log("\nWhen to use:");
215
+ log(" Discover skills directly, including stage-tagged orchestrator lookups.");
216
+ printGlobalOptions(log);
217
+ return;
218
+ case "show":
219
+ log("Usage:");
220
+ log(" mdkg skill show <slug> [--meta] [--json]");
221
+ log("\nWhen to use:");
222
+ log(" Inspect one skill body or metadata after discovery.");
223
+ printGlobalOptions(log);
224
+ return;
225
+ case "search":
226
+ log("Usage:");
227
+ log(' mdkg skill search "<query>" [--tags <tag,tag,...>] [--tags-mode any|all] [--json]');
228
+ log("\nWhen to use:");
229
+ log(" Search skills by trigger text, tags, and stage conventions like `stage:plan`.");
230
+ printGlobalOptions(log);
231
+ return;
232
+ case "validate":
233
+ log("Usage:");
234
+ log(" mdkg skill validate [<slug>]");
235
+ printGlobalOptions(log);
236
+ return;
237
+ default:
238
+ log("Usage:");
239
+ log(' mdkg skill new <slug> "<name>" --description "<description>" [options]');
240
+ log(" mdkg skill list [--tags <tag,tag,...>] [--tags-mode any|all] [--json]");
241
+ log(" mdkg skill show <slug> [--meta] [--json]");
242
+ log(' mdkg skill search "<query>" [--tags <tag,tag,...>] [--tags-mode any|all] [--json]');
243
+ log(" mdkg skill validate [<slug>]");
244
+ log("\nNotes:");
245
+ log(" Skills are first-class under `mdkg skill ...`.");
246
+ log(" Use stage tags like `stage:plan`, `stage:execute`, and `stage:review` with --tags.");
247
+ printGlobalOptions(log);
248
+ }
249
+ }
250
+ function printTaskHelp(log, subcommand) {
251
+ switch ((subcommand ?? "").toLowerCase()) {
252
+ case "start":
253
+ log("Usage:");
254
+ log(' mdkg task start <id-or-qid> [--ws <alias>] [--run-id <id>] [--note "<text>"]');
255
+ log("\nWhen to use:");
256
+ log(" Move a task, bug, or test into progress and emit a baseline event when logging is enabled.");
257
+ printGlobalOptions(log);
258
+ return;
259
+ case "update":
260
+ log("Usage:");
261
+ log(" mdkg task update <id-or-qid> [--ws <alias>] [--status <status>] [--priority <n>]");
262
+ log(" [--add-artifacts <a,...>] [--add-links <l,...>] [--add-refs <id,...>]");
263
+ log(" [--add-skills <slug,...>] [--add-tags <tag,...>] [--add-blocked-by <id,...>]");
264
+ log(' [--clear-blocked-by] [--run-id <id>] [--note "<text>"]');
265
+ log("\nWhen to use:");
266
+ log(" Update task metadata and evidence without editing markdown manually.");
267
+ printGlobalOptions(log);
268
+ return;
269
+ case "done":
270
+ log("Usage:");
271
+ log(' mdkg task done <id-or-qid> [--ws <alias>] [--add-artifacts <a,...>] [--add-links <l,...>]');
272
+ log(' [--add-refs <id,...>] [--checkpoint "<title>"] [--run-id <id>] [--note "<text>"]');
273
+ log("\nWhen to use:");
274
+ log(" Mark a task-like node done, optionally create a checkpoint, and emit a completion event when enabled.");
275
+ printGlobalOptions(log);
276
+ return;
277
+ default:
278
+ log("Usage:");
279
+ log(' mdkg task start <id-or-qid> [--ws <alias>] [--run-id <id>] [--note "<text>"]');
280
+ log(" mdkg task update <id-or-qid> [options]");
281
+ log(' mdkg task done <id-or-qid> [--checkpoint "<title>"] [options]');
282
+ log("\nNotes:");
283
+ log(" `mdkg task ...` only supports task, bug, and test nodes in this wave.");
284
+ printGlobalOptions(log);
285
+ }
286
+ }
287
+ function printEventHelp(log, subcommand) {
288
+ switch ((subcommand ?? "").toLowerCase()) {
289
+ case "enable":
290
+ log("Usage:");
291
+ log(" mdkg event enable [--ws <alias>] [--no-update-gitignore]");
292
+ log("\nWhen to use:");
293
+ log(" Create the append-only JSONL event log for a workspace.");
294
+ printGlobalOptions(log);
295
+ return;
296
+ case "append":
297
+ log("Usage:");
298
+ log(" mdkg event append --kind <kind> --status <ok|error|retry|skipped> --refs <id,...>");
299
+ log(' [--ws <alias>] [--artifacts <a,...>] [--notes "<text>"] [--run-id <id>]');
300
+ log(" [--agent <name>] [--skill <slug>] [--tool <id>]");
301
+ log("\nWhen to use:");
302
+ log(" Append explicit provenance events from an orchestrator or manual workflow.");
303
+ printGlobalOptions(log);
304
+ return;
305
+ default:
306
+ log("Usage:");
307
+ log(" mdkg event enable [--ws <alias>] [--no-update-gitignore]");
308
+ log(" mdkg event append --kind <kind> --status <ok|error|retry|skipped> --refs <id,...> [options]");
309
+ printGlobalOptions(log);
310
+ }
311
+ }
312
+ function printNextHelp(log) {
313
+ log("Usage:");
314
+ log(" mdkg next [<id-or-qid>] [--ws <alias>]");
315
+ printGlobalOptions(log);
316
+ }
317
+ function printCheckpointHelp(log) {
318
+ log("Usage:");
319
+ log(" mdkg checkpoint new <title> [--ws <alias>]");
320
+ log(' [--relates <id,id,...>] [--scope <id,id,...>] [--run-id <id>] [--note "<text>"]');
321
+ printGlobalOptions(log);
322
+ }
323
+ function printValidateHelp(log) {
324
+ log("Usage:");
325
+ log(" mdkg validate [--out <path>] [--quiet]");
326
+ printGlobalOptions(log);
327
+ }
328
+ function printFormatHelp(log) {
329
+ log("Usage:");
330
+ log(" mdkg format");
331
+ printGlobalOptions(log);
332
+ }
333
+ function printDoctorHelp(log) {
334
+ log("Usage:");
335
+ log(" mdkg doctor [--json]");
336
+ log("\nChecks:");
337
+ log(" - Node.js version compatibility");
338
+ log(" - mdkg repo root + .mdkg/config.json");
339
+ log(" - Template schema availability");
340
+ log(" - Index load/rebuild health");
341
+ log("\nOptions:");
342
+ log(" --json Emit machine-readable JSON output");
343
+ printGlobalOptions(log);
344
+ }
345
+ function printCommandHelp(log, command, subcommand) {
160
346
  switch ((command ?? "").toLowerCase()) {
161
347
  case "":
162
348
  case "help":
163
- printUsage();
349
+ printUsage(log);
164
350
  return;
165
351
  case "init":
166
- printInitHelp();
352
+ printInitHelp(log);
167
353
  return;
168
354
  case "guide":
169
- printGuideHelp();
355
+ printGuideHelp(log);
170
356
  return;
171
357
  case "new":
172
- printNewHelp();
358
+ printNewHelp(log);
173
359
  return;
174
360
  case "workspace":
175
- printWorkspaceHelp();
361
+ printWorkspaceHelp(log);
176
362
  return;
177
363
  case "index":
178
- printIndexHelp();
364
+ printIndexHelp(log);
179
365
  return;
180
366
  case "show":
181
- printShowHelp();
367
+ printShowHelp(log);
182
368
  return;
183
369
  case "list":
184
- printListHelp();
370
+ printListHelp(log);
185
371
  return;
186
372
  case "search":
187
- printSearchHelp();
373
+ printSearchHelp(log);
188
374
  return;
189
375
  case "pack":
190
- printPackHelp();
376
+ printPackHelp(log);
377
+ return;
378
+ case "skill":
379
+ printSkillHelp(log, subcommand);
380
+ return;
381
+ case "task":
382
+ printTaskHelp(log, subcommand);
383
+ return;
384
+ case "event":
385
+ printEventHelp(log, subcommand);
191
386
  return;
192
387
  case "next":
193
- printNextHelp();
388
+ printNextHelp(log);
194
389
  return;
195
390
  case "checkpoint":
196
- printCheckpointHelp();
391
+ printCheckpointHelp(log);
197
392
  return;
198
393
  case "validate":
199
- printValidateHelp();
394
+ printValidateHelp(log);
200
395
  return;
201
396
  case "format":
202
- printFormatHelp();
397
+ printFormatHelp(log);
398
+ return;
399
+ case "doctor":
400
+ printDoctorHelp(log);
203
401
  return;
204
402
  default:
205
- printUsage();
403
+ printUsage(log);
206
404
  }
207
405
  }
208
- function printRootError(root) {
209
- console.error("mdkg must be run from a repo root with .mdkg/config.json");
210
- console.error(`root checked: ${root}`);
211
- console.error("hint: run from the repo root, pass --root <path>, or run `mdkg init`");
406
+ function printRootError(error, root) {
407
+ error("mdkg must be run from a repo root with .mdkg/config.json");
408
+ error(`root checked: ${root}`);
409
+ error("hint: run from the repo root, pass --root <path>, or run `mdkg init`");
410
+ }
411
+ function readPackageVersion() {
412
+ const packagePath = path_1.default.resolve(__dirname, "..", "package.json");
413
+ if (!fs_1.default.existsSync(packagePath)) {
414
+ return "unknown";
415
+ }
416
+ try {
417
+ const raw = JSON.parse(fs_1.default.readFileSync(packagePath, "utf8"));
418
+ if (typeof raw.version === "string" && raw.version.trim().length > 0) {
419
+ return raw.version;
420
+ }
421
+ }
422
+ catch {
423
+ return "unknown";
424
+ }
425
+ return "unknown";
212
426
  }
213
427
  function hasConfig(root) {
214
428
  const configPath = path_1.default.join(root, ".mdkg", "config.json");
215
429
  return fs_1.default.existsSync(configPath);
216
430
  }
431
+ function shouldRequireConfig(command, flags) {
432
+ if (command === "init" || command === "help") {
433
+ return false;
434
+ }
435
+ if (command === "pack" && flags["--list-profiles"]) {
436
+ return false;
437
+ }
438
+ return true;
439
+ }
217
440
  function requireFlagValue(flag, value) {
218
441
  if (value === undefined) {
219
442
  return undefined;
@@ -268,101 +491,355 @@ function parseEdgesFlag(value) {
268
491
  .filter(Boolean);
269
492
  return raw.length > 0 ? raw : undefined;
270
493
  }
271
- function handleCommandError(err) {
494
+ function parseCsvFlag(flag, value) {
495
+ if (value === undefined) {
496
+ return undefined;
497
+ }
498
+ if (value === true) {
499
+ throw new errors_1.UsageError(`${flag} requires a value`);
500
+ }
501
+ const items = String(value)
502
+ .split(",")
503
+ .map((item) => item.trim().toLowerCase())
504
+ .filter(Boolean);
505
+ return items.length > 0 ? items : undefined;
506
+ }
507
+ function parseTagsModeFlag(value) {
508
+ if (value === undefined) {
509
+ return undefined;
510
+ }
511
+ if (value === true) {
512
+ throw new errors_1.UsageError("--tags-mode requires a value");
513
+ }
514
+ const normalized = String(value).toLowerCase();
515
+ if (normalized === "any" || normalized === "all") {
516
+ return normalized;
517
+ }
518
+ throw new errors_1.UsageError("--tags-mode must be any or all");
519
+ }
520
+ function handleCommandError(err, command, runtime) {
272
521
  const message = err instanceof Error ? err.message : String(err);
273
522
  if (err instanceof errors_1.UsageError) {
274
- console.error(message);
275
- printUsage();
276
- process.exit(1);
523
+ runtime.error(message);
524
+ printCommandHelp(runtime.log, command);
525
+ return 1;
277
526
  }
278
527
  if (err instanceof errors_1.ValidationError) {
279
- console.error(message);
280
- process.exit(2);
528
+ runtime.error(message);
529
+ return 2;
281
530
  }
282
531
  if (err instanceof errors_1.NotFoundError) {
283
- console.error(message);
284
- process.exit(3);
532
+ runtime.error(message);
533
+ return 3;
285
534
  }
286
- console.error(message);
287
- process.exit(4);
535
+ runtime.error(message);
536
+ return 4;
288
537
  }
289
- function main() {
290
- const parsed = (0, argparse_1.parseArgs)(process.argv.slice(2));
291
- if (parsed.error) {
292
- console.error(parsed.error);
293
- printUsage();
294
- process.exit(1);
538
+ function runWorkspaceSubcommand(parsed, root) {
539
+ const subcommand = (parsed.positionals[1] ?? "").toLowerCase();
540
+ switch (subcommand) {
541
+ case "ls": {
542
+ if (parsed.positionals.length > 2) {
543
+ throw new errors_1.UsageError("workspace ls takes no arguments");
544
+ }
545
+ (0, workspace_1.runWorkspaceListCommand)({ root });
546
+ return 0;
547
+ }
548
+ case "add": {
549
+ const alias = parsed.positionals[2];
550
+ const workspacePath = parsed.positionals[3];
551
+ if (!alias || !workspacePath) {
552
+ throw new errors_1.UsageError("workspace add requires <alias> <path>");
553
+ }
554
+ const mdkgDir = requireFlagValue("--mdkg-dir", parsed.flags["--mdkg-dir"]);
555
+ (0, workspace_1.runWorkspaceAddCommand)({ root, alias, workspacePath, mdkgDir });
556
+ return 0;
557
+ }
558
+ case "rm": {
559
+ const alias = parsed.positionals[2];
560
+ if (!alias || parsed.positionals.length > 3) {
561
+ throw new errors_1.UsageError("workspace rm requires <alias>");
562
+ }
563
+ (0, workspace_1.runWorkspaceRemoveCommand)({ root, alias });
564
+ return 0;
565
+ }
566
+ default:
567
+ throw new errors_1.UsageError("workspace requires ls/add/rm");
295
568
  }
296
- if (parsed.help) {
297
- printCommandHelp(parsed.positionals[0]);
298
- process.exit(0);
569
+ }
570
+ function runSkillSubcommand(parsed, root) {
571
+ const subcommand = (parsed.positionals[1] ?? "").toLowerCase();
572
+ switch (subcommand) {
573
+ case "new": {
574
+ const slug = parsed.positionals[2];
575
+ const name = parsed.positionals[3];
576
+ if (!slug || !name) {
577
+ throw new errors_1.UsageError('skill new requires <slug> "<name>"');
578
+ }
579
+ if (parsed.positionals.length > 4) {
580
+ throw new errors_1.UsageError('skill new accepts exactly <slug> "<name>"');
581
+ }
582
+ const description = requireFlagValue("--description", parsed.flags["--description"]);
583
+ if (!description) {
584
+ throw new errors_1.UsageError("skill new requires --description");
585
+ }
586
+ const tags = requireFlagValue("--tags", parsed.flags["--tags"]);
587
+ const authors = requireFlagValue("--authors", parsed.flags["--authors"]);
588
+ const links = requireFlagValue("--links", parsed.flags["--links"]);
589
+ const withScripts = parseBooleanFlag("--with-scripts", parsed.flags["--with-scripts"]);
590
+ const force = parseBooleanFlag("--force", parsed.flags["--force"]);
591
+ const runId = requireFlagValue("--run-id", parsed.flags["--run-id"]);
592
+ (0, skill_1.runSkillNewCommand)({
593
+ root,
594
+ slug,
595
+ name,
596
+ description,
597
+ tags,
598
+ authors,
599
+ links,
600
+ withScripts,
601
+ force,
602
+ runId,
603
+ });
604
+ return 0;
605
+ }
606
+ case "list": {
607
+ if (parsed.positionals.length > 2) {
608
+ throw new errors_1.UsageError("skill list does not accept positional arguments");
609
+ }
610
+ const tags = parseCsvFlag("--tags", parsed.flags["--tags"]);
611
+ const tagsMode = parseTagsModeFlag(parsed.flags["--tags-mode"]);
612
+ const noCache = parseBooleanFlag("--no-cache", parsed.flags["--no-cache"]);
613
+ const noReindex = parseBooleanFlag("--no-reindex", parsed.flags["--no-reindex"]);
614
+ const json = parseBooleanFlag("--json", parsed.flags["--json"]);
615
+ (0, skill_1.runSkillListCommand)({
616
+ root,
617
+ tags,
618
+ tagsMode,
619
+ json,
620
+ noCache,
621
+ noReindex,
622
+ });
623
+ return 0;
624
+ }
625
+ case "show": {
626
+ const slug = parsed.positionals[2];
627
+ if (!slug || parsed.positionals.length > 3) {
628
+ throw new errors_1.UsageError("skill show requires <slug>");
629
+ }
630
+ const metaOnly = parseBooleanFlag("--meta", parsed.flags["--meta"]);
631
+ const json = parseBooleanFlag("--json", parsed.flags["--json"]);
632
+ const noCache = parseBooleanFlag("--no-cache", parsed.flags["--no-cache"]);
633
+ const noReindex = parseBooleanFlag("--no-reindex", parsed.flags["--no-reindex"]);
634
+ (0, skill_1.runSkillShowCommand)({
635
+ root,
636
+ slug,
637
+ metaOnly,
638
+ json,
639
+ noCache,
640
+ noReindex,
641
+ });
642
+ return 0;
643
+ }
644
+ case "search": {
645
+ if (parsed.positionals.length < 3) {
646
+ throw new errors_1.UsageError("skill search requires a query");
647
+ }
648
+ const query = parsed.positionals.slice(2).join(" ");
649
+ const tags = parseCsvFlag("--tags", parsed.flags["--tags"]);
650
+ const tagsMode = parseTagsModeFlag(parsed.flags["--tags-mode"]);
651
+ const json = parseBooleanFlag("--json", parsed.flags["--json"]);
652
+ const noCache = parseBooleanFlag("--no-cache", parsed.flags["--no-cache"]);
653
+ const noReindex = parseBooleanFlag("--no-reindex", parsed.flags["--no-reindex"]);
654
+ (0, skill_1.runSkillSearchCommand)({
655
+ root,
656
+ query,
657
+ tags,
658
+ tagsMode,
659
+ json,
660
+ noCache,
661
+ noReindex,
662
+ });
663
+ return 0;
664
+ }
665
+ case "validate": {
666
+ if (parsed.positionals.length > 3) {
667
+ throw new errors_1.UsageError("skill validate accepts at most one slug");
668
+ }
669
+ const slug = parsed.positionals[2];
670
+ (0, skill_1.runSkillValidateCommand)({ root, slug });
671
+ return 0;
672
+ }
673
+ default:
674
+ throw new errors_1.UsageError("skill requires new/list/show/search/validate");
299
675
  }
300
- const command = (parsed.positionals[0] ?? "").toLowerCase();
301
- if (!command) {
302
- printUsage();
303
- process.exit(0);
676
+ }
677
+ function runTaskSubcommand(parsed, root) {
678
+ const subcommand = (parsed.positionals[1] ?? "").toLowerCase();
679
+ switch (subcommand) {
680
+ case "start": {
681
+ const id = parsed.positionals[2];
682
+ if (!id || parsed.positionals.length > 3) {
683
+ throw new errors_1.UsageError("task start requires <id-or-qid>");
684
+ }
685
+ const ws = requireFlagValue("--ws", parsed.flags["--ws"]);
686
+ const runId = requireFlagValue("--run-id", parsed.flags["--run-id"]);
687
+ const note = requireFlagValue("--note", parsed.flags["--note"]);
688
+ (0, task_1.runTaskStartCommand)({ root, id, ws, runId, note });
689
+ return 0;
690
+ }
691
+ case "update": {
692
+ const id = parsed.positionals[2];
693
+ if (!id || parsed.positionals.length > 3) {
694
+ throw new errors_1.UsageError("task update requires <id-or-qid>");
695
+ }
696
+ const ws = requireFlagValue("--ws", parsed.flags["--ws"]);
697
+ const status = requireFlagValue("--status", parsed.flags["--status"]);
698
+ const priority = parseNumberFlag("--priority", parsed.flags["--priority"]);
699
+ const addArtifacts = requireFlagValue("--add-artifacts", parsed.flags["--add-artifacts"]);
700
+ const addLinks = requireFlagValue("--add-links", parsed.flags["--add-links"]);
701
+ const addRefs = requireFlagValue("--add-refs", parsed.flags["--add-refs"]);
702
+ const addSkills = requireFlagValue("--add-skills", parsed.flags["--add-skills"]);
703
+ const addTags = requireFlagValue("--add-tags", parsed.flags["--add-tags"]);
704
+ const addBlockedBy = requireFlagValue("--add-blocked-by", parsed.flags["--add-blocked-by"]);
705
+ const clearBlockedBy = parseBooleanFlag("--clear-blocked-by", parsed.flags["--clear-blocked-by"]);
706
+ const runId = requireFlagValue("--run-id", parsed.flags["--run-id"]);
707
+ const note = requireFlagValue("--note", parsed.flags["--note"]);
708
+ (0, task_1.runTaskUpdateCommand)({
709
+ root,
710
+ id,
711
+ ws,
712
+ status,
713
+ priority,
714
+ addArtifacts,
715
+ addLinks,
716
+ addRefs,
717
+ addSkills,
718
+ addTags,
719
+ addBlockedBy,
720
+ clearBlockedBy,
721
+ runId,
722
+ note,
723
+ });
724
+ return 0;
725
+ }
726
+ case "done": {
727
+ const id = parsed.positionals[2];
728
+ if (!id || parsed.positionals.length > 3) {
729
+ throw new errors_1.UsageError("task done requires <id-or-qid>");
730
+ }
731
+ const ws = requireFlagValue("--ws", parsed.flags["--ws"]);
732
+ const addArtifacts = requireFlagValue("--add-artifacts", parsed.flags["--add-artifacts"]);
733
+ const addLinks = requireFlagValue("--add-links", parsed.flags["--add-links"]);
734
+ const addRefs = requireFlagValue("--add-refs", parsed.flags["--add-refs"]);
735
+ const checkpoint = requireFlagValue("--checkpoint", parsed.flags["--checkpoint"]);
736
+ const runId = requireFlagValue("--run-id", parsed.flags["--run-id"]);
737
+ const note = requireFlagValue("--note", parsed.flags["--note"]);
738
+ (0, task_1.runTaskDoneCommand)({
739
+ root,
740
+ id,
741
+ ws,
742
+ addArtifacts,
743
+ addLinks,
744
+ addRefs,
745
+ checkpoint,
746
+ runId,
747
+ note,
748
+ });
749
+ return 0;
750
+ }
751
+ default:
752
+ throw new errors_1.UsageError("task requires start/update/done");
304
753
  }
305
- if (command === "help") {
306
- printCommandHelp(parsed.positionals[1]);
307
- process.exit(0);
308
- }
309
- const root = parsed.root ? path_1.default.resolve(parsed.root) : process.cwd();
310
- if (command !== "init" && command !== "help") {
311
- if (!hasConfig(root)) {
312
- printRootError(root);
313
- process.exit(1);
754
+ }
755
+ function runEventSubcommand(parsed, root) {
756
+ const subcommand = (parsed.positionals[1] ?? "").toLowerCase();
757
+ switch (subcommand) {
758
+ case "enable": {
759
+ if (parsed.positionals.length > 2) {
760
+ throw new errors_1.UsageError("event enable does not accept positional arguments");
761
+ }
762
+ const ws = requireFlagValue("--ws", parsed.flags["--ws"]);
763
+ const noUpdateGitignore = parseBooleanFlag("--no-update-gitignore", parsed.flags["--no-update-gitignore"]);
764
+ (0, event_1.runEventEnableCommand)({ root, ws, updateGitignore: !noUpdateGitignore });
765
+ return 0;
314
766
  }
767
+ case "append": {
768
+ if (parsed.positionals.length > 2) {
769
+ throw new errors_1.UsageError("event append does not accept positional arguments");
770
+ }
771
+ const kind = requireFlagValue("--kind", parsed.flags["--kind"]);
772
+ const status = requireFlagValue("--status", parsed.flags["--status"]);
773
+ const refs = requireFlagValue("--refs", parsed.flags["--refs"]);
774
+ if (!kind || !status || !refs) {
775
+ throw new errors_1.UsageError("event append requires --kind, --status, and --refs");
776
+ }
777
+ const ws = requireFlagValue("--ws", parsed.flags["--ws"]);
778
+ const artifacts = requireFlagValue("--artifacts", parsed.flags["--artifacts"]);
779
+ const notes = requireFlagValue("--notes", parsed.flags["--notes"]);
780
+ const runId = requireFlagValue("--run-id", parsed.flags["--run-id"]);
781
+ const agent = requireFlagValue("--agent", parsed.flags["--agent"]);
782
+ const skill = requireFlagValue("--skill", parsed.flags["--skill"]);
783
+ const tool = requireFlagValue("--tool", parsed.flags["--tool"]);
784
+ (0, event_1.runEventAppendCommand)({
785
+ root,
786
+ ws,
787
+ kind,
788
+ status,
789
+ refs,
790
+ artifacts,
791
+ notes,
792
+ runId,
793
+ agent,
794
+ skill,
795
+ tool,
796
+ });
797
+ return 0;
798
+ }
799
+ default:
800
+ throw new errors_1.UsageError("event requires enable/append");
315
801
  }
802
+ }
803
+ function runCommand(parsed, root, runtime) {
804
+ const command = (parsed.positionals[0] ?? "").toLowerCase();
316
805
  switch (command) {
317
806
  case "init": {
318
807
  const force = parseBooleanFlag("--force", parsed.flags["--force"]);
319
808
  const createAgents = parseBooleanFlag("--agents", parsed.flags["--agents"]);
320
809
  const createClaude = parseBooleanFlag("--claude", parsed.flags["--claude"]);
321
810
  const createLlm = parseBooleanFlag("--llm", parsed.flags["--llm"]);
811
+ const omni = parseBooleanFlag("--omni", parsed.flags["--omni"]);
812
+ const noUpdateIgnores = parseBooleanFlag("--no-update-ignores", parsed.flags["--no-update-ignores"]);
322
813
  const updateGitignore = parseBooleanFlag("--update-gitignore", parsed.flags["--update-gitignore"]);
323
814
  const updateNpmignore = parseBooleanFlag("--update-npmignore", parsed.flags["--update-npmignore"]);
324
815
  const updateDockerignore = parseBooleanFlag("--update-dockerignore", parsed.flags["--update-dockerignore"]);
325
- try {
326
- (0, init_1.runInitCommand)({
327
- root,
328
- force,
329
- updateGitignore,
330
- updateNpmignore,
331
- updateDockerignore,
332
- createAgents,
333
- createClaude,
334
- createLlm,
335
- });
336
- }
337
- catch (err) {
338
- handleCommandError(err);
339
- }
340
- process.exit(0);
341
- }
342
- case "guide": {
343
- try {
344
- (0, guide_1.runGuideCommand)({ root });
345
- }
346
- catch (err) {
347
- handleCommandError(err);
348
- }
349
- process.exit(0);
816
+ (0, init_1.runInitCommand)({
817
+ root,
818
+ force,
819
+ updateGitignore,
820
+ updateNpmignore,
821
+ updateDockerignore,
822
+ noUpdateIgnores,
823
+ createAgents,
824
+ createClaude,
825
+ createLlm,
826
+ omni,
827
+ });
828
+ return 0;
350
829
  }
830
+ case "guide":
831
+ (0, guide_1.runGuideCommand)({ root });
832
+ return 0;
351
833
  case "index": {
352
834
  const tolerant = Boolean(parsed.flags["--tolerant"]);
353
- try {
354
- (0, index_1.runIndexCommand)({ root, tolerant });
355
- }
356
- catch (err) {
357
- handleCommandError(err);
358
- }
359
- process.exit(0);
835
+ (0, index_1.runIndexCommand)({ root, tolerant });
836
+ return 0;
360
837
  }
361
838
  case "new": {
362
839
  const type = parsed.positionals[1];
363
840
  const title = parsed.positionals.slice(2).join(" ");
364
841
  if (!type || !title) {
365
- handleCommandError(new errors_1.UsageError("new requires a type and title"));
842
+ throw new errors_1.UsageError("new requires a type and title");
366
843
  }
367
844
  const ws = requireFlagValue("--ws", parsed.flags["--ws"]);
368
845
  const status = requireFlagValue("--status", parsed.flags["--status"]);
@@ -378,6 +855,7 @@ function main() {
378
855
  const artifacts = requireFlagValue("--artifacts", parsed.flags["--artifacts"]);
379
856
  const refs = requireFlagValue("--refs", parsed.flags["--refs"]);
380
857
  const aliases = requireFlagValue("--aliases", parsed.flags["--aliases"]);
858
+ const skills = requireFlagValue("--skills", parsed.flags["--skills"]);
381
859
  const cases = requireFlagValue("--cases", parsed.flags["--cases"]);
382
860
  const tags = requireFlagValue("--tags", parsed.flags["--tags"]);
383
861
  const owners = requireFlagValue("--owners", parsed.flags["--owners"]);
@@ -385,115 +863,69 @@ function main() {
385
863
  const template = requireFlagValue("--template", parsed.flags["--template"]);
386
864
  const noCache = parseBooleanFlag("--no-cache", parsed.flags["--no-cache"]);
387
865
  const noReindex = parseBooleanFlag("--no-reindex", parsed.flags["--no-reindex"]);
388
- try {
389
- (0, new_1.runNewCommand)({
390
- root,
391
- type,
392
- title,
393
- ws,
394
- status,
395
- priority,
396
- epic,
397
- parent,
398
- prev,
399
- next,
400
- relates,
401
- blockedBy,
402
- blocks,
403
- links,
404
- artifacts,
405
- refs,
406
- aliases,
407
- cases,
408
- tags,
409
- owners,
410
- supersedes,
411
- template,
412
- noCache,
413
- noReindex,
414
- });
415
- }
416
- catch (err) {
417
- handleCommandError(err);
418
- }
419
- process.exit(0);
420
- }
421
- case "workspace": {
422
- const subcommand = (parsed.positionals[1] ?? "").toLowerCase();
423
- switch (subcommand) {
424
- case "ls": {
425
- if (parsed.positionals.length > 2) {
426
- handleCommandError(new errors_1.UsageError("workspace ls takes no arguments"));
427
- }
428
- try {
429
- (0, workspace_1.runWorkspaceListCommand)({ root });
430
- }
431
- catch (err) {
432
- handleCommandError(err);
433
- }
434
- process.exit(0);
435
- }
436
- case "add": {
437
- const alias = parsed.positionals[2];
438
- const workspacePath = parsed.positionals[3];
439
- if (!alias || !workspacePath) {
440
- handleCommandError(new errors_1.UsageError("workspace add requires <alias> <path>"));
441
- }
442
- const mdkgDir = requireFlagValue("--mdkg-dir", parsed.flags["--mdkg-dir"]);
443
- try {
444
- (0, workspace_1.runWorkspaceAddCommand)({ root, alias, workspacePath, mdkgDir });
445
- }
446
- catch (err) {
447
- handleCommandError(err);
448
- }
449
- process.exit(0);
450
- }
451
- case "rm": {
452
- const alias = parsed.positionals[2];
453
- if (!alias || parsed.positionals.length > 3) {
454
- handleCommandError(new errors_1.UsageError("workspace rm requires <alias>"));
455
- }
456
- try {
457
- (0, workspace_1.runWorkspaceRemoveCommand)({ root, alias });
458
- }
459
- catch (err) {
460
- handleCommandError(err);
461
- }
462
- process.exit(0);
463
- }
464
- default: {
465
- handleCommandError(new errors_1.UsageError("workspace requires ls/add/rm"));
466
- }
467
- }
468
- process.exit(0);
866
+ const runId = requireFlagValue("--run-id", parsed.flags["--run-id"]);
867
+ (0, new_1.runNewCommand)({
868
+ root,
869
+ type,
870
+ title,
871
+ ws,
872
+ status,
873
+ priority,
874
+ epic,
875
+ parent,
876
+ prev,
877
+ next,
878
+ relates,
879
+ blockedBy,
880
+ blocks,
881
+ links,
882
+ artifacts,
883
+ refs,
884
+ aliases,
885
+ skills,
886
+ cases,
887
+ tags,
888
+ owners,
889
+ supersedes,
890
+ template,
891
+ noCache,
892
+ noReindex,
893
+ runId,
894
+ });
895
+ return 0;
469
896
  }
897
+ case "workspace":
898
+ return runWorkspaceSubcommand(parsed, root);
899
+ case "skill":
900
+ return runSkillSubcommand(parsed, root);
901
+ case "task":
902
+ return runTaskSubcommand(parsed, root);
903
+ case "event":
904
+ return runEventSubcommand(parsed, root);
470
905
  case "show": {
471
906
  const id = parsed.positionals[1];
472
907
  if (!id || parsed.positionals.length > 2) {
473
- handleCommandError(new errors_1.UsageError("show requires a single id"));
908
+ throw new errors_1.UsageError("show requires a single id");
474
909
  }
475
910
  const ws = requireFlagValue("--ws", parsed.flags["--ws"]);
476
- const includeBody = parseBooleanFlag("--body", parsed.flags["--body"]);
911
+ const metaOnly = parseBooleanFlag("--meta", parsed.flags["--meta"]);
912
+ const json = parseBooleanFlag("--json", parsed.flags["--json"]);
477
913
  const noCache = parseBooleanFlag("--no-cache", parsed.flags["--no-cache"]);
478
914
  const noReindex = parseBooleanFlag("--no-reindex", parsed.flags["--no-reindex"]);
479
- try {
480
- (0, show_1.runShowCommand)({
481
- root,
482
- id,
483
- ws,
484
- includeBody,
485
- noCache,
486
- noReindex,
487
- });
488
- }
489
- catch (err) {
490
- handleCommandError(err);
491
- }
492
- process.exit(0);
915
+ (0, show_1.runShowCommand)({
916
+ root,
917
+ id,
918
+ ws,
919
+ metaOnly,
920
+ json,
921
+ noCache,
922
+ noReindex,
923
+ });
924
+ return 0;
493
925
  }
494
926
  case "list": {
495
927
  if (parsed.positionals.length > 1) {
496
- handleCommandError(new errors_1.UsageError("list does not accept positional arguments"));
928
+ throw new errors_1.UsageError("list does not accept positional arguments");
497
929
  }
498
930
  const ws = requireFlagValue("--ws", parsed.flags["--ws"]);
499
931
  const type = requireFlagValue("--type", parsed.flags["--type"]);
@@ -501,113 +933,139 @@ function main() {
501
933
  const epic = requireFlagValue("--epic", parsed.flags["--epic"]);
502
934
  const priority = parseNumberFlag("--priority", parsed.flags["--priority"]);
503
935
  const blocked = parseBooleanFlag("--blocked", parsed.flags["--blocked"]);
936
+ const tags = parseCsvFlag("--tags", parsed.flags["--tags"]);
937
+ const tagsMode = parseTagsModeFlag(parsed.flags["--tags-mode"]);
938
+ const json = parseBooleanFlag("--json", parsed.flags["--json"]);
504
939
  const noCache = parseBooleanFlag("--no-cache", parsed.flags["--no-cache"]);
505
940
  const noReindex = parseBooleanFlag("--no-reindex", parsed.flags["--no-reindex"]);
506
- try {
507
- (0, list_1.runListCommand)({
508
- root,
509
- ws,
510
- type,
511
- status,
512
- epic,
513
- priority,
514
- blocked,
515
- noCache,
516
- noReindex,
517
- });
518
- }
519
- catch (err) {
520
- handleCommandError(err);
521
- }
522
- process.exit(0);
941
+ (0, list_1.runListCommand)({
942
+ root,
943
+ ws,
944
+ type,
945
+ status,
946
+ epic,
947
+ priority,
948
+ blocked,
949
+ tags,
950
+ tagsMode,
951
+ json,
952
+ noCache,
953
+ noReindex,
954
+ });
955
+ return 0;
523
956
  }
524
957
  case "search": {
525
958
  if (parsed.positionals.length < 2) {
526
- handleCommandError(new errors_1.UsageError("search requires a query"));
959
+ throw new errors_1.UsageError("search requires a query");
527
960
  }
528
961
  const query = parsed.positionals.slice(1).join(" ");
529
962
  const ws = requireFlagValue("--ws", parsed.flags["--ws"]);
530
963
  const type = requireFlagValue("--type", parsed.flags["--type"]);
531
964
  const status = requireFlagValue("--status", parsed.flags["--status"]);
965
+ const tags = parseCsvFlag("--tags", parsed.flags["--tags"]);
966
+ const tagsMode = parseTagsModeFlag(parsed.flags["--tags-mode"]);
967
+ const json = parseBooleanFlag("--json", parsed.flags["--json"]);
532
968
  const noCache = parseBooleanFlag("--no-cache", parsed.flags["--no-cache"]);
533
969
  const noReindex = parseBooleanFlag("--no-reindex", parsed.flags["--no-reindex"]);
534
- try {
535
- (0, search_1.runSearchCommand)({
536
- root,
537
- query,
538
- ws,
539
- type,
540
- status,
541
- noCache,
542
- noReindex,
543
- });
544
- }
545
- catch (err) {
546
- handleCommandError(err);
547
- }
548
- process.exit(0);
970
+ (0, search_1.runSearchCommand)({
971
+ root,
972
+ query,
973
+ ws,
974
+ type,
975
+ status,
976
+ tags,
977
+ tagsMode,
978
+ json,
979
+ noCache,
980
+ noReindex,
981
+ });
982
+ return 0;
549
983
  }
550
984
  case "pack": {
985
+ const listProfiles = parseBooleanFlag("--list-profiles", parsed.flags["--list-profiles"]);
986
+ if (listProfiles) {
987
+ if (parsed.positionals.length > 1) {
988
+ throw new errors_1.UsageError("pack --list-profiles does not accept positional arguments");
989
+ }
990
+ printPackProfiles(runtime.log);
991
+ return 0;
992
+ }
551
993
  const id = parsed.positionals[1];
552
994
  if (!id || parsed.positionals.length > 2) {
553
- handleCommandError(new errors_1.UsageError("pack requires a single id"));
995
+ throw new errors_1.UsageError("pack requires a single id");
554
996
  }
555
997
  const ws = requireFlagValue("--ws", parsed.flags["--ws"]);
556
998
  const depth = parseNumberFlag("--depth", parsed.flags["--depth"]);
557
999
  const edges = parseEdgesFlag(parsed.flags["--edges"]);
558
1000
  const verbose = parseBooleanFlag("--verbose", parsed.flags["--verbose"]);
1001
+ const concise = parseBooleanFlag("--concise", parsed.flags["--concise"]);
1002
+ const stripCode = parseBooleanFlag("--strip-code", parsed.flags["--strip-code"]);
559
1003
  const format = requireFlagValue("--format", parsed.flags["--format"]);
1004
+ const packProfile = requireFlagValue("--pack-profile", parsed.flags["--pack-profile"]);
1005
+ const maxCodeLines = parseNumberFlag("--max-code-lines", parsed.flags["--max-code-lines"]);
1006
+ const maxChars = parseNumberFlag("--max-chars", parsed.flags["--max-chars"]);
1007
+ const maxLines = parseNumberFlag("--max-lines", parsed.flags["--max-lines"]);
1008
+ const maxTokens = parseNumberFlag("--max-tokens", parsed.flags["--max-tokens"]);
1009
+ const skills = requireFlagValue("--skills", parsed.flags["--skills"]);
1010
+ const skillsDepth = requireFlagValue("--skills-depth", parsed.flags["--skills-depth"]);
1011
+ const dryRun = parseBooleanFlag("--dry-run", parsed.flags["--dry-run"]);
1012
+ const stats = parseBooleanFlag("--stats", parsed.flags["--stats"]);
1013
+ const statsOut = requireFlagValue("--stats-out", parsed.flags["--stats-out"]);
1014
+ const truncationReport = requireFlagValue("--truncation-report", parsed.flags["--truncation-report"]);
560
1015
  const out = requireFlagValue("--out", parsed.flags["--out"]);
561
1016
  const noCache = parseBooleanFlag("--no-cache", parsed.flags["--no-cache"]);
562
1017
  const noReindex = parseBooleanFlag("--no-reindex", parsed.flags["--no-reindex"]);
563
- try {
564
- (0, pack_1.runPackCommand)({
565
- root,
566
- id,
567
- ws,
568
- depth,
569
- edges,
570
- verbose,
571
- format,
572
- out,
573
- noCache,
574
- noReindex,
575
- });
576
- }
577
- catch (err) {
578
- handleCommandError(err);
579
- }
580
- process.exit(0);
1018
+ (0, pack_1.runPackCommand)({
1019
+ root,
1020
+ id,
1021
+ ws,
1022
+ depth,
1023
+ edges,
1024
+ verbose,
1025
+ concise,
1026
+ stripCode,
1027
+ format,
1028
+ packProfile,
1029
+ maxCodeLines,
1030
+ maxChars,
1031
+ maxLines,
1032
+ maxTokens,
1033
+ skills,
1034
+ skillsDepth,
1035
+ dryRun,
1036
+ stats,
1037
+ statsOut,
1038
+ truncationReport,
1039
+ out,
1040
+ noCache,
1041
+ noReindex,
1042
+ });
1043
+ return 0;
581
1044
  }
582
1045
  case "next": {
583
1046
  if (parsed.positionals.length > 2) {
584
- handleCommandError(new errors_1.UsageError("next accepts at most one id"));
1047
+ throw new errors_1.UsageError("next accepts at most one id");
585
1048
  }
586
1049
  const id = parsed.positionals[1];
587
1050
  const ws = requireFlagValue("--ws", parsed.flags["--ws"]);
588
1051
  const noCache = parseBooleanFlag("--no-cache", parsed.flags["--no-cache"]);
589
1052
  const noReindex = parseBooleanFlag("--no-reindex", parsed.flags["--no-reindex"]);
590
- try {
591
- (0, next_1.runNextCommand)({
592
- root,
593
- id,
594
- ws,
595
- noCache,
596
- noReindex,
597
- });
598
- }
599
- catch (err) {
600
- handleCommandError(err);
601
- }
602
- process.exit(0);
1053
+ (0, next_1.runNextCommand)({
1054
+ root,
1055
+ id,
1056
+ ws,
1057
+ noCache,
1058
+ noReindex,
1059
+ });
1060
+ return 0;
603
1061
  }
604
1062
  case "checkpoint": {
605
1063
  const sub = (parsed.positionals[1] ?? "").toLowerCase();
606
1064
  if (!sub) {
607
- handleCommandError(new errors_1.UsageError("checkpoint requires a subcommand"));
1065
+ throw new errors_1.UsageError("checkpoint requires a subcommand");
608
1066
  }
609
1067
  if (sub !== "new") {
610
- handleCommandError(new errors_1.UsageError(`unknown checkpoint subcommand: ${sub}`));
1068
+ throw new errors_1.UsageError(`unknown checkpoint subcommand: ${sub}`);
611
1069
  }
612
1070
  const title = parsed.positionals.slice(2).join(" ");
613
1071
  const ws = requireFlagValue("--ws", parsed.flags["--ws"]);
@@ -616,53 +1074,93 @@ function main() {
616
1074
  const status = requireFlagValue("--status", parsed.flags["--status"]);
617
1075
  const priority = parseNumberFlag("--priority", parsed.flags["--priority"]);
618
1076
  const template = requireFlagValue("--template", parsed.flags["--template"]);
619
- try {
620
- (0, checkpoint_1.runCheckpointNewCommand)({
621
- root,
622
- title,
623
- ws,
624
- relates,
625
- scope,
626
- status,
627
- priority,
628
- template,
629
- });
630
- }
631
- catch (err) {
632
- handleCommandError(err);
633
- }
634
- process.exit(0);
1077
+ const runId = requireFlagValue("--run-id", parsed.flags["--run-id"]);
1078
+ const note = requireFlagValue("--note", parsed.flags["--note"]);
1079
+ (0, checkpoint_1.runCheckpointNewCommand)({
1080
+ root,
1081
+ title,
1082
+ ws,
1083
+ relates,
1084
+ scope,
1085
+ status,
1086
+ priority,
1087
+ template,
1088
+ runId,
1089
+ note,
1090
+ });
1091
+ return 0;
635
1092
  }
636
1093
  case "validate": {
637
1094
  if (parsed.positionals.length > 1) {
638
- handleCommandError(new errors_1.UsageError("validate does not accept positional arguments"));
1095
+ throw new errors_1.UsageError("validate does not accept positional arguments");
639
1096
  }
640
1097
  const out = requireFlagValue("--out", parsed.flags["--out"]);
641
1098
  const quiet = parseBooleanFlag("--quiet", parsed.flags["--quiet"]);
642
- try {
643
- (0, validate_1.runValidateCommand)({ root, out, quiet });
644
- }
645
- catch (err) {
646
- handleCommandError(err);
647
- }
648
- process.exit(0);
1099
+ (0, validate_1.runValidateCommand)({ root, out, quiet });
1100
+ return 0;
649
1101
  }
650
- case "format": {
1102
+ case "format":
651
1103
  if (parsed.positionals.length > 1) {
652
- handleCommandError(new errors_1.UsageError("format does not accept positional arguments"));
653
- }
654
- try {
655
- (0, format_1.runFormatCommand)({ root });
1104
+ throw new errors_1.UsageError("format does not accept positional arguments");
656
1105
  }
657
- catch (err) {
658
- handleCommandError(err);
1106
+ (0, format_1.runFormatCommand)({ root });
1107
+ return 0;
1108
+ case "doctor": {
1109
+ if (parsed.positionals.length > 1) {
1110
+ throw new errors_1.UsageError("doctor does not accept positional arguments");
659
1111
  }
660
- process.exit(0);
1112
+ const noCache = parseBooleanFlag("--no-cache", parsed.flags["--no-cache"]);
1113
+ const noReindex = parseBooleanFlag("--no-reindex", parsed.flags["--no-reindex"]);
1114
+ const json = parseBooleanFlag("--json", parsed.flags["--json"]);
1115
+ (0, doctor_1.runDoctorCommand)({ root, noCache, noReindex, json });
1116
+ return 0;
661
1117
  }
662
1118
  default:
663
- console.error(`Unknown command: ${command}`);
664
- printUsage();
665
- process.exit(1);
1119
+ runtime.error(`Unknown command: ${command}`);
1120
+ printUsage(runtime.log);
1121
+ return 1;
1122
+ }
1123
+ }
1124
+ function runCli(argv, runtime = {}) {
1125
+ const io = resolveRuntime(runtime);
1126
+ const parsed = (0, argparse_1.parseArgs)(argv);
1127
+ if (parsed.error) {
1128
+ io.error(parsed.error);
1129
+ printUsage(io.log);
1130
+ return 1;
1131
+ }
1132
+ if (parsed.help) {
1133
+ printCommandHelp(io.log, parsed.positionals[0], parsed.positionals[1]);
1134
+ return 0;
1135
+ }
1136
+ if (parsed.version) {
1137
+ io.log(readPackageVersion());
1138
+ return 0;
1139
+ }
1140
+ const command = (parsed.positionals[0] ?? "").toLowerCase();
1141
+ if (!command) {
1142
+ printUsage(io.log);
1143
+ return 0;
1144
+ }
1145
+ if (command === "help") {
1146
+ printCommandHelp(io.log, parsed.positionals[1], parsed.positionals[2]);
1147
+ return 0;
1148
+ }
1149
+ const root = parsed.root ? path_1.default.resolve(parsed.root) : io.cwd();
1150
+ if (shouldRequireConfig(command, parsed.flags) && !hasConfig(root)) {
1151
+ printRootError(io.error, root);
1152
+ return 1;
1153
+ }
1154
+ try {
1155
+ return runCommand(parsed, root, io);
666
1156
  }
1157
+ catch (err) {
1158
+ return handleCommandError(err, command, io);
1159
+ }
1160
+ }
1161
+ function main(argv = process.argv.slice(2)) {
1162
+ process.exit(runCli(argv, { cwd: () => process.cwd() }));
1163
+ }
1164
+ if (require.main === module) {
1165
+ main();
667
1166
  }
668
- main();