feat(web): agent-types settings CRUD UI (AT-6) #765

Merged
charles merged 2 commits from dev/748 into main 2026-05-02 20:37:18 +00:00
Collaborator

Summary

  • New Settings → Agent types page (/settings/agent-types) with a tab editor grouped by Identity / Container / Routing / Escalation / Examples
  • Scope selector per section (builtin/global for Identity; +agent_type for Container; +instance for Routing); "Fork to global" / "Fork to instance" buttons; reset-to-builtin (DELETE)
  • Confirm dialog for destructive identity edits (git_email / forgejo_user)
  • Field-level validation with inline error display
  • Eight new REST endpoints under /api/agent-types/:name covering upsert + delete for all three DB tables (agent_type, agent_type_container, agent_type_routing)
  • "Agent types" card added to the main Settings index

Closes #748

Test plan

  • Navigate to Settings → Agent types; confirm page loads with agent-type dropdown populated
  • Select an agent type; verify Identity tab shows resolved builtin values
  • Switch scope to global, change a field, save — confirm DB row created and values persist on reload
  • Edit git_email or forgejo_user → confirm destructive confirm dialog appears before saving
  • Click "Fork to global" on a builtin-scope Identity section — confirm scope switches to global with current values pre-filled
  • Open Container tab, fork to agent_type scope, save, reload — verify values persist
  • Open Routing tab, fork to instance scope (pick an instance), save, reload — verify per-instance row exists
  • Click "Reset to builtin" (DELETE) — confirm row is removed and values revert to builtin
  • Submit invalid data (empty required field) — confirm inline errors appear without saving
  • Verify Settings index shows the "Agent types" card with a working Configure link

🤖 Generated with Claude Code

## Summary - New **Settings → Agent types** page (`/settings/agent-types`) with a tab editor grouped by Identity / Container / Routing / Escalation / Examples - Scope selector per section (builtin/global for Identity; +agent_type for Container; +instance for Routing); "Fork to global" / "Fork to instance" buttons; reset-to-builtin (DELETE) - Confirm dialog for destructive identity edits (`git_email` / `forgejo_user`) - Field-level validation with inline error display - Eight new REST endpoints under `/api/agent-types/:name` covering upsert + delete for all three DB tables (`agent_type`, `agent_type_container`, `agent_type_routing`) - "Agent types" card added to the main Settings index Closes #748 ## Test plan - [ ] Navigate to Settings → Agent types; confirm page loads with agent-type dropdown populated - [ ] Select an agent type; verify Identity tab shows resolved builtin values - [ ] Switch scope to global, change a field, save — confirm DB row created and values persist on reload - [ ] Edit `git_email` or `forgejo_user` → confirm destructive confirm dialog appears before saving - [ ] Click "Fork to global" on a builtin-scope Identity section — confirm scope switches to global with current values pre-filled - [ ] Open Container tab, fork to agent_type scope, save, reload — verify values persist - [ ] Open Routing tab, fork to instance scope (pick an instance), save, reload — verify per-instance row exists - [ ] Click "Reset to builtin" (DELETE) — confirm row is removed and values revert to builtin - [ ] Submit invalid data (empty required field) — confirm inline errors appear without saving - [ ] Verify Settings index shows the "Agent types" card with a working Configure link 🤖 Generated with [Claude Code](https://claude.com/claude-code)
dev self-assigned this 2026-05-02 19:42:10 +00:00
feat(web): agent-types settings CRUD UI (AT-6, #748)
All checks were successful
qa / dockerfile (pull_request) Successful in 6s
qa / qa (pull_request) Successful in 2m53s
988bfe78b0
Add Settings → Agent types page with tab editor for Identity, Container,
Routing, Escalation and Examples sections. Each section exposes a scope
selector (builtin/global/agent_type/instance), per-field validation, a
confirm dialog for destructive identity changes (git_email/forgejo_user),
Fork-to-global and Fork-to-instance buttons, and reset-to-builtin (DELETE).

Server-side: eight new REST endpoints under /api/agent-types/:name covering
upsert and delete for all three DB tables (agent_type, agent_type_container,
agent_type_routing). Uses the existing resolver pattern from AT-1.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
dev requested review from reviewer 2026-05-02 19:45:05 +00:00
reviewer requested changes 2026-05-02 19:48:37 +00:00
Dismissed
reviewer left a comment
  • behavior agent-types-settings.ts ~line 321: existing is declared but never used, and the query has one ? but .get(name, scope) passes two params. Dead code + wrong type annotation — remove the existing block entirely; the builtinRow check below is the real guard.

  • behavior agent-types-settings.ts ~line 280: routing query type is [string, string] but SQL has one ?; .all(name, name) silently drops the second binding. Change to .all(name) / <RoutingRowRaw, [string]>.

  • AC gap Escalation and Examples tabs have no scope chips. Issue #748 AC says "Scope selector at the top of each editor." Escalation always silently writes to global; Examples inherits from wherever globalRow ?? builtinRow resolves. At minimum add a read-only label showing the active scope so operators know which layer they are editing.

- **behavior** `agent-types-settings.ts` ~line 321: `existing` is declared but never used, and the query has one `?` but `.get(name, scope)` passes two params. Dead code + wrong type annotation — remove the `existing` block entirely; the `builtinRow` check below is the real guard. - **behavior** `agent-types-settings.ts` ~line 280: routing query type is `[string, string]` but SQL has one `?`; `.all(name, name)` silently drops the second binding. Change to `.all(name)` / `<RoutingRowRaw, [string]>`. - **AC gap** Escalation and Examples tabs have no scope chips. Issue #748 AC says "Scope selector at the top of each editor." Escalation always silently writes to `global`; Examples inherits from wherever `globalRow ?? builtinRow` resolves. At minimum add a read-only label showing the active scope so operators know which layer they are editing.
fix(web): address review feedback on agent-types settings CRUD UI (AT-6)
All checks were successful
qa / dockerfile (pull_request) Successful in 7s
qa / qa (pull_request) Successful in 3m3s
1e002e774d
- Remove dead `existing` block in handleUpsertIdentity (query had one ?
  but passed two bindings; variable was never read)
- Fix routing list query type [string,string] → [string] and drop the
  second .all(name) binding that was silently ignored
- Add scope chips (Builtin / Global) to Escalation and Examples tabs so
  operators see which layer they are editing; both tabs reset draft and
  resync raw fields when scope changes, and hide the Save button in
  read-only (builtin) view

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Author
Collaborator

All three points fixed in 1e002e7:

  • Dead existing block (line ~321): removed entirely. The query had one ? but was typed [string, string] and passed .get(name, scope); the builtinRow check below was already the real guard.
  • Routing query binding (line ~280): changed to <RoutingRowRaw, [string]> and .all(name) — the second binding was silently dropped.
  • Scope chips on Escalation & Examples: both tabs now have interactive Builtin / Global scope chips matching the Identity tab pattern. Selecting Builtin shows the read-only layer and hides Save; Global is editable. Draft and raw textarea state reset on scope change.
All three points fixed in 1e002e7: - **Dead `existing` block** (line ~321): removed entirely. The query had one `?` but was typed `[string, string]` and passed `.get(name, scope)`; the `builtinRow` check below was already the real guard. - **Routing query binding** (line ~280): changed to `<RoutingRowRaw, [string]>` and `.all(name)` — the second binding was silently dropped. - **Scope chips on Escalation & Examples**: both tabs now have interactive `Builtin / Global` scope chips matching the Identity tab pattern. Selecting Builtin shows the read-only layer and hides Save; Global is editable. Draft and raw textarea state reset on scope change.
dev requested review from reviewer 2026-05-02 20:01:26 +00:00
reviewer approved these changes 2026-05-02 20:03:58 +00:00
reviewer left a comment

All three round-1 findings fixed:

  • Dead existing block removed
  • Routing query type corrected [string,string][string], .all(name) binding fixed
  • Scope chips added to Escalation and Examples tabs; read-only mode hides Save, drafts reset on scope change

CI green (run 2874, 1e002e7).

All three round-1 findings fixed: - Dead `existing` block removed - Routing query type corrected `[string,string]` → `[string]`, `.all(name)` binding fixed - Scope chips added to Escalation and Examples tabs; read-only mode hides Save, drafts reset on scope change CI green (run 2874, `1e002e7`).
charles deleted branch dev/748 2026-05-02 20:37:19 +00:00
Sign in to join this conversation.
No reviewers
No milestone
No project
No assignees
2 participants
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
charles/claude-hooks!765
No description provided.