@skaile/workspaces 2.3.0 → 2.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (217) hide show
  1. package/CHANGELOG.md +60 -0
  2. package/README.md +32 -13
  3. package/dist/app-sdk/index.js +1 -1
  4. package/dist/{asset-feeds-DKNYRLED.js → asset-feeds-4AWAT5PW.js} +6 -6
  5. package/dist/{asset-feeds-DKNYRLED.js.map → asset-feeds-4AWAT5PW.js.map} +1 -1
  6. package/dist/asset-manager/catalog-deployer.js +1 -1
  7. package/dist/asset-manager/index.js +5 -5
  8. package/dist/asset-manager/installer.js +2 -2
  9. package/dist/bridge/drivers/claude-sdk.js +108 -5
  10. package/dist/bridge/drivers/claude-sdk.js.map +1 -1
  11. package/dist/bridge/drivers/codex.js +1 -1
  12. package/dist/bridge/drivers/continue.js +2 -2
  13. package/dist/bridge/drivers/echo.js +1 -1
  14. package/dist/bridge/drivers/gemini.js +3 -3
  15. package/dist/bridge/drivers/goose.js +2 -2
  16. package/dist/bridge/drivers/omp.js +1 -1
  17. package/dist/bridge/drivers/opencode.js +2 -2
  18. package/dist/bridge/drivers/qwen.js +3 -3
  19. package/dist/bridge/index.js +2 -2
  20. package/dist/bridge/src/drivers/claude-sdk.d.ts +33 -0
  21. package/dist/bridge/src/drivers/claude-sdk.d.ts.map +1 -1
  22. package/dist/{chunk-CERGXDGG.js → chunk-2OCYS5EP.js} +3 -3
  23. package/dist/{chunk-CERGXDGG.js.map → chunk-2OCYS5EP.js.map} +1 -1
  24. package/dist/{chunk-W3Q37HEF.js → chunk-3HVASHBF.js} +3 -3
  25. package/dist/{chunk-W3Q37HEF.js.map → chunk-3HVASHBF.js.map} +1 -1
  26. package/dist/{chunk-UQ3RJKDD.js → chunk-4O2RAXKJ.js} +179 -52
  27. package/dist/chunk-4O2RAXKJ.js.map +1 -0
  28. package/dist/{chunk-DZM33LQO.js → chunk-4QROZZ5Z.js} +15 -3
  29. package/dist/chunk-4QROZZ5Z.js.map +1 -0
  30. package/dist/{chunk-G2ILW47R.js → chunk-57RFYEVM.js} +3 -3
  31. package/dist/{chunk-G2ILW47R.js.map → chunk-57RFYEVM.js.map} +1 -1
  32. package/dist/{chunk-BLWNI5KW.js → chunk-AKVAZ5CB.js} +2 -2
  33. package/dist/{chunk-BLWNI5KW.js.map → chunk-AKVAZ5CB.js.map} +1 -1
  34. package/dist/{chunk-BFIK6NPZ.js → chunk-AM5LFRXJ.js} +3 -3
  35. package/dist/{chunk-BFIK6NPZ.js.map → chunk-AM5LFRXJ.js.map} +1 -1
  36. package/dist/{chunk-RDE43ORT.js → chunk-D4VHBAJC.js} +4 -4
  37. package/dist/{chunk-RDE43ORT.js.map → chunk-D4VHBAJC.js.map} +1 -1
  38. package/dist/{chunk-PTS3QN5P.js → chunk-EEHOMCRU.js} +1021 -115
  39. package/dist/chunk-EEHOMCRU.js.map +1 -0
  40. package/dist/{chunk-CXX3UGJP.js → chunk-ENBTXMPL.js} +7 -7
  41. package/dist/{chunk-CXX3UGJP.js.map → chunk-ENBTXMPL.js.map} +1 -1
  42. package/dist/{chunk-LD6YGIKZ.js → chunk-EUWN4EK4.js} +60 -21
  43. package/dist/chunk-EUWN4EK4.js.map +1 -0
  44. package/dist/{chunk-FB4GPWYC.js → chunk-FKBQRV4J.js} +57 -16
  45. package/dist/chunk-FKBQRV4J.js.map +1 -0
  46. package/dist/{chunk-WG3L5VHF.js → chunk-HY3MBSNC.js} +2 -2
  47. package/dist/{chunk-WG3L5VHF.js.map → chunk-HY3MBSNC.js.map} +1 -1
  48. package/dist/{chunk-7IRH7MGV.js → chunk-IHX2SN35.js} +9 -9
  49. package/dist/{chunk-7IRH7MGV.js.map → chunk-IHX2SN35.js.map} +1 -1
  50. package/dist/{chunk-3F54MH2T.js → chunk-JAFEMG7W.js} +4 -4
  51. package/dist/{chunk-3F54MH2T.js.map → chunk-JAFEMG7W.js.map} +1 -1
  52. package/dist/{chunk-X6BPVUV2.js → chunk-L3TS7ZO4.js} +3 -3
  53. package/dist/{chunk-X6BPVUV2.js.map → chunk-L3TS7ZO4.js.map} +1 -1
  54. package/dist/{chunk-RIEXN7WA.js → chunk-MADO7PH5.js} +2 -2
  55. package/dist/{chunk-RIEXN7WA.js.map → chunk-MADO7PH5.js.map} +1 -1
  56. package/dist/{chunk-BCTU4TN7.js → chunk-MWFYXUFK.js} +3 -3
  57. package/dist/{chunk-BCTU4TN7.js.map → chunk-MWFYXUFK.js.map} +1 -1
  58. package/dist/{chunk-TK66CMXV.js → chunk-NU4E7C5I.js} +7 -3
  59. package/dist/chunk-NU4E7C5I.js.map +1 -0
  60. package/dist/{chunk-ZE2KEPE2.js → chunk-OEGHKO5N.js} +258 -24
  61. package/dist/chunk-OEGHKO5N.js.map +1 -0
  62. package/dist/{chunk-63ZPKREA.js → chunk-P43HBWKK.js} +11 -4
  63. package/dist/chunk-P43HBWKK.js.map +1 -0
  64. package/dist/{chunk-7UZGKVSK.js → chunk-PJ6INYDD.js} +3 -3
  65. package/dist/{chunk-7UZGKVSK.js.map → chunk-PJ6INYDD.js.map} +1 -1
  66. package/dist/{chunk-CA5CWLGN.js → chunk-PKEAYYEJ.js} +7 -4
  67. package/dist/chunk-PKEAYYEJ.js.map +1 -0
  68. package/dist/{chunk-ETFETLLB.js → chunk-UZYTSIX6.js} +6 -6
  69. package/dist/{chunk-ETFETLLB.js.map → chunk-UZYTSIX6.js.map} +1 -1
  70. package/dist/{chunk-SIF5F5SN.js → chunk-V4ZLZJFN.js} +3 -3
  71. package/dist/{chunk-SIF5F5SN.js.map → chunk-V4ZLZJFN.js.map} +1 -1
  72. package/dist/{chunk-ZR5Q4KZK.js → chunk-VNIKF66R.js} +3 -3
  73. package/dist/{chunk-ZR5Q4KZK.js.map → chunk-VNIKF66R.js.map} +1 -1
  74. package/dist/{chunk-CILACPUC.js → chunk-WSARNOPP.js} +5 -5
  75. package/dist/{chunk-CILACPUC.js.map → chunk-WSARNOPP.js.map} +1 -1
  76. package/dist/{chunk-TAJBFYCT.js → chunk-YWPEDILM.js} +83 -36
  77. package/dist/chunk-YWPEDILM.js.map +1 -0
  78. package/dist/{chunk-UNP4M5ZZ.js → chunk-ZR2X4SIG.js} +4 -4
  79. package/dist/{chunk-UNP4M5ZZ.js.map → chunk-ZR2X4SIG.js.map} +1 -1
  80. package/dist/cli/index.js +50 -50
  81. package/dist/connectors/config.js +1 -1
  82. package/dist/connectors/index.js +6 -6
  83. package/dist/core/index.js +1 -1
  84. package/dist/core/src/subprocess.d.ts +5 -1
  85. package/dist/core/src/subprocess.d.ts.map +1 -1
  86. package/dist/deploy/index.js +1 -1
  87. package/dist/discovery/index.js +1 -1
  88. package/dist/{ensure-sources-R6KW7K3M.js → ensure-sources-QF72HVUM.js} +8 -8
  89. package/dist/{ensure-sources-R6KW7K3M.js.map → ensure-sources-QF72HVUM.js.map} +1 -1
  90. package/dist/factory-assets/connectors/box.js +6 -6
  91. package/dist/factory-assets/connectors/deploy.js +6 -6
  92. package/dist/factory-assets/connectors/devserver.js +6 -6
  93. package/dist/factory-assets/connectors/flow/CONNECTOR.md +61 -14
  94. package/dist/factory-assets/connectors/flow/adapter.d.ts +78 -34
  95. package/dist/factory-assets/connectors/flow/adapter.d.ts.map +1 -1
  96. package/dist/factory-assets/connectors/flow/adapter.js +6 -6
  97. package/dist/factory-assets/connectors/flow/contract/expression.d.ts +55 -0
  98. package/dist/factory-assets/connectors/flow/contract/expression.d.ts.map +1 -1
  99. package/dist/factory-assets/connectors/flow/contract/flow.v2.schema.json +61 -134
  100. package/dist/factory-assets/connectors/flow/contract/index.d.ts +1 -1
  101. package/dist/factory-assets/connectors/flow/contract/index.d.ts.map +1 -1
  102. package/dist/factory-assets/connectors/flow/contract/normalize.d.ts.map +1 -1
  103. package/dist/factory-assets/connectors/flow/contract/schema.d.ts +14 -2
  104. package/dist/factory-assets/connectors/flow/contract/schema.d.ts.map +1 -1
  105. package/dist/factory-assets/connectors/flow/contract.js +2 -2
  106. package/dist/factory-assets/connectors/flow/engine/bindings.d.ts +9 -0
  107. package/dist/factory-assets/connectors/flow/engine/bindings.d.ts.map +1 -0
  108. package/dist/factory-assets/connectors/flow/engine/engine.d.ts +11 -6
  109. package/dist/factory-assets/connectors/flow/engine/engine.d.ts.map +1 -1
  110. package/dist/factory-assets/connectors/flow/engine/flow-kind-provider.d.ts.map +1 -1
  111. package/dist/factory-assets/connectors/flow/engine/index.d.ts +2 -0
  112. package/dist/factory-assets/connectors/flow/engine/index.d.ts.map +1 -1
  113. package/dist/factory-assets/connectors/flow/engine/node-shape.d.ts +22 -0
  114. package/dist/factory-assets/connectors/flow/engine/node-shape.d.ts.map +1 -1
  115. package/dist/factory-assets/connectors/flow/engine/output-schema.d.ts +18 -0
  116. package/dist/factory-assets/connectors/flow/engine/output-schema.d.ts.map +1 -0
  117. package/dist/factory-assets/connectors/flow/engine/types.d.ts +21 -15
  118. package/dist/factory-assets/connectors/flow/engine/types.d.ts.map +1 -1
  119. package/dist/factory-assets/connectors/flow/engine.js +4 -4
  120. package/dist/factory-assets/connectors/flow/index.d.ts +3 -0
  121. package/dist/factory-assets/connectors/flow/index.d.ts.map +1 -1
  122. package/dist/factory-assets/connectors/flow/inline-sub-flow-host.d.ts +48 -0
  123. package/dist/factory-assets/connectors/flow/inline-sub-flow-host.d.ts.map +1 -0
  124. package/dist/factory-assets/connectors/flow/node-executor.d.ts +45 -0
  125. package/dist/factory-assets/connectors/flow/node-executor.d.ts.map +1 -0
  126. package/dist/factory-assets/connectors/flow/prompt-fragments.d.ts +3 -2
  127. package/dist/factory-assets/connectors/flow/prompt-fragments.d.ts.map +1 -1
  128. package/dist/factory-assets/connectors/flow/prompt-fragments.js +2 -2
  129. package/dist/factory-assets/connectors/flow/run-flow.d.ts +10 -9
  130. package/dist/factory-assets/connectors/flow/run-flow.d.ts.map +1 -1
  131. package/dist/factory-assets/connectors/flow/run-flow.js +7 -7
  132. package/dist/factory-assets/connectors/flow/sub-flow-runner.d.ts +73 -0
  133. package/dist/factory-assets/connectors/flow/sub-flow-runner.d.ts.map +1 -0
  134. package/dist/factory-assets/connectors/flow.js +6 -6
  135. package/dist/factory-assets/connectors/git.js +6 -6
  136. package/dist/factory-assets/connectors/gmail.js +6 -6
  137. package/dist/factory-assets/connectors/googledrive.js +6 -6
  138. package/dist/factory-assets/connectors/local.js +6 -6
  139. package/dist/factory-assets/connectors/mattermost.js +6 -6
  140. package/dist/factory-assets/connectors/memory.js +6 -6
  141. package/dist/factory-assets/connectors/minio.js +6 -6
  142. package/dist/factory-assets/connectors/postgres.js +6 -6
  143. package/dist/factory-assets/connectors/s3.js +6 -6
  144. package/dist/factory-assets/connectors/sharepoint.js +6 -6
  145. package/dist/factory-assets/connectors/sqlite.js +6 -6
  146. package/dist/factory-assets/connectors/static-server.js +6 -6
  147. package/dist/factory-assets/connectors/tunnel.js +6 -6
  148. package/dist/factory-assets/connectors/webdav.js +6 -6
  149. package/dist/factory-assets/connectors/xstate-store.js +6 -6
  150. package/dist/factory-assets/connectors/xstate.js +6 -6
  151. package/dist/{flows-F3CJNMK6.js → flows-YIW4HL3L.js} +4 -4
  152. package/dist/{flows-F3CJNMK6.js.map → flows-YIW4HL3L.js.map} +1 -1
  153. package/dist/{helpers-KPOLCGKX.js → helpers-LURCZHA4.js} +8 -8
  154. package/dist/{helpers-KPOLCGKX.js.map → helpers-LURCZHA4.js.map} +1 -1
  155. package/dist/library/index.js +3 -3
  156. package/dist/library/install.js +1 -1
  157. package/dist/{library-publish-ZAPZS64O.js → library-publish-2GMJM3NZ.js} +14 -14
  158. package/dist/{library-publish-ZAPZS64O.js.map → library-publish-2GMJM3NZ.js.map} +1 -1
  159. package/dist/{open-library-I4F2UNOY.js → open-library-POFOXZWH.js} +12 -12
  160. package/dist/{open-library-I4F2UNOY.js.map → open-library-POFOXZWH.js.map} +1 -1
  161. package/dist/{paths-KBACHM5B.js → paths-ZLX4ITAQ.js} +6 -6
  162. package/dist/{paths-KBACHM5B.js.map → paths-ZLX4ITAQ.js.map} +1 -1
  163. package/dist/{plugin-store-CYSNVZIX.js → plugin-store-YIMNH2FH.js} +3 -3
  164. package/dist/{plugin-store-CYSNVZIX.js.map → plugin-store-YIMNH2FH.js.map} +1 -1
  165. package/dist/{project-SIHZBTGB.js → project-GVOPZEJZ.js} +9 -9
  166. package/dist/{project-SIHZBTGB.js.map → project-GVOPZEJZ.js.map} +1 -1
  167. package/dist/resolver/index.js +1 -1
  168. package/dist/runner/index.js +15 -12
  169. package/dist/runner/src/serve.d.ts +3 -1
  170. package/dist/runner/src/serve.d.ts.map +1 -1
  171. package/dist/sdk/asset-manager.js +5 -5
  172. package/dist/sdk/bridge.js +2 -2
  173. package/dist/sdk/core.js +1 -1
  174. package/dist/sdk/flow.js +4 -4
  175. package/dist/sdk/index.js +15 -12
  176. package/dist/sdk/index.js.map +1 -1
  177. package/dist/sdk/resolver.js +1 -1
  178. package/dist/sdk/runner.js +15 -12
  179. package/dist/sdk/session.js +2 -2
  180. package/dist/sdk/types.js +1 -1
  181. package/dist/session/index.js +2 -2
  182. package/dist/session/src/dispatcher.d.ts.map +1 -1
  183. package/dist/{setup-KMBXMV25.js → setup-RHWARBBB.js} +5 -5
  184. package/dist/{setup-KMBXMV25.js.map → setup-RHWARBBB.js.map} +1 -1
  185. package/dist/{skills-LHS4TOKK.js → skills-HGVH6UTA.js} +5 -5
  186. package/dist/{skills-LHS4TOKK.js.map → skills-HGVH6UTA.js.map} +1 -1
  187. package/dist/{source-X226ZJPR.js → source-FB3T4IHP.js} +13 -13
  188. package/dist/{source-X226ZJPR.js.map → source-FB3T4IHP.js.map} +1 -1
  189. package/dist/{source-manifest-publish-N2QVUR5U.js → source-manifest-publish-XTRDVPSC.js} +15 -15
  190. package/dist/{source-manifest-publish-N2QVUR5U.js.map → source-manifest-publish-XTRDVPSC.js.map} +1 -1
  191. package/dist/tui/index.js +15 -12
  192. package/dist/tui/index.js.map +1 -1
  193. package/dist/types/index.js +1 -1
  194. package/dist/types/src/events.d.ts +20 -1
  195. package/dist/types/src/events.d.ts.map +1 -1
  196. package/dist/types/src/flow.d.ts +26 -0
  197. package/dist/types/src/flow.d.ts.map +1 -1
  198. package/dist/types/src/index.d.ts +1 -1
  199. package/dist/types/src/index.d.ts.map +1 -1
  200. package/dist/types/src/protocol.d.ts +1 -0
  201. package/dist/types/src/protocol.d.ts.map +1 -1
  202. package/dist/types/src/version.d.ts +12 -1
  203. package/dist/types/src/version.d.ts.map +1 -1
  204. package/dist/workspace-plugin/adapters/mcp.js +4 -4
  205. package/dist/workspace-plugin/adapters/omp.js +7 -7
  206. package/dist/workspace-plugin/index.js +1 -1
  207. package/package.json +1 -1
  208. package/dist/chunk-63ZPKREA.js.map +0 -1
  209. package/dist/chunk-CA5CWLGN.js.map +0 -1
  210. package/dist/chunk-DZM33LQO.js.map +0 -1
  211. package/dist/chunk-FB4GPWYC.js.map +0 -1
  212. package/dist/chunk-LD6YGIKZ.js.map +0 -1
  213. package/dist/chunk-PTS3QN5P.js.map +0 -1
  214. package/dist/chunk-TAJBFYCT.js.map +0 -1
  215. package/dist/chunk-TK66CMXV.js.map +0 -1
  216. package/dist/chunk-UQ3RJKDD.js.map +0 -1
  217. package/dist/chunk-ZE2KEPE2.js.map +0 -1
@@ -1,15 +1,69 @@
1
- import { parseFlowDefinition } from './chunk-ZE2KEPE2.js';
2
- import { nodeIsOptional, nodeSkillId, nodeLabel, isAgentNode } from './chunk-DZM33LQO.js';
1
+ import { resolveFlowBindings, stableFlowJson, parseFlowDefinition, evaluateFlowExpression, inspectFlowExpression, collectFlowBindingExpressions } from './chunk-OEGHKO5N.js';
2
+ import { isAgentNode, nodeBindings, nodeIsOptional, nodeSkillId, nodeLabel, isActiveRuntimeNode } from './chunk-4QROZZ5Z.js';
3
3
  import { assetSearchDirs } from './chunk-ZAP2BDHG.js';
4
+ import * as z2 from 'zod';
4
5
  import * as path from 'path';
5
6
  import path__default from 'path';
6
- import * as z from 'zod';
7
7
  import fs from 'fs';
8
8
  import { parse } from 'yaml';
9
9
 
10
+ // factory-assets/connectors/flow/engine/bindings.ts
11
+ function buildFlowExpressionContext(flow, snapshots) {
12
+ const nodes = {};
13
+ for (const node of flow.nodes) {
14
+ const snapshot = snapshots.get(node.id);
15
+ const output = snapshot?.status === "complete" && snapshot.output?.fields ? { fields: snapshot.output.fields } : void 0;
16
+ nodes[node.id] = { status: snapshot?.status ?? "not_started", output };
17
+ }
18
+ return {
19
+ flow: { input: flow.defaults?.run_input ?? {} },
20
+ defaults: flow.defaults,
21
+ nodes
22
+ };
23
+ }
24
+ function resolveNodeBindings(flow, node, snapshots, flowInputOrigins = {}) {
25
+ const origins = Object.fromEntries(
26
+ flow.nodes.map((producer) => [producer.id, isAgentNode(producer) ? "agent" : "runtime"])
27
+ );
28
+ return resolveFlowBindings(
29
+ nodeBindings(node),
30
+ buildFlowExpressionContext(flow, snapshots),
31
+ origins,
32
+ flowInputOrigins
33
+ );
34
+ }
35
+ function interpolateNodeInstruction(instruction, values) {
36
+ return instruction.replace(/\$\{([A-Za-z_][A-Za-z0-9_-]*)\}/g, (_placeholder, name) => {
37
+ if (!Object.hasOwn(values, name)) {
38
+ throw new Error(`Node instruction binding ${name} is missing`);
39
+ }
40
+ const value = values[name];
41
+ return typeof value === "string" ? value : stableFlowJson(value);
42
+ });
43
+ }
44
+
10
45
  // factory-assets/connectors/flow/engine/engine.ts
11
- function agentNodes(flow) {
12
- return flow.nodes.filter(isAgentNode);
46
+ function activeRuntimeNodes(flow) {
47
+ return flow.nodes.filter(isActiveRuntimeNode);
48
+ }
49
+ function failedPreconditions(node, context) {
50
+ const failures = [];
51
+ for (const requirement of node.contract?.requires ?? []) {
52
+ const message = requirement.message ?? `Precondition failed: ${requirement.expr}`;
53
+ try {
54
+ if (!evaluateFlowExpression(requirement.expr, context)) {
55
+ failures.push({ expression: requirement.expr, message, reason: "false" });
56
+ }
57
+ } catch (error) {
58
+ failures.push({
59
+ expression: requirement.expr,
60
+ message,
61
+ reason: "error",
62
+ detail: error instanceof Error ? error.message : "Flow expression evaluation failed"
63
+ });
64
+ }
65
+ }
66
+ return failures;
13
67
  }
14
68
  function buildIncoming(edges) {
15
69
  const map = /* @__PURE__ */ new Map();
@@ -28,8 +82,14 @@ function buildOutgoing(edges) {
28
82
  return map;
29
83
  }
30
84
  function computeFlowState(flow, completedIds, runningIds = /* @__PURE__ */ new Set(), skippedIds = /* @__PURE__ */ new Set()) {
31
- const nodes = agentNodes(flow);
85
+ const nodes = activeRuntimeNodes(flow);
32
86
  const incoming = buildIncoming(flow.edges);
87
+ const snapshots = /* @__PURE__ */ new Map();
88
+ for (const node of nodes) {
89
+ const status = completedIds.has(node.id) ? "complete" : runningIds.has(node.id) ? "running" : skippedIds.has(node.id) ? "skipped" : "not_started";
90
+ snapshots.set(node.id, { status });
91
+ }
92
+ const context = buildFlowExpressionContext(flow, snapshots);
33
93
  const nodeStates = nodes.map((node) => {
34
94
  const optional = nodeIsOptional(node);
35
95
  const skillId = nodeSkillId(node);
@@ -42,7 +102,8 @@ function computeFlowState(flow, completedIds, runningIds = /* @__PURE__ */ new S
42
102
  status: "complete",
43
103
  optional,
44
104
  canRun: false,
45
- blockers: []
105
+ blockers: [],
106
+ failedPreconditions: []
46
107
  };
47
108
  }
48
109
  if (runningIds.has(node.id)) {
@@ -53,7 +114,8 @@ function computeFlowState(flow, completedIds, runningIds = /* @__PURE__ */ new S
53
114
  status: "running",
54
115
  optional,
55
116
  canRun: false,
56
- blockers: []
117
+ blockers: [],
118
+ failedPreconditions: []
57
119
  };
58
120
  }
59
121
  if (skippedIds.has(node.id)) {
@@ -64,19 +126,30 @@ function computeFlowState(flow, completedIds, runningIds = /* @__PURE__ */ new S
64
126
  status: "skipped",
65
127
  optional,
66
128
  canRun: false,
67
- blockers: []
129
+ blockers: [],
130
+ failedPreconditions: []
68
131
  };
69
132
  }
70
133
  const edges = incoming.get(node.id) ?? [];
71
134
  const hardBlockers = edges.filter((e) => e.type === "flow").filter((e) => !completedIds.has(e.source) && !skippedIds.has(e.source)).map((e) => e.source);
72
- const canRun = hardBlockers.length === 0;
135
+ const preconditionFailures = failedPreconditions(node, context);
136
+ const canRun = hardBlockers.length === 0 && preconditionFailures.length === 0;
73
137
  let status;
74
138
  if (!canRun) {
75
139
  status = "not_started";
76
140
  } else {
77
141
  status = "available";
78
142
  }
79
- return { nodeId: node.id, skillId, label, status, optional, canRun, blockers: hardBlockers };
143
+ return {
144
+ nodeId: node.id,
145
+ skillId,
146
+ label,
147
+ status,
148
+ optional,
149
+ canRun,
150
+ blockers: hardBlockers,
151
+ failedPreconditions: preconditionFailures
152
+ };
80
153
  });
81
154
  new Map(nodeStates.map((s) => [s.nodeId, s]));
82
155
  const available = nodeStates.filter((s) => s.status === "available").map((s) => s.nodeId);
@@ -89,8 +162,9 @@ function computeFlowState(flow, completedIds, runningIds = /* @__PURE__ */ new S
89
162
  return { flowId: flow.id, nodes: nodeStates, available, completed, focus, done };
90
163
  }
91
164
  function computeFlowStateFromSnapshots(flow, snapshots) {
92
- const nodes = agentNodes(flow);
165
+ const nodes = activeRuntimeNodes(flow);
93
166
  const incoming = buildIncoming(flow.edges);
167
+ const context = buildFlowExpressionContext(flow, snapshots);
94
168
  const statusFor = (nodeId) => snapshots.get(nodeId)?.status ?? "not_started";
95
169
  const passed = (nodeId) => {
96
170
  const s = statusFor(nodeId);
@@ -105,9 +179,11 @@ function computeFlowStateFromSnapshots(flow, snapshots) {
105
179
  const edges = incoming.get(node.id) ?? [];
106
180
  const flowPreds = edges.filter((e) => e.type === "flow");
107
181
  const hardBlockers = flowPreds.filter((e) => !passed(e.source)).map((e) => e.source);
182
+ const isAdmissionState = status === "not_started" || status === "available";
183
+ const preconditionFailures = isAdmissionState ? failedPreconditions(node, context) : [];
108
184
  let effectiveStatus = status;
109
- if (status === "not_started" && hardBlockers.length === 0) {
110
- effectiveStatus = "available";
185
+ if (isAdmissionState) {
186
+ effectiveStatus = hardBlockers.length === 0 && preconditionFailures.length === 0 ? "available" : "not_started";
111
187
  }
112
188
  return {
113
189
  nodeId: node.id,
@@ -115,8 +191,9 @@ function computeFlowStateFromSnapshots(flow, snapshots) {
115
191
  label,
116
192
  status: effectiveStatus,
117
193
  optional,
118
- canRun: hardBlockers.length === 0 && effectiveStatus === "available",
194
+ canRun: hardBlockers.length === 0 && preconditionFailures.length === 0 && effectiveStatus === "available",
119
195
  blockers: hardBlockers,
196
+ failedPreconditions: preconditionFailures,
120
197
  approval: snapshot?.approval,
121
198
  input: snapshot?.input,
122
199
  output: snapshot?.output,
@@ -154,7 +231,7 @@ function resolveNextNodes(flow, justCompleted, completedIds, skippedIds = /* @__
154
231
  return result;
155
232
  }
156
233
  function computeSkippable(flow, completedIds) {
157
- const nodes = agentNodes(flow);
234
+ const nodes = activeRuntimeNodes(flow);
158
235
  const outgoing = buildOutgoing(flow.edges);
159
236
  return nodes.filter((n) => !completedIds.has(n.id)).filter(nodeIsOptional).filter((n) => {
160
237
  const deps = (outgoing.get(n.id) ?? []).filter((e) => e.type === "flow");
@@ -164,47 +241,93 @@ function computeSkippable(flow, completedIds) {
164
241
  });
165
242
  }).map((n) => n.id);
166
243
  }
167
- var FlowNodeSchema = z.looseObject({
168
- id: z.string().min(1),
169
- skill: z.string().optional(),
170
- type: z.string().optional(),
171
- label: z.string().optional(),
172
- description: z.string().optional(),
173
- data: z.looseObject({
174
- optional: z.boolean().optional(),
244
+ function consumerExpressions(node) {
245
+ const expressions = (node.contract?.requires ?? []).map(({ expr }) => expr);
246
+ expressions.push(...collectFlowBindingExpressions(node.contract?.input));
247
+ if (node.run?.kind === "router") {
248
+ expressions.push(...node.run.routes.map(({ when }) => when));
249
+ }
250
+ return expressions;
251
+ }
252
+ function readsProducerOutput(node, producerId) {
253
+ return consumerExpressions(node).some(
254
+ (expression) => inspectFlowExpression(expression, false).some(
255
+ ({ path: path3 }) => path3.startsWith(`nodes.${producerId}.output.fields.`)
256
+ )
257
+ );
258
+ }
259
+ function getConsumedOutputSchema(flow, producerId) {
260
+ const producer = flow.nodes.find(({ id }) => id === producerId);
261
+ const schema = producer?.contract?.output?.fields;
262
+ if (!schema) return void 0;
263
+ return flow.nodes.some(
264
+ (consumer) => consumer.id !== producerId && readsProducerOutput(consumer, producerId)
265
+ ) ? schema : void 0;
266
+ }
267
+ function validateConsumedNodeOutput(flow, producerId, fields) {
268
+ const schema = getConsumedOutputSchema(flow, producerId);
269
+ if (!schema) return { valid: true, issues: [] };
270
+ try {
271
+ const validator = z2.fromJSONSchema(schema);
272
+ const parsed = validator.safeParse(fields ?? {});
273
+ if (parsed.success) return { valid: true, issues: [] };
274
+ return {
275
+ valid: false,
276
+ issues: parsed.error.issues.map((issue) => {
277
+ const suffix = issue.path.map(String).join(".");
278
+ return `fields${suffix ? `.${suffix}` : ""}: ${issue.message}`;
279
+ }).sort()
280
+ };
281
+ } catch (error) {
282
+ return {
283
+ valid: false,
284
+ issues: [
285
+ `fields: invalid authored JSON Schema: ${error instanceof Error ? error.message : String(error)}`
286
+ ]
287
+ };
288
+ }
289
+ }
290
+ var FlowNodeSchema = z2.looseObject({
291
+ id: z2.string().min(1),
292
+ skill: z2.string().optional(),
293
+ type: z2.string().optional(),
294
+ label: z2.string().optional(),
295
+ description: z2.string().optional(),
296
+ data: z2.looseObject({
297
+ optional: z2.boolean().optional(),
175
298
  // Mandatory approval gate — autonomous mode cannot skip it.
176
- approval: z.looseObject({ mandatory: z.boolean().optional() }).optional()
299
+ approval: z2.looseObject({ mandatory: z2.boolean().optional() }).optional()
177
300
  }).refine((d) => !(d.optional === true && d.approval?.mandatory === true), {
178
301
  // A mandatory gate can never be skipped, so optional+mandatory is a
179
302
  // contradiction — reject it rather than silently letting mandatory win.
180
303
  message: "a node cannot be both optional and a mandatory approval gate"
181
304
  }).optional()
182
305
  });
183
- var FlowEdgeSchema = z.looseObject({
184
- id: z.string().optional(),
185
- source: z.string().min(1),
186
- target: z.string().min(1),
187
- condition: z.string().optional()
306
+ var FlowEdgeSchema = z2.looseObject({
307
+ id: z2.string().optional(),
308
+ source: z2.string().min(1),
309
+ target: z2.string().min(1),
310
+ condition: z2.string().optional()
188
311
  });
189
- var FlowManifestSchema = z.looseObject({
190
- id: z.string().min(1),
191
- version: z.string().optional(),
192
- name: z.string().min(1),
193
- description: z.string().optional(),
194
- metadata: z.looseObject({
195
- tags: z.array(z.string()).optional(),
196
- stage: z.string().optional(),
197
- icon: z.string().optional(),
198
- category: z.string().optional(),
199
- onboarding: z.record(z.string(), z.unknown()).optional()
312
+ var FlowManifestSchema = z2.looseObject({
313
+ id: z2.string().min(1),
314
+ version: z2.string().optional(),
315
+ name: z2.string().min(1),
316
+ description: z2.string().optional(),
317
+ metadata: z2.looseObject({
318
+ tags: z2.array(z2.string()).optional(),
319
+ stage: z2.string().optional(),
320
+ icon: z2.string().optional(),
321
+ category: z2.string().optional(),
322
+ onboarding: z2.record(z2.string(), z2.unknown()).optional()
200
323
  }).optional(),
201
- globals: z.record(z.string(), z.unknown()).optional(),
202
- modes: z.record(z.string(), z.unknown()).optional(),
203
- tier_presets: z.record(z.string(), z.record(z.string(), z.unknown())).optional(),
204
- artifact_handoff: z.unknown().optional(),
205
- entry: z.string().optional(),
206
- nodes: z.array(FlowNodeSchema).optional(),
207
- edges: z.array(FlowEdgeSchema).optional()
324
+ globals: z2.record(z2.string(), z2.unknown()).optional(),
325
+ modes: z2.record(z2.string(), z2.unknown()).optional(),
326
+ tier_presets: z2.record(z2.string(), z2.record(z2.string(), z2.unknown())).optional(),
327
+ artifact_handoff: z2.unknown().optional(),
328
+ entry: z2.string().optional(),
329
+ nodes: z2.array(FlowNodeSchema).optional(),
330
+ edges: z2.array(FlowEdgeSchema).optional()
208
331
  });
209
332
  function validateFlow(data) {
210
333
  const result = FlowManifestSchema.safeParse(data);
@@ -258,13 +381,17 @@ var flowKindProvider = {
258
381
  if (typeof asset === "string") add(asset, "nodes[].run.assets");
259
382
  }
260
383
  }
384
+ if (run.kind === "sub-flow" && typeof run.flow === "string") {
385
+ const flowRef = run.flow.startsWith("flow:") ? run.flow : `flow:${run.flow}`;
386
+ add(flowRef, "nodes[].run.flow");
387
+ }
261
388
  const skill = typeof data.skill === "string" ? data.skill : n.skill;
262
389
  if (typeof skill === "string") {
263
390
  add(skill, "nodes[].data.skill");
264
391
  }
265
392
  const subFlow = typeof data.flow === "string" ? data.flow : n.flow;
266
393
  if (typeof subFlow === "string") {
267
- add(subFlow, "nodes[].data.flow");
394
+ add(subFlow.startsWith("flow:") ? subFlow : `flow:${subFlow}`, "nodes[].data.flow");
268
395
  }
269
396
  }
270
397
  }
@@ -314,6 +441,6 @@ function loadAllFlows(aiResourcesRoot) {
314
441
  return [...byId.values()];
315
442
  }
316
443
 
317
- export { FlowManifestSchema, computeFlowState, computeFlowStateFromSnapshots, computeSkippable, flowKindProvider, isBlocking, loadAllFlows, loadFlow, loadFlowsFromDir, resolveNextNodes, validateFlow };
318
- //# sourceMappingURL=chunk-UQ3RJKDD.js.map
319
- //# sourceMappingURL=chunk-UQ3RJKDD.js.map
444
+ export { FlowManifestSchema, buildFlowExpressionContext, computeFlowState, computeFlowStateFromSnapshots, computeSkippable, flowKindProvider, getConsumedOutputSchema, interpolateNodeInstruction, isBlocking, loadAllFlows, loadFlow, loadFlowsFromDir, resolveNextNodes, resolveNodeBindings, validateConsumedNodeOutput, validateFlow };
445
+ //# sourceMappingURL=chunk-4O2RAXKJ.js.map
446
+ //# sourceMappingURL=chunk-4O2RAXKJ.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../factory-assets/connectors/flow/engine/bindings.ts","../factory-assets/connectors/flow/engine/engine.ts","../factory-assets/connectors/flow/engine/output-schema.ts","../factory-assets/connectors/flow/engine/flow-manifest.ts","../factory-assets/connectors/flow/engine/flow-kind-provider.ts","../factory-assets/connectors/flow/engine/loader.ts"],"names":["path","z","parseYaml"],"mappings":"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","file":"chunk-4O2RAXKJ.js","sourcesContent":["import {\n resolveFlowBindings,\n stableFlowJson,\n type BindingOrigin,\n type FlowExpressionContext,\n type ResolvedNodeBindings,\n} from \"../contract/expression.js\";\nimport { isAgentNode, nodeBindings } from \"./node-shape.js\";\nimport type { FlowDefinition, FlowNode, NodeExecutionSnapshot } from \"./types.js\";\n\n/** Build the bounded expression context from immutable definition and snapshot state. */\nexport function buildFlowExpressionContext(\n flow: FlowDefinition,\n snapshots: Map<string, NodeExecutionSnapshot>,\n): FlowExpressionContext {\n const nodes: FlowExpressionContext[\"nodes\"] = {};\n for (const node of flow.nodes) {\n const snapshot = snapshots.get(node.id);\n const output =\n snapshot?.status === \"complete\" && snapshot.output?.fields\n ? { fields: snapshot.output.fields }\n : undefined;\n nodes[node.id] = { status: snapshot?.status ?? \"not_started\", output };\n }\n return {\n flow: { input: flow.defaults?.run_input ?? {} },\n defaults: flow.defaults,\n nodes,\n };\n}\n\n/** Resolve one node's named inputs and derive their runtime/agent origins. */\nexport function resolveNodeBindings(\n flow: FlowDefinition,\n node: FlowNode,\n snapshots: Map<string, NodeExecutionSnapshot>,\n flowInputOrigins: Record<string, BindingOrigin[]> = {},\n): ResolvedNodeBindings {\n const origins = Object.fromEntries(\n flow.nodes.map((producer) => [producer.id, isAgentNode(producer) ? \"agent\" : \"runtime\"]),\n ) as Record<string, \"agent\" | \"runtime\">;\n return resolveFlowBindings(\n nodeBindings(node),\n buildFlowExpressionContext(flow, snapshots),\n origins,\n flowInputOrigins,\n );\n}\n\n/** Interpolate named, already-resolved binding values into an agent instruction. */\nexport function interpolateNodeInstruction(\n instruction: string,\n values: Record<string, unknown>,\n): string {\n return instruction.replace(/\\$\\{([A-Za-z_][A-Za-z0-9_-]*)\\}/g, (_placeholder, name: string) => {\n if (!Object.hasOwn(values, name)) {\n throw new Error(`Node instruction binding ${name} is missing`);\n }\n const value = values[name];\n return typeof value === \"string\" ? value : stableFlowJson(value);\n });\n}\n","import type {\n FlowDefinition,\n FlowEdge,\n FlowNode,\n FlowState,\n NodeExecutionSnapshot,\n NodePreconditionFailure,\n NodeState,\n NodeStatus,\n} from \"./types.js\";\nimport { evaluateFlowExpression, type FlowExpressionContext } from \"../contract/expression.js\";\nimport { buildFlowExpressionContext } from \"./bindings.js\";\nimport { isActiveRuntimeNode, nodeIsOptional, nodeLabel, nodeSkillId } from \"./node-shape.js\";\n\n// ---------------------------------------------------------------------------\n// Core engine — stateless, pure functions\n// ---------------------------------------------------------------------------\n\n/** Return nodes with state owned by the current runtime. */\nfunction activeRuntimeNodes(flow: FlowDefinition): FlowNode[] {\n return flow.nodes.filter(isActiveRuntimeNode);\n}\n\n/** Evaluate every authored admission condition without mutating runtime state. */\nfunction failedPreconditions(\n node: FlowNode,\n context: FlowExpressionContext,\n): NodePreconditionFailure[] {\n const failures: NodePreconditionFailure[] = [];\n for (const requirement of node.contract?.requires ?? []) {\n const message = requirement.message ?? `Precondition failed: ${requirement.expr}`;\n try {\n if (!evaluateFlowExpression(requirement.expr, context)) {\n failures.push({ expression: requirement.expr, message, reason: \"false\" });\n }\n } catch (error) {\n failures.push({\n expression: requirement.expr,\n message,\n reason: \"error\",\n detail: error instanceof Error ? error.message : \"Flow expression evaluation failed\",\n });\n }\n }\n return failures;\n}\n\n/** Build adjacency: target → sources[] (incoming edges per node) */\nfunction buildIncoming(edges: FlowEdge[]): Map<string, FlowEdge[]> {\n const map = new Map<string, FlowEdge[]>();\n for (const edge of edges) {\n if (!map.has(edge.target)) map.set(edge.target, []);\n map.get(edge.target)!.push(edge);\n }\n return map;\n}\n\n/** Build adjacency: source → targets[] (outgoing edges per node) */\nfunction buildOutgoing(edges: FlowEdge[]): Map<string, FlowEdge[]> {\n const map = new Map<string, FlowEdge[]>();\n for (const edge of edges) {\n if (!map.has(edge.source)) map.set(edge.source, []);\n map.get(edge.source)!.push(edge);\n }\n return map;\n}\n\n/**\n * Compute the full {@link FlowState} from a flow definition and caller-supplied node ID sets.\n *\n * This is the primary engine function. It is stateless and side-effect-free — calling it\n * twice with the same arguments always returns an equivalent result.\n *\n * Edge semantics applied during computation:\n * - `'flow'` — hard dependency: target cannot start until source is `complete` or `skipped`.\n * - `'parallel'` — soft dependency: target may run while source is still running.\n * - `'optional'` — advisory: target can start regardless of source state.\n *\n * A node is `available` when every incoming `'flow'`-type edge has a complete or skipped source\n * and every authored precondition evaluates true.\n * A node is `not_started` when at least one hard predecessor is still pending.\n * The flow is `done` when every non-optional node is `complete` or `skipped`.\n *\n * This set-based overload has statuses but no completed output fields. Use\n * {@link computeFlowStateFromSnapshots} when a precondition reads node output.\n *\n * Prefer {@link computeFlowStateFromSnapshots} for callers that track full `NodeExecution`\n * state (interaction statuses such as `awaiting_approval`, `awaiting_input`, `failed`).\n *\n * @param flow - The parsed flow definition.\n * @param completedIds - Set of node IDs that have finished successfully.\n * @param runningIds - Set of node IDs currently executing. Defaults to an empty set.\n * @param skippedIds - Set of node IDs that were explicitly skipped. Skipped nodes count\n * as satisfied for downstream dependency checks. Defaults to an empty set.\n * @returns A {@link FlowState} describing every active runtime node.\n * @docLink packages/flow-engine/concepts#compute-flow-state\n */\nexport function computeFlowState(\n flow: FlowDefinition,\n completedIds: Set<string>,\n runningIds: Set<string> = new Set(),\n skippedIds: Set<string> = new Set(),\n): FlowState {\n const nodes = activeRuntimeNodes(flow);\n const incoming = buildIncoming(flow.edges);\n const snapshots = new Map<string, NodeExecutionSnapshot>();\n for (const node of nodes) {\n const status: NodeStatus = completedIds.has(node.id)\n ? \"complete\"\n : runningIds.has(node.id)\n ? \"running\"\n : skippedIds.has(node.id)\n ? \"skipped\"\n : \"not_started\";\n snapshots.set(node.id, { status });\n }\n const context = buildFlowExpressionContext(flow, snapshots);\n\n const nodeStates: NodeState[] = nodes.map((node) => {\n const optional = nodeIsOptional(node);\n const skillId = nodeSkillId(node);\n const label = nodeLabel(node);\n\n if (completedIds.has(node.id)) {\n return {\n nodeId: node.id,\n skillId,\n label,\n status: \"complete\",\n optional,\n canRun: false,\n blockers: [],\n failedPreconditions: [],\n };\n }\n if (runningIds.has(node.id)) {\n return {\n nodeId: node.id,\n skillId,\n label,\n status: \"running\",\n optional,\n canRun: false,\n blockers: [],\n failedPreconditions: [],\n };\n }\n if (skippedIds.has(node.id)) {\n return {\n nodeId: node.id,\n skillId,\n label,\n status: \"skipped\",\n optional,\n canRun: false,\n blockers: [],\n failedPreconditions: [],\n };\n }\n\n const edges = incoming.get(node.id) ?? [];\n\n // Hard blockers: flow-type edges whose source is neither complete nor skipped\n const hardBlockers = edges\n .filter((e) => e.type === \"flow\")\n .filter((e) => !completedIds.has(e.source) && !skippedIds.has(e.source))\n .map((e) => e.source);\n\n const preconditionFailures = failedPreconditions(node, context);\n const canRun = hardBlockers.length === 0 && preconditionFailures.length === 0;\n\n let status: NodeStatus;\n if (!canRun) {\n status = \"not_started\";\n } else {\n status = \"available\";\n }\n\n return {\n nodeId: node.id,\n skillId,\n label,\n status,\n optional,\n canRun,\n blockers: hardBlockers,\n failedPreconditions: preconditionFailures,\n };\n });\n\n const _stateMap = new Map(nodeStates.map((s) => [s.nodeId, s]));\n\n const available = nodeStates.filter((s) => s.status === \"available\").map((s) => s.nodeId);\n const completed = nodeStates.filter((s) => s.status === \"complete\").map((s) => s.nodeId);\n const focus = nodeStates\n .filter(\n (s) =>\n s.status === \"running\" || s.status === \"awaiting_approval\" || s.status === \"awaiting_input\",\n )\n .map((s) => s.nodeId);\n\n // Flow is done when all required nodes are complete or skipped\n const requiredNodes = nodes.filter((n) => !nodeIsOptional(n));\n const done = requiredNodes.every((n) => completedIds.has(n.id) || skippedIds.has(n.id));\n\n return { flowId: flow.id, nodes: nodeStates, available, completed, focus, done };\n}\n\n/**\n * Snapshot-based variant of {@link computeFlowState}.\n *\n * Accepts a map of `NodeExecutionSnapshot` values carrying the current status and\n * interaction metadata for every node the caller knows about. Nodes absent from the\n * map are treated as `not_started`.\n *\n * This is the preferred API for the turn-based runner, which has a full `FlowExecution`\n * and needs to convey richer statuses (`awaiting_approval`, `awaiting_input`, `failed`)\n * back to the engine so downstream availability is computed correctly.\n *\n * Engine semantics:\n * - A node is `available` when all its incoming `'flow'`-type predecessors are `complete`\n * or `skipped`. Any other upstream status — including `awaiting_approval`,\n * `awaiting_input`, and `failed` — is treated as blocking. Every authored precondition\n * must also evaluate true against the snapshot expression context.\n * - A `failed` optional node does **not** block its dependents.\n * - The flow is `done` when every non-optional node is `complete` or `skipped`. A single\n * required node stuck in `failed` keeps `done` false.\n *\n * @param flow - The parsed flow definition.\n * @param snapshots - Map from node ID to its current {@link NodeExecutionSnapshot}.\n * Missing entries default to `not_started` with no interaction metadata.\n * @returns A {@link FlowState} describing every active runtime node,\n * including interaction fields (`approval`, `input`, `output`, `error`) copied\n * from the matching snapshot.\n * @docLink packages/flow-engine/concepts#compute-flow-state-from-snapshots\n */\nexport function computeFlowStateFromSnapshots(\n flow: FlowDefinition,\n snapshots: Map<string, NodeExecutionSnapshot>,\n): FlowState {\n const nodes = activeRuntimeNodes(flow);\n const incoming = buildIncoming(flow.edges);\n const context = buildFlowExpressionContext(flow, snapshots);\n\n /** Resolve the effective status for a node — defaulting to `not_started`. */\n const statusFor = (nodeId: string): NodeStatus => snapshots.get(nodeId)?.status ?? \"not_started\";\n\n /** A predecessor \"passes\" when it is complete or skipped. */\n const passed = (nodeId: string): boolean => {\n const s = statusFor(nodeId);\n return s === \"complete\" || s === \"skipped\";\n };\n\n const nodeStates: NodeState[] = nodes.map((node) => {\n const snapshot = snapshots.get(node.id);\n const optional = nodeIsOptional(node);\n const skillId = nodeSkillId(node);\n const label = nodeLabel(node);\n const status = snapshot?.status ?? \"not_started\";\n\n const edges = incoming.get(node.id) ?? [];\n const flowPreds = edges.filter((e) => e.type === \"flow\");\n const hardBlockers = flowPreds.filter((e) => !passed(e.source)).map((e) => e.source);\n\n const isAdmissionState = status === \"not_started\" || status === \"available\";\n const preconditionFailures = isAdmissionState ? failedPreconditions(node, context) : [];\n\n // Recompute admission in both directions after fresh start or hydrate.\n let effectiveStatus: NodeStatus = status;\n if (isAdmissionState) {\n effectiveStatus =\n hardBlockers.length === 0 && preconditionFailures.length === 0\n ? \"available\"\n : \"not_started\";\n }\n\n return {\n nodeId: node.id,\n skillId,\n label,\n status: effectiveStatus,\n optional,\n canRun:\n hardBlockers.length === 0 &&\n preconditionFailures.length === 0 &&\n effectiveStatus === \"available\",\n blockers: hardBlockers,\n failedPreconditions: preconditionFailures,\n approval: snapshot?.approval,\n input: snapshot?.input,\n output: snapshot?.output,\n error: snapshot?.error,\n };\n });\n\n const available = nodeStates.filter((s) => s.status === \"available\").map((s) => s.nodeId);\n const completed = nodeStates.filter((s) => s.status === \"complete\").map((s) => s.nodeId);\n const focus = nodeStates\n .filter(\n (s) =>\n s.status === \"running\" || s.status === \"awaiting_approval\" || s.status === \"awaiting_input\",\n )\n .map((s) => s.nodeId);\n\n const requiredNodes = nodes.filter((n) => !nodeIsOptional(n));\n const done = requiredNodes.every((n) => {\n const s = statusFor(n.id);\n return s === \"complete\" || s === \"skipped\";\n });\n\n return { flowId: flow.id, nodes: nodeStates, available, completed, focus, done };\n}\n\n/**\n * Returns `true` when the given status prevents downstream nodes from starting.\n *\n * Only `'complete'` and `'skipped'` satisfy a hard (`'flow'`-type) edge dependency.\n * All other statuses — including `'awaiting_approval'`, `'awaiting_input'`, and\n * `'failed'` — are considered blocking.\n *\n * Use this helper in the FlowAdapter and the turn-based orchestrator instead of\n * hard-coding the two-value whitelist inline.\n *\n * @param status - The {@link NodeStatus} to evaluate.\n * @returns `true` if the status prevents dependents from becoming `available`.\n * @docLink packages/flow-engine/concepts#is-blocking\n */\nexport function isBlocking(status: NodeStatus): boolean {\n return status !== \"complete\" && status !== \"skipped\";\n}\n\n/**\n * Returns the IDs of nodes that become newly `available` after a specific node completes.\n *\n * More efficient than recomputing the full {@link FlowState} when only the downstream\n * impact of a single completion is needed. Only the direct successors of `justCompleted`\n * are evaluated — the rest of the graph is untouched.\n *\n * @param flow - The parsed flow definition.\n * @param justCompleted - ID of the node that just finished (will be added to the\n * effective completed set before evaluating successors).\n * @param completedIds - Set of node IDs already known to be complete before this call.\n * @param skippedIds - Set of node IDs that were explicitly skipped. Defaults to an empty set.\n * @returns Array of node IDs whose hard dependencies are now fully satisfied and that\n * were not already available before `justCompleted` finished. Unlike executable-node-filtered\n * helpers, this walks raw edge targets and does not filter by node type — if a `group`,\n * `sub-flow`, or `router` node is a direct successor, its ID can appear here. Callers that\n * dispatch these IDs are responsible for filtering inert nodes.\n * @docLink packages/flow-engine/concepts#resolve-next-nodes\n */\nexport function resolveNextNodes(\n flow: FlowDefinition,\n justCompleted: string,\n completedIds: Set<string>,\n skippedIds: Set<string> = new Set(),\n): string[] {\n const outgoing = buildOutgoing(flow.edges);\n const incoming = buildIncoming(flow.edges);\n const candidates = (outgoing.get(justCompleted) ?? []).map((e) => e.target);\n\n const nextCompleted = new Set([...completedIds, justCompleted]);\n const result: string[] = [];\n\n for (const candidateId of candidates) {\n const edges = incoming.get(candidateId) ?? [];\n const hardBlockers = edges\n .filter((e) => e.type === \"flow\")\n .filter((e) => !nextCompleted.has(e.source) && !skippedIds.has(e.source));\n if (hardBlockers.length === 0) {\n result.push(candidateId);\n }\n }\n\n return result;\n}\n\n/**\n * Returns the IDs of optional nodes that have not yet started and can be safely skipped.\n *\n * A node is skippable when it is:\n * 1. Not yet complete (absent from `completedIds`).\n * 2. Marked `optional` (`FlowNode.data.optional === true`).\n * 3. Not connected via a `'flow'`-type edge to any non-optional downstream node\n * (i.e. skipping it cannot starve a required node of a hard dependency).\n *\n * The runner may call this to present the user with a list of nodes they can bypass\n * without breaking the flow's required path.\n *\n * @param flow - The parsed flow definition.\n * @param completedIds - Set of node IDs that have already completed (excluded from results).\n * @returns Array of node IDs that are safe to skip at this point in the execution.\n * @docLink packages/flow-engine/concepts#compute-skippable\n */\nexport function computeSkippable(flow: FlowDefinition, completedIds: Set<string>): string[] {\n const nodes = activeRuntimeNodes(flow);\n const outgoing = buildOutgoing(flow.edges);\n\n return nodes\n .filter((n) => !completedIds.has(n.id))\n .filter(nodeIsOptional)\n .filter((n) => {\n // A node is skippable if none of its outgoing flow-type edges go to a required node\n const deps = (outgoing.get(n.id) ?? []).filter((e) => e.type === \"flow\");\n return deps.every((e) => {\n const target = flow.nodes.find((t) => t.id === e.target);\n return target ? nodeIsOptional(target) : false;\n });\n })\n .map((n) => n.id);\n}\n","import * as z from \"zod\";\nimport { collectFlowBindingExpressions, inspectFlowExpression } from \"../contract/expression.js\";\nimport type { FlowDefinition, FlowNode } from \"./types.js\";\n\n/** Result of validating fields at a producer's consumed-output boundary. */\nexport interface NodeOutputValidationResult {\n /** Whether the fields may be exposed to downstream consumers. */\n valid: boolean;\n /** Stable, path-bearing failures. Empty when validation is not required. */\n issues: string[];\n}\n\nfunction consumerExpressions(node: FlowNode): string[] {\n const expressions = (node.contract?.requires ?? []).map(({ expr }) => expr);\n expressions.push(...collectFlowBindingExpressions(node.contract?.input));\n if (node.run?.kind === \"router\") {\n expressions.push(...node.run.routes.map(({ when }) => when));\n }\n return expressions;\n}\n\nfunction readsProducerOutput(node: FlowNode, producerId: string): boolean {\n return consumerExpressions(node).some((expression) =>\n inspectFlowExpression(expression, false).some(({ path }) =>\n path.startsWith(`nodes.${producerId}.output.fields.`),\n ),\n );\n}\n\n/**\n * Return a producer's declared fields schema only when another node reads it.\n *\n * Consumption is deliberately limited to preconditions, named bindings, and\n * router conditions. Status reads and unreferenced declarations remain prose-only.\n */\nexport function getConsumedOutputSchema(\n flow: FlowDefinition,\n producerId: string,\n): Record<string, unknown> | undefined {\n const producer = flow.nodes.find(({ id }) => id === producerId);\n const schema = producer?.contract?.output?.fields;\n if (!schema) return undefined;\n return flow.nodes.some(\n (consumer) => consumer.id !== producerId && readsProducerOutput(consumer, producerId),\n )\n ? schema\n : undefined;\n}\n\n/** Validate proposed fields only when a downstream deterministic consumer requires them. */\nexport function validateConsumedNodeOutput(\n flow: FlowDefinition,\n producerId: string,\n fields: Record<string, unknown> | undefined,\n): NodeOutputValidationResult {\n const schema = getConsumedOutputSchema(flow, producerId);\n if (!schema) return { valid: true, issues: [] };\n\n try {\n const validator = z.fromJSONSchema(schema as Parameters<typeof z.fromJSONSchema>[0]);\n const parsed = validator.safeParse(fields ?? {});\n if (parsed.success) return { valid: true, issues: [] };\n return {\n valid: false,\n issues: parsed.error.issues\n .map((issue) => {\n const suffix = issue.path.map(String).join(\".\");\n return `fields${suffix ? `.${suffix}` : \"\"}: ${issue.message}`;\n })\n .sort(),\n };\n } catch (error) {\n return {\n valid: false,\n issues: [\n `fields: invalid authored JSON Schema: ${\n error instanceof Error ? error.message : String(error)\n }`,\n ],\n };\n }\n}\n","/**\n * Flow manifest schema and validation.\n *\n * Moved from @skaile/workspaces/types/manifests/flow.ts in Phase 1.7.3.\n * This is now the canonical location for flow manifest validation.\n */\n\nimport * as z from \"zod\";\n\n// ---------------------------------------------------------------------------\n// Validation result (inline — avoids importing from types/manifests/_shared)\n// ---------------------------------------------------------------------------\n\nexport interface ManifestValidationSuccess<T> {\n ok: true;\n data: T;\n}\n\nexport interface ManifestValidationFailure {\n ok: false;\n errors: Array<{ path: string; message: string }>;\n}\n\nexport type ManifestValidationResult<T> = ManifestValidationSuccess<T> | ManifestValidationFailure;\n\n// ---------------------------------------------------------------------------\n// Schema\n// ---------------------------------------------------------------------------\n\nconst FlowNodeSchema = z.looseObject({\n id: z.string().min(1),\n skill: z.string().optional(),\n type: z.string().optional(),\n label: z.string().optional(),\n description: z.string().optional(),\n data: z\n .looseObject({\n optional: z.boolean().optional(),\n // Mandatory approval gate — autonomous mode cannot skip it.\n approval: z.looseObject({ mandatory: z.boolean().optional() }).optional(),\n })\n .refine((d) => !(d.optional === true && d.approval?.mandatory === true), {\n // A mandatory gate can never be skipped, so optional+mandatory is a\n // contradiction — reject it rather than silently letting mandatory win.\n message: \"a node cannot be both optional and a mandatory approval gate\",\n })\n .optional(),\n});\n\nconst FlowEdgeSchema = z.looseObject({\n id: z.string().optional(),\n source: z.string().min(1),\n target: z.string().min(1),\n condition: z.string().optional(),\n});\n\nexport const FlowManifestSchema = z.looseObject({\n id: z.string().min(1),\n version: z.string().optional(),\n name: z.string().min(1),\n description: z.string().optional(),\n metadata: z\n .looseObject({\n tags: z.array(z.string()).optional(),\n stage: z.string().optional(),\n icon: z.string().optional(),\n category: z.string().optional(),\n onboarding: z.record(z.string(), z.unknown()).optional(),\n })\n .optional(),\n globals: z.record(z.string(), z.unknown()).optional(),\n modes: z.record(z.string(), z.unknown()).optional(),\n tier_presets: z.record(z.string(), z.record(z.string(), z.unknown())).optional(),\n artifact_handoff: z.unknown().optional(),\n entry: z.string().optional(),\n nodes: z.array(FlowNodeSchema).optional(),\n edges: z.array(FlowEdgeSchema).optional(),\n});\n\nexport type FlowManifest = z.infer<typeof FlowManifestSchema>;\n\n// ---------------------------------------------------------------------------\n// Validation\n// ---------------------------------------------------------------------------\n\nexport function validateFlow(data: unknown): ManifestValidationResult<FlowManifest> {\n const result = FlowManifestSchema.safeParse(data);\n if (result.success) {\n return { ok: true, data: result.data };\n }\n return {\n ok: false,\n errors: result.error.issues.map((issue) => ({\n path: issue.path.join(\".\"),\n message: issue.message,\n })),\n };\n}\n","/**\n * Flow asset kind provider.\n *\n * Exported from @skaile/workspaces/factory-assets/connectors/flow/engine for explicit registration\n * by the CLI at bootstrap. Discovery does NOT auto-include this provider\n * (discovery must stay a leaf — no flow-engine imports).\n *\n * Implements IAssetKindProvider with flow-specific:\n * - Discovery patterns: *.flow.yaml, *.flow.json\n * - Manifest validation via FlowManifestSchema\n * - Requires extraction: nodes[].run.assets plus legacy skill/sub-flow references\n * - File filter: just the manifest file (flows are single-file)\n */\n\nimport * as path from \"node:path\";\nimport type {\n AssetKindFileFilter,\n AssetKindRequiresEdge,\n IAssetKindProvider,\n} from \"@skaile/workspaces/plugins\";\nimport { validateFlow } from \"./flow-manifest.js\";\n\n// ---------------------------------------------------------------------------\n// Provider\n// ---------------------------------------------------------------------------\n\nexport const flowKindProvider: IAssetKindProvider = {\n kind: \"flow\",\n displayName: \"Flow\",\n providerVersion: \"1.1.0\",\n discoveryPatterns: [\"**/*.flow.yaml\", \"**/*.flow.json\"],\n\n matchesPath(relativePath: string): boolean {\n return relativePath.endsWith(\".flow.yaml\") || relativePath.endsWith(\".flow.json\");\n },\n\n validateManifest(data: unknown) {\n return validateFlow(data);\n },\n\n defaultFileFilter(manifestPath: string): AssetKindFileFilter {\n return {\n assetRoot: path.dirname(manifestPath),\n files: [path.basename(manifestPath)],\n };\n },\n\n extractRequires(assetRef: string, manifest: Record<string, unknown>): AssetKindRequiresEdge[] {\n const edges: AssetKindRequiresEdge[] = [];\n const seen = new Set<string>();\n const add = (to: string, field: string): void => {\n if (seen.has(to)) return;\n seen.add(to);\n edges.push({ from: assetRef, to, field });\n };\n\n const nodes = manifest.nodes;\n if (Array.isArray(nodes)) {\n for (const node of nodes) {\n if (typeof node !== \"object\" || node === null) continue;\n const n = node as Record<string, unknown>;\n const data = (\n typeof n.data === \"object\" && n.data !== null ? (n.data as Record<string, unknown>) : {}\n ) as Record<string, unknown>;\n const run =\n typeof n.run === \"object\" && n.run !== null ? (n.run as Record<string, unknown>) : {};\n\n if (Array.isArray(run.assets)) {\n for (const asset of run.assets) {\n if (typeof asset === \"string\") add(asset, \"nodes[].run.assets\");\n }\n }\n\n if (run.kind === \"sub-flow\" && typeof run.flow === \"string\") {\n const flowRef = run.flow.startsWith(\"flow:\") ? run.flow : `flow:${run.flow}`;\n add(flowRef, \"nodes[].run.flow\");\n }\n\n const skill = typeof data.skill === \"string\" ? data.skill : n.skill;\n if (typeof skill === \"string\") {\n add(skill, \"nodes[].data.skill\");\n }\n\n const subFlow = typeof data.flow === \"string\" ? data.flow : n.flow;\n if (typeof subFlow === \"string\") {\n add(subFlow.startsWith(\"flow:\") ? subFlow : `flow:${subFlow}`, \"nodes[].data.flow\");\n }\n }\n }\n\n return edges;\n },\n};\n","import fs from \"node:fs\";\nimport path from \"node:path\";\nimport { assetSearchDirs } from \"@skaile/workspaces/core\";\nimport { parse as parseYaml } from \"yaml\";\nimport { parseFlowDefinition } from \"../contract/normalize.js\";\nimport type { FlowDefinition } from \"./types.js\";\n\n/**\n * Load a single {@link FlowDefinition} from a YAML or JSON file on disk.\n *\n * Format detection is based on file extension:\n * - `.yaml` / `.yml` — parsed with the `yaml` library.\n * - Everything else — parsed as JSON.\n *\n * @param filePath - Absolute path to the flow file.\n * @returns The parsed {@link FlowDefinition}.\n * @throws {Error} If the file does not exist, cannot be read, or fails to parse.\n * @docLink packages/flow-engine/concepts#flow-loading\n */\nexport function loadFlow(filePath: string): FlowDefinition {\n const raw = fs.readFileSync(filePath, \"utf-8\");\n const ext = path.extname(filePath).toLowerCase();\n const authored = ext === \".yaml\" || ext === \".yml\" ? parseYaml(raw) : JSON.parse(raw);\n const parsed = parseFlowDefinition(authored);\n if (!parsed.ok) {\n const details = parsed.errors\n .map((issue) => ` ${issue.path || \"<root>\"}: ${issue.message}`)\n .join(\"\\n\");\n throw new Error(`Invalid flow definition:\\n${details}`);\n }\n return parsed.data;\n}\n\n/**\n * Load all `*.flow.yaml` and legacy `*.flow.json` / `*.json` flow files from a directory.\n *\n * Files that fail to parse are skipped with a warning written to `stderr` — they do not\n * cause the function to throw. Files whose name starts with `_` are skipped entirely\n * (treated as drafts or disabled flows). Files missing the required `id`, `nodes`, or\n * `edges` fields are also discarded silently.\n *\n * @param dirPath - Absolute path to the directory to scan.\n * @returns Array of successfully parsed {@link FlowDefinition} objects. Empty if the\n * directory does not exist or contains no valid flow files.\n * @docLink packages/flow-engine/concepts#flow-loading\n */\nexport function loadFlowsFromDir(dirPath: string): FlowDefinition[] {\n if (!fs.existsSync(dirPath)) return [];\n\n const files = fs.readdirSync(dirPath).filter((f) => {\n if (f.startsWith(\"_\")) return false;\n return f.endsWith(\".flow.yaml\") || f.endsWith(\".flow.json\") || f.endsWith(\".json\");\n });\n\n const flows: FlowDefinition[] = [];\n\n for (const file of files) {\n try {\n const def = loadFlow(path.join(dirPath, file));\n if (def.id && def.nodes && def.edges) {\n flows.push(def);\n }\n } catch (err) {\n process.stderr.write(`[agent-flow-engine] skipping ${file}: ${(err as Error).message}\\n`);\n }\n }\n\n return flows;\n}\n\n/**\n * Discover and load all flow definitions from every domain under an `ai-assets` root.\n *\n * Walks the top-level subdirectories of `aiResourcesRoot`, looks for a `flows/`\n * subdirectory inside each domain, and delegates to {@link loadFlowsFromDir} for\n * each one found. Files prefixed with `_` are skipped (draft/disabled).\n *\n * @param aiResourcesRoot - Absolute path to the `ai-assets/` directory (or equivalent\n * resource root). Typically the `ai-assets/` folder at the monorepo root.\n * @returns Flat array of all successfully parsed {@link FlowDefinition} objects across\n * all domains. Empty if the root directory does not exist.\n * @docLink packages/flow-engine/concepts#flow-loading\n */\nexport function loadAllFlows(aiResourcesRoot: string): FlowDefinition[] {\n if (!fs.existsSync(aiResourcesRoot)) return [];\n\n // `assetSearchDirs` covers both the flat (`<root>/flows/`) and domain-nested\n // (`<root>/<domain>/flows/`) layouts via the one shared layout primitive.\n // De-dupe by id (first dir wins) so a root that happens to define a flow in\n // both layouts surfaces it once.\n const byId = new Map<string, FlowDefinition>();\n for (const { dir } of assetSearchDirs(aiResourcesRoot, \"flows\")) {\n for (const flow of loadFlowsFromDir(dir)) {\n if (!byId.has(flow.id)) byId.set(flow.id, flow);\n }\n }\n return [...byId.values()];\n}\n"]}
@@ -2,6 +2,18 @@
2
2
  function isAgentNode(node) {
3
3
  return node.type === "skill" || node.run?.kind === "agent";
4
4
  }
5
+ function isFunctionNode(node) {
6
+ return node.run?.kind === "function";
7
+ }
8
+ function isGateNode(node) {
9
+ return node.run?.kind === "gate";
10
+ }
11
+ function isSubFlowNode(node) {
12
+ return node.run?.kind === "sub-flow";
13
+ }
14
+ function isActiveRuntimeNode(node) {
15
+ return isAgentNode(node) || isFunctionNode(node) || isGateNode(node) || isSubFlowNode(node);
16
+ }
5
17
  function nodeIsOptional(node) {
6
18
  return node.control?.optional ?? node.data?.optional ?? false;
7
19
  }
@@ -33,6 +45,6 @@ function flowDefaults(flow) {
33
45
  return flow.defaults ?? flow.globals ?? {};
34
46
  }
35
47
 
36
- export { flowDefaults, isAgentNode, nodeAssets, nodeBindings, nodeInstruction, nodeIsOptional, nodeLabel, nodeRequiresApproval, nodeSkillId };
37
- //# sourceMappingURL=chunk-DZM33LQO.js.map
38
- //# sourceMappingURL=chunk-DZM33LQO.js.map
48
+ export { flowDefaults, isActiveRuntimeNode, isAgentNode, isFunctionNode, isGateNode, isSubFlowNode, nodeAssets, nodeBindings, nodeInstruction, nodeIsOptional, nodeLabel, nodeRequiresApproval, nodeSkillId };
49
+ //# sourceMappingURL=chunk-4QROZZ5Z.js.map
50
+ //# sourceMappingURL=chunk-4QROZZ5Z.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../factory-assets/connectors/flow/engine/node-shape.ts"],"names":[],"mappings":";AAGO,SAAS,YAAY,IAAA,EAAyB;AACnD,EAAA,OAAO,IAAA,CAAK,IAAA,KAAS,OAAA,IAAW,IAAA,CAAK,KAAK,IAAA,KAAS,OAAA;AACrD;AAGO,SAAS,eACd,IAAA,EACyF;AACzF,EAAA,OAAO,IAAA,CAAK,KAAK,IAAA,KAAS,UAAA;AAC5B;AAGO,SAAS,WACd,IAAA,EACqF;AACrF,EAAA,OAAO,IAAA,CAAK,KAAK,IAAA,KAAS,MAAA;AAC5B;AAGO,SAAS,cACd,IAAA,EACyF;AACzF,EAAA,OAAO,IAAA,CAAK,KAAK,IAAA,KAAS,UAAA;AAC5B;AAGO,SAAS,oBAAoB,IAAA,EAAyB;AAC3D,EAAA,OAAO,WAAA,CAAY,IAAI,CAAA,IAAK,cAAA,CAAe,IAAI,KAAK,UAAA,CAAW,IAAI,CAAA,IAAK,aAAA,CAAc,IAAI,CAAA;AAC5F;AAMO,SAAS,eAAe,IAAA,EAAyB;AACtD,EAAA,OAAO,IAAA,CAAK,OAAA,EAAS,QAAA,IAAY,IAAA,CAAK,MAAM,QAAA,IAAY,KAAA;AAC1D;AAGO,SAAS,qBAAqB,IAAA,EAAyB;AAC5D,EAAA,OAAO,KAAK,IAAA,EAAM,QAAA,KAAa,eAAe,IAAA,CAAK,IAAA,EAAM,UAAU,SAAA,KAAc,IAAA;AACnF;AAGO,SAAS,YAAY,IAAA,EAAwB;AAClD,EAAA,IAAI,KAAK,IAAA,KAAS,OAAA,SAAgB,IAAA,CAAK,IAAA,EAAM,SAAS,IAAA,CAAK,EAAA;AAC3D,EAAA,MAAM,UAAA,GAAa,IAAA,CAAK,GAAA,EAAK,MAAA,EAAQ,IAAA,CAAK,CAAC,KAAA,KAAU,KAAA,CAAM,UAAA,CAAW,QAAQ,CAAC,CAAA;AAC/E,EAAA,OAAO,UAAA,EAAY,MAAM,QAAA,CAAS,MAAM,EAAE,OAAA,CAAQ,MAAA,EAAQ,EAAE,CAAA,IAAK,IAAA,CAAK,EAAA;AACxE;AAGO,SAAS,UAAU,IAAA,EAAwB;AAChD,EAAA,OAAO,KAAK,KAAA,IAAS,IAAA,CAAK,IAAA,EAAM,KAAA,IAAS,YAAY,IAAI,CAAA;AAC3D;AAGO,SAAS,WAAW,IAAA,EAA0B;AACnD,EAAA,IAAI,IAAA,CAAK,GAAA,EAAK,MAAA,EAAQ,OAAO,KAAK,GAAA,CAAI,MAAA;AACtC,EAAA,MAAM,eAAe,KAAA,CAAM,OAAA,CAAQ,IAAA,CAAK,IAAA,EAAM,MAAM,CAAA,GAChD,IAAA,CAAK,IAAA,CAAK,MAAA,CAAO,OAAO,CAAC,KAAA,KAA2B,OAAO,KAAA,KAAU,QAAQ,IAC7E,EAAC;AACL,EAAA,MAAM,KAAA,GAAQ,IAAA,CAAK,IAAA,KAAS,OAAA,IAAW,IAAA,CAAK,IAAA,EAAM,KAAA,GAAQ,CAAA,MAAA,EAAS,IAAA,CAAK,IAAA,CAAK,KAAK,CAAA,CAAA,GAAK,MAAA;AACvF,EAAA,OAAO,KAAA,GAAQ,CAAC,KAAA,EAAO,GAAG,YAAY,CAAA,GAAI,YAAA;AAC5C;AAGO,SAAS,aAAa,IAAA,EAAyC;AACpE,EAAA,IAAI,IAAA,CAAK,QAAA,EAAU,KAAA,EAAO,OAAO,KAAK,QAAA,CAAS,KAAA;AAC/C,EAAA,OAAO,IAAA,CAAK,IAAA,EAAM,UAAA,IAAc,EAAC;AACnC;AAGO,SAAS,gBAAgB,IAAA,EAAoC;AAClE,EAAA,OAAO,KAAK,GAAA,EAAK,IAAA,KAAS,OAAA,GAAU,IAAA,CAAK,IAAI,WAAA,GAAc,MAAA;AAC7D;AAGO,SAAS,aAAa,IAAA,EAA+C;AAC1E,EAAA,OAAO,IAAA,CAAK,QAAA,IAAY,IAAA,CAAK,OAAA,IAAW,EAAC;AAC3C","file":"chunk-4QROZZ5Z.js","sourcesContent":["import type { FlowDefinition, FlowNode } from \"./types.js\";\n\n/** Returns whether a node is executable by the currently active agent-turn runtime. */\nexport function isAgentNode(node: FlowNode): boolean {\n return node.type === \"skill\" || node.run?.kind === \"agent\";\n}\n\n/** Returns whether a node executes deterministically through NodeExecutor. */\nexport function isFunctionNode(\n node: FlowNode,\n): node is FlowNode & { run: Extract<NonNullable<FlowNode[\"run\"]>, { kind: \"function\" }> } {\n return node.run?.kind === \"function\";\n}\n\n/** Returns whether a node is a runtime-owned human decision point. */\nexport function isGateNode(\n node: FlowNode,\n): node is FlowNode & { run: Extract<NonNullable<FlowNode[\"run\"]>, { kind: \"gate\" }> } {\n return node.run?.kind === \"gate\";\n}\n\n/** Returns whether a node delegates once to an inline child flow. */\nexport function isSubFlowNode(\n node: FlowNode,\n): node is FlowNode & { run: Extract<NonNullable<FlowNode[\"run\"]>, { kind: \"sub-flow\" }> } {\n return node.run?.kind === \"sub-flow\";\n}\n\n/** Returns whether the current runtime owns the node's execution state. */\nexport function isActiveRuntimeNode(node: FlowNode): boolean {\n return isAgentNode(node) || isFunctionNode(node) || isGateNode(node) || isSubFlowNode(node);\n}\n\n/** @deprecated Use {@link isActiveRuntimeNode}; gates are active but nobody executes them. */\nexport const isExecutableNode = isActiveRuntimeNode;\n\n/** Returns the node's optional policy across strict v2 and legacy definitions. */\nexport function nodeIsOptional(node: FlowNode): boolean {\n return node.control?.optional ?? node.data?.optional ?? false;\n}\n\n/** Returns the node's mandatory approval policy across strict v2 and legacy definitions. */\nexport function nodeRequiresApproval(node: FlowNode): boolean {\n return node.gate?.approval === \"mandatory\" || node.data?.approval?.mandatory === true;\n}\n\n/** Returns the first declared skill requirement without making it the node identity. */\nexport function nodeSkillId(node: FlowNode): string {\n if (node.type === \"skill\") return node.data?.skill ?? node.id;\n const skillAsset = node.run?.assets?.find((asset) => asset.startsWith(\"skill:\"));\n return skillAsset?.slice(\"skill:\".length).replace(/#.*$/, \"\") ?? node.id;\n}\n\n/** Returns the user-facing node label across strict v2 and legacy definitions. */\nexport function nodeLabel(node: FlowNode): string {\n return node.label ?? node.data?.label ?? nodeSkillId(node);\n}\n\n/** Returns strict v2 run assets or the equivalent legacy declarations. */\nexport function nodeAssets(node: FlowNode): string[] {\n if (node.run?.assets) return node.run.assets;\n const legacyAssets = Array.isArray(node.data?.assets)\n ? node.data.assets.filter((asset): asset is string => typeof asset === \"string\")\n : [];\n const skill = node.type === \"skill\" && node.data?.skill ? `skill:${node.data.skill}` : undefined;\n return skill ? [skill, ...legacyAssets] : legacyAssets;\n}\n\n/** Returns the binding values already supplied at the node boundary. */\nexport function nodeBindings(node: FlowNode): Record<string, unknown> {\n if (node.contract?.input) return node.contract.input;\n return node.data?.parameters ?? {};\n}\n\n/** Returns the first-class instruction for a strict v2 agent node. */\nexport function nodeInstruction(node: FlowNode): string | undefined {\n return node.run?.kind === \"agent\" ? node.run.instruction : undefined;\n}\n\n/** Returns run-scoped defaults across strict v2 and legacy definitions. */\nexport function flowDefaults(flow: FlowDefinition): Record<string, unknown> {\n return flow.defaults ?? flow.globals ?? {};\n}\n"]}
@@ -1,4 +1,4 @@
1
- import { resolveLibraryDir } from './chunk-W3Q37HEF.js';
1
+ import { resolveLibraryDir } from './chunk-3HVASHBF.js';
2
2
  import { factoryAssetRoots } from './chunk-UFY2HFLO.js';
3
3
  import fs from 'fs';
4
4
  import os from 'os';
@@ -25,5 +25,5 @@ function aiResourceRoots() {
25
25
  }
26
26
 
27
27
  export { AI_RESOURCES, MONOREPO_ROOT, aiResourceRoots };
28
- //# sourceMappingURL=chunk-G2ILW47R.js.map
29
- //# sourceMappingURL=chunk-G2ILW47R.js.map
28
+ //# sourceMappingURL=chunk-57RFYEVM.js.map
29
+ //# sourceMappingURL=chunk-57RFYEVM.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../cli/src/paths.ts"],"names":[],"mappings":";;;;;;;AAOA,IAAM,WAAW,IAAA,CAAK,OAAA,CAAQ,aAAA,CAAc,MAAA,CAAA,IAAA,CAAY,GAAG,CAAC,CAAA;AAW5D,SAAS,iBAAiB,IAAA,EAA6B;AACrD,EAAA,IAAI,GAAA,GAAM,IAAA;AACV,EAAA,KAAA,IAAS,CAAA,GAAI,CAAA,EAAG,CAAA,GAAI,CAAA,EAAG,CAAA,EAAA,EAAK;AAC1B,IAAA,IAAI,EAAA,CAAG,WAAW,IAAA,CAAK,IAAA,CAAK,KAAK,YAAY,CAAC,GAAG,OAAO,GAAA;AACxD,IAAA,MAAM,MAAA,GAAS,IAAA,CAAK,OAAA,CAAQ,GAAG,CAAA;AAC/B,IAAA,IAAI,WAAW,GAAA,EAAK;AACpB,IAAA,GAAA,GAAM,MAAA;AAAA,EACR;AACA,EAAA,OAAO,IAAA;AACT;AAYO,IAAM,aAAA,GAA+B,iBAAiB,QAAQ;AAc9D,IAAM,YAAA,GACX,iBAAA,EAAkB,CAAE,CAAC,CAAA,IAAK,IAAA,CAAK,IAAA,CAAK,EAAA,CAAG,OAAA,EAAQ,EAAG,SAAA,EAAW,WAAW;AAoBnE,SAAS,eAAA,GAA4B;AAC1C,EAAA,MAAM,KAAA,GAAkB,CAAC,GAAG,iBAAA,EAAmB,CAAA;AAG/C,EAAA,KAAA,CAAM,IAAA,CAAK,mBAAmB,CAAA;AAC9B,EAAA,OAAO,CAAC,GAAG,IAAI,GAAA,CAAI,KAAK,CAAC,CAAA,CAAE,MAAA,CAAO,CAAC,CAAA,KAAM,EAAA,CAAG,UAAA,CAAW,CAAC,CAAC,CAAA;AAC3D","file":"chunk-G2ILW47R.js","sourcesContent":["import fs from \"node:fs\";\nimport os from \"node:os\";\nimport path from \"node:path\";\nimport { fileURLToPath } from \"node:url\";\nimport { factoryAssetRoots } from \"@skaile/workspaces/core\";\nimport { resolveLibraryDir } from \"@skaile/workspaces/library\";\n\nconst __ownDir = path.dirname(fileURLToPath(import.meta.url));\n\n/**\n * Walk up from `from` looking for the monorepo marker (`biome.json`, the\n * repo-root shared tooling config). Returns the matching directory or `null`\n * when none is found within eight levels — the latter is the typical case when\n * `@skaile/workspaces` has been installed via `npm i` without a skaile-dev\n * workspace context. Used only to gate dev-only commands (e.g.\n * `serve --compile-test`); first-party content is located via\n * {@link aiResourceRoots}, not this.\n */\nfunction findMonorepoRoot(from: string): string | null {\n let dir = from;\n for (let i = 0; i < 8; i++) {\n if (fs.existsSync(path.join(dir, \"biome.json\"))) return dir;\n const parent = path.dirname(dir);\n if (parent === dir) break;\n dir = parent;\n }\n return null;\n}\n\n/**\n * Absolute path to the monorepo root, or `null` when the CLI is running\n * outside the skaile-dev workspace (typical for `npm i -g` installs).\n *\n * Consumers that only make sense inside the workspace (e.g.\n * `skaile serve --compile-test`) MUST check for `null` and report a\n * \"monorepo-only feature\" error before proceeding.\n *\n * @docLink cli/dev-guide#paths\n */\nexport const MONOREPO_ROOT: string | null = findMonorepoRoot(__ownDir);\n\n/**\n * Default content root used by path display and the `validate` command.\n *\n * The primary first-party `factory-assets/` root resolved through the shared\n * `factoryAssetRoots()` helper — the `SKAILE_FACTORY_ASSETS_DIR` override when\n * set, else the in-repo source during dev / bundled `dist/factory-assets/` after\n * `npm i`. Falls back to `~/.skaile/libraries/` — the user-library directory\n * managed by `skaile library add` — when the package cannot be located.\n * Consumers `fs.existsSync` first and degrade to \"no skills / flows discovered\".\n *\n * @docLink cli/dev-guide#paths\n */\nexport const AI_RESOURCES: string =\n factoryAssetRoots()[0] ?? path.join(os.homedir(), \".skaile\", \"libraries\");\n\n/**\n * All content roots that skill / flow discovery should walk, in priority order,\n * filtered to those that exist on disk and de-duplicated.\n *\n * - The first-party `factory-assets/` roots from the shared `factoryAssetRoots()`\n * helper — the `SKAILE_FACTORY_ASSETS_DIR` override layer (when set) ahead of\n * the bundled tree (in-repo source in dev, `dist/factory-assets/` after\n * install). No monorepo special-case.\n * - The user-library dir `~/.skaile/libraries/`.\n *\n * Order is significant: `findSkills` / flow discovery dedupe first-root-wins, so\n * the env override shadows the bundled tree on a name clash.\n *\n * This is the discovery surface used by `findSkills`, flow discovery, and the\n * completion resolvers.\n *\n * @docLink cli/dev-guide#paths\n */\nexport function aiResourceRoots(): string[] {\n const roots: string[] = [...factoryAssetRoots()];\n // resolveLibraryDir honors SKAILE_LIBRARIES_DIR (the authoring side does too),\n // so a custom-dir library is visible to discovery instead of being missed.\n roots.push(resolveLibraryDir());\n return [...new Set(roots)].filter((r) => fs.existsSync(r));\n}\n"]}
1
+ {"version":3,"sources":["../cli/src/paths.ts"],"names":[],"mappings":";;;;;;;AAOA,IAAM,WAAW,IAAA,CAAK,OAAA,CAAQ,aAAA,CAAc,MAAA,CAAA,IAAA,CAAY,GAAG,CAAC,CAAA;AAW5D,SAAS,iBAAiB,IAAA,EAA6B;AACrD,EAAA,IAAI,GAAA,GAAM,IAAA;AACV,EAAA,KAAA,IAAS,CAAA,GAAI,CAAA,EAAG,CAAA,GAAI,CAAA,EAAG,CAAA,EAAA,EAAK;AAC1B,IAAA,IAAI,EAAA,CAAG,WAAW,IAAA,CAAK,IAAA,CAAK,KAAK,YAAY,CAAC,GAAG,OAAO,GAAA;AACxD,IAAA,MAAM,MAAA,GAAS,IAAA,CAAK,OAAA,CAAQ,GAAG,CAAA;AAC/B,IAAA,IAAI,WAAW,GAAA,EAAK;AACpB,IAAA,GAAA,GAAM,MAAA;AAAA,EACR;AACA,EAAA,OAAO,IAAA;AACT;AAYO,IAAM,aAAA,GAA+B,iBAAiB,QAAQ;AAc9D,IAAM,YAAA,GACX,iBAAA,EAAkB,CAAE,CAAC,CAAA,IAAK,IAAA,CAAK,IAAA,CAAK,EAAA,CAAG,OAAA,EAAQ,EAAG,SAAA,EAAW,WAAW;AAoBnE,SAAS,eAAA,GAA4B;AAC1C,EAAA,MAAM,KAAA,GAAkB,CAAC,GAAG,iBAAA,EAAmB,CAAA;AAG/C,EAAA,KAAA,CAAM,IAAA,CAAK,mBAAmB,CAAA;AAC9B,EAAA,OAAO,CAAC,GAAG,IAAI,GAAA,CAAI,KAAK,CAAC,CAAA,CAAE,MAAA,CAAO,CAAC,CAAA,KAAM,EAAA,CAAG,UAAA,CAAW,CAAC,CAAC,CAAA;AAC3D","file":"chunk-57RFYEVM.js","sourcesContent":["import fs from \"node:fs\";\nimport os from \"node:os\";\nimport path from \"node:path\";\nimport { fileURLToPath } from \"node:url\";\nimport { factoryAssetRoots } from \"@skaile/workspaces/core\";\nimport { resolveLibraryDir } from \"@skaile/workspaces/library\";\n\nconst __ownDir = path.dirname(fileURLToPath(import.meta.url));\n\n/**\n * Walk up from `from` looking for the monorepo marker (`biome.json`, the\n * repo-root shared tooling config). Returns the matching directory or `null`\n * when none is found within eight levels — the latter is the typical case when\n * `@skaile/workspaces` has been installed via `npm i` without a skaile-dev\n * workspace context. Used only to gate dev-only commands (e.g.\n * `serve --compile-test`); first-party content is located via\n * {@link aiResourceRoots}, not this.\n */\nfunction findMonorepoRoot(from: string): string | null {\n let dir = from;\n for (let i = 0; i < 8; i++) {\n if (fs.existsSync(path.join(dir, \"biome.json\"))) return dir;\n const parent = path.dirname(dir);\n if (parent === dir) break;\n dir = parent;\n }\n return null;\n}\n\n/**\n * Absolute path to the monorepo root, or `null` when the CLI is running\n * outside the skaile-dev workspace (typical for `npm i -g` installs).\n *\n * Consumers that only make sense inside the workspace (e.g.\n * `skaile serve --compile-test`) MUST check for `null` and report a\n * \"monorepo-only feature\" error before proceeding.\n *\n * @docLink cli/dev-guide#paths\n */\nexport const MONOREPO_ROOT: string | null = findMonorepoRoot(__ownDir);\n\n/**\n * Default content root used by path display and the `validate` command.\n *\n * The primary first-party `factory-assets/` root resolved through the shared\n * `factoryAssetRoots()` helper — the `SKAILE_FACTORY_ASSETS_DIR` override when\n * set, else the in-repo source during dev / bundled `dist/factory-assets/` after\n * `npm i`. Falls back to `~/.skaile/libraries/` — the user-library directory\n * managed by `skaile library add` — when the package cannot be located.\n * Consumers `fs.existsSync` first and degrade to \"no skills / flows discovered\".\n *\n * @docLink cli/dev-guide#paths\n */\nexport const AI_RESOURCES: string =\n factoryAssetRoots()[0] ?? path.join(os.homedir(), \".skaile\", \"libraries\");\n\n/**\n * All content roots that skill / flow discovery should walk, in priority order,\n * filtered to those that exist on disk and de-duplicated.\n *\n * - The first-party `factory-assets/` roots from the shared `factoryAssetRoots()`\n * helper — the `SKAILE_FACTORY_ASSETS_DIR` override layer (when set) ahead of\n * the bundled tree (in-repo source in dev, `dist/factory-assets/` after\n * install). No monorepo special-case.\n * - The user-library dir `~/.skaile/libraries/`.\n *\n * Order is significant: `findSkills` / flow discovery dedupe first-root-wins, so\n * the env override shadows the bundled tree on a name clash.\n *\n * This is the discovery surface used by `findSkills`, flow discovery, and the\n * completion resolvers.\n *\n * @docLink cli/dev-guide#paths\n */\nexport function aiResourceRoots(): string[] {\n const roots: string[] = [...factoryAssetRoots()];\n // resolveLibraryDir honors SKAILE_LIBRARIES_DIR (the authoring side does too),\n // so a custom-dir library is visible to discovery instead of being missed.\n roots.push(resolveLibraryDir());\n return [...new Set(roots)].filter((r) => fs.existsSync(r));\n}\n"]}
@@ -303,5 +303,5 @@ function resolveProjectDir(additionalEnvVars) {
303
303
  }
304
304
 
305
305
  export { PluginStore, WorkspacePlugin, buildClaudePluginFiles, resolveProjectDir };
306
- //# sourceMappingURL=chunk-BLWNI5KW.js.map
307
- //# sourceMappingURL=chunk-BLWNI5KW.js.map
306
+ //# sourceMappingURL=chunk-AKVAZ5CB.js.map
307
+ //# sourceMappingURL=chunk-AKVAZ5CB.js.map