@caupulican/pi-adaptative 0.93.2 → 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 +26 -0
- package/dist/bundled-resources/skills/worker-profile-writer/SKILL.md +6 -6
- package/dist/cli/args.js +1 -1
- package/dist/cli/args.js.map +1 -1
- package/dist/core/agent-session-contracts.d.ts +2 -2
- package/dist/core/agent-session-contracts.d.ts.map +1 -1
- package/dist/core/agent-session-contracts.js.map +1 -1
- package/dist/core/agent-session.d.ts.map +1 -1
- package/dist/core/agent-session.js +16 -11
- 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/autonomy/subagent-prompt.d.ts +1 -1
- package/dist/core/autonomy/subagent-prompt.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/cost-guard.js +1 -1
- package/dist/core/cost-guard.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-attempt-executor.d.ts.map +1 -1
- package/dist/core/delegation/worker-attempt-executor.js +7 -5
- package/dist/core/delegation/worker-attempt-executor.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-delegation-request.d.ts +5 -2
- package/dist/core/delegation/worker-delegation-request.d.ts.map +1 -1
- package/dist/core/delegation/worker-delegation-request.js +1 -1
- package/dist/core/delegation/worker-delegation-request.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-session-controller.js +1 -1
- package/dist/core/goals/goal-session-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/model-router-controller.js +2 -2
- package/dist/core/model-router-controller.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/orchestration/risk-budget.d.ts +0 -10
- package/dist/core/orchestration/risk-budget.d.ts.map +1 -1
- package/dist/core/orchestration/risk-budget.js +0 -14
- package/dist/core/orchestration/risk-budget.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/provider-prompt-contracts.d.ts +1 -0
- package/dist/core/provider-prompt-contracts.d.ts.map +1 -1
- package/dist/core/provider-prompt-contracts.js +6 -5
- package/dist/core/provider-prompt-contracts.js.map +1 -1
- package/dist/core/reflection-controller.js +1 -1
- package/dist/core/reflection-controller.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/settings-manager.d.ts +5 -6
- package/dist/core/settings-manager.d.ts.map +1 -1
- package/dist/core/settings-manager.js +8 -13
- package/dist/core/settings-manager.js.map +1 -1
- package/dist/core/system-prompt-builder.d.ts +2 -4
- package/dist/core/system-prompt-builder.d.ts.map +1 -1
- package/dist/core/system-prompt-builder.js +35 -11
- 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/delegate.d.ts +0 -16
- package/dist/core/tools/delegate.d.ts.map +1 -1
- package/dist/core/tools/delegate.js +21 -11
- package/dist/core/tools/delegate.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 +5 -1
- 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/profile-writer.d.ts +0 -9
- package/dist/core/tools/profile-writer.d.ts.map +1 -1
- package/dist/core/tools/profile-writer.js +0 -3
- package/dist/core/tools/profile-writer.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/dist/modes/interactive/components/settings-selector.d.ts.map +1 -1
- package/dist/modes/interactive/components/settings-selector.js +7 -16
- package/dist/modes/interactive/components/settings-selector.js.map +1 -1
- package/dist/modes/interactive/components/thinking-selector.d.ts.map +1 -1
- package/dist/modes/interactive/components/thinking-selector.js +2 -11
- package/dist/modes/interactive/components/thinking-selector.js.map +1 -1
- package/dist/modes/interactive/local-model-commands.d.ts.map +1 -1
- package/dist/modes/interactive/local-model-commands.js +1 -10
- package/dist/modes/interactive/local-model-commands.js.map +1 -1
- package/dist/modes/interactive/thinking-level-descriptions.d.ts +4 -0
- package/dist/modes/interactive/thinking-level-descriptions.d.ts.map +1 -0
- package/dist/modes/interactive/thinking-level-descriptions.js +12 -0
- package/dist/modes/interactive/thinking-level-descriptions.js.map +1 -0
- package/docs/resources.md +1 -1
- package/docs/settings.md +7 -5
- package/docs/worker-profiles.md +3 -3
- 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 +1 @@
|
|
|
1
|
-
{"version":3,"file":"discover.d.ts","sourceRoot":"","sources":["../../../src/core/pipelines/discover.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"discover.d.ts","sourceRoot":"","sources":["../../../src/core/pipelines/discover.ts"],"names":[],"mappings":"AAKA,OAAO,EAIN,KAAK,kBAAkB,EACvB,KAAK,WAAW,EAEhB,MAAM,YAAY,CAAC;AAUpB,wBAAgB,mBAAmB,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAEvD;AAED,wBAAgB,sBAAsB,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAE1D;AAED,kGAAkG;AAClG,wBAAgB,8BAA8B,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,WAAW,GAAG,eAAe,GAAG,MAAM,CAsBvG;AAED,MAAM,WAAW,uBAAuB;IACvC,iBAAiB,EAAE,MAAM,CAAC;IAC1B,GAAG,EAAE,MAAM,CAAC;CACZ;AAyFD,wBAAgB,sBAAsB,CAAC,OAAO,EAAE,MAAM,GAAG,kBAAkB,GAAG,SAAS,CAyBtF;AAED,wBAAgB,2BAA2B,CAAC,OAAO,EAAE,uBAAuB,GAAG,kBAAkB,EAAE,CAsBlG;AAED,wBAAgB,sBAAsB,CAAC,OAAO,EAAE,uBAAuB,EAAE,IAAI,EAAE,MAAM,GAAG,kBAAkB,GAAG,SAAS,CAIrH;AAED,0GAA0G;AAC1G,wBAAgB,+BAA+B,CAC9C,OAAO,EAAE,uBAAuB,EAChC,GAAG,EAAE,IAAI,CAAC,WAAW,EAAE,gBAAgB,GAAG,cAAc,CAAC,GACvD,kBAAkB,GAAG,SAAS,CAOhC"}
|
|
@@ -1,20 +1,57 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { lstatSync } from "node:fs";
|
|
2
2
|
import { basename, join } from "node:path";
|
|
3
|
+
import { canonicalPathScopeIdentity, isPathWithinScope, safeRealpathSync } from "../autonomy/path-scope.js";
|
|
4
|
+
import { readBoundedDirectoryNamesSync, readBoundedTextFileSync } from "../util/bounded-file.js";
|
|
3
5
|
import { parseStageContract, parseWorkspaceFrontmatter } from "./parse-contract.js";
|
|
4
6
|
import { MAX_PIPELINE_NAME_LENGTH, MAX_PIPELINE_STAGES, PIPELINE_STAGE_FOLDER_RE, } from "./types.js";
|
|
5
7
|
const ENTRY_FILES = ["AGENTS.md", "CLAUDE.md"];
|
|
6
8
|
const ROUTING_FILE = "CONTEXT.md";
|
|
7
9
|
const CONTRACT_FILE = "CONTEXT.md";
|
|
8
10
|
const FACTORY_DIRS = ["_shared", "references"];
|
|
11
|
+
const MAX_PIPELINE_DEFINITION_FILE_BYTES = 64 * 1024;
|
|
12
|
+
const MAX_PIPELINE_DIRECTORY_ENTRIES = 1_024;
|
|
13
|
+
const MAX_PIPELINE_DEFINITIONS = 64;
|
|
9
14
|
export function projectPipelinesDir(cwd) {
|
|
10
15
|
return join(cwd, ".pi", "pipelines");
|
|
11
16
|
}
|
|
12
17
|
export function projectPipelineRunsDir(cwd) {
|
|
13
18
|
return join(cwd, ".pi", "pipeline-runs");
|
|
14
19
|
}
|
|
15
|
-
|
|
20
|
+
/** Validate one project-owned pipeline storage root without following a managed symlink first. */
|
|
21
|
+
export function assertProjectPipelineDirectory(cwd, name) {
|
|
22
|
+
const piRoot = join(cwd, ".pi");
|
|
23
|
+
const directory = join(piRoot, name);
|
|
24
|
+
for (const [path, label] of [
|
|
25
|
+
[piRoot, "Project .pi path"],
|
|
26
|
+
[directory, `Project ${name} path`],
|
|
27
|
+
]) {
|
|
28
|
+
let stats;
|
|
29
|
+
try {
|
|
30
|
+
stats = lstatSync(path);
|
|
31
|
+
}
|
|
32
|
+
catch (error) {
|
|
33
|
+
if (error.code === "ENOENT")
|
|
34
|
+
continue;
|
|
35
|
+
throw error;
|
|
36
|
+
}
|
|
37
|
+
if (!stats.isDirectory() || stats.isSymbolicLink()) {
|
|
38
|
+
throw new Error(`${label} is not a real directory: ${path}`);
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
if (!isPathWithinScope(safeRealpathSync(directory), safeRealpathSync(cwd))) {
|
|
42
|
+
throw new Error(`Project ${name} directory escapes the working directory.`);
|
|
43
|
+
}
|
|
44
|
+
return directory;
|
|
45
|
+
}
|
|
46
|
+
function readText(path, rootDir) {
|
|
16
47
|
try {
|
|
17
|
-
|
|
48
|
+
const stats = lstatSync(path);
|
|
49
|
+
if (!stats.isFile() || stats.isSymbolicLink() || stats.size > MAX_PIPELINE_DEFINITION_FILE_BYTES) {
|
|
50
|
+
return undefined;
|
|
51
|
+
}
|
|
52
|
+
if (!isPathWithinScope(safeRealpathSync(path), safeRealpathSync(rootDir)))
|
|
53
|
+
return undefined;
|
|
54
|
+
return readBoundedTextFileSync(path, MAX_PIPELINE_DEFINITION_FILE_BYTES, "Pipeline definition file");
|
|
18
55
|
}
|
|
19
56
|
catch {
|
|
20
57
|
return undefined;
|
|
@@ -22,7 +59,8 @@ function readText(path) {
|
|
|
22
59
|
}
|
|
23
60
|
function isDir(path) {
|
|
24
61
|
try {
|
|
25
|
-
|
|
62
|
+
const stats = lstatSync(path);
|
|
63
|
+
return stats.isDirectory() && !stats.isSymbolicLink();
|
|
26
64
|
}
|
|
27
65
|
catch {
|
|
28
66
|
return false;
|
|
@@ -32,9 +70,8 @@ function listDirs(path) {
|
|
|
32
70
|
if (!isDir(path))
|
|
33
71
|
return [];
|
|
34
72
|
try {
|
|
35
|
-
return
|
|
36
|
-
.filter((
|
|
37
|
-
.map((entry) => entry.name)
|
|
73
|
+
return readBoundedDirectoryNamesSync(path, MAX_PIPELINE_DIRECTORY_ENTRIES, "Pipeline directory")
|
|
74
|
+
.filter((name) => !name.startsWith(".") && isDir(join(path, name)))
|
|
38
75
|
.sort();
|
|
39
76
|
}
|
|
40
77
|
catch {
|
|
@@ -44,7 +81,7 @@ function listDirs(path) {
|
|
|
44
81
|
function pickEntryFile(rootDir) {
|
|
45
82
|
for (const name of ENTRY_FILES) {
|
|
46
83
|
const path = join(rootDir, name);
|
|
47
|
-
if (
|
|
84
|
+
if (readText(path, rootDir) !== undefined)
|
|
48
85
|
return path;
|
|
49
86
|
}
|
|
50
87
|
return undefined;
|
|
@@ -63,12 +100,12 @@ function parseStageFolder(name) {
|
|
|
63
100
|
return undefined;
|
|
64
101
|
return { ordinal: Number(match[1]), slug: match[2] };
|
|
65
102
|
}
|
|
66
|
-
function loadStage(stagesDir, folderName) {
|
|
103
|
+
function loadStage(rootDir, stagesDir, folderName) {
|
|
67
104
|
const parsed = parseStageFolder(folderName);
|
|
68
105
|
if (!parsed)
|
|
69
106
|
return undefined;
|
|
70
107
|
const contractPath = join(stagesDir, folderName, CONTRACT_FILE);
|
|
71
|
-
const content = readText(contractPath);
|
|
108
|
+
const content = readText(contractPath, rootDir);
|
|
72
109
|
if (content === undefined)
|
|
73
110
|
return undefined;
|
|
74
111
|
const contract = parseStageContract(content);
|
|
@@ -87,7 +124,7 @@ function collectStages(rootDir) {
|
|
|
87
124
|
const stagesDir = isDir(nested) && listDirs(nested).some((name) => PIPELINE_STAGE_FOLDER_RE.test(name)) ? nested : rootDir;
|
|
88
125
|
const stages = [];
|
|
89
126
|
for (const name of listDirs(stagesDir)) {
|
|
90
|
-
const stage = loadStage(stagesDir, name);
|
|
127
|
+
const stage = loadStage(rootDir, stagesDir, name);
|
|
91
128
|
if (stage)
|
|
92
129
|
stages.push(stage);
|
|
93
130
|
if (stages.length >= MAX_PIPELINE_STAGES)
|
|
@@ -97,35 +134,49 @@ function collectStages(rootDir) {
|
|
|
97
134
|
return { stagesDir, stages };
|
|
98
135
|
}
|
|
99
136
|
export function loadPipelineDefinition(rootDir) {
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
137
|
+
try {
|
|
138
|
+
if (!isDir(rootDir))
|
|
139
|
+
return undefined;
|
|
140
|
+
const { stagesDir, stages } = collectStages(rootDir);
|
|
141
|
+
if (stages.length === 0)
|
|
142
|
+
return undefined;
|
|
143
|
+
const routingPath = join(rootDir, ROUTING_FILE);
|
|
144
|
+
const routing = readText(routingPath, rootDir);
|
|
145
|
+
const parsed = routing !== undefined ? parseWorkspaceFrontmatter(routing) : undefined;
|
|
146
|
+
const folderName = basename(rootDir).slice(0, MAX_PIPELINE_NAME_LENGTH);
|
|
147
|
+
const name = (parsed?.name || folderName).slice(0, MAX_PIPELINE_NAME_LENGTH);
|
|
148
|
+
const entryFile = pickEntryFile(rootDir) ?? routingPath;
|
|
149
|
+
return {
|
|
150
|
+
name,
|
|
151
|
+
description: parsed?.description ?? "",
|
|
152
|
+
form: parsed?.form ?? "pipeline",
|
|
153
|
+
rootDir,
|
|
154
|
+
entryFile,
|
|
155
|
+
routingPath: routing !== undefined ? routingPath : entryFile,
|
|
156
|
+
factoryDir: pickFactoryDir(rootDir),
|
|
157
|
+
stagesDir,
|
|
158
|
+
stages,
|
|
159
|
+
};
|
|
160
|
+
}
|
|
161
|
+
catch {
|
|
104
162
|
return undefined;
|
|
105
|
-
|
|
106
|
-
const routing = readText(routingPath);
|
|
107
|
-
const parsed = routing !== undefined ? parseWorkspaceFrontmatter(routing) : undefined;
|
|
108
|
-
const folderName = basename(rootDir).slice(0, MAX_PIPELINE_NAME_LENGTH);
|
|
109
|
-
const name = (parsed?.name || folderName).slice(0, MAX_PIPELINE_NAME_LENGTH);
|
|
110
|
-
const entryFile = pickEntryFile(rootDir) ?? routingPath;
|
|
111
|
-
return {
|
|
112
|
-
name,
|
|
113
|
-
description: parsed?.description ?? "",
|
|
114
|
-
form: parsed?.form ?? "pipeline",
|
|
115
|
-
rootDir,
|
|
116
|
-
entryFile,
|
|
117
|
-
routingPath: existsSync(routingPath) ? routingPath : entryFile,
|
|
118
|
-
factoryDir: pickFactoryDir(rootDir),
|
|
119
|
-
stagesDir,
|
|
120
|
-
stages,
|
|
121
|
-
};
|
|
163
|
+
}
|
|
122
164
|
}
|
|
123
165
|
export function discoverPipelineDefinitions(options) {
|
|
124
|
-
|
|
166
|
+
let projectRoot;
|
|
167
|
+
try {
|
|
168
|
+
projectRoot = assertProjectPipelineDirectory(options.cwd, "pipelines");
|
|
169
|
+
}
|
|
170
|
+
catch {
|
|
171
|
+
projectRoot = undefined;
|
|
172
|
+
}
|
|
173
|
+
const roots = [options.agentPipelinesDir, ...(projectRoot ? [projectRoot] : [])];
|
|
125
174
|
const seen = new Set();
|
|
126
175
|
const definitions = [];
|
|
127
176
|
for (const root of roots) {
|
|
128
177
|
for (const name of listDirs(root)) {
|
|
178
|
+
if (definitions.length >= MAX_PIPELINE_DEFINITIONS)
|
|
179
|
+
return definitions;
|
|
129
180
|
const path = join(root, name);
|
|
130
181
|
if (seen.has(path))
|
|
131
182
|
continue;
|
|
@@ -144,4 +195,11 @@ export function findPipelineDefinition(options, name) {
|
|
|
144
195
|
return undefined;
|
|
145
196
|
return discoverPipelineDefinitions(options).find((definition) => definition.name.toLocaleLowerCase() === wanted);
|
|
146
197
|
}
|
|
198
|
+
/** Resolve a run's immutable definition path, with the normal discovery roots as a move-safe fallback. */
|
|
199
|
+
export function resolvePipelineDefinitionForRun(options, run) {
|
|
200
|
+
const definitions = discoverPipelineDefinitions(options);
|
|
201
|
+
const storedPath = canonicalPathScopeIdentity(run.definitionPath);
|
|
202
|
+
return (definitions.find((definition) => canonicalPathScopeIdentity(definition.rootDir) === storedPath) ??
|
|
203
|
+
definitions.find((definition) => definition.name.toLocaleLowerCase() === run.pipelineName.toLocaleLowerCase()));
|
|
204
|
+
}
|
|
147
205
|
//# sourceMappingURL=discover.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"discover.js","sourceRoot":"","sources":["../../../src/core/pipelines/discover.ts"],"names":[],"mappings":"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","sourcesContent":["import { existsSync, readdirSync, readFileSync, statSync } from \"node:fs\";\nimport { basename, join } from \"node:path\";\nimport { parseStageContract, parseWorkspaceFrontmatter } from \"./parse-contract.ts\";\nimport {\n\tMAX_PIPELINE_NAME_LENGTH,\n\tMAX_PIPELINE_STAGES,\n\tPIPELINE_STAGE_FOLDER_RE,\n\ttype PipelineDefinition,\n\ttype PipelineStage,\n} from \"./types.ts\";\n\nconst ENTRY_FILES = [\"AGENTS.md\", \"CLAUDE.md\"] as const;\nconst ROUTING_FILE = \"CONTEXT.md\";\nconst CONTRACT_FILE = \"CONTEXT.md\";\nconst FACTORY_DIRS = [\"_shared\", \"references\"] as const;\n\nexport function projectPipelinesDir(cwd: string): string {\n\treturn join(cwd, \".pi\", \"pipelines\");\n}\n\nexport function projectPipelineRunsDir(cwd: string): string {\n\treturn join(cwd, \".pi\", \"pipeline-runs\");\n}\n\nexport interface DiscoverPipelineOptions {\n\tagentPipelinesDir: string;\n\tcwd: string;\n}\n\nfunction readText(path: string): string | undefined {\n\ttry {\n\t\treturn readFileSync(path, \"utf8\");\n\t} catch {\n\t\treturn undefined;\n\t}\n}\n\nfunction isDir(path: string): boolean {\n\ttry {\n\t\treturn statSync(path).isDirectory();\n\t} catch {\n\t\treturn false;\n\t}\n}\n\nfunction listDirs(path: string): string[] {\n\tif (!isDir(path)) return [];\n\ttry {\n\t\treturn readdirSync(path, { withFileTypes: true })\n\t\t\t.filter((entry) => entry.isDirectory() && !entry.name.startsWith(\".\"))\n\t\t\t.map((entry) => entry.name)\n\t\t\t.sort();\n\t} catch {\n\t\treturn [];\n\t}\n}\n\nfunction pickEntryFile(rootDir: string): string | undefined {\n\tfor (const name of ENTRY_FILES) {\n\t\tconst path = join(rootDir, name);\n\t\tif (existsSync(path)) return path;\n\t}\n\treturn undefined;\n}\n\nfunction pickFactoryDir(rootDir: string): string {\n\tfor (const name of FACTORY_DIRS) {\n\t\tconst path = join(rootDir, name);\n\t\tif (isDir(path)) return path;\n\t}\n\treturn join(rootDir, \"_shared\");\n}\n\nfunction parseStageFolder(name: string): { ordinal: number; slug: string } | undefined {\n\tconst match = name.match(PIPELINE_STAGE_FOLDER_RE);\n\tif (!match) return undefined;\n\treturn { ordinal: Number(match[1]), slug: match[2] };\n}\n\nfunction loadStage(stagesDir: string, folderName: string): PipelineStage | undefined {\n\tconst parsed = parseStageFolder(folderName);\n\tif (!parsed) return undefined;\n\tconst contractPath = join(stagesDir, folderName, CONTRACT_FILE);\n\tconst content = readText(contractPath);\n\tif (content === undefined) return undefined;\n\tconst contract = parseStageContract(content);\n\treturn {\n\t\tid: `${String(parsed.ordinal).padStart(2, \"0\")}_${parsed.slug}`,\n\t\tordinal: parsed.ordinal,\n\t\tslug: parsed.slug,\n\t\tfolderName,\n\t\tcontractPath,\n\t\toutputDir: join(stagesDir, folderName, \"output\"),\n\t\tcontract,\n\t};\n}\n\nfunction collectStages(rootDir: string): { stagesDir: string; stages: PipelineStage[] } {\n\tconst nested = join(rootDir, \"stages\");\n\tconst stagesDir =\n\t\tisDir(nested) && listDirs(nested).some((name) => PIPELINE_STAGE_FOLDER_RE.test(name)) ? nested : rootDir;\n\tconst stages: PipelineStage[] = [];\n\tfor (const name of listDirs(stagesDir)) {\n\t\tconst stage = loadStage(stagesDir, name);\n\t\tif (stage) stages.push(stage);\n\t\tif (stages.length >= MAX_PIPELINE_STAGES) break;\n\t}\n\tstages.sort((left, right) => left.ordinal - right.ordinal || left.slug.localeCompare(right.slug));\n\treturn { stagesDir, stages };\n}\n\nexport function loadPipelineDefinition(rootDir: string): PipelineDefinition | undefined {\n\tif (!isDir(rootDir)) return undefined;\n\tconst { stagesDir, stages } = collectStages(rootDir);\n\tif (stages.length === 0) return undefined;\n\tconst routingPath = join(rootDir, ROUTING_FILE);\n\tconst routing = readText(routingPath);\n\tconst parsed = routing !== undefined ? parseWorkspaceFrontmatter(routing) : undefined;\n\tconst folderName = basename(rootDir).slice(0, MAX_PIPELINE_NAME_LENGTH);\n\tconst name = (parsed?.name || folderName).slice(0, MAX_PIPELINE_NAME_LENGTH);\n\tconst entryFile = pickEntryFile(rootDir) ?? routingPath;\n\treturn {\n\t\tname,\n\t\tdescription: parsed?.description ?? \"\",\n\t\tform: parsed?.form ?? \"pipeline\",\n\t\trootDir,\n\t\tentryFile,\n\t\troutingPath: existsSync(routingPath) ? routingPath : entryFile,\n\t\tfactoryDir: pickFactoryDir(rootDir),\n\t\tstagesDir,\n\t\tstages,\n\t};\n}\n\nexport function discoverPipelineDefinitions(options: DiscoverPipelineOptions): PipelineDefinition[] {\n\tconst roots = [options.agentPipelinesDir, projectPipelinesDir(options.cwd)];\n\tconst seen = new Set<string>();\n\tconst definitions: PipelineDefinition[] = [];\n\tfor (const root of roots) {\n\t\tfor (const name of listDirs(root)) {\n\t\t\tconst path = join(root, name);\n\t\t\tif (seen.has(path)) continue;\n\t\t\tconst definition = loadPipelineDefinition(path);\n\t\t\tif (!definition) continue;\n\t\t\tseen.add(path);\n\t\t\tdefinitions.push(definition);\n\t\t}\n\t}\n\treturn definitions;\n}\n\nexport function findPipelineDefinition(options: DiscoverPipelineOptions, name: string): PipelineDefinition | undefined {\n\tconst wanted = name.trim().toLocaleLowerCase();\n\tif (!wanted) return undefined;\n\treturn discoverPipelineDefinitions(options).find((definition) => definition.name.toLocaleLowerCase() === wanted);\n}\n"]}
|
|
1
|
+
{"version":3,"file":"discover.js","sourceRoot":"","sources":["../../../src/core/pipelines/discover.ts"],"names":[],"mappings":"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","sourcesContent":["import { lstatSync } from \"node:fs\";\nimport { basename, join } from \"node:path\";\nimport { canonicalPathScopeIdentity, isPathWithinScope, safeRealpathSync } from \"../autonomy/path-scope.ts\";\nimport { readBoundedDirectoryNamesSync, readBoundedTextFileSync } from \"../util/bounded-file.ts\";\nimport { parseStageContract, parseWorkspaceFrontmatter } from \"./parse-contract.ts\";\nimport {\n\tMAX_PIPELINE_NAME_LENGTH,\n\tMAX_PIPELINE_STAGES,\n\tPIPELINE_STAGE_FOLDER_RE,\n\ttype PipelineDefinition,\n\ttype PipelineRun,\n\ttype PipelineStage,\n} from \"./types.ts\";\n\nconst ENTRY_FILES = [\"AGENTS.md\", \"CLAUDE.md\"] as const;\nconst ROUTING_FILE = \"CONTEXT.md\";\nconst CONTRACT_FILE = \"CONTEXT.md\";\nconst FACTORY_DIRS = [\"_shared\", \"references\"] as const;\nconst MAX_PIPELINE_DEFINITION_FILE_BYTES = 64 * 1024;\nconst MAX_PIPELINE_DIRECTORY_ENTRIES = 1_024;\nconst MAX_PIPELINE_DEFINITIONS = 64;\n\nexport function projectPipelinesDir(cwd: string): string {\n\treturn join(cwd, \".pi\", \"pipelines\");\n}\n\nexport function projectPipelineRunsDir(cwd: string): string {\n\treturn join(cwd, \".pi\", \"pipeline-runs\");\n}\n\n/** Validate one project-owned pipeline storage root without following a managed symlink first. */\nexport function assertProjectPipelineDirectory(cwd: string, name: \"pipelines\" | \"pipeline-runs\"): string {\n\tconst piRoot = join(cwd, \".pi\");\n\tconst directory = join(piRoot, name);\n\tfor (const [path, label] of [\n\t\t[piRoot, \"Project .pi path\"],\n\t\t[directory, `Project ${name} path`],\n\t] as const) {\n\t\tlet stats: ReturnType<typeof lstatSync>;\n\t\ttry {\n\t\t\tstats = lstatSync(path);\n\t\t} catch (error) {\n\t\t\tif ((error as NodeJS.ErrnoException).code === \"ENOENT\") continue;\n\t\t\tthrow error;\n\t\t}\n\t\tif (!stats.isDirectory() || stats.isSymbolicLink()) {\n\t\t\tthrow new Error(`${label} is not a real directory: ${path}`);\n\t\t}\n\t}\n\tif (!isPathWithinScope(safeRealpathSync(directory), safeRealpathSync(cwd))) {\n\t\tthrow new Error(`Project ${name} directory escapes the working directory.`);\n\t}\n\treturn directory;\n}\n\nexport interface DiscoverPipelineOptions {\n\tagentPipelinesDir: string;\n\tcwd: string;\n}\n\nfunction readText(path: string, rootDir: string): string | undefined {\n\ttry {\n\t\tconst stats = lstatSync(path);\n\t\tif (!stats.isFile() || stats.isSymbolicLink() || stats.size > MAX_PIPELINE_DEFINITION_FILE_BYTES) {\n\t\t\treturn undefined;\n\t\t}\n\t\tif (!isPathWithinScope(safeRealpathSync(path), safeRealpathSync(rootDir))) return undefined;\n\t\treturn readBoundedTextFileSync(path, MAX_PIPELINE_DEFINITION_FILE_BYTES, \"Pipeline definition file\");\n\t} catch {\n\t\treturn undefined;\n\t}\n}\n\nfunction isDir(path: string): boolean {\n\ttry {\n\t\tconst stats = lstatSync(path);\n\t\treturn stats.isDirectory() && !stats.isSymbolicLink();\n\t} catch {\n\t\treturn false;\n\t}\n}\n\nfunction listDirs(path: string): string[] {\n\tif (!isDir(path)) return [];\n\ttry {\n\t\treturn readBoundedDirectoryNamesSync(path, MAX_PIPELINE_DIRECTORY_ENTRIES, \"Pipeline directory\")\n\t\t\t.filter((name) => !name.startsWith(\".\") && isDir(join(path, name)))\n\t\t\t.sort();\n\t} catch {\n\t\treturn [];\n\t}\n}\n\nfunction pickEntryFile(rootDir: string): string | undefined {\n\tfor (const name of ENTRY_FILES) {\n\t\tconst path = join(rootDir, name);\n\t\tif (readText(path, rootDir) !== undefined) return path;\n\t}\n\treturn undefined;\n}\n\nfunction pickFactoryDir(rootDir: string): string {\n\tfor (const name of FACTORY_DIRS) {\n\t\tconst path = join(rootDir, name);\n\t\tif (isDir(path)) return path;\n\t}\n\treturn join(rootDir, \"_shared\");\n}\n\nfunction parseStageFolder(name: string): { ordinal: number; slug: string } | undefined {\n\tconst match = name.match(PIPELINE_STAGE_FOLDER_RE);\n\tif (!match) return undefined;\n\treturn { ordinal: Number(match[1]), slug: match[2] };\n}\n\nfunction loadStage(rootDir: string, stagesDir: string, folderName: string): PipelineStage | undefined {\n\tconst parsed = parseStageFolder(folderName);\n\tif (!parsed) return undefined;\n\tconst contractPath = join(stagesDir, folderName, CONTRACT_FILE);\n\tconst content = readText(contractPath, rootDir);\n\tif (content === undefined) return undefined;\n\tconst contract = parseStageContract(content);\n\treturn {\n\t\tid: `${String(parsed.ordinal).padStart(2, \"0\")}_${parsed.slug}`,\n\t\tordinal: parsed.ordinal,\n\t\tslug: parsed.slug,\n\t\tfolderName,\n\t\tcontractPath,\n\t\toutputDir: join(stagesDir, folderName, \"output\"),\n\t\tcontract,\n\t};\n}\n\nfunction collectStages(rootDir: string): { stagesDir: string; stages: PipelineStage[] } {\n\tconst nested = join(rootDir, \"stages\");\n\tconst stagesDir =\n\t\tisDir(nested) && listDirs(nested).some((name) => PIPELINE_STAGE_FOLDER_RE.test(name)) ? nested : rootDir;\n\tconst stages: PipelineStage[] = [];\n\tfor (const name of listDirs(stagesDir)) {\n\t\tconst stage = loadStage(rootDir, stagesDir, name);\n\t\tif (stage) stages.push(stage);\n\t\tif (stages.length >= MAX_PIPELINE_STAGES) break;\n\t}\n\tstages.sort((left, right) => left.ordinal - right.ordinal || left.slug.localeCompare(right.slug));\n\treturn { stagesDir, stages };\n}\n\nexport function loadPipelineDefinition(rootDir: string): PipelineDefinition | undefined {\n\ttry {\n\t\tif (!isDir(rootDir)) return undefined;\n\t\tconst { stagesDir, stages } = collectStages(rootDir);\n\t\tif (stages.length === 0) return undefined;\n\t\tconst routingPath = join(rootDir, ROUTING_FILE);\n\t\tconst routing = readText(routingPath, rootDir);\n\t\tconst parsed = routing !== undefined ? parseWorkspaceFrontmatter(routing) : undefined;\n\t\tconst folderName = basename(rootDir).slice(0, MAX_PIPELINE_NAME_LENGTH);\n\t\tconst name = (parsed?.name || folderName).slice(0, MAX_PIPELINE_NAME_LENGTH);\n\t\tconst entryFile = pickEntryFile(rootDir) ?? routingPath;\n\t\treturn {\n\t\t\tname,\n\t\t\tdescription: parsed?.description ?? \"\",\n\t\t\tform: parsed?.form ?? \"pipeline\",\n\t\t\trootDir,\n\t\t\tentryFile,\n\t\t\troutingPath: routing !== undefined ? routingPath : entryFile,\n\t\t\tfactoryDir: pickFactoryDir(rootDir),\n\t\t\tstagesDir,\n\t\t\tstages,\n\t\t};\n\t} catch {\n\t\treturn undefined;\n\t}\n}\n\nexport function discoverPipelineDefinitions(options: DiscoverPipelineOptions): PipelineDefinition[] {\n\tlet projectRoot: string | undefined;\n\ttry {\n\t\tprojectRoot = assertProjectPipelineDirectory(options.cwd, \"pipelines\");\n\t} catch {\n\t\tprojectRoot = undefined;\n\t}\n\tconst roots = [options.agentPipelinesDir, ...(projectRoot ? [projectRoot] : [])];\n\tconst seen = new Set<string>();\n\tconst definitions: PipelineDefinition[] = [];\n\tfor (const root of roots) {\n\t\tfor (const name of listDirs(root)) {\n\t\t\tif (definitions.length >= MAX_PIPELINE_DEFINITIONS) return definitions;\n\t\t\tconst path = join(root, name);\n\t\t\tif (seen.has(path)) continue;\n\t\t\tconst definition = loadPipelineDefinition(path);\n\t\t\tif (!definition) continue;\n\t\t\tseen.add(path);\n\t\t\tdefinitions.push(definition);\n\t\t}\n\t}\n\treturn definitions;\n}\n\nexport function findPipelineDefinition(options: DiscoverPipelineOptions, name: string): PipelineDefinition | undefined {\n\tconst wanted = name.trim().toLocaleLowerCase();\n\tif (!wanted) return undefined;\n\treturn discoverPipelineDefinitions(options).find((definition) => definition.name.toLocaleLowerCase() === wanted);\n}\n\n/** Resolve a run's immutable definition path, with the normal discovery roots as a move-safe fallback. */\nexport function resolvePipelineDefinitionForRun(\n\toptions: DiscoverPipelineOptions,\n\trun: Pick<PipelineRun, \"definitionPath\" | \"pipelineName\">,\n): PipelineDefinition | undefined {\n\tconst definitions = discoverPipelineDefinitions(options);\n\tconst storedPath = canonicalPathScopeIdentity(run.definitionPath);\n\treturn (\n\t\tdefinitions.find((definition) => canonicalPathScopeIdentity(definition.rootDir) === storedPath) ??\n\t\tdefinitions.find((definition) => definition.name.toLocaleLowerCase() === run.pipelineName.toLocaleLowerCase())\n\t);\n}\n"]}
|
|
@@ -1,10 +1,8 @@
|
|
|
1
1
|
import type { BackgroundToolTaskRef } from "../background-tool-task-controller.ts";
|
|
2
|
-
import type { GoalState } from "../goals/goal-state.ts";
|
|
3
2
|
import type { OpenTaskStepRef } from "../goals/goal-tool-core.ts";
|
|
4
3
|
import { type TaskStep, type TaskStepsState } from "../tasks/task-state.ts";
|
|
5
4
|
import { type IncrementResult, type PipelineDefinition, type PipelineRun } from "./types.ts";
|
|
6
5
|
export interface PipelineIncrementJoin {
|
|
7
|
-
goal?: GoalState;
|
|
8
6
|
openTaskSteps?: readonly OpenTaskStepRef[];
|
|
9
7
|
backgroundToolTasks?: readonly BackgroundToolTaskRef[];
|
|
10
8
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"increment.d.ts","sourceRoot":"","sources":["../../../src/core/pipelines/increment.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,uCAAuC,CAAC;AACnF,OAAO,KAAK,EAAE,
|
|
1
|
+
{"version":3,"file":"increment.d.ts","sourceRoot":"","sources":["../../../src/core/pipelines/increment.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,uCAAuC,CAAC;AACnF,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,4BAA4B,CAAC;AAClE,OAAO,EAAE,KAAK,QAAQ,EAAE,KAAK,cAAc,EAAkB,MAAM,wBAAwB,CAAC;AAG5F,OAAO,EACN,KAAK,eAAe,EAEpB,KAAK,kBAAkB,EACvB,KAAK,WAAW,EAEhB,MAAM,YAAY,CAAC;AAEpB,MAAM,WAAW,qBAAqB;IACrC,aAAa,CAAC,EAAE,SAAS,eAAe,EAAE,CAAC;IAC3C,mBAAmB,CAAC,EAAE,SAAS,qBAAqB,EAAE,CAAC;CACvD;AAED,qBAAa,sBAAuB,SAAQ,KAAK;IAChD,YAAY,OAAO,EAAE,MAAM,EAG1B;CACD;AAgBD,wBAAgB,oBAAoB,CACnC,UAAU,EAAE,kBAAkB,EAC9B,GAAG,EAAE,WAAW,EAChB,GAAG,EAAE,MAAM,EACX,IAAI,GAAE,qBAA0B,GAC9B;IAAE,GAAG,EAAE,WAAW,CAAC;IAAC,MAAM,EAAE,eAAe,CAAA;CAAE,CAmD/C;AAED,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,WAAW,EAAE,GAAG,EAAE,MAAM,GAAG,WAAW,CAG7E;AAED,wBAAgB,gBAAgB,CAC/B,KAAK,EAAE,cAAc,EACrB,GAAG,EAAE,MAAM,GACT;IACF,KAAK,EAAE,cAAc,CAAC;IACtB,MAAM,EAAE,eAAe,CAAC;CACxB,CAgEA;AAED,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,SAAS,QAAQ,EAAE,GAAG,QAAQ,GAAG,SAAS,CAEpF"}
|
|
@@ -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":"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","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"}
|