@cleocode/contracts 2026.6.13 → 2026.6.14
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/__tests__/operation-def.test.js +4 -1
- package/dist/__tests__/operation-def.test.js.map +1 -1
- package/dist/__tests__/provider-def.test.d.ts +12 -0
- package/dist/__tests__/provider-def.test.d.ts.map +1 -0
- package/dist/__tests__/provider-def.test.js +84 -0
- package/dist/__tests__/provider-def.test.js.map +1 -0
- package/dist/__tests__/service-provider.test.d.ts +17 -0
- package/dist/__tests__/service-provider.test.d.ts.map +1 -0
- package/dist/__tests__/service-provider.test.js +108 -0
- package/dist/__tests__/service-provider.test.js.map +1 -0
- package/dist/boundary.d.ts +52 -0
- package/dist/boundary.d.ts.map +1 -1
- package/dist/boundary.js +23 -0
- package/dist/boundary.js.map +1 -1
- package/dist/conduit.d.ts +171 -0
- package/dist/conduit.d.ts.map +1 -1
- package/dist/config/index.d.ts +23 -0
- package/dist/config/index.d.ts.map +1 -0
- package/dist/config/index.js +22 -0
- package/dist/config/index.js.map +1 -0
- package/dist/config.d.ts +2 -1
- package/dist/config.d.ts.map +1 -1
- package/dist/dispatch/__tests__/tasks-gateway-crud-ops.test.d.ts +21 -0
- package/dist/dispatch/__tests__/tasks-gateway-crud-ops.test.d.ts.map +1 -0
- package/dist/dispatch/__tests__/tasks-gateway-crud-ops.test.js +84 -0
- package/dist/dispatch/__tests__/tasks-gateway-crud-ops.test.js.map +1 -0
- package/dist/dispatch/identity.d.ts +1 -1
- package/dist/dispatch/identity.d.ts.map +1 -1
- package/dist/dispatch/identity.js +20 -0
- package/dist/dispatch/identity.js.map +1 -1
- package/dist/dispatch/operation-def.d.ts +20 -0
- package/dist/dispatch/operation-def.d.ts.map +1 -1
- package/dist/dispatch/operations-registry.d.ts.map +1 -1
- package/dist/dispatch/operations-registry.js +1030 -46
- package/dist/dispatch/operations-registry.js.map +1 -1
- package/dist/index.d.ts +15 -6
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +15 -2
- package/dist/index.js.map +1 -1
- package/dist/lease-ipc/__tests__/freeze.test.js +92 -0
- package/dist/lease-ipc/__tests__/freeze.test.js.map +1 -1
- package/dist/lease-ipc/index.d.ts +2 -2
- package/dist/lease-ipc/index.d.ts.map +1 -1
- package/dist/lease-ipc/index.js +1 -1
- package/dist/lease-ipc/index.js.map +1 -1
- package/dist/lease-ipc/messages.d.ts +167 -3
- package/dist/lease-ipc/messages.d.ts.map +1 -1
- package/dist/lease-ipc/messages.js +93 -0
- package/dist/lease-ipc/messages.js.map +1 -1
- package/dist/llm/catalog-schema.d.ts +242 -0
- package/dist/llm/catalog-schema.d.ts.map +1 -0
- package/dist/llm/catalog-schema.js +153 -0
- package/dist/llm/catalog-schema.js.map +1 -0
- package/dist/llm/catalog-schema.json +139 -0
- package/dist/llm/index.d.ts +15 -0
- package/dist/llm/index.d.ts.map +1 -0
- package/dist/llm/index.js +14 -0
- package/dist/llm/index.js.map +1 -0
- package/dist/llm/oauth.d.ts +16 -2
- package/dist/llm/oauth.d.ts.map +1 -1
- package/dist/llm/onboarding.d.ts +126 -0
- package/dist/llm/onboarding.d.ts.map +1 -0
- package/dist/llm/onboarding.js +34 -0
- package/dist/llm/onboarding.js.map +1 -0
- package/dist/llm/provider-def.d.ts +254 -0
- package/dist/llm/provider-def.d.ts.map +1 -0
- package/dist/llm/provider-def.js +93 -0
- package/dist/llm/provider-def.js.map +1 -0
- package/dist/llm/system-resolver.d.ts +42 -0
- package/dist/llm/system-resolver.d.ts.map +1 -1
- package/dist/operations/admin.d.ts +124 -1
- package/dist/operations/admin.d.ts.map +1 -1
- package/dist/operations/entities.d.ts +110 -0
- package/dist/operations/entities.d.ts.map +1 -0
- package/dist/operations/entities.js +695 -0
- package/dist/operations/entities.js.map +1 -0
- package/dist/operations/llm.d.ts +15 -0
- package/dist/operations/llm.d.ts.map +1 -1
- package/dist/operations/output-contracts-data.d.ts.map +1 -1
- package/dist/operations/output-contracts-data.js +230 -0
- package/dist/operations/output-contracts-data.js.map +1 -1
- package/dist/operations/service.d.ts +68 -0
- package/dist/operations/service.d.ts.map +1 -0
- package/dist/operations/service.js +336 -0
- package/dist/operations/service.js.map +1 -0
- package/dist/operations/tasks.d.ts +109 -0
- package/dist/operations/tasks.d.ts.map +1 -1
- package/dist/operations/tasks.js.map +1 -1
- package/dist/playbook.d.ts +56 -0
- package/dist/playbook.d.ts.map +1 -1
- package/dist/release/plan.d.ts +5 -5
- package/dist/vault/service-provider.d.ts +343 -0
- package/dist/vault/service-provider.d.ts.map +1 -0
- package/dist/vault/service-provider.js +857 -0
- package/dist/vault/service-provider.js.map +1 -0
- package/dist/workgraph.d.ts +12 -12
- package/package.json +10 -2
- package/src/__tests__/__snapshots__/operations-registry.test.ts.snap +1 -1
- package/src/__tests__/operation-def.test.ts +6 -1
- package/src/__tests__/provider-def.test.ts +93 -0
- package/src/__tests__/service-provider.test.ts +129 -0
- package/src/boundary.ts +69 -0
- package/src/conduit.ts +200 -0
- package/src/config/index.ts +35 -0
- package/src/config.ts +2 -1
- package/src/dispatch/__tests__/tasks-gateway-crud-ops.test.ts +99 -0
- package/src/dispatch/identity.ts +20 -0
- package/src/dispatch/operation-def.ts +21 -0
- package/src/dispatch/operations-registry.ts +1062 -36
- package/src/index.ts +137 -1
- package/src/lease-ipc/__tests__/freeze.test.ts +96 -0
- package/src/lease-ipc/index.ts +12 -0
- package/src/lease-ipc/messages.ts +117 -0
- package/src/llm/catalog-schema.json +139 -0
- package/src/llm/catalog-schema.ts +184 -0
- package/src/llm/index.ts +29 -0
- package/src/llm/oauth.ts +16 -2
- package/src/llm/onboarding.ts +131 -0
- package/src/llm/provider-def.ts +291 -0
- package/src/llm/system-resolver.ts +45 -0
- package/src/operations/admin.ts +144 -0
- package/src/operations/entities.ts +758 -0
- package/src/operations/llm.ts +15 -0
- package/src/operations/output-contracts-data.ts +264 -0
- package/src/operations/service.ts +360 -0
- package/src/operations/tasks.ts +119 -0
- package/src/playbook.ts +56 -0
- package/src/vault/service-provider.ts +1137 -0
|
@@ -9,6 +9,8 @@
|
|
|
9
9
|
* @since SG-ARCH-SOLID Saga T9831 · E-CLI-BOUNDARY T9833 · T10061
|
|
10
10
|
*/
|
|
11
11
|
import { DOCS_LIFECYCLE_STATUSES } from '../operations/docs.js';
|
|
12
|
+
import { OUTPUT_CONTRACTS } from '../operations/output-contracts-data.js';
|
|
13
|
+
import { tasksUpdateInputContract } from '../operations/tasks.js';
|
|
12
14
|
// ---------------------------------------------------------------------------
|
|
13
15
|
// Builder helpers
|
|
14
16
|
// ---------------------------------------------------------------------------
|
|
@@ -231,6 +233,38 @@ export const OPERATIONS = [
|
|
|
231
233
|
},
|
|
232
234
|
],
|
|
233
235
|
},
|
|
236
|
+
// T11785 (epic T11556 · E1-GATEWAY-CRUD) — the FIRST streaming task op. Served
|
|
237
|
+
// as `GET /v1/tasks/subscribe` → a `text/event-stream` body of
|
|
238
|
+
// `GatewayStreamEvent` frames (task/board created/updated/deleted lifecycle
|
|
239
|
+
// events), scoped to an optional saga/parent root. Studio's interactive Kanban
|
|
240
|
+
// (T11929) and the Pi-TUI board consume it for live updates. The default
|
|
241
|
+
// source ships a bounded heartbeat producer (stream-sources.ts); the daemon
|
|
242
|
+
// injects its real origin-tailing source via `registerStreamSource`.
|
|
243
|
+
{
|
|
244
|
+
gateway: 'query',
|
|
245
|
+
domain: 'tasks',
|
|
246
|
+
operation: 'subscribe',
|
|
247
|
+
description: 'tasks.subscribe (query, streaming) — SSE stream of task/board lifecycle events (created/updated/deleted), optionally scoped to a saga/parent root',
|
|
248
|
+
tier: 2,
|
|
249
|
+
idempotent: true,
|
|
250
|
+
sessionRequired: false,
|
|
251
|
+
streaming: true,
|
|
252
|
+
requiredParams: [],
|
|
253
|
+
params: [
|
|
254
|
+
{
|
|
255
|
+
name: 'root',
|
|
256
|
+
type: 'string',
|
|
257
|
+
required: false,
|
|
258
|
+
description: 'Optional saga/parent task ID to scope the event stream to (omit for the whole board)',
|
|
259
|
+
},
|
|
260
|
+
{
|
|
261
|
+
name: 'ticks',
|
|
262
|
+
type: 'number',
|
|
263
|
+
required: false,
|
|
264
|
+
description: 'Maximum number of event frames to emit before the terminal `done` frame (default: open-ended until client disconnect)',
|
|
265
|
+
},
|
|
266
|
+
],
|
|
267
|
+
},
|
|
234
268
|
{
|
|
235
269
|
gateway: 'query',
|
|
236
270
|
domain: 'tasks',
|
|
@@ -771,6 +805,30 @@ export const OPERATIONS = [
|
|
|
771
805
|
requiredParams: [],
|
|
772
806
|
params: [],
|
|
773
807
|
},
|
|
808
|
+
// T11921 — gateway SSE streaming on /v1. The agent/worker/board event stream
|
|
809
|
+
// the Studio Kanban (T11929) + Pi-TUI (T11936) consume as a realtime
|
|
810
|
+
// transport. Served as `GET /v1/orchestrate/events` → a `text/event-stream`
|
|
811
|
+
// body of `GatewayStreamEvent` frames terminated by a `done` frame, NOT as a
|
|
812
|
+
// unary POST. Secrets never touch the wire — the source resolves server-side.
|
|
813
|
+
{
|
|
814
|
+
gateway: 'query',
|
|
815
|
+
domain: 'orchestrate',
|
|
816
|
+
operation: 'events',
|
|
817
|
+
description: 'orchestrate.events (query, streaming) — SSE stream of agent/worker/board lifecycle events',
|
|
818
|
+
tier: 2,
|
|
819
|
+
idempotent: true,
|
|
820
|
+
sessionRequired: false,
|
|
821
|
+
streaming: true,
|
|
822
|
+
requiredParams: [],
|
|
823
|
+
params: [
|
|
824
|
+
{
|
|
825
|
+
name: 'ticks',
|
|
826
|
+
type: 'number',
|
|
827
|
+
required: false,
|
|
828
|
+
description: 'Maximum number of event frames to emit before the terminal `done` frame (default: open-ended until client disconnect)',
|
|
829
|
+
},
|
|
830
|
+
],
|
|
831
|
+
},
|
|
774
832
|
// T811 — IVTR multi-agent enforcement
|
|
775
833
|
{
|
|
776
834
|
gateway: 'query',
|
|
@@ -1718,6 +1776,70 @@ export const OPERATIONS = [
|
|
|
1718
1776
|
requiredParams: [],
|
|
1719
1777
|
params: [],
|
|
1720
1778
|
},
|
|
1779
|
+
{
|
|
1780
|
+
gateway: 'query',
|
|
1781
|
+
domain: 'admin',
|
|
1782
|
+
operation: 'config.get',
|
|
1783
|
+
description: 'admin.config.get (query) — resolve a single config value via the ConfigManifest cascade (T11917)',
|
|
1784
|
+
tier: 1,
|
|
1785
|
+
idempotent: true,
|
|
1786
|
+
sessionRequired: false,
|
|
1787
|
+
requiredParams: ['key'],
|
|
1788
|
+
params: [
|
|
1789
|
+
{
|
|
1790
|
+
name: 'key',
|
|
1791
|
+
type: 'string',
|
|
1792
|
+
required: true,
|
|
1793
|
+
description: 'Dot-notation config key to read (e.g. "release.branchModel")',
|
|
1794
|
+
cli: { positional: true },
|
|
1795
|
+
},
|
|
1796
|
+
{
|
|
1797
|
+
name: 'scope',
|
|
1798
|
+
type: 'string',
|
|
1799
|
+
required: false,
|
|
1800
|
+
description: 'Cascade slice to read from. Defaults to merged.',
|
|
1801
|
+
enum: ['global', 'project', 'merged'],
|
|
1802
|
+
},
|
|
1803
|
+
],
|
|
1804
|
+
},
|
|
1805
|
+
{
|
|
1806
|
+
gateway: 'query',
|
|
1807
|
+
domain: 'admin',
|
|
1808
|
+
operation: 'config.list',
|
|
1809
|
+
description: 'admin.config.list (query) — resolve the full config cascade and its flattened keys (T11917)',
|
|
1810
|
+
tier: 1,
|
|
1811
|
+
idempotent: true,
|
|
1812
|
+
sessionRequired: false,
|
|
1813
|
+
requiredParams: [],
|
|
1814
|
+
params: [
|
|
1815
|
+
{
|
|
1816
|
+
name: 'scope',
|
|
1817
|
+
type: 'string',
|
|
1818
|
+
required: false,
|
|
1819
|
+
description: 'Cascade slice to project. Defaults to merged.',
|
|
1820
|
+
enum: ['global', 'project', 'merged'],
|
|
1821
|
+
},
|
|
1822
|
+
],
|
|
1823
|
+
},
|
|
1824
|
+
{
|
|
1825
|
+
gateway: 'query',
|
|
1826
|
+
domain: 'admin',
|
|
1827
|
+
operation: 'config.validate',
|
|
1828
|
+
description: 'admin.config.validate (query) — schema-validate a scoped config file via its manifest entry (T11917)',
|
|
1829
|
+
tier: 1,
|
|
1830
|
+
idempotent: true,
|
|
1831
|
+
sessionRequired: false,
|
|
1832
|
+
requiredParams: [],
|
|
1833
|
+
params: [
|
|
1834
|
+
{
|
|
1835
|
+
name: 'scope',
|
|
1836
|
+
type: 'string',
|
|
1837
|
+
required: false,
|
|
1838
|
+
description: 'Scope to validate (global or project). Defaults to project.',
|
|
1839
|
+
enum: ['global', 'project'],
|
|
1840
|
+
},
|
|
1841
|
+
],
|
|
1842
|
+
},
|
|
1721
1843
|
{
|
|
1722
1844
|
gateway: 'query',
|
|
1723
1845
|
domain: 'admin',
|
|
@@ -2387,10 +2509,18 @@ export const OPERATIONS = [
|
|
|
2387
2509
|
],
|
|
2388
2510
|
},
|
|
2389
2511
|
{
|
|
2512
|
+
// T11784 (epic T11556 · E1-GATEWAY-CRUD) — the OperationDef.params used to
|
|
2513
|
+
// declare ONLY `taskId`, so every other mutable field a Studio form binds
|
|
2514
|
+
// to was invisible to dispatch introspection (`cleo update --describe`, the
|
|
2515
|
+
// SDK `describeOperation`) and silently dropped at the dispatch boundary.
|
|
2516
|
+
// The full mutable-field set is now enumerated here, grounded in
|
|
2517
|
+
// {@link TasksUpdateQueryParams} / {@link TASKS_UPDATE_INPUT_SCHEMA}; a
|
|
2518
|
+
// regression test (operations-registry tasks-update parity) asserts the
|
|
2519
|
+
// param names stay in sync with the schema's `properties`.
|
|
2390
2520
|
gateway: 'mutate',
|
|
2391
2521
|
domain: 'tasks',
|
|
2392
2522
|
operation: 'update',
|
|
2393
|
-
description: 'tasks.update (mutate)',
|
|
2523
|
+
description: 'tasks.update (mutate) — partial update; only supplied fields are mutated',
|
|
2394
2524
|
tier: 0,
|
|
2395
2525
|
idempotent: false,
|
|
2396
2526
|
sessionRequired: false,
|
|
@@ -2400,10 +2530,183 @@ export const OPERATIONS = [
|
|
|
2400
2530
|
name: 'taskId',
|
|
2401
2531
|
type: 'string',
|
|
2402
2532
|
required: true,
|
|
2403
|
-
description: '
|
|
2533
|
+
description: 'Task ID to update',
|
|
2404
2534
|
cli: { positional: true },
|
|
2405
2535
|
},
|
|
2536
|
+
{ name: 'title', type: 'string', required: false, description: 'New title (3–500 chars)' },
|
|
2537
|
+
{
|
|
2538
|
+
name: 'description',
|
|
2539
|
+
type: 'string',
|
|
2540
|
+
required: false,
|
|
2541
|
+
description: 'New description',
|
|
2542
|
+
cli: { flag: 'description', short: '-d' },
|
|
2543
|
+
},
|
|
2544
|
+
{
|
|
2545
|
+
name: 'status',
|
|
2546
|
+
type: 'string',
|
|
2547
|
+
required: false,
|
|
2548
|
+
description: 'New status',
|
|
2549
|
+
enum: ['pending', 'active', 'blocked', 'done', 'cancelled'],
|
|
2550
|
+
cli: { flag: 'status', short: '-s' },
|
|
2551
|
+
},
|
|
2552
|
+
{
|
|
2553
|
+
name: 'priority',
|
|
2554
|
+
type: 'string',
|
|
2555
|
+
required: false,
|
|
2556
|
+
description: 'New priority (orthogonal to severity)',
|
|
2557
|
+
enum: ['low', 'medium', 'high', 'critical'],
|
|
2558
|
+
cli: { flag: 'priority', short: '-p' },
|
|
2559
|
+
},
|
|
2560
|
+
{ name: 'notes', type: 'string', required: false, description: 'Append a note entry' },
|
|
2561
|
+
{
|
|
2562
|
+
name: 'labels',
|
|
2563
|
+
type: 'array',
|
|
2564
|
+
required: false,
|
|
2565
|
+
description: 'Replace labels (comma-separated)',
|
|
2566
|
+
cli: { flag: 'labels', short: '-l' },
|
|
2567
|
+
},
|
|
2568
|
+
{
|
|
2569
|
+
name: 'addLabels',
|
|
2570
|
+
type: 'array',
|
|
2571
|
+
required: false,
|
|
2572
|
+
description: 'Add labels incrementally',
|
|
2573
|
+
},
|
|
2574
|
+
{
|
|
2575
|
+
name: 'removeLabels',
|
|
2576
|
+
type: 'array',
|
|
2577
|
+
required: false,
|
|
2578
|
+
description: 'Remove labels incrementally',
|
|
2579
|
+
},
|
|
2580
|
+
{
|
|
2581
|
+
name: 'depends',
|
|
2582
|
+
type: 'array',
|
|
2583
|
+
required: false,
|
|
2584
|
+
description: 'Replace dependency task IDs',
|
|
2585
|
+
cli: { flag: 'depends', short: '-D' },
|
|
2586
|
+
},
|
|
2587
|
+
{
|
|
2588
|
+
name: 'addDepends',
|
|
2589
|
+
type: 'array',
|
|
2590
|
+
required: false,
|
|
2591
|
+
description: 'Add dependency task IDs incrementally',
|
|
2592
|
+
},
|
|
2593
|
+
{
|
|
2594
|
+
name: 'removeDepends',
|
|
2595
|
+
type: 'array',
|
|
2596
|
+
required: false,
|
|
2597
|
+
description: 'Remove dependency task IDs incrementally',
|
|
2598
|
+
},
|
|
2599
|
+
{
|
|
2600
|
+
name: 'acceptance',
|
|
2601
|
+
type: 'array',
|
|
2602
|
+
required: false,
|
|
2603
|
+
description: 'Replace acceptance criteria (pipe-separated)',
|
|
2604
|
+
},
|
|
2605
|
+
{
|
|
2606
|
+
name: 'parent',
|
|
2607
|
+
type: 'string',
|
|
2608
|
+
required: false,
|
|
2609
|
+
description: 'Set parent task ID (null/empty promotes to root)',
|
|
2610
|
+
},
|
|
2611
|
+
{
|
|
2612
|
+
name: 'type',
|
|
2613
|
+
type: 'string',
|
|
2614
|
+
required: false,
|
|
2615
|
+
description: 'New hierarchy type',
|
|
2616
|
+
enum: ['saga', 'epic', 'task', 'subtask'],
|
|
2617
|
+
cli: { flag: 'type', short: '-t' },
|
|
2618
|
+
},
|
|
2619
|
+
{
|
|
2620
|
+
name: 'size',
|
|
2621
|
+
type: 'string',
|
|
2622
|
+
required: false,
|
|
2623
|
+
description: 'New scope-size estimate',
|
|
2624
|
+
enum: ['small', 'medium', 'large'],
|
|
2625
|
+
},
|
|
2626
|
+
{
|
|
2627
|
+
name: 'files',
|
|
2628
|
+
type: 'array',
|
|
2629
|
+
required: false,
|
|
2630
|
+
description: 'Replace associated file paths',
|
|
2631
|
+
},
|
|
2632
|
+
{
|
|
2633
|
+
name: 'addFiles',
|
|
2634
|
+
type: 'array',
|
|
2635
|
+
required: false,
|
|
2636
|
+
description: 'Add file paths incrementally',
|
|
2637
|
+
},
|
|
2638
|
+
{
|
|
2639
|
+
name: 'removeFiles',
|
|
2640
|
+
type: 'array',
|
|
2641
|
+
required: false,
|
|
2642
|
+
description: 'Remove file paths incrementally',
|
|
2643
|
+
},
|
|
2644
|
+
{
|
|
2645
|
+
name: 'pipelineStage',
|
|
2646
|
+
type: 'string',
|
|
2647
|
+
required: false,
|
|
2648
|
+
description: 'Set pipeline stage (forward-only)',
|
|
2649
|
+
},
|
|
2650
|
+
{
|
|
2651
|
+
name: 'kind',
|
|
2652
|
+
type: 'string',
|
|
2653
|
+
required: false,
|
|
2654
|
+
description: 'Task kind / intent axis (orthogonal to type)',
|
|
2655
|
+
enum: ['work', 'research', 'experiment', 'bug', 'spike', 'release'],
|
|
2656
|
+
},
|
|
2657
|
+
{
|
|
2658
|
+
name: 'scope',
|
|
2659
|
+
type: 'string',
|
|
2660
|
+
required: false,
|
|
2661
|
+
description: 'Task scope / granularity axis',
|
|
2662
|
+
enum: ['project', 'feature', 'unit'],
|
|
2663
|
+
},
|
|
2664
|
+
{
|
|
2665
|
+
name: 'severity',
|
|
2666
|
+
type: 'string',
|
|
2667
|
+
required: false,
|
|
2668
|
+
description: 'Severity level (orthogonal to priority)',
|
|
2669
|
+
enum: ['P0', 'P1', 'P2', 'P3'],
|
|
2670
|
+
},
|
|
2671
|
+
{
|
|
2672
|
+
name: 'reason',
|
|
2673
|
+
type: 'string',
|
|
2674
|
+
required: false,
|
|
2675
|
+
description: 'Operator override reason for the AC-immutability guard',
|
|
2676
|
+
},
|
|
2677
|
+
{
|
|
2678
|
+
name: 'dependsWaiver',
|
|
2679
|
+
type: 'string',
|
|
2680
|
+
required: false,
|
|
2681
|
+
description: 'Justification to waive the critical-priority --depends requirement',
|
|
2682
|
+
},
|
|
2683
|
+
{
|
|
2684
|
+
name: 'clearBlockedBy',
|
|
2685
|
+
type: 'boolean',
|
|
2686
|
+
required: false,
|
|
2687
|
+
description: 'Clear the free-text blockedBy reason',
|
|
2688
|
+
},
|
|
2689
|
+
{
|
|
2690
|
+
name: 'relates',
|
|
2691
|
+
type: 'array',
|
|
2692
|
+
required: false,
|
|
2693
|
+
description: 'Replace related-task edges ({taskId, type, reason?})',
|
|
2694
|
+
},
|
|
2695
|
+
{
|
|
2696
|
+
name: 'addRelates',
|
|
2697
|
+
type: 'array',
|
|
2698
|
+
required: false,
|
|
2699
|
+
description: 'Add related-task edges without overwriting existing',
|
|
2700
|
+
},
|
|
2701
|
+
{
|
|
2702
|
+
name: 'removeRelates',
|
|
2703
|
+
type: 'array',
|
|
2704
|
+
required: false,
|
|
2705
|
+
description: 'Remove related-task edges by taskId',
|
|
2706
|
+
},
|
|
2406
2707
|
],
|
|
2708
|
+
inputSchema: tasksUpdateInputContract,
|
|
2709
|
+
outputSchema: OUTPUT_CONTRACTS['tasks.update'],
|
|
2407
2710
|
},
|
|
2408
2711
|
{
|
|
2409
2712
|
gateway: 'mutate',
|
|
@@ -2547,96 +2850,184 @@ export const OPERATIONS = [
|
|
|
2547
2850
|
},
|
|
2548
2851
|
],
|
|
2549
2852
|
},
|
|
2853
|
+
// T11786 (epic T11556 · E1-GATEWAY-CRUD) — bulk task mutate ops the Studio
|
|
2854
|
+
// interactive Kanban (M6) binds to: within-column re-rank, atomic multi-move,
|
|
2855
|
+
// and first-class assignee (distinct from the agent claim lock).
|
|
2550
2856
|
{
|
|
2551
2857
|
gateway: 'mutate',
|
|
2552
2858
|
domain: 'tasks',
|
|
2553
|
-
operation: '
|
|
2554
|
-
description: 'tasks.
|
|
2859
|
+
operation: 'reorder-rank',
|
|
2860
|
+
description: 'tasks.reorder-rank (mutate) — within-column positional re-rank from an explicit top-to-bottom task-ID order (Kanban drag-reorder)',
|
|
2555
2861
|
tier: 1,
|
|
2556
2862
|
idempotent: false,
|
|
2557
2863
|
sessionRequired: false,
|
|
2558
|
-
requiredParams: ['
|
|
2864
|
+
requiredParams: ['orderedIds'],
|
|
2559
2865
|
params: [
|
|
2560
2866
|
{
|
|
2561
|
-
name: '
|
|
2562
|
-
type: '
|
|
2563
|
-
required: true,
|
|
2564
|
-
description: 'taskId parameter',
|
|
2565
|
-
cli: { positional: true },
|
|
2566
|
-
},
|
|
2567
|
-
{
|
|
2568
|
-
name: 'type',
|
|
2569
|
-
type: 'string',
|
|
2867
|
+
name: 'orderedIds',
|
|
2868
|
+
type: 'array',
|
|
2570
2869
|
required: true,
|
|
2571
|
-
description: '
|
|
2870
|
+
description: 'Ordered task IDs describing the desired top-to-bottom column order; each task position is set to its 1-based index',
|
|
2572
2871
|
},
|
|
2573
2872
|
],
|
|
2873
|
+
outputSchema: OUTPUT_CONTRACTS['tasks.reorder-rank'],
|
|
2574
2874
|
},
|
|
2575
2875
|
{
|
|
2576
|
-
// T11575 — the handler (dispatch/domains/tasks.ts 'relates.add-batch') and
|
|
2577
|
-
// CLI command (cli/commands/relates.ts add-batch) shipped, but no
|
|
2578
|
-
// OperationDef existed here, so `resolve()` returned undefined and the
|
|
2579
|
-
// dispatcher rejected the call with E_INVALID_OPERATION before it ever
|
|
2580
|
-
// reached the handler. Registering the op (gateway:'mutate') closes the gap.
|
|
2581
2876
|
gateway: 'mutate',
|
|
2582
2877
|
domain: 'tasks',
|
|
2583
|
-
operation: '
|
|
2584
|
-
description: 'tasks.
|
|
2878
|
+
operation: 'bulk-move',
|
|
2879
|
+
description: 'tasks.bulk-move (mutate) — atomically move N tasks to a new status and/or pipeline stage in a single transaction (Kanban multi-card column move)',
|
|
2585
2880
|
tier: 1,
|
|
2586
2881
|
idempotent: false,
|
|
2587
2882
|
sessionRequired: false,
|
|
2588
|
-
|
|
2589
|
-
// accepts either shape and validates emptiness in core — so no param is
|
|
2590
|
-
// declared required at the dispatch boundary.
|
|
2591
|
-
requiredParams: [],
|
|
2883
|
+
requiredParams: ['taskIds'],
|
|
2592
2884
|
params: [
|
|
2593
2885
|
{
|
|
2594
|
-
name: '
|
|
2595
|
-
type: 'array',
|
|
2596
|
-
required: false,
|
|
2597
|
-
description: 'Array of relation edges ({from|taskId, to|relatedId, type, reason})',
|
|
2598
|
-
},
|
|
2599
|
-
{
|
|
2600
|
-
name: 'edges',
|
|
2886
|
+
name: 'taskIds',
|
|
2601
2887
|
type: 'array',
|
|
2602
|
-
required:
|
|
2603
|
-
description: '
|
|
2888
|
+
required: true,
|
|
2889
|
+
description: 'Task IDs to move (all-or-nothing; any failure rolls back every move)',
|
|
2604
2890
|
},
|
|
2605
2891
|
{
|
|
2606
|
-
name: '
|
|
2607
|
-
type: '
|
|
2892
|
+
name: 'status',
|
|
2893
|
+
type: 'string',
|
|
2608
2894
|
required: false,
|
|
2609
|
-
description: '
|
|
2895
|
+
description: 'Target lifecycle status applied to every task',
|
|
2896
|
+
enum: [
|
|
2897
|
+
'pending',
|
|
2898
|
+
'active',
|
|
2899
|
+
'blocked',
|
|
2900
|
+
'done',
|
|
2901
|
+
'cancelled',
|
|
2902
|
+
'archived',
|
|
2903
|
+
'proposed',
|
|
2904
|
+
],
|
|
2610
2905
|
},
|
|
2611
2906
|
{
|
|
2612
|
-
name: '
|
|
2907
|
+
name: 'pipelineStage',
|
|
2613
2908
|
type: 'string',
|
|
2614
2909
|
required: false,
|
|
2615
|
-
description: '
|
|
2910
|
+
description: 'Target pipeline stage applied to every task (forward-only)',
|
|
2616
2911
|
},
|
|
2617
2912
|
],
|
|
2913
|
+
outputSchema: OUTPUT_CONTRACTS['tasks.bulk-move'],
|
|
2618
2914
|
},
|
|
2619
2915
|
{
|
|
2620
2916
|
gateway: 'mutate',
|
|
2621
2917
|
domain: 'tasks',
|
|
2622
|
-
operation: '
|
|
2623
|
-
description: 'tasks.
|
|
2918
|
+
operation: 'assignee',
|
|
2919
|
+
description: 'tasks.assignee (mutate) — set/clear a first-class human assignee (DISTINCT from the agent claim/unclaim lock; pass assignee:null to clear)',
|
|
2624
2920
|
tier: 1,
|
|
2625
2921
|
idempotent: true,
|
|
2626
2922
|
sessionRequired: false,
|
|
2627
|
-
requiredParams: ['taskId'
|
|
2923
|
+
requiredParams: ['taskId'],
|
|
2628
2924
|
params: [
|
|
2629
2925
|
{
|
|
2630
2926
|
name: 'taskId',
|
|
2631
2927
|
type: 'string',
|
|
2632
2928
|
required: true,
|
|
2633
|
-
description: '
|
|
2929
|
+
description: 'Task ID whose assignee is being set or cleared',
|
|
2634
2930
|
cli: { positional: true },
|
|
2635
2931
|
},
|
|
2636
2932
|
{
|
|
2637
|
-
name: '
|
|
2933
|
+
name: 'assignee',
|
|
2638
2934
|
type: 'string',
|
|
2639
|
-
required:
|
|
2935
|
+
required: false,
|
|
2936
|
+
description: 'Assignee to set; omit / empty / null clears the assignee',
|
|
2937
|
+
},
|
|
2938
|
+
],
|
|
2939
|
+
outputSchema: OUTPUT_CONTRACTS['tasks.assignee'],
|
|
2940
|
+
},
|
|
2941
|
+
{
|
|
2942
|
+
gateway: 'mutate',
|
|
2943
|
+
domain: 'tasks',
|
|
2944
|
+
operation: 'relates.add',
|
|
2945
|
+
description: 'tasks.relates.add (mutate)',
|
|
2946
|
+
tier: 1,
|
|
2947
|
+
idempotent: false,
|
|
2948
|
+
sessionRequired: false,
|
|
2949
|
+
requiredParams: ['taskId', 'type'],
|
|
2950
|
+
params: [
|
|
2951
|
+
{
|
|
2952
|
+
name: 'taskId',
|
|
2953
|
+
type: 'string',
|
|
2954
|
+
required: true,
|
|
2955
|
+
description: 'taskId parameter',
|
|
2956
|
+
cli: { positional: true },
|
|
2957
|
+
},
|
|
2958
|
+
{
|
|
2959
|
+
name: 'type',
|
|
2960
|
+
type: 'string',
|
|
2961
|
+
required: true,
|
|
2962
|
+
description: 'type parameter',
|
|
2963
|
+
},
|
|
2964
|
+
],
|
|
2965
|
+
},
|
|
2966
|
+
{
|
|
2967
|
+
// T11575 — the handler (dispatch/domains/tasks.ts 'relates.add-batch') and
|
|
2968
|
+
// CLI command (cli/commands/relates.ts add-batch) shipped, but no
|
|
2969
|
+
// OperationDef existed here, so `resolve()` returned undefined and the
|
|
2970
|
+
// dispatcher rejected the call with E_INVALID_OPERATION before it ever
|
|
2971
|
+
// reached the handler. Registering the op (gateway:'mutate') closes the gap.
|
|
2972
|
+
gateway: 'mutate',
|
|
2973
|
+
domain: 'tasks',
|
|
2974
|
+
operation: 'relates.add-batch',
|
|
2975
|
+
description: 'tasks.relates.add-batch (mutate) — bulk-add advisory relation edges from a JSON payload ({relations:[...]} or {edges:[...]}); use dryRun to preview without writing.',
|
|
2976
|
+
tier: 1,
|
|
2977
|
+
idempotent: false,
|
|
2978
|
+
sessionRequired: false,
|
|
2979
|
+
// Neither `relations` nor `edges` is individually required — the handler
|
|
2980
|
+
// accepts either shape and validates emptiness in core — so no param is
|
|
2981
|
+
// declared required at the dispatch boundary.
|
|
2982
|
+
requiredParams: [],
|
|
2983
|
+
params: [
|
|
2984
|
+
{
|
|
2985
|
+
name: 'relations',
|
|
2986
|
+
type: 'array',
|
|
2987
|
+
required: false,
|
|
2988
|
+
description: 'Array of relation edges ({from|taskId, to|relatedId, type, reason})',
|
|
2989
|
+
},
|
|
2990
|
+
{
|
|
2991
|
+
name: 'edges',
|
|
2992
|
+
type: 'array',
|
|
2993
|
+
required: false,
|
|
2994
|
+
description: 'Alias for `relations` — array of relation edges',
|
|
2995
|
+
},
|
|
2996
|
+
{
|
|
2997
|
+
name: 'dryRun',
|
|
2998
|
+
type: 'boolean',
|
|
2999
|
+
required: false,
|
|
3000
|
+
description: 'Validate and report what would be created without writing',
|
|
3001
|
+
},
|
|
3002
|
+
{
|
|
3003
|
+
name: 'reasonWaiver',
|
|
3004
|
+
type: 'string',
|
|
3005
|
+
required: false,
|
|
3006
|
+
description: 'Explicit audit waiver text for edges without per-edge reasons',
|
|
3007
|
+
},
|
|
3008
|
+
],
|
|
3009
|
+
},
|
|
3010
|
+
{
|
|
3011
|
+
gateway: 'mutate',
|
|
3012
|
+
domain: 'tasks',
|
|
3013
|
+
operation: 'relates.remove',
|
|
3014
|
+
description: 'tasks.relates.remove (mutate) — delete a relation between two tasks. Pass `type` to scope deletion to a single relation kind; omit to remove any type.',
|
|
3015
|
+
tier: 1,
|
|
3016
|
+
idempotent: true,
|
|
3017
|
+
sessionRequired: false,
|
|
3018
|
+
requiredParams: ['taskId', 'relatedId'],
|
|
3019
|
+
params: [
|
|
3020
|
+
{
|
|
3021
|
+
name: 'taskId',
|
|
3022
|
+
type: 'string',
|
|
3023
|
+
required: true,
|
|
3024
|
+
description: 'Source task ID',
|
|
3025
|
+
cli: { positional: true },
|
|
3026
|
+
},
|
|
3027
|
+
{
|
|
3028
|
+
name: 'relatedId',
|
|
3029
|
+
type: 'string',
|
|
3030
|
+
required: true,
|
|
2640
3031
|
description: 'Target task ID to remove the relation to',
|
|
2641
3032
|
cli: { positional: true },
|
|
2642
3033
|
},
|
|
@@ -4334,6 +4725,31 @@ export const OPERATIONS = [
|
|
|
4334
4725
|
},
|
|
4335
4726
|
],
|
|
4336
4727
|
},
|
|
4728
|
+
{
|
|
4729
|
+
gateway: 'mutate',
|
|
4730
|
+
domain: 'admin',
|
|
4731
|
+
operation: 'config.unset',
|
|
4732
|
+
description: 'admin.config.unset (mutate) — remove a key from a scoped config file (idempotent) (T11917)',
|
|
4733
|
+
tier: 1,
|
|
4734
|
+
idempotent: true,
|
|
4735
|
+
sessionRequired: false,
|
|
4736
|
+
requiredParams: ['key'],
|
|
4737
|
+
params: [
|
|
4738
|
+
{
|
|
4739
|
+
name: 'key',
|
|
4740
|
+
type: 'string',
|
|
4741
|
+
required: true,
|
|
4742
|
+
description: 'Dot-notation config key to remove',
|
|
4743
|
+
cli: { positional: true },
|
|
4744
|
+
},
|
|
4745
|
+
{
|
|
4746
|
+
name: 'global',
|
|
4747
|
+
type: 'boolean',
|
|
4748
|
+
required: false,
|
|
4749
|
+
description: 'Remove from the global file instead of the project file',
|
|
4750
|
+
},
|
|
4751
|
+
],
|
|
4752
|
+
},
|
|
4337
4753
|
{
|
|
4338
4754
|
gateway: 'query',
|
|
4339
4755
|
domain: 'admin',
|
|
@@ -8521,5 +8937,573 @@ export const OPERATIONS = [
|
|
|
8521
8937
|
},
|
|
8522
8938
|
],
|
|
8523
8939
|
},
|
|
8940
|
+
// ── service domain: universal service-vault OAuth flow (T11939 · epic T11765) ──
|
|
8941
|
+
// Four verbs driving the declarative SERVICE_PROVIDERS registry: auth-url (query
|
|
8942
|
+
// — build a PKCE authorization URL), exchange (mutate — persist encrypted tokens
|
|
8943
|
+
// from an auth code), refresh (mutate — renew an access token honoring the
|
|
8944
|
+
// per-provider RefreshConfig), self-heal (mutate — resolve + transparently
|
|
8945
|
+
// refresh a past-expiry connection). The flow lives in CORE (store/service-oauth.ts).
|
|
8946
|
+
{
|
|
8947
|
+
gateway: 'query',
|
|
8948
|
+
domain: 'service',
|
|
8949
|
+
operation: 'auth-url',
|
|
8950
|
+
description: 'service.auth-url (query) — build a PKCE OAuth authorization URL for a service provider; returns the URL + the code verifier + state to round-trip into service.exchange.',
|
|
8951
|
+
tier: 2,
|
|
8952
|
+
idempotent: false,
|
|
8953
|
+
sessionRequired: false,
|
|
8954
|
+
requiredParams: ['provider'],
|
|
8955
|
+
params: [
|
|
8956
|
+
{
|
|
8957
|
+
name: 'provider',
|
|
8958
|
+
type: 'string',
|
|
8959
|
+
required: true,
|
|
8960
|
+
description: 'Service provider key (e.g. github, google, notion) — must be in SERVICE_PROVIDERS.',
|
|
8961
|
+
},
|
|
8962
|
+
{
|
|
8963
|
+
name: 'state',
|
|
8964
|
+
type: 'string',
|
|
8965
|
+
required: false,
|
|
8966
|
+
description: 'Opaque CSRF state to embed; a random value is generated when omitted.',
|
|
8967
|
+
},
|
|
8968
|
+
{
|
|
8969
|
+
name: 'scope',
|
|
8970
|
+
type: 'string',
|
|
8971
|
+
required: false,
|
|
8972
|
+
description: 'Scope override (e.g. a BYOC custom scope). Defaults to the provider scope.',
|
|
8973
|
+
},
|
|
8974
|
+
{
|
|
8975
|
+
name: 'redirectUri',
|
|
8976
|
+
type: 'string',
|
|
8977
|
+
required: false,
|
|
8978
|
+
description: 'Redirect URI override. Defaults to the provider loopback redirect.',
|
|
8979
|
+
},
|
|
8980
|
+
],
|
|
8981
|
+
},
|
|
8982
|
+
{
|
|
8983
|
+
gateway: 'mutate',
|
|
8984
|
+
domain: 'service',
|
|
8985
|
+
operation: 'exchange',
|
|
8986
|
+
description: 'service.exchange (mutate) — exchange an OAuth authorization code (+ PKCE verifier) for tokens and PERSIST them encryptGlobal-encrypted into service_connections. Returns the non-secret connection identity.',
|
|
8987
|
+
tier: 2,
|
|
8988
|
+
idempotent: false,
|
|
8989
|
+
sessionRequired: false,
|
|
8990
|
+
requiredParams: ['provider', 'code', 'codeVerifier', 'redirectUri'],
|
|
8991
|
+
params: [
|
|
8992
|
+
{ name: 'provider', type: 'string', required: true, description: 'Service provider key.' },
|
|
8993
|
+
{
|
|
8994
|
+
name: 'code',
|
|
8995
|
+
type: 'string',
|
|
8996
|
+
required: true,
|
|
8997
|
+
description: 'Authorization code from the redirect callback.',
|
|
8998
|
+
},
|
|
8999
|
+
{
|
|
9000
|
+
name: 'codeVerifier',
|
|
9001
|
+
type: 'string',
|
|
9002
|
+
required: true,
|
|
9003
|
+
description: 'PKCE code verifier from service.auth-url (round-tripped).',
|
|
9004
|
+
},
|
|
9005
|
+
{
|
|
9006
|
+
name: 'redirectUri',
|
|
9007
|
+
type: 'string',
|
|
9008
|
+
required: true,
|
|
9009
|
+
description: 'Redirect URI used in service.auth-url (must match).',
|
|
9010
|
+
},
|
|
9011
|
+
{
|
|
9012
|
+
name: 'label',
|
|
9013
|
+
type: 'string',
|
|
9014
|
+
required: false,
|
|
9015
|
+
description: 'Connection label, unique within the provider. Defaults to "default".',
|
|
9016
|
+
},
|
|
9017
|
+
],
|
|
9018
|
+
},
|
|
9019
|
+
{
|
|
9020
|
+
gateway: 'mutate',
|
|
9021
|
+
domain: 'service',
|
|
9022
|
+
operation: 'refresh',
|
|
9023
|
+
description: 'service.refresh (mutate) — refresh a service connection access token honoring the per-provider RefreshConfig (Form/Json × Body/BasicAuth, plus github-app / service-account-jwt / client-credentials variants); re-encrypts + persists the new blob.',
|
|
9024
|
+
tier: 2,
|
|
9025
|
+
idempotent: false,
|
|
9026
|
+
sessionRequired: false,
|
|
9027
|
+
requiredParams: ['agentId', 'provider', 'label'],
|
|
9028
|
+
params: [
|
|
9029
|
+
{
|
|
9030
|
+
name: 'agentId',
|
|
9031
|
+
type: 'string',
|
|
9032
|
+
required: true,
|
|
9033
|
+
description: 'Agent requesting the refresh (trust-gated).',
|
|
9034
|
+
},
|
|
9035
|
+
{ name: 'provider', type: 'string', required: true, description: 'Service provider key.' },
|
|
9036
|
+
{ name: 'label', type: 'string', required: true, description: 'Connection label.' },
|
|
9037
|
+
{
|
|
9038
|
+
name: 'approved',
|
|
9039
|
+
type: 'boolean',
|
|
9040
|
+
required: false,
|
|
9041
|
+
description: 'Out-of-band manual-approval flag forwarded to the trust gate.',
|
|
9042
|
+
},
|
|
9043
|
+
],
|
|
9044
|
+
},
|
|
9045
|
+
{
|
|
9046
|
+
gateway: 'mutate',
|
|
9047
|
+
domain: 'service',
|
|
9048
|
+
operation: 'self-heal',
|
|
9049
|
+
description: 'service.self-heal (mutate) — resolve a service connection and, when its expires_at is past, transparently refresh + re-encrypt + persist; returns a fresh sealed-credential reference (agents never see a stale token).',
|
|
9050
|
+
tier: 2,
|
|
9051
|
+
idempotent: true,
|
|
9052
|
+
sessionRequired: false,
|
|
9053
|
+
requiredParams: ['agentId', 'provider', 'label'],
|
|
9054
|
+
params: [
|
|
9055
|
+
{
|
|
9056
|
+
name: 'agentId',
|
|
9057
|
+
type: 'string',
|
|
9058
|
+
required: true,
|
|
9059
|
+
description: 'Agent requesting the connection (trust-gated).',
|
|
9060
|
+
},
|
|
9061
|
+
{ name: 'provider', type: 'string', required: true, description: 'Service provider key.' },
|
|
9062
|
+
{ name: 'label', type: 'string', required: true, description: 'Connection label.' },
|
|
9063
|
+
{
|
|
9064
|
+
name: 'approved',
|
|
9065
|
+
type: 'boolean',
|
|
9066
|
+
required: false,
|
|
9067
|
+
description: 'Out-of-band manual-approval flag forwarded to the trust gate.',
|
|
9068
|
+
},
|
|
9069
|
+
],
|
|
9070
|
+
},
|
|
9071
|
+
// ── service domain: user-facing service-vault CLI verbs (T11941 · M2-W4) ──
|
|
9072
|
+
// Four verbs making the universal vault USABLE from the CLI: connect (mutate —
|
|
9073
|
+
// store a credential via token-direct or paste-code OAuth exchange), list
|
|
9074
|
+
// (query — redacted connection views, NEVER the token), revoke (mutate — hard
|
|
9075
|
+
// delete + cascade agent grants), status (query — connection health: expired?
|
|
9076
|
+
// needsRefresh?). Thin handlers delegate to CORE accessor + service-oauth.
|
|
9077
|
+
{
|
|
9078
|
+
gateway: 'mutate',
|
|
9079
|
+
domain: 'service',
|
|
9080
|
+
operation: 'connect',
|
|
9081
|
+
description: 'service.connect (mutate) — connect a service credential: store an already-obtained token (--token) OR exchange an OAuth authorization code (--paste-code + --code-verifier + --redirect-uri). Persists the token blob encryptGlobal-encrypted; returns the NON-SECRET connection identity (never the token).',
|
|
9082
|
+
tier: 2,
|
|
9083
|
+
idempotent: false,
|
|
9084
|
+
sessionRequired: false,
|
|
9085
|
+
requiredParams: ['provider'],
|
|
9086
|
+
params: [
|
|
9087
|
+
{
|
|
9088
|
+
name: 'provider',
|
|
9089
|
+
type: 'string',
|
|
9090
|
+
required: true,
|
|
9091
|
+
description: 'Service provider key (e.g. github, google, notion).',
|
|
9092
|
+
},
|
|
9093
|
+
{
|
|
9094
|
+
name: 'label',
|
|
9095
|
+
type: 'string',
|
|
9096
|
+
required: false,
|
|
9097
|
+
description: "Connection label, unique within the provider. Defaults to 'default'.",
|
|
9098
|
+
},
|
|
9099
|
+
{
|
|
9100
|
+
name: 'token',
|
|
9101
|
+
type: 'string',
|
|
9102
|
+
required: false,
|
|
9103
|
+
description: 'Direct access token to store (token-direct mode). SECRET — never echoed.',
|
|
9104
|
+
},
|
|
9105
|
+
{
|
|
9106
|
+
name: 'refreshToken',
|
|
9107
|
+
type: 'string',
|
|
9108
|
+
required: false,
|
|
9109
|
+
description: 'Optional refresh token paired with --token. SECRET.',
|
|
9110
|
+
},
|
|
9111
|
+
{
|
|
9112
|
+
name: 'expiresAt',
|
|
9113
|
+
type: 'string',
|
|
9114
|
+
required: false,
|
|
9115
|
+
description: 'ISO-8601 access-token expiry (token-direct mode).',
|
|
9116
|
+
},
|
|
9117
|
+
{
|
|
9118
|
+
name: 'code',
|
|
9119
|
+
type: 'string',
|
|
9120
|
+
required: false,
|
|
9121
|
+
description: 'OAuth authorization code from the redirect callback (paste-code mode).',
|
|
9122
|
+
},
|
|
9123
|
+
{
|
|
9124
|
+
name: 'codeVerifier',
|
|
9125
|
+
type: 'string',
|
|
9126
|
+
required: false,
|
|
9127
|
+
description: 'PKCE code verifier from service.auth-url, round-tripped (paste-code mode).',
|
|
9128
|
+
},
|
|
9129
|
+
{
|
|
9130
|
+
name: 'redirectUri',
|
|
9131
|
+
type: 'string',
|
|
9132
|
+
required: false,
|
|
9133
|
+
description: 'Redirect URI used in service.auth-url; must match (paste-code mode).',
|
|
9134
|
+
},
|
|
9135
|
+
],
|
|
9136
|
+
},
|
|
9137
|
+
{
|
|
9138
|
+
gateway: 'query',
|
|
9139
|
+
domain: 'service',
|
|
9140
|
+
operation: 'list',
|
|
9141
|
+
description: 'service.list (query) — list service connections as NON-SECRET views (provider/label/status/scopes/expiresAt/hasCredentials). The decrypted token is NEVER surfaced.',
|
|
9142
|
+
tier: 2,
|
|
9143
|
+
idempotent: true,
|
|
9144
|
+
sessionRequired: false,
|
|
9145
|
+
requiredParams: [],
|
|
9146
|
+
params: [
|
|
9147
|
+
{
|
|
9148
|
+
name: 'provider',
|
|
9149
|
+
type: 'string',
|
|
9150
|
+
required: false,
|
|
9151
|
+
description: 'Optional provider filter; lists all providers when omitted.',
|
|
9152
|
+
},
|
|
9153
|
+
],
|
|
9154
|
+
},
|
|
9155
|
+
{
|
|
9156
|
+
gateway: 'mutate',
|
|
9157
|
+
domain: 'service',
|
|
9158
|
+
operation: 'revoke',
|
|
9159
|
+
description: 'service.revoke (mutate) — DELETE a service connection and CASCADE its agent_service_grants. Returns the {count, deleted, grantsRemoved} envelope (count=0 when no such connection).',
|
|
9160
|
+
tier: 2,
|
|
9161
|
+
idempotent: false,
|
|
9162
|
+
sessionRequired: false,
|
|
9163
|
+
requiredParams: ['provider', 'label'],
|
|
9164
|
+
params: [
|
|
9165
|
+
{ name: 'provider', type: 'string', required: true, description: 'Service provider key.' },
|
|
9166
|
+
{
|
|
9167
|
+
name: 'label',
|
|
9168
|
+
type: 'string',
|
|
9169
|
+
required: true,
|
|
9170
|
+
description: 'Connection label to revoke.',
|
|
9171
|
+
},
|
|
9172
|
+
],
|
|
9173
|
+
},
|
|
9174
|
+
{
|
|
9175
|
+
gateway: 'query',
|
|
9176
|
+
domain: 'service',
|
|
9177
|
+
operation: 'status',
|
|
9178
|
+
description: 'service.status (query) — report connection health: each connection adds `expired` + `needsRefresh` booleans computed from expires_at. NON-SECRET; never surfaces a token.',
|
|
9179
|
+
tier: 2,
|
|
9180
|
+
idempotent: true,
|
|
9181
|
+
sessionRequired: false,
|
|
9182
|
+
requiredParams: [],
|
|
9183
|
+
params: [
|
|
9184
|
+
{
|
|
9185
|
+
name: 'provider',
|
|
9186
|
+
type: 'string',
|
|
9187
|
+
required: false,
|
|
9188
|
+
description: 'Optional provider filter; reports all connections when omitted.',
|
|
9189
|
+
},
|
|
9190
|
+
],
|
|
9191
|
+
},
|
|
9192
|
+
// ── 5-entity provider experience (T11700 · epic T11666 · North-Star §2) ──
|
|
9193
|
+
// The addressable Provider / Alias / Account / Model / Profile surface. Each op
|
|
9194
|
+
// dispatches to the CORE entity-ops layer (llm/entity-ops.ts), which is a thin
|
|
9195
|
+
// composition over the ALREADY-MERGED accessors: the credential pool
|
|
9196
|
+
// (account.* — secret-bearing, redacted to tokenPreview), the declarative
|
|
9197
|
+
// `providers` table (#1039), the `models_catalog` table (#1037), and the
|
|
9198
|
+
// resolver-consumed `llm.profiles[name]` config (profile.*). The secret-bearing
|
|
9199
|
+
// ops carry NO `mcpExposed` flag → they are MCP-default-denied (AC5/AC7); read
|
|
9200
|
+
// ops are also unary CLI/RPC/HTTP (no `mcpExposed`), keeping the MCP surface
|
|
9201
|
+
// curated. INPUT + OUTPUT contracts live in contracts/operations/entities.ts.
|
|
9202
|
+
// account.* — the credential pool (the rename/successor of the secret-bearing
|
|
9203
|
+
// `llm` pool ops). `account.add` is SECRET-BEARING (cli-only; MCP-denied).
|
|
9204
|
+
{
|
|
9205
|
+
gateway: 'mutate',
|
|
9206
|
+
domain: 'account',
|
|
9207
|
+
operation: 'add',
|
|
9208
|
+
description: 'account.add (mutate) — store a pooled provider credential. SECRET-BEARING (cli-only): accepts an API key / OAuth token and persists it encrypted; returns the NON-SECRET redacted view (tokenPreview last-4 ONLY — never the raw secret).',
|
|
9209
|
+
tier: 2,
|
|
9210
|
+
idempotent: false,
|
|
9211
|
+
sessionRequired: false,
|
|
9212
|
+
requiredParams: ['provider', 'token'],
|
|
9213
|
+
params: [
|
|
9214
|
+
{
|
|
9215
|
+
name: 'provider',
|
|
9216
|
+
type: 'string',
|
|
9217
|
+
required: true,
|
|
9218
|
+
description: 'LLM provider transport key (e.g. anthropic, openai).',
|
|
9219
|
+
cli: { positional: true },
|
|
9220
|
+
},
|
|
9221
|
+
{
|
|
9222
|
+
name: 'token',
|
|
9223
|
+
type: 'string',
|
|
9224
|
+
required: true,
|
|
9225
|
+
description: 'API key or OAuth bearer token to persist. SECRET — never echoed.',
|
|
9226
|
+
},
|
|
9227
|
+
{
|
|
9228
|
+
name: 'label',
|
|
9229
|
+
type: 'string',
|
|
9230
|
+
required: false,
|
|
9231
|
+
description: "Account label, unique within the provider (default: 'default').",
|
|
9232
|
+
},
|
|
9233
|
+
{
|
|
9234
|
+
name: 'baseUrl',
|
|
9235
|
+
type: 'string',
|
|
9236
|
+
required: false,
|
|
9237
|
+
description: 'Optional override for the provider base URL.',
|
|
9238
|
+
},
|
|
9239
|
+
{
|
|
9240
|
+
name: 'authType',
|
|
9241
|
+
type: 'string',
|
|
9242
|
+
required: false,
|
|
9243
|
+
description: "Explicit auth-type override ('api_key' | 'oauth' | 'aws_sdk').",
|
|
9244
|
+
},
|
|
9245
|
+
{
|
|
9246
|
+
name: 'priority',
|
|
9247
|
+
type: 'number',
|
|
9248
|
+
required: false,
|
|
9249
|
+
description: 'Optional priority override (lower wins).',
|
|
9250
|
+
},
|
|
9251
|
+
],
|
|
9252
|
+
},
|
|
9253
|
+
{
|
|
9254
|
+
gateway: 'query',
|
|
9255
|
+
domain: 'account',
|
|
9256
|
+
operation: 'list',
|
|
9257
|
+
description: 'account.list (query) — list pooled accounts as NON-SECRET redacted views (provider/label/authType/tokenPreview). The decrypted secret is NEVER surfaced.',
|
|
9258
|
+
tier: 2,
|
|
9259
|
+
idempotent: true,
|
|
9260
|
+
sessionRequired: false,
|
|
9261
|
+
requiredParams: [],
|
|
9262
|
+
params: [
|
|
9263
|
+
{
|
|
9264
|
+
name: 'provider',
|
|
9265
|
+
type: 'string',
|
|
9266
|
+
required: false,
|
|
9267
|
+
description: 'Optional provider filter; lists all providers when omitted.',
|
|
9268
|
+
},
|
|
9269
|
+
],
|
|
9270
|
+
},
|
|
9271
|
+
{
|
|
9272
|
+
gateway: 'mutate',
|
|
9273
|
+
domain: 'account',
|
|
9274
|
+
operation: 'remove',
|
|
9275
|
+
description: 'account.remove (mutate) — delete a (provider, label) account from the pool. Returns the {count, deleted} envelope (count=0 when absent — idempotent).',
|
|
9276
|
+
tier: 2,
|
|
9277
|
+
idempotent: true,
|
|
9278
|
+
sessionRequired: false,
|
|
9279
|
+
requiredParams: ['provider', 'label'],
|
|
9280
|
+
params: [
|
|
9281
|
+
{
|
|
9282
|
+
name: 'provider',
|
|
9283
|
+
type: 'string',
|
|
9284
|
+
required: true,
|
|
9285
|
+
description: 'LLM provider transport key.',
|
|
9286
|
+
cli: { positional: true },
|
|
9287
|
+
},
|
|
9288
|
+
{
|
|
9289
|
+
name: 'label',
|
|
9290
|
+
type: 'string',
|
|
9291
|
+
required: true,
|
|
9292
|
+
description: 'Account label to remove.',
|
|
9293
|
+
},
|
|
9294
|
+
],
|
|
9295
|
+
},
|
|
9296
|
+
// provider.* — the declarative `providers` table (#1039) + alias resolution.
|
|
9297
|
+
{
|
|
9298
|
+
gateway: 'query',
|
|
9299
|
+
domain: 'provider',
|
|
9300
|
+
operation: 'list',
|
|
9301
|
+
description: 'provider.list (query) — list every declarative provider as a NON-SECRET view (id/displayName/aliases/authMethods/modelsDevId) from the providers table.',
|
|
9302
|
+
tier: 1,
|
|
9303
|
+
idempotent: true,
|
|
9304
|
+
sessionRequired: false,
|
|
9305
|
+
requiredParams: [],
|
|
9306
|
+
params: [],
|
|
9307
|
+
},
|
|
9308
|
+
{
|
|
9309
|
+
gateway: 'query',
|
|
9310
|
+
domain: 'provider',
|
|
9311
|
+
operation: 'show',
|
|
9312
|
+
description: 'provider.show (query) — resolve ONE provider by id OR case-insensitive alias against the declarative alias index; returns the provider view + the id/alias matched.',
|
|
9313
|
+
tier: 1,
|
|
9314
|
+
idempotent: true,
|
|
9315
|
+
sessionRequired: false,
|
|
9316
|
+
requiredParams: ['provider'],
|
|
9317
|
+
params: [
|
|
9318
|
+
{
|
|
9319
|
+
name: 'provider',
|
|
9320
|
+
type: 'string',
|
|
9321
|
+
required: true,
|
|
9322
|
+
description: 'Provider id OR a case-insensitive alias.',
|
|
9323
|
+
cli: { positional: true },
|
|
9324
|
+
},
|
|
9325
|
+
],
|
|
9326
|
+
},
|
|
9327
|
+
{
|
|
9328
|
+
gateway: 'mutate',
|
|
9329
|
+
domain: 'provider',
|
|
9330
|
+
operation: 'connect',
|
|
9331
|
+
description: 'provider.connect (mutate) — connect a provider by storing a token as one of its accounts (token-direct). SECRET-BEARING (cli-only): resolves the provider (id/alias) then delegates to the secret-bearing account write; returns the NON-SECRET account identity (never the raw token). OAuth flows route through `cleo service`.',
|
|
9332
|
+
tier: 2,
|
|
9333
|
+
idempotent: false,
|
|
9334
|
+
sessionRequired: false,
|
|
9335
|
+
requiredParams: ['provider'],
|
|
9336
|
+
params: [
|
|
9337
|
+
{
|
|
9338
|
+
name: 'provider',
|
|
9339
|
+
type: 'string',
|
|
9340
|
+
required: true,
|
|
9341
|
+
description: 'Provider id or alias to connect.',
|
|
9342
|
+
cli: { positional: true },
|
|
9343
|
+
},
|
|
9344
|
+
{
|
|
9345
|
+
name: 'token',
|
|
9346
|
+
type: 'string',
|
|
9347
|
+
required: false,
|
|
9348
|
+
description: 'Direct API key / bearer token to store (token-direct mode). SECRET.',
|
|
9349
|
+
},
|
|
9350
|
+
{
|
|
9351
|
+
name: 'label',
|
|
9352
|
+
type: 'string',
|
|
9353
|
+
required: false,
|
|
9354
|
+
description: "Account label to create (default: 'default').",
|
|
9355
|
+
},
|
|
9356
|
+
{
|
|
9357
|
+
name: 'authType',
|
|
9358
|
+
type: 'string',
|
|
9359
|
+
required: false,
|
|
9360
|
+
description: "Explicit auth-type override ('api_key' | 'oauth' | 'aws_sdk').",
|
|
9361
|
+
},
|
|
9362
|
+
],
|
|
9363
|
+
},
|
|
9364
|
+
// model.* — the models.dev catalog (`models_catalog` table, #1037). QUERY-ONLY.
|
|
9365
|
+
{
|
|
9366
|
+
gateway: 'query',
|
|
9367
|
+
domain: 'model',
|
|
9368
|
+
operation: 'query',
|
|
9369
|
+
description: 'model.query (query) — read the models.dev catalog (models_catalog table) newest-first by release date; optionally filtered by provider (models.dev id) and capped by --limit. Returns NON-SECRET catalog views.',
|
|
9370
|
+
tier: 1,
|
|
9371
|
+
idempotent: true,
|
|
9372
|
+
sessionRequired: false,
|
|
9373
|
+
requiredParams: [],
|
|
9374
|
+
params: [
|
|
9375
|
+
{
|
|
9376
|
+
name: 'provider',
|
|
9377
|
+
type: 'string',
|
|
9378
|
+
required: false,
|
|
9379
|
+
description: 'Optional provider filter (models.dev id); queries all providers when omitted.',
|
|
9380
|
+
},
|
|
9381
|
+
{
|
|
9382
|
+
name: 'limit',
|
|
9383
|
+
type: 'number',
|
|
9384
|
+
required: false,
|
|
9385
|
+
description: 'Optional cap on the number of rows returned (newest-first).',
|
|
9386
|
+
},
|
|
9387
|
+
],
|
|
9388
|
+
},
|
|
9389
|
+
{
|
|
9390
|
+
gateway: 'query',
|
|
9391
|
+
domain: 'model',
|
|
9392
|
+
operation: 'show',
|
|
9393
|
+
description: 'model.show (query) — resolve ONE catalog model by id; returns {found, model} (found=false when the id is absent — not an error).',
|
|
9394
|
+
tier: 1,
|
|
9395
|
+
idempotent: true,
|
|
9396
|
+
sessionRequired: false,
|
|
9397
|
+
requiredParams: ['model'],
|
|
9398
|
+
params: [
|
|
9399
|
+
{
|
|
9400
|
+
name: 'model',
|
|
9401
|
+
type: 'string',
|
|
9402
|
+
required: true,
|
|
9403
|
+
description: 'Model id (catalog key) to resolve.',
|
|
9404
|
+
cli: { positional: true },
|
|
9405
|
+
},
|
|
9406
|
+
],
|
|
9407
|
+
},
|
|
9408
|
+
// profile.* — the named binding account+model[+params+role], persisted into
|
|
9409
|
+
// `llm.profiles[name]` (the resolver-consumed config SSoT).
|
|
9410
|
+
{
|
|
9411
|
+
gateway: 'mutate',
|
|
9412
|
+
domain: 'profile',
|
|
9413
|
+
operation: 'create',
|
|
9414
|
+
description: 'profile.create (mutate) — bind an account + model into a named, addressable profile. Validates the binding (the pinned account must exist; the model must be in the catalog) then persists into llm.profiles[name]. Returns {count, created, profile}.',
|
|
9415
|
+
tier: 2,
|
|
9416
|
+
idempotent: false,
|
|
9417
|
+
sessionRequired: false,
|
|
9418
|
+
requiredParams: ['name', 'provider', 'model'],
|
|
9419
|
+
params: [
|
|
9420
|
+
{
|
|
9421
|
+
name: 'name',
|
|
9422
|
+
type: 'string',
|
|
9423
|
+
required: true,
|
|
9424
|
+
description: 'Profile name (the addressable handle).',
|
|
9425
|
+
cli: { positional: true },
|
|
9426
|
+
},
|
|
9427
|
+
{
|
|
9428
|
+
name: 'provider',
|
|
9429
|
+
type: 'string',
|
|
9430
|
+
required: true,
|
|
9431
|
+
description: 'Provider transport the bound account belongs to.',
|
|
9432
|
+
},
|
|
9433
|
+
{
|
|
9434
|
+
name: 'model',
|
|
9435
|
+
type: 'string',
|
|
9436
|
+
required: true,
|
|
9437
|
+
description: 'Model id to bind (validated against the catalog).',
|
|
9438
|
+
},
|
|
9439
|
+
{
|
|
9440
|
+
name: 'label',
|
|
9441
|
+
type: 'string',
|
|
9442
|
+
required: false,
|
|
9443
|
+
description: 'Account label to pin (the credential binding). Validated to exist.',
|
|
9444
|
+
},
|
|
9445
|
+
{
|
|
9446
|
+
name: 'role',
|
|
9447
|
+
type: 'string',
|
|
9448
|
+
required: false,
|
|
9449
|
+
description: 'Optional role this profile occupies (extraction | consolidation | …).',
|
|
9450
|
+
},
|
|
9451
|
+
],
|
|
9452
|
+
},
|
|
9453
|
+
{
|
|
9454
|
+
gateway: 'query',
|
|
9455
|
+
domain: 'profile',
|
|
9456
|
+
operation: 'list',
|
|
9457
|
+
description: 'profile.list (query) — list every named profile from llm.profiles (name + provider + model + optional credentialLabel).',
|
|
9458
|
+
tier: 2,
|
|
9459
|
+
idempotent: true,
|
|
9460
|
+
sessionRequired: false,
|
|
9461
|
+
requiredParams: [],
|
|
9462
|
+
params: [],
|
|
9463
|
+
},
|
|
9464
|
+
{
|
|
9465
|
+
gateway: 'mutate',
|
|
9466
|
+
domain: 'profile',
|
|
9467
|
+
operation: 'pin',
|
|
9468
|
+
description: 'profile.pin (mutate) — pin a role to a named profile (llm.roles[role].profile). The role must be a valid background role and the profile must already exist.',
|
|
9469
|
+
tier: 2,
|
|
9470
|
+
idempotent: true,
|
|
9471
|
+
sessionRequired: false,
|
|
9472
|
+
requiredParams: ['name', 'role'],
|
|
9473
|
+
params: [
|
|
9474
|
+
{
|
|
9475
|
+
name: 'name',
|
|
9476
|
+
type: 'string',
|
|
9477
|
+
required: true,
|
|
9478
|
+
description: 'Profile name to pin (must exist).',
|
|
9479
|
+
cli: { positional: true },
|
|
9480
|
+
},
|
|
9481
|
+
{
|
|
9482
|
+
name: 'role',
|
|
9483
|
+
type: 'string',
|
|
9484
|
+
required: true,
|
|
9485
|
+
description: 'Role to pin to this profile (extraction | consolidation | derivation | …).',
|
|
9486
|
+
},
|
|
9487
|
+
],
|
|
9488
|
+
},
|
|
9489
|
+
{
|
|
9490
|
+
gateway: 'mutate',
|
|
9491
|
+
domain: 'profile',
|
|
9492
|
+
operation: 'use',
|
|
9493
|
+
description: 'profile.use (mutate) — set a named profile as the global default binding (llm.defaultProfile). The profile must already exist.',
|
|
9494
|
+
tier: 2,
|
|
9495
|
+
idempotent: true,
|
|
9496
|
+
sessionRequired: false,
|
|
9497
|
+
requiredParams: ['name'],
|
|
9498
|
+
params: [
|
|
9499
|
+
{
|
|
9500
|
+
name: 'name',
|
|
9501
|
+
type: 'string',
|
|
9502
|
+
required: true,
|
|
9503
|
+
description: 'Profile name to mark as default (must exist).',
|
|
9504
|
+
cli: { positional: true },
|
|
9505
|
+
},
|
|
9506
|
+
],
|
|
9507
|
+
},
|
|
8524
9508
|
];
|
|
8525
9509
|
//# sourceMappingURL=operations-registry.js.map
|