@manny-est/node-red-flowpilot 0.4.1 → 0.5.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 +42 -0
- package/PROJECT-OVERVIEW.md +7 -7
- package/README.md +14 -8
- package/USER-GUIDE.md +27 -10
- package/flowpilot-core.css +103 -0
- package/flowpilot.js +123 -146
- package/lib/build-core-script.js +44 -0
- package/lib/build-system-prompt.js +6 -0
- package/lib/core/apply-review.js +1926 -0
- package/lib/core/history.js +93 -0
- package/lib/core/init.js +1435 -0
- package/lib/core/main.js +1777 -0
- package/lib/core/markdown.js +165 -0
- package/lib/core/modes.js +1690 -0
- package/lib/core/redaction.js +165 -0
- package/lib/core/selection-context.js +211 -0
- package/lib/envelope.js +136 -0
- package/lib/modify-system-prompt.js +3 -1
- package/lib/provider-openai-compatible.js +112 -15
- package/lib/storage.js +4 -0
- package/package.json +2 -3
- package/flowpilot-core.js +0 -6427
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,48 @@
|
|
|
2
2
|
|
|
3
3
|
All notable changes to FlowPilot are documented here.
|
|
4
4
|
|
|
5
|
+
## [0.5.1] - 2026-07-24
|
|
6
|
+
|
|
7
|
+
### Added
|
|
8
|
+
- **`/refresh` command**: re-renders the entire message panel from an in-memory record store without clearing conversation history. Restores interactive Apply buttons and review panels that may have become stale after a long session or a pop-out sync. Type `/refresh` at any time.
|
|
9
|
+
- **Reasoning model support**: FlowPilot detects reasoning models (Nemotron, DeepSeek, QwQ, and any model returning `reasoning_content` or `<think>` blocks) at pre-flight and handles them correctly throughout. Streaming: a live collapsing "Thinking…" block shows reasoning tokens as they arrive, then auto-collapses when the real response begins. Non-streaming (agent loop): a pre-collapsed thinking block renders alongside the final response. Both the SGLang/Nemotron (`delta.reasoning_content`) and llama.cpp/LocalAI (`<think>…</think>` in `delta.content`) formats are supported. Token count shown on collapse.
|
|
10
|
+
- **Auto-preflight on model change**: changing the model field and sending a message now triggers a silent capability probe before the request goes out — no need to click "Test Provider" after every model switch. A notice appears in the chat thread confirming the probe result (model name, tool support, reasoning flag). Settings are saved automatically as part of the probe so the backend uses the new model. The provider status line also updates live as you type the model name.
|
|
11
|
+
|
|
12
|
+
### Fixed
|
|
13
|
+
- **Pre-flight `probedModel` not reaching frontend**: after a `/test` run, `probedModel` was saved to disk but never mirrored into the in-memory provider profile, so the auto-probe condition (`probedModel !== currentModel`) could never fire after a page reload. The `/test` response now includes `probedModel` in the `capability` object and `handleSendResult` mirrors it into `currentSettings.providers`.
|
|
14
|
+
- **Reasoning content scrolling**: the live thinking block now scrolls to bottom on each streaming delta so long reasoning chains stay visible as they arrive.
|
|
15
|
+
|
|
16
|
+
### Internal
|
|
17
|
+
- Phase 10 Workstream 0A: shadow record store added across `main.js`, `apply-review.js`, `modes.js`, `init.js` — addMessage/addModifyReview/addGeneratedReview/renderActionChip/renderClarifyingQuestion/renderLoopCheckpoint/renderLoopStepper all create typed records; rerenderRecord dispatches each kind on refresh.
|
|
18
|
+
- Phase 10 Workstream 0B: DOM elements now carry `data-fp-record-id` (record id) instead of inline JSON payloads in `data-fp-apply-*` attributes. Four separate pop-out bind functions consolidated into a single `bindReviewApplyButtons`; four separate parent postMessage handlers replaced by a unified `applyByRecordId` handler that dispatches on the record's subkind.
|
|
19
|
+
|
|
20
|
+
## [0.5.0] - 2026-07-06
|
|
21
|
+
|
|
22
|
+
### Added
|
|
23
|
+
- **Slash autocomplete**: type `/` in the compose box and a panel shows all available commands with descriptions. Arrow keys, Tab, and Enter navigate; Escape dismisses.
|
|
24
|
+
- **Mode-suggestion chips**: FlowPilot detects when you describe a Generate, Modify, or Build task while in a different mode and offers a one-click chip to switch — no need to type the slash command manually. A chip also surfaces after a Generate response if the flow looks like it needs a follow-up Build loop.
|
|
25
|
+
- **Build loop — hold-at-next-step pacing**: a new Settings → Behavior toggle pauses the loop at each waypoint for review instead of auto-advancing. Useful for carefully inspecting each iteration.
|
|
26
|
+
- **Build loop — checkpoint questions**: the loop can now ask a focused clarifying question at any waypoint (e.g. "the debug output shows X — did you mean to test Y?") with prefilled quick-reply options, the same mechanism Modify uses. The loop only continues once you answer.
|
|
27
|
+
- **Build loop — context-aware start**: `/build` now reads your current selection as the starting context (same as `/modify`), letting you target an existing sub-flow to extend or fix rather than always building from scratch.
|
|
28
|
+
- **Build loop — done confirmation**: a "Done" confirmation step with an explicit success/fail verdict now closes the loop instead of silently stopping.
|
|
29
|
+
- **Pop-out — debug log**: the debug log panel is now fully mirrored in the pop-out window, including the "Clear debug" button and the "Attach N to context" indicator.
|
|
30
|
+
- **Pop-out — Recall and flight log**: the Recall panel and flight-log history are now accessible from the pop-out; opening a past conversation or recalling a message works the same as in the main window.
|
|
31
|
+
- **Pop-out — prompt resize handle**: the compose box in the pop-out can now be resized vertically, matching the main window.
|
|
32
|
+
|
|
33
|
+
### Fixed
|
|
34
|
+
- **Partial id-validation** (`finalizeModifyResult`): a Modify response containing a mix of valid patches and one bad node id no longer rejects the whole response — valid patches are applied and the bad ones are silently dropped. Previously a single unrecognized id caused every change in the batch to be discarded.
|
|
35
|
+
- **Redaction round-trip poisoning** (issue #7): when a Modify request targets a field that FlowPilot redacted (e.g. an HTTP Authorization header), the model's response — echoing back the `[redacted: ...]` placeholder — previously produced a silent empty diff. Now the diff step recognises placeholder values, skips those fields, and if ALL proposed changes were redacted-field-only, shows an explicit warning explaining the limitation and instructing the user to edit that field directly in the node editor.
|
|
36
|
+
- **Token credential redaction**: `Authorization: Token <value>` headers (used by Django REST Framework and similar APIs) were not caught by the existing bearer-token pattern and could be sent to the model in plain text. The `Token <credential>` form is now recognised as a separate pattern.
|
|
37
|
+
- **Recursive sentinel check**: `isSanitizeSentinel` now walks into nested arrays and objects, so a placeholder buried inside a list property (e.g. `rules[0].v`) is correctly detected and skipped instead of producing a spurious empty diff.
|
|
38
|
+
- **Group data corruption**: a plain `changes` patch could reach the `nodes` membership array of a group container (since context exposes it as a plain field), overwriting the live group membership with a stringified copy. The `nodes` array is now in `DIFF_SKIP` so Modify patches never touch it directly.
|
|
39
|
+
- **Group create/extend on mixed-membership selections**: creating or extending a group when the selection contained nodes from more than one existing group (or some grouped and some ungrouped) could silently fail or corrupt membership. The membership reconciliation step now handles the mixed case correctly.
|
|
40
|
+
- **Invalid port wiring**: FlowPilot now guards against wiring to or from a port index that doesn't exist on a node (e.g. connecting output 3 of a node that only has 2 outputs) — the bad wire is skipped with a warning instead of being applied and then causing a Node-RED canvas error.
|
|
41
|
+
- **Pop-out — settings auth failure**: opening Settings from the pop-out could fail with a 404 or 401 in certain auth configurations because the settings request was issued from the pop-out's nested route rather than through the main window. All settings reads and writes are now relayed through the parent window.
|
|
42
|
+
- **Pop-out — recall and flight-log relay**: recall and flight-log API calls are now relayed through the parent window so they resolve correctly from the pop-out.
|
|
43
|
+
|
|
44
|
+
### Internal
|
|
45
|
+
- Phase 9 refactor complete: `flowpilot-core.js` is now assembled at runtime from focused fragments under `lib/core/` (redaction, history, markdown, selection-context, apply-review, modes, main, init). The assembled script is functionally identical to the old single file; the split is purely for maintainability.
|
|
46
|
+
|
|
5
47
|
## [0.4.1] - 2026-06-29
|
|
6
48
|
|
|
7
49
|
### Fixed
|
package/PROJECT-OVERVIEW.md
CHANGED
|
@@ -115,13 +115,13 @@ including every step of the `/build` loop and every group mutation.
|
|
|
115
115
|
|
|
116
116
|
- **`flowpilot.html`** — the editor-side plugin entry point: registers the
|
|
117
117
|
sidebar panel and loads the shared client module below.
|
|
118
|
-
- **`
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
page (`lib/popout/view.html`)
|
|
124
|
-
state to/from the main editor window over `postMessage`.
|
|
118
|
+
- **`lib/core/*.js`** — the shared client logic, split into focused fragments
|
|
119
|
+
(redaction, history, markdown, selection-context, apply-review, modes, main,
|
|
120
|
+
init) and assembled at request time by `lib/build-core-script.js` into one
|
|
121
|
+
complete IIFE served at `/flowpilot/core.js`. Used by both the sidebar and
|
|
122
|
+
the pop-out window so they stay in sync by construction. The pop-out's
|
|
123
|
+
minimal page (`lib/popout/view.html`) loads this same assembled module and
|
|
124
|
+
relays state to/from the main editor window over `postMessage`.
|
|
125
125
|
- **`flowpilot.js`** — the Node-RED runtime plugin: HTTP routes
|
|
126
126
|
(`/flowpilot/*`), provider calls, response parsing/validation, and audit
|
|
127
127
|
logging.
|
package/README.md
CHANGED
|
@@ -93,26 +93,32 @@ See the [User Guide](USER-GUIDE.md#privacy-and-safety) for the full details.
|
|
|
93
93
|
|
|
94
94
|
Node-RED 4.x and 5.x, tested. Node.js 16+.
|
|
95
95
|
|
|
96
|
-
## Install
|
|
96
|
+
## Install
|
|
97
97
|
|
|
98
|
-
|
|
98
|
+
In the Node-RED editor: **Menu → Manage palette → Install**, search for
|
|
99
|
+
`@manny-est/node-red-flowpilot`, and click **Install**.
|
|
100
|
+
|
|
101
|
+
Or, from your Node-RED user directory:
|
|
99
102
|
|
|
100
103
|
```bash
|
|
101
104
|
cd ~/.node-red
|
|
102
|
-
npm install /
|
|
105
|
+
npm install @manny-est/node-red-flowpilot
|
|
103
106
|
node-red
|
|
104
107
|
```
|
|
105
108
|
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
+
Restart Node-RED (or the container) after installing or updating — FlowPilot's
|
|
110
|
+
editor UI is cached server-side, so a browser refresh alone is not enough.
|
|
111
|
+
|
|
112
|
+
For a Docker/container setup, install into the mounted Node-RED user directory.
|
|
113
|
+
If your user directory is `/data` (or `/workspaces/nodered`, etc.), this folder
|
|
114
|
+
should exist:
|
|
109
115
|
|
|
110
116
|
```text
|
|
111
117
|
<node-red-userDir>/node_modules/@manny-est/node-red-flowpilot
|
|
112
118
|
```
|
|
113
119
|
|
|
114
|
-
Restart the Node-RED container/process after
|
|
115
|
-
|
|
120
|
+
Restart the Node-RED container/process after updating the package files
|
|
121
|
+
directly — the plugin server caches assembled scripts in memory.
|
|
116
122
|
|
|
117
123
|
FlowPilot stores its own settings and logs separately from the plugin code,
|
|
118
124
|
under `<node-red-userDir>/flowpilot/`:
|
package/USER-GUIDE.md
CHANGED
|
@@ -212,14 +212,23 @@ and apply like any other change.
|
|
|
212
212
|
### Build (the agentic loop)
|
|
213
213
|
|
|
214
214
|
Describe a goal (e.g. "fetch the weather every hour and log it to a file")
|
|
215
|
-
and arm **Build**, or type `/build <goal>` directly.
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
215
|
+
and arm **Build**, or type `/build <goal>` directly. If you have nodes
|
|
216
|
+
selected, FlowPilot uses them as the starting context (like Modify) — useful
|
|
217
|
+
for targeting an existing sub-flow to extend or fix.
|
|
218
|
+
|
|
219
|
+
FlowPilot plans the work, proposes a first flow, and once you apply and
|
|
220
|
+
deploy it, walks an interactive loop: attach the resulting Debug output,
|
|
221
|
+
FlowPilot reviews it against the goal, and either confirms it's working
|
|
222
|
+
(with a Done confirmation showing the debug output that proved success) or
|
|
223
|
+
proposes a fix — repeating until it works or a configurable attempt limit is
|
|
224
|
+
reached (**Settings → Behavior → Build loop iteration cap**). At any waypoint
|
|
225
|
+
FlowPilot may ask a focused clarifying question with quick-reply buttons
|
|
226
|
+
before continuing. Every proposal and fix still goes through the same
|
|
227
|
+
review-then-apply flow as Modify — FlowPilot never deploys for you.
|
|
228
|
+
|
|
229
|
+
**Hold at next step** (**Settings → Behavior**): when enabled, the loop pauses
|
|
230
|
+
at each waypoint for you to review before auto-advancing — useful for
|
|
231
|
+
careful, step-by-step inspection of each iteration.
|
|
223
232
|
|
|
224
233
|
### Document
|
|
225
234
|
|
|
@@ -263,13 +272,18 @@ them from there or by clicking **Clear chat**.
|
|
|
263
272
|
|
|
264
273
|

|
|
265
274
|
|
|
266
|
-
### Action chips
|
|
275
|
+
### Action chips and mode suggestions
|
|
267
276
|
|
|
268
277
|
When FlowPilot's reply describes a change you could make, it may offer an
|
|
269
278
|
action chip — a one-click button that switches to the suggested mode
|
|
270
279
|
(Generate/Modify/Document/Chat) with the request pre-filled. Nothing is sent
|
|
271
280
|
until you review and hit Send yourself.
|
|
272
281
|
|
|
282
|
+
FlowPilot also watches what you type: if your prompt reads like a Generate,
|
|
283
|
+
Modify, or Build task but a different mode is armed, it surfaces a suggestion
|
|
284
|
+
chip below the reply so you can switch with one click instead of typing the
|
|
285
|
+
slash command manually.
|
|
286
|
+
|
|
273
287
|

|
|
274
288
|
|
|
275
289
|

|
|
@@ -303,7 +317,9 @@ Behavior → Stream chat replies**.
|
|
|
303
317
|
|
|
304
318
|
### Slash commands
|
|
305
319
|
|
|
306
|
-
Type
|
|
320
|
+
Type `/` in the prompt box to see a floating panel listing all available
|
|
321
|
+
commands with descriptions. Arrow keys or Tab to highlight, Enter or Tab to
|
|
322
|
+
complete, Escape to dismiss.
|
|
307
323
|
|
|
308
324
|
- `/help` — show the full command/feature briefing
|
|
309
325
|
- `/generate`, `/document`, `/modify`, `/build` — arm that Execute mode
|
|
@@ -312,6 +328,7 @@ Type these directly into the prompt box:
|
|
|
312
328
|
- `/history` — open the Flight log
|
|
313
329
|
- `/settings` — open Settings
|
|
314
330
|
- `/demo` — load a sample Generate request into the prompt box
|
|
331
|
+
- `/feedback` — links to the repo and issue tracker
|
|
315
332
|
- `/compact` / `/expand` — hide/restore labels on the selected node(s),
|
|
316
333
|
instant and deterministic, no AI round-trip
|
|
317
334
|
- `/disable` / `/enable` — disable/re-enable the selected node(s) (skipped on
|
package/flowpilot-core.css
CHANGED
|
@@ -103,6 +103,65 @@
|
|
|
103
103
|
border-color: rgba(80, 130, 255, 0.35);
|
|
104
104
|
}
|
|
105
105
|
|
|
106
|
+
/* Reasoning / thinking block — shown for models that emit reasoning_content
|
|
107
|
+
(e.g. Nemotron, DeepSeek-R1). Sits above the assistant response bubble.
|
|
108
|
+
Expanded while the model thinks; collapses automatically when content starts. */
|
|
109
|
+
.fp-thinking {
|
|
110
|
+
margin-bottom: 8px;
|
|
111
|
+
border-radius: 8px;
|
|
112
|
+
border: 1px solid rgba(120, 100, 220, 0.25);
|
|
113
|
+
background: rgba(100, 80, 200, 0.05);
|
|
114
|
+
overflow: hidden;
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
.fp-thinking summary {
|
|
118
|
+
display: flex;
|
|
119
|
+
align-items: center;
|
|
120
|
+
gap: 6px;
|
|
121
|
+
padding: 7px 12px;
|
|
122
|
+
cursor: pointer;
|
|
123
|
+
font-size: 11px;
|
|
124
|
+
font-weight: 600;
|
|
125
|
+
letter-spacing: 0.04em;
|
|
126
|
+
color: var(--red-ui-secondary-text-color, #888);
|
|
127
|
+
user-select: none;
|
|
128
|
+
list-style: none;
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
.fp-thinking summary::-webkit-details-marker { display: none; }
|
|
132
|
+
|
|
133
|
+
.fp-thinking summary::before {
|
|
134
|
+
content: "▶";
|
|
135
|
+
font-size: 8px;
|
|
136
|
+
display: inline-block;
|
|
137
|
+
transition: transform 0.15s ease;
|
|
138
|
+
color: var(--red-ui-secondary-text-color, #aaa);
|
|
139
|
+
flex-shrink: 0;
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
.fp-thinking[open] summary::before {
|
|
143
|
+
transform: rotate(90deg);
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
.fp-thinking-tokens {
|
|
147
|
+
margin-left: auto;
|
|
148
|
+
font-size: 10px;
|
|
149
|
+
font-weight: 400;
|
|
150
|
+
opacity: 0.55;
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
.fp-thinking-body {
|
|
154
|
+
padding: 4px 12px 10px 12px;
|
|
155
|
+
font-family: monospace;
|
|
156
|
+
font-size: 11px;
|
|
157
|
+
line-height: 1.5;
|
|
158
|
+
color: var(--red-ui-secondary-text-color, #999);
|
|
159
|
+
opacity: 0.8;
|
|
160
|
+
white-space: pre-wrap;
|
|
161
|
+
max-height: 180px;
|
|
162
|
+
overflow-y: auto;
|
|
163
|
+
}
|
|
164
|
+
|
|
106
165
|
.fp-error {
|
|
107
166
|
background: rgba(255, 80, 80, 0.12);
|
|
108
167
|
border-color: rgba(255, 80, 80, 0.65);
|
|
@@ -1056,6 +1115,50 @@
|
|
|
1056
1115
|
background: rgba(127, 127, 127, 0.15);
|
|
1057
1116
|
}
|
|
1058
1117
|
|
|
1118
|
+
/* Slash-command autocomplete panel */
|
|
1119
|
+
#fp-slash-suggest {
|
|
1120
|
+
position: absolute;
|
|
1121
|
+
bottom: 100%;
|
|
1122
|
+
left: 0;
|
|
1123
|
+
right: 0;
|
|
1124
|
+
margin-bottom: 4px;
|
|
1125
|
+
background: var(--red-ui-primary-background, #fff);
|
|
1126
|
+
border: 1px solid var(--red-ui-form-input-border-color, #ccc);
|
|
1127
|
+
border-radius: 6px;
|
|
1128
|
+
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.12);
|
|
1129
|
+
overflow: hidden;
|
|
1130
|
+
z-index: 100;
|
|
1131
|
+
}
|
|
1132
|
+
|
|
1133
|
+
.fp-slash-row {
|
|
1134
|
+
display: flex;
|
|
1135
|
+
align-items: baseline;
|
|
1136
|
+
gap: 10px;
|
|
1137
|
+
padding: 6px 10px;
|
|
1138
|
+
cursor: pointer;
|
|
1139
|
+
user-select: none;
|
|
1140
|
+
}
|
|
1141
|
+
|
|
1142
|
+
.fp-slash-row:hover,
|
|
1143
|
+
.fp-slash-row.fp-slash-active {
|
|
1144
|
+
background: var(--red-ui-secondary-background, #f5f5f5);
|
|
1145
|
+
}
|
|
1146
|
+
|
|
1147
|
+
.fp-slash-cmd {
|
|
1148
|
+
font-weight: 600;
|
|
1149
|
+
font-size: 13px;
|
|
1150
|
+
min-width: 90px;
|
|
1151
|
+
color: var(--red-ui-primary-text-color, #333);
|
|
1152
|
+
}
|
|
1153
|
+
|
|
1154
|
+
.fp-slash-desc {
|
|
1155
|
+
font-size: 12px;
|
|
1156
|
+
color: var(--red-ui-secondary-text-color, #777);
|
|
1157
|
+
white-space: nowrap;
|
|
1158
|
+
overflow: hidden;
|
|
1159
|
+
text-overflow: ellipsis;
|
|
1160
|
+
}
|
|
1161
|
+
|
|
1059
1162
|
#fp-provider-status {
|
|
1060
1163
|
flex: 0 1 auto;
|
|
1061
1164
|
min-width: 0;
|