@cat-factory/app 0.6.0 → 0.7.3
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 -21
- package/app/components/board/ContextPicker.vue +367 -367
- package/app/components/gates/GateResultView.vue +90 -12
- package/app/components/layout/SideBar.vue +11 -0
- package/app/components/observability/StepMetricsBar.vue +102 -102
- package/app/components/observability/StepModelActivity.vue +49 -0
- package/app/components/panels/ObservabilityPanel.vue +1 -1
- package/app/components/panels/StepMetadataCard.vue +4 -16
- package/app/components/panels/StepRunMeta.vue +105 -0
- package/app/components/panels/inspector/RecurringScheduleSettings.vue +178 -178
- package/app/components/panels/inspector/TaskRunSettings.vue +77 -0
- package/app/components/recurring/RecurrenceEditor.vue +124 -124
- package/app/components/settings/IssueTrackerWritebackPanel.vue +103 -0
- package/app/components/testing/TestReportWindow.vue +17 -8
- package/app/composables/useBlockQueries.ts +154 -154
- package/app/composables/useContextLinking.ts +65 -65
- package/app/composables/useFrameResize.ts +54 -54
- package/app/pages/index.vue +2 -0
- package/app/stores/documents.ts +176 -176
- package/app/stores/services.ts +87 -87
- package/app/stores/tracker.ts +39 -27
- package/app/stores/ui.ts +12 -0
- package/app/types/documents.ts +104 -104
- package/app/types/domain.ts +5 -1
- package/app/types/execution.ts +18 -0
- package/app/types/github.ts +173 -173
- package/app/types/services.ts +27 -27
- package/app/types/tasks.ts +82 -82
- package/app/types/tracker.ts +27 -18
- package/app/utils/agentOutput.spec.ts +128 -128
- package/app/utils/agentOutput.ts +173 -173
- package/app/utils/observability.ts +52 -52
- package/package.json +6 -1
package/app/types/documents.ts
CHANGED
|
@@ -1,104 +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
|
-
}
|
|
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
|
+
}
|
package/app/types/domain.ts
CHANGED
|
@@ -23,7 +23,7 @@ import type { ClarityReview } from './clarity'
|
|
|
23
23
|
import type { MergeThresholdPreset } from './merge'
|
|
24
24
|
import type { PipelineSchedule } from './recurring'
|
|
25
25
|
import type { Service, WorkspaceMount } from './services'
|
|
26
|
-
import type { TrackerSettings } from './tracker'
|
|
26
|
+
import type { TrackerSettings, WritebackOverride } from './tracker'
|
|
27
27
|
|
|
28
28
|
/** Lifecycle of an architecture building block. */
|
|
29
29
|
export type BlockStatus =
|
|
@@ -145,6 +145,10 @@ export interface Block {
|
|
|
145
145
|
* with the `product` role, notified when requirement review flags this task.
|
|
146
146
|
*/
|
|
147
147
|
responsibleProductUserId?: string | null
|
|
148
|
+
/** task-only: override "comment on the linked issue when a PR opens"; absent/null = inherit workspace. */
|
|
149
|
+
trackerCommentOnPrOpen?: WritebackOverride | null
|
|
150
|
+
/** task-only: override "close the linked issue as resolved on merge"; absent/null = inherit workspace. */
|
|
151
|
+
trackerResolveOnMerge?: WritebackOverride | null
|
|
148
152
|
}
|
|
149
153
|
|
|
150
154
|
/**
|
package/app/types/execution.ts
CHANGED
|
@@ -333,6 +333,22 @@ export interface PipelineStep {
|
|
|
333
333
|
export interface GateFailingCheck {
|
|
334
334
|
name: string
|
|
335
335
|
conclusion: string | null
|
|
336
|
+
/** GitHub web URL of the check run, so the UI can link to the failed run's logs */
|
|
337
|
+
url?: string | null
|
|
338
|
+
}
|
|
339
|
+
|
|
340
|
+
/** One helper-agent attempt the gate dispatched (mirrors `gateAttemptSchema`). */
|
|
341
|
+
export interface GateAttempt {
|
|
342
|
+
/** 1-based attempt number */
|
|
343
|
+
attempt: number
|
|
344
|
+
/** epoch ms when the helper job finished */
|
|
345
|
+
at: number
|
|
346
|
+
/** how the helper job ended */
|
|
347
|
+
outcome: 'completed' | 'failed'
|
|
348
|
+
/** the PR head commit the helper worked against, when known */
|
|
349
|
+
headSha?: string | null
|
|
350
|
+
/** the helper's own account of what it did / what remains */
|
|
351
|
+
summary?: string | null
|
|
336
352
|
}
|
|
337
353
|
|
|
338
354
|
/** Live state of a polling gate step (`ci` / `conflicts`); mirrors `gateStepStateSchema`. */
|
|
@@ -350,6 +366,8 @@ export interface GateStepState {
|
|
|
350
366
|
lastFailureSummary?: string | null
|
|
351
367
|
/** structured failing checks behind the summary (CI gate only; absent for conflicts) */
|
|
352
368
|
failingChecks?: GateFailingCheck[] | null
|
|
369
|
+
/** history of the helper-agent attempts this gate dispatched, newest last */
|
|
370
|
+
attemptLog?: GateAttempt[] | null
|
|
353
371
|
}
|
|
354
372
|
|
|
355
373
|
/** Live state of a `tester` step's Tester→Fixer loop (mirrors `testerStepStateSchema`). */
|
package/app/types/github.ts
CHANGED
|
@@ -1,173 +1,173 @@
|
|
|
1
|
-
// ---------------------------------------------------------------------------
|
|
2
|
-
// GitHub integration. The backend's `GitHubModule` projects GitHub data
|
|
3
|
-
// (repos/branches, pull requests/issues) into D1 and serves it fast and
|
|
4
|
-
// rate-limit-free, alongside connect/resync/write endpoints. These mirror the
|
|
5
|
-
// `@cat-factory/contracts` GitHub schemas so responses drop straight into the
|
|
6
|
-
// Pinia store, just as the document-source types do for Confluence/Notion.
|
|
7
|
-
// ---------------------------------------------------------------------------
|
|
8
|
-
|
|
9
|
-
/** A workspace's GitHub App installation, as exposed to clients (no token). */
|
|
10
|
-
export interface GitHubConnection {
|
|
11
|
-
installationId: number
|
|
12
|
-
accountLogin: string
|
|
13
|
-
targetType: 'Organization' | 'User'
|
|
14
|
-
connectedAt: number
|
|
15
|
-
/**
|
|
16
|
-
* Whether cat-factory can create repos under this account itself (privileged
|
|
17
|
-
* App tier). When true, the bootstrap UI drops the manual "create on GitHub"
|
|
18
|
-
* step. Defaults to false for older backends that don't send it.
|
|
19
|
-
*/
|
|
20
|
-
canCreateRepos?: boolean
|
|
21
|
-
/**
|
|
22
|
-
* Whether the installation granted the App `workflows: write`. When false, agent
|
|
23
|
-
* pushes that add/update `.github/workflows/*` are rejected by GitHub, so the UI
|
|
24
|
-
* warns the user to grant the permission. Defaults to false for older backends.
|
|
25
|
-
*/
|
|
26
|
-
canManageWorkflows?: boolean
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
/**
|
|
30
|
-
* A discoverable App installation for the connect picker. `connected` says
|
|
31
|
-
* whether it's already bound: to THIS workspace, to ANOTHER (so connecting would
|
|
32
|
-
* be rejected), or to NONE (free to connect).
|
|
33
|
-
*/
|
|
34
|
-
export interface GitHubInstallationOption {
|
|
35
|
-
installationId: number
|
|
36
|
-
accountLogin: string
|
|
37
|
-
targetType: 'Organization' | 'User'
|
|
38
|
-
accountAvatarUrl: string | null
|
|
39
|
-
connected: 'this' | 'other' | 'none'
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
/** A repository the integration tracks for a workspace. */
|
|
43
|
-
export interface GitHubRepo {
|
|
44
|
-
githubId: number
|
|
45
|
-
installationId: number
|
|
46
|
-
owner: string
|
|
47
|
-
name: string
|
|
48
|
-
defaultBranch: string | null
|
|
49
|
-
private: boolean
|
|
50
|
-
/** Optional link to a board block this repo backs. */
|
|
51
|
-
blockId: string | null
|
|
52
|
-
/** Whether this repo is a monorepo hosting several services (each pinned to a subdirectory). */
|
|
53
|
-
isMonorepo?: boolean
|
|
54
|
-
syncedAt: number
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
/** One directory entry of a repo's tree, used by the monorepo service picker. */
|
|
58
|
-
export interface RepoTreeEntry {
|
|
59
|
-
/** Path relative to the repo root, e.g. `packages/api`. */
|
|
60
|
-
path: string
|
|
61
|
-
/** Base name, e.g. `api`. */
|
|
62
|
-
name: string
|
|
63
|
-
/** `file` | `dir` | `symlink` | `submodule`. */
|
|
64
|
-
type: string
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
export interface GitHubBranch {
|
|
68
|
-
repoGithubId: number
|
|
69
|
-
name: string
|
|
70
|
-
headSha: string
|
|
71
|
-
protected: boolean
|
|
72
|
-
syncedAt: number
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
/**
|
|
76
|
-
* A repo the connected installation can access, annotated with whether the
|
|
77
|
-
* current workspace links it. Drives the per-workspace repo picker — repos are
|
|
78
|
-
* linked explicitly per board, since the installation is shared across an
|
|
79
|
-
* account's workspaces.
|
|
80
|
-
*/
|
|
81
|
-
export interface GitHubAvailableRepo {
|
|
82
|
-
githubId: number
|
|
83
|
-
owner: string
|
|
84
|
-
name: string
|
|
85
|
-
defaultBranch: string | null
|
|
86
|
-
private: boolean
|
|
87
|
-
linked: boolean
|
|
88
|
-
/** Whether the (linked) repo is flagged as a monorepo. */
|
|
89
|
-
isMonorepo?: boolean
|
|
90
|
-
}
|
|
91
|
-
|
|
92
|
-
export type GitHubPullRequestState = 'open' | 'closed'
|
|
93
|
-
|
|
94
|
-
export interface GitHubPullRequest {
|
|
95
|
-
repoGithubId: number
|
|
96
|
-
number: number
|
|
97
|
-
githubId: number
|
|
98
|
-
title: string
|
|
99
|
-
state: GitHubPullRequestState
|
|
100
|
-
headRef: string | null
|
|
101
|
-
baseRef: string | null
|
|
102
|
-
headSha: string | null
|
|
103
|
-
merged: boolean
|
|
104
|
-
author: string | null
|
|
105
|
-
updatedAt: number | null
|
|
106
|
-
syncedAt: number
|
|
107
|
-
}
|
|
108
|
-
|
|
109
|
-
export type GitHubIssueState = 'open' | 'closed'
|
|
110
|
-
|
|
111
|
-
export interface GitHubIssue {
|
|
112
|
-
repoGithubId: number
|
|
113
|
-
number: number
|
|
114
|
-
githubId: number
|
|
115
|
-
title: string
|
|
116
|
-
state: GitHubIssueState
|
|
117
|
-
author: string | null
|
|
118
|
-
labels: string[]
|
|
119
|
-
updatedAt: number | null
|
|
120
|
-
syncedAt: number
|
|
121
|
-
}
|
|
122
|
-
|
|
123
|
-
// ---- request inputs -------------------------------------------------------
|
|
124
|
-
|
|
125
|
-
/** Trigger a resync. Defaults to an incremental resync of all tracked repos. */
|
|
126
|
-
export interface ResyncRequest {
|
|
127
|
-
/** Limit the resync to a single repo (by its GitHub numeric id). */
|
|
128
|
-
repoGithubId?: number
|
|
129
|
-
/** Run a full backfill (durable Workflow) instead of an incremental pass. */
|
|
130
|
-
full?: boolean
|
|
131
|
-
}
|
|
132
|
-
|
|
133
|
-
export interface CreateBranchInput {
|
|
134
|
-
name: string
|
|
135
|
-
fromSha: string
|
|
136
|
-
}
|
|
137
|
-
|
|
138
|
-
/** Body for programmatic repo creation (privileged App tier). */
|
|
139
|
-
export interface CreateRepoRequest {
|
|
140
|
-
/** A single GitHub name segment — no "owner/" prefix. */
|
|
141
|
-
name: string
|
|
142
|
-
private?: boolean
|
|
143
|
-
description?: string
|
|
144
|
-
}
|
|
145
|
-
|
|
146
|
-
/** The freshly-created repository returned by the create-repo endpoint. */
|
|
147
|
-
export interface CreatedRepo {
|
|
148
|
-
githubId: number
|
|
149
|
-
owner: string
|
|
150
|
-
name: string
|
|
151
|
-
defaultBranch: string | null
|
|
152
|
-
private: boolean
|
|
153
|
-
}
|
|
154
|
-
|
|
155
|
-
export interface CommitFilesInput {
|
|
156
|
-
branch: string
|
|
157
|
-
message: string
|
|
158
|
-
files: { path: string; content: string }[]
|
|
159
|
-
/** Parent commit to build on; defaults to the branch tip. */
|
|
160
|
-
baseSha?: string
|
|
161
|
-
}
|
|
162
|
-
|
|
163
|
-
export interface OpenPullRequestInput {
|
|
164
|
-
title: string
|
|
165
|
-
head: string
|
|
166
|
-
base: string
|
|
167
|
-
body?: string
|
|
168
|
-
draft?: boolean
|
|
169
|
-
}
|
|
170
|
-
|
|
171
|
-
export interface MergePullRequestInput {
|
|
172
|
-
method?: 'merge' | 'squash' | 'rebase'
|
|
173
|
-
}
|
|
1
|
+
// ---------------------------------------------------------------------------
|
|
2
|
+
// GitHub integration. The backend's `GitHubModule` projects GitHub data
|
|
3
|
+
// (repos/branches, pull requests/issues) into D1 and serves it fast and
|
|
4
|
+
// rate-limit-free, alongside connect/resync/write endpoints. These mirror the
|
|
5
|
+
// `@cat-factory/contracts` GitHub schemas so responses drop straight into the
|
|
6
|
+
// Pinia store, just as the document-source types do for Confluence/Notion.
|
|
7
|
+
// ---------------------------------------------------------------------------
|
|
8
|
+
|
|
9
|
+
/** A workspace's GitHub App installation, as exposed to clients (no token). */
|
|
10
|
+
export interface GitHubConnection {
|
|
11
|
+
installationId: number
|
|
12
|
+
accountLogin: string
|
|
13
|
+
targetType: 'Organization' | 'User'
|
|
14
|
+
connectedAt: number
|
|
15
|
+
/**
|
|
16
|
+
* Whether cat-factory can create repos under this account itself (privileged
|
|
17
|
+
* App tier). When true, the bootstrap UI drops the manual "create on GitHub"
|
|
18
|
+
* step. Defaults to false for older backends that don't send it.
|
|
19
|
+
*/
|
|
20
|
+
canCreateRepos?: boolean
|
|
21
|
+
/**
|
|
22
|
+
* Whether the installation granted the App `workflows: write`. When false, agent
|
|
23
|
+
* pushes that add/update `.github/workflows/*` are rejected by GitHub, so the UI
|
|
24
|
+
* warns the user to grant the permission. Defaults to false for older backends.
|
|
25
|
+
*/
|
|
26
|
+
canManageWorkflows?: boolean
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* A discoverable App installation for the connect picker. `connected` says
|
|
31
|
+
* whether it's already bound: to THIS workspace, to ANOTHER (so connecting would
|
|
32
|
+
* be rejected), or to NONE (free to connect).
|
|
33
|
+
*/
|
|
34
|
+
export interface GitHubInstallationOption {
|
|
35
|
+
installationId: number
|
|
36
|
+
accountLogin: string
|
|
37
|
+
targetType: 'Organization' | 'User'
|
|
38
|
+
accountAvatarUrl: string | null
|
|
39
|
+
connected: 'this' | 'other' | 'none'
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
/** A repository the integration tracks for a workspace. */
|
|
43
|
+
export interface GitHubRepo {
|
|
44
|
+
githubId: number
|
|
45
|
+
installationId: number
|
|
46
|
+
owner: string
|
|
47
|
+
name: string
|
|
48
|
+
defaultBranch: string | null
|
|
49
|
+
private: boolean
|
|
50
|
+
/** Optional link to a board block this repo backs. */
|
|
51
|
+
blockId: string | null
|
|
52
|
+
/** Whether this repo is a monorepo hosting several services (each pinned to a subdirectory). */
|
|
53
|
+
isMonorepo?: boolean
|
|
54
|
+
syncedAt: number
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
/** One directory entry of a repo's tree, used by the monorepo service picker. */
|
|
58
|
+
export interface RepoTreeEntry {
|
|
59
|
+
/** Path relative to the repo root, e.g. `packages/api`. */
|
|
60
|
+
path: string
|
|
61
|
+
/** Base name, e.g. `api`. */
|
|
62
|
+
name: string
|
|
63
|
+
/** `file` | `dir` | `symlink` | `submodule`. */
|
|
64
|
+
type: string
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
export interface GitHubBranch {
|
|
68
|
+
repoGithubId: number
|
|
69
|
+
name: string
|
|
70
|
+
headSha: string
|
|
71
|
+
protected: boolean
|
|
72
|
+
syncedAt: number
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
/**
|
|
76
|
+
* A repo the connected installation can access, annotated with whether the
|
|
77
|
+
* current workspace links it. Drives the per-workspace repo picker — repos are
|
|
78
|
+
* linked explicitly per board, since the installation is shared across an
|
|
79
|
+
* account's workspaces.
|
|
80
|
+
*/
|
|
81
|
+
export interface GitHubAvailableRepo {
|
|
82
|
+
githubId: number
|
|
83
|
+
owner: string
|
|
84
|
+
name: string
|
|
85
|
+
defaultBranch: string | null
|
|
86
|
+
private: boolean
|
|
87
|
+
linked: boolean
|
|
88
|
+
/** Whether the (linked) repo is flagged as a monorepo. */
|
|
89
|
+
isMonorepo?: boolean
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
export type GitHubPullRequestState = 'open' | 'closed'
|
|
93
|
+
|
|
94
|
+
export interface GitHubPullRequest {
|
|
95
|
+
repoGithubId: number
|
|
96
|
+
number: number
|
|
97
|
+
githubId: number
|
|
98
|
+
title: string
|
|
99
|
+
state: GitHubPullRequestState
|
|
100
|
+
headRef: string | null
|
|
101
|
+
baseRef: string | null
|
|
102
|
+
headSha: string | null
|
|
103
|
+
merged: boolean
|
|
104
|
+
author: string | null
|
|
105
|
+
updatedAt: number | null
|
|
106
|
+
syncedAt: number
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
export type GitHubIssueState = 'open' | 'closed'
|
|
110
|
+
|
|
111
|
+
export interface GitHubIssue {
|
|
112
|
+
repoGithubId: number
|
|
113
|
+
number: number
|
|
114
|
+
githubId: number
|
|
115
|
+
title: string
|
|
116
|
+
state: GitHubIssueState
|
|
117
|
+
author: string | null
|
|
118
|
+
labels: string[]
|
|
119
|
+
updatedAt: number | null
|
|
120
|
+
syncedAt: number
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
// ---- request inputs -------------------------------------------------------
|
|
124
|
+
|
|
125
|
+
/** Trigger a resync. Defaults to an incremental resync of all tracked repos. */
|
|
126
|
+
export interface ResyncRequest {
|
|
127
|
+
/** Limit the resync to a single repo (by its GitHub numeric id). */
|
|
128
|
+
repoGithubId?: number
|
|
129
|
+
/** Run a full backfill (durable Workflow) instead of an incremental pass. */
|
|
130
|
+
full?: boolean
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
export interface CreateBranchInput {
|
|
134
|
+
name: string
|
|
135
|
+
fromSha: string
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
/** Body for programmatic repo creation (privileged App tier). */
|
|
139
|
+
export interface CreateRepoRequest {
|
|
140
|
+
/** A single GitHub name segment — no "owner/" prefix. */
|
|
141
|
+
name: string
|
|
142
|
+
private?: boolean
|
|
143
|
+
description?: string
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
/** The freshly-created repository returned by the create-repo endpoint. */
|
|
147
|
+
export interface CreatedRepo {
|
|
148
|
+
githubId: number
|
|
149
|
+
owner: string
|
|
150
|
+
name: string
|
|
151
|
+
defaultBranch: string | null
|
|
152
|
+
private: boolean
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
export interface CommitFilesInput {
|
|
156
|
+
branch: string
|
|
157
|
+
message: string
|
|
158
|
+
files: { path: string; content: string }[]
|
|
159
|
+
/** Parent commit to build on; defaults to the branch tip. */
|
|
160
|
+
baseSha?: string
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
export interface OpenPullRequestInput {
|
|
164
|
+
title: string
|
|
165
|
+
head: string
|
|
166
|
+
base: string
|
|
167
|
+
body?: string
|
|
168
|
+
draft?: boolean
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
export interface MergePullRequestInput {
|
|
172
|
+
method?: 'merge' | 'squash' | 'rebase'
|
|
173
|
+
}
|
package/app/types/services.ts
CHANGED
|
@@ -1,27 +1,27 @@
|
|
|
1
|
-
// In-org shared services. Mirrors the `@cat-factory/contracts` `services` wire schemas:
|
|
2
|
-
// a `Service` is the account-owned unit of work (a service frame + its subtree + repo),
|
|
3
|
-
// shared across the workspaces that *mount* it; a `WorkspaceMount` places a service onto a
|
|
4
|
-
// workspace board with that board's own frame layout override.
|
|
5
|
-
|
|
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
|
-
}
|
|
1
|
+
// In-org shared services. Mirrors the `@cat-factory/contracts` `services` wire schemas:
|
|
2
|
+
// a `Service` is the account-owned unit of work (a service frame + its subtree + repo),
|
|
3
|
+
// shared across the workspaces that *mount* it; a `WorkspaceMount` places a service onto a
|
|
4
|
+
// workspace board with that board's own frame layout override.
|
|
5
|
+
|
|
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
|
+
}
|