@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
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["/home/li/share/prj/x1/libraries/kanban/dist/chunk-AOHQCX7K.cjs","../src/contracts/board-control.ts","../src/contracts/task-projection.ts"],"names":["item"],"mappings":"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","file":"/home/li/share/prj/x1/libraries/kanban/dist/chunk-AOHQCX7K.cjs","sourcesContent":[null,"import type {KanbanBoard, KanbanItem} from './contracts';\n\nexport interface KanbanBoardControl {\n mode: 'automatic' | 'manual'; paused: boolean;\n controls: Record<string, string>;\n}\n/** Manual mode still honors an explicit per-task run request. */\nexport function boardAllowsStart(board: Pick<KanbanBoard, 'executionControl' | 'lifecycle'>, item?: Pick<KanbanItem, 'launch'>): boolean {\n return !board.lifecycle && !board.executionControl?.paused && (board.executionControl?.mode !== 'manual' || item?.launch?.requestedAt !== undefined);\n}\nexport function boardControlPhase(board: Pick<KanbanBoard, 'executionControl' | 'lifecycle'> & {items: Array<Pick<KanbanItem, 'id' | 'status' | 'control'>>}): 'automatic' | 'manual' | 'pausing' | 'paused' | 'resuming' | 'error' | 'cancelling' | 'cancelled' | 'waiting-deletion' {\n if (board.lifecycle) return board.lifecycle.intent === 'delete' ? 'waiting-deletion' : board.lifecycle.phase === 'ready' ? 'cancelled' : 'cancelling';\n const policy = board.executionControl;\n const controls = Object.entries(policy?.controls ?? {}).flatMap(([id, controlId]) => {\n const item = board.items.find(item => item.id === id);\n return item && !['completed', 'cancelled', 'review'].includes(item.status) && item.control?.id === controlId ? [item.control] : [];\n });\n if (controls.some(control => control?.state === 'failed' || control?.state === 'unknown')) return 'error';\n if (controls.some(control => control?.state === 'requested' || control?.state === 'accepted')) return policy?.paused ? 'pausing' : 'resuming';\n return policy?.paused ? 'paused' : policy?.mode ?? 'automatic';\n}\n","import type {KanbanDispatch,KanbanItem,KanbanItemSummary,KanbanWorkflowState,KanbanTaskProjection,KanbanTaskPhase} from './index';\n\ntype Item=Pick<KanbanItem,'deletedAt'|'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 || item.control.action === 'resume' && item.control.state === 'resumed')\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)??controlFact(item)??issueFact(item,dispatch)??failureFact(item,dispatch)??executionFact(item,dispatch)??waitingFact(item,now,all);\n const extra: KanbanTaskProjection['actions'] = [];\n if (!['completed','cancelled'].includes(item.status) && item.control?.action !== 'cancel') {\n if (!fact.actions?.includes('cancel')) extra.push('cancel');\n if (item.status !== 'review' && !fact.actions?.includes('pause') && !fact.actions?.includes('resume') && (dispatch?.controlCapabilities?.pause === 'boundary' || !dispatch)) extra.push('pause');\n }\n return {...fact,startAt:taskStartAt(item),dispatchId:dispatch?.id,sessionId:dispatch?.executionSessionId,\n actions:item.deletedAt === undefined ? [...fact.actions??[],...extra,...(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,actions:['delete']};\n if(item.control?.action==='cancel')return {phase:item.control.state==='failed'?'error':item.control.state==='unknown'?'unknown':'cancelling',reason:item.control.code,actions:item.control.state==='failed'?['cancel']:[]};\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"]}
@@ -9,7 +9,7 @@
9
9
 
10
10
 
11
11
 
12
- var _chunkL44TM4EEcjs = require('./chunk-L44TM4EE.cjs');
12
+ var _chunkEYTVC2H5cjs = require('./chunk-EYTVC2H5.cjs');
13
13
 
14
14
 
15
15
 
@@ -19,59 +19,55 @@ var _chunkL44TM4EEcjs = require('./chunk-L44TM4EE.cjs');
19
19
 
20
20
 
21
21
 
22
- var _chunk4KF7KUAIcjs = require('./chunk-4KF7KUAI.cjs');
22
+ var _chunkRBOER6EWcjs = require('./chunk-RBOER6EW.cjs');
23
23
 
24
24
 
25
- var _chunk2YFPV5GFcjs = require('./chunk-2YFPV5GF.cjs');
25
+ var _chunk7KDOTBRXcjs = require('./chunk-7KDOTBRX.cjs');
26
26
 
27
27
 
28
- var _chunkKYNYPKKHcjs = require('./chunk-KYNYPKKH.cjs');
29
28
 
29
+ var _chunkRSH6QSECcjs = require('./chunk-RSH6QSEC.cjs');
30
30
 
31
- var _chunkPSKQAFDFcjs = require('./chunk-PSKQAFDF.cjs');
32
31
 
33
32
 
34
- var _chunk6MN3H3YFcjs = require('./chunk-6MN3H3YF.cjs');
35
-
36
-
37
- var _chunkLSE6JG5Icjs = require('./chunk-LSE6JG5I.cjs');
33
+ var _chunkAOHQCX7Kcjs = require('./chunk-AOHQCX7K.cjs');
38
34
 
39
35
  // src/references.ts
40
36
  async function resolveReference(reference, store, read) {
41
- _chunk4KF7KUAIcjs.requireValue.call(void 0, typeof reference === "string" && reference.length <= 100, "INVALID_REFERENCE");
37
+ _chunkRBOER6EWcjs.requireValue.call(void 0, typeof reference === "string" && reference.length <= 100, "INVALID_REFERENCE");
42
38
  const match = /^KB-([1-9]\d*)(?:#([1-9]\d*)|\/(L|D)-([1-9]\d*))?$/i.exec(reference.trim());
43
- _chunk4KF7KUAIcjs.requireValue.call(void 0, match && [match[1], match[2], match[4]].every((value) => value === void 0 || Number.isSafeInteger(Number(value))), "INVALID_REFERENCE");
39
+ _chunkRBOER6EWcjs.requireValue.call(void 0, match && [match[1], match[2], match[4]].every((value) => value === void 0 || Number.isSafeInteger(Number(value))), "INVALID_REFERENCE");
44
40
  const id = await _optionalChain([store, 'access', _ => _.boardId, 'optionalCall', _2 => _2(Number(match[1]))]);
45
- _chunk4KF7KUAIcjs.requireValue.call(void 0, id, "REFERENCE_NOT_FOUND");
41
+ _chunkRBOER6EWcjs.requireValue.call(void 0, id, "REFERENCE_NOT_FOUND");
46
42
  const view = await read(id), board = view.state.board;
47
- _chunk4KF7KUAIcjs.requireValue.call(void 0, board.number === Number(match[1]), "INVALID_NUMBERING");
48
- const target = { boardId: id, scope: board.scope, reference: _chunkPSKQAFDFcjs.kanbanReference.call(void 0, board) };
43
+ _chunkRBOER6EWcjs.requireValue.call(void 0, board.number === Number(match[1]), "INVALID_NUMBERING");
44
+ const target = { boardId: id, scope: board.scope, reference: _chunk7KDOTBRXcjs.kanbanReference.call(void 0, board) };
49
45
  if (match[2]) {
50
46
  const item = [...view.items, ..._nullishCoalesce(view.state.archiveIndex, () => ( []))].find((item2) => item2.number === Number(match[2]));
51
- _chunk4KF7KUAIcjs.requireValue.call(void 0, item, "REFERENCE_NOT_FOUND");
47
+ _chunkRBOER6EWcjs.requireValue.call(void 0, item, "REFERENCE_NOT_FOUND");
52
48
  target.itemId = item.id;
53
- target.reference = _chunkPSKQAFDFcjs.kanbanReference.call(void 0, board, item);
49
+ target.reference = _chunk7KDOTBRXcjs.kanbanReference.call(void 0, board, item);
54
50
  } else if (match[3]) {
55
51
  const record = view.records.find((record2) => record2.kind === (match[3].toUpperCase() === "L" ? "log" : "decision") && record2.number === Number(match[4]));
56
- _chunk4KF7KUAIcjs.requireValue.call(void 0, record, "REFERENCE_NOT_FOUND");
52
+ _chunkRBOER6EWcjs.requireValue.call(void 0, record, "REFERENCE_NOT_FOUND");
57
53
  target.recordId = record.id;
58
- target.reference = _chunkPSKQAFDFcjs.kanbanReference.call(void 0, board, record);
54
+ target.reference = _chunk7KDOTBRXcjs.kanbanReference.call(void 0, board, record);
59
55
  }
60
56
  return target;
61
57
  }
62
58
 
63
59
  // src/suggestions.ts
64
60
  function validateSuggestionQuery(query) {
65
- _chunk4KF7KUAIcjs.requireValue.call(void 0, query && ["item", "parent", "dependency", "area", "milestone", "decision", "session"].includes(query.kind), "INVALID_SUGGESTION_KIND");
66
- _chunk4KF7KUAIcjs.requireValue.call(void 0, query.search === void 0 || typeof query.search === "string" && query.search.length <= 256, "INVALID_FILTER");
61
+ _chunkRBOER6EWcjs.requireValue.call(void 0, query && ["item", "parent", "dependency", "area", "milestone", "decision", "session"].includes(query.kind), "INVALID_SUGGESTION_KIND");
62
+ _chunkRBOER6EWcjs.requireValue.call(void 0, query.search === void 0 || typeof query.search === "string" && query.search.length <= 256, "INVALID_FILTER");
67
63
  const limit = _nullishCoalesce(query.limit, () => ( 20));
68
- _chunk4KF7KUAIcjs.requireValue.call(void 0, Number.isSafeInteger(limit) && limit > 0 && limit <= 50, "INVALID_LIMIT");
69
- if (query.excludeItemId !== void 0) _chunk4KF7KUAIcjs.identity.call(void 0, query.excludeItemId);
64
+ _chunkRBOER6EWcjs.requireValue.call(void 0, Number.isSafeInteger(limit) && limit > 0 && limit <= 50, "INVALID_LIMIT");
65
+ if (query.excludeItemId !== void 0) _chunkRBOER6EWcjs.identity.call(void 0, query.excludeItemId);
70
66
  if (query.excludeIds !== void 0) {
71
- _chunk4KF7KUAIcjs.requireValue.call(void 0, Array.isArray(query.excludeIds) && query.excludeIds.length <= 100, "INVALID_FILTER");
72
- query.excludeIds.forEach(_chunk4KF7KUAIcjs.identity);
67
+ _chunkRBOER6EWcjs.requireValue.call(void 0, Array.isArray(query.excludeIds) && query.excludeIds.length <= 100, "INVALID_FILTER");
68
+ query.excludeIds.forEach(_chunkRBOER6EWcjs.identity);
73
69
  }
74
- if (query.childKind !== void 0) _chunk4KF7KUAIcjs.identity.call(void 0, query.childKind);
70
+ if (query.childKind !== void 0) _chunkRBOER6EWcjs.identity.call(void 0, query.childKind);
75
71
  return limit;
76
72
  }
77
73
  function suggestionPage(revision, rows, query) {
@@ -80,13 +76,13 @@ function suggestionPage(revision, rows, query) {
80
76
  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 !== void 0 ? { archived: row.archived } : {} })), hasMore: matched.length > limit };
81
77
  }
82
78
  var score = (label, query) => label.toLocaleLowerCase() === query ? 0 : label.toLocaleLowerCase().startsWith(query) ? 1 : 2;
83
- function suggestFromState(state, query, items = _chunkL44TM4EEcjs.catalog.call(void 0, state), records = (_nullishCoalesce(state.records, () => ( []))).map(_chunkL44TM4EEcjs.recordSummary)) {
79
+ function suggestFromState(state, query, items = _chunkEYTVC2H5cjs.catalog.call(void 0, state), records = (_nullishCoalesce(state.records, () => ( []))).map(_chunkEYTVC2H5cjs.recordSummary)) {
84
80
  validateSuggestionQuery(query);
85
81
  if (query.kind === "area" || query.kind === "milestone") {
86
82
  const names = [...new Set(items.map((item) => item.planning[query.kind]).filter((name) => !!name))];
87
83
  return suggestionPage(state.board.revision, names.map((name) => ({ id: name, label: name })), query);
88
84
  }
89
- if (query.kind === "decision") return suggestionPage(state.board.revision, records.filter((record) => record.kind === "decision" && record.status === "confirmed").map((record) => ({ id: record.id, label: record.title, detail: _chunkPSKQAFDFcjs.kanbanReference.call(void 0, state.board, record) })), query);
85
+ if (query.kind === "decision") return suggestionPage(state.board.revision, records.filter((record) => record.kind === "decision" && record.status === "confirmed").map((record) => ({ id: record.id, label: record.title, detail: _chunk7KDOTBRXcjs.kanbanReference.call(void 0, state.board, record) })), query);
90
86
  if (query.kind === "session") {
91
87
  const ids = /* @__PURE__ */ new Set([
92
88
  ...state.board.participants.map((p) => p.sessionId),
@@ -96,13 +92,13 @@ function suggestFromState(state, query, items = _chunkL44TM4EEcjs.catalog.call(v
96
92
  return suggestionPage(state.board.revision, [...ids].map((id) => ({ id, label: id })), query);
97
93
  }
98
94
  const blocked = query.kind === "dependency" && query.excludeItemId ? dependents(items, query.excludeItemId) : /* @__PURE__ */ new Set();
99
- const rank = query.kind === "parent" ? _chunk4KF7KUAIcjs.workType.call(void 0, state.board, _nullishCoalesce(_nullishCoalesce(query.childKind, () => ( state.board.defaultWorkType)), () => ( "task"))).rank : void 0;
100
- const rows = items.filter((item) => item.id !== query.excludeItemId && !blocked.has(item.id) && (query.kind !== "dependency" || item.status !== "cancelled") && (rank === void 0 || item.archivedAt === void 0 && !_chunkL44TM4EEcjs.terminal.call(void 0, item) && _chunk4KF7KUAIcjs.workType.call(void 0, state.board, item.planning.kind).rank < rank)).map((item) => ({
95
+ const rank = query.kind === "parent" ? _chunkRBOER6EWcjs.workType.call(void 0, state.board, _nullishCoalesce(_nullishCoalesce(query.childKind, () => ( state.board.defaultWorkType)), () => ( "task"))).rank : void 0;
96
+ const rows = items.filter((item) => item.id !== query.excludeItemId && !blocked.has(item.id) && (query.kind !== "dependency" || item.status !== "cancelled") && (rank === void 0 || item.archivedAt === void 0 && !_chunkEYTVC2H5cjs.terminal.call(void 0, item) && _chunkRBOER6EWcjs.workType.call(void 0, state.board, item.planning.kind).rank < rank)).map((item) => ({
101
97
  id: item.id,
102
98
  label: item.title,
103
99
  status: item.status,
104
100
  archived: item.archivedAt !== void 0,
105
- detail: [_chunkPSKQAFDFcjs.kanbanReference.call(void 0, state.board, item), item.planning.area, item.planning.milestone].filter(Boolean).join(" \xB7 ")
101
+ detail: [_chunk7KDOTBRXcjs.kanbanReference.call(void 0, state.board, item), item.planning.area, item.planning.milestone].filter(Boolean).join(" \xB7 ")
106
102
  }));
107
103
  return suggestionPage(state.board.revision, rows, query);
108
104
  }
@@ -118,28 +114,28 @@ function dependents(items, id) {
118
114
  }
119
115
 
120
116
  // src/queries.ts
121
- function queryItems(state, query = {}, all = _chunkL44TM4EEcjs.catalog.call(void 0, state), now = Date.now()) {
117
+ function queryItems(state, query = {}, all = _chunkEYTVC2H5cjs.catalog.call(void 0, state), now = Date.now()) {
122
118
  const { cursor, limit = 50, ...filters } = query;
123
- _chunk4KF7KUAIcjs.requireValue.call(void 0, Number.isSafeInteger(limit) && limit >= 1 && limit <= 200, "INVALID_PAGE_SIZE");
124
- _chunk4KF7KUAIcjs.requireValue.call(void 0, ["ready", "backlog", "in-progress", "review", "closed", "proposed", "archive", "all"].includes(_nullishCoalesce(query.view, () => ( "ready"))), "INVALID_VIEW");
125
- for (const field of ["area", "milestone", "parentId", "kind", "sessionId", "search"]) if (filters[field] !== void 0) _chunk4KF7KUAIcjs.requireValue.call(void 0, typeof filters[field] === "string" && filters[field].length <= 256, "INVALID_FILTER");
126
- if (filters.reference) _chunk4KF7KUAIcjs.requireValue.call(void 0, typeof filters.reference.system === "string" && typeof filters.reference.id === "string" && filters.reference.system.length <= 256 && filters.reference.id.length <= 256, "INVALID_REFERENCE_FILTER");
119
+ _chunkRBOER6EWcjs.requireValue.call(void 0, Number.isSafeInteger(limit) && limit >= 1 && limit <= 200, "INVALID_PAGE_SIZE");
120
+ _chunkRBOER6EWcjs.requireValue.call(void 0, ["ready", "backlog", "in-progress", "review", "closed", "proposed", "archive", "all"].includes(_nullishCoalesce(query.view, () => ( "ready"))), "INVALID_VIEW");
121
+ for (const field of ["area", "milestone", "parentId", "kind", "sessionId", "search"]) if (filters[field] !== void 0) _chunkRBOER6EWcjs.requireValue.call(void 0, typeof filters[field] === "string" && filters[field].length <= 256, "INVALID_FILTER");
122
+ if (filters.reference) _chunkRBOER6EWcjs.requireValue.call(void 0, typeof filters.reference.system === "string" && typeof filters.reference.id === "string" && filters.reference.system.length <= 256 && filters.reference.id.length <= 256, "INVALID_REFERENCE_FILTER");
127
123
  const fingerprint = JSON.stringify(Object.fromEntries(Object.entries({ ...filters, view: _nullishCoalesce(filters.view, () => ( "ready")) }).sort(([a], [b]) => a.localeCompare(b)))), revision = state.board.revision;
128
- all = all.map((item) => ({ ...item, task: _chunkKYNYPKKHcjs.projectKanbanTask.call(void 0, item, state.workflow, now, all) }));
124
+ all = all.map((item) => ({ ...item, task: _chunkAOHQCX7Kcjs.projectKanbanTask.call(void 0, item, state.workflow, now, all) }));
129
125
  const matches = all.filter((item) => matchesQuery(item, filters, state.board)).sort(filters.view === "archive" ? (a, b) => (_nullishCoalesce(b.archivedAt, () => ( 0))) - (_nullishCoalesce(a.archivedAt, () => ( 0))) || a.id.localeCompare(b.id) : order);
130
126
  let start = 0;
131
127
  if (cursor) {
132
- _chunk4KF7KUAIcjs.requireValue.call(void 0, typeof cursor === "string" && cursor.length <= 4e3, "INVALID_CURSOR");
128
+ _chunkRBOER6EWcjs.requireValue.call(void 0, typeof cursor === "string" && cursor.length <= 4e3, "INVALID_CURSOR");
133
129
  let decoded;
134
130
  try {
135
131
  decoded = JSON.parse(cursor);
136
132
  } catch (e) {
137
- _chunk4KF7KUAIcjs.requireValue.call(void 0, false, "INVALID_CURSOR");
133
+ _chunkRBOER6EWcjs.requireValue.call(void 0, false, "INVALID_CURSOR");
138
134
  }
139
- _chunk4KF7KUAIcjs.requireValue.call(void 0, decoded && decoded.filter === fingerprint, "CURSOR_SCOPE_MISMATCH");
140
- _chunk4KF7KUAIcjs.requireValue.call(void 0, decoded.revision === revision, "CURSOR_STALE");
135
+ _chunkRBOER6EWcjs.requireValue.call(void 0, decoded && decoded.filter === fingerprint, "CURSOR_SCOPE_MISMATCH");
136
+ _chunkRBOER6EWcjs.requireValue.call(void 0, decoded.revision === revision, "CURSOR_STALE");
141
137
  start = matches.findIndex((i) => i.id === decoded.after) + 1;
142
- _chunk4KF7KUAIcjs.requireValue.call(void 0, start > 0, "INVALID_CURSOR");
138
+ _chunkRBOER6EWcjs.requireValue.call(void 0, start > 0, "INVALID_CURSOR");
143
139
  }
144
140
  const progress = progressByParent(state, all);
145
141
  const items = matches.slice(start, start + limit).map((item) => ({ ...item, ...progress.has(item.id) ? { progress: progress.get(item.id) } : {} }));
@@ -151,12 +147,13 @@ function order(a, b) {
151
147
  return a.planning.priority - b.planning.priority || a.createdAt - b.createdAt || a.id.localeCompare(b.id);
152
148
  }
153
149
  function matchesQuery(item, query, board) {
150
+ if (item.deletedAt !== void 0 && !query.includeDeleted) return false;
154
151
  if (query.phase && _optionalChain([item, 'access', _11 => _11.task, 'optionalAccess', _12 => _12.phase]) !== query.phase) return false;
155
152
  if (!matchesView(item, _nullishCoalesce(query.view, () => ( "ready")))) return false;
156
153
  for (const field of ["area", "milestone", "parentId", "kind"]) if (query[field] !== void 0 && item.planning[field] !== query[field]) return false;
157
154
  if (query.reference && !_optionalChain([item, 'access', _13 => _13.externalRefs, 'optionalAccess', _14 => _14.some, 'call', _15 => _15((r) => r.system === query.reference.system && r.id === query.reference.id)])) return false;
158
155
  if (query.sessionId && !item.sessionIds.includes(query.sessionId)) return false;
159
- if (query.search && !`${_chunkPSKQAFDFcjs.kanbanReference.call(void 0, board, item)} ${item.id} ${item.title} ${_nullishCoalesce(item.planning.area, () => ( ""))}`.toLowerCase().includes(query.search.toLowerCase())) return false;
156
+ if (query.search && !`${_chunk7KDOTBRXcjs.kanbanReference.call(void 0, board, item)} ${item.id} ${item.title} ${_nullishCoalesce(item.planning.area, () => ( ""))}`.toLowerCase().includes(query.search.toLowerCase())) return false;
160
157
  return true;
161
158
  }
162
159
  function matchesView(item, view) {
@@ -164,16 +161,17 @@ function matchesView(item, view) {
164
161
  if (view === "all") return true;
165
162
  if (item.archivedAt !== void 0) return false;
166
163
  if (view === "in-progress") return item.status === "claimed" || item.status === "review";
167
- if (view === "closed") return _chunkL44TM4EEcjs.terminal.call(void 0, item);
164
+ if (view === "closed") return _chunkEYTVC2H5cjs.terminal.call(void 0, item);
168
165
  return item.status === { ready: "open", backlog: "backlog", review: "review", proposed: "proposed" }[view];
169
166
  }
170
- function overview(state, now, items = state.board.items.map(_chunkL44TM4EEcjs.summary)) {
167
+ function overview(state, now, items = state.board.items.map(_chunkEYTVC2H5cjs.summary)) {
168
+ items = items.filter((item) => item.deletedAt === void 0);
171
169
  const count = (status) => items.filter((i) => i.status === status).length;
172
170
  const age = state.board.policy.backlogReviewMs;
173
171
  return {
174
172
  revision: state.board.revision,
175
173
  visible: items.length,
176
- active: items.filter((i) => !_chunkL44TM4EEcjs.terminal.call(void 0, i)).length,
174
+ active: items.filter((i) => !_chunkEYTVC2H5cjs.terminal.call(void 0, i)).length,
177
175
  archived: _nullishCoalesce(_optionalChain([state, 'access', _16 => _16.archiveIndex, 'optionalAccess', _17 => _17.length]), () => ( 0)),
178
176
  ready: count("open"),
179
177
  inProgress: count("claimed") + count("review"),
@@ -181,13 +179,13 @@ function overview(state, now, items = state.board.items.map(_chunkL44TM4EEcjs.su
181
179
  proposed: count("proposed"),
182
180
  closed: count("completed") + count("cancelled"),
183
181
  dueForReview: age ? items.filter((i) => i.status === "backlog" && now - i.updatedAt >= age).length : 0,
184
- limits: _chunkL44TM4EEcjs.limits.call(void 0, state)
182
+ limits: _chunkEYTVC2H5cjs.limits.call(void 0, state)
185
183
  };
186
184
  }
187
185
  function progressByParent(state, all) {
188
186
  const byId = new Map(all.map((i) => [i.id, i]));
189
187
  const result = /* @__PURE__ */ new Map();
190
- for (const item of all.filter((i) => _chunk4KF7KUAIcjs.executable.call(void 0, state.board, i))) {
188
+ for (const item of all.filter((i) => _chunkRBOER6EWcjs.executable.call(void 0, state.board, i))) {
191
189
  let parent = item.planning.parentId;
192
190
  const seen = /* @__PURE__ */ new Set();
193
191
  while (parent && !seen.has(parent)) {
@@ -212,8 +210,8 @@ var KanbanModule = (_class = class {
212
210
  constructor(options) {;_class.prototype.__init.call(this);_class.prototype.__init2.call(this);_class.prototype.__init3.call(this);_class.prototype.__init4.call(this);_class.prototype.__init5.call(this);_class.prototype.__init6.call(this);_class.prototype.__init7.call(this);_class.prototype.__init8.call(this);_class.prototype.__init9.call(this);_class.prototype.__init10.call(this);_class.prototype.__init11.call(this);_class.prototype.__init12.call(this);_class.prototype.__init13.call(this);_class.prototype.__init14.call(this);_class.prototype.__init15.call(this);_class.prototype.__init16.call(this);_class.prototype.__init17.call(this);_class.prototype.__init18.call(this);_class.prototype.__init19.call(this);
213
211
  this.options = options;
214
212
  this.now = _nullishCoalesce(options.now, () => ( Date.now));
215
- this.id = _nullishCoalesce(options.id, () => ( _chunk6MN3H3YFcjs.randomUUID));
216
- this.actor = _chunk4KF7KUAIcjs.normalizeActor.call(void 0, options.actor);
213
+ this.id = _nullishCoalesce(options.id, () => ( _chunkRSH6QSECcjs.randomUUID));
214
+ this.actor = _chunkRBOER6EWcjs.normalizeActor.call(void 0, options.actor);
217
215
  }
218
216
  __init() {this.stopping = false}
219
217
  __init2() {this.pending = /* @__PURE__ */ new Set()}
@@ -233,29 +231,29 @@ var KanbanModule = (_class = class {
233
231
  const snapshot = structuredClone(query), limit = validateSuggestionQuery(snapshot), view = await this.readView(boardId), state = view.state;
234
232
  const suggestions = () => suggestFromState(state, snapshot, [...view.items, ..._nullishCoalesce(state.archiveIndex, () => ( []))], view.records);
235
233
  if (!this.options.suggestions) return suggestions();
236
- const rows = await this.options.suggestions(structuredClone(state.board), snapshot.kind, _nullishCoalesce(_optionalChain([snapshot, 'access', _47 => _47.search, 'optionalAccess', _48 => _48.trim, 'call', _49 => _49()]), () => ( "")), limit + 1);
234
+ const rows = await this.options.suggestions(structuredClone(state.board), snapshot.kind, _nullishCoalesce(_optionalChain([snapshot, 'access', _50 => _50.search, 'optionalAccess', _51 => _51.trim, 'call', _52 => _52()]), () => ( "")), limit + 1);
237
235
  if (rows === void 0) return suggestions();
238
236
  const known = suggestions().items.filter((row) => !rows.some((entry) => entry.id === row.id));
239
237
  return suggestionPage(state.board.revision, [...rows, ...known], snapshot);
240
238
  })}
241
239
  __init6() {this.records = (boardId, query) => this.guard(this.id(), boardId, "records", async () => {
242
240
  const view = await this.readView(boardId);
243
- return structuredClone(_chunkL44TM4EEcjs.queryRecords.call(void 0, view.state, query, view.records));
241
+ return structuredClone(_chunkEYTVC2H5cjs.queryRecords.call(void 0, view.state, query, view.records));
244
242
  })}
245
243
  __init7() {this.record = (boardId, recordId) => this.guard(this.id(), boardId, "record", async () => {
246
- _chunk4KF7KUAIcjs.identity.call(void 0, recordId);
247
- const record = await _asyncOptionalChain([(await this.readState(boardId)), 'access', async _50 => _50.records, 'optionalAccess', async _51 => _51.find, 'call', async _52 => _52((record2) => record2.id === recordId)]);
248
- _chunk4KF7KUAIcjs.requireValue.call(void 0, record, "RECORD_NOT_FOUND");
244
+ _chunkRBOER6EWcjs.identity.call(void 0, recordId);
245
+ const record = await _asyncOptionalChain([(await this.readState(boardId)), 'access', async _53 => _53.records, 'optionalAccess', async _54 => _54.find, 'call', async _55 => _55((record2) => record2.id === recordId)]);
246
+ _chunkRBOER6EWcjs.requireValue.call(void 0, record, "RECORD_NOT_FOUND");
249
247
  return structuredClone(record);
250
248
  })}
251
- __init8() {this.currentPrincipal = async () => structuredClone(_chunk4KF7KUAIcjs.principal.call(void 0, this.actor))}
249
+ __init8() {this.currentPrincipal = async () => structuredClone(_chunkRBOER6EWcjs.principal.call(void 0, this.actor))}
252
250
  __init9() {this.create = (input) => {
253
251
  const snapshot = structuredClone(input);
254
252
  return this.guard(this.id(), snapshot.id, "create", async () => {
255
- const initial = _chunkL44TM4EEcjs.createBoardState.call(void 0, snapshot, this.actor, this.now()), board = initial.board;
253
+ const initial = _chunkEYTVC2H5cjs.createBoardState.call(void 0, snapshot, this.actor, this.now()), board = initial.board;
256
254
  await this.authorize(board, "create");
257
255
  const state = await this.options.store.update(board.id, `create:${board.id}`, JSON.stringify({ snapshot, actor: this.actor }), (previous) => {
258
- _chunk4KF7KUAIcjs.requireValue.call(void 0, !previous, "BOARD_EXISTS");
256
+ _chunkRBOER6EWcjs.requireValue.call(void 0, !previous, "BOARD_EXISTS");
259
257
  return initial;
260
258
  });
261
259
  return structuredClone(state.board);
@@ -273,9 +271,9 @@ var KanbanModule = (_class = class {
273
271
  try {
274
272
  const view = await this.readView(id);
275
273
  if (view.state.board.deletedAt !== void 0) continue;
276
- boards.push({ ...view.state.board, executionPhase: _chunkLSE6JG5Icjs.boardControlPhase.call(void 0, { ...view.state.board, items: view.items }), items: view.items.map(({ id: id2, title, number }) => ({ id: id2, title, ...number === void 0 ? {} : { number } })) });
274
+ boards.push({ ...view.state.board, executionPhase: _chunkAOHQCX7Kcjs.boardControlPhase.call(void 0, { ...view.state.board, items: view.items }), items: view.items.filter((item) => item.deletedAt === void 0).map(({ id: id2, title, number }) => ({ id: id2, title, ...number === void 0 ? {} : { number } })) });
277
275
  } catch (error) {
278
- if (!(error instanceof _chunk2YFPV5GFcjs.KanbanError) || error.code !== "FORBIDDEN") throw error;
276
+ if (!(error instanceof _chunkRSH6QSECcjs.KanbanError) || error.code !== "FORBIDDEN") throw error;
279
277
  }
280
278
  }
281
279
  return structuredClone(boards);
@@ -287,25 +285,26 @@ var KanbanModule = (_class = class {
287
285
  const board = (await this.readState(boardId)).board;
288
286
  if (board.deletedAt === void 0) boards.push(structuredClone(board));
289
287
  } catch (error) {
290
- if (!(error instanceof _chunk2YFPV5GFcjs.KanbanError) || error.code !== "FORBIDDEN") throw error;
288
+ if (!(error instanceof _chunkRSH6QSECcjs.KanbanError) || error.code !== "FORBIDDEN") throw error;
291
289
  }
292
290
  }
293
291
  return boards;
294
292
  })}
295
293
  __init13() {this.execute = (boardId, input) => this.guard(input.operationId, boardId, `execute:${input.command.type}`, async () => {
296
294
  const request = structuredClone(input);
297
- _chunk4KF7KUAIcjs.identity.call(void 0, request.operationId);
295
+ _chunkRBOER6EWcjs.identity.call(void 0, request.operationId);
298
296
  const state = await this.readState(boardId);
299
297
  await this.authorize(state.board, request.command.type, request.command);
300
- _chunk4KF7KUAIcjs.requireValue.call(void 0, state.board.deletedAt === void 0, "BOARD_DELETED");
301
- if (request.command.type === "delete-board") await _optionalChain([this, 'access', _53 => _53.options, 'access', _54 => _54.verifyDeletion, 'optionalCall', _55 => _55(structuredClone(state.board))]);
298
+ _chunkRBOER6EWcjs.requireValue.call(void 0, state.board.deletedAt === void 0, "BOARD_DELETED");
299
+ if (request.command.type === "delete-board") await _optionalChain([this, 'access', _56 => _56.options, 'access', _57 => _57.verifyDeletion, 'optionalCall', _58 => _58(structuredClone(state.board))]);
300
+ await _optionalChain([this, 'access', _59 => _59.options, 'access', _60 => _60.verifyLifecycle, 'optionalCall', _61 => _61(structuredClone(state.board), request.command)]);
302
301
  await this.verifyRelease(state.board, request.command);
303
302
  const verifyStage = request.command.type === "observe-execution" && request.command.outcome === "succeeded" ? "observe" : request.command.type === "accept-execution" && request.command.accept ? "accept" : void 0;
304
303
  if (verifyStage && "dispatchId" in request.command) {
305
- const dispatch = _optionalChain([state, 'access', _56 => _56.workflow, 'optionalAccess', _57 => _57.dispatches, 'access', _58 => _58[request.command.dispatchId]]);
306
- _chunk4KF7KUAIcjs.requireValue.call(void 0, dispatch, "DISPATCH_NOT_FOUND");
304
+ const dispatch = _optionalChain([state, 'access', _62 => _62.workflow, 'optionalAccess', _63 => _63.dispatches, 'access', _64 => _64[request.command.dispatchId]]);
305
+ _chunkRBOER6EWcjs.requireValue.call(void 0, dispatch, "DISPATCH_NOT_FOUND");
307
306
  const outputs = request.command.type === "observe-execution" ? request.command.outputs : dispatch.outputs;
308
- if (_optionalChain([outputs, 'optionalAccess', _59 => _59.length])) _chunk4KF7KUAIcjs.requireValue.call(void 0, await _optionalChain([this, 'access', _60 => _60.options, 'access', _61 => _61.verifyOutputs, 'optionalCall', _62 => _62({
307
+ if (_optionalChain([outputs, 'optionalAccess', _65 => _65.length])) _chunkRBOER6EWcjs.requireValue.call(void 0, await _optionalChain([this, 'access', _66 => _66.options, 'access', _67 => _67.verifyOutputs, 'optionalCall', _68 => _68({
309
308
  stage: verifyStage,
310
309
  board: state.board,
311
310
  itemId: dispatch.itemId,
@@ -315,16 +314,16 @@ var KanbanModule = (_class = class {
315
314
  }
316
315
  const restore = request.command.type === "restore-item" ? await this.options.store.archived(boardId, request.command.itemId) : void 0;
317
316
  const result = await this.options.store.update(boardId, request.operationId, JSON.stringify({ actor: this.actor, request }), (current) => {
318
- _chunk4KF7KUAIcjs.requireValue.call(void 0, current && current.board.revision === state.board.revision, "REVISION_CONFLICT");
319
- _chunk4KF7KUAIcjs.requireValue.call(void 0, current.board.revision === request.expectedRevision, "REVISION_CONFLICT");
317
+ _chunkRBOER6EWcjs.requireValue.call(void 0, current && current.board.revision === state.board.revision, "REVISION_CONFLICT");
318
+ _chunkRBOER6EWcjs.requireValue.call(void 0, current.board.revision === request.expectedRevision, "REVISION_CONFLICT");
320
319
  if (restore) current.restore = restore;
321
- return _chunkL44TM4EEcjs.reduce.call(void 0, current, request.command, this.actor, request.operationId, this.now(), this.id());
320
+ return _chunkEYTVC2H5cjs.reduce.call(void 0, current, request.command, this.actor, request.operationId, this.now(), this.id());
322
321
  });
323
322
  await this.publishNotifications(boardId, request.operationId);
324
323
  return structuredClone(result.board);
325
324
  })}
326
325
  __init14() {this.events = (boardId, after = 0, limit = 100) => this.guard(this.id(), boardId, "events", async () => {
327
- _chunk4KF7KUAIcjs.requireValue.call(void 0, Number.isSafeInteger(after) && after >= 0 && Number.isSafeInteger(limit) && limit > 0 && limit <= 500, "INVALID_CURSOR");
326
+ _chunkRBOER6EWcjs.requireValue.call(void 0, Number.isSafeInteger(after) && after >= 0 && Number.isSafeInteger(limit) && limit > 0 && limit <= 500, "INVALID_CURSOR");
328
327
  const { state } = await this.readView(boardId);
329
328
  return this.options.store.events(boardId, after, limit, state.sequence);
330
329
  })}
@@ -337,30 +336,35 @@ var KanbanModule = (_class = class {
337
336
  return overview(view.state, this.now(), view.items);
338
337
  })}
339
338
  __init17() {this.item = (boardId, itemId) => this.guard(this.id(), boardId, "item", async () => {
340
- _chunk4KF7KUAIcjs.identity.call(void 0, itemId);
339
+ _chunkRBOER6EWcjs.identity.call(void 0, itemId);
341
340
  const state = await this.readState(boardId), item = state.board.items.find((i) => i.id === itemId);
342
- if (item) return { item: structuredClone(item), task: _chunkKYNYPKKHcjs.projectKanbanTask.call(void 0, item, state.workflow, this.now(), [...state.board.items, ..._nullishCoalesce(state.archiveIndex, () => ( []))]) };
343
- _chunk4KF7KUAIcjs.requireValue.call(void 0, _optionalChain([state, 'access', _63 => _63.archiveIndex, 'optionalAccess', _64 => _64.some, 'call', _65 => _65((i) => i.id === itemId)]), "ITEM_NOT_FOUND");
341
+ if (item) return { item: structuredClone(item), task: _chunkAOHQCX7Kcjs.projectKanbanTask.call(void 0, item, state.workflow, this.now(), [...state.board.items, ..._nullishCoalesce(state.archiveIndex, () => ( []))]) };
342
+ _chunkRBOER6EWcjs.requireValue.call(void 0, _optionalChain([state, 'access', _69 => _69.archiveIndex, 'optionalAccess', _70 => _70.some, 'call', _71 => _71((i) => i.id === itemId)]), "ITEM_NOT_FOUND");
344
343
  const record = await this.options.store.archived(boardId, itemId);
345
- _chunk4KF7KUAIcjs.requireValue.call(void 0, record, "REVISION_CONFLICT");
346
- return { item: structuredClone(record.item), task: _chunkKYNYPKKHcjs.projectKanbanTask.call(void 0, record.item, state.workflow, this.now(), state.archiveIndex), archive: { archivedAt: record.archivedAt, reason: record.reason } };
344
+ _chunkRBOER6EWcjs.requireValue.call(void 0, record, "REVISION_CONFLICT");
345
+ return { item: structuredClone(record.item), task: _chunkAOHQCX7Kcjs.projectKanbanTask.call(void 0, record.item, state.workflow, this.now(), state.archiveIndex), archive: { archivedAt: record.archivedAt, reason: record.reason } };
347
346
  })}
348
347
  __init18() {this.related = (sessionId) => this.guard(this.id(), void 0, "related", async () => {
349
- _chunk4KF7KUAIcjs.identity.call(void 0, sessionId);
348
+ _chunkRBOER6EWcjs.identity.call(void 0, sessionId);
350
349
  const result = [];
351
350
  for (const board of await this.list()) {
352
351
  const state = await this.readState(board.id);
353
- if (_chunkL44TM4EEcjs.related.call(void 0, board).includes(sessionId) || _optionalChain([state, 'access', _66 => _66.records, 'optionalAccess', _67 => _67.some, 'call', _68 => _68((record) => record.sources.some((source) => source.sessionId === sessionId))]) || _optionalChain([state, 'access', _69 => _69.archiveIndex, 'optionalAccess', _70 => _70.some, 'call', _71 => _71((i) => i.sessionIds.includes(sessionId))])) result.push(board);
352
+ if (_chunkEYTVC2H5cjs.related.call(void 0, board).includes(sessionId) || _optionalChain([state, 'access', _72 => _72.records, 'optionalAccess', _73 => _73.some, 'call', _74 => _74((record) => record.sources.some((source) => source.sessionId === sessionId))]) || _optionalChain([state, 'access', _75 => _75.archiveIndex, 'optionalAccess', _76 => _76.some, 'call', _77 => _77((i) => i.sessionIds.includes(sessionId))])) result.push(board);
354
353
  }
355
354
  return result;
356
355
  })}
357
356
  __init19() {this.scan = () => this.guard(this.id(), void 0, "scan", async () => {
358
357
  const errors = [];
359
- for (const board of await this.list()) {
358
+ for (const id of await this.options.store.ids()) {
360
359
  try {
360
+ const board = (await this.readState(id)).board;
361
+ if (board.deletedAt !== void 0) {
362
+ await this.publishNotifications(id, this.id());
363
+ continue;
364
+ }
361
365
  await this.execute(board.id, { operationId: this.id(), expectedRevision: board.revision, command: { type: "scan" } });
362
366
  } catch (error) {
363
- if (!(error instanceof _chunk2YFPV5GFcjs.KanbanError) || error.code !== "REVISION_CONFLICT") errors.push(error);
367
+ if (!(error instanceof _chunkRSH6QSECcjs.KanbanError) || !["REVISION_CONFLICT", "FORBIDDEN"].includes(error.code)) errors.push(error);
364
368
  }
365
369
  }
366
370
  if (errors.length) throw new AggregateError(errors, "KANBAN_SCAN_FAILED");
@@ -368,11 +372,11 @@ var KanbanModule = (_class = class {
368
372
  async verifyRelease(board, command) {
369
373
  if (command.type !== "release-item") return;
370
374
  const item = board.items.find((i) => i.id === command.itemId);
371
- _chunk4KF7KUAIcjs.requireValue.call(void 0, _optionalChain([item, 'optionalAccess', _72 => _72.owner]) && item.owner.token === command.token, "OWNER_MISMATCH");
372
- const own = _chunk4KF7KUAIcjs.sameOwner.call(void 0, item.owner, this.actor), actor = _chunk4KF7KUAIcjs.principal.call(void 0, this.actor);
373
- const coordinator = _optionalChain([board, 'access', _73 => _73.members, 'optionalAccess', _74 => _74.some, 'call', _75 => _75((m) => _chunk4KF7KUAIcjs.principalKey.call(void 0, m) === _chunk4KF7KUAIcjs.principalKey.call(void 0, actor) && _optionalChain([m, 'access', _76 => _76.roles, 'optionalAccess', _77 => _77.includes, 'call', _78 => _78("coordinator")]))]);
374
- _chunk4KF7KUAIcjs.requireValue.call(void 0, own || coordinator, "OWNER_MISMATCH");
375
- if (!(own && actor.kind === "human")) _chunk4KF7KUAIcjs.requireValue.call(void 0, await _optionalChain([this, 'access', _79 => _79.options, 'access', _80 => _80.verifyRelease, 'optionalCall', _81 => _81({ actor: this.actor, board: structuredClone(board), item: structuredClone(item) })]), "EXECUTION_NOT_SETTLED");
375
+ _chunkRBOER6EWcjs.requireValue.call(void 0, _optionalChain([item, 'optionalAccess', _78 => _78.owner]) && item.owner.token === command.token, "OWNER_MISMATCH");
376
+ const own = _chunkRBOER6EWcjs.sameOwner.call(void 0, item.owner, this.actor), actor = _chunkRBOER6EWcjs.principal.call(void 0, this.actor);
377
+ const coordinator = _optionalChain([board, 'access', _79 => _79.members, 'optionalAccess', _80 => _80.some, 'call', _81 => _81((m) => _chunkRBOER6EWcjs.principalKey.call(void 0, m) === _chunkRBOER6EWcjs.principalKey.call(void 0, actor) && _optionalChain([m, 'access', _82 => _82.roles, 'optionalAccess', _83 => _83.includes, 'call', _84 => _84("coordinator")]))]);
378
+ _chunkRBOER6EWcjs.requireValue.call(void 0, own || coordinator, "OWNER_MISMATCH");
379
+ if (!(own && actor.kind === "human")) _chunkRBOER6EWcjs.requireValue.call(void 0, await _optionalChain([this, 'access', _85 => _85.options, 'access', _86 => _86.verifyRelease, 'optionalCall', _87 => _87({ actor: this.actor, board: structuredClone(board), item: structuredClone(item) })]), "EXECUTION_NOT_SETTLED");
376
380
  }
377
381
  async publishNotifications(boardId, operationId) {
378
382
  if (!this.options.onCommitted) return;
@@ -385,17 +389,17 @@ var KanbanModule = (_class = class {
385
389
  }
386
390
  }
387
391
  async readView(boardId) {
388
- _chunk4KF7KUAIcjs.identity.call(void 0, boardId);
389
- if (!this.options.store.view) return _chunkL44TM4EEcjs.viewFromState.call(void 0, await this.readState(boardId));
392
+ _chunkRBOER6EWcjs.identity.call(void 0, boardId);
393
+ if (!this.options.store.view) return _chunkEYTVC2H5cjs.viewFromState.call(void 0, await this.readState(boardId));
390
394
  const view = await this.options.store.view(boardId);
391
- _chunk4KF7KUAIcjs.requireValue.call(void 0, view, "BOARD_NOT_FOUND");
395
+ _chunkRBOER6EWcjs.requireValue.call(void 0, view, "BOARD_NOT_FOUND");
392
396
  await this.authorize(view.state.board, "read");
393
397
  return view;
394
398
  }
395
399
  async readState(boardId) {
396
- _chunk4KF7KUAIcjs.identity.call(void 0, boardId);
400
+ _chunkRBOER6EWcjs.identity.call(void 0, boardId);
397
401
  const state = await this.options.store.read(boardId);
398
- _chunk4KF7KUAIcjs.requireValue.call(void 0, state, "BOARD_NOT_FOUND");
402
+ _chunkRBOER6EWcjs.requireValue.call(void 0, state, "BOARD_NOT_FOUND");
399
403
  await this.authorize(state.board, "read");
400
404
  return state;
401
405
  }
@@ -406,7 +410,7 @@ var KanbanModule = (_class = class {
406
410
  const start = this.now();
407
411
  if (this.stopping) {
408
412
  this.log(operationId, boardId, stage, start, "failure", "SERVICE_STOPPING");
409
- throw new (0, _chunk2YFPV5GFcjs.KanbanError)("SERVICE_STOPPING");
413
+ throw new (0, _chunkRSH6QSECcjs.KanbanError)("SERVICE_STOPPING");
410
414
  }
411
415
  const operation = Promise.resolve().then(run);
412
416
  this.pending.add(operation);
@@ -429,11 +433,11 @@ var KanbanModule = (_class = class {
429
433
  }
430
434
  }, _class);
431
435
  function safeCode(error, fallback) {
432
- const code = _optionalChain([error, 'optionalAccess', _82 => _82.code]);
436
+ const code = _optionalChain([error, 'optionalAccess', _88 => _88.code]);
433
437
  return typeof code === "string" && /^[A-Z][A-Z0-9_]{0,79}$/.test(code) ? code : fallback;
434
438
  }
435
439
 
436
440
 
437
441
 
438
442
  exports.createKanbanModule = createKanbanModule;
439
- //# sourceMappingURL=chunk-IUI5CI2S.cjs.map
443
+ //# sourceMappingURL=chunk-DINLR6E6.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["/home/li/share/prj/x1/libraries/kanban/dist/chunk-DINLR6E6.cjs","../src/references.ts","../src/suggestions.ts","../src/queries.ts","../src/module.ts"],"names":["item","record"],"mappings":"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","file":"/home/li/share/prj/x1/libraries/kanban/dist/chunk-DINLR6E6.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 (item.deletedAt !== undefined && !query.includeDeleted) return false;\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 items = items.filter(item => item.deletedAt === undefined);\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.filter(item => item.deletedAt === undefined).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.options.verifyLifecycle?.(structuredClone(state.board), request.command);\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 id of await this.options.store.ids()) {\n try {\n const board = (await this.readState(id)).board;\n if (board.deletedAt !== undefined) {await this.publishNotifications(id,this.id()); continue;}\n await this.execute(board.id, { operationId: this.id(), expectedRevision: board.revision, command: { type: 'scan' } });\n }\n catch (error) {\n if (!(error instanceof KanbanError) || !['REVISION_CONFLICT','FORBIDDEN'].includes(error.code)) 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"]}