@khoavu882/doflow 2.0.0-beta.3 → 2.0.0-beta.4
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/bin/doflow.js +2 -2
- package/core/.claude-plugin/plugin.json +1 -1
- package/core/.codex-plugin/plugin.json +1 -1
- package/core/.plugin/plugin.json +1 -1
- package/core/registry/storage.json +87 -83
- package/core/registry/verification.json +1 -1
- package/core/shared/scripts/doflow/bash/render-puml.sh +2 -2
- package/core/shared/skills/do-execute-plan/references/scaffold.md +2 -2
- package/package.json +4 -2
- package/src/adapters/antigravity/{index.ts → index.js} +60 -60
- package/src/adapters/claude/{index.ts → index.js} +48 -48
- package/src/adapters/claude/{mcp.ts → mcp.js} +16 -16
- package/src/adapters/codex/{agents.ts → agents.js} +24 -24
- package/src/adapters/codex/{config.ts → config.js} +49 -49
- package/src/adapters/codex/{hooks.ts → hooks.js} +23 -23
- package/src/adapters/codex/{index.ts → index.js} +98 -98
- package/src/adapters/codex/{mcp.ts → mcp.js} +38 -38
- package/src/adapters/codex/{native-projection.ts → native-projection.js} +5 -5
- package/src/adapters/copilot/{index.ts → index.js} +42 -42
- package/src/adapters/{copy-tree.ts → copy-tree.js} +70 -70
- package/src/adapters/gemini/{hooks.ts → hooks.js} +24 -24
- package/src/adapters/gemini/{index.ts → index.js} +41 -41
- package/src/adapters/{hook-commands.ts → hook-commands.js} +8 -8
- package/src/adapters/{index.ts → index.js} +13 -13
- package/src/adapters/kiro/{index.ts → index.js} +34 -34
- package/src/adapters/{mcp-entries.ts → mcp-entries.js} +55 -55
- package/src/adapters/opencode/{index.ts → index.js} +52 -52
- package/src/adapters/pi/{index.ts → index.js} +30 -30
- package/src/adapters/pi/{json-members.ts → json-members.js} +23 -23
- package/src/adapters/pi/{mcp.ts → mcp.js} +70 -70
- package/src/adapters/{resolve-source.ts → resolve-source.js} +1 -1
- package/src/cli/commands/{install.ts → install.js} +24 -24
- package/src/cli/commands/{list-backups.ts → list-backups.js} +4 -4
- package/src/cli/commands/{reconcile.ts → reconcile.js} +19 -19
- package/src/cli/commands/{remove.ts → remove.js} +10 -10
- package/src/cli/commands/{rollback.ts → rollback.js} +17 -17
- package/src/cli/commands/{self-update.ts → self-update.js} +3 -3
- package/src/cli/commands/{status.ts → status.js} +24 -24
- package/src/cli/commands/{tools.ts → tools.js} +16 -16
- package/src/cli/commands/{update.ts → update.js} +19 -19
- package/src/cli/{index.ts → index.js} +26 -26
- package/src/cli/{runtime-commands.ts → runtime-commands.js} +48 -48
- package/src/cli/{shared.ts → shared.js} +40 -40
- package/src/helper/{bash-helper.ts → bash-helper.js} +7 -7
- package/src/helper/{git.ts → git.js} +2 -2
- package/src/helper/{guardrails.ts → guardrails.js} +10 -10
- package/src/helper/{harness-paths.ts → harness-paths.js} +24 -24
- package/src/helper/{marker-merge.ts → marker-merge.js} +4 -4
- package/src/helper/{prompt.ts → prompt.js} +5 -5
- package/src/helper/{repo-root.ts → repo-root.js} +2 -2
- package/src/helper/{settings-merge.ts → settings-merge.js} +27 -27
- package/src/helper/{settings-scope.ts → settings-scope.js} +3 -3
- package/src/helper/{toml.ts → toml.js} +48 -48
- package/src/install/{backup-set.ts → backup-set.js} +16 -16
- package/src/install/{backup.ts → backup.js} +65 -65
- package/src/install/{context.ts → context.js} +15 -15
- package/src/install/{manifest.ts → manifest.js} +27 -27
- package/src/install/{mcp.ts → mcp.js} +30 -30
- package/src/install/{paths.ts → paths.js} +15 -15
- package/src/install/{targets.ts → targets.js} +10 -10
- package/src/install/{tool-lifecycle.ts → tool-lifecycle.js} +20 -20
- package/src/lifecycle/{bash-availability.ts → bash-availability.js} +1 -1
- package/src/lifecycle/{index.ts → index.js} +140 -140
- package/src/lifecycle/{mcp-index.ts → mcp-index.js} +1 -1
- package/src/lifecycle/{policies.ts → policies.js} +11 -11
- package/src/lifecycle/{view.ts → view.js} +28 -28
- package/src/registry/{index.ts → index.js} +60 -60
- package/src/release/build-package.js +91 -0
- package/src/release/changelog-section.js +70 -0
- package/src/release/{sync-plugin-versions.ts → sync-plugin-versions.js} +4 -4
- package/src/runtime/advice/{cli.ts → cli.js} +31 -31
- package/src/runtime/advice/{client.ts → client.js} +44 -44
- package/src/runtime/advice/{config.ts → config.js} +16 -16
- package/src/runtime/advice/{doctor.ts → doctor.js} +32 -32
- package/src/runtime/advice/{endpoint-guard.ts → endpoint-guard.js} +20 -20
- package/src/runtime/advice/{kinds.ts → kinds.js} +16 -16
- package/src/runtime/advice/providers/{ollama-systemone.ts → ollama-systemone.js} +21 -21
- package/src/runtime/advice/{record.ts → record.js} +19 -19
- package/src/runtime/advice/{registry.ts → registry.js} +16 -16
- package/src/runtime/advice/{strength.ts → strength.js} +7 -7
- package/src/runtime/{brief-tools.ts → brief-tools.js} +50 -50
- package/src/runtime/{c4-project.ts → c4-project.js} +27 -27
- package/src/runtime/{capability-router.ts → capability-router.js} +39 -39
- package/src/runtime/{checkouts.ts → checkouts.js} +21 -21
- package/src/runtime/{claims.ts → claims.js} +30 -30
- package/src/runtime/{cli-result.ts → cli-result.js} +4 -4
- package/src/runtime/{cli.ts → cli.js} +37 -37
- package/src/runtime/{command-detect.ts → command-detect.js} +47 -47
- package/src/runtime/{context-pack.ts → context-pack.js} +20 -20
- package/src/runtime/{decision-register.ts → decision-register.js} +67 -67
- package/src/runtime/{evidence-ledger.ts → evidence-ledger.js} +25 -25
- package/src/runtime/failure/{capture.ts → capture.js} +29 -29
- package/src/runtime/failure/{classifier.ts → classifier.js} +4 -4
- package/src/runtime/failure/{cli.ts → cli.js} +30 -30
- package/src/runtime/failure/{home.ts → home.js} +6 -6
- package/src/runtime/failure/{store.ts → store.js} +32 -32
- package/src/runtime/{feature-resolve.ts → feature-resolve.js} +6 -6
- package/src/runtime/{freshness.ts → freshness.js} +15 -15
- package/src/runtime/{health.ts → health.js} +72 -72
- package/src/runtime/{history-compactor.ts → history-compactor.js} +25 -25
- package/src/runtime/{implementation-gate.ts → implementation-gate.js} +30 -30
- package/src/runtime/inventory/{coverage.ts → coverage.js} +10 -10
- package/src/runtime/inventory/{identity.ts → identity.js} +2 -2
- package/src/runtime/inventory/{index.ts → index.js} +36 -36
- package/src/runtime/inventory/{precedence.ts → precedence.js} +2 -2
- package/src/runtime/inventory/{read-scopes.ts → read-scopes.js} +9 -9
- package/src/runtime/inventory/{siblings.ts → siblings.js} +15 -15
- package/src/runtime/knowledge/{chunker.ts → chunker.js} +12 -12
- package/src/runtime/knowledge/{hybrid.ts → hybrid.js} +17 -17
- package/src/runtime/knowledge/{index-store.ts → index-store.js} +23 -23
- package/src/runtime/knowledge/{retrieval.ts → retrieval.js} +27 -27
- package/src/runtime/{leak-scan.ts → leak-scan.js} +12 -12
- package/src/runtime/lifecycle/{cli.ts → cli.js} +32 -32
- package/src/runtime/lifecycle/{event-store.ts → event-store.js} +48 -48
- package/src/runtime/lifecycle/{fold.ts → fold.js} +41 -41
- package/src/runtime/lifecycle/{followup.ts → followup.js} +54 -54
- package/src/runtime/lifecycle/{goal.ts → goal.js} +50 -50
- package/src/runtime/lifecycle/{intent-writer.ts → intent-writer.js} +5 -5
- package/src/runtime/lifecycle/{overview.ts → overview.js} +47 -47
- package/src/runtime/lifecycle/{release.ts → release.js} +29 -29
- package/src/runtime/lifecycle/{report-store.ts → report-store.js} +25 -25
- package/src/runtime/lifecycle/{retention.ts → retention.js} +37 -37
- package/src/runtime/lifecycle/{root.ts → root.js} +9 -9
- package/src/runtime/lifecycle/{status.ts → status.js} +64 -64
- package/src/runtime/lifecycle/{store-upkeep.ts → store-upkeep.js} +46 -46
- package/src/runtime/{locator-resolve.ts → locator-resolve.js} +7 -7
- package/src/runtime/{mask.ts → mask.js} +22 -22
- package/src/runtime/{mcp-consultations.ts → mcp-consultations.js} +54 -54
- package/src/runtime/{mcp-reach.ts → mcp-reach.js} +24 -24
- package/src/runtime/{model-router.ts → model-router.js} +20 -20
- package/src/runtime/{outcome.ts → outcome.js} +27 -27
- package/src/runtime/{reach.ts → reach.js} +21 -21
- package/src/runtime/{readiness-record.ts → readiness-record.js} +12 -12
- package/src/runtime/{readiness.ts → readiness.js} +35 -35
- package/src/runtime/{recovery.ts → recovery.js} +15 -15
- package/src/runtime/{research-request.ts → research-request.js} +34 -34
- package/src/runtime/{retrieval-plan.ts → retrieval-plan.js} +40 -40
- package/src/runtime/scaffold/{artifacts.ts → artifacts.js} +19 -19
- package/src/runtime/scaffold/{fingerprint.ts → fingerprint.js} +3 -3
- package/src/runtime/scaffold/{generate.ts → generate.js} +109 -109
- package/src/runtime/scaffold/{languages.ts → languages.js} +34 -34
- package/src/runtime/storage/{cli.ts → cli.js} +9 -9
- package/src/runtime/storage/{engine.ts → engine.js} +37 -37
- package/src/runtime/storage/{registry.ts → registry.js} +19 -19
- package/src/runtime/storage/{roots.ts → roots.js} +8 -8
- package/src/runtime/storage/{rules.ts → rules.js} +26 -26
- package/src/runtime/storage/{upkeep.ts → upkeep.js} +35 -35
- package/src/runtime/storage/{work-status.ts → work-status.js} +39 -39
- package/src/runtime/{task-attempts.ts → task-attempts.js} +61 -61
- package/src/runtime/{task-classifier.ts → task-classifier.js} +34 -34
- package/src/runtime/{task-scope.ts → task-scope.js} +13 -13
- package/src/runtime/{task-state.ts → task-state.js} +15 -15
- package/src/runtime/trace/{indicators.ts → indicators.js} +22 -22
- package/src/runtime/trace/{ledger.ts → ledger.js} +42 -42
- package/src/runtime/trace/{render.ts → render.js} +7 -7
- package/src/runtime/trace/{views.ts → views.js} +40 -40
- package/src/runtime/verification/{contract-runner.ts → contract-runner.js} +23 -23
- package/src/runtime/verification/{engine.ts → engine.js} +143 -143
- package/src/runtime/verification/{registry.ts → registry.js} +6 -6
- package/src/runtime/verification/{scope-bound.ts → scope-bound.js} +50 -50
- package/src/runtime/verification/{test-selection.ts → test-selection.js} +28 -28
- package/src/runtime/{workflow-engine.ts → workflow-engine.js} +50 -50
- package/src/runtime/{workflow-orchestrator.ts → workflow-orchestrator.js} +91 -91
- package/src/runtime/{worktree.ts → worktree.js} +31 -31
- package/src/state/{index.ts → index.js} +26 -26
- package/src/state/{lockfile.ts → lockfile.js} +20 -20
- package/src/state/{run-lock.ts → run-lock.js} +44 -44
|
@@ -6,31 +6,31 @@
|
|
|
6
6
|
// restores per tool, as it always did.
|
|
7
7
|
// TypeScript migration (agent-docs/BRIEF_GOAL_DOFLOW.md): run directly by Node native type-stripping.
|
|
8
8
|
const path = require('node:path');
|
|
9
|
-
const { resolveTargets, toolDirs } = require('../../install/targets.
|
|
10
|
-
const { resolveContext, printContext } = require('../../install/context.
|
|
9
|
+
const { resolveTargets, toolDirs } = require('../../install/targets.js');
|
|
10
|
+
const { resolveContext, printContext } = require('../../install/context.js');
|
|
11
11
|
const {
|
|
12
12
|
BackupError, createFileBackup, planRestore, executeRestore, listBackups, formatBytes,
|
|
13
|
-
} = require('../../install/backup.
|
|
14
|
-
const { backupSetFromPaths } = require('../../install/backup-set.
|
|
15
|
-
const { writeManifest } = require('../../install/manifest.
|
|
16
|
-
const { stateRoot, ledgerPath } = require('../../state/index.
|
|
17
|
-
const { confirm, promptLine } = require('../../helper/prompt.
|
|
18
|
-
const { sourceCommit } = require('../../helper/git.
|
|
19
|
-
const { captureCaught } = require('../../runtime/cli-result.
|
|
13
|
+
} = require('../../install/backup.js');
|
|
14
|
+
const { backupSetFromPaths } = require('../../install/backup-set.js');
|
|
15
|
+
const { writeManifest } = require('../../install/manifest.js');
|
|
16
|
+
const { stateRoot, ledgerPath } = require('../../state/index.js');
|
|
17
|
+
const { confirm, promptLine } = require('../../helper/prompt.js');
|
|
18
|
+
const { sourceCommit } = require('../../helper/git.js');
|
|
19
|
+
const { captureCaught } = require('../../runtime/cli-result.js');
|
|
20
20
|
const {
|
|
21
21
|
REPO_ROOT, SCRIPT_DIR, pkg, installPaths, printBackupTable, holdRunLock, checkpointRunLock,
|
|
22
|
-
} = require('../shared.
|
|
22
|
+
} = require('../shared.js');
|
|
23
23
|
|
|
24
24
|
const LISTED_ABSENT = 10;
|
|
25
25
|
|
|
26
|
-
function fail(error
|
|
26
|
+
function fail(error ) {
|
|
27
27
|
captureCaught(error, 'rollback', 1);
|
|
28
28
|
console.error(`[ERROR] ${error.message}`);
|
|
29
29
|
console.error('[ERROR] Use --list-backups to see available backups');
|
|
30
30
|
process.exit(1);
|
|
31
31
|
}
|
|
32
32
|
|
|
33
|
-
function cmdRollback(o
|
|
33
|
+
function cmdRollback(o ) {
|
|
34
34
|
const targets = resolveTargets(o.targets);
|
|
35
35
|
const dirs = toolDirs({ global: o.global, projectRoot: '.' });
|
|
36
36
|
const scope = { global: o.global, projectRoot: '.' };
|
|
@@ -50,7 +50,7 @@ function cmdRollback(o: any): void {
|
|
|
50
50
|
}
|
|
51
51
|
|
|
52
52
|
// Worked out before anything is written. Reads only, so a bad id fails here, before the prompt.
|
|
53
|
-
let plan
|
|
53
|
+
let plan ;
|
|
54
54
|
try {
|
|
55
55
|
const neutralStateRoot = stateRoot({ scope: scopeName, projectRoot: lifecyclePaths.scopeRoot, homeDir: lifecyclePaths.scopeRoot });
|
|
56
56
|
plan = planRestore({ bid, backupRoot, scope: scopeName, scopeRoot: lifecyclePaths.scopeRoot, targets, explicitTargets, dirs,
|
|
@@ -61,7 +61,7 @@ function cmdRollback(o: any): void {
|
|
|
61
61
|
// A per-file backup restores the harnesses it holds (only those in --target when given), so the
|
|
62
62
|
// banner and the install manifest name those, not the default target.
|
|
63
63
|
const restoredTools = plan.format === 2
|
|
64
|
-
? [...new Set(plan.restore.flatMap((item
|
|
64
|
+
? [...new Set(plan.restore.flatMap((item ) => item.harnesses))].filter((h) => !explicitTargets || targets.includes(h)).sort()
|
|
65
65
|
: targets;
|
|
66
66
|
printContext(resolveContext({ repoRoot: REPO_ROOT, targets: restoredTools, dirs, sourceCommit: commit, global: o.global, projectRoot: '.' }));
|
|
67
67
|
|
|
@@ -87,7 +87,7 @@ function cmdRollback(o: any): void {
|
|
|
87
87
|
|
|
88
88
|
snapshotBeforeRestore({ o, plan, bid, backupRoot, lifecyclePaths, scopeName, commit });
|
|
89
89
|
|
|
90
|
-
let result
|
|
90
|
+
let result ;
|
|
91
91
|
try {
|
|
92
92
|
result = executeRestore(plan, { backupRoot, dryRun: o.dryRun });
|
|
93
93
|
} catch (error) {
|
|
@@ -134,7 +134,7 @@ function cmdRollback(o: any): void {
|
|
|
134
134
|
/** A backup of exactly the files the restore will overwrite, taken regardless of --no-backup:
|
|
135
135
|
* rollback is destructive enough that skipping it is not offered. Skipped when the restore
|
|
136
136
|
* overwrites nothing, so an empty snapshot never pushes a real restore point out of retention. */
|
|
137
|
-
function snapshotBeforeRestore({ o, plan, bid, backupRoot, lifecyclePaths, scopeName, commit }
|
|
137
|
+
function snapshotBeforeRestore({ o, plan, bid, backupRoot, lifecyclePaths, scopeName, commit } ) {
|
|
138
138
|
if (o.dryRun) {
|
|
139
139
|
console.log(`[DRY] Would snapshot ${plan.snapshot.length} file(s) before restoring`);
|
|
140
140
|
return;
|
|
@@ -157,7 +157,7 @@ function snapshotBeforeRestore({ o, plan, bid, backupRoot, lifecyclePaths, scope
|
|
|
157
157
|
});
|
|
158
158
|
snapshot = createFileBackup({ operation: 'pre-rollback', set, backupRoot, repoRoot: SCRIPT_DIR, sourceCommit: commit,
|
|
159
159
|
version: pkg.version, date: new Date(), restores: bid });
|
|
160
|
-
} catch (error
|
|
160
|
+
} catch (error ) {
|
|
161
161
|
if (!(error instanceof BackupError)) throw error;
|
|
162
162
|
console.error(`[ERROR] Pre-rollback snapshot failed, nothing was restored: ${error.message}`);
|
|
163
163
|
process.exit(1);
|
|
@@ -3,10 +3,10 @@
|
|
|
3
3
|
// installed trees match the freshly pulled source.
|
|
4
4
|
// TypeScript migration (agent-docs/BRIEF_GOAL_DOFLOW.md): run directly by Node native type-stripping.
|
|
5
5
|
const { execFileSync } = require('node:child_process');
|
|
6
|
-
const { REPO_ROOT } = require('../shared.
|
|
7
|
-
const cmdInstall = require('./install.
|
|
6
|
+
const { REPO_ROOT } = require('../shared.js');
|
|
7
|
+
const cmdInstall = require('./install.js');
|
|
8
8
|
|
|
9
|
-
function cmdSelfUpdate(o
|
|
9
|
+
function cmdSelfUpdate(o ) {
|
|
10
10
|
console.log('[INFO] Self-update: checking for upstream changes...');
|
|
11
11
|
let pulled = false;
|
|
12
12
|
let fetchOk = false;
|
|
@@ -4,35 +4,35 @@
|
|
|
4
4
|
// scripting).
|
|
5
5
|
// TypeScript migration (agent-docs/BRIEF_GOAL_DOFLOW.md): run directly by Node native type-stripping.
|
|
6
6
|
const path = require('node:path');
|
|
7
|
-
const { resolveTargets, toolDirs } = require('../../install/targets.
|
|
8
|
-
const { resolveContext, printContext } = require('../../install/context.
|
|
9
|
-
const { readInstallManifest } = require('../../install/manifest.
|
|
10
|
-
const { sourceCommit } = require('../../helper/git.
|
|
11
|
-
const { loadRegistry, mcpCapable } = require('../../registry/index.
|
|
12
|
-
const { recordedMcpSelections } = require('../../install/mcp.
|
|
13
|
-
const { pinnedSelections } = require('../../state/lockfile.
|
|
14
|
-
const { readLedger } = require('../../state/index.
|
|
15
|
-
const { verifyLifecycle } = require('../../lifecycle/index.
|
|
16
|
-
const { registryLifecycleView, LIFECYCLE_HARNESSES } = require('../../lifecycle/view.
|
|
17
|
-
const { REPO_ROOT, SCRIPT_DIR, installPaths, scopeOf, scopeSelectionState } = require('../shared.
|
|
7
|
+
const { resolveTargets, toolDirs } = require('../../install/targets.js');
|
|
8
|
+
const { resolveContext, printContext } = require('../../install/context.js');
|
|
9
|
+
const { readInstallManifest } = require('../../install/manifest.js');
|
|
10
|
+
const { sourceCommit } = require('../../helper/git.js');
|
|
11
|
+
const { loadRegistry, mcpCapable } = require('../../registry/index.js');
|
|
12
|
+
const { recordedMcpSelections } = require('../../install/mcp.js');
|
|
13
|
+
const { pinnedSelections } = require('../../state/lockfile.js');
|
|
14
|
+
const { readLedger } = require('../../state/index.js');
|
|
15
|
+
const { verifyLifecycle } = require('../../lifecycle/index.js');
|
|
16
|
+
const { registryLifecycleView, LIFECYCLE_HARNESSES } = require('../../lifecycle/view.js');
|
|
17
|
+
const { REPO_ROOT, SCRIPT_DIR, installPaths, scopeOf, scopeSelectionState } = require('../shared.js');
|
|
18
18
|
|
|
19
|
-
function cmdStatus(o
|
|
19
|
+
function cmdStatus(o ) {
|
|
20
20
|
const targets = resolveTargets(o.targets);
|
|
21
21
|
const scope = scopeOf(o);
|
|
22
22
|
const dirs = toolDirs(scope);
|
|
23
23
|
const lifecyclePaths = installPaths(scope);
|
|
24
|
-
const ctx
|
|
24
|
+
const ctx = resolveContext({ repoRoot: REPO_ROOT, targets, dirs, sourceCommit: sourceCommit(SCRIPT_DIR), ...scope });
|
|
25
25
|
const manifest = readInstallManifest({ scopeRoot: lifecyclePaths.scopeRoot });
|
|
26
|
-
let registryView
|
|
26
|
+
let registryView = null;
|
|
27
27
|
// Per MCP-capable target, the servers doflow.lock records for it, or null when it records none.
|
|
28
|
-
let mcpSelections
|
|
28
|
+
let mcpSelections = null;
|
|
29
29
|
try {
|
|
30
30
|
const registry = loadRegistry({ repoRoot: REPO_ROOT });
|
|
31
31
|
const { lock, ledger, manifestServers } = scopeSelectionState(scope);
|
|
32
32
|
const recorded = recordedMcpSelections({ registry, lock, ledger, targets, manifestServers });
|
|
33
33
|
const rows = pinnedSelections(lock);
|
|
34
|
-
mcpSelections = Object.fromEntries(targets.filter((harness
|
|
35
|
-
.map((harness
|
|
34
|
+
mcpSelections = Object.fromEntries(targets.filter((harness ) => mcpCapable(registry, harness))
|
|
35
|
+
.map((harness ) => [harness, rows[harness] ?? null]));
|
|
36
36
|
registryView = registryLifecycleView({ registry, repoRoot: REPO_ROOT, scope, dirs, targets,
|
|
37
37
|
mcpSelections: recorded.selections, mcpAdoptable: recorded.adoptable, retainedMcpIds: recorded.retainedMcpIds });
|
|
38
38
|
ctx.registry = {
|
|
@@ -46,17 +46,17 @@ function cmdStatus(o: any): void {
|
|
|
46
46
|
// registryView.plan.changes/conflicts across every target — otherwise, e.g., Codex having
|
|
47
47
|
// pending changes when it isn't installed yet would make Claude's line falsely report
|
|
48
48
|
// 'drift-or-pending-change' even though Claude itself has nothing pending.
|
|
49
|
-
const harnessPlan = (harness
|
|
49
|
+
const harnessPlan = (harness ) => registryView.plan.targets.find((target ) => target.harness === harness);
|
|
50
50
|
// Hook-wiring status needs the same general per-harness verification every install/update run
|
|
51
51
|
// already flows through (src/lifecycle's verifyLifecycle) rather than a Codex-only hardcode:
|
|
52
52
|
// it is the one place that can tell 'installed and active' apart from 'installed but pending a
|
|
53
53
|
// prerequisite' (Codex's unreviewed trust, Gemini's live hook-trust check) from 'absent'.
|
|
54
54
|
const verification = verifyLifecycle({ plan: registryView.plan, adapters: registryView.adapters, context: { registry } });
|
|
55
|
-
const hooksFor = (harness
|
|
56
|
-
const harnessStatus = (harness
|
|
55
|
+
const hooksFor = (harness ) => verification.verifications.find((item ) => item.harness === harness)?.hookWiring ?? null;
|
|
56
|
+
const harnessStatus = (harness ) => {
|
|
57
57
|
const target = harnessPlan(harness);
|
|
58
58
|
if (!target) return { status: 'verified', resources: [], errors: [], hooks: hooksFor(harness) };
|
|
59
|
-
const resources = registryView.ledger.resources.filter((resource
|
|
59
|
+
const resources = registryView.ledger.resources.filter((resource ) => resource.harness === harness);
|
|
60
60
|
// A conflict is reported first: a user-owned file in the way is not the same as nothing being
|
|
61
61
|
// installed. With no conflict, a harness the ledger owns nothing of was never installed: its
|
|
62
62
|
// whole plan is pending, which is not drift from an installation that does not exist.
|
|
@@ -75,7 +75,7 @@ function cmdStatus(o: any): void {
|
|
|
75
75
|
for (const harness of LIFECYCLE_HARNESSES) {
|
|
76
76
|
if (targets.includes(harness)) ctx[harness] = harnessStatus(harness);
|
|
77
77
|
}
|
|
78
|
-
} catch (error
|
|
78
|
+
} catch (error ) {
|
|
79
79
|
// Status must remain usable for an existing installation even if a local registry is invalid.
|
|
80
80
|
ctx.registry = { status: 'invalid', error: error.message };
|
|
81
81
|
}
|
|
@@ -85,7 +85,7 @@ function cmdStatus(o: any): void {
|
|
|
85
85
|
return;
|
|
86
86
|
}
|
|
87
87
|
|
|
88
|
-
const hookLine = (label
|
|
88
|
+
const hookLine = (label , hooks ) => {
|
|
89
89
|
if (!hooks || hooks.status === 'absent') return null;
|
|
90
90
|
const prereqSuffix = hooks.prerequisites.length ? ` (unmet: ${hooks.prerequisites.join(', ')})` : '';
|
|
91
91
|
return ` ${label} hooks: ${hooks.status}${prereqSuffix}`;
|
|
@@ -104,7 +104,7 @@ function cmdStatus(o: any): void {
|
|
|
104
104
|
console.log(` Last backup ID: ${manifest.backupId}`);
|
|
105
105
|
console.log(` Script version: ${manifest.scriptVersion}`);
|
|
106
106
|
if (mcpSelections && Object.keys(mcpSelections).length) {
|
|
107
|
-
const recordedText = (ids
|
|
107
|
+
const recordedText = (ids ) => (ids === null ? 'not recorded' : ids.join(', ') || 'none');
|
|
108
108
|
console.log(` MCP selections: ${Object.entries(mcpSelections).map(([harness, ids]) => `${harness} ${recordedText(ids)}`).join('; ')}`);
|
|
109
109
|
}
|
|
110
110
|
// Printed in the same order LIFECYCLE_HARNESSES declares, so every wired harness gets a line —
|
|
@@ -2,34 +2,34 @@
|
|
|
2
2
|
// `doflow tools` — inspect or manage registered external tools (status/install/update/uninstall).
|
|
3
3
|
// --force is deliberately unavailable: every mutation gets its own confirmation.
|
|
4
4
|
// TypeScript migration (agent-docs/BRIEF_GOAL_DOFLOW.md): run directly by Node native type-stripping.
|
|
5
|
-
const { confirm, promptLine } = require('../../helper/prompt.
|
|
6
|
-
const { loadRegistry } = require('../../registry/index.
|
|
7
|
-
const { commandText, planToolLifecycle, executeToolLifecycle } = require('../../install/tool-lifecycle.
|
|
8
|
-
const { REPO_ROOT } = require('../shared.
|
|
5
|
+
const { confirm, promptLine } = require('../../helper/prompt.js');
|
|
6
|
+
const { loadRegistry } = require('../../registry/index.js');
|
|
7
|
+
const { commandText, planToolLifecycle, executeToolLifecycle } = require('../../install/tool-lifecycle.js');
|
|
8
|
+
const { REPO_ROOT } = require('../shared.js');
|
|
9
9
|
|
|
10
|
-
function selectExternalTools(registry
|
|
10
|
+
function selectExternalTools(registry , o ) {
|
|
11
11
|
let requested = o.tools;
|
|
12
12
|
if (!requested) {
|
|
13
13
|
const interactive = Boolean(process.stdin.isTTY) && Boolean(process.stdout.isTTY);
|
|
14
14
|
if (!interactive) throw new Error("doflow tools: --tool is required when stdin is not an interactive terminal");
|
|
15
15
|
const answer = promptLine('Select tools (rtk, graphify; comma-separated): ');
|
|
16
|
-
requested = answer.split(',').map((item
|
|
16
|
+
requested = answer.split(',').map((item ) => item.trim()).filter(Boolean);
|
|
17
17
|
}
|
|
18
18
|
if (!requested.length) throw new Error('doflow tools: select at least one tool');
|
|
19
|
-
const available = new Set(registry.externalTools.map((tool
|
|
19
|
+
const available = new Set(registry.externalTools.map((tool ) => tool.id));
|
|
20
20
|
const unknown = [...new Set(requested)].filter((id) => !available.has(id));
|
|
21
21
|
if (unknown.length) throw new Error(`doflow tools: unknown tool id(s): ${unknown.join(', ')}; expected: ${[...available].join(', ')}`);
|
|
22
22
|
const wanted = new Set(requested);
|
|
23
|
-
return registry.externalTools.filter((tool
|
|
23
|
+
return registry.externalTools.filter((tool ) => wanted.has(tool.id));
|
|
24
24
|
}
|
|
25
25
|
|
|
26
|
-
function toolJsonResults(plan
|
|
27
|
-
const executed = new Map((execution?.results || []).map((result
|
|
28
|
-
return plan.tools.map((item
|
|
26
|
+
function toolJsonResults(plan , execution = null) {
|
|
27
|
+
const executed = new Map((execution?.results || []).map((result ) => [result.tool, result]));
|
|
28
|
+
return plan.tools.map((item ) => ({
|
|
29
29
|
tool: item.tool.id,
|
|
30
30
|
state: item.state,
|
|
31
31
|
inspections: item.inspections,
|
|
32
|
-
prerequisites: item.prerequisites.map((prerequisite
|
|
32
|
+
prerequisites: item.prerequisites.map((prerequisite ) => ({ name: prerequisite.name, available: prerequisite.available })),
|
|
33
33
|
action: item.action,
|
|
34
34
|
result: executed.get(item.tool.id) ?? (item.action.applicable
|
|
35
35
|
? { tool: item.tool.id, status: 'not-attempted', command: [...item.action.command] }
|
|
@@ -37,7 +37,7 @@ function toolJsonResults(plan: any, execution: any = null): any[] {
|
|
|
37
37
|
}));
|
|
38
38
|
}
|
|
39
39
|
|
|
40
|
-
function cmdTools(o
|
|
40
|
+
function cmdTools(o ) {
|
|
41
41
|
if (o.force) throw new Error("doflow tools: --force is not supported; each lifecycle command requires its own confirmation");
|
|
42
42
|
if (!['status', 'install', 'update', 'uninstall'].includes(o.action)) {
|
|
43
43
|
throw new Error(`doflow tools: unsupported action '${o.action}'; expected: status, install, update, uninstall`);
|
|
@@ -72,12 +72,12 @@ function cmdTools(o: any): void {
|
|
|
72
72
|
|
|
73
73
|
const execution = executeToolLifecycle({
|
|
74
74
|
plan,
|
|
75
|
-
displayCommand: (command
|
|
76
|
-
confirmCommand: (command
|
|
75
|
+
displayCommand: (command , tool ) => console.error(`[INFO] ${tool.displayName}: ${commandText(command)}`),
|
|
76
|
+
confirmCommand: (command , tool , action ) => confirm(`Run ${tool.displayName} ${action}: ${commandText(command)}?`, false),
|
|
77
77
|
});
|
|
78
78
|
// Keep processing independent tools so the user receives every outcome, but make a confirmed
|
|
79
79
|
// command failure visible to scripts and CI through the process result as well as the report.
|
|
80
|
-
const hasFailures = execution.results.some((result
|
|
80
|
+
const hasFailures = execution.results.some((result ) => result.status === 'failed');
|
|
81
81
|
if (o.json) {
|
|
82
82
|
console.log(JSON.stringify({ action: o.action, dryRun: false, results: toolJsonResults(plan, execution) }, null, 2));
|
|
83
83
|
if (hasFailures) process.exitCode = 1;
|
|
@@ -4,30 +4,30 @@
|
|
|
4
4
|
// TypeScript migration (agent-docs/BRIEF_GOAL_DOFLOW.md): run directly by Node native type-stripping.
|
|
5
5
|
const os = require('node:os');
|
|
6
6
|
const path = require('node:path');
|
|
7
|
-
const { resolveTargets, toolDirs } = require('../../install/targets.
|
|
8
|
-
const { resolveContext, printContext } = require('../../install/context.
|
|
9
|
-
const { DEFAULT_BACKUP_RETENTION, createFileBackup, applyRetention, retentionNote } = require('../../install/backup.
|
|
10
|
-
const { backupSetFromPlan } = require('../../install/backup-set.
|
|
11
|
-
const { ledgerPath } = require('../../state/index.
|
|
12
|
-
const { backupStep, reportBackup, printBackupDryRun, applyBackupRetention } = require('./install.
|
|
13
|
-
const { writeManifest, readInstallManifest } = require('../../install/manifest.
|
|
14
|
-
const { confirm } = require('../../helper/prompt.
|
|
15
|
-
const { sourceCommit } = require('../../helper/git.
|
|
16
|
-
const { chmodHooksExecutable } = require('../../helper/settings-scope.
|
|
17
|
-
const { resolveMcpSelections } = require('../../install/mcp.
|
|
18
|
-
const { loadRegistry } = require('../../registry/index.
|
|
19
|
-
const { storageAfterInstall } = require('../../runtime/storage/upkeep.
|
|
20
|
-
const { applyLifecycle, recordMcpOwnership, retentionSummary } = require('../../lifecycle/index.
|
|
7
|
+
const { resolveTargets, toolDirs } = require('../../install/targets.js');
|
|
8
|
+
const { resolveContext, printContext } = require('../../install/context.js');
|
|
9
|
+
const { DEFAULT_BACKUP_RETENTION, createFileBackup, applyRetention, retentionNote } = require('../../install/backup.js');
|
|
10
|
+
const { backupSetFromPlan } = require('../../install/backup-set.js');
|
|
11
|
+
const { ledgerPath } = require('../../state/index.js');
|
|
12
|
+
const { backupStep, reportBackup, printBackupDryRun, applyBackupRetention } = require('./install.js');
|
|
13
|
+
const { writeManifest, readInstallManifest } = require('../../install/manifest.js');
|
|
14
|
+
const { confirm } = require('../../helper/prompt.js');
|
|
15
|
+
const { sourceCommit } = require('../../helper/git.js');
|
|
16
|
+
const { chmodHooksExecutable } = require('../../helper/settings-scope.js');
|
|
17
|
+
const { resolveMcpSelections } = require('../../install/mcp.js');
|
|
18
|
+
const { loadRegistry } = require('../../registry/index.js');
|
|
19
|
+
const { storageAfterInstall } = require('../../runtime/storage/upkeep.js');
|
|
20
|
+
const { applyLifecycle, recordMcpOwnership, retentionSummary } = require('../../lifecycle/index.js');
|
|
21
21
|
const {
|
|
22
22
|
codexScope, registryLifecycleView, printRegistryLifecycle, printPlanNotices, assertSafeRegistryPlan,
|
|
23
23
|
lockDocument, lockDelta, recordLock,
|
|
24
|
-
} = require('../../lifecycle/view.
|
|
24
|
+
} = require('../../lifecycle/view.js');
|
|
25
25
|
const {
|
|
26
26
|
REPO_ROOT, SCRIPT_DIR, pkg, scopeOf, installPaths, reportRetiredMcp, scopeSelectionState, printMcpSelection, plannedMcpSelections,
|
|
27
27
|
printRecordedMcpOwnership, buildAdapterRegistry, refuseHomeRootedProject, holdRunLock, checkpointRunLock,
|
|
28
|
-
} = require('../shared.
|
|
28
|
+
} = require('../shared.js');
|
|
29
29
|
|
|
30
|
-
function cmdUpdate(o
|
|
30
|
+
function cmdUpdate(o ) {
|
|
31
31
|
refuseHomeRootedProject(o, 'update');
|
|
32
32
|
const targets = resolveTargets(o.targets);
|
|
33
33
|
const scope = scopeOf(o);
|
|
@@ -69,7 +69,7 @@ function cmdUpdate(o: any): void {
|
|
|
69
69
|
const keep = o.prune ?? DEFAULT_BACKUP_RETENTION;
|
|
70
70
|
|
|
71
71
|
const lockArgs = scope.global ? { scope: 'global', homeDir: os.homedir() } : { scope: 'project', projectRoot: path.resolve(scope.projectRoot) };
|
|
72
|
-
const nextLock = (ledgerAfter
|
|
72
|
+
const nextLock = (ledgerAfter ) => lockDocument({
|
|
73
73
|
registry, scope: codexScope(scope), scopeRoot: scope.global ? os.homedir() : path.resolve(scope.projectRoot),
|
|
74
74
|
previous: lock, ledger: ledgerAfter, plannedTargets: targets, mcpSelections: plannedMcpSelections(lifecycleView),
|
|
75
75
|
});
|
|
@@ -136,7 +136,7 @@ function cmdUpdate(o: any): void {
|
|
|
136
136
|
stateRoot: lifecycleView.stateRoot, ledger: lifecycleView.ledger });
|
|
137
137
|
for (const target of lifecycleView.plan.targets) {
|
|
138
138
|
if (target.skipped || !target.changes.length) continue;
|
|
139
|
-
const owned = result.ledger.resources.filter((resource
|
|
139
|
+
const owned = result.ledger.resources.filter((resource ) => resource.harness === target.harness).length;
|
|
140
140
|
console.log(`[INFO] ${target.harness}: lifecycle verified (${owned} owned resource(s))`);
|
|
141
141
|
}
|
|
142
142
|
printPlanNotices(lifecycleView);
|
|
@@ -11,25 +11,25 @@
|
|
|
11
11
|
const {
|
|
12
12
|
handleCapabilitiesCommand, handleReadinessCommand, handleEvidenceCommand,
|
|
13
13
|
EVIDENCE_SCORE_FIELDS, scoreFieldRefusal,
|
|
14
|
-
} = require('../runtime/cli.
|
|
15
|
-
const { pkg } = require('./shared.
|
|
16
|
-
const { VALID: VALID_TARGETS, DEFAULT_TARGETS } = require('../install/targets.
|
|
17
|
-
const { dispatchRuntimeCommand } = require('./runtime-commands.
|
|
18
|
-
const { usageError } = require('../runtime/cli-result.
|
|
14
|
+
} = require('../runtime/cli.js');
|
|
15
|
+
const { pkg } = require('./shared.js');
|
|
16
|
+
const { VALID: VALID_TARGETS, DEFAULT_TARGETS } = require('../install/targets.js');
|
|
17
|
+
const { dispatchRuntimeCommand } = require('./runtime-commands.js');
|
|
18
|
+
const { usageError } = require('../runtime/cli-result.js');
|
|
19
19
|
|
|
20
|
-
const cmdInstall = require('./commands/install.
|
|
21
|
-
const cmdUpdate = require('./commands/update.
|
|
22
|
-
const cmdReconcile = require('./commands/reconcile.
|
|
23
|
-
const cmdRemove = require('./commands/remove.
|
|
24
|
-
const cmdStatus = require('./commands/status.
|
|
25
|
-
const cmdTools = require('./commands/tools.
|
|
26
|
-
const cmdListBackups = require('./commands/list-backups.
|
|
27
|
-
const cmdRollback = require('./commands/rollback.
|
|
28
|
-
const cmdSelfUpdate = require('./commands/self-update.
|
|
20
|
+
const cmdInstall = require('./commands/install.js');
|
|
21
|
+
const cmdUpdate = require('./commands/update.js');
|
|
22
|
+
const cmdReconcile = require('./commands/reconcile.js');
|
|
23
|
+
const cmdRemove = require('./commands/remove.js');
|
|
24
|
+
const cmdStatus = require('./commands/status.js');
|
|
25
|
+
const cmdTools = require('./commands/tools.js');
|
|
26
|
+
const cmdListBackups = require('./commands/list-backups.js');
|
|
27
|
+
const cmdRollback = require('./commands/rollback.js');
|
|
28
|
+
const cmdSelfUpdate = require('./commands/self-update.js');
|
|
29
29
|
|
|
30
30
|
/** The installer command surface, written down once. The runtime verbs are dispatched separately
|
|
31
31
|
* (see ./runtime-commands) because their namespace is owned by the doflow-run verb table. */
|
|
32
|
-
const COMMANDS
|
|
32
|
+
const COMMANDS = {
|
|
33
33
|
install: cmdInstall,
|
|
34
34
|
update: cmdUpdate,
|
|
35
35
|
reconcile: cmdReconcile,
|
|
@@ -42,15 +42,15 @@ const COMMANDS: Record<string, (o: any) => any> = {
|
|
|
42
42
|
};
|
|
43
43
|
|
|
44
44
|
/** "skip all backup protection" must be an explicit, deliberate choice, never a default combo. */
|
|
45
|
-
function assertNoBackupRequiresForce(o
|
|
45
|
+
function assertNoBackupRequiresForce(o ) {
|
|
46
46
|
if (o.noBackup && !o.force) {
|
|
47
47
|
console.error('doflow: --no-backup skips all backup protection and requires --force');
|
|
48
48
|
process.exit(1);
|
|
49
49
|
}
|
|
50
50
|
}
|
|
51
51
|
|
|
52
|
-
function parseArgs(argv
|
|
53
|
-
const o
|
|
52
|
+
function parseArgs(argv ) {
|
|
53
|
+
const o = { cmd: null, positional: [], targets: [], mcp: null, dryRun: false, force: false, adopt: false,
|
|
54
54
|
noBackup: false, prune: null, global: false, json: false, help: false, version: false,
|
|
55
55
|
tools: null, action: 'status', days: null, slug: null,
|
|
56
56
|
// Explicitly null, not absent. `handleReadinessCommand` declares defaults of `'feature'` and
|
|
@@ -324,12 +324,12 @@ const RUNTIME_INT_FLAGS = new Map([
|
|
|
324
324
|
*
|
|
325
325
|
* Returns the new loop index, or null when `arg` is not a runtime flag.
|
|
326
326
|
*/
|
|
327
|
-
function parseRuntimeFlag(arg
|
|
327
|
+
function parseRuntimeFlag(arg , argv , i , o ) {
|
|
328
328
|
const eq = arg.indexOf('=');
|
|
329
329
|
const name = eq === -1 ? arg : arg.slice(0, eq);
|
|
330
330
|
// A score-shaped flag is refused by name rather than falling through to "unknown flag", which
|
|
331
331
|
// reads as "not built yet" and invites someone to build it. The name set and the reason both
|
|
332
|
-
// come from the evidence write boundary (src/runtime/cli.
|
|
332
|
+
// come from the evidence write boundary (src/runtime/cli.js), so argv and a --batch JSON file
|
|
333
333
|
// are refused by one rule with two enforcement points rather than two rules.
|
|
334
334
|
const camel = name.replace(/^--/, '').replace(/-([a-z])/g, (_, c) => c.toUpperCase());
|
|
335
335
|
if (EVIDENCE_SCORE_FIELDS.has(camel)) { console.error(`doflow: ${scoreFieldRefusal(name)}`); process.exit(2); }
|
|
@@ -337,7 +337,7 @@ function parseRuntimeFlag(arg: string, argv: string[], i: number, o: any): numbe
|
|
|
337
337
|
const key = RUNTIME_STRING_FLAGS.get(name) || RUNTIME_LIST_FLAGS.get(name) || RUNTIME_INT_FLAGS.get(name);
|
|
338
338
|
if (!key) return null;
|
|
339
339
|
|
|
340
|
-
let value
|
|
340
|
+
let value = inline;
|
|
341
341
|
let next = i;
|
|
342
342
|
if (value === null) {
|
|
343
343
|
value = argv[i + 1];
|
|
@@ -363,7 +363,7 @@ function parseRuntimeFlag(arg: string, argv: string[], i: number, o: any): numbe
|
|
|
363
363
|
// spelling's comma-splitting, this generic path handling both spellings but never splitting),
|
|
364
364
|
// so `--exclude=bin,src` silently excluded nothing while `--exclude bin,src` worked. One path,
|
|
365
365
|
// both spellings, same behavior now.
|
|
366
|
-
const parts = name === '--exclude' ? value.split(',').map((s
|
|
366
|
+
const parts = name === '--exclude' ? value.split(',').map((s ) => s.trim()).filter(Boolean) : [value];
|
|
367
367
|
(o[key] = o[key] || []).push(...parts);
|
|
368
368
|
} else if (name === '--evidence-id' && o.cmd === 'research-request') {
|
|
369
369
|
(o.evidenceIds = o.evidenceIds || []).push(value);
|
|
@@ -527,14 +527,14 @@ External tools:
|
|
|
527
527
|
const COMMAND_NAMES = new Set([...Object.keys(COMMANDS), ...[...HELP.matchAll(/^ ([a-z][a-z-]*) {2,}\S/gm)].map((m) => m[1])]);
|
|
528
528
|
|
|
529
529
|
/** `name` when it is one of DoFlow's own command names, else `unknown`. */
|
|
530
|
-
function commandName(name
|
|
530
|
+
function commandName(name ) { return typeof name === 'string' && COMMAND_NAMES.has(name) ? name : 'unknown'; }
|
|
531
531
|
|
|
532
532
|
/**
|
|
533
533
|
* Run one CLI invocation. Same behavior as the pre-extraction monolith's main(): --version and
|
|
534
534
|
* --help answer first, --no-backup-without-force is refused, then the command resolves either
|
|
535
535
|
* through the installer table above or through the runtime-verb dispatcher.
|
|
536
536
|
*/
|
|
537
|
-
async function main(argv
|
|
537
|
+
async function main(argv ) {
|
|
538
538
|
const o = parseArgs(argv);
|
|
539
539
|
if (o.version) { console.log(pkg.version); return; }
|
|
540
540
|
if (o.help || !o.cmd) { console.log(HELP); return; }
|
|
@@ -546,11 +546,11 @@ async function main(argv: string[]): Promise<any> {
|
|
|
546
546
|
const handler = COMMANDS[o.cmd];
|
|
547
547
|
if (handler) return handler(o);
|
|
548
548
|
return await dispatchRuntimeCommand(o);
|
|
549
|
-
} catch (error
|
|
549
|
+
} catch (error ) {
|
|
550
550
|
// Recorded silently when it is a programming error (IC-016); the output and exit status below
|
|
551
551
|
// are the same whether or not anything was written.
|
|
552
552
|
// Required here, not at load, so a CLI whose failure modules cannot be loaded still runs as today.
|
|
553
|
-
try { require('../runtime/failure/capture.
|
|
553
|
+
try { require('../runtime/failure/capture.js').captureError(error, { command: commandName(o.cmd), exit: 1 }); } catch { /* best-effort */ }
|
|
554
554
|
// A lifecycle apply/remove can throw mid-mutation (fs error, TOCTOU ownership mismatch on a
|
|
555
555
|
// multi-harness run) — surface a clean, actionable message instead of a raw stack trace, and
|
|
556
556
|
// point at the recovery record applyLifecycle already wrote before rethrowing.
|