@relayflows/sdk 2.0.17 → 2.0.19
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/dist/authored-flow-error.d.ts +21 -1
- package/dist/authored-flow-error.d.ts.map +1 -1
- package/dist/authored-flow-error.js +14 -0
- package/dist/authored-flow-error.js.map +1 -1
- package/dist/authored-flow-executor.d.ts.map +1 -1
- package/dist/authored-flow-executor.js +47 -3
- package/dist/authored-flow-executor.js.map +1 -1
- package/dist/authored-human.d.ts +49 -0
- package/dist/authored-human.d.ts.map +1 -0
- package/dist/authored-human.js +97 -0
- package/dist/authored-human.js.map +1 -0
- package/dist/authored-node-entry.js +3 -2
- package/dist/authored-node-entry.js.map +1 -1
- package/dist/authored-node-runner.d.ts.map +1 -1
- package/dist/authored-node-runner.js +15 -4
- package/dist/authored-node-runner.js.map +1 -1
- package/dist/authored-root.d.ts.map +1 -1
- package/dist/authored-root.js +29 -1
- package/dist/authored-root.js.map +1 -1
- package/dist/cli/answer.d.ts +17 -0
- package/dist/cli/answer.d.ts.map +1 -0
- package/dist/cli/answer.js +89 -0
- package/dist/cli/answer.js.map +1 -0
- package/dist/cli/build.d.ts +9 -0
- package/dist/cli/build.d.ts.map +1 -1
- package/dist/cli/build.js +26 -7
- package/dist/cli/build.js.map +1 -1
- package/dist/cli/check-triggers.d.ts.map +1 -1
- package/dist/cli/check-triggers.js +2 -0
- package/dist/cli/check-triggers.js.map +1 -1
- package/dist/cli/check.d.ts +11 -0
- package/dist/cli/check.d.ts.map +1 -1
- package/dist/cli/check.js +14 -2
- package/dist/cli/check.js.map +1 -1
- package/dist/cli/cloud-connect-cli.d.ts +54 -0
- package/dist/cli/cloud-connect-cli.d.ts.map +1 -0
- package/dist/cli/cloud-connect-cli.js +109 -0
- package/dist/cli/cloud-connect-cli.js.map +1 -0
- package/dist/cli/cloud-deploy.d.ts +3 -1
- package/dist/cli/cloud-deploy.d.ts.map +1 -1
- package/dist/cli/cloud-deploy.js +44 -6
- package/dist/cli/cloud-deploy.js.map +1 -1
- package/dist/cli/cloud-run.d.ts +9 -2
- package/dist/cli/cloud-run.d.ts.map +1 -1
- package/dist/cli/cloud-run.js +27 -15
- package/dist/cli/cloud-run.js.map +1 -1
- package/dist/cli/cloud-schedule.d.ts +3 -1
- package/dist/cli/cloud-schedule.d.ts.map +1 -1
- package/dist/cli/cloud-schedule.js +31 -6
- package/dist/cli/cloud-schedule.js.map +1 -1
- package/dist/cli/cloud-sync.d.ts +8 -1
- package/dist/cli/cloud-sync.d.ts.map +1 -1
- package/dist/cli/cloud-sync.js +79 -8
- package/dist/cli/cloud-sync.js.map +1 -1
- package/dist/cli/deploy.d.ts +6 -0
- package/dist/cli/deploy.d.ts.map +1 -1
- package/dist/cli/deploy.js +29 -4
- package/dist/cli/deploy.js.map +1 -1
- package/dist/cli/direct-run.d.ts.map +1 -1
- package/dist/cli/direct-run.js +5 -1
- package/dist/cli/direct-run.js.map +1 -1
- package/dist/cli/run.d.ts +22 -2
- package/dist/cli/run.d.ts.map +1 -1
- package/dist/cli/run.js +34 -1
- package/dist/cli/run.js.map +1 -1
- package/dist/cli/serve-webhook.d.ts +7 -1
- package/dist/cli/serve-webhook.d.ts.map +1 -1
- package/dist/cli/serve-webhook.js +19 -9
- package/dist/cli/serve-webhook.js.map +1 -1
- package/dist/cli-commands.d.ts +398 -0
- package/dist/cli-commands.d.ts.map +1 -0
- package/dist/cli-commands.js +254 -0
- package/dist/cli-commands.js.map +1 -0
- package/dist/cli-watch.d.ts +3 -1
- package/dist/cli-watch.d.ts.map +1 -1
- package/dist/cli-watch.js +4 -10
- package/dist/cli-watch.js.map +1 -1
- package/dist/cli.d.ts +127 -1
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +195 -57
- package/dist/cli.js.map +1 -1
- package/dist/cloud-connect.d.ts +52 -0
- package/dist/cloud-connect.d.ts.map +1 -0
- package/dist/cloud-connect.js +138 -0
- package/dist/cloud-connect.js.map +1 -0
- package/dist/cloud-deploy.d.ts +19 -1
- package/dist/cloud-deploy.d.ts.map +1 -1
- package/dist/cloud-deploy.js +40 -1
- package/dist/cloud-deploy.js.map +1 -1
- package/dist/cloud-http.d.ts +2 -2
- package/dist/cloud-http.d.ts.map +1 -1
- package/dist/cloud-http.js.map +1 -1
- package/dist/cloud-schedule.d.ts +7 -0
- package/dist/cloud-schedule.d.ts.map +1 -1
- package/dist/cloud-schedule.js +22 -1
- package/dist/cloud-schedule.js.map +1 -1
- package/dist/cloud-sync.d.ts +85 -2
- package/dist/cloud-sync.d.ts.map +1 -1
- package/dist/cloud-sync.js +123 -10
- package/dist/cloud-sync.js.map +1 -1
- package/dist/failure-kinds.d.ts +1 -1
- package/dist/failure-kinds.d.ts.map +1 -1
- package/dist/failure-kinds.js +2 -0
- package/dist/failure-kinds.js.map +1 -1
- package/dist/flow-requirements.d.ts +68 -0
- package/dist/flow-requirements.d.ts.map +1 -0
- package/dist/flow-requirements.js +152 -0
- package/dist/flow-requirements.js.map +1 -0
- package/dist/index.d.ts +3 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +3 -1
- package/dist/index.js.map +1 -1
- package/dist/journal-client.d.ts +11 -0
- package/dist/journal-client.d.ts.map +1 -1
- package/dist/journal-client.js +13 -0
- package/dist/journal-client.js.map +1 -1
- package/dist/progress.d.ts +2 -1
- package/dist/progress.d.ts.map +1 -1
- package/dist/progress.js +9 -3
- package/dist/progress.js.map +1 -1
- package/dist/protocol.d.ts +25 -1
- package/dist/protocol.d.ts.map +1 -1
- package/dist/relay-cli.d.ts +50 -0
- package/dist/relay-cli.d.ts.map +1 -0
- package/dist/relay-cli.js +64 -0
- package/dist/relay-cli.js.map +1 -0
- package/package.json +7 -2
- package/src/authored-flow-error.ts +29 -0
- package/src/authored-flow-executor.ts +54 -2
- package/src/authored-human.ts +150 -0
- package/src/authored-node-entry.ts +3 -2
- package/src/authored-node-runner.ts +20 -5
- package/src/authored-root.ts +28 -1
- package/src/cli/answer.ts +98 -0
- package/src/cli/build.ts +21 -7
- package/src/cli/check-triggers.ts +2 -0
- package/src/cli/check.ts +24 -2
- package/src/cli/cloud-connect-cli.ts +130 -0
- package/src/cli/cloud-deploy.ts +40 -6
- package/src/cli/cloud-run.ts +26 -15
- package/src/cli/cloud-schedule.ts +31 -6
- package/src/cli/cloud-sync.ts +85 -8
- package/src/cli/deploy.ts +27 -5
- package/src/cli/direct-run.ts +5 -0
- package/src/cli/run.ts +48 -2
- package/src/cli/serve-webhook.ts +15 -8
- package/src/cli-commands.ts +339 -0
- package/src/cli-watch.ts +8 -9
- package/src/cli.ts +206 -54
- package/src/cloud-connect.ts +187 -0
- package/src/cloud-deploy.ts +57 -2
- package/src/cloud-http.ts +1 -1
- package/src/cloud-schedule.ts +20 -3
- package/src/cloud-sync.ts +164 -11
- package/src/failure-kinds.ts +2 -0
- package/src/flow-requirements.ts +201 -0
- package/src/index.ts +12 -2
- package/src/journal-client.ts +20 -0
- package/src/progress.ts +11 -4
- package/src/protocol.ts +23 -0
- package/src/relay-cli.ts +117 -0
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import { type ConnectPrompt, type ConnectionsOutcome } from '../cloud-connect.js';
|
|
2
|
+
import { type CloudConnectionOptions } from '../cloud-http.js';
|
|
3
|
+
import { type FlowRequirements, type FlowRequirementsContext } from '../flow-requirements.js';
|
|
4
|
+
import type { CliIo } from '../cli.js';
|
|
5
|
+
/**
|
|
6
|
+
* The hosted verbs' shared "are the integrations connected?" step. It runs
|
|
7
|
+
* before `flows deploy`, `flows schedule` and `flows run --cloud` submit
|
|
8
|
+
* anything, so a flow that would fail at its first `f.slack.post` with
|
|
9
|
+
* `helper_slack.credential_missing` is connected — or refused — first.
|
|
10
|
+
*
|
|
11
|
+
* The flow is read the same way the submission reads it (authored loader or
|
|
12
|
+
* YAML compile); a source that does not load is left for the submission to
|
|
13
|
+
* refuse with its own, better diagnostic, so this step never masks one.
|
|
14
|
+
*/
|
|
15
|
+
export interface FlowConnectionsInput extends FlowRequirementsContext {
|
|
16
|
+
path: string;
|
|
17
|
+
/** `undefined` refuses a missing integration instead of prompting (`--no-connect`, `--json`, no TTY). */
|
|
18
|
+
prompt: ConnectPrompt | undefined;
|
|
19
|
+
/** Known already (deploy resolved it); otherwise `whoami` supplies it. */
|
|
20
|
+
workspaceId?: string;
|
|
21
|
+
}
|
|
22
|
+
export declare function flowRequirementsForPath(path: string, context?: FlowRequirementsContext): Promise<FlowRequirements | undefined>;
|
|
23
|
+
/** `whoami`'s current workspace: the one every hosted verb submits into. */
|
|
24
|
+
export declare function currentWorkspaceId(options: CloudConnectionOptions): Promise<string>;
|
|
25
|
+
/**
|
|
26
|
+
* Connects (or refuses on) every integration `path` requires. Nothing is
|
|
27
|
+
* contacted when the flow requires no integration, so a flow with no
|
|
28
|
+
* helpers, sources or repository submits exactly as before; the derived
|
|
29
|
+
* requirements still come back so a later harness refusal can name its remedy.
|
|
30
|
+
* `undefined` only when the source does not load — the submission says why.
|
|
31
|
+
*/
|
|
32
|
+
export declare function ensureFlowConnections(input: FlowConnectionsInput, options?: CloudConnectionOptions): Promise<{
|
|
33
|
+
requirements: FlowRequirements;
|
|
34
|
+
outcome: ConnectionsOutcome;
|
|
35
|
+
} | undefined>;
|
|
36
|
+
/**
|
|
37
|
+
* A terminal prompt, or nothing. `--json` output is for a machine, and a
|
|
38
|
+
* pipe cannot answer a question, so both refuse instead of asking; `--no-connect`
|
|
39
|
+
* is the explicit form of the same choice.
|
|
40
|
+
*/
|
|
41
|
+
export declare function cliConnectPrompt(io: CliIo, { noConnect, json }: {
|
|
42
|
+
noConnect: boolean;
|
|
43
|
+
json: boolean;
|
|
44
|
+
}, streams?: {
|
|
45
|
+
stdin: NodeJS.ReadStream;
|
|
46
|
+
stdout: NodeJS.WriteStream;
|
|
47
|
+
}): ConnectPrompt | undefined;
|
|
48
|
+
/**
|
|
49
|
+
* Cloud refuses a run or activation whose coding-agent credential is missing
|
|
50
|
+
* (`flow_model_not_connected`, `cli_credentials_missing`); there is no status
|
|
51
|
+
* route to ask first, so the refusal is where the remedy is named.
|
|
52
|
+
*/
|
|
53
|
+
export declare function harnessRemedy(error: unknown, harnesses: readonly string[]): string;
|
|
54
|
+
//# sourceMappingURL=cloud-connect-cli.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cloud-connect-cli.d.ts","sourceRoot":"","sources":["../../src/cli/cloud-connect-cli.ts"],"names":[],"mappings":"AAKA,OAAO,EAA+B,KAAK,aAAa,EAAE,KAAK,kBAAkB,EAAE,MAAM,qBAAqB,CAAC;AAC/G,OAAO,EAA+C,KAAK,sBAAsB,EAAE,MAAM,kBAAkB,CAAC;AAE5G,OAAO,EAAoC,KAAK,gBAAgB,EAAE,KAAK,uBAAuB,EAAE,MAAM,yBAAyB,CAAC;AAEhI,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,WAAW,CAAC;AAEvC;;;;;;;;;GASG;AAEH,MAAM,WAAW,oBAAqB,SAAQ,uBAAuB;IACnE,IAAI,EAAE,MAAM,CAAC;IACb,yGAAyG;IACzG,MAAM,EAAE,aAAa,GAAG,SAAS,CAAC;IAClC,0EAA0E;IAC1E,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED,wBAAsB,uBAAuB,CAC3C,IAAI,EAAE,MAAM,EAAE,OAAO,GAAE,uBAA4B,GAClD,OAAO,CAAC,gBAAgB,GAAG,SAAS,CAAC,CAqBvC;AAUD,4EAA4E;AAC5E,wBAAsB,kBAAkB,CAAC,OAAO,EAAE,sBAAsB,GAAG,OAAO,CAAC,MAAM,CAAC,CAOzF;AAED;;;;;;GAMG;AACH,wBAAsB,qBAAqB,CACzC,KAAK,EAAE,oBAAoB,EAAE,OAAO,GAAE,sBAA2B,GAChE,OAAO,CAAC;IAAE,YAAY,EAAE,gBAAgB,CAAC;IAAC,OAAO,EAAE,kBAAkB,CAAA;CAAE,GAAG,SAAS,CAAC,CAStF;AAED;;;;GAIG;AACH,wBAAgB,gBAAgB,CAC9B,EAAE,EAAE,KAAK,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,EAAE;IAAE,SAAS,EAAE,OAAO,CAAC;IAAC,IAAI,EAAE,OAAO,CAAA;CAAE,EACrE,OAAO,GAAE;IAAE,KAAK,EAAE,MAAM,CAAC,UAAU,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC,WAAW,CAAA;CAAqD,GACnH,aAAa,GAAG,SAAS,CAY3B;AAED;;;;GAIG;AACH,wBAAgB,aAAa,CAAC,KAAK,EAAE,OAAO,EAAE,SAAS,EAAE,SAAS,MAAM,EAAE,GAAG,MAAM,CAQlF"}
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
import { readFile } from 'node:fs/promises';
|
|
2
|
+
import { dirname, resolve } from 'node:path';
|
|
3
|
+
import { createInterface } from 'node:readline';
|
|
4
|
+
import { parse as parseYaml } from 'yaml';
|
|
5
|
+
import { loadAuthoredFlow } from '../authored-flow-loader.js';
|
|
6
|
+
import { ensureIntegrationsConnected } from '../cloud-connect.js';
|
|
7
|
+
import { CloudFlowError, cloudRequest, isCloudRecord } from '../cloud-http.js';
|
|
8
|
+
import { CompileError, compileSpec, kernelToAuthoring } from '../compile.js';
|
|
9
|
+
import { FLOW_HARNESSES, flowRequirements } from '../flow-requirements.js';
|
|
10
|
+
import { readProjectConfig } from './check.js';
|
|
11
|
+
export async function flowRequirementsForPath(path, context = {}) {
|
|
12
|
+
const projectCli = context.projectCli ?? projectCliFor(path);
|
|
13
|
+
const withCli = { ...context, ...(projectCli === undefined ? {} : { projectCli }) };
|
|
14
|
+
try {
|
|
15
|
+
if (/\.flow\.ts$/iu.test(path)) {
|
|
16
|
+
const loaded = await loadAuthoredFlow(path);
|
|
17
|
+
return flowRequirements(loaded.getDefinition(loaded.handle), withCli);
|
|
18
|
+
}
|
|
19
|
+
if (!/\.(?:ya?ml|json)$/iu.test(path))
|
|
20
|
+
return undefined;
|
|
21
|
+
const parsed = parseYaml(await readFile(path, 'utf8'));
|
|
22
|
+
let spec;
|
|
23
|
+
try {
|
|
24
|
+
spec = compileSpec(parsed);
|
|
25
|
+
}
|
|
26
|
+
catch (error) {
|
|
27
|
+
if (!(error instanceof CompileError))
|
|
28
|
+
throw error;
|
|
29
|
+
spec = compileSpec(kernelToAuthoring(parsed));
|
|
30
|
+
}
|
|
31
|
+
return flowRequirements(spec, withCli);
|
|
32
|
+
}
|
|
33
|
+
catch {
|
|
34
|
+
return undefined;
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
function projectCliFor(path) {
|
|
38
|
+
try {
|
|
39
|
+
return readProjectConfig(dirname(resolve(path))).cli;
|
|
40
|
+
}
|
|
41
|
+
catch {
|
|
42
|
+
return undefined;
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
/** `whoami`'s current workspace: the one every hosted verb submits into. */
|
|
46
|
+
export async function currentWorkspaceId(options) {
|
|
47
|
+
const whoami = await cloudRequest('/api/v1/auth/whoami', options);
|
|
48
|
+
const workspace = isCloudRecord(whoami) && isCloudRecord(whoami.currentWorkspace) ? whoami.currentWorkspace : undefined;
|
|
49
|
+
if (workspace === undefined || typeof workspace.id !== 'string' || !workspace.id) {
|
|
50
|
+
throw new CloudFlowError('invalid_response', 'Cloud did not report a current workspace for this credential.');
|
|
51
|
+
}
|
|
52
|
+
return workspace.id;
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* Connects (or refuses on) every integration `path` requires. Nothing is
|
|
56
|
+
* contacted when the flow requires no integration, so a flow with no
|
|
57
|
+
* helpers, sources or repository submits exactly as before; the derived
|
|
58
|
+
* requirements still come back so a later harness refusal can name its remedy.
|
|
59
|
+
* `undefined` only when the source does not load — the submission says why.
|
|
60
|
+
*/
|
|
61
|
+
export async function ensureFlowConnections(input, options = {}) {
|
|
62
|
+
const requirements = await flowRequirementsForPath(input.path, input);
|
|
63
|
+
if (requirements === undefined)
|
|
64
|
+
return undefined;
|
|
65
|
+
if (requirements.integrations.length === 0)
|
|
66
|
+
return { requirements, outcome: { ready: [], connected: [] } };
|
|
67
|
+
const workspaceId = input.workspaceId ?? await currentWorkspaceId(options);
|
|
68
|
+
const outcome = await ensureIntegrationsConnected(requirements, {
|
|
69
|
+
...options, workspaceId, ...(input.prompt === undefined ? {} : { prompt: input.prompt }),
|
|
70
|
+
});
|
|
71
|
+
return { requirements, outcome };
|
|
72
|
+
}
|
|
73
|
+
/**
|
|
74
|
+
* A terminal prompt, or nothing. `--json` output is for a machine, and a
|
|
75
|
+
* pipe cannot answer a question, so both refuse instead of asking; `--no-connect`
|
|
76
|
+
* is the explicit form of the same choice.
|
|
77
|
+
*/
|
|
78
|
+
export function cliConnectPrompt(io, { noConnect, json }, streams = { stdin: process.stdin, stdout: process.stdout }) {
|
|
79
|
+
if (noConnect || json || !streams.stdin.isTTY || !streams.stdout.isTTY)
|
|
80
|
+
return undefined;
|
|
81
|
+
return {
|
|
82
|
+
info: line => io.stderr(line),
|
|
83
|
+
confirm: question => new Promise(resolveAnswer => {
|
|
84
|
+
const rl = createInterface({ input: streams.stdin, output: streams.stdout });
|
|
85
|
+
rl.question(question, answer => {
|
|
86
|
+
rl.close();
|
|
87
|
+
resolveAnswer(/^\s*(?:y(?:es)?)?\s*$/iu.test(answer));
|
|
88
|
+
});
|
|
89
|
+
}),
|
|
90
|
+
};
|
|
91
|
+
}
|
|
92
|
+
/**
|
|
93
|
+
* Cloud refuses a run or activation whose coding-agent credential is missing
|
|
94
|
+
* (`flow_model_not_connected`, `cli_credentials_missing`); there is no status
|
|
95
|
+
* route to ask first, so the refusal is where the remedy is named.
|
|
96
|
+
*/
|
|
97
|
+
export function harnessRemedy(error, harnesses) {
|
|
98
|
+
if (!(error instanceof CloudFlowError) || error.refusal === undefined)
|
|
99
|
+
return '';
|
|
100
|
+
if (!['flow_model_not_connected', 'cli_credentials_missing'].includes(error.refusal.code))
|
|
101
|
+
return '';
|
|
102
|
+
if (/agent-relay cloud connect/u.test(error.refusal.error))
|
|
103
|
+
return '';
|
|
104
|
+
const message = error.refusal.error.toLowerCase();
|
|
105
|
+
const named = FLOW_HARNESSES.filter(harness => message.includes(harness));
|
|
106
|
+
const targets = named.length > 0 ? named : harnesses.length > 0 ? harnesses : ['claude'];
|
|
107
|
+
return ` Connect it with: ${targets.map(harness => `agent-relay cloud connect ${harness}`).join('; ')}.`;
|
|
108
|
+
}
|
|
109
|
+
//# sourceMappingURL=cloud-connect-cli.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cloud-connect-cli.js","sourceRoot":"","sources":["../../src/cli/cloud-connect-cli.ts"],"names":[],"mappings":"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"}
|
|
@@ -8,11 +8,13 @@ export interface CloudDeployArgs {
|
|
|
8
8
|
name: string | undefined;
|
|
9
9
|
agents: string | undefined;
|
|
10
10
|
draft: boolean;
|
|
11
|
+
/** Refuse a missing integration instead of offering to connect it. */
|
|
12
|
+
noConnect: boolean;
|
|
11
13
|
json: boolean;
|
|
12
14
|
}
|
|
13
15
|
/**
|
|
14
16
|
* `flows deploy <flow.ts> --repo <owner/name> --on <provider>[:k=v,…] [--on …]
|
|
15
|
-
* --approver <handle> [--name <n>] [--json]`
|
|
17
|
+
* --approver <handle> [--name <n>] [--agents <list>] [--draft] [--no-connect] [--json]`
|
|
16
18
|
*
|
|
17
19
|
* Parsed here rather than in `parseDeployArgs` because the two `deploy` forms
|
|
18
20
|
* share nothing but the word: the digest form copies a sealed bundle into a
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cloud-deploy.d.ts","sourceRoot":"","sources":["../../src/cli/cloud-deploy.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"cloud-deploy.d.ts","sourceRoot":"","sources":["../../src/cli/cloud-deploy.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,WAAW,CAAC;AAEvC,MAAM,WAAW,eAAe;IAC9B,OAAO,EAAE,cAAc,CAAC;IACxB,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;IACb,EAAE,EAAE,MAAM,EAAE,CAAC;IACb,QAAQ,EAAE,MAAM,GAAG,SAAS,CAAC;IAC7B,IAAI,EAAE,MAAM,GAAG,SAAS,CAAC;IACzB,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC;IAC3B,KAAK,EAAE,OAAO,CAAC;IACf,sEAAsE;IACtE,SAAS,EAAE,OAAO,CAAC;IACnB,IAAI,EAAE,OAAO,CAAC;CACf;AAED;;;;;;;GAOG;AACH,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,SAAS,MAAM,EAAE,GAAG,eAAe,GAAG,SAAS,CAkDzF;AAOD,wBAAsB,iBAAiB,CAAC,IAAI,EAAE,eAAe,EAAE,EAAE,EAAE,KAAK,GAAG,OAAO,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CA0C5F;AAWD,wBAAsB,sBAAsB,CAAC,EAAE,IAAI,EAAE,EAAE;IAAE,IAAI,EAAE,OAAO,CAAA;CAAE,EAAE,EAAE,EAAE,KAAK,GAAG,OAAO,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAoBvG;AAED,wBAAsB,mBAAmB,CAAC,EAAE,OAAO,EAAE,IAAI,EAAE,EAAE;IAAE,OAAO,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,OAAO,CAAA;CAAE,EAAE,EAAE,EAAE,KAAK,GAAG,OAAO,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAQ9H"}
|
package/dist/cli/cloud-deploy.js
CHANGED
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
import { CloudFlowError } from '../cloud-http.js';
|
|
2
2
|
import { deployToCloud, listCloudDeployments, parseAgentHarnesses, parseRepository, parseTriggerSource, undeployFromCloud, } from '../cloud-deploy.js';
|
|
3
|
+
import { describeFlowRequirements } from '../flow-requirements.js';
|
|
4
|
+
import { cliConnectPrompt, flowRequirementsForPath, harnessRemedy } from './cloud-connect-cli.js';
|
|
3
5
|
/**
|
|
4
6
|
* `flows deploy <flow.ts> --repo <owner/name> --on <provider>[:k=v,…] [--on …]
|
|
5
|
-
* --approver <handle> [--name <n>] [--json]`
|
|
7
|
+
* --approver <handle> [--name <n>] [--agents <list>] [--draft] [--no-connect] [--json]`
|
|
6
8
|
*
|
|
7
9
|
* Parsed here rather than in `parseDeployArgs` because the two `deploy` forms
|
|
8
10
|
* share nothing but the word: the digest form copies a sealed bundle into a
|
|
@@ -15,6 +17,7 @@ export function parseCloudDeployArgs(args) {
|
|
|
15
17
|
let name;
|
|
16
18
|
let agents;
|
|
17
19
|
let draft = false;
|
|
20
|
+
let noConnect = false;
|
|
18
21
|
let json = false;
|
|
19
22
|
const on = [];
|
|
20
23
|
for (let i = 0; i < args.length; i++) {
|
|
@@ -31,6 +34,12 @@ export function parseCloudDeployArgs(args) {
|
|
|
31
34
|
draft = true;
|
|
32
35
|
continue;
|
|
33
36
|
}
|
|
37
|
+
if (arg === '--no-connect') {
|
|
38
|
+
if (noConnect)
|
|
39
|
+
return undefined;
|
|
40
|
+
noConnect = true;
|
|
41
|
+
continue;
|
|
42
|
+
}
|
|
34
43
|
if (arg === '--agents') {
|
|
35
44
|
const next = args[i + 1];
|
|
36
45
|
if (agents !== undefined || next === undefined || next.startsWith('-'))
|
|
@@ -71,17 +80,27 @@ export function parseCloudDeployArgs(args) {
|
|
|
71
80
|
}
|
|
72
81
|
if (value === undefined || repo === undefined || on.length === 0)
|
|
73
82
|
return undefined;
|
|
74
|
-
return { command: 'cloud-deploy', value, repo, on, approver, name, agents, draft, json };
|
|
83
|
+
return { command: 'cloud-deploy', value, repo, on, approver, name, agents, draft, noConnect, json };
|
|
75
84
|
}
|
|
76
85
|
function describeSource(source) {
|
|
77
86
|
const settings = Object.entries(source.settings).map(([k, v]) => `${k}=${v}`).join(' ');
|
|
78
87
|
return settings ? `${source.provider} ${settings}` : source.provider;
|
|
79
88
|
}
|
|
80
89
|
export async function runCloudDeployCli(args, io) {
|
|
90
|
+
const agents = args.agents === undefined ? undefined : parseAgentHarnessesOr(args.agents);
|
|
91
|
+
// What the source declares, so a harness refusal names the right remedy
|
|
92
|
+
// even when `--agents` was not given; the loader's own failure is reported
|
|
93
|
+
// by deployToCloud, not here.
|
|
94
|
+
let harnesses = agents instanceof CloudFlowError ? [] : agents ?? [];
|
|
81
95
|
try {
|
|
82
96
|
if (args.approver === undefined) {
|
|
83
97
|
throw new CloudFlowError('invalid_input', '--approver <handle> is required: every launched run receives it as input.approver for f.human.');
|
|
84
98
|
}
|
|
99
|
+
if (agents instanceof CloudFlowError)
|
|
100
|
+
throw agents;
|
|
101
|
+
const connect = cliConnectPrompt(io, { noConnect: args.noConnect, json: args.json });
|
|
102
|
+
if (agents === undefined)
|
|
103
|
+
harnesses = (await flowRequirementsForPath(args.value))?.harnesses ?? [];
|
|
85
104
|
const deployment = await deployToCloud({
|
|
86
105
|
path: args.value,
|
|
87
106
|
repository: parseRepository(args.repo),
|
|
@@ -89,7 +108,8 @@ export async function runCloudDeployCli(args, io) {
|
|
|
89
108
|
approver: args.approver,
|
|
90
109
|
draft: args.draft,
|
|
91
110
|
...(args.name === undefined ? {} : { name: args.name }),
|
|
92
|
-
...(
|
|
111
|
+
...(agents === undefined ? {} : { agents }),
|
|
112
|
+
...(connect === undefined ? {} : { connect }),
|
|
93
113
|
});
|
|
94
114
|
if (args.json) {
|
|
95
115
|
io.stdout(JSON.stringify({ ok: true, ...deployment }));
|
|
@@ -100,13 +120,28 @@ export async function runCloudDeployCli(args, io) {
|
|
|
100
120
|
io.stdout(` repository: ${deployment.repository.owner}/${deployment.repository.name}`);
|
|
101
121
|
for (const source of deployment.sources)
|
|
102
122
|
io.stdout(` on: ${describeSource(source)}`);
|
|
123
|
+
const requires = describeFlowRequirements(deployment.requirements);
|
|
124
|
+
if (requires)
|
|
125
|
+
io.stdout(` requires: ${requires}`);
|
|
126
|
+
for (const provider of deployment.connected)
|
|
127
|
+
io.stdout(` connected: ${provider}`);
|
|
103
128
|
io.stdout(deployment.status === 'draft'
|
|
104
129
|
? 'Saved without activating; activate it from the Cloud dashboard, or redeploy without --draft.'
|
|
105
130
|
: 'Each matching ticket launches a run of this source in a fresh branch; list with: flows deployments');
|
|
106
131
|
return 0;
|
|
107
132
|
}
|
|
108
133
|
catch (error) {
|
|
109
|
-
return reportCloudFailure(error, args.json, io);
|
|
134
|
+
return reportCloudFailure(error, args.json, io, harnesses);
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
function parseAgentHarnessesOr(value) {
|
|
138
|
+
try {
|
|
139
|
+
return parseAgentHarnesses(value);
|
|
140
|
+
}
|
|
141
|
+
catch (error) {
|
|
142
|
+
if (error instanceof CloudFlowError)
|
|
143
|
+
return error;
|
|
144
|
+
throw error;
|
|
110
145
|
}
|
|
111
146
|
}
|
|
112
147
|
export async function runCloudDeploymentsCli({ json }, io) {
|
|
@@ -142,9 +177,11 @@ export async function runCloudUndeployCli({ agentId, json }, io) {
|
|
|
142
177
|
return reportCloudFailure(error, json, io);
|
|
143
178
|
}
|
|
144
179
|
}
|
|
145
|
-
function reportCloudFailure(error, json, io) {
|
|
180
|
+
function reportCloudFailure(error, json, io, harnesses = []) {
|
|
146
181
|
const code = error instanceof CloudFlowError ? error.code : 'cloud_deploy_failed';
|
|
147
182
|
let message = error instanceof Error ? error.message : 'Cloud deploy failed.';
|
|
183
|
+
// Cloud names the missing coding-agent credential on activation; say how it is connected.
|
|
184
|
+
message += harnessRemedy(error, harnesses);
|
|
148
185
|
// The deploy routes take a browser session or a `cli:auth` token. A
|
|
149
186
|
// deployment (CI) token gets 403 `session_required`; say what fixes it.
|
|
150
187
|
if (error instanceof CloudFlowError && error.status === 403) {
|
|
@@ -156,7 +193,8 @@ function reportCloudFailure(error, json, io) {
|
|
|
156
193
|
else
|
|
157
194
|
io.stderr(`${code}: ${message}`);
|
|
158
195
|
return error instanceof CloudFlowError
|
|
159
|
-
&& (['configuration', 'unsupported_source', 'invalid_input'].includes(error.code)
|
|
196
|
+
&& (['configuration', 'unsupported_source', 'invalid_input', 'integration_not_connected'].includes(error.code)
|
|
197
|
+
|| error.status === 403 || error.status === 401)
|
|
160
198
|
? 2 : 1;
|
|
161
199
|
}
|
|
162
200
|
//# sourceMappingURL=cloud-deploy.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cloud-deploy.js","sourceRoot":"","sources":["../../src/cli/cloud-deploy.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAClD,OAAO,EACL,aAAa,EAAE,oBAAoB,EAAE,mBAAmB,EAAE,eAAe,EAAE,kBAAkB,EAAE,iBAAiB,GAEjH,MAAM,oBAAoB,CAAC;
|
|
1
|
+
{"version":3,"file":"cloud-deploy.js","sourceRoot":"","sources":["../../src/cli/cloud-deploy.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAClD,OAAO,EACL,aAAa,EAAE,oBAAoB,EAAE,mBAAmB,EAAE,eAAe,EAAE,kBAAkB,EAAE,iBAAiB,GAEjH,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EAAE,wBAAwB,EAAE,MAAM,yBAAyB,CAAC;AACnE,OAAO,EAAE,gBAAgB,EAAE,uBAAuB,EAAE,aAAa,EAAE,MAAM,wBAAwB,CAAC;AAiBlG;;;;;;;GAOG;AACH,MAAM,UAAU,oBAAoB,CAAC,IAAuB;IAC1D,IAAI,KAAyB,CAAC;IAC9B,IAAI,IAAwB,CAAC;IAC7B,IAAI,QAA4B,CAAC;IACjC,IAAI,IAAwB,CAAC;IAC7B,IAAI,MAA0B,CAAC;IAC/B,IAAI,KAAK,GAAG,KAAK,CAAC;IAClB,IAAI,SAAS,GAAG,KAAK,CAAC;IACtB,IAAI,IAAI,GAAG,KAAK,CAAC;IACjB,MAAM,EAAE,GAAa,EAAE,CAAC;IACxB,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QACrC,MAAM,GAAG,GAAG,IAAI,CAAC,CAAC,CAAE,CAAC;QACrB,IAAI,GAAG,KAAK,QAAQ,EAAE,CAAC;YACrB,IAAI,IAAI;gBAAE,OAAO,SAAS,CAAC;YAC3B,IAAI,GAAG,IAAI,CAAC;YACZ,SAAS;QACX,CAAC;QACD,IAAI,GAAG,KAAK,SAAS,EAAE,CAAC;YACtB,IAAI,KAAK;gBAAE,OAAO,SAAS,CAAC;YAC5B,KAAK,GAAG,IAAI,CAAC;YACb,SAAS;QACX,CAAC;QACD,IAAI,GAAG,KAAK,cAAc,EAAE,CAAC;YAC3B,IAAI,SAAS;gBAAE,OAAO,SAAS,CAAC;YAChC,SAAS,GAAG,IAAI,CAAC;YACjB,SAAS;QACX,CAAC;QACD,IAAI,GAAG,KAAK,UAAU,EAAE,CAAC;YACvB,MAAM,IAAI,GAAG,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;YACzB,IAAI,MAAM,KAAK,SAAS,IAAI,IAAI,KAAK,SAAS,IAAI,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC;gBAAE,OAAO,SAAS,CAAC;YACzF,MAAM,GAAG,IAAI,CAAC;YACd,CAAC,IAAI,CAAC,CAAC;YACP,SAAS;QACX,CAAC;QACD,IAAI,GAAG,KAAK,QAAQ,IAAI,GAAG,KAAK,YAAY,IAAI,GAAG,KAAK,QAAQ,IAAI,GAAG,KAAK,MAAM,EAAE,CAAC;YACnF,MAAM,IAAI,GAAG,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;YACzB,IAAI,IAAI,KAAK,SAAS,IAAI,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC;gBAAE,OAAO,SAAS,CAAC;YACjE,CAAC,IAAI,CAAC,CAAC;YACP,IAAI,GAAG,KAAK,MAAM,EAAE,CAAC;gBAAC,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;gBAAC,SAAS;YAAC,CAAC;YAChD,IAAI,GAAG,KAAK,QAAQ,EAAE,CAAC;gBAAC,IAAI,IAAI,KAAK,SAAS;oBAAE,OAAO,SAAS,CAAC;gBAAC,IAAI,GAAG,IAAI,CAAC;gBAAC,SAAS;YAAC,CAAC;YAC1F,IAAI,GAAG,KAAK,YAAY,EAAE,CAAC;gBAAC,IAAI,QAAQ,KAAK,SAAS;oBAAE,OAAO,SAAS,CAAC;gBAAC,QAAQ,GAAG,IAAI,CAAC;gBAAC,SAAS;YAAC,CAAC;YACtG,IAAI,IAAI,KAAK,SAAS;gBAAE,OAAO,SAAS,CAAC;YACzC,IAAI,GAAG,IAAI,CAAC;YACZ,SAAS;QACX,CAAC;QACD,IAAI,GAAG,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,KAAK,KAAK,SAAS;YAAE,OAAO,SAAS,CAAC;QACjE,KAAK,GAAG,GAAG,CAAC;IACd,CAAC;IACD,IAAI,KAAK,KAAK,SAAS,IAAI,IAAI,KAAK,SAAS,IAAI,EAAE,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,SAAS,CAAC;IACnF,OAAO,EAAE,OAAO,EAAE,cAAc,EAAE,KAAK,EAAE,IAAI,EAAE,EAAE,EAAE,QAAQ,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC;AACtG,CAAC;AAED,SAAS,cAAc,CAAC,MAAyB;IAC/C,MAAM,QAAQ,GAAG,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IACxF,OAAO,QAAQ,CAAC,CAAC,CAAC,GAAG,MAAM,CAAC,QAAQ,IAAI,QAAQ,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,QAAQ,CAAC;AACvE,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,iBAAiB,CAAC,IAAqB,EAAE,EAAS;IACtE,MAAM,MAAM,GAAG,IAAI,CAAC,MAAM,KAAK,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,qBAAqB,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;IAC1F,wEAAwE;IACxE,2EAA2E;IAC3E,8BAA8B;IAC9B,IAAI,SAAS,GAAsB,MAAM,YAAY,cAAc,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,IAAI,EAAE,CAAC;IACxF,IAAI,CAAC;QACH,IAAI,IAAI,CAAC,QAAQ,KAAK,SAAS,EAAE,CAAC;YAChC,MAAM,IAAI,cAAc,CAAC,eAAe,EACtC,gGAAgG,CAAC,CAAC;QACtG,CAAC;QACD,IAAI,MAAM,YAAY,cAAc;YAAE,MAAM,MAAM,CAAC;QACnD,MAAM,OAAO,GAAG,gBAAgB,CAAC,EAAE,EAAE,EAAE,SAAS,EAAE,IAAI,CAAC,SAAS,EAAE,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC;QACrF,IAAI,MAAM,KAAK,SAAS;YAAE,SAAS,GAAG,CAAC,MAAM,uBAAuB,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,SAAS,IAAI,EAAE,CAAC;QACnG,MAAM,UAAU,GAAG,MAAM,aAAa,CAAC;YACrC,IAAI,EAAE,IAAI,CAAC,KAAK;YAChB,UAAU,EAAE,eAAe,CAAC,IAAI,CAAC,IAAI,CAAC;YACtC,OAAO,EAAE,IAAI,CAAC,EAAE,CAAC,GAAG,CAAC,kBAAkB,CAAC;YACxC,QAAQ,EAAE,IAAI,CAAC,QAAQ;YACvB,KAAK,EAAE,IAAI,CAAC,KAAK;YACjB,GAAG,CAAC,IAAI,CAAC,IAAI,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE,CAAC;YACvD,GAAG,CAAC,MAAM,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC;YAC3C,GAAG,CAAC,OAAO,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,CAAC;SAC9C,CAAC,CAAC;QACH,IAAI,IAAI,CAAC,IAAI,EAAE,CAAC;YACd,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE,EAAE,EAAE,IAAI,EAAE,GAAG,UAAU,EAAE,CAAC,CAAC,CAAC;YACvD,OAAO,CAAC,CAAC;QACX,CAAC;QACD,EAAE,CAAC,MAAM,CAAC,GAAG,UAAU,CAAC,MAAM,KAAK,OAAO,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,UAAU,IAAI,UAAU,CAAC,OAAO,IAAI,UAAU,CAAC,MAAM,EAAE,CAAC,CAAC;QAChH,EAAE,CAAC,MAAM,CAAC,WAAW,UAAU,CAAC,IAAI,KAAK,IAAI,CAAC,KAAK,YAAY,UAAU,CAAC,YAAY,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,GAAG,CAAC,CAAC;QACxG,EAAE,CAAC,MAAM,CAAC,iBAAiB,UAAU,CAAC,UAAU,CAAC,KAAK,IAAI,UAAU,CAAC,UAAU,CAAC,IAAI,EAAE,CAAC,CAAC;QACxF,KAAK,MAAM,MAAM,IAAI,UAAU,CAAC,OAAO;YAAE,EAAE,CAAC,MAAM,CAAC,SAAS,cAAc,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;QACtF,MAAM,QAAQ,GAAG,wBAAwB,CAAC,UAAU,CAAC,YAAY,CAAC,CAAC;QACnE,IAAI,QAAQ;YAAE,EAAE,CAAC,MAAM,CAAC,eAAe,QAAQ,EAAE,CAAC,CAAC;QACnD,KAAK,MAAM,QAAQ,IAAI,UAAU,CAAC,SAAS;YAAE,EAAE,CAAC,MAAM,CAAC,gBAAgB,QAAQ,EAAE,CAAC,CAAC;QACnF,EAAE,CAAC,MAAM,CAAC,UAAU,CAAC,MAAM,KAAK,OAAO;YACrC,CAAC,CAAC,8FAA8F;YAChG,CAAC,CAAC,oGAAoG,CAAC,CAAC;QAC1G,OAAO,CAAC,CAAC;IACX,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,OAAO,kBAAkB,CAAC,KAAK,EAAE,IAAI,CAAC,IAAI,EAAE,EAAE,EAAE,SAAS,CAAC,CAAC;IAC7D,CAAC;AACH,CAAC;AAED,SAAS,qBAAqB,CAAC,KAAa;IAC1C,IAAI,CAAC;QACH,OAAO,mBAAmB,CAAC,KAAK,CAAC,CAAC;IACpC,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,IAAI,KAAK,YAAY,cAAc;YAAE,OAAO,KAAK,CAAC;QAClD,MAAM,KAAK,CAAC;IACd,CAAC;AACH,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,sBAAsB,CAAC,EAAE,IAAI,EAAqB,EAAE,EAAS;IACjF,IAAI,CAAC;QACH,MAAM,WAAW,GAAG,MAAM,oBAAoB,EAAE,CAAC;QACjD,IAAI,IAAI,EAAE,CAAC;YACT,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE,EAAE,EAAE,IAAI,EAAE,WAAW,EAAE,CAAC,CAAC,CAAC;YACrD,OAAO,CAAC,CAAC;QACX,CAAC;QACD,IAAI,WAAW,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YAC7B,EAAE,CAAC,MAAM,CAAC,wCAAwC,CAAC,CAAC;YACpD,OAAO,CAAC,CAAC;QACX,CAAC;QACD,KAAK,MAAM,CAAC,IAAI,WAAW,EAAE,CAAC;YAC5B,MAAM,IAAI,GAAG,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,UAAU,CAAC,KAAK,IAAI,CAAC,CAAC,UAAU,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;YAC/E,EAAE,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,OAAO,IAAI,CAAC,CAAC,MAAM,IAAI,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,IAAI,EAAE,CAAC,CAAC;YACvE,KAAK,MAAM,MAAM,IAAI,CAAC,CAAC,OAAO;gBAAE,EAAE,CAAC,MAAM,CAAC,SAAS,cAAc,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;QAC/E,CAAC;QACD,OAAO,CAAC,CAAC;IACX,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,OAAO,kBAAkB,CAAC,KAAK,EAAE,IAAI,EAAE,EAAE,CAAC,CAAC;IAC7C,CAAC;AACH,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,mBAAmB,CAAC,EAAE,OAAO,EAAE,IAAI,EAAsC,EAAE,EAAS;IACxG,IAAI,CAAC;QACH,MAAM,iBAAiB,CAAC,OAAO,CAAC,CAAC;QACjC,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE,EAAE,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,cAAc,OAAO,EAAE,CAAC,CAAC;QACrG,OAAO,CAAC,CAAC;IACX,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,OAAO,kBAAkB,CAAC,KAAK,EAAE,IAAI,EAAE,EAAE,CAAC,CAAC;IAC7C,CAAC;AACH,CAAC;AAED,SAAS,kBAAkB,CAAC,KAAc,EAAE,IAAa,EAAE,EAAS,EAAE,YAA+B,EAAE;IACrG,MAAM,IAAI,GAAG,KAAK,YAAY,cAAc,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,qBAAqB,CAAC;IAClF,IAAI,OAAO,GAAG,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,sBAAsB,CAAC;IAC9E,0FAA0F;IAC1F,OAAO,IAAI,aAAa,CAAC,KAAK,EAAE,SAAS,CAAC,CAAC;IAC3C,oEAAoE;IACpE,wEAAwE;IACxE,IAAI,KAAK,YAAY,cAAc,IAAI,KAAK,CAAC,MAAM,KAAK,GAAG,EAAE,CAAC;QAC5D,OAAO,IAAI,uFAAuF;cAC9F,yDAAyD,CAAC;IAChE,CAAC;IACD,IAAI,IAAI;QAAE,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC,CAAC,CAAC;;QAC7D,EAAE,CAAC,MAAM,CAAC,GAAG,IAAI,KAAK,OAAO,EAAE,CAAC,CAAC;IACtC,OAAO,KAAK,YAAY,cAAc;WACjC,CAAC,CAAC,eAAe,EAAE,oBAAoB,EAAE,eAAe,EAAE,2BAA2B,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,IAAI,CAAC;eACzG,KAAK,CAAC,MAAM,KAAK,GAAG,IAAI,KAAK,CAAC,MAAM,KAAK,GAAG,CAAC;QAClD,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;AACZ,CAAC"}
|
package/dist/cli/cloud-run.d.ts
CHANGED
|
@@ -1,10 +1,17 @@
|
|
|
1
1
|
import type { CliIo } from '../cli.js';
|
|
2
2
|
/** Presentation only: the central CLI parser owns argv; the SDK owns the lifecycle. */
|
|
3
|
-
export declare function runCloudCli({ value: path, json, wait, input, syncCode }: {
|
|
3
|
+
export declare function runCloudCli({ value: path, json, wait, input, syncCode, noConnect }: {
|
|
4
4
|
value: string;
|
|
5
5
|
json: boolean;
|
|
6
6
|
wait: boolean;
|
|
7
7
|
input: string | undefined;
|
|
8
8
|
syncCode: boolean;
|
|
9
|
-
|
|
9
|
+
noConnect?: boolean;
|
|
10
|
+
}, io: CliIo,
|
|
11
|
+
/**
|
|
12
|
+
* Cancellation, owned by the caller. `runCli` supplies either the embedder's
|
|
13
|
+
* signal or one it drives from SIGINT/SIGTERM itself, so no process-wide
|
|
14
|
+
* handler is installed here.
|
|
15
|
+
*/
|
|
16
|
+
signal: AbortSignal): Promise<0 | 1 | 2>;
|
|
10
17
|
//# sourceMappingURL=cloud-run.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cloud-run.d.ts","sourceRoot":"","sources":["../../src/cli/cloud-run.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"cloud-run.d.ts","sourceRoot":"","sources":["../../src/cli/cloud-run.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,WAAW,CAAC;AAEvC,uFAAuF;AACvF,wBAAsB,WAAW,CAC/B,EAAE,KAAK,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,QAAQ,EAAE,SAAiB,EAAE,EAAE;IAC/D,KAAK,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,OAAO,CAAC;IAAC,IAAI,EAAE,OAAO,CAAC;IAAC,KAAK,EAAE,MAAM,GAAG,SAAS,CAAC;IAAC,QAAQ,EAAE,OAAO,CAAC;IAAC,SAAS,CAAC,EAAE,OAAO,CAAC;CAChH,EACD,EAAE,EAAE,KAAK;AACT;;;;GAIG;AACH,MAAM,EAAE,WAAW,GAClB,OAAO,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAqEpB"}
|
package/dist/cli/cloud-run.js
CHANGED
|
@@ -2,19 +2,23 @@ import { CloudFlowError } from '../cloud-http.js';
|
|
|
2
2
|
import { runInCloud, waitForCloudFlowRun } from '../cloud-run.js';
|
|
3
3
|
import { DirectInputError, isAuthoredFlowPath, parseDirectInput } from '../direct-input.js';
|
|
4
4
|
import { snapshotJsonValue } from '../json-value.js';
|
|
5
|
+
import { cliConnectPrompt, ensureFlowConnections, harnessRemedy } from './cloud-connect-cli.js';
|
|
5
6
|
/** Presentation only: the central CLI parser owns argv; the SDK owns the lifecycle. */
|
|
6
|
-
export async function runCloudCli({ value: path, json, wait, input, syncCode }, io
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
7
|
+
export async function runCloudCli({ value: path, json, wait, input, syncCode, noConnect = false }, io,
|
|
8
|
+
/**
|
|
9
|
+
* Cancellation, owned by the caller. `runCli` supplies either the embedder's
|
|
10
|
+
* signal or one it drives from SIGINT/SIGTERM itself, so no process-wide
|
|
11
|
+
* handler is installed here.
|
|
12
|
+
*/
|
|
13
|
+
signal) {
|
|
11
14
|
let runId;
|
|
12
15
|
// Flips at the run submission. An interruption before it — during prepare,
|
|
13
16
|
// packing or upload — admitted nothing and is safe to retry; only an
|
|
14
17
|
// interrupted submission has unknown admission.
|
|
15
18
|
let submitting = false;
|
|
19
|
+
let harnesses = [];
|
|
16
20
|
try {
|
|
17
|
-
const options = { signal
|
|
21
|
+
const options = { signal, onSubmit: () => { submitting = true; } };
|
|
18
22
|
if (isAuthoredFlowPath(path)) {
|
|
19
23
|
// Same parse as a local direct run, so a file-or-inline argument means
|
|
20
24
|
// the same thing on both sides of `--cloud`.
|
|
@@ -27,6 +31,17 @@ export async function runCloudCli({ value: path, json, wait, input, syncCode },
|
|
|
27
31
|
throw error;
|
|
28
32
|
}
|
|
29
33
|
}
|
|
34
|
+
// After local validation, before anything is packed or uploaded: a helper
|
|
35
|
+
// the run would call against an unconnected integration is connected
|
|
36
|
+
// here, or refused here. A command that is going to be refused for its
|
|
37
|
+
// arguments must not first open a browser.
|
|
38
|
+
const connections = await ensureFlowConnections({
|
|
39
|
+
path, prompt: cliConnectPrompt(io, { noConnect, json }),
|
|
40
|
+
}, { signal });
|
|
41
|
+
harnesses = connections?.requirements.harnesses ?? [];
|
|
42
|
+
for (const provider of connections?.outcome.connected ?? [])
|
|
43
|
+
if (!json)
|
|
44
|
+
io.stdout(`CONNECTED ${provider}`);
|
|
30
45
|
// The tree is the invoking directory, as with v1: the flow path is where
|
|
31
46
|
// the body lives, not the boundary of what the run may read.
|
|
32
47
|
if (syncCode)
|
|
@@ -48,7 +63,7 @@ export async function runCloudCli({ value: path, json, wait, input, syncCode },
|
|
|
48
63
|
io.stdout(JSON.stringify({ ok: true, ...receipt }));
|
|
49
64
|
return 0;
|
|
50
65
|
}
|
|
51
|
-
const run = await waitForCloudFlowRun(receipt.runId, { signal
|
|
66
|
+
const run = await waitForCloudFlowRun(receipt.runId, { signal });
|
|
52
67
|
const ok = run.status === 'completed';
|
|
53
68
|
if (json)
|
|
54
69
|
io.stdout(JSON.stringify({ ok, ...receipt, ...run }));
|
|
@@ -57,26 +72,23 @@ export async function runCloudCli({ value: path, json, wait, input, syncCode },
|
|
|
57
72
|
return ok ? 0 : 1;
|
|
58
73
|
}
|
|
59
74
|
catch (error) {
|
|
60
|
-
const code =
|
|
75
|
+
const code = signal.aborted
|
|
61
76
|
? runId ? 'observation_aborted' : submitting ? 'admission_unknown' : 'submission_aborted'
|
|
62
77
|
: error instanceof CloudFlowError ? error.code : 'cloud_run_failed';
|
|
63
|
-
const message =
|
|
78
|
+
const message = signal.aborted
|
|
64
79
|
? runId ? 'Stopped observing; the hosted run has not been cancelled.'
|
|
65
80
|
: submitting
|
|
66
81
|
? 'Submission interrupted before a receipt was received. Admission is unknown; Cloud may have started the run. Do not resubmit blindly.'
|
|
67
82
|
: 'Interrupted before the run was submitted; nothing was admitted. Safe to run again.'
|
|
68
|
-
: error instanceof Error ? error.message : 'Cloud run failed.';
|
|
83
|
+
: (error instanceof Error ? error.message : 'Cloud run failed.') + harnessRemedy(error, harnesses);
|
|
69
84
|
if (json)
|
|
70
85
|
io.stdout(JSON.stringify({ ok: false, code, message, ...(runId ? { runId } : {}) }));
|
|
71
86
|
else
|
|
72
87
|
io.stderr(`${code}: ${message}${runId ? ` (run ${runId})` : ''}`);
|
|
73
88
|
return error instanceof CloudFlowError
|
|
74
|
-
&& (['configuration', 'unsupported_source', 'invalid_input', 'unsupported_storage_backend', 'sync_too_large', 'sync_unsupported'
|
|
89
|
+
&& (['configuration', 'unsupported_source', 'invalid_input', 'unsupported_storage_backend', 'sync_too_large', 'sync_unsupported',
|
|
90
|
+
'integration_not_connected'].includes(error.code)
|
|
75
91
|
|| (runId === undefined && error.code === 'http_error' && [401, 403].includes(error.status ?? 0))) ? 2 : 1;
|
|
76
92
|
}
|
|
77
|
-
finally {
|
|
78
|
-
process.off('SIGINT', abort);
|
|
79
|
-
process.off('SIGTERM', abort);
|
|
80
|
-
}
|
|
81
93
|
}
|
|
82
94
|
//# sourceMappingURL=cloud-run.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cloud-run.js","sourceRoot":"","sources":["../../src/cli/cloud-run.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAClD,OAAO,EAAE,UAAU,EAAE,mBAAmB,EAA0B,MAAM,iBAAiB,CAAC;AAC1F,OAAO,EAAE,gBAAgB,EAAE,kBAAkB,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AAC5F,OAAO,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;
|
|
1
|
+
{"version":3,"file":"cloud-run.js","sourceRoot":"","sources":["../../src/cli/cloud-run.ts"],"names":[],"mappings":"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"}
|
|
@@ -7,11 +7,13 @@ export interface CloudScheduleArgs {
|
|
|
7
7
|
tz: string | undefined;
|
|
8
8
|
input: string | undefined;
|
|
9
9
|
name: string | undefined;
|
|
10
|
+
/** Refuse a missing integration instead of offering to connect it. */
|
|
11
|
+
noConnect: boolean;
|
|
10
12
|
json: boolean;
|
|
11
13
|
}
|
|
12
14
|
/**
|
|
13
15
|
* `flows schedule <flow.yaml|flow.ts> [--cron "<expr>" | --every <n><s|m|h|d>]
|
|
14
|
-
* [--tz <IANA>] [--input <json|file>] [--name <n>] [--json]`
|
|
16
|
+
* [--tz <IANA>] [--input <json|file>] [--name <n>] [--no-connect] [--json]`
|
|
15
17
|
*
|
|
16
18
|
* With neither `--cron` nor `--every`, the flow's own `schedule.*` handler
|
|
17
19
|
* supplies the cron, so a declared schedule and its hosted registration
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cloud-schedule.d.ts","sourceRoot":"","sources":["../../src/cli/cloud-schedule.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"cloud-schedule.d.ts","sourceRoot":"","sources":["../../src/cli/cloud-schedule.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,WAAW,CAAC;AAEvC,MAAM,WAAW,iBAAiB;IAChC,OAAO,EAAE,UAAU,CAAC;IACpB,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,GAAG,SAAS,CAAC;IACzB,KAAK,EAAE,MAAM,GAAG,SAAS,CAAC;IAC1B,EAAE,EAAE,MAAM,GAAG,SAAS,CAAC;IACvB,KAAK,EAAE,MAAM,GAAG,SAAS,CAAC;IAC1B,IAAI,EAAE,MAAM,GAAG,SAAS,CAAC;IACzB,sEAAsE;IACtE,SAAS,EAAE,OAAO,CAAC;IACnB,IAAI,EAAE,OAAO,CAAC;CACf;AAED;;;;;;;GAOG;AACH,wBAAgB,sBAAsB,CAAC,IAAI,EAAE,SAAS,MAAM,EAAE,GAAG,iBAAiB,GAAG,SAAS,CAmC7F;AAQD,wBAAsB,mBAAmB,CAAC,IAAI,EAAE,iBAAiB,EAAE,EAAE,EAAE,KAAK,GAAG,OAAO,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CA6ChG;AAED,wBAAsB,oBAAoB,CAAC,EAAE,IAAI,EAAE,EAAE;IAAE,IAAI,EAAE,OAAO,CAAA;CAAE,EAAE,EAAE,EAAE,KAAK,GAAG,OAAO,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAarG;AAED,wBAAsB,qBAAqB,CACzC,EAAE,UAAU,EAAE,IAAI,EAAE,EAAE;IAAE,UAAU,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,OAAO,CAAA;CAAE,EAAE,EAAE,EAAE,KAAK,GACrE,OAAO,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAQpB"}
|
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
import { CloudFlowError } from '../cloud-http.js';
|
|
2
|
-
import { listCloudSchedules, scheduleInCloud, unscheduleInCloud } from '../cloud-schedule.js';
|
|
2
|
+
import { listCloudSchedules, scheduleInCloud, unscheduleInCloud, validateScheduleArgs } from '../cloud-schedule.js';
|
|
3
3
|
import { DirectInputError, isAuthoredFlowPath, parseDirectInput } from '../direct-input.js';
|
|
4
4
|
import { snapshotJsonValue } from '../json-value.js';
|
|
5
|
+
import { cliConnectPrompt, ensureFlowConnections, harnessRemedy } from './cloud-connect-cli.js';
|
|
5
6
|
/**
|
|
6
7
|
* `flows schedule <flow.yaml|flow.ts> [--cron "<expr>" | --every <n><s|m|h|d>]
|
|
7
|
-
* [--tz <IANA>] [--input <json|file>] [--name <n>] [--json]`
|
|
8
|
+
* [--tz <IANA>] [--input <json|file>] [--name <n>] [--no-connect] [--json]`
|
|
8
9
|
*
|
|
9
10
|
* With neither `--cron` nor `--every`, the flow's own `schedule.*` handler
|
|
10
11
|
* supplies the cron, so a declared schedule and its hosted registration
|
|
@@ -16,6 +17,7 @@ export function parseCloudScheduleArgs(args) {
|
|
|
16
17
|
cron: undefined, every: undefined, tz: undefined, input: undefined, name: undefined,
|
|
17
18
|
};
|
|
18
19
|
let json = false;
|
|
20
|
+
let noConnect = false;
|
|
19
21
|
for (let i = 0; i < args.length; i++) {
|
|
20
22
|
const arg = args[i];
|
|
21
23
|
if (arg === '--json') {
|
|
@@ -24,6 +26,12 @@ export function parseCloudScheduleArgs(args) {
|
|
|
24
26
|
json = true;
|
|
25
27
|
continue;
|
|
26
28
|
}
|
|
29
|
+
if (arg === '--no-connect') {
|
|
30
|
+
if (noConnect)
|
|
31
|
+
return undefined;
|
|
32
|
+
noConnect = true;
|
|
33
|
+
continue;
|
|
34
|
+
}
|
|
27
35
|
if (arg === '--cron' || arg === '--every' || arg === '--tz' || arg === '--input' || arg === '--name') {
|
|
28
36
|
const key = arg.slice(2);
|
|
29
37
|
const next = args[i + 1];
|
|
@@ -44,7 +52,7 @@ export function parseCloudScheduleArgs(args) {
|
|
|
44
52
|
return undefined;
|
|
45
53
|
if (flags.input !== undefined && !isAuthoredFlowPath(value))
|
|
46
54
|
return undefined;
|
|
47
|
-
return { command: 'schedule', value, ...flags, json };
|
|
55
|
+
return { command: 'schedule', value, ...flags, noConnect, json };
|
|
48
56
|
}
|
|
49
57
|
function describe(schedule) {
|
|
50
58
|
const last = schedule.lastTriggeredAt === undefined ? ''
|
|
@@ -52,6 +60,7 @@ function describe(schedule) {
|
|
|
52
60
|
return `${schedule.id} ${schedule.status} ${JSON.stringify(schedule.name)} cron "${schedule.cronExpression}" tz ${schedule.timezone}${last}`;
|
|
53
61
|
}
|
|
54
62
|
export async function runCloudScheduleCli(args, io) {
|
|
63
|
+
let harnesses = [];
|
|
55
64
|
try {
|
|
56
65
|
let input;
|
|
57
66
|
let inputPresent = false;
|
|
@@ -66,6 +75,18 @@ export async function runCloudScheduleCli(args, io) {
|
|
|
66
75
|
throw error;
|
|
67
76
|
}
|
|
68
77
|
}
|
|
78
|
+
validateScheduleArgs({
|
|
79
|
+
...(args.cron === undefined ? {} : { cron: args.cron }),
|
|
80
|
+
...(args.every === undefined ? {} : { every: args.every }),
|
|
81
|
+
...(args.tz === undefined ? {} : { tz: args.tz }),
|
|
82
|
+
});
|
|
83
|
+
// Each fire runs the flow as this workspace, so what it needs connected
|
|
84
|
+
// is checked once here — after the arguments are known to be good, so a
|
|
85
|
+
// refused command never opens a browser first — and before the schedule exists.
|
|
86
|
+
const connections = await ensureFlowConnections({
|
|
87
|
+
path: args.value, prompt: cliConnectPrompt(io, { noConnect: args.noConnect, json: args.json }),
|
|
88
|
+
});
|
|
89
|
+
harnesses = connections?.requirements.harnesses ?? [];
|
|
69
90
|
const schedule = await scheduleInCloud({
|
|
70
91
|
flow: { path: args.value },
|
|
71
92
|
...(args.cron === undefined ? {} : { cron: args.cron }),
|
|
@@ -79,11 +100,13 @@ export async function runCloudScheduleCli(args, io) {
|
|
|
79
100
|
return 0;
|
|
80
101
|
}
|
|
81
102
|
io.stdout(`SCHEDULED ${describe(schedule)}`);
|
|
103
|
+
for (const provider of connections?.outcome.connected ?? [])
|
|
104
|
+
io.stdout(` connected: ${provider}`);
|
|
82
105
|
io.stdout('Each fire submits this exact source through the same admission as flows run --cloud; list with: flows schedules');
|
|
83
106
|
return 0;
|
|
84
107
|
}
|
|
85
108
|
catch (error) {
|
|
86
|
-
return reportFailure(error, args.json, io);
|
|
109
|
+
return reportFailure(error, args.json, io, harnesses);
|
|
87
110
|
}
|
|
88
111
|
}
|
|
89
112
|
export async function runCloudSchedulesCli({ json }, io) {
|
|
@@ -113,9 +136,10 @@ export async function runCloudUnscheduleCli({ scheduleId, json }, io) {
|
|
|
113
136
|
return reportFailure(error, json, io);
|
|
114
137
|
}
|
|
115
138
|
}
|
|
116
|
-
function reportFailure(error, json, io) {
|
|
139
|
+
function reportFailure(error, json, io, harnesses = []) {
|
|
117
140
|
const code = error instanceof CloudFlowError ? error.code : 'cloud_schedule_failed';
|
|
118
141
|
let message = error instanceof Error ? error.message : 'Cloud schedule failed.';
|
|
142
|
+
message += harnessRemedy(error, harnesses);
|
|
119
143
|
// The schedule routes take a browser session or a `cli:auth` token.
|
|
120
144
|
if (error instanceof CloudFlowError && error.status === 403) {
|
|
121
145
|
message += ' Scheduling needs an interactive `cli:auth` credential: run `agent-relay cloud login`.';
|
|
@@ -125,7 +149,8 @@ function reportFailure(error, json, io) {
|
|
|
125
149
|
else
|
|
126
150
|
io.stderr(`${code}: ${message}`);
|
|
127
151
|
return error instanceof CloudFlowError
|
|
128
|
-
&& (['configuration', 'unsupported_source', 'invalid_input'].includes(error.code)
|
|
152
|
+
&& (['configuration', 'unsupported_source', 'invalid_input', 'integration_not_connected'].includes(error.code)
|
|
153
|
+
|| error.status === 403 || error.status === 401)
|
|
129
154
|
? 2 : 1;
|
|
130
155
|
}
|
|
131
156
|
//# sourceMappingURL=cloud-schedule.js.map
|