mustflow 2.112.3 → 2.112.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 CHANGED
@@ -272,6 +272,7 @@ mf run mustflow_update_apply
272
272
  | `mf workspace scan` | Scan a `projects/` directory for nested repositories without requiring workspace configuration or granting command authority. |
273
273
  | `mf workspace status` | Inspect configured workspace roots and nested repository contract readiness without granting parent-to-child command authority. |
274
274
  | `mf workspace command-catalog` | Aggregate per-repository command intent availability with safe `mf run` entrypoints and no raw command strings. |
275
+ | `mf workspace command-fragments` | Suggest repo-level `.mustflow/config/commands/*.toml` fragments for repo-farm orchestration without writing files or granting parent-to-child command authority. |
275
276
  | `mf workspace verify --changed --plan-only` | Aggregate per-repository changed-file verification plans without running commands or granting parent-to-child command authority. |
276
277
  | `mf doctor` | Inspect the current mustflow root without writing files. |
277
278
  | `mf api workspace-summary --json` | Print a stable, read-only JSON summary for coding agents and external harnesses. |
@@ -13,6 +13,7 @@ const DEFAULT_WORKSPACE_SCAN_ROOT = 'projects';
13
13
  const WORKSPACE_SCAN_SCHEMA_VERSION = '1';
14
14
  const WORKSPACE_STATUS_SCHEMA_VERSION = '1';
15
15
  const WORKSPACE_COMMAND_CATALOG_SCHEMA_VERSION = '1';
16
+ const WORKSPACE_COMMAND_FRAGMENTS_SCHEMA_VERSION = '1';
16
17
  const WORKSPACE_VERIFICATION_PLAN_SCHEMA_VERSION = '1';
17
18
  const WORKSPACE_SCAN_OPTIONS = [
18
19
  { name: '--json', kind: 'boolean' },
@@ -20,11 +21,17 @@ const WORKSPACE_SCAN_OPTIONS = [
20
21
  ];
21
22
  const WORKSPACE_STATUS_OPTIONS = [{ name: '--json', kind: 'boolean' }];
22
23
  const WORKSPACE_COMMAND_CATALOG_OPTIONS = [{ name: '--json', kind: 'boolean' }];
24
+ const WORKSPACE_COMMAND_FRAGMENTS_OPTIONS = [
25
+ { name: '--json', kind: 'boolean' },
26
+ { name: '--projects-dir', kind: 'string' },
27
+ ];
23
28
  const WORKSPACE_VERIFY_OPTIONS = [
24
29
  { name: '--changed', kind: 'boolean' },
25
30
  { name: '--plan-only', kind: 'boolean' },
26
31
  { name: '--json', kind: 'boolean' },
27
32
  ];
33
+ const COMMAND_FRAGMENT_DIRECTORY = '.mustflow/config/commands';
34
+ const COMMAND_FRAGMENT_INCLUDE_PREFIX = 'commands';
28
35
  function getWorkspaceHelp(lang = 'en') {
29
36
  return renderHelp({
30
37
  usage: 'mf workspace <action> [options]',
@@ -33,6 +40,7 @@ function getWorkspaceHelp(lang = 'en') {
33
40
  { label: 'scan', description: t(lang, 'workspace.help.action.scan') },
34
41
  { label: 'status', description: t(lang, 'workspace.help.action.status') },
35
42
  { label: 'command-catalog', description: t(lang, 'workspace.help.action.commandCatalog') },
43
+ { label: 'command-fragments', description: t(lang, 'workspace.help.action.commandFragments') },
36
44
  { label: 'verify', description: t(lang, 'workspace.help.action.verify') },
37
45
  ],
38
46
  options: [
@@ -47,6 +55,7 @@ function getWorkspaceHelp(lang = 'en') {
47
55
  'mf workspace scan --projects-dir projects --json',
48
56
  'mf workspace status --json',
49
57
  'mf workspace command-catalog --json',
58
+ 'mf workspace command-fragments --json',
50
59
  'mf workspace verify --changed --plan-only --json',
51
60
  ],
52
61
  exitCodes: [
@@ -73,6 +82,14 @@ function createWorkspaceVerificationPlanPolicy() {
73
82
  selected_intents_run_via: 'mf run <intent>',
74
83
  };
75
84
  }
85
+ function createWorkspaceCommandFragmentsPolicy() {
86
+ return {
87
+ ...createWorkspaceStatusPolicy(),
88
+ writes_files: false,
89
+ suggestions_are_review_only: true,
90
+ parent_fragments_grant_child_authority: false,
91
+ };
92
+ }
76
93
  function createAdHocWorkspaceConfig(base, projectsDir) {
77
94
  return {
78
95
  ...base,
@@ -80,6 +97,101 @@ function createAdHocWorkspaceConfig(base, projectsDir) {
80
97
  roots: [projectsDir],
81
98
  };
82
99
  }
100
+ function slugCommandFragmentSegment(segment) {
101
+ const slug = segment
102
+ .trim()
103
+ .toLowerCase()
104
+ .replace(/[^a-z0-9._-]+/gu, '-')
105
+ .replace(/^-+|-+$/gu, '')
106
+ .replace(/\.toml$/u, '');
107
+ return slug.length > 0 ? slug : 'repository';
108
+ }
109
+ function repositoryPathSegments(repositoryPath) {
110
+ return repositoryPath.split('/').filter((segment) => segment.length > 0);
111
+ }
112
+ function createCommandFragmentPaths(repositories) {
113
+ const leafSlugCounts = new Map();
114
+ for (const repository of repositories) {
115
+ const segments = repositoryPathSegments(repository.relative_path);
116
+ const leafSlug = slugCommandFragmentSegment(segments.at(-1) ?? repository.relative_path);
117
+ leafSlugCounts.set(leafSlug, (leafSlugCounts.get(leafSlug) ?? 0) + 1);
118
+ }
119
+ const usedSlugs = new Set();
120
+ const paths = new Map();
121
+ for (const repository of repositories) {
122
+ const segments = repositoryPathSegments(repository.relative_path);
123
+ const leafSlug = slugCommandFragmentSegment(segments.at(-1) ?? repository.relative_path);
124
+ const baseSlug = (leafSlugCounts.get(leafSlug) ?? 0) > 1
125
+ ? segments.map((segment) => slugCommandFragmentSegment(segment)).join('--')
126
+ : leafSlug;
127
+ let candidateSlug = baseSlug;
128
+ let suffix = 2;
129
+ while (usedSlugs.has(candidateSlug)) {
130
+ candidateSlug = `${baseSlug}-${suffix}`;
131
+ suffix += 1;
132
+ }
133
+ usedSlugs.add(candidateSlug);
134
+ paths.set(repository.relative_path, `${COMMAND_FRAGMENT_INCLUDE_PREFIX}/${candidateSlug}.toml`);
135
+ }
136
+ return paths;
137
+ }
138
+ function createCommandFragmentGuidance(repository) {
139
+ if (repository.status === 'mustflow_ready') {
140
+ return [
141
+ 'Prefer the child repository command contract for commands owned by this repository.',
142
+ 'Use the parent command fragment only for intentionally parent-owned orchestration or cross-repository workflows.',
143
+ ];
144
+ }
145
+ if (repository.status === 'contract_invalid') {
146
+ return [
147
+ 'Fix the child repository command contract before copying or mirroring any intent shape.',
148
+ 'Keep the parent command fragment empty or review-only until the child contract parses cleanly.',
149
+ ];
150
+ }
151
+ return [
152
+ 'Initialize or author this repository command contract before adding runnable parent-level orchestration.',
153
+ 'If the parent root still needs orchestration, keep that repository-specific intent group in the suggested fragment.',
154
+ ];
155
+ }
156
+ function createCommandFragmentSuggestion(repository, includeEntry) {
157
+ const commandSurface = repository.command_contract;
158
+ return {
159
+ repository: repository.relative_path,
160
+ status: repository.status === 'mustflow_ready'
161
+ ? 'child_contract_ready'
162
+ : repository.status === 'contract_invalid'
163
+ ? 'contract_invalid'
164
+ : 'contract_missing',
165
+ suggested_fragment_path: `.mustflow/config/${includeEntry}`,
166
+ include_entry: includeEntry,
167
+ source_command_contract: commandSurface.path,
168
+ intent_count: commandSurface.total_intents,
169
+ runnable_intent_count: commandSurface.runnable_count,
170
+ guidance: createCommandFragmentGuidance(repository),
171
+ };
172
+ }
173
+ function renderCommandFragmentIncludeSnippet(includeEntries) {
174
+ if (includeEntries.length === 0) {
175
+ return '[include]\nfiles = []';
176
+ }
177
+ return [
178
+ '[include]',
179
+ 'files = [',
180
+ ...includeEntries.map((entry) => ` "${entry}",`),
181
+ ']',
182
+ ].join('\n');
183
+ }
184
+ function commandFragmentNextActions(repositoryCount) {
185
+ if (repositoryCount === 0) {
186
+ return ['Run mf workspace scan --projects-dir <dir> --json against the directory that contains cloned repositories.'];
187
+ }
188
+ return [
189
+ 'Review each suggested fragment before editing .mustflow/config/commands.toml.',
190
+ 'Prefer child repository command contracts for repository-owned commands.',
191
+ 'Use parent command fragments only for intentionally parent-owned orchestration or cross-repository workflows.',
192
+ 'After accepting fragments, run the configured mustflow check intent.',
193
+ ];
194
+ }
83
195
  function getIntentNames(intents) {
84
196
  return Object.keys(intents).sort((left, right) => left.localeCompare(right));
85
197
  }
@@ -345,6 +457,36 @@ function createWorkspaceCommandCatalogOutput() {
345
457
  issues: createWorkspaceIssues(config, repositories.length),
346
458
  };
347
459
  }
460
+ function createWorkspaceCommandFragmentsOutput(projectsDir) {
461
+ const projectRoot = resolveMustflowRoot();
462
+ const config = getRepoMapConfig(projectRoot);
463
+ const workspace = projectsDir ? createAdHocWorkspaceConfig(config.workspace, projectsDir) : config.workspace;
464
+ const nestedRepositories = discoverNestedRepositories(projectRoot, { ...config.map, includeNested: true }, workspace);
465
+ const repositories = nestedRepositories.map((repository) => summarizeRepository(projectRoot, repository));
466
+ const includePaths = createCommandFragmentPaths(repositories);
467
+ const suggestions = repositories.map((repository) => createCommandFragmentSuggestion(repository, includePaths.get(repository.relative_path) ?? `${COMMAND_FRAGMENT_INCLUDE_PREFIX}/repository.toml`));
468
+ const includeEntries = suggestions.map((suggestion) => suggestion.include_entry);
469
+ const issues = projectsDir
470
+ ? repositories.length === 0
471
+ ? [t('en', 'workspace.scan.issue.noneDiscovered', { projectsDir })]
472
+ : []
473
+ : createWorkspaceIssues(config, repositories.length);
474
+ return {
475
+ schema_version: WORKSPACE_COMMAND_FRAGMENTS_SCHEMA_VERSION,
476
+ command: 'workspace command-fragments',
477
+ mustflow_root: projectRoot,
478
+ workspace: workspaceConfigOutput(workspace),
479
+ policy: createWorkspaceCommandFragmentsPolicy(),
480
+ repository_count: repositories.length,
481
+ fragment_directory: COMMAND_FRAGMENT_DIRECTORY,
482
+ root_command_contract: '.mustflow/config/commands.toml',
483
+ root_include_snippet: renderCommandFragmentIncludeSnippet(includeEntries),
484
+ suggestions,
485
+ issues,
486
+ projects_dir: projectsDir ?? null,
487
+ next_actions: commandFragmentNextActions(repositories.length),
488
+ };
489
+ }
348
490
  function createUnavailableVerificationRepository(repository, commandSurface, status, classification, issue) {
349
491
  return {
350
492
  relative_path: repository.relativePath,
@@ -527,6 +669,37 @@ function renderWorkspaceCommandCatalog(output) {
527
669
  }
528
670
  return lines.join('\n');
529
671
  }
672
+ function renderWorkspaceCommandFragments(output) {
673
+ const lines = [
674
+ 'mustflow workspace command-fragments',
675
+ `mustflow root: ${output.mustflow_root}`,
676
+ `workspace enabled: ${output.workspace.enabled ? 'yes' : 'no'}`,
677
+ `repositories: ${output.repository_count}`,
678
+ `fragment directory: ${output.fragment_directory}`,
679
+ '',
680
+ ];
681
+ if (output.suggestions.length === 0) {
682
+ lines.push('No nested repositories discovered.');
683
+ return lines.join('\n');
684
+ }
685
+ lines.push('Root include snippet:');
686
+ lines.push(output.root_include_snippet);
687
+ lines.push('', 'Suggested fragments:');
688
+ for (const suggestion of output.suggestions) {
689
+ lines.push(`- ${suggestion.repository} -> ${suggestion.suggested_fragment_path} (${suggestion.status})`);
690
+ if (suggestion.source_command_contract) {
691
+ lines.push(` source command contract: ${suggestion.source_command_contract}`);
692
+ }
693
+ for (const guidance of suggestion.guidance) {
694
+ lines.push(` - ${guidance}`);
695
+ }
696
+ }
697
+ lines.push('', 'Next actions:');
698
+ for (const action of output.next_actions) {
699
+ lines.push(`- ${action}`);
700
+ }
701
+ return lines.join('\n');
702
+ }
530
703
  function renderWorkspaceVerificationPlan(output) {
531
704
  const lines = [
532
705
  'mustflow workspace verify',
@@ -603,6 +776,22 @@ function runWorkspaceCommandCatalog(args, reporter, lang) {
603
776
  reporter.stdout(hasParsedCliOption(parsed, '--json') ? JSON.stringify(output, null, 2) : renderWorkspaceCommandCatalog(output));
604
777
  return 0;
605
778
  }
779
+ function runWorkspaceCommandFragments(args, reporter, lang) {
780
+ if (hasCliOptionToken(args, '--help', ['-h'])) {
781
+ reporter.stdout(getWorkspaceHelp(lang));
782
+ return 0;
783
+ }
784
+ const parsed = parseCliOptions(args, WORKSPACE_COMMAND_FRAGMENTS_OPTIONS);
785
+ if (parsed.error) {
786
+ printUsageError(reporter, formatCliOptionParseError(parsed.error, lang), 'mf workspace --help', getWorkspaceHelp(lang), lang);
787
+ return 1;
788
+ }
789
+ const projectsDirValue = parsed.values.get('--projects-dir');
790
+ const projectsDir = typeof projectsDirValue === 'string' ? projectsDirValue : undefined;
791
+ const output = createWorkspaceCommandFragmentsOutput(projectsDir);
792
+ reporter.stdout(hasParsedCliOption(parsed, '--json') ? JSON.stringify(output, null, 2) : renderWorkspaceCommandFragments(output));
793
+ return 0;
794
+ }
606
795
  function runWorkspaceVerify(args, reporter, lang) {
607
796
  if (hasCliOptionToken(args, '--help', ['-h'])) {
608
797
  reporter.stdout(getWorkspaceHelp(lang));
@@ -648,6 +837,9 @@ export function runWorkspace(args, reporter, lang = 'en') {
648
837
  if (action === 'command-catalog') {
649
838
  return runWorkspaceCommandCatalog(rest, reporter, lang);
650
839
  }
840
+ if (action === 'command-fragments') {
841
+ return runWorkspaceCommandFragments(rest, reporter, lang);
842
+ }
651
843
  if (action === 'verify') {
652
844
  return runWorkspaceVerify(rest, reporter, lang);
653
845
  }
@@ -138,10 +138,11 @@ export const enMessages = {
138
138
  "workspace.help.action.scan": "Scan a projects directory for nested repositories without requiring workspace configuration",
139
139
  "workspace.help.action.status": "Print discovered nested repositories and their local mustflow contract status",
140
140
  "workspace.help.action.commandCatalog": "Print per-repository command intent availability without raw command strings",
141
+ "workspace.help.action.commandFragments": "Suggest per-repository command fragment files for repo-farm orchestration without writing files",
141
142
  "workspace.help.action.verify": "Print per-repository changed-file verification plans without running commands",
142
143
  "workspace.help.option.projectsDir": "Select the child directory to scan; default: projects",
143
144
  "workspace.help.exit.ok": "Workspace status was inspected",
144
- "workspace.error.missingAction": "Specify a workspace action: scan, status, command-catalog, or verify",
145
+ "workspace.error.missingAction": "Specify a workspace action: scan, status, command-catalog, command-fragments, or verify",
145
146
  "workspace.error.unknownAction": "Unknown workspace action: {action}",
146
147
  "workspace.error.verifyRequiresChanged": "workspace verify requires --changed",
147
148
  "workspace.error.verifyRequiresPlanOnly": "workspace verify requires --plan-only",
@@ -138,10 +138,11 @@ export const esMessages = {
138
138
  "workspace.help.action.scan": "Escanea un directorio projects en busca de repositorios anidados sin requerir configuración de workspace",
139
139
  "workspace.help.action.status": "Imprime repositorios anidados descubiertos y su estado de contrato mustflow local",
140
140
  "workspace.help.action.commandCatalog": "Imprime disponibilidad de intents por repositorio sin cadenas de comando sin procesar",
141
+ "workspace.help.action.commandFragments": "Sugiere archivos command fragment por repositorio para orquestación repo-farm sin escribir archivos",
141
142
  "workspace.help.action.verify": "Imprime planes de verificación de cambios por repositorio sin ejecutar comandos",
142
143
  "workspace.help.option.projectsDir": "Selecciona el directorio hijo que se escaneará; predeterminado: projects",
143
144
  "workspace.help.exit.ok": "Se inspeccionó el estado del workspace",
144
- "workspace.error.missingAction": "Especifica una acción workspace: scan, status, command-catalog o verify",
145
+ "workspace.error.missingAction": "Especifica una acción workspace: scan, status, command-catalog, command-fragments o verify",
145
146
  "workspace.error.unknownAction": "Acción workspace desconocida: {action}",
146
147
  "workspace.error.verifyRequiresChanged": "workspace verify requiere --changed",
147
148
  "workspace.error.verifyRequiresPlanOnly": "workspace verify requiere --plan-only",
@@ -138,10 +138,11 @@ export const frMessages = {
138
138
  "workspace.help.action.scan": "Scanne un répertoire projects pour trouver des dépôts imbriqués sans exiger de configuration workspace",
139
139
  "workspace.help.action.status": "Affiche les dépôts imbriqués découverts et leur état de contrat mustflow local",
140
140
  "workspace.help.action.commandCatalog": "Affiche la disponibilité des intents par dépôt sans chaînes de commande brutes",
141
+ "workspace.help.action.commandFragments": "Suggère des fichiers command fragment par dépôt pour l'orchestration repo-farm sans écrire de fichiers",
141
142
  "workspace.help.action.verify": "Affiche les plans de vérification des changements par dépôt sans exécuter de commandes",
142
143
  "workspace.help.option.projectsDir": "Sélectionne le répertoire enfant à scanner ; par défaut : projects",
143
144
  "workspace.help.exit.ok": "L'état du workspace a été inspecté",
144
- "workspace.error.missingAction": "Indiquez une action workspace : scan, status, command-catalog ou verify",
145
+ "workspace.error.missingAction": "Indiquez une action workspace : scan, status, command-catalog, command-fragments ou verify",
145
146
  "workspace.error.unknownAction": "Action workspace inconnue : {action}",
146
147
  "workspace.error.verifyRequiresChanged": "workspace verify nécessite --changed",
147
148
  "workspace.error.verifyRequiresPlanOnly": "workspace verify nécessite --plan-only",
@@ -138,10 +138,11 @@ export const hiMessages = {
138
138
  "workspace.help.action.scan": "workspace configuration के बिना projects directory में nested repositories scan करें",
139
139
  "workspace.help.action.status": "discovered nested repositories और उनके local mustflow contract status प्रिंट करें",
140
140
  "workspace.help.action.commandCatalog": "raw command strings के बिना per-repository command intent availability प्रिंट करें",
141
+ "workspace.help.action.commandFragments": "files लिखे बिना repo-farm orchestration के लिए per-repository command fragment files suggest करें",
141
142
  "workspace.help.action.verify": "commands चलाए बिना per-repository changed-file verification plans प्रिंट करें",
142
143
  "workspace.help.option.projectsDir": "scan की जाने वाली child directory चुनें; default: projects",
143
144
  "workspace.help.exit.ok": "Workspace status inspect हुआ",
144
- "workspace.error.missingAction": "workspace action बताएँ: scan, status, command-catalog या verify",
145
+ "workspace.error.missingAction": "workspace action बताएँ: scan, status, command-catalog, command-fragments या verify",
145
146
  "workspace.error.unknownAction": "अज्ञात workspace action: {action}",
146
147
  "workspace.error.verifyRequiresChanged": "workspace verify के लिए --changed चाहिए",
147
148
  "workspace.error.verifyRequiresPlanOnly": "workspace verify के लिए --plan-only चाहिए",
@@ -138,10 +138,11 @@ export const koMessages = {
138
138
  "workspace.help.action.scan": "workspace 설정 없이 projects 디렉터리의 nested repository를 스캔합니다",
139
139
  "workspace.help.action.status": "발견된 nested repository와 각 로컬 mustflow 계약 상태를 출력합니다",
140
140
  "workspace.help.action.commandCatalog": "raw command string 없이 repository별 command intent 사용 가능 상태를 출력합니다",
141
+ "workspace.help.action.commandFragments": "파일을 쓰지 않고 repo farm orchestration용 repository별 command fragment 파일을 제안합니다",
141
142
  "workspace.help.action.verify": "명령을 실행하지 않고 repository별 changed-file verification plan을 출력합니다",
142
143
  "workspace.help.option.projectsDir": "스캔할 하위 디렉터리를 지정합니다. 기본값: projects",
143
144
  "workspace.help.exit.ok": "workspace 상태를 확인했습니다",
144
- "workspace.error.missingAction": "workspace 작업을 지정하세요: scan, status, command-catalog 또는 verify",
145
+ "workspace.error.missingAction": "workspace 작업을 지정하세요: scan, status, command-catalog, command-fragments 또는 verify",
145
146
  "workspace.error.unknownAction": "알 수 없는 workspace 작업: {action}",
146
147
  "workspace.error.verifyRequiresChanged": "workspace verify에는 --changed가 필요합니다",
147
148
  "workspace.error.verifyRequiresPlanOnly": "workspace verify에는 --plan-only가 필요합니다",
@@ -138,10 +138,11 @@ export const zhMessages = {
138
138
  "workspace.help.action.scan": "无需 workspace 配置即可扫描 projects 目录中的嵌套仓库",
139
139
  "workspace.help.action.status": "输出发现的嵌套仓库及其本地 mustflow 合同状态",
140
140
  "workspace.help.action.commandCatalog": "输出各仓库的命令 intent 可用性,不包含原始命令字符串",
141
+ "workspace.help.action.commandFragments": "建议按仓库拆分的 command fragment 文件,不写入文件",
141
142
  "workspace.help.action.verify": "输出各仓库的变更文件验证计划,但不运行命令",
142
143
  "workspace.help.option.projectsDir": "选择要扫描的子目录;默认值:projects",
143
144
  "workspace.help.exit.ok": "已检查 workspace 状态",
144
- "workspace.error.missingAction": "请指定 workspace 操作:scan、status、command-catalog 或 verify",
145
+ "workspace.error.missingAction": "请指定 workspace 操作:scan、status、command-catalog、command-fragments 或 verify",
145
146
  "workspace.error.unknownAction": "未知 workspace 操作:{action}",
146
147
  "workspace.error.verifyRequiresChanged": "workspace verify 需要 --changed",
147
148
  "workspace.error.verifyRequiresPlanOnly": "workspace verify 需要 --plan-only",
@@ -175,6 +175,14 @@ const PUBLIC_JSON_SCHEMA_CONTRACTS = [
175
175
  documented: true,
176
176
  installedCommand: ['mf', 'workspace', 'command-catalog', '--json'],
177
177
  },
178
+ {
179
+ id: 'workspace-command-fragments',
180
+ schemaFile: 'workspace-command-fragments.schema.json',
181
+ producer: 'mf workspace command-fragments --json',
182
+ packaged: true,
183
+ documented: true,
184
+ installedCommand: ['mf', 'workspace', 'command-fragments', '--json'],
185
+ },
178
186
  {
179
187
  id: 'workspace-verification-plan',
180
188
  schemaFile: 'workspace-verification-plan.schema.json',
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "mustflow",
3
- "version": "2.112.3",
3
+ "version": "2.112.7",
4
4
  "description": "Agent workflow documents and CLI for mustflow repository roots.",
5
5
  "type": "module",
6
6
  "license": "MIT-0",
package/schemas/README.md CHANGED
@@ -45,6 +45,9 @@ Current schemas:
45
45
  - `workspace-command-catalog.schema.json`: output of `mf workspace command-catalog --json`,
46
46
  containing per-root command intent availability, safe `mf run` entrypoints, and no raw command
47
47
  strings
48
+ - `workspace-command-fragments.schema.json`: output of `mf workspace command-fragments --json`,
49
+ containing read-only per-repository command fragment suggestions for repo-farm orchestration
50
+ without writing files or granting parent-to-child command authority
48
51
  - `workspace-verification-plan.schema.json`: output of
49
52
  `mf workspace verify --changed --plan-only --json`, containing per-root changed-file
50
53
  verification plans and risk-priced evidence assessment without running commands or granting
@@ -0,0 +1,121 @@
1
+ {
2
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
3
+ "$id": "https://mustflow.github.io/schemas/workspace-command-fragments.schema.json",
4
+ "title": "mustflow workspace command fragments report",
5
+ "type": "object",
6
+ "additionalProperties": false,
7
+ "required": [
8
+ "schema_version",
9
+ "command",
10
+ "mustflow_root",
11
+ "workspace",
12
+ "policy",
13
+ "repository_count",
14
+ "fragment_directory",
15
+ "root_command_contract",
16
+ "root_include_snippet",
17
+ "suggestions",
18
+ "issues",
19
+ "projects_dir",
20
+ "next_actions"
21
+ ],
22
+ "properties": {
23
+ "schema_version": { "const": "1" },
24
+ "command": { "const": "workspace command-fragments" },
25
+ "mustflow_root": { "type": "string" },
26
+ "workspace": { "$ref": "#/$defs/workspace" },
27
+ "policy": { "$ref": "#/$defs/policy" },
28
+ "repository_count": { "type": "integer", "minimum": 0 },
29
+ "fragment_directory": { "const": ".mustflow/config/commands" },
30
+ "root_command_contract": { "const": ".mustflow/config/commands.toml" },
31
+ "root_include_snippet": { "type": "string" },
32
+ "suggestions": {
33
+ "type": "array",
34
+ "items": { "$ref": "#/$defs/suggestion" }
35
+ },
36
+ "issues": { "$ref": "#/$defs/stringArray" },
37
+ "projects_dir": { "type": ["string", "null"] },
38
+ "next_actions": { "$ref": "#/$defs/stringArray" }
39
+ },
40
+ "$defs": {
41
+ "stringArray": {
42
+ "type": "array",
43
+ "items": { "type": "string" }
44
+ },
45
+ "nullableString": {
46
+ "type": ["string", "null"]
47
+ },
48
+ "workspace": {
49
+ "type": "object",
50
+ "additionalProperties": false,
51
+ "required": [
52
+ "enabled",
53
+ "roots",
54
+ "max_depth",
55
+ "max_repositories",
56
+ "follow_symlinks",
57
+ "stop_at_repository_root"
58
+ ],
59
+ "properties": {
60
+ "enabled": { "type": "boolean" },
61
+ "roots": { "$ref": "#/$defs/stringArray" },
62
+ "max_depth": { "type": "integer", "minimum": 1 },
63
+ "max_repositories": { "type": "integer", "minimum": 1 },
64
+ "follow_symlinks": { "type": "boolean" },
65
+ "stop_at_repository_root": { "type": "boolean" }
66
+ }
67
+ },
68
+ "policy": {
69
+ "type": "object",
70
+ "additionalProperties": false,
71
+ "required": [
72
+ "mode",
73
+ "grants_command_authority",
74
+ "parent_root_grants_child_authority",
75
+ "command_authority_per_root",
76
+ "run_entrypoint_per_root",
77
+ "executes_commands",
78
+ "raw_commands_included",
79
+ "writes_files",
80
+ "suggestions_are_review_only",
81
+ "parent_fragments_grant_child_authority"
82
+ ],
83
+ "properties": {
84
+ "mode": { "const": "read_only" },
85
+ "grants_command_authority": { "const": false },
86
+ "parent_root_grants_child_authority": { "const": false },
87
+ "command_authority_per_root": { "const": ".mustflow/config/commands.toml" },
88
+ "run_entrypoint_per_root": { "const": "mf run <intent>" },
89
+ "executes_commands": { "const": false },
90
+ "raw_commands_included": { "const": false },
91
+ "writes_files": { "const": false },
92
+ "suggestions_are_review_only": { "const": true },
93
+ "parent_fragments_grant_child_authority": { "const": false }
94
+ }
95
+ },
96
+ "suggestion": {
97
+ "type": "object",
98
+ "additionalProperties": false,
99
+ "required": [
100
+ "repository",
101
+ "status",
102
+ "suggested_fragment_path",
103
+ "include_entry",
104
+ "source_command_contract",
105
+ "intent_count",
106
+ "runnable_intent_count",
107
+ "guidance"
108
+ ],
109
+ "properties": {
110
+ "repository": { "type": "string" },
111
+ "status": { "enum": ["child_contract_ready", "contract_missing", "contract_invalid"] },
112
+ "suggested_fragment_path": { "type": "string" },
113
+ "include_entry": { "type": "string" },
114
+ "source_command_contract": { "$ref": "#/$defs/nullableString" },
115
+ "intent_count": { "type": ["integer", "null"], "minimum": 0 },
116
+ "runnable_intent_count": { "type": ["integer", "null"], "minimum": 0 },
117
+ "guidance": { "$ref": "#/$defs/stringArray" }
118
+ }
119
+ }
120
+ }
121
+ }
@@ -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 = 18
14
- translations.ko = { path = "locales/ko/AGENTS.md", source_revision = 18, status = "current" }
13
+ revision = 20
14
+ translations.ko = { path = "locales/ko/AGENTS.md", source_revision = 20, 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 = 217
65
+ revision = 220
66
66
  translations = {}
67
67
 
68
68
  [documents."skill.adapter-boundary"]
@@ -137,10 +137,16 @@ source_locale = "en"
137
137
  revision = 2
138
138
  translations = {}
139
139
 
140
+ [documents."skill.abstraction-boundary-review"]
141
+ source = "locales/en/.mustflow/skills/abstraction-boundary-review/SKILL.md"
142
+ source_locale = "en"
143
+ revision = 3
144
+ translations = {}
145
+
140
146
  [documents."skill.module-boundary-review"]
141
147
  source = "locales/en/.mustflow/skills/module-boundary-review/SKILL.md"
142
148
  source_locale = "en"
143
- revision = 2
149
+ revision = 3
144
150
  translations = {}
145
151
 
146
152
  [documents."skill.change-blast-radius-review"]