stageflow 0.1.0 → 0.3.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/README.md +190 -13
- package/dist/agent/activity.d.ts +10 -1
- package/dist/agent/activity.js +37 -2
- package/dist/agent/activityObserver.d.ts +5 -1
- package/dist/agent/activityObserver.js +174 -11
- package/dist/agent/fakeAgent.js +4 -0
- package/dist/agent/piAdapter.d.ts +16 -0
- package/dist/agent/piAdapter.js +88 -21
- package/dist/agent/port.d.ts +2 -0
- package/dist/agent/providerAuth.js +12 -7
- package/dist/catalog/displayCatalogPath.d.ts +12 -0
- package/dist/catalog/displayCatalogPath.js +28 -0
- package/dist/cli/ciIdentity.d.ts +14 -0
- package/dist/cli/ciIdentity.js +52 -0
- package/dist/cli/initCommand.d.ts +9 -0
- package/dist/cli/initCommand.js +71 -0
- package/dist/cli/initTemplates.d.ts +3 -0
- package/dist/cli/initTemplates.js +19 -0
- package/dist/cli/operatorCatalog.d.ts +10 -0
- package/dist/cli/operatorCatalog.js +16 -0
- package/dist/cli/runCommand.d.ts +26 -0
- package/dist/cli/runCommand.js +209 -0
- package/dist/cli/runOutput.d.ts +19 -0
- package/dist/cli/runOutput.js +125 -0
- package/dist/cli/validateCommand.d.ts +1 -1
- package/dist/cli/validateCommand.js +20 -3
- package/dist/cli.d.ts +12 -1
- package/dist/cli.js +82 -66
- package/dist/config/browseCatalog.d.ts +45 -0
- package/dist/config/browseCatalog.js +170 -0
- package/dist/config/createPipeline.d.ts +12 -3
- package/dist/config/createPipeline.js +292 -100
- package/dist/config/createStage.d.ts +10 -4
- package/dist/config/createStage.js +44 -14
- package/dist/config/listConfig.d.ts +14 -19
- package/dist/config/listConfig.js +26 -191
- package/dist/config/listModelsFromManifest.d.ts +2 -0
- package/dist/config/listModelsFromManifest.js +4 -0
- package/dist/config/loadOutcome.d.ts +4 -0
- package/dist/config/loadPipeline.d.ts +1 -15
- package/dist/config/loadPipeline.js +84 -142
- package/dist/config/loadStage.d.ts +4 -0
- package/dist/config/loadStage.js +60 -32
- package/dist/config/loadStageflowManifest.d.ts +5 -0
- package/dist/config/loadStageflowManifest.js +157 -0
- package/dist/config/mergePipelineIncludes.d.ts +9 -0
- package/dist/config/mergePipelineIncludes.js +141 -0
- package/dist/config/normalizePipelineStageEntry.d.ts +16 -0
- package/dist/config/normalizePipelineStageEntry.js +186 -0
- package/dist/config/pipelineStageKeys.d.ts +4 -0
- package/dist/config/pipelineStageKeys.js +14 -0
- package/dist/config/resolveCatalogContext.d.ts +13 -0
- package/dist/config/resolveCatalogContext.js +13 -0
- package/dist/config/resolveForkEmitContext.d.ts +3 -0
- package/dist/config/resolveForkEmitContext.js +12 -0
- package/dist/config/resolvePipelineDag.d.ts +5 -1
- package/dist/config/resolvePipelineDag.js +54 -36
- package/dist/config/scanCatalogPaths.d.ts +4 -0
- package/dist/config/scanCatalogPaths.js +83 -0
- package/dist/config/validateCatalog.d.ts +22 -4
- package/dist/config/validateCatalog.js +169 -132
- package/dist/envelope/check.js +7 -0
- package/dist/envelope/forkChoice.d.ts +3 -0
- package/dist/envelope/forkChoice.js +47 -0
- package/dist/index.d.ts +4 -0
- package/dist/index.js +4 -0
- package/dist/mcp/projectRun.d.ts +3 -0
- package/dist/mcp/projectRun.js +7 -0
- package/dist/mcp/server.js +1 -1
- package/dist/mcp/tools.js +28 -11
- package/dist/project/findProjectRoot.d.ts +2 -0
- package/dist/project/findProjectRoot.js +51 -0
- package/dist/project/globalHome.d.ts +2 -0
- package/dist/project/globalHome.js +19 -0
- package/dist/project/resolveProjectContext.d.ts +9 -0
- package/dist/project/resolveProjectContext.js +38 -0
- package/dist/project/resolveStageflowContext.d.ts +11 -0
- package/dist/project/resolveStageflowContext.js +66 -0
- package/dist/runstore/normalizeCatalogPath.d.ts +1 -0
- package/dist/runstore/normalizeCatalogPath.js +4 -0
- package/dist/runstore/port.d.ts +15 -0
- package/dist/runstore/runProjection.js +11 -1
- package/dist/runstore/sqlite/SqliteRunStore.js +46 -4
- package/dist/runstore/sqlite/schema.d.ts +1 -1
- package/dist/runstore/sqlite/schema.js +7 -1
- package/dist/runtime/credentialBinding.d.ts +8 -6
- package/dist/runtime/credentialBinding.js +18 -24
- package/dist/runtime/pipelineRunner.d.ts +11 -0
- package/dist/runtime/pipelineRunner.js +25 -1
- package/dist/runtime/pipelineScheduler.d.ts +3 -0
- package/dist/runtime/pipelineScheduler.js +70 -14
- package/dist/runtime/reloadRunCatalog.d.ts +5 -0
- package/dist/runtime/reloadRunCatalog.js +44 -0
- package/dist/runtime/resumeReconstruct.d.ts +1 -0
- package/dist/runtime/resumeReconstruct.js +27 -10
- package/dist/runtime/runManager.d.ts +8 -0
- package/dist/runtime/runManager.js +49 -18
- package/dist/runtime/settingsFile.d.ts +12 -0
- package/dist/runtime/settingsFile.js +87 -6
- package/dist/runtime/stageAttemptBootstrap.js +3 -0
- package/dist/runtime/stageProcessLauncher.d.ts +1 -0
- package/dist/runtime/stageProcessLauncher.js +6 -0
- package/dist/runtime/stageRecovery.js +3 -1
- package/dist/runtime/stageRunner.d.ts +2 -0
- package/dist/runtime/stageRunner.js +9 -2
- package/dist/runtime/stageWorker.js +4 -6
- package/dist/runtime/stageWorkerProtocol.d.ts +1 -0
- package/dist/server/http.js +33 -9
- package/dist/tools/emitStageEnvelope.d.ts +3 -1
- package/dist/tools/emitStageEnvelope.js +11 -1
- package/dist/types/envelope.d.ts +1 -0
- package/dist/types/forkChoice.d.ts +8 -0
- package/dist/types/forkChoice.js +1 -0
- package/dist/types/pipeline.d.ts +51 -2
- package/dist/types/stageflowManifest.d.ts +23 -0
- package/dist/types/stageflowManifest.js +1 -0
- package/dist/ui/assets/index-CFSzDZje.js +118 -0
- package/dist/ui/assets/{index-DCsDopak.css → index-DefBlEvN.css} +1 -1
- package/dist/ui/index.html +3 -2
- package/dist/ui/stageflow-icon.svg +12 -0
- package/package.json +7 -5
- package/dist/agent/cursorExtension.d.ts +0 -12
- package/dist/agent/cursorExtension.js +0 -88
- package/dist/runstore/catalog.d.ts +0 -8
- package/dist/runstore/catalog.js +0 -16
- package/dist/runstore/disk/DiskRunStore.d.ts +0 -30
- package/dist/runstore/disk/DiskRunStore.js +0 -238
- package/dist/runstore/layout.d.ts +0 -22
- package/dist/runstore/layout.js +0 -58
- package/dist/runtime/hitlSeams.d.ts +0 -38
- package/dist/runtime/hitlSeams.js +0 -2
- package/dist/ui/assets/index-Cry0Tpfx.js +0 -118
|
@@ -43,6 +43,16 @@ export function parseCreateStageBody(body) {
|
|
|
43
43
|
if ("skill" in body) {
|
|
44
44
|
return { ok: false, status: 400, error: "skill is not supported" };
|
|
45
45
|
}
|
|
46
|
+
if (typeof body.pipeline_directory !== "string" || !body.pipeline_directory.trim()) {
|
|
47
|
+
return { ok: false, status: 400, error: "pipeline_directory is required" };
|
|
48
|
+
}
|
|
49
|
+
if (typeof body.filename !== "string" || !body.filename.trim()) {
|
|
50
|
+
return { ok: false, status: 400, error: "filename is required" };
|
|
51
|
+
}
|
|
52
|
+
const filename = body.filename.trim().replace(/\\/g, "/");
|
|
53
|
+
if (!filename.endsWith(".yaml") && !filename.endsWith(".yml")) {
|
|
54
|
+
return { ok: false, status: 400, error: "filename must end with .yaml" };
|
|
55
|
+
}
|
|
46
56
|
if (typeof body.id !== "string") {
|
|
47
57
|
return { ok: false, status: 400, error: "id is required" };
|
|
48
58
|
}
|
|
@@ -65,6 +75,8 @@ export function parseCreateStageBody(body) {
|
|
|
65
75
|
};
|
|
66
76
|
}
|
|
67
77
|
return {
|
|
78
|
+
pipeline_directory: body.pipeline_directory.trim().replace(/\\/g, "/"),
|
|
79
|
+
filename,
|
|
68
80
|
id: body.id,
|
|
69
81
|
system_prompt: body.system_prompt,
|
|
70
82
|
model: body.model,
|
|
@@ -112,14 +124,21 @@ async function fileExists(filePath) {
|
|
|
112
124
|
return false;
|
|
113
125
|
}
|
|
114
126
|
}
|
|
115
|
-
|
|
127
|
+
function resolvePipelineDirectory(projectRoot, pipelineDirectory) {
|
|
128
|
+
const absDirectory = path.resolve(projectRoot, pipelineDirectory);
|
|
129
|
+
const rel = path.relative(projectRoot, absDirectory);
|
|
130
|
+
if (rel.startsWith("..") || path.isAbsolute(rel)) {
|
|
131
|
+
return null;
|
|
132
|
+
}
|
|
133
|
+
return absDirectory;
|
|
134
|
+
}
|
|
135
|
+
async function findStageIdCollision(pipelineDirectory, projectRoot, id, targetPath) {
|
|
116
136
|
if (await fileExists(targetPath)) {
|
|
117
|
-
return path.relative(
|
|
137
|
+
return path.relative(projectRoot, targetPath);
|
|
118
138
|
}
|
|
119
|
-
const dir = path.join(cwd, "stages");
|
|
120
139
|
let entries;
|
|
121
140
|
try {
|
|
122
|
-
entries = await readdir(
|
|
141
|
+
entries = await readdir(pipelineDirectory, { withFileTypes: true });
|
|
123
142
|
}
|
|
124
143
|
catch {
|
|
125
144
|
return null;
|
|
@@ -127,13 +146,13 @@ async function findStageIdCollision(cwd, id, targetPath) {
|
|
|
127
146
|
for (const entry of entries) {
|
|
128
147
|
if (!entry.isFile() || !entry.name.endsWith(".yaml"))
|
|
129
148
|
continue;
|
|
130
|
-
const filePath = path.join(
|
|
149
|
+
const filePath = path.join(pipelineDirectory, entry.name);
|
|
131
150
|
if (filePath === targetPath)
|
|
132
151
|
continue;
|
|
133
152
|
try {
|
|
134
153
|
const raw = await readYamlObject(filePath);
|
|
135
154
|
if (raw?.id === id) {
|
|
136
|
-
return path.relative(
|
|
155
|
+
return path.relative(projectRoot, filePath);
|
|
137
156
|
}
|
|
138
157
|
}
|
|
139
158
|
catch {
|
|
@@ -142,11 +161,18 @@ async function findStageIdCollision(cwd, id, targetPath) {
|
|
|
142
161
|
}
|
|
143
162
|
return null;
|
|
144
163
|
}
|
|
145
|
-
export async function createStage(
|
|
146
|
-
const
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
164
|
+
export async function createStage(projectRoot, input) {
|
|
165
|
+
const pipelineDirectory = resolvePipelineDirectory(projectRoot, input.pipeline_directory);
|
|
166
|
+
if (!pipelineDirectory) {
|
|
167
|
+
return {
|
|
168
|
+
ok: false,
|
|
169
|
+
status: 400,
|
|
170
|
+
error: "pipeline_directory must be inside the project root",
|
|
171
|
+
};
|
|
172
|
+
}
|
|
173
|
+
const filePath = path.join(pipelineDirectory, path.basename(input.filename));
|
|
174
|
+
const relPath = path.relative(projectRoot, filePath).replace(/\\/g, "/");
|
|
175
|
+
const collision = await findStageIdCollision(pipelineDirectory, projectRoot, input.id, filePath);
|
|
150
176
|
if (collision) {
|
|
151
177
|
return {
|
|
152
178
|
ok: false,
|
|
@@ -155,8 +181,13 @@ export async function createStage(cwd, input) {
|
|
|
155
181
|
};
|
|
156
182
|
}
|
|
157
183
|
try {
|
|
158
|
-
await mkdir(
|
|
159
|
-
await writeFile(filePath, stageConfigToYaml(
|
|
184
|
+
await mkdir(pipelineDirectory, { recursive: true });
|
|
185
|
+
await writeFile(filePath, stageConfigToYaml({
|
|
186
|
+
id: input.id,
|
|
187
|
+
system_prompt: input.system_prompt,
|
|
188
|
+
model: input.model,
|
|
189
|
+
...(input.gate_kinds ? { gate_kinds: input.gate_kinds } : {}),
|
|
190
|
+
}), "utf8");
|
|
160
191
|
}
|
|
161
192
|
catch (err) {
|
|
162
193
|
const message = err instanceof Error ? err.message : String(err);
|
|
@@ -169,7 +200,6 @@ export async function createStage(cwd, input) {
|
|
|
169
200
|
stage: {
|
|
170
201
|
path: relPath,
|
|
171
202
|
id: stage.id,
|
|
172
|
-
used_by_pipeline_ids: [],
|
|
173
203
|
...(stage.gate_kinds ? { gate_kinds: stage.gate_kinds } : {}),
|
|
174
204
|
},
|
|
175
205
|
};
|
|
@@ -1,18 +1,9 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
};
|
|
7
|
-
export type PipelineStageListing = {
|
|
8
|
-
id: string;
|
|
9
|
-
gate_kinds?: StageGateKind[];
|
|
10
|
-
};
|
|
11
|
-
export type PipelineListing = {
|
|
12
|
-
path: string;
|
|
13
|
-
id: string;
|
|
14
|
-
stages: PipelineStageListing[];
|
|
15
|
-
};
|
|
1
|
+
import type { StageGateKind } from "../types/stage.js";
|
|
2
|
+
import type { LoadedManifest } from "../types/stageflowManifest.js";
|
|
3
|
+
import { type PipelineListing, type TaskListing } from "./browseCatalog.js";
|
|
4
|
+
import { type StageflowContext } from "../project/resolveStageflowContext.js";
|
|
5
|
+
import { type CatalogContext } from "./resolveCatalogContext.js";
|
|
6
|
+
export type { PipelineListing, PipelineStageListing, TaskListing } from "./browseCatalog.js";
|
|
16
7
|
export type ValidStageListing = {
|
|
17
8
|
path: string;
|
|
18
9
|
id: string;
|
|
@@ -27,7 +18,11 @@ export type BrokenStageListing = {
|
|
|
27
18
|
gate_kinds?: StageGateKind[];
|
|
28
19
|
};
|
|
29
20
|
export type StageListing = ValidStageListing | BrokenStageListing;
|
|
30
|
-
export
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
21
|
+
export type CatalogListOptions = {
|
|
22
|
+
projectRoot: string;
|
|
23
|
+
manifest: LoadedManifest;
|
|
24
|
+
};
|
|
25
|
+
export declare function listTasks(options: CatalogListOptions): Promise<TaskListing[]>;
|
|
26
|
+
export declare function listPipelines(options: CatalogListOptions): Promise<PipelineListing[]>;
|
|
27
|
+
export declare function listStages(_options?: unknown): Promise<StageListing[]>;
|
|
28
|
+
export declare function listModels(cwdOrContext: string | CatalogContext | StageflowContext): Promise<string[]>;
|
|
@@ -1,195 +1,30 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import
|
|
3
|
-
import {
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
"cursor/auto",
|
|
12
|
-
"cursor/composer-2-5",
|
|
13
|
-
];
|
|
14
|
-
function parseSafeGateKinds(raw) {
|
|
15
|
-
if (!Array.isArray(raw) || !raw.every((item) => typeof item === "string")) {
|
|
16
|
-
return undefined;
|
|
17
|
-
}
|
|
18
|
-
const allowed = new Set(STAGE_GATE_KINDS);
|
|
19
|
-
const gateKinds = raw.filter((item) => allowed.has(item));
|
|
20
|
-
return gateKinds.length > 0 ? gateKinds : undefined;
|
|
1
|
+
import { listModelsForContext, listPipelinesForContext, listTasksForContext, } from "./browseCatalog.js";
|
|
2
|
+
import { resolveStageflowContext } from "../project/resolveStageflowContext.js";
|
|
3
|
+
import { catalogContextFromStageflow } from "./resolveCatalogContext.js";
|
|
4
|
+
export async function listTasks(options) {
|
|
5
|
+
return listTasksForContext({
|
|
6
|
+
projectRoot: options.projectRoot,
|
|
7
|
+
manifest: options.manifest,
|
|
8
|
+
manifestStatus: "ok",
|
|
9
|
+
issues: [],
|
|
10
|
+
});
|
|
21
11
|
}
|
|
22
|
-
async function
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
return new Map();
|
|
30
|
-
}
|
|
31
|
-
const usage = new Map();
|
|
32
|
-
for (const entry of entries) {
|
|
33
|
-
if (!entry.isFile() || !entry.name.endsWith(".yaml"))
|
|
34
|
-
continue;
|
|
35
|
-
const filePath = path.join(dir, entry.name);
|
|
36
|
-
try {
|
|
37
|
-
const raw = await readYamlObject(filePath);
|
|
38
|
-
if (typeof raw?.id !== "string" || !Array.isArray(raw.stages))
|
|
39
|
-
continue;
|
|
40
|
-
const stageIds = extractPipelineStageIds(raw.stages);
|
|
41
|
-
if (!stageIds)
|
|
42
|
-
continue;
|
|
43
|
-
for (const stageId of stageIds) {
|
|
44
|
-
let pipelineIds = usage.get(stageId);
|
|
45
|
-
if (!pipelineIds) {
|
|
46
|
-
pipelineIds = new Set();
|
|
47
|
-
usage.set(stageId, pipelineIds);
|
|
48
|
-
}
|
|
49
|
-
pipelineIds.add(raw.id);
|
|
50
|
-
}
|
|
51
|
-
}
|
|
52
|
-
catch {
|
|
53
|
-
// skip invalid pipeline files
|
|
54
|
-
}
|
|
55
|
-
}
|
|
56
|
-
return usage;
|
|
12
|
+
export async function listPipelines(options) {
|
|
13
|
+
return listPipelinesForContext({
|
|
14
|
+
projectRoot: options.projectRoot,
|
|
15
|
+
manifest: options.manifest,
|
|
16
|
+
manifestStatus: "ok",
|
|
17
|
+
issues: [],
|
|
18
|
+
});
|
|
57
19
|
}
|
|
58
|
-
export async function
|
|
59
|
-
|
|
60
|
-
let entries;
|
|
61
|
-
try {
|
|
62
|
-
entries = await readdir(dir, { withFileTypes: true });
|
|
63
|
-
}
|
|
64
|
-
catch {
|
|
65
|
-
return [];
|
|
66
|
-
}
|
|
67
|
-
const listings = [];
|
|
68
|
-
for (const entry of entries) {
|
|
69
|
-
if (!entry.isFile() || !entry.name.endsWith(".yaml"))
|
|
70
|
-
continue;
|
|
71
|
-
const filePath = path.join(dir, entry.name);
|
|
72
|
-
try {
|
|
73
|
-
const task = await loadTask(filePath);
|
|
74
|
-
listings.push({
|
|
75
|
-
path: path.relative(cwd, filePath),
|
|
76
|
-
id: task.id,
|
|
77
|
-
goal: task.goal,
|
|
78
|
-
});
|
|
79
|
-
}
|
|
80
|
-
catch {
|
|
81
|
-
// skip invalid
|
|
82
|
-
}
|
|
83
|
-
}
|
|
84
|
-
listings.sort((a, b) => a.id.localeCompare(b.id));
|
|
85
|
-
return listings;
|
|
20
|
+
export async function listStages(_options) {
|
|
21
|
+
return [];
|
|
86
22
|
}
|
|
87
|
-
export async function
|
|
88
|
-
const
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
return [];
|
|
95
|
-
}
|
|
96
|
-
const listings = [];
|
|
97
|
-
for (const entry of entries) {
|
|
98
|
-
if (!entry.isFile() || !entry.name.endsWith(".yaml"))
|
|
99
|
-
continue;
|
|
100
|
-
const filePath = path.join(dir, entry.name);
|
|
101
|
-
try {
|
|
102
|
-
const loaded = await loadPipeline(filePath, { cwd });
|
|
103
|
-
listings.push({
|
|
104
|
-
path: path.relative(cwd, filePath),
|
|
105
|
-
id: loaded.pipeline.id,
|
|
106
|
-
stages: loaded.stages.map((stage) => ({
|
|
107
|
-
id: stage.id,
|
|
108
|
-
...(stage.gate_kinds ? { gate_kinds: stage.gate_kinds } : {}),
|
|
109
|
-
})),
|
|
110
|
-
});
|
|
111
|
-
}
|
|
112
|
-
catch {
|
|
113
|
-
// skip invalid
|
|
114
|
-
}
|
|
115
|
-
}
|
|
116
|
-
listings.sort((a, b) => a.id.localeCompare(b.id));
|
|
117
|
-
return listings;
|
|
118
|
-
}
|
|
119
|
-
export async function listStages(cwd) {
|
|
120
|
-
const dir = path.join(cwd, "stages");
|
|
121
|
-
let entries;
|
|
122
|
-
try {
|
|
123
|
-
entries = await readdir(dir, { withFileTypes: true });
|
|
124
|
-
}
|
|
125
|
-
catch {
|
|
126
|
-
return [];
|
|
127
|
-
}
|
|
128
|
-
const usageByStage = await listPipelineUsageByStage(cwd);
|
|
129
|
-
const valid = [];
|
|
130
|
-
const broken = [];
|
|
131
|
-
for (const entry of entries) {
|
|
132
|
-
if (!entry.isFile() || !entry.name.endsWith(".yaml"))
|
|
133
|
-
continue;
|
|
134
|
-
const filePath = path.join(dir, entry.name);
|
|
135
|
-
const relPath = path.relative(cwd, filePath);
|
|
136
|
-
try {
|
|
137
|
-
const stage = await loadStage(filePath);
|
|
138
|
-
valid.push({
|
|
139
|
-
path: relPath,
|
|
140
|
-
id: stage.id,
|
|
141
|
-
used_by_pipeline_ids: [...(usageByStage.get(stage.id) ?? new Set())].sort(),
|
|
142
|
-
...(stage.gate_kinds ? { gate_kinds: stage.gate_kinds } : {}),
|
|
143
|
-
});
|
|
144
|
-
}
|
|
145
|
-
catch (err) {
|
|
146
|
-
const message = err instanceof Error ? err.message : String(err);
|
|
147
|
-
const brokenRow = {
|
|
148
|
-
path: relPath,
|
|
149
|
-
error: message,
|
|
150
|
-
};
|
|
151
|
-
try {
|
|
152
|
-
const raw = await readYamlObject(filePath);
|
|
153
|
-
if (typeof raw?.id === "string")
|
|
154
|
-
brokenRow.id = raw.id;
|
|
155
|
-
if (typeof raw?.model === "string")
|
|
156
|
-
brokenRow.model = raw.model;
|
|
157
|
-
const gateKinds = parseSafeGateKinds(raw?.gate_kinds);
|
|
158
|
-
if (gateKinds)
|
|
159
|
-
brokenRow.gate_kinds = gateKinds;
|
|
160
|
-
}
|
|
161
|
-
catch {
|
|
162
|
-
// keep path + error only when parsing itself fails
|
|
163
|
-
}
|
|
164
|
-
broken.push(brokenRow);
|
|
165
|
-
}
|
|
166
|
-
}
|
|
167
|
-
valid.sort((a, b) => a.id.localeCompare(b.id));
|
|
168
|
-
broken.sort((a, b) => a.path.localeCompare(b.path));
|
|
169
|
-
return [...valid, ...broken];
|
|
170
|
-
}
|
|
171
|
-
export async function listModels(cwd) {
|
|
172
|
-
const dir = path.join(cwd, "stages");
|
|
173
|
-
const models = new Set(BAKED_MODEL_IDS);
|
|
174
|
-
let entries;
|
|
175
|
-
try {
|
|
176
|
-
entries = await readdir(dir, { withFileTypes: true });
|
|
177
|
-
}
|
|
178
|
-
catch {
|
|
179
|
-
return [...models].sort((a, b) => a.localeCompare(b));
|
|
180
|
-
}
|
|
181
|
-
for (const entry of entries) {
|
|
182
|
-
if (!entry.isFile() || !entry.name.endsWith(".yaml"))
|
|
183
|
-
continue;
|
|
184
|
-
try {
|
|
185
|
-
const raw = await readYamlObject(path.join(dir, entry.name));
|
|
186
|
-
if (typeof raw?.model === "string" && raw.model.trim()) {
|
|
187
|
-
models.add(raw.model);
|
|
188
|
-
}
|
|
189
|
-
}
|
|
190
|
-
catch {
|
|
191
|
-
// ignore unreadable or invalid stage YAML
|
|
192
|
-
}
|
|
193
|
-
}
|
|
194
|
-
return [...models].sort((a, b) => a.localeCompare(b));
|
|
23
|
+
export async function listModels(cwdOrContext) {
|
|
24
|
+
const ctx = typeof cwdOrContext === "string"
|
|
25
|
+
? catalogContextFromStageflow(await resolveStageflowContext(cwdOrContext))
|
|
26
|
+
: "manifestIssues" in cwdOrContext
|
|
27
|
+
? catalogContextFromStageflow(cwdOrContext)
|
|
28
|
+
: cwdOrContext;
|
|
29
|
+
return listModelsForContext(ctx);
|
|
195
30
|
}
|
|
@@ -1,25 +1,11 @@
|
|
|
1
1
|
import type { LoadedPipeline } from "../types/pipeline.js";
|
|
2
2
|
import { type LoadOutcome } from "./loadOutcome.js";
|
|
3
|
-
import type { ValidationFinding } from "./validateCatalog.js";
|
|
4
3
|
export type { LoadedPipeline } from "../types/pipeline.js";
|
|
5
4
|
export type { LoadIssue, LoadOutcome } from "./loadOutcome.js";
|
|
6
|
-
export
|
|
7
|
-
ok: true;
|
|
8
|
-
loaded: LoadedPipeline;
|
|
9
|
-
} | {
|
|
10
|
-
ok: false;
|
|
11
|
-
findings: ValidationFinding[];
|
|
12
|
-
};
|
|
5
|
+
export declare function resolvePipelinePath(pipelinePath: string, cwd: string): Promise<string>;
|
|
13
6
|
export declare function loadPipelineOutcome(nameOrPath: string, options?: {
|
|
14
7
|
cwd?: string;
|
|
15
|
-
stagesDir?: string;
|
|
16
8
|
}): Promise<LoadOutcome<LoadedPipeline>>;
|
|
17
|
-
export declare function loadPipelineValidated(nameOrPath: string, options?: {
|
|
18
|
-
cwd?: string;
|
|
19
|
-
stagesDir?: string;
|
|
20
|
-
validateStages?: boolean;
|
|
21
|
-
}): Promise<LoadPipelineValidatedResult>;
|
|
22
9
|
export declare function loadPipeline(nameOrPath: string, options?: {
|
|
23
10
|
cwd?: string;
|
|
24
|
-
stagesDir?: string;
|
|
25
11
|
}): Promise<LoadedPipeline>;
|