@diff-review-system/drs 4.0.1 → 4.1.0
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/.pi/agents/review/unified-reviewer.md +2 -6
- package/.pi/agents/task/review-assistant.md +22 -0
- package/.pi/workflows/github-pr-fix-review-issues-stacked.yaml +10 -4
- package/.pi/workflows/github-pr-review-post.yaml +0 -1
- package/.pi/workflows/github-pr-review.yaml +14 -8
- package/.pi/workflows/github-pr-visual-explain.yaml +46 -1
- package/.pi/workflows/gitlab-mr-fix-review-issues-stacked.yaml +10 -4
- package/.pi/workflows/gitlab-mr-review.yaml +14 -8
- package/.pi/workflows/gitlab-mr-visual-explain.yaml +46 -1
- package/.pi/workflows/local-fix-review-issues.yaml +13 -6
- package/.pi/workflows/local-review.yaml +7 -1
- package/.pi/workflows/local-visual-explain.yaml +46 -1
- package/.pi/workflows/temporal-control-smoke.yaml +63 -0
- package/README.md +39 -0
- package/dist/cli/index.js +211 -4
- package/dist/cli/index.js.map +1 -1
- package/dist/cli/init.d.ts +6 -1
- package/dist/cli/init.d.ts.map +1 -1
- package/dist/cli/init.js +29 -10
- package/dist/cli/init.js.map +1 -1
- package/dist/cli/run-agent.d.ts +2 -7
- package/dist/cli/run-agent.d.ts.map +1 -1
- package/dist/cli/run-agent.js.map +1 -1
- package/dist/cli/workflow-executor-selection.d.ts +3 -0
- package/dist/cli/workflow-executor-selection.d.ts.map +1 -0
- package/dist/cli/workflow-executor-selection.js +15 -0
- package/dist/cli/workflow-executor-selection.js.map +1 -0
- package/dist/cli/workflow.d.ts +38 -42
- package/dist/cli/workflow.d.ts.map +1 -1
- package/dist/cli/workflow.js +190 -838
- package/dist/cli/workflow.js.map +1 -1
- package/dist/lib/agent-result.d.ts +8 -0
- package/dist/lib/agent-result.d.ts.map +1 -0
- package/dist/lib/agent-result.js +2 -0
- package/dist/lib/agent-result.js.map +1 -0
- package/dist/lib/config.d.ts +21 -0
- package/dist/lib/config.d.ts.map +1 -1
- package/dist/lib/config.js.map +1 -1
- package/dist/lib/output-paths.d.ts +0 -1
- package/dist/lib/output-paths.d.ts.map +1 -1
- package/dist/lib/output-paths.js +0 -1
- package/dist/lib/output-paths.js.map +1 -1
- package/dist/lib/project-setup.d.ts +10 -0
- package/dist/lib/project-setup.d.ts.map +1 -0
- package/dist/lib/project-setup.js +25 -0
- package/dist/lib/project-setup.js.map +1 -0
- package/dist/lib/review-artifact-store.d.ts +16 -0
- package/dist/lib/review-artifact-store.d.ts.map +1 -0
- package/dist/lib/review-artifact-store.js +84 -0
- package/dist/lib/review-artifact-store.js.map +1 -0
- package/dist/lib/review-artifact.d.ts.map +1 -1
- package/dist/lib/review-artifact.js +1 -0
- package/dist/lib/review-artifact.js.map +1 -1
- package/dist/lib/review-core.d.ts +1 -0
- package/dist/lib/review-core.d.ts.map +1 -1
- package/dist/lib/review-core.js +11 -14
- package/dist/lib/review-core.js.map +1 -1
- package/dist/lib/review-parser.d.ts.map +1 -1
- package/dist/lib/review-parser.js +15 -12
- package/dist/lib/review-parser.js.map +1 -1
- package/dist/lib/skills.d.ts +16 -0
- package/dist/lib/skills.d.ts.map +1 -0
- package/dist/lib/skills.js +140 -0
- package/dist/lib/skills.js.map +1 -0
- package/dist/lib/workflow/artifact-store.d.ts +71 -0
- package/dist/lib/workflow/artifact-store.d.ts.map +1 -0
- package/dist/lib/workflow/artifact-store.js +121 -0
- package/dist/lib/workflow/artifact-store.js.map +1 -0
- package/dist/lib/workflow/compiled-plan.d.ts +87 -0
- package/dist/lib/workflow/compiled-plan.d.ts.map +1 -0
- package/dist/lib/workflow/compiled-plan.js +62 -0
- package/dist/lib/workflow/compiled-plan.js.map +1 -0
- package/dist/lib/workflow/executor.d.ts +18 -0
- package/dist/lib/workflow/executor.d.ts.map +1 -0
- package/dist/lib/workflow/executor.js +2 -0
- package/dist/lib/workflow/executor.js.map +1 -0
- package/dist/lib/workflow/graph.d.ts +30 -0
- package/dist/lib/workflow/graph.d.ts.map +1 -0
- package/dist/lib/workflow/graph.js +139 -0
- package/dist/lib/workflow/graph.js.map +1 -0
- package/dist/lib/workflow/input.d.ts +4 -0
- package/dist/lib/workflow/input.d.ts.map +1 -0
- package/dist/lib/workflow/input.js +4 -0
- package/dist/lib/workflow/input.js.map +1 -0
- package/dist/lib/workflow/node-executor.d.ts +19 -0
- package/dist/lib/workflow/node-executor.d.ts.map +1 -0
- package/dist/lib/workflow/node-executor.js +2 -0
- package/dist/lib/workflow/node-executor.js.map +1 -0
- package/dist/lib/workflow/planning.d.ts +51 -0
- package/dist/lib/workflow/planning.d.ts.map +1 -0
- package/dist/lib/workflow/planning.js +814 -0
- package/dist/lib/workflow/planning.js.map +1 -0
- package/dist/lib/workflow/types.d.ts +66 -0
- package/dist/lib/workflow/types.d.ts.map +1 -0
- package/dist/lib/workflow/types.js +2 -0
- package/dist/lib/workflow/types.js.map +1 -0
- package/dist/lib/write-json-output.d.ts.map +1 -1
- package/dist/lib/write-json-output.js +3 -8
- package/dist/lib/write-json-output.js.map +1 -1
- package/dist/pi/sdk.d.ts.map +1 -1
- package/dist/pi/sdk.js +6 -2
- package/dist/pi/sdk.js.map +1 -1
- package/dist/runtime/built-in-paths.d.ts +1 -0
- package/dist/runtime/built-in-paths.d.ts.map +1 -1
- package/dist/runtime/built-in-paths.js +7 -0
- package/dist/runtime/built-in-paths.js.map +1 -1
- package/dist/temporal/activities.d.ts +26 -0
- package/dist/temporal/activities.d.ts.map +1 -0
- package/dist/temporal/activities.js +219 -0
- package/dist/temporal/activities.js.map +1 -0
- package/dist/temporal/config.d.ts +4 -0
- package/dist/temporal/config.d.ts.map +1 -0
- package/dist/temporal/config.js +36 -0
- package/dist/temporal/config.js.map +1 -0
- package/dist/temporal/executor.d.ts +7 -0
- package/dist/temporal/executor.d.ts.map +1 -0
- package/dist/temporal/executor.js +233 -0
- package/dist/temporal/executor.js.map +1 -0
- package/dist/temporal/retry-policy.d.ts +28 -0
- package/dist/temporal/retry-policy.d.ts.map +1 -0
- package/dist/temporal/retry-policy.js +56 -0
- package/dist/temporal/retry-policy.js.map +1 -0
- package/dist/temporal/types.d.ts +86 -0
- package/dist/temporal/types.d.ts.map +1 -0
- package/dist/temporal/types.js +2 -0
- package/dist/temporal/types.js.map +1 -0
- package/dist/temporal/worker.d.ts +3 -0
- package/dist/temporal/worker.d.ts.map +1 -0
- package/dist/temporal/worker.js +18 -0
- package/dist/temporal/worker.js.map +1 -0
- package/dist/temporal/workflow-id.d.ts +27 -0
- package/dist/temporal/workflow-id.d.ts.map +1 -0
- package/dist/temporal/workflow-id.js +53 -0
- package/dist/temporal/workflow-id.js.map +1 -0
- package/dist/temporal/workflows.d.ts +6 -0
- package/dist/temporal/workflows.d.ts.map +1 -0
- package/dist/temporal/workflows.js +342 -0
- package/dist/temporal/workflows.js.map +1 -0
- package/package.json +6 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"review-parser.d.ts","sourceRoot":"","sources":["../../src/lib/review-parser.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"review-parser.d.ts","sourceRoot":"","sources":["../../src/lib/review-parser.ts"],"names":[],"mappings":"AAqEA,wBAAsB,iBAAiB,CACrC,UAAU,GAAE,MAAsB,EAClC,KAAK,UAAQ,EACb,SAAS,CAAC,EAAE,MAAM,GACjB,OAAO,CAAC,OAAO,CAAC,CAgDlB"}
|
|
@@ -1,11 +1,10 @@
|
|
|
1
1
|
import { readFile } from 'fs/promises';
|
|
2
|
-
import { OUTPUT_PATHS } from './output-paths.js';
|
|
3
2
|
import { resolveWithinWorkingDir } from './path-utils.js';
|
|
4
3
|
import { parseJsonFromAgentOutput } from './describe-parser.js';
|
|
4
|
+
import { loadLatestReviewArtifact, reviewArtifactToJsonOutput, toRepoRelativePath, } from './review-artifact-store.js';
|
|
5
5
|
function isOutputPointer(value) {
|
|
6
6
|
return !!value && typeof value === 'object' && ('outputType' in value || 'outputPath' in value);
|
|
7
7
|
}
|
|
8
|
-
const REVIEW_OUTPUT_PATH = OUTPUT_PATHS.review_output;
|
|
9
8
|
async function readJsonIfExists(workingDir, targetPath) {
|
|
10
9
|
const resolvedPath = resolveWithinWorkingDir(workingDir, targetPath, 'read');
|
|
11
10
|
try {
|
|
@@ -23,15 +22,12 @@ function resolveReviewOutputPath(pointer) {
|
|
|
23
22
|
if (!pointer) {
|
|
24
23
|
return null;
|
|
25
24
|
}
|
|
26
|
-
if (pointer.outputType
|
|
25
|
+
if (pointer.outputType) {
|
|
27
26
|
throw new Error(`Unexpected output type for review output: ${pointer.outputType}`);
|
|
28
27
|
}
|
|
29
28
|
if (pointer.outputPath) {
|
|
30
29
|
return pointer.outputPath;
|
|
31
30
|
}
|
|
32
|
-
if (pointer.outputType) {
|
|
33
|
-
return OUTPUT_PATHS[pointer.outputType];
|
|
34
|
-
}
|
|
35
31
|
return null;
|
|
36
32
|
}
|
|
37
33
|
function parseReviewOutputPointer(raw, debug) {
|
|
@@ -76,16 +72,23 @@ export async function parseReviewOutput(workingDir = process.cwd(), debug = fals
|
|
|
76
72
|
return pointerOutput;
|
|
77
73
|
}
|
|
78
74
|
if (debug) {
|
|
79
|
-
console.log(`Review output not found at ${pointerPath}
|
|
75
|
+
console.log(`Review output not found at ${pointerPath}.`);
|
|
80
76
|
}
|
|
81
77
|
}
|
|
82
|
-
const
|
|
83
|
-
if (
|
|
78
|
+
const latestReviewArtifact = await loadLatestReviewArtifact(workingDir);
|
|
79
|
+
if (latestReviewArtifact) {
|
|
80
|
+
const artifactPath = toRepoRelativePath(workingDir, latestReviewArtifact.path);
|
|
84
81
|
if (debug) {
|
|
85
|
-
console.log(`Review output loaded from ${
|
|
82
|
+
console.log(`Review output loaded from ${artifactPath}`);
|
|
86
83
|
}
|
|
87
|
-
return
|
|
84
|
+
return {
|
|
85
|
+
...reviewArtifactToJsonOutput(latestReviewArtifact.artifact.payload),
|
|
86
|
+
artifact: {
|
|
87
|
+
reviewId: latestReviewArtifact.artifact.payload.reviewId,
|
|
88
|
+
path: artifactPath,
|
|
89
|
+
},
|
|
90
|
+
};
|
|
88
91
|
}
|
|
89
|
-
throw new Error(
|
|
92
|
+
throw new Error('Review output not found in raw output or canonical review artifacts.');
|
|
90
93
|
}
|
|
91
94
|
//# sourceMappingURL=review-parser.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"review-parser.js","sourceRoot":"","sources":["../../src/lib/review-parser.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AACvC,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"review-parser.js","sourceRoot":"","sources":["../../src/lib/review-parser.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
export interface SkillStatus {
|
|
2
|
+
name: string;
|
|
3
|
+
bundled: boolean;
|
|
4
|
+
installed: boolean;
|
|
5
|
+
installedPath: string;
|
|
6
|
+
modified: boolean;
|
|
7
|
+
outdated: boolean;
|
|
8
|
+
}
|
|
9
|
+
export declare function listBundledSkills(): string[];
|
|
10
|
+
export declare function getSkillStatuses(workingDir: string): SkillStatus[];
|
|
11
|
+
export declare function getSkillStatus(workingDir: string, name: string): SkillStatus;
|
|
12
|
+
export declare function installBundledSkill(workingDir: string, name: string, options?: {
|
|
13
|
+
force?: boolean;
|
|
14
|
+
}): SkillStatus;
|
|
15
|
+
export declare function syncBundledSkills(workingDir: string): SkillStatus[];
|
|
16
|
+
//# sourceMappingURL=skills.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"skills.d.ts","sourceRoot":"","sources":["../../src/lib/skills.ts"],"names":[],"mappings":"AAKA,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,OAAO,CAAC;IACjB,SAAS,EAAE,OAAO,CAAC;IACnB,aAAa,EAAE,MAAM,CAAC;IACtB,QAAQ,EAAE,OAAO,CAAC;IAClB,QAAQ,EAAE,OAAO,CAAC;CACnB;AAeD,wBAAgB,iBAAiB,IAAI,MAAM,EAAE,CAW5C;AAED,wBAAgB,gBAAgB,CAAC,UAAU,EAAE,MAAM,GAAG,WAAW,EAAE,CAElE;AAED,wBAAgB,cAAc,CAAC,UAAU,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,WAAW,CAiB5E;AAED,wBAAgB,mBAAmB,CACjC,UAAU,EAAE,MAAM,EAClB,IAAI,EAAE,MAAM,EACZ,OAAO,GAAE;IAAE,KAAK,CAAC,EAAE,OAAO,CAAA;CAAO,GAChC,WAAW,CA4Bb;AAED,wBAAgB,iBAAiB,CAAC,UAAU,EAAE,MAAM,GAAG,WAAW,EAAE,CAuBnE"}
|
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
import { createHash } from 'crypto';
|
|
2
|
+
import { cpSync, existsSync, mkdirSync, readdirSync, readFileSync, writeFileSync } from 'fs';
|
|
3
|
+
import { dirname, join } from 'path';
|
|
4
|
+
import { getBuiltInSkillPaths } from '../runtime/built-in-paths.js';
|
|
5
|
+
const PROJECT_SKILL_DIR = '.agents/skills';
|
|
6
|
+
const LOCK_PATH = '.drs/skills-lock.json';
|
|
7
|
+
export function listBundledSkills() {
|
|
8
|
+
const names = new Set();
|
|
9
|
+
for (const base of getBuiltInSkillPaths()) {
|
|
10
|
+
if (!existsSync(base))
|
|
11
|
+
continue;
|
|
12
|
+
for (const entry of readdirSync(base, { withFileTypes: true })) {
|
|
13
|
+
if (entry.isDirectory() && existsSync(join(base, entry.name, 'SKILL.md'))) {
|
|
14
|
+
names.add(entry.name);
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
return [...names].sort();
|
|
19
|
+
}
|
|
20
|
+
export function getSkillStatuses(workingDir) {
|
|
21
|
+
return listBundledSkills().map((name) => getSkillStatus(workingDir, name));
|
|
22
|
+
}
|
|
23
|
+
export function getSkillStatus(workingDir, name) {
|
|
24
|
+
const source = resolveBundledSkillPath(name);
|
|
25
|
+
const installedPath = join(PROJECT_SKILL_DIR, name);
|
|
26
|
+
const absoluteInstalledPath = join(workingDir, installedPath);
|
|
27
|
+
const lock = readSkillLock(workingDir);
|
|
28
|
+
const lockEntry = lock.skills[name];
|
|
29
|
+
const installed = existsSync(join(absoluteInstalledPath, 'SKILL.md'));
|
|
30
|
+
const currentHash = installed ? hashDirectory(absoluteInstalledPath) : '';
|
|
31
|
+
const sourceHash = source ? hashDirectory(source) : '';
|
|
32
|
+
return {
|
|
33
|
+
name,
|
|
34
|
+
bundled: !!source,
|
|
35
|
+
installed,
|
|
36
|
+
installedPath,
|
|
37
|
+
modified: installed && !!lockEntry && currentHash !== lockEntry.contentHash,
|
|
38
|
+
outdated: installed && !!source && currentHash !== sourceHash,
|
|
39
|
+
};
|
|
40
|
+
}
|
|
41
|
+
export function installBundledSkill(workingDir, name, options = {}) {
|
|
42
|
+
const source = resolveBundledSkillPath(name);
|
|
43
|
+
if (!source)
|
|
44
|
+
throw new Error(`Bundled skill not found: ${name}`);
|
|
45
|
+
const target = join(workingDir, PROJECT_SKILL_DIR, name);
|
|
46
|
+
const lock = readSkillLock(workingDir);
|
|
47
|
+
const lockEntry = lock.skills[name];
|
|
48
|
+
if (existsSync(join(target, 'SKILL.md')) && !options.force) {
|
|
49
|
+
const currentHash = hashDirectory(target);
|
|
50
|
+
const sourceHash = hashDirectory(source);
|
|
51
|
+
const unmodifiedManaged = currentHash === lockEntry?.contentHash;
|
|
52
|
+
if (!unmodifiedManaged && currentHash !== sourceHash) {
|
|
53
|
+
throw new Error(`Skill ${name} is already installed and has local changes. Use --force to overwrite.`);
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
mkdirSync(dirname(target), { recursive: true });
|
|
57
|
+
cpSync(source, target, { recursive: true, force: true });
|
|
58
|
+
const contentHash = hashDirectory(target);
|
|
59
|
+
lock.skills[name] = {
|
|
60
|
+
source: 'bundled',
|
|
61
|
+
installedPath: join(PROJECT_SKILL_DIR, name),
|
|
62
|
+
contentHash,
|
|
63
|
+
};
|
|
64
|
+
writeSkillLock(workingDir, lock);
|
|
65
|
+
return getSkillStatus(workingDir, name);
|
|
66
|
+
}
|
|
67
|
+
export function syncBundledSkills(workingDir) {
|
|
68
|
+
const lock = readSkillLock(workingDir);
|
|
69
|
+
const synced = [];
|
|
70
|
+
for (const name of Object.keys(lock.skills).sort()) {
|
|
71
|
+
const source = resolveBundledSkillPath(name);
|
|
72
|
+
if (!source)
|
|
73
|
+
continue;
|
|
74
|
+
const target = join(workingDir, PROJECT_SKILL_DIR, name);
|
|
75
|
+
if (!existsSync(join(target, 'SKILL.md'))) {
|
|
76
|
+
synced.push(installBundledSkill(workingDir, name));
|
|
77
|
+
continue;
|
|
78
|
+
}
|
|
79
|
+
const currentHash = hashDirectory(target);
|
|
80
|
+
if (currentHash !== lock.skills[name].contentHash) {
|
|
81
|
+
synced.push(getSkillStatus(workingDir, name));
|
|
82
|
+
continue;
|
|
83
|
+
}
|
|
84
|
+
if (currentHash !== hashDirectory(source)) {
|
|
85
|
+
synced.push(installBundledSkill(workingDir, name));
|
|
86
|
+
}
|
|
87
|
+
else {
|
|
88
|
+
synced.push(getSkillStatus(workingDir, name));
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
return synced;
|
|
92
|
+
}
|
|
93
|
+
function resolveBundledSkillPath(name) {
|
|
94
|
+
for (const base of getBuiltInSkillPaths()) {
|
|
95
|
+
const candidate = join(base, name);
|
|
96
|
+
if (existsSync(join(candidate, 'SKILL.md')))
|
|
97
|
+
return candidate;
|
|
98
|
+
}
|
|
99
|
+
return null;
|
|
100
|
+
}
|
|
101
|
+
function readSkillLock(workingDir) {
|
|
102
|
+
const lockPath = join(workingDir, LOCK_PATH);
|
|
103
|
+
if (!existsSync(lockPath))
|
|
104
|
+
return { skills: {} };
|
|
105
|
+
try {
|
|
106
|
+
const parsed = JSON.parse(readFileSync(lockPath, 'utf-8'));
|
|
107
|
+
return { skills: parsed.skills && typeof parsed.skills === 'object' ? parsed.skills : {} };
|
|
108
|
+
}
|
|
109
|
+
catch {
|
|
110
|
+
return { skills: {} };
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
function writeSkillLock(workingDir, lock) {
|
|
114
|
+
const lockPath = join(workingDir, LOCK_PATH);
|
|
115
|
+
mkdirSync(dirname(lockPath), { recursive: true });
|
|
116
|
+
writeFileSync(lockPath, `${JSON.stringify(lock, null, 2)}\n`, 'utf-8');
|
|
117
|
+
}
|
|
118
|
+
function hashDirectory(dir) {
|
|
119
|
+
const hash = createHash('sha256');
|
|
120
|
+
for (const file of listFiles(dir)) {
|
|
121
|
+
const rel = file.slice(dir.length + 1);
|
|
122
|
+
hash.update(rel);
|
|
123
|
+
hash.update('\0');
|
|
124
|
+
hash.update(readFileSync(file));
|
|
125
|
+
hash.update('\0');
|
|
126
|
+
}
|
|
127
|
+
return hash.digest('hex');
|
|
128
|
+
}
|
|
129
|
+
function listFiles(dir) {
|
|
130
|
+
const files = [];
|
|
131
|
+
for (const entry of readdirSync(dir, { withFileTypes: true })) {
|
|
132
|
+
const path = join(dir, entry.name);
|
|
133
|
+
if (entry.isDirectory())
|
|
134
|
+
files.push(...listFiles(path));
|
|
135
|
+
else if (entry.isFile())
|
|
136
|
+
files.push(path);
|
|
137
|
+
}
|
|
138
|
+
return files.sort();
|
|
139
|
+
}
|
|
140
|
+
//# sourceMappingURL=skills.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"skills.js","sourceRoot":"","sources":["../../src/lib/skills.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Reference to a workflow artifact stored outside Temporal history.
|
|
3
|
+
*
|
|
4
|
+
* Large node outputs (diffs, review payloads, model responses) are persisted
|
|
5
|
+
* to an artifact store and replaced with this ref in the Temporal event
|
|
6
|
+
* history so history stays small and replayable.
|
|
7
|
+
*/
|
|
8
|
+
export interface TemporalArtifactRef {
|
|
9
|
+
kind: 'artifact-ref';
|
|
10
|
+
key: string;
|
|
11
|
+
uri: string;
|
|
12
|
+
contentType?: string;
|
|
13
|
+
sizeBytes?: number;
|
|
14
|
+
sha256?: string;
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* Metadata recorded alongside a stored artifact value.
|
|
18
|
+
*/
|
|
19
|
+
export interface ArtifactMetadata {
|
|
20
|
+
contentType?: string;
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Policy controlling which node output values stay inline in workflow/results
|
|
24
|
+
* and which are offloaded to the artifact store as refs.
|
|
25
|
+
*
|
|
26
|
+
* - `inline-only`: every value stays inline (local executor default).
|
|
27
|
+
* - `ref-large-values`: values larger than `inlineMaxBytes` become refs
|
|
28
|
+
* (Temporal executor default).
|
|
29
|
+
* - `ref-all-values`: every value becomes a ref (useful for debugging or
|
|
30
|
+
* strict-history-size scenarios).
|
|
31
|
+
*/
|
|
32
|
+
export type ArtifactInliningMode = 'inline-only' | 'ref-large-values' | 'ref-all-values';
|
|
33
|
+
export interface ArtifactInliningPolicy {
|
|
34
|
+
mode: ArtifactInliningMode;
|
|
35
|
+
inlineMaxBytes: number;
|
|
36
|
+
}
|
|
37
|
+
export declare const DEFAULT_ARTIFACT_POLICY: ArtifactInliningPolicy;
|
|
38
|
+
/**
|
|
39
|
+
* Backend for persisting and hydrating workflow artifact values.
|
|
40
|
+
*
|
|
41
|
+
* The local filesystem store is used for development and the Temporal MVP.
|
|
42
|
+
* S3-compatible and other object stores can implement the same interface for
|
|
43
|
+
* CI/production without changing workflow code.
|
|
44
|
+
*/
|
|
45
|
+
export interface WorkflowArtifactStore {
|
|
46
|
+
put(key: string, value: unknown, metadata?: ArtifactMetadata): Promise<TemporalArtifactRef>;
|
|
47
|
+
get(ref: TemporalArtifactRef): Promise<unknown>;
|
|
48
|
+
exists(ref: TemporalArtifactRef): Promise<boolean>;
|
|
49
|
+
}
|
|
50
|
+
export declare function isArtifactRef(value: unknown): value is TemporalArtifactRef;
|
|
51
|
+
/**
|
|
52
|
+
* Decide whether a value should stay inline or be offloaded to the store.
|
|
53
|
+
*/
|
|
54
|
+
export declare function shouldInline(serializedSize: number, policy: ArtifactInliningPolicy): boolean;
|
|
55
|
+
/**
|
|
56
|
+
* Local filesystem artifact store.
|
|
57
|
+
*
|
|
58
|
+
* Persists artifacts under `.drs/artifacts/temporal/<namespace>/<key>` within
|
|
59
|
+
* the specified working directory. The `uri` in returned refs is a relative
|
|
60
|
+
* path so the store works consistently across machines when the working
|
|
61
|
+
* directory matches.
|
|
62
|
+
*/
|
|
63
|
+
export declare class LocalWorkflowArtifactStore implements WorkflowArtifactStore {
|
|
64
|
+
private readonly workingDir;
|
|
65
|
+
private readonly baseDir;
|
|
66
|
+
constructor(workingDir: string, namespace?: string);
|
|
67
|
+
put(key: string, value: unknown, metadata?: ArtifactMetadata): Promise<TemporalArtifactRef>;
|
|
68
|
+
get(ref: TemporalArtifactRef): Promise<unknown>;
|
|
69
|
+
exists(ref: TemporalArtifactRef): Promise<boolean>;
|
|
70
|
+
}
|
|
71
|
+
//# sourceMappingURL=artifact-store.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"artifact-store.d.ts","sourceRoot":"","sources":["../../../src/lib/workflow/artifact-store.ts"],"names":[],"mappings":"AAKA;;;;;;GAMG;AACH,MAAM,WAAW,mBAAmB;IAClC,IAAI,EAAE,cAAc,CAAC;IACrB,GAAG,EAAE,MAAM,CAAC;IACZ,GAAG,EAAE,MAAM,CAAC;IACZ,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED;;GAEG;AACH,MAAM,WAAW,gBAAgB;IAC/B,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED;;;;;;;;;GASG;AACH,MAAM,MAAM,oBAAoB,GAAG,aAAa,GAAG,kBAAkB,GAAG,gBAAgB,CAAC;AAEzF,MAAM,WAAW,sBAAsB;IACrC,IAAI,EAAE,oBAAoB,CAAC;IAC3B,cAAc,EAAE,MAAM,CAAC;CACxB;AAED,eAAO,MAAM,uBAAuB,EAAE,sBAGrC,CAAC;AAEF;;;;;;GAMG;AACH,MAAM,WAAW,qBAAqB;IACpC,GAAG,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,EAAE,QAAQ,CAAC,EAAE,gBAAgB,GAAG,OAAO,CAAC,mBAAmB,CAAC,CAAC;IAC5F,GAAG,CAAC,GAAG,EAAE,mBAAmB,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IAChD,MAAM,CAAC,GAAG,EAAE,mBAAmB,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;CACpD;AAED,wBAAgB,aAAa,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,mBAAmB,CAQ1E;AAED;;GAEG;AACH,wBAAgB,YAAY,CAAC,cAAc,EAAE,MAAM,EAAE,MAAM,EAAE,sBAAsB,GAAG,OAAO,CAI5F;AAiDD;;;;;;;GAOG;AACH,qBAAa,0BAA2B,YAAW,qBAAqB;IAIpE,OAAO,CAAC,QAAQ,CAAC,UAAU;IAH7B,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAS;gBAGd,UAAU,EAAE,MAAM,EACnC,SAAS,SAAY;IAMjB,GAAG,CACP,GAAG,EAAE,MAAM,EACX,KAAK,EAAE,OAAO,EACd,QAAQ,CAAC,EAAE,gBAAgB,GAC1B,OAAO,CAAC,mBAAmB,CAAC;IAqBzB,GAAG,CAAC,GAAG,EAAE,mBAAmB,GAAG,OAAO,CAAC,OAAO,CAAC;IAM/C,MAAM,CAAC,GAAG,EAAE,mBAAmB,GAAG,OAAO,CAAC,OAAO,CAAC;CAUzD"}
|
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
import { createHash } from 'crypto';
|
|
2
|
+
import { mkdir, readFile, writeFile } from 'fs/promises';
|
|
3
|
+
import { dirname, join } from 'path';
|
|
4
|
+
import { resolveWithinWorkingDir } from '../path-utils.js';
|
|
5
|
+
export const DEFAULT_ARTIFACT_POLICY = {
|
|
6
|
+
mode: 'ref-large-values',
|
|
7
|
+
inlineMaxBytes: 64 * 1024,
|
|
8
|
+
};
|
|
9
|
+
export function isArtifactRef(value) {
|
|
10
|
+
return (typeof value === 'object' &&
|
|
11
|
+
value !== null &&
|
|
12
|
+
value.kind === 'artifact-ref' &&
|
|
13
|
+
typeof value.key === 'string' &&
|
|
14
|
+
typeof value.uri === 'string');
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* Decide whether a value should stay inline or be offloaded to the store.
|
|
18
|
+
*/
|
|
19
|
+
export function shouldInline(serializedSize, policy) {
|
|
20
|
+
if (policy.mode === 'inline-only')
|
|
21
|
+
return true;
|
|
22
|
+
if (policy.mode === 'ref-all-values')
|
|
23
|
+
return false;
|
|
24
|
+
return serializedSize <= policy.inlineMaxBytes;
|
|
25
|
+
}
|
|
26
|
+
function serialize(value) {
|
|
27
|
+
if (typeof value === 'string') {
|
|
28
|
+
return { bytes: Buffer.from(value, 'utf-8'), contentType: 'text/plain' };
|
|
29
|
+
}
|
|
30
|
+
return {
|
|
31
|
+
bytes: Buffer.from(JSON.stringify(value, null, 2), 'utf-8'),
|
|
32
|
+
contentType: 'application/json',
|
|
33
|
+
};
|
|
34
|
+
}
|
|
35
|
+
function deserialize(buf, contentType) {
|
|
36
|
+
const text = buf.toString('utf-8');
|
|
37
|
+
if (contentType === 'application/json') {
|
|
38
|
+
return JSON.parse(text);
|
|
39
|
+
}
|
|
40
|
+
if (contentType === 'text/plain') {
|
|
41
|
+
return text;
|
|
42
|
+
}
|
|
43
|
+
// Fallback: try JSON, then treat as string.
|
|
44
|
+
try {
|
|
45
|
+
return JSON.parse(text);
|
|
46
|
+
}
|
|
47
|
+
catch {
|
|
48
|
+
return text;
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
function sha256(buf) {
|
|
52
|
+
return createHash('sha256').update(buf).digest('hex');
|
|
53
|
+
}
|
|
54
|
+
function slugSegment(value, fallback) {
|
|
55
|
+
const raw = value === undefined || value === '' ? fallback : String(value);
|
|
56
|
+
const slug = raw
|
|
57
|
+
.trim()
|
|
58
|
+
.replace(/[^A-Za-z0-9._-]+/g, '-')
|
|
59
|
+
.replace(/^-+|-+$/g, '');
|
|
60
|
+
return slug || fallback;
|
|
61
|
+
}
|
|
62
|
+
function sanitizeKey(key) {
|
|
63
|
+
const segments = key.split('/').map((seg) => slugSegment(seg, 'segment'));
|
|
64
|
+
if (segments.some((seg) => seg === '..' || seg === '.')) {
|
|
65
|
+
throw new Error(`Refusing to put artifact with unsafe key: ${key}`);
|
|
66
|
+
}
|
|
67
|
+
return segments.join('/');
|
|
68
|
+
}
|
|
69
|
+
/**
|
|
70
|
+
* Local filesystem artifact store.
|
|
71
|
+
*
|
|
72
|
+
* Persists artifacts under `.drs/artifacts/temporal/<namespace>/<key>` within
|
|
73
|
+
* the specified working directory. The `uri` in returned refs is a relative
|
|
74
|
+
* path so the store works consistently across machines when the working
|
|
75
|
+
* directory matches.
|
|
76
|
+
*/
|
|
77
|
+
export class LocalWorkflowArtifactStore {
|
|
78
|
+
workingDir;
|
|
79
|
+
baseDir;
|
|
80
|
+
constructor(workingDir, namespace = 'default') {
|
|
81
|
+
this.workingDir = workingDir;
|
|
82
|
+
const slug = slugSegment(namespace, 'default');
|
|
83
|
+
this.baseDir = `.drs/artifacts/temporal/${slug}`;
|
|
84
|
+
}
|
|
85
|
+
async put(key, value, metadata) {
|
|
86
|
+
const { bytes, contentType } = serialize(value);
|
|
87
|
+
const resolvedContentType = metadata?.contentType ?? contentType;
|
|
88
|
+
const hash = sha256(bytes);
|
|
89
|
+
const safeKey = sanitizeKey(key);
|
|
90
|
+
const relativePath = join(this.baseDir, `${safeKey}.json`);
|
|
91
|
+
const fullPath = resolveWithinWorkingDir(this.workingDir, relativePath, 'write');
|
|
92
|
+
await mkdir(dirname(fullPath), { recursive: true });
|
|
93
|
+
await writeFile(fullPath, bytes, 'utf-8');
|
|
94
|
+
return {
|
|
95
|
+
kind: 'artifact-ref',
|
|
96
|
+
key,
|
|
97
|
+
uri: relativePath,
|
|
98
|
+
contentType: resolvedContentType,
|
|
99
|
+
sizeBytes: bytes.length,
|
|
100
|
+
sha256: hash,
|
|
101
|
+
};
|
|
102
|
+
}
|
|
103
|
+
async get(ref) {
|
|
104
|
+
const fullPath = resolveWithinWorkingDir(this.workingDir, ref.uri, 'read');
|
|
105
|
+
const bytes = await readFile(fullPath);
|
|
106
|
+
return deserialize(bytes, ref.contentType);
|
|
107
|
+
}
|
|
108
|
+
async exists(ref) {
|
|
109
|
+
try {
|
|
110
|
+
const fullPath = resolveWithinWorkingDir(this.workingDir, ref.uri, 'read');
|
|
111
|
+
await readFile(fullPath);
|
|
112
|
+
return true;
|
|
113
|
+
}
|
|
114
|
+
catch (error) {
|
|
115
|
+
if (error.code === 'ENOENT')
|
|
116
|
+
return false;
|
|
117
|
+
throw error;
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
//# sourceMappingURL=artifact-store.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"artifact-store.js","sourceRoot":"","sources":["../../../src/lib/workflow/artifact-store.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
import type { DRSConfig, WorkflowNodeConfig } from '../config.js';
|
|
2
|
+
/**
|
|
3
|
+
* Workflow node as it appears in a compiled plan.
|
|
4
|
+
*
|
|
5
|
+
* This is currently an API-facing alias for WorkflowNodeConfig so future plan
|
|
6
|
+
* schema changes can evolve independently from raw workflow config types.
|
|
7
|
+
*/
|
|
8
|
+
export type CompiledWorkflowNode = WorkflowNodeConfig;
|
|
9
|
+
/**
|
|
10
|
+
* A DRS workflow control-flow segment expressed as JSON-serializable data.
|
|
11
|
+
*
|
|
12
|
+
* - DAG segments list their node ids plus, when a control node routes into
|
|
13
|
+
* them, the set of active node ids that should actually execute (inactive
|
|
14
|
+
* node ids are skipped by the runner). Active ids are absent for plain DAG
|
|
15
|
+
* segments with no gating control node.
|
|
16
|
+
* - Control segments record the controlling node id.
|
|
17
|
+
*/
|
|
18
|
+
export type CompiledWorkflowSegment = {
|
|
19
|
+
type: 'dag';
|
|
20
|
+
nodeIds: string[];
|
|
21
|
+
activeNodeIds?: string[];
|
|
22
|
+
} | {
|
|
23
|
+
type: 'control';
|
|
24
|
+
nodeId: string;
|
|
25
|
+
};
|
|
26
|
+
/**
|
|
27
|
+
* Metadata for a single workflow input, normalized to a plain object so the
|
|
28
|
+
* compiled plan is JSON-serializable even when the original input is declared
|
|
29
|
+
* as a bare string.
|
|
30
|
+
*/
|
|
31
|
+
export interface CompiledWorkflowInput {
|
|
32
|
+
type: 'string' | 'boolean' | 'number' | 'enum';
|
|
33
|
+
value?: string;
|
|
34
|
+
file?: string;
|
|
35
|
+
default?: string | number | boolean;
|
|
36
|
+
required?: boolean;
|
|
37
|
+
values?: Array<string | number | boolean>;
|
|
38
|
+
description?: string;
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* A fully resolved, JSON-serializable description of a workflow ready to be
|
|
42
|
+
* handed to an executor (local or Temporal). It carries everything needed to
|
|
43
|
+
* schedule nodes without reloading repo config: normalized nodes, execution
|
|
44
|
+
* order, waves, control-flow segments, input metadata, and the output key.
|
|
45
|
+
*
|
|
46
|
+
* Resolved input *values* are intentionally not part of the plan; they are
|
|
47
|
+
* supplied separately at run time so the same plan can dispatch multiple runs
|
|
48
|
+
* with different inputs.
|
|
49
|
+
*/
|
|
50
|
+
export interface CompiledWorkflowPlan {
|
|
51
|
+
/** Schema version so executors can evolve the shape safely. */
|
|
52
|
+
schemaVersion: 1;
|
|
53
|
+
/** Workflow name as resolved from config.workflows. */
|
|
54
|
+
workflowName: string;
|
|
55
|
+
/** Optional human-readable description. */
|
|
56
|
+
description?: string;
|
|
57
|
+
/** Origin of the workflow definition: packaged or project. */
|
|
58
|
+
source: 'packaged' | 'project';
|
|
59
|
+
/** Project workflows overriding a packaged workflow of the same name. */
|
|
60
|
+
overridesPackaged: boolean;
|
|
61
|
+
/** Workflow-level output artifact key. May be undefined (last node output). */
|
|
62
|
+
output?: string;
|
|
63
|
+
/** Workflow input metadata keyed by input name. */
|
|
64
|
+
inputs: Record<string, CompiledWorkflowInput>;
|
|
65
|
+
/** Normalized nodes keyed by id, identical in shape to WorkflowNodeConfig. */
|
|
66
|
+
nodes: Record<string, CompiledWorkflowNode>;
|
|
67
|
+
/** Dependency-ordered node ids (topological). */
|
|
68
|
+
executionOrder: string[];
|
|
69
|
+
/** Wave grouping for parallel DAG execution. */
|
|
70
|
+
waves: string[][];
|
|
71
|
+
/** Control-flow segments for control-bearing workflows; empty for DAG-only. */
|
|
72
|
+
segments: CompiledWorkflowSegment[];
|
|
73
|
+
/** True when the workflow uses any control (loop/switch/end/passThrough) node. */
|
|
74
|
+
hasControlNodes: boolean;
|
|
75
|
+
/** Id of the last node in execution order, used when output is undefined. */
|
|
76
|
+
lastNodeId: string;
|
|
77
|
+
}
|
|
78
|
+
/**
|
|
79
|
+
* Subset of {@link WorkflowRunOptions} relevant to plan compilation. The
|
|
80
|
+
* workingDir is used only to resolve workflow source info (packaged vs.
|
|
81
|
+
* project) and does not become part of the serialized plan.
|
|
82
|
+
*/
|
|
83
|
+
export interface CompileWorkflowPlanOptions {
|
|
84
|
+
workingDir?: string;
|
|
85
|
+
}
|
|
86
|
+
export declare function compileWorkflowPlan(config: DRSConfig, workflowName: string, options?: CompileWorkflowPlanOptions): CompiledWorkflowPlan;
|
|
87
|
+
//# sourceMappingURL=compiled-plan.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"compiled-plan.d.ts","sourceRoot":"","sources":["../../../src/lib/workflow/compiled-plan.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,SAAS,EAGT,kBAAkB,EACnB,MAAM,cAAc,CAAC;AAWtB;;;;;GAKG;AACH,MAAM,MAAM,oBAAoB,GAAG,kBAAkB,CAAC;AAEtD;;;;;;;;GAQG;AACH,MAAM,MAAM,uBAAuB,GAC/B;IAAE,IAAI,EAAE,KAAK,CAAC;IAAC,OAAO,EAAE,MAAM,EAAE,CAAC;IAAC,aAAa,CAAC,EAAE,MAAM,EAAE,CAAA;CAAE,GAC5D;IAAE,IAAI,EAAE,SAAS,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAAC;AAExC;;;;GAIG;AACH,MAAM,WAAW,qBAAqB;IACpC,IAAI,EAAE,QAAQ,GAAG,SAAS,GAAG,QAAQ,GAAG,MAAM,CAAC;IAC/C,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,OAAO,CAAC,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO,CAAC;IACpC,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,MAAM,CAAC,EAAE,KAAK,CAAC,MAAM,GAAG,MAAM,GAAG,OAAO,CAAC,CAAC;IAC1C,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED;;;;;;;;;GASG;AACH,MAAM,WAAW,oBAAoB;IACnC,+DAA+D;IAC/D,aAAa,EAAE,CAAC,CAAC;IACjB,uDAAuD;IACvD,YAAY,EAAE,MAAM,CAAC;IACrB,2CAA2C;IAC3C,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,8DAA8D;IAC9D,MAAM,EAAE,UAAU,GAAG,SAAS,CAAC;IAC/B,yEAAyE;IACzE,iBAAiB,EAAE,OAAO,CAAC;IAC3B,+EAA+E;IAC/E,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,mDAAmD;IACnD,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,qBAAqB,CAAC,CAAC;IAC9C,8EAA8E;IAC9E,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,oBAAoB,CAAC,CAAC;IAC5C,iDAAiD;IACjD,cAAc,EAAE,MAAM,EAAE,CAAC;IACzB,gDAAgD;IAChD,KAAK,EAAE,MAAM,EAAE,EAAE,CAAC;IAClB,+EAA+E;IAC/E,QAAQ,EAAE,uBAAuB,EAAE,CAAC;IACpC,kFAAkF;IAClF,eAAe,EAAE,OAAO,CAAC;IACzB,6EAA6E;IAC7E,UAAU,EAAE,MAAM,CAAC;CACpB;AAED;;;;GAIG;AACH,MAAM,WAAW,0BAA0B;IACzC,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAiBD,wBAAgB,mBAAmB,CACjC,MAAM,EAAE,SAAS,EACjB,YAAY,EAAE,MAAM,EACpB,OAAO,GAAE,0BAA+B,GACvC,oBAAoB,CAmDtB"}
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
import { loadWorkflowSourceInfo } from '../config.js';
|
|
2
|
+
import { getWorkflowExecutionOrder, getWorkflowExecutionWaves, getWorkflowNodes, hasWorkflowControlNodes, splitWorkflowSegments, } from './planning.js';
|
|
3
|
+
import { getWorkflowInputConfigType } from './input.js';
|
|
4
|
+
function normalizeWorkflowInput(input) {
|
|
5
|
+
if (typeof input === 'string') {
|
|
6
|
+
return { type: 'string', value: input };
|
|
7
|
+
}
|
|
8
|
+
return {
|
|
9
|
+
type: getWorkflowInputConfigType(input),
|
|
10
|
+
value: input.value,
|
|
11
|
+
file: input.file,
|
|
12
|
+
default: input.default,
|
|
13
|
+
required: input.required,
|
|
14
|
+
values: input.values,
|
|
15
|
+
description: input.description,
|
|
16
|
+
};
|
|
17
|
+
}
|
|
18
|
+
export function compileWorkflowPlan(config, workflowName, options = {}) {
|
|
19
|
+
const workflow = config.workflows?.[workflowName];
|
|
20
|
+
if (!workflow) {
|
|
21
|
+
throw new Error(`Unknown workflow "${workflowName}".`);
|
|
22
|
+
}
|
|
23
|
+
const workingDir = options.workingDir ?? process.cwd();
|
|
24
|
+
const sourceInfo = loadWorkflowSourceInfo(workingDir)[workflowName] ?? {
|
|
25
|
+
source: 'packaged',
|
|
26
|
+
overridesPackaged: false,
|
|
27
|
+
};
|
|
28
|
+
const nodes = getWorkflowNodes(workflowName, workflow);
|
|
29
|
+
const executionOrder = getWorkflowExecutionOrder(nodes);
|
|
30
|
+
const waves = getWorkflowExecutionWaves(nodes, executionOrder);
|
|
31
|
+
const hasControlNodes = hasWorkflowControlNodes(nodes);
|
|
32
|
+
const segments = hasControlNodes
|
|
33
|
+
? splitWorkflowSegments(nodes, executionOrder).map((segment) => segment.type === 'control'
|
|
34
|
+
? { type: 'control', nodeId: segment.nodeId }
|
|
35
|
+
: {
|
|
36
|
+
type: 'dag',
|
|
37
|
+
nodeIds: segment.nodeIds,
|
|
38
|
+
...(segment.activeNodeIds
|
|
39
|
+
? { activeNodeIds: Array.from(segment.activeNodeIds) }
|
|
40
|
+
: {}),
|
|
41
|
+
})
|
|
42
|
+
: [];
|
|
43
|
+
return {
|
|
44
|
+
schemaVersion: 1,
|
|
45
|
+
workflowName,
|
|
46
|
+
description: workflow.description,
|
|
47
|
+
source: sourceInfo.source,
|
|
48
|
+
overridesPackaged: sourceInfo.overridesPackaged,
|
|
49
|
+
output: workflow.output,
|
|
50
|
+
inputs: Object.fromEntries(Object.entries(workflow.inputs ?? {}).map(([name, input]) => [
|
|
51
|
+
name,
|
|
52
|
+
normalizeWorkflowInput(input),
|
|
53
|
+
])),
|
|
54
|
+
nodes,
|
|
55
|
+
executionOrder,
|
|
56
|
+
waves,
|
|
57
|
+
segments,
|
|
58
|
+
hasControlNodes,
|
|
59
|
+
lastNodeId: executionOrder[executionOrder.length - 1] ?? '',
|
|
60
|
+
};
|
|
61
|
+
}
|
|
62
|
+
//# sourceMappingURL=compiled-plan.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"compiled-plan.js","sourceRoot":"","sources":["../../../src/lib/workflow/compiled-plan.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import type { DRSConfig } from '../config.js';
|
|
2
|
+
import type { WorkflowRunOptions, WorkflowRunResult } from './types.js';
|
|
3
|
+
/**
|
|
4
|
+
* Execution backend for DRS workflows.
|
|
5
|
+
*
|
|
6
|
+
* The CLI's default backend is the local in-process executor. A Temporal
|
|
7
|
+
* executor will implement this same interface so that `drs workflow run` can
|
|
8
|
+
* dispatch through either backend without changing the workflow DSL or the
|
|
9
|
+
* result shape.
|
|
10
|
+
*/
|
|
11
|
+
export interface WorkflowExecutor {
|
|
12
|
+
/**
|
|
13
|
+
* Run a workflow by name using the project config and return the same
|
|
14
|
+
* `WorkflowRunResult` shape as the local executor.
|
|
15
|
+
*/
|
|
16
|
+
run(config: DRSConfig, workflowName: string, options?: WorkflowRunOptions): Promise<WorkflowRunResult>;
|
|
17
|
+
}
|
|
18
|
+
//# sourceMappingURL=executor.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"executor.d.ts","sourceRoot":"","sources":["../../../src/lib/workflow/executor.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAC9C,OAAO,KAAK,EAAE,kBAAkB,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAC;AAExE;;;;;;;GAOG;AACH,MAAM,WAAW,gBAAgB;IAC/B;;;OAGG;IACH,GAAG,CACD,MAAM,EAAE,SAAS,EACjB,YAAY,EAAE,MAAM,EACpB,OAAO,CAAC,EAAE,kBAAkB,GAC3B,OAAO,CAAC,iBAAiB,CAAC,CAAC;CAC/B"}
|