@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 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
@@ -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
- - **`flowpilot-core.js`** — the shared client logic (chat/generate/modify/
119
- document/build, selection/context handling, settings UI, diff review and
120
- apply, group mutations) used by both the sidebar and the pop-out window,
121
- so they stay in sync by construction rather than by copy-pasted code.
122
- Served via a dedicated static route alongside the pop-out's own minimal
123
- page (`lib/popout/view.html`), which loads this same module and relays
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 in a local Node-RED user directory
96
+ ## Install
97
97
 
98
- From your Node-RED user directory:
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 /path/to/node-red-flowpilot
105
+ npm install @manny-est/node-red-flowpilot
103
106
  node-red
104
107
  ```
105
108
 
106
- For a Docker/container setup, place or install the package inside the
107
- mounted Node-RED user directory. If your user directory is
108
- `/data` (or `/workspaces/nodered`, etc.), this folder should exist:
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 installing or updating
115
- plugin HTML is cached server-side, so a browser refresh alone is not enough.
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. FlowPilot plans the
216
- work, proposes a first flow, and once you apply and deploy it, walks an
217
- interactive loop with you: attach the resulting Debug output, FlowPilot
218
- reviews it against the goal, and either confirms it's working or proposes a
219
- fix repeating until it works or a configurable attempt limit is reached
220
- (**Settings Behavior Build loop iteration cap**). Every proposal and fix
221
- still goes through the same review-then-apply flow as Modify — FlowPilot
222
- never deploys for you.
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
  ![A debug message attached, shown in the status strip](https://github.com/manny-est/flowpilot/releases/download/v0.2.1/debug-log-attached.png)
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
  ![A reply with an action chip below it](https://github.com/manny-est/flowpilot/releases/download/v0.2.1/action-chip.png)
274
288
 
275
289
  ![The full chat thread leading up to an action chip](https://github.com/manny-est/flowpilot/releases/download/v0.2.1/action-chip-full.png)
@@ -303,7 +317,9 @@ Behavior → Stream chat replies**.
303
317
 
304
318
  ### Slash commands
305
319
 
306
- Type these directly into the prompt box:
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
@@ -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;