@cat-factory/app 0.6.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.
- package/LICENSE +21 -0
- package/README.md +88 -0
- package/app/app.config.ts +8 -0
- package/app/app.vue +11 -0
- package/app/assets/css/main.css +100 -0
- package/app/components/auth/AuthGate.vue +24 -0
- package/app/components/auth/LoginScreen.vue +143 -0
- package/app/components/auth/UserMenu.vue +39 -0
- package/app/components/board/AddTaskModal.vue +444 -0
- package/app/components/board/AgentFailureCard.vue +97 -0
- package/app/components/board/AgentStopButton.vue +61 -0
- package/app/components/board/BoardCanvas.vue +183 -0
- package/app/components/board/ContextPicker.vue +367 -0
- package/app/components/board/RecurringPipelineModal.vue +219 -0
- package/app/components/board/TaskDependencyEdges.vue +132 -0
- package/app/components/board/nodes/AgentChip.vue +59 -0
- package/app/components/board/nodes/BlockNode.vue +433 -0
- package/app/components/board/nodes/DecisionBadge.vue +27 -0
- package/app/components/board/nodes/DraggableTask.vue +48 -0
- package/app/components/board/nodes/ModuleFrame.vue +97 -0
- package/app/components/board/nodes/TaskCard.vue +359 -0
- package/app/components/board/nodes/TaskPipelineMini.vue +159 -0
- package/app/components/bootstrap/BootstrapModal.vue +665 -0
- package/app/components/clarity/ClarityReviewWindow.vue +611 -0
- package/app/components/consensus/ConsensusSessionWindow.vue +210 -0
- package/app/components/documents/DocumentImportModal.vue +161 -0
- package/app/components/documents/DocumentSourceConnectModal.vue +127 -0
- package/app/components/documents/SpawnPreviewModal.vue +161 -0
- package/app/components/documents/TaskContextDocs.vue +83 -0
- package/app/components/focus/BlockFocusView.vue +171 -0
- package/app/components/fragments/FragmentLibraryPanel.vue +340 -0
- package/app/components/gates/GateResultView.vue +282 -0
- package/app/components/github/AddServiceFromRepoModal.vue +354 -0
- package/app/components/github/GitHubConnect.vue +183 -0
- package/app/components/github/GitHubOnboarding.vue +45 -0
- package/app/components/github/GitHubPanel.vue +584 -0
- package/app/components/github/RepoTreeBrowser.vue +171 -0
- package/app/components/layout/AccountTeamSettings.vue +237 -0
- package/app/components/layout/BoardSwitcher.vue +280 -0
- package/app/components/layout/BoardToolbar.vue +156 -0
- package/app/components/layout/CommandBar.vue +336 -0
- package/app/components/layout/GitHubPatBanner.vue +73 -0
- package/app/components/layout/NotificationsInbox.vue +175 -0
- package/app/components/layout/SideBar.vue +314 -0
- package/app/components/layout/SpendWarningBanner.vue +107 -0
- package/app/components/observability/StepMetricsBar.vue +102 -0
- package/app/components/palettes/AgentPalette.vue +86 -0
- package/app/components/panels/AgentStepDetail.vue +737 -0
- package/app/components/panels/DecisionModal.vue +71 -0
- package/app/components/panels/InspectorPanel.vue +465 -0
- package/app/components/panels/ObservabilityPanel.vue +351 -0
- package/app/components/panels/StepMetadataCard.vue +253 -0
- package/app/components/panels/StepRestartControl.vue +90 -0
- package/app/components/panels/StepResultViewHost.vue +40 -0
- package/app/components/panels/StepTestReport.vue +84 -0
- package/app/components/panels/inspector/ContainerSummary.vue +74 -0
- package/app/components/panels/inspector/RecurringScheduleSettings.vue +178 -0
- package/app/components/panels/inspector/ServiceFragments.vue +82 -0
- package/app/components/panels/inspector/ServiceTestConfig.vue +198 -0
- package/app/components/panels/inspector/TaskAgentConfig.vue +81 -0
- package/app/components/panels/inspector/TaskDependencies.vue +70 -0
- package/app/components/panels/inspector/TaskEstimateBadge.vue +56 -0
- package/app/components/panels/inspector/TaskExecution.vue +364 -0
- package/app/components/panels/inspector/TaskRunSettings.vue +187 -0
- package/app/components/panels/inspector/TaskStructure.vue +96 -0
- package/app/components/pipeline/AgentKindIcon.vue +30 -0
- package/app/components/pipeline/IterationCapPrompt.vue +70 -0
- package/app/components/pipeline/PipelineBuilder.vue +817 -0
- package/app/components/pipeline/PipelineProgress.vue +484 -0
- package/app/components/providers/ApiKeysSection.vue +273 -0
- package/app/components/providers/PersonalCredentialModal.vue +128 -0
- package/app/components/providers/PersonalSubscriptionSection.vue +225 -0
- package/app/components/providers/VendorCredentialsModal.vue +197 -0
- package/app/components/recurring/RecurrenceEditor.vue +124 -0
- package/app/components/requirements/RequirementsReviewWindow.vue +620 -0
- package/app/components/settings/DatadogPanel.vue +213 -0
- package/app/components/settings/LocalModelEndpointsPanel.vue +286 -0
- package/app/components/settings/MergeThresholdsPanel.vue +378 -0
- package/app/components/settings/ModelDefaultsPanel.vue +250 -0
- package/app/components/settings/ServiceFragmentDefaultsPanel.vue +124 -0
- package/app/components/settings/WorkspaceSettingsPanel.vue +142 -0
- package/app/components/slack/SlackPanel.vue +299 -0
- package/app/components/tasks/TaskContextIssues.vue +88 -0
- package/app/components/tasks/TaskImportModal.vue +207 -0
- package/app/components/tasks/TaskSourceConnectModal.vue +133 -0
- package/app/components/testing/TestReportWindow.vue +404 -0
- package/app/composables/api/accounts.ts +81 -0
- package/app/composables/api/auth.ts +45 -0
- package/app/composables/api/board.ts +101 -0
- package/app/composables/api/bootstrap.ts +62 -0
- package/app/composables/api/context.ts +25 -0
- package/app/composables/api/documents.ts +74 -0
- package/app/composables/api/execution.ts +127 -0
- package/app/composables/api/fragments.ts +71 -0
- package/app/composables/api/github.ts +131 -0
- package/app/composables/api/models.ts +127 -0
- package/app/composables/api/notifications.ts +23 -0
- package/app/composables/api/presets.ts +29 -0
- package/app/composables/api/recurring.ts +68 -0
- package/app/composables/api/releaseHealth.ts +43 -0
- package/app/composables/api/reviews.ts +146 -0
- package/app/composables/api/slack.ts +54 -0
- package/app/composables/api/tasks.ts +72 -0
- package/app/composables/api/workspaces.ts +36 -0
- package/app/composables/useApi.ts +89 -0
- package/app/composables/useBlockDrag.ts +90 -0
- package/app/composables/useBlockQueries.ts +154 -0
- package/app/composables/useBoardFlow.ts +11 -0
- package/app/composables/useContextLinking.ts +65 -0
- package/app/composables/useDepLabels.ts +26 -0
- package/app/composables/useFrameResize.ts +54 -0
- package/app/composables/useResultView.ts +48 -0
- package/app/composables/useReviewStage.ts +40 -0
- package/app/composables/useSemanticZoom.ts +31 -0
- package/app/composables/useStepApproval.ts +233 -0
- package/app/composables/useStepProse.ts +78 -0
- package/app/composables/useStepTimer.ts +63 -0
- package/app/composables/useTaskExpansion.ts +92 -0
- package/app/composables/useWorkspaceStream.ts +155 -0
- package/app/docs/architecture.md +31 -0
- package/app/pages/index.vue +141 -0
- package/app/stores/accounts.ts +152 -0
- package/app/stores/agentConfig.ts +35 -0
- package/app/stores/agentRuns.ts +122 -0
- package/app/stores/agents.ts +40 -0
- package/app/stores/apiKeys.ts +108 -0
- package/app/stores/auth.ts +166 -0
- package/app/stores/board.spec.ts +205 -0
- package/app/stores/board.ts +286 -0
- package/app/stores/bootstrap.ts +97 -0
- package/app/stores/clarity.ts +196 -0
- package/app/stores/consensus.ts +60 -0
- package/app/stores/documents.ts +176 -0
- package/app/stores/execution.ts +273 -0
- package/app/stores/fragmentLibrary.ts +147 -0
- package/app/stores/fragments.ts +40 -0
- package/app/stores/github.ts +305 -0
- package/app/stores/localModels.ts +51 -0
- package/app/stores/mergePresets.ts +58 -0
- package/app/stores/modelDefaults.ts +76 -0
- package/app/stores/models.ts +134 -0
- package/app/stores/notifications.ts +70 -0
- package/app/stores/observability.ts +144 -0
- package/app/stores/personalSubscriptions.ts +215 -0
- package/app/stores/pipelines.ts +327 -0
- package/app/stores/recurringPipelines.ts +112 -0
- package/app/stores/releaseHealth.ts +75 -0
- package/app/stores/requirements.spec.ts +94 -0
- package/app/stores/requirements.ts +208 -0
- package/app/stores/serviceFragmentDefaults.ts +29 -0
- package/app/stores/services.ts +87 -0
- package/app/stores/slack.ts +142 -0
- package/app/stores/taskExpansion.ts +36 -0
- package/app/stores/tasks.spec.ts +71 -0
- package/app/stores/tasks.ts +176 -0
- package/app/stores/tracker.ts +27 -0
- package/app/stores/ui.ts +434 -0
- package/app/stores/vendorCredentials.ts +54 -0
- package/app/stores/workspace.ts +215 -0
- package/app/stores/workspaceSettings.ts +36 -0
- package/app/types/accounts.ts +77 -0
- package/app/types/bootstrap.ts +83 -0
- package/app/types/clarity.ts +59 -0
- package/app/types/consensus.ts +91 -0
- package/app/types/documents.ts +104 -0
- package/app/types/domain.ts +495 -0
- package/app/types/execution.ts +383 -0
- package/app/types/fragments.ts +72 -0
- package/app/types/github.ts +173 -0
- package/app/types/localModels.ts +73 -0
- package/app/types/merge.ts +71 -0
- package/app/types/models.ts +157 -0
- package/app/types/notifications.ts +74 -0
- package/app/types/recurring.ts +69 -0
- package/app/types/releaseHealth.ts +31 -0
- package/app/types/requirements.ts +61 -0
- package/app/types/services.ts +27 -0
- package/app/types/slack.ts +57 -0
- package/app/types/tasks.ts +82 -0
- package/app/types/tracker.ts +18 -0
- package/app/utils/agentOutput.spec.ts +128 -0
- package/app/utils/agentOutput.ts +173 -0
- package/app/utils/catalog.spec.ts +112 -0
- package/app/utils/catalog.ts +455 -0
- package/app/utils/dnd.ts +29 -0
- package/app/utils/observability.ts +52 -0
- package/app/utils/pipelineRender.ts +151 -0
- package/nuxt.config.ts +55 -0
- package/package.json +45 -0
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { defineStore } from 'pinia'
|
|
2
|
+
import { ref } from 'vue'
|
|
3
|
+
import type { UpdateWorkspaceSettingsInput, WorkspaceSettings } from '~/types/domain'
|
|
4
|
+
import { useWorkspaceStore } from '~/stores/workspace'
|
|
5
|
+
|
|
6
|
+
/** Built-in defaults, mirrored from the backend's DEFAULT_WORKSPACE_SETTINGS. */
|
|
7
|
+
const DEFAULTS: WorkspaceSettings = {
|
|
8
|
+
waitingEscalationMinutes: 120,
|
|
9
|
+
taskLimitMode: 'off',
|
|
10
|
+
taskLimitShared: null,
|
|
11
|
+
taskLimitPerType: null,
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* The workspace's runtime settings — the human-wait escalation threshold (after which a
|
|
16
|
+
* waiting notification turns red) and the per-service running-task limit policy. Hydrated
|
|
17
|
+
* from the workspace snapshot; edited via the settings panel. Falls back to the built-in
|
|
18
|
+
* defaults until the snapshot lands (or on an older server that doesn't send them).
|
|
19
|
+
*/
|
|
20
|
+
export const useWorkspaceSettingsStore = defineStore('workspaceSettings', () => {
|
|
21
|
+
const api = useApi()
|
|
22
|
+
const settings = ref<WorkspaceSettings>({ ...DEFAULTS })
|
|
23
|
+
|
|
24
|
+
function hydrate(value: WorkspaceSettings | undefined) {
|
|
25
|
+
settings.value = value ? { ...value } : { ...DEFAULTS }
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
async function update(patch: UpdateWorkspaceSettingsInput) {
|
|
29
|
+
const ws = useWorkspaceStore()
|
|
30
|
+
const updated = await api.updateWorkspaceSettings(ws.requireId(), patch)
|
|
31
|
+
settings.value = updated
|
|
32
|
+
return updated
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
return { settings, hydrate, update }
|
|
36
|
+
})
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
// ---------------------------------------------------------------------------
|
|
2
|
+
// Account tenancy. An account owns workspaces (boards): either a single user's
|
|
3
|
+
// `personal` account or an `org` shared by many engineers. Memberships map users
|
|
4
|
+
// to accounts with a role. Mirrors the `@cat-factory/contracts` account schemas
|
|
5
|
+
// so responses drop straight into the Pinia store.
|
|
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
|
+
}
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
// ---------------------------------------------------------------------------
|
|
2
|
+
// Repo-bootstrap domain types. Mirrors the `@cat-factory/contracts` bootstrap
|
|
3
|
+
// schemas so backend payloads drop straight into the Pinia store.
|
|
4
|
+
//
|
|
5
|
+
// A "reference architecture" is a managed base repo (an opinionated starter the
|
|
6
|
+
// org wants new services to follow); the "bootstrap repo" task creates a new repo
|
|
7
|
+
// from one and runs a bootstrapper agent in a container to adapt it.
|
|
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
|
+
}
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
// Clarity-review wire types. Mirror of `@cat-factory/contracts`' clarity.ts, kept
|
|
2
|
+
// in sync by hand like the rest of `~/types/*` (the SPA does not import the backend
|
|
3
|
+
// package directly).
|
|
4
|
+
//
|
|
5
|
+
// A stateless reviewer agent triages a block's BUG REPORT for fixability — raising
|
|
6
|
+
// questions / gaps / clarifications about the report; a human answers or dismisses
|
|
7
|
+
// each; then the agent folds the answers back into a clarified bug report.
|
|
8
|
+
//
|
|
9
|
+
// Structurally identical to a requirements review (the items share the same shape),
|
|
10
|
+
// so the per-item types are reused from `~/types/requirements`; only the
|
|
11
|
+
// incorporated document differs (`clarifiedReport`).
|
|
12
|
+
|
|
13
|
+
import type {
|
|
14
|
+
RequirementReviewItem,
|
|
15
|
+
ReviewItemCategory,
|
|
16
|
+
ReviewItemSeverity,
|
|
17
|
+
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'
|
|
45
|
+
|
|
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
|
+
}
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
// Frontend mirror of the consensus + task-estimate wire contracts in
|
|
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
|
+
}
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
// ---------------------------------------------------------------------------
|
|
2
|
+
// Document-source integration. Requirements / RFCs / PRDs imported from external
|
|
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`.
|
|
6
|
+
// ---------------------------------------------------------------------------
|
|
7
|
+
|
|
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. */
|
|
100
|
+
export interface SpawnResult {
|
|
101
|
+
frames: number
|
|
102
|
+
modules: number
|
|
103
|
+
tasks: number
|
|
104
|
+
}
|