@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,77 +1,18 @@
1
- // Notification shapes, mirroring `@cat-factory/contracts` (notifications.ts). A
2
- // notification is a first-class, human-actionable item surfaced on the board that
3
- // outlives the run that raised it (a PR awaiting a merge decision, a completed
4
- // pipeline awaiting confirmation, CI that gave up).
5
-
6
- import type { MergeAssessment } from './merge'
7
-
8
- export type NotificationType =
9
- | 'merge_review'
10
- | 'pipeline_complete'
11
- | 'ci_failed'
12
- | 'test_failed'
13
- | 'requirement_review'
14
- | 'clarity_review'
15
- | 'release_regression'
16
- | 'decision_required'
17
- | 'human_test_ready'
18
- | 'human_review'
19
- | 'followup_pending'
20
- export type NotificationStatus = 'open' | 'acted' | 'dismissed'
21
-
22
- /** The on-call agent's recommendation on a `release_regression`. */
23
- export type OnCallRecommendation = 'revert' | 'hold' | 'monitor'
24
-
25
- /** The on-call agent's assessment of a post-release regression. */
26
- export interface OnCallAssessment {
27
- culpritConfidence: number
28
- recommendation: OnCallRecommendation
29
- rationale: string
30
- evidence?: string[]
31
- }
32
-
33
- /** A regressed monitor/SLO on a `release_regression`. */
34
- export interface ReleaseSignal {
35
- kind: 'monitor' | 'slo'
36
- id: string
37
- name: string
38
- state: 'ok' | 'warn' | 'alert' | 'no_data'
39
- detail?: string
40
- }
41
-
42
- /** Optional structured detail for rendering a notification card. */
43
- export interface NotificationPayload {
44
- assessment?: MergeAssessment
45
- prUrl?: string
46
- pipelineName?: string
47
- findingCount?: number
48
- /** The on-call assessment, on a `release_regression`. */
49
- onCallAssessment?: OnCallAssessment
50
- /** The regressed monitors/SLOs, on a `release_regression`. */
51
- releaseSignals?: ReleaseSignal[]
52
- /** A proposed revert PR URL, when known. */
53
- revertUrl?: string
54
- }
55
-
56
- /** A human-actionable item surfaced on the board. */
57
- /**
58
- * Render urgency. A notification starts `normal` (the inbox's usual per-type colour) and
59
- * is escalated to `urgent` (red) by the backend's sweep once it has waited for a human
60
- * past the workspace's `waitingEscalationMinutes` threshold. Absent ⇒ `normal`.
61
- */
62
- export type NotificationSeverity = 'normal' | 'urgent'
63
-
64
- export interface Notification {
65
- id: string
66
- type: NotificationType
67
- status: NotificationStatus
68
- /** Render urgency (yellow vs red); escalated by the backend sweep. Absent ⇒ normal. */
69
- severity?: NotificationSeverity
70
- blockId: string | null
71
- executionId: string | null
72
- title: string
73
- body: string
74
- payload?: NotificationPayload | null
75
- createdAt: number
76
- resolvedAt: number | null
77
- }
1
+ // Notification shapes. A notification is a first-class, human-actionable item
2
+ // surfaced on the board that outlives the run that raised it (a PR awaiting a
3
+ // merge decision, a completed pipeline awaiting confirmation, CI that gave up).
4
+ //
5
+ // All wire shapes are sourced from @cat-factory/contracts (single source of
6
+ // truth). The historical frontend name `ReleaseSignal` is the contract's
7
+ // `ReleaseSignalWire`.
8
+
9
+ export type {
10
+ NotificationType,
11
+ NotificationStatus,
12
+ OnCallRecommendation,
13
+ OnCallAssessment,
14
+ NotificationPayload,
15
+ NotificationSeverity,
16
+ Notification,
17
+ ReleaseSignalWire as ReleaseSignal,
18
+ } from '@cat-factory/contracts'
@@ -8,38 +8,12 @@
8
8
  // Mirrors the `@cat-factory/contracts` `openrouter` schemas exactly, so a payload
9
9
  // returned by the backend drops straight into the Pinia store without translation.
10
10
  // ---------------------------------------------------------------------------
11
+ //
12
+ // All wire shapes are sourced from @cat-factory/contracts (single source of truth).
11
13
 
12
- /** Metadata for one OpenRouter model (prices per 1M tokens, in the spend currency). */
13
- export interface OpenRouterModelMeta {
14
- /** OpenRouter `vendor/model` slug, e.g. `anthropic/claude-opus-4.8`. */
15
- id: string
16
- /** Human-readable model name from OpenRouter's catalog. */
17
- name: string
18
- /** Total context window (input + output tokens), when reported. */
19
- contextLength?: number
20
- /** Input price per 1M tokens, in the spend currency. */
21
- inputPerMillion: number
22
- /** Output price per 1M tokens, in the spend currency. */
23
- outputPerMillion: number
24
- }
25
-
26
- /** A workspace's enabled OpenRouter models (the persisted subset). */
27
- export interface OpenRouterCatalog {
28
- models: OpenRouterModelMeta[]
29
- createdAt: number
30
- updatedAt: number
31
- }
32
-
33
- /** Replace a workspace's enabled OpenRouter models with this subset (+ metadata). */
34
- export interface UpsertOpenRouterCatalogInput {
35
- models: OpenRouterModelMeta[]
36
- }
37
-
38
- /** The result of probing OpenRouter's live `/models` for the browse list. */
39
- export interface OpenRouterRefreshResult {
40
- reachable: boolean
41
- /** Every model OpenRouter currently serves (empty when unreachable). */
42
- models: OpenRouterModelMeta[]
43
- /** Human-readable failure reason when `reachable` is false. */
44
- error?: string
45
- }
14
+ export type {
15
+ OpenRouterModelMeta,
16
+ OpenRouterCatalog,
17
+ UpsertOpenRouterCatalogInput,
18
+ OpenRouterRefreshResult,
19
+ } from '@cat-factory/contracts'
@@ -1,44 +1,22 @@
1
- // Frontend mirrors of the shared provider self-description + connection wire contracts
2
- // (`@cat-factory/contracts` provider-config.ts + environments.ts + runners.ts), used by
3
- // the generic connect form for the two infrastructure providers: the ephemeral-environment
4
- // provider and the self-hosted runner pool. Both speak the same ProviderDescriptor.
1
+ // Provider self-description + connection wire contracts for the generic connect form
2
+ // used by the two infrastructure providers: the ephemeral-environment provider and the
3
+ // self-hosted runner pool. Both speak the same ProviderDescriptor.
4
+ //
5
+ // The shared shapes are sourced from @cat-factory/contracts (single source of truth).
6
+ // The register/test request bodies are the union of the two per-kind contract inputs
7
+ // (the composable picks the right contract per kind). `ProviderConnectionKind` and the
8
+ // generic `ProviderConnection` view have no exported contract type, so they stay
9
+ // frontend-only below.
10
+
11
+ export type {
12
+ ProviderConfigField,
13
+ ProviderDescriptor,
14
+ ConnectionTestResult,
15
+ } from '@cat-factory/contracts'
5
16
 
6
17
  /** The two infrastructure providers configured through the generic connect form. */
7
18
  export type ProviderConnectionKind = 'environment' | 'runner-pool'
8
19
 
9
- /** One config value a provider needs, rendered as a single form field. */
10
- export interface ProviderConfigField {
11
- key: string
12
- label: string
13
- help?: string
14
- placeholder?: string
15
- secret?: boolean
16
- required?: boolean
17
- type?: 'text' | 'password' | 'select'
18
- options?: { value: string; label: string }[]
19
- /** The provider/manifest default; a field with one is optional (UI shows a hint). */
20
- default?: string
21
- }
22
-
23
- /** What the SPA needs to render a provider's connect form. */
24
- export interface ProviderDescriptor {
25
- providerId: string
26
- label: string
27
- kind: 'native' | 'manifest'
28
- configFields: ProviderConfigField[]
29
- supportsTest: boolean
30
- /** Required-without-default keys not yet supplied (drives the banner). */
31
- missingRequired: string[]
32
- /** Base manifest a native provider's flat fields are overlaid onto before save. */
33
- manifestTemplate?: Record<string, unknown>
34
- /**
35
- * The CURRENT saved manifest (non-secret — only secret-ref key names), present once a
36
- * connection exists. Edits are overlaid onto this (not the bare `manifestTemplate`) so
37
- * re-saving preserves previously-stored providerConfig instead of dropping it.
38
- */
39
- savedManifest?: Record<string, unknown>
40
- }
41
-
42
20
  /** A workspace's provider binding, as exposed to clients (never secret values). */
43
21
  export interface ProviderConnection {
44
22
  providerId: string
@@ -49,10 +27,11 @@ export interface ProviderConnection {
49
27
  secretKeys: string[]
50
28
  }
51
29
 
52
- export interface ConnectionTestResult {
53
- ok: boolean
54
- message?: string
55
- }
30
+ // The connect form builds the manifest dynamically from a server-provided scaffold
31
+ // (`ProviderDescriptor.manifestTemplate`/`savedManifest`) overlaid with form values, so
32
+ // the FE treats it as an opaque JSON bag. The backend re-validates it against the precise
33
+ // per-provider manifest contract on receipt; the composable casts to the contract input
34
+ // type at the single `send` boundary.
56
35
 
57
36
  /** The assembled register payload (a full manifest + the write-only secret bundle). */
58
37
  export interface RegisterProviderInput {
@@ -60,6 +39,7 @@ export interface RegisterProviderInput {
60
39
  secrets: Record<string, string>
61
40
  }
62
41
 
42
+ /** The test/probe payload (manifest-driven or native), shared by both providers. */
63
43
  export interface TestProviderInput {
64
44
  manifest?: Record<string, unknown>
65
45
  config?: Record<string, string>
@@ -1,32 +1,12 @@
1
1
  // Frontend mirror of the unified provisioning event-log wire shapes
2
2
  // (`@cat-factory/contracts` provisioning-logs.ts). Drives the "View logs" drawers in
3
3
  // the environment-provider + runner-pool config panels and the run-details env surface.
4
-
5
- export type ProvisioningSubsystem = 'environment' | 'runner-pool' | 'container'
6
-
7
- export type ProvisioningOperation =
8
- | 'provision'
9
- | 'teardown'
10
- | 'status'
11
- | 'dispatch'
12
- | 'release'
13
- | 'poll-failure'
14
-
15
- export type ProvisioningOutcome = 'success' | 'failure'
16
-
17
- /** One provisioning attempt (spin-up / tear-down), as returned by the logs endpoint. */
18
- export interface ProvisioningLogEntry {
19
- id: string
20
- workspaceId: string
21
- subsystem: ProvisioningSubsystem
22
- operation: ProvisioningOperation
23
- targetId: string | null
24
- providerId: string | null
25
- blockId: string | null
26
- executionId: string | null
27
- outcome: ProvisioningOutcome
28
- /** The verbatim provider/runtime error on a failure, else null. */
29
- error: string | null
30
- detail: string | null
31
- createdAt: number
32
- }
4
+ //
5
+ // All wire shapes are sourced from @cat-factory/contracts (single source of truth).
6
+
7
+ export type {
8
+ ProvisioningSubsystem,
9
+ ProvisioningOperation,
10
+ ProvisioningOutcome,
11
+ ProvisioningLogEntry,
12
+ } from '@cat-factory/contracts'
@@ -3,67 +3,14 @@
3
3
  // run every `intervalHours`, constrained to an optional allowed window (weekdays +
4
4
  // an hour-of-day range, in the schedule's timezone). Each schedule owns one reused
5
5
  // on-board task block; firing it starts the pipeline against that block.
6
+ //
7
+ // All wire shapes are sourced from @cat-factory/contracts (single source of truth).
6
8
 
7
- /** Template a schedule was created from; drives the seeded block description. */
8
- export type ScheduleTemplate = 'dep-update' | 'tech-debt' | 'custom'
9
-
10
- /** How often a schedule fires and when it is allowed to. */
11
- export interface Recurrence {
12
- /** Base cadence in hours (≥1). */
13
- intervalHours: number
14
- /** Allowed weekdays (0=Sun..6=Sat). Empty = every day. */
15
- weekdays: number[]
16
- /** Inclusive start of the allowed hour-of-day window, or null for no lower bound. */
17
- windowStartHour: number | null
18
- /** Exclusive end of the allowed hour-of-day window, or null for no upper bound. */
19
- windowEndHour: number | null
20
- /** IANA timezone the weekday/hour window is evaluated in (e.g. 'UTC'). */
21
- timezone: string
22
- }
23
-
24
- /** A recurring pipeline attached to a service. */
25
- export interface PipelineSchedule {
26
- id: string
27
- /** The reused on-board task block the pipeline runs against. */
28
- blockId: string
29
- /** The service frame it lives in. */
30
- frameId: string
31
- pipelineId: string
32
- template: ScheduleTemplate
33
- name: string
34
- recurrence: Recurrence
35
- enabled: boolean
36
- lastRunAt: number | null
37
- /** Computed epoch-ms of the next eligible fire. */
38
- nextRunAt: number
39
- createdAt: number
40
- }
41
-
42
- /** One historical fire of a schedule (retained ~1 week), shown in the inspector. */
43
- export interface ScheduleRun {
44
- id: string
45
- scheduleId: string
46
- executionId: string | null
47
- status: 'running' | 'done' | 'failed' | 'skipped'
48
- startedAt: number
49
- finishedAt: number | null
50
- outcome: string | null
51
- }
52
-
53
- export interface CreateScheduleInput {
54
- frameId: string
55
- pipelineId: string
56
- template?: ScheduleTemplate
57
- name: string
58
- recurrence: Recurrence
59
- enabled?: boolean
60
- /** The prompt/description for the reused on-board task; empty → the template seed. */
61
- description?: string
62
- }
63
-
64
- export interface UpdateScheduleInput {
65
- name?: string
66
- pipelineId?: string
67
- recurrence?: Recurrence
68
- enabled?: boolean
69
- }
9
+ export type {
10
+ ScheduleTemplate,
11
+ Recurrence,
12
+ PipelineSchedule,
13
+ ScheduleRun,
14
+ CreateScheduleInput,
15
+ UpdateScheduleInput,
16
+ } from '@cat-factory/contracts'
@@ -1,39 +1,15 @@
1
- // Post-release-health (observability) settings shapes, mirroring `@cat-factory/contracts`
2
- // (release.ts). Per-workspace observability connection (provider + credentials, write-only,
3
- // never read back) and the per-block monitor/SLO mappings the post-release-health gate reads.
4
-
5
- /** Observability vendors a workspace can connect (extensible; Datadog today). */
6
- export type ObservabilityProviderKind = 'datadog'
7
-
8
- /** What `GET /observability/connection` returns — never the secret keys. */
9
- export interface ObservabilityConnectionView {
10
- connected: boolean
11
- provider: ObservabilityProviderKind | null
12
- /** Non-secret display fields, e.g. `{ site }` for Datadog. */
13
- summary: Record<string, string> | null
14
- }
15
-
16
- /** Set/replace the workspace's observability connection. */
17
- export interface UpsertObservabilityConnectionInput {
18
- provider: ObservabilityProviderKind
19
- credentials: {
20
- site: string
21
- apiKey: string
22
- appKey: string
23
- }
24
- }
25
-
26
- /** A block's monitor/SLO mapping for the post-release-health gate. */
27
- export interface ReleaseHealthConfig {
28
- blockId: string
29
- monitorIds: string[]
30
- sloIds: string[]
31
- envTag: string | null
32
- }
33
-
34
- /** Create/replace a block's release-health config. */
35
- export interface UpsertReleaseHealthConfigInput {
36
- monitorIds?: string[]
37
- sloIds?: string[]
38
- envTag?: string | null
39
- }
1
+ // Post-release-health (observability) settings shapes. Per-workspace observability
2
+ // connection (provider + credentials, write-only, never read back) and the per-block
3
+ // monitor/SLO mappings the post-release-health gate reads.
4
+ //
5
+ // All wire shapes are sourced from @cat-factory/contracts (single source of truth).
6
+ // The historical frontend name `ReleaseHealthConfig` is the contract's
7
+ // `ReleaseHealthConfigWire`.
8
+
9
+ export type {
10
+ ObservabilityProviderKind,
11
+ ObservabilityConnectionView,
12
+ UpsertObservabilityConnectionInput,
13
+ UpsertReleaseHealthConfigInput,
14
+ ReleaseHealthConfigWire as ReleaseHealthConfig,
15
+ } from '@cat-factory/contracts'
@@ -5,87 +5,17 @@
5
5
  // A stateless reviewer agent inspects a block's collected requirements and
6
6
  // raises questions / gaps / clarifications; a human answers or dismisses each;
7
7
  // then the agent folds the answers back into the block's requirements.
8
-
9
- export type ReviewItemCategory = 'gap' | 'clarification' | 'assumption' | 'risk' | 'question'
10
-
11
- export type ReviewItemSeverity = 'low' | 'medium' | 'high'
12
-
13
- export type ReviewItemStatus =
14
- | 'open'
15
- | 'answered'
16
- | 'resolved'
17
- | 'dismissed'
18
- | 'recommend_requested'
19
-
20
- export interface RequirementReviewItem {
21
- id: string
22
- category: ReviewItemCategory
23
- severity: ReviewItemSeverity
24
- title: string
25
- detail: string
26
- status: ReviewItemStatus
27
- reply: string | null
28
- createdAt: number
29
- updatedAt: number
30
- }
31
-
32
- /**
33
- * - `ready`: the reviewer raised findings awaiting human answers/dismissals.
34
- * - `incorporating`: transient; the driver is folding the answers into a document (the FIRST
35
- * async stage — the user is back on the board).
36
- * - `reviewing`: transient; the reviewer is RE-reviewing the folded document (the SECOND
37
- * async stage). Distinct from `incorporating` so the UI can show which stage is running.
38
- * - `merged`: the companion produced a document (an internal transient on the async path).
39
- * - `exceeded`: the iteration cap was hit with findings open — awaiting the human's choice.
40
- * - `incorporated`: terminal; the requirements phase is settled.
41
- */
42
- export type RequirementReviewStatus =
43
- | 'ready'
44
- | 'incorporating'
45
- | 'reviewing'
46
- | 'merged'
47
- | 'exceeded'
48
- | 'incorporated'
49
-
50
- /** How a human resolves a review that hit its iteration cap. */
51
- export type ResolveRequirementsExceededChoice = 'extra-round' | 'proceed' | 'stop-reset'
52
-
53
- /**
54
- * Lifecycle of a Requirement-Writer recommendation. `pending` is a placeholder created the
55
- * moment the human requests it — the Writer is still producing the suggestion in the background
56
- * (the async story); it fills in to `ready` via the `requirements` stream.
57
- */
58
- export type RecommendationStatus = 'pending' | 'ready' | 'accepted' | 'rejected'
59
-
60
- /**
61
- * A Requirement-Writer suggestion for one finding. First-class on the review (survives the
62
- * re-review item churn); the source finding is snapshotted by title/detail. `groundedInFragment`
63
- * marks a suggestion taken straight from a best-practice fragment (the "current standard").
64
- */
65
- export interface RequirementRecommendation {
66
- id: string
67
- sourceFinding: { title: string; detail: string; itemId?: string }
68
- recommendedText: string
69
- status: RecommendationStatus
70
- note: string | null
71
- groundedInFragment: { id: string; title: string } | null
72
- createdAt: number
73
- updatedAt: number
74
- }
75
-
76
- export interface RequirementReview {
77
- id: string
78
- blockId: string
79
- status: RequirementReviewStatus
80
- items: RequirementReviewItem[]
81
- model: string | null
82
- incorporatedRequirements: string | null
83
- /** Reviewer passes run so far (initial review is 1; each re-review adds one). */
84
- iteration: number
85
- /** The reviewer-pass budget (from the task's merge preset; an extra round bumps it). */
86
- maxIterations: number
87
- /** Requirement-Writer suggestions awaiting (or settled by) human accept/reject. */
88
- recommendations: RequirementRecommendation[]
89
- createdAt: number
90
- updatedAt: number
91
- }
8
+ //
9
+ // All wire shapes are sourced from @cat-factory/contracts (single source of truth).
10
+
11
+ export type {
12
+ ReviewItemCategory,
13
+ ReviewItemSeverity,
14
+ ReviewItemStatus,
15
+ RequirementReviewItem,
16
+ RequirementReviewStatus,
17
+ ResolveRequirementsExceededChoice,
18
+ RecommendationStatus,
19
+ RequirementRecommendation,
20
+ RequirementReview,
21
+ } from '@cat-factory/contracts'