SR-7 CRUD endpoints for agent_skill (type + instance) #875

Closed
opened 2026-05-05 10:29:54 +00:00 by claude-desktop · 1 comment
Collaborator

User story

As an operator, I want HTTP endpoints to list, upsert, and delete skill rows scoped to either an agent_type or an agent instance, so that the new web UI can run all CRUD without touching the legacy /agent-config/* routes.

Acceptance criteria

Type-scope endpoints

  • GET /agents/<type>/skills → array of { name, body, updated_at } for agent_skill rows where scope='type' and agent_type=<type>.
  • POST /agents/<type>/skills body { name, body } → upsert with scope='type'. Returns 200 + the persisted row.
  • DELETE /agents/<type>/skills/<name> → delete row. 404 when no matching row.

Instance-scope endpoints

  • GET /agents/<type>/<instance>/skills → array of { name, body, updated_at } for agent_skill rows where scope='instance' and instance_id matches. Includes a parallel "inherits from type" array of names that are present at type scope but not overridden at instance scope, so the UI can show the full effective list.
  • POST /agents/<type>/<instance>/skills body { name, body } → upsert with scope='instance', instance_id=<instance>, agent_type=<type>. Trigger from SR-1 enforces consistency between the URL <type> and the agents row.
  • DELETE /agents/<type>/<instance>/skills/<name> → delete the instance-scope row only; type-scope row (if any) is untouched and becomes effective again.

Pool-session caveat

  • When a POST /agents/<type>/<instance>/skills succeeds and at least one active session exists for the instance's pool ((forge, type, repo, issue) keys), the response payload includes pool_session_warning: true and a body listing the affected sessions. The UI can render a warning. Server does not auto-invalidate; that policy lives in SR-9 / a follow-up.

Auth

  • All endpoints require the same operator-auth middleware as the existing /agent-config/* routes (Authelia + admin scope).

Tests

  • agent-skill-routes.test.ts — happy-path CRUD, 404 on missing row, trigger rejection on mismatched <type> vs agents.type, FK cascade behaviour when an agents row is deleted.

Out of scope

  • The web UI consuming these endpoints (covered in SR-8).
  • Preview / render endpoint (covered in SR-9).
  • Removing the legacy /agent-config/* routes for kind=skills (covered in SR-10).

References

  • Spec: specs/skills-rework.md §API surface, §CRUD UI.
  • Existing route registration: apps/server/src/main.ts.
  • Depends on SR-1.
## User story As an operator, I want HTTP endpoints to list, upsert, and delete skill rows scoped to either an `agent_type` or an `agent instance`, so that the new web UI can run all CRUD without touching the legacy `/agent-config/*` routes. ## Acceptance criteria ### Type-scope endpoints - [ ] `GET /agents/<type>/skills` → array of `{ name, body, updated_at }` for `agent_skill` rows where `scope='type'` and `agent_type=<type>`. - [ ] `POST /agents/<type>/skills` body `{ name, body }` → upsert with `scope='type'`. Returns 200 + the persisted row. - [ ] `DELETE /agents/<type>/skills/<name>` → delete row. 404 when no matching row. ### Instance-scope endpoints - [ ] `GET /agents/<type>/<instance>/skills` → array of `{ name, body, updated_at }` for `agent_skill` rows where `scope='instance'` and `instance_id` matches. Includes a parallel "inherits from type" array of names that are present at type scope but not overridden at instance scope, so the UI can show the full effective list. - [ ] `POST /agents/<type>/<instance>/skills` body `{ name, body }` → upsert with `scope='instance'`, `instance_id=<instance>`, `agent_type=<type>`. Trigger from SR-1 enforces consistency between the URL `<type>` and the agents row. - [ ] `DELETE /agents/<type>/<instance>/skills/<name>` → delete the instance-scope row only; type-scope row (if any) is untouched and becomes effective again. ### Pool-session caveat - [ ] When a `POST /agents/<type>/<instance>/skills` succeeds and at least one active session exists for the instance's pool (`(forge, type, repo, issue)` keys), the response payload includes `pool_session_warning: true` and a body listing the affected sessions. The UI can render a warning. Server does not auto-invalidate; that policy lives in SR-9 / a follow-up. ### Auth - [ ] All endpoints require the same operator-auth middleware as the existing `/agent-config/*` routes (Authelia + admin scope). ### Tests - [ ] `agent-skill-routes.test.ts` — happy-path CRUD, 404 on missing row, trigger rejection on mismatched `<type>` vs `agents.type`, FK cascade behaviour when an `agents` row is deleted. ## Out of scope - The web UI consuming these endpoints (covered in SR-8). - Preview / render endpoint (covered in SR-9). - Removing the legacy `/agent-config/*` routes for kind=skills (covered in SR-10). ## References - Spec: `specs/skills-rework.md` §API surface, §CRUD UI. - Existing route registration: `apps/server/src/main.ts`. - Depends on **SR-1**.
Collaborator

🦵 @charles kicked the queue — re-running implement on @code-lead.

🦵 @charles kicked the queue — re-running implement on @code-lead.
Sign in to join this conversation.
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#875
No description provided.