Skip to content

feat: agent baseUrl & model passthrough#130

Merged
dean0x merged 11 commits intomainfrom
feature/agent-config-passthrough
Apr 3, 2026
Merged

feat: agent baseUrl & model passthrough#130
dean0x merged 11 commits intomainfrom
feature/agent-config-passthrough

Conversation

@dean0x
Copy link
Copy Markdown
Owner

@dean0x dean0x commented Apr 1, 2026

Summary

  • Add baseUrl and model fields to per-agent configuration (~/.autobeat/config.json), enabling custom API endpoints and model selection for Claude Code, Codex CLI, and Gemini CLI
  • Thread model through the entire task lifecycle: domain types → MCP tools → CLI → spawn pipeline → database persistence (migration v16)
  • Inject baseUrl as the provider-specific env var (ANTHROPIC_BASE_URL, OPENAI_BASE_URL, GEMINI_BASE_URL) at spawn time with user env var precedence
  • Auto-disable Claude Code experimental beta headers when a custom baseUrl is configured (prevents proxy failures)
  • Add --model/-m flag to beat run and beat orchestrate CLI commands
  • Extend ConfigureAgent and ListAgents MCP tools with baseUrl/model support, including Claude-specific warning when baseUrl is set without an API key

Test plan

  • Build compiles cleanly (npm run build)
  • 1,546 tests passing across all grouped test suites
  • Agent config: round-trip save/load for baseUrl/model, no field clobbering, empty string clears key, trailing slash normalized
  • Agent adapters: baseUrl env var injection per adapter, user env precedence, --model flag in args, config model fallback, per-task model override, Claude experimental betas auto-disable
  • Task repository: save/load task with model field, backward compat for null model
  • MCP adapter: DelegateTask/ConfigureAgent/ListAgents with model and baseUrl, Claude warning when baseUrl set without apiKey
  • CLI: --model flag parsing on beat run and beat orchestrate
  • Manual: beat agents config set claude baseUrl https://proxy.example.com → verify shown in beat agents config show claude
  • Manual: beat run --model claude-sonnet-4-6 "hello" → verify --model in spawned args

Dean Sharon added 4 commits April 1, 2026 15:58
- Add baseUrl and model to AgentConfig; saveAgentConfig accepts 'apiKey'|'baseUrl'|'model'
- Add AGENT_BASE_URL_ENV mapping providers to their env var names
- BaseAgentAdapter: resolveBaseUrl() injects env var from config when user hasn't set it;
  resolveModel(taskModel?) applies per-task then falls back to config default
- ClaudeAdapter: overrides resolveBaseUrl() to also inject CLAUDE_CODE_DISABLE_EXPERIMENTAL_BETAS=1
  when a baseUrl is active
- Codex/GeminiAdapter: buildArgs(prompt, model?) threads --model flag
- ProcessSpawner/adapter: spawn() accepts optional model param (interface compliance)
- EventDrivenWorkerPool: passes task.model to spawn()
- TaskManager: preserves model on retry and resume
- Database migration v16: adds model TEXT column to tasks table
- TaskRepository: persist/restore model field; Zod schema + row type updated
- Domain: model field on Task, TaskRequest, PipelineStepRequest, PipelineCreateRequest,
  ScheduleCreateRequest, ScheduledPipelineCreateRequest, LoopCreateRequest, OrchestratorCreateRequest;
  propagated in createTask, createLoop, createOrchestration factories
- MCP: DelegateTask/ScheduleTask/CreatePipeline/SchedulePipeline/CreateLoop/ScheduleLoop schemas
  gain model field; ConfigureAgent gains baseUrl+model set/check; ListAgents exposes baseUrl/model;
  handleDelegateTask wires model to TaskRequest; all handlers thread model through
- CLI: beat run --model/-m flag; agents config set accepts baseUrl/model keys; agents config show
  displays baseUrl and model; shell history warning only for apiKey
- MCP instructions: document model resolution order and ConfigureAgent baseUrl/model usage
- Add missing `model` field to CreateOrchestrator MCP tool (Zod schema,
  inputSchema, and handler) so orchestrations can use per-task model overrides
- Thread shared `model` into taskTemplate for scheduled pipelines so the
  default model propagates to triggered pipeline tasks
- Add --model/-m flag to `beat orchestrate` CLI command
- Include model in OrchestratorStatus MCP response and CLI status output
… docs (task-2026-04-01_shepherd-fixes)

- Thread orchestration model to inner loop createLoop() call so iterations
  respect the --model flag passed to CreateOrchestrator
- Add Claude-specific warning in ConfigureAgent (set/check) and ListAgents
  when baseUrl is configured without an API key (login-based auth ignores baseUrl)
- Document in ConfigureAgent tool description that clearing individual fields
  requires action=reset or the CLI (MCP set action requires non-empty values)
- Tests: verify model is propagated to loop taskTemplate; verify Claude warning
  appears in set/check actions and ListAgents; verify no warning for other agents
@greptile-apps
Copy link
Copy Markdown
Contributor

greptile-apps bot commented Apr 1, 2026

Greptile Summary

This PR threads baseUrl and model configuration through the full autobeat stack — agent config file, domain types, MCP tools, CLI flags, the spawn pipeline, and SQLite persistence (migration v16). The implementation is thorough and well-tested (dedicated test suites for agent-config round-trips, adapter env/arg injection, task-repository persistence, and MCP tool responses).

Key changes:

  • AgentConfig gains baseUrl and model; saveAgentConfig normalises trailing slashes and treats empty string as a delete
  • BaseAgentAdapter.resolveBaseUrl() / resolveModel() implement the correct resolution order (per-task > agent-config > CLI default) with user-env-var precedence for baseUrl
  • ClaudeAdapter overrides resolveBaseUrl to auto-set CLAUDE_CODE_DISABLE_EXPERIMENTAL_BETAS=1 when a base URL is active, preventing proxy failures
  • AGENT_BASE_URL_ENV provides a single source of truth for provider → env-var mapping
  • Migration v16 adds a nullable model TEXT column to tasks with correct backward compatibility (null → undefined)
  • Two minor style findings: ClaudeProcessSpawner silently discards _model (safe today but a latent trap), and the 'baseUrl cleared'/'model cleared' message branches in the MCP set handler are unreachable through the MCP path due to Zod's url()/min(1) validators

Confidence Score: 5/5

Safe to merge — all remaining findings are P2 style/cleanup items with no correctness or data-integrity impact.

The feature is fully implemented end-to-end with correct precedence logic, env-var safety, backward-compatible migration, and comprehensive tests (1,546 passing). The two findings are both P2: one is a latent trap in a class confirmed unused in the production path, and the other is unreachable dead code in a message-building branch. Neither affects current behaviour.

src/implementations/process-spawner.ts (model silently discarded), src/adapters/mcp-adapter.ts (dead message branches)

Important Files Changed

Filename Overview
src/implementations/base-agent-adapter.ts Adds resolveBaseUrl() and resolveModel() helpers; threads both into spawn() with correct env-var/config precedence ordering.
src/implementations/claude-adapter.ts Overrides resolveBaseUrl() to auto-inject CLAUDE_CODE_DISABLE_EXPERIMENTAL_BETAS=1 when a base URL is active; logic is sound and stripping order is correct.
src/implementations/process-spawner.ts Signature updated to accept _model but the parameter is silently ignored; confirmed unused in the production agentRegistry path but the discard is not obvious from the call site.
src/adapters/mcp-adapter.ts Model field added to all schemas and threaded through correctly; the 'baseUrl cleared' / 'model cleared' message branches in the set action are unreachable dead code due to Zod validation.
src/core/configuration.ts Extends AgentConfig with baseUrl/model; saveAgentConfig now handles empty-string-as-delete and trailing-slash normalisation correctly.
src/implementations/database.ts Migration v16 adds nullable model TEXT column to tasks; backward-compatible and correctly placed in the migration sequence.
src/implementations/task-repository.ts model column added to all SELECT/INSERT/UPDATE statements and the Zod row schema; null → undefined coercion on read is correct.
src/core/domain.ts Model field added to Task, TaskRequest, and all schedule/pipeline/loop/orchestration request types; createTask and createOrchestration correctly propagate it.
src/services/orchestration-manager.ts Correctly spreads model into loop creation only when defined (!== undefined guard prevents accidental undefined spread).
src/core/agents.ts Adds AGENT_BASE_URL_ENV map as the single source of truth for provider-to-env-var mapping; spawn signature updated with optional model param.

Sequence Diagram

sequenceDiagram
    participant CLI as beat run / MCP tool
    participant TM as TaskManager
    participant Repo as TaskRepository (DB)
    participant WP as EventDrivenWorkerPool
    participant Reg as AgentRegistry
    participant Adapter as ClaudeAdapter / CodexAdapter / GeminiAdapter
    participant Proc as Child Process

    CLI->>TM: delegate(TaskRequest { model? })
    TM->>Repo: save(Task { model? })
    Note over Repo: migration v16 — model TEXT column
    TM->>WP: enqueue(task)

    WP->>Reg: getAdapter(task.agent)
    Reg-->>WP: AgentAdapter
    WP->>Adapter: spawn(prompt, cwd, taskId, task.model)

    Note over Adapter: resolveModel(taskModel)<br/>1. per-task model<br/>2. agentConfig.model<br/>3. CLI default (none)

    Note over Adapter: resolveBaseUrl()<br/>1. user env var (skip inject)<br/>2. agentConfig.baseUrl

    Adapter->>Adapter: buildArgs(prompt, resolvedModel)<br/>e.g. [--model, claude-opus-4-5, --, prompt]
    Adapter->>Proc: spawn(cmd, args, { env: {ANTHROPIC_BASE_URL?, ...} })
Loading

Comments Outside Diff (1)

  1. src/adapters/mcp-adapter.ts, line 418-429 (link)

    P2 Dead code: 'baseUrl cleared' and 'model cleared' message branches are unreachable via MCP

    Because ConfigureAgentSchema validates baseUrl with z.string().url() (rejects empty strings) and model with z.string().min(1) (rejects empty strings), neither value can ever be an empty/falsy string after parseResult.data is destructured. The ternary's false-branch in each push:

    messages.push(baseUrl ? `baseUrl set to ${baseUrl}` : 'baseUrl cleared');
    // ...
    messages.push(model ? `model set to ${model}` : 'model cleared');

    …can never be reached through the MCP set action. The 'baseUrl cleared' / 'model cleared' paths are only reachable through saveAgentConfig directly (e.g. the CLI path, which permits empty strings). Consider simplifying to unconditional strings here, or adding a comment explaining that these branches are unreachable from MCP but kept for potential direct callers:

    messages.push(`baseUrl set to ${baseUrl}`);
    // ...
    messages.push(`model set to ${model}`);

Reviews (1): Last reviewed commit: "fix: shepherd review fixes — model threa..." | Re-trigger Greptile

Comment thread src/implementations/process-spawner.ts Outdated
Comment on lines +24 to +25
// eslint-disable-next-line @typescript-eslint/no-unused-vars
spawn(prompt: string, workingDirectory: string, taskId?: string, _model?: string): Result<{ process: ChildProcess; pid: number }> {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

P2 _model silently dropped in ClaudeProcessSpawner

ClaudeProcessSpawner accepts the model parameter but discards it entirely. This is confirmed safe today — bootstrap.ts registers this class as the processSpawner service but that service is never retrieved by any production consumer (the agentRegistry uses ClaudeAdapter directly). However, the silent discard creates a trap: if ClaudeProcessSpawner is ever re-wired into a live spawn path, tasks that specify a model will silently use the CLI's default model instead of the requested one, with no error or warning.

Consider either:

  • Adding a TODO/FIXME comment that explicitly documents the model is intentionally not forwarded, or
  • Implementing it the same way ClaudeAdapter.buildArgs does (['--model', model]) so the class is a complete implementation of the updated interface.

Dean Sharon added 2 commits April 3, 2026 01:03
Replace misleading "placeholder" wording with explanation of why
taskTemplate exists alongside loopConfig on scheduled loops.
@dean0x
Copy link
Copy Markdown
Owner Author

dean0x commented Apr 2, 2026

Code Review Findings

I've analyzed the code review reports and identified blocking issues requiring attention before merge:

CRITICAL (5 issues - 95% confidence)

  • Model field silently dropped on DB roundtrip for loops, schedules, and pipelines
  • Orchestration model field not persisted to database

HIGH (6 issues - 80-92% confidence)

  • Repeated loadAgentConfig() calls (3x per spawn)
  • JSON Schema validation inconsistent for model field
  • Partial-write risk in ConfigureAgent set action
  • Missing baseUrl validation in CLI path
  • Duplicate test blocks in test file

Posting inline comments on specific files now.

@dean0x
Copy link
Copy Markdown
Owner Author

dean0x commented Apr 2, 2026

BLOCKING ISSUES (80%+ confidence)

CRITICAL (95% confidence)

1. Model field stripped on DB roundtrip (4 locations)

Files affected:

  • (TaskRequestSchema)
  • (TaskRequestSchema)
  • (PipelineStepsSchema)
  • (LoopConfigSchema)

The model field is not included in these Zod boundary schemas. When data is persisted to the database and then loaded back, Zod's .parse() strips unknown keys, causing model to be silently lost. This breaks per-task model overrides for:

  • Loops after server restart or recovery
  • Scheduled tasks after persistence roundtrip
  • Scheduled pipeline steps
  • Scheduled loop iterations

Fix: Add model: z.string().optional() to each schema:

// TaskRequestSchema
agent: z.enum(AGENT_PROVIDERS_TUPLE).optional(),
model: z.string().optional(),

// PipelineStepsSchema (within step object)
agent: z.enum(AGENT_PROVIDERS_TUPLE).optional(),
model: z.string().optional(),

// LoopConfigSchema
agent: z.enum(AGENT_PROVIDERS_TUPLE).optional(),
model: z.string().optional(),

2. Orchestration model not persisted to database

Files affected:

  • src/implementations/orchestration-repository.ts:25-58 (OrchestrationRowSchema, OrchestrationRow)
  • src/implementations/orchestration-repository.ts:279-314 (toRow/rowToOrchestration methods)
  • src/implementations/database.ts (no migration for model column)

The Orchestration domain type includes model?: string but:

  1. No database migration adds a model column to the orchestrations table
  2. OrchestrationRowSchema, OrchestrationRow, toRow(), and rowToOrchestration() don't include model

Result: model is in-memory only and lost on persistence. After server restart, OrchestratorStatus and beat orchestrate status will never show the model.

Fixes required:

  1. Add migration v17 in database.ts: ALTER TABLE orchestrations ADD COLUMN model TEXT
  2. Add model: z.string().nullable() to OrchestrationRowSchema
  3. Add readonly model: string | null to OrchestrationRow interface
  4. Update toRow(): add model: orchestration.model ?? null
  5. Update rowToOrchestration(): add model: data.model ?? undefined
  6. Add model to INSERT and UPDATE SQL statements

HIGH (80-92% confidence)

3. loadAgentConfig() called 3x per spawn

File: src/implementations/base-agent-adapter.ts:76, 103, 116

Each spawn() invocation calls loadAgentConfig() three times:

  • Line 76: in resolveAuth()
  • Line 103: in resolveBaseUrl()
  • Line 116: in resolveModel()

Each call reads ~/.autobeat/config.json from disk and parses JSON. Under concurrent task delegation (multiple workers spawning in parallel), this triples disk I/O.

Fix: Load config once at the start of spawn() and pass it to all three resolution methods.

4. JSON Schema model field validation inconsistent

Files: src/adapters/mcp-adapter.ts (multiple tool definitions)

The model field JSON Schema definitions are inconsistent:

  • DelegateTask (line ~600): Has minLength: 1, maxLength: 200
  • ScheduleTask (line ~756): Missing constraints
  • CreatePipeline steps (line ~888): Missing constraints
  • CreatePipeline top-level (line ~912): Missing constraints
  • SchedulePipeline steps (line ~954): Missing constraints
  • SchedulePipeline top-level (line ~1011): Missing constraints
  • CreateLoop (line ~1105): Missing constraints
  • ScheduleLoop (line ~1257): Missing constraints
  • CreateOrchestrator (line ~1300): Missing constraints
  • ConfigureAgent (line ~1408): Missing constraints

MCP clients rely on JSON Schema for validation. Inconsistent constraints cause confusion and may allow invalid values to be sent.

Fix: Add minLength: 1, maxLength: 200 to all model field definitions in inputSchema blocks.

5. ConfigureAgent set action — partial-write risk

File: src/adapters/mcp-adapter.ts:2983-3065

The set action saves apiKey, baseUrl, and model sequentially with early returns. If apiKey saves but baseUrl fails, the method returns an error while apiKey is already persisted. The caller sees isError: true and may assume nothing changed, but the disk has a partial update.

Fixes (choose one):

  1. Batch write: Build merged config object first, then write once
  2. Partial state in error: Return savedFields array in error so caller knows current state

6. CLI baseUrl validation missing

File: src/cli/commands/agents.ts:106

The CLI beat agents config set <agent> baseUrl <value> accepts any string without validation. The MCP path validates with z.string().url(), but the CLI path skips validation. Malformed URLs (file:///, javascript:, non-URLs) would be injected as environment variables for spawned processes.

Fix: Validate with new URL(value) before calling saveAgentConfig.


Recommendation: These issues must be addressed before merge. The CRITICAL issues (5 instances) cause silent data loss where the feature appears to work initially but fails after persistence. The HIGH issues prevent the feature from working correctly in production workloads.

@dean0x
Copy link
Copy Markdown
Owner Author

dean0x commented Apr 2, 2026

MEDIUM-CONFIDENCE SUGGESTIONS (60-79%)

These don't block merge but should be tracked for next release:

Complexity

  • Duplicated Claude baseUrl warning logic (88% confidence): The warning 'Warning: Claude requires an API key when using a custom baseUrl...' appears in 3 places (check action, set action, ListAgents). Extract to shared helper.

  • handleConfigureAgent complexity growing (85% confidence): The method is now 154 lines with nested conditionals. Extract set case into handleConfigureAgentSet() and check case into handleConfigureAgentCheck().

  • mcp-adapter.ts at 3086 lines (80% confidence): File continues to grow. Consider extracting Zod schemas and tool definitions into separate files (mcp-schemas.ts, mcp-tool-definitions.ts).

Performance

  • loadAgentConfig() re-read in ListAgents and ConfigureAgent (82% confidence): The handlers call loadAgentConfig() multiple times per request. Cache at handler start and reuse.

  • saveAgentConfig() loads config twice on sequential calls (70% confidence): ConfigureAgent set calls saveAgentConfig 3 times for apiKey/baseUrl/model. Batch into single read-modify-write cycle.

Architecture

  • ProcessSpawner interface duplication (80% confidence): ProcessSpawner.spawn() and AgentAdapter.spawn() now have identical signatures. Consider deprecating ProcessSpawner and migrating tests to mock AgentAdapter.

Testing

  • No test for TaskManager.retry() preserving model (82% confidence): The production code threads model: originalTask.model but no test verifies it survives retry operation.

  • No test for TaskManager.resume() preserving model (82% confidence): Same as retry - production code is correct but unverified by tests.

  • No tests for ScheduleHandler model threading (80% confidence): handlePipelineTrigger and createScheduledLoop thread model but service-layer tests don't verify this.


SUMMARY

Blocking Issues: 6 (including 2 CRITICAL with 95% confidence, 4 HIGH with 80-92%)
Should-Fix Issues: 1 (test duplication - 85% confidence)
Medium-Confidence: 10+ suggestions

The PR demonstrates strong architectural consistency for the model passthrough feature across all layers. However, the 5 CRITICAL data-loss issues in persistence schemas and the HIGH-severity validation gaps must be fixed before merge. These are not architectural concerns but implementation gaps where the feature was added to domain types and APIs but not fully integrated into the persistence and validation layers.

Once fixed, this will be a clean, well-tested feature addition.

Dean Sharon added 5 commits April 3, 2026 02:11
The CLI path for 'beat agents config set <agent> baseUrl <value>' accepted
any string without validation, while the MCP ConfigureAgent tool correctly
enforced z.string().url(). Adds new URL() validation before saveAgentConfig
to reject malformed URLs with a user-friendly error message, matching the
MCP validation boundary. Empty string (clear) is still allowed.
BaseAgentAdapter.spawn() previously called loadAgentConfig() independently
inside resolveAuth(), resolveBaseUrl(), and resolveModel(), causing three
separate readFileSync + JSON.parse operations per spawn. Config is now
loaded once at the top of spawn() and passed as an AgentConfig parameter
to each of the three methods. ClaudeAdapter.resolveBaseUrl() updated to
accept and forward the pre-loaded config to super.
…hedules, and orchestrations

Add model to TaskRequestSchema in loop-repository and schedule-repository so Zod does
not strip it on read-back. Add model to PipelineStepsSchema step object and LoopConfigSchema
in schedule-repository for the same reason. Add migration v17 to add model column to the
orchestrations table, and wire model through OrchestrationRowSchema, OrchestrationRow,
toRow(), rowToOrchestration(), and the INSERT/UPDATE SQL statements.
…onstraints

- configure-agent-partial-write: replace sequential early-return saves with
  collect-all pattern; errors now report which fields were already saved via
  alreadySaved[] to make partial-write visible instead of silent
- json-schema-model-validation-inconsistent: add minLength:1/maxLength:200 to
  model fields in ScheduleTask, CreatePipeline (step+top-level),
  SchedulePipeline (step+top-level), CreateLoop, ScheduleLoop,
  CreateOrchestrator, and ConfigureAgent inputSchema blocks — matching the
  existing Zod schemas and the DelegateTask JSON Schema pattern
- record-string-unknown-type-safety: replace Record<string,unknown> with
  typed CheckPayload and SetPayload interfaces in handleConfigureAgent
- duplicated-claude-baseurl-warning: extract getClaudeBaseUrlWarning() private
  helper; remove three copies of identical condition+string
…ths (batch-e)

- Add retry() model threading tests: verify model survives retry for both
  set and undefined values, preventing silent regression if the field is dropped
- Add resume() model threading tests: same coverage for resume path
- Add schedule manager model threading tests: createSchedule threads model to
  taskTemplate; createPipeline threads shared and per-step model; createScheduledLoop
  threads model through both taskTemplate and loopConfig
- Fix stale docstring in ClaudeAdapter: remove reference to prompt transformation
  that was dropped during the v0.5.0 BaseAgentAdapter refactor
@dean0x dean0x merged commit 3d894e2 into main Apr 3, 2026
1 check failed
@dean0x dean0x deleted the feature/agent-config-passthrough branch April 3, 2026 10:44
dean0x pushed a commit that referenced this pull request Apr 10, 2026
Release v1.2.0 with two features merged since v1.1.0:

- Terminal Dashboard (#131): Ink-based TUI (`beat dashboard`/`dash`)
  with 4 panels, keyboard nav, detail views, per-panel filters
- Agent baseUrl & model passthrough (#130): per-agent config, --model
  CLI flag, provider env var injection, Migration 16

No breaking changes. Fully additive.

Also includes biome formatter auto-fixes for src/adapters/mcp-adapter.ts,
src/cli/dashboard/*, src/implementations/base-agent-adapter.ts, and
related tests — these landed on main via admin-merged PRs and were
blocking CI.
@dean0x dean0x mentioned this pull request Apr 10, 2026
6 tasks
dean0x pushed a commit that referenced this pull request Apr 10, 2026
Two pre-existing test bugs that only surfaced once CI got past the
formatter step on this release PR:

1. panel.test.tsx:50 — 'renders children' was wrapping a raw string in
   <React.Fragment> inside a <Box>. Ink requires text to be wrapped in
   <Text>. On macOS local the render was lenient; on Linux CI the frame
   came back as '\n'. Fixed by using <Text>child content</Text>.

2. use-keyboard.test.tsx press() — the 0ms setTimeout flush wasn't giving
   ink's useInput effect enough time to re-register after React 19 state
   commits on Linux CI runners. Escape (\x1B) also needs ink's internal
   escape-sequence debounce to settle. Bumped the macrotask flush to
   10ms and added explicit microtask flushes on both sides. Local test
   duration for this suite goes from ~100ms to ~450ms — acceptable for
   reliability.

These two tests have never run green in CI (both #130 and #131 were
admin-merged past a failing biome step, so the test phase was skipped).
Not regressions — latent bugs surfaced by fixing the formatter block.
dean0x added a commit that referenced this pull request Apr 10, 2026
## Summary

Release v1.2.0 — **Terminal Dashboard & Agent Config Passthrough**.
Fully additive, no breaking changes.

### Features Since v1.1.0
- **Terminal Dashboard** (#131): `beat dashboard` / `beat dash` Ink TUI
with 4 panels (loops, tasks, schedules, orchestrations), keyboard
navigation (Tab/Shift+Tab, 1-4, j/k, Enter, Esc, f, q, r), detail views
per entity, per-panel filter cycles, truncation indicators, and smart
EmptyState.
- **Agent baseUrl & model passthrough** (#130): Per-agent `baseUrl` and
`model` in `~/.autobeat/config.json`; `--model`/`-m` CLI flag on `beat
run` and `beat orchestrate`; provider env var injection
(`ANTHROPIC_BASE_URL`, `OPENAI_BASE_URL`, `GEMINI_BASE_URL`); Claude
experimental-betas auto-disable on custom `baseUrl`; extended
`ConfigureAgent`/`ListAgents` MCP tools.

### Database
- **Migration 16**: Adds `model` column to both `tasks` and
`orchestrations` tables. Auto-applies on startup, backward compatible.

## Files Changed
- `package.json` / `package-lock.json` — version bump 1.1.0 → 1.2.0
- `CHANGELOG.md` — v1.2.0 entry under `[Unreleased]`
- `docs/releases/RELEASE_NOTES_v1.2.0.md` — new, required by release
workflow
- `docs/releases/RELEASE_NOTES.md` — index updated (v1.2.0 latest,
v1.1.0 moved)
- `docs/FEATURES.md` — added v1.2.0 section, reframed stale "Web UI"
line as "No web-based UI (TUI dashboard available via `beat dashboard`)"
- `docs/ROADMAP.md` — current status → v1.2.0, added to Released
Versions and Version Timeline, removed TUI dashboard from upcoming
Monitoring & REST API section
- `CLAUDE.md` — replaced Release Process section with a mechanical
recipe (version decision matrix, file checklist, validation commands,
Snyk step, commit/PR/merge flow, workflow trigger, post-release
verification, gotchas including orphan-publish recovery)

### Formatter Cleanup (bundled)
This PR also includes biome formatter auto-fixes for files landed on
main via admin-merged PRs #130/#131 that were blocking CI. Files
affected: `src/adapters/mcp-adapter.ts`,
`src/cli/dashboard/{components,types,use-keyboard,views}`,
`src/implementations/base-agent-adapter.ts`, and related tests. Produced
by `npm run check:fix` (formatter-only, no semantic changes).

## Security Scan
Ran `mcp__Snyk__snyk_code_scan` on `src/` with
`severity_threshold=medium`. Found **2 pre-existing Medium Path
Traversal findings** in `src/core/orchestrator-state.ts` /
`src/cli/commands/orchestrate.ts` / `src/utils/validation.ts` (unchanged
files from v1.0.0 orchestration code). **Not introduced by this
release.** No new findings from #130 or #131 changes. Not blocking.

## Test plan
- [x] `npm run typecheck` clean
- [x] `npm run check` clean (after formatter fixes)
- [x] `npm run build` clean
- [x] Grouped test suites pass locally: core (359), handlers (168),
services (179), repositories (211), adapters (110), implementations
(327), cli (295), dashboard (253), scheduling (139), checkpoints (36),
error-scenarios (31), orchestration (79), integration (70/75 — known
flaky `worker-pool-management.test.ts` OOMs in Claude Code only, passes
in CI)
- [ ] CI runs full `test:all` — source of truth
- [ ] Squash merge → trigger release workflow manually via `gh workflow
run release.yml --ref main`

---------

Co-authored-by: Dean Sharon <deanshrn@gmain.com>
dean0x pushed a commit that referenced this pull request Apr 12, 2026
All Added/Changed/Fixed/Breaking bullets now include (#133) links,
consistent with the style used in v1.2.0 (#131, #130) and prior entries.
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.

1 participant