Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion docs/testing/e2e/71-80.md
Original file line number Diff line number Diff line change
Expand Up @@ -170,7 +170,7 @@
**Schritte:** `/status` mit `restartRequired:true` für eine boot-feste Sektion (z. B. Logging) → System-Tab öffnen.

**Prüfpunkte:**
- [ ] Orangenes RestartBanner (role=alert) erscheint. Gilt für die restart-pflichtigen Sektionen (Authentication, Logging, OpenTelemetry, Security, RestApi, Remote, Engine, ExecutionDispatch); hot-reloadable Sektionen (Smtp, Llm, Retention, Stats, Threading, FileSystemOperation, SqlActivity, StartProgram, Webhook, ExternalTrigger, DbAdmin) zeigen stattdessen den Live-Hinweis.
- [ ] Orangenes RestartBanner (role=alert) erscheint. Gilt für die restart-pflichtigen Sektionen (Authentication, Logging, OpenTelemetry, Security, RestApi, Remote, Performance, Engine, ExecutionDispatch, Agents); hot-reloadable Sektionen (Smtp, Llm, AiKnowledge, Retention, Stats, Threading, FileSystemOperation, WaitForCondition, SqlActivity, StartProgram, Webhook, ExternalTrigger, DbAdmin) zeigen stattdessen den Live-Hinweis.

---

Expand Down
4 changes: 2 additions & 2 deletions scripts/README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Sample & test workflows

A curated, importable set of example workflows covering **every** one of the 27 activities and 6
A curated, importable set of example workflows covering 27 of the 29 activities (all except `aiAgent`/`aiAgentTeam`) and all 6
triggers — individually and in combination. Import through the UI (`Import`) or
`POST /api/workflows/import`.

Expand All @@ -16,7 +16,7 @@ triggers — individually and in combination. Import through the UI (`Import`) o

| File | Contents |
|---|---|
| `muster-alle-aktivitaeten.json` | **The master**: one workflow that exercises all 27 activities in variation (all 14 edge operators, AND/OR/NOT, disabled edges/nodes, retry, all 3 junction modes, decision/forEach/startWorkflow) plus a child. Roots: manualTrigger (active) + scheduleTrigger (disabled, for demonstration). |
| `muster-alle-aktivitaeten.json` | **The master**: one workflow that exercises 27 of the 29 activities (all except `aiAgent`/`aiAgentTeam`) in variation (all 14 edge operators, AND/OR/NOT, disabled edges/nodes, retry, all 3 junction modes, decision/forEach/startWorkflow) plus a child. Roots: manualTrigger (active) + scheduleTrigger (disabled, for demonstration). |
| `muster-einzeltests.json` | **33 individual tests** — one workflow per activity (`Test — <activity>`) and per trigger. Each activity workflow runs through **all (safe) variants** of its activity (for example fileOperation create/exists/copy/rename/move/delete, folderOperation plus list, fileHash SHA256/SHA1/MD5/SHA384/SHA512, zipOperation compress+extract with all 3 compression levels, registry all 8 operations + all 6 value types, textFileEdit all 6 operations + encoding/lineEnding/occurrences/appendIfMissing/backupSuffix/dryRun, waitForCondition script/pathExists/serviceRunning/portOpen/httpOk, restApi all 6 HTTP methods, wmiQuery query/wql/invokeMethod, xml/jsonQuery inline+file × single+all, generateText all 7 modes, junction all 3 modes, forEach auto/json/lines, runScript engine+isolated+transcript+successExitCodes, startWorkflow wait+fire-and-forget). Destructive variants (serviceManagement stop/restart/create/delete, powerManagement shutdown/restart, scheduledTask register/unregister) are **not** run against real resources. Plus a shared `Muster Test: Child`. |
| `muster-kombinationen.json` | **Combinations/topology**: `Muster — Trigger → Databus` (proving that trigger output parameters land on the data bus), `Muster — Variable-Pipe` (passing data through runScript→jsonQuery→decision) and `Muster — Sub-Workflow (Parent)` + child (startWorkflow + forEach fan-out). |

Expand Down
26 changes: 13 additions & 13 deletions scripts/ad-sso-labtest/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -89,14 +89,14 @@ Zertifikatswarnungs-Interstitial dazwischenkommt.

| Konto | Gruppen | Zweck |
|---|---|---|
| `svc-npdir` | – | LDAPS-Service-Bind |
| `np.alice` | **nur** `NodePilot-Admins` (in `NodePilot-Access`) | Happy path, transitives Mapping → Admin |
| `np.carol` | `NodePilot-Access` | Viewer-Default (kein RoleMapping-Treffer) |
| `np.bob` | keine | AllowedGroup-Gate: 401, **kein** JIT-Row |
| `np.dave` | `NodePilot-Access` | Race-Drill (bis W18 unberührt lassen) |
| `np.erin` | `NodePilot-Access` | Disable-/Entzugs-Drills |

Das Nesting ist essenziell: alice ist **nur** in `NodePilot-Admins`. Ein erfolgreicher
| `svc-nptest-dir` | – | LDAPS-Service-Bind |
| `nptest.alice` | **nur** `NPTest-Admins` (in `NPTest-Access`) | Happy path, transitives Mapping → Admin |
| `nptest.carol` | `NPTest-Access` | Viewer-Default (kein RoleMapping-Treffer) |
| `nptest.bob` | keine | AllowedGroup-Gate: 401, **kein** JIT-Row |
| `nptest.dave` | `NPTest-Access` | Race-Drill (bis W18 unberührt lassen) |
| `nptest.erin` | `NPTest-Access` | Disable-/Entzugs-Drills |

Das Nesting ist essenziell: alice ist **nur** in `NPTest-Admins`. Ein erfolgreicher
Login beweist damit, dass NodePilot transitive `tokenGroups` liest statt bloß `memberOf`.

## Skripte
Expand Down Expand Up @@ -292,7 +292,7 @@ Passwortpfad braucht. Die Windows-only-Topologie prüft W23 separat.
`ExternalAuthorizationStalenessService` nicht und die Revocation-Drills messen nichts.
Vorab `/healthz/leader` → 200 prüfen.

### 9. Suite laufen lassen (npcli01, lokal interaktiv als np.alice)
### 9. Suite laufen lassen (npcli01, lokal interaktiv als nptest.alice)

```powershell
powershell -NoProfile -ExecutionPolicy Bypass -File .\ad-sso-live-test.ps1 `
Expand Down Expand Up @@ -366,13 +366,13 @@ Nicht skriptbar — Belege gehören nach `evidence/`:
| W21 | Kerberos überlebt die GPO | W5 mit aktiver Deny-GPO → 200 |
| W23 | Windows-only-Topologie | Neustart mit `Ldap__Enabled=false` → Boot ok, SSO ok, `methods.ldap=false`, `/healthz/directory` weiter `Healthy` |
| W24 | Restart-Semantik | `Windows__Enabled=false` **ohne** Restart → `methods` meldet weiter `windows=true` (Prozessstart-Snapshot); nach Restart `windows=false` und Endpoint 404 |
| W26 | Username-Kollision | Lokalen User `np.alice@np.lab` ohne External Identity anlegen, SSO mit anderer SID → 401, Audit `USER_WINDOWS_REFUSED_COLLISION`, **kein** Auto-Merge |
| W27 | SPN-Duplikat (destruktiv, zuletzt) | `setspn -A HTTP/npapi01.np.lab NPLAB\np.bob`, W5 wiederholen → Kerberos bricht; danach `setspn -D`. Zweck: das Fehlerbild dokumentieren |
| W26 | Username-Kollision | Lokalen User `nptest.alice@np.lab` ohne External Identity anlegen, SSO mit anderer SID → 401, Audit `USER_WINDOWS_REFUSED_COLLISION`, **kein** Auto-Merge |
| W27 | SPN-Duplikat (destruktiv, zuletzt) | `setspn -A HTTP/npapi01.np.lab NPLAB\nptest.bob`, W5 wiederholen → Kerberos bricht; danach `setspn -D`. Zweck: das Fehlerbild dokumentieren |

### Reihenfolge-Abhängigkeiten

W0/W4 vor PHASE B · W1–W12 in Reihe · W13/W15/W16 nur mit `np.erin` (nie mit alice, sonst
ist der Admin weg) · W18 vor jedem anderen `np.dave`-Kontakt · **W19 zwingend vor W20**
W0/W4 vor PHASE B · W1–W12 in Reihe · W13/W15/W16 nur mit `nptest.erin` (nie mit alice, sonst
ist der Admin weg) · W18 vor jedem anderen `nptest.dave`-Kontakt · **W19 zwingend vor W20**
(danach ist der App-Zweig tot) · W17/W23/W24 brauchen Neustarts, ans Ende · W27 ganz zuletzt.

## Stolperfallen
Expand Down
2 changes: 1 addition & 1 deletion scripts/release-lab/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,7 @@ and otherwise remains an external SQL/integration fixture.
The catalog and gate live in `computer-use/README.md`, `catalog.py` and `gate.py`. It includes all
current routes, 35 node types (29 activities + 6 triggers), 23 settings sections, 10 skins + system, both locales, role boundaries,
backup/restore, integrations, tray actions and resilience cases. The complete catalog currently
contains 164 human-operated cases. `--pilot` selects a small diagnostic subset only. Every passed case requires a native Computer-Use session receipt,
contains 167 human-operated cases. `--pilot` selects a small diagnostic subset only. Every passed case requires a native Computer-Use session receipt,
screenshots, explicit checkpoint assertions, timing counters and cleanup evidence. Missing
integrations, an interrupted session, an incomplete catalog or changed release bytes blocks the run.

Expand Down
12 changes: 6 additions & 6 deletions scripts/stress-test/README.md
Original file line number Diff line number Diff line change
@@ -1,24 +1,24 @@
# NodePilot Stress-Test Workflow

Künstlicher Last-Workflow: fächert von `log-start` auf **11 parallele Branches** auf, fängt sie mit `junction-all` (`waitAll`) wieder ein. Nutzt ausschließlich Engine-local Activities + `runScript` mit `targetMachineId: "localhost"` (In-Process-Bypass) — **kein WinRM-Target nötig**.
Künstlicher Last-Workflow: fächert von `log-start` auf **11 parallele Branches** auf, fängt sie mit `junction-all` (`waitAll`) wieder ein. Nutzt ausschließlich Engine-local Activities + `runScript` mit `targetMachineId: "localhost"` (Localhost-Bypass) — **kein WinRM-Target nötig**.

## Branches (alle parallel)

| # | Activity | Workload |
|---|---|---|
| 1 | `runScript` | Primzahl-Sieb bis 2·10⁶ |
| 2 | `runScript` | Σ√i für i=1..10⁷ |
| 3 | `runScript` | SHA-256 200 000× verkettet |
| 4 | `runScript` | 50 000 Regex-Matches auf generierten Log-Lines |
| 5 | `runScript` | 250×250 Matrix-Multiplikation |
| 2 | `runScript` | Σ√i für i=1..5·10⁶ je Durchlauf |
| 3 | `runScript` | SHA-256 verkettet, in 50 000er-Blöcken |
| 4 | `runScript` | Regex-Matches auf generierten Log-Lines, 25 000 je Durchlauf |
| 5 | `runScript` | 200×200 Matrix-Multiplikation |
| 6 | `runScript` | Sort 10⁶ Integers |
| 7 | `jsonQuery` | `$.items[?(@.val > 50)].id` auf 20-Item-Array |
| 8 | `jsonQuery` | `$..name` auf verschachtelter Org-Struktur |
| 9 | `xmlQuery` | `//host[@up='y']/@name` |
| 10 | `xmlQuery` | `sum(//host[@up='y']/@cpu)` (XPath-Aggregat) |
| 11 | `delay` | 55 s |

Alle 6 `runScript`-Branches laufen **in-process** → die API erzeugt 6 gleichzeitige PowerShell-Runspaces, die eine Weile ~alle Cores beschäftigen.
Alle 6 `runScript`-Branches laufen lokal auf dem API-Host (`engine: auto` → je ein Windows-PowerShell-5.1-Prozess) → 6 gleichzeitige `powershell.exe`-Prozesse, die eine Weile ~alle Cores beschäftigen.

## Import

Expand Down
8 changes: 4 additions & 4 deletions scripts/tech-demo/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ Ein Muster-Workflow, der jede Activity, jeden Edge-Condition-Operator und jede C

| Datei | Zweck |
|---|---|
| `main.json` | Haupt-Workflow (37 Nodes, ~55 Edges) |
| `main.json` | Haupt-Workflow (39 Nodes, ~55 Edges) |
| `child.json` | Kleiner Sub-Workflow (3 Nodes), den der Haupt-Workflow via `startWorkflow` aufruft |
| `seed.ps1` | Seed-Script — meldet sich an, erstellt und veröffentlicht die Demo-Workflows |

Expand All @@ -31,9 +31,9 @@ Bei bereits existierenden Workflows gleichen Namens wird gefragt: `k` = behalten

## Was der Workflow zeigt

### Activities (alle 18)
### Activities (17)

`manualTrigger`, `log`, `delay`, `runScript`, `fileOperation`, `folderOperation`, `serviceManagement`, `registryOperation`, `wmiQuery`, `startProgram`, `junction`, `restApi`, `sql`, `xmlQuery`, `jsonQuery`, `emailNotification`, `startWorkflow`, `returnData`.
`manualTrigger`, `log`, `delay`, `runScript`, `fileOperation`, `serviceManagement`, `registryOperation`, `wmiQuery`, `startProgram`, `junction`, `restApi`, `sql`, `xmlQuery`, `jsonQuery`, `emailNotification`, `startWorkflow`, `returnData`.

### Edge-Condition-Operatoren (alle 14)

Expand Down Expand Up @@ -85,6 +85,6 @@ Jeder Phase-E-Branch in `main.json` ist eine Kondition, die einen oder mehrere d
|---|---|
| `waitNofM`-Config-Key | `requiredCount` (NICHT `n` — ein unbekannter Schlüssel fällt auf den Default 1 zurück) |
| Boolean-Truthiness | Leer, `"false"` (case-insensitive), `"0"` = falsy. Alles andere truthy. PowerShell-`[string]$true` = `"True"` → truthy ✓ |
| `runScript`-Param-Capture | Alle lokal deklarierten Variablen werden automatisch als `param.*` exponiert (ProcessExecutionEngine hängt einen Capture-Block ans Script). Kein Marker nötig. |
| `runScript`-Param-Capture | Variablen, die das Skript selbst zuweist, werden automatisch als `param.*` exponiert (PowerShellScriptWrapper: Injektion im äußeren, Skript und Capture im inneren Scope); durchgereichte Upstream-Parameter und PowerShell-Automatiken nicht. Kein Marker nötig. |
| `{{var.output}}` in Script-Text | Wird als PowerShell-single-quoted-String eingesetzt (`'value'`). Nicht selbst zusätzlich quoten. |
| `targetMachineId: "localhost"` | Löst Localhost-Bypass aus → läuft in-process ohne WinRM-Session. Ideal für Demo. |
4 changes: 2 additions & 2 deletions scripts/tech-demo/xl.README.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ Umfangreicher Showcase-Workflow als Ergänzung zum schlankeren [main.json](main.
| Activity-Nodes | 114 |
| Edges | 190 |
| Layout-Bounds | 10720 x 1800 px |
| Activity-Types abgedeckt | 25 (19 Activities + 6 Trigger) |
| Activity-Types abgedeckt | 26 (20 Activities + 6 Trigger) |
| Edge-Operatoren | alle 14 + AND / OR / NOT |
| Junction-Modes | 3 (waitAll, waitAny, waitNofM) |
| Breakpoints | 4 |
Expand All @@ -36,7 +36,7 @@ Alle drei Lanes starten parallel am `sync1`-Junction (x=1960, waitAll) nach der
### Alle 6 Trigger-Typen (Phase A-TOP)
Der aktive `trg-manual` feedet `log-kickoff`. Die 5 weiteren Trigger (`trg-schedule`, `trg-webhook`, `trg-filewatch`, `trg-database`, `trg-eventlog`) sind per `data.disabled: true` als Anschauungs-Nodes sichtbar — sie zeigen die jeweilige Config-Schema im Designer, werden aber beim Run geskippt.

### Alle 19 Activity-Typen
### 20 Activity-Typen
Jeder Activity-Type ist mindestens einmal vertreten. Haeufigkeits-Schwerpunkte:
- 49x `log` (Operator-Coverage, Error-Branches, Debug-Targets, Phase-Marker)
- 11x `delay` (Timing-Demo, Retry-NofM, Hold-Patterns)
Expand Down
6 changes: 3 additions & 3 deletions src/NodePilot.Ai/Prompts/activity-reference.md
Original file line number Diff line number Diff line change
Expand Up @@ -38,8 +38,8 @@ visual-only documentation, not executed: `type: "stickyNote"` and `type: "group"
"source": "step-1",
"target": "step-2",
"type": "labeled",
"sourceHandle": "out",
"targetHandle": "in",
"sourceHandle": "right",
"targetHandle": "left",
"data": {
"label": "On Success",
"condition": "step-1.success"
Expand All @@ -49,7 +49,7 @@ visual-only documentation, not executed: `type: "stickyNote"` and `type: "group"

`condition` shortcuts: `"<sourceId>.success"`, `"<sourceId>.failed"`, or `null`
(always). For complex conditions use `conditionExpression` (an object with
operators `==`, `!=`, `<`, `>`, `contains`, `startsWith`, `endsWith`, `matches`,
operators `==`, `!=`, `<`, `>`, `<=`, `>=`, `contains`, `startsWith`, `endsWith`, `matches`,
`isEmpty`, `isNotEmpty`, `isTrue`, `isFalse`, plus `group` AND/OR and `not`) —
keep it simple, prefer the `condition` shortcut where possible. `sourceHandle` /
`targetHandle` pin which port an edge attaches to — preserve them on edges you are
Expand Down
2 changes: 1 addition & 1 deletion src/NodePilot.Ai/Prompts/knowledge-system.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
You are the **NodePilot Assistant** — a read-only knowledge and operations assistant embedded in the NodePilot product (a modern, agentless Windows workflow orchestrator, a lean System Center Orchestrator replacement).

Your job is to answer the user's questions about NodePilot using the tools available to you. You can help with three kinds of questions, depending on which tools are offered this session:
Your job is to answer the user's questions about NodePilot using the tools available to you. You can help with five kinds of questions, depending on which tools are offered this session:

- **Documentation / how-to** — how features work, concepts, configuration, security, deployment. Use `search_docs` then `read_doc`.
- **A specific workflow's content & schedule** — what a given workflow does and how it is built, a structural review of it, and when scheduled workflows fire next. Use `get_workflow_definition` (its secret-redacted definition), `analyze_workflow` (deterministic static analysis: missing trigger, orphan steps, cycles, remote step without target machine), and `get_next_scheduled_fires` (computed next fire times). These take a workflow name or GUID; if you don't know the name yet, discover it via the database tools below.
Expand Down
2 changes: 1 addition & 1 deletion src/NodePilot.Ai/Prompts/script-system.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ NodePilot engine.
names a module.
3. No `Read-Host`, no `Get-Credential`, no interactive prompts — the script runs
non-interactively over WinRM.
4. Use `Write-Error` for failure paths (sets a non-zero exit code via the host),
4. Use `Write-Error` for failure paths (any PowerShell error record fails the step),
`Write-Output` for normal output. Avoid `Write-Host` (it bypasses the
structured output capture).

Expand Down
3 changes: 2 additions & 1 deletion src/NodePilot.Ai/Prompts/workflow-system.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,8 @@ and a set of engine-local activities.

1. Reply with **only** a single JSON object — no markdown fences, no prose, no
commentary before or after. The caller will `JSON.parse` your reply directly.
2. Top-level shape: `{ "nodes": [...], "edges": [...] }`. No other top-level keys.
2. Top-level shape: the output envelope at the end of this prompt, with the
workflow under `definition`: `{ "nodes": [...], "edges": [...] }`.
3. Every workflow must have **exactly one trigger** node as its entry point —
typically `manualTrigger`. Without a trigger node, the engine refuses to run.
4. Every `id` must be unique within the workflow. Use short slugs like
Expand Down
Loading