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,221 @@
1
+ /**
2
+ * Generates an efficient thin map of the workspace.
3
+ * Instead of sending the full codebase content to the LLM (~8000 tokens),
4
+ * this produces a compact directory tree + export signatures (~500 tokens).
5
+ * The model can then selectively read specific files via the read_file tool.
6
+ */
7
+ import fs from 'fs';
8
+ import path from 'path';
9
+ /* ──────────────────────── Config ──────────────────────── */
10
+ const IGNORE_DIRS = new Set([
11
+ 'node_modules', '.git', 'dist', 'build', '.next', '.nuxt',
12
+ '__pycache__', '.pytest_cache', 'coverage', '.turbo',
13
+ '.vercel', '.output', '.cache', '.parcel-cache', 'vendor',
14
+ ]);
15
+ const IGNORE_FILES = new Set([
16
+ '.DS_Store', 'Thumbs.db', 'package-lock.json', 'yarn.lock',
17
+ 'pnpm-lock.yaml', 'bun.lockb', '.env', '.env.local',
18
+ ]);
19
+ const CODE_EXTENSIONS = new Set([
20
+ '.ts', '.tsx', '.js', '.jsx', '.py', '.go', '.rs',
21
+ '.java', '.kt', '.swift', '.rb', '.php', '.c', '.cpp',
22
+ '.h', '.cs', '.vue', '.svelte',
23
+ ]);
24
+ const MAX_DEPTH = 4;
25
+ const MAX_FILES = 200;
26
+ /* ──────────────────────── Main ──────────────────────── */
27
+ /**
28
+ * Build a compact repo map string suitable for LLM context injection.
29
+ * Returns ~200-500 tokens of structured information about the workspace.
30
+ */
31
+ export function buildRepoMap(cwd, additionalExcludes) {
32
+ const excludes = new Set([...IGNORE_DIRS, ...(additionalExcludes ?? [])]);
33
+ const tree = scanDirectory(cwd, excludes, 0);
34
+ if (!tree)
35
+ return '(empty workspace)';
36
+ const lines = ['## Workspace Structure'];
37
+ renderTree(tree, '', lines, true);
38
+ // Count stats
39
+ let fileCount = 0;
40
+ let dirCount = 0;
41
+ countEntries(tree, { files: 0, dirs: 0 }, (stats) => {
42
+ fileCount = stats.files;
43
+ dirCount = stats.dirs;
44
+ });
45
+ lines.push('');
46
+ lines.push(`_${fileCount} files, ${dirCount} directories_`);
47
+ return lines.join('\n');
48
+ }
49
+ /* ──────────────────────── Tree Scanner ──────────────────────── */
50
+ function scanDirectory(dirPath, excludes, depth) {
51
+ if (depth > MAX_DEPTH)
52
+ return null;
53
+ let entries;
54
+ try {
55
+ entries = fs.readdirSync(dirPath, { withFileTypes: true });
56
+ }
57
+ catch {
58
+ return null;
59
+ }
60
+ const children = [];
61
+ let filesSeen = 0;
62
+ // Sort: directories first, then files, alphabetically
63
+ entries.sort((a, b) => {
64
+ if (a.isDirectory() !== b.isDirectory()) {
65
+ return a.isDirectory() ? -1 : 1;
66
+ }
67
+ return a.name.localeCompare(b.name);
68
+ });
69
+ for (const entry of entries) {
70
+ // Hardcoded global structural blacklist to prevent token explosion
71
+ const blacklist = ['.git', 'node_modules', 'dist', 'build', 'out', '.next', '.nuxt', 'coverage', 'package-lock.json', 'yarn.lock'];
72
+ if (blacklist.includes(entry.name))
73
+ continue;
74
+ if (excludes.has(entry.name))
75
+ continue;
76
+ if (IGNORE_FILES.has(entry.name))
77
+ continue;
78
+ if (entry.name.startsWith('.') && entry.isFile())
79
+ continue;
80
+ if (entry.isDirectory()) {
81
+ const subtree = scanDirectory(path.join(dirPath, entry.name), excludes, depth + 1);
82
+ if (subtree) {
83
+ children.push(subtree);
84
+ }
85
+ }
86
+ else if (entry.isFile()) {
87
+ if (filesSeen >= MAX_FILES)
88
+ continue;
89
+ filesSeen++;
90
+ const ext = path.extname(entry.name);
91
+ const filePath = path.join(dirPath, entry.name);
92
+ let sizeBytes;
93
+ try {
94
+ const stat = fs.statSync(filePath);
95
+ sizeBytes = stat.size;
96
+ }
97
+ catch {
98
+ // Ignore stat errors
99
+ }
100
+ const treeEntry = {
101
+ name: entry.name,
102
+ isDir: false,
103
+ sizeBytes,
104
+ };
105
+ // Extract export signatures from code files (fast, regex-based)
106
+ if (CODE_EXTENSIONS.has(ext) && sizeBytes && sizeBytes < 100_000) {
107
+ const exports = extractExports(filePath, ext);
108
+ if (exports.length > 0) {
109
+ treeEntry.exports = exports;
110
+ }
111
+ }
112
+ children.push(treeEntry);
113
+ }
114
+ }
115
+ if (children.length === 0)
116
+ return null;
117
+ return {
118
+ name: path.basename(dirPath),
119
+ isDir: true,
120
+ children,
121
+ };
122
+ }
123
+ /* ──────────────────────── Export Extraction ──────────────────────── */
124
+ function extractExports(filePath, ext) {
125
+ try {
126
+ const content = fs.readFileSync(filePath, 'utf-8');
127
+ const exports = [];
128
+ if (['.ts', '.tsx', '.js', '.jsx'].includes(ext)) {
129
+ // Match: export function name, export class name, export const name, export interface name, export type name
130
+ const patterns = [
131
+ /export\s+(?:async\s+)?function\s+(\w+)/g,
132
+ /export\s+class\s+(\w+)/g,
133
+ /export\s+(?:const|let|var)\s+(\w+)/g,
134
+ /export\s+interface\s+(\w+)/g,
135
+ /export\s+type\s+(\w+)/g,
136
+ /export\s+enum\s+(\w+)/g,
137
+ /export\s+default\s+(?:class|function)\s+(\w+)/g,
138
+ ];
139
+ for (const pattern of patterns) {
140
+ let match;
141
+ while ((match = pattern.exec(content)) !== null) {
142
+ exports.push(match[1]);
143
+ }
144
+ }
145
+ }
146
+ else if (ext === '.py') {
147
+ // Match: def name, class name (top-level only)
148
+ const patterns = [
149
+ /^def\s+(\w+)/gm,
150
+ /^class\s+(\w+)/gm,
151
+ ];
152
+ for (const pattern of patterns) {
153
+ let match;
154
+ while ((match = pattern.exec(content)) !== null) {
155
+ exports.push(match[1]);
156
+ }
157
+ }
158
+ }
159
+ else if (ext === '.go') {
160
+ // Match: func Name (capitalized = exported)
161
+ const pattern = /^func\s+([A-Z]\w*)/gm;
162
+ let match;
163
+ while ((match = pattern.exec(content)) !== null) {
164
+ exports.push(match[1]);
165
+ }
166
+ }
167
+ // Deduplicate
168
+ return [...new Set(exports)].slice(0, 15); // Max 15 per file
169
+ }
170
+ catch {
171
+ return [];
172
+ }
173
+ }
174
+ /* ──────────────────────── Tree Rendering ──────────────────────── */
175
+ function renderTree(entry, prefix, lines, isRoot) {
176
+ if (isRoot) {
177
+ lines.push(`📁 ${entry.name}/`);
178
+ }
179
+ if (!entry.children)
180
+ return;
181
+ for (let i = 0; i < entry.children.length; i++) {
182
+ const child = entry.children[i];
183
+ const isLast = i === entry.children.length - 1;
184
+ const connector = isLast ? '└── ' : '├── ';
185
+ const nextPrefix = prefix + (isLast ? ' ' : '│ ');
186
+ if (child.isDir) {
187
+ lines.push(`${prefix}${connector}📁 ${child.name}/`);
188
+ renderTree(child, nextPrefix, lines, false);
189
+ }
190
+ else {
191
+ let line = `${prefix}${connector}${child.name}`;
192
+ // Append compact export list
193
+ if (child.exports && child.exports.length > 0) {
194
+ const exportStr = child.exports.slice(0, 8).join(', ');
195
+ const suffix = child.exports.length > 8 ? ', …' : '';
196
+ line += ` → {${exportStr}${suffix}}`;
197
+ }
198
+ lines.push(line);
199
+ }
200
+ }
201
+ }
202
+ /* ──────────────────────── Helpers ──────────────────────── */
203
+ function countEntries(entry, stats, callback, depth = 0) {
204
+ if (depth > 20)
205
+ return;
206
+ if (entry.isDir) {
207
+ stats.dirs++;
208
+ if (entry.children) {
209
+ for (const child of entry.children) {
210
+ countEntries(child, stats, () => { }, depth + 1);
211
+ }
212
+ }
213
+ }
214
+ else {
215
+ stats.files++;
216
+ }
217
+ if (depth === 0) {
218
+ callback(stats);
219
+ }
220
+ }
221
+ //# sourceMappingURL=repo-map.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"repo-map.js","sourceRoot":"","sources":["../../src/agent/repo-map.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,103 @@
1
+ /**
2
+ * retry.ts — Unified retry engine for the FixO CLI.
3
+ *
4
+ * Consolidates the five ad-hoc retry loops that previously lived in
5
+ * `agent-client.ts`, `orchestrator.ts`, `worker-agent.ts`, `mcp-client.ts`,
6
+ * and `index.ts` behind a single, type-safe helper.
7
+ *
8
+ * Features:
9
+ * - Exponential backoff with three jitter strategies (full / equal / none).
10
+ * - Strict, type-safe `isRetryable` predicate (no generic `any`).
11
+ * - Honors the HTTP `Retry-After` header (delta-seconds *or* HTTP-date).
12
+ * - Fully cooperative with an external `AbortSignal`. The internal
13
+ * `setTimeout` handle is cleared the instant the signal fires so the
14
+ * timer never leaks after cancellation.
15
+ * - Optional `onRetry` hook for telemetry (errors are swallowed so a
16
+ * misbehaving observer can never break the retry chain).
17
+ */
18
+ export type JitterStrategy = 'full' | 'equal' | 'none';
19
+ export interface RetryPolicy {
20
+ /** Maximum number of attempts (1 = no retry). */
21
+ maxAttempts: number;
22
+ /** Base delay in milliseconds before jitter is applied. */
23
+ baseDelayMs: number;
24
+ /** Upper bound for the computed delay. */
25
+ maxDelayMs: number;
26
+ /** Jitter strategy. 'full' is recommended for distributed systems. */
27
+ jitter: JitterStrategy;
28
+ /**
29
+ * Predicate that decides whether a thrown error is retryable.
30
+ * Returning `false` aborts the loop immediately and rethrows.
31
+ */
32
+ isRetryable: (err: unknown) => boolean;
33
+ /**
34
+ * Optional observer. Called *before* the backoff sleep starts.
35
+ * Any throw inside the observer is swallowed and logged via
36
+ * `console.warn` so telemetry failures cannot break the retry chain.
37
+ */
38
+ onRetry?: (info: RetryEvent) => void;
39
+ }
40
+ export interface RetryEvent {
41
+ /** 0-indexed attempt that just failed. */
42
+ attempt: number;
43
+ /** The error thrown by that attempt. */
44
+ error: unknown;
45
+ /** The delay (ms) that will be slept before the next attempt. */
46
+ delayMs: number;
47
+ /** The retry-after value (ms) derived from headers, if any. */
48
+ retryAfterMs: number | null;
49
+ /** Total attempts used so far (including the one that failed). */
50
+ attemptsConsumed: number;
51
+ /** True if the loop will not retry after this event. */
52
+ willAbort: boolean;
53
+ }
54
+ export declare const DEFAULT_RETRY_POLICY: RetryPolicy;
55
+ /** HTTP status codes that the default policy treats as retryable. */
56
+ export declare const DEFAULT_RETRYABLE_STATUS_CODES: ReadonlySet<number>;
57
+ /**
58
+ * Default `isRetryable` predicate that recognises:
59
+ * - Native `HttpError` instances (status code match).
60
+ * - Plain `Error` objects whose `message` includes a retryable status.
61
+ * - Network-layer failures (`ECONNREFUSED`, `ECONNRESET`, `ETIMEDOUT`,
62
+ * `fetch failed`).
63
+ */
64
+ export declare function defaultIsRetryable(err: unknown): boolean;
65
+ /**
66
+ * Sleep helper that can be cancelled by an `AbortSignal`. Returns
67
+ * a promise that resolves after `ms` milliseconds, or rejects with
68
+ * an `AbortError` if the signal fires before the timer elapses.
69
+ *
70
+ * The internal timer is cleared synchronously when the signal fires,
71
+ * so no Node.js timer handle leaks.
72
+ */
73
+ export declare function abortableSleep(ms: number, signal?: AbortSignal): Promise<void>;
74
+ /**
75
+ * Computes the backoff delay for a given attempt, applying the policy's
76
+ * jitter strategy. Exposed for testability — the result is always a
77
+ * non-negative integer in milliseconds.
78
+ */
79
+ export declare function computeBackoffMs(attempt: number, baseDelayMs: number, maxDelayMs: number, jitter: JitterStrategy, retryAfterMs?: number | null): number;
80
+ /**
81
+ * Parses an HTTP `Retry-After` header value.
82
+ *
83
+ * - `Retry-After: 120` → 120 000 ms
84
+ * - `Retry-After: Fri, 31 Dec 1999 23:59:59 GMT` → ms until that date
85
+ * - Missing / malformed → `null`
86
+ *
87
+ * Returned value is clamped to `[0, 24h]` to protect against pathological
88
+ * server values (e.g. `Retry-After: 999999999`).
89
+ */
90
+ export declare function parseRetryAfter(header: string | null | undefined, now?: number): number | null;
91
+ /**
92
+ * Executes `fn` under a retry policy. The function is invoked with an
93
+ * `AbortSignal` that fires when either the external signal aborts or the
94
+ * retry loop gives up. The signal is *additive* — it is aborted as soon
95
+ * as either source fires, and both listeners are removed in `finally`.
96
+ *
97
+ * Throws:
98
+ * - The last error thrown by `fn` if it is non-retryable or the budget
99
+ * is exhausted.
100
+ * - An `AbortError` if the external signal aborts.
101
+ */
102
+ export declare function withRetry<T>(fn: (signal: AbortSignal) => Promise<T>, policy?: RetryPolicy, externalSignal?: AbortSignal): Promise<T>;
103
+ //# sourceMappingURL=retry.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"retry.d.ts","sourceRoot":"","sources":["../../src/agent/retry.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAEH,MAAM,MAAM,cAAc,GAAG,MAAM,GAAG,OAAO,GAAG,MAAM,CAAC;AAEvD,MAAM,WAAW,WAAW;IAC1B,iDAAiD;IACjD,WAAW,EAAE,MAAM,CAAC;IACpB,2DAA2D;IAC3D,WAAW,EAAE,MAAM,CAAC;IACpB,0CAA0C;IAC1C,UAAU,EAAE,MAAM,CAAC;IACnB,sEAAsE;IACtE,MAAM,EAAE,cAAc,CAAC;IACvB;;;OAGG;IACH,WAAW,EAAE,CAAC,GAAG,EAAE,OAAO,KAAK,OAAO,CAAC;IACvC;;;;OAIG;IACH,OAAO,CAAC,EAAE,CAAC,IAAI,EAAE,UAAU,KAAK,IAAI,CAAC;CACtC;AAED,MAAM,WAAW,UAAU;IACzB,0CAA0C;IAC1C,OAAO,EAAE,MAAM,CAAC;IAChB,wCAAwC;IACxC,KAAK,EAAE,OAAO,CAAC;IACf,iEAAiE;IACjE,OAAO,EAAE,MAAM,CAAC;IAChB,+DAA+D;IAC/D,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,kEAAkE;IAClE,gBAAgB,EAAE,MAAM,CAAC;IACzB,wDAAwD;IACxD,SAAS,EAAE,OAAO,CAAC;CACpB;AAED,eAAO,MAAM,oBAAoB,EAAE,WAMlC,CAAC;AAEF,qEAAqE;AACrE,eAAO,MAAM,8BAA8B,EAAE,WAAW,CAAC,MAAM,CAE7D,CAAC;AAEH;;;;;;GAMG;AACH,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,OAAO,GAAG,OAAO,CA0BxD;AAED;;;;;;;GAOG;AACH,wBAAgB,cAAc,CAAC,EAAE,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC,CAoB9E;AAaD;;;;GAIG;AACH,wBAAgB,gBAAgB,CAC9B,OAAO,EAAE,MAAM,EACf,WAAW,EAAE,MAAM,EACnB,UAAU,EAAE,MAAM,EAClB,MAAM,EAAE,cAAc,EACtB,YAAY,GAAE,MAAM,GAAG,IAAW,GACjC,MAAM,CAoBR;AAED;;;;;;;;;GASG;AACH,wBAAgB,eAAe,CAC7B,MAAM,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,EACjC,GAAG,GAAE,MAAmB,GACvB,MAAM,GAAG,IAAI,CAmBf;AASD;;;;;;;;;;GAUG;AACH,wBAAsB,SAAS,CAAC,CAAC,EAC/B,EAAE,EAAE,CAAC,MAAM,EAAE,WAAW,KAAK,OAAO,CAAC,CAAC,CAAC,EACvC,MAAM,GAAE,WAA0E,EAClF,cAAc,CAAC,EAAE,WAAW,GAC3B,OAAO,CAAC,CAAC,CAAC,CAsEZ"}
@@ -0,0 +1,276 @@
1
+ /**
2
+ * retry.ts — Unified retry engine for the FixO CLI.
3
+ *
4
+ * Consolidates the five ad-hoc retry loops that previously lived in
5
+ * `agent-client.ts`, `orchestrator.ts`, `worker-agent.ts`, `mcp-client.ts`,
6
+ * and `index.ts` behind a single, type-safe helper.
7
+ *
8
+ * Features:
9
+ * - Exponential backoff with three jitter strategies (full / equal / none).
10
+ * - Strict, type-safe `isRetryable` predicate (no generic `any`).
11
+ * - Honors the HTTP `Retry-After` header (delta-seconds *or* HTTP-date).
12
+ * - Fully cooperative with an external `AbortSignal`. The internal
13
+ * `setTimeout` handle is cleared the instant the signal fires so the
14
+ * timer never leaks after cancellation.
15
+ * - Optional `onRetry` hook for telemetry (errors are swallowed so a
16
+ * misbehaving observer can never break the retry chain).
17
+ */
18
+ export const DEFAULT_RETRY_POLICY = {
19
+ maxAttempts: 5,
20
+ baseDelayMs: 1_500,
21
+ maxDelayMs: 30_000,
22
+ jitter: 'full',
23
+ isRetryable: () => true,
24
+ };
25
+ /** HTTP status codes that the default policy treats as retryable. */
26
+ export const DEFAULT_RETRYABLE_STATUS_CODES = new Set([
27
+ 408, 429, 500, 502, 503, 504,
28
+ ]);
29
+ /**
30
+ * Default `isRetryable` predicate that recognises:
31
+ * - Native `HttpError` instances (status code match).
32
+ * - Plain `Error` objects whose `message` includes a retryable status.
33
+ * - Network-layer failures (`ECONNREFUSED`, `ECONNRESET`, `ETIMEDOUT`,
34
+ * `fetch failed`).
35
+ */
36
+ export function defaultIsRetryable(err) {
37
+ if (err instanceof Error) {
38
+ const name = err.name;
39
+ if (name === 'AbortError' || name === 'AbortError' || /abort/i.test(err.message)) {
40
+ return false;
41
+ }
42
+ if (name === 'HttpError' && 'status' in err) {
43
+ const status = err.status;
44
+ if (typeof status === 'number') {
45
+ return DEFAULT_RETRYABLE_STATUS_CODES.has(status);
46
+ }
47
+ }
48
+ if (/(?:408|429|500|502|503|504)/.test(err.message)) {
49
+ return true;
50
+ }
51
+ if (err.message.includes('ECONNREFUSED') ||
52
+ err.message.includes('ECONNRESET') ||
53
+ err.message.includes('ETIMEDOUT') ||
54
+ err.message.includes('fetch failed') ||
55
+ err.message.includes('socket hang up')) {
56
+ return true;
57
+ }
58
+ }
59
+ return false;
60
+ }
61
+ /**
62
+ * Sleep helper that can be cancelled by an `AbortSignal`. Returns
63
+ * a promise that resolves after `ms` milliseconds, or rejects with
64
+ * an `AbortError` if the signal fires before the timer elapses.
65
+ *
66
+ * The internal timer is cleared synchronously when the signal fires,
67
+ * so no Node.js timer handle leaks.
68
+ */
69
+ export function abortableSleep(ms, signal) {
70
+ return new Promise((resolve, reject) => {
71
+ if (signal?.aborted) {
72
+ reject(abortError(signal.reason));
73
+ return;
74
+ }
75
+ const timer = setTimeout(() => {
76
+ cleanup();
77
+ resolve();
78
+ }, ms);
79
+ const onAbort = () => {
80
+ clearTimeout(timer);
81
+ cleanup();
82
+ reject(abortError(signal?.reason));
83
+ };
84
+ const cleanup = () => {
85
+ signal?.removeEventListener('abort', onAbort);
86
+ };
87
+ signal?.addEventListener('abort', onAbort, { once: true });
88
+ });
89
+ }
90
+ function abortError(reason) {
91
+ if (reason instanceof Error) {
92
+ const err = new Error(`Aborted: ${reason.message}`);
93
+ err.name = 'AbortError';
94
+ return err;
95
+ }
96
+ const err = new Error('Aborted');
97
+ err.name = 'AbortError';
98
+ return err;
99
+ }
100
+ /**
101
+ * Computes the backoff delay for a given attempt, applying the policy's
102
+ * jitter strategy. Exposed for testability — the result is always a
103
+ * non-negative integer in milliseconds.
104
+ */
105
+ export function computeBackoffMs(attempt, baseDelayMs, maxDelayMs, jitter, retryAfterMs = null) {
106
+ // Retry-After always wins if it was supplied.
107
+ if (retryAfterMs !== null) {
108
+ return Math.min(retryAfterMs, maxDelayMs);
109
+ }
110
+ const exp = Math.min(maxDelayMs, baseDelayMs * Math.pow(2, attempt));
111
+ switch (jitter) {
112
+ case 'none':
113
+ return Math.floor(exp);
114
+ case 'equal': {
115
+ // Half deterministic, half random.
116
+ const half = exp / 2;
117
+ return Math.floor(half + Math.random() * half);
118
+ }
119
+ case 'full':
120
+ default: {
121
+ // 0 .. exp
122
+ return Math.floor(Math.random() * exp);
123
+ }
124
+ }
125
+ }
126
+ /**
127
+ * Parses an HTTP `Retry-After` header value.
128
+ *
129
+ * - `Retry-After: 120` → 120 000 ms
130
+ * - `Retry-After: Fri, 31 Dec 1999 23:59:59 GMT` → ms until that date
131
+ * - Missing / malformed → `null`
132
+ *
133
+ * Returned value is clamped to `[0, 24h]` to protect against pathological
134
+ * server values (e.g. `Retry-After: 999999999`).
135
+ */
136
+ export function parseRetryAfter(header, now = Date.now()) {
137
+ if (!header)
138
+ return null;
139
+ const trimmed = header.trim();
140
+ if (!trimmed)
141
+ return null;
142
+ // 1) Delta-seconds form.
143
+ if (/^\d+(\.\d+)?$/.test(trimmed)) {
144
+ const seconds = Number(trimmed);
145
+ if (!Number.isFinite(seconds) || seconds < 0)
146
+ return null;
147
+ const ms = Math.floor(seconds * 1000);
148
+ return clampRetryAfterMs(ms);
149
+ }
150
+ // 2) HTTP-date form.
151
+ const parsed = Date.parse(trimmed);
152
+ if (!Number.isFinite(parsed))
153
+ return null;
154
+ const ms = parsed - now;
155
+ if (ms <= 0)
156
+ return 0;
157
+ return clampRetryAfterMs(ms);
158
+ }
159
+ function clampRetryAfterMs(ms) {
160
+ const ONE_DAY = 86_400_000;
161
+ if (ms < 0)
162
+ return 0;
163
+ if (ms > ONE_DAY)
164
+ return ONE_DAY;
165
+ return Math.floor(ms);
166
+ }
167
+ /**
168
+ * Executes `fn` under a retry policy. The function is invoked with an
169
+ * `AbortSignal` that fires when either the external signal aborts or the
170
+ * retry loop gives up. The signal is *additive* — it is aborted as soon
171
+ * as either source fires, and both listeners are removed in `finally`.
172
+ *
173
+ * Throws:
174
+ * - The last error thrown by `fn` if it is non-retryable or the budget
175
+ * is exhausted.
176
+ * - An `AbortError` if the external signal aborts.
177
+ */
178
+ export async function withRetry(fn, policy = { ...DEFAULT_RETRY_POLICY, isRetryable: defaultIsRetryable }, externalSignal) {
179
+ if (policy.maxAttempts < 1) {
180
+ throw new Error('RetryPolicy.maxAttempts must be >= 1');
181
+ }
182
+ // Combined signal: aborts when either source fires.
183
+ const controller = new AbortController();
184
+ const forwardAbort = () => controller.abort();
185
+ if (externalSignal) {
186
+ if (externalSignal.aborted) {
187
+ controller.abort();
188
+ }
189
+ else {
190
+ externalSignal.addEventListener('abort', forwardAbort, { once: true });
191
+ }
192
+ }
193
+ let lastError;
194
+ try {
195
+ for (let attempt = 0; attempt < policy.maxAttempts; attempt++) {
196
+ if (controller.signal.aborted) {
197
+ throw abortError(externalSignal?.reason);
198
+ }
199
+ try {
200
+ return await fn(controller.signal);
201
+ }
202
+ catch (err) {
203
+ lastError = err;
204
+ if (controller.signal.aborted) {
205
+ throw abortError(externalSignal?.reason);
206
+ }
207
+ const retryable = policy.isRetryable(err);
208
+ const isLastAttempt = attempt === policy.maxAttempts - 1;
209
+ if (!retryable || isLastAttempt) {
210
+ throw err;
211
+ }
212
+ const retryAfterMs = extractRetryAfterFromError(err);
213
+ const delayMs = computeBackoffMs(attempt, policy.baseDelayMs, policy.maxDelayMs, policy.jitter, retryAfterMs);
214
+ const event = {
215
+ attempt,
216
+ error: err,
217
+ delayMs,
218
+ retryAfterMs,
219
+ attemptsConsumed: attempt + 1,
220
+ willAbort: false,
221
+ };
222
+ emitRetryEvent(policy.onRetry, event);
223
+ await abortableSleep(delayMs, controller.signal);
224
+ }
225
+ }
226
+ // Unreachable: the loop above either returns or throws.
227
+ throw lastError ?? new Error('Retry loop exited unexpectedly');
228
+ }
229
+ finally {
230
+ if (externalSignal) {
231
+ externalSignal.removeEventListener('abort', forwardAbort);
232
+ }
233
+ }
234
+ }
235
+ /**
236
+ * Best-effort extraction of a Retry-After value from a thrown error.
237
+ * Looks at the well-known `headers` property (e.g. set by the upstream
238
+ * HTTP layer) and falls back to scanning the error message for a
239
+ * numeric `Retry-After: N` snippet.
240
+ */
241
+ function extractRetryAfterFromError(err) {
242
+ if (!err || typeof err !== 'object')
243
+ return null;
244
+ const obj = err;
245
+ if (obj.headers && typeof obj.headers === 'object') {
246
+ const headers = obj.headers;
247
+ const raw = headers['retry-after'] ?? headers['Retry-After'];
248
+ if (typeof raw === 'string')
249
+ return parseRetryAfter(raw);
250
+ if (Array.isArray(raw) && typeof raw[0] === 'string')
251
+ return parseRetryAfter(raw[0]);
252
+ }
253
+ if (typeof obj.message === 'string') {
254
+ const m = /retry-after\s*[:=]\s*(\d+)/i.exec(obj.message);
255
+ if (m && m[1]) {
256
+ const seconds = Number(m[1]);
257
+ if (Number.isFinite(seconds))
258
+ return Math.min(seconds * 1000, 86_400_000);
259
+ }
260
+ }
261
+ return null;
262
+ }
263
+ function emitRetryEvent(hook, event) {
264
+ if (!hook)
265
+ return;
266
+ try {
267
+ hook(event);
268
+ }
269
+ catch (hookErr) {
270
+ // Telemetry must never break the retry chain.
271
+ const msg = hookErr instanceof Error ? hookErr.message : String(hookErr);
272
+ // eslint-disable-next-line no-console
273
+ console.warn(`[retry] onRetry hook threw: ${msg}`);
274
+ }
275
+ }
276
+ //# sourceMappingURL=retry.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"retry.js","sourceRoot":"","sources":["../../src/agent/retry.ts"],"names":[],"mappings":"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"}