@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.
Files changed (167) hide show
  1. package/bin/doflow.js +2 -2
  2. package/core/.claude-plugin/plugin.json +1 -1
  3. package/core/.codex-plugin/plugin.json +1 -1
  4. package/core/.plugin/plugin.json +1 -1
  5. package/core/registry/storage.json +87 -83
  6. package/core/registry/verification.json +1 -1
  7. package/core/shared/scripts/doflow/bash/render-puml.sh +2 -2
  8. package/core/shared/skills/do-execute-plan/references/scaffold.md +2 -2
  9. package/package.json +4 -2
  10. package/src/adapters/antigravity/{index.ts → index.js} +60 -60
  11. package/src/adapters/claude/{index.ts → index.js} +48 -48
  12. package/src/adapters/claude/{mcp.ts → mcp.js} +16 -16
  13. package/src/adapters/codex/{agents.ts → agents.js} +24 -24
  14. package/src/adapters/codex/{config.ts → config.js} +49 -49
  15. package/src/adapters/codex/{hooks.ts → hooks.js} +23 -23
  16. package/src/adapters/codex/{index.ts → index.js} +98 -98
  17. package/src/adapters/codex/{mcp.ts → mcp.js} +38 -38
  18. package/src/adapters/codex/{native-projection.ts → native-projection.js} +5 -5
  19. package/src/adapters/copilot/{index.ts → index.js} +42 -42
  20. package/src/adapters/{copy-tree.ts → copy-tree.js} +70 -70
  21. package/src/adapters/gemini/{hooks.ts → hooks.js} +24 -24
  22. package/src/adapters/gemini/{index.ts → index.js} +41 -41
  23. package/src/adapters/{hook-commands.ts → hook-commands.js} +8 -8
  24. package/src/adapters/{index.ts → index.js} +13 -13
  25. package/src/adapters/kiro/{index.ts → index.js} +34 -34
  26. package/src/adapters/{mcp-entries.ts → mcp-entries.js} +55 -55
  27. package/src/adapters/opencode/{index.ts → index.js} +52 -52
  28. package/src/adapters/pi/{index.ts → index.js} +30 -30
  29. package/src/adapters/pi/{json-members.ts → json-members.js} +23 -23
  30. package/src/adapters/pi/{mcp.ts → mcp.js} +70 -70
  31. package/src/adapters/{resolve-source.ts → resolve-source.js} +1 -1
  32. package/src/cli/commands/{install.ts → install.js} +24 -24
  33. package/src/cli/commands/{list-backups.ts → list-backups.js} +4 -4
  34. package/src/cli/commands/{reconcile.ts → reconcile.js} +19 -19
  35. package/src/cli/commands/{remove.ts → remove.js} +10 -10
  36. package/src/cli/commands/{rollback.ts → rollback.js} +17 -17
  37. package/src/cli/commands/{self-update.ts → self-update.js} +3 -3
  38. package/src/cli/commands/{status.ts → status.js} +24 -24
  39. package/src/cli/commands/{tools.ts → tools.js} +16 -16
  40. package/src/cli/commands/{update.ts → update.js} +19 -19
  41. package/src/cli/{index.ts → index.js} +26 -26
  42. package/src/cli/{runtime-commands.ts → runtime-commands.js} +48 -48
  43. package/src/cli/{shared.ts → shared.js} +40 -40
  44. package/src/helper/{bash-helper.ts → bash-helper.js} +7 -7
  45. package/src/helper/{git.ts → git.js} +2 -2
  46. package/src/helper/{guardrails.ts → guardrails.js} +10 -10
  47. package/src/helper/{harness-paths.ts → harness-paths.js} +24 -24
  48. package/src/helper/{marker-merge.ts → marker-merge.js} +4 -4
  49. package/src/helper/{prompt.ts → prompt.js} +5 -5
  50. package/src/helper/{repo-root.ts → repo-root.js} +2 -2
  51. package/src/helper/{settings-merge.ts → settings-merge.js} +27 -27
  52. package/src/helper/{settings-scope.ts → settings-scope.js} +3 -3
  53. package/src/helper/{toml.ts → toml.js} +48 -48
  54. package/src/install/{backup-set.ts → backup-set.js} +16 -16
  55. package/src/install/{backup.ts → backup.js} +65 -65
  56. package/src/install/{context.ts → context.js} +15 -15
  57. package/src/install/{manifest.ts → manifest.js} +27 -27
  58. package/src/install/{mcp.ts → mcp.js} +30 -30
  59. package/src/install/{paths.ts → paths.js} +15 -15
  60. package/src/install/{targets.ts → targets.js} +10 -10
  61. package/src/install/{tool-lifecycle.ts → tool-lifecycle.js} +20 -20
  62. package/src/lifecycle/{bash-availability.ts → bash-availability.js} +1 -1
  63. package/src/lifecycle/{index.ts → index.js} +140 -140
  64. package/src/lifecycle/{mcp-index.ts → mcp-index.js} +1 -1
  65. package/src/lifecycle/{policies.ts → policies.js} +11 -11
  66. package/src/lifecycle/{view.ts → view.js} +28 -28
  67. package/src/registry/{index.ts → index.js} +60 -60
  68. package/src/release/build-package.js +91 -0
  69. package/src/release/changelog-section.js +70 -0
  70. package/src/release/{sync-plugin-versions.ts → sync-plugin-versions.js} +4 -4
  71. package/src/runtime/advice/{cli.ts → cli.js} +31 -31
  72. package/src/runtime/advice/{client.ts → client.js} +44 -44
  73. package/src/runtime/advice/{config.ts → config.js} +16 -16
  74. package/src/runtime/advice/{doctor.ts → doctor.js} +32 -32
  75. package/src/runtime/advice/{endpoint-guard.ts → endpoint-guard.js} +20 -20
  76. package/src/runtime/advice/{kinds.ts → kinds.js} +16 -16
  77. package/src/runtime/advice/providers/{ollama-systemone.ts → ollama-systemone.js} +21 -21
  78. package/src/runtime/advice/{record.ts → record.js} +19 -19
  79. package/src/runtime/advice/{registry.ts → registry.js} +16 -16
  80. package/src/runtime/advice/{strength.ts → strength.js} +7 -7
  81. package/src/runtime/{brief-tools.ts → brief-tools.js} +50 -50
  82. package/src/runtime/{c4-project.ts → c4-project.js} +27 -27
  83. package/src/runtime/{capability-router.ts → capability-router.js} +39 -39
  84. package/src/runtime/{checkouts.ts → checkouts.js} +21 -21
  85. package/src/runtime/{claims.ts → claims.js} +30 -30
  86. package/src/runtime/{cli-result.ts → cli-result.js} +4 -4
  87. package/src/runtime/{cli.ts → cli.js} +37 -37
  88. package/src/runtime/{command-detect.ts → command-detect.js} +47 -47
  89. package/src/runtime/{context-pack.ts → context-pack.js} +20 -20
  90. package/src/runtime/{decision-register.ts → decision-register.js} +67 -67
  91. package/src/runtime/{evidence-ledger.ts → evidence-ledger.js} +25 -25
  92. package/src/runtime/failure/{capture.ts → capture.js} +29 -29
  93. package/src/runtime/failure/{classifier.ts → classifier.js} +4 -4
  94. package/src/runtime/failure/{cli.ts → cli.js} +30 -30
  95. package/src/runtime/failure/{home.ts → home.js} +6 -6
  96. package/src/runtime/failure/{store.ts → store.js} +32 -32
  97. package/src/runtime/{feature-resolve.ts → feature-resolve.js} +6 -6
  98. package/src/runtime/{freshness.ts → freshness.js} +15 -15
  99. package/src/runtime/{health.ts → health.js} +72 -72
  100. package/src/runtime/{history-compactor.ts → history-compactor.js} +25 -25
  101. package/src/runtime/{implementation-gate.ts → implementation-gate.js} +30 -30
  102. package/src/runtime/inventory/{coverage.ts → coverage.js} +10 -10
  103. package/src/runtime/inventory/{identity.ts → identity.js} +2 -2
  104. package/src/runtime/inventory/{index.ts → index.js} +36 -36
  105. package/src/runtime/inventory/{precedence.ts → precedence.js} +2 -2
  106. package/src/runtime/inventory/{read-scopes.ts → read-scopes.js} +9 -9
  107. package/src/runtime/inventory/{siblings.ts → siblings.js} +15 -15
  108. package/src/runtime/knowledge/{chunker.ts → chunker.js} +12 -12
  109. package/src/runtime/knowledge/{hybrid.ts → hybrid.js} +17 -17
  110. package/src/runtime/knowledge/{index-store.ts → index-store.js} +23 -23
  111. package/src/runtime/knowledge/{retrieval.ts → retrieval.js} +27 -27
  112. package/src/runtime/{leak-scan.ts → leak-scan.js} +12 -12
  113. package/src/runtime/lifecycle/{cli.ts → cli.js} +32 -32
  114. package/src/runtime/lifecycle/{event-store.ts → event-store.js} +48 -48
  115. package/src/runtime/lifecycle/{fold.ts → fold.js} +41 -41
  116. package/src/runtime/lifecycle/{followup.ts → followup.js} +54 -54
  117. package/src/runtime/lifecycle/{goal.ts → goal.js} +50 -50
  118. package/src/runtime/lifecycle/{intent-writer.ts → intent-writer.js} +5 -5
  119. package/src/runtime/lifecycle/{overview.ts → overview.js} +47 -47
  120. package/src/runtime/lifecycle/{release.ts → release.js} +29 -29
  121. package/src/runtime/lifecycle/{report-store.ts → report-store.js} +25 -25
  122. package/src/runtime/lifecycle/{retention.ts → retention.js} +37 -37
  123. package/src/runtime/lifecycle/{root.ts → root.js} +9 -9
  124. package/src/runtime/lifecycle/{status.ts → status.js} +64 -64
  125. package/src/runtime/lifecycle/{store-upkeep.ts → store-upkeep.js} +46 -46
  126. package/src/runtime/{locator-resolve.ts → locator-resolve.js} +7 -7
  127. package/src/runtime/{mask.ts → mask.js} +22 -22
  128. package/src/runtime/{mcp-consultations.ts → mcp-consultations.js} +54 -54
  129. package/src/runtime/{mcp-reach.ts → mcp-reach.js} +24 -24
  130. package/src/runtime/{model-router.ts → model-router.js} +20 -20
  131. package/src/runtime/{outcome.ts → outcome.js} +27 -27
  132. package/src/runtime/{reach.ts → reach.js} +21 -21
  133. package/src/runtime/{readiness-record.ts → readiness-record.js} +12 -12
  134. package/src/runtime/{readiness.ts → readiness.js} +35 -35
  135. package/src/runtime/{recovery.ts → recovery.js} +15 -15
  136. package/src/runtime/{research-request.ts → research-request.js} +34 -34
  137. package/src/runtime/{retrieval-plan.ts → retrieval-plan.js} +40 -40
  138. package/src/runtime/scaffold/{artifacts.ts → artifacts.js} +19 -19
  139. package/src/runtime/scaffold/{fingerprint.ts → fingerprint.js} +3 -3
  140. package/src/runtime/scaffold/{generate.ts → generate.js} +109 -109
  141. package/src/runtime/scaffold/{languages.ts → languages.js} +34 -34
  142. package/src/runtime/storage/{cli.ts → cli.js} +9 -9
  143. package/src/runtime/storage/{engine.ts → engine.js} +37 -37
  144. package/src/runtime/storage/{registry.ts → registry.js} +19 -19
  145. package/src/runtime/storage/{roots.ts → roots.js} +8 -8
  146. package/src/runtime/storage/{rules.ts → rules.js} +26 -26
  147. package/src/runtime/storage/{upkeep.ts → upkeep.js} +35 -35
  148. package/src/runtime/storage/{work-status.ts → work-status.js} +39 -39
  149. package/src/runtime/{task-attempts.ts → task-attempts.js} +61 -61
  150. package/src/runtime/{task-classifier.ts → task-classifier.js} +34 -34
  151. package/src/runtime/{task-scope.ts → task-scope.js} +13 -13
  152. package/src/runtime/{task-state.ts → task-state.js} +15 -15
  153. package/src/runtime/trace/{indicators.ts → indicators.js} +22 -22
  154. package/src/runtime/trace/{ledger.ts → ledger.js} +42 -42
  155. package/src/runtime/trace/{render.ts → render.js} +7 -7
  156. package/src/runtime/trace/{views.ts → views.js} +40 -40
  157. package/src/runtime/verification/{contract-runner.ts → contract-runner.js} +23 -23
  158. package/src/runtime/verification/{engine.ts → engine.js} +143 -143
  159. package/src/runtime/verification/{registry.ts → registry.js} +6 -6
  160. package/src/runtime/verification/{scope-bound.ts → scope-bound.js} +50 -50
  161. package/src/runtime/verification/{test-selection.ts → test-selection.js} +28 -28
  162. package/src/runtime/{workflow-engine.ts → workflow-engine.js} +50 -50
  163. package/src/runtime/{workflow-orchestrator.ts → workflow-orchestrator.js} +91 -91
  164. package/src/runtime/{worktree.ts → worktree.js} +31 -31
  165. package/src/state/{index.ts → index.js} +26 -26
  166. package/src/state/{lockfile.ts → lockfile.js} +20 -20
  167. package/src/state/{run-lock.ts → run-lock.js} +44 -44
@@ -23,52 +23,52 @@ const os = require('node:os');
23
23
  const path = require('node:path');
24
24
  const {
25
25
  handleCapabilitiesCommand, handleReadinessCommand, handleEvidenceCommand,
26
- } = require('../runtime/cli.ts');
27
- // `doctor` comes from the health module rather than src/runtime/cli.ts: the health-probe report
26
+ } = require('../runtime/cli.js');
27
+ // `doctor` comes from the health module rather than src/runtime/cli.js: the health-probe report
28
28
  // (FR-013) supersedes the presence-check version, and one verb must have one implementation.
29
- const { handleDoctorCommand } = require('../runtime/health.ts');
30
- const { handleTraceCommand, handleStatsCommand, handleDiscoverCommand, resolveRunsLocation } = require('../runtime/trace/ledger.ts');
31
- const { handleIndicatorsCommand } = require('../runtime/trace/indicators.ts');
29
+ const { handleDoctorCommand } = require('../runtime/health.js');
30
+ const { handleTraceCommand, handleStatsCommand, handleDiscoverCommand, resolveRunsLocation } = require('../runtime/trace/ledger.js');
31
+ const { handleIndicatorsCommand } = require('../runtime/trace/indicators.js');
32
32
  // The rest of the verb surface design §4.2 declares. `classify`, `workflow`, `route`, `claim`,
33
33
  // `context-pack`, `verify`, `recover` and `scaffold` each have exactly one implementation, in the
34
34
  // engine module named on the right; this file only dispatches to them.
35
- const { ReadinessEngine } = require('../runtime/readiness.ts');
36
- const { handleClaimCommand } = require('../runtime/claims.ts');
37
- const { handleClassifyCommand } = require('../runtime/task-classifier.ts');
38
- const { handleWorkflowCommand } = require('../runtime/workflow-engine.ts');
39
- const { handleOrchestrateCommand } = require('../runtime/workflow-orchestrator.ts');
40
- const { handleResearchRequestCommand } = require('../runtime/research-request.ts');
41
- const { handleTaskAttemptCommand } = require('../runtime/task-attempts.ts');
42
- const { handleRetrieveCommand } = require('../runtime/knowledge/retrieval.ts');
43
- const { handleModelRoleCommand } = require('../runtime/model-router.ts');
44
- const { handleRouteCommand } = require('../runtime/capability-router.ts');
45
- const { handleContextPackCommand } = require('../runtime/context-pack.ts');
46
- const { handleRetrievalPlanCommand } = require('../runtime/retrieval-plan.ts');
47
- const { handleOutcomeCommand } = require('../runtime/outcome.ts');
48
- const { handleVerifyCommand } = require('../runtime/verification/engine.ts');
49
- const { handleLeakScanCommand } = require('../runtime/leak-scan.ts');
50
- const { handleRecoverCommand } = require('../runtime/recovery.ts');
51
- const { handleScaffoldCommand } = require('../runtime/scaffold/generate.ts');
52
- const { handleDecisionCommand } = require('../runtime/decision-register.ts');
53
- const { handleFollowupCommand, handleLifecycleCommand, handleGoalCommand } = require('../runtime/lifecycle/cli.ts');
54
- const { projectRoot: lifecycleProjectRoot } = require('../runtime/lifecycle/root.ts');
55
- const { upkeepAfterVerb } = require('../runtime/storage/upkeep.ts');
56
- const { handleStorageCommand } = require('../runtime/storage/cli.ts');
35
+ const { ReadinessEngine } = require('../runtime/readiness.js');
36
+ const { handleClaimCommand } = require('../runtime/claims.js');
37
+ const { handleClassifyCommand } = require('../runtime/task-classifier.js');
38
+ const { handleWorkflowCommand } = require('../runtime/workflow-engine.js');
39
+ const { handleOrchestrateCommand } = require('../runtime/workflow-orchestrator.js');
40
+ const { handleResearchRequestCommand } = require('../runtime/research-request.js');
41
+ const { handleTaskAttemptCommand } = require('../runtime/task-attempts.js');
42
+ const { handleRetrieveCommand } = require('../runtime/knowledge/retrieval.js');
43
+ const { handleModelRoleCommand } = require('../runtime/model-router.js');
44
+ const { handleRouteCommand } = require('../runtime/capability-router.js');
45
+ const { handleContextPackCommand } = require('../runtime/context-pack.js');
46
+ const { handleRetrievalPlanCommand } = require('../runtime/retrieval-plan.js');
47
+ const { handleOutcomeCommand } = require('../runtime/outcome.js');
48
+ const { handleVerifyCommand } = require('../runtime/verification/engine.js');
49
+ const { handleLeakScanCommand } = require('../runtime/leak-scan.js');
50
+ const { handleRecoverCommand } = require('../runtime/recovery.js');
51
+ const { handleScaffoldCommand } = require('../runtime/scaffold/generate.js');
52
+ const { handleDecisionCommand } = require('../runtime/decision-register.js');
53
+ const { handleFollowupCommand, handleLifecycleCommand, handleGoalCommand } = require('../runtime/lifecycle/cli.js');
54
+ const { projectRoot: lifecycleProjectRoot } = require('../runtime/lifecycle/root.js');
55
+ const { upkeepAfterVerb } = require('../runtime/storage/upkeep.js');
56
+ const { handleStorageCommand } = require('../runtime/storage/cli.js');
57
57
  // Required on first use, so a CLI whose failure modules cannot be loaded still runs every other verb.
58
- function handleFailureCommand(options: any): any { return require('../runtime/failure/cli.ts').handleFailureCommand(options); }
59
- const { handleInventoryCommand } = require('../runtime/inventory/index.ts');
60
- const { finishRuntime, usageError } = require('../runtime/cli-result.ts');
61
- const { setDefaultSlug, invalidSlugRefusal, slugNamesNoFeature } = require('../runtime/task-scope.ts');
62
- const { listCheckouts } = require('../runtime/checkouts.ts');
63
- const { featureSlugFor } = require('../runtime/implementation-gate.ts');
64
- const { handleBriefToolsCommand } = require('../runtime/brief-tools.ts');
65
- const { handleAdviseCommand } = require('../runtime/advice/cli.ts');
66
- const { REPO_ROOT, buildAdapterRegistry } = require('./shared.ts');
58
+ function handleFailureCommand(options ) { return require('../runtime/failure/cli.js').handleFailureCommand(options); }
59
+ const { handleInventoryCommand } = require('../runtime/inventory/index.js');
60
+ const { finishRuntime, usageError } = require('../runtime/cli-result.js');
61
+ const { setDefaultSlug, invalidSlugRefusal, slugNamesNoFeature } = require('../runtime/task-scope.js');
62
+ const { listCheckouts } = require('../runtime/checkouts.js');
63
+ const { featureSlugFor } = require('../runtime/implementation-gate.js');
64
+ const { handleBriefToolsCommand } = require('../runtime/brief-tools.js');
65
+ const { handleAdviseCommand } = require('../runtime/advice/cli.js');
66
+ const { REPO_ROOT, buildAdapterRegistry } = require('./shared.js');
67
67
 
68
68
  /** Where `readiness`/`evidence` read and write per-task state. Mirrors scopeOf()'s rules so these
69
69
  * commands are scope-aware like the rest of the CLI, rather than defaulting to the DoFlow install
70
70
  * directory — which for an npm install is inside node_modules/. */
71
- function evidenceRoot(o: any): string {
71
+ function evidenceRoot(o ) {
72
72
  return o.global ? os.homedir() : path.resolve(o.positional[0] || '.');
73
73
  }
74
74
 
@@ -81,7 +81,7 @@ function evidenceRoot(o: any): string {
81
81
  * The valid set comes from the readiness registry rather than a list written here, so it cannot
82
82
  * drift from the templates that actually exist.
83
83
  */
84
- function requireTaskClass(o: any): string {
84
+ function requireTaskClass(o ) {
85
85
  if (typeof o.taskClass === 'string' && o.taskClass.trim() !== '') return o.taskClass;
86
86
  let valid = '';
87
87
  try {
@@ -92,7 +92,7 @@ function requireTaskClass(o: any): string {
92
92
  }
93
93
 
94
94
  /** The task id the caller named, or exit 2. Same reasoning as requireTaskClass. */
95
- function requireTaskId(o: any): string {
95
+ function requireTaskId(o ) {
96
96
  if (typeof o.taskId === 'string' && o.taskId.trim() !== '') return o.taskId;
97
97
  usageError(o.cmd, '--task-id is required — evidence and claims belong to one task, so guessing an id would report on a different one.', o.json);
98
98
  process.exit(2);
@@ -104,8 +104,8 @@ function requireTaskId(o: any): string {
104
104
  * Absent flags stay absent. Filling a gap here with 'unknown'/'general' would move the omission out
105
105
  * of the caller's error message and into the stored record, where it reads as a measurement.
106
106
  */
107
- function evidenceItemFromFlags(o: any): any {
108
- const item: any = {};
107
+ function evidenceItemFromFlags(o ) {
108
+ const item = {};
109
109
  if (o.kind !== undefined) item.kind = o.kind;
110
110
  if (o.provenance !== undefined) item.provenance = o.provenance;
111
111
  if (o.locator !== undefined) item.locator = o.locator;
@@ -118,7 +118,7 @@ function evidenceItemFromFlags(o: any): any {
118
118
  if (o.observedCommand !== undefined) item.observation.command = o.observedCommand;
119
119
  if (o.observedExit !== undefined) item.observation.exitCode = o.observedExit;
120
120
  }
121
- const source: any = {};
121
+ const source = {};
122
122
  if (o.provider !== undefined) source.provider = o.provider;
123
123
  if (o.capability !== undefined) source.capability = o.capability;
124
124
  if (Object.keys(source).length > 0) item.source = source;
@@ -139,12 +139,12 @@ const FEATURE_STORE_VERBS = new Set(['evidence', 'claim', 'readiness']);
139
139
  * the readiness record written there is the one verify, orchestrate and the edit hook read from
140
140
  * the worktree.
141
141
  */
142
- function featureStoreRoot(o: any): { root: string; slug: string } | null {
142
+ function featureStoreRoot(o ) {
143
143
  if (!FEATURE_STORE_VERBS.has(o.cmd) || o.global) return null;
144
144
  const checkouts = listCheckouts({ cwd: evidenceRoot(o) });
145
145
  if (!checkouts.isLinked) return null;
146
146
  const slug = featureSlugFor({ projectRoot: checkouts.current, slug: o.slug });
147
- const folder = (root: string) => path.join(root, 'agent-docs', 'doflow', slug || '');
147
+ const folder = (root ) => path.join(root, 'agent-docs', 'doflow', slug || '');
148
148
  if (!slug || fs.existsSync(folder(checkouts.current)) || !fs.existsSync(folder(checkouts.main))) return null;
149
149
  return { root: checkouts.main, slug };
150
150
  }
@@ -155,7 +155,7 @@ function featureStoreRoot(o: any): { root: string; slug: string } | null {
155
155
  * validate parsed CLI arguments, which is the CLI's job, not a library's); everything else belongs
156
156
  * to the engine module each case names.
157
157
  */
158
- function dispatchRuntimeCommandInner(o: any, moment: any): any {
158
+ function dispatchRuntimeCommandInner(o , moment ) {
159
159
  // A slug becomes a directory name and a state key, so one that could name a path is refused
160
160
  // here, once, for every verb that reads `--slug`, before any of them reads or writes state
161
161
  // (FR-013, IC-009). A well-formed slug that names no feature is the verbs' own business.
@@ -253,7 +253,7 @@ function dispatchRuntimeCommandInner(o: any, moment: any): any {
253
253
  case 'research-request': return handleResearchRequestCommand({ slug: o.slug, action: o.action === 'status' ? 'list' : o.action, taskId: requireTaskId(o), stageId: o.stageId, question: o.question, reason: o.reason, blocking: o.blocking === undefined ? undefined : o.blocking === 'true' ? true : o.blocking === 'false' ? false : o.blocking, requestId: o.requestId, outcome: o.researchOutcome, claimId: o.claimId, evidenceIds: o.evidenceIds, gap: o.gap, json: o.json, projectRoot: evidenceRoot(o) });
254
254
  // The store is shared by every linked worktree of the clone (lifecycle's main-worktree root); the
255
255
  // feature is `--slug`, else the branch's, resolved the way decision and scaffold resolve it.
256
- case 'task-attempt': return handleTaskAttemptCommand({ action: o.actionGiven ? o.action : undefined, slug: o.slug, task: o.task, owner: o.owner, mode: o.mode, token: o.token, result: o.result, evidenceId: o.evidenceId, reason: o.reason, json: o.json, cwd: evidenceRoot(o), resolveSlug: (cwd: string) => featureSlugFor({ projectRoot: cwd }) });
256
+ case 'task-attempt': return handleTaskAttemptCommand({ action: o.actionGiven ? o.action : undefined, slug: o.slug, task: o.task, owner: o.owner, mode: o.mode, token: o.token, result: o.result, evidenceId: o.evidenceId, reason: o.reason, json: o.json, cwd: evidenceRoot(o), resolveSlug: (cwd ) => featureSlugFor({ projectRoot: cwd }) });
257
257
  case 'retrieve': return handleRetrieveCommand({ query: o.query, top: o.top, json: o.json });
258
258
  case 'brief-tools': return handleBriefToolsCommand({ owner: o.owner, tier: o.tier, harness: o.harness, slug: o.slug, headingLevel: o.headingLevel, tasks: o.tasks, json: o.json, repoRoot: REPO_ROOT, projectRoot: storeRoot, buildAdapters: buildAdapterRegistry });
259
259
  case 'advise': return handleAdviseCommand({ action: o.action, actionGiven: o.actionGiven, kind: o.kind, server: o.server, state: o.state, stateFile: o.stateFile, staticAnswer: o.staticAnswer, questionsFile: o.questionsFile, taskId: o.taskId, pickId: o.pickId, actual: o.actual, model: o.model, endpoint: o.endpoint, off: o.off, project: o.project, force: o.force, global: o.global, json: o.json, projectRoot: evidenceRoot(o) });
@@ -271,8 +271,8 @@ function dispatchRuntimeCommandInner(o: any, moment: any): any {
271
271
  }
272
272
 
273
273
  /** Await the verb without changing its return value, output or exit code; usage exits never return. */
274
- async function dispatchRuntimeCommand(o: any): Promise<any> {
275
- const moment: any = {};
274
+ async function dispatchRuntimeCommand(o ) {
275
+ const moment = {};
276
276
  const result = await dispatchRuntimeCommandInner(o, moment);
277
277
  if (o.cmd !== 'storage') upkeepAfterVerb({ projectRoot: moment.projectRoot });
278
278
  return result;
@@ -9,23 +9,23 @@
9
9
  const fs = require('node:fs');
10
10
  const os = require('node:os');
11
11
  const path = require('node:path');
12
- const { REPO_ROOT } = require('../helper/repo-root.ts');
13
- const { doflowPaths } = require('../install/paths.ts');
14
- const { readInstallManifest } = require('../install/manifest.ts');
15
- const { DEFAULT_BACKUP_RETENTION, formatBytes } = require('../install/backup.ts');
16
- const { stateRoot, readLedger } = require('../state/index.ts');
17
- const { readLock } = require('../state/lockfile.ts');
18
- const { acquireRunLock, RunLockTimeoutError, RunLockError, RunLockLostError } = require('../state/run-lock.ts');
19
- const { createAdapterRegistry } = require('../adapters/index.ts');
20
- const { declaredHarnessPaths } = require('../helper/harness-paths.ts');
21
- const claudeAdapter = require('../adapters/claude/index.ts');
22
- const codexAdapter = require('../adapters/codex/index.ts');
23
- const { createGeminiAdapter } = require('../adapters/gemini/index.ts');
24
- const { createOpenCodeAdapter } = require('../adapters/opencode/index.ts');
25
- const { createPiAdapter } = require('../adapters/pi/index.ts');
26
- const { createCopilotAdapter } = require('../adapters/copilot/index.ts');
27
- const { createKiroAdapter } = require('../adapters/kiro/index.ts');
28
- const { createAntigravityAdapter } = require('../adapters/antigravity/index.ts');
12
+ const { REPO_ROOT } = require('../helper/repo-root.js');
13
+ const { doflowPaths } = require('../install/paths.js');
14
+ const { readInstallManifest } = require('../install/manifest.js');
15
+ const { DEFAULT_BACKUP_RETENTION, formatBytes } = require('../install/backup.js');
16
+ const { stateRoot, readLedger } = require('../state/index.js');
17
+ const { readLock } = require('../state/lockfile.js');
18
+ const { acquireRunLock, RunLockTimeoutError, RunLockError, RunLockLostError } = require('../state/run-lock.js');
19
+ const { createAdapterRegistry } = require('../adapters/index.js');
20
+ const { declaredHarnessPaths } = require('../helper/harness-paths.js');
21
+ const claudeAdapter = require('../adapters/claude/index.js');
22
+ const codexAdapter = require('../adapters/codex/index.js');
23
+ const { createGeminiAdapter } = require('../adapters/gemini/index.js');
24
+ const { createOpenCodeAdapter } = require('../adapters/opencode/index.js');
25
+ const { createPiAdapter } = require('../adapters/pi/index.js');
26
+ const { createCopilotAdapter } = require('../adapters/copilot/index.js');
27
+ const { createKiroAdapter } = require('../adapters/kiro/index.js');
28
+ const { createAntigravityAdapter } = require('../adapters/antigravity/index.js');
29
29
 
30
30
  // The directory of the `doflow` entrypoint. Derived from the shared package root rather than
31
31
  // __dirname so its value survives this code physically moving between directories: manifests,
@@ -36,7 +36,7 @@ const SCRIPT_DIR = path.join(REPO_ROOT, 'bin');
36
36
  // core/registry/ but no package.json — see the `runtime.*` assets in core/registry/assets.json.
37
37
  // A hard require here would make every Node-backed verb fail in an install, which is the exact
38
38
  // defect that projection exists to fix. Only version reporting depends on this.
39
- function loadPkg(): any {
39
+ function loadPkg() {
40
40
  try { return require('../../package.json'); } catch { return { version: '0.0.0-installed', name: '@khoavu882/doflow' }; }
41
41
  }
42
42
  const pkg = loadPkg();
@@ -44,13 +44,13 @@ const pkg = loadPkg();
44
44
  /**
45
45
  * The one adapter registry construction, used by install/update/remove/reconcile. There used to
46
46
  * be three inline copies of the same construction (one per mutating command); a fourth variant
47
- * once grew in src/lifecycle/view.ts and silently fell behind (fixed in 96006da) — which is why
47
+ * once grew in src/lifecycle/view.js and silently fell behind (fixed in 96006da) — which is why
48
48
  * the registry guard pins every declared harness into each call site by parsing them.
49
49
  * Build one here rather than copying the object literal again. Stage 3: each adapter factory
50
50
  * receives its harness's declared native paths from core/registry/harnesses.json, so the CLI
51
51
  * consumes exactly what the loader validates.
52
52
  */
53
- function buildAdapterRegistry(): any {
53
+ function buildAdapterRegistry() {
54
54
  const declared = declaredHarnessPaths();
55
55
  return createAdapterRegistry({
56
56
  claude: claudeAdapter.createClaudeAdapter({ declaredPaths: declared.claude }),
@@ -65,11 +65,11 @@ function buildAdapterRegistry(): any {
65
65
  }
66
66
 
67
67
  /** Resolve {global, projectRoot} scope options for src/install/targets.js#toolDirs from parsed args. */
68
- function scopeOf(o: any): { global: boolean; projectRoot: string } {
68
+ function scopeOf(o ) {
69
69
  return { global: o.global, projectRoot: o.positional[0] || '.' };
70
70
  }
71
71
 
72
- function installPaths(scope: any): any {
72
+ function installPaths(scope ) {
73
73
  const scopeRoot = scope.global ? os.homedir() : path.resolve(scope.projectRoot);
74
74
  return doflowPaths({ scopeRoot });
75
75
  }
@@ -77,7 +77,7 @@ function installPaths(scope: any): any {
77
77
  /** Whether two paths name the same directory. Device and inode follow symlinks (macOS reaches
78
78
  * /var through /private/var) and ignore letter case on a case-insensitive volume; a file system
79
79
  * that reports inode 0 falls back to real paths, and paths that do not exist to resolved strings. */
80
- function sameDirectory(a: string, b: string, { fsImpl = fs }: any = {}): boolean {
80
+ function sameDirectory(a , b , { fsImpl = fs } = {}) {
81
81
  const ra = path.resolve(a);
82
82
  const rb = path.resolve(b);
83
83
  try {
@@ -95,7 +95,7 @@ function sameDirectory(a: string, b: string, { fsImpl = fs }: any = {}): boolean
95
95
  /** A project install, update, remove or reconcile rooted at the home directory would share the
96
96
  * global install's files and records, and its remove could delete them. Refuses that run with one
97
97
  * line and exit 1 before anything is read, locked or written; `-g` and every other root pass. */
98
- function refuseHomeRootedProject(o: any, command: string): void {
98
+ function refuseHomeRootedProject(o , command ) {
99
99
  if (o.global) return;
100
100
  const projectRoot = o.positional[0] || '.';
101
101
  if (!sameDirectory(projectRoot, os.homedir())) return;
@@ -106,40 +106,40 @@ function refuseHomeRootedProject(o: any, command: string): void {
106
106
 
107
107
  /** Takes the scope's run lock for a mutating command, or returns null under --dry-run. A run that
108
108
  * cannot take it prints the one reason line and exits 1 before it has read or changed anything. */
109
- function holdRunLock(o: any, scope: any, command: string): any {
109
+ function holdRunLock(o , scope , command ) {
110
110
  if (o.dryRun) return null;
111
111
  try {
112
112
  return acquireRunLock({ scopeRoot: installPaths(scope).scopeRoot, scope: scope.global ? 'global' : 'project', command });
113
113
  } catch (err) {
114
114
  if (!(err instanceof RunLockTimeoutError || err instanceof RunLockError)) throw err;
115
- console.error((err as any).message);
115
+ console.error((err ).message);
116
116
  process.exit(1);
117
117
  }
118
118
  }
119
119
 
120
120
  /** After the confirm prompt: renews the hold, and exits 1 before the first write if another run
121
121
  * took the lock over while the prompt waited. */
122
- function checkpointRunLock(hold: any): void {
122
+ function checkpointRunLock(hold ) {
123
123
  if (!hold) return;
124
124
  try {
125
125
  hold.checkpoint();
126
126
  } catch (err) {
127
127
  if (!(err instanceof RunLockLostError)) throw err;
128
- console.error((err as any).message);
128
+ console.error((err ).message);
129
129
  process.exit(1);
130
130
  }
131
131
  }
132
132
 
133
133
  /** Surface a reconciled-away MCP server rather than dropping it silently: the user picked it once,
134
134
  * so its disappearance from their config should be explained, not discovered. */
135
- function reportRetiredMcp(retired: string[]): void {
135
+ function reportRetiredMcp(retired ) {
136
136
  console.error(`[WARN] Dropping MCP server(s) no longer in the registry: ${retired.join(', ')}`);
137
137
  console.error(' They were removed from DoFlow; your saved selection is being reconciled.');
138
138
  }
139
139
 
140
140
  /** The scope's doflow.lock, ledger and 1.18.0 manifest MCP list, as the MCP selection functions in
141
141
  * src/install/mcp.js read them. */
142
- function scopeSelectionState(scope: any): any {
142
+ function scopeSelectionState(scope ) {
143
143
  const scopeRoot = scope.global ? os.homedir() : path.resolve(scope.projectRoot);
144
144
  return {
145
145
  lock: readLock(scope.global ? { scope: 'global', homeDir: scopeRoot } : { scope: 'project', projectRoot: scopeRoot }),
@@ -148,13 +148,13 @@ function scopeSelectionState(scope: any): any {
148
148
  };
149
149
  }
150
150
 
151
- const MCP_SOURCE_WORDS = Object.freeze({ flag: '--mcp', prompt: 'prompt', recorded: 'recorded', kept: 'kept', manifest: 'remembered', default: 'default' } as Record<string, string>);
151
+ const MCP_SOURCE_WORDS = Object.freeze({ flag: '--mcp', prompt: 'prompt', recorded: 'recorded', kept: 'kept', manifest: 'remembered', default: 'default' } );
152
152
 
153
153
  /** The one line a run names its MCP selections in, from what the plan resolved for each harness:
154
154
  * harnesses with the same servers and source share a group, groups follow target order. Prints
155
155
  * nothing when no target takes MCP servers, except that an explicit --mcp is said to do nothing. */
156
- function printMcpSelection(view: any, sources: any, { requested, prefix = '[INFO]' }: any = {}): void {
157
- const groups: any[] = [];
156
+ function printMcpSelection(view , sources , { requested, prefix = '[INFO]' } = {}) {
157
+ const groups = [];
158
158
  for (const target of view.plan.targets) {
159
159
  if (target.skipped || !Array.isArray(target.mcpSelected) || !(target.harness in sources)) continue;
160
160
  const ids = target.mcpSelected.join(', ') || 'none';
@@ -172,26 +172,26 @@ function printMcpSelection(view: any, sources: any, { requested, prefix = '[INFO
172
172
 
173
173
  /** Says which MCP entries a run with no native change recorded as DoFlow's (lifecycle
174
174
  * recordMcpOwnership), or, under --dry-run, would record. */
175
- function printRecordedMcpOwnership(recorded: any, { dryRun = false }: any = {}): void {
176
- for (const [harness, ids] of Object.entries<any>(recorded)) {
175
+ function printRecordedMcpOwnership(recorded , { dryRun = false } = {}) {
176
+ for (const [harness, ids] of Object.entries (recorded)) {
177
177
  const what = `${ids.length} MCP ${ids.length === 1 ? 'entry' : 'entries'} (${ids.join(', ')})`;
178
178
  console.log(dryRun ? `[DRY] ${harness}: would record DoFlow's ownership of ${what}` : `[INFO] ${harness}: recorded DoFlow's ownership of ${what}`);
179
179
  }
180
180
  }
181
181
 
182
182
  /** What each planned harness that takes MCP servers will hold, as doflow.lock records it. */
183
- function plannedMcpSelections(view: any): any {
184
- return Object.fromEntries(view.plan.targets.filter((target: any) => !target.skipped && Array.isArray(target.mcpSelected))
185
- .map((target: any) => [target.harness, target.mcpSelected]));
183
+ function plannedMcpSelections(view ) {
184
+ return Object.fromEntries(view.plan.targets.filter((target ) => !target.skipped && Array.isArray(target.mcpSelected))
185
+ .map((target ) => [target.harness, target.mcpSelected]));
186
186
  }
187
187
 
188
188
  /** Total size of some rows, noting when any of them could not be measured. */
189
- function rowsSize(rows: any[]): string {
189
+ function rowsSize(rows ) {
190
190
  const total = formatBytes(rows.reduce((sum, r) => sum + (r.bytes ?? 0), 0));
191
191
  return rows.some((r) => r.bytes === null) ? `${total} (some sizes unknown)` : total;
192
192
  }
193
193
 
194
- function printBackupTable(rows: any[], rootLabel: string): void {
194
+ function printBackupTable(rows , rootLabel ) {
195
195
  if (rows.length === 0) { console.log(`[INFO] No backups found in ${rootLabel}`); return; }
196
196
  const header = `${'BACKUP ID'.padEnd(42)} ${'OPERATION'.padEnd(14)} ${'TYPE'.padEnd(9)} ${'ORIGIN'.padEnd(9)} ${'SIZE'.padEnd(11)} TIMESTAMP`;
197
197
  console.log(`\n${header}`);
@@ -2,12 +2,12 @@
2
2
 
3
3
  // TypeScript migration (agent-docs/BRIEF_GOAL_DOFLOW.md): authored as `.ts`, run directly by Node
4
4
  // native type-stripping — no build step, no runtime dependency. Body stays CommonJS so a `.js`
5
- // caller's `require('../helper/bash-helper.ts')` keeps working while the rest of the tree is still
5
+ // caller's `require('../helper/bash-helper.js')` keeps working while the rest of the tree is still
6
6
  // `.js`. The `./repo-root` require stays bare while repo-root is still `.js`; it gains `.ts` in the
7
7
  // same slice that converts repo-root.
8
8
  const fs = require('node:fs');
9
9
  const path = require('node:path');
10
- const { REPO_ROOT } = require('./repo-root.ts');
10
+ const { REPO_ROOT } = require('./repo-root.js');
11
11
 
12
12
  /**
13
13
  * Where a bash helper (`do-paths.sh`, `do-git-state.sh`) is: inside the package (a checkout or a
@@ -20,15 +20,15 @@ const { REPO_ROOT } = require('./repo-root.ts');
20
20
  * @param repoRoot the runtime root; only a test moves it
21
21
  */
22
22
  function resolveBashHelper(
23
- name: string,
24
- repoRoot: string = REPO_ROOT,
25
- existsImpl: (file: string) => boolean = fs.existsSync,
26
- ): string | null {
23
+ name ,
24
+ repoRoot = REPO_ROOT,
25
+ existsImpl = fs.existsSync,
26
+ ) {
27
27
  const candidates = [
28
28
  path.join(repoRoot, 'core', 'shared', 'scripts', 'doflow', 'bash', name),
29
29
  path.resolve(repoRoot, '..', 'scripts', 'doflow', 'bash', name),
30
30
  ];
31
- return candidates.find((candidate: string) => existsImpl(candidate)) || null;
31
+ return candidates.find((candidate ) => existsImpl(candidate)) || null;
32
32
  }
33
33
 
34
34
  module.exports = { resolveBashHelper };
@@ -6,13 +6,13 @@
6
6
  // First module of the TypeScript migration (agent-docs/BRIEF_GOAL_DOFLOW.md). Authored as `.ts` and
7
7
  // run directly by Node's native type-stripping (process.features.typescript === 'strip', Node
8
8
  // ^22.18.0 || >=24.3.0), so no build step and no runtime dependency are added. The body stays CommonJS
9
- // (`module.exports`) so a `require('../helper/git.ts')` from a `.js` caller keeps working while the
9
+ // (`module.exports`) so a `require('../helper/git.js')` from a `.js` caller keeps working while the
10
10
  // rest of the tree is still `.js`; the explicit `.ts` extension on those requires is what the
11
11
  // CommonJS resolver needs to find this file.
12
12
  const { execFileSync } = require('node:child_process');
13
13
 
14
14
  /** Short HEAD commit of the repo at `repoRoot`, or 'unknown' if not a git repo / git unavailable. */
15
- function sourceCommit(repoRoot: string): string {
15
+ function sourceCommit(repoRoot ) {
16
16
  try {
17
17
  return execFileSync('git', ['-C', repoRoot, 'rev-parse', '--short', 'HEAD'], { stdio: ['ignore', 'pipe', 'ignore'] })
18
18
  .toString().trim() || 'unknown';
@@ -11,7 +11,7 @@
11
11
  //
12
12
  // TypeScript migration (agent-docs/BRIEF_GOAL_DOFLOW.md): authored as `.ts`, run directly by Node
13
13
  // native type-stripping (process.features.typescript === 'strip', Node ^22.18.0 || >=24.3.0) — no build step and
14
- // no runtime dependency. The body stays CommonJS so a `.js` caller's `require('../helper/guardrails.ts')`
14
+ // no runtime dependency. The body stays CommonJS so a `.js` caller's `require('../helper/guardrails.js')`
15
15
  // keeps working while the rest of the tree is still `.js`; the explicit `.ts` extension is what the
16
16
  // CommonJS resolver needs to find this file.
17
17
 
@@ -20,26 +20,26 @@ const path = require('node:path');
20
20
 
21
21
  const DENY_RULE = /^Bash\((.*):\*\)$/;
22
22
 
23
- interface FsReadFileSync {
24
- readFileSync(file: string, encoding: 'utf8'): string;
25
- }
23
+
24
+
25
+
26
26
 
27
- interface DestructiveCommandGlobsOptions {
28
- repoRoot: string;
29
- fsImpl?: FsReadFileSync;
30
- }
27
+
28
+
29
+
30
+
31
31
 
32
32
  /** Read the canonical blocklist as bare command globs, e.g. `git push --force*`. Throws when the
33
33
  * authored file is missing or malformed — a silent empty blocklist would look like success while
34
34
  * projecting no protection at all. */
35
- function destructiveCommandGlobs({ repoRoot, fsImpl = fs }: DestructiveCommandGlobsOptions = {} as DestructiveCommandGlobsOptions): string[] {
35
+ function destructiveCommandGlobs({ repoRoot, fsImpl = fs } = {} ) {
36
36
  const file = path.join(repoRoot, 'core', 'harnesses', 'claude', 'settings', 'settings.json');
37
37
  const parsed = JSON.parse(fsImpl.readFileSync(file, 'utf8'));
38
38
  const deny = parsed?.permissions?.deny;
39
39
  if (!Array.isArray(deny) || deny.length === 0) {
40
40
  throw new Error(`guardrails: no permissions.deny list in ${file}`);
41
41
  }
42
- return deny.map((rule: string) => {
42
+ return deny.map((rule ) => {
43
43
  const m = DENY_RULE.exec(rule);
44
44
  if (!m) throw new Error(`guardrails: unrecognized deny rule '${rule}' in ${file}`);
45
45
  return m[1];
@@ -28,33 +28,33 @@
28
28
  //
29
29
  // TypeScript migration (agent-docs/BRIEF_GOAL_DOFLOW.md): authored as `.ts`, run directly by Node
30
30
  // native type-stripping — no build step, no runtime dependency. Body stays CommonJS so a `.js`
31
- // caller's `require('../helper/harness-paths.ts')` keeps working while the tree is still `.js`. The
31
+ // caller's `require('../helper/harness-paths.js')` keeps working while the tree is still `.js`. The
32
32
  // `./repo-root` require stays bare while repo-root is still `.js`.
33
33
 
34
34
  const fs = require('node:fs');
35
35
  const path = require('node:path');
36
- const { REPO_ROOT } = require('./repo-root.ts');
36
+ const { REPO_ROOT } = require('./repo-root.js');
37
37
 
38
38
  const PATH_BASES = new Set(['root', 'home']);
39
39
  const SURFACE_NAME = /^[a-z][a-zA-Z0-9]*$/;
40
40
  const SEGMENT = /^(?!\.\.$)[^\\/]+$/;
41
41
  const SCOPES = ['project', 'user'];
42
42
 
43
- interface PathRule {
44
- base?: string;
45
- segments?: string[];
46
- }
43
+
44
+
45
+
46
+
47
47
 
48
- interface ResolveInputs {
49
- scope?: string;
50
- scopeRoot?: string;
51
- homeDir?: string;
52
- }
48
+
49
+
50
+
51
+
52
+
53
53
 
54
- function issue(errors: string[], location: string, message: string): void { errors.push(`${location}: ${message}`); }
54
+ function issue(errors , location , message ) { errors.push(`${location}: ${message}`); }
55
55
 
56
56
  /** Validate one {base, segments} rule. Returns errors via the pushed array. */
57
- function validateRule(rule: any, location: string, errors: string[]): void {
57
+ function validateRule(rule , location , errors ) {
58
58
  if (!rule || typeof rule !== 'object' || Array.isArray(rule)) {
59
59
  issue(errors, location, 'must be an object'); return;
60
60
  }
@@ -63,7 +63,7 @@ function validateRule(rule: any, location: string, errors: string[]): void {
63
63
  }
64
64
  if (!PATH_BASES.has(rule.base)) issue(errors, location, `base must be one of ${[...PATH_BASES].join(', ')}`);
65
65
  const segments = rule.segments;
66
- if (!Array.isArray(segments) || segments.some((segment: any) => typeof segment !== 'string' || !SEGMENT.test(segment))) {
66
+ if (!Array.isArray(segments) || segments.some((segment ) => typeof segment !== 'string' || !SEGMENT.test(segment))) {
67
67
  issue(errors, location, "segments must be an array of plain single path segments (no '/', no '\\', no '..')");
68
68
  }
69
69
  }
@@ -71,12 +71,12 @@ function validateRule(rule: any, location: string, errors: string[]): void {
71
71
  /** Validate one harness's whole paths section. Unknown keys and malformed rules are rejected
72
72
  * loudly: a typo'd declaration must fail the registry load, not silently fall back to whatever
73
73
  * the adapter used to hardcode. Returns an array of error messages (empty when valid). */
74
- function validatePathsSection(section: any, location: string): string[] {
75
- const errors: string[] = [];
74
+ function validatePathsSection(section , location ) {
75
+ const errors = [];
76
76
  if (!section || typeof section !== 'object' || Array.isArray(section)) {
77
77
  return [`${location}: must be an object`];
78
78
  }
79
- for (const [name, value] of Object.entries<any>(section)) {
79
+ for (const [name, value] of Object.entries (section)) {
80
80
  const at = `${location}.${name}`;
81
81
  if (!SURFACE_NAME.test(name)) { issue(errors, at, `surface name '${name}' must be camelCase`); continue; }
82
82
  if (!value || typeof value !== 'object' || Array.isArray(value)) { issue(errors, at, 'must be an object'); continue; }
@@ -98,7 +98,7 @@ function validatePathsSection(section: any, location: string): string[] {
98
98
  }
99
99
 
100
100
  /** Resolve one rule to an absolute path. */
101
- function resolveRule(rule: PathRule, { root, home }: { root: string; home: string }): string {
101
+ function resolveRule(rule , { root, home } ) {
102
102
  const base = rule.base === 'home' ? home : root;
103
103
  return path.join(base, ...(rule.segments || []));
104
104
  }
@@ -109,12 +109,12 @@ function resolveRule(rule: PathRule, { root, home }: { root: string; home: strin
109
109
  * Returns { <surface>: absolutePath | null } — null when the scope has no rule for a surface —
110
110
  * plus `root`, the scope's install root itself (an input, not a declaration).
111
111
  */
112
- function resolveHarnessPaths(section: any, { scope, scopeRoot, homeDir }: ResolveInputs = {}): Record<string, string | null> {
112
+ function resolveHarnessPaths(section , { scope, scopeRoot, homeDir } = {}) {
113
113
  const userScope = scope === 'user' || scope === 'global';
114
114
  const home = path.resolve(homeDir || scopeRoot);
115
115
  const root = userScope ? home : path.resolve(scopeRoot);
116
- const resolved: Record<string, string | null> = { root };
117
- for (const [name, value] of Object.entries<any>(section || {})) {
116
+ const resolved = { root };
117
+ for (const [name, value] of Object.entries (section || {})) {
118
118
  const rule = (value.base !== undefined || value.segments !== undefined)
119
119
  ? value
120
120
  : (value[userScope ? 'user' : 'project'] ?? null);
@@ -123,16 +123,16 @@ function resolveHarnessPaths(section: any, { scope, scopeRoot, homeDir }: Resolv
123
123
  return resolved;
124
124
  }
125
125
 
126
- let declaredCache: { repoRoot: string; paths: Record<string, any> } | undefined;
126
+ let declaredCache ;
127
127
  /** Every harness's declared paths section, keyed by harness id, read straight from
128
128
  * core/registry/harnesses.json (memoized per process — the file ships inside the package).
129
129
  * Adapters default their factories to this, so a factory called with no arguments and the CLI
130
130
  * wiring in src/cli/shared.js#buildAdapterRegistry consume byte-identical declarations. */
131
- function declaredHarnessPaths(repoRoot: string = REPO_ROOT): Record<string, any> {
131
+ function declaredHarnessPaths(repoRoot = REPO_ROOT) {
132
132
  if (declaredCache && declaredCache.repoRoot === path.resolve(repoRoot)) return declaredCache.paths;
133
133
  const file = path.join(path.resolve(repoRoot), 'core', 'registry', 'harnesses.json');
134
134
  const parsed = JSON.parse(fs.readFileSync(file, 'utf8'));
135
- const paths = Object.fromEntries((parsed.harnesses || []).map((harness: any) => [harness.id, harness.paths ?? {}]));
135
+ const paths = Object.fromEntries((parsed.harnesses || []).map((harness ) => [harness.id, harness.paths ?? {}]));
136
136
  declaredCache = { repoRoot: path.resolve(repoRoot), paths };
137
137
  return paths;
138
138
  }
@@ -5,7 +5,7 @@
5
5
  //
6
6
  // TypeScript migration (agent-docs/BRIEF_GOAL_DOFLOW.md): authored as `.ts`, run directly by Node
7
7
  // native type-stripping — no build step, no runtime dependency. Body stays CommonJS so a `.js`
8
- // caller's `require('../helper/marker-merge.ts')` keeps working while the tree is still `.js`.
8
+ // caller's `require('../helper/marker-merge.js')` keeps working while the tree is still `.js`.
9
9
  const fs = require('node:fs');
10
10
  const path = require('node:path');
11
11
 
@@ -17,14 +17,14 @@ const MARKER_END = '<!-- doflow:end -->';
17
17
  * Merge `srcAbs`'s content into `dstAbs` inside a doflow-owned marker span,
18
18
  * preserving any of `dstAbs`'s own content outside that span byte-for-byte.
19
19
  */
20
- function mergeMarkedSection(srcAbs: string, dstAbs: string, { dryRun = false }: { dryRun?: boolean } = {}): { changed: boolean } {
20
+ function mergeMarkedSection(srcAbs , dstAbs , { dryRun = false } = {}) {
21
21
  const srcContent = fs.readFileSync(srcAbs, 'utf8').replace(/\s+$/, '');
22
22
  const section = `${MARKER_START}\n${srcContent}\n${MARKER_END}\n`;
23
23
 
24
24
  // Read once, reused both for parsing and for the final no-op comparison below.
25
25
  const existing = fs.existsSync(dstAbs) ? fs.readFileSync(dstAbs, 'utf8') : null;
26
26
 
27
- let newContent: string;
27
+ let newContent ;
28
28
  if (existing === null) {
29
29
  newContent = section;
30
30
  } else {
@@ -90,7 +90,7 @@ function mergeMarkedSection(srcAbs: string, dstAbs: string, { dryRun = false }:
90
90
  * @returns whether a managed span was found and stripped (false if the file doesn't
91
91
  * exist or has no doflow markers — both are no-ops, not errors)
92
92
  */
93
- function removeMarkedSection(file: string): boolean {
93
+ function removeMarkedSection(file ) {
94
94
  if (!fs.existsSync(file)) return false;
95
95
  const existing = fs.readFileSync(file, 'utf8');
96
96
  const start = existing.indexOf(MARKER_START);