@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.
Files changed (98) hide show
  1. package/dist/agent-artifacts.d.ts +20 -0
  2. package/dist/agent-artifacts.d.ts.map +1 -0
  3. package/dist/agent-artifacts.js +81 -0
  4. package/dist/agent-artifacts.js.map +1 -0
  5. package/dist/authored-flow-executor.d.ts +33 -3
  6. package/dist/authored-flow-executor.d.ts.map +1 -1
  7. package/dist/authored-flow-executor.js +56 -10
  8. package/dist/authored-flow-executor.js.map +1 -1
  9. package/dist/authored-node-runner.d.ts.map +1 -1
  10. package/dist/authored-node-runner.js +11 -4
  11. package/dist/authored-node-runner.js.map +1 -1
  12. package/dist/authored-root.d.ts.map +1 -1
  13. package/dist/authored-root.js +2 -2
  14. package/dist/authored-root.js.map +1 -1
  15. package/dist/authored-step-output.d.ts +2 -0
  16. package/dist/authored-step-output.d.ts.map +1 -1
  17. package/dist/authored-step-output.js +5 -1
  18. package/dist/authored-step-output.js.map +1 -1
  19. package/dist/authored-worker-step.d.ts.map +1 -1
  20. package/dist/authored-worker-step.js +19 -1
  21. package/dist/authored-worker-step.js.map +1 -1
  22. package/dist/cli/check-triggers.d.ts.map +1 -1
  23. package/dist/cli/check-triggers.js +14 -3
  24. package/dist/cli/check-triggers.js.map +1 -1
  25. package/dist/cli/check.js +6 -1
  26. package/dist/cli/check.js.map +1 -1
  27. package/dist/cli/cloud-deploy.d.ts +30 -0
  28. package/dist/cli/cloud-deploy.d.ts.map +1 -0
  29. package/dist/cli/cloud-deploy.js +162 -0
  30. package/dist/cli/cloud-deploy.js.map +1 -0
  31. package/dist/cli/cloud-run.d.ts +3 -1
  32. package/dist/cli/cloud-run.d.ts.map +1 -1
  33. package/dist/cli/cloud-run.js +37 -5
  34. package/dist/cli/cloud-run.js.map +1 -1
  35. package/dist/cli/cloud-sync.d.ts +13 -0
  36. package/dist/cli/cloud-sync.d.ts.map +1 -0
  37. package/dist/cli/cloud-sync.js +39 -0
  38. package/dist/cli/cloud-sync.js.map +1 -0
  39. package/dist/cli/direct-run.d.ts.map +1 -1
  40. package/dist/cli/direct-run.js +2 -26
  41. package/dist/cli/direct-run.js.map +1 -1
  42. package/dist/cli/run.d.ts +20 -1
  43. package/dist/cli/run.d.ts.map +1 -1
  44. package/dist/cli/run.js +77 -15
  45. package/dist/cli/run.js.map +1 -1
  46. package/dist/cli.d.ts.map +1 -1
  47. package/dist/cli.js +82 -12
  48. package/dist/cli.js.map +1 -1
  49. package/dist/cloud-deploy.d.ts +70 -0
  50. package/dist/cloud-deploy.d.ts.map +1 -0
  51. package/dist/cloud-deploy.js +181 -0
  52. package/dist/cloud-deploy.js.map +1 -0
  53. package/dist/cloud-http.d.ts +37 -2
  54. package/dist/cloud-http.d.ts.map +1 -1
  55. package/dist/cloud-http.js +98 -8
  56. package/dist/cloud-http.js.map +1 -1
  57. package/dist/cloud-run.d.ts +23 -0
  58. package/dist/cloud-run.d.ts.map +1 -1
  59. package/dist/cloud-run.js +30 -1
  60. package/dist/cloud-run.js.map +1 -1
  61. package/dist/cloud-sync.d.ts +66 -0
  62. package/dist/cloud-sync.d.ts.map +1 -0
  63. package/dist/cloud-sync.js +287 -0
  64. package/dist/cloud-sync.js.map +1 -0
  65. package/dist/failure-kinds.d.ts +8 -1
  66. package/dist/failure-kinds.d.ts.map +1 -1
  67. package/dist/failure-kinds.js +8 -0
  68. package/dist/failure-kinds.js.map +1 -1
  69. package/dist/index.d.ts +2 -0
  70. package/dist/index.d.ts.map +1 -1
  71. package/dist/index.js +2 -0
  72. package/dist/index.js.map +1 -1
  73. package/dist/provider-trigger-contract.d.ts +27 -0
  74. package/dist/provider-trigger-contract.d.ts.map +1 -0
  75. package/dist/provider-trigger-contract.js +0 -0
  76. package/dist/provider-trigger-contract.js.map +1 -0
  77. package/package.json +2 -2
  78. package/src/agent-artifacts.ts +76 -0
  79. package/src/authored-flow-executor.ts +77 -15
  80. package/src/authored-node-runner.ts +11 -4
  81. package/src/authored-root.ts +2 -2
  82. package/src/authored-step-output.ts +6 -1
  83. package/src/authored-worker-step.ts +19 -1
  84. package/src/cli/check-triggers.ts +14 -5
  85. package/src/cli/check.ts +6 -1
  86. package/src/cli/cloud-deploy.ts +157 -0
  87. package/src/cli/cloud-run.ts +37 -6
  88. package/src/cli/cloud-sync.ts +37 -0
  89. package/src/cli/direct-run.ts +2 -25
  90. package/src/cli/run.ts +86 -16
  91. package/src/cli.ts +75 -12
  92. package/src/cloud-deploy.ts +236 -0
  93. package/src/cloud-http.ts +129 -9
  94. package/src/cloud-run.ts +47 -1
  95. package/src/cloud-sync.ts +315 -0
  96. package/src/failure-kinds.ts +8 -0
  97. package/src/index.ts +8 -0
  98. package/src/provider-trigger-contract.ts +0 -0
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
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;AAExB,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"}
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"}
@@ -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.14",
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.14",
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: FlowCompletionReason;
86
+ readonly completionReason: LoweredCompletionReason;
87
87
  readonly journalSteps: readonly AuthoredFlowJournalStep[];
88
88
  }
89
89
 
90
- type ExecutionResultUsesFlowCompletionReason = Assert<
91
- Equal<AuthoredFlowExecutionResult['completionReason'], FlowCompletionReason>
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 `f.done("success")` or `f.done("needs_human")`. Each step and the terminal marker is
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: FlowCompletionReason | undefined;
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 (reason !== 'needs_human' && !isSurfaceRunCompletionReason(reason)) {
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
- if (reason !== 'success' && reason !== 'needs_human') {
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
- `the initial authored executor cannot lower done("${reason}")`,
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
- // The authored runner has no durable root yet. Record the handoff as a
409
- // successful effect containing the authored outcome, not a fabricated kernel
410
- // run.completed reason. The CLI reports this outcome as parked (exit 3).
411
- await lowerDeterministic(`complete-${nextStep}`, requestedCompletion === 'needs_human'
412
- ? `printf '%s' '{"completionReason":"needs_human"}'` : ':', true);
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 === 'needs_human' ? undefined : 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
- || !['success', 'needs_human'].includes(result.completionReason)
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
- const command = result.completionReason === 'needs_human'
214
- ? `printf '%s' '{"completionReason":"needs_human"}'` : ':';
215
- if (step?.type !== 'deterministic' || step.command !== command) invalid();
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(); }
@@ -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 === 'success' || output.completionReason === 'needs_human')
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
- return { summary: typeof stdout === 'string' ? stdout : JSON.stringify(output), artifacts: [] };
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 triggerDiagnostics = preflightWebhookTriggers(
23
- (definition.handlers ?? []).map(handler => handler.trigger), config.executors,
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 = [...triggerDiagnostics, ...helperReport.diagnostics];
31
+ const diagnostics = [
32
+ ...triggerDiagnostics, ...providerDiagnostics, ...helperReport.diagnostics,
33
+ ];
27
34
  return {
28
35
  loaded,
29
36
  report: {
30
- ok: diagnostics.length === 0, path, gates: [], resolutions: [], diagnostics,
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
- command: (binary) => executableExists(binary, flowDirectory),
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