mdkg 0.0.5 → 0.0.7
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 +16 -10
- package/dist/cli.js +48 -29
- package/dist/commands/event.js +1 -2
- package/dist/commands/event_support.js +2 -30
- package/dist/commands/init.js +6 -1
- package/dist/commands/list.js +4 -3
- package/dist/commands/query_output.js +108 -0
- package/dist/commands/search.js +4 -3
- package/dist/commands/show.js +4 -3
- package/dist/commands/skill.js +12 -9
- package/dist/commands/skill_mirror.js +42 -9
- package/dist/commands/task.js +1 -1
- package/dist/init/AGENTS.md +1 -0
- package/dist/init/AGENT_START.md +10 -3
- package/dist/init/CLI_COMMAND_MATRIX.md +7 -0
- package/dist/init/config.json +1 -11
- package/dist/init/core/rule-3-cli-contract.md +14 -9
- package/dist/init/core/rule-4-repo-safety-and-ignores.md +2 -3
- package/dist/init/llms.txt +2 -0
- package/dist/init/skills/default/build-pack-and-execute-task/SKILL.md +57 -0
- package/dist/init/skills/default/select-work-and-ground-context/SKILL.md +55 -0
- package/dist/init/skills/default/verify-close-and-checkpoint/SKILL.md +62 -0
- package/dist/util/argparse.js +3 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -13,7 +13,7 @@ mdkg stays deliberately boring:
|
|
|
13
13
|
- zero runtime dependencies
|
|
14
14
|
- no sqlite, daemon, hosted index, or vector DB
|
|
15
15
|
|
|
16
|
-
Current package version in source: `0.0.
|
|
16
|
+
Current package version in source: `0.0.6`
|
|
17
17
|
|
|
18
18
|
## The product shape
|
|
19
19
|
|
|
@@ -49,7 +49,7 @@ Initialize mdkg in a repo:
|
|
|
49
49
|
mdkg init --llm
|
|
50
50
|
```
|
|
51
51
|
|
|
52
|
-
This is the generic OSS bootstrap path. It creates `.mdkg/` and updates `.gitignore` / `.npmignore` by default. Use `--no-update-ignores` to opt out.
|
|
52
|
+
This is the generic OSS bootstrap path. It creates `.mdkg/` and updates `.gitignore` / `.npmignore` by default. Use `--no-update-ignores` to opt out of those ignore-file updates.
|
|
53
53
|
|
|
54
54
|
Optional agent-ready scaffold:
|
|
55
55
|
|
|
@@ -57,7 +57,7 @@ Optional agent-ready scaffold:
|
|
|
57
57
|
mdkg init --agent
|
|
58
58
|
```
|
|
59
59
|
|
|
60
|
-
This adds strict-node `SOUL.md` / `HUMAN.md`,
|
|
60
|
+
This adds strict-node `SOUL.md` / `HUMAN.md`, seeds the three default mdkg usage skills, creates `events.jsonl`, updates the skill registry, adds core pin updates, and creates mirrored skill folders under `.agents/skills/` and `.claude/skills/`.
|
|
61
61
|
|
|
62
62
|
Create a task:
|
|
63
63
|
|
|
@@ -86,7 +86,7 @@ Validate before handoff or commit:
|
|
|
86
86
|
mdkg validate
|
|
87
87
|
```
|
|
88
88
|
|
|
89
|
-
|
|
89
|
+
Update structured task state and evidence while keeping body and narrative edits in markdown:
|
|
90
90
|
|
|
91
91
|
```bash
|
|
92
92
|
mdkg task start task-1 --run-id run_local_1
|
|
@@ -94,7 +94,7 @@ mdkg task update task-1 --add-artifacts tests://unit.txt --add-tags release
|
|
|
94
94
|
mdkg task done task-1 --checkpoint "release readiness milestone"
|
|
95
95
|
```
|
|
96
96
|
|
|
97
|
-
|
|
97
|
+
Ensure and append baseline event memory:
|
|
98
98
|
|
|
99
99
|
```bash
|
|
100
100
|
mdkg event enable
|
|
@@ -176,10 +176,13 @@ Current source behavior:
|
|
|
176
176
|
- `mdkg skill show <slug>`
|
|
177
177
|
- `mdkg skill validate [<slug>]`
|
|
178
178
|
- `mdkg skill sync`
|
|
179
|
-
- machine-readable skill discovery is available through:
|
|
179
|
+
- machine-readable skill discovery and inspection is available through:
|
|
180
180
|
- `mdkg skill list --json`
|
|
181
181
|
- `mdkg skill search "<query>" --json`
|
|
182
182
|
- `mdkg skill show <slug> --json`
|
|
183
|
+
- `mdkg skill list --xml|--toon|--md`
|
|
184
|
+
- `mdkg skill search "<query>" --xml|--toon|--md`
|
|
185
|
+
- `mdkg skill show <slug> --xml|--toon|--md`
|
|
183
186
|
- work items may reference `skills: [slug,...]`
|
|
184
187
|
- packs may include skills with `--skills` and `--skills-depth`
|
|
185
188
|
- mdkg indexes and discovers skills but does not execute skill scripts
|
|
@@ -200,12 +203,14 @@ This repo now dogfoods three internal skills:
|
|
|
200
203
|
|
|
201
204
|
This release includes:
|
|
202
205
|
- `init --agent`
|
|
203
|
-
- default ignore updates with `--no-update-ignores`
|
|
206
|
+
- default ignore updates with `--no-update-ignores` for `.mdkg/index/` and `.mdkg/pack/`
|
|
207
|
+
- root-only published init seed config
|
|
204
208
|
- skills indexing and search/show/list support
|
|
205
209
|
- optional `skills: [...]` on work items
|
|
206
210
|
- pack-time skill inclusion
|
|
207
211
|
- latest-checkpoint resolver + index hint
|
|
208
212
|
- events JSONL validation
|
|
213
|
+
- XML / TOON / Markdown output for node and skill list/search/show
|
|
209
214
|
- product-specific skill mirrors for Codex/OpenAI and Claude
|
|
210
215
|
- shared `AGENT_START.md` startup guidance
|
|
211
216
|
|
|
@@ -213,7 +218,8 @@ Current direction:
|
|
|
213
218
|
- keep the OSS story generic around `init --llm`
|
|
214
219
|
- use `init --agent` for deeper AI-agent bootstrap
|
|
215
220
|
- keep `pack <id>` at the center of the human/agent loop
|
|
216
|
-
-
|
|
221
|
+
- use `mdkg task ...` for structured state changes and markdown edits for narrative/body content
|
|
222
|
+
- make event logging guided instead of purely manual
|
|
217
223
|
- dogfood real skills inside the repo
|
|
218
224
|
- make skill authoring first-class through `mdkg skill`
|
|
219
225
|
- make `CLI_COMMAND_MATRIX.md` the single source of truth for the live CLI surface
|
|
@@ -228,7 +234,7 @@ mdkg is not a secret store.
|
|
|
228
234
|
Use these defaults:
|
|
229
235
|
- keep `.mdkg/index/` gitignored
|
|
230
236
|
- keep `.mdkg/pack/` gitignored
|
|
231
|
-
-
|
|
237
|
+
- event logs are committed by default; ignore or delete them manually if a repo wants local-only provenance
|
|
232
238
|
- do not ship `.mdkg/` into production builds or published packages
|
|
233
239
|
- if an external orchestrator is writing mdkg state, keep one durable writer per run and batch commits at end-of-run or checkpoint boundaries
|
|
234
240
|
- do not commit on every tool call
|
|
@@ -245,7 +251,7 @@ Suggested local loop:
|
|
|
245
251
|
2. inspect truth with `search`, `show`, or `next`
|
|
246
252
|
3. build context with `pack <id>`
|
|
247
253
|
4. mutate task state with `mdkg task ...` when durable state changes
|
|
248
|
-
5.
|
|
254
|
+
5. ensure event logging exists if the JSONL file was deleted or is missing
|
|
249
255
|
6. implement and test
|
|
250
256
|
7. run `mdkg validate`
|
|
251
257
|
|
package/dist/cli.js
CHANGED
|
@@ -134,7 +134,7 @@ function printIndexHelp(log) {
|
|
|
134
134
|
}
|
|
135
135
|
function printShowHelp(log) {
|
|
136
136
|
log("Usage:");
|
|
137
|
-
log(" mdkg show <id-or-qid> [--ws <alias>] [--meta] [--json]");
|
|
137
|
+
log(" mdkg show <id-or-qid> [--ws <alias>] [--meta] [--json|--xml|--toon|--md]");
|
|
138
138
|
log("\nWhen to use:");
|
|
139
139
|
log(" Inspect one mdkg node exactly. Use `mdkg skill show <slug>` for skills.");
|
|
140
140
|
log("\nDefault behavior:");
|
|
@@ -144,7 +144,8 @@ function printShowHelp(log) {
|
|
|
144
144
|
function printListHelp(log) {
|
|
145
145
|
log("Usage:");
|
|
146
146
|
log(" mdkg list [--type <type>] [--status <status>] [--ws <alias>] [--epic <id>]");
|
|
147
|
-
log(" [--priority <n>] [--blocked] [--tags <tag,tag,...>] [--tags-mode any|all]
|
|
147
|
+
log(" [--priority <n>] [--blocked] [--tags <tag,tag,...>] [--tags-mode any|all]");
|
|
148
|
+
log(" [--json|--xml|--toon|--md]");
|
|
148
149
|
log("\nWhen to use:");
|
|
149
150
|
log(" List mdkg nodes. Use `mdkg skill list` for skills.");
|
|
150
151
|
printGlobalOptions(log);
|
|
@@ -152,7 +153,7 @@ function printListHelp(log) {
|
|
|
152
153
|
function printSearchHelp(log) {
|
|
153
154
|
log("Usage:");
|
|
154
155
|
log(' mdkg search "<query>" [--type <type>] [--status <status>] [--ws <alias>]');
|
|
155
|
-
log(" [--tags <tag,tag,...>] [--tags-mode any|all] [--json]");
|
|
156
|
+
log(" [--tags <tag,tag,...>] [--tags-mode any|all] [--json|--xml|--toon|--md]");
|
|
156
157
|
log("\nWhen to use:");
|
|
157
158
|
log(" Search mdkg nodes by metadata. Use `mdkg skill search` for skills.");
|
|
158
159
|
printGlobalOptions(log);
|
|
@@ -210,21 +211,21 @@ function printSkillHelp(log, subcommand) {
|
|
|
210
211
|
return;
|
|
211
212
|
case "list":
|
|
212
213
|
log("Usage:");
|
|
213
|
-
log(" mdkg skill list [--tags <tag,tag,...>] [--tags-mode any|all] [--json]");
|
|
214
|
+
log(" mdkg skill list [--tags <tag,tag,...>] [--tags-mode any|all] [--json|--xml|--toon|--md]");
|
|
214
215
|
log("\nWhen to use:");
|
|
215
216
|
log(" Discover skills directly, including stage-tagged orchestrator lookups.");
|
|
216
217
|
printGlobalOptions(log);
|
|
217
218
|
return;
|
|
218
219
|
case "show":
|
|
219
220
|
log("Usage:");
|
|
220
|
-
log(" mdkg skill show <slug> [--meta] [--json]");
|
|
221
|
+
log(" mdkg skill show <slug> [--meta] [--json|--xml|--toon|--md]");
|
|
221
222
|
log("\nWhen to use:");
|
|
222
223
|
log(" Inspect one skill body or metadata after discovery.");
|
|
223
224
|
printGlobalOptions(log);
|
|
224
225
|
return;
|
|
225
226
|
case "search":
|
|
226
227
|
log("Usage:");
|
|
227
|
-
log(' mdkg skill search "<query>" [--tags <tag,tag,...>] [--tags-mode any|all] [--json]');
|
|
228
|
+
log(' mdkg skill search "<query>" [--tags <tag,tag,...>] [--tags-mode any|all] [--json|--xml|--toon|--md]');
|
|
228
229
|
log("\nWhen to use:");
|
|
229
230
|
log(" Search skills by trigger text, tags, and stage conventions like `stage:plan`.");
|
|
230
231
|
printGlobalOptions(log);
|
|
@@ -244,9 +245,9 @@ function printSkillHelp(log, subcommand) {
|
|
|
244
245
|
default:
|
|
245
246
|
log("Usage:");
|
|
246
247
|
log(' mdkg skill new <slug> "<name>" --description "<description>" [options]');
|
|
247
|
-
log(" mdkg skill list [--tags <tag,tag,...>] [--tags-mode any|all] [--json]");
|
|
248
|
-
log(" mdkg skill show <slug> [--meta] [--json]");
|
|
249
|
-
log(' mdkg skill search "<query>" [--tags <tag,tag,...>] [--tags-mode any|all] [--json]');
|
|
248
|
+
log(" mdkg skill list [--tags <tag,tag,...>] [--tags-mode any|all] [--json|--xml|--toon|--md]");
|
|
249
|
+
log(" mdkg skill show <slug> [--meta] [--json|--xml|--toon|--md]");
|
|
250
|
+
log(' mdkg skill search "<query>" [--tags <tag,tag,...>] [--tags-mode any|all] [--json|--xml|--toon|--md]');
|
|
250
251
|
log(" mdkg skill validate [<slug>]");
|
|
251
252
|
log(" mdkg skill sync [--force]");
|
|
252
253
|
log("\nNotes:");
|
|
@@ -261,8 +262,8 @@ function printTaskHelp(log, subcommand) {
|
|
|
261
262
|
log("Usage:");
|
|
262
263
|
log(' mdkg task start <id-or-qid> [--ws <alias>] [--run-id <id>] [--note "<text>"]');
|
|
263
264
|
log("\nWhen to use:");
|
|
264
|
-
log(" Move a task, bug, or test into progress
|
|
265
|
-
log(" If events
|
|
265
|
+
log(" Move a task, bug, or test into progress as a structured state change.");
|
|
266
|
+
log(" If `events.jsonl` is missing, mdkg prints a short reminder about `mdkg event enable`.");
|
|
266
267
|
printGlobalOptions(log);
|
|
267
268
|
return;
|
|
268
269
|
case "update":
|
|
@@ -272,7 +273,7 @@ function printTaskHelp(log, subcommand) {
|
|
|
272
273
|
log(" [--add-skills <slug,...>] [--add-tags <tag,...>] [--add-blocked-by <id,...>]");
|
|
273
274
|
log(' [--clear-blocked-by] [--run-id <id>] [--note "<text>"]');
|
|
274
275
|
log("\nWhen to use:");
|
|
275
|
-
log(" Update task metadata and evidence
|
|
276
|
+
log(" Update structured task metadata and evidence while keeping body and narrative edits in markdown.");
|
|
276
277
|
printGlobalOptions(log);
|
|
277
278
|
return;
|
|
278
279
|
case "done":
|
|
@@ -299,9 +300,9 @@ function printEventHelp(log, subcommand) {
|
|
|
299
300
|
switch ((subcommand ?? "").toLowerCase()) {
|
|
300
301
|
case "enable":
|
|
301
302
|
log("Usage:");
|
|
302
|
-
log(" mdkg event enable [--ws <alias>]
|
|
303
|
+
log(" mdkg event enable [--ws <alias>]");
|
|
303
304
|
log("\nWhen to use:");
|
|
304
|
-
log(" Create the append-only JSONL event log for a workspace.");
|
|
305
|
+
log(" Create or ensure the append-only JSONL event log for a workspace.");
|
|
305
306
|
printGlobalOptions(log);
|
|
306
307
|
return;
|
|
307
308
|
case "append":
|
|
@@ -315,7 +316,7 @@ function printEventHelp(log, subcommand) {
|
|
|
315
316
|
return;
|
|
316
317
|
default:
|
|
317
318
|
log("Usage:");
|
|
318
|
-
log(" mdkg event enable [--ws <alias>]
|
|
319
|
+
log(" mdkg event enable [--ws <alias>]");
|
|
319
320
|
log(" mdkg event append --kind <kind> --status <ok|error|retry|skipped> --refs <id,...> [options]");
|
|
320
321
|
printGlobalOptions(log);
|
|
321
322
|
}
|
|
@@ -528,6 +529,25 @@ function parseTagsModeFlag(value) {
|
|
|
528
529
|
}
|
|
529
530
|
throw new errors_1.UsageError("--tags-mode must be any or all");
|
|
530
531
|
}
|
|
532
|
+
function parseQueryOutputFormat(parsed) {
|
|
533
|
+
const enabled = [];
|
|
534
|
+
if (parseBooleanFlag("--json", parsed.flags["--json"])) {
|
|
535
|
+
enabled.push("json");
|
|
536
|
+
}
|
|
537
|
+
if (parseBooleanFlag("--xml", parsed.flags["--xml"])) {
|
|
538
|
+
enabled.push("xml");
|
|
539
|
+
}
|
|
540
|
+
if (parseBooleanFlag("--toon", parsed.flags["--toon"])) {
|
|
541
|
+
enabled.push("toon");
|
|
542
|
+
}
|
|
543
|
+
if (parseBooleanFlag("--md", parsed.flags["--md"])) {
|
|
544
|
+
enabled.push("md");
|
|
545
|
+
}
|
|
546
|
+
if (enabled.length > 1) {
|
|
547
|
+
throw new errors_1.UsageError("choose at most one output flag: --json, --xml, --toon, or --md");
|
|
548
|
+
}
|
|
549
|
+
return enabled[0];
|
|
550
|
+
}
|
|
531
551
|
function handleCommandError(err, command, runtime) {
|
|
532
552
|
const message = err instanceof Error ? err.message : String(err);
|
|
533
553
|
if (err instanceof errors_1.UsageError) {
|
|
@@ -622,12 +642,12 @@ function runSkillSubcommand(parsed, root) {
|
|
|
622
642
|
const tagsMode = parseTagsModeFlag(parsed.flags["--tags-mode"]);
|
|
623
643
|
const noCache = parseBooleanFlag("--no-cache", parsed.flags["--no-cache"]);
|
|
624
644
|
const noReindex = parseBooleanFlag("--no-reindex", parsed.flags["--no-reindex"]);
|
|
625
|
-
const
|
|
645
|
+
const format = parseQueryOutputFormat(parsed);
|
|
626
646
|
(0, skill_1.runSkillListCommand)({
|
|
627
647
|
root,
|
|
628
648
|
tags,
|
|
629
649
|
tagsMode,
|
|
630
|
-
|
|
650
|
+
format,
|
|
631
651
|
noCache,
|
|
632
652
|
noReindex,
|
|
633
653
|
});
|
|
@@ -639,14 +659,14 @@ function runSkillSubcommand(parsed, root) {
|
|
|
639
659
|
throw new errors_1.UsageError("skill show requires <slug>");
|
|
640
660
|
}
|
|
641
661
|
const metaOnly = parseBooleanFlag("--meta", parsed.flags["--meta"]);
|
|
642
|
-
const
|
|
662
|
+
const format = parseQueryOutputFormat(parsed);
|
|
643
663
|
const noCache = parseBooleanFlag("--no-cache", parsed.flags["--no-cache"]);
|
|
644
664
|
const noReindex = parseBooleanFlag("--no-reindex", parsed.flags["--no-reindex"]);
|
|
645
665
|
(0, skill_1.runSkillShowCommand)({
|
|
646
666
|
root,
|
|
647
667
|
slug,
|
|
648
668
|
metaOnly,
|
|
649
|
-
|
|
669
|
+
format,
|
|
650
670
|
noCache,
|
|
651
671
|
noReindex,
|
|
652
672
|
});
|
|
@@ -659,7 +679,7 @@ function runSkillSubcommand(parsed, root) {
|
|
|
659
679
|
const query = parsed.positionals.slice(2).join(" ");
|
|
660
680
|
const tags = parseCsvFlag("--tags", parsed.flags["--tags"]);
|
|
661
681
|
const tagsMode = parseTagsModeFlag(parsed.flags["--tags-mode"]);
|
|
662
|
-
const
|
|
682
|
+
const format = parseQueryOutputFormat(parsed);
|
|
663
683
|
const noCache = parseBooleanFlag("--no-cache", parsed.flags["--no-cache"]);
|
|
664
684
|
const noReindex = parseBooleanFlag("--no-reindex", parsed.flags["--no-reindex"]);
|
|
665
685
|
(0, skill_1.runSkillSearchCommand)({
|
|
@@ -667,7 +687,7 @@ function runSkillSubcommand(parsed, root) {
|
|
|
667
687
|
query,
|
|
668
688
|
tags,
|
|
669
689
|
tagsMode,
|
|
670
|
-
|
|
690
|
+
format,
|
|
671
691
|
noCache,
|
|
672
692
|
noReindex,
|
|
673
693
|
});
|
|
@@ -779,8 +799,7 @@ function runEventSubcommand(parsed, root) {
|
|
|
779
799
|
throw new errors_1.UsageError("event enable does not accept positional arguments");
|
|
780
800
|
}
|
|
781
801
|
const ws = requireFlagValue("--ws", parsed.flags["--ws"]);
|
|
782
|
-
|
|
783
|
-
(0, event_1.runEventEnableCommand)({ root, ws, updateGitignore: !noUpdateGitignore });
|
|
802
|
+
(0, event_1.runEventEnableCommand)({ root, ws });
|
|
784
803
|
return 0;
|
|
785
804
|
}
|
|
786
805
|
case "append": {
|
|
@@ -931,7 +950,7 @@ function runCommand(parsed, root, runtime) {
|
|
|
931
950
|
}
|
|
932
951
|
const ws = requireFlagValue("--ws", parsed.flags["--ws"]);
|
|
933
952
|
const metaOnly = parseBooleanFlag("--meta", parsed.flags["--meta"]);
|
|
934
|
-
const
|
|
953
|
+
const format = parseQueryOutputFormat(parsed);
|
|
935
954
|
const noCache = parseBooleanFlag("--no-cache", parsed.flags["--no-cache"]);
|
|
936
955
|
const noReindex = parseBooleanFlag("--no-reindex", parsed.flags["--no-reindex"]);
|
|
937
956
|
(0, show_1.runShowCommand)({
|
|
@@ -939,7 +958,7 @@ function runCommand(parsed, root, runtime) {
|
|
|
939
958
|
id,
|
|
940
959
|
ws,
|
|
941
960
|
metaOnly,
|
|
942
|
-
|
|
961
|
+
format,
|
|
943
962
|
noCache,
|
|
944
963
|
noReindex,
|
|
945
964
|
});
|
|
@@ -957,7 +976,7 @@ function runCommand(parsed, root, runtime) {
|
|
|
957
976
|
const blocked = parseBooleanFlag("--blocked", parsed.flags["--blocked"]);
|
|
958
977
|
const tags = parseCsvFlag("--tags", parsed.flags["--tags"]);
|
|
959
978
|
const tagsMode = parseTagsModeFlag(parsed.flags["--tags-mode"]);
|
|
960
|
-
const
|
|
979
|
+
const format = parseQueryOutputFormat(parsed);
|
|
961
980
|
const noCache = parseBooleanFlag("--no-cache", parsed.flags["--no-cache"]);
|
|
962
981
|
const noReindex = parseBooleanFlag("--no-reindex", parsed.flags["--no-reindex"]);
|
|
963
982
|
(0, list_1.runListCommand)({
|
|
@@ -970,7 +989,7 @@ function runCommand(parsed, root, runtime) {
|
|
|
970
989
|
blocked,
|
|
971
990
|
tags,
|
|
972
991
|
tagsMode,
|
|
973
|
-
|
|
992
|
+
format,
|
|
974
993
|
noCache,
|
|
975
994
|
noReindex,
|
|
976
995
|
});
|
|
@@ -986,7 +1005,7 @@ function runCommand(parsed, root, runtime) {
|
|
|
986
1005
|
const status = requireFlagValue("--status", parsed.flags["--status"]);
|
|
987
1006
|
const tags = parseCsvFlag("--tags", parsed.flags["--tags"]);
|
|
988
1007
|
const tagsMode = parseTagsModeFlag(parsed.flags["--tags-mode"]);
|
|
989
|
-
const
|
|
1008
|
+
const format = parseQueryOutputFormat(parsed);
|
|
990
1009
|
const noCache = parseBooleanFlag("--no-cache", parsed.flags["--no-cache"]);
|
|
991
1010
|
const noReindex = parseBooleanFlag("--no-reindex", parsed.flags["--no-reindex"]);
|
|
992
1011
|
(0, search_1.runSearchCommand)({
|
|
@@ -997,7 +1016,7 @@ function runCommand(parsed, root, runtime) {
|
|
|
997
1016
|
status,
|
|
998
1017
|
tags,
|
|
999
1018
|
tagsMode,
|
|
1000
|
-
|
|
1019
|
+
format,
|
|
1001
1020
|
noCache,
|
|
1002
1021
|
noReindex,
|
|
1003
1022
|
});
|
package/dist/commands/event.js
CHANGED
|
@@ -7,8 +7,7 @@ const errors_1 = require("../util/errors");
|
|
|
7
7
|
function runEventEnableCommand(options) {
|
|
8
8
|
const result = (0, event_support_1.ensureEventsEnabled)(options);
|
|
9
9
|
const createdLabel = result.created ? "created" : "already present";
|
|
10
|
-
|
|
11
|
-
console.log(`event logging enabled: ${result.ws} (${createdLabel}; ${ignoreLabel})`);
|
|
10
|
+
console.log(`event logging enabled: ${result.ws} (${createdLabel})`);
|
|
12
11
|
}
|
|
13
12
|
function normalizeEventStatus(value) {
|
|
14
13
|
const normalized = value.trim().toLowerCase();
|
|
@@ -16,27 +16,6 @@ const fs_1 = __importDefault(require("fs"));
|
|
|
16
16
|
const path_1 = __importDefault(require("path"));
|
|
17
17
|
const config_1 = require("../core/config");
|
|
18
18
|
const errors_1 = require("../util/errors");
|
|
19
|
-
function appendIgnoreEntries(filePath, entries) {
|
|
20
|
-
const normalizedEntries = entries.map((entry) => entry.trim()).filter(Boolean);
|
|
21
|
-
if (normalizedEntries.length === 0) {
|
|
22
|
-
return false;
|
|
23
|
-
}
|
|
24
|
-
let existing = "";
|
|
25
|
-
if (fs_1.default.existsSync(filePath)) {
|
|
26
|
-
existing = fs_1.default.readFileSync(filePath, "utf8");
|
|
27
|
-
}
|
|
28
|
-
const existingLines = new Set(existing
|
|
29
|
-
.split(/\r?\n/)
|
|
30
|
-
.map((line) => line.trim())
|
|
31
|
-
.filter(Boolean));
|
|
32
|
-
const additions = normalizedEntries.filter((entry) => !existingLines.has(entry));
|
|
33
|
-
if (additions.length === 0) {
|
|
34
|
-
return false;
|
|
35
|
-
}
|
|
36
|
-
const next = existing.length === 0 ? `${additions.join("\n")}\n` : `${existing.replace(/\s*$/, "\n")}${additions.join("\n")}\n`;
|
|
37
|
-
fs_1.default.writeFileSync(filePath, next, "utf8");
|
|
38
|
-
return true;
|
|
39
|
-
}
|
|
40
19
|
function normalizeWorkspaceForEvents(config, raw) {
|
|
41
20
|
const normalized = (raw ?? "root").toLowerCase();
|
|
42
21
|
if (normalized === "all") {
|
|
@@ -70,20 +49,13 @@ function ensureEventsEnabled(options) {
|
|
|
70
49
|
const config = (0, config_1.loadConfig)(options.root);
|
|
71
50
|
const ws = normalizeWorkspaceForEvents(config, options.ws);
|
|
72
51
|
const eventsPath = resolveEventsPath(options.root, config, ws);
|
|
73
|
-
const updateGitignore = options.updateGitignore !== false;
|
|
74
52
|
let created = false;
|
|
75
53
|
if (!fs_1.default.existsSync(eventsPath)) {
|
|
76
54
|
fs_1.default.mkdirSync(path_1.default.dirname(eventsPath), { recursive: true });
|
|
77
55
|
fs_1.default.writeFileSync(eventsPath, "", "utf8");
|
|
78
56
|
created = true;
|
|
79
57
|
}
|
|
80
|
-
|
|
81
|
-
if (updateGitignore) {
|
|
82
|
-
gitignoreUpdated = appendIgnoreEntries(path_1.default.join(options.root, ".gitignore"), [
|
|
83
|
-
".mdkg/work/events/*.jsonl",
|
|
84
|
-
]);
|
|
85
|
-
}
|
|
86
|
-
return { ws, eventsPath, created, gitignoreUpdated };
|
|
58
|
+
return { ws, eventsPath, created };
|
|
87
59
|
}
|
|
88
60
|
function normalizeIdOrIdRef(value) {
|
|
89
61
|
return value.trim().toLowerCase();
|
|
@@ -131,7 +103,7 @@ function appendEvent(options) {
|
|
|
131
103
|
}
|
|
132
104
|
const eventsPath = resolveEventsPath(options.root, config, record.workspace);
|
|
133
105
|
if (!fs_1.default.existsSync(eventsPath)) {
|
|
134
|
-
throw new errors_1.NotFoundError(`
|
|
106
|
+
throw new errors_1.NotFoundError(`events.jsonl is missing for workspace ${record.workspace}; run \`mdkg event enable --ws ${record.workspace}\``);
|
|
135
107
|
}
|
|
136
108
|
fs_1.default.appendFileSync(eventsPath, `${JSON.stringify(record)}\n`, "utf8");
|
|
137
109
|
return record;
|
package/dist/commands/init.js
CHANGED
|
@@ -235,6 +235,7 @@ function runInitCommand(options) {
|
|
|
235
235
|
const seedAgentStart = path_1.default.join(seedRoot, "AGENT_START.md");
|
|
236
236
|
const seedCliMatrix = path_1.default.join(seedRoot, "CLI_COMMAND_MATRIX.md");
|
|
237
237
|
const seedReadme = path_1.default.join(seedRoot, "README.md");
|
|
238
|
+
const seedDefaultSkills = path_1.default.join(seedRoot, "skills", "default");
|
|
238
239
|
if (!fs_1.default.existsSync(seedConfig) || !fs_1.default.existsSync(seedCore) || !fs_1.default.existsSync(seedTemplates)) {
|
|
239
240
|
throw new errors_1.NotFoundError(`init assets not found at ${seedRoot} (try reinstalling mdkg)`);
|
|
240
241
|
}
|
|
@@ -256,6 +257,9 @@ function runInitCommand(options) {
|
|
|
256
257
|
if (!fs_1.default.existsSync(seedReadme)) {
|
|
257
258
|
throw new errors_1.NotFoundError(`init assets missing README.md at ${seedRoot}`);
|
|
258
259
|
}
|
|
260
|
+
if (options.agent && !fs_1.default.existsSync(seedDefaultSkills)) {
|
|
261
|
+
throw new errors_1.NotFoundError(`init assets missing default skills at ${seedRoot}`);
|
|
262
|
+
}
|
|
259
263
|
const mdkgDir = path_1.default.join(root, ".mdkg");
|
|
260
264
|
fs_1.default.mkdirSync(mdkgDir, { recursive: true });
|
|
261
265
|
fs_1.default.mkdirSync(path_1.default.join(mdkgDir, "work"), { recursive: true });
|
|
@@ -286,6 +290,7 @@ function runInitCommand(options) {
|
|
|
286
290
|
const eventsPath = path_1.default.join(eventsDir, "events.jsonl");
|
|
287
291
|
fs_1.default.mkdirSync(skillsDir, { recursive: true });
|
|
288
292
|
fs_1.default.mkdirSync(eventsDir, { recursive: true });
|
|
293
|
+
copySeedDir(seedDefaultSkills, skillsDir, force, stats);
|
|
289
294
|
writeFileIfMissing(soulPath, soulTemplate(today), force, stats);
|
|
290
295
|
writeFileIfMissing(humanPath, humanTemplate(today), force, stats);
|
|
291
296
|
writeFileIfMissing(registryPath, (0, skill_support_1.registryTemplate)(), force, stats);
|
|
@@ -296,6 +301,7 @@ function runInitCommand(options) {
|
|
|
296
301
|
ensureCorePins(coreListPath, [SOUL_PIN_ID, HUMAN_PIN_ID]);
|
|
297
302
|
(0, skill_mirror_1.scaffoldMirrorRoots)(root);
|
|
298
303
|
const config = (0, config_1.loadConfig)(root);
|
|
304
|
+
(0, skill_support_1.refreshSkillsRegistry)(root, config);
|
|
299
305
|
(0, skill_mirror_1.syncSkillMirrors)({ root, config, createRoots: true, force });
|
|
300
306
|
}
|
|
301
307
|
const noUpdateIgnores = Boolean(options.noUpdateIgnores);
|
|
@@ -305,7 +311,6 @@ function runInitCommand(options) {
|
|
|
305
311
|
appendIgnoreEntries(path_1.default.join(root, ".gitignore"), [
|
|
306
312
|
".mdkg/index/",
|
|
307
313
|
".mdkg/pack/",
|
|
308
|
-
".mdkg/work/events/*.jsonl",
|
|
309
314
|
]);
|
|
310
315
|
}
|
|
311
316
|
if (shouldUpdateNpmignore) {
|
package/dist/commands/list.js
CHANGED
|
@@ -53,13 +53,14 @@ function runListCommand(options) {
|
|
|
53
53
|
tagsMode: options.tagsMode,
|
|
54
54
|
});
|
|
55
55
|
const sorted = (0, sort_1.sortNodesByQid)(filtered);
|
|
56
|
-
|
|
57
|
-
|
|
56
|
+
const format = options.format ?? (options.json ? "json" : undefined);
|
|
57
|
+
if (format) {
|
|
58
|
+
(0, query_output_1.writeStructuredOutput)({
|
|
58
59
|
command: "list",
|
|
59
60
|
kind: "node",
|
|
60
61
|
count: sorted.length,
|
|
61
62
|
items: sorted.map(query_output_1.toNodeSummaryJson),
|
|
62
|
-
});
|
|
63
|
+
}, format);
|
|
63
64
|
return;
|
|
64
65
|
}
|
|
65
66
|
(0, query_output_1.writeCount)(sorted.length, sorted.length === 0 ? "no nodes matched current filters" : undefined);
|
|
@@ -5,6 +5,7 @@ exports.toNodeDetailJson = toNodeDetailJson;
|
|
|
5
5
|
exports.toSkillSummaryJson = toSkillSummaryJson;
|
|
6
6
|
exports.toSkillDetailJson = toSkillDetailJson;
|
|
7
7
|
exports.writeJson = writeJson;
|
|
8
|
+
exports.writeStructuredOutput = writeStructuredOutput;
|
|
8
9
|
exports.writeCount = writeCount;
|
|
9
10
|
function toNodeSummaryJson(node) {
|
|
10
11
|
return {
|
|
@@ -76,6 +77,113 @@ function toSkillDetailJson(skill, body) {
|
|
|
76
77
|
function writeJson(payload) {
|
|
77
78
|
console.log(JSON.stringify(payload, null, 2));
|
|
78
79
|
}
|
|
80
|
+
function escapeXml(value) {
|
|
81
|
+
return value
|
|
82
|
+
.replace(/&/g, "&")
|
|
83
|
+
.replace(/</g, "<")
|
|
84
|
+
.replace(/>/g, ">")
|
|
85
|
+
.replace(/"/g, """)
|
|
86
|
+
.replace(/'/g, "'");
|
|
87
|
+
}
|
|
88
|
+
function isPrimitive(value) {
|
|
89
|
+
return (value === null ||
|
|
90
|
+
typeof value === "string" ||
|
|
91
|
+
typeof value === "number" ||
|
|
92
|
+
typeof value === "boolean");
|
|
93
|
+
}
|
|
94
|
+
function objectToXml(tag, value, indent = "") {
|
|
95
|
+
if (value === undefined) {
|
|
96
|
+
return [];
|
|
97
|
+
}
|
|
98
|
+
if (Array.isArray(value)) {
|
|
99
|
+
const lines = [`${indent}<${tag}>`];
|
|
100
|
+
for (const item of value) {
|
|
101
|
+
lines.push(...objectToXml("item", item, `${indent} `));
|
|
102
|
+
}
|
|
103
|
+
lines.push(`${indent}</${tag}>`);
|
|
104
|
+
return lines;
|
|
105
|
+
}
|
|
106
|
+
if (isPrimitive(value)) {
|
|
107
|
+
return [`${indent}<${tag}>${escapeXml(value === null ? "" : String(value))}</${tag}>`];
|
|
108
|
+
}
|
|
109
|
+
const lines = [`${indent}<${tag}>`];
|
|
110
|
+
for (const [key, child] of Object.entries(value)) {
|
|
111
|
+
lines.push(...objectToXml(key, child, `${indent} `));
|
|
112
|
+
}
|
|
113
|
+
lines.push(`${indent}</${tag}>`);
|
|
114
|
+
return lines;
|
|
115
|
+
}
|
|
116
|
+
function formatMarkdownScalar(value) {
|
|
117
|
+
return value === null ? "null" : String(value);
|
|
118
|
+
}
|
|
119
|
+
function objectToMarkdown(value, lines, indent = "", key) {
|
|
120
|
+
if (value === undefined) {
|
|
121
|
+
return;
|
|
122
|
+
}
|
|
123
|
+
if (Array.isArray(value)) {
|
|
124
|
+
if (key) {
|
|
125
|
+
lines.push(`${indent}- ${key}:`);
|
|
126
|
+
}
|
|
127
|
+
const childIndent = key ? `${indent} ` : indent;
|
|
128
|
+
if (value.length === 0) {
|
|
129
|
+
lines.push(`${childIndent}- []`);
|
|
130
|
+
return;
|
|
131
|
+
}
|
|
132
|
+
for (const item of value) {
|
|
133
|
+
if (isPrimitive(item)) {
|
|
134
|
+
lines.push(`${childIndent}- ${formatMarkdownScalar(item)}`);
|
|
135
|
+
continue;
|
|
136
|
+
}
|
|
137
|
+
lines.push(`${childIndent}-`);
|
|
138
|
+
objectToMarkdown(item, lines, `${childIndent} `);
|
|
139
|
+
}
|
|
140
|
+
return;
|
|
141
|
+
}
|
|
142
|
+
if (isPrimitive(value)) {
|
|
143
|
+
if (!key) {
|
|
144
|
+
lines.push(`${indent}- ${formatMarkdownScalar(value)}`);
|
|
145
|
+
return;
|
|
146
|
+
}
|
|
147
|
+
lines.push(`${indent}- ${key}: ${formatMarkdownScalar(value)}`);
|
|
148
|
+
return;
|
|
149
|
+
}
|
|
150
|
+
if (key) {
|
|
151
|
+
lines.push(`${indent}- ${key}:`);
|
|
152
|
+
}
|
|
153
|
+
const childIndent = key ? `${indent} ` : indent;
|
|
154
|
+
for (const [childKey, childValue] of Object.entries(value)) {
|
|
155
|
+
objectToMarkdown(childValue, lines, childIndent, childKey);
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
function writeXml(payload) {
|
|
159
|
+
const lines = ['<?xml version="1.0" encoding="UTF-8"?>'];
|
|
160
|
+
lines.push(...objectToXml("response", payload));
|
|
161
|
+
console.log(lines.join("\n"));
|
|
162
|
+
}
|
|
163
|
+
function writeToon(payload) {
|
|
164
|
+
console.log(JSON.stringify(payload, null, 2));
|
|
165
|
+
}
|
|
166
|
+
function writeMarkdown(payload) {
|
|
167
|
+
const lines = ["# mdkg response"];
|
|
168
|
+
objectToMarkdown(payload, lines);
|
|
169
|
+
console.log(lines.join("\n"));
|
|
170
|
+
}
|
|
171
|
+
function writeStructuredOutput(payload, format) {
|
|
172
|
+
switch (format) {
|
|
173
|
+
case "json":
|
|
174
|
+
writeJson(payload);
|
|
175
|
+
return;
|
|
176
|
+
case "xml":
|
|
177
|
+
writeXml(payload);
|
|
178
|
+
return;
|
|
179
|
+
case "toon":
|
|
180
|
+
writeToon(payload);
|
|
181
|
+
return;
|
|
182
|
+
case "md":
|
|
183
|
+
writeMarkdown(payload);
|
|
184
|
+
return;
|
|
185
|
+
}
|
|
186
|
+
}
|
|
79
187
|
function writeCount(count, note) {
|
|
80
188
|
console.error(`count: ${count}`);
|
|
81
189
|
if (note) {
|
package/dist/commands/search.js
CHANGED
|
@@ -71,13 +71,14 @@ function runSearchCommand(options) {
|
|
|
71
71
|
tagsMode: options.tagsMode,
|
|
72
72
|
}).filter((node) => matchesQuery(node, terms));
|
|
73
73
|
const sorted = (0, sort_1.sortNodesByQid)(nodeResults);
|
|
74
|
-
|
|
75
|
-
|
|
74
|
+
const format = options.format ?? (options.json ? "json" : undefined);
|
|
75
|
+
if (format) {
|
|
76
|
+
(0, query_output_1.writeStructuredOutput)({
|
|
76
77
|
command: "search",
|
|
77
78
|
kind: "node",
|
|
78
79
|
count: sorted.length,
|
|
79
80
|
items: sorted.map(query_output_1.toNodeSummaryJson),
|
|
80
|
-
});
|
|
81
|
+
}, format);
|
|
81
82
|
return;
|
|
82
83
|
}
|
|
83
84
|
(0, query_output_1.writeCount)(sorted.length, sorted.length === 0 ? `no nodes matched query "${query}"` : undefined);
|
package/dist/commands/show.js
CHANGED
|
@@ -58,12 +58,13 @@ function runShowCommand(options) {
|
|
|
58
58
|
const content = fs_1.default.readFileSync(filePath, "utf8");
|
|
59
59
|
body = (0, frontmatter_1.parseFrontmatter)(content, filePath).body.trimEnd();
|
|
60
60
|
}
|
|
61
|
-
|
|
62
|
-
|
|
61
|
+
const format = options.format ?? (options.json ? "json" : undefined);
|
|
62
|
+
if (format) {
|
|
63
|
+
(0, query_output_1.writeStructuredOutput)({
|
|
63
64
|
command: "show",
|
|
64
65
|
kind: "node",
|
|
65
66
|
item: (0, query_output_1.toNodeDetailJson)(node, options.metaOnly ? undefined : body),
|
|
66
|
-
});
|
|
67
|
+
}, format);
|
|
67
68
|
return;
|
|
68
69
|
}
|
|
69
70
|
const lines = [];
|
package/dist/commands/skill.js
CHANGED
|
@@ -205,13 +205,14 @@ function runSkillListCommand(options) {
|
|
|
205
205
|
console.error("warning: skills index is stale; run mdkg index to refresh");
|
|
206
206
|
}
|
|
207
207
|
const skills = filterSkills(Object.values(index.skills), options.tags, options.tagsMode ?? "any").sort((a, b) => a.qid.localeCompare(b.qid));
|
|
208
|
-
|
|
209
|
-
|
|
208
|
+
const format = options.format ?? (options.json ? "json" : undefined);
|
|
209
|
+
if (format) {
|
|
210
|
+
(0, query_output_1.writeStructuredOutput)({
|
|
210
211
|
command: "list",
|
|
211
212
|
kind: "skill",
|
|
212
213
|
count: skills.length,
|
|
213
214
|
items: skills.map(query_output_1.toSkillSummaryJson),
|
|
214
|
-
});
|
|
215
|
+
}, format);
|
|
215
216
|
return;
|
|
216
217
|
}
|
|
217
218
|
(0, query_output_1.writeCount)(skills.length, skills.length === 0 ? "no skills matched current filters" : undefined);
|
|
@@ -243,12 +244,13 @@ function runSkillShowCommand(options) {
|
|
|
243
244
|
}
|
|
244
245
|
body = fs_1.default.readFileSync(skillPath, "utf8").trimEnd();
|
|
245
246
|
}
|
|
246
|
-
|
|
247
|
-
|
|
247
|
+
const format = options.format ?? (options.json ? "json" : undefined);
|
|
248
|
+
if (format) {
|
|
249
|
+
(0, query_output_1.writeStructuredOutput)({
|
|
248
250
|
command: "show",
|
|
249
251
|
kind: "skill",
|
|
250
252
|
item: (0, query_output_1.toSkillDetailJson)(skill, options.metaOnly ? undefined : body),
|
|
251
|
-
});
|
|
253
|
+
}, format);
|
|
252
254
|
return;
|
|
253
255
|
}
|
|
254
256
|
if (options.metaOnly) {
|
|
@@ -307,13 +309,14 @@ function runSkillSearchCommand(options) {
|
|
|
307
309
|
const skills = filterSkills(Object.values(index.skills), options.tags, options.tagsMode ?? "any")
|
|
308
310
|
.filter((skill) => matchesSkillQuery(skill, terms))
|
|
309
311
|
.sort((a, b) => a.qid.localeCompare(b.qid));
|
|
310
|
-
|
|
311
|
-
|
|
312
|
+
const format = options.format ?? (options.json ? "json" : undefined);
|
|
313
|
+
if (format) {
|
|
314
|
+
(0, query_output_1.writeStructuredOutput)({
|
|
312
315
|
command: "search",
|
|
313
316
|
kind: "skill",
|
|
314
317
|
count: skills.length,
|
|
315
318
|
items: skills.map(query_output_1.toSkillSummaryJson),
|
|
316
|
-
});
|
|
319
|
+
}, format);
|
|
317
320
|
return;
|
|
318
321
|
}
|
|
319
322
|
(0, query_output_1.writeCount)(skills.length, skills.length === 0 ? `no skills matched query "${query}"` : undefined);
|
|
@@ -110,29 +110,62 @@ function loadCanonicalSources(root, config) {
|
|
|
110
110
|
};
|
|
111
111
|
});
|
|
112
112
|
}
|
|
113
|
-
function
|
|
113
|
+
function writeFileIfChanged(srcPath, destPath) {
|
|
114
|
+
const next = fs_1.default.readFileSync(srcPath);
|
|
115
|
+
if (fs_1.default.existsSync(destPath) && fs_1.default.statSync(destPath).isFile()) {
|
|
116
|
+
const current = fs_1.default.readFileSync(destPath);
|
|
117
|
+
if (current.equals(next)) {
|
|
118
|
+
return;
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
fs_1.default.mkdirSync(path_1.default.dirname(destPath), { recursive: true });
|
|
122
|
+
fs_1.default.writeFileSync(destPath, next);
|
|
123
|
+
}
|
|
124
|
+
function syncDir(srcDir, destDir) {
|
|
114
125
|
fs_1.default.mkdirSync(destDir, { recursive: true });
|
|
115
|
-
const
|
|
116
|
-
|
|
126
|
+
const sourceEntries = fs_1.default.readdirSync(srcDir, { withFileTypes: true });
|
|
127
|
+
const sourceNames = new Set(sourceEntries.map((entry) => entry.name));
|
|
128
|
+
if (fs_1.default.existsSync(destDir)) {
|
|
129
|
+
for (const existing of fs_1.default.readdirSync(destDir)) {
|
|
130
|
+
if (!sourceNames.has(existing)) {
|
|
131
|
+
fs_1.default.rmSync(path_1.default.join(destDir, existing), { recursive: true, force: true });
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
for (const entry of sourceEntries) {
|
|
117
136
|
const srcPath = path_1.default.join(srcDir, entry.name);
|
|
118
137
|
const destPath = path_1.default.join(destDir, entry.name);
|
|
119
138
|
if (entry.isDirectory()) {
|
|
120
|
-
|
|
139
|
+
syncDir(srcPath, destPath);
|
|
121
140
|
}
|
|
122
141
|
else if (entry.isFile()) {
|
|
123
|
-
|
|
124
|
-
fs_1.default.copyFileSync(srcPath, destPath);
|
|
142
|
+
writeFileIfChanged(srcPath, destPath);
|
|
125
143
|
}
|
|
126
144
|
}
|
|
127
145
|
}
|
|
128
146
|
function materializeSkillMirror(source, destDir) {
|
|
129
|
-
fs_1.default.rmSync(destDir, { recursive: true, force: true });
|
|
130
147
|
fs_1.default.mkdirSync(destDir, { recursive: true });
|
|
131
|
-
|
|
148
|
+
const expectedRootEntries = new Set(["SKILL.md"]);
|
|
149
|
+
for (const entry of ["references", "assets", "scripts"]) {
|
|
150
|
+
const srcPath = path_1.default.join(source.sourceDir, entry);
|
|
151
|
+
if (fs_1.default.existsSync(srcPath) && fs_1.default.statSync(srcPath).isDirectory()) {
|
|
152
|
+
expectedRootEntries.add(entry);
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
for (const existing of fs_1.default.readdirSync(destDir)) {
|
|
156
|
+
if (!expectedRootEntries.has(existing)) {
|
|
157
|
+
fs_1.default.rmSync(path_1.default.join(destDir, existing), { recursive: true, force: true });
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
writeFileIfChanged(source.docPath, path_1.default.join(destDir, "SKILL.md"));
|
|
132
161
|
for (const entry of ["references", "assets", "scripts"]) {
|
|
133
162
|
const srcPath = path_1.default.join(source.sourceDir, entry);
|
|
163
|
+
const destPath = path_1.default.join(destDir, entry);
|
|
134
164
|
if (fs_1.default.existsSync(srcPath) && fs_1.default.statSync(srcPath).isDirectory()) {
|
|
135
|
-
|
|
165
|
+
syncDir(srcPath, destPath);
|
|
166
|
+
}
|
|
167
|
+
else if (fs_1.default.existsSync(destPath)) {
|
|
168
|
+
fs_1.default.rmSync(destPath, { recursive: true, force: true });
|
|
136
169
|
}
|
|
137
170
|
}
|
|
138
171
|
}
|
package/dist/commands/task.js
CHANGED
|
@@ -173,7 +173,7 @@ function maybeWarnEventsDisabled(root, config, ws) {
|
|
|
173
173
|
if ((0, event_support_1.isEventLoggingEnabled)(root, config, ws)) {
|
|
174
174
|
return;
|
|
175
175
|
}
|
|
176
|
-
console.error(`note:
|
|
176
|
+
console.error(`note: events.jsonl is missing for workspace ${ws}; run mdkg event enable --ws ${ws} to restore JSONL provenance`);
|
|
177
177
|
}
|
|
178
178
|
function runTaskStartCommand(options) {
|
|
179
179
|
const loaded = loadMutableTaskNode(options.root, options.id, options.ws);
|
package/dist/init/AGENTS.md
CHANGED
|
@@ -6,3 +6,4 @@ Codex/OpenAI conventions for this repo:
|
|
|
6
6
|
- use `AGENT_START.md` as the startup contract
|
|
7
7
|
- use `.agents/skills/` for product-facing mirrored skills when present
|
|
8
8
|
- use `mdkg skill ...` as the canonical skill command family
|
|
9
|
+
- use `mdkg task ...` for structured task fields and markdown edits for narrative/body changes
|
package/dist/init/AGENT_START.md
CHANGED
|
@@ -40,7 +40,14 @@ Conventions:
|
|
|
40
40
|
- `.agents/skills/` and `.claude/skills/` mirror canonical skills from `.mdkg/skills/` when agent bootstrap is enabled.
|
|
41
41
|
- mdkg does not execute skill scripts; runtimes decide when and whether to do that.
|
|
42
42
|
- Prefer packs over ad-hoc file lists.
|
|
43
|
-
- Prefer task/event commands
|
|
43
|
+
- Prefer task/event commands for structured work-state changes and use markdown edits for narrative/body updates.
|
|
44
44
|
- Use `mdkg task done <id> --checkpoint "<title>"` for milestone compression, not every routine task completion.
|
|
45
|
-
- Prefer checkpoints for feat/epic closeout summaries; parent status edits remain manual
|
|
46
|
-
- If events
|
|
45
|
+
- Prefer checkpoints for feat/epic closeout summaries; parent status edits remain manual.
|
|
46
|
+
- If `events.jsonl` is missing, `mdkg task start` and `mdkg task done` will remind you how to recreate it.
|
|
47
|
+
- Files outside mdkg-managed skill mirrors, such as local tool permission files, are not managed by mdkg unless documented explicitly.
|
|
48
|
+
|
|
49
|
+
Structured discovery/show exports:
|
|
50
|
+
- `--json`
|
|
51
|
+
- `--xml`
|
|
52
|
+
- `--toon`
|
|
53
|
+
- `--md`
|
|
@@ -21,9 +21,16 @@ Agent bootstrap:
|
|
|
21
21
|
- `mdkg init --llm`
|
|
22
22
|
- `mdkg init --agent`
|
|
23
23
|
- `mdkg init --llm --agent`
|
|
24
|
+
- published bootstrap config is root-only by default
|
|
24
25
|
|
|
25
26
|
Skill discovery:
|
|
26
27
|
- `mdkg skill list --tags stage:plan --json`
|
|
27
28
|
- `mdkg skill search "<query>" --json`
|
|
28
29
|
- `mdkg skill show <slug> --json`
|
|
29
30
|
- `mdkg skill sync`
|
|
31
|
+
|
|
32
|
+
Discovery/show export flags:
|
|
33
|
+
- `--json`
|
|
34
|
+
- `--xml`
|
|
35
|
+
- `--toon`
|
|
36
|
+
- `--md`
|
package/dist/init/config.json
CHANGED
|
@@ -52,16 +52,6 @@
|
|
|
52
52
|
"path": ".",
|
|
53
53
|
"enabled": true,
|
|
54
54
|
"mdkg_dir": ".mdkg"
|
|
55
|
-
},
|
|
56
|
-
"polish": {
|
|
57
|
-
"path": "polish",
|
|
58
|
-
"enabled": true,
|
|
59
|
-
"mdkg_dir": ".mdkg"
|
|
60
|
-
},
|
|
61
|
-
"smoke": {
|
|
62
|
-
"path": "smoke",
|
|
63
|
-
"enabled": true,
|
|
64
|
-
"mdkg_dir": ".mdkg"
|
|
65
55
|
}
|
|
66
56
|
}
|
|
67
|
-
}
|
|
57
|
+
}
|
|
@@ -88,7 +88,7 @@ If a user provides an unqualified ID and it is ambiguous globally:
|
|
|
88
88
|
- Commands should be script-friendly:
|
|
89
89
|
- concise outputs for single items
|
|
90
90
|
- predictable formatting
|
|
91
|
-
- `--json` output for supported discovery/show commands
|
|
91
|
+
- `--json`, `--xml`, `--toon`, and `--md` output for supported discovery/show commands
|
|
92
92
|
- when printing node summaries (e.g., `show`/list results), outputs SHOULD surface key searchable frontmatter fields such as `links` and `artifacts`
|
|
93
93
|
|
|
94
94
|
## Command set (v1 target)
|
|
@@ -107,6 +107,10 @@ If a user provides an unqualified ID and it is ambiguous globally:
|
|
|
107
107
|
- `--agent` adds strict-node bootstrap docs and scaffolding:
|
|
108
108
|
- `.mdkg/core/SOUL.md` (`id: rule-soul`)
|
|
109
109
|
- `.mdkg/core/HUMAN.md` (`id: rule-human`)
|
|
110
|
+
- seeded canonical skills:
|
|
111
|
+
- `.mdkg/skills/select-work-and-ground-context/SKILL.md`
|
|
112
|
+
- `.mdkg/skills/build-pack-and-execute-task/SKILL.md`
|
|
113
|
+
- `.mdkg/skills/verify-close-and-checkpoint/SKILL.md`
|
|
110
114
|
- `.mdkg/skills/registry.md`
|
|
111
115
|
- `.mdkg/work/events/events.jsonl`
|
|
112
116
|
- `.agents/skills/`
|
|
@@ -160,18 +164,19 @@ Common flags:
|
|
|
160
164
|
- `--template <set>` (default from config)
|
|
161
165
|
|
|
162
166
|
### Read/search
|
|
163
|
-
- `mdkg show <id-or-qid> [--meta] [--json]`
|
|
167
|
+
- `mdkg show <id-or-qid> [--meta] [--json|--xml|--toon|--md]`
|
|
164
168
|
- default behavior shows the full node body
|
|
165
169
|
- `--meta` is the compact card-only view
|
|
166
|
-
- `mdkg search "<query>" [--type <type>] [--status <status>] [--ws <alias>] [--tags <tag,tag,...>] [--tags-mode any|all] [--json]`
|
|
170
|
+
- `mdkg search "<query>" [--type <type>] [--status <status>] [--ws <alias>] [--tags <tag,tag,...>] [--tags-mode any|all] [--json|--xml|--toon|--md]`
|
|
167
171
|
- search SHOULD match on IDs, titles, tags, path tokens, and searchable frontmatter lists (`links`, `artifacts`, `refs`, `aliases`)
|
|
168
|
-
- `mdkg list [--type <type>] [--status <status>] [--ws <alias>] [--epic <id>] [--blocked] [--priority <n>] [--tags <tag,tag,...>] [--tags-mode any|all] [--json]`
|
|
172
|
+
- `mdkg list [--type <type>] [--status <status>] [--ws <alias>] [--epic <id>] [--blocked] [--priority <n>] [--tags <tag,tag,...>] [--tags-mode any|all] [--json|--xml|--toon|--md]`
|
|
169
173
|
- skills are first-class under `mdkg skill ...` only:
|
|
170
|
-
- `mdkg skill list [--tags <tag,tag,...>] [--tags-mode any|all] [--json]`
|
|
171
|
-
- `mdkg skill show <slug> [--meta] [--json]`
|
|
172
|
-
- `mdkg skill search "<query>" [--tags <tag,tag,...>] [--tags-mode any|all] [--json]`
|
|
174
|
+
- `mdkg skill list [--tags <tag,tag,...>] [--tags-mode any|all] [--json|--xml|--toon|--md]`
|
|
175
|
+
- `mdkg skill show <slug> [--meta] [--json|--xml|--toon|--md]`
|
|
176
|
+
- `mdkg skill search "<query>" [--tags <tag,tag,...>] [--tags-mode any|all] [--json|--xml|--toon|--md]`
|
|
173
177
|
- `mdkg skill validate [<slug>]`
|
|
174
178
|
- `mdkg skill sync [--force]`
|
|
179
|
+
- discovery/show output flags are mutually exclusive; text mode remains the default when none are supplied
|
|
175
180
|
|
|
176
181
|
### Task lifecycle mutation
|
|
177
182
|
- `mdkg task start <id-or-qid> [--ws <alias>] [--run-id <id>] [--note "<text>"]`
|
|
@@ -219,9 +224,9 @@ Common flags:
|
|
|
219
224
|
- designed as a phase summary / compression node
|
|
220
225
|
|
|
221
226
|
### Events
|
|
222
|
-
- `mdkg event enable [--ws <alias>]
|
|
227
|
+
- `mdkg event enable [--ws <alias>]`
|
|
223
228
|
- creates `.mdkg/work/events/events.jsonl` if missing
|
|
224
|
-
-
|
|
229
|
+
- leaves `.gitignore` unchanged
|
|
225
230
|
- `mdkg event append --kind <kind> --status <ok|error|retry|skipped> --refs <id,...> [...]`
|
|
226
231
|
- appends one JSONL provenance record
|
|
227
232
|
- automatic command-level events append only when event logging is enabled for the target workspace
|
|
@@ -36,7 +36,6 @@ Recommended `.gitignore` entries:
|
|
|
36
36
|
- `.mdkg/index/`
|
|
37
37
|
- `.mdkg/index/**`
|
|
38
38
|
- `.mdkg/pack/`
|
|
39
|
-
- `.mdkg/work/events/*.jsonl` (when episodic logging is enabled)
|
|
40
39
|
|
|
41
40
|
## npm publish safety (required)
|
|
42
41
|
|
|
@@ -70,7 +69,7 @@ For application builds:
|
|
|
70
69
|
|
|
71
70
|
`mdkg init` updates ignore files by default for safety:
|
|
72
71
|
|
|
73
|
-
- `.gitignore` appends `.mdkg/index/`, `.mdkg/pack
|
|
72
|
+
- `.gitignore` appends `.mdkg/index/`, `.mdkg/pack/`
|
|
74
73
|
- `.npmignore` appends `.mdkg/`, `.mdkg/index/`, `.mdkg/pack/`
|
|
75
74
|
- `--no-update-ignores` disables these default writes
|
|
76
75
|
|
|
@@ -97,7 +96,7 @@ Workspace-local `.mdkg/` directories (near code) should follow the same rules:
|
|
|
97
96
|
## Summary checklist
|
|
98
97
|
|
|
99
98
|
- ✅ `.mdkg/index/` ignored
|
|
100
|
-
- ✅
|
|
99
|
+
- ✅ event logs are committed by default unless a repo chooses to ignore them manually
|
|
101
100
|
- ✅ npm publishes only `dist/`, `README.md`, `LICENSE`
|
|
102
101
|
- ✅ optional `.npmignore` excludes `.mdkg/`
|
|
103
102
|
- ✅ `.dockerignore` excludes `.mdkg/` when applicable
|
package/dist/init/llms.txt
CHANGED
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: build-pack-and-execute-task
|
|
3
|
+
description: Build a deterministic mdkg pack for the active work item and use it as the execution handoff when coding or delegating to another AI agent.
|
|
4
|
+
tags: [stage:execute, writer:patch-only, mdkg, pack-first, context]
|
|
5
|
+
version: 0.1.0
|
|
6
|
+
authors: [mdkg]
|
|
7
|
+
links: [README.md, PACK_EXAMPLES.md, llms.txt]
|
|
8
|
+
---
|
|
9
|
+
|
|
10
|
+
# Goal
|
|
11
|
+
|
|
12
|
+
Use `mdkg pack <id>` as the default execution context instead of ad-hoc file gathering.
|
|
13
|
+
|
|
14
|
+
## When To Use
|
|
15
|
+
|
|
16
|
+
- Before coding
|
|
17
|
+
- Before handing work to another AI agent
|
|
18
|
+
- Before review when precise linked context matters
|
|
19
|
+
|
|
20
|
+
## Inputs
|
|
21
|
+
|
|
22
|
+
- Selected node id
|
|
23
|
+
- Optional profile choice
|
|
24
|
+
- Optional skills inclusion mode
|
|
25
|
+
|
|
26
|
+
## Steps
|
|
27
|
+
|
|
28
|
+
1. Start with `mdkg pack <id>`.
|
|
29
|
+
2. For a preview, use `mdkg pack <id> --profile concise --dry-run --stats`.
|
|
30
|
+
3. Use `--verbose` only when pinned core docs must be included in the pack body.
|
|
31
|
+
4. Use `--skills auto` when the work item already references the right skills.
|
|
32
|
+
5. Use `--skills-depth full` only for active execution, not early discovery.
|
|
33
|
+
6. Discover skills by metadata first; load full skill bodies only for the selected execution procedures.
|
|
34
|
+
7. Hand the pack, not a loose file list, to the next coding step or agent.
|
|
35
|
+
8. Keep this stage patch-only: subagents and tools may produce patches, test output, and evidence, but not direct mdkg state writes or commits.
|
|
36
|
+
9. If execution reveals new artifacts or blockers, hand them to the orchestrator stage for `mdkg task update ...` as structured field updates; keep narrative summaries in markdown.
|
|
37
|
+
|
|
38
|
+
## Outputs
|
|
39
|
+
|
|
40
|
+
- Deterministic pack file or dry-run selection report
|
|
41
|
+
- Stable context bundle for execution or review
|
|
42
|
+
- Patch bundles, test output, or evidence artifacts ready for orchestrator review
|
|
43
|
+
|
|
44
|
+
## Safety
|
|
45
|
+
|
|
46
|
+
- Prefer smaller packs first; expand only when the task requires it.
|
|
47
|
+
- Keep pinned rules ahead of opportunistic context.
|
|
48
|
+
- Do not treat raw event logs as primary execution context.
|
|
49
|
+
- Do not mutate task status, create checkpoints, or commit from this stage.
|
|
50
|
+
- mdkg indexes and discovers skills, but does not execute skill scripts.
|
|
51
|
+
- If event logging is enabled, rely on later task/checkpoint commands to append baseline events instead of writing ad-hoc log entries here.
|
|
52
|
+
|
|
53
|
+
## Failure Handling
|
|
54
|
+
|
|
55
|
+
- If the pack is too broad, reduce profile or skill depth before continuing.
|
|
56
|
+
- If the required procedure is unclear, return to metadata discovery instead of loading every skill body.
|
|
57
|
+
- If execution requires a durable memory update, hand control back to the orchestrator stage instead of writing directly.
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: select-work-and-ground-context
|
|
3
|
+
description: Select the right mdkg work item and ground execution before coding when the active task or context is still being established.
|
|
4
|
+
tags: [stage:plan, writer:read-only, mdkg, onboarding, context]
|
|
5
|
+
version: 0.1.0
|
|
6
|
+
authors: [mdkg]
|
|
7
|
+
links: [AGENT_START.md, README.md, CLI_COMMAND_MATRIX.md]
|
|
8
|
+
---
|
|
9
|
+
|
|
10
|
+
# Goal
|
|
11
|
+
|
|
12
|
+
Choose the correct work item and load the smallest deterministic context needed to act.
|
|
13
|
+
|
|
14
|
+
## When To Use
|
|
15
|
+
|
|
16
|
+
- At the start of a work session
|
|
17
|
+
- When the active task is unclear
|
|
18
|
+
- Before generating a pack or making code changes
|
|
19
|
+
|
|
20
|
+
## Inputs
|
|
21
|
+
|
|
22
|
+
- Current repo root
|
|
23
|
+
- Optional task or epic id
|
|
24
|
+
- Optional user goal in plain language
|
|
25
|
+
|
|
26
|
+
## Steps
|
|
27
|
+
|
|
28
|
+
1. If a task id is already known, inspect it with `mdkg show <id>`.
|
|
29
|
+
2. If the task is not known, read `AGENT_START.md` and use `mdkg next` or `mdkg search "<query>"` to narrow candidates.
|
|
30
|
+
3. Use `mdkg show <id> --meta` when you only need the card and link metadata.
|
|
31
|
+
4. Confirm the selected node has the right constraints, related design docs, and current status.
|
|
32
|
+
5. If the task is ambiguous, resolve that before building a pack.
|
|
33
|
+
6. If the chosen task is ready to be claimed, hand off to `mdkg task start <id>` in the writer stage for the structured status change.
|
|
34
|
+
7. If resuming closeout work for a feat or epic, inspect the latest relevant checkpoint before deciding what remains open.
|
|
35
|
+
8. Treat this stage as read-only: inspect and decide, but do not mutate mdkg state or commit.
|
|
36
|
+
|
|
37
|
+
## Outputs
|
|
38
|
+
|
|
39
|
+
- One selected node id
|
|
40
|
+
- Clear understanding of the active task, related docs, and current state
|
|
41
|
+
- No durable mdkg writes or commits from this stage
|
|
42
|
+
|
|
43
|
+
## Safety
|
|
44
|
+
|
|
45
|
+
- Do not start coding from chat memory alone.
|
|
46
|
+
- Prefer explicit rules, EDDs, DECs, and task nodes over informal notes.
|
|
47
|
+
- If multiple tasks appear valid, stop and choose deliberately instead of guessing.
|
|
48
|
+
- If writer ownership or policy boundaries are unclear, stop and resolve them before execution.
|
|
49
|
+
- mdkg indexes and discovers skills, but does not execute skill scripts.
|
|
50
|
+
- Event logging is committed by default in `init --agent` repos; use `mdkg event enable` only if `events.jsonl` is missing.
|
|
51
|
+
|
|
52
|
+
## Failure Handling
|
|
53
|
+
|
|
54
|
+
- If no clear work item exists, stop and ask for clarification instead of guessing.
|
|
55
|
+
- If the selected task conflicts with current status or linked design docs, resolve the conflict before moving to pack generation.
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: verify-close-and-checkpoint
|
|
3
|
+
description: Verify code and mdkg state, attach evidence, and close work cleanly when the single-writer AI agent or human orchestrator is ready to perform durable writes.
|
|
4
|
+
tags: [stage:review, writer:orchestrator, mdkg, validation, release]
|
|
5
|
+
version: 0.1.0
|
|
6
|
+
authors: [mdkg]
|
|
7
|
+
links: [README.md, AGENT_PROMPT_SNIPPET.md]
|
|
8
|
+
---
|
|
9
|
+
|
|
10
|
+
# Goal
|
|
11
|
+
|
|
12
|
+
Finish work with evidence, validation, and minimal memory drift.
|
|
13
|
+
|
|
14
|
+
## When To Use
|
|
15
|
+
|
|
16
|
+
- After implementation
|
|
17
|
+
- Before commit
|
|
18
|
+
- Before marking a task done
|
|
19
|
+
- Before creating a checkpoint
|
|
20
|
+
|
|
21
|
+
## Inputs
|
|
22
|
+
|
|
23
|
+
- Active task id
|
|
24
|
+
- Test or build outputs
|
|
25
|
+
- Any new artifact references
|
|
26
|
+
|
|
27
|
+
## Steps
|
|
28
|
+
|
|
29
|
+
1. Run the relevant technical gates for the changed surface.
|
|
30
|
+
2. Run `mdkg validate` before closing the task.
|
|
31
|
+
3. Use `mdkg task update <id> ...` for additive evidence and structured metadata changes; keep narrative/body edits in markdown.
|
|
32
|
+
4. Use `mdkg task done <id> --checkpoint "<title>"` when the task should close with milestone compression.
|
|
33
|
+
5. Batch durable mdkg writes at one boundary: task status, artifact refs, optional checkpoint, and commit.
|
|
34
|
+
6. Mark tasks done only after evidence exists.
|
|
35
|
+
7. Create a checkpoint only for milestone-level transitions, not every small step.
|
|
36
|
+
8. For feat or epic closeout, prefer a checkpoint body as the durable narrative summary of what changed and what is next.
|
|
37
|
+
9. Use feat closeout scope as direct children with `parent: <feat-id>` and epic closeout scope as descendant work with `epic: <epic-id>`.
|
|
38
|
+
10. Parent status edits remain manual; do not invent a hidden parent-closeout workflow.
|
|
39
|
+
11. If the latest checkpoint is relevant, use it as durable recall; treat raw events as provenance/debugging, not primary execution context.
|
|
40
|
+
12. If `events.jsonl` is missing, recreate it with `mdkg event enable` before expecting automatic JSONL provenance.
|
|
41
|
+
|
|
42
|
+
## Outputs
|
|
43
|
+
|
|
44
|
+
- Verified mdkg graph state
|
|
45
|
+
- Attached evidence and artifact refs
|
|
46
|
+
- Task ready for review, done, or checkpointing
|
|
47
|
+
- One durable writer action at the selected run or milestone boundary
|
|
48
|
+
|
|
49
|
+
## Safety
|
|
50
|
+
|
|
51
|
+
- Do not mark work done without validation.
|
|
52
|
+
- Do not create checkpoint spam.
|
|
53
|
+
- Keep commits event-driven and single-writer when agents are involved.
|
|
54
|
+
- Only the orchestrator performs durable mdkg writes or commit/push actions.
|
|
55
|
+
- Never commit on every tool call.
|
|
56
|
+
- mdkg indexes and discovers skills, but does not execute skill scripts.
|
|
57
|
+
|
|
58
|
+
## Failure Handling
|
|
59
|
+
|
|
60
|
+
- If validation fails, stop and return the task to active work instead of closing it.
|
|
61
|
+
- If artifact or evidence refs are missing, attach them before status changes or checkpoint creation.
|
|
62
|
+
- If writer ownership is unclear, stop and resolve it before any durable mdkg update or commit.
|
package/dist/util/argparse.js
CHANGED
|
@@ -79,10 +79,12 @@ const BOOLEAN_FLAGS = new Set([
|
|
|
79
79
|
"--version",
|
|
80
80
|
"--dry-run",
|
|
81
81
|
"--json",
|
|
82
|
+
"--xml",
|
|
83
|
+
"--toon",
|
|
84
|
+
"--md",
|
|
82
85
|
"--list-profiles",
|
|
83
86
|
"--with-scripts",
|
|
84
87
|
"--clear-blocked-by",
|
|
85
|
-
"--no-update-gitignore",
|
|
86
88
|
]);
|
|
87
89
|
const FLAG_ALIASES = {
|
|
88
90
|
"--o": "--out",
|