kanbo-cli 0.1.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 +79 -0
- package/dist/better-sqlite3-fU3G4xnX.cjs +2254 -0
- package/dist/better-sqlite3-fU3G4xnX.cjs.map +1 -0
- package/dist/cli.cjs +42949 -0
- package/dist/cli.cjs.map +1 -0
- package/dist/dist-Cd6wg8pp.cjs +942 -0
- package/dist/dist-Cd6wg8pp.cjs.map +1 -0
- package/dist/drizzle-postgres/0000_board.sql +135 -0
- package/dist/drizzle-postgres/0001_history_order.sql +2 -0
- package/dist/drizzle-postgres/0002_issue_pull_requests.sql +16 -0
- package/dist/drizzle-postgres/0003_milestone_start_date.sql +1 -0
- package/dist/drizzle-postgres/0004_status_entry_rules.sql +1 -0
- package/dist/drizzle-postgres/0005_run_external_session_ref.sql +1 -0
- package/dist/drizzle-postgres/README.md +61 -0
- package/dist/drizzle-postgres/meta/0000_snapshot.json +1078 -0
- package/dist/drizzle-postgres/meta/0001_snapshot.json +1090 -0
- package/dist/drizzle-postgres/meta/0002_snapshot.json +1239 -0
- package/dist/drizzle-postgres/meta/0003_snapshot.json +1245 -0
- package/dist/drizzle-postgres/meta/0004_snapshot.json +1251 -0
- package/dist/drizzle-postgres/meta/0005_snapshot.json +1257 -0
- package/dist/drizzle-postgres/meta/_journal.json +48 -0
- package/dist/drizzle-sqlite/0000_board.sql +133 -0
- package/dist/drizzle-sqlite/0001_issue_pull_requests.sql +15 -0
- package/dist/drizzle-sqlite/0002_milestone_start_date.sql +1 -0
- package/dist/drizzle-sqlite/0003_status_entry_rules.sql +1 -0
- package/dist/drizzle-sqlite/0004_run_external_session_ref.sql +1 -0
- package/dist/drizzle-sqlite/README.md +67 -0
- package/dist/drizzle-sqlite/meta/0000_snapshot.json +946 -0
- package/dist/drizzle-sqlite/meta/0001_snapshot.json +1054 -0
- package/dist/drizzle-sqlite/meta/0002_snapshot.json +1061 -0
- package/dist/drizzle-sqlite/meta/0003_snapshot.json +1068 -0
- package/dist/drizzle-sqlite/meta/0004_snapshot.json +1075 -0
- package/dist/drizzle-sqlite/meta/_journal.json +41 -0
- package/dist/lib/board-store-B16YarvX.d.mts +281 -0
- package/dist/lib/board-store-BHHo_ZlR.d.cts +281 -0
- package/dist/lib/index.cjs +340 -0
- package/dist/lib/index.cjs.map +1 -0
- package/dist/lib/index.d.cts +1608 -0
- package/dist/lib/index.d.mts +1608 -0
- package/dist/lib/index.mjs +284 -0
- package/dist/lib/index.mjs.map +1 -0
- package/dist/lib/manifest-C0EcwwgO.mjs +7866 -0
- package/dist/lib/manifest-C0EcwwgO.mjs.map +1 -0
- package/dist/lib/manifest-CpZOcB_6.cjs +8272 -0
- package/dist/lib/manifest-CpZOcB_6.cjs.map +1 -0
- package/dist/lib/mcp/index.cjs +184 -0
- package/dist/lib/mcp/index.cjs.map +1 -0
- package/dist/lib/mcp/index.d.cts +346 -0
- package/dist/lib/mcp/index.d.mts +346 -0
- package/dist/lib/mcp/index.mjs +173 -0
- package/dist/lib/mcp/index.mjs.map +1 -0
- package/dist/lib/migrate-BhYi9cXw.mjs +656 -0
- package/dist/lib/migrate-BhYi9cXw.mjs.map +1 -0
- package/dist/lib/migrate-DnMjTCvu.cjs +709 -0
- package/dist/lib/migrate-DnMjTCvu.cjs.map +1 -0
- package/dist/lib/migrations-path-CZxVOgeD.cjs +109 -0
- package/dist/lib/migrations-path-CZxVOgeD.cjs.map +1 -0
- package/dist/lib/migrations-path-Ciwan537.mjs +80 -0
- package/dist/lib/migrations-path-Ciwan537.mjs.map +1 -0
- package/dist/lib/postgres/index.cjs +56 -0
- package/dist/lib/postgres/index.cjs.map +1 -0
- package/dist/lib/postgres/index.d.cts +3403 -0
- package/dist/lib/postgres/index.d.mts +3403 -0
- package/dist/lib/postgres/index.mjs +35 -0
- package/dist/lib/postgres/index.mjs.map +1 -0
- package/dist/lib/roles.sql-B9rt-x4o.cjs +1033 -0
- package/dist/lib/roles.sql-B9rt-x4o.cjs.map +1 -0
- package/dist/lib/roles.sql-CvyCGt38.mjs +920 -0
- package/dist/lib/roles.sql-CvyCGt38.mjs.map +1 -0
- package/dist/lib/schema-epoch-ZyumVL_A.d.cts +16 -0
- package/dist/lib/schema-epoch-ZyumVL_A.d.mts +16 -0
- package/dist/lib/schema-fsHqNAip.d.cts +3612 -0
- package/dist/lib/schema-fsHqNAip.d.mts +3612 -0
- package/dist/lib/sqlite/index.cjs +23 -0
- package/dist/lib/sqlite/index.d.cts +175 -0
- package/dist/lib/sqlite/index.d.mts +175 -0
- package/dist/lib/sqlite/index.mjs +4 -0
- package/dist/lib/sqlite/schema.cjs +266 -0
- package/dist/lib/sqlite/schema.cjs.map +1 -0
- package/dist/lib/sqlite/schema.d.cts +2 -0
- package/dist/lib/sqlite/schema.d.mts +2 -0
- package/dist/lib/sqlite/schema.mjs +256 -0
- package/dist/lib/sqlite/schema.mjs.map +1 -0
- package/dist/lib/tool-names-9cmCn0gP.d.cts +112 -0
- package/dist/lib/tool-names-Dxg1UTUl.d.mts +112 -0
- package/dist/page/board.css +477 -0
- package/dist/page/board.js +2 -0
- package/drizzle-postgres/0000_board.sql +135 -0
- package/drizzle-postgres/0001_history_order.sql +2 -0
- package/drizzle-postgres/0002_issue_pull_requests.sql +16 -0
- package/drizzle-postgres/0003_milestone_start_date.sql +1 -0
- package/drizzle-postgres/0004_status_entry_rules.sql +1 -0
- package/drizzle-postgres/0005_run_external_session_ref.sql +1 -0
- package/drizzle-postgres/README.md +61 -0
- package/drizzle-postgres/meta/0000_snapshot.json +1078 -0
- package/drizzle-postgres/meta/0001_snapshot.json +1090 -0
- package/drizzle-postgres/meta/0002_snapshot.json +1239 -0
- package/drizzle-postgres/meta/0003_snapshot.json +1245 -0
- package/drizzle-postgres/meta/0004_snapshot.json +1251 -0
- package/drizzle-postgres/meta/0005_snapshot.json +1257 -0
- package/drizzle-postgres/meta/_journal.json +48 -0
- package/drizzle-sqlite/0000_board.sql +133 -0
- package/drizzle-sqlite/0001_issue_pull_requests.sql +15 -0
- package/drizzle-sqlite/0002_milestone_start_date.sql +1 -0
- package/drizzle-sqlite/0003_status_entry_rules.sql +1 -0
- package/drizzle-sqlite/0004_run_external_session_ref.sql +1 -0
- package/drizzle-sqlite/README.md +67 -0
- package/drizzle-sqlite/meta/0000_snapshot.json +946 -0
- package/drizzle-sqlite/meta/0001_snapshot.json +1054 -0
- package/drizzle-sqlite/meta/0002_snapshot.json +1061 -0
- package/drizzle-sqlite/meta/0003_snapshot.json +1068 -0
- package/drizzle-sqlite/meta/0004_snapshot.json +1075 -0
- package/drizzle-sqlite/meta/_journal.json +41 -0
- package/package.json +147 -0
|
@@ -0,0 +1,346 @@
|
|
|
1
|
+
import { s as IssueRun, t as Issue } from "../schema-fsHqNAip.mjs";
|
|
2
|
+
import { i as KanboToolName, n as KANBO_TOOL_NAMES, r as KanboToolCliEquivalent, s as EntryRule, t as KANBO_TOOL_CLI_EQUIVALENTS } from "../tool-names-Dxg1UTUl.mjs";
|
|
3
|
+
import { z } from "zod";
|
|
4
|
+
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
5
|
+
import { CallToolResult } from "@modelcontextprotocol/sdk/types.js";
|
|
6
|
+
//#region src/mcp/transport.d.ts
|
|
7
|
+
/**
|
|
8
|
+
* What the board's tools ask for, and what comes back.
|
|
9
|
+
*
|
|
10
|
+
* A tool knows one operation and nothing about how it is performed: the same
|
|
11
|
+
* `kanbo_card_move` runs against a server over HTTP inside an app's own MCP
|
|
12
|
+
* server, and against the board itself inside `kanbo mcp`, because both transports answer this interface. Which one a tool
|
|
13
|
+
* holds is the caller's decision, made once, and no tool can tell the
|
|
14
|
+
* difference.
|
|
15
|
+
*
|
|
16
|
+
* The workspace is not a parameter here. Each transport is built for one board
|
|
17
|
+
* — the CLI resolves it the way every `kanbo` command does, the server takes
|
|
18
|
+
* it from the runtime it was launched for — and a tool that could name a
|
|
19
|
+
* workspace could name one the agent was never given.
|
|
20
|
+
*/
|
|
21
|
+
/** A card, as a tool hands it to an agent. */
|
|
22
|
+
interface KanboCardResult {
|
|
23
|
+
/** The issue key, which is also the row id: `MAN-012`. */
|
|
24
|
+
id: string;
|
|
25
|
+
number: number;
|
|
26
|
+
title: string;
|
|
27
|
+
description: string | null;
|
|
28
|
+
/** The column's name, `null` when the card sits in no column. */
|
|
29
|
+
column: string | null;
|
|
30
|
+
/** The same column as the slug `kanbo_card_move` takes. */
|
|
31
|
+
columnSlug: string | null;
|
|
32
|
+
statusLine: string | null;
|
|
33
|
+
waitingFor: 'human' | null;
|
|
34
|
+
priority: Issue['priority'];
|
|
35
|
+
labels: string[];
|
|
36
|
+
executionMode: Issue['executionMode'];
|
|
37
|
+
parentIssueId: string | null;
|
|
38
|
+
/** Every run the card has ever had; the next launch is attempt `attemptCount + 1`. */
|
|
39
|
+
attemptCount: number;
|
|
40
|
+
/** The run going on right now, `null` when nobody is working on the card. */
|
|
41
|
+
activeRun: KanboActiveRunResult | null;
|
|
42
|
+
updatedAt: number;
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* A card read on its own, as `kanbo_card_get` hands it to an agent: the card,
|
|
46
|
+
* and the sub-cards under it in board order. Its parent is `parentIssueId`.
|
|
47
|
+
*/
|
|
48
|
+
interface KanboCardDetailResult extends KanboCardResult {
|
|
49
|
+
subCards: Pick<KanboCardResult, 'id' | 'title' | 'columnSlug'>[];
|
|
50
|
+
}
|
|
51
|
+
/** The run of a card that is going on right now. */
|
|
52
|
+
interface KanboActiveRunResult {
|
|
53
|
+
id: string;
|
|
54
|
+
agentName: string;
|
|
55
|
+
state: IssueRun['state'];
|
|
56
|
+
executionMode: IssueRun['executionMode'];
|
|
57
|
+
branch: string | null;
|
|
58
|
+
startedAt: number;
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* A column of the board, as a tool hands it to an agent.
|
|
62
|
+
*
|
|
63
|
+
* What the column means is its description, written for exactly this reader;
|
|
64
|
+
* the category behind it is the board's own classification of the column and says
|
|
65
|
+
* nothing an agent moving a card can act on.
|
|
66
|
+
*/
|
|
67
|
+
interface KanboColumnResult {
|
|
68
|
+
id: string;
|
|
69
|
+
name: string;
|
|
70
|
+
/** What `kanbo_card_move` calls this column. */
|
|
71
|
+
slug: string;
|
|
72
|
+
description: string | null;
|
|
73
|
+
order: number;
|
|
74
|
+
/** What a card must satisfy before an agent may move it here; empty for nothing. */
|
|
75
|
+
entryRules: EntryRule[];
|
|
76
|
+
}
|
|
77
|
+
/**
|
|
78
|
+
* A milestone read as a sprint, as `kanbo_sprints` hands it to an agent: its
|
|
79
|
+
* dates (unix seconds), whether it is the one running now, and how many of its
|
|
80
|
+
* cards are still open and how many are done.
|
|
81
|
+
*/
|
|
82
|
+
interface KanboSprintResult {
|
|
83
|
+
id: string;
|
|
84
|
+
title: string;
|
|
85
|
+
status: 'open' | 'closed';
|
|
86
|
+
startDate: number | null;
|
|
87
|
+
dueDate: number | null;
|
|
88
|
+
current: boolean;
|
|
89
|
+
openCards: number;
|
|
90
|
+
doneCards: number;
|
|
91
|
+
}
|
|
92
|
+
/** A comment, as `kanbo_card_comment` hands it back. */
|
|
93
|
+
interface KanboCommentResult {
|
|
94
|
+
id: string;
|
|
95
|
+
issueId: string;
|
|
96
|
+
content: string;
|
|
97
|
+
createdAt: number;
|
|
98
|
+
}
|
|
99
|
+
/** A pull request a card names, as the pull-request tools hand it back. */
|
|
100
|
+
interface KanboPullRequestResult {
|
|
101
|
+
id: string;
|
|
102
|
+
issueId: string;
|
|
103
|
+
owner: string;
|
|
104
|
+
repo: string;
|
|
105
|
+
number: number;
|
|
106
|
+
url: string;
|
|
107
|
+
createdAt: number;
|
|
108
|
+
}
|
|
109
|
+
/** One launch of a card, as the run tools hand it back. */
|
|
110
|
+
interface KanboRunResult {
|
|
111
|
+
id: string;
|
|
112
|
+
issueId: string;
|
|
113
|
+
agentName: string;
|
|
114
|
+
state: IssueRun['state'];
|
|
115
|
+
executionMode: IssueRun['executionMode'];
|
|
116
|
+
branch: string | null;
|
|
117
|
+
startedAt: number;
|
|
118
|
+
endedAt: number | null;
|
|
119
|
+
/** Where the caller's own log of this run lives, if it said — `claude:<id>` or `codex:<id>` (ruling 7-1), else `null`. */
|
|
120
|
+
externalSessionRef: string | null;
|
|
121
|
+
}
|
|
122
|
+
/**
|
|
123
|
+
* What each tool asks its transport for. They are named rather than written
|
|
124
|
+
* inline so the interface below reads as a list of operations, and kept inside
|
|
125
|
+
* this module because a caller reaches them through `KanboToolTransport`.
|
|
126
|
+
*/
|
|
127
|
+
/** What `kanbo_card_create` needs to open a card. */
|
|
128
|
+
interface KanboCardCreateInput {
|
|
129
|
+
/** Optional: a card without one is titled with its own key. */
|
|
130
|
+
title?: string;
|
|
131
|
+
description?: string;
|
|
132
|
+
/** The column to open it in, by slug or name; the board's first column when absent. */
|
|
133
|
+
column?: string;
|
|
134
|
+
/** The card this one belongs under, making it a sub-card. */
|
|
135
|
+
parent?: string;
|
|
136
|
+
executionMode?: Issue['executionMode'];
|
|
137
|
+
}
|
|
138
|
+
/** The fields `kanbo_card_update` may change. */
|
|
139
|
+
interface KanboCardUpdateInput {
|
|
140
|
+
card: string;
|
|
141
|
+
title?: string;
|
|
142
|
+
description?: string;
|
|
143
|
+
priority?: Issue['priority'];
|
|
144
|
+
labels?: string[];
|
|
145
|
+
executionMode?: Issue['executionMode'];
|
|
146
|
+
}
|
|
147
|
+
/** What `kanbo_run_start` records about a launch. */
|
|
148
|
+
interface KanboRunStartInput {
|
|
149
|
+
card: string;
|
|
150
|
+
agent: string;
|
|
151
|
+
branch?: string;
|
|
152
|
+
executionMode?: Issue['executionMode'];
|
|
153
|
+
/** Where the agent's own log of this run lives: `claude:<id>` or `codex:<id>` (ruling 7-1). */
|
|
154
|
+
session?: string;
|
|
155
|
+
}
|
|
156
|
+
/** How `kanbo_run_finish` says a run ended. */
|
|
157
|
+
interface KanboRunFinishInput {
|
|
158
|
+
run: string;
|
|
159
|
+
state: 'finished' | 'failed' | 'stopped';
|
|
160
|
+
errorText?: string;
|
|
161
|
+
}
|
|
162
|
+
/** One method per thing the board's tools do. Both transports answer all of it. */
|
|
163
|
+
interface KanboToolTransport {
|
|
164
|
+
prime: () => Promise<{
|
|
165
|
+
text: string;
|
|
166
|
+
}>;
|
|
167
|
+
ready: (input: {
|
|
168
|
+
limit?: number;
|
|
169
|
+
}) => Promise<KanboCardResult[]>;
|
|
170
|
+
columns: () => Promise<KanboColumnResult[]>;
|
|
171
|
+
sprints: () => Promise<KanboSprintResult[]>;
|
|
172
|
+
cardGet: (input: {
|
|
173
|
+
card: string;
|
|
174
|
+
}) => Promise<KanboCardDetailResult>;
|
|
175
|
+
cardList: (input: {
|
|
176
|
+
column?: string;
|
|
177
|
+
limit?: number;
|
|
178
|
+
}) => Promise<KanboCardResult[]>;
|
|
179
|
+
cardCreate: (input: KanboCardCreateInput) => Promise<KanboCardResult>;
|
|
180
|
+
cardUpdate: (input: KanboCardUpdateInput) => Promise<KanboCardResult>;
|
|
181
|
+
cardMove: (input: {
|
|
182
|
+
card: string;
|
|
183
|
+
column: string;
|
|
184
|
+
}) => Promise<KanboCardResult>;
|
|
185
|
+
cardComment: (input: {
|
|
186
|
+
card: string;
|
|
187
|
+
content: string;
|
|
188
|
+
}) => Promise<KanboCommentResult>;
|
|
189
|
+
cardLinkPullRequest: (input: {
|
|
190
|
+
card: string;
|
|
191
|
+
url: string;
|
|
192
|
+
}) => Promise<KanboPullRequestResult>;
|
|
193
|
+
cardPullRequests: (input: {
|
|
194
|
+
card: string;
|
|
195
|
+
}) => Promise<KanboPullRequestResult[]>;
|
|
196
|
+
statusLine: (input: {
|
|
197
|
+
card: string;
|
|
198
|
+
text: string;
|
|
199
|
+
}) => Promise<KanboCardResult>;
|
|
200
|
+
waitApproval: (input: {
|
|
201
|
+
card: string;
|
|
202
|
+
text?: string;
|
|
203
|
+
}) => Promise<KanboCardResult>;
|
|
204
|
+
runStart: (input: KanboRunStartInput) => Promise<KanboRunResult>;
|
|
205
|
+
runFinish: (input: KanboRunFinishInput) => Promise<KanboRunResult>;
|
|
206
|
+
}
|
|
207
|
+
//#endregion
|
|
208
|
+
//#region src/mcp/http-transport.d.ts
|
|
209
|
+
/**
|
|
210
|
+
* The board's tools, run against a server of the board's `/issues` routes over
|
|
211
|
+
* HTTP.
|
|
212
|
+
*
|
|
213
|
+
* This is the transport an app's own MCP server holds, and going
|
|
214
|
+
* through the server rather than the file is the whole point of it: the server
|
|
215
|
+
* is the board's single writing connection, it resolves the calling agent from
|
|
216
|
+
* the session the request carries, it registers the await that wakes a session
|
|
217
|
+
* whose card is waiting for a person, and its board version is what every open
|
|
218
|
+
* host window is watching.
|
|
219
|
+
*
|
|
220
|
+
* How the request is made is the host's: it passes `request`, which is where
|
|
221
|
+
* the server URL, the session header and the error contract live. This package
|
|
222
|
+
* knows only the routes and the shapes that come back.
|
|
223
|
+
*/
|
|
224
|
+
/** One call to the server. The host owns the URL, the headers and what a failure means. */
|
|
225
|
+
type KanboHttpRequest = (method: 'GET' | 'POST' | 'PATCH', path: string, body?: Record<string, unknown>) => Promise<unknown>;
|
|
226
|
+
/** How to reach the server, and which board to ask it about. */
|
|
227
|
+
interface KanboHttpTransportInput {
|
|
228
|
+
request: KanboHttpRequest;
|
|
229
|
+
/**
|
|
230
|
+
* The workspace every question is about, asked per call rather than captured:
|
|
231
|
+
* the host learns it when a runtime is launched, which can be after the tools
|
|
232
|
+
* were built.
|
|
233
|
+
*/
|
|
234
|
+
workspaceId: () => string;
|
|
235
|
+
}
|
|
236
|
+
declare function createHttpTransport(input: KanboHttpTransportInput): KanboToolTransport;
|
|
237
|
+
//#endregion
|
|
238
|
+
//#region src/mcp/resources.d.ts
|
|
239
|
+
/** The URI a client reads the manifest as JSON from. */
|
|
240
|
+
declare const KANBO_CAPABILITIES_RESOURCE_URI = "kanbo://capabilities";
|
|
241
|
+
/** The URI a client reads the same manifest from, laid out as Markdown. */
|
|
242
|
+
declare const KANBO_CAPABILITIES_MARKDOWN_RESOURCE_URI = "kanbo://capabilities.md";
|
|
243
|
+
/**
|
|
244
|
+
* The board's own capabilities manifest, as two MCP resources rather than a
|
|
245
|
+
* tool: a client reads it once, before it ever calls a board tool, to learn
|
|
246
|
+
* what the tools take and what the board promises and refuses. `kanbo
|
|
247
|
+
* capabilities` prints the same two shapes from a terminal.
|
|
248
|
+
*
|
|
249
|
+
* Registered on the server `kanbo mcp` builds for itself rather than on
|
|
250
|
+
* `registerKanboTools` — the function an app's own MCP server calls to add the
|
|
251
|
+
* board's tools to an inventory of its own — so an agent inside such an app
|
|
252
|
+
* reads the manifest the way that app documents everything else, and a client
|
|
253
|
+
* with no server around it still gets the manifest from the one server it is
|
|
254
|
+
* talking to.
|
|
255
|
+
*/
|
|
256
|
+
declare function registerKanboCapabilitiesResources(server: McpServer): void;
|
|
257
|
+
//#endregion
|
|
258
|
+
//#region src/mcp/tools/tool.d.ts
|
|
259
|
+
/**
|
|
260
|
+
* What every board tool is, and the one way all of them answer.
|
|
261
|
+
*
|
|
262
|
+
* A tool is a name, a schema and exactly one call into the transport. It never
|
|
263
|
+
* throws: a board rule the caller broke, a card that is not there, a server
|
|
264
|
+
* that refused — all of it comes back as a tool error the model can read and
|
|
265
|
+
* act on, because an exception out of a handler reaches the model as a
|
|
266
|
+
* transport failure with nothing in it to correct.
|
|
267
|
+
*/
|
|
268
|
+
/** The zod raw shape `McpServer.registerTool` takes. */
|
|
269
|
+
type KanboToolShape = Record<string, z.ZodType>;
|
|
270
|
+
/**
|
|
271
|
+
* What a tool call answers with: the result, or the reason it did not happen.
|
|
272
|
+
*
|
|
273
|
+
* It is the MCP result the protocol defines, narrowed to what the board's tools
|
|
274
|
+
* actually produce — one block of text, and whether that text is a failure.
|
|
275
|
+
*/
|
|
276
|
+
interface KanboToolResult extends CallToolResult {
|
|
277
|
+
content: {
|
|
278
|
+
type: 'text';
|
|
279
|
+
text: string;
|
|
280
|
+
}[];
|
|
281
|
+
isError?: true;
|
|
282
|
+
}
|
|
283
|
+
/** One tool of the board, ready to register against any transport. */
|
|
284
|
+
interface KanboTool {
|
|
285
|
+
name: KanboToolName;
|
|
286
|
+
title: string;
|
|
287
|
+
description: string;
|
|
288
|
+
inputSchema: KanboToolShape;
|
|
289
|
+
run: (transport: KanboToolTransport, input: unknown) => Promise<KanboToolResult>;
|
|
290
|
+
}
|
|
291
|
+
//#endregion
|
|
292
|
+
//#region src/mcp/tools/index.d.ts
|
|
293
|
+
/**
|
|
294
|
+
* Every tool the board has, in the order it declares them.
|
|
295
|
+
*
|
|
296
|
+
* The list is the board's, not a server's: the same sixteen are registered
|
|
297
|
+
* whether they run against a server or against the board directly, and the
|
|
298
|
+
* only thing a host decides is which of them it publishes.
|
|
299
|
+
*/
|
|
300
|
+
declare const KANBO_TOOLS: readonly KanboTool[];
|
|
301
|
+
/** What a host decides about the board's tools. */
|
|
302
|
+
interface KanboToolOptions {
|
|
303
|
+
/** Publish `kanbo_run_start` and `kanbo_run_finish`. False for a host that manages runs itself. */
|
|
304
|
+
includeRunTools: boolean;
|
|
305
|
+
}
|
|
306
|
+
/** One tool bound to a transport, ready for an MCP server to register. */
|
|
307
|
+
interface KanboToolRegistration {
|
|
308
|
+
name: KanboToolName;
|
|
309
|
+
register: (server: McpServer) => void;
|
|
310
|
+
}
|
|
311
|
+
/**
|
|
312
|
+
* The board's tools, bound to the transport they run against.
|
|
313
|
+
*
|
|
314
|
+
* Nothing here reaches the board: the registration is what an MCP server needs
|
|
315
|
+
* to publish the tool, and the transport is only called when a client actually
|
|
316
|
+
* calls one.
|
|
317
|
+
*/
|
|
318
|
+
declare function buildKanboTools(transport: KanboToolTransport, options: KanboToolOptions): KanboToolRegistration[];
|
|
319
|
+
//#endregion
|
|
320
|
+
//#region src/mcp/server.d.ts
|
|
321
|
+
/** The name a client sees this server under. */
|
|
322
|
+
declare const KANBO_MCP_SERVER_NAME = "kanbo";
|
|
323
|
+
/**
|
|
324
|
+
* Add the board's tools to a server that already exists.
|
|
325
|
+
*
|
|
326
|
+
* This is how an app with an MCP server of its own carries them: one server holds every
|
|
327
|
+
* tool an agent has, and the board's are part of that inventory rather than a
|
|
328
|
+
* second server the runtime would have to be told about.
|
|
329
|
+
*/
|
|
330
|
+
declare function registerKanboTools(server: McpServer, transport: KanboToolTransport, options: KanboToolOptions): void;
|
|
331
|
+
/**
|
|
332
|
+
* A server that is only the board — what `kanbo mcp` serves to a client that
|
|
333
|
+
* brings no board tools of its own: an editor, an agent CLI, another machine.
|
|
334
|
+
*
|
|
335
|
+
* It carries the capabilities manifest as two resources, on top of the tools
|
|
336
|
+
* `registerKanboTools` adds — a client here has no other way to learn the
|
|
337
|
+
* board's rules, its canonical strings or its CLI equivalents before it calls
|
|
338
|
+
* anything. An app's own MCP server does not get them through this
|
|
339
|
+
* function: it documents its capabilities its own way, and adding a second
|
|
340
|
+
* `kanbo://` resource namespace to an inventory that is not only the board's
|
|
341
|
+
* is a decision for that server to make, not this one.
|
|
342
|
+
*/
|
|
343
|
+
declare function createKanboMcpServer(transport: KanboToolTransport, options: KanboToolOptions): McpServer;
|
|
344
|
+
//#endregion
|
|
345
|
+
export { KANBO_CAPABILITIES_MARKDOWN_RESOURCE_URI, KANBO_CAPABILITIES_RESOURCE_URI, KANBO_MCP_SERVER_NAME, KANBO_TOOLS, KANBO_TOOL_CLI_EQUIVALENTS, KANBO_TOOL_NAMES, type KanboActiveRunResult, type KanboCardResult, type KanboColumnResult, type KanboCommentResult, type KanboHttpRequest, type KanboHttpTransportInput, type KanboPullRequestResult, type KanboRunResult, type KanboTool, type KanboToolCliEquivalent, type KanboToolName, type KanboToolOptions, type KanboToolRegistration, type KanboToolResult, type KanboToolTransport, buildKanboTools, createHttpTransport, createKanboMcpServer, registerKanboCapabilitiesResources, registerKanboTools };
|
|
346
|
+
//# sourceMappingURL=index.d.mts.map
|
|
@@ -0,0 +1,173 @@
|
|
|
1
|
+
import { U as normalizeStatusName, _ as projectKanboRun, c as registerKanboTools, d as KANBO_CAPABILITIES_MARKDOWN_RESOURCE_URI, f as KANBO_CAPABILITIES_RESOURCE_URI, g as projectKanboPullRequest, h as projectKanboColumn, i as KANBO_TOOL_NAMES, l as KANBO_TOOLS, m as projectKanboCard, o as KANBO_MCP_SERVER_NAME, p as registerKanboCapabilitiesResources, r as KANBO_TOOL_CLI_EQUIVALENTS, s as createKanboMcpServer, u as buildKanboTools, v as projectKanboSprint, y as projectKanboSubCard } from "../manifest-C0EcwwgO.mjs";
|
|
2
|
+
import { a as BoardError } from "../migrations-path-Ciwan537.mjs";
|
|
3
|
+
import { z } from "zod";
|
|
4
|
+
//#region src/mcp/http-transport.ts
|
|
5
|
+
const IssueSchema = z.object({
|
|
6
|
+
id: z.string(),
|
|
7
|
+
number: z.number(),
|
|
8
|
+
title: z.string(),
|
|
9
|
+
description: z.string().nullable(),
|
|
10
|
+
statusId: z.string().nullable(),
|
|
11
|
+
statusLine: z.string().nullable(),
|
|
12
|
+
waitingFor: z.literal("human").nullable(),
|
|
13
|
+
priority: z.enum([
|
|
14
|
+
"none",
|
|
15
|
+
"low",
|
|
16
|
+
"medium",
|
|
17
|
+
"high",
|
|
18
|
+
"urgent"
|
|
19
|
+
]),
|
|
20
|
+
labels: z.array(z.string()),
|
|
21
|
+
executionMode: z.enum(["worktree", "main"]),
|
|
22
|
+
parentIssueId: z.string().nullable(),
|
|
23
|
+
updatedAt: z.number(),
|
|
24
|
+
attemptCount: z.number(),
|
|
25
|
+
activeRun: z.object({
|
|
26
|
+
id: z.string(),
|
|
27
|
+
agentName: z.string(),
|
|
28
|
+
state: z.enum([
|
|
29
|
+
"running",
|
|
30
|
+
"finished",
|
|
31
|
+
"failed",
|
|
32
|
+
"stopped"
|
|
33
|
+
]),
|
|
34
|
+
executionMode: z.enum(["worktree", "main"]),
|
|
35
|
+
branch: z.string().nullable(),
|
|
36
|
+
startedAt: z.number()
|
|
37
|
+
}).nullable()
|
|
38
|
+
});
|
|
39
|
+
const StatusSchema = z.object({
|
|
40
|
+
id: z.string(),
|
|
41
|
+
name: z.string(),
|
|
42
|
+
description: z.string().nullable(),
|
|
43
|
+
order: z.number(),
|
|
44
|
+
entryRules: z.union([z.string(), z.array(z.string())]).nullish()
|
|
45
|
+
});
|
|
46
|
+
const CommentSchema = z.object({
|
|
47
|
+
id: z.string(),
|
|
48
|
+
issueId: z.string(),
|
|
49
|
+
content: z.string(),
|
|
50
|
+
createdAt: z.number()
|
|
51
|
+
});
|
|
52
|
+
const RunSchema = z.object({
|
|
53
|
+
id: z.string(),
|
|
54
|
+
issueId: z.string(),
|
|
55
|
+
agentName: z.string(),
|
|
56
|
+
state: z.enum([
|
|
57
|
+
"running",
|
|
58
|
+
"finished",
|
|
59
|
+
"failed",
|
|
60
|
+
"stopped"
|
|
61
|
+
]),
|
|
62
|
+
executionMode: z.enum(["worktree", "main"]),
|
|
63
|
+
branch: z.string().nullable(),
|
|
64
|
+
startedAt: z.number(),
|
|
65
|
+
endedAt: z.number().nullable(),
|
|
66
|
+
externalSessionRef: z.string().nullish()
|
|
67
|
+
});
|
|
68
|
+
const PullRequestSchema = z.object({
|
|
69
|
+
id: z.string(),
|
|
70
|
+
issueId: z.string(),
|
|
71
|
+
owner: z.string(),
|
|
72
|
+
repo: z.string(),
|
|
73
|
+
number: z.number(),
|
|
74
|
+
url: z.string(),
|
|
75
|
+
createdAt: z.number()
|
|
76
|
+
});
|
|
77
|
+
const SprintSchema = z.object({
|
|
78
|
+
id: z.string(),
|
|
79
|
+
title: z.string(),
|
|
80
|
+
status: z.enum(["open", "closed"]),
|
|
81
|
+
startDate: z.number().nullable(),
|
|
82
|
+
dueDate: z.number().nullable(),
|
|
83
|
+
current: z.boolean(),
|
|
84
|
+
cards: z.object({
|
|
85
|
+
open: z.number(),
|
|
86
|
+
done: z.number()
|
|
87
|
+
})
|
|
88
|
+
});
|
|
89
|
+
const PrimeSchema = z.object({ text: z.string() });
|
|
90
|
+
function createHttpTransport(input) {
|
|
91
|
+
const { request } = input;
|
|
92
|
+
async function readColumns() {
|
|
93
|
+
return z.array(StatusSchema).parse(await request("GET", `/issues/statuses?workspaceId=${encodeURIComponent(input.workspaceId())}`)).map(projectKanboColumn);
|
|
94
|
+
}
|
|
95
|
+
/**
|
|
96
|
+
* One card as a tool prints it. The response carries the column as a foreign
|
|
97
|
+
* key, so the columns are read alongside it to turn that back into the slug
|
|
98
|
+
* an agent moves a card by.
|
|
99
|
+
*/
|
|
100
|
+
async function projectOne(response) {
|
|
101
|
+
return projectKanboCard(IssueSchema.parse(response), await readColumns());
|
|
102
|
+
}
|
|
103
|
+
/** The column a caller named, by slug or by name, as the id the list route filters on. */
|
|
104
|
+
function requireColumn(columns, nameOrId) {
|
|
105
|
+
const slug = normalizeStatusName(nameOrId);
|
|
106
|
+
const column = columns.find((candidate) => candidate.id === nameOrId || candidate.slug === slug);
|
|
107
|
+
if (!column) throw new BoardError("issue_status_not_found", {
|
|
108
|
+
statusName: nameOrId,
|
|
109
|
+
normalizedStatusName: slug
|
|
110
|
+
});
|
|
111
|
+
return column;
|
|
112
|
+
}
|
|
113
|
+
return {
|
|
114
|
+
prime: async () => PrimeSchema.parse(await request("GET", `/issues/prime?workspaceId=${encodeURIComponent(input.workspaceId())}`)),
|
|
115
|
+
ready: async ({ limit }) => {
|
|
116
|
+
const query = new URLSearchParams({ workspaceId: input.workspaceId() });
|
|
117
|
+
if (limit !== void 0) query.set("limit", String(limit));
|
|
118
|
+
const cards = z.array(IssueSchema).parse(await request("GET", `/issues/ready?${query.toString()}`));
|
|
119
|
+
const columns = await readColumns();
|
|
120
|
+
return cards.map((row) => projectKanboCard(row, columns));
|
|
121
|
+
},
|
|
122
|
+
columns: readColumns,
|
|
123
|
+
sprints: async () => z.array(SprintSchema).parse(await request("GET", `/issues/sprints?workspaceId=${encodeURIComponent(input.workspaceId())}`)).map(projectKanboSprint),
|
|
124
|
+
cardGet: async ({ card }) => {
|
|
125
|
+
const found = IssueSchema.parse(await request("GET", `/issues/${encodeURIComponent(card)}`));
|
|
126
|
+
const columns = await readColumns();
|
|
127
|
+
const query = new URLSearchParams({
|
|
128
|
+
workspaceId: input.workspaceId(),
|
|
129
|
+
parentIssueId: found.id
|
|
130
|
+
});
|
|
131
|
+
const subCards = z.array(IssueSchema).parse(await request("GET", `/issues/?${query.toString()}`));
|
|
132
|
+
return {
|
|
133
|
+
...projectKanboCard(found, columns),
|
|
134
|
+
subCards: subCards.map((row) => projectKanboSubCard(row, columns))
|
|
135
|
+
};
|
|
136
|
+
},
|
|
137
|
+
cardList: async ({ column, limit }) => {
|
|
138
|
+
const columns = await readColumns();
|
|
139
|
+
const query = new URLSearchParams({ workspaceId: input.workspaceId() });
|
|
140
|
+
if (column) query.set("statusId", requireColumn(columns, column).id);
|
|
141
|
+
return z.array(IssueSchema).parse(await request("GET", `/issues/?${query.toString()}`)).slice(0, limit ?? Number.POSITIVE_INFINITY).map((row) => projectKanboCard(row, columns));
|
|
142
|
+
},
|
|
143
|
+
cardCreate: async ({ title, description, column, parent, executionMode }) => await projectOne(await request("POST", "/issues/", {
|
|
144
|
+
workspaceId: input.workspaceId(),
|
|
145
|
+
...title !== void 0 ? { title } : {},
|
|
146
|
+
...description !== void 0 ? { description } : {},
|
|
147
|
+
...column !== void 0 ? { statusName: column } : {},
|
|
148
|
+
...parent !== void 0 ? { parentIssueId: parent } : {},
|
|
149
|
+
...executionMode !== void 0 ? { executionMode } : {}
|
|
150
|
+
})),
|
|
151
|
+
cardUpdate: async ({ card, ...patch }) => await projectOne(await request("PATCH", `/issues/${encodeURIComponent(card)}`, patch)),
|
|
152
|
+
cardMove: async ({ card, column }) => await projectOne(await request("PATCH", `/issues/${encodeURIComponent(card)}/status/${encodeURIComponent(column)}`)),
|
|
153
|
+
cardComment: async ({ card, content }) => CommentSchema.parse(await request("POST", `/issues/${encodeURIComponent(card)}/comments`, { content })),
|
|
154
|
+
cardLinkPullRequest: async ({ card, url }) => projectKanboPullRequest(PullRequestSchema.parse(await request("POST", `/issues/${encodeURIComponent(card)}/pull-requests`, { url }))),
|
|
155
|
+
cardPullRequests: async ({ card }) => z.array(PullRequestSchema).parse(await request("GET", `/issues/${encodeURIComponent(card)}/pull-requests`)).map(projectKanboPullRequest),
|
|
156
|
+
statusLine: async ({ card, text }) => await projectOne(await request("PATCH", `/issues/${encodeURIComponent(card)}/status-line`, { statusLine: text })),
|
|
157
|
+
waitApproval: async ({ card, text }) => await projectOne(await request("POST", `/issues/${encodeURIComponent(card)}/wait-approval`, text === void 0 ? {} : { statusLine: text })),
|
|
158
|
+
runStart: async ({ card, agent, branch, executionMode, session }) => projectKanboRun(RunSchema.parse(await request("POST", `/issues/${encodeURIComponent(card)}/runs`, {
|
|
159
|
+
agentName: agent,
|
|
160
|
+
...branch !== void 0 ? { branch } : {},
|
|
161
|
+
...executionMode !== void 0 ? { executionMode } : {},
|
|
162
|
+
...session !== void 0 ? { externalSessionRef: session } : {}
|
|
163
|
+
}))),
|
|
164
|
+
runFinish: async ({ run, state, errorText }) => projectKanboRun(RunSchema.parse(await request("PATCH", `/issues/runs/${encodeURIComponent(run)}`, {
|
|
165
|
+
state,
|
|
166
|
+
...errorText !== void 0 ? { errorText } : {}
|
|
167
|
+
})))
|
|
168
|
+
};
|
|
169
|
+
}
|
|
170
|
+
//#endregion
|
|
171
|
+
export { KANBO_CAPABILITIES_MARKDOWN_RESOURCE_URI, KANBO_CAPABILITIES_RESOURCE_URI, KANBO_MCP_SERVER_NAME, KANBO_TOOLS, KANBO_TOOL_CLI_EQUIVALENTS, KANBO_TOOL_NAMES, buildKanboTools, createHttpTransport, createKanboMcpServer, registerKanboCapabilitiesResources, registerKanboTools };
|
|
172
|
+
|
|
173
|
+
//# sourceMappingURL=index.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.mjs","names":[],"sources":["../../../src/mcp/http-transport.ts"],"sourcesContent":["import { z } from 'zod'\n\nimport { BoardError } from '../domain/errors'\nimport { normalizeStatusName } from '../domain/status-name'\nimport type { KanboCardResult, KanboColumnResult, KanboToolTransport } from './transport'\nimport {\n projectKanboCard,\n projectKanboColumn,\n projectKanboPullRequest,\n projectKanboRun,\n projectKanboSprint,\n projectKanboSubCard,\n} from './transport'\n\n/**\n * The board's tools, run against a server of the board's `/issues` routes over\n * HTTP.\n *\n * This is the transport an app's own MCP server holds, and going\n * through the server rather than the file is the whole point of it: the server\n * is the board's single writing connection, it resolves the calling agent from\n * the session the request carries, it registers the await that wakes a session\n * whose card is waiting for a person, and its board version is what every open\n * host window is watching.\n *\n * How the request is made is the host's: it passes `request`, which is where\n * the server URL, the session header and the error contract live. This package\n * knows only the routes and the shapes that come back.\n */\n\n/** One call to the server. The host owns the URL, the headers and what a failure means. */\nexport type KanboHttpRequest = (\n method: 'GET' | 'POST' | 'PATCH',\n path: string,\n body?: Record<string, unknown>,\n) => Promise<unknown>\n\n/** How to reach the server, and which board to ask it about. */\nexport interface KanboHttpTransportInput {\n request: KanboHttpRequest\n /**\n * The workspace every question is about, asked per call rather than captured:\n * the host learns it when a runtime is launched, which can be after the tools\n * were built.\n */\n workspaceId: () => string\n}\n\nconst IssueSchema = z.object({\n id: z.string(),\n number: z.number(),\n title: z.string(),\n description: z.string().nullable(),\n statusId: z.string().nullable(),\n statusLine: z.string().nullable(),\n waitingFor: z.literal('human').nullable(),\n priority: z.enum(['none', 'low', 'medium', 'high', 'urgent']),\n labels: z.array(z.string()),\n executionMode: z.enum(['worktree', 'main']),\n parentIssueId: z.string().nullable(),\n updatedAt: z.number(),\n attemptCount: z.number(),\n activeRun: z.object({\n id: z.string(),\n agentName: z.string(),\n state: z.enum(['running', 'finished', 'failed', 'stopped']),\n executionMode: z.enum(['worktree', 'main']),\n branch: z.string().nullable(),\n startedAt: z.number(),\n }).nullable(),\n})\n\nconst StatusSchema = z.object({\n id: z.string(),\n name: z.string(),\n description: z.string().nullable(),\n order: z.number(),\n // The column's entry rules, as the row stores them (a JSON array in text) or\n // already read into a list; absent from a server that predates them.\n entryRules: z.union([z.string(), z.array(z.string())]).nullish(),\n})\n\nconst CommentSchema = z.object({\n id: z.string(),\n issueId: z.string(),\n content: z.string(),\n createdAt: z.number(),\n})\n\nconst RunSchema = z.object({\n id: z.string(),\n issueId: z.string(),\n agentName: z.string(),\n state: z.enum(['running', 'finished', 'failed', 'stopped']),\n executionMode: z.enum(['worktree', 'main']),\n branch: z.string().nullable(),\n startedAt: z.number(),\n endedAt: z.number().nullable(),\n // Absent from a server that predates it (ruling 7-1).\n externalSessionRef: z.string().nullish(),\n})\n\nconst PullRequestSchema = z.object({\n id: z.string(),\n issueId: z.string(),\n owner: z.string(),\n repo: z.string(),\n number: z.number(),\n url: z.string(),\n createdAt: z.number(),\n})\n\nconst SprintSchema = z.object({\n id: z.string(),\n title: z.string(),\n status: z.enum(['open', 'closed']),\n startDate: z.number().nullable(),\n dueDate: z.number().nullable(),\n current: z.boolean(),\n cards: z.object({ open: z.number(), done: z.number() }),\n})\n\nconst PrimeSchema = z.object({ text: z.string() })\n\nexport function createHttpTransport(input: KanboHttpTransportInput): KanboToolTransport {\n const { request } = input\n\n async function readColumns(): Promise<KanboColumnResult[]> {\n const statuses = z.array(StatusSchema).parse(\n await request('GET', `/issues/statuses?workspaceId=${encodeURIComponent(input.workspaceId())}`),\n )\n return statuses.map(projectKanboColumn)\n }\n\n /**\n * One card as a tool prints it. The response carries the column as a foreign\n * key, so the columns are read alongside it to turn that back into the slug\n * an agent moves a card by.\n */\n async function projectOne(response: unknown): Promise<KanboCardResult> {\n return projectKanboCard(IssueSchema.parse(response), await readColumns())\n }\n\n /** The column a caller named, by slug or by name, as the id the list route filters on. */\n function requireColumn(columns: KanboColumnResult[], nameOrId: string): KanboColumnResult {\n const slug = normalizeStatusName(nameOrId)\n const column = columns.find(candidate => candidate.id === nameOrId || candidate.slug === slug)\n if (!column) {\n throw new BoardError('issue_status_not_found', { statusName: nameOrId, normalizedStatusName: slug })\n }\n return column\n }\n\n return {\n prime: async () => PrimeSchema.parse(\n await request('GET', `/issues/prime?workspaceId=${encodeURIComponent(input.workspaceId())}`),\n ),\n\n ready: async ({ limit }) => {\n const query = new URLSearchParams({ workspaceId: input.workspaceId() })\n if (limit !== undefined) {\n query.set('limit', String(limit))\n }\n const cards = z.array(IssueSchema).parse(await request('GET', `/issues/ready?${query.toString()}`))\n const columns = await readColumns()\n return cards.map(row => projectKanboCard(row, columns))\n },\n\n columns: readColumns,\n\n sprints: async () => z.array(SprintSchema).parse(\n await request('GET', `/issues/sprints?workspaceId=${encodeURIComponent(input.workspaceId())}`),\n ).map(projectKanboSprint),\n\n cardGet: async ({ card }) => {\n const found = IssueSchema.parse(await request('GET', `/issues/${encodeURIComponent(card)}`))\n const columns = await readColumns()\n const query = new URLSearchParams({ workspaceId: input.workspaceId(), parentIssueId: found.id })\n const subCards = z.array(IssueSchema).parse(await request('GET', `/issues/?${query.toString()}`))\n return {\n ...projectKanboCard(found, columns),\n subCards: subCards.map(row => projectKanboSubCard(row, columns)),\n }\n },\n\n cardList: async ({ column, limit }) => {\n const columns = await readColumns()\n const query = new URLSearchParams({ workspaceId: input.workspaceId() })\n if (column) {\n query.set('statusId', requireColumn(columns, column).id)\n }\n const cards = z.array(IssueSchema).parse(await request('GET', `/issues/?${query.toString()}`))\n return cards.slice(0, limit ?? Number.POSITIVE_INFINITY).map(row => projectKanboCard(row, columns))\n },\n\n cardCreate: async ({ title, description, column, parent, executionMode }) => await projectOne(\n await request('POST', '/issues/', {\n workspaceId: input.workspaceId(),\n ...(title !== undefined ? { title } : {}),\n ...(description !== undefined ? { description } : {}),\n ...(column !== undefined ? { statusName: column } : {}),\n ...(parent !== undefined ? { parentIssueId: parent } : {}),\n ...(executionMode !== undefined ? { executionMode } : {}),\n }),\n ),\n\n cardUpdate: async ({ card, ...patch }) => await projectOne(\n await request('PATCH', `/issues/${encodeURIComponent(card)}`, patch),\n ),\n\n cardMove: async ({ card, column }) => await projectOne(\n await request('PATCH', `/issues/${encodeURIComponent(card)}/status/${encodeURIComponent(column)}`),\n ),\n\n cardComment: async ({ card, content }) => CommentSchema.parse(\n await request('POST', `/issues/${encodeURIComponent(card)}/comments`, { content }),\n ),\n\n cardLinkPullRequest: async ({ card, url }) => projectKanboPullRequest(PullRequestSchema.parse(\n await request('POST', `/issues/${encodeURIComponent(card)}/pull-requests`, { url }),\n )),\n\n cardPullRequests: async ({ card }) => z.array(PullRequestSchema).parse(\n await request('GET', `/issues/${encodeURIComponent(card)}/pull-requests`),\n ).map(projectKanboPullRequest),\n\n statusLine: async ({ card, text }) => await projectOne(\n await request('PATCH', `/issues/${encodeURIComponent(card)}/status-line`, { statusLine: text }),\n ),\n\n waitApproval: async ({ card, text }) => await projectOne(\n await request(\n 'POST',\n `/issues/${encodeURIComponent(card)}/wait-approval`,\n text === undefined ? {} : { statusLine: text },\n ),\n ),\n\n runStart: async ({ card, agent, branch, executionMode, session }) => projectKanboRun(RunSchema.parse(\n await request('POST', `/issues/${encodeURIComponent(card)}/runs`, {\n agentName: agent,\n ...(branch !== undefined ? { branch } : {}),\n ...(executionMode !== undefined ? { executionMode } : {}),\n ...(session !== undefined ? { externalSessionRef: session } : {}),\n }),\n )),\n\n runFinish: async ({ run, state, errorText }) => projectKanboRun(RunSchema.parse(\n await request('PATCH', `/issues/runs/${encodeURIComponent(run)}`, {\n state,\n ...(errorText !== undefined ? { errorText } : {}),\n }),\n )),\n }\n}\n"],"mappings":"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"}
|