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.
- package/LICENSE +201 -0
- package/README.md +530 -0
- package/dist/agent/agent-client.d.ts +108 -0
- package/dist/agent/agent-client.d.ts.map +1 -0
- package/dist/agent/agent-client.js +1247 -0
- package/dist/agent/agent-client.js.map +1 -0
- package/dist/agent/agent-pool.d.ts +20 -0
- package/dist/agent/agent-pool.d.ts.map +1 -0
- package/dist/agent/agent-pool.js +217 -0
- package/dist/agent/agent-pool.js.map +1 -0
- package/dist/agent/background-awareness.d.ts +55 -0
- package/dist/agent/background-awareness.d.ts.map +1 -0
- package/dist/agent/background-awareness.js +104 -0
- package/dist/agent/background-awareness.js.map +1 -0
- package/dist/agent/command-parser.d.ts +33 -0
- package/dist/agent/command-parser.d.ts.map +1 -0
- package/dist/agent/command-parser.js +120 -0
- package/dist/agent/command-parser.js.map +1 -0
- package/dist/agent/context-budget.d.ts +91 -0
- package/dist/agent/context-budget.d.ts.map +1 -0
- package/dist/agent/context-budget.js +219 -0
- package/dist/agent/context-budget.js.map +1 -0
- package/dist/agent/conversation.d.ts +190 -0
- package/dist/agent/conversation.d.ts.map +1 -0
- package/dist/agent/conversation.js +547 -0
- package/dist/agent/conversation.js.map +1 -0
- package/dist/agent/hooks.d.ts +72 -0
- package/dist/agent/hooks.d.ts.map +1 -0
- package/dist/agent/hooks.js +214 -0
- package/dist/agent/hooks.js.map +1 -0
- package/dist/agent/mcp-bridge.d.ts +13 -0
- package/dist/agent/mcp-bridge.d.ts.map +1 -0
- package/dist/agent/mcp-bridge.js +86 -0
- package/dist/agent/mcp-bridge.js.map +1 -0
- package/dist/agent/mcp-client.d.ts +24 -0
- package/dist/agent/mcp-client.d.ts.map +1 -0
- package/dist/agent/mcp-client.js +146 -0
- package/dist/agent/mcp-client.js.map +1 -0
- package/dist/agent/mcp-manager.d.ts +13 -0
- package/dist/agent/mcp-manager.d.ts.map +1 -0
- package/dist/agent/mcp-manager.js +84 -0
- package/dist/agent/mcp-manager.js.map +1 -0
- package/dist/agent/mcp-registry.d.ts +45 -0
- package/dist/agent/mcp-registry.d.ts.map +1 -0
- package/dist/agent/mcp-registry.js +98 -0
- package/dist/agent/mcp-registry.js.map +1 -0
- package/dist/agent/orchestrator.d.ts +14 -0
- package/dist/agent/orchestrator.d.ts.map +1 -0
- package/dist/agent/orchestrator.js +118 -0
- package/dist/agent/orchestrator.js.map +1 -0
- package/dist/agent/parser-adapter.d.ts +120 -0
- package/dist/agent/parser-adapter.d.ts.map +1 -0
- package/dist/agent/parser-adapter.js +265 -0
- package/dist/agent/parser-adapter.js.map +1 -0
- package/dist/agent/parsers/imports.d.ts +11 -0
- package/dist/agent/parsers/imports.d.ts.map +1 -0
- package/dist/agent/parsers/imports.js +94 -0
- package/dist/agent/parsers/imports.js.map +1 -0
- package/dist/agent/parsers/shell.d.ts +23 -0
- package/dist/agent/parsers/shell.d.ts.map +1 -0
- package/dist/agent/parsers/shell.js +200 -0
- package/dist/agent/parsers/shell.js.map +1 -0
- package/dist/agent/parsers/symbols.d.ts +17 -0
- package/dist/agent/parsers/symbols.d.ts.map +1 -0
- package/dist/agent/parsers/symbols.js +103 -0
- package/dist/agent/parsers/symbols.js.map +1 -0
- package/dist/agent/permissions.d.ts +65 -0
- package/dist/agent/permissions.d.ts.map +1 -0
- package/dist/agent/permissions.js +219 -0
- package/dist/agent/permissions.js.map +1 -0
- package/dist/agent/predictive-gate.d.ts +69 -0
- package/dist/agent/predictive-gate.d.ts.map +1 -0
- package/dist/agent/predictive-gate.js +128 -0
- package/dist/agent/predictive-gate.js.map +1 -0
- package/dist/agent/provider-cooldown.d.ts +144 -0
- package/dist/agent/provider-cooldown.d.ts.map +1 -0
- package/dist/agent/provider-cooldown.js +300 -0
- package/dist/agent/provider-cooldown.js.map +1 -0
- package/dist/agent/providers-manager.d.ts +109 -0
- package/dist/agent/providers-manager.d.ts.map +1 -0
- package/dist/agent/providers-manager.js +464 -0
- package/dist/agent/providers-manager.js.map +1 -0
- package/dist/agent/repo-map.d.ts +6 -0
- package/dist/agent/repo-map.d.ts.map +1 -0
- package/dist/agent/repo-map.js +221 -0
- package/dist/agent/repo-map.js.map +1 -0
- package/dist/agent/retry.d.ts +103 -0
- package/dist/agent/retry.d.ts.map +1 -0
- package/dist/agent/retry.js +276 -0
- package/dist/agent/retry.js.map +1 -0
- package/dist/agent/search/index.d.ts +61 -0
- package/dist/agent/search/index.d.ts.map +1 -0
- package/dist/agent/search/index.js +314 -0
- package/dist/agent/search/index.js.map +1 -0
- package/dist/agent/single-agent.d.ts +76 -0
- package/dist/agent/single-agent.d.ts.map +1 -0
- package/dist/agent/single-agent.js +697 -0
- package/dist/agent/single-agent.js.map +1 -0
- package/dist/agent/skills.d.ts +22 -0
- package/dist/agent/skills.d.ts.map +1 -0
- package/dist/agent/skills.js +139 -0
- package/dist/agent/skills.js.map +1 -0
- package/dist/agent/stream-glue.d.ts +85 -0
- package/dist/agent/stream-glue.d.ts.map +1 -0
- package/dist/agent/stream-glue.js +120 -0
- package/dist/agent/stream-glue.js.map +1 -0
- package/dist/agent/subagent.d.ts +72 -0
- package/dist/agent/subagent.d.ts.map +1 -0
- package/dist/agent/subagent.js +193 -0
- package/dist/agent/subagent.js.map +1 -0
- package/dist/agent/telemetry.d.ts +192 -0
- package/dist/agent/telemetry.d.ts.map +1 -0
- package/dist/agent/telemetry.js +400 -0
- package/dist/agent/telemetry.js.map +1 -0
- package/dist/agent/tokenizer.d.ts +42 -0
- package/dist/agent/tokenizer.d.ts.map +1 -0
- package/dist/agent/tokenizer.js +107 -0
- package/dist/agent/tokenizer.js.map +1 -0
- package/dist/agent/tool-executor.d.ts +289 -0
- package/dist/agent/tool-executor.d.ts.map +1 -0
- package/dist/agent/tool-executor.js +2519 -0
- package/dist/agent/tool-executor.js.map +1 -0
- package/dist/agent/web-impl.d.ts +2 -0
- package/dist/agent/web-impl.d.ts.map +1 -0
- package/dist/agent/web-impl.js +34 -0
- package/dist/agent/web-impl.js.map +1 -0
- package/dist/agent/web.d.ts +8 -0
- package/dist/agent/web.d.ts.map +1 -0
- package/dist/agent/web.js +8 -0
- package/dist/agent/web.js.map +1 -0
- package/dist/agent/worker-agent.d.ts +27 -0
- package/dist/agent/worker-agent.d.ts.map +1 -0
- package/dist/agent/worker-agent.js +503 -0
- package/dist/agent/worker-agent.js.map +1 -0
- package/dist/config.d.ts +162 -0
- package/dist/config.d.ts.map +1 -0
- package/dist/config.js +138 -0
- package/dist/config.js.map +1 -0
- package/dist/context/fixo-md-watcher.d.ts +42 -0
- package/dist/context/fixo-md-watcher.d.ts.map +1 -0
- package/dist/context/fixo-md-watcher.js +126 -0
- package/dist/context/fixo-md-watcher.js.map +1 -0
- package/dist/context/fixo-md.d.ts +50 -0
- package/dist/context/fixo-md.d.ts.map +1 -0
- package/dist/context/fixo-md.js +118 -0
- package/dist/context/fixo-md.js.map +1 -0
- package/dist/context/todo.d.ts +65 -0
- package/dist/context/todo.d.ts.map +1 -0
- package/dist/context/todo.js +194 -0
- package/dist/context/todo.js.map +1 -0
- package/dist/git/git-manager.d.ts +33 -0
- package/dist/git/git-manager.d.ts.map +1 -0
- package/dist/git/git-manager.js +293 -0
- package/dist/git/git-manager.js.map +1 -0
- package/dist/git/git-ops.d.ts +10 -0
- package/dist/git/git-ops.d.ts.map +1 -0
- package/dist/git/git-ops.js +131 -0
- package/dist/git/git-ops.js.map +1 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +352 -0
- package/dist/index.js.map +1 -0
- package/dist/indexer.d.ts +30 -0
- package/dist/indexer.d.ts.map +1 -0
- package/dist/indexer.js +273 -0
- package/dist/indexer.js.map +1 -0
- package/dist/lsp/lsp-client.d.ts +24 -0
- package/dist/lsp/lsp-client.d.ts.map +1 -0
- package/dist/lsp/lsp-client.js +205 -0
- package/dist/lsp/lsp-client.js.map +1 -0
- package/dist/lsp/lsp-manager.d.ts +17 -0
- package/dist/lsp/lsp-manager.d.ts.map +1 -0
- package/dist/lsp/lsp-manager.js +154 -0
- package/dist/lsp/lsp-manager.js.map +1 -0
- package/dist/lsp/lsp-pre-save.d.ts +137 -0
- package/dist/lsp/lsp-pre-save.d.ts.map +1 -0
- package/dist/lsp/lsp-pre-save.js +245 -0
- package/dist/lsp/lsp-pre-save.js.map +1 -0
- package/dist/lsp/syntax-fallback.d.ts +83 -0
- package/dist/lsp/syntax-fallback.d.ts.map +1 -0
- package/dist/lsp/syntax-fallback.js +275 -0
- package/dist/lsp/syntax-fallback.js.map +1 -0
- package/dist/model-outcomes.d.ts +12 -0
- package/dist/model-outcomes.d.ts.map +1 -0
- package/dist/model-outcomes.js +46 -0
- package/dist/model-outcomes.js.map +1 -0
- package/dist/planner.d.ts +32 -0
- package/dist/planner.d.ts.map +1 -0
- package/dist/planner.js +163 -0
- package/dist/planner.js.map +1 -0
- package/dist/project-memory.d.ts +29 -0
- package/dist/project-memory.d.ts.map +1 -0
- package/dist/project-memory.js +349 -0
- package/dist/project-memory.js.map +1 -0
- package/dist/review.d.ts +2 -0
- package/dist/review.d.ts.map +1 -0
- package/dist/review.js +61 -0
- package/dist/review.js.map +1 -0
- package/dist/runtime/background-jobs.d.ts +97 -0
- package/dist/runtime/background-jobs.d.ts.map +1 -0
- package/dist/runtime/background-jobs.js +331 -0
- package/dist/runtime/background-jobs.js.map +1 -0
- package/dist/runtime/credential-vault.d.ts +124 -0
- package/dist/runtime/credential-vault.d.ts.map +1 -0
- package/dist/runtime/credential-vault.js +184 -0
- package/dist/runtime/credential-vault.js.map +1 -0
- package/dist/runtime/loop-trap.d.ts +197 -0
- package/dist/runtime/loop-trap.d.ts.map +1 -0
- package/dist/runtime/loop-trap.js +420 -0
- package/dist/runtime/loop-trap.js.map +1 -0
- package/dist/runtime/policy.d.ts +15 -0
- package/dist/runtime/policy.d.ts.map +1 -0
- package/dist/runtime/policy.js +60 -0
- package/dist/runtime/policy.js.map +1 -0
- package/dist/runtime/redaction.d.ts +66 -0
- package/dist/runtime/redaction.d.ts.map +1 -0
- package/dist/runtime/redaction.js +155 -0
- package/dist/runtime/redaction.js.map +1 -0
- package/dist/runtime/session-snapshots.d.ts +76 -0
- package/dist/runtime/session-snapshots.d.ts.map +1 -0
- package/dist/runtime/session-snapshots.js +166 -0
- package/dist/runtime/session-snapshots.js.map +1 -0
- package/dist/runtime/staging.d.ts +205 -0
- package/dist/runtime/staging.d.ts.map +1 -0
- package/dist/runtime/staging.js +526 -0
- package/dist/runtime/staging.js.map +1 -0
- package/dist/runtime/task-session.d.ts +95 -0
- package/dist/runtime/task-session.d.ts.map +1 -0
- package/dist/runtime/task-session.js +263 -0
- package/dist/runtime/task-session.js.map +1 -0
- package/dist/runtime/worktree.d.ts +55 -0
- package/dist/runtime/worktree.d.ts.map +1 -0
- package/dist/runtime/worktree.js +175 -0
- package/dist/runtime/worktree.js.map +1 -0
- package/dist/setup-wizard.d.ts +8 -0
- package/dist/setup-wizard.d.ts.map +1 -0
- package/dist/setup-wizard.js +73 -0
- package/dist/setup-wizard.js.map +1 -0
- package/dist/shared/content.d.ts +43 -0
- package/dist/shared/content.d.ts.map +1 -0
- package/dist/shared/content.js +61 -0
- package/dist/shared/content.js.map +1 -0
- package/dist/shared/types.d.ts +217 -0
- package/dist/shared/types.d.ts.map +1 -0
- package/dist/shared/types.js +3 -0
- package/dist/shared/types.js.map +1 -0
- package/dist/test-runner.d.ts +5 -0
- package/dist/test-runner.d.ts.map +1 -0
- package/dist/test-runner.js +42 -0
- package/dist/test-runner.js.map +1 -0
- package/dist/types.d.ts +85 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +2 -0
- package/dist/types.js.map +1 -0
- package/dist/ui/ascii.d.ts +23 -0
- package/dist/ui/ascii.d.ts.map +1 -0
- package/dist/ui/ascii.js +45 -0
- package/dist/ui/ascii.js.map +1 -0
- package/dist/ui/colors.d.ts +111 -0
- package/dist/ui/colors.d.ts.map +1 -0
- package/dist/ui/colors.js +166 -0
- package/dist/ui/colors.js.map +1 -0
- package/dist/ui/image-attach.d.ts +27 -0
- package/dist/ui/image-attach.d.ts.map +1 -0
- package/dist/ui/image-attach.js +100 -0
- package/dist/ui/image-attach.js.map +1 -0
- package/dist/ui/index.d.ts +18 -0
- package/dist/ui/index.d.ts.map +1 -0
- package/dist/ui/index.js +18 -0
- package/dist/ui/index.js.map +1 -0
- package/dist/ui/markdown-stream.d.ts +91 -0
- package/dist/ui/markdown-stream.d.ts.map +1 -0
- package/dist/ui/markdown-stream.js +524 -0
- package/dist/ui/markdown-stream.js.map +1 -0
- package/dist/ui/plan-renderer.d.ts +36 -0
- package/dist/ui/plan-renderer.d.ts.map +1 -0
- package/dist/ui/plan-renderer.js +79 -0
- package/dist/ui/plan-renderer.js.map +1 -0
- package/dist/ui/prompt.d.ts +11 -0
- package/dist/ui/prompt.d.ts.map +1 -0
- package/dist/ui/prompt.js +1960 -0
- package/dist/ui/prompt.js.map +1 -0
- package/dist/ui/render-primitives.d.ts +117 -0
- package/dist/ui/render-primitives.d.ts.map +1 -0
- package/dist/ui/render-primitives.js +322 -0
- package/dist/ui/render-primitives.js.map +1 -0
- package/dist/ui/render.d.ts +133 -0
- package/dist/ui/render.d.ts.map +1 -0
- package/dist/ui/render.js +547 -0
- package/dist/ui/render.js.map +1 -0
- package/dist/ui/session-header.d.ts +30 -0
- package/dist/ui/session-header.d.ts.map +1 -0
- package/dist/ui/session-header.js +74 -0
- package/dist/ui/session-header.js.map +1 -0
- package/dist/workspace-guard.d.ts +68 -0
- package/dist/workspace-guard.d.ts.map +1 -0
- package/dist/workspace-guard.js +168 -0
- package/dist/workspace-guard.js.map +1 -0
- package/dist/workspace-lock.d.ts +27 -0
- package/dist/workspace-lock.d.ts.map +1 -0
- package/dist/workspace-lock.js +95 -0
- package/dist/workspace-lock.js.map +1 -0
- 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":"AAAA;;;;;GAKG;AACH,OAAO,EAAE,MAAM,IAAI,CAAC;AACpB,OAAO,IAAI,MAAM,MAAM,CAAC;AAExB,8DAA8D;AAE9D,MAAM,WAAW,GAAG,IAAI,GAAG,CAAC;IAC1B,cAAc,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,EAAE,OAAO;IACzD,aAAa,EAAE,eAAe,EAAE,UAAU,EAAE,QAAQ;IACpD,SAAS,EAAE,SAAS,EAAE,QAAQ,EAAE,eAAe,EAAE,QAAQ;CAC1D,CAAC,CAAC;AAEH,MAAM,YAAY,GAAG,IAAI,GAAG,CAAC;IAC3B,WAAW,EAAE,WAAW,EAAE,mBAAmB,EAAE,WAAW;IAC1D,gBAAgB,EAAE,WAAW,EAAE,MAAM,EAAE,YAAY;CACpD,CAAC,CAAC;AAEH,MAAM,eAAe,GAAG,IAAI,GAAG,CAAC;IAC9B,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK;IACjD,OAAO,EAAE,KAAK,EAAE,QAAQ,EAAE,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM;IACrD,IAAI,EAAE,KAAK,EAAE,MAAM,EAAE,SAAS;CAC/B,CAAC,CAAC;AAEH,MAAM,SAAS,GAAG,CAAC,CAAC;AACpB,MAAM,SAAS,GAAG,GAAG,CAAC;AAYtB,4DAA4D;AAE5D;;;GAGG;AACH,MAAM,UAAU,YAAY,CAAC,GAAW,EAAE,kBAA6B;IACrE,MAAM,QAAQ,GAAG,IAAI,GAAG,CAAC,CAAC,GAAG,WAAW,EAAE,GAAG,CAAC,kBAAkB,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;IAC1E,MAAM,IAAI,GAAG,aAAa,CAAC,GAAG,EAAE,QAAQ,EAAE,CAAC,CAAC,CAAC;IAE7C,IAAI,CAAC,IAAI;QAAE,OAAO,mBAAmB,CAAC;IAEtC,MAAM,KAAK,GAAa,CAAC,wBAAwB,CAAC,CAAC;IACnD,UAAU,CAAC,IAAI,EAAE,EAAE,EAAE,KAAK,EAAE,IAAI,CAAC,CAAC;IAElC,cAAc;IACd,IAAI,SAAS,GAAG,CAAC,CAAC;IAClB,IAAI,QAAQ,GAAG,CAAC,CAAC;IACjB,YAAY,CAAC,IAAI,EAAE,EAAE,KAAK,EAAE,CAAC,EAAE,IAAI,EAAE,CAAC,EAAE,EAAE,CAAC,KAAK,EAAE,EAAE;QAClD,SAAS,GAAG,KAAK,CAAC,KAAK,CAAC;QACxB,QAAQ,GAAG,KAAK,CAAC,IAAI,CAAC;IACxB,CAAC,CAAC,CAAC;IAEH,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IACf,KAAK,CAAC,IAAI,CAAC,IAAI,SAAS,WAAW,QAAQ,eAAe,CAAC,CAAC;IAE5D,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AAC1B,CAAC;AAED,oEAAoE;AAEpE,SAAS,aAAa,CACpB,OAAe,EACf,QAAqB,EACrB,KAAa;IAEb,IAAI,KAAK,GAAG,SAAS;QAAE,OAAO,IAAI,CAAC;IAEnC,IAAI,OAAoB,CAAC;IACzB,IAAI,CAAC;QACH,OAAO,GAAG,EAAE,CAAC,WAAW,CAAC,OAAO,EAAE,EAAE,aAAa,EAAE,IAAI,EAAE,CAAC,CAAC;IAC7D,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC;IACd,CAAC;IAED,MAAM,QAAQ,GAAgB,EAAE,CAAC;IACjC,IAAI,SAAS,GAAG,CAAC,CAAC;IAElB,sDAAsD;IACtD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE;QACpB,IAAI,CAAC,CAAC,WAAW,EAAE,KAAK,CAAC,CAAC,WAAW,EAAE,EAAE,CAAC;YACxC,OAAO,CAAC,CAAC,WAAW,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;QAClC,CAAC;QACD,OAAO,CAAC,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;IACtC,CAAC,CAAC,CAAC;IAEH,KAAK,MAAM,KAAK,IAAI,OAAO,EAAE,CAAC;QAC5B,mEAAmE;QACnE,MAAM,SAAS,GAAG,CAAC,MAAM,EAAE,cAAc,EAAE,MAAM,EAAE,OAAO,EAAE,KAAK,EAAE,OAAO,EAAE,OAAO,EAAE,UAAU,EAAE,mBAAmB,EAAE,WAAW,CAAC,CAAC;QACnI,IAAI,SAAS,CAAC,QAAQ,CAAC,KAAK,CAAC,IAAI,CAAC;YAAE,SAAS;QAE7C,IAAI,QAAQ,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC;YAAE,SAAS;QACvC,IAAI,YAAY,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC;YAAE,SAAS;QAC3C,IAAI,KAAK,CAAC,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,KAAK,CAAC,MAAM,EAAE;YAAE,SAAS;QAE3D,IAAI,KAAK,CAAC,WAAW,EAAE,EAAE,CAAC;YACxB,MAAM,OAAO,GAAG,aAAa,CAC3B,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,KAAK,CAAC,IAAI,CAAC,EAC9B,QAAQ,EACR,KAAK,GAAG,CAAC,CACV,CAAC;YACF,IAAI,OAAO,EAAE,CAAC;gBACZ,QAAQ,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;YACzB,CAAC;QACH,CAAC;aAAM,IAAI,KAAK,CAAC,MAAM,EAAE,EAAE,CAAC;YAC1B,IAAI,SAAS,IAAI,SAAS;gBAAE,SAAS;YACrC,SAAS,EAAE,CAAC;YAEZ,MAAM,GAAG,GAAG,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;YACrC,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,KAAK,CAAC,IAAI,CAAC,CAAC;YAChD,IAAI,SAA6B,CAAC;YAElC,IAAI,CAAC;gBACH,MAAM,IAAI,GAAG,EAAE,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC;gBACnC,SAAS,GAAG,IAAI,CAAC,IAAI,CAAC;YACxB,CAAC;YAAC,MAAM,CAAC;gBACP,qBAAqB;YACvB,CAAC;YAED,MAAM,SAAS,GAAc;gBAC3B,IAAI,EAAE,KAAK,CAAC,IAAI;gBAChB,KAAK,EAAE,KAAK;gBACZ,SAAS;aACV,CAAC;YAEF,gEAAgE;YAChE,IAAI,eAAe,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,SAAS,IAAI,SAAS,GAAG,OAAO,EAAE,CAAC;gBACjE,MAAM,OAAO,GAAG,cAAc,CAAC,QAAQ,EAAE,GAAG,CAAC,CAAC;gBAC9C,IAAI,OAAO,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;oBACvB,SAAS,CAAC,OAAO,GAAG,OAAO,CAAC;gBAC9B,CAAC;YACH,CAAC;YAED,QAAQ,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;QAC3B,CAAC;IACH,CAAC;IAED,IAAI,QAAQ,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,IAAI,CAAC;IAEvC,OAAO;QACL,IAAI,EAAE,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC;QAC5B,KAAK,EAAE,IAAI;QACX,QAAQ;KACT,CAAC;AACJ,CAAC;AAED,yEAAyE;AAEzE,SAAS,cAAc,CAAC,QAAgB,EAAE,GAAW;IACnD,IAAI,CAAC;QACH,MAAM,OAAO,GAAG,EAAE,CAAC,YAAY,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;QACnD,MAAM,OAAO,GAAa,EAAE,CAAC;QAE7B,IAAI,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,CAAC,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC;YACjD,6GAA6G;YAC7G,MAAM,QAAQ,GAAG;gBACf,yCAAyC;gBACzC,yBAAyB;gBACzB,qCAAqC;gBACrC,6BAA6B;gBAC7B,wBAAwB;gBACxB,wBAAwB;gBACxB,gDAAgD;aACjD,CAAC;YAEF,KAAK,MAAM,OAAO,IAAI,QAAQ,EAAE,CAAC;gBAC/B,IAAI,KAA6B,CAAC;gBAClC,OAAO,CAAC,KAAK,GAAG,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,KAAK,IAAI,EAAE,CAAC;oBAChD,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;gBACzB,CAAC;YACH,CAAC;QACH,CAAC;aAAM,IAAI,GAAG,KAAK,KAAK,EAAE,CAAC;YACzB,+CAA+C;YAC/C,MAAM,QAAQ,GAAG;gBACf,gBAAgB;gBAChB,kBAAkB;aACnB,CAAC;YACF,KAAK,MAAM,OAAO,IAAI,QAAQ,EAAE,CAAC;gBAC/B,IAAI,KAA6B,CAAC;gBAClC,OAAO,CAAC,KAAK,GAAG,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,KAAK,IAAI,EAAE,CAAC;oBAChD,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;gBACzB,CAAC;YACH,CAAC;QACH,CAAC;aAAM,IAAI,GAAG,KAAK,KAAK,EAAE,CAAC;YACzB,4CAA4C;YAC5C,MAAM,OAAO,GAAG,sBAAsB,CAAC;YACvC,IAAI,KAA6B,CAAC;YAClC,OAAO,CAAC,KAAK,GAAG,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,KAAK,IAAI,EAAE,CAAC;gBAChD,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;YACzB,CAAC;QACH,CAAC;QAED,cAAc;QACd,OAAO,CAAC,GAAG,IAAI,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,kBAAkB;IAC/D,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,EAAE,CAAC;IACZ,CAAC;AACH,CAAC;AAED,sEAAsE;AAEtE,SAAS,UAAU,CAAC,KAAgB,EAAE,MAAc,EAAE,KAAe,EAAE,MAAe;IACpF,IAAI,MAAM,EAAE,CAAC;QACX,KAAK,CAAC,IAAI,CAAC,MAAM,KAAK,CAAC,IAAI,GAAG,CAAC,CAAC;IAClC,CAAC;IAED,IAAI,CAAC,KAAK,CAAC,QAAQ;QAAE,OAAO;IAE5B,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,CAAC,QAAQ,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QAC/C,MAAM,KAAK,GAAG,KAAK,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC;QAChC,MAAM,MAAM,GAAG,CAAC,KAAK,KAAK,CAAC,QAAQ,CAAC,MAAM,GAAG,CAAC,CAAC;QAC/C,MAAM,SAAS,GAAG,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC;QAC3C,MAAM,UAAU,GAAG,MAAM,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC;QAEvD,IAAI,KAAK,CAAC,KAAK,EAAE,CAAC;YAChB,KAAK,CAAC,IAAI,CAAC,GAAG,MAAM,GAAG,SAAS,MAAM,KAAK,CAAC,IAAI,GAAG,CAAC,CAAC;YACrD,UAAU,CAAC,KAAK,EAAE,UAAU,EAAE,KAAK,EAAE,KAAK,CAAC,CAAC;QAC9C,CAAC;aAAM,CAAC;YACN,IAAI,IAAI,GAAG,GAAG,MAAM,GAAG,SAAS,GAAG,KAAK,CAAC,IAAI,EAAE,CAAC;YAEhD,6BAA6B;YAC7B,IAAI,KAAK,CAAC,OAAO,IAAI,KAAK,CAAC,OAAO,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;gBAC9C,MAAM,SAAS,GAAG,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;gBACvD,MAAM,MAAM,GAAG,KAAK,CAAC,OAAO,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC;gBACrD,IAAI,IAAI,QAAQ,SAAS,GAAG,MAAM,GAAG,CAAC;YACxC,CAAC;YAED,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACnB,CAAC;IACH,CAAC;AACH,CAAC;AAED,+DAA+D;AAE/D,SAAS,YAAY,CACnB,KAAgB,EAChB,KAAsC,EACtC,QAA0D,EAC1D,KAAK,GAAG,CAAC;IAET,IAAI,KAAK,GAAG,EAAE;QAAE,OAAO;IACvB,IAAI,KAAK,CAAC,KAAK,EAAE,CAAC;QAChB,KAAK,CAAC,IAAI,EAAE,CAAC;QACb,IAAI,KAAK,CAAC,QAAQ,EAAE,CAAC;YACnB,KAAK,MAAM,KAAK,IAAI,KAAK,CAAC,QAAQ,EAAE,CAAC;gBACnC,YAAY,CAAC,KAAK,EAAE,KAAK,EAAE,GAAG,EAAE,GAAE,CAAC,EAAE,KAAK,GAAG,CAAC,CAAC,CAAC;YAClD,CAAC;QACH,CAAC;IACH,CAAC;SAAM,CAAC;QACN,KAAK,CAAC,KAAK,EAAE,CAAC;IAChB,CAAC;IACD,IAAI,KAAK,KAAK,CAAC,EAAE,CAAC;QAChB,QAAQ,CAAC,KAAK,CAAC,CAAC;IAClB,CAAC;AACH,CAAC"}
|
|
@@ -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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"}
|