@north-light/crouter 0.3.347 → 0.3.349

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.
@@ -1 +1 @@
1
- var z=Object.defineProperty;var v=(e,o)=>z(e,"name",{value:o,configurable:!0});import{isRecord as x}from"../../shared/predicates.js";const B=new Set(["normal","common","important"]),I=new Set(["string","int","bool","path","enum"]),U=/^[a-z][a-z0-9]*(-[a-z0-9]+)*$/,N=new Set(["kind","name","description","whenToUse","tier","rootEntry","extensible","summary","model","children"]),V=new Set([...N,"passthrough"]),Z=new Set(["bin","installHint"]),O=new Set(["kind","name","description","whenToUse","tier","summary","params","output","effects"]),L=new Set([...O,"outputKind"]),W=new Set([...O,"rest"]),X=new Set(["concept","description","whenToUse"]),J=new Set(["text","base64"]),H={positional:new Set(["kind","name","type","required","constraint","repeatable","encoding","defaultFromEnv"]),flag:new Set(["kind","name","type","choices","required","constraint","default","repeatable","encoding","defaultFromEnv"]),stdin:new Set(["kind","name","required","constraint"]),"context-file":new Set(["kind","name","required","constraint","shape"])},Q=new Set(["name","type","required","constraint"]),w=/^[A-Z][A-Z0-9_]*$/;function m(e){return e===null?"null":Array.isArray(e)?"array":typeof e}v(m,"typeName");function R(e,o,t,n){const a=Object.keys(e).filter(l=>!o.has(l));return a.length>0?(n("command_node_invalid","unknown keys",a.join(", "),`only: ${[...o].join(", ")}`,"Remove the unknown keys.",t),!1):!0}v(R,"checkKeys");function ee(e,o,t){if(!x(e))return t("command_node_invalid","rootEntry must be an object",m(e),"a { concept, description, whenToUse } object","Fix rootEntry.",o),null;if(!R(e,X,o,t))return null;for(const n of["concept","description","whenToUse"])if(typeof e[n]!="string"||e[n].length===0)return t("command_node_invalid",`rootEntry.${n} must be a non-empty string`,m(e[n]),"a non-empty string",`Add rootEntry.${n}.`,`${o}.${n}`),null;return{concept:e.concept,description:e.description,whenToUse:e.whenToUse}}v(ee,"validateRootEntry");function ne(e,o,t){if(e===void 0)return[];if(!Array.isArray(e))return t("command_node_invalid","params must be an array",m(e),"an array of params (or omitted)","Fix params.",o),null;const n=[],a=new Set;let l=0;for(let s=0;s<e.length;s++){const r=e[s],d=`${o}[${s}]`;if(!x(r))return t("command_node_invalid","param must be an object",m(r),"a param object","Fix the param.",d),null;const g=r.kind;if(typeof g!="string"||!(g in H))return t("command_node_invalid","param kind must be positional|flag|stdin|context-file",String(g),"positional | flag | stdin | context-file","Fix the param kind.",`${d}.kind`),null;if(!R(r,H[g],d,t))return null;const p=r.name;if(typeof p!="string"||!U.test(p))return t("command_node_invalid","param name must be a kebab-case token",String(p),"a kebab-case token","Rename the param.",`${d}.name`),null;if(a.has(p))return t("command_node_invalid","duplicate param name",p,"unique param names","Rename the duplicate param.",`${d}.name`),null;if(a.add(p),typeof r.required!="boolean")return t("command_node_invalid","param required must be a boolean",m(r.required),"true | false","Set required.",`${d}.required`),null;if(typeof r.constraint!="string")return t("command_node_invalid","param constraint must be a string",m(r.constraint),"an inline constraint string","Add a constraint.",`${d}.constraint`),null;if(g==="positional"){if(l++,l>1)return t("command_node_invalid","a leaf may declare at most one positional","multiple positionals","at most one positional param","Convert extra positionals to flags.",d),null;if(r.type!==void 0&&r.type!=="string"&&r.type!=="path")return t("command_node_invalid","positional type must be string|path",String(r.type),"string | path | omitted","Fix the positional type.",`${d}.type`),null;let y=!1;if(r.repeatable!==void 0){if(typeof r.repeatable!="boolean")return t("command_node_invalid","repeatable must be a boolean",m(r.repeatable),"true | false | omitted","Fix repeatable.",`${d}.repeatable`),null;y=r.repeatable}const _=C(r,d,t);if(_===null)return null;const c=M(r,d,t);if(c===null)return null;if(y&&c!==void 0)return t("command_node_invalid","repeatable positional must not declare defaultFromEnv",p,"no defaultFromEnv on a repeatable positional (values accumulate into an array)","Remove defaultFromEnv, or drop repeatable.",`${d}.defaultFromEnv`),null;n.push({kind:"positional",name:p,...r.type!==void 0?{type:r.type}:{},required:r.required,constraint:r.constraint,...y?{repeatable:!0}:{},..._!==void 0?{encoding:_}:{},...c!==void 0?{defaultFromEnv:c}:{}})}else if(g==="stdin")n.push({kind:"stdin",name:p,required:r.required,constraint:r.constraint});else if(g==="context-file")n.push({kind:"context-file",name:p,required:r.required,constraint:r.constraint,...typeof r.shape=="string"?{shape:r.shape}:{}});else if(g==="flag"){const y=r.type;if(typeof y!="string"||!I.has(y))return t("command_node_invalid","flag type must be string|int|bool|path|enum",String(y),"string | int | bool | path | enum","Fix the flag type.",`${d}.type`),null;let _;if(y==="enum"){const f=r.choices;if(!Array.isArray(f)||f.length===0||!f.every(k=>typeof k=="string"))return t("command_node_invalid","enum flag requires a non-empty string choices array",m(f),"a non-empty array of strings","Declare choices for the enum flag.",`${d}.choices`),null;_=f}else if(r.choices!==void 0)return t("command_node_invalid","choices is only valid on an enum flag","choices","no choices unless type is enum","Remove choices.",`${d}.choices`),null;let c=!1;if(r.repeatable!==void 0){if(typeof r.repeatable!="boolean")return t("command_node_invalid","repeatable must be a boolean",m(r.repeatable),"true | false | omitted","Fix repeatable.",`${d}.repeatable`),null;c=r.repeatable}if(c&&(y==="bool"||y==="path"))return t("command_node_invalid",`repeatable is not valid on a ${y} flag`,`${p}: ${y}`,"repeatable only on string | int | enum flags","Remove repeatable or change the flag type.",`${d}.repeatable`),null;if(c&&r.default!==void 0)return t("command_node_invalid","repeatable flag must not declare a default",p,"no default on a repeatable flag (values accumulate into an array)","Remove the default.",`${d}.default`),null;const $=C(r,d,t);if($===null)return null;const E=M(r,d,t);if(E===null)return null;if(c&&E!==void 0)return t("command_node_invalid","repeatable flag must not declare defaultFromEnv",p,"no defaultFromEnv on a repeatable flag (values accumulate into an array)","Remove defaultFromEnv, or drop repeatable.",`${d}.defaultFromEnv`),null;n.push({kind:"flag",name:p,type:y,..._!==void 0?{choices:_}:{},...$!==void 0?{encoding:$}:{},required:r.required,constraint:r.constraint,...r.default!==void 0?{default:r.default}:{},...c?{repeatable:!0}:{},...E!==void 0?{defaultFromEnv:E}:{}})}}return n}v(ne,"validateParams");function C(e,o,t){const n=e.encoding;if(n!==void 0)return typeof n!="string"||!J.has(n)?(t("command_node_invalid","param encoding must be text|base64",String(n),"text | base64 | omitted","Fix the encoding.",`${o}.encoding`),null):e.type!=="path"?(t("command_node_invalid",'encoding is only valid on a type:"path" param',`type ${String(e.type)}`,'type: "path"','Set the param type to "path", or remove encoding.',`${o}.encoding`),null):n}v(C,"validateFileEncoding");function M(e,o,t){const n=e.defaultFromEnv;if(n===void 0)return;if(typeof n!="string"||!w.test(n))return t("command_node_invalid","defaultFromEnv must name an environment variable in UPPER_SNAKE_CASE",String(n),'e.g. "CRTR_NODE_ID"',"Fix the environment variable name.",`${o}.defaultFromEnv`),null;const a=e.type===void 0&&e.kind==="positional"?"string":e.type;return a!=="string"&&a!=="path"?(t("command_node_invalid","defaultFromEnv is only valid on a string|path param",`type ${String(e.type)}`,'type: "string" | "path"',"Change the param type, or remove defaultFromEnv.",`${o}.defaultFromEnv`),null):e.default!==void 0?(t("command_node_invalid","a param must not declare both default and defaultFromEnv",`${String(e.name)}: default + defaultFromEnv`,"exactly one default source","Remove one \u2014 defaultFromEnv counts as supplied, a static default does not.",`${o}.defaultFromEnv`),null):n}v(M,"validateDefaultFromEnv");function te(e,o,t){if(!Array.isArray(e))return t("command_node_invalid","output must be an array",m(e),"an array of output fields","Declare the leaf output fields.",o),null;const n=[];for(let a=0;a<e.length;a++){const l=e[a],s=`${o}[${a}]`;if(!x(l))return t("command_node_invalid","output field must be an object",m(l),"a { name, type, required, constraint } object","Fix the output field.",s),null;if(!R(l,Q,s,t))return null;if(typeof l.name!="string"||l.name.length===0)return t("command_node_invalid","output field name must be a non-empty string",m(l.name),"a field name","Add a name.",`${s}.name`),null;if(typeof l.type!="string"||l.type.length===0)return t("command_node_invalid","output field type must be a non-empty string",m(l.type),"a type name","Add a type.",`${s}.type`),null;if(typeof l.required!="boolean")return t("command_node_invalid","output field required must be a boolean",m(l.required),"true | false","Set required.",`${s}.required`),null;if(typeof l.constraint!="string")return t("command_node_invalid","output field constraint must be a string",m(l.constraint),"a constraint string","Add a constraint.",`${s}.constraint`),null;n.push({name:l.name,type:l.type,required:l.required,constraint:l.constraint})}return n}v(te,"validateOutput");function G(e,o,t){const n=e.name;return typeof n!="string"||!U.test(n)?(t("command_node_invalid","node name must be a lowercase kebab-case token",String(n),'a kebab-case token like "app" or "list-all"',"Rename the node.",`${o}.name`),!1):typeof e.description!="string"||e.description.length===0?(t("command_node_invalid","node description must be a non-empty string",m(e.description),"a short parent-listing description","Add a description.",`${o}.description`),!1):typeof e.whenToUse!="string"||e.whenToUse.length===0?(t("command_node_invalid","node whenToUse must be a non-empty string",m(e.whenToUse),"a parent selection rubric","Add a whenToUse rubric.",`${o}.whenToUse`),!1):e.tier!==void 0&&!B.has(String(e.tier))?(t("command_node_invalid","node tier must be normal|common|important",String(e.tier),"normal | common | important","Fix or omit tier (external plugins cannot declare hidden commands).",`${o}.tier`),!1):!0}v(G,"checkCommon");function ae(e,o,t,n,a,l={}){const s=o.join(".");if(!x(e))return a("command_node_invalid","node must be an object",m(e),"a branch or leaf node object","Fix the node.",s),null;const r=e.kind;return r==="branch"?oe(e,s,t,n,a,l):r==="leaf"?t&&l.topLevelRootEntry!=="forbidden"?(a("command_node_invalid","top-level node must be a branch","leaf","a branch node with a rootEntry","Wrap the command in a top-level branch (noun) with a rootEntry.",`${s}.kind`),null):ie(e,s,n,a):(a("command_node_invalid",'node kind must be "branch" or "leaf"',String(r),"branch | leaf","Set kind to branch or leaf.",`${s}.kind`),null)}v(ae,"validateCommandNode");function oe(e,o,t,n,a,l){const s=l.allowPassthrough!==!1;if(!R(e,n==="exec"&&s?V:N,o,a)||!G(e,o,a))return null;const d=e.rootEntry!==void 0,g=l.topLevelRootEntry??"required";if(t&&g==="required"&&!d)return a("command_node_invalid","top-level branch requires a rootEntry","(missing)","a rootEntry { concept, description, whenToUse }","Add a rootEntry to the top-level branch.",`${o}.rootEntry`),null;if((!t||g==="forbidden")&&d)return a("command_node_invalid",t?"repository fragment root must not declare a rootEntry":"nested branch must not declare a rootEntry","rootEntry",t?"no rootEntry (the owning plugin branch already has one)":"no rootEntry (only top-level branches carry one)",t?"Remove rootEntry from the repository fragment root.":"Remove rootEntry from the nested branch.",`${o}.rootEntry`),null;const p=e.extensible!==void 0;if(p&&(!t||l.allowExtensible===!1||e.extensible!==!0))return a("command_node_invalid",t?"extensible must be exactly true on a plugin top-level branch":"extensible is valid only on a top-level branch mount",String(e.extensible),t?"extensible: true":"no extensible marker on nested branches",t?"Set extensible to true or remove it.":"Move the marker to the plugin top-level branch or remove it.",`${o}.extensible`),null;let y;if(d){const f=ee(e.rootEntry,`${o}.rootEntry`,a);if(f===null)return null;y=f}if(typeof e.summary!="string"||e.summary.length===0)return a("command_node_invalid","branch summary must be a non-empty string",m(e.summary),"a one-line summary string","Add a summary.",`${o}.summary`),null;if(e.model!==void 0&&typeof e.model!="string")return a("command_node_invalid","branch model must be a string",m(e.model),"a string or omitted","Fix or remove model.",`${o}.model`),null;let _;if(n==="exec"&&e.passthrough!==void 0){const f=re(e.passthrough,`${o}.passthrough`,a);if(f===null)return null;_=f}if(p&&_!==void 0)return a("command_node_invalid","an extensible branch cannot declare passthrough","extensible and passthrough","one branch mode: extensible or passthrough","Remove passthrough or remove extensible.",o),null;const c=e.children;if(_!==void 0){if(!Array.isArray(c)||c.length!==0)return a("command_node_invalid","a passthrough branch must declare children: []",Array.isArray(c)?`${c.length} children`:m(c),"an empty children array","Set children to [] \u2014 a passthrough branch forwards all argv and can own no subcommands.",`${o}.children`),null}else if(!Array.isArray(c))return a("command_node_invalid","branch children must be an array",m(c),"an array of branch/leaf nodes (may be empty for populated by mounts)","Fix children.",`${o}.children`),null;const $=[],E=new Set;for(let f=0;f<c.length;f++){const k=ae(c[f],[...o.split("."),`children[${f}]`],!1,n,a,l);if(k===null)return null;if(E.has(k.name))return a("command_node_invalid","duplicate child name",k.name,"unique child names within a branch","Rename the duplicate child.",`${o}.children[${f}].name`),null;E.add(k.name),$.push(k)}return{kind:"branch",name:e.name,description:e.description,whenToUse:e.whenToUse,...e.tier!==void 0?{tier:e.tier}:{},...y!==void 0?{rootEntry:y}:{},...p?{extensible:!0}:{},summary:e.summary,...e.model!==void 0?{model:e.model}:{},..._!==void 0?{passthrough:_}:{},children:$}}v(oe,"validateBranch");function re(e,o,t){if(!x(e))return t("command_node_invalid","passthrough must be an object",m(e),"an object { bin, installHint }","Fix or remove passthrough.",o),null;if(!R(e,Z,o,t))return null;for(const n of["bin","installHint"])if(typeof e[n]!="string"||e[n].length===0)return t("command_node_invalid",`passthrough ${n} must be a non-empty string`,m(e[n]),n==="bin"?"the external binary name":"a one-line install hint",`Set passthrough.${n}.`,`${o}.${n}`),null;return{bin:e.bin,installHint:e.installHint}}v(re,"validatePassthrough");function ie(e,o,t,n){if(!R(e,t==="exec"?L:W,o,n)||!G(e,o,n))return null;if(typeof e.summary!="string"||e.summary.length===0)return n("command_node_invalid","leaf summary must be a non-empty string",m(e.summary),"a one-line summary string","Add a summary.",`${o}.summary`),null;if(t==="exec"&&e.outputKind!=="object")return n("command_node_invalid",'leaf outputKind must be "object" in v1',String(e.outputKind),'exactly "object"','Set outputKind to "object".',`${o}.outputKind`),null;if(t==="http"&&e.rest===void 0)return n("command_node_invalid","HTTP leaf requires a rest mapping","(missing)","a rest object with method, path, and params","Add a rest mapping.",`${o}.rest`),null;const a=ne(e.params,`${o}.params`,n);if(a===null)return null;const l=te(e.output,`${o}.output`,n);if(l===null)return null;const s=e.effects;if(!Array.isArray(s)||s.length===0||!s.every(g=>typeof g=="string"))return n("command_node_invalid","leaf effects must be a non-empty string array",m(s),'a non-empty array of strings (["None. Read-only."] for read-only leaves)',"Declare every persistent effect.",`${o}.effects`),null;const r={kind:"leaf",name:e.name,description:e.description,whenToUse:e.whenToUse,...e.tier!==void 0?{tier:e.tier}:{},summary:e.summary,params:a,output:l,effects:s};if(t==="exec")return{...r,outputKind:"object"};const d=se(e.rest,o,a,n);return d===null?null:{...r,rest:d}}v(ie,"validateLeaf");const le=new Set(["GET","POST","PUT","PATCH","DELETE"]),de=/^[!#$%&'*+\-.^_`|~0-9A-Za-z]+$/,me=new Set(["path","query","body","header"]);function se(e,o,t,n){const a=`${o}.rest`;if(!x(e))return n("command_rest_invalid","rest must be an object",m(e),"{ method, path, streaming?, params }","Provide a valid rest mapping.",a),null;const l=new Set(["method","path","streaming","body","bodyRoot","params"]),s=Object.keys(e).filter(i=>!l.has(i));if(s.length>0)return n("command_rest_invalid","unknown rest keys",s.join(", "),"only: method, path, streaming, body, bodyRoot, params","Remove the unknown keys.",a),null;const r=e.method;if(typeof r!="string"||!le.has(r))return n("command_rest_invalid","method must be GET|POST|PUT|PATCH|DELETE",String(r),"one of the HTTP methods","Set method to a valid HTTP verb.",`${a}.method`),null;const d=e.path;if(typeof d!="string"||!d.startsWith("/"))return n("command_rest_invalid","path must be an absolute path starting with /",String(d),'an absolute path like "/v1/devices/{id}"',"Fix the path.",`${a}.path`),null;const g=new Set,p=/\{([a-z][a-z0-9]*(?:-[a-z0-9]+)*)\}/g;let y;for(;(y=p.exec(d))!==null;)g.add(y[1]);let _=!1;if(e.streaming!==void 0){if(typeof e.streaming!="boolean")return n("command_rest_invalid","streaming must be a boolean",m(e.streaming),"true | false | omitted","Fix streaming.",`${a}.streaming`),null;_=e.streaming}const c=e.params;if(!x(c))return n("command_rest_invalid","params must be an object",m(c),"a mapping of param names to placement specs","Provide params.",`${a}.params`),null;const $=new Map;for(const i of t)$.set(i.name,i);const E={},f=[],k=new Set;for(const[i,h]of Object.entries(c)){if(!$.has(i))return n("command_rest_invalid","rest params key has no matching declared param",i,"a name from the leaf params array","Remove this rest params entry or declare the param.",`${a}.params.${i}`),null;if(k.add(i),!x(h))return n("command_rest_invalid","param mapping must be an object",m(h),"{ in, as? }","Fix the param mapping.",`${a}.params.${i}`),null;const S=new Set(["in","as"]),T=Object.keys(h).filter(F=>!S.has(F));if(T.length>0)return n("command_rest_invalid","unknown param mapping keys",T.join(", "),"only: in, as","Remove the unknown keys.",`${a}.params.${i}`),null;const u=h.in;if(typeof u!="string"||!me.has(u))return n("command_rest_invalid","param placement must be path|query|body|header",String(u),"path | query | body | header","Set in to a valid placement.",`${a}.params.${i}.in`),null;const b=h.as;if(b!==void 0&&(typeof b!="string"||b.length===0))return n("command_rest_invalid","as must be a non-empty string",String(b),"a non-empty string","Fix the as value.",`${a}.params.${i}.as`),null;if(u==="header"){if(typeof b!="string"||b.length===0)return n("command_rest_invalid","header placement requires a non-empty as",String(b),"a header name","Provide an as value for the header name.",`${a}.params.${i}.as`),null;if(!de.test(b))return n("command_rest_invalid",'header "as" must be a legal HTTP header field name',b,"an HTTP token (letters, digits, and !#$%&'*+-.^_`|~)","Fix the header name.",`${a}.params.${i}.as`),null}else if(u==="path"){if(b!==void 0)return n("command_rest_invalid","path placement must not have as","as","no as (placeholder name governs)","Remove as.",`${a}.params.${i}.as`),null;const F=$.get(i);if(F.required!==!0)return n("command_rest_invalid",'in:"path" param must be declared required',`${i}: required ${String(F.required)}`,"required: true",`Set "required": true on the "${i}" param.`,`${a}.params.${i}`),null}const K=$.get(i);if((K.kind==="flag"||K.kind==="positional")&&K.repeatable===!0&&u!=="body")return n("command_rest_invalid","repeatable param must use body placement",`${i}: in "${u}"`,'in: "body" (array values ship as a JSON array)',`Map "${i}" to body placement.`,`${a}.params.${i}.in`),null;if(u==="body"){const D=$.get(i).kind==="stdin",Y=b||i;f.push({name:i,isStdin:D,as:Y})}E[i]={in:u,...b!==void 0?{as:b}:{}}}for(const i of t)if(!k.has(i.name))return n("command_rest_invalid","declared param not in rest mapping",i.name,"an entry in rest.params","Add a rest mapping for this param.",`${a}.params`),null;const A=new Set;for(const[i,h]of Object.entries(E))h.in==="path"&&A.add(i);if(A.size!==g.size||![...g].every(i=>A.has(i)))return n("command_rest_invalid","mismatch between path placeholders and path params",`placeholders: ${[...g].join(", ")} | params: ${[...A].join(", ")}`,'exact bijection between {placeholders} and in:"path" params',"Ensure every placeholder has a matching path param, and vice versa.",`${a}.path and ${a}.params`),null;if(r==="GET"&&f.length>0)return n("command_rest_invalid","GET method cannot have body params",f.map(i=>i.name).join(", "),"no body placement for GET","Move body params to query, or change the method.",`${a}.method or ${a}.params`),null;let j;if(e.body!==void 0){if(r==="GET")return n("command_rest_invalid","GET method cannot have body constants","body","no body for GET","Remove body, or change the method.",`${a}.body`),null;const i=e.body;if(!x(i))return n("command_rest_invalid","body must be an object",m(i),"a map of constant literal body fields (string | number | boolean)","Fix body.",`${a}.body`),null;const h={};for(const[u,b]of Object.entries(i)){if(typeof b!="string"&&typeof b!="number"&&typeof b!="boolean")return n("command_rest_invalid",`body.${u} must be a string, number, or boolean`,m(b),"string | number | boolean",`Fix body.${u}.`,`${a}.body.${u}`),null;h[u]=b}const S=new Set(f.map(u=>u.as)),T=Object.keys(h).filter(u=>S.has(u));if(T.length>0)return n("command_rest_invalid","body constant key collides with a param's body key",T.join(", "),"body constant keys distinct from every param's body key (its as or name)","Rename the colliding body constant or param.",`${a}.body`),null;j=h}let P;if(e.bodyRoot!==void 0){if(r==="GET")return n("command_rest_invalid","GET method cannot have bodyRoot","bodyRoot","no bodyRoot for GET","Remove bodyRoot, or change the method.",`${a}.bodyRoot`),null;const i=e.bodyRoot;if(typeof i!="string"||i.length===0)return n("command_rest_invalid","bodyRoot must be a non-empty string",m(i),"a non-empty string key","Fix bodyRoot.",`${a}.bodyRoot`),null;P=i}for(const[i,h]of Object.entries(E)){const S=$.get(i);if((S.kind==="context-file"||(S.kind==="positional"||S.kind==="flag")&&S.type==="path")&&h.in!=="body"){const u=S.kind==="context-file"?"context-file":`path ${S.kind}`;return n("command_rest_invalid",`file param (${u}) must be placed in body`,`${i}: in "${h.in}"`,'in: "body"',"Move the file param to body.",`${a}.params.${i}.in`),null}}const q=new Map;for(const i of f)q.has(i.as)||q.set(i.as,[]),q.get(i.as).push({name:i.name,isStdin:i.isStdin});for(const[i,h]of q.entries())if(h.length>1){const S=h.filter(u=>u.isStdin).length,T=h.filter(u=>!u.isStdin).length;if(!(S===1&&T===1))return n("command_rest_invalid","invalid body as grouping",h.map(u=>u.name).join(", "),"exactly one stdin param and one non-stdin param may share a body as (for coalesced sources)","Fix the body grouping.",`${a}.params (as: "${i}")`),null}return{method:r,path:d,..._!==!1?{streaming:_}:{},...j!==void 0?{body:j}:{},...P!==void 0?{bodyRoot:P}:{},params:E}}v(se,"validateRestMapping");export{ae as validateCommandNode};
1
+ var z=Object.defineProperty;var v=(e,o)=>z(e,"name",{value:o,configurable:!0});import{isRecord as x}from"../../shared/predicates.js";const B=new Set(["normal","common","important"]),I=new Set(["string","int","bool","path","enum"]),U=/^[a-z][a-z0-9]*(-[a-z0-9]+)*$/,N=new Set(["kind","name","description","whenToUse","tier","rootEntry","extensible","summary","model","children"]),V=new Set([...N,"passthrough"]),L=new Set(["bin","installHint"]),O=new Set(["kind","name","description","whenToUse","tier","summary","params","output","effects"]),Z=new Set([...O,"outputKind"]),W=new Set([...O,"rest"]),X=new Set(["concept","description","whenToUse"]),J=new Set(["text","base64"]),C={positional:new Set(["kind","name","type","required","constraint","repeatable","encoding","defaultFromEnv"]),flag:new Set(["kind","name","type","choices","required","constraint","default","repeatable","encoding","defaultFromEnv"]),stdin:new Set(["kind","name","required","constraint"]),"context-file":new Set(["kind","name","required","constraint","shape"])},Q=new Set(["name","type","required","constraint"]),w=/^[A-Z][A-Z0-9_]*$/;function m(e){return e===null?"null":Array.isArray(e)?"array":typeof e}v(m,"typeName");function R(e,o,t,n){const a=Object.keys(e).filter(l=>!o.has(l));return a.length>0?(n("command_node_invalid","unknown keys",a.join(", "),`only: ${[...o].join(", ")}`,"Remove the unknown keys.",t),!1):!0}v(R,"checkKeys");function ee(e,o,t){if(!x(e))return t("command_node_invalid","rootEntry must be an object",m(e),"a { concept, description, whenToUse } object","Fix rootEntry.",o),null;if(!R(e,X,o,t))return null;for(const n of["concept","description","whenToUse"])if(typeof e[n]!="string"||e[n].length===0)return t("command_node_invalid",`rootEntry.${n} must be a non-empty string`,m(e[n]),"a non-empty string",`Add rootEntry.${n}.`,`${o}.${n}`),null;return{concept:e.concept,description:e.description,whenToUse:e.whenToUse}}v(ee,"validateRootEntry");function ne(e,o,t){if(e===void 0)return[];if(!Array.isArray(e))return t("command_node_invalid","params must be an array",m(e),"an array of params (or omitted)","Fix params.",o),null;const n=[],a=new Set;let l=0;for(let s=0;s<e.length;s++){const r=e[s],d=`${o}[${s}]`;if(!x(r))return t("command_node_invalid","param must be an object",m(r),"a param object","Fix the param.",d),null;const g=r.kind;if(typeof g!="string"||!(g in C))return t("command_node_invalid","param kind must be positional|flag|stdin|context-file",String(g),"positional | flag | stdin | context-file","Fix the param kind.",`${d}.kind`),null;if(!R(r,C[g],d,t))return null;const y=r.name;if(typeof y!="string"||!U.test(y))return t("command_node_invalid","param name must be a kebab-case token",String(y),"a kebab-case token","Rename the param.",`${d}.name`),null;if(a.has(y))return t("command_node_invalid","duplicate param name",y,"unique param names","Rename the duplicate param.",`${d}.name`),null;if(a.add(y),typeof r.required!="boolean")return t("command_node_invalid","param required must be a boolean",m(r.required),"true | false","Set required.",`${d}.required`),null;if(typeof r.constraint!="string")return t("command_node_invalid","param constraint must be a string",m(r.constraint),"an inline constraint string","Add a constraint.",`${d}.constraint`),null;if(g==="positional"){if(l++,l>1)return t("command_node_invalid","a leaf may declare at most one positional","multiple positionals","at most one positional param","Convert extra positionals to flags.",d),null;if(r.type!==void 0&&r.type!=="string"&&r.type!=="path")return t("command_node_invalid","positional type must be string|path",String(r.type),"string | path | omitted","Fix the positional type.",`${d}.type`),null;let h=!1;if(r.repeatable!==void 0){if(typeof r.repeatable!="boolean")return t("command_node_invalid","repeatable must be a boolean",m(r.repeatable),"true | false | omitted","Fix repeatable.",`${d}.repeatable`),null;h=r.repeatable}const _=H(r,d,t);if(_===null)return null;const c=M(r,d,t);if(c===null)return null;if(h&&c!==void 0)return t("command_node_invalid","repeatable positional must not declare defaultFromEnv",y,"no defaultFromEnv on a repeatable positional (values accumulate into an array)","Remove defaultFromEnv, or drop repeatable.",`${d}.defaultFromEnv`),null;n.push({kind:"positional",name:y,...r.type!==void 0?{type:r.type}:{},required:r.required,constraint:r.constraint,...h?{repeatable:!0}:{},..._!==void 0?{encoding:_}:{},...c!==void 0?{defaultFromEnv:c}:{}})}else if(g==="stdin")n.push({kind:"stdin",name:y,required:r.required,constraint:r.constraint});else if(g==="context-file")n.push({kind:"context-file",name:y,required:r.required,constraint:r.constraint,...typeof r.shape=="string"?{shape:r.shape}:{}});else if(g==="flag"){const h=r.type;if(typeof h!="string"||!I.has(h))return t("command_node_invalid","flag type must be string|int|bool|path|enum",String(h),"string | int | bool | path | enum","Fix the flag type.",`${d}.type`),null;let _;if(h==="enum"){const f=r.choices;if(!Array.isArray(f)||f.length===0||!f.every(k=>typeof k=="string"))return t("command_node_invalid","enum flag requires a non-empty string choices array",m(f),"a non-empty array of strings","Declare choices for the enum flag.",`${d}.choices`),null;_=f}else if(r.choices!==void 0)return t("command_node_invalid","choices is only valid on an enum flag","choices","no choices unless type is enum","Remove choices.",`${d}.choices`),null;let c=!1;if(r.repeatable!==void 0){if(typeof r.repeatable!="boolean")return t("command_node_invalid","repeatable must be a boolean",m(r.repeatable),"true | false | omitted","Fix repeatable.",`${d}.repeatable`),null;c=r.repeatable}if(c&&(h==="bool"||h==="path"))return t("command_node_invalid",`repeatable is not valid on a ${h} flag`,`${y}: ${h}`,"repeatable only on string | int | enum flags","Remove repeatable or change the flag type.",`${d}.repeatable`),null;if(c&&r.default!==void 0)return t("command_node_invalid","repeatable flag must not declare a default",y,"no default on a repeatable flag (values accumulate into an array)","Remove the default.",`${d}.default`),null;const $=H(r,d,t);if($===null)return null;const E=M(r,d,t);if(E===null)return null;if(c&&E!==void 0)return t("command_node_invalid","repeatable flag must not declare defaultFromEnv",y,"no defaultFromEnv on a repeatable flag (values accumulate into an array)","Remove defaultFromEnv, or drop repeatable.",`${d}.defaultFromEnv`),null;n.push({kind:"flag",name:y,type:h,..._!==void 0?{choices:_}:{},...$!==void 0?{encoding:$}:{},required:r.required,constraint:r.constraint,...r.default!==void 0?{default:r.default}:{},...c?{repeatable:!0}:{},...E!==void 0?{defaultFromEnv:E}:{}})}}return n}v(ne,"validateParams");function H(e,o,t){const n=e.encoding;if(n!==void 0)return typeof n!="string"||!J.has(n)?(t("command_node_invalid","param encoding must be text|base64",String(n),"text | base64 | omitted","Fix the encoding.",`${o}.encoding`),null):e.type!=="path"?(t("command_node_invalid",'encoding is only valid on a type:"path" param',`type ${String(e.type)}`,'type: "path"','Set the param type to "path", or remove encoding.',`${o}.encoding`),null):n}v(H,"validateFileEncoding");function M(e,o,t){const n=e.defaultFromEnv;if(n===void 0)return;if(typeof n!="string"||!w.test(n))return t("command_node_invalid","defaultFromEnv must name an environment variable in UPPER_SNAKE_CASE",String(n),'e.g. "CRTR_NODE_ID"',"Fix the environment variable name.",`${o}.defaultFromEnv`),null;const a=e.type===void 0&&e.kind==="positional"?"string":e.type;return a!=="string"&&a!=="path"?(t("command_node_invalid","defaultFromEnv is only valid on a string|path param",`type ${String(e.type)}`,'type: "string" | "path"',"Change the param type, or remove defaultFromEnv.",`${o}.defaultFromEnv`),null):e.default!==void 0?(t("command_node_invalid","a param must not declare both default and defaultFromEnv",`${String(e.name)}: default + defaultFromEnv`,"exactly one default source","Remove one \u2014 defaultFromEnv counts as supplied, a static default does not.",`${o}.defaultFromEnv`),null):n}v(M,"validateDefaultFromEnv");function te(e,o,t){if(!Array.isArray(e))return t("command_node_invalid","output must be an array",m(e),"an array of output fields","Declare the leaf output fields.",o),null;const n=[];for(let a=0;a<e.length;a++){const l=e[a],s=`${o}[${a}]`;if(!x(l))return t("command_node_invalid","output field must be an object",m(l),"a { name, type, required, constraint } object","Fix the output field.",s),null;if(!R(l,Q,s,t))return null;if(typeof l.name!="string"||l.name.length===0)return t("command_node_invalid","output field name must be a non-empty string",m(l.name),"a field name","Add a name.",`${s}.name`),null;if(typeof l.type!="string"||l.type.length===0)return t("command_node_invalid","output field type must be a non-empty string",m(l.type),"a type name","Add a type.",`${s}.type`),null;if(typeof l.required!="boolean")return t("command_node_invalid","output field required must be a boolean",m(l.required),"true | false","Set required.",`${s}.required`),null;if(typeof l.constraint!="string")return t("command_node_invalid","output field constraint must be a string",m(l.constraint),"a constraint string","Add a constraint.",`${s}.constraint`),null;n.push({name:l.name,type:l.type,required:l.required,constraint:l.constraint})}return n}v(te,"validateOutput");function G(e,o,t){const n=e.name;return typeof n!="string"||!U.test(n)?(t("command_node_invalid","node name must be a lowercase kebab-case token",String(n),'a kebab-case token like "app" or "list-all"',"Rename the node.",`${o}.name`),!1):typeof e.description!="string"||e.description.length===0?(t("command_node_invalid","node description must be a non-empty string",m(e.description),"a short parent-listing description","Add a description.",`${o}.description`),!1):typeof e.whenToUse!="string"||e.whenToUse.length===0?(t("command_node_invalid","node whenToUse must be a non-empty string",m(e.whenToUse),"a parent selection rubric","Add a whenToUse rubric.",`${o}.whenToUse`),!1):e.tier!==void 0&&!B.has(String(e.tier))?(t("command_node_invalid","node tier must be normal|common|important",String(e.tier),"normal | common | important","Fix or omit tier (external plugins cannot declare hidden commands).",`${o}.tier`),!1):!0}v(G,"checkCommon");function ae(e,o,t,n,a,l={}){const s=o.join(".");if(!x(e))return a("command_node_invalid","node must be an object",m(e),"a branch or leaf node object","Fix the node.",s),null;const r=e.kind;return r==="branch"?oe(e,s,t,n,a,l):r==="leaf"?t&&l.topLevelRootEntry!=="forbidden"?(a("command_node_invalid","top-level node must be a branch","leaf","a branch node with a rootEntry","Wrap the command in a top-level branch (noun) with a rootEntry.",`${s}.kind`),null):ie(e,s,n,a):(a("command_node_invalid",'node kind must be "branch" or "leaf"',String(r),"branch | leaf","Set kind to branch or leaf.",`${s}.kind`),null)}v(ae,"validateCommandNode");function oe(e,o,t,n,a,l){const s=l.allowPassthrough!==!1;if(!R(e,n==="exec"&&s?V:N,o,a)||!G(e,o,a))return null;const d=e.rootEntry!==void 0,g=l.topLevelRootEntry??"required";if(t&&g==="required"&&!d)return a("command_node_invalid","top-level branch requires a rootEntry","(missing)","a rootEntry { concept, description, whenToUse }","Add a rootEntry to the top-level branch.",`${o}.rootEntry`),null;if((!t||g==="forbidden")&&d)return a("command_node_invalid",t?"repository fragment root must not declare a rootEntry":"nested branch must not declare a rootEntry","rootEntry",t?"no rootEntry (the owning plugin branch already has one)":"no rootEntry (only top-level branches carry one)",t?"Remove rootEntry from the repository fragment root.":"Remove rootEntry from the nested branch.",`${o}.rootEntry`),null;const y=e.extensible!==void 0;if(y&&(!t||l.allowExtensible===!1||e.extensible!==!0))return a("command_node_invalid",t?"extensible must be exactly true on a plugin top-level branch":"extensible is valid only on a top-level branch mount",String(e.extensible),t?"extensible: true":"no extensible marker on nested branches",t?"Set extensible to true or remove it.":"Move the marker to the plugin top-level branch or remove it.",`${o}.extensible`),null;let h;if(d){const f=ee(e.rootEntry,`${o}.rootEntry`,a);if(f===null)return null;h=f}if(typeof e.summary!="string"||e.summary.length===0)return a("command_node_invalid","branch summary must be a non-empty string",m(e.summary),"a one-line summary string","Add a summary.",`${o}.summary`),null;if(e.model!==void 0&&typeof e.model!="string")return a("command_node_invalid","branch model must be a string",m(e.model),"a string or omitted","Fix or remove model.",`${o}.model`),null;let _;if(n==="exec"&&e.passthrough!==void 0){const f=re(e.passthrough,`${o}.passthrough`,a);if(f===null)return null;_=f}if(y&&_!==void 0)return a("command_node_invalid","an extensible branch cannot declare passthrough","extensible and passthrough","one branch mode: extensible or passthrough","Remove passthrough or remove extensible.",o),null;const c=e.children;if(_!==void 0){if(!Array.isArray(c)||c.length!==0)return a("command_node_invalid","a passthrough branch must declare children: []",Array.isArray(c)?`${c.length} children`:m(c),"an empty children array","Set children to [] \u2014 a passthrough branch forwards all argv and can own no subcommands.",`${o}.children`),null}else if(!Array.isArray(c))return a("command_node_invalid","branch children must be an array",m(c),"an array of branch/leaf nodes (may be empty for populated by mounts)","Fix children.",`${o}.children`),null;const $=[],E=new Set;for(let f=0;f<c.length;f++){const k=ae(c[f],[...o.split("."),`children[${f}]`],!1,n,a,l);if(k===null)return null;if(E.has(k.name))return a("command_node_invalid","duplicate child name",k.name,"unique child names within a branch","Rename the duplicate child.",`${o}.children[${f}].name`),null;E.add(k.name),$.push(k)}return{kind:"branch",name:e.name,description:e.description,whenToUse:e.whenToUse,...e.tier!==void 0?{tier:e.tier}:{},...h!==void 0?{rootEntry:h}:{},...y?{extensible:!0}:{},summary:e.summary,...e.model!==void 0?{model:e.model}:{},..._!==void 0?{passthrough:_}:{},children:$}}v(oe,"validateBranch");function re(e,o,t){if(!x(e))return t("command_node_invalid","passthrough must be an object",m(e),"an object { bin, installHint }","Fix or remove passthrough.",o),null;if(!R(e,L,o,t))return null;for(const n of["bin","installHint"])if(typeof e[n]!="string"||e[n].length===0)return t("command_node_invalid",`passthrough ${n} must be a non-empty string`,m(e[n]),n==="bin"?"the external binary name":"a one-line install hint",`Set passthrough.${n}.`,`${o}.${n}`),null;return{bin:e.bin,installHint:e.installHint}}v(re,"validatePassthrough");function ie(e,o,t,n){if(!R(e,t==="exec"?Z:W,o,n)||!G(e,o,n))return null;if(typeof e.summary!="string"||e.summary.length===0)return n("command_node_invalid","leaf summary must be a non-empty string",m(e.summary),"a one-line summary string","Add a summary.",`${o}.summary`),null;if(t==="exec"&&e.outputKind!=="object")return n("command_node_invalid",'leaf outputKind must be "object" in v1',String(e.outputKind),'exactly "object"','Set outputKind to "object".',`${o}.outputKind`),null;if(t==="http"&&e.rest===void 0)return n("command_node_invalid","HTTP leaf requires a rest mapping","(missing)","a rest object with method, path, and params","Add a rest mapping.",`${o}.rest`),null;const a=ne(e.params,`${o}.params`,n);if(a===null)return null;const l=te(e.output,`${o}.output`,n);if(l===null)return null;const s=e.effects;if(!Array.isArray(s)||s.length===0||!s.every(g=>typeof g=="string"))return n("command_node_invalid","leaf effects must be a non-empty string array",m(s),'a non-empty array of strings (["None. Read-only."] for read-only leaves)',"Declare every persistent effect.",`${o}.effects`),null;const r={kind:"leaf",name:e.name,description:e.description,whenToUse:e.whenToUse,...e.tier!==void 0?{tier:e.tier}:{},summary:e.summary,params:a,output:l,effects:s};if(t==="exec")return{...r,outputKind:"object"};const d=se(e.rest,o,a,n);return d===null?null:{...r,rest:d}}v(ie,"validateLeaf");const le=new Set(["GET","POST","PUT","PATCH","DELETE"]),de=/^[!#$%&'*+\-.^_`|~0-9A-Za-z]+$/,me=new Set(["path","query","body","header"]);function se(e,o,t,n){const a=`${o}.rest`;if(!x(e))return n("command_rest_invalid","rest must be an object",m(e),"{ method, path, streaming?, params }","Provide a valid rest mapping.",a),null;const l=new Set(["method","path","streaming","body","bodyRoot","params"]),s=Object.keys(e).filter(i=>!l.has(i));if(s.length>0)return n("command_rest_invalid","unknown rest keys",s.join(", "),"only: method, path, streaming, body, bodyRoot, params","Remove the unknown keys.",a),null;const r=e.method;if(typeof r!="string"||!le.has(r))return n("command_rest_invalid","method must be GET|POST|PUT|PATCH|DELETE",String(r),"one of the HTTP methods","Set method to a valid HTTP verb.",`${a}.method`),null;const d=e.path;if(typeof d!="string"||!d.startsWith("/"))return n("command_rest_invalid","path must be an absolute path starting with /",String(d),'an absolute path like "/v1/devices/{id}"',"Fix the path.",`${a}.path`),null;const g=new Set,y=/\{([a-z][a-z0-9]*(?:-[a-z0-9]+)*)\}/g;let h;for(;(h=y.exec(d))!==null;)g.add(h[1]);let _=!1;if(e.streaming!==void 0){if(typeof e.streaming!="boolean")return n("command_rest_invalid","streaming must be a boolean",m(e.streaming),"true | false | omitted","Fix streaming.",`${a}.streaming`),null;_=e.streaming}const c=e.params;if(!x(c))return n("command_rest_invalid","params must be an object",m(c),"a mapping of param names to placement specs","Provide params.",`${a}.params`),null;const $=new Map;for(const i of t)$.set(i.name,i);const E={},f=[],k=new Set;for(const[i,b]of Object.entries(c)){if(!$.has(i))return n("command_rest_invalid","rest params key has no matching declared param",i,"a name from the leaf params array","Remove this rest params entry or declare the param.",`${a}.params.${i}`),null;if(k.add(i),!x(b))return n("command_rest_invalid","param mapping must be an object",m(b),"{ in, as? }","Fix the param mapping.",`${a}.params.${i}`),null;const S=new Set(["in","as"]),T=Object.keys(b).filter(F=>!S.has(F));if(T.length>0)return n("command_rest_invalid","unknown param mapping keys",T.join(", "),"only: in, as","Remove the unknown keys.",`${a}.params.${i}`),null;const u=b.in;if(typeof u!="string"||!me.has(u))return n("command_rest_invalid","param placement must be path|query|body|header",String(u),"path | query | body | header","Set in to a valid placement.",`${a}.params.${i}.in`),null;const p=b.as;if(p!==void 0&&(typeof p!="string"||p.length===0))return n("command_rest_invalid","as must be a non-empty string",String(p),"a non-empty string","Fix the as value.",`${a}.params.${i}.as`),null;if(u==="header"){if(typeof p!="string"||p.length===0)return n("command_rest_invalid","header placement requires a non-empty as",String(p),"a header name","Provide an as value for the header name.",`${a}.params.${i}.as`),null;if(!de.test(p))return n("command_rest_invalid",'header "as" must be a legal HTTP header field name',p,"an HTTP token (letters, digits, and !#$%&'*+-.^_`|~)","Fix the header name.",`${a}.params.${i}.as`),null;if(p.toLowerCase()==="crtr-request-id")return n("command_rest_invalid","Crtr-Request-Id is assigned by crtr for each leaf call",p,"a header name other than Crtr-Request-Id","Remove this header mapping.",`${a}.params.${i}.as`),null}else if(u==="path"){if(p!==void 0)return n("command_rest_invalid","path placement must not have as","as","no as (placeholder name governs)","Remove as.",`${a}.params.${i}.as`),null;const F=$.get(i);if(F.required!==!0)return n("command_rest_invalid",'in:"path" param must be declared required',`${i}: required ${String(F.required)}`,"required: true",`Set "required": true on the "${i}" param.`,`${a}.params.${i}`),null}const K=$.get(i);if((K.kind==="flag"||K.kind==="positional")&&K.repeatable===!0&&u!=="body")return n("command_rest_invalid","repeatable param must use body placement",`${i}: in "${u}"`,'in: "body" (array values ship as a JSON array)',`Map "${i}" to body placement.`,`${a}.params.${i}.in`),null;if(u==="body"){const D=$.get(i).kind==="stdin",Y=p||i;f.push({name:i,isStdin:D,as:Y})}E[i]={in:u,...p!==void 0?{as:p}:{}}}for(const i of t)if(!k.has(i.name))return n("command_rest_invalid","declared param not in rest mapping",i.name,"an entry in rest.params","Add a rest mapping for this param.",`${a}.params`),null;const A=new Set;for(const[i,b]of Object.entries(E))b.in==="path"&&A.add(i);if(A.size!==g.size||![...g].every(i=>A.has(i)))return n("command_rest_invalid","mismatch between path placeholders and path params",`placeholders: ${[...g].join(", ")} | params: ${[...A].join(", ")}`,'exact bijection between {placeholders} and in:"path" params',"Ensure every placeholder has a matching path param, and vice versa.",`${a}.path and ${a}.params`),null;if(r==="GET"&&f.length>0)return n("command_rest_invalid","GET method cannot have body params",f.map(i=>i.name).join(", "),"no body placement for GET","Move body params to query, or change the method.",`${a}.method or ${a}.params`),null;let j;if(e.body!==void 0){if(r==="GET")return n("command_rest_invalid","GET method cannot have body constants","body","no body for GET","Remove body, or change the method.",`${a}.body`),null;const i=e.body;if(!x(i))return n("command_rest_invalid","body must be an object",m(i),"a map of constant literal body fields (string | number | boolean)","Fix body.",`${a}.body`),null;const b={};for(const[u,p]of Object.entries(i)){if(typeof p!="string"&&typeof p!="number"&&typeof p!="boolean")return n("command_rest_invalid",`body.${u} must be a string, number, or boolean`,m(p),"string | number | boolean",`Fix body.${u}.`,`${a}.body.${u}`),null;b[u]=p}const S=new Set(f.map(u=>u.as)),T=Object.keys(b).filter(u=>S.has(u));if(T.length>0)return n("command_rest_invalid","body constant key collides with a param's body key",T.join(", "),"body constant keys distinct from every param's body key (its as or name)","Rename the colliding body constant or param.",`${a}.body`),null;j=b}let P;if(e.bodyRoot!==void 0){if(r==="GET")return n("command_rest_invalid","GET method cannot have bodyRoot","bodyRoot","no bodyRoot for GET","Remove bodyRoot, or change the method.",`${a}.bodyRoot`),null;const i=e.bodyRoot;if(typeof i!="string"||i.length===0)return n("command_rest_invalid","bodyRoot must be a non-empty string",m(i),"a non-empty string key","Fix bodyRoot.",`${a}.bodyRoot`),null;P=i}for(const[i,b]of Object.entries(E)){const S=$.get(i);if((S.kind==="context-file"||(S.kind==="positional"||S.kind==="flag")&&S.type==="path")&&b.in!=="body"){const u=S.kind==="context-file"?"context-file":`path ${S.kind}`;return n("command_rest_invalid",`file param (${u}) must be placed in body`,`${i}: in "${b.in}"`,'in: "body"',"Move the file param to body.",`${a}.params.${i}.in`),null}}const q=new Map;for(const i of f)q.has(i.as)||q.set(i.as,[]),q.get(i.as).push({name:i.name,isStdin:i.isStdin});for(const[i,b]of q.entries())if(b.length>1){const S=b.filter(u=>u.isStdin).length,T=b.filter(u=>!u.isStdin).length;if(!(S===1&&T===1))return n("command_rest_invalid","invalid body as grouping",b.map(u=>u.name).join(", "),"exactly one stdin param and one non-stdin param may share a body as (for coalesced sources)","Fix the body grouping.",`${a}.params (as: "${i}")`),null}return{method:r,path:d,..._!==!1?{streaming:_}:{},...j!==void 0?{body:j}:{},...P!==void 0?{bodyRoot:P}:{},params:E}}v(se,"validateRestMapping");export{ae as validateCommandNode};
@@ -1,3 +1,3 @@
1
- var I=Object.defineProperty;var u=(e,t)=>I(e,"name",{value:t,configurable:!0});import{readFileSync as O,statSync as B}from"node:fs";import{resolve as J}from"node:path";import{request as A}from"node:http";import{request as U}from"node:https";import{validateDeclaredResult as z}from"../../../api/command-manifest/result.js";import{CrtrError as S}from"../../errors.js";import{envelopeClaimsStale as G,staleErrorDetails as F}from"../../manifest-stale.js";import{diag as H,recordPreviewError as V,recordPreviewJsonLine as q,writeStdout as C}from"../../io.js";import{ExitCode as b}from"../../../types.js";import{isRecord as R}from"../../../shared/predicates.js";const P=1e4,K=3e4,W=6e4,Q=/^[a-z][a-z0-9]*(_[a-z0-9]+)*$/,X=new Set(["internal","unknown_path","command_collision","cli_protocol_error"]);class M extends Error{static{u(this,"StreamIdleError")}}async function we(e,t,n){const r=Y(e,t,n);if(e.rest.streaming===!0){await re(e,r);return}const{status:d,body:i}=await te(e,r);if(d>=200&&d<300)return ne(e,i);L(e,d,i)}u(we,"invokeHttpLeaf");function Y(e,t,n){const r=new Map;for(const o of e.params)r.set(o.name,o);const d=Object.entries(e.rest.params),i=e.baseUrl??new URL(e.registration.endpoint).origin;let m=e.rest.path;for(const[o,s]of d){if(s.in!=="path")continue;const c=t[E(o)];m=m.split(`{${o}}`).join(ee(c))}const p=new URL(m,i);for(const[o,s]of d){if(s.in!=="query")continue;const c=E(o);_(r.get(o),c,t,n)&&p.searchParams.append(s.as??o,String(t[c]))}const a=Z(e,d,r,t,n),l=Object.keys(a).length>0?JSON.stringify(a):void 0;let y;const f=e.registration.authEnv;if(f!==void 0&&f!==""){const o=process.env[f];if(o===void 0||o==="")throw new S("auth_env_missing",`${T(e)}: environment variable ${f} is not set or empty`,b.USAGE,{field:f,received:f,next:`Export ${f} with the bearer token, then retry.`});y=`Bearer ${o}`}const h=[["Accept","application/json"]];y!==void 0&&h.push(["Authorization",y]);for(const[o,s]of d){if(s.in!=="header")continue;const c=E(o);if(!_(r.get(o),c,t,n))continue;const w=s.as,g=String(t[c]);if(/[\r\n]/.test(g))throw new S("invalid_type",`${T(e)}: header "${w}" value must not contain a newline`,b.USAGE,{field:o,received:"(newline in header value)",next:"Remove newline characters from the value."});h.push([w,g])}return l!==void 0&&h.push(["Content-Type","application/json"]),{url:p,method:e.rest.method,headers:h,...l!==void 0?{body:l}:{}}}u(Y,"buildRequestPlan");function Z(e,t,n,r,d){const i=new Map;for(const[a,l]of t){if(l.in!=="body")continue;const y=l.as??a,f=i.get(y);f!==void 0?f.push(a):i.set(y,[a])}const m={};for(const[a,l]of i){const y=l.map(s=>({name:s,param:n.get(s)})),f=y.find(s=>s.param.kind!=="stdin"),h=y.find(s=>s.param.kind==="stdin");let o;f!==void 0&&_(f.param,E(f.name),r,d)?o={param:f.param,value:r[E(f.name)]}:h!==void 0&&_(h.param,E(h.name),r,d)&&(o={param:h.param,value:r[E(h.name)]}),o!==void 0&&(m[a]=j(e,o.param,o.value))}const p={...e.rest.body};return e.rest.bodyRoot!==void 0?p[e.rest.bodyRoot]=m:Object.assign(p,m),p}u(Z,"assembleBody");function j(e,t,n){if(t.kind==="context-file")return n;if((t.kind==="positional"||t.kind==="flag")&&t.type==="path"){if(Array.isArray(n))return n.map(m=>j(e,t,m));const r=String(n),d=J(process.cwd(),r);let i;try{i=B(d)}catch{throw N(e,t.name,r,"no file exists at that path","an existing local file path")}if(!i.isFile())throw N(e,t.name,r,"the path is not a regular file","a regular local file (not a directory, socket, or device)");try{return t.encoding==="base64"?O(d).toString("base64"):O(d,"utf8")}catch{throw N(e,t.name,r,"the file could not be read","a readable local file path")}}return n}u(j,"materializeBodyValue");function N(e,t,n,r,d){return new S("invalid_type",`${T(e)}: cannot read file for "${t}" \u2014 ${r}: ${n}`,b.USAGE,{field:t,received:n,next:`Pass ${d}, relative to the current directory or absolute.`})}u(N,"fileError");function _(e,t,n,r){return r!==void 0?r.providedParams.has(t):Object.prototype.hasOwnProperty.call(n,t)&&n[t]!==void 0}u(_,"isPresent");function ee(e){const t=String(e);return t==="."||t===".."?t.replace(/\./g,"%2E"):encodeURIComponent(t)}u(ee,"encodePathSegmentValue");function E(e){return e.replace(/-([a-z])/g,(t,n)=>n.toUpperCase())}u(E,"paramKey");function te(e,t){const n=e.timeouts?.connectMs??P,r=e.timeouts?.requestMs??K,d=t.url.protocol==="https:"?U:A;return new Promise((i,m)=>{let p=!1,a=null,l=null;const y=u(()=>{a!==null&&clearTimeout(a),l!==null&&clearTimeout(l),a=null,l=null},"clearTimers"),f=u(c=>{p||(p=!0,y(),o.destroy(),m(c))},"fail"),h=u(c=>{p||(p=!0,y(),i(c))},"succeed"),o=d(t.url,{method:t.method},c=>{a!==null&&(clearTimeout(a),a=null);const w=[];c.on("data",g=>w.push(g)),c.on("end",()=>h({status:c.statusCode??0,body:Buffer.concat(w).toString("utf8")})),c.on("error",g=>f(v(e,t,`connection error (${x(g)})`)))});for(const[c,w]of t.headers)o.setHeader(c,w);a=setTimeout(()=>f(v(e,t,`connection timed out after ${n}ms`)),n),l=setTimeout(()=>f(v(e,t,`request exceeded the ${r}ms timeout`)),r),o.on("socket",c=>{c.connecting?c.once("connect",()=>s()):s()});const s=u(()=>{a!==null&&(clearTimeout(a),a=null)},"clearConnectTimer");o.on("error",c=>f(v(e,t,`could not reach the backend (${x(c)})`))),t.body!==void 0&&o.write(t.body),o.end()})}u(te,"requestUnary");function ne(e,t){let n;try{n=JSON.parse(t)}catch{throw k(e,"response body was not valid JSON","a JSON object matching the declared output")}if(!R(n))throw k(e,`response body was not a JSON object (got ${ae(n)})`,"a JSON object matching the declared output");const r=z(e.output,n);if(r!==null){const i=e.output.find(m=>m.name===r.field)?.type??"unknown";throw r.receivedType!==void 0?k(e,`output field "${r.field}" has the wrong type`,`${r.field}: ${i}`):k(e,`response is missing required output field "${r.field}"`,`a "${r.field}" field of type ${i}`)}return n}u(ne,"mapUnary2xx");async function re(e,t){const n=e.timeouts?.connectMs??P,r=e.timeouts?.streamIdleMs??W,d=t.url.protocol==="https:"?U:A,i=await new Promise((h,o)=>{let s=!1,c=null;const w=u(()=>{c!==null&&(clearTimeout(c),c=null)},"clearConnect"),g=d(t.url,{method:t.method},$=>{s||(s=!0,w(),h($))});for(const[$,D]of t.headers)g.setHeader($,D);c=setTimeout(()=>{s||(s=!0,g.destroy(),o(v(e,t,`connection timed out after ${n}ms`)))},n),g.on("socket",$=>{$.connecting?$.once("connect",w):w()}),g.on("error",$=>{s||(s=!0,w(),o(v(e,t,`could not reach the backend (${x($)})`)))}),t.body!==void 0&&g.write(t.body),g.end()}),m=i.statusCode??0;if(!(m>=200&&m<300)){const h=await ie(i);L(e,m,h)}let p=!1,a="",l=null;const y=u(()=>{l!==null&&clearTimeout(l),l=setTimeout(()=>i.destroy(new M),r)},"armIdle"),f=u(()=>{l!==null&&(clearTimeout(l),l=null)},"clearIdle");try{y();for await(const h of i){y(),a+=h.toString("utf8");let o;for(;(o=a.indexOf(`
2
- `))!==-1;){const s=a.slice(0,o);if(a=a.slice(o+1),s.trim()==="")continue;if(p=!0,q(s),!await C(s+`
3
- `)){f(),i.destroy();return}}}f(),a.trim()!==""&&(p=!0,q(a),await C(a));return}catch(h){f();const o=h instanceof M?`stream idle for ${r}ms`:`connection error (${x(h)})`;if(p){const s=`${T(e)}: stream interrupted (${o})`;H(`crtr: ${s}`),V({error:"stream_interrupted",message:s,next:"Retry the command to begin a fresh stream."}),process.exitCode=b.NETWORK;return}throw v(e,t,o)}}u(re,"requestStreaming");function L(e,t,n){const r=oe(t);let d;try{d=JSON.parse(n)}catch{d=void 0}if(R(d)){const i=d.error;if(R(i)&&typeof i.code=="string"&&typeof i.message=="string"){const m=i.code,p=i.message,a=typeof i.field=="string"?i.field:void 0,l=typeof i.next=="string"?i.next:"Inspect the backend response, then retry if appropriate.",y=Q.test(m)&&!X.has(m),f=G(i);throw new S(y?m:"cli_protocol_error",p,r,{...i.received!==void 0?{received:i.received}:{},...a!==void 0?{field:a}:{},...f?F(e.registration.name):{},http_status:t,next:l})}}throw new S("cli_http_error",`${T(e)}: request failed with HTTP ${t}`,r,{http_status:t,next:"Inspect the backend response, then retry if appropriate."})}u(L,"throwNon2xx");function oe(e){return e===400||e===401||e===403||e===422?b.USAGE:e===404?b.NOT_FOUND:e===409?b.AMBIGUOUS:b.GENERAL}u(oe,"deriveExit");function k(e,t,n){return new S("cli_protocol_error",`${T(e)}: ${t}. Expected ${n}.`,b.GENERAL,{received:t,next:`Run \`crtr pkg plugin update ${e.registration.name}\` or inspect the backend response.`})}u(k,"protocolError");function v(e,t,n){return new S("cli_unreachable",`${T(e)}: ${n}`,b.NETWORK,{received:t.url.origin,next:`Check connectivity to ${t.url.host} and retry; run \`crtr pkg plugin update ${e.registration.name}\` if the command surface changed.`})}u(v,"unreachable");function T(e){return`HTTP-transport plugin "${e.registration.name}" command \`${e.commandPath.join(" ")}\``}u(T,"label");function x(e){const t=e;return t?.code??t?.message??String(e)}u(x,"errCode");function ie(e){return new Promise(t=>{const n=[];e.on("data",r=>n.push(r)),e.on("end",()=>t(Buffer.concat(n).toString("utf8"))),e.on("error",()=>t(Buffer.concat(n).toString("utf8")))})}u(ie,"readAll");function ae(e){return e===null?"null":Array.isArray(e)?"array":typeof e}u(ae,"typeName");export{we as invokeHttpLeaf};
1
+ var B=Object.defineProperty;var d=(e,t)=>B(e,"name",{value:t,configurable:!0});import{randomUUID as L}from"node:crypto";import{readFileSync as x,statSync as J}from"node:fs";import{resolve as z}from"node:path";import{request as C}from"node:http";import{request as A}from"node:https";import{validateDeclaredResult as G}from"../../../api/command-manifest/result.js";import{CrtrError as $}from"../../errors.js";import{envelopeClaimsStale as H,staleErrorDetails as K}from"../../manifest-stale.js";import{diag as V,recordPreviewError as W,recordPreviewJsonLine as U,writeStdout as M}from"../../io.js";import{ExitCode as E}from"../../../types.js";import{isRecord as O}from"../../../shared/predicates.js";const P=1e4,Y=3e4,Q=6e4,X=250,Z=2e3,ee=new Set(["ECONNREFUSED","ECONNRESET","EPIPE"]);class q extends Error{static{d(this,"ConnectionError")}detail;constructor(t){super(t),this.detail=t}}const te=/^[a-z][a-z0-9]*(_[a-z0-9]+)*$/,ne=new Set(["internal","unknown_path","command_collision","cli_protocol_error"]);class D extends Error{static{d(this,"StreamIdleError")}}async function ve(e,t,n){const r=re(e,t,n);if(e.rest.streaming===!0){await ue(e,r);return}const{status:a,body:o}=await ae(e,r);if(a>=200&&a<300)return de(e,o);F(e,a,o)}d(ve,"invokeHttpLeaf");function re(e,t,n){const r=new Map;for(const i of e.params)r.set(i.name,i);const a=Object.entries(e.rest.params),o=e.baseUrl??new URL(e.registration.endpoint).origin;let l=e.rest.path;for(const[i,c]of a){if(c.in!=="path")continue;const u=t[_(i)];l=l.split(`{${i}}`).join(ie(u))}const p=new URL(l,o);for(const[i,c]of a){if(c.in!=="query")continue;const u=_(i);R(r.get(i),u,t,n)&&p.searchParams.append(c.as??i,String(t[u]))}const s=oe(e,a,r,t,n),m=Object.keys(s).length>0?JSON.stringify(s):void 0;let y;const f=e.registration.authEnv;if(f!==void 0&&f!==""){const i=process.env[f];if(i===void 0||i==="")throw new $("auth_env_missing",`${T(e)}: environment variable ${f} is not set or empty`,E.USAGE,{field:f,received:f,next:`Export ${f} with the bearer token, then retry.`});y=`Bearer ${i}`}const h=[["Accept","application/json"],["Crtr-Request-Id",L()]];y!==void 0&&h.push(["Authorization",y]);for(const[i,c]of a){if(c.in!=="header")continue;const u=_(i);if(!R(r.get(i),u,t,n))continue;const w=c.as,g=String(t[u]);if(/[\r\n]/.test(g))throw new $("invalid_type",`${T(e)}: header "${w}" value must not contain a newline`,E.USAGE,{field:i,received:"(newline in header value)",next:"Remove newline characters from the value."});h.push([w,g])}return m!==void 0&&h.push(["Content-Type","application/json"]),{url:p,method:e.rest.method,headers:h,...m!==void 0?{body:m}:{}}}d(re,"buildRequestPlan");function oe(e,t,n,r,a){const o=new Map;for(const[s,m]of t){if(m.in!=="body")continue;const y=m.as??s,f=o.get(y);f!==void 0?f.push(s):o.set(y,[s])}const l={};for(const[s,m]of o){const y=m.map(c=>({name:c,param:n.get(c)})),f=y.find(c=>c.param.kind!=="stdin"),h=y.find(c=>c.param.kind==="stdin");let i;f!==void 0&&R(f.param,_(f.name),r,a)?i={param:f.param,value:r[_(f.name)]}:h!==void 0&&R(h.param,_(h.name),r,a)&&(i={param:h.param,value:r[_(h.name)]}),i!==void 0&&(l[s]=I(e,i.param,i.value))}const p={...e.rest.body};return e.rest.bodyRoot!==void 0?p[e.rest.bodyRoot]=l:Object.assign(p,l),p}d(oe,"assembleBody");function I(e,t,n){if(t.kind==="context-file")return n;if((t.kind==="positional"||t.kind==="flag")&&t.type==="path"){if(Array.isArray(n))return n.map(l=>I(e,t,l));const r=String(n),a=z(process.cwd(),r);let o;try{o=J(a)}catch{throw k(e,t.name,r,"no file exists at that path","an existing local file path")}if(!o.isFile())throw k(e,t.name,r,"the path is not a regular file","a regular local file (not a directory, socket, or device)");try{return t.encoding==="base64"?x(a).toString("base64"):x(a,"utf8")}catch{throw k(e,t.name,r,"the file could not be read","a readable local file path")}}return n}d(I,"materializeBodyValue");function k(e,t,n,r,a){return new $("invalid_type",`${T(e)}: cannot read file for "${t}" \u2014 ${r}: ${n}`,E.USAGE,{field:t,received:n,next:`Pass ${a}, relative to the current directory or absolute.`})}d(k,"fileError");function R(e,t,n,r){return r!==void 0?r.providedParams.has(t):Object.prototype.hasOwnProperty.call(n,t)&&n[t]!==void 0}d(R,"isPresent");function ie(e){const t=String(e);return t==="."||t===".."?t.replace(/\./g,"%2E"):encodeURIComponent(t)}d(ie,"encodePathSegmentValue");function _(e){return e.replace(/-([a-z])/g,(t,n)=>n.toUpperCase())}d(_,"paramKey");async function ae(e,t){const n=e.timeouts?.requestMs??Y,r=Date.now()+n;let a=X;for(;;)try{return await se(e,t,r-Date.now())}catch(o){if(!(o instanceof q))throw o;const l=r-Date.now(),p=b(e,t,`${o.detail}; retried with the same request id until the ${n}ms deadline`);if(l<=0||(await new Promise(s=>setTimeout(s,Math.min(a,l))),Date.now()>=r))throw p;a=Math.min(a*2,Z)}}d(ae,"requestUnary");function se(e,t,n){const r=Math.min(e.timeouts?.connectMs??P,n),a=t.url.protocol==="https:"?A:C;return new Promise((o,l)=>{let p=!1,s=null,m=null;const y=d(()=>{s!==null&&clearTimeout(s),m!==null&&clearTimeout(m),s=null,m=null},"clearTimers"),f=d(u=>{p||(p=!0,y(),i.destroy(),l(u))},"fail"),h=d(u=>{p||(p=!0,y(),o(u))},"succeed"),i=a(t.url,{method:t.method},u=>{s!==null&&(clearTimeout(s),s=null);const w=[];u.on("data",g=>w.push(g)),u.on("end",()=>h({status:u.statusCode??0,body:Buffer.concat(w).toString("utf8")})),u.on("error",g=>f(b(e,t,`response interrupted (${N(g)})`))),u.on("close",()=>f(b(e,t,"response closed before the full body")))});for(const[u,w]of t.headers)i.setHeader(u,w);s=setTimeout(()=>f(b(e,t,`connection timed out after ${r}ms`)),r),m=setTimeout(()=>f(b(e,t,`request exceeded the ${n}ms timeout`)),n),i.on("socket",u=>{u.connecting?u.once("connect",()=>c()):c()});const c=d(()=>{s!==null&&(clearTimeout(s),s=null)},"clearConnectTimer");i.on("error",u=>f(ce(e,t,u,"could not reach the backend"))),t.body!==void 0&&i.write(t.body),i.end()})}d(se,"requestUnaryOnce");function ce(e,t,n,r){const a=N(n),o=`${r} (${a})`;return ee.has(a)?new q(o):b(e,t,o)}d(ce,"transportFailure");function de(e,t){let n;try{n=JSON.parse(t)}catch{throw v(e,"response body was not valid JSON","a JSON object matching the declared output")}if(!O(n))throw v(e,`response body was not a JSON object (got ${me(n)})`,"a JSON object matching the declared output");const r=G(e.output,n);if(r!==null){const o=e.output.find(l=>l.name===r.field)?.type??"unknown";throw r.receivedType!==void 0?v(e,`output field "${r.field}" has the wrong type`,`${r.field}: ${o}`):v(e,`response is missing required output field "${r.field}"`,`a "${r.field}" field of type ${o}`)}return n}d(de,"mapUnary2xx");async function ue(e,t){const n=e.timeouts?.connectMs??P,r=e.timeouts?.streamIdleMs??Q,a=t.url.protocol==="https:"?A:C,o=await new Promise((h,i)=>{let c=!1,u=null;const w=d(()=>{u!==null&&(clearTimeout(u),u=null)},"clearConnect"),g=a(t.url,{method:t.method},S=>{c||(c=!0,w(),h(S))});for(const[S,j]of t.headers)g.setHeader(S,j);u=setTimeout(()=>{c||(c=!0,g.destroy(),i(b(e,t,`connection timed out after ${n}ms`)))},n),g.on("socket",S=>{S.connecting?S.once("connect",w):w()}),g.on("error",S=>{c||(c=!0,w(),i(b(e,t,`could not reach the backend (${N(S)})`)))}),t.body!==void 0&&g.write(t.body),g.end()}),l=o.statusCode??0;if(!(l>=200&&l<300)){const h=await le(o);F(e,l,h)}let p=!1,s="",m=null;const y=d(()=>{m!==null&&clearTimeout(m),m=setTimeout(()=>o.destroy(new D),r)},"armIdle"),f=d(()=>{m!==null&&(clearTimeout(m),m=null)},"clearIdle");try{y();for await(const h of o){y(),s+=h.toString("utf8");let i;for(;(i=s.indexOf(`
2
+ `))!==-1;){const c=s.slice(0,i);if(s=s.slice(i+1),c.trim()==="")continue;if(p=!0,U(c),!await M(c+`
3
+ `)){f(),o.destroy();return}}}f(),s.trim()!==""&&(p=!0,U(s),await M(s));return}catch(h){f();const i=h instanceof D?`stream idle for ${r}ms`:`connection error (${N(h)})`;if(p){const c=`${T(e)}: stream interrupted (${i})`;V(`crtr: ${c}`),W({error:"stream_interrupted",message:c,next:"Retry the command to begin a fresh stream."}),process.exitCode=E.NETWORK;return}throw b(e,t,i)}}d(ue,"requestStreaming");function F(e,t,n){const r=fe(t);let a;try{a=JSON.parse(n)}catch{a=void 0}if(O(a)){const o=a.error;if(O(o)&&typeof o.code=="string"&&typeof o.message=="string"){const l=o.code,p=o.message,s=typeof o.field=="string"?o.field:void 0,m=typeof o.next=="string"?o.next:"Inspect the backend response, then retry if appropriate.",y=te.test(l)&&!ne.has(l),f=H(o);throw new $(y?l:"cli_protocol_error",p,r,{...o.received!==void 0?{received:o.received}:{},...s!==void 0?{field:s}:{},...f?K(e.registration.name):{},http_status:t,next:m})}}throw new $("cli_http_error",`${T(e)}: request failed with HTTP ${t}`,r,{http_status:t,next:"Inspect the backend response, then retry if appropriate."})}d(F,"throwNon2xx");function fe(e){return e===400||e===401||e===403||e===422?E.USAGE:e===404?E.NOT_FOUND:e===409?E.AMBIGUOUS:E.GENERAL}d(fe,"deriveExit");function v(e,t,n){return new $("cli_protocol_error",`${T(e)}: ${t}. Expected ${n}.`,E.GENERAL,{received:t,next:`Run \`crtr pkg plugin update ${e.registration.name}\` or inspect the backend response.`})}d(v,"protocolError");function b(e,t,n){return new $("cli_unreachable",`${T(e)}: ${n}`,E.NETWORK,{received:t.url.origin,next:`Check connectivity to ${t.url.host} and retry; run \`crtr pkg plugin update ${e.registration.name}\` if the command surface changed.`})}d(b,"unreachable");function T(e){return`HTTP-transport plugin "${e.registration.name}" command \`${e.commandPath.join(" ")}\``}d(T,"label");function N(e){const t=e;return t?.code??t?.message??String(e)}d(N,"errCode");function le(e){return new Promise(t=>{const n=[];e.on("data",r=>n.push(r)),e.on("end",()=>t(Buffer.concat(n).toString("utf8"))),e.on("error",()=>t(Buffer.concat(n).toString("utf8")))})}d(le,"readAll");function me(e){return e===null?"null":Array.isArray(e)?"array":typeof e}d(me,"typeName");export{ve as invokeHttpLeaf};
@@ -1 +1 @@
1
- var i=Object.defineProperty;var n=(r,e)=>i(r,"name",{value:e,configurable:!0});import"../suppress-experimental-warnings.js";import{runDaemon as c}from"./crtrd.js";function s(r){for(let e=0;e<r.length;e++){const t=r[e];if(t==="--tcp")return r[e+1];if(t!==void 0&&t.startsWith("--tcp="))return t.slice(6)}}n(s,"parseTcpArg");function a(r){return r.includes("--prepare")}n(a,"parsePrepareArg");const p=process.argv.slice(2);await c({tcp:s(p),prepare:a(p)});
1
+ var i=Object.defineProperty;var n=(r,e)=>i(r,"name",{value:e,configurable:!0});import"../suppress-experimental-warnings.js";import{runDaemon as c}from"./crtrd.js";import{configureDaemonHttpDispatcher as o}from"./http-dispatcher.js";function a(r){for(let e=0;e<r.length;e++){const t=r[e];if(t==="--tcp")return r[e+1];if(t!==void 0&&t.startsWith("--tcp="))return t.slice(6)}}n(a,"parseTcpArg");function s(r){return r.includes("--prepare")}n(s,"parsePrepareArg"),o();const p=process.argv.slice(2);await c({tcp:a(p),prepare:s(p)});
@@ -0,0 +1 @@
1
+ export declare function configureDaemonHttpDispatcher(): void;
@@ -0,0 +1 @@
1
+ var i=Object.defineProperty;var n=(t,e)=>i(t,"name",{value:e,configurable:!0});import{EventEmitter as r}from"node:events";import{Agent as l,Client as a,Pool as f,setGlobalDispatcher as m}from"undici";const u=2e3;function o(t){return t instanceof r&&r.prototype.on.call(t,"error",()=>{}),t}n(o,"withErrorListener");function c(t,e){return o(new a(t,e))}n(c,"createClient");function p(){m(o(new l({allowH2:!1,connect:{autoSelectFamilyAttemptTimeout:u},factory:n((t,e)=>e.connections===1?c(t,e):o(new f(t,{...e,factory:c})),"factory")})))}n(p,"configureDaemonHttpDispatcher");export{p as configureDaemonHttpDispatcher};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@north-light/crouter",
3
- "version": "0.3.347",
3
+ "version": "0.3.349",
4
4
  "description": "crtr — agent runtime with memory, plugins, and marketplaces",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
@@ -125,6 +125,7 @@
125
125
  "string-width": "^7.0.0",
126
126
  "tar": "^7.5.22",
127
127
  "typescript": "^5.7.0",
128
+ "undici": "8.10.2",
128
129
  "ws": "^8.21.0",
129
130
  "yaml": "^2.9.0",
130
131
  "zod": "^4.3.6"
package/runtime.lock.json CHANGED
@@ -1,12 +1,12 @@
1
1
  {
2
2
  "name": "@north-light/crouter",
3
- "version": "0.3.347",
3
+ "version": "0.3.349",
4
4
  "lockfileVersion": 3,
5
5
  "requires": true,
6
6
  "packages": {
7
7
  "": {
8
8
  "name": "@north-light/crouter",
9
- "version": "0.3.347",
9
+ "version": "0.3.349",
10
10
  "hasInstallScript": true,
11
11
  "license": "GPL-3.0-only",
12
12
  "workspaces": [
@@ -24,6 +24,7 @@
24
24
  "string-width": "^7.0.0",
25
25
  "tar": "^7.5.22",
26
26
  "typescript": "^5.7.0",
27
+ "undici": "8.10.2",
27
28
  "ws": "^8.21.0",
28
29
  "yaml": "^2.9.0",
29
30
  "zod": "^4.3.6"
@@ -10527,6 +10528,15 @@
10527
10528
  "node": ">=14.17"
10528
10529
  }
10529
10530
  },
10531
+ "node_modules/undici": {
10532
+ "version": "8.10.2",
10533
+ "resolved": "https://registry.npmjs.org/undici/-/undici-8.10.2.tgz",
10534
+ "integrity": "sha512-/y4/bH9YNU5hi9NIrpOuvGXFcxrj3CMrV+/AYpowAYTpHn8gX/XPFjNy766FPoYY0miQhdW977JFWKGNhBdwyQ==",
10535
+ "license": "MIT",
10536
+ "engines": {
10537
+ "node": ">=22.19.0"
10538
+ }
10539
+ },
10530
10540
  "node_modules/undici-types": {
10531
10541
  "version": "7.18.2",
10532
10542
  "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-7.18.2.tgz",
@@ -10859,28 +10869,28 @@
10859
10869
  },
10860
10870
  "packages/crouter-api": {
10861
10871
  "name": "@north-light/crouter-api",
10862
- "version": "0.3.347",
10872
+ "version": "0.3.349",
10863
10873
  "license": "GPL-3.0-only"
10864
10874
  },
10865
10875
  "packages/crouter-env-docker": {
10866
10876
  "name": "@north-light/crouter-env-docker",
10867
- "version": "0.3.347",
10877
+ "version": "0.3.349",
10868
10878
  "license": "GPL-3.0-only"
10869
10879
  },
10870
10880
  "packages/crouter-plugin": {
10871
10881
  "name": "@north-light/crouter-plugin",
10872
- "version": "0.3.347",
10882
+ "version": "0.3.349",
10873
10883
  "license": "GPL-3.0-only",
10874
10884
  "dependencies": {
10875
- "@north-light/crouter-api": "^0.3.347"
10885
+ "@north-light/crouter-api": "^0.3.349"
10876
10886
  }
10877
10887
  },
10878
10888
  "packages/crouter-sdk": {
10879
10889
  "name": "@north-light/crouter-sdk",
10880
- "version": "0.3.347",
10890
+ "version": "0.3.349",
10881
10891
  "license": "GPL-3.0-only",
10882
10892
  "dependencies": {
10883
- "@north-light/crouter-api": "^0.3.347"
10893
+ "@north-light/crouter-api": "^0.3.349"
10884
10894
  }
10885
10895
  }
10886
10896
  }