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.
- package/dist/cli/lib/repo-map-frontmatter.js +18 -0
- package/dist/cli/lib/repo-map.js +204 -11
- package/package.json +3 -3
- package/templates/default/i18n.toml +40 -4
- package/templates/default/locales/en/.mustflow/skills/INDEX.md +13 -2
- package/templates/default/locales/en/.mustflow/skills/clickhouse-code-change/SKILL.md +266 -0
- package/templates/default/locales/en/.mustflow/skills/duckdb-code-change/SKILL.md +284 -0
- package/templates/default/locales/en/.mustflow/skills/java-code-change/SKILL.md +499 -0
- package/templates/default/locales/en/.mustflow/skills/routes.toml +30 -0
- package/templates/default/locales/en/.mustflow/skills/technology-stack-selection/SKILL.md +328 -0
- package/templates/default/locales/en/.mustflow/skills/version-freshness-check/SKILL.md +16 -10
- package/templates/default/locales/en/.mustflow/skills/writing-elegance/SKILL.md +193 -0
- package/templates/default/locales/en/.mustflow/skills/writing-elegance/references/phrase-bank.md +302 -0
- package/templates/default/locales/en/AGENTS.md +10 -1
- package/templates/default/locales/ko/AGENTS.md +7 -1
- package/templates/default/manifest.toml +35 -1
|
@@ -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
|
};
|
package/dist/cli/lib/repo-map.js
CHANGED
|
@@ -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([
|
|
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
|
|
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 =
|
|
507
|
-
.filter(
|
|
641
|
+
const manifests = discoveredAnchors
|
|
642
|
+
.filter(isManifestAnchor)
|
|
508
643
|
.map((anchorFile) => `${relativeRoot}${anchorFile}`);
|
|
509
|
-
const commandAdapters =
|
|
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 =
|
|
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 =
|
|
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 =
|
|
522
|
-
.filter(
|
|
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.
|
|
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.
|
|
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.
|
|
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 =
|
|
14
|
-
translations.ko = { path = "locales/ko/AGENTS.md", source_revision =
|
|
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 =
|
|
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 =
|
|
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"
|