@nestos/kanban 0.5.1 → 0.5.2

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 (147) hide show
  1. package/LICENSE +674 -0
  2. package/README.md +73 -29
  3. package/dist/{activity-C6xDM-cg.d.cts → activity-BbC4sgKL.d.cts} +28 -2
  4. package/dist/{activity-Dw8DOw0L.d.ts → activity-Czlan5xW.d.ts} +28 -2
  5. package/dist/activity-module-DaO1Rry0.d.cts +22 -0
  6. package/dist/activity-module-T22wliZu.d.ts +22 -0
  7. package/dist/activity-ports-Dqxa86zT.d.cts +12 -0
  8. package/dist/activity-ports-cxfrelaL.d.ts +12 -0
  9. package/dist/activity.cjs +10 -282
  10. package/dist/activity.cjs.map +1 -1
  11. package/dist/activity.d.cts +8 -30
  12. package/dist/activity.d.ts +8 -30
  13. package/dist/activity.js +9 -281
  14. package/dist/activity.js.map +1 -1
  15. package/dist/{chunk-O4OGAAV4.js → chunk-3JYLJPE5.js} +29 -5
  16. package/dist/chunk-3JYLJPE5.js.map +1 -0
  17. package/dist/{chunk-ATUFFNLV.js → chunk-3LEIHB7Y.js} +5 -5
  18. package/dist/chunk-4XF6LQSU.cjs.map +1 -1
  19. package/dist/chunk-5Q7WB63A.cjs +282 -0
  20. package/dist/chunk-5Q7WB63A.cjs.map +1 -0
  21. package/dist/{chunk-PSKQAFDF.cjs → chunk-7KDOTBRX.cjs} +1 -1
  22. package/dist/chunk-7KDOTBRX.cjs.map +1 -0
  23. package/dist/{chunk-5DLZWW5Y.js → chunk-AHHEGTUA.js} +3 -3
  24. package/dist/chunk-AOHQCX7K.cjs +95 -0
  25. package/dist/chunk-AOHQCX7K.cjs.map +1 -0
  26. package/dist/{chunk-IUI5CI2S.cjs → chunk-DINLR6E6.cjs} +96 -92
  27. package/dist/chunk-DINLR6E6.cjs.map +1 -0
  28. package/dist/{chunk-L44TM4EE.cjs → chunk-EYTVC2H5.cjs} +568 -454
  29. package/dist/chunk-EYTVC2H5.cjs.map +1 -0
  30. package/dist/chunk-FEE2YBZ7.js +1972 -0
  31. package/dist/chunk-FEE2YBZ7.js.map +1 -0
  32. package/dist/chunk-FNO5K3A7.js +282 -0
  33. package/dist/chunk-FNO5K3A7.js.map +1 -0
  34. package/dist/chunk-IHHDXZPZ.js +382 -0
  35. package/dist/chunk-IHHDXZPZ.js.map +1 -0
  36. package/dist/chunk-J3EAIVA3.js +280 -0
  37. package/dist/chunk-J3EAIVA3.js.map +1 -0
  38. package/dist/{chunk-DFTOTBGF.js → chunk-KH3WF3K4.js} +20 -16
  39. package/dist/chunk-KH3WF3K4.js.map +1 -0
  40. package/dist/{chunk-TB2RZGDV.js → chunk-M35X5PHO.js} +14 -1
  41. package/dist/chunk-M35X5PHO.js.map +1 -0
  42. package/dist/chunk-QRGZD2JU.cjs +1972 -0
  43. package/dist/chunk-QRGZD2JU.cjs.map +1 -0
  44. package/dist/{chunk-4KF7KUAI.cjs → chunk-RBOER6EW.cjs} +6 -6
  45. package/dist/chunk-RBOER6EW.cjs.map +1 -0
  46. package/dist/{chunk-6MN3H3YF.cjs → chunk-RSH6QSEC.cjs} +16 -3
  47. package/dist/chunk-RSH6QSEC.cjs.map +1 -0
  48. package/dist/{chunk-T7P5EIC4.cjs → chunk-VMRDXOLX.cjs} +33 -33
  49. package/dist/chunk-VMRDXOLX.cjs.map +1 -0
  50. package/dist/{chunk-5XKOCKY2.js → chunk-X4UHZX6F.js} +1 -1
  51. package/dist/chunk-XBSGUVCY.cjs +382 -0
  52. package/dist/chunk-XBSGUVCY.cjs.map +1 -0
  53. package/dist/{chunk-OHQTKGQN.js → chunk-XKDZHAUE.js} +242 -128
  54. package/dist/chunk-XKDZHAUE.js.map +1 -0
  55. package/dist/chunk-ZUZGAO6G.cjs +280 -0
  56. package/dist/chunk-ZUZGAO6G.cjs.map +1 -0
  57. package/dist/{content-CAIp1njn.d.cts → content-C5aJZFlw.d.cts} +1 -1
  58. package/dist/{content-CGMJdyH_.d.ts → content-hLH5BNud.d.ts} +1 -1
  59. package/dist/contracts/index.cjs +13 -3
  60. package/dist/contracts/index.cjs.map +1 -1
  61. package/dist/contracts/index.d.cts +5 -4
  62. package/dist/contracts/index.d.ts +5 -4
  63. package/dist/contracts/index.js +14 -4
  64. package/dist/{discovery-DxpirOz3.d.cts → discovery-9E-LfwIw.d.cts} +1 -1
  65. package/dist/{discovery-gSqWpuRm.d.ts → discovery-D60yrjej.d.ts} +1 -1
  66. package/dist/discovery.cjs +63 -65
  67. package/dist/discovery.cjs.map +1 -1
  68. package/dist/discovery.d.cts +4 -4
  69. package/dist/discovery.d.ts +4 -4
  70. package/dist/discovery.js +5 -7
  71. package/dist/discovery.js.map +1 -1
  72. package/dist/execution-bridge-fpCnH6z5.d.cts +52 -0
  73. package/dist/execution-bridge-rk0uVy_n.d.ts +52 -0
  74. package/dist/execution.cjs +6 -356
  75. package/dist/execution.cjs.map +1 -1
  76. package/dist/execution.d.cts +4 -51
  77. package/dist/execution.d.ts +4 -51
  78. package/dist/execution.js +9 -359
  79. package/dist/execution.js.map +1 -1
  80. package/dist/index.cjs +10 -12
  81. package/dist/index.cjs.map +1 -1
  82. package/dist/index.d.cts +9 -16
  83. package/dist/index.d.ts +9 -16
  84. package/dist/index.js +10 -12
  85. package/dist/index.js.map +1 -1
  86. package/dist/{module-CWNK2BMj.d.ts → module-CYfE7YhM.d.ts} +2 -2
  87. package/dist/{module-BbvwdCDF.d.cts → module-Ca9L3qCn.d.cts} +2 -2
  88. package/dist/{planning-CcFZYdIL.d.cts → planning-CHrOqQ6b.d.cts} +45 -10
  89. package/dist/{planning-CcFZYdIL.d.ts → planning-CHrOqQ6b.d.ts} +45 -10
  90. package/dist/{ports-Bn6ro2FB.d.ts → ports-B0McVg7B.d.ts} +4 -3
  91. package/dist/ports-BeGO1VRI.d.cts +49 -0
  92. package/dist/{ports-CaL6geqR.d.cts → ports-GQy0x-RI.d.cts} +4 -3
  93. package/dist/ports-ykGiNUSx.d.ts +49 -0
  94. package/dist/runtime/index.cjs +205 -0
  95. package/dist/runtime/index.cjs.map +1 -0
  96. package/dist/runtime/index.d.cts +75 -0
  97. package/dist/runtime/index.d.ts +75 -0
  98. package/dist/runtime/index.js +205 -0
  99. package/dist/runtime/index.js.map +1 -0
  100. package/dist/runtime/integration.cjs +423 -0
  101. package/dist/runtime/integration.cjs.map +1 -0
  102. package/dist/runtime/integration.d.cts +658 -0
  103. package/dist/runtime/integration.d.ts +658 -0
  104. package/dist/runtime/integration.js +423 -0
  105. package/dist/runtime/integration.js.map +1 -0
  106. package/dist/storage.cjs +9 -277
  107. package/dist/storage.cjs.map +1 -1
  108. package/dist/storage.d.cts +6 -6
  109. package/dist/storage.d.ts +6 -6
  110. package/dist/storage.js +11 -279
  111. package/dist/storage.js.map +1 -1
  112. package/dist/{store-q63eSMoT.d.cts → store-DPwHzGiz.d.cts} +2 -2
  113. package/dist/{store-Ct0gOAAg.d.ts → store-DgdrPCV9.d.ts} +2 -2
  114. package/dist/task-projection-CSorlMws.d.ts +11 -0
  115. package/dist/task-projection-DKKB_ueb.d.cts +11 -0
  116. package/examples/standalone.ts +22 -0
  117. package/package.json +117 -87
  118. package/dist/chunk-2YFPV5GF.cjs +0 -16
  119. package/dist/chunk-2YFPV5GF.cjs.map +0 -1
  120. package/dist/chunk-4KF7KUAI.cjs.map +0 -1
  121. package/dist/chunk-6MN3H3YF.cjs.map +0 -1
  122. package/dist/chunk-DFTOTBGF.js.map +0 -1
  123. package/dist/chunk-G6FCDLDF.js +0 -16
  124. package/dist/chunk-G6FCDLDF.js.map +0 -1
  125. package/dist/chunk-IUI5CI2S.cjs.map +0 -1
  126. package/dist/chunk-KYNYPKKH.cjs +0 -71
  127. package/dist/chunk-KYNYPKKH.cjs.map +0 -1
  128. package/dist/chunk-L44TM4EE.cjs.map +0 -1
  129. package/dist/chunk-LSE6JG5I.cjs +0 -20
  130. package/dist/chunk-LSE6JG5I.cjs.map +0 -1
  131. package/dist/chunk-O4OGAAV4.js.map +0 -1
  132. package/dist/chunk-OHQTKGQN.js.map +0 -1
  133. package/dist/chunk-PSKQAFDF.cjs.map +0 -1
  134. package/dist/chunk-QTMTBEBA.js +0 -20
  135. package/dist/chunk-QTMTBEBA.js.map +0 -1
  136. package/dist/chunk-T7P5EIC4.cjs.map +0 -1
  137. package/dist/chunk-TB2RZGDV.js.map +0 -1
  138. package/dist/ui/index.cjs +0 -1961
  139. package/dist/ui/index.cjs.map +0 -1
  140. package/dist/ui/index.d.cts +0 -209
  141. package/dist/ui/index.d.ts +0 -209
  142. package/dist/ui/index.js +0 -1961
  143. package/dist/ui/index.js.map +0 -1
  144. package/dist/ui/kanban.css +0 -194
  145. /package/dist/{chunk-ATUFFNLV.js.map → chunk-3LEIHB7Y.js.map} +0 -0
  146. /package/dist/{chunk-5DLZWW5Y.js.map → chunk-AHHEGTUA.js.map} +0 -0
  147. /package/dist/{chunk-5XKOCKY2.js.map → chunk-X4UHZX6F.js.map} +0 -0
@@ -1,16 +0,0 @@
1
- "use strict";Object.defineProperty(exports, "__esModule", {value: true});// src/ports.ts
2
- var KanbanError = class extends Error {
3
- constructor(code) {
4
- super(code);
5
- this.code = code;
6
- this.name = "KanbanError";
7
- }
8
- };
9
- var KanbanScanNotStartedError = class extends KanbanError {
10
- };
11
-
12
-
13
-
14
-
15
- exports.KanbanError = KanbanError; exports.KanbanScanNotStartedError = KanbanScanNotStartedError;
16
- //# sourceMappingURL=chunk-2YFPV5GF.cjs.map
@@ -1 +0,0 @@
1
- {"version":3,"sources":["/home/li/share/prj/x1/release/local-libraries/work/1ca933a0-6fe7-4e9c-b13b-76d7f318e0fb/source/libraries/kanban/dist/chunk-2YFPV5GF.cjs","../src/ports.ts"],"names":[],"mappings":"AAAA;AC8CO,IAAM,YAAA,EAAN,MAAA,QAA0B,MAAM;AAAA,EACnC,WAAA,CAAqB,IAAA,EAAc;AAAE,IAAA,KAAA,CAAM,IAAI,CAAA;AAA1B,IAAA,IAAA,CAAA,KAAA,EAAA,IAAA;AAA6B,IAAA,IAAA,CAAK,KAAA,EAAO,aAAA;AAAA,EAAe;AACjF,CAAA;AAEO,IAAM,0BAAA,EAAN,MAAA,QAAwC,YAAY;AAAC,CAAA;ADxC5D;AACA;AACE;AACA;AACF,iGAAC","file":"/home/li/share/prj/x1/release/local-libraries/work/1ca933a0-6fe7-4e9c-b13b-76d7f318e0fb/source/libraries/kanban/dist/chunk-2YFPV5GF.cjs","sourcesContent":[null,"import type { KanbanActor, KanbanBoard, KanbanCommand, KanbanEvent, KanbanArchivedItem, KanbanItemSummary } from './contracts';\n\nexport interface KanbanState {\n workflow?: import('./contracts').KanbanWorkflowState;\n numbering?: {item: number; log: number; decision: number};\n presetVersions?: Record<string, number>;\n records?: import('./contracts').KanbanProjectRecord[];\n discovery?: import('./scan-ports').KanbanDiscoveryState;\n archiveIndex?: KanbanItemSummary[];\n archiveWrites?: Array<{id: string; value: KanbanArchivedItem | null}>;\n restore?: KanbanArchivedItem;\n schema: 1; board: KanbanBoard; sequence: number; events: KanbanEvent[]; escalations: string[];\n}\nexport interface KanbanReadView {\n /** Board metadata and summary indexes; no item/record bodies. */\n state: KanbanState;\n items: import('./contracts').KanbanItemSummary[];\n records: import('./contracts').KanbanRecordSummary[];\n}\nexport interface KanbanStore {\n boardId?(number: number): Promise<string | null>;\n view?(id: string): Promise<KanbanReadView | null>;\n ids(): Promise<string[]>;\n archived(boardId: string, itemId: string): Promise<KanbanArchivedItem | null>;\n events(id: string, after: number, limit: number, through: number): Promise<KanbanEvent[]>;\n read(id: string): Promise<KanbanState | null>;\n update(id: string, operationId: string, fingerprint: string,\n change: (state: KanbanState | null) => KanbanState): Promise<KanbanState>;\n}\nexport interface KanbanModuleOptions {\n /** Host supplies metadata within the authorized user's/project's session scope. */\n suggestions?(board: KanbanBoard, kind: import('./contracts').KanbanSuggestionKind, search: string, limit: number): Promise<import('./contracts').KanbanSuggestion[] | undefined>;\n verifyOutputs?(input: {stage?: 'observe' | 'accept'; board: KanbanBoard; itemId: string; dispatchId?: string; outputs: import('./contracts').KanbanArtifactRef[]}): Promise<boolean>;\n onCommitted?(boardId: string, service: import('./contracts').KanbanService, now: number): Promise<void>;\n store: KanbanStore;\n /** Trusted identity resolved by the host, never from command payloads. */\n actor: KanbanActor;\n /** Must validate project access, delegated authority and session registration. */\n authorize(input: { actor: KanbanActor; board: KanbanBoard; action: 'create' | 'read' | 'install-content' | KanbanCommand['type']; command?: KanbanCommand }): Promise<void>;\n /** Confirm an automated owner has settled before releasing responsibility. */\n verifyDeletion?(board: KanbanBoard): Promise<void>;\n verifyRelease?(input: {actor: KanbanActor; board: KanbanBoard; item: import('./contracts').KanbanItem}): Promise<boolean>;\n now?: () => number;\n id?: () => string;\n log(event: { operationId: string; boardId?: string; sessionId?: string; stage: string; result: 'success' | 'failure'; code?: string; durationMs: number }): void;\n}\nexport class KanbanError extends Error {\n constructor(readonly code: string) { super(code); this.name = 'KanbanError'; }\n}\n\nexport class KanbanScanNotStartedError extends KanbanError {}\n"]}
@@ -1 +0,0 @@
1
- {"version":3,"sources":["/home/li/share/prj/x1/release/local-libraries/work/1ca933a0-6fe7-4e9c-b13b-76d7f318e0fb/source/libraries/kanban/dist/chunk-4KF7KUAI.cjs","../src/discovery-state.ts","../src/configuration.ts","../src/rules.ts","../src/identity.ts"],"names":["executable"],"mappings":"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","file":"/home/li/share/prj/x1/release/local-libraries/work/1ca933a0-6fe7-4e9c-b13b-76d7f318e0fb/source/libraries/kanban/dist/chunk-4KF7KUAI.cjs","sourcesContent":[null,"import type {KanbanDiscoveryState} from './scan-ports';\n\nexport function discoveryState(state: {discovery?: unknown} | null | undefined): KanbanDiscoveryState | undefined {\n return state?.discovery as KanbanDiscoveryState | undefined;\n}\n","import {DEFAULT_KANBAN_WORK_TYPES, executableWorkItem} from './contracts';\nimport type {KanbanBoard, KanbanPolicy, KanbanWorkType} from './contracts';\nimport {identity, requireValue, text} from './rules';\nimport {principalKey, roster} from './identity';\n\nexport function policy(input: Partial<KanbanPolicy> = {}): KanbanPolicy {\n return {claimTimeoutMs: 86400000, leaseMs: 600000, progressTimeoutMs: 3600000, transferTimeoutMs: 1800000,\n maxComplexity: 10, maxWorkUnits: 100, maxDurationMs: 28800000, escalationSessionIds: [], ...input};\n}\nexport function workTypes(board: KanbanBoard): readonly KanbanWorkType[] {return board.workTypes ?? DEFAULT_KANBAN_WORK_TYPES;}\nexport function workType(board: KanbanBoard, id: string): KanbanWorkType {\n const found = workTypes(board).find(type => type.id === id); requireValue(found, 'UNKNOWN_WORK_TYPE'); return found;\n}\nexport function executable(board: KanbanBoard, item: {planning?: {kind: string; execution?: 'direct'|'children'}}): boolean {\n workType(board, item.planning?.kind ?? board.defaultWorkType ?? 'task');\n return executableWorkItem(board,item);\n}\nexport function validateConfiguration(board: KanbanBoard): void {\n const types = workTypes(board); requireValue(types.length > 0 && types.length <= 20, 'WORK_TYPE_LIMIT');\n requireValue(new Set(types.map(t => t.id)).size === types.length, 'DUPLICATE_WORK_TYPE');\n for (const type of types) {\n identity(type.id); text(type.label); requireValue(Number.isInteger(type.rank) && type.rank >= 0 && type.rank <= 9 && typeof type.executable === 'boolean', 'INVALID_WORK_TYPE');\n }\n workType(board, board.defaultWorkType ?? 'task');\n const members = roster(board); requireValue(members.length > 0, 'MEMBER_ROSTER_REQUIRED');\n requireValue(new Set(members.map(principalKey)).size === members.length, 'DUPLICATE_MEMBER');\n for (const member of members) {identity(member.id); requireValue(['agent', 'human', 'service'].includes(member.kind), 'INVALID_PRINCIPAL');}\n for (const member of board.members ?? []) {\n text(member.responsibility); requireValue(!member.roles || member.roles.every(r => ['worker', 'reviewer', 'coordinator'].includes(r)), 'INVALID_MEMBER_ROLE');\n }\n validateColumns(board);\n for (const [kind, value] of Object.entries(board.notifications?.rules ?? {}))\n requireValue(/^[a-z][a-z0-9.-]{0,79}$/.test(kind) && ['info', 'error', 'none'].includes(value), 'INVALID_NOTIFICATION_RULE');\n}\nfunction validateColumns(board: KanbanBoard): void {\n if (!board.columns) return;\n const states = board.columns.flatMap(c => c.states);\n requireValue(states.length === 7 && new Set(states).size === 7 && ['proposed', 'backlog', 'open', 'claimed', 'review', 'completed', 'cancelled'].every(s => states.includes(s as never)), 'INVALID_COLUMNS');\n requireValue(new Set(board.columns.map(c => c.id)).size === board.columns.length, 'DUPLICATE_COLUMN');\n for (const column of board.columns) {identity(column.id); text(column.label); requireValue(column.states.length > 0, 'EMPTY_COLUMN');}\n}\n","import type { KanbanActor, KanbanBoard, KanbanEstimate, KanbanItem, KanbanParticipant } from './contracts';\nimport {validateConfiguration} from './configuration';\nimport {sameOwner} from './identity';\nimport { KanbanError } from './ports';\n\nexport function requireValue(condition: unknown, code: string): asserts condition {\n if (!condition) throw new KanbanError(code);\n}\nexport function text(value: string): void { requireValue(typeof value === 'string' && value.trim().length > 0 && value.length <= 8000, 'INVALID_TEXT'); }\nexport function identity(value: string): void { requireValue(typeof value === 'string' && value.length > 0 && value.length <= 256 && !['__proto__', 'prototype', 'constructor'].includes(value), 'INVALID_ID'); }\nexport function positive(value: number): void { requireValue(Number.isFinite(value) && value > 0, 'INVALID_THRESHOLD'); }\nexport function validateEstimate(estimate: KanbanEstimate): void {\n positive(estimate.complexity); positive(estimate.workUnits); positive(estimate.durationMs);\n requireValue(['low', 'medium', 'high'].includes(estimate.confidence), 'INVALID_CONFIDENCE');\n}\nexport function validateBoard(board: KanbanBoard): void {\n identity(board.id); text(board.title);\n requireValue(['system', 'project', 'collection'].includes(board.scope.kind), 'INVALID_SCOPE');\n if (board.scope.kind === 'project') identity(board.scope.projectId);\n if (board.scope.kind === 'collection') {identity(board.scope.namespace); identity(board.scope.id);}\n validateConfiguration(board);\n for (const agent of board.agents ?? []) { identity(agent.agentId); text(agent.responsibility); }\n requireValue(new Set((board.agents ?? []).map(a => a.agentId)).size === (board.agents ?? []).length, 'DUPLICATE_AGENT');\n const p = board.policy;\n for (const value of [p.maxReady, p.maxInProgress, p.maxInProgressPerAgent, p.maxInProgressPerAssignee]) if (value !== undefined) requireValue(Number.isSafeInteger(value) && value > 0, 'INVALID_LIMIT');\n requireValue(p.maxInProgressPerAgent === undefined || p.maxInProgressPerAssignee === undefined || p.maxInProgressPerAgent === p.maxInProgressPerAssignee, 'POLICY_LIMIT_CONFLICT');\n for (const value of [p.archiveAfterMs, p.backlogReviewMs]) if (value !== undefined) positive(value);\n for (const value of [p.claimTimeoutMs, p.leaseMs, p.progressTimeoutMs, p.transferTimeoutMs,\n p.maxComplexity, p.maxWorkUnits, p.maxDurationMs]) positive(value);\n requireValue(Array.isArray(p.escalationSessionIds), 'INVALID_ESCALATION_TARGETS');\n requireValue(p.review === undefined || ['independent', 'assignee'].includes(p.review), 'INVALID_REVIEW_POLICY');\n requireValue(p.requireEstimate === undefined || typeof p.requireEstimate === 'boolean', 'INVALID_ESTIMATE_POLICY');\n p.escalationSessionIds.forEach(identity);\n}\nexport function participant(list: KanbanParticipant[], sessionId: string, agentId: string | undefined,\n role: KanbanParticipant['roles'][number], subscribed: boolean, now: number): void {\n identity(sessionId);\n requireValue(['creator', 'owner', 'consultant', 'reviewer', 'observer', 'escalation'].includes(role), 'INVALID_ROLE');\n let entry = list.find(value => value.sessionId === sessionId);\n if (!entry) { entry = { sessionId, agentId, roles: [], subscribed, joinedAt: now }; list.push(entry); }\n if (entry.agentId && agentId) requireValue(entry.agentId === agentId, 'SESSION_AGENT_CONFLICT');\n entry.agentId ??= agentId;\n if (!entry.roles.includes(role)) entry.roles.push(role);\n entry.subscribed = subscribed;\n}\nexport function owned(item: KanbanItem, actor: KanbanActor, token: string, now: number): void {\n requireValue(item.status === 'claimed', 'ITEM_NOT_RUNNING');\n requireValue(item.owner && sameOwner(item.owner, actor) && item.owner.token === token, 'OWNER_MISMATCH');\n requireValue(item.owner.leaseUntil > now, 'LEASE_EXPIRED');\n}\n","import type {KanbanActor, KanbanAssignment, KanbanBoard, KanbanItem, KanbanPrincipal} from './contracts';\nimport {identity, requireValue} from './rules';\n\nexport function principal(actor: KanbanActor): KanbanPrincipal {\n const kind = actor.kind ?? 'agent', id = kind === 'agent' ? actor.agentId ?? actor.id : actor.id;\n requireValue(['agent', 'human', 'service'].includes(kind) && id, 'INVALID_ACTOR'); identity(id);\n if (kind === 'agent') {requireValue(!actor.agentId || !actor.id || actor.agentId === actor.id, 'ACTOR_ID_MISMATCH'); if (actor.sessionId !== undefined) identity(actor.sessionId); if (actor.taskId !== undefined) identity(actor.taskId);}\n return {kind, id};\n}\nexport function principalKey(value: KanbanPrincipal): string {return JSON.stringify([value.kind, value.id]);}\nexport function assigneeKey(value: KanbanAssignment): string {\n return value.principalId ?? principalKey({kind: 'agent', id: value.agentId!});\n}\nexport function sameOwner(owner: KanbanAssignment, actor: KanbanActor): boolean {\n const value = principal(actor);\n return assigneeKey(owner) === principalKey(value) && (value.kind !== 'agent' || owner.sessionId === actor.sessionId && owner.taskId === actor.taskId);\n}\nexport function roster(board: KanbanBoard): KanbanPrincipal[] {\n return [...(board.agents ?? []).map(a => ({kind: 'agent' as const, id: a.agentId})), ...(board.members ?? [])];\n}\nexport function candidates(board: KanbanBoard, item: KanbanItem): KanbanPrincipal[] {\n if (item.eligibleAgentIds === undefined && item.eligiblePrincipals === undefined)\n return [...(board.agents ?? []).map(a => ({kind: 'agent' as const, id: a.agentId})),\n ...(board.members ?? []).filter(m => !m.roles || m.roles.includes('worker'))];\n return [...(item.eligibleAgentIds ?? []).map(id => ({kind: 'agent' as const, id})), ...(item.eligiblePrincipals ?? [])];\n}\nexport function eligible(board: KanbanBoard, item: KanbanItem, actor: KanbanActor): void {\n const key = principalKey(principal(actor));\n requireValue(candidates(board, item).some(p => principalKey(p) === key), actor.kind && actor.kind !== 'agent' ? 'ASSIGNEE_NOT_ELIGIBLE' : 'AGENT_NOT_ELIGIBLE');\n}\nexport function validateCandidates(board: KanbanBoard, item: KanbanItem, executable: boolean): void {\n const allowed = new Set(roster(board).map(principalKey)), values = candidates(board, item);\n requireValue(!executable || values.length > 0, 'ELIGIBLE_ASSIGNEES_REQUIRED');\n for (const value of values) {\n identity(value.id); requireValue(['agent', 'human', 'service'].includes(value.kind), 'INVALID_PRINCIPAL');\n requireValue(allowed.has(principalKey(value)), value.kind === 'agent' ? 'AGENT_NOT_REGISTERED' : 'ASSIGNEE_NOT_REGISTERED');\n }\n}\n\nexport function normalizeActor(actor: KanbanActor): KanbanActor {\n const value = principal(actor);\n return value.kind === 'agent' ? {agentId: value.id, sessionId: actor.sessionId, taskId: actor.taskId}\n : {kind: value.kind, id: value.id};\n}\n"]}
@@ -1 +0,0 @@
1
- {"version":3,"sources":["/home/li/share/prj/x1/release/local-libraries/work/1ca933a0-6fe7-4e9c-b13b-76d7f318e0fb/source/libraries/kanban/dist/chunk-6MN3H3YF.cjs","../src/utils/random.ts","../src/utils/digest.ts"],"names":[],"mappings":"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","file":"/home/li/share/prj/x1/release/local-libraries/work/1ca933a0-6fe7-4e9c-b13b-76d7f318e0fb/source/libraries/kanban/dist/chunk-6MN3H3YF.cjs","sourcesContent":[null,"/**\n * @file common/utils/random.ts\n * @description UUID v4 that also works outside a secure context.\n *\n * `crypto.randomUUID()` is secure-context-only: it is undefined over plain-HTTP\n * LAN origins (e.g. http://192.168.x.x:3000) and in WebKitGTK, so calling it\n * directly throws \"crypto.randomUUID is not a function\". `crypto.getRandomValues()`\n * stays available everywhere, so it backs the fallback below.\n */\n\n/** UUID v4 — native WebCrypto when available, `getRandomValues` otherwise. */\nexport function randomUUID(): string {\n const webCrypto = globalThis.crypto;\n if (typeof webCrypto?.randomUUID === 'function') {\n try {\n return webCrypto.randomUUID();\n } catch {\n // Present but unusable (insecure context) — fall through.\n }\n }\n return formatV4(randomBytes(16));\n}\n\nfunction randomBytes(length: number): Uint8Array {\n const bytes = new Uint8Array(length);\n if (typeof globalThis.crypto?.getRandomValues === 'function') {\n globalThis.crypto.getRandomValues(bytes);\n return bytes;\n }\n for (let i = 0; i < length; i++) bytes[i] = Math.floor(Math.random() * 256);\n return bytes;\n}\n\nfunction formatV4(bytes: Uint8Array): string {\n bytes[6] = (bytes[6] & 0x0f) | 0x40; // version 4\n bytes[8] = (bytes[8] & 0x3f) | 0x80; // RFC 4122 variant\n const hex = [...bytes].map(byte => byte.toString(16).padStart(2, '0'));\n return `${hex.slice(0, 4).join('')}-${hex.slice(4, 6).join('')}-${hex.slice(6, 8).join('')}-${hex.slice(8, 10).join('')}-${hex.slice(10).join('')}`;\n}\n","/**\n * @file common/utils/digest.ts\n * @description SHA-256 that does not require WebCrypto.\n *\n * `crypto.subtle` only exists in a secure context (HTTPS or localhost) and is\n * absent in WebKitGTK, so `crypto.subtle.digest(...)` throws \"Cannot read\n * properties of undefined (reading 'digest')\" when the app is opened over a LAN\n * HTTP origin (e.g. http://192.168.x.x:3000) or in the packaged Linux app. The\n * pure-JS fallback below computes the very same SHA-256, so digests stay stable\n * across environments.\n */\n\n/** Any input a caller may want hashed. */\nexport type DigestInput = string | ArrayBuffer | ArrayBufferView;\n\nconst SHA256_K = new Uint32Array([\n 0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5,\n 0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3, 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174,\n 0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc, 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da,\n 0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7, 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967,\n 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13, 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85,\n 0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3, 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070,\n 0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3,\n 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208, 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2,\n]);\n\nconst SHA256_H = new Uint32Array([\n 0x6a09e667, 0xbb67ae85, 0x3c6ef372, 0xa54ff53a, 0x510e527f, 0x9b05688c, 0x1f83d9ab, 0x5be0cd19,\n]);\n\nconst rotateRight = (value: number, bits: number): number =>\n ((value >>> bits) | (value << (32 - bits))) >>> 0;\n\nfunction toBytes(input: DigestInput): Uint8Array<ArrayBuffer> {\n if (typeof input === 'string') return new TextEncoder().encode(input);\n if (input instanceof Uint8Array && input.buffer instanceof ArrayBuffer) {\n return input as Uint8Array<ArrayBuffer>;\n }\n if (ArrayBuffer.isView(input)) {\n // Copy so WebCrypto gets a plain ArrayBuffer (never a SharedArrayBuffer view).\n const source = new Uint8Array(input.buffer as ArrayBufferLike, input.byteOffset, input.byteLength);\n const copy = new Uint8Array(input.byteLength);\n copy.set(source);\n return copy;\n }\n return new Uint8Array(input);\n}\n\nfunction toHex(bytes: Uint8Array): string {\n return [...bytes].map(byte => byte.toString(16).padStart(2, '0')).join('');\n}\n\nfunction paddedMessage(message: Uint8Array): Uint8Array {\n const padded = new Uint8Array((Math.floor((message.length + 8) / 64) + 1) * 64);\n padded.set(message);\n padded[message.length] = 0x80;\n const view = new DataView(padded.buffer);\n const bitLength = message.length * 8;\n view.setUint32(padded.length - 8, Math.floor(bitLength / 0x1_0000_0000));\n view.setUint32(padded.length - 4, bitLength >>> 0);\n return padded;\n}\n\nfunction blockSchedule(view: DataView, offset: number): Uint32Array {\n const words = new Uint32Array(64);\n for (let i = 0; i < 16; i++) words[i] = view.getUint32(offset + i * 4);\n for (let i = 16; i < 64; i++) {\n const s0 = rotateRight(words[i - 15], 7) ^ rotateRight(words[i - 15], 18) ^ (words[i - 15] >>> 3);\n const s1 = rotateRight(words[i - 2], 17) ^ rotateRight(words[i - 2], 19) ^ (words[i - 2] >>> 10);\n words[i] = (words[i - 16] + s0 + words[i - 7] + s1) >>> 0;\n }\n return words;\n}\n\nfunction compressBlock(state: Uint32Array, words: Uint32Array): void {\n let [a, b, c, d, e, f, g, h] = state;\n for (let i = 0; i < 64; i++) {\n const sigma1 = rotateRight(e, 6) ^ rotateRight(e, 11) ^ rotateRight(e, 25);\n const choose = (e & f) ^ (~e & g);\n const temp1 = (h + sigma1 + choose + SHA256_K[i] + words[i]) >>> 0;\n const sigma0 = rotateRight(a, 2) ^ rotateRight(a, 13) ^ rotateRight(a, 22);\n const majority = (a & b) ^ (a & c) ^ (b & c);\n const temp2 = (sigma0 + majority) >>> 0;\n h = g; g = f; f = e; e = (d + temp1) >>> 0;\n d = c; c = b; b = a; a = (temp1 + temp2) >>> 0;\n }\n const next = [a, b, c, d, e, f, g, h];\n for (let i = 0; i < 8; i++) state[i] = (state[i] + next[i]) >>> 0;\n}\n\n/** Pure-JS SHA-256 usable where WebCrypto is unavailable. */\nexport function sha256Bytes(input: DigestInput): Uint8Array {\n const padded = paddedMessage(toBytes(input));\n const view = new DataView(padded.buffer);\n const state = SHA256_H.slice();\n for (let offset = 0; offset < padded.length; offset += 64) {\n compressBlock(state, blockSchedule(view, offset));\n }\n const out = new Uint8Array(32);\n const outView = new DataView(out.buffer);\n for (let i = 0; i < 8; i++) outView.setUint32(i * 4, state[i]);\n return out;\n}\n\n/** SHA-256 hex digest — WebCrypto when available, pure JS otherwise. */\nexport async function sha256Hex(input: DigestInput): Promise<string> {\n const bytes = toBytes(input);\n const subtle = globalThis.crypto?.subtle;\n if (subtle?.digest) {\n try {\n return toHex(new Uint8Array(await subtle.digest('SHA-256', bytes)));\n } catch {\n // WebCrypto present but unusable (e.g. blocked by an insecure context).\n }\n }\n return toHex(sha256Bytes(bytes));\n}\n\n/** Synchronous SHA-256 hex digest (pure JS, no WebCrypto). */\nexport function sha256HexSync(input: DigestInput): string {\n return toHex(sha256Bytes(input));\n}\n"]}
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/references.ts","../src/suggestions.ts","../src/queries.ts","../src/module.ts"],"sourcesContent":["import {kanbanReference, type KanbanReferenceTarget} from './contracts';\nimport type {KanbanReadView, KanbanStore} from './ports';\nimport {requireValue} from './rules';\n\nexport async function resolveReference(reference: string, store: KanbanStore, read: (id: string) => Promise<KanbanReadView>): Promise<KanbanReferenceTarget> {\n requireValue(typeof reference === 'string' && reference.length <= 100, 'INVALID_REFERENCE');\n const match = /^KB-([1-9]\\d*)(?:#([1-9]\\d*)|\\/(L|D)-([1-9]\\d*))?$/i.exec(reference.trim());\n requireValue(match && [match[1], match[2], match[4]].every(value => value === undefined || Number.isSafeInteger(Number(value))), 'INVALID_REFERENCE');\n const id = await store.boardId?.(Number(match[1])); requireValue(id, 'REFERENCE_NOT_FOUND');\n const view = await read(id), board = view.state.board;\n requireValue(board.number === Number(match[1]), 'INVALID_NUMBERING');\n const target: KanbanReferenceTarget = {boardId: id, scope: board.scope, reference: kanbanReference(board)};\n if (match[2]) {\n const item = [...view.items, ...(view.state.archiveIndex ?? [])].find(item => item.number === Number(match[2]));\n requireValue(item, 'REFERENCE_NOT_FOUND'); target.itemId = item.id; target.reference = kanbanReference(board, item);\n } else if (match[3]) {\n const record = view.records.find(record => record.kind === (match[3].toUpperCase() === 'L' ? 'log' : 'decision') && record.number === Number(match[4]));\n requireValue(record, 'REFERENCE_NOT_FOUND'); target.recordId = record.id; target.reference = kanbanReference(board, record);\n }\n return target;\n}\n","import {kanbanReference} from './contracts';\nimport type {KanbanSuggestion, KanbanSuggestionPage, KanbanSuggestionQuery} from './contracts';\nimport type {KanbanState} from './ports';\nimport {recordSummary} from './project-records';\nimport {catalog, terminal} from './planning';\nimport {workType} from './configuration';\nimport {identity, requireValue} from './rules';\n\nexport function validateSuggestionQuery(query: KanbanSuggestionQuery): number {\n requireValue(query && ['item', 'parent', 'dependency', 'area', 'milestone', 'decision', 'session'].includes(query.kind), 'INVALID_SUGGESTION_KIND');\n requireValue(query.search === undefined || typeof query.search === 'string' && query.search.length <= 256, 'INVALID_FILTER');\n const limit = query.limit ?? 20; requireValue(Number.isSafeInteger(limit) && limit > 0 && limit <= 50, 'INVALID_LIMIT');\n if (query.excludeItemId !== undefined) identity(query.excludeItemId);\n if (query.excludeIds !== undefined) {requireValue(Array.isArray(query.excludeIds) && query.excludeIds.length <= 100, 'INVALID_FILTER'); query.excludeIds.forEach(identity);}\n if (query.childKind !== undefined) identity(query.childKind);\n return limit;\n}\nexport function suggestionPage(revision: number, rows: KanbanSuggestion[], query: KanbanSuggestionQuery): KanbanSuggestionPage {\n const limit = validateSuggestionQuery(query), search = query.search?.trim().toLocaleLowerCase() ?? '';\n const matched = rows.filter(row => !query.excludeIds?.includes(row.id)).filter(row => `${row.id} ${row.label} ${row.detail ?? ''}`.toLocaleLowerCase().includes(search))\n .sort((a, b) => score(a.label, search) - score(b.label, search) || a.label.localeCompare(b.label) || a.id.localeCompare(b.id));\n return {revision, items: matched.slice(0, limit).map(row => ({id: row.id, label: row.label.slice(0, 256), ...(row.detail ? {detail: row.detail.slice(0, 512)} : {}), ...(row.status ? {status: row.status} : {}), ...(row.archived !== undefined ? {archived: row.archived} : {})})), hasMore: matched.length > limit};\n}\nconst score = (label: string, query: string) => label.toLocaleLowerCase() === query ? 0 : label.toLocaleLowerCase().startsWith(query) ? 1 : 2;\nexport function suggestFromState(state: KanbanState, query: KanbanSuggestionQuery, items = catalog(state), records = (state.records ?? []).map(recordSummary)): KanbanSuggestionPage {\n validateSuggestionQuery(query);\n if (query.kind === 'area' || query.kind === 'milestone') {\n const names = [...new Set(items.map(item => item.planning[query.kind as 'area' | 'milestone']).filter((name): name is string => !!name))];\n return suggestionPage(state.board.revision, names.map(name => ({id: name, label: name})), query);\n }\n if (query.kind === 'decision') return suggestionPage(state.board.revision, records\n .filter(record => record.kind === 'decision' && record.status === 'confirmed').map(record => ({id: record.id, label: record.title, detail: kanbanReference(state.board, record)})), query);\n if (query.kind === 'session') {\n const ids = new Set([...state.board.participants.map(p => p.sessionId), ...items.flatMap(item => item.sessionIds),\n ...records.flatMap(record => record.sessionIds)]);\n return suggestionPage(state.board.revision, [...ids].map(id => ({id, label: id})), query);\n }\n const blocked = query.kind === 'dependency' && query.excludeItemId ? dependents(items, query.excludeItemId) : new Set<string>();\n const rank = query.kind === 'parent' ? workType(state.board, query.childKind ?? state.board.defaultWorkType ?? 'task').rank : undefined;\n const rows = items.filter(item => item.id !== query.excludeItemId && !blocked.has(item.id)\n && (query.kind !== 'dependency' || item.status !== 'cancelled')\n && (rank === undefined || item.archivedAt === undefined && !terminal(item) && workType(state.board, item.planning.kind).rank < rank))\n .map(item => ({id: item.id, label: item.title, status: item.status, archived: item.archivedAt !== undefined,\n detail: [kanbanReference(state.board, item), item.planning.area, item.planning.milestone].filter(Boolean).join(' · ')}));\n return suggestionPage(state.board.revision, rows, query);\n}\nfunction dependents(items: import('./contracts').KanbanItemSummary[], id: string): Set<string> {\n const reverse = new Map<string, string[]>();\n for (const item of items) for (const dependency of item.planning.dependencies) reverse.set(dependency, [...(reverse.get(dependency) ?? []), item.id]);\n const result = new Set([id]), pending = [id];\n while (pending.length) for (const next of reverse.get(pending.pop()!) ?? []) if (!result.has(next)) {result.add(next); pending.push(next);}\n return result;\n}\n","import {projectKanbanTask} from './contracts/task-projection';\nimport {kanbanReference} from './contracts';\nimport type {KanbanItemPage, KanbanItemQuery, KanbanItemSummary, KanbanOverview} from './contracts';\nimport type {KanbanState} from './ports';\nimport {requireValue} from './rules';\nimport {executable} from './configuration';\nimport {catalog, limits, summary, terminal} from './planning';\n\nexport function queryItems(state: KanbanState, query: KanbanItemQuery = {}, all = catalog(state), now = Date.now()): KanbanItemPage {\n const {cursor, limit = 50, ...filters} = query;\n requireValue(Number.isSafeInteger(limit) && limit >= 1 && limit <= 200, 'INVALID_PAGE_SIZE');\n requireValue(['ready', 'backlog', 'in-progress', 'review', 'closed', 'proposed', 'archive', 'all'].includes(query.view ?? 'ready'), 'INVALID_VIEW');\n for (const field of ['area', 'milestone', 'parentId', 'kind', 'sessionId', 'search'] as const) if (filters[field] !== undefined) requireValue(typeof filters[field] === 'string' && filters[field]!.length <= 256, 'INVALID_FILTER');\n if (filters.reference) requireValue(typeof filters.reference.system === 'string' && typeof filters.reference.id === 'string' && filters.reference.system.length <= 256 && filters.reference.id.length <= 256, 'INVALID_REFERENCE_FILTER');\n const fingerprint = JSON.stringify(Object.fromEntries(Object.entries({...filters, view: filters.view ?? 'ready'}).sort(([a], [b]) => a.localeCompare(b)))), revision = state.board.revision;\n all = all.map(item => ({...item, task: projectKanbanTask(item, state.workflow, now, all)}));\n const matches = all.filter(item => matchesQuery(item, filters, state.board)).sort(filters.view === 'archive'\n ? (a, b) => (b.archivedAt ?? 0) - (a.archivedAt ?? 0) || a.id.localeCompare(b.id) : order);\n let start = 0;\n if (cursor) {\n requireValue(typeof cursor === 'string' && cursor.length <= 4000, 'INVALID_CURSOR');\n let decoded: {revision: number; after: string; filter: string};\n try {decoded = JSON.parse(cursor);} catch {requireValue(false, 'INVALID_CURSOR');}\n requireValue(decoded && decoded.filter === fingerprint, 'CURSOR_SCOPE_MISMATCH');\n requireValue(decoded.revision === revision, 'CURSOR_STALE');\n start = matches.findIndex(i => i.id === decoded.after) + 1; requireValue(start > 0, 'INVALID_CURSOR');\n }\n const progress = progressByParent(state, all);\n const items = matches.slice(start, start + limit).map(item => ({...item, ...(progress.has(item.id) ? {progress: progress.get(item.id)} : {})}));\n return {revision, total: matches.length, items, ...(start + items.length < matches.length ? {\n nextCursor: JSON.stringify({revision, after: items.at(-1)!.id, filter: fingerprint}),\n } : {})};\n}\nfunction order(a: KanbanItemSummary, b: KanbanItemSummary): number {\n return a.planning.priority - b.planning.priority || a.createdAt - b.createdAt || a.id.localeCompare(b.id);\n}\nfunction matchesQuery(item: KanbanItemSummary, query: Omit<KanbanItemQuery, 'cursor' | 'limit'>, board: KanbanState['board']): boolean {\n if (query.phase && item.task?.phase !== query.phase) return false;\n if (!matchesView(item, query.view ?? 'ready')) return false;\n for (const field of ['area', 'milestone', 'parentId', 'kind'] as const) if (query[field] !== undefined && item.planning[field] !== query[field]) return false;\n if (query.reference && !item.externalRefs?.some(r => r.system === query.reference!.system && r.id === query.reference!.id)) return false;\n if (query.sessionId && !item.sessionIds.includes(query.sessionId)) return false;\n if (query.search && !`${kanbanReference(board, item)} ${item.id} ${item.title} ${item.planning.area ?? ''}`.toLowerCase().includes(query.search.toLowerCase())) return false;\n return true;\n}\nfunction matchesView(item: KanbanItemSummary, view: KanbanItemQuery['view']): boolean {\n if (view === 'archive') return item.archivedAt !== undefined;\n if (view === 'all') return true;\n if (item.archivedAt !== undefined) return false;\n if (view === 'in-progress') return item.status === 'claimed' || item.status === 'review';\n if (view === 'closed') return terminal(item);\n return item.status === ({ready: 'open', backlog: 'backlog', review: 'review', proposed: 'proposed'} as Record<string, string>)[view!];\n}\nexport function overview(state: KanbanState, now: number, items = state.board.items.map(summary)): KanbanOverview {\n const count = (status: string) => items.filter(i => i.status === status).length;\n const age = state.board.policy.backlogReviewMs;\n return {revision: state.board.revision, visible: items.length, active: items.filter(i => !terminal(i)).length, archived: state.archiveIndex?.length ?? 0, ready: count('open'),\n inProgress: count('claimed') + count('review'), backlog: count('backlog'), proposed: count('proposed'),\n closed: count('completed') + count('cancelled'), dueForReview: age ? items.filter(i => i.status === 'backlog' && now - i.updatedAt >= age).length : 0,\n limits: limits(state)};\n}\n\nfunction progressByParent(state: KanbanState, all: KanbanItemSummary[]): Map<string, NonNullable<KanbanItemSummary['progress']>> {\n const byId = new Map(all.map(i => [i.id, i]));\n const result = new Map<string, NonNullable<KanbanItemSummary['progress']>>();\n for (const item of all.filter(i => executable(state.board, i))) {\n let parent = item.planning.parentId; const seen = new Set<string>();\n while (parent && !seen.has(parent)) {\n seen.add(parent); const progress = result.get(parent) ?? {total: 0, completed: 0, cancelled: 0, inProgress: 0};\n progress.total++; if (item.status === 'completed') progress.completed++; if (item.status === 'cancelled') progress.cancelled++;\n if (item.status === 'claimed' || item.status === 'review') progress.inProgress++;\n result.set(parent, progress); parent = byId.get(parent)?.planning.parentId;\n }\n }\n return result;\n}\n","import {boardControlPhase} from './contracts/board-control';\nimport {projectKanbanTask} from './contracts/task-projection';\nimport {resolveReference} from './references';\nimport {suggestFromState, suggestionPage, validateSuggestionQuery} from './suggestions';\nimport {queryRecords} from './project-records';\nimport { randomUUID } from './utils';\nimport type { KanbanBoard, KanbanRequest, KanbanService, KanbanItemQuery, KanbanBoardInput } from './contracts';\nimport { KanbanError, type KanbanModuleOptions, type KanbanState } from './ports';\nimport { identity, requireValue } from './rules';\nimport {createBoardState} from './board';\nimport {normalizeActor, principal, principalKey, sameOwner} from './identity';\nimport {queryItems, overview} from './queries';\nimport {viewFromState} from './storage-codec';\nimport { reduce, related } from './reducer';\n\n/** Optional host-owned service; no timer or model calls are started implicitly. */\nexport function createKanbanModule(options: KanbanModuleOptions): KanbanModuleHandle { return new KanbanModule(options); }\nexport interface KanbanModuleHandle extends KanbanService {quiesce(): Promise<void>; dispose(): Promise<void>}\nclass KanbanModule implements KanbanService {\n private stopping = false;\n private readonly pending = new Set<Promise<unknown>>();\n async quiesce(): Promise<void> {this.stopping = true; await Promise.allSettled([...this.pending]);}\n async dispose(): Promise<void> {await this.quiesce();}\n private readonly now;\n private readonly id;\n private readonly actor;\n constructor(private readonly options: KanbanModuleOptions) {\n this.now = options.now ?? Date.now; this.id = options.id ?? randomUUID;\n this.actor = normalizeActor(options.actor);\n }\n workflow = (boardId: string) => this.guard(this.id(), boardId, 'workflow', async () => structuredClone((await this.readView(boardId)).state.workflow ?? {plans:{},dispatches:{},ready:[],completedPlans:[]}));\n resolve = (reference: string) => this.guard(this.id(), undefined, 'resolve', () => resolveReference(reference, this.options.store, id => this.readView(id)));\n suggest = (boardId: string, query: import('./contracts').KanbanSuggestionQuery) => this.guard(this.id(), boardId, 'suggest', async () => {\n const snapshot = structuredClone(query), limit = validateSuggestionQuery(snapshot), view = await this.readView(boardId), state = view.state;\n const suggestions = () => suggestFromState(state, snapshot, [...view.items, ...(state.archiveIndex ?? [])], view.records);\n if (!this.options.suggestions) return suggestions();\n const rows = await this.options.suggestions(structuredClone(state.board), snapshot.kind, snapshot.search?.trim() ?? '', limit + 1);\n if (rows === undefined) return suggestions();\n const known = suggestions().items.filter(row => !rows.some(entry => entry.id === row.id));\n return suggestionPage(state.board.revision, [...rows, ...known], snapshot);\n });\n records = (boardId: string, query?: import('./contracts').KanbanRecordQuery) => this.guard(this.id(), boardId, 'records', async () => {const view = await this.readView(boardId); return structuredClone(queryRecords(view.state, query, view.records));});\n record = (boardId: string, recordId: string) => this.guard(this.id(), boardId, 'record', async () => {\n identity(recordId); const record = (await this.readState(boardId)).records?.find(record => record.id === recordId);\n requireValue(record, 'RECORD_NOT_FOUND'); return structuredClone(record);\n });\n currentPrincipal = async () => structuredClone(principal(this.actor));\n create = (input: KanbanBoardInput): Promise<KanbanBoard> => {\n const snapshot = structuredClone(input);\n return this.guard(this.id(), snapshot.id, 'create', async () => {\n const initial = createBoardState(snapshot, this.actor, this.now()), board = initial.board;\n await this.authorize(board, 'create');\n const state = await this.options.store.update(board.id, `create:${board.id}`, JSON.stringify({ snapshot, actor: this.actor }), previous => {\n requireValue(!previous, 'BOARD_EXISTS'); return initial;\n });\n return structuredClone(state.board);\n });\n };\n read = (boardId: string): Promise<KanbanBoard> => this.guard(this.id(), boardId, 'read',\n async () => structuredClone((await this.readState(boardId)).board));\n catalog = () => this.guard(this.id(), undefined, 'catalog', async () => {\n const boards: import('./contracts').KanbanBoardSummary[] = [];\n for (const id of await this.options.store.ids()) {\n try {const view = await this.readView(id); if (view.state.board.deletedAt !== undefined) continue; boards.push({...view.state.board, executionPhase: boardControlPhase({...view.state.board, items: view.items}), items: view.items.map(({id, title, number}) => ({id, title, ...(number === undefined ? {} : {number})}))});}\n catch (error) {if (!(error instanceof KanbanError) || error.code !== 'FORBIDDEN') throw error;}\n }\n return structuredClone(boards);\n });\n list = (): Promise<KanbanBoard[]> => this.guard(this.id(), undefined, 'list', async () => {\n const boards: KanbanBoard[] = [];\n for (const boardId of await this.options.store.ids()) {\n try { const board = (await this.readState(boardId)).board; if (board.deletedAt === undefined) boards.push(structuredClone(board)); }\n catch (error) { if (!(error instanceof KanbanError) || error.code !== 'FORBIDDEN') throw error; }\n }\n return boards;\n });\n execute = (boardId: string, input: KanbanRequest): Promise<KanbanBoard> => this.guard(input.operationId, boardId, `execute:${input.command.type}`, async () => {\n const request = structuredClone(input); identity(request.operationId);\n const state = await this.readState(boardId);\n await this.authorize(state.board, request.command.type, request.command);\n requireValue(state.board.deletedAt === undefined, 'BOARD_DELETED');\n if (request.command.type === 'delete-board') await this.options.verifyDeletion?.(structuredClone(state.board));\n await this.verifyRelease(state.board, request.command);\n const verifyStage = request.command.type === 'observe-execution' && request.command.outcome === 'succeeded' ? 'observe'\n : request.command.type === 'accept-execution' && request.command.accept ? 'accept' : undefined;\n if (verifyStage && 'dispatchId' in request.command) {\n const dispatch = state.workflow?.dispatches[request.command.dispatchId]; requireValue(dispatch, 'DISPATCH_NOT_FOUND');\n const outputs = request.command.type === 'observe-execution' ? request.command.outputs : dispatch.outputs;\n if (outputs?.length) requireValue(await this.options.verifyOutputs?.({stage: verifyStage, board: state.board, itemId: dispatch.itemId,\n dispatchId: dispatch.id, outputs: structuredClone(outputs)}), 'OUTPUT_VERIFICATION_REQUIRED');\n }\n const restore = request.command.type === 'restore-item' ? await this.options.store.archived(boardId, request.command.itemId) : undefined;\n const result = await this.options.store.update(boardId, request.operationId, JSON.stringify({ actor: this.actor, request }), current => {\n requireValue(current && current.board.revision === state.board.revision, 'REVISION_CONFLICT');\n requireValue(current.board.revision === request.expectedRevision, 'REVISION_CONFLICT');\n if (restore) current.restore = restore;\n return reduce(current, request.command, this.actor, request.operationId, this.now(), this.id());\n });\n await this.publishNotifications(boardId, request.operationId);\n return structuredClone(result.board);\n });\n events = (boardId: string, after = 0, limit = 100) => this.guard(this.id(), boardId, 'events', async () => {\n requireValue(Number.isSafeInteger(after) && after >= 0 && Number.isSafeInteger(limit) && limit > 0 && limit <= 500, 'INVALID_CURSOR');\n const {state} = await this.readView(boardId);\n return this.options.store.events(boardId, after, limit, state.sequence);\n });\n query = (boardId: string, query?: KanbanItemQuery) => this.guard(this.id(), boardId, 'query', async () => {const view = await this.readView(boardId); return structuredClone(queryItems(view.state, query, [...view.items, ...(view.state.archiveIndex ?? [])], this.now()));});\n overview = (boardId: string) => this.guard(this.id(), boardId, 'overview', async () => {const view = await this.readView(boardId); return overview(view.state, this.now(), view.items);});\n item = (boardId: string, itemId: string) => this.guard(this.id(), boardId, 'item', async () => {\n identity(itemId); const state = await this.readState(boardId), item = state.board.items.find(i => i.id === itemId);\n if (item) return {item: structuredClone(item),task:projectKanbanTask(item,state.workflow,this.now(),[...state.board.items,...state.archiveIndex??[]])};\n requireValue(state.archiveIndex?.some(i => i.id === itemId), 'ITEM_NOT_FOUND');\n const record = await this.options.store.archived(boardId, itemId); requireValue(record, 'REVISION_CONFLICT');\n return {item: structuredClone(record.item), task:projectKanbanTask(record.item,state.workflow,this.now(),state.archiveIndex), archive: {archivedAt: record.archivedAt, reason: record.reason}};\n });\n related = (sessionId: string): Promise<KanbanBoard[]> => this.guard(this.id(), undefined, 'related', async () => {\n identity(sessionId); const result: KanbanBoard[] = [];\n for (const board of await this.list()) {\n const state = await this.readState(board.id);\n if (related(board).includes(sessionId) || state.records?.some(record => record.sources.some(source => source.sessionId === sessionId)) || state.archiveIndex?.some(i => i.sessionIds.includes(sessionId))) result.push(board);\n }\n return result;\n });\n scan = (): Promise<void> => this.guard(this.id(), undefined, 'scan', async () => {\n const errors: unknown[] = [];\n for (const board of await this.list()) {\n try { await this.execute(board.id, { operationId: this.id(), expectedRevision: board.revision, command: { type: 'scan' } }); }\n catch (error) {\n if (!(error instanceof KanbanError) || error.code !== 'REVISION_CONFLICT') errors.push(error);\n }\n }\n if (errors.length) throw new AggregateError(errors, 'KANBAN_SCAN_FAILED');\n });\n private async verifyRelease(board: KanbanBoard, command: KanbanRequest['command']): Promise<void> {\n if (command.type !== 'release-item') return;\n const item = board.items.find(i => i.id === command.itemId); requireValue(item?.owner && item.owner.token === command.token, 'OWNER_MISMATCH');\n const own = sameOwner(item.owner, this.actor), actor = principal(this.actor);\n const coordinator = board.members?.some(m => principalKey(m) === principalKey(actor) && m.roles?.includes('coordinator'));\n requireValue(own || coordinator, 'OWNER_MISMATCH');\n if (!(own && actor.kind === 'human')) requireValue(await this.options.verifyRelease?.({actor: this.actor, board: structuredClone(board), item: structuredClone(item)}), 'EXECUTION_NOT_SETTLED');\n }\n private async publishNotifications(boardId: string, operationId: string): Promise<void> {\n if (!this.options.onCommitted) return;\n const started = this.now();\n try {await this.options.onCommitted(boardId, this, this.now()); this.log(operationId, boardId, 'notify', started, 'success');}\n catch (error) {this.log(operationId, boardId, 'notify', started, 'failure', safeCode(error, 'NOTIFICATION_PROJECTION_FAILED'));}\n }\n private async readView(boardId: string) {\n identity(boardId);\n if (!this.options.store.view) return viewFromState(await this.readState(boardId));\n const view = await this.options.store.view(boardId); requireValue(view, 'BOARD_NOT_FOUND');\n await this.authorize(view.state.board, 'read'); return view;\n }\n private async readState(boardId: string): Promise<KanbanState> {\n identity(boardId); const state = await this.options.store.read(boardId); requireValue(state, 'BOARD_NOT_FOUND');\n await this.authorize(state.board, 'read'); return state;\n }\n private authorize(board: KanbanBoard, action: Parameters<KanbanModuleOptions['authorize']>[0]['action'], command?: KanbanRequest['command']) {\n return this.options.authorize({ actor: structuredClone(this.actor), board: structuredClone(board), action, command: structuredClone(command) });\n }\n private async guard<T>(operationId: string, boardId: string | undefined, stage: string, run: () => Promise<T>): Promise<T> {\n const start = this.now();\n if (this.stopping) {this.log(operationId,boardId,stage,start,'failure','SERVICE_STOPPING'); throw new KanbanError('SERVICE_STOPPING');}\n const operation = Promise.resolve().then(run); this.pending.add(operation);\n try { const result = await operation; this.log(operationId, boardId, stage, start, 'success'); return result; }\n catch (error) {\n this.log(operationId, boardId, stage, start, 'failure', safeCode(error, 'PORT_FAILURE')); throw error;\n } finally {this.pending.delete(operation);}\n }\n private log(operationId: string, boardId: string | undefined, stage: string, start: number, result: 'success' | 'failure', code?: string): void {\n try { this.options.log({ operationId, boardId, stage, result, code, durationMs: this.now() - start }); }\n catch { /* Diagnostics cannot undo a commit. */ }\n }\n}\n\nfunction safeCode(error: unknown, fallback: string): string {\n const code = (error as {code?: unknown})?.code;\n return typeof code === 'string' && /^[A-Z][A-Z0-9_]{0,79}$/.test(code) ? code : fallback;\n}\n"],"mappings":"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","names":["item","record","record","id"]}
@@ -1,16 +0,0 @@
1
- // src/ports.ts
2
- var KanbanError = class extends Error {
3
- constructor(code) {
4
- super(code);
5
- this.code = code;
6
- this.name = "KanbanError";
7
- }
8
- };
9
- var KanbanScanNotStartedError = class extends KanbanError {
10
- };
11
-
12
- export {
13
- KanbanError,
14
- KanbanScanNotStartedError
15
- };
16
- //# sourceMappingURL=chunk-G6FCDLDF.js.map
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/ports.ts"],"sourcesContent":["import type { KanbanActor, KanbanBoard, KanbanCommand, KanbanEvent, KanbanArchivedItem, KanbanItemSummary } from './contracts';\n\nexport interface KanbanState {\n workflow?: import('./contracts').KanbanWorkflowState;\n numbering?: {item: number; log: number; decision: number};\n presetVersions?: Record<string, number>;\n records?: import('./contracts').KanbanProjectRecord[];\n discovery?: import('./scan-ports').KanbanDiscoveryState;\n archiveIndex?: KanbanItemSummary[];\n archiveWrites?: Array<{id: string; value: KanbanArchivedItem | null}>;\n restore?: KanbanArchivedItem;\n schema: 1; board: KanbanBoard; sequence: number; events: KanbanEvent[]; escalations: string[];\n}\nexport interface KanbanReadView {\n /** Board metadata and summary indexes; no item/record bodies. */\n state: KanbanState;\n items: import('./contracts').KanbanItemSummary[];\n records: import('./contracts').KanbanRecordSummary[];\n}\nexport interface KanbanStore {\n boardId?(number: number): Promise<string | null>;\n view?(id: string): Promise<KanbanReadView | null>;\n ids(): Promise<string[]>;\n archived(boardId: string, itemId: string): Promise<KanbanArchivedItem | null>;\n events(id: string, after: number, limit: number, through: number): Promise<KanbanEvent[]>;\n read(id: string): Promise<KanbanState | null>;\n update(id: string, operationId: string, fingerprint: string,\n change: (state: KanbanState | null) => KanbanState): Promise<KanbanState>;\n}\nexport interface KanbanModuleOptions {\n /** Host supplies metadata within the authorized user's/project's session scope. */\n suggestions?(board: KanbanBoard, kind: import('./contracts').KanbanSuggestionKind, search: string, limit: number): Promise<import('./contracts').KanbanSuggestion[] | undefined>;\n verifyOutputs?(input: {stage?: 'observe' | 'accept'; board: KanbanBoard; itemId: string; dispatchId?: string; outputs: import('./contracts').KanbanArtifactRef[]}): Promise<boolean>;\n onCommitted?(boardId: string, service: import('./contracts').KanbanService, now: number): Promise<void>;\n store: KanbanStore;\n /** Trusted identity resolved by the host, never from command payloads. */\n actor: KanbanActor;\n /** Must validate project access, delegated authority and session registration. */\n authorize(input: { actor: KanbanActor; board: KanbanBoard; action: 'create' | 'read' | 'install-content' | KanbanCommand['type']; command?: KanbanCommand }): Promise<void>;\n /** Confirm an automated owner has settled before releasing responsibility. */\n verifyDeletion?(board: KanbanBoard): Promise<void>;\n verifyRelease?(input: {actor: KanbanActor; board: KanbanBoard; item: import('./contracts').KanbanItem}): Promise<boolean>;\n now?: () => number;\n id?: () => string;\n log(event: { operationId: string; boardId?: string; sessionId?: string; stage: string; result: 'success' | 'failure'; code?: string; durationMs: number }): void;\n}\nexport class KanbanError extends Error {\n constructor(readonly code: string) { super(code); this.name = 'KanbanError'; }\n}\n\nexport class KanbanScanNotStartedError extends KanbanError {}\n"],"mappings":";AA8CO,IAAM,cAAN,cAA0B,MAAM;AAAA,EACnC,YAAqB,MAAc;AAAE,UAAM,IAAI;AAA1B;AAA6B,SAAK,OAAO;AAAA,EAAe;AACjF;AAEO,IAAM,4BAAN,cAAwC,YAAY;AAAC;","names":[]}
@@ -1 +0,0 @@
1
- {"version":3,"sources":["/home/li/share/prj/x1/release/local-libraries/work/1ca933a0-6fe7-4e9c-b13b-76d7f318e0fb/source/libraries/kanban/dist/chunk-IUI5CI2S.cjs","../src/references.ts","../src/suggestions.ts","../src/queries.ts","../src/module.ts"],"names":["item","record"],"mappings":"AAAA;AACE;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACF,wDAA6B;AAC7B;AACE;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACF,wDAA6B;AAC7B;AACE;AACF,wDAA6B;AAC7B;AACE;AACF,wDAA6B;AAC7B;AACE;AACF,wDAA6B;AAC7B;AACE;AACF,wDAA6B;AAC7B;AACE;AACF,wDAA6B;AAC7B;AACA;AClCA,MAAA,SAAsB,gBAAA,CAAiB,SAAA,EAAmB,KAAA,EAAoB,IAAA,EAA+E;AACzJ,EAAA,4CAAA,OAAoB,UAAA,IAAc,SAAA,GAAY,SAAA,CAAU,OAAA,GAAU,GAAA,EAAK,mBAAmB,CAAA;AAC1F,EAAA,MAAM,MAAA,EAAQ,qDAAA,CAAsD,IAAA,CAAK,SAAA,CAAU,IAAA,CAAK,CAAC,CAAA;AACzF,EAAA,4CAAA,MAAa,GAAS,CAAC,KAAA,CAAM,CAAC,CAAA,EAAG,KAAA,CAAM,CAAC,CAAA,EAAG,KAAA,CAAM,CAAC,CAAC,CAAA,CAAE,KAAA,CAAM,CAAA,KAAA,EAAA,GAAS,MAAA,IAAU,KAAA,EAAA,GAAa,MAAA,CAAO,aAAA,CAAc,MAAA,CAAO,KAAK,CAAC,CAAC,CAAA,EAAG,mBAAmB,CAAA;AACpJ,EAAA,MAAM,GAAA,EAAK,sBAAM,KAAA,mBAAM,OAAA,0BAAA,CAAU,MAAA,CAAO,KAAA,CAAM,CAAC,CAAC,CAAC,GAAA;AAAG,EAAA,4CAAA,EAAa,EAAI,qBAAqB,CAAA;AAC1F,EAAA,MAAM,KAAA,EAAO,MAAM,IAAA,CAAK,EAAE,CAAA,EAAG,MAAA,EAAQ,IAAA,CAAK,KAAA,CAAM,KAAA;AAChD,EAAA,4CAAA,KAAa,CAAM,OAAA,IAAW,MAAA,CAAO,KAAA,CAAM,CAAC,CAAC,CAAA,EAAG,mBAAmB,CAAA;AACnE,EAAA,MAAM,OAAA,EAAgC,EAAC,OAAA,EAAS,EAAA,EAAI,KAAA,EAAO,KAAA,CAAM,KAAA,EAAO,SAAA,EAAW,+CAAA,KAAqB,EAAC,CAAA;AACzG,EAAA,GAAA,CAAI,KAAA,CAAM,CAAC,CAAA,EAAG;AACV,IAAA,MAAM,KAAA,EAAO,CAAC,GAAG,IAAA,CAAK,KAAA,EAAO,oBAAI,IAAA,CAAK,KAAA,CAAM,YAAA,UAAgB,CAAC,GAAE,CAAA,CAAE,IAAA,CAAK,CAAAA,KAAAA,EAAAA,GAAQA,KAAAA,CAAK,OAAA,IAAW,MAAA,CAAO,KAAA,CAAM,CAAC,CAAC,CAAC,CAAA;AAC9G,IAAA,4CAAA,IAAa,EAAM,qBAAqB,CAAA;AAAG,IAAA,MAAA,CAAO,OAAA,EAAS,IAAA,CAAK,EAAA;AAAI,IAAA,MAAA,CAAO,UAAA,EAAY,+CAAA,KAAgB,EAAO,IAAI,CAAA;AAAA,EACtH,EAAA,KAAA,GAAA,CAAW,KAAA,CAAM,CAAC,CAAA,EAAG;AACjB,IAAA,MAAM,OAAA,EAAS,IAAA,CAAK,OAAA,CAAQ,IAAA,CAAK,CAAAC,OAAAA,EAAAA,GAAUA,OAAAA,CAAO,KAAA,IAAA,CAAU,KAAA,CAAM,CAAC,CAAA,CAAE,WAAA,CAAY,EAAA,IAAM,IAAA,EAAM,MAAA,EAAQ,UAAA,EAAA,GAAeA,OAAAA,CAAO,OAAA,IAAW,MAAA,CAAO,KAAA,CAAM,CAAC,CAAC,CAAC,CAAA;AACtJ,IAAA,4CAAA,MAAa,EAAQ,qBAAqB,CAAA;AAAG,IAAA,MAAA,CAAO,SAAA,EAAW,MAAA,CAAO,EAAA;AAAI,IAAA,MAAA,CAAO,UAAA,EAAY,+CAAA,KAAgB,EAAO,MAAM,CAAA;AAAA,EAC9H;AACA,EAAA,OAAO,MAAA;AACX;ADyCA;AACA;AEtDO,SAAS,uBAAA,CAAwB,KAAA,EAAsC;AAC1E,EAAA,4CAAA,MAAa,GAAS,CAAC,MAAA,EAAQ,QAAA,EAAU,YAAA,EAAc,MAAA,EAAQ,WAAA,EAAa,UAAA,EAAY,SAAS,CAAA,CAAE,QAAA,CAAS,KAAA,CAAM,IAAI,CAAA,EAAG,yBAAyB,CAAA;AAClJ,EAAA,4CAAA,KAAa,CAAM,OAAA,IAAW,KAAA,EAAA,GAAa,OAAO,KAAA,CAAM,OAAA,IAAW,SAAA,GAAY,KAAA,CAAM,MAAA,CAAO,OAAA,GAAU,GAAA,EAAK,gBAAgB,CAAA;AAC3H,EAAA,MAAM,MAAA,mBAAQ,KAAA,CAAM,KAAA,UAAS,IAAA;AAAI,EAAA,4CAAA,MAAa,CAAO,aAAA,CAAc,KAAK,EAAA,GAAK,MAAA,EAAQ,EAAA,GAAK,MAAA,GAAS,EAAA,EAAI,eAAe,CAAA;AACtH,EAAA,GAAA,CAAI,KAAA,CAAM,cAAA,IAAkB,KAAA,CAAA,EAAW,wCAAA,KAAS,CAAM,aAAa,CAAA;AACnE,EAAA,GAAA,CAAI,KAAA,CAAM,WAAA,IAAe,KAAA,CAAA,EAAW;AAAC,IAAA,4CAAA,KAAa,CAAM,OAAA,CAAQ,KAAA,CAAM,UAAU,EAAA,GAAK,KAAA,CAAM,UAAA,CAAW,OAAA,GAAU,GAAA,EAAK,gBAAgB,CAAA;AAAG,IAAA,KAAA,CAAM,UAAA,CAAW,OAAA,CAAQ,0BAAQ,CAAA;AAAA,EAAE;AAC3K,EAAA,GAAA,CAAI,KAAA,CAAM,UAAA,IAAc,KAAA,CAAA,EAAW,wCAAA,KAAS,CAAM,SAAS,CAAA;AAC3D,EAAA,OAAO,KAAA;AACX;AACO,SAAS,cAAA,CAAe,QAAA,EAAkB,IAAA,EAA0B,KAAA,EAAoD;AAC3H,EAAA,MAAM,MAAA,EAAQ,uBAAA,CAAwB,KAAK,CAAA,EAAG,OAAA,mCAAS,KAAA,qBAAM,MAAA,6BAAQ,IAAA,mBAAK,CAAA,qBAAE,iBAAA,mBAAkB,GAAA,UAAK,IAAA;AACnG,EAAA,MAAM,QAAA,EAAU,IAAA,CAAK,MAAA,CAAO,CAAA,GAAA,EAAA,GAAO,iBAAC,KAAA,qBAAM,UAAA,6BAAY,QAAA,qBAAS,GAAA,CAAI,EAAE,GAAC,CAAA,CAAE,MAAA,CAAO,CAAA,GAAA,EAAA,GAAO,CAAA,EAAA;AAED,EAAA;AACzF;AACgG;AACwC;AACvG,EAAA;AAC4B,EAAA;AACkD,IAAA;AAClB,IAAA;AACzF,EAAA;AAEY,EAAA;AACkB,EAAA;AACN,IAAA;AAAiD,MAAA;AAA2C,MAAA;AAC9D,MAAA;AAAE,IAAA;AAC+B,IAAA;AACvF,EAAA;AACuF,EAAA;AACD,EAAA;AACG,EAAA;AAG7D,IAAA;AAAgB,IAAA;AAAoB,IAAA;AAAsC,IAAA;AACN,IAAA;AAA+B,EAAA;AACxE,EAAA;AAC3D;AAC+F;AACjD,EAAA;AACiD,EAAA;AAChD,EAAA;AAC8C,EAAA;AAA2B,IAAA;AAAoB,IAAA;AAAE,EAAA;AACnI,EAAA;AACX;AFkE6F;AACA;AG/GuC;AACvF,EAAA;AACkD,EAAA;AACV,EAAA;AACkB,EAAA;AACR,EAAA;AACH,EAAA;AACD,EAAA;AACL,EAAA;AAEtE,EAAA;AACA,EAAA;AAC0E,IAAA;AAC9E,IAAA;AACA,IAAA;AAA4B,MAAA;AAAU,IAAA;AAAqC,MAAA;AAAE,IAAA;AACF,IAAA;AACrB,IAAA;AACD,IAAA;AAA2C,IAAA;AACxG,EAAA;AAC4C,EAAA;AAC0C,EAAA;AACH,EAAA;AACI,IAAA;AAChF,EAAA;AACX;AACmE;AACuB,EAAA;AAC1F;AACuI;AACvE,EAAA;AACN,EAAA;AACuC,EAAA;AACV,EAAA;AACT,EAAA;AACY,EAAA;AAC/E,EAAA;AACX;AACsF;AAC/B,EAAA;AACxB,EAAA;AACe,EAAA;AACsC,EAAA;AACrC,EAAA;AAC6C,EAAA;AAC5F;AACkH;AACrC,EAAA;AAC1C,EAAA;AACxB,EAAA;AAAuB,IAAA;AAAyB,IAAA;AAAgD,IAAA;AAAgD,IAAA;AAAsB,IAAA;AAC5H,IAAA;AAA2B,IAAA;AAA6B,IAAA;AACvD,IAAA;AAAwF,IAAA;AAClH,IAAA;AAAC,EAAA;AAC7B;AAEiI;AACjF,EAAA;AAC+B,EAAA;AACX,EAAA;AACjC,IAAA;AAAuC,IAAA;AAC9B,IAAA;AACjB,MAAA;AAAiF,MAAA;AACvF,MAAA;AAAmD,MAAA;AAAuD,MAAA;AAC/C,MAAA;AACzC,MAAA;AAAuC,MAAA;AACtE,IAAA;AACJ,EAAA;AACO,EAAA;AACX;AHkI6F;AACA;AI9LR;AAAiC,EAAA;AAAG;AAE7E;AAQmB,EAAA;AAA9B,IAAA;AACM,IAAA;AAA6B,IAAA;AACnB,IAAA;AAC7C,EAAA;AAVmB,iBAAA;AACkC,kBAAA;AACtB,EAAA;AAAiB,IAAA;AAAgD,IAAA;AAAE,EAAA;AACnE,EAAA;AAAoB,IAAA;AAAE,EAAA;AACpC,EAAA;AACA,EAAA;AACA,EAAA;AAKsE,kBAAA;AACa,kBAAA;AACqC,kBAAA;AACjD,IAAA;AACE,IAAA;AACpC,IAAA;AACuC,IAAA;AAC9C,IAAA;AAC0C,IAAA;AACZ,IAAA;AAC5E,EAAA;AACqI,kBAAA;AAAyC,IAAA;AAAuE,IAAA;AAAG,EAAA;AACpJ,kBAAA;AAChF,IAAA;AAAwF,IAAA;AAClE,IAAA;AAAgC,IAAA;AAC1E,EAAA;AACmE,kBAAA;AACR,kBAAA;AAClB,IAAA;AAC0B,IAAA;AACwB,MAAA;AAChD,MAAA;AAC+C,MAAA;AACzC,QAAA;AAAU,QAAA;AACnD,MAAA;AACiC,MAAA;AACrC,IAAA;AACL,EAAA;AACuD,mBAAA;AAAc,IAAA;AAAG,IAAA;AAAS,IAAA;AACZ,IAAA;AAAC,EAAA;AACE,mBAAA;AACR,IAAA;AACX,IAAA;AACzC,MAAA;AAAoC,QAAA;AAAiD,QAAA;AAA6F,QAAA;AACxK,MAAA;AAA0E,QAAA;AAAM,MAAA;AAClG,IAAA;AAC6B,IAAA;AAChC,EAAA;AACyF,mBAAA;AACvD,IAAA;AACuB,IAAA;AAC9C,MAAA;AAAgD,QAAA;AAA4E,QAAA;AAClH,MAAA;AAA2E,QAAA;AAAO,MAAA;AACpG,IAAA;AACO,IAAA;AACV,EAAA;AACkI,mBAAA;AAC1F,IAAA;AAA+B,IAAA;AAC1B,IAAA;AAC6B,IAAA;AACN,IAAA;AACgB,IAAA;AAC5B,IAAA;AAC+B,IAAA;AAEhC,IAAA;AACsB,MAAA;AAA8C,MAAA;AACrC,MAAA;AACV,MAAA;AAAQ,QAAA;AAA0B,QAAA;AAAwB,QAAA;AACtG,QAAA;AAAoC,QAAA;AAAmC,MAAA;AACpG,IAAA;AACmF,IAAA;AACD,IAAA;AACL,MAAA;AACY,MAAA;AACtD,MAAA;AACsD,MAAA;AACxF,IAAA;AAC2D,IAAA;AACzB,IAAA;AACtC,EAAA;AAC8F,mBAAA;AACF,IAAA;AAC9C,IAAA;AAC2B,IAAA;AACzE,EAAA;AACyG,mBAAA;AAAyC,IAAA;AAAuF,IAAA;AAAoC,EAAA;AACvL,mBAAA;AAAyC,IAAA;AAAqD,IAAA;AAAG,EAAA;AACzF,mBAAA;AAC5E,IAAA;AAAqF,IAAA;AACpB,IAAA;AACH,IAAA;AACb,IAAA;AAA2C,IAAA;AACtB,IAAA;AACxF,EAAA;AACgH,mBAAA;AAC3F,IAAA;AAAkC,IAAA;AACb,IAAA;AACQ,MAAA;AACoC,MAAA;AACnF,IAAA;AACO,IAAA;AACV,EAAA;AACgF,mBAAA;AAClD,IAAA;AACY,IAAA;AAC/B,MAAA;AAAiF,QAAA;AACvE,MAAA;AACwE,QAAA;AACtF,MAAA;AACJ,IAAA;AACwE,IAAA;AAC3E,EAAA;AACiG,EAAA;AACzD,IAAA;AACqB,IAAA;AAAmF,IAAA;AAClE,IAAA;AACQ,IAAA;AAClC,IAAA;AACsC,IAAA;AAC3F,EAAA;AACwF,EAAA;AACrD,IAAA;AACN,IAAA;AACrB,IAAA;AAAyD,MAAA;AAA8D,MAAA;AAC7G,IAAA;AAA8E,MAAA;AAAmC,IAAA;AACnI,EAAA;AACwC,EAAA;AACpB,IAAA;AACgE,IAAA;AAC9B,IAAA;AAAuC,IAAA;AAC5C,IAAA;AAAU,IAAA;AAC3D,EAAA;AAC+D,EAAA;AAC3C,IAAA;AAAsD,IAAA;AAAwC,IAAA;AACtE,IAAA;AAAU,IAAA;AACtD,EAAA;AAC6I,EAAA;AAC9D,IAAA;AAC/E,EAAA;AAC2H,EAAA;AAChG,IAAA;AACJ,IAAA;AAAsE,MAAA;AAA2C,MAAA;AAAE,IAAA;AAC1F,IAAA;AAA6B,IAAA;AACrE,IAAA;AAAuB,MAAA;AAAiE,MAAA;AAAU,MAAA;AACxF,IAAA;AAC6E,MAAA;AAAS,MAAA;AAClG,IAAA;AAAsC,MAAA;AAAE,IAAA;AAC9C,EAAA;AACgJ,EAAA;AACxI,IAAA;AAAyF,MAAA;AACvF,IAAA;AAA0C,IAAA;AACpD,EAAA;AACJ;AAE4D;AACd,EAAA;AACsC,EAAA;AACpF;AJgQ6F;AACA;AACA;AACA","file":"/home/li/share/prj/x1/release/local-libraries/work/1ca933a0-6fe7-4e9c-b13b-76d7f318e0fb/source/libraries/kanban/dist/chunk-IUI5CI2S.cjs","sourcesContent":[null,"import {kanbanReference, type KanbanReferenceTarget} from './contracts';\nimport type {KanbanReadView, KanbanStore} from './ports';\nimport {requireValue} from './rules';\n\nexport async function resolveReference(reference: string, store: KanbanStore, read: (id: string) => Promise<KanbanReadView>): Promise<KanbanReferenceTarget> {\n requireValue(typeof reference === 'string' && reference.length <= 100, 'INVALID_REFERENCE');\n const match = /^KB-([1-9]\\d*)(?:#([1-9]\\d*)|\\/(L|D)-([1-9]\\d*))?$/i.exec(reference.trim());\n requireValue(match && [match[1], match[2], match[4]].every(value => value === undefined || Number.isSafeInteger(Number(value))), 'INVALID_REFERENCE');\n const id = await store.boardId?.(Number(match[1])); requireValue(id, 'REFERENCE_NOT_FOUND');\n const view = await read(id), board = view.state.board;\n requireValue(board.number === Number(match[1]), 'INVALID_NUMBERING');\n const target: KanbanReferenceTarget = {boardId: id, scope: board.scope, reference: kanbanReference(board)};\n if (match[2]) {\n const item = [...view.items, ...(view.state.archiveIndex ?? [])].find(item => item.number === Number(match[2]));\n requireValue(item, 'REFERENCE_NOT_FOUND'); target.itemId = item.id; target.reference = kanbanReference(board, item);\n } else if (match[3]) {\n const record = view.records.find(record => record.kind === (match[3].toUpperCase() === 'L' ? 'log' : 'decision') && record.number === Number(match[4]));\n requireValue(record, 'REFERENCE_NOT_FOUND'); target.recordId = record.id; target.reference = kanbanReference(board, record);\n }\n return target;\n}\n","import {kanbanReference} from './contracts';\nimport type {KanbanSuggestion, KanbanSuggestionPage, KanbanSuggestionQuery} from './contracts';\nimport type {KanbanState} from './ports';\nimport {recordSummary} from './project-records';\nimport {catalog, terminal} from './planning';\nimport {workType} from './configuration';\nimport {identity, requireValue} from './rules';\n\nexport function validateSuggestionQuery(query: KanbanSuggestionQuery): number {\n requireValue(query && ['item', 'parent', 'dependency', 'area', 'milestone', 'decision', 'session'].includes(query.kind), 'INVALID_SUGGESTION_KIND');\n requireValue(query.search === undefined || typeof query.search === 'string' && query.search.length <= 256, 'INVALID_FILTER');\n const limit = query.limit ?? 20; requireValue(Number.isSafeInteger(limit) && limit > 0 && limit <= 50, 'INVALID_LIMIT');\n if (query.excludeItemId !== undefined) identity(query.excludeItemId);\n if (query.excludeIds !== undefined) {requireValue(Array.isArray(query.excludeIds) && query.excludeIds.length <= 100, 'INVALID_FILTER'); query.excludeIds.forEach(identity);}\n if (query.childKind !== undefined) identity(query.childKind);\n return limit;\n}\nexport function suggestionPage(revision: number, rows: KanbanSuggestion[], query: KanbanSuggestionQuery): KanbanSuggestionPage {\n const limit = validateSuggestionQuery(query), search = query.search?.trim().toLocaleLowerCase() ?? '';\n const matched = rows.filter(row => !query.excludeIds?.includes(row.id)).filter(row => `${row.id} ${row.label} ${row.detail ?? ''}`.toLocaleLowerCase().includes(search))\n .sort((a, b) => score(a.label, search) - score(b.label, search) || a.label.localeCompare(b.label) || a.id.localeCompare(b.id));\n return {revision, items: matched.slice(0, limit).map(row => ({id: row.id, label: row.label.slice(0, 256), ...(row.detail ? {detail: row.detail.slice(0, 512)} : {}), ...(row.status ? {status: row.status} : {}), ...(row.archived !== undefined ? {archived: row.archived} : {})})), hasMore: matched.length > limit};\n}\nconst score = (label: string, query: string) => label.toLocaleLowerCase() === query ? 0 : label.toLocaleLowerCase().startsWith(query) ? 1 : 2;\nexport function suggestFromState(state: KanbanState, query: KanbanSuggestionQuery, items = catalog(state), records = (state.records ?? []).map(recordSummary)): KanbanSuggestionPage {\n validateSuggestionQuery(query);\n if (query.kind === 'area' || query.kind === 'milestone') {\n const names = [...new Set(items.map(item => item.planning[query.kind as 'area' | 'milestone']).filter((name): name is string => !!name))];\n return suggestionPage(state.board.revision, names.map(name => ({id: name, label: name})), query);\n }\n if (query.kind === 'decision') return suggestionPage(state.board.revision, records\n .filter(record => record.kind === 'decision' && record.status === 'confirmed').map(record => ({id: record.id, label: record.title, detail: kanbanReference(state.board, record)})), query);\n if (query.kind === 'session') {\n const ids = new Set([...state.board.participants.map(p => p.sessionId), ...items.flatMap(item => item.sessionIds),\n ...records.flatMap(record => record.sessionIds)]);\n return suggestionPage(state.board.revision, [...ids].map(id => ({id, label: id})), query);\n }\n const blocked = query.kind === 'dependency' && query.excludeItemId ? dependents(items, query.excludeItemId) : new Set<string>();\n const rank = query.kind === 'parent' ? workType(state.board, query.childKind ?? state.board.defaultWorkType ?? 'task').rank : undefined;\n const rows = items.filter(item => item.id !== query.excludeItemId && !blocked.has(item.id)\n && (query.kind !== 'dependency' || item.status !== 'cancelled')\n && (rank === undefined || item.archivedAt === undefined && !terminal(item) && workType(state.board, item.planning.kind).rank < rank))\n .map(item => ({id: item.id, label: item.title, status: item.status, archived: item.archivedAt !== undefined,\n detail: [kanbanReference(state.board, item), item.planning.area, item.planning.milestone].filter(Boolean).join(' · ')}));\n return suggestionPage(state.board.revision, rows, query);\n}\nfunction dependents(items: import('./contracts').KanbanItemSummary[], id: string): Set<string> {\n const reverse = new Map<string, string[]>();\n for (const item of items) for (const dependency of item.planning.dependencies) reverse.set(dependency, [...(reverse.get(dependency) ?? []), item.id]);\n const result = new Set([id]), pending = [id];\n while (pending.length) for (const next of reverse.get(pending.pop()!) ?? []) if (!result.has(next)) {result.add(next); pending.push(next);}\n return result;\n}\n","import {projectKanbanTask} from './contracts/task-projection';\nimport {kanbanReference} from './contracts';\nimport type {KanbanItemPage, KanbanItemQuery, KanbanItemSummary, KanbanOverview} from './contracts';\nimport type {KanbanState} from './ports';\nimport {requireValue} from './rules';\nimport {executable} from './configuration';\nimport {catalog, limits, summary, terminal} from './planning';\n\nexport function queryItems(state: KanbanState, query: KanbanItemQuery = {}, all = catalog(state), now = Date.now()): KanbanItemPage {\n const {cursor, limit = 50, ...filters} = query;\n requireValue(Number.isSafeInteger(limit) && limit >= 1 && limit <= 200, 'INVALID_PAGE_SIZE');\n requireValue(['ready', 'backlog', 'in-progress', 'review', 'closed', 'proposed', 'archive', 'all'].includes(query.view ?? 'ready'), 'INVALID_VIEW');\n for (const field of ['area', 'milestone', 'parentId', 'kind', 'sessionId', 'search'] as const) if (filters[field] !== undefined) requireValue(typeof filters[field] === 'string' && filters[field]!.length <= 256, 'INVALID_FILTER');\n if (filters.reference) requireValue(typeof filters.reference.system === 'string' && typeof filters.reference.id === 'string' && filters.reference.system.length <= 256 && filters.reference.id.length <= 256, 'INVALID_REFERENCE_FILTER');\n const fingerprint = JSON.stringify(Object.fromEntries(Object.entries({...filters, view: filters.view ?? 'ready'}).sort(([a], [b]) => a.localeCompare(b)))), revision = state.board.revision;\n all = all.map(item => ({...item, task: projectKanbanTask(item, state.workflow, now, all)}));\n const matches = all.filter(item => matchesQuery(item, filters, state.board)).sort(filters.view === 'archive'\n ? (a, b) => (b.archivedAt ?? 0) - (a.archivedAt ?? 0) || a.id.localeCompare(b.id) : order);\n let start = 0;\n if (cursor) {\n requireValue(typeof cursor === 'string' && cursor.length <= 4000, 'INVALID_CURSOR');\n let decoded: {revision: number; after: string; filter: string};\n try {decoded = JSON.parse(cursor);} catch {requireValue(false, 'INVALID_CURSOR');}\n requireValue(decoded && decoded.filter === fingerprint, 'CURSOR_SCOPE_MISMATCH');\n requireValue(decoded.revision === revision, 'CURSOR_STALE');\n start = matches.findIndex(i => i.id === decoded.after) + 1; requireValue(start > 0, 'INVALID_CURSOR');\n }\n const progress = progressByParent(state, all);\n const items = matches.slice(start, start + limit).map(item => ({...item, ...(progress.has(item.id) ? {progress: progress.get(item.id)} : {})}));\n return {revision, total: matches.length, items, ...(start + items.length < matches.length ? {\n nextCursor: JSON.stringify({revision, after: items.at(-1)!.id, filter: fingerprint}),\n } : {})};\n}\nfunction order(a: KanbanItemSummary, b: KanbanItemSummary): number {\n return a.planning.priority - b.planning.priority || a.createdAt - b.createdAt || a.id.localeCompare(b.id);\n}\nfunction matchesQuery(item: KanbanItemSummary, query: Omit<KanbanItemQuery, 'cursor' | 'limit'>, board: KanbanState['board']): boolean {\n if (query.phase && item.task?.phase !== query.phase) return false;\n if (!matchesView(item, query.view ?? 'ready')) return false;\n for (const field of ['area', 'milestone', 'parentId', 'kind'] as const) if (query[field] !== undefined && item.planning[field] !== query[field]) return false;\n if (query.reference && !item.externalRefs?.some(r => r.system === query.reference!.system && r.id === query.reference!.id)) return false;\n if (query.sessionId && !item.sessionIds.includes(query.sessionId)) return false;\n if (query.search && !`${kanbanReference(board, item)} ${item.id} ${item.title} ${item.planning.area ?? ''}`.toLowerCase().includes(query.search.toLowerCase())) return false;\n return true;\n}\nfunction matchesView(item: KanbanItemSummary, view: KanbanItemQuery['view']): boolean {\n if (view === 'archive') return item.archivedAt !== undefined;\n if (view === 'all') return true;\n if (item.archivedAt !== undefined) return false;\n if (view === 'in-progress') return item.status === 'claimed' || item.status === 'review';\n if (view === 'closed') return terminal(item);\n return item.status === ({ready: 'open', backlog: 'backlog', review: 'review', proposed: 'proposed'} as Record<string, string>)[view!];\n}\nexport function overview(state: KanbanState, now: number, items = state.board.items.map(summary)): KanbanOverview {\n const count = (status: string) => items.filter(i => i.status === status).length;\n const age = state.board.policy.backlogReviewMs;\n return {revision: state.board.revision, visible: items.length, active: items.filter(i => !terminal(i)).length, archived: state.archiveIndex?.length ?? 0, ready: count('open'),\n inProgress: count('claimed') + count('review'), backlog: count('backlog'), proposed: count('proposed'),\n closed: count('completed') + count('cancelled'), dueForReview: age ? items.filter(i => i.status === 'backlog' && now - i.updatedAt >= age).length : 0,\n limits: limits(state)};\n}\n\nfunction progressByParent(state: KanbanState, all: KanbanItemSummary[]): Map<string, NonNullable<KanbanItemSummary['progress']>> {\n const byId = new Map(all.map(i => [i.id, i]));\n const result = new Map<string, NonNullable<KanbanItemSummary['progress']>>();\n for (const item of all.filter(i => executable(state.board, i))) {\n let parent = item.planning.parentId; const seen = new Set<string>();\n while (parent && !seen.has(parent)) {\n seen.add(parent); const progress = result.get(parent) ?? {total: 0, completed: 0, cancelled: 0, inProgress: 0};\n progress.total++; if (item.status === 'completed') progress.completed++; if (item.status === 'cancelled') progress.cancelled++;\n if (item.status === 'claimed' || item.status === 'review') progress.inProgress++;\n result.set(parent, progress); parent = byId.get(parent)?.planning.parentId;\n }\n }\n return result;\n}\n","import {boardControlPhase} from './contracts/board-control';\nimport {projectKanbanTask} from './contracts/task-projection';\nimport {resolveReference} from './references';\nimport {suggestFromState, suggestionPage, validateSuggestionQuery} from './suggestions';\nimport {queryRecords} from './project-records';\nimport { randomUUID } from './utils';\nimport type { KanbanBoard, KanbanRequest, KanbanService, KanbanItemQuery, KanbanBoardInput } from './contracts';\nimport { KanbanError, type KanbanModuleOptions, type KanbanState } from './ports';\nimport { identity, requireValue } from './rules';\nimport {createBoardState} from './board';\nimport {normalizeActor, principal, principalKey, sameOwner} from './identity';\nimport {queryItems, overview} from './queries';\nimport {viewFromState} from './storage-codec';\nimport { reduce, related } from './reducer';\n\n/** Optional host-owned service; no timer or model calls are started implicitly. */\nexport function createKanbanModule(options: KanbanModuleOptions): KanbanModuleHandle { return new KanbanModule(options); }\nexport interface KanbanModuleHandle extends KanbanService {quiesce(): Promise<void>; dispose(): Promise<void>}\nclass KanbanModule implements KanbanService {\n private stopping = false;\n private readonly pending = new Set<Promise<unknown>>();\n async quiesce(): Promise<void> {this.stopping = true; await Promise.allSettled([...this.pending]);}\n async dispose(): Promise<void> {await this.quiesce();}\n private readonly now;\n private readonly id;\n private readonly actor;\n constructor(private readonly options: KanbanModuleOptions) {\n this.now = options.now ?? Date.now; this.id = options.id ?? randomUUID;\n this.actor = normalizeActor(options.actor);\n }\n workflow = (boardId: string) => this.guard(this.id(), boardId, 'workflow', async () => structuredClone((await this.readView(boardId)).state.workflow ?? {plans:{},dispatches:{},ready:[],completedPlans:[]}));\n resolve = (reference: string) => this.guard(this.id(), undefined, 'resolve', () => resolveReference(reference, this.options.store, id => this.readView(id)));\n suggest = (boardId: string, query: import('./contracts').KanbanSuggestionQuery) => this.guard(this.id(), boardId, 'suggest', async () => {\n const snapshot = structuredClone(query), limit = validateSuggestionQuery(snapshot), view = await this.readView(boardId), state = view.state;\n const suggestions = () => suggestFromState(state, snapshot, [...view.items, ...(state.archiveIndex ?? [])], view.records);\n if (!this.options.suggestions) return suggestions();\n const rows = await this.options.suggestions(structuredClone(state.board), snapshot.kind, snapshot.search?.trim() ?? '', limit + 1);\n if (rows === undefined) return suggestions();\n const known = suggestions().items.filter(row => !rows.some(entry => entry.id === row.id));\n return suggestionPage(state.board.revision, [...rows, ...known], snapshot);\n });\n records = (boardId: string, query?: import('./contracts').KanbanRecordQuery) => this.guard(this.id(), boardId, 'records', async () => {const view = await this.readView(boardId); return structuredClone(queryRecords(view.state, query, view.records));});\n record = (boardId: string, recordId: string) => this.guard(this.id(), boardId, 'record', async () => {\n identity(recordId); const record = (await this.readState(boardId)).records?.find(record => record.id === recordId);\n requireValue(record, 'RECORD_NOT_FOUND'); return structuredClone(record);\n });\n currentPrincipal = async () => structuredClone(principal(this.actor));\n create = (input: KanbanBoardInput): Promise<KanbanBoard> => {\n const snapshot = structuredClone(input);\n return this.guard(this.id(), snapshot.id, 'create', async () => {\n const initial = createBoardState(snapshot, this.actor, this.now()), board = initial.board;\n await this.authorize(board, 'create');\n const state = await this.options.store.update(board.id, `create:${board.id}`, JSON.stringify({ snapshot, actor: this.actor }), previous => {\n requireValue(!previous, 'BOARD_EXISTS'); return initial;\n });\n return structuredClone(state.board);\n });\n };\n read = (boardId: string): Promise<KanbanBoard> => this.guard(this.id(), boardId, 'read',\n async () => structuredClone((await this.readState(boardId)).board));\n catalog = () => this.guard(this.id(), undefined, 'catalog', async () => {\n const boards: import('./contracts').KanbanBoardSummary[] = [];\n for (const id of await this.options.store.ids()) {\n try {const view = await this.readView(id); if (view.state.board.deletedAt !== undefined) continue; boards.push({...view.state.board, executionPhase: boardControlPhase({...view.state.board, items: view.items}), items: view.items.map(({id, title, number}) => ({id, title, ...(number === undefined ? {} : {number})}))});}\n catch (error) {if (!(error instanceof KanbanError) || error.code !== 'FORBIDDEN') throw error;}\n }\n return structuredClone(boards);\n });\n list = (): Promise<KanbanBoard[]> => this.guard(this.id(), undefined, 'list', async () => {\n const boards: KanbanBoard[] = [];\n for (const boardId of await this.options.store.ids()) {\n try { const board = (await this.readState(boardId)).board; if (board.deletedAt === undefined) boards.push(structuredClone(board)); }\n catch (error) { if (!(error instanceof KanbanError) || error.code !== 'FORBIDDEN') throw error; }\n }\n return boards;\n });\n execute = (boardId: string, input: KanbanRequest): Promise<KanbanBoard> => this.guard(input.operationId, boardId, `execute:${input.command.type}`, async () => {\n const request = structuredClone(input); identity(request.operationId);\n const state = await this.readState(boardId);\n await this.authorize(state.board, request.command.type, request.command);\n requireValue(state.board.deletedAt === undefined, 'BOARD_DELETED');\n if (request.command.type === 'delete-board') await this.options.verifyDeletion?.(structuredClone(state.board));\n await this.verifyRelease(state.board, request.command);\n const verifyStage = request.command.type === 'observe-execution' && request.command.outcome === 'succeeded' ? 'observe'\n : request.command.type === 'accept-execution' && request.command.accept ? 'accept' : undefined;\n if (verifyStage && 'dispatchId' in request.command) {\n const dispatch = state.workflow?.dispatches[request.command.dispatchId]; requireValue(dispatch, 'DISPATCH_NOT_FOUND');\n const outputs = request.command.type === 'observe-execution' ? request.command.outputs : dispatch.outputs;\n if (outputs?.length) requireValue(await this.options.verifyOutputs?.({stage: verifyStage, board: state.board, itemId: dispatch.itemId,\n dispatchId: dispatch.id, outputs: structuredClone(outputs)}), 'OUTPUT_VERIFICATION_REQUIRED');\n }\n const restore = request.command.type === 'restore-item' ? await this.options.store.archived(boardId, request.command.itemId) : undefined;\n const result = await this.options.store.update(boardId, request.operationId, JSON.stringify({ actor: this.actor, request }), current => {\n requireValue(current && current.board.revision === state.board.revision, 'REVISION_CONFLICT');\n requireValue(current.board.revision === request.expectedRevision, 'REVISION_CONFLICT');\n if (restore) current.restore = restore;\n return reduce(current, request.command, this.actor, request.operationId, this.now(), this.id());\n });\n await this.publishNotifications(boardId, request.operationId);\n return structuredClone(result.board);\n });\n events = (boardId: string, after = 0, limit = 100) => this.guard(this.id(), boardId, 'events', async () => {\n requireValue(Number.isSafeInteger(after) && after >= 0 && Number.isSafeInteger(limit) && limit > 0 && limit <= 500, 'INVALID_CURSOR');\n const {state} = await this.readView(boardId);\n return this.options.store.events(boardId, after, limit, state.sequence);\n });\n query = (boardId: string, query?: KanbanItemQuery) => this.guard(this.id(), boardId, 'query', async () => {const view = await this.readView(boardId); return structuredClone(queryItems(view.state, query, [...view.items, ...(view.state.archiveIndex ?? [])], this.now()));});\n overview = (boardId: string) => this.guard(this.id(), boardId, 'overview', async () => {const view = await this.readView(boardId); return overview(view.state, this.now(), view.items);});\n item = (boardId: string, itemId: string) => this.guard(this.id(), boardId, 'item', async () => {\n identity(itemId); const state = await this.readState(boardId), item = state.board.items.find(i => i.id === itemId);\n if (item) return {item: structuredClone(item),task:projectKanbanTask(item,state.workflow,this.now(),[...state.board.items,...state.archiveIndex??[]])};\n requireValue(state.archiveIndex?.some(i => i.id === itemId), 'ITEM_NOT_FOUND');\n const record = await this.options.store.archived(boardId, itemId); requireValue(record, 'REVISION_CONFLICT');\n return {item: structuredClone(record.item), task:projectKanbanTask(record.item,state.workflow,this.now(),state.archiveIndex), archive: {archivedAt: record.archivedAt, reason: record.reason}};\n });\n related = (sessionId: string): Promise<KanbanBoard[]> => this.guard(this.id(), undefined, 'related', async () => {\n identity(sessionId); const result: KanbanBoard[] = [];\n for (const board of await this.list()) {\n const state = await this.readState(board.id);\n if (related(board).includes(sessionId) || state.records?.some(record => record.sources.some(source => source.sessionId === sessionId)) || state.archiveIndex?.some(i => i.sessionIds.includes(sessionId))) result.push(board);\n }\n return result;\n });\n scan = (): Promise<void> => this.guard(this.id(), undefined, 'scan', async () => {\n const errors: unknown[] = [];\n for (const board of await this.list()) {\n try { await this.execute(board.id, { operationId: this.id(), expectedRevision: board.revision, command: { type: 'scan' } }); }\n catch (error) {\n if (!(error instanceof KanbanError) || error.code !== 'REVISION_CONFLICT') errors.push(error);\n }\n }\n if (errors.length) throw new AggregateError(errors, 'KANBAN_SCAN_FAILED');\n });\n private async verifyRelease(board: KanbanBoard, command: KanbanRequest['command']): Promise<void> {\n if (command.type !== 'release-item') return;\n const item = board.items.find(i => i.id === command.itemId); requireValue(item?.owner && item.owner.token === command.token, 'OWNER_MISMATCH');\n const own = sameOwner(item.owner, this.actor), actor = principal(this.actor);\n const coordinator = board.members?.some(m => principalKey(m) === principalKey(actor) && m.roles?.includes('coordinator'));\n requireValue(own || coordinator, 'OWNER_MISMATCH');\n if (!(own && actor.kind === 'human')) requireValue(await this.options.verifyRelease?.({actor: this.actor, board: structuredClone(board), item: structuredClone(item)}), 'EXECUTION_NOT_SETTLED');\n }\n private async publishNotifications(boardId: string, operationId: string): Promise<void> {\n if (!this.options.onCommitted) return;\n const started = this.now();\n try {await this.options.onCommitted(boardId, this, this.now()); this.log(operationId, boardId, 'notify', started, 'success');}\n catch (error) {this.log(operationId, boardId, 'notify', started, 'failure', safeCode(error, 'NOTIFICATION_PROJECTION_FAILED'));}\n }\n private async readView(boardId: string) {\n identity(boardId);\n if (!this.options.store.view) return viewFromState(await this.readState(boardId));\n const view = await this.options.store.view(boardId); requireValue(view, 'BOARD_NOT_FOUND');\n await this.authorize(view.state.board, 'read'); return view;\n }\n private async readState(boardId: string): Promise<KanbanState> {\n identity(boardId); const state = await this.options.store.read(boardId); requireValue(state, 'BOARD_NOT_FOUND');\n await this.authorize(state.board, 'read'); return state;\n }\n private authorize(board: KanbanBoard, action: Parameters<KanbanModuleOptions['authorize']>[0]['action'], command?: KanbanRequest['command']) {\n return this.options.authorize({ actor: structuredClone(this.actor), board: structuredClone(board), action, command: structuredClone(command) });\n }\n private async guard<T>(operationId: string, boardId: string | undefined, stage: string, run: () => Promise<T>): Promise<T> {\n const start = this.now();\n if (this.stopping) {this.log(operationId,boardId,stage,start,'failure','SERVICE_STOPPING'); throw new KanbanError('SERVICE_STOPPING');}\n const operation = Promise.resolve().then(run); this.pending.add(operation);\n try { const result = await operation; this.log(operationId, boardId, stage, start, 'success'); return result; }\n catch (error) {\n this.log(operationId, boardId, stage, start, 'failure', safeCode(error, 'PORT_FAILURE')); throw error;\n } finally {this.pending.delete(operation);}\n }\n private log(operationId: string, boardId: string | undefined, stage: string, start: number, result: 'success' | 'failure', code?: string): void {\n try { this.options.log({ operationId, boardId, stage, result, code, durationMs: this.now() - start }); }\n catch { /* Diagnostics cannot undo a commit. */ }\n }\n}\n\nfunction safeCode(error: unknown, fallback: string): string {\n const code = (error as {code?: unknown})?.code;\n return typeof code === 'string' && /^[A-Z][A-Z0-9_]{0,79}$/.test(code) ? code : fallback;\n}\n"]}
@@ -1,71 +0,0 @@
1
- "use strict";Object.defineProperty(exports, "__esModule", {value: true}); function _nullishCoalesce(lhs, rhsFn) { if (lhs != null) { return lhs; } else { return rhsFn(); } } function _optionalChain(ops) { let lastAccessLHS = undefined; let value = ops[0]; let i = 1; while (i < ops.length) { const op = ops[i]; const fn = ops[i + 1]; i += 2; if ((op === 'optionalAccess' || op === 'optionalCall') && value == null) { return undefined; } if (op === 'access' || op === 'optionalAccess') { lastAccessLHS = value; value = fn(value); } else if (op === 'call' || op === 'optionalCall') { value = fn((...args) => value.call(lastAccessLHS, ...args)); lastAccessLHS = undefined; } } return value; }// src/contracts/task-projection.ts
2
- var TASK_START_DELAY_MS = 3e5;
3
- function taskStartAt(item) {
4
- return _nullishCoalesce(_optionalChain([item, 'access', _ => _.launch, 'optionalAccess', _2 => _2.startAt]), () => ( item.createdAt + TASK_START_DELAY_MS));
5
- }
6
- function taskEditing(item, now) {
7
- return (_nullishCoalesce(_optionalChain([item, 'access', _3 => _3.launch, 'optionalAccess', _4 => _4.editing, 'optionalAccess', _5 => _5.expiresAt]), () => ( 0))) > now;
8
- }
9
- function taskDue(item, now) {
10
- return !taskEditing(item, now) && !item.blocked && _optionalChain([item, 'access', _6 => _6.control, 'optionalAccess', _7 => _7.action]) !== "pause" && (_optionalChain([item, 'access', _8 => _8.launch, 'optionalAccess', _9 => _9.requestedAt]) !== void 0 || _optionalChain([item, 'access', _10 => _10.launch, 'optionalAccess', _11 => _11.mode]) !== "manual" && taskStartAt(item) <= now);
11
- }
12
- function projectKanbanTask(item, workflow, now = Date.now(), all = []) {
13
- const dispatch = Object.values(_nullishCoalesce(_optionalChain([workflow, 'optionalAccess', _12 => _12.dispatches]), () => ( {}))).filter((d) => d.itemId === item.id).sort((a, b) => b.attempt - a.attempt)[0];
14
- const fact = _nullishCoalesce(_nullishCoalesce(_nullishCoalesce(_nullishCoalesce(_nullishCoalesce(terminalFact(item), () => ( issueFact(item, dispatch))), () => ( failureFact(item, dispatch))), () => ( controlFact(item))), () => ( executionFact(item, dispatch))), () => ( waitingFact(item, now, all)));
15
- return {
16
- ...fact,
17
- startAt: taskStartAt(item),
18
- dispatchId: _optionalChain([dispatch, 'optionalAccess', _13 => _13.id]),
19
- sessionId: _optionalChain([dispatch, 'optionalAccess', _14 => _14.executionSessionId]),
20
- actions: [..._nullishCoalesce(fact.actions, () => ( [])), ...dispatch || _optionalChain([item, 'access', _15 => _15.launch, 'optionalAccess', _16 => _16.admittedAt]) !== void 0 || ["claimed", "review", "completed"].includes(item.status) ? ["fix"] : [], ..._optionalChain([dispatch, 'optionalAccess', _17 => _17.executionSessionId]) ? ["open-session"] : []]
21
- };
22
- }
23
- function terminalFact(item) {
24
- if (item.status === "completed" || item.status === "cancelled") return { phase: item.status };
25
- if (item.status === "review") return { phase: "review", actions: ["review"] };
26
- }
27
- function issueFact(item, dispatch) {
28
- const issue = _optionalChain([item, 'access', _18 => _18.issues, 'optionalAccess', _19 => _19.find, 'call', _20 => _20((i) => !i.resolvedBy && (!dispatch || i.attemptId === dispatch.id))]);
29
- if (issue) return { phase: issue.type === "clarification" ? "waiting-input" : "error", reason: issue.id, actions: ["resolve"] };
30
- }
31
- function controlFact(item) {
32
- const control = item.control;
33
- if (!control) return;
34
- const reason = control.code;
35
- if (control.state === "unknown") return { phase: "unknown", reason };
36
- if (control.state === "failed") return { phase: "error", reason, actions: ["resume"] };
37
- if (control.action === "pause") return { phase: control.state === "paused" ? "paused" : "pausing", reason, actions: ["resume"] };
38
- if (["requested", "accepted"].includes(control.state)) return { phase: "resuming", reason };
39
- }
40
- function failureFact(item, dispatch) {
41
- if (_optionalChain([dispatch, 'optionalAccess', _21 => _21.outcome]) === "unknown" || _optionalChain([item, 'access', _22 => _22.analysis, 'optionalAccess', _23 => _23.state]) === "unknown") return { phase: "unknown", reason: _nullishCoalesce(_optionalChain([dispatch, 'optionalAccess', _24 => _24.code]), () => ( _optionalChain([item, 'access', _25 => _25.analysis, 'optionalAccess', _26 => _26.code]))) };
42
- if (dispatch && ["failed", "cancelled", "rejected"].includes(dispatch.outcome)) return { phase: "error", reason: _nullishCoalesce(dispatch.code, () => ( dispatch.outcome)) };
43
- if (_optionalChain([item, 'access', _27 => _27.analysis, 'optionalAccess', _28 => _28.state]) === "failed") return { phase: "error", reason: item.analysis.code };
44
- }
45
- function executionFact(item, dispatch) {
46
- if (item.blocked) return { phase: item.blocked.reason === "WORKSPACE_INPUT_REQUIRED" ? "waiting-input" : "error", reason: item.blocked.reason };
47
- if (_optionalChain([dispatch, 'optionalAccess', _29 => _29.outcome]) === "prepared") return { phase: "preparing" };
48
- if (_optionalChain([dispatch, 'optionalAccess', _30 => _30.outcome]) === "running" || item.status === "claimed") return { phase: "running", actions: _optionalChain([dispatch, 'optionalAccess', _31 => _31.controlCapabilities, 'optionalAccess', _32 => _32.pause]) === "boundary" ? ["pause"] : [] };
49
- }
50
- function waitingFact(item, now, all) {
51
- const analysis = analysisFact(item);
52
- if (analysis) return analysis;
53
- const dependency = _optionalChain([item, 'access', _33 => _33.planning, 'optionalAccess', _34 => _34.dependencies, 'access', _35 => _35.find, 'call', _36 => _36((id) => _optionalChain([all, 'access', _37 => _37.find, 'call', _38 => _38((i) => i.id === id), 'optionalAccess', _39 => _39.status]) !== "completed")]);
54
- if (dependency) return { phase: "waiting-dependency", reason: "DEPENDENCY_UNFINISHED:" + dependency, actions: _optionalChain([item, 'access', _40 => _40.launch, 'optionalAccess', _41 => _41.admittedAt]) === void 0 ? ["edit", "cancel"] : [] };
55
- if (taskEditing(item, now)) return { phase: "waiting-start", reason: "EDIT_LEASE_ACTIVE" };
56
- if (_optionalChain([item, 'access', _42 => _42.launch, 'optionalAccess', _43 => _43.admittedAt]) !== void 0) return { phase: "queued" };
57
- return { phase: "waiting-start", reason: _optionalChain([item, 'access', _44 => _44.launch, 'optionalAccess', _45 => _45.mode]) === "manual" ? "MANUAL_START_REQUIRED" : taskDue(item, now) ? "ADMISSION_PENDING" : "START_AT_PENDING", actions: ["run", "edit", "pause", "cancel"] };
58
- }
59
- function analysisFact(item) {
60
- if (_optionalChain([item, 'access', _46 => _46.analysis, 'optionalAccess', _47 => _47.state]) === "clarification") return { phase: "waiting-input", reason: item.analysis.reason };
61
- if (_optionalChain([item, 'access', _48 => _48.analysis, 'optionalAccess', _49 => _49.state]) === "analyzing") return { phase: "analyzing" };
62
- }
63
-
64
-
65
-
66
-
67
-
68
-
69
-
70
- exports.TASK_START_DELAY_MS = TASK_START_DELAY_MS; exports.taskStartAt = taskStartAt; exports.taskEditing = taskEditing; exports.taskDue = taskDue; exports.projectKanbanTask = projectKanbanTask;
71
- //# sourceMappingURL=chunk-KYNYPKKH.cjs.map
@@ -1 +0,0 @@
1
- {"version":3,"sources":["/home/li/share/prj/x1/release/local-libraries/work/1ca933a0-6fe7-4e9c-b13b-76d7f318e0fb/source/libraries/kanban/dist/chunk-KYNYPKKH.cjs","../src/contracts/task-projection.ts"],"names":[],"mappings":"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","file":"/home/li/share/prj/x1/release/local-libraries/work/1ca933a0-6fe7-4e9c-b13b-76d7f318e0fb/source/libraries/kanban/dist/chunk-KYNYPKKH.cjs","sourcesContent":[null,"import type {KanbanDispatch,KanbanItem,KanbanItemSummary,KanbanWorkflowState,KanbanTaskProjection,KanbanTaskPhase} from './index';\n\ntype Item=Pick<KanbanItem,'id'|'status'|'createdAt'|'launch'|'analysis'|'control'|'issues'|'blocked'|'externalRefs'|'planning'>;\ntype Fact={phase:KanbanTaskPhase;reason?:string;actions?:KanbanTaskProjection['actions']};\nexport const TASK_START_DELAY_MS=300000;\nexport function taskStartAt(item:Pick<Item,'createdAt'|'launch'>):number {return item.launch?.startAt??item.createdAt+TASK_START_DELAY_MS;}\nexport function taskEditing(item:Pick<Item,'launch'>,now:number):boolean {return (item.launch?.editing?.expiresAt??0)>now;}\nexport function taskDue(item:Item,now:number):boolean {\n return !taskEditing(item,now)&&!item.blocked&&item.control?.action!=='pause'\n &&(item.launch?.requestedAt!==undefined||item.launch?.mode!=='manual'&&taskStartAt(item)<=now);\n}\n/** Ordered evidence projection shared by storage queries, CLI and UI. Session idle never proves acceptance. */\nexport function projectKanbanTask(item:Item,workflow?:KanbanWorkflowState,now=Date.now(),all:Array<Pick<KanbanItemSummary,'id'|'status'>>=[]):KanbanTaskProjection {\n const dispatch=Object.values(workflow?.dispatches??{}).filter(d=>d.itemId===item.id).sort((a,b)=>b.attempt-a.attempt)[0];\n const fact=terminalFact(item)??issueFact(item,dispatch)??failureFact(item,dispatch)??controlFact(item)??executionFact(item,dispatch)??waitingFact(item,now,all);\n return {...fact,startAt:taskStartAt(item),dispatchId:dispatch?.id,sessionId:dispatch?.executionSessionId,\n actions:[...fact.actions??[],...(dispatch||item.launch?.admittedAt!==undefined||['claimed','review','completed'].includes(item.status)?['fix' as const]:[]),...(dispatch?.executionSessionId?['open-session' as const]:[])]};\n}\nfunction terminalFact(item:Item):Fact|undefined {\n if(item.status==='completed'||item.status==='cancelled')return {phase:item.status};\n if(item.status==='review')return {phase:'review',actions:['review']};\n}\nfunction issueFact(item:Item,dispatch?:KanbanDispatch):Fact|undefined {\n const issue=item.issues?.find(i=>!i.resolvedBy&&(!dispatch||i.attemptId===dispatch.id));\n if(issue)return {phase:issue.type==='clarification'?'waiting-input':'error',reason:issue.id,actions:['resolve']};\n}\nfunction controlFact(item:Item):Fact|undefined {\n const control=item.control;if(!control)return;\n const reason=control.code;\n if(control.state==='unknown')return {phase:'unknown',reason};\n if(control.state==='failed')return {phase:'error',reason,actions:['resume']};\n if(control.action==='pause')return {phase:control.state==='paused'?'paused':'pausing',reason,actions:['resume']};\n if(['requested','accepted'].includes(control.state))return {phase:'resuming',reason};\n}\nfunction failureFact(item:Item,dispatch?:KanbanDispatch):Fact|undefined {\n if(dispatch?.outcome==='unknown'||item.analysis?.state==='unknown')return {phase:'unknown',reason:dispatch?.code??item.analysis?.code};\n if(dispatch&&['failed','cancelled','rejected'].includes(dispatch.outcome))return {phase:'error',reason:dispatch.code??dispatch.outcome};\n if(item.analysis?.state==='failed')return {phase:'error',reason:item.analysis.code};\n}\nfunction executionFact(item:Item,dispatch?:KanbanDispatch):Fact|undefined {\n if(item.blocked)return {phase:item.blocked.reason==='WORKSPACE_INPUT_REQUIRED'?'waiting-input':'error',reason:item.blocked.reason};\n if(dispatch?.outcome==='prepared')return {phase:'preparing'};\n if(dispatch?.outcome==='running'||item.status==='claimed')return {phase:'running',actions:dispatch?.controlCapabilities?.pause==='boundary'?['pause']:[]};\n}\nfunction waitingFact(item:Item,now:number,all:Array<Pick<KanbanItemSummary,'id'|'status'>>):Fact {\n const analysis=analysisFact(item);if(analysis)return analysis;\n const dependency=item.planning?.dependencies.find(id=>all.find(i=>i.id===id)?.status!=='completed');\n if(dependency)return {phase:'waiting-dependency',reason:'DEPENDENCY_UNFINISHED:'+dependency,actions:item.launch?.admittedAt===undefined?['edit','cancel']:[]};\n if(taskEditing(item,now))return {phase:'waiting-start',reason:'EDIT_LEASE_ACTIVE'};\n if(item.launch?.admittedAt!==undefined)return {phase:'queued'};\n return {phase:'waiting-start',reason:item.launch?.mode==='manual'?'MANUAL_START_REQUIRED':taskDue(item,now)?'ADMISSION_PENDING':'START_AT_PENDING',actions:['run','edit','pause','cancel']};\n}\nfunction analysisFact(item:Item):Fact|undefined {\n if(item.analysis?.state==='clarification')return {phase:'waiting-input',reason:item.analysis.reason};\n if(item.analysis?.state==='analyzing')return {phase:'analyzing'};\n}\n"]}