kanban-lite 1.2.2 → 1.2.4

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 (39) hide show
  1. package/dist/cli.js +257 -90
  2. package/dist/extension.js +245 -78
  3. package/dist/mcp-server.js +117 -33
  4. package/dist/sdk/index.cjs +117 -32
  5. package/dist/sdk/index.mjs +117 -32
  6. package/dist/sdk/sdk/KanbanSDK.d.ts +27 -10
  7. package/dist/sdk/sdk/modules/cards.d.ts +11 -2
  8. package/dist/sdk/sdk/plugins/index.d.ts +7 -0
  9. package/dist/sdk/sdk/types.d.ts +12 -27
  10. package/dist/sdk/shared/config.d.ts +17 -1
  11. package/dist/standalone-webview/index.js +38 -38
  12. package/dist/standalone-webview/index.js.map +1 -1
  13. package/dist/standalone.js +307 -125
  14. package/package.json +1 -1
  15. package/src/cli/index.test.ts +157 -0
  16. package/src/cli/index.ts +1 -1
  17. package/src/mcp-server/index.test.ts +76 -0
  18. package/src/mcp-server/index.ts +1 -1
  19. package/src/sdk/KanbanSDK.d.ts +26 -10
  20. package/src/sdk/KanbanSDK.ts +37 -11
  21. package/src/sdk/__tests__/KanbanSDK.test.ts +79 -24
  22. package/src/sdk/integrationCatalog.ts +1 -0
  23. package/src/sdk/modules/cards.ts +13 -24
  24. package/src/sdk/plugins/index.d.ts +7 -0
  25. package/src/sdk/plugins/index.ts +17 -2
  26. package/src/sdk/types.d.ts +10 -26
  27. package/src/sdk/types.ts +11 -24
  28. package/src/sdk/webhooks.ts +19 -2
  29. package/src/shared/config.ts +130 -2
  30. package/src/standalone/__tests__/server.integration.test.ts +81 -2
  31. package/src/standalone/internal/runtime.ts +11 -6
  32. package/src/standalone/internal/websocket.ts +13 -3
  33. package/src/standalone/server.ts +67 -9
  34. package/src/standalone/watcherSetup.ts +9 -0
  35. package/src/webview/standalone-shim.ts +2 -1
  36. package/tmp/screenshots-workspace/.kanban/.active-card.json +5 -0
  37. package/tmp/screenshots-workspace/.kanban/boards/default/deleted/1-dddd.md +17 -0
  38. package/tmp/screenshots-workspace/.kanban/boards/default/deleted/attachments/1.log +1 -0
  39. package/tmp/screenshots-workspace/.kanban.json +59 -0
@@ -1,6 +1,6 @@
1
1
  import type { Comment, Card, KanbanColumn, BoardInfo, LabelDefinition, CardSortOption, LogEntry } from '../shared/types';
2
2
  import type { CardDisplaySettings, Priority } from '../shared/types';
3
- import type { BoardConfig, ResolvedCapabilities, Webhook } from '../shared/config';
3
+ import type { BoardConfig, KanbanConfig, ResolvedCapabilities, Webhook } from '../shared/config';
4
4
  import type { CreateCardInput, SDKEvent, SDKEventType, SDKOptions, SubmitFormInput, SubmitFormResult, AuthContext, AuthDecision, SDKBeforeEventType, SDKAfterEventType, CardStateStatus, CardUnreadSummary } from './types';
5
5
  import type { EventBusAnyListener, EventBusWaitOptions } from './eventBus';
6
6
  import { EventBus } from './eventBus';
@@ -46,6 +46,9 @@ export interface AuthStatus {
46
46
  */
47
47
  policyEnabled: boolean;
48
48
  }
49
+ type ReadonlySnapshot<T> = T extends (...args: never[]) => unknown ? T : T extends readonly (infer U)[] ? readonly ReadonlySnapshot<U>[] : T extends object ? {
50
+ readonly [K in keyof T]: ReadonlySnapshot<T[K]>;
51
+ } : T;
49
52
  /**
50
53
  * Active webhook provider metadata for diagnostics and host surfaces.
51
54
  *
@@ -535,6 +538,23 @@ export declare class KanbanSDK {
535
538
  * ```
536
539
  */
537
540
  get workspaceRoot(): string;
541
+ /**
542
+ * Returns a cloned read-only snapshot of the current workspace config.
543
+ *
544
+ * The returned snapshot is created from a fresh config read and deep-cloned
545
+ * before being returned, so callers receive an isolated view of the current
546
+ * `.kanban.json` state rather than a live mutable runtime object. Mutating the
547
+ * returned snapshot does not update persisted config or affect this SDK instance.
548
+ *
549
+ * @returns A cloned read-only snapshot of the current {@link KanbanConfig}.
550
+ *
551
+ * @example
552
+ * ```ts
553
+ * const config = sdk.getConfigSnapshot()
554
+ * console.log(config.defaultBoard)
555
+ * ```
556
+ */
557
+ getConfigSnapshot(): ReadonlySnapshot<KanbanConfig>;
538
558
  /** @internal */
539
559
  _resolveBoardId(boardId?: string): string;
540
560
  /** @internal */
@@ -969,21 +989,17 @@ export declare class KanbanSDK {
969
989
  */
970
990
  submitForm(input: SubmitFormInput): Promise<SubmitFormResult>;
971
991
  /**
972
- * Triggers a named action for a card by POSTing to the global `actionWebhookUrl`
973
- * configured in `.kanban.json`.
992
+ * Triggers a named action for a card.
974
993
  *
975
- * The payload sent to the webhook is:
976
- * ```json
977
- * { "action": "retry", "board": "default", "list": "in-progress", "card": { ...sanitizedCard } }
978
- * ```
994
+ * Validates the card, appends an activity log entry, and emits the
995
+ * `card.action.triggered` after-event so registered webhooks receive
996
+ * the action payload automatically.
979
997
  *
980
998
  * @param cardId - The ID of the card to trigger the action for.
981
999
  * @param action - The action name string (e.g. `'retry'`, `'sendEmail'`).
982
1000
  * @param boardId - Optional board ID. Defaults to the workspace's default board.
983
- * @returns A promise resolving when the webhook responds with 2xx.
984
- * @throws {Error} If no `actionWebhookUrl` is configured in `.kanban.json`.
1001
+ * @returns A promise that resolves when the action has been processed.
985
1002
  * @throws {Error} If the card is not found.
986
- * @throws {Error} If the webhook responds with a non-2xx status.
987
1003
  *
988
1004
  * @example
989
1005
  * ```ts
@@ -1775,3 +1791,4 @@ export declare class KanbanSDK {
1775
1791
  */
1776
1792
  updateWebhook(id: string, updates: Partial<Pick<Webhook, 'url' | 'events' | 'secret' | 'active'>>): Promise<Webhook | null>;
1777
1793
  }
1794
+ export {};
@@ -52,13 +52,22 @@ export declare function updateCard(ctx: SDKContext, { cardId, updates, boardId }
52
52
  boardId?: string;
53
53
  }): Promise<Card>;
54
54
  /**
55
- * Triggers a named action for a card by POSTing to the global `actionWebhookUrl`.
55
+ * Triggers a named action for a card.
56
+ *
57
+ * Validates the card exists, appends an activity log entry, and returns the
58
+ * action payload. Webhook delivery is handled by the webhook plugin via the
59
+ * `card.action.triggered` after-event emitted by {@link KanbanSDK.triggerAction}.
56
60
  */
57
61
  export declare function triggerAction(ctx: SDKContext, { cardId, action, boardId }: {
58
62
  cardId: string;
59
63
  action: string;
60
64
  boardId?: string;
61
- }): Promise<void>;
65
+ }): Promise<{
66
+ action: string;
67
+ board: string;
68
+ list: string;
69
+ card: Omit<Card, 'filePath'>;
70
+ }>;
62
71
  /**
63
72
  * Validates and persists a card form submission, then emits `form.submit`.
64
73
  */
@@ -337,6 +337,13 @@ export type StandaloneHttpHandler = (request: StandaloneHttpRequestContext) => P
337
337
  * resolved the active workspace capability selections.
338
338
  */
339
339
  export interface StandaloneHttpPluginRegistrationOptions {
340
+ /**
341
+ * Active SDK instance backing the standalone runtime, when provided by the host.
342
+ *
343
+ * Plugin registration code may use the full public {@link KanbanSDK} surface,
344
+ * including `getConfigSnapshot()`, when this seam is available.
345
+ */
346
+ readonly sdk?: KanbanSDK;
340
347
  /** Absolute workspace root containing `.kanban.json`. */
341
348
  readonly workspaceRoot: string;
342
349
  /** Absolute workspace `.kanban` directory. */
@@ -1,5 +1,6 @@
1
1
  import type { Card, CardFormAttachment, CardFormDataMap, Priority, ResolvedFormDescriptor } from '../shared/types';
2
- import type { CapabilitySelections, Webhook } from '../shared/config';
2
+ import type { CapabilitySelections } from '../shared/config';
3
+ import type { KanbanSDK } from './KanbanSDK';
3
4
  import type { StorageEngine, StorageEngineType } from './plugins/types';
4
5
  import type { CardStateCursor } from './plugins';
5
6
  export type { StorageEngine, StorageEngineType } from './plugins/types';
@@ -58,7 +59,7 @@ export type SDKBeforeEventType = 'card.create' | 'card.update' | 'card.move' | '
58
59
  *
59
60
  * @see AfterEventPayload for the payload envelope passed to after-event listeners.
60
61
  */
61
- export type SDKAfterEventType = 'task.created' | 'task.updated' | 'task.moved' | 'task.deleted' | 'comment.created' | 'comment.updated' | 'comment.deleted' | 'column.created' | 'column.updated' | 'column.deleted' | 'attachment.added' | 'attachment.removed' | 'settings.updated' | 'board.created' | 'board.updated' | 'board.deleted' | 'board.action' | 'board.log.added' | 'board.log.cleared' | 'log.added' | 'log.cleared' | 'storage.migrated' | 'form.submitted' | 'auth.allowed' | 'auth.denied';
62
+ export type SDKAfterEventType = 'task.created' | 'task.updated' | 'task.moved' | 'task.deleted' | 'comment.created' | 'comment.updated' | 'comment.deleted' | 'column.created' | 'column.updated' | 'column.deleted' | 'attachment.added' | 'attachment.removed' | 'settings.updated' | 'board.created' | 'board.updated' | 'board.deleted' | 'board.action' | 'card.action.triggered' | 'board.log.added' | 'board.log.cleared' | 'log.added' | 'log.cleared' | 'storage.migrated' | 'form.submitted' | 'auth.allowed' | 'auth.denied';
62
63
  /**
63
64
  * Union of all SDK event types (before-events and after-events).
64
65
  *
@@ -489,29 +490,11 @@ export declare class CardStateError extends Error {
489
490
  constructor(code: CardStateErrorCode, message: string);
490
491
  }
491
492
  /**
492
- * Minimal SDK webhook facade supplied to CLI plugins via {@link CliPluginContext}.
493
- *
494
- * Structural subset of `KanbanSDK`; plugins should use this surface instead of
495
- * importing `KanbanSDK` directly so they remain decoupled from core internals.
493
+ * @deprecated Use {@link KanbanSDK}. CLI plugin hosts now advertise the full
494
+ * public SDK surface, including `getConfigSnapshot()`, instead of a narrowed
495
+ * webhook-only facade.
496
496
  */
497
- export interface CliPluginSdk {
498
- /**
499
- * Returns the SDK extension bag contributed by the plugin with the given id,
500
- * when the host is backed by a full `KanbanSDK` instance.
501
- *
502
- * CLI plugins should prefer this extension path when available and fall back
503
- * to compatibility methods only when running against older or mocked SDK facades.
504
- */
505
- getExtension?<T extends Record<string, unknown> = Record<string, unknown>>(id: string): T | undefined;
506
- listWebhooks(): Webhook[];
507
- createWebhook(input: {
508
- url: string;
509
- events: string[];
510
- secret?: string;
511
- }): Promise<Webhook>;
512
- updateWebhook(id: string, updates: Partial<Pick<Webhook, 'url' | 'events' | 'secret' | 'active'>>): Promise<Webhook | null>;
513
- deleteWebhook(id: string): Promise<boolean>;
514
- }
497
+ export type CliPluginSdk = KanbanSDK;
515
498
  /**
516
499
  * Runtime context supplied to a {@link KanbanCliPlugin} when it is invoked by
517
500
  * the `kl` CLI.
@@ -524,10 +507,12 @@ export interface CliPluginContext {
524
507
  *
525
508
  * Present when the plugin is invoked through the core `kl` CLI.
526
509
  * Absent in isolated unit tests or standalone invocations.
527
- * Plugins should prefer this over constructing their own SDK so that
528
- * SDK-level auth policy is honoured.
510
+ * Plugins may use the full public {@link KanbanSDK} contract here, including
511
+ * extension lookup and `getConfigSnapshot()`, instead of relying on older
512
+ * helper-only SDK facades. Plugins should prefer this over constructing their
513
+ * own SDK so that SDK-level auth policy is honoured.
529
514
  */
530
- sdk?: CliPluginSdk;
515
+ sdk?: KanbanSDK;
531
516
  /**
532
517
  * Core-owned CLI auth helper.
533
518
  *
@@ -171,7 +171,10 @@ export interface KanbanConfig {
171
171
  webhooks?: Webhook[];
172
172
  /** Label definitions keyed by label name, with color and optional group. */
173
173
  labels?: Record<string, LabelDefinition>;
174
- /** Optional URL to POST to when a card action is triggered. */
174
+ /**
175
+ * @deprecated Removed in favour of the webhook plugin. Register a webhook
176
+ * for the `card.action.triggered` event instead.
177
+ */
175
178
  actionWebhookUrl?: string;
176
179
  /**
177
180
  * Global auto-increment card ID counter shared across all boards.
@@ -255,6 +258,13 @@ export interface KanbanConfig {
255
258
  customHeadHtml?: string;
256
259
  /** Path to an HTML file (relative to workspace root) whose content is injected into the standalone board's `<head>` element. Takes precedence over `customHeadHtml`. */
257
260
  customHeadHtmlFile?: string;
261
+ /**
262
+ * Optional URL base path prefix for subfolder reverse-proxy deployments
263
+ * (e.g. `'/kanban'`). Must start with `/` and have no trailing slash.
264
+ * When set, all asset URLs, the WebSocket endpoint, and API routes are
265
+ * served under this prefix. Only applies to the standalone server.
266
+ */
267
+ basePath?: string;
258
268
  }
259
269
  /**
260
270
  * Default configuration used when no `.kanban.json` file exists or when
@@ -282,6 +292,12 @@ export declare function configPath(workspaceRoot: string): string;
282
292
  * returns the default config. If the file contains a v1 config, it is
283
293
  * automatically migrated to v2 format and persisted back to disk.
284
294
  *
295
+ * Any `${VAR_NAME}` placeholders found in string values are resolved against
296
+ * `process.env` before the config is returned. If a referenced environment
297
+ * variable is not set the process will throw a descriptive error rather than
298
+ * silently falling back to defaults, because an unresolved secret is never a
299
+ * safe default.
300
+ *
285
301
  * @param workspaceRoot - Absolute path to the workspace root directory.
286
302
  * @returns The parsed (and possibly migrated) kanban configuration.
287
303
  *