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,275 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* syntax-fallback.ts — Pure-JS brace/paren/bracket balance check
|
|
3
|
+
* used as a fallback when no real language server is on the PATH.
|
|
4
|
+
*
|
|
5
|
+
* Why this exists
|
|
6
|
+
* ---------------
|
|
7
|
+
* The LspPreSaveGate calls into `LspManager` to ask the local
|
|
8
|
+
* language server for diagnostics. On a freshly-installed system
|
|
9
|
+
* there is no `tsserver` / `gopls` / `rust-analyzer` on the PATH —
|
|
10
|
+
* the user has a working FixO CLI but no editor infrastructure.
|
|
11
|
+
* In that case the pre-save gate would silently fall through and
|
|
12
|
+
* commit syntactically broken edits.
|
|
13
|
+
*
|
|
14
|
+
* This module provides a *very* cheap structural sanity check
|
|
15
|
+
* (brace/paren/bracket/quote balance) that runs in microseconds
|
|
16
|
+
* and catches the most common form of "LLM forgot a closing
|
|
17
|
+
* brace" corruption. It is intentionally not a real parser — it
|
|
18
|
+
* is a smoke detector, not a smoke alarm. If the syntax check
|
|
19
|
+
* reports `ok`, the real LSP may still surface semantic errors;
|
|
20
|
+
* if it reports `unbalanced`, the file is almost certainly
|
|
21
|
+
* broken and we should refuse the write.
|
|
22
|
+
*
|
|
23
|
+
* The check is env-gated behind `FIXO_LSP_FALLBACK=syntax-only`
|
|
24
|
+
* so a developer who *does* have a language server is never
|
|
25
|
+
* bothered by it.
|
|
26
|
+
*/
|
|
27
|
+
import fs from 'node:fs';
|
|
28
|
+
import path from 'node:path';
|
|
29
|
+
/**
|
|
30
|
+
* Run the structural sanity check on a source string. Pure,
|
|
31
|
+
* sync, and allocation-light. The output is stable so tests can
|
|
32
|
+
* pin the verdict exactly.
|
|
33
|
+
*/
|
|
34
|
+
export function syntaxHealthCheck(source) {
|
|
35
|
+
const stack = [];
|
|
36
|
+
const lineStarts = [0];
|
|
37
|
+
for (let i = 0; i < source.length; i++) {
|
|
38
|
+
if (source.charCodeAt(i) === 10)
|
|
39
|
+
lineStarts.push(i + 1);
|
|
40
|
+
}
|
|
41
|
+
let inSingle = false;
|
|
42
|
+
let inDouble = false;
|
|
43
|
+
let inTemplate = false;
|
|
44
|
+
let inLineComment = false;
|
|
45
|
+
let inBlockComment = false;
|
|
46
|
+
let blockCommentStartLine = 1;
|
|
47
|
+
let singleStartLine = 0;
|
|
48
|
+
let doubleStartLine = 0;
|
|
49
|
+
let templateStartLine = 0;
|
|
50
|
+
let prevCh = '';
|
|
51
|
+
for (let i = 0; i < source.length; i++) {
|
|
52
|
+
const ch = source[i];
|
|
53
|
+
const code = source.charCodeAt(i);
|
|
54
|
+
const nextCh = i + 1 < source.length ? source[i + 1] : '';
|
|
55
|
+
const line = lineNumberAt(lineStarts, i);
|
|
56
|
+
if (inLineComment) {
|
|
57
|
+
if (code === 10)
|
|
58
|
+
inLineComment = false;
|
|
59
|
+
prevCh = ch;
|
|
60
|
+
continue;
|
|
61
|
+
}
|
|
62
|
+
if (inBlockComment) {
|
|
63
|
+
if (prevCh === '*' && ch === '/') {
|
|
64
|
+
inBlockComment = false;
|
|
65
|
+
}
|
|
66
|
+
prevCh = ch;
|
|
67
|
+
continue;
|
|
68
|
+
}
|
|
69
|
+
if (inSingle) {
|
|
70
|
+
if (ch === '\\') {
|
|
71
|
+
// Skip the next char. (No need to handle surrogate pairs
|
|
72
|
+
// separately — `\\u{1F600}` etc. still consume 2 source
|
|
73
|
+
// chars; the skip-i+1 below handles it.)
|
|
74
|
+
i++;
|
|
75
|
+
prevCh = '';
|
|
76
|
+
continue;
|
|
77
|
+
}
|
|
78
|
+
if (ch === "'" && prevCh !== '\\') {
|
|
79
|
+
inSingle = false;
|
|
80
|
+
}
|
|
81
|
+
else if (code === 10) {
|
|
82
|
+
return { state: 'unterminated-string', line: singleStartLine };
|
|
83
|
+
}
|
|
84
|
+
prevCh = ch;
|
|
85
|
+
continue;
|
|
86
|
+
}
|
|
87
|
+
if (inDouble) {
|
|
88
|
+
if (ch === '\\') {
|
|
89
|
+
i++;
|
|
90
|
+
prevCh = '';
|
|
91
|
+
continue;
|
|
92
|
+
}
|
|
93
|
+
if (ch === '"' && prevCh !== '\\') {
|
|
94
|
+
inDouble = false;
|
|
95
|
+
}
|
|
96
|
+
else if (code === 10) {
|
|
97
|
+
return { state: 'unterminated-string', line: doubleStartLine };
|
|
98
|
+
}
|
|
99
|
+
prevCh = ch;
|
|
100
|
+
continue;
|
|
101
|
+
}
|
|
102
|
+
if (inTemplate) {
|
|
103
|
+
if (ch === '\\') {
|
|
104
|
+
i++;
|
|
105
|
+
prevCh = '';
|
|
106
|
+
continue;
|
|
107
|
+
}
|
|
108
|
+
if (ch === '`') {
|
|
109
|
+
inTemplate = false;
|
|
110
|
+
}
|
|
111
|
+
else if (code === 10) {
|
|
112
|
+
return { state: 'unterminated-string', line: templateStartLine };
|
|
113
|
+
}
|
|
114
|
+
prevCh = ch;
|
|
115
|
+
continue;
|
|
116
|
+
}
|
|
117
|
+
// Not in any string/comment — check for new states.
|
|
118
|
+
if (ch === '/' && nextCh === '/') {
|
|
119
|
+
inLineComment = true;
|
|
120
|
+
prevCh = ch;
|
|
121
|
+
i++;
|
|
122
|
+
continue;
|
|
123
|
+
}
|
|
124
|
+
if (ch === '/' && nextCh === '*') {
|
|
125
|
+
inBlockComment = true;
|
|
126
|
+
blockCommentStartLine = line;
|
|
127
|
+
prevCh = ch;
|
|
128
|
+
i++;
|
|
129
|
+
continue;
|
|
130
|
+
}
|
|
131
|
+
if (ch === "'") {
|
|
132
|
+
inSingle = true;
|
|
133
|
+
singleStartLine = line;
|
|
134
|
+
prevCh = ch;
|
|
135
|
+
continue;
|
|
136
|
+
}
|
|
137
|
+
if (ch === '"') {
|
|
138
|
+
inDouble = true;
|
|
139
|
+
doubleStartLine = line;
|
|
140
|
+
prevCh = ch;
|
|
141
|
+
continue;
|
|
142
|
+
}
|
|
143
|
+
if (ch === '`') {
|
|
144
|
+
inTemplate = true;
|
|
145
|
+
templateStartLine = line;
|
|
146
|
+
prevCh = ch;
|
|
147
|
+
continue;
|
|
148
|
+
}
|
|
149
|
+
if (ch === '{' || ch === '(' || ch === '[') {
|
|
150
|
+
stack.push({ ch: ch, line });
|
|
151
|
+
}
|
|
152
|
+
else if (ch === '}' || ch === ')' || ch === ']') {
|
|
153
|
+
const expected = ch === '}' ? '{' : ch === ')' ? '(' : '[';
|
|
154
|
+
const top = stack.pop();
|
|
155
|
+
if (!top || top.ch !== expected) {
|
|
156
|
+
// The first missing closer tells us the first unclosed
|
|
157
|
+
// opener, which is what we report. If the stack is empty
|
|
158
|
+
// we still report a synthetic 'unbalanced' so the caller
|
|
159
|
+
// sees a verdict.
|
|
160
|
+
if (top) {
|
|
161
|
+
return { state: 'unbalanced', opener: top.ch, line: top.line };
|
|
162
|
+
}
|
|
163
|
+
return { state: 'unbalanced', opener: expected, line };
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
prevCh = ch;
|
|
167
|
+
}
|
|
168
|
+
if (inBlockComment) {
|
|
169
|
+
return { state: 'unterminated-comment', line: blockCommentStartLine };
|
|
170
|
+
}
|
|
171
|
+
if (stack.length > 0) {
|
|
172
|
+
const top = stack[stack.length - 1];
|
|
173
|
+
return { state: 'unbalanced', opener: top.ch, line: top.line };
|
|
174
|
+
}
|
|
175
|
+
return { state: 'ok' };
|
|
176
|
+
}
|
|
177
|
+
function lineNumberAt(lineStarts, index) {
|
|
178
|
+
// Binary search would be O(log n) but a linear scan is fine for
|
|
179
|
+
// files up to ~10_000 lines, and the inlined version lets V8
|
|
180
|
+
// keep both arrays hot in the same cache line.
|
|
181
|
+
let line = 1;
|
|
182
|
+
for (let i = 0; i < lineStarts.length; i++) {
|
|
183
|
+
if (lineStarts[i] > index)
|
|
184
|
+
break;
|
|
185
|
+
line = i + 1;
|
|
186
|
+
}
|
|
187
|
+
return line;
|
|
188
|
+
}
|
|
189
|
+
/**
|
|
190
|
+
* Format a {@link SyntaxHealthVerdict} as a single-line summary
|
|
191
|
+
* suitable for the LLM's `tool_result`.
|
|
192
|
+
*/
|
|
193
|
+
export function formatSyntaxVerdict(verdict) {
|
|
194
|
+
switch (verdict.state) {
|
|
195
|
+
case 'ok':
|
|
196
|
+
return 'Syntax health check: OK (balanced).';
|
|
197
|
+
case 'unbalanced':
|
|
198
|
+
return `Syntax health check: unbalanced — '${verdict.opener}' opened on line ${verdict.line} has no matching closer.`;
|
|
199
|
+
case 'unterminated-string':
|
|
200
|
+
return `Syntax health check: unterminated string starting on line ${verdict.line}.`;
|
|
201
|
+
case 'unterminated-comment':
|
|
202
|
+
return `Syntax health check: unterminated block comment starting on line ${verdict.line}.`;
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
const COMMON_LANGUAGE_SERVERS = [
|
|
206
|
+
'typescript-language-server',
|
|
207
|
+
'tsserver',
|
|
208
|
+
'vscode-langservers-extracted',
|
|
209
|
+
'gopls',
|
|
210
|
+
'rust-analyzer',
|
|
211
|
+
'pyright',
|
|
212
|
+
'pylsp',
|
|
213
|
+
'clangd',
|
|
214
|
+
'jdtls',
|
|
215
|
+
'solargraph',
|
|
216
|
+
];
|
|
217
|
+
/**
|
|
218
|
+
* Synchronous PATH check for common language servers. Returns a
|
|
219
|
+
* {@link LspSanityResult} the boot code can use to decide whether
|
|
220
|
+
* to warn the user. Pure — no side effects, no I/O beyond
|
|
221
|
+
* `which`-style PATH scanning.
|
|
222
|
+
*
|
|
223
|
+
* The check is intentionally permissive: a missing language server
|
|
224
|
+
* is a `reason` to warn, not a hard failure. The user can always
|
|
225
|
+
* install one later. The hard fail mode is when neither a
|
|
226
|
+
* language server nor `FIXO_LSP_FALLBACK=syntax-only` is present
|
|
227
|
+
* AND the user has configured `lspPreSave: 'block'` — in that
|
|
228
|
+
* case the pre-save gate would block all writes, which is a much
|
|
229
|
+
* worse experience than a boot-time warning.
|
|
230
|
+
*/
|
|
231
|
+
export function checkLspSanity(env = process.env) {
|
|
232
|
+
const syntaxOnly = env.FIXO_LSP_FALLBACK === 'syntax-only';
|
|
233
|
+
const pathEntries = (env.PATH ?? '').split(path.delimiter).filter(Boolean);
|
|
234
|
+
// `execFileSync('which', ...)` would spawn a child process —
|
|
235
|
+
// expensive and unnecessary. PATH scan is enough: a binary on
|
|
236
|
+
// the PATH is in one of these directories.
|
|
237
|
+
const pathDirs = pathEntries;
|
|
238
|
+
const found = [];
|
|
239
|
+
for (const server of COMMON_LANGUAGE_SERVERS) {
|
|
240
|
+
for (const dir of pathDirs) {
|
|
241
|
+
if (!dir)
|
|
242
|
+
continue;
|
|
243
|
+
try {
|
|
244
|
+
if (fs.existsSync(path.join(dir, server))) {
|
|
245
|
+
found.push(server);
|
|
246
|
+
break;
|
|
247
|
+
}
|
|
248
|
+
}
|
|
249
|
+
catch {
|
|
250
|
+
// ignore
|
|
251
|
+
}
|
|
252
|
+
}
|
|
253
|
+
}
|
|
254
|
+
if (found.length > 0) {
|
|
255
|
+
return { ok: true, reason: '', checked: [...COMMON_LANGUAGE_SERVERS], found, syntaxOnly };
|
|
256
|
+
}
|
|
257
|
+
if (syntaxOnly) {
|
|
258
|
+
return {
|
|
259
|
+
ok: true,
|
|
260
|
+
reason: 'FIXO_LSP_FALLBACK=syntax-only; brace-balance check will run instead of a real LSP.',
|
|
261
|
+
checked: [...COMMON_LANGUAGE_SERVERS],
|
|
262
|
+
found: [],
|
|
263
|
+
syntaxOnly: true,
|
|
264
|
+
};
|
|
265
|
+
}
|
|
266
|
+
return {
|
|
267
|
+
ok: false,
|
|
268
|
+
reason: 'No common language server found on PATH. Pre-save diagnostics will be skipped. ' +
|
|
269
|
+
'Install typescript-language-server / gopls / rust-analyzer or set FIXO_LSP_FALLBACK=syntax-only.',
|
|
270
|
+
checked: [...COMMON_LANGUAGE_SERVERS],
|
|
271
|
+
found: [],
|
|
272
|
+
syntaxOnly: false,
|
|
273
|
+
};
|
|
274
|
+
}
|
|
275
|
+
//# sourceMappingURL=syntax-fallback.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"syntax-fallback.js","sourceRoot":"","sources":["../../src/lsp/syntax-fallback.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
export interface ModelOutcome {
|
|
2
|
+
model: string;
|
|
3
|
+
taskType: string;
|
|
4
|
+
success: boolean;
|
|
5
|
+
latencyMs: number;
|
|
6
|
+
toolCalls: number;
|
|
7
|
+
verificationPassed: boolean | null;
|
|
8
|
+
timestamp: string;
|
|
9
|
+
}
|
|
10
|
+
export declare function recordModelOutcome(cwd: string, outcome: Omit<ModelOutcome, 'timestamp'>): void;
|
|
11
|
+
export declare function summarizeModelOutcomes(cwd: string): string;
|
|
12
|
+
//# sourceMappingURL=model-outcomes.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"model-outcomes.d.ts","sourceRoot":"","sources":["../src/model-outcomes.ts"],"names":[],"mappings":"AAGA,MAAM,WAAW,YAAY;IAC3B,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,OAAO,CAAC;IACjB,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,kBAAkB,EAAE,OAAO,GAAG,IAAI,CAAC;IACnC,SAAS,EAAE,MAAM,CAAC;CACnB;AAID,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,EAAE,IAAI,CAAC,YAAY,EAAE,WAAW,CAAC,GAAG,IAAI,CAM9F;AAeD,wBAAgB,sBAAsB,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAmB1D"}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import fs from 'fs';
|
|
2
|
+
import path from 'path';
|
|
3
|
+
const MAX_OUTCOMES = 100;
|
|
4
|
+
export function recordModelOutcome(cwd, outcome) {
|
|
5
|
+
const dir = path.join(cwd, '.fixo');
|
|
6
|
+
fs.mkdirSync(dir, { recursive: true });
|
|
7
|
+
const file = path.join(dir, 'model-outcomes.jsonl');
|
|
8
|
+
fs.appendFileSync(file, JSON.stringify({ ...outcome, timestamp: new Date().toISOString() }) + '\n', 'utf-8');
|
|
9
|
+
pruneOutcomes(file);
|
|
10
|
+
}
|
|
11
|
+
function pruneOutcomes(file) {
|
|
12
|
+
try {
|
|
13
|
+
const content = fs.readFileSync(file, 'utf-8');
|
|
14
|
+
const lines = content.split('\n').filter(Boolean);
|
|
15
|
+
if (lines.length <= MAX_OUTCOMES)
|
|
16
|
+
return;
|
|
17
|
+
fs.writeFileSync(file, lines.slice(lines.length - MAX_OUTCOMES).join('\n') + '\n', 'utf-8');
|
|
18
|
+
}
|
|
19
|
+
catch (error) {
|
|
20
|
+
if (process.env.DEBUG || process.env.VERBOSE || process.argv.includes('--verbose')) {
|
|
21
|
+
console.warn(`[Debug Warning] Failed to prune model outcomes from ${file}: ${error.message || error}`);
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
export function summarizeModelOutcomes(cwd) {
|
|
26
|
+
const file = path.join(cwd, '.fixo', 'model-outcomes.jsonl');
|
|
27
|
+
if (!fs.existsSync(file))
|
|
28
|
+
return 'No model outcomes recorded.';
|
|
29
|
+
const rows = fs.readFileSync(file, 'utf-8')
|
|
30
|
+
.split('\n')
|
|
31
|
+
.filter(Boolean)
|
|
32
|
+
.map(line => JSON.parse(line));
|
|
33
|
+
const byModel = new Map();
|
|
34
|
+
for (const row of rows) {
|
|
35
|
+
const entry = byModel.get(row.model) ?? { total: 0, success: 0, latency: 0, verified: 0 };
|
|
36
|
+
entry.total++;
|
|
37
|
+
if (row.success)
|
|
38
|
+
entry.success++;
|
|
39
|
+
if (row.verificationPassed)
|
|
40
|
+
entry.verified++;
|
|
41
|
+
entry.latency += row.latencyMs;
|
|
42
|
+
byModel.set(row.model, entry);
|
|
43
|
+
}
|
|
44
|
+
return Array.from(byModel.entries()).map(([model, entry]) => `${model}: ${entry.success}/${entry.total} success, ${entry.verified}/${entry.total} verified, avg ${(entry.latency / entry.total / 1000).toFixed(1)}s`).join('\n');
|
|
45
|
+
}
|
|
46
|
+
//# sourceMappingURL=model-outcomes.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"model-outcomes.js","sourceRoot":"","sources":["../src/model-outcomes.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Re-exported here so external callers (e.g. `SingleAgent`,
|
|
3
|
+
* telemetry sinks) can import the entire loop-trap surface from
|
|
4
|
+
* `src/planner.ts` without taking a hard dependency on the
|
|
5
|
+
* `src/runtime/` directory layout. The implementation lives in
|
|
6
|
+
* `src/runtime/loop-trap.ts`; this file is the public façade.
|
|
7
|
+
*/
|
|
8
|
+
export { LoopTrapDetector, LoopTrapAbortedError, DEFAULT_LOOP_TRAP_PREFS, canonicaliseArgs, } from './runtime/loop-trap.js';
|
|
9
|
+
export type { LoopSnapshot, LoopTrapVerdict, LoopTrapLayer, LoopTrapPreferences, } from './runtime/loop-trap.js';
|
|
10
|
+
export interface SavedPlan {
|
|
11
|
+
task: string;
|
|
12
|
+
createdAt: string;
|
|
13
|
+
taskType: 'chat' | 'review' | 'mutation' | 'test-fix' | 'refactor' | 'investigation';
|
|
14
|
+
expectedFiles: string[];
|
|
15
|
+
verificationCommand: string | null;
|
|
16
|
+
stages: string[];
|
|
17
|
+
}
|
|
18
|
+
export declare function createStructuredPlan(task: string): SavedPlan;
|
|
19
|
+
export declare function validatePlan(plan: unknown): plan is SavedPlan;
|
|
20
|
+
export declare function savePlan(cwd: string, task: string): SavedPlan;
|
|
21
|
+
export declare function loadPlan(cwd: string): SavedPlan | null;
|
|
22
|
+
export declare function renderPlan(plan: SavedPlan): string;
|
|
23
|
+
export declare const TRIVIAL_PATTERNS: RegExp[];
|
|
24
|
+
export declare function isTrivialQuery(input: string): boolean;
|
|
25
|
+
export interface ComplexityClassification {
|
|
26
|
+
complexity: 'simple' | 'complex';
|
|
27
|
+
reason: string;
|
|
28
|
+
}
|
|
29
|
+
export declare function classifyComplexityHeuristic(task: string): ComplexityClassification;
|
|
30
|
+
import type { AgentClient } from './agent/agent-client.js';
|
|
31
|
+
export declare function classifyComplexityModel(task: string, model: string, client: AgentClient): Promise<ComplexityClassification>;
|
|
32
|
+
//# sourceMappingURL=planner.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"planner.d.ts","sourceRoot":"","sources":["../src/planner.ts"],"names":[],"mappings":"AAKA;;;;;;GAMG;AACH,OAAO,EACL,gBAAgB,EAChB,oBAAoB,EACpB,uBAAuB,EACvB,gBAAgB,GACjB,MAAM,wBAAwB,CAAC;AAEhC,YAAY,EACV,YAAY,EACZ,eAAe,EACf,aAAa,EACb,mBAAmB,GACpB,MAAM,wBAAwB,CAAC;AAEhC,MAAM,WAAW,SAAS;IACxB,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,MAAM,GAAG,QAAQ,GAAG,UAAU,GAAG,UAAU,GAAG,UAAU,GAAG,eAAe,CAAC;IACrF,aAAa,EAAE,MAAM,EAAE,CAAC;IACxB,mBAAmB,EAAE,MAAM,GAAG,IAAI,CAAC;IACnC,MAAM,EAAE,MAAM,EAAE,CAAC;CAClB;AAUD,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,MAAM,GAAG,SAAS,CAsB5D;AAED,wBAAgB,YAAY,CAAC,IAAI,EAAE,OAAO,GAAG,IAAI,IAAI,SAAS,CAS7D;AAED,wBAAgB,QAAQ,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,SAAS,CAM7D;AAED,wBAAgB,QAAQ,CAAC,GAAG,EAAE,MAAM,GAAG,SAAS,GAAG,IAAI,CAKtD;AAED,wBAAgB,UAAU,CAAC,IAAI,EAAE,SAAS,GAAG,MAAM,CASlD;AAID,eAAO,MAAM,gBAAgB,UAO5B,CAAC;AAEF,wBAAgB,cAAc,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAUrD;AAID,MAAM,WAAW,wBAAwB;IACvC,UAAU,EAAE,QAAQ,GAAG,SAAS,CAAC;IACjC,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,wBAAgB,2BAA2B,CAAC,IAAI,EAAE,MAAM,GAAG,wBAAwB,CA8BlF;AAED,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,yBAAyB,CAAC;AAE3D,wBAAsB,uBAAuB,CAC3C,IAAI,EAAE,MAAM,EACZ,KAAK,EAAE,MAAM,EACb,MAAM,EAAE,WAAW,GAClB,OAAO,CAAC,wBAAwB,CAAC,CA4CnC"}
|
package/dist/planner.js
ADDED
|
@@ -0,0 +1,163 @@
|
|
|
1
|
+
import fs from 'fs';
|
|
2
|
+
import path from 'path';
|
|
3
|
+
/* ──────────────────────── Loop-Trap Detector Re-Exports ─────────────────── */
|
|
4
|
+
/**
|
|
5
|
+
* Re-exported here so external callers (e.g. `SingleAgent`,
|
|
6
|
+
* telemetry sinks) can import the entire loop-trap surface from
|
|
7
|
+
* `src/planner.ts` without taking a hard dependency on the
|
|
8
|
+
* `src/runtime/` directory layout. The implementation lives in
|
|
9
|
+
* `src/runtime/loop-trap.ts`; this file is the public façade.
|
|
10
|
+
*/
|
|
11
|
+
export { LoopTrapDetector, LoopTrapAbortedError, DEFAULT_LOOP_TRAP_PREFS, canonicaliseArgs, } from './runtime/loop-trap.js';
|
|
12
|
+
const DEFAULT_STAGES = [
|
|
13
|
+
'Understand: inspect indexed context and relevant files before editing.',
|
|
14
|
+
'Plan: choose patch-based edits and expected verification command.',
|
|
15
|
+
'Act: apply minimal workspace-scoped changes through guarded tools.',
|
|
16
|
+
'Verify: run detected checks or configured checkCommand.',
|
|
17
|
+
'Summarize: report changed files, checks, and residual risk.',
|
|
18
|
+
];
|
|
19
|
+
export function createStructuredPlan(task) {
|
|
20
|
+
const lower = task.toLowerCase();
|
|
21
|
+
const taskType = lower.includes('review') ? 'review'
|
|
22
|
+
: lower.includes('test') || lower.includes('failing') ? 'test-fix'
|
|
23
|
+
: lower.includes('refactor') ? 'refactor'
|
|
24
|
+
: /explain|what|why|how|list|show/.test(lower) ? 'investigation'
|
|
25
|
+
: /^(hi|hello|hey|thanks|thank you|ok|bye)\b/.test(lower) ? 'chat'
|
|
26
|
+
: 'mutation';
|
|
27
|
+
const extensions = '(ts|tsx|js|jsx|mjs|cjs|py|go|rs|java|rb|php|css|scss|json|md|yml|yaml|toml|sh|bash|txt|html|vue|svelte)';
|
|
28
|
+
const expectedFiles = Array.from(task.matchAll(new RegExp(`\\b([\\w./-]+\\.${extensions})\\b`, 'gi'))).map(match => match[1]);
|
|
29
|
+
const verificationCommand = taskType === 'chat' || taskType === 'investigation' || taskType === 'review'
|
|
30
|
+
? null
|
|
31
|
+
: 'auto-detect';
|
|
32
|
+
return {
|
|
33
|
+
task,
|
|
34
|
+
taskType,
|
|
35
|
+
expectedFiles,
|
|
36
|
+
verificationCommand,
|
|
37
|
+
createdAt: new Date().toISOString(),
|
|
38
|
+
stages: DEFAULT_STAGES,
|
|
39
|
+
};
|
|
40
|
+
}
|
|
41
|
+
export function validatePlan(plan) {
|
|
42
|
+
if (!plan || typeof plan !== 'object')
|
|
43
|
+
return false;
|
|
44
|
+
const p = plan;
|
|
45
|
+
return typeof p.task === 'string'
|
|
46
|
+
&& typeof p.createdAt === 'string'
|
|
47
|
+
&& ['chat', 'review', 'mutation', 'test-fix', 'refactor', 'investigation'].includes(p.taskType)
|
|
48
|
+
&& Array.isArray(p.expectedFiles)
|
|
49
|
+
&& (typeof p.verificationCommand === 'string' || p.verificationCommand === null)
|
|
50
|
+
&& Array.isArray(p.stages);
|
|
51
|
+
}
|
|
52
|
+
export function savePlan(cwd, task) {
|
|
53
|
+
const plan = createStructuredPlan(task);
|
|
54
|
+
const dir = path.join(cwd, '.fixo');
|
|
55
|
+
fs.mkdirSync(dir, { recursive: true });
|
|
56
|
+
fs.writeFileSync(path.join(dir, 'last-plan.json'), JSON.stringify(plan, null, 2) + '\n', 'utf-8');
|
|
57
|
+
return plan;
|
|
58
|
+
}
|
|
59
|
+
export function loadPlan(cwd) {
|
|
60
|
+
const file = path.join(cwd, '.fixo', 'last-plan.json');
|
|
61
|
+
if (!fs.existsSync(file))
|
|
62
|
+
return null;
|
|
63
|
+
const parsed = JSON.parse(fs.readFileSync(file, 'utf-8'));
|
|
64
|
+
return validatePlan(parsed) ? parsed : null;
|
|
65
|
+
}
|
|
66
|
+
export function renderPlan(plan) {
|
|
67
|
+
return [
|
|
68
|
+
`Task: ${plan.task}`,
|
|
69
|
+
`Type: ${plan.taskType}`,
|
|
70
|
+
`Created: ${plan.createdAt}`,
|
|
71
|
+
`Expected files: ${plan.expectedFiles.join(', ') || '(none)'}`,
|
|
72
|
+
`Verification: ${plan.verificationCommand ?? '(none)'}`,
|
|
73
|
+
...plan.stages.map((stage, index) => `${index + 1}. ${stage}`),
|
|
74
|
+
].join('\n');
|
|
75
|
+
}
|
|
76
|
+
/* ──────────────────────── Trivial Query Detection ──────────────────────── */
|
|
77
|
+
export const TRIVIAL_PATTERNS = [
|
|
78
|
+
/^(hi|hey|hello|howdy|yo|sup|greetings|hola|namaste)/i,
|
|
79
|
+
/^(thanks|thank you|thx|ty|cheers)/i,
|
|
80
|
+
/^(what can you do|who are you|help me|how does this work)/i,
|
|
81
|
+
/^(good morning|good evening|good night|gm|gn)/i,
|
|
82
|
+
/^(ok|okay|sure|great|nice|cool|awesome|perfect|got it)/i,
|
|
83
|
+
/^(bye|goodbye|see you|later|exit|quit)/i,
|
|
84
|
+
];
|
|
85
|
+
export function isTrivialQuery(input) {
|
|
86
|
+
const trimmed = input.trim();
|
|
87
|
+
if (trimmed.length < 3)
|
|
88
|
+
return true;
|
|
89
|
+
if (trimmed.length > 100)
|
|
90
|
+
return false; // Long inputs are usually tasks
|
|
91
|
+
for (const pattern of TRIVIAL_PATTERNS) {
|
|
92
|
+
if (pattern.test(trimmed))
|
|
93
|
+
return true;
|
|
94
|
+
}
|
|
95
|
+
return false;
|
|
96
|
+
}
|
|
97
|
+
export function classifyComplexityHeuristic(task) {
|
|
98
|
+
const trimmed = task.trim();
|
|
99
|
+
if (isTrivialQuery(trimmed)) {
|
|
100
|
+
return { complexity: 'simple', reason: 'Trivial chat query' };
|
|
101
|
+
}
|
|
102
|
+
const plan = createStructuredPlan(trimmed);
|
|
103
|
+
if (plan.taskType === 'chat' || plan.taskType === 'investigation' || plan.taskType === 'review') {
|
|
104
|
+
return { complexity: 'simple', reason: `Task type is ${plan.taskType}` };
|
|
105
|
+
}
|
|
106
|
+
// Check expected files.
|
|
107
|
+
if (plan.expectedFiles.length > 1) {
|
|
108
|
+
return { complexity: 'complex', reason: `Affects multiple files: ${plan.expectedFiles.join(', ')}` };
|
|
109
|
+
}
|
|
110
|
+
// Keywords that hint at complex operations
|
|
111
|
+
const complexKeywords = [
|
|
112
|
+
'system-wide', 'across the codebase', 'all files', 'every file', 'refactor the entire',
|
|
113
|
+
'multiple modules', 'architecture', 'orchestration', 'parallel', 'concurrent'
|
|
114
|
+
];
|
|
115
|
+
const lower = trimmed.toLowerCase();
|
|
116
|
+
for (const kw of complexKeywords) {
|
|
117
|
+
if (lower.includes(kw)) {
|
|
118
|
+
return { complexity: 'complex', reason: `Contains complexity keyword: "${kw}"` };
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
// Simple edits / single file modifications are default simple
|
|
122
|
+
return { complexity: 'simple', reason: 'Single-file or narrow mutation scope' };
|
|
123
|
+
}
|
|
124
|
+
export async function classifyComplexityModel(task, model, client) {
|
|
125
|
+
const heuristic = classifyComplexityHeuristic(task);
|
|
126
|
+
// If heuristic is already complex, or if it is trivially simple, return it to save latency/tokens.
|
|
127
|
+
if (heuristic.complexity === 'complex' || heuristic.reason.startsWith('Trivial')) {
|
|
128
|
+
return heuristic;
|
|
129
|
+
}
|
|
130
|
+
const systemPrompt = `You are the FixO Complexity Classifier. Your job is to classify if a software engineering task is SIMPLE or COMPLEX.
|
|
131
|
+
|
|
132
|
+
CRITERIA:
|
|
133
|
+
- SIMPLE: Questions, explanations, conceptual reviews, single-file mutations (e.g. adding a field, fixing a minor bug, writing a test for a single file), or basic script creation.
|
|
134
|
+
- COMPLEX: Multi-file changes, large refactoring, integration changes across layers (e.g. modifying both frontend and backend, changing API contracts between multiple files), or anything requiring parallel execution of subtasks.
|
|
135
|
+
|
|
136
|
+
Output ONLY a JSON object:
|
|
137
|
+
{
|
|
138
|
+
"complexity": "simple" | "complex",
|
|
139
|
+
"reason": "short explanation of the decision"
|
|
140
|
+
}
|
|
141
|
+
NO markdown formatting, NO backticks, and NO conversational text.`;
|
|
142
|
+
try {
|
|
143
|
+
const response = await client.chat([
|
|
144
|
+
{ role: 'system', content: systemPrompt },
|
|
145
|
+
{ role: 'user', content: task }
|
|
146
|
+
], model, { agent_task_type: 'investigation', required_capabilities: ['fast'] });
|
|
147
|
+
const content = response.content?.trim() || '';
|
|
148
|
+
// Clean JSON from potential markdown blocks
|
|
149
|
+
const jsonMatch = content.match(/\{[\s\S]*\}/);
|
|
150
|
+
const parsed = JSON.parse(jsonMatch ? jsonMatch[0] : content);
|
|
151
|
+
if (parsed && (parsed.complexity === 'simple' || parsed.complexity === 'complex')) {
|
|
152
|
+
return {
|
|
153
|
+
complexity: parsed.complexity,
|
|
154
|
+
reason: parsed.reason || 'Model classification'
|
|
155
|
+
};
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
catch (err) {
|
|
159
|
+
// Fallback to heuristic
|
|
160
|
+
}
|
|
161
|
+
return heuristic;
|
|
162
|
+
}
|
|
163
|
+
//# sourceMappingURL=planner.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"planner.js","sourceRoot":"","sources":["../src/planner.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
export interface ProjectFacts {
|
|
2
|
+
packageManager: 'npm' | 'pnpm' | 'yarn' | 'unknown';
|
|
3
|
+
scripts: Record<string, string>;
|
|
4
|
+
testCommands: string[];
|
|
5
|
+
buildCommands: string[];
|
|
6
|
+
tsconfigs: string[];
|
|
7
|
+
updatedAt: string;
|
|
8
|
+
allowRules: {
|
|
9
|
+
commands: string[];
|
|
10
|
+
};
|
|
11
|
+
}
|
|
12
|
+
export declare function detectProjectFacts(cwd: string): ProjectFacts;
|
|
13
|
+
import { DatabaseSync } from 'node:sqlite';
|
|
14
|
+
export declare function getDb(cwd: string): DatabaseSync;
|
|
15
|
+
export declare function calculateTfidfSimilarity(query: string, documents: string[]): number[];
|
|
16
|
+
export declare function retrieveRelevantFacts(cwd: string, query: string, client?: any, limit?: number): Promise<string[]>;
|
|
17
|
+
export declare function appendSessionSummary(cwd: string, summary: string): void;
|
|
18
|
+
export declare function readSessionHistory(cwd: string): string[];
|
|
19
|
+
export declare function memoryDir(cwd: string): string;
|
|
20
|
+
export declare function ensureProjectMemory(cwd: string): ProjectFacts;
|
|
21
|
+
export declare function readMemory(cwd: string): string;
|
|
22
|
+
export declare function appendMemory(cwd: string, text: string): void;
|
|
23
|
+
export declare function readAllowRules(cwd: string): {
|
|
24
|
+
commands: string[];
|
|
25
|
+
};
|
|
26
|
+
export declare function allowCommand(cwd: string, command: string): void;
|
|
27
|
+
export declare function forgetMemory(cwd: string): void;
|
|
28
|
+
export declare function doctor(cwd: string): string;
|
|
29
|
+
//# sourceMappingURL=project-memory.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"project-memory.d.ts","sourceRoot":"","sources":["../src/project-memory.ts"],"names":[],"mappings":"AAGA,MAAM,WAAW,YAAY;IAC3B,cAAc,EAAE,KAAK,GAAG,MAAM,GAAG,MAAM,GAAG,SAAS,CAAC;IACpD,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAChC,YAAY,EAAE,MAAM,EAAE,CAAC;IACvB,aAAa,EAAE,MAAM,EAAE,CAAC;IACxB,SAAS,EAAE,MAAM,EAAE,CAAC;IACpB,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE;QACV,QAAQ,EAAE,MAAM,EAAE,CAAC;KACpB,CAAC;CACH;AAED,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,MAAM,GAAG,YAAY,CA8B5D;AAED,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAM3C,wBAAgB,KAAK,CAAC,GAAG,EAAE,MAAM,GAAG,YAAY,CAiE/C;AAED,wBAAgB,wBAAwB,CAAC,KAAK,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,GAAG,MAAM,EAAE,CA4ErF;AAgBD,wBAAsB,qBAAqB,CACzC,GAAG,EAAE,MAAM,EACX,KAAK,EAAE,MAAM,EACb,MAAM,CAAC,EAAE,GAAG,EACZ,KAAK,SAAI,GACR,OAAO,CAAC,MAAM,EAAE,CAAC,CAmEnB;AAED,wBAAgB,oBAAoB,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,IAAI,CAIvE;AAED,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,EAAE,CAKxD;AAED,wBAAgB,SAAS,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAE7C;AAED,wBAAgB,mBAAmB,CAAC,GAAG,EAAE,MAAM,GAAG,YAAY,CAQ7D;AAED,wBAAgB,UAAU,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAQ9C;AAED,wBAAgB,YAAY,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,IAAI,CAK5D;AAED,wBAAgB,cAAc,CAAC,GAAG,EAAE,MAAM,GAAG;IAAE,QAAQ,EAAE,MAAM,EAAE,CAAA;CAAE,CAYlE;AAED,wBAAgB,YAAY,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,IAAI,CAM/D;AAED,wBAAgB,YAAY,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,CAG9C;AAED,wBAAgB,MAAM,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAmB1C"}
|