@khoavu882/doflow 2.0.0-beta.3 → 2.0.0-beta.5

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 (236) hide show
  1. package/bin/doflow.js +2 -2
  2. package/core/.antigravity-plugin/plugin.json +0 -1
  3. package/core/.claude-plugin/plugin.json +1 -1
  4. package/core/.codex-plugin/plugin.json +1 -1
  5. package/core/.plugin/plugin.json +1 -1
  6. package/core/harnesses/claude/hooks/mcp-tool-guard.sh +7 -17
  7. package/core/harnesses/claude/hooks/pre-bash-guard.sh +7 -17
  8. package/core/harnesses/claude/hooks/pre-implement-gate.sh +7 -18
  9. package/core/harnesses/claude/hooks/session-start.sh +5 -3
  10. package/core/harnesses/claude/hooks/stop-check.sh +5 -3
  11. package/core/harnesses/claude/hooks/subagent-audit.sh +5 -5
  12. package/core/harnesses/claude/hooks/user-prompt-submit.sh +5 -3
  13. package/core/harnesses/codex/hooks/mcp-tool-guard.sh +7 -15
  14. package/core/harnesses/codex/hooks/pre-bash-guard.sh +7 -15
  15. package/core/harnesses/codex/hooks/pre-implement-gate.sh +7 -16
  16. package/core/harnesses/codex/hooks/session-start.sh +5 -3
  17. package/core/harnesses/codex/hooks/stop-check.sh +6 -5
  18. package/core/harnesses/codex/hooks/subagent-audit.sh +17 -6
  19. package/core/harnesses/codex/hooks/user-prompt-submit.sh +5 -4
  20. package/core/harnesses/gemini/hooks/mcp-tool-guard.sh +7 -18
  21. package/core/harnesses/gemini/hooks/pre-bash-guard.sh +7 -18
  22. package/core/harnesses/gemini/hooks/pre-implement-gate.sh +7 -19
  23. package/core/harnesses/gemini/hooks/session-start.sh +5 -3
  24. package/core/harnesses/kiro/hooks/mcp-tool-guard.sh +20 -5
  25. package/core/harnesses/kiro/hooks/pre-bash-guard.sh +20 -5
  26. package/core/harnesses/kiro/hooks/pre-implement-gate.sh +20 -5
  27. package/core/harnesses/kiro/hooks/session-start.sh +11 -5
  28. package/core/harnesses/kiro/hooks/stop-check.sh +21 -30
  29. package/core/harnesses/pi/extensions/doflow-guard.js +159 -0
  30. package/core/harnesses/shared/hooks/ENVELOPE_MIGRATION.md +27 -11
  31. package/core/harnesses/shared/hooks/adapters/antigravity.js +14 -57
  32. package/core/harnesses/shared/hooks/bridge/bridge.sh +184 -0
  33. package/core/harnesses/shared/hooks/bridge/envelope.jq +60 -0
  34. package/core/harnesses/shared/hooks/bridge/respond.sh +62 -0
  35. package/core/harnesses/shared/hooks/policies/capture-failure.sh +4 -2
  36. package/core/harnesses/shared/hooks/policies/contract.sh +75 -0
  37. package/core/harnesses/shared/hooks/policies/deny-json.sh +39 -4
  38. package/core/harnesses/shared/hooks/policies/lib.sh +4 -2
  39. package/core/harnesses/shared/hooks/policies/mcp-tool-guard.sh +46 -34
  40. package/core/harnesses/shared/hooks/policies/pre-bash-guard.sh +75 -25
  41. package/core/harnesses/shared/hooks/policies/pre-implementation-gate.sh +67 -73
  42. package/core/harnesses/shared/hooks/policies/session-context.sh +37 -7
  43. package/core/harnesses/shared/hooks/policies/stop-check.sh +42 -15
  44. package/core/harnesses/shared/hooks/policies/subagent-audit.sh +35 -5
  45. package/core/harnesses/shared/hooks/policies/user-prompt-submit.sh +40 -7
  46. package/core/harnesses/shared/hooks/stream-hook-runner.js +69 -181
  47. package/core/registry/assets.json +19 -0
  48. package/core/registry/contracts.json +2 -2
  49. package/core/registry/harnesses.json +196 -10
  50. package/core/registry/lifecycle.json +2626 -7
  51. package/core/registry/storage.json +110 -83
  52. package/core/registry/verification.json +1 -1
  53. package/core/shared/scripts/doflow/bash/render-puml.sh +2 -2
  54. package/core/shared/scripts/doflow/bin/doflow-run +10 -6
  55. package/core/shared/skills/do-design/SKILL.md +6 -6
  56. package/core/shared/skills/do-execute-plan/SKILL.md +11 -10
  57. package/core/shared/skills/do-execute-plan/references/readiness_gate.md +2 -0
  58. package/core/shared/skills/do-execute-plan/references/scaffold.md +2 -2
  59. package/core/shared/skills/do-implement/SKILL.md +3 -2
  60. package/core/shared/skills/do-plan/SKILL.md +7 -8
  61. package/package.json +4 -2
  62. package/src/adapters/antigravity/{index.ts → index.js} +141 -105
  63. package/src/adapters/claude/{index.ts → index.js} +63 -49
  64. package/src/adapters/claude/{mcp.ts → mcp.js} +16 -16
  65. package/src/adapters/codex/{agents.ts → agents.js} +24 -24
  66. package/src/adapters/codex/{config.ts → config.js} +49 -49
  67. package/src/adapters/codex/{hooks.ts → hooks.js} +62 -27
  68. package/src/adapters/codex/{index.ts → index.js} +148 -105
  69. package/src/adapters/codex/{mcp.ts → mcp.js} +38 -38
  70. package/src/adapters/codex/{native-projection.ts → native-projection.js} +5 -5
  71. package/src/adapters/copilot/{index.ts → index.js} +42 -42
  72. package/src/adapters/{copy-tree.ts → copy-tree.js} +74 -74
  73. package/src/adapters/gemini/{hooks.ts → hooks.js} +78 -37
  74. package/src/adapters/gemini/{index.ts → index.js} +96 -57
  75. package/src/adapters/{hook-commands.ts → hook-commands.js} +8 -8
  76. package/src/adapters/{index.ts → index.js} +13 -13
  77. package/src/adapters/kiro/{index.ts → index.js} +49 -35
  78. package/src/adapters/{mcp-entries.ts → mcp-entries.js} +55 -55
  79. package/src/adapters/opencode/{index.ts → index.js} +52 -52
  80. package/src/adapters/pi/hooks.js +119 -0
  81. package/src/adapters/pi/{index.ts → index.js} +64 -39
  82. package/src/adapters/pi/{json-members.ts → json-members.js} +23 -23
  83. package/src/adapters/pi/{mcp.ts → mcp.js} +70 -70
  84. package/src/adapters/{resolve-source.ts → resolve-source.js} +1 -1
  85. package/src/cli/commands/{install.ts → install.js} +25 -25
  86. package/src/cli/commands/{list-backups.ts → list-backups.js} +4 -4
  87. package/src/cli/commands/{reconcile.ts → reconcile.js} +19 -19
  88. package/src/cli/commands/{remove.ts → remove.js} +10 -10
  89. package/src/cli/commands/{rollback.ts → rollback.js} +17 -17
  90. package/src/cli/commands/{self-update.ts → self-update.js} +3 -3
  91. package/src/cli/commands/{status.ts → status.js} +24 -24
  92. package/src/cli/commands/{tools.ts → tools.js} +16 -16
  93. package/src/cli/commands/{update.ts → update.js} +20 -20
  94. package/src/cli/{index.ts → index.js} +43 -31
  95. package/src/cli/{runtime-commands.ts → runtime-commands.js} +97 -58
  96. package/src/cli/{shared.ts → shared.js} +40 -40
  97. package/src/helper/{bash-helper.ts → bash-helper.js} +7 -7
  98. package/src/helper/{git.ts → git.js} +2 -2
  99. package/src/helper/{guardrails.ts → guardrails.js} +10 -10
  100. package/src/helper/{harness-paths.ts → harness-paths.js} +24 -24
  101. package/src/helper/{marker-merge.ts → marker-merge.js} +4 -4
  102. package/src/helper/{prompt.ts → prompt.js} +5 -5
  103. package/src/helper/{repo-root.ts → repo-root.js} +2 -2
  104. package/src/helper/{settings-merge.ts → settings-merge.js} +27 -27
  105. package/src/helper/{settings-scope.ts → settings-scope.js} +3 -3
  106. package/src/helper/{toml.ts → toml.js} +48 -48
  107. package/src/install/{backup-set.ts → backup-set.js} +16 -16
  108. package/src/install/{backup.ts → backup.js} +65 -65
  109. package/src/install/{context.ts → context.js} +15 -15
  110. package/src/install/{manifest.ts → manifest.js} +27 -27
  111. package/src/install/{mcp.ts → mcp.js} +30 -30
  112. package/src/install/{paths.ts → paths.js} +15 -15
  113. package/src/install/{targets.ts → targets.js} +10 -10
  114. package/src/install/{tool-lifecycle.ts → tool-lifecycle.js} +20 -20
  115. package/src/lifecycle/{bash-availability.ts → bash-availability.js} +1 -1
  116. package/src/lifecycle/coverage.js +57 -0
  117. package/src/lifecycle/hook-step.js +61 -0
  118. package/src/lifecycle/{index.ts → index.js} +160 -146
  119. package/src/lifecycle/{mcp-index.ts → mcp-index.js} +1 -1
  120. package/src/lifecycle/{policies.ts → policies.js} +11 -11
  121. package/src/lifecycle/{view.ts → view.js} +28 -28
  122. package/src/registry/{index.ts → index.js} +195 -66
  123. package/src/release/build-package.js +91 -0
  124. package/src/release/changelog-section.js +70 -0
  125. package/src/release/{sync-plugin-versions.ts → sync-plugin-versions.js} +4 -4
  126. package/src/runtime/advice/{cli.ts → cli.js} +31 -31
  127. package/src/runtime/advice/{client.ts → client.js} +44 -44
  128. package/src/runtime/advice/{config.ts → config.js} +16 -16
  129. package/src/runtime/advice/{doctor.ts → doctor.js} +32 -32
  130. package/src/runtime/advice/{endpoint-guard.ts → endpoint-guard.js} +20 -20
  131. package/src/runtime/advice/{kinds.ts → kinds.js} +16 -16
  132. package/src/runtime/advice/providers/{ollama-systemone.ts → ollama-systemone.js} +21 -21
  133. package/src/runtime/advice/{record.ts → record.js} +19 -19
  134. package/src/runtime/advice/{registry.ts → registry.js} +16 -16
  135. package/src/runtime/advice/{strength.ts → strength.js} +7 -7
  136. package/src/runtime/{brief-tools.ts → brief-tools.js} +50 -50
  137. package/src/runtime/{c4-project.ts → c4-project.js} +27 -27
  138. package/src/runtime/candidate.js +505 -0
  139. package/src/runtime/{capability-router.ts → capability-router.js} +39 -39
  140. package/src/runtime/{checkouts.ts → checkouts.js} +21 -21
  141. package/src/runtime/{claims.ts → claims.js} +44 -35
  142. package/src/runtime/{cli-result.ts → cli-result.js} +15 -8
  143. package/src/runtime/{cli.ts → cli.js} +59 -292
  144. package/src/runtime/{command-detect.ts → command-detect.js} +47 -47
  145. package/src/runtime/context/budget.js +203 -0
  146. package/src/runtime/context/compose.js +1367 -0
  147. package/src/runtime/context/delivery-store.js +102 -0
  148. package/src/runtime/context/mandatory.js +594 -0
  149. package/src/runtime/context/pointer.js +142 -0
  150. package/src/runtime/context-pack.js +1277 -0
  151. package/src/runtime/{decision-register.ts → decision-register.js} +67 -67
  152. package/src/runtime/evidence-fields.js +39 -0
  153. package/src/runtime/{evidence-ledger.ts → evidence-ledger.js} +32 -25
  154. package/src/runtime/failure/{capture.ts → capture.js} +29 -29
  155. package/src/runtime/failure/{classifier.ts → classifier.js} +4 -4
  156. package/src/runtime/failure/{cli.ts → cli.js} +30 -30
  157. package/src/runtime/failure/{home.ts → home.js} +6 -6
  158. package/src/runtime/failure/{store.ts → store.js} +32 -32
  159. package/src/runtime/{feature-resolve.ts → feature-resolve.js} +6 -6
  160. package/src/runtime/{freshness.ts → freshness.js} +59 -22
  161. package/src/runtime/{health.ts → health.js} +72 -72
  162. package/src/runtime/{history-compactor.ts → history-compactor.js} +25 -25
  163. package/src/runtime/{implementation-gate.ts → implementation-gate.js} +30 -30
  164. package/src/runtime/inventory/{coverage.ts → coverage.js} +10 -10
  165. package/src/runtime/inventory/{identity.ts → identity.js} +2 -2
  166. package/src/runtime/inventory/{index.ts → index.js} +36 -36
  167. package/src/runtime/inventory/{precedence.ts → precedence.js} +2 -2
  168. package/src/runtime/inventory/{read-scopes.ts → read-scopes.js} +9 -9
  169. package/src/runtime/inventory/{siblings.ts → siblings.js} +15 -15
  170. package/src/runtime/knowledge/{chunker.ts → chunker.js} +12 -12
  171. package/src/runtime/knowledge/{hybrid.ts → hybrid.js} +17 -17
  172. package/src/runtime/knowledge/{index-store.ts → index-store.js} +23 -23
  173. package/src/runtime/knowledge/{retrieval.ts → retrieval.js} +27 -27
  174. package/src/runtime/{leak-scan.ts → leak-scan.js} +12 -12
  175. package/src/runtime/lifecycle/{cli.ts → cli.js} +32 -32
  176. package/src/runtime/lifecycle/{event-store.ts → event-store.js} +48 -48
  177. package/src/runtime/lifecycle/{fold.ts → fold.js} +41 -41
  178. package/src/runtime/lifecycle/{followup.ts → followup.js} +54 -54
  179. package/src/runtime/lifecycle/{goal.ts → goal.js} +50 -50
  180. package/src/runtime/lifecycle/{intent-writer.ts → intent-writer.js} +5 -5
  181. package/src/runtime/lifecycle/{overview.ts → overview.js} +47 -47
  182. package/src/runtime/lifecycle/{release.ts → release.js} +29 -29
  183. package/src/runtime/lifecycle/{report-store.ts → report-store.js} +25 -25
  184. package/src/runtime/lifecycle/{retention.ts → retention.js} +37 -37
  185. package/src/runtime/lifecycle/{root.ts → root.js} +9 -9
  186. package/src/runtime/lifecycle/{status.ts → status.js} +64 -64
  187. package/src/runtime/lifecycle/{store-upkeep.ts → store-upkeep.js} +46 -46
  188. package/src/runtime/{locator-resolve.ts → locator-resolve.js} +7 -7
  189. package/src/runtime/{mask.ts → mask.js} +22 -22
  190. package/src/runtime/{mcp-consultations.ts → mcp-consultations.js} +54 -54
  191. package/src/runtime/{mcp-reach.ts → mcp-reach.js} +24 -24
  192. package/src/runtime/{model-router.ts → model-router.js} +20 -20
  193. package/src/runtime/{outcome.ts → outcome.js} +27 -27
  194. package/src/runtime/{reach.ts → reach.js} +21 -21
  195. package/src/runtime/{readiness-record.ts → readiness-record.js} +12 -12
  196. package/src/runtime/{readiness.ts → readiness.js} +113 -43
  197. package/src/runtime/{recovery.ts → recovery.js} +15 -15
  198. package/src/runtime/{research-request.ts → research-request.js} +34 -34
  199. package/src/runtime/{retrieval-plan.ts → retrieval-plan.js} +453 -104
  200. package/src/runtime/retrieval-record.js +223 -0
  201. package/src/runtime/scaffold/{artifacts.ts → artifacts.js} +22 -19
  202. package/src/runtime/scaffold/{fingerprint.ts → fingerprint.js} +3 -3
  203. package/src/runtime/scaffold/{generate.ts → generate.js} +109 -109
  204. package/src/runtime/scaffold/{languages.ts → languages.js} +34 -34
  205. package/src/runtime/source-version.js +289 -0
  206. package/src/runtime/storage/{cli.ts → cli.js} +9 -9
  207. package/src/runtime/storage/{engine.ts → engine.js} +37 -37
  208. package/src/runtime/storage/{registry.ts → registry.js} +19 -19
  209. package/src/runtime/storage/{roots.ts → roots.js} +8 -8
  210. package/src/runtime/storage/{rules.ts → rules.js} +26 -26
  211. package/src/runtime/storage/{upkeep.ts → upkeep.js} +35 -35
  212. package/src/runtime/storage/{work-status.ts → work-status.js} +39 -39
  213. package/src/runtime/{task-attempts.ts → task-attempts.js} +62 -62
  214. package/src/runtime/{task-classifier.ts → task-classifier.js} +34 -34
  215. package/src/runtime/{task-scope.ts → task-scope.js} +40 -15
  216. package/src/runtime/{task-state.ts → task-state.js} +86 -21
  217. package/src/runtime/trace/{indicators.ts → indicators.js} +22 -22
  218. package/src/runtime/trace/{ledger.ts → ledger.js} +42 -42
  219. package/src/runtime/trace/{render.ts → render.js} +7 -7
  220. package/src/runtime/trace/{views.ts → views.js} +40 -40
  221. package/src/runtime/verification/{contract-runner.ts → contract-runner.js} +23 -23
  222. package/src/runtime/verification/{engine.ts → engine.js} +143 -143
  223. package/src/runtime/verification/{registry.ts → registry.js} +6 -6
  224. package/src/runtime/verification/{scope-bound.ts → scope-bound.js} +50 -50
  225. package/src/runtime/verification/{test-selection.ts → test-selection.js} +28 -28
  226. package/src/runtime/{workflow-engine.ts → workflow-engine.js} +50 -50
  227. package/src/runtime/{workflow-orchestrator.ts → workflow-orchestrator.js} +91 -91
  228. package/src/runtime/{worktree.ts → worktree.js} +31 -31
  229. package/src/state/{index.ts → index.js} +26 -26
  230. package/src/state/{lockfile.ts → lockfile.js} +20 -20
  231. package/src/state/{run-lock.ts → run-lock.js} +44 -44
  232. package/core/.antigravity-plugin/hooks.json +0 -39
  233. package/core/harnesses/shared/hooks/adapters/arg-fields.js +0 -19
  234. package/core/harnesses/shared/hooks/adapters/gemini.js +0 -114
  235. package/core/harnesses/shared/hooks/hooks.json +0 -47
  236. package/src/runtime/context-pack.ts +0 -492
@@ -14,8 +14,8 @@
14
14
 
15
15
  const path = require('node:path');
16
16
  const nodeFs = require('node:fs');
17
- const { parseYamlFile } = require('../capability-router.ts');
18
- const { REPO_ROOT } = require('../../helper/repo-root.ts');
17
+ const { parseYamlFile } = require('../capability-router.js');
18
+ const { REPO_ROOT } = require('../../helper/repo-root.js');
19
19
 
20
20
  const REGISTRY_FILENAME = 'verification.json';
21
21
 
@@ -48,7 +48,7 @@ const RECOVERY_OUTCOMES = Object.freeze([
48
48
  'NO_REMEDIATION',
49
49
  ]);
50
50
 
51
- function assert(condition: any, message: string): void {
51
+ function assert(condition , message ) {
52
52
  if (!condition) throw new Error(`verification.json is invalid: ${message}`);
53
53
  }
54
54
 
@@ -67,7 +67,7 @@ function assert(condition: any, message: string): void {
67
67
  * @param {Object} [options.fsImpl]
68
68
  * @returns {Object} the validated registry
69
69
  */
70
- function loadVerificationRegistry(options: any = {}): any {
70
+ function loadVerificationRegistry(options = {}) {
71
71
  let data = options.registry;
72
72
  if (!data) {
73
73
  const repoRoot = options.repoRoot || REPO_ROOT;
@@ -84,7 +84,7 @@ function loadVerificationRegistry(options: any = {}): any {
84
84
  // FR-009 states this as a MUST, so it is enforced at load rather than trusted at call sites.
85
85
  assert(policy.modelReviewIsPrimaryProof === false, 'policy.modelReviewIsPrimaryProof must be false');
86
86
 
87
- const seen = new Set<string>();
87
+ const seen = new Set ();
88
88
  let previousOrder = -Infinity;
89
89
  let lastNonModelOrder = -Infinity;
90
90
  let firstModelOrder = Infinity;
@@ -107,7 +107,7 @@ function loadVerificationRegistry(options: any = {}): any {
107
107
  // of the registry, so it is checkable here instead of being re-asserted in prose.
108
108
  assert(firstModelOrder > lastNonModelOrder, 'every model-based tier must be ordered after every deterministic tier');
109
109
 
110
- for (const [level, def] of Object.entries(data.riskLevels) as [string, any][]) {
110
+ for (const [level, def] of Object.entries(data.riskLevels) ) {
111
111
  assert(def && Array.isArray(def.requiredTiers), `risk level '${level}' needs requiredTiers`);
112
112
  for (const id of def.requiredTiers.concat(def.advisoryTiers || [])) {
113
113
  assert(seen.has(id), `risk level '${level}' references unknown tier '${id}'`);
@@ -5,9 +5,9 @@
5
5
  const fs = require('node:fs');
6
6
  const path = require('node:path');
7
7
  const { spawnSync } = require('node:child_process');
8
- const { resolveActiveFeature } = require('../feature-resolve.ts');
9
- const { resolveBashHelper } = require('../../helper/bash-helper.ts');
10
- const { listCheckouts } = require('../checkouts.ts');
8
+ const { resolveActiveFeature } = require('../feature-resolve.js');
9
+ const { resolveBashHelper } = require('../../helper/bash-helper.js');
10
+ const { listCheckouts } = require('../checkouts.js');
11
11
 
12
12
  // The change-scope bound of a planned feature, and the baseline a change is measured from
13
13
  // (feature 045, IC-003 / IC-004).
@@ -36,13 +36,13 @@ const NONE_FIELD = /^none(?=$|[\s(;,`])/i;
36
36
  * @param {string} planText
37
37
  * @returns {Array<string>}
38
38
  */
39
- function taskFilesFromPlan(planText: any): string[] {
39
+ function taskFilesFromPlan(planText ) {
40
40
  const lines = String(planText || '').split('\n');
41
- const paths: string[] = [];
41
+ const paths = [];
42
42
  for (let i = 0; i < lines.length; i += 1) {
43
43
  if (!TASK_LINE.test(lines[i])) continue;
44
44
  let at = -1;
45
- for (const m of lines[i].matchAll(FILES_FIELD)) at = (m.index as number) + m[0].length;
45
+ for (const m of lines[i].matchAll(FILES_FIELD)) at = (m.index ) + m[0].length;
46
46
  if (at === -1) continue;
47
47
  let rest = lines[i].slice(at);
48
48
  // `files: none (...)` states that a task changes no file; its words are not paths.
@@ -65,9 +65,9 @@ function taskFilesFromPlan(planText: any): string[] {
65
65
  return [...new Set(paths)];
66
66
  }
67
67
 
68
- const folderOf = (slug: string | null) => (slug ? `agent-docs/doflow/${slug}/` : null);
68
+ const folderOf = (slug ) => (slug ? `agent-docs/doflow/${slug}/` : null);
69
69
 
70
- function isFile(file: string): boolean {
70
+ function isFile(file ) {
71
71
  try {
72
72
  return fs.statSync(file).isFile();
73
73
  } catch {
@@ -75,7 +75,7 @@ function isFile(file: string): boolean {
75
75
  }
76
76
  }
77
77
 
78
- function isDirectory(dir: string): boolean {
78
+ function isDirectory(dir ) {
79
79
  try {
80
80
  return fs.statSync(dir).isDirectory();
81
81
  } catch {
@@ -84,7 +84,7 @@ function isDirectory(dir: string): boolean {
84
84
  }
85
85
 
86
86
  /** Why no other checkout was consulted, in the words a reason text lists. */
87
- function noMainCheckout(checkouts: any): string {
87
+ function noMainCheckout(checkouts ) {
88
88
  if (!checkouts.ok) {
89
89
  if (checkouts.reason === 'not-a-git-repository') return 'not a git repository';
90
90
  if (checkouts.reason === 'git-unavailable') return 'git is not available';
@@ -110,20 +110,20 @@ function noMainCheckout(checkouts: any): string {
110
110
  * @returns {{plan: string|null, planRel: string|null, origin: string|null, root: string|null, slug: string|null,
111
111
  * folderRel: string|null, hasRegister: boolean, searched: Array<{place: string, result: string}>, reason: string|null}}
112
112
  */
113
- function resolvePlanSource({ projectRoot, slug = null, planPath = null, exec = spawnSync }: {
114
- projectRoot: string;
115
- slug?: string | null;
116
- planPath?: string | null;
117
- exec?: any;
118
- }): any {
119
- const searched: any[] = [];
120
- const result = (fields: any) => ({
113
+ function resolvePlanSource({ projectRoot, slug = null, planPath = null, exec = spawnSync }
114
+
115
+
116
+
117
+
118
+ ) {
119
+ const searched = [];
120
+ const result = (fields ) => ({
121
121
  plan: null, planRel: null, origin: null, root: null, slug: null, folderRel: null, hasRegister: false, searched, reason: null, ...fields,
122
122
  });
123
- const resolve = (s: string | null) => {
123
+ const resolve = (s ) => {
124
124
  try {
125
125
  return resolveActiveFeature({ projectRoot, slug: s });
126
- } catch (error: any) {
126
+ } catch (error ) {
127
127
  return { error: 'resolver-failed', message: `could not run the feature resolver: ${error.message}` };
128
128
  }
129
129
  };
@@ -151,7 +151,7 @@ function resolvePlanSource({ projectRoot, slug = null, planPath = null, exec = s
151
151
  }
152
152
  const s = found.paths.feature_slug;
153
153
  const folderRel = folderOf(s);
154
- const withFolder = (fields: any) => {
154
+ const withFolder = (fields ) => {
155
155
  const plan = path.resolve(fields.root, fields.planRel);
156
156
  let reason = null;
157
157
  if (!isFile(plan)) reason = 'no-plan';
@@ -182,7 +182,7 @@ function resolvePlanSource({ projectRoot, slug = null, planPath = null, exec = s
182
182
  }
183
183
 
184
184
  /** Why a declared-scope token is refused, or null when it is a repository-relative path. */
185
- function refusedToken(token: string): string | null {
185
+ function refusedToken(token ) {
186
186
  if (token === '') return 'it is empty';
187
187
  if (/[\s\\\0]/.test(token)) return 'it contains whitespace';
188
188
  if (token.startsWith('/') || token.startsWith('~') || /^[A-Za-z]:/.test(token)) return 'it is absolute';
@@ -200,8 +200,8 @@ function refusedToken(token: string): string | null {
200
200
  * @param {string} text
201
201
  * @returns {{paths: Array<string>, reason: null}|{paths: null, reason: string}}
202
202
  */
203
- function parseDeclaredScope(text: any): any {
204
- const paths: string[] = [];
203
+ function parseDeclaredScope(text ) {
204
+ const paths = [];
205
205
  for (const raw of String(text).trim().split(',')) {
206
206
  const written = raw.trim();
207
207
  const token = written.replace(/^(\.\/)+/, '');
@@ -225,20 +225,20 @@ function parseDeclaredScope(text: any): any {
225
225
  * @param {Function} [options.exec]
226
226
  * @returns {{bound: Object|null, reason: string|null, searched: Array<Object>, planSource: Object}}
227
227
  */
228
- function resolveScopeBound({ projectRoot, slug = null, planPath = null, declared = null, baselineRef = null, exec = spawnSync }: {
229
- projectRoot: string;
230
- slug?: string | null;
231
- planPath?: string | null;
232
- declared?: any;
233
- baselineRef?: string | null;
234
- exec?: any;
235
- }): any {
228
+ function resolveScopeBound({ projectRoot, slug = null, planPath = null, declared = null, baselineRef = null, exec = spawnSync }
229
+
230
+
231
+
232
+
233
+
234
+
235
+ ) {
236
236
  const planSource = resolvePlanSource({ projectRoot, slug, planPath, exec });
237
237
  let reason = planSource.reason;
238
- const allowed: string[] = [];
239
- const sources: any[] = [];
238
+ const allowed = [];
239
+ const sources = [];
240
240
  if (reason === null) {
241
- let text: string | null = null;
241
+ let text = null;
242
242
  try {
243
243
  text = fs.readFileSync(planSource.plan, 'utf8');
244
244
  } catch {
@@ -257,7 +257,7 @@ function resolveScopeBound({ projectRoot, slug = null, planPath = null, declared
257
257
  sources.push({ kind: 'declared', paths: [...declared.paths], origin: declared.origin, ...(declared.record ? { record: declared.record } : {}) });
258
258
  }
259
259
 
260
- let baseline: any = null;
260
+ let baseline = null;
261
261
  if (baselineRef !== null && baselineRef !== undefined) {
262
262
  const res = resolveExplicitBaseline({ cwd: projectRoot, ref: baselineRef, exec });
263
263
  if (!res.ok) {
@@ -294,12 +294,12 @@ function resolveScopeBound({ projectRoot, slug = null, planPath = null, declared
294
294
  * @param {string|null} [options.slug]
295
295
  * @returns {{allowedPaths: Array<string>, source: string}|null}
296
296
  */
297
- function buildScopeBound({ projectRoot, slug = null }: { projectRoot: string; slug?: string | null }): any {
297
+ function buildScopeBound({ projectRoot, slug = null } ) {
298
298
  const { bound } = resolveScopeBound({ projectRoot, slug });
299
299
  return bound ? { allowedPaths: bound.allowedPaths, source: bound.source } : null;
300
300
  }
301
301
 
302
- function originText(origin: string | null, root: string | null): string {
302
+ function originText(origin , root ) {
303
303
  if (origin === 'main-checkout') return `main checkout ${root}`;
304
304
  if (origin === 'plan-path') return '--plan-path';
305
305
  return 'current checkout';
@@ -314,8 +314,8 @@ function originText(origin: string | null, root: string | null): string {
314
314
  * @param {Object} options.planSource the `resolvePlanSource` result
315
315
  * @returns {string}
316
316
  */
317
- function scopeReasonText({ reason, taskId, planSource }: { reason: string; taskId: string; planSource: any }): string {
318
- const places = planSource.searched.map((s: any) => `${s.place}: ${s.result}`).join('; ');
317
+ function scopeReasonText({ reason, taskId, planSource } ) {
318
+ const places = planSource.searched.map((s ) => `${s.place}: ${s.result}`).join('; ');
319
319
  const where = `${planSource.folderRel} (${originText(planSource.origin, planSource.root)})`;
320
320
  switch (reason) {
321
321
  case 'no-plan':
@@ -336,8 +336,8 @@ function scopeReasonText({ reason, taskId, planSource }: { reason: string; taskI
336
336
  * @param {Array<Object>} sources a bound's `sources`
337
337
  * @returns {string}
338
338
  */
339
- function boundSourcesText(sources: any[]): string {
340
- return sources.map((s: any) => (s.kind === 'plan'
339
+ function boundSourcesText(sources ) {
340
+ return sources.map((s ) => (s.kind === 'plan'
341
341
  ? `plan ${s.path} (${originText(s.origin, s.root)})`
342
342
  : `declared ${s.paths.join(',')} (${s.origin === 'readiness-record' ? `readiness record ${s.record}` : '--scope'})`)).join(' + ');
343
343
  }
@@ -351,17 +351,17 @@ function boundSourcesText(sources: any[]): string {
351
351
  * @param {Function} [options.exec] spawnSync-compatible
352
352
  * @returns {{ref: string, mergeBase: string}|{reason: string}}
353
353
  */
354
- function resolveIntegrationBase({ cwd, exec = spawnSync }: { cwd: string; exec?: any }): any {
355
- const run = (cmd: string, args: string[]) => {
354
+ function resolveIntegrationBase({ cwd, exec = spawnSync } ) {
355
+ const run = (cmd , args ) => {
356
356
  try {
357
357
  return exec(cmd, args, { cwd, encoding: 'utf8', timeout: 30000 });
358
- } catch (error: any) {
358
+ } catch (error ) {
359
359
  return { error };
360
360
  }
361
361
  };
362
362
  const gitState = resolveBashHelper('do-git-state.sh');
363
363
  const state = gitState ? run('bash', [gitState, '--json']) : null;
364
- let ref: string | null = null;
364
+ let ref = null;
365
365
  if (state && !state.error && state.status === 0) {
366
366
  try { ref = JSON.parse(state.stdout).integration_ref || null; } catch { /* reported below */ }
367
367
  }
@@ -386,13 +386,13 @@ function resolveIntegrationBase({ cwd, exec = spawnSync }: { cwd: string; exec?:
386
386
  * @param {Function} [options.exec] spawnSync-compatible
387
387
  * @returns {{ok: true, ref: string, sha: string}|{ok: false, ref: string, reason: string}}
388
388
  */
389
- function resolveExplicitBaseline({ cwd, ref, exec = spawnSync }: { cwd: string; ref: string; exec?: any }): any {
390
- const fail = (reason: string) => ({ ok: false, ref, reason });
389
+ function resolveExplicitBaseline({ cwd, ref, exec = spawnSync } ) {
390
+ const fail = (reason ) => ({ ok: false, ref, reason });
391
391
  if (typeof ref !== 'string' || ref.trim() === '' || ref.startsWith('-')) {
392
392
  return fail(`baseline ref '${ref}' is not a usable commit or ref`);
393
393
  }
394
- const run = (args: string[]) => {
395
- try { return exec('git', args, { cwd, encoding: 'utf8', timeout: 30000 }); } catch (error: any) { return { error }; }
394
+ const run = (args ) => {
395
+ try { return exec('git', args, { cwd, encoding: 'utf8', timeout: 30000 }); } catch (error ) { return { error }; }
396
396
  };
397
397
  const parsed = run(['rev-parse', '--verify', '--quiet', '--end-of-options', `${ref}^{commit}`]);
398
398
  const sha = parsed && !parsed.error && parsed.status === 0 ? String(parsed.stdout || '').trim() : '';
@@ -40,18 +40,18 @@ const WIN32_UNQUOTABLE = /[%!]/;
40
40
  * @param {string} [platform]
41
41
  * @returns {string}
42
42
  */
43
- function quotePath(file: string, platform: string = process.platform): string {
43
+ function quotePath(file , platform = process.platform) {
44
44
  if (SAFE_WORD.test(file)) return file;
45
45
  if (platform === 'win32') return `"${file.replace(/"/g, '""')}"`;
46
46
  return `'${file.replace(/'/g, `'\\''`)}'`;
47
47
  }
48
48
 
49
49
  /** Normalises a repository-relative path: forward slashes, no leading `./`, no trailing `/`. */
50
- function normalize(file: any): string {
50
+ function normalize(file ) {
51
51
  return String(file).replace(/\\/g, '/').replace(/^(?:\.\/)+/, '').replace(/\/+$/, '');
52
52
  }
53
53
 
54
- function statOf(fsImpl: any, file: string): any {
54
+ function statOf(fsImpl , file ) {
55
55
  try {
56
56
  return fsImpl.statSync(file);
57
57
  } catch {
@@ -60,14 +60,14 @@ function statOf(fsImpl: any, file: string): any {
60
60
  }
61
61
 
62
62
  /** Repository-relative paths of every file under `rel` (a file counts as itself). */
63
- function walkFiles(fsImpl: any, root: string, rel: string): string[] {
63
+ function walkFiles(fsImpl , root , rel ) {
64
64
  const abs = path.join(root, rel);
65
65
  const stat = statOf(fsImpl, abs);
66
66
  if (!stat) return [];
67
67
  if (stat.isFile()) return [normalize(rel)];
68
68
  if (!stat.isDirectory()) return [];
69
- const out: string[] = [];
70
- let entries: any[];
69
+ const out = [];
70
+ let entries ;
71
71
  try {
72
72
  entries = fsImpl.readdirSync(abs, { withFileTypes: true });
73
73
  } catch {
@@ -88,19 +88,19 @@ function walkFiles(fsImpl: any, root: string, rel: string): string[] {
88
88
  * @param {{ source?: string, testDirs?: Array<string> }} found the detected `testTargeted` entry
89
89
  * @returns {null|{ basis: string, isTest: Function, roots: Array<string>, guardDir: string|null }}
90
90
  */
91
- function conventionFor(found: any): any {
91
+ function conventionFor(found ) {
92
92
  if (found && found.source === 'package.json' && Array.isArray(found.testDirs) && found.testDirs.length > 0) {
93
93
  const roots = found.testDirs.map(normalize).filter(Boolean);
94
- const underRoot = (file: string) => roots.some((r: string) => file === r || file.startsWith(`${r}/`));
94
+ const underRoot = (file ) => roots.some((r ) => file === r || file.startsWith(`${r}/`));
95
95
  return {
96
96
  basis: 'changed-test-files',
97
97
  roots,
98
- isTest: (file: string) => NODE_TEST_FILE.test(file) && underRoot(file),
99
- guardDir: roots.some((r: string) => GUARD_DIR === r || GUARD_DIR.startsWith(`${r}/`)) ? GUARD_DIR : null,
98
+ isTest: (file ) => NODE_TEST_FILE.test(file) && underRoot(file),
99
+ guardDir: roots.some((r ) => GUARD_DIR === r || GUARD_DIR.startsWith(`${r}/`)) ? GUARD_DIR : null,
100
100
  };
101
101
  }
102
102
  if (found && found.source === 'pyproject.toml') {
103
- return { basis: 'changed-test-files', roots: ['.'], isTest: (file: string) => PYTEST_FILE.test(file), guardDir: null };
103
+ return { basis: 'changed-test-files', roots: ['.'], isTest: (file ) => PYTEST_FILE.test(file), guardDir: null };
104
104
  }
105
105
  return null;
106
106
  }
@@ -116,22 +116,22 @@ function conventionFor(found: any): any {
116
116
  * @returns {null|{ pattern: string|null, selection: { basis: string, selectedCount: number|null,
117
117
  * totalCount: number|null, fallback: string|null } }} null when no convention applies to the toolchain
118
118
  */
119
- function selectChangedTests({ found, observation, root, fsImpl = nodeFs, platform = process.platform }: {
120
- found: any;
121
- observation: any;
122
- root: string;
123
- fsImpl?: any;
124
- platform?: string;
125
- }): any {
119
+ function selectChangedTests({ found, observation, root, fsImpl = nodeFs, platform = process.platform }
120
+
121
+
122
+
123
+
124
+
125
+ ) {
126
126
  const convention = conventionFor(found);
127
127
  if (!convention) return null;
128
128
 
129
- const total = new Set<string>();
129
+ const total = new Set ();
130
130
  for (const r of convention.roots) {
131
131
  for (const file of walkFiles(fsImpl, root, r)) if (convention.isTest(file)) total.add(file);
132
132
  }
133
133
  const totalCount = total.size;
134
- const fallback = (reason: string, selectedCount: number | null = 0) => ({
134
+ const fallback = (reason , selectedCount = 0) => ({
135
135
  pattern: null,
136
136
  selection: { basis: convention.basis, selectedCount, totalCount, fallback: reason },
137
137
  });
@@ -141,22 +141,22 @@ function selectChangedTests({ found, observation, root, fsImpl = nodeFs, platfor
141
141
  const guardDir = convention.guardDir && statOf(fsImpl, path.join(root, convention.guardDir))?.isDirectory()
142
142
  ? convention.guardDir
143
143
  : null;
144
- const underGuard = (file: string) => guardDir !== null && file.startsWith(`${guardDir}/`);
144
+ const underGuard = (file ) => guardDir !== null && file.startsWith(`${guardDir}/`);
145
145
 
146
- const changed = [...new Set<string>(observation.files.map(normalize))]
147
- .filter((file: string) => convention.isTest(file))
148
- .filter((file: string) => statOf(fsImpl, path.join(root, file))?.isFile())
146
+ const changed = [...new Set (observation.files.map(normalize))]
147
+ .filter((file ) => convention.isTest(file))
148
+ .filter((file ) => statOf(fsImpl, path.join(root, file))?.isFile())
149
149
  .sort();
150
150
  if (changed.length === 0) return fallback('no-changed-tests');
151
151
 
152
152
  // A changed guard file is already covered by running the guard directory itself.
153
- const files = changed.filter((file: string) => !underGuard(file));
153
+ const files = changed.filter((file ) => !underGuard(file));
154
154
  const guardFiles = guardDir ? [...total].filter(underGuard).length : 0;
155
155
  // `cmd.exe` expands `%` and `!` even inside quotes, so such a path cannot be passed safely there.
156
- if (platform === 'win32' && files.some((file: string) => WIN32_UNQUOTABLE.test(file))) return fallback('unsafe-path');
156
+ if (platform === 'win32' && files.some((file ) => WIN32_UNQUOTABLE.test(file))) return fallback('unsafe-path');
157
157
  // A relative path starting with `-` would be read as a runner option, so it gets a directory prefix.
158
- const asArgument = (file: string) => (file.startsWith('-') ? `./${file}` : file);
159
- const words = [...files.map((file: string) => quotePath(asArgument(file), platform))];
158
+ const asArgument = (file ) => (file.startsWith('-') ? `./${file}` : file);
159
+ const words = [...files.map((file ) => quotePath(asArgument(file), platform))];
160
160
  if (guardDir) words.push(quotePath(`${guardDir}/`, platform));
161
161
  return {
162
162
  pattern: words.join(' '),