@w6w/embed 0.2.1 → 0.2.19

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (185) hide show
  1. package/README.md +22 -5
  2. package/dist/ConfirmModal-Pv2-A_3U.js +186 -0
  3. package/dist/ConfirmModal-Pv2-A_3U.js.map +1 -0
  4. package/dist/{CreateFunctionModal-DRsFx-FB.js → CreateFunctionModal-DScxp_LN.js} +25 -25
  5. package/dist/{CreateFunctionModal-DRsFx-FB.js.map → CreateFunctionModal-DScxp_LN.js.map} +1 -1
  6. package/dist/{DocumentFormModal-BExK1V-B.js → DocumentFormModal-Br4s8wmi.js} +5 -5
  7. package/dist/{DocumentFormModal-BExK1V-B.js.map → DocumentFormModal-Br4s8wmi.js.map} +1 -1
  8. package/dist/ImportSpecModal-Cpzp8ndt.js +251 -0
  9. package/dist/ImportSpecModal-Cpzp8ndt.js.map +1 -0
  10. package/dist/ModelRoutesManager-1Ac5wcas.js +345 -0
  11. package/dist/ModelRoutesManager-1Ac5wcas.js.map +1 -0
  12. package/dist/WorkflowEditor-CmhXHRxi.js +1109 -0
  13. package/dist/WorkflowEditor-CmhXHRxi.js.map +1 -0
  14. package/dist/apps-ItBvnWX3.js +92 -0
  15. package/dist/apps-ItBvnWX3.js.map +1 -0
  16. package/dist/{callables-3mFrMVG_.js → callables-tOlflvbl.js} +11 -11
  17. package/dist/{callables-3mFrMVG_.js.map → callables-tOlflvbl.js.map} +1 -1
  18. package/dist/chrome/ConfirmModal.d.ts +4 -1
  19. package/dist/chrome/DangerZone.d.ts +4 -3
  20. package/dist/chrome/ExecutionProfileHeader.d.ts +3 -3
  21. package/dist/chrome/JsonToggle.d.ts +29 -20
  22. package/dist/chrome/Modal.d.ts +3 -1
  23. package/dist/chrome/RightRail.d.ts +6 -1
  24. package/dist/chrome/VersionHistoryModal.d.ts +2 -0
  25. package/dist/chrome/index.d.ts +1 -0
  26. package/dist/chrome/workspace.d.ts +36 -1
  27. package/dist/coerce-input-DFJ4n_wc.js +150 -0
  28. package/dist/coerce-input-DFJ4n_wc.js.map +1 -0
  29. package/dist/connections-CzsCyIxY.js +119 -0
  30. package/dist/connections-CzsCyIxY.js.map +1 -0
  31. package/dist/credentials-Cn92LGhJ.js +171 -0
  32. package/dist/credentials-Cn92LGhJ.js.map +1 -0
  33. package/dist/data-stores-UeQvwVCa.js +170 -0
  34. package/dist/data-stores-UeQvwVCa.js.map +1 -0
  35. package/dist/document-sources-DNmBojx6.js +169 -0
  36. package/dist/document-sources-DNmBojx6.js.map +1 -0
  37. package/dist/draft/use-workflow-draft.d.ts +2 -0
  38. package/dist/draft.mjs +2 -2
  39. package/dist/editor/BindingBanner.d.ts +13 -0
  40. package/dist/editor/CallableEditorFrame.d.ts +7 -0
  41. package/dist/editor/EndpointCards.d.ts +4 -1
  42. package/dist/editor/PublishControl.d.ts +19 -0
  43. package/dist/editor/PublishTooltip.d.ts +7 -0
  44. package/dist/editor/SetupIncompleteBanner.d.ts +12 -0
  45. package/dist/editor/StartingStateModal.d.ts +14 -0
  46. package/dist/editor/TargetSelector.d.ts +15 -0
  47. package/dist/editor/TargetSelector.types.d.ts +2 -0
  48. package/dist/editor/WorkflowSettingsModal.d.ts +6 -1
  49. package/dist/editor/WorkflowVariablesEditor.d.ts +6 -0
  50. package/dist/editor/definition.d.ts +6 -0
  51. package/dist/editor/json-apply.d.ts +29 -0
  52. package/dist/editor/step-problems-feed.d.ts +5 -0
  53. package/dist/editor/types.d.ts +2 -2
  54. package/dist/editor-apps-DkkC7wOQ.js +152 -0
  55. package/dist/editor-apps-DkkC7wOQ.js.map +1 -0
  56. package/dist/editor-tools-BR27RGto.js +1683 -0
  57. package/dist/editor-tools-BR27RGto.js.map +1 -0
  58. package/dist/editor.mjs +1 -1
  59. package/dist/editors.mjs +855 -650
  60. package/dist/editors.mjs.map +1 -1
  61. package/dist/{endpoints-B2ynbZo-.js → endpoints-DSRo1Lc5.js} +113 -107
  62. package/dist/endpoints-DSRo1Lc5.js.map +1 -0
  63. package/dist/fields-DvS8XZFc.js +21 -0
  64. package/dist/fields-DvS8XZFc.js.map +1 -0
  65. package/dist/forms/ModelBudgetsManager.d.ts +9 -0
  66. package/dist/forms/ModelRoutesManager.d.ts +14 -0
  67. package/dist/forms.d.ts +4 -0
  68. package/dist/forms.mjs +611 -212
  69. package/dist/forms.mjs.map +1 -1
  70. package/dist/{rail-settings-XYGToh00.js → import-bindings-EUtxZ9Ti.js} +90 -24
  71. package/dist/import-bindings-EUtxZ9Ti.js.map +1 -0
  72. package/dist/index.mjs +154 -117
  73. package/dist/index.mjs.map +1 -1
  74. package/dist/lib/binding-problems.d.ts +42 -0
  75. package/dist/lib/code-rail.d.ts +4 -2
  76. package/dist/lib/history-query.d.ts +45 -0
  77. package/dist/lib/import-bindings.d.ts +89 -0
  78. package/dist/lib/index.d.ts +4 -0
  79. package/dist/lib/invoke-error.d.ts +1 -0
  80. package/dist/lib/rail-settings.d.ts +1 -1
  81. package/dist/lib/sdk-snippets.d.ts +1 -1
  82. package/dist/lib/setup-incomplete.d.ts +22 -0
  83. package/dist/lib/starting-data.d.ts +31 -0
  84. package/dist/lib/state-panel.d.ts +29 -0
  85. package/dist/lib/target-fields.d.ts +11 -15
  86. package/dist/lib/trigger-preview.d.ts +1 -0
  87. package/dist/lib/workflow-live-run.d.ts +93 -8
  88. package/dist/lib/workflow-nodes.d.ts +5 -0
  89. package/dist/lib/workflow-validity.d.ts +65 -16
  90. package/dist/lib/workflow-variables.d.ts +1 -1
  91. package/dist/lib/workflow-version.d.ts +2 -0
  92. package/dist/lib.mjs +86 -69
  93. package/dist/lists/ConnectionDependents.d.ts +31 -0
  94. package/dist/lists/ConnectionDetail.d.ts +4 -1
  95. package/dist/lists/ConnectionList.d.ts +4 -1
  96. package/dist/lists/CredentialDetail.d.ts +15 -0
  97. package/dist/lists/CredentialList.d.ts +14 -0
  98. package/dist/lists/DataStoreList.d.ts +17 -0
  99. package/dist/lists/DataStoreView.d.ts +19 -0
  100. package/dist/lists/Logs.d.ts +19 -0
  101. package/dist/lists/ModelCatalog.d.ts +12 -0
  102. package/dist/lists/ModelUsage.d.ts +12 -0
  103. package/dist/lists.d.ts +14 -0
  104. package/dist/lists.mjs +1766 -609
  105. package/dist/lists.mjs.map +1 -1
  106. package/dist/models-bAayQPJ_.js +270 -0
  107. package/dist/models-bAayQPJ_.js.map +1 -0
  108. package/dist/{project-context-BiCjv_E3.js → project-context-Tvp-La7A.js} +3 -3
  109. package/dist/{project-context-BiCjv_E3.js.map → project-context-Tvp-La7A.js.map} +1 -1
  110. package/dist/rail/ConnectionsTool.d.ts +2 -0
  111. package/dist/rail/HistoryTool.d.ts +2 -0
  112. package/dist/rail/StartingStateTool.d.ts +2 -0
  113. package/dist/rail/settings-sections.d.ts +4 -1
  114. package/dist/rail.mjs +4 -4
  115. package/dist/repos/agents-studio-agents.d.ts +52 -0
  116. package/dist/repos/agents-studio-assets.d.ts +68 -0
  117. package/dist/repos/connections.d.ts +30 -12
  118. package/dist/repos/constants.d.ts +12 -0
  119. package/dist/repos/credentials.d.ts +83 -0
  120. package/dist/repos/data-stores.d.ts +84 -0
  121. package/dist/repos/endpoints.d.ts +9 -3
  122. package/dist/repos/fields.d.ts +34 -0
  123. package/dist/repos/functions.d.ts +7 -5
  124. package/dist/repos/history.d.ts +9 -0
  125. package/dist/repos/index.d.ts +7 -0
  126. package/dist/repos/models.d.ts +289 -0
  127. package/dist/repos/spec-export.d.ts +3 -3
  128. package/dist/repos/spec-import.d.ts +30 -1
  129. package/dist/repos/step-tests.d.ts +2 -0
  130. package/dist/repos/webhook-listen.d.ts +35 -0
  131. package/dist/repos/workflows.d.ts +105 -2
  132. package/dist/repos.mjs +655 -176
  133. package/dist/repos.mjs.map +1 -1
  134. package/dist/setup-incomplete-BHs3Lpfy.js +199 -0
  135. package/dist/setup-incomplete-BHs3Lpfy.js.map +1 -0
  136. package/dist/{slug-C4ktDPdy.js → slug-BVdgiP_L.js} +64 -60
  137. package/dist/slug-BVdgiP_L.js.map +1 -0
  138. package/dist/{spec-export-Cf3VQSQS.js → spec-export-DGy5ijps.js} +73 -60
  139. package/dist/spec-export-DGy5ijps.js.map +1 -0
  140. package/dist/spec-import-SWOonsNr.js +116 -0
  141. package/dist/spec-import-SWOonsNr.js.map +1 -0
  142. package/dist/{step-tests-CivICmTq.js → step-tests-B4E4W3ly.js} +8 -7
  143. package/dist/step-tests-B4E4W3ly.js.map +1 -0
  144. package/dist/theme-context-E2ZhlXDX.js +6 -0
  145. package/dist/theme-context-E2ZhlXDX.js.map +1 -0
  146. package/dist/theme-context.d.ts +2 -0
  147. package/dist/{use-callable-draft-zHLpcr-b.js → use-callable-draft-DCauHt5o.js} +23 -23
  148. package/dist/{use-callable-draft-zHLpcr-b.js.map → use-callable-draft-DCauHt5o.js.map} +1 -1
  149. package/dist/use-workflow-draft-l3P5KZzw.js +338 -0
  150. package/dist/use-workflow-draft-l3P5KZzw.js.map +1 -0
  151. package/dist/{workflow-blank-DyL3_RUA.js → workflow-blank-DFpGObrn.js} +6 -6
  152. package/dist/{workflow-blank-DyL3_RUA.js.map → workflow-blank-DFpGObrn.js.map} +1 -1
  153. package/dist/workflows-BZN4Hyz1.js +623 -0
  154. package/dist/workflows-BZN4Hyz1.js.map +1 -0
  155. package/package.json +3 -2
  156. package/src/styles.css +155 -7
  157. package/dist/ConfirmModal-RLbZT5_k.js +0 -181
  158. package/dist/ConfirmModal-RLbZT5_k.js.map +0 -1
  159. package/dist/ImportSpecModal-BDQIf6rg.js +0 -136
  160. package/dist/ImportSpecModal-BDQIf6rg.js.map +0 -1
  161. package/dist/WorkflowEditor-DlbVv6Fs.js +0 -854
  162. package/dist/WorkflowEditor-DlbVv6Fs.js.map +0 -1
  163. package/dist/apps-1FNUwbGv.js +0 -77
  164. package/dist/apps-1FNUwbGv.js.map +0 -1
  165. package/dist/coerce-input-BicYr7nc.js +0 -139
  166. package/dist/coerce-input-BicYr7nc.js.map +0 -1
  167. package/dist/connections-CjjYeRqb.js +0 -78
  168. package/dist/connections-CjjYeRqb.js.map +0 -1
  169. package/dist/document-sources-C0grrtdq.js +0 -86
  170. package/dist/document-sources-C0grrtdq.js.map +0 -1
  171. package/dist/editor-apps-BdenSV1o.js +0 -95
  172. package/dist/editor-apps-BdenSV1o.js.map +0 -1
  173. package/dist/editor-tools-RxmY5iyi.js +0 -1279
  174. package/dist/editor-tools-RxmY5iyi.js.map +0 -1
  175. package/dist/endpoints-B2ynbZo-.js.map +0 -1
  176. package/dist/rail-settings-XYGToh00.js.map +0 -1
  177. package/dist/slug-C4ktDPdy.js.map +0 -1
  178. package/dist/spec-export-Cf3VQSQS.js.map +0 -1
  179. package/dist/spec-import-CjmxyZDR.js +0 -465
  180. package/dist/spec-import-CjmxyZDR.js.map +0 -1
  181. package/dist/step-tests-CivICmTq.js.map +0 -1
  182. package/dist/trigger-preview-VPkrryDl.js +0 -120
  183. package/dist/trigger-preview-VPkrryDl.js.map +0 -1
  184. package/dist/use-workflow-draft-DzAyUeA6.js +0 -316
  185. package/dist/use-workflow-draft-DzAyUeA6.js.map +0 -1
@@ -0,0 +1,89 @@
1
+ /**
2
+ * Pure row logic behind `ImportSpecModal`'s configure step (T2.1.1, IF-1 / D-B8 / D-B9).
3
+ *
4
+ * Turns the server's `POST /spec/preview` dependencies into editable rows and back into the
5
+ * `selections` map the import body carries. The client NEVER ranks: a row's initial selection is
6
+ * exactly the server's `suggested`. Every dependency yields exactly one selection on the way out —
7
+ * `{mode:"unconfigured"}` included, never omitted and never upgraded to a suggestion the user
8
+ * cleared.
9
+ *
10
+ * `node --test` throws `ERR_UNKNOWN_FILE_EXTENSION` on anything reaching the `@w6w/ui` import graph
11
+ * (see `lib/import-paste.ts`), so this module takes no value import at all.
12
+ */
13
+ export type DependencyKind = "connection" | "var" | "secret" | "const" | "store";
14
+ export type Selection = {
15
+ mode: "bind";
16
+ target: string;
17
+ } | {
18
+ mode: "create";
19
+ name: string;
20
+ } | {
21
+ mode: "unconfigured";
22
+ };
23
+ export type SelectionMode = Selection["mode"];
24
+ export interface DependencyOption {
25
+ id: string;
26
+ label: string;
27
+ source: "connection" | "built-in" | "var" | "secret" | "const" | "store";
28
+ authKey?: string;
29
+ compatible?: boolean;
30
+ reason?: string;
31
+ }
32
+ export interface SpecDependency {
33
+ key: string;
34
+ kind: DependencyKind;
35
+ name: string;
36
+ app?: string;
37
+ authHint?: {
38
+ method: "built-in";
39
+ } | {
40
+ method: "authKey";
41
+ authKey: string;
42
+ };
43
+ usages: {
44
+ nodeId: string | null;
45
+ path: string;
46
+ access?: "read" | "write" | "delete";
47
+ }[];
48
+ store?: {
49
+ kind: "kv" | "doc" | "table" | null;
50
+ schema: unknown | null;
51
+ access: {
52
+ read: boolean;
53
+ write: boolean;
54
+ delete: boolean;
55
+ };
56
+ };
57
+ dynamic?: true;
58
+ }
59
+ export interface PreviewDependency extends SpecDependency {
60
+ options: DependencyOption[];
61
+ suggested: Selection;
62
+ canCreate: boolean;
63
+ }
64
+ export interface ImportRow {
65
+ key: string;
66
+ dep: PreviewDependency;
67
+ /** Options offered to the row (the server's, plus any connection created in-modal). */
68
+ options: DependencyOption[];
69
+ selection: Selection;
70
+ /** Remembered name for `create`, so toggling modes does not lose an edit. */
71
+ createName: string;
72
+ }
73
+ /** IF-1 "Allowed modes". */
74
+ export declare function allowedModes(dep: PreviewDependency): SelectionMode[];
75
+ /** One row per dependency; the initial selection is `suggested` verbatim (D-B9). */
76
+ export declare function buildRows(deps: readonly PreviewDependency[]): ImportRow[];
77
+ /** Bind a row to an option. Refused (row unchanged) for an unknown / incompatible option or a disallowed mode. */
78
+ export declare function setBind(rows: readonly ImportRow[], key: string, target: string): ImportRow[];
79
+ /** Switch a store row to `create` / edit its name. Refused unless `create` is allowed. */
80
+ export declare function setCreateName(rows: readonly ImportRow[], key: string, name: string): ImportRow[];
81
+ /** Leave the dependency unconfigured (always allowed). */
82
+ export declare function setUnconfigured(rows: readonly ImportRow[], key: string): ImportRow[];
83
+ /** A connection was just created via "Add connection": offer it and bind the row to it. */
84
+ export declare function withCreatedConnection(rows: readonly ImportRow[], key: string, id: string, label: string): ImportRow[];
85
+ /** Whether a row can be submitted: a `create` needs a non-blank name. */
86
+ export declare function rowReady(row: ImportRow): boolean;
87
+ export declare function rowsReady(rows: readonly ImportRow[]): boolean;
88
+ /** The import body's `selections`: ONE entry per dependency key, `unconfigured` included. */
89
+ export declare function toSelections(rows: readonly ImportRow[]): Record<string, Selection>;
@@ -1,5 +1,6 @@
1
1
  export * from './workflow-validity.ts';
2
2
  export * from './workflow-variables.ts';
3
+ export * from './starting-data.ts';
3
4
  export * from './workflow-settings.ts';
4
5
  export * from './workflow-route.ts';
5
6
  export type { RailCallable } from './code-rail.ts';
@@ -22,3 +23,6 @@ export * from './input-seeding.ts';
22
23
  export * from './input-coverage.ts';
23
24
  export * from './coerce-input.ts';
24
25
  export * from './callable-record.ts';
26
+ export * from './binding-problems.ts';
27
+ export * from './setup-incomplete.ts';
28
+ export * from './import-bindings.ts';
@@ -0,0 +1 @@
1
+ export declare function invokeErrorCopy(e: unknown): string;
@@ -78,7 +78,7 @@ export declare function hasDelete(kind: RailSettingsKind): boolean;
78
78
  * `/endpoints/:id/spec` by a wrong `if`/`else` fallthrough — every one of the four
79
79
  * `RailSettingsKind` arms is named explicitly below.
80
80
  */
81
- export declare function specCollectionForKind(kind: RailSettingsKind): "functions" | "endpoints" | null;
81
+ export declare function specCollectionForKind(kind: RailSettingsKind): "functions" | "endpoints" | "workflows" | null;
82
82
  /** What A8's `evaluateEdit` needs to know about the row already on screen — deliberately
83
83
  * narrower than a whole `FunctionDef`/`EndpointDef`: the two fields a hand-edit must not
84
84
  * be allowed to change out from under the row it opened on. */
@@ -49,7 +49,7 @@ export type SnippetCallable = {
49
49
  kind: "connection";
50
50
  id: string;
51
51
  action: string;
52
- params?: string[];
52
+ params?: readonly SnippetInput[];
53
53
  } | {
54
54
  kind: "var";
55
55
  name: string;
@@ -0,0 +1,22 @@
1
+ /** A name list for one category; `ready:false` (loading/errored) means that category is never flagged. */
2
+ export interface SetupNameList {
3
+ names: string[];
4
+ ready: boolean;
5
+ }
6
+ export interface SetupIncompleteInput {
7
+ /** The parsed saved workflow (nodes, connections, variables, …). */
8
+ workflow: unknown;
9
+ lists: {
10
+ vars: SetupNameList;
11
+ secrets: SetupNameList;
12
+ constants: SetupNameList;
13
+ stores: SetupNameList;
14
+ };
15
+ }
16
+ /** Node id -> human labels of what is missing at that node (e.g. `connection "gmail"`, `var.x`). */
17
+ export type SetupIncompleteResult = Record<string, string[]>;
18
+ /**
19
+ * Derive what is unconfigured in a saved workflow (plan IF-1 shape), keyed by node id.
20
+ * A category whose list is not `ready` is never flagged.
21
+ */
22
+ export declare function findSetupIncomplete(input: SetupIncompleteInput): SetupIncompleteResult;
@@ -0,0 +1,31 @@
1
+ import { WorkflowVariableRow } from './workflow-variables.ts';
2
+ /** Why a Starting data draft cannot be saved. */
3
+ export type StartingDataProblem = "invalid_json" | "not_object" | "too_large";
4
+ /** The outcome of reading a Starting data draft for save. `value: undefined` drops the key. */
5
+ export type StartingDataForSave = {
6
+ ok: true;
7
+ value: Record<string, unknown> | undefined;
8
+ } | {
9
+ ok: false;
10
+ reason: StartingDataProblem;
11
+ };
12
+ /**
13
+ * Read a definition's `initialState` field. Takes `unknown` because the source is
14
+ * `JSON.parse`d and the `</>` editor lets an author type anything: only a plain
15
+ * object counts; anything else reads as "no starting data".
16
+ */
17
+ export declare function readStartingData(raw: unknown): Record<string, unknown> | undefined;
18
+ /**
19
+ * Turn the tab's JSON text into the value `patchMeta({ initialState })` saves.
20
+ * Blank text and `{}` both mean "no starting data" (`value: undefined`, so the
21
+ * key is dropped from the definition). Anything but a plain object is refused,
22
+ * as is an object whose serialised form exceeds `STATE_LIMITS.initialChars`
23
+ * (measured exactly as the server measures it: `JSON.stringify(v).length`).
24
+ */
25
+ export declare function startingDataForSave(text: string): StartingDataForSave;
26
+ /**
27
+ * The declared variable keys that are also top-level keys of the starting data —
28
+ * on those keys the variable's value wins (R2'). Variable declaration order, no
29
+ * duplicates, no empty keys.
30
+ */
31
+ export declare function startingDataCollisions(initial: Record<string, unknown> | undefined, variables: readonly WorkflowVariableRow[]): string[];
@@ -0,0 +1,29 @@
1
+ import { StateLogRow } from '@w6w/expr';
2
+ /**
3
+ * The run's state tree: the snapshot `GET /runs/:id` serves when one was persisted, else the
4
+ * state-write log folded by `@w6w/expr`'s `foldStateLog` (the same fold the run log's "state
5
+ * after this step" uses). `undefined` when neither has anything.
6
+ */
7
+ export declare function runStateTree(snapshot: unknown, writes: readonly StateLogRow[] | undefined): Record<string, unknown> | undefined;
8
+ /**
9
+ * Who last wrote each top-level state key, from the run's state-write log: the node id of the
10
+ * last write under that key, or `null` for a key that came from the starting state (the seed row,
11
+ * `seq 0` with no node). A warning row wrote nothing; a delete (`new` absent or `null`) forgets the
12
+ * key; a whole-tree write (`path []`) hands every key it sets to its node. Read in `seq` order
13
+ * whatever order the rows arrive in.
14
+ */
15
+ export declare function stateKeyWriters(writes: readonly StateLogRow[]): Map<string, string | null>;
16
+ /** One line of the starting state preview: a leaf's dotted path and how it reads. */
17
+ export interface StartingStateRow {
18
+ path: string;
19
+ /** `reference`: a string carrying a `{{ }}` reference, resolved when a run starts. */
20
+ kind: "literal" | "reference";
21
+ /** The reference text verbatim, or the literal as JSON. */
22
+ text: string;
23
+ }
24
+ /**
25
+ * The starting state flattened to one row per leaf, in key order: nested objects descend
26
+ * (`a.b`), arrays and empty objects stay one literal row. A string with a `{{ }}` reference is a
27
+ * `reference` row shown as typed, never as a value: it only resolves when a run starts.
28
+ */
29
+ export declare function startingStateRows(initial: Record<string, unknown> | undefined): StartingStateRow[];
@@ -1,18 +1,4 @@
1
- /**
2
- * Pure helpers shared by `TargetSelector`'s three arms (rfcs/endpoint.md
3
- * :339-347 — `EndpointTarget = CallableRef | ActionTarget`) and by
4
- * `EndpointsPage`'s save gate.
5
- *
6
- * Pure and testable by design, mirroring `workflow-validity.ts`'s shape:
7
- * `@w6w/ui`'s `package.json` `exports["."]` resolves to raw `./src/index.ts`,
8
- * which re-exports `.tsx` files, so `node --test` throws
9
- * `ERR_UNKNOWN_FILE_EXTENSION` the moment anything here imports `@w6w/ui` or
10
- * `@w6w/ui/flow` — even type-only. So this module declares its own local
11
- * structural (`*Like`) types instead of importing the real ones from
12
- * `../api/types.ts`, and `isTriggerApp`/`asFieldDefs` (the workflow arm's only
13
- * dependency on `@w6w/ui/flow`) are **caller-injected** — `TargetSelector.tsx`
14
- * (unaffected by the JSX constraint) imports the real ones and passes them in.
15
- */
1
+ import { ParamWhen } from '@w6w/expr';
16
2
  /** The four arms `EndpointTarget` can take; a Function's `impl` takes the
17
3
  * first three (D-8) — `"endpoint"` is alias-only, never legal for `Fn.impl`. */
18
4
  export type TargetKind = "action" | "function" | "workflow" | "endpoint";
@@ -79,6 +65,7 @@ export interface ParamLike {
79
65
  required?: boolean;
80
66
  default?: unknown;
81
67
  showIf?: ShowIfPredicate;
68
+ when?: ParamWhen[];
82
69
  }
83
70
  /** Visibility predicate — mirroring ActionParam.showIf from @w6w/ui. */
84
71
  export interface ShowIfPredicate {
@@ -104,6 +91,7 @@ export interface WorkflowStepLike {
104
91
  }
105
92
  /** A workflow definition, just enough of it for the trigger-field union. */
106
93
  export interface WorkflowLike {
94
+ nodes?: unknown;
107
95
  steps?: unknown;
108
96
  }
109
97
  /** Everything `fieldsFromWorkflow` needs from `@w6w/ui/flow` but cannot import itself. */
@@ -121,6 +109,7 @@ export interface TargetField {
121
109
  required?: boolean;
122
110
  default?: unknown;
123
111
  showIf?: ShowIfPredicate;
112
+ when?: ParamWhen[];
124
113
  }
125
114
  /** One row of an input-contract list (`FunctionInput`/`EndpointInput`'s common shape). */
126
115
  export interface InputRowLike {
@@ -153,6 +142,13 @@ export declare function implToTarget(impl: FunctionImplLike | undefined): Action
153
142
  * `{}`, not absent, on a CallableRef impl too.
154
143
  */
155
144
  export declare function targetToImpl(target: ActionTargetLike | CallableTargetLike): FunctionImplLike;
145
+ /**
146
+ * The `impl` a re-pick produces. `outputMap` adapts ONE binding's vendor response, so it survives
147
+ * only while the binding identity is unchanged: the same `uses.app` + `uses.action` (action arm),
148
+ * or the same callable kind + id (ref arm). Connection and `with` edits keep it; a different
149
+ * action or callee drops it (rfcs/function.md: switching provider replaces `impl` wholesale).
150
+ */
151
+ export declare function implAfterRebind(prev: FunctionImplLike | undefined, target: ActionTargetLike | CallableTargetLike): FunctionImplLike;
156
152
  /** Project a list of action/function params into the normalized `TargetField[]` (A5). */
157
153
  export declare function paramsToFields(params: ParamLike[]): TargetField[];
158
154
  /**
@@ -44,6 +44,7 @@ export interface WorkflowStepLike {
44
44
  }
45
45
  /** A workflow definition, just enough of it for this preview. */
46
46
  export interface WorkflowLike {
47
+ nodes?: WorkflowStepLike[];
47
48
  steps?: WorkflowStepLike[];
48
49
  }
49
50
  /**
@@ -1,3 +1,4 @@
1
+ import { StateLogRow } from '@w6w/expr';
1
2
  import { RunStatus } from '@w6w/sdk';
2
3
  export type { RunStatus };
3
4
  /**
@@ -23,16 +24,25 @@ export type StepMetaLike = {
23
24
  * `ExecutionLogPanel` row. */
24
25
  export interface StepExecutionLike {
25
26
  status: StepStatus;
27
+ /** Why a `skipped` step did not run (`NodeExecution.skipReason`); read as `unknown` (opaque
28
+ * wire) and carried only when it is one of the four known reasons. */
29
+ skipReason?: unknown;
26
30
  startedAt?: string;
27
31
  finishedAt?: string;
28
32
  input?: unknown;
29
33
  output?: unknown;
34
+ logs?: string[];
30
35
  /** `StepExecution.error` — a `StepError` on `failed` per rfcs/workflow.md
31
36
  * §StepExecution, but read as `unknown` because `RunState.steps` is opaque
32
37
  * on the wire; {@link toLogError} normalises whatever actually arrives. */
33
38
  error?: unknown;
34
39
  /** Recorded metadata; absent (or null) for steps that recorded none. */
35
40
  meta?: StepMetaLike | null;
41
+ /** For each only (I3): per-iteration body records, read as `unknown` (opaque wire). */
42
+ iterations?: unknown;
43
+ iterationsTotal?: unknown;
44
+ iterationsFailed?: unknown;
45
+ iterationsTruncated?: unknown;
36
46
  }
37
47
  /** A step or run error, as the run log panel renders it — field-for-field
38
48
  * `@w6w/ui`'s `ExecutionLogError` (rfcs/workflow.md §StepError's
@@ -56,17 +66,24 @@ export interface RunErrorSourceLike {
56
66
  status?: string;
57
67
  error?: unknown;
58
68
  stepErrors?: ReadonlyArray<{
59
- stepId: string;
69
+ nodeId?: string;
70
+ stepId?: string;
60
71
  error: unknown;
61
72
  }>;
62
73
  }
74
+ /** The per-node execution map of a run record, in either shape — `nodes`
75
+ * preferred, else the legacy `steps`. */
76
+ export declare function runNodeMap(run: {
77
+ nodes?: unknown;
78
+ steps?: unknown;
79
+ } | undefined | null): Record<string, StepExecutionLike> | undefined;
63
80
  /** The slice of a saved step-test fixture (`StepTest`) {@link latestFixtureInput}
64
81
  * reads — `with` is what the trigger's Test tab invokes it with. */
65
82
  export interface StepTestFixtureLike {
66
83
  with?: unknown;
67
84
  }
68
85
  /** The row-level fallback for a `failed` step that carries no `error` at all. */
69
- export declare const STEP_FAILED_NO_REASON = "Step failed without reporting a reason.";
86
+ export declare const STEP_FAILED_NO_REASON = "Node failed without reporting a reason.";
70
87
  /** The run-level fallback for a `failed` run where nothing carries a reason. */
71
88
  export declare const RUN_FAILED_NO_REASON = "Run failed without reporting a reason.";
72
89
  /** One `ExecutionLogPanel` row — field-for-field `@w6w/ui`'s
@@ -76,12 +93,39 @@ export declare const RUN_FAILED_NO_REASON = "Run failed without reporting a reas
76
93
  export interface ExecutionLogStepLike {
77
94
  id: string;
78
95
  status: StepStatus;
96
+ skipReason?: SkipReasonLike;
79
97
  startedAt?: string;
80
98
  finishedAt?: string;
81
99
  input?: unknown;
82
100
  output?: unknown;
101
+ logs?: string[];
83
102
  error?: LogErrorLike;
84
103
  meta?: StepMetaLike;
104
+ /** For each only (I4) — field-for-field `@w6w/ui`'s `ExecutionLogStep`. */
105
+ iterations?: ExecutionLogIterationLike[];
106
+ iterationsTotal?: number;
107
+ iterationsFailed?: number;
108
+ iterationsTruncated?: boolean;
109
+ /** This node's state writes (`GET /runs/:id/state-writes` rows, in `seq` order) —
110
+ * field-for-field `@w6w/ui`'s `ExecutionLogStep.stateWrites` (plan §2.7). Absent → no State block. */
111
+ stateWrites?: StateWriteEntryLike[] | null;
112
+ /** The state tree right after this node's last write (`foldStateLog`). */
113
+ stateAfter?: Record<string, unknown> | null;
114
+ }
115
+ /** One state-write entry on a run-log row — `@w6w/ui`'s `ExecutionLogStep.stateWrites[number]`. */
116
+ export type StateWriteEntryLike = {
117
+ path: string[];
118
+ item?: number;
119
+ old?: unknown;
120
+ new?: unknown;
121
+ warning?: string;
122
+ };
123
+ /** One For each iteration row (I4) — mirrors `@w6w/ui`'s `ExecutionLogIteration`. */
124
+ export interface ExecutionLogIterationLike {
125
+ index: number;
126
+ status: "succeeded" | "failed" | "running";
127
+ failedNodeId?: string;
128
+ steps: ExecutionLogStepLike[];
85
129
  }
86
130
  /** How a cancel-request failure should be handled (A6). */
87
131
  export type CancelErrorOutcome = "reconcile" | "surface";
@@ -103,6 +147,21 @@ export declare function shouldContinuePolling(status: RunStatus | undefined): bo
103
147
  * each other.
104
148
  */
105
149
  export declare function isRunInFlight(status: RunStatus | undefined, pollFailed: boolean): boolean;
150
+ /**
151
+ * When a run turns terminal, how long after (ms) the editor re-reads the workflow's saved step
152
+ * tests. The server books every step that succeeded in an editor run as its passing saved test
153
+ * (`step-passes.ts`) — the record the publish gate reads — but only AFTER the engine has
154
+ * checkpointed the run's terminal state, so the poll can see `succeeded` a few milliseconds before
155
+ * the pass lands. The immediate read covers the usual case; the later one covers that window.
156
+ */
157
+ export declare const STEP_PASS_REFRESH_DELAYS_MS: readonly number[];
158
+ /**
159
+ * Should the editor re-read this workflow's saved step tests now? Only once the run it polls is
160
+ * terminal and belongs to the open workflow — a run's passes are booked as it finishes, and the
161
+ * step-tests cache never refetches on its own (`refetchOnWindowFocus: false`), so without this
162
+ * the publish gate keeps the pre-run list and a step that just passed still blocks Publish.
163
+ */
164
+ export declare function stepPassRefreshDue(status: RunStatus | undefined, runWorkflowId: string | undefined, workflowId: string): boolean;
106
165
  /** A1/A6 — what the Run button should read right now. */
107
166
  export declare function runButtonLabel(status: RunStatus | undefined, pollFailed: boolean): string;
108
167
  /**
@@ -115,12 +174,13 @@ export declare function runButtonLabel(status: RunStatus | undefined, pollFailed
115
174
  export declare function classifyCancelError(code: string): CancelErrorOutcome;
116
175
  /**
117
176
  * G5 — map a `RunState`'s opaque `steps` record onto `ExecutionLogPanel`'s
118
- * row shape, in the record's own key order (the order the server checkpoints
119
- * steps in, so it already reads as execution order). `ExecutionLogPanel`'s
120
- * own contract is "never re-sorted" (`ExecutionLogPanel.tsx`'s header), so
121
- * this function must not reorder either.
177
+ * row shape, preserving its keys and timestamps. Record key order is not
178
+ * execution order; `ExecutionLogPanel` sorts the rows chronologically for
179
+ * both live runs and saved history.
122
180
  */
123
- export declare function mapRunStateToLogSteps(steps: Record<string, StepExecutionLike> | undefined): ExecutionLogStepLike[];
181
+ export declare function mapRunStateToLogSteps(steps: Record<string, StepExecutionLike> | undefined, stateLog?: readonly StateLogRow[]): ExecutionLogStepLike[];
182
+ /** `@w6w/ui`'s `SkipReason`, restated locally (see {@link ExecutionLogStepLike}). */
183
+ export type SkipReasonLike = "not_on_path" | "condition" | "stopped" | "disabled";
124
184
  /**
125
185
  * Normalise whatever a step or run reported as its error into the panel's
126
186
  * {@link LogErrorLike}. `null`/`undefined` mean "no error". A non-empty string
@@ -162,4 +222,29 @@ export declare function latestFixtureInput(tests: ReadonlyArray<StepTestFixtureL
162
222
  * click time on purpose — a cached `stepTestsKey` query can be stale, since
163
223
  * saving a fixture does not invalidate it.
164
224
  */
165
- export declare function resolveHeaderRunInput(triggerStepId: string | undefined, list: (stepId: string) => Promise<ReadonlyArray<StepTestFixtureLike> | undefined>): Promise<Record<string, unknown> | undefined>;
225
+ export declare function resolveHeaderRunInput(triggerStepId: string | undefined, list: (stepId: string) => Promise<ReadonlyArray<StepTestFixtureLike> | undefined>, remembered?: () => Promise<ReadonlyArray<{
226
+ nodeId: string;
227
+ input: unknown;
228
+ }> | undefined>): Promise<Record<string, unknown> | undefined>;
229
+ /** The trigger the header Run starts at, and whether it is the Manual trigger. */
230
+ export interface HeaderRunEntry {
231
+ id: string;
232
+ manual: boolean;
233
+ }
234
+ /**
235
+ * The trigger the header Run starts at, and so whose remembered sample payload it runs with: the
236
+ * FIRST Manual trigger (a run's own default entry), else the first other entry trigger — a
237
+ * webhook, a schedule or an app trigger. Before, only a Manual trigger was looked up, so a
238
+ * webhook-started workflow's header Run sent no payload at all. `undefined` when nothing in
239
+ * `steps` is a trigger. The predicates are injected (`@w6w/ui/flow`), as in `trigger-preview.ts`.
240
+ */
241
+ export declare function headerRunEntry(steps: ReadonlyArray<{
242
+ id: string;
243
+ uses?: {
244
+ app?: string;
245
+ trigger?: unknown;
246
+ };
247
+ }>, isManualTrigger: (app: string) => boolean, isEntryTrigger: (uses: {
248
+ app: string;
249
+ trigger?: true;
250
+ }) => boolean): HeaderRunEntry | undefined;
@@ -0,0 +1,5 @@
1
+ /** The vertex array of a workflow definition, in either shape — `nodes` wins, `steps` is the legacy name. */
2
+ export declare function workflowNodes<T = unknown>(def: {
3
+ nodes?: T[];
4
+ steps?: T[];
5
+ } | null | undefined): T[];
@@ -8,6 +8,22 @@
8
8
  * > and every step is valid. Graph well-formedness (orphaned/unreachable
9
9
  * > nodes, dangling edges) is explicitly OUT of scope for this project.
10
10
  *
11
+ * **Amended 2026-10-29: no trigger NODE is required.** A workflow without one is
12
+ * a manual workflow (`rfcs/workflow.md:114`): it already runs from the editor's
13
+ * Run button and from code, and the server publishes it, so gating Publish on a
14
+ * trigger node only blocked a workflow that works. The workflow is now valid iff
15
+ * it has at least one step and every step is valid.
16
+ *
17
+ * **Amended 2026-11-01: an app trigger node is never test-gated.** A node with
18
+ * `uses.trigger: true` runs when its app reports the event; its Test tab has
19
+ * nothing to run by hand ("Publish the workflow to start listening",
20
+ * `AppTriggerTestNote` in `@w6w/ui`), so it can never hold a saved passing
21
+ * test. Gating it on one made every app-triggered workflow unpublishable.
22
+ *
23
+ * **Amended 2026-11-02: tests never gate publishing.** Successful runs and saved
24
+ * test records can disagree, and users may publish without testing. Only the
25
+ * target and required configuration are checked; test history is advisory.
26
+ *
11
27
  * Pure and testable by design: `WorkflowsPage.tsx` is JSX, which Node 24's
12
28
  * type-stripping cannot parse, so nothing in it can be loaded by `node --test`
13
29
  * (same shape as `src/lib/workflow-save.ts` + its `.test.ts`). This module
@@ -18,11 +34,7 @@
18
34
  * the two functions the pinned predicate reuses
19
35
  * (`requiredParamsFilled`/`isTestRequired`) are **caller-injected** on
20
36
  * `ValidityContext` — `WorkflowsPage.tsx` (unaffected by the JSX constraint)
21
- * imports the real ones from `@w6w/ui` and passes them in. Same for "a
22
- * trigger exists": that reads a graph STEP whose `INTERNAL_NODES` entry has
23
- * `group === "trigger"` (`@w6w/ui/flow`), never the workflow's top-level
24
- * `trigger` field (`rfcs/workflow.md:114`, "Absent means manual-only" — always
25
- * present, so it can't gate anything) — so `hasTrigger` is caller-computed too.
37
+ * imports the real ones from `@w6w/ui` and passes them in.
26
38
  *
27
39
  * `ActionParamLike`/`WorkflowStepLike`/`WorkflowLike` below are this file's
28
40
  * own minimal local types (see `rfcs/workflow.md` §"Step" for the real shape,
@@ -42,13 +54,18 @@ export interface WorkflowStepLike {
42
54
  uses?: {
43
55
  app?: string;
44
56
  action?: string;
57
+ connection?: string | null;
58
+ connectionRef?: string;
45
59
  /** The "or a function id" arm (`rfcs/function.md:49,260`) — `Step.uses.function`. */
46
60
  function?: string;
61
+ /** An app trigger node (`uses.trigger: true`): never gated on a saved test. */
62
+ trigger?: boolean;
47
63
  };
48
64
  with?: Record<string, unknown>;
49
65
  }
50
66
  /** A workflow definition, just enough of it for this gate. */
51
67
  export interface WorkflowLike {
68
+ nodes?: WorkflowStepLike[];
52
69
  steps?: WorkflowStepLike[];
53
70
  /**
54
71
  * Present on real definitions, never read here — graph well-formedness
@@ -63,30 +80,62 @@ export interface WorkflowLike {
63
80
  * each field is caller-built rather than derived in here.
64
81
  */
65
82
  export interface ValidityContext {
66
- /** Does the graph contain a step whose (app, action) is a trigger node? */
67
- hasTrigger: boolean;
68
83
  /** Declared params for a step's target, keyed `` `${app}::${action}` ``. */
69
84
  actionParamsByKey: Record<string, ActionParamLike[]>;
70
- /** The fetched apps list, keyed by app id — only a key present here is test-gated. */
85
+ /** @deprecated Kept for caller compatibility; app test policy does not gate publishing. */
71
86
  appsById: Record<string, unknown>;
72
- /** Whether the given step id has a saved test that last ran successfully. */
87
+ /** @deprecated Kept for caller compatibility; test results do not gate publishing. */
73
88
  testStatus: Record<string, boolean>;
74
89
  /** `@w6w/ui`'s `requiredParamsFilled`, injected (see module docstring). */
75
90
  requiredParamsFilled: (params: ActionParamLike[], values: Record<string, unknown>) => boolean;
76
- /** `@w6w/ui`'s `isTestRequired`, injected (see module docstring). */
91
+ /** @deprecated Kept for caller compatibility; never consulted for publishing. */
77
92
  isTestRequired: (app: unknown) => boolean;
78
93
  }
94
+ /** Which of the pinned predicate's checks a step fails, or `null` when it's valid. */
95
+ type StepFailure = "target missing" | "required params";
79
96
  /** Is this one step valid, per the pinned predicate? */
80
97
  export declare function stepValid(step: WorkflowStepLike, ctx: ValidityContext): boolean;
81
98
  /**
82
- * Is the whole workflow valid? A trigger step must exist and every step must
83
- * be individually valid — nothing about graph well-formedness (this never
84
- * reads `workflow.edges`, even when present).
99
+ * Is the whole workflow valid? It must have at least one step and every step
100
+ * must be individually valid — a trigger node is not required, and nothing
101
+ * about graph well-formedness is checked (this never reads `workflow.edges`).
85
102
  */
86
103
  export declare function workflowValid(workflow: WorkflowLike, ctx: ValidityContext): boolean;
87
104
  /**
88
- * `null` when the workflow is valid; otherwise names the cause — `"no trigger
89
- * step"`, or the id of the first invalid step in declared order plus which
90
- * check it fails.
105
+ * `null` when the workflow is valid; otherwise names the cause — `"no steps"`,
106
+ * or the id of the first invalid step in declared order plus which check it
107
+ * fails.
91
108
  */
92
109
  export declare function invalidReason(workflow: WorkflowLike, ctx: ValidityContext): string | null;
110
+ /** One reason the workflow cannot be published: the node it is about and how to fix it. */
111
+ export interface PublishProblem {
112
+ /** The node's id, or `null` for a workflow-wide problem (`"no steps"`). */
113
+ stepId: string | null;
114
+ check: StepFailure | "no steps";
115
+ /** Names the node and says how to fix it — shown verbatim in the tooltip and the list. */
116
+ message: string;
117
+ }
118
+ /**
119
+ * Every publish problem, in declared node order — the full list `invalidReason`
120
+ * stops at the first of. Empty iff `workflowValid`.
121
+ */
122
+ export declare function publishProblems(workflow: WorkflowLike, ctx: ValidityContext): PublishProblem[];
123
+ /** What the header Publish button's `disabled` reads, each cause kept apart for its reason. */
124
+ export interface PublishGate {
125
+ /** No project to publish into. */
126
+ projectMissing: boolean;
127
+ /** The draft has not loaded, is saving, or is switching context. */
128
+ loading: boolean;
129
+ /** The draft refuses to save (and so to publish): its reason, verbatim. */
130
+ saveBlockedReason: string | null;
131
+ /** The node catalog the validity gate needs has not arrived yet. */
132
+ catalogLoading: boolean;
133
+ problems: readonly PublishProblem[];
134
+ publishing: boolean;
135
+ }
136
+ /**
137
+ * Why Publish is disabled, or `null` when it is enabled. Every disabled state
138
+ * has a reason, so the button never greys out silently.
139
+ */
140
+ export declare function publishDisabledReason(g: PublishGate): string | null;
141
+ export {};
@@ -66,7 +66,7 @@ export declare function variablesForSave(rows: WorkflowVariableRow[]): WorkflowV
66
66
  */
67
67
  export declare function duplicateKeyIndexes(rows: WorkflowVariableRow[]): number[];
68
68
  /**
69
- * The `vars.*` names to offer row `index`'s expression rail: the keys of
69
+ * The `var.*` names to offer row `index`'s expression rail: the keys of
70
70
  * rows **strictly above** it, then `projectVars`, deduped, with blanks
71
71
  * dropped. Declaration order is resolution order (D-5), so a row can only
72
72
  * reference a variable declared earlier than itself — offering a row at or
@@ -0,0 +1,2 @@
1
+ /** Compare JSON definitions independent of object property order. Array order is meaningful. */
2
+ export declare function sameWorkflowDefinition(a: unknown, b: unknown): boolean;