feat(ai): PR 5 — test extractor + core runner [5/7]#416
Merged
ianwhitedeveloper merged 2 commits intoai-testing-framework-implementation-consolidationfrom Feb 26, 2026
Merged
Conversation
Comment on lines
-7
to
-18
| /** | ||
| * Format Zod validation errors into a human-readable message. | ||
| * @param {any} zodError - Zod validation error | ||
| * @returns {string} Formatted error message | ||
| */ | ||
| export const formatZodError = (zodError) => { | ||
| const issues = zodError.issues || zodError.errors; | ||
| return issues | ||
| ? issues.map(e => `${e.path.join('.')}: ${e.message}`).join('; ') | ||
| : zodError.message || 'Validation failed'; | ||
| }; | ||
|
|
Collaborator
Author
There was a problem hiding this comment.
I determined this was a completely unnecessary abstraction
This comment was marked as outdated.
This comment was marked as outdated.
8cb4278 to
3e64783
Compare
b65d74b to
efada8b
Compare
ecd2c58 to
82202d2
Compare
efada8b to
18fd7ab
Compare
janhesters
approved these changes
Feb 26, 2026
Base automatically changed from
pr/ai-debug-logger-removal
to
ai-testing-framework-implementation-consolidation
February 26, 2026 17:57
- Add AgentConfigReadError, AgentConfigParseError, AgentConfigValidationError to ai-errors.js - Update agent-config.js to use specific AgentConfig* error types; z.prettifyError() inline - Update agent-config.test.js to use handleAIErrors routing pattern throughout - Add test-extractor.js: buildExtractionPrompt, buildResultPrompt, buildJudgePrompt, extractTests - Add ai-runner.js: runAITests, verifyAgentAuthentication - Add @paralleldrive/cuid2 dependency for hermetic test temp-dir naming Co-authored-by: Cursor <cursoragent@cursor.com>
- Fix fragile error tests in test-extractor.test.js that relied on package.json at process.cwd(); replace with hermetic temp dirs - Add resolves-imports-without-testFilePath test to cover the testFilePath guard removal behavioral branch - Remove misleading testFilePath guard from resolveImportPaths condition in extractTests (guard was unused; resolution depends only on importPaths.length) - Add error path tests to ai-runner.test.js: file-not-found and extraction agent non-zero exit (AgentProcessError routing) - Document loadAgentConfig command injection trust boundary - Fix Enhancement comments in ai-runner.js to self-contained TODOs - Inline redundant judgments intermediate variable in executeSingleRun - Add agentConfig default to runAITests JSDoc - Add TODO(post-consolidation) markers for deferred items: buildJudgePrompt promptUnderTest guard, validation ordering before IO, judgeAssertion param bloat, tapYAML mock fragility Made-with: Cursor
335ff01 to
ae15c8f
Compare
abe98d9
into
ai-testing-framework-implementation-consolidation
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
PR 5 of 7 in the consolidation of draft PR #394 — decomposing the 80-commit monolith into small, focused, dependency-ordered PRs.
Depends on: PR 1 (ai-errors, constants), PR 2 (tap-yaml), PR 3 (agent-parser, execute-agent), PR 4 (agent-config, validation) — all merged. Plus #417 (debug-logger removal) which is the direct base branch for this PR.
What's in This PR
New modules
source/test-extractor.js— Two-agent prompt pipeline for extracting and evaluating test assertions:buildExtractionPrompt— instructs an LLM to parse a test file into structured{ userPrompt, importPaths, assertions[] }databuildResultPrompt— instructs the result agent to execute the user prompt and return plain textbuildJudgePrompt— instructs the judge agent to evaluate one result against one requirement and return TAP YAMLextractTests— full extraction pipeline: calls extraction agent → validates result → resolves imported prompt files → returns{ userPrompt, promptUnderTest, assertions }source/ai-runner.js— Orchestration layer for the two-agent test execution flow:runAITests— full pipeline: read file → extract tests → run N runs (result agent once per run, judge agents per assertion in parallel) → aggregate resultsverifyAgentAuthentication— delegates tovalidation.jswith injectedexecuteAgentModified modules
source/ai-errors.js— Three new error types (AgentConfigReadError,AgentConfigParseError,AgentConfigValidationError)source/agent-config.js— Updated to use specificAgentConfig*error types;z.prettifyError()used directly for Zod error formatting (customformatZodErrorabstraction removed as unnecessary)Dependency graph (this PR)
No cycles.
test-extractor.jsimportsexecuteAgentdirectly fromexecute-agent.js— not fromai-runner.js. This was the circular dependency in the original feature branch.Fixes and remediations details
WIP Fixes Applied
formatZodErrorremoved;z.prettifyError()used directly inagent-config.jstest-extractor.jsparseTAPYAMLandparseExtractionResultimported directly by callersAgentConfig*error types (Eric's PR #410 review)ai-errors.js;agent-config.jsuses specific types; tests usehandleAIErrorsroutingReview Remediations Applied
package.jsonatprocess.cwd()projectRootin all affected testsai-runner.test.jsENOENT) and extraction agent non-zero exit (AgentProcessErrorrouting)loadAgentConfigcommand injection trust boundary undocumentedtestFilePath &&guard inresolveImportPathsconditionimportPaths.length, nottestFilePathtestFilePathomitted path (import resolution still works)resolves imports using projectRoot when testFilePath is not provided// TODO:markersrunAITestsJSDoc missingagentConfigdefault[options.agentConfig=getAgentConfig()]with default noteDeferred with
TODO(post-consolidation to mitigate derailing overall recomposition plan - can be decided upon once all functionality + e2e tests are in place):markers (tracked in consolidation plan):buildJudgePromptmissingpromptUnderTestguard (inconsistency withbuildResultPrompt)extractTests(structural errors should surface beforeresolveImportPaths)judgeAssertionparameter bloat from logging (assertionIndex/totalAssertionsforconsole.logonly)createTwoAgentMockArgsTAP YAML backtick fragility (useJSON.stringify)resolveImportPaths— intentional, requires GitHub issue for remediation epicArchitectural Notes (Deferred)
outputFormatstring strategy +parseOutputThe
parseOutput: fnpattern stays as-is for PRs 5–7. TheoutputFormatdeclarative string strategy (making configs fully serializable forriteway ai init) and the IO/mapping separation inexecuteAgentare deferred to the post-consolidation epic. See the consolidation plan's Post-Consolidation section for details.runAITestsdefaultagentConfigrunAITestsusesgetAgentConfig('claude')as its default — eliminates the previously duplicated inline claude config literal. Deferred cleanup tracked in the plan.Test Results
136 tests across 12 test files, all passing. 19 new tests: 13 in
test-extractor.test.js+ 6 inai-runner.test.js.test-extractortests coverbuildExtractionPrompt,buildResultPrompt,buildJudgePrompt(full string comparison), andextractTests(integration tests using real node subprocesses for the agent mock, hermetic temp dirs for all fixtures — no reliance on project files)ai-runnertests coverrunAITestsend-to-end using a two-agent node mock (extraction → result → judge) with hermetic temp dirs, including error paths: file-not-found and extraction agent failureChecklist
test-extractor.js→execute-agent.js(notai-runner.js)test-extractor.jsz.prettifyError()used directly — customformatZodErrorabstraction removedhandleAIErrorsrouting pattern used throughout — no.cause.codeinspection in teststest.eachfor any table-driven cases; nofor...ofloops in test filesallNoopspread patterntestFilePathguard removed — import resolution correct without itloadAgentConfigtrust boundary documentednpm test— 136/136 passingnpm run lint— cleannpm run ts— cleanMade with Cursor