kanban-lite 1.2.2 → 1.2.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli.js +168 -85
- package/dist/extension.js +157 -74
- package/dist/mcp-server.js +94 -33
- package/dist/sdk/index.cjs +94 -32
- package/dist/sdk/index.mjs +94 -32
- package/dist/sdk/sdk/KanbanSDK.d.ts +5 -9
- package/dist/sdk/sdk/modules/cards.d.ts +11 -2
- package/dist/sdk/sdk/types.d.ts +1 -1
- package/dist/sdk/shared/config.d.ts +17 -1
- package/dist/standalone-webview/index.js +15 -15
- package/dist/standalone-webview/index.js.map +1 -1
- package/dist/standalone.js +219 -121
- package/package.json +1 -1
- package/src/mcp-server/index.ts +1 -1
- package/src/sdk/KanbanSDK.d.ts +5 -9
- package/src/sdk/KanbanSDK.ts +7 -10
- package/src/sdk/integrationCatalog.ts +1 -0
- package/src/sdk/modules/cards.ts +13 -24
- package/src/sdk/plugins/index.ts +10 -2
- package/src/sdk/types.d.ts +1 -1
- package/src/sdk/types.ts +1 -0
- package/src/sdk/webhooks.ts +19 -2
- package/src/shared/config.ts +124 -2
- package/src/standalone/internal/runtime.ts +11 -6
- package/src/standalone/server.ts +21 -7
- package/src/standalone/watcherSetup.ts +9 -0
- package/src/webview/standalone-shim.ts +2 -1
package/dist/cli.js
CHANGED
|
@@ -173,11 +173,83 @@ function migrateConfigV1ToV2(raw) {
|
|
|
173
173
|
}
|
|
174
174
|
return v2;
|
|
175
175
|
}
|
|
176
|
+
function loadDotEnv(dir) {
|
|
177
|
+
const envPath = path.join(dir, ".env");
|
|
178
|
+
let content;
|
|
179
|
+
try {
|
|
180
|
+
content = fs.readFileSync(envPath, "utf-8");
|
|
181
|
+
} catch {
|
|
182
|
+
return;
|
|
183
|
+
}
|
|
184
|
+
for (const line of content.split("\n")) {
|
|
185
|
+
const trimmed = line.trim();
|
|
186
|
+
if (!trimmed || trimmed.startsWith("#"))
|
|
187
|
+
continue;
|
|
188
|
+
const eqIdx = trimmed.indexOf("=");
|
|
189
|
+
if (eqIdx < 1)
|
|
190
|
+
continue;
|
|
191
|
+
const key = trimmed.slice(0, eqIdx).trim();
|
|
192
|
+
let val = trimmed.slice(eqIdx + 1).trim();
|
|
193
|
+
if (val.startsWith('"') && val.endsWith('"') || val.startsWith("'") && val.endsWith("'")) {
|
|
194
|
+
val = val.slice(1, -1);
|
|
195
|
+
}
|
|
196
|
+
if (process.env[key] === void 0) {
|
|
197
|
+
process.env[key] = val;
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
function resolveConfigEnvVars(node, configFileName, nodePath = "") {
|
|
202
|
+
if (typeof node === "string") {
|
|
203
|
+
return node.replace(/\$\{([^}]+)\}/g, (_match, varName) => {
|
|
204
|
+
const envValue = process.env[varName];
|
|
205
|
+
if (envValue === void 0) {
|
|
206
|
+
throw new Error(
|
|
207
|
+
`missing ${varName} in ${configFileName}: ${nodePath} "${node}"`
|
|
208
|
+
);
|
|
209
|
+
}
|
|
210
|
+
return envValue;
|
|
211
|
+
});
|
|
212
|
+
}
|
|
213
|
+
if (Array.isArray(node)) {
|
|
214
|
+
for (let i = 0; i < node.length; i++) {
|
|
215
|
+
node[i] = resolveConfigEnvVars(node[i], configFileName, `${nodePath}[${i}]`);
|
|
216
|
+
}
|
|
217
|
+
return node;
|
|
218
|
+
}
|
|
219
|
+
if (node !== null && typeof node === "object") {
|
|
220
|
+
const obj = node;
|
|
221
|
+
for (const key of Object.keys(obj)) {
|
|
222
|
+
const jsonKey = /[^a-zA-Z0-9_]/.test(key) ? `"${key}"` : key;
|
|
223
|
+
const childPath = nodePath ? `${nodePath}.${jsonKey}` : `.${jsonKey}`;
|
|
224
|
+
obj[key] = resolveConfigEnvVars(obj[key], configFileName, childPath);
|
|
225
|
+
}
|
|
226
|
+
return obj;
|
|
227
|
+
}
|
|
228
|
+
return node;
|
|
229
|
+
}
|
|
176
230
|
function readConfig(workspaceRoot) {
|
|
177
231
|
const filePath = configPath(workspaceRoot);
|
|
178
232
|
const defaults = { ...DEFAULT_CONFIG, boards: { default: { ...DEFAULT_BOARD_CONFIG, columns: [...DEFAULT_COLUMNS] } } };
|
|
233
|
+
let raw;
|
|
234
|
+
try {
|
|
235
|
+
raw = JSON.parse(fs.readFileSync(filePath, "utf-8"));
|
|
236
|
+
} catch {
|
|
237
|
+
return defaults;
|
|
238
|
+
}
|
|
239
|
+
loadDotEnv(workspaceRoot);
|
|
240
|
+
try {
|
|
241
|
+
resolveConfigEnvVars(raw, CONFIG_FILENAME);
|
|
242
|
+
} catch (err) {
|
|
243
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
244
|
+
process.stderr.write(`
|
|
245
|
+
Configuration error: ${msg}
|
|
246
|
+
|
|
247
|
+
Set the missing environment variable before starting the server.
|
|
248
|
+
|
|
249
|
+
`);
|
|
250
|
+
process.exit(1);
|
|
251
|
+
}
|
|
179
252
|
try {
|
|
180
|
-
const raw = JSON.parse(fs.readFileSync(filePath, "utf-8"));
|
|
181
253
|
const isV1 = raw.version === 1 || !raw.version && !(typeof raw.boards === "object" && raw.boards !== null && !Array.isArray(raw.boards));
|
|
182
254
|
if (isV1) {
|
|
183
255
|
const v2 = migrateConfigV1ToV2(raw);
|
|
@@ -5315,7 +5387,7 @@ function resolveAuthIdentityPlugin(ref) {
|
|
|
5315
5387
|
if (ref.provider === "rbac")
|
|
5316
5388
|
return RBAC_IDENTITY_PLUGIN;
|
|
5317
5389
|
const packageName = AUTH_PROVIDER_ALIASES.get(ref.provider) ?? ref.provider;
|
|
5318
|
-
return loadExternalAuthIdentityPlugin(packageName, ref.provider);
|
|
5390
|
+
return loadExternalAuthIdentityPlugin(packageName, ref.provider, ref.options);
|
|
5319
5391
|
}
|
|
5320
5392
|
function resolveAuthPolicyPlugin(ref) {
|
|
5321
5393
|
if (ref.provider === "noop")
|
|
@@ -5447,8 +5519,13 @@ function selectAuthPolicyPlugin(mod, providerId) {
|
|
|
5447
5519
|
return direct;
|
|
5448
5520
|
return null;
|
|
5449
5521
|
}
|
|
5450
|
-
function loadExternalAuthIdentityPlugin(packageName, providerId) {
|
|
5522
|
+
function loadExternalAuthIdentityPlugin(packageName, providerId, options) {
|
|
5451
5523
|
const mod = loadExternalModule(packageName);
|
|
5524
|
+
if (options !== void 0 && typeof mod.createAuthIdentityPlugin === "function") {
|
|
5525
|
+
const created = mod.createAuthIdentityPlugin(options);
|
|
5526
|
+
if (isValidAuthIdentityPlugin(created, providerId))
|
|
5527
|
+
return created;
|
|
5528
|
+
}
|
|
5452
5529
|
const plugin = selectAuthIdentityPlugin(mod, providerId);
|
|
5453
5530
|
if (!plugin) {
|
|
5454
5531
|
throw new Error(
|
|
@@ -24633,29 +24710,10 @@ async function updateCard(ctx, { cardId, updates, boardId }) {
|
|
|
24633
24710
|
return card;
|
|
24634
24711
|
}
|
|
24635
24712
|
async function triggerAction(ctx, { cardId, action, boardId }) {
|
|
24636
|
-
const config3 = readConfig(ctx.workspaceRoot);
|
|
24637
|
-
const { actionWebhookUrl } = config3;
|
|
24638
|
-
if (!actionWebhookUrl) {
|
|
24639
|
-
throw new Error("No action webhook URL configured. Set actionWebhookUrl in .kanban.json");
|
|
24640
|
-
}
|
|
24641
24713
|
const card = await getCard(ctx, { cardId, boardId });
|
|
24642
24714
|
if (!card)
|
|
24643
24715
|
throw new Error(`Card not found: ${cardId}`);
|
|
24644
24716
|
const resolvedBoardId = card.boardId || ctx._resolveBoardId(boardId);
|
|
24645
|
-
const payload = {
|
|
24646
|
-
action,
|
|
24647
|
-
board: resolvedBoardId,
|
|
24648
|
-
list: card.status,
|
|
24649
|
-
card: sanitizeCard(card)
|
|
24650
|
-
};
|
|
24651
|
-
const response = await fetch(actionWebhookUrl, {
|
|
24652
|
-
method: "POST",
|
|
24653
|
-
headers: { "Content-Type": "application/json" },
|
|
24654
|
-
body: JSON.stringify(payload)
|
|
24655
|
-
});
|
|
24656
|
-
if (!response.ok) {
|
|
24657
|
-
throw new Error(`Action webhook responded with ${response.status}: ${response.statusText}`);
|
|
24658
|
-
}
|
|
24659
24717
|
await appendActivityLog(ctx, {
|
|
24660
24718
|
cardId,
|
|
24661
24719
|
boardId: resolvedBoardId,
|
|
@@ -24666,6 +24724,12 @@ async function triggerAction(ctx, { cardId, action, boardId }) {
|
|
|
24666
24724
|
}
|
|
24667
24725
|
}).catch(() => {
|
|
24668
24726
|
});
|
|
24727
|
+
return {
|
|
24728
|
+
action,
|
|
24729
|
+
board: resolvedBoardId,
|
|
24730
|
+
list: card.status,
|
|
24731
|
+
card: sanitizeCard(card)
|
|
24732
|
+
};
|
|
24669
24733
|
}
|
|
24670
24734
|
async function submitForm(ctx, input) {
|
|
24671
24735
|
const card = await getCard(ctx, { cardId: input.cardId, boardId: input.boardId });
|
|
@@ -26636,21 +26700,17 @@ var init_KanbanSDK = __esm({
|
|
|
26636
26700
|
return result;
|
|
26637
26701
|
}
|
|
26638
26702
|
/**
|
|
26639
|
-
* Triggers a named action for a card
|
|
26640
|
-
* configured in `.kanban.json`.
|
|
26703
|
+
* Triggers a named action for a card.
|
|
26641
26704
|
*
|
|
26642
|
-
*
|
|
26643
|
-
*
|
|
26644
|
-
*
|
|
26645
|
-
* ```
|
|
26705
|
+
* Validates the card, appends an activity log entry, and emits the
|
|
26706
|
+
* `card.action.triggered` after-event so registered webhooks receive
|
|
26707
|
+
* the action payload automatically.
|
|
26646
26708
|
*
|
|
26647
26709
|
* @param cardId - The ID of the card to trigger the action for.
|
|
26648
26710
|
* @param action - The action name string (e.g. `'retry'`, `'sendEmail'`).
|
|
26649
26711
|
* @param boardId - Optional board ID. Defaults to the workspace's default board.
|
|
26650
|
-
* @returns A promise
|
|
26651
|
-
* @throws {Error} If no `actionWebhookUrl` is configured in `.kanban.json`.
|
|
26712
|
+
* @returns A promise that resolves when the action has been processed.
|
|
26652
26713
|
* @throws {Error} If the card is not found.
|
|
26653
|
-
* @throws {Error} If the webhook responds with a non-2xx status.
|
|
26654
26714
|
*
|
|
26655
26715
|
* @example
|
|
26656
26716
|
* ```ts
|
|
@@ -26660,7 +26720,8 @@ var init_KanbanSDK = __esm({
|
|
|
26660
26720
|
*/
|
|
26661
26721
|
async triggerAction(cardId, action, boardId) {
|
|
26662
26722
|
const mergedInput = await this._runBeforeEvent("card.action.trigger", { cardId, action, boardId }, void 0, boardId);
|
|
26663
|
-
|
|
26723
|
+
const payload = await triggerAction(this, mergedInput);
|
|
26724
|
+
this._runAfterEvent("card.action.triggered", payload, void 0, payload.board);
|
|
26664
26725
|
}
|
|
26665
26726
|
/**
|
|
26666
26727
|
* Moves a card to a different status column and/or position within that column.
|
|
@@ -60340,7 +60401,7 @@ async function main() {
|
|
|
60340
60401
|
);
|
|
60341
60402
|
server.tool(
|
|
60342
60403
|
"trigger_action",
|
|
60343
|
-
"Trigger a named action on a card. The action name must match one of the card's configured actions.
|
|
60404
|
+
"Trigger a named action on a card. The action name must match one of the card's configured actions. Emits a card.action.triggered event delivered to registered webhooks.",
|
|
60344
60405
|
{
|
|
60345
60406
|
card_id: external_exports4.string().describe("Card ID (partial match supported)"),
|
|
60346
60407
|
action: external_exports4.string().describe("Action name to trigger"),
|
|
@@ -66751,7 +66812,7 @@ var require_thread_stream = __commonJS({
|
|
|
66751
66812
|
var { version: version3 } = require_package();
|
|
66752
66813
|
var { EventEmitter: EventEmitter3 } = require("events");
|
|
66753
66814
|
var { Worker } = require("worker_threads");
|
|
66754
|
-
var { join:
|
|
66815
|
+
var { join: join22 } = require("path");
|
|
66755
66816
|
var { pathToFileURL } = require("url");
|
|
66756
66817
|
var { wait } = require_wait();
|
|
66757
66818
|
var {
|
|
@@ -66787,7 +66848,7 @@ var require_thread_stream = __commonJS({
|
|
|
66787
66848
|
function createWorker(stream, opts) {
|
|
66788
66849
|
const { filename, workerData } = opts;
|
|
66789
66850
|
const bundlerOverrides = "__bundlerPathsOverrides" in globalThis ? globalThis.__bundlerPathsOverrides : {};
|
|
66790
|
-
const toExecute = bundlerOverrides["thread-stream-worker"] ||
|
|
66851
|
+
const toExecute = bundlerOverrides["thread-stream-worker"] || join22(__dirname, "lib", "worker.js");
|
|
66791
66852
|
const worker = new Worker(toExecute, {
|
|
66792
66853
|
...opts.workerOpts,
|
|
66793
66854
|
trackUnmanagedFds: false,
|
|
@@ -67178,7 +67239,7 @@ var require_transport = __commonJS({
|
|
|
67178
67239
|
var { createRequire: createRequire2 } = require("module");
|
|
67179
67240
|
var { existsSync: existsSync4 } = require("node:fs");
|
|
67180
67241
|
var getCallers = require_caller();
|
|
67181
|
-
var { join:
|
|
67242
|
+
var { join: join22, isAbsolute: isAbsolute2, sep: sep2 } = require("node:path");
|
|
67182
67243
|
var { fileURLToPath: fileURLToPath2 } = require("node:url");
|
|
67183
67244
|
var sleep = require_atomic_sleep();
|
|
67184
67245
|
var onExit = require_on_exit_leak_free();
|
|
@@ -67331,7 +67392,7 @@ var require_transport = __commonJS({
|
|
|
67331
67392
|
throw new Error("only one of target or targets can be specified");
|
|
67332
67393
|
}
|
|
67333
67394
|
if (targets) {
|
|
67334
|
-
target = bundlerOverrides["pino-worker"] ||
|
|
67395
|
+
target = bundlerOverrides["pino-worker"] || join22(__dirname, "worker.js");
|
|
67335
67396
|
options.targets = targets.filter((dest) => dest.target).map((dest) => {
|
|
67336
67397
|
return {
|
|
67337
67398
|
...dest,
|
|
@@ -67349,7 +67410,7 @@ var require_transport = __commonJS({
|
|
|
67349
67410
|
});
|
|
67350
67411
|
});
|
|
67351
67412
|
} else if (pipeline) {
|
|
67352
|
-
target = bundlerOverrides["pino-worker"] ||
|
|
67413
|
+
target = bundlerOverrides["pino-worker"] || join22(__dirname, "worker.js");
|
|
67353
67414
|
options.pipelines = [pipeline.map((dest) => {
|
|
67354
67415
|
return {
|
|
67355
67416
|
...dest,
|
|
@@ -67372,7 +67433,7 @@ var require_transport = __commonJS({
|
|
|
67372
67433
|
return origin;
|
|
67373
67434
|
}
|
|
67374
67435
|
if (origin === "pino/file") {
|
|
67375
|
-
return
|
|
67436
|
+
return join22(__dirname, "..", "file.js");
|
|
67376
67437
|
}
|
|
67377
67438
|
let fixTarget2;
|
|
67378
67439
|
for (const filePath of callers) {
|
|
@@ -68362,7 +68423,7 @@ var require_safe_stable_stringify = __commonJS({
|
|
|
68362
68423
|
return circularValue;
|
|
68363
68424
|
}
|
|
68364
68425
|
let res = "";
|
|
68365
|
-
let
|
|
68426
|
+
let join22 = ",";
|
|
68366
68427
|
const originalIndentation = indentation;
|
|
68367
68428
|
if (Array.isArray(value)) {
|
|
68368
68429
|
if (value.length === 0) {
|
|
@@ -68376,7 +68437,7 @@ var require_safe_stable_stringify = __commonJS({
|
|
|
68376
68437
|
indentation += spacer;
|
|
68377
68438
|
res += `
|
|
68378
68439
|
${indentation}`;
|
|
68379
|
-
|
|
68440
|
+
join22 = `,
|
|
68380
68441
|
${indentation}`;
|
|
68381
68442
|
}
|
|
68382
68443
|
const maximumValuesToStringify = Math.min(value.length, maximumBreadth);
|
|
@@ -68384,13 +68445,13 @@ ${indentation}`;
|
|
|
68384
68445
|
for (; i < maximumValuesToStringify - 1; i++) {
|
|
68385
68446
|
const tmp2 = stringifyFnReplacer(String(i), value, stack, replacer, spacer, indentation);
|
|
68386
68447
|
res += tmp2 !== void 0 ? tmp2 : "null";
|
|
68387
|
-
res +=
|
|
68448
|
+
res += join22;
|
|
68388
68449
|
}
|
|
68389
68450
|
const tmp = stringifyFnReplacer(String(i), value, stack, replacer, spacer, indentation);
|
|
68390
68451
|
res += tmp !== void 0 ? tmp : "null";
|
|
68391
68452
|
if (value.length - 1 > maximumBreadth) {
|
|
68392
68453
|
const removedKeys = value.length - maximumBreadth - 1;
|
|
68393
|
-
res += `${
|
|
68454
|
+
res += `${join22}"... ${getItemCount(removedKeys)} not stringified"`;
|
|
68394
68455
|
}
|
|
68395
68456
|
if (spacer !== "") {
|
|
68396
68457
|
res += `
|
|
@@ -68411,7 +68472,7 @@ ${originalIndentation}`;
|
|
|
68411
68472
|
let separator = "";
|
|
68412
68473
|
if (spacer !== "") {
|
|
68413
68474
|
indentation += spacer;
|
|
68414
|
-
|
|
68475
|
+
join22 = `,
|
|
68415
68476
|
${indentation}`;
|
|
68416
68477
|
whitespace = " ";
|
|
68417
68478
|
}
|
|
@@ -68425,13 +68486,13 @@ ${indentation}`;
|
|
|
68425
68486
|
const tmp = stringifyFnReplacer(key2, value, stack, replacer, spacer, indentation);
|
|
68426
68487
|
if (tmp !== void 0) {
|
|
68427
68488
|
res += `${separator}${strEscape(key2)}:${whitespace}${tmp}`;
|
|
68428
|
-
separator =
|
|
68489
|
+
separator = join22;
|
|
68429
68490
|
}
|
|
68430
68491
|
}
|
|
68431
68492
|
if (keyLength > maximumBreadth) {
|
|
68432
68493
|
const removedKeys = keyLength - maximumBreadth;
|
|
68433
68494
|
res += `${separator}"...":${whitespace}"${getItemCount(removedKeys)} not stringified"`;
|
|
68434
|
-
separator =
|
|
68495
|
+
separator = join22;
|
|
68435
68496
|
}
|
|
68436
68497
|
if (spacer !== "" && separator.length > 1) {
|
|
68437
68498
|
res = `
|
|
@@ -68471,7 +68532,7 @@ ${originalIndentation}`;
|
|
|
68471
68532
|
}
|
|
68472
68533
|
const originalIndentation = indentation;
|
|
68473
68534
|
let res = "";
|
|
68474
|
-
let
|
|
68535
|
+
let join22 = ",";
|
|
68475
68536
|
if (Array.isArray(value)) {
|
|
68476
68537
|
if (value.length === 0) {
|
|
68477
68538
|
return "[]";
|
|
@@ -68484,7 +68545,7 @@ ${originalIndentation}`;
|
|
|
68484
68545
|
indentation += spacer;
|
|
68485
68546
|
res += `
|
|
68486
68547
|
${indentation}`;
|
|
68487
|
-
|
|
68548
|
+
join22 = `,
|
|
68488
68549
|
${indentation}`;
|
|
68489
68550
|
}
|
|
68490
68551
|
const maximumValuesToStringify = Math.min(value.length, maximumBreadth);
|
|
@@ -68492,13 +68553,13 @@ ${indentation}`;
|
|
|
68492
68553
|
for (; i < maximumValuesToStringify - 1; i++) {
|
|
68493
68554
|
const tmp2 = stringifyArrayReplacer(String(i), value[i], stack, replacer, spacer, indentation);
|
|
68494
68555
|
res += tmp2 !== void 0 ? tmp2 : "null";
|
|
68495
|
-
res +=
|
|
68556
|
+
res += join22;
|
|
68496
68557
|
}
|
|
68497
68558
|
const tmp = stringifyArrayReplacer(String(i), value[i], stack, replacer, spacer, indentation);
|
|
68498
68559
|
res += tmp !== void 0 ? tmp : "null";
|
|
68499
68560
|
if (value.length - 1 > maximumBreadth) {
|
|
68500
68561
|
const removedKeys = value.length - maximumBreadth - 1;
|
|
68501
|
-
res += `${
|
|
68562
|
+
res += `${join22}"... ${getItemCount(removedKeys)} not stringified"`;
|
|
68502
68563
|
}
|
|
68503
68564
|
if (spacer !== "") {
|
|
68504
68565
|
res += `
|
|
@@ -68511,7 +68572,7 @@ ${originalIndentation}`;
|
|
|
68511
68572
|
let whitespace = "";
|
|
68512
68573
|
if (spacer !== "") {
|
|
68513
68574
|
indentation += spacer;
|
|
68514
|
-
|
|
68575
|
+
join22 = `,
|
|
68515
68576
|
${indentation}`;
|
|
68516
68577
|
whitespace = " ";
|
|
68517
68578
|
}
|
|
@@ -68520,7 +68581,7 @@ ${indentation}`;
|
|
|
68520
68581
|
const tmp = stringifyArrayReplacer(key2, value[key2], stack, replacer, spacer, indentation);
|
|
68521
68582
|
if (tmp !== void 0) {
|
|
68522
68583
|
res += `${separator}${strEscape(key2)}:${whitespace}${tmp}`;
|
|
68523
|
-
separator =
|
|
68584
|
+
separator = join22;
|
|
68524
68585
|
}
|
|
68525
68586
|
}
|
|
68526
68587
|
if (spacer !== "" && separator.length > 1) {
|
|
@@ -68577,20 +68638,20 @@ ${originalIndentation}`;
|
|
|
68577
68638
|
indentation += spacer;
|
|
68578
68639
|
let res2 = `
|
|
68579
68640
|
${indentation}`;
|
|
68580
|
-
const
|
|
68641
|
+
const join23 = `,
|
|
68581
68642
|
${indentation}`;
|
|
68582
68643
|
const maximumValuesToStringify = Math.min(value.length, maximumBreadth);
|
|
68583
68644
|
let i = 0;
|
|
68584
68645
|
for (; i < maximumValuesToStringify - 1; i++) {
|
|
68585
68646
|
const tmp2 = stringifyIndent(String(i), value[i], stack, spacer, indentation);
|
|
68586
68647
|
res2 += tmp2 !== void 0 ? tmp2 : "null";
|
|
68587
|
-
res2 +=
|
|
68648
|
+
res2 += join23;
|
|
68588
68649
|
}
|
|
68589
68650
|
const tmp = stringifyIndent(String(i), value[i], stack, spacer, indentation);
|
|
68590
68651
|
res2 += tmp !== void 0 ? tmp : "null";
|
|
68591
68652
|
if (value.length - 1 > maximumBreadth) {
|
|
68592
68653
|
const removedKeys = value.length - maximumBreadth - 1;
|
|
68593
|
-
res2 += `${
|
|
68654
|
+
res2 += `${join23}"... ${getItemCount(removedKeys)} not stringified"`;
|
|
68594
68655
|
}
|
|
68595
68656
|
res2 += `
|
|
68596
68657
|
${originalIndentation}`;
|
|
@@ -68606,16 +68667,16 @@ ${originalIndentation}`;
|
|
|
68606
68667
|
return '"[Object]"';
|
|
68607
68668
|
}
|
|
68608
68669
|
indentation += spacer;
|
|
68609
|
-
const
|
|
68670
|
+
const join22 = `,
|
|
68610
68671
|
${indentation}`;
|
|
68611
68672
|
let res = "";
|
|
68612
68673
|
let separator = "";
|
|
68613
68674
|
let maximumPropertiesToStringify = Math.min(keyLength, maximumBreadth);
|
|
68614
68675
|
if (isTypedArrayWithEntries(value)) {
|
|
68615
|
-
res += stringifyTypedArray(value,
|
|
68676
|
+
res += stringifyTypedArray(value, join22, maximumBreadth);
|
|
68616
68677
|
keys = keys.slice(value.length);
|
|
68617
68678
|
maximumPropertiesToStringify -= value.length;
|
|
68618
|
-
separator =
|
|
68679
|
+
separator = join22;
|
|
68619
68680
|
}
|
|
68620
68681
|
if (deterministic) {
|
|
68621
68682
|
keys = sort(keys, comparator);
|
|
@@ -68626,13 +68687,13 @@ ${indentation}`;
|
|
|
68626
68687
|
const tmp = stringifyIndent(key2, value[key2], stack, spacer, indentation);
|
|
68627
68688
|
if (tmp !== void 0) {
|
|
68628
68689
|
res += `${separator}${strEscape(key2)}: ${tmp}`;
|
|
68629
|
-
separator =
|
|
68690
|
+
separator = join22;
|
|
68630
68691
|
}
|
|
68631
68692
|
}
|
|
68632
68693
|
if (keyLength > maximumBreadth) {
|
|
68633
68694
|
const removedKeys = keyLength - maximumBreadth;
|
|
68634
68695
|
res += `${separator}"...": "${getItemCount(removedKeys)} not stringified"`;
|
|
68635
|
-
separator =
|
|
68696
|
+
separator = join22;
|
|
68636
68697
|
}
|
|
68637
68698
|
if (separator !== "") {
|
|
68638
68699
|
res = `
|
|
@@ -103100,7 +103161,7 @@ var require_send = __commonJS({
|
|
|
103100
103161
|
var { parseTokenList } = require_parseTokenList();
|
|
103101
103162
|
var { createHttpError } = require_createHttpError();
|
|
103102
103163
|
var extname4 = path24.extname;
|
|
103103
|
-
var
|
|
103164
|
+
var join22 = path24.join;
|
|
103104
103165
|
var normalize2 = path24.normalize;
|
|
103105
103166
|
var resolve11 = path24.resolve;
|
|
103106
103167
|
var sep2 = path24.sep;
|
|
@@ -103187,7 +103248,7 @@ var require_send = __commonJS({
|
|
|
103187
103248
|
return { statusCode: 403 };
|
|
103188
103249
|
}
|
|
103189
103250
|
parts = path25.split(sep2);
|
|
103190
|
-
path25 = normalize2(
|
|
103251
|
+
path25 = normalize2(join22(root, path25));
|
|
103191
103252
|
} else {
|
|
103192
103253
|
if (UP_PATH_REGEXP.test(path25)) {
|
|
103193
103254
|
debug('malicious path "%s"', path25);
|
|
@@ -103471,7 +103532,7 @@ var require_send = __commonJS({
|
|
|
103471
103532
|
let err;
|
|
103472
103533
|
for (let i = 0; i < options.index.length; i++) {
|
|
103473
103534
|
const index = options.index[i];
|
|
103474
|
-
const p =
|
|
103535
|
+
const p = join22(path25, index);
|
|
103475
103536
|
const { error: error49, stat: stat4 } = await tryStat(p);
|
|
103476
103537
|
if (error49) {
|
|
103477
103538
|
err = error49;
|
|
@@ -111887,6 +111948,13 @@ function setupWatcher(ctx, server) {
|
|
|
111887
111948
|
ctx.wss.close();
|
|
111888
111949
|
});
|
|
111889
111950
|
}
|
|
111951
|
+
const configFilePath = path17.join(ctx.workspaceRoot, ".kanban.json");
|
|
111952
|
+
const configWatcher = esm_default.watch(configFilePath, {
|
|
111953
|
+
ignoreInitial: true,
|
|
111954
|
+
awaitWriteFinish: { stabilityThreshold: 100 }
|
|
111955
|
+
});
|
|
111956
|
+
configWatcher.on("change", () => handleFileChange(ctx, debounceRef));
|
|
111957
|
+
server.on("close", () => configWatcher.close());
|
|
111890
111958
|
}
|
|
111891
111959
|
var fs10, path17;
|
|
111892
111960
|
var init_watcherSetup = __esm({
|
|
@@ -112092,6 +112160,23 @@ var init_lifecycle = __esm({
|
|
|
112092
112160
|
});
|
|
112093
112161
|
|
|
112094
112162
|
// src/standalone/internal/runtime.ts
|
|
112163
|
+
function getIndexHtml(basePath = "") {
|
|
112164
|
+
return `<!DOCTYPE html>
|
|
112165
|
+
<html lang="en">
|
|
112166
|
+
<head>
|
|
112167
|
+
<meta charset="UTF-8">
|
|
112168
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
112169
|
+
<link rel="icon" type="image/svg+xml" href="${basePath}/favicon.svg">
|
|
112170
|
+
<link href="${basePath}/style.css" rel="stylesheet">
|
|
112171
|
+
<title>Kanban Board</title>
|
|
112172
|
+
<script>window.__KB_BASE__ = ${JSON.stringify(basePath)}</script>
|
|
112173
|
+
</head>
|
|
112174
|
+
<body>
|
|
112175
|
+
<div id="root"></div>
|
|
112176
|
+
<script type="module" src="${basePath}/index.js"></script>
|
|
112177
|
+
</body>
|
|
112178
|
+
</html>`;
|
|
112179
|
+
}
|
|
112095
112180
|
function resolveStandaloneWebviewDir(webviewDir) {
|
|
112096
112181
|
if (webviewDir)
|
|
112097
112182
|
return webviewDir;
|
|
@@ -112105,12 +112190,12 @@ function resolveStandaloneWebviewDir(webviewDir) {
|
|
|
112105
112190
|
}
|
|
112106
112191
|
return candidates[0];
|
|
112107
112192
|
}
|
|
112108
|
-
function createStandaloneRuntime(kanbanDir, webviewDir, httpServer) {
|
|
112193
|
+
function createStandaloneRuntime(kanbanDir, webviewDir, httpServer, basePath) {
|
|
112109
112194
|
const absoluteKanbanDir = path19.resolve(kanbanDir);
|
|
112110
112195
|
const workspaceRoot = path19.dirname(absoluteKanbanDir);
|
|
112111
112196
|
const resolvedWebviewDir = resolveStandaloneWebviewDir(webviewDir);
|
|
112112
112197
|
const server = httpServer ?? http.createServer();
|
|
112113
|
-
const wss = new import_websocket_server.default({ server, path: "/ws" });
|
|
112198
|
+
const wss = new import_websocket_server.default({ server, path: (basePath || "") + "/ws" });
|
|
112114
112199
|
const ctx = {};
|
|
112115
112200
|
const sdk = new KanbanSDK(absoluteKanbanDir, {
|
|
112116
112201
|
onEvent: (event, data) => {
|
|
@@ -112159,20 +112244,7 @@ var init_runtime = __esm({
|
|
|
112159
112244
|
init_wrapper();
|
|
112160
112245
|
init_KanbanSDK();
|
|
112161
112246
|
init_broadcastService();
|
|
112162
|
-
indexHtml =
|
|
112163
|
-
<html lang="en">
|
|
112164
|
-
<head>
|
|
112165
|
-
<meta charset="UTF-8">
|
|
112166
|
-
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
112167
|
-
<link rel="icon" type="image/svg+xml" href="/favicon.svg">
|
|
112168
|
-
<link href="/style.css" rel="stylesheet">
|
|
112169
|
-
<title>Kanban Board</title>
|
|
112170
|
-
</head>
|
|
112171
|
-
<body>
|
|
112172
|
-
<div id="root"></div>
|
|
112173
|
-
<script type="module" src="/index.js"></script>
|
|
112174
|
-
</body>
|
|
112175
|
-
</html>`;
|
|
112247
|
+
indexHtml = getIndexHtml();
|
|
112176
112248
|
}
|
|
112177
112249
|
});
|
|
112178
112250
|
|
|
@@ -114380,10 +114452,13 @@ function startServer(kanbanDir, port, webviewDir, resolvedConfigPath) {
|
|
|
114380
114452
|
const swaggerUiStaticDir = resolveSwaggerUiStaticDir();
|
|
114381
114453
|
const swaggerUiLogoPath = swaggerUiStaticDir ? path21.join(swaggerUiStaticDir, "logo.svg") : void 0;
|
|
114382
114454
|
const swaggerUiLogo = swaggerUiLogoPath && fs15.existsSync(swaggerUiLogoPath) ? { type: "image/svg+xml", content: fs15.readFileSync(swaggerUiLogoPath) } : null;
|
|
114383
|
-
const
|
|
114455
|
+
const workspaceRoot = path21.dirname(path21.resolve(kanbanDir));
|
|
114456
|
+
const config3 = readConfig(workspaceRoot);
|
|
114457
|
+
const rawBase = config3.basePath ?? "";
|
|
114458
|
+
const basePath = rawBase ? (rawBase.startsWith("/") ? rawBase : "/" + rawBase).replace(/\/+$/, "") : "";
|
|
114459
|
+
const runtime = createStandaloneRuntime(kanbanDir, webviewDir, fastify.server, basePath);
|
|
114384
114460
|
const { ctx, resolvedWebviewDir } = runtime;
|
|
114385
|
-
|
|
114386
|
-
let resolvedIndexHtml = indexHtml;
|
|
114461
|
+
let resolvedIndexHtml = getIndexHtml(basePath);
|
|
114387
114462
|
let customHead = config3.customHeadHtml || "";
|
|
114388
114463
|
if (config3.customHeadHtmlFile) {
|
|
114389
114464
|
try {
|
|
@@ -114393,14 +114468,14 @@ function startServer(kanbanDir, port, webviewDir, resolvedConfigPath) {
|
|
|
114393
114468
|
}
|
|
114394
114469
|
}
|
|
114395
114470
|
if (customHead) {
|
|
114396
|
-
resolvedIndexHtml =
|
|
114471
|
+
resolvedIndexHtml = resolvedIndexHtml.replace("</head>", `${customHead}
|
|
114397
114472
|
</head>`);
|
|
114398
114473
|
}
|
|
114399
114474
|
const standaloneHttpPlugins = ctx.sdk.capabilities?.standaloneHttpPlugins ?? [];
|
|
114400
114475
|
const standaloneOpenApiSpec = buildStandaloneOpenApiSpec(standaloneHttpPlugins);
|
|
114401
114476
|
fastify.register(import_swagger.default, { openapi: standaloneOpenApiSpec });
|
|
114402
114477
|
fastify.register(import_swagger_ui.default, {
|
|
114403
|
-
routePrefix:
|
|
114478
|
+
routePrefix: `${basePath}/api/docs`,
|
|
114404
114479
|
uiConfig: { docExpansion: "list", deepLinking: false },
|
|
114405
114480
|
logo: swaggerUiLogo,
|
|
114406
114481
|
...swaggerUiStaticDir ? { baseDir: swaggerUiStaticDir } : {}
|
|
@@ -114432,6 +114507,14 @@ function startServer(kanbanDir, port, webviewDir, resolvedConfigPath) {
|
|
|
114432
114507
|
if (request.body instanceof Buffer && request.body.length > 0) {
|
|
114433
114508
|
req._rawBody = request.body;
|
|
114434
114509
|
}
|
|
114510
|
+
if (basePath) {
|
|
114511
|
+
const rawUrl = req.url ?? "/";
|
|
114512
|
+
if (rawUrl === basePath) {
|
|
114513
|
+
req.url = "/";
|
|
114514
|
+
} else if (rawUrl.startsWith(basePath + "/") || rawUrl.startsWith(basePath + "?")) {
|
|
114515
|
+
req.url = rawUrl.slice(basePath.length);
|
|
114516
|
+
}
|
|
114517
|
+
}
|
|
114435
114518
|
const requestContext = createRequestContext(ctx, req, reply.raw, resolvedWebviewDir, resolvedIndexHtml);
|
|
114436
114519
|
await dispatchRequest(requestContext, middlewareHandlers);
|
|
114437
114520
|
if (!reply.sent && !reply.raw.writableEnded) {
|
|
@@ -114447,7 +114530,7 @@ function startServer(kanbanDir, port, webviewDir, resolvedConfigPath) {
|
|
|
114447
114530
|
console.error("Failed to start server:", err);
|
|
114448
114531
|
process.exit(1);
|
|
114449
114532
|
}
|
|
114450
|
-
console.log(`Kanban board running at http://localhost:${port}`);
|
|
114533
|
+
console.log(`Kanban board running at http://localhost:${port}${basePath}`);
|
|
114451
114534
|
console.log(`API available at http://localhost:${port}/api`);
|
|
114452
114535
|
console.log(`Kanban config: ${effectiveConfigPath}`);
|
|
114453
114536
|
console.log(`Kanban directory: ${ctx.absoluteKanbanDir}`);
|