stageflow 0.2.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.
Files changed (113) hide show
  1. package/README.md +158 -14
  2. package/dist/agent/activity.d.ts +10 -1
  3. package/dist/agent/activity.js +37 -2
  4. package/dist/agent/activityObserver.d.ts +5 -1
  5. package/dist/agent/activityObserver.js +174 -11
  6. package/dist/agent/fakeAgent.js +4 -0
  7. package/dist/agent/piAdapter.d.ts +16 -0
  8. package/dist/agent/piAdapter.js +88 -21
  9. package/dist/agent/port.d.ts +2 -0
  10. package/dist/agent/providerAuth.js +12 -7
  11. package/dist/catalog/displayCatalogPath.d.ts +12 -0
  12. package/dist/catalog/displayCatalogPath.js +28 -0
  13. package/dist/cli/initCommand.d.ts +9 -0
  14. package/dist/cli/initCommand.js +71 -0
  15. package/dist/cli/initTemplates.d.ts +3 -0
  16. package/dist/cli/initTemplates.js +19 -0
  17. package/dist/cli/operatorCatalog.d.ts +10 -0
  18. package/dist/cli/operatorCatalog.js +16 -0
  19. package/dist/cli/runCommand.d.ts +3 -1
  20. package/dist/cli/runCommand.js +48 -7
  21. package/dist/cli/validateCommand.d.ts +1 -1
  22. package/dist/cli/validateCommand.js +20 -3
  23. package/dist/cli.d.ts +1 -0
  24. package/dist/cli.js +52 -19
  25. package/dist/config/browseCatalog.d.ts +45 -0
  26. package/dist/config/browseCatalog.js +170 -0
  27. package/dist/config/createPipeline.d.ts +12 -3
  28. package/dist/config/createPipeline.js +292 -100
  29. package/dist/config/createStage.d.ts +10 -4
  30. package/dist/config/createStage.js +44 -14
  31. package/dist/config/listConfig.d.ts +14 -19
  32. package/dist/config/listConfig.js +26 -191
  33. package/dist/config/listModelsFromManifest.d.ts +2 -0
  34. package/dist/config/listModelsFromManifest.js +4 -0
  35. package/dist/config/loadOutcome.d.ts +4 -0
  36. package/dist/config/loadPipeline.d.ts +1 -15
  37. package/dist/config/loadPipeline.js +84 -142
  38. package/dist/config/loadStage.d.ts +4 -0
  39. package/dist/config/loadStage.js +60 -32
  40. package/dist/config/loadStageflowManifest.d.ts +5 -0
  41. package/dist/config/loadStageflowManifest.js +157 -0
  42. package/dist/config/mergePipelineIncludes.d.ts +9 -0
  43. package/dist/config/mergePipelineIncludes.js +141 -0
  44. package/dist/config/normalizePipelineStageEntry.d.ts +16 -0
  45. package/dist/config/normalizePipelineStageEntry.js +186 -0
  46. package/dist/config/pipelineStageKeys.d.ts +4 -0
  47. package/dist/config/pipelineStageKeys.js +14 -0
  48. package/dist/config/resolveCatalogContext.d.ts +13 -0
  49. package/dist/config/resolveCatalogContext.js +13 -0
  50. package/dist/config/resolveForkEmitContext.d.ts +3 -0
  51. package/dist/config/resolveForkEmitContext.js +12 -0
  52. package/dist/config/resolvePipelineDag.d.ts +5 -1
  53. package/dist/config/resolvePipelineDag.js +54 -36
  54. package/dist/config/scanCatalogPaths.d.ts +4 -0
  55. package/dist/config/scanCatalogPaths.js +83 -0
  56. package/dist/config/validateCatalog.d.ts +22 -4
  57. package/dist/config/validateCatalog.js +169 -132
  58. package/dist/envelope/check.js +7 -0
  59. package/dist/envelope/forkChoice.d.ts +3 -0
  60. package/dist/envelope/forkChoice.js +47 -0
  61. package/dist/index.d.ts +4 -0
  62. package/dist/index.js +4 -0
  63. package/dist/mcp/projectRun.d.ts +3 -0
  64. package/dist/mcp/projectRun.js +7 -0
  65. package/dist/mcp/tools.js +28 -11
  66. package/dist/project/findProjectRoot.d.ts +2 -0
  67. package/dist/project/findProjectRoot.js +51 -0
  68. package/dist/project/globalHome.d.ts +2 -0
  69. package/dist/project/globalHome.js +19 -0
  70. package/dist/project/resolveProjectContext.d.ts +9 -0
  71. package/dist/project/resolveProjectContext.js +38 -0
  72. package/dist/project/resolveStageflowContext.d.ts +11 -0
  73. package/dist/project/resolveStageflowContext.js +66 -0
  74. package/dist/runstore/normalizeCatalogPath.d.ts +1 -0
  75. package/dist/runstore/normalizeCatalogPath.js +4 -0
  76. package/dist/runstore/port.d.ts +9 -0
  77. package/dist/runstore/runProjection.js +11 -1
  78. package/dist/runstore/sqlite/SqliteRunStore.js +30 -4
  79. package/dist/runstore/sqlite/schema.d.ts +1 -1
  80. package/dist/runstore/sqlite/schema.js +4 -1
  81. package/dist/runtime/credentialBinding.d.ts +8 -6
  82. package/dist/runtime/credentialBinding.js +18 -24
  83. package/dist/runtime/pipelineRunner.d.ts +3 -0
  84. package/dist/runtime/pipelineRunner.js +15 -1
  85. package/dist/runtime/pipelineScheduler.d.ts +2 -0
  86. package/dist/runtime/pipelineScheduler.js +51 -11
  87. package/dist/runtime/reloadRunCatalog.d.ts +5 -0
  88. package/dist/runtime/reloadRunCatalog.js +44 -0
  89. package/dist/runtime/resumeReconstruct.d.ts +1 -0
  90. package/dist/runtime/resumeReconstruct.js +23 -7
  91. package/dist/runtime/runManager.d.ts +4 -0
  92. package/dist/runtime/runManager.js +36 -16
  93. package/dist/runtime/settingsFile.d.ts +12 -0
  94. package/dist/runtime/settingsFile.js +87 -6
  95. package/dist/runtime/stageAttemptBootstrap.js +3 -0
  96. package/dist/runtime/stageProcessLauncher.js +3 -0
  97. package/dist/runtime/stageRecovery.js +3 -1
  98. package/dist/runtime/stageWorker.js +2 -6
  99. package/dist/server/http.js +33 -9
  100. package/dist/tools/emitStageEnvelope.d.ts +3 -1
  101. package/dist/tools/emitStageEnvelope.js +11 -1
  102. package/dist/types/envelope.d.ts +1 -0
  103. package/dist/types/forkChoice.d.ts +8 -0
  104. package/dist/types/forkChoice.js +1 -0
  105. package/dist/types/pipeline.d.ts +51 -2
  106. package/dist/types/stageflowManifest.d.ts +23 -0
  107. package/dist/types/stageflowManifest.js +1 -0
  108. package/dist/ui/assets/index-CFSzDZje.js +118 -0
  109. package/dist/ui/assets/{index-DCsDopak.css → index-DefBlEvN.css} +1 -1
  110. package/dist/ui/index.html +3 -2
  111. package/dist/ui/stageflow-icon.svg +12 -0
  112. package/package.json +7 -5
  113. package/dist/ui/assets/index-Cry0Tpfx.js +0 -118
package/dist/cli.js CHANGED
@@ -4,16 +4,20 @@ import { realpathSync } from "node:fs";
4
4
  import path from "node:path";
5
5
  import { fileURLToPath } from "node:url";
6
6
  import { PiAgentAdapter } from "./agent/piAdapter.js";
7
+ import { INIT_USAGE, runInitCommand } from "./cli/initCommand.js";
7
8
  import { PROVIDERS_USAGE, runProvidersCommand } from "./cli/providersCommand.js";
8
9
  import { RUN_USAGE, runRunCommand } from "./cli/runCommand.js";
10
+ import { resolveOperatorCatalog } from "./cli/operatorCatalog.js";
9
11
  import { VALIDATE_USAGE, runValidateCommand } from "./cli/validateCommand.js";
10
12
  import { createRunStore } from "./runstore/createStore.js";
13
+ import { resolveStageflowContext } from "./project/resolveStageflowContext.js";
11
14
  import { exitForOutcome, runStageWorker } from "./runtime/stageWorker.js";
12
15
  import { SF_STAGE_WORKER } from "./runtime/stageWorkerProtocol.js";
13
16
  import { DEFAULT_PORT, startUiServer } from "./server/http.js";
14
17
  const USAGE = `Usage:
15
- sf run --task <path> --pipeline <name-or-path> [--checkout <path>] [--json] [--skip-gates] [--git-sha <sha>] [--ci-pr-url <url>] [--ci-job-url <url>]
16
- sf validate [--pipeline <name-or-path>] [--strict] [--json]
18
+ sf init
19
+ sf run --task <path> --pipeline <path> [--checkout <path>] [--json] [--skip-gates] [--git-sha <sha>] [--ci-pr-url <url>] [--ci-job-url <url>] [--operator-cwd <path>] [--operator-agent-dir <path>]
20
+ sf validate [--pipeline <path>] [--task <path>] [--strict] [--json]
17
21
  sf ui [--port ${DEFAULT_PORT}]
18
22
  sf providers list
19
23
  sf providers status [--provider <id>]
@@ -27,6 +31,8 @@ Stageflow (sf) runs YAML-defined automatic stage pipelines.
27
31
 
28
32
  Store backend: SF_STORE=sqlite only. SF_STORE=disk is rejected; disk-era .stageflow/runs trees import when the SQLite store is empty. Data under .stageflow/.
29
33
 
34
+ ${INIT_USAGE}
35
+
30
36
  ${RUN_USAGE}
31
37
 
32
38
  ${VALIDATE_USAGE}
@@ -44,7 +50,8 @@ function parseArgs(argv) {
44
50
  const command = args[0];
45
51
  if (command === "providers" ||
46
52
  command === "validate" ||
47
- command === "run") {
53
+ command === "run" ||
54
+ command === "init") {
48
55
  return { help: false, command };
49
56
  }
50
57
  if (args.includes("--help") || args.includes("-h")) {
@@ -85,6 +92,7 @@ export function parseRunStageArgs(argv) {
85
92
  let resumeAnswer;
86
93
  let attempt;
87
94
  let sessionFilePath;
95
+ let operatorCwd;
88
96
  let operatorAgentDir;
89
97
  let skipGates = false;
90
98
  for (let i = 0; i < argv.length; i++) {
@@ -130,6 +138,12 @@ export function parseRunStageArgs(argv) {
130
138
  throw new Error("Missing value for --session-file");
131
139
  }
132
140
  }
141
+ else if (argv[i] === "--operator-cwd") {
142
+ operatorCwd = argv[++i];
143
+ if (operatorCwd === undefined) {
144
+ throw new Error("Missing value for --operator-cwd");
145
+ }
146
+ }
133
147
  else if (argv[i] === "--operator-agent-dir") {
134
148
  operatorAgentDir = argv[++i];
135
149
  if (operatorAgentDir === undefined) {
@@ -143,6 +157,11 @@ export function parseRunStageArgs(argv) {
143
157
  if (!runId || !stageId) {
144
158
  throw new Error("Missing --run-id and/or --stage-id");
145
159
  }
160
+ const operatorCatalog = resolveOperatorCatalog({
161
+ flags: { operatorCwd, operatorAgentDir },
162
+ env: process.env,
163
+ defaultCwd: process.cwd(),
164
+ });
146
165
  return {
147
166
  runId,
148
167
  stageId,
@@ -151,9 +170,7 @@ export function parseRunStageArgs(argv) {
151
170
  attempt,
152
171
  sessionFilePath,
153
172
  skipGates,
154
- ...(operatorAgentDir !== undefined
155
- ? { operatorCatalog: { cwd: process.cwd(), agentDir: operatorAgentDir } }
156
- : {}),
173
+ operatorCatalog,
157
174
  };
158
175
  }
159
176
  async function handleInternalRunStage(argv) {
@@ -194,21 +211,30 @@ async function main(argv) {
194
211
  console.log(USAGE);
195
212
  return argv.slice(2).length === 0 ? 1 : 0;
196
213
  }
197
- const rootDir = process.cwd();
214
+ const ctx = await resolveStageflowContext(process.cwd());
215
+ if (parsed.command === "init") {
216
+ return runInitCommand(argv.slice(3), { cwd: ctx.invocationCwd });
217
+ }
198
218
  if (parsed.command === "validate") {
199
- return runValidateCommand(argv.slice(3), { cwd: rootDir });
219
+ return runValidateCommand(argv.slice(3), { cwd: ctx.invocationCwd });
200
220
  }
201
221
  if (parsed.command === "run") {
202
- return runRunCommand(argv.slice(3), { cwd: rootDir });
222
+ return runRunCommand(argv.slice(3), {
223
+ cwd: ctx.invocationCwd,
224
+ projectRoot: ctx.projectRoot,
225
+ isGitProject: ctx.isGitProject,
226
+ });
203
227
  }
204
228
  if (parsed.command === "providers") {
205
- return runProvidersCommand(argv.slice(3), rootDir);
229
+ return runProvidersCommand(argv.slice(3), ctx.invocationCwd);
206
230
  }
207
- const store = createRunStore({ rootDir });
231
+ const store = createRunStore({ rootDir: ctx.projectRoot });
208
232
  if (parsed.command === "ui") {
209
233
  const { url, mcpUrl } = await startUiServer({
210
234
  agent: new PiAgentAdapter(),
211
235
  store,
236
+ cwd: ctx.invocationCwd,
237
+ rootDir: ctx.projectRoot,
212
238
  port: parsed.port,
213
239
  });
214
240
  console.log(`Operator console: ${url}`);
@@ -235,16 +261,23 @@ async function main(argv) {
235
261
  return 1;
236
262
  }
237
263
  }
264
+ function normalizeCliEntry(filePath) {
265
+ const resolved = path.resolve(filePath);
266
+ let canonical;
267
+ try {
268
+ canonical = realpathSync(resolved);
269
+ }
270
+ catch {
271
+ canonical = resolved;
272
+ }
273
+ return canonical.replace(/\.(?:[cm]?[jt]s)$/i, "");
274
+ }
275
+ export function sameCliEntry(a, b) {
276
+ return normalizeCliEntry(a) === normalizeCliEntry(b);
277
+ }
238
278
  function isDirectCliInvocation() {
239
279
  const self = fileURLToPath(import.meta.url);
240
- return process.argv.slice(1).some((arg) => {
241
- try {
242
- return realpathSync(path.resolve(arg)) === realpathSync(self);
243
- }
244
- catch {
245
- return false;
246
- }
247
- });
280
+ return process.argv.slice(1).some((arg) => sameCliEntry(arg, self));
248
281
  }
249
282
  if (isDirectCliInvocation()) {
250
283
  main(process.argv)
@@ -0,0 +1,45 @@
1
+ import type { StageGateKind } from "../types/stage.js";
2
+ import type { LoadedManifest } from "../types/stageflowManifest.js";
3
+ import type { LoadIssue } from "./loadOutcome.js";
4
+ import type { CatalogContext } from "./resolveCatalogContext.js";
5
+ import { type CatalogManifestStatus, type StageflowContext } from "../project/resolveStageflowContext.js";
6
+ export type TaskListing = {
7
+ path: string;
8
+ id: string;
9
+ goal: string;
10
+ };
11
+ export type PipelineStageListing = {
12
+ id: string;
13
+ gate_kinds?: StageGateKind[];
14
+ uses_path?: string;
15
+ inline?: boolean;
16
+ };
17
+ export type PipelineListing = {
18
+ path: string;
19
+ id: string;
20
+ stages: PipelineStageListing[];
21
+ };
22
+ export type CatalogBrowseWarning = {
23
+ path: string;
24
+ kind: "pipeline" | "task";
25
+ error: string;
26
+ };
27
+ export type CatalogBrowseResult = {
28
+ projectRoot: string | null;
29
+ manifest: LoadedManifest | null;
30
+ manifestStatus: CatalogManifestStatus;
31
+ issues: LoadIssue[];
32
+ pipelines: PipelineListing[];
33
+ tasks: TaskListing[];
34
+ models: string[];
35
+ warnings: CatalogBrowseWarning[];
36
+ };
37
+ export type CatalogScanPaths = {
38
+ pipelinePaths: string[];
39
+ taskPaths: string[];
40
+ };
41
+ export declare function getCatalogScanPaths(ctx: CatalogContext): Promise<CatalogScanPaths | null>;
42
+ export declare function browseCatalog(invocationCwd: string | StageflowContext): Promise<CatalogBrowseResult>;
43
+ export declare function listPipelinesForContext(ctx: CatalogContext): Promise<PipelineListing[]>;
44
+ export declare function listTasksForContext(ctx: CatalogContext): Promise<TaskListing[]>;
45
+ export declare function listModelsForContext(ctx: CatalogContext): Promise<string[]>;
@@ -0,0 +1,170 @@
1
+ import path from "node:path";
2
+ import { loadPipeline } from "./loadPipeline.js";
3
+ import { loadTask } from "./loadTask.js";
4
+ import { resolveStageflowContext, } from "../project/resolveStageflowContext.js";
5
+ import { scanCatalogPaths } from "./scanCatalogPaths.js";
6
+ const BAKED_MODEL_IDS = [
7
+ "anthropic/claude-sonnet-4-5",
8
+ "cursor/auto",
9
+ "cursor/composer-2-5",
10
+ ];
11
+ function repoRelPath(projectRoot, absPath) {
12
+ return path.relative(projectRoot, absPath).replace(/\\/g, "/");
13
+ }
14
+ function mapStageListing(stage, source, projectRoot) {
15
+ const listing = {
16
+ id: stage.id,
17
+ ...(stage.gate_kinds ? { gate_kinds: stage.gate_kinds } : {}),
18
+ };
19
+ if (source?.kind === "inline") {
20
+ listing.inline = true;
21
+ }
22
+ else if (source?.kind === "file") {
23
+ listing.uses_path = repoRelPath(projectRoot, source.path);
24
+ }
25
+ return listing;
26
+ }
27
+ function bakedModels() {
28
+ return [...BAKED_MODEL_IDS].sort((a, b) => a.localeCompare(b));
29
+ }
30
+ function catalogReadyFromStageflow(ctx) {
31
+ return ctx.isGitProject && ctx.manifestStatus === "ok" && ctx.manifest !== null;
32
+ }
33
+ function catalogReady(ctx) {
34
+ return ctx.manifestStatus === "ok" && ctx.projectRoot !== null && ctx.manifest !== null;
35
+ }
36
+ export async function getCatalogScanPaths(ctx) {
37
+ if (!catalogReady(ctx)) {
38
+ return null;
39
+ }
40
+ const [pipelinePaths, taskPaths] = await Promise.all([
41
+ scanCatalogPaths(ctx.manifest, "pipeline"),
42
+ scanCatalogPaths(ctx.manifest, "task"),
43
+ ]);
44
+ return { pipelinePaths, taskPaths };
45
+ }
46
+ async function listTasksFromManifest(projectRoot, manifest, warnings) {
47
+ const filePaths = await scanCatalogPaths(manifest, "task");
48
+ const listings = [];
49
+ for (const filePath of filePaths) {
50
+ try {
51
+ const task = await loadTask(filePath);
52
+ listings.push({
53
+ path: repoRelPath(projectRoot, filePath),
54
+ id: task.id,
55
+ goal: task.goal,
56
+ });
57
+ }
58
+ catch (err) {
59
+ warnings.push({
60
+ path: repoRelPath(projectRoot, filePath),
61
+ kind: "task",
62
+ error: err instanceof Error ? err.message : String(err),
63
+ });
64
+ }
65
+ }
66
+ listings.sort((a, b) => {
67
+ const pathCmp = a.path.localeCompare(b.path);
68
+ if (pathCmp !== 0)
69
+ return pathCmp;
70
+ return a.id.localeCompare(b.id);
71
+ });
72
+ return listings;
73
+ }
74
+ async function listPipelinesFromManifest(projectRoot, manifest, warnings) {
75
+ const filePaths = await scanCatalogPaths(manifest, "pipeline");
76
+ const listings = [];
77
+ for (const filePath of filePaths) {
78
+ try {
79
+ const loaded = await loadPipeline(filePath, { cwd: projectRoot });
80
+ listings.push({
81
+ path: repoRelPath(projectRoot, filePath),
82
+ id: loaded.pipeline.id,
83
+ stages: loaded.stages.map((stage) => mapStageListing(stage, loaded.stageSources?.[stage.id], projectRoot)),
84
+ });
85
+ }
86
+ catch (err) {
87
+ warnings.push({
88
+ path: repoRelPath(projectRoot, filePath),
89
+ kind: "pipeline",
90
+ error: err instanceof Error ? err.message : String(err),
91
+ });
92
+ }
93
+ }
94
+ listings.sort((a, b) => {
95
+ const pathCmp = a.path.localeCompare(b.path);
96
+ if (pathCmp !== 0)
97
+ return pathCmp;
98
+ return a.id.localeCompare(b.id);
99
+ });
100
+ return listings;
101
+ }
102
+ async function listModelsFromManifest(projectRoot, manifest) {
103
+ const models = new Set(BAKED_MODEL_IDS);
104
+ const filePaths = await scanCatalogPaths(manifest, "pipeline");
105
+ for (const filePath of filePaths) {
106
+ try {
107
+ const loaded = await loadPipeline(filePath, { cwd: projectRoot });
108
+ for (const stage of loaded.stages) {
109
+ if (stage.model.trim()) {
110
+ models.add(stage.model);
111
+ }
112
+ }
113
+ }
114
+ catch {
115
+ // skip invalid pipelines
116
+ }
117
+ }
118
+ return [...models].sort((a, b) => a.localeCompare(b));
119
+ }
120
+ export async function browseCatalog(invocationCwd) {
121
+ const ctx = typeof invocationCwd === "string"
122
+ ? await resolveStageflowContext(invocationCwd)
123
+ : invocationCwd;
124
+ const base = {
125
+ projectRoot: ctx.isGitProject ? ctx.projectRoot : null,
126
+ manifest: ctx.manifest,
127
+ manifestStatus: ctx.manifestStatus,
128
+ issues: ctx.manifestIssues,
129
+ };
130
+ if (!catalogReadyFromStageflow(ctx)) {
131
+ return {
132
+ ...base,
133
+ pipelines: [],
134
+ tasks: [],
135
+ models: bakedModels(),
136
+ warnings: [],
137
+ };
138
+ }
139
+ const warnings = [];
140
+ const [pipelines, tasks, models] = await Promise.all([
141
+ listPipelinesFromManifest(ctx.projectRoot, ctx.manifest, warnings),
142
+ listTasksFromManifest(ctx.projectRoot, ctx.manifest, warnings),
143
+ listModelsFromManifest(ctx.projectRoot, ctx.manifest),
144
+ ]);
145
+ return {
146
+ ...base,
147
+ pipelines,
148
+ tasks,
149
+ models,
150
+ warnings,
151
+ };
152
+ }
153
+ export async function listPipelinesForContext(ctx) {
154
+ if (!catalogReady(ctx)) {
155
+ return [];
156
+ }
157
+ return listPipelinesFromManifest(ctx.projectRoot, ctx.manifest, []);
158
+ }
159
+ export async function listTasksForContext(ctx) {
160
+ if (!catalogReady(ctx)) {
161
+ return [];
162
+ }
163
+ return listTasksFromManifest(ctx.projectRoot, ctx.manifest, []);
164
+ }
165
+ export async function listModelsForContext(ctx) {
166
+ if (!catalogReady(ctx)) {
167
+ return bakedModels();
168
+ }
169
+ return listModelsFromManifest(ctx.projectRoot, ctx.manifest);
170
+ }
@@ -1,11 +1,20 @@
1
+ import type { StageGateKind } from "../types/stage.js";
1
2
  import type { PipelineListing } from "./listConfig.js";
3
+ export type CreatePipelineStageInline = {
4
+ system_prompt: string;
5
+ model: string;
6
+ gate_kinds?: StageGateKind[];
7
+ };
2
8
  export type CreatePipelineStageRef = {
3
9
  id: string;
4
10
  needs?: string;
11
+ uses?: string;
12
+ inline?: CreatePipelineStageInline;
5
13
  };
6
14
  export type CreatePipelineInput = {
15
+ directory: string;
7
16
  id: string;
8
- stages: CreatePipelineStageRef[] | string[];
17
+ stages: CreatePipelineStageRef[];
9
18
  };
10
19
  export type CreatePipelineParseError = {
11
20
  ok: false;
@@ -20,7 +29,7 @@ export type CreatePipelineResult = {
20
29
  status: 400 | 409 | 422 | 500;
21
30
  error: string;
22
31
  };
23
- export declare function normalizeCreatePipelineStages(stages: CreatePipelineStageRef[] | string[]): CreatePipelineStageRef[];
32
+ export declare function normalizeCreatePipelineStages(stages: CreatePipelineStageRef[]): CreatePipelineStageRef[];
24
33
  export declare function parseCreatePipelineBody(body: unknown): CreatePipelineInput | CreatePipelineParseError;
25
34
  export declare function pipelineConfigToYaml(pipeline: {
26
35
  id: string;
@@ -28,4 +37,4 @@ export declare function pipelineConfigToYaml(pipeline: {
28
37
  }, options: {
29
38
  format: "linear" | "dag";
30
39
  }): string;
31
- export declare function createPipeline(cwd: string, input: CreatePipelineInput): Promise<CreatePipelineResult>;
40
+ export declare function createPipeline(projectRoot: string, input: CreatePipelineInput): Promise<CreatePipelineResult>;