@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,39 +1,14 @@
1
1
  // Per-account (deployment-wide) integration settings. Mirrors
2
2
  // `@cat-factory/contracts` accountSettings. Secrets are write-only — the read view
3
3
  // returns only `config` + a non-secret presence `summary`.
4
-
5
- export interface SlackOAuthSecret {
6
- clientId: string
7
- clientSecret: string
8
- redirectUrl: string
9
- }
10
-
11
- export interface WebSearchSecret {
12
- braveApiKey?: string
13
- searxngUrl?: string
14
- searxngApiKey?: string
15
- }
16
-
17
- /** Non-secret per-account config (empty today; reserved for forward-compatible tuning). */
18
- export type AccountSettingsConfig = Record<string, never>
19
-
20
- export interface AccountSettingsSummary {
21
- slackOAuthConfigured: boolean
22
- webSearch: 'brave' | 'searxng' | null
23
- }
24
-
25
- export interface AccountSettingsView {
26
- config: AccountSettingsConfig
27
- summary: AccountSettingsSummary
28
- }
29
-
30
- /**
31
- * Admin write. Each secrets group: omit ⇒ leave unchanged, `null` ⇒ clear, value ⇒ set.
32
- */
33
- export interface UpdateAccountSettingsInput {
34
- config?: AccountSettingsConfig
35
- secrets?: {
36
- slackOAuth?: SlackOAuthSecret | null
37
- webSearch?: WebSearchSecret | null
38
- }
39
- }
4
+ //
5
+ // All wire shapes are sourced from @cat-factory/contracts (single source of truth).
6
+
7
+ export type {
8
+ SlackOAuthSecret,
9
+ WebSearchSecret,
10
+ AccountSettingsConfig,
11
+ AccountSettingsSummary,
12
+ AccountSettingsView,
13
+ UpdateAccountSettingsInput,
14
+ } from '@cat-factory/contracts'
@@ -4,74 +4,19 @@
4
4
  // to accounts with a role. Mirrors the `@cat-factory/contracts` account schemas
5
5
  // so responses drop straight into the Pinia store.
6
6
  // ---------------------------------------------------------------------------
7
-
8
- import type { CloudProvider } from './domain'
9
-
10
- export type AccountType = 'personal' | 'org'
11
- /** Combinable account roles: admin controls the org account, product owns tasks. */
12
- export type AccountRole = 'admin' | 'developer' | 'product'
13
-
14
- /** An account, annotated with the signed-in caller's roles in it. */
15
- export interface Account {
16
- id: string
17
- type: AccountType
18
- name: string
19
- githubAccountLogin: string | null
20
- createdAt: number
21
- /** The caller's roles in this account (`null` in the auth-disabled path). */
22
- roles: AccountRole[] | null
23
- /** The cloud provider new services in this account default to; absent = built-in default. */
24
- defaultCloudProvider?: CloudProvider
25
- }
26
-
27
- /** A member of an account, with display details when resolvable. */
28
- export interface AccountMember {
29
- accountId: string
30
- userId: string
31
- roles: AccountRole[]
32
- createdAt: number
33
- name?: string | null
34
- email?: string | null
35
- avatarUrl?: string | null
36
- }
37
-
38
- export interface CreateAccountInput {
39
- name: string
40
- githubAccountLogin?: string
41
- }
42
-
43
- /** Update an account's settings (today: its default cloud provider for new services). */
44
- export interface UpdateAccountInput {
45
- defaultCloudProvider?: CloudProvider
46
- }
47
-
48
- export interface AddMemberInput {
49
- userId: string
50
- roles?: AccountRole[]
51
- }
52
-
53
- /** Set a member's role set (admin-only). */
54
- export interface SetMemberRolesInput {
55
- roles: AccountRole[]
56
- }
57
-
58
- /** An email invitation into an org account (never carries the raw token). */
59
- export interface AccountInvitation {
60
- id: string
61
- accountId: string
62
- email: string
63
- roles: AccountRole[]
64
- status: 'pending' | 'accepted' | 'revoked'
65
- invitedBy: string
66
- expiresAt: number
67
- createdAt: number
68
- }
69
-
70
- export type EmailProviderKind = 'sendgrid' | 'resend'
71
-
72
- /** A per-account email-sender connection (safe metadata; never the API key). */
73
- export interface EmailConnection {
74
- provider: EmailProviderKind
75
- fromAddress: string
76
- connectedAt: number
77
- }
7
+ //
8
+ // All wire shapes are sourced from @cat-factory/contracts (single source of truth).
9
+
10
+ export type {
11
+ AccountType,
12
+ AccountRole,
13
+ Account,
14
+ AccountMember,
15
+ CreateAccountInput,
16
+ UpdateAccountInput,
17
+ AddMemberInput,
18
+ SetMemberRolesInput,
19
+ AccountInvitation,
20
+ EmailProviderKind,
21
+ EmailConnection,
22
+ } from '@cat-factory/contracts'
@@ -6,78 +6,16 @@
6
6
  // org wants new services to follow); the "bootstrap repo" task creates a new repo
7
7
  // from one and runs a bootstrapper agent in a container to adapt it.
8
8
  // ---------------------------------------------------------------------------
9
-
10
- import type { AgentFailure, AgentFailureKind, StepSubtasks } from './execution'
11
-
12
- /** A managed base repository new repos are bootstrapped from. */
13
- export interface ReferenceArchitecture {
14
- id: string
15
- workspaceId: string
16
- name: string
17
- description: string
18
- repoOwner: string
19
- repoName: string
20
- defaultInstructions: string
21
- createdAt: number
22
- updatedAt: number
23
- }
24
-
25
- /** Body to register a reference architecture. */
26
- export interface CreateReferenceArchitectureInput {
27
- name: string
28
- description?: string
29
- repoOwner: string
30
- repoName: string
31
- defaultInstructions?: string
32
- }
33
-
34
- /** Body to patch a reference architecture (only supplied fields change). */
35
- export type UpdateReferenceArchitectureInput = Partial<CreateReferenceArchitectureInput>
36
-
37
- /** Lifecycle of a single "bootstrap repo" run. */
38
- export type BootstrapStatus = 'pending' | 'running' | 'succeeded' | 'failed'
39
-
40
- /**
41
- * A bootstrap run's failure is now the shared {@link AgentFailure} (same shape
42
- * execution runs use), so the board renders one failure banner + retry for any
43
- * agent. These aliases stay for back-compat / documentation of the bootstrap
44
- * subset; `bootstrapFailureKindSchema` on the backend stays narrow.
45
- */
46
- export type BootstrapFailureKind = AgentFailureKind
47
-
48
- /** Structured failure diagnostics captured when a bootstrap run fails. */
49
- export type BootstrapFailure = AgentFailure
50
-
51
- /** One "bootstrap repo" run with its outcome. */
52
- export interface BootstrapJob {
53
- id: string
54
- workspaceId: string
55
- /** Reference architecture the run was based on, or null for a from-scratch run. */
56
- referenceArchitectureId: string | null
57
- /** Denormalized reference architecture name, or null for a from-scratch run. */
58
- referenceArchitectureName: string | null
59
- repoName: string
60
- repoOwner: string | null
61
- repoUrl: string | null
62
- instructions: string
63
- status: BootstrapStatus
64
- /** The board service frame this run materialises, or null if none was created. */
65
- blockId: string | null
66
- /** Live subtask counts from the bootstrapper agent, or null until it reports. */
67
- subtasks: StepSubtasks | null
68
- error: string | null
69
- /** Structured failure diagnostics when `status` is `failed`; null otherwise. */
70
- failure: BootstrapFailure | null
71
- createdAt: number
72
- updatedAt: number
73
- }
74
-
75
- /** Body to kick off a bootstrap run. Omit `referenceArchitectureId` to bootstrap
76
- * from a freeform prompt alone (then `instructions` must be non-empty). */
77
- export interface BootstrapRepoInput {
78
- referenceArchitectureId?: string | null
79
- repoName: string
80
- description?: string
81
- private?: boolean
82
- instructions?: string
83
- }
9
+ //
10
+ // All wire shapes are sourced from @cat-factory/contracts (single source of truth).
11
+
12
+ export type {
13
+ ReferenceArchitecture,
14
+ CreateReferenceArchitectureInput,
15
+ UpdateReferenceArchitectureInput,
16
+ BootstrapStatus,
17
+ BootstrapFailureKind,
18
+ BootstrapFailure,
19
+ BootstrapJob,
20
+ BootstrapRepoInput,
21
+ } from '@cat-factory/contracts'
@@ -10,46 +10,21 @@
10
10
  // Structurally identical to a requirements review (the items share the same shape), so the
11
11
  // per-item types are reused from `~/types/requirements`; only the `stage` discriminator and
12
12
  // the converged document (`convergedDirection`) differ.
13
+ //
14
+ // All wire shapes are sourced from @cat-factory/contracts (single source of truth).
13
15
 
14
- import type {
15
- RequirementReviewItem,
16
+ export type {
17
+ BrainstormStage,
18
+ BrainstormItem,
19
+ BrainstormStatus,
20
+ ResolveBrainstormExceededChoice,
21
+ BrainstormSession,
22
+ // The per-item types are shared with a requirements review (same shape).
16
23
  ReviewItemCategory,
17
24
  ReviewItemSeverity,
18
25
  ReviewItemStatus,
19
- } from '~/types/requirements'
20
-
21
- export type { ReviewItemCategory, ReviewItemSeverity, ReviewItemStatus }
22
-
23
- /** Which dialogue a brainstorm session drives. */
24
- export type BrainstormStage = 'requirements' | 'architecture'
25
-
26
- /** A brainstorm option is the same shape as a requirements-review item. */
27
- export type BrainstormItem = RequirementReviewItem
28
-
29
- /** Lifecycle of a brainstorm session — identical to the requirements review lifecycle. */
30
- export type BrainstormStatus =
31
- | 'ready'
32
- | 'incorporating'
33
- | 'reviewing'
34
- | 'merged'
35
- | 'exceeded'
36
- | 'incorporated'
37
-
38
- /** How a human resolves a session that hit its iteration cap. */
39
- export type ResolveBrainstormExceededChoice = 'extra-round' | 'proceed' | 'stop-reset'
26
+ } from '@cat-factory/contracts'
27
+ import type { UpdateBrainstormItemStatusInput } from '@cat-factory/contracts'
40
28
 
41
- export interface BrainstormSession {
42
- id: string
43
- blockId: string
44
- stage: BrainstormStage
45
- status: BrainstormStatus
46
- items: BrainstormItem[]
47
- model: string | null
48
- convergedDirection: string | null
49
- /** Agent passes run so far (initial pass is 1; each re-run adds one). */
50
- iteration: number
51
- /** The agent-pass budget (from the task's merge preset; an extra round bumps it). */
52
- maxIterations: number
53
- createdAt: number
54
- updatedAt: number
55
- }
29
+ /** The narrower status set the set-item-status action accepts (a subset of ReviewItemStatus). */
30
+ export type BrainstormItemStatus = UpdateBrainstormItemStatusInput['status']
@@ -9,51 +9,20 @@
9
9
  // Structurally identical to a requirements review (the items share the same shape),
10
10
  // so the per-item types are reused from `~/types/requirements`; only the
11
11
  // incorporated document differs (`clarifiedReport`).
12
+ //
13
+ // All wire shapes are sourced from @cat-factory/contracts (single source of truth).
12
14
 
13
- import type {
14
- RequirementReviewItem,
15
+ export type {
16
+ ClarityReviewItem,
17
+ ClarityReviewStatus,
18
+ ResolveClarityExceededChoice,
19
+ ClarityReview,
20
+ // The per-item types are shared with a requirements review (same shape).
15
21
  ReviewItemCategory,
16
22
  ReviewItemSeverity,
17
23
  ReviewItemStatus,
18
- } from '~/types/requirements'
19
-
20
- export type { ReviewItemCategory, ReviewItemSeverity, ReviewItemStatus }
21
-
22
- /** A clarity-review item is the same shape as a requirements-review item. */
23
- export type ClarityReviewItem = RequirementReviewItem
24
-
25
- /**
26
- * - `ready`: the reviewer raised findings awaiting human answers/dismissals.
27
- * - `incorporating`: transient; the driver is folding the answers into a document (the FIRST
28
- * async stage — the user is back on the board).
29
- * - `reviewing`: transient; the reviewer is RE-reviewing the folded document (the SECOND
30
- * async stage). Distinct from `incorporating` so the UI can show which stage is running.
31
- * - `merged`: the companion produced a document (an internal transient on the async path).
32
- * - `exceeded`: the iteration cap was hit with findings open — awaiting the human's choice.
33
- * - `incorporated`: terminal; the clarity phase is settled.
34
- */
35
- export type ClarityReviewStatus =
36
- | 'ready'
37
- | 'incorporating'
38
- | 'reviewing'
39
- | 'merged'
40
- | 'exceeded'
41
- | 'incorporated'
42
-
43
- /** How a human resolves a review that hit its iteration cap. */
44
- export type ResolveClarityExceededChoice = 'extra-round' | 'proceed' | 'stop-reset'
24
+ } from '@cat-factory/contracts'
25
+ import type { UpdateClarityItemStatusInput } from '@cat-factory/contracts'
45
26
 
46
- export interface ClarityReview {
47
- id: string
48
- blockId: string
49
- status: ClarityReviewStatus
50
- items: ClarityReviewItem[]
51
- model: string | null
52
- clarifiedReport: string | null
53
- /** Reviewer passes run so far (initial review is 1; each re-review adds one). */
54
- iteration: number
55
- /** The reviewer-pass budget (from the task's merge preset; an extra round bumps it). */
56
- maxIterations: number
57
- createdAt: number
58
- updatedAt: number
59
- }
27
+ /** The narrower status set the set-item-status action accepts (a subset of ReviewItemStatus). */
28
+ export type ClarityItemStatus = UpdateClarityItemStatusInput['status']
@@ -1,91 +1,18 @@
1
1
  // Frontend mirror of the consensus + task-estimate wire contracts in
2
2
  // `@cat-factory/contracts` (src/consensus.ts). Hand-synced, like the other type mirrors.
3
-
4
- export type ConsensusStrategy = 'specialist-panel' | 'debate' | 'ranked-voting'
5
-
6
- export interface ConsensusParticipant {
7
- id: string
8
- role: string
9
- systemFraming?: string
10
- modelId?: string
11
- }
12
-
13
- export interface ConsensusGating {
14
- enabled: boolean
15
- minComplexity?: number
16
- minRisk?: number
17
- minImpact?: number
18
- onMissingEstimate?: 'consensus' | 'standard'
19
- }
20
-
21
- /**
22
- * Estimate-based gating of whether a pipeline STEP runs at all (the same three axes as
23
- * {@link ConsensusGating}). When enabled the step runs only if ANY supplied axis is met or
24
- * exceeded; otherwise it is skipped at runtime. Used to make a companion conditional on how
25
- * heavy the task is. A step with enabled gating requires a `task-estimator` earlier in the
26
- * pipeline.
27
- */
28
- export interface StepGating {
29
- enabled: boolean
30
- minComplexity?: number
31
- minRisk?: number
32
- minImpact?: number
33
- onMissingEstimate?: 'run' | 'skip'
34
- }
35
-
36
- export interface ConsensusStepConfig {
37
- enabled: boolean
38
- strategy: ConsensusStrategy
39
- participants: ConsensusParticipant[]
40
- synthesizerModelId?: string
41
- rounds?: number
42
- gating?: ConsensusGating
43
- }
44
-
45
- /** The task-estimator's triage of a task (each axis 0..1). */
46
- export interface TaskEstimate {
47
- complexity: number
48
- risk: number
49
- impact: number
50
- rationale: string
51
- model?: string | null
52
- createdAt: number
53
- }
54
-
55
- export interface ConsensusScore {
56
- dimension: string
57
- value: number
58
- rationale?: string
59
- }
60
-
61
- export interface ConsensusContribution {
62
- participantId: string
63
- text: string
64
- scores?: ConsensusScore[]
65
- }
66
-
67
- export interface ConsensusRound {
68
- index: number
69
- kind?: 'draft' | 'critique' | 'score'
70
- contributions: ConsensusContribution[]
71
- }
72
-
73
- export type ConsensusSessionStatus = 'running' | 'synthesizing' | 'done' | 'failed'
74
-
75
- export interface ConsensusSession {
76
- id: string
77
- blockId: string
78
- executionId: string | null
79
- stepIndex: number
80
- agentKind: string
81
- strategy: ConsensusStrategy
82
- status: ConsensusSessionStatus
83
- participants: ConsensusParticipant[]
84
- rounds: ConsensusRound[]
85
- synthesis: string | null
86
- confidence?: number | null
87
- dissent?: string[]
88
- error?: string | null
89
- createdAt: number
90
- updatedAt: number
91
- }
3
+ //
4
+ // All wire shapes are sourced from @cat-factory/contracts (single source of truth).
5
+
6
+ export type {
7
+ ConsensusStrategy,
8
+ ConsensusParticipant,
9
+ ConsensusGating,
10
+ StepGating,
11
+ ConsensusStepConfig,
12
+ TaskEstimate,
13
+ ConsensusScore,
14
+ ConsensusContribution,
15
+ ConsensusRound,
16
+ ConsensusSessionStatus,
17
+ ConsensusSession,
18
+ } from '@cat-factory/contracts'
@@ -1,102 +1,27 @@
1
1
  // ---------------------------------------------------------------------------
2
2
  // Document-source integration. Requirements / RFCs / PRDs imported from external
3
3
  // sources (Confluence, Notion, …) can be expanded into board structure or
4
- // attached to a task as agent context. These mirror the `@cat-factory/contracts`
5
- // document schemas; the abstraction is source-agnostic, keyed by `source`.
4
+ // attached to a task as agent context.
5
+ //
6
+ // All wire shapes are sourced from @cat-factory/contracts (single source of
7
+ // truth). `SpawnResult` has no exported contract type (the contract models it
8
+ // inline), so it stays frontend-only below.
6
9
  // ---------------------------------------------------------------------------
7
10
 
8
- import type { BlockType } from './domain'
9
-
10
- /** The external document sources cat-factory can link to. */
11
- export type DocumentSourceKind = 'confluence' | 'notion' | 'github'
12
-
13
- /** One credential a provider needs to connect (rendered as a form field). */
14
- export interface CredentialField {
15
- key: string
16
- label: string
17
- help?: string
18
- placeholder?: string
19
- secret?: boolean
20
- }
21
-
22
- /** A source's self-description: drives the generic connect + import UI. */
23
- export interface DocumentSourceDescriptor {
24
- source: DocumentSourceKind
25
- label: string
26
- /** Lucide icon name for the source. */
27
- icon: string
28
- credentialFields: CredentialField[]
29
- refLabel: string
30
- refPlaceholder: string
31
- /** Whether the source supports searching its catalogue by title/content. */
32
- searchable?: boolean
33
- }
34
-
35
- /** A workspace's connection to a document source (never carries credentials). */
36
- export interface DocumentConnection {
37
- source: DocumentSourceKind
38
- /** Human-friendly label for what we're connected to (site URL, workspace name). */
39
- label: string
40
- /** When the connection was established (epoch ms). */
41
- connectedAt: number
42
- }
43
-
44
- /** A page imported from a source into the workspace. */
45
- export interface SourceDocument {
46
- source: DocumentSourceKind
47
- /** The source's stable id for the page. */
48
- externalId: string
49
- title: string
50
- url: string
51
- /** Short plain-text preview of the page body. */
52
- excerpt: string
53
- /** The board block this document is attached to as context, if any. */
54
- linkedBlockId: string | null
55
- syncedAt: number
56
- }
57
-
58
- /** A lean hit from searching a document source's catalogue (not yet imported). */
59
- export interface DocumentSearchResult {
60
- source: DocumentSourceKind
61
- /** The source's stable id for the page (re-usable as an import ref). */
62
- externalId: string
63
- title: string
64
- url: string
65
- /** Short plain-text preview (may be empty). */
66
- excerpt: string
67
- }
68
-
69
- /** A proposed task within a planned frame/module. */
70
- export interface PlanTask {
71
- title: string
72
- description?: string
73
- }
74
-
75
- /** A proposed module grouping tasks within a planned frame. */
76
- export interface PlanModule {
77
- name: string
78
- tasks: PlanTask[]
79
- }
80
-
81
- /** A proposed top-level frame with its modules and loose tasks. */
82
- export interface PlanFrame {
83
- type: BlockType
84
- title: string
85
- description?: string
86
- modules: PlanModule[]
87
- tasks: PlanTask[]
88
- }
89
-
90
- /** A board structure extracted from an imported document. */
91
- export interface DocumentBoardPlan {
92
- source: DocumentSourceKind
93
- externalId: string
94
- /** Whether an LLM produced the plan or the deterministic heading parser did. */
95
- planner: 'llm' | 'headings'
96
- frames: PlanFrame[]
97
- }
98
-
99
- /** Counts of blocks created by spawning a plan onto the board. */
11
+ export type {
12
+ DocumentSourceKind,
13
+ CredentialField,
14
+ DocumentSourceDescriptor,
15
+ DocumentConnection,
16
+ SourceDocument,
17
+ DocumentSearchResult,
18
+ PlanTask,
19
+ PlanModule,
20
+ PlanFrame,
21
+ DocumentBoardPlan,
22
+ } from '@cat-factory/contracts'
23
+
24
+ /** Counts of blocks created by spawning a plan onto the board. Frontend-only. */
100
25
  export interface SpawnResult {
101
26
  frames: number
102
27
  modules: number