@cat-factory/app 0.36.0 → 0.37.1

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.
Files changed (88) hide show
  1. package/app/components/auth/UserMenu.vue +11 -1
  2. package/app/components/brainstorm/BrainstormWindow.vue +2 -1
  3. package/app/components/clarity/ClarityReviewWindow.vue +2 -1
  4. package/app/components/layout/IntegrationBackTitle.vue +12 -7
  5. package/app/components/layout/IntegrationsHub.vue +191 -43
  6. package/app/components/layout/PersonalSetupModal.vue +141 -0
  7. package/app/components/pipeline/PipelineBuilder.vue +1 -1
  8. package/app/components/providers/VendorCredentialsModal.vue +7 -2
  9. package/app/composables/api/accounts.ts +36 -51
  10. package/app/composables/api/auth.ts +20 -19
  11. package/app/composables/api/board.ts +60 -40
  12. package/app/composables/api/bootstrap.ts +25 -22
  13. package/app/composables/api/client.ts +102 -0
  14. package/app/composables/api/context.ts +25 -6
  15. package/app/composables/api/documents.ts +36 -34
  16. package/app/composables/api/execution.ts +65 -48
  17. package/app/composables/api/followUps.ts +26 -26
  18. package/app/composables/api/fragments.ts +47 -34
  19. package/app/composables/api/github.ts +65 -45
  20. package/app/composables/api/humanReview.ts +7 -6
  21. package/app/composables/api/humanTest.ts +15 -11
  22. package/app/composables/api/kaizen.ts +8 -6
  23. package/app/composables/api/localSettings.ts +5 -4
  24. package/app/composables/api/models.ts +58 -51
  25. package/app/composables/api/notifications.ts +13 -7
  26. package/app/composables/api/presets.ts +34 -28
  27. package/app/composables/api/providerConnections.ts +68 -26
  28. package/app/composables/api/recurring.ts +40 -30
  29. package/app/composables/api/releaseHealth.ts +28 -26
  30. package/app/composables/api/reviews.ts +136 -114
  31. package/app/composables/api/sandbox.ts +52 -34
  32. package/app/composables/api/slack.ts +22 -25
  33. package/app/composables/api/spec.ts +3 -3
  34. package/app/composables/api/tasks.ts +42 -41
  35. package/app/composables/api/userSecrets.ts +12 -17
  36. package/app/composables/api/workspaces.ts +21 -15
  37. package/app/composables/useApi.ts +9 -1
  38. package/app/composables/useIntegrationBack.ts +9 -3
  39. package/app/composables/useSourceIntegration.ts +107 -0
  40. package/app/composables/useUpsertList.spec.ts +60 -0
  41. package/app/composables/useUpsertList.ts +57 -0
  42. package/app/pages/index.vue +2 -0
  43. package/app/stores/auth.ts +2 -1
  44. package/app/stores/board.ts +2 -1
  45. package/app/stores/brainstorm.ts +2 -2
  46. package/app/stores/clarity.ts +6 -2
  47. package/app/stores/documents.ts +27 -62
  48. package/app/stores/execution.ts +3 -2
  49. package/app/stores/github.ts +1 -2
  50. package/app/stores/mergePresets.ts +2 -6
  51. package/app/stores/notifications.ts +9 -6
  52. package/app/stores/pipelines.ts +1 -1
  53. package/app/stores/recurringPipelines.ts +2 -7
  54. package/app/stores/sandbox.ts +1 -2
  55. package/app/stores/tasks.ts +25 -76
  56. package/app/stores/ui.ts +62 -19
  57. package/app/types/accountSettings.ts +11 -36
  58. package/app/types/accounts.ts +16 -71
  59. package/app/types/bootstrap.ts +13 -75
  60. package/app/types/brainstorm.ts +13 -38
  61. package/app/types/clarity.ts +12 -43
  62. package/app/types/consensus.ts +16 -89
  63. package/app/types/documents.ts +19 -94
  64. package/app/types/domain.ts +54 -586
  65. package/app/types/execution.ts +48 -515
  66. package/app/types/fragments.ts +15 -83
  67. package/app/types/github.ts +25 -161
  68. package/app/types/incidentEnrichment.ts +10 -25
  69. package/app/types/localModels.ts +11 -61
  70. package/app/types/localSettings.ts +9 -26
  71. package/app/types/merge.ts +10 -68
  72. package/app/types/model-presets.ts +7 -28
  73. package/app/types/models.ts +16 -164
  74. package/app/types/notifications.ts +18 -77
  75. package/app/types/openrouter.ts +8 -34
  76. package/app/types/providerConnections.ts +21 -41
  77. package/app/types/provisioningLogs.ts +9 -29
  78. package/app/types/recurring.ts +10 -63
  79. package/app/types/releaseHealth.ts +15 -39
  80. package/app/types/requirements.ts +14 -84
  81. package/app/types/sandbox.ts +45 -161
  82. package/app/types/services.ts +3 -22
  83. package/app/types/slack.ts +10 -47
  84. package/app/types/spec.ts +15 -68
  85. package/app/types/tasks.ts +15 -111
  86. package/app/types/tracker.ts +9 -24
  87. package/app/types/userSecrets.ts +12 -47
  88. package/package.json +9 -2
@@ -1,332 +1,58 @@
1
1
  // ---------------------------------------------------------------------------
2
2
  // Domain model for the Agent Architecture Board.
3
3
  //
4
- // These shapes mirror the `@cat-factory/contracts` wire schemas exactly, so a
5
- // payload returned by the backend drops straight into the Pinia stores without
6
- // translation. The board and its agent pipelines are owned by the backend; the
7
- // frontend renders and mutates that state over the REST API.
4
+ // The wire shapes are owned by `@cat-factory/contracts` and re-exported here, so
5
+ // a payload returned by the backend drops straight into the Pinia stores without
6
+ // translation. This module re-exports the core board vocabulary from the
7
+ // contracts package and adds the few genuinely frontend-only types (palette
8
+ // presentation, level-of-detail, the signed-in user view) on top.
8
9
  //
9
- // This module holds the core board vocabulary. Adjacent concerns live in
10
- // sibling modules and are re-exported below so `~/types/domain` stays the single
11
- // import surface:
10
+ // Adjacent concerns live in sibling modules and are re-exported below so
11
+ // `~/types/domain` stays the single import surface:
12
12
  // - execution model → ./execution
13
13
  // - models/fragments → ./models
14
14
  // - document sources → ./documents
15
15
  // ---------------------------------------------------------------------------
16
16
 
17
- import type { ExecutionInstance, LlmCallActivity } from './execution'
18
- import type { BootstrapJob } from './bootstrap'
19
- import type { Notification } from './notifications'
20
- import type { RequirementReview } from './requirements'
21
- import type { ConsensusSession, ConsensusStepConfig, StepGating, TaskEstimate } from './consensus'
22
- import type { ClarityReview } from './clarity'
23
- import type { BrainstormSession } from './brainstorm'
24
- import type { MergeThresholdPreset } from './merge'
25
- import type { ModelPreset } from './model-presets'
26
- import type { PipelineSchedule } from './recurring'
27
- import type { Service, WorkspaceMount } from './services'
28
- import type { TrackerSettings, WritebackOverride } from './tracker'
29
-
30
- /** Lifecycle of an architecture building block. */
31
- export type BlockStatus =
32
- | 'planned' // sketched, no dependencies satisfied yet
33
- | 'ready' // dependencies done, can be implemented
34
- | 'in_progress' // a pipeline is (visually) running against it
35
- | 'blocked' // a pipeline step is waiting on a human decision
36
- | 'pr_ready' // pipeline finished — a PR is open and awaiting merge
37
- | 'done' // PR merged, implementation complete
38
-
39
- /**
40
- * Kind of architecture building block (drives icon + accent). `external` and
41
- * `environment` are no longer user-creatable, but the backend still emits them
42
- * (the seed's third-party `external` service, and the environments integration's
43
- * `environment` blocks), so they remain part of the union for display parity with
44
- * the contracts `blockTypeSchema`.
45
- */
46
- export type BlockType =
47
- | 'frontend'
48
- | 'service'
49
- | 'api'
50
- | 'database'
51
- | 'queue'
52
- | 'integration'
53
- | 'external'
54
- | 'environment'
55
-
56
- /**
57
- * Where a block sits in the granularity hierarchy. Both `frame` and `module`
58
- * are containers ("frames") that hold draggable tasks:
59
- * - `frame` a top-level Service; the only level rendered as a board node
60
- * - `module` a sub-frame inside a service; created when a task assigned to a
61
- * not-yet-existing module is implemented (tasks can also be dragged in)
62
- * - `task` a draggable unit of work living inside a service or a module
63
- * - `epic` a NON-structural grouping node: it groups tasks (which keep their own
64
- * service/module parent) via their `epicId`, and is drawn linked to them.
65
- * Never a container — nothing is reparented into an epic.
66
- */
67
- export type BlockLevel = 'frame' | 'module' | 'task' | 'epic'
68
-
69
- /**
70
- * The kind of work a task represents, chosen at creation. Drives the card's badge/icon
71
- * and the optional per-service running-task limit's bucketing. `recurring` tasks are
72
- * created via a recurring-pipeline schedule, not the add-task form.
73
- */
74
- export type TaskType = 'feature' | 'bug' | 'document' | 'spike' | 'recurring'
75
-
76
- /** The task types selectable in the add-task form (recurring is created via a schedule). */
77
- export type CreateTaskType = 'feature' | 'bug' | 'document' | 'spike'
78
-
79
- /** Small, optional per-type fields collected on the add-task form. */
80
- export interface TaskTypeFields {
81
- /** bug: defect severity. */
82
- severity?: 'low' | 'medium' | 'high' | 'critical'
83
- /** bug: reproduction steps / observed-vs-expected. */
84
- stepsToReproduce?: string
85
- /** spike: the investigation time-box, in hours. */
86
- timeboxHours?: number
87
- /** document: what kind of document this task produces. */
88
- docKind?: 'prd' | 'rfc' | 'runbook' | 'reference' | 'other'
89
- }
90
-
91
- /** A building block dropped on the board. */
92
- export interface Block {
93
- id: string
94
- title: string
95
- type: BlockType
96
- description: string
97
- /** position relative to the parent container (service or module). */
98
- position: { x: number; y: number }
99
- /**
100
- * Explicit, user-dragged pixel size for a resizable frame (Miro-style border
101
- * drag). Absent = the board auto-sizes the frame from its contents; present =
102
- * the dragged size, never shrunk below the content's natural extent.
103
- */
104
- size?: { w: number; h: number }
105
- status: BlockStatus
106
- /** 0..1 implementation progress, derived from the running execution. */
107
- progress: number
108
- /** ids of tasks that must be implemented before this one (drives arrows). */
109
- dependsOn: string[]
110
- /** id of the ExecutionInstance currently running against this block, if any. */
111
- executionId: string | null
112
- /** granularity level; absent on legacy/persisted data means `frame`. */
113
- level: BlockLevel
114
- /** parent container: service or module for a task, service for a module. */
115
- parentId: string | null
116
- /**
117
- * task-only: membership link to an `epic`-level block, independent of `parentId`.
118
- * Set when the task belongs to an epic (drawn linked to it); absent/null otherwise.
119
- */
120
- epicId?: string | null
121
- /**
122
- * task-only: when this task merges, automatically start the tasks that depend on it
123
- * (and whose other dependencies are also done). Off/absent ⇒ dependents wait.
124
- */
125
- autoStartDependents?: boolean
126
- /** task-only: 0..1 confidence produced when the pipeline finishes. */
127
- confidence?: number
128
- /** task-only: the task-estimator's triage (complexity/risk/impact); absent until it runs. */
129
- estimate?: TaskEstimate | null
130
- /** task-only: the module this task belongs to (created on implement if absent). */
131
- moduleName?: string
132
- /** task-only: the kind of work (feature/bug/document/spike/recurring); absent = feature. */
133
- taskType?: TaskType
134
- /** task-only: small per-type form fields (bug severity, spike timebox, …). */
135
- taskTypeFields?: TaskTypeFields | null
136
- /**
137
- * task-only: TECHNICAL label. `true` ⇒ a refactor / non-functional / internal change
138
- * (the implementer treats the task definition as primary, specs as a regression
139
- * reference; the spec-writer may produce no business specs). `false` ⇒ a business task.
140
- * `null`/absent ⇒ not yet determined — the engine may infer it from the spec phase. A
141
- * human-set value is authoritative and never overridden; the inspector toggle is
142
- * tri-state (unset / technical / business) and sends `null` for "unset".
143
- */
144
- technical?: boolean | null
145
- /** ids of best-practice prompt fragments folded into this block's agent prompts. */
146
- fragmentIds?: string[]
147
- /**
148
- * frame-only: the service's selected best-practice fragment ids. Folded into the
149
- * prompt of every `code-aware` agent on tasks under this service. Seeded from the
150
- * workspace default on new services; absent = none.
151
- */
152
- serviceFragmentIds?: string[]
153
- /** id of the model (from MODEL_CATALOG) to run this block's agents with; absent = default. */
154
- modelId?: string
155
- /** the PR the block's implementer agent opened for its work; absent = none yet. */
156
- pullRequest?: PullRequestRef
157
- /** task-only: selected merge threshold preset id; absent = workspace default. */
158
- mergePresetId?: string
159
- /** task-only: selected model preset id (which model each agent runs); absent = workspace default. */
160
- modelPresetId?: string
161
- /** task-only: pinned default pipeline id picked at creation; absent = none. */
162
- pipelineId?: string
163
- /** task-only: agent-contributed config values (id→value), e.g. the Tester's environment. */
164
- agentConfig?: Record<string, string>
165
- /** service-only (frame): docker-compose path for the Tester's local infra; absent = none. */
166
- testComposePath?: string
167
- /** service-only (frame): the service has no infra dependencies to stand up. */
168
- noInfraDependencies?: boolean
169
- /**
170
- * service-only (frame): the default test environment a task under this service is
171
- * spawned with — `local` (docker-compose infra) or `ephemeral` (provisioned env).
172
- * Tasks inherit it unless they override via their `tester.environment` config.
173
- * absent = the built-in `ephemeral`.
174
- */
175
- defaultTestEnvironment?: 'local' | 'ephemeral'
176
- /** service-only (frame): cloud provider the service's jobs run on; absent = account default. */
177
- cloudProvider?: CloudProvider
178
- /** service-only (frame): abstract instance size for the service's jobs; absent = default. */
179
- instanceSize?: InstanceSize
180
- /** GitHub user id of the task's creator; drives "notify the task creator" routing. */
181
- createdBy?: number | null
182
- /**
183
- * Internal user id (`usr_*`) of the responsible product person — an account member
184
- * with the `product` role, notified when requirement review flags this task.
185
- */
186
- responsibleProductUserId?: string | null
187
- /** task-only: override "comment on the linked issue when a PR opens"; absent/null = inherit workspace. */
188
- trackerCommentOnPrOpen?: WritebackOverride | null
189
- /** task-only: override "close the linked issue as resolved on merge"; absent/null = inherit workspace. */
190
- trackerResolveOnMerge?: WritebackOverride | null
191
- }
192
-
193
- /**
194
- * A lightweight link from a block to the pull request its implementer agent
195
- * opened. Just enough to display the PR on the board and navigate to it; mirrors
196
- * `PullRequestRef` in `@cat-factory/contracts`.
197
- */
198
- export interface PullRequestRef {
199
- /** The PR's web URL, opened when the user clicks through from the board. */
200
- url: string
201
- /** The PR number within the repo, shown as `#<number>` when known. */
202
- number?: number
203
- /** The head branch the agent pushed its work to, when known. */
204
- branch?: string
205
- }
206
-
207
- /** The cloud provider a service's container jobs run on (per service; account default otherwise). */
208
- export type CloudProvider = 'cloudflare' | 'docker' | 'aws' | 'gcp' | 'azure' | 'custom'
209
-
210
- /** Abstract, cloud-neutral instance size selectable per service. */
211
- export type InstanceSize = 'small' | 'medium' | 'large' | 'xlarge'
212
-
213
- /** One choice of a `select` agent-config descriptor. */
214
- export interface AgentConfigOption {
215
- value: string
216
- label: string
217
- }
218
-
219
- /** A task-level configuration parameter an agent kind contributes (see the snapshot catalog). */
220
- export interface AgentConfigDescriptor {
221
- id: string
222
- agentKind: string
223
- label: string
224
- description: string
225
- type: 'select'
226
- options: AgentConfigOption[]
227
- default: string
228
- }
229
-
230
- /** Severity of a Tester-raised concern. */
231
- export type TestConcernSeverity = 'low' | 'medium' | 'high' | 'critical'
232
-
233
- /** A bug/risk the Tester surfaced. */
234
- export interface TestConcern {
235
- title: string
236
- detail: string
237
- severity: TestConcernSeverity
238
- }
239
-
240
- /** A per-area Tester result. */
241
- export interface TestOutcome {
242
- name: string
243
- status: 'passed' | 'failed' | 'skipped'
244
- detail?: string
245
- }
246
-
247
- /** A Tester's structured report (what was tested, outcomes, concerns, greenlight). */
248
- export interface TestReport {
249
- greenlight: boolean
250
- summary: string
251
- tested: string[]
252
- outcomes: TestOutcome[]
253
- concerns: TestConcern[]
254
- environment?: 'local' | 'ephemeral'
255
- }
256
-
257
- /** The kinds of agents available in the agent palette. */
258
- export type AgentKind =
259
- | 'requirements-review'
260
- // Brainstorm (structured-dialogue) gates: propose options with trade-offs and let the human
261
- // converge. `requirements-brainstorm` runs before the requirements review; `architecture-
262
- // brainstorm` before the architect. Both open the shared brainstorm window.
263
- | 'requirements-brainstorm'
264
- | 'architecture-brainstorm'
265
- | 'architect'
266
- | 'researcher'
267
- | 'coder'
268
- | 'tester'
269
- // `reviewer` is the coder's companion: it rates the change and loops it back for
270
- // automatic rework below the quality threshold (see companions below).
271
- | 'reviewer'
272
- | 'documenter'
273
- | 'integrator'
274
- | 'playwright'
275
- | 'mocker'
276
- | 'business-documenter'
277
- | 'business-reviewer'
278
- // Companion agents: they grade a prior producer step's output (0..1), loop it back
279
- // for automatic rework below threshold, then raise the human gate on a pass.
280
- | 'architect-companion'
281
- | 'spec-companion'
282
- // Engine-driven "system" kinds: not user-addable palette archetypes, but they
283
- // appear in seeded pipelines and run timelines. The spec-writer (aggregates every
284
- // task's clarified requirements + acceptance scenarios into the service's in-repo
285
- // `spec/` document before the coder runs), the blueprint mapper, the conflicts gate
286
- // + its resolver, the CI gate (a special non-LLM step that polls checks + loops the
287
- // fixer) + its fixer, and the PR-scoring merger.
288
- | 'spec-writer'
289
- | 'blueprints'
290
- | 'conflicts'
291
- | 'conflict-resolver'
292
- | 'ci'
293
- | 'ci-fixer'
294
- // The Tester's companion: dispatched within the tester gate to fix the bugs the
295
- // Tester found, then the Tester re-runs (skipped when the tests pass).
296
- | 'fixer'
297
- | 'merger'
298
- // The observability-gated post-release-health gate: not in any default pipeline and
299
- // only addable once an observability integration is connected. Watches the released
300
- // PR's monitors/SLOs and escalates to the on-call agent on a regression.
301
- | 'post-release-health'
302
- // Recurring tech-debt pipeline: read-only code `analysis`, then a special
303
- // non-LLM `tracker` step that files a GitHub issue / Jira ticket.
304
- | 'analysis'
305
- | 'tracker'
306
- // Pre-implementation triage: rates Complexity/Risk/Impact after requirements are
307
- // clarified, used to gate the optional consensus mechanism (and shown as ratings).
308
- | 'task-estimator'
309
- // Bug-fix pipeline: the `clarity-review` gate triages the bug report (the analogue
310
- // of `requirements-review`, with its own structured review window), then the
311
- // read-only `bug-investigator` container agent enriches it into a prose report.
312
- | 'clarity-review'
313
- | 'bug-investigator'
314
- // The human-testing gate: spins up an ephemeral environment and PARKS for a person to
315
- // validate the change in a live URL, dispatching the Tester's `fixer` (from findings) or
316
- // the `conflict-resolver` (on a conflicting pull-main) on demand. Opens its own window.
317
- | 'human-test'
318
- // The human-review gate: watches the PR for a human code review on GitHub, looping the
319
- // `fixer` to address review comments and advancing once approved with no unresolved threads.
320
- // Opens the shared gate window (with a freeform "request a fix" box).
321
- | 'human-review'
322
- // The Kaizen agent: post-run grader (NOT a pipeline step / palette archetype). Surfaced
323
- // only in Model Configuration (its model is pinnable like any agent) and run details.
324
- | 'kaizen'
325
-
326
- /** A draggable agent definition shown in the agent palette. */
327
- /** Palette grouping for the agent archetypes (collapsible sections in the builder). */
328
- export type AgentCategory = 'review' | 'design' | 'build' | 'test' | 'docs' | 'gates'
329
-
17
+ // Wire types sourced from the contracts package (single source of truth).
18
+ export type {
19
+ BlockStatus,
20
+ BlockType,
21
+ BlockLevel,
22
+ TaskType,
23
+ CreateTaskType,
24
+ TaskTypeFields,
25
+ Block,
26
+ PullRequestRef,
27
+ CloudProvider,
28
+ InstanceSize,
29
+ AgentConfigOption,
30
+ AgentConfigDescriptor,
31
+ TestConcernSeverity,
32
+ TestConcern,
33
+ TestOutcome,
34
+ TestReport,
35
+ AgentKind,
36
+ AgentCategory,
37
+ CustomAgentKind,
38
+ Pipeline,
39
+ SpendStatus,
40
+ Workspace,
41
+ WorkspaceSnapshot,
42
+ TaskLimitMode,
43
+ WorkspaceSettings,
44
+ UpdateWorkspaceSettingsInput,
45
+ ServiceFragmentDefaults,
46
+ KaizenGradingStatus,
47
+ KaizenGrading,
48
+ KaizenVerifiedCombo,
49
+ KaizenOverview,
50
+ WorkspaceEvent,
51
+ } from '@cat-factory/contracts'
52
+
53
+ import type { AgentCategory, AgentKind } from '@cat-factory/contracts'
54
+
55
+ /** A draggable agent definition shown in the agent palette. Frontend-only. */
330
56
  export interface AgentArchetype {
331
57
  kind: AgentKind
332
58
  label: string
@@ -346,281 +72,23 @@ export interface AgentArchetype {
346
72
  resultView?: string
347
73
  }
348
74
 
349
- /**
350
- * A registered CUSTOM agent kind carried in the workspace snapshot: its id + display
351
- * metadata + whether it runs in a container. The SPA merges these into its palette
352
- * catalog (`registerCustomKinds`) so a deployment's proprietary kind becomes a
353
- * first-class palette block + result view. Mirrors `CustomAgentKind` in
354
- * `@cat-factory/contracts`.
355
- */
356
- export interface CustomAgentKind {
357
- kind: AgentKind
358
- presentation: {
359
- label: string
360
- icon: string
361
- color: string
362
- description: string
363
- category?: AgentCategory
364
- resultView?: string
365
- }
366
- container: boolean
367
- }
368
-
369
- /** A reusable, linear sequence of agents. */
370
- export interface Pipeline {
371
- id: string
372
- name: string
373
- /** ordered agent kinds — the chain executes left to right */
374
- agentKinds: AgentKind[]
375
- /**
376
- * Per-step human approval gates, parallel to `agentKinds`: `gates[i]` true ⇒
377
- * the run pauses after step `i` for a human to review/edit its proposal. Absent
378
- * means no gates.
379
- */
380
- gates?: boolean[]
381
- /**
382
- * Per-step companion quality thresholds (0..1), parallel to `agentKinds`. Only
383
- * meaningful on companion steps; `null`/absent ⇒ use the companion's default bar.
384
- */
385
- thresholds?: (number | null)[]
386
- /**
387
- * Per-step enable flags, parallel to `agentKinds`: `enabled[i] === false` keeps the
388
- * step in the pipeline but skips it at run start. Absent/true ⇒ the step runs.
389
- */
390
- enabled?: boolean[]
391
- /**
392
- * Per-step consensus config, parallel to `agentKinds`: when set (with `enabled`) and the
393
- * step's kind carries a consensus trait, the step runs through the multi-model consensus
394
- * mechanism. `null`/absent ⇒ standard single-actor agent.
395
- */
396
- consensus?: (ConsensusStepConfig | null)[]
397
- /**
398
- * Per-step estimate gating, parallel to `agentKinds`: when set (with `enabled`) the step
399
- * is skipped at runtime unless the task estimate meets the threshold. `null`/absent ⇒
400
- * always run. Used to make a companion conditional on the task estimate.
401
- */
402
- gating?: (StepGating | null)[]
403
- /**
404
- * Per-step Follow-up companion toggle, parallel to `agentKinds`: governs whether a `coder`
405
- * step runs the future-looking Follow-up companion. `followUps[i] === false` disables it;
406
- * `null`/`true`/absent ⇒ enabled (a Coder step gets it by default). Ignored on non-coder steps.
407
- */
408
- followUps?: (boolean | null)[]
409
- /** Free-form organizational labels for the library (filter/search). */
410
- labels?: string[]
411
- /** True when archived: kept but hidden from the default library view. */
412
- archived?: boolean
413
- /**
414
- * True for the curated built-in catalog pipelines. Built-ins are read-only
415
- * templates — clone one to make an editable copy. Absent/false on custom pipelines.
416
- */
417
- builtin?: boolean
418
- }
419
-
420
- /**
421
- * Spend-safeguard status for the current billing period (a calendar month).
422
- * Token usage is priced into a single currency and gated by a budget; once
423
- * `exceeded`, runs are paused and the frontend shows a large warning.
424
- */
425
- export interface SpendStatus {
426
- /** Start of the current billing period (epoch ms). */
427
- periodStart: number
428
- inputTokens: number
429
- outputTokens: number
430
- /** Estimated spend this period, in `currency`. */
431
- costSpent: number
432
- /** Configured budget for one period, in `currency`. */
433
- costLimit: number
434
- /** ISO 4217 currency (e.g. 'EUR'). */
435
- currency: string
436
- /** True once the budget is reached: execution is paused. */
437
- exceeded: boolean
438
- }
439
-
440
- /** A board/project container owned by the backend. */
441
- export interface Workspace {
442
- id: string
443
- name: string
444
- /** Optional free-text description (null when unset). */
445
- description: string | null
446
- createdAt: number
447
- /** The account this board belongs to, or null for a legacy/unscoped board. */
448
- accountId: string | null
449
- }
450
-
451
- /** Full server-side state of a workspace, returned on load and after resets. */
452
- export interface WorkspaceSnapshot {
453
- workspace: Workspace
454
- blocks: Block[]
455
- pipelines: Pipeline[]
456
- executions: ExecutionInstance[]
457
- /** Bootstrap runs (the unified `agent_runs` bootstrap rows), so the board can
458
- * render a bootstrap's live progress / failure + retry on load. Absent on
459
- * older servers. */
460
- bootstrapJobs?: BootstrapJob[]
461
- /** Current spend-safeguard status; absent on older servers. */
462
- spend?: SpendStatus
463
- /** Open human-actionable notifications for the board inbox + badges. */
464
- notifications?: Notification[]
465
- /** The workspace's merge threshold presets (the task preset picker's options). */
466
- mergePresets?: MergeThresholdPreset[]
467
- /** Agent config-contribution descriptors (the task-level fields the board renders). */
468
- agentConfigCatalog?: AgentConfigDescriptor[]
469
- /** The workspace's model presets (the Model Configuration library + per-task picker). */
470
- modelPresets?: ModelPreset[]
471
- /**
472
- * The deployment's env-routing defaults as `provider:model` refs: the model a
473
- * kind runs on when neither the task nor the workspace pins one. `default` is the
474
- * global fallback; `byKind` carries kinds the operator routed specifically. Used
475
- * to name the model behind "Deployment default" in the settings panel.
476
- */
477
- deploymentModelDefaults?: { default: string; byKind: Record<string, string> }
478
- /** The workspace's default service-fragment selection (ids new services inherit). */
479
- serviceFragmentDefaults?: ServiceFragmentDefaults
480
- /** The workspace's recurring pipelines (schedules shown on the board + inspector). */
481
- recurringPipelines?: PipelineSchedule[]
482
- /** The workspace's issue-tracker selection (where the tech-debt pipeline files tickets). */
483
- trackerSettings?: TrackerSettings
484
- /** In-org sharing: the services this workspace mounts (with per-board frame layout). */
485
- mounts?: WorkspaceMount[]
486
- /** In-org sharing: the org's services this board can mount from (with mount counts). */
487
- serviceCatalog?: Service[]
488
- /** The workspace's runtime settings (human-wait escalation threshold + task limit). */
489
- settings?: WorkspaceSettings
490
- /**
491
- * Registered custom agent kinds (kind + presentation + container flag) a deployment
492
- * mixed in. The SPA merges these into its palette catalog so a proprietary kind becomes
493
- * a first-class palette block + result view. Absent when none are registered.
494
- */
495
- customAgentKinds?: CustomAgentKind[]
496
- }
497
-
498
- /** How the per-service running-task limit is bucketed. Mirrors `@cat-factory/contracts`. */
499
- export type TaskLimitMode = 'off' | 'shared' | 'per_type'
500
-
501
- /**
502
- * A workspace's runtime settings: how long a run may wait for a human before its
503
- * notification escalates yellow → red, and whether/how the number of tasks running
504
- * concurrently under one service is capped. Mirrors `@cat-factory/contracts`.
505
- */
506
- export interface WorkspaceSettings {
507
- /** Minutes a run may wait for human input before its notification turns red. */
508
- waitingEscalationMinutes: number
509
- /** Whether/how the per-service running-task limit is enforced. */
510
- taskLimitMode: TaskLimitMode
511
- /** The shared cap, when `taskLimitMode` is `shared`. */
512
- taskLimitShared: number | null
513
- /** The per-type caps, when `taskLimitMode` is `per_type` (type → cap). */
514
- taskLimitPerType: Partial<Record<CreateTaskType, number>> | null
515
- /** Whether to store the complete provided-context snapshot for each container agent. */
516
- storeAgentContext: boolean
517
- /** Whether the Kaizen agent grades agent steps after each run. On by default. */
518
- kaizenEnabled: boolean
519
- /** Local mode only: dispatch container agents to the runner pool instead of host Docker. */
520
- delegateAgentsToRunnerPool: boolean
521
- /** Local mode only: provision Tester environments via the env provider instead of DinD. */
522
- delegateTestEnvToProvider: boolean
523
- /** Spend budget currency (ISO 4217). Null ⇒ the built-in default (`EUR`). */
524
- spendCurrency: string | null
525
- /** Monthly spend budget in `spendCurrency`. Null ⇒ the built-in default. */
526
- spendMonthlyLimit: number | null
527
- }
528
-
529
- /** Patch a workspace's settings (only the supplied fields change). */
530
- export interface UpdateWorkspaceSettingsInput {
531
- waitingEscalationMinutes?: number
532
- taskLimitMode?: TaskLimitMode
533
- taskLimitShared?: number | null
534
- taskLimitPerType?: Partial<Record<CreateTaskType, number>> | null
535
- storeAgentContext?: boolean
536
- kaizenEnabled?: boolean
537
- delegateAgentsToRunnerPool?: boolean
538
- delegateTestEnvToProvider?: boolean
539
- spendCurrency?: string | null
540
- spendMonthlyLimit?: number | null
541
- }
542
-
543
- /**
544
- * A workspace's default service-fragment selection: the best-practice fragment ids
545
- * new services inherit onto their `serviceFragmentIds`. Mirrors `@cat-factory/contracts`.
546
- */
547
- export interface ServiceFragmentDefaults {
548
- fragmentIds: string[]
549
- }
550
-
551
- /** Lifecycle of a Kaizen grading. Mirrors `@cat-factory/contracts`. */
552
- export type KaizenGradingStatus = 'scheduled' | 'running' | 'complete' | 'failed'
553
-
554
- /**
555
- * A Kaizen grading of one completed agent step (how smooth/efficient the interaction
556
- * was, 1..5, plus recommendations). Mirrors `@cat-factory/contracts`.
557
- */
558
- export interface KaizenGrading {
559
- id: string
560
- executionId: string
561
- blockId: string
562
- stepIndex: number
563
- agentKind: string
564
- model: string
565
- promptVersion: number
566
- comboKey: string
567
- status: KaizenGradingStatus
568
- grade: number | null
569
- summary: string
570
- recommendations: string[]
571
- graderModel: string | null
572
- error: string | null
573
- createdAt: number
574
- updatedAt: number
575
- }
576
-
577
- /** A `(promptVersion, agentKind, model)` combo's verification progress. */
578
- export interface KaizenVerifiedCombo {
579
- comboKey: string
580
- agentKind: string
581
- model: string
582
- promptVersion: number
583
- consecutiveHighGrades: number
584
- verified: boolean
585
- verifiedAt: number | null
586
- updatedAt: number
587
- }
588
-
589
- /** The Kaizen screen payload: recent grading history + the verified-combo library. */
590
- export interface KaizenOverview {
591
- gradings: KaizenGrading[]
592
- verified: KaizenVerifiedCombo[]
593
- }
594
-
595
- /**
596
- * Real-time events pushed over the workspace WebSocket stream (see
597
- * `useWorkspaceStream`). Mirrors `WorkspaceEvent` in `@cat-factory/contracts`.
598
- */
599
- export type WorkspaceEvent =
600
- | { type: 'execution'; instance: ExecutionInstance; block: Block | null; at: number }
601
- | { type: 'board'; reason: string; at: number }
602
- | { type: 'bootstrap'; job: BootstrapJob; block: Block | null; at: number }
603
- | { type: 'notification'; notification: Notification; at: number }
604
- | { type: 'llmCall'; call: LlmCallActivity; at: number }
605
- | { type: 'requirements'; review: RequirementReview; at: number }
606
- | { type: 'consensus'; session: ConsensusSession; at: number }
607
- | { type: 'clarity'; review: ClarityReview; at: number }
608
- | { type: 'brainstorm'; session: BrainstormSession; at: number }
609
- | { type: 'kaizen'; grading: KaizenGrading; at: number }
610
-
611
75
  /** Level-of-detail buckets driven by the canvas zoom level. Shallow → deep:
612
76
  * `far`/`mid`/`close` govern a service frame (chip → card → opened with tasks);
613
77
  * `steps`/`subtasks` drill spatially into an individual task — revealing its
614
- * build-pipeline steps, then each step's live todo breakdown. */
78
+ * build-pipeline steps, then each step's live todo breakdown. Frontend-only. */
615
79
  export type LodLevel = 'far' | 'mid' | 'close' | 'steps' | 'subtasks'
616
80
 
617
- /** The signed-in GitHub user, as returned by the backend's /auth/me. */
81
+ /**
82
+ * The signed-in user, as returned by the backend's /auth/me. The backend's
83
+ * session-user id is an internal `usr_*` string (NOT the GitHub numeric id).
84
+ */
618
85
  export interface AuthUser {
619
- /** GitHub user id (stable across renames). */
620
- id: number
86
+ /** Internal user id (`usr_*`). */
87
+ id: string
621
88
  login: string
622
89
  name: string | null
623
90
  avatarUrl: string | null
91
+ email?: string | null
624
92
  }
625
93
 
626
94
  // Re-export the adjacent domain modules so `~/types/domain` remains the single