fixo-cli 1.0.4 → 2.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.
Potentially problematic release.
This version of fixo-cli might be problematic. Click here for more details.
- package/CHANGELOG.md +62 -0
- package/README.md +18 -14
- package/dist/agent/agent-client.d.ts +28 -6
- package/dist/agent/agent-client.d.ts.map +1 -1
- package/dist/agent/agent-client.js +118 -39
- package/dist/agent/agent-client.js.map +1 -1
- package/dist/agent/agent-pool.d.ts +55 -6
- package/dist/agent/agent-pool.d.ts.map +1 -1
- package/dist/agent/agent-pool.js +120 -20
- package/dist/agent/agent-pool.js.map +1 -1
- package/dist/agent/auto-verifier.d.ts +55 -0
- package/dist/agent/auto-verifier.d.ts.map +1 -0
- package/dist/agent/auto-verifier.js +50 -0
- package/dist/agent/auto-verifier.js.map +1 -0
- package/dist/agent/command-parser.d.ts.map +1 -1
- package/dist/agent/command-parser.js +176 -0
- package/dist/agent/command-parser.js.map +1 -1
- package/dist/agent/context-builder.d.ts +24 -0
- package/dist/agent/context-builder.d.ts.map +1 -0
- package/dist/agent/context-builder.js +197 -0
- package/dist/agent/context-builder.js.map +1 -0
- package/dist/agent/conversation.d.ts +14 -1
- package/dist/agent/conversation.d.ts.map +1 -1
- package/dist/agent/conversation.js +53 -7
- package/dist/agent/conversation.js.map +1 -1
- package/dist/agent/mcp-bridge.js +1 -1
- package/dist/agent/mcp-bridge.js.map +1 -1
- package/dist/agent/orchestrator.d.ts +45 -0
- package/dist/agent/orchestrator.d.ts.map +1 -1
- package/dist/agent/orchestrator.js +140 -3
- package/dist/agent/orchestrator.js.map +1 -1
- package/dist/agent/parser-adapter.d.ts +17 -0
- package/dist/agent/parser-adapter.d.ts.map +1 -1
- package/dist/agent/parser-adapter.js +254 -2
- package/dist/agent/parser-adapter.js.map +1 -1
- package/dist/agent/predictive-gate.d.ts.map +1 -1
- package/dist/agent/predictive-gate.js +4 -1
- package/dist/agent/predictive-gate.js.map +1 -1
- package/dist/agent/providers-manager.d.ts +5 -0
- package/dist/agent/providers-manager.d.ts.map +1 -1
- package/dist/agent/providers-manager.js +119 -8
- package/dist/agent/providers-manager.js.map +1 -1
- package/dist/agent/repo-map.d.ts +18 -1
- package/dist/agent/repo-map.d.ts.map +1 -1
- package/dist/agent/repo-map.js +144 -54
- package/dist/agent/repo-map.js.map +1 -1
- package/dist/agent/retry.js +1 -2
- package/dist/agent/retry.js.map +1 -1
- package/dist/agent/single-agent.d.ts.map +1 -1
- package/dist/agent/single-agent.js +129 -22
- package/dist/agent/single-agent.js.map +1 -1
- package/dist/agent/skills.d.ts.map +1 -1
- package/dist/agent/skills.js +2 -1
- package/dist/agent/skills.js.map +1 -1
- package/dist/agent/subagent.js +2 -2
- package/dist/agent/subagent.js.map +1 -1
- package/dist/agent/task-router.d.ts +46 -0
- package/dist/agent/task-router.d.ts.map +1 -0
- package/dist/agent/task-router.js +352 -0
- package/dist/agent/task-router.js.map +1 -0
- package/dist/agent/telemetry.d.ts +29 -1
- package/dist/agent/telemetry.d.ts.map +1 -1
- package/dist/agent/telemetry.js +25 -10
- package/dist/agent/telemetry.js.map +1 -1
- package/dist/agent/tool-definitions.d.ts +3 -0
- package/dist/agent/tool-definitions.d.ts.map +1 -0
- package/dist/agent/tool-definitions.js +519 -0
- package/dist/agent/tool-definitions.js.map +1 -0
- package/dist/agent/tool-executor.d.ts +6 -1
- package/dist/agent/tool-executor.d.ts.map +1 -1
- package/dist/agent/tool-executor.js +99 -553
- package/dist/agent/tool-executor.js.map +1 -1
- package/dist/agent/tools/command-tools.d.ts +6 -0
- package/dist/agent/tools/command-tools.d.ts.map +1 -0
- package/dist/agent/tools/command-tools.js +104 -0
- package/dist/agent/tools/command-tools.js.map +1 -0
- package/dist/agent/tools/file-tools.d.ts +15 -0
- package/dist/agent/tools/file-tools.d.ts.map +1 -0
- package/dist/agent/tools/file-tools.js +551 -0
- package/dist/agent/tools/file-tools.js.map +1 -0
- package/dist/agent/tools/todo-tools.d.ts +3 -0
- package/dist/agent/tools/todo-tools.d.ts.map +1 -0
- package/dist/agent/tools/todo-tools.js +70 -0
- package/dist/agent/tools/todo-tools.js.map +1 -0
- package/dist/agent/web-impl.d.ts.map +1 -1
- package/dist/agent/web-impl.js +45 -0
- package/dist/agent/web-impl.js.map +1 -1
- package/dist/agent/worker-agent.d.ts +3 -1
- package/dist/agent/worker-agent.d.ts.map +1 -1
- package/dist/agent/worker-agent.js +51 -14
- package/dist/agent/worker-agent.js.map +1 -1
- package/dist/config.d.ts +242 -0
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +79 -0
- package/dist/config.js.map +1 -1
- package/dist/git/git-manager.d.ts +33 -2
- package/dist/git/git-manager.d.ts.map +1 -1
- package/dist/git/git-manager.js +111 -15
- package/dist/git/git-manager.js.map +1 -1
- package/dist/git/git-ops.d.ts.map +1 -1
- package/dist/git/git-ops.js +2 -1
- package/dist/git/git-ops.js.map +1 -1
- package/dist/index.js +85 -8
- package/dist/index.js.map +1 -1
- package/dist/lsp/lsp-manager.js +1 -1
- package/dist/lsp/lsp-manager.js.map +1 -1
- package/dist/model-outcomes.d.ts.map +1 -1
- package/dist/model-outcomes.js +2 -1
- package/dist/model-outcomes.js.map +1 -1
- package/dist/planner.d.ts +0 -9
- package/dist/planner.d.ts.map +1 -1
- package/dist/planner.js +0 -9
- package/dist/planner.js.map +1 -1
- package/dist/project-memory.d.ts +12 -1
- package/dist/project-memory.d.ts.map +1 -1
- package/dist/project-memory.js +8 -6
- package/dist/project-memory.js.map +1 -1
- package/dist/runtime/loop-mitigation.d.ts +78 -7
- package/dist/runtime/loop-mitigation.d.ts.map +1 -1
- package/dist/runtime/loop-mitigation.js +122 -9
- package/dist/runtime/loop-mitigation.js.map +1 -1
- package/dist/runtime/os-sandbox.d.ts +100 -0
- package/dist/runtime/os-sandbox.d.ts.map +1 -0
- package/dist/runtime/os-sandbox.js +246 -0
- package/dist/runtime/os-sandbox.js.map +1 -0
- package/dist/runtime/run-inventory.d.ts +17 -0
- package/dist/runtime/run-inventory.d.ts.map +1 -0
- package/dist/runtime/run-inventory.js +49 -0
- package/dist/runtime/run-inventory.js.map +1 -0
- package/dist/runtime/staging.d.ts.map +1 -1
- package/dist/runtime/staging.js +4 -1
- package/dist/runtime/staging.js.map +1 -1
- package/dist/runtime/task-session.d.ts +14 -0
- package/dist/runtime/task-session.d.ts.map +1 -1
- package/dist/runtime/task-session.js +26 -0
- package/dist/runtime/task-session.js.map +1 -1
- package/dist/setup-wizard.d.ts +11 -3
- package/dist/setup-wizard.d.ts.map +1 -1
- package/dist/setup-wizard.js +113 -15
- package/dist/setup-wizard.js.map +1 -1
- package/dist/types.d.ts +8 -0
- package/dist/types.d.ts.map +1 -1
- package/dist/ui/commands/context-commands.d.ts +7 -0
- package/dist/ui/commands/context-commands.d.ts.map +1 -0
- package/dist/ui/commands/context-commands.js +241 -0
- package/dist/ui/commands/context-commands.js.map +1 -0
- package/dist/ui/commands/index.d.ts +3 -0
- package/dist/ui/commands/index.d.ts.map +1 -0
- package/dist/ui/commands/index.js +46 -0
- package/dist/ui/commands/index.js.map +1 -0
- package/dist/ui/commands/info-commands.d.ts +15 -0
- package/dist/ui/commands/info-commands.d.ts.map +1 -0
- package/dist/ui/commands/info-commands.js +122 -0
- package/dist/ui/commands/info-commands.js.map +1 -0
- package/dist/ui/commands/model-commands.d.ts +5 -0
- package/dist/ui/commands/model-commands.d.ts.map +1 -0
- package/dist/ui/commands/model-commands.js +417 -0
- package/dist/ui/commands/model-commands.js.map +1 -0
- package/dist/ui/commands/session-commands.d.ts +5 -0
- package/dist/ui/commands/session-commands.d.ts.map +1 -0
- package/dist/ui/commands/session-commands.js +154 -0
- package/dist/ui/commands/session-commands.js.map +1 -0
- package/dist/ui/commands/task-commands.d.ts +8 -0
- package/dist/ui/commands/task-commands.d.ts.map +1 -0
- package/dist/ui/commands/task-commands.js +152 -0
- package/dist/ui/commands/task-commands.js.map +1 -0
- package/dist/ui/commands/types.d.ts +46 -0
- package/dist/ui/commands/types.d.ts.map +1 -0
- package/dist/ui/commands/types.js +2 -0
- package/dist/ui/commands/types.js.map +1 -0
- package/dist/ui/commands/workspace-commands.d.ts +8 -0
- package/dist/ui/commands/workspace-commands.d.ts.map +1 -0
- package/dist/ui/commands/workspace-commands.js +131 -0
- package/dist/ui/commands/workspace-commands.js.map +1 -0
- package/dist/ui/loading-animation.d.ts +24 -0
- package/dist/ui/loading-animation.d.ts.map +1 -0
- package/dist/ui/loading-animation.js +123 -0
- package/dist/ui/loading-animation.js.map +1 -0
- package/dist/ui/markdown-stream.js +2 -2
- package/dist/ui/markdown-stream.js.map +1 -1
- package/dist/ui/prompt.d.ts +7 -0
- package/dist/ui/prompt.d.ts.map +1 -1
- package/dist/ui/prompt.js +435 -1214
- package/dist/ui/prompt.js.map +1 -1
- package/dist/ui/render-primitives.d.ts +6 -0
- package/dist/ui/render-primitives.d.ts.map +1 -1
- package/dist/ui/render-primitives.js +30 -13
- package/dist/ui/render-primitives.js.map +1 -1
- package/dist/ui/render.d.ts.map +1 -1
- package/dist/ui/render.js +2 -0
- package/dist/ui/render.js.map +1 -1
- package/package.json +17 -3
- package/scripts/check-vendor-wasm.js +11 -0
- package/vendor/tree-sitter-go.wasm +0 -0
- package/vendor/tree-sitter-javascript.wasm +0 -0
- package/vendor/tree-sitter-python.wasm +0 -0
- package/vendor/tree-sitter-rust.wasm +0 -0
- package/vendor/tree-sitter-tsx.wasm +0 -0
- package/vendor/tree-sitter-typescript.wasm +0 -0
package/dist/config.d.ts
CHANGED
|
@@ -1,5 +1,18 @@
|
|
|
1
1
|
import type { PolicyProfile } from './runtime/policy.js';
|
|
2
2
|
export declare const DEFAULT_API_URL = "https://freellm-liart.vercel.app/v1";
|
|
3
|
+
/**
|
|
4
|
+
* How the CLI authenticates against an LLM backend.
|
|
5
|
+
*
|
|
6
|
+
* - `direct` — Requests go straight to a provider (OpenAI, Anthropic,
|
|
7
|
+
* Groq, etc.) using a key the user pasted at setup. Zero
|
|
8
|
+
* traffic to the FreeLLMAPI proxy. This is the default
|
|
9
|
+
* for fresh installs starting with v1.1.
|
|
10
|
+
* - `proxy` — Requests transit the FreeLLMAPI proxy at
|
|
11
|
+
* {@link DEFAULT_API_URL} (or a custom URL). Opt-in
|
|
12
|
+
* convenience for users who want load-balanced failover
|
|
13
|
+
* across free-tier providers without managing keys.
|
|
14
|
+
*/
|
|
15
|
+
export type ProviderMode = 'direct' | 'proxy';
|
|
3
16
|
/** Stream-resume policy. */
|
|
4
17
|
export type StreamResumePolicy = 'auto' | 'never';
|
|
5
18
|
/**
|
|
@@ -73,6 +86,25 @@ export interface ToolCallBudgetPolicy {
|
|
|
73
86
|
}
|
|
74
87
|
/** Pre-save gate severity. */
|
|
75
88
|
export type LspPreSaveMode = 'off' | 'warn' | 'block' | 'sandbox-mock';
|
|
89
|
+
/**
|
|
90
|
+
* Sandbox mode for `run_command` execution.
|
|
91
|
+
*
|
|
92
|
+
* - `guard` — Today's behaviour. The in-process command-parser
|
|
93
|
+
* regex layer + WorkspaceGuard path-boundary checks
|
|
94
|
+
* are the only line of defence. Fast, no platform
|
|
95
|
+
* dependencies, no behaviour change.
|
|
96
|
+
* - `os-sandbox` — Opt-in. Wraps every shell command in an
|
|
97
|
+
* OS-enforced sandbox (`sandbox-exec` on macOS,
|
|
98
|
+
* `bwrap` on Linux). Blocks writes outside the
|
|
99
|
+
* workspace + tmpdir even when the regex guard is
|
|
100
|
+
* bypassed by a creative command. Requires the
|
|
101
|
+
* platform binary to be present; surfaces a
|
|
102
|
+
* structured error otherwise rather than silently
|
|
103
|
+
* downgrading to `guard`.
|
|
104
|
+
*
|
|
105
|
+
* Always combined with the regex/guard layer — defence in depth.
|
|
106
|
+
*/
|
|
107
|
+
export type SandboxMode = 'guard' | 'os-sandbox';
|
|
76
108
|
/** Safety preferences — Pillar 1, 2, 3 surface. Pillar 4 lives in the
|
|
77
109
|
* credential vault module, not in the user-facing config. */
|
|
78
110
|
export interface SafetyConfig {
|
|
@@ -100,6 +132,166 @@ export interface SafetyConfig {
|
|
|
100
132
|
predictiveBudgetPct?: number;
|
|
101
133
|
/** Tool-call budget — see {@link ToolCallBudgetPolicy}. */
|
|
102
134
|
toolCalls: ToolCallBudgetPolicy;
|
|
135
|
+
/** OS-level sandbox for `run_command`. Defaults to `'guard'`. */
|
|
136
|
+
sandboxMode?: SandboxMode;
|
|
137
|
+
/**
|
|
138
|
+
* Phase 2 — automatic post-edit verification. When `true` (default)
|
|
139
|
+
* AND the run is in BUILD mode AND at least one file-mutating tool
|
|
140
|
+
* was called, the agent runs the project's detected test/typecheck
|
|
141
|
+
* command at the end of the tool loop and — if it fails — pushes a
|
|
142
|
+
* repair-request message back to the model up to
|
|
143
|
+
* {@link autoVerifyMaxRepairs} times before returning.
|
|
144
|
+
*
|
|
145
|
+
* Set to `false` to restore the pre-Phase-2 "trust the model"
|
|
146
|
+
* behaviour. Cheap-to-detect projects (no test/typecheck command in
|
|
147
|
+
* {@link import('./project-memory.js').detectProjectFacts}) silently
|
|
148
|
+
* skip the verifier — there's nothing to run.
|
|
149
|
+
*/
|
|
150
|
+
autoVerify?: boolean;
|
|
151
|
+
/**
|
|
152
|
+
* Maximum number of automatic repair turns the verifier may use in
|
|
153
|
+
* one run. The default of 1 was chosen so a long-horizon task gets
|
|
154
|
+
* exactly one self-correction shot — enough to catch obvious type
|
|
155
|
+
* errors without spinning forever on hard failures.
|
|
156
|
+
*/
|
|
157
|
+
autoVerifyMaxRepairs?: number;
|
|
158
|
+
}
|
|
159
|
+
/**
|
|
160
|
+
* Phase 5 — Agent Pool tuning surface.
|
|
161
|
+
*
|
|
162
|
+
* Controls the concurrency and per-subtask budget of the orchestrator's
|
|
163
|
+
* parallel worker pool. All defaults match the constants that were
|
|
164
|
+
* hardcoded in `agent-pool.ts` before this namespace existed, so adding
|
|
165
|
+
* the namespace alone is a zero-behavior-change refactor.
|
|
166
|
+
*/
|
|
167
|
+
export interface AgentPoolConfig {
|
|
168
|
+
/** Maximum concurrent worker subtasks. Default 3. */
|
|
169
|
+
concurrencyLimit: number;
|
|
170
|
+
/** Tool-call budget per subtask. Default 12 (raised to 40 in Phase 4a). */
|
|
171
|
+
subtaskBudget: number;
|
|
172
|
+
/**
|
|
173
|
+
* When true, successful peer subtasks are committed even if siblings
|
|
174
|
+
* fail (Phase 2). Default false; flipped in Phase 7 after the regression
|
|
175
|
+
* harness validates the partial-commit path.
|
|
176
|
+
*/
|
|
177
|
+
preservePartialOnFailure: boolean;
|
|
178
|
+
}
|
|
179
|
+
/**
|
|
180
|
+
* Phase 5 — loop-mitigation policy.
|
|
181
|
+
*
|
|
182
|
+
* The legacy `LoopMitigationTracker` (loop-mitigation.ts) blocks reads
|
|
183
|
+
* on a target permanently once the warn threshold trips. Phase 1b adds a
|
|
184
|
+
* sliding-window alternative; this config selects between them.
|
|
185
|
+
*/
|
|
186
|
+
export interface AgentLoopGuardConfig {
|
|
187
|
+
/**
|
|
188
|
+
* When true, block accounting uses a sliding window of tool calls
|
|
189
|
+
* instead of session-lifetime lockout. Default false in phase 1b;
|
|
190
|
+
* flipped to true in Phase 7 after soak.
|
|
191
|
+
*/
|
|
192
|
+
useSlidingWindow: boolean;
|
|
193
|
+
/** Sliding-window size in tool calls. Default 10. Ignored when sliding is off. */
|
|
194
|
+
blockWindowTurns: number;
|
|
195
|
+
/**
|
|
196
|
+
* When true, the loop-mitigation tracker is reset between orchestrator
|
|
197
|
+
* subtasks so one stuck subtask cannot poison the rest of the run.
|
|
198
|
+
* Default true.
|
|
199
|
+
*/
|
|
200
|
+
blockResetOnSubtask: boolean;
|
|
201
|
+
}
|
|
202
|
+
/**
|
|
203
|
+
* Phase 5 — routing-honor policy.
|
|
204
|
+
*
|
|
205
|
+
* The router currently surfaces a "model unverified for autonomous DAG
|
|
206
|
+
* execution" warning but routes to the Orchestrator anyway. Phase 6
|
|
207
|
+
* makes the warning actionable.
|
|
208
|
+
*/
|
|
209
|
+
export interface AgentRoutingConfig {
|
|
210
|
+
/**
|
|
211
|
+
* When true, Complex-classified tasks on models NOT in the
|
|
212
|
+
* verified-DAG list are routed to SingleAgent. Default false in
|
|
213
|
+
* Phase 0; flipped to true in Phase 6.
|
|
214
|
+
*/
|
|
215
|
+
honorVerificationFlag: boolean;
|
|
216
|
+
/**
|
|
217
|
+
* Override that permits unverified-model DAG execution even when
|
|
218
|
+
* `honorVerificationFlag` is true. For power users who explicitly
|
|
219
|
+
* accept the risk. Default false.
|
|
220
|
+
*/
|
|
221
|
+
allowUnverifiedDag: boolean;
|
|
222
|
+
}
|
|
223
|
+
/**
|
|
224
|
+
* Phase 5.3 — DAG-level conflict policy.
|
|
225
|
+
*
|
|
226
|
+
* The orchestrator currently parallelizes any subtasks that don't
|
|
227
|
+
* declare a dependency on each other. This causes write-conflicts
|
|
228
|
+
* when the LLM emits multiple subtasks targeting the same file (the
|
|
229
|
+
* "3 workers all writing style.css" race observed in the log).
|
|
230
|
+
*
|
|
231
|
+
* `serializeWriteConflicts`, when true, runs a post-pass on the
|
|
232
|
+
* generated DAG that injects dependency edges whenever two subtasks
|
|
233
|
+
* could write to overlapping files. Default true since the
|
|
234
|
+
* alternative is observed-broken; flag exists so users can opt out
|
|
235
|
+
* for benchmarks or future verified orchestrators.
|
|
236
|
+
*
|
|
237
|
+
* `serializeMissingFiles` extends the same policy to subtasks that
|
|
238
|
+
* declared no files at all (LLMs often omit). Conservative default
|
|
239
|
+
* trades parallelism for correctness — over-serialization is the
|
|
240
|
+
* worst case.
|
|
241
|
+
*/
|
|
242
|
+
export interface AgentDagConfig {
|
|
243
|
+
serializeWriteConflicts: boolean;
|
|
244
|
+
serializeMissingFiles: boolean;
|
|
245
|
+
}
|
|
246
|
+
export interface AgentConfig {
|
|
247
|
+
pool: AgentPoolConfig;
|
|
248
|
+
loopGuard: AgentLoopGuardConfig;
|
|
249
|
+
routing: AgentRoutingConfig;
|
|
250
|
+
dag: AgentDagConfig;
|
|
251
|
+
}
|
|
252
|
+
/**
|
|
253
|
+
* Phase 3.3 — repo-map scan caps.
|
|
254
|
+
*
|
|
255
|
+
* Controls how aggressively `buildRepoMap` walks the workspace.
|
|
256
|
+
* Both fields are optional; defaults track the pre-Phase-3.3
|
|
257
|
+
* constants (depth 4, 200 files) so existing users see no
|
|
258
|
+
* behaviour change. Increase these on large repos where the
|
|
259
|
+
* default cap truncates important directories.
|
|
260
|
+
*/
|
|
261
|
+
export interface RepoMapConfig {
|
|
262
|
+
/** Maximum recursion depth. Default 4. */
|
|
263
|
+
maxDepth?: number;
|
|
264
|
+
/** Maximum files per directory. Default 200. */
|
|
265
|
+
maxFiles?: number;
|
|
266
|
+
}
|
|
267
|
+
/**
|
|
268
|
+
* Phase 2.4 — local fast/heavy-tier model substitution.
|
|
269
|
+
*
|
|
270
|
+
* When a code path tags its request with `required_capabilities`,
|
|
271
|
+
* the client looks up the corresponding tier in this table and
|
|
272
|
+
* substitutes the locally-configured model BEFORE issuing the
|
|
273
|
+
* request. Works in both direct and proxy modes — direct sends the
|
|
274
|
+
* substituted model to the provider; proxy still sees the
|
|
275
|
+
* substitution as well as the legacy metadata headers.
|
|
276
|
+
*
|
|
277
|
+
* Per-tier semantics:
|
|
278
|
+
* - `fast` — used for planner classification, complexity
|
|
279
|
+
* routing, summary turns. Optimise for latency
|
|
280
|
+
* + cost; quality is less important.
|
|
281
|
+
* - `heavy` — used for the orchestrator's plan() and any
|
|
282
|
+
* call that asks for `'heavy'`. Optimise for
|
|
283
|
+
* quality.
|
|
284
|
+
* - `default` — fallback when a request asks for a capability
|
|
285
|
+
* the user hasn't configured; equivalent to
|
|
286
|
+
* not substituting at all.
|
|
287
|
+
*
|
|
288
|
+
* All three fields are optional. When a tier is unset, the
|
|
289
|
+
* client falls through to the model the caller passed.
|
|
290
|
+
*/
|
|
291
|
+
export interface ModelRoutingConfig {
|
|
292
|
+
fast?: string;
|
|
293
|
+
default?: string;
|
|
294
|
+
heavy?: string;
|
|
103
295
|
}
|
|
104
296
|
/** Resilience preferences for the new withRetry + chatStreamWithResume paths. */
|
|
105
297
|
export interface ResilienceConfig {
|
|
@@ -128,9 +320,33 @@ export interface ResilienceConfig {
|
|
|
128
320
|
* Persisted at `~/.fixocli/config.json`.
|
|
129
321
|
*/
|
|
130
322
|
export interface FreeLLMConfig {
|
|
323
|
+
/**
|
|
324
|
+
* Authentication mode. New installs default to `'direct'`. Existing
|
|
325
|
+
* configs that predate this field are inferred at load time:
|
|
326
|
+
* presence of `freellmapi_api_key` means `'proxy'`, absence means
|
|
327
|
+
* `'direct'`. Never undefined after {@link loadConfig} returns.
|
|
328
|
+
*/
|
|
329
|
+
provider_mode: ProviderMode;
|
|
330
|
+
/**
|
|
331
|
+
* When `provider_mode === 'direct'`, identifies the provider the
|
|
332
|
+
* user selected at setup time and the default model to use for new
|
|
333
|
+
* sessions. The actual API key lives in the providers store
|
|
334
|
+
* (`~/.fixocli/providers.json`) and the in-memory credential vault,
|
|
335
|
+
* never here.
|
|
336
|
+
*/
|
|
337
|
+
directProvider?: {
|
|
338
|
+
name: string;
|
|
339
|
+
defaultModel: string;
|
|
340
|
+
};
|
|
131
341
|
freellmapi_api_key?: string;
|
|
132
342
|
apiUrl?: string;
|
|
133
343
|
defaultModel: string;
|
|
344
|
+
/** Persisted across launches so the next boot auto-reconnects. */
|
|
345
|
+
lastSession?: {
|
|
346
|
+
provider: string;
|
|
347
|
+
model: string;
|
|
348
|
+
updatedAt: string;
|
|
349
|
+
};
|
|
134
350
|
preferences: {
|
|
135
351
|
autoCommit: boolean;
|
|
136
352
|
streaming: boolean;
|
|
@@ -165,6 +381,22 @@ export interface FreeLLMConfig {
|
|
|
165
381
|
* is a programmatic-only surface and is not user-configurable.
|
|
166
382
|
*/
|
|
167
383
|
safety: SafetyConfig;
|
|
384
|
+
/**
|
|
385
|
+
* Phase 2.4 — per-capability model substitution. Optional. See
|
|
386
|
+
* {@link ModelRoutingConfig}.
|
|
387
|
+
*/
|
|
388
|
+
modelRouting?: ModelRoutingConfig;
|
|
389
|
+
/**
|
|
390
|
+
* Phase 3.3 — repo-map walk caps. Optional. See
|
|
391
|
+
* {@link RepoMapConfig}.
|
|
392
|
+
*/
|
|
393
|
+
repoMap?: RepoMapConfig;
|
|
394
|
+
/**
|
|
395
|
+
* Phase 5 — Agent subsystem tunables (pool, loop guard, routing).
|
|
396
|
+
* Optional. Missing fields fall through to the defaults in
|
|
397
|
+
* {@link getDefaultConfig}. See {@link AgentConfig}.
|
|
398
|
+
*/
|
|
399
|
+
agent?: AgentConfig;
|
|
168
400
|
};
|
|
169
401
|
_firstRunComplete: boolean;
|
|
170
402
|
}
|
|
@@ -182,6 +414,16 @@ export declare function getDefaultConfig(): FreeLLMConfig;
|
|
|
182
414
|
* instead — the caller can then decide whether to run the setup wizard.
|
|
183
415
|
*/
|
|
184
416
|
export declare function loadConfig(): FreeLLMConfig;
|
|
417
|
+
/**
|
|
418
|
+
* Returns the resolved {@link AgentConfig} from the loaded config.
|
|
419
|
+
* Guaranteed non-null — falls back to defaults for old configs that
|
|
420
|
+
* predate this namespace.
|
|
421
|
+
*/
|
|
422
|
+
export declare function getAgentConfig(config?: FreeLLMConfig): AgentConfig;
|
|
423
|
+
export declare function getAgentPoolConfig(config?: FreeLLMConfig): AgentPoolConfig;
|
|
424
|
+
export declare function getAgentLoopGuardConfig(config?: FreeLLMConfig): AgentLoopGuardConfig;
|
|
425
|
+
export declare function getAgentRoutingConfig(config?: FreeLLMConfig): AgentRoutingConfig;
|
|
426
|
+
export declare function getAgentDagConfig(config?: FreeLLMConfig): AgentDagConfig;
|
|
185
427
|
/**
|
|
186
428
|
* Persists the given config to `~/.fixocli/config.json`.
|
|
187
429
|
* Creates the config directory if it doesn't already exist.
|
package/dist/config.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAEzD,eAAO,MAAM,eAAe,wCAAwC,CAAC;AAErE,4BAA4B;AAC5B,MAAM,MAAM,kBAAkB,GAAG,MAAM,GAAG,OAAO,CAAC;AAElD;;;;;;;;;;;GAWG;AACH,MAAM,MAAM,mBAAmB,GAAG,MAAM,GAAG,UAAU,GAAG,OAAO,CAAC;AAIhE;;;;;;;;GAQG;AACH,MAAM,WAAW,cAAc;IAC7B,wEAAwE;IACxE,YAAY,EAAE,MAAM,CAAC;IACrB,yEAAyE;IACzE,cAAc,EAAE,MAAM,CAAC;IACvB,yEAAyE;IACzE,mBAAmB,EAAE,MAAM,CAAC;IAC5B,4DAA4D;IAC5D,UAAU,EAAE,MAAM,CAAC;IACnB,qEAAqE;IACrE,OAAO,EAAE,OAAO,CAAC;CAClB;AAED;;+DAE+D;AAC/D,MAAM,WAAW,sBAAsB;IACrC,OAAO,EAAE,OAAO,CAAC;IACjB,UAAU,EAAE,MAAM,CAAC;IACnB,YAAY,EAAE,MAAM,CAAC;IACrB,cAAc,EAAE,MAAM,CAAC;CACxB;AAED;;;;;;;GAOG;AACH,MAAM,WAAW,oBAAoB;IACnC,mCAAmC;IACnC,SAAS,EAAE,MAAM,CAAC;IAClB,sEAAsE;IACtE,SAAS,EAAE,MAAM,CAAC;IAClB,yEAAyE;IACzE,UAAU,EAAE,OAAO,CAAC;IACpB;;;;;;;;OAQG;IACH,uBAAuB,EAAE,MAAM,CAAC;CACjC;AAED,8BAA8B;AAC9B,MAAM,MAAM,cAAc,GAAG,KAAK,GAAG,MAAM,GAAG,OAAO,GAAG,cAAc,CAAC;AAEvE;8DAC8D;AAC9D,MAAM,WAAW,YAAY;IAC3B,kEAAkE;IAClE,aAAa,EAAE,OAAO,CAAC;IACvB,mEAAmE;IACnE,YAAY,EAAE,MAAM,CAAC;IACrB,yDAAyD;IACzD,UAAU,EAAE,cAAc,CAAC;IAC3B,4BAA4B;IAC5B,QAAQ,EAAE,cAAc,CAAC;IACzB,6DAA6D;IAC7D,gBAAgB,EAAE,sBAAsB,CAAC;IACzC;wDACoD;IACpD,kBAAkB,EAAE,MAAM,CAAC;IAC3B,qEAAqE;IACrE,kBAAkB,EAAE,MAAM,CAAC;IAC3B;;;;;OAKG;IACH,mBAAmB,CAAC,EAAE,MAAM,CAAC;IAC7B,2DAA2D;IAC3D,SAAS,EAAE,oBAAoB,CAAC;
|
|
1
|
+
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"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"}
|
package/dist/config.js
CHANGED
|
@@ -23,6 +23,7 @@ export function getHistoryPath() {
|
|
|
23
23
|
/** Returns a complete default configuration object. */
|
|
24
24
|
export function getDefaultConfig() {
|
|
25
25
|
return {
|
|
26
|
+
provider_mode: 'direct',
|
|
26
27
|
defaultModel: 'auto',
|
|
27
28
|
preferences: {
|
|
28
29
|
autoCommit: false,
|
|
@@ -65,6 +66,29 @@ export function getDefaultConfig() {
|
|
|
65
66
|
autoExtend: true,
|
|
66
67
|
investigationMultiplier: 3,
|
|
67
68
|
},
|
|
69
|
+
sandboxMode: 'guard',
|
|
70
|
+
autoVerify: true,
|
|
71
|
+
autoVerifyMaxRepairs: 1,
|
|
72
|
+
},
|
|
73
|
+
agent: {
|
|
74
|
+
pool: {
|
|
75
|
+
concurrencyLimit: 3,
|
|
76
|
+
subtaskBudget: 12,
|
|
77
|
+
preservePartialOnFailure: true,
|
|
78
|
+
},
|
|
79
|
+
loopGuard: {
|
|
80
|
+
useSlidingWindow: true,
|
|
81
|
+
blockWindowTurns: 10,
|
|
82
|
+
blockResetOnSubtask: true,
|
|
83
|
+
},
|
|
84
|
+
routing: {
|
|
85
|
+
honorVerificationFlag: true,
|
|
86
|
+
allowUnverifiedDag: false,
|
|
87
|
+
},
|
|
88
|
+
dag: {
|
|
89
|
+
serializeWriteConflicts: true,
|
|
90
|
+
serializeMissingFiles: true,
|
|
91
|
+
},
|
|
68
92
|
},
|
|
69
93
|
},
|
|
70
94
|
_firstRunComplete: false,
|
|
@@ -91,9 +115,20 @@ export function loadConfig() {
|
|
|
91
115
|
const parsedSemanticLoopTrap = parsedSafety
|
|
92
116
|
.semanticLoopTrap ?? {};
|
|
93
117
|
const parsedToolCalls = parsedSafety.toolCalls ?? {};
|
|
118
|
+
const parsedAgent = parsedPreferences.agent ?? {};
|
|
119
|
+
const parsedAgentPool = parsedAgent.pool ?? {};
|
|
120
|
+
const parsedAgentLoopGuard = parsedAgent.loopGuard ?? {};
|
|
121
|
+
const parsedAgentRouting = parsedAgent.routing ?? {};
|
|
122
|
+
const parsedAgentDag = parsedAgent.dag ?? {};
|
|
123
|
+
// Back-compat: existing configs predating v1.1 don't have
|
|
124
|
+
// `provider_mode`. If they have a FreeLLMAPI key they were
|
|
125
|
+
// implicitly proxy users; otherwise they're either fresh or
|
|
126
|
+
// explicitly direct. Never silently flip an existing user.
|
|
127
|
+
const inferredMode = parsed.provider_mode ?? (parsed.freellmapi_api_key ? 'proxy' : 'direct');
|
|
94
128
|
return {
|
|
95
129
|
...defaults,
|
|
96
130
|
...parsed,
|
|
131
|
+
provider_mode: inferredMode,
|
|
97
132
|
preferences: {
|
|
98
133
|
...defaults.preferences,
|
|
99
134
|
...parsedPreferences,
|
|
@@ -117,6 +152,24 @@ export function loadConfig() {
|
|
|
117
152
|
...parsedToolCalls,
|
|
118
153
|
},
|
|
119
154
|
},
|
|
155
|
+
agent: {
|
|
156
|
+
pool: {
|
|
157
|
+
...defaults.preferences.agent.pool,
|
|
158
|
+
...parsedAgentPool,
|
|
159
|
+
},
|
|
160
|
+
loopGuard: {
|
|
161
|
+
...defaults.preferences.agent.loopGuard,
|
|
162
|
+
...parsedAgentLoopGuard,
|
|
163
|
+
},
|
|
164
|
+
routing: {
|
|
165
|
+
...defaults.preferences.agent.routing,
|
|
166
|
+
...parsedAgentRouting,
|
|
167
|
+
},
|
|
168
|
+
dag: {
|
|
169
|
+
...defaults.preferences.agent.dag,
|
|
170
|
+
...parsedAgentDag,
|
|
171
|
+
},
|
|
172
|
+
},
|
|
120
173
|
},
|
|
121
174
|
};
|
|
122
175
|
}
|
|
@@ -125,6 +178,32 @@ export function loadConfig() {
|
|
|
125
178
|
return getDefaultConfig();
|
|
126
179
|
}
|
|
127
180
|
}
|
|
181
|
+
// ---------------------------------------------------------------------------
|
|
182
|
+
// Agent subsystem helpers (Phase 5 — see AgentConfig)
|
|
183
|
+
// ---------------------------------------------------------------------------
|
|
184
|
+
/**
|
|
185
|
+
* Returns the resolved {@link AgentConfig} from the loaded config.
|
|
186
|
+
* Guaranteed non-null — falls back to defaults for old configs that
|
|
187
|
+
* predate this namespace.
|
|
188
|
+
*/
|
|
189
|
+
export function getAgentConfig(config) {
|
|
190
|
+
const cfg = config ?? loadConfig();
|
|
191
|
+
if (cfg.preferences.agent)
|
|
192
|
+
return cfg.preferences.agent;
|
|
193
|
+
return getDefaultConfig().preferences.agent;
|
|
194
|
+
}
|
|
195
|
+
export function getAgentPoolConfig(config) {
|
|
196
|
+
return getAgentConfig(config).pool;
|
|
197
|
+
}
|
|
198
|
+
export function getAgentLoopGuardConfig(config) {
|
|
199
|
+
return getAgentConfig(config).loopGuard;
|
|
200
|
+
}
|
|
201
|
+
export function getAgentRoutingConfig(config) {
|
|
202
|
+
return getAgentConfig(config).routing;
|
|
203
|
+
}
|
|
204
|
+
export function getAgentDagConfig(config) {
|
|
205
|
+
return getAgentConfig(config).dag;
|
|
206
|
+
}
|
|
128
207
|
/**
|
|
129
208
|
* Persists the given config to `~/.fixocli/config.json`.
|
|
130
209
|
* Creates the config directory if it doesn't already exist.
|
package/dist/config.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,SAAS,CAAC;AACzB,OAAO,EAAE,MAAM,SAAS,CAAC;AACzB,OAAO,IAAI,MAAM,WAAW,CAAC;AAG7B,MAAM,CAAC,MAAM,eAAe,GAAG,qCAAqC,CAAC;
|
|
1
|
+
{"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"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"}
|
|
@@ -21,8 +21,39 @@ export declare class GitManager {
|
|
|
21
21
|
undoLastCommit(): boolean;
|
|
22
22
|
/** Get last N commit messages for display. */
|
|
23
23
|
getRecentCommits(count?: number): string;
|
|
24
|
-
/**
|
|
25
|
-
|
|
24
|
+
/**
|
|
25
|
+
* Discard the agent's edits to a specific set of files only.
|
|
26
|
+
*
|
|
27
|
+
* Background: an earlier version exposed a `discardUncommittedChanges()`
|
|
28
|
+
* method that ran `git checkout -- .` followed by `git clean -fd`,
|
|
29
|
+
* unconditionally wiping every uncommitted change in the workspace —
|
|
30
|
+
* including pre-existing user work the agent never touched. The
|
|
31
|
+
* orchestrator's failure-rollback path called it on any error, which
|
|
32
|
+
* meant a *read-only* task failing on a tool-call budget could
|
|
33
|
+
* destroy hours of unrelated in-progress work. That method has been
|
|
34
|
+
* removed. Callers must now name the files they want to roll back.
|
|
35
|
+
*
|
|
36
|
+
* For tracked files in `files`, the change is reverted to the
|
|
37
|
+
* `HEAD` revision. For untracked files in `files` (i.e. new files
|
|
38
|
+
* the agent created during the run), the file is unlinked. Files
|
|
39
|
+
* NOT in `files` are left completely alone — including any other
|
|
40
|
+
* uncommitted user work.
|
|
41
|
+
*
|
|
42
|
+
* Passing an empty list is a no-op.
|
|
43
|
+
*
|
|
44
|
+
* @param files Absolute or workspace-relative paths the run actually modified.
|
|
45
|
+
*/
|
|
46
|
+
discardChangesIn(files: string[]): void;
|
|
47
|
+
/**
|
|
48
|
+
* Escape hatch — full workspace wipe (`git checkout -- .` + `git clean -fd`).
|
|
49
|
+
* Removed from any agent-driven path; intentionally kept here for
|
|
50
|
+
* the rare case where a user explicitly chooses to discard
|
|
51
|
+
* everything from a slash command. Callers must pass
|
|
52
|
+
* `{ iAmCertain: true }` to spell out the intent.
|
|
53
|
+
*/
|
|
54
|
+
forceDiscardAllUncommittedChanges(opts: {
|
|
55
|
+
iAmCertain: true;
|
|
56
|
+
}): void;
|
|
26
57
|
/**
|
|
27
58
|
* Create a named workspace snapshot commit (works in non-auto-commit mode).
|
|
28
59
|
* Stages all changes and commits with "fixo-snapshot: <label>" message.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"git-manager.d.ts","sourceRoot":"","sources":["../../src/git/git-manager.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"git-manager.d.ts","sourceRoot":"","sources":["../../src/git/git-manager.ts"],"names":[],"mappings":"AAwBA,qBAAa,UAAU;IACrB,OAAO,CAAC,GAAG,CAAS;IACpB,OAAO,CAAC,KAAK,CAAiB;gBAElB,GAAG,EAAE,MAAM;IAKvB,iEAAiE;IACjE,SAAS,IAAI,OAAO;IAapB,mCAAmC;IACnC,gBAAgB,IAAI,MAAM;IAY1B,8CAA8C;IAC9C,UAAU,IAAI,OAAO;IAarB,qFAAqF;IACrF,aAAa,IAAI,MAAM,EAAE;IA8BzB,8CAA8C;IAC9C,OAAO,IAAI,MAAM;IA8CjB;;;OAGG;IACH,UAAU,CAAC,IAAI,EAAE,MAAM,EAAE,aAAa,EAAE,MAAM,EAAE,GAAG,MAAM,GAAG,IAAI;IAkEhE,yEAAyE;IACzE,cAAc,IAAI,OAAO;IAsCzB,8CAA8C;IAC9C,gBAAgB,CAAC,KAAK,SAAI,GAAG,MAAM;IAWnC;;;;;;;;;;;;;;;;;;;;;OAqBG;IACH,gBAAgB,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,IAAI;IAiDvC;;;;;;OAMG;IACH,iCAAiC,CAAC,IAAI,EAAE;QAAE,UAAU,EAAE,IAAI,CAAA;KAAE,GAAG,IAAI;IAanE;;;;OAIG;IACH,cAAc,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI;CAiC7C"}
|
package/dist/git/git-manager.js
CHANGED
|
@@ -3,6 +3,8 @@
|
|
|
3
3
|
* All git operations are safely sandboxed to the workspace directory.
|
|
4
4
|
*/
|
|
5
5
|
import { execFileSync } from 'child_process';
|
|
6
|
+
import fs from 'node:fs';
|
|
7
|
+
import path from 'node:path';
|
|
6
8
|
import { WorkspaceGuard } from '../workspace-guard.js';
|
|
7
9
|
import { C } from '../ui/colors.js';
|
|
8
10
|
/* ──────────────────────── ANSI Colors ──────────────────────── */
|
|
@@ -69,21 +71,27 @@ export class GitManager {
|
|
|
69
71
|
if (!this.isGitRepo())
|
|
70
72
|
return [];
|
|
71
73
|
try {
|
|
72
|
-
const output = execFileSync('git', ['status', '--porcelain'], {
|
|
74
|
+
const output = execFileSync('git', ['status', '--porcelain', '-z'], {
|
|
73
75
|
cwd: this.cwd,
|
|
74
76
|
encoding: 'utf-8',
|
|
75
77
|
stdio: ['pipe', 'pipe', 'pipe'],
|
|
76
78
|
});
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
79
|
+
if (!output)
|
|
80
|
+
return [];
|
|
81
|
+
const files = [];
|
|
82
|
+
const parts = output.split('\0');
|
|
83
|
+
for (let i = 0; i < parts.length; i++) {
|
|
84
|
+
const part = parts[i];
|
|
85
|
+
if (!part)
|
|
86
|
+
continue;
|
|
87
|
+
const xy = part.slice(0, 2);
|
|
88
|
+
files.push(part.slice(3));
|
|
89
|
+
// If it's a rename (R) or copy (C), skip the old path that follows
|
|
90
|
+
if (xy[0] === 'R' || xy[0] === 'C') {
|
|
91
|
+
i++;
|
|
84
92
|
}
|
|
85
|
-
|
|
86
|
-
|
|
93
|
+
}
|
|
94
|
+
return files;
|
|
87
95
|
}
|
|
88
96
|
catch {
|
|
89
97
|
return [];
|
|
@@ -242,17 +250,104 @@ export class GitManager {
|
|
|
242
250
|
return '(no commits)';
|
|
243
251
|
}
|
|
244
252
|
}
|
|
245
|
-
/**
|
|
246
|
-
|
|
253
|
+
/**
|
|
254
|
+
* Discard the agent's edits to a specific set of files only.
|
|
255
|
+
*
|
|
256
|
+
* Background: an earlier version exposed a `discardUncommittedChanges()`
|
|
257
|
+
* method that ran `git checkout -- .` followed by `git clean -fd`,
|
|
258
|
+
* unconditionally wiping every uncommitted change in the workspace —
|
|
259
|
+
* including pre-existing user work the agent never touched. The
|
|
260
|
+
* orchestrator's failure-rollback path called it on any error, which
|
|
261
|
+
* meant a *read-only* task failing on a tool-call budget could
|
|
262
|
+
* destroy hours of unrelated in-progress work. That method has been
|
|
263
|
+
* removed. Callers must now name the files they want to roll back.
|
|
264
|
+
*
|
|
265
|
+
* For tracked files in `files`, the change is reverted to the
|
|
266
|
+
* `HEAD` revision. For untracked files in `files` (i.e. new files
|
|
267
|
+
* the agent created during the run), the file is unlinked. Files
|
|
268
|
+
* NOT in `files` are left completely alone — including any other
|
|
269
|
+
* uncommitted user work.
|
|
270
|
+
*
|
|
271
|
+
* Passing an empty list is a no-op.
|
|
272
|
+
*
|
|
273
|
+
* @param files Absolute or workspace-relative paths the run actually modified.
|
|
274
|
+
*/
|
|
275
|
+
discardChangesIn(files) {
|
|
276
|
+
if (!this.isGitRepo())
|
|
277
|
+
return;
|
|
278
|
+
if (files.length === 0) {
|
|
279
|
+
console.log(`${colors.dim} ⏪ Rollback: nothing to discard (0 files reported).${colors.reset}`);
|
|
280
|
+
return;
|
|
281
|
+
}
|
|
282
|
+
const relativeFiles = files.map((f) => path.isAbsolute(f) ? path.relative(this.cwd, f) : f);
|
|
283
|
+
const tracked = [];
|
|
284
|
+
const untracked = [];
|
|
285
|
+
try {
|
|
286
|
+
for (const rel of relativeFiles) {
|
|
287
|
+
let status = '';
|
|
288
|
+
try {
|
|
289
|
+
status = execFileSync('git', ['status', '--porcelain', '-z', '--', rel], {
|
|
290
|
+
cwd: this.cwd,
|
|
291
|
+
encoding: 'utf-8',
|
|
292
|
+
stdio: ['pipe', 'pipe', 'pipe'],
|
|
293
|
+
});
|
|
294
|
+
}
|
|
295
|
+
catch {
|
|
296
|
+
// safe: file may have been deleted mid-run; treat as no-op
|
|
297
|
+
continue;
|
|
298
|
+
}
|
|
299
|
+
if (!status)
|
|
300
|
+
continue; // file is clean — nothing to roll back
|
|
301
|
+
if (status.startsWith('??'))
|
|
302
|
+
untracked.push(rel);
|
|
303
|
+
else
|
|
304
|
+
tracked.push(rel);
|
|
305
|
+
}
|
|
306
|
+
if (tracked.length > 0) {
|
|
307
|
+
execFileSync('git', ['checkout', 'HEAD', '--', ...tracked], {
|
|
308
|
+
cwd: this.cwd,
|
|
309
|
+
stdio: ['pipe', 'pipe', 'pipe'],
|
|
310
|
+
});
|
|
311
|
+
}
|
|
312
|
+
for (const rel of untracked) {
|
|
313
|
+
try {
|
|
314
|
+
fs.unlinkSync(path.join(this.cwd, rel));
|
|
315
|
+
}
|
|
316
|
+
catch { /* safe: best-effort */ }
|
|
317
|
+
}
|
|
318
|
+
const total = tracked.length + untracked.length;
|
|
319
|
+
if (total > 0) {
|
|
320
|
+
console.log(`${colors.green} ⏪ Rolled back ${tracked.length} modified + ${untracked.length} new file(s) the agent touched.${colors.reset}`);
|
|
321
|
+
}
|
|
322
|
+
else {
|
|
323
|
+
console.log(`${colors.dim} ⏪ Rollback: agent-touched files were already clean.${colors.reset}`);
|
|
324
|
+
}
|
|
325
|
+
}
|
|
326
|
+
catch (error) {
|
|
327
|
+
const msg = error instanceof Error ? error.message : String(error);
|
|
328
|
+
console.log(`${colors.yellow} ⚠ Failed to discard targeted changes: ${msg}${colors.reset}`);
|
|
329
|
+
}
|
|
330
|
+
}
|
|
331
|
+
/**
|
|
332
|
+
* Escape hatch — full workspace wipe (`git checkout -- .` + `git clean -fd`).
|
|
333
|
+
* Removed from any agent-driven path; intentionally kept here for
|
|
334
|
+
* the rare case where a user explicitly chooses to discard
|
|
335
|
+
* everything from a slash command. Callers must pass
|
|
336
|
+
* `{ iAmCertain: true }` to spell out the intent.
|
|
337
|
+
*/
|
|
338
|
+
forceDiscardAllUncommittedChanges(opts) {
|
|
339
|
+
if (!opts.iAmCertain)
|
|
340
|
+
return;
|
|
247
341
|
if (!this.isGitRepo())
|
|
248
342
|
return;
|
|
249
343
|
try {
|
|
250
344
|
execFileSync('git', ['checkout', '--', '.'], { cwd: this.cwd, stdio: ['pipe', 'pipe', 'pipe'] });
|
|
251
345
|
execFileSync('git', ['clean', '-fd'], { cwd: this.cwd, stdio: ['pipe', 'pipe', 'pipe'] });
|
|
252
|
-
console.log(`${colors.green} ⏪ Discarded
|
|
346
|
+
console.log(`${colors.green} ⏪ Discarded ALL uncommitted workspace changes (explicit user request).${colors.reset}`);
|
|
253
347
|
}
|
|
254
348
|
catch (error) {
|
|
255
|
-
|
|
349
|
+
const msg = error instanceof Error ? error.message : String(error);
|
|
350
|
+
console.log(`${colors.yellow} ⚠ Failed to discard uncommitted changes: ${msg}${colors.reset}`);
|
|
256
351
|
}
|
|
257
352
|
}
|
|
258
353
|
/**
|
|
@@ -285,7 +380,8 @@ export class GitManager {
|
|
|
285
380
|
return hash;
|
|
286
381
|
}
|
|
287
382
|
catch (error) {
|
|
288
|
-
|
|
383
|
+
const msg = error instanceof Error ? error.message : String(error);
|
|
384
|
+
console.log(`${colors.yellow} ⚠ Snapshot failed: ${msg.slice(0, 80)}${colors.reset}`);
|
|
289
385
|
return null;
|
|
290
386
|
}
|
|
291
387
|
}
|