@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.
- package/dist/{chunk-QAA4CA22.js → chunk-ATQXZEVD.js} +117 -6
- package/dist/chunk-ATQXZEVD.js.map +1 -0
- package/dist/{chunk-OHVSEHDC.js → chunk-N5ICD2WZ.js} +3 -3
- package/dist/{chunk-OHVSEHDC.js.map → chunk-N5ICD2WZ.js.map} +1 -1
- package/dist/{chunk-ZS6DVGB3.js → chunk-OFW7GN3Y.js} +4 -4
- package/dist/{chunk-ZS6DVGB3.js.map → chunk-OFW7GN3Y.js.map} +1 -1
- package/dist/{chunk-YXRLIV7A.js → chunk-Q6IPK64P.js} +4 -2
- package/dist/chunk-Q6IPK64P.js.map +1 -0
- package/dist/{chunk-KDHLKBL2.js → chunk-U2VJB7HR.js} +7 -5
- package/dist/chunk-U2VJB7HR.js.map +1 -0
- package/dist/engine.cjs +4 -2
- package/dist/engine.cjs.map +1 -1
- package/dist/engine.js +3 -3
- package/dist/index.cjs +119 -23
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +3 -8
- package/dist/index.d.ts +3 -8
- package/dist/index.js +13 -32
- package/dist/index.js.map +1 -1
- package/dist/registry/index.d.cts +2 -2
- package/dist/registry/index.d.ts +2 -2
- package/dist/registry.cjs +110 -2
- package/dist/registry.cjs.map +1 -1
- package/dist/registry.js +3 -3
- package/dist/runtime.cjs +4 -2
- package/dist/runtime.cjs.map +1 -1
- package/dist/runtime.js +3 -3
- package/dist/schema.cjs.map +1 -1
- package/dist/schema.js +2 -2
- package/dist/styles.css +60 -0
- package/dist/styles.css.map +1 -1
- package/dist/{types-DwRpXXNy.d.ts → types-BGtR3k9J.d.ts} +1 -1
- package/dist/{types-BekE5JTG.d.cts → types-B_pxRqfw.d.cts} +1 -1
- package/dist/ux.cjs.map +1 -1
- package/dist/ux.d.cts +1 -1
- package/dist/ux.d.ts +1 -1
- package/dist/ux.js +1 -1
- package/package.json +1 -1
- package/dist/chunk-KDHLKBL2.js.map +0 -1
- package/dist/chunk-QAA4CA22.js.map +0 -1
- package/dist/chunk-YXRLIV7A.js.map +0 -1
package/dist/index.cjs
CHANGED
|
@@ -1870,6 +1870,8 @@ function categoryAccent(category) {
|
|
|
1870
1870
|
return "#a855f7";
|
|
1871
1871
|
case "layout":
|
|
1872
1872
|
return "#64748b";
|
|
1873
|
+
case "annotation":
|
|
1874
|
+
return "#eab308";
|
|
1873
1875
|
default:
|
|
1874
1876
|
return "#71717a";
|
|
1875
1877
|
}
|
|
@@ -10976,6 +10978,88 @@ function LaneNodeInner(props) {
|
|
|
10976
10978
|
);
|
|
10977
10979
|
}
|
|
10978
10980
|
var LaneNode = ReactExports.memo(LaneNodeInner);
|
|
10981
|
+
var FlowEditorContext = ReactExports.createContext(null);
|
|
10982
|
+
var FlowEditorProvider = FlowEditorContext.Provider;
|
|
10983
|
+
function useFlowEditor() {
|
|
10984
|
+
const api = ReactExports.useContext(FlowEditorContext);
|
|
10985
|
+
if (api === null) {
|
|
10986
|
+
throw new Error("useFlowEditor() must be called inside <FlowEditor>.");
|
|
10987
|
+
}
|
|
10988
|
+
return api;
|
|
10989
|
+
}
|
|
10990
|
+
function useFlowEditorOptional() {
|
|
10991
|
+
return ReactExports.useContext(FlowEditorContext);
|
|
10992
|
+
}
|
|
10993
|
+
var NOTE_COLORS = {
|
|
10994
|
+
amber: { bg: "rgba(234, 179, 8, 0.14)", border: "rgba(234, 179, 8, 0.55)", title: "#a16207" },
|
|
10995
|
+
sky: { bg: "rgba(14, 165, 233, 0.12)", border: "rgba(14, 165, 233, 0.5)", title: "#0369a1" },
|
|
10996
|
+
violet: { bg: "rgba(139, 92, 246, 0.13)", border: "rgba(139, 92, 246, 0.5)", title: "#6d28d9" },
|
|
10997
|
+
emerald: { bg: "rgba(16, 185, 129, 0.13)", border: "rgba(16, 185, 129, 0.5)", title: "#047857" },
|
|
10998
|
+
rose: { bg: "rgba(244, 63, 94, 0.12)", border: "rgba(244, 63, 94, 0.5)", title: "#be123c" },
|
|
10999
|
+
slate: { bg: "rgba(100, 116, 139, 0.12)", border: "rgba(100, 116, 139, 0.5)", title: "#475569" }
|
|
11000
|
+
};
|
|
11001
|
+
function coerceColor(v2) {
|
|
11002
|
+
return typeof v2 === "string" && v2 in NOTE_COLORS ? v2 : "amber";
|
|
11003
|
+
}
|
|
11004
|
+
function NoteNodeInner(props) {
|
|
11005
|
+
const data = props.data;
|
|
11006
|
+
const config = data.config ?? {};
|
|
11007
|
+
const api = useFlowEditorOptional();
|
|
11008
|
+
const hasConfigText = typeof config.text === "string" && config.text.length > 0;
|
|
11009
|
+
const text = hasConfigText ? String(config.text) : typeof data.body === "string" ? data.body : typeof data.text === "string" ? data.text : "";
|
|
11010
|
+
const title = typeof config.title === "string" && config.title || (!hasConfigText && typeof data.body === "string" && typeof data.label === "string" ? data.label : "");
|
|
11011
|
+
const skin = NOTE_COLORS[coerceColor(config.color)];
|
|
11012
|
+
const [editing, setEditing] = ReactExports.useState(false);
|
|
11013
|
+
const [draft, setDraft] = ReactExports.useState(text);
|
|
11014
|
+
const areaRef = ReactExports.useRef(null);
|
|
11015
|
+
ReactExports.useEffect(() => {
|
|
11016
|
+
if (editing && areaRef.current) {
|
|
11017
|
+
const el = areaRef.current;
|
|
11018
|
+
el.focus();
|
|
11019
|
+
el.setSelectionRange(el.value.length, el.value.length);
|
|
11020
|
+
}
|
|
11021
|
+
}, [editing]);
|
|
11022
|
+
const commit = () => {
|
|
11023
|
+
setEditing(false);
|
|
11024
|
+
if (!api || draft === text) return;
|
|
11025
|
+
const current = api.nodes.find((n) => n.id === props.id);
|
|
11026
|
+
if (!current) return;
|
|
11027
|
+
api.updateNode({
|
|
11028
|
+
...current,
|
|
11029
|
+
data: { ...current.data, config: { ...config, text: draft } }
|
|
11030
|
+
});
|
|
11031
|
+
};
|
|
11032
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
11033
|
+
"div",
|
|
11034
|
+
{
|
|
11035
|
+
className: ["ff-note", props.selected ? "ff-note--selected" : ""].filter(Boolean).join(" "),
|
|
11036
|
+
style: { background: skin.bg, borderColor: skin.border },
|
|
11037
|
+
onDoubleClick: api ? () => {
|
|
11038
|
+
setDraft(text);
|
|
11039
|
+
setEditing(true);
|
|
11040
|
+
} : void 0,
|
|
11041
|
+
children: [
|
|
11042
|
+
/* @__PURE__ */ jsxRuntime.jsx(NodeResizer, { isVisible: props.selected ?? false, color: skin.border, minWidth: 140, minHeight: 80 }),
|
|
11043
|
+
title && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "ff-note__title", style: { color: skin.title }, children: title }),
|
|
11044
|
+
editing ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
11045
|
+
"textarea",
|
|
11046
|
+
{
|
|
11047
|
+
ref: areaRef,
|
|
11048
|
+
className: "ff-note__input nodrag nowheel",
|
|
11049
|
+
value: draft,
|
|
11050
|
+
onChange: (e) => setDraft(e.target.value),
|
|
11051
|
+
onBlur: commit,
|
|
11052
|
+
onKeyDown: (e) => {
|
|
11053
|
+
if (e.key === "Escape") setEditing(false);
|
|
11054
|
+
if (e.key === "Enter" && (e.metaKey || e.ctrlKey)) commit();
|
|
11055
|
+
}
|
|
11056
|
+
}
|
|
11057
|
+
) : /* @__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" }) })
|
|
11058
|
+
]
|
|
11059
|
+
}
|
|
11060
|
+
);
|
|
11061
|
+
}
|
|
11062
|
+
var NoteNode = ReactExports.memo(NoteNodeInner);
|
|
10979
11063
|
|
|
10980
11064
|
// src/registry/capabilities.ts
|
|
10981
11065
|
var llmClient = null;
|
|
@@ -11091,12 +11175,14 @@ async function runFlow(graph, executors, onEvent = () => {
|
|
|
11091
11175
|
}
|
|
11092
11176
|
}
|
|
11093
11177
|
const visualKind = getNodeKind(node.type ?? "");
|
|
11094
|
-
|
|
11178
|
+
const isLayout = visualKind?.category === "layout";
|
|
11179
|
+
const isAnnotation = node.type === "note" || visualKind?.category === "annotation";
|
|
11180
|
+
if (isLayout || isAnnotation) {
|
|
11095
11181
|
onEvent({
|
|
11096
11182
|
type: "node-status",
|
|
11097
11183
|
nodeId: node.id,
|
|
11098
11184
|
status: "idle",
|
|
11099
|
-
text:
|
|
11185
|
+
text: isLayout ? "lane" : "annotation"
|
|
11100
11186
|
});
|
|
11101
11187
|
continue;
|
|
11102
11188
|
}
|
|
@@ -12053,6 +12139,35 @@ var KINDS = [
|
|
|
12053
12139
|
defaultConfig: { title: "Lane", orientation: "horizontal" },
|
|
12054
12140
|
resizable: { minWidth: 160, minHeight: 72 },
|
|
12055
12141
|
component: LaneNode
|
|
12142
|
+
},
|
|
12143
|
+
{
|
|
12144
|
+
// Note — a sticky-note annotation. Portless + visual-only: the runtime skips
|
|
12145
|
+
// the `annotation` category, so a note's text NEVER reaches a runner — it
|
|
12146
|
+
// rides in the document purely for people, editors, and MCP tools. Uses its
|
|
12147
|
+
// own renderer (NoteNode); double-click on the canvas to edit in place.
|
|
12148
|
+
name: "@particle-academy/note",
|
|
12149
|
+
aliases: ["note", "@fancy/note"],
|
|
12150
|
+
category: "annotation",
|
|
12151
|
+
label: "Note",
|
|
12152
|
+
description: "A sticky note that documents the canvas. Never runs \u2014 editor + agent only.",
|
|
12153
|
+
icon: "\u{1F5D2}",
|
|
12154
|
+
inputs: [],
|
|
12155
|
+
outputs: [],
|
|
12156
|
+
configSchema: [
|
|
12157
|
+
{ type: "text", key: "title", label: "Title", placeholder: "Optional heading" },
|
|
12158
|
+
{ type: "textarea", key: "text", label: "Note", rows: 5, placeholder: "What does this part of the flow do?" },
|
|
12159
|
+
{ type: "select", key: "color", label: "Color", default: "amber", options: [
|
|
12160
|
+
{ value: "amber", label: "Amber" },
|
|
12161
|
+
{ value: "sky", label: "Sky" },
|
|
12162
|
+
{ value: "violet", label: "Violet" },
|
|
12163
|
+
{ value: "emerald", label: "Emerald" },
|
|
12164
|
+
{ value: "rose", label: "Rose" },
|
|
12165
|
+
{ value: "slate", label: "Slate" }
|
|
12166
|
+
] }
|
|
12167
|
+
],
|
|
12168
|
+
defaultConfig: { text: "", color: "amber" },
|
|
12169
|
+
resizable: { minWidth: 140, minHeight: 80 },
|
|
12170
|
+
component: NoteNode
|
|
12056
12171
|
}
|
|
12057
12172
|
];
|
|
12058
12173
|
function registerBuiltinKinds() {
|
|
@@ -12151,14 +12266,6 @@ function OutputNodeInner(props) {
|
|
|
12151
12266
|
return /* @__PURE__ */ jsxRuntime.jsx(NodeShell, { node: props, accent: "#a855f7", tag: "OUTPUT", icon: "\u25CF", showOutputs: false });
|
|
12152
12267
|
}
|
|
12153
12268
|
var OutputNode2 = ReactExports.memo(OutputNodeInner);
|
|
12154
|
-
function NoteNodeInner({ data, selected: selected2 }) {
|
|
12155
|
-
const noteData = data;
|
|
12156
|
-
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: `ff-note ${selected2 ? "ff-note--selected" : ""}`, children: [
|
|
12157
|
-
noteData.label && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "ff-note__title", children: noteData.label }),
|
|
12158
|
-
noteData.body && /* @__PURE__ */ jsxRuntime.jsx("p", { className: "ff-note__body", children: noteData.body })
|
|
12159
|
-
] });
|
|
12160
|
-
}
|
|
12161
|
-
var NoteNode = ReactExports.memo(NoteNodeInner);
|
|
12162
12269
|
function SubgraphNodeInner(props) {
|
|
12163
12270
|
const data = props.data;
|
|
12164
12271
|
const childCount = data.childIds?.length ?? 0;
|
|
@@ -12545,7 +12652,7 @@ function FlowCanvas({
|
|
|
12545
12652
|
}
|
|
12546
12653
|
);
|
|
12547
12654
|
}
|
|
12548
|
-
var CATEGORY_ORDER = ["trigger", "logic", "data", "ai", "io", "human", "output", "layout", "custom"];
|
|
12655
|
+
var CATEGORY_ORDER = ["trigger", "logic", "data", "ai", "io", "human", "output", "layout", "annotation", "custom"];
|
|
12549
12656
|
var CATEGORY_LABELS = {
|
|
12550
12657
|
trigger: "Triggers",
|
|
12551
12658
|
logic: "Logic",
|
|
@@ -12555,6 +12662,7 @@ var CATEGORY_LABELS = {
|
|
|
12555
12662
|
human: "Human",
|
|
12556
12663
|
output: "Output",
|
|
12557
12664
|
layout: "Layout",
|
|
12665
|
+
annotation: "Notes",
|
|
12558
12666
|
custom: "Custom"
|
|
12559
12667
|
};
|
|
12560
12668
|
function NodePalette({ categories, onPick, className, style: style2 }) {
|
|
@@ -13694,18 +13802,6 @@ function buildNodeTypes() {
|
|
|
13694
13802
|
}
|
|
13695
13803
|
return map;
|
|
13696
13804
|
}
|
|
13697
|
-
var FlowEditorContext = ReactExports.createContext(null);
|
|
13698
|
-
var FlowEditorProvider = FlowEditorContext.Provider;
|
|
13699
|
-
function useFlowEditor() {
|
|
13700
|
-
const api = ReactExports.useContext(FlowEditorContext);
|
|
13701
|
-
if (api === null) {
|
|
13702
|
-
throw new Error("useFlowEditor() must be called inside <FlowEditor>.");
|
|
13703
|
-
}
|
|
13704
|
-
return api;
|
|
13705
|
-
}
|
|
13706
|
-
function useFlowEditorOptional() {
|
|
13707
|
-
return ReactExports.useContext(FlowEditorContext);
|
|
13708
|
-
}
|
|
13709
13805
|
var FlowEditor = ReactExports.forwardRef(function FlowEditor2(props, ref) {
|
|
13710
13806
|
return /* @__PURE__ */ jsxRuntime.jsx(ReactFlowProvider, { children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
13711
13807
|
"div",
|