@warpgogol/forge 0.27.0 → 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (104) hide show
  1. package/AGENTS.md +17 -0
  2. package/README.md +4 -4
  3. package/README.uk.md +4 -4
  4. package/dist/bin/cli.js +1 -0
  5. package/dist/bin/cli.js.map +1 -1
  6. package/dist/os/core/core.module.d.ts.map +1 -1
  7. package/dist/os/core/core.module.js +34 -0
  8. package/dist/os/core/core.module.js.map +1 -1
  9. package/dist/os/mission/handlers/archive.d.ts.map +1 -1
  10. package/dist/os/mission/handlers/archive.js +77 -5
  11. package/dist/os/mission/handlers/archive.js.map +1 -1
  12. package/dist/os/notes/index.d.ts +2 -0
  13. package/dist/os/notes/index.d.ts.map +1 -0
  14. package/dist/os/notes/index.js +10 -0
  15. package/dist/os/notes/index.js.map +1 -0
  16. package/dist/os/notes/notes.module.d.ts +3 -0
  17. package/dist/os/notes/notes.module.d.ts.map +1 -0
  18. package/dist/os/notes/notes.module.js +83 -0
  19. package/dist/os/notes/notes.module.js.map +1 -0
  20. package/dist/os/program/discovery.d.ts +61 -0
  21. package/dist/os/program/discovery.d.ts.map +1 -0
  22. package/dist/os/program/discovery.js +236 -0
  23. package/dist/os/program/discovery.js.map +1 -0
  24. package/dist/os/program/handlers/complete.d.ts +12 -0
  25. package/dist/os/program/handlers/complete.d.ts.map +1 -0
  26. package/dist/os/program/handlers/complete.js +344 -0
  27. package/dist/os/program/handlers/complete.js.map +1 -0
  28. package/dist/os/program/handlers/lease.d.ts +13 -0
  29. package/dist/os/program/handlers/lease.d.ts.map +1 -0
  30. package/dist/os/program/handlers/lease.js +322 -0
  31. package/dist/os/program/handlers/lease.js.map +1 -0
  32. package/dist/os/program/handlers/seal.d.ts +12 -0
  33. package/dist/os/program/handlers/seal.d.ts.map +1 -0
  34. package/dist/os/program/handlers/seal.js +265 -0
  35. package/dist/os/program/handlers/seal.js.map +1 -0
  36. package/dist/os/program/handlers/validate.d.ts +14 -0
  37. package/dist/os/program/handlers/validate.d.ts.map +1 -0
  38. package/dist/os/program/handlers/validate.js +164 -0
  39. package/dist/os/program/handlers/validate.js.map +1 -0
  40. package/dist/os/program/lease.d.ts +39 -0
  41. package/dist/os/program/lease.d.ts.map +1 -0
  42. package/dist/os/program/lease.js +129 -0
  43. package/dist/os/program/lease.js.map +1 -0
  44. package/dist/os/program/program.module.d.ts +3 -0
  45. package/dist/os/program/program.module.d.ts.map +1 -0
  46. package/dist/os/program/program.module.js +201 -0
  47. package/dist/os/program/program.module.js.map +1 -0
  48. package/dist/os/program/schemas.d.ts +225 -0
  49. package/dist/os/program/schemas.d.ts.map +1 -0
  50. package/dist/os/program/schemas.js +174 -0
  51. package/dist/os/program/schemas.js.map +1 -0
  52. package/dist/os/program/state.d.ts +38 -0
  53. package/dist/os/program/state.d.ts.map +1 -0
  54. package/dist/os/program/state.js +189 -0
  55. package/dist/os/program/state.js.map +1 -0
  56. package/dist/os/rfc/handlers/archive.d.ts +1 -0
  57. package/dist/os/rfc/handlers/archive.d.ts.map +1 -1
  58. package/dist/os/rfc/handlers/archive.js +54 -0
  59. package/dist/os/rfc/handlers/archive.js.map +1 -1
  60. package/dist/os/rfc/handlers/validate.d.ts.map +1 -1
  61. package/dist/os/rfc/handlers/validate.js +5 -5
  62. package/dist/os/rfc/handlers/validate.js.map +1 -1
  63. package/dist/src/index.d.ts +2 -0
  64. package/dist/src/index.d.ts.map +1 -1
  65. package/dist/src/index.js +2 -0
  66. package/dist/src/index.js.map +1 -1
  67. package/dist/src/onboarding/invariant-engine.d.ts.map +1 -1
  68. package/dist/src/onboarding/invariant-engine.js +137 -5
  69. package/dist/src/onboarding/invariant-engine.js.map +1 -1
  70. package/dist/src/profiles/profile-schema.d.ts +16 -1
  71. package/dist/src/profiles/profile-schema.d.ts.map +1 -1
  72. package/dist/src/profiles/profile-schema.js +16 -1
  73. package/dist/src/profiles/profile-schema.js.map +1 -1
  74. package/dist/src/profiles/stack-profile.d.ts +5 -0
  75. package/dist/src/profiles/stack-profile.d.ts.map +1 -1
  76. package/dist/src/profiles/stack-profile.js +3 -0
  77. package/dist/src/profiles/stack-profile.js.map +1 -1
  78. package/dist/src/validators/note-frontmatter-validate.d.ts +20 -0
  79. package/dist/src/validators/note-frontmatter-validate.d.ts.map +1 -0
  80. package/dist/src/validators/note-frontmatter-validate.js +117 -0
  81. package/dist/src/validators/note-frontmatter-validate.js.map +1 -0
  82. package/dist/src/validators/note-link-validate.d.ts +21 -0
  83. package/dist/src/validators/note-link-validate.d.ts.map +1 -0
  84. package/dist/src/validators/note-link-validate.js +121 -0
  85. package/dist/src/validators/note-link-validate.js.map +1 -0
  86. package/dist/src/validators/note-orphan-detect.d.ts +19 -0
  87. package/dist/src/validators/note-orphan-detect.d.ts.map +1 -0
  88. package/dist/src/validators/note-orphan-detect.js +123 -0
  89. package/dist/src/validators/note-orphan-detect.js.map +1 -0
  90. package/package.json +31 -15
  91. package/profiles/astro-typescript-turborepo.yaml +1 -1
  92. package/profiles/editframe.yaml +2 -2
  93. package/profiles/forge-shell.yaml +1 -1
  94. package/profiles/godot-csharp.yaml +388 -0
  95. package/profiles/obsidian-vault.yaml +103 -0
  96. package/profiles/phaser-turborepo.yaml +1 -1
  97. package/skills/fo/ef-onboard/SKILL.md +1 -1
  98. package/skills/fo/fo-idea/SKILL.md +2 -2
  99. package/skills/fo/fo-idea-implement/SKILL.md +1 -1
  100. package/skills/fo/fo-step-commit/SKILL.md +7 -5
  101. package/skills/shared/grilling/learned-principles.archive.md +212 -0
  102. package/skills/shared/grilling/learned-principles.md +0 -13
  103. package/skills/shared/grilling/qa-log.md +624 -0
  104. package/skills/shared/knowledge/learned-principles.md +99 -0
@@ -68,12 +68,16 @@ export declare const stackProfileSchema: z.ZodObject<{
68
68
  "file-contains": "file-contains";
69
69
  "file-not-contains": "file-not-contains";
70
70
  "attribute-pattern": "attribute-pattern";
71
+ "link-resolution": "link-resolution";
72
+ "frontmatter-required": "frontmatter-required";
73
+ "path-exclusion": "path-exclusion";
71
74
  }>;
72
75
  glob: z.ZodOptional<z.ZodString>;
73
76
  pattern: z.ZodOptional<z.ZodString>;
74
77
  negatedPattern: z.ZodOptional<z.ZodString>;
75
78
  elements: z.ZodOptional<z.ZodArray<z.ZodString>>;
76
79
  attribute: z.ZodOptional<z.ZodString>;
80
+ fields: z.ZodOptional<z.ZodArray<z.ZodString>>;
77
81
  }, z.core.$strip>>;
78
82
  }, z.core.$strip>>>;
79
83
  register: z.ZodOptional<z.ZodEnum<{
@@ -130,6 +134,7 @@ export declare const stackProfileSchema: z.ZodObject<{
130
134
  install: z.ZodDefault<z.ZodArray<z.ZodString>>;
131
135
  }, z.core.$strip>;
132
136
  }, z.core.$strip>>>;
137
+ scriptDir: z.ZodOptional<z.ZodString>;
133
138
  }, z.core.$strip>;
134
139
  export interface ProfileFile {
135
140
  path: string;
@@ -1 +1 @@
1
- {"version":3,"file":"stack-profile.d.ts","sourceRoot":"","sources":["../../../src/profiles/stack-profile.ts"],"names":[],"mappings":"AAmBA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,OAAO,EAAkC,KAAK,wBAAwB,EAAE,MAAM,qBAAqB,CAAC;AAMpG,eAAO,MAAM,kBAAkB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBA8C7B,CAAC;AAEH,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,YAAa,SAAQ,wBAAwB;IAC5D,MAAM,EAAE,uBAAuB,CAAC;IAChC,EAAE,EAAE,MAAM,CAAC;IACX,WAAW,EAAE,MAAM,CAAC;IACpB,MAAM,EAAE;QAAE,KAAK,EAAE,MAAM,EAAE,CAAA;KAAE,CAAC;IAC5B,SAAS,EAAE;QACT,IAAI,EAAE,MAAM,EAAE,CAAC;QACf,KAAK,EAAE,WAAW,EAAE,CAAC;KACtB,CAAC;IACF,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,cAAc,CAAC,EAAE;QACf,IAAI,EAAE,MAAM,CAAC;QACb,KAAK,EAAE,WAAW,EAAE,CAAC;QACrB,OAAO,EAAE,MAAM,EAAE,CAAC;KACnB,CAAC;IACF,aAAa,CAAC,EAAE,OAAO,qBAAqB,EAAE,mBAAmB,EAAE,CAAC;IACpE,SAAS,CAAC,EAAE,OAAO,qBAAqB,EAAE,eAAe,EAAE,CAAC;CAC7D;AAMD,wBAAgB,gBAAgB,CAAC,WAAW,EAAE,MAAM,GAAG,YAAY,CAkBlE;AAED,wBAAgB,iBAAiB,CAAC,SAAS,EAAE,MAAM,GAAG,YAAY,EAAE,CAiBnE;AAMD,wBAAgB,WAAW,CAAC,WAAW,EAAE,MAAM,EAAE,QAAQ,EAAE,YAAY,EAAE,GAAG,YAAY,GAAG,IAAI,CAO9F"}
1
+ {"version":3,"file":"stack-profile.d.ts","sourceRoot":"","sources":["../../../src/profiles/stack-profile.ts"],"names":[],"mappings":"AAoBA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,OAAO,EAAkC,KAAK,wBAAwB,EAAE,MAAM,qBAAqB,CAAC;AAMpG,eAAO,MAAM,kBAAkB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBAgD7B,CAAC;AAEH,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,YAAa,SAAQ,wBAAwB;IAC5D,MAAM,EAAE,uBAAuB,CAAC;IAChC,EAAE,EAAE,MAAM,CAAC;IACX,WAAW,EAAE,MAAM,CAAC;IACpB,MAAM,EAAE;QAAE,KAAK,EAAE,MAAM,EAAE,CAAA;KAAE,CAAC;IAC5B,SAAS,EAAE;QACT,IAAI,EAAE,MAAM,EAAE,CAAC;QACf,KAAK,EAAE,WAAW,EAAE,CAAC;KACtB,CAAC;IACF,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,cAAc,CAAC,EAAE;QACf,IAAI,EAAE,MAAM,CAAC;QACb,KAAK,EAAE,WAAW,EAAE,CAAC;QACrB,OAAO,EAAE,MAAM,EAAE,CAAC;KACnB,CAAC;IACF,aAAa,CAAC,EAAE,OAAO,qBAAqB,EAAE,mBAAmB,EAAE,CAAC;IACpE,SAAS,CAAC,EAAE,OAAO,qBAAqB,EAAE,eAAe,EAAE,CAAC;CAC7D;AAMD,wBAAgB,gBAAgB,CAAC,WAAW,EAAE,MAAM,GAAG,YAAY,CAkBlE;AAED,wBAAgB,iBAAiB,CAAC,SAAS,EAAE,MAAM,GAAG,YAAY,EAAE,CAiBnE;AAMD,wBAAgB,WAAW,CAAC,WAAW,EAAE,MAAM,EAAE,QAAQ,EAAE,YAAY,EAAE,GAAG,YAAY,GAAG,IAAI,CAO9F"}
@@ -12,6 +12,7 @@
12
12
  <item>RFC-0674: add devServer field to stackProfileSchema for lifecycle commands.</item>
13
13
  <item>RFC-0679: add assets field to stackProfileSchema for asset management commands.</item>
14
14
  <item>RFC-0680: add release field to stackProfileSchema for release lifecycle commands.</item>
15
+ <item>ADR-0043: add scriptDir field for agent-generated script directory convention.</item>
15
16
  </CHANGE_SUMMARY>
16
17
  */
17
18
  import fs from "node:fs";
@@ -64,6 +65,8 @@ export const stackProfileSchema = z.object({
64
65
  prerequisites: stackProfileDomainFieldsSchema.shape.prerequisites,
65
66
  // Templates: multi-template profiles (e.g. React + HTML)
66
67
  templates: stackProfileDomainFieldsSchema.shape.templates,
68
+ // ADR-0043: Agent-generated script directory override
69
+ scriptDir: stackProfileDomainFieldsSchema.shape.scriptDir,
67
70
  });
68
71
  // ---------------------------------------------------------------------------
69
72
  // Loader
@@ -1 +1 @@
1
- {"version":3,"file":"stack-profile.js","sourceRoot":"","sources":["../../../src/profiles/stack-profile.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"stack-profile.js","sourceRoot":"","sources":["../../../src/profiles/stack-profile.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,20 @@
1
+ import type { ForgeCommandResult } from "../types.ts";
2
+ interface NoteFrontmatterValidateInput {
3
+ flags: Record<string, unknown>;
4
+ }
5
+ export interface FrontmatterViolation {
6
+ file: string;
7
+ field: string;
8
+ rule: "NOTE-02";
9
+ message: string;
10
+ }
11
+ export interface NoteFrontmatterValidateResult {
12
+ command: "note.frontmatter.validate";
13
+ violations: FrontmatterViolation[];
14
+ count: number;
15
+ }
16
+ export declare function runNoteFrontmatterValidate(input: NoteFrontmatterValidateInput, context: {
17
+ workspaceRoot?: string;
18
+ }): ForgeCommandResult<NoteFrontmatterValidateResult>;
19
+ export {};
20
+ //# sourceMappingURL=note-frontmatter-validate.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"note-frontmatter-validate.d.ts","sourceRoot":"","sources":["../../../src/validators/note-frontmatter-validate.ts"],"names":[],"mappings":"AAgBA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,aAAa,CAAC;AAEtD,UAAU,4BAA4B;IACpC,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CAChC;AAED,MAAM,WAAW,oBAAoB;IACnC,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,SAAS,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,6BAA6B;IAC5C,OAAO,EAAE,2BAA2B,CAAC;IACrC,UAAU,EAAE,oBAAoB,EAAE,CAAC;IACnC,KAAK,EAAE,MAAM,CAAC;CACf;AAiBD,wBAAgB,0BAA0B,CACxC,KAAK,EAAE,4BAA4B,EACnC,OAAO,EAAE;IAAE,aAAa,CAAC,EAAE,MAAM,CAAA;CAAE,GAClC,kBAAkB,CAAC,6BAA6B,CAAC,CAwFnD"}
@@ -0,0 +1,117 @@
1
+ /*
2
+ <MODULE_CONTRACT>
3
+ <purpose>Validate frontmatter consistency across an Obsidian vault — checks for required fields in YAML frontmatter.</purpose>
4
+ <non-goals>
5
+ <item>Do not import from @warpgogol/* — this module is portable.</item>
6
+ <item>Do not implement domain-specific logic beyond frontmatter validation.</item>
7
+ </non-goals>
8
+ </MODULE_CONTRACT>
9
+ <CHANGE_SUMMARY>
10
+ <item>RFC-0808: initial note.frontmatter.validate command handler.</item>
11
+ </CHANGE_SUMMARY>
12
+ */
13
+ import fs from "node:fs";
14
+ import path from "node:path";
15
+ import { parse as parseYaml } from "yaml";
16
+ function collectMarkdownFiles(dir, baseDir, results) {
17
+ const SKIP_DIRS = new Set(["node_modules", ".git", ".turbo", "dist", ".cache", ".obsidian"]);
18
+ const entries = fs.readdirSync(dir, { withFileTypes: true });
19
+ for (const entry of entries) {
20
+ if (entry.isDirectory() && SKIP_DIRS.has(entry.name))
21
+ continue;
22
+ const fullPath = path.join(dir, entry.name);
23
+ const relPath = path.relative(baseDir, fullPath).replace(/\\/g, "/");
24
+ if (entry.isDirectory()) {
25
+ collectMarkdownFiles(fullPath, baseDir, results);
26
+ }
27
+ else if (entry.name.endsWith(".md")) {
28
+ results.push(relPath);
29
+ }
30
+ }
31
+ }
32
+ export function runNoteFrontmatterValidate(input, context) {
33
+ const workspaceRoot = context.workspaceRoot ?? process.cwd();
34
+ const vaultDir = input.flags["vault-dir"] ?? "vault";
35
+ const requiredFields = (input.flags["fields"] ?? "title")
36
+ .split(",")
37
+ .map((f) => f.trim())
38
+ .filter(Boolean);
39
+ const scanDir = path.join(workspaceRoot, vaultDir);
40
+ if (!fs.existsSync(scanDir)) {
41
+ return {
42
+ data: {
43
+ command: "note.frontmatter.validate",
44
+ violations: [],
45
+ count: 0,
46
+ },
47
+ exitCode: 0,
48
+ summary: "note.frontmatter.validate: vault directory not found — 0 violations",
49
+ };
50
+ }
51
+ const allMdFiles = [];
52
+ collectMarkdownFiles(scanDir, workspaceRoot, allMdFiles);
53
+ const violations = [];
54
+ for (const file of allMdFiles) {
55
+ const fullPath = path.join(workspaceRoot, file);
56
+ try {
57
+ const content = fs.readFileSync(fullPath, "utf8");
58
+ const fmMatch = content.match(/^---\r?\n([\s\S]*?)\r?\n---/);
59
+ if (!fmMatch) {
60
+ for (const field of requiredFields) {
61
+ violations.push({
62
+ file,
63
+ field,
64
+ rule: "NOTE-02",
65
+ message: `File '${file}' has no frontmatter — missing field '${field}'`,
66
+ });
67
+ }
68
+ continue;
69
+ }
70
+ let fm = {};
71
+ try {
72
+ fm = parseYaml(fmMatch[1]);
73
+ }
74
+ catch {
75
+ for (const field of requiredFields) {
76
+ violations.push({
77
+ file,
78
+ field,
79
+ rule: "NOTE-02",
80
+ message: `File '${file}' has malformed frontmatter — missing field '${field}'`,
81
+ });
82
+ }
83
+ continue;
84
+ }
85
+ for (const field of requiredFields) {
86
+ if (!(field in fm) || fm[field] == null || fm[field] === "") {
87
+ if (field === "title") {
88
+ const hasH1 = /^\s*#\s+\S/.test(content.slice(fmMatch[0].length));
89
+ if (hasH1)
90
+ continue;
91
+ }
92
+ violations.push({
93
+ file,
94
+ field,
95
+ rule: "NOTE-02",
96
+ message: `File '${file}' missing required field '${field}'`,
97
+ });
98
+ }
99
+ }
100
+ }
101
+ catch {
102
+ // skip unreadable files
103
+ }
104
+ }
105
+ return {
106
+ data: {
107
+ command: "note.frontmatter.validate",
108
+ violations,
109
+ count: violations.length,
110
+ },
111
+ exitCode: violations.length > 0 ? 1 : 0,
112
+ summary: violations.length > 0
113
+ ? `note.frontmatter.validate: ${violations.length} violation(s) found`
114
+ : "note.frontmatter.validate: OK — 0 violations",
115
+ };
116
+ }
117
+ //# sourceMappingURL=note-frontmatter-validate.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"note-frontmatter-validate.js","sourceRoot":"","sources":["../../../src/validators/note-frontmatter-validate.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;EAWE;AAEF,OAAO,EAAE,MAAM,SAAS,CAAC;AACzB,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,EAAE,KAAK,IAAI,SAAS,EAAE,MAAM,MAAM,CAAC;AAoB1C,SAAS,oBAAoB,CAAC,GAAW,EAAE,OAAe,EAAE,OAAiB;IAC3E,MAAM,SAAS,GAAG,IAAI,GAAG,CAAC,CAAC,cAAc,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,QAAQ,EAAE,WAAW,CAAC,CAAC,CAAC;IAC7F,MAAM,OAAO,GAAG,EAAE,CAAC,WAAW,CAAC,GAAG,EAAE,EAAE,aAAa,EAAE,IAAI,EAAE,CAAC,CAAC;IAC7D,KAAK,MAAM,KAAK,IAAI,OAAO,EAAE,CAAC;QAC5B,IAAI,KAAK,CAAC,WAAW,EAAE,IAAI,SAAS,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC;YAAE,SAAS;QAC/D,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,CAAC,CAAC;QAC5C,MAAM,OAAO,GAAG,IAAI,CAAC,QAAQ,CAAC,OAAO,EAAE,QAAQ,CAAC,CAAC,OAAO,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC;QACrE,IAAI,KAAK,CAAC,WAAW,EAAE,EAAE,CAAC;YACxB,oBAAoB,CAAC,QAAQ,EAAE,OAAO,EAAE,OAAO,CAAC,CAAC;QACnD,CAAC;aAAM,IAAI,KAAK,CAAC,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,EAAE,CAAC;YACtC,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;QACxB,CAAC;IACH,CAAC;AACH,CAAC;AAED,MAAM,UAAU,0BAA0B,CACxC,KAAmC,EACnC,OAAmC;IAEnC,MAAM,aAAa,GAAG,OAAO,CAAC,aAAa,IAAI,OAAO,CAAC,GAAG,EAAE,CAAC;IAC7D,MAAM,QAAQ,GAAI,KAAK,CAAC,KAAK,CAAC,WAAW,CAAY,IAAI,OAAO,CAAC;IACjE,MAAM,cAAc,GAAG,CAAE,KAAK,CAAC,KAAK,CAAC,QAAQ,CAAY,IAAI,OAAO,CAAC;SAClE,KAAK,CAAC,GAAG,CAAC;SACV,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;SACpB,MAAM,CAAC,OAAO,CAAC,CAAC;IAEnB,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI,CAAC,aAAa,EAAE,QAAQ,CAAC,CAAC;IAEnD,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,OAAO,CAAC,EAAE,CAAC;QAC5B,OAAO;YACL,IAAI,EAAE;gBACJ,OAAO,EAAE,2BAA2B;gBACpC,UAAU,EAAE,EAAE;gBACd,KAAK,EAAE,CAAC;aACT;YACD,QAAQ,EAAE,CAAC;YACX,OAAO,EAAE,qEAAqE;SAC/E,CAAC;IACJ,CAAC;IAED,MAAM,UAAU,GAAa,EAAE,CAAC;IAChC,oBAAoB,CAAC,OAAO,EAAE,aAAa,EAAE,UAAU,CAAC,CAAC;IAEzD,MAAM,UAAU,GAA2B,EAAE,CAAC;IAE9C,KAAK,MAAM,IAAI,IAAI,UAAU,EAAE,CAAC;QAC9B,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAC,aAAa,EAAE,IAAI,CAAC,CAAC;QAChD,IAAI,CAAC;YACH,MAAM,OAAO,GAAG,EAAE,CAAC,YAAY,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC;YAClD,MAAM,OAAO,GAAG,OAAO,CAAC,KAAK,CAAC,6BAA6B,CAAC,CAAC;YAC7D,IAAI,CAAC,OAAO,EAAE,CAAC;gBACb,KAAK,MAAM,KAAK,IAAI,cAAc,EAAE,CAAC;oBACnC,UAAU,CAAC,IAAI,CAAC;wBACd,IAAI;wBACJ,KAAK;wBACL,IAAI,EAAE,SAAS;wBACf,OAAO,EAAE,SAAS,IAAI,yCAAyC,KAAK,GAAG;qBACxE,CAAC,CAAC;gBACL,CAAC;gBACD,SAAS;YACX,CAAC;YACD,IAAI,EAAE,GAA4B,EAAE,CAAC;YACrC,IAAI,CAAC;gBACH,EAAE,GAAG,SAAS,CAAC,OAAO,CAAC,CAAC,CAAC,CAA4B,CAAC;YACxD,CAAC;YAAC,MAAM,CAAC;gBACP,KAAK,MAAM,KAAK,IAAI,cAAc,EAAE,CAAC;oBACnC,UAAU,CAAC,IAAI,CAAC;wBACd,IAAI;wBACJ,KAAK;wBACL,IAAI,EAAE,SAAS;wBACf,OAAO,EAAE,SAAS,IAAI,gDAAgD,KAAK,GAAG;qBAC/E,CAAC,CAAC;gBACL,CAAC;gBACD,SAAS;YACX,CAAC;YACD,KAAK,MAAM,KAAK,IAAI,cAAc,EAAE,CAAC;gBACnC,IAAI,CAAC,CAAC,KAAK,IAAI,EAAE,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,IAAI,IAAI,IAAI,EAAE,CAAC,KAAK,CAAC,KAAK,EAAE,EAAE,CAAC;oBAC5D,IAAI,KAAK,KAAK,OAAO,EAAE,CAAC;wBACtB,MAAM,KAAK,GAAG,YAAY,CAAC,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC;wBAClE,IAAI,KAAK;4BAAE,SAAS;oBACtB,CAAC;oBACD,UAAU,CAAC,IAAI,CAAC;wBACd,IAAI;wBACJ,KAAK;wBACL,IAAI,EAAE,SAAS;wBACf,OAAO,EAAE,SAAS,IAAI,6BAA6B,KAAK,GAAG;qBAC5D,CAAC,CAAC;gBACL,CAAC;YACH,CAAC;QACH,CAAC;QAAC,MAAM,CAAC;YACP,wBAAwB;QAC1B,CAAC;IACH,CAAC;IAED,OAAO;QACL,IAAI,EAAE;YACJ,OAAO,EAAE,2BAA2B;YACpC,UAAU;YACV,KAAK,EAAE,UAAU,CAAC,MAAM;SACzB;QACD,QAAQ,EAAE,UAAU,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;QACvC,OAAO,EACL,UAAU,CAAC,MAAM,GAAG,CAAC;YACnB,CAAC,CAAC,8BAA8B,UAAU,CAAC,MAAM,qBAAqB;YACtE,CAAC,CAAC,8CAA8C;KACrD,CAAC;AACJ,CAAC"}
@@ -0,0 +1,21 @@
1
+ import type { ForgeCommandResult } from "../types.ts";
2
+ interface NoteLinkValidateInput {
3
+ flags: Record<string, unknown>;
4
+ }
5
+ export interface NoteLinkViolation {
6
+ file: string;
7
+ line: number;
8
+ link: string;
9
+ rule: "NOTE-01";
10
+ message: string;
11
+ }
12
+ export interface NoteLinkValidateResult {
13
+ command: "note.link.validate";
14
+ violations: NoteLinkViolation[];
15
+ count: number;
16
+ }
17
+ export declare function runNoteLinkValidate(input: NoteLinkValidateInput, context: {
18
+ workspaceRoot?: string;
19
+ }): ForgeCommandResult<NoteLinkValidateResult>;
20
+ export {};
21
+ //# sourceMappingURL=note-link-validate.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"note-link-validate.d.ts","sourceRoot":"","sources":["../../../src/validators/note-link-validate.ts"],"names":[],"mappings":"AAgBA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,aAAa,CAAC;AAEtD,UAAU,qBAAqB;IAC7B,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CAChC;AAED,MAAM,WAAW,iBAAiB;IAChC,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,SAAS,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,sBAAsB;IACrC,OAAO,EAAE,oBAAoB,CAAC;IAC9B,UAAU,EAAE,iBAAiB,EAAE,CAAC;IAChC,KAAK,EAAE,MAAM,CAAC;CACf;AAiBD,wBAAgB,mBAAmB,CACjC,KAAK,EAAE,qBAAqB,EAC5B,OAAO,EAAE;IAAE,aAAa,CAAC,EAAE,MAAM,CAAA;CAAE,GAClC,kBAAkB,CAAC,sBAAsB,CAAC,CA0F5C"}
@@ -0,0 +1,121 @@
1
+ /*
2
+ <MODULE_CONTRACT>
3
+ <purpose>Validate wikilink integrity across an Obsidian vault — scans [[wikilinks]] and resolves each against the note graph.</purpose>
4
+ <non-goals>
5
+ <item>Do not import from @warpgogol/* — this module is portable.</item>
6
+ <item>Do not implement domain-specific logic beyond wikilink resolution.</item>
7
+ </non-goals>
8
+ </MODULE_CONTRACT>
9
+ <CHANGE_SUMMARY>
10
+ <item>RFC-0808: initial note.link.validate command handler.</item>
11
+ </CHANGE_SUMMARY>
12
+ */
13
+ import fs from "node:fs";
14
+ import path from "node:path";
15
+ import { parse as parseYaml } from "yaml";
16
+ function collectMarkdownFiles(dir, baseDir, results) {
17
+ const SKIP_DIRS = new Set(["node_modules", ".git", ".turbo", "dist", ".cache", ".obsidian"]);
18
+ const entries = fs.readdirSync(dir, { withFileTypes: true });
19
+ for (const entry of entries) {
20
+ if (entry.isDirectory() && SKIP_DIRS.has(entry.name))
21
+ continue;
22
+ const fullPath = path.join(dir, entry.name);
23
+ const relPath = path.relative(baseDir, fullPath).replace(/\\/g, "/");
24
+ if (entry.isDirectory()) {
25
+ collectMarkdownFiles(fullPath, baseDir, results);
26
+ }
27
+ else if (entry.name.endsWith(".md")) {
28
+ results.push(relPath);
29
+ }
30
+ }
31
+ }
32
+ export function runNoteLinkValidate(input, context) {
33
+ const workspaceRoot = context.workspaceRoot ?? process.cwd();
34
+ const vaultDir = input.flags["vault-dir"] ?? "vault";
35
+ const pathFilter = input.flags["path"];
36
+ const scanDir = pathFilter
37
+ ? path.join(workspaceRoot, vaultDir, pathFilter)
38
+ : path.join(workspaceRoot, vaultDir);
39
+ if (!fs.existsSync(scanDir)) {
40
+ return {
41
+ data: {
42
+ command: "note.link.validate",
43
+ violations: [],
44
+ count: 0,
45
+ },
46
+ exitCode: 0,
47
+ summary: "note.link.validate: vault directory not found — 0 violations",
48
+ };
49
+ }
50
+ const allMdFiles = [];
51
+ collectMarkdownFiles(scanDir, workspaceRoot, allMdFiles);
52
+ const noteMap = new Map();
53
+ for (const mdFile of allMdFiles) {
54
+ const basename = path.basename(mdFile, ".md");
55
+ noteMap.set(basename, mdFile);
56
+ const fullPath = path.join(workspaceRoot, mdFile);
57
+ try {
58
+ const content = fs.readFileSync(fullPath, "utf8");
59
+ const fmMatch = content.match(/^---\r?\n([\s\S]*?)\r?\n---/);
60
+ if (fmMatch) {
61
+ try {
62
+ const fm = parseYaml(fmMatch[1]);
63
+ if (fm.aliases && Array.isArray(fm.aliases)) {
64
+ for (const alias of fm.aliases) {
65
+ if (typeof alias === "string")
66
+ noteMap.set(alias, mdFile);
67
+ }
68
+ }
69
+ }
70
+ catch {
71
+ // skip malformed frontmatter
72
+ }
73
+ }
74
+ }
75
+ catch {
76
+ // skip unreadable files
77
+ }
78
+ }
79
+ const linkRegex = /\[\[([^\]]+?)\]\]/g;
80
+ const violations = [];
81
+ for (const file of allMdFiles) {
82
+ const fullPath = path.join(workspaceRoot, file);
83
+ try {
84
+ const content = fs.readFileSync(fullPath, "utf8");
85
+ const lines = content.split(/\r?\n/);
86
+ for (let i = 0; i < lines.length; i++) {
87
+ let match;
88
+ linkRegex.lastIndex = 0;
89
+ while ((match = linkRegex.exec(lines[i])) !== null) {
90
+ const linkTarget = match[1].split("|")[0].split("#")[0].trim();
91
+ if (!linkTarget)
92
+ continue;
93
+ if (!noteMap.has(linkTarget)) {
94
+ violations.push({
95
+ file,
96
+ line: i + 1,
97
+ link: match[0],
98
+ rule: "NOTE-01",
99
+ message: `Wikilink target '${linkTarget}' not found in vault`,
100
+ });
101
+ }
102
+ }
103
+ }
104
+ }
105
+ catch {
106
+ // skip unreadable files
107
+ }
108
+ }
109
+ return {
110
+ data: {
111
+ command: "note.link.validate",
112
+ violations,
113
+ count: violations.length,
114
+ },
115
+ exitCode: violations.length > 0 ? 1 : 0,
116
+ summary: violations.length > 0
117
+ ? `note.link.validate: ${violations.length} violation(s) found`
118
+ : "note.link.validate: OK — 0 violations",
119
+ };
120
+ }
121
+ //# sourceMappingURL=note-link-validate.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"note-link-validate.js","sourceRoot":"","sources":["../../../src/validators/note-link-validate.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,19 @@
1
+ import type { ForgeCommandResult } from "../types.ts";
2
+ interface NoteOrphanDetectInput {
3
+ flags: Record<string, unknown>;
4
+ }
5
+ export interface OrphanReport {
6
+ file: string;
7
+ inboundLinks: 0;
8
+ severity: "warning";
9
+ }
10
+ export interface NoteOrphanDetectResult {
11
+ command: "note.orphan.detect";
12
+ orphans: OrphanReport[];
13
+ count: number;
14
+ }
15
+ export declare function runNoteOrphanDetect(input: NoteOrphanDetectInput, context: {
16
+ workspaceRoot?: string;
17
+ }): ForgeCommandResult<NoteOrphanDetectResult>;
18
+ export {};
19
+ //# sourceMappingURL=note-orphan-detect.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"note-orphan-detect.d.ts","sourceRoot":"","sources":["../../../src/validators/note-orphan-detect.ts"],"names":[],"mappings":"AAgBA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,aAAa,CAAC;AAEtD,UAAU,qBAAqB;IAC7B,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CAChC;AAED,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,MAAM,CAAC;IACb,YAAY,EAAE,CAAC,CAAC;IAChB,QAAQ,EAAE,SAAS,CAAC;CACrB;AAED,MAAM,WAAW,sBAAsB;IACrC,OAAO,EAAE,oBAAoB,CAAC;IAC9B,OAAO,EAAE,YAAY,EAAE,CAAC;IACxB,KAAK,EAAE,MAAM,CAAC;CACf;AAiBD,wBAAgB,mBAAmB,CACjC,KAAK,EAAE,qBAAqB,EAC5B,OAAO,EAAE;IAAE,aAAa,CAAC,EAAE,MAAM,CAAA;CAAE,GAClC,kBAAkB,CAAC,sBAAsB,CAAC,CA6F5C"}
@@ -0,0 +1,123 @@
1
+ /*
2
+ <MODULE_CONTRACT>
3
+ <purpose>Detect orphan notes in an Obsidian vault — notes with zero inbound wikilinks.</purpose>
4
+ <non-goals>
5
+ <item>Do not import from @warpgogol/* — this module is portable.</item>
6
+ <item>Do not implement domain-specific logic beyond orphan detection.</item>
7
+ </non-goals>
8
+ </MODULE_CONTRACT>
9
+ <CHANGE_SUMMARY>
10
+ <item>RFC-0808: initial note.orphan.detect command handler.</item>
11
+ </CHANGE_SUMMARY>
12
+ */
13
+ import fs from "node:fs";
14
+ import path from "node:path";
15
+ import { parse as parseYaml } from "yaml";
16
+ function collectMarkdownFiles(dir, baseDir, results) {
17
+ const SKIP_DIRS = new Set(["node_modules", ".git", ".turbo", "dist", ".cache", ".obsidian"]);
18
+ const entries = fs.readdirSync(dir, { withFileTypes: true });
19
+ for (const entry of entries) {
20
+ if (entry.isDirectory() && SKIP_DIRS.has(entry.name))
21
+ continue;
22
+ const fullPath = path.join(dir, entry.name);
23
+ const relPath = path.relative(baseDir, fullPath).replace(/\\/g, "/");
24
+ if (entry.isDirectory()) {
25
+ collectMarkdownFiles(fullPath, baseDir, results);
26
+ }
27
+ else if (entry.name.endsWith(".md")) {
28
+ results.push(relPath);
29
+ }
30
+ }
31
+ }
32
+ export function runNoteOrphanDetect(input, context) {
33
+ const workspaceRoot = context.workspaceRoot ?? process.cwd();
34
+ const vaultDir = input.flags["vault-dir"] ?? "vault";
35
+ const scanDir = path.join(workspaceRoot, vaultDir);
36
+ if (!fs.existsSync(scanDir)) {
37
+ return {
38
+ data: {
39
+ command: "note.orphan.detect",
40
+ orphans: [],
41
+ count: 0,
42
+ },
43
+ exitCode: 0,
44
+ summary: "note.orphan.detect: vault directory not found — 0 orphans",
45
+ };
46
+ }
47
+ const allMdFiles = [];
48
+ collectMarkdownFiles(scanDir, workspaceRoot, allMdFiles);
49
+ const noteMap = new Map();
50
+ for (const mdFile of allMdFiles) {
51
+ const basename = path.basename(mdFile, ".md");
52
+ noteMap.set(basename, mdFile);
53
+ const fullPath = path.join(workspaceRoot, mdFile);
54
+ try {
55
+ const content = fs.readFileSync(fullPath, "utf8");
56
+ const fmMatch = content.match(/^---\r?\n([\s\S]*?)\r?\n---/);
57
+ if (fmMatch) {
58
+ try {
59
+ const fm = parseYaml(fmMatch[1]);
60
+ if (fm.aliases && Array.isArray(fm.aliases)) {
61
+ for (const alias of fm.aliases) {
62
+ if (typeof alias === "string")
63
+ noteMap.set(alias, mdFile);
64
+ }
65
+ }
66
+ }
67
+ catch {
68
+ // skip malformed frontmatter
69
+ }
70
+ }
71
+ }
72
+ catch {
73
+ // skip unreadable files
74
+ }
75
+ }
76
+ const inboundLinks = new Map();
77
+ for (const mdFile of allMdFiles) {
78
+ inboundLinks.set(mdFile, 0);
79
+ }
80
+ const linkRegex = /\[\[([^\]]+?)\]\]/g;
81
+ for (const file of allMdFiles) {
82
+ const fullPath = path.join(workspaceRoot, file);
83
+ try {
84
+ const content = fs.readFileSync(fullPath, "utf8");
85
+ let match;
86
+ linkRegex.lastIndex = 0;
87
+ while ((match = linkRegex.exec(content)) !== null) {
88
+ const linkTarget = match[1].split("|")[0].split("#")[0].trim();
89
+ if (!linkTarget)
90
+ continue;
91
+ const targetFile = noteMap.get(linkTarget);
92
+ if (targetFile && targetFile !== file) {
93
+ inboundLinks.set(targetFile, (inboundLinks.get(targetFile) ?? 0) + 1);
94
+ }
95
+ }
96
+ }
97
+ catch {
98
+ // skip unreadable files
99
+ }
100
+ }
101
+ const orphans = [];
102
+ for (const [file, count] of inboundLinks) {
103
+ if (count === 0) {
104
+ orphans.push({
105
+ file,
106
+ inboundLinks: 0,
107
+ severity: "warning",
108
+ });
109
+ }
110
+ }
111
+ return {
112
+ data: {
113
+ command: "note.orphan.detect",
114
+ orphans,
115
+ count: orphans.length,
116
+ },
117
+ exitCode: 0,
118
+ summary: orphans.length > 0
119
+ ? `note.orphan.detect: ${orphans.length} orphan(s) found`
120
+ : "note.orphan.detect: OK — 0 orphans",
121
+ };
122
+ }
123
+ //# sourceMappingURL=note-orphan-detect.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"note-orphan-detect.js","sourceRoot":"","sources":["../../../src/validators/note-orphan-detect.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,19 +1,11 @@
1
1
  {
2
2
  "name": "@warpgogol/forge",
3
- "version": "0.27.0",
3
+ "version": "1.0.0",
4
4
  "private": false,
5
5
  "type": "module",
6
6
  "license": "Apache-2.0",
7
7
  "description": "Framework for documenting and implementing ideas — RFC/ADR governance, skills, and project bootstrapping.",
8
- "keywords": [
9
- "rfc",
10
- "adr",
11
- "governance",
12
- "skills",
13
- "ai-agent",
14
- "documentation",
15
- "framework"
16
- ],
8
+ "keywords": ["rfc", "adr", "governance", "skills", "ai-agent", "documentation", "framework"],
17
9
  "homepage": "https://warpgogol.com",
18
10
  "main": "./src/index.ts",
19
11
  "types": "./src/index.ts",
@@ -124,6 +116,18 @@
124
116
  "./os/exploration-module": {
125
117
  "types": "./os/exploration/exploration.module.ts",
126
118
  "default": "./os/exploration/exploration.module.ts"
119
+ },
120
+ "./os/notes": {
121
+ "types": "./os/notes/index.ts",
122
+ "default": "./os/notes/index.ts"
123
+ },
124
+ "./os/notes-module": {
125
+ "types": "./os/notes/notes.module.ts",
126
+ "default": "./os/notes/notes.module.ts"
127
+ },
128
+ "./os/program": {
129
+ "types": "./os/program/program.module.ts",
130
+ "default": "./os/program/program.module.ts"
127
131
  }
128
132
  },
129
133
  "files": [
@@ -143,7 +147,8 @@
143
147
  "lint": "pnpm exec eslint src --ext .ts",
144
148
  "typecheck": "pnpm exec tsc -p tsconfig.json --noEmit",
145
149
  "test": "vitest run --passWithNoTests",
146
- "test:watch": "vitest"
150
+ "test:watch": "vitest",
151
+ "test:tarball:node24": "node test-fixtures/node24-consumer/smoke.mjs"
147
152
  },
148
153
  "dependencies": {
149
154
  "@aws-sdk/client-s3": "^3.700.0",
@@ -152,13 +157,13 @@
152
157
  "zod": "^4.4.3"
153
158
  },
154
159
  "devDependencies": {
155
- "@types/node": "^26.1.2",
160
+ "@types/node": "^24.0.0",
156
161
  "fast-check": "^4.9.0",
157
162
  "typescript": "^6.0.3",
158
163
  "vitest": "^4.1.10"
159
164
  },
160
165
  "engines": {
161
- "node": ">=20.0.0"
166
+ "node": ">=24 <25"
162
167
  },
163
168
  "publishConfig": {
164
169
  "access": "public",
@@ -268,8 +273,19 @@
268
273
  "./os/exploration-module": {
269
274
  "types": "./dist/os/exploration/exploration.module.d.ts",
270
275
  "default": "./dist/os/exploration/exploration.module.js"
276
+ },
277
+ "./os/notes": {
278
+ "types": "./dist/os/notes/index.d.ts",
279
+ "default": "./dist/os/notes/index.js"
280
+ },
281
+ "./os/notes-module": {
282
+ "types": "./dist/os/notes/notes.module.d.ts",
283
+ "default": "./dist/os/notes/notes.module.js"
284
+ },
285
+ "./os/program": {
286
+ "types": "./dist/os/program/program.module.d.ts",
287
+ "default": "./dist/os/program/program.module.js"
271
288
  }
272
289
  }
273
- },
274
- "packageManager": "pnpm@11.10.0"
290
+ }
275
291
  }
@@ -150,7 +150,7 @@ workspace:
150
150
  "private": true,
151
151
  "type": "module",
152
152
  "engines": {
153
- "node": ">=22"
153
+ "node": ">=24 <25"
154
154
  },
155
155
  "scripts": {
156
156
  "clean": "node scripts/clean.mjs",