@touchskyer/opc
Advanced tools
@@ -99,4 +99,21 @@ // ext-commands.mjs — CLI commands for extension system | ||
| // Resolve nodeType from flow-state.json + template | ||
| let nodeType = null; | ||
| try { | ||
| const stPath = join(resolve(dir), "flow-state.json"); | ||
| if (existsSync(stPath)) { | ||
| const st = JSON.parse(readFileSync(stPath, "utf8")); | ||
| const tplName = st.flowTemplate; | ||
| if (tplName) { | ||
| const { FLOW_TEMPLATES } = await import("./flow-templates.mjs"); | ||
| const tpl = FLOW_TEMPLATES[tplName]; | ||
| if (tpl?.nodeTypes) nodeType = tpl.nodeTypes[node] || null; | ||
| } | ||
| } | ||
| } catch { /* best effort */ } | ||
| const context = { | ||
| node, | ||
| nodeId: node, | ||
| nodeType, | ||
| role, | ||
@@ -103,0 +120,0 @@ task, |
@@ -18,2 +18,3 @@ // Flow core commands: route, init, validate, validateHandshakeData, validate-context | ||
| import { parseBypassArgs } from "./bypass-args.mjs"; | ||
| import { readTaskFromAC } from "./ext-commands.mjs"; | ||
@@ -214,3 +215,4 @@ // ─── route ────────────────────────────────────────────────────── | ||
| role: "preflight", | ||
| task: "", | ||
| task: readTaskFromAC(dir), | ||
| taskDescription: readTaskFromAC(dir), | ||
| flowDir: resolve(dir), | ||
@@ -217,0 +219,0 @@ devServerUrl: process.env.DEV_SERVER_URL || "", |
@@ -102,4 +102,10 @@ // Flow transition commands: transition, validate-chain, finalize | ||
| if (to === null) { | ||
| // Load persisted state for _flow_file resolution (same as non-terminal path) | ||
| let terminalState = null; | ||
| const termStatePath = join(dir, "flow-state.json"); | ||
| if (existsSync(termStatePath)) { | ||
| try { terminalState = JSON.parse(readFileSync(termStatePath, "utf8")); } catch { /* will be caught later */ } | ||
| } | ||
| // Verify the edge actually goes to null in the template | ||
| const resolvedTpl = resolveFlowTemplate(args); | ||
| const resolvedTpl = resolveFlowTemplate(args, terminalState); | ||
| if (!resolvedTpl.error) { | ||
@@ -164,3 +170,3 @@ const edges = resolvedTpl.template.edges[from]; | ||
| try { | ||
| await _cmdTransitionLocked(from, to, verdict, flow, dir, template, statePath); | ||
| await _cmdTransitionLocked(from, to, verdict, flow, dir, template, statePath, args); | ||
| } finally { | ||
@@ -171,3 +177,3 @@ lock.release(); | ||
| async function _cmdTransitionLocked(from, to, verdict, flow, dir, template, statePath) { | ||
| async function _cmdTransitionLocked(from, to, verdict, flow, dir, template, statePath, args) { | ||
| let state; | ||
@@ -346,3 +352,3 @@ if (existsSync(statePath)) { | ||
| const vConfig = loadOpcConfig(dir); | ||
| Object.assign(vConfig, parseBypassArgs([]), { flowDir: dir }); | ||
| Object.assign(vConfig, parseBypassArgs(args || []), { flowDir: dir }); | ||
| const vTask = readTaskFromAC(dir); | ||
@@ -372,2 +378,8 @@ const vRegistry = await loadExtensions(vConfig); | ||
| saveRegistryCache(resolve(dir), vRegistry); | ||
| // Write extensionsApplied to handshake (same as cmdExtensionVerdict) | ||
| const handshakePath = join(latestRunDir, "handshake.json"); | ||
| let handshake = {}; | ||
| try { handshake = JSON.parse(readFileSync(handshakePath, "utf8")); } catch { /* start fresh */ } | ||
| handshake.extensionsApplied = survivingExtensions(vRegistry); | ||
| writeFileSync(handshakePath, JSON.stringify(handshake, null, 2)); | ||
| } | ||
@@ -516,3 +528,3 @@ } | ||
| const config = loadOpcConfig(dir); | ||
| Object.assign(config, parseBypassArgs([]), { flowDir: dir }); | ||
| Object.assign(config, parseBypassArgs(args || []), { flowDir: dir }); | ||
| const task = readTaskFromAC(dir); | ||
@@ -519,0 +531,0 @@ const registry = await loadExtensions(config); |
+1
-1
| { | ||
| "name": "@touchskyer/opc", | ||
| "version": "0.10.4", | ||
| "version": "0.10.5", | ||
| "description": "OPC — One Person Company. Task pipeline with independent multi-role evaluation.", | ||
@@ -5,0 +5,0 @@ "type": "module", |
@@ -56,3 +56,3 @@ # Gate Protocol | ||
| **Override:** The orchestrator MUST NOT skip or relax these rules. If structured data says tests failed, the gate FAILs — even if the upstream node verdict was PASS. The only way past this is `/opc pass` (explicit user override). | ||
| **Override:** The orchestrator MUST NOT skip or relax these rules. If structured data says tests failed, the gate FAILs — even if the upstream node verdict was PASS. `/opc pass` (explicit user override) also runs Step 1.5 — it is NOT a bypass. If Step 1.5 detects failing artifacts, `/opc pass` is rejected. | ||
@@ -59,0 +59,0 @@ ### Step 2 — Mechanical Validation |
AI-detected potential code anomaly
Supply chain riskAI has identified unusual behaviors that may pose a security risk.
URL strings
Supply chain riskPackage contains fragments of external URLs or IP addresses, which the package may be accessing at runtime.
AI-detected potential code anomaly
Supply chain riskAI has identified unusual behaviors that may pose a security risk.
Found 3 instances
URL strings
Supply chain riskPackage contains fragments of external URLs or IP addresses, which the package may be accessing at runtime.
22283923
0.01%17133
0.18%110
-1.79%