Эх сурвалжийг харах

docs: expose the workflow id to nodes, which the polling cursors need

fszontagh 1 сар өмнө
parent
commit
eab9b1cb07

+ 40 - 9
docs/superpowers/plans/2026-08-05-tier-2-triggers.md

@@ -171,14 +171,16 @@ git commit -m "test: let the harness assert on HTTP responses and answer a pause
 
 ---
 
-### Task 2: `fs.readdir`
+### Task 2: `fs.readdir`, and a workflow id a node can see
 
 **Files:**
-- Modify: `src/runner/engine/script_engine.cpp` (after the `fs.stat` registration, before `JS_SetPropertyStr(ctx, smartbotic, "fs", fs);`)
+- Modify: `src/runner/engine/script_engine.cpp` (after the `fs.stat` registration, before `JS_SetPropertyStr(ctx, smartbotic, "fs", fs);`, and the context object around line 4393)
+- Modify: `src/runner/workflow_engine.cpp:905` (the `ctx` filled before a node runs)
 - Create: `tests/nodes/fs-readdir.json`
 
 **Interfaces:**
 - Produces: `smartbotic.fs.readdir(path)` returning `{success: true, entries: [{name, path, size, modifiedAt, isDirectory}]}` or `{success: false, error}`. `modifiedAt` is milliseconds since the epoch, matching `fs.stat`'s `mtime`. Not recursive.
+- Produces: `context.workflowId`, alongside the `context.executionId` and `context.nodeId` a node already receives. Tasks 3 and 4 key their cursors on it.
 
 - [ ] **Step 1: Register the function**
 
@@ -263,11 +265,40 @@ Insert after the closing `}, "stat", 1));`:
     }, "readdir", 1));
 ```
 
-- [ ] **Step 2: Build and restart**
+- [ ] **Step 2: Expose the workflow id to nodes**
+
+A node currently receives only `executionId` and `nodeId` on its `context`. The
+two polling triggers in Tasks 3 and 4 key their cursor on the workflow, and
+without it every workflow's cursor would collide under one key - two workflows
+watching different directories would consume each other's changes.
+
+`ScriptContext` already declares `workflow_id` (`script_engine.hpp:147`) and
+`executeNode` already receives the `Workflow`, so nothing new has to be plumbed
+through. It is simply never set and never exposed.
+
+In `workflow_engine.cpp`, in `executeNode` beside the other `ctx` assignments
+around line 903:
+
+```cpp
+    ctx.workflow_id = workflow.id;
+```
+
+In `script_engine.cpp`, in the context object built for the execute function
+around line 4393:
+
+```cpp
+    nlohmann::json ctx_json = {
+        {"executionId", context.execution_id},
+        {"nodeId", context.node_id},
+        {"workflowId", context.workflow_id}
+    };
+```
+
+- [ ] **Step 3: Build and restart**
 
 Run the rebuild and restart sequence from the Reference section. Expected: clean build, all three ports listening.
 
-- [ ] **Step 3: Write the fixture**
+- [ ] **Step 4: Write the fixture**
 
 `tests/nodes/fs-readdir.json` - a `code` node creates a directory with two files, lists it, then cleans up:
 
@@ -277,7 +308,7 @@ Run the rebuild and restart sequence from the Reference section. Expected: clean
   "nodes": [
     {"id": "n1", "name": "Trigger", "type": "click-trigger", "position": {"x": 0, "y": 0}, "config": {}},
     {"id": "n2", "name": "List", "type": "code", "position": {"x": 0, "y": 100},
-     "config": {"code": "const dir = '/tmp/sb-readdir-test';\nsmartbotic.fs.mkdir(dir);\nsmartbotic.fs.writeFile(dir + '/one.txt', smartbotic.utils.base64Encode('hello'));\nsmartbotic.fs.writeFile(dir + '/two.txt', smartbotic.utils.base64Encode('worldwide'));\nsmartbotic.fs.mkdir(dir + '/sub');\n\nconst listing = smartbotic.fs.readdir(dir);\nconst missing = smartbotic.fs.readdir('/tmp/sb-readdir-does-not-exist');\nconst notDir = smartbotic.fs.readdir(dir + '/one.txt');\n\nconst names = listing.entries.map(function (e) { return e.name; }).sort();\nconst one = listing.entries.filter(function (e) { return e.name === 'one.txt'; })[0];\nconst sub = listing.entries.filter(function (e) { return e.name === 'sub'; })[0];\n\nsmartbotic.fs.unlink(dir + '/one.txt');\nsmartbotic.fs.unlink(dir + '/two.txt');\n\nreturn {\n    ok: listing.success,\n    names: names,\n    oneSize: one.size,\n    oneHasMtime: one.modifiedAt > 1600000000000,\n    subIsDirectory: sub.isDirectory,\n    oneIsDirectory: one.isDirectory,\n    missingRejected: missing.success === false,\n    notDirRejected: notDir.success === false\n};"}}
+     "config": {"code": "const dir = '/tmp/sb-readdir-test';\nsmartbotic.fs.mkdir(dir);\nsmartbotic.fs.writeFile(dir + '/one.txt', smartbotic.utils.base64Encode('hello'));\nsmartbotic.fs.writeFile(dir + '/two.txt', smartbotic.utils.base64Encode('worldwide'));\nsmartbotic.fs.mkdir(dir + '/sub');\n\nconst listing = smartbotic.fs.readdir(dir);\nconst missing = smartbotic.fs.readdir('/tmp/sb-readdir-does-not-exist');\nconst notDir = smartbotic.fs.readdir(dir + '/one.txt');\n\nconst names = listing.entries.map(function (e) { return e.name; }).sort();\nconst one = listing.entries.filter(function (e) { return e.name === 'one.txt'; })[0];\nconst sub = listing.entries.filter(function (e) { return e.name === 'sub'; })[0];\n\nsmartbotic.fs.unlink(dir + '/one.txt');\nsmartbotic.fs.unlink(dir + '/two.txt');\n\nreturn {\n    ok: listing.success,\n    names: names,\n    oneSize: one.size,\n    oneHasMtime: one.modifiedAt > 1600000000000,\n    subIsDirectory: sub.isDirectory,\n    oneIsDirectory: one.isDirectory,\n    missingRejected: missing.success === false,\n    notDirRejected: notDir.success === false,\n    hasWorkflowId: typeof context.workflowId === 'string' && context.workflowId.length > 0\n};"}}
   ],
   "connections": [
     {"sourceNodeId": "n1", "sourceOutput": "main", "targetNodeId": "n2", "targetInput": "data"}
@@ -299,16 +330,16 @@ Run the rebuild and restart sequence from the Reference section. Expected: clean
 
 `oneSize` is 5 because the file holds `hello`. That pins the size actually being read rather than defaulted to zero.
 
-- [ ] **Step 4: Run it**
+- [ ] **Step 5: Run it**
 
 Run: `python3 scripts/verify-node.py tests/nodes/fs-readdir.json`
 Expected: `PASS`.
 
-- [ ] **Step 5: Commit**
+- [ ] **Step 6: Commit**
 
 ```bash
-git add src/runner/engine/script_engine.cpp tests/nodes/fs-readdir.json
-git commit -m "feat: fs.readdir, so a node can see what is in a directory"
+git add src/runner/engine/script_engine.cpp src/runner/workflow_engine.cpp tests/nodes/fs-readdir.json
+git commit -m "feat: fs.readdir, and a workflow id a node can see"
 ```
 
 ---