diff --git a/.fallowrc.json b/.fallowrc.json index 5fdc941a5..ff1a43b76 100644 --- a/.fallowrc.json +++ b/.fallowrc.json @@ -6,6 +6,9 @@ "**/*.{test,spec}.{ts,tsx}", "**/*.eval.ts" ], + "ignorePatterns": [ + ".claude/**" + ], "dynamicallyLoaded": [ "src/deploy/runtime.ts", "src/deploy/runtime.worker.ts", diff --git a/.gitignore b/.gitignore index 29a283088..05d40d7ae 100644 --- a/.gitignore +++ b/.gitignore @@ -52,3 +52,6 @@ docs/api/ # fallow cache/snapshots .fallow/ + +# Local agent worktrees and session state +.claude/ diff --git a/src/execution/AgentExecutor.ts b/src/execution/AgentExecutor.ts index 51f81c8ec..71afe4d68 100644 --- a/src/execution/AgentExecutor.ts +++ b/src/execution/AgentExecutor.ts @@ -494,11 +494,14 @@ export class AgentExecutor { // A failed tool carries its message as `{error}` (the same shape // resume.ts uses) - `result` is null then, so the model would - // otherwise see a bare "null" and never learn the call failed. + // otherwise see a bare "null" and never learn the call failed. A + // failure that already has a structured result (argument validation) + // keeps it, so the model gets the per-issue detail. const failed = toolResult.error !== undefined; + const failurePayload = toolResult.result ?? { error: toolResult.error }; state.messages.push({ role: 'tool', - content: JSON.stringify(failed ? { error: toolResult.error } : toolResult.result), + content: JSON.stringify(failed ? failurePayload : toolResult.result), name: toolCall.function.name, toolCallId: toolCall.id, toolName: toolCall.function.name, diff --git a/vitest.config.ts b/vitest.config.ts index d34b929c4..7b4a68470 100644 --- a/vitest.config.ts +++ b/vitest.config.ts @@ -35,6 +35,9 @@ export default defineConfig({ // DOM globals (File, Blob, HTMLAnchorElement, ...) those tests need. // Each app is tested via its own `npm run test --workspace=apps/*`. 'apps/**', + // Agent worktrees (.claude/worktrees/*) are full checkouts of this repo; + // without this the main checkout would run every copy's tests too. + '.claude/**', ], coverage: { provider: 'v8', @@ -49,7 +52,7 @@ export default defineConfig({ // LOU-P's growth (new server/chat + ChatPanel/ApprovalCard code, all // covered by apps/agent-forge's own 49/49 + 74/74 suites) tipped the // denominator enough to trip the global threshold below. - exclude: ['**/*.test.ts', '**/*.spec.ts', 'dist/**', 'node_modules/**', 'apps/**'], + exclude: ['**/*.test.ts', '**/*.spec.ts', 'dist/**', 'node_modules/**', 'apps/**', '.claude/**'], // Floor set 1-2 points below the measured baseline (LOU-B4). Measured with // `npm run test:coverage`, excluding the 3 provider test suites that fail // to even load in this repo because @ai-sdk/openai and ollama-ai-provider