@caupulican/pi-adaptative 0.93.3 → 0.93.4
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/CHANGELOG.md +16 -0
- package/dist/core/agent-session.d.ts.map +1 -1
- package/dist/core/agent-session.js +15 -9
- package/dist/core/agent-session.js.map +1 -1
- package/dist/core/autonomy/approval-gate.d.ts +1 -0
- package/dist/core/autonomy/approval-gate.d.ts.map +1 -1
- package/dist/core/autonomy/approval-gate.js +4 -1
- package/dist/core/autonomy/approval-gate.js.map +1 -1
- package/dist/core/autonomy/composite-tool-gate.d.ts +13 -0
- package/dist/core/autonomy/composite-tool-gate.d.ts.map +1 -0
- package/dist/core/autonomy/composite-tool-gate.js +44 -0
- package/dist/core/autonomy/composite-tool-gate.js.map +1 -0
- package/dist/core/autonomy/envelope-enforcement.d.ts +2 -0
- package/dist/core/autonomy/envelope-enforcement.d.ts.map +1 -1
- package/dist/core/autonomy/envelope-enforcement.js +48 -7
- package/dist/core/autonomy/envelope-enforcement.js.map +1 -1
- package/dist/core/autonomy/gates.d.ts.map +1 -1
- package/dist/core/autonomy/gates.js +48 -76
- package/dist/core/autonomy/gates.js.map +1 -1
- package/dist/core/autonomy/path-scope.d.ts.map +1 -1
- package/dist/core/autonomy/path-scope.js +7 -7
- package/dist/core/autonomy/path-scope.js.map +1 -1
- package/dist/core/background-tool-task-controller.d.ts +2 -0
- package/dist/core/background-tool-task-controller.d.ts.map +1 -1
- package/dist/core/background-tool-task-controller.js +13 -5
- package/dist/core/background-tool-task-controller.js.map +1 -1
- package/dist/core/compaction-controller.d.ts +3 -0
- package/dist/core/compaction-controller.d.ts.map +1 -1
- package/dist/core/compaction-controller.js +132 -97
- package/dist/core/compaction-controller.js.map +1 -1
- package/dist/core/delegation/session-root-mailbox.d.ts.map +1 -1
- package/dist/core/delegation/session-root-mailbox.js +14 -1
- package/dist/core/delegation/session-root-mailbox.js.map +1 -1
- package/dist/core/delegation/worker-agent-control-coordinator.d.ts.map +1 -1
- package/dist/core/delegation/worker-agent-control-coordinator.js +6 -9
- package/dist/core/delegation/worker-agent-control-coordinator.js.map +1 -1
- package/dist/core/delegation/worker-authority-resolver.d.ts.map +1 -1
- package/dist/core/delegation/worker-authority-resolver.js +3 -2
- package/dist/core/delegation/worker-authority-resolver.js.map +1 -1
- package/dist/core/delegation/worker-execution-policy.d.ts.map +1 -1
- package/dist/core/delegation/worker-execution-policy.js +10 -8
- package/dist/core/delegation/worker-execution-policy.js.map +1 -1
- package/dist/core/foreground-recovery-controller.d.ts +2 -0
- package/dist/core/foreground-recovery-controller.d.ts.map +1 -1
- package/dist/core/foreground-recovery-controller.js +18 -9
- package/dist/core/foreground-recovery-controller.js.map +1 -1
- package/dist/core/goal-loop-controller.d.ts.map +1 -1
- package/dist/core/goal-loop-controller.js +3 -5
- package/dist/core/goal-loop-controller.js.map +1 -1
- package/dist/core/goals/goal-auto-continue-controller.d.ts.map +1 -1
- package/dist/core/goals/goal-auto-continue-controller.js +6 -0
- package/dist/core/goals/goal-auto-continue-controller.js.map +1 -1
- package/dist/core/goals/goal-state.d.ts.map +1 -1
- package/dist/core/goals/goal-state.js +1 -0
- package/dist/core/goals/goal-state.js.map +1 -1
- package/dist/core/goals/goal-tool-core.d.ts +2 -0
- package/dist/core/goals/goal-tool-core.d.ts.map +1 -1
- package/dist/core/goals/goal-tool-core.js +1 -1
- package/dist/core/goals/goal-tool-core.js.map +1 -1
- package/dist/core/orchestration/capability-gateway.d.ts.map +1 -1
- package/dist/core/orchestration/capability-gateway.js +32 -9
- package/dist/core/orchestration/capability-gateway.js.map +1 -1
- package/dist/core/orchestration/lane-tool-manifests.js +5 -5
- package/dist/core/orchestration/lane-tool-manifests.js.map +1 -1
- package/dist/core/orchestration/policy-compiler.d.ts.map +1 -1
- package/dist/core/orchestration/policy-compiler.js +7 -0
- package/dist/core/orchestration/policy-compiler.js.map +1 -1
- package/dist/core/orchestration/profile-registry.js +2 -2
- package/dist/core/orchestration/profile-registry.js.map +1 -1
- package/dist/core/pipelines/active-context.d.ts +16 -0
- package/dist/core/pipelines/active-context.d.ts.map +1 -0
- package/dist/core/pipelines/active-context.js +29 -0
- package/dist/core/pipelines/active-context.js.map +1 -0
- package/dist/core/pipelines/context.d.ts +1 -1
- package/dist/core/pipelines/context.d.ts.map +1 -1
- package/dist/core/pipelines/context.js +40 -31
- package/dist/core/pipelines/context.js.map +1 -1
- package/dist/core/pipelines/discover.d.ts +5 -1
- package/dist/core/pipelines/discover.d.ts.map +1 -1
- package/dist/core/pipelines/discover.js +91 -33
- package/dist/core/pipelines/discover.js.map +1 -1
- package/dist/core/pipelines/increment.d.ts +0 -2
- package/dist/core/pipelines/increment.d.ts.map +1 -1
- package/dist/core/pipelines/increment.js +35 -13
- package/dist/core/pipelines/increment.js.map +1 -1
- package/dist/core/pipelines/index.d.ts +4 -3
- package/dist/core/pipelines/index.d.ts.map +1 -1
- package/dist/core/pipelines/index.js +4 -3
- package/dist/core/pipelines/index.js.map +1 -1
- package/dist/core/pipelines/run-state.d.ts +8 -0
- package/dist/core/pipelines/run-state.d.ts.map +1 -1
- package/dist/core/pipelines/run-state.js +172 -38
- package/dist/core/pipelines/run-state.js.map +1 -1
- package/dist/core/pipelines/types.d.ts +2 -0
- package/dist/core/pipelines/types.d.ts.map +1 -1
- package/dist/core/pipelines/types.js +21 -4
- package/dist/core/pipelines/types.js.map +1 -1
- package/dist/core/runtime-builder.d.ts +2 -1
- package/dist/core/runtime-builder.d.ts.map +1 -1
- package/dist/core/runtime-builder.js +46 -10
- package/dist/core/runtime-builder.js.map +1 -1
- package/dist/core/system-prompt-builder.d.ts +1 -0
- package/dist/core/system-prompt-builder.d.ts.map +1 -1
- package/dist/core/system-prompt-builder.js +25 -1
- package/dist/core/system-prompt-builder.js.map +1 -1
- package/dist/core/system-prompt.d.ts.map +1 -1
- package/dist/core/system-prompt.js +6 -1
- package/dist/core/system-prompt.js.map +1 -1
- package/dist/core/tasks/task-projection.d.ts +2 -0
- package/dist/core/tasks/task-projection.d.ts.map +1 -1
- package/dist/core/tasks/task-projection.js +2 -0
- package/dist/core/tasks/task-projection.js.map +1 -1
- package/dist/core/tasks/task-state.d.ts +10 -0
- package/dist/core/tasks/task-state.d.ts.map +1 -1
- package/dist/core/tasks/task-state.js +43 -2
- package/dist/core/tasks/task-state.js.map +1 -1
- package/dist/core/tool-capability-policy.d.ts +13 -3
- package/dist/core/tool-capability-policy.d.ts.map +1 -1
- package/dist/core/tool-capability-policy.js +136 -28
- package/dist/core/tool-capability-policy.js.map +1 -1
- package/dist/core/tools/edit-diff.d.ts.map +1 -1
- package/dist/core/tools/edit-diff.js +45 -7
- package/dist/core/tools/edit-diff.js.map +1 -1
- package/dist/core/tools/edit.d.ts.map +1 -1
- package/dist/core/tools/edit.js +4 -0
- package/dist/core/tools/edit.js.map +1 -1
- package/dist/core/tools/goal.d.ts.map +1 -1
- package/dist/core/tools/goal.js +17 -1
- package/dist/core/tools/goal.js.map +1 -1
- package/dist/core/tools/orchestration-panel.d.ts.map +1 -1
- package/dist/core/tools/orchestration-panel.js +1 -0
- package/dist/core/tools/orchestration-panel.js.map +1 -1
- package/dist/core/tools/persistent-process-coordinator.d.ts.map +1 -1
- package/dist/core/tools/persistent-process-coordinator.js +12 -7
- package/dist/core/tools/persistent-process-coordinator.js.map +1 -1
- package/dist/core/tools/pipeline.d.ts +1 -0
- package/dist/core/tools/pipeline.d.ts.map +1 -1
- package/dist/core/tools/pipeline.js +95 -44
- package/dist/core/tools/pipeline.js.map +1 -1
- package/dist/core/tools/secret-store.d.ts.map +1 -1
- package/dist/core/tools/secret-store.js +2 -1
- package/dist/core/tools/secret-store.js.map +1 -1
- package/dist/core/tools/shell-session.d.ts.map +1 -1
- package/dist/core/tools/shell-session.js +6 -1
- package/dist/core/tools/shell-session.js.map +1 -1
- package/dist/core/tools/task-steps.d.ts +10 -0
- package/dist/core/tools/task-steps.d.ts.map +1 -1
- package/dist/core/tools/task-steps.js +70 -29
- package/dist/core/tools/task-steps.js.map +1 -1
- package/dist/core/tools/windows-shell-engine.d.ts.map +1 -1
- package/dist/core/tools/windows-shell-engine.js +6 -1
- package/dist/core/tools/windows-shell-engine.js.map +1 -1
- package/dist/core/util/bounded-file.d.ts +8 -0
- package/dist/core/util/bounded-file.d.ts.map +1 -1
- package/dist/core/util/bounded-file.js +81 -16
- package/dist/core/util/bounded-file.js.map +1 -1
- package/examples/extensions/custom-provider-anthropic/package-lock.json +2 -2
- package/examples/extensions/custom-provider-anthropic/package.json +1 -1
- package/examples/extensions/custom-provider-gitlab-duo/package.json +1 -1
- package/examples/extensions/sandbox/package-lock.json +2 -2
- package/examples/extensions/sandbox/package.json +1 -1
- package/examples/extensions/with-deps/package-lock.json +2 -2
- package/examples/extensions/with-deps/package.json +1 -1
- package/npm-shrinkwrap.json +12 -12
- package/package.json +4 -4
|
@@ -1,8 +1,7 @@
|
|
|
1
|
-
import { taskStepReferencesRequirement } from "../tasks/task-projection.js";
|
|
2
1
|
import { updateTaskStep } from "../tasks/task-state.js";
|
|
3
2
|
import { currentPipelineStage } from "./context.js";
|
|
4
3
|
import { persistPipelineRun, scanStageOutput, stageOutputDir } from "./run-state.js";
|
|
5
|
-
import { isPipelineRunActive } from "./types.js";
|
|
4
|
+
import { isPipelineRunActive, } from "./types.js";
|
|
6
5
|
export class PipelineIncrementError extends Error {
|
|
7
6
|
constructor(message) {
|
|
8
7
|
super(message);
|
|
@@ -14,31 +13,31 @@ function inFlightToolTasks(tasks) {
|
|
|
14
13
|
return [];
|
|
15
14
|
return tasks.filter((task) => task.status === "running").map((task) => task.taskId);
|
|
16
15
|
}
|
|
17
|
-
function linkedOpenStepIds(join, run) {
|
|
18
|
-
if (!
|
|
16
|
+
function linkedOpenStepIds(join, run, stage) {
|
|
17
|
+
if (!stage)
|
|
19
18
|
return [];
|
|
20
19
|
if (!join.openTaskSteps || join.openTaskSteps.length === 0)
|
|
21
20
|
return [];
|
|
22
21
|
return join.openTaskSteps
|
|
23
|
-
.filter((step) =>
|
|
22
|
+
.filter((step) => step.pipelineRunId === run.runId && step.pipelineStageId === stage.id)
|
|
24
23
|
.map((step) => step.id);
|
|
25
24
|
}
|
|
26
25
|
export function incrementPipelineRun(definition, run, now, join = {}) {
|
|
27
26
|
if (!isPipelineRunActive(run)) {
|
|
28
27
|
throw new PipelineIncrementError(`Pipeline run '${run.runId}' is ${run.status}.`);
|
|
29
28
|
}
|
|
30
|
-
const
|
|
29
|
+
const stage = currentPipelineStage(definition, run);
|
|
30
|
+
if (!stage) {
|
|
31
|
+
throw new PipelineIncrementError(`Current stage '${run.currentStageId}' is missing from the definition.`);
|
|
32
|
+
}
|
|
33
|
+
const linked = linkedOpenStepIds(join, run, stage);
|
|
31
34
|
if (linked.length > 0) {
|
|
32
|
-
throw new PipelineIncrementError(`Cannot increment pipeline: open task_steps still reference
|
|
35
|
+
throw new PipelineIncrementError(`Cannot increment pipeline: open task_steps still reference current stage '${stage.id}' (${linked.join(", ")}).`);
|
|
33
36
|
}
|
|
34
37
|
const running = inFlightToolTasks(join.backgroundToolTasks);
|
|
35
38
|
if (running.length > 0) {
|
|
36
39
|
throw new PipelineIncrementError(`Cannot increment pipeline: tool_task(s) still running (${running.join(", ")}). Wait once via tool_task.`);
|
|
37
40
|
}
|
|
38
|
-
const stage = currentPipelineStage(definition, run);
|
|
39
|
-
if (!stage) {
|
|
40
|
-
throw new PipelineIncrementError(`Current stage '${run.currentStageId}' is missing from the definition.`);
|
|
41
|
-
}
|
|
42
41
|
const scanned = scanStageOutput(stageOutputDir(run.runRoot, stage));
|
|
43
42
|
if (scanned.status !== "complete") {
|
|
44
43
|
throw new PipelineIncrementError(`Cannot increment pipeline: stage '${stage.id}' output/ has no files yet. Write the stage outputs first.`);
|
|
@@ -78,6 +77,17 @@ export function advanceTaskSteps(state, now) {
|
|
|
78
77
|
const current = state.steps.find((step) => step.status === "in_progress") ??
|
|
79
78
|
state.steps.find((step) => step.status === "pending");
|
|
80
79
|
if (!current) {
|
|
80
|
+
const blocked = state.steps.filter((step) => step.status === "blocked");
|
|
81
|
+
if (blocked.length > 0) {
|
|
82
|
+
return {
|
|
83
|
+
state,
|
|
84
|
+
result: {
|
|
85
|
+
surface: "task_steps",
|
|
86
|
+
completed: false,
|
|
87
|
+
detail: `Cannot advance: all remaining steps are blocked (${blocked.map((step) => step.id).join(", ")}).`,
|
|
88
|
+
},
|
|
89
|
+
};
|
|
90
|
+
}
|
|
81
91
|
return {
|
|
82
92
|
state,
|
|
83
93
|
result: {
|
|
@@ -91,8 +101,8 @@ export function advanceTaskSteps(state, now) {
|
|
|
91
101
|
if (current.status !== "completed") {
|
|
92
102
|
nextState = updateTaskStep(nextState, current.id, { status: "completed" }, now);
|
|
93
103
|
}
|
|
94
|
-
const following = nextState.steps.find((step) => step.id !== current.id &&
|
|
95
|
-
if (following
|
|
104
|
+
const following = nextState.steps.find((step) => step.id !== current.id && step.status === "pending");
|
|
105
|
+
if (following) {
|
|
96
106
|
nextState = updateTaskStep(nextState, following.id, { status: "in_progress" }, now);
|
|
97
107
|
return {
|
|
98
108
|
state: nextState,
|
|
@@ -105,6 +115,18 @@ export function advanceTaskSteps(state, now) {
|
|
|
105
115
|
},
|
|
106
116
|
};
|
|
107
117
|
}
|
|
118
|
+
const blocked = nextState.steps.filter((step) => step.status === "blocked");
|
|
119
|
+
if (blocked.length > 0) {
|
|
120
|
+
return {
|
|
121
|
+
state: nextState,
|
|
122
|
+
result: {
|
|
123
|
+
surface: "task_steps",
|
|
124
|
+
from: current.id,
|
|
125
|
+
completed: false,
|
|
126
|
+
detail: `Completed ${current.id}. Remaining steps are blocked: ${blocked.map((step) => step.id).join(", ")}.`,
|
|
127
|
+
},
|
|
128
|
+
};
|
|
129
|
+
}
|
|
108
130
|
return {
|
|
109
131
|
state: nextState,
|
|
110
132
|
result: {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"increment.js","sourceRoot":"","sources":["../../../src/core/pipelines/increment.ts"],"names":[],"mappings":"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","sourcesContent":["import type { BackgroundToolTaskRef } from \"../background-tool-task-controller.ts\";\nimport type { GoalState } from \"../goals/goal-state.ts\";\nimport type { OpenTaskStepRef } from \"../goals/goal-tool-core.ts\";\nimport { taskStepReferencesRequirement } from \"../tasks/task-projection.ts\";\nimport { type TaskStep, type TaskStepsState, updateTaskStep } from \"../tasks/task-state.ts\";\nimport { currentPipelineStage } from \"./context.ts\";\nimport { persistPipelineRun, scanStageOutput, stageOutputDir } from \"./run-state.ts\";\nimport { type IncrementResult, isPipelineRunActive, type PipelineDefinition, type PipelineRun } from \"./types.ts\";\n\nexport interface PipelineIncrementJoin {\n\tgoal?: GoalState;\n\topenTaskSteps?: readonly OpenTaskStepRef[];\n\tbackgroundToolTasks?: readonly BackgroundToolTaskRef[];\n}\n\nexport class PipelineIncrementError extends Error {\n\tconstructor(message: string) {\n\t\tsuper(message);\n\t\tthis.name = \"PipelineIncrementError\";\n\t}\n}\n\nfunction inFlightToolTasks(tasks: readonly BackgroundToolTaskRef[] | undefined): string[] {\n\tif (!tasks) return [];\n\treturn tasks.filter((task) => task.status === \"running\").map((task) => task.taskId);\n}\n\nfunction linkedOpenStepIds(join: PipelineIncrementJoin, run: PipelineRun): string[] {\n\tif (!run.goalId || !join.goal || join.goal.goalId !== run.goalId) return [];\n\tif (!join.openTaskSteps || join.openTaskSteps.length === 0) return [];\n\treturn join.openTaskSteps\n\t\t.filter((step) => join.goal!.requirements.some((requirement) => taskStepReferencesRequirement(step, requirement)))\n\t\t.map((step) => step.id);\n}\n\nexport function incrementPipelineRun(\n\tdefinition: PipelineDefinition,\n\trun: PipelineRun,\n\tnow: string,\n\tjoin: PipelineIncrementJoin = {},\n): { run: PipelineRun; result: IncrementResult } {\n\tif (!isPipelineRunActive(run)) {\n\t\tthrow new PipelineIncrementError(`Pipeline run '${run.runId}' is ${run.status}.`);\n\t}\n\tconst linked = linkedOpenStepIds(join, run);\n\tif (linked.length > 0) {\n\t\tthrow new PipelineIncrementError(\n\t\t\t`Cannot increment pipeline: open task_steps still reference the linked goal (${linked.join(\", \")}).`,\n\t\t);\n\t}\n\tconst running = inFlightToolTasks(join.backgroundToolTasks);\n\tif (running.length > 0) {\n\t\tthrow new PipelineIncrementError(\n\t\t\t`Cannot increment pipeline: tool_task(s) still running (${running.join(\", \")}). Wait once via tool_task.`,\n\t\t);\n\t}\n\tconst stage = currentPipelineStage(definition, run);\n\tif (!stage) {\n\t\tthrow new PipelineIncrementError(`Current stage '${run.currentStageId}' is missing from the definition.`);\n\t}\n\tconst scanned = scanStageOutput(stageOutputDir(run.runRoot, stage));\n\tif (scanned.status !== \"complete\") {\n\t\tthrow new PipelineIncrementError(\n\t\t\t`Cannot increment pipeline: stage '${stage.id}' output/ has no files yet. Write the stage outputs first.`,\n\t\t);\n\t}\n\tconst currentIndex = definition.stages.findIndex((candidate) => candidate.id === stage.id);\n\tconst next = definition.stages[currentIndex + 1];\n\tif (!next) {\n\t\tconst completed = persistPipelineRun({ ...run, status: \"completed\" }, now);\n\t\treturn {\n\t\t\trun: completed,\n\t\t\tresult: {\n\t\t\t\tsurface: \"pipeline\",\n\t\t\t\tfrom: stage.id,\n\t\t\t\tcompleted: true,\n\t\t\t\tdetail: `Completed final stage '${stage.id}'. Pipeline run '${run.runId}' is done.`,\n\t\t\t},\n\t\t};\n\t}\n\tconst advanced = persistPipelineRun({ ...run, currentStageId: next.id }, now);\n\treturn {\n\t\trun: advanced,\n\t\tresult: {\n\t\t\tsurface: \"pipeline\",\n\t\t\tfrom: stage.id,\n\t\t\tto: next.id,\n\t\t\tcompleted: false,\n\t\t\tdetail: `Completed '${stage.id}', started '${next.id}'. ${next.contract.oneJob || next.contract.title}`,\n\t\t},\n\t};\n}\n\nexport function abandonPipelineRun(run: PipelineRun, now: string): PipelineRun {\n\tif (!isPipelineRunActive(run)) return run;\n\treturn persistPipelineRun({ ...run, status: \"abandoned\" }, now);\n}\n\nexport function advanceTaskSteps(\n\tstate: TaskStepsState,\n\tnow: string,\n): {\n\tstate: TaskStepsState;\n\tresult: IncrementResult;\n} {\n\tconst current =\n\t\tstate.steps.find((step) => step.status === \"in_progress\") ??\n\t\tstate.steps.find((step) => step.status === \"pending\");\n\tif (!current) {\n\t\treturn {\n\t\t\tstate,\n\t\t\tresult: {\n\t\t\t\tsurface: \"task_steps\",\n\t\t\t\tcompleted: true,\n\t\t\t\tdetail: \"No open task steps remain.\",\n\t\t\t},\n\t\t};\n\t}\n\tlet nextState = state;\n\tif (current.status !== \"completed\") {\n\t\tnextState = updateTaskStep(nextState, current.id, { status: \"completed\" }, now);\n\t}\n\tconst following = nextState.steps.find(\n\t\t(step) => step.id !== current.id && (step.status === \"pending\" || step.status === \"blocked\"),\n\t);\n\tif (following && following.status === \"pending\") {\n\t\tnextState = updateTaskStep(nextState, following.id, { status: \"in_progress\" }, now);\n\t\treturn {\n\t\t\tstate: nextState,\n\t\t\tresult: {\n\t\t\t\tsurface: \"task_steps\",\n\t\t\t\tfrom: current.id,\n\t\t\t\tto: following.id,\n\t\t\t\tcompleted: false,\n\t\t\t\tdetail: `Completed ${current.id}, started ${following.id}.`,\n\t\t\t},\n\t\t};\n\t}\n\treturn {\n\t\tstate: nextState,\n\t\tresult: {\n\t\t\tsurface: \"task_steps\",\n\t\t\tfrom: current.id,\n\t\t\tcompleted: true,\n\t\t\tdetail: `Completed ${current.id}. No further pending steps.`,\n\t\t},\n\t};\n}\n\nexport function currentOpenTaskStep(steps: readonly TaskStep[]): TaskStep | undefined {\n\treturn steps.find((step) => step.status === \"in_progress\") ?? steps.find((step) => step.status === \"pending\");\n}\n"]}
|
|
1
|
+
{"version":3,"file":"increment.js","sourceRoot":"","sources":["../../../src/core/pipelines/increment.ts"],"names":[],"mappings":"AAEA,OAAO,EAAsC,cAAc,EAAE,MAAM,wBAAwB,CAAC;AAC5F,OAAO,EAAE,oBAAoB,EAAE,MAAM,cAAc,CAAC;AACpD,OAAO,EAAE,kBAAkB,EAAE,eAAe,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC;AACrF,OAAO,EAEN,mBAAmB,GAInB,MAAM,YAAY,CAAC;AAOpB,MAAM,OAAO,sBAAuB,SAAQ,KAAK;IAChD,YAAY,OAAe;QAC1B,KAAK,CAAC,OAAO,CAAC,CAAC;QACf,IAAI,CAAC,IAAI,GAAG,wBAAwB,CAAC;IACtC,CAAC;CACD;AAED,SAAS,iBAAiB,CAAC,KAAmD;IAC7E,IAAI,CAAC,KAAK;QAAE,OAAO,EAAE,CAAC;IACtB,OAAO,KAAK,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,MAAM,KAAK,SAAS,CAAC,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;AACrF,CAAC;AAED,SAAS,iBAAiB,CAAC,IAA2B,EAAE,GAAgB,EAAE,KAAqB;IAC9F,IAAI,CAAC,KAAK;QAAE,OAAO,EAAE,CAAC;IACtB,IAAI,CAAC,IAAI,CAAC,aAAa,IAAI,IAAI,CAAC,aAAa,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,EAAE,CAAC;IAEtE,OAAO,IAAI,CAAC,aAAa;SACvB,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,aAAa,KAAK,GAAG,CAAC,KAAK,IAAI,IAAI,CAAC,eAAe,KAAK,KAAK,CAAC,EAAE,CAAC;SACvF,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;AAC1B,CAAC;AAED,MAAM,UAAU,oBAAoB,CACnC,UAA8B,EAC9B,GAAgB,EAChB,GAAW,EACX,IAAI,GAA0B,EAAE;IAEhC,IAAI,CAAC,mBAAmB,CAAC,GAAG,CAAC,EAAE,CAAC;QAC/B,MAAM,IAAI,sBAAsB,CAAC,iBAAiB,GAAG,CAAC,KAAK,QAAQ,GAAG,CAAC,MAAM,GAAG,CAAC,CAAC;IACnF,CAAC;IACD,MAAM,KAAK,GAAG,oBAAoB,CAAC,UAAU,EAAE,GAAG,CAAC,CAAC;IACpD,IAAI,CAAC,KAAK,EAAE,CAAC;QACZ,MAAM,IAAI,sBAAsB,CAAC,kBAAkB,GAAG,CAAC,cAAc,mCAAmC,CAAC,CAAC;IAC3G,CAAC;IACD,MAAM,MAAM,GAAG,iBAAiB,CAAC,IAAI,EAAE,GAAG,EAAE,KAAK,CAAC,CAAC;IACnD,IAAI,MAAM,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACvB,MAAM,IAAI,sBAAsB,CAC/B,6EAA6E,KAAK,CAAC,EAAE,MAAM,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAChH,CAAC;IACH,CAAC;IACD,MAAM,OAAO,GAAG,iBAAiB,CAAC,IAAI,CAAC,mBAAmB,CAAC,CAAC;IAC5D,IAAI,OAAO,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACxB,MAAM,IAAI,sBAAsB,CAC/B,0DAA0D,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,6BAA6B,CACzG,CAAC;IACH,CAAC;IACD,MAAM,OAAO,GAAG,eAAe,CAAC,cAAc,CAAC,GAAG,CAAC,OAAO,EAAE,KAAK,CAAC,CAAC,CAAC;IACpE,IAAI,OAAO,CAAC,MAAM,KAAK,UAAU,EAAE,CAAC;QACnC,MAAM,IAAI,sBAAsB,CAC/B,qCAAqC,KAAK,CAAC,EAAE,4DAA4D,CACzG,CAAC;IACH,CAAC;IACD,MAAM,YAAY,GAAG,UAAU,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC,SAAS,EAAE,EAAE,CAAC,SAAS,CAAC,EAAE,KAAK,KAAK,CAAC,EAAE,CAAC,CAAC;IAC3F,MAAM,IAAI,GAAG,UAAU,CAAC,MAAM,CAAC,YAAY,GAAG,CAAC,CAAC,CAAC;IACjD,IAAI,CAAC,IAAI,EAAE,CAAC;QACX,MAAM,SAAS,GAAG,kBAAkB,CAAC,EAAE,GAAG,GAAG,EAAE,MAAM,EAAE,WAAW,EAAE,EAAE,GAAG,CAAC,CAAC;QAC3E,OAAO;YACN,GAAG,EAAE,SAAS;YACd,MAAM,EAAE;gBACP,OAAO,EAAE,UAAU;gBACnB,IAAI,EAAE,KAAK,CAAC,EAAE;gBACd,SAAS,EAAE,IAAI;gBACf,MAAM,EAAE,0BAA0B,KAAK,CAAC,EAAE,oBAAoB,GAAG,CAAC,KAAK,YAAY;aACnF;SACD,CAAC;IACH,CAAC;IACD,MAAM,QAAQ,GAAG,kBAAkB,CAAC,EAAE,GAAG,GAAG,EAAE,cAAc,EAAE,IAAI,CAAC,EAAE,EAAE,EAAE,GAAG,CAAC,CAAC;IAC9E,OAAO;QACN,GAAG,EAAE,QAAQ;QACb,MAAM,EAAE;YACP,OAAO,EAAE,UAAU;YACnB,IAAI,EAAE,KAAK,CAAC,EAAE;YACd,EAAE,EAAE,IAAI,CAAC,EAAE;YACX,SAAS,EAAE,KAAK;YAChB,MAAM,EAAE,cAAc,KAAK,CAAC,EAAE,eAAe,IAAI,CAAC,EAAE,MAAM,IAAI,CAAC,QAAQ,CAAC,MAAM,IAAI,IAAI,CAAC,QAAQ,CAAC,KAAK,EAAE;SACvG;KACD,CAAC;AACH,CAAC;AAED,MAAM,UAAU,kBAAkB,CAAC,GAAgB,EAAE,GAAW;IAC/D,IAAI,CAAC,mBAAmB,CAAC,GAAG,CAAC;QAAE,OAAO,GAAG,CAAC;IAC1C,OAAO,kBAAkB,CAAC,EAAE,GAAG,GAAG,EAAE,MAAM,EAAE,WAAW,EAAE,EAAE,GAAG,CAAC,CAAC;AACjE,CAAC;AAED,MAAM,UAAU,gBAAgB,CAC/B,KAAqB,EACrB,GAAW;IAKX,MAAM,OAAO,GACZ,KAAK,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,MAAM,KAAK,aAAa,CAAC;QACzD,KAAK,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,MAAM,KAAK,SAAS,CAAC,CAAC;IACvD,IAAI,CAAC,OAAO,EAAE,CAAC;QACd,MAAM,OAAO,GAAG,KAAK,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,MAAM,KAAK,SAAS,CAAC,CAAC;QACxE,IAAI,OAAO,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACxB,OAAO;gBACN,KAAK;gBACL,MAAM,EAAE;oBACP,OAAO,EAAE,YAAY;oBACrB,SAAS,EAAE,KAAK;oBAChB,MAAM,EAAE,oDAAoD,OAAO,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI;iBACzG;aACD,CAAC;QACH,CAAC;QACD,OAAO;YACN,KAAK;YACL,MAAM,EAAE;gBACP,OAAO,EAAE,YAAY;gBACrB,SAAS,EAAE,IAAI;gBACf,MAAM,EAAE,4BAA4B;aACpC;SACD,CAAC;IACH,CAAC;IACD,IAAI,SAAS,GAAG,KAAK,CAAC;IACtB,IAAI,OAAO,CAAC,MAAM,KAAK,WAAW,EAAE,CAAC;QACpC,SAAS,GAAG,cAAc,CAAC,SAAS,EAAE,OAAO,CAAC,EAAE,EAAE,EAAE,MAAM,EAAE,WAAW,EAAE,EAAE,GAAG,CAAC,CAAC;IACjF,CAAC;IACD,MAAM,SAAS,GAAG,SAAS,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,EAAE,KAAK,OAAO,CAAC,EAAE,IAAI,IAAI,CAAC,MAAM,KAAK,SAAS,CAAC,CAAC;IACtG,IAAI,SAAS,EAAE,CAAC;QACf,SAAS,GAAG,cAAc,CAAC,SAAS,EAAE,SAAS,CAAC,EAAE,EAAE,EAAE,MAAM,EAAE,aAAa,EAAE,EAAE,GAAG,CAAC,CAAC;QACpF,OAAO;YACN,KAAK,EAAE,SAAS;YAChB,MAAM,EAAE;gBACP,OAAO,EAAE,YAAY;gBACrB,IAAI,EAAE,OAAO,CAAC,EAAE;gBAChB,EAAE,EAAE,SAAS,CAAC,EAAE;gBAChB,SAAS,EAAE,KAAK;gBAChB,MAAM,EAAE,aAAa,OAAO,CAAC,EAAE,aAAa,SAAS,CAAC,EAAE,GAAG;aAC3D;SACD,CAAC;IACH,CAAC;IACD,MAAM,OAAO,GAAG,SAAS,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,MAAM,KAAK,SAAS,CAAC,CAAC;IAC5E,IAAI,OAAO,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACxB,OAAO;YACN,KAAK,EAAE,SAAS;YAChB,MAAM,EAAE;gBACP,OAAO,EAAE,YAAY;gBACrB,IAAI,EAAE,OAAO,CAAC,EAAE;gBAChB,SAAS,EAAE,KAAK;gBAChB,MAAM,EAAE,aAAa,OAAO,CAAC,EAAE,kCAAkC,OAAO,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG;aAC7G;SACD,CAAC;IACH,CAAC;IACD,OAAO;QACN,KAAK,EAAE,SAAS;QAChB,MAAM,EAAE;YACP,OAAO,EAAE,YAAY;YACrB,IAAI,EAAE,OAAO,CAAC,EAAE;YAChB,SAAS,EAAE,IAAI;YACf,MAAM,EAAE,aAAa,OAAO,CAAC,EAAE,6BAA6B;SAC5D;KACD,CAAC;AACH,CAAC;AAED,MAAM,UAAU,mBAAmB,CAAC,KAA0B;IAC7D,OAAO,KAAK,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,MAAM,KAAK,aAAa,CAAC,IAAI,KAAK,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,MAAM,KAAK,SAAS,CAAC,CAAC;AAC/G,CAAC","sourcesContent":["import type { BackgroundToolTaskRef } from \"../background-tool-task-controller.ts\";\nimport type { OpenTaskStepRef } from \"../goals/goal-tool-core.ts\";\nimport { type TaskStep, type TaskStepsState, updateTaskStep } from \"../tasks/task-state.ts\";\nimport { currentPipelineStage } from \"./context.ts\";\nimport { persistPipelineRun, scanStageOutput, stageOutputDir } from \"./run-state.ts\";\nimport {\n\ttype IncrementResult,\n\tisPipelineRunActive,\n\ttype PipelineDefinition,\n\ttype PipelineRun,\n\ttype PipelineStage,\n} from \"./types.ts\";\n\nexport interface PipelineIncrementJoin {\n\topenTaskSteps?: readonly OpenTaskStepRef[];\n\tbackgroundToolTasks?: readonly BackgroundToolTaskRef[];\n}\n\nexport class PipelineIncrementError extends Error {\n\tconstructor(message: string) {\n\t\tsuper(message);\n\t\tthis.name = \"PipelineIncrementError\";\n\t}\n}\n\nfunction inFlightToolTasks(tasks: readonly BackgroundToolTaskRef[] | undefined): string[] {\n\tif (!tasks) return [];\n\treturn tasks.filter((task) => task.status === \"running\").map((task) => task.taskId);\n}\n\nfunction linkedOpenStepIds(join: PipelineIncrementJoin, run: PipelineRun, stage?: PipelineStage): string[] {\n\tif (!stage) return [];\n\tif (!join.openTaskSteps || join.openTaskSteps.length === 0) return [];\n\n\treturn join.openTaskSteps\n\t\t.filter((step) => step.pipelineRunId === run.runId && step.pipelineStageId === stage.id)\n\t\t.map((step) => step.id);\n}\n\nexport function incrementPipelineRun(\n\tdefinition: PipelineDefinition,\n\trun: PipelineRun,\n\tnow: string,\n\tjoin: PipelineIncrementJoin = {},\n): { run: PipelineRun; result: IncrementResult } {\n\tif (!isPipelineRunActive(run)) {\n\t\tthrow new PipelineIncrementError(`Pipeline run '${run.runId}' is ${run.status}.`);\n\t}\n\tconst stage = currentPipelineStage(definition, run);\n\tif (!stage) {\n\t\tthrow new PipelineIncrementError(`Current stage '${run.currentStageId}' is missing from the definition.`);\n\t}\n\tconst linked = linkedOpenStepIds(join, run, stage);\n\tif (linked.length > 0) {\n\t\tthrow new PipelineIncrementError(\n\t\t\t`Cannot increment pipeline: open task_steps still reference current stage '${stage.id}' (${linked.join(\", \")}).`,\n\t\t);\n\t}\n\tconst running = inFlightToolTasks(join.backgroundToolTasks);\n\tif (running.length > 0) {\n\t\tthrow new PipelineIncrementError(\n\t\t\t`Cannot increment pipeline: tool_task(s) still running (${running.join(\", \")}). Wait once via tool_task.`,\n\t\t);\n\t}\n\tconst scanned = scanStageOutput(stageOutputDir(run.runRoot, stage));\n\tif (scanned.status !== \"complete\") {\n\t\tthrow new PipelineIncrementError(\n\t\t\t`Cannot increment pipeline: stage '${stage.id}' output/ has no files yet. Write the stage outputs first.`,\n\t\t);\n\t}\n\tconst currentIndex = definition.stages.findIndex((candidate) => candidate.id === stage.id);\n\tconst next = definition.stages[currentIndex + 1];\n\tif (!next) {\n\t\tconst completed = persistPipelineRun({ ...run, status: \"completed\" }, now);\n\t\treturn {\n\t\t\trun: completed,\n\t\t\tresult: {\n\t\t\t\tsurface: \"pipeline\",\n\t\t\t\tfrom: stage.id,\n\t\t\t\tcompleted: true,\n\t\t\t\tdetail: `Completed final stage '${stage.id}'. Pipeline run '${run.runId}' is done.`,\n\t\t\t},\n\t\t};\n\t}\n\tconst advanced = persistPipelineRun({ ...run, currentStageId: next.id }, now);\n\treturn {\n\t\trun: advanced,\n\t\tresult: {\n\t\t\tsurface: \"pipeline\",\n\t\t\tfrom: stage.id,\n\t\t\tto: next.id,\n\t\t\tcompleted: false,\n\t\t\tdetail: `Completed '${stage.id}', started '${next.id}'. ${next.contract.oneJob || next.contract.title}`,\n\t\t},\n\t};\n}\n\nexport function abandonPipelineRun(run: PipelineRun, now: string): PipelineRun {\n\tif (!isPipelineRunActive(run)) return run;\n\treturn persistPipelineRun({ ...run, status: \"abandoned\" }, now);\n}\n\nexport function advanceTaskSteps(\n\tstate: TaskStepsState,\n\tnow: string,\n): {\n\tstate: TaskStepsState;\n\tresult: IncrementResult;\n} {\n\tconst current =\n\t\tstate.steps.find((step) => step.status === \"in_progress\") ??\n\t\tstate.steps.find((step) => step.status === \"pending\");\n\tif (!current) {\n\t\tconst blocked = state.steps.filter((step) => step.status === \"blocked\");\n\t\tif (blocked.length > 0) {\n\t\t\treturn {\n\t\t\t\tstate,\n\t\t\t\tresult: {\n\t\t\t\t\tsurface: \"task_steps\",\n\t\t\t\t\tcompleted: false,\n\t\t\t\t\tdetail: `Cannot advance: all remaining steps are blocked (${blocked.map((step) => step.id).join(\", \")}).`,\n\t\t\t\t},\n\t\t\t};\n\t\t}\n\t\treturn {\n\t\t\tstate,\n\t\t\tresult: {\n\t\t\t\tsurface: \"task_steps\",\n\t\t\t\tcompleted: true,\n\t\t\t\tdetail: \"No open task steps remain.\",\n\t\t\t},\n\t\t};\n\t}\n\tlet nextState = state;\n\tif (current.status !== \"completed\") {\n\t\tnextState = updateTaskStep(nextState, current.id, { status: \"completed\" }, now);\n\t}\n\tconst following = nextState.steps.find((step) => step.id !== current.id && step.status === \"pending\");\n\tif (following) {\n\t\tnextState = updateTaskStep(nextState, following.id, { status: \"in_progress\" }, now);\n\t\treturn {\n\t\t\tstate: nextState,\n\t\t\tresult: {\n\t\t\t\tsurface: \"task_steps\",\n\t\t\t\tfrom: current.id,\n\t\t\t\tto: following.id,\n\t\t\t\tcompleted: false,\n\t\t\t\tdetail: `Completed ${current.id}, started ${following.id}.`,\n\t\t\t},\n\t\t};\n\t}\n\tconst blocked = nextState.steps.filter((step) => step.status === \"blocked\");\n\tif (blocked.length > 0) {\n\t\treturn {\n\t\t\tstate: nextState,\n\t\t\tresult: {\n\t\t\t\tsurface: \"task_steps\",\n\t\t\t\tfrom: current.id,\n\t\t\t\tcompleted: false,\n\t\t\t\tdetail: `Completed ${current.id}. Remaining steps are blocked: ${blocked.map((step) => step.id).join(\", \")}.`,\n\t\t\t},\n\t\t};\n\t}\n\treturn {\n\t\tstate: nextState,\n\t\tresult: {\n\t\t\tsurface: \"task_steps\",\n\t\t\tfrom: current.id,\n\t\t\tcompleted: true,\n\t\t\tdetail: `Completed ${current.id}. No further pending steps.`,\n\t\t},\n\t};\n}\n\nexport function currentOpenTaskStep(steps: readonly TaskStep[]): TaskStep | undefined {\n\treturn steps.find((step) => step.status === \"in_progress\") ?? steps.find((step) => step.status === \"pending\");\n}\n"]}
|
|
@@ -1,8 +1,9 @@
|
|
|
1
|
+
export { type ActivePipelineContext, createActivePipelineContextMessage, resolveActivePipelineContext, } from "./active-context.ts";
|
|
1
2
|
export { assembleStageContext, currentPipelineStage, formatActivePipelineContext, formatPipelineContext, } from "./context.ts";
|
|
2
|
-
export { discoverPipelineDefinitions, findPipelineDefinition, loadPipelineDefinition, projectPipelineRunsDir, projectPipelinesDir, } from "./discover.ts";
|
|
3
|
+
export { discoverPipelineDefinitions, findPipelineDefinition, loadPipelineDefinition, projectPipelineRunsDir, projectPipelinesDir, resolvePipelineDefinitionForRun, } from "./discover.ts";
|
|
3
4
|
export { abandonPipelineRun, advanceTaskSteps, currentOpenTaskStep, incrementPipelineRun, PipelineIncrementError, type PipelineIncrementJoin, } from "./increment.ts";
|
|
4
5
|
export { parseStageContract, parseWorkspaceFrontmatter } from "./parse-contract.ts";
|
|
5
|
-
export { createPipelineRunRoot, findActivePipelineRun, instantiatePipelineRun, loadPipelineRunById, persistPipelineRun, readPipelineRun, scanPipelineRun, scanStageOutput, stageOutputDir, writePipelineRun, } from "./run-state.ts";
|
|
6
|
+
export { createPipelineRunRoot, findActivePipelineRun, instantiatePipelineRun, isProjectPipelineRun, loadPipelineRunById, persistPipelineRun, readPipelineRun, resolveCurrentProjectPipelineRun, resolveProjectPipelineRun, scanPipelineRun, scanStageOutput, stageOutputDir, withPipelineLifecycleLock, writePipelineRun, } from "./run-state.ts";
|
|
6
7
|
export { appendPipelineRunSnapshot, decodePipelineRunSnapshotPayload, getLatestPipelineRunSnapshot, } from "./session-pipeline-run.ts";
|
|
7
|
-
export { type AssembledStageContext, clonePipelineRun, type IncrementResult, isPipelineRun, isPipelineRunActive, PIPELINE_CONTEXT_MARKER, PIPELINE_RUN_CUSTOM_TYPE, PIPELINE_STAGE_FOLDER_RE, type PipelineDefinition, type PipelineForm, type PipelineRun, type PipelineStage, type StageContract, type StageScan, } from "./types.ts";
|
|
8
|
+
export { type AssembledStageContext, clonePipelineRun, type IncrementResult, isPipelineRun, isPipelineRunActive, MAX_PIPELINE_STAGE_ID_LENGTH, PIPELINE_CONTEXT_MARKER, PIPELINE_RUN_CUSTOM_TYPE, PIPELINE_STAGE_FOLDER_RE, type PipelineDefinition, type PipelineForm, type PipelineRun, type PipelineStage, type StageContract, type StageScan, } from "./types.ts";
|
|
8
9
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/core/pipelines/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACN,oBAAoB,EACpB,oBAAoB,EACpB,2BAA2B,EAC3B,qBAAqB,GACrB,MAAM,cAAc,CAAC;AACtB,OAAO,EACN,2BAA2B,EAC3B,sBAAsB,EACtB,sBAAsB,EACtB,sBAAsB,EACtB,mBAAmB,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/core/pipelines/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACN,KAAK,qBAAqB,EAC1B,kCAAkC,EAClC,4BAA4B,GAC5B,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EACN,oBAAoB,EACpB,oBAAoB,EACpB,2BAA2B,EAC3B,qBAAqB,GACrB,MAAM,cAAc,CAAC;AACtB,OAAO,EACN,2BAA2B,EAC3B,sBAAsB,EACtB,sBAAsB,EACtB,sBAAsB,EACtB,mBAAmB,EACnB,+BAA+B,GAC/B,MAAM,eAAe,CAAC;AACvB,OAAO,EACN,kBAAkB,EAClB,gBAAgB,EAChB,mBAAmB,EACnB,oBAAoB,EACpB,sBAAsB,EACtB,KAAK,qBAAqB,GAC1B,MAAM,gBAAgB,CAAC;AACxB,OAAO,EAAE,kBAAkB,EAAE,yBAAyB,EAAE,MAAM,qBAAqB,CAAC;AACpF,OAAO,EACN,qBAAqB,EACrB,qBAAqB,EACrB,sBAAsB,EACtB,oBAAoB,EACpB,mBAAmB,EACnB,kBAAkB,EAClB,eAAe,EACf,gCAAgC,EAChC,yBAAyB,EACzB,eAAe,EACf,eAAe,EACf,cAAc,EACd,yBAAyB,EACzB,gBAAgB,GAChB,MAAM,gBAAgB,CAAC;AACxB,OAAO,EACN,yBAAyB,EACzB,gCAAgC,EAChC,4BAA4B,GAC5B,MAAM,2BAA2B,CAAC;AACnC,OAAO,EACN,KAAK,qBAAqB,EAC1B,gBAAgB,EAChB,KAAK,eAAe,EACpB,aAAa,EACb,mBAAmB,EACnB,4BAA4B,EAC5B,uBAAuB,EACvB,wBAAwB,EACxB,wBAAwB,EACxB,KAAK,kBAAkB,EACvB,KAAK,YAAY,EACjB,KAAK,WAAW,EAChB,KAAK,aAAa,EAClB,KAAK,aAAa,EAClB,KAAK,SAAS,GACd,MAAM,YAAY,CAAC"}
|
|
@@ -1,8 +1,9 @@
|
|
|
1
|
+
export { createActivePipelineContextMessage, resolveActivePipelineContext, } from "./active-context.js";
|
|
1
2
|
export { assembleStageContext, currentPipelineStage, formatActivePipelineContext, formatPipelineContext, } from "./context.js";
|
|
2
|
-
export { discoverPipelineDefinitions, findPipelineDefinition, loadPipelineDefinition, projectPipelineRunsDir, projectPipelinesDir, } from "./discover.js";
|
|
3
|
+
export { discoverPipelineDefinitions, findPipelineDefinition, loadPipelineDefinition, projectPipelineRunsDir, projectPipelinesDir, resolvePipelineDefinitionForRun, } from "./discover.js";
|
|
3
4
|
export { abandonPipelineRun, advanceTaskSteps, currentOpenTaskStep, incrementPipelineRun, PipelineIncrementError, } from "./increment.js";
|
|
4
5
|
export { parseStageContract, parseWorkspaceFrontmatter } from "./parse-contract.js";
|
|
5
|
-
export { createPipelineRunRoot, findActivePipelineRun, instantiatePipelineRun, loadPipelineRunById, persistPipelineRun, readPipelineRun, scanPipelineRun, scanStageOutput, stageOutputDir, writePipelineRun, } from "./run-state.js";
|
|
6
|
+
export { createPipelineRunRoot, findActivePipelineRun, instantiatePipelineRun, isProjectPipelineRun, loadPipelineRunById, persistPipelineRun, readPipelineRun, resolveCurrentProjectPipelineRun, resolveProjectPipelineRun, scanPipelineRun, scanStageOutput, stageOutputDir, withPipelineLifecycleLock, writePipelineRun, } from "./run-state.js";
|
|
6
7
|
export { appendPipelineRunSnapshot, decodePipelineRunSnapshotPayload, getLatestPipelineRunSnapshot, } from "./session-pipeline-run.js";
|
|
7
|
-
export { clonePipelineRun, isPipelineRun, isPipelineRunActive, PIPELINE_CONTEXT_MARKER, PIPELINE_RUN_CUSTOM_TYPE, PIPELINE_STAGE_FOLDER_RE, } from "./types.js";
|
|
8
|
+
export { clonePipelineRun, isPipelineRun, isPipelineRunActive, MAX_PIPELINE_STAGE_ID_LENGTH, PIPELINE_CONTEXT_MARKER, PIPELINE_RUN_CUSTOM_TYPE, PIPELINE_STAGE_FOLDER_RE, } from "./types.js";
|
|
8
9
|
//# sourceMappingURL=index.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/core/pipelines/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACN,oBAAoB,EACpB,oBAAoB,EACpB,2BAA2B,EAC3B,qBAAqB,GACrB,MAAM,cAAc,CAAC;AACtB,OAAO,EACN,2BAA2B,EAC3B,sBAAsB,EACtB,sBAAsB,EACtB,sBAAsB,EACtB,mBAAmB,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/core/pipelines/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAEN,kCAAkC,EAClC,4BAA4B,GAC5B,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EACN,oBAAoB,EACpB,oBAAoB,EACpB,2BAA2B,EAC3B,qBAAqB,GACrB,MAAM,cAAc,CAAC;AACtB,OAAO,EACN,2BAA2B,EAC3B,sBAAsB,EACtB,sBAAsB,EACtB,sBAAsB,EACtB,mBAAmB,EACnB,+BAA+B,GAC/B,MAAM,eAAe,CAAC;AACvB,OAAO,EACN,kBAAkB,EAClB,gBAAgB,EAChB,mBAAmB,EACnB,oBAAoB,EACpB,sBAAsB,GAEtB,MAAM,gBAAgB,CAAC;AACxB,OAAO,EAAE,kBAAkB,EAAE,yBAAyB,EAAE,MAAM,qBAAqB,CAAC;AACpF,OAAO,EACN,qBAAqB,EACrB,qBAAqB,EACrB,sBAAsB,EACtB,oBAAoB,EACpB,mBAAmB,EACnB,kBAAkB,EAClB,eAAe,EACf,gCAAgC,EAChC,yBAAyB,EACzB,eAAe,EACf,eAAe,EACf,cAAc,EACd,yBAAyB,EACzB,gBAAgB,GAChB,MAAM,gBAAgB,CAAC;AACxB,OAAO,EACN,yBAAyB,EACzB,gCAAgC,EAChC,4BAA4B,GAC5B,MAAM,2BAA2B,CAAC;AACnC,OAAO,EAEN,gBAAgB,EAEhB,aAAa,EACb,mBAAmB,EACnB,4BAA4B,EAC5B,uBAAuB,EACvB,wBAAwB,EACxB,wBAAwB,GAOxB,MAAM,YAAY,CAAC","sourcesContent":["export {\n\ttype ActivePipelineContext,\n\tcreateActivePipelineContextMessage,\n\tresolveActivePipelineContext,\n} from \"./active-context.ts\";\nexport {\n\tassembleStageContext,\n\tcurrentPipelineStage,\n\tformatActivePipelineContext,\n\tformatPipelineContext,\n} from \"./context.ts\";\nexport {\n\tdiscoverPipelineDefinitions,\n\tfindPipelineDefinition,\n\tloadPipelineDefinition,\n\tprojectPipelineRunsDir,\n\tprojectPipelinesDir,\n\tresolvePipelineDefinitionForRun,\n} from \"./discover.ts\";\nexport {\n\tabandonPipelineRun,\n\tadvanceTaskSteps,\n\tcurrentOpenTaskStep,\n\tincrementPipelineRun,\n\tPipelineIncrementError,\n\ttype PipelineIncrementJoin,\n} from \"./increment.ts\";\nexport { parseStageContract, parseWorkspaceFrontmatter } from \"./parse-contract.ts\";\nexport {\n\tcreatePipelineRunRoot,\n\tfindActivePipelineRun,\n\tinstantiatePipelineRun,\n\tisProjectPipelineRun,\n\tloadPipelineRunById,\n\tpersistPipelineRun,\n\treadPipelineRun,\n\tresolveCurrentProjectPipelineRun,\n\tresolveProjectPipelineRun,\n\tscanPipelineRun,\n\tscanStageOutput,\n\tstageOutputDir,\n\twithPipelineLifecycleLock,\n\twritePipelineRun,\n} from \"./run-state.ts\";\nexport {\n\tappendPipelineRunSnapshot,\n\tdecodePipelineRunSnapshotPayload,\n\tgetLatestPipelineRunSnapshot,\n} from \"./session-pipeline-run.ts\";\nexport {\n\ttype AssembledStageContext,\n\tclonePipelineRun,\n\ttype IncrementResult,\n\tisPipelineRun,\n\tisPipelineRunActive,\n\tMAX_PIPELINE_STAGE_ID_LENGTH,\n\tPIPELINE_CONTEXT_MARKER,\n\tPIPELINE_RUN_CUSTOM_TYPE,\n\tPIPELINE_STAGE_FOLDER_RE,\n\ttype PipelineDefinition,\n\ttype PipelineForm,\n\ttype PipelineRun,\n\ttype PipelineStage,\n\ttype StageContract,\n\ttype StageScan,\n} from \"./types.ts\";\n"]}
|
|
@@ -11,6 +11,14 @@ export declare function parsePipelineRun(value: unknown): PipelineRun | undefine
|
|
|
11
11
|
export declare function readPipelineRun(runRoot: string): PipelineRun | undefined;
|
|
12
12
|
export declare function writePipelineRun(run: PipelineRun): void;
|
|
13
13
|
export declare function createPipelineRunRoot(cwd: string, runId: string): string;
|
|
14
|
+
/** Serialize project-wide pipeline admission and transitions across sessions and OS processes. */
|
|
15
|
+
export declare function withPipelineLifecycleLock<T>(cwd: string, mutate: () => T): T;
|
|
16
|
+
/** A restored run may operate only on its exact project-owned run directory. */
|
|
17
|
+
export declare function isProjectPipelineRun(cwd: string, run: PipelineRun): boolean;
|
|
18
|
+
/** Resolve the exact validated durable manifest for a project-owned session snapshot. */
|
|
19
|
+
export declare function resolveProjectPipelineRun(cwd: string, run: PipelineRun): PipelineRun | undefined;
|
|
20
|
+
/** Resolve the durable project-wide current run, using a session snapshot only as an identity hint. */
|
|
21
|
+
export declare function resolveCurrentProjectPipelineRun(cwd: string, snapshot?: PipelineRun): PipelineRun | undefined;
|
|
14
22
|
export declare function instantiatePipelineRun(args: {
|
|
15
23
|
definition: PipelineDefinition;
|
|
16
24
|
runId: string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"run-state.d.ts","sourceRoot":"","sources":["../../../src/core/pipelines/run-state.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"run-state.d.ts","sourceRoot":"","sources":["../../../src/core/pipelines/run-state.ts"],"names":[],"mappings":"AAQA,OAAO,EAIN,KAAK,kBAAkB,EACvB,KAAK,WAAW,EAChB,KAAK,aAAa,EAClB,KAAK,eAAe,EACpB,KAAK,SAAS,EACd,MAAM,YAAY,CAAC;AAEpB,eAAO,MAAM,iBAAiB,aAAa,CAAC;AAqE5C,wBAAgB,eAAe,CAAC,SAAS,EAAE,MAAM,GAAG;IAAE,MAAM,EAAE,eAAe,CAAC;IAAC,WAAW,EAAE,MAAM,EAAE,CAAA;CAAE,CASrG;AAED,wBAAgB,cAAc,CAAC,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,aAAa,GAAG,MAAM,CAE5E;AAED,wBAAgB,eAAe,CAAC,UAAU,EAAE,kBAAkB,EAAE,GAAG,EAAE,WAAW,GAAG,SAAS,SAAS,EAAE,CAKtG;AAED,wBAAgB,eAAe,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAEvD;AAED,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,OAAO,GAAG,WAAW,GAAG,SAAS,CAGxE;AAED,wBAAgB,eAAe,CAAC,OAAO,EAAE,MAAM,GAAG,WAAW,GAAG,SAAS,CA4BxE;AAED,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,WAAW,GAAG,IAAI,CAYvD;AAED,wBAAgB,qBAAqB,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,CAGxE;AAED,kGAAkG;AAClG,wBAAgB,yBAAyB,CAAC,CAAC,EAAE,GAAG,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,GAAG,CAAC,CAS5E;AAED,gFAAgF;AAChF,wBAAgB,oBAAoB,CAAC,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,WAAW,GAAG,OAAO,CAS3E;AAED,yFAAyF;AACzF,wBAAgB,yBAAyB,CAAC,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,WAAW,GAAG,WAAW,GAAG,SAAS,CAGhG;AAED,uGAAuG;AACvG,wBAAgB,gCAAgC,CAAC,GAAG,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,WAAW,GAAG,WAAW,GAAG,SAAS,CAG7G;AAED,wBAAgB,sBAAsB,CAAC,IAAI,EAAE;IAC5C,UAAU,EAAE,kBAAkB,CAAC;IAC/B,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,GAAG,EAAE,MAAM,CAAC;CACZ,GAAG,WAAW,CAqBd;AAED,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,WAAW,EAAE,GAAG,EAAE,MAAM,GAAG,WAAW,CAI7E;AAED,wBAAgB,qBAAqB,CAAC,GAAG,EAAE,MAAM,GAAG,WAAW,GAAG,SAAS,CA6B1E;AAED,wBAAgB,mBAAmB,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,WAAW,GAAG,SAAS,CAUvF;AAED,wBAAgB,wBAAwB,CAAC,IAAI,EAAE,OAAO,GAAG,WAAW,GAAG,SAAS,CAI/E;AAED,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAE5D"}
|
|
@@ -1,29 +1,84 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { dirname, join } from "node:path";
|
|
3
|
-
import {
|
|
1
|
+
import { lstatSync, mkdirSync, opendirSync, statSync } from "node:fs";
|
|
2
|
+
import { basename, dirname, join } from "node:path";
|
|
3
|
+
import { assertPortablePathSegment } from "../../utils/work-directory.js";
|
|
4
|
+
import { canonicalPathScopeIdentity, isPathWithinScope, safeRealpathSync } from "../autonomy/path-scope.js";
|
|
5
|
+
import { withFileLockSync, writeFileAtomicSync } from "../util/atomic-file.js";
|
|
6
|
+
import { readBoundedDirectoryNamesSync, readBoundedTextFileSync } from "../util/bounded-file.js";
|
|
4
7
|
import { isPlainRecord } from "../util/value-guards.js";
|
|
5
|
-
import {
|
|
6
|
-
import { clonePipelineRun, isPipelineRun, } from "./types.js";
|
|
8
|
+
import { assertProjectPipelineDirectory } from "./discover.js";
|
|
9
|
+
import { clonePipelineRun, isPipelineRun, isPipelineRunActive, } from "./types.js";
|
|
7
10
|
export const RUN_MANIFEST_NAME = "run.json";
|
|
11
|
+
const MAX_STAGE_OUTPUT_SCAN_DEPTH = 16;
|
|
12
|
+
const MAX_STAGE_OUTPUT_SCAN_ENTRIES = 1000;
|
|
13
|
+
const MAX_PIPELINE_RUN_MANIFEST_BYTES = 64 * 1024;
|
|
14
|
+
const MAX_PIPELINE_RUN_SCAN_ENTRIES = 1_024;
|
|
15
|
+
const PIPELINE_LIFECYCLE_LOCK_NAME = ".lifecycle";
|
|
8
16
|
function isRealOutputFile(name) {
|
|
9
17
|
return name !== ".gitkeep" && name !== ".DS_Store" && !name.startsWith(".");
|
|
10
18
|
}
|
|
11
|
-
|
|
12
|
-
if (
|
|
13
|
-
return
|
|
19
|
+
function collectOutputFiles(realBaseDir, currentDir, relativePrefix = "", depth = 0, collected = [], budget = { visitedEntries: 0 }) {
|
|
20
|
+
if (depth > MAX_STAGE_OUTPUT_SCAN_DEPTH || budget.visitedEntries >= MAX_STAGE_OUTPUT_SCAN_ENTRIES) {
|
|
21
|
+
return collected;
|
|
22
|
+
}
|
|
23
|
+
let directory;
|
|
24
|
+
try {
|
|
25
|
+
directory = opendirSync(currentDir);
|
|
26
|
+
}
|
|
27
|
+
catch {
|
|
28
|
+
return collected;
|
|
29
|
+
}
|
|
14
30
|
try {
|
|
15
|
-
|
|
16
|
-
.
|
|
17
|
-
if (!
|
|
18
|
-
|
|
31
|
+
while (budget.visitedEntries < MAX_STAGE_OUTPUT_SCAN_ENTRIES) {
|
|
32
|
+
const dirent = directory.readSync();
|
|
33
|
+
if (!dirent)
|
|
34
|
+
break;
|
|
35
|
+
budget.visitedEntries++;
|
|
36
|
+
const entry = dirent.name;
|
|
37
|
+
if (!isRealOutputFile(entry))
|
|
38
|
+
continue;
|
|
39
|
+
const fullPath = join(currentDir, entry);
|
|
40
|
+
const relPath = relativePrefix ? `${relativePrefix}/${entry}` : entry;
|
|
19
41
|
try {
|
|
20
|
-
|
|
42
|
+
const real = safeRealpathSync(fullPath);
|
|
43
|
+
if (!isPathWithinScope(real, realBaseDir))
|
|
44
|
+
continue;
|
|
45
|
+
const lstat = lstatSync(fullPath);
|
|
46
|
+
if (lstat.isSymbolicLink()) {
|
|
47
|
+
const realStat = statSync(real);
|
|
48
|
+
if (realStat.isFile())
|
|
49
|
+
collected.push(relPath);
|
|
50
|
+
}
|
|
51
|
+
else if (lstat.isFile()) {
|
|
52
|
+
collected.push(relPath);
|
|
53
|
+
}
|
|
54
|
+
else if (lstat.isDirectory()) {
|
|
55
|
+
collectOutputFiles(realBaseDir, fullPath, relPath, depth + 1, collected, budget);
|
|
56
|
+
}
|
|
21
57
|
}
|
|
22
58
|
catch {
|
|
23
|
-
|
|
59
|
+
// Ignore unreadable entries
|
|
24
60
|
}
|
|
25
|
-
}
|
|
26
|
-
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
catch {
|
|
64
|
+
return collected;
|
|
65
|
+
}
|
|
66
|
+
finally {
|
|
67
|
+
try {
|
|
68
|
+
directory.closeSync();
|
|
69
|
+
}
|
|
70
|
+
catch {
|
|
71
|
+
// The scan result remains valid if the OS already closed the directory handle.
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
return collected;
|
|
75
|
+
}
|
|
76
|
+
export function scanStageOutput(outputDir) {
|
|
77
|
+
try {
|
|
78
|
+
const root = lstatSync(outputDir);
|
|
79
|
+
if (root.isSymbolicLink() || !root.isDirectory())
|
|
80
|
+
return { status: "empty", outputFiles: [] };
|
|
81
|
+
const outputFiles = collectOutputFiles(safeRealpathSync(outputDir), outputDir).sort();
|
|
27
82
|
return { status: outputFiles.length > 0 ? "complete" : "empty", outputFiles };
|
|
28
83
|
}
|
|
29
84
|
catch {
|
|
@@ -49,10 +104,23 @@ export function parsePipelineRun(value) {
|
|
|
49
104
|
}
|
|
50
105
|
export function readPipelineRun(runRoot) {
|
|
51
106
|
try {
|
|
52
|
-
const
|
|
107
|
+
const rootStats = lstatSync(runRoot);
|
|
108
|
+
if (!rootStats.isDirectory() || rootStats.isSymbolicLink())
|
|
109
|
+
return undefined;
|
|
110
|
+
const manifestPath = runManifestPath(runRoot);
|
|
111
|
+
const manifestStats = lstatSync(manifestPath);
|
|
112
|
+
if (!manifestStats.isFile() ||
|
|
113
|
+
manifestStats.isSymbolicLink() ||
|
|
114
|
+
manifestStats.size > MAX_PIPELINE_RUN_MANIFEST_BYTES) {
|
|
115
|
+
return undefined;
|
|
116
|
+
}
|
|
117
|
+
const parsed = JSON.parse(readBoundedTextFileSync(manifestPath, MAX_PIPELINE_RUN_MANIFEST_BYTES, "Pipeline run manifest"));
|
|
53
118
|
const run = parsePipelineRun(parsed);
|
|
54
|
-
if (!run ||
|
|
119
|
+
if (!run ||
|
|
120
|
+
canonicalPathScopeIdentity(run.runRoot) !== canonicalPathScopeIdentity(runRoot) ||
|
|
121
|
+
basename(runRoot) !== run.runId) {
|
|
55
122
|
return undefined;
|
|
123
|
+
}
|
|
56
124
|
return run;
|
|
57
125
|
}
|
|
58
126
|
catch {
|
|
@@ -60,11 +128,57 @@ export function readPipelineRun(runRoot) {
|
|
|
60
128
|
}
|
|
61
129
|
}
|
|
62
130
|
export function writePipelineRun(run) {
|
|
131
|
+
if (!isPipelineRun(run))
|
|
132
|
+
throw new Error("Pipeline run state is invalid and was not persisted.");
|
|
133
|
+
assertPortablePathSegment("Pipeline run id", run.runId);
|
|
134
|
+
if (basename(run.runRoot) !== run.runId) {
|
|
135
|
+
throw new Error("Pipeline run root must end with its exact run id.");
|
|
136
|
+
}
|
|
63
137
|
mkdirSync(run.runRoot, { recursive: true });
|
|
138
|
+
const rootStats = lstatSync(run.runRoot);
|
|
139
|
+
if (!rootStats.isDirectory() || rootStats.isSymbolicLink()) {
|
|
140
|
+
throw new Error(`Pipeline run root is not a real directory: ${run.runRoot}`);
|
|
141
|
+
}
|
|
64
142
|
writeFileAtomicSync(runManifestPath(run.runRoot), `${JSON.stringify(run, null, 2)}\n`);
|
|
65
143
|
}
|
|
66
144
|
export function createPipelineRunRoot(cwd, runId) {
|
|
67
|
-
|
|
145
|
+
assertPortablePathSegment("Pipeline run id", runId);
|
|
146
|
+
return join(assertProjectPipelineDirectory(cwd, "pipeline-runs"), runId);
|
|
147
|
+
}
|
|
148
|
+
/** Serialize project-wide pipeline admission and transitions across sessions and OS processes. */
|
|
149
|
+
export function withPipelineLifecycleLock(cwd, mutate) {
|
|
150
|
+
const runsRoot = assertProjectPipelineDirectory(cwd, "pipeline-runs");
|
|
151
|
+
return withFileLockSync(join(runsRoot, PIPELINE_LIFECYCLE_LOCK_NAME), () => {
|
|
152
|
+
const verifiedRoot = assertProjectPipelineDirectory(cwd, "pipeline-runs");
|
|
153
|
+
if (canonicalPathScopeIdentity(verifiedRoot) !== canonicalPathScopeIdentity(runsRoot)) {
|
|
154
|
+
throw new Error("Project pipeline-runs directory changed during lifecycle lock acquisition.");
|
|
155
|
+
}
|
|
156
|
+
return mutate();
|
|
157
|
+
});
|
|
158
|
+
}
|
|
159
|
+
/** A restored run may operate only on its exact project-owned run directory. */
|
|
160
|
+
export function isProjectPipelineRun(cwd, run) {
|
|
161
|
+
try {
|
|
162
|
+
const expectedRoot = createPipelineRunRoot(cwd, run.runId);
|
|
163
|
+
if (canonicalPathScopeIdentity(run.runRoot) !== canonicalPathScopeIdentity(expectedRoot))
|
|
164
|
+
return false;
|
|
165
|
+
const rootStats = lstatSync(expectedRoot);
|
|
166
|
+
return rootStats.isDirectory() && !rootStats.isSymbolicLink();
|
|
167
|
+
}
|
|
168
|
+
catch {
|
|
169
|
+
return false;
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
/** Resolve the exact validated durable manifest for a project-owned session snapshot. */
|
|
173
|
+
export function resolveProjectPipelineRun(cwd, run) {
|
|
174
|
+
if (!isProjectPipelineRun(cwd, run))
|
|
175
|
+
return undefined;
|
|
176
|
+
return readPipelineRun(createPipelineRunRoot(cwd, run.runId));
|
|
177
|
+
}
|
|
178
|
+
/** Resolve the durable project-wide current run, using a session snapshot only as an identity hint. */
|
|
179
|
+
export function resolveCurrentProjectPipelineRun(cwd, snapshot) {
|
|
180
|
+
const durableSnapshot = snapshot ? resolveProjectPipelineRun(cwd, snapshot) : undefined;
|
|
181
|
+
return findActivePipelineRun(cwd) ?? durableSnapshot;
|
|
68
182
|
}
|
|
69
183
|
export function instantiatePipelineRun(args) {
|
|
70
184
|
const first = args.definition.stages[0];
|
|
@@ -95,33 +209,53 @@ export function persistPipelineRun(run, now) {
|
|
|
95
209
|
return next;
|
|
96
210
|
}
|
|
97
211
|
export function findActivePipelineRun(cwd) {
|
|
98
|
-
|
|
99
|
-
if (!existsSync(root))
|
|
100
|
-
return undefined;
|
|
101
|
-
let latest;
|
|
212
|
+
let root;
|
|
102
213
|
try {
|
|
103
|
-
|
|
104
|
-
const run = readPipelineRun(join(root, name));
|
|
105
|
-
if (!run || run.status !== "active")
|
|
106
|
-
continue;
|
|
107
|
-
if (!latest || run.updatedAt > latest.updatedAt)
|
|
108
|
-
latest = run;
|
|
109
|
-
}
|
|
214
|
+
root = assertProjectPipelineDirectory(cwd, "pipeline-runs");
|
|
110
215
|
}
|
|
111
|
-
catch {
|
|
112
|
-
|
|
216
|
+
catch (error) {
|
|
217
|
+
if (error.code === "ENOENT")
|
|
218
|
+
return undefined;
|
|
219
|
+
throw error;
|
|
220
|
+
}
|
|
221
|
+
let names;
|
|
222
|
+
try {
|
|
223
|
+
names = readBoundedDirectoryNamesSync(root, MAX_PIPELINE_RUN_SCAN_ENTRIES, "Pipeline run directory");
|
|
113
224
|
}
|
|
114
|
-
|
|
225
|
+
catch (error) {
|
|
226
|
+
if (error.code === "ENOENT")
|
|
227
|
+
return undefined;
|
|
228
|
+
throw error;
|
|
229
|
+
}
|
|
230
|
+
let active;
|
|
231
|
+
for (const name of names) {
|
|
232
|
+
if (name.startsWith("."))
|
|
233
|
+
continue;
|
|
234
|
+
const run = readPipelineRun(join(root, name));
|
|
235
|
+
if (!run) {
|
|
236
|
+
throw new Error(`Pipeline run directory contains an invalid managed entry: ${name}`);
|
|
237
|
+
}
|
|
238
|
+
if (!isPipelineRunActive(run))
|
|
239
|
+
continue;
|
|
240
|
+
if (active) {
|
|
241
|
+
throw new Error(`Pipeline run directory contains multiple active runs: ${active.runId}, ${run.runId}`);
|
|
242
|
+
}
|
|
243
|
+
active = run;
|
|
244
|
+
}
|
|
245
|
+
return active;
|
|
115
246
|
}
|
|
116
247
|
export function loadPipelineRunById(cwd, runId) {
|
|
117
248
|
const trimmed = runId.trim();
|
|
118
249
|
if (!trimmed)
|
|
119
250
|
return undefined;
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
251
|
+
let runRoot;
|
|
252
|
+
try {
|
|
253
|
+
runRoot = createPipelineRunRoot(cwd, trimmed);
|
|
254
|
+
}
|
|
255
|
+
catch {
|
|
256
|
+
return undefined;
|
|
257
|
+
}
|
|
258
|
+
return readPipelineRun(runRoot);
|
|
125
259
|
}
|
|
126
260
|
export function decodePipelineRunPayload(data) {
|
|
127
261
|
if (!isPlainRecord(data))
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"run-state.js","sourceRoot":"","sources":["../../../src/core/pipelines/run-state.ts"],"names":[],"mappings":"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","sourcesContent":["import { existsSync, mkdirSync, readdirSync, readFileSync, statSync } from \"node:fs\";\nimport { dirname, join } from \"node:path\";\nimport { writeFileAtomicSync } from \"../util/atomic-file.ts\";\nimport { isPlainRecord } from \"../util/value-guards.ts\";\nimport { projectPipelineRunsDir } from \"./discover.ts\";\nimport {\n\tclonePipelineRun,\n\tisPipelineRun,\n\ttype PipelineDefinition,\n\ttype PipelineRun,\n\ttype PipelineStage,\n\ttype StageDiskStatus,\n\ttype StageScan,\n} from \"./types.ts\";\n\nexport const RUN_MANIFEST_NAME = \"run.json\";\n\nfunction isRealOutputFile(name: string): boolean {\n\treturn name !== \".gitkeep\" && name !== \".DS_Store\" && !name.startsWith(\".\");\n}\n\nexport function scanStageOutput(outputDir: string): { status: StageDiskStatus; outputFiles: string[] } {\n\tif (!existsSync(outputDir)) return { status: \"empty\", outputFiles: [] };\n\ttry {\n\t\tconst outputFiles = readdirSync(outputDir)\n\t\t\t.filter((name) => {\n\t\t\t\tif (!isRealOutputFile(name)) return false;\n\t\t\t\ttry {\n\t\t\t\t\treturn statSync(join(outputDir, name)).isFile();\n\t\t\t\t} catch {\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t})\n\t\t\t.sort();\n\t\treturn { status: outputFiles.length > 0 ? \"complete\" : \"empty\", outputFiles };\n\t} catch {\n\t\treturn { status: \"empty\", outputFiles: [] };\n\t}\n}\n\nexport function stageOutputDir(runRoot: string, stage: PipelineStage): string {\n\treturn join(runRoot, stage.folderName, \"output\");\n}\n\nexport function scanPipelineRun(definition: PipelineDefinition, run: PipelineRun): readonly StageScan[] {\n\treturn definition.stages.map((stage) => {\n\t\tconst scanned = scanStageOutput(stageOutputDir(run.runRoot, stage));\n\t\treturn { stageId: stage.id, status: scanned.status, outputFiles: scanned.outputFiles };\n\t});\n}\n\nexport function runManifestPath(runRoot: string): string {\n\treturn join(runRoot, RUN_MANIFEST_NAME);\n}\n\nexport function parsePipelineRun(value: unknown): PipelineRun | undefined {\n\tif (!isPipelineRun(value)) return undefined;\n\treturn clonePipelineRun(value);\n}\n\nexport function readPipelineRun(runRoot: string): PipelineRun | undefined {\n\ttry {\n\t\tconst parsed: unknown = JSON.parse(readFileSync(runManifestPath(runRoot), \"utf8\"));\n\t\tconst run = parsePipelineRun(parsed);\n\t\tif (!run || run.runRoot !== runRoot) return undefined;\n\t\treturn run;\n\t} catch {\n\t\treturn undefined;\n\t}\n}\n\nexport function writePipelineRun(run: PipelineRun): void {\n\tmkdirSync(run.runRoot, { recursive: true });\n\twriteFileAtomicSync(runManifestPath(run.runRoot), `${JSON.stringify(run, null, 2)}\\n`);\n}\n\nexport function createPipelineRunRoot(cwd: string, runId: string): string {\n\treturn join(projectPipelineRunsDir(cwd), runId);\n}\n\nexport function instantiatePipelineRun(args: {\n\tdefinition: PipelineDefinition;\n\trunId: string;\n\trunRoot: string;\n\tgoalId?: string;\n\tnow: string;\n}): PipelineRun {\n\tconst first = args.definition.stages[0];\n\tif (!first) throw new Error(\"Pipeline definition has no stages.\");\n\tfor (const stage of args.definition.stages) {\n\t\tmkdirSync(stageOutputDir(args.runRoot, stage), { recursive: true });\n\t}\n\tconst run: PipelineRun = {\n\t\tversion: 1,\n\t\trevision: 1,\n\t\trunId: args.runId,\n\t\tpipelineName: args.definition.name,\n\t\tdefinitionPath: args.definition.rootDir,\n\t\trunRoot: args.runRoot,\n\t\tcurrentStageId: first.id,\n\t\tstatus: \"active\",\n\t\tgoalId: args.goalId,\n\t\tcreatedAt: args.now,\n\t\tupdatedAt: args.now,\n\t};\n\twritePipelineRun(run);\n\treturn run;\n}\n\nexport function persistPipelineRun(run: PipelineRun, now: string): PipelineRun {\n\tconst next = { ...run, revision: run.revision + 1, updatedAt: now };\n\twritePipelineRun(next);\n\treturn next;\n}\n\nexport function findActivePipelineRun(cwd: string): PipelineRun | undefined {\n\tconst root = projectPipelineRunsDir(cwd);\n\tif (!existsSync(root)) return undefined;\n\tlet latest: PipelineRun | undefined;\n\ttry {\n\t\tfor (const name of readdirSync(root)) {\n\t\t\tconst run = readPipelineRun(join(root, name));\n\t\t\tif (!run || run.status !== \"active\") continue;\n\t\t\tif (!latest || run.updatedAt > latest.updatedAt) latest = run;\n\t\t}\n\t} catch {\n\t\treturn latest;\n\t}\n\treturn latest;\n}\n\nexport function loadPipelineRunById(cwd: string, runId: string): PipelineRun | undefined {\n\tconst trimmed = runId.trim();\n\tif (!trimmed) return undefined;\n\tconst fromDisk = readPipelineRun(join(projectPipelineRunsDir(cwd), trimmed));\n\tif (fromDisk) return fromDisk;\n\tconst active = findActivePipelineRun(cwd);\n\treturn active?.runId === trimmed ? active : undefined;\n}\n\nexport function decodePipelineRunPayload(data: unknown): PipelineRun | undefined {\n\tif (!isPlainRecord(data)) return undefined;\n\tconst value = data.run ?? data;\n\treturn parsePipelineRun(value);\n}\n\nexport function pipelineRunParentDir(runRoot: string): string {\n\treturn dirname(runRoot);\n}\n"]}
|
|
1
|
+
{"version":3,"file":"run-state.js","sourceRoot":"","sources":["../../../src/core/pipelines/run-state.ts"],"names":[],"mappings":"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","sourcesContent":["import { lstatSync, mkdirSync, opendirSync, statSync } from \"node:fs\";\nimport { basename, dirname, join } from \"node:path\";\nimport { assertPortablePathSegment } from \"../../utils/work-directory.ts\";\nimport { canonicalPathScopeIdentity, isPathWithinScope, safeRealpathSync } from \"../autonomy/path-scope.ts\";\nimport { withFileLockSync, writeFileAtomicSync } from \"../util/atomic-file.ts\";\nimport { readBoundedDirectoryNamesSync, readBoundedTextFileSync } from \"../util/bounded-file.ts\";\nimport { isPlainRecord } from \"../util/value-guards.ts\";\nimport { assertProjectPipelineDirectory } from \"./discover.ts\";\nimport {\n\tclonePipelineRun,\n\tisPipelineRun,\n\tisPipelineRunActive,\n\ttype PipelineDefinition,\n\ttype PipelineRun,\n\ttype PipelineStage,\n\ttype StageDiskStatus,\n\ttype StageScan,\n} from \"./types.ts\";\n\nexport const RUN_MANIFEST_NAME = \"run.json\";\nconst MAX_STAGE_OUTPUT_SCAN_DEPTH = 16;\nconst MAX_STAGE_OUTPUT_SCAN_ENTRIES = 1000;\nconst MAX_PIPELINE_RUN_MANIFEST_BYTES = 64 * 1024;\nconst MAX_PIPELINE_RUN_SCAN_ENTRIES = 1_024;\nconst PIPELINE_LIFECYCLE_LOCK_NAME = \".lifecycle\";\n\ninterface StageOutputScanBudget {\n\tvisitedEntries: number;\n}\n\nfunction isRealOutputFile(name: string): boolean {\n\treturn name !== \".gitkeep\" && name !== \".DS_Store\" && !name.startsWith(\".\");\n}\n\nfunction collectOutputFiles(\n\trealBaseDir: string,\n\tcurrentDir: string,\n\trelativePrefix = \"\",\n\tdepth = 0,\n\tcollected: string[] = [],\n\tbudget: StageOutputScanBudget = { visitedEntries: 0 },\n): string[] {\n\tif (depth > MAX_STAGE_OUTPUT_SCAN_DEPTH || budget.visitedEntries >= MAX_STAGE_OUTPUT_SCAN_ENTRIES) {\n\t\treturn collected;\n\t}\n\tlet directory: ReturnType<typeof opendirSync>;\n\ttry {\n\t\tdirectory = opendirSync(currentDir);\n\t} catch {\n\t\treturn collected;\n\t}\n\ttry {\n\t\twhile (budget.visitedEntries < MAX_STAGE_OUTPUT_SCAN_ENTRIES) {\n\t\t\tconst dirent = directory.readSync();\n\t\t\tif (!dirent) break;\n\t\t\tbudget.visitedEntries++;\n\t\t\tconst entry = dirent.name;\n\t\t\tif (!isRealOutputFile(entry)) continue;\n\t\t\tconst fullPath = join(currentDir, entry);\n\t\t\tconst relPath = relativePrefix ? `${relativePrefix}/${entry}` : entry;\n\t\t\ttry {\n\t\t\t\tconst real = safeRealpathSync(fullPath);\n\t\t\t\tif (!isPathWithinScope(real, realBaseDir)) continue;\n\t\t\t\tconst lstat = lstatSync(fullPath);\n\t\t\t\tif (lstat.isSymbolicLink()) {\n\t\t\t\t\tconst realStat = statSync(real);\n\t\t\t\t\tif (realStat.isFile()) collected.push(relPath);\n\t\t\t\t} else if (lstat.isFile()) {\n\t\t\t\t\tcollected.push(relPath);\n\t\t\t\t} else if (lstat.isDirectory()) {\n\t\t\t\t\tcollectOutputFiles(realBaseDir, fullPath, relPath, depth + 1, collected, budget);\n\t\t\t\t}\n\t\t\t} catch {\n\t\t\t\t// Ignore unreadable entries\n\t\t\t}\n\t\t}\n\t} catch {\n\t\treturn collected;\n\t} finally {\n\t\ttry {\n\t\t\tdirectory.closeSync();\n\t\t} catch {\n\t\t\t// The scan result remains valid if the OS already closed the directory handle.\n\t\t}\n\t}\n\treturn collected;\n}\n\nexport function scanStageOutput(outputDir: string): { status: StageDiskStatus; outputFiles: string[] } {\n\ttry {\n\t\tconst root = lstatSync(outputDir);\n\t\tif (root.isSymbolicLink() || !root.isDirectory()) return { status: \"empty\", outputFiles: [] };\n\t\tconst outputFiles = collectOutputFiles(safeRealpathSync(outputDir), outputDir).sort();\n\t\treturn { status: outputFiles.length > 0 ? \"complete\" : \"empty\", outputFiles };\n\t} catch {\n\t\treturn { status: \"empty\", outputFiles: [] };\n\t}\n}\n\nexport function stageOutputDir(runRoot: string, stage: PipelineStage): string {\n\treturn join(runRoot, stage.folderName, \"output\");\n}\n\nexport function scanPipelineRun(definition: PipelineDefinition, run: PipelineRun): readonly StageScan[] {\n\treturn definition.stages.map((stage) => {\n\t\tconst scanned = scanStageOutput(stageOutputDir(run.runRoot, stage));\n\t\treturn { stageId: stage.id, status: scanned.status, outputFiles: scanned.outputFiles };\n\t});\n}\n\nexport function runManifestPath(runRoot: string): string {\n\treturn join(runRoot, RUN_MANIFEST_NAME);\n}\n\nexport function parsePipelineRun(value: unknown): PipelineRun | undefined {\n\tif (!isPipelineRun(value)) return undefined;\n\treturn clonePipelineRun(value);\n}\n\nexport function readPipelineRun(runRoot: string): PipelineRun | undefined {\n\ttry {\n\t\tconst rootStats = lstatSync(runRoot);\n\t\tif (!rootStats.isDirectory() || rootStats.isSymbolicLink()) return undefined;\n\t\tconst manifestPath = runManifestPath(runRoot);\n\t\tconst manifestStats = lstatSync(manifestPath);\n\t\tif (\n\t\t\t!manifestStats.isFile() ||\n\t\t\tmanifestStats.isSymbolicLink() ||\n\t\t\tmanifestStats.size > MAX_PIPELINE_RUN_MANIFEST_BYTES\n\t\t) {\n\t\t\treturn undefined;\n\t\t}\n\t\tconst parsed: unknown = JSON.parse(\n\t\t\treadBoundedTextFileSync(manifestPath, MAX_PIPELINE_RUN_MANIFEST_BYTES, \"Pipeline run manifest\"),\n\t\t);\n\t\tconst run = parsePipelineRun(parsed);\n\t\tif (\n\t\t\t!run ||\n\t\t\tcanonicalPathScopeIdentity(run.runRoot) !== canonicalPathScopeIdentity(runRoot) ||\n\t\t\tbasename(runRoot) !== run.runId\n\t\t) {\n\t\t\treturn undefined;\n\t\t}\n\t\treturn run;\n\t} catch {\n\t\treturn undefined;\n\t}\n}\n\nexport function writePipelineRun(run: PipelineRun): void {\n\tif (!isPipelineRun(run)) throw new Error(\"Pipeline run state is invalid and was not persisted.\");\n\tassertPortablePathSegment(\"Pipeline run id\", run.runId);\n\tif (basename(run.runRoot) !== run.runId) {\n\t\tthrow new Error(\"Pipeline run root must end with its exact run id.\");\n\t}\n\tmkdirSync(run.runRoot, { recursive: true });\n\tconst rootStats = lstatSync(run.runRoot);\n\tif (!rootStats.isDirectory() || rootStats.isSymbolicLink()) {\n\t\tthrow new Error(`Pipeline run root is not a real directory: ${run.runRoot}`);\n\t}\n\twriteFileAtomicSync(runManifestPath(run.runRoot), `${JSON.stringify(run, null, 2)}\\n`);\n}\n\nexport function createPipelineRunRoot(cwd: string, runId: string): string {\n\tassertPortablePathSegment(\"Pipeline run id\", runId);\n\treturn join(assertProjectPipelineDirectory(cwd, \"pipeline-runs\"), runId);\n}\n\n/** Serialize project-wide pipeline admission and transitions across sessions and OS processes. */\nexport function withPipelineLifecycleLock<T>(cwd: string, mutate: () => T): T {\n\tconst runsRoot = assertProjectPipelineDirectory(cwd, \"pipeline-runs\");\n\treturn withFileLockSync(join(runsRoot, PIPELINE_LIFECYCLE_LOCK_NAME), () => {\n\t\tconst verifiedRoot = assertProjectPipelineDirectory(cwd, \"pipeline-runs\");\n\t\tif (canonicalPathScopeIdentity(verifiedRoot) !== canonicalPathScopeIdentity(runsRoot)) {\n\t\t\tthrow new Error(\"Project pipeline-runs directory changed during lifecycle lock acquisition.\");\n\t\t}\n\t\treturn mutate();\n\t});\n}\n\n/** A restored run may operate only on its exact project-owned run directory. */\nexport function isProjectPipelineRun(cwd: string, run: PipelineRun): boolean {\n\ttry {\n\t\tconst expectedRoot = createPipelineRunRoot(cwd, run.runId);\n\t\tif (canonicalPathScopeIdentity(run.runRoot) !== canonicalPathScopeIdentity(expectedRoot)) return false;\n\t\tconst rootStats = lstatSync(expectedRoot);\n\t\treturn rootStats.isDirectory() && !rootStats.isSymbolicLink();\n\t} catch {\n\t\treturn false;\n\t}\n}\n\n/** Resolve the exact validated durable manifest for a project-owned session snapshot. */\nexport function resolveProjectPipelineRun(cwd: string, run: PipelineRun): PipelineRun | undefined {\n\tif (!isProjectPipelineRun(cwd, run)) return undefined;\n\treturn readPipelineRun(createPipelineRunRoot(cwd, run.runId));\n}\n\n/** Resolve the durable project-wide current run, using a session snapshot only as an identity hint. */\nexport function resolveCurrentProjectPipelineRun(cwd: string, snapshot?: PipelineRun): PipelineRun | undefined {\n\tconst durableSnapshot = snapshot ? resolveProjectPipelineRun(cwd, snapshot) : undefined;\n\treturn findActivePipelineRun(cwd) ?? durableSnapshot;\n}\n\nexport function instantiatePipelineRun(args: {\n\tdefinition: PipelineDefinition;\n\trunId: string;\n\trunRoot: string;\n\tgoalId?: string;\n\tnow: string;\n}): PipelineRun {\n\tconst first = args.definition.stages[0];\n\tif (!first) throw new Error(\"Pipeline definition has no stages.\");\n\tfor (const stage of args.definition.stages) {\n\t\tmkdirSync(stageOutputDir(args.runRoot, stage), { recursive: true });\n\t}\n\tconst run: PipelineRun = {\n\t\tversion: 1,\n\t\trevision: 1,\n\t\trunId: args.runId,\n\t\tpipelineName: args.definition.name,\n\t\tdefinitionPath: args.definition.rootDir,\n\t\trunRoot: args.runRoot,\n\t\tcurrentStageId: first.id,\n\t\tstatus: \"active\",\n\t\tgoalId: args.goalId,\n\t\tcreatedAt: args.now,\n\t\tupdatedAt: args.now,\n\t};\n\twritePipelineRun(run);\n\treturn run;\n}\n\nexport function persistPipelineRun(run: PipelineRun, now: string): PipelineRun {\n\tconst next = { ...run, revision: run.revision + 1, updatedAt: now };\n\twritePipelineRun(next);\n\treturn next;\n}\n\nexport function findActivePipelineRun(cwd: string): PipelineRun | undefined {\n\tlet root: string;\n\ttry {\n\t\troot = assertProjectPipelineDirectory(cwd, \"pipeline-runs\");\n\t} catch (error) {\n\t\tif ((error as NodeJS.ErrnoException).code === \"ENOENT\") return undefined;\n\t\tthrow error;\n\t}\n\tlet names: string[];\n\ttry {\n\t\tnames = readBoundedDirectoryNamesSync(root, MAX_PIPELINE_RUN_SCAN_ENTRIES, \"Pipeline run directory\");\n\t} catch (error) {\n\t\tif ((error as NodeJS.ErrnoException).code === \"ENOENT\") return undefined;\n\t\tthrow error;\n\t}\n\tlet active: PipelineRun | undefined;\n\tfor (const name of names) {\n\t\tif (name.startsWith(\".\")) continue;\n\t\tconst run = readPipelineRun(join(root, name));\n\t\tif (!run) {\n\t\t\tthrow new Error(`Pipeline run directory contains an invalid managed entry: ${name}`);\n\t\t}\n\t\tif (!isPipelineRunActive(run)) continue;\n\t\tif (active) {\n\t\t\tthrow new Error(`Pipeline run directory contains multiple active runs: ${active.runId}, ${run.runId}`);\n\t\t}\n\t\tactive = run;\n\t}\n\treturn active;\n}\n\nexport function loadPipelineRunById(cwd: string, runId: string): PipelineRun | undefined {\n\tconst trimmed = runId.trim();\n\tif (!trimmed) return undefined;\n\tlet runRoot: string;\n\ttry {\n\t\trunRoot = createPipelineRunRoot(cwd, trimmed);\n\t} catch {\n\t\treturn undefined;\n\t}\n\treturn readPipelineRun(runRoot);\n}\n\nexport function decodePipelineRunPayload(data: unknown): PipelineRun | undefined {\n\tif (!isPlainRecord(data)) return undefined;\n\tconst value = data.run ?? data;\n\treturn parsePipelineRun(value);\n}\n\nexport function pipelineRunParentDir(runRoot: string): string {\n\treturn dirname(runRoot);\n}\n"]}
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
/** ICM pipeline form: numbered stages, factory vs product, status from files. */
|
|
2
2
|
export declare const PIPELINE_STAGE_FOLDER_RE: RegExp;
|
|
3
|
+
/** Two-digit ordinal, separator, and the longest stage slug accepted by PIPELINE_STAGE_FOLDER_RE. */
|
|
4
|
+
export declare const MAX_PIPELINE_STAGE_ID_LENGTH = 66;
|
|
3
5
|
export declare const MAX_PIPELINE_STAGES = 32;
|
|
4
6
|
export declare const MAX_PIPELINE_NAME_LENGTH = 64;
|
|
5
7
|
export declare const MAX_CONTRACT_PROCESS_CHARS = 4000;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/core/pipelines/types.ts"],"names":[],"mappings":"AAAA,iFAAiF;
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/core/pipelines/types.ts"],"names":[],"mappings":"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"}
|