@codemation/core-nodes 1.0.0 → 1.0.1

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/CHANGELOG.md CHANGED
@@ -1,5 +1,28 @@
1
1
  # @codemation/core-nodes
2
2
 
3
+ ## 1.0.1
4
+
5
+ ### Patch Changes
6
+
7
+ - [#95](https://github.com/MadeRelevant/codemation/pull/95) [`328c975`](https://github.com/MadeRelevant/codemation/commit/328c9759d45b711c177ea9a360ed4960ffdf5ffa) Thanks [@cblokland90](https://github.com/cblokland90)! - Workflow-canvas icon system redesign: LTR-oriented control-flow icons, pixel-perfect Split / Aggregate SVGs, and a single icon renderer shared by the canvas and the execution tree panel.
8
+
9
+ **Why**
10
+
11
+ The canvas reads left-to-right, but Lucide's `split`, `merge`, and `git-*` family are oriented vertically (top-to-bottom git-graph convention), so `If` and `Merge` nodes rendered 90° off from the flow direction. The execution-tree panel also ran a parallel icon-rendering path that only understood Lucide names — every time a plugin node set an icon as `builtin:<id>`, `si:<slug>`, or a URL, the tree panel silently fell back to a type-substring-guessed Lucide glyph (e.g. `"wait".includes("ai")` → the agent Bot icon). That duplication is gone.
12
+
13
+ **What changed**
14
+ - **Rotation suffix**: `NodeConfigBase.icon` now accepts an optional `@rot=<0|90|180|270>` tail modifier on any icon token (`lucide:`, `builtin:`, `si:`, or URL). Parsed by a strict tail regex so URLs with `@` (for example `http://user@host/icon.svg`) are unaffected, and non-orthogonal angles are rejected so glyphs stay pixel-crisp.
15
+ - **LTR control-flow icons**:
16
+ - `If`: `lucide:split@rot=90` — Y-fork with the single leg on the left and two arms fanning right.
17
+ - `Merge`: `lucide:merge@rot=90` — chevron pointing right, two arms merging from the left.
18
+ - **Pixel-perfect builtin SVGs** shipped under `packages/next-host/public/canvas-icons/builtin/`:
19
+ - `builtin:split-rows`: 1 source square on the left, tree trunk / spine, 3 output lines on the right.
20
+ - `builtin:aggregate-rows`: mirror — 3 input lines on the left converging through a spine into 1 summary square on the right.
21
+ - Stroke-based SVGs (matching Lucide stroke weight next to them on the canvas).
22
+ - **`@codemation/core-nodes` built-in node icon updates** that plug into the above: `If` (rotated split), `Merge` (rotated merge), `Split` (`builtin:split-rows`), `Aggregate` (`builtin:aggregate-rows`), `Wait` (`lucide:hourglass`), `MapData` (`lucide:square-pen`), `HttpRequest` (`lucide:globe`), `WebhookTrigger` (`lucide:webhook`), `NoOp` (`lucide:circle-dashed`).
23
+ - **One renderer, role-only fallback**: `WorkflowExecutionInspectorTreePanelContent` now renders `<WorkflowCanvasNodeIcon />` so `builtin:`, `si:`, URLs, and `@rot=…` resolve identically in the execution tree panel and on the canvas. `WorkflowNodeIconResolver.resolveFallback` shrank from 11 branches of type-substring guessing to 4 role mappings (`agent` / `nestedAgent` → `Bot`, `languageModel` → `Brain`, `tool` → `Wrench`, else → `Boxes`). Plugin nodes that forget to set an icon now get a generic `Boxes` — a clear visual signal rather than a silent substring mismatch.
24
+ - **New test file** `test/canvas/workflowCanvasNodeIcon.test.tsx` pins 12 behaviours across the rotation parser and the role-only fallback, including a regression case that the pre-fix `"wait".includes("ai")` mis-mapping is impossible now.
25
+
3
26
  ## 1.0.0
4
27
 
5
28
  ### Major Changes
package/dist/index.cjs CHANGED
@@ -4049,6 +4049,7 @@ var HttpRequest = class {
4049
4049
  kind = "node";
4050
4050
  type = HttpRequestNode;
4051
4051
  execution = { hint: "local" };
4052
+ icon = "lucide:globe";
4052
4053
  constructor(name, args = {}, retryPolicy = __codemation_core.RetryPolicy.defaultForHttp) {
4053
4054
  this.name = name;
4054
4055
  this.args = args;
@@ -4090,7 +4091,7 @@ var Aggregate = class {
4090
4091
  type = AggregateNode;
4091
4092
  execution = { hint: "local" };
4092
4093
  keepBinaries = true;
4093
- icon = "lucide:layers";
4094
+ icon = "builtin:aggregate-rows";
4094
4095
  constructor(name, aggregate, id) {
4095
4096
  this.name = name;
4096
4097
  this.aggregate = aggregate;
@@ -4185,7 +4186,7 @@ var If = class {
4185
4186
  kind = "node";
4186
4187
  type = IfNode;
4187
4188
  execution = { hint: "local" };
4188
- icon = "lucide:split";
4189
+ icon = "lucide:split@rot=90";
4189
4190
  declaredOutputPorts = ["true", "false"];
4190
4191
  constructor(name, predicate, id) {
4191
4192
  this.name = name;
@@ -4250,7 +4251,7 @@ var Split = class {
4250
4251
  * Mirrors {@link MapData}'s empty-output behavior.
4251
4252
  */
4252
4253
  continueWhenEmptyOutput = true;
4253
- icon = "lucide:ungroup";
4254
+ icon = "builtin:split-rows";
4254
4255
  constructor(name, getElements, id) {
4255
4256
  this.name = name;
4256
4257
  this.getElements = getElements;
@@ -4321,6 +4322,7 @@ var MapData = class {
4321
4322
  execution = { hint: "local" };
4322
4323
  /** Zero mapped items should still allow downstream nodes to run. */
4323
4324
  continueWhenEmptyOutput = true;
4325
+ icon = "lucide:square-pen";
4324
4326
  keepBinaries;
4325
4327
  constructor(name, map, options = {}) {
4326
4328
  this.name = name;
@@ -4390,7 +4392,7 @@ MergeNode = __decorate([(0, __codemation_core.node)({ packageName: "@codemation/
4390
4392
  var Merge = class {
4391
4393
  kind = "node";
4392
4394
  type = MergeNode;
4393
- icon = "lucide:git-merge";
4395
+ icon = "lucide:merge@rot=90";
4394
4396
  constructor(name, cfg = { mode: "passThrough" }, id) {
4395
4397
  this.name = name;
4396
4398
  this.cfg = cfg;
@@ -4415,6 +4417,7 @@ var NoOp = class {
4415
4417
  kind = "node";
4416
4418
  type = NoOpNode;
4417
4419
  execution = { hint: "local" };
4420
+ icon = "lucide:circle-dashed";
4418
4421
  constructor(name = "NoOp", id) {
4419
4422
  this.name = name;
4420
4423
  this.id = id;
@@ -4520,6 +4523,7 @@ var Wait = class {
4520
4523
  execution = { hint: "local" };
4521
4524
  /** Pass-through empty batches should still advance to downstream nodes. */
4522
4525
  continueWhenEmptyOutput = true;
4526
+ icon = "lucide:hourglass";
4523
4527
  constructor(name, milliseconds, id) {
4524
4528
  this.name = name;
4525
4529
  this.milliseconds = milliseconds;
@@ -4570,7 +4574,7 @@ WebhookTriggerNode = __decorate([(0, __codemation_core.node)({ packageName: "@co
4570
4574
  var WebhookTrigger = class WebhookTrigger {
4571
4575
  kind = "trigger";
4572
4576
  type = WebhookTriggerNode;
4573
- icon = "lucide:globe";
4577
+ icon = "lucide:webhook";
4574
4578
  constructor(name, args, handler = WebhookTrigger.defaultHandler, id) {
4575
4579
  this.name = name;
4576
4580
  this.args = args;