kanban-lite 1.2.9 → 1.2.11
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/dist/cli.js +78 -14
- package/dist/extension.js +57 -8
- package/dist/mcp-server.js +61 -5
- package/dist/sdk/index.cjs +46 -2
- package/dist/sdk/index.mjs +45 -2
- package/dist/sdk/sdk/KanbanSDK.d.ts +3 -2
- package/dist/sdk/sdk/index.d.ts +1 -1
- package/dist/sdk/shared/config.d.ts +2 -0
- package/dist/sdk/shared/types.d.ts +23 -0
- package/dist/standalone-webview/index.js +63 -63
- package/dist/standalone-webview/index.js.map +1 -1
- package/dist/standalone.js +9 -3
- package/package.json +1 -1
- package/src/cli/index.test.ts +65 -3
- package/src/cli/index.ts +16 -9
- package/src/extension/KanbanPanel.ts +6 -6
- package/src/extension/SidebarViewProvider.ts +6 -2
- package/src/mcp-server/index.ts +23 -4
- package/src/sdk/KanbanSDK.ts +3 -2
- package/src/sdk/__tests__/board-actions.test.ts +29 -0
- package/src/sdk/index.ts +1 -1
- package/src/sdk/modules/boards.ts +2 -0
- package/src/shared/config.ts +2 -0
- package/src/shared/types.test.ts +27 -0
- package/src/shared/types.ts +76 -0
- package/src/standalone/internal/openapi-spec.ts +3 -1
- package/src/webview/App.tsx +4 -2
- package/src/webview/components/CardEditor.test.tsx +5 -4
- package/src/webview/components/CardEditor.tsx +3 -2
- package/src/webview/components/CardItem.test.tsx +14 -3
- package/src/webview/components/CardItem.tsx +2 -11
package/dist/cli.js
CHANGED
|
@@ -42,6 +42,44 @@ function getTitleFromContent(content) {
|
|
|
42
42
|
const firstLine = content.split("\n").map((l) => l.trim()).find((l) => l.length > 0);
|
|
43
43
|
return firstLine || "Untitled";
|
|
44
44
|
}
|
|
45
|
+
function getMetadataPathValue(metadata, path24) {
|
|
46
|
+
if (!metadata || !path24.trim())
|
|
47
|
+
return void 0;
|
|
48
|
+
return path24.split(".").reduce((current, key) => {
|
|
49
|
+
if (current === null || current === void 0 || typeof current !== "object") {
|
|
50
|
+
return void 0;
|
|
51
|
+
}
|
|
52
|
+
return current[key];
|
|
53
|
+
}, metadata);
|
|
54
|
+
}
|
|
55
|
+
function stringifyDisplayTitlePrefix(value) {
|
|
56
|
+
if (value === null || value === void 0)
|
|
57
|
+
return null;
|
|
58
|
+
if (typeof value === "string") {
|
|
59
|
+
const trimmed = value.trim();
|
|
60
|
+
return trimmed.length > 0 ? trimmed : null;
|
|
61
|
+
}
|
|
62
|
+
if (typeof value === "number" || typeof value === "boolean" || typeof value === "bigint") {
|
|
63
|
+
return String(value);
|
|
64
|
+
}
|
|
65
|
+
if (Array.isArray(value)) {
|
|
66
|
+
const parts = value.map((item) => stringifyDisplayTitlePrefix(item)).filter((item) => Boolean(item));
|
|
67
|
+
return parts.length > 0 ? parts.join(", ") : null;
|
|
68
|
+
}
|
|
69
|
+
if (typeof value === "object") {
|
|
70
|
+
const json2 = JSON.stringify(value);
|
|
71
|
+
return json2 && json2 !== "{}" && json2 !== "[]" ? json2 : null;
|
|
72
|
+
}
|
|
73
|
+
return null;
|
|
74
|
+
}
|
|
75
|
+
function getDisplayTitleFromContent(content, metadata, titleFields) {
|
|
76
|
+
const title = getTitleFromContent(content);
|
|
77
|
+
if (!titleFields || titleFields.length === 0) {
|
|
78
|
+
return title;
|
|
79
|
+
}
|
|
80
|
+
const prefixes = titleFields.map((field) => stringifyDisplayTitlePrefix(getMetadataPathValue(metadata, field))).filter((value) => Boolean(value));
|
|
81
|
+
return prefixes.length > 0 ? `${prefixes.join(" ")} ${title}` : title;
|
|
82
|
+
}
|
|
45
83
|
function generateSlug(title) {
|
|
46
84
|
return title.toLowerCase().replace(/[^a-z0-9\s-]/g, "").replace(/\s+/g, "-").replace(/-+/g, "-").replace(/^-|-$/g, "").slice(0, 50) || "card";
|
|
47
85
|
}
|
|
@@ -6515,6 +6553,7 @@ function listBoards(ctx) {
|
|
|
6515
6553
|
columns: board.columns,
|
|
6516
6554
|
actions: board.actions,
|
|
6517
6555
|
metadata: board.metadata,
|
|
6556
|
+
title: board.title,
|
|
6518
6557
|
forms: config2.forms
|
|
6519
6558
|
}));
|
|
6520
6559
|
}
|
|
@@ -6589,6 +6628,8 @@ function updateBoard(ctx, { boardId, updates }) {
|
|
|
6589
6628
|
board.defaultPriority = updates.defaultPriority;
|
|
6590
6629
|
if (updates.metadata !== void 0)
|
|
6591
6630
|
board.metadata = updates.metadata;
|
|
6631
|
+
if (updates.title !== void 0)
|
|
6632
|
+
board.title = updates.title;
|
|
6592
6633
|
writeConfig(ctx.workspaceRoot, config2);
|
|
6593
6634
|
return board;
|
|
6594
6635
|
}
|
|
@@ -26310,7 +26351,7 @@ var init_KanbanSDK = __esm({
|
|
|
26310
26351
|
* Lists all boards defined in the workspace configuration.
|
|
26311
26352
|
*
|
|
26312
26353
|
* @returns An array of {@link BoardInfo} objects containing each board's
|
|
26313
|
-
|
|
26354
|
+
* `id`, `name`, optional `description`, and display-title metadata config.
|
|
26314
26355
|
*
|
|
26315
26356
|
* @example
|
|
26316
26357
|
* ```ts
|
|
@@ -26379,7 +26420,7 @@ var init_KanbanSDK = __esm({
|
|
|
26379
26420
|
* Retrieves the full configuration for a specific board.
|
|
26380
26421
|
*
|
|
26381
26422
|
* @param boardId - The ID of the board to retrieve.
|
|
26382
|
-
|
|
26423
|
+
* @returns The {@link BoardConfig} object containing columns, settings, metadata, and display-title metadata config.
|
|
26383
26424
|
* @throws {Error} If the board does not exist.
|
|
26384
26425
|
*
|
|
26385
26426
|
* @example
|
|
@@ -26404,6 +26445,7 @@ var init_KanbanSDK = __esm({
|
|
|
26404
26445
|
* @param updates.columns - Replacement column definitions.
|
|
26405
26446
|
* @param updates.defaultStatus - New default status for new cards.
|
|
26406
26447
|
* @param updates.defaultPriority - New default priority for new cards.
|
|
26448
|
+
* @param updates.title - Ordered metadata keys whose values should prefix rendered card titles.
|
|
26407
26449
|
* @returns The updated {@link BoardConfig} object.
|
|
26408
26450
|
* @throws {Error} If the board does not exist.
|
|
26409
26451
|
*
|
|
@@ -42879,6 +42921,17 @@ async function buildMcpCardStateMutationModel(sdk, unread) {
|
|
|
42879
42921
|
}
|
|
42880
42922
|
};
|
|
42881
42923
|
}
|
|
42924
|
+
function getBoardTitleFieldsForMcp(sdk, boardId) {
|
|
42925
|
+
const config2 = sdk.getConfigSnapshot();
|
|
42926
|
+
const resolvedBoardId = boardId || config2.defaultBoard;
|
|
42927
|
+
return config2.boards[resolvedBoardId]?.title;
|
|
42928
|
+
}
|
|
42929
|
+
function decorateMcpCardTitle(card, titleFields) {
|
|
42930
|
+
return {
|
|
42931
|
+
...card,
|
|
42932
|
+
title: getDisplayTitleFromContent(card.content, card.metadata, titleFields)
|
|
42933
|
+
};
|
|
42934
|
+
}
|
|
42882
42935
|
function registerCardStateMcpTools(server, options) {
|
|
42883
42936
|
const registeredNames = [
|
|
42884
42937
|
"get_card_state_status",
|
|
@@ -43097,6 +43150,7 @@ async function main() {
|
|
|
43097
43150
|
sort: external_exports.enum(["created:asc", "created:desc", "modified:asc", "modified:desc"]).optional().describe("Sort order: created:asc, created:desc, modified:asc, or modified:desc. Defaults to board order.")
|
|
43098
43151
|
},
|
|
43099
43152
|
async ({ boardId, status, priority, assignee, label, labelGroup, includeDeleted, searchQuery, fuzzy, metaFilter, sort }) => {
|
|
43153
|
+
const titleFields = getBoardTitleFieldsForMcp(sdk, boardId);
|
|
43100
43154
|
let cards = await sdk.listCards(void 0, boardId, {
|
|
43101
43155
|
metaFilter: metaFilter && Object.keys(metaFilter).length > 0 ? metaFilter : void 0,
|
|
43102
43156
|
sort: sort || void 0,
|
|
@@ -43119,7 +43173,7 @@ async function main() {
|
|
|
43119
43173
|
}
|
|
43120
43174
|
const summary = cards.map((c) => ({
|
|
43121
43175
|
id: c.id,
|
|
43122
|
-
title:
|
|
43176
|
+
title: getDisplayTitleFromContent(c.content, c.metadata, titleFields),
|
|
43123
43177
|
status: c.status,
|
|
43124
43178
|
priority: c.priority,
|
|
43125
43179
|
assignee: c.assignee,
|
|
@@ -43160,10 +43214,11 @@ async function main() {
|
|
|
43160
43214
|
};
|
|
43161
43215
|
}
|
|
43162
43216
|
}
|
|
43217
|
+
const titleFields = getBoardTitleFieldsForMcp(sdk, card.boardId ?? boardId);
|
|
43163
43218
|
return {
|
|
43164
43219
|
content: [{
|
|
43165
43220
|
type: "text",
|
|
43166
|
-
text: JSON.stringify(card, null, 2)
|
|
43221
|
+
text: JSON.stringify(decorateMcpCardTitle(card, titleFields), null, 2)
|
|
43167
43222
|
}]
|
|
43168
43223
|
};
|
|
43169
43224
|
}
|
|
@@ -43176,10 +43231,11 @@ async function main() {
|
|
|
43176
43231
|
},
|
|
43177
43232
|
async ({ boardId }) => {
|
|
43178
43233
|
const card = await sdk.getActiveCard(boardId);
|
|
43234
|
+
const titleFields = card ? getBoardTitleFieldsForMcp(sdk, card.boardId ?? boardId) : void 0;
|
|
43179
43235
|
return {
|
|
43180
43236
|
content: [{
|
|
43181
43237
|
type: "text",
|
|
43182
|
-
text: JSON.stringify(card, null, 2)
|
|
43238
|
+
text: JSON.stringify(card ? decorateMcpCardTitle(card, titleFields) : null, null, 2)
|
|
43183
43239
|
}]
|
|
43184
43240
|
};
|
|
43185
43241
|
}
|
|
@@ -88350,6 +88406,8 @@ var init_openapi_spec = __esm({
|
|
|
88350
88406
|
name: { type: "string" },
|
|
88351
88407
|
description: { type: "string" },
|
|
88352
88408
|
columns: { type: "array", items: { $ref: "#/components/schemas/Column" } },
|
|
88409
|
+
metadata: { type: "array", items: { type: "string" }, description: "Board metadata keys pinned in the card detail panel." },
|
|
88410
|
+
title: { type: "array", items: { type: "string" }, description: "Ordered metadata keys whose rendered values prefix user-visible card titles." },
|
|
88353
88411
|
defaultStatus: { type: "string" },
|
|
88354
88412
|
defaultPriority: { type: "string", enum: ["critical", "high", "medium", "low"] }
|
|
88355
88413
|
}
|
|
@@ -88436,7 +88494,7 @@ var init_openapi_spec = __esm({
|
|
|
88436
88494
|
"application/json": {
|
|
88437
88495
|
schema: {
|
|
88438
88496
|
type: "object",
|
|
88439
|
-
description: "Any subset of board config fields: `name`, `description`, `columns`, `defaultStatus`, `defaultPriority`."
|
|
88497
|
+
description: "Any subset of board config fields: `name`, `description`, `columns`, `metadata`, `title`, `defaultStatus`, `defaultPriority`."
|
|
88440
88498
|
}
|
|
88441
88499
|
}
|
|
88442
88500
|
}
|
|
@@ -98614,14 +98672,17 @@ function printCardStateMutationModel(label, payload) {
|
|
|
98614
98672
|
cardState: payload.cardState
|
|
98615
98673
|
});
|
|
98616
98674
|
}
|
|
98617
|
-
function
|
|
98618
|
-
const
|
|
98675
|
+
function getBoardTitleFieldsForCli(sdk, boardId) {
|
|
98676
|
+
const config2 = sdk.getConfigSnapshot();
|
|
98677
|
+
const resolvedBoardId = boardId || config2.defaultBoard;
|
|
98678
|
+
return config2.boards[resolvedBoardId]?.title;
|
|
98679
|
+
}
|
|
98680
|
+
function formatCardRow(c, title = getTitleFromContent(c.content)) {
|
|
98619
98681
|
const truncTitle = title.length > 40 ? title.slice(0, 37) + "..." : title;
|
|
98620
98682
|
const assignee = c.assignee || "-";
|
|
98621
98683
|
return ` ${bold(c.id.slice(0, 30).padEnd(30))} ${colorStatus(c.status.padEnd(12))} ${colorPriority(c.priority.padEnd(8))} ${assignee.padEnd(12)} ${truncTitle}`;
|
|
98622
98684
|
}
|
|
98623
|
-
function formatCardDetail(c) {
|
|
98624
|
-
const title = getTitleFromContent(c.content);
|
|
98685
|
+
function formatCardDetail(c, title = getTitleFromContent(c.content)) {
|
|
98625
98686
|
const lines = [
|
|
98626
98687
|
`${bold(title)}`,
|
|
98627
98688
|
"",
|
|
@@ -98652,6 +98713,7 @@ function formatCardDetail(c) {
|
|
|
98652
98713
|
}
|
|
98653
98714
|
async function cmdList(sdk, flags) {
|
|
98654
98715
|
const boardId = getBoardId(flags);
|
|
98716
|
+
const boardTitleFields = getBoardTitleFieldsForCli(sdk, boardId);
|
|
98655
98717
|
const searchQuery = typeof flags.search === "string" ? flags.search : void 0;
|
|
98656
98718
|
const fuzzy = flags.fuzzy === true;
|
|
98657
98719
|
const metaFilter = Array.isArray(flags.meta) ? (() => {
|
|
@@ -98712,13 +98774,14 @@ async function cmdList(sdk, flags) {
|
|
|
98712
98774
|
console.log(` ${dim("ID".padEnd(30))} ${dim("STATUS".padEnd(12))} ${dim("PRIORITY".padEnd(8))} ${dim("ASSIGNEE".padEnd(12))} ${dim("TITLE")}`);
|
|
98713
98775
|
console.log(dim(" " + "-".repeat(90)));
|
|
98714
98776
|
for (const c of cards) {
|
|
98715
|
-
console.log(formatCardRow(c));
|
|
98777
|
+
console.log(formatCardRow(c, getDisplayTitleFromContent(c.content, c.metadata, boardTitleFields)));
|
|
98716
98778
|
}
|
|
98717
98779
|
console.log(dim(`
|
|
98718
98780
|
${cards.length} card(s)`));
|
|
98719
98781
|
}
|
|
98720
98782
|
async function cmdActive(sdk, flags) {
|
|
98721
98783
|
const boardId = getBoardId(flags);
|
|
98784
|
+
const boardTitleFields = getBoardTitleFieldsForCli(sdk, boardId);
|
|
98722
98785
|
const card = await sdk.getActiveCard(boardId);
|
|
98723
98786
|
if (flags.json) {
|
|
98724
98787
|
console.log(JSON.stringify(card, null, 2));
|
|
@@ -98728,7 +98791,7 @@ async function cmdActive(sdk, flags) {
|
|
|
98728
98791
|
console.log(dim(" No active card."));
|
|
98729
98792
|
return;
|
|
98730
98793
|
}
|
|
98731
|
-
console.log(formatCardDetail(card));
|
|
98794
|
+
console.log(formatCardDetail(card, getDisplayTitleFromContent(card.content, card.metadata, boardTitleFields)));
|
|
98732
98795
|
}
|
|
98733
98796
|
async function cmdShow(sdk, positional, flags) {
|
|
98734
98797
|
const cardId = positional[0];
|
|
@@ -98737,6 +98800,7 @@ async function cmdShow(sdk, positional, flags) {
|
|
|
98737
98800
|
process.exit(1);
|
|
98738
98801
|
}
|
|
98739
98802
|
const boardId = getBoardId(flags);
|
|
98803
|
+
const boardTitleFields = getBoardTitleFieldsForCli(sdk, boardId);
|
|
98740
98804
|
const card = await sdk.getCard(cardId, boardId);
|
|
98741
98805
|
if (!card) {
|
|
98742
98806
|
const all = await sdk.listCards(void 0, boardId);
|
|
@@ -98745,7 +98809,7 @@ async function cmdShow(sdk, positional, flags) {
|
|
|
98745
98809
|
if (flags.json) {
|
|
98746
98810
|
console.log(JSON.stringify(matches[0], null, 2));
|
|
98747
98811
|
} else {
|
|
98748
|
-
console.log(formatCardDetail(matches[0]));
|
|
98812
|
+
console.log(formatCardDetail(matches[0], getDisplayTitleFromContent(matches[0].content, matches[0].metadata, boardTitleFields)));
|
|
98749
98813
|
}
|
|
98750
98814
|
return;
|
|
98751
98815
|
} else if (matches.length > 1) {
|
|
@@ -98760,7 +98824,7 @@ async function cmdShow(sdk, positional, flags) {
|
|
|
98760
98824
|
if (flags.json) {
|
|
98761
98825
|
console.log(JSON.stringify(card, null, 2));
|
|
98762
98826
|
} else {
|
|
98763
|
-
console.log(formatCardDetail(card));
|
|
98827
|
+
console.log(formatCardDetail(card, getDisplayTitleFromContent(card.content, card.metadata, boardTitleFields)));
|
|
98764
98828
|
}
|
|
98765
98829
|
}
|
|
98766
98830
|
async function cmdAdd(sdk, flags) {
|
package/dist/extension.js
CHANGED
|
@@ -65170,6 +65170,44 @@ function getTitleFromContent(content) {
|
|
|
65170
65170
|
const firstLine = content.split("\n").map((l) => l.trim()).find((l) => l.length > 0);
|
|
65171
65171
|
return firstLine || "Untitled";
|
|
65172
65172
|
}
|
|
65173
|
+
function getMetadataPathValue(metadata, path24) {
|
|
65174
|
+
if (!metadata || !path24.trim())
|
|
65175
|
+
return void 0;
|
|
65176
|
+
return path24.split(".").reduce((current, key) => {
|
|
65177
|
+
if (current === null || current === void 0 || typeof current !== "object") {
|
|
65178
|
+
return void 0;
|
|
65179
|
+
}
|
|
65180
|
+
return current[key];
|
|
65181
|
+
}, metadata);
|
|
65182
|
+
}
|
|
65183
|
+
function stringifyDisplayTitlePrefix(value) {
|
|
65184
|
+
if (value === null || value === void 0)
|
|
65185
|
+
return null;
|
|
65186
|
+
if (typeof value === "string") {
|
|
65187
|
+
const trimmed = value.trim();
|
|
65188
|
+
return trimmed.length > 0 ? trimmed : null;
|
|
65189
|
+
}
|
|
65190
|
+
if (typeof value === "number" || typeof value === "boolean" || typeof value === "bigint") {
|
|
65191
|
+
return String(value);
|
|
65192
|
+
}
|
|
65193
|
+
if (Array.isArray(value)) {
|
|
65194
|
+
const parts = value.map((item) => stringifyDisplayTitlePrefix(item)).filter((item) => Boolean(item));
|
|
65195
|
+
return parts.length > 0 ? parts.join(", ") : null;
|
|
65196
|
+
}
|
|
65197
|
+
if (typeof value === "object") {
|
|
65198
|
+
const json2 = JSON.stringify(value);
|
|
65199
|
+
return json2 && json2 !== "{}" && json2 !== "[]" ? json2 : null;
|
|
65200
|
+
}
|
|
65201
|
+
return null;
|
|
65202
|
+
}
|
|
65203
|
+
function getDisplayTitleFromContent(content, metadata, titleFields) {
|
|
65204
|
+
const title = getTitleFromContent(content);
|
|
65205
|
+
if (!titleFields || titleFields.length === 0) {
|
|
65206
|
+
return title;
|
|
65207
|
+
}
|
|
65208
|
+
const prefixes = titleFields.map((field) => stringifyDisplayTitlePrefix(getMetadataPathValue(metadata, field))).filter((value) => Boolean(value));
|
|
65209
|
+
return prefixes.length > 0 ? `${prefixes.join(" ")} ${title}` : title;
|
|
65210
|
+
}
|
|
65173
65211
|
function generateSlug(title) {
|
|
65174
65212
|
return title.toLowerCase().replace(/[^a-z0-9\s-]/g, "").replace(/\s+/g, "-").replace(/-+/g, "-").replace(/^-|-$/g, "").slice(0, 50) || "card";
|
|
65175
65213
|
}
|
|
@@ -70030,6 +70068,7 @@ function listBoards(ctx) {
|
|
|
70030
70068
|
columns: board.columns,
|
|
70031
70069
|
actions: board.actions,
|
|
70032
70070
|
metadata: board.metadata,
|
|
70071
|
+
title: board.title,
|
|
70033
70072
|
forms: config.forms
|
|
70034
70073
|
}));
|
|
70035
70074
|
}
|
|
@@ -70104,6 +70143,8 @@ function updateBoard(ctx, { boardId, updates }) {
|
|
|
70104
70143
|
board.defaultPriority = updates.defaultPriority;
|
|
70105
70144
|
if (updates.metadata !== void 0)
|
|
70106
70145
|
board.metadata = updates.metadata;
|
|
70146
|
+
if (updates.title !== void 0)
|
|
70147
|
+
board.title = updates.title;
|
|
70107
70148
|
writeConfig(ctx.workspaceRoot, config);
|
|
70108
70149
|
return board;
|
|
70109
70150
|
}
|
|
@@ -73756,7 +73797,7 @@ var KanbanSDK = class _KanbanSDK {
|
|
|
73756
73797
|
* Lists all boards defined in the workspace configuration.
|
|
73757
73798
|
*
|
|
73758
73799
|
* @returns An array of {@link BoardInfo} objects containing each board's
|
|
73759
|
-
|
|
73800
|
+
* `id`, `name`, optional `description`, and display-title metadata config.
|
|
73760
73801
|
*
|
|
73761
73802
|
* @example
|
|
73762
73803
|
* ```ts
|
|
@@ -73825,7 +73866,7 @@ var KanbanSDK = class _KanbanSDK {
|
|
|
73825
73866
|
* Retrieves the full configuration for a specific board.
|
|
73826
73867
|
*
|
|
73827
73868
|
* @param boardId - The ID of the board to retrieve.
|
|
73828
|
-
|
|
73869
|
+
* @returns The {@link BoardConfig} object containing columns, settings, metadata, and display-title metadata config.
|
|
73829
73870
|
* @throws {Error} If the board does not exist.
|
|
73830
73871
|
*
|
|
73831
73872
|
* @example
|
|
@@ -73850,6 +73891,7 @@ var KanbanSDK = class _KanbanSDK {
|
|
|
73850
73891
|
* @param updates.columns - Replacement column definitions.
|
|
73851
73892
|
* @param updates.defaultStatus - New default status for new cards.
|
|
73852
73893
|
* @param updates.defaultPriority - New default priority for new cards.
|
|
73894
|
+
* @param updates.title - Ordered metadata keys whose values should prefix rendered card titles.
|
|
73853
73895
|
* @returns The updated {@link BoardConfig} object.
|
|
73854
73896
|
* @throws {Error} If the board does not exist.
|
|
73855
73897
|
*
|
|
@@ -75460,6 +75502,8 @@ var KANBAN_OPENAPI_SPEC = {
|
|
|
75460
75502
|
name: { type: "string" },
|
|
75461
75503
|
description: { type: "string" },
|
|
75462
75504
|
columns: { type: "array", items: { $ref: "#/components/schemas/Column" } },
|
|
75505
|
+
metadata: { type: "array", items: { type: "string" }, description: "Board metadata keys pinned in the card detail panel." },
|
|
75506
|
+
title: { type: "array", items: { type: "string" }, description: "Ordered metadata keys whose rendered values prefix user-visible card titles." },
|
|
75463
75507
|
defaultStatus: { type: "string" },
|
|
75464
75508
|
defaultPriority: { type: "string", enum: ["critical", "high", "medium", "low"] }
|
|
75465
75509
|
}
|
|
@@ -75546,7 +75590,7 @@ var KANBAN_OPENAPI_SPEC = {
|
|
|
75546
75590
|
"application/json": {
|
|
75547
75591
|
schema: {
|
|
75548
75592
|
type: "object",
|
|
75549
|
-
description: "Any subset of board config fields: `name`, `description`, `columns`, `defaultStatus`, `defaultPriority`."
|
|
75593
|
+
description: "Any subset of board config fields: `name`, `description`, `columns`, `metadata`, `title`, `defaultStatus`, `defaultPriority`."
|
|
75550
75594
|
}
|
|
75551
75595
|
}
|
|
75552
75596
|
}
|
|
@@ -82182,15 +82226,16 @@ var KanbanPanel = class _KanbanPanel {
|
|
|
82182
82226
|
vscode.window.showErrorMessage("No card selected");
|
|
82183
82227
|
return;
|
|
82184
82228
|
}
|
|
82185
|
-
const
|
|
82186
|
-
const
|
|
82229
|
+
const aiRoot = this._getWorkspaceRoot();
|
|
82230
|
+
const aiConfig = aiRoot ? readConfig(aiRoot) : DEFAULT_CONFIG;
|
|
82231
|
+
const activeBoardId = this._currentBoardId || aiConfig.defaultBoard;
|
|
82232
|
+
const titleFields = aiConfig.boards[activeBoardId]?.title;
|
|
82233
|
+
const title = getDisplayTitleFromContent(card.content, card.metadata, titleFields);
|
|
82187
82234
|
const labels = card.labels.length > 0 ? ` [${card.labels.join(", ")}]` : "";
|
|
82188
82235
|
const description = card.content.replace(/\n/g, " ").replace(/\s+/g, " ").trim();
|
|
82189
82236
|
const shortDesc = description.length > 200 ? description.substring(0, 200) + "..." : description;
|
|
82190
82237
|
const promptTarget = this._sdk?.getLocalCardPath(card) ?? `card ${card.id}`;
|
|
82191
82238
|
const prompt = `Implement this card: "${title}" (${card.priority} priority)${labels}. ${shortDesc} See full details in: ${promptTarget}`;
|
|
82192
|
-
const aiRoot = this._getWorkspaceRoot();
|
|
82193
|
-
const aiConfig = aiRoot ? readConfig(aiRoot) : DEFAULT_CONFIG;
|
|
82194
82239
|
const selectedAgent = agent || aiConfig.aiAgent || "claude";
|
|
82195
82240
|
const selectedPermissionMode = permissionMode || "default";
|
|
82196
82241
|
let command;
|
|
@@ -82527,10 +82572,14 @@ var SidebarViewProvider = class {
|
|
|
82527
82572
|
}
|
|
82528
82573
|
try {
|
|
82529
82574
|
const sdk = new KanbanSDK(kanbanDir);
|
|
82575
|
+
const workspaceFolders = vscode2.workspace.workspaceFolders;
|
|
82576
|
+
const root = workspaceFolders?.[0]?.uri.fsPath;
|
|
82577
|
+
const config = root ? readConfig(root) : void 0;
|
|
82578
|
+
const defaultBoardTitleFields = config?.boards[config.defaultBoard]?.title;
|
|
82530
82579
|
const cards = await sdk.listCards();
|
|
82531
82580
|
this._cards = cards.map((c) => ({
|
|
82532
82581
|
id: c.id,
|
|
82533
|
-
title:
|
|
82582
|
+
title: getDisplayTitleFromContent(c.content, c.metadata, defaultBoardTitleFields),
|
|
82534
82583
|
status: c.status,
|
|
82535
82584
|
priority: c.priority
|
|
82536
82585
|
}));
|
package/dist/mcp-server.js
CHANGED
|
@@ -17503,6 +17503,44 @@ function getTitleFromContent(content) {
|
|
|
17503
17503
|
const firstLine = content.split("\n").map((l) => l.trim()).find((l) => l.length > 0);
|
|
17504
17504
|
return firstLine || "Untitled";
|
|
17505
17505
|
}
|
|
17506
|
+
function getMetadataPathValue(metadata, path16) {
|
|
17507
|
+
if (!metadata || !path16.trim())
|
|
17508
|
+
return void 0;
|
|
17509
|
+
return path16.split(".").reduce((current, key) => {
|
|
17510
|
+
if (current === null || current === void 0 || typeof current !== "object") {
|
|
17511
|
+
return void 0;
|
|
17512
|
+
}
|
|
17513
|
+
return current[key];
|
|
17514
|
+
}, metadata);
|
|
17515
|
+
}
|
|
17516
|
+
function stringifyDisplayTitlePrefix(value) {
|
|
17517
|
+
if (value === null || value === void 0)
|
|
17518
|
+
return null;
|
|
17519
|
+
if (typeof value === "string") {
|
|
17520
|
+
const trimmed = value.trim();
|
|
17521
|
+
return trimmed.length > 0 ? trimmed : null;
|
|
17522
|
+
}
|
|
17523
|
+
if (typeof value === "number" || typeof value === "boolean" || typeof value === "bigint") {
|
|
17524
|
+
return String(value);
|
|
17525
|
+
}
|
|
17526
|
+
if (Array.isArray(value)) {
|
|
17527
|
+
const parts = value.map((item) => stringifyDisplayTitlePrefix(item)).filter((item) => Boolean(item));
|
|
17528
|
+
return parts.length > 0 ? parts.join(", ") : null;
|
|
17529
|
+
}
|
|
17530
|
+
if (typeof value === "object") {
|
|
17531
|
+
const json2 = JSON.stringify(value);
|
|
17532
|
+
return json2 && json2 !== "{}" && json2 !== "[]" ? json2 : null;
|
|
17533
|
+
}
|
|
17534
|
+
return null;
|
|
17535
|
+
}
|
|
17536
|
+
function getDisplayTitleFromContent(content, metadata, titleFields) {
|
|
17537
|
+
const title = getTitleFromContent(content);
|
|
17538
|
+
if (!titleFields || titleFields.length === 0) {
|
|
17539
|
+
return title;
|
|
17540
|
+
}
|
|
17541
|
+
const prefixes = titleFields.map((field) => stringifyDisplayTitlePrefix(getMetadataPathValue(metadata, field))).filter((value) => Boolean(value));
|
|
17542
|
+
return prefixes.length > 0 ? `${prefixes.join(" ")} ${title}` : title;
|
|
17543
|
+
}
|
|
17506
17544
|
function generateSlug(title) {
|
|
17507
17545
|
return title.toLowerCase().replace(/[^a-z0-9\s-]/g, "").replace(/\s+/g, "-").replace(/-+/g, "-").replace(/^-|-$/g, "").slice(0, 50) || "card";
|
|
17508
17546
|
}
|
|
@@ -22428,6 +22466,7 @@ function listBoards(ctx) {
|
|
|
22428
22466
|
columns: board.columns,
|
|
22429
22467
|
actions: board.actions,
|
|
22430
22468
|
metadata: board.metadata,
|
|
22469
|
+
title: board.title,
|
|
22431
22470
|
forms: config.forms
|
|
22432
22471
|
}));
|
|
22433
22472
|
}
|
|
@@ -22502,6 +22541,8 @@ function updateBoard(ctx, { boardId, updates }) {
|
|
|
22502
22541
|
board.defaultPriority = updates.defaultPriority;
|
|
22503
22542
|
if (updates.metadata !== void 0)
|
|
22504
22543
|
board.metadata = updates.metadata;
|
|
22544
|
+
if (updates.title !== void 0)
|
|
22545
|
+
board.title = updates.title;
|
|
22505
22546
|
writeConfig(ctx.workspaceRoot, config);
|
|
22506
22547
|
return board;
|
|
22507
22548
|
}
|
|
@@ -26154,7 +26195,7 @@ var KanbanSDK = class _KanbanSDK {
|
|
|
26154
26195
|
* Lists all boards defined in the workspace configuration.
|
|
26155
26196
|
*
|
|
26156
26197
|
* @returns An array of {@link BoardInfo} objects containing each board's
|
|
26157
|
-
|
|
26198
|
+
* `id`, `name`, optional `description`, and display-title metadata config.
|
|
26158
26199
|
*
|
|
26159
26200
|
* @example
|
|
26160
26201
|
* ```ts
|
|
@@ -26223,7 +26264,7 @@ var KanbanSDK = class _KanbanSDK {
|
|
|
26223
26264
|
* Retrieves the full configuration for a specific board.
|
|
26224
26265
|
*
|
|
26225
26266
|
* @param boardId - The ID of the board to retrieve.
|
|
26226
|
-
|
|
26267
|
+
* @returns The {@link BoardConfig} object containing columns, settings, metadata, and display-title metadata config.
|
|
26227
26268
|
* @throws {Error} If the board does not exist.
|
|
26228
26269
|
*
|
|
26229
26270
|
* @example
|
|
@@ -26248,6 +26289,7 @@ var KanbanSDK = class _KanbanSDK {
|
|
|
26248
26289
|
* @param updates.columns - Replacement column definitions.
|
|
26249
26290
|
* @param updates.defaultStatus - New default status for new cards.
|
|
26250
26291
|
* @param updates.defaultPriority - New default priority for new cards.
|
|
26292
|
+
* @param updates.title - Ordered metadata keys whose values should prefix rendered card titles.
|
|
26251
26293
|
* @returns The updated {@link BoardConfig} object.
|
|
26252
26294
|
* @throws {Error} If the board does not exist.
|
|
26253
26295
|
*
|
|
@@ -27640,6 +27682,17 @@ async function buildMcpCardStateMutationModel(sdk, unread) {
|
|
|
27640
27682
|
}
|
|
27641
27683
|
};
|
|
27642
27684
|
}
|
|
27685
|
+
function getBoardTitleFieldsForMcp(sdk, boardId) {
|
|
27686
|
+
const config = sdk.getConfigSnapshot();
|
|
27687
|
+
const resolvedBoardId = boardId || config.defaultBoard;
|
|
27688
|
+
return config.boards[resolvedBoardId]?.title;
|
|
27689
|
+
}
|
|
27690
|
+
function decorateMcpCardTitle(card, titleFields) {
|
|
27691
|
+
return {
|
|
27692
|
+
...card,
|
|
27693
|
+
title: getDisplayTitleFromContent(card.content, card.metadata, titleFields)
|
|
27694
|
+
};
|
|
27695
|
+
}
|
|
27643
27696
|
function registerCardStateMcpTools(server, options) {
|
|
27644
27697
|
const registeredNames = [
|
|
27645
27698
|
"get_card_state_status",
|
|
@@ -27858,6 +27911,7 @@ async function main() {
|
|
|
27858
27911
|
sort: import_zod.z.enum(["created:asc", "created:desc", "modified:asc", "modified:desc"]).optional().describe("Sort order: created:asc, created:desc, modified:asc, or modified:desc. Defaults to board order.")
|
|
27859
27912
|
},
|
|
27860
27913
|
async ({ boardId, status, priority, assignee, label, labelGroup, includeDeleted, searchQuery, fuzzy, metaFilter, sort }) => {
|
|
27914
|
+
const titleFields = getBoardTitleFieldsForMcp(sdk, boardId);
|
|
27861
27915
|
let cards = await sdk.listCards(void 0, boardId, {
|
|
27862
27916
|
metaFilter: metaFilter && Object.keys(metaFilter).length > 0 ? metaFilter : void 0,
|
|
27863
27917
|
sort: sort || void 0,
|
|
@@ -27880,7 +27934,7 @@ async function main() {
|
|
|
27880
27934
|
}
|
|
27881
27935
|
const summary = cards.map((c) => ({
|
|
27882
27936
|
id: c.id,
|
|
27883
|
-
title:
|
|
27937
|
+
title: getDisplayTitleFromContent(c.content, c.metadata, titleFields),
|
|
27884
27938
|
status: c.status,
|
|
27885
27939
|
priority: c.priority,
|
|
27886
27940
|
assignee: c.assignee,
|
|
@@ -27921,10 +27975,11 @@ async function main() {
|
|
|
27921
27975
|
};
|
|
27922
27976
|
}
|
|
27923
27977
|
}
|
|
27978
|
+
const titleFields = getBoardTitleFieldsForMcp(sdk, card.boardId ?? boardId);
|
|
27924
27979
|
return {
|
|
27925
27980
|
content: [{
|
|
27926
27981
|
type: "text",
|
|
27927
|
-
text: JSON.stringify(card, null, 2)
|
|
27982
|
+
text: JSON.stringify(decorateMcpCardTitle(card, titleFields), null, 2)
|
|
27928
27983
|
}]
|
|
27929
27984
|
};
|
|
27930
27985
|
}
|
|
@@ -27937,10 +27992,11 @@ async function main() {
|
|
|
27937
27992
|
},
|
|
27938
27993
|
async ({ boardId }) => {
|
|
27939
27994
|
const card = await sdk.getActiveCard(boardId);
|
|
27995
|
+
const titleFields = card ? getBoardTitleFieldsForMcp(sdk, card.boardId ?? boardId) : void 0;
|
|
27940
27996
|
return {
|
|
27941
27997
|
content: [{
|
|
27942
27998
|
type: "text",
|
|
27943
|
-
text: JSON.stringify(card, null, 2)
|
|
27999
|
+
text: JSON.stringify(card ? decorateMcpCardTitle(card, titleFields) : null, null, 2)
|
|
27944
28000
|
}]
|
|
27945
28001
|
};
|
|
27946
28002
|
}
|
package/dist/sdk/index.cjs
CHANGED
|
@@ -17502,6 +17502,7 @@ __export(sdk_exports, {
|
|
|
17502
17502
|
getBoardConfig: () => getBoardConfig,
|
|
17503
17503
|
getCardFilePath: () => getCardFilePath,
|
|
17504
17504
|
getDefaultBoardId: () => getDefaultBoardId,
|
|
17505
|
+
getDisplayTitleFromContent: () => getDisplayTitleFromContent,
|
|
17505
17506
|
getEventsByResource: () => getEventsByResource,
|
|
17506
17507
|
getSdkAfterEvents: () => getSdkAfterEvents,
|
|
17507
17508
|
getSdkBeforeEvents: () => getSdkBeforeEvents,
|
|
@@ -17533,6 +17534,44 @@ function getTitleFromContent(content) {
|
|
|
17533
17534
|
const firstLine = content.split("\n").map((l) => l.trim()).find((l) => l.length > 0);
|
|
17534
17535
|
return firstLine || "Untitled";
|
|
17535
17536
|
}
|
|
17537
|
+
function getMetadataPathValue(metadata, path15) {
|
|
17538
|
+
if (!metadata || !path15.trim())
|
|
17539
|
+
return void 0;
|
|
17540
|
+
return path15.split(".").reduce((current, key) => {
|
|
17541
|
+
if (current === null || current === void 0 || typeof current !== "object") {
|
|
17542
|
+
return void 0;
|
|
17543
|
+
}
|
|
17544
|
+
return current[key];
|
|
17545
|
+
}, metadata);
|
|
17546
|
+
}
|
|
17547
|
+
function stringifyDisplayTitlePrefix(value) {
|
|
17548
|
+
if (value === null || value === void 0)
|
|
17549
|
+
return null;
|
|
17550
|
+
if (typeof value === "string") {
|
|
17551
|
+
const trimmed = value.trim();
|
|
17552
|
+
return trimmed.length > 0 ? trimmed : null;
|
|
17553
|
+
}
|
|
17554
|
+
if (typeof value === "number" || typeof value === "boolean" || typeof value === "bigint") {
|
|
17555
|
+
return String(value);
|
|
17556
|
+
}
|
|
17557
|
+
if (Array.isArray(value)) {
|
|
17558
|
+
const parts = value.map((item) => stringifyDisplayTitlePrefix(item)).filter((item) => Boolean(item));
|
|
17559
|
+
return parts.length > 0 ? parts.join(", ") : null;
|
|
17560
|
+
}
|
|
17561
|
+
if (typeof value === "object") {
|
|
17562
|
+
const json2 = JSON.stringify(value);
|
|
17563
|
+
return json2 && json2 !== "{}" && json2 !== "[]" ? json2 : null;
|
|
17564
|
+
}
|
|
17565
|
+
return null;
|
|
17566
|
+
}
|
|
17567
|
+
function getDisplayTitleFromContent(content, metadata, titleFields) {
|
|
17568
|
+
const title = getTitleFromContent(content);
|
|
17569
|
+
if (!titleFields || titleFields.length === 0) {
|
|
17570
|
+
return title;
|
|
17571
|
+
}
|
|
17572
|
+
const prefixes = titleFields.map((field) => stringifyDisplayTitlePrefix(getMetadataPathValue(metadata, field))).filter((value) => Boolean(value));
|
|
17573
|
+
return prefixes.length > 0 ? `${prefixes.join(" ")} ${title}` : title;
|
|
17574
|
+
}
|
|
17536
17575
|
function generateSlug(title) {
|
|
17537
17576
|
return title.toLowerCase().replace(/[^a-z0-9\s-]/g, "").replace(/\s+/g, "-").replace(/-+/g, "-").replace(/^-|-$/g, "").slice(0, 50) || "card";
|
|
17538
17577
|
}
|
|
@@ -22395,6 +22434,7 @@ function listBoards(ctx) {
|
|
|
22395
22434
|
columns: board.columns,
|
|
22396
22435
|
actions: board.actions,
|
|
22397
22436
|
metadata: board.metadata,
|
|
22437
|
+
title: board.title,
|
|
22398
22438
|
forms: config.forms
|
|
22399
22439
|
}));
|
|
22400
22440
|
}
|
|
@@ -22469,6 +22509,8 @@ function updateBoard(ctx, { boardId, updates }) {
|
|
|
22469
22509
|
board.defaultPriority = updates.defaultPriority;
|
|
22470
22510
|
if (updates.metadata !== void 0)
|
|
22471
22511
|
board.metadata = updates.metadata;
|
|
22512
|
+
if (updates.title !== void 0)
|
|
22513
|
+
board.title = updates.title;
|
|
22472
22514
|
writeConfig(ctx.workspaceRoot, config);
|
|
22473
22515
|
return board;
|
|
22474
22516
|
}
|
|
@@ -26121,7 +26163,7 @@ var KanbanSDK = class _KanbanSDK {
|
|
|
26121
26163
|
* Lists all boards defined in the workspace configuration.
|
|
26122
26164
|
*
|
|
26123
26165
|
* @returns An array of {@link BoardInfo} objects containing each board's
|
|
26124
|
-
|
|
26166
|
+
* `id`, `name`, optional `description`, and display-title metadata config.
|
|
26125
26167
|
*
|
|
26126
26168
|
* @example
|
|
26127
26169
|
* ```ts
|
|
@@ -26190,7 +26232,7 @@ var KanbanSDK = class _KanbanSDK {
|
|
|
26190
26232
|
* Retrieves the full configuration for a specific board.
|
|
26191
26233
|
*
|
|
26192
26234
|
* @param boardId - The ID of the board to retrieve.
|
|
26193
|
-
|
|
26235
|
+
* @returns The {@link BoardConfig} object containing columns, settings, metadata, and display-title metadata config.
|
|
26194
26236
|
* @throws {Error} If the board does not exist.
|
|
26195
26237
|
*
|
|
26196
26238
|
* @example
|
|
@@ -26215,6 +26257,7 @@ var KanbanSDK = class _KanbanSDK {
|
|
|
26215
26257
|
* @param updates.columns - Replacement column definitions.
|
|
26216
26258
|
* @param updates.defaultStatus - New default status for new cards.
|
|
26217
26259
|
* @param updates.defaultPriority - New default priority for new cards.
|
|
26260
|
+
* @param updates.title - Ordered metadata keys whose values should prefix rendered card titles.
|
|
26218
26261
|
* @returns The updated {@link BoardConfig} object.
|
|
26219
26262
|
* @throws {Error} If the board does not exist.
|
|
26220
26263
|
*
|
|
@@ -27727,6 +27770,7 @@ function getActionsByResource(resource) {
|
|
|
27727
27770
|
getBoardConfig,
|
|
27728
27771
|
getCardFilePath,
|
|
27729
27772
|
getDefaultBoardId,
|
|
27773
|
+
getDisplayTitleFromContent,
|
|
27730
27774
|
getEventsByResource,
|
|
27731
27775
|
getSdkAfterEvents,
|
|
27732
27776
|
getSdkBeforeEvents,
|