Skip to content

Comments

feat(ai): PR 4 — agent config + validation [4/7]#410

Draft
ianwhitedeveloper wants to merge 2 commits intoai-testing-framework-implementation-consolidationfrom
pr/ai-config-validation
Draft

feat(ai): PR 4 — agent config + validation [4/7]#410
ianwhitedeveloper wants to merge 2 commits intoai-testing-framework-implementation-consolidationfrom
pr/ai-config-validation

Conversation

@ianwhitedeveloper
Copy link
Collaborator

Summary

PR 4 of 7 in the consolidation of draft PR #394 — decomposing the 80-commit monolith into small, focused, dependency-ordered PRs. Targets ai-testing-framework-implementation-consolidation (staging area before master).

Depends on: PR 1 (ai-errors, constants), PR 2 (debug-logger), PR 3 (agent-parser, execute-agent) — all merged.


What's in This PR

New modules

  • source/agent-config.js — Agent configuration for the three supported agents (claude, opencode, cursor) plus loading and Zod-validating JSON config files for custom agents
  • source/validation.js — Path traversal guard (validateFilePath) and agent auth smoke-test (verifyAgentAuthentication)

New fixtures

  • source/fixtures/test-agent-config.json — valid custom agent config
  • source/fixtures/invalid-agent-config.txt — malformed JSON (triggers AGENT_CONFIG_PARSE_ERROR)
  • source/fixtures/no-command-agent-config.json — missing required field (triggers AGENT_CONFIG_VALIDATION_ERROR)

WIP fixes applied

# Issue Resolution
#2 Schema extensibility comment was a verbose JSDoc Replaced with single-line YAGNI comment
#10 Cursor agent missing --trust flag Added --trust to cursor args for non-interactive execution
#11 Test constants must be explicit per TDD rules Confirmed — all expected values are literal in tests

Test Results

186 tests passing (19 new: 14 agent-config + 5 formatZodError, 8 validation — wait, let me recount: 14 agent-config tests + 8 validation tests = 22 new), zero lint errors, TypeScript clean.

186/186 passing across 12 test files.


Open Architectural Questions (deferred, not blocking)

Two design issues surfaced during review that are worth flagging before PR 6 (CLI integration) wires up --agent-config. They are not regressions from the feature branch — they existed there too — but consolidation is the right moment to decide.

1. Built-in agent configs are hardcoded CLI flags outside our control

getAgentConfig() returns hardcoded CLI flag arrays for claude, opencode, and cursor. These are internal to those CLIs and can change without notice. If claude --output-format json changes flags, every riteway user breaks until we ship an update.

Proposed solution: An eject/init pattern combined with named output format strategies (see #2 below). riteway ai init writes a starter config file to the project. Built-in defaults remain for first-time convenience but teams who want stability own their config file. The library stops being the source of truth for third-party CLI flags.

2. parseOutput function cannot be expressed in JSON config files

Custom agents loaded from JSON (--agent-config my-agent.json) are silently locked to default stdout JSON parsing. There is no way for a custom agent that emits NDJSON (like OpenCode does) to declare its output format in a config file — because parseOutput is a JavaScript function and JSON can't serialize functions.

Proposed solution: Replace the parseOutput function field with a declarative "outputFormat": "json" | "ndjson" | "text" string field in both built-in configs and the JSON schema. Riteway owns the mapping from format name to parser. This makes the schema fully serializable, allows custom agents to declare their output format, and removes the hidden asymmetry between built-in and custom agent configs.

These two changes together would:

  • Decouple riteway from third-party CLI version churn
  • Make custom agent configs a first-class, fully-capable alternative to built-in configs
  • Keep the code clean (no functions in data)

Plan: Add a follow-up task before PR 6. The --agent-config CLI flag is where custom configs are consumed, so the output format strategy needs to be resolved before that PR lands.

3. formatZodError module placement

Currently exported from agent-config.js but has no external consumers. PR 5 (ai-runner.js) will also need Zod error formatting. If that happens, importing a Zod formatting utility from agent-config creates an odd dependency direction. Decision deferred to PR 5: if the formatter is needed there, move it to ai-errors.js at that time.


Checklist

  • All WIP fixes from the consolidation plan applied (Switch to node modules #2, Fix index.d.ts — should is optional #10, Fix Try in index.d.ts #11)
  • No for (const loops in test files (uses test.each where tables apply)
  • Every export has direct unit tests (including formatZodError both code paths)
  • assert({ given, should, actual, expected }) structure throughout
  • Dependency graph is acyclic: agent-config and validation are leaves at this layer
  • npm test — 186/186 passing
  • npm run lint — clean
  • npm run ts — clean

ianwhitedeveloper and others added 2 commits February 18, 2026 15:37
- agent-config: getAgentConfig() for claude/opencode/cursor agents
- agent-config: loadAgentConfig() reads + validates JSON config files
- validation: validateFilePath() guards against path traversal
- validation: verifyAgentAuthentication() smoke-tests agent availability
- fixtures: test-agent-config.json, invalid-agent-config.txt, no-command-agent-config.json

WIP fixes applied:
- #2: replace verbose schema JSDoc with single-line YAGNI comment
- #10: add --trust flag to cursor agent args for non-interactive execution

182 tests passing (19 new: 10 agent-config + 9 validation).

Co-authored-by: Cursor <cursoragent@cursor.com>
- add direct unit tests for formatZodError (4 cases, both code paths)
- simplify parseJson: remove unnecessary currying → plain two-arg fn
- remove spurious await on synchronous parseJson call
- convert multi-line string concat to template literal in validation.js
- rename misleading test: 'uses default timeout' → 'succeeds without explicit timeout argument'

Co-authored-by: Cursor <cursoragent@cursor.com>
@ericelliott
Copy link
Collaborator

@paralleldrive/parelleldrive-com please /review

Comment on lines +64 to +69
throw createError({
...ValidationError,
message: `Failed to read agent config file: ${configPath}`,
code: 'AGENT_CONFIG_READ_ERROR',
cause: err
});
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Note: These should use custom error types so handlers can automatically route them individually using a handleErrors pattern match. This is probably fine as-is, but we should write an error-causes skill so agents know how to properly use this library.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants