diff --git a/docs/workflow-designer-features.md b/docs/workflow-designer-features.md index 7aad04e8..f91b52b4 100644 --- a/docs/workflow-designer-features.md +++ b/docs/workflow-designer-features.md @@ -13,7 +13,9 @@ Admins can force-release another user's lock. Changes are saved automatically after 5 seconds without further edits when write permission is available. Manual save and a warning before leaving with unsaved changes -remain available. Lint errors block publishing, while warnings require confirmation. +remain available. If the workflow was saved elsewhere in the meantime, the save is rejected: +the draft stays on the canvas, autosave stops and a reload shows the current version. +Lint errors block publishing, while warnings require confirmation. The lint panel links each finding to the affected node or edge. ## Canvas and workflow structure diff --git a/src/nodepilot-docs-ui/content/de/activities-reference.md b/src/nodepilot-docs-ui/content/de/activities-reference.md index 2c8da616..df81d8fe 100644 --- a/src/nodepilot-docs-ui/content/de/activities-reference.md +++ b/src/nodepilot-docs-ui/content/de/activities-reference.md @@ -104,6 +104,7 @@ Jeder Step unterstützt `config.retry` mit `maxAttempts`, `backoff`, `initialDel - `runspace` läuft im In-Process-Pool mit PowerShell 7. Das ist am schnellsten, weil kein Prozessstart anfällt. Dafür lädt es nur Module mit Core-Kennzeichnung, kann keine Hintergrund-Jobs starten (`Start-Job`, `Get-WindowsUpdateLog`) und lässt sich nicht mit `isolated` kombinieren. Startet ein Skript dort selbst eine Windows PowerShell, bekommt nur der direkte Aufruf `& powershell.exe` die richtigen Module; eine über `cmd /c`, `Start-Process` oder `[Diagnostics.Process]` gestartete fehlen Befehle wie `New-Guid`. - **Module aus der PowerShell Gallery** (z. B. `PSWindowsUpdate` mit `Get-WindowsUpdate`) sind keine Windows-Module. Sie müssen dort installiert sein, wo der Step läuft: lokal für alle Benutzer auf dem NodePilot-Server, remote auf der Zielmaschine. - **Hintergrundprogramme und Isolation-Robustheit:** Ein Step, der als Prozess läuft, endet mit seinem Skript. Nach dem Skriptende sammelt NodePilot restliche Ausgabe höchstens `Engine:IsolatedDrainGraceSeconds` lang (default 5 s). Ein Programm, das das Skript ohne neues Fenster im Hintergrund startet (`Start-Process -NoNewWindow`, `cmd /c start`), läuft weiter, hält den Step aber nicht mehr fest. Außerdem serialisiert NodePilot inheritable-handle-Spawns, damit ein in einen Fremdprozess geleaktes Pipe-Handle einen isolierten Lauf nicht dauerhaft blockiert. +- **Ausgabelimit:** `Engine:MaxCapturedOutputChars` (default 16.777.216 Zeichen, restart-pflichtig) begrenzt die Ausgabe, die eine Skriptausführung über alle Streams sammelt, für Prozess-, Runspace- und WinRM-Ausführung gleichermaßen. Eine Überschreitung beendet den Step mit einem Ausgabelimit-Fehler. Der Standard lässt Platz für die beiden je 1 MiB großen Ausgaben von `startProgram`; ein kleinerer Wert begrenzt auch diese Aktivität. - **Outputs:** `output`, `error`, `param.exitCode` (immer — das letzte native Kommando **dieses** Skripts), `param.*` (die Variablen, die dieses Skript zuweist). `output` enthält jedes Pipeline-Objekt als Text, wie bei einem Remote-Step; `Write-Host`, Warnungen und Fortschritt gehören nicht dazu. - **Erfolg (fehler-basiert, lokal wie remote):** Ein Step scheitert, sobald das Skript einen PowerShell-Fehler schreibt, auch einen nicht terminierenden (`Write-Error`, ein fehlgeschlagenes Cmdlet unter `Continue`), oder wenn es sich nicht parsen lässt. In Windows PowerShell 5.1 zählt stderr eines nativen Programms als Fehler und beendet das Skript; wer das nicht will, führt die Ströme im Programmaufruf zusammen: `cmd /c "tool.exe 2>&1"`. Ein `exit N` markiert den Step nicht automatisch als fehlgeschlagen. Für exit-code-basierte Bewertung ist `successExitCodes` zu setzen, zum Beispiel `"0"`. `successExitCodes`/`param.exitCode` greifen für Native-Command-Codes (`$LASTEXITCODE`) in allen Engines; ein script-eigenes `exit N` ist nur im Prozess/isoliert-Modus als Wert sichtbar (Runspace sieht `exit` nicht). - **Notes:** Variablen, die das Skript zuweist, werden zu `param.*` (`$hostName = …` → `{{step.param.hostName}}`) — auch wenn das Skript danach mit `exit` oder `return` endet oder einen Fehler wirft. Ein Upstream-Parameter, den das Skript nur liest, bleibt Output des erzeugenden Steps; PowerShell-Automatiken und Preference-Variablen werden nie publiziert. Auto-Quoting: `{{step.output}}` wird als Single-Quoted String eingesetzt — `$x = {{step.output}}` schreiben, nicht `$x = '{{step.output}}'`. In einem Wort oder Pfad wird der Wert Teil dieses einen Worts, egal wo die Vorlage steht: `C:\logs\{{step.output}}.txt`, `{{step.param.dir}}\app.txt` und `{{step.param.name}}.log` bleiben jeweils ein Argument. Ein Methodenaufruf wie `{{step.output}}.Trim()` bleibt ein Methodenaufruf. diff --git a/src/nodepilot-docs-ui/content/de/api/endpoints.md b/src/nodepilot-docs-ui/content/de/api/endpoints.md index 8cfd33c2..e5db25b4 100644 --- a/src/nodepilot-docs-ui/content/de/api/endpoints.md +++ b/src/nodepilot-docs-ui/content/de/api/endpoints.md @@ -129,6 +129,8 @@ curl -s -b cookie.jar -H "X-CSRF-Token: $(csrf_token)" -X POST "$NP/api/workflow curl -s -b cookie.jar "$NP/api/workflows/21f1c0d4-.../coverage?windowDays=7" | jq ``` +Statt `configOverride`, das nur `data.config` des gespeicherten Nodes ersetzt, übergibt `stepOverride` den vollständigen aktuellen `node.data`-Stand (Activity-Typ, Config, Maschine, Credential, Output-Variable); weggelassene Ziel- oder Credential-Felder leeren die gespeicherten Werte. Beide Overrides schließen sich gegenseitig aus und verlangen Edit-Recht plus eine eigene aktive Edit-Sperre. Eine ausgewählte Maschine, die nicht mehr existiert, wird abgelehnt. + ## Import/Export | Endpoint | Zweck | diff --git a/src/nodepilot-docs-ui/content/de/designer/properties-modes.md b/src/nodepilot-docs-ui/content/de/designer/properties-modes.md index 6be9e309..bb5c428e 100644 --- a/src/nodepilot-docs-ui/content/de/designer/properties-modes.md +++ b/src/nodepilot-docs-ui/content/de/designer/properties-modes.md @@ -96,7 +96,7 @@ Bei einem Breakpoint pausiert der Debug-Lauf vor dem betroffenen Schritt. Danach ## Speichern, veröffentlichen und exportieren -Änderungen werden nach einer kurzen Bearbeitungspause automatisch als Entwurf gespeichert. `Ctrl+S` speichert den Entwurf sofort. +Änderungen werden nach einer kurzen Bearbeitungspause automatisch als Entwurf gespeichert. `Ctrl+S` speichert den Entwurf sofort. Wurde der Workflow inzwischen an anderer Stelle gespeichert, wird das Speichern abgelehnt: Der Entwurf bleibt auf dem Canvas, das automatische Speichern stoppt, und erst ein Neuladen zeigt den aktuellen Stand. **Veröffentlichen** übernimmt den aktuellen Entwurf als ausführbare Version. Abhängig vom Workflow-Status kann dieselbe Aktion den Workflow aktivieren oder deaktivieren. Frühere Versionen bleiben über den Versionsverlauf verfügbar. diff --git a/src/nodepilot-docs-ui/content/en/activities-reference.md b/src/nodepilot-docs-ui/content/en/activities-reference.md index 11ca9850..b053f121 100644 --- a/src/nodepilot-docs-ui/content/en/activities-reference.md +++ b/src/nodepilot-docs-ui/content/en/activities-reference.md @@ -99,6 +99,7 @@ Every step supports `config.retry` with `maxAttempts`, `backoff`, `initialDelayM - `runspace` runs in the in-process PowerShell 7 pool. It is the fastest option, with no process start, but only loads modules marked Core-compatible, cannot start background jobs (`Start-Job`, `Get-WindowsUpdateLog`) and cannot be combined with `isolated`. If a script there starts Windows PowerShell itself, only the direct call `& powershell.exe` gets the right modules; one started through `cmd /c`, `Start-Process` or `[Diagnostics.Process]` lacks commands such as `New-Guid`. - **Modules from the PowerShell Gallery** (for example `PSWindowsUpdate` with `Get-WindowsUpdate`) are not Windows modules. They have to be installed where the step runs: locally for all users on the NodePilot server, remotely on the target machine. - **Background programs and isolation robustness:** a step that runs as a process ends when its script ends. After the script exits, NodePilot collects remaining output for at most `Engine:IsolatedDrainGraceSeconds` (default 5 s). A program the script started in the background without a new window (`Start-Process -NoNewWindow`, `cmd /c start`) keeps running but no longer holds the step. NodePilot also serializes inheritable-handle spawns, so a pipe handle leaked into a foreign process cannot block an isolated run indefinitely. +- **Output limit:** `Engine:MaxCapturedOutputChars` (default 16,777,216 characters, requires a restart) caps the output one script execution captures across all streams, for process, runspace and WinRM execution alike. Exceeding it fails the step with an output-limit error. The default leaves room for the two 1 MiB `startProgram` streams; a smaller value limits that activity too. - **Outputs:** `output`, `error`, `param.exitCode` (always — the last native command **of this script**), `param.*` (the variables this script assigns). `output` holds each pipeline object as text, as on a remote step; `Write-Host`, warnings and progress are not part of it. - **Success (error-based, locally as remotely):** a step fails as soon as the script writes a PowerShell error, including a non-terminating one (`Write-Error`, a failed cmdlet under `Continue`), or when it does not parse. In Windows PowerShell 5.1, stderr from a native program counts as an error and ends the script; to avoid that, merge the streams inside the program call: `cmd /c "tool.exe 2>&1"`. An `exit N` does not automatically mark the step as failed. For exit-code-based evaluation, set `successExitCodes`, for example `"0"`. `successExitCodes`/`param.exitCode` apply to native command codes (`$LASTEXITCODE`) in every engine; a script's own `exit N` is only visible as a value in process/isolated mode (a runspace cannot observe `exit`). - **Notes:** variables the script assigns become `param.*` (`$hostName = …` → `{{step.param.hostName}}`), even when the script then ends with `exit` or `return` or throws. An upstream parameter the script only reads stays the output of the step that produced it, and PowerShell automatic/preference variables are never published. Auto-quoting: `{{step.output}}` is substituted as a single-quoted string — write `$x = {{step.output}}`, not `$x = '{{step.output}}'`. Inside a word or path the value becomes part of that one word, wherever the template stands: `C:\logs\{{step.output}}.txt`, `{{step.param.dir}}\app.txt` and `{{step.param.name}}.log` each stay a single argument. A method call such as `{{step.output}}.Trim()` stays a method call. diff --git a/src/nodepilot-docs-ui/content/en/api/endpoints.md b/src/nodepilot-docs-ui/content/en/api/endpoints.md index 7e16293b..d6bb9602 100644 --- a/src/nodepilot-docs-ui/content/en/api/endpoints.md +++ b/src/nodepilot-docs-ui/content/en/api/endpoints.md @@ -128,6 +128,8 @@ curl -s -b cookie.jar -H "X-CSRF-Token: $(csrf_token)" -X POST "$NP/api/workflow curl -s -b cookie.jar "$NP/api/workflows/21f1c0d4-.../coverage?windowDays=7" | jq ``` +Instead of `configOverride`, which replaces only `data.config` of the saved node, `stepOverride` sends the complete current `node.data` (activity type, config, machine, credential, output variable); omitted target or credential fields clear the saved values. The two overrides are mutually exclusive, and either requires Edit permission plus your own active edit lock. A selected machine that no longer exists is rejected. + ## Import/export | Endpoint | Purpose | diff --git a/src/nodepilot-docs-ui/content/en/designer/properties-modes.md b/src/nodepilot-docs-ui/content/en/designer/properties-modes.md index e26339f2..7f3cdd61 100644 --- a/src/nodepilot-docs-ui/content/en/designer/properties-modes.md +++ b/src/nodepilot-docs-ui/content/en/designer/properties-modes.md @@ -96,7 +96,7 @@ At a breakpoint, the debug run pauses before the step concerned. The following a ## Saving, publishing and exporting -Changes are saved automatically as a draft after a short editing pause. `Ctrl+S` saves the draft immediately. +Changes are saved automatically as a draft after a short editing pause. `Ctrl+S` saves the draft immediately. If the workflow was saved elsewhere in the meantime, the save is rejected: the draft stays on the canvas, autosave stops and a reload shows the current version. **Publishing** promotes the current draft to the executable version. Depending on the workflow's state, the same action can enable or disable the workflow. Earlier versions remain available through the version history.