@cat-factory/app 0.6.0 → 0.7.2
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 +109 -4
- package/app/components/layout/SideBar.vue +11 -0
- package/app/components/observability/StepMetricsBar.vue +102 -102
- 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/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/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
|
+
}
|
package/app/types/tasks.ts
CHANGED
|
@@ -1,82 +1,82 @@
|
|
|
1
|
-
// ---------------------------------------------------------------------------
|
|
2
|
-
// Task-source integration. Individual issues imported from external task
|
|
3
|
-
// trackers (Jira, …) can be attached to a board task as agent context. These
|
|
4
|
-
// mirror the `@cat-factory/contracts` task schemas; the abstraction is
|
|
5
|
-
// source-agnostic, keyed by `source`. Unlike document sources there is no
|
|
6
|
-
// plan/spawn — an issue is linked for context, never expanded into structure.
|
|
7
|
-
// ---------------------------------------------------------------------------
|
|
8
|
-
|
|
9
|
-
import type { CredentialField } from './documents'
|
|
10
|
-
|
|
11
|
-
/** The external task trackers cat-factory can link to. */
|
|
12
|
-
export type TaskSourceKind = 'jira' | 'github'
|
|
13
|
-
|
|
14
|
-
export type { CredentialField }
|
|
15
|
-
|
|
16
|
-
/** A source's self-description: drives the generic connect + import UI. */
|
|
17
|
-
export interface TaskSourceDescriptor {
|
|
18
|
-
source: TaskSourceKind
|
|
19
|
-
label: string
|
|
20
|
-
/** Lucide icon name for the source. */
|
|
21
|
-
icon: string
|
|
22
|
-
credentialFields: CredentialField[]
|
|
23
|
-
refLabel: string
|
|
24
|
-
refPlaceholder: string
|
|
25
|
-
/** Whether the source supports searching its catalogue by title/content. */
|
|
26
|
-
searchable?: boolean
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
/** A workspace's connection to a task source (never carries credentials). */
|
|
30
|
-
export interface TaskConnection {
|
|
31
|
-
source: TaskSourceKind
|
|
32
|
-
/** Human-friendly label for what we're connected to (site URL). */
|
|
33
|
-
label: string
|
|
34
|
-
/** When the connection was established (epoch ms). */
|
|
35
|
-
connectedAt: number
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
/** A single comment on an issue, with its body as lightweight Markdown. */
|
|
39
|
-
export interface TaskComment {
|
|
40
|
-
author: string
|
|
41
|
-
createdAt: string
|
|
42
|
-
body: string
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
/** An issue imported from a source into the workspace, as a structured record. */
|
|
46
|
-
export interface SourceTask {
|
|
47
|
-
source: TaskSourceKind
|
|
48
|
-
/** The source's canonical key for the issue (e.g. `PROJ-123`). */
|
|
49
|
-
externalId: string
|
|
50
|
-
title: string
|
|
51
|
-
url: string
|
|
52
|
-
/** Workflow status name, e.g. `In Progress`. */
|
|
53
|
-
status: string
|
|
54
|
-
/** Issue type name, e.g. `Bug`. */
|
|
55
|
-
type: string
|
|
56
|
-
/** Assignee display name, or null when unassigned. */
|
|
57
|
-
assignee: string | null
|
|
58
|
-
/** Priority name, or null when none. */
|
|
59
|
-
priority: string | null
|
|
60
|
-
labels: string[]
|
|
61
|
-
/** Issue description as lightweight Markdown. */
|
|
62
|
-
description: string
|
|
63
|
-
comments: TaskComment[]
|
|
64
|
-
/** Short plain-text preview of the issue. */
|
|
65
|
-
excerpt: string
|
|
66
|
-
/** The board block this issue is attached to as context, if any. */
|
|
67
|
-
linkedBlockId: string | null
|
|
68
|
-
syncedAt: number
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
/** A lean hit from searching a tracker's issues (not yet imported). */
|
|
72
|
-
export interface TaskSearchResult {
|
|
73
|
-
source: TaskSourceKind
|
|
74
|
-
/** The source's canonical key for the issue (re-usable as an import ref). */
|
|
75
|
-
externalId: string
|
|
76
|
-
title: string
|
|
77
|
-
url: string
|
|
78
|
-
/** Workflow status name, e.g. `In Progress` (may be empty). */
|
|
79
|
-
status: string
|
|
80
|
-
/** Short plain-text preview (may be empty). */
|
|
81
|
-
excerpt: string
|
|
82
|
-
}
|
|
1
|
+
// ---------------------------------------------------------------------------
|
|
2
|
+
// Task-source integration. Individual issues imported from external task
|
|
3
|
+
// trackers (Jira, …) can be attached to a board task as agent context. These
|
|
4
|
+
// mirror the `@cat-factory/contracts` task schemas; the abstraction is
|
|
5
|
+
// source-agnostic, keyed by `source`. Unlike document sources there is no
|
|
6
|
+
// plan/spawn — an issue is linked for context, never expanded into structure.
|
|
7
|
+
// ---------------------------------------------------------------------------
|
|
8
|
+
|
|
9
|
+
import type { CredentialField } from './documents'
|
|
10
|
+
|
|
11
|
+
/** The external task trackers cat-factory can link to. */
|
|
12
|
+
export type TaskSourceKind = 'jira' | 'github'
|
|
13
|
+
|
|
14
|
+
export type { CredentialField }
|
|
15
|
+
|
|
16
|
+
/** A source's self-description: drives the generic connect + import UI. */
|
|
17
|
+
export interface TaskSourceDescriptor {
|
|
18
|
+
source: TaskSourceKind
|
|
19
|
+
label: string
|
|
20
|
+
/** Lucide icon name for the source. */
|
|
21
|
+
icon: string
|
|
22
|
+
credentialFields: CredentialField[]
|
|
23
|
+
refLabel: string
|
|
24
|
+
refPlaceholder: string
|
|
25
|
+
/** Whether the source supports searching its catalogue by title/content. */
|
|
26
|
+
searchable?: boolean
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
/** A workspace's connection to a task source (never carries credentials). */
|
|
30
|
+
export interface TaskConnection {
|
|
31
|
+
source: TaskSourceKind
|
|
32
|
+
/** Human-friendly label for what we're connected to (site URL). */
|
|
33
|
+
label: string
|
|
34
|
+
/** When the connection was established (epoch ms). */
|
|
35
|
+
connectedAt: number
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
/** A single comment on an issue, with its body as lightweight Markdown. */
|
|
39
|
+
export interface TaskComment {
|
|
40
|
+
author: string
|
|
41
|
+
createdAt: string
|
|
42
|
+
body: string
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
/** An issue imported from a source into the workspace, as a structured record. */
|
|
46
|
+
export interface SourceTask {
|
|
47
|
+
source: TaskSourceKind
|
|
48
|
+
/** The source's canonical key for the issue (e.g. `PROJ-123`). */
|
|
49
|
+
externalId: string
|
|
50
|
+
title: string
|
|
51
|
+
url: string
|
|
52
|
+
/** Workflow status name, e.g. `In Progress`. */
|
|
53
|
+
status: string
|
|
54
|
+
/** Issue type name, e.g. `Bug`. */
|
|
55
|
+
type: string
|
|
56
|
+
/** Assignee display name, or null when unassigned. */
|
|
57
|
+
assignee: string | null
|
|
58
|
+
/** Priority name, or null when none. */
|
|
59
|
+
priority: string | null
|
|
60
|
+
labels: string[]
|
|
61
|
+
/** Issue description as lightweight Markdown. */
|
|
62
|
+
description: string
|
|
63
|
+
comments: TaskComment[]
|
|
64
|
+
/** Short plain-text preview of the issue. */
|
|
65
|
+
excerpt: string
|
|
66
|
+
/** The board block this issue is attached to as context, if any. */
|
|
67
|
+
linkedBlockId: string | null
|
|
68
|
+
syncedAt: number
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
/** A lean hit from searching a tracker's issues (not yet imported). */
|
|
72
|
+
export interface TaskSearchResult {
|
|
73
|
+
source: TaskSourceKind
|
|
74
|
+
/** The source's canonical key for the issue (re-usable as an import ref). */
|
|
75
|
+
externalId: string
|
|
76
|
+
title: string
|
|
77
|
+
url: string
|
|
78
|
+
/** Workflow status name, e.g. `In Progress` (may be empty). */
|
|
79
|
+
status: string
|
|
80
|
+
/** Short plain-text preview (may be empty). */
|
|
81
|
+
excerpt: string
|
|
82
|
+
}
|
package/app/types/tracker.ts
CHANGED
|
@@ -1,18 +1,27 @@
|
|
|
1
|
-
// Issue-tracker selection shapes, mirroring `@cat-factory/contracts` (tracker.ts).
|
|
2
|
-
// A workspace designates one tracker — GitHub Issues or Jira — where the tech-debt
|
|
3
|
-
// recurring pipeline files its ticket before implementation starts.
|
|
4
|
-
|
|
5
|
-
export type TrackerKind = 'github' | 'jira'
|
|
6
|
-
|
|
7
|
-
export interface TrackerSettings {
|
|
8
|
-
/** The selected tracker, or null when none is configured. */
|
|
9
|
-
tracker: TrackerKind | null
|
|
10
|
-
/** Jira project key new tickets are filed under (e.g. 'ENG'); null unless Jira. */
|
|
11
|
-
jiraProjectKey: string | null
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
1
|
+
// Issue-tracker selection shapes, mirroring `@cat-factory/contracts` (tracker.ts).
|
|
2
|
+
// A workspace designates one tracker — GitHub Issues or Jira — where the tech-debt
|
|
3
|
+
// recurring pipeline files its ticket before implementation starts.
|
|
4
|
+
|
|
5
|
+
export type TrackerKind = 'github' | 'jira'
|
|
6
|
+
|
|
7
|
+
export interface TrackerSettings {
|
|
8
|
+
/** The selected tracker, or null when none is configured. */
|
|
9
|
+
tracker: TrackerKind | null
|
|
10
|
+
/** Jira project key new tickets are filed under (e.g. 'ENG'); null unless Jira. */
|
|
11
|
+
jiraProjectKey: string | null
|
|
12
|
+
/** Writeback: comment on a task's linked issue when its PR opens. Per-task overridable. */
|
|
13
|
+
writebackCommentOnPrOpen: boolean
|
|
14
|
+
/** Writeback: comment + close a task's linked issue as resolved when its PR merges. */
|
|
15
|
+
writebackResolveOnMerge: boolean
|
|
16
|
+
updatedAt: number
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
export interface PutTrackerSettingsInput {
|
|
20
|
+
tracker: TrackerKind | null
|
|
21
|
+
jiraProjectKey?: string | null
|
|
22
|
+
writebackCommentOnPrOpen?: boolean
|
|
23
|
+
writebackResolveOnMerge?: boolean
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
/** Per-task writeback override; absent ⇒ inherit the workspace setting. */
|
|
27
|
+
export type WritebackOverride = 'on' | 'off'
|