@nestos/kanban 0.0.0-stage → 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 +165 -2
- package/dist/activity-BbC4sgKL.d.cts +258 -0
- package/dist/activity-Czlan5xW.d.ts +258 -0
- 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 +16 -0
- package/dist/activity.cjs.map +1 -0
- package/dist/activity.d.cts +12 -0
- package/dist/activity.d.ts +12 -0
- package/dist/activity.js +16 -0
- package/dist/activity.js.map +1 -0
- package/dist/chunk-3JYLJPE5.js +95 -0
- package/dist/chunk-3JYLJPE5.js.map +1 -0
- package/dist/chunk-3LEIHB7Y.js +221 -0
- package/dist/chunk-3LEIHB7Y.js.map +1 -0
- package/dist/chunk-4XF6LQSU.cjs +9 -0
- package/dist/chunk-4XF6LQSU.cjs.map +1 -0
- package/dist/chunk-5Q7WB63A.cjs +282 -0
- package/dist/chunk-5Q7WB63A.cjs.map +1 -0
- package/dist/chunk-7KDOTBRX.cjs +58 -0
- package/dist/chunk-7KDOTBRX.cjs.map +1 -0
- package/dist/chunk-AHHEGTUA.js +148 -0
- package/dist/chunk-AHHEGTUA.js.map +1 -0
- package/dist/chunk-AOHQCX7K.cjs +95 -0
- package/dist/chunk-AOHQCX7K.cjs.map +1 -0
- package/dist/chunk-DINLR6E6.cjs +443 -0
- package/dist/chunk-DINLR6E6.cjs.map +1 -0
- package/dist/chunk-EYTVC2H5.cjs +1612 -0
- 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-KH3WF3K4.js +443 -0
- package/dist/chunk-KH3WF3K4.js.map +1 -0
- package/dist/chunk-M35X5PHO.js +196 -0
- 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-RBOER6EW.cjs +221 -0
- package/dist/chunk-RBOER6EW.cjs.map +1 -0
- package/dist/chunk-RQP77ZTY.js +9 -0
- package/dist/chunk-RQP77ZTY.js.map +1 -0
- package/dist/chunk-RSH6QSEC.cjs +196 -0
- package/dist/chunk-RSH6QSEC.cjs.map +1 -0
- package/dist/chunk-VMRDXOLX.cjs +148 -0
- package/dist/chunk-VMRDXOLX.cjs.map +1 -0
- package/dist/chunk-X4UHZX6F.js +58 -0
- package/dist/chunk-X4UHZX6F.js.map +1 -0
- package/dist/chunk-XBSGUVCY.cjs +382 -0
- package/dist/chunk-XBSGUVCY.cjs.map +1 -0
- package/dist/chunk-XKDZHAUE.js +1612 -0
- 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-C5aJZFlw.d.cts +35 -0
- package/dist/content-hLH5BNud.d.ts +35 -0
- package/dist/contracts/index.cjs +31 -0
- package/dist/contracts/index.cjs.map +1 -0
- package/dist/contracts/index.d.cts +5 -0
- package/dist/contracts/index.d.ts +5 -0
- package/dist/contracts/index.js +31 -0
- package/dist/contracts/index.js.map +1 -0
- package/dist/discovery-9E-LfwIw.d.cts +61 -0
- package/dist/discovery-D60yrjej.d.ts +61 -0
- package/dist/discovery.cjs +377 -0
- package/dist/discovery.cjs.map +1 -0
- package/dist/discovery.d.cts +22 -0
- package/dist/discovery.d.ts +22 -0
- package/dist/discovery.js +377 -0
- package/dist/discovery.js.map +1 -0
- package/dist/execution-bridge-fpCnH6z5.d.cts +52 -0
- package/dist/execution-bridge-rk0uVy_n.d.ts +52 -0
- package/dist/execution.cjs +18 -0
- package/dist/execution.cjs.map +1 -0
- package/dist/execution.d.cts +42 -0
- package/dist/execution.d.ts +42 -0
- package/dist/execution.js +18 -0
- package/dist/execution.js.map +1 -0
- package/dist/index.cjs +74 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +54 -0
- package/dist/index.d.ts +54 -0
- package/dist/index.js +74 -0
- package/dist/index.js.map +1 -0
- package/dist/module-CYfE7YhM.d.ts +11 -0
- package/dist/module-Ca9L3qCn.d.cts +11 -0
- package/dist/planning-CHrOqQ6b.d.cts +879 -0
- package/dist/planning-CHrOqQ6b.d.ts +879 -0
- package/dist/ports-B0McVg7B.d.ts +143 -0
- package/dist/ports-BeGO1VRI.d.cts +49 -0
- package/dist/ports-GQy0x-RI.d.cts +143 -0
- 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 +21 -0
- package/dist/storage.cjs.map +1 -0
- package/dist/storage.d.cts +71 -0
- package/dist/storage.d.ts +71 -0
- package/dist/storage.js +21 -0
- package/dist/storage.js.map +1 -0
- package/dist/store-DPwHzGiz.d.cts +28 -0
- package/dist/store-DgdrPCV9.d.ts +28 -0
- 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 +143 -4
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
import { IFileSystem } from '@nestos/vfs-core';
|
|
2
|
+
import { f as KanbanAutomationCatalog, u as KanbanExternalReference, T as KanbanService, d as KanbanArtifactRef, K as KanbanActor } from '../planning-CHrOqQ6b.cjs';
|
|
3
|
+
import { K as KanbanClient } from '../activity-BbC4sgKL.cjs';
|
|
4
|
+
import { K as KanbanModuleOptions } from '../ports-GQy0x-RI.cjs';
|
|
5
|
+
import { K as KanbanSessionSource } from '../activity-ports-Dqxa86zT.cjs';
|
|
6
|
+
import { K as KanbanResourceCatalog, a as KanbanRuntimeDiagnostic } from '../ports-BeGO1VRI.cjs';
|
|
7
|
+
import '../discovery-9E-LfwIw.cjs';
|
|
8
|
+
|
|
9
|
+
/** A persistable adapter-owned binding. Its payload is never interpreted by Kanban. */
|
|
10
|
+
interface KanbanExecutionHandle {
|
|
11
|
+
id: string;
|
|
12
|
+
data?: unknown;
|
|
13
|
+
}
|
|
14
|
+
interface KanbanExecutionIntent {
|
|
15
|
+
id: string;
|
|
16
|
+
purpose: 'planning' | 'work';
|
|
17
|
+
scope: {
|
|
18
|
+
boardId: string;
|
|
19
|
+
itemId: string;
|
|
20
|
+
itemRevision: number;
|
|
21
|
+
};
|
|
22
|
+
target: KanbanExternalReference;
|
|
23
|
+
context: unknown;
|
|
24
|
+
preparation?: {
|
|
25
|
+
reference: KanbanExternalReference;
|
|
26
|
+
options?: Record<string, string>;
|
|
27
|
+
};
|
|
28
|
+
previous?: KanbanExecutionHandle;
|
|
29
|
+
}
|
|
30
|
+
interface KanbanExecutionReceipt {
|
|
31
|
+
outcome: 'running' | 'unknown' | 'succeeded' | 'failed' | 'cancelled';
|
|
32
|
+
executionId?: string;
|
|
33
|
+
result?: unknown;
|
|
34
|
+
code?: string;
|
|
35
|
+
controlCapabilities?: {
|
|
36
|
+
pause: 'boundary' | 'none';
|
|
37
|
+
resume: boolean;
|
|
38
|
+
};
|
|
39
|
+
}
|
|
40
|
+
interface KanbanExecutionAdapter {
|
|
41
|
+
catalog(): Promise<KanbanAutomationCatalog>;
|
|
42
|
+
/** Prepare a binding without starting external work. The runtime persists it before submit. */
|
|
43
|
+
prepare(intent: KanbanExecutionIntent): Promise<KanbanExecutionHandle>;
|
|
44
|
+
submit(handle: KanbanExecutionHandle): Promise<KanbanExecutionReceipt>;
|
|
45
|
+
inspect(handle: KanbanExecutionHandle): Promise<KanbanExecutionReceipt>;
|
|
46
|
+
control?(handle: KanbanExecutionHandle, command: {
|
|
47
|
+
operationId: string;
|
|
48
|
+
action: 'pause' | 'resume' | 'cancel';
|
|
49
|
+
}): Promise<'accepted' | 'paused' | 'resumed' | 'cancelled' | 'unknown'>;
|
|
50
|
+
}
|
|
51
|
+
interface KanbanRuntimeOptions {
|
|
52
|
+
fs: IFileSystem;
|
|
53
|
+
directory?: string;
|
|
54
|
+
actor: KanbanActor;
|
|
55
|
+
authorize: KanbanModuleOptions['authorize'];
|
|
56
|
+
execution?: KanbanExecutionAdapter;
|
|
57
|
+
resources?: KanbanResourceCatalog;
|
|
58
|
+
activity?: KanbanSessionSource;
|
|
59
|
+
onCommitted?: KanbanModuleOptions['onCommitted'];
|
|
60
|
+
log?(event: KanbanRuntimeDiagnostic): void;
|
|
61
|
+
}
|
|
62
|
+
/** All persistence, projections, control and deletion barriers are owned by this service. */
|
|
63
|
+
interface KanbanRuntime extends KanbanService, Pick<KanbanClient, 'records' | 'record' | 'runRecord' | 'recordExecutions' | 'controlRecord' | 'itemResources' | 'recordResources' | 'previewDeletion' | 'deleteBoard' | 'cancelBoard' | 'requestBoardDeletion' | 'queryActivity' | 'executionSession' | 'automationCatalog' | 'analysisStatus'> {
|
|
64
|
+
results(boardId: string, dispatchId: string): Promise<Array<{
|
|
65
|
+
reference: KanbanArtifactRef;
|
|
66
|
+
value: unknown;
|
|
67
|
+
}>>;
|
|
68
|
+
quiesce(): Promise<void>;
|
|
69
|
+
dispose(): Promise<void>;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
/** The public instance contains semantic operations only; all coordination state is private. */
|
|
73
|
+
declare function createKanbanRuntime(options: KanbanRuntimeOptions): Promise<KanbanRuntime>;
|
|
74
|
+
|
|
75
|
+
export { type KanbanExecutionAdapter, type KanbanExecutionHandle, type KanbanExecutionIntent, type KanbanExecutionReceipt, KanbanResourceCatalog, type KanbanRuntime, KanbanRuntimeDiagnostic, type KanbanRuntimeOptions, createKanbanRuntime };
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
import { IFileSystem } from '@nestos/vfs-core';
|
|
2
|
+
import { f as KanbanAutomationCatalog, u as KanbanExternalReference, T as KanbanService, d as KanbanArtifactRef, K as KanbanActor } from '../planning-CHrOqQ6b.js';
|
|
3
|
+
import { K as KanbanClient } from '../activity-Czlan5xW.js';
|
|
4
|
+
import { K as KanbanModuleOptions } from '../ports-B0McVg7B.js';
|
|
5
|
+
import { K as KanbanSessionSource } from '../activity-ports-cxfrelaL.js';
|
|
6
|
+
import { K as KanbanResourceCatalog, a as KanbanRuntimeDiagnostic } from '../ports-ykGiNUSx.js';
|
|
7
|
+
import '../discovery-D60yrjej.js';
|
|
8
|
+
|
|
9
|
+
/** A persistable adapter-owned binding. Its payload is never interpreted by Kanban. */
|
|
10
|
+
interface KanbanExecutionHandle {
|
|
11
|
+
id: string;
|
|
12
|
+
data?: unknown;
|
|
13
|
+
}
|
|
14
|
+
interface KanbanExecutionIntent {
|
|
15
|
+
id: string;
|
|
16
|
+
purpose: 'planning' | 'work';
|
|
17
|
+
scope: {
|
|
18
|
+
boardId: string;
|
|
19
|
+
itemId: string;
|
|
20
|
+
itemRevision: number;
|
|
21
|
+
};
|
|
22
|
+
target: KanbanExternalReference;
|
|
23
|
+
context: unknown;
|
|
24
|
+
preparation?: {
|
|
25
|
+
reference: KanbanExternalReference;
|
|
26
|
+
options?: Record<string, string>;
|
|
27
|
+
};
|
|
28
|
+
previous?: KanbanExecutionHandle;
|
|
29
|
+
}
|
|
30
|
+
interface KanbanExecutionReceipt {
|
|
31
|
+
outcome: 'running' | 'unknown' | 'succeeded' | 'failed' | 'cancelled';
|
|
32
|
+
executionId?: string;
|
|
33
|
+
result?: unknown;
|
|
34
|
+
code?: string;
|
|
35
|
+
controlCapabilities?: {
|
|
36
|
+
pause: 'boundary' | 'none';
|
|
37
|
+
resume: boolean;
|
|
38
|
+
};
|
|
39
|
+
}
|
|
40
|
+
interface KanbanExecutionAdapter {
|
|
41
|
+
catalog(): Promise<KanbanAutomationCatalog>;
|
|
42
|
+
/** Prepare a binding without starting external work. The runtime persists it before submit. */
|
|
43
|
+
prepare(intent: KanbanExecutionIntent): Promise<KanbanExecutionHandle>;
|
|
44
|
+
submit(handle: KanbanExecutionHandle): Promise<KanbanExecutionReceipt>;
|
|
45
|
+
inspect(handle: KanbanExecutionHandle): Promise<KanbanExecutionReceipt>;
|
|
46
|
+
control?(handle: KanbanExecutionHandle, command: {
|
|
47
|
+
operationId: string;
|
|
48
|
+
action: 'pause' | 'resume' | 'cancel';
|
|
49
|
+
}): Promise<'accepted' | 'paused' | 'resumed' | 'cancelled' | 'unknown'>;
|
|
50
|
+
}
|
|
51
|
+
interface KanbanRuntimeOptions {
|
|
52
|
+
fs: IFileSystem;
|
|
53
|
+
directory?: string;
|
|
54
|
+
actor: KanbanActor;
|
|
55
|
+
authorize: KanbanModuleOptions['authorize'];
|
|
56
|
+
execution?: KanbanExecutionAdapter;
|
|
57
|
+
resources?: KanbanResourceCatalog;
|
|
58
|
+
activity?: KanbanSessionSource;
|
|
59
|
+
onCommitted?: KanbanModuleOptions['onCommitted'];
|
|
60
|
+
log?(event: KanbanRuntimeDiagnostic): void;
|
|
61
|
+
}
|
|
62
|
+
/** All persistence, projections, control and deletion barriers are owned by this service. */
|
|
63
|
+
interface KanbanRuntime extends KanbanService, Pick<KanbanClient, 'records' | 'record' | 'runRecord' | 'recordExecutions' | 'controlRecord' | 'itemResources' | 'recordResources' | 'previewDeletion' | 'deleteBoard' | 'cancelBoard' | 'requestBoardDeletion' | 'queryActivity' | 'executionSession' | 'automationCatalog' | 'analysisStatus'> {
|
|
64
|
+
results(boardId: string, dispatchId: string): Promise<Array<{
|
|
65
|
+
reference: KanbanArtifactRef;
|
|
66
|
+
value: unknown;
|
|
67
|
+
}>>;
|
|
68
|
+
quiesce(): Promise<void>;
|
|
69
|
+
dispose(): Promise<void>;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
/** The public instance contains semantic operations only; all coordination state is private. */
|
|
73
|
+
declare function createKanbanRuntime(options: KanbanRuntimeOptions): Promise<KanbanRuntime>;
|
|
74
|
+
|
|
75
|
+
export { type KanbanExecutionAdapter, type KanbanExecutionHandle, type KanbanExecutionIntent, type KanbanExecutionReceipt, KanbanResourceCatalog, type KanbanRuntime, KanbanRuntimeDiagnostic, type KanbanRuntimeOptions, createKanbanRuntime };
|
|
@@ -0,0 +1,205 @@
|
|
|
1
|
+
import {
|
|
2
|
+
analyzeItem,
|
|
3
|
+
assembleKanbanRuntime,
|
|
4
|
+
createKanbanAutomation,
|
|
5
|
+
defaultReferences,
|
|
6
|
+
drainBoardAnalyses,
|
|
7
|
+
scanTaskControls,
|
|
8
|
+
workContext
|
|
9
|
+
} from "../chunk-FEE2YBZ7.js";
|
|
10
|
+
import "../chunk-FNO5K3A7.js";
|
|
11
|
+
import "../chunk-KH3WF3K4.js";
|
|
12
|
+
import "../chunk-J3EAIVA3.js";
|
|
13
|
+
import "../chunk-AHHEGTUA.js";
|
|
14
|
+
import "../chunk-XKDZHAUE.js";
|
|
15
|
+
import "../chunk-IHHDXZPZ.js";
|
|
16
|
+
import "../chunk-RQP77ZTY.js";
|
|
17
|
+
import {
|
|
18
|
+
requireValue
|
|
19
|
+
} from "../chunk-3LEIHB7Y.js";
|
|
20
|
+
import {
|
|
21
|
+
DEFAULT_KANBAN_WORK_TYPES
|
|
22
|
+
} from "../chunk-X4UHZX6F.js";
|
|
23
|
+
import "../chunk-M35X5PHO.js";
|
|
24
|
+
import "../chunk-3JYLJPE5.js";
|
|
25
|
+
|
|
26
|
+
// src/runtime/public-authorization.ts
|
|
27
|
+
function runtimeAuthorization(options) {
|
|
28
|
+
return async (input) => {
|
|
29
|
+
await options.authorize(input);
|
|
30
|
+
const command = input.command;
|
|
31
|
+
if (command?.type !== "configure-automation") return;
|
|
32
|
+
if (!options.execution) {
|
|
33
|
+
requireValue(!command.settings.enabled, "AUTOMATION_UNAVAILABLE");
|
|
34
|
+
return;
|
|
35
|
+
}
|
|
36
|
+
const catalog = await options.execution.catalog(), settings = command.settings;
|
|
37
|
+
for (const reference of [settings.planner, settings.executor]) requireValue(catalog.targets.some((target) => sameReference(target.reference, reference)), "AUTOMATION_TARGET_CHANGED");
|
|
38
|
+
if (settings.preparation) requireValue(catalog.preparations?.some((target) => sameReference(target.reference, settings.preparation)), "PREPARATION_UNAVAILABLE");
|
|
39
|
+
requireValue(settings.coordinator.kind === catalog.coordinator.kind && settings.coordinator.id === catalog.coordinator.id && settings.worker.kind === catalog.worker.kind && settings.worker.id === catalog.worker.id, "AUTOMATION_PRINCIPAL_CHANGED");
|
|
40
|
+
};
|
|
41
|
+
}
|
|
42
|
+
function sameReference(left, right) {
|
|
43
|
+
return left.system === right.system && left.id === right.id && left.revision === right.revision;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
// src/runtime/execution-bindings.ts
|
|
47
|
+
var ExecutionBindings = class {
|
|
48
|
+
constructor(journal) {
|
|
49
|
+
this.journal = journal;
|
|
50
|
+
}
|
|
51
|
+
async save(intent, handle) {
|
|
52
|
+
requireValue(typeof handle?.id === "string" && handle.id.length > 0 && handle.id.length <= 512, "EXECUTION_HANDLE_INVALID");
|
|
53
|
+
const next = { scope: intent.scope, handle }, encoded = JSON.stringify(next);
|
|
54
|
+
requireValue(new TextEncoder().encode(encoded).byteLength <= 128 * 1024, "EXECUTION_HANDLE_TOO_LARGE");
|
|
55
|
+
const saved = await this.journal.update("execution-binding:" + intent.id, (old) => {
|
|
56
|
+
requireValue(!old || JSON.stringify(old) === encoded, "EXECUTION_BINDING_CONFLICT");
|
|
57
|
+
return old ?? next;
|
|
58
|
+
});
|
|
59
|
+
return saved.handle;
|
|
60
|
+
}
|
|
61
|
+
async get(id) {
|
|
62
|
+
return (await this.journal.get("execution-binding:" + id))?.handle;
|
|
63
|
+
}
|
|
64
|
+
};
|
|
65
|
+
|
|
66
|
+
// src/runtime/public-execution.ts
|
|
67
|
+
function createExecutionRuntime(context, adapter, resourceSystem = defaultReferences.resource) {
|
|
68
|
+
const bindings = new ExecutionBindings(context.journal), references = { ...defaultReferences, resource: resourceSystem };
|
|
69
|
+
const prepare = async (intent) => bindings.save(intent, await adapter.prepare(intent));
|
|
70
|
+
const controls = { control: {
|
|
71
|
+
control: async (request) => {
|
|
72
|
+
const handle = await bindings.get(request.attemptId ?? request.executionId);
|
|
73
|
+
requireValue(adapter.control, "TASK_CONTROL_UNSUPPORTED");
|
|
74
|
+
requireValue(handle, "TASK_CONTROL_ROUTE_MISSING");
|
|
75
|
+
return adapter.control(handle, { operationId: request.operationId, action: request.action });
|
|
76
|
+
},
|
|
77
|
+
inspect: async (id, attempt = id) => {
|
|
78
|
+
const handle = await bindings.get(attempt);
|
|
79
|
+
if (!handle) return void 0;
|
|
80
|
+
const receipt = validateReceipt(await adapter.inspect(handle));
|
|
81
|
+
return { settled: ["succeeded", "failed", "cancelled"].includes(receipt.outcome), outcome: terminalOutcome(receipt) };
|
|
82
|
+
}
|
|
83
|
+
} };
|
|
84
|
+
const automation = createKanbanAutomation({
|
|
85
|
+
...context,
|
|
86
|
+
directory: context.journal.directory + "/executions",
|
|
87
|
+
catalog: () => adapter.catalog(),
|
|
88
|
+
log: (event) => context.journal.diagnostic(event),
|
|
89
|
+
controls: (board, service) => scanTaskControls(controls, context.journal, board, service),
|
|
90
|
+
drain: (board, service) => drainBoardAnalyses(controls, context.journal, board, service),
|
|
91
|
+
executor: async (execution) => workExecutor(context, adapter, prepare, execution.boardId, references, execution.dependencies),
|
|
92
|
+
analyze: async (board, item, service, active) => analyzeItem(
|
|
93
|
+
{
|
|
94
|
+
journal: context.journal,
|
|
95
|
+
active,
|
|
96
|
+
log: (event) => context.journal.diagnostic(event),
|
|
97
|
+
inheritReferences: (refs) => refs.filter((ref) => [references.resource, references.decision].includes(ref.system)),
|
|
98
|
+
port: {
|
|
99
|
+
prepare: async ({ id, target }) => prepare({ id, purpose: "planning", target, ...preparation(board), scope: scope(board, item), context: {
|
|
100
|
+
...await executionContext(context, board, item, references),
|
|
101
|
+
workTypes: board.workTypes ?? DEFAULT_KANBAN_WORK_TYPES,
|
|
102
|
+
related: board.items.map(({ id: id2, title, status, planning }) => ({ id: id2, title, status, planning }))
|
|
103
|
+
} }),
|
|
104
|
+
prepareExecution: async () => {
|
|
105
|
+
},
|
|
106
|
+
submit: async (handle) => {
|
|
107
|
+
await adapter.submit(handle);
|
|
108
|
+
},
|
|
109
|
+
inspect: async (_id, handle) => {
|
|
110
|
+
const receipt = validateReceipt(await adapter.inspect(handle));
|
|
111
|
+
return { state: receipt.outcome, output: receipt.result, code: receipt.code };
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
},
|
|
115
|
+
board,
|
|
116
|
+
item,
|
|
117
|
+
board.automation?.enabled ? board.automation.planner : void 0,
|
|
118
|
+
service
|
|
119
|
+
)
|
|
120
|
+
});
|
|
121
|
+
return { ...automation, controls };
|
|
122
|
+
}
|
|
123
|
+
function workExecutor(context, adapter, prepare, boardId, references, dependencies) {
|
|
124
|
+
const frozen = async (dispatch, item, previous) => {
|
|
125
|
+
const board = await context.service.read(boardId);
|
|
126
|
+
requireValue(board.automation, "AUTOMATION_UNAVAILABLE");
|
|
127
|
+
return { id: dispatch.id, handle: await prepare({
|
|
128
|
+
id: dispatch.id,
|
|
129
|
+
purpose: "work",
|
|
130
|
+
...preparation(board),
|
|
131
|
+
scope: scope(board, item),
|
|
132
|
+
target: board.automation.executor,
|
|
133
|
+
context: { ...await executionContext(context, board, item, references), inputs: dispatch.inputs, dependencies: await dependencies(item) },
|
|
134
|
+
...previous ? { previous } : {}
|
|
135
|
+
}) };
|
|
136
|
+
};
|
|
137
|
+
const observe = async (value, submit) => {
|
|
138
|
+
const saved = value;
|
|
139
|
+
requireValue(saved?.id && saved.handle?.id, "EXECUTION_HANDLE_INVALID");
|
|
140
|
+
const receipt = validateReceipt(await (submit ? adapter.submit(saved.handle) : adapter.inspect(saved.handle)));
|
|
141
|
+
if (receipt.outcome === "succeeded" && receipt.result === void 0) return { outcome: "unknown", code: "EXECUTION_RESULT_PENDING", executionSessionId: receipt.executionId };
|
|
142
|
+
const outputs = receipt.outcome === "succeeded" && receipt.result !== void 0 ? await context.journal.artifact(saved.id, receipt.result) : void 0;
|
|
143
|
+
return { outcome: receipt.outcome, code: receipt.code, executionSessionId: receipt.executionId, controlCapabilities: receipt.controlCapabilities, outputs };
|
|
144
|
+
};
|
|
145
|
+
return { prepare: frozen, prepareContinuation: (dispatch, item, previous) => frozen(dispatch, item, previous.handle), start: (value) => observe(value, true), inspect: (value) => observe(value, false) };
|
|
146
|
+
}
|
|
147
|
+
function scope(board, item) {
|
|
148
|
+
return { boardId: board.id, itemId: item.id, itemRevision: item.revision };
|
|
149
|
+
}
|
|
150
|
+
function terminalOutcome(receipt) {
|
|
151
|
+
return receipt.outcome === "succeeded" || receipt.outcome === "failed" || receipt.outcome === "cancelled" ? receipt.outcome : void 0;
|
|
152
|
+
}
|
|
153
|
+
async function executionContext(context, board, item, references) {
|
|
154
|
+
const value = await workContext(context.journal, board, item, references), decision = value.decision;
|
|
155
|
+
return { ...value, decision: decision ? { sourceBoardId: decision.sourceBoardId, recordId: decision.recordId, recordRevision: decision.recordRevision, runId: decision.runId } : null };
|
|
156
|
+
}
|
|
157
|
+
function validateReceipt(receipt) {
|
|
158
|
+
requireValue(receipt && ["running", "unknown", "succeeded", "failed", "cancelled"].includes(receipt.outcome), "EXECUTION_RECEIPT_INVALID");
|
|
159
|
+
requireValue(receipt.executionId === void 0 || typeof receipt.executionId === "string" && receipt.executionId.length > 0 && receipt.executionId.length <= 512, "EXECUTION_RECEIPT_INVALID");
|
|
160
|
+
requireValue(receipt.code === void 0 || typeof receipt.code === "string" && /^[A-Z][A-Z0-9_]{0,79}$/.test(receipt.code), "EXECUTION_RECEIPT_INVALID");
|
|
161
|
+
return receipt;
|
|
162
|
+
}
|
|
163
|
+
function preparation(board) {
|
|
164
|
+
return board.automation?.preparation ? { preparation: { reference: board.automation.preparation, options: board.automation.preparationOptions } } : {};
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
// src/runtime/public-runtime.ts
|
|
168
|
+
async function createKanbanRuntime(options) {
|
|
169
|
+
let context, execution;
|
|
170
|
+
const assembled = await assembleKanbanRuntime({
|
|
171
|
+
...options,
|
|
172
|
+
authorize: runtimeAuthorization(options),
|
|
173
|
+
log: options.log ?? (() => {
|
|
174
|
+
}),
|
|
175
|
+
referenceSystem: "kanban-execution",
|
|
176
|
+
executionSessions: options.activity ? { source: options.activity } : void 0,
|
|
177
|
+
verifyOutputs: async ({ board, itemId, dispatchId, outputs }) => {
|
|
178
|
+
if (!context || !dispatchId) return false;
|
|
179
|
+
const dispatch = (await context.service.workflow(board.id)).dispatches[dispatchId];
|
|
180
|
+
return dispatch?.itemId === itemId && context.journal.verify(outputs, dispatchId);
|
|
181
|
+
},
|
|
182
|
+
control: { control: {
|
|
183
|
+
control: (request) => execution?.controls.control.control(request) ?? Promise.resolve("unknown"),
|
|
184
|
+
inspect: (id, attempt) => execution?.controls.control.inspect?.(id, attempt) ?? Promise.resolve(void 0)
|
|
185
|
+
} },
|
|
186
|
+
extensions: (bound) => {
|
|
187
|
+
context = bound;
|
|
188
|
+
if (!options.execution) return [];
|
|
189
|
+
execution = createExecutionRuntime(bound, options.execution, options.resources?.system);
|
|
190
|
+
return [{ ...execution, capabilities: { automationCatalog: execution.automationCatalog, analysisStatus: execution.analysisStatus } }];
|
|
191
|
+
}
|
|
192
|
+
});
|
|
193
|
+
const service = assembled.service;
|
|
194
|
+
return { ...service, results: async (boardId, dispatchId) => {
|
|
195
|
+
const dispatch = (await service.workflow(boardId)).dispatches[dispatchId];
|
|
196
|
+
requireValue(dispatch, "DISPATCH_NOT_FOUND");
|
|
197
|
+
const outputs = dispatch.outputs ?? [];
|
|
198
|
+
requireValue(!outputs.length || await assembled.journal.verify(outputs, dispatchId), "ARTIFACT_INVALID");
|
|
199
|
+
return Promise.all(outputs.map(async (reference) => ({ reference, value: JSON.parse(await assembled.journal.get("artifact:" + reference.sha256)) })));
|
|
200
|
+
} };
|
|
201
|
+
}
|
|
202
|
+
export {
|
|
203
|
+
createKanbanRuntime
|
|
204
|
+
};
|
|
205
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/runtime/public-authorization.ts","../../src/runtime/execution-bindings.ts","../../src/runtime/public-execution.ts","../../src/runtime/public-runtime.ts"],"sourcesContent":["import type {KanbanExternalReference} from '../contracts';\nimport type {KanbanModuleOptions} from '../ports';\nimport type {KanbanRuntimeOptions} from './public-ports';\nimport {requireValue} from '../rules';\n/** Catalog validation complements the host's current principal/resource authorization. */\nexport function runtimeAuthorization(options:KanbanRuntimeOptions):KanbanModuleOptions['authorize'] {\n return async input=>{\n await options.authorize(input);\n const command=input.command;if(command?.type!=='configure-automation')return;\n if(!options.execution){requireValue(!command.settings.enabled,'AUTOMATION_UNAVAILABLE');return;}\n const catalog=await options.execution.catalog(),settings=command.settings;\n for(const reference of [settings.planner,settings.executor])requireValue(catalog.targets.some(target=>sameReference(target.reference,reference)),'AUTOMATION_TARGET_CHANGED');\n if(settings.preparation)requireValue(catalog.preparations?.some(target=>sameReference(target.reference,settings.preparation!)),'PREPARATION_UNAVAILABLE');\n requireValue(settings.coordinator.kind===catalog.coordinator.kind&&settings.coordinator.id===catalog.coordinator.id\n &&settings.worker.kind===catalog.worker.kind&&settings.worker.id===catalog.worker.id,'AUTOMATION_PRINCIPAL_CHANGED');\n };\n}\nfunction sameReference(left:KanbanExternalReference,right:KanbanExternalReference):boolean {\n return left.system===right.system&&left.id===right.id&&left.revision===right.revision;\n}\n","import type {KanbanExecutionHandle,KanbanExecutionIntent} from './public-ports';\nimport type {KanbanAutomationJournal} from './automation-journal';\nimport {requireValue} from '../rules';\ninterface Binding {scope:KanbanExecutionIntent['scope'];handle:KanbanExecutionHandle}\n/** Stable intent identities are the only index used by control and recovery. */\nexport class ExecutionBindings {\n constructor(private readonly journal:KanbanAutomationJournal) {}\n async save(intent:KanbanExecutionIntent,handle:KanbanExecutionHandle):Promise<KanbanExecutionHandle> {\n requireValue(typeof handle?.id==='string'&&handle.id.length>0&&handle.id.length<=512,'EXECUTION_HANDLE_INVALID');\n const next:Binding={scope:intent.scope,handle},encoded=JSON.stringify(next);\n requireValue(new TextEncoder().encode(encoded).byteLength<=128*1024,'EXECUTION_HANDLE_TOO_LARGE');\n const saved=await this.journal.update<Binding>('execution-binding:'+intent.id,old=>{\n requireValue(!old||JSON.stringify(old)===encoded,'EXECUTION_BINDING_CONFLICT');return old??next;\n });\n return saved.handle;\n }\n async get(id:string):Promise<KanbanExecutionHandle|undefined> {\n return (await this.journal.get<Binding>('execution-binding:'+id))?.handle;\n }\n}\n","import type {KanbanBoard,KanbanItem} from '../contracts';\nimport {DEFAULT_KANBAN_WORK_TYPES} from '../contracts';\nimport type {KanbanExecutionPort} from '../execution';\nimport type {KanbanRuntimeContext} from './runtime-ports';\nimport type {KanbanExecutionAdapter,KanbanExecutionHandle,KanbanExecutionIntent,KanbanExecutionReceipt} from './public-ports';\nimport type {KanbanTaskControlOptions} from './control-ports';\nimport {ExecutionBindings} from './execution-bindings';\nimport {createKanbanAutomation} from './automation';\nimport {analyzeItem} from './analysis';\nimport {drainBoardAnalyses} from './board-drain';\nimport {scanTaskControls} from './task-controls';\nimport {workContext} from './work-context';\nimport {defaultReferences} from './ports';\nimport {requireValue} from '../rules';\nexport function createExecutionRuntime(context:KanbanRuntimeContext,adapter:KanbanExecutionAdapter,resourceSystem=defaultReferences.resource) {\n const bindings=new ExecutionBindings(context.journal),references={...defaultReferences,resource:resourceSystem};\n const prepare=async(intent:KanbanExecutionIntent)=>bindings.save(intent,await adapter.prepare(intent));\n const controls:KanbanTaskControlOptions={control:{\n control:async request=>{\n const handle=await bindings.get(request.attemptId??request.executionId);\n requireValue(adapter.control,'TASK_CONTROL_UNSUPPORTED');requireValue(handle,'TASK_CONTROL_ROUTE_MISSING');\n return adapter.control(handle,{operationId:request.operationId,action:request.action});\n },inspect:async(id,attempt=id)=>{\n const handle=await bindings.get(attempt);if(!handle)return undefined;\n const receipt=validateReceipt(await adapter.inspect(handle));\n return {settled:['succeeded','failed','cancelled'].includes(receipt.outcome),outcome:terminalOutcome(receipt)};\n }}};\n const automation=createKanbanAutomation({...context,directory:context.journal.directory+'/executions',catalog:()=>adapter.catalog(),\n log:event=>context.journal.diagnostic(event),controls:(board,service)=>scanTaskControls(controls,context.journal,board,service),\n drain:(board,service)=>drainBoardAnalyses(controls,context.journal,board,service),\n executor:async execution=>workExecutor(context,adapter,prepare,execution.boardId,references,execution.dependencies),\n analyze:async(board,item,service,active)=>analyzeItem({journal:context.journal,active,log:event=>context.journal.diagnostic(event),\n inheritReferences:refs=>refs.filter(ref=>[references.resource,references.decision].includes(ref.system)),\n port:{prepare:async({id,target})=>prepare({id,purpose:'planning',target,...preparation(board),scope:scope(board,item),context:{...await executionContext(context,board,item,references),\n workTypes:board.workTypes??DEFAULT_KANBAN_WORK_TYPES,related:board.items.map(({id,title,status,planning})=>({id,title,status,planning}))}}),\n prepareExecution:async()=>{},submit:async handle=>{await adapter.submit(handle);},\n inspect:async(_id,handle)=>{const receipt=validateReceipt(await adapter.inspect(handle));return {state:receipt.outcome,output:receipt.result,code:receipt.code};}}},\n board,item,board.automation?.enabled?board.automation.planner:undefined,service)});\n return {...automation,controls};\n}\nfunction workExecutor(context:KanbanRuntimeContext,adapter:KanbanExecutionAdapter,prepare:(intent:KanbanExecutionIntent)=>Promise<KanbanExecutionHandle>,boardId:string,references:typeof defaultReferences,dependencies:(item:KanbanItem)=>Promise<unknown>):KanbanExecutionPort {\n const frozen=async(dispatch:Parameters<KanbanExecutionPort['prepare']>[0],item:KanbanItem,previous?:KanbanExecutionHandle)=>{\n const board=await context.service.read(boardId);requireValue(board.automation,'AUTOMATION_UNAVAILABLE');\n return {id:dispatch.id,handle:await prepare({id:dispatch.id,purpose:'work',...preparation(board),scope:scope(board,item),target:board.automation.executor,\n context:{...await executionContext(context,board,item,references),inputs:dispatch.inputs,dependencies:await dependencies(item)},...(previous?{previous}:{})})};\n };\n const observe=async(value:unknown,submit:boolean)=>{\n const saved=value as {id:string;handle:KanbanExecutionHandle};requireValue(saved?.id&&saved.handle?.id,'EXECUTION_HANDLE_INVALID');\n const receipt=validateReceipt(await (submit?adapter.submit(saved.handle):adapter.inspect(saved.handle)));\n if(receipt.outcome==='succeeded'&&receipt.result===undefined)return {outcome:'unknown' as const,code:'EXECUTION_RESULT_PENDING',executionSessionId:receipt.executionId};\n const outputs=receipt.outcome==='succeeded'&&receipt.result!==undefined?await context.journal.artifact(saved.id,receipt.result):undefined;\n return {outcome:receipt.outcome,code:receipt.code,executionSessionId:receipt.executionId,controlCapabilities:receipt.controlCapabilities,outputs};\n };\n return {prepare:frozen,prepareContinuation:(dispatch,item,previous)=>frozen(dispatch,item,(previous as {handle:KanbanExecutionHandle}).handle),start:value=>observe(value,true),inspect:value=>observe(value,false)};\n}\nfunction scope(board:KanbanBoard,item:KanbanItem):KanbanExecutionIntent['scope'] {return {boardId:board.id,itemId:item.id,itemRevision:item.revision};}\nfunction terminalOutcome(receipt:KanbanExecutionReceipt):'succeeded'|'failed'|'cancelled'|undefined {\n return receipt.outcome==='succeeded'||receipt.outcome==='failed'||receipt.outcome==='cancelled'?receipt.outcome:undefined;\n}\n\nasync function executionContext(context:KanbanRuntimeContext,board:KanbanBoard,item:KanbanItem,references:typeof defaultReferences) {\n const value=await workContext(context.journal,board,item,references),decision=value.decision;\n return {...value,decision:decision?{sourceBoardId:decision.sourceBoardId,recordId:decision.recordId,recordRevision:decision.recordRevision,runId:decision.runId}:null};\n}\nfunction validateReceipt(receipt:KanbanExecutionReceipt):KanbanExecutionReceipt {\n requireValue(receipt&&['running','unknown','succeeded','failed','cancelled'].includes(receipt.outcome),'EXECUTION_RECEIPT_INVALID');\n requireValue(receipt.executionId===undefined||typeof receipt.executionId==='string'&&receipt.executionId.length>0&&receipt.executionId.length<=512,'EXECUTION_RECEIPT_INVALID');\n requireValue(receipt.code===undefined||typeof receipt.code==='string'&&/^[A-Z][A-Z0-9_]{0,79}$/.test(receipt.code),'EXECUTION_RECEIPT_INVALID');\n return receipt;\n}\n\nfunction preparation(board:KanbanBoard):Pick<KanbanExecutionIntent,'preparation'> {\n return board.automation?.preparation?{preparation:{reference:board.automation.preparation,options:board.automation.preparationOptions}}:{};\n}\n","import {assembleKanbanRuntime} from './runtime';\nimport {runtimeAuthorization} from './public-authorization';\nimport {createExecutionRuntime} from './public-execution';\nimport {requireValue} from '../rules';\nimport type {KanbanRuntime,KanbanRuntimeOptions} from './public-ports';\nimport type {KanbanRuntimeContext} from './runtime-ports';\n/** The public instance contains semantic operations only; all coordination state is private. */\nexport async function createKanbanRuntime(options:KanbanRuntimeOptions):Promise<KanbanRuntime> {\n let context:KanbanRuntimeContext|undefined,execution:ReturnType<typeof createExecutionRuntime>|undefined;\n const assembled=await assembleKanbanRuntime({...options,authorize:runtimeAuthorization(options),log:options.log??(()=>{}),\n referenceSystem:'kanban-execution',executionSessions:options.activity?{source:options.activity}:undefined,\n verifyOutputs:async({board,itemId,dispatchId,outputs})=>{\n if(!context||!dispatchId)return false;\n const dispatch=(await context.service.workflow(board.id)).dispatches[dispatchId];\n return dispatch?.itemId===itemId&&context.journal.verify(outputs,dispatchId);\n },control:{control:{control:request=>execution?.controls.control.control(request)??Promise.resolve('unknown'),\n inspect:(id,attempt)=>execution?.controls.control.inspect?.(id,attempt)??Promise.resolve(undefined)}},\n extensions:bound=>{\n context=bound;if(!options.execution)return [];\n execution=createExecutionRuntime(bound,options.execution,options.resources?.system);\n return [{...execution,capabilities:{automationCatalog:execution.automationCatalog,analysisStatus:execution.analysisStatus}}];\n }});\n const service=assembled.service;\n return {...service,results:async(boardId,dispatchId)=>{\n const dispatch=(await service.workflow(boardId)).dispatches[dispatchId];requireValue(dispatch,'DISPATCH_NOT_FOUND');\n const outputs=dispatch.outputs??[];requireValue(!outputs.length||await assembled.journal.verify(outputs,dispatchId),'ARTIFACT_INVALID');\n return Promise.all(outputs.map(async reference=>({reference,value:JSON.parse((await assembled.journal.get<string>('artifact:'+reference.sha256))!)})));\n }};\n}\n"],"mappings":"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","names":["id"]}
|