@particle-academy/fancy-flow 0.24.0 → 0.25.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 (41) hide show
  1. package/dist/{chunk-QAA4CA22.js → chunk-ATQXZEVD.js} +117 -6
  2. package/dist/chunk-ATQXZEVD.js.map +1 -0
  3. package/dist/{chunk-OHVSEHDC.js → chunk-N5ICD2WZ.js} +3 -3
  4. package/dist/{chunk-OHVSEHDC.js.map → chunk-N5ICD2WZ.js.map} +1 -1
  5. package/dist/{chunk-ZS6DVGB3.js → chunk-OFW7GN3Y.js} +4 -4
  6. package/dist/{chunk-ZS6DVGB3.js.map → chunk-OFW7GN3Y.js.map} +1 -1
  7. package/dist/{chunk-YXRLIV7A.js → chunk-Q6IPK64P.js} +4 -2
  8. package/dist/chunk-Q6IPK64P.js.map +1 -0
  9. package/dist/{chunk-KDHLKBL2.js → chunk-U2VJB7HR.js} +7 -5
  10. package/dist/chunk-U2VJB7HR.js.map +1 -0
  11. package/dist/engine.cjs +4 -2
  12. package/dist/engine.cjs.map +1 -1
  13. package/dist/engine.js +3 -3
  14. package/dist/index.cjs +119 -23
  15. package/dist/index.cjs.map +1 -1
  16. package/dist/index.d.cts +3 -8
  17. package/dist/index.d.ts +3 -8
  18. package/dist/index.js +13 -32
  19. package/dist/index.js.map +1 -1
  20. package/dist/registry/index.d.cts +2 -2
  21. package/dist/registry/index.d.ts +2 -2
  22. package/dist/registry.cjs +110 -2
  23. package/dist/registry.cjs.map +1 -1
  24. package/dist/registry.js +3 -3
  25. package/dist/runtime.cjs +4 -2
  26. package/dist/runtime.cjs.map +1 -1
  27. package/dist/runtime.js +3 -3
  28. package/dist/schema.cjs.map +1 -1
  29. package/dist/schema.js +2 -2
  30. package/dist/styles.css +60 -0
  31. package/dist/styles.css.map +1 -1
  32. package/dist/{types-DwRpXXNy.d.ts → types-BGtR3k9J.d.ts} +1 -1
  33. package/dist/{types-BekE5JTG.d.cts → types-B_pxRqfw.d.cts} +1 -1
  34. package/dist/ux.cjs.map +1 -1
  35. package/dist/ux.d.cts +1 -1
  36. package/dist/ux.d.ts +1 -1
  37. package/dist/ux.js +1 -1
  38. package/package.json +1 -1
  39. package/dist/chunk-KDHLKBL2.js.map +0 -1
  40. package/dist/chunk-QAA4CA22.js.map +0 -1
  41. package/dist/chunk-YXRLIV7A.js.map +0 -1
@@ -1,5 +1,5 @@
1
- import { a as NodeKindDefinition, P as PortSpec } from '../types-BekE5JTG.cjs';
2
- export { C as ConfigField, b as CredentialConfigField, D as DocumentConfigField, E as ExpressionConfigField, J as JsonConfigField, K as KeyValueConfigField, N as NodeCategory, c as NumberConfigField, R as RenderBodyContext, d as RepeaterConfigField, e as RepeaterRowField, S as SelectConfigField, f as SwitchConfigField, T as TextConfigField, g as TextareaConfigField } from '../types-BekE5JTG.cjs';
1
+ import { a as NodeKindDefinition, P as PortSpec } from '../types-B_pxRqfw.cjs';
2
+ export { C as ConfigField, b as CredentialConfigField, D as DocumentConfigField, E as ExpressionConfigField, J as JsonConfigField, K as KeyValueConfigField, N as NodeCategory, c as NumberConfigField, R as RenderBodyContext, d as RepeaterConfigField, e as RepeaterRowField, S as SelectConfigField, f as SwitchConfigField, T as TextConfigField, g as TextareaConfigField } from '../types-B_pxRqfw.cjs';
3
3
  import { P as PortDescriptor, a as FlowNode, N as NodeExecutor } from '../types-CMSrWVYM.cjs';
4
4
  import { Connection, Edge, NodeProps, NodeTypes } from '@xyflow/react';
5
5
  import { b as LlmRoute } from '../capabilities-exVeADXz.cjs';
@@ -1,5 +1,5 @@
1
- import { a as NodeKindDefinition, P as PortSpec } from '../types-DwRpXXNy.js';
2
- export { C as ConfigField, b as CredentialConfigField, D as DocumentConfigField, E as ExpressionConfigField, J as JsonConfigField, K as KeyValueConfigField, N as NodeCategory, c as NumberConfigField, R as RenderBodyContext, d as RepeaterConfigField, e as RepeaterRowField, S as SelectConfigField, f as SwitchConfigField, T as TextConfigField, g as TextareaConfigField } from '../types-DwRpXXNy.js';
1
+ import { a as NodeKindDefinition, P as PortSpec } from '../types-BGtR3k9J.js';
2
+ export { C as ConfigField, b as CredentialConfigField, D as DocumentConfigField, E as ExpressionConfigField, J as JsonConfigField, K as KeyValueConfigField, N as NodeCategory, c as NumberConfigField, R as RenderBodyContext, d as RepeaterConfigField, e as RepeaterRowField, S as SelectConfigField, f as SwitchConfigField, T as TextConfigField, g as TextareaConfigField } from '../types-BGtR3k9J.js';
3
3
  import { P as PortDescriptor, a as FlowNode, N as NodeExecutor } from '../types-CMSrWVYM.js';
4
4
  import { Connection, Edge, NodeProps, NodeTypes } from '@xyflow/react';
5
5
  import { b as LlmRoute } from '../capabilities-85Mjn4uW.js';
package/dist/registry.cjs CHANGED
@@ -181,6 +181,8 @@ function categoryAccent(category) {
181
181
  return "#a855f7";
182
182
  case "layout":
183
183
  return "#64748b";
184
+ case "annotation":
185
+ return "#eab308";
184
186
  default:
185
187
  return "#71717a";
186
188
  }
@@ -324,12 +326,14 @@ async function runFlow(graph, executors, onEvent = () => {
324
326
  }
325
327
  }
326
328
  const visualKind = getNodeKind(node.type ?? "");
327
- if (node.type === "note" || visualKind?.category === "layout") {
329
+ const isLayout = visualKind?.category === "layout";
330
+ const isAnnotation = node.type === "note" || visualKind?.category === "annotation";
331
+ if (isLayout || isAnnotation) {
328
332
  onEvent({
329
333
  type: "node-status",
330
334
  nodeId: node.id,
331
335
  status: "idle",
332
- text: visualKind?.category === "layout" ? "lane" : "annotation"
336
+ text: isLayout ? "lane" : "annotation"
333
337
  });
334
338
  continue;
335
339
  }
@@ -9776,6 +9780,81 @@ function LaneNodeInner(props) {
9776
9780
  );
9777
9781
  }
9778
9782
  var LaneNode = ReactExports.memo(LaneNodeInner);
9783
+ var FlowEditorContext = ReactExports.createContext(null);
9784
+ FlowEditorContext.Provider;
9785
+ function useFlowEditorOptional() {
9786
+ return ReactExports.useContext(FlowEditorContext);
9787
+ }
9788
+ var NOTE_COLORS = {
9789
+ amber: { bg: "rgba(234, 179, 8, 0.14)", border: "rgba(234, 179, 8, 0.55)", title: "#a16207" },
9790
+ sky: { bg: "rgba(14, 165, 233, 0.12)", border: "rgba(14, 165, 233, 0.5)", title: "#0369a1" },
9791
+ violet: { bg: "rgba(139, 92, 246, 0.13)", border: "rgba(139, 92, 246, 0.5)", title: "#6d28d9" },
9792
+ emerald: { bg: "rgba(16, 185, 129, 0.13)", border: "rgba(16, 185, 129, 0.5)", title: "#047857" },
9793
+ rose: { bg: "rgba(244, 63, 94, 0.12)", border: "rgba(244, 63, 94, 0.5)", title: "#be123c" },
9794
+ slate: { bg: "rgba(100, 116, 139, 0.12)", border: "rgba(100, 116, 139, 0.5)", title: "#475569" }
9795
+ };
9796
+ function coerceColor(v) {
9797
+ return typeof v === "string" && v in NOTE_COLORS ? v : "amber";
9798
+ }
9799
+ function NoteNodeInner(props) {
9800
+ const data = props.data;
9801
+ const config = data.config ?? {};
9802
+ const api = useFlowEditorOptional();
9803
+ const hasConfigText = typeof config.text === "string" && config.text.length > 0;
9804
+ const text = hasConfigText ? String(config.text) : typeof data.body === "string" ? data.body : typeof data.text === "string" ? data.text : "";
9805
+ const title = typeof config.title === "string" && config.title || (!hasConfigText && typeof data.body === "string" && typeof data.label === "string" ? data.label : "");
9806
+ const skin = NOTE_COLORS[coerceColor(config.color)];
9807
+ const [editing, setEditing] = ReactExports.useState(false);
9808
+ const [draft, setDraft] = ReactExports.useState(text);
9809
+ const areaRef = ReactExports.useRef(null);
9810
+ ReactExports.useEffect(() => {
9811
+ if (editing && areaRef.current) {
9812
+ const el = areaRef.current;
9813
+ el.focus();
9814
+ el.setSelectionRange(el.value.length, el.value.length);
9815
+ }
9816
+ }, [editing]);
9817
+ const commit = () => {
9818
+ setEditing(false);
9819
+ if (!api || draft === text) return;
9820
+ const current = api.nodes.find((n) => n.id === props.id);
9821
+ if (!current) return;
9822
+ api.updateNode({
9823
+ ...current,
9824
+ data: { ...current.data, config: { ...config, text: draft } }
9825
+ });
9826
+ };
9827
+ return /* @__PURE__ */ jsxRuntime.jsxs(
9828
+ "div",
9829
+ {
9830
+ className: ["ff-note", props.selected ? "ff-note--selected" : ""].filter(Boolean).join(" "),
9831
+ style: { background: skin.bg, borderColor: skin.border },
9832
+ onDoubleClick: api ? () => {
9833
+ setDraft(text);
9834
+ setEditing(true);
9835
+ } : void 0,
9836
+ children: [
9837
+ /* @__PURE__ */ jsxRuntime.jsx(NodeResizer, { isVisible: props.selected ?? false, color: skin.border, minWidth: 140, minHeight: 80 }),
9838
+ title && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "ff-note__title", style: { color: skin.title }, children: title }),
9839
+ editing ? /* @__PURE__ */ jsxRuntime.jsx(
9840
+ "textarea",
9841
+ {
9842
+ ref: areaRef,
9843
+ className: "ff-note__input nodrag nowheel",
9844
+ value: draft,
9845
+ onChange: (e) => setDraft(e.target.value),
9846
+ onBlur: commit,
9847
+ onKeyDown: (e) => {
9848
+ if (e.key === "Escape") setEditing(false);
9849
+ if (e.key === "Enter" && (e.metaKey || e.ctrlKey)) commit();
9850
+ }
9851
+ }
9852
+ ) : /* @__PURE__ */ jsxRuntime.jsx("div", { className: "ff-note__body", children: text || /* @__PURE__ */ jsxRuntime.jsx("span", { className: "ff-note__placeholder", children: api ? "Double-click to write a note\u2026" : "Note" }) })
9853
+ ]
9854
+ }
9855
+ );
9856
+ }
9857
+ var NoteNode = ReactExports.memo(NoteNodeInner);
9779
9858
 
9780
9859
  // src/registry/builtin.ts
9781
9860
  function casePorts(cases) {
@@ -10544,6 +10623,35 @@ var KINDS = [
10544
10623
  defaultConfig: { title: "Lane", orientation: "horizontal" },
10545
10624
  resizable: { minWidth: 160, minHeight: 72 },
10546
10625
  component: LaneNode
10626
+ },
10627
+ {
10628
+ // Note — a sticky-note annotation. Portless + visual-only: the runtime skips
10629
+ // the `annotation` category, so a note's text NEVER reaches a runner — it
10630
+ // rides in the document purely for people, editors, and MCP tools. Uses its
10631
+ // own renderer (NoteNode); double-click on the canvas to edit in place.
10632
+ name: "@particle-academy/note",
10633
+ aliases: ["note", "@fancy/note"],
10634
+ category: "annotation",
10635
+ label: "Note",
10636
+ description: "A sticky note that documents the canvas. Never runs \u2014 editor + agent only.",
10637
+ icon: "\u{1F5D2}",
10638
+ inputs: [],
10639
+ outputs: [],
10640
+ configSchema: [
10641
+ { type: "text", key: "title", label: "Title", placeholder: "Optional heading" },
10642
+ { type: "textarea", key: "text", label: "Note", rows: 5, placeholder: "What does this part of the flow do?" },
10643
+ { type: "select", key: "color", label: "Color", default: "amber", options: [
10644
+ { value: "amber", label: "Amber" },
10645
+ { value: "sky", label: "Sky" },
10646
+ { value: "violet", label: "Violet" },
10647
+ { value: "emerald", label: "Emerald" },
10648
+ { value: "rose", label: "Rose" },
10649
+ { value: "slate", label: "Slate" }
10650
+ ] }
10651
+ ],
10652
+ defaultConfig: { text: "", color: "amber" },
10653
+ resizable: { minWidth: 140, minHeight: 80 },
10654
+ component: NoteNode
10547
10655
  }
10548
10656
  ];
10549
10657
  function registerBuiltinKinds() {