@relayflows/sdk 2.0.14 → 2.0.16
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/agent-artifacts.d.ts +20 -0
- package/dist/agent-artifacts.d.ts.map +1 -0
- package/dist/agent-artifacts.js +81 -0
- package/dist/agent-artifacts.js.map +1 -0
- package/dist/authored-flow-executor.d.ts +33 -3
- package/dist/authored-flow-executor.d.ts.map +1 -1
- package/dist/authored-flow-executor.js +56 -10
- package/dist/authored-flow-executor.js.map +1 -1
- package/dist/authored-node-runner.d.ts.map +1 -1
- package/dist/authored-node-runner.js +11 -4
- package/dist/authored-node-runner.js.map +1 -1
- package/dist/authored-root.d.ts.map +1 -1
- package/dist/authored-root.js +2 -2
- package/dist/authored-root.js.map +1 -1
- package/dist/authored-step-output.d.ts +2 -0
- package/dist/authored-step-output.d.ts.map +1 -1
- package/dist/authored-step-output.js +5 -1
- package/dist/authored-step-output.js.map +1 -1
- package/dist/authored-worker-step.d.ts.map +1 -1
- package/dist/authored-worker-step.js +19 -1
- package/dist/authored-worker-step.js.map +1 -1
- package/dist/cli/check-triggers.d.ts.map +1 -1
- package/dist/cli/check-triggers.js +14 -3
- package/dist/cli/check-triggers.js.map +1 -1
- package/dist/cli/check.js +6 -1
- package/dist/cli/check.js.map +1 -1
- package/dist/cli/cloud-deploy.d.ts +30 -0
- package/dist/cli/cloud-deploy.d.ts.map +1 -0
- package/dist/cli/cloud-deploy.js +162 -0
- package/dist/cli/cloud-deploy.js.map +1 -0
- package/dist/cli/cloud-run.d.ts +3 -1
- package/dist/cli/cloud-run.d.ts.map +1 -1
- package/dist/cli/cloud-run.js +37 -5
- package/dist/cli/cloud-run.js.map +1 -1
- package/dist/cli/cloud-sync.d.ts +13 -0
- package/dist/cli/cloud-sync.d.ts.map +1 -0
- package/dist/cli/cloud-sync.js +39 -0
- package/dist/cli/cloud-sync.js.map +1 -0
- package/dist/cli/direct-run.d.ts.map +1 -1
- package/dist/cli/direct-run.js +2 -26
- package/dist/cli/direct-run.js.map +1 -1
- package/dist/cli/run.d.ts +20 -1
- package/dist/cli/run.d.ts.map +1 -1
- package/dist/cli/run.js +77 -15
- package/dist/cli/run.js.map +1 -1
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +82 -12
- package/dist/cli.js.map +1 -1
- package/dist/cloud-deploy.d.ts +70 -0
- package/dist/cloud-deploy.d.ts.map +1 -0
- package/dist/cloud-deploy.js +181 -0
- package/dist/cloud-deploy.js.map +1 -0
- package/dist/cloud-http.d.ts +37 -2
- package/dist/cloud-http.d.ts.map +1 -1
- package/dist/cloud-http.js +98 -8
- package/dist/cloud-http.js.map +1 -1
- package/dist/cloud-run.d.ts +23 -0
- package/dist/cloud-run.d.ts.map +1 -1
- package/dist/cloud-run.js +30 -1
- package/dist/cloud-run.js.map +1 -1
- package/dist/cloud-sync.d.ts +66 -0
- package/dist/cloud-sync.d.ts.map +1 -0
- package/dist/cloud-sync.js +287 -0
- package/dist/cloud-sync.js.map +1 -0
- package/dist/failure-kinds.d.ts +8 -1
- package/dist/failure-kinds.d.ts.map +1 -1
- package/dist/failure-kinds.js +8 -0
- package/dist/failure-kinds.js.map +1 -1
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -0
- package/dist/index.js.map +1 -1
- package/dist/provider-trigger-contract.d.ts +27 -0
- package/dist/provider-trigger-contract.d.ts.map +1 -0
- package/dist/provider-trigger-contract.js +0 -0
- package/dist/provider-trigger-contract.js.map +1 -0
- package/package.json +2 -2
- package/src/agent-artifacts.ts +76 -0
- package/src/authored-flow-executor.ts +77 -15
- package/src/authored-node-runner.ts +11 -4
- package/src/authored-root.ts +2 -2
- package/src/authored-step-output.ts +6 -1
- package/src/authored-worker-step.ts +19 -1
- package/src/cli/check-triggers.ts +14 -5
- package/src/cli/check.ts +6 -1
- package/src/cli/cloud-deploy.ts +157 -0
- package/src/cli/cloud-run.ts +37 -6
- package/src/cli/cloud-sync.ts +37 -0
- package/src/cli/direct-run.ts +2 -25
- package/src/cli/run.ts +86 -16
- package/src/cli.ts +75 -12
- package/src/cloud-deploy.ts +236 -0
- package/src/cloud-http.ts +129 -9
- package/src/cloud-run.ts +47 -1
- package/src/cloud-sync.ts +315 -0
- package/src/failure-kinds.ts +8 -0
- package/src/index.ts +8 -0
- package/src/provider-trigger-contract.ts +0 -0
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAIA,YAAY,EACV,aAAa,EACb,aAAa,EACb,YAAY,EACZ,UAAU,EACV,UAAU,EACV,gBAAgB,EAChB,qBAAqB,EACrB,YAAY,EACZ,QAAQ,EACR,YAAY,EACZ,kBAAkB,EAClB,gBAAgB,EAChB,SAAS,EACT,eAAe,EACf,cAAc,EACd,gBAAgB,EAChB,eAAe,EACf,mBAAmB,EACnB,gBAAgB,EAChB,uBAAuB,EACvB,aAAa,EACb,qBAAqB,EACrB,iBAAiB,EACjB,aAAa,EACb,gBAAgB,EAChB,cAAc,EACd,iBAAiB,EACjB,sBAAsB,EACtB,WAAW,EACX,cAAc,EACd,aAAa,EACb,mBAAmB,EACnB,cAAc,EACd,mBAAmB,EACnB,cAAc,EACd,kBAAkB,EAClB,aAAa,EACb,sBAAsB,EACtB,eAAe,EACf,YAAY,EACZ,aAAa,EACb,QAAQ,EACR,QAAQ,EACR,qBAAqB,EACrB,2BAA2B,EAC3B,WAAW,EACX,oBAAoB,EACpB,gBAAgB,EAChB,gBAAgB,GACjB,MAAM,WAAW,CAAC;AACnB,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AACnD,YAAY,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAChD,YAAY,EAAE,SAAS,EAAE,MAAM,eAAe,CAAC;AAC/C,OAAO,EAAE,mBAAmB,EAAE,MAAM,WAAW,CAAC;AAEhD,OAAO,EAAE,cAAc,EAAE,KAAK,sBAAsB,EAAE,MAAM,iBAAiB,CAAC;AAC9E,OAAO,EACL,UAAU,EAAE,eAAe,EAAE,mBAAmB,EAChD,KAAK,eAAe,EAAE,KAAK,iBAAiB,EAAE,KAAK,eAAe,EAAE,KAAK,aAAa,GACvF,MAAM,gBAAgB,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
package/dist/index.js
CHANGED
|
@@ -5,6 +5,8 @@ export { MODEL_PRICING } from './model-pricing.js';
|
|
|
5
5
|
export { SPEC_SCHEMA_VERSION } from './spec.js';
|
|
6
6
|
export { CloudFlowError } from './cloud-http.js';
|
|
7
7
|
export { runInCloud, getCloudFlowRun, waitForCloudFlowRun, } from './cloud-run.js';
|
|
8
|
+
export { downloadCloudPatch, applyCloudPatch, packWorkingTree, patchedPaths, MAX_SYNC_BYTES, } from './cloud-sync.js';
|
|
9
|
+
export { deployToCloud, listCloudDeployments, undeployFromCloud, parseRepository, parseTriggerSource, FLOW_TRIGGER_PROVIDERS, } from './cloud-deploy.js';
|
|
8
10
|
export { canonicalize, specHash } from './canonical.js';
|
|
9
11
|
export { compileAndHash, compileSpec, compileYaml, compileYamlToCanonicalJson, kernelToAuthoring, toKernelSpec, CompileError, } from './compile.js';
|
|
10
12
|
export { validateSpec } from './validate.js';
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,mEAAmE;AACnE,yEAAyE;AACzE,yBAAyB;AAqDzB,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AAGnD,OAAO,EAAE,mBAAmB,EAAE,MAAM,WAAW,CAAC;AAEhD,OAAO,EAAE,cAAc,EAA+B,MAAM,iBAAiB,CAAC;AAC9E,OAAO,EACL,UAAU,EAAE,eAAe,EAAE,mBAAmB,GAEjD,MAAM,gBAAgB,CAAC;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,mEAAmE;AACnE,yEAAyE;AACzE,yBAAyB;AAqDzB,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AAGnD,OAAO,EAAE,mBAAmB,EAAE,MAAM,WAAW,CAAC;AAEhD,OAAO,EAAE,cAAc,EAA+B,MAAM,iBAAiB,CAAC;AAC9E,OAAO,EACL,UAAU,EAAE,eAAe,EAAE,mBAAmB,GAEjD,MAAM,gBAAgB,CAAC;AACxB,OAAO,EACL,kBAAkB,EAAE,eAAe,EAAE,eAAe,EAAE,YAAY,EAAE,cAAc,GAEnF,MAAM,iBAAiB,CAAC;AACzB,OAAO,EACL,aAAa,EAAE,oBAAoB,EAAE,iBAAiB,EAAE,eAAe,EAAE,kBAAkB,EAAE,sBAAsB,GAEpH,MAAM,mBAAmB,CAAC;AAE3B,OAAO,EAAE,YAAY,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AACxD,OAAO,EACL,cAAc,EACd,WAAW,EACX,WAAW,EACX,0BAA0B,EAC1B,iBAAiB,EACjB,YAAY,EACZ,YAAY,GACb,MAAM,cAAc,CAAC;AACtB,OAAO,EAAE,YAAY,EAAyB,MAAM,eAAe,CAAC;AAEpE,OAAO,EACL,yBAAyB,GAG1B,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EACL,SAAS,EACT,gBAAgB,GAUjB,MAAM,gBAAgB,CAAC;AAMxB,OAAO,EACL,mBAAmB,EACnB,yBAAyB,EACzB,uBAAuB,EACvB,uBAAuB,EACvB,kBAAkB,GAInB,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EAAE,MAAM,EAA2D,MAAM,UAAU,CAAC;AA6C3F,OAAO,EAAE,oBAAoB,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAC;AAEvE,OAAO,EAAE,aAAa,EAA6B,MAAM,qBAAqB,CAAC;AAC/E,OAAO,EAAE,WAAW,EAA2B,MAAM,aAAa,CAAC;AAEnE,OAAO,EACL,mBAAmB,EACnB,gBAAgB,GAIjB,MAAM,qBAAqB,CAAC;AAE7B,OAAO,EACL,kBAAkB,GAInB,MAAM,4BAA4B,CAAC;AAEpC,OAAO,EACL,uBAAuB,GAIxB,MAAM,6BAA6B,CAAC;AAErC,iFAAiF;AACjF,OAAO,EACL,kBAAkB,EAClB,qBAAqB,EACrB,kBAAkB,GAInB,MAAM,gBAAgB,CAAC;AAExB,uEAAuE;AACvE,yEAAyE;AACzE,4EAA4E;AAC5E,2BAA2B;AAC3B,OAAO,EACL,iBAAiB,GAGlB,MAAM,yBAAyB,CAAC;AAEjC,2EAA2E;AAC3E,6EAA6E;AAC7E,oEAAoE;AACpE,gCAAgC;AAChC,OAAO,EACL,YAAY,EACZ,cAAc,EACd,aAAa,EACb,OAAO,EACP,aAAa,EACb,oBAAoB,EACpB,wBAAwB,EACxB,eAAe,GAMhB,MAAM,kBAAkB,CAAC;AAE1B,OAAO,EAAE,UAAU,EAA4C,MAAM,kBAAkB,CAAC;AAExF,OAAO,EAAE,cAAc,EAAsB,MAAM,eAAe,CAAC;AACnE,OAAO,EAAE,kBAAkB,EAAE,MAAM,uBAAuB,CAAC"}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { type TriggerSource } from '@relayflows/surface';
|
|
2
|
+
import type { PreflightRefusal } from './preflight.js';
|
|
3
|
+
export interface ProviderDeclaration {
|
|
4
|
+
/** The provider inbox this trigger routes to. */
|
|
5
|
+
readonly provider: string;
|
|
6
|
+
/** The event type the filter pinned. */
|
|
7
|
+
readonly type: string;
|
|
8
|
+
/** The event types that provider publishes. */
|
|
9
|
+
readonly events: readonly string[];
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* The provider subscription a trigger declares, or undefined when the source
|
|
13
|
+
* is not provably one. Reads only inert filter data; it never runs a handler.
|
|
14
|
+
*/
|
|
15
|
+
export declare function providerDeclaration(source: TriggerSource): ProviderDeclaration | undefined;
|
|
16
|
+
/**
|
|
17
|
+
* Pure declared-surface check over provider subscriptions, before opening a
|
|
18
|
+
* receiver or journal. The single refusal names a condition under which the
|
|
19
|
+
* declaration can never match a delivered event -- not a preference.
|
|
20
|
+
*
|
|
21
|
+
* Reuses the existing `invalid_spec` kind rather than minting a new one: the
|
|
22
|
+
* refusal taxonomy is closed and gated on every declared kind being reachable
|
|
23
|
+
* from `preflight()` (preflight.test.ts), and this check runs on the authored
|
|
24
|
+
* path instead. The message carries the precision.
|
|
25
|
+
*/
|
|
26
|
+
export declare function preflightProviderTriggers(triggers: readonly TriggerSource[]): PreflightRefusal[];
|
|
27
|
+
//# sourceMappingURL=provider-trigger-contract.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"provider-trigger-contract.d.ts","sourceRoot":"","sources":["../src/provider-trigger-contract.ts"],"names":[],"mappings":"AAAA,OAAO,EAAsB,KAAK,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAC7E,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AA+CvD,MAAM,WAAW,mBAAmB;IAClC,iDAAiD;IACjD,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,wCAAwC;IACxC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,+CAA+C;IAC/C,QAAQ,CAAC,MAAM,EAAE,SAAS,MAAM,EAAE,CAAC;CACpC;AAED;;;GAGG;AACH,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,aAAa,GAAG,mBAAmB,GAAG,SAAS,CAa1F;AAED;;;;;;;;;GASG;AACH,wBAAgB,yBAAyB,CACvC,QAAQ,EAAE,SAAS,aAAa,EAAE,GACjC,gBAAgB,EAAE,CAuBpB"}
|
|
Binary file
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"provider-trigger-contract.js","sourceRoot":"","sources":["../src/provider-trigger-contract.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kBAAkB,EAAsB,MAAM,qBAAqB,CAAC;AAyC7E,iFAAiF;AACjF,SAAS,SAAS,CAAC,QAAgB;IACjC,OAAO,MAAM,CAAC,MAAM,CAAC,kBAAkB,EAAE,QAAQ,CAAC;QAChD,CAAC,CAAC,kBAAkB,CAAC,QAAkC,CAAC;QACxD,CAAC,CAAC,SAAS,CAAC;AAChB,CAAC;AAWD;;;GAGG;AACH,MAAM,UAAU,mBAAmB,CAAC,MAAqB;IACvD,IAAI,MAAM,CAAC,IAAI,KAAK,SAAS;QAAE,OAAO,SAAS,CAAC;IAChD,MAAM,MAAM,GAAG,SAAS,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;IACtC,IAAI,MAAM,KAAK,SAAS;QAAE,OAAO,SAAS,CAAC;IAC3C,MAAM,MAAM,GAAG,MAAM,CAAC,MAAM,CAAC;IAC7B,IAAI,MAAM,KAAK,SAAS;QAAE,OAAO,SAAS,CAAC;IAC3C,4EAA4E;IAC5E,8EAA8E;IAC9E,uEAAuE;IACvE,IAAI,MAAM,CAAC,UAAU,CAAC,KAAK,MAAM,CAAC,IAAI;QAAE,OAAO,SAAS,CAAC;IACzD,MAAM,IAAI,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC;IAC5B,IAAI,OAAO,IAAI,KAAK,QAAQ;QAAE,OAAO,SAAS,CAAC;IAC/C,OAAO,EAAE,QAAQ,EAAE,MAAM,CAAC,IAAI,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;AACjD,CAAC;AAED;;;;;;;;;GASG;AACH,MAAM,UAAU,yBAAyB,CACvC,QAAkC;IAElC,MAAM,QAAQ,GAAuB,EAAE,CAAC;IACxC,MAAM,IAAI,GAAG,IAAI,GAAG,EAAU,CAAC;IAC/B,KAAK,MAAM,OAAO,IAAI,QAAQ,EAAE,CAAC;QAC/B,MAAM,WAAW,GAAG,mBAAmB,CAAC,OAAO,CAAC,CAAC;QACjD,IAAI,WAAW,KAAK,SAAS;YAAE,SAAS;QACxC,IAAI,WAAW,CAAC,MAAM,CAAC,QAAQ,CAAC,WAAW,CAAC,IAAI,CAAC;YAAE,SAAS;QAC5D,oEAAoE;QACpE,wEAAwE;QACxE,sDAAsD;QACtD,MAAM,GAAG,GAAG,GAAG,WAAW,CAAC,QAAQ,IAAI,WAAW,CAAC,IAAI,EAAE,CAAC;QAC1D,IAAI,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC;YAAE,SAAS;QAC5B,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;QACd,QAAQ,CAAC,IAAI,CAAC;YACZ,QAAQ,EAAE,SAAS;YACnB,IAAI,EAAE,cAAc;YACpB,QAAQ,EAAE,WAAW,CAAC,QAAQ;YAC9B,OAAO,EAAE,qBAAqB,WAAW,CAAC,QAAQ,wBAAwB;kBACtE,IAAI,WAAW,CAAC,IAAI,YAAY,WAAW,CAAC,QAAQ,2BAA2B;kBAC/E,4DAA4D,WAAW,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE;SAChG,CAAC,CAAC;IACL,CAAC;IACD,OAAO,QAAQ,CAAC;AAClB,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@relayflows/sdk",
|
|
3
|
-
"version": "2.0.
|
|
3
|
+
"version": "2.0.16",
|
|
4
4
|
"description": "TypeScript-first authoring SDK for Relayflows. Compiles specs; speaks the journal protocol.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -45,7 +45,7 @@
|
|
|
45
45
|
"@modelcontextprotocol/sdk": "^1.30.0",
|
|
46
46
|
"@relayfile/adapter-core": "0.5.24",
|
|
47
47
|
"@relayfile/relay-helpers": "0.4.11",
|
|
48
|
-
"@relayflows/surface": "2.0.
|
|
48
|
+
"@relayflows/surface": "2.0.16",
|
|
49
49
|
"@types/js-yaml": "^4.0.9",
|
|
50
50
|
"ai-hist": "0.4.1",
|
|
51
51
|
"ajv": "^8.17.1",
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
import { createHash } from 'node:crypto';
|
|
2
|
+
import { readFile, readdir, stat } from 'node:fs/promises';
|
|
3
|
+
import { join, relative, sep } from 'node:path';
|
|
4
|
+
|
|
5
|
+
function isEnoent(error: unknown): boolean {
|
|
6
|
+
return error instanceof Error && (error as NodeJS.ErrnoException).code === 'ENOENT';
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
const SKIPPED_DIR_NAMES = new Set(['node_modules']);
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* A recursive snapshot of every regular file under `dir`, keyed by its
|
|
13
|
+
* `dir`-relative POSIX path, valued by a content signature (size + sha256).
|
|
14
|
+
* Content, not mtime: a fast rewrite inside the filesystem's timestamp
|
|
15
|
+
* resolution must still count as a change — the same rule
|
|
16
|
+
* `examples/research/shims/agent-cli.ts`'s `snapshot()` uses for the same
|
|
17
|
+
* "did the agent actually write something" question. Dotfiles/dotdirs
|
|
18
|
+
* (`.git`, the kernel's own `.relayflowd` data dir, editor swap files, ...)
|
|
19
|
+
* are never agent-authored content and are skipped, as is `node_modules`.
|
|
20
|
+
* A missing `dir` (an agent step whose cwd does not exist yet) yields an
|
|
21
|
+
* empty snapshot rather than throwing. Only a vanished path (`ENOENT`) is
|
|
22
|
+
* ever swallowed this way; any other filesystem error (permissions,
|
|
23
|
+
* `ENOTDIR`, `EISDIR`, ...) propagates, because a step whose artifact scan
|
|
24
|
+
* silently dropped files it could not read must not report a successful,
|
|
25
|
+
* incomplete `artifacts` list as if it were the truth.
|
|
26
|
+
*/
|
|
27
|
+
export async function snapshotWorkspaceFiles(dir: string): Promise<Map<string, string>> {
|
|
28
|
+
const out = new Map<string, string>();
|
|
29
|
+
await walk(dir, dir, out);
|
|
30
|
+
return out;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
async function walk(root: string, current: string, out: Map<string, string>): Promise<void> {
|
|
34
|
+
let entries;
|
|
35
|
+
try {
|
|
36
|
+
entries = await readdir(current, { withFileTypes: true });
|
|
37
|
+
} catch (error) {
|
|
38
|
+
if (isEnoent(error)) return;
|
|
39
|
+
throw error;
|
|
40
|
+
}
|
|
41
|
+
for (const entry of entries) {
|
|
42
|
+
if (entry.name.startsWith('.') || SKIPPED_DIR_NAMES.has(entry.name)) continue;
|
|
43
|
+
const path = join(current, entry.name);
|
|
44
|
+
if (entry.isDirectory()) {
|
|
45
|
+
await walk(root, path, out);
|
|
46
|
+
continue;
|
|
47
|
+
}
|
|
48
|
+
if (!entry.isFile()) continue;
|
|
49
|
+
let info;
|
|
50
|
+
try {
|
|
51
|
+
info = await stat(path);
|
|
52
|
+
} catch (error) {
|
|
53
|
+
// A file can vanish between readdir and stat (a CLI's own temp file);
|
|
54
|
+
// that is not an artifact, not a scan failure.
|
|
55
|
+
if (isEnoent(error)) continue;
|
|
56
|
+
throw error;
|
|
57
|
+
}
|
|
58
|
+
let bytes;
|
|
59
|
+
try {
|
|
60
|
+
bytes = await readFile(path);
|
|
61
|
+
} catch (error) {
|
|
62
|
+
if (isEnoent(error)) continue;
|
|
63
|
+
throw error;
|
|
64
|
+
}
|
|
65
|
+
out.set(relative(root, path).split(sep).join('/'), `${info.size}:${createHash('sha256').update(bytes).digest('hex')}`);
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
/** `dir`-relative paths present in `after` that are new or changed since `before`, sorted. */
|
|
70
|
+
export function diffWorkspaceFiles(before: Map<string, string>, after: Map<string, string>): string[] {
|
|
71
|
+
const changed: string[] = [];
|
|
72
|
+
for (const [path, signature] of after) {
|
|
73
|
+
if (before.get(path) !== signature) changed.push(path);
|
|
74
|
+
}
|
|
75
|
+
return changed.sort();
|
|
76
|
+
}
|
|
@@ -12,7 +12,7 @@ import { buildMcpProxy, runMcpEffect } from './authored-mcp.js';
|
|
|
12
12
|
import { AuthoredBudget } from './authored-budget.js';
|
|
13
13
|
import { assertMemoryReachable, authoredMemory, scriptMemoryScope } from './authored-memory.js';
|
|
14
14
|
import { authoredDeterministicRunner, authoredWorkerRunner } from './authored-worker-step.js';
|
|
15
|
-
import { isSurfaceRunCompletionReason } from './authored-step-output.js';
|
|
15
|
+
import { isSurfaceFlowCompletionReason, isSurfaceRunCompletionReason } from './authored-step-output.js';
|
|
16
16
|
import {
|
|
17
17
|
type AgentResult,
|
|
18
18
|
type LlmOptions,
|
|
@@ -83,12 +83,22 @@ export interface AuthoredFlowExecutionResult {
|
|
|
83
83
|
readonly executionRuntime?: AuthoredExecutionRuntime;
|
|
84
84
|
readonly rootRunId?: string;
|
|
85
85
|
readonly name: string;
|
|
86
|
-
readonly completionReason:
|
|
86
|
+
readonly completionReason: LoweredCompletionReason;
|
|
87
87
|
readonly journalSteps: readonly AuthoredFlowJournalStep[];
|
|
88
88
|
}
|
|
89
89
|
|
|
90
|
-
|
|
91
|
-
|
|
90
|
+
// The authoring SURFACE stays wide: `done()` accepts every
|
|
91
|
+
// `FlowCompletionReason` and refuses the kernel-owned ones at runtime with a
|
|
92
|
+
// diagnostic that names the alternative. The RESULT is narrow, because `done()`
|
|
93
|
+
// cannot store a reason this executor does not lower.
|
|
94
|
+
//
|
|
95
|
+
// Pinning the narrow type here is load-bearing, not cosmetic. Every reader of
|
|
96
|
+
// this result — the CLI report, the durable root, the IPC verifier — would
|
|
97
|
+
// otherwise have to re-derive "can this really be `canceled`?" and answer it
|
|
98
|
+
// by hand. Those hand-written answers disagreeing is the exact defect this
|
|
99
|
+
// change exists to close; a widening here re-opens it at compile time instead.
|
|
100
|
+
type ExecutionResultUsesLoweredCompletionReason = Assert<
|
|
101
|
+
Equal<AuthoredFlowExecutionResult['completionReason'], LoweredCompletionReason>
|
|
92
102
|
>;
|
|
93
103
|
type JournalStepUsesStepCompletionReason = Assert<
|
|
94
104
|
Equal<AuthoredFlowJournalStep['completionReason'], ProtocolCompletionReason>
|
|
@@ -100,7 +110,8 @@ type JournalStepUsesStepCompletionReason = Assert<
|
|
|
100
110
|
* This is deliberately not exported by the SDK package: without a durable
|
|
101
111
|
* authored root, it is not a resumable public runner. The seam is narrow: an
|
|
102
112
|
* flow with an optional budget may await `f.run`, `f.llm`, and `f.agent` steps and must
|
|
103
|
-
* finish with
|
|
113
|
+
* finish with one of the lowered completions — `f.done("success")`,
|
|
114
|
+
* `f.done("needs_human")`, `f.done("step_failed")` or `f.done("declined")`. Each step and the terminal marker is
|
|
104
115
|
* a compiled spec submitted through
|
|
105
116
|
* `JournalClient`; values are read back from `step.completed` journal entries.
|
|
106
117
|
* Unsupported headers, verbs, gates, or completion lowering fail closed.
|
|
@@ -189,7 +200,7 @@ export async function executeAuthoredFlow<Input = undefined>(
|
|
|
189
200
|
const authoredSteps: AuthoredFlowOperation<unknown>[] = [];
|
|
190
201
|
const lifecycle = new AuthoredFlowLifecycle();
|
|
191
202
|
let nextStep = 1;
|
|
192
|
-
let requestedCompletion:
|
|
203
|
+
let requestedCompletion: LoweredCompletionReason | undefined;
|
|
193
204
|
|
|
194
205
|
const lowerDeterministic = authoredDeterministicRunner(
|
|
195
206
|
definition.name, journal, journalSteps, budget, options.rootRunId,
|
|
@@ -317,7 +328,7 @@ export async function executeAuthoredFlow<Input = undefined>(
|
|
|
317
328
|
throw unsupportedVerb('dispatch');
|
|
318
329
|
},
|
|
319
330
|
done(reason) {
|
|
320
|
-
if (
|
|
331
|
+
if (!isSurfaceFlowCompletionReason(reason)) {
|
|
321
332
|
throw new AuthoredFlowExecutionError(
|
|
322
333
|
'unsupported_completion',
|
|
323
334
|
`unknown completion reason: ${String(reason)}`,
|
|
@@ -329,10 +340,23 @@ export async function executeAuthoredFlow<Input = undefined>(
|
|
|
329
340
|
`flow "${definition.name}" called done() more than once`,
|
|
330
341
|
);
|
|
331
342
|
}
|
|
332
|
-
|
|
343
|
+
// `step_failed` is a verdict about the flow's OWN work — "the checks I
|
|
344
|
+
// ran did not pass" — and an authored body is authoritative about that.
|
|
345
|
+
// `canceled` and `budget_exceeded` are control-plane facts the kernel
|
|
346
|
+
// owns: cancellation arrives through `run.cancel`, budget exhaustion
|
|
347
|
+
// through the enforced budget (authored-budget.ts). A body that declared
|
|
348
|
+
// either would be asserting a kernel fact that never happened, so they
|
|
349
|
+
// stay refused — with a reason, not with "this executor cannot yet".
|
|
350
|
+
// `canceled` has no terminal shape to lower into either: there is no
|
|
351
|
+
// `cancelled` RunStatus in the local protocol, and Cloud accepts that
|
|
352
|
+
// completionReason only under a `cancelled` status this CLI never reports.
|
|
353
|
+
if (!isLoweredCompletion(reason)) {
|
|
333
354
|
throw new AuthoredFlowExecutionError(
|
|
334
355
|
'unsupported_completion',
|
|
335
|
-
`
|
|
356
|
+
`done("${reason}") is a kernel outcome, not an authored verdict: the kernel `
|
|
357
|
+
+ 'records it when it cancels a run or exhausts its budget, so a flow body '
|
|
358
|
+
+ 'cannot declare it. Use done("step_failed") to declare that the flow\'s own '
|
|
359
|
+
+ 'checks did not pass, or done("declined") to deliberately choose not to act.',
|
|
336
360
|
reason,
|
|
337
361
|
);
|
|
338
362
|
}
|
|
@@ -405,11 +429,12 @@ export async function executeAuthoredFlow<Input = undefined>(
|
|
|
405
429
|
lifecycle.close();
|
|
406
430
|
}
|
|
407
431
|
|
|
408
|
-
//
|
|
409
|
-
//
|
|
410
|
-
//
|
|
411
|
-
|
|
412
|
-
|
|
432
|
+
// Record the authored verdict as a SUCCESSFUL effect carrying that verdict,
|
|
433
|
+
// not as a fabricated kernel run.completed reason. The marker step reports
|
|
434
|
+
// what the body decided; it is not itself a step that failed. The CLI turns
|
|
435
|
+
// the verdict into the exit code (success/declined 0, needs_human 3, step_failed 1).
|
|
436
|
+
await lowerDeterministic(`complete-${nextStep}`,
|
|
437
|
+
completionMarker(requestedCompletion), true);
|
|
413
438
|
return Object.freeze({
|
|
414
439
|
...(options.rootRunId === undefined ? {} : { rootRunId: options.rootRunId }),
|
|
415
440
|
name: definition.name,
|
|
@@ -433,6 +458,43 @@ function unsupportedVerb(verb: string): AuthoredFlowExecutionError {
|
|
|
433
458
|
);
|
|
434
459
|
}
|
|
435
460
|
|
|
461
|
+
/**
|
|
462
|
+
* The completion reasons an authored body may declare and this executor lowers.
|
|
463
|
+
*
|
|
464
|
+
* `FlowCompletionReason` is wider than this on purpose — it is the journal's
|
|
465
|
+
* run vocabulary plus authored verdicts — but the two sets drifting silently is
|
|
466
|
+
* exactly what made a type-valid `done("step_failed")` die at runtime as
|
|
467
|
+
* `unsupported_completion`. Every gate that asks "is this a completion this
|
|
468
|
+
* runtime can lower?" now asks this one function, so a reason cannot be
|
|
469
|
+
* accepted in one place and rejected in another.
|
|
470
|
+
*
|
|
471
|
+
* These three are internal cross-module helpers for the authored seam (the
|
|
472
|
+
* executor, the durable root, the IPC verifier and the CLI report), NOT public
|
|
473
|
+
* SDK surface. `src/index.ts` deliberately re-exports nothing from this module
|
|
474
|
+
* — keep it that way, or the whole authored seam leaks with them.
|
|
475
|
+
*/
|
|
476
|
+
export const LOWERED_COMPLETIONS = ['success', 'needs_human', 'step_failed', 'declined'] as const;
|
|
477
|
+
export type LoweredCompletionReason = (typeof LOWERED_COMPLETIONS)[number];
|
|
478
|
+
|
|
479
|
+
export function isLoweredCompletion(value: unknown): value is LoweredCompletionReason {
|
|
480
|
+
return typeof value === 'string' && (LOWERED_COMPLETIONS as readonly string[]).includes(value);
|
|
481
|
+
}
|
|
482
|
+
|
|
483
|
+
/**
|
|
484
|
+
* The deterministic command that carries an authored verdict into the journal.
|
|
485
|
+
*
|
|
486
|
+
* `success` lowers to `:` because success needs no marker: the marker run's own
|
|
487
|
+
* kernel `success` already IS that record. Every other lowered verdict is
|
|
488
|
+
* something the kernel's completion vocabulary cannot express on a step that
|
|
489
|
+
* *succeeded*, so it travels as data on stdout and is read back from
|
|
490
|
+
* `step.completed`. It is deliberately not lowered as a failing command: no
|
|
491
|
+
* step failed here, and a fabricated failure would put bogus evidence in the
|
|
492
|
+
* journal for a flow whose steps all ran correctly.
|
|
493
|
+
*/
|
|
494
|
+
export function completionMarker(reason: LoweredCompletionReason): string {
|
|
495
|
+
return reason === 'success' ? ':' : `printf '%s' '{"completionReason":"${reason}"}'`;
|
|
496
|
+
}
|
|
497
|
+
|
|
436
498
|
function assertOperationAllowed(
|
|
437
499
|
verb: string,
|
|
438
500
|
flowName: string,
|
|
@@ -442,7 +504,7 @@ function assertOperationAllowed(
|
|
|
442
504
|
throw new AuthoredFlowExecutionError(
|
|
443
505
|
'operation_after_completion',
|
|
444
506
|
`flow "${flowName}" called f.${verb} after done()`,
|
|
445
|
-
completion
|
|
507
|
+
isSurfaceRunCompletionReason(completion) ? completion : undefined,
|
|
446
508
|
);
|
|
447
509
|
}
|
|
448
510
|
}
|
|
@@ -8,6 +8,7 @@ import { isAbsolute, join } from 'node:path';
|
|
|
8
8
|
import type { Readable } from 'node:stream';
|
|
9
9
|
import type { AuthoredRootMetadata } from './authored-root.js';
|
|
10
10
|
import type { AuthoredExecutionRuntime, AuthoredFlowExecutionResult, ExecuteAuthoredFlowOptions } from './authored-flow-executor.js';
|
|
11
|
+
import { completionMarker, isLoweredCompletion } from './authored-flow-executor.js';
|
|
11
12
|
import { AuthoredFlowExecutionError, type AuthoredFlowExecutionErrorCode } from './authored-flow-error.js';
|
|
12
13
|
import { assertAuthoredPromiseHooks } from './authored-runtime-capability.js';
|
|
13
14
|
|
|
@@ -162,7 +163,7 @@ export async function verifyAuthoredNodeResult(
|
|
|
162
163
|
): Promise<void> {
|
|
163
164
|
const invalid = (): never => { throw new Error('authored runtime result has no matching durable completion'); };
|
|
164
165
|
if (result.rootRunId !== rootRunId || result.name !== metadata.flowName
|
|
165
|
-
|| !
|
|
166
|
+
|| !isLoweredCompletion(result.completionReason)
|
|
166
167
|
|| !Array.isArray(result.journalSteps) || result.journalSteps.length === 0) invalid();
|
|
167
168
|
const terminal = result.journalSteps.at(-1)!;
|
|
168
169
|
if (!terminal || !/^complete-[1-9][0-9]*$/.test(terminal.id)) invalid();
|
|
@@ -210,9 +211,15 @@ export async function verifyAuthoredNodeResult(
|
|
|
210
211
|
|| completed[0]?.payload?.completionReason !== 'success'
|
|
211
212
|
|| terminalFacts.length !== 1 || terminalFacts[0]?.payload?.completionReason !== 'success') invalid();
|
|
212
213
|
if (claimed === terminal) {
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
214
|
+
// The claimed verdict must match the marker the journal actually
|
|
215
|
+
// recorded, so an IPC frame cannot claim `success` over a run whose
|
|
216
|
+
// durable terminal says `step_failed` (or the reverse). The
|
|
217
|
+
// `isLoweredCompletion` check at the top of this function already
|
|
218
|
+
// rejected a frame whose reason is not lowerable at all — that one is
|
|
219
|
+
// the runtime validation of untrusted IPC, and it is why nothing has
|
|
220
|
+
// to be re-asserted here just to satisfy the type.
|
|
221
|
+
if (step?.type !== 'deterministic'
|
|
222
|
+
|| step.command !== completionMarker(result.completionReason)) invalid();
|
|
216
223
|
}
|
|
217
224
|
}
|
|
218
225
|
} finally { journal.close(); }
|
package/src/authored-root.ts
CHANGED
|
@@ -4,7 +4,7 @@ import { createHash, randomUUID } from 'node:crypto';
|
|
|
4
4
|
import { readFile } from 'node:fs/promises';
|
|
5
5
|
import { canonicalize } from './canonical.js';
|
|
6
6
|
import { compileSpec, toKernelSpec } from './compile.js';
|
|
7
|
-
import { executeAuthoredFlow, type AuthoredFlowExecutionResult } from './authored-flow-executor.js';
|
|
7
|
+
import { executeAuthoredFlow, isLoweredCompletion, type AuthoredFlowExecutionResult } from './authored-flow-executor.js';
|
|
8
8
|
import {
|
|
9
9
|
loadAuthoredFlow,
|
|
10
10
|
type LoadedAuthoredFlow,
|
|
@@ -340,7 +340,7 @@ function isCompletedRootOutput(value: unknown): value is Omit<AuthoredFlowExecut
|
|
|
340
340
|
if (typeof value !== 'object' || value === null || Array.isArray(value)) return false;
|
|
341
341
|
const output = value as Partial<AuthoredFlowExecutionResult>;
|
|
342
342
|
return typeof output.name === 'string'
|
|
343
|
-
&& (output.completionReason
|
|
343
|
+
&& isLoweredCompletion(output.completionReason)
|
|
344
344
|
&& Array.isArray(output.journalSteps)
|
|
345
345
|
&& output.journalSteps.every(step => typeof step === 'object' && step !== null
|
|
346
346
|
&& typeof step.id === 'string' && typeof step.runId === 'string'
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { COMPLETION_REASONS, RUN_COMPLETION_REASONS } from '@relayflows/surface';
|
|
1
|
+
import { COMPLETION_REASONS, RUN_COMPLETION_REASONS, FLOW_COMPLETION_REASONS, type FlowCompletionReason } from '@relayflows/surface';
|
|
2
2
|
import { AuthoredFlowExecutionError } from './authored-flow-error.js';
|
|
3
3
|
import type { JournalClient } from './journal-client.js';
|
|
4
4
|
import type { CompletionReason as ProtocolCompletionReason, RunCompletionReason as ProtocolRunCompletionReason, RunOutcome } from './protocol.js';
|
|
@@ -93,6 +93,11 @@ export function isSurfaceRunCompletionReason(value: unknown): value is ProtocolR
|
|
|
93
93
|
&& (RUN_COMPLETION_REASONS as readonly string[]).includes(value);
|
|
94
94
|
}
|
|
95
95
|
|
|
96
|
+
export function isSurfaceFlowCompletionReason(value: unknown): value is FlowCompletionReason {
|
|
97
|
+
return typeof value === 'string'
|
|
98
|
+
&& (FLOW_COMPLETION_REASONS as readonly string[]).includes(value);
|
|
99
|
+
}
|
|
100
|
+
|
|
96
101
|
function isRecord(value: unknown): value is Record<string, unknown> {
|
|
97
102
|
return typeof value === 'object' && value !== null && !Array.isArray(value);
|
|
98
103
|
}
|
|
@@ -12,6 +12,7 @@ import { isSurfaceCompletionReason, readCompletedStepOutput, readSuccessfulOutpu
|
|
|
12
12
|
import type { AuthoredFlowJournalStep } from './authored-flow-executor.js';
|
|
13
13
|
import { snapshotJsonValue } from './json-value.js';
|
|
14
14
|
import { authoredChildAdmissionKey } from './authored-admission.js';
|
|
15
|
+
import { diffWorkspaceFiles, snapshotWorkspaceFiles } from './agent-artifacts.js';
|
|
15
16
|
|
|
16
17
|
const WORKSPACE_PERMISSION_ANNOTATION = /:\s*(readonly|readwrite)\s*$/i;
|
|
17
18
|
|
|
@@ -129,6 +130,20 @@ export function authoredWorkerRunner(
|
|
|
129
130
|
`f.agent options.transport must be 'direct' or 'relay' (got ${JSON.stringify(options.transport)}).`,
|
|
130
131
|
);
|
|
131
132
|
}
|
|
133
|
+
// Artifact detection only tells the truth for the local-agent DIRECT
|
|
134
|
+
// path: that is the only case that runs in this same process, on this
|
|
135
|
+
// same filesystem, so `options.cwd` (or `process.cwd()`) is provably
|
|
136
|
+
// where the CLI actually wrote — a workspace-scoped step never reaches
|
|
137
|
+
// here with a local agent attached (refused above). `transport: 'relay'`
|
|
138
|
+
// dispatches to agent-relay, which executes on a remote host even
|
|
139
|
+
// though a local agent stream is still attached, so it gets no local
|
|
140
|
+
// snapshot either. Any other worker attachment may execute on a
|
|
141
|
+
// different host entirely; snapshotting this process's filesystem for
|
|
142
|
+
// that case would be a guess, not a fact, so `artifacts` stays `[]`
|
|
143
|
+
// there, exactly as before this fix.
|
|
144
|
+
const artifactRoot = localAgentStream === undefined || options.transport === 'relay'
|
|
145
|
+
? undefined : options.cwd ?? process.cwd();
|
|
146
|
+
const before = artifactRoot === undefined ? undefined : await snapshotWorkspaceFiles(artifactRoot);
|
|
132
147
|
const output = await run({
|
|
133
148
|
id, type: 'agent', instruction: options.task,
|
|
134
149
|
...(localAgentStream === undefined ? {} : { surfaces: { streams: [{ stream: localAgentStream }] } }),
|
|
@@ -143,7 +158,10 @@ export function authoredWorkerRunner(
|
|
|
143
158
|
throw new AuthoredFlowExecutionError('journal_protocol_violation', `step "${id}" produced a non-object output`);
|
|
144
159
|
}
|
|
145
160
|
const stdout = 'stdout_tail' in output ? output.stdout_tail : undefined;
|
|
146
|
-
|
|
161
|
+
const artifacts = before === undefined || artifactRoot === undefined
|
|
162
|
+
? []
|
|
163
|
+
: diffWorkspaceFiles(before, await snapshotWorkspaceFiles(artifactRoot));
|
|
164
|
+
return { summary: typeof stdout === 'string' ? stdout : JSON.stringify(output), artifacts };
|
|
147
165
|
},
|
|
148
166
|
async llm(id: string, prompt: string, options?: LlmOptions, verification?: NamedGate): Promise<unknown> {
|
|
149
167
|
if (options !== undefined && (typeof options !== 'object' || options === null || options.output === undefined)) {
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { dirname, resolve } from 'node:path';
|
|
2
2
|
import { loadAuthoredFlow, type LoadedAuthoredFlow } from '../authored-flow-loader.js';
|
|
3
3
|
import { preflightWebhookTriggers } from '../preflight.js';
|
|
4
|
+
import { preflightProviderTriggers } from '../provider-trigger-contract.js';
|
|
4
5
|
import { checkSlackHelpers } from '../slack-preflight.js';
|
|
5
6
|
import { inputFailureReport, readProjectConfig, type CheckReport } from './check.js';
|
|
6
7
|
|
|
@@ -19,15 +20,23 @@ export async function checkAuthoredTriggers(path: string): Promise<{
|
|
|
19
20
|
const loaded = await loadAuthoredFlow(path);
|
|
20
21
|
const definition = loaded.getDefinition(loaded.handle);
|
|
21
22
|
const config = readProjectConfig(dirname(resolve(path)));
|
|
22
|
-
const
|
|
23
|
-
|
|
24
|
-
|
|
23
|
+
const triggers = (definition.handlers ?? []).map(handler => handler.trigger);
|
|
24
|
+
const triggerDiagnostics = preflightWebhookTriggers(triggers, config.executors);
|
|
25
|
+
// Registration answers "may this inbox run here"; the provider contract
|
|
26
|
+
// answers "can this subscription ever be delivered". A provider trigger
|
|
27
|
+
// that passes the first and fails the second used to reach ingress and be
|
|
28
|
+
// refused there, on the first real event.
|
|
29
|
+
const providerDiagnostics = preflightProviderTriggers(triggers);
|
|
25
30
|
const helperReport = checkSlackHelpers(definition);
|
|
26
|
-
const diagnostics = [
|
|
31
|
+
const diagnostics = [
|
|
32
|
+
...triggerDiagnostics, ...providerDiagnostics, ...helperReport.diagnostics,
|
|
33
|
+
];
|
|
27
34
|
return {
|
|
28
35
|
loaded,
|
|
29
36
|
report: {
|
|
30
|
-
|
|
37
|
+
// Severity, not emptiness: a warning must never refuse a flow.
|
|
38
|
+
ok: !diagnostics.some(diagnostic => diagnostic.severity === 'refusal'),
|
|
39
|
+
path, gates: [], resolutions: [], diagnostics,
|
|
31
40
|
...(config.path === undefined ? {} : { projectConfigPath: config.path }),
|
|
32
41
|
},
|
|
33
42
|
};
|
package/src/cli/check.ts
CHANGED
|
@@ -340,7 +340,12 @@ function systemProbes(flowDirectory: string, config: ProjectConfig): PreflightPr
|
|
|
340
340
|
helper: helperReady,
|
|
341
341
|
cli: (cli, source, model) => probeCli(cli, source === 'project' ? config.directory : flowDirectory, model),
|
|
342
342
|
executor: (trigger) => config.executors.includes(trigger.executor),
|
|
343
|
-
|
|
343
|
+
// A deterministic step runs in the daemon's working directory — the
|
|
344
|
+
// directory `flows run` was invoked from, or Cloud's code mount — not in
|
|
345
|
+
// the flow file's. Probing `./x` against the flow's directory answered a
|
|
346
|
+
// question the kernel never asks, and refused a Cloud run whose synced
|
|
347
|
+
// tree held the script while its source sat in the state directory.
|
|
348
|
+
command: (binary) => executableExists(binary, process.cwd()),
|
|
344
349
|
};
|
|
345
350
|
}
|
|
346
351
|
|