kanban-lite 1.0.9 → 1.0.13

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.
Files changed (38) hide show
  1. package/dist/cli.js +1015 -407
  2. package/dist/extension.js +897 -347
  3. package/dist/mcp-server.js +550 -189
  4. package/dist/sdk/index.cjs +1223 -0
  5. package/dist/sdk/index.mjs +1168 -0
  6. package/dist/sdk/sdk/KanbanSDK.d.ts +39 -21
  7. package/dist/sdk/sdk/index.d.ts +4 -3
  8. package/dist/sdk/sdk/migration.d.ts +6 -0
  9. package/dist/sdk/sdk/types.d.ts +3 -5
  10. package/dist/sdk/shared/config.d.ts +23 -10
  11. package/dist/sdk/shared/types.d.ts +18 -4
  12. package/dist/standalone-webview/index.js +27 -27
  13. package/dist/standalone-webview/index.js.map +1 -1
  14. package/dist/standalone-webview/style.css +1 -1
  15. package/dist/standalone.js +831 -328
  16. package/dist/webview/index.js +45 -45
  17. package/dist/webview/index.js.map +1 -1
  18. package/dist/webview/style.css +1 -1
  19. package/package.json +4 -3
  20. package/src/cli/index.ts +217 -95
  21. package/src/extension/KanbanPanel.ts +49 -22
  22. package/src/mcp-server/index.ts +138 -62
  23. package/src/sdk/KanbanSDK.ts +283 -77
  24. package/src/sdk/__tests__/KanbanSDK.test.ts +5 -5
  25. package/src/sdk/__tests__/migration.test.ts +269 -0
  26. package/src/sdk/__tests__/multi-board.test.ts +449 -0
  27. package/src/sdk/index.ts +4 -3
  28. package/src/sdk/migration.ts +52 -0
  29. package/src/sdk/types.ts +3 -6
  30. package/src/shared/config.ts +144 -22
  31. package/src/shared/types.ts +14 -5
  32. package/src/standalone/__tests__/server.integration.test.ts +38 -37
  33. package/src/standalone/server.ts +239 -21
  34. package/src/webview/App.tsx +17 -7
  35. package/src/webview/components/Toolbar.tsx +99 -3
  36. package/src/webview/store/index.ts +11 -3
  37. package/.kanban/backlog/1-test1.md +0 -30
  38. package/.kanban.json +0 -42
package/dist/extension.js CHANGED
@@ -5,6 +5,9 @@ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
5
  var __getOwnPropNames = Object.getOwnPropertyNames;
6
6
  var __getProtoOf = Object.getPrototypeOf;
7
7
  var __hasOwnProp = Object.prototype.hasOwnProperty;
8
+ var __esm = (fn, res) => function __init() {
9
+ return fn && (res = (0, fn[__getOwnPropNames(fn)[0]])(fn = 0)), res;
10
+ };
8
11
  var __commonJS = (cb, mod) => function __require() {
9
12
  return mod || (0, cb[__getOwnPropNames(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports;
10
13
  };
@@ -30,6 +33,47 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
30
33
  ));
31
34
  var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
32
35
 
36
+ // src/shared/types.ts
37
+ var types_exports = {};
38
+ __export(types_exports, {
39
+ DEFAULT_COLUMNS: () => DEFAULT_COLUMNS,
40
+ extractNumericId: () => extractNumericId,
41
+ generateFeatureFilename: () => generateFeatureFilename,
42
+ generateSlug: () => generateSlug,
43
+ getTitleFromContent: () => getTitleFromContent
44
+ });
45
+ function getTitleFromContent(content) {
46
+ const match = content.match(/^#\s+(.+)$/m);
47
+ if (match)
48
+ return match[1].trim();
49
+ const firstLine = content.split("\n").map((l) => l.trim()).find((l) => l.length > 0);
50
+ return firstLine || "Untitled";
51
+ }
52
+ function generateSlug(title) {
53
+ return title.toLowerCase().replace(/[^a-z0-9\s-]/g, "").replace(/\s+/g, "-").replace(/-+/g, "-").replace(/^-|-$/g, "").slice(0, 50) || "feature";
54
+ }
55
+ function generateFeatureFilename(id, title) {
56
+ const slug = generateSlug(title);
57
+ return `${id}-${slug}`;
58
+ }
59
+ function extractNumericId(filenameOrId) {
60
+ const match = filenameOrId.match(/^(\d+)(?:-|$)/);
61
+ return match ? parseInt(match[1], 10) : null;
62
+ }
63
+ var DEFAULT_COLUMNS;
64
+ var init_types = __esm({
65
+ "src/shared/types.ts"() {
66
+ "use strict";
67
+ DEFAULT_COLUMNS = [
68
+ { id: "backlog", name: "Backlog", color: "#6b7280" },
69
+ { id: "todo", name: "To Do", color: "#3b82f6" },
70
+ { id: "in-progress", name: "In Progress", color: "#f59e0b" },
71
+ { id: "review", name: "Review", color: "#8b5cf6" },
72
+ { id: "done", name: "Done", color: "#22c55e" }
73
+ ];
74
+ }
75
+ });
76
+
33
77
  // node_modules/.pnpm/ws@8.19.0/node_modules/ws/lib/constants.js
34
78
  var require_constants = __commonJS({
35
79
  "node_modules/.pnpm/ws@8.19.0/node_modules/ws/lib/constants.js"(exports2, module2) {
@@ -3747,25 +3791,30 @@ __export(extension_exports, {
3747
3791
  });
3748
3792
  module.exports = __toCommonJS(extension_exports);
3749
3793
  var net = __toESM(require("node:net"));
3750
- var path9 = __toESM(require("node:path"));
3794
+ var path10 = __toESM(require("node:path"));
3751
3795
  var vscode3 = __toESM(require("vscode"));
3752
3796
 
3753
3797
  // src/shared/config.ts
3754
3798
  var fs = __toESM(require("fs"));
3755
3799
  var path = __toESM(require("path"));
3800
+ init_types();
3801
+ var DEFAULT_BOARD_CONFIG = {
3802
+ name: "Default",
3803
+ columns: [...DEFAULT_COLUMNS],
3804
+ nextCardId: 1,
3805
+ defaultStatus: "backlog",
3806
+ defaultPriority: "medium"
3807
+ };
3756
3808
  var DEFAULT_CONFIG = {
3809
+ version: 2,
3810
+ boards: {
3811
+ default: { ...DEFAULT_BOARD_CONFIG, columns: [...DEFAULT_COLUMNS] }
3812
+ },
3813
+ defaultBoard: "default",
3757
3814
  featuresDirectory: ".kanban",
3815
+ aiAgent: "claude",
3758
3816
  defaultPriority: "medium",
3759
3817
  defaultStatus: "backlog",
3760
- columns: [
3761
- { id: "backlog", name: "Backlog", color: "#6b7280" },
3762
- { id: "todo", name: "To Do", color: "#3b82f6" },
3763
- { id: "in-progress", name: "In Progress", color: "#f59e0b" },
3764
- { id: "review", name: "Review", color: "#8b5cf6" },
3765
- { id: "done", name: "Done", color: "#22c55e" }
3766
- ],
3767
- aiAgent: "claude",
3768
- nextCardId: 1,
3769
3818
  showPriorityBadges: true,
3770
3819
  showAssignee: true,
3771
3820
  showDueDate: true,
@@ -3779,12 +3828,65 @@ var CONFIG_FILENAME = ".kanban.json";
3779
3828
  function configPath(workspaceRoot) {
3780
3829
  return path.join(workspaceRoot, CONFIG_FILENAME);
3781
3830
  }
3831
+ function migrateConfigV1ToV2(raw) {
3832
+ const v1Defaults = {
3833
+ featuresDirectory: ".kanban",
3834
+ defaultPriority: "medium",
3835
+ defaultStatus: "backlog",
3836
+ columns: [...DEFAULT_COLUMNS],
3837
+ aiAgent: "claude",
3838
+ nextCardId: 1,
3839
+ showPriorityBadges: true,
3840
+ showAssignee: true,
3841
+ showDueDate: true,
3842
+ showLabels: true,
3843
+ showBuildWithAI: true,
3844
+ showFileName: false,
3845
+ compactMode: false,
3846
+ markdownEditorMode: false
3847
+ };
3848
+ const v1 = { ...v1Defaults, ...raw };
3849
+ return {
3850
+ version: 2,
3851
+ boards: {
3852
+ default: {
3853
+ name: "Default",
3854
+ columns: v1.columns,
3855
+ nextCardId: v1.nextCardId,
3856
+ defaultStatus: v1.defaultStatus,
3857
+ defaultPriority: v1.defaultPriority
3858
+ }
3859
+ },
3860
+ defaultBoard: "default",
3861
+ featuresDirectory: v1.featuresDirectory,
3862
+ aiAgent: v1.aiAgent,
3863
+ defaultPriority: v1.defaultPriority,
3864
+ defaultStatus: v1.defaultStatus,
3865
+ showPriorityBadges: v1.showPriorityBadges,
3866
+ showAssignee: v1.showAssignee,
3867
+ showDueDate: v1.showDueDate,
3868
+ showLabels: v1.showLabels,
3869
+ showBuildWithAI: v1.showBuildWithAI,
3870
+ showFileName: v1.showFileName,
3871
+ compactMode: v1.compactMode,
3872
+ markdownEditorMode: v1.markdownEditorMode
3873
+ };
3874
+ }
3782
3875
  function readConfig(workspaceRoot) {
3783
3876
  const filePath = configPath(workspaceRoot);
3784
- const defaults = { ...DEFAULT_CONFIG, columns: [...DEFAULT_CONFIG.columns] };
3877
+ const defaults = { ...DEFAULT_CONFIG, boards: { default: { ...DEFAULT_BOARD_CONFIG, columns: [...DEFAULT_COLUMNS] } } };
3785
3878
  try {
3786
3879
  const raw = JSON.parse(fs.readFileSync(filePath, "utf-8"));
3787
- return { ...defaults, ...raw };
3880
+ if (!raw.version || raw.version === 1) {
3881
+ const v2 = migrateConfigV1ToV2(raw);
3882
+ writeConfig(workspaceRoot, v2);
3883
+ return v2;
3884
+ }
3885
+ const config = { ...defaults, ...raw };
3886
+ if (!config.boards || Object.keys(config.boards).length === 0) {
3887
+ config.boards = defaults.boards;
3888
+ }
3889
+ return config;
3788
3890
  } catch {
3789
3891
  return defaults;
3790
3892
  }
@@ -3793,19 +3895,39 @@ function writeConfig(workspaceRoot, config) {
3793
3895
  const filePath = configPath(workspaceRoot);
3794
3896
  fs.writeFileSync(filePath, JSON.stringify(config, null, 2) + "\n", "utf-8");
3795
3897
  }
3796
- function allocateCardId(workspaceRoot) {
3898
+ function getBoardConfig(workspaceRoot, boardId) {
3797
3899
  const config = readConfig(workspaceRoot);
3798
- const id = config.nextCardId;
3799
- writeConfig(workspaceRoot, { ...config, nextCardId: id + 1 });
3900
+ const resolvedId = boardId || config.defaultBoard;
3901
+ const board = config.boards[resolvedId];
3902
+ if (!board) {
3903
+ throw new Error(`Board '${resolvedId}' not found`);
3904
+ }
3905
+ return board;
3906
+ }
3907
+ function allocateCardId(workspaceRoot, boardId) {
3908
+ const config = readConfig(workspaceRoot);
3909
+ const resolvedId = boardId || config.defaultBoard;
3910
+ const board = config.boards[resolvedId];
3911
+ if (!board) {
3912
+ throw new Error(`Board '${resolvedId}' not found`);
3913
+ }
3914
+ const id = board.nextCardId;
3915
+ board.nextCardId = id + 1;
3916
+ writeConfig(workspaceRoot, config);
3800
3917
  return id;
3801
3918
  }
3802
- function syncCardIdCounter(workspaceRoot, existingIds) {
3919
+ function syncCardIdCounter(workspaceRoot, boardId, existingIds) {
3803
3920
  if (existingIds.length === 0)
3804
3921
  return;
3805
3922
  const maxId = Math.max(...existingIds);
3806
3923
  const config = readConfig(workspaceRoot);
3807
- if (config.nextCardId <= maxId) {
3808
- writeConfig(workspaceRoot, { ...config, nextCardId: maxId + 1 });
3924
+ const resolvedId = boardId || config.defaultBoard;
3925
+ const board = config.boards[resolvedId];
3926
+ if (!board)
3927
+ return;
3928
+ if (board.nextCardId <= maxId) {
3929
+ board.nextCardId = maxId + 1;
3930
+ writeConfig(workspaceRoot, config);
3809
3931
  }
3810
3932
  }
3811
3933
  function configToSettings(config) {
@@ -3837,8 +3959,8 @@ function settingsToConfig(config, settings) {
3837
3959
  }
3838
3960
 
3839
3961
  // src/sdk/KanbanSDK.ts
3840
- var fs3 = __toESM(require("fs/promises"));
3841
- var path4 = __toESM(require("path"));
3962
+ var fs4 = __toESM(require("fs/promises"));
3963
+ var path5 = __toESM(require("path"));
3842
3964
 
3843
3965
  // node_modules/.pnpm/fractional-indexing@3.2.0/node_modules/fractional-indexing/src/index.js
3844
3966
  var BASE_62_DIGITS = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
@@ -4050,25 +4172,8 @@ function generateNKeysBetween(a, b, n, digits = BASE_62_DIGITS) {
4050
4172
  ];
4051
4173
  }
4052
4174
 
4053
- // src/shared/types.ts
4054
- function getTitleFromContent(content) {
4055
- const match = content.match(/^#\s+(.+)$/m);
4056
- if (match)
4057
- return match[1].trim();
4058
- const firstLine = content.split("\n").map((l) => l.trim()).find((l) => l.length > 0);
4059
- return firstLine || "Untitled";
4060
- }
4061
- function generateSlug(title) {
4062
- return title.toLowerCase().replace(/[^a-z0-9\s-]/g, "").replace(/\s+/g, "-").replace(/-+/g, "-").replace(/^-|-$/g, "").slice(0, 50) || "feature";
4063
- }
4064
- function generateFeatureFilename(id, title) {
4065
- const slug = generateSlug(title);
4066
- return `${id}-${slug}`;
4067
- }
4068
- function extractNumericId(filenameOrId) {
4069
- const match = filenameOrId.match(/^(\d+)(?:-|$)/);
4070
- return match ? parseInt(match[1], 10) : null;
4071
- }
4175
+ // src/sdk/KanbanSDK.ts
4176
+ init_types();
4072
4177
 
4073
4178
  // src/sdk/parser.ts
4074
4179
  var path2 = __toESM(require("path"));
@@ -4257,30 +4362,203 @@ async function fileExists(filePath) {
4257
4362
  }
4258
4363
  }
4259
4364
 
4365
+ // src/sdk/migration.ts
4366
+ var fs3 = __toESM(require("fs/promises"));
4367
+ var path4 = __toESM(require("path"));
4368
+ async function migrateFileSystemToMultiBoard(featuresDir) {
4369
+ const boardsDir = path4.join(featuresDir, "boards");
4370
+ const defaultBoardDir = path4.join(boardsDir, "default");
4371
+ try {
4372
+ await fs3.access(boardsDir);
4373
+ return;
4374
+ } catch {
4375
+ }
4376
+ await fs3.mkdir(defaultBoardDir, { recursive: true });
4377
+ let entries;
4378
+ try {
4379
+ entries = await fs3.readdir(featuresDir, { withFileTypes: true });
4380
+ } catch {
4381
+ return;
4382
+ }
4383
+ for (const entry of entries) {
4384
+ if (!entry.isDirectory())
4385
+ continue;
4386
+ if (entry.name === "boards" || entry.name.startsWith("."))
4387
+ continue;
4388
+ const src = path4.join(featuresDir, entry.name);
4389
+ const dest = path4.join(defaultBoardDir, entry.name);
4390
+ await fs3.rename(src, dest);
4391
+ }
4392
+ const rootMdFiles = entries.filter((e) => e.isFile() && e.name.endsWith(".md"));
4393
+ if (rootMdFiles.length > 0) {
4394
+ const backlogDir = path4.join(defaultBoardDir, "backlog");
4395
+ await fs3.mkdir(backlogDir, { recursive: true });
4396
+ for (const file of rootMdFiles) {
4397
+ await fs3.rename(
4398
+ path4.join(featuresDir, file.name),
4399
+ path4.join(backlogDir, file.name)
4400
+ );
4401
+ }
4402
+ }
4403
+ }
4404
+
4260
4405
  // src/sdk/KanbanSDK.ts
4261
4406
  var KanbanSDK = class {
4262
4407
  constructor(featuresDir) {
4263
4408
  this.featuresDir = featuresDir;
4409
+ this._migrated = false;
4264
4410
  }
4265
4411
  get workspaceRoot() {
4266
- return path4.dirname(this.featuresDir);
4412
+ return path5.dirname(this.featuresDir);
4413
+ }
4414
+ // --- Board resolution helpers ---
4415
+ _resolveBoardId(boardId) {
4416
+ const config = readConfig(this.workspaceRoot);
4417
+ return boardId || config.defaultBoard;
4418
+ }
4419
+ _boardDir(boardId) {
4420
+ const resolvedId = this._resolveBoardId(boardId);
4421
+ return path5.join(this.featuresDir, "boards", resolvedId);
4422
+ }
4423
+ _isCompletedStatus(status, boardId) {
4424
+ const config = readConfig(this.workspaceRoot);
4425
+ const resolvedId = boardId || config.defaultBoard;
4426
+ const board = config.boards[resolvedId];
4427
+ if (!board || board.columns.length === 0)
4428
+ return status === "done";
4429
+ return board.columns[board.columns.length - 1].id === status;
4430
+ }
4431
+ async _ensureMigrated() {
4432
+ if (this._migrated)
4433
+ return;
4434
+ await migrateFileSystemToMultiBoard(this.featuresDir);
4435
+ this._migrated = true;
4267
4436
  }
4268
4437
  async init() {
4269
- await ensureDirectories(this.featuresDir);
4438
+ await this._ensureMigrated();
4439
+ const boardDir = this._boardDir();
4440
+ await ensureDirectories(boardDir);
4441
+ }
4442
+ // --- Board management ---
4443
+ listBoards() {
4444
+ const config = readConfig(this.workspaceRoot);
4445
+ return Object.entries(config.boards).map(([id, board]) => ({
4446
+ id,
4447
+ name: board.name,
4448
+ description: board.description
4449
+ }));
4450
+ }
4451
+ createBoard(id, name, options) {
4452
+ const config = readConfig(this.workspaceRoot);
4453
+ if (config.boards[id]) {
4454
+ throw new Error(`Board already exists: ${id}`);
4455
+ }
4456
+ const columns = options?.columns || [...config.boards[config.defaultBoard]?.columns || [
4457
+ { id: "backlog", name: "Backlog", color: "#6b7280" },
4458
+ { id: "todo", name: "To Do", color: "#3b82f6" },
4459
+ { id: "in-progress", name: "In Progress", color: "#f59e0b" },
4460
+ { id: "review", name: "Review", color: "#8b5cf6" },
4461
+ { id: "done", name: "Done", color: "#22c55e" }
4462
+ ]];
4463
+ config.boards[id] = {
4464
+ name,
4465
+ description: options?.description,
4466
+ columns,
4467
+ nextCardId: 1,
4468
+ defaultStatus: options?.defaultStatus || columns[0]?.id || "backlog",
4469
+ defaultPriority: options?.defaultPriority || config.defaultPriority
4470
+ };
4471
+ writeConfig(this.workspaceRoot, config);
4472
+ return { id, name, description: options?.description };
4473
+ }
4474
+ async deleteBoard(boardId) {
4475
+ const config = readConfig(this.workspaceRoot);
4476
+ if (!config.boards[boardId]) {
4477
+ throw new Error(`Board not found: ${boardId}`);
4478
+ }
4479
+ if (config.defaultBoard === boardId) {
4480
+ throw new Error(`Cannot delete the default board: ${boardId}`);
4481
+ }
4482
+ const cards = await this.listCards(void 0, boardId);
4483
+ if (cards.length > 0) {
4484
+ throw new Error(`Cannot delete board "${boardId}": ${cards.length} card(s) still exist`);
4485
+ }
4486
+ const boardDir = this._boardDir(boardId);
4487
+ try {
4488
+ await fs4.rm(boardDir, { recursive: true });
4489
+ } catch {
4490
+ }
4491
+ delete config.boards[boardId];
4492
+ writeConfig(this.workspaceRoot, config);
4493
+ }
4494
+ getBoard(boardId) {
4495
+ return getBoardConfig(this.workspaceRoot, boardId);
4496
+ }
4497
+ updateBoard(boardId, updates) {
4498
+ const config = readConfig(this.workspaceRoot);
4499
+ const board = config.boards[boardId];
4500
+ if (!board) {
4501
+ throw new Error(`Board not found: ${boardId}`);
4502
+ }
4503
+ if (updates.name !== void 0)
4504
+ board.name = updates.name;
4505
+ if (updates.description !== void 0)
4506
+ board.description = updates.description;
4507
+ if (updates.columns !== void 0)
4508
+ board.columns = updates.columns;
4509
+ if (updates.defaultStatus !== void 0)
4510
+ board.defaultStatus = updates.defaultStatus;
4511
+ if (updates.defaultPriority !== void 0)
4512
+ board.defaultPriority = updates.defaultPriority;
4513
+ writeConfig(this.workspaceRoot, config);
4514
+ return board;
4515
+ }
4516
+ async transferCard(cardId, fromBoardId, toBoardId, targetStatus) {
4517
+ const toBoardDir = this._boardDir(toBoardId);
4518
+ const config = readConfig(this.workspaceRoot);
4519
+ if (!config.boards[fromBoardId])
4520
+ throw new Error(`Board not found: ${fromBoardId}`);
4521
+ if (!config.boards[toBoardId])
4522
+ throw new Error(`Board not found: ${toBoardId}`);
4523
+ const card = await this.getCard(cardId, fromBoardId);
4524
+ if (!card)
4525
+ throw new Error(`Card not found: ${cardId} in board ${fromBoardId}`);
4526
+ const toBoard = config.boards[toBoardId];
4527
+ const newStatus = targetStatus || toBoard.defaultStatus || toBoard.columns[0]?.id || "backlog";
4528
+ const targetDir = path5.join(toBoardDir, newStatus);
4529
+ await fs4.mkdir(targetDir, { recursive: true });
4530
+ const oldPath = card.filePath;
4531
+ const filename = path5.basename(oldPath);
4532
+ const newPath = path5.join(targetDir, filename);
4533
+ await fs4.rename(oldPath, newPath);
4534
+ card.status = newStatus;
4535
+ card.boardId = toBoardId;
4536
+ card.filePath = newPath;
4537
+ card.modified = (/* @__PURE__ */ new Date()).toISOString();
4538
+ card.completedAt = this._isCompletedStatus(newStatus, toBoardId) ? (/* @__PURE__ */ new Date()).toISOString() : null;
4539
+ const targetCards = await this.listCards(void 0, toBoardId);
4540
+ const cardsInStatus = targetCards.filter((c) => c.status === newStatus && c.id !== cardId).sort((a, b) => a.order < b.order ? -1 : a.order > b.order ? 1 : 0);
4541
+ const lastOrder = cardsInStatus.length > 0 ? cardsInStatus[cardsInStatus.length - 1].order : null;
4542
+ card.order = generateKeyBetween(lastOrder, null);
4543
+ await fs4.writeFile(card.filePath, serializeFeature(card), "utf-8");
4544
+ return card;
4270
4545
  }
4271
4546
  // --- Card CRUD ---
4272
- async listCards(columns) {
4273
- await ensureDirectories(this.featuresDir);
4547
+ async listCards(columns, boardId) {
4548
+ await this._ensureMigrated();
4549
+ const boardDir = this._boardDir(boardId);
4550
+ const resolvedBoardId = this._resolveBoardId(boardId);
4551
+ await ensureDirectories(boardDir);
4274
4552
  if (columns) {
4275
- await ensureStatusSubfolders(this.featuresDir, columns);
4553
+ await ensureStatusSubfolders(boardDir, columns);
4276
4554
  }
4277
4555
  try {
4278
- const rootFiles = await this._readMdFiles(this.featuresDir);
4556
+ const rootFiles = await this._readMdFiles(boardDir);
4279
4557
  for (const filePath of rootFiles) {
4280
4558
  try {
4281
4559
  const card = await this._loadCard(filePath);
4282
4560
  if (card) {
4283
- await moveFeatureFile(filePath, this.featuresDir, card.status, card.attachments);
4561
+ await moveFeatureFile(filePath, boardDir, card.status, card.attachments);
4284
4562
  }
4285
4563
  } catch {
4286
4564
  }
@@ -4288,26 +4566,33 @@ var KanbanSDK = class {
4288
4566
  } catch {
4289
4567
  }
4290
4568
  const cards = [];
4291
- const entries = await fs3.readdir(this.featuresDir, { withFileTypes: true });
4569
+ let entries;
4570
+ try {
4571
+ entries = await fs4.readdir(boardDir, { withFileTypes: true });
4572
+ } catch {
4573
+ return [];
4574
+ }
4292
4575
  for (const entry of entries) {
4293
4576
  if (!entry.isDirectory() || entry.name.startsWith("."))
4294
4577
  continue;
4295
- const subdir = path4.join(this.featuresDir, entry.name);
4578
+ const subdir = path5.join(boardDir, entry.name);
4296
4579
  try {
4297
4580
  const mdFiles = await this._readMdFiles(subdir);
4298
4581
  for (const filePath of mdFiles) {
4299
4582
  const card = await this._loadCard(filePath);
4300
- if (card)
4583
+ if (card) {
4584
+ card.boardId = resolvedBoardId;
4301
4585
  cards.push(card);
4586
+ }
4302
4587
  }
4303
4588
  } catch {
4304
4589
  }
4305
4590
  }
4306
4591
  for (const card of cards) {
4307
- const pathStatus = getStatusFromPath(card.filePath, this.featuresDir);
4592
+ const pathStatus = getStatusFromPath(card.filePath, boardDir);
4308
4593
  if (pathStatus !== null && pathStatus !== card.status) {
4309
4594
  try {
4310
- card.filePath = await moveFeatureFile(card.filePath, this.featuresDir, card.status, card.attachments);
4595
+ card.filePath = await moveFeatureFile(card.filePath, boardDir, card.status, card.attachments);
4311
4596
  } catch {
4312
4597
  }
4313
4598
  }
@@ -4325,65 +4610,72 @@ var KanbanSDK = class {
4325
4610
  const keys = generateNKeysBetween(null, null, columnCards.length);
4326
4611
  for (let i = 0; i < columnCards.length; i++) {
4327
4612
  columnCards[i].order = keys[i];
4328
- await fs3.writeFile(columnCards[i].filePath, serializeFeature(columnCards[i]), "utf-8");
4613
+ await fs4.writeFile(columnCards[i].filePath, serializeFeature(columnCards[i]), "utf-8");
4329
4614
  }
4330
4615
  }
4331
4616
  }
4332
4617
  const numericIds = cards.map((c) => parseInt(c.id, 10)).filter((n) => !Number.isNaN(n));
4333
4618
  if (numericIds.length > 0) {
4334
- syncCardIdCounter(path4.dirname(this.featuresDir), numericIds);
4619
+ syncCardIdCounter(this.workspaceRoot, resolvedBoardId, numericIds);
4335
4620
  }
4336
4621
  return cards.sort((a, b) => a.order < b.order ? -1 : a.order > b.order ? 1 : 0);
4337
4622
  }
4338
- async getCard(cardId) {
4339
- const cards = await this.listCards();
4623
+ async getCard(cardId, boardId) {
4624
+ const cards = await this.listCards(void 0, boardId);
4340
4625
  return cards.find((c) => c.id === cardId) || null;
4341
4626
  }
4342
4627
  async createCard(data) {
4343
- await ensureDirectories(this.featuresDir);
4344
- const status = data.status || "backlog";
4345
- const priority = data.priority || "medium";
4628
+ await this._ensureMigrated();
4629
+ const resolvedBoardId = this._resolveBoardId(data.boardId);
4630
+ const boardDir = this._boardDir(resolvedBoardId);
4631
+ await ensureDirectories(boardDir);
4632
+ const config = readConfig(this.workspaceRoot);
4633
+ const board = config.boards[resolvedBoardId];
4634
+ const status = data.status || board?.defaultStatus || config.defaultStatus || "backlog";
4635
+ const priority = data.priority || board?.defaultPriority || config.defaultPriority || "medium";
4346
4636
  const title = getTitleFromContent(data.content);
4347
- const workspaceRoot = path4.dirname(this.featuresDir);
4348
- const numericId = allocateCardId(workspaceRoot);
4637
+ const numericId = allocateCardId(this.workspaceRoot, resolvedBoardId);
4349
4638
  const filename = generateFeatureFilename(numericId, title);
4350
4639
  const now = (/* @__PURE__ */ new Date()).toISOString();
4351
- const cards = await this.listCards();
4640
+ const cards = await this.listCards(void 0, resolvedBoardId);
4352
4641
  const cardsInStatus = cards.filter((c) => c.status === status).sort((a, b) => a.order < b.order ? -1 : a.order > b.order ? 1 : 0);
4353
4642
  const lastOrder = cardsInStatus.length > 0 ? cardsInStatus[cardsInStatus.length - 1].order : null;
4354
4643
  const card = {
4355
4644
  id: String(numericId),
4645
+ boardId: resolvedBoardId,
4356
4646
  status,
4357
4647
  priority,
4358
4648
  assignee: data.assignee ?? null,
4359
4649
  dueDate: data.dueDate ?? null,
4360
4650
  created: now,
4361
4651
  modified: now,
4362
- completedAt: status === "done" ? now : null,
4652
+ completedAt: this._isCompletedStatus(status, resolvedBoardId) ? now : null,
4363
4653
  labels: data.labels || [],
4364
4654
  attachments: data.attachments || [],
4365
4655
  comments: [],
4366
4656
  order: generateKeyBetween(lastOrder, null),
4367
4657
  content: data.content,
4368
- filePath: getFeatureFilePath(this.featuresDir, status, filename)
4658
+ filePath: getFeatureFilePath(boardDir, status, filename)
4369
4659
  };
4370
- await fs3.mkdir(path4.dirname(card.filePath), { recursive: true });
4371
- await fs3.writeFile(card.filePath, serializeFeature(card), "utf-8");
4660
+ await fs4.mkdir(path5.dirname(card.filePath), { recursive: true });
4661
+ await fs4.writeFile(card.filePath, serializeFeature(card), "utf-8");
4372
4662
  return card;
4373
4663
  }
4374
- async updateCard(cardId, updates) {
4375
- const card = await this.getCard(cardId);
4664
+ async updateCard(cardId, updates, boardId) {
4665
+ const card = await this.getCard(cardId, boardId);
4376
4666
  if (!card)
4377
4667
  throw new Error(`Card not found: ${cardId}`);
4668
+ const resolvedBoardId = card.boardId || this._resolveBoardId(boardId);
4669
+ const boardDir = this._boardDir(resolvedBoardId);
4378
4670
  const oldStatus = card.status;
4379
4671
  const oldTitle = getTitleFromContent(card.content);
4380
- const { filePath: _fp, id: _id, ...safeUpdates } = updates;
4672
+ const { filePath: _fp, id: _id, boardId: _bid, ...safeUpdates } = updates;
4381
4673
  Object.assign(card, safeUpdates);
4382
4674
  card.modified = (/* @__PURE__ */ new Date()).toISOString();
4383
4675
  if (oldStatus !== card.status) {
4384
- card.completedAt = card.status === "done" ? (/* @__PURE__ */ new Date()).toISOString() : null;
4676
+ card.completedAt = this._isCompletedStatus(card.status, resolvedBoardId) ? (/* @__PURE__ */ new Date()).toISOString() : null;
4385
4677
  }
4386
- await fs3.writeFile(card.filePath, serializeFeature(card), "utf-8");
4678
+ await fs4.writeFile(card.filePath, serializeFeature(card), "utf-8");
4387
4679
  const newTitle = getTitleFromContent(card.content);
4388
4680
  const numericId = extractNumericId(card.id);
4389
4681
  if (numericId !== null && newTitle !== oldTitle) {
@@ -4391,46 +4683,48 @@ var KanbanSDK = class {
4391
4683
  card.filePath = await renameFeatureFile(card.filePath, newFilename);
4392
4684
  }
4393
4685
  if (oldStatus !== card.status) {
4394
- const newPath = await moveFeatureFile(card.filePath, this.featuresDir, card.status, card.attachments);
4686
+ const newPath = await moveFeatureFile(card.filePath, boardDir, card.status, card.attachments);
4395
4687
  card.filePath = newPath;
4396
4688
  }
4397
4689
  return card;
4398
4690
  }
4399
- async moveCard(cardId, newStatus, position) {
4400
- const cards = await this.listCards();
4691
+ async moveCard(cardId, newStatus, position, boardId) {
4692
+ const cards = await this.listCards(void 0, boardId);
4401
4693
  const card = cards.find((c) => c.id === cardId);
4402
4694
  if (!card)
4403
4695
  throw new Error(`Card not found: ${cardId}`);
4696
+ const resolvedBoardId = card.boardId || this._resolveBoardId(boardId);
4697
+ const boardDir = this._boardDir(resolvedBoardId);
4404
4698
  const oldStatus = card.status;
4405
4699
  card.status = newStatus;
4406
4700
  card.modified = (/* @__PURE__ */ new Date()).toISOString();
4407
4701
  if (oldStatus !== newStatus) {
4408
- card.completedAt = newStatus === "done" ? (/* @__PURE__ */ new Date()).toISOString() : null;
4702
+ card.completedAt = this._isCompletedStatus(newStatus, resolvedBoardId) ? (/* @__PURE__ */ new Date()).toISOString() : null;
4409
4703
  }
4410
4704
  const targetColumnCards = cards.filter((c) => c.status === newStatus && c.id !== cardId).sort((a, b) => a.order < b.order ? -1 : a.order > b.order ? 1 : 0);
4411
4705
  const pos = position !== void 0 ? Math.max(0, Math.min(position, targetColumnCards.length)) : targetColumnCards.length;
4412
4706
  const before = pos > 0 ? targetColumnCards[pos - 1].order : null;
4413
4707
  const after = pos < targetColumnCards.length ? targetColumnCards[pos].order : null;
4414
4708
  card.order = generateKeyBetween(before, after);
4415
- await fs3.writeFile(card.filePath, serializeFeature(card), "utf-8");
4709
+ await fs4.writeFile(card.filePath, serializeFeature(card), "utf-8");
4416
4710
  if (oldStatus !== newStatus) {
4417
- const newPath = await moveFeatureFile(card.filePath, this.featuresDir, newStatus, card.attachments);
4711
+ const newPath = await moveFeatureFile(card.filePath, boardDir, newStatus, card.attachments);
4418
4712
  card.filePath = newPath;
4419
4713
  }
4420
4714
  return card;
4421
4715
  }
4422
- async deleteCard(cardId) {
4423
- const card = await this.getCard(cardId);
4716
+ async deleteCard(cardId, boardId) {
4717
+ const card = await this.getCard(cardId, boardId);
4424
4718
  if (!card)
4425
4719
  throw new Error(`Card not found: ${cardId}`);
4426
- await fs3.unlink(card.filePath);
4720
+ await fs4.unlink(card.filePath);
4427
4721
  }
4428
- async getCardsByStatus(status) {
4429
- const cards = await this.listCards();
4722
+ async getCardsByStatus(status, boardId) {
4723
+ const cards = await this.listCards(void 0, boardId);
4430
4724
  return cards.filter((c) => c.status === status);
4431
4725
  }
4432
- async getUniqueAssignees() {
4433
- const cards = await this.listCards();
4726
+ async getUniqueAssignees(boardId) {
4727
+ const cards = await this.listCards(void 0, boardId);
4434
4728
  const assignees = /* @__PURE__ */ new Set();
4435
4729
  for (const c of cards) {
4436
4730
  if (c.assignee)
@@ -4438,8 +4732,8 @@ var KanbanSDK = class {
4438
4732
  }
4439
4733
  return [...assignees].sort();
4440
4734
  }
4441
- async getUniqueLabels() {
4442
- const cards = await this.listCards();
4735
+ async getUniqueLabels(boardId) {
4736
+ const cards = await this.listCards(void 0, boardId);
4443
4737
  const labels = /* @__PURE__ */ new Set();
4444
4738
  for (const c of cards) {
4445
4739
  for (const l of c.labels)
@@ -4448,48 +4742,48 @@ var KanbanSDK = class {
4448
4742
  return [...labels].sort();
4449
4743
  }
4450
4744
  // --- Attachment management ---
4451
- async addAttachment(cardId, sourcePath) {
4452
- const card = await this.getCard(cardId);
4745
+ async addAttachment(cardId, sourcePath, boardId) {
4746
+ const card = await this.getCard(cardId, boardId);
4453
4747
  if (!card)
4454
4748
  throw new Error(`Card not found: ${cardId}`);
4455
- const fileName = path4.basename(sourcePath);
4456
- const cardDir = path4.dirname(card.filePath);
4457
- const destPath = path4.join(cardDir, fileName);
4458
- const sourceDir = path4.dirname(path4.resolve(sourcePath));
4749
+ const fileName = path5.basename(sourcePath);
4750
+ const cardDir = path5.dirname(card.filePath);
4751
+ const destPath = path5.join(cardDir, fileName);
4752
+ const sourceDir = path5.dirname(path5.resolve(sourcePath));
4459
4753
  if (sourceDir !== cardDir) {
4460
- await fs3.copyFile(path4.resolve(sourcePath), destPath);
4754
+ await fs4.copyFile(path5.resolve(sourcePath), destPath);
4461
4755
  }
4462
4756
  if (!card.attachments.includes(fileName)) {
4463
4757
  card.attachments.push(fileName);
4464
4758
  }
4465
4759
  card.modified = (/* @__PURE__ */ new Date()).toISOString();
4466
- await fs3.writeFile(card.filePath, serializeFeature(card), "utf-8");
4760
+ await fs4.writeFile(card.filePath, serializeFeature(card), "utf-8");
4467
4761
  return card;
4468
4762
  }
4469
- async removeAttachment(cardId, attachment) {
4470
- const card = await this.getCard(cardId);
4763
+ async removeAttachment(cardId, attachment, boardId) {
4764
+ const card = await this.getCard(cardId, boardId);
4471
4765
  if (!card)
4472
4766
  throw new Error(`Card not found: ${cardId}`);
4473
4767
  card.attachments = card.attachments.filter((a) => a !== attachment);
4474
4768
  card.modified = (/* @__PURE__ */ new Date()).toISOString();
4475
- await fs3.writeFile(card.filePath, serializeFeature(card), "utf-8");
4769
+ await fs4.writeFile(card.filePath, serializeFeature(card), "utf-8");
4476
4770
  return card;
4477
4771
  }
4478
- async listAttachments(cardId) {
4479
- const card = await this.getCard(cardId);
4772
+ async listAttachments(cardId, boardId) {
4773
+ const card = await this.getCard(cardId, boardId);
4480
4774
  if (!card)
4481
4775
  throw new Error(`Card not found: ${cardId}`);
4482
4776
  return card.attachments;
4483
4777
  }
4484
4778
  // --- Comment management ---
4485
- async listComments(cardId) {
4486
- const card = await this.getCard(cardId);
4779
+ async listComments(cardId, boardId) {
4780
+ const card = await this.getCard(cardId, boardId);
4487
4781
  if (!card)
4488
4782
  throw new Error(`Card not found: ${cardId}`);
4489
4783
  return card.comments || [];
4490
4784
  }
4491
- async addComment(cardId, author, content) {
4492
- const card = await this.getCard(cardId);
4785
+ async addComment(cardId, author, content, boardId) {
4786
+ const card = await this.getCard(cardId, boardId);
4493
4787
  if (!card)
4494
4788
  throw new Error(`Card not found: ${cardId}`);
4495
4789
  if (!card.comments)
@@ -4506,11 +4800,11 @@ var KanbanSDK = class {
4506
4800
  };
4507
4801
  card.comments.push(comment);
4508
4802
  card.modified = (/* @__PURE__ */ new Date()).toISOString();
4509
- await fs3.writeFile(card.filePath, serializeFeature(card), "utf-8");
4803
+ await fs4.writeFile(card.filePath, serializeFeature(card), "utf-8");
4510
4804
  return card;
4511
4805
  }
4512
- async updateComment(cardId, commentId, content) {
4513
- const card = await this.getCard(cardId);
4806
+ async updateComment(cardId, commentId, content, boardId) {
4807
+ const card = await this.getCard(cardId, boardId);
4514
4808
  if (!card)
4515
4809
  throw new Error(`Card not found: ${cardId}`);
4516
4810
  const comment = (card.comments || []).find((c) => c.id === commentId);
@@ -4518,34 +4812,45 @@ var KanbanSDK = class {
4518
4812
  throw new Error(`Comment not found: ${commentId}`);
4519
4813
  comment.content = content;
4520
4814
  card.modified = (/* @__PURE__ */ new Date()).toISOString();
4521
- await fs3.writeFile(card.filePath, serializeFeature(card), "utf-8");
4815
+ await fs4.writeFile(card.filePath, serializeFeature(card), "utf-8");
4522
4816
  return card;
4523
4817
  }
4524
- async deleteComment(cardId, commentId) {
4525
- const card = await this.getCard(cardId);
4818
+ async deleteComment(cardId, commentId, boardId) {
4819
+ const card = await this.getCard(cardId, boardId);
4526
4820
  if (!card)
4527
4821
  throw new Error(`Card not found: ${cardId}`);
4528
4822
  card.comments = (card.comments || []).filter((c) => c.id !== commentId);
4529
4823
  card.modified = (/* @__PURE__ */ new Date()).toISOString();
4530
- await fs3.writeFile(card.filePath, serializeFeature(card), "utf-8");
4824
+ await fs4.writeFile(card.filePath, serializeFeature(card), "utf-8");
4531
4825
  return card;
4532
4826
  }
4533
- // --- Column management ---
4534
- listColumns() {
4535
- return readConfig(this.workspaceRoot).columns;
4827
+ // --- Column management (board-scoped) ---
4828
+ listColumns(boardId) {
4829
+ const config = readConfig(this.workspaceRoot);
4830
+ const resolvedId = boardId || config.defaultBoard;
4831
+ const board = config.boards[resolvedId];
4832
+ return board?.columns || [];
4536
4833
  }
4537
- addColumn(column) {
4834
+ addColumn(column, boardId) {
4538
4835
  const config = readConfig(this.workspaceRoot);
4539
- if (config.columns.some((c) => c.id === column.id)) {
4836
+ const resolvedId = boardId || config.defaultBoard;
4837
+ const board = config.boards[resolvedId];
4838
+ if (!board)
4839
+ throw new Error(`Board not found: ${resolvedId}`);
4840
+ if (board.columns.some((c) => c.id === column.id)) {
4540
4841
  throw new Error(`Column already exists: ${column.id}`);
4541
4842
  }
4542
- config.columns.push(column);
4843
+ board.columns.push(column);
4543
4844
  writeConfig(this.workspaceRoot, config);
4544
- return config.columns;
4845
+ return board.columns;
4545
4846
  }
4546
- updateColumn(columnId, updates) {
4847
+ updateColumn(columnId, updates, boardId) {
4547
4848
  const config = readConfig(this.workspaceRoot);
4548
- const col = config.columns.find((c) => c.id === columnId);
4849
+ const resolvedId = boardId || config.defaultBoard;
4850
+ const board = config.boards[resolvedId];
4851
+ if (!board)
4852
+ throw new Error(`Board not found: ${resolvedId}`);
4853
+ const col = board.columns.find((c) => c.id === columnId);
4549
4854
  if (!col)
4550
4855
  throw new Error(`Column not found: ${columnId}`);
4551
4856
  if (updates.name !== void 0)
@@ -4553,37 +4858,45 @@ var KanbanSDK = class {
4553
4858
  if (updates.color !== void 0)
4554
4859
  col.color = updates.color;
4555
4860
  writeConfig(this.workspaceRoot, config);
4556
- return config.columns;
4861
+ return board.columns;
4557
4862
  }
4558
- async removeColumn(columnId) {
4863
+ async removeColumn(columnId, boardId) {
4559
4864
  const config = readConfig(this.workspaceRoot);
4560
- const idx = config.columns.findIndex((c) => c.id === columnId);
4865
+ const resolvedId = boardId || config.defaultBoard;
4866
+ const board = config.boards[resolvedId];
4867
+ if (!board)
4868
+ throw new Error(`Board not found: ${resolvedId}`);
4869
+ const idx = board.columns.findIndex((c) => c.id === columnId);
4561
4870
  if (idx === -1)
4562
4871
  throw new Error(`Column not found: ${columnId}`);
4563
- const cards = await this.listCards();
4872
+ const cards = await this.listCards(void 0, resolvedId);
4564
4873
  const cardsInColumn = cards.filter((c) => c.status === columnId);
4565
4874
  if (cardsInColumn.length > 0) {
4566
4875
  throw new Error(`Cannot remove column "${columnId}": ${cardsInColumn.length} card(s) still in this column`);
4567
4876
  }
4568
- config.columns.splice(idx, 1);
4877
+ board.columns.splice(idx, 1);
4569
4878
  writeConfig(this.workspaceRoot, config);
4570
- return config.columns;
4879
+ return board.columns;
4571
4880
  }
4572
- reorderColumns(columnIds) {
4881
+ reorderColumns(columnIds, boardId) {
4573
4882
  const config = readConfig(this.workspaceRoot);
4574
- const colMap = new Map(config.columns.map((c) => [c.id, c]));
4883
+ const resolvedId = boardId || config.defaultBoard;
4884
+ const board = config.boards[resolvedId];
4885
+ if (!board)
4886
+ throw new Error(`Board not found: ${resolvedId}`);
4887
+ const colMap = new Map(board.columns.map((c) => [c.id, c]));
4575
4888
  for (const id of columnIds) {
4576
4889
  if (!colMap.has(id))
4577
4890
  throw new Error(`Column not found: ${id}`);
4578
4891
  }
4579
- if (columnIds.length !== config.columns.length) {
4892
+ if (columnIds.length !== board.columns.length) {
4580
4893
  throw new Error("Must include all column IDs when reordering");
4581
4894
  }
4582
- config.columns = columnIds.map((id) => colMap.get(id));
4895
+ board.columns = columnIds.map((id) => colMap.get(id));
4583
4896
  writeConfig(this.workspaceRoot, config);
4584
- return config.columns;
4897
+ return board.columns;
4585
4898
  }
4586
- // --- Settings management ---
4899
+ // --- Settings management (global) ---
4587
4900
  getSettings() {
4588
4901
  return configToSettings(readConfig(this.workspaceRoot));
4589
4902
  }
@@ -4593,19 +4906,19 @@ var KanbanSDK = class {
4593
4906
  }
4594
4907
  // --- Private helpers ---
4595
4908
  async _readMdFiles(dir) {
4596
- const entries = await fs3.readdir(dir, { withFileTypes: true });
4597
- return entries.filter((e) => e.isFile() && e.name.endsWith(".md")).map((e) => path4.join(dir, e.name));
4909
+ const entries = await fs4.readdir(dir, { withFileTypes: true });
4910
+ return entries.filter((e) => e.isFile() && e.name.endsWith(".md")).map((e) => path5.join(dir, e.name));
4598
4911
  }
4599
4912
  async _loadCard(filePath) {
4600
- const content = await fs3.readFile(filePath, "utf-8");
4913
+ const content = await fs4.readFile(filePath, "utf-8");
4601
4914
  return parseFeatureFile(content, filePath);
4602
4915
  }
4603
4916
  };
4604
4917
 
4605
4918
  // src/standalone/server.ts
4606
4919
  var http2 = __toESM(require("http"));
4607
- var fs5 = __toESM(require("fs"));
4608
- var path6 = __toESM(require("path"));
4920
+ var fs6 = __toESM(require("fs"));
4921
+ var path7 = __toESM(require("path"));
4609
4922
 
4610
4923
  // node_modules/.pnpm/ws@8.19.0/node_modules/ws/wrapper.mjs
4611
4924
  var import_stream = __toESM(require_stream(), 1);
@@ -4690,7 +5003,7 @@ var ReaddirpStream = class extends import_node_stream.Readable {
4690
5003
  this._directoryFilter = normalizeFilter(opts.directoryFilter);
4691
5004
  const statMethod = opts.lstat ? import_promises.lstat : import_promises.stat;
4692
5005
  if (wantBigintFsStats) {
4693
- this._stat = (path10) => statMethod(path10, { bigint: true });
5006
+ this._stat = (path11) => statMethod(path11, { bigint: true });
4694
5007
  } else {
4695
5008
  this._stat = statMethod;
4696
5009
  }
@@ -4715,8 +5028,8 @@ var ReaddirpStream = class extends import_node_stream.Readable {
4715
5028
  const par = this.parent;
4716
5029
  const fil = par && par.files;
4717
5030
  if (fil && fil.length > 0) {
4718
- const { path: path10, depth } = par;
4719
- const slice = fil.splice(0, batch).map((dirent) => this._formatEntry(dirent, path10));
5031
+ const { path: path11, depth } = par;
5032
+ const slice = fil.splice(0, batch).map((dirent) => this._formatEntry(dirent, path11));
4720
5033
  const awaited = await Promise.all(slice);
4721
5034
  for (const entry of awaited) {
4722
5035
  if (!entry)
@@ -4756,20 +5069,20 @@ var ReaddirpStream = class extends import_node_stream.Readable {
4756
5069
  this.reading = false;
4757
5070
  }
4758
5071
  }
4759
- async _exploreDir(path10, depth) {
5072
+ async _exploreDir(path11, depth) {
4760
5073
  let files;
4761
5074
  try {
4762
- files = await (0, import_promises.readdir)(path10, this._rdOptions);
5075
+ files = await (0, import_promises.readdir)(path11, this._rdOptions);
4763
5076
  } catch (error) {
4764
5077
  this._onError(error);
4765
5078
  }
4766
- return { files, depth, path: path10 };
5079
+ return { files, depth, path: path11 };
4767
5080
  }
4768
- async _formatEntry(dirent, path10) {
5081
+ async _formatEntry(dirent, path11) {
4769
5082
  let entry;
4770
5083
  const basename6 = this._isDirent ? dirent.name : dirent;
4771
5084
  try {
4772
- const fullPath = (0, import_node_path.resolve)((0, import_node_path.join)(path10, basename6));
5085
+ const fullPath = (0, import_node_path.resolve)((0, import_node_path.join)(path11, basename6));
4773
5086
  entry = { path: (0, import_node_path.relative)(this._root, fullPath), fullPath, basename: basename6 };
4774
5087
  entry[this._statsProp] = this._isDirent ? dirent : await this._stat(fullPath);
4775
5088
  } catch (err) {
@@ -5169,16 +5482,16 @@ var delFromSet = (main, prop, item) => {
5169
5482
  };
5170
5483
  var isEmptySet = (val) => val instanceof Set ? val.size === 0 : !val;
5171
5484
  var FsWatchInstances = /* @__PURE__ */ new Map();
5172
- function createFsWatchInstance(path10, options, listener, errHandler, emitRaw) {
5485
+ function createFsWatchInstance(path11, options, listener, errHandler, emitRaw) {
5173
5486
  const handleEvent = (rawEvent, evPath) => {
5174
- listener(path10);
5175
- emitRaw(rawEvent, evPath, { watchedPath: path10 });
5176
- if (evPath && path10 !== evPath) {
5177
- fsWatchBroadcast(sysPath.resolve(path10, evPath), KEY_LISTENERS, sysPath.join(path10, evPath));
5487
+ listener(path11);
5488
+ emitRaw(rawEvent, evPath, { watchedPath: path11 });
5489
+ if (evPath && path11 !== evPath) {
5490
+ fsWatchBroadcast(sysPath.resolve(path11, evPath), KEY_LISTENERS, sysPath.join(path11, evPath));
5178
5491
  }
5179
5492
  };
5180
5493
  try {
5181
- return (0, import_fs.watch)(path10, {
5494
+ return (0, import_fs.watch)(path11, {
5182
5495
  persistent: options.persistent
5183
5496
  }, handleEvent);
5184
5497
  } catch (error) {
@@ -5194,12 +5507,12 @@ var fsWatchBroadcast = (fullPath, listenerType, val1, val2, val3) => {
5194
5507
  listener(val1, val2, val3);
5195
5508
  });
5196
5509
  };
5197
- var setFsWatchListener = (path10, fullPath, options, handlers) => {
5510
+ var setFsWatchListener = (path11, fullPath, options, handlers) => {
5198
5511
  const { listener, errHandler, rawEmitter } = handlers;
5199
5512
  let cont = FsWatchInstances.get(fullPath);
5200
5513
  let watcher;
5201
5514
  if (!options.persistent) {
5202
- watcher = createFsWatchInstance(path10, options, listener, errHandler, rawEmitter);
5515
+ watcher = createFsWatchInstance(path11, options, listener, errHandler, rawEmitter);
5203
5516
  if (!watcher)
5204
5517
  return;
5205
5518
  return watcher.close.bind(watcher);
@@ -5210,7 +5523,7 @@ var setFsWatchListener = (path10, fullPath, options, handlers) => {
5210
5523
  addAndConvert(cont, KEY_RAW, rawEmitter);
5211
5524
  } else {
5212
5525
  watcher = createFsWatchInstance(
5213
- path10,
5526
+ path11,
5214
5527
  options,
5215
5528
  fsWatchBroadcast.bind(null, fullPath, KEY_LISTENERS),
5216
5529
  errHandler,
@@ -5225,7 +5538,7 @@ var setFsWatchListener = (path10, fullPath, options, handlers) => {
5225
5538
  cont.watcherUnusable = true;
5226
5539
  if (isWindows && error.code === "EPERM") {
5227
5540
  try {
5228
- const fd = await (0, import_promises2.open)(path10, "r");
5541
+ const fd = await (0, import_promises2.open)(path11, "r");
5229
5542
  await fd.close();
5230
5543
  broadcastErr(error);
5231
5544
  } catch (err) {
@@ -5256,7 +5569,7 @@ var setFsWatchListener = (path10, fullPath, options, handlers) => {
5256
5569
  };
5257
5570
  };
5258
5571
  var FsWatchFileInstances = /* @__PURE__ */ new Map();
5259
- var setFsWatchFileListener = (path10, fullPath, options, handlers) => {
5572
+ var setFsWatchFileListener = (path11, fullPath, options, handlers) => {
5260
5573
  const { listener, rawEmitter } = handlers;
5261
5574
  let cont = FsWatchFileInstances.get(fullPath);
5262
5575
  const copts = cont && cont.options;
@@ -5278,7 +5591,7 @@ var setFsWatchFileListener = (path10, fullPath, options, handlers) => {
5278
5591
  });
5279
5592
  const currmtime = curr.mtimeMs;
5280
5593
  if (curr.size !== prev.size || currmtime > prev.mtimeMs || currmtime === 0) {
5281
- foreach(cont.listeners, (listener2) => listener2(path10, curr));
5594
+ foreach(cont.listeners, (listener2) => listener2(path11, curr));
5282
5595
  }
5283
5596
  })
5284
5597
  };
@@ -5306,13 +5619,13 @@ var NodeFsHandler = class {
5306
5619
  * @param listener on fs change
5307
5620
  * @returns closer for the watcher instance
5308
5621
  */
5309
- _watchWithNodeFs(path10, listener) {
5622
+ _watchWithNodeFs(path11, listener) {
5310
5623
  const opts = this.fsw.options;
5311
- const directory = sysPath.dirname(path10);
5312
- const basename6 = sysPath.basename(path10);
5624
+ const directory = sysPath.dirname(path11);
5625
+ const basename6 = sysPath.basename(path11);
5313
5626
  const parent = this.fsw._getWatchedDir(directory);
5314
5627
  parent.add(basename6);
5315
- const absolutePath = sysPath.resolve(path10);
5628
+ const absolutePath = sysPath.resolve(path11);
5316
5629
  const options = {
5317
5630
  persistent: opts.persistent
5318
5631
  };
@@ -5322,12 +5635,12 @@ var NodeFsHandler = class {
5322
5635
  if (opts.usePolling) {
5323
5636
  const enableBin = opts.interval !== opts.binaryInterval;
5324
5637
  options.interval = enableBin && isBinaryPath(basename6) ? opts.binaryInterval : opts.interval;
5325
- closer = setFsWatchFileListener(path10, absolutePath, options, {
5638
+ closer = setFsWatchFileListener(path11, absolutePath, options, {
5326
5639
  listener,
5327
5640
  rawEmitter: this.fsw._emitRaw
5328
5641
  });
5329
5642
  } else {
5330
- closer = setFsWatchListener(path10, absolutePath, options, {
5643
+ closer = setFsWatchListener(path11, absolutePath, options, {
5331
5644
  listener,
5332
5645
  errHandler: this._boundHandleError,
5333
5646
  rawEmitter: this.fsw._emitRaw
@@ -5349,7 +5662,7 @@ var NodeFsHandler = class {
5349
5662
  let prevStats = stats;
5350
5663
  if (parent.has(basename6))
5351
5664
  return;
5352
- const listener = async (path10, newStats) => {
5665
+ const listener = async (path11, newStats) => {
5353
5666
  if (!this.fsw._throttle(THROTTLE_MODE_WATCH, file, 5))
5354
5667
  return;
5355
5668
  if (!newStats || newStats.mtimeMs === 0) {
@@ -5363,11 +5676,11 @@ var NodeFsHandler = class {
5363
5676
  this.fsw._emit(EV.CHANGE, file, newStats2);
5364
5677
  }
5365
5678
  if ((isMacos || isLinux || isFreeBSD) && prevStats.ino !== newStats2.ino) {
5366
- this.fsw._closeFile(path10);
5679
+ this.fsw._closeFile(path11);
5367
5680
  prevStats = newStats2;
5368
5681
  const closer2 = this._watchWithNodeFs(file, listener);
5369
5682
  if (closer2)
5370
- this.fsw._addPathCloser(path10, closer2);
5683
+ this.fsw._addPathCloser(path11, closer2);
5371
5684
  } else {
5372
5685
  prevStats = newStats2;
5373
5686
  }
@@ -5399,7 +5712,7 @@ var NodeFsHandler = class {
5399
5712
  * @param item basename of this item
5400
5713
  * @returns true if no more processing is needed for this entry.
5401
5714
  */
5402
- async _handleSymlink(entry, directory, path10, item) {
5715
+ async _handleSymlink(entry, directory, path11, item) {
5403
5716
  if (this.fsw.closed) {
5404
5717
  return;
5405
5718
  }
@@ -5409,7 +5722,7 @@ var NodeFsHandler = class {
5409
5722
  this.fsw._incrReadyCount();
5410
5723
  let linkPath;
5411
5724
  try {
5412
- linkPath = await (0, import_promises2.realpath)(path10);
5725
+ linkPath = await (0, import_promises2.realpath)(path11);
5413
5726
  } catch (e) {
5414
5727
  this.fsw._emitReady();
5415
5728
  return true;
@@ -5419,12 +5732,12 @@ var NodeFsHandler = class {
5419
5732
  if (dir.has(item)) {
5420
5733
  if (this.fsw._symlinkPaths.get(full) !== linkPath) {
5421
5734
  this.fsw._symlinkPaths.set(full, linkPath);
5422
- this.fsw._emit(EV.CHANGE, path10, entry.stats);
5735
+ this.fsw._emit(EV.CHANGE, path11, entry.stats);
5423
5736
  }
5424
5737
  } else {
5425
5738
  dir.add(item);
5426
5739
  this.fsw._symlinkPaths.set(full, linkPath);
5427
- this.fsw._emit(EV.ADD, path10, entry.stats);
5740
+ this.fsw._emit(EV.ADD, path11, entry.stats);
5428
5741
  }
5429
5742
  this.fsw._emitReady();
5430
5743
  return true;
@@ -5453,9 +5766,9 @@ var NodeFsHandler = class {
5453
5766
  return;
5454
5767
  }
5455
5768
  const item = entry.path;
5456
- let path10 = sysPath.join(directory, item);
5769
+ let path11 = sysPath.join(directory, item);
5457
5770
  current.add(item);
5458
- if (entry.stats.isSymbolicLink() && await this._handleSymlink(entry, directory, path10, item)) {
5771
+ if (entry.stats.isSymbolicLink() && await this._handleSymlink(entry, directory, path11, item)) {
5459
5772
  return;
5460
5773
  }
5461
5774
  if (this.fsw.closed) {
@@ -5464,8 +5777,8 @@ var NodeFsHandler = class {
5464
5777
  }
5465
5778
  if (item === target || !target && !previous.has(item)) {
5466
5779
  this.fsw._incrReadyCount();
5467
- path10 = sysPath.join(dir, sysPath.relative(dir, path10));
5468
- this._addToNodeFs(path10, initialAdd, wh, depth + 1);
5780
+ path11 = sysPath.join(dir, sysPath.relative(dir, path11));
5781
+ this._addToNodeFs(path11, initialAdd, wh, depth + 1);
5469
5782
  }
5470
5783
  }).on(EV.ERROR, this._boundHandleError);
5471
5784
  return new Promise((resolve6, reject) => {
@@ -5534,13 +5847,13 @@ var NodeFsHandler = class {
5534
5847
  * @param depth Child path actually targeted for watch
5535
5848
  * @param target Child path actually targeted for watch
5536
5849
  */
5537
- async _addToNodeFs(path10, initialAdd, priorWh, depth, target) {
5850
+ async _addToNodeFs(path11, initialAdd, priorWh, depth, target) {
5538
5851
  const ready = this.fsw._emitReady;
5539
- if (this.fsw._isIgnored(path10) || this.fsw.closed) {
5852
+ if (this.fsw._isIgnored(path11) || this.fsw.closed) {
5540
5853
  ready();
5541
5854
  return false;
5542
5855
  }
5543
- const wh = this.fsw._getWatchHelpers(path10);
5856
+ const wh = this.fsw._getWatchHelpers(path11);
5544
5857
  if (priorWh) {
5545
5858
  wh.filterPath = (entry) => priorWh.filterPath(entry);
5546
5859
  wh.filterDir = (entry) => priorWh.filterDir(entry);
@@ -5556,8 +5869,8 @@ var NodeFsHandler = class {
5556
5869
  const follow = this.fsw.options.followSymlinks;
5557
5870
  let closer;
5558
5871
  if (stats.isDirectory()) {
5559
- const absPath = sysPath.resolve(path10);
5560
- const targetPath = follow ? await (0, import_promises2.realpath)(path10) : path10;
5872
+ const absPath = sysPath.resolve(path11);
5873
+ const targetPath = follow ? await (0, import_promises2.realpath)(path11) : path11;
5561
5874
  if (this.fsw.closed)
5562
5875
  return;
5563
5876
  closer = await this._handleDir(wh.watchPath, stats, initialAdd, depth, target, wh, targetPath);
@@ -5567,29 +5880,29 @@ var NodeFsHandler = class {
5567
5880
  this.fsw._symlinkPaths.set(absPath, targetPath);
5568
5881
  }
5569
5882
  } else if (stats.isSymbolicLink()) {
5570
- const targetPath = follow ? await (0, import_promises2.realpath)(path10) : path10;
5883
+ const targetPath = follow ? await (0, import_promises2.realpath)(path11) : path11;
5571
5884
  if (this.fsw.closed)
5572
5885
  return;
5573
5886
  const parent = sysPath.dirname(wh.watchPath);
5574
5887
  this.fsw._getWatchedDir(parent).add(wh.watchPath);
5575
5888
  this.fsw._emit(EV.ADD, wh.watchPath, stats);
5576
- closer = await this._handleDir(parent, stats, initialAdd, depth, path10, wh, targetPath);
5889
+ closer = await this._handleDir(parent, stats, initialAdd, depth, path11, wh, targetPath);
5577
5890
  if (this.fsw.closed)
5578
5891
  return;
5579
5892
  if (targetPath !== void 0) {
5580
- this.fsw._symlinkPaths.set(sysPath.resolve(path10), targetPath);
5893
+ this.fsw._symlinkPaths.set(sysPath.resolve(path11), targetPath);
5581
5894
  }
5582
5895
  } else {
5583
5896
  closer = this._handleFile(wh.watchPath, stats, initialAdd);
5584
5897
  }
5585
5898
  ready();
5586
5899
  if (closer)
5587
- this.fsw._addPathCloser(path10, closer);
5900
+ this.fsw._addPathCloser(path11, closer);
5588
5901
  return false;
5589
5902
  } catch (error) {
5590
5903
  if (this.fsw._handleError(error)) {
5591
5904
  ready();
5592
- return path10;
5905
+ return path11;
5593
5906
  }
5594
5907
  }
5595
5908
  }
@@ -5632,26 +5945,26 @@ function createPattern(matcher) {
5632
5945
  }
5633
5946
  return () => false;
5634
5947
  }
5635
- function normalizePath(path10) {
5636
- if (typeof path10 !== "string")
5948
+ function normalizePath(path11) {
5949
+ if (typeof path11 !== "string")
5637
5950
  throw new Error("string expected");
5638
- path10 = sysPath2.normalize(path10);
5639
- path10 = path10.replace(/\\/g, "/");
5951
+ path11 = sysPath2.normalize(path11);
5952
+ path11 = path11.replace(/\\/g, "/");
5640
5953
  let prepend = false;
5641
- if (path10.startsWith("//"))
5954
+ if (path11.startsWith("//"))
5642
5955
  prepend = true;
5643
5956
  const DOUBLE_SLASH_RE2 = /\/\//;
5644
- while (path10.match(DOUBLE_SLASH_RE2))
5645
- path10 = path10.replace(DOUBLE_SLASH_RE2, "/");
5957
+ while (path11.match(DOUBLE_SLASH_RE2))
5958
+ path11 = path11.replace(DOUBLE_SLASH_RE2, "/");
5646
5959
  if (prepend)
5647
- path10 = "/" + path10;
5648
- return path10;
5960
+ path11 = "/" + path11;
5961
+ return path11;
5649
5962
  }
5650
5963
  function matchPatterns(patterns, testString, stats) {
5651
- const path10 = normalizePath(testString);
5964
+ const path11 = normalizePath(testString);
5652
5965
  for (let index = 0; index < patterns.length; index++) {
5653
5966
  const pattern = patterns[index];
5654
- if (pattern(path10, stats)) {
5967
+ if (pattern(path11, stats)) {
5655
5968
  return true;
5656
5969
  }
5657
5970
  }
@@ -5691,19 +6004,19 @@ var toUnix = (string) => {
5691
6004
  }
5692
6005
  return str;
5693
6006
  };
5694
- var normalizePathToUnix = (path10) => toUnix(sysPath2.normalize(toUnix(path10)));
5695
- var normalizeIgnored = (cwd = "") => (path10) => {
5696
- if (typeof path10 === "string") {
5697
- return normalizePathToUnix(sysPath2.isAbsolute(path10) ? path10 : sysPath2.join(cwd, path10));
6007
+ var normalizePathToUnix = (path11) => toUnix(sysPath2.normalize(toUnix(path11)));
6008
+ var normalizeIgnored = (cwd = "") => (path11) => {
6009
+ if (typeof path11 === "string") {
6010
+ return normalizePathToUnix(sysPath2.isAbsolute(path11) ? path11 : sysPath2.join(cwd, path11));
5698
6011
  } else {
5699
- return path10;
6012
+ return path11;
5700
6013
  }
5701
6014
  };
5702
- var getAbsolutePath = (path10, cwd) => {
5703
- if (sysPath2.isAbsolute(path10)) {
5704
- return path10;
6015
+ var getAbsolutePath = (path11, cwd) => {
6016
+ if (sysPath2.isAbsolute(path11)) {
6017
+ return path11;
5705
6018
  }
5706
- return sysPath2.join(cwd, path10);
6019
+ return sysPath2.join(cwd, path11);
5707
6020
  };
5708
6021
  var EMPTY_SET = Object.freeze(/* @__PURE__ */ new Set());
5709
6022
  var DirEntry = class {
@@ -5758,10 +6071,10 @@ var DirEntry = class {
5758
6071
  var STAT_METHOD_F = "stat";
5759
6072
  var STAT_METHOD_L = "lstat";
5760
6073
  var WatchHelper = class {
5761
- constructor(path10, follow, fsw) {
6074
+ constructor(path11, follow, fsw) {
5762
6075
  this.fsw = fsw;
5763
- const watchPath = path10;
5764
- this.path = path10 = path10.replace(REPLACER_RE, "");
6076
+ const watchPath = path11;
6077
+ this.path = path11 = path11.replace(REPLACER_RE, "");
5765
6078
  this.watchPath = watchPath;
5766
6079
  this.fullWatchPath = sysPath2.resolve(watchPath);
5767
6080
  this.dirParts = [];
@@ -5883,20 +6196,20 @@ var FSWatcher = class extends import_events.EventEmitter {
5883
6196
  this._closePromise = void 0;
5884
6197
  let paths = unifyPaths(paths_);
5885
6198
  if (cwd) {
5886
- paths = paths.map((path10) => {
5887
- const absPath = getAbsolutePath(path10, cwd);
6199
+ paths = paths.map((path11) => {
6200
+ const absPath = getAbsolutePath(path11, cwd);
5888
6201
  return absPath;
5889
6202
  });
5890
6203
  }
5891
- paths.forEach((path10) => {
5892
- this._removeIgnoredPath(path10);
6204
+ paths.forEach((path11) => {
6205
+ this._removeIgnoredPath(path11);
5893
6206
  });
5894
6207
  this._userIgnored = void 0;
5895
6208
  if (!this._readyCount)
5896
6209
  this._readyCount = 0;
5897
6210
  this._readyCount += paths.length;
5898
- Promise.all(paths.map(async (path10) => {
5899
- const res = await this._nodeFsHandler._addToNodeFs(path10, !_internal, void 0, 0, _origAdd);
6211
+ Promise.all(paths.map(async (path11) => {
6212
+ const res = await this._nodeFsHandler._addToNodeFs(path11, !_internal, void 0, 0, _origAdd);
5900
6213
  if (res)
5901
6214
  this._emitReady();
5902
6215
  return res;
@@ -5918,17 +6231,17 @@ var FSWatcher = class extends import_events.EventEmitter {
5918
6231
  return this;
5919
6232
  const paths = unifyPaths(paths_);
5920
6233
  const { cwd } = this.options;
5921
- paths.forEach((path10) => {
5922
- if (!sysPath2.isAbsolute(path10) && !this._closers.has(path10)) {
6234
+ paths.forEach((path11) => {
6235
+ if (!sysPath2.isAbsolute(path11) && !this._closers.has(path11)) {
5923
6236
  if (cwd)
5924
- path10 = sysPath2.join(cwd, path10);
5925
- path10 = sysPath2.resolve(path10);
6237
+ path11 = sysPath2.join(cwd, path11);
6238
+ path11 = sysPath2.resolve(path11);
5926
6239
  }
5927
- this._closePath(path10);
5928
- this._addIgnoredPath(path10);
5929
- if (this._watched.has(path10)) {
6240
+ this._closePath(path11);
6241
+ this._addIgnoredPath(path11);
6242
+ if (this._watched.has(path11)) {
5930
6243
  this._addIgnoredPath({
5931
- path: path10,
6244
+ path: path11,
5932
6245
  recursive: true
5933
6246
  });
5934
6247
  }
@@ -5992,38 +6305,38 @@ var FSWatcher = class extends import_events.EventEmitter {
5992
6305
  * @param stats arguments to be passed with event
5993
6306
  * @returns the error if defined, otherwise the value of the FSWatcher instance's `closed` flag
5994
6307
  */
5995
- async _emit(event, path10, stats) {
6308
+ async _emit(event, path11, stats) {
5996
6309
  if (this.closed)
5997
6310
  return;
5998
6311
  const opts = this.options;
5999
6312
  if (isWindows)
6000
- path10 = sysPath2.normalize(path10);
6313
+ path11 = sysPath2.normalize(path11);
6001
6314
  if (opts.cwd)
6002
- path10 = sysPath2.relative(opts.cwd, path10);
6003
- const args = [path10];
6315
+ path11 = sysPath2.relative(opts.cwd, path11);
6316
+ const args = [path11];
6004
6317
  if (stats != null)
6005
6318
  args.push(stats);
6006
6319
  const awf = opts.awaitWriteFinish;
6007
6320
  let pw;
6008
- if (awf && (pw = this._pendingWrites.get(path10))) {
6321
+ if (awf && (pw = this._pendingWrites.get(path11))) {
6009
6322
  pw.lastChange = /* @__PURE__ */ new Date();
6010
6323
  return this;
6011
6324
  }
6012
6325
  if (opts.atomic) {
6013
6326
  if (event === EVENTS.UNLINK) {
6014
- this._pendingUnlinks.set(path10, [event, ...args]);
6327
+ this._pendingUnlinks.set(path11, [event, ...args]);
6015
6328
  setTimeout(() => {
6016
- this._pendingUnlinks.forEach((entry, path11) => {
6329
+ this._pendingUnlinks.forEach((entry, path12) => {
6017
6330
  this.emit(...entry);
6018
6331
  this.emit(EVENTS.ALL, ...entry);
6019
- this._pendingUnlinks.delete(path11);
6332
+ this._pendingUnlinks.delete(path12);
6020
6333
  });
6021
6334
  }, typeof opts.atomic === "number" ? opts.atomic : 100);
6022
6335
  return this;
6023
6336
  }
6024
- if (event === EVENTS.ADD && this._pendingUnlinks.has(path10)) {
6337
+ if (event === EVENTS.ADD && this._pendingUnlinks.has(path11)) {
6025
6338
  event = EVENTS.CHANGE;
6026
- this._pendingUnlinks.delete(path10);
6339
+ this._pendingUnlinks.delete(path11);
6027
6340
  }
6028
6341
  }
6029
6342
  if (awf && (event === EVENTS.ADD || event === EVENTS.CHANGE) && this._readyEmitted) {
@@ -6041,16 +6354,16 @@ var FSWatcher = class extends import_events.EventEmitter {
6041
6354
  this.emitWithAll(event, args);
6042
6355
  }
6043
6356
  };
6044
- this._awaitWriteFinish(path10, awf.stabilityThreshold, event, awfEmit);
6357
+ this._awaitWriteFinish(path11, awf.stabilityThreshold, event, awfEmit);
6045
6358
  return this;
6046
6359
  }
6047
6360
  if (event === EVENTS.CHANGE) {
6048
- const isThrottled = !this._throttle(EVENTS.CHANGE, path10, 50);
6361
+ const isThrottled = !this._throttle(EVENTS.CHANGE, path11, 50);
6049
6362
  if (isThrottled)
6050
6363
  return this;
6051
6364
  }
6052
6365
  if (opts.alwaysStat && stats === void 0 && (event === EVENTS.ADD || event === EVENTS.ADD_DIR || event === EVENTS.CHANGE)) {
6053
- const fullPath = opts.cwd ? sysPath2.join(opts.cwd, path10) : path10;
6366
+ const fullPath = opts.cwd ? sysPath2.join(opts.cwd, path11) : path11;
6054
6367
  let stats2;
6055
6368
  try {
6056
6369
  stats2 = await (0, import_promises3.stat)(fullPath);
@@ -6081,23 +6394,23 @@ var FSWatcher = class extends import_events.EventEmitter {
6081
6394
  * @param timeout duration of time to suppress duplicate actions
6082
6395
  * @returns tracking object or false if action should be suppressed
6083
6396
  */
6084
- _throttle(actionType, path10, timeout) {
6397
+ _throttle(actionType, path11, timeout) {
6085
6398
  if (!this._throttled.has(actionType)) {
6086
6399
  this._throttled.set(actionType, /* @__PURE__ */ new Map());
6087
6400
  }
6088
6401
  const action = this._throttled.get(actionType);
6089
6402
  if (!action)
6090
6403
  throw new Error("invalid throttle");
6091
- const actionPath = action.get(path10);
6404
+ const actionPath = action.get(path11);
6092
6405
  if (actionPath) {
6093
6406
  actionPath.count++;
6094
6407
  return false;
6095
6408
  }
6096
6409
  let timeoutObject;
6097
6410
  const clear = () => {
6098
- const item = action.get(path10);
6411
+ const item = action.get(path11);
6099
6412
  const count = item ? item.count : 0;
6100
- action.delete(path10);
6413
+ action.delete(path11);
6101
6414
  clearTimeout(timeoutObject);
6102
6415
  if (item)
6103
6416
  clearTimeout(item.timeoutObject);
@@ -6105,7 +6418,7 @@ var FSWatcher = class extends import_events.EventEmitter {
6105
6418
  };
6106
6419
  timeoutObject = setTimeout(clear, timeout);
6107
6420
  const thr = { timeoutObject, clear, count: 0 };
6108
- action.set(path10, thr);
6421
+ action.set(path11, thr);
6109
6422
  return thr;
6110
6423
  }
6111
6424
  _incrReadyCount() {
@@ -6119,44 +6432,44 @@ var FSWatcher = class extends import_events.EventEmitter {
6119
6432
  * @param event
6120
6433
  * @param awfEmit Callback to be called when ready for event to be emitted.
6121
6434
  */
6122
- _awaitWriteFinish(path10, threshold, event, awfEmit) {
6435
+ _awaitWriteFinish(path11, threshold, event, awfEmit) {
6123
6436
  const awf = this.options.awaitWriteFinish;
6124
6437
  if (typeof awf !== "object")
6125
6438
  return;
6126
6439
  const pollInterval = awf.pollInterval;
6127
6440
  let timeoutHandler;
6128
- let fullPath = path10;
6129
- if (this.options.cwd && !sysPath2.isAbsolute(path10)) {
6130
- fullPath = sysPath2.join(this.options.cwd, path10);
6441
+ let fullPath = path11;
6442
+ if (this.options.cwd && !sysPath2.isAbsolute(path11)) {
6443
+ fullPath = sysPath2.join(this.options.cwd, path11);
6131
6444
  }
6132
6445
  const now = /* @__PURE__ */ new Date();
6133
6446
  const writes = this._pendingWrites;
6134
6447
  function awaitWriteFinishFn(prevStat) {
6135
6448
  (0, import_fs2.stat)(fullPath, (err, curStat) => {
6136
- if (err || !writes.has(path10)) {
6449
+ if (err || !writes.has(path11)) {
6137
6450
  if (err && err.code !== "ENOENT")
6138
6451
  awfEmit(err);
6139
6452
  return;
6140
6453
  }
6141
6454
  const now2 = Number(/* @__PURE__ */ new Date());
6142
6455
  if (prevStat && curStat.size !== prevStat.size) {
6143
- writes.get(path10).lastChange = now2;
6456
+ writes.get(path11).lastChange = now2;
6144
6457
  }
6145
- const pw = writes.get(path10);
6458
+ const pw = writes.get(path11);
6146
6459
  const df = now2 - pw.lastChange;
6147
6460
  if (df >= threshold) {
6148
- writes.delete(path10);
6461
+ writes.delete(path11);
6149
6462
  awfEmit(void 0, curStat);
6150
6463
  } else {
6151
6464
  timeoutHandler = setTimeout(awaitWriteFinishFn, pollInterval, curStat);
6152
6465
  }
6153
6466
  });
6154
6467
  }
6155
- if (!writes.has(path10)) {
6156
- writes.set(path10, {
6468
+ if (!writes.has(path11)) {
6469
+ writes.set(path11, {
6157
6470
  lastChange: now,
6158
6471
  cancelWait: () => {
6159
- writes.delete(path10);
6472
+ writes.delete(path11);
6160
6473
  clearTimeout(timeoutHandler);
6161
6474
  return event;
6162
6475
  }
@@ -6167,8 +6480,8 @@ var FSWatcher = class extends import_events.EventEmitter {
6167
6480
  /**
6168
6481
  * Determines whether user has asked to ignore this path.
6169
6482
  */
6170
- _isIgnored(path10, stats) {
6171
- if (this.options.atomic && DOT_RE.test(path10))
6483
+ _isIgnored(path11, stats) {
6484
+ if (this.options.atomic && DOT_RE.test(path11))
6172
6485
  return true;
6173
6486
  if (!this._userIgnored) {
6174
6487
  const { cwd } = this.options;
@@ -6178,17 +6491,17 @@ var FSWatcher = class extends import_events.EventEmitter {
6178
6491
  const list = [...ignoredPaths.map(normalizeIgnored(cwd)), ...ignored];
6179
6492
  this._userIgnored = anymatch(list, void 0);
6180
6493
  }
6181
- return this._userIgnored(path10, stats);
6494
+ return this._userIgnored(path11, stats);
6182
6495
  }
6183
- _isntIgnored(path10, stat4) {
6184
- return !this._isIgnored(path10, stat4);
6496
+ _isntIgnored(path11, stat4) {
6497
+ return !this._isIgnored(path11, stat4);
6185
6498
  }
6186
6499
  /**
6187
6500
  * Provides a set of common helpers and properties relating to symlink handling.
6188
6501
  * @param path file or directory pattern being watched
6189
6502
  */
6190
- _getWatchHelpers(path10) {
6191
- return new WatchHelper(path10, this.options.followSymlinks, this);
6503
+ _getWatchHelpers(path11) {
6504
+ return new WatchHelper(path11, this.options.followSymlinks, this);
6192
6505
  }
6193
6506
  // Directory helpers
6194
6507
  // -----------------
@@ -6220,63 +6533,63 @@ var FSWatcher = class extends import_events.EventEmitter {
6220
6533
  * @param item base path of item/directory
6221
6534
  */
6222
6535
  _remove(directory, item, isDirectory) {
6223
- const path10 = sysPath2.join(directory, item);
6224
- const fullPath = sysPath2.resolve(path10);
6225
- isDirectory = isDirectory != null ? isDirectory : this._watched.has(path10) || this._watched.has(fullPath);
6226
- if (!this._throttle("remove", path10, 100))
6536
+ const path11 = sysPath2.join(directory, item);
6537
+ const fullPath = sysPath2.resolve(path11);
6538
+ isDirectory = isDirectory != null ? isDirectory : this._watched.has(path11) || this._watched.has(fullPath);
6539
+ if (!this._throttle("remove", path11, 100))
6227
6540
  return;
6228
6541
  if (!isDirectory && this._watched.size === 1) {
6229
6542
  this.add(directory, item, true);
6230
6543
  }
6231
- const wp = this._getWatchedDir(path10);
6544
+ const wp = this._getWatchedDir(path11);
6232
6545
  const nestedDirectoryChildren = wp.getChildren();
6233
- nestedDirectoryChildren.forEach((nested) => this._remove(path10, nested));
6546
+ nestedDirectoryChildren.forEach((nested) => this._remove(path11, nested));
6234
6547
  const parent = this._getWatchedDir(directory);
6235
6548
  const wasTracked = parent.has(item);
6236
6549
  parent.remove(item);
6237
6550
  if (this._symlinkPaths.has(fullPath)) {
6238
6551
  this._symlinkPaths.delete(fullPath);
6239
6552
  }
6240
- let relPath = path10;
6553
+ let relPath = path11;
6241
6554
  if (this.options.cwd)
6242
- relPath = sysPath2.relative(this.options.cwd, path10);
6555
+ relPath = sysPath2.relative(this.options.cwd, path11);
6243
6556
  if (this.options.awaitWriteFinish && this._pendingWrites.has(relPath)) {
6244
6557
  const event = this._pendingWrites.get(relPath).cancelWait();
6245
6558
  if (event === EVENTS.ADD)
6246
6559
  return;
6247
6560
  }
6248
- this._watched.delete(path10);
6561
+ this._watched.delete(path11);
6249
6562
  this._watched.delete(fullPath);
6250
6563
  const eventName = isDirectory ? EVENTS.UNLINK_DIR : EVENTS.UNLINK;
6251
- if (wasTracked && !this._isIgnored(path10))
6252
- this._emit(eventName, path10);
6253
- this._closePath(path10);
6564
+ if (wasTracked && !this._isIgnored(path11))
6565
+ this._emit(eventName, path11);
6566
+ this._closePath(path11);
6254
6567
  }
6255
6568
  /**
6256
6569
  * Closes all watchers for a path
6257
6570
  */
6258
- _closePath(path10) {
6259
- this._closeFile(path10);
6260
- const dir = sysPath2.dirname(path10);
6261
- this._getWatchedDir(dir).remove(sysPath2.basename(path10));
6571
+ _closePath(path11) {
6572
+ this._closeFile(path11);
6573
+ const dir = sysPath2.dirname(path11);
6574
+ this._getWatchedDir(dir).remove(sysPath2.basename(path11));
6262
6575
  }
6263
6576
  /**
6264
6577
  * Closes only file-specific watchers
6265
6578
  */
6266
- _closeFile(path10) {
6267
- const closers = this._closers.get(path10);
6579
+ _closeFile(path11) {
6580
+ const closers = this._closers.get(path11);
6268
6581
  if (!closers)
6269
6582
  return;
6270
6583
  closers.forEach((closer) => closer());
6271
- this._closers.delete(path10);
6584
+ this._closers.delete(path11);
6272
6585
  }
6273
- _addPathCloser(path10, closer) {
6586
+ _addPathCloser(path11, closer) {
6274
6587
  if (!closer)
6275
6588
  return;
6276
- let list = this._closers.get(path10);
6589
+ let list = this._closers.get(path11);
6277
6590
  if (!list) {
6278
6591
  list = [];
6279
- this._closers.set(path10, list);
6592
+ this._closers.set(path11, list);
6280
6593
  }
6281
6594
  list.push(closer);
6282
6595
  }
@@ -6305,19 +6618,22 @@ function watch(paths, options = {}) {
6305
6618
  }
6306
6619
  var esm_default = { watch, FSWatcher };
6307
6620
 
6621
+ // src/standalone/server.ts
6622
+ init_types();
6623
+
6308
6624
  // src/standalone/webhooks.ts
6309
- var fs4 = __toESM(require("fs"));
6310
- var path5 = __toESM(require("path"));
6625
+ var fs5 = __toESM(require("fs"));
6626
+ var path6 = __toESM(require("path"));
6311
6627
  var http = __toESM(require("http"));
6312
6628
  var https = __toESM(require("https"));
6313
6629
  var crypto = __toESM(require("crypto"));
6314
6630
  var WEBHOOKS_FILENAME = ".kanban-webhooks.json";
6315
6631
  function webhooksPath(workspaceRoot) {
6316
- return path5.join(workspaceRoot, WEBHOOKS_FILENAME);
6632
+ return path6.join(workspaceRoot, WEBHOOKS_FILENAME);
6317
6633
  }
6318
6634
  function loadWebhooks(workspaceRoot) {
6319
6635
  try {
6320
- const raw = fs4.readFileSync(webhooksPath(workspaceRoot), "utf-8");
6636
+ const raw = fs5.readFileSync(webhooksPath(workspaceRoot), "utf-8");
6321
6637
  const data = JSON.parse(raw);
6322
6638
  return Array.isArray(data) ? data : [];
6323
6639
  } catch {
@@ -6325,7 +6641,7 @@ function loadWebhooks(workspaceRoot) {
6325
6641
  }
6326
6642
  }
6327
6643
  function saveWebhooks(workspaceRoot, webhooks) {
6328
- fs4.writeFileSync(webhooksPath(workspaceRoot), JSON.stringify(webhooks, null, 2) + "\n", "utf-8");
6644
+ fs5.writeFileSync(webhooksPath(workspaceRoot), JSON.stringify(webhooks, null, 2) + "\n", "utf-8");
6329
6645
  }
6330
6646
  function createWebhook(workspaceRoot, config) {
6331
6647
  const webhooks = loadWebhooks(workspaceRoot);
@@ -6420,13 +6736,14 @@ var MIME_TYPES = {
6420
6736
  ".map": "application/json"
6421
6737
  };
6422
6738
  function startServer(featuresDir, port, webviewDir) {
6423
- const absoluteFeaturesDir = path6.resolve(featuresDir);
6739
+ const absoluteFeaturesDir = path7.resolve(featuresDir);
6424
6740
  let features = [];
6425
6741
  let migrating = false;
6426
6742
  let currentEditingFeatureId = null;
6427
6743
  let lastWrittenContent = "";
6428
- const resolvedWebviewDir = webviewDir || path6.join(__dirname, "standalone-webview");
6429
- const workspaceRoot = path6.dirname(absoluteFeaturesDir);
6744
+ let currentBoardId;
6745
+ const resolvedWebviewDir = webviewDir || path7.join(__dirname, "standalone-webview");
6746
+ const workspaceRoot = path7.dirname(absoluteFeaturesDir);
6430
6747
  const sdk = new KanbanSDK(absoluteFeaturesDir);
6431
6748
  function sanitizeFeature(feature) {
6432
6749
  const { filePath: _, ...rest } = feature;
@@ -6492,17 +6809,20 @@ function startServer(featuresDir, port, webviewDir) {
6492
6809
  </body>
6493
6810
  </html>`;
6494
6811
  async function loadFeatures() {
6495
- features = await sdk.listCards(sdk.listColumns().map((c) => c.id));
6812
+ features = await sdk.listCards(sdk.listColumns(currentBoardId).map((c) => c.id), currentBoardId);
6496
6813
  }
6497
6814
  function buildInitMessage() {
6815
+ const config = readConfig(workspaceRoot);
6498
6816
  const settings = sdk.getSettings();
6499
6817
  settings.showBuildWithAI = false;
6500
6818
  settings.markdownEditorMode = false;
6501
6819
  return {
6502
6820
  type: "init",
6503
6821
  features,
6504
- columns: sdk.listColumns(),
6505
- settings
6822
+ columns: sdk.listColumns(currentBoardId),
6823
+ settings,
6824
+ boards: sdk.listBoards(),
6825
+ currentBoard: currentBoardId || config.defaultBoard
6506
6826
  };
6507
6827
  }
6508
6828
  function broadcast(message) {
@@ -6522,7 +6842,8 @@ function startServer(featuresDir, port, webviewDir) {
6522
6842
  priority: data.priority,
6523
6843
  assignee: data.assignee,
6524
6844
  dueDate: data.dueDate,
6525
- labels: data.labels
6845
+ labels: data.labels,
6846
+ boardId: currentBoardId
6526
6847
  });
6527
6848
  await loadFeatures();
6528
6849
  broadcast(buildInitMessage());
@@ -6539,7 +6860,7 @@ function startServer(featuresDir, port, webviewDir) {
6539
6860
  const oldStatus = feature.status;
6540
6861
  migrating = true;
6541
6862
  try {
6542
- const updated = await sdk.moveCard(featureId, newStatus, newOrder);
6863
+ const updated = await sdk.moveCard(featureId, newStatus, newOrder, currentBoardId);
6543
6864
  await loadFeatures();
6544
6865
  broadcast(buildInitMessage());
6545
6866
  fireWebhooks(workspaceRoot, "task.moved", {
@@ -6557,7 +6878,7 @@ function startServer(featuresDir, port, webviewDir) {
6557
6878
  return null;
6558
6879
  migrating = true;
6559
6880
  try {
6560
- const updated = await sdk.updateCard(featureId, updates);
6881
+ const updated = await sdk.updateCard(featureId, updates, currentBoardId);
6561
6882
  lastWrittenContent = serializeFeature(updated);
6562
6883
  await loadFeatures();
6563
6884
  broadcast(buildInitMessage());
@@ -6573,7 +6894,7 @@ function startServer(featuresDir, port, webviewDir) {
6573
6894
  return false;
6574
6895
  try {
6575
6896
  const deleted = sanitizeFeature(feature);
6576
- await sdk.deleteCard(featureId);
6897
+ await sdk.deleteCard(featureId, currentBoardId);
6577
6898
  await loadFeatures();
6578
6899
  broadcast(buildInitMessage());
6579
6900
  fireWebhooks(workspaceRoot, "task.deleted", deleted);
@@ -6584,7 +6905,7 @@ function startServer(featuresDir, port, webviewDir) {
6584
6905
  }
6585
6906
  }
6586
6907
  function doAddColumn(name, color) {
6587
- const existingColumns = sdk.listColumns();
6908
+ const existingColumns = sdk.listColumns(currentBoardId);
6588
6909
  const id = name.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-|-$/g, "");
6589
6910
  let uniqueId = id;
6590
6911
  let counter = 1;
@@ -6592,14 +6913,14 @@ function startServer(featuresDir, port, webviewDir) {
6592
6913
  uniqueId = `${id}-${counter++}`;
6593
6914
  }
6594
6915
  const column = { id: uniqueId, name, color };
6595
- sdk.addColumn(column);
6916
+ sdk.addColumn(column, currentBoardId);
6596
6917
  broadcast(buildInitMessage());
6597
6918
  fireWebhooks(workspaceRoot, "column.created", column);
6598
6919
  return column;
6599
6920
  }
6600
6921
  function doEditColumn(columnId, updates) {
6601
6922
  try {
6602
- const columns = sdk.updateColumn(columnId, { name: updates.name, color: updates.color });
6923
+ const columns = sdk.updateColumn(columnId, { name: updates.name, color: updates.color }, currentBoardId);
6603
6924
  const updated = columns.find((c) => c.id === columnId) ?? null;
6604
6925
  broadcast(buildInitMessage());
6605
6926
  if (updated)
@@ -6611,13 +6932,13 @@ function startServer(featuresDir, port, webviewDir) {
6611
6932
  }
6612
6933
  async function doRemoveColumn(columnId) {
6613
6934
  try {
6614
- const columns = sdk.listColumns();
6935
+ const columns = sdk.listColumns(currentBoardId);
6615
6936
  if (columns.length <= 1)
6616
6937
  return { removed: false, error: "Cannot remove last column" };
6617
6938
  const col = columns.find((c) => c.id === columnId);
6618
6939
  if (!col)
6619
6940
  return { removed: false, error: "Column not found" };
6620
- await sdk.removeColumn(columnId);
6941
+ await sdk.removeColumn(columnId, currentBoardId);
6621
6942
  broadcast(buildInitMessage());
6622
6943
  fireWebhooks(workspaceRoot, "column.deleted", col);
6623
6944
  return { removed: true };
@@ -6633,11 +6954,11 @@ function startServer(featuresDir, port, webviewDir) {
6633
6954
  const feature = features.find((f) => f.id === featureId);
6634
6955
  if (!feature)
6635
6956
  return false;
6636
- const featureDir = path6.dirname(feature.filePath);
6637
- fs5.writeFileSync(path6.join(featureDir, filename), fileData);
6957
+ const featureDir = path7.dirname(feature.filePath);
6958
+ fs6.writeFileSync(path7.join(featureDir, filename), fileData);
6638
6959
  migrating = true;
6639
6960
  try {
6640
- const updated = await sdk.addAttachment(featureId, path6.join(featureDir, filename));
6961
+ const updated = await sdk.addAttachment(featureId, path7.join(featureDir, filename), currentBoardId);
6641
6962
  lastWrittenContent = serializeFeature(updated);
6642
6963
  await loadFeatures();
6643
6964
  } finally {
@@ -6651,7 +6972,7 @@ function startServer(featuresDir, port, webviewDir) {
6651
6972
  return null;
6652
6973
  migrating = true;
6653
6974
  try {
6654
- const updated = await sdk.removeAttachment(featureId, attachment);
6975
+ const updated = await sdk.removeAttachment(featureId, attachment, currentBoardId);
6655
6976
  lastWrittenContent = serializeFeature(updated);
6656
6977
  await loadFeatures();
6657
6978
  broadcast(buildInitMessage());
@@ -6663,7 +6984,7 @@ function startServer(featuresDir, port, webviewDir) {
6663
6984
  async function doAddComment(featureId, author, content) {
6664
6985
  migrating = true;
6665
6986
  try {
6666
- const updated = await sdk.addComment(featureId, author, content);
6987
+ const updated = await sdk.addComment(featureId, author, content, currentBoardId);
6667
6988
  lastWrittenContent = serializeFeature(updated);
6668
6989
  const comment = updated.comments[updated.comments.length - 1];
6669
6990
  await loadFeatures();
@@ -6679,7 +7000,7 @@ function startServer(featuresDir, port, webviewDir) {
6679
7000
  async function doUpdateComment(featureId, commentId, content) {
6680
7001
  migrating = true;
6681
7002
  try {
6682
- const updated = await sdk.updateComment(featureId, commentId, content);
7003
+ const updated = await sdk.updateComment(featureId, commentId, content, currentBoardId);
6683
7004
  lastWrittenContent = serializeFeature(updated);
6684
7005
  const comment = (updated.comments || []).find((c) => c.id === commentId);
6685
7006
  await loadFeatures();
@@ -6702,7 +7023,7 @@ function startServer(featuresDir, port, webviewDir) {
6702
7023
  return false;
6703
7024
  migrating = true;
6704
7025
  try {
6705
- const updated = await sdk.deleteComment(featureId, commentId);
7026
+ const updated = await sdk.deleteComment(featureId, commentId, currentBoardId);
6706
7027
  lastWrittenContent = serializeFeature(updated);
6707
7028
  await loadFeatures();
6708
7029
  broadcast(buildInitMessage());
@@ -6887,6 +7208,34 @@ function startServer(featuresDir, port, webviewDir) {
6887
7208
  }
6888
7209
  break;
6889
7210
  }
7211
+ case "switchBoard":
7212
+ currentBoardId = msg.boardId;
7213
+ migrating = true;
7214
+ try {
7215
+ await loadFeatures();
7216
+ broadcast(buildInitMessage());
7217
+ } finally {
7218
+ migrating = false;
7219
+ }
7220
+ break;
7221
+ case "createBoard": {
7222
+ const boardName = msg.name;
7223
+ const boardId = generateSlug(boardName) || "board";
7224
+ try {
7225
+ sdk.createBoard(boardId, boardName);
7226
+ currentBoardId = boardId;
7227
+ migrating = true;
7228
+ try {
7229
+ await loadFeatures();
7230
+ broadcast(buildInitMessage());
7231
+ } finally {
7232
+ migrating = false;
7233
+ }
7234
+ } catch (err) {
7235
+ console.error("Failed to create board:", err);
7236
+ }
7237
+ break;
7238
+ }
6890
7239
  case "openFile":
6891
7240
  case "focusMenuBar":
6892
7241
  case "startWithAI":
@@ -6910,7 +7259,178 @@ function startServer(featuresDir, port, webviewDir) {
6910
7259
  return;
6911
7260
  }
6912
7261
  const route = (expectedMethod, pattern) => matchRoute(expectedMethod, method, pathname, pattern);
6913
- let params = route("GET", "/api/tasks");
7262
+ let params = route("GET", "/api/boards");
7263
+ if (params) {
7264
+ return jsonOk(res, sdk.listBoards());
7265
+ }
7266
+ params = route("POST", "/api/boards");
7267
+ if (params) {
7268
+ try {
7269
+ const body = await readBody(req);
7270
+ const id = body.id;
7271
+ const name = body.name;
7272
+ if (!id)
7273
+ return jsonError(res, 400, "id is required");
7274
+ if (!name)
7275
+ return jsonError(res, 400, "name is required");
7276
+ const board = sdk.createBoard(id, name, {
7277
+ description: body.description,
7278
+ columns: body.columns
7279
+ });
7280
+ return jsonOk(res, board, 201);
7281
+ } catch (err) {
7282
+ return jsonError(res, 400, String(err));
7283
+ }
7284
+ }
7285
+ params = route("GET", "/api/boards/:boardId");
7286
+ if (params) {
7287
+ try {
7288
+ const { boardId } = params;
7289
+ const board = sdk.getBoard(boardId);
7290
+ return jsonOk(res, board);
7291
+ } catch (err) {
7292
+ return jsonError(res, 404, String(err));
7293
+ }
7294
+ }
7295
+ params = route("PUT", "/api/boards/:boardId");
7296
+ if (params) {
7297
+ try {
7298
+ const { boardId } = params;
7299
+ const body = await readBody(req);
7300
+ const board = sdk.updateBoard(boardId, body);
7301
+ return jsonOk(res, board);
7302
+ } catch (err) {
7303
+ return jsonError(res, 400, String(err));
7304
+ }
7305
+ }
7306
+ params = route("DELETE", "/api/boards/:boardId");
7307
+ if (params) {
7308
+ try {
7309
+ const { boardId } = params;
7310
+ await sdk.deleteBoard(boardId);
7311
+ return jsonOk(res, { deleted: true });
7312
+ } catch (err) {
7313
+ return jsonError(res, 400, String(err));
7314
+ }
7315
+ }
7316
+ params = route("POST", "/api/boards/:boardId/tasks/:id/transfer");
7317
+ if (params) {
7318
+ try {
7319
+ const { boardId, id } = params;
7320
+ const body = await readBody(req);
7321
+ const config = readConfig(workspaceRoot);
7322
+ const fromBoard = currentBoardId || config.defaultBoard;
7323
+ const targetStatus = body.targetStatus;
7324
+ const card = await sdk.transferCard(id, fromBoard, boardId, targetStatus);
7325
+ return jsonOk(res, sanitizeFeature(card));
7326
+ } catch (err) {
7327
+ return jsonError(res, 400, String(err));
7328
+ }
7329
+ }
7330
+ params = route("GET", "/api/boards/:boardId/tasks");
7331
+ if (params) {
7332
+ try {
7333
+ const { boardId } = params;
7334
+ const boardColumns = sdk.listColumns(boardId);
7335
+ const boardTasks = await sdk.listCards(boardColumns.map((c) => c.id), boardId);
7336
+ let result = boardTasks.map(sanitizeFeature);
7337
+ const status = url.searchParams.get("status");
7338
+ if (status)
7339
+ result = result.filter((f) => f.status === status);
7340
+ const priority = url.searchParams.get("priority");
7341
+ if (priority)
7342
+ result = result.filter((f) => f.priority === priority);
7343
+ const assignee = url.searchParams.get("assignee");
7344
+ if (assignee)
7345
+ result = result.filter((f) => f.assignee === assignee);
7346
+ const label = url.searchParams.get("label");
7347
+ if (label)
7348
+ result = result.filter((f) => f.labels.includes(label));
7349
+ return jsonOk(res, result);
7350
+ } catch (err) {
7351
+ return jsonError(res, 400, String(err));
7352
+ }
7353
+ }
7354
+ params = route("POST", "/api/boards/:boardId/tasks");
7355
+ if (params) {
7356
+ try {
7357
+ const { boardId } = params;
7358
+ const body = await readBody(req);
7359
+ const content = body.content || "";
7360
+ if (!content)
7361
+ return jsonError(res, 400, "content is required");
7362
+ const feature = await sdk.createCard({
7363
+ content,
7364
+ status: body.status || "backlog",
7365
+ priority: body.priority || "medium",
7366
+ assignee: body.assignee || null,
7367
+ dueDate: body.dueDate || null,
7368
+ labels: body.labels || [],
7369
+ boardId
7370
+ });
7371
+ return jsonOk(res, sanitizeFeature(feature), 201);
7372
+ } catch (err) {
7373
+ return jsonError(res, 400, String(err));
7374
+ }
7375
+ }
7376
+ params = route("GET", "/api/boards/:boardId/tasks/:id");
7377
+ if (params) {
7378
+ try {
7379
+ const { boardId, id } = params;
7380
+ const card = await sdk.getCard(id, boardId);
7381
+ if (!card)
7382
+ return jsonError(res, 404, "Task not found");
7383
+ return jsonOk(res, sanitizeFeature(card));
7384
+ } catch (err) {
7385
+ return jsonError(res, 400, String(err));
7386
+ }
7387
+ }
7388
+ params = route("PUT", "/api/boards/:boardId/tasks/:id");
7389
+ if (params) {
7390
+ try {
7391
+ const { boardId, id } = params;
7392
+ const body = await readBody(req);
7393
+ const feature = await sdk.updateCard(id, body, boardId);
7394
+ return jsonOk(res, sanitizeFeature(feature));
7395
+ } catch (err) {
7396
+ return jsonError(res, 400, String(err));
7397
+ }
7398
+ }
7399
+ params = route("PATCH", "/api/boards/:boardId/tasks/:id/move");
7400
+ if (params) {
7401
+ try {
7402
+ const { boardId, id } = params;
7403
+ const body = await readBody(req);
7404
+ const newStatus = body.status;
7405
+ const position = body.position ?? 0;
7406
+ if (!newStatus)
7407
+ return jsonError(res, 400, "status is required");
7408
+ const feature = await sdk.moveCard(id, newStatus, position, boardId);
7409
+ return jsonOk(res, sanitizeFeature(feature));
7410
+ } catch (err) {
7411
+ return jsonError(res, 400, String(err));
7412
+ }
7413
+ }
7414
+ params = route("DELETE", "/api/boards/:boardId/tasks/:id");
7415
+ if (params) {
7416
+ try {
7417
+ const { boardId, id } = params;
7418
+ await sdk.deleteCard(id, boardId);
7419
+ return jsonOk(res, { deleted: true });
7420
+ } catch (err) {
7421
+ return jsonError(res, 400, String(err));
7422
+ }
7423
+ }
7424
+ params = route("GET", "/api/boards/:boardId/columns");
7425
+ if (params) {
7426
+ try {
7427
+ const { boardId } = params;
7428
+ return jsonOk(res, sdk.listColumns(boardId));
7429
+ } catch (err) {
7430
+ return jsonError(res, 400, String(err));
7431
+ }
7432
+ }
7433
+ params = route("GET", "/api/tasks");
6914
7434
  if (params) {
6915
7435
  await loadFeatures();
6916
7436
  let result = features.map(sanitizeFeature);
@@ -7021,16 +7541,16 @@ function startServer(featuresDir, port, webviewDir) {
7021
7541
  const feature = features.find((f) => f.id === id);
7022
7542
  if (!feature)
7023
7543
  return jsonError(res, 404, "Task not found");
7024
- const featureDir = path6.dirname(feature.filePath);
7025
- const attachmentPath = path6.resolve(featureDir, attachName);
7544
+ const featureDir = path7.dirname(feature.filePath);
7545
+ const attachmentPath = path7.resolve(featureDir, attachName);
7026
7546
  if (!attachmentPath.startsWith(absoluteFeaturesDir)) {
7027
7547
  res.writeHead(403, { "Content-Type": "text/plain" });
7028
7548
  res.end("Forbidden");
7029
7549
  return;
7030
7550
  }
7031
- const ext2 = path6.extname(attachName);
7551
+ const ext2 = path7.extname(attachName);
7032
7552
  const contentType2 = MIME_TYPES[ext2] || "application/octet-stream";
7033
- fs5.readFile(attachmentPath, (err, data) => {
7553
+ fs6.readFile(attachmentPath, (err, data) => {
7034
7554
  if (err) {
7035
7555
  res.writeHead(404);
7036
7556
  res.end("File not found");
@@ -7106,7 +7626,7 @@ function startServer(featuresDir, port, webviewDir) {
7106
7626
  }
7107
7627
  params = route("GET", "/api/columns");
7108
7628
  if (params) {
7109
- return jsonOk(res, sdk.listColumns());
7629
+ return jsonOk(res, sdk.listColumns(currentBoardId));
7110
7630
  }
7111
7631
  params = route("POST", "/api/columns");
7112
7632
  if (params) {
@@ -7245,16 +7765,16 @@ function startServer(featuresDir, port, webviewDir) {
7245
7765
  res.end("Feature not found");
7246
7766
  return;
7247
7767
  }
7248
- const featureDir = path6.dirname(feature.filePath);
7249
- const attachmentPath = path6.resolve(featureDir, filename);
7768
+ const featureDir = path7.dirname(feature.filePath);
7769
+ const attachmentPath = path7.resolve(featureDir, filename);
7250
7770
  if (!attachmentPath.startsWith(absoluteFeaturesDir)) {
7251
7771
  res.writeHead(403, { "Content-Type": "text/plain" });
7252
7772
  res.end("Forbidden");
7253
7773
  return;
7254
7774
  }
7255
- const ext2 = path6.extname(filename);
7775
+ const ext2 = path7.extname(filename);
7256
7776
  const contentType2 = MIME_TYPES[ext2] || "application/octet-stream";
7257
- fs5.readFile(attachmentPath, (err, data) => {
7777
+ fs6.readFile(attachmentPath, (err, data) => {
7258
7778
  if (err) {
7259
7779
  res.writeHead(404, { "Content-Type": "text/plain" });
7260
7780
  res.end("File not found");
@@ -7268,15 +7788,15 @@ function startServer(featuresDir, port, webviewDir) {
7268
7788
  if (pathname.startsWith("/api/")) {
7269
7789
  return jsonError(res, 404, "Not found");
7270
7790
  }
7271
- const filePath = path6.join(resolvedWebviewDir, pathname === "/" ? "index.html" : pathname);
7272
- if (!path6.extname(filePath)) {
7791
+ const filePath = path7.join(resolvedWebviewDir, pathname === "/" ? "index.html" : pathname);
7792
+ if (!path7.extname(filePath)) {
7273
7793
  res.writeHead(200, { "Content-Type": "text/html" });
7274
7794
  res.end(indexHtml);
7275
7795
  return;
7276
7796
  }
7277
- const ext = path6.extname(filePath);
7797
+ const ext = path7.extname(filePath);
7278
7798
  const contentType = MIME_TYPES[ext] || "application/octet-stream";
7279
- fs5.readFile(filePath, (err, data) => {
7799
+ fs6.readFile(filePath, (err, data) => {
7280
7800
  if (err) {
7281
7801
  res.writeHead(200, { "Content-Type": "text/html" });
7282
7802
  res.end(indexHtml);
@@ -7298,7 +7818,7 @@ function startServer(featuresDir, port, webviewDir) {
7298
7818
  });
7299
7819
  });
7300
7820
  let debounceTimer;
7301
- fs5.mkdirSync(absoluteFeaturesDir, { recursive: true });
7821
+ fs6.mkdirSync(absoluteFeaturesDir, { recursive: true });
7302
7822
  const watcher = esm_default.watch(absoluteFeaturesDir, {
7303
7823
  ignoreInitial: true,
7304
7824
  awaitWriteFinish: { stabilityThreshold: 100 }
@@ -7361,12 +7881,14 @@ function startServer(featuresDir, port, webviewDir) {
7361
7881
 
7362
7882
  // src/extension/KanbanPanel.ts
7363
7883
  var vscode = __toESM(require("vscode"));
7364
- var path7 = __toESM(require("path"));
7884
+ var path8 = __toESM(require("path"));
7885
+ init_types();
7365
7886
  var KanbanPanel = class _KanbanPanel {
7366
7887
  constructor(panel, extensionUri, context) {
7367
7888
  this._features = [];
7368
7889
  this._disposables = [];
7369
7890
  this._currentEditingFeatureId = null;
7891
+ this._currentBoardId = void 0;
7370
7892
  this._lastWrittenContent = "";
7371
7893
  this._migrating = false;
7372
7894
  this._onDisposeCallbacks = [];
@@ -7479,6 +8001,26 @@ var KanbanPanel = class _KanbanPanel {
7479
8001
  case "removeColumn":
7480
8002
  await this._removeColumn(message.columnId);
7481
8003
  break;
8004
+ case "switchBoard":
8005
+ this._currentBoardId = message.boardId;
8006
+ await this._loadFeatures();
8007
+ this._sendFeaturesToWebview();
8008
+ break;
8009
+ case "createBoard": {
8010
+ if (!this._sdk)
8011
+ break;
8012
+ const { generateSlug: generateSlug2 } = await Promise.resolve().then(() => (init_types(), types_exports));
8013
+ const boardId = generateSlug2(message.name) || "board";
8014
+ try {
8015
+ this._sdk.createBoard(boardId, message.name);
8016
+ this._currentBoardId = boardId;
8017
+ await this._loadFeatures();
8018
+ this._sendFeaturesToWebview();
8019
+ } catch (err) {
8020
+ vscode.window.showErrorMessage(`Failed to create board: ${err}`);
8021
+ }
8022
+ break;
8023
+ }
7482
8024
  case "toggleTheme":
7483
8025
  await vscode.commands.executeCommand("workbench.action.toggleLightDarkThemes");
7484
8026
  break;
@@ -7528,7 +8070,7 @@ var KanbanPanel = class _KanbanPanel {
7528
8070
  const featuresDir = this._getWorkspaceFeaturesDir();
7529
8071
  if (!featuresDir)
7530
8072
  return;
7531
- const pattern = new vscode.RelativePattern(featuresDir, "**/*.md");
8073
+ const pattern = new vscode.RelativePattern(featuresDir, "boards/**/*.md");
7532
8074
  this._fileWatcher = vscode.workspace.createFileSystemWatcher(pattern);
7533
8075
  let debounceTimer;
7534
8076
  const handleFileChange = (uri) => {
@@ -7642,7 +8184,7 @@ var KanbanPanel = class _KanbanPanel {
7642
8184
  if (!root)
7643
8185
  return null;
7644
8186
  const config = readConfig(root);
7645
- return path7.join(root, config.featuresDirectory);
8187
+ return path8.join(root, config.featuresDirectory);
7646
8188
  }
7647
8189
  _getSDK() {
7648
8190
  const featuresDir = this._getWorkspaceFeaturesDir();
@@ -7662,7 +8204,7 @@ var KanbanPanel = class _KanbanPanel {
7662
8204
  try {
7663
8205
  this._migrating = true;
7664
8206
  const columns = this._getColumns().map((c) => c.id);
7665
- this._features = await sdk.listCards(columns);
8207
+ this._features = await sdk.listCards(columns, this._currentBoardId);
7666
8208
  } catch {
7667
8209
  this._features = [];
7668
8210
  } finally {
@@ -7695,7 +8237,8 @@ var KanbanPanel = class _KanbanPanel {
7695
8237
  priority: data.priority,
7696
8238
  assignee: data.assignee ?? void 0,
7697
8239
  dueDate: data.dueDate ?? void 0,
7698
- labels: data.labels
8240
+ labels: data.labels,
8241
+ boardId: this._currentBoardId
7699
8242
  });
7700
8243
  this._features.push(feature);
7701
8244
  this._sendFeaturesToWebview();
@@ -7709,7 +8252,7 @@ var KanbanPanel = class _KanbanPanel {
7709
8252
  return;
7710
8253
  this._migrating = true;
7711
8254
  try {
7712
- const updated = await sdk.moveCard(featureId, newStatus, newOrder);
8255
+ const updated = await sdk.moveCard(featureId, newStatus, newOrder, this._currentBoardId);
7713
8256
  const idx = this._features.findIndex((f) => f.id === featureId);
7714
8257
  if (idx !== -1)
7715
8258
  this._features[idx] = updated;
@@ -7723,7 +8266,7 @@ var KanbanPanel = class _KanbanPanel {
7723
8266
  if (!sdk)
7724
8267
  return;
7725
8268
  try {
7726
- await sdk.deleteCard(featureId);
8269
+ await sdk.deleteCard(featureId, this._currentBoardId);
7727
8270
  this._features = this._features.filter((f) => f.id !== featureId);
7728
8271
  this._sendFeaturesToWebview();
7729
8272
  } catch (err) {
@@ -7736,7 +8279,7 @@ var KanbanPanel = class _KanbanPanel {
7736
8279
  return;
7737
8280
  this._migrating = true;
7738
8281
  try {
7739
- const updated = await sdk.updateCard(featureId, updates);
8282
+ const updated = await sdk.updateCard(featureId, updates, this._currentBoardId);
7740
8283
  const idx = this._features.findIndex((f) => f.id === featureId);
7741
8284
  if (idx !== -1)
7742
8285
  this._features[idx] = updated;
@@ -7794,7 +8337,7 @@ var KanbanPanel = class _KanbanPanel {
7794
8337
  dueDate: frontmatter.dueDate,
7795
8338
  labels: frontmatter.labels,
7796
8339
  attachments: frontmatter.attachments
7797
- });
8340
+ }, this._currentBoardId);
7798
8341
  this._lastWrittenContent = serializeFeature(updated);
7799
8342
  const idx = this._features.findIndex((f) => f.id === featureId);
7800
8343
  if (idx !== -1)
@@ -7820,7 +8363,7 @@ var KanbanPanel = class _KanbanPanel {
7820
8363
  try {
7821
8364
  let updated = feature;
7822
8365
  for (const uri of uris) {
7823
- updated = await sdk.addAttachment(featureId, uri.fsPath);
8366
+ updated = await sdk.addAttachment(featureId, uri.fsPath, this._currentBoardId);
7824
8367
  }
7825
8368
  const idx = this._features.findIndex((f) => f.id === featureId);
7826
8369
  if (idx !== -1)
@@ -7837,8 +8380,8 @@ var KanbanPanel = class _KanbanPanel {
7837
8380
  const feature = this._features.find((f) => f.id === featureId);
7838
8381
  if (!feature)
7839
8382
  return;
7840
- const featureDir = path7.dirname(feature.filePath);
7841
- const attachmentPath = path7.resolve(featureDir, attachment);
8383
+ const featureDir = path8.dirname(feature.filePath);
8384
+ const attachmentPath = path8.resolve(featureDir, attachment);
7842
8385
  try {
7843
8386
  await vscode.workspace.fs.stat(vscode.Uri.file(attachmentPath));
7844
8387
  const doc = await vscode.workspace.openTextDocument(vscode.Uri.file(attachmentPath));
@@ -7853,7 +8396,7 @@ var KanbanPanel = class _KanbanPanel {
7853
8396
  return;
7854
8397
  this._migrating = true;
7855
8398
  try {
7856
- const updated = await sdk.removeAttachment(featureId, attachment);
8399
+ const updated = await sdk.removeAttachment(featureId, attachment, this._currentBoardId);
7857
8400
  const idx = this._features.findIndex((f) => f.id === featureId);
7858
8401
  if (idx !== -1)
7859
8402
  this._features[idx] = updated;
@@ -7871,7 +8414,7 @@ var KanbanPanel = class _KanbanPanel {
7871
8414
  return;
7872
8415
  this._migrating = true;
7873
8416
  try {
7874
- const updated = await sdk.addComment(featureId, author, content);
8417
+ const updated = await sdk.addComment(featureId, author, content, this._currentBoardId);
7875
8418
  const idx = this._features.findIndex((f) => f.id === featureId);
7876
8419
  if (idx !== -1)
7877
8420
  this._features[idx] = updated;
@@ -7889,7 +8432,7 @@ var KanbanPanel = class _KanbanPanel {
7889
8432
  return;
7890
8433
  this._migrating = true;
7891
8434
  try {
7892
- const updated = await sdk.updateComment(featureId, commentId, content);
8435
+ const updated = await sdk.updateComment(featureId, commentId, content, this._currentBoardId);
7893
8436
  const idx = this._features.findIndex((f) => f.id === featureId);
7894
8437
  if (idx !== -1)
7895
8438
  this._features[idx] = updated;
@@ -7907,7 +8450,7 @@ var KanbanPanel = class _KanbanPanel {
7907
8450
  return;
7908
8451
  this._migrating = true;
7909
8452
  try {
7910
- const updated = await sdk.deleteComment(featureId, commentId);
8453
+ const updated = await sdk.deleteComment(featureId, commentId, this._currentBoardId);
7911
8454
  const idx = this._features.findIndex((f) => f.id === featureId);
7912
8455
  if (idx !== -1)
7913
8456
  this._features[idx] = updated;
@@ -7983,13 +8526,17 @@ var KanbanPanel = class _KanbanPanel {
7983
8526
  _getColumns() {
7984
8527
  const sdk = this._getSDK();
7985
8528
  if (!sdk)
7986
- return [...DEFAULT_CONFIG.columns];
7987
- return sdk.listColumns();
8529
+ return [...DEFAULT_CONFIG.boards.default.columns];
8530
+ return sdk.listColumns(this._currentBoardId);
7988
8531
  }
7989
8532
  _sendFeaturesToWebview() {
7990
8533
  const sdk = this._getSDK();
7991
- const columns = sdk ? sdk.listColumns() : [...DEFAULT_CONFIG.columns];
8534
+ const columns = sdk ? sdk.listColumns(this._currentBoardId) : [...DEFAULT_CONFIG.boards.default.columns];
7992
8535
  const settings = sdk ? sdk.getSettings() : configToSettings(DEFAULT_CONFIG);
8536
+ const boards = sdk ? sdk.listBoards() : [];
8537
+ const root = this._getWorkspaceRoot();
8538
+ const config = root ? readConfig(root) : DEFAULT_CONFIG;
8539
+ const currentBoard = this._currentBoardId || config.defaultBoard;
7993
8540
  const aiDisabled = vscode.workspace.getConfiguration("chat").get("disableAIFeatures", false);
7994
8541
  if (aiDisabled) {
7995
8542
  settings.showBuildWithAI = false;
@@ -7998,7 +8545,9 @@ var KanbanPanel = class _KanbanPanel {
7998
8545
  type: "init",
7999
8546
  features: this._features,
8000
8547
  columns,
8001
- settings
8548
+ settings,
8549
+ boards,
8550
+ currentBoard
8002
8551
  });
8003
8552
  }
8004
8553
  _addColumn(column) {
@@ -8012,14 +8561,14 @@ var KanbanPanel = class _KanbanPanel {
8012
8561
  while (existing.some((c) => c.id === uniqueId)) {
8013
8562
  uniqueId = `${id}-${counter++}`;
8014
8563
  }
8015
- sdk.addColumn({ id: uniqueId, name: column.name, color: column.color });
8564
+ sdk.addColumn({ id: uniqueId, name: column.name, color: column.color }, this._currentBoardId);
8016
8565
  this._sendFeaturesToWebview();
8017
8566
  }
8018
8567
  _editColumn(columnId, updates) {
8019
8568
  const sdk = this._getSDK();
8020
8569
  if (!sdk)
8021
8570
  return;
8022
- sdk.updateColumn(columnId, updates);
8571
+ sdk.updateColumn(columnId, updates, this._currentBoardId);
8023
8572
  this._sendFeaturesToWebview();
8024
8573
  }
8025
8574
  _removeColumn(columnId) {
@@ -8036,14 +8585,15 @@ var KanbanPanel = class _KanbanPanel {
8036
8585
  vscode.window.showWarningMessage("Cannot remove the last list.");
8037
8586
  return;
8038
8587
  }
8039
- sdk.removeColumn(columnId);
8588
+ sdk.removeColumn(columnId, this._currentBoardId);
8040
8589
  this._sendFeaturesToWebview();
8041
8590
  }
8042
8591
  };
8043
8592
 
8044
8593
  // src/extension/SidebarViewProvider.ts
8045
8594
  var vscode2 = __toESM(require("vscode"));
8046
- var path8 = __toESM(require("path"));
8595
+ var path9 = __toESM(require("path"));
8596
+ init_types();
8047
8597
  var SidebarViewProvider = class {
8048
8598
  constructor(_extensionUri, _context) {
8049
8599
  this._extensionUri = _extensionUri;
@@ -8161,7 +8711,7 @@ var SidebarViewProvider = class {
8161
8711
  return null;
8162
8712
  const root = workspaceFolders[0].uri.fsPath;
8163
8713
  const config = readConfig(root);
8164
- return path8.join(root, config.featuresDirectory);
8714
+ return path9.join(root, config.featuresDirectory);
8165
8715
  }
8166
8716
  _getColumns() {
8167
8717
  const featuresDir = this._getFeaturesDir();
@@ -8518,7 +9068,7 @@ async function createFeatureFromPrompts() {
8518
9068
  });
8519
9069
  const root = workspaceFolders[0].uri.fsPath;
8520
9070
  const kanbanConfig = readConfig(root);
8521
- const featuresDir = path9.join(root, kanbanConfig.featuresDirectory);
9071
+ const featuresDir = path10.join(root, kanbanConfig.featuresDirectory);
8522
9072
  const sdk = new KanbanSDK(featuresDir);
8523
9073
  const content = `# ${title}${description ? "\n\n" + description : ""}`;
8524
9074
  const feature = await sdk.createCard({ content, status, priority });
@@ -8554,8 +9104,8 @@ function activate(context) {
8554
9104
  if (workspaceFolders) {
8555
9105
  const root = workspaceFolders[0].uri.fsPath;
8556
9106
  const kanbanConfig = readConfig(root);
8557
- const featuresDir = path9.join(root, kanbanConfig.featuresDirectory);
8558
- const webviewDir = path9.join(context.extensionPath, "dist", "standalone-webview");
9107
+ const featuresDir = path10.join(root, kanbanConfig.featuresDirectory);
9108
+ const webviewDir = path10.join(context.extensionPath, "dist", "standalone-webview");
8559
9109
  findFreePort(3464).then((port) => {
8560
9110
  standaloneServer = startServer(featuresDir, port, webviewDir);
8561
9111
  standaloneServer.on("error", () => {