mustflow 2.74.4 → 2.74.6

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.
@@ -9,6 +9,7 @@ import { listActiveRunLocks } from '../../core/active-run-locks.js';
9
9
  import { createChangeVerificationReport, } from '../../core/change-verification.js';
10
10
  import { createComplexityBudgetReport, } from '../../core/complexity-budget.js';
11
11
  import { readUtf8FileInsideWithoutSymlinks } from '../../core/safe-filesystem.js';
12
+ import { createScriptPackSuggestionReport, } from '../../core/script-pack-suggestions.js';
12
13
  import { createVerificationPlanId } from '../../core/verification-plan-id.js';
13
14
  import { printUsageError, renderHelp } from '../lib/cli-output.js';
14
15
  import { hasCliOptionToken } from '../lib/option-parser.js';
@@ -18,6 +19,7 @@ import { readGitChangedFiles } from '../lib/git-changes.js';
18
19
  import { t } from '../lib/i18n.js';
19
20
  import { resolveMustflowRoot } from '../lib/project-root.js';
20
21
  import { createRunPlan } from '../lib/run-plan.js';
22
+ import { listScriptPackScripts } from '../lib/script-pack-registry.js';
21
23
  import { checkMustflowProjectReport } from '../lib/validation.js';
22
24
  const API_WORKSPACE_SUMMARY_SCHEMA_VERSION = '1';
23
25
  const API_COMMAND_CATALOG_SCHEMA_VERSION = '1';
@@ -411,6 +413,39 @@ function toVerificationPlanTestSelection(report) {
411
413
  note: report.test_selection.notes[0] ?? null,
412
414
  };
413
415
  }
416
+ function createEmptyScriptPackSuggestions() {
417
+ return {
418
+ status: 'empty',
419
+ input: {
420
+ phases: [],
421
+ skills: [],
422
+ paths: [],
423
+ changed: false,
424
+ },
425
+ analyzed_paths: [],
426
+ suggestions: [],
427
+ issues: [],
428
+ };
429
+ }
430
+ function createApiScriptPackSuggestions(mustflowRoot, classification) {
431
+ if (!classification || classification.files.length === 0) {
432
+ return createEmptyScriptPackSuggestions();
433
+ }
434
+ const report = createScriptPackSuggestionReport(mustflowRoot, {
435
+ changed: false,
436
+ phases: ['after_change', 'review'],
437
+ skills: [],
438
+ paths: classification.files,
439
+ scripts: listScriptPackScripts(),
440
+ });
441
+ return {
442
+ status: report.status,
443
+ input: report.input,
444
+ analyzed_paths: report.analyzed_paths,
445
+ suggestions: report.suggestions,
446
+ issues: report.issues,
447
+ };
448
+ }
414
449
  function createUnavailableVerificationPlanOutput(mustflowRoot, classification, issue) {
415
450
  return {
416
451
  schema_version: API_VERIFICATION_PLAN_SCHEMA_VERSION,
@@ -426,6 +461,7 @@ function createUnavailableVerificationPlanOutput(mustflowRoot, classification, i
426
461
  risk_assessment: null,
427
462
  schedule: null,
428
463
  test_selection: null,
464
+ script_pack_suggestions: createApiScriptPackSuggestions(mustflowRoot, classification),
429
465
  execution_policy: createVerificationPlanExecutionPolicy(),
430
466
  issues: [issue],
431
467
  };
@@ -484,6 +520,7 @@ function createVerificationPlanOutput() {
484
520
  risk_assessment: report.risk_assessment,
485
521
  schedule: toVerificationPlanSchedule(report),
486
522
  test_selection: toVerificationPlanTestSelection(report),
523
+ script_pack_suggestions: createApiScriptPackSuggestions(mustflowRoot, classification),
487
524
  execution_policy: createVerificationPlanExecutionPolicy(),
488
525
  issues: [],
489
526
  };
@@ -2,12 +2,14 @@ import { createClassifyOutput } from './classify.js';
2
2
  import { createChangeVerificationReport, } from '../../core/change-verification.js';
3
3
  import { isRecord, readCommandContract, } from '../../core/config-loading.js';
4
4
  import { createVerificationPlanId } from '../../core/verification-plan-id.js';
5
+ import { createScriptPackSuggestionReport, } from '../../core/script-pack-suggestions.js';
5
6
  import { printUsageError, renderHelp } from '../lib/cli-output.js';
6
7
  import { getAgentContext } from '../lib/agent-context.js';
7
8
  import { t } from '../lib/i18n.js';
8
9
  import { formatCliOptionParseError, hasCliOptionToken, hasParsedCliOption, parseCliOptions, } from '../lib/option-parser.js';
9
10
  import { resolveMustflowRoot } from '../lib/project-root.js';
10
11
  import { createRunPlan } from '../lib/run-plan.js';
12
+ import { listScriptPackScripts } from '../lib/script-pack-registry.js';
11
13
  import { checkMustflowProjectReport } from '../lib/validation.js';
12
14
  const NEXT_SCHEMA_VERSION = '1';
13
15
  const COMMAND_AUTHORITY = '.mustflow/config/commands.toml';
@@ -65,6 +67,7 @@ function toOutput(input) {
65
67
  blockers: input.blockers ?? [],
66
68
  warnings: input.warnings ?? [],
67
69
  gaps: input.gaps ?? [],
70
+ script_pack_suggestions: input.scriptPackSuggestions ?? createEmptyScriptPackSuggestions(),
68
71
  verification_plan_id: input.verificationPlanId ?? null,
69
72
  };
70
73
  }
@@ -82,6 +85,39 @@ function toNextGap(gap) {
82
85
  detail: gap.detail,
83
86
  };
84
87
  }
88
+ function createEmptyScriptPackSuggestions() {
89
+ return {
90
+ status: 'empty',
91
+ input: {
92
+ phases: [],
93
+ skills: [],
94
+ paths: [],
95
+ changed: false,
96
+ },
97
+ analyzed_paths: [],
98
+ suggestions: [],
99
+ issues: [],
100
+ };
101
+ }
102
+ function createNextScriptPackSuggestions(mustflowRoot, classification) {
103
+ if (classification.files.length === 0) {
104
+ return createEmptyScriptPackSuggestions();
105
+ }
106
+ const report = createScriptPackSuggestionReport(mustflowRoot, {
107
+ changed: false,
108
+ phases: ['after_change', 'review'],
109
+ skills: [],
110
+ paths: classification.files,
111
+ scripts: listScriptPackScripts(),
112
+ });
113
+ return {
114
+ status: report.status,
115
+ input: report.input,
116
+ analyzed_paths: report.analyzed_paths,
117
+ suggestions: report.suggestions,
118
+ issues: report.issues,
119
+ };
120
+ }
85
121
  function runnableIntentCommand(mustflowRoot, contract, intentName) {
86
122
  const rawIntent = contract.intents[intentName];
87
123
  if (!isRecord(rawIntent)) {
@@ -100,6 +136,7 @@ function createChangedOutput(mustflowRoot, contract, classification, report) {
100
136
  const intents = selectedIntents(report);
101
137
  const gaps = report.gaps.map(toNextGap);
102
138
  const verificationPlanId = createVerificationPlanId(report, contract);
139
+ const scriptPackSuggestions = createNextScriptPackSuggestions(mustflowRoot, classification);
103
140
  const state = createState({
104
141
  installed: true,
105
142
  check_ok: true,
@@ -120,6 +157,7 @@ function createChangedOutput(mustflowRoot, contract, classification, report) {
120
157
  recommendedCommands: [...fallbackCommands(mustflowRoot, contract), ...(intents.length > 0 ? ['mf verify --changed --json'] : [])],
121
158
  blockers: gaps.map((gap) => gap.detail),
122
159
  gaps,
160
+ scriptPackSuggestions,
123
161
  verificationPlanId,
124
162
  });
125
163
  }
@@ -130,6 +168,7 @@ function createChangedOutput(mustflowRoot, contract, classification, report) {
130
168
  state,
131
169
  decision: action('verify', 'mf verify --changed --json', 'Run configured verification', 'Changed files have runnable configured verification intents. Use mustflow verification instead of direct commands.'),
132
170
  recommendedCommands: ['mf api verification-plan --changed --json', 'mf verify --changed --json'],
171
+ scriptPackSuggestions,
133
172
  verificationPlanId,
134
173
  });
135
174
  }
@@ -139,6 +178,7 @@ function createChangedOutput(mustflowRoot, contract, classification, report) {
139
178
  state,
140
179
  decision: action('inspect', 'mf api verification-plan --changed --json', 'Inspect verification plan', 'No runnable verification entries were selected.'),
141
180
  recommendedCommands: ['mf api verification-plan --changed --json'],
181
+ scriptPackSuggestions,
142
182
  verificationPlanId,
143
183
  });
144
184
  }
@@ -272,6 +312,16 @@ function renderNextOutput(output, lang) {
272
312
  lines.push(`- ${warning}`);
273
313
  }
274
314
  }
315
+ if (output.script_pack_suggestions.suggestions.length > 0 || output.script_pack_suggestions.issues.length > 0) {
316
+ lines.push('', t(lang, 'scriptPack.suggest.label.recommendations'));
317
+ for (const suggestion of output.script_pack_suggestions.suggestions) {
318
+ lines.push(`- ${suggestion.script_ref}: ${suggestion.confidence}, score ${suggestion.score}`);
319
+ lines.push(` ${t(lang, 'scriptPack.suggest.label.runHint')}: ${suggestion.run_hint}`);
320
+ }
321
+ for (const issue of output.script_pack_suggestions.issues) {
322
+ lines.push(`- ${issue}`);
323
+ }
324
+ }
275
325
  lines.push('', t(lang, 'next.section.commands'));
276
326
  for (const command of output.recommended_commands) {
277
327
  lines.push(`- ${command}`);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "mustflow",
3
- "version": "2.74.4",
3
+ "version": "2.74.6",
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
@@ -11,7 +11,8 @@ Current schemas:
11
11
  - `workspace-summary.schema.json`: output of `mf api workspace-summary --json`
12
12
  - `command-catalog.schema.json`: output of `mf api command-catalog --json`
13
13
  - `verification-plan.schema.json`: output of `mf api verification-plan --changed --json`, including
14
- risk-priced evidence assessment for the changed surfaces and selected command contract
14
+ risk-priced evidence assessment for the changed surfaces, selected command contract, and optional
15
+ read-only script-pack helper suggestions
15
16
  - `latest-evidence.schema.json`: output of `mf api latest-evidence --json`
16
17
  - `diff-risk.schema.json`: output of `mf api diff-risk --changed --json`, including a read-only
17
18
  complexity budget for structural additions
@@ -29,7 +30,8 @@ Current schemas:
29
30
  - `onboard-commands-report.schema.json`: output of `mf onboard commands --json`, containing
30
31
  review-only command-intent suggestions that do not grant command authority or write files
31
32
  - `next-report.schema.json`: output of `mf next --json`, containing the next safe action,
32
- changed-file verification gaps, and read-only command recommendations
33
+ changed-file verification gaps, read-only command recommendations, and optional read-only
34
+ script-pack helper suggestions
33
35
  - `evidence-report.schema.json`: output of `mf evidence --changed --json`, containing verification
34
36
  requirements, risk-priced evidence assessment, latest bounded evidence, failure replay capsules,
35
37
  conflict ledgers, receipts, remaining risks, and gaps without running commands
@@ -116,6 +116,146 @@
116
116
  }
117
117
  }
118
118
  },
119
+ "script_pack_suggestions": {
120
+ "type": "object",
121
+ "additionalProperties": false,
122
+ "required": ["status", "input", "analyzed_paths", "suggestions", "issues"],
123
+ "properties": {
124
+ "status": { "type": "string", "enum": ["suggested", "empty", "partial"] },
125
+ "input": { "$ref": "#/$defs/scriptPackSuggestionInput" },
126
+ "analyzed_paths": {
127
+ "type": "array",
128
+ "items": { "$ref": "#/$defs/scriptPackAnalyzedPath" }
129
+ },
130
+ "suggestions": {
131
+ "type": "array",
132
+ "items": { "$ref": "#/$defs/scriptPackSuggestion" }
133
+ },
134
+ "issues": {
135
+ "type": "array",
136
+ "items": { "type": "string" }
137
+ }
138
+ }
139
+ },
119
140
  "verification_plan_id": { "type": ["string", "null"] }
141
+ },
142
+ "$defs": {
143
+ "scriptPackPhase": {
144
+ "type": "string",
145
+ "enum": ["before_change", "during_change", "after_change", "review"]
146
+ },
147
+ "scriptPackSurface": {
148
+ "type": "string",
149
+ "enum": [
150
+ "config",
151
+ "docs",
152
+ "generated",
153
+ "package",
154
+ "schema",
155
+ "skill",
156
+ "source",
157
+ "template",
158
+ "test",
159
+ "unknown"
160
+ ]
161
+ },
162
+ "scriptPackSuggestionInput": {
163
+ "type": "object",
164
+ "additionalProperties": false,
165
+ "required": ["phases", "skills", "paths", "changed"],
166
+ "properties": {
167
+ "phases": {
168
+ "type": "array",
169
+ "items": { "$ref": "#/$defs/scriptPackPhase" }
170
+ },
171
+ "skills": {
172
+ "type": "array",
173
+ "items": { "type": "string", "pattern": "^[a-z0-9]+(?:-[a-z0-9]+)*$" }
174
+ },
175
+ "paths": {
176
+ "type": "array",
177
+ "items": { "type": "string" }
178
+ },
179
+ "changed": { "type": "boolean" }
180
+ }
181
+ },
182
+ "scriptPackAnalyzedPath": {
183
+ "type": "object",
184
+ "additionalProperties": false,
185
+ "required": ["path", "surfaces"],
186
+ "properties": {
187
+ "path": { "type": "string" },
188
+ "surfaces": {
189
+ "type": "array",
190
+ "items": { "$ref": "#/$defs/scriptPackSurface" },
191
+ "minItems": 1
192
+ }
193
+ }
194
+ },
195
+ "scriptPackSuggestion": {
196
+ "type": "object",
197
+ "additionalProperties": false,
198
+ "required": [
199
+ "script_ref",
200
+ "score",
201
+ "confidence",
202
+ "usage",
203
+ "phases",
204
+ "matched_phases",
205
+ "matched_skills",
206
+ "matched_surfaces",
207
+ "reasons",
208
+ "read_only",
209
+ "mutates",
210
+ "network",
211
+ "risk_level",
212
+ "cost",
213
+ "report_schema_file",
214
+ "run_hint"
215
+ ],
216
+ "properties": {
217
+ "script_ref": {
218
+ "type": "string",
219
+ "pattern": "^[a-z0-9]+(?:-[a-z0-9]+)*/[a-z0-9]+(?:-[a-z0-9]+)*$"
220
+ },
221
+ "score": { "type": "integer", "minimum": 0 },
222
+ "confidence": { "type": "string", "enum": ["low", "medium", "high"] },
223
+ "usage": { "type": "string" },
224
+ "phases": {
225
+ "type": "array",
226
+ "items": { "$ref": "#/$defs/scriptPackPhase" },
227
+ "minItems": 1
228
+ },
229
+ "matched_phases": {
230
+ "type": "array",
231
+ "items": { "$ref": "#/$defs/scriptPackPhase" }
232
+ },
233
+ "matched_skills": {
234
+ "type": "array",
235
+ "items": { "type": "string", "pattern": "^[a-z0-9]+(?:-[a-z0-9]+)*$" }
236
+ },
237
+ "matched_surfaces": {
238
+ "type": "array",
239
+ "items": { "$ref": "#/$defs/scriptPackSurface" }
240
+ },
241
+ "reasons": {
242
+ "type": "array",
243
+ "items": { "type": "string" },
244
+ "minItems": 1
245
+ },
246
+ "read_only": { "type": "boolean" },
247
+ "mutates": { "type": "boolean" },
248
+ "network": { "type": "boolean" },
249
+ "risk_level": { "type": "string", "enum": ["low", "medium", "high"] },
250
+ "cost": { "type": "string", "enum": ["low", "medium", "high"] },
251
+ "report_schema_file": {
252
+ "anyOf": [
253
+ { "type": "string", "pattern": "^[a-z0-9-]+\\.schema\\.json$" },
254
+ { "type": "null" }
255
+ ]
256
+ },
257
+ "run_hint": { "type": "string" }
258
+ }
259
+ }
120
260
  }
121
261
  }
@@ -66,6 +66,27 @@
66
66
  { "$ref": "#/$defs/testSelection" }
67
67
  ]
68
68
  },
69
+ "script_pack_suggestions": {
70
+ "type": "object",
71
+ "additionalProperties": false,
72
+ "required": ["status", "input", "analyzed_paths", "suggestions", "issues"],
73
+ "properties": {
74
+ "status": { "type": "string", "enum": ["suggested", "empty", "partial"] },
75
+ "input": { "$ref": "#/$defs/scriptPackSuggestionInput" },
76
+ "analyzed_paths": {
77
+ "type": "array",
78
+ "items": { "$ref": "#/$defs/scriptPackAnalyzedPath" }
79
+ },
80
+ "suggestions": {
81
+ "type": "array",
82
+ "items": { "$ref": "#/$defs/scriptPackSuggestion" }
83
+ },
84
+ "issues": {
85
+ "type": "array",
86
+ "items": { "type": "string" }
87
+ }
88
+ }
89
+ },
69
90
  "execution_policy": { "$ref": "#/$defs/executionPolicy" },
70
91
  "issues": {
71
92
  "type": "array",
@@ -86,6 +107,123 @@
86
107
  "type": "array",
87
108
  "items": { "type": "string" }
88
109
  },
110
+ "scriptPackPhase": {
111
+ "type": "string",
112
+ "enum": ["before_change", "during_change", "after_change", "review"]
113
+ },
114
+ "scriptPackSurface": {
115
+ "type": "string",
116
+ "enum": [
117
+ "config",
118
+ "docs",
119
+ "generated",
120
+ "package",
121
+ "schema",
122
+ "skill",
123
+ "source",
124
+ "template",
125
+ "test",
126
+ "unknown"
127
+ ]
128
+ },
129
+ "scriptPackSuggestionInput": {
130
+ "type": "object",
131
+ "additionalProperties": false,
132
+ "required": ["phases", "skills", "paths", "changed"],
133
+ "properties": {
134
+ "phases": {
135
+ "type": "array",
136
+ "items": { "$ref": "#/$defs/scriptPackPhase" }
137
+ },
138
+ "skills": {
139
+ "type": "array",
140
+ "items": { "type": "string", "pattern": "^[a-z0-9]+(?:-[a-z0-9]+)*$" }
141
+ },
142
+ "paths": {
143
+ "type": "array",
144
+ "items": { "type": "string" }
145
+ },
146
+ "changed": { "type": "boolean" }
147
+ }
148
+ },
149
+ "scriptPackAnalyzedPath": {
150
+ "type": "object",
151
+ "additionalProperties": false,
152
+ "required": ["path", "surfaces"],
153
+ "properties": {
154
+ "path": { "type": "string" },
155
+ "surfaces": {
156
+ "type": "array",
157
+ "items": { "$ref": "#/$defs/scriptPackSurface" },
158
+ "minItems": 1
159
+ }
160
+ }
161
+ },
162
+ "scriptPackSuggestion": {
163
+ "type": "object",
164
+ "additionalProperties": false,
165
+ "required": [
166
+ "script_ref",
167
+ "score",
168
+ "confidence",
169
+ "usage",
170
+ "phases",
171
+ "matched_phases",
172
+ "matched_skills",
173
+ "matched_surfaces",
174
+ "reasons",
175
+ "read_only",
176
+ "mutates",
177
+ "network",
178
+ "risk_level",
179
+ "cost",
180
+ "report_schema_file",
181
+ "run_hint"
182
+ ],
183
+ "properties": {
184
+ "script_ref": {
185
+ "type": "string",
186
+ "pattern": "^[a-z0-9]+(?:-[a-z0-9]+)*/[a-z0-9]+(?:-[a-z0-9]+)*$"
187
+ },
188
+ "score": { "type": "integer", "minimum": 0 },
189
+ "confidence": { "type": "string", "enum": ["low", "medium", "high"] },
190
+ "usage": { "type": "string" },
191
+ "phases": {
192
+ "type": "array",
193
+ "items": { "$ref": "#/$defs/scriptPackPhase" },
194
+ "minItems": 1
195
+ },
196
+ "matched_phases": {
197
+ "type": "array",
198
+ "items": { "$ref": "#/$defs/scriptPackPhase" }
199
+ },
200
+ "matched_skills": {
201
+ "type": "array",
202
+ "items": { "type": "string", "pattern": "^[a-z0-9]+(?:-[a-z0-9]+)*$" }
203
+ },
204
+ "matched_surfaces": {
205
+ "type": "array",
206
+ "items": { "$ref": "#/$defs/scriptPackSurface" }
207
+ },
208
+ "reasons": {
209
+ "type": "array",
210
+ "items": { "type": "string" },
211
+ "minItems": 1
212
+ },
213
+ "read_only": { "type": "boolean" },
214
+ "mutates": { "type": "boolean" },
215
+ "network": { "type": "boolean" },
216
+ "risk_level": { "type": "string", "enum": ["low", "medium", "high"] },
217
+ "cost": { "type": "string", "enum": ["low", "medium", "high"] },
218
+ "report_schema_file": {
219
+ "anyOf": [
220
+ { "type": "string", "pattern": "^[a-z0-9-]+\\.schema\\.json$" },
221
+ { "type": "null" }
222
+ ]
223
+ },
224
+ "run_hint": { "type": "string" }
225
+ }
226
+ },
89
227
  "classification": {
90
228
  "type": "object",
91
229
  "additionalProperties": false,
@@ -1,6 +1,6 @@
1
1
  id = "default"
2
2
  name = "default"
3
- version = "2.74.4"
3
+ version = "2.74.6"
4
4
  description = "Minimal workflow for LLM agents to read, edit, and verify their work in a repository."
5
5
  common_root = "common"
6
6
  locales_root = "locales"