mustflow 2.108.8 → 2.112.1

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.
@@ -27,6 +27,24 @@ export function getRepoMapSourceFingerprint(input) {
27
27
  manifests: [...repository.manifests].sort(),
28
28
  commandAdapters: [...repository.commandAdapters].sort(),
29
29
  editingPolicies: [...repository.editingPolicies].sort(),
30
+ agentScaffolds: [...(repository.agentScaffolds ?? [])].sort(),
31
+ validationGuides: [...(repository.validationGuides ?? [])].sort(),
32
+ diagrams: [...(repository.diagrams ?? [])].sort(),
33
+ githubTemplates: [...(repository.githubTemplates ?? [])].sort(),
34
+ ssealedScaffold: repository.ssealedScaffold
35
+ ? {
36
+ manifestPath: repository.ssealedScaffold.manifestPath,
37
+ version: repository.ssealedScaffold.version,
38
+ scope: repository.ssealedScaffold.scope,
39
+ profile: repository.ssealedScaffold.profile,
40
+ density: repository.ssealedScaffold.density,
41
+ runner: repository.ssealedScaffold.runner,
42
+ fileCount: repository.ssealedScaffold.fileCount,
43
+ fileKinds: repository.ssealedScaffold.fileKinds
44
+ .map((kind) => ({ name: kind.name, count: kind.count }))
45
+ .sort((left, right) => left.name.localeCompare(right.name)),
46
+ }
47
+ : undefined,
30
48
  }))
31
49
  .sort((left, right) => left.relativePath.localeCompare(right.relativePath)),
32
50
  };
@@ -1,5 +1,5 @@
1
1
  import { spawnSync } from 'node:child_process';
2
- import { existsSync, lstatSync, readdirSync, realpathSync, statSync } from 'node:fs';
2
+ import { existsSync, lstatSync, readFileSync, readdirSync, realpathSync, statSync } from 'node:fs';
3
3
  import path from 'node:path';
4
4
  import { toPosixPath } from './filesystem.js';
5
5
  import { getRepoMapSourceFingerprint, renderRepoMapFrontmatter, } from './repo-map-frontmatter.js';
@@ -7,6 +7,7 @@ import { writeUtf8FileInsideWithoutSymlinks } from '../../core/safe-filesystem.j
7
7
  import { isRecord } from './command-contract.js';
8
8
  import { readMustflowTomlFile } from './toml.js';
9
9
  const DEFAULT_DEPTH = 3;
10
+ const NESTED_REPOSITORY_ANCHOR_DEPTH = 3;
10
11
  const GIT_LS_FILES_TIMEOUT_MS = 5_000;
11
12
  const GIT_LS_FILES_MAX_BUFFER_BYTES = 1_048_576;
12
13
  const EXCLUDED_SEGMENTS = new Set([
@@ -39,6 +40,7 @@ const ROOT_OPTIONAL_MARKDOWN_ANCHOR_FILES = [
39
40
  'ROADMAP.md',
40
41
  'DESIGN.md',
41
42
  'CONTRIBUTING.md',
43
+ 'DEVELOPMENT.md',
42
44
  'SECURITY.md',
43
45
  'CHANGELOG.md',
44
46
  'CODE_OF_CONDUCT.md',
@@ -58,6 +60,8 @@ const ROOT_OPTIONAL_MARKDOWN_ANCHOR_FILES = [
58
60
  'TROUBLESHOOTING.md',
59
61
  'ARCHITECTURE.md',
60
62
  'API.md',
63
+ 'CHECKLIST.md',
64
+ 'VALIDATION.md',
61
65
  ];
62
66
  const MACHINE_CONTRACT_ANCHOR_FILES = [
63
67
  'project.contract.json',
@@ -71,6 +75,7 @@ const MACHINE_CONTRACT_ANCHOR_FILES = [
71
75
  'asyncapi.yml',
72
76
  'schema.graphql',
73
77
  'schema.prisma',
78
+ 'schema.dbml',
74
79
  ];
75
80
  const ROOT_OPTIONAL_MARKDOWN_ANCHOR_FILE_SET = new Set(ROOT_OPTIONAL_MARKDOWN_ANCHOR_FILES);
76
81
  const MACHINE_CONTRACT_ANCHOR_FILE_SET = new Set(MACHINE_CONTRACT_ANCHOR_FILES);
@@ -102,7 +107,32 @@ const DEFAULT_NESTED_ANCHOR_FILES = [
102
107
  'Taskfile.yml',
103
108
  'Taskfile.yaml',
104
109
  ];
105
- const MANIFEST_ANCHORS = new Set(['package.json', 'pyproject.toml', 'go.mod', 'Cargo.toml', 'deno.json', 'deno.jsonc']);
110
+ const MANIFEST_ANCHORS = new Set([
111
+ '.ssealed/manifest.json',
112
+ 'package.json',
113
+ 'pyproject.toml',
114
+ 'go.mod',
115
+ 'Cargo.toml',
116
+ 'deno.json',
117
+ 'deno.jsonc',
118
+ ]);
119
+ const SSEALED_MANIFEST_PATH = '.ssealed/manifest.json';
120
+ const SSEALED_SCOPES = new Set(['backend', 'frontend', 'fullstack', 'design']);
121
+ const SSEALED_PROFILES = new Set(['generic', 'cli-tool', 'api-service', 'desktop-app', 'library']);
122
+ const SSEALED_DENSITIES = new Set(['minimal', 'standard', 'strict']);
123
+ const SSEALED_RUNNERS = new Set(['none', 'make', 'just', 'task', 'npm', 'pnpm']);
124
+ const SSEALED_FILE_KINDS = new Set([
125
+ 'document',
126
+ 'contract',
127
+ 'agent',
128
+ 'checklist',
129
+ 'validation',
130
+ 'diagram',
131
+ 'github',
132
+ 'runner',
133
+ 'manifest',
134
+ 'hygiene',
135
+ ]);
106
136
  const COMMAND_ADAPTER_ANCHORS = new Set(['justfile', 'Justfile', 'Makefile', 'Taskfile.yml', 'Taskfile.yaml']);
107
137
  const EDITING_POLICY_ANCHORS = new Set(['.gitattributes', '.editorconfig']);
108
138
  const NESTED_ROOT_DOC_LABELS = new Map([
@@ -111,6 +141,7 @@ const NESTED_ROOT_DOC_LABELS = new Map([
111
141
  ['ROADMAP.md', 'planning context'],
112
142
  ['DESIGN.md', 'visual design'],
113
143
  ['CONTRIBUTING.md', 'contribution guide'],
144
+ ['DEVELOPMENT.md', 'development guide'],
114
145
  ['SECURITY.md', 'security policy'],
115
146
  ['CHANGELOG.md', 'changelog'],
116
147
  ['CODE_OF_CONDUCT.md', 'code of conduct'],
@@ -130,6 +161,8 @@ const NESTED_ROOT_DOC_LABELS = new Map([
130
161
  ['TROUBLESHOOTING.md', 'troubleshooting guide'],
131
162
  ['ARCHITECTURE.md', 'architecture reference'],
132
163
  ['API.md', 'API reference'],
164
+ ['CHECKLIST.md', 'checklist router'],
165
+ ['VALIDATION.md', 'validation router'],
133
166
  ]);
134
167
  const EXACT_ANCHOR_DESCRIPTIONS = new Map([
135
168
  ['AGENTS.md', 'Root agent operating rules. Read this before changing files.'],
@@ -141,6 +174,7 @@ const EXACT_ANCHOR_DESCRIPTIONS = new Map([
141
174
  ['ROADMAP.md', 'Optional project planning, priority, milestone, and non-goal context.'],
142
175
  ['DESIGN.md', 'Optional visual identity and design-token reference for UI work.'],
143
176
  ['CONTRIBUTING.md', 'Optional contribution workflow and pull request guidance.'],
177
+ ['DEVELOPMENT.md', 'Optional local development setup and workflow guide.'],
144
178
  ['SECURITY.md', 'Optional security policy, vulnerability reporting, and sensitive-change guidance.'],
145
179
  ['CHANGELOG.md', 'Optional release history and user-visible change log.'],
146
180
  ['CODE_OF_CONDUCT.md', 'Optional community participation and conduct expectations.'],
@@ -160,6 +194,8 @@ const EXACT_ANCHOR_DESCRIPTIONS = new Map([
160
194
  ['TROUBLESHOOTING.md', 'Optional known-failure and recovery guide.'],
161
195
  ['ARCHITECTURE.md', 'Optional system structure, module boundaries, and architectural decisions.'],
162
196
  ['API.md', 'Optional API surface and integration contract reference.'],
197
+ ['CHECKLIST.md', 'Checklist router for selecting project review checklists.'],
198
+ ['VALIDATION.md', 'Validation router for stable verification names and reporting requirements.'],
163
199
  ['project.contract.json', 'Machine-readable project contract. Prefer domain-specific names over catch-all files.'],
164
200
  ['project.constants.json', 'Machine-readable project constants. Prefer domain-specific names over catch-all files.'],
165
201
  ['design-tokens.json', 'Machine-readable design token contract.'],
@@ -171,6 +207,8 @@ const EXACT_ANCHOR_DESCRIPTIONS = new Map([
171
207
  ['asyncapi.yml', 'Machine-readable AsyncAPI contract.'],
172
208
  ['schema.graphql', 'Machine-readable GraphQL schema contract.'],
173
209
  ['schema.prisma', 'Machine-readable Prisma data schema contract.'],
210
+ ['schema.dbml', 'Machine-readable DBML database schema contract.'],
211
+ ['.ssealed/manifest.json', 'ssealed scaffold manifest with generated file paths and checksums.'],
174
212
  ['package.json', 'Node.js package manifest, binary entry points, and package scripts.'],
175
213
  ['pyproject.toml', 'Python project metadata and tool configuration.'],
176
214
  ['go.mod', 'Go module definition and dependency boundary.'],
@@ -219,6 +257,15 @@ function getBoolean(value, fallback) {
219
257
  function getPositiveInteger(value, fallback) {
220
258
  return Number.isInteger(value) && Number(value) > 0 ? Number(value) : fallback;
221
259
  }
260
+ function getKnownString(value, knownValues) {
261
+ return typeof value === 'string' && knownValues.has(value) ? value : undefined;
262
+ }
263
+ function getSafeVersionString(value) {
264
+ if (typeof value !== 'string') {
265
+ return undefined;
266
+ }
267
+ return /^[0-9A-Za-z][0-9A-Za-z.+_-]{0,63}$/u.test(value) ? value : undefined;
268
+ }
222
269
  function readMustflowConfig(projectRoot) {
223
270
  const configPath = path.join(projectRoot, '.mustflow', 'config', 'mustflow.toml');
224
271
  if (!existsSync(configPath)) {
@@ -364,11 +411,57 @@ function getDirectoryName(relativePath) {
364
411
  const directory = path.posix.dirname(relativePath);
365
412
  return directory === '.' ? '/' : `${directory}/`;
366
413
  }
414
+ function isAgentsScaffoldAnchor(relativePath) {
415
+ return (relativePath === '.agents/README.md' ||
416
+ relativePath === '.agents/context-map.md' ||
417
+ /^\.agents\/skills\/[^/]+\/SKILL\.md$/u.test(relativePath));
418
+ }
419
+ function isValidationGuideAnchor(relativePath) {
420
+ return (relativePath === 'CHECKLIST.md' ||
421
+ relativePath === 'VALIDATION.md' ||
422
+ /^\.agents\/(?:checklists|validations)\/[^/]+\.md$/u.test(relativePath));
423
+ }
424
+ function isDiagramAnchor(relativePath) {
425
+ return relativePath === 'diagrams/README.md' || /^diagrams\/[^/]+\.mmd$/u.test(relativePath);
426
+ }
427
+ function isGithubTemplateAnchor(relativePath) {
428
+ return (relativePath === '.github/CODEOWNERS' ||
429
+ relativePath === '.github/PULL_REQUEST_TEMPLATE.md' ||
430
+ /^\.github\/ISSUE_TEMPLATE\/[^/]+\.md$/u.test(relativePath));
431
+ }
432
+ function isApiExampleContractAnchor(relativePath) {
433
+ return (/^api\/examples\/[^/]+\.json$/u.test(relativePath) ||
434
+ /^contracts\/[^/]+\/examples\/[^/]+\.json$/u.test(relativePath));
435
+ }
436
+ function isMachineContractAnchor(relativePath) {
437
+ const fileName = path.posix.basename(relativePath);
438
+ return (MACHINE_CONTRACT_ANCHOR_FILE_SET.has(relativePath) ||
439
+ MACHINE_CONTRACT_ANCHOR_FILE_SET.has(fileName) ||
440
+ isApiExampleContractAnchor(relativePath));
441
+ }
442
+ function isManifestAnchor(relativePath) {
443
+ return MANIFEST_ANCHORS.has(relativePath);
444
+ }
367
445
  function getAnchorDescription(relativePath) {
368
446
  if (EXACT_ANCHOR_DESCRIPTIONS.has(relativePath)) {
369
447
  return EXACT_ANCHOR_DESCRIPTIONS.get(relativePath);
370
448
  }
371
449
  const fileName = path.posix.basename(relativePath);
450
+ if (isAgentsScaffoldAnchor(relativePath)) {
451
+ return 'Agent scaffold router, skill, or workspace guide for this repository.';
452
+ }
453
+ if (isValidationGuideAnchor(relativePath)) {
454
+ return 'Checklist or validation router for project-specific review and verification.';
455
+ }
456
+ if (isDiagramAnchor(relativePath)) {
457
+ return 'Diagram navigation or Mermaid source for repository design flows.';
458
+ }
459
+ if (isGithubTemplateAnchor(relativePath)) {
460
+ return 'GitHub collaboration template or ownership entrypoint.';
461
+ }
462
+ if (isApiExampleContractAnchor(relativePath)) {
463
+ return 'Machine-readable API example payload contract.';
464
+ }
372
465
  if (fileName === 'AGENTS.md') {
373
466
  return 'Scoped agent operating rules for this directory.';
374
467
  }
@@ -381,6 +474,9 @@ function getAnchorDescription(relativePath) {
381
474
  if (fileName === 'SKILL.md') {
382
475
  return 'Procedural skill document for a repeatable agent task.';
383
476
  }
477
+ if (fileName === 'schema.dbml') {
478
+ return 'Machine-readable DBML database schema contract.';
479
+ }
384
480
  return EXACT_ANCHOR_DESCRIPTIONS.get(fileName);
385
481
  }
386
482
  function isUnderNestedRepository(relativePath, nestedRepositories) {
@@ -494,35 +590,87 @@ function resolveSafeDirectoryTarget(projectRootRealPath, logicalPath, followSyml
494
590
  return undefined;
495
591
  }
496
592
  }
593
+ function readSsealedScaffoldSummary(repositoryPath, relativeRoot) {
594
+ const manifestAbsolutePath = path.join(repositoryPath, ...SSEALED_MANIFEST_PATH.split('/'));
595
+ if (!existsSync(manifestAbsolutePath)) {
596
+ return undefined;
597
+ }
598
+ try {
599
+ const parsed = JSON.parse(readFileSync(manifestAbsolutePath, 'utf8'));
600
+ if (!isRecord(parsed) || parsed.tool !== 'ssealed') {
601
+ return undefined;
602
+ }
603
+ const fileKinds = new Map();
604
+ const manifestFiles = Array.isArray(parsed.files)
605
+ ? parsed.files.filter((file) => isRecord(file))
606
+ : [];
607
+ for (const file of manifestFiles) {
608
+ const kind = getKnownString(file.kind, SSEALED_FILE_KINDS);
609
+ if (kind) {
610
+ fileKinds.set(kind, (fileKinds.get(kind) ?? 0) + 1);
611
+ }
612
+ }
613
+ return {
614
+ manifestPath: `${relativeRoot}${SSEALED_MANIFEST_PATH}`,
615
+ version: getSafeVersionString(parsed.version),
616
+ scope: getKnownString(parsed.scope, SSEALED_SCOPES),
617
+ profile: getKnownString(parsed.profile, SSEALED_PROFILES),
618
+ density: getKnownString(parsed.density, SSEALED_DENSITIES),
619
+ runner: getKnownString(parsed.runner, SSEALED_RUNNERS),
620
+ fileCount: manifestFiles.length,
621
+ fileKinds: [...fileKinds.entries()]
622
+ .map(([name, count]) => ({ name, count }))
623
+ .sort((left, right) => left.name.localeCompare(right.name)),
624
+ };
625
+ }
626
+ catch {
627
+ return undefined;
628
+ }
629
+ }
497
630
  function collectNestedRepository(projectRoot, repositoryPath, anchorFiles) {
498
631
  const relativeRoot = `${toPosixPath(path.relative(projectRoot, repositoryPath))}/`;
499
- const existingAnchors = new Set();
632
+ const anchorFileSet = new Set(anchorFiles);
633
+ const existingAnchors = new Set(listAnchorCandidateFilesRecursive(repositoryPath, NESTED_REPOSITORY_ANCHOR_DEPTH, anchorFileSet));
500
634
  for (const anchorFile of anchorFiles) {
501
635
  if (existsSync(path.join(repositoryPath, ...anchorFile.split('/')))) {
502
636
  existingAnchors.add(anchorFile);
503
637
  }
504
638
  }
639
+ const discoveredAnchors = [...existingAnchors].sort((left, right) => left.localeCompare(right));
505
640
  const resolveAnchor = (anchorFile) => existingAnchors.has(anchorFile) ? `${relativeRoot}${anchorFile}` : undefined;
506
- const manifests = anchorFiles
507
- .filter((anchorFile) => MANIFEST_ANCHORS.has(anchorFile) && existingAnchors.has(anchorFile))
641
+ const manifests = discoveredAnchors
642
+ .filter(isManifestAnchor)
508
643
  .map((anchorFile) => `${relativeRoot}${anchorFile}`);
509
- const commandAdapters = anchorFiles
644
+ const commandAdapters = discoveredAnchors
510
645
  .filter((anchorFile) => COMMAND_ADAPTER_ANCHORS.has(anchorFile) && existingAnchors.has(anchorFile))
511
646
  .map((anchorFile) => `${relativeRoot}${anchorFile}`);
512
- const editingPolicies = anchorFiles
647
+ const editingPolicies = discoveredAnchors
513
648
  .filter((anchorFile) => EDITING_POLICY_ANCHORS.has(anchorFile) && existingAnchors.has(anchorFile))
514
649
  .map((anchorFile) => `${relativeRoot}${anchorFile}`);
515
- const rootDocuments = anchorFiles
650
+ const rootDocuments = discoveredAnchors
516
651
  .filter((anchorFile) => ROOT_OPTIONAL_MARKDOWN_ANCHOR_FILE_SET.has(anchorFile) && existingAnchors.has(anchorFile))
517
652
  .map((anchorFile) => ({
518
653
  label: NESTED_ROOT_DOC_LABELS.get(anchorFile) ?? 'root document',
519
654
  relativePath: `${relativeRoot}${anchorFile}`,
520
655
  }));
521
- const machineContracts = anchorFiles
522
- .filter((anchorFile) => MACHINE_CONTRACT_ANCHOR_FILE_SET.has(anchorFile) && existingAnchors.has(anchorFile))
656
+ const machineContracts = discoveredAnchors
657
+ .filter(isMachineContractAnchor)
658
+ .map((anchorFile) => `${relativeRoot}${anchorFile}`);
659
+ const agentScaffolds = discoveredAnchors
660
+ .filter(isAgentsScaffoldAnchor)
661
+ .map((anchorFile) => `${relativeRoot}${anchorFile}`);
662
+ const validationGuides = discoveredAnchors
663
+ .filter((anchorFile) => /^\.agents\/(?:checklists|validations)\/[^/]+\.md$/u.test(anchorFile))
664
+ .map((anchorFile) => `${relativeRoot}${anchorFile}`);
665
+ const diagrams = discoveredAnchors
666
+ .filter(isDiagramAnchor)
667
+ .map((anchorFile) => `${relativeRoot}${anchorFile}`);
668
+ const githubTemplates = discoveredAnchors
669
+ .filter(isGithubTemplateAnchor)
523
670
  .map((anchorFile) => `${relativeRoot}${anchorFile}`);
524
671
  const mustflowConfig = resolveAnchor('.mustflow/config/mustflow.toml');
525
672
  const commandContract = resolveAnchor('.mustflow/config/commands.toml');
673
+ const ssealedScaffold = readSsealedScaffoldSummary(repositoryPath, relativeRoot);
526
674
  return {
527
675
  relativePath: relativeRoot,
528
676
  mustflow: Boolean(mustflowConfig || commandContract),
@@ -537,6 +685,11 @@ function collectNestedRepository(projectRoot, repositoryPath, anchorFiles) {
537
685
  manifests,
538
686
  commandAdapters,
539
687
  editingPolicies,
688
+ agentScaffolds,
689
+ validationGuides,
690
+ diagrams,
691
+ githubTemplates,
692
+ ssealedScaffold,
540
693
  };
541
694
  }
542
695
  export function discoverNestedRepositories(projectRoot, mapConfig, workspaceConfig) {
@@ -594,6 +747,23 @@ export function discoverNestedRepositories(projectRoot, mapConfig, workspaceConf
594
747
  }
595
748
  return repositories.sort((left, right) => left.relativePath.localeCompare(right.relativePath));
596
749
  }
750
+ function renderSsealedScaffoldSummary(summary) {
751
+ const facts = [
752
+ `manifest \`${summary.manifestPath}\``,
753
+ summary.scope ? `scope \`${summary.scope}\`` : undefined,
754
+ summary.profile ? `profile \`${summary.profile}\`` : undefined,
755
+ summary.density ? `density \`${summary.density}\`` : undefined,
756
+ summary.runner ? `runner \`${summary.runner}\`` : undefined,
757
+ summary.version ? `version \`${summary.version}\`` : undefined,
758
+ `generated files ${summary.fileCount}`,
759
+ ].filter((fact) => Boolean(fact));
760
+ const lines = [`- ssealed scaffold: ${facts.join(', ')}`];
761
+ if (summary.fileKinds.length > 0) {
762
+ lines.push('- ssealed generated file kinds:');
763
+ lines.push(...summary.fileKinds.map((kind) => ` - ${kind.name}: ${kind.count}`));
764
+ }
765
+ return lines;
766
+ }
597
767
  function renderNestedRepositories(nestedRepositories) {
598
768
  if (nestedRepositories.length === 0) {
599
769
  return [];
@@ -628,10 +798,17 @@ function renderNestedRepositories(nestedRepositories) {
628
798
  if (repository.skillIndex) {
629
799
  lines.push(`- skill index: \`${repository.skillIndex}\``);
630
800
  }
801
+ if (repository.agentScaffolds.length > 0) {
802
+ lines.push('- agent scaffolds:');
803
+ lines.push(...repository.agentScaffolds.map((anchor) => ` - \`${anchor}\``));
804
+ }
631
805
  if (repository.manifests.length > 0) {
632
806
  lines.push('- manifests:');
633
807
  lines.push(...repository.manifests.map((manifest) => ` - \`${manifest}\``));
634
808
  }
809
+ if (repository.ssealedScaffold) {
810
+ lines.push(...renderSsealedScaffoldSummary(repository.ssealedScaffold));
811
+ }
635
812
  if (repository.commandAdapters.length > 0) {
636
813
  lines.push('- command adapters:');
637
814
  lines.push(...repository.commandAdapters.map((adapter) => ` - \`${adapter}\``));
@@ -640,6 +817,18 @@ function renderNestedRepositories(nestedRepositories) {
640
817
  lines.push('- editing policies:');
641
818
  lines.push(...repository.editingPolicies.map((policy) => ` - \`${policy}\``));
642
819
  }
820
+ if (repository.validationGuides.length > 0) {
821
+ lines.push('- validation guides:');
822
+ lines.push(...repository.validationGuides.map((guide) => ` - \`${guide}\``));
823
+ }
824
+ if (repository.diagrams.length > 0) {
825
+ lines.push('- diagrams:');
826
+ lines.push(...repository.diagrams.map((diagram) => ` - \`${diagram}\``));
827
+ }
828
+ if (repository.githubTemplates.length > 0) {
829
+ lines.push('- GitHub templates:');
830
+ lines.push(...repository.githubTemplates.map((template) => ` - \`${template}\``));
831
+ }
643
832
  for (const document of repository.rootDocuments) {
644
833
  lines.push(`- ${document.label}: \`${document.relativePath}\``);
645
834
  }
@@ -664,6 +853,10 @@ function countNestedEntrypoints(repository) {
664
853
  ...repository.manifests,
665
854
  ...repository.commandAdapters,
666
855
  ...repository.editingPolicies,
856
+ ...repository.agentScaffolds,
857
+ ...repository.validationGuides,
858
+ ...repository.diagrams,
859
+ ...repository.githubTemplates,
667
860
  ].filter(Boolean).length;
668
861
  }
669
862
  function renderSourceQuality(gitLsFilesStatus) {
@@ -736,7 +929,7 @@ export function generateRepoMap(projectRoot, options = {}) {
736
929
  '## How To Use',
737
930
  '',
738
931
  '- Start with `AGENTS.md` and the mustflow files listed in Priority Anchors.',
739
- '- Use Directory Anchors to find local rules, guides, package manifests, and command adapters.',
932
+ '- Use Directory Anchors to find local rules, guides, scaffold routers, package manifests, and command adapters.',
740
933
  ...(nestedRepositories.length > 0
741
934
  ? ['- Use Nested Repositories only as entrypoints into independent repositories.']
742
935
  : []),
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "mustflow",
3
- "version": "2.108.8",
3
+ "version": "2.112.1",
4
4
  "description": "Agent workflow documents and CLI for mustflow repository roots.",
5
5
  "type": "module",
6
6
  "license": "MIT-0",
@@ -77,13 +77,13 @@
77
77
  "workflow"
78
78
  ],
79
79
  "devDependencies": {
80
- "@types/node": "^25.8.0",
80
+ "@types/node": "^25.9.4",
81
81
  "@types/sql.js": "^1.4.11",
82
82
  "fast-check": "^4.8.0",
83
83
  "typescript": "^6.0.3"
84
84
  },
85
85
  "dependencies": {
86
- "smol-toml": "^1.6.1",
86
+ "smol-toml": "^1.7.0",
87
87
  "sql.js": "^1.14.1"
88
88
  }
89
89
  }
@@ -10,8 +10,8 @@ status_values = ["current", "stale", "needs_review", "missing"]
10
10
  [documents."agents.root"]
11
11
  source = "locales/en/AGENTS.md"
12
12
  source_locale = "en"
13
- revision = 17
14
- translations.ko = { path = "locales/ko/AGENTS.md", source_revision = 17, status = "current" }
13
+ revision = 18
14
+ translations.ko = { path = "locales/ko/AGENTS.md", source_revision = 18, status = "current" }
15
15
  translations.zh = { path = "locales/zh/AGENTS.md", source_revision = 11, status = "needs_review" }
16
16
  translations.es = { path = "locales/es/AGENTS.md", source_revision = 11, status = "needs_review" }
17
17
  translations.fr = { path = "locales/fr/AGENTS.md", source_revision = 11, status = "needs_review" }
@@ -62,7 +62,7 @@ translations = {}
62
62
  [documents."skills.index"]
63
63
  source = "locales/en/.mustflow/skills/INDEX.md"
64
64
  source_locale = "en"
65
- revision = 214
65
+ revision = 217
66
66
  translations = {}
67
67
 
68
68
  [documents."skill.adapter-boundary"]
@@ -544,6 +544,18 @@ source_locale = "en"
544
544
  revision = 1
545
545
  translations = {}
546
546
 
547
+ [documents."skill.clickhouse-code-change"]
548
+ source = "locales/en/.mustflow/skills/clickhouse-code-change/SKILL.md"
549
+ source_locale = "en"
550
+ revision = 1
551
+ translations = {}
552
+
553
+ [documents."skill.duckdb-code-change"]
554
+ source = "locales/en/.mustflow/skills/duckdb-code-change/SKILL.md"
555
+ source_locale = "en"
556
+ revision = 1
557
+ translations = {}
558
+
547
559
  [documents."skill.search-index-integrity-review"]
548
560
  source = "locales/en/.mustflow/skills/search-index-integrity-review/SKILL.md"
549
561
  source_locale = "en"
@@ -583,7 +595,7 @@ translations = {}
583
595
  [documents."skill.version-freshness-check"]
584
596
  source = "locales/en/.mustflow/skills/version-freshness-check/SKILL.md"
585
597
  source_locale = "en"
586
- revision = 9
598
+ revision = 10
587
599
  translations = {}
588
600
 
589
601
  [documents."skill.line-ending-hygiene"]
@@ -748,6 +760,12 @@ source_locale = "en"
748
760
  revision = 3
749
761
  translations = {}
750
762
 
763
+ [documents."skill.java-code-change"]
764
+ source = "locales/en/.mustflow/skills/java-code-change/SKILL.md"
765
+ source_locale = "en"
766
+ revision = 3
767
+ translations = {}
768
+
751
769
  [documents."skill.node-code-change"]
752
770
  source = "locales/en/.mustflow/skills/node-code-change/SKILL.md"
753
771
  source_locale = "en"
@@ -808,6 +826,12 @@ source_locale = "en"
808
826
  revision = 1
809
827
  translations = {}
810
828
 
829
+ [documents."skill.technology-stack-selection"]
830
+ source = "locales/en/.mustflow/skills/technology-stack-selection/SKILL.md"
831
+ source_locale = "en"
832
+ revision = 1
833
+ translations = {}
834
+
811
835
  [documents."skill.structure-first-engineering"]
812
836
  source = "locales/en/.mustflow/skills/structure-first-engineering/SKILL.md"
813
837
  source_locale = "en"
@@ -958,6 +982,18 @@ source_locale = "en"
958
982
  revision = 3
959
983
  translations = {}
960
984
 
985
+ [documents."skill.writing-elegance"]
986
+ source = "locales/en/.mustflow/skills/writing-elegance/SKILL.md"
987
+ source_locale = "en"
988
+ revision = 1
989
+ translations = {}
990
+
991
+ [documents."skill.writing-elegance.phrase-bank"]
992
+ source = "locales/en/.mustflow/skills/writing-elegance/references/phrase-bank.md"
993
+ source_locale = "en"
994
+ revision = 1
995
+ translations = {}
996
+
961
997
  [documents."skill.failure-triage"]
962
998
  source = "locales/en/.mustflow/skills/failure-triage/SKILL.md"
963
999
  source_locale = "en"