@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.
- package/LICENSE +674 -0
- package/README.md +73 -29
- package/dist/{activity-C6xDM-cg.d.cts → activity-BbC4sgKL.d.cts} +28 -2
- package/dist/{activity-Dw8DOw0L.d.ts → activity-Czlan5xW.d.ts} +28 -2
- package/dist/activity-module-DaO1Rry0.d.cts +22 -0
- package/dist/activity-module-T22wliZu.d.ts +22 -0
- package/dist/activity-ports-Dqxa86zT.d.cts +12 -0
- package/dist/activity-ports-cxfrelaL.d.ts +12 -0
- package/dist/activity.cjs +10 -282
- package/dist/activity.cjs.map +1 -1
- package/dist/activity.d.cts +8 -30
- package/dist/activity.d.ts +8 -30
- package/dist/activity.js +9 -281
- package/dist/activity.js.map +1 -1
- package/dist/{chunk-O4OGAAV4.js → chunk-3JYLJPE5.js} +29 -5
- package/dist/chunk-3JYLJPE5.js.map +1 -0
- package/dist/{chunk-ATUFFNLV.js → chunk-3LEIHB7Y.js} +5 -5
- package/dist/chunk-4XF6LQSU.cjs.map +1 -1
- package/dist/chunk-5Q7WB63A.cjs +282 -0
- package/dist/chunk-5Q7WB63A.cjs.map +1 -0
- package/dist/{chunk-PSKQAFDF.cjs → chunk-7KDOTBRX.cjs} +1 -1
- package/dist/chunk-7KDOTBRX.cjs.map +1 -0
- package/dist/{chunk-5DLZWW5Y.js → chunk-AHHEGTUA.js} +3 -3
- package/dist/chunk-AOHQCX7K.cjs +95 -0
- package/dist/chunk-AOHQCX7K.cjs.map +1 -0
- package/dist/{chunk-IUI5CI2S.cjs → chunk-DINLR6E6.cjs} +96 -92
- package/dist/chunk-DINLR6E6.cjs.map +1 -0
- package/dist/{chunk-L44TM4EE.cjs → chunk-EYTVC2H5.cjs} +568 -454
- package/dist/chunk-EYTVC2H5.cjs.map +1 -0
- package/dist/chunk-FEE2YBZ7.js +1972 -0
- package/dist/chunk-FEE2YBZ7.js.map +1 -0
- package/dist/chunk-FNO5K3A7.js +282 -0
- package/dist/chunk-FNO5K3A7.js.map +1 -0
- package/dist/chunk-IHHDXZPZ.js +382 -0
- package/dist/chunk-IHHDXZPZ.js.map +1 -0
- package/dist/chunk-J3EAIVA3.js +280 -0
- package/dist/chunk-J3EAIVA3.js.map +1 -0
- package/dist/{chunk-DFTOTBGF.js → chunk-KH3WF3K4.js} +20 -16
- package/dist/chunk-KH3WF3K4.js.map +1 -0
- package/dist/{chunk-TB2RZGDV.js → chunk-M35X5PHO.js} +14 -1
- package/dist/chunk-M35X5PHO.js.map +1 -0
- package/dist/chunk-QRGZD2JU.cjs +1972 -0
- package/dist/chunk-QRGZD2JU.cjs.map +1 -0
- package/dist/{chunk-4KF7KUAI.cjs → chunk-RBOER6EW.cjs} +6 -6
- package/dist/chunk-RBOER6EW.cjs.map +1 -0
- package/dist/{chunk-6MN3H3YF.cjs → chunk-RSH6QSEC.cjs} +16 -3
- package/dist/chunk-RSH6QSEC.cjs.map +1 -0
- package/dist/{chunk-T7P5EIC4.cjs → chunk-VMRDXOLX.cjs} +33 -33
- package/dist/chunk-VMRDXOLX.cjs.map +1 -0
- package/dist/{chunk-5XKOCKY2.js → chunk-X4UHZX6F.js} +1 -1
- package/dist/chunk-XBSGUVCY.cjs +382 -0
- package/dist/chunk-XBSGUVCY.cjs.map +1 -0
- package/dist/{chunk-OHQTKGQN.js → chunk-XKDZHAUE.js} +242 -128
- package/dist/chunk-XKDZHAUE.js.map +1 -0
- package/dist/chunk-ZUZGAO6G.cjs +280 -0
- package/dist/chunk-ZUZGAO6G.cjs.map +1 -0
- package/dist/{content-CAIp1njn.d.cts → content-C5aJZFlw.d.cts} +1 -1
- package/dist/{content-CGMJdyH_.d.ts → content-hLH5BNud.d.ts} +1 -1
- package/dist/contracts/index.cjs +13 -3
- package/dist/contracts/index.cjs.map +1 -1
- package/dist/contracts/index.d.cts +5 -4
- package/dist/contracts/index.d.ts +5 -4
- package/dist/contracts/index.js +14 -4
- package/dist/{discovery-DxpirOz3.d.cts → discovery-9E-LfwIw.d.cts} +1 -1
- package/dist/{discovery-gSqWpuRm.d.ts → discovery-D60yrjej.d.ts} +1 -1
- package/dist/discovery.cjs +63 -65
- package/dist/discovery.cjs.map +1 -1
- package/dist/discovery.d.cts +4 -4
- package/dist/discovery.d.ts +4 -4
- package/dist/discovery.js +5 -7
- package/dist/discovery.js.map +1 -1
- package/dist/execution-bridge-fpCnH6z5.d.cts +52 -0
- package/dist/execution-bridge-rk0uVy_n.d.ts +52 -0
- package/dist/execution.cjs +6 -356
- package/dist/execution.cjs.map +1 -1
- package/dist/execution.d.cts +4 -51
- package/dist/execution.d.ts +4 -51
- package/dist/execution.js +9 -359
- package/dist/execution.js.map +1 -1
- package/dist/index.cjs +10 -12
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +9 -16
- package/dist/index.d.ts +9 -16
- package/dist/index.js +10 -12
- package/dist/index.js.map +1 -1
- package/dist/{module-CWNK2BMj.d.ts → module-CYfE7YhM.d.ts} +2 -2
- package/dist/{module-BbvwdCDF.d.cts → module-Ca9L3qCn.d.cts} +2 -2
- package/dist/{planning-CcFZYdIL.d.cts → planning-CHrOqQ6b.d.cts} +45 -10
- package/dist/{planning-CcFZYdIL.d.ts → planning-CHrOqQ6b.d.ts} +45 -10
- package/dist/{ports-Bn6ro2FB.d.ts → ports-B0McVg7B.d.ts} +4 -3
- package/dist/ports-BeGO1VRI.d.cts +49 -0
- package/dist/{ports-CaL6geqR.d.cts → ports-GQy0x-RI.d.cts} +4 -3
- package/dist/ports-ykGiNUSx.d.ts +49 -0
- package/dist/runtime/index.cjs +205 -0
- package/dist/runtime/index.cjs.map +1 -0
- package/dist/runtime/index.d.cts +75 -0
- package/dist/runtime/index.d.ts +75 -0
- package/dist/runtime/index.js +205 -0
- package/dist/runtime/index.js.map +1 -0
- package/dist/runtime/integration.cjs +423 -0
- package/dist/runtime/integration.cjs.map +1 -0
- package/dist/runtime/integration.d.cts +658 -0
- package/dist/runtime/integration.d.ts +658 -0
- package/dist/runtime/integration.js +423 -0
- package/dist/runtime/integration.js.map +1 -0
- package/dist/storage.cjs +9 -277
- package/dist/storage.cjs.map +1 -1
- package/dist/storage.d.cts +6 -6
- package/dist/storage.d.ts +6 -6
- package/dist/storage.js +11 -279
- package/dist/storage.js.map +1 -1
- package/dist/{store-q63eSMoT.d.cts → store-DPwHzGiz.d.cts} +2 -2
- package/dist/{store-Ct0gOAAg.d.ts → store-DgdrPCV9.d.ts} +2 -2
- package/dist/task-projection-CSorlMws.d.ts +11 -0
- package/dist/task-projection-DKKB_ueb.d.cts +11 -0
- package/examples/standalone.ts +22 -0
- package/package.json +117 -87
- package/dist/chunk-2YFPV5GF.cjs +0 -16
- package/dist/chunk-2YFPV5GF.cjs.map +0 -1
- package/dist/chunk-4KF7KUAI.cjs.map +0 -1
- package/dist/chunk-6MN3H3YF.cjs.map +0 -1
- package/dist/chunk-DFTOTBGF.js.map +0 -1
- package/dist/chunk-G6FCDLDF.js +0 -16
- package/dist/chunk-G6FCDLDF.js.map +0 -1
- package/dist/chunk-IUI5CI2S.cjs.map +0 -1
- package/dist/chunk-KYNYPKKH.cjs +0 -71
- package/dist/chunk-KYNYPKKH.cjs.map +0 -1
- package/dist/chunk-L44TM4EE.cjs.map +0 -1
- package/dist/chunk-LSE6JG5I.cjs +0 -20
- package/dist/chunk-LSE6JG5I.cjs.map +0 -1
- package/dist/chunk-O4OGAAV4.js.map +0 -1
- package/dist/chunk-OHQTKGQN.js.map +0 -1
- package/dist/chunk-PSKQAFDF.cjs.map +0 -1
- package/dist/chunk-QTMTBEBA.js +0 -20
- package/dist/chunk-QTMTBEBA.js.map +0 -1
- package/dist/chunk-T7P5EIC4.cjs.map +0 -1
- package/dist/chunk-TB2RZGDV.js.map +0 -1
- package/dist/ui/index.cjs +0 -1961
- package/dist/ui/index.cjs.map +0 -1
- package/dist/ui/index.d.cts +0 -209
- package/dist/ui/index.d.ts +0 -209
- package/dist/ui/index.js +0 -1961
- package/dist/ui/index.js.map +0 -1
- package/dist/ui/kanban.css +0 -194
- /package/dist/{chunk-ATUFFNLV.js.map → chunk-3LEIHB7Y.js.map} +0 -0
- /package/dist/{chunk-5DLZWW5Y.js.map → chunk-AHHEGTUA.js.map} +0 -0
- /package/dist/{chunk-5XKOCKY2.js.map → chunk-X4UHZX6F.js.map} +0 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/contracts/board-control.ts","../src/contracts/task-projection.ts"],"sourcesContent":["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"],"mappings":"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","names":["item"]}
|
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
import {
|
|
2
|
-
KanbanError
|
|
3
|
-
} from "./chunk-G6FCDLDF.js";
|
|
4
1
|
import {
|
|
5
2
|
DEFAULT_KANBAN_WORK_TYPES,
|
|
6
3
|
executableWorkItem
|
|
7
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-X4UHZX6F.js";
|
|
5
|
+
import {
|
|
6
|
+
KanbanError
|
|
7
|
+
} from "./chunk-M35X5PHO.js";
|
|
8
8
|
|
|
9
9
|
// src/discovery-state.ts
|
|
10
10
|
function discoveryState(state) {
|
|
@@ -218,4 +218,4 @@ export {
|
|
|
218
218
|
owned,
|
|
219
219
|
discoveryState
|
|
220
220
|
};
|
|
221
|
-
//# sourceMappingURL=chunk-
|
|
221
|
+
//# sourceMappingURL=chunk-3LEIHB7Y.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["/home/li/share/prj/x1/
|
|
1
|
+
{"version":3,"sources":["/home/li/share/prj/x1/libraries/kanban/dist/chunk-4XF6LQSU.cjs","../src/execution-observation.ts"],"names":[],"mappings":"AAAA;ACIO,SAAS,2BAAA,CAA4B,OAAA,EAAsB,IAAA,EAA4B;AAC1F,EAAA,OAAO,OAAA,CAAQ,QAAA,IAAY,IAAA,CAAK,QAAA,GAAW,OAAA,CAAQ,KAAA,IAAS,IAAA,CAAK,KAAA,GAC1D,IAAA,CAAK,SAAA,kBAAU,OAAA,CAAQ,OAAA,UAAW,CAAC,GAAC,EAAA,IAAM,IAAA,CAAK,SAAA,kBAAU,IAAA,CAAK,OAAA,UAAW,CAAC,GAAC,EAAA,GAC3E,IAAA,CAAK,mBAAA,IAAuB,KAAA,EAAA,GAAa,OAAA,CAAQ,mBAAA,IAAuB,IAAA,CAAK,mBAAA,GAC7E,IAAA,CAAK,oBAAA,IAAwB,KAAA,EAAA,GAAa,IAAA,CAAK,SAAA,CAAU,OAAA,CAAQ,mBAAmB,EAAA,IAAM,IAAA,CAAK,SAAA,CAAU,IAAA,CAAK,mBAAmB,CAAA;AAC5I;ADLA;AACA;AACE;AACF,kEAAC","file":"/home/li/share/prj/x1/libraries/kanban/dist/chunk-4XF6LQSU.cjs","sourcesContent":[null,"import type {KanbanDispatch} from './contracts';\n\ntype Observation = Pick<KanbanDispatch, 'outcome' | 'code' | 'outputs' | 'executionSessionId' | 'controlCapabilities'>;\n/** A lease renewal is operational state, separate from observable execution changes. */\nexport function executionObservationChanged(current: Observation, next: Observation): boolean {\n return current.outcome !== next.outcome || current.code !== next.code\n || JSON.stringify(current.outputs ?? []) !== JSON.stringify(next.outputs ?? [])\n || next.executionSessionId !== undefined && current.executionSessionId !== next.executionSessionId\n || next.controlCapabilities !== undefined && JSON.stringify(current.controlCapabilities) !== JSON.stringify(next.controlCapabilities);\n}\n"]}
|
|
@@ -0,0 +1,282 @@
|
|
|
1
|
+
"use strict";Object.defineProperty(exports, "__esModule", {value: true}); function _nullishCoalesce(lhs, rhsFn) { if (lhs != null) { return lhs; } else { return rhsFn(); } } async function _asyncNullishCoalesce(lhs, rhsFn) { if (lhs != null) { return lhs; } else { return await 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; } async function _asyncOptionalChain(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 = await fn(value); } else if (op === 'call' || op === 'optionalCall') { value = await fn((...args) => value.call(lastAccessLHS, ...args)); lastAccessLHS = undefined; } } return value; }
|
|
2
|
+
|
|
3
|
+
var _chunkDINLR6E6cjs = require('./chunk-DINLR6E6.cjs');
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
var _chunkRBOER6EWcjs = require('./chunk-RBOER6EW.cjs');
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
var _chunkRSH6QSECcjs = require('./chunk-RSH6QSEC.cjs');
|
|
14
|
+
|
|
15
|
+
// src/session-activity-query.ts
|
|
16
|
+
async function querySessionItems(core, boardId, input, project) {
|
|
17
|
+
const { execution = "all", ...query } = input;
|
|
18
|
+
if (!["all", "running", "recent", "active"].includes(execution)) throw new (0, _chunkRSH6QSECcjs.KanbanError)("INVALID_EXECUTION_FILTER");
|
|
19
|
+
if (execution === "all") {
|
|
20
|
+
const page2 = await core.query(boardId, query);
|
|
21
|
+
return { ...page2, items: await project(page2.items) };
|
|
22
|
+
}
|
|
23
|
+
const { cursor, limit = 50, ...filters } = query;
|
|
24
|
+
if (!Number.isSafeInteger(limit) || limit < 1 || limit > 200) throw new (0, _chunkRSH6QSECcjs.KanbanError)("INVALID_PAGE_SIZE");
|
|
25
|
+
let page = await core.query(boardId, { ...filters, limit: 200 }), rows = [...page.items];
|
|
26
|
+
const revision = page.revision;
|
|
27
|
+
while (page.nextCursor) {
|
|
28
|
+
if (rows.length >= 1e4) throw new (0, _chunkRSH6QSECcjs.KanbanError)("ACTIVITY_QUERY_LIMIT");
|
|
29
|
+
page = await core.query(boardId, { ...filters, limit: 200, cursor: page.nextCursor });
|
|
30
|
+
if (page.revision !== revision) throw new (0, _chunkRSH6QSECcjs.KanbanError)("CURSOR_STALE");
|
|
31
|
+
rows.push(...page.items);
|
|
32
|
+
}
|
|
33
|
+
const matching = (await project(rows)).filter((row) => matchesExecution(row, execution));
|
|
34
|
+
if ((await core.query(boardId, { ...filters, limit: 1 })).revision !== revision) throw new (0, _chunkRSH6QSECcjs.KanbanError)("CURSOR_STALE");
|
|
35
|
+
const scope = _chunkRSH6QSECcjs.sha256HexSync.call(void 0, JSON.stringify({ filters, execution, limit })), signature = _chunkRSH6QSECcjs.sha256HexSync.call(void 0, JSON.stringify(matching.map((row) => row.id)));
|
|
36
|
+
let start = 0;
|
|
37
|
+
if (cursor) {
|
|
38
|
+
let saved;
|
|
39
|
+
try {
|
|
40
|
+
saved = JSON.parse(cursor);
|
|
41
|
+
} catch (e) {
|
|
42
|
+
throw new (0, _chunkRSH6QSECcjs.KanbanError)("INVALID_CURSOR");
|
|
43
|
+
}
|
|
44
|
+
if (saved.scope !== scope) throw new (0, _chunkRSH6QSECcjs.KanbanError)("CURSOR_SCOPE_MISMATCH");
|
|
45
|
+
if (saved.revision !== revision || saved.signature !== signature) throw new (0, _chunkRSH6QSECcjs.KanbanError)("CURSOR_STALE");
|
|
46
|
+
start = matching.findIndex((row) => row.id === saved.after) + 1;
|
|
47
|
+
if (start < 1) throw new (0, _chunkRSH6QSECcjs.KanbanError)("INVALID_CURSOR");
|
|
48
|
+
}
|
|
49
|
+
const items = matching.slice(start, start + limit);
|
|
50
|
+
return { revision, total: matching.length, items, ...start + items.length < matching.length ? { nextCursor: JSON.stringify({ scope, revision, signature, after: items.at(-1).id }) } : {} };
|
|
51
|
+
}
|
|
52
|
+
function matchesExecution(row, filter) {
|
|
53
|
+
const session = row.execution;
|
|
54
|
+
if (!session || session.stale) return false;
|
|
55
|
+
return filter === "running" ? session.state === "running" : filter === "recent" ? session.recent : session.state === "running" || session.recent;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
// src/session-relations.ts
|
|
59
|
+
function sessionAssociations(item, bindings, workflow) {
|
|
60
|
+
return [...bindings.map((ref) => {
|
|
61
|
+
const dispatch = workflow.dispatches[_nullishCoalesce(ref.revision, () => ( ""))];
|
|
62
|
+
const execution = _optionalChain([dispatch, 'optionalAccess', _ => _.itemId]) === item.id ? {
|
|
63
|
+
id: dispatch.id,
|
|
64
|
+
purpose: "execution",
|
|
65
|
+
dispatchId: dispatch.id,
|
|
66
|
+
attempt: dispatch.attempt,
|
|
67
|
+
outcome: dispatch.outcome,
|
|
68
|
+
createdAt: dispatch.preparedAt,
|
|
69
|
+
code: dispatch.code,
|
|
70
|
+
...dispatch.continuation ? { previousDispatchId: dispatch.continuation.previousDispatchId } : {}
|
|
71
|
+
} : void 0;
|
|
72
|
+
return { sessionId: ref.id, purpose: "execution", ...execution ? { execution } : {} };
|
|
73
|
+
}), ...item.participants.filter((row) => !bindings.some((ref) => ref.id === row.sessionId)).map((row) => ({ sessionId: row.sessionId, purpose: "discussion" }))];
|
|
74
|
+
}
|
|
75
|
+
async function projectRelatedSessions(associations, currentId, inspect) {
|
|
76
|
+
const grouped = /* @__PURE__ */ new Map();
|
|
77
|
+
for (const row of associations) {
|
|
78
|
+
let group = grouped.get(row.sessionId);
|
|
79
|
+
if (!group) grouped.set(row.sessionId, group = { purposes: /* @__PURE__ */ new Set(), executions: /* @__PURE__ */ new Map() });
|
|
80
|
+
group.purposes.add(row.purpose);
|
|
81
|
+
if (row.execution) group.executions.set(row.execution.id, { ...group.executions.get(row.execution.id), ...row.execution });
|
|
82
|
+
}
|
|
83
|
+
const rows = [], entries = [...grouped];
|
|
84
|
+
let next = 0;
|
|
85
|
+
await Promise.all(Array.from({ length: Math.min(entries.length, 8) }, async () => {
|
|
86
|
+
while (next < entries.length) {
|
|
87
|
+
const [sessionId, group] = entries[next++], state = await inspect(sessionId);
|
|
88
|
+
rows.push({
|
|
89
|
+
...state,
|
|
90
|
+
current: sessionId === currentId,
|
|
91
|
+
purposes: [...group.purposes].sort(),
|
|
92
|
+
executions: [...group.executions.values()].sort((a, b) => (_nullishCoalesce(a.createdAt, () => ( 0))) - (_nullishCoalesce(b.createdAt, () => ( 0))) || a.id.localeCompare(b.id))
|
|
93
|
+
});
|
|
94
|
+
}
|
|
95
|
+
}));
|
|
96
|
+
return rows.sort((a, b) => Number(b.current) - Number(a.current) || a.sessionId.localeCompare(b.sessionId));
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
// src/session-activity.ts
|
|
100
|
+
function executionBindings(refs, referenceSystem) {
|
|
101
|
+
return (_nullishCoalesce(refs, () => ( []))).filter((ref) => ref.system === referenceSystem);
|
|
102
|
+
}
|
|
103
|
+
function currentBinding(refs, itemId, workflow, referenceSystem) {
|
|
104
|
+
const binding = executionBindings(refs, referenceSystem).at(-1), latest = Object.values(workflow.dispatches).filter((dispatch) => dispatch.itemId === itemId).sort((a, b) => b.attempt - a.attempt)[0];
|
|
105
|
+
if (!binding || !latest || binding.revision === latest.id) return binding;
|
|
106
|
+
return ["prepared", "running", "unknown", "succeeded"].includes(latest.outcome) || workflow.dispatches[_nullishCoalesce(binding.revision, () => ( ""))] ? void 0 : binding;
|
|
107
|
+
}
|
|
108
|
+
function createKanbanSessionActivity(core, options, log, referenceSystem) {
|
|
109
|
+
const inspect = createSessionInspector(options, log);
|
|
110
|
+
const project = async (boardId, rows) => {
|
|
111
|
+
if (!rows.some((row) => executionBindings(row.externalRefs, referenceSystem).length)) return rows;
|
|
112
|
+
const [board, workflow] = await Promise.all([boardMetadata(core, boardId), core.workflow(boardId)]), bindings = new Map(rows.map((row) => [row.id, currentBinding(row.externalRefs, row.id, workflow, referenceSystem)]));
|
|
113
|
+
const ids = [...new Set([...bindings.values()].flatMap((ref) => ref ? [ref.id] : []))], states = /* @__PURE__ */ new Map();
|
|
114
|
+
let next = 0;
|
|
115
|
+
await Promise.all(Array.from({ length: Math.min(ids.length, 8) }, async () => {
|
|
116
|
+
while (next < ids.length) {
|
|
117
|
+
const id = ids[next++];
|
|
118
|
+
states.set(id, await inspect(board, id));
|
|
119
|
+
}
|
|
120
|
+
}));
|
|
121
|
+
return rows.map((row) => {
|
|
122
|
+
const binding = bindings.get(row.id);
|
|
123
|
+
return { ...row, ...binding ? { execution: states.get(binding.id) } : {} };
|
|
124
|
+
});
|
|
125
|
+
};
|
|
126
|
+
return {
|
|
127
|
+
queryActivity: (boardId, query = {}) => querySessionItems(core, boardId, query, (rows) => project(boardId, rows)),
|
|
128
|
+
async executionSession(boardId, itemId, query = {}) {
|
|
129
|
+
const started = Date.now();
|
|
130
|
+
if (!query || typeof query !== "object" || Array.isArray(query) || Object.keys(query).some((key) => key !== "includeRelated") || query.includeRelated !== void 0 && typeof query.includeRelated !== "boolean") throw new (0, _chunkRSH6QSECcjs.KanbanError)("INVALID_QUERY");
|
|
131
|
+
const { item } = await core.item(boardId, itemId), bindings = executionBindings(item.externalRefs, referenceSystem);
|
|
132
|
+
if (!bindings.length && !query.includeRelated) return { history: [] };
|
|
133
|
+
const [board, workflow] = await Promise.all([boardMetadata(core, boardId), core.workflow(boardId)]), last = currentBinding(item.externalRefs, itemId, workflow, referenceSystem);
|
|
134
|
+
let sessionsCode;
|
|
135
|
+
const related = query.includeRelated ? await _optionalChain([options, 'optionalAccess', _2 => _2.source, 'access', _3 => _3.related, 'optionalCall', _4 => _4(board, item, workflow), 'access', _5 => _5.catch, 'call', _6 => _6((error) => {
|
|
136
|
+
const candidate = _optionalChain([error, 'optionalAccess', _7 => _7.code]);
|
|
137
|
+
sessionsCode = candidate && /^[A-Z][A-Z0-9_]{0,79}$/.test(candidate) ? candidate : "SESSION_RELATIONS_FAILED";
|
|
138
|
+
try {
|
|
139
|
+
log({ operationId: _chunkRSH6QSECcjs.randomUUID.call(void 0, ), stage: "session.relations", result: "failure", code: sessionsCode, durationMs: Date.now() - started });
|
|
140
|
+
} catch (e2) {
|
|
141
|
+
}
|
|
142
|
+
return [];
|
|
143
|
+
})]) : [];
|
|
144
|
+
const sessions = query.includeRelated ? await projectRelatedSessions([
|
|
145
|
+
...sessionAssociations(item, bindings, workflow),
|
|
146
|
+
..._nullishCoalesce(related, () => ( []))
|
|
147
|
+
], _optionalChain([last, 'optionalAccess', _8 => _8.id]), (id) => inspect(board, id)) : void 0;
|
|
148
|
+
return {
|
|
149
|
+
current: last ? await _asyncNullishCoalesce(await _asyncOptionalChain([sessions, 'optionalAccess', async _9 => _9.find, 'call', async _10 => _10((row) => row.sessionId === last.id)]), async () => ( await inspect(board, last.id))) : void 0,
|
|
150
|
+
history: bindings.map((ref) => ({ sessionId: ref.id, bindingId: ref.revision, current: ref === last })).reverse(),
|
|
151
|
+
...sessions ? { sessions } : {},
|
|
152
|
+
...sessionsCode ? { sessionsCode } : {}
|
|
153
|
+
};
|
|
154
|
+
},
|
|
155
|
+
validate: (board, command, actor) => validateBinding(core, options, board, command, actor, referenceSystem)
|
|
156
|
+
};
|
|
157
|
+
}
|
|
158
|
+
function createSessionInspector(options, log) {
|
|
159
|
+
const now = _nullishCoalesce(_optionalChain([options, 'optionalAccess', _11 => _11.now]), () => ( Date.now)), cache = /* @__PURE__ */ new Map();
|
|
160
|
+
return async (board, sessionId) => {
|
|
161
|
+
const started = now(), key = JSON.stringify([board.id, sessionId]);
|
|
162
|
+
try {
|
|
163
|
+
if (!options) throw new (0, _chunkRSH6QSECcjs.KanbanError)("EXECUTION_SESSION_UNAVAILABLE");
|
|
164
|
+
const row = await options.source.inspect(board, sessionId);
|
|
165
|
+
if (row.sessionId !== sessionId) throw new (0, _chunkRSH6QSECcjs.KanbanError)("SESSION_ACTIVITY_SCOPE_MISMATCH");
|
|
166
|
+
const stale = row.stale || row.observedAt === void 0 || now() - row.observedAt > 9e4;
|
|
167
|
+
const value = {
|
|
168
|
+
sessionId,
|
|
169
|
+
...typeof row.resourceId === "string" && row.resourceId.length <= 4096 && !row.resourceId.includes("\0") ? { resourceId: row.resourceId } : {},
|
|
170
|
+
title: _optionalChain([row, 'access', _12 => _12.title, 'optionalAccess', _13 => _13.slice, 'call', _14 => _14(0, 256)]),
|
|
171
|
+
state: row.state,
|
|
172
|
+
createdAt: row.createdAt,
|
|
173
|
+
lastActivityAt: row.lastActivityAt,
|
|
174
|
+
observedAt: row.observedAt,
|
|
175
|
+
stale,
|
|
176
|
+
recent: !stale && row.lastActivityAt !== void 0 && row.lastActivityAt <= now() && now() - row.lastActivityAt <= 6e5,
|
|
177
|
+
...row.code && /^[A-Z][A-Z0-9_]{0,79}$/.test(row.code) ? { code: row.code } : {}
|
|
178
|
+
};
|
|
179
|
+
if (cache.size >= 256) cache.delete(cache.keys().next().value);
|
|
180
|
+
cache.set(key, value);
|
|
181
|
+
return value;
|
|
182
|
+
} catch (error) {
|
|
183
|
+
const candidate = _optionalChain([error, 'optionalAccess', _15 => _15.code]), code = candidate && /^[A-Z][A-Z0-9_]{0,79}$/.test(candidate) ? candidate : "SESSION_ACTIVITY_FAILED";
|
|
184
|
+
try {
|
|
185
|
+
log({ operationId: _chunkRSH6QSECcjs.randomUUID.call(void 0, ), sessionId, stage: "session.activity", result: "failure", code, durationMs: now() - started });
|
|
186
|
+
} catch (e3) {
|
|
187
|
+
}
|
|
188
|
+
const prior = ["EIO", "ETIMEDOUT", "ECONNRESET", "ECONNREFUSED", "SESSION_ACTIVITY_FAILED"].includes(code) ? cache.get(key) : void 0;
|
|
189
|
+
return { ...prior, sessionId, state: _nullishCoalesce(_optionalChain([prior, 'optionalAccess', _16 => _16.state]), () => ( "unknown")), stale: true, recent: false, code };
|
|
190
|
+
}
|
|
191
|
+
};
|
|
192
|
+
}
|
|
193
|
+
async function boardMetadata(core, boardId) {
|
|
194
|
+
const board = await _asyncNullishCoalesce((await core.catalog()).find((board2) => board2.id === boardId), async () => ( await core.read(boardId)));
|
|
195
|
+
return { ...board, items: [] };
|
|
196
|
+
}
|
|
197
|
+
async function validateBinding(core, options, board, command, actor, referenceSystem) {
|
|
198
|
+
if (_optionalChain([command, 'optionalAccess', _17 => _17.type]) !== "link-reference" || command.reference.system !== referenceSystem) return;
|
|
199
|
+
if (!options || !command.reference.revision) throw new (0, _chunkRSH6QSECcjs.KanbanError)("EXECUTION_SESSION_UNAVAILABLE");
|
|
200
|
+
const item = board.items.find((item2) => item2.id === command.itemId);
|
|
201
|
+
if (!item) throw new (0, _chunkRSH6QSECcjs.KanbanError)("ITEM_NOT_FOUND");
|
|
202
|
+
const key = _chunkRBOER6EWcjs.principalKey.call(void 0, _chunkRBOER6EWcjs.principal.call(void 0, actor)), coordinator = _optionalChain([board, 'access', _18 => _18.members, 'optionalAccess', _19 => _19.some, 'call', _20 => _20((member) => _chunkRBOER6EWcjs.principalKey.call(void 0, member) === key && _optionalChain([member, 'access', _21 => _21.roles, 'optionalAccess', _22 => _22.includes, 'call', _23 => _23("coordinator")]))]);
|
|
203
|
+
if (!coordinator && _optionalChain([item, 'access', _24 => _24.owner, 'optionalAccess', _25 => _25.principalId]) !== key && !(item.owner === void 0 && _chunkRBOER6EWcjs.candidates.call(void 0, board, item).some((candidate) => _chunkRBOER6EWcjs.principalKey.call(void 0, candidate) === key))) throw new (0, _chunkRSH6QSECcjs.KanbanError)("EXECUTION_SESSION_ASSIGNMENT_DENIED");
|
|
204
|
+
const active = Object.values((await core.workflow(board.id)).dispatches).filter((dispatch) => dispatch.itemId === item.id).sort((a, b) => b.attempt - a.attempt)[0];
|
|
205
|
+
if (active && command.reference.revision !== active.id) throw new (0, _chunkRSH6QSECcjs.KanbanError)("EXECUTION_SESSION_LOCKED");
|
|
206
|
+
if (active && executionBindings(item.externalRefs, referenceSystem).some((ref) => ref.revision === active.id && ref.id !== command.reference.id)) throw new (0, _chunkRSH6QSECcjs.KanbanError)("EXECUTION_SESSION_LOCKED");
|
|
207
|
+
if (options.source.authorizeBinding) return options.source.authorizeBinding(board, command.reference.id);
|
|
208
|
+
const state = await options.source.inspect(board, command.reference.id);
|
|
209
|
+
if (state.sessionId !== command.reference.id || state.stale) throw new (0, _chunkRSH6QSECcjs.KanbanError)("EXECUTION_SESSION_UNAVAILABLE");
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
// src/activity-module.ts
|
|
213
|
+
function createKanbanActivityModule(options) {
|
|
214
|
+
const { executionSessions, referenceSystem, ...core } = options;
|
|
215
|
+
let activity;
|
|
216
|
+
const service = _chunkDINLR6E6cjs.createKanbanModule.call(void 0, {
|
|
217
|
+
...core,
|
|
218
|
+
authorize: async (input) => {
|
|
219
|
+
await core.authorize(input);
|
|
220
|
+
await activity.validate(input.board, input.command, input.actor);
|
|
221
|
+
}
|
|
222
|
+
});
|
|
223
|
+
activity = createKanbanSessionActivity(service, executionSessions, core.log, referenceSystem);
|
|
224
|
+
let stopping = false;
|
|
225
|
+
const pending = /* @__PURE__ */ new Set();
|
|
226
|
+
const track = (run) => {
|
|
227
|
+
if (stopping) return Promise.reject(new (0, _chunkRSH6QSECcjs.KanbanError)("SERVICE_STOPPING"));
|
|
228
|
+
const work = Promise.resolve().then(run).finally(() => {
|
|
229
|
+
pending.delete(work);
|
|
230
|
+
});
|
|
231
|
+
pending.add(work);
|
|
232
|
+
return work;
|
|
233
|
+
};
|
|
234
|
+
const quiesce = async () => {
|
|
235
|
+
stopping = true;
|
|
236
|
+
await Promise.allSettled([...pending]);
|
|
237
|
+
await service.quiesce();
|
|
238
|
+
};
|
|
239
|
+
return {
|
|
240
|
+
...forwardCore(service, track),
|
|
241
|
+
queryActivity: (...args) => track(() => activity.queryActivity(...args)),
|
|
242
|
+
executionSession: (...args) => track(() => activity.executionSession(...args)),
|
|
243
|
+
related: (sessionId) => track(() => relatedBoards(service, referenceSystem, sessionId)),
|
|
244
|
+
quiesce,
|
|
245
|
+
dispose: quiesce
|
|
246
|
+
};
|
|
247
|
+
}
|
|
248
|
+
function forwardCore(service, track) {
|
|
249
|
+
return {
|
|
250
|
+
create: (input) => track(() => service.create(input)),
|
|
251
|
+
read: (id) => track(() => service.read(id)),
|
|
252
|
+
list: () => track(() => service.list()),
|
|
253
|
+
catalog: () => track(() => service.catalog()),
|
|
254
|
+
execute: (id, request) => track(() => service.execute(id, request)),
|
|
255
|
+
events: (id, after, limit) => track(() => service.events(id, after, limit)),
|
|
256
|
+
query: (id, query) => track(() => service.query(id, query)),
|
|
257
|
+
item: (id, item) => track(() => service.item(id, item)),
|
|
258
|
+
overview: (id) => track(() => service.overview(id)),
|
|
259
|
+
scan: () => track(() => service.scan()),
|
|
260
|
+
workflow: (id) => track(() => service.workflow(id)),
|
|
261
|
+
resolve: (reference) => track(() => service.resolve(reference)),
|
|
262
|
+
suggest: (id, query) => track(() => service.suggest(id, query)),
|
|
263
|
+
records: (id, query) => track(() => service.records(id, query)),
|
|
264
|
+
record: (id, record) => track(() => service.record(id, record)),
|
|
265
|
+
currentPrincipal: () => track(() => service.currentPrincipal())
|
|
266
|
+
};
|
|
267
|
+
}
|
|
268
|
+
async function relatedBoards(service, referenceSystem, sessionId) {
|
|
269
|
+
const boards = await service.related(sessionId);
|
|
270
|
+
for (const board of await service.catalog()) {
|
|
271
|
+
if (boards.some((old) => old.id === board.id)) continue;
|
|
272
|
+
const matches = await service.query(board.id, { view: "all", reference: { system: referenceSystem, id: sessionId }, limit: 1 });
|
|
273
|
+
if (matches.total) boards.push(await service.read(board.id));
|
|
274
|
+
}
|
|
275
|
+
return boards;
|
|
276
|
+
}
|
|
277
|
+
|
|
278
|
+
|
|
279
|
+
|
|
280
|
+
|
|
281
|
+
exports.querySessionItems = querySessionItems; exports.createKanbanActivityModule = createKanbanActivityModule;
|
|
282
|
+
//# sourceMappingURL=chunk-5Q7WB63A.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["/home/li/share/prj/x1/libraries/kanban/dist/chunk-5Q7WB63A.cjs","../src/session-activity-query.ts","../src/session-relations.ts","../src/session-activity.ts","../src/activity-module.ts"],"names":["page","board","item"],"mappings":"AAAA;AACE;AACF,wDAA6B;AAC7B;AACE;AACA;AACA;AACF,wDAA6B;AAC7B;AACE;AACA;AACA;AACF,wDAA6B;AAC7B;AACA;ACVA,MAAA,SAAsB,iBAAA,CAAkB,IAAA,EAAqB,OAAA,EAAiB,KAAA,EAC1E,OAAA,EAAkH;AAClH,EAAA,MAAM,EAAC,UAAA,EAAU,KAAA,EAAM,GAAG,MAAK,EAAA,EAAE,KAAA;AACjC,EAAA,GAAA,CAAG,CAAC,CAAC,KAAA,EAAM,SAAA,EAAU,QAAA,EAAS,QAAQ,CAAA,CAAE,QAAA,CAAS,SAAS,CAAA,EAAG,MAAM,IAAI,kCAAA,CAAY,0BAA0B,CAAA;AAC7G,EAAA,GAAA,CAAG,UAAA,IAAY,KAAA,EAAO;AAAC,IAAA,MAAMA,MAAAA,EAAK,MAAM,IAAA,CAAK,KAAA,CAAM,OAAA,EAAQ,KAAK,CAAA;AAAE,IAAA,OAAO,EAAC,GAAGA,KAAAA,EAAK,KAAA,EAAM,MAAM,OAAA,CAAQA,KAAAA,CAAK,KAAK,EAAC,CAAA;AAAA,EAAE;AACnH,EAAA,MAAM,EAAC,MAAA,EAAO,MAAA,EAAM,EAAA,EAAG,GAAG,QAAO,EAAA,EAAE,KAAA;AACnC,EAAA,GAAA,CAAG,CAAC,MAAA,CAAO,aAAA,CAAc,KAAK,EAAA,GAAG,MAAA,EAAM,EAAA,GAAG,MAAA,EAAM,GAAA,EAAK,MAAM,IAAI,kCAAA,CAAY,mBAAmB,CAAA;AAC9F,EAAA,IAAI,KAAA,EAAK,MAAM,IAAA,CAAK,KAAA,CAAM,OAAA,EAAQ,EAAC,GAAG,OAAA,EAAQ,KAAA,EAAM,IAAG,CAAC,CAAA,EAAG,KAAA,EAAK,CAAC,GAAG,IAAA,CAAK,KAAK,CAAA;AAAE,EAAA,MAAM,SAAA,EAAS,IAAA,CAAK,QAAA;AACpG,EAAA,MAAA,CAAM,IAAA,CAAK,UAAA,EAAY;AACnB,IAAA,GAAA,CAAG,IAAA,CAAK,OAAA,GAAQ,GAAA,EAAO,MAAM,IAAI,kCAAA,CAAY,sBAAsB,CAAA;AACnE,IAAA,KAAA,EAAK,MAAM,IAAA,CAAK,KAAA,CAAM,OAAA,EAAQ,EAAC,GAAG,OAAA,EAAQ,KAAA,EAAM,GAAA,EAAI,MAAA,EAAO,IAAA,CAAK,WAAU,CAAC,CAAA;AAC3E,IAAA,GAAA,CAAG,IAAA,CAAK,SAAA,IAAW,QAAA,EAAU,MAAM,IAAI,kCAAA,CAAY,cAAc,CAAA;AAAE,IAAA,IAAA,CAAK,IAAA,CAAK,GAAG,IAAA,CAAK,KAAK,CAAA;AAAA,EAC9F;AACA,EAAA,MAAM,SAAA,EAAA,CAAU,MAAM,OAAA,CAAQ,IAAI,CAAA,CAAA,CAAG,MAAA,CAAO,CAAA,GAAA,EAAA,GAAK,gBAAA,CAAiB,GAAA,EAAI,SAAS,CAAC,CAAA;AAChF,EAAA,GAAA,CAAA,CAAI,MAAM,IAAA,CAAK,KAAA,CAAM,OAAA,EAAQ,EAAC,GAAG,OAAA,EAAQ,KAAA,EAAM,EAAC,CAAC,CAAA,CAAA,CAAG,SAAA,IAAW,QAAA,EAAU,MAAM,IAAI,kCAAA,CAAY,cAAc,CAAA;AAC7G,EAAA,MAAM,MAAA,EAAM,6CAAA,IAAc,CAAK,SAAA,CAAU,EAAC,OAAA,EAAQ,SAAA,EAAU,MAAK,CAAC,CAAC,CAAA,EAAG,UAAA,EAAU,6CAAA,IAAc,CAAK,SAAA,CAAU,QAAA,CAAS,GAAA,CAAI,CAAA,GAAA,EAAA,GAAK,GAAA,CAAI,EAAE,CAAC,CAAC,CAAA;AACvI,EAAA,IAAI,MAAA,EAAM,CAAA;AACV,EAAA,GAAA,CAAG,MAAA,EAAQ;AACP,IAAA,IAAI,KAAA;AAAM,IAAA,IAAI;AAAC,MAAA,MAAA,EAAM,IAAA,CAAK,KAAA,CAAM,MAAM,CAAA;AAAA,IAAE,EAAA,UAAQ;AAAC,MAAA,MAAM,IAAI,kCAAA,CAAY,gBAAgB,CAAA;AAAA,IAAE;AACzF,IAAA,GAAA,CAAG,KAAA,CAAM,MAAA,IAAQ,KAAA,EAAO,MAAM,IAAI,kCAAA,CAAY,uBAAuB,CAAA;AACrE,IAAA,GAAA,CAAG,KAAA,CAAM,SAAA,IAAW,SAAA,GAAU,KAAA,CAAM,UAAA,IAAY,SAAA,EAAW,MAAM,IAAI,kCAAA,CAAY,cAAc,CAAA;AAC/F,IAAA,MAAA,EAAM,QAAA,CAAS,SAAA,CAAU,CAAA,GAAA,EAAA,GAAK,GAAA,CAAI,GAAA,IAAK,KAAA,CAAM,KAAK,EAAA,EAAE,CAAA;AAAE,IAAA,GAAA,CAAG,MAAA,EAAM,CAAA,EAAG,MAAM,IAAI,kCAAA,CAAY,gBAAgB,CAAA;AAAA,EAC5G;AACA,EAAA,MAAM,MAAA,EAAM,QAAA,CAAS,KAAA,CAAM,KAAA,EAAM,MAAA,EAAM,KAAK,CAAA;AAC5C,EAAA,OAAO,EAAC,QAAA,EAAS,KAAA,EAAM,QAAA,CAAS,MAAA,EAAO,KAAA,EAAM,GAAI,MAAA,EAAM,KAAA,CAAM,OAAA,EAAO,QAAA,CAAS,OAAA,EAAO,EAAC,UAAA,EAAW,IAAA,CAAK,SAAA,CAAU,EAAC,KAAA,EAAM,QAAA,EAAS,SAAA,EAAU,KAAA,EAAM,KAAA,CAAM,EAAA,CAAG,CAAA,CAAE,CAAA,CAAG,GAAE,CAAC,EAAC,EAAA,EAAG,CAAC,EAAE,CAAA;AAC3K;AACA,SAAS,gBAAA,CAAiB,GAAA,EAA+B,MAAA,EAAyB;AAC9E,EAAA,MAAM,QAAA,EAAQ,GAAA,CAAI,SAAA;AAAU,EAAA,GAAA,CAAG,CAAC,QAAA,GAAS,OAAA,CAAQ,KAAA,EAAO,OAAO,KAAA;AAC/D,EAAA,OAAO,OAAA,IAAS,UAAA,EAAU,OAAA,CAAQ,MAAA,IAAQ,UAAA,EAAU,OAAA,IAAS,SAAA,EAAS,OAAA,CAAQ,OAAA,EAAO,OAAA,CAAQ,MAAA,IAAQ,UAAA,GAAW,OAAA,CAAQ,MAAA;AAC5H;ADuBA;AACA;AEvDO,SAAS,mBAAA,CAAoB,IAAA,EAAkB,QAAA,EAAqC,QAAA,EAA2D;AAClJ,EAAA,OAAO,CAAC,GAAG,QAAA,CAAS,GAAA,CAAI,CAAA,GAAA,EAAA,GAAO;AAC3B,IAAA,MAAM,SAAA,EAAW,QAAA,CAAS,UAAA,kBAAW,GAAA,CAAI,QAAA,UAAY,IAAE,CAAA;AACvD,IAAA,MAAM,UAAA,kBAAgD,QAAA,2BAAU,SAAA,IAAW,IAAA,CAAK,GAAA,EAAK;AAAA,MACjF,EAAA,EAAI,QAAA,CAAS,EAAA;AAAA,MAAI,OAAA,EAAS,WAAA;AAAA,MAAa,UAAA,EAAY,QAAA,CAAS,EAAA;AAAA,MAAI,OAAA,EAAS,QAAA,CAAS,OAAA;AAAA,MAClF,OAAA,EAAS,QAAA,CAAS,OAAA;AAAA,MAAS,SAAA,EAAW,QAAA,CAAS,UAAA;AAAA,MAAY,IAAA,EAAM,QAAA,CAAS,IAAA;AAAA,MAC1E,GAAI,QAAA,CAAS,aAAA,EAAe,EAAC,kBAAA,EAAoB,QAAA,CAAS,YAAA,CAAa,mBAAkB,EAAA,EAAI,CAAC;AAAA,IAClG,EAAA,EAAI,KAAA,CAAA;AACJ,IAAA,OAAO,EAAC,SAAA,EAAW,GAAA,CAAI,EAAA,EAAI,OAAA,EAAS,WAAA,EAAsB,GAAI,UAAA,EAAY,EAAC,UAAS,EAAA,EAAI,CAAC,EAAE,CAAA;AAAA,EAC/F,CAAC,CAAA,EAAG,GAAG,IAAA,CAAK,YAAA,CAAa,MAAA,CAAO,CAAA,GAAA,EAAA,GAAO,CAAC,QAAA,CAAS,IAAA,CAAK,CAAA,GAAA,EAAA,GAAO,GAAA,CAAI,GAAA,IAAO,GAAA,CAAI,SAAS,CAAC,CAAA,CAAE,GAAA,CAAI,CAAA,GAAA,EAAA,GAAA,CAAQ,EAAC,SAAA,EAAW,GAAA,CAAI,SAAA,EAAW,OAAA,EAAS,aAAqB,CAAA,CAAE,CAAC,CAAA;AACpK;AAGA,MAAA,SAAsB,sBAAA,CAAuB,YAAA,EAA0C,SAAA,EACnF,OAAA,EAA2F;AAC3F,EAAA,MAAM,QAAA,kBAAU,IAAI,GAAA,CAAmH,CAAA;AACvI,EAAA,IAAA,CAAA,MAAW,IAAA,GAAO,YAAA,EAAc;AAC5B,IAAA,IAAI,MAAA,EAAQ,OAAA,CAAQ,GAAA,CAAI,GAAA,CAAI,SAAS,CAAA;AACrC,IAAA,GAAA,CAAI,CAAC,KAAA,EAAO,OAAA,CAAQ,GAAA,CAAI,GAAA,CAAI,SAAA,EAAW,MAAA,EAAQ,EAAC,QAAA,kBAAU,IAAI,GAAA,CAAI,CAAA,EAAG,UAAA,kBAAY,IAAI,GAAA,CAAI,EAAC,CAAC,CAAA;AAC3F,IAAA,KAAA,CAAM,QAAA,CAAS,GAAA,CAAI,GAAA,CAAI,OAAO,CAAA;AAC9B,IAAA,GAAA,CAAI,GAAA,CAAI,SAAA,EAAW,KAAA,CAAM,UAAA,CAAW,GAAA,CAAI,GAAA,CAAI,SAAA,CAAU,EAAA,EAAI,EAAC,GAAG,KAAA,CAAM,UAAA,CAAW,GAAA,CAAI,GAAA,CAAI,SAAA,CAAU,EAAE,CAAA,EAAG,GAAG,GAAA,CAAI,UAAS,CAAC,CAAA;AAAA,EAC3H;AACA,EAAA,MAAM,KAAA,EAA+B,CAAC,CAAA,EAAG,QAAA,EAAU,CAAC,GAAG,OAAO,CAAA;AAAG,EAAA,IAAI,KAAA,EAAO,CAAA;AAC5E,EAAA,MAAM,OAAA,CAAQ,GAAA,CAAI,KAAA,CAAM,IAAA,CAAK,EAAC,MAAA,EAAQ,IAAA,CAAK,GAAA,CAAI,OAAA,CAAQ,MAAA,EAAQ,CAAC,EAAC,CAAA,EAAG,MAAA,CAAA,EAAA,GAAY;AAC5E,IAAA,MAAA,CAAO,KAAA,EAAO,OAAA,CAAQ,MAAA,EAAQ;AAC1B,MAAA,MAAM,CAAC,SAAA,EAAW,KAAK,EAAA,EAAI,OAAA,CAAQ,IAAA,EAAM,CAAA,EAAG,MAAA,EAAQ,MAAM,OAAA,CAAQ,SAAS,CAAA;AAC3E,MAAA,IAAA,CAAK,IAAA,CAAK;AAAA,QAAC,GAAG,KAAA;AAAA,QAAO,OAAA,EAAS,UAAA,IAAc,SAAA;AAAA,QAAW,QAAA,EAAU,CAAC,GAAG,KAAA,CAAM,QAAQ,CAAA,CAAE,IAAA,CAAK,CAAA;AAAA,QACtF,UAAA,EAAY,CAAC,GAAG,KAAA,CAAM,UAAA,CAAW,MAAA,CAAO,CAAC,CAAA,CAAE,IAAA,CAAK,CAAC,CAAA,EAAG,CAAA,EAAA,GAAA,kBAAO,CAAA,CAAE,SAAA,UAAa,GAAA,EAAA,EAAA,kBAAM,CAAA,CAAE,SAAA,UAAa,GAAA,EAAA,GAAM,CAAA,CAAE,EAAA,CAAG,aAAA,CAAc,CAAA,CAAE,EAAE,CAAC;AAAA,MAAC,CAAC,CAAA;AAAA,IACvI;AAAA,EACJ,CAAC,CAAC,CAAA;AACF,EAAA,OAAO,IAAA,CAAK,IAAA,CAAK,CAAC,CAAA,EAAG,CAAA,EAAA,GAAM,MAAA,CAAO,CAAA,CAAE,OAAO,EAAA,EAAI,MAAA,CAAO,CAAA,CAAE,OAAO,EAAA,GAAK,CAAA,CAAE,SAAA,CAAU,aAAA,CAAc,CAAA,CAAE,SAAS,CAAC,CAAA;AAC9G;AFgEA;AACA;AG1FO,SAAS,iBAAA,CAAkB,IAAA,EAA6C,eAAA,EAAyB;AAAC,EAAA,OAAA,kBAAQ,IAAA,UAAQ,CAAC,GAAA,CAAA,CAAG,MAAA,CAAO,CAAA,GAAA,EAAA,GAAK,GAAA,CAAI,OAAA,IAAS,eAAe,CAAA;AAAE;AACvK,SAAS,cAAA,CAAe,IAAA,EAA2C,MAAA,EAAe,QAAA,EAA8B,eAAA,EAAyB;AACrI,EAAA,MAAM,QAAA,EAAQ,iBAAA,CAAkB,IAAA,EAAM,eAAe,CAAA,CAAE,EAAA,CAAG,CAAA,CAAE,CAAA,EAAE,OAAA,EAAO,MAAA,CAAO,MAAA,CAAO,QAAA,CAAS,UAAU,CAAA,CAAE,MAAA,CAAO,CAAA,QAAA,EAAA,GAAU,QAAA,CAAS,OAAA,IAAS,MAAM,CAAA,CAAE,IAAA,CAAK,CAAC,CAAA,EAAE,CAAA,EAAA,GAAI,CAAA,CAAE,QAAA,EAAQ,CAAA,CAAE,OAAO,CAAA,CAAE,CAAC,CAAA;AACrL,EAAA,GAAA,CAAG,CAAC,QAAA,GAAS,CAAC,OAAA,GAAQ,OAAA,CAAQ,SAAA,IAAW,MAAA,CAAO,EAAA,EAAI,OAAO,OAAA;AAC3D,EAAA,OAAO,CAAC,UAAA,EAAW,SAAA,EAAU,SAAA,EAAU,WAAW,CAAA,CAAE,QAAA,CAAS,MAAA,CAAO,OAAO,EAAA,GAAG,QAAA,CAAS,UAAA,kBAAW,OAAA,CAAQ,QAAA,UAAY,IAAE,EAAA,EAAE,KAAA,EAAA,EAAU,OAAA;AACxI;AAGO,SAAS,2BAAA,CAA4B,IAAA,EAAqB,OAAA,EAAmD,GAAA,EAAwH,eAAA,EAAyB;AACjQ,EAAA,MAAM,QAAA,EAAQ,sBAAA,CAAuB,OAAA,EAAQ,GAAG,CAAA;AAChD,EAAA,MAAM,QAAA,EAAQ,MAAA,CAAM,OAAA,EAAe,IAAA,EAAA,GAAkC;AACjE,IAAA,GAAA,CAAG,CAAC,IAAA,CAAK,IAAA,CAAK,CAAA,GAAA,EAAA,GAAK,iBAAA,CAAkB,GAAA,CAAI,YAAA,EAAa,eAAe,CAAA,CAAE,MAAM,CAAA,EAAE,OAAO,IAAA;AACtF,IAAA,MAAM,CAAC,KAAA,EAAM,QAAQ,EAAA,EAAE,MAAM,OAAA,CAAQ,GAAA,CAAI,CAAC,aAAA,CAAc,IAAA,EAAK,OAAO,CAAA,EAAE,IAAA,CAAK,QAAA,CAAS,OAAO,CAAC,CAAC,CAAA,EAAG,SAAA,EAAS,IAAI,GAAA,CAAI,IAAA,CAAK,GAAA,CAAI,CAAA,GAAA,EAAA,GAAK,CAAC,GAAA,CAAI,EAAA,EAAG,cAAA,CAAe,GAAA,CAAI,YAAA,EAAa,GAAA,CAAI,EAAA,EAAG,QAAA,EAAS,eAAe,CAAC,CAAC,CAAC,CAAA;AACzM,IAAA,MAAM,IAAA,EAAI,CAAC,GAAG,IAAI,GAAA,CAAI,CAAC,GAAG,QAAA,CAAS,MAAA,CAAO,CAAC,CAAA,CAAE,OAAA,CAAQ,CAAA,GAAA,EAAA,GAAK,IAAA,EAAI,CAAC,GAAA,CAAI,EAAE,EAAA,EAAE,CAAC,CAAC,CAAC,CAAC,CAAA,EAAG,OAAA,kBAAO,IAAI,GAAA,CAAmC,CAAA;AAAE,IAAA,IAAI,KAAA,EAAK,CAAA;AACvI,IAAA,MAAM,OAAA,CAAQ,GAAA,CAAI,KAAA,CAAM,IAAA,CAAK,EAAC,MAAA,EAAO,IAAA,CAAK,GAAA,CAAI,GAAA,CAAI,MAAA,EAAO,CAAC,EAAC,CAAA,EAAE,MAAA,CAAA,EAAA,GAAS;AAAC,MAAA,MAAA,CAAM,KAAA,EAAK,GAAA,CAAI,MAAA,EAAQ;AAAC,QAAA,MAAM,GAAA,EAAG,GAAA,CAAI,IAAA,EAAM,CAAA;AAAE,QAAA,MAAA,CAAO,GAAA,CAAI,EAAA,EAAG,MAAM,OAAA,CAAQ,KAAA,EAAM,EAAE,CAAC,CAAA;AAAA,MAAE;AAAA,IAAC,CAAC,CAAC,CAAA;AAC9J,IAAA,OAAO,IAAA,CAAK,GAAA,CAAI,CAAA,GAAA,EAAA,GAAK;AAAC,MAAA,MAAM,QAAA,EAAQ,QAAA,CAAS,GAAA,CAAI,GAAA,CAAI,EAAE,CAAA;AAAE,MAAA,OAAO,EAAC,GAAG,GAAA,EAAI,GAAI,QAAA,EAAQ,EAAC,SAAA,EAAU,MAAA,CAAO,GAAA,CAAI,OAAA,CAAQ,EAAE,EAAC,EAAA,EAAG,CAAC,EAAE,CAAA;AAAA,IAAE,CAAC,CAAA;AAAA,EAClI,CAAA;AACA,EAAA,OAAO;AAAA,IACH,aAAA,EAAc,CAAC,OAAA,EAAe,MAAA,EAAuD,CAAC,CAAA,EAAA,GAAI,iBAAA,CAAkB,IAAA,EAAK,OAAA,EAAQ,KAAA,EAAM,CAAA,IAAA,EAAA,GAAM,OAAA,CAAQ,OAAA,EAAQ,IAAI,CAAC,CAAA;AAAA,IAC1J,MAAM,gBAAA,CAAiB,OAAA,EAAe,MAAA,EAAe,MAAA,EAAwD,CAAC,CAAA,EAAG;AAC7G,MAAA,MAAM,QAAA,EAAU,IAAA,CAAK,GAAA,CAAI,CAAA;AACzB,MAAA,GAAA,CAAI,CAAC,MAAA,GAAS,OAAO,MAAA,IAAU,SAAA,GAAY,KAAA,CAAM,OAAA,CAAQ,KAAK,EAAA,GAAK,MAAA,CAAO,IAAA,CAAK,KAAK,CAAA,CAAE,IAAA,CAAK,CAAA,GAAA,EAAA,GAAO,IAAA,IAAQ,gBAAgB,EAAA,GAAK,KAAA,CAAM,eAAA,IAAmB,KAAA,EAAA,GAAa,OAAO,KAAA,CAAM,eAAA,IAAmB,SAAA,EAAW,MAAM,IAAI,kCAAA,CAAY,eAAe,CAAA;AACrP,MAAA,MAAM,EAAC,KAAI,EAAA,EAAE,MAAM,IAAA,CAAK,IAAA,CAAK,OAAA,EAAQ,MAAM,CAAA,EAAE,SAAA,EAAS,iBAAA,CAAkB,IAAA,CAAK,YAAA,EAAa,eAAe,CAAA;AACzG,MAAA,GAAA,CAAG,CAAC,QAAA,CAAS,OAAA,GAAU,CAAC,KAAA,CAAM,cAAA,EAAe,OAAO,EAAC,OAAA,EAAQ,CAAC,EAAC,CAAA;AAC/D,MAAA,MAAM,CAAC,KAAA,EAAM,QAAQ,EAAA,EAAE,MAAM,OAAA,CAAQ,GAAA,CAAI,CAAC,aAAA,CAAc,IAAA,EAAK,OAAO,CAAA,EAAE,IAAA,CAAK,QAAA,CAAS,OAAO,CAAC,CAAC,CAAA,EAAE,KAAA,EAAK,cAAA,CAAe,IAAA,CAAK,YAAA,EAAa,MAAA,EAAO,QAAA,EAAS,eAAe,CAAA;AACpK,MAAA,IAAI,YAAA;AACJ,MAAA,MAAM,QAAA,EAAU,KAAA,CAAM,eAAA,EAAiB,sBAAM,OAAA,6BAAS,MAAA,qBAAO,OAAA,0BAAA,CAAU,KAAA,EAAO,IAAA,EAAM,QAAQ,CAAA,qBAAE,KAAA,mBAAM,CAAA,KAAA,EAAA,GAAS;AACzG,QAAA,MAAM,UAAA,kBAAa,KAAA,6BAA2B,MAAA;AAC9C,QAAA,aAAA,EAAe,UAAA,GAAa,wBAAA,CAAyB,IAAA,CAAK,SAAS,EAAA,EAAI,UAAA,EAAY,0BAAA;AACnF,QAAA,IAAI;AAAC,UAAA,GAAA,CAAI,EAAC,WAAA,EAAa,0CAAA,CAAW,EAAG,KAAA,EAAO,mBAAA,EAAqB,MAAA,EAAQ,SAAA,EAAW,IAAA,EAAM,YAAA,EAAc,UAAA,EAAY,IAAA,CAAK,GAAA,CAAI,EAAA,EAAI,QAAO,CAAC,CAAA;AAAA,QAAE,EAAA,WAAQ;AAAA,QAAoD;AACvM,QAAA,OAAO,CAAC,CAAA;AAAA,MACZ,CAAC,IAAA,EAAI,CAAC,CAAA;AACN,MAAA,MAAM,SAAA,EAAW,KAAA,CAAM,eAAA,EAAiB,MAAM,sBAAA,CAAuB;AAAA,QACjE,GAAG,mBAAA,CAAoB,IAAA,EAAM,QAAA,EAAU,QAAQ,CAAA;AAAA,QAAG,oBAAG,OAAA,UAAW,CAAC;AAAA,MACrE,CAAA,kBAAG,IAAA,6BAAM,IAAA,EAAI,CAAA,EAAA,EAAA,GAAM,OAAA,CAAQ,KAAA,EAAO,EAAE,CAAC,EAAA,EAAI,KAAA,CAAA;AACzC,MAAA,OAAO;AAAA,QAAC,OAAA,EAAQ,KAAA,yDAAM,QAAA,mCAAU,IAAA,2BAAK,CAAA,GAAA,EAAA,GAAK,GAAA,CAAI,UAAA,IAAY,IAAA,CAAK,EAAE,GAAA,gBAAK,MAAM,OAAA,CAAQ,KAAA,EAAM,IAAA,CAAK,EAAE,IAAA,EAAG,KAAA,CAAA;AAAA,QAChG,OAAA,EAAQ,QAAA,CAAS,GAAA,CAAI,CAAA,GAAA,EAAA,GAAA,CAAM,EAAC,SAAA,EAAU,GAAA,CAAI,EAAA,EAAG,SAAA,EAAU,GAAA,CAAI,QAAA,EAAS,OAAA,EAAQ,IAAA,IAAM,KAAI,CAAA,CAAE,CAAA,CAAE,OAAA,CAAQ,CAAA;AAAA,QAAG,GAAI,SAAA,EAAW,EAAC,SAAQ,EAAA,EAAI,CAAC,CAAA;AAAA,QAAI,GAAI,aAAA,EAAe,EAAC,aAAY,EAAA,EAAI,CAAC;AAAA,MAAE,CAAA;AAAA,IACrL,CAAA;AAAA,IACA,QAAA,EAAS,CAAC,KAAA,EAAkB,OAAA,EAAgC,KAAA,EAAA,GAAoB,eAAA,CAAgB,IAAA,EAAK,OAAA,EAAQ,KAAA,EAAM,OAAA,EAAQ,KAAA,EAAM,eAAe;AAAA,EACpJ,CAAA;AACJ;AACA,SAAS,sBAAA,CAAuB,OAAA,EAA+C,GAAA,EAAuD;AAClI,EAAA,MAAM,IAAA,mCAAI,OAAA,+BAAS,KAAA,UAAO,IAAA,CAAK,KAAA,EAAK,MAAA,kBAAM,IAAI,GAAA,CAAmC,CAAA;AACjF,EAAA,OAAO,MAAA,CAAM,KAAA,EAAkB,SAAA,EAAA,GAAmD;AAC9E,IAAA,MAAM,QAAA,EAAQ,GAAA,CAAI,CAAA,EAAE,IAAA,EAAI,IAAA,CAAK,SAAA,CAAU,CAAC,KAAA,CAAM,EAAA,EAAG,SAAS,CAAC,CAAA;AAC3D,IAAA,IAAI;AACA,MAAA,GAAA,CAAG,CAAC,OAAA,EAAS,MAAM,IAAI,kCAAA,CAAY,+BAA+B,CAAA;AAClE,MAAA,MAAM,IAAA,EAAI,MAAM,OAAA,CAAQ,MAAA,CAAO,OAAA,CAAQ,KAAA,EAAM,SAAS,CAAA;AACtD,MAAA,GAAA,CAAG,GAAA,CAAI,UAAA,IAAY,SAAA,EAAW,MAAM,IAAI,kCAAA,CAAY,iCAAiC,CAAA;AACrF,MAAA,MAAM,MAAA,EAAM,GAAA,CAAI,MAAA,GAAO,GAAA,CAAI,WAAA,IAAa,KAAA,EAAA,GAAW,GAAA,CAAI,EAAA,EAAE,GAAA,CAAI,WAAA,EAAW,GAAA;AACxE,MAAA,MAAM,MAAA,EAA6B;AAAA,QAAC,SAAA;AAAA,QAAU,GAAI,OAAO,GAAA,CAAI,WAAA,IAAa,SAAA,GAAU,GAAA,CAAI,UAAA,CAAW,OAAA,GAAQ,KAAA,GAAM,CAAC,GAAA,CAAI,UAAA,CAAW,QAAA,CAAS,IAAI,EAAA,EAAE,EAAC,UAAA,EAAW,GAAA,CAAI,WAAU,EAAA,EAAE,CAAC,CAAA;AAAA,QAAG,KAAA,kBAAM,GAAA,uBAAI,KAAA,+BAAO,KAAA,qBAAM,CAAA,EAAE,GAAG,GAAA;AAAA,QAAE,KAAA,EAAM,GAAA,CAAI,KAAA;AAAA,QAAM,SAAA,EAAU,GAAA,CAAI,SAAA;AAAA,QAAU,cAAA,EAAe,GAAA,CAAI,cAAA;AAAA,QAAe,UAAA,EAAW,GAAA,CAAI,UAAA;AAAA,QAAW,KAAA;AAAA,QAC9S,MAAA,EAAO,CAAC,MAAA,GAAO,GAAA,CAAI,eAAA,IAAiB,KAAA,EAAA,GAAW,GAAA,CAAI,eAAA,GAAgB,GAAA,CAAI,EAAA,GAAG,GAAA,CAAI,EAAA,EAAE,GAAA,CAAI,eAAA,GAAgB,GAAA;AAAA,QAAO,GAAI,GAAA,CAAI,KAAA,GAAM,wBAAA,CAAyB,IAAA,CAAK,GAAA,CAAI,IAAI,EAAA,EAAE,EAAC,IAAA,EAAK,GAAA,CAAI,KAAI,EAAA,EAAE,CAAC;AAAA,MAAE,CAAA;AACxL,MAAA,GAAA,CAAG,KAAA,CAAM,KAAA,GAAM,GAAA,EAAK,KAAA,CAAM,MAAA,CAAO,KAAA,CAAM,IAAA,CAAK,CAAA,CAAE,IAAA,CAAK,CAAA,CAAE,KAAM,CAAA;AAAE,MAAA,KAAA,CAAM,GAAA,CAAI,GAAA,EAAI,KAAK,CAAA;AAAE,MAAA,OAAO,KAAA;AAAA,IAC7F,EAAA,MAAA,CAAQ,KAAA,EAAO;AACX,MAAA,MAAM,UAAA,kBAAW,KAAA,+BAA0B,MAAA,EAAK,KAAA,EAAK,UAAA,GAAW,wBAAA,CAAyB,IAAA,CAAK,SAAS,EAAA,EAAE,UAAA,EAAU,yBAAA;AACnH,MAAA,IAAI;AAAC,QAAA,GAAA,CAAI,EAAC,WAAA,EAAY,0CAAA,CAAW,EAAE,SAAA,EAAU,KAAA,EAAM,kBAAA,EAAmB,MAAA,EAAO,SAAA,EAAU,IAAA,EAAK,UAAA,EAAW,GAAA,CAAI,EAAA,EAAE,QAAO,CAAC,CAAA;AAAA,MAAE,EAAA,WAAQ;AAAA,MAA2D;AAC1L,MAAA,MAAM,MAAA,EAAM,CAAC,KAAA,EAAM,WAAA,EAAY,YAAA,EAAa,cAAA,EAAe,yBAAyB,CAAA,CAAE,QAAA,CAAS,IAAI,EAAA,EAAE,KAAA,CAAM,GAAA,CAAI,GAAG,EAAA,EAAE,KAAA,CAAA;AACpH,MAAA,OAAO,EAAC,GAAG,KAAA,EAAM,SAAA,EAAU,KAAA,mCAAM,KAAA,+BAAO,OAAA,UAAS,WAAA,EAAU,KAAA,EAAM,IAAA,EAAK,MAAA,EAAO,KAAA,EAAM,KAAI,CAAA;AAAA,IAC3F;AAAA,EACJ,CAAA;AACJ;AACA,MAAA,SAAe,aAAA,CAAc,IAAA,EAAqB,OAAA,EAAuC;AACrF,EAAA,MAAM,MAAA,8BAAA,CAAO,MAAM,IAAA,CAAK,OAAA,CAAQ,CAAA,CAAA,CAAG,IAAA,CAAK,CAAAC,MAAAA,EAAAA,GAAOA,MAAAA,CAAM,GAAA,IAAK,OAAO,CAAA,gBAAK,MAAM,IAAA,CAAK,IAAA,CAAK,OAAO,GAAA;AAC7F,EAAA,OAAO,EAAC,GAAG,KAAA,EAAM,KAAA,EAAM,CAAC,EAAC,CAAA;AAC7B;AACA,MAAA,SAAe,eAAA,CAAgB,IAAA,EAAqB,OAAA,EAAgD,KAAA,EAAmB,OAAA,EAAiC,KAAA,EAAmB,eAAA,EAAwC;AAC/M,EAAA,GAAA,iBAAG,OAAA,+BAAS,OAAA,IAAO,iBAAA,GAAkB,OAAA,CAAQ,SAAA,CAAU,OAAA,IAAS,eAAA,EAAiB,MAAA;AACjF,EAAA,GAAA,CAAG,CAAC,QAAA,GAAS,CAAC,OAAA,CAAQ,SAAA,CAAU,QAAA,EAAU,MAAM,IAAI,kCAAA,CAAY,+BAA+B,CAAA;AAC/F,EAAA,MAAM,KAAA,EAAK,KAAA,CAAM,KAAA,CAAM,IAAA,CAAK,CAAAC,KAAAA,EAAAA,GAAMA,KAAAA,CAAK,GAAA,IAAK,OAAA,CAAQ,MAAM,CAAA;AAAE,EAAA,GAAA,CAAG,CAAC,IAAA,EAAM,MAAM,IAAI,kCAAA,CAAY,gBAAgB,CAAA;AAC5G,EAAA,MAAM,IAAA,EAAI,4CAAA,yCAAa,KAAe,CAAC,CAAA,EAAG,YAAA,kBAAY,KAAA,uBAAM,OAAA,+BAAS,IAAA,qBAAK,CAAA,MAAA,EAAA,GAAQ,4CAAA,MAAmB,EAAA,IAAI,IAAA,mBAAK,MAAA,uBAAO,KAAA,+BAAO,QAAA,qBAAS,aAAa,GAAC,GAAA;AACnJ,EAAA,GAAA,CAAG,CAAC,YAAA,mBAAa,IAAA,uBAAK,KAAA,+BAAO,cAAA,IAAc,IAAA,GAAK,CAAA,CAAE,IAAA,CAAK,MAAA,IAAQ,KAAA,EAAA,GAAW,0CAAA,KAAW,EAAM,IAAI,CAAA,CAAE,IAAA,CAAK,CAAA,SAAA,EAAA,GAAW,4CAAA,SAAsB,EAAA,IAAI,GAAG,CAAA,CAAA,EAAI,MAAM,IAAI,kCAAA,CAAY,qCAAqC,CAAA;AAC7M,EAAA,MAAM,OAAA,EAAO,MAAA,CAAO,MAAA,CAAA,CAAQ,MAAM,IAAA,CAAK,QAAA,CAAS,KAAA,CAAM,EAAE,CAAA,CAAA,CAAG,UAAU,CAAA,CAAE,MAAA,CAAO,CAAA,QAAA,EAAA,GAAU,QAAA,CAAS,OAAA,IAAS,IAAA,CAAK,EAAE,CAAA,CAAE,IAAA,CAAK,CAAC,CAAA,EAAE,CAAA,EAAA,GAAI,CAAA,CAAE,QAAA,EAAQ,CAAA,CAAE,OAAO,CAAA,CAAE,CAAC,CAAA;AACrJ,EAAA,GAAA,CAAG,OAAA,GAAQ,OAAA,CAAQ,SAAA,CAAU,SAAA,IAAW,MAAA,CAAO,EAAA,EAAI,MAAM,IAAI,kCAAA,CAAY,0BAA0B,CAAA;AACnG,EAAA,GAAA,CAAG,OAAA,GAAQ,iBAAA,CAAkB,IAAA,CAAK,YAAA,EAAa,eAAe,CAAA,CAAE,IAAA,CAAK,CAAA,GAAA,EAAA,GAAK,GAAA,CAAI,SAAA,IAAW,MAAA,CAAO,GAAA,GAAI,GAAA,CAAI,GAAA,IAAK,OAAA,CAAQ,SAAA,CAAU,EAAE,CAAA,EAAG,MAAM,IAAI,kCAAA,CAAY,0BAA0B,CAAA;AACpL,EAAA,GAAA,CAAG,OAAA,CAAQ,MAAA,CAAO,gBAAA,EAAkB,OAAO,OAAA,CAAQ,MAAA,CAAO,gBAAA,CAAiB,KAAA,EAAM,OAAA,CAAQ,SAAA,CAAU,EAAE,CAAA;AACrG,EAAA,MAAM,MAAA,EAAM,MAAM,OAAA,CAAQ,MAAA,CAAO,OAAA,CAAQ,KAAA,EAAM,OAAA,CAAQ,SAAA,CAAU,EAAE,CAAA;AACnE,EAAA,GAAA,CAAG,KAAA,CAAM,UAAA,IAAY,OAAA,CAAQ,SAAA,CAAU,GAAA,GAAI,KAAA,CAAM,KAAA,EAAO,MAAM,IAAI,kCAAA,CAAY,+BAA+B,CAAA;AACjH;AH6HA;AACA;AIpMO,SAAS,0BAAA,CAA2B,OAAA,EAA4D;AACnG,EAAA,MAAM,EAAC,iBAAA,EAAmB,eAAA,EAAiB,GAAG,KAAI,EAAA,EAAI,OAAA;AACtD,EAAA,IAAI,QAAA;AACJ,EAAA,MAAM,QAAA,EAAQ,kDAAA;AAAW,IAAC,GAAG,IAAA;AAAA,IACzB,SAAA,EAAU,MAAA,CAAM,KAAA,EAAA,GAAO;AAAC,MAAA,MAAM,IAAA,CAAK,SAAA,CAAU,KAAK,CAAA;AAAE,MAAA,MAAM,QAAA,CAAS,QAAA,CAAS,KAAA,CAAM,KAAA,EAAM,KAAA,CAAM,OAAA,EAAQ,KAAA,CAAM,KAAK,CAAA;AAAA,IAAE;AAAA,EACvH,CAAC,CAAA;AACD,EAAA,SAAA,EAAS,2BAAA,CAA4B,OAAA,EAAQ,iBAAA,EAAkB,IAAA,CAAK,GAAA,EAAI,eAAe,CAAA;AACvF,EAAA,IAAI,SAAA,EAAW,KAAA;AACf,EAAA,MAAM,QAAA,kBAAU,IAAI,GAAA,CAAsB,CAAA;AAC1C,EAAA,MAAM,MAAA,EAAQ,CAAI,GAAA,EAAA,GAAsC;AACpD,IAAA,GAAA,CAAI,QAAA,EAAU,OAAO,OAAA,CAAQ,MAAA,CAAO,IAAI,kCAAA,CAAY,kBAAkB,CAAC,CAAA;AACvE,IAAA,MAAM,KAAA,EAAO,OAAA,CAAQ,OAAA,CAAQ,CAAA,CAAE,IAAA,CAAK,GAAG,CAAA,CAAE,OAAA,CAAQ,CAAA,EAAA,GAAM;AAAC,MAAA,OAAA,CAAQ,MAAA,CAAO,IAAI,CAAA;AAAA,IAAE,CAAC,CAAA;AAC9E,IAAA,OAAA,CAAQ,GAAA,CAAI,IAAI,CAAA;AAAG,IAAA,OAAO,IAAA;AAAA,EAC9B,CAAA;AACA,EAAA,MAAM,QAAA,EAAU,MAAA,CAAA,EAAA,GAAY;AACxB,IAAA,SAAA,EAAW,IAAA;AACX,IAAA,MAAM,OAAA,CAAQ,UAAA,CAAW,CAAC,GAAG,OAAO,CAAC,CAAA;AACrC,IAAA,MAAM,OAAA,CAAQ,OAAA,CAAQ,CAAA;AAAA,EAC1B,CAAA;AACA,EAAA,OAAO;AAAA,IACH,GAAG,WAAA,CAAY,OAAA,EAAS,KAAK,CAAA;AAAA,IAC7B,aAAA,EAAe,CAAA,GAAI,IAAA,EAAA,GAAS,KAAA,CAAM,CAAA,EAAA,GAAM,QAAA,CAAS,aAAA,CAAc,GAAG,IAAI,CAAC,CAAA;AAAA,IACvE,gBAAA,EAAkB,CAAA,GAAI,IAAA,EAAA,GAAS,KAAA,CAAM,CAAA,EAAA,GAAM,QAAA,CAAS,gBAAA,CAAiB,GAAG,IAAI,CAAC,CAAA;AAAA,IAC7E,OAAA,EAAS,CAAA,SAAA,EAAA,GAAa,KAAA,CAAM,CAAA,EAAA,GAAM,aAAA,CAAc,OAAA,EAAS,eAAA,EAAiB,SAAS,CAAC,CAAA;AAAA,IACpF,OAAA;AAAA,IAAS,OAAA,EAAS;AAAA,EACtB,CAAA;AACJ;AAEA,SAAS,WAAA,CAAY,OAAA,EAAqB,KAAA,EAAsG;AAC5I,EAAA,OAAO;AAAA,IACH,MAAA,EAAQ,CAAC,KAAA,EAAA,GAAU,KAAA,CAAM,CAAA,EAAA,GAAM,OAAA,CAAQ,MAAA,CAAO,KAAK,CAAC,CAAA;AAAA,IACpD,IAAA,EAAM,CAAC,EAAA,EAAA,GAAO,KAAA,CAAM,CAAA,EAAA,GAAM,OAAA,CAAQ,IAAA,CAAK,EAAE,CAAC,CAAA;AAAA,IAC1C,IAAA,EAAM,CAAA,EAAA,GAAM,KAAA,CAAM,CAAA,EAAA,GAAM,OAAA,CAAQ,IAAA,CAAK,CAAC,CAAA;AAAA,IACtC,OAAA,EAAS,CAAA,EAAA,GAAM,KAAA,CAAM,CAAA,EAAA,GAAM,OAAA,CAAQ,OAAA,CAAQ,CAAC,CAAA;AAAA,IAC5C,OAAA,EAAS,CAAC,EAAA,EAAI,OAAA,EAAA,GAAY,KAAA,CAAM,CAAA,EAAA,GAAM,OAAA,CAAQ,OAAA,CAAQ,EAAA,EAAI,OAAO,CAAC,CAAA;AAAA,IAClE,MAAA,EAAQ,CAAC,EAAA,EAAI,KAAA,EAAO,KAAA,EAAA,GAAU,KAAA,CAAM,CAAA,EAAA,GAAM,OAAA,CAAQ,MAAA,CAAO,EAAA,EAAI,KAAA,EAAO,KAAK,CAAC,CAAA;AAAA,IAC1E,KAAA,EAAO,CAAC,EAAA,EAAI,KAAA,EAAA,GAAU,KAAA,CAAM,CAAA,EAAA,GAAM,OAAA,CAAQ,KAAA,CAAM,EAAA,EAAI,KAAK,CAAC,CAAA;AAAA,IAC1D,IAAA,EAAM,CAAC,EAAA,EAAI,IAAA,EAAA,GAAS,KAAA,CAAM,CAAA,EAAA,GAAM,OAAA,CAAQ,IAAA,CAAK,EAAA,EAAI,IAAI,CAAC,CAAA;AAAA,IACtD,QAAA,EAAU,CAAC,EAAA,EAAA,GAAO,KAAA,CAAM,CAAA,EAAA,GAAM,OAAA,CAAQ,QAAA,CAAS,EAAE,CAAC,CAAA;AAAA,IAClD,IAAA,EAAM,CAAA,EAAA,GAAM,KAAA,CAAM,CAAA,EAAA,GAAM,OAAA,CAAQ,IAAA,CAAK,CAAC,CAAA;AAAA,IACtC,QAAA,EAAU,CAAC,EAAA,EAAA,GAAO,KAAA,CAAM,CAAA,EAAA,GAAM,OAAA,CAAQ,QAAA,CAAS,EAAE,CAAC,CAAA;AAAA,IAClD,OAAA,EAAS,CAAC,SAAA,EAAA,GAAc,KAAA,CAAM,CAAA,EAAA,GAAM,OAAA,CAAQ,OAAA,CAAQ,SAAS,CAAC,CAAA;AAAA,IAC9D,OAAA,EAAS,CAAC,EAAA,EAAI,KAAA,EAAA,GAAU,KAAA,CAAM,CAAA,EAAA,GAAM,OAAA,CAAQ,OAAA,CAAQ,EAAA,EAAI,KAAK,CAAC,CAAA;AAAA,IAC9D,OAAA,EAAS,CAAC,EAAA,EAAI,KAAA,EAAA,GAAU,KAAA,CAAM,CAAA,EAAA,GAAM,OAAA,CAAQ,OAAA,CAAQ,EAAA,EAAI,KAAK,CAAC,CAAA;AAAA,IAC9D,MAAA,EAAQ,CAAC,EAAA,EAAI,MAAA,EAAA,GAAW,KAAA,CAAM,CAAA,EAAA,GAAM,OAAA,CAAQ,MAAA,CAAO,EAAA,EAAI,MAAM,CAAC,CAAA;AAAA,IAC9D,gBAAA,EAAkB,CAAA,EAAA,GAAM,KAAA,CAAM,CAAA,EAAA,GAAM,OAAA,CAAQ,gBAAA,CAAiB,CAAC;AAAA,EAClE,CAAA;AACJ;AACA,MAAA,SAAe,aAAA,CAAc,OAAA,EAAqB,eAAA,EAAyB,SAAA,EAAmB;AAC1F,EAAA,MAAM,OAAA,EAAS,MAAM,OAAA,CAAQ,OAAA,CAAQ,SAAS,CAAA;AAC9C,EAAA,IAAA,CAAA,MAAW,MAAA,GAAS,MAAM,OAAA,CAAQ,OAAA,CAAQ,CAAA,EAAG;AACzC,IAAA,GAAA,CAAI,MAAA,CAAO,IAAA,CAAK,CAAA,GAAA,EAAA,GAAO,GAAA,CAAI,GAAA,IAAO,KAAA,CAAM,EAAE,CAAA,EAAG,QAAA;AAC7C,IAAA,MAAM,QAAA,EAAU,MAAM,OAAA,CAAQ,KAAA,CAAM,KAAA,CAAM,EAAA,EAAI,EAAC,IAAA,EAAM,KAAA,EAAO,SAAA,EAAW,EAAC,MAAA,EAAQ,eAAA,EAAiB,EAAA,EAAI,UAAS,CAAA,EAAG,KAAA,EAAO,EAAC,CAAC,CAAA;AAC1H,IAAA,GAAA,CAAI,OAAA,CAAQ,KAAA,EAAO,MAAA,CAAO,IAAA,CAAK,MAAM,OAAA,CAAQ,IAAA,CAAK,KAAA,CAAM,EAAE,CAAC,CAAA;AAAA,EAC/D;AACA,EAAA,OAAO,MAAA;AACX;AJ6MA;AACA;AACE;AACA;AACF,+GAAC","file":"/home/li/share/prj/x1/libraries/kanban/dist/chunk-5Q7WB63A.cjs","sourcesContent":[null,"import {sha256HexSync} from './utils';\nimport type {KanbanService, KanbanSessionActivityQuery, KanbanSessionItemPage, KanbanSessionItemSummary} from './contracts';\nimport {KanbanError} from './ports';\n/** Filter before pagination; Session activity changes invalidate the filtered keyset. */\nexport async function querySessionItems(core: KanbanService, boardId: string, input: KanbanSessionActivityQuery,\n project: (rows: KanbanSessionItemSummary[])=>Promise<KanbanSessionItemSummary[]>): Promise<KanbanSessionItemPage> {\n const {execution='all',...query}=input;\n if(!['all','running','recent','active'].includes(execution)) throw new KanbanError('INVALID_EXECUTION_FILTER');\n if(execution==='all') {const page=await core.query(boardId,query);return {...page,items:await project(page.items)};}\n const {cursor,limit=50,...filters}=query;\n if(!Number.isSafeInteger(limit)||limit<1||limit>200) throw new KanbanError('INVALID_PAGE_SIZE');\n let page=await core.query(boardId,{...filters,limit:200}), rows=[...page.items];const revision=page.revision;\n while(page.nextCursor) {\n if(rows.length>=10000) throw new KanbanError('ACTIVITY_QUERY_LIMIT');\n page=await core.query(boardId,{...filters,limit:200,cursor:page.nextCursor});\n if(page.revision!==revision) throw new KanbanError('CURSOR_STALE');rows.push(...page.items);\n }\n const matching=(await project(rows)).filter(row=>matchesExecution(row,execution));\n if((await core.query(boardId,{...filters,limit:1})).revision!==revision) throw new KanbanError('CURSOR_STALE');\n const scope=sha256HexSync(JSON.stringify({filters,execution,limit})), signature=sha256HexSync(JSON.stringify(matching.map(row=>row.id)));\n let start=0;\n if(cursor) {\n let saved;try {saved=JSON.parse(cursor);} catch {throw new KanbanError('INVALID_CURSOR');}\n if(saved.scope!==scope) throw new KanbanError('CURSOR_SCOPE_MISMATCH');\n if(saved.revision!==revision||saved.signature!==signature) throw new KanbanError('CURSOR_STALE');\n start=matching.findIndex(row=>row.id===saved.after)+1;if(start<1) throw new KanbanError('INVALID_CURSOR');\n }\n const items=matching.slice(start,start+limit);\n return {revision,total:matching.length,items,...(start+items.length<matching.length?{nextCursor:JSON.stringify({scope,revision,signature,after:items.at(-1)!.id})}: {})};\n}\nfunction matchesExecution(row: KanbanSessionItemSummary, filter: string): boolean {\n const session=row.execution;if(!session||session.stale) return false;\n return filter==='running'?session.state==='running':filter==='recent'?session.recent:session.state==='running'||session.recent;\n}\n","import type {KanbanItem, KanbanExternalReference, KanbanWorkflowState, KanbanSessionAssociation, KanbanRelatedSession, KanbanSessionExecution, KanbanExecutionSession} from './contracts';\n\nexport function sessionAssociations(item: KanbanItem, bindings: KanbanExternalReference[], workflow: KanbanWorkflowState): KanbanSessionAssociation[] {\n return [...bindings.map(ref => {\n const dispatch = workflow.dispatches[ref.revision ?? ''];\n const execution: KanbanSessionExecution | undefined = dispatch?.itemId === item.id ? {\n id: dispatch.id, purpose: 'execution', dispatchId: dispatch.id, attempt: dispatch.attempt,\n outcome: dispatch.outcome, createdAt: dispatch.preparedAt, code: dispatch.code,\n ...(dispatch.continuation ? {previousDispatchId: dispatch.continuation.previousDispatchId} : {}),\n } : undefined;\n return {sessionId: ref.id, purpose: 'execution' as const, ...(execution ? {execution} : {})};\n }), ...item.participants.filter(row => !bindings.some(ref => ref.id === row.sessionId)).map(row => ({sessionId: row.sessionId, purpose: 'discussion' as const}))];\n}\n\n/** Session identity and run identity are independent; neither activity nor a hook selects the primary. */\nexport async function projectRelatedSessions(associations: KanbanSessionAssociation[], currentId: string | undefined,\n inspect: (id: string) => Promise<KanbanExecutionSession>): Promise<KanbanRelatedSession[]> {\n const grouped = new Map<string, {purposes: Set<KanbanSessionAssociation['purpose']>; executions: Map<string, KanbanSessionExecution>}>();\n for (const row of associations) {\n let group = grouped.get(row.sessionId);\n if (!group) grouped.set(row.sessionId, group = {purposes: new Set(), executions: new Map()});\n group.purposes.add(row.purpose);\n if (row.execution) group.executions.set(row.execution.id, {...group.executions.get(row.execution.id), ...row.execution});\n }\n const rows: KanbanRelatedSession[] = [], entries = [...grouped]; let next = 0;\n await Promise.all(Array.from({length: Math.min(entries.length, 8)}, async () => {\n while (next < entries.length) {\n const [sessionId, group] = entries[next++], state = await inspect(sessionId);\n rows.push({...state, current: sessionId === currentId, purposes: [...group.purposes].sort(),\n executions: [...group.executions.values()].sort((a, b) => (a.createdAt ?? 0) - (b.createdAt ?? 0) || a.id.localeCompare(b.id))});\n }\n }));\n return rows.sort((a, b) => Number(b.current) - Number(a.current) || a.sessionId.localeCompare(b.sessionId));\n}\n","import type {KanbanBoard, KanbanCommand, KanbanActor, KanbanService, KanbanExecutionSession, KanbanExternalReference, KanbanSessionItemSummary, KanbanWorkflowState} from './contracts';\nimport type {KanbanSessionSource} from './activity-ports';\nimport {principal,principalKey,candidates} from './identity';\nimport {KanbanError} from './ports';\nimport {querySessionItems} from './session-activity-query';\nimport {randomUUID} from './utils';\nimport {sessionAssociations, projectRelatedSessions} from './session-relations';\nexport interface KanbanSessionActivityOptions {source: KanbanSessionSource; now?:()=>number}\nexport function executionBindings(refs: KanbanExternalReference[] | undefined, referenceSystem: string) {return (refs ?? []).filter(ref=>ref.system===referenceSystem);}\nfunction currentBinding(refs: KanbanExternalReference[]|undefined, itemId:string, workflow:KanbanWorkflowState, referenceSystem: string) {\n const binding=executionBindings(refs, referenceSystem).at(-1),latest=Object.values(workflow.dispatches).filter(dispatch=>dispatch.itemId===itemId).sort((a,b)=>b.attempt-a.attempt)[0];\n if(!binding||!latest||binding.revision===latest.id) return binding;\n return ['prepared','running','unknown','succeeded'].includes(latest.outcome)||workflow.dispatches[binding.revision ?? '']?undefined:binding;\n}\n\n/** Optional resource projection; access checks remain owned by the injected source. */\nexport function createKanbanSessionActivity(core: KanbanService, options: KanbanSessionActivityOptions | undefined, log: (event: {operationId:string;sessionId?:string;stage:string;result:'failure';code:string;durationMs:number})=>void, referenceSystem: string) {\n const inspect=createSessionInspector(options,log);\n const project=async(boardId:string,rows:KanbanSessionItemSummary[])=>{\n if(!rows.some(row=>executionBindings(row.externalRefs,referenceSystem).length))return rows;\n const [board,workflow]=await Promise.all([boardMetadata(core,boardId),core.workflow(boardId)]), bindings=new Map(rows.map(row=>[row.id,currentBinding(row.externalRefs,row.id,workflow,referenceSystem)]));\n const ids=[...new Set([...bindings.values()].flatMap(ref=>ref?[ref.id]:[]))], states=new Map<string,KanbanExecutionSession>();let next=0;\n await Promise.all(Array.from({length:Math.min(ids.length,8)},async()=>{while(next<ids.length) {const id=ids[next++];states.set(id,await inspect(board,id));}}));\n return rows.map(row=>{const binding=bindings.get(row.id);return {...row,...(binding?{execution:states.get(binding.id)}: {})};});\n };\n return {\n queryActivity:(boardId:string,query:import('./contracts').KanbanSessionActivityQuery={})=>querySessionItems(core,boardId,query,rows=>project(boardId,rows)),\n async executionSession(boardId:string,itemId:string, query: import('./contracts').KanbanSessionDetailQuery = {}) {\n const started = Date.now();\n if (!query || typeof query !== 'object' || Array.isArray(query) || Object.keys(query).some(key => key !== 'includeRelated') || query.includeRelated !== undefined && typeof query.includeRelated !== 'boolean') throw new KanbanError('INVALID_QUERY');\n const {item}=await core.item(boardId,itemId),bindings=executionBindings(item.externalRefs,referenceSystem);\n if(!bindings.length && !query.includeRelated)return {history:[]};\n const [board,workflow]=await Promise.all([boardMetadata(core,boardId),core.workflow(boardId)]),last=currentBinding(item.externalRefs,itemId,workflow,referenceSystem);\n let sessionsCode: string | undefined;\n const related = query.includeRelated ? await options?.source.related?.(board, item, workflow).catch(error => {\n const candidate = (error as {code?: string})?.code;\n sessionsCode = candidate && /^[A-Z][A-Z0-9_]{0,79}$/.test(candidate) ? candidate : 'SESSION_RELATIONS_FAILED';\n try {log({operationId: randomUUID(), stage: 'session.relations', result: 'failure', code: sessionsCode, durationMs: Date.now() - started});} catch { /* Diagnostics cannot hide known associations. */ }\n return [];\n }) : [];\n const sessions = query.includeRelated ? await projectRelatedSessions([\n ...sessionAssociations(item, bindings, workflow), ...related ?? [],\n ], last?.id, id => inspect(board, id)) : undefined;\n return {current:last?(sessions?.find(row=>row.sessionId===last.id) ?? await inspect(board,last.id)):undefined,\n history:bindings.map(ref=>({sessionId:ref.id,bindingId:ref.revision,current:ref===last})).reverse(), ...(sessions ? {sessions} : {}), ...(sessionsCode ? {sessionsCode} : {})};\n },\n validate:(board:KanbanBoard,command:KanbanCommand|undefined,actor:KanbanActor)=>validateBinding(core,options,board,command,actor,referenceSystem),\n };\n}\nfunction createSessionInspector(options:KanbanSessionActivityOptions|undefined,log:Parameters<typeof createKanbanSessionActivity>[2]) {\n const now=options?.now ?? Date.now, cache=new Map<string,KanbanExecutionSession>();\n return async(board:KanbanBoard,sessionId:string):Promise<KanbanExecutionSession>=>{\n const started=now(),key=JSON.stringify([board.id,sessionId]);\n try {\n if(!options) throw new KanbanError('EXECUTION_SESSION_UNAVAILABLE');\n const row=await options.source.inspect(board,sessionId);\n if(row.sessionId!==sessionId) throw new KanbanError('SESSION_ACTIVITY_SCOPE_MISMATCH');\n const stale=row.stale||row.observedAt===undefined||now()-row.observedAt>90000;\n const value:KanbanExecutionSession={sessionId,...(typeof row.resourceId==='string'&&row.resourceId.length<=4096&&!row.resourceId.includes('\\0')?{resourceId:row.resourceId}:{}),title:row.title?.slice(0,256),state:row.state,createdAt:row.createdAt,lastActivityAt:row.lastActivityAt,observedAt:row.observedAt,stale,\n recent:!stale&&row.lastActivityAt!==undefined&&row.lastActivityAt<=now()&&now()-row.lastActivityAt<=600000,...(row.code&&/^[A-Z][A-Z0-9_]{0,79}$/.test(row.code)?{code:row.code}:{})};\n if(cache.size>=256) cache.delete(cache.keys().next().value!);cache.set(key,value);return value;\n } catch(error) {\n const candidate=(error as {code?:string})?.code,code=candidate&&/^[A-Z][A-Z0-9_]{0,79}$/.test(candidate)?candidate:'SESSION_ACTIVITY_FAILED';\n try {log({operationId:randomUUID(),sessionId,stage:'session.activity',result:'failure',code,durationMs:now()-started});} catch { /* Observation diagnostics cannot change assignments. */ }\n const prior=['EIO','ETIMEDOUT','ECONNRESET','ECONNREFUSED','SESSION_ACTIVITY_FAILED'].includes(code)?cache.get(key):undefined;\n return {...prior,sessionId,state:prior?.state ?? 'unknown',stale:true,recent:false,code};\n }\n };\n}\nasync function boardMetadata(core: KanbanService, boardId: string): Promise<KanbanBoard> {\n const board=(await core.catalog()).find(board=>board.id===boardId) ?? await core.read(boardId);\n return {...board,items:[]};\n}\nasync function validateBinding(core: KanbanService, options:KanbanSessionActivityOptions|undefined, board:KanbanBoard, command:KanbanCommand|undefined, actor:KanbanActor, referenceSystem: string): Promise<void> {\n if(command?.type!=='link-reference'||command.reference.system!==referenceSystem) return;\n if(!options||!command.reference.revision) throw new KanbanError('EXECUTION_SESSION_UNAVAILABLE');\n const item=board.items.find(item=>item.id===command.itemId);if(!item) throw new KanbanError('ITEM_NOT_FOUND');\n const key=principalKey(principal(actor)), coordinator=board.members?.some(member=>principalKey(member)===key&&member.roles?.includes('coordinator'));\n if(!coordinator&&item.owner?.principalId!==key&&!(item.owner===undefined&&candidates(board,item).some(candidate=>principalKey(candidate)===key))) throw new KanbanError('EXECUTION_SESSION_ASSIGNMENT_DENIED');\n const active=Object.values((await core.workflow(board.id)).dispatches).filter(dispatch=>dispatch.itemId===item.id).sort((a,b)=>b.attempt-a.attempt)[0];\n if(active&&command.reference.revision!==active.id) throw new KanbanError('EXECUTION_SESSION_LOCKED');\n if(active&&executionBindings(item.externalRefs,referenceSystem).some(ref=>ref.revision===active.id&&ref.id!==command.reference.id)) throw new KanbanError('EXECUTION_SESSION_LOCKED');\n if(options.source.authorizeBinding) return options.source.authorizeBinding(board,command.reference.id);\n const state=await options.source.inspect(board,command.reference.id);\n if(state.sessionId!==command.reference.id||state.stale) throw new KanbanError('EXECUTION_SESSION_UNAVAILABLE');\n}\n","import {createKanbanModule as createCore, type KanbanModuleHandle as CoreHandle} from './module';\nimport type {KanbanModuleOptions} from './ports';\nimport {KanbanError} from './ports';\nimport type {KanbanSessionActivityQuery, KanbanSessionItemPage, KanbanExecutionSessionDetail} from './contracts';\nimport {createKanbanSessionActivity, type KanbanSessionActivityOptions} from './session-activity';\nexport interface KanbanActivityModuleOptions extends KanbanModuleOptions {\n executionSessions?: KanbanSessionActivityOptions;\n referenceSystem: string;\n}\nexport interface KanbanActivityHandle extends CoreHandle {\n queryActivity: (boardId: string, query?: KanbanSessionActivityQuery) => Promise<KanbanSessionItemPage>;\n executionSession: (boardId: string, itemId: string, query?: import('./contracts').KanbanSessionDetailQuery) => Promise<KanbanExecutionSessionDetail>;\n}\n\n/** Application integrations stay outside the portable core. */\nexport function createKanbanActivityModule(options: KanbanActivityModuleOptions): KanbanActivityHandle {\n const {executionSessions, referenceSystem, ...core} = options;\n let activity: ReturnType<typeof createKanbanSessionActivity>;\n const service=createCore({...core,\n authorize:async input=>{await core.authorize(input);await activity.validate(input.board,input.command,input.actor);},\n });\n activity=createKanbanSessionActivity(service,executionSessions,core.log,referenceSystem);\n let stopping = false;\n const pending = new Set<Promise<unknown>>();\n const track = <T>(run: () => Promise<T>): Promise<T> => {\n if (stopping) return Promise.reject(new KanbanError('SERVICE_STOPPING'));\n const work = Promise.resolve().then(run).finally(() => {pending.delete(work);});\n pending.add(work); return work;\n };\n const quiesce = async () => {\n stopping = true;\n await Promise.allSettled([...pending]);\n await service.quiesce();\n };\n return {\n ...forwardCore(service, track),\n queryActivity: (...args) => track(() => activity.queryActivity(...args)),\n executionSession: (...args) => track(() => activity.executionSession(...args)),\n related: sessionId => track(() => relatedBoards(service, referenceSystem, sessionId)),\n quiesce, dispose: quiesce,\n };\n}\n\nfunction forwardCore(service: CoreHandle, track: <T>(run: () => Promise<T>) => Promise<T>): Omit<CoreHandle, 'related' | 'quiesce' | 'dispose'> {\n return {\n create: (input) => track(() => service.create(input)),\n read: (id) => track(() => service.read(id)),\n list: () => track(() => service.list()),\n catalog: () => track(() => service.catalog()),\n execute: (id, request) => track(() => service.execute(id, request)),\n events: (id, after, limit) => track(() => service.events(id, after, limit)),\n query: (id, query) => track(() => service.query(id, query)),\n item: (id, item) => track(() => service.item(id, item)),\n overview: (id) => track(() => service.overview(id)),\n scan: () => track(() => service.scan()),\n workflow: (id) => track(() => service.workflow(id)),\n resolve: (reference) => track(() => service.resolve(reference)),\n suggest: (id, query) => track(() => service.suggest(id, query)),\n records: (id, query) => track(() => service.records(id, query)),\n record: (id, record) => track(() => service.record(id, record)),\n currentPrincipal: () => track(() => service.currentPrincipal()),\n };\n}\nasync function relatedBoards(service: CoreHandle, referenceSystem: string, sessionId: string) {\n const boards = await service.related(sessionId);\n for (const board of await service.catalog()) {\n if (boards.some(old => old.id === board.id)) continue;\n const matches = await service.query(board.id, {view: 'all', reference: {system: referenceSystem, id: sessionId}, limit: 1});\n if (matches.total) boards.push(await service.read(board.id));\n }\n return boards;\n}\n"]}
|
|
@@ -55,4 +55,4 @@ function sameAutomationBinding(left, right) {
|
|
|
55
55
|
|
|
56
56
|
|
|
57
57
|
exports.kanbanReference = kanbanReference; exports.DEFAULT_KANBAN_WORK_TYPES = DEFAULT_KANBAN_WORK_TYPES; exports.executableWorkItem = executableWorkItem; exports.DEFAULT_KANBAN_SCAN_POLICY = DEFAULT_KANBAN_SCAN_POLICY; exports.sameAutomationBinding = sameAutomationBinding;
|
|
58
|
-
//# sourceMappingURL=chunk-
|
|
58
|
+
//# sourceMappingURL=chunk-7KDOTBRX.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["/home/li/share/prj/x1/libraries/kanban/dist/chunk-7KDOTBRX.cjs","../src/contracts/references.ts","../src/contracts/configuration.ts","../src/contracts/discovery.ts","../src/contracts/automation.ts"],"names":[],"mappings":"AAAA;ACGO,SAAS,eAAA,CAAgB,KAAA,EAAsC,MAAA,EAA2E;AAC7I,EAAA,MAAM,OAAA,EAAS,KAAA,CAAM,OAAA,EAAS,CAAA,GAAA,EAAM,KAAA,CAAM,MAAM,CAAA,EAAA;AAC5B,EAAA;AAC6B,EAAA;AACR,EAAA;AAC7C;ADDmD;AACA;AECiB;AACrB,EAAA;AACF,EAAA;AACF,EAAA;AACQ,EAAA;AACJ,EAAA;AAC/C;AAKiK;AAC3H,EAAA;AAEtC;AFJmD;AACA;AGO6B;AACpE,EAAA;AAAyB,EAAA;AAAmB,EAAA;AAAyB,EAAA;AAAe,EAAA;AAAoB,EAAA;AACpH;AHAmD;AACA;AIT+D;AACvC,EAAA;AAAiB,oBAAA;AAAwB,oBAAA;AAAoB,oBAAA;AAC/G,oBAAA;AAAyB,oBAAA;AAAqB,oBAAA;AAA8B,oBAAA;AAA0B,oBAAA;AACxG,oBAAA;AAAqB,oBAAA;AAAW,oBAAA;AAAmB,oBAAA;AAA2D,IAAA;AAAyC,EAAA;AAChI,EAAA;AAC9C;AJuBmD;AACA;AACA;AACA;AACA;AACA;AACA;AACA","file":"/home/li/share/prj/x1/libraries/kanban/dist/chunk-7KDOTBRX.cjs","sourcesContent":[null,"import type {KanbanBoard} from './contracts';\n\nexport interface KanbanReferenceTarget {boardId: string; itemId?: string; recordId?: string; reference: string; scope: KanbanBoard['scope']}\nexport function kanbanReference(board: {id: string; number?: number}, entity?: {id: string; number?: number; kind?: 'log' | 'decision'}): string {\n const prefix = board.number ? `KB-${board.number}` : board.id;\n if (!entity) return prefix;\n if (!entity.number) return `${prefix}/${entity.id}`;\n return entity.kind ? `${prefix}/${entity.kind === 'log' ? 'L' : 'D'}-${entity.number}` : `${prefix}#${entity.number}`;\n}\n","import type {KanbanItem, KanbanBoard} from './contracts';\n\nexport interface KanbanPrincipal {kind: 'agent' | 'human' | 'service'; id: string}\nexport interface KanbanMember extends KanbanPrincipal {\n responsibility: string; roles?: Array<'worker' | 'reviewer' | 'coordinator'>;\n}\nexport interface KanbanWorkType {id: string; label: string; rank: number; executable: boolean}\nexport interface KanbanColumn {id: string; label: string; states: KanbanItem['status'][]}\nexport interface KanbanNotificationPolicy {rules?: Record<string, 'info' | 'error' | 'none'>}\nexport const DEFAULT_KANBAN_WORK_TYPES: readonly KanbanWorkType[] = [\n {id: 'initiative', label: 'Goal', rank: 0, executable: false},\n {id: 'feature', label: 'Group', rank: 1, executable: false},\n {id: 'task', label: 'Action', rank: 2, executable: true},\n {id: 'fix', label: 'Fix', rank: 2, executable: true},\n {id: 'subtask', label: 'Subtask', rank: 3, executable: true},\n];\n\nexport interface KanbanExternalReference {system: string; id: string; revision?: string}\n\n/** A composite work item delegates execution to its children. */\nexport function executableWorkItem(board:Pick<KanbanBoard,'workTypes'|'defaultWorkType'>, item:{planning?:{kind:string;execution?:'direct'|'children'}}):boolean {\n return item.planning?.execution!=='children'&&(board.workTypes??DEFAULT_KANBAN_WORK_TYPES)\n .some(type=>type.id===(item.planning?.kind??board.defaultWorkType??'task')&&type.executable);\n}\n","import type {KanbanItemSummary} from './planning';\nimport type {KanbanBoard} from './contracts';\n\nexport type {KanbanSourceRef, KanbanDiscoveryChange, KanbanDiscoveryBatch} from './source';\nimport type {KanbanDiscoveryChange} from './source';\nexport interface KanbanScanSession {\n id: string; revision: string; updatedAt: number | null; idleSince: number | null;\n activity: 'idle' | 'active' | 'waiting' | 'unknown'; archived: boolean; scannerOwned?: boolean;\n}\nexport interface KanbanScanText {\n session: KanbanScanSession; complete: boolean;\n messages: Array<{id: string; role: 'user' | 'assistant'; text: string}>;\n}\nexport interface KanbanScanConnection {\n kind: 'local' | 'remote'; connectionId: string;\n /** Explicit consent for moving source text to a different execution boundary. */\n allowContentTransfer: boolean;\n}\nexport interface KanbanScanPolicy {\n idleMs: number; includeArchived: boolean; maxSessions: number; maxInputBytes: number; leaseMs: number;\n autoCreate: boolean; connection: KanbanScanConnection;\n}\nexport interface KanbanScanInput {\n projectContext?: {totalRecords: number; excludedRecords?: number; omittedRecords: number; records: import('./context').KanbanProjectRecord[]};\n context?: {totalItems: number; omittedItems: number; archivedTotal: number; archivedItems: KanbanItemSummary[]};\n runId: string; executorId: string; board: KanbanBoard; sessions: KanbanScanText[]; connection: KanbanScanConnection;\n}\nexport const DEFAULT_KANBAN_SCAN_POLICY: Omit<KanbanScanPolicy, 'connection'> = {\n idleMs: 300000, includeArchived: true, maxSessions: 20, maxInputBytes: 128 * 1024, leaseMs: 600000, autoCreate: false,\n};\n\nexport interface KanbanDiscoveryResult {changes: KanbanDiscoveryChange[]; records?: import('./context').KanbanRecordInput[]}\n","import type {KanbanExternalReference, KanbanPrincipal} from './configuration';\n\nexport interface KanbanAutomationSettings {\n preparation?: KanbanExternalReference;\n preparationOptions?: Record<string, string>;\n enabled: boolean; planner: KanbanExternalReference; executor: KanbanExternalReference;\n coordinator: KanbanPrincipal; worker: KanbanPrincipal; autoAccept: boolean;\n}\nexport interface KanbanAutomationOption {\n name: string; label: string; defaultValue?: string;\n choices?: Array<{value: string; label: string}>;\n}\nexport interface KanbanAutomationTarget {reference: KanbanExternalReference; label: string; options?: KanbanAutomationOption[]}\nexport interface KanbanAutomationCatalog {\n preparations?: KanbanAutomationTarget[];\n targets: KanbanAutomationTarget[]; coordinator: KanbanPrincipal; worker: KanbanPrincipal;\n}\nexport interface KanbanAnalysisStatus {\n itemId: string; state: 'analyzing' | 'ready' | 'clarification' | 'failed' | 'unknown';\n reason?: string; code?: string; dependencies?: string[];\n}\nexport function sameAutomationBinding(left?: KanbanAutomationSettings, right?: KanbanAutomationSettings): boolean {\n const signature = (value?: KanbanAutomationSettings) => JSON.stringify([value?.planner?.system, value?.planner?.id, value?.planner?.revision,\n value?.executor?.system, value?.executor?.id, value?.executor?.revision, value?.coordinator?.kind, value?.coordinator?.id,\n value?.worker?.kind, value?.worker?.id, value?.autoAccept, value?.preparation, Object.entries(value?.preparationOptions ?? {}).sort(([a], [b]) => a.localeCompare(b))]);\n return signature(left) === signature(right);\n}\n"]}
|
|
@@ -17,10 +17,10 @@ import {
|
|
|
17
17
|
rowKeys,
|
|
18
18
|
verifyReceipt,
|
|
19
19
|
viewFromState
|
|
20
|
-
} from "./chunk-
|
|
20
|
+
} from "./chunk-XKDZHAUE.js";
|
|
21
21
|
import {
|
|
22
22
|
KanbanError
|
|
23
|
-
} from "./chunk-
|
|
23
|
+
} from "./chunk-M35X5PHO.js";
|
|
24
24
|
|
|
25
25
|
// src/store.ts
|
|
26
26
|
import { FSError } from "@nestos/vfs-core";
|
|
@@ -145,4 +145,4 @@ async function commitBoardNumber(tx, path, id, before, next, encoded) {
|
|
|
145
145
|
export {
|
|
146
146
|
SeqKanbanStore
|
|
147
147
|
};
|
|
148
|
-
//# sourceMappingURL=chunk-
|
|
148
|
+
//# sourceMappingURL=chunk-AHHEGTUA.js.map
|
|
@@ -0,0 +1,95 @@
|
|
|
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/board-control.ts
|
|
2
|
+
function boardAllowsStart(board, item) {
|
|
3
|
+
return !board.lifecycle && !_optionalChain([board, 'access', _ => _.executionControl, 'optionalAccess', _2 => _2.paused]) && (_optionalChain([board, 'access', _3 => _3.executionControl, 'optionalAccess', _4 => _4.mode]) !== "manual" || _optionalChain([item, 'optionalAccess', _5 => _5.launch, 'optionalAccess', _6 => _6.requestedAt]) !== void 0);
|
|
4
|
+
}
|
|
5
|
+
function boardControlPhase(board) {
|
|
6
|
+
if (board.lifecycle) return board.lifecycle.intent === "delete" ? "waiting-deletion" : board.lifecycle.phase === "ready" ? "cancelled" : "cancelling";
|
|
7
|
+
const policy = board.executionControl;
|
|
8
|
+
const controls = Object.entries(_nullishCoalesce(_optionalChain([policy, 'optionalAccess', _7 => _7.controls]), () => ( {}))).flatMap(([id, controlId]) => {
|
|
9
|
+
const item = board.items.find((item2) => item2.id === id);
|
|
10
|
+
return item && !["completed", "cancelled", "review"].includes(item.status) && _optionalChain([item, 'access', _8 => _8.control, 'optionalAccess', _9 => _9.id]) === controlId ? [item.control] : [];
|
|
11
|
+
});
|
|
12
|
+
if (controls.some((control) => _optionalChain([control, 'optionalAccess', _10 => _10.state]) === "failed" || _optionalChain([control, 'optionalAccess', _11 => _11.state]) === "unknown")) return "error";
|
|
13
|
+
if (controls.some((control) => _optionalChain([control, 'optionalAccess', _12 => _12.state]) === "requested" || _optionalChain([control, 'optionalAccess', _13 => _13.state]) === "accepted")) return _optionalChain([policy, 'optionalAccess', _14 => _14.paused]) ? "pausing" : "resuming";
|
|
14
|
+
return _optionalChain([policy, 'optionalAccess', _15 => _15.paused]) ? "paused" : _nullishCoalesce(_optionalChain([policy, 'optionalAccess', _16 => _16.mode]), () => ( "automatic"));
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
// src/contracts/task-projection.ts
|
|
18
|
+
var TASK_START_DELAY_MS = 3e5;
|
|
19
|
+
function taskStartAt(item) {
|
|
20
|
+
return _nullishCoalesce(_optionalChain([item, 'access', _17 => _17.launch, 'optionalAccess', _18 => _18.startAt]), () => ( item.createdAt + TASK_START_DELAY_MS));
|
|
21
|
+
}
|
|
22
|
+
function taskEditing(item, now) {
|
|
23
|
+
return (_nullishCoalesce(_optionalChain([item, 'access', _19 => _19.launch, 'optionalAccess', _20 => _20.editing, 'optionalAccess', _21 => _21.expiresAt]), () => ( 0))) > now;
|
|
24
|
+
}
|
|
25
|
+
function taskDue(item, now) {
|
|
26
|
+
return !taskEditing(item, now) && !item.blocked && (!item.control || item.control.action === "resume" && item.control.state === "resumed") && (_optionalChain([item, 'access', _22 => _22.launch, 'optionalAccess', _23 => _23.requestedAt]) !== void 0 || _optionalChain([item, 'access', _24 => _24.launch, 'optionalAccess', _25 => _25.mode]) !== "manual" && taskStartAt(item) <= now);
|
|
27
|
+
}
|
|
28
|
+
function projectKanbanTask(item, workflow, now = Date.now(), all = []) {
|
|
29
|
+
const dispatch = Object.values(_nullishCoalesce(_optionalChain([workflow, 'optionalAccess', _26 => _26.dispatches]), () => ( {}))).filter((d) => d.itemId === item.id).sort((a, b) => b.attempt - a.attempt)[0];
|
|
30
|
+
const fact = _nullishCoalesce(_nullishCoalesce(_nullishCoalesce(_nullishCoalesce(_nullishCoalesce(terminalFact(item), () => ( controlFact(item))), () => ( issueFact(item, dispatch))), () => ( failureFact(item, dispatch))), () => ( executionFact(item, dispatch))), () => ( waitingFact(item, now, all)));
|
|
31
|
+
const extra = [];
|
|
32
|
+
if (!["completed", "cancelled"].includes(item.status) && _optionalChain([item, 'access', _27 => _27.control, 'optionalAccess', _28 => _28.action]) !== "cancel") {
|
|
33
|
+
if (!_optionalChain([fact, 'access', _29 => _29.actions, 'optionalAccess', _30 => _30.includes, 'call', _31 => _31("cancel")])) extra.push("cancel");
|
|
34
|
+
if (item.status !== "review" && !_optionalChain([fact, 'access', _32 => _32.actions, 'optionalAccess', _33 => _33.includes, 'call', _34 => _34("pause")]) && !_optionalChain([fact, 'access', _35 => _35.actions, 'optionalAccess', _36 => _36.includes, 'call', _37 => _37("resume")]) && (_optionalChain([dispatch, 'optionalAccess', _38 => _38.controlCapabilities, 'optionalAccess', _39 => _39.pause]) === "boundary" || !dispatch)) extra.push("pause");
|
|
35
|
+
}
|
|
36
|
+
return {
|
|
37
|
+
...fact,
|
|
38
|
+
startAt: taskStartAt(item),
|
|
39
|
+
dispatchId: _optionalChain([dispatch, 'optionalAccess', _40 => _40.id]),
|
|
40
|
+
sessionId: _optionalChain([dispatch, 'optionalAccess', _41 => _41.executionSessionId]),
|
|
41
|
+
actions: item.deletedAt === void 0 ? [..._nullishCoalesce(fact.actions, () => ( [])), ...extra, ...dispatch || _optionalChain([item, 'access', _42 => _42.launch, 'optionalAccess', _43 => _43.admittedAt]) !== void 0 || ["claimed", "review", "completed"].includes(item.status) ? ["fix"] : [], ..._optionalChain([dispatch, 'optionalAccess', _44 => _44.executionSessionId]) ? ["open-session"] : []] : []
|
|
42
|
+
};
|
|
43
|
+
}
|
|
44
|
+
function terminalFact(item) {
|
|
45
|
+
if (item.status === "completed" || item.status === "cancelled") return { phase: item.status, actions: ["delete"] };
|
|
46
|
+
if (_optionalChain([item, 'access', _45 => _45.control, 'optionalAccess', _46 => _46.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"] : [] };
|
|
47
|
+
if (item.status === "review") return { phase: "review", actions: ["review"] };
|
|
48
|
+
}
|
|
49
|
+
function issueFact(item, dispatch) {
|
|
50
|
+
const issue = _optionalChain([item, 'access', _47 => _47.issues, 'optionalAccess', _48 => _48.find, 'call', _49 => _49((i) => !i.resolvedBy && (!dispatch || i.attemptId === dispatch.id))]);
|
|
51
|
+
if (issue) return { phase: issue.type === "clarification" ? "waiting-input" : "error", reason: issue.id, actions: ["resolve"] };
|
|
52
|
+
}
|
|
53
|
+
function controlFact(item) {
|
|
54
|
+
const control = item.control;
|
|
55
|
+
if (!control) return;
|
|
56
|
+
const reason = control.code;
|
|
57
|
+
if (control.state === "unknown") return { phase: "unknown", reason };
|
|
58
|
+
if (control.state === "failed") return { phase: "error", reason, actions: ["resume"] };
|
|
59
|
+
if (control.action === "pause") return { phase: control.state === "paused" ? "paused" : "pausing", reason, actions: ["resume"] };
|
|
60
|
+
if (["requested", "accepted"].includes(control.state)) return { phase: "resuming", reason };
|
|
61
|
+
}
|
|
62
|
+
function failureFact(item, dispatch) {
|
|
63
|
+
if (_optionalChain([dispatch, 'optionalAccess', _50 => _50.outcome]) === "unknown" || _optionalChain([item, 'access', _51 => _51.analysis, 'optionalAccess', _52 => _52.state]) === "unknown") return { phase: "unknown", reason: _nullishCoalesce(_optionalChain([dispatch, 'optionalAccess', _53 => _53.code]), () => ( _optionalChain([item, 'access', _54 => _54.analysis, 'optionalAccess', _55 => _55.code]))) };
|
|
64
|
+
if (dispatch && ["failed", "cancelled", "rejected"].includes(dispatch.outcome)) return { phase: "error", reason: _nullishCoalesce(dispatch.code, () => ( dispatch.outcome)) };
|
|
65
|
+
if (_optionalChain([item, 'access', _56 => _56.analysis, 'optionalAccess', _57 => _57.state]) === "failed") return { phase: "error", reason: item.analysis.code };
|
|
66
|
+
}
|
|
67
|
+
function executionFact(item, dispatch) {
|
|
68
|
+
if (item.blocked) return { phase: item.blocked.reason === "WORKSPACE_INPUT_REQUIRED" ? "waiting-input" : "error", reason: item.blocked.reason };
|
|
69
|
+
if (_optionalChain([dispatch, 'optionalAccess', _58 => _58.outcome]) === "prepared") return { phase: "preparing" };
|
|
70
|
+
if (_optionalChain([dispatch, 'optionalAccess', _59 => _59.outcome]) === "running" || item.status === "claimed") return { phase: "running", actions: _optionalChain([dispatch, 'optionalAccess', _60 => _60.controlCapabilities, 'optionalAccess', _61 => _61.pause]) === "boundary" ? ["pause"] : [] };
|
|
71
|
+
}
|
|
72
|
+
function waitingFact(item, now, all) {
|
|
73
|
+
const analysis = analysisFact(item);
|
|
74
|
+
if (analysis) return analysis;
|
|
75
|
+
const dependency = _optionalChain([item, 'access', _62 => _62.planning, 'optionalAccess', _63 => _63.dependencies, 'access', _64 => _64.find, 'call', _65 => _65((id) => _optionalChain([all, 'access', _66 => _66.find, 'call', _67 => _67((i) => i.id === id), 'optionalAccess', _68 => _68.status]) !== "completed")]);
|
|
76
|
+
if (dependency) return { phase: "waiting-dependency", reason: "DEPENDENCY_UNFINISHED:" + dependency, actions: _optionalChain([item, 'access', _69 => _69.launch, 'optionalAccess', _70 => _70.admittedAt]) === void 0 ? ["edit", "cancel"] : [] };
|
|
77
|
+
if (taskEditing(item, now)) return { phase: "waiting-start", reason: "EDIT_LEASE_ACTIVE" };
|
|
78
|
+
if (_optionalChain([item, 'access', _71 => _71.launch, 'optionalAccess', _72 => _72.admittedAt]) !== void 0) return { phase: "queued" };
|
|
79
|
+
return { phase: "waiting-start", reason: _optionalChain([item, 'access', _73 => _73.launch, 'optionalAccess', _74 => _74.mode]) === "manual" ? "MANUAL_START_REQUIRED" : taskDue(item, now) ? "ADMISSION_PENDING" : "START_AT_PENDING", actions: ["run", "edit", "pause", "cancel"] };
|
|
80
|
+
}
|
|
81
|
+
function analysisFact(item) {
|
|
82
|
+
if (_optionalChain([item, 'access', _75 => _75.analysis, 'optionalAccess', _76 => _76.state]) === "clarification") return { phase: "waiting-input", reason: item.analysis.reason };
|
|
83
|
+
if (_optionalChain([item, 'access', _77 => _77.analysis, 'optionalAccess', _78 => _78.state]) === "analyzing") return { phase: "analyzing" };
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
|
|
87
|
+
|
|
88
|
+
|
|
89
|
+
|
|
90
|
+
|
|
91
|
+
|
|
92
|
+
|
|
93
|
+
|
|
94
|
+
exports.boardAllowsStart = boardAllowsStart; exports.boardControlPhase = boardControlPhase; exports.TASK_START_DELAY_MS = TASK_START_DELAY_MS; exports.taskStartAt = taskStartAt; exports.taskEditing = taskEditing; exports.taskDue = taskDue; exports.projectKanbanTask = projectKanbanTask;
|
|
95
|
+
//# sourceMappingURL=chunk-AOHQCX7K.cjs.map
|