@manny-est/node-red-flowpilot 0.5.2 → 0.6.0-beta.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 +53 -74
- package/USER-GUIDE.md +5 -1
- package/flowpilot-core.css +38 -10
- package/flowpilot.js +1007 -181
- package/lib/agent-contract.js +45 -0
- package/lib/build-core-script.js +1 -0
- package/lib/chat-data.js +106 -0
- package/lib/core/apply-review.js +34 -11
- package/lib/core/graph-truth.js +63 -0
- package/lib/core/history.js +10 -1
- package/lib/core/init.js +138 -5
- package/lib/core/main.js +664 -16
- package/lib/core/modes.js +882 -100
- package/lib/core/selection-context.js +27 -24
- package/lib/default-system-prompt.js +4 -3
- package/lib/document-system-prompt.js +3 -2
- package/lib/envelope.js +13 -7
- package/lib/generation-system-prompt.js +5 -4
- package/lib/modify-system-prompt.js +64 -12
- package/lib/persona-prompt.js +81 -54
- package/lib/prompt-fragments.js +13 -2
- package/lib/provider-anthropic.js +11 -8
- package/lib/provider-openai-compatible.js +37 -9
- package/lib/provider-shape-check.js +34 -0
- package/lib/storage.js +128 -21
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -2,84 +2,63 @@
|
|
|
2
2
|
|
|
3
3
|
All notable changes to FlowPilot are documented here.
|
|
4
4
|
|
|
5
|
-
## [0.
|
|
5
|
+
## [0.6.0-beta.1] - 2026-08-31
|
|
6
6
|
|
|
7
|
-
|
|
8
|
-
(WRITE-tool loop, per-call consent gates, `ask_user`) is developed
|
|
9
|
-
separately and is not included here — it ships under its own beta line
|
|
10
|
-
until it's ready to replace this one.
|
|
7
|
+
Prerelease — published to the `beta` npm tag only. `latest` stays on `0.5.2`.
|
|
11
8
|
|
|
12
9
|
### Added
|
|
13
|
-
- **
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
the
|
|
10
|
+
- **Agentic WRITE-tool loop for Modify** (behind the `enableAgentWrite`
|
|
11
|
+
setting, default off): step-by-step tool calls against the live flow
|
|
12
|
+
(`apply_step`, `remove_step`, `rename_node`, `group_nodes`), each
|
|
13
|
+
write-gated by a per-step consent prompt (Proceed / Skip this step) before
|
|
14
|
+
it touches the canvas. Multi-item requests are tracked and executed as
|
|
15
|
+
separate, individually-verified steps rather than one all-or-nothing
|
|
16
|
+
envelope; an injected mid-run failure (e.g. a referenced node no longer
|
|
17
|
+
exists) fails only that item, with the rest completing normally.
|
|
18
|
+
- **`ask_user` clarifying-question tool**: an agent-strategy turn can pause
|
|
19
|
+
mid-run to ask a single focused question (with optional quick-reply
|
|
20
|
+
buttons) instead of guessing, and resumes exactly where it left off once
|
|
21
|
+
answered.
|
|
22
|
+
- **Contract-exclusivity enforcement**: a server-side safety net
|
|
23
|
+
(`enforceAgentContract`) strips any classic-style mutation fields
|
|
24
|
+
(`changes`/`newNodes`/`newWires`/`removeNodes`/`newGroups`) that
|
|
25
|
+
accidentally appear on an agent-strategy turn with no tool calls, before
|
|
26
|
+
they ever reach the client — the two mutation paths (classic envelope vs.
|
|
27
|
+
agentic WRITE tools) stay mutually exclusive per turn.
|
|
28
|
+
- **Run identity and honest interruption**: agent-strategy runs now carry a
|
|
29
|
+
stable run/operation id so a duplicate tool-call delivery (a retry, or the
|
|
30
|
+
model repeating itself) is applied at most once; a run that's stopped or
|
|
31
|
+
hits its step/token ceiling reports an honest "interrupted after N steps"
|
|
32
|
+
instead of silently truncating.
|
|
33
|
+
|
|
34
|
+
### Security
|
|
35
|
+
- **API keys are now write-only over HTTP** (previously exposed on
|
|
36
|
+
`GET`/`POST /flowpilot/settings` — a fork-hygiene regression from the
|
|
37
|
+
0.5.1 stable line, now ported forward and closed for good). Every
|
|
38
|
+
provider's `apiKey` is masked to a sentinel or `""` in both responses;
|
|
39
|
+
the real key never leaves the server. `settings.json` and per-conversation
|
|
40
|
+
transcripts are now created with `0600` permissions.
|
|
41
|
+
- **Provider-confirmation gate (SSRF mitigation)**: no chat, generate,
|
|
42
|
+
modify, document, build, agent-step, or model-list request reaches a
|
|
43
|
+
configured provider's Base URL until that exact URL has passed a real
|
|
44
|
+
FlowPilot connection check (Pre-flight check / Test Provider). The check
|
|
45
|
+
itself is blind on failure — a non-provider target's response is never
|
|
46
|
+
reflected back to the client — so pointing a provider at an unintended
|
|
47
|
+
internal address yields nothing readable. Confirmation is tied to the
|
|
48
|
+
exact URL and clears automatically if the Base URL or API key changes.
|
|
49
|
+
See `dev-docs/decisions/ADR-007-Provider-Confirmation-Gate.md` for the
|
|
50
|
+
full design.
|
|
51
|
+
- **Audit-trail completeness**: an agent-strategy request whose very first
|
|
52
|
+
model turn is a tool call (rather than a later continuation) is now
|
|
53
|
+
always recorded to the audit log — previously this specific case left no
|
|
54
|
+
trace at all.
|
|
40
55
|
|
|
41
|
-
###
|
|
42
|
-
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
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
|
-
- Redaction round-trip poisoning, token-credential redaction gaps, and
|
|
69
|
-
several redaction echo/false-positive fixes across Modify and the build
|
|
70
|
-
loop's review step.
|
|
71
|
-
- Group data corruption from a stray `changes` patch touching a group's
|
|
72
|
-
membership array directly; mixed-membership group create/extend
|
|
73
|
-
corruption.
|
|
74
|
-
- Invalid port wiring (wiring to/from a port index that doesn't exist)
|
|
75
|
-
now guarded instead of silently applied.
|
|
76
|
-
- New-node insertion collision avoidance tuned for faster, more reliable
|
|
77
|
-
separation on dense flows.
|
|
78
|
-
- Several build-loop review false positives (metadata-field echoes,
|
|
79
|
-
debug/function/mqtt node misclassification, stale in-progress status
|
|
80
|
-
read as a real error).
|
|
81
|
-
- Partial id-validation no longer discards an entire valid Modify batch
|
|
82
|
-
over one bad node id.
|
|
56
|
+
### Internal
|
|
57
|
+
- Phase 10: strategy propagation, contract-exclusivity enforcement, agent
|
|
58
|
+
turn output caps, run identity/idempotency, and verification consolidation
|
|
59
|
+
across the classic and agentic Modify paths. Full history in
|
|
60
|
+
`dev-docs/current/Phase10-Build-Progress.md` and
|
|
61
|
+
`dev-docs/current/Phase10-Gate-Closeout-Final.md`.
|
|
83
62
|
|
|
84
63
|
## [0.5.1] - 2026-07-24
|
|
85
64
|
|
package/USER-GUIDE.md
CHANGED
|
@@ -134,7 +134,11 @@ OpenAI-compatible endpoint), LM Studio, etc.
|
|
|
134
134
|

|
|
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
|

|
|
140
144
|
|
package/flowpilot-core.css
CHANGED
|
@@ -249,7 +249,7 @@
|
|
|
249
249
|
padding: 4px 0;
|
|
250
250
|
}
|
|
251
251
|
|
|
252
|
-
.fp-typing span:not(.fp-typing-label) {
|
|
252
|
+
.fp-typing span:not(.fp-typing-label):not(.fp-typing-elapsed) {
|
|
253
253
|
width: 7px;
|
|
254
254
|
height: 7px;
|
|
255
255
|
border-radius: 50%;
|
|
@@ -258,8 +258,15 @@
|
|
|
258
258
|
animation: fp-bounce 1.2s infinite ease-in-out;
|
|
259
259
|
}
|
|
260
260
|
|
|
261
|
-
|
|
262
|
-
|
|
261
|
+
/* CLAUDE-033: matches the base rule's :not() clauses too, so specificity
|
|
262
|
+
(0,4,1) beats the base rule's (0,3,1) — otherwise the base rule's
|
|
263
|
+
"animation" SHORTHAND implicitly resets animation-delay back to 0s on
|
|
264
|
+
every dot regardless of source order, since shorthand properties reset
|
|
265
|
+
unspecified sub-values, and CSS resolves same-property conflicts by
|
|
266
|
+
specificity first. Without this, all three dots silently bounce in
|
|
267
|
+
perfect sync instead of staggered. */
|
|
268
|
+
.fp-typing span:not(.fp-typing-label):not(.fp-typing-elapsed):nth-child(2) { animation-delay: 0.18s; }
|
|
269
|
+
.fp-typing span:not(.fp-typing-label):not(.fp-typing-elapsed):nth-child(3) { animation-delay: 0.36s; }
|
|
263
270
|
|
|
264
271
|
.fp-typing-label {
|
|
265
272
|
font-size: 11px;
|
|
@@ -268,6 +275,12 @@
|
|
|
268
275
|
align-self: center;
|
|
269
276
|
}
|
|
270
277
|
|
|
278
|
+
.fp-typing-elapsed {
|
|
279
|
+
font-size: 11px;
|
|
280
|
+
color: var(--red-ui-secondary-text-color, #999);
|
|
281
|
+
align-self: center;
|
|
282
|
+
}
|
|
283
|
+
|
|
271
284
|
.fp-agent-stop {
|
|
272
285
|
margin-left: 8px;
|
|
273
286
|
align-self: center;
|
|
@@ -371,15 +384,11 @@
|
|
|
371
384
|
font-size: 16px;
|
|
372
385
|
}
|
|
373
386
|
|
|
374
|
-
/* Secondary/escape-hatch variant:
|
|
387
|
+
/* Secondary/escape-hatch variant: transparent background, muted text.
|
|
375
388
|
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.
|
|
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. */
|
|
389
|
+
without competing visually with the primary action above it. */
|
|
381
390
|
.fp-chip-card.fp-chip-card-alt {
|
|
382
|
-
background:
|
|
391
|
+
background: transparent;
|
|
383
392
|
border-color: #2a333c;
|
|
384
393
|
color: #8a96a3;
|
|
385
394
|
}
|
|
@@ -388,6 +397,14 @@
|
|
|
388
397
|
font-weight: 500;
|
|
389
398
|
}
|
|
390
399
|
.fp-chip-card.fp-chip-card-alt:hover {
|
|
400
|
+
/* CLAUDE-031: this variant's background stays transparent at rest by
|
|
401
|
+
design, so on Node-RED's LIGHT theme it inherits a white/near-white
|
|
402
|
+
surrounding background — the near-white hover text below then had
|
|
403
|
+
nothing dark to sit on and became unreadable. A solid dark fill on
|
|
404
|
+
hover (paired with the same green glow as the primary chip) fixes
|
|
405
|
+
contrast regardless of the surrounding theme, without touching the
|
|
406
|
+
transparent, theme-following look at rest. */
|
|
407
|
+
background: #141a21;
|
|
391
408
|
border-color: #46d39a;
|
|
392
409
|
box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.05), 0 0 0 1px #46d39a, 0 0 14px -2px #46d39a;
|
|
393
410
|
color: #dfe6ee;
|
|
@@ -722,6 +739,17 @@
|
|
|
722
739
|
.fp-todo-item-done { color: #1a7a1a; }
|
|
723
740
|
.fp-todo-item-failed { color: #b22222; }
|
|
724
741
|
|
|
742
|
+
/* P10-D2: honest-interruption notice appended inside a "todo" record whose
|
|
743
|
+
last run event isn't "done" (see rerenderTodoRecord, modes.js). */
|
|
744
|
+
.fp-todo-interrupted {
|
|
745
|
+
margin-top: 6px;
|
|
746
|
+
padding: 4px 8px;
|
|
747
|
+
border-radius: 4px;
|
|
748
|
+
font-size: 12px;
|
|
749
|
+
background: rgba(200, 140, 0, 0.10);
|
|
750
|
+
color: #8a5a00;
|
|
751
|
+
}
|
|
752
|
+
|
|
725
753
|
.fp-json-toolbar {
|
|
726
754
|
display: flex;
|
|
727
755
|
justify-content: flex-end;
|