stageflow 0.27.0 → 0.30.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 +4 -0
- package/builtin-skills/browser/SKILL.md +42 -0
- package/dist/agent/claudeAdapter.js +2 -2
- package/dist/agent/cursorProvider.d.ts +2 -0
- package/dist/agent/cursorProvider.js +30 -5
- package/dist/agent/fakeAgent.d.ts +1 -0
- package/dist/agent/fakeAgent.js +13 -0
- package/dist/agent/piAdapter.d.ts +3 -24
- package/dist/agent/piAdapter.js +49 -47
- package/dist/agent/piSessionFactory.d.ts +38 -0
- package/dist/agent/piSessionFactory.js +60 -0
- package/dist/agent/port.d.ts +2 -0
- package/dist/agent/streamLogRedact.d.ts +6 -0
- package/dist/agent/streamLogRedact.js +23 -1
- package/dist/browser/anchor.d.ts +27 -0
- package/dist/browser/anchor.js +127 -0
- package/dist/browser/auditSink.d.ts +38 -0
- package/dist/browser/auditSink.js +34 -0
- package/dist/browser/browserHost.d.ts +86 -0
- package/dist/browser/browserHost.js +7 -0
- package/dist/browser/browserSweep.d.ts +14 -0
- package/dist/browser/browserSweep.js +54 -0
- package/dist/browser/browserTeardown.d.ts +56 -0
- package/dist/browser/browserTeardown.js +235 -0
- package/dist/browser/fakeRemoteBrowserHost.d.ts +2 -0
- package/dist/browser/fakeRemoteBrowserHost.js +34 -0
- package/dist/browser/gateHandoff.d.ts +25 -0
- package/dist/browser/gateHandoff.js +83 -0
- package/dist/browser/humanLogin.d.ts +18 -0
- package/dist/browser/humanLogin.js +34 -0
- package/dist/browser/keyProvider.d.ts +10 -0
- package/dist/browser/keyProvider.js +39 -0
- package/dist/browser/localBrowserHost.d.ts +10 -0
- package/dist/browser/localBrowserHost.js +152 -0
- package/dist/browser/localProfileLock.d.ts +2 -0
- package/dist/browser/localProfileLock.js +218 -0
- package/dist/browser/localProfileStore.d.ts +5 -0
- package/dist/browser/localProfileStore.js +91 -0
- package/dist/browser/loginCheck.d.ts +53 -0
- package/dist/browser/loginCheck.js +147 -0
- package/dist/browser/memoryProfileLock.d.ts +2 -0
- package/dist/browser/memoryProfileLock.js +53 -0
- package/dist/browser/memoryProfileStore.d.ts +2 -0
- package/dist/browser/memoryProfileStore.js +31 -0
- package/dist/browser/navigationAudit.d.ts +16 -0
- package/dist/browser/navigationAudit.js +53 -0
- package/dist/browser/persistedEnv.d.ts +3 -0
- package/dist/browser/persistedEnv.js +15 -0
- package/dist/browser/profileLock.d.ts +40 -0
- package/dist/browser/profileLock.js +10 -0
- package/dist/browser/profileStore.d.ts +23 -0
- package/dist/browser/profileStore.js +39 -0
- package/dist/browser/runLiveness.d.ts +13 -0
- package/dist/browser/runLiveness.js +39 -0
- package/dist/browser/sitePolicy.d.ts +10 -0
- package/dist/browser/sitePolicy.js +61 -0
- package/dist/browser/stageBrowserEnv.d.ts +22 -0
- package/dist/browser/stageBrowserEnv.js +147 -0
- package/dist/browser/stageProfileLock.d.ts +17 -0
- package/dist/browser/stageProfileLock.js +39 -0
- package/dist/cli/browserCommand.d.ts +44 -0
- package/dist/cli/browserCommand.js +472 -0
- package/dist/cli/hostClient.d.ts +20 -0
- package/dist/cli/hostClient.js +36 -2
- package/dist/cli/initCommand.d.ts +1 -0
- package/dist/cli/initCommand.js +23 -7
- package/dist/cli/initTemplates.d.ts +5 -2
- package/dist/cli/initTemplates.js +25 -2
- package/dist/cli/runsCommand.js +6 -2
- package/dist/cli/triggerCommand.d.ts +12 -0
- package/dist/cli/triggerCommand.js +183 -0
- package/dist/cli/validateCommand.d.ts +1 -1
- package/dist/cli/validateCommand.js +23 -6
- package/dist/cli.js +31 -2
- package/dist/config/browseCatalog.d.ts +1 -0
- package/dist/config/browseCatalog.js +5 -4
- package/dist/config/builtinSkills.d.ts +4 -0
- package/dist/config/builtinSkills.js +23 -0
- package/dist/config/catalogRelativePath.d.ts +1 -0
- package/dist/config/catalogRelativePath.js +10 -2
- package/dist/config/createTrigger.d.ts +27 -0
- package/dist/config/createTrigger.js +232 -0
- package/dist/config/draftPackage.d.ts +117 -0
- package/dist/config/draftPackage.js +550 -0
- package/dist/config/ensureCatalogScanRoot.d.ts +16 -0
- package/dist/config/ensureCatalogScanRoot.js +73 -0
- package/dist/config/hostConfig.d.ts +2 -0
- package/dist/config/hostConfig.js +27 -0
- package/dist/config/listSkills.d.ts +2 -2
- package/dist/config/listSkills.js +17 -3
- package/dist/config/loadOutcome.d.ts +6 -0
- package/dist/config/loadPipeline.js +16 -0
- package/dist/config/loadStage.js +7 -0
- package/dist/config/loadStageflowManifest.js +25 -0
- package/dist/config/loadTrigger.d.ts +9 -0
- package/dist/config/loadTrigger.js +120 -0
- package/dist/config/multiProjectCatalog.d.ts +2 -0
- package/dist/config/multiProjectCatalog.js +26 -18
- package/dist/config/normalizePipelineStageEntry.js +8 -1
- package/dist/config/parseCompletionContract.js +6 -0
- package/dist/config/pipelineStageKeys.js +1 -0
- package/dist/config/publishDraftPackage.d.ts +7 -0
- package/dist/config/publishDraftPackage.js +25 -0
- package/dist/config/resolveCatalogContext.js +1 -1
- package/dist/config/resolvePipelineDag.js +1 -1
- package/dist/config/scanCatalogPaths.d.ts +1 -1
- package/dist/config/scanCatalogPaths.js +6 -2
- package/dist/config/stageBrowser.d.ts +12 -0
- package/dist/config/stageBrowser.js +118 -0
- package/dist/config/triggerCatalog.d.ts +10 -0
- package/dist/config/triggerCatalog.js +37 -0
- package/dist/config/validateCatalog.d.ts +13 -3
- package/dist/config/validateCatalog.js +83 -2
- package/dist/config/validateCompletionContract.js +8 -0
- package/dist/envelope/preEmitChecks.d.ts +1 -1
- package/dist/envelope/preEmitChecks.js +8 -0
- package/dist/logging/redact.d.ts +4 -0
- package/dist/logging/redact.js +17 -0
- package/dist/mcp/catalogTools.js +43 -8
- package/dist/mcp/controlTools.js +3 -1
- package/dist/mcp/deps.d.ts +2 -0
- package/dist/mcp/server.js +1 -0
- package/dist/mcp/tools.js +2 -0
- package/dist/mcp/triggerTools.d.ts +3 -0
- package/dist/mcp/triggerTools.js +176 -0
- package/dist/operatorAgent/docsRetrieval.d.ts +40 -0
- package/dist/operatorAgent/docsRetrieval.js +269 -0
- package/dist/operatorAgent/draftContext.d.ts +16 -0
- package/dist/operatorAgent/draftContext.js +68 -0
- package/dist/operatorAgent/fakeHost.d.ts +39 -0
- package/dist/operatorAgent/fakeHost.js +92 -0
- package/dist/operatorAgent/host.d.ts +40 -0
- package/dist/operatorAgent/host.js +179 -0
- package/dist/operatorAgent/index.d.ts +9 -0
- package/dist/operatorAgent/index.js +8 -0
- package/dist/operatorAgent/piModel.d.ts +80 -0
- package/dist/operatorAgent/piModel.js +528 -0
- package/dist/operatorAgent/profiles/workshopAuthor.d.ts +23 -0
- package/dist/operatorAgent/profiles/workshopAuthor.js +338 -0
- package/dist/operatorAgent/profiles/workshopAuthorPlaybook.d.ts +6 -0
- package/dist/operatorAgent/profiles/workshopAuthorPlaybook.js +103 -0
- package/dist/operatorAgent/profiles/workshopAuthorTools.d.ts +57 -0
- package/dist/operatorAgent/profiles/workshopAuthorTools.js +623 -0
- package/dist/operatorAgent/proposals.d.ts +32 -0
- package/dist/operatorAgent/proposals.js +144 -0
- package/dist/operatorAgent/types.d.ts +128 -0
- package/dist/operatorAgent/types.js +1 -0
- package/dist/package-meta.d.ts +1 -1
- package/dist/package-meta.js +1 -1
- package/dist/project/findManifestRoot.d.ts +3 -0
- package/dist/project/findManifestRoot.js +35 -0
- package/dist/project/resolveStageflowContext.d.ts +7 -0
- package/dist/project/resolveStageflowContext.js +44 -28
- package/dist/runstore/assertTmpdir.js +6 -2
- package/dist/runstore/port.d.ts +28 -0
- package/dist/runstore/sqlite/SqliteRunStore.d.ts +8 -1
- package/dist/runstore/sqlite/SqliteRunStore.js +90 -0
- package/dist/runstore/sqlite/migrations/008-triggers-table.d.ts +7 -0
- package/dist/runstore/sqlite/migrations/008-triggers-table.js +19 -0
- package/dist/runstore/sqlite/migrations/009-trigger-next-run.d.ts +7 -0
- package/dist/runstore/sqlite/migrations/009-trigger-next-run.js +19 -0
- package/dist/runstore/sqlite/migrations/010-trigger-adapter-state.d.ts +7 -0
- package/dist/runstore/sqlite/migrations/010-trigger-adapter-state.js +17 -0
- package/dist/runstore/sqlite/migrations/index.js +6 -0
- package/dist/runtime/answerResume.d.ts +1 -0
- package/dist/runtime/answerResume.js +3 -1
- package/dist/runtime/completionCheckRunner.d.ts +12 -1
- package/dist/runtime/completionCheckRunner.js +22 -0
- package/dist/runtime/credentialBinding.d.ts +2 -0
- package/dist/runtime/credentialBinding.js +3 -0
- package/dist/runtime/emailSource.d.ts +72 -0
- package/dist/runtime/emailSource.js +304 -0
- package/dist/runtime/githubPollSource.d.ts +86 -0
- package/dist/runtime/githubPollSource.js +284 -0
- package/dist/runtime/pipelineRunner.d.ts +4 -0
- package/dist/runtime/pipelineRunner.js +3 -0
- package/dist/runtime/pipelineScheduler.d.ts +2 -0
- package/dist/runtime/pipelineScheduler.js +85 -1
- package/dist/runtime/repositoryMaterialize.d.ts +1 -1
- package/dist/runtime/runManager.d.ts +11 -0
- package/dist/runtime/runManager.js +149 -1
- package/dist/runtime/runRetryCoordinator.d.ts +2 -0
- package/dist/runtime/runRetryCoordinator.js +1 -0
- package/dist/runtime/scheduleSource.d.ts +38 -0
- package/dist/runtime/scheduleSource.js +119 -0
- package/dist/runtime/settingsFile.d.ts +5 -0
- package/dist/runtime/settingsFile.js +61 -54
- package/dist/runtime/stageAttemptBootstrap.js +55 -3
- package/dist/runtime/stageEnvironment.js +1 -0
- package/dist/runtime/stageHitl.d.ts +1 -0
- package/dist/runtime/stageHitl.js +5 -1
- package/dist/runtime/stageProcessLauncher.d.ts +2 -0
- package/dist/runtime/stageProcessLauncher.js +44 -5
- package/dist/runtime/stageRunner.d.ts +5 -0
- package/dist/runtime/stageRunner.js +30 -6
- package/dist/runtime/stageStreamLog.d.ts +1 -0
- package/dist/runtime/stageStreamLog.js +2 -1
- package/dist/runtime/triggerCatalog.d.ts +6 -0
- package/dist/runtime/triggerCatalog.js +24 -0
- package/dist/runtime/triggerEventMatch.d.ts +2 -0
- package/dist/runtime/triggerEventMatch.js +6 -0
- package/dist/runtime/triggerPort.d.ts +14 -0
- package/dist/runtime/triggerPort.js +1 -0
- package/dist/runtime/triggerRunner.d.ts +17 -0
- package/dist/runtime/triggerRunner.js +89 -0
- package/dist/runtime/verifiedStageExecution.d.ts +7 -0
- package/dist/runtime/verifiedStageExecution.js +14 -0
- package/dist/runtime/webhookSignature.d.ts +1 -0
- package/dist/runtime/webhookSignature.js +12 -0
- package/dist/server/bootstrap.d.ts +6 -0
- package/dist/server/bootstrap.js +64 -0
- package/dist/server/controlToken.js +13 -0
- package/dist/server/createHttpHost.js +3 -0
- package/dist/server/healthSurfaces.js +31 -6
- package/dist/server/http.d.ts +15 -0
- package/dist/server/http.js +1251 -74
- package/dist/server/requestAuthContext.d.ts +1 -1
- package/dist/server/triggerRoutes.d.ts +15 -0
- package/dist/server/triggerRoutes.js +268 -0
- package/dist/tools/askOperator.d.ts +3 -2
- package/dist/types/completion.d.ts +3 -0
- package/dist/types/pipeline.d.ts +3 -1
- package/dist/types/preEmitCheck.d.ts +7 -0
- package/dist/types/stage.d.ts +14 -0
- package/dist/types/stageflowManifest.d.ts +3 -0
- package/dist/types/trigger.d.ts +18 -0
- package/dist/types/trigger.js +1 -0
- package/dist/ui/assets/{index-CSsDued1.css → index-Bv4p1aPK.css} +1 -1
- package/dist/ui/assets/index-CntB4bZR.js +133 -0
- package/dist/ui/index.html +2 -2
- package/dist/workshop/autosave.d.ts +58 -0
- package/dist/workshop/autosave.js +222 -0
- package/dist/workshop/buildStore.d.ts +79 -0
- package/dist/workshop/buildStore.js +326 -0
- package/dist/workshop/chatTurn.d.ts +232 -0
- package/dist/workshop/chatTurn.js +475 -0
- package/dist/workshop/modelSettings.d.ts +18 -0
- package/dist/workshop/modelSettings.js +44 -0
- package/dist/workshop/sessionStore.d.ts +61 -0
- package/dist/workshop/sessionStore.js +254 -0
- package/dist/workshop/workshopPin.d.ts +72 -0
- package/dist/workshop/workshopPin.js +193 -0
- package/examples/README.md +2 -1
- package/examples/browser-session/README.md +77 -0
- package/examples/browser-session/browser-session.pipeline.yaml +50 -0
- package/examples/browser-session/browser-session.task.yaml +6 -0
- package/examples/browser-session/check-login.yaml +22 -0
- package/examples/browser-session/fixture-server.mjs +64 -0
- package/examples/browser-session/human-login.yaml +31 -0
- package/examples/browser-session/merge.yaml +36 -0
- package/examples/browser-session/work-a.yaml +41 -0
- package/examples/browser-session/work-b.yaml +41 -0
- package/examples/stage-mcp/README.md +3 -2
- package/examples/stageflow.yaml +51 -0
- package/package.json +5 -1
- package/skills/stageflow/references/control-surface.md +3 -1
- package/skills/stageflow-author/references/stage-prompt-template.md +4 -4
- package/skills/stageflow-run/SKILL.md +2 -0
- package/skills/stageflow-run/references/task-and-pipeline-selection.md +3 -1
- package/skills/stageflow-setup/SKILL.md +11 -0
- package/dist/ui/assets/index-B6hlSXXn.js +0 -120
package/dist/cli/runsCommand.js
CHANGED
|
@@ -616,10 +616,14 @@ export async function runRunsCommand(args, options = {}) {
|
|
|
616
616
|
return 1;
|
|
617
617
|
}
|
|
618
618
|
if (parsed.json) {
|
|
619
|
-
printJson(out,
|
|
619
|
+
printJson(out, result.verification !== undefined
|
|
620
|
+
? { ok: true, verification: result.verification }
|
|
621
|
+
: { ok: true });
|
|
620
622
|
}
|
|
621
623
|
else {
|
|
622
|
-
out.log(
|
|
624
|
+
out.log(result.verification !== undefined
|
|
625
|
+
? `ok (${result.verification})`
|
|
626
|
+
: "ok");
|
|
623
627
|
}
|
|
624
628
|
return 0;
|
|
625
629
|
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { type EnsureGlobalServiceResult } from "../server/ensureGlobalService.js";
|
|
2
|
+
export declare const TRIGGER_USAGE = "Usage:\n sf trigger list [--json]\n sf trigger show <id> [--json]\n sf trigger fire <id> [--task-inline '<json>'] [--json]";
|
|
3
|
+
export type TriggerCommandIo = {
|
|
4
|
+
log: (line: string) => void;
|
|
5
|
+
error: (line: string) => void;
|
|
6
|
+
};
|
|
7
|
+
export declare function runTriggerCommand(args: string[], options?: {
|
|
8
|
+
cwd?: string;
|
|
9
|
+
io?: Partial<TriggerCommandIo>;
|
|
10
|
+
hostBaseUrl?: string;
|
|
11
|
+
ensureService?: () => Promise<EnsureGlobalServiceResult>;
|
|
12
|
+
}): Promise<number>;
|
|
@@ -0,0 +1,183 @@
|
|
|
1
|
+
import { completeCliRun } from "./runCommand.js";
|
|
2
|
+
import { reportCliRun, writeQueuedAdmissionLine } from "./runOutput.js";
|
|
3
|
+
import { ensureGlobalService, hostBaseUrl, } from "../server/ensureGlobalService.js";
|
|
4
|
+
import { httpFireTrigger, httpGetTrigger, httpListTriggers, } from "./hostClient.js";
|
|
5
|
+
export const TRIGGER_USAGE = `Usage:
|
|
6
|
+
sf trigger list [--json]
|
|
7
|
+
sf trigger show <id> [--json]
|
|
8
|
+
sf trigger fire <id> [--task-inline '<json>'] [--json]`;
|
|
9
|
+
const defaultIo = {
|
|
10
|
+
log: (line) => console.log(line),
|
|
11
|
+
error: (line) => console.error(line),
|
|
12
|
+
};
|
|
13
|
+
function parseTriggerArgs(args) {
|
|
14
|
+
if (args.length === 0) {
|
|
15
|
+
return { help: false, json: false };
|
|
16
|
+
}
|
|
17
|
+
if (args[0] === "--help" || args[0] === "-h") {
|
|
18
|
+
return { help: true, json: false };
|
|
19
|
+
}
|
|
20
|
+
const subcommand = args[0];
|
|
21
|
+
let help = false;
|
|
22
|
+
let json = false;
|
|
23
|
+
let id;
|
|
24
|
+
let taskInline;
|
|
25
|
+
for (let i = 1; i < args.length; i++) {
|
|
26
|
+
const arg = args[i];
|
|
27
|
+
if (arg === "--help" || arg === "-h") {
|
|
28
|
+
help = true;
|
|
29
|
+
}
|
|
30
|
+
else if (arg === "--json") {
|
|
31
|
+
json = true;
|
|
32
|
+
}
|
|
33
|
+
else if (arg === "--task-inline") {
|
|
34
|
+
const value = args[++i];
|
|
35
|
+
if (value === undefined || value.length === 0) {
|
|
36
|
+
throw new Error("Missing value for --task-inline");
|
|
37
|
+
}
|
|
38
|
+
taskInline = value;
|
|
39
|
+
}
|
|
40
|
+
else if (arg.startsWith("-")) {
|
|
41
|
+
throw new Error(`Unknown flag: ${arg}`);
|
|
42
|
+
}
|
|
43
|
+
else if (id === undefined) {
|
|
44
|
+
id = arg;
|
|
45
|
+
}
|
|
46
|
+
else {
|
|
47
|
+
throw new Error(`Unexpected argument: ${arg}`);
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
return { help, json, subcommand, id, taskInline };
|
|
51
|
+
}
|
|
52
|
+
function parseJsonFlag(raw, flagName) {
|
|
53
|
+
let parsed;
|
|
54
|
+
try {
|
|
55
|
+
parsed = JSON.parse(raw);
|
|
56
|
+
}
|
|
57
|
+
catch {
|
|
58
|
+
throw new Error(`${flagName} must be valid JSON`);
|
|
59
|
+
}
|
|
60
|
+
if (parsed === null || typeof parsed !== "object" || Array.isArray(parsed)) {
|
|
61
|
+
throw new Error(`${flagName} must be a JSON object`);
|
|
62
|
+
}
|
|
63
|
+
return parsed;
|
|
64
|
+
}
|
|
65
|
+
function printJson(io, payload) {
|
|
66
|
+
io.log(JSON.stringify(payload, null, 2));
|
|
67
|
+
}
|
|
68
|
+
function usageError(io, message) {
|
|
69
|
+
if (message !== undefined)
|
|
70
|
+
io.error(message);
|
|
71
|
+
io.error(TRIGGER_USAGE);
|
|
72
|
+
return 1;
|
|
73
|
+
}
|
|
74
|
+
export async function runTriggerCommand(args, options = {}) {
|
|
75
|
+
const out = { ...defaultIo, ...options.io };
|
|
76
|
+
const base = options.hostBaseUrl ?? hostBaseUrl();
|
|
77
|
+
const ensureService = options.ensureService ?? (() => ensureGlobalService());
|
|
78
|
+
let parsed;
|
|
79
|
+
try {
|
|
80
|
+
parsed = parseTriggerArgs(args);
|
|
81
|
+
}
|
|
82
|
+
catch (err) {
|
|
83
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
84
|
+
return usageError(out, message);
|
|
85
|
+
}
|
|
86
|
+
if (parsed.help) {
|
|
87
|
+
out.error(TRIGGER_USAGE);
|
|
88
|
+
return 0;
|
|
89
|
+
}
|
|
90
|
+
if (!parsed.subcommand) {
|
|
91
|
+
return usageError(out);
|
|
92
|
+
}
|
|
93
|
+
if (parsed.subcommand !== "list" &&
|
|
94
|
+
parsed.subcommand !== "show" &&
|
|
95
|
+
parsed.subcommand !== "fire") {
|
|
96
|
+
return usageError(out, `Unknown trigger subcommand: ${parsed.subcommand}`);
|
|
97
|
+
}
|
|
98
|
+
const ensured = await ensureService();
|
|
99
|
+
if (!ensured.ok) {
|
|
100
|
+
if (parsed.json) {
|
|
101
|
+
printJson(out, { error: ensured.message, reason: ensured.reason });
|
|
102
|
+
}
|
|
103
|
+
else {
|
|
104
|
+
out.error(ensured.message);
|
|
105
|
+
}
|
|
106
|
+
return 1;
|
|
107
|
+
}
|
|
108
|
+
const mutatingIo = out;
|
|
109
|
+
switch (parsed.subcommand) {
|
|
110
|
+
case "list": {
|
|
111
|
+
const result = await httpListTriggers(base);
|
|
112
|
+
if (!result.ok) {
|
|
113
|
+
const payload = { error: result.reason };
|
|
114
|
+
if (result.status !== undefined)
|
|
115
|
+
payload.status = result.status;
|
|
116
|
+
if (parsed.json) {
|
|
117
|
+
printJson(out, payload);
|
|
118
|
+
}
|
|
119
|
+
else {
|
|
120
|
+
out.error(result.reason);
|
|
121
|
+
}
|
|
122
|
+
return 1;
|
|
123
|
+
}
|
|
124
|
+
if (parsed.json) {
|
|
125
|
+
printJson(out, { triggers: result.triggers });
|
|
126
|
+
}
|
|
127
|
+
else {
|
|
128
|
+
for (const trigger of result.triggers) {
|
|
129
|
+
out.log(`${trigger.id}\t${trigger.kind}\t${trigger.enabled}`);
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
return 0;
|
|
133
|
+
}
|
|
134
|
+
case "show": {
|
|
135
|
+
if (!parsed.id) {
|
|
136
|
+
return usageError(out, "Missing <id>");
|
|
137
|
+
}
|
|
138
|
+
const result = await httpGetTrigger(base, parsed.id);
|
|
139
|
+
if (!result.ok) {
|
|
140
|
+
const payload = { error: result.reason };
|
|
141
|
+
if (result.status !== undefined)
|
|
142
|
+
payload.status = result.status;
|
|
143
|
+
if (parsed.json) {
|
|
144
|
+
printJson(out, payload);
|
|
145
|
+
}
|
|
146
|
+
else {
|
|
147
|
+
out.error(result.reason);
|
|
148
|
+
}
|
|
149
|
+
return 1;
|
|
150
|
+
}
|
|
151
|
+
if (parsed.json) {
|
|
152
|
+
printJson(out, result.trigger);
|
|
153
|
+
}
|
|
154
|
+
else {
|
|
155
|
+
out.log(`${result.trigger.id}\t${result.trigger.kind}\t${result.trigger.enabled}`);
|
|
156
|
+
}
|
|
157
|
+
return 0;
|
|
158
|
+
}
|
|
159
|
+
case "fire": {
|
|
160
|
+
if (!parsed.id) {
|
|
161
|
+
return usageError(out, "Missing <id>");
|
|
162
|
+
}
|
|
163
|
+
let task;
|
|
164
|
+
if (parsed.taskInline !== undefined) {
|
|
165
|
+
try {
|
|
166
|
+
task = parseJsonFlag(parsed.taskInline, "--task-inline");
|
|
167
|
+
}
|
|
168
|
+
catch (err) {
|
|
169
|
+
out.error(err instanceof Error ? err.message : String(err));
|
|
170
|
+
return 1;
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
const started = await httpFireTrigger(base, parsed.id, task);
|
|
174
|
+
if (!started.ok) {
|
|
175
|
+
return reportCliRun({ kind: "start-failure", started }, { json: parsed.json, io: mutatingIo });
|
|
176
|
+
}
|
|
177
|
+
writeQueuedAdmissionLine(started, mutatingIo);
|
|
178
|
+
return completeCliRun(started, mutatingIo, { json: parsed.json });
|
|
179
|
+
}
|
|
180
|
+
default:
|
|
181
|
+
return usageError(out, `Unknown trigger subcommand: ${parsed.subcommand}`);
|
|
182
|
+
}
|
|
183
|
+
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { validateCatalog as defaultValidateCatalog, type ValidationResult } from "../config/validateCatalog.js";
|
|
2
|
-
export declare const VALIDATE_USAGE = "Usage:\n sf validate [--pipeline <path>] [--task <path>] [--strict] [--json]\n\n With no flags, validates all pipelines and tasks declared in stageflow.yaml (manifest-all).\n --pipeline validates one pipeline file (includes uses:/include: transitively).\n --task validates one task file.";
|
|
2
|
+
export declare const VALIDATE_USAGE = "Usage:\n sf validate [--pipeline <path>] [--task <path>] [--trigger <path>] [--strict] [--json]\n\n With no flags, validates all pipelines and tasks declared in stageflow.yaml (manifest-all).\n --pipeline validates one pipeline file (includes uses:/include: transitively).\n --task validates one task file.\n --trigger validates one trigger file, including its pipeline/task refs.";
|
|
3
3
|
export type ValidateCommandIo = {
|
|
4
4
|
log: (line: string) => void;
|
|
5
5
|
error: (line: string) => void;
|
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
import { validateCatalog as defaultValidateCatalog, } from "../config/validateCatalog.js";
|
|
2
2
|
import { exitCodeForValidation, formatValidationHuman, formatValidationJson, } from "./validateOutput.js";
|
|
3
3
|
export const VALIDATE_USAGE = `Usage:
|
|
4
|
-
sf validate [--pipeline <path>] [--task <path>] [--strict] [--json]
|
|
4
|
+
sf validate [--pipeline <path>] [--task <path>] [--trigger <path>] [--strict] [--json]
|
|
5
5
|
|
|
6
6
|
With no flags, validates all pipelines and tasks declared in stageflow.yaml (manifest-all).
|
|
7
7
|
--pipeline validates one pipeline file (includes uses:/include: transitively).
|
|
8
|
-
--task validates one task file
|
|
8
|
+
--task validates one task file.
|
|
9
|
+
--trigger validates one trigger file, including its pipeline/task refs.`;
|
|
9
10
|
const defaultIo = {
|
|
10
11
|
log: (line) => console.log(line),
|
|
11
12
|
error: (line) => console.error(line),
|
|
@@ -19,6 +20,7 @@ function parseValidateArgs(args) {
|
|
|
19
20
|
}
|
|
20
21
|
let pipeline;
|
|
21
22
|
let task;
|
|
23
|
+
let trigger;
|
|
22
24
|
let strict = false;
|
|
23
25
|
let json = false;
|
|
24
26
|
let help = false;
|
|
@@ -41,6 +43,13 @@ function parseValidateArgs(args) {
|
|
|
41
43
|
}
|
|
42
44
|
task = value;
|
|
43
45
|
}
|
|
46
|
+
else if (arg === "--trigger") {
|
|
47
|
+
const value = args[++i];
|
|
48
|
+
if (value === undefined || value.length === 0) {
|
|
49
|
+
throw new Error("Missing value for --trigger");
|
|
50
|
+
}
|
|
51
|
+
trigger = value;
|
|
52
|
+
}
|
|
44
53
|
else if (arg === "--strict") {
|
|
45
54
|
strict = true;
|
|
46
55
|
}
|
|
@@ -54,10 +63,11 @@ function parseValidateArgs(args) {
|
|
|
54
63
|
throw new Error(`Unexpected argument: ${arg}`);
|
|
55
64
|
}
|
|
56
65
|
}
|
|
57
|
-
|
|
58
|
-
|
|
66
|
+
const scopedFlagCount = [pipeline, task, trigger].filter((v) => v !== undefined).length;
|
|
67
|
+
if (scopedFlagCount > 1) {
|
|
68
|
+
throw new Error("Use at most one of --pipeline, --task, or --trigger");
|
|
59
69
|
}
|
|
60
|
-
return { help, pipeline, task, strict, json };
|
|
70
|
+
return { help, pipeline, task, trigger, strict, json };
|
|
61
71
|
}
|
|
62
72
|
export async function runValidateCommand(args, options = {}) {
|
|
63
73
|
const cwd = options.cwd ?? process.cwd();
|
|
@@ -70,13 +80,20 @@ export async function runValidateCommand(args, options = {}) {
|
|
|
70
80
|
out.error(VALIDATE_USAGE);
|
|
71
81
|
return 0;
|
|
72
82
|
}
|
|
73
|
-
const scope = parsed.pipeline
|
|
83
|
+
const scope = parsed.pipeline
|
|
84
|
+
? "pipeline"
|
|
85
|
+
: parsed.task
|
|
86
|
+
? "task"
|
|
87
|
+
: parsed.trigger
|
|
88
|
+
? "trigger"
|
|
89
|
+
: "full";
|
|
74
90
|
const result = await validateCatalogFn({
|
|
75
91
|
scope,
|
|
76
92
|
cwd,
|
|
77
93
|
projectRoot,
|
|
78
94
|
pipeline: parsed.pipeline,
|
|
79
95
|
task: parsed.task,
|
|
96
|
+
trigger: parsed.trigger,
|
|
80
97
|
strict: parsed.strict,
|
|
81
98
|
});
|
|
82
99
|
if (parsed.json) {
|
package/dist/cli.js
CHANGED
|
@@ -5,6 +5,7 @@ import { realpathSync } from "node:fs";
|
|
|
5
5
|
import path from "node:path";
|
|
6
6
|
import { fileURLToPath } from "node:url";
|
|
7
7
|
import { globalAgentBackendFromManifest, resolveAgentPort } from "./agent/resolveAgentPort.js";
|
|
8
|
+
import { BROWSER_USAGE, runBrowserCommand } from "./cli/browserCommand.js";
|
|
8
9
|
import { ARTIFACT_USAGE, runArtifactCommand } from "./cli/artifactCommand.js";
|
|
9
10
|
import { ENVELOPE_USAGE, runEnvelopeCommand, } from "./cli/envelopeCommand.js";
|
|
10
11
|
import { EXPORT_RUN_USAGE, runExportRunCommand, } from "./cli/exportRunCommand.js";
|
|
@@ -17,6 +18,7 @@ import { PROVIDERS_USAGE, runProvidersCommand } from "./cli/providersCommand.js"
|
|
|
17
18
|
import { RUN_USAGE, runRunCommand } from "./cli/runCommand.js";
|
|
18
19
|
import { RUN_STAGE_USAGE, runRunStageCommand } from "./cli/runStageCommand.js";
|
|
19
20
|
import { RUNS_USAGE, runRunsCommand } from "./cli/runsCommand.js";
|
|
21
|
+
import { TRIGGER_USAGE, runTriggerCommand } from "./cli/triggerCommand.js";
|
|
20
22
|
import { resolveOperatorCatalog } from "./cli/operatorCatalog.js";
|
|
21
23
|
import { SKILLS_USAGE, runSkillsCommand } from "./cli/skillsCommand.js";
|
|
22
24
|
import { VALIDATE_USAGE, runValidateCommand } from "./cli/validateCommand.js";
|
|
@@ -73,6 +75,11 @@ const USAGE = `Usage:
|
|
|
73
75
|
sf skills list
|
|
74
76
|
sf skills install --from-path <dir> [--skill-name <name>]
|
|
75
77
|
sf skills install --from-zip <url-or-path> [--skill-name <name>] [--checksum sha256:<hex>]
|
|
78
|
+
sf browser profiles [--json]
|
|
79
|
+
sf browser status <name> [--json]
|
|
80
|
+
sf browser check <name> --url <url> --logged-in <glob> [--logged-out <glob>]... [--headless] [--json]
|
|
81
|
+
sf browser login <name> --url <login-url> --logged-in <glob> [--timeout-sec <n>]
|
|
82
|
+
sf browser clear <name> [--yes]
|
|
76
83
|
sf --version
|
|
77
84
|
sf -V
|
|
78
85
|
sf --help
|
|
@@ -115,9 +122,13 @@ ${EXPORT_ALL_USAGE}
|
|
|
115
122
|
|
|
116
123
|
${RUNS_USAGE}
|
|
117
124
|
|
|
125
|
+
${TRIGGER_USAGE}
|
|
126
|
+
|
|
118
127
|
${PROVIDERS_USAGE}
|
|
119
128
|
|
|
120
|
-
${SKILLS_USAGE}
|
|
129
|
+
${SKILLS_USAGE}
|
|
130
|
+
|
|
131
|
+
${BROWSER_USAGE}`;
|
|
121
132
|
function parseArgs(argv) {
|
|
122
133
|
const args = argv.slice(2);
|
|
123
134
|
if (args.length === 0) {
|
|
@@ -153,7 +164,9 @@ function parseArgs(argv) {
|
|
|
153
164
|
command === "restore" ||
|
|
154
165
|
command === "export" ||
|
|
155
166
|
command === "runs" ||
|
|
156
|
-
command === "
|
|
167
|
+
command === "trigger" ||
|
|
168
|
+
command === "skills" ||
|
|
169
|
+
command === "browser") {
|
|
157
170
|
return { help: false, command };
|
|
158
171
|
}
|
|
159
172
|
if (args.includes("--help") || args.includes("-h")) {
|
|
@@ -473,6 +486,11 @@ async function main(argv) {
|
|
|
473
486
|
cwd: ctx.invocationCwd,
|
|
474
487
|
});
|
|
475
488
|
}
|
|
489
|
+
if (parsed.command === "trigger") {
|
|
490
|
+
return runTriggerCommand(argv.slice(3), {
|
|
491
|
+
cwd: ctx.invocationCwd,
|
|
492
|
+
});
|
|
493
|
+
}
|
|
476
494
|
if (parsed.command === "providers") {
|
|
477
495
|
return runProvidersCommand(argv.slice(3), ctx.invocationCwd);
|
|
478
496
|
}
|
|
@@ -482,6 +500,9 @@ async function main(argv) {
|
|
|
482
500
|
projectRoot: ctx.projectRoot,
|
|
483
501
|
});
|
|
484
502
|
}
|
|
503
|
+
if (parsed.command === "browser") {
|
|
504
|
+
return runBrowserCommand(argv.slice(3));
|
|
505
|
+
}
|
|
485
506
|
const globalAgent = globalAgentBackendFromManifest(ctx.manifest);
|
|
486
507
|
if (parsed.command === "ui") {
|
|
487
508
|
const listenHost = resolveListenHost({ flag: parsed.host });
|
|
@@ -499,6 +520,14 @@ async function main(argv) {
|
|
|
499
520
|
mcpStateless,
|
|
500
521
|
controlTokens: tokens,
|
|
501
522
|
});
|
|
523
|
+
if (host.store) {
|
|
524
|
+
try {
|
|
525
|
+
await host.store.ensureProject(ctx.projectRoot);
|
|
526
|
+
}
|
|
527
|
+
catch {
|
|
528
|
+
// The console still serves seeded catalogs when this project cannot be registered.
|
|
529
|
+
}
|
|
530
|
+
}
|
|
502
531
|
console.log(`Operator console: ${host.url}`);
|
|
503
532
|
console.log(`MCP endpoint: ${host.mcpUrl}`);
|
|
504
533
|
if (!isNoOpenEnabled(parsed.noOpen)) {
|
|
@@ -37,6 +37,7 @@ export type CatalogBrowseResult = {
|
|
|
37
37
|
export type CatalogScanPaths = {
|
|
38
38
|
pipelinePaths: string[];
|
|
39
39
|
taskPaths: string[];
|
|
40
|
+
triggerPaths: string[];
|
|
40
41
|
};
|
|
41
42
|
export declare function getCatalogScanPaths(ctx: CatalogContext): Promise<CatalogScanPaths | null>;
|
|
42
43
|
export declare function browseCatalog(invocationCwd: string | StageflowContext): Promise<CatalogBrowseResult>;
|
|
@@ -28,7 +28,7 @@ function bakedModels() {
|
|
|
28
28
|
return [...BAKED_MODEL_IDS].sort((a, b) => a.localeCompare(b));
|
|
29
29
|
}
|
|
30
30
|
function catalogReadyFromStageflow(ctx) {
|
|
31
|
-
return ctx.
|
|
31
|
+
return ctx.manifestStatus === "ok" && ctx.manifest !== null;
|
|
32
32
|
}
|
|
33
33
|
function catalogReady(ctx) {
|
|
34
34
|
return ctx.manifestStatus === "ok" && ctx.projectRoot !== null && ctx.manifest !== null;
|
|
@@ -37,11 +37,12 @@ export async function getCatalogScanPaths(ctx) {
|
|
|
37
37
|
if (!catalogReady(ctx)) {
|
|
38
38
|
return null;
|
|
39
39
|
}
|
|
40
|
-
const [pipelinePaths, taskPaths] = await Promise.all([
|
|
40
|
+
const [pipelinePaths, taskPaths, triggerPaths] = await Promise.all([
|
|
41
41
|
scanCatalogPaths(ctx.manifest, "pipeline"),
|
|
42
42
|
scanCatalogPaths(ctx.manifest, "task"),
|
|
43
|
+
scanCatalogPaths(ctx.manifest, "trigger"),
|
|
43
44
|
]);
|
|
44
|
-
return { pipelinePaths, taskPaths };
|
|
45
|
+
return { pipelinePaths, taskPaths, triggerPaths };
|
|
45
46
|
}
|
|
46
47
|
async function listTasksFromManifest(projectRoot, manifest, warnings) {
|
|
47
48
|
const filePaths = await scanCatalogPaths(manifest, "task");
|
|
@@ -122,7 +123,7 @@ export async function browseCatalog(invocationCwd) {
|
|
|
122
123
|
? await resolveStageflowContext(invocationCwd)
|
|
123
124
|
: invocationCwd;
|
|
124
125
|
const base = {
|
|
125
|
-
projectRoot: ctx.
|
|
126
|
+
projectRoot: ctx.manifestStatus === "not_git" ? null : ctx.projectRoot,
|
|
126
127
|
manifest: ctx.manifest,
|
|
127
128
|
manifestStatus: ctx.manifestStatus,
|
|
128
129
|
issues: ctx.manifestIssues,
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
export declare const BROWSER_SKILL_NAME = "browser";
|
|
2
|
+
export declare function isBuiltinSkillName(name: string): boolean;
|
|
3
|
+
/** Absolute SKILL.md of a skill shipped inside the package, if present on disk. */
|
|
4
|
+
export declare function resolveBuiltinSkillFile(name: string, fromUrl?: string): string | undefined;
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { existsSync } from "node:fs";
|
|
2
|
+
import path from "node:path";
|
|
3
|
+
import { fileURLToPath } from "node:url";
|
|
4
|
+
export const BROWSER_SKILL_NAME = "browser";
|
|
5
|
+
const BUILTIN_SKILL_NAMES = new Set([BROWSER_SKILL_NAME]);
|
|
6
|
+
export function isBuiltinSkillName(name) {
|
|
7
|
+
return BUILTIN_SKILL_NAMES.has(name);
|
|
8
|
+
}
|
|
9
|
+
/** Absolute SKILL.md of a skill shipped inside the package, if present on disk. */
|
|
10
|
+
export function resolveBuiltinSkillFile(name, fromUrl = import.meta.url) {
|
|
11
|
+
if (!isBuiltinSkillName(name))
|
|
12
|
+
return undefined;
|
|
13
|
+
const here = path.dirname(fileURLToPath(fromUrl));
|
|
14
|
+
for (const root of [
|
|
15
|
+
path.resolve(here, "../../builtin-skills"),
|
|
16
|
+
path.resolve(here, "../../../builtin-skills"),
|
|
17
|
+
]) {
|
|
18
|
+
const file = path.join(root, name, "SKILL.md");
|
|
19
|
+
if (existsSync(file))
|
|
20
|
+
return file;
|
|
21
|
+
}
|
|
22
|
+
return undefined;
|
|
23
|
+
}
|
|
@@ -33,7 +33,10 @@ export function resolveCatalogRelativePath(input) {
|
|
|
33
33
|
const field = input.fieldName ?? "path";
|
|
34
34
|
const registered = input.roots.map((r) => r.project_root);
|
|
35
35
|
if (path.isAbsolute(input.inputPath)) {
|
|
36
|
-
|
|
36
|
+
const rootsList = registered.length > 0
|
|
37
|
+
? registered.join(", ")
|
|
38
|
+
: "(none — register a project or use seeded examples)";
|
|
39
|
+
throw new CatalogPathError(`Absolute ${field} is not allowed on network surfaces. Use a catalog-relative path under project_root (registered or seeded roots: ${rootsList}). Local CLI may pass absolute paths and auto-registers the project folder.`, "absolute_path_not_allowed", registered);
|
|
37
40
|
}
|
|
38
41
|
const root = selectCatalogRootForStart(input.roots, input.projectRoot);
|
|
39
42
|
const absolutePath = path.resolve(root.path, input.inputPath);
|
|
@@ -47,11 +50,16 @@ export function resolveCatalogRelativePath(input) {
|
|
|
47
50
|
};
|
|
48
51
|
}
|
|
49
52
|
export function catalogPathErrorBody(err) {
|
|
50
|
-
|
|
53
|
+
const body = {
|
|
51
54
|
error: err.message,
|
|
52
55
|
code: err.code,
|
|
53
56
|
registered_roots: err.registered_roots,
|
|
54
57
|
};
|
|
58
|
+
if (err.code === "absolute_path_not_allowed") {
|
|
59
|
+
body.hint =
|
|
60
|
+
"MCP/HTTP: relative path under project_root; CLI may pass absolute paths and auto-register.";
|
|
61
|
+
}
|
|
62
|
+
return body;
|
|
55
63
|
}
|
|
56
64
|
/**
|
|
57
65
|
* Pick the catalog root for start_run / POST /api/runs.
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import type { TriggerEvent, TriggerSchedule } from "../types/trigger.js";
|
|
2
|
+
import type { TriggerListItem } from "./triggerCatalog.js";
|
|
3
|
+
export type CreateTriggerInput = {
|
|
4
|
+
directory: string;
|
|
5
|
+
id: string;
|
|
6
|
+
pipeline: string;
|
|
7
|
+
task?: string;
|
|
8
|
+
kind: "manual" | "schedule" | "event";
|
|
9
|
+
schedule?: TriggerSchedule;
|
|
10
|
+
event?: TriggerEvent;
|
|
11
|
+
enabled?: boolean;
|
|
12
|
+
};
|
|
13
|
+
export type CreateTriggerParseError = {
|
|
14
|
+
ok: false;
|
|
15
|
+
status: 400;
|
|
16
|
+
error: string;
|
|
17
|
+
};
|
|
18
|
+
export type CreateTriggerResult = {
|
|
19
|
+
ok: true;
|
|
20
|
+
trigger: TriggerListItem;
|
|
21
|
+
} | {
|
|
22
|
+
ok: false;
|
|
23
|
+
status: 400 | 409 | 422 | 500;
|
|
24
|
+
error: string;
|
|
25
|
+
};
|
|
26
|
+
export declare function parseCreateTriggerBody(body: unknown): CreateTriggerInput | CreateTriggerParseError;
|
|
27
|
+
export declare function createTrigger(rawProjectRoot: string, input: CreateTriggerInput): Promise<CreateTriggerResult>;
|