@danypops/papyrus 0.42.0 → 0.42.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/package.json +2 -2
- package/src/adapters/sqlite-artifact-scope-store.ts +18 -9
- package/src/adapters/sqlite-artifact-store.ts +7 -5
- package/src/adapters/sqlite-discussion-round-store.ts +26 -17
- package/src/adapters/sqlite-gate-runner.ts +1 -1
- package/src/adapters/sqlite-graph-projection-store.ts +14 -10
- package/src/adapters/sqlite-log-store.ts +36 -17
- package/src/adapters/sqlite-note-event-store.ts +20 -16
- package/src/adapters/sqlite-session-identity-store.ts +13 -7
- package/src/adapters/sqlite-task-event-store.ts +29 -21
- package/src/adapters/sqlite-task-focus-store.ts +36 -10
- package/src/adapters/sqlite-task-lease-store.ts +12 -6
- package/src/adapters/sqlite-task-scope-store.ts +25 -14
- package/src/artifact-relationship-view.ts +3 -3
- package/src/artifact-subtree.ts +4 -2
- package/src/authority-registry.ts +2 -1
- package/src/cli.ts +785 -179
- package/src/client.ts +46 -20
- package/src/constants.ts +15 -4
- package/src/daemon-state.ts +4 -12
- package/src/daemon.ts +31 -9
- package/src/db.ts +119 -98
- package/src/discussion-service.ts +109 -44
- package/src/domain/artifact-event.ts +17 -4
- package/src/domain/artifact.ts +3 -1
- package/src/domain/blueprint-definition.ts +26 -31
- package/src/domain/checklist.ts +20 -17
- package/src/domain/discussion.ts +37 -18
- package/src/domain/gate.ts +7 -7
- package/src/domain/log-entry.ts +1 -1
- package/src/domain/note-event.ts +20 -7
- package/src/domain/task-event.ts +17 -7
- package/src/domain-services.ts +241 -110
- package/src/graph-projection-service.ts +34 -8
- package/src/id-migration.ts +17 -4
- package/src/index.ts +16 -11
- package/src/log-service.ts +6 -5
- package/src/log.ts +19 -0
- package/src/modules/discuss.ts +63 -28
- package/src/modules/docs.ts +74 -17
- package/src/modules/graph-projection.ts +20 -9
- package/src/modules/logs.ts +33 -21
- package/src/modules/notes.ts +66 -28
- package/src/modules/playbooks.ts +88 -29
- package/src/modules/rules.ts +57 -15
- package/src/modules/session-identity.ts +6 -2
- package/src/modules/tasks.ts +142 -67
- package/src/note-service.ts +11 -7
- package/src/ops.ts +131 -68
- package/src/playbook-definition.ts +56 -17
- package/src/playbook-execution.ts +13 -3
- package/src/ports/note-event-store.ts +6 -4
- package/src/ports/task-event-store.ts +9 -6
- package/src/ports/task-focus-store.ts +17 -4
- package/src/ports/task-lease-store.ts +9 -4
- package/src/ports/task-scope-store.ts +3 -1
- package/src/service.ts +143 -89
- package/src/session-identity-service.ts +10 -2
- package/src/task-context.ts +28 -16
- package/src/task-execution.ts +4 -12
- package/src/task-graph-view.ts +12 -12
- package/src/task-relationship-view.ts +1 -3
- package/src/task-service.ts +167 -72
- package/src/vehicle/artifact-trash-vehicle.ts +25 -13
- package/src/vehicle/artifact-vehicle-shared.ts +28 -7
- package/src/vehicle/docs-vehicle.ts +48 -16
- package/src/vehicle/notes-vehicle.ts +24 -6
- package/src/vehicle/papyrus-vehicle.ts +14 -3
- package/src/vehicle/playbooks-vehicle.ts +87 -18
- package/src/vehicle/rules-vehicle.ts +58 -21
- package/src/vehicle/tasks-vehicle.ts +366 -54
- package/src/version.ts +1 -1
- package/src/workflow-execution.ts +71 -52
|
@@ -1,21 +1,26 @@
|
|
|
1
1
|
import { randomUUID } from "node:crypto";
|
|
2
|
-
import {
|
|
2
|
+
import {
|
|
3
|
+
SKILL_MAX_RENDERED_BYTES,
|
|
4
|
+
SKILL_RUN_ID_MAX_LENGTH,
|
|
5
|
+
SKILL_WORKFLOW_MAX_NESTING_DEPTH,
|
|
6
|
+
TASK_EXECUTION_MAX_EDGES,
|
|
7
|
+
} from "./constants.ts";
|
|
3
8
|
import type { Artifact } from "./domain/artifact.ts";
|
|
4
|
-
import { validateChecklist } from "./domain/checklist.ts";
|
|
5
9
|
import {
|
|
6
|
-
resolveBlueprintArguments,
|
|
7
|
-
validateBlueprintDefinition,
|
|
8
10
|
type BlueprintArgumentValue,
|
|
9
|
-
type CallBlueprint,
|
|
10
11
|
type BlueprintDefinition,
|
|
12
|
+
type CallBlueprint,
|
|
13
|
+
resolveBlueprintArguments,
|
|
14
|
+
validateBlueprintDefinition,
|
|
11
15
|
} from "./domain/blueprint-definition.ts";
|
|
12
|
-
import
|
|
13
|
-
import { compilePlaybookDefinition, type PlaybookExternalLink } from "./playbook-definition.ts";
|
|
16
|
+
import { validateChecklist } from "./domain/checklist.ts";
|
|
14
17
|
import type { TaskEventContext } from "./domain/task-event.ts";
|
|
15
|
-
import type { TaskEventStore } from "./ports/task-event-store.ts";
|
|
16
|
-
import type { TaskScopeStore } from "./ports/task-scope-store.ts";
|
|
17
18
|
import { normalizeProjectRoot } from "./domain/task-scope.ts";
|
|
19
|
+
import { compilePlaybookDefinition, type PlaybookExternalLink } from "./playbook-definition.ts";
|
|
20
|
+
import type { ArtifactStore } from "./ports/artifact-store.ts";
|
|
18
21
|
import { requireAtomicArtifactStore } from "./ports/atomic-artifact-store.ts";
|
|
22
|
+
import type { TaskEventStore } from "./ports/task-event-store.ts";
|
|
23
|
+
import type { TaskScopeStore } from "./ports/task-scope-store.ts";
|
|
19
24
|
import { projectTaskExecution, type TaskExecutionPlan } from "./task-execution.ts";
|
|
20
25
|
import type { TaskGraph, TaskNode, TaskStatus } from "./task-service.ts";
|
|
21
26
|
|
|
@@ -76,7 +81,7 @@ function requireWorkflowSkill(artifacts: ArtifactStore, skillId: string): { skil
|
|
|
76
81
|
throw new Error(`artifact "${skillId}" is not a workflow-definition playbook`);
|
|
77
82
|
}
|
|
78
83
|
if (skill.status !== "active") throw new Error(`cannot run workflow playbook from ${skill.status}`);
|
|
79
|
-
return { skill, definition: validateBlueprintDefinition(skill.extra
|
|
84
|
+
return { skill, definition: validateBlueprintDefinition(skill.extra.definition) };
|
|
80
85
|
}
|
|
81
86
|
|
|
82
87
|
function normalizeRunId(skillId: string, requested: string | undefined): string {
|
|
@@ -115,8 +120,8 @@ function renderDefinition(definition: BlueprintDefinition, arguments_: Record<st
|
|
|
115
120
|
const bytes = new TextEncoder().encode(JSON.stringify(rendered)).byteLength;
|
|
116
121
|
if (bytes > SKILL_MAX_RENDERED_BYTES) throw new Error(`rendered workflow exceeds ${SKILL_MAX_RENDERED_BYTES} bytes`);
|
|
117
122
|
for (const task of rendered.blueprints.tasks) {
|
|
118
|
-
if (task.extra?.
|
|
119
|
-
task.extra
|
|
123
|
+
if (task.extra?.checklist !== undefined) {
|
|
124
|
+
task.extra.checklist = validateChecklist(task.extra.checklist);
|
|
120
125
|
}
|
|
121
126
|
}
|
|
122
127
|
return validateBlueprintDefinition(rendered);
|
|
@@ -129,9 +134,10 @@ function withRunLabel(labels: string[] | undefined, labelPrefix: string, runId:
|
|
|
129
134
|
function executionGraph(tasks: Artifact[], definition: BlueprintDefinition, ids: Map<string, string>, extraKey: string): TaskGraph {
|
|
130
135
|
const byRef = new Map(definition.blueprints.tasks.map((task) => [task.ref, task]));
|
|
131
136
|
const nodes: TaskNode[] = tasks.map((task) => {
|
|
132
|
-
const ref =
|
|
133
|
-
|
|
134
|
-
|
|
137
|
+
const ref =
|
|
138
|
+
task.extra[extraKey] && typeof task.extra[extraKey] === "object"
|
|
139
|
+
? ((task.extra[extraKey] as Record<string, unknown>).ref as string)
|
|
140
|
+
: "";
|
|
135
141
|
const blueprint = byRef.get(ref)!;
|
|
136
142
|
return {
|
|
137
143
|
task,
|
|
@@ -171,14 +177,18 @@ export function resolveRefToTaskId(artifacts: ArtifactStore, taskIds: string[],
|
|
|
171
177
|
for (const taskId of taskIds) {
|
|
172
178
|
const lineage = artifacts.get(taskId)?.extra[extraKey];
|
|
173
179
|
if (typeof lineage !== "object" || lineage === null || Array.isArray(lineage)) continue;
|
|
174
|
-
const ref = (lineage as Record<string, unknown>)
|
|
180
|
+
const ref = (lineage as Record<string, unknown>).ref;
|
|
175
181
|
if (typeof ref === "string") map.set(ref, taskId);
|
|
176
182
|
}
|
|
177
183
|
return map;
|
|
178
184
|
}
|
|
179
185
|
|
|
180
186
|
/** Applies a compiled Playbook's external links (a Rule that `gates` it, a Doc it `references`, etc.) once its blueprint refs have resolved to real task ids -- shared by top-level Playbook invocation and a nested Playbook pipeline-call step alike. */
|
|
181
|
-
export function applyPlaybookExternalLinks(
|
|
187
|
+
export function applyPlaybookExternalLinks(
|
|
188
|
+
artifacts: ArtifactStore,
|
|
189
|
+
externalLinks: PlaybookExternalLink[],
|
|
190
|
+
refToTaskId: Map<string, string>,
|
|
191
|
+
): void {
|
|
182
192
|
for (const link of externalLinks) {
|
|
183
193
|
const taskId = refToTaskId.get(link.rootRef);
|
|
184
194
|
if (!taskId) continue; // defensive -- every rootRef the compiler emits is always materialized
|
|
@@ -287,39 +297,44 @@ export function materializeWorkflowDefinition(
|
|
|
287
297
|
// way at their own level, and nesting depth is separately capped -- so total blast radius
|
|
288
298
|
// across a whole pipeline stays bounded on both dimensions even though a step's dependency
|
|
289
299
|
// on a call ref can fan out to more edges than this per-level count captures exactly.
|
|
290
|
-
const relationshipCount =
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
300
|
+
const relationshipCount =
|
|
301
|
+
rendered.links.length +
|
|
302
|
+
rendered.blueprints.tasks.reduce((count, task) => count + (task.dependsOn?.length ?? 0) + (task.parent ? 2 : 0), 0) +
|
|
303
|
+
rendered.blueprints.skills.reduce((count, call) => count + (call.dependsOn?.length ?? 0) + (call.parent ? 2 : 0), 0) +
|
|
304
|
+
rendered.blueprints.tasks.filter((task) => (task.dependsOn?.length ?? 0) === 0).length +
|
|
305
|
+
rendered.blueprints.skills.filter((call) => (call.dependsOn?.length ?? 0) === 0).length;
|
|
295
306
|
if (relationshipCount > TASK_EXECUTION_MAX_EDGES) {
|
|
296
307
|
throw new Error(`workflow run exceeds ${TASK_EXECUTION_MAX_EDGES} relationships`);
|
|
297
308
|
}
|
|
298
309
|
|
|
299
|
-
const docs = rendered.blueprints.docs.map((blueprint) =>
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
310
|
+
const docs = rendered.blueprints.docs.map((blueprint) =>
|
|
311
|
+
artifacts.create({
|
|
312
|
+
id: ids.get(blueprint.ref),
|
|
313
|
+
kind: "doc",
|
|
314
|
+
title: blueprint.title,
|
|
315
|
+
body: blueprint.body,
|
|
316
|
+
subtype: blueprint.subtype,
|
|
317
|
+
labels: withRunLabel(blueprint.labels, labelPrefix, runId),
|
|
318
|
+
extra: { ...(blueprint.extra ?? {}), [extraKey]: { id: runId, ownerId, ref: blueprint.ref } },
|
|
319
|
+
}),
|
|
320
|
+
);
|
|
321
|
+
const rules = rendered.blueprints.rules.map((blueprint) =>
|
|
322
|
+
artifacts.create({
|
|
323
|
+
id: ids.get(blueprint.ref),
|
|
324
|
+
kind: "rule",
|
|
325
|
+
title: blueprint.title,
|
|
326
|
+
body: blueprint.body,
|
|
327
|
+
labels: withRunLabel(blueprint.labels, labelPrefix, runId),
|
|
328
|
+
extra: {
|
|
329
|
+
...(blueprint.extra ?? {}),
|
|
330
|
+
...(blueprint.condition ? { condition: blueprint.condition } : {}),
|
|
331
|
+
...(blueprint.action ? { action: blueprint.action } : {}),
|
|
332
|
+
...(blueprint.severity ? { severity: blueprint.severity } : {}),
|
|
333
|
+
[extraKey]: { id: runId, ownerId, ref: blueprint.ref },
|
|
334
|
+
scope: { type: labelPrefix, runId, taskIds },
|
|
335
|
+
},
|
|
336
|
+
}),
|
|
337
|
+
);
|
|
323
338
|
const tasks = rendered.blueprints.tasks.map((blueprint) => {
|
|
324
339
|
const task = artifacts.create({
|
|
325
340
|
id: ids.get(blueprint.ref),
|
|
@@ -351,7 +366,10 @@ export function materializeWorkflowDefinition(
|
|
|
351
366
|
const nestedRuns: WorkflowRunResult[] = [];
|
|
352
367
|
const stepTaskIds = new Map<string, string[]>(tasks.map((task, index) => [rendered.blueprints.tasks[index]!.ref, [task.id]]));
|
|
353
368
|
const stepRootTaskIds = new Map<string, string[]>(
|
|
354
|
-
tasks.map((task, index) => [
|
|
369
|
+
tasks.map((task, index) => [
|
|
370
|
+
rendered.blueprints.tasks[index]!.ref,
|
|
371
|
+
(rendered.blueprints.tasks[index]!.dependsOn?.length ?? 0) === 0 ? [task.id] : [],
|
|
372
|
+
]),
|
|
355
373
|
);
|
|
356
374
|
// A call ref never gets its own real task -- it resolves to whatever the nested run's entry
|
|
357
375
|
// (or, absent a resolvable one, its first root task) actually is. Lets a focusRef chain
|
|
@@ -421,11 +439,12 @@ export function materializeWorkflowDefinition(
|
|
|
421
439
|
// A focusRef naming an ordinary task ref resolves directly through ids; one naming a call
|
|
422
440
|
// ref resolves through the nested run it triggered instead (never through ids, which only
|
|
423
441
|
// maps a call ref to a synthetic placeholder that was never actually created).
|
|
424
|
-
const focusTaskId =
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
442
|
+
const focusTaskId =
|
|
443
|
+
input.focusRef === undefined
|
|
444
|
+
? undefined
|
|
445
|
+
: rendered.blueprints.tasks.some((task) => task.ref === input.focusRef)
|
|
446
|
+
? ids.get(input.focusRef)
|
|
447
|
+
: stepEntryTaskIds.get(input.focusRef);
|
|
429
448
|
|
|
430
449
|
return {
|
|
431
450
|
skillId: ownerId,
|