@arbidocs/blocks 0.4.73 → 0.4.75

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 (104) hide show
  1. package/README.md +2 -1
  2. package/dist/agents/index.cjs +255 -254
  3. package/dist/agents/index.js +5 -4
  4. package/dist/agents/workflows/WorkflowRunner.d.ts +20 -4
  5. package/dist/agents/workflows/WorkflowStepBar.d.ts +23 -0
  6. package/dist/agents/workflows/run.d.ts +1 -0
  7. package/dist/agents/workflows/types.d.ts +2 -0
  8. package/dist/chat/index.cjs +124 -124
  9. package/dist/chat/index.js +3 -3
  10. package/dist/{chunk-3SFFTSOI.cjs → chunk-7CVF3DK2.cjs} +5 -5
  11. package/dist/{chunk-3SFFTSOI.cjs.map → chunk-7CVF3DK2.cjs.map} +1 -1
  12. package/dist/{chunk-V3L5DONY.cjs → chunk-B4SRYJLM.cjs} +31 -2
  13. package/dist/chunk-B4SRYJLM.cjs.map +1 -0
  14. package/dist/{chunk-IUR565UW.cjs → chunk-F4LUD3YC.cjs} +49 -48
  15. package/dist/chunk-F4LUD3YC.cjs.map +1 -0
  16. package/dist/{chunk-WOYUXVVQ.cjs → chunk-HITAN7JF.cjs} +4 -4
  17. package/dist/{chunk-WOYUXVVQ.cjs.map → chunk-HITAN7JF.cjs.map} +1 -1
  18. package/dist/{chunk-3VQYJBOI.js → chunk-HOXKR26S.js} +31 -4
  19. package/dist/chunk-HOXKR26S.js.map +1 -0
  20. package/dist/{chunk-KJ3QEKOJ.cjs → chunk-IPGKTUF7.cjs} +7 -33
  21. package/dist/chunk-IPGKTUF7.cjs.map +1 -0
  22. package/dist/{chunk-IA7RTPT3.cjs → chunk-IXALYQT7.cjs} +2 -200
  23. package/dist/chunk-IXALYQT7.cjs.map +1 -0
  24. package/dist/{chunk-QDNXEB3T.js → chunk-LT2UORRG.js} +7 -6
  25. package/dist/chunk-LT2UORRG.js.map +1 -0
  26. package/dist/{chunk-ORA2XE7U.js → chunk-MK6NJQGF.js} +3 -3
  27. package/dist/{chunk-ORA2XE7U.js.map → chunk-MK6NJQGF.js.map} +1 -1
  28. package/dist/chunk-NUNKSZKU.js +203 -0
  29. package/dist/chunk-NUNKSZKU.js.map +1 -0
  30. package/dist/{chunk-6OL5S7MJ.cjs → chunk-NYBIKDWI.cjs} +5 -2
  31. package/dist/chunk-NYBIKDWI.cjs.map +1 -0
  32. package/dist/{chunk-GTNUQBXI.cjs → chunk-P2RBE3FD.cjs} +254 -102
  33. package/dist/chunk-P2RBE3FD.cjs.map +1 -0
  34. package/dist/{chunk-D46ZAPEE.js → chunk-R3PDNQYT.js} +5 -2
  35. package/dist/chunk-R3PDNQYT.js.map +1 -0
  36. package/dist/{chunk-G5DP27DU.js → chunk-UIWLDSTF.js} +3 -29
  37. package/dist/chunk-UIWLDSTF.js.map +1 -0
  38. package/dist/chunk-V4ISCZJ7.cjs +207 -0
  39. package/dist/chunk-V4ISCZJ7.cjs.map +1 -0
  40. package/dist/{chunk-VRPRAU3J.js → chunk-WJEKRSPH.js} +3 -3
  41. package/dist/{chunk-VRPRAU3J.js.map → chunk-WJEKRSPH.js.map} +1 -1
  42. package/dist/{chunk-2P3T23C7.js → chunk-YWYVIQ7T.js} +256 -104
  43. package/dist/chunk-YWYVIQ7T.js.map +1 -0
  44. package/dist/{chunk-BUHKUKKB.js → chunk-ZPLG7QYF.js} +4 -199
  45. package/dist/chunk-ZPLG7QYF.js.map +1 -0
  46. package/dist/connect/index.cjs +96 -37
  47. package/dist/connect/index.cjs.map +1 -1
  48. package/dist/connect/index.js +81 -22
  49. package/dist/connect/index.js.map +1 -1
  50. package/dist/connection/ConnectedWorkflowRunner.d.ts +5 -1
  51. package/dist/connection/useWorkflowThread.d.ts +4 -0
  52. package/dist/databases/DatabaseColumnDialog.d.ts +43 -0
  53. package/dist/databases/DatabaseList.d.ts +28 -0
  54. package/dist/databases/DatabaseTable.d.ts +38 -0
  55. package/dist/databases/DatabaseToolbar.d.ts +38 -0
  56. package/dist/databases/NewDatabaseDialog.d.ts +25 -0
  57. package/dist/databases/SelectCellEditor.d.ts +6 -0
  58. package/dist/databases/SelectChip.d.ts +4 -0
  59. package/dist/databases/column-types.d.ts +58 -0
  60. package/dist/databases/databaseColumns.d.ts +28 -0
  61. package/dist/databases/index.cjs +1081 -0
  62. package/dist/databases/index.cjs.map +1 -0
  63. package/dist/databases/index.d.ts +13 -0
  64. package/dist/databases/index.js +1055 -0
  65. package/dist/databases/index.js.map +1 -0
  66. package/dist/facts/index.cjs +7 -6
  67. package/dist/facts/index.cjs.map +1 -1
  68. package/dist/facts/index.js +3 -2
  69. package/dist/facts/index.js.map +1 -1
  70. package/dist/files/index.cjs +14 -13
  71. package/dist/files/index.cjs.map +1 -1
  72. package/dist/files/index.js +4 -2
  73. package/dist/files/index.js.map +1 -1
  74. package/dist/index.cjs +632 -631
  75. package/dist/index.cjs.map +1 -1
  76. package/dist/index.js +12 -11
  77. package/dist/index.js.map +1 -1
  78. package/dist/settings/index.cjs +1 -1
  79. package/dist/settings/index.js +1 -1
  80. package/dist/shell/ActionCluster.d.ts +3 -1
  81. package/dist/shell/index.cjs +45 -45
  82. package/dist/shell/index.js +1 -1
  83. package/dist/studio/index.cjs +4 -4
  84. package/dist/studio/index.js +3 -3
  85. package/dist/workflow-canvas/StepInspector.d.ts +11 -0
  86. package/dist/workflow-canvas/WorkflowCanvas.d.ts +6 -2
  87. package/dist/workflow-canvas/index.cjs +202 -91
  88. package/dist/workflow-canvas/index.cjs.map +1 -1
  89. package/dist/workflow-canvas/index.js +170 -59
  90. package/dist/workflow-canvas/index.js.map +1 -1
  91. package/dist/workflow-canvas/viewport.d.ts +47 -0
  92. package/package.json +9 -4
  93. package/dist/chunk-2P3T23C7.js.map +0 -1
  94. package/dist/chunk-3VQYJBOI.js.map +0 -1
  95. package/dist/chunk-6OL5S7MJ.cjs.map +0 -1
  96. package/dist/chunk-BUHKUKKB.js.map +0 -1
  97. package/dist/chunk-D46ZAPEE.js.map +0 -1
  98. package/dist/chunk-G5DP27DU.js.map +0 -1
  99. package/dist/chunk-GTNUQBXI.cjs.map +0 -1
  100. package/dist/chunk-IA7RTPT3.cjs.map +0 -1
  101. package/dist/chunk-IUR565UW.cjs.map +0 -1
  102. package/dist/chunk-KJ3QEKOJ.cjs.map +0 -1
  103. package/dist/chunk-QDNXEB3T.js.map +0 -1
  104. package/dist/chunk-V3L5DONY.cjs.map +0 -1
@@ -2,20 +2,21 @@
2
2
  'use strict';
3
3
 
4
4
  var chunkMUMH3Z6K_cjs = require('../chunk-MUMH3Z6K.cjs');
5
- var chunkIUR565UW_cjs = require('../chunk-IUR565UW.cjs');
5
+ var chunkF4LUD3YC_cjs = require('../chunk-F4LUD3YC.cjs');
6
6
  require('../chunk-YJQVLVBJ.cjs');
7
7
  require('../chunk-ZW6FPIFC.cjs');
8
- var chunkGTNUQBXI_cjs = require('../chunk-GTNUQBXI.cjs');
8
+ var chunkP2RBE3FD_cjs = require('../chunk-P2RBE3FD.cjs');
9
9
  require('../chunk-7RGLTF76.cjs');
10
10
  require('../chunk-3AFWGEDJ.cjs');
11
11
  require('../chunk-VFUWWH52.cjs');
12
12
  require('../chunk-DETZZBG2.cjs');
13
- require('../chunk-IA7RTPT3.cjs');
13
+ require('../chunk-V4ISCZJ7.cjs');
14
14
  require('../chunk-2EI7NCUA.cjs');
15
+ require('../chunk-IXALYQT7.cjs');
15
16
  require('../chunk-Z5VUZ6YD.cjs');
16
17
  require('../chunk-7D737FLE.cjs');
17
18
  require('../chunk-OB5F4577.cjs');
18
- require('../chunk-V3L5DONY.cjs');
19
+ require('../chunk-B4SRYJLM.cjs');
19
20
  require('../chunk-7UTB4PHM.cjs');
20
21
  require('../chunk-FX3K6LNZ.cjs');
21
22
  require('../chunk-PPCATBOY.cjs');
@@ -47,11 +48,11 @@ function withSteps(workflow, steps, layout) {
47
48
  const run = workflow.run.kind === "steps" ? workflow.run : { kind: "steps", steps: [] };
48
49
  return {
49
50
  ...workflow,
50
- run: { ...run, steps: chunkGTNUQBXI_cjs.orderSteps(steps), layout: layout ?? run.layout }
51
+ run: { ...run, steps: chunkP2RBE3FD_cjs.orderSteps(steps), layout: layout ?? run.layout }
51
52
  };
52
53
  }
53
54
  var layoutOf = (workflow) => workflow.run.kind === "steps" && workflow.run.layout || {};
54
- var explicit = (steps) => steps.map((s) => ({ ...s, after: chunkGTNUQBXI_cjs.stepDependencies(steps, s.id) }));
55
+ var explicit = (steps) => steps.map((s) => ({ ...s, after: chunkP2RBE3FD_cjs.stepDependencies(steps, s.id) }));
55
56
  function stepIdFor(steps, title) {
56
57
  const base = title.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, "").replace(/^[^a-z]+/, "") || "step";
57
58
  const taken = new Set(steps.map((s) => s.id));
@@ -73,13 +74,13 @@ function blankStep(kind, id, title) {
73
74
  case "upload":
74
75
  return { id, kind, title };
75
76
  case "agent":
76
- return { id, kind, title, run: { kind: "prompt", promptTemplate: "" } };
77
+ return { id, kind, title };
77
78
  case "review":
78
79
  return { id, kind, title, instructions: "" };
79
80
  }
80
81
  }
81
82
  function addStep(workflow, kind, options = {}) {
82
- const steps = explicit(chunkGTNUQBXI_cjs.workflowSteps(workflow));
83
+ const steps = explicit(chunkP2RBE3FD_cjs.workflowSteps(workflow));
83
84
  const title = options.title ?? DEFAULT_TITLES[kind];
84
85
  const id = stepIdFor(steps, title);
85
86
  const step = { ...blankStep(kind, id, title), after: options.after ? [options.after] : [] };
@@ -88,7 +89,7 @@ function addStep(workflow, kind, options = {}) {
88
89
  return { workflow: withSteps(workflow, [...steps, step], layout), id };
89
90
  }
90
91
  function removeStep(workflow, id) {
91
- const steps = explicit(chunkGTNUQBXI_cjs.workflowSteps(workflow));
92
+ const steps = explicit(chunkP2RBE3FD_cjs.workflowSteps(workflow));
92
93
  const removed = steps.find((s) => s.id === id);
93
94
  if (!removed) return workflow;
94
95
  const bridged = steps.filter((s) => s.id !== id).map(
@@ -101,8 +102,8 @@ function removeStep(workflow, id) {
101
102
  return withSteps(workflow, bridged, layout);
102
103
  }
103
104
  function connectSteps(workflow, from, to) {
104
- const steps = explicit(chunkGTNUQBXI_cjs.workflowSteps(workflow));
105
- if (from === to || !steps.some((s) => s.id === from) || chunkGTNUQBXI_cjs.dependsOn(steps, from, to)) {
105
+ const steps = explicit(chunkP2RBE3FD_cjs.workflowSteps(workflow));
106
+ if (from === to || !steps.some((s) => s.id === from) || chunkP2RBE3FD_cjs.dependsOn(steps, from, to)) {
106
107
  return workflow;
107
108
  }
108
109
  return withSteps(
@@ -112,16 +113,16 @@ function connectSteps(workflow, from, to) {
112
113
  )
113
114
  );
114
115
  }
115
- var wouldCycle = (workflow, from, to) => from === to || chunkGTNUQBXI_cjs.dependsOn(chunkGTNUQBXI_cjs.workflowSteps(workflow), from, to);
116
+ var wouldCycle = (workflow, from, to) => from === to || chunkP2RBE3FD_cjs.dependsOn(chunkP2RBE3FD_cjs.workflowSteps(workflow), from, to);
116
117
  function disconnectSteps(workflow, from, to) {
117
- const steps = explicit(chunkGTNUQBXI_cjs.workflowSteps(workflow));
118
+ const steps = explicit(chunkP2RBE3FD_cjs.workflowSteps(workflow));
118
119
  return withSteps(
119
120
  workflow,
120
121
  steps.map((s) => s.id === to ? { ...s, after: (s.after ?? []).filter((d) => d !== from) } : s)
121
122
  );
122
123
  }
123
124
  function updateStep(workflow, id, patch) {
124
- const steps = explicit(chunkGTNUQBXI_cjs.workflowSteps(workflow));
125
+ const steps = explicit(chunkP2RBE3FD_cjs.workflowSteps(workflow));
125
126
  return withSteps(
126
127
  workflow,
127
128
  steps.map(
@@ -135,7 +136,7 @@ var renameIn = (text, from, to) => text.replace(
135
136
  );
136
137
  function renameInput(workflow, from, to) {
137
138
  if (from === to) return workflow;
138
- const steps = chunkGTNUQBXI_cjs.workflowSteps(workflow).map((s) => {
139
+ const steps = chunkP2RBE3FD_cjs.workflowSteps(workflow).map((s) => {
139
140
  if (s.kind === "agent")
140
141
  return {
141
142
  ...s,
@@ -149,13 +150,13 @@ function renameInput(workflow, from, to) {
149
150
  return withSteps(workflow, steps);
150
151
  }
151
152
  function moveStep(workflow, id, position) {
152
- return withSteps(workflow, chunkGTNUQBXI_cjs.workflowSteps(workflow), { ...layoutOf(workflow), [id]: position });
153
+ return withSteps(workflow, chunkP2RBE3FD_cjs.workflowSteps(workflow), { ...layoutOf(workflow), [id]: position });
153
154
  }
154
155
  var COLUMN = 300;
155
156
  var ROW = 140;
156
157
  function autoLayout(steps) {
157
158
  const layout = {};
158
- chunkGTNUQBXI_cjs.stepLevels(steps).forEach(
159
+ chunkP2RBE3FD_cjs.stepLevels(steps).forEach(
159
160
  (level, x) => level.forEach((s, y) => {
160
161
  layout[s.id] = { x: x * COLUMN, y: (y - (level.length - 1) / 2) * ROW };
161
162
  })
@@ -163,7 +164,7 @@ function autoLayout(steps) {
163
164
  return layout;
164
165
  }
165
166
  function layoutWithDefaults(workflow) {
166
- const auto = autoLayout(chunkGTNUQBXI_cjs.workflowSteps(workflow));
167
+ const auto = autoLayout(chunkP2RBE3FD_cjs.workflowSteps(workflow));
167
168
  return { ...auto, ...layoutOf(workflow) };
168
169
  }
169
170
  var DEFAULT_STEP_INSPECTOR_LABELS = {
@@ -178,10 +179,13 @@ var DEFAULT_STEP_INSPECTOR_LABELS = {
178
179
  fieldType: "Type",
179
180
  required: "Required",
180
181
  runs: "Runs",
182
+ chooseRun: "Choose a skill or write an instruction\u2026",
181
183
  ownPrompt: "Its own instruction",
182
184
  prompt: "Instruction",
183
185
  promptHint: "Use {{field}} for an input and {{steps.<id>}} for an earlier step\u2019s answer.",
184
186
  inputFor: "Input",
187
+ inputHint: "Type a value, or use a field: {fields}",
188
+ inputHintNoFields: "Type a value, or add a form field to fill it from.",
185
189
  thread: "Where it runs",
186
190
  threadMain: "In the run\u2019s thread (sees the conversation so far)",
187
191
  threadBranch: "On a branch (delivers only its result to the thread)",
@@ -220,7 +224,7 @@ function StepInspector({
220
224
  testId = "step-inspector"
221
225
  }) {
222
226
  const l = { ...DEFAULT_STEP_INSPECTOR_LABELS, ...labels };
223
- const steps = chunkGTNUQBXI_cjs.workflowSteps(workflow);
227
+ const steps = chunkP2RBE3FD_cjs.workflowSteps(workflow);
224
228
  const step = steps.find((s) => s.id === stepId);
225
229
  const run = workflow.run.kind === "steps" ? workflow.run : void 0;
226
230
  if (!step || !run) {
@@ -245,7 +249,7 @@ function StepInspector({
245
249
  ] });
246
250
  }
247
251
  const patch = (p) => onChange(updateStep(workflow, step.id, p));
248
- const deps = chunkGTNUQBXI_cjs.stepDependencies(steps, step.id);
252
+ const deps = chunkP2RBE3FD_cjs.stepDependencies(steps, step.id);
249
253
  const titleOf = (id) => steps.find((s) => s.id === id)?.title ?? id;
250
254
  return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-4", "data-testid": `${testId}-step`, children: [
251
255
  /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-between gap-2", children: [
@@ -329,7 +333,17 @@ function StepInspector({
329
333
  }
330
334
  ) })
331
335
  ] }),
332
- step.kind === "agent" && /* @__PURE__ */ jsxRuntime.jsx(AgentSettings, { step, workflows, patch, l, testId }),
336
+ step.kind === "agent" && /* @__PURE__ */ jsxRuntime.jsx(
337
+ AgentSettings,
338
+ {
339
+ step,
340
+ workflows,
341
+ fields: chunkP2RBE3FD_cjs.runFields(workflow).map((f) => f.name),
342
+ patch,
343
+ l,
344
+ testId
345
+ }
346
+ ),
333
347
  step.kind === "review" && /* @__PURE__ */ jsxRuntime.jsx(Field, { label: l.instructions, hint: l.instructionsHint, children: /* @__PURE__ */ jsxRuntime.jsx(
334
348
  ui.Textarea,
335
349
  {
@@ -442,42 +456,77 @@ function FormFields({
442
456
  )
443
457
  ] }) });
444
458
  }
459
+ var OWN_PROMPT = "__prompt";
460
+ function prefillSkillInputs(target, fields, current = {}) {
461
+ const out = {};
462
+ for (const f of target?.inputs ?? []) {
463
+ const typed = current[f.name];
464
+ if (typed) out[f.name] = typed;
465
+ else if (fields.includes(f.name)) out[f.name] = `{{${f.name}}}`;
466
+ }
467
+ return out;
468
+ }
445
469
  function AgentSettings({
446
470
  step,
447
471
  workflows,
472
+ fields,
448
473
  patch,
449
474
  l,
450
475
  testId
451
476
  }) {
452
477
  const target = step.workflow ? workflows.find((w) => w.id === step.workflow) : void 0;
478
+ const value = step.workflow ?? (step.run ? OWN_PROMPT : "");
479
+ const codes = fields.map((f) => `{{${f}}}`).join(", ");
453
480
  return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
454
481
  /* @__PURE__ */ jsxRuntime.jsx(Field, { label: l.runs, children: /* @__PURE__ */ jsxRuntime.jsxs(
455
482
  "select",
456
483
  {
457
484
  className: selectClass,
458
- value: step.workflow ?? "",
459
- onChange: (e) => e.target.value ? patch({ workflow: e.target.value, run: void 0, with: step.with ?? {} }) : patch({
460
- workflow: void 0,
461
- with: void 0,
462
- run: { kind: "prompt", promptTemplate: "" }
463
- }),
485
+ value,
486
+ onChange: (e) => {
487
+ const id = e.target.value;
488
+ if (id === OWN_PROMPT)
489
+ patch({
490
+ workflow: void 0,
491
+ with: void 0,
492
+ run: { kind: "prompt", promptTemplate: "" }
493
+ });
494
+ else if (id)
495
+ patch({
496
+ workflow: id,
497
+ run: void 0,
498
+ with: prefillSkillInputs(
499
+ workflows.find((w) => w.id === id),
500
+ fields,
501
+ step.with
502
+ )
503
+ });
504
+ },
464
505
  "data-testid": `${testId}-runs`,
465
506
  children: [
466
- /* @__PURE__ */ jsxRuntime.jsx("option", { value: "", children: l.ownPrompt }),
507
+ !value && /* @__PURE__ */ jsxRuntime.jsx("option", { value: "", disabled: true, children: l.chooseRun }),
508
+ /* @__PURE__ */ jsxRuntime.jsx("option", { value: OWN_PROMPT, children: l.ownPrompt }),
467
509
  workflows.map((w) => /* @__PURE__ */ jsxRuntime.jsx("option", { value: w.id, children: w.title }, w.id)),
468
510
  step.workflow && !target && /* @__PURE__ */ jsxRuntime.jsx("option", { value: step.workflow, children: step.workflow })
469
511
  ]
470
512
  }
471
513
  ) }),
472
- step.workflow ? (target?.inputs ?? []).map((f) => /* @__PURE__ */ jsxRuntime.jsx(Field, { label: `${l.inputFor}: ${f.label}`, children: /* @__PURE__ */ jsxRuntime.jsx(
473
- ui.Input,
514
+ step.workflow ? (target?.inputs ?? []).map((f) => /* @__PURE__ */ jsxRuntime.jsx(
515
+ Field,
474
516
  {
475
- value: step.with?.[f.name] ?? "",
476
- placeholder: `{{${f.name}}}`,
477
- onChange: (e) => patch({ with: { ...step.with, [f.name]: e.target.value } }),
478
- "data-testid": `${testId}-with-${f.name}`
479
- }
480
- ) }, f.name)) : step.run?.kind === "prompt" ? /* @__PURE__ */ jsxRuntime.jsx(Field, { label: l.prompt, hint: l.promptHint, children: /* @__PURE__ */ jsxRuntime.jsx(
517
+ label: `${l.inputFor}: ${f.label}`,
518
+ hint: step.with?.[f.name] ? void 0 : codes ? l.inputHint.replace("{fields}", codes) : l.inputHintNoFields,
519
+ children: /* @__PURE__ */ jsxRuntime.jsx(
520
+ ui.Input,
521
+ {
522
+ value: step.with?.[f.name] ?? "",
523
+ onChange: (e) => patch({ with: { ...step.with, [f.name]: e.target.value } }),
524
+ "data-testid": `${testId}-with-${f.name}`
525
+ }
526
+ )
527
+ },
528
+ f.name
529
+ )) : step.run?.kind === "prompt" ? /* @__PURE__ */ jsxRuntime.jsx(Field, { label: l.prompt, hint: l.promptHint, children: /* @__PURE__ */ jsxRuntime.jsx(
481
530
  ui.Textarea,
482
531
  {
483
532
  value: step.run.promptTemplate,
@@ -539,7 +588,7 @@ function triggerSummary(trigger, options = {}) {
539
588
  case "once":
540
589
  return trigger.runAt ? new Date(trigger.runAt).toLocaleString() : l.starts.once;
541
590
  case "repeat":
542
- return trigger.rrule ? chunkIUR565UW_cjs.describeRRule(trigger.rrule) : l.starts.repeat;
591
+ return trigger.rrule ? chunkF4LUD3YC_cjs.describeRRule(trigger.rrule) : l.starts.repeat;
543
592
  case "event":
544
593
  return trigger.eventKind && options.eventLabel?.(trigger.eventKind) || trigger.eventKind || l.starts.event;
545
594
  case "task":
@@ -594,7 +643,7 @@ function TriggerInspector({
594
643
  }
595
644
  )
596
645
  ] }),
597
- trigger.start === "repeat" && /* @__PURE__ */ jsxRuntime.jsx(chunkIUR565UW_cjs.RecurrenceBuilder, { rrule: trigger.rrule, onChange: (rrule) => set({ rrule }) }),
646
+ trigger.start === "repeat" && /* @__PURE__ */ jsxRuntime.jsx(chunkF4LUD3YC_cjs.RecurrenceBuilder, { rrule: trigger.rrule, onChange: (rrule) => set({ rrule }) }),
598
647
  trigger.start === "event" && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-1.5", children: [
599
648
  /* @__PURE__ */ jsxRuntime.jsx(ui.Label, { className: "text-xs", children: l.event }),
600
649
  /* @__PURE__ */ jsxRuntime.jsxs(
@@ -630,7 +679,7 @@ function TriggerInspector({
630
679
  /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-1.5", children: [
631
680
  /* @__PURE__ */ jsxRuntime.jsx(ui.Label, { className: "text-xs", children: l.agent }),
632
681
  /* @__PURE__ */ jsxRuntime.jsx(
633
- chunkIUR565UW_cjs.AgentSelect,
682
+ chunkF4LUD3YC_cjs.AgentSelect,
634
683
  {
635
684
  agents,
636
685
  value: trigger.agentId,
@@ -658,6 +707,45 @@ function TriggerInspector({
658
707
  ] })
659
708
  ] });
660
709
  }
710
+
711
+ // src/workflow-canvas/viewport.ts
712
+ var READABLE_ZOOM = 0.7;
713
+ var DEFAULT_W = 256;
714
+ var DEFAULT_H = 80;
715
+ var MARGIN = 48;
716
+ var sizeOf = (n) => ({
717
+ w: n.measured?.width ?? DEFAULT_W,
718
+ h: n.measured?.height ?? DEFAULT_H
719
+ });
720
+ function readableViewport(nodes, fittedZoom, frame, {
721
+ anchor,
722
+ centre = false,
723
+ reserveRight = 0
724
+ } = {}) {
725
+ if (fittedZoom >= READABLE_ZOOM || !frame.height || nodes.length === 0) return null;
726
+ const z = READABLE_ZOOM;
727
+ const at = nodes.find((n) => n.id === anchor) ?? nodes.reduce((a, b) => b.position.x < a.position.x ? b : a);
728
+ const { w, h } = sizeOf(at);
729
+ const y = frame.height / 2 - (at.position.y + h / 2) * z;
730
+ if (centre && at.id === anchor) {
731
+ const visible = Math.max(0, frame.width - reserveRight);
732
+ return { x: visible / 2 - (at.position.x + w / 2) * z, y, zoom: z };
733
+ }
734
+ return { x: MARGIN - at.position.x * z, y, zoom: z };
735
+ }
736
+ function revealCenter(node, view, frame, reserveRight = 0) {
737
+ const { w, h } = sizeOf(node);
738
+ const { x, y, zoom } = view;
739
+ const left = node.position.x * zoom + x;
740
+ const top = node.position.y * zoom + y;
741
+ const right = frame.width - reserveRight;
742
+ if (left >= 16 && top >= 16 && left + w * zoom <= right - 16 && top + h * zoom <= frame.height - 16)
743
+ return null;
744
+ return {
745
+ x: node.position.x + w / 2 + reserveRight / 2 / zoom,
746
+ y: node.position.y + h / 2
747
+ };
748
+ }
661
749
  var DEFAULT_WORKFLOW_CANVAS_LABELS = {
662
750
  form: "Form",
663
751
  upload: "Upload",
@@ -672,12 +760,13 @@ var DEFAULT_WORKFLOW_CANVAS_LABELS = {
672
760
  },
673
761
  addNext: "Add the next step",
674
762
  runs: "Runs \u201C{name}\u201D",
675
- instruction: "No instruction yet",
763
+ chooseRun: "Choose a skill or write an instruction",
676
764
  fields: "{count} fields",
677
765
  noFields: "No fields yet",
678
766
  approvedBy: "A person approves",
679
767
  emptyTitle: "Start your workflow",
680
- emptyHint: "Add the first step: what should happen when it starts?"
768
+ emptyHint: "Add the first step: what should happen when it starts?",
769
+ fitView: "Fit view"
681
770
  };
682
771
  var TRIGGER_NODE = "__trigger";
683
772
  var STEP_KIND_ICONS = {
@@ -802,7 +891,6 @@ function TriggerNode({ data }) {
802
891
  );
803
892
  }
804
893
  var NODE_TYPES = { step: StepNode, trigger: TriggerNode };
805
- var READABLE_ZOOM = 0.7;
806
894
  var firstWords = (text, n = 14) => {
807
895
  const words = text.trim().split(/\s+/);
808
896
  return words.length > n ? `${words.slice(0, n).join(" ")}\u2026` : text.trim();
@@ -813,7 +901,8 @@ function summaryOf(step, l, workflowTitle) {
813
901
  case "agent":
814
902
  if (step.workflow)
815
903
  return l.runs.replace("{name}", workflowTitle?.(step.workflow) ?? step.workflow);
816
- return step.run?.kind === "prompt" && step.run.promptTemplate.trim() ? firstWords(step.run.promptTemplate) : l.instruction;
904
+ if (step.run?.kind === "operation") return void 0;
905
+ return step.run?.kind === "prompt" && step.run.promptTemplate.trim() ? firstWords(step.run.promptTemplate) : l.chooseRun;
817
906
  case "form":
818
907
  return step.inputs.length ? step.inputs.length === 1 ? step.inputs[0].label : l.fields.replace("{count}", String(step.inputs.length)) : l.noFields;
819
908
  case "upload":
@@ -827,6 +916,7 @@ function WorkflowCanvas({
827
916
  onChange,
828
917
  selected = null,
829
918
  onSelect,
919
+ focus,
830
920
  onAddAfter,
831
921
  phases,
832
922
  workflowTitle,
@@ -838,12 +928,12 @@ function WorkflowCanvas({
838
928
  testId = "workflow-canvas"
839
929
  }) {
840
930
  const l = react.useMemo(() => ({ ...DEFAULT_WORKFLOW_CANVAS_LABELS, ...labels }), [labels]);
841
- const steps = chunkGTNUQBXI_cjs.workflowSteps(workflow);
931
+ const steps = chunkP2RBE3FD_cjs.workflowSteps(workflow);
842
932
  const editable = !!onChange;
843
933
  const built = react.useMemo(() => {
844
934
  const layout = layoutWithDefaults(workflow);
845
- const all = chunkGTNUQBXI_cjs.workflowSteps(workflow);
846
- const roots = all.filter((s) => chunkGTNUQBXI_cjs.stepDependencies(all, s.id).length === 0);
935
+ const all = chunkP2RBE3FD_cjs.workflowSteps(workflow);
936
+ const roots = all.filter((s) => chunkP2RBE3FD_cjs.stepDependencies(all, s.id).length === 0);
847
937
  const triggerNode = trigger ? [
848
938
  {
849
939
  id: TRIGGER_NODE,
@@ -880,7 +970,7 @@ function WorkflowCanvas({
880
970
  react.useEffect(() => setNodes(built), [built]);
881
971
  const edges = react.useMemo(
882
972
  () => steps.flatMap((s) => {
883
- const deps = chunkGTNUQBXI_cjs.stepDependencies(steps, s.id);
973
+ const deps = chunkP2RBE3FD_cjs.stepDependencies(steps, s.id);
884
974
  const from = deps.length ? deps : trigger ? [TRIGGER_NODE] : [];
885
975
  return from.map((d) => ({
886
976
  id: `${d}->${s.id}`,
@@ -918,46 +1008,57 @@ function WorkflowCanvas({
918
1008
  );
919
1009
  const frame = react.useRef(null);
920
1010
  const flowRef = react.useRef(null);
921
- const onInit = react.useCallback(
922
- async (flow) => {
923
- flowRef.current = flow;
1011
+ const hasTrigger = !!trigger;
1012
+ const selectedRef = react.useRef(selected);
1013
+ selectedRef.current = selected;
1014
+ const fit = react.useCallback(
1015
+ async (flow, anchorOnSelection) => {
924
1016
  await flow.fitView({
925
1017
  padding: { top: "48px", bottom: "48px", left: "48px", right: `${reserveRight + 48}px` },
926
1018
  maxZoom: 1
927
1019
  });
928
- const height = frame.current?.clientHeight;
929
- const shown = flow.getNodes();
930
- if (flow.getZoom() >= READABLE_ZOOM || !height || !shown.length) return;
931
- const left = Math.min(...shown.map((n) => n.position.x));
932
- const ys = shown.map((n) => n.position.y + (n.measured?.height ?? 0) / 2);
933
- const middle = (Math.min(...ys) + Math.max(...ys)) / 2;
934
- flow.setViewport({
935
- x: 48 - left * READABLE_ZOOM,
936
- y: height / 2 - middle * READABLE_ZOOM,
937
- zoom: READABLE_ZOOM
938
- });
1020
+ const box = frame.current;
1021
+ const picked = anchorOnSelection ? selectedRef.current : null;
1022
+ const view = readableViewport(
1023
+ flow.getNodes(),
1024
+ flow.getZoom(),
1025
+ { width: box?.clientWidth ?? 0, height: box?.clientHeight ?? 0 },
1026
+ {
1027
+ anchor: picked ?? (hasTrigger ? TRIGGER_NODE : null),
1028
+ centre: !!picked,
1029
+ reserveRight
1030
+ }
1031
+ );
1032
+ if (view) await flow.setViewport(view);
1033
+ },
1034
+ [reserveRight, hasTrigger]
1035
+ );
1036
+ const onInit = react.useCallback(
1037
+ async (flow) => {
1038
+ flowRef.current = flow;
1039
+ await fit(flow, false);
939
1040
  },
940
- [reserveRight]
1041
+ [fit]
941
1042
  );
1043
+ const target = focus ?? selected;
1044
+ const revealed = react.useRef(null);
942
1045
  react.useEffect(() => {
943
1046
  const flow = flowRef.current;
944
1047
  const box = frame.current;
945
- const node = selected ? flow?.getNode(selected) : void 0;
946
- if (!flow || !box || !node) return;
947
- const { x, y, zoom } = flow.getViewport();
948
- const w = (node.measured?.width ?? 256) * zoom;
949
- const h = (node.measured?.height ?? 80) * zoom;
950
- const left = node.position.x * zoom + x;
951
- const top = node.position.y * zoom + y;
952
- const right = box.clientWidth - reserveRight;
953
- if (left >= 16 && top >= 16 && left + w <= right - 16 && top + h <= box.clientHeight - 16)
954
- return;
955
- void flow.setCenter(
956
- node.position.x + (node.measured?.width ?? 256) / 2 + reserveRight / 2 / zoom,
957
- node.position.y + (node.measured?.height ?? 80) / 2,
958
- { zoom, duration: 250 }
1048
+ const node = target ? flow?.getNode(target) : void 0;
1049
+ const key = `${target}:${reserveRight}`;
1050
+ if (!target) revealed.current = null;
1051
+ if (!flow || !box || !node || revealed.current === key) return;
1052
+ revealed.current = key;
1053
+ const view = flow.getViewport();
1054
+ const centre = revealCenter(
1055
+ node,
1056
+ view,
1057
+ { width: box.clientWidth, height: box.clientHeight },
1058
+ reserveRight
959
1059
  );
960
- }, [selected, nodes, reserveRight]);
1060
+ if (centre) void flow.setCenter(centre.x, centre.y, { zoom: view.zoom, duration: 250 });
1061
+ }, [target, nodes, reserveRight]);
961
1062
  const onDelete = react.useCallback(
962
1063
  ({ nodes: gone, edges: cut }) => {
963
1064
  if (!onChange) return;
@@ -999,12 +1100,21 @@ function WorkflowCanvas({
999
1100
  elementsSelectable: true,
1000
1101
  deleteKeyCode: editable ? ["Backspace", "Delete"] : null,
1001
1102
  onInit,
1002
- fitViewOptions: { padding: 0.2, maxZoom: 1 },
1003
1103
  minZoom: 0.3,
1004
1104
  proOptions: { hideAttribution: true },
1005
1105
  children: [
1006
1106
  /* @__PURE__ */ jsxRuntime.jsx(react$1.Background, { variant: react$1.BackgroundVariant.Dots, gap: 18, size: 1.5 }),
1007
- /* @__PURE__ */ jsxRuntime.jsx(react$1.Controls, { showInteractive: false, position: "bottom-left" }),
1107
+ /* @__PURE__ */ jsxRuntime.jsx(react$1.Controls, { showInteractive: false, showFitView: false, position: "bottom-left", children: /* @__PURE__ */ jsxRuntime.jsx(
1108
+ react$1.ControlButton,
1109
+ {
1110
+ className: "react-flow__controls-fitview",
1111
+ onClick: () => flowRef.current && void fit(flowRef.current, true),
1112
+ title: l.fitView,
1113
+ "aria-label": l.fitView,
1114
+ "data-testid": `${testId}-fit`,
1115
+ children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Maximize, {})
1116
+ }
1117
+ ) }),
1008
1118
  steps.length > 3 && /* @__PURE__ */ jsxRuntime.jsx(
1009
1119
  react$1.MiniMap,
1010
1120
  {
@@ -1100,8 +1210,8 @@ function WorkflowBuilder({
1100
1210
  const [mode, setMode] = react.useState("design");
1101
1211
  const [adding, setAdding] = react.useState(false);
1102
1212
  const { workflow, trigger } = value;
1103
- const steps = chunkGTNUQBXI_cjs.workflowSteps(workflow);
1104
- const problems = chunkGTNUQBXI_cjs.validateWorkflowGraph(steps);
1213
+ const steps = chunkP2RBE3FD_cjs.workflowSteps(workflow);
1214
+ const problems = chunkP2RBE3FD_cjs.validateWorkflowGraph(steps);
1105
1215
  const titles = react.useMemo(() => new Map(workflows.map((w) => [w.id, w.title])), [workflows]);
1106
1216
  const setWorkflow = (next) => onChange({ ...value, workflow: next });
1107
1217
  const addAfter = (from, kind) => {
@@ -1226,6 +1336,7 @@ function WorkflowBuilder({
1226
1336
  onChange: setWorkflow,
1227
1337
  selected,
1228
1338
  onSelect: setSelected,
1339
+ focus: selected ?? (panelOpen ? TRIGGER_NODE : null),
1229
1340
  onAddAfter: addAfter,
1230
1341
  trigger: { title: l.start, summary },
1231
1342
  workflowTitle: (id) => titles.get(id),
@@ -1315,13 +1426,13 @@ function WorkflowPreview({
1315
1426
  renderIcon,
1316
1427
  testId
1317
1428
  }) {
1318
- const run = chunkIUR565UW_cjs.useWorkflowPreview(workflow, {
1429
+ const run = chunkF4LUD3YC_cjs.useWorkflowPreview(workflow, {
1319
1430
  resolveWorkflow: (id) => workflows.find((w) => w.id === id),
1320
1431
  compose,
1321
1432
  answer
1322
1433
  });
1323
1434
  return /* @__PURE__ */ jsxRuntime.jsx(
1324
- chunkGTNUQBXI_cjs.WorkflowRunner,
1435
+ chunkP2RBE3FD_cjs.WorkflowRunner,
1325
1436
  {
1326
1437
  workflow,
1327
1438
  run,
@@ -1362,7 +1473,7 @@ function triggerFields(trigger, clearOthers) {
1362
1473
  return {
1363
1474
  timezone: trigger.timezone,
1364
1475
  rrule: trigger.start === "repeat" ? trigger.rrule.trim() : none,
1365
- run_at: trigger.start === "once" ? chunkIUR565UW_cjs.localInputToIso(trigger.runAt) : none,
1476
+ run_at: trigger.start === "once" ? chunkF4LUD3YC_cjs.localInputToIso(trigger.runAt) : none,
1366
1477
  event_kind: trigger.start === "event" ? trigger.eventKind.trim() : none,
1367
1478
  after_conversation_ext_id: trigger.start === "task" ? trigger.afterTaskId : none,
1368
1479
  on_demand: trigger.start === "manual"
@@ -1376,7 +1487,7 @@ function plan(value, options) {
1376
1487
  criteria: [],
1377
1488
  max_passes: 3,
1378
1489
  documents: [],
1379
- steps: chunkGTNUQBXI_cjs.toPlanSteps(value.workflow, options)
1490
+ steps: chunkP2RBE3FD_cjs.toPlanSteps(value.workflow, options)
1380
1491
  };
1381
1492
  }
1382
1493
  function builderToWorkflowRequest(value, workspaceId, options = {}) {
@@ -1411,7 +1522,7 @@ function builderToWorkflowUpdate(value, options = {}) {
1411
1522
  }
1412
1523
  function workflowRecordToBuilder(record) {
1413
1524
  const planned = record.plan?.steps ?? [];
1414
- const steps = planned.length ? chunkGTNUQBXI_cjs.fromPlanSteps(planned) : record.prompt || record.skill_ref ? [
1525
+ const steps = planned.length ? chunkP2RBE3FD_cjs.fromPlanSteps(planned) : record.prompt || record.skill_ref ? [
1415
1526
  {
1416
1527
  id: "work",
1417
1528
  kind: "agent",
@@ -1419,7 +1530,7 @@ function workflowRecordToBuilder(record) {
1419
1530
  ...record.skill_ref ? { workflow: record.skill_ref } : { run: { kind: "prompt", promptTemplate: record.prompt } }
1420
1531
  }
1421
1532
  ] : [];
1422
- const when = chunkIUR565UW_cjs.workflowWhen(record);
1533
+ const when = chunkF4LUD3YC_cjs.workflowWhen(record);
1423
1534
  return {
1424
1535
  workflow: {
1425
1536
  id: record.external_id,
@@ -1428,12 +1539,12 @@ function workflowRecordToBuilder(record) {
1428
1539
  inputs: [],
1429
1540
  landing: "chat",
1430
1541
  schedulable: false,
1431
- run: { kind: "steps", steps, layout: chunkGTNUQBXI_cjs.layoutFromPlanSteps(planned ?? []) }
1542
+ run: { kind: "steps", steps, layout: chunkP2RBE3FD_cjs.layoutFromPlanSteps(planned ?? []) }
1432
1543
  },
1433
1544
  trigger: {
1434
1545
  ...DEFAULT_WORKFLOW_TRIGGER,
1435
1546
  start: when === "now" ? "manual" : when,
1436
- runAt: chunkIUR565UW_cjs.isoToLocalInput(record.run_at),
1547
+ runAt: chunkF4LUD3YC_cjs.isoToLocalInput(record.run_at),
1437
1548
  rrule: record.rrule ?? "",
1438
1549
  timezone: record.timezone || DEFAULT_WORKFLOW_TRIGGER.timezone,
1439
1550
  eventKind: record.event_kind ?? "",
@@ -1494,7 +1605,7 @@ function ConnectedWorkflowBuilder({
1494
1605
  () => [
1495
1606
  ...hostWorkflows,
1496
1607
  ...(skills.data ?? []).map(
1497
- (s) => chunkGTNUQBXI_cjs.skillToWorkflow({
1608
+ (s) => chunkP2RBE3FD_cjs.skillToWorkflow({
1498
1609
  name: s.name,
1499
1610
  slug: s.slug,
1500
1611
  description: s.description,
@@ -1510,7 +1621,7 @@ function ConnectedWorkflowBuilder({
1510
1621
  }));
1511
1622
  const tasks = (conversations.data ?? []).filter((c) => c.status && c.status !== "done").map((c) => ({ value: c.external_id, label: c.title || c.external_id }));
1512
1623
  const options = { resolveWorkflow: (wid) => workflows.find((w) => w.id === wid), compose };
1513
- const problem = triggerProblem(value.trigger) ?? (chunkGTNUQBXI_cjs.validateWorkflowGraph(chunkGTNUQBXI_cjs.workflowSteps(value.workflow)).length ? "graph" : null);
1624
+ const problem = triggerProblem(value.trigger) ?? (chunkP2RBE3FD_cjs.validateWorkflowGraph(chunkP2RBE3FD_cjs.workflowSteps(value.workflow)).length ? "graph" : null);
1514
1625
  const busy = create.isPending || update.isPending || run.isPending;
1515
1626
  const save = async () => {
1516
1627
  if (!workspaceId) return void 0;