0df2bbac0a
* docs(plugins): draft Host data API proto (read + write DTOs) Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * docs(plugins): ADR + spec + plan for the Host data API Plugins access kandev data via capability-gated Host gRPC RPCs returning hand-mapped DTOs, never the DB directly. ADR 0042. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * feat(plugins): add Host data API RPCs and DTOs to plugin proto Extends the existing service Host (per ADR 0042) with read RPCs (ListTasks/GetTask, ListWorkspaces, ListWorkflows, ListWorkflowSteps, ListAgentProfiles, ListRepositories, ListSessions, ListSessionCodeStats) and declares the deferred phase-2 write RPCs (CreateTask, UpdateTask, CreateComment) so the contract is stable for later tasks. Regenerates plugin.pb.go/plugin_grpc.pb.go via `make -C apps/backend proto`. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * feat(plugins): Host data API SDK accessors + session LOC aggregation Wave 1-2 of ADR 0042: pkg/pluginsdk gains typed reader accessors (host.Tasks(), host.Sessions().CodeStats(), host.Workflows(), ...) over the extended Host gRPC service, with proto<->native DTO conversions and an UnimplementedHostData seam for the kandev-side impl. internal/analytics gains the per-session LOC aggregation those readers surface. Backend handlers + capability gating land in the next wave. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * feat(plugins): capability-gated Host data read handlers (ADR 0042) Implement pluginHost Tasks/Sessions/Workspaces/Workflows/AgentProfiles/ Repositories readers: each gated on api_read:<resource> (PermissionDenied otherwise), backed by the service layer via narrow injected interfaces, and hand-mapped to the pluginsdk DTOs. Sessions().CodeStats routes through the analytics aggregation; acp_session_id preserves the metadata->resume_token fallback. Wired through plugins.Service.SetDataSources + backendapp. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * test(plugins): wire test for Host data reads + docs (ADR 0042 accepted) End-to-end test over the real go-plugin transport: session data round-trips, per-resource api_read gating returns PermissionDenied over the wire, cursor pagination. Document the Host data API + SDK accessors in GRPC-CONTRACT.md, reconcile the spec to shipped code, mark ADR 0042 accepted. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * feat(plugins): full session history + snapshot profile name in data API Sessions().List now fetches tasks with includeArchived=true — an archived task's sessions are still real sessions, and CodeStats already made the same call at the SQL layer, so the two session reads were inconsistent (26 of 359 sessions visible on a real instance). Tasks().List keeps archived tasks excluded. Session gains agent_profile_name (proto field 10) sourced from the profile snapshot, so sessions of since-uninstalled agents keep a human label — the AgentProfiles registry only lists live agents. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * docs(plugins): renumber Host data API ADR 0042 -> 0043 main merged its own ADR 0042 (project shell output); renumber this one to the next free slot and update all references. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * fix(plugins): address Host data API review (perf, pagination, filters, proto) - paginate before DTO conversion so per-session ACP lookups run <=limit times - fetch all source pages (no silent 1000/workspace truncation); accurate HasMore - stable id tiebreaker on paginated sorts - AND SessionFilter.TaskIDs with WorkspaceIDs; exclude config-mode sessions from CodeStats (shared dialect.ExcludeConfigModePredicate) so List/CodeStats match - Get returns codes.NotFound consistently in-process and over the wire - wrap bare-DTO RPC responses (GetTaskResponse etc.) for Buf response uniqueness Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * docs(plugins): mark Host data API plan tasks done --------- Co-authored-by: Kandev Agent <agent@kandev.dev> Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
6.9 KiB
6.9 KiB
id, title, status, wave, depends_on, plan, spec, adr
| id | title | status | wave | depends_on | plan | spec | adr | |
|---|---|---|---|---|---|---|---|---|
| 07-docs | Author docs: Host data API + manifest api_read/api_write resource list | done | 4 |
|
plan.md | ../../../specs/plugins/spec.md | ../../../decisions/0043-plugin-host-data-api.md |
Task 07: Author docs for the Host data API
Document the Host data API for plugin authors: which resources are readable, the
api_read/api_write capability vocabulary, and the SDK accessor surface.
Scope
- Wire reference (
docs/plans/plugins/GRPC-CONTRACT.md): add the Host data RPCs to theservice Hostblock (§3) and note capability gating usesapi_read:<resource>/api_write:<resource>(§5), replacing the "reserved" language. Note write RPCs are deferred (Unimplemented). - SDK reference (
docs/plans/plugins/GRPC-CONTRACT.md§4 and/orPLUGIN-API.md): document the author accessors (host.Tasks().List(...),host.Sessions().List(...),host.Sessions().CodeStats(...), etc.) and that they return Go-native structs. - Manifest reference: wherever the manifest
capabilitiesblock is documented for authors, list theapi_read/api_writeresource vocabulary (tasks,sessions,workspaces,workflows,agents,repositories,comments) and what each unlocks, with theapi_read: ["sessions"]example from the agent-stats plugin. - Public docs: if a user-facing plugin authoring page exists under
docs/public/**at implementation time, add the resource list there too; there is none today, so the authoritative author docs are the plans references above. Do not invent a new public page in this task.
Acceptance
GRPC-CONTRACT.mdlists the Host data RPCs and the per-resource capability gating; the "reserved / not implemented" wording forapi_read/api_writeis removed or scoped to the deferred write RPCs.- The manifest capability vocabulary is documented with the readable-resource list and an example.
Verification
- Markdown-only; no build.
cd apps && pnpm --filter @kandev/web lintonly if adocs/publicpage is touched (none expected).
Files likely touched
docs/plans/plugins/GRPC-CONTRACT.mddocs/plans/plugins/PLUGIN-API.md(if the SDK/author surface is documented there)
Inputs
- Final RPC set + accessor names from tasks 01/03/04.
- Spec: "Host data API"; ADR 0043.
Dependencies
Task 04 (behavior finalized).
Output contract
Summary, files changed, and status update here + in plan.md.
Output
Summary: Documented the Host data API (ADR 0043) in the wire/SDK contract reference and reconciled the spec section against the shipped code.
Files changed:
docs/plans/plugins/GRPC-CONTRACT.md— added the 9 read RPCs + 3 deferred write RPCs to theservice Hostblock (§3); added a new "§3a. Host data API (ADR 0043)" subsection covering the resource/capability table, deferred writes, service-layer/DTO conventions, pagination/timestamp/nullable/scoping conventions; added theHostinterface's 6 data accessors plus the 6 reader interfaces (TaskReader,SessionReader,WorkspaceReader,WorkflowReader,AgentProfileReader,RepositoryReader) with their real Go signatures, and an authoring example (manifest snippet +Sessions().CodeStatscall) to §4; rewrote the §5 "Capability gating" bullet to remove the stale "api_read/api_write reserved" wording and describe the real per-RPC gating plus the write RPCs' currentUnimplementedbehavior.docs/specs/plugins/spec.md— fixed capability-vocabulary drift against code (see below) and added a "Declaring data access" note under the manifest capabilities section; reworded the interceptor description to match the actual per-RPC inline checks (no shared unary interceptor exists in code); updated the readable-resources table'sListAgentProfilesrow.docs/plans/plugins/host-data-api/plan.md— marked task-07 done in the wave list.
Code-vs-doc drift found and corrected (spec.md only; code is source of truth, left unchanged):
- The
ListAgentProfilescapability isapi_read:agent_profilesin code (internal/plugins/host_data.go: resourceAgentProfiles = "agent_profiles", confirmed byhost_data_test.go), notapi_read:agentsas the spec had it in the manifest example, the resource-vocabulary sentence, and the readable- resources table. Fixed all three. - The spec's manifest example listed
"projects"as anapi_readresource; there is noListProjectsRPC, resource constant, or reader anywhere in the proto orinternal/plugins/host_data.go. Removed it from the example. - The spec described
api_read/api_writeas "reserved for future Host RPCs" in the manifest example comments and said the capability-gating interceptor covers "state, secrets; api_read/api_write reserved" — both predate this ADR shipping;api_readis live now (write RPCs remain deferred/Unimplemented). Reworded both. - The spec attributed capability gating to "a unary server interceptor on
Host"; there is no
grpc.UnaryServerInterceptorininternal/pluginsorpkg/pluginsdk— each Host/Host-data method checks its own capability inline at the top of the handler (host.go,host_data.go). Reworded to describe the actual per-RPC check without implying a shared interceptor layer (this was pre-existing drift, unrelated to ADR 0043, caught while editing the same paragraph). GRPC-CONTRACT.md's pre-ADR text already read "api_read/api_write reserved for future" in §5 and theservice Hostproto snippet only listed the 6 pre-ADR RPCs; both were stale relative to the shipped proto and are now updated in place.
Not touched (out of scope / already correct):
docs/decisions/0043-plugin-host-data-api.md— read for context per the task's Inputs; itsStatus: proposedfront matter looks stale given the code is fully implemented, but the task's edit scope was spec.md, not the ADR, so it is left for whoever finalizes the ADR's status.docs/plans/plugins/PLUGIN-API.md— this is the native frontend (JS) UI plugin contract; it has no backend Host/SDK content and the Host data API has no UI surface, so nothing there needed updating. The SDK reference went intoGRPC-CONTRACT.md§4 per the task's "and/or" framing.docs/public/plugins*.md— do not exist on this branch (confirmed); per the task instructions these live onfeature/kandev-plugin-system-docsand are out of scope here.apps/backend/internal/plugins/manifest/manifest_test.gohas an unrelated test fixture usingapi_read: ["tasks", "agents"]as a manifest capability example — manifest capability values are freeform strings with no vocabulary validation at that layer (confirmed: no enum/allow-list check ininternal/plugins/manifest), so this is a test fixture choice, not a functional bug; flagged here as a code-side echo of the same naming drift, left unchanged since it's code, not docs.