/** * `/api/v1/editors` (DES-artifact-editor-plugins §6, §8.2, §9.1; EP-C1). * * - `GET /editors` (operator+): the registry, as Settings → Editors renders it. * - `POST /editors {packRoot, enabled?}` (HUMAN-only): install or update a pack's editors — garden's * fail-closed gate, then crew's own conformance run, then the registry (`pack-install.ts`). 200 with * the installed editors; 422 with the verdict or the conformance report; 501 with the approval list * for a pack that also ships skills or blocks; 409 for an id another pack or a first-party editor holds. * - `DELETE /editors/:id` (HUMAN-only): an installed pack editor is removed from the registry (the * installer deletes its files); a first-party editor ships with studio and cannot be removed (409; * disable it instead). * - `POST /editors/:id/enabled {enabled}` (HUMAN-only): the operator's switch. * - `GET /editors/:id/grants?project=` (operator+): the engine's decided set * (`evaluate_editor_grants`: EDITOR-GRANTS ledger + EDITOR-BUILTIN posture, deny dominates), with * the token an "allow" would add. The host fetches it before `host.hello` and enforces it. * - `GET /editors/:id/:version/entry`: the bundle, with exactly the §8.2 headers. The file path comes * from the registry record — never from the URL — and the bytes are re-hashed on every serve: a * changed file answers 409 `bundle_hash_mismatch`, never the changed bundle. * * Human-only means `actor.kind === 'human'` (the DC `remember()` check). Under `auth=off` every * same-uid caller is the local human actor — the honest limit §6.4 states; refusing a worker token * is a tripwire, not a control. */ import type { FastifyInstance, FastifyReply } from 'fastify'; import type { ConformanceRule, EditorGrantsResponse } from '../core/types.js'; import { type ConformanceRunner, type PackCheckRunner } from './pack-install.js'; import { EditorRegistry, type EditorRecord } from './registry.js'; /** The slice of the adapter the grants route needs; every method optional so a stub never throws. */ export interface EditorGrantsAdapter { editorGrantsSupported?(): boolean; evaluateEditorGrants?(request: { editorId: string; version: string; sha256: string; permissions: string[]; project?: string; firstParty: boolean; }): Promise; /** The rule store, for the install consent's `mcp.session` grant (DES-MCP-INSPECTOR-001 §6). */ listConformanceRules?(): Promise; upsertConformanceRule?(rule: ConformanceRule): Promise; } /** The approvals ledger the engine reads (core `editor_gate.rs` GRANTS_LEDGER). */ export declare const EDITOR_GRANTS_LEDGER = "EDITOR-GRANTS"; /** The permission only an install consent grants: no posture or allow rule can (core LEDGER_ONLY_PERMISSIONS). */ export declare const INSTALL_GRANTED = "mcp.session"; export declare function grantToken(id: string, version: string, sha256: string, permission: string): string; /** * Rewrite the ledger's `mcp.session` tokens for `ids`: every token of those editors is dropped, and * `add` (this install's tokens, for the builds that declare it) is written. One read-modify-write; * nothing is written when the list is unchanged. With nothing to add, an engine with no ledger has * no grant to withdraw, so that is no change; with something to add it is an error (it would ask). * * The edit is serialized against the other editor routes only. A governance write landing between * the read and the upsert is not covered, the same limit as the MCP approvals ledger (`mcp/policies.ts`). */ export declare function editInstallGrants(adapter: EditorGrantsAdapter, ids: readonly string[], add: readonly string[]): Promise; export interface EditorRoutesDeps { registry: EditorRegistry; adapter: EditorGrantsAdapter; packCheck: PackCheckRunner; /** The install-time conformance run (garden's runner against this daemon's conformance host page). */ conformance: ConformanceRunner; log?: (msg: string) => void; } export declare function registerEditorRoutes(app: FastifyInstance, deps: EditorRoutesDeps): void; /** Re-hash on every serve: a bundle that changed on disk is refused, never served. */ export declare function serveBundle(record: EditorRecord, reply: FastifyReply, log?: (msg: string) => void): FastifyReply; //# sourceMappingURL=routes.d.ts.map