@cat-factory/app 0.36.0 → 0.37.0

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 (82) 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/pages/index.vue +2 -0
  40. package/app/stores/auth.ts +2 -1
  41. package/app/stores/board.ts +2 -1
  42. package/app/stores/brainstorm.ts +2 -2
  43. package/app/stores/clarity.ts +6 -2
  44. package/app/stores/execution.ts +3 -2
  45. package/app/stores/github.ts +1 -2
  46. package/app/stores/mergePresets.ts +2 -6
  47. package/app/stores/pipelines.ts +1 -1
  48. package/app/stores/recurringPipelines.ts +2 -7
  49. package/app/stores/sandbox.ts +1 -2
  50. package/app/stores/ui.ts +62 -19
  51. package/app/types/accountSettings.ts +11 -36
  52. package/app/types/accounts.ts +16 -71
  53. package/app/types/bootstrap.ts +13 -75
  54. package/app/types/brainstorm.ts +13 -38
  55. package/app/types/clarity.ts +12 -43
  56. package/app/types/consensus.ts +16 -89
  57. package/app/types/documents.ts +19 -94
  58. package/app/types/domain.ts +54 -586
  59. package/app/types/execution.ts +48 -515
  60. package/app/types/fragments.ts +15 -83
  61. package/app/types/github.ts +25 -161
  62. package/app/types/incidentEnrichment.ts +10 -25
  63. package/app/types/localModels.ts +11 -61
  64. package/app/types/localSettings.ts +9 -26
  65. package/app/types/merge.ts +10 -68
  66. package/app/types/model-presets.ts +7 -28
  67. package/app/types/models.ts +16 -164
  68. package/app/types/notifications.ts +18 -77
  69. package/app/types/openrouter.ts +8 -34
  70. package/app/types/providerConnections.ts +21 -41
  71. package/app/types/provisioningLogs.ts +9 -29
  72. package/app/types/recurring.ts +10 -63
  73. package/app/types/releaseHealth.ts +15 -39
  74. package/app/types/requirements.ts +14 -84
  75. package/app/types/sandbox.ts +45 -161
  76. package/app/types/services.ts +3 -22
  77. package/app/types/slack.ts +10 -47
  78. package/app/types/spec.ts +15 -68
  79. package/app/types/tasks.ts +15 -111
  80. package/app/types/tracker.ts +9 -24
  81. package/app/types/userSecrets.ts +12 -47
  82. package/package.json +9 -2
@@ -1,147 +1,55 @@
1
- // Sandbox (the parallel prompt/model testing surface) wire shapes, hand-mirrored from
2
- // `@cat-factory/contracts` (sandbox.ts) so a backend payload drops straight into the
3
- // store. Clone a shipped agent prompt into a versioned candidate, run an experiment
4
- // matrix (prompt versions × models × fixtures) for one agent kind, and grade every cell
5
- // with a judge model plus (where a fixture supports it) an objective findings score.
6
-
7
- export type SandboxPromptOrigin = 'baseline' | 'candidate'
8
-
9
- export interface SandboxPromptVersion {
10
- id: string
11
- lineageId: string
12
- agentKind: string
13
- name: string
14
- origin: SandboxPromptOrigin
15
- systemText: string
16
- basePromptId: string | null
17
- version: number
18
- parentId: string | null
19
- labels: string[]
20
- createdAt: number
21
- createdBy: string | null
22
- archivedAt: number | null
23
- }
24
-
25
- export type SandboxFixtureKind =
26
- | 'requirements'
27
- | 'clarity'
28
- | 'architecture'
29
- | 'code-review'
30
- | 'repo-feature'
31
- | 'repo-bug'
32
-
33
- export interface SandboxExpectation {
34
- id: string
35
- summary: string
36
- detail: string
37
- trickiness: number
38
- impact: number
39
- matchHints: string[]
40
- }
41
-
42
- export type SandboxFixtureObjective =
43
- | { kind: 'tests'; testCmd: string }
44
- | { kind: 'findings'; expectations: SandboxExpectation[] }
45
-
46
- export interface SandboxFixture {
47
- id: string
48
- kind: SandboxFixtureKind
49
- name: string
50
- payload: Record<string, unknown> | null
51
- repoRef: { owner: string; name: string; seedRef: string } | null
52
- objective: SandboxFixtureObjective | null
53
- origin: 'builtin' | 'custom'
54
- createdAt: number
55
- }
56
-
57
- export type SandboxExperimentStatus = 'draft' | 'running' | 'done' | 'failed'
58
-
59
- export interface SandboxMatrix {
60
- promptVersionIds: string[]
61
- models: string[]
62
- fixtureIds: string[]
63
- }
64
-
65
- export interface SandboxExperiment {
66
- id: string
67
- name: string
68
- agentKind: string
69
- judgeModel: string
70
- repeats: number
71
- status: SandboxExperimentStatus
72
- matrix: SandboxMatrix
73
- budgetTokens: number | null
74
- createdAt: number
75
- createdBy: string | null
76
- }
77
-
78
- export type SandboxRunStatus = 'queued' | 'running' | 'done' | 'failed'
79
-
80
- export interface SandboxTokenUsage {
81
- inputTokens: number
82
- outputTokens: number
83
- }
84
-
85
- export interface SandboxRun {
86
- id: string
87
- experimentId: string
88
- promptVersionId: string
89
- model: string
90
- fixtureId: string
91
- repeatIndex: number
92
- status: SandboxRunStatus
93
- outputText: string | null
94
- usage: SandboxTokenUsage | null
95
- latencyMs: number | null
96
- branch: string | null
97
- prUrl: string | null
98
- diff: string | null
99
- error: string | null
100
- seedSha: string | null
101
- promptLabel: string
102
- startedAt: number | null
103
- finishedAt: number | null
104
- }
105
-
106
- export interface SandboxGradeDimension {
107
- key: string
108
- score: number
109
- rationale: string
110
- }
111
-
112
- export interface SandboxObjectiveResult {
113
- kind: 'tests' | 'findings'
114
- pass: boolean
115
- detail: string
116
- impactRecall: number | null
117
- wowBonus: number | null
118
- caught: number | null
119
- total: number | null
120
- missedHighImpact: string[] | null
121
- }
122
-
123
- export interface SandboxGrade {
124
- id: string
125
- runId: string
126
- judgeModel: string
127
- scores: SandboxGradeDimension[]
128
- weightedTotal: number
129
- objective: SandboxObjectiveResult | null
130
- createdAt: number
131
- }
132
-
133
- /** The Sandbox catalog entry for a testable agent kind (from the overview). */
1
+ // Sandbox (the parallel prompt/model testing surface) wire shapes. Clone a shipped
2
+ // agent prompt into a versioned candidate, run an experiment matrix (prompt versions ×
3
+ // models × fixtures) for one agent kind, and grade every cell with a judge model plus
4
+ // (where a fixture supports it) an objective findings score.
5
+ //
6
+ // All wire shapes are sourced from @cat-factory/contracts (single source of truth).
7
+ // The overview / agent-kind-meta / experiment-detail composites have no exported
8
+ // contract type (the routes model them inline), so they stay frontend-only below —
9
+ // and follow the contract's looser `string` for `bucket`/`rubric`.
10
+
11
+ export type {
12
+ SandboxPromptOrigin,
13
+ SandboxPromptVersion,
14
+ SandboxFixtureKind,
15
+ SandboxExpectation,
16
+ SandboxFixtureObjective,
17
+ SandboxFixture,
18
+ SandboxExperimentStatus,
19
+ SandboxMatrix,
20
+ SandboxExperiment,
21
+ SandboxRunStatus,
22
+ SandboxTokenUsage,
23
+ SandboxRun,
24
+ SandboxGradeDimension,
25
+ SandboxObjectiveResult,
26
+ SandboxGrade,
27
+ CloneSandboxPromptInput,
28
+ SaveSandboxVersionInput,
29
+ CreateSandboxExperimentInput,
30
+ } from '@cat-factory/contracts'
31
+
32
+ import type {
33
+ SandboxExperiment,
34
+ SandboxFixture,
35
+ SandboxFixtureKind,
36
+ SandboxGrade,
37
+ SandboxPromptVersion,
38
+ SandboxRun,
39
+ } from '@cat-factory/contracts'
40
+
41
+ /** The Sandbox catalog entry for a testable agent kind (from the overview). Frontend-only. */
134
42
  export interface SandboxAgentKindMeta {
135
43
  agentKind: string
136
44
  label: string
137
- bucket: 'inline' | 'container'
138
- rubric: 'requirement-review' | 'code-review' | 'implementation'
45
+ bucket: string
46
+ rubric: string
139
47
  /** Fixture kinds this agent is exercised against (the UI filters the library by these). */
140
48
  fixtureKinds: SandboxFixtureKind[]
141
49
  basePromptId: string | null
142
50
  }
143
51
 
144
- /** The composite the management surface loads on open (`GET /sandbox/overview`). */
52
+ /** The composite the management surface loads on open (`GET /sandbox/overview`). Frontend-only. */
145
53
  export interface SandboxOverview {
146
54
  agentKinds: SandboxAgentKindMeta[]
147
55
  prompts: SandboxPromptVersion[]
@@ -151,33 +59,9 @@ export interface SandboxOverview {
151
59
  maxCells: number
152
60
  }
153
61
 
154
- /** An experiment with its result grid (`GET /sandbox/experiments/:id`, also from launch). */
62
+ /** An experiment with its result grid (`GET /sandbox/experiments/:id`, also from launch). Frontend-only. */
155
63
  export interface SandboxExperimentDetail {
156
64
  experiment: SandboxExperiment
157
65
  runs: SandboxRun[]
158
66
  grades: SandboxGrade[]
159
67
  }
160
-
161
- // ---- request bodies --------------------------------------------------------
162
-
163
- export interface CloneSandboxPromptInput {
164
- agentKind: string
165
- basePromptId: string | null
166
- name?: string
167
- labels?: string[]
168
- }
169
-
170
- export interface SaveSandboxVersionInput {
171
- parentId: string
172
- systemText: string
173
- labels?: string[]
174
- }
175
-
176
- export interface CreateSandboxExperimentInput {
177
- name: string
178
- agentKind: string
179
- matrix: SandboxMatrix
180
- judgeModel?: string
181
- repeats?: number
182
- budgetTokens?: number | null
183
- }
@@ -2,26 +2,7 @@
2
2
  // a `Service` is the account-owned unit of work (a service frame + its subtree + repo),
3
3
  // shared across the workspaces that *mount* it; a `WorkspaceMount` places a service onto a
4
4
  // workspace board with that board's own frame layout override.
5
+ //
6
+ // All wire shapes are sourced from @cat-factory/contracts (single source of truth).
5
7
 
6
- export interface Service {
7
- id: string
8
- accountId: string | null
9
- frameBlockId: string
10
- installationId: number | null
11
- repoGithubId: number | null
12
- /** Subdirectory within the linked monorepo this service lives in (null = whole repo). */
13
- directory?: string | null
14
- createdAt: number
15
- /** How many boards mount this service. Set only on the org catalog (for the "Shared" badge). */
16
- mountCount?: number
17
- }
18
-
19
- export interface WorkspaceMount {
20
- workspaceId: string
21
- serviceId: string
22
- /** This board's frame position override. */
23
- position: { x: number; y: number }
24
- /** This board's dragged frame size; null/absent = auto-size. */
25
- size?: { w: number; h: number } | null
26
- createdAt: number
27
- }
8
+ export type { Service, WorkspaceMount } from '@cat-factory/contracts'
@@ -7,51 +7,14 @@
7
7
  // Two scopes: the connection (+ bot token, never sent here) is per-account; the
8
8
  // notification routing is per-workspace; the @-mention member map is per-account.
9
9
  // ---------------------------------------------------------------------------
10
+ //
11
+ // All wire shapes are sourced from @cat-factory/contracts (single source of truth).
10
12
 
11
- import type { NotificationType } from './notifications'
12
-
13
- /** An account's Slack connection, as exposed to clients — safe metadata only. */
14
- export interface SlackConnection {
15
- teamId: string
16
- teamName: string
17
- teamIconUrl?: string | null
18
- botUserId?: string | null
19
- scopes?: string[]
20
- connectedAt: number
21
- }
22
-
23
- /** Routing for a single notification type: whether it posts, and where. */
24
- export interface SlackRoute {
25
- enabled: boolean
26
- /** A channel id (`C0123…`) or name (`#general`); empty = unrouted. */
27
- channel: string
28
- }
29
-
30
- /** A workspace's Slack notification routing. */
31
- export interface SlackNotificationSettings {
32
- routes: Partial<Record<NotificationType, SlackRoute>>
33
- mentionsEnabled: boolean
34
- updatedAt: number
35
- }
36
-
37
- /** One internal user id → Slack member id mapping entry. */
38
- export type SlackMemberRole = 'product' | 'engineering'
39
-
40
- export interface SlackMemberMappingEntry {
41
- /** Internal user id (`usr_*`) — the same id the member roster shows. */
42
- userId: string
43
- slackUserId: string
44
- /**
45
- * Notification role: `product` people are @-mentioned on requirement-review
46
- * findings; everyone else (`engineering`) only when they created the task.
47
- * Absent means `engineering`.
48
- */
49
- role?: SlackMemberRole
50
- }
51
-
52
- /** A Slack channel option for the routing picker. */
53
- export interface SlackChannel {
54
- id: string
55
- name: string
56
- isPrivate: boolean
57
- }
13
+ export type {
14
+ SlackConnection,
15
+ SlackRoute,
16
+ SlackNotificationSettings,
17
+ SlackMemberRole,
18
+ SlackMemberMappingEntry,
19
+ SlackChannel,
20
+ } from '@cat-factory/contracts'
package/app/types/spec.ts CHANGED
@@ -4,71 +4,18 @@
4
4
  // sharded in the service repo under `spec/`; the backend reassembles it from the repo's
5
5
  // default branch and serves it as `ServiceSpecView` for the inspector's "View
6
6
  // Requirements" window.
7
-
8
- export type RequirementPriority = 'must' | 'should' | 'could'
9
- export type RequirementKind = 'functional' | 'nonfunctional' | 'constraint'
10
-
11
- /** One acceptance criterion in Given/When/Then form — the seed for a Gherkin scenario. */
12
- export interface AcceptanceCriterion {
13
- id: string
14
- given: string
15
- when: string
16
- /** The Gherkin "Then" clause (named `outcome` so the object is never thenable). */
17
- outcome: string
18
- }
19
-
20
- /** A single prescriptive requirement, traceable to the board task(s) it came from. */
21
- export interface RequirementItem {
22
- id: string
23
- title: string
24
- statement: string
25
- kind: RequirementKind
26
- priority: RequirementPriority
27
- sourceBlockIds?: string[]
28
- acceptance?: AcceptanceCriterion[]
29
- }
30
-
31
- /** A domain rule / invariant scoped to the feature group it governs. */
32
- export interface DomainRule {
33
- id: string
34
- rule: string
35
- rationale?: string
36
- sourceBlockIds?: string[]
37
- }
38
-
39
- /** A feature / logical group: related requirements plus the domain rules scoped to them. */
40
- export interface RequirementGroup {
41
- name: string
42
- summary?: string
43
- requirements?: RequirementItem[]
44
- rules?: DomainRule[]
45
- }
46
-
47
- /** A module (domain) — the top level of the taxonomy, holding feature groups. */
48
- export interface SpecModule {
49
- name: string
50
- summary?: string
51
- groups?: RequirementGroup[]
52
- }
53
-
54
- /** The unified prescriptive specification document for one service. */
55
- export interface SpecDoc {
56
- service: string
57
- summary?: string
58
- modules?: SpecModule[]
59
- }
60
-
61
- /** A rendered Gherkin feature file read back from the repo. */
62
- export interface SpecFeatureFile {
63
- module: string
64
- group: string
65
- path: string
66
- content: string
67
- }
68
-
69
- /** The service-spec view: the reassembled tree + its Gherkin files (empty when none). */
70
- export interface ServiceSpecView {
71
- present: boolean
72
- spec: SpecDoc | null
73
- features: SpecFeatureFile[]
74
- }
7
+ //
8
+ // All wire shapes are sourced from @cat-factory/contracts (single source of truth).
9
+
10
+ export type {
11
+ RequirementPriority,
12
+ RequirementKind,
13
+ AcceptanceCriterion,
14
+ RequirementItem,
15
+ DomainRule,
16
+ RequirementGroup,
17
+ SpecModule,
18
+ SpecDoc,
19
+ SpecFeatureFile,
20
+ ServiceSpecView,
21
+ } from '@cat-factory/contracts'
@@ -5,114 +5,18 @@
5
5
  // source-agnostic, keyed by `source`. Unlike document sources there is no
6
6
  // plan/spawn — an issue is linked for context, never expanded into structure.
7
7
  // ---------------------------------------------------------------------------
8
-
9
- import type { CredentialField } from './documents'
10
-
11
- /** The external task trackers cat-factory can link to. */
12
- export type TaskSourceKind = 'jira' | 'github'
13
-
14
- export type { CredentialField }
15
-
16
- /** A source's self-description: drives the generic connect + import UI. */
17
- export interface TaskSourceDescriptor {
18
- source: TaskSourceKind
19
- label: string
20
- /** Lucide icon name for the source. */
21
- icon: string
22
- credentialFields: CredentialField[]
23
- refLabel: string
24
- refPlaceholder: string
25
- /** Whether the source supports searching its catalogue by title/content. */
26
- searchable?: boolean
27
- }
28
-
29
- /**
30
- * A source's descriptor plus the workspace's live state: whether it's usable now
31
- * (`available` — a credentialed source is connected; GitHub Issues' App is
32
- * installed) and whether the workspace offers it (`enabled`, the per-workspace
33
- * toggle, default true). `available && enabled` is what makes a source offered.
34
- */
35
- export interface TaskSourceState extends TaskSourceDescriptor {
36
- available: boolean
37
- enabled: boolean
38
- }
39
-
40
- /**
41
- * The verdict of a live "check setup" probe against a source (mirrors
42
- * `@cat-factory/contracts`). Unlike `available` (a passive row-exists flag) this
43
- * is the result of actually authenticating + reading, so it distinguishes a
44
- * configured-but-broken source from a working one.
45
- */
46
- export type TaskSourceDiagnosticStatus =
47
- | 'ready'
48
- | 'not_installed'
49
- | 'not_connected'
50
- | 'auth_failed'
51
- | 'forbidden'
52
- | 'unreachable'
53
- | 'error'
54
-
55
- export interface TaskSourceDiagnostic {
56
- source: TaskSourceKind
57
- ok: boolean
58
- status: TaskSourceDiagnosticStatus
59
- /** A one-line, actionable explanation shown verbatim in the panel. */
60
- message: string
61
- /** Optional extra context (account login, repo count, signed-in user). */
62
- detail?: string | null
63
- }
64
-
65
- /** A workspace's connection to a task source (never carries credentials). */
66
- export interface TaskConnection {
67
- source: TaskSourceKind
68
- /** Human-friendly label for what we're connected to (site URL). */
69
- label: string
70
- /** When the connection was established (epoch ms). */
71
- connectedAt: number
72
- }
73
-
74
- /** A single comment on an issue, with its body as lightweight Markdown. */
75
- export interface TaskComment {
76
- author: string
77
- createdAt: string
78
- body: string
79
- }
80
-
81
- /** An issue imported from a source into the workspace, as a structured record. */
82
- export interface SourceTask {
83
- source: TaskSourceKind
84
- /** The source's canonical key for the issue (e.g. `PROJ-123`). */
85
- externalId: string
86
- title: string
87
- url: string
88
- /** Workflow status name, e.g. `In Progress`. */
89
- status: string
90
- /** Issue type name, e.g. `Bug`. */
91
- type: string
92
- /** Assignee display name, or null when unassigned. */
93
- assignee: string | null
94
- /** Priority name, or null when none. */
95
- priority: string | null
96
- labels: string[]
97
- /** Issue description as lightweight Markdown. */
98
- description: string
99
- comments: TaskComment[]
100
- /** Short plain-text preview of the issue. */
101
- excerpt: string
102
- /** The board block this issue is attached to as context, if any. */
103
- linkedBlockId: string | null
104
- syncedAt: number
105
- }
106
-
107
- /** A lean hit from searching a tracker's issues (not yet imported). */
108
- export interface TaskSearchResult {
109
- source: TaskSourceKind
110
- /** The source's canonical key for the issue (re-usable as an import ref). */
111
- externalId: string
112
- title: string
113
- url: string
114
- /** Workflow status name, e.g. `In Progress` (may be empty). */
115
- status: string
116
- /** Short plain-text preview (may be empty). */
117
- excerpt: string
118
- }
8
+ //
9
+ // All wire shapes are sourced from @cat-factory/contracts (single source of truth).
10
+
11
+ export type {
12
+ TaskSourceKind,
13
+ TaskSourceDescriptor,
14
+ TaskSourceState,
15
+ TaskSourceDiagnosticStatus,
16
+ TaskSourceDiagnostic,
17
+ TaskConnection,
18
+ TaskComment,
19
+ SourceTask,
20
+ TaskSearchResult,
21
+ CredentialField,
22
+ } from '@cat-factory/contracts'
@@ -1,27 +1,12 @@
1
1
  // Issue-tracker selection shapes, mirroring `@cat-factory/contracts` (tracker.ts).
2
2
  // A workspace designates one tracker — GitHub Issues or Jira — where the tech-debt
3
3
  // recurring pipeline files its ticket before implementation starts.
4
-
5
- export type TrackerKind = 'github' | 'jira'
6
-
7
- export interface TrackerSettings {
8
- /** The selected tracker, or null when none is configured. */
9
- tracker: TrackerKind | null
10
- /** Jira project key new tickets are filed under (e.g. 'ENG'); null unless Jira. */
11
- jiraProjectKey: string | null
12
- /** Writeback: comment on a task's linked issue when its PR opens. Per-task overridable. */
13
- writebackCommentOnPrOpen: boolean
14
- /** Writeback: comment + close a task's linked issue as resolved when its PR merges. */
15
- writebackResolveOnMerge: boolean
16
- updatedAt: number
17
- }
18
-
19
- export interface PutTrackerSettingsInput {
20
- tracker: TrackerKind | null
21
- jiraProjectKey?: string | null
22
- writebackCommentOnPrOpen?: boolean
23
- writebackResolveOnMerge?: boolean
24
- }
25
-
26
- /** Per-task writeback override; absent ⇒ inherit the workspace setting. */
27
- export type WritebackOverride = 'on' | 'off'
4
+ //
5
+ // All wire shapes are sourced from @cat-factory/contracts (single source of truth).
6
+
7
+ export type {
8
+ TrackerKind,
9
+ TrackerSettings,
10
+ PutTrackerSettingsInput,
11
+ WritebackOverride,
12
+ } from '@cat-factory/contracts'
@@ -1,49 +1,14 @@
1
1
  // Frontend mirrors of the per-user secret + provider-config wire contracts
2
2
  // (`@cat-factory/contracts` user-secret.ts + provider-config.ts).
3
-
4
- export type UserSecretKind = 'github_pat'
5
-
6
- /** One config value a kind needs, rendered as a single form field. */
7
- export interface ProviderConfigField {
8
- key: string
9
- label: string
10
- help?: string
11
- placeholder?: string
12
- secret?: boolean
13
- required?: boolean
14
- type?: 'text' | 'password' | 'select'
15
- options?: { value: string; label: string }[]
16
- }
17
-
18
- /** Read-only status of one stored per-user secret — never the secret value. */
19
- export interface UserSecretStatus {
20
- kind: UserSecretKind
21
- label: string
22
- hasSecret: boolean
23
- metadata?: Record<string, string>
24
- connectedAt: number
25
- }
26
-
27
- /** A kind's self-description for the generic connect form. */
28
- export interface UserSecretDescriptor {
29
- kind: UserSecretKind
30
- label: string
31
- configFields: ProviderConfigField[]
32
- supportsTest: boolean
33
- }
34
-
35
- export interface StoreUserSecretInput {
36
- label?: string
37
- secret: string
38
- metadata?: Record<string, string>
39
- }
40
-
41
- export interface TestUserSecretInput {
42
- secret: string
43
- metadata?: Record<string, string>
44
- }
45
-
46
- export interface ConnectionTestResult {
47
- ok: boolean
48
- message?: string
49
- }
3
+ //
4
+ // All wire shapes are sourced from @cat-factory/contracts (single source of truth).
5
+
6
+ export type {
7
+ UserSecretKind,
8
+ ProviderConfigField,
9
+ UserSecretStatus,
10
+ UserSecretDescriptor,
11
+ StoreUserSecretInput,
12
+ TestUserSecretInput,
13
+ ConnectionTestResult,
14
+ } from '@cat-factory/contracts'
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cat-factory/app",
3
- "version": "0.36.0",
3
+ "version": "0.37.0",
4
4
  "description": "Reusable Nuxt layer for the Agent Architecture Board SPA (components, stores, composables, pages). Consume it from a thin deployment app via `extends: ['@cat-factory/app']` and point it at your backend with NUXT_PUBLIC_API_BASE. See deploy/frontend for an example.",
5
5
  "repository": {
6
6
  "type": "git",
@@ -19,6 +19,9 @@
19
19
  "dependencies": {
20
20
  "@nuxt/ui": "^4.9.0",
21
21
  "@pinia/nuxt": "^0.11.3",
22
+ "@toad-contracts/core": "0.3.1",
23
+ "@toad-contracts/frontend-http-client": "0.3.1",
24
+ "@toad-contracts/valibot": "0.3.1",
22
25
  "@vue-flow/background": "^1.3.2",
23
26
  "@vue-flow/core": "^1.48.2",
24
27
  "@vue-flow/minimap": "^1.5.4",
@@ -27,11 +30,15 @@
27
30
  "markdown-it": "^14.2.0",
28
31
  "pinia": "^3.0.4",
29
32
  "pinia-plugin-persistedstate": "^4.7.1",
30
- "vue": "^3.5.38"
33
+ "vue": "^3.5.38",
34
+ "wretch": "^3.0.9",
35
+ "@cat-factory/contracts": "0.35.0"
31
36
  },
32
37
  "devDependencies": {
38
+ "@toad-contracts/testing": "0.3.1",
33
39
  "@types/markdown-it": "^14.1.2",
34
40
  "happy-dom": "^20.10.6",
41
+ "msw": "^2.6.0",
35
42
  "nuxt": "^4.4.8",
36
43
  "typescript": "^6.0.3",
37
44
  "vitest": "^4.1.9",