@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
@@ -25,40 +25,40 @@ const LOCK_FILE = 'run.lock';
25
25
  const CLAIM_PREFIX = `${LOCK_FILE}.claim.`;
26
26
  const TEMP_NAME = /^\.run\.lock\.([0-9a-f]{32})\.tmp$/;
27
27
 
28
- function loadVersion(): string {
28
+ function loadVersion() {
29
29
  try { return require('../../package.json').version; } catch { return '0.0.0-installed'; }
30
30
  }
31
31
  const DOFLOW_VERSION = loadVersion();
32
32
 
33
33
  /** Holds of this process, by resolved scope root: a nested acquisition counts instead of waiting on itself. */
34
- const held = new Map<string, { count: number, handle: any }>();
34
+ const held = new Map ();
35
35
 
36
- function runLockPath(scopeRoot: string): string { return path.join(path.resolve(scopeRoot), '.doflow', 'state', LOCK_FILE); }
36
+ function runLockPath(scopeRoot ) { return path.join(path.resolve(scopeRoot), '.doflow', 'state', LOCK_FILE); }
37
37
 
38
- function atomicsSleep(ms: number): void {
38
+ function atomicsSleep(ms ) {
39
39
  Atomics.wait(new Int32Array(new SharedArrayBuffer(4)), 0, 0, ms);
40
40
  }
41
41
 
42
42
  /** Alive when signal 0 reaches it, or it exists but belongs to someone else (EPERM). */
43
- function defaultIsAlive(pid: any): boolean {
43
+ function defaultIsAlive(pid ) {
44
44
  if (!Number.isInteger(pid) || pid <= 0) return false;
45
45
  try {
46
46
  process.kill(pid, 0);
47
47
  return true;
48
- } catch (err: any) {
48
+ } catch (err ) {
49
49
  return err.code === 'EPERM';
50
50
  }
51
51
  }
52
52
 
53
- function scopeLabel({ scope, scopeRoot }: { scope: string, scopeRoot: string }): string {
53
+ function scopeLabel({ scope, scopeRoot } ) {
54
54
  return scope === 'global' ? `global scope (${scopeRoot})` : `project ${scopeRoot}`;
55
55
  }
56
56
 
57
- function holderLabel(holder: any): string {
57
+ function holderLabel(holder ) {
58
58
  return holder ? `pid ${holder.pid}, ${holder.command}, started ${holder.startedAt}` : 'holder unknown';
59
59
  }
60
60
 
61
- const STALE_REASONS: Record<string, string> = Object.freeze({ 'not-running': 'that process is not running', expired: 'it is older than 10 minutes' });
61
+ const STALE_REASONS = Object.freeze({ 'not-running': 'that process is not running', expired: 'it is older than 10 minutes' });
62
62
 
63
63
  /**
64
64
  * The one text of every run-lock line, so the CLI prints exactly these.
@@ -66,7 +66,7 @@ const STALE_REASONS: Record<string, string> = Object.freeze({ 'not-running': 'th
66
66
  * @param {{scope: string, scopeRoot: string, holder?: Object|null, waitMs?: number, reason?: string,
67
67
  * lockPath?: string, waitedMs?: number, code?: string}} details
68
68
  */
69
- function formatRunLockMessage(kind: string, details: any): string {
69
+ function formatRunLockMessage(kind , details ) {
70
70
  const where = scopeLabel(details);
71
71
  switch (kind) {
72
72
  case 'waiting':
@@ -85,7 +85,7 @@ function formatRunLockMessage(kind: string, details: any): string {
85
85
  }
86
86
 
87
87
  class RunLockError extends Error {
88
- constructor(details: any) {
88
+ constructor(details ) {
89
89
  super(formatRunLockMessage('error', details));
90
90
  this.name = 'RunLockError';
91
91
  Object.assign(this, { code: details.code, lockPath: details.lockPath, scopeRoot: details.scopeRoot });
@@ -93,7 +93,7 @@ class RunLockError extends Error {
93
93
  }
94
94
 
95
95
  class RunLockTimeoutError extends Error {
96
- constructor(details: any) {
96
+ constructor(details ) {
97
97
  super(formatRunLockMessage('timeout', details));
98
98
  this.name = 'RunLockTimeoutError';
99
99
  Object.assign(this, { holder: details.holder, lockPath: details.lockPath, scopeRoot: details.scopeRoot, waitedMs: details.waitedMs });
@@ -101,14 +101,14 @@ class RunLockTimeoutError extends Error {
101
101
  }
102
102
 
103
103
  class RunLockLostError extends Error {
104
- constructor(details: any) {
104
+ constructor(details ) {
105
105
  super(formatRunLockMessage('lost', details));
106
106
  this.name = 'RunLockLostError';
107
107
  Object.assign(this, { lockPath: details.lockPath, scopeRoot: details.scopeRoot });
108
108
  }
109
109
  }
110
110
 
111
- function isIdentified(record: any): boolean {
111
+ function isIdentified(record ) {
112
112
  return Boolean(record) && typeof record.token === 'string' && Number.isInteger(record.pid) && typeof record.hostname === 'string';
113
113
  }
114
114
 
@@ -117,15 +117,15 @@ function isIdentified(record: any): boolean {
117
117
  * replaced between the two calls can never pair one instance's record with another's age.
118
118
  * @returns {{record: Object|null, stat: fs.Stats, key: string}|null} null when there is no lock
119
119
  */
120
- function readLockFile(fsImpl: any, lockPath: string): { record: any, stat: any, key: string } | null {
121
- let fd: any;
120
+ function readLockFile(fsImpl , lockPath ) {
121
+ let fd ;
122
122
  try {
123
123
  fd = fsImpl.openSync(lockPath, 'r');
124
- } catch (err: any) {
124
+ } catch (err ) {
125
125
  if (err.code !== 'ENOENT') throw err;
126
126
  // A dangling symlink opens as ENOENT yet blocks link(); judge it by its own lstat.
127
127
  let stat;
128
- try { stat = fsImpl.lstatSync(lockPath); } catch (lstatErr: any) {
128
+ try { stat = fsImpl.lstatSync(lockPath); } catch (lstatErr ) {
129
129
  if (lstatErr.code === 'ENOENT') return null;
130
130
  throw lstatErr;
131
131
  }
@@ -142,12 +142,12 @@ function readLockFile(fsImpl: any, lockPath: string): { record: any, stat: any,
142
142
  }
143
143
  }
144
144
 
145
- function instanceKey(record: any, stat: any): string {
145
+ function instanceKey(record , stat ) {
146
146
  return record ? record.token : `u-${stat.dev}-${stat.ino}-${Math.floor(stat.mtimeMs)}`;
147
147
  }
148
148
 
149
149
  /** @returns {null|'not-running'|'expired'} */
150
- function staleReason(found: any, { token, hostname, isAlive, now, staleMs }: any): 'not-running' | 'expired' | null {
150
+ function staleReason(found , { token, hostname, isAlive, now, staleMs } ) {
151
151
  const { record, stat } = found;
152
152
  if (record && record.token === token) return null;
153
153
  if (record && record.hostname === hostname && (record.pid === process.pid || !isAlive(record.pid))) return 'not-running';
@@ -155,16 +155,16 @@ function staleReason(found: any, { token, hostname, isAlive, now, staleMs }: any
155
155
  return null;
156
156
  }
157
157
 
158
- function unlinkQuietly(fsImpl: any, file: string): void {
158
+ function unlinkQuietly(fsImpl , file ) {
159
159
  try { fsImpl.unlinkSync(file); } catch { /* already gone, or the stale rule clears it later */ }
160
160
  }
161
161
 
162
- function readRaw(fsImpl: any, file: string): string | null {
162
+ function readRaw(fsImpl , file ) {
163
163
  try { return fsImpl.readFileSync(file, 'utf8'); } catch { return null; }
164
164
  }
165
165
 
166
166
  /** A claim left by a run that died while clearing: its process is gone, or it is older than claimStaleMs. */
167
- function isOrphanClaim(fsImpl: any, claimPath: string, { hostname, isAlive, now, claimStaleMs }: any): boolean {
167
+ function isOrphanClaim(fsImpl , claimPath , { hostname, isAlive, now, claimStaleMs } ) {
168
168
  let stat;
169
169
  try { stat = fsImpl.statSync(claimPath); } catch { return false; }
170
170
  if (now() - stat.mtimeMs > claimStaleMs) return true;
@@ -174,12 +174,12 @@ function isOrphanClaim(fsImpl: any, claimPath: string, { hostname, isAlive, now,
174
174
  }
175
175
 
176
176
  /** Creates the claim for one lock instance. @returns {boolean} true when this run now holds it */
177
- function createClaim(fsImpl: any, claimPath: string, { token, hostname, target }: any): boolean {
177
+ function createClaim(fsImpl , claimPath , { token, hostname, target } ) {
178
178
  const body = `${JSON.stringify({ version: RECORD_VERSION, token, pid: process.pid, hostname, at: new Date().toISOString(), target })}\n`;
179
179
  try {
180
180
  fsImpl.writeFileSync(claimPath, body, { flag: 'wx' });
181
181
  return true;
182
- } catch (err: any) {
182
+ } catch (err ) {
183
183
  if (err.code === 'EEXIST') return false;
184
184
  throw err;
185
185
  }
@@ -191,7 +191,7 @@ function createClaim(fsImpl: any, claimPath: string, { token, hostname, target }
191
191
  * back when what was moved is not what was judged, so a fresh claim is never deleted by mistake.
192
192
  * @returns {boolean}
193
193
  */
194
- function claimInstance(fsImpl: any, stateDir: string, key: string, options: any): boolean {
194
+ function claimInstance(fsImpl , stateDir , key , options ) {
195
195
  const claimPath = path.join(stateDir, `${CLAIM_PREFIX}${key}`);
196
196
  for (let attempt = 0; attempt < 2; attempt += 1) {
197
197
  if (createClaim(fsImpl, claimPath, { token: options.token, hostname: options.hostname, target: key })) return true;
@@ -213,7 +213,7 @@ function claimInstance(fsImpl: any, stateDir: string, key: string, options: any)
213
213
  * Removes the stale instance `found` under its claim.
214
214
  * @returns {'cleared'|'aborted'}
215
215
  */
216
- function takeOver(fsImpl: any, stateDir: string, lockPath: string, found: any, options: any): 'cleared' | 'aborted' {
216
+ function takeOver(fsImpl , stateDir , lockPath , found , options ) {
217
217
  if (!claimInstance(fsImpl, stateDir, found.key, options)) return 'aborted';
218
218
  const claimPath = path.join(stateDir, `${CLAIM_PREFIX}${found.key}`);
219
219
  try {
@@ -222,7 +222,7 @@ function takeOver(fsImpl: any, stateDir: string, lockPath: string, found: any, o
222
222
  // Judged again under the claim: a holder whose checkpoint renewed the lock since the first
223
223
  // judgment is no longer stale, and its lock stays.
224
224
  if (!staleReason(current, options)) return 'aborted';
225
- try { fsImpl.unlinkSync(lockPath); } catch (err: any) {
225
+ try { fsImpl.unlinkSync(lockPath); } catch (err ) {
226
226
  if (err.code !== 'ENOENT') return 'aborted';
227
227
  }
228
228
  return 'cleared';
@@ -235,7 +235,7 @@ function takeOver(fsImpl: any, stateDir: string, lockPath: string, found: any, o
235
235
 
236
236
  /** Removes owner temp files left by runs that died while they waited, judged by the stale rule as
237
237
  * a lock would be: interrupting a waiting run is the one exit that never reaches its own cleanup. */
238
- function sweepOrphanTemps(fsImpl: any, stateDir: string, judge: any): void {
238
+ function sweepOrphanTemps(fsImpl , stateDir , judge ) {
239
239
  let names;
240
240
  try { names = fsImpl.readdirSync(stateDir); } catch { return; }
241
241
  for (const name of names) {
@@ -249,7 +249,7 @@ function sweepOrphanTemps(fsImpl: any, stateDir: string, judge: any): void {
249
249
  }
250
250
 
251
251
  /** Removes, innermost first, the directories an acquisition created, stopping at the first non-empty one. */
252
- function removeCreatedDirs(fsImpl: any, stateDir: string, firstCreated: any): void {
252
+ function removeCreatedDirs(fsImpl , stateDir , firstCreated ) {
253
253
  if (!firstCreated) return;
254
254
  const top = path.resolve(firstCreated);
255
255
  for (let dir = stateDir; ; dir = path.dirname(dir)) {
@@ -267,11 +267,11 @@ function removeCreatedDirs(fsImpl: any, stateDir: string, firstCreated: any): vo
267
267
  * checkpoint: () => void, release: () => void}}
268
268
  * @throws {RunLockTimeoutError|RunLockError}
269
269
  */
270
- function acquireRunLock({ scopeRoot, scope, command }: { scopeRoot: string, scope: 'global' | 'project', command: string }, {
270
+ function acquireRunLock({ scopeRoot, scope, command } , {
271
271
  waitMs = 60_000, pollMs = 250, staleMs = 600_000, claimStaleMs = 30_000,
272
272
  now = Date.now, isAlive = defaultIsAlive, hostname = os.hostname(),
273
- log = (line: string) => process.stderr.write(`${line}\n`), fsImpl = fs, sleep = atomicsSleep,
274
- }: any = {}): any {
273
+ log = (line ) => process.stderr.write(`${line}\n`), fsImpl = fs, sleep = atomicsSleep,
274
+ } = {}) {
275
275
  const root = path.resolve(scopeRoot);
276
276
  const existing = held.get(root);
277
277
  if (existing) {
@@ -283,7 +283,7 @@ function acquireRunLock({ scopeRoot, scope, command }: { scopeRoot: string, scop
283
283
  const stateDir = path.dirname(lockPath);
284
284
  const token = crypto.randomBytes(16).toString('hex');
285
285
  const where = { scope, scopeRoot: root, lockPath };
286
- const fail = (code: any) => new RunLockError({ ...where, code });
286
+ const fail = (code ) => new RunLockError({ ...where, code });
287
287
 
288
288
  const tempPath = path.join(stateDir, `.${LOCK_FILE}.${token}.tmp`);
289
289
  const record = {
@@ -292,20 +292,20 @@ function acquireRunLock({ scopeRoot, scope, command }: { scopeRoot: string, scop
292
292
  };
293
293
  // A first-ever run that gives up removes the state directory it created. Doing so between this
294
294
  // run's mkdir and its temp write surfaces here as ENOENT, so both steps are tried once more.
295
- let firstCreated: any;
295
+ let firstCreated ;
296
296
  for (let attempt = 0; ; attempt += 1) {
297
- try { firstCreated = fsImpl.mkdirSync(stateDir, { recursive: true }); } catch (err: any) { throw fail(err.code); }
297
+ try { firstCreated = fsImpl.mkdirSync(stateDir, { recursive: true }); } catch (err ) { throw fail(err.code); }
298
298
  try {
299
299
  fsImpl.writeFileSync(tempPath, `${JSON.stringify(record)}\n`, { flag: 'wx' });
300
300
  break;
301
- } catch (err: any) {
301
+ } catch (err ) {
302
302
  if (err.code === 'ENOENT' && attempt === 0) continue;
303
303
  unlinkQuietly(fsImpl, tempPath);
304
304
  removeCreatedDirs(fsImpl, stateDir, firstCreated);
305
305
  throw fail(err.code);
306
306
  }
307
307
  }
308
- const giveUp = (error: any) => {
308
+ const giveUp = (error ) => {
309
309
  unlinkQuietly(fsImpl, tempPath);
310
310
  removeCreatedDirs(fsImpl, stateDir, firstCreated);
311
311
  return error;
@@ -314,16 +314,16 @@ function acquireRunLock({ scopeRoot, scope, command }: { scopeRoot: string, scop
314
314
  const judge = { token, hostname, isAlive, now, staleMs, claimStaleMs };
315
315
  sweepOrphanTemps(fsImpl, stateDir, judge);
316
316
  const start = now();
317
- const cleared: any[] = [];
318
- let lastHolder: any = null;
317
+ const cleared = [];
318
+ let lastHolder = null;
319
319
  let announced = false;
320
320
  while (now() - start < waitMs) {
321
321
  try {
322
322
  fsImpl.linkSync(tempPath, lockPath);
323
- } catch (err: any) {
323
+ } catch (err ) {
324
324
  if (err.code !== 'EEXIST') throw giveUp(fail(err.code));
325
325
  let found;
326
- try { found = readLockFile(fsImpl, lockPath); } catch (readErr: any) { throw giveUp(fail(readErr.code)); }
326
+ try { found = readLockFile(fsImpl, lockPath); } catch (readErr ) { throw giveUp(fail(readErr.code)); }
327
327
  if (!found) continue;
328
328
  lastHolder = found.record;
329
329
  const reason = staleReason(found, judge);
@@ -346,8 +346,8 @@ function acquireRunLock({ scopeRoot, scope, command }: { scopeRoot: string, scop
346
346
  throw giveUp(new RunLockTimeoutError({ ...where, holder: lastHolder, waitedMs: now() - start }));
347
347
  }
348
348
 
349
- function holdHandle({ fsImpl, root, stateDir, lockPath, token, hostname, firstCreated, where, now, waitedMs, cleared }: any): any {
350
- const entry: { count: number, handle: any } = { count: 1, handle: null };
349
+ function holdHandle({ fsImpl, root, stateDir, lockPath, token, hostname, firstCreated, where, now, waitedMs, cleared } ) {
350
+ const entry = { count: 1, handle: null };
351
351
  let released = false;
352
352
 
353
353
  const releaseNow = () => {
@@ -1,39 +0,0 @@
1
- {
2
- "description": "DoFlow lifecycle hooks for Google Antigravity (IDE & CLI). Uses stdin/stdout JSON protocol for real-time gating.",
3
- "hooks": {
4
- "SessionStart": [
5
- {
6
- "type": "command",
7
- "command": "bash \"$DOFLOW_PROJECT_DIR/.gemini/hooks/session-start.sh\""
8
- }
9
- ],
10
- "PreToolUse": [
11
- {
12
- "matcher": "^(run_command|replace_file_content|write_to_file|multi_replace_file_content)$",
13
- "hooks": [
14
- {
15
- "type": "command",
16
- "command": "node \"$DOFLOW_PROJECT_DIR/.doflow/scripts/stream-hook-runner.js\""
17
- }
18
- ]
19
- }
20
- ],
21
- "PostToolUse": [
22
- {
23
- "matcher": "^(replace_file_content|write_to_file|multi_replace_file_content)$",
24
- "hooks": [
25
- {
26
- "type": "command",
27
- "command": "bash \"$DOFLOW_PROJECT_DIR/.gemini/hooks/post-edit-lint.sh\""
28
- }
29
- ]
30
- }
31
- ],
32
- "Stop": [
33
- {
34
- "type": "command",
35
- "command": "bash \"$DOFLOW_PROJECT_DIR/.gemini/hooks/stop-check.sh\""
36
- }
37
- ]
38
- }
39
- }
@@ -1,19 +0,0 @@
1
- 'use strict';
2
-
3
- /**
4
- * Shared toolCall.args field-name lookup for the toolCall/args envelope adapters
5
- * (antigravity.js, gemini.js's fallback path) both read when mapping to canonical
6
- * file_path/command. Extracted because both adapters carried an identical copy.
7
- */
8
-
9
- const FILE_PATH_ARG_FIELDS = ['AbsolutePath', 'TargetFile', 'Path', 'file_path', 'path'];
10
- const COMMAND_ARG_FIELDS = ['CommandLine', 'command'];
11
-
12
- function firstArgField(args, fields) {
13
- for (const field of fields) {
14
- if (args && args[field]) return args[field];
15
- }
16
- return '';
17
- }
18
-
19
- module.exports = { FILE_PATH_ARG_FIELDS, COMMAND_ARG_FIELDS, firstArgField };
@@ -1,114 +0,0 @@
1
- 'use strict';
2
-
3
- /**
4
- * Gemini CLI payload/decision adapter for the Cross-Harness Hook Runner (design.md C2's
5
- * Payload Adapter / Decision Adapter seam, D2).
6
- *
7
- * Gemini's own native contract — evidenced by core/harnesses/gemini/hooks/*.sh and
8
- * core/harnesses/gemini/hooks/hooks.json, all currently invoked directly by bash rather than
9
- * through this runner — already speaks field names close to Claude/Codex/Kiro's, NOT
10
- * Antigravity's toolCall/args envelope:
11
- *
12
- * SessionStart : stdin { session_id, cwd } (session-start.sh)
13
- * BeforeTool (~PreToolUse): stdin { tool_name, tool_input: { file_path, command } }
14
- * stdout { decision: "allow"|"deny", reason } — TOP-LEVEL, not
15
- * nested under hookSpecificOutput.permissionDecision like
16
- * Claude/Codex (confirmed in gemini/hooks/pre-bash-guard.sh's header).
17
- * AfterTool (~PostToolUse): stdin { tool_name, tool_input: { file_path }, session_id }
18
- * (post-edit-lint.sh) — stdout {} (ack; no Phase A policy owns this
19
- * event, post-edit-lint.sh's collector role is out of FR-001's scope)
20
- * Stop : NOT a documented Gemini lifecycle event — gemini/hooks/
21
- * post-edit-lint.sh's own comment states "Gemini has no
22
- * Stop-equivalent event," and no stop-check.sh ships under
23
- * gemini/hooks/ today. Handled defensively below (same field-name
24
- * union stop-check.sh itself accepts) in case a future Gemini
25
- * version adds one, or in case core/harnesses/shared/hooks/hooks.json's
26
- * existing (currently dangling) Stop entry is corrected to a real target.
27
- *
28
- * NFR-002 note: core/harnesses/shared/hooks/hooks.json has historically routed PreToolUse through
29
- * this runner using Antigravity's { toolCall: { name, args } } envelope — inherited from this
30
- * runner's original Antigravity-only design (see the runner's own prior header comment), not
31
- * verified against Gemini's own documented schema above. toCanonical() below reads the
32
- * tool_name/tool_input shape first (Gemini's own evidenced contract) and falls back to the
33
- * toolCall envelope only if that shape isn't present, so this adapter is correct once that
34
- * wiring is corrected without silently breaking before it is.
35
- */
36
-
37
- const { FILE_PATH_ARG_FIELDS, COMMAND_ARG_FIELDS, firstArgField } = require('./arg-fields');
38
-
39
- function toCanonical(event, payload) {
40
- const safePayload = payload && typeof payload === 'object' ? payload : {};
41
-
42
- switch (event) {
43
- case 'SessionStart':
44
- return { session_id: safePayload.session_id || '', cwd: safePayload.cwd || '' };
45
-
46
- case 'PreToolUse': {
47
- if (safePayload.tool_name !== undefined || safePayload.tool_input !== undefined) {
48
- const toolInput = safePayload.tool_input || {};
49
- return {
50
- tool_name: safePayload.tool_name || '',
51
- tool_input: {
52
- file_path: toolInput.file_path || '',
53
- command: toolInput.command || '',
54
- },
55
- };
56
- }
57
- // Defensive fallback: Antigravity-shaped envelope (see header note).
58
- const toolCall = safePayload.toolCall || {};
59
- const args = toolCall.args || {};
60
- return {
61
- tool_name: toolCall.name || '',
62
- tool_input: {
63
- file_path: firstArgField(args, FILE_PATH_ARG_FIELDS),
64
- command: firstArgField(args, COMMAND_ARG_FIELDS),
65
- },
66
- };
67
- }
68
-
69
- case 'PostToolUse':
70
- return {
71
- tool_name: safePayload.tool_name || '',
72
- session_id: safePayload.session_id || '',
73
- tool_input: { file_path: (safePayload.tool_input && safePayload.tool_input.file_path) || '' },
74
- };
75
-
76
- case 'Stop':
77
- return {
78
- session_id: safePayload.session_id || '',
79
- transcript_path: safePayload.transcript_path || safePayload.transcriptPath || '',
80
- };
81
-
82
- default:
83
- return safePayload;
84
- }
85
- }
86
-
87
- function toNative(event, decision) {
88
- const safeDecision = decision || { decision: 'allow' };
89
-
90
- switch (event) {
91
- case 'PreToolUse':
92
- if (safeDecision.decision === 'deny') {
93
- return { decision: 'deny', reason: safeDecision.reason };
94
- }
95
- return { decision: 'allow' };
96
-
97
- case 'PostToolUse':
98
- return {};
99
-
100
- case 'Stop':
101
- if (safeDecision.decision === 'deny') {
102
- return { decision: 'deny', reason: safeDecision.reason };
103
- }
104
- return { decision: 'allow' };
105
-
106
- case 'SessionStart':
107
- return {};
108
-
109
- default:
110
- return { decision: 'allow' };
111
- }
112
- }
113
-
114
- module.exports = { toCanonical, toNative };
@@ -1,47 +0,0 @@
1
- {
2
- "description": "DoFlow shared lifecycle hooks schema for Antigravity, Gemini, and Claude.",
3
- "hooks": {
4
- "SessionStart": [
5
- {
6
- "hooks": [
7
- {
8
- "type": "command",
9
- "command": "bash \"$DOFLOW_PROJECT_DIR/.gemini/hooks/session-start.sh\""
10
- }
11
- ]
12
- }
13
- ],
14
- "PreToolUse": [
15
- {
16
- "matcher": "^(run_command|run_shell_command|replace_file_content|write_to_file|multi_replace_file_content|edit_file|Edit|Write)$",
17
- "hooks": [
18
- {
19
- "type": "command",
20
- "command": "node \"$DOFLOW_PROJECT_DIR/.doflow/scripts/stream-hook-runner.js\""
21
- }
22
- ]
23
- }
24
- ],
25
- "PostToolUse": [
26
- {
27
- "matcher": "^(replace_file_content|write_to_file|multi_replace_file_content|edit_file|Edit|Write)$",
28
- "hooks": [
29
- {
30
- "type": "command",
31
- "command": "bash \"$DOFLOW_PROJECT_DIR/.gemini/hooks/post-edit-lint.sh\""
32
- }
33
- ]
34
- }
35
- ],
36
- "Stop": [
37
- {
38
- "hooks": [
39
- {
40
- "type": "command",
41
- "command": "bash \"$DOFLOW_PROJECT_DIR/.gemini/hooks/stop-check.sh\""
42
- }
43
- ]
44
- }
45
- ]
46
- }
47
- }