@manny-est/node-red-flowpilot 0.5.2 → 0.6.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/CHANGELOG.md CHANGED
@@ -2,6 +2,91 @@
2
2
 
3
3
  All notable changes to FlowPilot are documented here.
4
4
 
5
+ ## [0.6.0] - 2026-09-01
6
+
7
+ Promoted from `0.6.0-beta.1` to the stable `latest` npm tag.
8
+
9
+ ### Added
10
+ - **Agentic WRITE-tool loop for Modify and Generate** (behind the
11
+ `enableAgentWrite` setting, default off): step-by-step tool calls
12
+ against the live flow (`apply_step`, `remove_step`, `rename_node`,
13
+ `group_nodes`), each write-gated by a per-step consent prompt (Proceed
14
+ / Skip this step) before it touches the canvas. Multi-item requests are
15
+ tracked and executed as separate, individually-verified steps rather
16
+ than one all-or-nothing envelope; an injected mid-run failure (e.g. a
17
+ referenced node no longer exists) fails only that item, with the rest
18
+ completing normally. Generate joined the same agentic runtime Modify
19
+ already used, closing the last place a mutation could land through the
20
+ older, less-verified classic JSON path while write-tool mode is on.
21
+ - **`ask_user` clarifying-question tool**: an agent-strategy turn can pause
22
+ mid-run to ask a single focused question (with optional quick-reply
23
+ buttons) instead of guessing, and resumes exactly where it left off once
24
+ answered.
25
+ - **Deterministic run summaries**: when a Modify or Generate run actually
26
+ applied WRITE-tool steps, the per-item outcome you see (✓ applied and
27
+ verified / ✗ failed, with why) now comes straight from what the tools
28
+ actually reported — not from the model's own retelling. The model's own
29
+ wrap-up explanation still shows, underneath, clearly secondary — useful
30
+ context, never the thing you have to trust to know what really
31
+ happened.
32
+ - **Contract-exclusivity enforcement**: a server-side safety net
33
+ (`enforceAgentContract`) strips any classic-style mutation fields
34
+ (`changes`/`newNodes`/`newWires`/`removeNodes`/`newGroups`/`flow`) that
35
+ accidentally appear on an agent-strategy turn with no tool calls, before
36
+ they ever reach the client — the two mutation paths (classic envelope vs.
37
+ agentic WRITE tools) stay mutually exclusive per turn, for every mode
38
+ that can run agentically.
39
+ - **Run identity and honest interruption**: agent-strategy runs now carry a
40
+ stable run/operation id so a duplicate tool-call delivery (a retry, or the
41
+ model repeating itself) is applied at most once; a run that's stopped or
42
+ hits its step/token ceiling reports an honest "interrupted after N steps"
43
+ instead of silently truncating. That step-by-step record is also now
44
+ visible to the server (previously client-side only), the foundation for
45
+ the deterministic run summaries above.
46
+
47
+ ### Fixed
48
+ - **The FlowPilot sidebar's entire client script was loading twice on
49
+ every single editor page load** — a packaging issue present since the
50
+ plugin's first release, only now found and fixed. In practice this
51
+ meant a page reload silently lost the current conversation (a second,
52
+ redundant script execution would stomp the first one's restored state)
53
+ and, more subtly, any other one-time setup code in the client ran
54
+ twice per load. Reloading the Node-RED editor now correctly picks the
55
+ conversation back up where you left off.
56
+ - Anthropic (Claude) responses now get the exact same deterministic
57
+ run-summary and contract-exclusivity treatment as every other
58
+ provider — verified directly against Claude Sonnet, not just the
59
+ OpenAI-compatible path.
60
+
61
+ ### Security
62
+ - **API keys are now write-only over HTTP** (previously exposed on
63
+ `GET`/`POST /flowpilot/settings` — a fork-hygiene regression from the
64
+ 0.5.1 stable line, now ported forward and closed for good). Every
65
+ provider's `apiKey` is masked to a sentinel or `""` in both responses;
66
+ the real key never leaves the server. `settings.json` and per-conversation
67
+ transcripts are now created with `0600` permissions.
68
+ - **Provider-confirmation gate (SSRF mitigation)**: no chat, generate,
69
+ modify, document, build, agent-step, or model-list request reaches a
70
+ configured provider's Base URL until that exact URL has passed a real
71
+ FlowPilot connection check (Pre-flight check / Test Provider). The check
72
+ itself is blind on failure — a non-provider target's response is never
73
+ reflected back to the client — so pointing a provider at an unintended
74
+ internal address yields nothing readable. Confirmation is tied to the
75
+ exact URL and clears automatically if the Base URL or API key changes.
76
+ See `dev-docs/decisions/ADR-007-Provider-Confirmation-Gate.md` for the
77
+ full design.
78
+ - **Audit-trail completeness**: an agent-strategy request whose very first
79
+ model turn is a tool call (rather than a later continuation) is now
80
+ always recorded to the audit log — previously this specific case left no
81
+ trace at all.
82
+
83
+ ### Internal
84
+ - Phase 10: strategy propagation, contract-exclusivity enforcement, agent
85
+ turn output caps, run identity/idempotency, and verification consolidation
86
+ across the classic and agentic Modify paths. Full history in
87
+ `dev-docs/current/Phase10-Build-Progress.md` and
88
+ `dev-docs/current/Phase10-Gate-Closeout-Final.md`.
89
+
5
90
  ## [0.5.2] - 2026-08-04
6
91
 
7
92
  This release continues the 0.5.x line. Phase 10's agentic Modify redesign
@@ -39,32 +124,6 @@ until it's ready to replace this one.
39
124
  the canvas.
40
125
 
41
126
  ### Fixed
42
- - **Build loop — status-only evidence false negatives**: a live, working
43
- node could be declared "disconnected"/broken off a single coarse
44
- node-status read, with no way to confirm otherwise. Evidence is now
45
- tagged by source (`debug` vs. `status`); when only status-line evidence
46
- is available and it doesn't clearly prove success or failure, the build
47
- loop asks a direct yes/no confirmation instead of guessing.
48
- - **Modify's wire verification** read a node's stale `.wires` array
49
- instead of the live link registry — a wire added earlier in the same
50
- editing session could be reported as "did not land" even though it was
51
- actually there. Verification now reads from `RED.nodes.eachLink`.
52
- - **Phantom output port on newly-created nodes**: a model-supplied
53
- `wires` array that disagreed with a node type's real port count (e.g.
54
- a stray empty port on a 0-output type like `http response`) rendered a
55
- visible port anchor that shouldn't exist. The array length is now
56
- reconciled against the node's real output count on insertion.
57
- - **New-node layout scatter**: the collision-avoidance grid still placed
58
- two nodes at the same vertical level; switched to a single-column
59
- layout (one node per row, wrap to a new column after 5 rows).
60
- - **`newWires` endpoint aliases**: a model response using `fromId`/`toId`
61
- instead of `from`/`to` on a `newWires` entry is now repaired
62
- automatically instead of both endpoints silently appearing missing.
63
- - **`.fp-chip-card-alt` background**: the secondary "Just add to canvas"
64
- chip relied on its surrounding message bubble being dark to read as
65
- part of the same chip-card family as the primary action above it —
66
- bubbles follow Node-RED's light editor theme by default, so it rendered
67
- as a plain white box instead.
68
127
  - Redaction round-trip poisoning, token-credential redaction gaps, and
69
128
  several redaction echo/false-positive fixes across Modify and the build
70
129
  loop's review step.
package/README.md CHANGED
@@ -26,7 +26,9 @@ installation, the sidebar UI, and a chapter on every feature.
26
26
  - **User-initiated only** — FlowPilot never changes your flow without an
27
27
  explicit request.
28
28
  - **Complete visibility** — every proposed change is shown as a diff/review
29
- before anything is applied.
29
+ before it's applied; in the opt-in agentic mode (below), each step is
30
+ gated by its own Proceed/Skip prompt instead, so you're still in control
31
+ of what actually lands on the canvas.
30
32
  - **Undo first** — every change goes through Node-RED's native undo
31
33
  (Ctrl+Z), including multi-part changes (insertions + rewires + new nodes)
32
34
  as a single step.
@@ -73,6 +75,13 @@ See the [User Guide](USER-GUIDE.md#privacy-and-safety) for the full details.
73
75
  Document, with a clear notice when older messages are truncated.
74
76
  - **Clarifying questions** — if an instruction is too vague to act on
75
77
  safely, FlowPilot asks ONE question instead of guessing.
78
+ - **Agentic mode (opt-in, Settings)** — Generate and Modify can work
79
+ step by step instead of one big review-then-apply diff: each step
80
+ (insert, rewire, rename, remove, group) lands on the canvas as it's
81
+ proposed, gated by its own Proceed/Skip consent prompt for anything
82
+ beyond the safest node types. The summary you see when a run finishes
83
+ is built from what the tools actually reported happened, not just the
84
+ model's own retelling — if a step failed or was skipped, it says so.
76
85
  - **Streaming replies** — optional SSE streaming for chat responses.
77
86
  - **`/build`** — describe a goal and FlowPilot plans it, proposes a first
78
87
  flow, then walks an interactive build → deploy → debug → review → fix loop
package/USER-GUIDE.md CHANGED
@@ -134,7 +134,11 @@ OpenAI-compatible endpoint), LM Studio, etc.
134
134
  ![Provider settings: Base URL, API key, model, and temperature fields](https://github.com/manny-est/flowpilot/releases/download/v0.2.1/sidebar-settings-providers.png)
135
135
 
136
136
  4. Click **Pre-flight check**. This saves your settings and sends a small
137
- test request. A reply in the chat panel means you're connected.
137
+ test request. A reply in the chat panel means you're connected. **This
138
+ step is required** — a provider must pass Pre-flight check before Chat,
139
+ Generate, Modify, Document, or Build will send it anything; a provider
140
+ you just added or just changed the Base URL/API key on starts
141
+ unconfirmed until this check passes again.
138
142
 
139
143
  ![A successful Pre-flight check reply in Chat](https://github.com/manny-est/flowpilot/releases/download/v0.2.1/preflight-success.png)
140
144
 
@@ -108,6 +108,21 @@
108
108
  border-color: rgba(80, 130, 255, 0.35);
109
109
  }
110
110
 
111
+ /* Subordinate to the deterministic run summary above it (C1): same shape,
112
+ visibly de-emphasized so a model's free-text recap can't be mistaken for
113
+ the authoritative per-item outcome. */
114
+ .fp-secondary {
115
+ padding: 8px 14px;
116
+ background: transparent;
117
+ border-style: dashed;
118
+ font-size: 12px;
119
+ color: var(--red-ui-secondary-text-color, #888);
120
+ }
121
+
122
+ .fp-secondary .fp-label {
123
+ opacity: 0.7;
124
+ }
125
+
111
126
  /* Reasoning / thinking block — shown for models that emit reasoning_content
112
127
  (e.g. Nemotron, DeepSeek-R1). Sits above the assistant response bubble.
113
128
  Expanded while the model thinks; collapses automatically when content starts. */
@@ -249,7 +264,7 @@
249
264
  padding: 4px 0;
250
265
  }
251
266
 
252
- .fp-typing span:not(.fp-typing-label) {
267
+ .fp-typing span:not(.fp-typing-label):not(.fp-typing-elapsed) {
253
268
  width: 7px;
254
269
  height: 7px;
255
270
  border-radius: 50%;
@@ -258,8 +273,15 @@
258
273
  animation: fp-bounce 1.2s infinite ease-in-out;
259
274
  }
260
275
 
261
- .fp-typing span:nth-child(2) { animation-delay: 0.18s; }
262
- .fp-typing span:nth-child(3) { animation-delay: 0.36s; }
276
+ /* CLAUDE-033: matches the base rule's :not() clauses too, so specificity
277
+ (0,4,1) beats the base rule's (0,3,1) otherwise the base rule's
278
+ "animation" SHORTHAND implicitly resets animation-delay back to 0s on
279
+ every dot regardless of source order, since shorthand properties reset
280
+ unspecified sub-values, and CSS resolves same-property conflicts by
281
+ specificity first. Without this, all three dots silently bounce in
282
+ perfect sync instead of staggered. */
283
+ .fp-typing span:not(.fp-typing-label):not(.fp-typing-elapsed):nth-child(2) { animation-delay: 0.18s; }
284
+ .fp-typing span:not(.fp-typing-label):not(.fp-typing-elapsed):nth-child(3) { animation-delay: 0.36s; }
263
285
 
264
286
  .fp-typing-label {
265
287
  font-size: 11px;
@@ -268,6 +290,12 @@
268
290
  align-self: center;
269
291
  }
270
292
 
293
+ .fp-typing-elapsed {
294
+ font-size: 11px;
295
+ color: var(--red-ui-secondary-text-color, #999);
296
+ align-self: center;
297
+ }
298
+
271
299
  .fp-agent-stop {
272
300
  margin-left: 8px;
273
301
  align-self: center;
@@ -371,15 +399,11 @@
371
399
  font-size: 16px;
372
400
  }
373
401
 
374
- /* Secondary/escape-hatch variant: muted dark background, muted text.
402
+ /* Secondary/escape-hatch variant: transparent background, muted text.
375
403
  Same hover glow as fp-chip-card so it reads as part of the same family
376
- without competing visually with the primary action above it. Explicit
377
- background, not transparent — .fp-message's surrounding bubble follows
378
- Node-RED's light editor theme variable by default, so "transparent"
379
- showed through as plain white instead of blending into a dark parent
380
- that doesn't actually exist. */
404
+ without competing visually with the primary action above it. */
381
405
  .fp-chip-card.fp-chip-card-alt {
382
- background: #171e25;
406
+ background: transparent;
383
407
  border-color: #2a333c;
384
408
  color: #8a96a3;
385
409
  }
@@ -388,6 +412,14 @@
388
412
  font-weight: 500;
389
413
  }
390
414
  .fp-chip-card.fp-chip-card-alt:hover {
415
+ /* CLAUDE-031: this variant's background stays transparent at rest by
416
+ design, so on Node-RED's LIGHT theme it inherits a white/near-white
417
+ surrounding background — the near-white hover text below then had
418
+ nothing dark to sit on and became unreadable. A solid dark fill on
419
+ hover (paired with the same green glow as the primary chip) fixes
420
+ contrast regardless of the surrounding theme, without touching the
421
+ transparent, theme-following look at rest. */
422
+ background: #141a21;
391
423
  border-color: #46d39a;
392
424
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.05), 0 0 0 1px #46d39a, 0 0 14px -2px #46d39a;
393
425
  color: #dfe6ee;
@@ -722,6 +754,17 @@
722
754
  .fp-todo-item-done { color: #1a7a1a; }
723
755
  .fp-todo-item-failed { color: #b22222; }
724
756
 
757
+ /* P10-D2: honest-interruption notice appended inside a "todo" record whose
758
+ last run event isn't "done" (see rerenderTodoRecord, modes.js). */
759
+ .fp-todo-interrupted {
760
+ margin-top: 6px;
761
+ padding: 4px 8px;
762
+ border-radius: 4px;
763
+ font-size: 12px;
764
+ background: rgba(200, 140, 0, 0.10);
765
+ color: #8a5a00;
766
+ }
767
+
725
768
  .fp-json-toolbar {
726
769
  display: flex;
727
770
  justify-content: flex-end;
@@ -0,0 +1,15 @@
1
+ // Node-RED's "nodes" registration entry needs its own .js file, separate
2
+ // from flowpilot.js — Node-RED derives an editor-template path for every
3
+ // declared "nodes" entry by replacing the .js extension with .html
4
+ // (@node-red/registry/lib/loader.js loadNodeConfig: `file.replace(/\.c?js$/,".html")`),
5
+ // with NO awareness of the "plugins" entry that already explicitly declares
6
+ // flowpilot.html. If this entry pointed at flowpilot.js directly, Node-RED
7
+ // would derive "flowpilot.html" as this node's own template, find the real
8
+ // file (same basename), and load its content a SECOND time — the plugin's
9
+ // entire client bundle (flowpilot/core.js and its inline init script)
10
+ // ends up in the editor page twice, executing every module-level
11
+ // side effect (including sessionStorage init) twice per page load.
12
+ // This shim's own basename ("flowpilot-node-entry") has no matching .html,
13
+ // so Node-RED's template lookup misses (ENOENT) and loads no content for
14
+ // it — exactly what a route-registration-only, no-editor-UI node needs.
15
+ module.exports = require("./flowpilot.js");