@hyperscale0/cli 1.0.0-beta.23 → 1.0.0-beta.24

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 +49 -150
  2. package/package.json +2 -2
package/hyperscale.js CHANGED
@@ -1,152 +1,51 @@
1
1
  #!/usr/bin/env node
2
- import{spawn as Je}from"node:child_process";import{createHash as mt}from"node:crypto";import{createServer as ht}from"node:http";import{createInterface as ft}from"node:readline/promises";import{chmod as ce,mkdir as yt,readdir as wt,readFile as J,rename as gt,unlink as It,writeFile as $t}from"node:fs/promises";import{homedir as kt}from"node:os";import{basename as Pt,dirname as le,join as ee}from"node:path";var $e="https://hyperscale0.ai",ke="sandbox",Pe="hyperscale-cli-session",bt="/v1/personal-access-tokens/current",me=process.platform==="darwin"?"/usr/bin/security":null,At="config.json",be="https://hyperscale0.ai/desk/security/tokens",Ae="https://hyperscale0.ai/request-access",he=`Mint a founder PAT in Hyperscale Portal at ${be}. Open Security, then Personal access tokens.`,St=`Not logged in. Run "hyperscale auth login" to open Hyperscale Portal sign-in. In a headless environment, mint a founder PAT in Hyperscale Portal at ${be}. Open Security, then Personal access tokens. Then set HYPERSCALE_TOKEN or pass --token. Unapproved founders can request access at ${Ae}.`,xt=`Run "hyperscale auth login". For headless use, mint a founder PAT in Hyperscale Portal at ${be}. Open Security, then Personal access tokens. Unapproved founders can request access at ${Ae}.`,fe=3e4,vt=2e3,Tt=120*1e3,Et=/^prd_(sandbox|live)_[a-z0-9]{8,64}$/,Ne=`hyperscale <command> [options]
3
-
4
- The founder command line.
5
-
6
- Concepts:
7
- Blueprint -> Product:
8
- A Blueprint is a public catalog template. Composing from a Blueprint
9
- or raw HSX source creates a tenant Product.
10
- Founder PAT vs Product API key:
11
- A founder Personal Access Token (PAT) manages the company and tenant:
12
- Blueprints, Product creation, composition (plan/apply), and keys.
13
- A Product API key authenticates against one Product's operational
14
- surface and executes runtime actions. The two credentials are not
15
- interchangeable.
16
- Custom product actions vs operation calls:
17
- Product actions ("product actions" and "product run") execute the Product's
18
- frozen, published public contract actions. Platform operations ("ops list"
19
- and "call") invoke catalog operations from the Product machine document.
20
- Credential-free blueprint discovery:
21
- "blueprint list" and "blueprint show" are public discovery commands that
22
- require no authentication or credentials.
23
-
24
- Commands:
25
- start Create a Product and run its first published step
26
- help [command] Print help for hyperscale or a specific command
27
- auth login Sign in through the portal or save a founder PAT
28
- auth status Verify and show the active founder PAT
29
- auth logout [--revoke] Forget the local founder PAT, optionally revoke it
30
- blueprint list List public Blueprints without authentication
31
- blueprint show <id> Show one public Blueprint
32
- product create Create a Product from a Blueprint or HSX source
33
- product list List Products in the signed-in company
34
- product show [id] Show a Product (default: selected Product)
35
- product select <id> Select the default Product for later commands
36
- product actions [operation-id]
37
- List frozen public actions or describe one exactly
38
- product run <operation-id> Run one frozen public action
39
- compose check <file.hsx> Compile and check an HSX program
40
- compose plan <file.hsx> Diff an HSX program against the selected Product
41
- compose apply <file.hsx> Recompose the selected Product from checked HSX
42
- key create Create a sandbox Product API key
43
- key list List keys for the selected Product
44
- key revoke <id> Revoke a Product API key
45
- activity list List company activity
46
- whoami Show the user and company this founder PAT resolves to
47
- ops list [filter] List the product's callable operations (supports substring filter)
48
- call <operation> Call one operation by name or operation id
49
-
50
- Options:
51
- --token <pat> Founder PAT (default: $HYPERSCALE_TOKEN)
52
- --revoke Revoke the active founder PAT during auth logout
53
- --no-browser Skip browser login. Needs a PAT or it fails
54
- --api-key <key> Product API key (default: $HYPERSCALE_API_KEY)
55
- --base-url <url> API origin (default: $HYPERSCALE_BASE_URL, else ${$e})
56
- --environment <name> sandbox or live (default: $HYPERSCALE_ENVIRONMENT, else ${ke})
57
- --blueprint <slug> Blueprint for non-interactive start or product create
58
- --source <file> HSX source file for initial Product creation
59
- --name <name> Product or key name
60
- --product <id> Product id for key commands and Product-key actions
61
- --catalog-revision <id> Tenant catalog revision for HSX composition
62
- --input <json> JSON input object for call or product run
63
- --input-file <path> Read call or product run input from a JSON file
64
- --idempotency-key <key> Idempotency key for a mutation or public action (default: generated)
65
- --confirm Confirm compose apply for a person
66
- --yes Confirm compose apply without a prompt for an agent
67
- --pricing-identity <id> Candidate pricing identity from compose plan (required with --confirm when scheduled pricing exists)
68
- --plan-file <path> Saved JSON plan file from compose plan --json (used with --confirm when scheduled pricing exists)
69
- --json Print machine-readable JSON
70
- --version, -v Print the CLI version
71
- --help, -h Print this help (use "hyperscale help <command>" for command help)
72
-
73
- Founder PAT commands: auth, whoami, product create/list/show, compose check/plan/apply,
74
- key, and activity. Product API key commands: product actions/run, ops list,
75
- and call. The server compiles every compose command against the selected tenant
76
- catalog revision. The two credential types are not interchangeable. Browser
77
- login returns through a single-use localhost callback.
78
-
79
- compose check, plan, and apply exit 2 when the compiler or composer refuses the
80
- program. Command, credential, request, and server failures exit 1.
81
- compose apply requires --confirm (with --pricing-identity or --plan-file only when scheduled pricing exists), or --yes for an agent to accept the current candidate price.
82
- Compose check and plan JSON retain operationId and receiptId when the server
83
- returns them. Plan JSON includes the prerequisite check result and its identifiers.
84
-
85
- Use HYPERSCALE_TOKEN for a founder PAT. Use HYPERSCALE_API_KEY for a Product API
86
- key. The explicit flag wins over its environment variable. Founder logins use
87
- macOS Keychain when available. Set HYPERSCALE_CREDENTIAL_STORE=file to keep the
88
- founder PAT in the owner-only CLI profile instead and skip Keychain access.
89
-
90
- ${he}
91
- Request access at ${Ae}.
92
-
93
- Examples:
94
- hyperscale start
95
- hyperscale start --blueprint vehicle-escrow-marketplace --json
96
- hyperscale whoami
97
- hyperscale auth login
98
- hyperscale auth login --token hyperscale_pat_...
99
- hyperscale blueprint list
100
- hyperscale product create --blueprint luxury-goods-consignment-escrow --name "Luxury Consignment"
101
- hyperscale product create --source company.hsx --name "Company"
102
- hyperscale key create --name "Founder laptop"
103
- hyperscale product actions
104
- hyperscale product actions escrow_order.placeBuyerHold --json
105
- hyperscale product run escrow_order.placeBuyerHold --input '{"escrowOrderId":"eord_sandbox_..."}'
106
- hyperscale compose check product.hsx
107
- hyperscale compose plan product.hsx --json
108
- hyperscale compose apply product.hsx --yes
109
- hyperscale activity list
110
- hyperscale ops list account
111
- hyperscale call account.list --input '{"limit":5}'
112
- hyperscale call account.list --input-file input.json
113
- printf '{"limit":5}' | hyperscale call account.list
114
- hyperscale call account.retrieve --input '{"accountId":"acct_sandbox_..."}'
115
- `,ue={start:{usage:"start [--blueprint <slug>] [--name <name>] [--json]",summary:"Choose a catalog company, create its Product, and run its first published runnable step.",options:["--blueprint <slug> Skip the prompt and choose this catalog Blueprint.","--name <name> Product name. Defaults to the selected Blueprint name.","--json Print one machine document, including the one-time API key under shown_once."],notes:["The command requires an active founder login.","Without --blueprint, start requires an interactive terminal and asks which company to build.","Scripts and agents must pass --blueprint <slug>.","Machine output returns the Product API key only under shown_once.","A Blueprint without a published runnable step stops after composition and names the next command."],example:"hyperscale start --blueprint vehicle-escrow-marketplace --json"},"auth login":{usage:"auth login [--no-browser] [--token <pat>]",summary:"Sign in through the portal callback or save a founder PAT.",options:["--no-browser Skip browser login. Saves the PAT or fails without one.","--token <pat> Founder PAT. Defaults to HYPERSCALE_TOKEN.","--json Print the saved session summary as one JSON document."],notes:["Without a PAT, the CLI opens portal sign-in and accepts one","localhost callback.","With --no-browser and no token, the command fails with a login","error and fix text. Pass HYPERSCALE_TOKEN or --token to save a PAT.","Set HYPERSCALE_CREDENTIAL_STORE=file to use the 0600 profile file","instead of macOS Keychain."],example:"hyperscale auth login --no-browser"},"auth status":{usage:"auth status [--json]",summary:"Verify and show the active founder PAT and selected Product.",options:["--json Print machine-readable JSON."],example:"hyperscale auth status --json"},"auth logout":{usage:"auth logout [--revoke] [--json]",summary:"Forget the local founder PAT. Optionally revoke it first.",options:["--revoke Revoke the PAT before deleting local state.","--json Print machine-readable JSON."],example:"hyperscale auth logout --revoke"},"blueprint list":{usage:"blueprint list [--json]",summary:"List public Blueprints without authentication.",options:["--json Print the complete collection as JSON."],example:"hyperscale blueprint list"},"blueprint show":{usage:"blueprint show <id> [--json]",summary:"Show one public Blueprint.",options:["--json Print the complete Blueprint as JSON."],example:"hyperscale blueprint show luxury-goods-consignment-escrow"},"product create":{usage:"product create (--blueprint <id> | --source <file>) --name <name> [--catalog-revision <id>] [--json]",summary:"Create and select a Product. The command refuses a duplicate name.",options:["--blueprint <id> Blueprint id to compose from.","--source <file> HSX source file for initial Product creation.","--name <name> Required Product name.","--catalog-revision <id> Tenant catalog revision for HSX composition.","--json Print the creation summary as JSON."],example:'hyperscale product create --blueprint luxury-goods-consignment-escrow --name "Luxury Consignment"'},"product list":{usage:"product list [--json]",summary:"List Products in the signed-in company.",options:["--json Print the complete collection as JSON."],example:"hyperscale product list"},"product show":{usage:"product show [id] [--json]",summary:"Show a Product summary, or the complete Product document as JSON.",options:["--json Print the complete Product document."],example:"hyperscale product show prd_sandbox_..."},"product select":{usage:"product select <id> [--json]",summary:"Verify a Product and save it as the default for later commands.",options:["--token <pat> Founder PAT. Defaults to HYPERSCALE_TOKEN or the stored login.","--base-url <url> API origin. Defaults to the active founder profile.","--environment <name> sandbox or live. Defaults to the active founder profile.","--json Print the selected Product id as JSON."],notes:["The CLI stores the selection in the active founder profile.","Product show, compose plan/apply, and key commands use it when --product is absent.","Product create and start select the Product they create."],example:"hyperscale product select prd_sandbox_..."},"product actions":{usage:"product actions [operation-id] [--product <id>] [--json]",summary:"List frozen public actions or show one action's full schemas.",options:["--product <id> Product to inspect. Defaults to the selected Product.","--api-key <key> Product API key. Defaults to HYPERSCALE_API_KEY.","--json Print machine-readable JSON."],notes:["Setup operation details include the public input schema used by hyperscale call.","When that schema has no required fields, omit --input or pass {}."],example:"hyperscale product actions escrow_order.placeBuyerHold --json"},"product run":{usage:"product run <operation-id> [--input <json> | --input-file <path>] [--idempotency-key <key>] [--json]",summary:"Run one frozen public action with a Product API key.",options:["--input <json> JSON input object. Stdin is used when piped.","--input-file <path> Read the JSON input object from a file.","--product <id> Product to call. Defaults to the selected Product.","--api-key <key> Product API key. Defaults to HYPERSCALE_API_KEY.","--idempotency-key <key> Send this exact Idempotency-Key header. The default is a generated UUID.","--json Print the key, receipt ids, and output as JSON."],notes:["Reuse an Idempotency-Key only with the same operation and input.",'If a bounded validation value appears as "[Truncated]", run "hyperscale product actions <operation-id>" for the full input schema.'],example:`hyperscale product run escrow_order.placeBuyerHold --input '{"escrowOrderId":"eord_sandbox_..."}' --idempotency-key hold-001`},"compose check":{usage:"compose check <file.hsx> [--catalog-revision <id>] [--json]",summary:"Ask the server to compile and check an HSX program.",options:["--catalog-revision <id> Compile against this immutable tenant catalog revision.","--json Print diagnostics and the verdict as JSON."],example:"hyperscale compose check product.hsx"},"compose plan":{usage:"compose plan <file.hsx> [--product <id>] [--catalog-revision <id>] [--json]",summary:"Diff an HSX program against a Product.",options:["--product <id> Product to compare. Defaults to the selected Product.","--catalog-revision <id> Compile against this immutable tenant catalog revision.","--json Print the plan as JSON."],example:"hyperscale compose plan product.hsx --json"},"compose apply":{usage:"compose apply <file.hsx> (--confirm [--pricing-identity <id> | --plan-file <path>] | --yes) [--product <id>] [--catalog-revision <id>] [--json]",summary:"Recompose the selected Product from checked HSX.",options:["--confirm Confirm the mutation for a person.","--yes Confirm the mutation without a prompt for an agent; accepts the candidate price current at apply time.","--pricing-identity <id> Candidate pricing identity from compose plan. Required with --confirm only when scheduled pricing exists.","--plan-file <path> Saved JSON plan file from compose plan --json. Used with --confirm to extract pricing identity when scheduled pricing exists.","--product <id> Product to recompose. Defaults to the selected Product.","--catalog-revision <id> Compile and persist against this immutable tenant catalog revision.","--json Print the result as JSON."],notes:["Apply --confirm requires a reviewed pricing identity or saved plan only when plan.pricing.scheduled exists; --yes selects the current candidate."],example:"hyperscale compose apply product.hsx --yes --pricing-identity <id>"},"key create":{usage:"key create [--name <name>] [--product <id>] [--json]",summary:"Create a sandbox Product API key.",options:["--name <name> Key name. Defaults to Founder CLI.","--product <id> Product for the key. Defaults to the selected Product.","--json Print the one-time secret and key metadata as JSON."],example:'hyperscale key create --name "Founder laptop"'},"key list":{usage:"key list [--product <id>] [--json]",summary:"List keys for one Product.",options:["--product <id> Product to inspect. Defaults to the selected Product.","--json Print the collection as JSON."],example:"hyperscale key list --json"},"key revoke":{usage:"key revoke <id> [--product <id>] [--json]",summary:"Revoke one Product API key.",options:["--product <id> Product that owns the key. Defaults to the selected Product.","--json Print the result as JSON."],example:"hyperscale key revoke key_sandbox_..."},"activity list":{usage:"activity list [--json]",summary:"List company activity with timestamps and resource targets.",options:["--json Print the complete collection as JSON."],example:"hyperscale activity list"},whoami:{usage:"whoami [--json]",summary:"Show the user and company the founder PAT resolves to.",options:["--json Print machine-readable JSON."],example:"hyperscale whoami --json"},"ops list":{usage:"ops list [filter] [--product <id>] [--json]",summary:"List callable operations from the Product machine document.",options:["filter Optional case-insensitive substring filter matching operation names and paths.","--product <id> Product to inspect. The Product API key must belong to it.","--api-key <key> Product API key. Defaults to HYPERSCALE_API_KEY.","--json Print matching operations as JSON."],notes:["The optional filter argument matches operation names and paths by case-insensitive substring."],example:"hyperscale ops list account"},call:{usage:"call <operation> [--input <json> | --input-file <path>] [--idempotency-key <key>] [--product <id>]",summary:"Call one operation from the Product machine document.",options:["--input <json> JSON input object. Stdin is used when piped.","--input-file <path> Read the JSON input object from a file.","--product <id> Product to call. The Product API key must belong to it.","--api-key <key> Product API key. Defaults to HYPERSCALE_API_KEY.","--idempotency-key <key> Send this exact Idempotency-Key header for a mutation. The default is a generated UUID."],notes:["Reuse an Idempotency-Key only with the same operation and input."],example:`hyperscale call account.create --input '{"currency":"SAR"}'`},help:{usage:"help [command]",summary:"Print help for hyperscale or a specific command.",options:[],notes:['Pass a command name to read its usage, options, and examples (e.g. "hyperscale help product create").'],example:"hyperscale help product create"}};function je(e){let t=Object.keys(ue).sort((i,s)=>s.split(" ").length-i.split(" ").length),n=t.find(i=>i.split(" ").every((c,u)=>e[u]===c));if(n){let i=ue[n];return[`Usage: hyperscale ${i.usage}`,"",i.summary,"","Options:",...i.options.map(s=>` ${s}`),...i.notes?["","Notes:",...i.notes.map(s=>` ${s}`)]:[],"","Example:",` ${i.example}`,""].join(`
116
- `)}let o=e.join(" "),r=t.filter(i=>i.startsWith(`${o} `));if(r.length>0)return[`Usage: hyperscale ${o} <subcommand> [options]`,"",`Available ${o} subcommands:`,...r.map(i=>` ${i.slice(o.length+1).padEnd(20)} ${ue[i].summary}`),"",`Run "hyperscale help ${o} <subcommand>" for detailed options and examples.`,""].join(`
117
- `);throw new d(`No help for ${e.join(" ")}. Run "hyperscale --help" to list commands.`,{fix:'Run "hyperscale --help" to list commands.'})}var d=class extends Error{constructor(t,n={}){super(t),typeof n.code=="string"&&(this.code=n.code),n.details!==void 0&&(this.details=n.details),Number.isInteger(n.exitCode)&&(this.exitCode=n.exitCode),typeof n.fix=="string"&&(this.fix=n.fix)}},E=class extends d{constructor(t,{requestId:n,status:o,code:r,details:i,operationId:s,receiptId:c,traceId:u,structuredError:p,fix:l}={}){super(t,{code:r,details:i,fix:l}),this.requestId=n,this.status=o,this.operationId=s??null,this.receiptId=c??null,this.traceId=u??null,this.structuredError=p}};function U(){return new d(St,{fix:xt})}function Be(e){let t=e??"<id>";return new d(`This command needs a Product API key. Create one with "hyperscale key create --name 'Founder CLI' --product ${t}", then set HYPERSCALE_API_KEY or pass --api-key.`,{fix:`Run "hyperscale key create --name 'Founder CLI' --product ${t}", then set HYPERSCALE_API_KEY or pass --api-key.`})}var X=class extends d{constructor(t,n){super(t),this.code="check_failed",this.details=n,this.exitCode=2}},Ct=new Set(["--api-key","--base-url","--blueprint","--catalog-revision","--environment","--idempotency-key","--input","--input-file","--name","--plan-file","--pricing-identity","--product","--source","--token"]);function Rt(e){let t=[],n={};for(let o=0;o<e.length;o+=1){let r=e[o];if(r==="-h")r="--help";else if(r==="-v")r="--version";else if(r.startsWith("-")&&!r.startsWith("--"))throw new d(`Unknown option: ${r}`);if(!r.startsWith("--")){t.push(r);continue}if(Ct.has(r)){let i=e[o+1];if(i===void 0)throw new d(`${r} needs a value`);n[r]=i,o+=1;continue}if(r==="--help"||r==="--version"||r==="--json"||r==="--confirm"||r==="--yes"||r==="--no-browser"||r==="--revoke"){n[r]=!0;continue}throw new d(`Unknown option: ${r}`)}return{flags:n,positional:t}}function Le(e,t){let n=e["--api-key"]??t.HYPERSCALE_API_KEY;if(!n)throw Be();let o=e["--environment"]??t.HYPERSCALE_ENVIRONMENT??ke;if(o!=="sandbox"&&o!=="live")throw new d(`Unknown environment: ${o}. Use sandbox or live.`);let r=(e["--base-url"]??t.HYPERSCALE_BASE_URL??$e).replace(/\/+$/,"");return{apiKey:n,baseUrl:r,environment:o}}function D(e,t,n={}){let o=e["--environment"]??t.HYPERSCALE_ENVIRONMENT??n.environment??ke;if(o!=="sandbox"&&o!=="live")throw new d(`Unknown environment: ${o}. Use sandbox or live.`);let r=(e["--base-url"]??t.HYPERSCALE_BASE_URL??n.baseUrl??$e).replace(/\/+$/,"");return ve(r),{baseUrl:r,environment:o}}function qe(e){return e.HYPERSCALE_CONFIG_DIR??ee(kt(),".config","hyperscale")}function Ye(e){return ee(qe(e),At)}function x(e,t){return ee(qe(t),`session-${B(e)}.json`)}function te(e){let t=e.HYPERSCALE_CREDENTIAL_STORE??"auto";if(t==="auto"||t==="file")return t;throw new d(`Unknown HYPERSCALE_CREDENTIAL_STORE value: ${t}. Use auto or file.`)}async function Se(e,t){let n=x(e,t),o=`${Pt(n)}.`,r;try{r=await wt(le(n),{withFileTypes:!0})}catch(i){if(i&&i.code==="ENOENT")return;throw i}for(let i of r){if(!i.isFile()||!i.name.startsWith(o))continue;let s=i.name.slice(o.length);/^\d+\.[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}\.tmp$/.test(s)&&await K(ee(le(n),i.name))}}async function _t(e){try{return JSON.parse(await J(e,"utf8"))}catch(t){if(t&&t.code==="ENOENT")return null;throw t instanceof SyntaxError?new d(`The CLI profile at ${e} is corrupt: not valid JSON.`,{code:"corrupt_profile",fix:`Back up or remove ${e} before logging in again with "hyperscale auth login" (or "hyperscale auth login --no-browser").`}):t}}async function H(e,t){let n=Ot(e);await yt(n,{mode:448,recursive:!0}),await ce(n,448);let o=`${e}.${process.pid}.${globalThis.crypto.randomUUID()}.tmp`;await $t(o,t,{flag:"wx",mode:384}),await ce(o,384);try{await gt(o,e),await ce(e,384)}catch(r){throw await K(o),r}}function Ot(e){return le(e)}async function K(e){try{await It(e)}catch(t){if(!t||t.code!=="ENOENT")throw t}}function Nt(e,t){if(!e||typeof e!="object"||Array.isArray(e))throw new d(`The CLI profile at ${t} is corrupt: not a profile object.`,{code:"corrupt_profile",fix:`Back up or remove ${t} before logging in again with "hyperscale auth login" (or "hyperscale auth login --no-browser").`});let{baseUrl:n,email:o,environment:r,selectedProduct:i}=e;if(typeof n!="string"||typeof o!="string"||r!=="sandbox"&&r!=="live"||!(i===null||typeof i=="string"))throw new d(`The CLI profile at ${t} is corrupt: invalid profile fields.`,{code:"corrupt_profile",fix:`Back up or remove ${t} before logging in again with "hyperscale auth login" (or "hyperscale auth login --no-browser").`});return{baseUrl:n,email:o,environment:r,selectedProduct:i}}async function ne(e){let t=Ye(e),n=await _t(t);return n===null?null:Nt(n,t)}async function oe(e,t){let n={email:t.email,baseUrl:t.baseUrl,environment:t.environment,selectedProduct:t.selectedProduct??null};await H(Ye(e),`${JSON.stringify(n,null,2)}
118
- `)}function B(e){return mt("sha256").update(`${e.baseUrl}\0${e.environment}\0${e.email}`).digest("hex")}async function re(e,t){return me===null?{error:null,status:null,stdout:"",unavailable:!0}:await new Promise(n=>{let o={...process.env};delete o.HYPERSCALE_API_KEY,delete o.HYPERSCALE_TOKEN;let r=Je(me,e,{env:o,stdio:["pipe","pipe","pipe"]}),i=[],s=!1,c=p=>{s||(s=!0,clearTimeout(u),n(p))},u=setTimeout(()=>{r.kill("SIGKILL"),c({error:null,status:null,stdout:"",unavailable:!0})},vt);r.stdout.on("data",p=>i.push(p)),r.stderr.on("data",()=>{}),r.stdin.on("error",()=>{}),r.once("error",p=>c({error:p,status:null,stdout:"",unavailable:!0})),r.once("close",p=>c({error:null,status:p,stdout:Buffer.concat(i).toString("utf8"),unavailable:!1})),t===void 0?r.stdin.end():r.stdin.end(`${t}
119
- `)})}async function xe(){return(await re(["show-keychain-info"])).status===0}function Fe(e){try{let t=typeof e=="string"?JSON.parse(e):e;if(t&&typeof t=="object"&&!Array.isArray(t)&&typeof t.token=="string"&&typeof t.tenantId=="string"&&(t.personalAccessTokenId===void 0||typeof t.personalAccessTokenId=="string")&&(t.tokenName===void 0||typeof t.tokenName=="string"))return{token:t.token,tenantId:t.tenantId,...t.personalAccessTokenId?{personalAccessTokenId:t.personalAccessTokenId}:{},...t.tokenName?{tokenName:t.tokenName}:{}}}catch{}return null}async function jt(e,t,n){await Se(e,n);let o=B(e);if(te(n)==="auto"&&await xe()){let r=JSON.stringify(t),i=["add-generic-password","-a",o,"-s",Pe,"-U","-X",Buffer.from(r,"utf8").toString("hex")].join(" ");if((await re(["-i"],i)).status===0)return await K(x(e,n)),"keychain"}return await H(x(e,n),`${JSON.stringify({account:o,activeStore:"file",credential:t})}
120
- `),"file"}async function Lt(e,t){let n=B(e);try{let o=JSON.parse(await J(x(e,t),"utf8"));if(!o||typeof o!="object"||Array.isArray(o)||o.account!==n)return{state:"invalid"};if(o.revoked===!0)return{state:"revoked"};let r=Fe(o.credential);return r?{activeStore:o.activeStore==="file"?"file":null,credential:r,state:"valid"}:{state:"invalid"}}catch(o){return o&&o.code==="ENOENT"?{state:"missing"}:{state:"invalid"}}}async function Me(e,t){await Se(e,t);let n=te(t),o=await Lt(e,t);if(o.state==="revoked")return null;if(o.state==="valid"&&(o.activeStore==="file"||n==="file"))return o.credential;if(n==="file")return null;let r=null;if(await xe()){let i=await re(["find-generic-password","-a",B(e),"-s",Pe,"-w"]);i.status===0&&(r=Fe(i.stdout.trim()))}return r||(o.state==="valid"?o.credential:null)}async function ze(e,t){await Se(e,t);let n=B(e);if(te(t)==="file")return await H(x(e,t),`${JSON.stringify({account:n,revoked:!0})}
121
- `),{keychainDeleted:!0};if(me===null)return await K(x(e,t)),{keychainDeleted:!0};if(!await xe())return await H(x(e,t),`${JSON.stringify({account:n,revoked:!0})}
122
- `),{keychainDeleted:!1};let o=await re(["delete-generic-password","-a",n,"-s",Pe]);return o.status!==0&&o.status!==44?(await H(x(e,t),`${JSON.stringify({account:n,revoked:!0})}
123
- `),{keychainDeleted:!1}):(await K(x(e,t)),{keychainDeleted:!0})}function We(e,t){return e["--token"]!==void 0?e["--token"]:t.HYPERSCALE_TOKEN||void 0}async function P(e,t,n=!1){let o=await ne(t),r=We(e,t);if(r!==void 0){if(!r)throw U();let c=D(e,t,o??{}),u=await C(c,r),p=o?.baseUrl===c.baseUrl&&o.environment===c.environment&&o.email===u.email;return{...c,email:u.email,identity:u,personalAccessTokenId:u.personalAccessTokenId,selectedProduct:p?o.selectedProduct:null,tenantId:u.tenantId,token:r,tokenName:u.name}}if(!o){if(n)return null;throw U()}let i=D(e,t,o);if(i.baseUrl!==o.baseUrl||i.environment!==o.environment)throw new d(`The active founder login belongs to ${o.baseUrl} (${o.environment}). Log in again to change it.`);let s=await Me(o,t);if(!s){if(n)return null;throw U()}return{...o,...s}}function $(e){return e.replace(new RegExp("\\p{Cc}","gu"),t=>`
124
- \r`.includes(t)?t:"")}function Ve(e){try{return new URL(e).origin}catch{return null}}function ve(e){let t;try{t=new URL(e)}catch{t=null}if(!t||t.origin!==e)throw new d(`Invalid API origin: ${e}. Use a scheme, host, and optional port with nothing after them, such as https://hyperscale0.ai.`);let n=["localhost","127.0.0.1","[::1]","::1"].includes(t.hostname);if(t.protocol!=="https:"&&!(t.protocol==="http:"&&n))throw new d(`Refusing cleartext API origin ${e}: no credential was sent. Use https://${t.host} instead, or keep http:// only for a loopback API such as http://127.0.0.1:8787.`);return t.origin}var Ut=/(?<![A-Za-z0-9_-])(?:hyperscale|arc)_[A-Za-z0-9_-]{32,}(?![A-Za-z0-9_-])/g,Ht=/(?<![A-Za-z0-9_-])whsec_[A-Za-z0-9+/=]{32,}(?![A-Za-z0-9+/=])/g;function y(e,t=[]){let n=e;for(let o of t)typeof o=="string"&&o.length>0&&(n=n.replaceAll(o,"[redacted]"));return n.replaceAll(Ut,"[redacted]").replaceAll(Ht,"[redacted]")}function Ge(e,t=[]){if(!e?.ok||!e?.headers)return;let n=e.headers.get("x-request-id"),o=e.headers.get("hyperscale-operation-id"),r=e.headers.get("hyperscale-receipt-id"),i=n?y(n,t):null,s=o?y(o,t):null,c=r?y(r,t):null;i&&process.stderr.write(`Request id: ${i}
125
- `),s&&process.stderr.write(`Operation: ${s}
126
- `),c&&process.stderr.write(`Receipt: ${c}
127
- `)}async function ie(e,t,n={},o){let r=`${e.baseUrl}${t}`,i=ve(e.baseUrl);if(Ve(r)!==i)throw new d(`The requested path ${t} leaves the ${i} origin; refusing the request.`);let s=[o].filter(Boolean);try{let c=await fetch(r,{...n,headers:{accept:"application/json",...o?{authorization:`Bearer ${o}`}:{},"x-hyperscale-environment":e.environment,...n.headers},signal:AbortSignal.timeout(fe),redirect:"manual"});if(c.status>=300&&c.status<400){let u=$(y(r,s));throw new d(`${u} redirected, so no credential was sent on. Point --base-url at the origin the API answers on.`,{code:"unexpected_redirect",fix:"Point --base-url at the origin the API answers on."})}return Ge(c,s),{response:c,text:$(await c.text())}}catch(c){if(c instanceof d)throw c;let u=$(y(r,s)),p=n.headers?.["idempotency-key"]??n.headers?.["Idempotency-Key"],l=p?$(y(p,s)):void 0,h=$(y(c?.message??"network failure",s)),m=l?`Retry the request with the same idempotency key: ${l}.`:`Check that --base-url names the Hyperscale API origin and connectivity to ${u}.`;throw new d(`Could not reach ${u}: ${h}`,{code:"transport_error",details:{...l?{idempotencyKey:l}:{},path:t,url:u},fix:m})}}async function A(e,t,n={},o,r=[]){let{response:i,text:s}=await ie(e,t,n,o);if(!i.ok)throw ae(i,s,r);try{return JSON.parse(s)}catch{throw new d(`HTTP ${i.status} returned invalid JSON`)}}function v(e,t=globalThis.crypto.randomUUID()){return{body:JSON.stringify(e),headers:{"content-type":"application/json","idempotency-key":t},method:"POST"}}async function Dt(){let e=[];for await(let t of process.stdin)e.push(Buffer.from(t));return Buffer.concat(e).toString("utf8")}async function se(e,t,n={},o){let r=`${e.baseUrl}${t}`,i=ve(e.baseUrl);if(Ve(r)!==i)throw new d(`The product document puts ${t} on another origin than the ${i} you configured; refusing to send the key there.`);let s=[e.apiKey].filter(Boolean);try{let c=await fetch(r,{...n,headers:{accept:"application/json",authorization:`Bearer ${e.apiKey}`,"x-hyperscale-environment":e.environment,...n.headers},signal:AbortSignal.timeout(fe),redirect:"manual"});if(c.status>=300&&c.status<400){let u=$(y(r,s));throw new d(`${u} redirected, so the key was not sent on. Point --base-url at the origin the API answers on; the usual cause is http:// where it serves https://.`,{code:"unexpected_redirect",fix:"Point --base-url at the origin the API answers on; the usual cause is http:// where it serves https://."})}return Ge(c,s),{response:c,text:$(await c.text())}}catch(c){if(c instanceof d)throw c;if(o&&(c?.name==="TimeoutError"||c?.name==="AbortError"))throw new d(`product run ${o} timed out after ${fe/1e3} seconds.`);let u=$(y(r,s)),p=n.headers?.["idempotency-key"]??n.headers?.["Idempotency-Key"],l=p?$(y(p,s)):void 0,h=$(y(c?.message??"network failure",s)),m=l?`Retry the request with the same idempotency key: ${l}.`:`Check that --base-url names the Hyperscale API origin and connectivity to ${u}.`;throw new d(`Could not reach ${u}: ${h}`,{code:"transport_error",details:{...l?{idempotencyKey:l}:{},path:t,url:u},fix:m})}}async function Xe(e){let{response:t,text:n}=await se(e,"/v1/product.json");if(!t.ok)throw ae(t,n,[e.apiKey]);let o=Kt(n);if(!o)throw new d("The product document is not in the expected format.",{fix:'Run the latest unpinned CLI (e.g. "bunx @hyperscale0/cli@latest <command>"), or report the issue without including credentials.'});if(e.productId&&o.productId===void 0)throw new d(`The server's product document names no Product, so "--product ${e.productId}" cannot be checked against the API key. The platform predates Product identity in the descriptor: redeploy it, or drop --product.`);if(e.productId&&o.productId&&e.productId!==o.productId)throw new d(`Selected Product ${e.productId} does not match API key Product ${o.productId}. Run "hyperscale product select ${o.productId}" or pass "--product ${o.productId}". Or set HYPERSCALE_API_KEY to a key for ${e.productId}, or pass that key with --api-key.`);let r=o.operations.map(i=>{if(typeof i.summary!="string"||typeof i.description!="string")throw new d(`The product document carries no prose for ${i.operationId}. The server descriptor predates operation prose. Redeploy the platform, then recompose the Product.`);return{description:i.description,idempotency:i.idempotency,method:i.method,name:i.name,operationId:i.operationId,path:i.path,summary:i.summary}});return{compositionId:o.composition.id,operations:r,packageName:o.sdk?o.sdk.packageName.trim():null,title:o.title.trim()}}function Kt(e){let t;try{t=JSON.parse(e)}catch{return null}let n=ye(t),o=r=>typeof r=="string";if(!L(n)||n.schemaVersion!==1||!(n.productId===void 0||o(n.productId))||!o(n.title)||!L(n.composition)||!o(n.composition.id)||!Array.isArray(n.operations))return null;for(let r of n.operations)if(!L(r)||!o(r.method)||!o(r.path)||!o(r.name)||!o(r.operationId)||!o(r.idempotency))return null;return n.sdk!==void 0&&(!L(n.sdk)||!o(n.sdk.packageName))?null:n}function L(e){return typeof e=="object"&&e!==null&&!Array.isArray(e)}function ye(e){return typeof e=="string"?$(e):Array.isArray(e)?e.map(ye):L(e)?Object.fromEntries(Object.entries(e).map(([t,n])=>[$(t),ye(n)])):e}function Ze(e){let t=e.get("x-trace-id");if(t&&t.trim()!=="")return t.trim();let n=e.get("traceparent");if(n){let o=/^00-([0-9a-fA-F]{32})-[0-9a-fA-F]{16}-[0-9a-fA-F]{2}$/.exec(n.trim());if(o)return o[1]}return null}function Jt(e){if(!e||e.trim()==="")return null;try{return JSON.parse(e)}catch{return e}}function Qe(e,t,n=[]){let o=e?.get?.("x-request-id")??t??null,r=e?.get?.("hyperscale-operation-id")??null,i=e?.get?.("hyperscale-receipt-id")??null,s=e?Ze(e):null;return{requestId:o?$(y(o,n)):null,operationId:r?$(y(r,n)):null,receiptId:i?$(y(i,n)):null,traceId:s?$(y(s,n)):null}}function Z(e,t=[]){if(typeof e=="string")return $(y(e,t));if(Array.isArray(e))return e.map(n=>Z(n,t));if(e&&typeof e=="object"){let n=[];for(let[o,r]of Object.entries(e)){let i=$(y(o,t));n.push([i,Z(r,t)])}return Object.fromEntries(n)}return e}function et(e,t=[],n){let o;try{o=JSON.parse(e)}catch{o=null}let r=o&&typeof o=="object"&&o.error&&typeof o.error=="object"?o.error:null;if(r){let c=typeof r.code=="string"?r.code:void 0,u=typeof r.fix=="string"?r.fix:void 0,p=u?$(y(u,t)):void 0,l=typeof r.message=="string"?r.message:n?`HTTP ${n}`:"HTTP error",h=$(y(l,t)),m=h.length>1024?h.slice(0,1024):h,I=c&&typeof r.message=="string"?`${c}: ${m}`:m,g=r.details!==void 0?Z(r.details,t):void 0,f=o&&typeof o=="object"&&typeof o.requestId=="string"?$(y(o.requestId,t)):void 0;return{code:c,details:g,fix:p,humanMessage:I,redactedMessage:m,requestId:f,structuredError:{code:c??"http_error",message:m,...g!==void 0?{details:g}:{},...p!==void 0?{fix:p}:{}}}}let i=n?`HTTP ${n}`:"HTTP error",s="Check that --base-url names the Hyperscale API origin, or report the issue without including credentials.";return{code:"http_error",details:void 0,fix:s,humanMessage:i,redactedMessage:i,requestId:void 0,structuredError:{code:"http_error",message:i,fix:s}}}function ae(e,t,n=[]){let o=et(t,n,e.status),r=Qe(e.headers,o.requestId,n),i=o.humanMessage;return new E(`HTTP ${e.status}${i?` \xB7 ${i}`:""}${r.requestId?`
128
- Request id: ${r.requestId}`:""}`,{code:o.code,details:o.details,fix:o.fix,operationId:r.operationId,receiptId:r.receiptId,requestId:r.requestId,status:e.status,structuredError:o.structuredError,traceId:r.traceId})}function Te(e,t){return{authenticated:!0,baseUrl:e.baseUrl,email:t.email,environment:e.environment,expiresAt:t.expiresAt,personalAccessTokenId:t.personalAccessTokenId,role:t.role,scopes:t.scopes,selectedProduct:e.selectedProduct,teamId:t.teamId,tenantId:t.tenantId,tokenName:t.name,userId:t.userId}}function Bt(e){if(!e||typeof e!="object"||typeof e.userId!="string"||typeof e.email!="string"||typeof e.tenantId!="string"||typeof e.teamId!="string"||typeof e.role!="string"||typeof e.personalAccessTokenId!="string"||typeof e.name!="string"||!Array.isArray(e.scopes)||e.scopes.some(t=>typeof t!="string")||typeof e.expiresAt!="string"||e.status!=="active")throw new d("personal_access_token.current returned invalid data");return e}async function C(e,t){try{return Bt(await A(e,bt,{},t,[t]))}catch(n){throw!(n instanceof E)||n.status!==401?n:new d(`That founder PAT was not accepted (HTTP 401). ${he}${n.requestId?` Request id: ${n.requestId}.`:""}`,{code:"founder_pat_rejected",fix:he})}}function qt(e,t){return e.HYPERSCALE_CLI_BROWSER?{command:e.HYPERSCALE_CLI_BROWSER,args:[t]}:e.HYPERSCALE_NO_BROWSER==="1"||e.CI==="1"||e.CI==="true"||process.platform==="linux"&&!e.DISPLAY&&!e.WAYLAND_DISPLAY?null:process.platform==="darwin"?{command:"/usr/bin/open",args:[t]}:process.platform==="win32"?{command:"rundll32.exe",args:["url.dll,FileProtocolHandler",t]}:{command:"xdg-open",args:[t]}}async function Yt(e,t){let n=qt(e,t);return n?new Promise(o=>{let r=Je(n.command,n.args,{detached:!0,stdio:"ignore"});r.once("error",()=>o(!1)),r.once("spawn",()=>{r.unref(),o(!0)})}):!1}function de(e){return new Promise(t=>{if(!e.listening){t();return}e.close(()=>t())})}async function Ft(e,t){let n=globalThis.crypto.randomUUID(),o=!1,r,i=new Promise((g,f)=>{r={reject:f,resolve:g}}),s=ht((g,f)=>{let w=new URL(g.url??"/","http://127.0.0.1");if(g.method!=="GET"||w.pathname!=="/callback"){f.writeHead(404,{"content-type":"text/plain; charset=utf-8"}),f.end(`Not found.
129
- `);return}if(o){f.writeHead(409,{"content-type":"text/plain; charset=utf-8"}),f.end(`Login callback was already received.
130
- `);return}if(w.searchParams.get("state")!==n){f.writeHead(400,{"content-type":"text/plain; charset=utf-8"}),f.end(`Login state did not match. Return to the terminal.
131
- `);return}if(w.searchParams.get("error")!==null){o=!0,f.writeHead(200,{"content-type":"text/plain; charset=utf-8"}),f.end(`Login declined. Return to the terminal.
132
- `),r.reject(new d("Portal login was declined. Run hyperscale auth login to start again.",{code:"auth_callback_denied"}));return}let b=w.searchParams.get("grant"),T=w.searchParams.get("tenantId");if(!b||!T){f.writeHead(400,{"content-type":"text/plain; charset=utf-8"}),f.end(`Login callback is missing its grant or tenant.
133
- `);return}o=!0,f.writeHead(200,{"content-type":"text/plain; charset=utf-8"}),f.end(`Login received. Return to the terminal.
134
- `),r.resolve({grant:b,tenantId:T})});await new Promise((g,f)=>{let w=b=>f(b);s.once("error",w),s.listen(0,"127.0.0.1",()=>{s.off("error",w),g()})}),s.once("error",g=>r.reject(g));let c=s.address();if(!c||typeof c=="string")throw await de(s),new d("Could not bind the localhost login callback");let u=`http://127.0.0.1:${c.port}/callback`,p=new URL("/auth/cli",e.baseUrl);p.searchParams.set("callback",u),p.searchParams.set("state",n);let l=new URL("/signin",e.baseUrl);l.searchParams.set("returnTo",`${p.pathname}${p.search}`);let h=l.toString();if(!await Yt(t,h))return await de(s),null;process.stderr.write(`Opening portal sign-in: ${h}
135
- `);let I=setTimeout(()=>{r.reject(new d("Portal login timed out. Run hyperscale auth login to start a new callback.",{code:"auth_callback_timeout"}))},Tt);try{return await i}finally{clearTimeout(I),await de(s)}}async function Ue(e,t,n,o,r){let i=await ne(r),s={email:t.email,...e,selectedProduct:i&&i.email===t.email&&i.baseUrl===e.baseUrl&&i.environment===e.environment?i.selectedProduct:null},c=await jt(s,{personalAccessTokenId:t.personalAccessTokenId,token:n,tokenName:t.name,tenantId:t.tenantId},r);try{await oe(r,s)}catch(p){throw await ze(s,r),p}if(c==="file"){let p=te(r)==="file"?"Founder PAT file storage is active.":"macOS Keychain is unavailable.";process.stderr.write(`${p} The founder PAT is in ${x(s,r)} with mode 0600.
136
- `)}let u=Te(s,t);o["--json"]?k(u):a(`Logged in as ${t.email} with PAT ${t.name}.`)}async function Mt(e,t){let n=D(e,t),o=We(e,t);if(o){if(!o.startsWith("hyperscale_pat_"))throw new d("Founder PATs start with hyperscale_pat_. Product API keys belong in HYPERSCALE_API_KEY.");let u=await C(n,o);await Ue(n,u,o,e,t);return}if(e["--no-browser"])throw U();let r=await Ft(n,t);if(!r)throw U();let i=await A(n,"/v1/personal-access-token-login-grants/exchange",v({tenantId:r.tenantId,grant:r.grant}),void 0,[r.grant]),s=i?.secret;if(typeof s!="string"||!s.startsWith("hyperscale_pat_")||i?.tenantId!==r.tenantId)throw new d("CLI login grant exchange returned an invalid PAT");let c=await C(n,s);await Ue(n,c,s,e,t)}async function zt(e,t){let n=await P(e,t),o=n.identity??await C(n,n.token),r=Te(n,o);if(e["--json"]){k(r);return}a(`User: ${o.email}`),a(`Tenant: ${o.tenantId}`),a(`Role: ${o.role}`),a(`Token: ${o.name}`),a(`Scopes: ${o.scopes.join(", ")}`),a(`Expires: ${o.expiresAt}`),a(`API: ${n.baseUrl}`),a(`Environment: ${n.environment}`),a(`Product: ${n.selectedProduct??"not selected"}`)}async function Wt(e,t){let n=await ne(t);if(!n){e["--json"]?k({status:"signed_out"}):a("Already logged out.");return}let o=await Me(n,t);if(e["--revoke"]&&!o)throw new d("The local founder PAT is missing, so the CLI cannot revoke it.");let r=o?.personalAccessTokenId,i=o?.tokenName;if(e["--revoke"]&&o){if(!r||!i){let u=await C(n,o.token);r=u.personalAccessTokenId,i=u.name}await A(n,`/v1/personal-access-tokens/${encodeURIComponent(r)}/revoke`,v({tenantId:o.tenantId,personalAccessTokenId:r}),o.token,[o.token])}let s=await ze(n,t),c=e["--revoke"]===!0;Vt(e,{cleanup:s,personalAccessTokenId:r,revoked:c,status:"signed_out",tokenName:i})}function Vt(e,t){let n=t.cleanup.keychainDeleted?"complete":"tombstoned";if(e["--json"])k({credentialCleanup:n,...t.personalAccessTokenId?{personalAccessTokenId:t.personalAccessTokenId}:{},...t.revoked===void 0?{}:{revoked:t.revoked},status:t.status,...t.tokenName?{tokenName:t.tokenName}:{},...t.revoked===!1?{tokenStillValid:!0}:{}});else{let o=t.tokenName&&t.personalAccessTokenId?`${t.tokenName} (${t.personalAccessTokenId})`:"with unavailable local metadata";t.revoked?a(`Revoked founder PAT ${o} and forgot local state.`):(a(`Forgot local founder PAT ${o}.`),a("The PAT stays valid until expiry; revoke at /desk/security/tokens."))}t.cleanup.keychainDeleted||process.stderr.write(`Keychain cleanup failed. A 0600 profile tombstone blocks the stale founder PAT.
137
- `)}function R(e,t){if(!e||typeof e!="object"||!Array.isArray(e.items))throw new d(`${t} returned an invalid collection`);return e.items}async function O(e,t,n,o,r,i=[]){let s=[],c=new Set,u,p;for(;;){let I=new URLSearchParams(n);u&&I.set("cursor",u);let g=I.size>0?`?${I}`:"",f=await A(e,`${t}${g}`,{},r,i);p===void 0&&(p=f),s.push(...R(f,o));let w=f.nextCursor;if(typeof w!="string"||w.length===0)break;if(c.has(w))throw new d(`${o} repeated cursor ${w}`);c.add(w),u=w}let{items:l,nextCursor:h,...m}=p;return{...m,items:s}}async function Gt(e,t){let n=await O(e,"/v1/blueprints",{},"blueprint.list"),o=R(n,"blueprint.list");if(t["--json"]){k(n);return}a("ID Name Summary");for(let r of o)a(`${r.id} ${r.name}${r.summary?` ${r.summary}`:""}`);a("Next:"),a(" hyperscale blueprint show <id>"),a(" hyperscale product create --blueprint <id> --name <name>")}async function Xt(e,t,n){if(!n)throw new d("blueprint show needs a Blueprint id",{fix:'Run "hyperscale blueprint list" to list Blueprints, then pass one ID.'});let o=await A(e,`/v1/blueprints/${encodeURIComponent(n)}`),r={...Qt(o,e.baseUrl),nextCommands:[`hyperscale product create --blueprint ${n} --name <name>`]};if(t["--json"]){k(r);return}a(`${r.name} (${r.id})`),a(r.summary),a(r.description),a("Nouns:");for(let i of r.customInstruments??[])a(` ${i.name} (${i.id}): ${i.summary}`);for(let i of r.instruments??[])a(` ${i.title} (${i.id}): ${i.summary}`);a("Verbs:");for(let i of r.verbs??[])a(` ${i.alias} -> ${i.operation}: ${i.summary}`);a("Parties:");for(let i of r.parties??[])a(` ${i.instrumentId}.${i.role} -> ${i.accountField}`);a("Money flows:");for(let i of r.moneyFlows??[]){let s=i.sourceAccount??"action input",c=i.destinationAccount??"action input",u=i.amountPath??"action input";a(` ${i.action} [${i.kind}]: ${s} -> ${c}; amount ${u}`)}a("Fee forms:");for(let i of r.feeForms??[]){let s=i.bps?`${i.bps} bps`:i.amount?`SAR ${i.amount}`:i.includedQuantity?`${i.includedQuantity} included`:i.kind;a(` ${i.id}: ${s} per ${i.unit}. ${i.summary}`)}if(r.priceEstimate){let i=r.priceEstimate.currency??"SAR";a("Price estimate:"),r.priceEstimate.monthly!==void 0&&a(` monthly: ${i} ${Number(r.priceEstimate.monthly).toLocaleString("en-US")}`),r.priceEstimate.setup!==void 0&&a(` setup: ${i} ${Number(r.priceEstimate.setup).toLocaleString("en-US")}`),r.priceEstimate.complexityScore!==void 0&&a(` complexityScore: ${r.priceEstimate.complexityScore}`)}a("Dials:");for(let i of r.dials??[])a(` ${i.instrumentId}.${i.key} (${i.kind}): ${i.summary}`);a("Journeys:");for(let i of r.journeys??[])a(` ${i.title} (${i.id}): ${i.summary}`),(i.steps??[]).forEach((s,c)=>{a(` ${c+1}. ${Zt(s)}`)});r.hsxStructured&&(a("HSX:"),a(` Source:
138
- ${He(r.hsxStructured.source," ")}`),r.hsxStructured.document&&a(` Structured document:
139
- ${He(JSON.stringify(r.hsxStructured.document,null,2)," ")}`)),a("Terms:");for(let[i,s]of Object.entries(r.terminology))a(` ${i}: ${s.definition}`),a(` ${s.href}`);a("Next:"),a(` hyperscale product create --blueprint ${r.id} --name <name>`)}function Zt(e){if(typeof e=="string")return e;let t=e.id?`${e.id} -> ${e.operation}`:e.operation,n=Object.entries(e.bind??{}).map(([r,i])=>`${r} <- ${i}`),o=[e.example?`example ${e.example}`:"",n.length>0?`binds ${n.join(", ")}`:""].filter(Boolean);return o.length>0?`${t}: ${o.join("; ")}`:t}function Qt(e,t){let n=en(e?.hsx);return{...e,...n?{hsxStructured:n}:{},terminology:{firedBy:{definition:"Who invokes an action: tenant through the Product surface, operator through a console session, or machine when a due condition arrives.",href:`${t}/glossary#action-caller`},publicIntents:{definition:"The retired name for publicActions. publicActions contains the canonical action IDs frozen into a composed Product.",href:`${t}/glossary#public-actions`},trustFile:{definition:"The evidence attached to a business record for later review, such as inspection, authentication, delivery, or proof-of-work records.",href:`${t}/glossary#trust-file`}}}}function en(e){if(typeof e!="string"||e.length===0)return;try{let n=JSON.parse(e);if(n&&typeof n=="object"&&!Array.isArray(n))return{document:n,language:"hsx-json",source:e,verdict:"valid"}}catch{}let t=compile(e);return{diagnostics:t.diagnostics,...t.artifacts?{document:t.artifacts.document,frame:t.artifacts.frame}:{},language:"hsx-text",source:e,verdict:t.verdict}}function He(e,t){return e.split(`
2
+ import{spawn as Ve}from"node:child_process";import{createHash as Rt}from"node:crypto";import{createServer as Ct}from"node:http";import{createInterface as Ge}from"node:readline/promises";import{chmod as me,mkdir as vt,readdir as jt,readFile as Y,rename as Ot,unlink as _t,writeFile as Nt}from"node:fs/promises";import{homedir as Lt}from"node:os";import{basename as Ut,dirname as ge,join as oe}from"node:path";var Et=new RegExp("[\x1B](?:\\[[0-?]*[ -/]*[@-~]|\\][^\x07\x1B]*(?:\x07|\x1B\\\\)|[PX^_][^\x1B]*\x1B\\\\|.)|[^\\P{Cc}\\t\\n\\r]","gu");function Ne(e){return String(e??"").replace(Et,"")}function P(e,t,n){let o=!!e?.isTTY&&t?.NO_COLOR===void 0&&!n?.json,r=(i,a)=>c=>{let l=Ne(c);return o?`${i}${l}${a}`:l},s=r("\x1B[2m","\x1B[22m");return{accent:r("\x1B[34m","\x1B[39m"),strong:r("\x1B[1m","\x1B[22m"),dim:s,rule:i=>{let a=Number.isFinite(i)?Math.min(80,Math.max(0,Math.floor(i))):80;return s("-".repeat(a))},text:Ne}}var Tt="HYPERSCALE",Le={wordmark:Tt},Ue="Finance, authored by you.";function He(e){return[e.strong(Le.wordmark),"",Ue,"",e.accent("Run hyperscale auth login to sign in.")].join(`
3
+ `)}function De(e,t){let n=e.text(t.identity),o=[e.strong("Logged in"),"",` Identity: ${n}`];if(t.team){let r=e.text(t.team);o.push(` Team: ${r}`)}return o.join(`
4
+ `)}function le(e){return[`${e.strong("Usage:")} hyperscale <command> [options]`,"","The founder command line.","",e.strong("Concepts:")," Blueprint -> Product A Blueprint is a public catalog template."," Composing one, or raw HSX, creates a Product."," Founder PAT vs API key A founder PAT manages the company: Blueprints,"," Products, composition, keys. A Product API key"," runs one Product's operations. Not interchangeable."," Actions vs operations product actions / product run execute a Product's"," frozen public contract. ops list / call invoke"," catalog operations from the machine document."," Public discovery blueprint list and blueprint show need no login.","",e.strong("Commands:")," start Create a Product and run its first published step"," help [command] Print help for hyperscale or a specific command"," auth login Sign in through the portal or save a founder PAT"," auth status Verify and show the active founder PAT"," auth logout [--revoke] Forget the local founder PAT, optionally revoke it"," blueprint list List public Blueprints without authentication"," blueprint show <id> Show one public Blueprint"," product create Create a Product from a Blueprint or HSX source"," product list List Products in the signed-in company"," product show [id] Show a Product (default: selected Product)"," product select <id> Select the default Product for later commands"," product actions [op-id] List frozen public actions or describe one exactly"," product run <op-id> Run one frozen public action"," compose check <file.hsx> Compile and check an HSX program"," compose plan <file.hsx> Diff an HSX program against the selected Product"," compose apply <file.hsx> Recompose the selected Product from checked HSX"," key create Create a sandbox Product API key"," key list List keys for the selected Product"," key revoke <id> Revoke a Product API key"," activity list List company activity"," whoami Show the user and company this founder PAT maps to"," ops list [filter] List callable operations (substring filter)"," call <operation> Call one operation by name or operation id","",e.strong("Options:")," --token <pat> Founder PAT (default: $HYPERSCALE_TOKEN)"," --api-key <key> Product API key (default: $HYPERSCALE_API_KEY)"," --base-url <url> API origin (default: $HYPERSCALE_BASE_URL)"," --environment <name> sandbox or live (default: $HYPERSCALE_ENVIRONMENT)"," --no-browser Skip browser login. Needs a PAT or it fails"," --revoke Revoke the founder PAT during auth logout"," --blueprint <slug> Blueprint for start or product create"," --source <file> HSX source for initial Product creation"," --name <name> Product or key name"," --product <id> Product id for key commands and actions"," --catalog-revision <id> Tenant catalog revision for HSX composition"," --json Print machine-readable JSON"," --help, -h Print this help"," --version, -v Print the CLI version"].join(`
5
+ `)}function pe(e,t){if(!t)return[`${e.strong("Usage:")} hyperscale auth login [--no-browser] [--token <pat>]`,"","Sign in through the portal callback or save a founder PAT.","",e.strong("Options:")," --no-browser Skip browser login. Saves the PAT or fails without one."," --token <pat> Founder PAT. Defaults to HYPERSCALE_TOKEN."," --json Print the saved session summary as one JSON document.","",e.strong("Notes:")," Without a PAT, the CLI opens portal sign-in and accepts one callback."," With --no-browser and no token, the command fails with a login error."," Pass HYPERSCALE_TOKEN or --token to save a PAT.","",e.strong("Example:")," hyperscale auth login --no-browser"].join(`
6
+ `);if("subcommands"in t)return[`${e.strong("Usage:")} hyperscale ${t.prefix} <subcommand> [options]`,"",`Available ${t.prefix} subcommands:`,...t.subcommands.map(([o,r])=>` ${o.padEnd(20)} ${r}`),"",`Run "hyperscale help ${t.prefix} <subcommand>" for detailed options and examples.`].join(`
7
+ `);let n=[`${e.strong("Usage:")} hyperscale ${t.usage}`,"",t.summary,"",e.strong("Options:"),...(t.options??[]).map(o=>` ${o}`)];return t.notes&&t.notes.length>0&&n.push("",e.strong("Notes:"),...t.notes.map(o=>` ${o}`)),t.example&&n.push("",e.strong("Example:"),` ${t.example}`),n.join(`
8
+ `)}function C(e,t){let n=[];if(t.title&&n.push(e.strong(e.text(t.title)),""),t.columns.length===0)return n.join(`
9
+ `);let o=t.columns.map(a=>e.text(a)),r=t.rows.map(a=>a.map(c=>e.text(c))),s=o.map((a,c)=>Math.max(a.length,...r.map(l=>(l[c]??"").length)));if(s.reduce((a,c)=>a+c,0)+2*(o.length-1)<=80){let a=o.map((c,l)=>l===o.length-1?c:c.padEnd(s[l])).join(" ");n.push(e.strong(a));for(let c of r){let l=o.map((p,f)=>{let m=c[f]??"";return f===o.length-1?m:m.padEnd(s[f])}).join(" ");n.push(l)}}else{let a=Math.max(...o.map(c=>c.length));for(let c=0;c<r.length;c++){let l=r[c];c>0&&n.push("");for(let p=0;p<o.length;p++){let f=o[p],m=l[p]??"";n.push(` ${f.padEnd(a)}: ${m}`)}}}return n.join(`
10
+ `)}function N(e,t){let n=[];if(t.title&&n.push(e.strong(e.text(t.title)),""),t.fields.length===0)return n.join(`
11
+ `);let o=t.fields.map(([s,i])=>[e.text(s),e.text(i)]),r=Math.max(...o.map(([s])=>s.length));for(let[s,i]of o){let a=` ${(s+":").padEnd(r+3)}`;if(i.includes(`
12
+ `)){let c=i.split(`
13
+ `);n.push(`${a}${c[0]}`);let l=" ".repeat(a.length);for(let p=1;p<c.length;p++)n.push(`${l}${c[p]}`)}else n.push(`${a}${i}`)}return n.join(`
14
+ `)}function Ke(e,t){let n=e.text(t.action),o=e.text(t.subject),r=typeof t.confirmation=="string"&&t.confirmation.trim()?e.text(t.confirmation):"Continue?";return[e.strong("Confirm mutation"),"",` Action: ${n}`,` Subject: ${o}`,"",` ${r} [y/N]`].join(`
15
+ `)}function Je(e,t){let n=e.text(String(t.code)),o=e.text(t.message),r=e.accent(t.nextStep);return[e.strong(`Error [${n}]`),o,"",`Next step: ${r}`].join(`
16
+ `)}var Xe="https://hyperscale0.ai",Ze="sandbox",xe="hyperscale-cli-session",Ht="/v1/personal-access-tokens/current",we=process.platform==="darwin"?"/usr/bin/security":null,Dt="config.json",Se="https://hyperscale0.ai/desk/security/tokens",Qe="https://hyperscale0.ai/request-access",Be=`Mint a founder PAT in Hyperscale Portal at ${Se}. Open Security, then Personal access tokens.`,Kt=`Not logged in. Run "hyperscale auth login" to open Hyperscale Portal sign-in. In a headless environment, mint a founder PAT in Hyperscale Portal at ${Se}. Open Security, then Personal access tokens. Then set HYPERSCALE_TOKEN or pass --token. Unapproved founders can request access at ${Qe}.`,Jt=`Run "hyperscale auth login". For headless use, mint a founder PAT in Hyperscale Portal at ${Se}. Open Security, then Personal access tokens. Unapproved founders can request access at ${Qe}.`,Ie=3e4,Bt=2e3,Mt=120*1e3,Yt=/^prd_(sandbox|live)_[a-z0-9]{8,64}$/,fe={start:{usage:"start [--blueprint <slug>] [--name <name>] [--json]",summary:"Choose a catalog company, create its Product, and run its first published runnable step.",options:["--blueprint <slug> Skip the prompt and choose this catalog Blueprint.","--name <name> Product name. Defaults to the selected Blueprint name.","--json Print one machine document, including the one-time API key under shown_once."],notes:["The command requires an active founder login.","Without --blueprint, start requires an interactive terminal and asks which company to build.","Scripts and agents must pass --blueprint <slug>.","Machine output returns the Product API key only under shown_once.","A Blueprint without a published runnable step stops after composition and names the next command."],example:"hyperscale start --blueprint vehicle-escrow-marketplace --json"},"auth login":{usage:"auth login [--no-browser] [--token <pat>]",summary:"Sign in through the portal callback or save a founder PAT.",options:["--no-browser Skip browser login. Saves the PAT or fails without one.","--token <pat> Founder PAT. Defaults to HYPERSCALE_TOKEN.","--json Print the saved session summary as one JSON document."],notes:["Without a PAT, the CLI opens portal sign-in and accepts one","localhost callback.","With --no-browser and no token, the command fails with a login","error and fix text. Pass HYPERSCALE_TOKEN or --token to save a PAT.","Set HYPERSCALE_CREDENTIAL_STORE=file to use the 0600 profile file","instead of macOS Keychain."],example:"hyperscale auth login --no-browser"},"auth status":{usage:"auth status [--json]",summary:"Verify and show the active founder PAT and selected Product.",options:["--json Print machine-readable JSON."],example:"hyperscale auth status --json"},"auth logout":{usage:"auth logout [--revoke] [--json]",summary:"Forget the local founder PAT. Optionally revoke it first.",options:["--revoke Revoke the PAT before deleting local state.","--json Print machine-readable JSON."],example:"hyperscale auth logout --revoke"},"blueprint list":{usage:"blueprint list [--json]",summary:"List public Blueprints without authentication.",options:["--json Print the complete collection as JSON."],example:"hyperscale blueprint list"},"blueprint show":{usage:"blueprint show <id> [--json]",summary:"Show one public Blueprint.",options:["--json Print the complete Blueprint as JSON."],example:"hyperscale blueprint show luxury-goods-consignment-escrow"},"product create":{usage:"product create (--blueprint <id> | --source <file>) --name <name> [--catalog-revision <id>] [--json]",summary:"Create and select a Product. The command refuses a duplicate name.",options:["--blueprint <id> Blueprint id to compose from.","--source <file> HSX source file for initial Product creation.","--name <name> Required Product name.","--catalog-revision <id> Tenant catalog revision for HSX composition.","--json Print the creation summary as JSON."],example:'hyperscale product create --blueprint luxury-goods-consignment-escrow --name "Luxury Consignment"'},"product list":{usage:"product list [--json]",summary:"List Products in the signed-in company.",options:["--json Print the complete collection as JSON."],example:"hyperscale product list"},"product show":{usage:"product show [id] [--json]",summary:"Show a Product summary, or the complete Product document as JSON.",options:["--json Print the complete Product document."],example:"hyperscale product show prd_sandbox_..."},"product select":{usage:"product select <id> [--json]",summary:"Verify a Product and save it as the default for later commands.",options:["--token <pat> Founder PAT. Defaults to HYPERSCALE_TOKEN or the stored login.","--base-url <url> API origin. Defaults to the active founder profile.","--environment <name> sandbox or live. Defaults to the active founder profile.","--json Print the selected Product id as JSON."],notes:["The CLI stores the selection in the active founder profile.","Product show, compose plan/apply, and key commands use it when --product is absent.","Product create and start select the Product they create."],example:"hyperscale product select prd_sandbox_..."},"product actions":{usage:"product actions [operation-id] [--product <id>] [--json]",summary:"List frozen public actions or show one action's full schemas.",options:["--product <id> Product to inspect. Defaults to the selected Product.","--api-key <key> Product API key. Defaults to HYPERSCALE_API_KEY.","--json Print machine-readable JSON."],notes:["Setup operation details include the public input schema used by hyperscale call.","When that schema has no required fields, omit --input or pass {}."],example:"hyperscale product actions escrow_order.placeBuyerHold --json"},"product run":{usage:"product run <operation-id> [--input <json> | --input-file <path>] [--idempotency-key <key>] [--json]",summary:"Run one frozen public action with a Product API key.",options:["--input <json> JSON input object. Stdin is used when piped.","--input-file <path> Read the JSON input object from a file.","--product <id> Product to call. Defaults to the selected Product.","--api-key <key> Product API key. Defaults to HYPERSCALE_API_KEY.","--idempotency-key <key> Send this exact Idempotency-Key header. The default is a generated UUID.","--json Print the key, receipt ids, and output as JSON."],notes:["Reuse an Idempotency-Key only with the same operation and input.",'If a bounded validation value appears as "[Truncated]", run "hyperscale product actions <operation-id>" for the full input schema.'],example:`hyperscale product run escrow_order.placeBuyerHold --input '{"escrowOrderId":"eord_sandbox_..."}' --idempotency-key hold-001`},"compose check":{usage:"compose check <file.hsx> [--catalog-revision <id>] [--json]",summary:"Ask the server to compile and check an HSX program.",options:["--catalog-revision <id> Compile against this immutable tenant catalog revision.","--json Print diagnostics and the verdict as JSON."],example:"hyperscale compose check product.hsx"},"compose plan":{usage:"compose plan <file.hsx> [--product <id>] [--catalog-revision <id>] [--json]",summary:"Diff an HSX program against a Product.",options:["--product <id> Product to compare. Defaults to the selected Product.","--catalog-revision <id> Compile against this immutable tenant catalog revision.","--json Print the plan as JSON."],example:"hyperscale compose plan product.hsx --json"},"compose apply":{usage:"compose apply <file.hsx> (--confirm [--pricing-identity <id> | --plan-file <path>] | --yes) [--product <id>] [--catalog-revision <id>] [--json]",summary:"Recompose the selected Product from checked HSX.",options:["--confirm Confirm the mutation for a person.","--yes Confirm the mutation without a prompt for an agent; accepts the candidate price current at apply time.","--pricing-identity <id> Candidate pricing identity from compose plan. Required with --confirm only when scheduled pricing exists.","--plan-file <path> Saved JSON plan file from compose plan --json. Used with --confirm to extract pricing identity when scheduled pricing exists.","--product <id> Product to recompose. Defaults to the selected Product.","--catalog-revision <id> Compile and persist against this immutable tenant catalog revision.","--json Print the result as JSON."],notes:["Apply --confirm requires a reviewed pricing identity or saved plan only when plan.pricing.scheduled exists; --yes selects the current candidate."],example:"hyperscale compose apply product.hsx --yes --pricing-identity <id>"},"key create":{usage:"key create [--name <name>] [--product <id>] [--json]",summary:"Create a sandbox Product API key.",options:["--name <name> Key name. Defaults to Founder CLI.","--product <id> Product for the key. Defaults to the selected Product.","--json Print the one-time secret and key metadata as JSON."],example:'hyperscale key create --name "Founder laptop"'},"key list":{usage:"key list [--product <id>] [--json]",summary:"List keys for one Product.",options:["--product <id> Product to inspect. Defaults to the selected Product.","--json Print the collection as JSON."],example:"hyperscale key list --json"},"key revoke":{usage:"key revoke <id> [--product <id>] [--json]",summary:"Revoke one Product API key.",options:["--product <id> Product that owns the key. Defaults to the selected Product.","--json Print the result as JSON."],example:"hyperscale key revoke key_sandbox_..."},"activity list":{usage:"activity list [--json]",summary:"List company activity with timestamps and resource targets.",options:["--json Print the complete collection as JSON."],example:"hyperscale activity list"},whoami:{usage:"whoami [--json]",summary:"Show the user and company the founder PAT resolves to.",options:["--json Print machine-readable JSON."],example:"hyperscale whoami --json"},"ops list":{usage:"ops list [filter] [--product <id>] [--json]",summary:"List callable operations from the Product machine document.",options:["filter Optional case-insensitive substring filter matching operation names and paths.","--product <id> Product to inspect. The Product API key must belong to it.","--api-key <key> Product API key. Defaults to HYPERSCALE_API_KEY.","--json Print matching operations as JSON."],notes:["The optional filter argument matches operation names and paths by case-insensitive substring."],example:"hyperscale ops list account"},call:{usage:"call <operation> [--input <json> | --input-file <path>] [--idempotency-key <key>] [--product <id>]",summary:"Call one operation from the Product machine document.",options:["--input <json> JSON input object. Stdin is used when piped.","--input-file <path> Read the JSON input object from a file.","--product <id> Product to call. The Product API key must belong to it.","--api-key <key> Product API key. Defaults to HYPERSCALE_API_KEY.","--idempotency-key <key> Send this exact Idempotency-Key header for a mutation. The default is a generated UUID."],notes:["Reuse an Idempotency-Key only with the same operation and input."],example:`hyperscale call account.create --input '{"currency":"SAR"}'`},help:{usage:"help [command]",summary:"Print help for hyperscale or a specific command.",options:[],notes:['Pass a command name to read its usage, options, and examples (e.g. "hyperscale help product create").'],example:"hyperscale help product create"}};function Me(e,t){let n=t??P(process.stdout,process.env,{json:!1}),o=Object.keys(fe).sort((a,c)=>c.split(" ").length-a.split(" ").length),r=o.find(a=>a.split(" ").every((l,p)=>e[p]===l));if(r){let a=fe[r];return pe(n,{usage:a.usage,summary:a.summary,options:a.options,notes:a.notes,example:a.example})}let s=e.join(" "),i=o.filter(a=>a.startsWith(`${s} `));if(i.length>0)return pe(n,{prefix:s,subcommands:i.map(a=>[a.slice(s.length+1),fe[a].summary])});throw new d(`No help for ${e.join(" ")}. Run "hyperscale --help" to list commands.`,{fix:'Run "hyperscale --help" to list commands.'})}var d=class extends Error{constructor(t,n={}){super(t),typeof n.code=="string"&&(this.code=n.code),n.details!==void 0&&(this.details=n.details),Number.isInteger(n.exitCode)&&(this.exitCode=n.exitCode),typeof n.fix=="string"&&(this.fix=n.fix)}},v=class extends d{constructor(t,{requestId:n,status:o,code:r,details:s,operationId:i,receiptId:a,traceId:c,structuredError:l,fix:p}={}){super(t,{code:r,details:s,fix:p}),this.requestId=n,this.status=o,this.operationId=i??null,this.receiptId=a??null,this.traceId=c??null,this.structuredError=l}};function K(){return new d(Kt,{fix:Jt})}function et(e){let t=e??"<id>";return new d(`This command needs a Product API key. Create one with "hyperscale key create --name 'Founder CLI' --product ${t}", then set HYPERSCALE_API_KEY or pass --api-key.`,{fix:`Run "hyperscale key create --name 'Founder CLI' --product ${t}", then set HYPERSCALE_API_KEY or pass --api-key.`})}var ee=class extends d{constructor(t,n){super(t),this.code="check_failed",this.details=n,this.exitCode=2}},qt=new Set(["--api-key","--base-url","--blueprint","--catalog-revision","--environment","--idempotency-key","--input","--input-file","--name","--plan-file","--pricing-identity","--product","--source","--token"]);function Ft(e){let t=[],n={};for(let o=0;o<e.length;o+=1){let r=e[o];if(r==="-h")r="--help";else if(r==="-v")r="--version";else if(r.startsWith("-")&&!r.startsWith("--"))throw new d(`Unknown option: ${r}`);if(!r.startsWith("--")){t.push(r);continue}if(qt.has(r)){let s=e[o+1];if(s===void 0)throw new d(`${r} needs a value`);n[r]=s,o+=1;continue}if(r==="--help"||r==="--version"||r==="--json"||r==="--confirm"||r==="--yes"||r==="--no-browser"||r==="--revoke"){n[r]=!0;continue}throw new d(`Unknown option: ${r}`)}return{flags:n,positional:t}}function Ye(e,t){let n=e["--api-key"]??t.HYPERSCALE_API_KEY;if(!n)throw et();let o=e["--environment"]??t.HYPERSCALE_ENVIRONMENT??Ze;if(o!=="sandbox"&&o!=="live")throw new d(`Unknown environment: ${o}. Use sandbox or live.`);let r=(e["--base-url"]??t.HYPERSCALE_BASE_URL??Xe).replace(/\/+$/,"");return{apiKey:n,baseUrl:r,environment:o}}function B(e,t,n={}){let o=e["--environment"]??t.HYPERSCALE_ENVIRONMENT??n.environment??Ze;if(o!=="sandbox"&&o!=="live")throw new d(`Unknown environment: ${o}. Use sandbox or live.`);let r=(e["--base-url"]??t.HYPERSCALE_BASE_URL??n.baseUrl??Xe).replace(/\/+$/,"");return Te(r),{baseUrl:r,environment:o}}function tt(e){return e.HYPERSCALE_CONFIG_DIR??oe(Lt(),".config","hyperscale")}function nt(e){return oe(tt(e),Dt)}function E(e,t){return oe(tt(t),`session-${q(e)}.json`)}function re(e){let t=e.HYPERSCALE_CREDENTIAL_STORE??"auto";if(t==="auto"||t==="file")return t;throw new d(`Unknown HYPERSCALE_CREDENTIAL_STORE value: ${t}. Use auto or file.`)}async function Ae(e,t){let n=E(e,t),o=`${Ut(n)}.`,r;try{r=await jt(ge(n),{withFileTypes:!0})}catch(s){if(s&&s.code==="ENOENT")return;throw s}for(let s of r){if(!s.isFile()||!s.name.startsWith(o))continue;let i=s.name.slice(o.length);/^\d+\.[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}\.tmp$/.test(i)&&await M(oe(ge(n),s.name))}}async function Wt(e){try{return JSON.parse(await Y(e,"utf8"))}catch(t){if(t&&t.code==="ENOENT")return null;throw t instanceof SyntaxError?new d(`The CLI profile at ${e} is corrupt: not valid JSON.`,{code:"corrupt_profile",fix:`Back up or remove ${e} before logging in again with "hyperscale auth login" (or "hyperscale auth login --no-browser").`}):t}}async function J(e,t){let n=zt(e);await vt(n,{mode:448,recursive:!0}),await me(n,448);let o=`${e}.${process.pid}.${globalThis.crypto.randomUUID()}.tmp`;await Nt(o,t,{flag:"wx",mode:384}),await me(o,384);try{await Ot(o,e),await me(e,384)}catch(r){throw await M(o),r}}function zt(e){return ge(e)}async function M(e){try{await _t(e)}catch(t){if(!t||t.code!=="ENOENT")throw t}}function Vt(e,t){if(!e||typeof e!="object"||Array.isArray(e))throw new d(`The CLI profile at ${t} is corrupt: not a profile object.`,{code:"corrupt_profile",fix:`Back up or remove ${t} before logging in again with "hyperscale auth login" (or "hyperscale auth login --no-browser").`});let{baseUrl:n,email:o,environment:r,selectedProduct:s}=e;if(typeof n!="string"||typeof o!="string"||r!=="sandbox"&&r!=="live"||!(s===null||typeof s=="string"))throw new d(`The CLI profile at ${t} is corrupt: invalid profile fields.`,{code:"corrupt_profile",fix:`Back up or remove ${t} before logging in again with "hyperscale auth login" (or "hyperscale auth login --no-browser").`});return{baseUrl:n,email:o,environment:r,selectedProduct:s}}async function se(e){let t=nt(e),n=await Wt(t);return n===null?null:Vt(n,t)}async function ie(e,t){let n={email:t.email,baseUrl:t.baseUrl,environment:t.environment,selectedProduct:t.selectedProduct??null};await J(nt(e),`${JSON.stringify(n,null,2)}
17
+ `)}function q(e){return Rt("sha256").update(`${e.baseUrl}\0${e.environment}\0${e.email}`).digest("hex")}async function ae(e,t){return we===null?{error:null,status:null,stdout:"",unavailable:!0}:await new Promise(n=>{let o={...process.env};delete o.HYPERSCALE_API_KEY,delete o.HYPERSCALE_TOKEN;let r=Ve(we,e,{env:o,stdio:["pipe","pipe","pipe"]}),s=[],i=!1,a=l=>{i||(i=!0,clearTimeout(c),n(l))},c=setTimeout(()=>{r.kill("SIGKILL"),a({error:null,status:null,stdout:"",unavailable:!0})},Bt);r.stdout.on("data",l=>s.push(l)),r.stderr.on("data",()=>{}),r.stdin.on("error",()=>{}),r.once("error",l=>a({error:l,status:null,stdout:"",unavailable:!0})),r.once("close",l=>a({error:null,status:l,stdout:Buffer.concat(s).toString("utf8"),unavailable:!1})),t===void 0?r.stdin.end():r.stdin.end(`${t}
18
+ `)})}async function Ee(){return(await ae(["show-keychain-info"])).status===0}function ot(e){try{let t=typeof e=="string"?JSON.parse(e):e;if(t&&typeof t=="object"&&!Array.isArray(t)&&typeof t.token=="string"&&typeof t.tenantId=="string"&&(t.personalAccessTokenId===void 0||typeof t.personalAccessTokenId=="string")&&(t.tokenName===void 0||typeof t.tokenName=="string"))return{token:t.token,tenantId:t.tenantId,...t.personalAccessTokenId?{personalAccessTokenId:t.personalAccessTokenId}:{},...t.tokenName?{tokenName:t.tokenName}:{}}}catch{}return null}async function Gt(e,t,n){await Ae(e,n);let o=q(e);if(re(n)==="auto"&&await Ee()){let r=JSON.stringify(t),s=["add-generic-password","-a",o,"-s",xe,"-U","-X",Buffer.from(r,"utf8").toString("hex")].join(" ");if((await ae(["-i"],s)).status===0)return await M(E(e,n)),"keychain"}return await J(E(e,n),`${JSON.stringify({account:o,activeStore:"file",credential:t})}
19
+ `),"file"}async function Xt(e,t){let n=q(e);try{let o=JSON.parse(await Y(E(e,t),"utf8"));if(!o||typeof o!="object"||Array.isArray(o)||o.account!==n)return{state:"invalid"};if(o.revoked===!0)return{state:"revoked"};let r=ot(o.credential);return r?{activeStore:o.activeStore==="file"?"file":null,credential:r,state:"valid"}:{state:"invalid"}}catch(o){return o&&o.code==="ENOENT"?{state:"missing"}:{state:"invalid"}}}async function rt(e,t){await Ae(e,t);let n=re(t),o=await Xt(e,t);if(o.state==="revoked")return null;if(o.state==="valid"&&(o.activeStore==="file"||n==="file"))return o.credential;if(n==="file")return null;let r=null;if(await Ee()){let s=await ae(["find-generic-password","-a",q(e),"-s",xe,"-w"]);s.status===0&&(r=ot(s.stdout.trim()))}return r||(o.state==="valid"?o.credential:null)}async function st(e,t){await Ae(e,t);let n=q(e);if(re(t)==="file")return await J(E(e,t),`${JSON.stringify({account:n,revoked:!0})}
20
+ `),{keychainDeleted:!0};if(we===null)return await M(E(e,t)),{keychainDeleted:!0};if(!await Ee())return await J(E(e,t),`${JSON.stringify({account:n,revoked:!0})}
21
+ `),{keychainDeleted:!1};let o=await ae(["delete-generic-password","-a",n,"-s",xe]);return o.status!==0&&o.status!==44?(await J(E(e,t),`${JSON.stringify({account:n,revoked:!0})}
22
+ `),{keychainDeleted:!1}):(await M(E(e,t)),{keychainDeleted:!0})}function it(e,t){return e["--token"]!==void 0?e["--token"]:t.HYPERSCALE_TOKEN||void 0}async function $(e,t,n=!1){let o=await se(t),r=it(e,t);if(r!==void 0){if(!r)throw K();let a=B(e,t,o??{}),c=await j(a,r),l=o?.baseUrl===a.baseUrl&&o.environment===a.environment&&o.email===c.email;return{...a,email:c.email,identity:c,personalAccessTokenId:c.personalAccessTokenId,selectedProduct:l?o.selectedProduct:null,tenantId:c.tenantId,token:r,tokenName:c.name}}if(!o){if(n)return null;throw K()}let s=B(e,t,o);if(s.baseUrl!==o.baseUrl||s.environment!==o.environment)throw new d(`The active founder login belongs to ${o.baseUrl} (${o.environment}). Log in again to change it.`);let i=await rt(o,t);if(!i){if(n)return null;throw K()}return{...o,...i}}function b(e){return e.replace(new RegExp("\\p{Cc}","gu"),t=>`
23
+ \r`.includes(t)?t:"")}function at(e){try{return new URL(e).origin}catch{return null}}function Te(e){let t;try{t=new URL(e)}catch{t=null}if(!t||t.origin!==e)throw new d(`Invalid API origin: ${e}. Use a scheme, host, and optional port with nothing after them, such as https://hyperscale0.ai.`);let n=["localhost","127.0.0.1","[::1]","::1"].includes(t.hostname);if(t.protocol!=="https:"&&!(t.protocol==="http:"&&n))throw new d(`Refusing cleartext API origin ${e}: no credential was sent. Use https://${t.host} instead, or keep http:// only for a loopback API such as http://127.0.0.1:8787.`);return t.origin}var Zt=/(?<![A-Za-z0-9_-])(?:hyperscale|arc)_[A-Za-z0-9_-]{32,}(?![A-Za-z0-9_-])/g,Qt=/(?<![A-Za-z0-9_-])whsec_[A-Za-z0-9+/=]{32,}(?![A-Za-z0-9+/=])/g;function y(e,t=[]){let n=e;for(let o of t)typeof o=="string"&&o.length>0&&(n=n.replaceAll(o,"[redacted]"));return n.replaceAll(Zt,"[redacted]").replaceAll(Qt,"[redacted]")}function ct(e,t=[]){if(!e?.ok||!e?.headers)return;let n=e.headers.get("x-request-id"),o=e.headers.get("hyperscale-operation-id"),r=e.headers.get("hyperscale-receipt-id"),s=n?y(n,t):null,i=o?y(o,t):null,a=r?y(r,t):null;s&&process.stderr.write(`Request id: ${s}
24
+ `),i&&process.stderr.write(`Operation: ${i}
25
+ `),a&&process.stderr.write(`Receipt: ${a}
26
+ `)}async function ce(e,t,n={},o){let r=`${e.baseUrl}${t}`,s=Te(e.baseUrl);if(at(r)!==s)throw new d(`The requested path ${t} leaves the ${s} origin; refusing the request.`);let i=[o].filter(Boolean);try{let a=await fetch(r,{...n,headers:{accept:"application/json",...o?{authorization:`Bearer ${o}`}:{},"x-hyperscale-environment":e.environment,...n.headers},signal:AbortSignal.timeout(Ie),redirect:"manual"});if(a.status>=300&&a.status<400){let c=b(y(r,i));throw new d(`${c} redirected, so no credential was sent on. Point --base-url at the origin the API answers on.`,{code:"unexpected_redirect",fix:"Point --base-url at the origin the API answers on."})}return ct(a,i),{response:a,text:b(await a.text())}}catch(a){if(a instanceof d)throw a;let c=b(y(r,i)),l=n.headers?.["idempotency-key"]??n.headers?.["Idempotency-Key"],p=l?b(y(l,i)):void 0,f=b(y(a?.message??"network failure",i)),m=p?`Retry the request with the same idempotency key: ${p}.`:`Check that --base-url names the Hyperscale API origin and connectivity to ${c}.`;throw new d(`Could not reach ${c}: ${f}`,{code:"transport_error",details:{...p?{idempotencyKey:p}:{},path:t,url:c},fix:m})}}async function S(e,t,n={},o,r=[]){let{response:s,text:i}=await ce(e,t,n,o);if(!s.ok)throw de(s,i,r);try{return JSON.parse(i)}catch{throw new d(`HTTP ${s.status} returned invalid JSON`)}}function T(e,t=globalThis.crypto.randomUUID()){return{body:JSON.stringify(e),headers:{"content-type":"application/json","idempotency-key":t},method:"POST"}}async function en(){let e=[];for await(let t of process.stdin)e.push(Buffer.from(t));return Buffer.concat(e).toString("utf8")}async function ue(e,t,n={},o){let r=`${e.baseUrl}${t}`,s=Te(e.baseUrl);if(at(r)!==s)throw new d(`The product document puts ${t} on another origin than the ${s} you configured; refusing to send the key there.`);let i=[e.apiKey].filter(Boolean);try{let a=await fetch(r,{...n,headers:{accept:"application/json",authorization:`Bearer ${e.apiKey}`,"x-hyperscale-environment":e.environment,...n.headers},signal:AbortSignal.timeout(Ie),redirect:"manual"});if(a.status>=300&&a.status<400){let c=b(y(r,i));throw new d(`${c} redirected, so the key was not sent on. Point --base-url at the origin the API answers on; the usual cause is http:// where it serves https://.`,{code:"unexpected_redirect",fix:"Point --base-url at the origin the API answers on; the usual cause is http:// where it serves https://."})}return ct(a,i),{response:a,text:b(await a.text())}}catch(a){if(a instanceof d)throw a;if(o&&(a?.name==="TimeoutError"||a?.name==="AbortError"))throw new d(`product run ${o} timed out after ${Ie/1e3} seconds.`);let c=b(y(r,i)),l=n.headers?.["idempotency-key"]??n.headers?.["Idempotency-Key"],p=l?b(y(l,i)):void 0,f=b(y(a?.message??"network failure",i)),m=p?`Retry the request with the same idempotency key: ${p}.`:`Check that --base-url names the Hyperscale API origin and connectivity to ${c}.`;throw new d(`Could not reach ${c}: ${f}`,{code:"transport_error",details:{...p?{idempotencyKey:p}:{},path:t,url:c},fix:m})}}async function ut(e){let{response:t,text:n}=await ue(e,"/v1/product.json");if(!t.ok)throw de(t,n,[e.apiKey]);let o=tn(n);if(!o)throw new d("The product document is not in the expected format.",{fix:'Run the latest unpinned CLI (e.g. "bunx @hyperscale0/cli@latest <command>"), or report the issue without including credentials.'});if(e.productId&&o.productId===void 0)throw new d(`The server's product document names no Product, so "--product ${e.productId}" cannot be checked against the API key. The platform predates Product identity in the descriptor: redeploy it, or drop --product.`);if(e.productId&&o.productId&&e.productId!==o.productId)throw new d(`Selected Product ${e.productId} does not match API key Product ${o.productId}. Run "hyperscale product select ${o.productId}" or pass "--product ${o.productId}". Or set HYPERSCALE_API_KEY to a key for ${e.productId}, or pass that key with --api-key.`);let r=o.operations.map(s=>{if(typeof s.summary!="string"||typeof s.description!="string")throw new d(`The product document carries no prose for ${s.operationId}. The server descriptor predates operation prose. Redeploy the platform, then recompose the Product.`);return{description:s.description,idempotency:s.idempotency,method:s.method,name:s.name,operationId:s.operationId,path:s.path,summary:s.summary}});return{compositionId:o.composition.id,operations:r,packageName:o.sdk?o.sdk.packageName.trim():null,title:o.title.trim()}}function tn(e){let t;try{t=JSON.parse(e)}catch{return null}let n=be(t),o=r=>typeof r=="string";if(!D(n)||n.schemaVersion!==1||!(n.productId===void 0||o(n.productId))||!o(n.title)||!D(n.composition)||!o(n.composition.id)||!Array.isArray(n.operations))return null;for(let r of n.operations)if(!D(r)||!o(r.method)||!o(r.path)||!o(r.name)||!o(r.operationId)||!o(r.idempotency))return null;return n.sdk!==void 0&&(!D(n.sdk)||!o(n.sdk.packageName))?null:n}function D(e){return typeof e=="object"&&e!==null&&!Array.isArray(e)}function be(e){return typeof e=="string"?b(e):Array.isArray(e)?e.map(be):D(e)?Object.fromEntries(Object.entries(e).map(([t,n])=>[b(t),be(n)])):e}function dt(e){let t=e.get("x-trace-id");if(t&&t.trim()!=="")return t.trim();let n=e.get("traceparent");if(n){let o=/^00-([0-9a-fA-F]{32})-[0-9a-fA-F]{16}-[0-9a-fA-F]{2}$/.exec(n.trim());if(o)return o[1]}return null}function nn(e){if(!e||e.trim()==="")return null;try{return JSON.parse(e)}catch{return e}}function lt(e,t,n=[]){let o=e?.get?.("x-request-id")??t??null,r=e?.get?.("hyperscale-operation-id")??null,s=e?.get?.("hyperscale-receipt-id")??null,i=e?dt(e):null;return{requestId:o?b(y(o,n)):null,operationId:r?b(y(r,n)):null,receiptId:s?b(y(s,n)):null,traceId:i?b(y(i,n)):null}}function te(e,t=[]){if(typeof e=="string")return b(y(e,t));if(Array.isArray(e))return e.map(n=>te(n,t));if(e&&typeof e=="object"){let n=[];for(let[o,r]of Object.entries(e)){let s=b(y(o,t));n.push([s,te(r,t)])}return Object.fromEntries(n)}return e}function pt(e,t=[],n){let o;try{o=JSON.parse(e)}catch{o=null}let r=o&&typeof o=="object"&&o.error&&typeof o.error=="object"?o.error:null;if(r){let a=typeof r.code=="string"?r.code:void 0,c=typeof r.fix=="string"?r.fix:void 0,l=c?b(y(c,t)):void 0,p=typeof r.message=="string"?r.message:n?`HTTP ${n}`:"HTTP error",f=b(y(p,t)),m=f.length>1024?f.slice(0,1024):f,g=a&&typeof r.message=="string"?`${a}: ${m}`:m,I=r.details!==void 0?te(r.details,t):void 0,h=o&&typeof o=="object"&&typeof o.requestId=="string"?b(y(o.requestId,t)):void 0;return{code:a,details:I,fix:l,humanMessage:g,redactedMessage:m,requestId:h,structuredError:{code:a??"http_error",message:m,...I!==void 0?{details:I}:{},...l!==void 0?{fix:l}:{}}}}let s=n?`HTTP ${n}`:"HTTP error",i="Check that --base-url names the Hyperscale API origin, or report the issue without including credentials.";return{code:"http_error",details:void 0,fix:i,humanMessage:s,redactedMessage:s,requestId:void 0,structuredError:{code:"http_error",message:s,fix:i}}}function de(e,t,n=[]){let o=pt(t,n,e.status),r=lt(e.headers,o.requestId,n),s=o.humanMessage;return new v(`HTTP ${e.status}${s?` \xB7 ${s}`:""}${r.requestId?`
27
+ Request id: ${r.requestId}`:""}`,{code:o.code,details:o.details,fix:o.fix,operationId:r.operationId,receiptId:r.receiptId,requestId:r.requestId,status:e.status,structuredError:o.structuredError,traceId:r.traceId})}function Re(e,t){return{authenticated:!0,baseUrl:e.baseUrl,email:t.email,environment:e.environment,expiresAt:t.expiresAt,personalAccessTokenId:t.personalAccessTokenId,role:t.role,scopes:t.scopes,selectedProduct:e.selectedProduct,teamId:t.teamId,tenantId:t.tenantId,tokenName:t.name,userId:t.userId}}function on(e){if(!e||typeof e!="object"||typeof e.userId!="string"||typeof e.email!="string"||typeof e.tenantId!="string"||typeof e.teamId!="string"||typeof e.role!="string"||typeof e.personalAccessTokenId!="string"||typeof e.name!="string"||!Array.isArray(e.scopes)||e.scopes.some(t=>typeof t!="string")||typeof e.expiresAt!="string"||e.status!=="active")throw new d("personal_access_token.current returned invalid data");return e}async function j(e,t){try{return on(await S(e,Ht,{},t,[t]))}catch(n){throw!(n instanceof v)||n.status!==401?n:new d(`That founder PAT was not accepted (HTTP 401). ${Be}${n.requestId?` Request id: ${n.requestId}.`:""}`,{code:"founder_pat_rejected",fix:Be})}}function rn(e,t){return e.HYPERSCALE_CLI_BROWSER?{command:e.HYPERSCALE_CLI_BROWSER,args:[t]}:e.HYPERSCALE_NO_BROWSER==="1"||e.CI==="1"||e.CI==="true"||process.platform==="linux"&&!e.DISPLAY&&!e.WAYLAND_DISPLAY?null:process.platform==="darwin"?{command:"/usr/bin/open",args:[t]}:process.platform==="win32"?{command:"rundll32.exe",args:["url.dll,FileProtocolHandler",t]}:{command:"xdg-open",args:[t]}}async function sn(e,t){let n=rn(e,t);return n?new Promise(o=>{let r=Ve(n.command,n.args,{detached:!0,stdio:"ignore"});r.once("error",()=>o(!1)),r.once("spawn",()=>{r.unref(),o(!0)})}):!1}function he(e){return new Promise(t=>{if(!e.listening){t();return}e.close(()=>t())})}async function an(e,t){let n=globalThis.crypto.randomUUID(),o=!1,r,s=new Promise((I,h)=>{r={reject:h,resolve:I}}),i=Ct((I,h)=>{let w=new URL(I.url??"/","http://127.0.0.1");if(I.method!=="GET"||w.pathname!=="/callback"){h.writeHead(404,{"content-type":"text/plain; charset=utf-8"}),h.end(`Not found.
28
+ `);return}if(o){h.writeHead(409,{"content-type":"text/plain; charset=utf-8"}),h.end(`Login callback was already received.
29
+ `);return}if(w.searchParams.get("state")!==n){h.writeHead(400,{"content-type":"text/plain; charset=utf-8"}),h.end(`Login state did not match. Return to the terminal.
30
+ `);return}if(w.searchParams.get("error")!==null){o=!0,h.writeHead(200,{"content-type":"text/plain; charset=utf-8"}),h.end(`Login declined. Return to the terminal.
31
+ `),r.reject(new d("Portal login was declined. Run hyperscale auth login to start again.",{code:"auth_callback_denied"}));return}let x=w.searchParams.get("grant"),R=w.searchParams.get("tenantId");if(!x||!R){h.writeHead(400,{"content-type":"text/plain; charset=utf-8"}),h.end(`Login callback is missing its grant or tenant.
32
+ `);return}o=!0,h.writeHead(200,{"content-type":"text/plain; charset=utf-8"}),h.end(`Login received. Return to the terminal.
33
+ `),r.resolve({grant:x,tenantId:R})});await new Promise((I,h)=>{let w=x=>h(x);i.once("error",w),i.listen(0,"127.0.0.1",()=>{i.off("error",w),I()})}),i.once("error",I=>r.reject(I));let a=i.address();if(!a||typeof a=="string")throw await he(i),new d("Could not bind the localhost login callback");let c=`http://127.0.0.1:${a.port}/callback`,l=new URL("/auth/cli",e.baseUrl);l.searchParams.set("callback",c),l.searchParams.set("state",n);let p=new URL("/signin",e.baseUrl);p.searchParams.set("returnTo",`${l.pathname}${l.search}`);let f=p.toString();if(!await sn(t,f))return await he(i),null;process.stderr.write(`Opening portal sign-in: ${f}
34
+ `);let g=setTimeout(()=>{r.reject(new d("Portal login timed out. Run hyperscale auth login to start a new callback.",{code:"auth_callback_timeout"}))},Mt);try{return await s}finally{clearTimeout(g),await he(i)}}async function qe(e,t,n,o,r){let s=await se(r),i={email:t.email,...e,selectedProduct:s&&s.email===t.email&&s.baseUrl===e.baseUrl&&s.environment===e.environment?s.selectedProduct:null},a=await Gt(i,{personalAccessTokenId:t.personalAccessTokenId,token:n,tokenName:t.name,tenantId:t.tenantId},r);try{await ie(r,i)}catch(l){throw await st(i,r),l}if(a==="file"){let l=re(r)==="file"?"Founder PAT file storage is active.":"macOS Keychain is unavailable.";process.stderr.write(`${l} The founder PAT is in ${E(i,r)} with mode 0600.
35
+ `)}let c=Re(i,t);if(o["--json"])k(c);else{let l=P(process.stdout,r,{json:!1});u(De(l,{identity:t.email,team:t.teamId}))}}async function cn(e,t){let n=B(e,t),o=it(e,t);if(o){if(!o.startsWith("hyperscale_pat_"))throw new d("Founder PATs start with hyperscale_pat_. Product API keys belong in HYPERSCALE_API_KEY.");let c=await j(n,o);await qe(n,c,o,e,t);return}if(e["--no-browser"])throw K();let r=await an(n,t);if(!r)throw K();let s=await S(n,"/v1/personal-access-token-login-grants/exchange",T({tenantId:r.tenantId,grant:r.grant}),void 0,[r.grant]),i=s?.secret;if(typeof i!="string"||!i.startsWith("hyperscale_pat_")||s?.tenantId!==r.tenantId)throw new d("CLI login grant exchange returned an invalid PAT");let a=await j(n,i);await qe(n,a,i,e,t)}async function un(e,t){let n=await $(e,t),o=n.identity??await j(n,n.token),r=Re(n,o);if(e["--json"]){k(r);return}let s=P(process.stdout,t,{json:!1});u(N(s,{fields:[["User",o.email],["Tenant",o.tenantId],["Role",o.role],["Token",o.name],["Scopes",o.scopes.join(", ")],["Expires",o.expiresAt],["API",n.baseUrl],["Environment",n.environment],["Product",n.selectedProduct??"not selected"]]}))}async function dn(e,t){let n=await se(t);if(!n){e["--json"]?k({status:"signed_out"}):u("Already logged out.");return}let o=await rt(n,t);if(e["--revoke"]&&!o)throw new d("The local founder PAT is missing, so the CLI cannot revoke it.");let r=o?.personalAccessTokenId,s=o?.tokenName;if(e["--revoke"]&&o){if(!r||!s){let c=await j(n,o.token);r=c.personalAccessTokenId,s=c.name}await S(n,`/v1/personal-access-tokens/${encodeURIComponent(r)}/revoke`,T({tenantId:o.tenantId,personalAccessTokenId:r}),o.token,[o.token])}let i=await st(n,t),a=e["--revoke"]===!0;ln(e,{cleanup:i,personalAccessTokenId:r,revoked:a,status:"signed_out",tokenName:s})}function ln(e,t){let n=t.cleanup.keychainDeleted?"complete":"tombstoned";if(e["--json"])k({credentialCleanup:n,...t.personalAccessTokenId?{personalAccessTokenId:t.personalAccessTokenId}:{},...t.revoked===void 0?{}:{revoked:t.revoked},status:t.status,...t.tokenName?{tokenName:t.tokenName}:{},...t.revoked===!1?{tokenStillValid:!0}:{}});else{let o=t.tokenName&&t.personalAccessTokenId?`${t.tokenName} (${t.personalAccessTokenId})`:"with unavailable local metadata";t.revoked?u(`Revoked founder PAT ${o} and forgot local state.`):(u(`Forgot local founder PAT ${o}.`),u("The PAT stays valid until expiry; revoke at /desk/security/tokens."))}t.cleanup.keychainDeleted||process.stderr.write(`Keychain cleanup failed. A 0600 profile tombstone blocks the stale founder PAT.
36
+ `)}function O(e,t){if(!e||typeof e!="object"||!Array.isArray(e.items))throw new d(`${t} returned an invalid collection`);return e.items}async function L(e,t,n,o,r,s=[]){let i=[],a=new Set,c,l;for(;;){let g=new URLSearchParams(n);c&&g.set("cursor",c);let I=g.size>0?`?${g}`:"",h=await S(e,`${t}${I}`,{},r,s);l===void 0&&(l=h),i.push(...O(h,o));let w=h.nextCursor;if(typeof w!="string"||w.length===0)break;if(a.has(w))throw new d(`${o} repeated cursor ${w}`);a.add(w),c=w}let{items:p,nextCursor:f,...m}=l;return{...m,items:i}}async function pn(e,t){let n=await L(e,"/v1/blueprints",{},"blueprint.list"),o=O(n,"blueprint.list");if(t["--json"]){k(n);return}let r=P(process.stdout,process.env,{json:!1});u(C(r,{columns:["ID","Name","Summary"],rows:o.map(s=>[s.id,s.name,s.summary??""])})),u(""),u("Next:"),u(" hyperscale blueprint show <id>"),u(" hyperscale product create --blueprint <id> --name <name>")}async function mn(e,t,n){if(!n)throw new d("blueprint show needs a Blueprint id",{fix:'Run "hyperscale blueprint list" to list Blueprints, then pass one ID.'});let o=await S(e,`/v1/blueprints/${encodeURIComponent(n)}`),r={...hn(o,e.baseUrl),nextCommands:[`hyperscale product create --blueprint ${n} --name <name>`]};if(t["--json"]){k(r);return}u(`${r.name} (${r.id})`),u(r.summary),u(r.description),u("Nouns:");for(let s of r.customInstruments??[])u(` ${s.name} (${s.id}): ${s.summary}`);for(let s of r.instruments??[])u(` ${s.title} (${s.id}): ${s.summary}`);u("Verbs:");for(let s of r.verbs??[])u(` ${s.alias} -> ${s.operation}: ${s.summary}`);u("Parties:");for(let s of r.parties??[])u(` ${s.instrumentId}.${s.role} -> ${s.accountField}`);u("Money flows:");for(let s of r.moneyFlows??[]){let i=s.sourceAccount??"action input",a=s.destinationAccount??"action input",c=s.amountPath??"action input";u(` ${s.action} [${s.kind}]: ${i} -> ${a}; amount ${c}`)}u("Fee forms:");for(let s of r.feeForms??[]){let i=s.bps?`${s.bps} bps`:s.amount?`SAR ${s.amount}`:s.includedQuantity?`${s.includedQuantity} included`:s.kind;u(` ${s.id}: ${i} per ${s.unit}. ${s.summary}`)}if(r.priceEstimate){let s=r.priceEstimate.currency??"SAR";u("Price estimate:"),r.priceEstimate.monthly!==void 0&&u(` monthly: ${s} ${Number(r.priceEstimate.monthly).toLocaleString("en-US")}`),r.priceEstimate.setup!==void 0&&u(` setup: ${s} ${Number(r.priceEstimate.setup).toLocaleString("en-US")}`),r.priceEstimate.complexityScore!==void 0&&u(` complexityScore: ${r.priceEstimate.complexityScore}`)}u("Dials:");for(let s of r.dials??[])u(` ${s.instrumentId}.${s.key} (${s.kind}): ${s.summary}`);u("Journeys:");for(let s of r.journeys??[])u(` ${s.title} (${s.id}): ${s.summary}`),(s.steps??[]).forEach((i,a)=>{u(` ${a+1}. ${fn(i)}`)});r.hsxStructured&&(u("HSX:"),u(` Source:
37
+ ${Fe(r.hsxStructured.source," ")}`),r.hsxStructured.document&&u(` Structured document:
38
+ ${Fe(JSON.stringify(r.hsxStructured.document,null,2)," ")}`)),u("Terms:");for(let[s,i]of Object.entries(r.terminology))u(` ${s}: ${i.definition}`),u(` ${i.href}`);u("Next:"),u(` hyperscale product create --blueprint ${r.id} --name <name>`)}function fn(e){if(typeof e=="string")return e;let t=e.id?`${e.id} -> ${e.operation}`:e.operation,n=Object.entries(e.bind??{}).map(([r,s])=>`${r} <- ${s}`),o=[e.example?`example ${e.example}`:"",n.length>0?`binds ${n.join(", ")}`:""].filter(Boolean);return o.length>0?`${t}: ${o.join("; ")}`:t}function hn(e,t){let n=yn(e?.hsx);return{...e,...n?{hsxStructured:n}:{},terminology:{firedBy:{definition:"Who invokes an action: tenant through the Product surface, operator through a console session, or machine when a due condition arrives.",href:`${t}/glossary#action-caller`},publicIntents:{definition:"The retired name for publicActions. publicActions contains the canonical action IDs frozen into a composed Product.",href:`${t}/glossary#public-actions`},trustFile:{definition:"The evidence attached to a business record for later review, such as inspection, authentication, delivery, or proof-of-work records.",href:`${t}/glossary#trust-file`}}}}function yn(e){if(typeof e!="string"||e.length===0)return;try{let n=JSON.parse(e);if(n&&typeof n=="object"&&!Array.isArray(n))return{document:n,language:"hsx-json",source:e,verdict:"valid"}}catch{}let t=compile(e);return{diagnostics:t.diagnostics,...t.artifacts?{document:t.artifacts.document,frame:t.artifacts.frame}:{},language:"hsx-text",source:e,verdict:t.verdict}}function Fe(e,t){return e.split(`
140
39
  `).map(n=>`${t}${n}`).join(`
141
- `)}function Ee(e,t=[]){let n=e.headers.get("hyperscale-operation-id"),o=e.headers.get("hyperscale-receipt-id"),r=n?y(n,t):void 0,i=o?y(o,t):void 0;return{...r?{operationId:r}:{},...i?{receiptId:i}:{}}}function Ce(e,t,n=[]){if(!e.ok)throw ae(e,t,n);try{return JSON.parse(t)}catch{throw new d(`HTTP ${e.status} returned invalid JSON`)}}function tn(e,t){t.operationId&&a(`${e} operation: ${t.operationId}`),t.receiptId&&a(`${e} receipt: ${t.receiptId}`)}function nn(e,t,n){let o=e?.message??String(e),r=[...n?[`hyperscale product show ${n}`]:[],"hyperscale product list"],i="Warning: The returned Product API key was the only copy. Save it or mint a replacement with key create.",s=[`hyperscale start failed after Product ${n??""} was created: ${o}.`,i,"Inspect the created Product with:",...r.map(u=>` ${u}`)].join(`
142
- `),c=new d(s,{code:"start_failed_after_compose",details:{cause:o,...n?{productId:n}:{},recovery:r,warning:i},fix:n?`Inspect the created Product with "hyperscale product show ${n}".`:'Inspect created Products with "hyperscale product list".'});return c.shownOnce=t,c}function on(e){if(!e["--blueprint"]&&!(process.stdin.isTTY&&process.stderr.isTTY))throw new d("hyperscale start needs an interactive terminal to choose a company. Pass --blueprint <slug> in scripts and non-interactive environments.",{code:"start_blueprint_required",fix:'Run "hyperscale blueprint list", then pass --blueprint <slug>.'})}function rn(e){return R(e,"blueprint.list").map(t=>{if(typeof t?.id!="string"||t.id.length===0||typeof t?.name!="string"||t.name.length===0)throw new d("blueprint.list returned an invalid start choice");return{id:t.id,name:t.name,summary:typeof t.summary=="string"?t.summary:""}})}async function sn(e,t){let n=await O(t,"/v1/blueprints",{},"blueprint.list"),o=rn(n);if(o.length===0)throw new d("The Blueprint catalog has no companies to build.");let r=e["--blueprint"];if(r){let h=o.find(({id:m})=>m===r);if(h)return h;throw new d(`Unknown Blueprint: ${r}`,{fix:'Run "hyperscale blueprint list" and pass one listed slug to --blueprint.'})}process.stderr.write(`Which company do you want to build?
143
- `);for(let[h,m]of o.entries()){let I=m.summary.replace(/\s+/g," ").trim();process.stderr.write(` ${h+1}. ${m.name} (${m.id})${I?`: ${I}`:""}
144
- `)}let i=ft({input:process.stdin,output:process.stderr,terminal:!0}),s=new AbortController,c=()=>s.abort();process.stdin.once("end",c),process.stdin.readableEnded&&s.abort();let u;try{try{u=(await i.question("Choose a number or Blueprint slug: ",{signal:s.signal})).trim()}catch(h){throw h?.name!=="AbortError"&&h?.code!=="ABORT_ERR"?h:new d("Start cancelled before a Blueprint was chosen.",{code:"start_cancelled"})}}finally{process.stdin.off("end",c),i.close()}let p=Number(u),l=Number.isInteger(p)?o[p-1]:o.find(({id:h})=>h===u);if(l)return l;throw new d(`No Blueprint matches ${JSON.stringify(u)}.`,{fix:"Run hyperscale start again and choose a listed number or slug."})}async function De(e,t){on(e);let n={};try{await an(e,t,n)}catch(o){throw typeof n.apiKey!="string"?o:nn(o,n.apiKey,n.productId)}}async function an(e,t,n){let o=await P(e,t),r=await C(o,o.token),i=await sn(e,o),s=e["--name"]??i.name;e["--json"]||a(`Authenticated: ${r.email}`);let c=await ie(o,"/v1/products/blueprint-compose",v({blueprintId:i.id,name:s,tenantId:o.tenantId}),o.token),u=Ce(c.response,c.text,[o.token]);if(typeof u?.productId!="string"||!Et.test(u.productId)||typeof u?.productBuildId!="string"||u?.blueprintId!==i.id)throw new d("product.blueprint.compose returned an invalid start Product");let p=u?.shown_once;if(typeof p!="string"||p.length===0)throw new d("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=p,n.productId=u.productId;let l=Ee(c.response);await oe(t,{...o,selectedProduct:u.productId}),e["--json"]||(a(`Product: ${u.productId}`),a(`Blueprint: ${u.blueprintId}`),tn("Compose",l));let h=[`hyperscale compose plan product.hsx --product ${u.productId}`],m="Composition completed. Run SDK journeys against your Product.",I={blueprintId:u.blueprintId,composeOnly:!0,nextCommands:h,notice:m,productBuildId:u.productBuildId,productId:u.productId,receipts:[{stage:"product.blueprint.compose",...l}],...typeof u.startKeyId=="string"?{startKeyId:u.startKeyId}:{},shown_once:p};if(e["--json"]){k(I);return}a(m),a(`Shown once Product API key: ${p}`),a("Next:");for(let g of h)a(` ${g}`);a(" Run journeys with the Hyperscale SDK using the Product API key above.")}async function cn(e,t){let n=e["--blueprint"],o=e["--source"],r=e["--name"];if(n&&o)throw new d("product create accepts either --blueprint <id> or --source <file>, not both");if(!n&&!o)throw new d("product create needs either --blueprint <id> or --source <file>");if(!r)throw new d("product create needs --name <name>");let i=o?await ot(o,"product create"):void 0,s=await P(e,t),c;try{c=await O(s,"/v1/products",{tenantId:s.tenantId},"product.list",s.token,[s.token])}catch(w){if(!(w instanceof E)||w.status!==403)throw w}let u=r.trim().toLocaleLowerCase("en-US"),p=(c?R(c,"product.list"):[]).find(w=>{let b=w?.displayName??w?.name;return typeof b=="string"&&b.trim().toLocaleLowerCase("en-US")===u});if(p){let w=p.productId??p.id??"<id>";throw new d(`A Product named ${JSON.stringify(r.trim())} already exists as ${w}.`,{code:"duplicate_product_name",fix:`Use "hyperscale product select ${w}" or choose another --name.`})}let l=o?"/v1/products/instruments-compose":"/v1/products/blueprint-compose",h=o?{name:r,program:{source:i.source},tenantId:s.tenantId,...e["--catalog-revision"]?{catalogRevisionId:e["--catalog-revision"]}:{}}:{blueprintId:n,name:r,tenantId:s.tenantId},m=await A(s,l,v(h),s.token,[s.token]);if(typeof m?.productId!="string"||typeof m?.productBuildId!="string"||!o&&typeof m?.blueprintId!="string")throw new d(`${o?"product.instruments.compose":"product.blueprint.compose"} returned an invalid Product`);await oe(t,{...s,selectedProduct:m.productId});let I=typeof m?.shown_once=="string"&&m.shown_once.length>0?m.shown_once:void 0,g=[`hyperscale product show ${m.productId}`,...I?[]:[`hyperscale key create --name "Founder CLI" --product ${m.productId}`]],f={...m.blueprintId?{blueprintId:m.blueprintId}:{},nextCommands:g,nextSteps:g,productBuildId:m.productBuildId,productId:m.productId,selectedProduct:m.productId,...typeof m.startKeyId=="string"?{startKeyId:m.startKeyId}:{},...I?{shown_once:I}:{}};if(e["--json"]){k(f);return}a(`Product: ${f.productId}`),f.blueprintId&&a(`Blueprint: ${f.blueprintId}`),a(`Build: ${f.productBuildId}`),a(`Selected: ${f.selectedProduct}`),f.shown_once&&a(`Shown once Product API key: ${f.shown_once}`),a("Next:");for(let w of f.nextSteps)a(` ${w}`)}function tt(e){return new URLSearchParams({tenantId:e}).toString()}async function un(e,t){let n=await P(e,t),o=await O(n,"/v1/products",{tenantId:n.tenantId},"product.list",n.token,[n.token]),r=R(o,"product.list");if(e["--json"]){k(o);return}if(r.length===0){a('No Products yet. Run "hyperscale blueprint list", then "hyperscale product create --blueprint <id> --name <name>".');return}a("ID Name Status");for(let i of r){let s=i.productId??i.id??"unknown",c=i.displayName??i.name??"unnamed";a(`${s} ${c}${i.status?` ${i.status}`:""}`)}}async function dn(e,t,n){let o=await P(e,t),r=n??o.selectedProduct;if(!r)throw new d("product show needs an id because no Product is selected. Create a Product first.",{fix:'Run "hyperscale product list" to see existing Products, or "hyperscale product create" to create one.'});let i=await A(o,`/v1/products/${encodeURIComponent(r)}?${tt(o.tenantId)}`,{},o.token,[o.token]);if(e["--json"]){k({...i,nextCommands:[`hyperscale product actions --product ${r}`,`hyperscale key list --product ${r}`]});return}pn(i,r)}function pn(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",s=e?.pricing?.currency??e?.cost?.currency??"SAR",c=e?.pricing?.current?.monthly??e?.cost?.platformMonthly,u=e?.pricing?.current?.setup??e?.cost?.platformSetup,p=[...Array.isArray(e?.readiness?.outstandingLiveRequirements)?e.readiness.outstandingLiveRequirements.map(l=>typeof l=="string"?l:l?.owner?`${l.key} (${l.owner})`:l?.key):[],...Array.isArray(e?.readiness?.liveUnavailableCapabilities)?e.readiness.liveUnavailableCapabilities.map(l=>`unavailable:${l}`):[],...Array.isArray(e?.cost?.blockers)?e.cost.blockers.map(l=>l?.code??"pricing"):[]];if(a(`Name: ${n}`),a(`Product: ${e?.productId??t}`),a(`Status: ${o}`),a(`Blueprint: ${i}`),e?.pricing?.scheduled){let l=e.pricing.current?.monthly,h=e.pricing.scheduled?.monthly;a(`Current billing price: ${s} ${l}/mo`),a(`Accepted price from ${e.pricing.scheduled.effectiveAt}: ${s} ${h}/mo`)}else a(`Monthly: ${c==null?"not returned":`${s} ${c}`}`);a(`Setup: ${u==null?"not returned":`${s} ${u}`}`),a(`Live: ${e?.readiness?.live===!0?"active":"not active"}`),a(`Live blockers: ${p.length>0?p.join(", "):"none"}`);for(let[l,h]of[["openapi","OpenAPI"],["mcp","MCP"],["sdk","SDK"],["graphql","GraphQL"]]){let m=e?.surfaces?.[l];m?.url&&a(`${h}: ${m.url}`)}a("Next:"),a(` hyperscale key create --name "Founder CLI" --product ${e?.productId??t}`)}async function ln(e,t,n){if(!n)throw new d("product select needs a Product id",{fix:'Run "hyperscale product list" to list Products, then pass one ID.'});let o=await P(e,t),r=await A(o,`/v1/products/${encodeURIComponent(n)}?${tt(o.tenantId)}`,{},o.token,[o.token]);if(r?.productId!==n)throw new d("product.retrieve returned the wrong Product");await oe(t,{...o,selectedProduct:n});let s={nextCommands:[`hyperscale product show ${n}`,`hyperscale key list --product ${n}`],productId:n,selected:!0};e["--json"]?k(s):a(`Selected Product: ${r.displayName??n} (${n})`)}function mn(e){return e.map(t=>`${t.path}: error [composer] ${t.code}: ${t.message}`)}function hn(e){return JSON.stringify(we(e))}function we(e){if(e===null||typeof e!="object")return e;if(Array.isArray(e))return e.map(we);let t={};for(let n of Object.keys(e).sort())t[n]=we(e[n]);return t}function nt(e,t=""){if(e==null)return t;if(typeof e=="string")return e;if(typeof e=="object")try{return hn(e)}catch{return t}return String(e)}async function ot(e,t="compose"){if(!e)throw new d(`${t} needs a .hsx file`,{fix:`Run "hyperscale ${t} <file.hsx>" with an existing .hsx file.`});if(!e.endsWith(".hsx"))throw new d(`${t} reads a .hsx file, got ${e}`,{fix:`Point ${t} at a file ending in .hsx.`});let n;try{n=await J(e,"utf8")}catch(o){throw new d(`Could not read ${e}: ${o.message}`)}return{file:e,source:n}}function fn(e){if(!e||typeof e!="object"||typeof e.ok!="boolean"||!Array.isArray(e.issues))throw new d("composer.check returned an invalid result",{fix:'Run the latest unpinned CLI (e.g. "bunx @hyperscale0/cli@latest <command>"), or report the issue without including credentials.'});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 d("composer.check returned an invalid issue",{fix:'Run the latest unpinned CLI (e.g. "bunx @hyperscale0/cli@latest <command>"), or report the issue without including credentials.'});return{code:n.code,message:n.message,path:n.path}}),ok:e.ok}}async function Re(e,t,n,o="none",r="compose"){let i=await ot(n,r),s=await P(e,t),c=o==="required"?q(s,e):o==="optional"?it(s,e):void 0,u=await ie(s,"/v1/composer/check",v({tenantId:s.tenantId,document:i.source,...e["--catalog-revision"]?{catalogRevisionId:e["--catalog-revision"]}:{}}),s.token),p=Ee(u.response,[s.token]),l=fn(Ce(u.response,u.text,[s.token]));if(!l.ok)throw new X(["composer.check refused the program.",...mn(l.issues)].join(`
145
- `),{file:n,issues:l.issues,...p});return{check:l,receipt:p,context:s,productId:c,program:i,catalogRevisionId:e["--catalog-revision"]}}async function yn(e,t,n){let o=await Re(e,t,n,"none","compose check");if(e["--json"]){k({command:"composer.check",file:n,issues:o.check.issues,ok:!0,...o.receipt});return}a(`Check passed: ${n}`)}async function rt(e,t){let n=await ie(e.context,"/v1/composer/plan",v({document:e.program.source,tenantId:e.context.tenantId,...e.productId?{productId:e.productId}:{},...e.catalogRevisionId?{catalogRevisionId:e.catalogRevisionId}:{}}),e.context.token),o=Ce(n.response,n.text,[e.context.token]),r=Ee(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 d("composer.plan returned an invalid result");let i=o.actions.filter(s=>!s||typeof s!="object"||s.kind!=="configure_product");if(i.length>0)throw new X([o.summary,...i.map(s=>s&&typeof s=="object"?`${s.kind??"unknown"} ${s.target??"unknown"} ${nt(s.detail,"Composer refused this action.")}`:"unknown unknown Composer returned an invalid refusal action.")].join(`
146
- `),{actions:i,file:t,...r,...e.productId?{productId:e.productId}:{}});return{...o,...r}}async function wn(e,t,n){let o=await Re(e,t,n,"optional","compose plan"),r=await rt(o,n);if(e["--json"]){k({command:"composer.plan",file:n,check:{...o.check,...o.receipt},plan:r,...o.productId?{productId:o.productId}:{}});return}a(r.summary);for(let s of r.actions)a(`${s.kind} ${s.target} ${nt(s.detail)}`);let i=r.pricing?.currency??"SAR";if(r.pricing?.scheduled){let s=r.pricing.current?.monthly,c=r.pricing.scheduled?.monthly;a(`Current billing price: ${i} ${s}/mo`),a(`Candidate price from ${r.pricing.scheduled.effectiveAt}: ${i} ${c}/mo`),a(`Pricing identity: ${r.pricing.scheduled.pricingIdentity}`)}else if(r.pricing){let s=r.pricing.monthly,c=r.pricing.activation;s!==void 0&&a(`Monthly: ${i} ${s}`),c!==void 0&&a(`Activation: ${i} ${c}`)}}async function gn(e,t,n){if(!e["--confirm"]&&!e["--yes"])throw new d("compose apply changes the selected Product. Pass --confirm, or --yes for an agent.");let o=e["--pricing-identity"];if(!o&&e["--plan-file"]){let u=e["--plan-file"];try{let p=await J(u,"utf8"),l=JSON.parse(p);o=l.plan?.pricing?.scheduled?.pricingIdentity??l.pricing?.scheduled?.pricingIdentity??l.pricingIdentity}catch(p){throw new d(`Failed to read saved plan file ${u}: ${p.message}`)}}let r=await Re(e,t,n,"required","compose apply"),i=await rt(r,n);if(i.pricing?.scheduled&&!o){if(!e["--yes"])throw new d(`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 s=e["--idempotency-key"]??globalThis.crypto.randomUUID(),c;try{c=await A(r.context,"/v1/products/recompose",v({program:{source:r.program.source},...r.catalogRevisionId?{catalogRevisionId:r.catalogRevisionId}:{},...o?{pricingIdentity:o}:{},tenantId:r.context.tenantId,productId:r.productId},s),r.context.token,[r.context.token])}catch(u){throw u instanceof E&&u.code==="product_instrument_not_drained"&&(u.fix=`Drain live instrument instances, or create a new Product directly from source: hyperscale product create --source ${n} --name <name>`),u}if(!c||typeof c.productBuildId!="string")throw new d("product.recompose returned no new build identity");if(e["--json"]){k({command:"product.recompose",file:n,output:c});return}if(a(`Product: ${c.productId??r.productId}`),a(`Build: ${c.productBuildId}`),c.buildDigest&&a(`Digest: ${c.buildDigest}`),c.pricing?.scheduled){let u=c.pricing.currency??"SAR",p=c.pricing.current?.monthly,l=c.pricing.scheduled?.monthly;a(`Current billing price: ${u} ${p}/mo`),a(`Accepted price from ${c.pricing.scheduled.effectiveAt}: ${u} ${l}/mo`)}}function it(e,t){let n=t["--product"]??e.selectedProduct;return typeof n=="string"&&n.length>0?n:void 0}function q(e,t){let n=it(e,t);if(!n)throw new d("No Product selected. Pass --product <id> or create a Product first.",{fix:'Run "hyperscale product list" to see existing Products, or "hyperscale product create" to create one.'});return n}async function Q(e,t){let n=await ne(t),o=q(n??{},e),r=D(e,t,n??{});if(n&&(r.baseUrl!==n.baseUrl||r.environment!==n.environment))throw new d(`The selected Product belongs to ${n.baseUrl} (${n.environment}). Select a Product at the configured API origin first.`);let i=e["--api-key"]??t.HYPERSCALE_API_KEY;if(!i)throw Be(o);return{...r,apiKey:i,productId:o}}async function st(e,t){let n=`/v1/products/${encodeURIComponent(e.productId)}/operation-set`,{response:o,text:r}=await se(e,n,{},t);if(!o.ok)throw ct(o,r,[e.apiKey],{productId:e.productId});return kn(r,o.status)}async function In(e,t,n){let o=await Q(e,t),r=await st(o);if(n){$n(r,n,e);return}if(e["--json"]){k(r);return}if(r.publicActions.length===0)a("No public actions");else{a("Operation ID Input Kind");for(let i of r.publicActions){let s=i.idempotencyPolicy?.mode==="not_required"?"read-only":"mutation";a(`${i.instrument}.${i.name} ${An(i.inputSchema)} ${s}`)}}if(r.setupOperations.length>0){a("Setup operations (run with hyperscale call)");for(let i of r.setupOperations)a(i.operationName)}if(r.readOperationIds.length>0){a("Reads (run with hyperscale call)");for(let i of r.readOperationIds)a(bn(i))}a(`Digest: ${r.tenantOperationSetDigest}`),a(`Setup digest: ${r.tenantSetupOperationSetDigest}`),a(`Read digest: ${r.tenantReadOperationSetDigest}`),a(`Build: ${r.productBuildId}`),a(`Surface version: ${r.tenantSurfaceVersion}`)}function $n(e,t,n){let o=e.publicActions.find(c=>c&&`${c.instrument}.${c.name}`===t),r=Pn(t),i=e.setupOperations.find(c=>c&&(c.operationId===t||c.operationId===r||c.operationName===t));if(i){let{inputSchema:c,operationId:u,operationName:p}=i,l={status:e.status,productBuildId:e.productBuildId,tenantSurfaceVersion:e.tenantSurfaceVersion,tenantSetupOperationSetDigest:e.tenantSetupOperationSetDigest,setupOperationId:u,operationName:p,command:`hyperscale call ${p}`,inputSchema:c};if(n["--json"]){k(l);return}a(`Operation ID: ${u}`),a(`Operation name: ${p}`),a(`Run: hyperscale call ${p}`),a(`Input schema: ${JSON.stringify(c,null,2)}`),(!Array.isArray(c.required)||c.required.length===0)&&a("Input: omit --input or pass {}."),a(`Setup digest: ${e.tenantSetupOperationSetDigest}`),a(`Build: ${e.productBuildId}`),a(`Surface version: ${e.tenantSurfaceVersion}`);return}if(!o)throw new d(`Unknown frozen public action: ${t}. Run "hyperscale product actions" to list exact names.`);let s={status:e.status,productBuildId:e.productBuildId,tenantSurfaceVersion:e.tenantSurfaceVersion,tenantOperationSetDigest:e.tenantOperationSetDigest,qualifiedName:`${o.instrument}.${o.name}`,publicAction:o};if(n["--json"]){k(s);return}a(`Operation ID: ${o.instrument}.${o.name}`),a(`Instrument: ${o.instrument}`),a(`Input schema: ${JSON.stringify(o.inputSchema,null,2)}`),a(`Output schema: ${JSON.stringify(o.outputSchema,null,2)}`),a(`Actor policy: ${JSON.stringify(o.actorPolicy,null,2)}`),a(`Port policy: ${JSON.stringify(o.portPolicy,null,2)}`),a(`Idempotency policy: ${JSON.stringify(o.idempotencyPolicy,null,2)}`),a(`Receipt policy: ${JSON.stringify(o.receiptPolicy,null,2)}`),a(`Receipt evidence: ${JSON.stringify(o.receiptEvidence,null,2)}`),a(`Digest: ${e.tenantOperationSetDigest}`),a(`Build: ${e.productBuildId}`),a(`Surface version: ${e.tenantSurfaceVersion}`)}function kn(e,t){let n;try{n=JSON.parse(e)}catch{throw new d(`HTTP ${t} returned invalid JSON`)}if(!n||typeof n!="object"||n.status!=="frozen"||typeof n.productBuildId!="string"||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 d("The Product operation set is not in the expected format.",{fix:'Run the latest unpinned CLI (e.g. "bunx @hyperscale0/cli@latest <command>"), or report the issue without including credentials.'});return n.publicActions=n.publicActions.map(o=>{if(!o||typeof o!="object"||typeof o.instrument!="string"||o.instrument.length===0||typeof o.name!="string"||o.name.length===0)throw new d("The server's public action names no instrument or action name. The platform predates Product identity in public actions: redeploy it.");return{...o,qualifiedName:`${o.instrument}.${o.name}`}}),n}function Pn(e){return e.replaceAll(".","_")}function bn(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 An(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)?"":"?"}: ${at(i)}`);return o.length===0?"no input":o.join(", ")}function at(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"?`${at(e.items)}[]`:typeof e.type=="string"?typeof e.format=="string"?`${e.type} (${e.format})`:e.type:"value"}async function Sn(e,t,n){if(!n)throw new d("product run needs a public action");let o=await Q(e,t),r=await st(o,n);xn(r,n);let i=await ut(e),s=e["--idempotency-key"]??globalThis.crypto.randomUUID(),{response:c,text:u}=await se(o,`/v1/operations/${encodeURIComponent(n)}`,{body:JSON.stringify(i),headers:{"content-type":"application/json","idempotency-key":s},method:"POST"},n);if(!c.ok)throw ct(c,u,[o.apiKey],{action:n,productId:o.productId});let p=c.headers.get("hyperscale-operation-id"),l=c.headers.get("hyperscale-receipt-id"),h=c.headers.get("x-request-id"),m=p?y(p,[o.apiKey]):null,I=l?y(l,[o.apiKey]):null,g=h?y(h,[o.apiKey]):null;if(e["--json"]){k({idempotencyKey:s,...g?{requestId:g}:{},operationId:m,receiptId:I,output:vn(u)});return}m&&a(`Operation: ${m}`),I&&a(`Receipt: ${I}`),a(`Idempotency key: ${s}`);let f=dt(u);f&&a(f)}function xn(e,t){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:Ie(t,r)})).sort((r,i)=>r.distance-i.distance||r.candidate.localeCompare(i.candidate)).slice(0,3).map(({candidate:r})=>r);throw new d(`Unknown frozen public action: ${t}. Closest valid names: ${o.join(", ")}. Run "hyperscale product actions" to list exact names.`)}function vn(e){if(e.trim()==="")return null;try{return JSON.parse(e)}catch{return e}}function ct(e,t,n=[],o={}){let r=et(t,n,e.status),i=Qe(e.headers,r.requestId,n),s=r.code??"user_error",c=r.redactedMessage;if(typeof c=="string"&&c.includes("does not match API key Product")){let m=o.productId??c.match(/^Selected Product (\S+) does not match/)?.[1];m&&(c=`${c} Or set HYPERSCALE_API_KEY to a key for ${m}, or pass that key with --api-key.`)}let u=s==="user_error"?"":`${s}: `,p=`HTTP ${e.status} \xB7 ${u}${c}`,l=Tn(r.details,n),h=r.fix;return s==="idempotency_conflict"?h="Reuse the same key only with the same operation and input. Use a new unique key for a different request.":e.status===409&&typeof c=="string"&&c.includes("capability-derived")?h='This Product has no frozen public actions. List its operations with "hyperscale ops list" and run them with "hyperscale call".':[c,...l].some(m=>typeof m=="string"&&m.includes("[Truncated]"))&&o.action&&(h=`Run "hyperscale product actions ${o.action}" to read the full input schema and allowed values.`),new E([p,...l].join(`
147
- `),{code:s,details:r.details,fix:h,operationId:i.operationId,receiptId:i.receiptId,requestId:i.requestId,status:e.status,traceId:i.traceId})}function Tn(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 ge(e,"",n,t),n}function ge(e,t,n,o){if(Array.isArray(e)){if(e.every(r=>r===null||typeof r!="object")){n.push(`${Ke(t)}: ${y(e.join(", "),o)}`);return}e.forEach((r,i)=>ge(r,`${t}[${i}]`,n,o));return}if(e&&typeof e=="object"){for(let[r,i]of Object.entries(e))ge(i,t?`${t}.${r}`:r,n,o);return}t&&n.push(`${Ke(t)}: ${y(String(e),o)}`)}function Ke(e){let t=e.replace(/([a-z0-9])([A-Z])/g,"$1 $2").replaceAll("."," ");return t.charAt(0).toUpperCase()+t.slice(1)}async function En(e,t){let n=await P(e,t),o=q(n,e),r=await A(n,"/v1/sandbox-api-keys",v({name:e["--name"]??"Founder CLI",tenantId:n.tenantId,productId:o}),n.token,[n.token]),i=["export HYPERSCALE_API_KEY=<paste the shown_once value>",`hyperscale product actions --product ${o}`];if(e["--json"]){let{secret:s,...c}=r;k({...c,...typeof s=="string"?{shown_once:s}:{},nextCommands:i});return}a(`Key: ${r.apiKeyId??"unknown"}`),a(`Product: ${r.productId??o}`),a(`Status: ${r.status??"unknown"}`),r.secret?(a(`Secret: ${r.secret}`),a("Store it now. Hyperscale will not return it again."),a("Next:"),a(" export HYPERSCALE_API_KEY=<paste the secret above>"),a(` hyperscale product actions --product ${o}`)):a("The key already existed, so the one-time secret is unavailable.")}async function Cn(e,t){let n=await P(e,t),o=q(n,e),r=await O(n,"/v1/api-keys",{productId:o,tenantId:n.tenantId},"api_key.list",n.token,[n.token]),i=R(r,"api_key.list");if(e["--json"]){k(r);return}for(let s of i)a(`${s.apiKeyId} ${s.name??"unnamed"} ${s.status??"unknown"}`)}async function Rn(e,t,n){if(!n)throw new d("key revoke needs an API key id",{fix:'Run "hyperscale key list" to list keys, then pass one ID.'});let o=await P(e,t),r=q(o,e),i=await A(o,`/v1/api-keys/${encodeURIComponent(n)}/revoke`,v({tenantId:o.tenantId,productId:r}),o.token,[o.token]);e["--json"]?k(i):a(`Key ${i.apiKeyId??n}: ${i.status??"revoked"}`)}async function _n(e,t){let n=await P(e,t),o=n.identity??await C(n,n.token),r=Te(n,o);if(e["--json"]){k(r);return}a(`User: ${o.email}`),a(`Tenant: ${o.tenantId}`),a(`Role: ${o.role}`),a(`Token: ${o.name}`),a(`Expires: ${o.expiresAt}`)}async function On(e,t,n){let o=await Xe(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"]){a(JSON.stringify(i,null,2));return}if(i.length===0){a(n?`No operation matches ${n}`:"No operations");return}let s=Math.max(...i.map(c=>c.name.length));for(let c of i)a(`${c.name.padEnd(s)} ${c.method.padEnd(6)}${c.path}`)}async function Nn(e,t){let n=await P(e,t),o=await O(n,"/v1/activity",{tenantId:n.tenantId},"activity.list",n.token,[n.token]),r=R(o,"activity.list");if(e["--json"]){k(o);return}a("Time Activity Target Status");for(let i of r){let s=i.operation??i.auditEvent??"activity",c=i.resourceKind&&i.resourceId?`${i.resourceKind}:${i.resourceId}`:i.resourceKind??i.resourceId??"-";a(`${i.occurredAt??"unknown"} ${s} ${c} ${i.status??"recorded"}`)}}function jn(e,t){let n={...t},o=[],r=e.path.replace(/\{([^}]+)\}/g,(i,s)=>{let c=n[s];return c==null?(o.push(s),""):(delete n[s],encodeURIComponent(String(c)))});if(o.length>0)throw new d(`${e.name} needs ${o.join(", ")} in --input`);return{path:r,remaining:n}}function Ln(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 Ie(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 Un(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 d(`${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(Ie(t,i.name),Ie(t,i.operationId))})).sort((i,s)=>i.distance-s.distance||i.candidate.name.localeCompare(s.candidate.name)).slice(0,3).flatMap(({candidate:i})=>[i.name,i.operationId]);throw new d(`${t} is not an operation in the selected Product's machine document. Closest valid names: ${r.join(", ")}.`)}async function Hn(e,t,n){if(!n)throw new d("call needs an operation name",{fix:'Run "hyperscale ops list" to list operations.'});let o=await Xe(e),r=Un(o.operations,n),i=await ut(t),{path:s,remaining:c}=jn(r,i),u={method:r.method},p=s;r.method==="GET"?p+=Ln(c):(u.body=JSON.stringify(c),u.headers={"content-type":"application/json",...r.idempotency==="not_required"?{}:{"idempotency-key":t["--idempotency-key"]??globalThis.crypto.randomUUID()}});let{response:l,text:h}=await se(e,p,u);if(l.ok){if(t["--json"]){let m=Jt(h),I=l.headers.get("x-request-id")??(m&&typeof m=="object"&&typeof m.requestId=="string"?m.requestId:null),g=l.headers.get("hyperscale-operation-id")??null,f=l.headers.get("hyperscale-receipt-id")??null,w=Ze(l.headers),b=I?y(I,[e.apiKey]):null,T=g?y(g,[e.apiKey]):null,Y=f?y(f,[e.apiKey]):null,_=w?y(w,[e.apiKey]):null;k({status:l.status,data:m,requestId:b,operationId:T,receiptId:Y,traceId:_});return}a(dt(h));return}throw ae(l,h,[e.apiKey])}async function ut(e){if(e["--input"]!==void 0&&e["--input-file"]!==void 0)throw new d("Use only one of --input and --input-file");if(e["--input"]!==void 0)return pe(e["--input"],"--input");if(e["--input-file"]!==void 0){let t;try{t=await J(e["--input-file"],"utf8")}catch(n){throw new d(`Could not read ${e["--input-file"]}: ${n.message}`)}return pe(t,"--input-file")}if(!process.stdin.isTTY){let t=await Dt();if(t.trim()!=="")return pe(t,"stdin")}return{}}function pe(e,t="--input"){if(e===void 0)return{};let n;try{n=JSON.parse(e)}catch(o){throw new d(`${t} is not valid JSON: ${o.message}`)}if(n===null||typeof n!="object"||Array.isArray(n))throw new d(`${t} must be a JSON object`);return n}function dt(e){if(e.trim()==="")return"";try{return JSON.stringify(JSON.parse(e),null,2)}catch{return e}}function a(e){process.stdout.write(`${e}
148
- `)}function k(e){a(JSON.stringify(e,null,2))}function Dn(e,t){let n=t.includes("--json"),o=[process.env.HYPERSCALE_API_KEY,process.env.HYPERSCALE_TOKEN].filter(Boolean),r=e instanceof d,i=r?e.message:"The command failed unexpectedly.",s=$(y(String(i),o)),c=s.length>1024?s.slice(0,1024):s,u=r?e.fix??'Follow the message, or run "hyperscale --help" for command usage.':"Report the failure without including credentials.",p=$(y(String(u),o)),l=r&&typeof e.shownOnce=="string"?$(y(e.shownOnce,o)):void 0;if(!n){let S=r?c:e?.stack??s,pt=r&&typeof e.fix=="string"?`
149
- Fix: ${p}`:"",lt=l?`
150
- Shown once Product API key: ${l}`:"";process.stderr.write(`${S}${pt}${lt}
151
- `);return}let h=(typeof e?.structuredError?.code=="string"?e.structuredError.code:void 0)??(r&&typeof e.code=="string"?e.code:r?"user_error":"internal_error"),m=(typeof e?.structuredError?.message=="string"?e.structuredError.message:void 0)??(r?e.message:"The command failed unexpectedly."),I=$(y(String(m),o)),g=I.length>1024?I.slice(0,1024):I,f=(typeof e?.structuredError?.fix=="string"?e.structuredError.fix:void 0)??(r?e.fix??'Follow the message, or run "hyperscale --help" for command usage.':"Report the failure without including credentials."),w=$(y(String(f),o)),b=w.length>1024?w.slice(0,1024):w,T=e?.structuredError?.details!==void 0?e.structuredError.details:r&&e.details!==void 0?e.details:void 0,Y=T!==void 0?Z(T,o):void 0,_=r&&typeof e.status=="number"?e.status:void 0,F=S=>typeof S!="string"||S.trim().length===0?null:$(y(S.trim(),o)),M=r&&(e.requestId!==void 0||e.operationId!==void 0||e.receiptId!==void 0||e.traceId!==void 0),z=M?F(e.requestId):void 0,W=M?F(e.operationId):void 0,V=M?F(e.receiptId):void 0,G=M?F(e.traceId):void 0,_e=S=>({..._!==void 0?{status:_}:{},error:{code:h,message:g,...S!==void 0?{details:S}:{},fix:b},...z!==void 0?{requestId:z}:{},...W!==void 0?{operationId:W}:{},...V!==void 0?{receiptId:V}:{},...G!==void 0?{traceId:G}:{},...l?{shown_once:l}:{}}),Oe=S=>Buffer.byteLength(S,"utf8")>8192,N=_e(Y),j=JSON.stringify(N);Oe(j)&&Y!==void 0&&(N=_e("[Truncated]"),j=JSON.stringify(N)),Oe(j)&&(N={..._!==void 0?{status:_}:{},error:{code:h,message:g,fix:"[Truncated]"},...z!==void 0?{requestId:z}:{},...W!==void 0?{operationId:W}:{},...V!==void 0?{receiptId:V}:{},...G!==void 0?{traceId:G}:{}},j=JSON.stringify(N)),process.stderr.write(`${j}
152
- `)}async function Kn(){let{readFileSync:e}=await import("node:fs");return JSON.parse(e(new URL("./package.json",import.meta.url),"utf8")).version}async function Jn(e,t){let{flags:n,positional:o}=Rt(e);if(n["--version"])return a(await Kn()),0;if(n["--help"]&&o.length>0)return process.stdout.write(je(o)),0;if(o[0]==="help"){let s=o.slice(1);return s.length===0?process.stdout.write(Ne):process.stdout.write(je(s)),0}if(o.length===0&&!n["--help"]){if(n["--json"])throw new d('No command. Run "hyperscale --help" to list commands.');return process.stdin.isTTY&&process.stderr.isTTY?(await De(n,t),0):(a('Build your first Product with "hyperscale start".'),a('Run "hyperscale --help" for every command.'),0)}if(n["--help"])return process.stdout.write(Ne),0;let[r,...i]=o;if(r==="start")return await De(n,t),0;if(r==="auth"){if(i[0]==="login")await Mt(n,t);else if(i[0]==="status")await zt(n,t);else if(i[0]==="logout")await Wt(n,t);else throw new d('Auth subcommands are "login", "status", and "logout"',{fix:'Run "hyperscale help auth" to see valid subcommands.'});return 0}if(r==="blueprint"){let s=D(n,t);if(i[0]==="list")await Gt(s,n);else if(i[0]==="show")await Xt(s,n,i[1]);else throw new d('Blueprint subcommands are "list" and "show"',{fix:'Run "hyperscale help blueprint" to see valid subcommands.'});return 0}if(r==="product"){if(i[0]==="create")await cn(n,t);else if(i[0]==="list")await un(n,t);else if(i[0]==="show")await dn(n,t,i[1]);else if(i[0]==="select")await ln(n,t,i[1]);else if(i[0]==="actions")await In(n,t,i[1]);else if(i[0]==="run")await Sn(n,t,i[1]);else throw new d('Product subcommands are "create", "list", "show", "select", "actions", and "run"',{fix:'Run "hyperscale help product" to see valid subcommands.'});return 0}if(r==="compose"){if(i[0]==="check")await yn(n,t,i[1]);else if(i[0]==="plan")await wn(n,t,i[1]);else if(i[0]==="apply")await gn(n,t,i[1]);else throw new d('Compose subcommands are "check", "plan", and "apply"',{fix:'Run "hyperscale help compose" to see valid subcommands.'});return 0}if(r==="key"){if(i[0]==="create")await En(n,t);else if(i[0]==="list")await Cn(n,t);else if(i[0]==="revoke")await Rn(n,t,i[1]);else throw new d('Key subcommands are "create", "list", and "revoke"',{fix:'Run "hyperscale help key" to see valid subcommands.'});return 0}if(r==="whoami")return await _n(n,t),0;if(r==="activity"){if(i[0]!=="list")throw new d('The only activity subcommand is "list"',{fix:'Run "hyperscale help activity" to see usage.'});return await Nn(n,t),0}if(r==="ops"){if(i[0]!=="list")throw new d('The only ops subcommand is "list"',{fix:'Run "hyperscale help ops" to see usage.'});let s=n["--product"]?await Q(n,t):Le(n,t);return await On(s,n,i[1]),0}if(r==="call"){let s=n["--product"]?await Q(n,t):Le(n,t);return await Hn(s,n,i[0]),0}throw new d(`Unknown command: ${r}`,{fix:'Run "hyperscale --help" to list commands.'})}Jn(process.argv.slice(2),process.env).then(e=>{process.exitCode=e},e=>{Dn(e,process.argv.slice(2)),process.exitCode=e instanceof d&&Number.isInteger(e.exitCode)?e.exitCode:1});
40
+ `)}function Ce(e,t=[]){let n=e.headers.get("hyperscale-operation-id"),o=e.headers.get("hyperscale-receipt-id"),r=n?y(n,t):void 0,s=o?y(o,t):void 0;return{...r?{operationId:r}:{},...s?{receiptId:s}:{}}}function ve(e,t,n=[]){if(!e.ok)throw de(e,t,n);try{return JSON.parse(t)}catch{throw new d(`HTTP ${e.status} returned invalid JSON`)}}function gn(e,t){t.operationId&&u(`${e} operation: ${t.operationId}`),t.receiptId&&u(`${e} receipt: ${t.receiptId}`)}function wn(e,t,n){let o=e?.message??String(e),r=[...n?[`hyperscale product show ${n}`]:[],"hyperscale product list"],s="Warning: The returned Product API key was the only copy. Save it or mint a replacement with key create.",i=[`hyperscale start failed after Product ${n??""} was created: ${o}.`,s,"Inspect the created Product with:",...r.map(c=>` ${c}`)].join(`
41
+ `),a=new d(i,{code:"start_failed_after_compose",details:{cause:o,...n?{productId:n}:{},recovery:r,warning:s},fix:n?`Inspect the created Product with "hyperscale product show ${n}".`:'Inspect created Products with "hyperscale product list".'});return a.shownOnce=t,a}function In(e){if(!e["--blueprint"]&&!(process.stdin.isTTY&&process.stderr.isTTY))throw new d("hyperscale start needs an interactive terminal to choose a company. Pass --blueprint <slug> in scripts and non-interactive environments.",{code:"start_blueprint_required",fix:'Run "hyperscale blueprint list", then pass --blueprint <slug>.'})}function bn(e){return O(e,"blueprint.list").map(t=>{if(typeof t?.id!="string"||t.id.length===0||typeof t?.name!="string"||t.name.length===0)throw new d("blueprint.list returned an invalid start choice");return{id:t.id,name:t.name,summary:typeof t.summary=="string"?t.summary:""}})}async function kn(e,t){let n=await L(t,"/v1/blueprints",{},"blueprint.list"),o=bn(n);if(o.length===0)throw new d("The Blueprint catalog has no companies to build.");let r=e["--blueprint"];if(r){let f=o.find(({id:m})=>m===r);if(f)return f;throw new d(`Unknown Blueprint: ${r}`,{fix:'Run "hyperscale blueprint list" and pass one listed slug to --blueprint.'})}process.stderr.write(`Which company do you want to build?
42
+ `);for(let[f,m]of o.entries()){let g=m.summary.replace(/\s+/g," ").trim();process.stderr.write(` ${f+1}. ${m.name} (${m.id})${g?`: ${g}`:""}
43
+ `)}let s=Ge({input:process.stdin,output:process.stderr,terminal:!0}),i=new AbortController,a=()=>i.abort();process.stdin.once("end",a),process.stdin.readableEnded&&i.abort();let c;try{try{c=(await s.question("Choose a number or Blueprint slug: ",{signal:i.signal})).trim()}catch(f){throw f?.name!=="AbortError"&&f?.code!=="ABORT_ERR"?f:new d("Start cancelled before a Blueprint was chosen.",{code:"start_cancelled"})}}finally{process.stdin.off("end",a),s.close()}let l=Number(c),p=Number.isInteger(l)?o[l-1]:o.find(({id:f})=>f===c);if(p)return p;throw new d(`No Blueprint matches ${JSON.stringify(c)}.`,{fix:"Run hyperscale start again and choose a listed number or slug."})}async function We(e,t){In(e);let n={};try{await Pn(e,t,n)}catch(o){throw typeof n.apiKey!="string"?o:wn(o,n.apiKey,n.productId)}}async function Pn(e,t,n){let o=await $(e,t),r=await j(o,o.token),s=await kn(e,o),i=e["--name"]??s.name;e["--json"]||u(`Authenticated: ${r.email}`);let a=await ce(o,"/v1/products/blueprint-compose",T({blueprintId:s.id,name:i,tenantId:o.tenantId}),o.token),c=ve(a.response,a.text,[o.token]);if(typeof c?.productId!="string"||!Yt.test(c.productId)||typeof c?.productBuildId!="string"||c?.blueprintId!==s.id)throw new d("product.blueprint.compose returned an invalid start Product");let l=c?.shown_once;if(typeof l!="string"||l.length===0)throw new d("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,n.productId=c.productId;let p=Ce(a.response);await ie(t,{...o,selectedProduct:c.productId}),e["--json"]||(u(`Product: ${c.productId}`),u(`Blueprint: ${c.blueprintId}`),gn("Compose",p));let f=[`hyperscale compose plan product.hsx --product ${c.productId}`],m="Composition completed. Run SDK journeys against your Product.",g={blueprintId:c.blueprintId,composeOnly:!0,nextCommands:f,notice:m,productBuildId:c.productBuildId,productId:c.productId,receipts:[{stage:"product.blueprint.compose",...p}],...typeof c.startKeyId=="string"?{startKeyId:c.startKeyId}:{},shown_once:l};if(e["--json"]){k(g);return}u(m),u(`Shown once Product API key: ${l}`),u("Next:");for(let I of f)u(` ${I}`);u(" Run journeys with the Hyperscale SDK using the Product API key above.")}async function $n(e,t){let n=e["--blueprint"],o=e["--source"],r=e["--name"];if(n&&o)throw new d("product create accepts either --blueprint <id> or --source <file>, not both");if(!n&&!o)throw new d("product create needs either --blueprint <id> or --source <file>");if(!r)throw new d("product create needs --name <name>");let s=o?await ht(o,"product create"):void 0,i=await $(e,t),a;try{a=await L(i,"/v1/products",{tenantId:i.tenantId},"product.list",i.token,[i.token])}catch(w){if(!(w instanceof v)||w.status!==403)throw w}let c=r.trim().toLocaleLowerCase("en-US"),l=(a?O(a,"product.list"):[]).find(w=>{let x=w?.displayName??w?.name;return typeof x=="string"&&x.trim().toLocaleLowerCase("en-US")===c});if(l){let w=l.productId??l.id??"<id>";throw new d(`A Product named ${JSON.stringify(r.trim())} already exists as ${w}.`,{code:"duplicate_product_name",fix:`Use "hyperscale product select ${w}" or choose another --name.`})}let p=o?"/v1/products/instruments-compose":"/v1/products/blueprint-compose",f=o?{name:r,program:{source:s.source},tenantId:i.tenantId,...e["--catalog-revision"]?{catalogRevisionId:e["--catalog-revision"]}:{}}:{blueprintId:n,name:r,tenantId:i.tenantId},m=await S(i,p,T(f),i.token,[i.token]);if(typeof m?.productId!="string"||typeof m?.productBuildId!="string"||!o&&typeof m?.blueprintId!="string")throw new d(`${o?"product.instruments.compose":"product.blueprint.compose"} returned an invalid Product`);await ie(t,{...i,selectedProduct:m.productId});let g=typeof m?.shown_once=="string"&&m.shown_once.length>0?m.shown_once:void 0,I=[`hyperscale product show ${m.productId}`,...g?[]:[`hyperscale key create --name "Founder CLI" --product ${m.productId}`]],h={...m.blueprintId?{blueprintId:m.blueprintId}:{},nextCommands:I,nextSteps:I,productBuildId:m.productBuildId,productId:m.productId,selectedProduct:m.productId,...typeof m.startKeyId=="string"?{startKeyId:m.startKeyId}:{},...g?{shown_once:g}:{}};if(e["--json"]){k(h);return}u(`Product: ${h.productId}`),h.blueprintId&&u(`Blueprint: ${h.blueprintId}`),u(`Build: ${h.productBuildId}`),u(`Selected: ${h.selectedProduct}`),h.shown_once&&u(`Shown once Product API key: ${h.shown_once}`),u("Next:");for(let w of h.nextSteps)u(` ${w}`)}function mt(e){return new URLSearchParams({tenantId:e}).toString()}async function xn(e,t){let n=await $(e,t),o=await L(n,"/v1/products",{tenantId:n.tenantId},"product.list",n.token,[n.token]),r=O(o,"product.list");if(e["--json"]){k(o);return}if(r.length===0){u('No Products yet. Run "hyperscale blueprint list", then "hyperscale product create --blueprint <id> --name <name>".');return}let s=P(process.stdout,t,{json:!1});u(C(s,{columns:["ID","Name","Status"],rows:r.map(i=>[i.productId??i.id??"unknown",i.displayName??i.name??"unnamed",i.status??""])}))}async function Sn(e,t,n){let o=await $(e,t),r=n??o.selectedProduct;if(!r)throw new d("product show needs an id because no Product is selected. Create a Product first.",{fix:'Run "hyperscale product list" to see existing Products, or "hyperscale product create" to create one.'});let s=await S(o,`/v1/products/${encodeURIComponent(r)}?${mt(o.tenantId)}`,{},o.token,[o.token]);if(e["--json"]){k({...s,nextCommands:[`hyperscale product actions --product ${r}`,`hyperscale key list --product ${r}`]});return}An(s,r)}function An(e,t){let n=e?.displayName??e?.name??"unnamed",o=e?.status??"unknown",r=e?.blueprint,s=r?.id?`${r.name??r.id}${r.name?` (${r.id})`:""}`:"custom composition",i=e?.pricing?.currency??e?.cost?.currency??"SAR",a=e?.pricing?.current?.monthly??e?.cost?.platformMonthly,c=e?.pricing?.current?.setup??e?.cost?.platformSetup,l=[...Array.isArray(e?.readiness?.outstandingLiveRequirements)?e.readiness.outstandingLiveRequirements.map(m=>typeof m=="string"?m:m?.owner?`${m.key} (${m.owner})`:m?.key):[],...Array.isArray(e?.readiness?.liveUnavailableCapabilities)?e.readiness.liveUnavailableCapabilities.map(m=>`unavailable:${m}`):[],...Array.isArray(e?.cost?.blockers)?e.cost.blockers.map(m=>m?.code??"pricing"):[]],p=P(process.stdout,process.env,{json:!1}),f=[["Name",n],["Product",e?.productId??t],["Status",o],["Blueprint",s]];if(e?.pricing?.scheduled){let m=e.pricing.current?.monthly,g=e.pricing.scheduled?.monthly;f.push(["Current billing price",`${i} ${m}/mo`],[`Accepted price from ${e.pricing.scheduled.effectiveAt}`,`${i} ${g}/mo`])}else f.push(["Monthly",a==null?"not returned":`${i} ${a}`]);f.push(["Setup",c==null?"not returned":`${i} ${c}`]),f.push(["Live",e?.readiness?.live===!0?"active":"not active"]),f.push(["Live blockers",l.length>0?l.join(", "):"none"]);for(let[m,g]of[["openapi","OpenAPI"],["mcp","MCP"],["sdk","SDK"],["graphql","GraphQL"]]){let I=e?.surfaces?.[m];I?.url&&f.push([g,I.url])}u(N(p,{fields:f})),u(""),u("Next:"),u(` hyperscale key create --name "Founder CLI" --product ${e?.productId??t}`)}async function En(e,t,n){if(!n)throw new d("product select needs a Product id",{fix:'Run "hyperscale product list" to list Products, then pass one ID.'});let o=await $(e,t),r=await S(o,`/v1/products/${encodeURIComponent(n)}?${mt(o.tenantId)}`,{},o.token,[o.token]);if(r?.productId!==n)throw new d("product.retrieve returned the wrong Product");await ie(t,{...o,selectedProduct:n});let i={nextCommands:[`hyperscale product show ${n}`,`hyperscale key list --product ${n}`],productId:n,selected:!0};e["--json"]?k(i):u(`Selected Product: ${r.displayName??n} (${n})`)}function Tn(e){return e.map(t=>`${t.path}: error [composer] ${t.code}: ${t.message}`)}function Rn(e){return JSON.stringify(ke(e))}function ke(e){if(e===null||typeof e!="object")return e;if(Array.isArray(e))return e.map(ke);let t={};for(let n of Object.keys(e).sort())t[n]=ke(e[n]);return t}function ft(e,t=""){if(e==null)return t;if(typeof e=="string")return e;if(typeof e=="object")try{return Rn(e)}catch{return t}return String(e)}async function ht(e,t="compose"){if(!e)throw new d(`${t} needs a .hsx file`,{fix:`Run "hyperscale ${t} <file.hsx>" with an existing .hsx file.`});if(!e.endsWith(".hsx"))throw new d(`${t} reads a .hsx file, got ${e}`,{fix:`Point ${t} at a file ending in .hsx.`});let n;try{n=await Y(e,"utf8")}catch(o){throw new d(`Could not read ${e}: ${o.message}`)}return{file:e,source:n}}function Cn(e){if(!e||typeof e!="object"||typeof e.ok!="boolean"||!Array.isArray(e.issues))throw new d("composer.check returned an invalid result",{fix:'Run the latest unpinned CLI (e.g. "bunx @hyperscale0/cli@latest <command>"), or report the issue without including credentials.'});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 d("composer.check returned an invalid issue",{fix:'Run the latest unpinned CLI (e.g. "bunx @hyperscale0/cli@latest <command>"), or report the issue without including credentials.'});return{code:n.code,message:n.message,path:n.path}}),ok:e.ok}}async function je(e,t,n,o="none",r="compose"){let s=await ht(n,r),i=await $(e,t),a=o==="required"?F(i,e):o==="optional"?gt(i,e):void 0,c=await ce(i,"/v1/composer/check",T({tenantId:i.tenantId,document:s.source,...e["--catalog-revision"]?{catalogRevisionId:e["--catalog-revision"]}:{}}),i.token),l=Ce(c.response,[i.token]),p=Cn(ve(c.response,c.text,[i.token]));if(!p.ok)throw new ee(["composer.check refused the program.",...Tn(p.issues)].join(`
44
+ `),{file:n,issues:p.issues,...l});return{check:p,receipt:l,context:i,productId:a,program:s,catalogRevisionId:e["--catalog-revision"]}}async function vn(e,t,n){let o=await je(e,t,n,"none","compose check");if(e["--json"]){k({command:"composer.check",file:n,issues:o.check.issues,ok:!0,...o.receipt});return}u(`Check passed: ${n}`)}async function yt(e,t){let n=await ce(e.context,"/v1/composer/plan",T({document:e.program.source,tenantId:e.context.tenantId,...e.productId?{productId:e.productId}:{},...e.catalogRevisionId?{catalogRevisionId:e.catalogRevisionId}:{}}),e.context.token),o=ve(n.response,n.text,[e.context.token]),r=Ce(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 d("composer.plan returned an invalid result");let s=o.actions.filter(i=>!i||typeof i!="object"||i.kind!=="configure_product");if(s.length>0)throw new ee([o.summary,...s.map(i=>i&&typeof i=="object"?`${i.kind??"unknown"} ${i.target??"unknown"} ${ft(i.detail,"Composer refused this action.")}`:"unknown unknown Composer returned an invalid refusal action.")].join(`
45
+ `),{actions:s,file:t,...r,...e.productId?{productId:e.productId}:{}});return{...o,...r}}async function jn(e,t,n){let o=await je(e,t,n,"optional","compose plan"),r=await yt(o,n);if(e["--json"]){k({command:"composer.plan",file:n,check:{...o.check,...o.receipt},plan:r,...o.productId?{productId:o.productId}:{}});return}u(r.summary);for(let i of r.actions)u(`${i.kind} ${i.target} ${ft(i.detail)}`);let s=r.pricing?.currency??"SAR";if(r.pricing?.scheduled){let i=r.pricing.current?.monthly,a=r.pricing.scheduled?.monthly;u(`Current billing price: ${s} ${i}/mo`),u(`Candidate price from ${r.pricing.scheduled.effectiveAt}: ${s} ${a}/mo`),u(`Pricing identity: ${r.pricing.scheduled.pricingIdentity}`)}else if(r.pricing){let i=r.pricing.monthly,a=r.pricing.activation;i!==void 0&&u(`Monthly: ${s} ${i}`),a!==void 0&&u(`Activation: ${s} ${a}`)}}async function On(e,t,n){if(!e["--confirm"]&&!e["--yes"])if(process.stdin.isTTY&&process.stderr.isTTY){let c=P(process.stderr,process.env,{json:!1});process.stderr.write(`${Ke(c,{action:"recompose",subject:n,confirmation:"Recompose selected Product?"})}
46
+ `);let l=Ge({input:process.stdin,output:process.stderr,terminal:!0});try{let p=await l.question("");if(p.trim().toLowerCase()!=="y"&&p.trim().toLowerCase()!=="yes")throw new d("Mutation cancelled.",{code:"cancelled"})}finally{l.close()}}else throw new d("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 l=await Y(c,"utf8"),p=JSON.parse(l);o=p.plan?.pricing?.scheduled?.pricingIdentity??p.pricing?.scheduled?.pricingIdentity??p.pricingIdentity}catch(l){throw new d(`Failed to read saved plan file ${c}: ${l.message}`)}}let r=await je(e,t,n,"required","compose apply"),s=await yt(r,n);if(s.pricing?.scheduled&&!o){if(!e["--yes"])throw new d(`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=s.pricing.scheduled.pricingIdentity}let i=e["--idempotency-key"]??globalThis.crypto.randomUUID(),a;try{a=await S(r.context,"/v1/products/recompose",T({program:{source:r.program.source},...r.catalogRevisionId?{catalogRevisionId:r.catalogRevisionId}:{},...o?{pricingIdentity:o}:{},tenantId:r.context.tenantId,productId:r.productId},i),r.context.token,[r.context.token])}catch(c){throw c instanceof v&&c.code==="product_instrument_not_drained"&&(c.fix=`Drain live instrument instances, or create a new Product directly from source: hyperscale product create --source ${n} --name <name>`),c}if(!a||typeof a.productBuildId!="string")throw new d("product.recompose returned no new build identity");if(e["--json"]){k({command:"product.recompose",file:n,output:a});return}if(u(`Product: ${a.productId??r.productId}`),u(`Build: ${a.productBuildId}`),a.buildDigest&&u(`Digest: ${a.buildDigest}`),a.pricing?.scheduled){let c=a.pricing.currency??"SAR",l=a.pricing.current?.monthly,p=a.pricing.scheduled?.monthly;u(`Current billing price: ${c} ${l}/mo`),u(`Accepted price from ${a.pricing.scheduled.effectiveAt}: ${c} ${p}/mo`)}}function gt(e,t){let n=t["--product"]??e.selectedProduct;return typeof n=="string"&&n.length>0?n:void 0}function F(e,t){let n=gt(e,t);if(!n)throw new d("No Product selected. Pass --product <id> or create a Product first.",{fix:'Run "hyperscale product list" to see existing Products, or "hyperscale product create" to create one.'});return n}async function ne(e,t){let n=await se(t),o=F(n??{},e),r=B(e,t,n??{});if(n&&(r.baseUrl!==n.baseUrl||r.environment!==n.environment))throw new d(`The selected Product belongs to ${n.baseUrl} (${n.environment}). Select a Product at the configured API origin first.`);let s=e["--api-key"]??t.HYPERSCALE_API_KEY;if(!s)throw et(o);return{...r,apiKey:s,productId:o}}async function wt(e,t){let n=`/v1/products/${encodeURIComponent(e.productId)}/operation-set`,{response:o,text:r}=await ue(e,n,{},t);if(!o.ok)throw bt(o,r,[e.apiKey],{productId:e.productId});return Ln(r,o.status)}async function _n(e,t,n){let o=await ne(e,t),r=await wt(o);if(n){Nn(r,n,e);return}if(e["--json"]){k(r);return}if(r.publicActions.length===0)u("No public actions");else{let s=P(process.stdout,t,{json:!1});u(C(s,{columns:["Operation ID","Input","Kind"],rows:r.publicActions.map(i=>{let a=i.idempotencyPolicy?.mode==="not_required"?"read-only":"mutation";return[`${i.instrument}.${i.name}`,Dn(i.inputSchema),a]})}))}if(r.setupOperations.length>0){u("Setup operations (run with hyperscale call)");for(let s of r.setupOperations)u(s.operationName)}if(r.readOperationIds.length>0){u("Reads (run with hyperscale call)");for(let s of r.readOperationIds)u(Hn(s))}u(`Digest: ${r.tenantOperationSetDigest}`),u(`Setup digest: ${r.tenantSetupOperationSetDigest}`),u(`Read digest: ${r.tenantReadOperationSetDigest}`),u(`Build: ${r.productBuildId}`),u(`Surface version: ${r.tenantSurfaceVersion}`)}function Nn(e,t,n){let o=e.publicActions.find(c=>c&&`${c.instrument}.${c.name}`===t),r=Un(t),s=e.setupOperations.find(c=>c&&(c.operationId===t||c.operationId===r||c.operationName===t));if(s){let{inputSchema:c,operationId:l,operationName:p}=s,f={status:e.status,productBuildId:e.productBuildId,tenantSurfaceVersion:e.tenantSurfaceVersion,tenantSetupOperationSetDigest:e.tenantSetupOperationSetDigest,setupOperationId:l,operationName:p,command:`hyperscale call ${p}`,inputSchema:c};if(n["--json"]){k(f);return}let m=P(process.stdout,n?process.env:{},{json:!1}),g=[["Operation ID",l],["Operation name",p],["Run",`hyperscale call ${p}`],["Input schema",JSON.stringify(c,null,2)]];(!Array.isArray(c.required)||c.required.length===0)&&g.push(["Input","omit --input or pass {}."]),g.push(["Setup digest",e.tenantSetupOperationSetDigest],["Build",e.productBuildId],["Surface version",e.tenantSurfaceVersion]),u(N(m,{fields:g}));return}if(!o)throw new d(`Unknown frozen public action: ${t}. Run "hyperscale product actions" to list exact names.`);let i={status:e.status,productBuildId:e.productBuildId,tenantSurfaceVersion:e.tenantSurfaceVersion,tenantOperationSetDigest:e.tenantOperationSetDigest,qualifiedName:`${o.instrument}.${o.name}`,publicAction:o};if(n["--json"]){k(i);return}let a=P(process.stdout,n?process.env:{},{json:!1});u(N(a,{fields:[["Operation ID",`${o.instrument}.${o.name}`],["Instrument",o.instrument],["Input schema",JSON.stringify(o.inputSchema,null,2)],["Output schema",JSON.stringify(o.outputSchema,null,2)],["Actor policy",JSON.stringify(o.actorPolicy,null,2)],["Port policy",JSON.stringify(o.portPolicy,null,2)],["Idempotency policy",JSON.stringify(o.idempotencyPolicy,null,2)],["Receipt policy",JSON.stringify(o.receiptPolicy,null,2)],["Receipt evidence",JSON.stringify(o.receiptEvidence,null,2)],["Digest",e.tenantOperationSetDigest],["Build",e.productBuildId],["Surface version",e.tenantSurfaceVersion]]}))}function Ln(e,t){let n;try{n=JSON.parse(e)}catch{throw new d(`HTTP ${t} returned invalid JSON`)}if(!n||typeof n!="object"||n.status!=="frozen"||typeof n.productBuildId!="string"||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 d("The Product operation set is not in the expected format.",{fix:'Run the latest unpinned CLI (e.g. "bunx @hyperscale0/cli@latest <command>"), or report the issue without including credentials.'});return n.publicActions=n.publicActions.map(o=>{if(!o||typeof o!="object"||typeof o.instrument!="string"||o.instrument.length===0||typeof o.name!="string"||o.name.length===0)throw new d("The server's public action names no instrument or action name. The platform predates Product identity in public actions: redeploy it.");return{...o,qualifiedName:`${o.instrument}.${o.name}`}}),n}function Un(e){return e.replaceAll(".","_")}function Hn(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 Dn(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,s])=>`${r}${n.has(r)?"":"?"}: ${It(s)}`);return o.length===0?"no input":o.join(", ")}function It(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"?`${It(e.items)}[]`:typeof e.type=="string"?typeof e.format=="string"?`${e.type} (${e.format})`:e.type:"value"}async function Kn(e,t,n){if(!n)throw new d("product run needs a public action");let o=await ne(e,t),r=await wt(o,n);Jn(r,n);let s=await kt(e),i=e["--idempotency-key"]??globalThis.crypto.randomUUID(),{response:a,text:c}=await ue(o,`/v1/operations/${encodeURIComponent(n)}`,{body:JSON.stringify(s),headers:{"content-type":"application/json","idempotency-key":i},method:"POST"},n);if(!a.ok)throw bt(a,c,[o.apiKey],{action:n,productId:o.productId});let l=a.headers.get("hyperscale-operation-id"),p=a.headers.get("hyperscale-receipt-id"),f=a.headers.get("x-request-id"),m=l?y(l,[o.apiKey]):null,g=p?y(p,[o.apiKey]):null,I=f?y(f,[o.apiKey]):null;if(e["--json"]){k({idempotencyKey:i,...I?{requestId:I}:{},operationId:m,receiptId:g,output:Bn(c)});return}m&&u(`Operation: ${m}`),g&&u(`Receipt: ${g}`),u(`Idempotency key: ${i}`);let h=Pt(c);h&&u(h)}function Jn(e,t){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:$e(t,r)})).sort((r,s)=>r.distance-s.distance||r.candidate.localeCompare(s.candidate)).slice(0,3).map(({candidate:r})=>r);throw new d(`Unknown frozen public action: ${t}. Closest valid names: ${o.join(", ")}. Run "hyperscale product actions" to list exact names.`)}function Bn(e){if(e.trim()==="")return null;try{return JSON.parse(e)}catch{return e}}function bt(e,t,n=[],o={}){let r=pt(t,n,e.status),s=lt(e.headers,r.requestId,n),i=r.code??"user_error",a=r.redactedMessage;if(typeof a=="string"&&a.includes("does not match API key Product")){let m=o.productId??a.match(/^Selected Product (\S+) does not match/)?.[1];m&&(a=`${a} Or set HYPERSCALE_API_KEY to a key for ${m}, or pass that key with --api-key.`)}let c=i==="user_error"?"":`${i}: `,l=`HTTP ${e.status} \xB7 ${c}${a}`,p=Mn(r.details,n),f=r.fix;return i==="idempotency_conflict"?f="Reuse the same key only with the same operation and input. Use a new unique key for a different request.":e.status===409&&typeof a=="string"&&a.includes("capability-derived")?f='This Product has no frozen public actions. List its operations with "hyperscale ops list" and run them with "hyperscale call".':[a,...p].some(m=>typeof m=="string"&&m.includes("[Truncated]"))&&o.action&&(f=`Run "hyperscale product actions ${o.action}" to read the full input schema and allowed values.`),new v([l,...p].join(`
47
+ `),{code:i,details:r.details,fix:f,operationId:s.operationId,receiptId:s.receiptId,requestId:s.requestId,status:e.status,traceId:s.traceId})}function Mn(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 s=(Array.isArray(o.path)?o.path.join("."):"input")||"input";return typeof o.message=="string"?[`${s}: ${y(o.message,t)}`]:[]});let n=[];return Pe(e,"",n,t),n}function Pe(e,t,n,o){if(Array.isArray(e)){if(e.every(r=>r===null||typeof r!="object")){n.push(`${ze(t)}: ${y(e.join(", "),o)}`);return}e.forEach((r,s)=>Pe(r,`${t}[${s}]`,n,o));return}if(e&&typeof e=="object"){for(let[r,s]of Object.entries(e))Pe(s,t?`${t}.${r}`:r,n,o);return}t&&n.push(`${ze(t)}: ${y(String(e),o)}`)}function ze(e){let t=e.replace(/([a-z0-9])([A-Z])/g,"$1 $2").replaceAll("."," ");return t.charAt(0).toUpperCase()+t.slice(1)}async function Yn(e,t){let n=await $(e,t),o=F(n,e),r=await S(n,"/v1/sandbox-api-keys",T({name:e["--name"]??"Founder CLI",tenantId:n.tenantId,productId:o}),n.token,[n.token]),s=["export HYPERSCALE_API_KEY=<paste the shown_once value>",`hyperscale product actions --product ${o}`];if(e["--json"]){let{secret:i,...a}=r;k({...a,...typeof i=="string"?{shown_once:i}:{},nextCommands:s});return}u(`Key: ${r.apiKeyId??"unknown"}`),u(`Product: ${r.productId??o}`),u(`Status: ${r.status??"unknown"}`),r.secret?(u(`Secret: ${r.secret}`),u("Store it now. Hyperscale will not return it again."),u("Next:"),u(" export HYPERSCALE_API_KEY=<paste the secret above>"),u(` hyperscale product actions --product ${o}`)):u("The key already existed, so the one-time secret is unavailable.")}async function qn(e,t){let n=await $(e,t),o=F(n,e),r=await L(n,"/v1/api-keys",{productId:o,tenantId:n.tenantId},"api_key.list",n.token,[n.token]),s=O(r,"api_key.list");if(e["--json"]){k(r);return}let i=P(process.stdout,t,{json:!1});u(C(i,{columns:["ID","Name","Status"],rows:s.map(a=>[a.apiKeyId,a.name??"unnamed",a.status??"unknown"])}))}async function Fn(e,t,n){if(!n)throw new d("key revoke needs an API key id",{fix:'Run "hyperscale key list" to list keys, then pass one ID.'});let o=await $(e,t),r=F(o,e),s=await S(o,`/v1/api-keys/${encodeURIComponent(n)}/revoke`,T({tenantId:o.tenantId,productId:r}),o.token,[o.token]);e["--json"]?k(s):u(`Key ${s.apiKeyId??n}: ${s.status??"revoked"}`)}async function Wn(e,t){let n=await $(e,t),o=n.identity??await j(n,n.token),r=Re(n,o);if(e["--json"]){k(r);return}let s=P(process.stdout,t,{json:!1});u(N(s,{fields:[["User",o.email],["Tenant",o.tenantId],["Role",o.role],["Token",o.name],["Expires",o.expiresAt]]}))}async function zn(e,t,n){let o=await ut(e),r=n?n.toLowerCase():null,s=r?o.operations.filter(a=>a.name.toLowerCase().includes(r)||a.path.toLowerCase().includes(r)):o.operations;if(t["--json"]){u(JSON.stringify(s,null,2));return}if(s.length===0){u(n?`No operation matches ${n}`:"No operations");return}let i=P(process.stdout,process.env,{json:!1});u(C(i,{columns:["Operation","Method","Path"],rows:s.map(a=>[a.name,a.method,a.path])}))}async function Vn(e,t){let n=await $(e,t),o=await L(n,"/v1/activity",{tenantId:n.tenantId},"activity.list",n.token,[n.token]),r=O(o,"activity.list");if(e["--json"]){k(o);return}let s=P(process.stdout,t,{json:!1});u(C(s,{columns:["Time","Activity","Target","Status"],rows:r.map(i=>{let a=i.operation??i.auditEvent??"activity",c=i.resourceKind&&i.resourceId?`${i.resourceKind}:${i.resourceId}`:i.resourceKind??i.resourceId??"-";return[i.occurredAt??"unknown",a,c,i.status??"recorded"]})}))}function Gn(e,t){let n={...t},o=[],r=e.path.replace(/\{([^}]+)\}/g,(s,i)=>{let a=n[i];return a==null?(o.push(i),""):(delete n[i],encodeURIComponent(String(a)))});if(o.length>0)throw new d(`${e.name} needs ${o.join(", ")} in --input`);return{path:r,remaining:n}}function Xn(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 $e(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 s=1;s<=t.length;s+=1)r[s]=Math.min(r[s-1]+1,n[s]+1,n[s-1]+(e[o-1]===t[s-1]?0:1));n.splice(0,n.length,...r)}return n[t.length]}function Zn(e,t){let n=e.find(s=>s.name===t);if(n)return n;let o=e.filter(s=>s.operationId===t);if(o.length===1)return o[0];if(o.length>1)throw new d(`${t} matches more than one operation. Use one of: ${o.map(s=>s.name).join(", ")}.`);let r=e.map(s=>({candidate:s,distance:Math.min($e(t,s.name),$e(t,s.operationId))})).sort((s,i)=>s.distance-i.distance||s.candidate.name.localeCompare(i.candidate.name)).slice(0,3).flatMap(({candidate:s})=>[s.name,s.operationId]);throw new d(`${t} is not an operation in the selected Product's machine document. Closest valid names: ${r.join(", ")}.`)}async function Qn(e,t,n){if(!n)throw new d("call needs an operation name",{fix:'Run "hyperscale ops list" to list operations.'});let o=await ut(e),r=Zn(o.operations,n),s=await kt(t),{path:i,remaining:a}=Gn(r,s),c={method:r.method},l=i;r.method==="GET"?l+=Xn(a):(c.body=JSON.stringify(a),c.headers={"content-type":"application/json",...r.idempotency==="not_required"?{}:{"idempotency-key":t["--idempotency-key"]??globalThis.crypto.randomUUID()}});let{response:p,text:f}=await ue(e,l,c);if(p.ok){if(t["--json"]){let m=nn(f),g=p.headers.get("x-request-id")??(m&&typeof m=="object"&&typeof m.requestId=="string"?m.requestId:null),I=p.headers.get("hyperscale-operation-id")??null,h=p.headers.get("hyperscale-receipt-id")??null,w=dt(p.headers),x=g?y(g,[e.apiKey]):null,R=I?y(I,[e.apiKey]):null,W=h?y(h,[e.apiKey]):null,_=w?y(w,[e.apiKey]):null;k({status:p.status,data:m,requestId:x,operationId:R,receiptId:W,traceId:_});return}u(Pt(f));return}throw de(p,f,[e.apiKey])}async function kt(e){if(e["--input"]!==void 0&&e["--input-file"]!==void 0)throw new d("Use only one of --input and --input-file");if(e["--input"]!==void 0)return ye(e["--input"],"--input");if(e["--input-file"]!==void 0){let t;try{t=await Y(e["--input-file"],"utf8")}catch(n){throw new d(`Could not read ${e["--input-file"]}: ${n.message}`)}return ye(t,"--input-file")}if(!process.stdin.isTTY){let t=await en();if(t.trim()!=="")return ye(t,"stdin")}return{}}function ye(e,t="--input"){if(e===void 0)return{};let n;try{n=JSON.parse(e)}catch(o){throw new d(`${t} is not valid JSON: ${o.message}`)}if(n===null||typeof n!="object"||Array.isArray(n))throw new d(`${t} must be a JSON object`);return n}function Pt(e){if(e.trim()==="")return"";try{return JSON.stringify(JSON.parse(e),null,2)}catch{return e}}function u(e){process.stdout.write(`${e}
48
+ `)}function k(e){u(JSON.stringify(e,null,2))}function eo(e,t){let n=t.includes("--json"),o=[process.env.HYPERSCALE_API_KEY,process.env.HYPERSCALE_TOKEN].filter(Boolean),r=e instanceof d,s=r?e.message:"The command failed unexpectedly.",i=b(y(String(s),o)),a=i.length>1024?i.slice(0,1024):i,c=r?e.fix??'Follow the message, or run "hyperscale --help" for command usage.':"Report the failure without including credentials.",l=b(y(String(c),o)),p=r&&typeof e.shownOnce=="string"?b(y(e.shownOnce,o)):void 0;if(!n){let A=P(process.stderr,process.env,{json:!1}),$t=(typeof e?.structuredError?.code=="string"?e.structuredError.code:void 0)??(r&&typeof e.code=="string"?e.code:r?"user_error":"internal_error"),xt=r?a:i,St=p?`
49
+ Shown once Product API key: ${p}`:"",At=Je(A,{code:$t,message:xt,nextStep:l});process.stderr.write(`${At}${St}
50
+ `);return}let f=(typeof e?.structuredError?.code=="string"?e.structuredError.code:void 0)??(r&&typeof e.code=="string"?e.code:r?"user_error":"internal_error"),m=(typeof e?.structuredError?.message=="string"?e.structuredError.message:void 0)??(r?e.message:"The command failed unexpectedly."),g=b(y(String(m),o)),I=g.length>1024?g.slice(0,1024):g,h=(typeof e?.structuredError?.fix=="string"?e.structuredError.fix:void 0)??(r?e.fix??'Follow the message, or run "hyperscale --help" for command usage.':"Report the failure without including credentials."),w=b(y(String(h),o)),x=w.length>1024?w.slice(0,1024):w,R=e?.structuredError?.details!==void 0?e.structuredError.details:r&&e.details!==void 0?e.details:void 0,W=R!==void 0?te(R,o):void 0,_=r&&typeof e.status=="number"?e.status:void 0,z=A=>typeof A!="string"||A.trim().length===0?null:b(y(A.trim(),o)),V=r&&(e.requestId!==void 0||e.operationId!==void 0||e.receiptId!==void 0||e.traceId!==void 0),G=V?z(e.requestId):void 0,X=V?z(e.operationId):void 0,Z=V?z(e.receiptId):void 0,Q=V?z(e.traceId):void 0,Oe=A=>({..._!==void 0?{status:_}:{},error:{code:f,message:I,...A!==void 0?{details:A}:{},fix:x},...G!==void 0?{requestId:G}:{},...X!==void 0?{operationId:X}:{},...Z!==void 0?{receiptId:Z}:{},...Q!==void 0?{traceId:Q}:{},...p?{shown_once:p}:{}}),_e=A=>Buffer.byteLength(A,"utf8")>8192,U=Oe(W),H=JSON.stringify(U);_e(H)&&W!==void 0&&(U=Oe("[Truncated]"),H=JSON.stringify(U)),_e(H)&&(U={..._!==void 0?{status:_}:{},error:{code:f,message:I,fix:"[Truncated]"},...G!==void 0?{requestId:G}:{},...X!==void 0?{operationId:X}:{},...Z!==void 0?{receiptId:Z}:{},...Q!==void 0?{traceId:Q}:{}},H=JSON.stringify(U)),process.stderr.write(`${H}
51
+ `)}async function to(){let{readFileSync:e}=await import("node:fs");return JSON.parse(e(new URL("./package.json",import.meta.url),"utf8")).version}async function no(e,t){let{flags:n,positional:o}=Ft(e);if(n["--version"])return u(await to()),0;if(n["--help"]&&o.length>0){let i=P(process.stdout,t,{json:!1});return u(Me(o,i)),0}if(o[0]==="help"){let i=o.slice(1),a=P(process.stdout,t,{json:!1});return i.length===0?u(le(a)):u(Me(i,a)),0}if(o.length===0&&!n["--help"]){if(n["--json"])throw new d('No command. Run "hyperscale --help" to list commands.');if(!await $(n,t,!0)){let a=P(process.stdout,t,{json:!1});return u(He(a)),0}return process.stdin.isTTY&&process.stderr.isTTY?(await We(n,t),0):(u('Build your first Product with "hyperscale start".'),u('Run "hyperscale --help" for every command.'),0)}if(n["--help"]){let i=P(process.stdout,t,{json:!1});return u(le(i)),0}let[r,...s]=o;if(r==="start")return await We(n,t),0;if(r==="auth"){if(s[0]==="login")await cn(n,t);else if(s[0]==="status")await un(n,t);else if(s[0]==="logout")await dn(n,t);else throw new d('Auth subcommands are "login", "status", and "logout"',{fix:'Run "hyperscale help auth" to see valid subcommands.'});return 0}if(r==="blueprint"){let i=B(n,t);if(s[0]==="list")await pn(i,n);else if(s[0]==="show")await mn(i,n,s[1]);else throw new d('Blueprint subcommands are "list" and "show"',{fix:'Run "hyperscale help blueprint" to see valid subcommands.'});return 0}if(r==="product"){if(s[0]==="create")await $n(n,t);else if(s[0]==="list")await xn(n,t);else if(s[0]==="show")await Sn(n,t,s[1]);else if(s[0]==="select")await En(n,t,s[1]);else if(s[0]==="actions")await _n(n,t,s[1]);else if(s[0]==="run")await Kn(n,t,s[1]);else throw new d('Product subcommands are "create", "list", "show", "select", "actions", and "run"',{fix:'Run "hyperscale help product" to see valid subcommands.'});return 0}if(r==="compose"){if(s[0]==="check")await vn(n,t,s[1]);else if(s[0]==="plan")await jn(n,t,s[1]);else if(s[0]==="apply")await On(n,t,s[1]);else throw new d('Compose subcommands are "check", "plan", and "apply"',{fix:'Run "hyperscale help compose" to see valid subcommands.'});return 0}if(r==="key"){if(s[0]==="create")await Yn(n,t);else if(s[0]==="list")await qn(n,t);else if(s[0]==="revoke")await Fn(n,t,s[1]);else throw new d('Key subcommands are "create", "list", and "revoke"',{fix:'Run "hyperscale help key" to see valid subcommands.'});return 0}if(r==="whoami")return await Wn(n,t),0;if(r==="activity"){if(s[0]!=="list")throw new d('The only activity subcommand is "list"',{fix:'Run "hyperscale help activity" to see usage.'});return await Vn(n,t),0}if(r==="ops"){if(s[0]!=="list")throw new d('The only ops subcommand is "list"',{fix:'Run "hyperscale help ops" to see usage.'});let i=n["--product"]?await ne(n,t):Ye(n,t);return await zn(i,n,s[1]),0}if(r==="call"){let i=n["--product"]?await ne(n,t):Ye(n,t);return await Qn(i,n,s[0]),0}throw new d(`Unknown command: ${r}`,{fix:'Run "hyperscale --help" to list commands.'})}no(process.argv.slice(2),process.env).then(e=>{process.exitCode=e},e=>{eo(e,process.argv.slice(2)),process.exitCode=e instanceof d&&Number.isInteger(e.exitCode)?e.exitCode:1});
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hyperscale0/cli",
3
- "version": "1.0.0-beta.23",
3
+ "version": "1.0.0-beta.24",
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": "7c00e694bad0797575b9ebb68f5815664476b7b6"
23
+ "gitHead": "31f3658701acad034dff6143b93abad18baa03a1"
24
24
  }