mustflow 1.17.0 → 1.18.14
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 +17 -7
- package/dist/cli/commands/context.js +2 -2
- package/dist/cli/commands/dashboard.js +61 -7
- package/dist/cli/commands/explain.js +47 -7
- package/dist/cli/commands/index.js +9 -2
- package/dist/cli/commands/run.js +7 -15
- package/dist/cli/commands/verify.js +44 -9
- package/dist/cli/i18n/en.js +3 -0
- package/dist/cli/i18n/es.js +3 -0
- package/dist/cli/i18n/fr.js +3 -0
- package/dist/cli/i18n/hi.js +3 -0
- package/dist/cli/i18n/ko.js +3 -0
- package/dist/cli/i18n/zh.js +3 -0
- package/dist/cli/lib/agent-context.js +19 -4
- package/dist/cli/lib/dashboard-html.js +41 -0
- package/dist/cli/lib/dashboard-locale.js +2 -0
- package/dist/cli/lib/local-index.js +910 -32
- package/dist/core/change-classification.js +33 -60
- package/dist/core/command-classification.js +0 -2
- package/dist/core/source-anchor-status.js +4 -4
- package/dist/core/source-anchor-validation.js +2 -6
- package/dist/core/source-anchors.js +81 -3
- package/package.json +1 -1
- package/schemas/change-verification-report.schema.json +194 -0
- package/schemas/context-report.schema.json +30 -2
- package/schemas/explain-report.schema.json +191 -0
- package/templates/default/i18n.toml +20 -10
- package/templates/default/locales/en/.mustflow/docs/agent-workflow.md +4 -3
- package/templates/default/locales/en/.mustflow/skills/INDEX.md +2 -1
- package/templates/default/locales/en/.mustflow/skills/database-change-safety/SKILL.md +155 -0
- package/templates/default/locales/en/AGENTS.md +10 -10
- package/templates/default/locales/es/.mustflow/skills/INDEX.md +2 -1
- package/templates/default/locales/es/.mustflow/skills/database-change-safety/SKILL.md +155 -0
- package/templates/default/locales/fr/.mustflow/skills/INDEX.md +2 -1
- package/templates/default/locales/fr/.mustflow/skills/database-change-safety/SKILL.md +155 -0
- package/templates/default/locales/hi/.mustflow/skills/INDEX.md +2 -1
- package/templates/default/locales/hi/.mustflow/skills/database-change-safety/SKILL.md +155 -0
- package/templates/default/locales/ko/.mustflow/docs/agent-workflow.md +3 -3
- package/templates/default/locales/ko/.mustflow/skills/INDEX.md +2 -1
- package/templates/default/locales/ko/.mustflow/skills/database-change-safety/SKILL.md +155 -0
- package/templates/default/locales/ko/AGENTS.md +2 -2
- package/templates/default/locales/zh/.mustflow/skills/INDEX.md +2 -1
- package/templates/default/locales/zh/.mustflow/skills/database-change-safety/SKILL.md +155 -0
- package/templates/default/manifest.toml +7 -1
package/README.md
CHANGED
|
@@ -55,7 +55,7 @@ flowchart TD
|
|
|
55
55
|
|
|
56
56
|
`read_order` defines the required reading sequence, while `optional_read_order` and `[context]` control how task-specific context loads. The `[refresh]` policy sets when agents reread the same instructions.
|
|
57
57
|
|
|
58
|
-
The skills index acts as an active routing step: agents compare the task with `.mustflow/skills/INDEX.md` and read matching `SKILL.md` files before editing that scope. This step is required before file edits even when `mf doctor` or `mf check` passes, because health checks do not decide which task procedure applies. Skills guide procedure only; command execution still comes from `.mustflow/config/commands.toml`.
|
|
58
|
+
The skills index acts as an active routing step: agents compare the task with `.mustflow/skills/INDEX.md` and read matching `SKILL.md` files before editing that scope. This step is required before file edits even when `mf doctor` or `mf check` passes, because health checks do not decide which task procedure applies. When files are created or modified, the final report should include a concise skill-selection note. Skills guide procedure only; command execution still comes from `.mustflow/config/commands.toml`.
|
|
59
59
|
|
|
60
60
|
## Quick start
|
|
61
61
|
|
|
@@ -91,11 +91,11 @@ mustflow installs and validates an agent workflow for user projects.
|
|
|
91
91
|
- Declares runnable command rules in `.mustflow/config/commands.toml`.
|
|
92
92
|
- Checks installation health and configuration structure with `mf check` and `mf doctor`.
|
|
93
93
|
- Classifies changed files, public surfaces, and validation reasons with `mf classify`.
|
|
94
|
-
- Prints execution-free verification plans with `mf verify --plan-only --json
|
|
94
|
+
- Prints execution-free verification plans with `mf verify --plan-only --json`, including read-only local-index lock explanations when available.
|
|
95
95
|
- Runs only allowed one-shot commands within a timeout via `mf run <intent>` or `mf verify` when the selected intent is runnable.
|
|
96
96
|
- Writes command receipts to `.mustflow/state/runs/latest.json`.
|
|
97
97
|
- Generates a concise repository navigation map, `REPO_MAP.md`, with `mf map`.
|
|
98
|
-
- Indexes and searches mustflow docs, skills, skill routes, command rules, command-effect locks, and opt-in source anchor metadata with SQLite via `mf index` and `mf search`. The local SQLite file is a rebuildable lookup cache, not a memory store, audit log, command transcript store, or source-content database.
|
|
98
|
+
- Indexes and searches mustflow docs, skills, skill routes, command rules, command-effect locks, file fingerprints, and opt-in source anchor metadata with SQLite via `mf index` and `mf search`. The local SQLite file is a rebuildable lookup cache, not a memory store, audit log, command transcript store, or source-content database.
|
|
99
99
|
- Tracks agent-created or agent-modified documentation needing prose review with `mf docs review`.
|
|
100
100
|
- Previews and applies bundled template updates safely with `mf update`.
|
|
101
101
|
- Publishes JSON Schemas for automation-facing reports and command contracts in `schemas/`.
|
|
@@ -145,6 +145,8 @@ your-project/
|
|
|
145
145
|
│ └─ SKILL.md
|
|
146
146
|
├─ date-number-audit/
|
|
147
147
|
│ └─ SKILL.md
|
|
148
|
+
├─ database-change-safety/
|
|
149
|
+
│ └─ SKILL.md
|
|
148
150
|
├─ dependency-reality-check/
|
|
149
151
|
│ └─ SKILL.md
|
|
150
152
|
├─ diff-risk-review/
|
|
@@ -217,7 +219,8 @@ npx mf verify --from-plan .mustflow/state/change-plan.json --plan-only --json
|
|
|
217
219
|
npx mf verify --from-plan .mustflow/state/change-plan.json --json
|
|
218
220
|
```
|
|
219
221
|
|
|
220
|
-
Create the optional local search index if search capabilities are needed.
|
|
222
|
+
Create the optional local search index if search capabilities are needed. Run the normal command
|
|
223
|
+
when creating the index for the first time.
|
|
221
224
|
|
|
222
225
|
```sh
|
|
223
226
|
npx mf index --dry-run --json
|
|
@@ -225,6 +228,13 @@ npx mf index
|
|
|
225
228
|
npx mf search mustflow_check
|
|
226
229
|
```
|
|
227
230
|
|
|
231
|
+
On later runs, use incremental mode when you want to reuse a compatible fresh cache without rewriting
|
|
232
|
+
the SQLite file. If the cache is missing, stale, or incompatible, mustflow falls back to a full rebuild.
|
|
233
|
+
|
|
234
|
+
```sh
|
|
235
|
+
npx mf index --incremental --json
|
|
236
|
+
```
|
|
237
|
+
|
|
228
238
|
Preview template updates before applying them. Files marked as customized in `.mustflow/config/manifest.lock.toml` remain as repository-specific baselines while their current content matches the lock.
|
|
229
239
|
|
|
230
240
|
```sh
|
|
@@ -261,7 +271,7 @@ mf run mustflow_update_apply
|
|
|
261
271
|
| `mf map --stdout` | Print the current mustflow root map to stdout. |
|
|
262
272
|
| `mf map --write` | Create or update `REPO_MAP.md`. |
|
|
263
273
|
| `mf run <intent>` | Run an allowed one-shot command. |
|
|
264
|
-
| `mf index` | Build a SQLite index for mustflow docs, skill routes, command rules,
|
|
274
|
+
| `mf index` | Build a SQLite index for mustflow docs, skill routes, command rules, command-effect locks, and file fingerprints. Use `--incremental` to reuse a compatible fresh index without rewriting it. |
|
|
265
275
|
| `mf search <query>` | Search docs, skills, skill routes, command rules, and command-effect locks in the SQLite index. |
|
|
266
276
|
| `mf status` | Inspect installed state and changed or missing files. |
|
|
267
277
|
| `mf update --dry-run` | Calculate a template update plan without writing files. |
|
|
@@ -294,7 +304,7 @@ Runnable work is declared in `.mustflow/config/commands.toml` so agents do not g
|
|
|
294
304
|
|
|
295
305
|
Development servers, watch modes, browser UIs, interactive commands, and background processes do not run directly.
|
|
296
306
|
|
|
297
|
-
Use `mf verify --reason <event> --plan-only --json` to inspect matching verification intents and missing runnable coverage without executing commands.
|
|
307
|
+
Use `mf verify --reason <event> --plan-only --json` to inspect matching verification intents and missing runnable coverage without executing commands. When `.mustflow/cache/mustflow.sqlite` is fresh, scheduled entries include read-only `effectGraph` metadata for write locks and lock conflicts.
|
|
298
308
|
|
|
299
309
|
Each command run writes the latest run record to `.mustflow/state/runs/latest.json`. The record includes the intent name, working directory, timeout, exit code, timeout status, and the tail of stdout and stderr.
|
|
300
310
|
|
|
@@ -379,7 +389,7 @@ mf run docs_validate
|
|
|
379
389
|
mf run mustflow_check
|
|
380
390
|
```
|
|
381
391
|
|
|
382
|
-
The Bun scripts remain available for human maintainers and release packaging. `test_fast` runs the fast CLI regression baseline, `test_related` selects tests from changed files and falls back to the fast baseline, and `test_release` keeps package metadata and packaging checks out of routine local edits. `test_coverage` runs the fast CLI baseline through Node's built-in coverage report with no enforced threshold; set `MUSTFLOW_TEST_COVERAGE_CONCURRENCY=1`, `2`, or another positive integer to adjust worker count
|
|
392
|
+
The Bun scripts remain available for human maintainers and release packaging. `test_fast` runs the fast CLI regression baseline, `test_related` selects tests from changed files and falls back to the fast baseline, and both use 8 Node test workers by default. Set `MUSTFLOW_TEST_CONCURRENCY=1`, `2`, or another positive integer to tune those workers on local machines. `test_release` keeps package metadata and packaging checks out of routine local edits. `test_coverage` runs the fast CLI baseline through Node's built-in coverage report with no enforced threshold; set `MUSTFLOW_TEST_COVERAGE_CONCURRENCY=1`, `2`, or another positive integer to adjust its worker count. `lint` and test-audit are configured as narrow repository-local gates. `docs_validate_fast` checks documentation navigation and localized content links without building the entire static site; `docs_validate` performs the full static documentation build, search index, and sitemap gate for release-sensitive changes.
|
|
383
393
|
|
|
384
394
|
`dist/` is a generated build output and is not committed. `npm pack` and `npm publish` run `npm run build` via `prepack`, so the npm package contains the built CLI.
|
|
385
395
|
|
|
@@ -42,7 +42,7 @@ function parseCacheProfile(args) {
|
|
|
42
42
|
}
|
|
43
43
|
return { profile: value, error: null };
|
|
44
44
|
}
|
|
45
|
-
export function runContext(args, reporter, lang = 'en') {
|
|
45
|
+
export async function runContext(args, reporter, lang = 'en') {
|
|
46
46
|
if (args.includes('--help') || args.includes('-h')) {
|
|
47
47
|
reporter.stdout(getContextHelp(lang));
|
|
48
48
|
return 0;
|
|
@@ -77,7 +77,7 @@ export function runContext(args, reporter, lang = 'en') {
|
|
|
77
77
|
const mustflowRoot = resolveMustflowRoot();
|
|
78
78
|
if (args.includes('--json')) {
|
|
79
79
|
if (cacheProfile.profile) {
|
|
80
|
-
reporter.stdout(JSON.stringify(getPromptCacheProfileContext(mustflowRoot, cacheProfile.profile), null, 2));
|
|
80
|
+
reporter.stdout(JSON.stringify(await getPromptCacheProfileContext(mustflowRoot, cacheProfile.profile), null, 2));
|
|
81
81
|
return 0;
|
|
82
82
|
}
|
|
83
83
|
const context = getAgentContext(mustflowRoot);
|
|
@@ -4,7 +4,7 @@ import http from 'node:http';
|
|
|
4
4
|
import path from 'node:path';
|
|
5
5
|
import { openPathInFileManager, openUrlInBrowser } from '../lib/browser-open.js';
|
|
6
6
|
import { printUsageError, renderHelp } from '../lib/cli-output.js';
|
|
7
|
-
import { renderDashboardHtml } from '../lib/dashboard-html.js';
|
|
7
|
+
import { renderDashboardHtml, } from '../lib/dashboard-html.js';
|
|
8
8
|
import { DASHBOARD_VERIFICATION_MAX_FILE_MATCHES, createDashboardVerificationSnapshot, } from '../../core/dashboard-verification.js';
|
|
9
9
|
import { parseSkillIndexRoutes } from '../../core/skill-route-alignment.js';
|
|
10
10
|
import { getAgentContext } from '../lib/agent-context.js';
|
|
@@ -13,6 +13,7 @@ import { isRecord, readCommandContract, readPositiveInteger, readString, readStr
|
|
|
13
13
|
import { readDashboardPreferences, updateDashboardPreferences, } from '../lib/dashboard-preferences.js';
|
|
14
14
|
import { DOC_REVIEW_LEDGER_RELATIVE_PATH, isDocReviewStatus, isReviewerKind, listDocReviewEntries, markDocReviewEntry, } from '../lib/doc-review-ledger.js';
|
|
15
15
|
import { inspectManifestLock } from '../lib/manifest-lock.js';
|
|
16
|
+
import { readLocalCommandEffectGraphs } from '../lib/local-index.js';
|
|
16
17
|
import { readPackageMetadata } from '../lib/package-info.js';
|
|
17
18
|
import { t } from '../lib/i18n.js';
|
|
18
19
|
import { resolveMustflowRoot } from '../lib/project-root.js';
|
|
@@ -278,7 +279,55 @@ function readDashboardCommandContract(projectRoot) {
|
|
|
278
279
|
return null;
|
|
279
280
|
}
|
|
280
281
|
}
|
|
281
|
-
function
|
|
282
|
+
function toDashboardCommandEffectGraphStatus(graph) {
|
|
283
|
+
return {
|
|
284
|
+
source: graph.source,
|
|
285
|
+
status: graph.status,
|
|
286
|
+
database_path: graph.databasePath,
|
|
287
|
+
index_fresh: graph.indexFresh,
|
|
288
|
+
stale_paths: graph.stalePaths,
|
|
289
|
+
refresh_hint: graph.refreshHint,
|
|
290
|
+
};
|
|
291
|
+
}
|
|
292
|
+
function toDashboardCommandEffectGraph(graph) {
|
|
293
|
+
return {
|
|
294
|
+
...toDashboardCommandEffectGraphStatus(graph),
|
|
295
|
+
write_locks: graph.writeLocks.map((writeLock) => ({
|
|
296
|
+
lock: writeLock.lock,
|
|
297
|
+
paths: writeLock.paths,
|
|
298
|
+
modes: writeLock.modes,
|
|
299
|
+
sources: writeLock.sources,
|
|
300
|
+
concurrencies: writeLock.concurrencies,
|
|
301
|
+
effect_count: writeLock.effectCount,
|
|
302
|
+
})),
|
|
303
|
+
lock_conflicts: graph.lockConflicts.map((conflict) => ({
|
|
304
|
+
intent: conflict.intent,
|
|
305
|
+
lock: conflict.lock,
|
|
306
|
+
paths: conflict.paths,
|
|
307
|
+
modes: conflict.modes,
|
|
308
|
+
concurrencies: conflict.concurrencies,
|
|
309
|
+
conflicting_paths: conflict.conflictingPaths,
|
|
310
|
+
conflicting_modes: conflict.conflictingModes,
|
|
311
|
+
conflicting_concurrencies: conflict.conflictingConcurrencies,
|
|
312
|
+
})),
|
|
313
|
+
};
|
|
314
|
+
}
|
|
315
|
+
async function readCommandEffectGraphMap(projectRoot, intentNames) {
|
|
316
|
+
if (intentNames.length === 0) {
|
|
317
|
+
return { graphs: new Map() };
|
|
318
|
+
}
|
|
319
|
+
const graphs = new Map();
|
|
320
|
+
let status;
|
|
321
|
+
const localGraphs = await readLocalCommandEffectGraphs(projectRoot, intentNames);
|
|
322
|
+
for (const [intentName, graph] of localGraphs) {
|
|
323
|
+
status ??= toDashboardCommandEffectGraphStatus(graph);
|
|
324
|
+
if (graph.status === 'fresh') {
|
|
325
|
+
graphs.set(intentName, toDashboardCommandEffectGraph(graph));
|
|
326
|
+
}
|
|
327
|
+
}
|
|
328
|
+
return { status, graphs };
|
|
329
|
+
}
|
|
330
|
+
async function renderCommandContractResponse(projectRoot, contract) {
|
|
282
331
|
if (!contract) {
|
|
283
332
|
return {
|
|
284
333
|
path: '.mustflow/config/commands.toml',
|
|
@@ -321,10 +370,15 @@ function renderCommandContractResponse(contract) {
|
|
|
321
370
|
},
|
|
322
371
|
];
|
|
323
372
|
});
|
|
373
|
+
const effectGraphs = await readCommandEffectGraphMap(projectRoot, intents.map((intent) => intent.name));
|
|
324
374
|
return {
|
|
325
375
|
path: '.mustflow/config/commands.toml',
|
|
326
376
|
exists: true,
|
|
327
|
-
|
|
377
|
+
effect_graph_status: effectGraphs.status,
|
|
378
|
+
intents: intents.map((intent) => {
|
|
379
|
+
const graph = effectGraphs.graphs.get(intent.name);
|
|
380
|
+
return graph ? { ...intent, effect_graph: graph } : intent;
|
|
381
|
+
}),
|
|
328
382
|
};
|
|
329
383
|
}
|
|
330
384
|
function pathMatches(filePath, patterns) {
|
|
@@ -475,13 +529,13 @@ function renderRunHistoryResponse(projectRoot) {
|
|
|
475
529
|
};
|
|
476
530
|
}
|
|
477
531
|
}
|
|
478
|
-
function renderStatusResponse(projectRoot) {
|
|
532
|
+
async function renderStatusResponse(projectRoot) {
|
|
479
533
|
const context = getAgentContext(projectRoot);
|
|
480
534
|
const manifest = inspectManifestLock(projectRoot);
|
|
481
535
|
const lock = manifest.readResult.kind === 'present' ? manifest.readResult.lock : undefined;
|
|
482
536
|
const activeDocuments = listDocReviewEntries(projectRoot);
|
|
483
537
|
const rawCommandContract = readDashboardCommandContract(projectRoot);
|
|
484
|
-
const commandContract = renderCommandContractResponse(rawCommandContract);
|
|
538
|
+
const commandContract = await renderCommandContractResponse(projectRoot, rawCommandContract);
|
|
485
539
|
const gitChangedFiles = readGitChangedFiles(projectRoot);
|
|
486
540
|
const packageMetadata = readPackageMetadata();
|
|
487
541
|
return {
|
|
@@ -536,7 +590,7 @@ export async function runDashboard(args, reporter, lang = 'en') {
|
|
|
536
590
|
'cache-control': 'no-store',
|
|
537
591
|
'content-type': 'text/html; charset=utf-8',
|
|
538
592
|
});
|
|
539
|
-
response.end(renderDashboardHtml(readDashboardPreferences(projectRoot), token, renderStatusResponse(projectRoot), renderDocReviewResponse(projectRoot, new URL('/api/docs/review', 'http://localhost'))));
|
|
593
|
+
response.end(renderDashboardHtml(readDashboardPreferences(projectRoot), token, await renderStatusResponse(projectRoot), renderDocReviewResponse(projectRoot, new URL('/api/docs/review', 'http://localhost'))));
|
|
540
594
|
return;
|
|
541
595
|
}
|
|
542
596
|
if (request.method === 'GET' && requestUrl.pathname === '/favicon.ico') {
|
|
@@ -550,7 +604,7 @@ export async function runDashboard(args, reporter, lang = 'en') {
|
|
|
550
604
|
return;
|
|
551
605
|
}
|
|
552
606
|
if (request.method === 'GET') {
|
|
553
|
-
sendJson(response, 200, renderStatusResponse(projectRoot));
|
|
607
|
+
sendJson(response, 200, await renderStatusResponse(projectRoot));
|
|
554
608
|
return;
|
|
555
609
|
}
|
|
556
610
|
}
|
|
@@ -10,6 +10,7 @@ import { explainSkillRouteAlignment, } from '../../core/skill-route-alignment.js
|
|
|
10
10
|
import { explainPublicSurface } from '../../core/public-surface-explanation.js';
|
|
11
11
|
import { explainSourceAnchor } from '../../core/source-anchor-explanation.js';
|
|
12
12
|
import { checkMustflowProject } from '../lib/validation.js';
|
|
13
|
+
import { readLocalCommandEffectGraph, readLocalPathSurface, } from '../lib/local-index.js';
|
|
13
14
|
const EXPLAIN_SCHEMA_VERSION = '1';
|
|
14
15
|
export function getExplainHelp(lang = 'en') {
|
|
15
16
|
return renderHelp({
|
|
@@ -71,13 +72,15 @@ function getAnchorExplainOutput(projectRoot, anchorId) {
|
|
|
71
72
|
decision: explainSourceAnchor(projectRoot, anchorId),
|
|
72
73
|
};
|
|
73
74
|
}
|
|
74
|
-
function getCommandExplainOutput(projectRoot, commandName) {
|
|
75
|
+
async function getCommandExplainOutput(projectRoot, commandName) {
|
|
76
|
+
const decision = explainCommandIntent(readCommandContract(projectRoot), commandName);
|
|
77
|
+
const effectGraph = decision.intent ? await readLocalCommandEffectGraph(projectRoot, commandName) : undefined;
|
|
75
78
|
return {
|
|
76
79
|
schema_version: EXPLAIN_SCHEMA_VERSION,
|
|
77
80
|
command: 'explain',
|
|
78
81
|
topic: 'command',
|
|
79
82
|
mustflow_root: projectRoot,
|
|
80
|
-
decision:
|
|
83
|
+
decision: effectGraph ? { ...decision, effectGraph } : decision,
|
|
81
84
|
};
|
|
82
85
|
}
|
|
83
86
|
function getRetentionExplainOutput(projectRoot) {
|
|
@@ -107,13 +110,15 @@ function getSkillExplainOutput(projectRoot, skillName) {
|
|
|
107
110
|
decision: explainSkillRoute(projectRoot, skillName),
|
|
108
111
|
};
|
|
109
112
|
}
|
|
110
|
-
function getSurfaceExplainOutput(projectRoot, pathArg) {
|
|
113
|
+
async function getSurfaceExplainOutput(projectRoot, pathArg) {
|
|
114
|
+
const decision = explainPublicSurface(pathArg);
|
|
115
|
+
const readModel = await readLocalPathSurface(projectRoot, pathArg);
|
|
111
116
|
return {
|
|
112
117
|
schema_version: EXPLAIN_SCHEMA_VERSION,
|
|
113
118
|
command: 'explain',
|
|
114
119
|
topic: 'surface',
|
|
115
120
|
mustflow_root: projectRoot,
|
|
116
|
-
decision:
|
|
121
|
+
decision: { ...decision, readModel },
|
|
117
122
|
};
|
|
118
123
|
}
|
|
119
124
|
function formatNullable(value, lang) {
|
|
@@ -160,6 +165,28 @@ function renderExplainDecision(output, lang) {
|
|
|
160
165
|
const intent = output.decision.intent;
|
|
161
166
|
lines.push('', t(lang, 'explain.label.commandIntent'), `- ${t(lang, 'explain.label.commandName')}: ${intent.name}`, `- status: ${intent.status ?? t(lang, 'value.none')}`, `- lifecycle: ${intent.lifecycle ?? t(lang, 'value.none')}`, `- run_policy: ${intent.runPolicy ?? t(lang, 'value.none')}`, `- stdin: ${intent.stdin ?? t(lang, 'value.none')}`, `- timeout_seconds: ${intent.timeoutSeconds ?? t(lang, 'value.none')}`, `- mode: ${intent.mode}`, `- cwd: ${intent.cwd ?? t(lang, 'value.none')}`, `- writes: ${intent.writes.join(', ') || t(lang, 'value.none')}`, `- network: ${formatNullable(intent.network, lang)}`, `- destructive: ${formatNullable(intent.destructive, lang)}`, `- success_exit_codes: ${intent.successExitCodes.join(', ') || t(lang, 'value.none')}`, `- required_after: ${intent.requiredAfter.join(', ') || t(lang, 'value.none')}`);
|
|
162
167
|
}
|
|
168
|
+
if ('effectGraph' in output.decision && output.decision.effectGraph) {
|
|
169
|
+
const graph = output.decision.effectGraph;
|
|
170
|
+
lines.push('', 'Command effect graph', `- source: ${graph.source}`, `- status: ${graph.status}`, `- index_fresh: ${graph.indexFresh ? t(lang, 'value.yes') : t(lang, 'value.no')}`);
|
|
171
|
+
if (graph.refreshHint) {
|
|
172
|
+
lines.push(`- refresh_hint: ${graph.refreshHint}`);
|
|
173
|
+
}
|
|
174
|
+
if (graph.stalePaths.length > 0) {
|
|
175
|
+
lines.push(`- stale_paths: ${graph.stalePaths.join(', ')}`);
|
|
176
|
+
}
|
|
177
|
+
if (graph.writeLocks.length > 0) {
|
|
178
|
+
lines.push('- write_locks:');
|
|
179
|
+
for (const lock of graph.writeLocks) {
|
|
180
|
+
lines.push(` - ${lock.lock}`, ` paths: ${lock.paths.join(', ') || t(lang, 'value.none')}`, ` modes: ${lock.modes.join(', ') || t(lang, 'value.none')}`, ` concurrencies: ${lock.concurrencies.join(', ') || t(lang, 'value.none')}`);
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
if (graph.lockConflicts.length > 0) {
|
|
184
|
+
lines.push('- lock_conflicts:');
|
|
185
|
+
for (const conflict of graph.lockConflicts) {
|
|
186
|
+
lines.push(` - ${conflict.intent} (${conflict.lock})`, ` paths: ${conflict.paths.join(', ') || t(lang, 'value.none')}`, ` conflicting_paths: ${conflict.conflictingPaths.join(', ') || t(lang, 'value.none')}`);
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
}
|
|
163
190
|
if ('retention' in output.decision) {
|
|
164
191
|
const retention = output.decision.retention;
|
|
165
192
|
lines.push('', t(lang, 'explain.label.retentionPolicy'), `- enabled: ${formatNullable(retention.enabled, lang)}`, `- raw_events.store: ${formatNullable(retention.rawEvents.store, lang)}`, `- raw_events.on_limit: ${formatNullable(retention.rawEvents.onLimit, lang)}`, `- run_receipts.store: ${retention.runReceipts.store}`, `- run_receipts.max_file_kb: ${retention.runReceipts.maxFileKb}`, `- run_receipts.max_items: ${retention.runReceipts.maxItems}`, `- run_receipts.keep_stdout_tail_bytes: ${retention.runReceipts.stdoutTailBytes}`, `- run_receipts.keep_stderr_tail_bytes: ${retention.runReceipts.stderrTailBytes}`, `- knowledge.enabled: ${formatNullable(retention.knowledge.enabled, lang)}`, `- context.max_file_kb: ${retention.context.maxFileKb}`, `- repo_map.max_file_kb: ${retention.repoMap.maxFileKb}`, `- repo_map.fail_if_larger: ${formatNullable(retention.repoMap.failIfLarger, lang)}`);
|
|
@@ -187,6 +214,19 @@ function renderExplainDecision(output, lang) {
|
|
|
187
214
|
if ('surface' in output.decision) {
|
|
188
215
|
const surface = output.decision.surface;
|
|
189
216
|
lines.push('', t(lang, 'explain.label.publicSurface'), `- kind: ${surface.kind}`, `- category: ${surface.category}`, `- is_public_surface: ${surface.isPublicSurface ? t(lang, 'value.yes') : t(lang, 'value.no')}`, `- ${t(lang, 'explain.label.validationReasons')}: ${surface.validationReasons.join(', ') || t(lang, 'value.none')}`, `- ${t(lang, 'explain.label.affectedContracts')}: ${surface.affectedContracts.join(', ') || t(lang, 'value.none')}`, `- ${t(lang, 'classify.label.updatePolicy')}: ${surface.updatePolicy}`, `- ${t(lang, 'classify.label.driftChecks')}: ${surface.driftChecks.join(', ') || t(lang, 'value.none')}`);
|
|
217
|
+
const readModel = output.decision.readModel;
|
|
218
|
+
if (readModel) {
|
|
219
|
+
lines.push('', 'Local index path-surface model', `- status: ${readModel.status}`, `- index_fresh: ${readModel.indexFresh ? t(lang, 'value.yes') : t(lang, 'value.no')}`);
|
|
220
|
+
if (readModel.refreshHint) {
|
|
221
|
+
lines.push(`- refresh_hint: ${readModel.refreshHint}`);
|
|
222
|
+
}
|
|
223
|
+
if (readModel.stalePaths.length > 0) {
|
|
224
|
+
lines.push(`- stale_paths: ${readModel.stalePaths.join(', ')}`);
|
|
225
|
+
}
|
|
226
|
+
if (readModel.match) {
|
|
227
|
+
lines.push(`- rule_id: ${readModel.match.ruleId}`, `- pattern: ${readModel.match.pattern}`, `- change_kinds: ${readModel.match.changeKinds.join(', ') || t(lang, 'value.none')}`);
|
|
228
|
+
}
|
|
229
|
+
}
|
|
190
230
|
}
|
|
191
231
|
if ('anchor' in output.decision) {
|
|
192
232
|
const anchor = output.decision.anchor;
|
|
@@ -200,7 +240,7 @@ function renderExplainDecision(output, lang) {
|
|
|
200
240
|
}
|
|
201
241
|
return lines.join('\n');
|
|
202
242
|
}
|
|
203
|
-
export function runExplain(args, reporter, lang = 'en') {
|
|
243
|
+
export async function runExplain(args, reporter, lang = 'en') {
|
|
204
244
|
if (args.includes('--help') || args.includes('-h')) {
|
|
205
245
|
reporter.stdout(getExplainHelp(lang));
|
|
206
246
|
return 0;
|
|
@@ -269,7 +309,7 @@ export function runExplain(args, reporter, lang = 'en') {
|
|
|
269
309
|
output = getAuthorityExplainOutput(projectRoot, targetArg);
|
|
270
310
|
break;
|
|
271
311
|
case 'command':
|
|
272
|
-
output = getCommandExplainOutput(projectRoot, targetArg);
|
|
312
|
+
output = await getCommandExplainOutput(projectRoot, targetArg);
|
|
273
313
|
break;
|
|
274
314
|
case 'retention':
|
|
275
315
|
output = getRetentionExplainOutput(projectRoot);
|
|
@@ -278,7 +318,7 @@ export function runExplain(args, reporter, lang = 'en') {
|
|
|
278
318
|
output = getSkillExplainOutput(projectRoot, targetArg);
|
|
279
319
|
break;
|
|
280
320
|
case 'surface':
|
|
281
|
-
output = getSurfaceExplainOutput(projectRoot, targetArg);
|
|
321
|
+
output = await getSurfaceExplainOutput(projectRoot, targetArg);
|
|
282
322
|
break;
|
|
283
323
|
case 'skills':
|
|
284
324
|
output = getSkillsExplainOutput(projectRoot);
|
|
@@ -15,10 +15,14 @@ export function getIndexHelp(lang = 'en') {
|
|
|
15
15
|
label: '--source',
|
|
16
16
|
description: t(lang, 'index.help.option.source'),
|
|
17
17
|
},
|
|
18
|
+
{
|
|
19
|
+
label: '--incremental',
|
|
20
|
+
description: t(lang, 'index.help.option.incremental'),
|
|
21
|
+
},
|
|
18
22
|
{ label: '--json', description: t(lang, 'cli.option.json') },
|
|
19
23
|
{ label: '-h, --help', description: t(lang, 'cli.option.help') },
|
|
20
24
|
],
|
|
21
|
-
examples: ['mf index --dry-run --json', 'mf index', 'mf index --json'],
|
|
25
|
+
examples: ['mf index --dry-run --json', 'mf index', 'mf index --incremental --json'],
|
|
22
26
|
exitCodes: [
|
|
23
27
|
{
|
|
24
28
|
label: '0',
|
|
@@ -39,6 +43,8 @@ function renderIndexSummary(result, lang) {
|
|
|
39
43
|
`${t(lang, 'label.commandIntents')}: ${result.command_intent_count}`,
|
|
40
44
|
`command_effects: ${result.command_effect_count}`,
|
|
41
45
|
`source_anchors: ${result.source_anchor_count}`,
|
|
46
|
+
`index_mode: ${result.index_mode}`,
|
|
47
|
+
`reused_existing: ${result.reused_existing ? 'yes' : 'no'}`,
|
|
42
48
|
`${t(lang, 'label.wroteFiles')}: ${result.wrote_files ? 'yes' : 'no'}`,
|
|
43
49
|
];
|
|
44
50
|
if (result.dry_run) {
|
|
@@ -51,7 +57,7 @@ export async function runIndex(args, reporter, lang = 'en') {
|
|
|
51
57
|
reporter.stdout(getIndexHelp(lang));
|
|
52
58
|
return 0;
|
|
53
59
|
}
|
|
54
|
-
const supported = new Set(['--dry-run', '--json', '--source']);
|
|
60
|
+
const supported = new Set(['--dry-run', '--json', '--source', '--incremental']);
|
|
55
61
|
const unsupported = args.filter((arg) => !supported.has(arg));
|
|
56
62
|
if (unsupported.length > 0) {
|
|
57
63
|
printUsageError(reporter, t(lang, 'cli.error.unknownOption', { option: unsupported[0] }), 'mf index --help', getIndexHelp(lang), lang);
|
|
@@ -60,6 +66,7 @@ export async function runIndex(args, reporter, lang = 'en') {
|
|
|
60
66
|
const result = await createLocalIndex(resolveMustflowRoot(), {
|
|
61
67
|
dryRun: args.includes('--dry-run'),
|
|
62
68
|
includeSource: args.includes('--source'),
|
|
69
|
+
incremental: args.includes('--incremental'),
|
|
63
70
|
});
|
|
64
71
|
if (args.includes('--json')) {
|
|
65
72
|
reporter.stdout(JSON.stringify(result, null, 2));
|
package/dist/cli/commands/run.js
CHANGED
|
@@ -4,14 +4,12 @@ import { runCheck } from './check.js';
|
|
|
4
4
|
import { runClassify } from './classify.js';
|
|
5
5
|
import { runContext } from './context.js';
|
|
6
6
|
import { runDoctor } from './doctor.js';
|
|
7
|
-
import { runExplain } from './explain.js';
|
|
8
7
|
import { runHelp } from './help.js';
|
|
9
8
|
import { runImpact } from './impact.js';
|
|
10
9
|
import { runLineEndings } from './line-endings.js';
|
|
11
10
|
import { runMap } from './map.js';
|
|
12
11
|
import { runStatus } from './status.js';
|
|
13
12
|
import { runUpdate } from './update.js';
|
|
14
|
-
import { runVerify } from './verify.js';
|
|
15
13
|
import { runVersionSources } from './version-sources.js';
|
|
16
14
|
import { canRunMustflowBuiltinInProcess, isMustflowBinName } from '../../core/command-classification.js';
|
|
17
15
|
import { resolveSafeProjectCwd } from '../../core/command-cwd.js';
|
|
@@ -144,7 +142,7 @@ function createBufferedReporter() {
|
|
|
144
142
|
* invariant: Only commands classified by command-classification can use this path.
|
|
145
143
|
* risk: config, state
|
|
146
144
|
*/
|
|
147
|
-
function runKnownBuiltinCommand(args, reporter, lang) {
|
|
145
|
+
async function runKnownBuiltinCommand(args, reporter, lang) {
|
|
148
146
|
const [command, ...commandArgs] = args;
|
|
149
147
|
if ((command === '--version' || command === '-v' || command === 'version') && commandArgs.length === 0) {
|
|
150
148
|
reporter.stdout(getPackageVersion());
|
|
@@ -165,9 +163,6 @@ function runKnownBuiltinCommand(args, reporter, lang) {
|
|
|
165
163
|
if (command === 'doctor') {
|
|
166
164
|
return runDoctor(commandArgs, reporter, lang);
|
|
167
165
|
}
|
|
168
|
-
if (command === 'explain') {
|
|
169
|
-
return runExplain(commandArgs, reporter, lang);
|
|
170
|
-
}
|
|
171
166
|
if (command === 'help') {
|
|
172
167
|
return runHelp(commandArgs, reporter, lang);
|
|
173
168
|
}
|
|
@@ -189,29 +184,26 @@ function runKnownBuiltinCommand(args, reporter, lang) {
|
|
|
189
184
|
if (command === 'version-sources') {
|
|
190
185
|
return runVersionSources(commandArgs, reporter, lang);
|
|
191
186
|
}
|
|
192
|
-
if (command === 'verify') {
|
|
193
|
-
return runVerify(commandArgs, reporter, lang);
|
|
194
|
-
}
|
|
195
187
|
return undefined;
|
|
196
188
|
}
|
|
197
|
-
function withWorkingDirectory(cwd, callback) {
|
|
189
|
+
async function withWorkingDirectory(cwd, callback) {
|
|
198
190
|
const previousCwd = process.cwd();
|
|
199
191
|
process.chdir(cwd);
|
|
200
192
|
try {
|
|
201
|
-
return callback();
|
|
193
|
+
return await callback();
|
|
202
194
|
}
|
|
203
195
|
finally {
|
|
204
196
|
process.chdir(previousCwd);
|
|
205
197
|
}
|
|
206
198
|
}
|
|
207
|
-
function runBuiltinArgvInProcess(commandArgv, cwd, lang) {
|
|
199
|
+
async function runBuiltinArgvInProcess(commandArgv, cwd, lang) {
|
|
208
200
|
const [command = '', ...builtinArgs] = commandArgv;
|
|
209
201
|
if (!isMustflowBinName(command)) {
|
|
210
202
|
return undefined;
|
|
211
203
|
}
|
|
212
204
|
const output = createBufferedReporter();
|
|
213
205
|
try {
|
|
214
|
-
const status = withWorkingDirectory(cwd, () => runKnownBuiltinCommand(builtinArgs, output.reporter, lang));
|
|
206
|
+
const status = await withWorkingDirectory(cwd, () => runKnownBuiltinCommand(builtinArgs, output.reporter, lang));
|
|
215
207
|
if (status === undefined) {
|
|
216
208
|
return undefined;
|
|
217
209
|
}
|
|
@@ -296,7 +288,7 @@ export function getRunHelp(lang = 'en') {
|
|
|
296
288
|
* invariant: Execution requires configured status, oneshot lifecycle, agent_allowed policy, and closed stdin.
|
|
297
289
|
* risk: config, security, state
|
|
298
290
|
*/
|
|
299
|
-
export function runRun(args, reporter, lang = 'en') {
|
|
291
|
+
export async function runRun(args, reporter, lang = 'en') {
|
|
300
292
|
if (args.includes('--help') || args.includes('-h')) {
|
|
301
293
|
reporter.stdout(getRunHelp(lang));
|
|
302
294
|
return 0;
|
|
@@ -384,7 +376,7 @@ export function runRun(args, reporter, lang = 'en') {
|
|
|
384
376
|
const startedAt = new Date();
|
|
385
377
|
const argvCommand = commandArgv ? resolveArgvCommand(intent, commandArgv) : undefined;
|
|
386
378
|
const result = commandArgv && isMustflowBuiltinIntent(intent)
|
|
387
|
-
? (runBuiltinArgvInProcess(commandArgv, cwd, lang) ??
|
|
379
|
+
? ((await runBuiltinArgvInProcess(commandArgv, cwd, lang)) ??
|
|
388
380
|
runArgvCommand(argvCommand, cwd, maxOutputBytes, env, timeoutSeconds))
|
|
389
381
|
: commandArgv
|
|
390
382
|
? runArgvCommand(argvCommand, cwd, maxOutputBytes, env, timeoutSeconds)
|
|
@@ -6,6 +6,7 @@ import { createVerificationPlan } from '../../core/verification-plan.js';
|
|
|
6
6
|
import { readCommandContract } from '../../core/config-loading.js';
|
|
7
7
|
import { printUsageError, renderHelp } from '../lib/cli-output.js';
|
|
8
8
|
import { t } from '../lib/i18n.js';
|
|
9
|
+
import { readLocalCommandEffectGraph, readLocalPathSurfaces, } from '../lib/local-index.js';
|
|
9
10
|
import { resolveMustflowRoot } from '../lib/project-root.js';
|
|
10
11
|
const VERIFY_SCHEMA_VERSION = '1';
|
|
11
12
|
function createBufferedOutput() {
|
|
@@ -276,9 +277,9 @@ function skippedResult(candidate) {
|
|
|
276
277
|
receipt: null,
|
|
277
278
|
};
|
|
278
279
|
}
|
|
279
|
-
function runVerificationIntent(intent, lang) {
|
|
280
|
+
async function runVerificationIntent(intent, lang) {
|
|
280
281
|
const output = createBufferedOutput();
|
|
281
|
-
const exitCode = runRun([intent, '--json'], output.reporter, lang);
|
|
282
|
+
const exitCode = await runRun([intent, '--json'], output.reporter, lang);
|
|
282
283
|
const rawStdout = output.stdout().trim();
|
|
283
284
|
let receipt = null;
|
|
284
285
|
let status = exitCode === 0 ? 'passed' : 'failed';
|
|
@@ -332,7 +333,7 @@ function getVerificationStatus(summary) {
|
|
|
332
333
|
}
|
|
333
334
|
return 'passed';
|
|
334
335
|
}
|
|
335
|
-
function createVerifyOutput(reasons, planSource, projectRoot, lang) {
|
|
336
|
+
async function createVerifyOutput(reasons, planSource, projectRoot, lang) {
|
|
336
337
|
const contract = readCommandContract(projectRoot);
|
|
337
338
|
const candidatesByIntent = new Map();
|
|
338
339
|
const unmatchedCandidates = [];
|
|
@@ -349,7 +350,10 @@ function createVerifyOutput(reasons, planSource, projectRoot, lang) {
|
|
|
349
350
|
}
|
|
350
351
|
}
|
|
351
352
|
const candidates = [...candidatesByIntent.values(), ...unmatchedCandidates].sort((left, right) => left.intent.localeCompare(right.intent));
|
|
352
|
-
const results =
|
|
353
|
+
const results = [];
|
|
354
|
+
for (const candidate of candidates) {
|
|
355
|
+
results.push(candidate.status === 'runnable' ? await runVerificationIntent(candidate.intent, lang) : skippedResult(candidate));
|
|
356
|
+
}
|
|
353
357
|
const summary = summarizeResults(results);
|
|
354
358
|
return {
|
|
355
359
|
schema_version: VERIFY_SCHEMA_VERSION,
|
|
@@ -363,9 +367,40 @@ function createVerifyOutput(reasons, planSource, projectRoot, lang) {
|
|
|
363
367
|
results,
|
|
364
368
|
};
|
|
365
369
|
}
|
|
366
|
-
function createPlanOnlyOutput(input, projectRoot) {
|
|
370
|
+
async function createPlanOnlyOutput(input, projectRoot) {
|
|
367
371
|
const contract = readCommandContract(projectRoot);
|
|
368
|
-
|
|
372
|
+
const report = createChangeVerificationReport(input.classificationReport, contract, projectRoot);
|
|
373
|
+
const localSurfaceReadModels = await readLocalPathSurfaces(projectRoot, report.files);
|
|
374
|
+
const [firstEntry] = report.schedule.entries;
|
|
375
|
+
const requirements = report.requirements.map((requirement) => {
|
|
376
|
+
const surfaceReadModels = requirement.files
|
|
377
|
+
.map((filePath) => localSurfaceReadModels.get(filePath))
|
|
378
|
+
.filter((readModel) => Boolean(readModel));
|
|
379
|
+
return surfaceReadModels.length > 0 ? { ...requirement, surfaceReadModels } : requirement;
|
|
380
|
+
});
|
|
381
|
+
if (!firstEntry) {
|
|
382
|
+
return { ...report, requirements };
|
|
383
|
+
}
|
|
384
|
+
const firstGraph = await readLocalCommandEffectGraph(projectRoot, firstEntry.intent);
|
|
385
|
+
const graphsByIntent = new Map([[firstEntry.intent, firstGraph]]);
|
|
386
|
+
if (firstGraph.status === 'fresh') {
|
|
387
|
+
for (const entry of report.schedule.entries.slice(1)) {
|
|
388
|
+
if (!graphsByIntent.has(entry.intent)) {
|
|
389
|
+
graphsByIntent.set(entry.intent, await readLocalCommandEffectGraph(projectRoot, entry.intent));
|
|
390
|
+
}
|
|
391
|
+
}
|
|
392
|
+
}
|
|
393
|
+
return {
|
|
394
|
+
...report,
|
|
395
|
+
requirements,
|
|
396
|
+
schedule: {
|
|
397
|
+
...report.schedule,
|
|
398
|
+
entries: report.schedule.entries.map((entry) => ({
|
|
399
|
+
...entry,
|
|
400
|
+
effectGraph: graphsByIntent.get(entry.intent) ?? firstGraph,
|
|
401
|
+
})),
|
|
402
|
+
},
|
|
403
|
+
};
|
|
369
404
|
}
|
|
370
405
|
function renderVerifyOutput(output, lang) {
|
|
371
406
|
const lines = [
|
|
@@ -389,7 +424,7 @@ function renderVerifyOutput(output, lang) {
|
|
|
389
424
|
}
|
|
390
425
|
return lines.join('\n');
|
|
391
426
|
}
|
|
392
|
-
export function runVerify(args, reporter, lang = 'en') {
|
|
427
|
+
export async function runVerify(args, reporter, lang = 'en') {
|
|
393
428
|
if (args.includes('--help') || args.includes('-h')) {
|
|
394
429
|
reporter.stdout(getVerifyHelp(lang));
|
|
395
430
|
return 0;
|
|
@@ -434,10 +469,10 @@ export function runVerify(args, reporter, lang = 'en') {
|
|
|
434
469
|
return 1;
|
|
435
470
|
}
|
|
436
471
|
if (parsed.planOnly) {
|
|
437
|
-
reporter.stdout(JSON.stringify(createPlanOnlyOutput(input, projectRoot), null, 2));
|
|
472
|
+
reporter.stdout(JSON.stringify(await createPlanOnlyOutput(input, projectRoot), null, 2));
|
|
438
473
|
return 0;
|
|
439
474
|
}
|
|
440
|
-
const output = createVerifyOutput(input.reasons, parsed.fromPlan ?? null, projectRoot, lang);
|
|
475
|
+
const output = await createVerifyOutput(input.reasons, parsed.fromPlan ?? null, projectRoot, lang);
|
|
441
476
|
if (parsed.json) {
|
|
442
477
|
reporter.stdout(JSON.stringify(output, null, 2));
|
|
443
478
|
}
|
package/dist/cli/i18n/en.js
CHANGED
|
@@ -179,6 +179,8 @@ export const enMessages = {
|
|
|
179
179
|
"dashboard.commands.writes": "writes",
|
|
180
180
|
"dashboard.commands.reason": "reason",
|
|
181
181
|
"dashboard.commands.agentAction": "agent action",
|
|
182
|
+
"dashboard.commands.effectGraph": "effect graph",
|
|
183
|
+
"dashboard.commands.effectGraphUnavailable": "Command effect graph unavailable",
|
|
182
184
|
"dashboard.release.reloaded": "Release status reloaded",
|
|
183
185
|
"dashboard.release.copied": "Command copied",
|
|
184
186
|
"dashboard.release.overview": "Overview",
|
|
@@ -459,6 +461,7 @@ export const enMessages = {
|
|
|
459
461
|
"index.help.summary": "Build a SQLite index that can be regenerated for the mustflow workflow.",
|
|
460
462
|
"index.help.option.dryRun": "Calculate index targets without writing files",
|
|
461
463
|
"index.help.option.source": "Include structured source-code anchors without storing source content",
|
|
464
|
+
"index.help.option.incremental": "Reuse a fresh compatible local index instead of rewriting it",
|
|
462
465
|
"index.help.exit.ok": "Index targets were calculated and optionally written",
|
|
463
466
|
"index.title": "mustflow index",
|
|
464
467
|
"index.dryRunNoFiles": "Dry run: no files were written.",
|
package/dist/cli/i18n/es.js
CHANGED
|
@@ -179,6 +179,8 @@ export const esMessages = {
|
|
|
179
179
|
"dashboard.commands.writes": "rutas de escritura",
|
|
180
180
|
"dashboard.commands.reason": "motivo",
|
|
181
181
|
"dashboard.commands.agentAction": "acción del agente",
|
|
182
|
+
"dashboard.commands.effectGraph": "efectos del comando",
|
|
183
|
+
"dashboard.commands.effectGraphUnavailable": "Efectos del comando no disponibles",
|
|
182
184
|
"dashboard.release.reloaded": "Estado de lanzamiento recargado",
|
|
183
185
|
"dashboard.release.copied": "Comando copiado",
|
|
184
186
|
"dashboard.release.overview": "Resumen",
|
|
@@ -459,6 +461,7 @@ export const esMessages = {
|
|
|
459
461
|
"index.help.summary": "Construye un índice SQLite que se puede regenerar para el flujo de trabajo mustflow.",
|
|
460
462
|
"index.help.option.dryRun": "Calcula los objetivos del índice sin escribir archivos",
|
|
461
463
|
"index.help.option.source": "Incluye anclas estructuradas de código fuente sin guardar el contenido fuente",
|
|
464
|
+
"index.help.option.incremental": "Reutiliza un índice local fresco y compatible en lugar de reescribirlo",
|
|
462
465
|
"index.help.exit.ok": "Los objetivos del índice se calcularon y se escribieron opcionalmente",
|
|
463
466
|
"index.title": "índice mustflow",
|
|
464
467
|
"index.dryRunNoFiles": "Ensayo: no se escribieron archivos.",
|
package/dist/cli/i18n/fr.js
CHANGED
|
@@ -179,6 +179,8 @@ export const frMessages = {
|
|
|
179
179
|
"dashboard.commands.writes": "chemins écrits",
|
|
180
180
|
"dashboard.commands.reason": "raison",
|
|
181
181
|
"dashboard.commands.agentAction": "action agent",
|
|
182
|
+
"dashboard.commands.effectGraph": "effets de commande",
|
|
183
|
+
"dashboard.commands.effectGraphUnavailable": "Effets de commande indisponibles",
|
|
182
184
|
"dashboard.release.reloaded": "État de publication rechargé",
|
|
183
185
|
"dashboard.release.copied": "Commande copiée",
|
|
184
186
|
"dashboard.release.overview": "Aperçu",
|
|
@@ -459,6 +461,7 @@ export const frMessages = {
|
|
|
459
461
|
"index.help.summary": "Construit un index SQLite régénérable pour le flux de travail mustflow.",
|
|
460
462
|
"index.help.option.dryRun": "Calcule les cibles d'index sans écrire de fichiers",
|
|
461
463
|
"index.help.option.source": "Inclure les ancres structurées du code source sans stocker le contenu source",
|
|
464
|
+
"index.help.option.incremental": "Réutilise un index local récent et compatible au lieu de le réécrire",
|
|
462
465
|
"index.help.exit.ok": "Les cibles d'index ont été calculées et éventuellement écrites",
|
|
463
466
|
"index.title": "index mustflow",
|
|
464
467
|
"index.dryRunNoFiles": "Simulation : aucun fichier n'a été écrit.",
|