@hyperscale0/cli 1.0.0-beta.20 → 1.0.0-beta.21
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +3 -0
- package/hyperscale.js +39 -37
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -25,6 +25,7 @@ bunx @hyperscale0/cli whoami
|
|
|
25
25
|
bunx @hyperscale0/cli start --blueprint vehicle-escrow-marketplace --json
|
|
26
26
|
bunx @hyperscale0/cli blueprint list
|
|
27
27
|
bunx @hyperscale0/cli product create --blueprint luxury-goods-consignment-escrow --name "Luxury Consignment"
|
|
28
|
+
bunx @hyperscale0/cli product create --source product.hsx --name "Custom Escrow"
|
|
28
29
|
bunx @hyperscale0/cli product select <Product id>
|
|
29
30
|
bunx @hyperscale0/cli key create --name "Founder laptop"
|
|
30
31
|
bunx @hyperscale0/cli compose check product.hsx
|
|
@@ -46,6 +47,8 @@ bunx @hyperscale0/cli call account.list --input '{"limit":5}'
|
|
|
46
47
|
operation id such as `escrow_order.placeBuyerHold` to return its full input
|
|
47
48
|
schema, output schema, policies, build id, surface version, and operation-set
|
|
48
49
|
digest.
|
|
50
|
+
`product create` creates and selects a new Product with `--name <name>`
|
|
51
|
+
from either `--blueprint <slug>` or `--source <file.hsx>`.
|
|
49
52
|
`start` asks which catalog company to build in a terminal. Scripts and agents
|
|
50
53
|
pass `--blueprint <slug>` to skip the prompt. `product select <Product id>`
|
|
51
54
|
stores the default Product used by compose, key, and Product commands when
|
package/hyperscale.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import{spawn as
|
|
2
|
+
import{spawn as Ee}from"node:child_process";import{createHash as Qe}from"node:crypto";import{createServer as Ze}from"node:http";import{createInterface as et}from"node:readline/promises";import{chmod as Q,mkdir as tt,readdir as nt,readFile as U,rename as ot,unlink as rt,writeFile as it}from"node:fs/promises";import{homedir as at}from"node:os";import{basename as st,dirname as ne,join as q}from"node:path";var de="https://hyperscale0.ai",pe="sandbox",le="hyperscale-cli-session",ct="/v1/personal-access-tokens/current",oe=process.platform==="darwin"?"/usr/bin/security":null,ut="config.json",re="https://hyperscale0.ai/desk/security/tokens",_="https://hyperscale0.ai/request-access",N=`Mint a founder PAT in Hyperscale Portal at ${re}. Open Security, then Personal access tokens.`,dt=`Not logged in. Run "hyperscale auth login" to open Hyperscale Portal sign-in. In a headless environment, ${N} Then set HYPERSCALE_TOKEN or pass --token. Unapproved founders can request access at ${_}.`,pt=`Run "hyperscale auth login". For headless use, ${N} Unapproved founders can request access at ${_}.`,ie=3e4,lt=2e3,mt=120*1e3,ft=/^prd_(sandbox|live)_[a-z0-9]{8,64}$/,ht=`hyperscale <command> [options]
|
|
3
3
|
|
|
4
4
|
Commands:
|
|
5
5
|
start Create a Product and run its first published journey step
|
|
@@ -8,7 +8,7 @@ Commands:
|
|
|
8
8
|
auth logout [--revoke] Forget the local founder PAT, optionally revoke it
|
|
9
9
|
blueprint list List public Blueprints without authentication
|
|
10
10
|
blueprint show <id> Show one public Blueprint
|
|
11
|
-
product create Create a Product from a Blueprint
|
|
11
|
+
product create Create a Product from a Blueprint or HSX source
|
|
12
12
|
product list List Products in the signed-in company
|
|
13
13
|
product show [id] Show a Product (default: selected Product)
|
|
14
14
|
product select <id> Select the default Product for later commands
|
|
@@ -31,9 +31,10 @@ Options:
|
|
|
31
31
|
--revoke Revoke the active founder PAT during auth logout
|
|
32
32
|
--no-browser Skip browser login and print the founder PAT path
|
|
33
33
|
--api-key <key> Product API key (default: $HYPERSCALE_API_KEY)
|
|
34
|
-
--base-url <url> API origin (default: $HYPERSCALE_BASE_URL, else ${
|
|
35
|
-
--environment <name> sandbox or live (default: $HYPERSCALE_ENVIRONMENT, else ${
|
|
34
|
+
--base-url <url> API origin (default: $HYPERSCALE_BASE_URL, else ${de})
|
|
35
|
+
--environment <name> sandbox or live (default: $HYPERSCALE_ENVIRONMENT, else ${pe})
|
|
36
36
|
--blueprint <slug> Blueprint for non-interactive start or product create
|
|
37
|
+
--source <file> HSX source file for product create
|
|
37
38
|
--name <name> Product or key name
|
|
38
39
|
--product <id> Product id for key commands and Product-key actions
|
|
39
40
|
--catalog-revision <id> Tenant catalog revision for HSX composition
|
|
@@ -63,7 +64,7 @@ key. The explicit flag wins over its environment variable. Founder logins use
|
|
|
63
64
|
macOS Keychain when available. Set HYPERSCALE_CREDENTIAL_STORE=file to keep the
|
|
64
65
|
founder PAT in the owner-only CLI profile instead and skip Keychain access.
|
|
65
66
|
|
|
66
|
-
${
|
|
67
|
+
${N}
|
|
67
68
|
Request access at ${_}.
|
|
68
69
|
|
|
69
70
|
Examples:
|
|
@@ -74,6 +75,7 @@ Examples:
|
|
|
74
75
|
hyperscale auth login --token hyperscale_pat_...
|
|
75
76
|
hyperscale blueprint list
|
|
76
77
|
hyperscale product create --blueprint luxury-goods-consignment-escrow --name "Luxury Consignment"
|
|
78
|
+
hyperscale product create --source company.hsx --name "Company"
|
|
77
79
|
hyperscale key create --name "Founder laptop"
|
|
78
80
|
hyperscale product actions
|
|
79
81
|
hyperscale product actions escrow_order.placeBuyerHold --json
|
|
@@ -87,40 +89,40 @@ Examples:
|
|
|
87
89
|
hyperscale call account.list --input-file input.json
|
|
88
90
|
printf '{"limit":5}' | hyperscale call account.list
|
|
89
91
|
hyperscale call account.retrieve --input '{"accountId":"acct_sandbox_..."}'
|
|
90
|
-
`,$e={start:{usage:"start [--blueprint <slug>] [--name <name>] [--json]",summary:"Choose a catalog company, create its Product, and run its first published runnable journey 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 journey 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 the portal callback. Print where to mint a PAT when no token is set.","--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.","Headless environments should pass --no-browser and set HYPERSCALE_TOKEN or --token to a portal-minted founder 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> --name <name> [--json]",summary:"Create and select a Product. The command refuses a duplicate name.",options:["--blueprint <id> Required Blueprint id.","--name <name> Required Product name.","--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 a Product from checked HSX.",options:["--confirm Confirm the mutation for a person, who must also name the candidate price they reviewed.","--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.","--plan-file <path> Saved JSON plan file from compose plan --json.","--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."],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:["--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."],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"}'`}};function lt(e){let n=Object.keys($e).sort((r,i)=>i.split(" ").length-r.split(" ").length).find(r=>r.split(" ").every((s,c)=>e[c]===s));if(!n)throw new u(`No help for ${e.join(" ")}. Run "hyperscale --help" to list commands.`);let o=$e[n];return[`Usage: hyperscale ${o.usage}`,"",o.summary,"","Options:",...o.options.map(r=>` ${r}`),...o.notes?["","Notes:",...o.notes.map(r=>` ${r}`)]:[],"","Example:",` ${o.example}`,""].join(`
|
|
91
|
-
`)}var u=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)}},
|
|
92
|
-
`)}function H(e){return
|
|
93
|
-
`)})}async function
|
|
94
|
-
`),"file"}async function
|
|
95
|
-
`),{keychainDeleted:!0};if(
|
|
96
|
-
`),{keychainDeleted:!1};let o=await
|
|
97
|
-
`),{keychainDeleted:!1}):(await
|
|
98
|
-
\r`.includes(t)?t:"")}function
|
|
99
|
-
`),
|
|
92
|
+
`,$e={start:{usage:"start [--blueprint <slug>] [--name <name>] [--json]",summary:"Choose a catalog company, create its Product, and run its first published runnable journey 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 journey 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 the portal callback. Print where to mint a PAT when no token is set.","--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.","Headless environments should pass --no-browser and set HYPERSCALE_TOKEN or --token to a portal-minted founder 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 to compose from.","--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 a Product from checked HSX.",options:["--confirm Confirm the mutation for a person, who must also name the candidate price they reviewed.","--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.","--plan-file <path> Saved JSON plan file from compose plan --json.","--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."],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:["--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."],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"}'`}};function yt(e){let n=Object.keys($e).sort((r,i)=>i.split(" ").length-r.split(" ").length).find(r=>r.split(" ").every((a,c)=>e[c]===a));if(!n)throw new u(`No help for ${e.join(" ")}. Run "hyperscale --help" to list commands.`);let o=$e[n];return[`Usage: hyperscale ${o.usage}`,"",o.summary,"","Options:",...o.options.map(r=>` ${r}`),...o.notes?["","Notes:",...o.notes.map(r=>` ${r}`)]:[],"","Example:",` ${o.example}`,""].join(`
|
|
93
|
+
`)}var u=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)}},T=class extends u{constructor(t,{requestId:n,status:o,code:r,details:i,operationId:a,receiptId:c,traceId:d,structuredError:p}={}){super(t,{code:r,details:i}),this.requestId=n,this.status=o,this.operationId=a??null,this.receiptId=c??null,this.traceId=d??null,this.structuredError=p}};function Z(){return new u(dt,{fix:pt})}function ve(e){let t=e??"<id>";return new u(`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.`)}var J=class extends u{constructor(t,n){super(t),this.code="check_failed",this.details=n,this.exitCode=2}},Ce=new Set(["--api-key","--base-url","--blueprint","--catalog-revision","--environment","--idempotency-key","--input","--input-file","--name","--plan-file","--pricing-identity","--product","--source","--token"]);function wt(e){let t=[],n={};for(let o=0;o<e.length;o+=1){let r=e[o];if(!r.startsWith("--")){t.push(r);continue}if(Ce.has(r)){let i=e[o+1];if(i===void 0)throw new u(`${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==="--passkey"||r==="--revoke"){n[r]=!0;continue}throw new u(`Unknown option: ${r}`)}return{flags:n,positional:t}}function ke(e,t){let n=e["--api-key"]??t.HYPERSCALE_API_KEY;if(!n)throw ve();let o=e["--environment"]??t.HYPERSCALE_ENVIRONMENT??pe;if(o!=="sandbox"&&o!=="live")throw new u(`Unknown environment: ${o}. Use sandbox or live.`);let r=(e["--base-url"]??t.HYPERSCALE_BASE_URL??de).replace(/\/+$/,"");return{apiKey:n,baseUrl:r,environment:o}}function j(e,t,n={}){let o=e["--environment"]??t.HYPERSCALE_ENVIRONMENT??n.environment??pe;if(o!=="sandbox"&&o!=="live")throw new u(`Unknown environment: ${o}. Use sandbox or live.`);let r=(e["--base-url"]??t.HYPERSCALE_BASE_URL??n.baseUrl??de).replace(/\/+$/,"");return he(r),{baseUrl:r,environment:o}}function Oe(e){return e.HYPERSCALE_CONFIG_DIR??q(at(),".config","hyperscale")}function Re(e){return q(Oe(e),ut)}function A(e,t){return q(Oe(t),`session-${H(e)}.json`)}function F(e){let t=e.HYPERSCALE_CREDENTIAL_STORE??"auto";if(t==="auto"||t==="file")return t;throw new u(`Unknown HYPERSCALE_CREDENTIAL_STORE value: ${t}. Use auto or file.`)}async function me(e,t){let n=A(e,t),o=`${st(n)}.`,r;try{r=await nt(ne(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 a=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(a)&&await L(q(ne(n),i.name))}}async function gt(e){try{return JSON.parse(await U(e,"utf8"))}catch(t){if(t&&t.code==="ENOENT")return null;throw t instanceof SyntaxError?new u(`${e} is not valid JSON`):t}}async function R(e,t){let n=It(e);await tt(n,{mode:448,recursive:!0}),await Q(n,448);let o=`${e}.${process.pid}.${globalThis.crypto.randomUUID()}.tmp`;await it(o,t,{flag:"wx",mode:384}),await Q(o,384);try{await ot(o,e),await Q(e,384)}catch(r){throw await L(o),r}}function It(e){return ne(e)}async function L(e){try{await rt(e)}catch(t){if(!t||t.code!=="ENOENT")throw t}}function $t(e,t){if(!e||typeof e!="object"||Array.isArray(e))throw new u(`${t} does not contain a CLI profile`);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 u(`${t} does not contain a valid CLI profile`);return{baseUrl:n,email:o,environment:r,selectedProduct:i}}async function M(e){let t=Re(e),n=await gt(t);return n===null?null:$t(n,t)}async function z(e,t){let n={email:t.email,baseUrl:t.baseUrl,environment:t.environment,selectedProduct:t.selectedProduct??null};await R(Re(e),`${JSON.stringify(n,null,2)}
|
|
94
|
+
`)}function H(e){return Qe("sha256").update(`${e.baseUrl}\0${e.environment}\0${e.email}`).digest("hex")}async function W(e,t){return oe===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=Ee(oe,e,{env:o,stdio:["pipe","pipe","pipe"]}),i=[],a=!1,c=p=>{a||(a=!0,clearTimeout(d),n(p))},d=setTimeout(()=>{r.kill("SIGKILL"),c({error:null,status:null,stdout:"",unavailable:!0})},lt);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}
|
|
95
|
+
`)})}async function fe(){return(await W(["show-keychain-info"])).status===0}function _e(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 kt(e,t,n){await me(e,n);let o=H(e);if(F(n)==="auto"&&await fe()){let r=JSON.stringify(t),i=["add-generic-password","-a",o,"-s",le,"-U","-X",Buffer.from(r,"utf8").toString("hex")].join(" ");if((await W(["-i"],i)).status===0)return await L(A(e,n)),"keychain"}return await R(A(e,n),`${JSON.stringify({account:o,activeStore:"file",credential:t})}
|
|
96
|
+
`),"file"}async function Pt(e,t){let n=H(e);try{let o=JSON.parse(await U(A(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=_e(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 Ne(e,t){await me(e,t);let n=F(t),o=await Pt(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 fe()){let i=await W(["find-generic-password","-a",H(e),"-s",le,"-w"]);i.status===0&&(r=_e(i.stdout.trim()))}return r||(o.state==="valid"?o.credential:null)}async function je(e,t){await me(e,t);let n=H(e);if(F(t)==="file")return await R(A(e,t),`${JSON.stringify({account:n,revoked:!0})}
|
|
97
|
+
`),{keychainDeleted:!0};if(oe===null)return await L(A(e,t)),{keychainDeleted:!0};if(!await fe())return await R(A(e,t),`${JSON.stringify({account:n,revoked:!0})}
|
|
98
|
+
`),{keychainDeleted:!1};let o=await W(["delete-generic-password","-a",n,"-s",le]);return o.status!==0&&o.status!==44?(await R(A(e,t),`${JSON.stringify({account:n,revoked:!0})}
|
|
99
|
+
`),{keychainDeleted:!1}):(await L(A(e,t)),{keychainDeleted:!0})}function Le(e,t){return e["--token"]!==void 0?e["--token"]:t.HYPERSCALE_TOKEN||void 0}async function k(e,t,n=!1){let o=await M(t),r=Le(e,t);if(r!==void 0){if(!r)throw Z();let c=j(e,t,o??{}),d=await E(c,r),p=o?.baseUrl===c.baseUrl&&o.environment===c.environment&&o.email===d.email;return{...c,email:d.email,identity:d,personalAccessTokenId:d.personalAccessTokenId,selectedProduct:p?o.selectedProduct:null,tenantId:d.tenantId,token:r,tokenName:d.name}}if(!o){if(n)return null;throw Z()}let i=j(e,t,o);if(i.baseUrl!==o.baseUrl||i.environment!==o.environment)throw new u(`The active founder login belongs to ${o.baseUrl} (${o.environment}). Log in again to change it.`);let a=await Ne(o,t);if(!a){if(n)return null;throw Z()}return{...o,...a}}function K(e){return e.replace(new RegExp("\\p{Cc}","gu"),t=>`
|
|
100
|
+
\r`.includes(t)?t:"")}function Ue(e){try{return new URL(e).origin}catch{return null}}function he(e){let t;try{t=new URL(e)}catch{t=null}if(!t||t.origin!==e)throw new u(`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 u(`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 bt=/(?<![A-Za-z0-9_-])(?:hyperscale|arc)_[A-Za-z0-9_-]{32,}(?![A-Za-z0-9_-])/g,St=/(?<![A-Za-z0-9_-])whsec_[A-Za-z0-9+/=]{32,}(?![A-Za-z0-9+/=])/g;function w(e,t=[]){let n=e;for(let o of t)typeof o=="string"&&o.length>0&&(n=n.replaceAll(o,"[redacted]"));return n.replaceAll(bt,"[redacted]").replaceAll(St,"[redacted]")}function He(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?w(n,t):null,a=o?w(o,t):null,c=r?w(r,t):null;i&&process.stderr.write(`Request id: ${i}
|
|
101
|
+
`),a&&process.stderr.write(`Operation: ${a}
|
|
100
102
|
`),c&&process.stderr.write(`Receipt: ${c}
|
|
101
|
-
`)}async function
|
|
102
|
-
Request id: ${c}`:""}`,{code:o.code,details:o.details,operationId:d,receiptId:p,requestId:c,status:e.status,structuredError:o.structuredError,traceId:
|
|
103
|
-
`);return}if(o){
|
|
104
|
-
`);return}if(
|
|
105
|
-
`);return}if(
|
|
106
|
-
`),r.reject(new u("Portal login was declined. Run hyperscale auth login to start again.",{code:"auth_callback_denied"}));return}let
|
|
107
|
-
`);return}o=!0,
|
|
108
|
-
`),r.resolve({grant:
|
|
109
|
-
`);let
|
|
110
|
-
`)}let d=ye(
|
|
111
|
-
`)}function v(e,t){if(!e||typeof e!="object"||!Array.isArray(e.items))throw new u(`${t} returned an invalid collection`);return e.items}async function C(e,t,n,o,r,i=[]){let
|
|
112
|
-
${
|
|
113
|
-
${
|
|
103
|
+
`)}async function V(e,t,n={},o){let r=`${e.baseUrl}${t}`,i=he(e.baseUrl);if(Ue(r)!==i)throw new u(`The requested path ${t} leaves the ${i} origin; refusing the request.`);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)throw new u(`${r} redirected, so no credential was sent on. Point --base-url at the origin the API answers on.`);return He(a,[o].filter(Boolean)),{response:a,text:K(await a.text())}}catch(a){throw a instanceof u?a:new u(`Could not reach ${r}: ${a.message}`)}}async function b(e,t,n={},o,r=[]){let{response:i,text:a}=await V(e,t,n,o);if(!i.ok)throw X(i,a,r);try{return JSON.parse(a)}catch{throw new u(`HTTP ${i.status} returned invalid JSON`)}}function x(e,t=globalThis.crypto.randomUUID()){return{body:JSON.stringify(e),headers:{"content-type":"application/json","idempotency-key":t},method:"POST"}}async function At(){let e=[];for await(let t of process.stdin)e.push(Buffer.from(t));return Buffer.concat(e).toString("utf8")}async function G(e,t,n={},o){let r=`${e.baseUrl}${t}`,i=he(e.baseUrl);if(Ue(r)!==i)throw new u(`The product document puts ${t} on another origin than the ${i} you configured; refusing to send the key there.`);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)throw new u(`${r} 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://.`);return He(a,[e.apiKey].filter(Boolean)),{response:a,text:K(await a.text())}}catch(a){throw a instanceof u?a:o&&(a?.name==="TimeoutError"||a?.name==="AbortError")?new u(`product run ${o} timed out after ${ie/1e3} seconds.`):new u(`Could not reach ${r}: ${a.message}`)}}async function De(e){let{response:t,text:n}=await G(e,"/v1/product.json");if(!t.ok)throw X(t,n,[e.apiKey]);let o=xt(n);if(!o)throw new u("The product document is not in the expected format; upgrade the CLI.");if(e.productId&&o.productId===void 0)throw new u(`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 u(`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 u(`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 xt(e){let t;try{t=JSON.parse(e)}catch{return null}let n=ae(t),o=r=>typeof r=="string";if(!O(n)||n.schemaVersion!==1||!(n.productId===void 0||o(n.productId))||!o(n.title)||!O(n.composition)||!o(n.composition.id)||!Array.isArray(n.operations))return null;for(let r of n.operations)if(!O(r)||!o(r.method)||!o(r.path)||!o(r.name)||!o(r.operationId)||!o(r.idempotency))return null;return n.sdk!==void 0&&(!O(n.sdk)||!o(n.sdk.packageName))?null:n}function O(e){return typeof e=="object"&&e!==null&&!Array.isArray(e)}function ae(e){return typeof e=="string"?K(e):Array.isArray(e)?e.map(ae):O(e)?Object.fromEntries(Object.entries(e).map(([t,n])=>[K(t),ae(n)])):e}function Je(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 Tt(e){if(!e||e.trim()==="")return null;try{return JSON.parse(e)}catch{return e}}var Pe=200;function se(e,t=[]){let n=w(e,t).replace(/\s+/g," ").trim(),o="The server did not return a Hyperscale error payload. Check that --base-url names the Hyperscale API and not a proxy, a login page, or the wrong host.";if(!n)return`${o} The body was empty.`;let r=n.length>Pe?`${n.slice(0,Pe)}\u2026 (${n.length} characters in all)`:n;return`${o} The body began: ${r}`}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,i=typeof r?.code=="string"?r.code:void 0,a=typeof r?.fix=="string"?r.fix:void 0,c=typeof r?.message=="string"?r.message:se(e,t),d=w(c,t),p=i&&typeof r?.message=="string"?`${i}: ${d}`:d,l=r?.details!==void 0?Y(r.details,t):void 0,h=o&&typeof o=="object"&&typeof o.requestId=="string"?o.requestId:void 0,m=n?`HTTP ${n}`:"HTTP error";return{code:i,details:l,fix:a,humanMessage:p,redactedMessage:d,requestId:h,structuredError:{code:i??"http_error",message:d||m,...l!==void 0?{details:l}:{},...a!==void 0?{fix:a}:{}}}}function X(e,t,n=[]){let o=Et(t,n,e.status),r=e.headers.get("x-request-id")??o.requestId??null,i=e.headers.get("hyperscale-operation-id")??null,a=e.headers.get("hyperscale-receipt-id")??null,c=r?w(r,n):null,d=i?w(i,n):null,p=a?w(a,n):null,l=Je(e.headers),h=o.humanMessage;return new T(`HTTP ${e.status}${h?` \xB7 ${h}`:""}${c?`
|
|
104
|
+
Request id: ${c}`:""}`,{code:o.code,details:o.details,fix:o.fix,operationId:d,receiptId:p,requestId:c,status:e.status,structuredError:o.structuredError,traceId:l})}function ye(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 vt(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 u("personal_access_token.current returned invalid data");return e}async function E(e,t){try{return vt(await b(e,ct,{},t,[t]))}catch(n){throw!(n instanceof T)||n.status!==401?n:new u(`That founder PAT was not accepted (HTTP 401). ${N}${n.requestId?` Request id: ${n.requestId}.`:""}`,{code:"founder_pat_rejected",fix:N})}}function Ct(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 Ot(e,t){let n=Ct(e,t);return n?new Promise(o=>{let r=Ee(n.command,n.args,{detached:!0,stdio:"ignore"});r.once("error",()=>o(!1)),r.once("spawn",()=>{r.unref(),o(!0)})}):!1}function ee(e){return new Promise(t=>{if(!e.listening){t();return}e.close(()=>t())})}async function Rt(e,t){let n=globalThis.crypto.randomUUID(),o=!1,r,i=new Promise((y,f)=>{r={reject:f,resolve:y}}),a=Ze((y,f)=>{let $=new URL(y.url??"/","http://127.0.0.1");if(y.method!=="GET"||$.pathname!=="/callback"){f.writeHead(404,{"content-type":"text/plain; charset=utf-8"}),f.end(`Not found.
|
|
105
|
+
`);return}if(o){f.writeHead(409,{"content-type":"text/plain; charset=utf-8"}),f.end(`Login callback was already received.
|
|
106
|
+
`);return}if($.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.
|
|
107
|
+
`);return}if($.searchParams.get("error")!==null){o=!0,f.writeHead(200,{"content-type":"text/plain; charset=utf-8"}),f.end(`Login declined. Return to the terminal.
|
|
108
|
+
`),r.reject(new u("Portal login was declined. Run hyperscale auth login to start again.",{code:"auth_callback_denied"}));return}let P=$.searchParams.get("grant"),S=$.searchParams.get("tenantId");if(!P||!S){f.writeHead(400,{"content-type":"text/plain; charset=utf-8"}),f.end(`Login callback is missing its grant or tenant.
|
|
109
|
+
`);return}o=!0,f.writeHead(200,{"content-type":"text/plain; charset=utf-8"}),f.end(`Login received. Return to the terminal.
|
|
110
|
+
`),r.resolve({grant:P,tenantId:S})});await new Promise((y,f)=>{let $=P=>f(P);a.once("error",$),a.listen(0,"127.0.0.1",()=>{a.off("error",$),y()})}),a.once("error",y=>r.reject(y));let c=a.address();if(!c||typeof c=="string")throw await ee(a),new u("Could not bind the localhost login callback");let d=`http://127.0.0.1:${c.port}/callback`,p=new URL("/auth/cli",e.baseUrl);p.searchParams.set("callback",d),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 Ot(t,h))return await ee(a),null;process.stderr.write(`Opening portal sign-in: ${h}
|
|
111
|
+
`);let I=setTimeout(()=>{r.reject(new u("Portal login timed out. Run hyperscale auth login to start a new callback.",{code:"auth_callback_timeout"}))},mt);try{return await i}finally{clearTimeout(I),await ee(a)}}function be(e){let t={authenticated:!1,browserOpened:!1,next:["export HYPERSCALE_TOKEN=hyperscale_pat_...","hyperscale auth login --no-browser"],patMintUrl:re,requestAccessUrl:_};if(e["--json"]){g(t);return}s("No browser detected. Mint a founder PAT in the portal, then run:");for(let n of t.next)s(` ${n}`);s(`PAT desk: ${re}`),s(`No access yet: ${_}`)}async function Se(e,t,n,o,r){let i=await M(r),a={email:t.email,...e,selectedProduct:i&&i.email===t.email&&i.baseUrl===e.baseUrl&&i.environment===e.environment?i.selectedProduct:null},c=await kt(a,{personalAccessTokenId:t.personalAccessTokenId,token:n,tokenName:t.name,tenantId:t.tenantId},r);try{await z(r,a)}catch(p){throw await je(a,r),p}if(c==="file"){let p=F(r)==="file"?"Founder PAT file storage is active.":"macOS Keychain is unavailable.";process.stderr.write(`${p} The founder PAT is in ${A(a,r)} with mode 0600.
|
|
112
|
+
`)}let d=ye(a,t);o["--json"]?g(d):s(`Logged in as ${t.email} with PAT ${t.name}.`)}async function _t(e,t){let n=j(e,t),o=Le(e,t);if(o){if(!o.startsWith("hyperscale_pat_"))throw new u("Founder PATs start with hyperscale_pat_. Product API keys belong in HYPERSCALE_API_KEY.");let d=await E(n,o);await Se(n,d,o,e,t);return}if(e["--no-browser"]){be(e);return}let r=await Rt(n,t);if(!r){be(e);return}let i=await b(n,"/v1/personal-access-token-login-grants/exchange",x({tenantId:r.tenantId,grant:r.grant}),void 0,[r.grant]),a=i?.secret;if(typeof a!="string"||!a.startsWith("hyperscale_pat_")||i?.tenantId!==r.tenantId)throw new u("CLI login grant exchange returned an invalid PAT");let c=await E(n,a);await Se(n,c,a,e,t)}async function Nt(e,t){let n=await k(e,t),o=n.identity??await E(n,n.token),r=ye(n,o);if(e["--json"]){g(r);return}s(`User: ${o.email}`),s(`Tenant: ${o.tenantId}`),s(`Role: ${o.role}`),s(`Token: ${o.name}`),s(`Scopes: ${o.scopes.join(", ")}`),s(`Expires: ${o.expiresAt}`),s(`API: ${n.baseUrl}`),s(`Environment: ${n.environment}`),s(`Product: ${n.selectedProduct??"not selected"}`)}async function jt(e,t){let n=await M(t);if(!n){e["--json"]?g({status:"signed_out"}):s("Already logged out.");return}let o=await Ne(n,t);if(e["--revoke"]&&!o)throw new u("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 d=await E(n,o.token);r=d.personalAccessTokenId,i=d.name}await b(n,`/v1/personal-access-tokens/${encodeURIComponent(r)}/revoke`,x({tenantId:o.tenantId,personalAccessTokenId:r}),o.token,[o.token])}let a=await je(n,t),c=e["--revoke"]===!0;Lt(e,{cleanup:a,personalAccessTokenId:r,revoked:c,status:"signed_out",tokenName:i})}function Lt(e,t){let n=t.cleanup.keychainDeleted?"complete":"tombstoned";if(e["--json"])g({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?s(`Revoked founder PAT ${o} and forgot local state.`):(s(`Forgot local founder PAT ${o}.`),s("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.
|
|
113
|
+
`)}function v(e,t){if(!e||typeof e!="object"||!Array.isArray(e.items))throw new u(`${t} returned an invalid collection`);return e.items}async function C(e,t,n,o,r,i=[]){let a=[],c=new Set,d,p;for(;;){let I=new URLSearchParams(n);d&&I.set("cursor",d);let y=I.size>0?`?${I}`:"",f=await b(e,`${t}${y}`,{},r,i);p===void 0&&(p=f),a.push(...v(f,o));let $=f.nextCursor;if(typeof $!="string"||$.length===0)break;if(c.has($))throw new u(`${o} repeated cursor ${$}`);c.add($),d=$}let{items:l,nextCursor:h,...m}=p;return{...m,items:a}}async function Ut(e,t){let n=await C(e,"/v1/blueprints",{},"blueprint.list"),o=v(n,"blueprint.list");if(t["--json"]){g(n);return}s("ID Name Summary");for(let r of o)s(`${r.id} ${r.name}${r.summary?` ${r.summary}`:""}`);s("Next:"),s(" hyperscale blueprint show <id>"),s(" hyperscale product create --blueprint <id> --name <name>")}async function Ht(e,t,n){if(!n)throw new u("blueprint show needs a Blueprint id");let o=await b(e,`/v1/blueprints/${encodeURIComponent(n)}`),r=Jt(o,e.baseUrl);if(t["--json"]){g(r);return}s(`${r.name} (${r.id})`),s(r.summary),s(r.description),s("Nouns:");for(let i of r.customInstruments??[])s(` ${i.name} (${i.id}): ${i.summary}`);for(let i of r.instruments??[])s(` ${i.title} (${i.id}): ${i.summary}`);s("Verbs:");for(let i of r.verbs??[])s(` ${i.alias} -> ${i.operation}: ${i.summary}`);s("Parties:");for(let i of r.parties??[])s(` ${i.instrumentId}.${i.role} -> ${i.accountField}`);s("Money flows:");for(let i of r.moneyFlows??[]){let a=i.sourceAccount??"action input",c=i.destinationAccount??"action input",d=i.amountPath??"action input";s(` ${i.action} [${i.kind}]: ${a} -> ${c}; amount ${d}`)}s("Fee forms:");for(let i of r.feeForms??[]){let a=i.bps?`${i.bps} bps`:i.amountSar?`SAR ${i.amountSar}`:i.includedQuantity?`${i.includedQuantity} included`:i.kind;s(` ${i.id}: ${a} per ${i.unit}. ${i.summary}`)}r.priceEstimate&&(s("Price estimate:"),s(` monthlySar: SAR ${Number(r.priceEstimate.monthlySar).toLocaleString("en-US")}`),s(` setupSar: SAR ${Number(r.priceEstimate.setupSar).toLocaleString("en-US")}`),s(` complexityScore: ${r.priceEstimate.complexityScore}`)),s("Dials:");for(let i of r.dials??[])s(` ${i.instrumentId}.${i.key} (${i.kind}): ${i.summary}`);s("Journeys:");for(let i of r.journeys??[])s(` ${i.title} (${i.id}): ${i.summary}`),(i.steps??[]).forEach((a,c)=>{s(` ${c+1}. ${Dt(a)}`)});r.hsxStructured&&(s("HSX:"),s(` Source:
|
|
114
|
+
${Ae(r.hsxStructured.source," ")}`),r.hsxStructured.document&&s(` Structured document:
|
|
115
|
+
${Ae(JSON.stringify(r.hsxStructured.document,null,2)," ")}`)),s("Terms:");for(let[i,a]of Object.entries(r.terminology))s(` ${i}: ${a.definition}`),s(` ${a.href}`);s("Next:"),s(` hyperscale product create --blueprint ${r.id} --name <name>`)}function Dt(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 Jt(e,t){let n=Kt(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 Kt(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 Ae(e,t){return e.split(`
|
|
114
116
|
`).map(n=>`${t}${n}`).join(`
|
|
115
|
-
`)}function we(e,t=[]){let n=e.headers.get("hyperscale-operation-id"),o=e.headers.get("hyperscale-receipt-id"),r=n?
|
|
116
|
-
`);for(let[
|
|
117
|
-
`)}let i=
|
|
118
|
-
`),{file:n,issues:p.issues,...d});return{check:p,receipt:d,context:i,productId:
|
|
119
|
-
`),{actions:i,file:t,...r,...e.productId?{productId:e.productId}:{}});return{...o,...r}}async function Xt(e,t,n){let o=await Ie(e,t,n,"optional"),r=await Je(o,n);if(e["--json"]){w({command:"composer.plan",file:n,check:{...o.check,...o.receipt},plan:r,...o.productId?{productId:o.productId}:{}});return}a(r.summary);for(let i of r.actions)a(`${i.kind} ${i.target} ${i.detail}`);r.pricing?.scheduled?(a(`Current billing price: SAR ${r.pricing.current.monthlySar}/mo`),a(`Candidate price from ${r.pricing.scheduled.effectiveAt}: SAR ${r.pricing.scheduled.monthlySar}/mo`),a(`Pricing identity: ${r.pricing.scheduled.pricingIdentity}`)):(a(`Monthly: SAR ${r.pricing.monthlySar}`),a(`Activation: SAR ${r.pricing.activationSar}`))}async function Qt(e,t,n){if(!e["--confirm"]&&!e["--yes"])throw new u("compose apply changes the selected Product. Pass --confirm, or --yes for an agent.");let o=e["--pricing-identity"];if(!o&&e["--plan-file"]){let c=e["--plan-file"];try{let d=await D(c,"utf8"),p=JSON.parse(d);o=p.plan?.pricing?.scheduled?.pricingIdentity??p.pricing?.scheduled?.pricingIdentity??p.pricingIdentity}catch(d){throw new u(`Failed to read saved plan file ${c}: ${d.message}`)}}let r=await Ie(e,t,n,"required"),i=await Je(r,n);if(i.pricing?.scheduled&&!o){if(!e["--yes"])throw new u(`compose apply --confirm requires --pricing-identity (or --plan-file). Run "hyperscale compose plan ${n}" to review candidate pricing and copy the pricing identity, or pass --yes to accept the current candidate.`);o=i.pricing.scheduled.pricingIdentity}let s=await P(r.context,"/v1/products/recompose",x({program:{source:r.program.source},...r.catalogRevisionId?{catalogRevisionId:r.catalogRevisionId}:{},...o?{pricingIdentity:o}:{},tenantId:r.context.tenantId,productId:r.productId},e["--idempotency-key"]),r.context.token,[r.context.token]);if(!s||typeof s.productBuildId!="string")throw new u("product.recompose returned no new build identity");if(e["--json"]){w({command:"product.recompose",file:n,output:s});return}a(`Product: ${s.productId??r.productId}`),a(`Build: ${s.productBuildId}`),s.buildDigest&&a(`Digest: ${s.buildDigest}`),s.pricing?.scheduled&&(a(`Current billing price: SAR ${s.pricing.current.monthlySar}/mo`),a(`Accepted price from ${s.pricing.scheduled.effectiveAt}: SAR ${s.pricing.scheduled.monthlySar}/mo`))}function Ke(e,t){let n=t["--product"]??e.selectedProduct;return typeof n=="string"&&n.length>0?n:void 0}function J(e,t){let n=Ke(e,t);if(!n)throw new u("No Product selected. Pass --product <id> or create a Product first.");return n}async function Y(e,t){let n=await W(t),o=J(n??{},e),r=L(e,t,n??{});if(n&&(r.baseUrl!==n.baseUrl||r.environment!==n.environment))throw new u(`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 Ee(o);return{...r,apiKey:i,productId:o}}async function Be(e,t){let n=`/v1/products/${encodeURIComponent(e.productId)}/operation-set`,{response:o,text:r}=await Q(e,n,{},t);if(!o.ok)throw Ye(o,r,[e.apiKey],{productId:e.productId});return tn(r,o.status)}async function Zt(e,t,n){let o=await Y(e,t),r=await Be(o);if(n){en(r,n,e);return}if(e["--json"]){w(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} ${rn(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(on(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 en(e,t,n){let o=e.publicActions.find(c=>c&&`${c.instrument}.${c.name}`===t),r=nn(t),i=e.setupOperations.find(c=>c&&(c.operationId===t||c.operationId===r||c.operationName===t));if(i){let{inputSchema:c,operationId:d,operationName:p}=i,m={status:e.status,productBuildId:e.productBuildId,tenantSurfaceVersion:e.tenantSurfaceVersion,tenantSetupOperationSetDigest:e.tenantSetupOperationSetDigest,setupOperationId:d,operationName:p,command:`hyperscale call ${p}`,inputSchema:c};if(n["--json"]){w(m);return}a(`Operation ID: ${d}`),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 u(`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,publicAction:o};if(n["--json"]){w(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 tn(e,t){let n;try{n=JSON.parse(e)}catch{throw new u(`HTTP ${t} returned invalid JSON`)}if(!n||typeof n!="object"||n.status!=="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 u("The Product operation set is not in the expected format. Upgrade the CLI.");return n}function nn(e){return e.replaceAll(".","_")}function on(e){for(let t of["create","list","retrieve"]){let n=`_${t}`;if(e.endsWith(n))return`${e.slice(0,-n.length)}.${t}`}return e}function rn(e){if(!e||typeof e!="object")return"input schema unavailable";let t=e.properties&&typeof e.properties=="object"&&!Array.isArray(e.properties)?e.properties:{},n=new Set(Array.isArray(e.required)?e.required.filter(r=>typeof r=="string"):[]),o=Object.entries(t).map(([r,i])=>`${r}${n.has(r)?"":"?"}: ${qe(i)}`);return o.length===0?"no input":o.join(", ")}function qe(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"?`${qe(e.items)}[]`:typeof e.type=="string"?typeof e.format=="string"?`${e.type} (${e.format})`:e.type:"value"}async function an(e,t,n){if(!n)throw new u("product run needs a public action");let o=await Y(e,t),r=await Be(o,n);sn(r,n);let i=await Fe(e),s=e["--idempotency-key"]??globalThis.crypto.randomUUID(),{response:c,text:d}=await Q(o,`/v1/operations/${encodeURIComponent(n)}`,{body:JSON.stringify(i),headers:{"content-type":"application/json","idempotency-key":s},method:"POST"},n);if(!c.ok)throw Ye(c,d,[o.apiKey],{action:n,productId:o.productId});let p=c.headers.get("hyperscale-operation-id"),m=c.headers.get("hyperscale-receipt-id"),l=c.headers.get("x-request-id"),f=p?y(p,[o.apiKey]):null,$=m?y(m,[o.apiKey]):null,g=l?y(l,[o.apiKey]):null;if(e["--json"]){w({idempotencyKey:s,...g?{requestId:g}:{},operationId:f,receiptId:$,output:cn(d)});return}f&&a(`Operation: ${f}`),$&&a(`Receipt: ${$}`),a(`Idempotency key: ${s}`);let h=Me(d);h&&a(h)}function sn(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:de(t,r)})).sort((r,i)=>r.distance-i.distance||r.candidate.localeCompare(i.candidate)).slice(0,3).map(({candidate:r})=>r);throw new u(`Unknown frozen public action: ${t}. Closest valid names: ${o.join(", ")}. Run "hyperscale product actions" to list exact names.`)}function cn(e){if(e.trim()==="")return null;try{return JSON.parse(e)}catch{return e}}function Ye(e,t,n=[],o={}){let r=y(t.trim(),n),i;try{i=JSON.parse(t)}catch{return new u(`HTTP ${e.status}${r?` \xB7 ${r}`:""}`)}if(!i?.error||typeof i.error.message!="string")return new u(`HTTP ${e.status}`);let s=typeof i.error.code=="string"?i.error.code:"user_error",c=s==="user_error"?"":`${s}: `,d=i.error.message;if(typeof d=="string"&&d.includes("does not match API key Product")){let T=o.productId??d.match(/^Selected Product (\S+) does not match/)?.[1];T&&(d=`${d} Or set HYPERSCALE_API_KEY to a key for ${T}, or pass that key with --api-key.`)}let p=y(`HTTP ${e.status} \xB7 ${c}${d}`,n),m=un(i.error.details,n),l;s==="idempotency_conflict"?l="Reuse the same key only with the same operation and input. Use a new unique key for a different request.":e.status===409&&typeof i.error.message=="string"&&i.error.message.includes("capability-derived")?l='This Product has no frozen public actions. List its operations with "hyperscale ops list" and run them with "hyperscale call".':[i.error.message,...m].some(T=>typeof T=="string"&&T.includes("[Truncated]"))&&o.action&&(l=`Run "hyperscale product actions ${o.action}" to read the full input schema and allowed values.`);let f=e.headers.get("x-request-id")??(i&&typeof i=="object"&&typeof i.requestId=="string"?i.requestId:void 0),$=e.headers.get("hyperscale-operation-id")??void 0,g=e.headers.get("hyperscale-receipt-id")??void 0,h=f?y(f,n):void 0,I=$?y($,n):void 0,S=g?y(g,n):void 0,A=new u([p,...m].join(`
|
|
120
|
-
`),{code:
|
|
121
|
-
`)}function
|
|
117
|
+
`)}function we(e,t=[]){let n=e.headers.get("hyperscale-operation-id"),o=e.headers.get("hyperscale-receipt-id"),r=n?w(n,t):void 0,i=o?w(o,t):void 0;return{...r?{operationId:r}:{},...i?{receiptId:i}:{}}}function ge(e,t,n=[]){if(!e.ok)throw X(e,t,n);try{return JSON.parse(t)}catch{throw new u(`HTTP ${e.status} returned invalid JSON`)}}function Bt(e,t){t.operationId&&s(`${e} operation: ${t.operationId}`),t.receiptId&&s(`${e} receipt: ${t.receiptId}`)}function Yt(e,t){let n=e instanceof u?e:new u("hyperscale start failed after the Product was created",{code:"start_failed_after_compose"});return n.shownOnce=t,n}function qt(e){if(!e["--blueprint"]&&!(process.stdin.isTTY&&process.stderr.isTTY))throw new u("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 Ft(e){return v(e,"blueprint.list").map(t=>{if(typeof t?.id!="string"||t.id.length===0||typeof t?.name!="string"||t.name.length===0)throw new u("blueprint.list returned an invalid start choice");return{id:t.id,name:t.name,summary:typeof t.summary=="string"?t.summary:""}})}async function Mt(e,t){let n=await C(t,"/v1/blueprints",{},"blueprint.list"),o=Ft(n);if(o.length===0)throw new u("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 u(`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?
|
|
118
|
+
`);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}`:""}
|
|
119
|
+
`)}let i=et({input:process.stdin,output:process.stderr,terminal:!0}),a=new AbortController,c=()=>a.abort();process.stdin.once("end",c),process.stdin.readableEnded&&a.abort();let d;try{try{d=(await i.question("Choose a number or Blueprint slug: ",{signal:a.signal})).trim()}catch(h){throw h?.name!=="AbortError"&&h?.code!=="ABORT_ERR"?h:new u("Start cancelled before a Blueprint was chosen.",{code:"start_cancelled"})}}finally{process.stdin.off("end",c),i.close()}let p=Number(d),l=Number.isInteger(p)?o[p-1]:o.find(({id:h})=>h===d);if(l)return l;throw new u(`No Blueprint matches ${JSON.stringify(d)}.`,{fix:"Run hyperscale start again and choose a listed number or slug."})}async function xe(e,t){qt(e);let n={};try{await zt(e,t,n)}catch(o){throw typeof n.apiKey!="string"?o:Yt(o,n.apiKey)}}async function zt(e,t,n){let o=await k(e,t),r=await E(o,o.token),i=await Mt(e,o),a=e["--name"]??i.name;e["--json"]||s(`Authenticated: ${r.email}`);let c=await V(o,"/v1/products/blueprint-compose",x({blueprintId:i.id,name:a,tenantId:o.tenantId}),o.token),d=ge(c.response,c.text,[o.token]);if(typeof d?.productId!="string"||!ft.test(d.productId)||typeof d?.productBuildId!="string"||d?.blueprintId!==i.id)throw new u("product.blueprint.compose returned an invalid start Product");let p=d?.shown_once;if(typeof p!="string"||p.length===0)throw new u("The composed Product did not return its one-time API key. Choose a new Product name and run hyperscale start again.",{code:"start_api_key_unavailable"});n.apiKey=p;let l=we(c.response);await z(t,{...o,selectedProduct:d.productId}),e["--json"]||(s(`Product: ${d.productId}`),s(`Blueprint: ${d.blueprintId}`),Bt("Compose",l));let h=[`hyperscale compose plan product.hsx --product ${d.productId}`],m="Composition completed. Run SDK journeys against your Product.",I={blueprintId:d.blueprintId,composeOnly:!0,nextCommands:h,notice:m,productBuildId:d.productBuildId,productId:d.productId,receipts:[{stage:"product.blueprint.compose",...l}],...typeof d.startKeyId=="string"?{startKeyId:d.startKeyId}:{},shown_once:p};if(e["--json"]){g(I);return}s(m),s(`Shown once Product API key: ${p}`),s("Next:");for(let y of h)s(` ${y}`);s(" Run journeys with the Hyperscale SDK using the Product API key above.")}async function Wt(e,t){let n=e["--blueprint"],o=e["--source"],r=e["--name"];if(n&&o)throw new u("product create accepts either --blueprint <id> or --source <file>, not both");if(!n&&!o)throw new u("product create needs either --blueprint <id> or --source <file>");if(!r)throw new u("product create needs --name <name>");let i=o?await Be(o,"product create"):void 0,a=await k(e,t),c;try{c=await C(a,"/v1/products",{tenantId:a.tenantId},"product.list",a.token,[a.token])}catch(f){if(!(f instanceof T)||f.status!==403)throw f}let d=r.trim().toLocaleLowerCase("en-US"),p=(c?v(c,"product.list"):[]).find(f=>{let $=f?.displayName??f?.name;return typeof $=="string"&&$.trim().toLocaleLowerCase("en-US")===d});if(p){let f=p.productId??p.id??"<id>";throw new u(`A Product named ${JSON.stringify(r.trim())} already exists as ${f}.`,{code:"duplicate_product_name",fix:`Use "hyperscale product select ${f}" or choose another --name.`})}let l=o?"/v1/products/instruments-compose":"/v1/products/blueprint-compose",h=o?{name:r,program:{source:i.source},tenantId:a.tenantId,...e["--catalog-revision"]?{catalogRevisionId:e["--catalog-revision"]}:{}}:{blueprintId:n,name:r,tenantId:a.tenantId},m=await b(a,l,x(h),a.token,[a.token]);if(typeof m?.productId!="string"||typeof m?.productBuildId!="string"||!o&&typeof m?.blueprintId!="string")throw new u(`${o?"product.instruments.compose":"product.blueprint.compose"} returned an invalid Product`);await z(t,{...a,selectedProduct:m.productId});let I=typeof m?.shown_once=="string"&&m.shown_once.length>0?m.shown_once:void 0,y={...m.blueprintId?{blueprintId:m.blueprintId}:{},nextSteps:[`hyperscale product show ${m.productId}`,...I?[]:['hyperscale key create --name "Founder CLI"']],productBuildId:m.productBuildId,productId:m.productId,selectedProduct:m.productId,...typeof m.startKeyId=="string"?{startKeyId:m.startKeyId}:{},...I?{shown_once:I}:{}};if(e["--json"]){g(y);return}s(`Product: ${y.productId}`),y.blueprintId&&s(`Blueprint: ${y.blueprintId}`),s(`Build: ${y.productBuildId}`),s(`Selected: ${y.selectedProduct}`),y.shown_once&&s(`Shown once Product API key: ${y.shown_once}`),s("Next:");for(let f of y.nextSteps)s(` ${f}`)}function Ke(e){return new URLSearchParams({tenantId:e}).toString()}async function Vt(e,t){let n=await k(e,t),o=await C(n,"/v1/products",{tenantId:n.tenantId},"product.list",n.token,[n.token]),r=v(o,"product.list");if(e["--json"]){g(o);return}if(r.length===0){s('No Products yet. Run "hyperscale blueprint list", then "hyperscale product create --blueprint <id> --name <name>".');return}s("ID Name Status");for(let i of r){let a=i.productId??i.id??"unknown",c=i.displayName??i.name??"unnamed";s(`${a} ${c}${i.status?` ${i.status}`:""}`)}}async function Gt(e,t,n){let o=await k(e,t),r=n??o.selectedProduct;if(!r)throw new u("product show needs an id because no Product is selected. Create a Product first.");let i=await b(o,`/v1/products/${encodeURIComponent(r)}?${Ke(o.tenantId)}`,{},o.token,[o.token]);if(e["--json"]){g(i);return}Xt(i,r)}function Xt(e,t){let n=e?.displayName??e?.name??"unnamed",o=e?.status??"unknown",r=e?.blueprint,i=r?.id?`${r.name??r.id}${r.name?` (${r.id})`:""}`:"custom composition",a=e?.cost?.currency??"SAR",c=e?.pricing?.current?.monthlySar??e?.cost?.platformMonthlySar,d=e?.pricing?.current?.setupSar??e?.cost?.platformSetupSar,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"):[]];s(`Name: ${n}`),s(`Product: ${e?.productId??t}`),s(`Status: ${o}`),s(`Blueprint: ${i}`),e?.pricing?.scheduled?(s(`Current billing price: ${a} ${e.pricing.current.monthlySar}/mo`),s(`Accepted price from ${e.pricing.scheduled.effectiveAt}: ${a} ${e.pricing.scheduled.monthlySar}/mo`)):s(`Monthly: ${c==null?"not returned":`${a} ${c}`}`),s(`Setup: ${d==null?"not returned":`${a} ${d}`}`),s(`Live: ${e?.readiness?.live===!0?"active":"not active"}`),s(`Live blockers: ${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&&s(`${h}: ${m.url}`)}s("Next:"),s(` hyperscale key create --name "Founder CLI" --product ${e?.productId??t}`)}async function Qt(e,t,n){if(!n)throw new u("product select needs a Product id");let o=await k(e,t),r=await b(o,`/v1/products/${encodeURIComponent(n)}?${Ke(o.tenantId)}`,{},o.token,[o.token]);if(r?.productId!==n)throw new u("product.retrieve returned the wrong Product");await z(t,{...o,selectedProduct:n});let i={productId:n,selected:!0};e["--json"]?g(i):s(`Selected Product: ${r.displayName??n} (${n})`)}function Zt(e){return e.map(t=>`${t.path}: error [composer] ${t.code}: ${t.message}`)}async function Be(e,t="compose"){if(!e)throw new u(`${t} needs a .hsx file`);if(!e.endsWith(".hsx"))throw new u(`${t} reads a .hsx file, got ${e}`);let n;try{n=await U(e,"utf8")}catch(o){throw new u(`Could not read ${e}: ${o.message}`)}return{file:e,source:n}}function en(e){if(!e||typeof e!="object"||typeof e.ok!="boolean"||!Array.isArray(e.issues))throw new u("composer.check returned an invalid result");return{issues:e.issues.map(n=>{if(!n||typeof n!="object"||typeof n.code!="string"||typeof n.message!="string"||typeof n.path!="string")throw new u("composer.check returned an invalid issue");return{code:n.code,message:n.message,path:n.path}}),ok:e.ok}}async function Ie(e,t,n,o="none"){let r=await Be(n),i=await k(e,t),a=o==="required"?D(i,e):o==="optional"?qe(i,e):void 0,c=await V(i,"/v1/composer/check",x({tenantId:i.tenantId,document:r.source,...e["--catalog-revision"]?{catalogRevisionId:e["--catalog-revision"]}:{}}),i.token),d=we(c.response,[i.token]),p=en(ge(c.response,c.text,[i.token]));if(!p.ok)throw new J(["composer.check refused the program.",...Zt(p.issues)].join(`
|
|
120
|
+
`),{file:n,issues:p.issues,...d});return{check:p,receipt:d,context:i,productId:a,program:r,catalogRevisionId:e["--catalog-revision"]}}async function tn(e,t,n){let o=await Ie(e,t,n,"none");if(e["--json"]){g({command:"composer.check",file:n,issues:o.check.issues,ok:!0,...o.receipt});return}s(`Check passed: ${n}`)}async function Ye(e,t){let n=await V(e.context,"/v1/composer/plan",x({document:e.program.source,tenantId:e.context.tenantId,...e.productId?{productId:e.productId}:{},...e.catalogRevisionId?{catalogRevisionId:e.catalogRevisionId}:{}}),e.context.token),o=ge(n.response,n.text,[e.context.token]),r=we(n.response,[e.context.token]);if(!o||typeof o!="object"||typeof o.summary!="string"||!Array.isArray(o.actions)||!o.pricing||typeof o.pricing!="object")throw new u("composer.plan returned an invalid result");let i=o.actions.filter(a=>!a||typeof a!="object"||a.kind!=="configure_product");if(i.length>0)throw new J([o.summary,...i.map(a=>a&&typeof a=="object"?`${a.kind??"unknown"} ${a.target??"unknown"} ${a.detail??"Composer refused this action."}`:"unknown unknown Composer returned an invalid refusal action.")].join(`
|
|
121
|
+
`),{actions:i,file:t,...r,...e.productId?{productId:e.productId}:{}});return{...o,...r}}async function nn(e,t,n){let o=await Ie(e,t,n,"optional"),r=await Ye(o,n);if(e["--json"]){g({command:"composer.plan",file:n,check:{...o.check,...o.receipt},plan:r,...o.productId?{productId:o.productId}:{}});return}s(r.summary);for(let i of r.actions)s(`${i.kind} ${i.target} ${i.detail}`);r.pricing?.scheduled?(s(`Current billing price: SAR ${r.pricing.current.monthlySar}/mo`),s(`Candidate price from ${r.pricing.scheduled.effectiveAt}: SAR ${r.pricing.scheduled.monthlySar}/mo`),s(`Pricing identity: ${r.pricing.scheduled.pricingIdentity}`)):(s(`Monthly: SAR ${r.pricing.monthlySar}`),s(`Activation: SAR ${r.pricing.activationSar}`))}async function on(e,t,n){if(!e["--confirm"]&&!e["--yes"])throw new u("compose apply changes the selected Product. Pass --confirm, or --yes for an agent.");let o=e["--pricing-identity"];if(!o&&e["--plan-file"]){let c=e["--plan-file"];try{let d=await U(c,"utf8"),p=JSON.parse(d);o=p.plan?.pricing?.scheduled?.pricingIdentity??p.pricing?.scheduled?.pricingIdentity??p.pricingIdentity}catch(d){throw new u(`Failed to read saved plan file ${c}: ${d.message}`)}}let r=await Ie(e,t,n,"required"),i=await Ye(r,n);if(i.pricing?.scheduled&&!o){if(!e["--yes"])throw new u(`compose apply --confirm requires --pricing-identity (or --plan-file). Run "hyperscale compose plan ${n}" to review candidate pricing and copy the pricing identity, or pass --yes to accept the current candidate.`);o=i.pricing.scheduled.pricingIdentity}let a;try{a=await b(r.context,"/v1/products/recompose",x({program:{source:r.program.source},...r.catalogRevisionId?{catalogRevisionId:r.catalogRevisionId}:{},...o?{pricingIdentity:o}:{},tenantId:r.context.tenantId,productId:r.productId},e["--idempotency-key"]),r.context.token,[r.context.token])}catch(c){throw c instanceof T&&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 u("product.recompose returned no new build identity");if(e["--json"]){g({command:"product.recompose",file:n,output:a});return}s(`Product: ${a.productId??r.productId}`),s(`Build: ${a.productBuildId}`),a.buildDigest&&s(`Digest: ${a.buildDigest}`),a.pricing?.scheduled&&(s(`Current billing price: SAR ${a.pricing.current.monthlySar}/mo`),s(`Accepted price from ${a.pricing.scheduled.effectiveAt}: SAR ${a.pricing.scheduled.monthlySar}/mo`))}function qe(e,t){let n=t["--product"]??e.selectedProduct;return typeof n=="string"&&n.length>0?n:void 0}function D(e,t){let n=qe(e,t);if(!n)throw new u("No Product selected. Pass --product <id> or create a Product first.");return n}async function B(e,t){let n=await M(t),o=D(n??{},e),r=j(e,t,n??{});if(n&&(r.baseUrl!==n.baseUrl||r.environment!==n.environment))throw new u(`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 ve(o);return{...r,apiKey:i,productId:o}}async function Fe(e,t){let n=`/v1/products/${encodeURIComponent(e.productId)}/operation-set`,{response:o,text:r}=await G(e,n,{},t);if(!o.ok)throw ze(o,r,[e.apiKey],{productId:e.productId});return sn(r,o.status)}async function rn(e,t,n){let o=await B(e,t),r=await Fe(o);if(n){an(r,n,e);return}if(e["--json"]){g(r);return}if(r.publicActions.length===0)s("No public actions");else{s("Operation ID Input Kind");for(let i of r.publicActions){let a=i.idempotencyPolicy?.mode==="not_required"?"read-only":"mutation";s(`${i.instrument}.${i.name} ${dn(i.inputSchema)} ${a}`)}}if(r.setupOperations.length>0){s("Setup operations (run with hyperscale call)");for(let i of r.setupOperations)s(i.operationName)}if(r.readOperationIds.length>0){s("Reads (run with hyperscale call)");for(let i of r.readOperationIds)s(un(i))}s(`Digest: ${r.tenantOperationSetDigest}`),s(`Setup digest: ${r.tenantSetupOperationSetDigest}`),s(`Read digest: ${r.tenantReadOperationSetDigest}`),s(`Build: ${r.productBuildId}`),s(`Surface version: ${r.tenantSurfaceVersion}`)}function an(e,t,n){let o=e.publicActions.find(c=>c&&`${c.instrument}.${c.name}`===t),r=cn(t),i=e.setupOperations.find(c=>c&&(c.operationId===t||c.operationId===r||c.operationName===t));if(i){let{inputSchema:c,operationId:d,operationName:p}=i,l={status:e.status,productBuildId:e.productBuildId,tenantSurfaceVersion:e.tenantSurfaceVersion,tenantSetupOperationSetDigest:e.tenantSetupOperationSetDigest,setupOperationId:d,operationName:p,command:`hyperscale call ${p}`,inputSchema:c};if(n["--json"]){g(l);return}s(`Operation ID: ${d}`),s(`Operation name: ${p}`),s(`Run: hyperscale call ${p}`),s(`Input schema: ${JSON.stringify(c,null,2)}`),(!Array.isArray(c.required)||c.required.length===0)&&s("Input: omit --input or pass {}."),s(`Setup digest: ${e.tenantSetupOperationSetDigest}`),s(`Build: ${e.productBuildId}`),s(`Surface version: ${e.tenantSurfaceVersion}`);return}if(!o)throw new u(`Unknown frozen public action: ${t}. Run "hyperscale product actions" to list exact names.`);let a={status:e.status,productBuildId:e.productBuildId,tenantSurfaceVersion:e.tenantSurfaceVersion,tenantOperationSetDigest:e.tenantOperationSetDigest,publicAction:o};if(n["--json"]){g(a);return}s(`Operation ID: ${o.instrument}.${o.name}`),s(`Instrument: ${o.instrument}`),s(`Input schema: ${JSON.stringify(o.inputSchema,null,2)}`),s(`Output schema: ${JSON.stringify(o.outputSchema,null,2)}`),s(`Actor policy: ${JSON.stringify(o.actorPolicy,null,2)}`),s(`Port policy: ${JSON.stringify(o.portPolicy,null,2)}`),s(`Idempotency policy: ${JSON.stringify(o.idempotencyPolicy,null,2)}`),s(`Receipt policy: ${JSON.stringify(o.receiptPolicy,null,2)}`),s(`Receipt evidence: ${JSON.stringify(o.receiptEvidence,null,2)}`),s(`Digest: ${e.tenantOperationSetDigest}`),s(`Build: ${e.productBuildId}`),s(`Surface version: ${e.tenantSurfaceVersion}`)}function sn(e,t){let n;try{n=JSON.parse(e)}catch{throw new u(`HTTP ${t} returned invalid JSON`)}if(!n||typeof n!="object"||n.status!=="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 u("The Product operation set is not in the expected format. Upgrade the CLI.");return n}function cn(e){return e.replaceAll(".","_")}function un(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,i])=>`${r}${n.has(r)?"":"?"}: ${Me(i)}`);return o.length===0?"no input":o.join(", ")}function Me(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"?`${Me(e.items)}[]`:typeof e.type=="string"?typeof e.format=="string"?`${e.type} (${e.format})`:e.type:"value"}async function pn(e,t,n){if(!n)throw new u("product run needs a public action");let o=await B(e,t),r=await Fe(o,n);ln(r,n);let i=await We(e),a=e["--idempotency-key"]??globalThis.crypto.randomUUID(),{response:c,text:d}=await G(o,`/v1/operations/${encodeURIComponent(n)}`,{body:JSON.stringify(i),headers:{"content-type":"application/json","idempotency-key":a},method:"POST"},n);if(!c.ok)throw ze(c,d,[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?w(p,[o.apiKey]):null,I=l?w(l,[o.apiKey]):null,y=h?w(h,[o.apiKey]):null;if(e["--json"]){g({idempotencyKey:a,...y?{requestId:y}:{},operationId:m,receiptId:I,output:mn(d)});return}m&&s(`Operation: ${m}`),I&&s(`Receipt: ${I}`),s(`Idempotency key: ${a}`);let f=Ve(d);f&&s(f)}function ln(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:ue(t,r)})).sort((r,i)=>r.distance-i.distance||r.candidate.localeCompare(i.candidate)).slice(0,3).map(({candidate:r})=>r);throw new u(`Unknown frozen public action: ${t}. Closest valid names: ${o.join(", ")}. Run "hyperscale product actions" to list exact names.`)}function mn(e){if(e.trim()==="")return null;try{return JSON.parse(e)}catch{return e}}function ze(e,t,n=[],o={}){let r;try{r=JSON.parse(t)}catch{return new u(`HTTP ${e.status} \xB7 ${se(t,n)}`)}if(!r?.error||typeof r.error.message!="string")return new u(`HTTP ${e.status} \xB7 ${se(t,n)}`);let i=typeof r.error.code=="string"?r.error.code:"user_error",a=i==="user_error"?"":`${i}: `,c=r.error.message;if(typeof c=="string"&&c.includes("does not match API key Product")){let S=o.productId??c.match(/^Selected Product (\S+) does not match/)?.[1];S&&(c=`${c} Or set HYPERSCALE_API_KEY to a key for ${S}, or pass that key with --api-key.`)}let d=w(`HTTP ${e.status} \xB7 ${a}${c}`,n),p=fn(r.error.details,n),l;i==="idempotency_conflict"?l="Reuse the same key only with the same operation and input. Use a new unique key for a different request.":e.status===409&&typeof r.error.message=="string"&&r.error.message.includes("capability-derived")?l='This Product has no frozen public actions. List its operations with "hyperscale ops list" and run them with "hyperscale call".':[r.error.message,...p].some(S=>typeof S=="string"&&S.includes("[Truncated]"))&&o.action&&(l=`Run "hyperscale product actions ${o.action}" to read the full input schema and allowed values.`);let h=e.headers.get("x-request-id")??(r&&typeof r=="object"&&typeof r.requestId=="string"?r.requestId:void 0),m=e.headers.get("hyperscale-operation-id")??void 0,I=e.headers.get("hyperscale-receipt-id")??void 0,y=h?w(h,n):void 0,f=m?w(m,n):void 0,$=I?w(I,n):void 0,P=new u([d,...p].join(`
|
|
122
|
+
`),{code:i,...r.error.details?{details:Y(r.error.details,n)}:{},...l?{fix:l}:{}});return y&&(P.requestId=y),f&&(P.operationId=f),$&&(P.receiptId=$),P}function Y(e,t){return typeof e=="string"?w(e,t):Array.isArray(e)?e.map(n=>Y(n,t)):e&&typeof e=="object"?Object.fromEntries(Object.entries(e).map(([n,o])=>[w(n,t),Y(o,t)])):e}function fn(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}: ${w(o.message,t)}`]:[]});let n=[];return ce(e,"",n,t),n}function ce(e,t,n,o){if(Array.isArray(e)){if(e.every(r=>r===null||typeof r!="object")){n.push(`${Te(t)}: ${w(e.join(", "),o)}`);return}e.forEach((r,i)=>ce(r,`${t}[${i}]`,n,o));return}if(e&&typeof e=="object"){for(let[r,i]of Object.entries(e))ce(i,t?`${t}.${r}`:r,n,o);return}t&&n.push(`${Te(t)}: ${w(String(e),o)}`)}function Te(e){let t=e.replace(/([a-z0-9])([A-Z])/g,"$1 $2").replaceAll("."," ");return t.charAt(0).toUpperCase()+t.slice(1)}async function hn(e,t){let n=await k(e,t),o=D(n,e),r=await b(n,"/v1/sandbox-api-keys",x({name:e["--name"]??"Founder CLI",tenantId:n.tenantId,productId:o}),n.token,[n.token]);if(e["--json"]){g(r);return}s(`Key: ${r.apiKeyId??"unknown"}`),s(`Product: ${r.productId??o}`),s(`Status: ${r.status??"unknown"}`),r.secret?(s(`Secret: ${r.secret}`),s("Store it now. Hyperscale will not return it again."),s("Next:"),s(` export HYPERSCALE_API_KEY=${yn(r.secret)}`),s(` hyperscale product actions --product ${o}`)):s("The key already existed, so the one-time secret is unavailable.")}function yn(e){return`'${String(e).replaceAll("'",`'"'"'`)}'`}async function wn(e,t){let n=await k(e,t),o=D(n,e),r=await C(n,"/v1/api-keys",{productId:o,tenantId:n.tenantId},"api_key.list",n.token,[n.token]),i=v(r,"api_key.list");if(e["--json"]){g(r);return}for(let a of i)s(`${a.apiKeyId} ${a.name??"unnamed"} ${a.status??"unknown"}`)}async function gn(e,t,n){if(!n)throw new u("key revoke needs an API key id");let o=await k(e,t),r=D(o,e),i=await b(o,`/v1/api-keys/${encodeURIComponent(n)}/revoke`,x({tenantId:o.tenantId,productId:r}),o.token,[o.token]);e["--json"]?g(i):s(`Key ${i.apiKeyId??n}: ${i.status??"revoked"}`)}async function In(e,t){let n=await k(e,t),o=n.identity??await E(n,n.token),r=ye(n,o);if(e["--json"]){g(r);return}s(`User: ${o.email}`),s(`Tenant: ${o.tenantId}`),s(`Role: ${o.role}`),s(`Token: ${o.name}`),s(`Expires: ${o.expiresAt}`)}async function $n(e,t,n){let o=await De(e),r=n?n.toLowerCase():null,i=r?o.operations.filter(c=>c.name.toLowerCase().includes(r)||c.path.toLowerCase().includes(r)):o.operations;if(t["--json"]){s(JSON.stringify(i,null,2));return}if(i.length===0){s(n?`No operation matches ${n}`:"No operations");return}let a=Math.max(...i.map(c=>c.name.length));for(let c of i)s(`${c.name.padEnd(a)} ${c.method.padEnd(6)}${c.path}`)}async function kn(e,t){let n=await k(e,t),o=await C(n,"/v1/activity",{tenantId:n.tenantId},"activity.list",n.token,[n.token]),r=v(o,"activity.list");if(e["--json"]){g(o);return}s("Time Activity Target Status");for(let i of r){let a=i.operation??i.auditEvent??"activity",c=i.resourceKind&&i.resourceId?`${i.resourceKind}:${i.resourceId}`:i.resourceKind??i.resourceId??"-";s(`${i.occurredAt??"unknown"} ${a} ${c} ${i.status??"recorded"}`)}}function Pn(e,t){let n={...t},o=[],r=e.path.replace(/\{([^}]+)\}/g,(i,a)=>{let c=n[a];return c==null?(o.push(a),""):(delete n[a],encodeURIComponent(String(c)))});if(o.length>0)throw new u(`${e.name} needs ${o.join(", ")} in --input`);return{path:r,remaining:n}}function bn(e){let t=new URLSearchParams;for(let[o,r]of Object.entries(e))r!=null&&t.set(o,typeof r=="string"?r:JSON.stringify(r));let n=t.toString();return n?`?${n}`:""}function ue(e,t){let n=Array.from({length:t.length+1},(o,r)=>r);for(let o=1;o<=e.length;o+=1){let r=[o];for(let i=1;i<=t.length;i+=1)r[i]=Math.min(r[i-1]+1,n[i]+1,n[i-1]+(e[o-1]===t[i-1]?0:1));n.splice(0,n.length,...r)}return n[t.length]}function Sn(e,t){let n=e.find(i=>i.name===t);if(n)return n;let o=e.filter(i=>i.operationId===t);if(o.length===1)return o[0];if(o.length>1)throw new u(`${t} matches more than one operation. Use one of: ${o.map(i=>i.name).join(", ")}.`);let r=e.map(i=>({candidate:i,distance:Math.min(ue(t,i.name),ue(t,i.operationId))})).sort((i,a)=>i.distance-a.distance||i.candidate.name.localeCompare(a.candidate.name)).slice(0,3).flatMap(({candidate:i})=>[i.name,i.operationId]);throw new u(`${t} is not an operation in the selected Product's machine document. Closest valid names: ${r.join(", ")}.`)}async function An(e,t,n){if(!n)throw new u("call needs an operation name");let o=await De(e),r=Sn(o.operations,n),i=await We(t),{path:a,remaining:c}=Pn(r,i),d={method:r.method},p=a;r.method==="GET"?p+=bn(c):(d.body=JSON.stringify(c),d.headers={"content-type":"application/json",...r.idempotency==="not_required"?{}:{"idempotency-key":t["--idempotency-key"]??globalThis.crypto.randomUUID()}});let{response:l,text:h}=await G(e,p,d);if(l.ok){if(t["--json"]){let m=Tt(h),I=l.headers.get("x-request-id")??(m&&typeof m=="object"&&typeof m.requestId=="string"?m.requestId:null),y=l.headers.get("hyperscale-operation-id")??null,f=l.headers.get("hyperscale-receipt-id")??null,$=Je(l.headers),P=I?w(I,[e.apiKey]):null,S=y?w(y,[e.apiKey]):null,Ge=f?w(f,[e.apiKey]):null,Xe=$?w($,[e.apiKey]):null;g({status:l.status,data:m,requestId:P,operationId:S,receiptId:Ge,traceId:Xe});return}s(Ve(h));return}throw X(l,h,[e.apiKey])}async function We(e){if(e["--input"]!==void 0&&e["--input-file"]!==void 0)throw new u("Use only one of --input and --input-file");if(e["--input"]!==void 0)return te(e["--input"],"--input");if(e["--input-file"]!==void 0){let t;try{t=await U(e["--input-file"],"utf8")}catch(n){throw new u(`Could not read ${e["--input-file"]}: ${n.message}`)}return te(t,"--input-file")}if(!process.stdin.isTTY){let t=await At();if(t.trim()!=="")return te(t,"stdin")}return{}}function te(e,t="--input"){if(e===void 0)return{};let n;try{n=JSON.parse(e)}catch(o){throw new u(`${t} is not valid JSON: ${o.message}`)}if(n===null||typeof n!="object"||Array.isArray(n))throw new u(`${t} must be a JSON object`);return n}function Ve(e){if(e.trim()==="")return"";try{return JSON.stringify(JSON.parse(e),null,2)}catch{return e}}function s(e){process.stdout.write(`${e}
|
|
123
|
+
`)}function g(e){s(JSON.stringify(e,null,2))}function xn(e){for(let t=0;t<e.length;t+=1){let n=e[t];if(!n.startsWith("--"))return n;Ce.has(n)&&(t+=1)}}function Tn(e,t){let n=xn(t)==="call",o=t.includes("--json");if(n&&o&&e instanceof T){g({status:e.status,error:e.structuredError??{code:e.code??"http_error",message:e.message},requestId:e.requestId??null,operationId:e.operationId??null,receiptId:e.receiptId??null,traceId:e.traceId??null});let c=typeof e.message=="string"?e.message:e.stack??String(e);process.stderr.write(`${c}
|
|
122
124
|
`);return}let r=e instanceof u&&typeof e.shownOnce=="string"?e.shownOnce:void 0;if(!o){let c=e instanceof u?e.message:e.stack??String(e),d=e instanceof u&&typeof e.fix=="string"?`
|
|
123
125
|
Fix: ${e.fix}`:"",p=r?`
|
|
124
126
|
Shown once Product API key: ${r}`:"";process.stderr.write(`${c}${d}${p}
|
|
125
|
-
`);return}let i=e instanceof u,
|
|
126
|
-
`)}async function
|
|
127
|
+
`);return}let i=e instanceof u,a=i&&typeof e.code=="string"?e.code:i?"user_error":"internal_error";process.stderr.write(`${JSON.stringify({error:{code:a,message:i?e.message:"The command failed unexpectedly.",...i&&e.details?{details:e.details}:{},fix:i?e.fix??'Follow the message, or run "hyperscale --help" for command usage.':"Report the failure without including credentials."},...r?{shown_once:r}:{}})}
|
|
128
|
+
`)}async function En(){let{readFileSync:e}=await import("node:fs");return JSON.parse(e(new URL("./package.json",import.meta.url),"utf8")).version}async function vn(e,t){let{flags:n,positional:o}=wt(e);if(n["--version"])return s(await En()),0;if(n["--help"]&&o.length>0)return process.stdout.write(yt(o)),0;if(o.length===0&&!n["--help"]){if(n["--json"])throw new u('No command. Run "hyperscale --help" to list commands.');return process.stdin.isTTY&&process.stderr.isTTY?(await xe(n,t),0):(s('Build your first Product with "hyperscale start".'),s('Run "hyperscale --help" for every command.'),0)}if(n["--help"])return process.stdout.write(ht),0;let[r,...i]=o;if(r==="start")return await xe(n,t),0;if(r==="auth"){if(i[0]==="login")await _t(n,t);else if(i[0]==="status")await Nt(n,t);else if(i[0]==="logout")await jt(n,t);else throw new u('Auth subcommands are "login", "status", and "logout"');return 0}if(r==="blueprint"){let a=j(n,t);if(i[0]==="list")await Ut(a,n);else if(i[0]==="show")await Ht(a,n,i[1]);else throw new u('Blueprint subcommands are "list" and "show"');return 0}if(r==="product"){if(i[0]==="create")await Wt(n,t);else if(i[0]==="list")await Vt(n,t);else if(i[0]==="show")await Gt(n,t,i[1]);else if(i[0]==="select")await Qt(n,t,i[1]);else if(i[0]==="actions")await rn(n,t,i[1]);else if(i[0]==="run")await pn(n,t,i[1]);else throw new u('Product subcommands are "create", "list", "show", "select", "actions", and "run"');return 0}if(r==="compose"){if(i[0]==="check")await tn(n,t,i[1]);else if(i[0]==="plan")await nn(n,t,i[1]);else if(i[0]==="apply")await on(n,t,i[1]);else throw new u('Compose subcommands are "check", "plan", and "apply"');return 0}if(r==="key"){if(i[0]==="create")await hn(n,t);else if(i[0]==="list")await wn(n,t);else if(i[0]==="revoke")await gn(n,t,i[1]);else throw new u('Key subcommands are "create", "list", and "revoke"');return 0}if(r==="whoami")return await In(n,t),0;if(r==="activity"){if(i[0]!=="list")throw new u('The only activity subcommand is "list"');return await kn(n,t),0}if(r==="ops"){if(i[0]!=="list")throw new u('The only ops subcommand is "list"');let a=n["--product"]?await B(n,t):ke(n,t);return await $n(a,n,i[1]),0}if(r==="call"){let a=n["--product"]?await B(n,t):ke(n,t);return await An(a,n,i[0]),0}throw new u(`Unknown command: ${r}`)}vn(process.argv.slice(2),process.env).then(e=>{process.exitCode=e},e=>{Tn(e,process.argv.slice(2)),process.exitCode=e instanceof u&&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.
|
|
3
|
+
"version": "1.0.0-beta.21",
|
|
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": "
|
|
23
|
+
"gitHead": "15441e0688e4f3031c5560eba341be6d431e3d32"
|
|
24
24
|
}
|