@voiden/runner 2.3.0-beta.14 → 2.3.0-beta.16

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
@@ -3,6 +3,71 @@
3
3
  All notable changes to `@voiden/runner` are documented here. This package is
4
4
  versioned and released independently of the Voiden desktop app.
5
5
 
6
+ ## v2.3.0-beta.16 - 2026-09-09
7
+
8
+ ### Fixed
9
+ - A `.void` file's `multipart-table` block (including a multipart file field, e.g. the Multipart
10
+ Form with Files example) silently sent an empty body when run via `run`/`run_request`/`tool
11
+ verify` — no error, just zero fields ever attached. Table-shaped blocks are saved to disk in a
12
+ compact shorthand (`{type: "table", rows: [...]}`); the Voiden app expands this back into the
13
+ full node tree it needs on load, but the shared standalone parser (`@voiden/executors`'
14
+ `parseVoidFile`, adapted from the app's own converter) never got that expansion step, so
15
+ `voiden-rest-api`'s field-extraction logic found nothing to read. A pure single-file `restFile`
16
+ binary upload (not table-based) was unaffected and continued working correctly. Fixed by porting
17
+ the missing expansion step over — scoped specifically to table structure, since an earlier,
18
+ broader attempt at this also corrupted plain-string block content (e.g. a `method` block's value)
19
+ that was never meant to be touched.
20
+ - Once the above was fixed, a binary/multipart file field's stored path still failed with `ENOENT`
21
+ if it used the app's own legacy `/subfolder/file.png` project-relative convention (a leading slash
22
+ that isn't actually filesystem-root) — the Electron app's own file adapter already resolves this
23
+ correctly (with a fallback for exactly this legacy shape), but this CLI's adapter just passed the
24
+ raw path straight to `fs.readFile` with no project-relative resolution at all. Ported the same
25
+ resolution logic over.
26
+
27
+ ### Added
28
+ - `--profile [name]` on `run`, `mcp serve`, and `tool verify` — reuses the same env-profile system
29
+ `list_environments`/`select_environment` already expose to an MCP agent
30
+ (`.voiden/env-<profile>-{public,private}.yaml`, both files merged together, or that profile's
31
+ legacy `.env*` fallback), now also reachable from the command line instead of only knowing the
32
+ raw file path. Bare `--profile` (no name) means `"default"`. Combine with `--environment <name>`
33
+ to scope to one named environment within that profile's tree (dotted path for a nested child,
34
+ e.g. `"staging.eu"`).
35
+
36
+ ### Changed
37
+ - `--env <path>` now only accepts a plain `.env` file, and errors clearly (pointing at `--profile`)
38
+ if given a `.yaml`/`.yml` path or combined with `--environment`. A single `--env` path pointing at
39
+ one YAML file could never correctly represent a profile anyway — a profile is always a *pair* of
40
+ files (`-public.yaml` + `-private.yaml`, merged), and `--env` only ever loaded whichever one you
41
+ happened to point it at. `--profile` already merges both correctly; there's no reason to keep a
42
+ half-working path to YAML alongside it. `--env` pointing at a plain `.env` file is unchanged.
43
+
44
+ ## v2.3.0-beta.15 - 2026-09-07
45
+
46
+ ### Added
47
+ - Two new fixed MCP tools, alongside the existing `list_void_files`/`list_requests`/`run_request`/
48
+ `write_result` — `list_environments` and `select_environment` (`mcpServing.ts`, exposed by
49
+ `voiden-runner mcp serve`/`mcp install`; `@voiden/mcp` is unaffected, see below). `list_environments`
50
+ discovers every env profile in the project (`.voiden/env-{profile}-public/private.yaml`, or the
51
+ `default` profile's unsuffixed files) and, for each, either its YAML environment hierarchy as
52
+ dotted paths (e.g. `"staging"`, `"staging.eu"` for a nested child) or — if that profile has no YAML
53
+ environments — the plain `.env*` file(s) it falls back to. `select_environment` resolves a chosen
54
+ profile (+ optional dotted environment path within it) and makes its variables the default base
55
+ layer for every `run_request` call for the rest of the session; an explicit `envFile`/`envVars` on
56
+ a given `run_request` call still overrides it for that call only. Returns variable *keys* only, not
57
+ values — `env-*-private.yaml` can hold real secrets, and echoing them into a tool-call response
58
+ that likely ends up in the calling agent's own transcript is an avoidable exposure `run_request`'s
59
+ existing `envVars` param doesn't already create.
60
+ - `envFile.ts`: exported `parseYamlEnv`, added and exported `listYamlEnvironmentNames` (full nested
61
+ environment tree as dotted paths) and `findEnvironmentByPath` (resolves a tree by exact dotted
62
+ path rather than searching for a bare key anywhere — needed because two different parents can each
63
+ have a same-named child, e.g. `staging.eu` vs `prod.eu`; only a full-path walk tells them apart).
64
+ - New `envProfiles.ts` — headless profile discovery/resolution (no Electron dependency), a
65
+ deliberately simplified port of `apps/electron/src/main/env.ts`'s profile logic, same precedent as
66
+ `plugins/voiden-mcp-tool/src/lib/toolCapability.ts`'s `loadProjectEnvironmentVars`.
67
+ - Note: `@voiden/mcp` does not call `registerFixedTools` at all today (a pre-existing gap, not
68
+ changed by this release) — none of the 6 fixed tools, old or new, currently reach connections made
69
+ through that package, only `voiden-runner mcp serve`/`mcp install`.
70
+
6
71
  ## v2.3.0-beta.14 - 2026-08-26
7
72
 
8
73
  ### Fixed
@@ -1 +1 @@
1
- "use strict";var y=Object.defineProperty;var C=Object.getOwnPropertyDescriptor;var R=Object.getOwnPropertyNames;var T=Object.prototype.hasOwnProperty;var A=(r,e)=>()=>(r&&(e=r(r=0)),e);var w=(r,e)=>{for(var t in e)y(r,t,{get:e[t],enumerable:!0})},D=(r,e,t,n)=>{if(e&&typeof e=="object"||typeof e=="function")for(let s of R(e))!T.call(r,s)&&s!==t&&y(r,s,{get:()=>e[s],enumerable:!(n=C(e,s))||n.enumerable});return r};var E=r=>D(y({},"__esModule",{value:!0}),r);function F(r,e){let t=r.trim();if(t==="status"||t==="statusCode")return e.response.status;if(t==="statusText")return e.response.statusText;if(t==="responseTime"||t==="duration")return e.response.timing?.duration||0;if(t.startsWith("header.")||t.startsWith("headers.")){let n=t.split("."),s=n[1];if(s.toLowerCase()==="set-cookie"){let i=(0,x.parseCookies)(e.response.headers);if(n.length===2)return i;let c=n.slice(2).join(".");return l(i,c)}return e.response.headers.find(i=>i.key.toLowerCase()===s.toLowerCase())?.value}if(t==="body"||t==="response.body")return e.response.body;if(t.startsWith("body.")||t.startsWith("response.body.")){let n=t.replace(/^(response\.)?body\./,"");return l(e.response.body,n)}if(t.startsWith("response.")){let n=t.replace(/^response\./,"");return l(e.response,n)}return l(e.response.body,t)}function l(r,e){if(!r)return;let t=e.split(/\.|\[/).map(s=>s.replace(/\]$/,"")),n=r;for(let s of t){if(n==null)return;/^\d+$/.test(s)?n=n[parseInt(s,10)]:n=n[s]}return n}function O(r,e){try{if(r.enabled===!1)return{assertion:r,passed:!0,actualValue:null,error:"Skipped (disabled)"};let t=j(r.field),n=t.field,s=t.operator||r.operator||"equals",o=r.expectedValue,i=F(n,e),c=W(s,i,o);return{assertion:r,passed:c,actualValue:i}}catch(t){return{assertion:r,passed:!1,actualValue:null,error:t.message||String(t)}}}function j(r){let e=["equals","eq","==","===","not-equals","ne","!=","!==","contains","includes","not-contains","not-includes","starts-with","startswith","ends-with","endswith","matches","regex","exists","is-defined","not-exists","is-null","is-undefined","greater-than","gt",">","less-than","lt","<","greater-equal","gte",">=","less-equal","lte","<=","is-empty","empty","not-empty","is-truthy","truthy","is-falsy","falsy","type-is","typeof"],t=r.trim().split(/\s+/);if(t.length>=2){let n=t[t.length-1].toLowerCase();if(e.includes(n))return{field:t.slice(0,-1).join(" "),operator:n}}return{field:r.trim(),operator:null}}function W(r,e,t){switch(r.toLowerCase().trim()){case"equals":case"eq":case"==":case"===":return e==null?!1:String(e)===t;case"not-equals":case"ne":case"!=":case"!==":return e==null?!1:String(e)!==t;case"contains":case"includes":return e==null?!1:String(e).includes(t);case"not-contains":case"not-includes":return e==null?!1:!String(e).includes(t);case"starts-with":case"startswith":return e==null?!1:String(e).startsWith(t);case"ends-with":case"endswith":return e==null?!1:String(e).endsWith(t);case"matches":case"regex":if(e==null)return!1;try{return new RegExp(t).test(String(e))}catch{return!1}case"exists":case"is-defined":return e!=null;case"not-exists":case"is-null":case"is-undefined":return e==null;case"greater-than":case"gt":case">":{let s=Number(e),o=Number(t);return!isNaN(s)&&!isNaN(o)&&s>o}case"less-than":case"lt":case"<":{let s=Number(e),o=Number(t);return!isNaN(s)&&!isNaN(o)&&s<o}case"greater-equal":case"gte":case">=":{let s=Number(e),o=Number(t);return!isNaN(s)&&!isNaN(o)&&s>=o}case"less-equal":case"lte":case"<=":{let s=Number(e),o=Number(t);return!isNaN(s)&&!isNaN(o)&&s<=o}case"is-empty":case"empty":return e==null?!1:Array.isArray(e)?e.length===0:typeof e=="string"?e==="":typeof e=="object"?Object.keys(e).length===0:!1;case"not-empty":return e==null?!1:Array.isArray(e)?e.length>0:typeof e=="string"?e!=="":typeof e=="object"?Object.keys(e).length>0:!0;case"is-truthy":case"truthy":return!!e;case"is-falsy":case"falsy":return!e;case"type-is":case"typeof":return typeof e===t.toLowerCase();default:throw new Error(`Unknown operator: ${r}`)}}function S(r,e){return r.map(t=>O(t,e))}var x,N=A(()=>{"use strict";x=require("@voiden/sdk/shared")});var q={};w(q,{postProcessAssertionsHook:()=>$});function v(r){let e=[];if(!r||!r.content)return e;function t(n){if(n.type==="assertions-table"){let s=L(n);e.push(...s)}n.content&&Array.isArray(n.content)&&n.content.forEach(s=>t(s))}return t(r),e}function L(r){let e=[];try{if(r.attrs&&Array.isArray(r.attrs.rows)){let s=r.attrs.rows;for(let o of s)!o.description&&!o.field&&!o.operator&&!o.expectedValue||o.enabled!==!1&&e.push({description:o.description||"",field:o.field||"",operator:o.operator||"equals",expectedValue:o.expectedValue||"",enabled:!0});return e}let t=Array.isArray(r.content)?r.content.find(s=>s.type==="table"||s.type==="assertions-table"):null;if(!t)return e;let n=t.rows||t.content||[];for(let s=0;s<n.length;s++){let o=n[s];if(Array.isArray(o.row)){if(o.attrs?.disabled===!0)continue;let[a,g,h,b]=o.row;if(!a&&!g&&!h&&!b)continue;e.push({description:String(a||"").trim(),field:String(g||"").trim(),operator:String(h||"equals").trim()||"equals",expectedValue:String(b||"").trim(),enabled:!0});continue}if(o.type!=="tableRow"||o.attrs&&o.attrs.disabled===!0)continue;let i=o.content||[];if(i.length<4)continue;let c=d(i[0]).trim(),p=d(i[1]).trim(),f=d(i[2]).trim(),u=d(i[3]).trim();!c&&!p&&!f&&!u||!(!(i.length>=5)||P(i[4]))||e.push({description:c,field:p,operator:f||"equals",expectedValue:u,enabled:!0})}}catch(t){console.error("Error extracting assertions from table:",t)}return e}function d(r){return r?r.type==="text"?r.text||"":r.content&&Array.isArray(r.content)?r.content.map(e=>d(e)).join(""):"":""}function P(r){if(!r||!r.content)return!0;let e=r.content.find(t=>t.type==="checkbox");return e&&e.attrs?e.attrs.checked!==!1:!0}async function $(r){let{requestState:e,responseState:t,metadata:n}=r;try{let s=e?.metadata?.editorDocument||n?.requestDocument||n?.editorDocument;if(!s)return;let o=v(s);if(o.length===0)return;let i=(typeof window<"u"?window:void 0)?.electron?.env?.replaceVariables;if(i)for(let a of o)a.expectedValue&&a.expectedValue.includes("{{")&&(a.expectedValue=await i(a.expectedValue)),a.field&&a.field.includes("{{")&&(a.field=await i(a.field));let c=t.body;if(typeof c=="string"&&c.trim())try{c=JSON.parse(c)}catch{}let p={response:{status:t.status,statusText:t.statusText,headers:t.headers||[],body:c,contentType:t.contentType,timing:t.timing}},f=S(o,p),u=f.filter(a=>a.passed).length,m=f.filter(a=>!a.passed).length;t.metadata||(t.metadata={}),t.metadata.assertionResults={results:f,totalAssertions:o.length,passedAssertions:u,failedAssertions:m}}catch(s){console.error("[Simple Assertions] Error in post-process assertions hook:",s)}}var k=A(()=>{"use strict";N()});var J={};w(J,{default:()=>z});module.exports=E(J);var H=r=>({onload(){r.pipeline.registerHook("pre-processing",async e=>{e.editor&&(e.requestState.metadata||(e.requestState.metadata={}),e.requestState.metadata.editorDocument=e.editor.getJSON())},5),r.pipeline.registerHook("post-processing",async e=>{let{postProcessAssertionsHook:t}=await Promise.resolve().then(()=>(k(),q));await t(e)},15),r.pipeline.registerHook("post-processing",async e=>{let t=e.responseState?.metadata?.assertionResults;if(t?.results?.length){e.responseState.metadata||(e.responseState.metadata={}),Array.isArray(e.responseState.metadata.reportEntries)||(e.responseState.metadata.reportEntries=[]);for(let n of t.results){let s=n.assertion?.description?.trim()||`${n.assertion?.field??""} ${n.assertion?.operator??""} ${n.assertion?.expectedValue??""}`.trim();e.responseState.metadata.reportEntries.push({type:"assertion",message:s||"Assertion",passed:n.passed,actual:n.actualValue,expected:n.assertion?.expectedValue,operator:n.assertion?.operator})}}},50)}}),z=H;
1
+ "use strict";var y=Object.defineProperty;var C=Object.getOwnPropertyDescriptor;var R=Object.getOwnPropertyNames;var T=Object.prototype.hasOwnProperty;var A=(r,e)=>()=>(r&&(e=r(r=0)),e);var w=(r,e)=>{for(var t in e)y(r,t,{get:e[t],enumerable:!0})},D=(r,e,t,n)=>{if(e&&typeof e=="object"||typeof e=="function")for(let s of R(e))!T.call(r,s)&&s!==t&&y(r,s,{get:()=>e[s],enumerable:!(n=C(e,s))||n.enumerable});return r};var W=r=>D(y({},"__esModule",{value:!0}),r);function v(r,e){let t=r.trim();if(t==="status"||t==="statusCode")return e.response.status;if(t==="statusText")return e.response.statusText;if(t==="responseTime"||t==="duration")return e.response.timing?.duration||0;if(t.startsWith("requestHeader.")||t.startsWith("requestHeaders.")){let s=t.split(".")[1];return e.request?.headers.find(i=>i.key.toLowerCase()===s.toLowerCase())?.value}if(t.startsWith("header.")||t.startsWith("headers.")){let n=t.split("."),s=n[1];if(s.toLowerCase()==="set-cookie"){let i=(0,x.parseCookies)(e.response.headers);if(n.length===2)return i;let c=n.slice(2).join(".");return l(i,c)}return e.response.headers.find(i=>i.key.toLowerCase()===s.toLowerCase())?.value}if(t==="body"||t==="response.body")return e.response.body;if(t.startsWith("body.")||t.startsWith("response.body.")){let n=t.replace(/^(response\.)?body\./,"");return l(e.response.body,n)}if(t.startsWith("response.")){let n=t.replace(/^response\./,"");return l(e.response,n)}return l(e.response.body,t)}function l(r,e){if(!r)return;let t=e.split(/\.|\[/).map(s=>s.replace(/\]$/,"")),n=r;for(let s of t){if(n==null)return;/^\d+$/.test(s)?n=n[parseInt(s,10)]:n=n[s]}return n}function E(r,e){try{if(r.enabled===!1)return{assertion:r,passed:!0,actualValue:null,error:"Skipped (disabled)"};let t=F(r.field),n=t.field,s=t.operator||r.operator||"equals",o=r.expectedValue,i=v(n,e),c=L(s,i,o);return{assertion:r,passed:c,actualValue:i}}catch(t){return{assertion:r,passed:!1,actualValue:null,error:t.message||String(t)}}}function F(r){let e=["equals","eq","==","===","not-equals","ne","!=","!==","contains","includes","not-contains","not-includes","starts-with","startswith","ends-with","endswith","matches","regex","exists","is-defined","not-exists","is-null","is-undefined","greater-than","gt",">","less-than","lt","<","greater-equal","gte",">=","less-equal","lte","<=","is-empty","empty","not-empty","is-truthy","truthy","is-falsy","falsy","type-is","typeof"],t=r.trim().split(/\s+/);if(t.length>=2){let n=t[t.length-1].toLowerCase();if(e.includes(n))return{field:t.slice(0,-1).join(" "),operator:n}}return{field:r.trim(),operator:null}}function L(r,e,t){switch(r.toLowerCase().trim()){case"equals":case"eq":case"==":case"===":return e==null?!1:String(e)===t;case"not-equals":case"ne":case"!=":case"!==":return e==null?!1:String(e)!==t;case"contains":case"includes":return e==null?!1:String(e).includes(t);case"not-contains":case"not-includes":return e==null?!1:!String(e).includes(t);case"starts-with":case"startswith":return e==null?!1:String(e).startsWith(t);case"ends-with":case"endswith":return e==null?!1:String(e).endsWith(t);case"matches":case"regex":if(e==null)return!1;try{return new RegExp(t).test(String(e))}catch{return!1}case"exists":case"is-defined":return e!=null;case"not-exists":case"is-null":case"is-undefined":return e==null;case"greater-than":case"gt":case">":{let s=Number(e),o=Number(t);return!isNaN(s)&&!isNaN(o)&&s>o}case"less-than":case"lt":case"<":{let s=Number(e),o=Number(t);return!isNaN(s)&&!isNaN(o)&&s<o}case"greater-equal":case"gte":case">=":{let s=Number(e),o=Number(t);return!isNaN(s)&&!isNaN(o)&&s>=o}case"less-equal":case"lte":case"<=":{let s=Number(e),o=Number(t);return!isNaN(s)&&!isNaN(o)&&s<=o}case"is-empty":case"empty":return e==null?!1:Array.isArray(e)?e.length===0:typeof e=="string"?e==="":typeof e=="object"?Object.keys(e).length===0:!1;case"not-empty":return e==null?!1:Array.isArray(e)?e.length>0:typeof e=="string"?e!=="":typeof e=="object"?Object.keys(e).length>0:!0;case"is-truthy":case"truthy":return!!e;case"is-falsy":case"falsy":return!e;case"type-is":case"typeof":return typeof e===t.toLowerCase();default:throw new Error(`Unknown operator: ${r}`)}}function S(r,e){return r.map(t=>E(t,e))}var x,q=A(()=>{"use strict";x=require("@voiden/sdk/shared")});var N={};w(N,{postProcessAssertionsHook:()=>P});function O(r){let e=[];if(!r||!r.content)return e;function t(n){if(n.type==="assertions-table"){let s=j(n);e.push(...s)}n.content&&Array.isArray(n.content)&&n.content.forEach(s=>t(s))}return t(r),e}function j(r){let e=[];try{if(r.attrs&&Array.isArray(r.attrs.rows)){let s=r.attrs.rows;for(let o of s)!o.description&&!o.field&&!o.operator&&!o.expectedValue||o.enabled!==!1&&e.push({description:o.description||"",field:o.field||"",operator:o.operator||"equals",expectedValue:o.expectedValue||"",enabled:!0});return e}let t=Array.isArray(r.content)?r.content.find(s=>s.type==="table"||s.type==="assertions-table"):null;if(!t)return e;let n=t.rows||t.content||[];for(let s=0;s<n.length;s++){let o=n[s];if(Array.isArray(o.row)){if(o.attrs?.disabled===!0)continue;let[a,h,g,b]=o.row;if(!a&&!h&&!g&&!b)continue;e.push({description:String(a||"").trim(),field:String(h||"").trim(),operator:String(g||"equals").trim()||"equals",expectedValue:String(b||"").trim(),enabled:!0});continue}if(o.type!=="tableRow"||o.attrs&&o.attrs.disabled===!0)continue;let i=o.content||[];if(i.length<4)continue;let c=f(i[0]).trim(),p=f(i[1]).trim(),d=f(i[2]).trim(),u=f(i[3]).trim();!c&&!p&&!d&&!u||!(!(i.length>=5)||H(i[4]))||e.push({description:c,field:p,operator:d||"equals",expectedValue:u,enabled:!0})}}catch(t){console.error("Error extracting assertions from table:",t)}return e}function f(r){return r?r.type==="text"?r.text||"":r.content&&Array.isArray(r.content)?r.content.map(e=>f(e)).join(""):"":""}function H(r){if(!r||!r.content)return!0;let e=r.content.find(t=>t.type==="checkbox");return e&&e.attrs?e.attrs.checked!==!1:!0}async function P(r){let{requestState:e,responseState:t,metadata:n}=r;try{let s=e?.metadata?.editorDocument||n?.requestDocument||n?.editorDocument;if(!s)return;let o=O(s);if(o.length===0)return;let i=(typeof window<"u"?window:void 0)?.electron?.env?.replaceVariables;if(i)for(let a of o)a.expectedValue&&a.expectedValue.includes("{{")&&(a.expectedValue=await i(a.expectedValue)),a.field&&a.field.includes("{{")&&(a.field=await i(a.field));let c=t.body;if(typeof c=="string"&&c.trim())try{c=JSON.parse(c)}catch{}let p={response:{status:t.status,statusText:t.statusText,headers:t.headers||[],body:c,contentType:t.contentType,timing:t.timing},request:{headers:t.requestMeta?.headers||[]}},d=S(o,p),u=d.filter(a=>a.passed).length,m=d.filter(a=>!a.passed).length;t.metadata||(t.metadata={}),t.metadata.assertionResults={results:d,totalAssertions:o.length,passedAssertions:u,failedAssertions:m}}catch(s){console.error("[Simple Assertions] Error in post-process assertions hook:",s)}}var k=A(()=>{"use strict";q()});var J={};w(J,{default:()=>z});module.exports=W(J);var $=r=>({onload(){r.pipeline.registerHook("pre-processing",async e=>{e.editor&&(e.requestState.metadata||(e.requestState.metadata={}),e.requestState.metadata.editorDocument=e.editor.getJSON())},5),r.pipeline.registerHook("post-processing",async e=>{let{postProcessAssertionsHook:t}=await Promise.resolve().then(()=>(k(),N));await t(e)},15),r.pipeline.registerHook("post-processing",async e=>{let t=e.responseState?.metadata?.assertionResults;if(t?.results?.length){e.responseState.metadata||(e.responseState.metadata={}),Array.isArray(e.responseState.metadata.reportEntries)||(e.responseState.metadata.reportEntries=[]);for(let n of t.results){let s=n.assertion?.description?.trim()||`${n.assertion?.field??""} ${n.assertion?.operator??""} ${n.assertion?.expectedValue??""}`.trim();e.responseState.metadata.reportEntries.push({type:"assertion",message:s||"Assertion",passed:n.passed,actual:n.actualValue,expected:n.assertion?.expectedValue,operator:n.assertion?.operator})}}},50)}}),z=$;
@@ -1,5 +1,5 @@
1
1
  {
2
- "simple-assertions": "1.0.5",
2
+ "simple-assertions": "1.1.0",
3
3
  "voiden-advanced-auth": "2.0.8",
4
4
  "voiden-faker": "1.1.1",
5
5
  "voiden-graphql": "1.0.7",
@@ -5,7 +5,7 @@
5
5
  * runs entirely in Node.js — no IPC, no Electron main process involved.
6
6
  *
7
7
  * Electron side: sendRequestHybrid(..., window.electron)
8
- * CLI side: sendRequestHybrid(..., createCliElectron(env))
8
+ * CLI side: sendRequestHybrid(..., createCliElectron(env, runtimeVars, projectRoot))
9
9
  *
10
10
  * request.sendSecure → delegates to executeSecureRequest from @voiden/executors
11
11
  * (same variable replacement + body building + HTTP execution)
@@ -14,13 +14,13 @@
14
14
  * runtime.* → stubs for UI-only hooks (preSend vars, linked blocks, etc.)
15
15
  */
16
16
  import type { RestApiRequestState } from '@voiden/sdk';
17
- export declare function createCliElectron(env: Record<string, string>, runtimeVars?: Record<string, any>): {
17
+ export declare function createCliElectron(env: Record<string, string>, runtimeVars?: Record<string, any>, projectRoot?: string): {
18
18
  isApp: boolean;
19
19
  request: {
20
20
  /**
21
21
  * Drop-in replacement for window.electron.request.sendSecure.
22
- * Injects __cliEnv so sendSecure can access the env map without
23
- * changing the RestApiRequestState interface.
22
+ * Injects __cliEnv/__cliProjectRoot so sendSecure can access them
23
+ * without changing the RestApiRequestState interface.
24
24
  */
25
25
  sendSecure: (requestState: RestApiRequestState, signalState?: any) => Promise<any>;
26
26
  };
@@ -1 +1 @@
1
- {"version":3,"file":"cliElectron.d.ts","sourceRoot":"","sources":["../src/cliElectron.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAIH,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,aAAa,CAAA;AA8EtD,wBAAgB,iBAAiB,CAAC,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,WAAW,GAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAM;;;QAK9F;;;;WAIG;mCACwB,mBAAmB,gBAAgB,GAAG;;;QAKjE,sFAAsF;iCAC7D,MAAM;;;QAI/B,gFAAgF;;;;;;QAKhF;;;;WAIG;gCACqB,mBAAmB;QAG3C,iEAAiE;2BAC9C,MAAM;QAEzB,mEAAmE;mCACxC,GAAG;QAE9B,mEAAmE;qCACtC,GAAG;QAEhC,yEAAyE;;;EAI9E;AAED,MAAM,MAAM,WAAW,GAAG,UAAU,CAAC,OAAO,iBAAiB,CAAC,CAAA"}
1
+ {"version":3,"file":"cliElectron.d.ts","sourceRoot":"","sources":["../src/cliElectron.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAIH,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,aAAa,CAAA;AAgHtD,wBAAgB,iBAAiB,CAAC,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,WAAW,GAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAM,EAAE,WAAW,CAAC,EAAE,MAAM;;;QAKpH;;;;WAIG;mCACwB,mBAAmB,gBAAgB,GAAG;;;QAKjE,sFAAsF;iCAC7D,MAAM;;;QAI/B,gFAAgF;;;;;;QAKhF;;;;WAIG;gCACqB,mBAAmB;QAG3C,iEAAiE;2BAC9C,MAAM;QAEzB,mEAAmE;mCACxC,GAAG;QAE9B,mEAAmE;qCACtC,GAAG;QAEhC,yEAAyE;;;EAI9E;AAED,MAAM,MAAM,WAAW,GAAG,UAAU,CAAC,OAAO,iBAAiB,CAAC,CAAA"}
@@ -5,7 +5,7 @@
5
5
  * runs entirely in Node.js — no IPC, no Electron main process involved.
6
6
  *
7
7
  * Electron side: sendRequestHybrid(..., window.electron)
8
- * CLI side: sendRequestHybrid(..., createCliElectron(env))
8
+ * CLI side: sendRequestHybrid(..., createCliElectron(env, runtimeVars, projectRoot))
9
9
  *
10
10
  * request.sendSecure → delegates to executeSecureRequest from @voiden/executors
11
11
  * (same variable replacement + body building + HTTP execution)
@@ -15,13 +15,45 @@
15
15
  */
16
16
  import { replaceEnvVars, executeSecureRequest } from '@voiden/executors';
17
17
  import { readFile } from 'node:fs/promises';
18
+ import { isAbsolute, join } from 'node:path';
18
19
  import { applyProcessVarsToState } from './runtimeVars.js';
20
+ /**
21
+ * Resolves a binary/multipart file field's stored path the same way
22
+ * apps/electron/src/main/ipc/request.ts's own readFile adapter does (see
23
+ * its own doc comment for the platform-specific "genuinely absolute" logic
24
+ * this mirrors) — this CLI adapter used to just pass the raw path straight
25
+ * to fs.readFile with no project-relative resolution and no fallback at
26
+ * all, which broke any .void file's binary/multipart-table file field
27
+ * whose stored path used the app's own legacy "/subfolder/file.png"
28
+ * project-relative convention (a leading slash that isn't actually
29
+ * filesystem-root — .void files created by the app can and do use this).
30
+ * Kept in sync manually since this package has no runtime dependency on
31
+ * Electron to import the original from.
32
+ */
33
+ async function readProjectFile(filePath, projectRoot) {
34
+ const isGenuinelyAbsolute = process.platform === 'win32'
35
+ ? /^([A-Za-z]:[/\\]|[/\\]{2})/.test(filePath)
36
+ : isAbsolute(filePath);
37
+ if (projectRoot && !isGenuinelyAbsolute) {
38
+ return readFile(join(projectRoot, filePath));
39
+ }
40
+ try {
41
+ return await readFile(filePath);
42
+ }
43
+ catch (err) {
44
+ if (err?.code === 'ENOENT' && projectRoot) {
45
+ return readFile(join(projectRoot, filePath));
46
+ }
47
+ throw err;
48
+ }
49
+ }
19
50
  // ─── Core sendSecure — delegates to the shared executor ───────────────────────
20
51
  async function sendSecure(requestState, _signalState) {
21
52
  const env = requestState.__cliEnv ?? {};
53
+ const projectRoot = requestState.__cliProjectRoot;
22
54
  const adapter = {
23
55
  replaceVar: (text) => Promise.resolve(replaceEnvVars(text, env)),
24
- readFile: (filePath) => readFile(filePath),
56
+ readFile: (filePath) => readProjectFile(filePath, projectRoot),
25
57
  isElectron: false, // CLI: connect inline and return a report in the body
26
58
  };
27
59
  try {
@@ -80,16 +112,16 @@ async function sendSecure(requestState, _signalState) {
80
112
  }
81
113
  }
82
114
  // ─── Public factory ───────────────────────────────────────────────────────────
83
- export function createCliElectron(env, runtimeVars = {}) {
115
+ export function createCliElectron(env, runtimeVars = {}, projectRoot) {
84
116
  return {
85
117
  isApp: false,
86
118
  request: {
87
119
  /**
88
120
  * Drop-in replacement for window.electron.request.sendSecure.
89
- * Injects __cliEnv so sendSecure can access the env map without
90
- * changing the RestApiRequestState interface.
121
+ * Injects __cliEnv/__cliProjectRoot so sendSecure can access them
122
+ * without changing the RestApiRequestState interface.
91
123
  */
92
- sendSecure: (requestState, signalState) => sendSecure({ ...requestState, __cliEnv: env }, signalState),
124
+ sendSecure: (requestState, signalState) => sendSecure({ ...requestState, __cliEnv: env, __cliProjectRoot: projectRoot }, signalState),
93
125
  },
94
126
  env: {
95
127
  /** Drop-in for window.electron.env.replaceVariables (used in auth header building) */
@@ -1 +1 @@
1
- {"version":3,"file":"cliElectron.js","sourceRoot":"","sources":["../src/cliElectron.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"cliElectron.js","sourceRoot":"","sources":["../src/cliElectron.ts"],"names":[],"mappings":"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"}
package/dist/envFile.d.ts CHANGED
@@ -1,3 +1,12 @@
1
+ /**
2
+ * Structurally merges two parsed YAML env trees (e.g. a profile's public +
3
+ * private content) — `b`'s `variables:` win over `a`'s per node on key
4
+ * conflict (matches the app's own public/private precedence, see env.ts's
5
+ * loadYamlEnvironments), `children:` are merged recursively rather than one
6
+ * replacing the other wholesale, so a child defined only in `a` still shows
7
+ * up even if `b` also defines siblings under the same parent.
8
+ */
9
+ export declare function mergeYamlEnvTrees(a: unknown, b: unknown): Record<string, unknown>;
1
10
  /**
2
11
  * `environmentName`, when given, scopes YAML loading to exactly one named
3
12
  * environment (e.g. "dev") instead of the default "flatten every
@@ -10,4 +19,21 @@
10
19
  * treated as an error, since there's genuinely nothing to scope to.
11
20
  */
12
21
  export declare function loadEnvFile(envPath: string, environmentName?: string): Record<string, string>;
22
+ /**
23
+ * Navigates a tree by an exact dotted path (as produced by
24
+ * listYamlEnvironmentNames, e.g. "staging.eu") rather than searching for a
25
+ * bare key anywhere — unlike findEnvironment above (kept as-is for the
26
+ * CLI's existing --environment <name> flag, which intentionally matches by
27
+ * bare name wherever it occurs), a dotted path must resolve deterministically:
28
+ * two different parents can each have a child literally named "eu", and
29
+ * only a full-path walk tells them apart. Same inheritance order (each
30
+ * segment's own variables merge on top of everything above it).
31
+ */
32
+ export declare function findEnvironmentByPath(tree: Record<string, unknown>, dottedPath: string): Record<string, string> | null;
33
+ /** Every named environment in the tree, at any depth, as dotted paths
34
+ * (e.g. "staging", "staging.eu") — unlike topLevelEnvironmentNames, this
35
+ * IS meant to show the full nested shape (used by list_environments to
36
+ * show a profile's environment hierarchy, not just an error hint). */
37
+ export declare function listYamlEnvironmentNames(content: string): string[];
38
+ export declare function parseYamlEnv(content: string, environmentName?: string): Record<string, string>;
13
39
  //# sourceMappingURL=envFile.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"envFile.d.ts","sourceRoot":"","sources":["../src/envFile.ts"],"names":[],"mappings":"AASA;;;;;;;;;;GAUG;AACH,wBAAgB,WAAW,CAAC,OAAO,EAAE,MAAM,EAAE,eAAe,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAS7F"}
1
+ {"version":3,"file":"envFile.d.ts","sourceRoot":"","sources":["../src/envFile.ts"],"names":[],"mappings":"AASA;;;;;;;GAOG;AACH,wBAAgB,iBAAiB,CAAC,CAAC,EAAE,OAAO,EAAE,CAAC,EAAE,OAAO,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAqBjF;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,WAAW,CAAC,OAAO,EAAE,MAAM,EAAE,eAAe,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAS7F;AA6DD;;;;;;;;;GASG;AACH,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,UAAU,EAAE,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,IAAI,CAWtH;AAED;;;uEAGuE;AACvE,wBAAgB,wBAAwB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,EAAE,CAiBlE;AAED,wBAAgB,YAAY,CAAC,OAAO,EAAE,MAAM,EAAE,eAAe,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAsC9F"}
package/dist/envFile.js CHANGED
@@ -1,6 +1,39 @@
1
1
  import { readFileSync } from 'fs';
2
2
  import { extname } from 'path';
3
3
  import YAML from 'yaml';
4
+ /**
5
+ * Structurally merges two parsed YAML env trees (e.g. a profile's public +
6
+ * private content) — `b`'s `variables:` win over `a`'s per node on key
7
+ * conflict (matches the app's own public/private precedence, see env.ts's
8
+ * loadYamlEnvironments), `children:` are merged recursively rather than one
9
+ * replacing the other wholesale, so a child defined only in `a` still shows
10
+ * up even if `b` also defines siblings under the same parent.
11
+ */
12
+ export function mergeYamlEnvTrees(a, b) {
13
+ const treeA = a && typeof a === 'object' && !Array.isArray(a) ? a : {};
14
+ const treeB = b && typeof b === 'object' && !Array.isArray(b) ? b : {};
15
+ const keys = new Set([...Object.keys(treeA), ...Object.keys(treeB)]);
16
+ const result = {};
17
+ for (const key of keys) {
18
+ const nodeA = treeA[key];
19
+ const nodeB = treeB[key];
20
+ const isNodeA = nodeA != null && typeof nodeA === 'object' && !Array.isArray(nodeA);
21
+ const isNodeB = nodeB != null && typeof nodeB === 'object' && !Array.isArray(nodeB);
22
+ if (!isNodeA && !isNodeB) {
23
+ result[key] = nodeB ?? nodeA;
24
+ continue;
25
+ }
26
+ const a2 = (isNodeA ? nodeA : {});
27
+ const b2 = (isNodeB ? nodeB : {});
28
+ result[key] = {
29
+ variables: { ...(a2.variables ?? {}), ...(b2.variables ?? {}) },
30
+ ...(a2.children || b2.children
31
+ ? { children: mergeYamlEnvTrees(a2.children ?? {}, b2.children ?? {}) }
32
+ : {}),
33
+ };
34
+ }
35
+ return result;
36
+ }
4
37
  /**
5
38
  * `environmentName`, when given, scopes YAML loading to exactly one named
6
39
  * environment (e.g. "dev") instead of the default "flatten every
@@ -78,7 +111,54 @@ function topLevelEnvironmentNames(tree) {
78
111
  .filter(([, value]) => value != null && typeof value === 'object' && !Array.isArray(value))
79
112
  .map(([key]) => key);
80
113
  }
81
- function parseYamlEnv(content, environmentName) {
114
+ /**
115
+ * Navigates a tree by an exact dotted path (as produced by
116
+ * listYamlEnvironmentNames, e.g. "staging.eu") rather than searching for a
117
+ * bare key anywhere — unlike findEnvironment above (kept as-is for the
118
+ * CLI's existing --environment <name> flag, which intentionally matches by
119
+ * bare name wherever it occurs), a dotted path must resolve deterministically:
120
+ * two different parents can each have a child literally named "eu", and
121
+ * only a full-path walk tells them apart. Same inheritance order (each
122
+ * segment's own variables merge on top of everything above it).
123
+ */
124
+ export function findEnvironmentByPath(tree, dottedPath) {
125
+ let current = tree;
126
+ let resolved = {};
127
+ for (const segment of dottedPath.split('.')) {
128
+ const value = current[segment];
129
+ if (value === null || value === undefined || Array.isArray(value) || typeof value !== 'object')
130
+ return null;
131
+ const node = value;
132
+ resolved = { ...resolved, ...ownVariables(node) };
133
+ current = (node.children ?? {});
134
+ }
135
+ return resolved;
136
+ }
137
+ /** Every named environment in the tree, at any depth, as dotted paths
138
+ * (e.g. "staging", "staging.eu") — unlike topLevelEnvironmentNames, this
139
+ * IS meant to show the full nested shape (used by list_environments to
140
+ * show a profile's environment hierarchy, not just an error hint). */
141
+ export function listYamlEnvironmentNames(content) {
142
+ const parsed = YAML.parse(content);
143
+ if (!parsed || typeof parsed !== 'object' || Array.isArray(parsed))
144
+ return [];
145
+ const names = [];
146
+ const walk = (tree, prefix) => {
147
+ for (const [key, value] of Object.entries(tree)) {
148
+ if (value === null || value === undefined || Array.isArray(value) || typeof value !== 'object')
149
+ continue;
150
+ const path = prefix ? `${prefix}.${key}` : key;
151
+ names.push(path);
152
+ const node = value;
153
+ if (node.children != null && typeof node.children === 'object') {
154
+ walk(node.children, path);
155
+ }
156
+ }
157
+ };
158
+ walk(parsed, '');
159
+ return names;
160
+ }
161
+ export function parseYamlEnv(content, environmentName) {
82
162
  const parsed = YAML.parse(content);
83
163
  if (!parsed || typeof parsed !== 'object' || Array.isArray(parsed))
84
164
  return {};
@@ -1 +1 @@
1
- {"version":3,"file":"envFile.js","sourceRoot":"","sources":["../src/envFile.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"envFile.js","sourceRoot":"","sources":["../src/envFile.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,69 @@
1
+ /**
2
+ * Headless env-profile discovery/resolution for the `list_environments`/
3
+ * `select_environment` fixed MCP tools (mcpServing.ts). A deliberately
4
+ * simplified port of apps/electron/src/main/env.ts's profile logic — same
5
+ * precedent as plugins/voiden-mcp-tool/src/lib/toolCapability.ts's
6
+ * loadProjectEnvironmentVars, which already does this for its own narrower
7
+ * needs. No Electron dependency (this package is a standalone CLI/library),
8
+ * no UI "active profile" state, no nested sub-project scanning, no legacy
9
+ * dotted `.env.foo.bar` hierarchy chain — see mcpServing.ts's callers for
10
+ * what's actually needed here.
11
+ */
12
+ export interface EnvProfileInfo {
13
+ name: string;
14
+ source: 'yaml' | 'legacy-dotenv';
15
+ /** Present only when source === 'yaml' and the file actually exists. */
16
+ publicFile?: string;
17
+ privateFile?: string;
18
+ /** Dotted environment paths (e.g. "staging", "staging.eu") — only when source === 'yaml'. */
19
+ environments?: string[];
20
+ /** Discovered .env* files (project root + .voiden/) — only when source === 'legacy-dotenv'. */
21
+ dotEnvFiles?: string[];
22
+ }
23
+ export declare function discoverEnvProfiles(projectRoot: string): EnvProfileInfo[];
24
+ /** Resolves the final variable map for one profile (+ optional named
25
+ * environment within it). Throws if the profile doesn't exist or the
26
+ * named environment isn't found in it (same "available: ..." style error
27
+ * envFile.ts's own parseYamlEnv already throws for an unknown name). */
28
+ export declare function resolveEnvProfile(projectRoot: string, profile: string, environmentName?: string): Record<string, string>;
29
+ export interface EnvCliOpts {
30
+ /** Path to one plain .env (dotenv) file — for a file outside the
31
+ * project's profile convention entirely (e.g. a CI-provided secrets
32
+ * path). Deliberately NOT for YAML: a real profile is always a *pair*
33
+ * of files (env-<profile>-public.yaml + -private.yaml, merged), which a
34
+ * single --env path could never represent correctly anyway — that's
35
+ * what --profile is for. */
36
+ env?: string;
37
+ /** Which profile to use — same profile system list_environments/
38
+ * select_environment already expose to an MCP agent, now also reachable
39
+ * from the command line instead of only knowing a raw file path. `true`
40
+ * (commander's value for a bare flag with no argument) means "default",
41
+ * the same profile discoverEnvProfiles/resolveEnvProfile already treat
42
+ * as the unnamed one. */
43
+ profile?: string | true;
44
+ /** Scopes either of the above down to one named environment inside
45
+ * whichever file/profile was actually loaded. */
46
+ environment?: string;
47
+ }
48
+ /** Thrown by resolveCliEnv for a usage mistake (not found, ambiguous
49
+ * flags) — callers already wrap their existing --env loading in a
50
+ * try/catch that prints the message and exits with EXIT_USAGE_ERROR; this
51
+ * just gives that same catch something to catch for the --profile path
52
+ * too, instead of duplicating that error-reporting shape here. */
53
+ export declare class EnvCliOptsError extends Error {
54
+ }
55
+ /**
56
+ * Resolves the env-selection flags shared across voiden-runner's
57
+ * run/mcp serve/tool verify commands into a merged variable map, layered on
58
+ * top of whatever base env the caller already has (typically process.env).
59
+ *
60
+ * Two independent ways to point at variables — --profile and --env — are
61
+ * deliberately mutually exclusive: mixing "use the profile system" and
62
+ * "use this one specific file instead" has no obvious shared meaning, so
63
+ * this throws rather than silently picking one. Passing neither is
64
+ * unchanged from before this existed: nothing gets loaded, only baseEnv
65
+ * comes back — an existing invocation with no env flags at all keeps
66
+ * working exactly as it did.
67
+ */
68
+ export declare function resolveCliEnv(opts: EnvCliOpts, projectRoot: string, baseEnv: Record<string, string>): Record<string, string>;
69
+ //# sourceMappingURL=envProfiles.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"envProfiles.d.ts","sourceRoot":"","sources":["../src/envProfiles.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAUH,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,MAAM,CAAA;IACZ,MAAM,EAAE,MAAM,GAAG,eAAe,CAAA;IAChC,wEAAwE;IACxE,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,6FAA6F;IAC7F,YAAY,CAAC,EAAE,MAAM,EAAE,CAAA;IACvB,+FAA+F;IAC/F,WAAW,CAAC,EAAE,MAAM,EAAE,CAAA;CACvB;AAoDD,wBAAgB,mBAAmB,CAAC,WAAW,EAAE,MAAM,GAAG,cAAc,EAAE,CAyBzE;AAED;;;yEAGyE;AACzE,wBAAgB,iBAAiB,CAC/B,WAAW,EAAE,MAAM,EACnB,OAAO,EAAE,MAAM,EACf,eAAe,CAAC,EAAE,MAAM,GACvB,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CA4CxB;AAED,MAAM,WAAW,UAAU;IACzB;;;;;iCAK6B;IAC7B,GAAG,CAAC,EAAE,MAAM,CAAA;IACZ;;;;;8BAK0B;IAC1B,OAAO,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IACvB;sDACkD;IAClD,WAAW,CAAC,EAAE,MAAM,CAAA;CACrB;AAED;;;;mEAImE;AACnE,qBAAa,eAAgB,SAAQ,KAAK;CAAG;AAE7C;;;;;;;;;;;;GAYG;AACH,wBAAgB,aAAa,CAC3B,IAAI,EAAE,UAAU,EAChB,WAAW,EAAE,MAAM,EACnB,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAC9B,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAyCxB"}