@hyperscale0/cli 1.0.0-beta.16 → 1.0.0-beta.17

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.
Files changed (2) hide show
  1. package/hyperscale.js +1 -1
  2. package/package.json +2 -2
package/hyperscale.js CHANGED
@@ -117,7 +117,7 @@ ${be(JSON.stringify(r.hsxStructured.document,null,2)," ")}`)),s("Terms:");for
117
117
  `)}let i=Ge({input:process.stdin,output:process.stderr,terminal:!0}),a=new AbortController,c=()=>a.abort();process.stdin.once("end",c),process.stdin.readableEnded&&a.abort();let d;try{try{d=(await i.question("Choose a number or Blueprint slug: ",{signal:a.signal})).trim()}catch(m){throw m?.name!=="AbortError"&&m?.code!=="ABORT_ERR"?m:new u("Start cancelled before a Blueprint was chosen.",{code:"start_cancelled"})}}finally{process.stdin.off("end",c),i.close()}let l=Number(d),p=Number.isInteger(l)?o[l-1]:o.find(({id:m})=>m===d);if(p)return p;throw new u(`No Blueprint matches ${JSON.stringify(d)}.`,{fix:"Run hyperscale start again and choose a listed number or slug."})}async function Se(e,t){Ut(e);let n={};try{await Ht(e,t,n)}catch(o){throw typeof n.apiKey!="string"?o:Lt(o,n.apiKey)}}async function Ht(e,t,n){let o=await k(e,t),r=await T(o,o.token),i=await Jt(e,o),a=e["--name"]??i.name;e["--json"]||s(`Authenticated: ${r.email}`);let c=await Q(o,"/v1/products/blueprint-compose",A({blueprintId:i.id,name:a,tenantId:o.tenantId}),o.token),d=we(c.response,c.text,[o.token]);if(typeof d?.productId!="string"||!dt.test(d.productId)||typeof d?.productBuildId!="string"||d?.blueprintId!==i.id)throw new u("product.blueprint.compose returned an invalid start Product");let l=d?.shown_once;if(typeof l!="string"||l.length===0)throw new u("The composed Product did not return its one-time API key. Choose a new Product name and run hyperscale start again.",{code:"start_api_key_unavailable"});n.apiKey=l;let p=ye(c.response);await G(t,{...o,selectedProduct:d.productId}),e["--json"]||(s(`Product: ${d.productId}`),s(`Blueprint: ${d.blueprintId}`),jt("Compose",p));let m=[`hyperscale compose plan product.hsx --product ${d.productId}`],f="Composition completed. Run SDK journeys against your Product.",$={blueprintId:d.blueprintId,composeOnly:!0,nextCommands:m,notice:f,productBuildId:d.productBuildId,productId:d.productId,receipts:[{stage:"product.blueprint.compose",...p}],...typeof d.startKeyId=="string"?{startKeyId:d.startKeyId}:{},shown_once:l};if(e["--json"]){w($);return}s(f),s(`Shown once Product API key: ${l}`),s("Next:");for(let g of m)s(` ${g}`);s(" Run journeys with the Hyperscale SDK using the Product API key above.")}async function Kt(e,t){let n=e["--blueprint"],o=e["--name"];if(!n)throw new u("product create needs --blueprint <id>");if(!o)throw new u("product create needs --name <name>");let r=await k(e,t),i;try{i=await C(r,"/v1/products",{tenantId:r.tenantId},"product.list",r.token,[r.token])}catch(m){if(!(m instanceof E)||m.status!==403)throw m}let a=o.trim().toLocaleLowerCase("en-US"),c=(i?v(i,"product.list"):[]).find(m=>{let f=m?.displayName??m?.name;return typeof f=="string"&&f.trim().toLocaleLowerCase("en-US")===a});if(c){let m=c.productId??c.id??"<id>";throw new u(`A Product named ${JSON.stringify(o.trim())} already exists as ${m}.`,{code:"duplicate_product_name",fix:`Use "hyperscale product select ${m}" or choose another --name.`})}let d=await b(r,"/v1/products/blueprint-compose",A({blueprintId:n,name:o,tenantId:r.tenantId}),r.token,[r.token]);if(typeof d?.productId!="string"||typeof d?.blueprintId!="string"||typeof d?.productBuildId!="string")throw new u("product.blueprint.compose returned an invalid Product");await G(t,{...r,selectedProduct:d.productId});let l=typeof d?.shown_once=="string"&&d.shown_once.length>0?d.shown_once:void 0,p={blueprintId:d.blueprintId,nextSteps:[`hyperscale product show ${d.productId}`,...l?[]:['hyperscale key create --name "Founder CLI"']],productBuildId:d.productBuildId,productId:d.productId,selectedProduct:d.productId,...typeof d.startKeyId=="string"?{startKeyId:d.startKeyId}:{},...l?{shown_once:l}:{}};if(e["--json"]){w(p);return}s(`Product: ${p.productId}`),s(`Blueprint: ${p.blueprintId}`),s(`Build: ${p.productBuildId}`),s(`Selected: ${p.selectedProduct}`),p.shown_once&&s(`Shown once Product API key: ${p.shown_once}`),s("Next:");for(let m of p.nextSteps)s(` ${m}`)}function De(e){return new URLSearchParams({tenantId:e}).toString()}async function Bt(e,t){let n=await k(e,t),o=await C(n,"/v1/products",{tenantId:n.tenantId},"product.list",n.token,[n.token]),r=v(o,"product.list");if(e["--json"]){w(o);return}if(r.length===0){s('No Products yet. Run "hyperscale blueprint list", then "hyperscale product create --blueprint <id> --name <name>".');return}s("ID Name Status");for(let i of r){let a=i.productId??i.id??"unknown",c=i.displayName??i.name??"unnamed";s(`${a} ${c}${i.status?` ${i.status}`:""}`)}}async function Yt(e,t,n){let o=await k(e,t),r=n??o.selectedProduct;if(!r)throw new u("product show needs an id because no Product is selected. Create a Product first.");let i=await b(o,`/v1/products/${encodeURIComponent(r)}?${De(o.tenantId)}`,{},o.token,[o.token]);if(e["--json"]){w(i);return}qt(i,r)}function qt(e,t){let n=e?.displayName??e?.name??"unnamed",o=e?.status??"unknown",r=e?.blueprint,i=r?.id?`${r.name??r.id}${r.name?` (${r.id})`:""}`:"custom composition",a=e?.cost?.currency??"SAR",c=e?.pricing?.current?.monthlySar??e?.cost?.platformMonthlySar,d=e?.pricing?.current?.setupSar??e?.cost?.platformSetupSar,l=[...Array.isArray(e?.readiness?.outstandingLiveRequirements)?e.readiness.outstandingLiveRequirements:[],...Array.isArray(e?.readiness?.liveUnavailableCapabilities)?e.readiness.liveUnavailableCapabilities.map(p=>`unavailable:${p}`):[],...Array.isArray(e?.cost?.blockers)?e.cost.blockers.map(p=>p?.code??"pricing"):[]];s(`Name: ${n}`),s(`Product: ${e?.productId??t}`),s(`Status: ${o}`),s(`Blueprint: ${i}`),e?.pricing?.scheduled?(s(`Current billing price: ${a} ${e.pricing.current.monthlySar}/mo`),s(`Accepted price from ${e.pricing.scheduled.effectiveAt}: ${a} ${e.pricing.scheduled.monthlySar}/mo`)):s(`Monthly: ${c==null?"not returned":`${a} ${c}`}`),s(`Setup: ${d==null?"not returned":`${a} ${d}`}`),s(`Live: ${e?.readiness?.live===!0?"active":"not active"}`),s(`Live blockers: ${l.length>0?l.join(", "):"none"}`);for(let[p,m]of[["openapi","OpenAPI"],["mcp","MCP"],["sdk","SDK"],["graphql","GraphQL"]]){let f=e?.surfaces?.[p];f?.url&&s(`${m}: ${f.url}`)}s("Next:"),s(` hyperscale key create --name "Founder CLI" --product ${e?.productId??t}`)}async function Ft(e,t,n){if(!n)throw new u("product select needs a Product id");let o=await k(e,t),r=await b(o,`/v1/products/${encodeURIComponent(n)}?${De(o.tenantId)}`,{},o.token,[o.token]);if(r?.productId!==n)throw new u("product.retrieve returned the wrong Product");await G(t,{...o,selectedProduct:n});let i={productId:n,selected:!0};e["--json"]?w(i):s(`Selected Product: ${r.displayName??n} (${n})`)}function Mt(e){return e.map(t=>`${t.path}: error [composer] ${t.code}: ${t.message}`)}async function zt(e){if(!e)throw new u("compose needs a .hsx file");if(!e.endsWith(".hsx"))throw new u(`compose reads a .hsx file, got ${e}`);let t;try{t=await U(e,"utf8")}catch(n){throw new u(`Could not read ${e}: ${n.message}`)}return{file:e,source:t}}function Vt(e){if(!e||typeof e!="object"||typeof e.ok!="boolean"||!Array.isArray(e.issues))throw new u("composer.check returned an invalid result");return{issues:e.issues.map(n=>{if(!n||typeof n!="object"||typeof n.code!="string"||typeof n.message!="string"||typeof n.path!="string")throw new u("composer.check returned an invalid issue");return{code:n.code,message:n.message,path:n.path}}),ok:e.ok}}async function ge(e,t,n,o="none"){let r=await zt(n),i=await k(e,t),a=o==="required"?K(i,e):o==="optional"?He(i,e):void 0,c=await Q(i,"/v1/composer/check",A({tenantId:i.tenantId,document:r.source,...e["--catalog-revision"]?{catalogRevisionId:e["--catalog-revision"]}:{}}),i.token),d=ye(c.response,[i.token]),l=Vt(we(c.response,c.text,[i.token]));if(!l.ok)throw new B(["composer.check refused the program.",...Mt(l.issues)].join(`
118
118
  `),{file:n,issues:l.issues,...d});return{check:l,receipt:d,context:i,productId:a,program:r,catalogRevisionId:e["--catalog-revision"]}}async function Wt(e,t,n){let o=await ge(e,t,n,"none");if(e["--json"]){w({command:"composer.check",file:n,issues:o.check.issues,ok:!0,...o.receipt});return}s(`Check passed: ${n}`)}async function Je(e,t){let n=await Q(e.context,"/v1/composer/plan",A({document:e.program.source,tenantId:e.context.tenantId,...e.productId?{productId:e.productId}:{},...e.catalogRevisionId?{catalogRevisionId:e.catalogRevisionId}:{}}),e.context.token),o=we(n.response,n.text,[e.context.token]),r=ye(n.response,[e.context.token]);if(!o||typeof o!="object"||typeof o.summary!="string"||!Array.isArray(o.actions)||!o.pricing||typeof o.pricing!="object")throw new u("composer.plan returned an invalid result");let i=o.actions.filter(a=>!a||typeof a!="object"||a.kind!=="configure_product");if(i.length>0)throw new B([o.summary,...i.map(a=>a&&typeof a=="object"?`${a.kind??"unknown"} ${a.target??"unknown"} ${a.detail??"Composer refused this action."}`:"unknown unknown Composer returned an invalid refusal action.")].join(`
119
119
  `),{actions:i,file:t,...r,...e.productId?{productId:e.productId}:{}});return{...o,...r}}async function Gt(e,t,n){let o=await ge(e,t,n,"optional"),r=await Je(o,n);if(e["--json"]){w({command:"composer.plan",file:n,check:{...o.check,...o.receipt},plan:r,...o.productId?{productId:o.productId}:{}});return}s(r.summary);for(let i of r.actions)s(`${i.kind} ${i.target} ${i.detail}`);r.pricing?.scheduled?(s(`Current billing price: SAR ${r.pricing.current.monthlySar}/mo`),s(`Candidate price from ${r.pricing.scheduled.effectiveAt}: SAR ${r.pricing.scheduled.monthlySar}/mo`),s(`Pricing identity: ${r.pricing.scheduled.pricingIdentity}`)):(s(`Monthly: SAR ${r.pricing.monthlySar}`),s(`Activation: SAR ${r.pricing.activationSar}`))}async function Xt(e,t,n){if(!e["--confirm"]&&!e["--yes"])throw new u("compose apply changes the selected Product. Pass --confirm, or --yes for an agent.");let o=e["--pricing-identity"];if(!o&&e["--plan-file"]){let c=e["--plan-file"];try{let d=await U(c,"utf8"),l=JSON.parse(d);o=l.plan?.pricing?.scheduled?.pricingIdentity??l.pricing?.scheduled?.pricingIdentity??l.pricingIdentity}catch(d){throw new u(`Failed to read saved plan file ${c}: ${d.message}`)}}let r=await ge(e,t,n,"required"),i=await Je(r,n);if(i.pricing?.scheduled&&!o){if(!e["--yes"])throw new u(`compose apply --confirm requires --pricing-identity (or --plan-file). Run "hyperscale compose plan ${n}" to review candidate pricing and copy the pricing identity, or pass --yes to accept the current candidate.`);o=i.pricing.scheduled.pricingIdentity}let a=await b(r.context,"/v1/products/recompose",A({program:{source:r.program.source},...r.catalogRevisionId?{catalogRevisionId:r.catalogRevisionId}:{},...o?{pricingIdentity:o}:{},tenantId:r.context.tenantId,productId:r.productId},e["--idempotency-key"]),r.context.token,[r.context.token]);if(!a||typeof a.productBuildId!="string")throw new u("product.recompose returned no new build identity");if(e["--json"]){w({command:"product.recompose",file:n,output:a});return}s(`Product: ${a.productId??r.productId}`),s(`Build: ${a.productBuildId}`),a.buildDigest&&s(`Digest: ${a.buildDigest}`),a.pricing?.scheduled&&(s(`Current billing price: SAR ${a.pricing.current.monthlySar}/mo`),s(`Accepted price from ${a.pricing.scheduled.effectiveAt}: SAR ${a.pricing.scheduled.monthlySar}/mo`))}function He(e,t){let n=t["--product"]??e.selectedProduct;return typeof n=="string"&&n.length>0?n:void 0}function K(e,t){let n=He(e,t);if(!n)throw new u("No Product selected. Pass --product <id> or create a Product first.");return n}async function F(e,t,n){let o=await W(t),r=K(o??{},e),i=j(e,t,o??{});if(o&&(i.baseUrl!==o.baseUrl||i.environment!==o.environment))throw new u(`The selected Product belongs to ${o.baseUrl} (${o.environment}). Select a Product at the configured API origin first.`);let a=e["--api-key"]??t.HYPERSCALE_API_KEY;if(!a)throw Te(r);let c={...i,apiKey:a,productId:r};return await Qt(c,r,n),c}async function Qt(e,t,n){let o=`/v1/products/${encodeURIComponent(t)}/operation-set`,{response:r,text:i}=await J(e,o,{},n);if(r.ok)return;let a;try{a=JSON.parse(i)?.error?.message}catch{a=void 0}throw typeof a=="string"&&a.includes("does not match API key Product")?new u(`${a} Or set HYPERSCALE_API_KEY to a key for ${t}, or pass that key with --api-key.`):H(r,i,[e.apiKey])}async function Ke(e,t){let n=`/v1/products/${encodeURIComponent(e.productId)}/operation-set`,{response:o,text:r}=await J(e,n,{},t);if(!o.ok)throw Ye(o,r,[e.apiKey]);return tn(r,o.status)}async function Zt(e,t,n){let o=await F(e,t),r=await Ke(o);if(n){en(r,n,e);return}if(e["--json"]){w(r);return}if(r.status==="legacy"){s("This Product uses a legacy surface. It has no frozen public actions yet."),s(`Build: ${r.productBuildId}`);return}if(r.publicActions.length===0)s("No public actions");else{s("Operation ID Input Kind");for(let i of r.publicActions){let a=i.idempotencyPolicy?.mode==="not_required"?"read-only":"mutation";s(`${i.instrument}.${i.name} ${rn(i.inputSchema)} ${a}`)}}if(r.setupOperations.length>0){s("Setup operations (run with hyperscale call)");for(let i of r.setupOperations)s(i.operationName)}if(r.readOperationIds.length>0){s("Reads (run with hyperscale call)");for(let i of r.readOperationIds)s(on(i))}s(`Digest: ${r.tenantOperationSetDigest}`),s(`Setup digest: ${r.tenantSetupOperationSetDigest}`),s(`Read digest: ${r.tenantReadOperationSetDigest}`),s(`Build: ${r.productBuildId}`),s(`Surface version: ${r.tenantSurfaceVersion}`)}function en(e,t,n){if(e.status==="legacy")throw new u(`This Product uses a legacy surface and has no frozen public action named ${t}. Run "hyperscale product actions" after rebuilding the Product.`);let o=e.publicActions.find(c=>c&&`${c.instrument}.${c.name}`===t),r=nn(t),i=e.setupOperations.find(c=>c&&(c.operationId===t||c.operationId===r||c.operationName===t));if(i){let{inputSchema:c,operationId:d,operationName:l}=i,p={status:e.status,productBuildId:e.productBuildId,tenantSurfaceVersion:e.tenantSurfaceVersion,tenantSetupOperationSetDigest:e.tenantSetupOperationSetDigest,setupOperationId:d,operationName:l,command:`hyperscale call ${l}`,inputSchema:c};if(n["--json"]){w(p);return}s(`Operation ID: ${d}`),s(`Operation name: ${l}`),s(`Run: hyperscale call ${l}`),s(`Input schema: ${JSON.stringify(c,null,2)}`),(!Array.isArray(c.required)||c.required.length===0)&&s("Input: omit --input or pass {}."),s(`Setup digest: ${e.tenantSetupOperationSetDigest}`),s(`Build: ${e.productBuildId}`),s(`Surface version: ${e.tenantSurfaceVersion}`);return}if(!o)throw new u(`Unknown frozen public action: ${t}. Run "hyperscale product actions" to list exact names.`);let a={status:e.status,productBuildId:e.productBuildId,tenantSurfaceVersion:e.tenantSurfaceVersion,tenantOperationSetDigest:e.tenantOperationSetDigest,publicAction:o};if(n["--json"]){w(a);return}s(`Operation ID: ${o.instrument}.${o.name}`),s(`Instrument: ${o.instrument}`),s(`Input schema: ${JSON.stringify(o.inputSchema,null,2)}`),s(`Output schema: ${JSON.stringify(o.outputSchema,null,2)}`),s(`Actor policy: ${JSON.stringify(o.actorPolicy,null,2)}`),s(`Port policy: ${JSON.stringify(o.portPolicy,null,2)}`),s(`Idempotency policy: ${JSON.stringify(o.idempotencyPolicy,null,2)}`),s(`Receipt policy: ${JSON.stringify(o.receiptPolicy,null,2)}`),s(`Receipt evidence: ${JSON.stringify(o.receiptEvidence,null,2)}`),s(`Digest: ${e.tenantOperationSetDigest}`),s(`Build: ${e.productBuildId}`),s(`Surface version: ${e.tenantSurfaceVersion}`)}function tn(e,t){let n;try{n=JSON.parse(e)}catch{throw new u(`HTTP ${t} returned invalid JSON`)}if(!n||typeof n!="object"||n.status!=="legacy"&&n.status!=="frozen"||typeof n.productBuildId!="string")throw new u("The Product operation set is not in the expected format. Upgrade the CLI.");if(n.status==="legacy")return n;if(typeof n.tenantSurfaceVersion!="number"||typeof n.tenantOperationSetDigest!="string"||typeof n.tenantReadOperationSetDigest!="string"||typeof n.tenantSetupOperationSetDigest!="string"||!Array.isArray(n.publicActions)||!Array.isArray(n.readOperationIds)||!Array.isArray(n.setupOperationIds)||!Array.isArray(n.setupOperations))throw new u("The Product operation set is not in the expected format. Upgrade the CLI.");return n}function nn(e){return e.replaceAll(".","_")}function on(e){for(let t of["create","list","retrieve"]){let n=`_${t}`;if(e.endsWith(n))return`${e.slice(0,-n.length)}.${t}`}return e}function rn(e){if(!e||typeof e!="object")return"input schema unavailable";let t=e.properties&&typeof e.properties=="object"&&!Array.isArray(e.properties)?e.properties:{},n=new Set(Array.isArray(e.required)?e.required.filter(r=>typeof r=="string"):[]),o=Object.entries(t).map(([r,i])=>`${r}${n.has(r)?"":"?"}: ${Be(i)}`);return o.length===0?"no input":o.join(", ")}function Be(e){return!e||typeof e!="object"?"value":Array.isArray(e.enum)&&e.enum.length>0?e.enum.map(t=>String(t)).join(" | "):e.type==="array"?`${Be(e.items)}[]`:typeof e.type=="string"?typeof e.format=="string"?`${e.type} (${e.format})`:e.type:"value"}async function an(e,t,n){if(!n)throw new u("product run needs a public action");let o=await F(e,t,n),r=await Ke(o,n);sn(r,n);let i=await qe(e),a=e["--idempotency-key"]??globalThis.crypto.randomUUID(),{response:c,text:d}=await J(o,`/v1/operations/${encodeURIComponent(n)}`,{body:JSON.stringify(i),headers:{"content-type":"application/json","idempotency-key":a},method:"POST"},n);if(!c.ok)throw Ye(c,d,[o.apiKey],{action:n});let l=c.headers.get("hyperscale-operation-id"),p=c.headers.get("hyperscale-receipt-id"),m=c.headers.get("x-request-id"),f=l?y(l,[o.apiKey]):null,$=p?y(p,[o.apiKey]):null,g=m?y(m,[o.apiKey]):null;if(e["--json"]){w({idempotencyKey:a,...g?{requestId:g}:{},operationId:f,receiptId:$,output:cn(d)});return}f&&s(`Operation: ${f}`),$&&s(`Receipt: ${$}`),s(`Idempotency key: ${a}`);let h=Fe(d);h&&s(h)}function sn(e,t){if(e.status==="legacy")throw new u(`This Product uses a legacy surface and has no frozen public action named ${t}. Run "hyperscale product actions" after rebuilding the Product.`);let n=e.publicActions.find(r=>r&&`${r.instrument}.${r.name}`===t);if(n)return n;let o=e.publicActions.map(r=>`${r.instrument}.${r.name}`).map(r=>({candidate:r,distance:ue(t,r)})).sort((r,i)=>r.distance-i.distance||r.candidate.localeCompare(i.candidate)).slice(0,3).map(({candidate:r})=>r);throw new u(`Unknown frozen public action: ${t}. Closest valid names: ${o.join(", ")}. Run "hyperscale product actions" to list exact names.`)}function cn(e){if(e.trim()==="")return null;try{return JSON.parse(e)}catch{return e}}function Ye(e,t,n=[],o={}){let r=y(t.trim(),n),i;try{i=JSON.parse(t)}catch{return new u(`HTTP ${e.status}${r?` \xB7 ${r}`:""}`)}if(!i?.error||typeof i.error.message!="string")return new u(`HTTP ${e.status}`);let a=typeof i.error.code=="string"?i.error.code:"user_error",c=a==="user_error"?"":`${a}: `,d=y(`HTTP ${e.status} \xB7 ${c}${i.error.message}`,n),l=un(i.error.details,n),p;a==="idempotency_conflict"?p="Reuse the same key only with the same operation and input. Use a new unique key for a different request.":[i.error.message,...l].some(x=>typeof x=="string"&&x.includes("[Truncated]"))&&o.action&&(p=`Run "hyperscale product actions ${o.action}" to read the full input schema and allowed values.`);let m=e.headers.get("x-request-id")??(i&&typeof i=="object"&&typeof i.requestId=="string"?i.requestId:void 0),f=e.headers.get("hyperscale-operation-id")??void 0,$=e.headers.get("hyperscale-receipt-id")??void 0,g=m?y(m,n):void 0,h=f?y(f,n):void 0,I=$?y($,n):void 0,P=new u([d,...l].join(`
120
- `),{code:a,...i.error.details?{details:M(i.error.details,n)}:{},...p?{fix:p}:{}});return g&&(P.requestId=g),h&&(P.operationId=h),I&&(P.receiptId=I),P}function M(e,t){return typeof e=="string"?y(e,t):Array.isArray(e)?e.map(n=>M(n,t)):e&&typeof e=="object"?Object.fromEntries(Object.entries(e).map(([n,o])=>[y(n,t),M(o,t)])):e}function un(e,t){if(!e||typeof e!="object")return[];if(Array.isArray(e.issues))return e.issues.flatMap(o=>{if(!o||typeof o!="object")return[];let i=(Array.isArray(o.path)?o.path.join("."):"input")||"input";return typeof o.message=="string"?[`${i}: ${y(o.message,t)}`]:[]});let n=[];return ce(e,"",n,t),n}function ce(e,t,n,o){if(Array.isArray(e)){if(e.every(r=>r===null||typeof r!="object")){n.push(`${Ae(t)}: ${y(e.join(", "),o)}`);return}e.forEach((r,i)=>ce(r,`${t}[${i}]`,n,o));return}if(e&&typeof e=="object"){for(let[r,i]of Object.entries(e))ce(i,t?`${t}.${r}`:r,n,o);return}t&&n.push(`${Ae(t)}: ${y(String(e),o)}`)}function Ae(e){let t=e.replace(/([a-z0-9])([A-Z])/g,"$1 $2").replaceAll("."," ");return t.charAt(0).toUpperCase()+t.slice(1)}async function dn(e,t){let n=await k(e,t),o=K(n,e),r=await b(n,"/v1/sandbox-api-keys",A({name:e["--name"]??"Founder CLI",tenantId:n.tenantId,productId:o}),n.token,[n.token]);if(e["--json"]){w(r);return}s(`Key: ${r.apiKeyId??"unknown"}`),s(`Product: ${r.productId??o}`),s(`Status: ${r.status??"unknown"}`),r.secret?(s(`Secret: ${r.secret}`),s("Store it now. Hyperscale will not return it again."),s("Next:"),s(` export HYPERSCALE_API_KEY=${ln(r.secret)}`),s(` hyperscale product actions --product ${o}`)):s("The key already existed, so the one-time secret is unavailable.")}function ln(e){return`'${String(e).replaceAll("'",`'"'"'`)}'`}async function pn(e,t){let n=await k(e,t),o=K(n,e),r=await C(n,"/v1/api-keys",{tenantId:n.tenantId},"api_key.list",n.token,[n.token]),i=v(r,"api_key.list").filter(c=>c.productId===o),a={...r,items:i};if(e["--json"]){w(a);return}for(let c of i)s(`${c.apiKeyId} ${c.name??"unnamed"} ${c.status??"unknown"}`)}async function mn(e,t,n){if(!n)throw new u("key revoke needs an API key id");let o=await k(e,t),r=K(o,e),i=await b(o,`/v1/api-keys/${encodeURIComponent(n)}/revoke`,A({tenantId:o.tenantId,productId:r}),o.token,[o.token]);e["--json"]?w(i):s(`Key ${i.apiKeyId??n}: ${i.status??"revoked"}`)}async function fn(e,t){let n=await k(e,t),o=n.identity??await T(n,n.token),r=he(n,o);if(e["--json"]){w(r);return}s(`User: ${o.email}`),s(`Tenant: ${o.tenantId}`),s(`Role: ${o.role}`),s(`Token: ${o.name}`),s(`Expires: ${o.expiresAt}`)}async function hn(e,t,n){let o=await Le(e),r=n?n.toLowerCase():null,i=r?o.operations.filter(c=>c.name.toLowerCase().includes(r)||c.path.toLowerCase().includes(r)):o.operations;if(t["--json"]){s(JSON.stringify(i,null,2));return}if(i.length===0){s(n?`No operation matches ${n}`:"No operations");return}let a=Math.max(...i.map(c=>c.name.length));for(let c of i)s(`${c.name.padEnd(a)} ${c.method.padEnd(6)}${c.path}`)}async function yn(e,t){let n=await k(e,t),o=await C(n,"/v1/activity",{tenantId:n.tenantId},"activity.list",n.token,[n.token]),r=v(o,"activity.list");if(e["--json"]){w(o);return}s("Time Activity Target Status");for(let i of r){let a=i.operation??i.auditEvent??"activity",c=i.resourceKind&&i.resourceId?`${i.resourceKind}:${i.resourceId}`:i.resourceKind??i.resourceId??"-";s(`${i.occurredAt??"unknown"} ${a} ${c} ${i.status??"recorded"}`)}}function wn(e,t){let n={...t},o=[],r=e.path.replace(/\{([^}]+)\}/g,(i,a)=>{let c=n[a];return c==null?(o.push(a),""):(delete n[a],encodeURIComponent(String(c)))});if(o.length>0)throw new u(`${e.name} needs ${o.join(", ")} in --input`);return{path:r,remaining:n}}function gn(e){let t=new URLSearchParams;for(let[o,r]of Object.entries(e))r!=null&&t.set(o,typeof r=="string"?r:JSON.stringify(r));let n=t.toString();return n?`?${n}`:""}function ue(e,t){let n=Array.from({length:t.length+1},(o,r)=>r);for(let o=1;o<=e.length;o+=1){let r=[o];for(let i=1;i<=t.length;i+=1)r[i]=Math.min(r[i-1]+1,n[i]+1,n[i-1]+(e[o-1]===t[i-1]?0:1));n.splice(0,n.length,...r)}return n[t.length]}function In(e,t){let n=e.find(i=>i.name===t);if(n)return n;let o=e.filter(i=>i.operationId===t);if(o.length===1)return o[0];if(o.length>1)throw new u(`${t} matches more than one operation. Use one of: ${o.map(i=>i.name).join(", ")}.`);let r=e.map(i=>({candidate:i,distance:Math.min(ue(t,i.name),ue(t,i.operationId))})).sort((i,a)=>i.distance-a.distance||i.candidate.name.localeCompare(a.candidate.name)).slice(0,3).flatMap(({candidate:i})=>[i.name,i.operationId]);throw new u(`${t} is not an operation in the selected Product's machine document. Closest valid names: ${r.join(", ")}.`)}async function $n(e,t,n){if(!n)throw new u("call needs an operation name");let o=await Le(e),r=In(o.operations,n),i=await qe(t),{path:a,remaining:c}=wn(r,i),d={method:r.method},l=a;r.method==="GET"?l+=gn(c):(d.body=JSON.stringify(c),d.headers={"content-type":"application/json",...r.idempotency==="not_required"?{}:{"idempotency-key":t["--idempotency-key"]??globalThis.crypto.randomUUID()}});let{response:p,text:m}=await J(e,l,d);if(p.ok){if(t["--json"]){let f=kt(m),$=p.headers.get("x-request-id")??(f&&typeof f=="object"&&typeof f.requestId=="string"?f.requestId:null),g=p.headers.get("hyperscale-operation-id")??null,h=p.headers.get("hyperscale-receipt-id")??null,I=Ue(p.headers),P=$?y($,[e.apiKey]):null,x=g?y(g,[e.apiKey]):null,Me=h?y(h,[e.apiKey]):null,ze=I?y(I,[e.apiKey]):null;w({status:p.status,data:f,requestId:P,operationId:x,receiptId:Me,traceId:ze});return}s(Fe(m));return}throw H(p,m,[e.apiKey])}async function qe(e){if(e["--input"]!==void 0&&e["--input-file"]!==void 0)throw new u("Use only one of --input and --input-file");if(e["--input"]!==void 0)return ne(e["--input"],"--input");if(e["--input-file"]!==void 0){let t;try{t=await U(e["--input-file"],"utf8")}catch(n){throw new u(`Could not read ${e["--input-file"]}: ${n.message}`)}return ne(t,"--input-file")}if(!process.stdin.isTTY){let t=await It();if(t.trim()!=="")return ne(t,"stdin")}return{}}function ne(e,t="--input"){if(e===void 0)return{};let n;try{n=JSON.parse(e)}catch(o){throw new u(`${t} is not valid JSON: ${o.message}`)}if(n===null||typeof n!="object"||Array.isArray(n))throw new u(`${t} must be a JSON object`);return n}function Fe(e){if(e.trim()==="")return"";try{return JSON.stringify(JSON.parse(e),null,2)}catch{return e}}function s(e){process.stdout.write(`${e}
120
+ `),{code:a,...i.error.details?{details:M(i.error.details,n)}:{},...p?{fix:p}:{}});return g&&(P.requestId=g),h&&(P.operationId=h),I&&(P.receiptId=I),P}function M(e,t){return typeof e=="string"?y(e,t):Array.isArray(e)?e.map(n=>M(n,t)):e&&typeof e=="object"?Object.fromEntries(Object.entries(e).map(([n,o])=>[y(n,t),M(o,t)])):e}function un(e,t){if(!e||typeof e!="object")return[];if(Array.isArray(e.issues))return e.issues.flatMap(o=>{if(!o||typeof o!="object")return[];let i=(Array.isArray(o.path)?o.path.join("."):"input")||"input";return typeof o.message=="string"?[`${i}: ${y(o.message,t)}`]:[]});let n=[];return ce(e,"",n,t),n}function ce(e,t,n,o){if(Array.isArray(e)){if(e.every(r=>r===null||typeof r!="object")){n.push(`${Ae(t)}: ${y(e.join(", "),o)}`);return}e.forEach((r,i)=>ce(r,`${t}[${i}]`,n,o));return}if(e&&typeof e=="object"){for(let[r,i]of Object.entries(e))ce(i,t?`${t}.${r}`:r,n,o);return}t&&n.push(`${Ae(t)}: ${y(String(e),o)}`)}function Ae(e){let t=e.replace(/([a-z0-9])([A-Z])/g,"$1 $2").replaceAll("."," ");return t.charAt(0).toUpperCase()+t.slice(1)}async function dn(e,t){let n=await k(e,t),o=K(n,e),r=await b(n,"/v1/sandbox-api-keys",A({name:e["--name"]??"Founder CLI",tenantId:n.tenantId,productId:o}),n.token,[n.token]);if(e["--json"]){w(r);return}s(`Key: ${r.apiKeyId??"unknown"}`),s(`Product: ${r.productId??o}`),s(`Status: ${r.status??"unknown"}`),r.secret?(s(`Secret: ${r.secret}`),s("Store it now. Hyperscale will not return it again."),s("Next:"),s(` export HYPERSCALE_API_KEY=${ln(r.secret)}`),s(` hyperscale product actions --product ${o}`)):s("The key already existed, so the one-time secret is unavailable.")}function ln(e){return`'${String(e).replaceAll("'",`'"'"'`)}'`}async function pn(e,t){let n=await k(e,t),o=K(n,e),r=await C(n,"/v1/api-keys",{productId:o,tenantId:n.tenantId},"api_key.list",n.token,[n.token]),i=v(r,"api_key.list");if(e["--json"]){w(r);return}for(let a of i)s(`${a.apiKeyId} ${a.name??"unnamed"} ${a.status??"unknown"}`)}async function mn(e,t,n){if(!n)throw new u("key revoke needs an API key id");let o=await k(e,t),r=K(o,e),i=await b(o,`/v1/api-keys/${encodeURIComponent(n)}/revoke`,A({tenantId:o.tenantId,productId:r}),o.token,[o.token]);e["--json"]?w(i):s(`Key ${i.apiKeyId??n}: ${i.status??"revoked"}`)}async function fn(e,t){let n=await k(e,t),o=n.identity??await T(n,n.token),r=he(n,o);if(e["--json"]){w(r);return}s(`User: ${o.email}`),s(`Tenant: ${o.tenantId}`),s(`Role: ${o.role}`),s(`Token: ${o.name}`),s(`Expires: ${o.expiresAt}`)}async function hn(e,t,n){let o=await Le(e),r=n?n.toLowerCase():null,i=r?o.operations.filter(c=>c.name.toLowerCase().includes(r)||c.path.toLowerCase().includes(r)):o.operations;if(t["--json"]){s(JSON.stringify(i,null,2));return}if(i.length===0){s(n?`No operation matches ${n}`:"No operations");return}let a=Math.max(...i.map(c=>c.name.length));for(let c of i)s(`${c.name.padEnd(a)} ${c.method.padEnd(6)}${c.path}`)}async function yn(e,t){let n=await k(e,t),o=await C(n,"/v1/activity",{tenantId:n.tenantId},"activity.list",n.token,[n.token]),r=v(o,"activity.list");if(e["--json"]){w(o);return}s("Time Activity Target Status");for(let i of r){let a=i.operation??i.auditEvent??"activity",c=i.resourceKind&&i.resourceId?`${i.resourceKind}:${i.resourceId}`:i.resourceKind??i.resourceId??"-";s(`${i.occurredAt??"unknown"} ${a} ${c} ${i.status??"recorded"}`)}}function wn(e,t){let n={...t},o=[],r=e.path.replace(/\{([^}]+)\}/g,(i,a)=>{let c=n[a];return c==null?(o.push(a),""):(delete n[a],encodeURIComponent(String(c)))});if(o.length>0)throw new u(`${e.name} needs ${o.join(", ")} in --input`);return{path:r,remaining:n}}function gn(e){let t=new URLSearchParams;for(let[o,r]of Object.entries(e))r!=null&&t.set(o,typeof r=="string"?r:JSON.stringify(r));let n=t.toString();return n?`?${n}`:""}function ue(e,t){let n=Array.from({length:t.length+1},(o,r)=>r);for(let o=1;o<=e.length;o+=1){let r=[o];for(let i=1;i<=t.length;i+=1)r[i]=Math.min(r[i-1]+1,n[i]+1,n[i-1]+(e[o-1]===t[i-1]?0:1));n.splice(0,n.length,...r)}return n[t.length]}function In(e,t){let n=e.find(i=>i.name===t);if(n)return n;let o=e.filter(i=>i.operationId===t);if(o.length===1)return o[0];if(o.length>1)throw new u(`${t} matches more than one operation. Use one of: ${o.map(i=>i.name).join(", ")}.`);let r=e.map(i=>({candidate:i,distance:Math.min(ue(t,i.name),ue(t,i.operationId))})).sort((i,a)=>i.distance-a.distance||i.candidate.name.localeCompare(a.candidate.name)).slice(0,3).flatMap(({candidate:i})=>[i.name,i.operationId]);throw new u(`${t} is not an operation in the selected Product's machine document. Closest valid names: ${r.join(", ")}.`)}async function $n(e,t,n){if(!n)throw new u("call needs an operation name");let o=await Le(e),r=In(o.operations,n),i=await qe(t),{path:a,remaining:c}=wn(r,i),d={method:r.method},l=a;r.method==="GET"?l+=gn(c):(d.body=JSON.stringify(c),d.headers={"content-type":"application/json",...r.idempotency==="not_required"?{}:{"idempotency-key":t["--idempotency-key"]??globalThis.crypto.randomUUID()}});let{response:p,text:m}=await J(e,l,d);if(p.ok){if(t["--json"]){let f=kt(m),$=p.headers.get("x-request-id")??(f&&typeof f=="object"&&typeof f.requestId=="string"?f.requestId:null),g=p.headers.get("hyperscale-operation-id")??null,h=p.headers.get("hyperscale-receipt-id")??null,I=Ue(p.headers),P=$?y($,[e.apiKey]):null,x=g?y(g,[e.apiKey]):null,Me=h?y(h,[e.apiKey]):null,ze=I?y(I,[e.apiKey]):null;w({status:p.status,data:f,requestId:P,operationId:x,receiptId:Me,traceId:ze});return}s(Fe(m));return}throw H(p,m,[e.apiKey])}async function qe(e){if(e["--input"]!==void 0&&e["--input-file"]!==void 0)throw new u("Use only one of --input and --input-file");if(e["--input"]!==void 0)return ne(e["--input"],"--input");if(e["--input-file"]!==void 0){let t;try{t=await U(e["--input-file"],"utf8")}catch(n){throw new u(`Could not read ${e["--input-file"]}: ${n.message}`)}return ne(t,"--input-file")}if(!process.stdin.isTTY){let t=await It();if(t.trim()!=="")return ne(t,"stdin")}return{}}function ne(e,t="--input"){if(e===void 0)return{};let n;try{n=JSON.parse(e)}catch(o){throw new u(`${t} is not valid JSON: ${o.message}`)}if(n===null||typeof n!="object"||Array.isArray(n))throw new u(`${t} must be a JSON object`);return n}function Fe(e){if(e.trim()==="")return"";try{return JSON.stringify(JSON.parse(e),null,2)}catch{return e}}function s(e){process.stdout.write(`${e}
121
121
  `)}function w(e){s(JSON.stringify(e,null,2))}function kn(e){for(let t=0;t<e.length;t+=1){let n=e[t];if(!n.startsWith("--"))return n;ve.has(n)&&(t+=1)}}function Pn(e,t){let n=kn(t)==="call",o=t.includes("--json");if(n&&o&&e instanceof E){w({status:e.status,error:e.structuredError??{code:e.code??"http_error",message:e.message},requestId:e.requestId??null,operationId:e.operationId??null,receiptId:e.receiptId??null,traceId:e.traceId??null});let c=typeof e.message=="string"?e.message:e.stack??String(e);process.stderr.write(`${c}
122
122
  `);return}let r=e instanceof u&&typeof e.shownOnce=="string"?e.shownOnce:void 0;if(!o){let c=e instanceof u?e.message:e.stack??String(e),d=e instanceof u&&typeof e.fix=="string"?`
123
123
  Fix: ${e.fix}`:"",l=r?`
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hyperscale0/cli",
3
- "version": "1.0.0-beta.16",
3
+ "version": "1.0.0-beta.17",
4
4
  "description": "Hyperscale CLI: compose Products, manage keys, and call Product operations.",
5
5
  "license": "LicenseRef-Hyperscale-Proprietary",
6
6
  "author": "Hyperscale LLC",
@@ -20,5 +20,5 @@
20
20
  "publishConfig": {
21
21
  "access": "public"
22
22
  },
23
- "gitHead": "67dc24fafb99eaacc2622151f451cbe670ae75e0"
23
+ "gitHead": "bd85e5d6a022fec17562b97d3d79a372a444a9c3"
24
24
  }