fixo-cli 1.0.0

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 (303) hide show
  1. package/LICENSE +201 -0
  2. package/README.md +530 -0
  3. package/dist/agent/agent-client.d.ts +108 -0
  4. package/dist/agent/agent-client.d.ts.map +1 -0
  5. package/dist/agent/agent-client.js +1247 -0
  6. package/dist/agent/agent-client.js.map +1 -0
  7. package/dist/agent/agent-pool.d.ts +20 -0
  8. package/dist/agent/agent-pool.d.ts.map +1 -0
  9. package/dist/agent/agent-pool.js +217 -0
  10. package/dist/agent/agent-pool.js.map +1 -0
  11. package/dist/agent/background-awareness.d.ts +55 -0
  12. package/dist/agent/background-awareness.d.ts.map +1 -0
  13. package/dist/agent/background-awareness.js +104 -0
  14. package/dist/agent/background-awareness.js.map +1 -0
  15. package/dist/agent/command-parser.d.ts +33 -0
  16. package/dist/agent/command-parser.d.ts.map +1 -0
  17. package/dist/agent/command-parser.js +120 -0
  18. package/dist/agent/command-parser.js.map +1 -0
  19. package/dist/agent/context-budget.d.ts +91 -0
  20. package/dist/agent/context-budget.d.ts.map +1 -0
  21. package/dist/agent/context-budget.js +219 -0
  22. package/dist/agent/context-budget.js.map +1 -0
  23. package/dist/agent/conversation.d.ts +190 -0
  24. package/dist/agent/conversation.d.ts.map +1 -0
  25. package/dist/agent/conversation.js +547 -0
  26. package/dist/agent/conversation.js.map +1 -0
  27. package/dist/agent/hooks.d.ts +72 -0
  28. package/dist/agent/hooks.d.ts.map +1 -0
  29. package/dist/agent/hooks.js +214 -0
  30. package/dist/agent/hooks.js.map +1 -0
  31. package/dist/agent/mcp-bridge.d.ts +13 -0
  32. package/dist/agent/mcp-bridge.d.ts.map +1 -0
  33. package/dist/agent/mcp-bridge.js +86 -0
  34. package/dist/agent/mcp-bridge.js.map +1 -0
  35. package/dist/agent/mcp-client.d.ts +24 -0
  36. package/dist/agent/mcp-client.d.ts.map +1 -0
  37. package/dist/agent/mcp-client.js +146 -0
  38. package/dist/agent/mcp-client.js.map +1 -0
  39. package/dist/agent/mcp-manager.d.ts +13 -0
  40. package/dist/agent/mcp-manager.d.ts.map +1 -0
  41. package/dist/agent/mcp-manager.js +84 -0
  42. package/dist/agent/mcp-manager.js.map +1 -0
  43. package/dist/agent/mcp-registry.d.ts +45 -0
  44. package/dist/agent/mcp-registry.d.ts.map +1 -0
  45. package/dist/agent/mcp-registry.js +98 -0
  46. package/dist/agent/mcp-registry.js.map +1 -0
  47. package/dist/agent/orchestrator.d.ts +14 -0
  48. package/dist/agent/orchestrator.d.ts.map +1 -0
  49. package/dist/agent/orchestrator.js +118 -0
  50. package/dist/agent/orchestrator.js.map +1 -0
  51. package/dist/agent/parser-adapter.d.ts +120 -0
  52. package/dist/agent/parser-adapter.d.ts.map +1 -0
  53. package/dist/agent/parser-adapter.js +265 -0
  54. package/dist/agent/parser-adapter.js.map +1 -0
  55. package/dist/agent/parsers/imports.d.ts +11 -0
  56. package/dist/agent/parsers/imports.d.ts.map +1 -0
  57. package/dist/agent/parsers/imports.js +94 -0
  58. package/dist/agent/parsers/imports.js.map +1 -0
  59. package/dist/agent/parsers/shell.d.ts +23 -0
  60. package/dist/agent/parsers/shell.d.ts.map +1 -0
  61. package/dist/agent/parsers/shell.js +200 -0
  62. package/dist/agent/parsers/shell.js.map +1 -0
  63. package/dist/agent/parsers/symbols.d.ts +17 -0
  64. package/dist/agent/parsers/symbols.d.ts.map +1 -0
  65. package/dist/agent/parsers/symbols.js +103 -0
  66. package/dist/agent/parsers/symbols.js.map +1 -0
  67. package/dist/agent/permissions.d.ts +65 -0
  68. package/dist/agent/permissions.d.ts.map +1 -0
  69. package/dist/agent/permissions.js +219 -0
  70. package/dist/agent/permissions.js.map +1 -0
  71. package/dist/agent/predictive-gate.d.ts +69 -0
  72. package/dist/agent/predictive-gate.d.ts.map +1 -0
  73. package/dist/agent/predictive-gate.js +128 -0
  74. package/dist/agent/predictive-gate.js.map +1 -0
  75. package/dist/agent/provider-cooldown.d.ts +144 -0
  76. package/dist/agent/provider-cooldown.d.ts.map +1 -0
  77. package/dist/agent/provider-cooldown.js +300 -0
  78. package/dist/agent/provider-cooldown.js.map +1 -0
  79. package/dist/agent/providers-manager.d.ts +109 -0
  80. package/dist/agent/providers-manager.d.ts.map +1 -0
  81. package/dist/agent/providers-manager.js +464 -0
  82. package/dist/agent/providers-manager.js.map +1 -0
  83. package/dist/agent/repo-map.d.ts +6 -0
  84. package/dist/agent/repo-map.d.ts.map +1 -0
  85. package/dist/agent/repo-map.js +221 -0
  86. package/dist/agent/repo-map.js.map +1 -0
  87. package/dist/agent/retry.d.ts +103 -0
  88. package/dist/agent/retry.d.ts.map +1 -0
  89. package/dist/agent/retry.js +276 -0
  90. package/dist/agent/retry.js.map +1 -0
  91. package/dist/agent/search/index.d.ts +61 -0
  92. package/dist/agent/search/index.d.ts.map +1 -0
  93. package/dist/agent/search/index.js +314 -0
  94. package/dist/agent/search/index.js.map +1 -0
  95. package/dist/agent/single-agent.d.ts +76 -0
  96. package/dist/agent/single-agent.d.ts.map +1 -0
  97. package/dist/agent/single-agent.js +697 -0
  98. package/dist/agent/single-agent.js.map +1 -0
  99. package/dist/agent/skills.d.ts +22 -0
  100. package/dist/agent/skills.d.ts.map +1 -0
  101. package/dist/agent/skills.js +139 -0
  102. package/dist/agent/skills.js.map +1 -0
  103. package/dist/agent/stream-glue.d.ts +85 -0
  104. package/dist/agent/stream-glue.d.ts.map +1 -0
  105. package/dist/agent/stream-glue.js +120 -0
  106. package/dist/agent/stream-glue.js.map +1 -0
  107. package/dist/agent/subagent.d.ts +72 -0
  108. package/dist/agent/subagent.d.ts.map +1 -0
  109. package/dist/agent/subagent.js +193 -0
  110. package/dist/agent/subagent.js.map +1 -0
  111. package/dist/agent/telemetry.d.ts +192 -0
  112. package/dist/agent/telemetry.d.ts.map +1 -0
  113. package/dist/agent/telemetry.js +400 -0
  114. package/dist/agent/telemetry.js.map +1 -0
  115. package/dist/agent/tokenizer.d.ts +42 -0
  116. package/dist/agent/tokenizer.d.ts.map +1 -0
  117. package/dist/agent/tokenizer.js +107 -0
  118. package/dist/agent/tokenizer.js.map +1 -0
  119. package/dist/agent/tool-executor.d.ts +289 -0
  120. package/dist/agent/tool-executor.d.ts.map +1 -0
  121. package/dist/agent/tool-executor.js +2519 -0
  122. package/dist/agent/tool-executor.js.map +1 -0
  123. package/dist/agent/web-impl.d.ts +2 -0
  124. package/dist/agent/web-impl.d.ts.map +1 -0
  125. package/dist/agent/web-impl.js +34 -0
  126. package/dist/agent/web-impl.js.map +1 -0
  127. package/dist/agent/web.d.ts +8 -0
  128. package/dist/agent/web.d.ts.map +1 -0
  129. package/dist/agent/web.js +8 -0
  130. package/dist/agent/web.js.map +1 -0
  131. package/dist/agent/worker-agent.d.ts +27 -0
  132. package/dist/agent/worker-agent.d.ts.map +1 -0
  133. package/dist/agent/worker-agent.js +503 -0
  134. package/dist/agent/worker-agent.js.map +1 -0
  135. package/dist/config.d.ts +162 -0
  136. package/dist/config.d.ts.map +1 -0
  137. package/dist/config.js +138 -0
  138. package/dist/config.js.map +1 -0
  139. package/dist/context/fixo-md-watcher.d.ts +42 -0
  140. package/dist/context/fixo-md-watcher.d.ts.map +1 -0
  141. package/dist/context/fixo-md-watcher.js +126 -0
  142. package/dist/context/fixo-md-watcher.js.map +1 -0
  143. package/dist/context/fixo-md.d.ts +50 -0
  144. package/dist/context/fixo-md.d.ts.map +1 -0
  145. package/dist/context/fixo-md.js +118 -0
  146. package/dist/context/fixo-md.js.map +1 -0
  147. package/dist/context/todo.d.ts +65 -0
  148. package/dist/context/todo.d.ts.map +1 -0
  149. package/dist/context/todo.js +194 -0
  150. package/dist/context/todo.js.map +1 -0
  151. package/dist/git/git-manager.d.ts +33 -0
  152. package/dist/git/git-manager.d.ts.map +1 -0
  153. package/dist/git/git-manager.js +293 -0
  154. package/dist/git/git-manager.js.map +1 -0
  155. package/dist/git/git-ops.d.ts +10 -0
  156. package/dist/git/git-ops.d.ts.map +1 -0
  157. package/dist/git/git-ops.js +131 -0
  158. package/dist/git/git-ops.js.map +1 -0
  159. package/dist/index.d.ts +3 -0
  160. package/dist/index.d.ts.map +1 -0
  161. package/dist/index.js +352 -0
  162. package/dist/index.js.map +1 -0
  163. package/dist/indexer.d.ts +30 -0
  164. package/dist/indexer.d.ts.map +1 -0
  165. package/dist/indexer.js +273 -0
  166. package/dist/indexer.js.map +1 -0
  167. package/dist/lsp/lsp-client.d.ts +24 -0
  168. package/dist/lsp/lsp-client.d.ts.map +1 -0
  169. package/dist/lsp/lsp-client.js +205 -0
  170. package/dist/lsp/lsp-client.js.map +1 -0
  171. package/dist/lsp/lsp-manager.d.ts +17 -0
  172. package/dist/lsp/lsp-manager.d.ts.map +1 -0
  173. package/dist/lsp/lsp-manager.js +154 -0
  174. package/dist/lsp/lsp-manager.js.map +1 -0
  175. package/dist/lsp/lsp-pre-save.d.ts +137 -0
  176. package/dist/lsp/lsp-pre-save.d.ts.map +1 -0
  177. package/dist/lsp/lsp-pre-save.js +245 -0
  178. package/dist/lsp/lsp-pre-save.js.map +1 -0
  179. package/dist/lsp/syntax-fallback.d.ts +83 -0
  180. package/dist/lsp/syntax-fallback.d.ts.map +1 -0
  181. package/dist/lsp/syntax-fallback.js +275 -0
  182. package/dist/lsp/syntax-fallback.js.map +1 -0
  183. package/dist/model-outcomes.d.ts +12 -0
  184. package/dist/model-outcomes.d.ts.map +1 -0
  185. package/dist/model-outcomes.js +46 -0
  186. package/dist/model-outcomes.js.map +1 -0
  187. package/dist/planner.d.ts +32 -0
  188. package/dist/planner.d.ts.map +1 -0
  189. package/dist/planner.js +163 -0
  190. package/dist/planner.js.map +1 -0
  191. package/dist/project-memory.d.ts +29 -0
  192. package/dist/project-memory.d.ts.map +1 -0
  193. package/dist/project-memory.js +349 -0
  194. package/dist/project-memory.js.map +1 -0
  195. package/dist/review.d.ts +2 -0
  196. package/dist/review.d.ts.map +1 -0
  197. package/dist/review.js +61 -0
  198. package/dist/review.js.map +1 -0
  199. package/dist/runtime/background-jobs.d.ts +97 -0
  200. package/dist/runtime/background-jobs.d.ts.map +1 -0
  201. package/dist/runtime/background-jobs.js +331 -0
  202. package/dist/runtime/background-jobs.js.map +1 -0
  203. package/dist/runtime/credential-vault.d.ts +124 -0
  204. package/dist/runtime/credential-vault.d.ts.map +1 -0
  205. package/dist/runtime/credential-vault.js +184 -0
  206. package/dist/runtime/credential-vault.js.map +1 -0
  207. package/dist/runtime/loop-trap.d.ts +197 -0
  208. package/dist/runtime/loop-trap.d.ts.map +1 -0
  209. package/dist/runtime/loop-trap.js +420 -0
  210. package/dist/runtime/loop-trap.js.map +1 -0
  211. package/dist/runtime/policy.d.ts +15 -0
  212. package/dist/runtime/policy.d.ts.map +1 -0
  213. package/dist/runtime/policy.js +60 -0
  214. package/dist/runtime/policy.js.map +1 -0
  215. package/dist/runtime/redaction.d.ts +66 -0
  216. package/dist/runtime/redaction.d.ts.map +1 -0
  217. package/dist/runtime/redaction.js +155 -0
  218. package/dist/runtime/redaction.js.map +1 -0
  219. package/dist/runtime/session-snapshots.d.ts +76 -0
  220. package/dist/runtime/session-snapshots.d.ts.map +1 -0
  221. package/dist/runtime/session-snapshots.js +166 -0
  222. package/dist/runtime/session-snapshots.js.map +1 -0
  223. package/dist/runtime/staging.d.ts +205 -0
  224. package/dist/runtime/staging.d.ts.map +1 -0
  225. package/dist/runtime/staging.js +526 -0
  226. package/dist/runtime/staging.js.map +1 -0
  227. package/dist/runtime/task-session.d.ts +95 -0
  228. package/dist/runtime/task-session.d.ts.map +1 -0
  229. package/dist/runtime/task-session.js +263 -0
  230. package/dist/runtime/task-session.js.map +1 -0
  231. package/dist/runtime/worktree.d.ts +55 -0
  232. package/dist/runtime/worktree.d.ts.map +1 -0
  233. package/dist/runtime/worktree.js +175 -0
  234. package/dist/runtime/worktree.js.map +1 -0
  235. package/dist/setup-wizard.d.ts +8 -0
  236. package/dist/setup-wizard.d.ts.map +1 -0
  237. package/dist/setup-wizard.js +73 -0
  238. package/dist/setup-wizard.js.map +1 -0
  239. package/dist/shared/content.d.ts +43 -0
  240. package/dist/shared/content.d.ts.map +1 -0
  241. package/dist/shared/content.js +61 -0
  242. package/dist/shared/content.js.map +1 -0
  243. package/dist/shared/types.d.ts +217 -0
  244. package/dist/shared/types.d.ts.map +1 -0
  245. package/dist/shared/types.js +3 -0
  246. package/dist/shared/types.js.map +1 -0
  247. package/dist/test-runner.d.ts +5 -0
  248. package/dist/test-runner.d.ts.map +1 -0
  249. package/dist/test-runner.js +42 -0
  250. package/dist/test-runner.js.map +1 -0
  251. package/dist/types.d.ts +85 -0
  252. package/dist/types.d.ts.map +1 -0
  253. package/dist/types.js +2 -0
  254. package/dist/types.js.map +1 -0
  255. package/dist/ui/ascii.d.ts +23 -0
  256. package/dist/ui/ascii.d.ts.map +1 -0
  257. package/dist/ui/ascii.js +45 -0
  258. package/dist/ui/ascii.js.map +1 -0
  259. package/dist/ui/colors.d.ts +111 -0
  260. package/dist/ui/colors.d.ts.map +1 -0
  261. package/dist/ui/colors.js +166 -0
  262. package/dist/ui/colors.js.map +1 -0
  263. package/dist/ui/image-attach.d.ts +27 -0
  264. package/dist/ui/image-attach.d.ts.map +1 -0
  265. package/dist/ui/image-attach.js +100 -0
  266. package/dist/ui/image-attach.js.map +1 -0
  267. package/dist/ui/index.d.ts +18 -0
  268. package/dist/ui/index.d.ts.map +1 -0
  269. package/dist/ui/index.js +18 -0
  270. package/dist/ui/index.js.map +1 -0
  271. package/dist/ui/markdown-stream.d.ts +91 -0
  272. package/dist/ui/markdown-stream.d.ts.map +1 -0
  273. package/dist/ui/markdown-stream.js +524 -0
  274. package/dist/ui/markdown-stream.js.map +1 -0
  275. package/dist/ui/plan-renderer.d.ts +36 -0
  276. package/dist/ui/plan-renderer.d.ts.map +1 -0
  277. package/dist/ui/plan-renderer.js +79 -0
  278. package/dist/ui/plan-renderer.js.map +1 -0
  279. package/dist/ui/prompt.d.ts +11 -0
  280. package/dist/ui/prompt.d.ts.map +1 -0
  281. package/dist/ui/prompt.js +1960 -0
  282. package/dist/ui/prompt.js.map +1 -0
  283. package/dist/ui/render-primitives.d.ts +117 -0
  284. package/dist/ui/render-primitives.d.ts.map +1 -0
  285. package/dist/ui/render-primitives.js +322 -0
  286. package/dist/ui/render-primitives.js.map +1 -0
  287. package/dist/ui/render.d.ts +133 -0
  288. package/dist/ui/render.d.ts.map +1 -0
  289. package/dist/ui/render.js +547 -0
  290. package/dist/ui/render.js.map +1 -0
  291. package/dist/ui/session-header.d.ts +30 -0
  292. package/dist/ui/session-header.d.ts.map +1 -0
  293. package/dist/ui/session-header.js +74 -0
  294. package/dist/ui/session-header.js.map +1 -0
  295. package/dist/workspace-guard.d.ts +68 -0
  296. package/dist/workspace-guard.d.ts.map +1 -0
  297. package/dist/workspace-guard.js +168 -0
  298. package/dist/workspace-guard.js.map +1 -0
  299. package/dist/workspace-lock.d.ts +27 -0
  300. package/dist/workspace-lock.d.ts.map +1 -0
  301. package/dist/workspace-lock.js +95 -0
  302. package/dist/workspace-lock.js.map +1 -0
  303. package/package.json +63 -0
@@ -0,0 +1,526 @@
1
+ /**
2
+ * Atomic Workspace Shadow Staging — Pillar 2 of the Phase 2 safety
3
+ * refactor. The problem: a direct `fs.writeFileSync` to a user's
4
+ * source file is a non-atomic, non-rollbackable operation. If the
5
+ * process is killed mid-write, the user is left with a partially
6
+ * truncated file. If a downstream validation step fails, the
7
+ * user is left with a corrupted file. Both outcomes are
8
+ * unacceptable for a tool that markets itself as "enterprise
9
+ * safe".
10
+ *
11
+ * The fix: route every file write through a `.fixo/staging/`
12
+ * shadow directory, validate it (Pillar 3 LSP gate will plug in
13
+ * here), and only then perform an atomic `fs.renameSync` swap.
14
+ * If anything goes wrong, restore the original from a sibling
15
+ * `.pending.bak` file and the user is none the wiser.
16
+ *
17
+ * Layout under `cwd`:
18
+ *
19
+ * .fixo/staging/<run-id>/
20
+ * <sha256(targetPath)>.pending # staged content
21
+ * <sha256(targetPath)>.meta.json # { targetPath, mode, createdAt }
22
+ *
23
+ * <targetPath>.pending.bak # temporary backup, only
24
+ * # present during commit()
25
+ *
26
+ * The staging directory is created with mode `0o700`. Pending
27
+ * files and their metadata are written with mode `0o600`.
28
+ *
29
+ * The manager is synchronous (writes are small, no streaming),
30
+ * safe to construct at the start of a run, and thread-agnostic —
31
+ * the run-id is the only thing that disambiguates concurrent
32
+ * runs against the same workspace.
33
+ */
34
+ import crypto from 'node:crypto';
35
+ import fs from 'node:fs';
36
+ import path from 'node:path';
37
+ import { WorkspaceGuard } from '../workspace-guard.js';
38
+ // ---------------------------------------------------------------------------
39
+ // Errors
40
+ // ---------------------------------------------------------------------------
41
+ /** Thrown when a requested staged write does not exist. */
42
+ export class StagedWriteNotFoundError extends Error {
43
+ id;
44
+ constructor(id) {
45
+ super(`No staged write with id ${id}`);
46
+ this.name = 'StagedWriteNotFoundError';
47
+ this.id = id;
48
+ }
49
+ }
50
+ /** Thrown when commit() rolls back due to a pre-commit hook failure. */
51
+ export class PreCommitHookRejectedError extends Error {
52
+ id;
53
+ cause;
54
+ constructor(id, cause) {
55
+ super(`Pre-commit hook rejected staged write ${id}: ${String(cause)}`);
56
+ this.name = 'PreCommitHookRejectedError';
57
+ this.id = id;
58
+ this.cause = cause;
59
+ }
60
+ }
61
+ /** Thrown when a target path escapes the workspace root. */
62
+ export class StagingPathEscapeError extends Error {
63
+ attempted;
64
+ constructor(attempted) {
65
+ super(`Staging refused: path escapes workspace root: ${attempted}`);
66
+ this.name = 'StagingPathEscapeError';
67
+ this.attempted = attempted;
68
+ }
69
+ }
70
+ // ---------------------------------------------------------------------------
71
+ // Constants
72
+ // ---------------------------------------------------------------------------
73
+ const DEFAULT_TTL_MS = 24 * 60 * 60 * 1000; // 24h
74
+ const STAGING_DIR_NAME = 'staging';
75
+ const META_SUFFIX = '.meta.json';
76
+ const PENDING_SUFFIX = '.pending';
77
+ const BACKUP_SUFFIX = '.pending.bak';
78
+ // ---------------------------------------------------------------------------
79
+ // Helpers
80
+ // ---------------------------------------------------------------------------
81
+ const sha256 = (input) => crypto.createHash('sha256').update(input, 'utf-8').digest('hex');
82
+ /** Try to chmod; ignore on platforms that don't support it. */
83
+ const chmodSafe = (filePath, mode) => {
84
+ try {
85
+ fs.chmodSync(filePath, mode);
86
+ }
87
+ catch {
88
+ // ignore
89
+ }
90
+ };
91
+ /** Best-effort deletion that does not throw. */
92
+ const rmSafe = (target) => {
93
+ try {
94
+ fs.unlinkSync(target);
95
+ }
96
+ catch {
97
+ // ignore
98
+ }
99
+ };
100
+ // ---------------------------------------------------------------------------
101
+ // AtomicStagingManager
102
+ // ---------------------------------------------------------------------------
103
+ export class AtomicStagingManager {
104
+ cwd;
105
+ runId;
106
+ options;
107
+ /** Absolute path of the staging directory for this run. */
108
+ stagingDir;
109
+ constructor(cwd, runId, options = {}) {
110
+ if (!runId || !/^[A-Za-z0-9._-]+$/.test(runId)) {
111
+ throw new Error(`runId must match [A-Za-z0-9._-]+ (got: ${JSON.stringify(runId)})`);
112
+ }
113
+ this.cwd = path.resolve(cwd);
114
+ this.runId = runId;
115
+ this.options = {
116
+ ttlMs: options.ttlMs ?? DEFAULT_TTL_MS,
117
+ enabled: options.enabled ?? true,
118
+ preCommitHook: options.preCommitHook,
119
+ syntaxHealthCheck: options.syntaxHealthCheck,
120
+ };
121
+ this.stagingDir = path.join(this.cwd, '.fixo', STAGING_DIR_NAME, this.runId);
122
+ }
123
+ /** Ensure the staging directory exists with mode 0o700. */
124
+ ensureStagingDir() {
125
+ fs.mkdirSync(this.stagingDir, { recursive: true, mode: 0o700 });
126
+ chmodSafe(this.stagingDir, 0o700);
127
+ }
128
+ /** Reject paths that escape the workspace root. */
129
+ resolveTarget(relativeOrAbsolute) {
130
+ const guard = new WorkspaceGuard(this.cwd);
131
+ try {
132
+ return guard.resolve(relativeOrAbsolute, 'file');
133
+ }
134
+ catch {
135
+ throw new StagingPathEscapeError(relativeOrAbsolute);
136
+ }
137
+ }
138
+ /**
139
+ * Stage a file for atomic write. Writes the content to
140
+ * `<staging>/<sha256(target)>.pending` and a sidecar
141
+ * `<staging>/<sha256(target)>.meta.json` containing the target
142
+ * path, mode, and timestamp. Returns the staged write metadata.
143
+ */
144
+ stage(target, content, mode = 0o644) {
145
+ const resolved = this.resolveTarget(target);
146
+ const id = sha256(resolved);
147
+ this.ensureStagingDir();
148
+ const pendingPath = path.join(this.stagingDir, `${id}${PENDING_SUFFIX}`);
149
+ const metaPath = path.join(this.stagingDir, `${id}${META_SUFFIX}`);
150
+ // Write pending content (atomic: write to temp + rename).
151
+ const tmpPath = `${pendingPath}.tmp`;
152
+ fs.writeFileSync(tmpPath, content, { encoding: 'utf-8', mode: 0o600 });
153
+ chmodSafe(tmpPath, 0o600);
154
+ fs.renameSync(tmpPath, pendingPath);
155
+ // Write meta sidecar.
156
+ const meta = {
157
+ targetPath: resolved,
158
+ mode,
159
+ createdAt: Date.now(),
160
+ };
161
+ fs.writeFileSync(metaPath, JSON.stringify(meta), {
162
+ encoding: 'utf-8',
163
+ mode: 0o600,
164
+ });
165
+ chmodSafe(metaPath, 0o600);
166
+ return {
167
+ id,
168
+ targetPath: resolved,
169
+ pendingPath,
170
+ metaPath,
171
+ createdAt: meta.createdAt,
172
+ mode,
173
+ };
174
+ }
175
+ /** Read a staged write's content (lazy — only read on demand). */
176
+ read(id) {
177
+ const entry = this.readEntry(id);
178
+ return fs.readFileSync(entry.pendingPath, 'utf-8');
179
+ }
180
+ /** Look up a staged write by id without touching the file system further. */
181
+ readEntry(id) {
182
+ const pendingPath = path.join(this.stagingDir, `${id}${PENDING_SUFFIX}`);
183
+ const metaPath = path.join(this.stagingDir, `${id}${META_SUFFIX}`);
184
+ if (!fs.existsSync(pendingPath) || !fs.existsSync(metaPath)) {
185
+ throw new StagedWriteNotFoundError(id);
186
+ }
187
+ const raw = JSON.parse(fs.readFileSync(metaPath, 'utf-8'));
188
+ return {
189
+ id,
190
+ targetPath: raw.targetPath,
191
+ pendingPath,
192
+ metaPath,
193
+ createdAt: raw.createdAt,
194
+ mode: raw.mode,
195
+ };
196
+ }
197
+ /** List all staged writes for this run. */
198
+ list() {
199
+ if (!fs.existsSync(this.stagingDir))
200
+ return [];
201
+ const names = fs.readdirSync(this.stagingDir);
202
+ const entries = [];
203
+ for (const name of names) {
204
+ if (!name.endsWith(META_SUFFIX))
205
+ continue;
206
+ const id = name.slice(0, -META_SUFFIX.length);
207
+ try {
208
+ entries.push(this.readEntry(id));
209
+ }
210
+ catch {
211
+ // Stale meta without a pending counterpart — skip.
212
+ }
213
+ }
214
+ return entries;
215
+ }
216
+ /**
217
+ * Remove a staged write without touching the target. Used by the
218
+ * LSP pre-save gate when it rejects a write.
219
+ */
220
+ discard(id) {
221
+ const entry = this.readEntry(id);
222
+ rmSafe(entry.pendingPath);
223
+ rmSafe(entry.metaPath);
224
+ }
225
+ /**
226
+ * Commit a staged write to its target path. The flow is:
227
+ *
228
+ * 1. Run the optional pre-commit hook (Pillar 3 plugs in here).
229
+ * 2. Ensure the parent directory of the target exists.
230
+ * 3. If the target exists, rename it to `<target>.pending.bak`.
231
+ * 4. Rename the pending file to the target.
232
+ * 5. Delete the backup.
233
+ *
234
+ * If any step fails, the backup (if any) is restored to the
235
+ * target and the backup itself is removed. The pending and
236
+ * metadata files are always cleaned up on success.
237
+ */
238
+ async commit(id) {
239
+ const entry = this.readEntry(id);
240
+ const target = entry.targetPath;
241
+ const backup = `${target}${BACKUP_SUFFIX}`;
242
+ const existed = fs.existsSync(target);
243
+ // 1. Pre-commit hook (Pillar 3 plugs in here).
244
+ if (this.options.preCommitHook) {
245
+ try {
246
+ await this.options.preCommitHook(entry);
247
+ }
248
+ catch (cause) {
249
+ // Hook rejected — discard the staged write but do NOT
250
+ // touch the target.
251
+ this.discard(id);
252
+ throw new PreCommitHookRejectedError(id, cause);
253
+ }
254
+ }
255
+ // 1.5 Pillar 5 / Protection 3 — structural syntax health
256
+ // check. Runs *after* the LSP gate and *before* the rename
257
+ // swap. If the staged content is syntactically broken the
258
+ // write is rejected and discarded; the target is preserved.
259
+ if (this.options.syntaxHealthCheck) {
260
+ const content = fs.readFileSync(entry.pendingPath, 'utf-8');
261
+ try {
262
+ await this.options.syntaxHealthCheck(entry, content);
263
+ }
264
+ catch (cause) {
265
+ this.discard(id);
266
+ throw new PreCommitHookRejectedError(id, cause);
267
+ }
268
+ }
269
+ if (!this.options.enabled) {
270
+ // Dry-run mode: leave the staged write in place.
271
+ const bytes = Buffer.byteLength(fs.readFileSync(entry.pendingPath), 'utf-8');
272
+ return {
273
+ committed: false,
274
+ targetPath: target,
275
+ backupCreated: false,
276
+ bytesWritten: bytes,
277
+ committedAt: new Date().toISOString(),
278
+ };
279
+ }
280
+ // 2. Ensure parent directory exists.
281
+ const parent = path.dirname(target);
282
+ fs.mkdirSync(parent, { recursive: true });
283
+ try {
284
+ // 3. Back up the existing file (if any).
285
+ if (existed) {
286
+ // If a stale backup is present from a previous failed
287
+ // commit, clear it first.
288
+ rmSafe(backup);
289
+ fs.renameSync(target, backup);
290
+ }
291
+ // 4. Swap pending into place.
292
+ fs.renameSync(entry.pendingPath, target);
293
+ // Apply mode.
294
+ try {
295
+ fs.chmodSync(target, entry.mode);
296
+ }
297
+ catch {
298
+ // ignore
299
+ }
300
+ // 5. Clear the backup.
301
+ if (existed)
302
+ rmSafe(backup);
303
+ const bytes = Buffer.byteLength(fs.readFileSync(target, 'utf-8'), 'utf-8');
304
+ // Tidy up the meta sidecar.
305
+ rmSafe(entry.metaPath);
306
+ return {
307
+ committed: true,
308
+ targetPath: target,
309
+ backupCreated: existed,
310
+ bytesWritten: bytes,
311
+ committedAt: new Date().toISOString(),
312
+ };
313
+ }
314
+ catch (err) {
315
+ // Rollback: restore the backup, remove the .pending if any.
316
+ try {
317
+ if (existed && fs.existsSync(backup)) {
318
+ if (fs.existsSync(target))
319
+ fs.unlinkSync(target);
320
+ fs.renameSync(backup, target);
321
+ }
322
+ else if (!existed && fs.existsSync(target)) {
323
+ // We created the file but the rename to target itself
324
+ // succeeded — only reached if chmod fails. Target is
325
+ // already correct; nothing to undo.
326
+ }
327
+ }
328
+ catch {
329
+ // Last-ditch: leave the backup in place so a human can
330
+ // recover. The next GC pass will clean it up.
331
+ }
332
+ // Pending may have been consumed; if not, leave it.
333
+ throw err;
334
+ }
335
+ }
336
+ /**
337
+ * Apply a surgical in-place edit to an existing file. The new
338
+ * content is staged under the same `.fixo/staging/<runId>/<id>.pending`
339
+ * layout and the commit step mirrors `commit()`: backup the
340
+ * target, atomic rename, clear the backup, clear the meta.
341
+ *
342
+ * This is functionally `stage() + commit()` collapsed into a
343
+ * single call, but the on-disk layout, backup semantics, and
344
+ * rollback path are identical. Provided so `str_replace` (and
345
+ * future surgical-edit tools) can route their edits through the
346
+ * same atomic staging pipeline as `write_file` without touching
347
+ * the existing `stage()` / `commit()` flow.
348
+ *
349
+ * The optional `meta` argument is recorded into `.meta.json` so
350
+ * the audit trail records the originator of the edit (e.g. a
351
+ * `str_replace` tool call vs. a `subagent`). The method never
352
+ * weakens the Pillar 2 atomicity guarantee: if the rename
353
+ * swap fails, the backup is restored and the original file is
354
+ * preserved byte-for-byte.
355
+ */
356
+ async applySurgicalReplace(target, newContent, meta) {
357
+ const resolved = this.resolveTarget(target);
358
+ const id = sha256(resolved);
359
+ this.ensureStagingDir();
360
+ const pendingPath = path.join(this.stagingDir, `${id}${PENDING_SUFFIX}`);
361
+ const metaPath = path.join(this.stagingDir, `${id}${META_SUFFIX}`);
362
+ const backup = `${resolved}${BACKUP_SUFFIX}`;
363
+ const existed = fs.existsSync(resolved);
364
+ // 1. Write the new content to the .pending file (atomic via temp+rename).
365
+ const tmpPath = `${pendingPath}.tmp`;
366
+ fs.writeFileSync(tmpPath, newContent, { encoding: 'utf-8', mode: 0o600 });
367
+ chmodSafe(tmpPath, 0o600);
368
+ fs.renameSync(tmpPath, pendingPath);
369
+ // 2. Write the sidecar meta with audit trail.
370
+ const metaPayload = {
371
+ targetPath: resolved,
372
+ mode: 0o644,
373
+ createdAt: Date.now(),
374
+ reason: meta.reason,
375
+ actorId: meta.actorId,
376
+ runId: meta.runId,
377
+ };
378
+ fs.writeFileSync(metaPath, JSON.stringify(metaPayload), {
379
+ encoding: 'utf-8',
380
+ mode: 0o600,
381
+ });
382
+ chmodSafe(metaPath, 0o600);
383
+ // 3. Ensure parent dir exists.
384
+ const parent = path.dirname(resolved);
385
+ fs.mkdirSync(parent, { recursive: true });
386
+ try {
387
+ // 4. Back up the existing file (if any).
388
+ if (existed) {
389
+ // Clear any stale backup from a previous failed commit.
390
+ rmSafe(backup);
391
+ fs.renameSync(resolved, backup);
392
+ }
393
+ // 5. Atomic swap of the pending file into the target.
394
+ fs.renameSync(pendingPath, resolved);
395
+ // 6. Apply file mode (best-effort across platforms).
396
+ try {
397
+ fs.chmodSync(resolved, 0o644);
398
+ }
399
+ catch {
400
+ // ignore
401
+ }
402
+ // 7. Clear backup and meta sidecar.
403
+ if (existed)
404
+ rmSafe(backup);
405
+ rmSafe(metaPath);
406
+ const bytes = Buffer.byteLength(fs.readFileSync(resolved, 'utf-8'), 'utf-8');
407
+ return { ok: true, path: resolved, bytes };
408
+ }
409
+ catch (err) {
410
+ // Rollback: restore the backup, clean up the .pending if any.
411
+ try {
412
+ if (existed && fs.existsSync(backup)) {
413
+ if (fs.existsSync(resolved))
414
+ fs.unlinkSync(resolved);
415
+ fs.renameSync(backup, resolved);
416
+ }
417
+ else if (!existed && fs.existsSync(resolved)) {
418
+ // We created the file but the rename to target itself
419
+ // succeeded — only reached if chmod fails. Target is
420
+ // already correct; nothing to undo.
421
+ }
422
+ }
423
+ catch {
424
+ // Last-ditch: leave the backup in place so a human can
425
+ // recover. The next GC pass will clean it up.
426
+ }
427
+ // Pending may have been consumed; if not, leave it.
428
+ throw err;
429
+ }
430
+ }
431
+ /**
432
+ * Remove any staged write older than `ttlMs`. Returns the number
433
+ * of entries removed. Designed to be cheap at run start
434
+ * (typically <2ms for a few hundred entries).
435
+ */
436
+ gc(now = Date.now()) {
437
+ if (!fs.existsSync(this.stagingDir))
438
+ return 0;
439
+ const cutoff = now - this.options.ttlMs;
440
+ let removed = 0;
441
+ for (const entry of this.list()) {
442
+ if (entry.createdAt < cutoff) {
443
+ this.discard(entry.id);
444
+ removed += 1;
445
+ }
446
+ }
447
+ return removed;
448
+ }
449
+ /**
450
+ * Sweep every run-id directory under `<cwd>/.fixo/staging/`.
451
+ * Returns the total number of expired entries removed. Called
452
+ * automatically at the start of every streaming run and is also
453
+ * exposed via the `/fixo gc` slash command.
454
+ */
455
+ static garbageCollectAll(cwd, ttlMs) {
456
+ const root = path.resolve(cwd);
457
+ const stagingRoot = path.join(root, '.fixo', STAGING_DIR_NAME);
458
+ if (!fs.existsSync(stagingRoot))
459
+ return 0;
460
+ let removed = 0;
461
+ let runDirs;
462
+ try {
463
+ runDirs = fs.readdirSync(stagingRoot);
464
+ }
465
+ catch {
466
+ return 0;
467
+ }
468
+ for (const runDir of runDirs) {
469
+ const runPath = path.join(stagingRoot, runDir);
470
+ let stat;
471
+ try {
472
+ stat = fs.lstatSync(runPath);
473
+ }
474
+ catch {
475
+ continue;
476
+ }
477
+ if (!stat.isDirectory())
478
+ continue;
479
+ // Safe: runDir names are sanitised in the constructor.
480
+ const mgr = new AtomicStagingManager(root, runDir, { ttlMs });
481
+ removed += mgr.gc();
482
+ }
483
+ return removed;
484
+ }
485
+ /**
486
+ * Discard every staged write for the given (cwd, runId) pair. Used
487
+ * when an agent is force-killed (e.g. loop-trap hard-abort) so the
488
+ * workspace is left in its pre-run state. Returns the number of
489
+ * entries removed.
490
+ *
491
+ * Best-effort: a failure to remove a single entry is logged and
492
+ * swallowed so the caller never sees an exception from cleanup.
493
+ */
494
+ static rollbackAll(cwd, runId) {
495
+ const root = path.resolve(cwd);
496
+ let removed = 0;
497
+ let mgr;
498
+ try {
499
+ mgr = new AtomicStagingManager(root, runId);
500
+ }
501
+ catch {
502
+ return 0;
503
+ }
504
+ if (!fs.existsSync(mgr.stagingDir))
505
+ return 0;
506
+ const entries = mgr.list();
507
+ for (const entry of entries) {
508
+ try {
509
+ mgr.discard(entry.id);
510
+ removed += 1;
511
+ }
512
+ catch (err) {
513
+ console.error(`[AtomicStagingManager.rollbackAll] failed to discard ${entry.id}: ${err instanceof Error ? err.message : String(err)}`);
514
+ }
515
+ }
516
+ // Best-effort: remove the now-empty run directory.
517
+ try {
518
+ fs.rmSync(mgr.stagingDir, { recursive: true, force: true });
519
+ }
520
+ catch {
521
+ // ignore
522
+ }
523
+ return removed;
524
+ }
525
+ }
526
+ //# sourceMappingURL=staging.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"staging.js","sourceRoot":"","sources":["../../src/runtime/staging.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,95 @@
1
+ import { WorkspaceGuard } from '../workspace-guard.js';
2
+ import type { PolicyProfile } from './policy.js';
3
+ export interface TaskEvent {
4
+ type: string;
5
+ timestamp: string;
6
+ [key: string]: unknown;
7
+ }
8
+ export interface TaskSessionSummary {
9
+ id: string;
10
+ task: string;
11
+ model: string;
12
+ cwd: string;
13
+ startedAt: string;
14
+ endedAt?: string;
15
+ status: 'running' | 'success' | 'error';
16
+ modifiedFiles: string[];
17
+ verification: string[];
18
+ response?: string;
19
+ }
20
+ export interface ChangeRecord {
21
+ file: string;
22
+ beforeHash: string | null;
23
+ afterHash: string | null;
24
+ beforeExists: boolean;
25
+ afterExists: boolean;
26
+ beforeSnapshot?: string;
27
+ }
28
+ export declare class TaskSession {
29
+ readonly id: string;
30
+ readonly cwd: string;
31
+ readonly guard: WorkspaceGuard;
32
+ readonly policy: PolicyProfile;
33
+ readonly runDir: string;
34
+ readonly startedAt: string;
35
+ readonly readFiles: Map<string, string | null>;
36
+ readonly changedFiles: Map<string, ChangeRecord>;
37
+ /**
38
+ * Tracks which files the agent has done a *structural* pre-scan on
39
+ * (via `extract_symbols` / `extract_imports`). The map is read by
40
+ * Pillar 3 (Context-Budget Guard) to verify that a large file the
41
+ * LLM wants to read was first reduced to its declarations. The
42
+ * `noteStructuralMap` and `hasStructuralMap` helpers below are
43
+ * intentionally side-effect-free for tests.
44
+ */
45
+ readonly structuralMaps: Map<string, {
46
+ symbols: boolean;
47
+ imports: boolean;
48
+ }>;
49
+ private summary;
50
+ constructor(opts: {
51
+ cwd: string;
52
+ task: string;
53
+ model: string;
54
+ policy?: PolicyProfile;
55
+ });
56
+ record(type: string, data?: Record<string, unknown>): void;
57
+ noteRead(file: string): void;
58
+ /**
59
+ * Mark a file as having been pre-scanned structurally. The
60
+ * `flags` object records which dimensions were extracted so
61
+ * Pillar 3 can decide whether the LLM is still missing
62
+ * information when it later calls `read_file` on the same path.
63
+ */
64
+ noteStructuralMap(file: string, flags: {
65
+ symbols: boolean;
66
+ imports: boolean;
67
+ }): void;
68
+ /**
69
+ * Returns the structural pre-scan flags recorded for a file.
70
+ * Returns `null` if the file has never been pre-scanned — the
71
+ * caller should treat this as a hard-fail for the
72
+ * Context-Budget Guard rule.
73
+ */
74
+ hasStructuralMap(file: string): {
75
+ symbols: boolean;
76
+ imports: boolean;
77
+ } | null;
78
+ captureBefore(file: string): void;
79
+ noteChange(file: string): void;
80
+ canMutate(file: string): {
81
+ ok: boolean;
82
+ reason?: string;
83
+ };
84
+ addVerification(message: string): void;
85
+ finish(status: 'success' | 'error', response: string): void;
86
+ private writeSummary;
87
+ private writeChanges;
88
+ }
89
+ export declare function hashFile(file: string): string | null;
90
+ export declare function gcRuns(cwd: string, keepLimit?: number): void;
91
+ export declare function listRuns(cwd: string, limit?: number): TaskSessionSummary[];
92
+ export declare function showRun(cwd: string, id: string): string;
93
+ export declare function undoRun(cwd: string, id: string): string;
94
+ export declare function revertAgentCommit(cwd: string): string;
95
+ //# sourceMappingURL=task-session.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"task-session.d.ts","sourceRoot":"","sources":["../../src/runtime/task-session.ts"],"names":[],"mappings":"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"}