@hyperscale0/cli 1.0.0-beta.2 → 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.
Files changed (3) hide show
  1. package/README.md +66 -25
  2. package/hyperscale.js +73 -46
  3. package/package.json +4 -3
package/README.md CHANGED
@@ -1,57 +1,98 @@
1
1
  # @hyperscale0/cli
2
2
 
3
- The Hyperscale founder command line. It logs a founder in, discovers public
4
- Blueprints, composes Products, manages sandbox API keys, and runs one Product's
5
- frozen public verbs.
3
+ Hyperscale CLI: the founder command line. It logs a founder in, discovers
4
+ public Blueprints, composes Products, manages sandbox API keys, and runs one
5
+ Product's frozen public actions.
6
6
 
7
- ## Use
7
+ ## Install
8
8
 
9
- Request access at https://hyperscale0.ai/request-access.
9
+ ```bash
10
+ npm install -g @hyperscale0/cli
11
+ # or run directly with bunx / npx
12
+ bunx @hyperscale0/cli --help
13
+ ```
14
+
15
+ ## Quickstart
16
+
17
+ Mint a founder PAT in Hyperscale Portal at https://hyperscale0.ai/desk. Open
18
+ Security, then Personal access tokens. Unapproved founders can request access at
19
+ https://hyperscale0.ai/request-access.
10
20
 
11
21
  ```bash
12
- export HYPERSCALE_TOKEN=<your founder PAT>
13
- bunx @hyperscale0/cli auth login
22
+ export HYPERSCALE_TOKEN="<your founder PAT>"
23
+ bunx @hyperscale0/cli auth login --no-browser
14
24
  bunx @hyperscale0/cli whoami
25
+ bunx @hyperscale0/cli start --blueprint vehicle-escrow-marketplace --json
15
26
  bunx @hyperscale0/cli blueprint list
16
- bunx @hyperscale0/cli product create --blueprint vehicle-escrow-marketplace --name "Vehicle Escrow"
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"
29
+ bunx @hyperscale0/cli product select <Product id>
17
30
  bunx @hyperscale0/cli key create --name "Founder laptop"
18
31
  bunx @hyperscale0/cli compose check product.hsx
19
32
  bunx @hyperscale0/cli compose plan product.hsx
20
33
  bunx @hyperscale0/cli compose apply product.hsx --yes
21
- bunx @hyperscale0/cli team list
22
- bunx @hyperscale0/cli team invite --email developer@example.com --role developer
23
34
  bunx @hyperscale0/cli activity list
24
35
  bunx @hyperscale0/cli ops list payment
25
36
 
26
- export HYPERSCALE_API_KEY=<your Product API key>
27
- bunx @hyperscale0/cli product verbs
28
- bunx @hyperscale0/cli product verbs escrow.release --json
29
- bunx @hyperscale0/cli product run escrow.release --input '{"saleId":"sale_sandbox_..."}'
37
+ export HYPERSCALE_API_KEY="<your Product API key>"
38
+ bunx @hyperscale0/cli product actions
39
+ bunx @hyperscale0/cli product actions escrow_order.placeBuyerHold --json
40
+ bunx @hyperscale0/cli product run escrow_order.placeBuyerHold --input '{"escrowOrderId":"eord_sandbox_..."}'
30
41
  bunx @hyperscale0/cli call account.list --input '{"limit":5}'
31
42
  ```
32
43
 
33
- `product verbs` lists the frozen Product surface. Pass one exact public
34
- operation id such as `escrow.release` to return its full input schema, output
35
- schema, policies, build id, surface version, and operation-set digest.
44
+ ## Commands
45
+
46
+ `product actions` lists the frozen Product surface. Pass one exact public
47
+ operation id such as `escrow_order.placeBuyerHold` to return its full input
48
+ schema, output schema, policies, build id, surface version, and operation-set
49
+ digest.
50
+ `product create` creates and selects a new Product with `--name <name>`
51
+ from either `--blueprint <slug>` or `--source <file.hsx>`.
52
+ `start` asks which catalog company to build in a terminal. Scripts and agents
53
+ pass `--blueprint <slug>` to skip the prompt. `product select <Product id>`
54
+ stores the default Product used by compose, key, and Product commands when
55
+ `--product` is absent.
36
56
  `compose check` compiles textual HSX and runs the independent composer check.
37
57
  `compose plan` diffs it against the selected Product. `compose apply`
38
58
  recomposes that Product and requires `--confirm`, or `--yes` for an agent.
39
59
  Compiler or composer refusal exits 2. Transport and server failure exit 1.
40
60
  `npx @hyperscale0/cli` runs the same commands. Add
41
61
  `--json` for machine-readable success and failure output.
62
+ `auth login --no-browser` skips the localhost browser callback. Without a PAT,
63
+ it prints the PAT desk and request-access URL. With `--token` or
64
+ `HYPERSCALE_TOKEN`, it validates and stores that founder PAT without opening a
65
+ browser.
42
66
 
43
- Founder control commands, including `ops`, `team`, and `activity`, use
44
- `HYPERSCALE_TOKEN`. Product-key commands use
45
- `HYPERSCALE_API_KEY` and need no founder login profile. On a clean machine,
46
- set the Product API key and pass `--product <id>`. Use `--base-url` and
67
+ Founder PAT commands are `auth`, `whoami`, `product create/list/show/select`,
68
+ `compose plan/apply`, `key`, and `activity`. They use
69
+ `--token`, `HYPERSCALE_TOKEN`, or a stored login in that order. Product API
70
+ key commands are `product actions/run`, `ops list`, and `call`. They use
71
+ `HYPERSCALE_API_KEY` and need no founder login profile. `compose check`
72
+ runs locally when no founder credential exists. On a clean machine, set the
73
+ Product API key and pass `--product <id>`. Use `--base-url` and
47
74
  `--environment` when their defaults do not name the Product's plane.
48
75
 
49
76
  Point it at another host with `--base-url`, and at the live plane with
50
77
  `--environment live`. Live keys and sandbox keys are never interchangeable.
51
- The CLI stores the founder PAT in macOS Keychain, with a 0600 file fallback on
52
- systems where Keychain is unavailable. `auth logout` deletes local state and
53
- does not revoke the PAT. `auth logout --revoke` revokes the active PAT before
54
- deleting local state. Passkey login stays in the portal at
78
+ The CLI stores the founder PAT in macOS Keychain by default. If Keychain is
79
+ unavailable, it falls back to an owner-only 0600 file under
80
+ `HYPERSCALE_CONFIG_DIR`, or `~/.config/hyperscale` by default. Set
81
+ `HYPERSCALE_CREDENTIAL_STORE=file` to choose that file store and skip
82
+ Keychain access. `auth logout` deletes local state and does not revoke the
83
+ PAT. `auth logout --revoke` revokes the active PAT before deleting local
84
+ state. Passkey login stays in the portal at
55
85
  https://hyperscale0.ai/signin.
56
86
 
57
87
  Run `bunx @hyperscale0/cli --help` for the full option list.
88
+
89
+ ## Reference
90
+
91
+ - [Portal desk](https://hyperscale0.ai/desk)
92
+ - [Developer entry point](https://hyperscale0.ai/developers)
93
+ - [Documentation](https://hyperscale0.ai/docs)
94
+
95
+ ## Security and license
96
+
97
+ - Security: https://hyperscale0.ai/security
98
+ - License: LicenseRef-Hyperscale-Proprietary
package/hyperscale.js CHANGED
@@ -1,29 +1,26 @@
1
1
  #!/usr/bin/env node
2
- var Ae=["advance","captured_payment","conditional_disbursement","credit_facility","deposit","funding_round","held_payment","instant_transfer","metered","pooled_split","premium_forward","recurring_collection","rotating_pool","scheduled","settlement_batch","swap","weighted_distribution"],le={advance:{eventCap:2,keys:["against","amount","count","every","fee","first_due","funder","to"],referenceableExits:[],required:["funder","to","amount"]},captured_payment:{eventCap:4,keys:["amount","capture_mode","correction","correction_mode","external_reversal","fees","negative_position","payee","payer","reserve_until","timeout"],referenceableExits:[],required:["payer","payee","amount","capture_mode","reserve_until","correction","external_reversal","correction_mode","negative_position","timeout"]},conditional_disbursement:{eventCap:1,keys:["amount","cap","decision","destination","recovery_policy","reopen_policy","source"],referenceableExits:[],required:["source","destination","cap","amount","decision","reopen_policy","recovery_policy"]},credit_facility:{eventCap:1,keys:["availability_policy","borrower","close_policy","draw_destination","expires_at","expiry_policy","lender","limit","obligation"],referenceableExits:[],required:["lender","borrower","draw_destination","limit","expires_at","obligation","availability_policy","expiry_policy","close_policy"]},deposit:{eventCap:1,keys:["amount","claim","holder","payer","return"],referenceableExits:[],required:["payer","holder","amount","claim","return"]},funding_round:{eventCap:4,keys:["beneficiary","cancel_policy","close_by","close_policy","commitment","contributor","fail_policy","max_contributors","overfund_policy","target"],referenceableExits:[],required:["contributor","beneficiary","target","commitment","max_contributors","close_by","close_policy","overfund_policy","cancel_policy","fail_policy"]},held_payment:{eventCap:7,keys:["amount","fees","on_cancel","payer","payee","release"],referenceableExits:["release"],required:["payer","payee","amount","release"]},instant_transfer:{eventCap:3,keys:["amount","fees","payer","payee"],referenceableExits:[],required:["payer","payee","amount"]},metered:{eventCap:14,keys:["close_by","payer","payee","rates"],maxRates:14,referenceableExits:[],required:["payer","payee","rates","close_by"]},pooled_split:{eventCap:14,keys:["amount","payer","payout_due","split"],maxRecipients:7,referenceableExits:[],required:["payer","amount","split","payout_due"]},premium_forward:{eventCap:6,keys:["amount","bind","carrier","commission","endorsement","endorsement_policy","lapse_policy","on_cancel","payer","policy_ref","renewal_due","renewal_policy"],referenceableExits:[],required:["payer","carrier","amount","bind"]},recurring_collection:{eventCap:0,keys:["attempt_policy","failure_policy","mandate","obligation","period_idempotency","retry_policy"],referenceableExits:[],required:["obligation","mandate","attempt_policy","period_idempotency","retry_policy","failure_policy"]},rotating_pool:{eventCap:3,keys:["contribution","count","default_policy","every","exit_policy","first_due","guarantee_policy","guarantor","members","payout_order"],referenceableExits:[],required:["members","contribution","count","every","first_due","payout_order","default_policy","guarantee_policy","exit_policy"]},scheduled:{eventCap:3,keys:["advance_to","amount","count","debtor","delinquency_policy","every","first_due","mode","partial_payment","payer","payee","refund_policy","repayment_matching","reschedule_policy"],referenceableExits:["obligation"],required:["payer","payee","amount","count","every","first_due"]},settlement_batch:{eventCap:1,keys:["close_trigger","external_reversal_offsets","fee_entries","negative_position","payout_destination","payout_acknowledgement","payout_beneficiary_ref","settlement_account","source_capture_refs"],referenceableExits:[],required:["settlement_account","source_capture_refs","fee_entries","external_reversal_offsets","close_trigger","payout_destination","negative_position","payout_acknowledgement","payout_beneficiary_ref"]},swap:{eventCap:10,keys:["amounts","between","dispute","fees","release"],referenceableExits:[],required:["between","amounts","release"]},weighted_distribution:{eventCap:1,keys:["amount","correction_policy","max_recipients","recipient","record_at","rounding_policy","snapshot","source","weight","withholding_policy"],referenceableExits:[],required:["source","recipient","amount","weight","max_recipients","record_at","snapshot","rounding_policy","withholding_policy","correction_policy"]}};var Xe=["business","person"],Ze=["access","claim","good","service","ticket"];var An=["count","every","first_due"],Qe=/^[a-z][a-z0-9]*(?:_[a-z0-9]+)*$/,ve=/^[a-z][A-Za-z0-9]*$/,xn=/^[A-Z]{3}$/,xe=1e4;function Cn(e){let t=[],n=(i,m)=>{t.push({message:m,severity:"error",span:i})},r=(i,m)=>{t.push({message:m,severity:"warning",span:i})},o=[],a=e.decls.filter(i=>i.kind==="program"),l=a[0];l||n({end:0,start:0},'the file needs a program header naming the company, like: program used_car_escrow "Used-car escrow"');for(let i of a.slice(1))n(i.span,"a file declares exactly one program");l&&!Qe.test(l.name.name)&&n(l.name.span,`the program name must be snake_case, like used_car_escrow; "${l.name.name}" is not`);let s=new Map;for(let i of e.decls)if(i.kind==="import"){if(i.from.value!=="settlement"){n(i.from.span,`"${i.from.value}" is not an importable module; the settlement algebra lives in "settlement"`);continue}for(let m of i.names){if(!Ae.includes(m.name)){n(m.span,`"settlement" has no archetype named ${m.name}; it offers ${Ae.join(", ")}`);continue}s.has(m.name)&&r(m.span,`${m.name} is imported more than once`),s.set(m.name,m.span)}}let u=new Map,w=(i,m)=>{if(i.name==="platform"||i.name==="escrow")return n(i.span,`the name ${i.name} is reserved: the platform and each settlement's escrow are always present without being declared`),!1;let c=u.get(i.name);return c?(n(i.span,`the name ${i.name} is already taken by a ${c.kind}; every party, asset, settlement, and port needs its own name`),!1):Qe.test(i.name)?(u.set(i.name,{kind:m,span:i.span}),!0):(n(i.span,`${m} names are snake_case; "${i.name}" is not`),!1)},v=new Map,P=new Map;for(let i of e.decls){if(i.kind==="party"){if(!w(i.name,"party"))continue;if(!Xe.includes(i.partyKind.name)){n(i.partyKind.span,`a party is a ${Xe.join(" or a ")}; "${i.partyKind.name}" is neither`);continue}i.attrs&&n(i.attrs.span,`party ${i.name.name} takes no attribute block yet`),v.set(i.name.name,{kind:i.partyKind.name,name:i.name.name,origin:i.span})}if(i.kind==="asset"){if(!w(i.name,"asset"))continue;if(!Ze.includes(i.assetKind.name)){n(i.assetKind.span,`an asset is one of ${Ze.join(", ")}; "${i.assetKind.name}" is none of those`);continue}let m="on_platform";for(let c of i.attrs?.entries??[]){if(c.key.name!=="title_transfer"){n(c.key.span,`asset ${i.name.name} does not understand "${c.key.name}"; the only attribute is title_transfer`);continue}let y=c.value;y.kind==="ident"&&(y.name==="off_platform"||y.name==="on_platform")?m=y.name:n(y.span,"title_transfer is either on_platform or off_platform")}P.set(i.name.name,{kind:i.assetKind.name,name:i.name.name,origin:i.span,titleTransfer:m})}}let _=e.decls.filter(i=>i.kind==="port"),g=e.decls.filter(i=>i.kind==="settlement");for(let i of g)w(i.name,"settlement");let C=new Set;for(let i of _)w(i.name,"port")&&C.add(i.name.name);let D=(i,m,c)=>{let y=new Map;for(let d of i.entries){if(!m.includes(d.key.name)){n(d.key.span,`${c} does not understand "${d.key.name}"; it takes ${m.join(", ")}`);continue}if(y.has(d.key.name)){n(d.key.span,`${c} sets ${d.key.name} twice`);continue}y.set(d.key.name,d)}return y},I=(i,m)=>{i.qualifiers.length>0&&n(i.span,`${i.key.name} on ${m} takes no ( ... ) qualifier`)},Z=new Set,ee=(i,m)=>{if(i.kind==="ident"&&v.has(i.name))return Z.add(i.name),i.name;n(i.span,i.kind==="ident"?`${m} must name a declared party; there is no party named ${i.name}`:`${m} must name a declared party`)},te=new Set,q=[],h=new Set(["currency","feeAmount","repayableAmount","serviceFeeAmount","clawbackAt"]),T=[/^piece\d+Amount$/,/^installment\d+Amount$/,/^repayment\d+Amount$/,/^carve(?:Hold|Recourse\d+)Id$/,/ShareAmount$/,/AccountId$/],J=(i,m,c)=>h.has(i)||T.some(y=>y.test(i))?(n(m,`${c} names a field ${i}, but the compiler reserves that name for a generated field; pick another name`),!0):!1,A=(i,m)=>{if(!i)return;I(i,m);let c=i.value;if(c.kind==="binding"&&c.type.kind==="call"&&c.type.callee.name==="money"&&c.type.args.length===1&&c.type.args[0]?.kind==="ident"){let y=c.type.args[0].name;if(!ve.test(c.name.name))n(c.name.span,`the ${i.key.name} field is a camelCase name like price; "${c.name.name}" is not`);else if(!xn.test(y))n(c.type.args[0].span,`"${y}" is not a currency code; use three capital letters like SAR`);else if(!J(c.name.name,c.name.span,m))return{currency:y,name:c.name.name,origin:c.span};return}n(c.span,`${m} declares ${i.key.name} as a typed field, like: ${i.key.name}: price: money(SAR)`)},R=(i,m,c,y=!1)=>{if(!i)return;I(i,m);let d=i.value;if(d.kind!=="port_ref"){n(d.span,`${m} needs a ${c} decision, like: ${i.key.name}: port ${i.key.name}_decided`);return}if(d.within){n(d.within.span,`${i.key.name} on ${m} has no time window; only dispute accepts "within <duration>"`);return}if(d.deadline&&!y){n(d.deadline.span,`${i.key.name} on ${m} has no date default; only a held payment's release falls back to a date`);return}if(!C.has(d.name.name)){n(d.name.span,`${m} decides ${c} through port ${d.name.name}, but no port with that name is declared`);return}let k;if(d.deadline){if(!ve.test(d.deadline.name)){n(d.deadline.span,`at( ... ) names a camelCase date field, like at(releaseDueAt); "${d.deadline.name}" is not`);return}if(J(d.deadline.name,d.deadline.span,m))return;k=d.deadline.name}return te.add(d.name.name),{...k?{deadlineField:k}:{},origin:d.span,port:d.name.name}},N=(i,m,c="dispute")=>{if(!i)return;I(i,m);let y=i.value;if(y.kind!=="port_ref"){n(y.span,`${m} needs one ${c} decision through a fixed windowed port`);return}if(!C.has(y.name.name)){n(y.name.span,`${m} routes ${c} through port ${y.name.name}, but no port with that name is declared`);return}if(!y.within){n(y.span,`${m} ${c} needs a fixed window, like: ${i.key.name}: port ${y.name.name} within P14D`);return}let d=y.within.name,k=/^P([1-9]\d{0,3})([DW])$/.exec(d);if(!k){n(y.within.span,`${c} on ${m} uses a fixed duration in days or weeks, like P14D; calendar months cannot define an exact money deadline`);return}let L=Number(k[1]),j=k[2]==="W"?L*7:L;return te.add(y.name.name),{origin:y.span,port:y.name.name,window:{days:j,raw:d}}},M=(i,m,c)=>{if(i){if(I(i,m),i.value.kind!=="percent"){n(i.value.span,`${c} on ${m} must be a percent`);return}if(i.value.bps>=xe){n(i.value.span,`a ${i.value.raw}% ${c} consumes the whole amount; it stays under 100%`);return}return i.value.bps===0&&r(i.value.span,`${c} on ${m} is 0%; drop the entry if none is meant`),i.value.bps}},oe=(i,m,c,y)=>{let d=[];if(!i)return d;if(I(i,m),i.value.kind!=="block")return n(i.value.span,"fees is a block of party shares, like: fees { buyer: 1% }"),d;for(let k of i.value.entries){let L=k.key.name;if(L!==c&&L!==y){n(k.key.span,`fees are borne by this settlement's payer or payee; ${L} is neither`);continue}if(d.some(j=>j.bearer===L)){n(k.key.span,`${m} sets a fee for ${L} twice`);continue}if(k.value.kind!=="percent"){n(k.value.span,`the fee for ${L} must be a percent`);continue}if(k.value.bps>=xe){n(k.value.span,`a ${k.value.raw}% fee consumes the whole amount; fees stay under 100%`);continue}k.value.bps===0&&r(k.value.span,`the fee for ${L} is 0%; drop the entry if no fee is meant`),d.push({bearer:L,bps:k.value.bps,origin:k.span})}return d},de=(i,m,c)=>{let y=[];if(!i)return y;if(I(i,m),i.value.kind!=="block")return n(i.value.span,"fees is a block of exact on-top money fields, like: fees { buyer: buyerFee: money(SAR) }"),y;for(let d of i.value.entries){let k=d.key.name;if(!c.includes(k)){n(d.key.span,`swap fees are borne by one of its two parties; ${k} is not in between`);continue}if(y.some(j=>j.bearer===k)){n(d.key.span,`${m} sets a fee for ${k} twice`);continue}let L=A(d,`${m} fee for ${k}`);L&&y.push({amount:L,bearer:k})}return y},pe=(i,m,c,y,d)=>{if(i.value.kind!=="block"){n(i.value.span,`${i.key.name} on ${m} is a block of percent shares, like: { ${c[0]??"party"}: 100% }`);return}let k=[],L,j=0,p=!0;for(let f of i.value.entries){let b=f.key.name;if(b==="remainder_to"){if(!d){n(f.key.span,`${m} does not take remainder_to here; the first share carries the integer remainder`),p=!1;continue}if(f.value.kind!=="ident"){n(f.value.span,"remainder_to names one of the recipients"),p=!1;continue}if(L){n(f.key.span,`${m} sets remainder_to twice`),p=!1;continue}L={name:f.value.name,span:f.value.span};continue}if(!c.includes(b)){n(f.key.span,`the ${i.key.name} split goes to ${y}; ${b} is not among them`),p=!1;continue}if(Z.add(b),k.some($=>$.to===b)){n(f.key.span,`${m} splits to ${b} twice`),p=!1;continue}if(f.value.kind!=="percent"){n(f.value.span,`the share for ${b} must be a percent`),p=!1;continue}if(f.value.bps===0){n(f.value.span,`the share for ${b} is 0%; drop ${b} from the split instead of giving it nothing`),p=!1;continue}k.push({bps:f.value.bps,origin:f.span,to:b}),j+=f.value.bps}if(p&&j!==xe&&(n(i.value.span,`the ${i.key.name} split must account for exactly 100%; these shares total ${(j/100).toFixed(2).replace(/\.?0+$/,"")}%`),p=!1),L&&!k.some(f=>f.to===L?.name)&&(n(L.span,`remainder_to must name one of the split's recipients; ${L.name} holds no share`),p=!1),!(!p||k.length===0))return{...L?{remainderTo:L.name}:{},shares:k}},me=(i,m,c,y)=>{if(!i)return;let d=i.qualifiers[0];if(i.qualifiers.length!==1||d?.name!=="funded"){n(i.span,"on_cancel states the phase it covers; today that is on_cancel(funded)");return}let k=pe(i,m,c,y,!1);if(k)return{origin:i.span,shares:k.shares,when:"funded"}},fe=(i,m)=>{if(i){if(I(i,m),i.value.kind==="ident"&&ve.test(i.value.name))return J(i.value.name,i.value.span,m)?void 0:i.value.name;n(i.value.span,`${i.key.name} on ${m} names a camelCase date field, like: ${i.key.name}: dueDate`)}},_e=(i,m)=>{if(i){if(I(i,m),i.value.kind==="ident"&&ve.test(i.value.name))return J(i.value.name,i.value.span,m)?void 0:i.value.name;n(i.value.span,`${i.key.name} on ${m} names a camelCase lineage field, like: ${i.key.name}: captureReference`)}},G=(i,m,c,y)=>i?(I(i,m),i.value.kind==="ident"&&i.value.name===c?!0:(n(i.value.span,`${i.key.name} on ${m} is ${c}; ${y}`),!1)):!1,vn=(i,m,c,y,d)=>{if(!i)return;I(i,m);let k=i.value.kind==="number"?Number(i.value.raw):Number.NaN;if(Number.isInteger(k)&&k>=y&&k<=d)return k;n(i.value.span,`${c} on ${m} is a literal integer from ${y} through ${d}`)},wn=(i,m,c,y,d)=>{if(!i)return;if(I(i,m),i.value.kind!=="list"||i.value.items.length<y||i.value.items.length>d){n(i.value.span,`${c} on ${m} lists ${y} through ${d} declared parties`);return}let k=i.value.items.map(L=>ee(L,`${m} ${c}`)).filter(L=>L!==void 0);if(new Set(k).size!==k.length){n(i.value.span,`${c} on ${m} must not repeat a party`);return}return k.length===i.value.items.length?k:void 0},Ve=(i,m,c,y=12)=>{let d=i.get("count"),k=i.get("every"),L;if(d){I(d,m);let f=d.value,b=f.kind==="number"?Number(f.raw):Number.NaN;Number.isInteger(b)&&b>=2&&b<=y?L=b:n(f.span,`count on ${m} is a literal number of anchors between 2 and ${y}; the schedule stays finite by construction`)}let j;if(k){I(k,m);let f=k.value,b=f.kind==="ident"?f.name:f.kind==="string"?f.value:void 0,$=b?/^P([1-9]\d{0,3})([DW])$/.exec(b):null;if($&&b){let F=Number($[1]);j={days:$[2]==="W"?F*7:F,raw:b}}else n(f.span,`every on ${m} is a fixed duration in days or weeks, like P30D or P2W; calendar months drift and cannot anchor an exact schedule`)}let p=fe(i.get("first_due"),m);if(!(L===void 0||!j||!p))return{count:L,every:j,firstDueField:p,origin:c}},We=(i,m)=>{I(i,m);let c=i.value;if(c.kind!=="settlement_ref"){n(c.span,`${m} draws against a held payment's release, like: against: retention.release`);return}let y=c.owner.name,d=g.find(j=>j.name.name===y);if(!d){let j=u.get(y);n(c.owner.span,j?`${m} references ${y}, which is a ${j.kind}; settlement exits belong to settlements`:`${m} references ${y}, but no settlement with that name is declared`);return}let k=d.archetype.name;if(!Ae.includes(k))return;let L=le[k].referenceableExits;if(!L.includes(c.member.name)){let j=L.length>0?`it exposes ${L.join(", ")}`:"it exposes no referenceable exits";n(c.member.span,`${m} references ${y}.${c.member.name}, but ${k} does not expose that exit; ${j}`);return}return{exit:c.member.name,origin:c.span,settlement:y,targetArchetype:k}},ot=(i,m,c)=>{let y=i.get("against"),d=An.filter(L=>i.has(L));if(y&&d.length>0){n(y.span,`${m} is repaid by a carve and by its own schedule (${d.join(", ")}); an advance draws on one source`);return}if(!y){if(d.length===0){n(c,`${m} needs a repayment source: against: <hold>.release carves it out of a hold's release, or count + every + first_due collects it on a schedule`);return}for(let j of An)i.has(j)||n(c,`${m} is missing ${j}`);let L=Ve(i,m,c);return L?{kind:"schedule",schedule:L}:void 0}let k=We(y,m);return k?{kind:"carve",...k}:void 0};for(let i of g){let m=i.archetype.name;if(!s.has(m)){n(i.archetype.span,Ae.includes(m)?`${m} must be imported first: import { ${m} } from "settlement"`:`there is no settlement archetype named ${m}`);continue}let c=`settlement ${i.name.name}`,y=le[m],d=D(i.body,[...y.keys,"derived_amount"],c);for(let p of y.required)d.has(p)||n(i.span,`${c} is missing ${p}`);let k=(p,f)=>{let b=d.get(p);if(b)return I(b,c),ee(b.value,`${c} ${f}`)},L=(p,f,b)=>p&&f&&p===f?(n(i.span,`${c} ${b}`),!1):!0,j=d.get("derived_amount");if(j)if(I(j,c),j.value.kind!=="block")n(j.value.span,"derived_amount is a block with field, source, rule, and bearer");else{let p=D(j.value,["field","source","rule","bearer"],`${c} derived_amount`);for(let K of["field","source","rule","bearer"])p.has(K)||n(j.span,`${c} derived_amount is missing ${K}`);let f=p.get("field")?.value,b=p.get("source")?.value,$=p.get("rule")?.value,F=p.get("bearer")?.value,S=f?.kind==="ident"?f.name:void 0,O=b?.kind==="ident"?b.name:void 0,z=F?ee(F,`${c} derived amount bearer`):void 0;f&&f.kind!=="ident"&&n(f.span,"derived amount field must be a camelCase identifier"),b&&b.kind!=="ident"&&n(b.span,"derived amount source must name one stored money field"),$&&$.kind!=="percent"&&n($.span,"derived_amount proves percentage-of rules only; fixed and tiered rules are refused"),$?.kind==="percent"&&($.bps<=0||$.bps>=xe)&&n($.span,"derived amount percentage must be above 0% and below 100%"),S&&!ve.test(S)&&n(f.span,`derived amount field ${S} must be camelCase`),O&&!ve.test(O)&&n(b.span,`derived amount source ${O} must be camelCase`),S&&O&&S===O&&n(j.span,"derived amount field must differ from its source field"),S&&O&&z&&$?.kind==="percent"&&$.bps>0&&$.bps<xe&&o.push({baseField:O,bearer:z,bps:$.bps,field:S,origin:j.span,settlement:i.name.name})}switch(m){case"captured_payment":{let p=k("payer","payer"),f=k("payee","payee"),b=L(p,f,`pays ${p} from ${p}; payer and payee must differ`),$=A(d.get("amount"),c),F=fe(d.get("reserve_until"),c),S=R(d.get("correction"),c,"payee correction"),O=N(d.get("external_reversal"),c,"external reversal"),z=G(d.get("capture_mode"),c,"partial_then_full","capture calls must leave a remainder and settle posts the final remainder"),K=G(d.get("correction_mode"),c,"full_only","repeated partial corrections are not representable yet, so the checker refuses them"),X=G(d.get("negative_position"),c,"reject","a correction or reversal must fail when the payee cannot fund it"),ae=G(d.get("timeout"),c,"reject","a timeout records no money movement; only a confirmed decision may reverse funds");if(d.has("fees")&&n(d.get("fees").span,`${c} does not price fees inside captured_payment; compose a separate fee settlement so capture and correction amounts stay exact`),$&&F===$.name){n(d.get("reserve_until")?.span??i.span,`${c} uses ${$.name} as both the reserved amount and reserve_until date field; they need distinct names`);break}p&&f&&$&&F&&S&&O&&z&&K&&X&&ae&&b&&q.push({amount:$,archetype:"captured_payment",correction:S,externalReversal:O,name:i.name.name,origin:i.span,payee:f,payer:p,reserveUntilField:F});break}case"settlement_batch":{let p=k("settlement_account","settlement account"),f=k("payout_destination","payout destination"),b=L(p,f,`routes payout from ${p} back to itself; settlement account and payout destination must differ`),$=_e(d.get("source_capture_refs"),c),F=_e(d.get("fee_entries"),c),S=_e(d.get("external_reversal_offsets"),c),O=fe(d.get("close_trigger"),c),z=R(d.get("payout_acknowledgement"),c,"payout acknowledgement"),K=_e(d.get("payout_beneficiary_ref"),c),X=G(d.get("negative_position"),c,"reject","offsets beyond gross capture entries must stop calculation and post no payout"),ae=[$,F,S,O,K].filter(Y=>Y!==void 0);if(new Set(ae).size!==ae.length){n(i.span,`${c} needs distinct source_capture_refs, fee_entries, external_reversal_offsets, close_trigger, and payout_beneficiary_ref field names`);break}p&&f&&$&&F&&S&&O&&z&&K&&X&&b&&q.push({archetype:"settlement_batch",closeTriggerField:O,externalReversalReferenceField:S,feeReferenceField:F,name:i.name.name,origin:i.span,payoutDestination:f,payoutAcknowledgement:z,payoutBeneficiaryReferenceField:K,settlementAccount:p,sourceCaptureReferenceField:$});break}case"funding_round":{let p=k("contributor","contributor"),f=k("beneficiary","beneficiary"),b=A(d.get("target"),c),$=A(d.get("commitment"),c),F=vn(d.get("max_contributors"),c,"max_contributors",2,1e4),S=fe(d.get("close_by"),c),O=[G(d.get("close_policy"),c,"threshold","close must follow the locked committed sum at the stored close date"),G(d.get("overfund_policy"),c,"reject","a commitment past the remaining target headroom must refuse"),G(d.get("cancel_policy"),c,"before_close","a commitment may cancel only while its parent remains open"),G(d.get("fail_policy"),c,"whole_commitment_refund","failure refunds each stored commitment whole")].every(Boolean),z=L(p,f,`uses ${p} as both contributor and beneficiary; the roles must differ`);b&&$&&b.currency!==$.currency&&n($.origin,`${c} mixes ${b.currency} and ${$.currency}; target and commitment need one currency`),b&&$&&b.name===$.name&&n($.origin,`${c} uses ${b.name} for both target and commitment; the parent and child amounts need distinct fields`),p&&f&&b&&$&&b.currency===$.currency&&b.name!==$.name&&F&&S&&O&&z&&q.push({archetype:"funding_round",beneficiary:f,cancelPolicy:"before_close",closeByField:S,closePolicy:"threshold",commitment:$,contributor:p,failPolicy:"whole_commitment_refund",maxContributors:F,name:i.name.name,origin:i.span,overfundPolicy:"reject",target:b});break}case"weighted_distribution":{let p=k("source","source"),f=k("recipient","recipient template"),b=A(d.get("amount"),c),$=A(d.get("weight"),c),F=vn(d.get("max_recipients"),c,"max_recipients",2,1e4),S=fe(d.get("record_at"),c),O=R(d.get("snapshot"),c,"entitlement snapshot"),z=[G(d.get("rounding_policy"),c,"largest_remainder","floor shares use a deterministic largest-remainder allocation with noun id as the tie-break"),G(d.get("withholding_policy"),c,"refuse","withholding needs its own proved retained-amount mechanism"),G(d.get("correction_policy"),c,"new_distribution","post-payout correction is a new linked distribution, never a rewrite or caller amount")].every(Boolean),K=L(p,f,`uses ${p} as both source and recipient; the roles must differ`);b&&$&&b.currency!==$.currency&&n($.origin,`${c} mixes ${b.currency} and ${$.currency}; pool and stored weights need one denomination`),b&&$&&b.name===$.name&&n($.origin,`${c} uses ${b.name} for both pool and weight; the fields must differ`),p&&f&&b&&$&&b.currency===$.currency&&b.name!==$.name&&F&&S&&O&&z&&K&&q.push({amount:b,archetype:"weighted_distribution",correctionPolicy:"new_distribution",maxRecipients:F,name:i.name.name,origin:i.span,recipient:f,recordAtField:S,roundingPolicy:"largest_remainder",snapshot:O,source:p,weight:$,withholdingPolicy:"refuse"});break}case"credit_facility":{let p=k("lender","lender"),f=k("borrower","borrower"),b=k("draw_destination","draw destination"),$=A(d.get("limit"),c),F=fe(d.get("expires_at"),c),S=d.get("obligation"),O=S?We(S,c):void 0,z=d.get("availability_policy"),K;z?.value.kind==="ident"&&(z.value.name==="revolving"||z.value.name==="non_revolving")?K=z.value.name:z&&n(z.value.span,`availability_policy on ${c} is revolving or non_revolving; the factpack does not justify an implicit choice`);let X=[G(d.get("expiry_policy"),c,"freeze_draws","expiry stops new draws without closing linked debt"),G(d.get("close_policy"),c,"no_open_draws","the facility closes only after every linked obligation resolves")].every(Boolean),ae=[L(p,f,`uses ${p} as both lender and borrower; the roles must differ`),L(p,b,`draws back to its lender ${p}; draw_destination must differ`)].every(Boolean);p&&f&&b&&$&&F&&O&&K&&X&&ae&&q.push({archetype:"credit_facility",availabilityPolicy:K,borrower:f,closePolicy:"no_open_draws",drawDestination:b,expiresAtField:F,expiryPolicy:"freeze_draws",lender:p,limit:$,name:i.name.name,obligation:O,origin:i.span});break}case"recurring_collection":{let p=d.get("obligation"),f=p?We(p,c):void 0,b=R(d.get("mandate"),c,"mandate evidence"),$=[G(d.get("attempt_policy"),c,"explicit","every attempt is a separate receipted call"),G(d.get("period_idempotency"),c,"obligation_and_anchor","the parent obligation and stored anchor form the period identity"),G(d.get("retry_policy"),c,"explicit_attempt","PRINCIPLES.md bans hidden retries; a retry needs a new explicit idempotency key"),G(d.get("failure_policy"),c,"parent_delinquency","the scheduled obligation owns due state and delinquency")].every(Boolean);f&&b&&$&&q.push({archetype:"recurring_collection",attemptPolicy:"explicit",failurePolicy:"parent_delinquency",mandate:b,name:i.name.name,obligation:f,origin:i.span,periodIdempotency:"obligation_and_anchor",retryPolicy:"explicit_attempt"});break}case"conditional_disbursement":{let p=k("source","source"),f=k("destination","destination"),b=A(d.get("cap"),c),$=A(d.get("amount"),c),F=R(d.get("decision"),c,"capped disbursement decision"),S=[G(d.get("reopen_policy"),c,"refuse","a closed decision cannot be reopened; create a new linked disbursement"),G(d.get("recovery_policy"),c,"separate_transfer","recovery is a new money movement with its own receipt")].every(Boolean),O=L(p,f,`pays ${p} from itself; source and destination must differ`);b&&$&&b.currency!==$.currency&&n($.origin,`${c} mixes ${b.currency} and ${$.currency}; cap and approved amount need one currency`),b&&$&&b.name===$.name&&n($.origin,`${c} uses ${b.name} for both cap and approved amount; the fields must differ`),p&&f&&b&&$&&b.currency===$.currency&&b.name!==$.name&&F&&S&&O&&q.push({amount:$,archetype:"conditional_disbursement",cap:b,decision:F,destination:f,name:i.name.name,origin:i.span,recoveryPolicy:"separate_transfer",reopenPolicy:"refuse",source:p});break}case"rotating_pool":{let p=wn(d.get("members"),c,"members",2,5),f=wn(d.get("payout_order"),c,"payout_order",2,5),b=A(d.get("contribution"),c),$=Ve(d,c,i.span,12),F=d.has("guarantor")?k("guarantor","guarantor"):void 0,S=[G(d.get("default_policy"),c,"due_condition","default follows an unmet stored contribution due condition"),G(d.get("guarantee_policy"),c,"funded_only","a guarantee changes money only through an explicit funded contribution"),G(d.get("exit_policy"),c,"before_activation_only","membership and order freeze before the first contribution")].every(Boolean),O=!0;if(p&&f){let z=new Set(p);(f.length!==p.length||f.some(K=>!z.has(K)))&&(n(d.get("payout_order")?.span??i.span,`${c} payout_order must contain every member exactly once`),O=!1)}p&&$&&$.count!==p.length&&(n(d.get("count")?.span??i.span,`${c} count ${$.count} must equal its ${p.length}-member roster`),O=!1),p&&F&&p.includes(F)&&(n(d.get("guarantor")?.span??i.span,`${c} guarantor must differ from every member`),O=!1),p&&F&&p.length>4&&(n(d.get("members")?.span??i.span,`${c} supports at most 4 members with a guarantor so every generated child binding stays within the 8-entry cap`),O=!1),p&&f&&b&&$&&S&&O&&q.push({archetype:"rotating_pool",contribution:b,defaultPolicy:"due_condition",exitPolicy:"before_activation_only",guaranteePolicy:"funded_only",...F?{guarantor:F}:{},members:p,name:i.name.name,origin:i.span,payoutOrder:f,schedule:$});break}case"swap":{let p=d.get("between"),f,b;p&&(I(p,c),p.value.kind!=="list"||p.value.items.length!==2?n(p.value.span,`${c} swaps between exactly two parties, like: between: [buyer, seller]`):(f=ee(p.value.items[0],`${c} first side`),b=ee(p.value.items[1],`${c} second side`),L(f,b,`names ${f} on both sides; the two swap parties must differ`)));let $=new Map,F=d.get("amounts");if(F)if(I(F,c),F.value.kind!=="block")n(F.value.span,`${c} amounts is a two-party block, like: amounts { buyer: buyerPays: money(SAR), seller: sellerPays: money(SAR) }`);else for(let Y of F.value.entries){let ne=Y.key.name;if(ne!==f&&ne!==b){n(Y.key.span,`${c} amount belongs to one of its two parties; ${ne} is not in between`);continue}if($.has(ne)){n(Y.key.span,`${c} declares more than one amount for ${ne}`);continue}let ie=A(Y,c);ie&&$.set(ne,ie)}let S=f?$.get(f):void 0,O=b?$.get(b):void 0;f&&!S&&n(F?.span??i.span,`${c} needs exactly one funded amount for ${f}`),b&&!O&&n(F?.span??i.span,`${c} needs exactly one funded amount for ${b}`),S&&O&&S.currency!==O.currency&&n(F?.span??i.span,`${c} cannot link ${S.currency} and ${O.currency} in one atomic ledger batch; both amounts need one currency`);let z=R(d.get("release"),c,"whole-trade release"),K=N(d.get("dispute"),c),X=de(d.get("fees"),c,[f,b]),ae=[S,O].filter(Y=>Y!==void 0);for(let Y of X)(ae.some(ne=>ne.name===Y.amount.name)||X.some(ne=>ne!==Y&&ne.amount.name===Y.amount.name))&&n(Y.amount.origin,`${c} fee field ${Y.amount.name} must be distinct from both principal and fee fields`),S&&Y.amount.currency!==S.currency&&n(Y.amount.origin,`${c} fee field ${Y.amount.name} must use the trade currency ${S.currency}`);if(f&&b&&S&&O&&S.currency===O.currency&&z){let Y=X.find(ie=>ie.bearer===f),ne=X.find(ie=>ie.bearer===b);q.push({archetype:"swap",...K?{dispute:K}:{},name:i.name.name,origin:i.span,release:z,sides:[{amount:S,...Y?{fee:Y}:{},party:f},{amount:O,...ne?{fee:ne}:{},party:b}]})}break}case"held_payment":{let p=k("payer","payer"),f=k("payee","payee"),b=L(p,f,`pays ${p} from ${p}; payer and payee must differ`),$=A(d.get("amount"),c),F=R(d.get("release"),c,"release",!0),S=oe(d.get("fees"),c,p,f),O=me(d.get("on_cancel"),c,[p,f].filter(z=>z!==void 0),"this settlement's payer or payee");if($&&F?.deadlineField===$.name){n(F.origin,`${c} uses ${$.name} as both the held amount and the release date field; they need distinct names`);break}p&&f&&$&&F&&b&&q.push({amount:$,archetype:"held_payment",fees:S,name:i.name.name,...O?{onCancel:O}:{},origin:i.span,payee:f,payer:p,release:{origin:F.origin,port:F.port},...F.deadlineField?{releaseDeadlineField:F.deadlineField}:{}});break}case"instant_transfer":{let p=k("payer","payer"),f=k("payee","payee"),b=L(p,f,`pays ${p} from ${p}; payer and payee must differ`),$=A(d.get("amount"),c),F=oe(d.get("fees"),c,p,f);p&&f&&$&&b&&q.push({amount:$,archetype:"instant_transfer",fees:F,name:i.name.name,origin:i.span,payee:f,payer:p});break}case"premium_forward":{let p=k("payer","payer"),f=k("carrier","carrier"),b=L(p,f,`forwards the premium from ${p} to ${p}; payer and carrier must differ`),$=A(d.get("amount"),c),F=R(d.get("bind"),c,"binding"),S=M(d.get("commission"),c,"commission")??0,O=me(d.get("on_cancel"),c,[p,f].filter(ie=>ie!==void 0),"this settlement's payer or carrier"),z=["policy_ref","renewal_due","renewal_policy","endorsement","endorsement_policy","lapse_policy"],K=z.some(ie=>d.has(ie));if(K)for(let ie of z)d.has(ie)||n(i.span,`${c} is missing ${ie}`);let X=K?_e(d.get("policy_ref"),c):void 0,ae=K?fe(d.get("renewal_due"),c):void 0,Y=K?R(d.get("endorsement"),c,"endorsement evidence"):void 0,ne=K?[G(d.get("renewal_policy"),c,"explicit_new_forward","each renewal creates a new premium_forward instead of moving money from policy state"),G(d.get("endorsement_policy"),c,"non_money_only","a money adjustment needs a separate corrected movement"),G(d.get("lapse_policy"),c,"due_condition","lapse follows the stored renewal due condition")].every(Boolean):!0;if(p&&f&&$&&F&&b&&ne&&(!K||X&&ae&&Y)){let ie={amount:$,archetype:"premium_forward",bind:F,carrier:f,commissionBps:S,...Y?{endorsement:Y}:{},...K&&X&&ae&&Y?{endorsementPolicy:"non_money_only",lapsePolicy:"due_condition",policyReferenceField:X,renewalDueField:ae,renewalPolicy:"explicit_new_forward"}:{},name:i.name.name,...O?{onCancel:O}:{},origin:i.span,payer:p};q.push(ie)}break}case"deposit":{let p=k("payer","payer"),f=k("holder","holder"),b=L(p,f,`holds ${p}'s deposit for ${p}; payer and holder must differ`),$=A(d.get("amount"),c),F=R(d.get("claim"),c,"claim"),S=R(d.get("return"),c,"return");if(F&&S&&F.port===S.port){n(S.origin,`${c} claims and returns through the same port ${F.port}; the two exits need their own ports`);break}p&&f&&$&&F&&S&&b&&q.push({amount:$,archetype:"deposit",claim:F,holder:f,name:i.name.name,origin:i.span,payer:p,return:S});break}case"scheduled":{let p=k("payer","payer"),f=k("payee","payee"),b=L(p,f,`pays ${p} from ${p}; payer and payee must differ`),$=A(d.get("amount"),c),F=d.get("mode")?.value,S=F?.kind==="ident"&&F.name==="obligation",O=Ve(d,c,i.span,S?7:12);if($&&O&&$.name===O.firstDueField){n(O.origin,`${c} uses ${$.name} as both the amount and the first_due date field; they need distinct names`);break}let z=d.get("mode"),X=["advance_to","debtor","delinquency_policy","partial_payment","refund_policy","repayment_matching","reschedule_policy"].some(De=>d.has(De));if(!z&&X){n(i.span,`${c} uses obligation policies without mode: obligation`);break}if(!z){p&&f&&$&&O&&b&&q.push({amount:$,archetype:"scheduled",mode:"transfer",name:i.name.name,origin:i.span,payee:f,payer:p,schedule:O});break}if(!G(z,c,"obligation","omit mode for a fixed transfer schedule"))break;let ae=["debtor","partial_payment","repayment_matching","refund_policy","reschedule_policy","delinquency_policy"];for(let De of ae)d.has(De)||n(i.span,`${c} is missing ${De}`);let Y=k("debtor","debtor"),ne=d.has("advance_to")?k("advance_to","advance recipient"):void 0,ie=[G(d.get("partial_payment"),c,"anchor_bound","payments must bind to one stored installment anchor"),G(d.get("repayment_matching"),c,"obligation_and_anchor","each payment must name both the obligation and its installment anchor; fuzzy or balance-wide matching is refused"),G(d.get("refund_policy"),c,"full_payment_only","a refund reverses one stored payment whole so it cannot exceed that payment"),G(d.get("reschedule_policy"),c,"refuse","forward-version carryover is not mechanically proven; create a new obligation after closing this one"),G(d.get("delinquency_policy"),c,"due_condition","delinquency must come from an unmet stored due anchor")].every(Boolean),Re=[L(Y,f,`${c} names ${Y} as both debtor and settlement recipient; they must differ`),ne?L(ne,Y,`${c} advances to its debtor ${Y}; advance_to must name a distinct recipient`):!0].every(Boolean);p&&f&&$&&O&&b&&Y&&ie&&Re&&q.push({...ne?{advanceTo:ne}:{},amount:$,archetype:"scheduled",debtor:Y,mode:"obligation",name:i.name.name,origin:i.span,payee:f,payer:p,schedule:O});break}case"advance":{let p=k("funder","funder"),f=k("to","advanced party"),b=L(p,f,`advances ${p} their own money; funder and advanced party must differ`),$=A(d.get("amount"),c),F=M(d.get("fee"),c,"fee")??0,S=ot(d,c,i.span);if($&&S?.kind==="schedule"&&$.name===S.schedule.firstDueField){n(S.schedule.origin,`${c} uses ${$.name} as both the amount and the first_due date field; they need distinct names`);break}p&&f&&$&&S&&b&&q.push({advanced:f,amount:$,archetype:"advance",feeBps:F,funder:p,name:i.name.name,origin:i.span,source:S});break}case"metered":{let p=k("payer","payer"),f=k("payee","payee"),b=L(p,f,`meters ${p} against ${p}; payer and payee must differ`),$=fe(d.get("close_by"),c),F=[],S=d.get("rates"),O=!0;if(S)if(I(S,c),S.value.kind!=="block")n(S.value.span,"rates is a block of per-unit prices, like: rates { api_call: unitFee: money(SAR) }");else{let z=le.metered.maxRates??le.metered.eventCap;S.value.entries.length>z&&(n(S.value.span,`${c} prices ${S.value.entries.length} meters, but metered allows at most ${z} so one settlement stays within its ${le.metered.eventCap}-event cap`),O=!1);for(let K of S.value.entries){if(!Qe.test(K.key.name)){n(K.key.span,`meter names are snake_case; "${K.key.name}" is not`);continue}if(F.some(Y=>Y.meter===K.key.name)){n(K.key.span,`${c} prices meter ${K.key.name} twice`);continue}let X=A(K,c);if(!X)continue;if(F.some(Y=>Y.field.name===X.name)){n(X.origin,`${c} reuses the field ${X.name} for two meters`);continue}let ae=F[0]?.field.currency;if(ae&&ae!==X.currency){n(X.origin,`${c} mixes ${ae} and ${X.currency}; one settlement meters in one currency`);continue}F.push({field:X,meter:K.key.name,origin:K.span})}S.value.entries.length===0&&n(S.value.span,`${c} prices no meters`)}if($&&F.some(z=>z.field.name===$)){n(i.span,`${c} uses ${$} as both a rate field and the close_by date field; they need distinct names`);break}p&&f&&$&&F.length>0&&b&&O&&q.push({archetype:"metered",closeByField:$,name:i.name.name,origin:i.span,payee:f,payer:p,rates:F});break}case"pooled_split":{let p=k("payer","payer"),f=A(d.get("amount"),c),b=fe(d.get("payout_due"),c),$=d.get("split"),F=[...v.keys()].filter(K=>K!==p),S=$?pe($,c,F,"declared parties other than the funder",!0):void 0;if(S&&S.shares.length<2){n($.value.span,`${c} splits to a single recipient; a pool distributes between at least two`);break}let O=le.pooled_split.maxRecipients??Math.floor(le.pooled_split.eventCap/2),z=!S||S.shares.length<=O;if(z||n($.value.span,`${c} splits to ${S.shares.length} recipients, but pooled_split allows at most ${O} so funding and payout stay within its ${le.pooled_split.eventCap}-event cap`),S){let K=new Map;for(let X of S.shares){let[ae="",...Y]=X.to.split("_"),ne=`${ae+Y.map(Re=>Re.charAt(0).toUpperCase()+Re.slice(1)).join("")}ShareAmount`,ie=K.get(ne);ie&&n(X.origin,`${c} splits to ${ie} and ${X.to}, whose generated share fields both come out as ${ne}; rename one party`),K.set(ne,X.to)}}if(f&&b&&f.name===b){n(i.span,`${c} uses ${f.name} as both the amount and the payout_due date field; they need distinct names`);break}p&&f&&b&&S&&z&&q.push({amount:f,archetype:"pooled_split",distributeDueField:b,name:i.name.name,origin:i.span,payer:p,remainderTo:S.remainderTo??S.shares[0].to,shares:S.shares});break}}}let Ge=[];for(let i of _){let m=`port ${i.name.name}`,c=D(i.body,["allowed","shape"],m);c.has("allowed")||n(i.span,`${m} is missing allowed`);let y=[],d=c.get("allowed");if(d){I(d,m);let j=d.value;if(j.kind!=="list"||j.items.length===0)n(j.span,"allowed lists who may ask this question, like: allowed: [buyer]");else for(let p of j.items){let f=ee(p,`${m} allowed`);if(f){if(y.includes(f)){n(p.span,`${m} allows ${f} twice`);continue}y.push(f)}}}let k=[],L=c.get("shape");if(L)if(I(L,m),L.value.kind!=="block")n(L.value.span,"shape is a block of typed fields, like: shape { vehicleId: id(vehicle) }");else for(let j of L.value.entries){if(!ve.test(j.key.name)){n(j.key.span,`shape fields are camelCase names; "${j.key.name}" is not`);continue}if(k.some(f=>f.name===j.key.name)){n(j.key.span,`${m} declares ${j.key.name} twice`);continue}let p=st(j.value);if(!p){n(j.value.span,`${j.key.name} needs a type: id(<asset>), money(<CUR>), text, or date`);continue}if(p.kind==="asset_id"&&!P.has(p.asset)){n(j.value.span,`id(${p.asset}) points at an asset that is not declared`);continue}if(p.kind==="money"&&!xn.test(p.currency)){n(j.value.span,`"${p.currency}" is not a currency code; use three capital letters like SAR`);continue}k.push({name:j.key.name,origin:j.span,type:p})}y.length>0&&Ge.push({allowed:y,fields:k,name:i.name.name,origin:i.span})}let ye=new Map(Ge.map(i=>[i.name,i]));for(let i of q){if(i.archetype==="captured_payment"){let y=ye.get(i.correction.port);y&&(y.allowed.length!==1||y.allowed[0]!==i.payee)&&n(y.origin,`captured_payment ${i.name} correction port ${y.name} must allow only its payee ${i.payee}`);let d=ye.get(i.externalReversal.port);d&&!d.fields.some(k=>k.name==="externalReference"&&k.type.kind==="text")&&n(d.origin,`captured_payment ${i.name} external reversal port ${d.name} needs shape { externalReference: text }`);continue}if(i.archetype==="settlement_batch"){let y=ye.get(i.payoutAcknowledgement.port);y&&!y.fields.some(d=>d.name==="acknowledgementReference"&&d.type.kind==="text")&&n(y.origin,`settlement_batch ${i.name} payout acknowledgement port ${y.name} needs shape { acknowledgementReference: text }`);continue}if(i.archetype==="weighted_distribution"){let y=ye.get(i.snapshot.port);y&&!y.fields.some(d=>d.name==="evidenceReference"&&d.type.kind==="text")&&n(y.origin,`weighted_distribution ${i.name} snapshot port ${y.name} needs shape { evidenceReference: text }`);continue}if(i.archetype==="recurring_collection"){let y=ye.get(i.mandate.port);y&&!y.fields.some(d=>d.name==="evidenceReference"&&d.type.kind==="text")&&n(y.origin,`recurring_collection ${i.name} mandate port ${y.name} needs shape { evidenceReference: text }`);continue}if(i.archetype==="conditional_disbursement"){let y=ye.get(i.decision.port);y&&(!y.fields.some(d=>d.name==="evidenceReference"&&d.type.kind==="text")||y.allowed.length!==1||y.allowed[0]!==i.source)&&n(y.origin,`conditional_disbursement ${i.name} decision port ${y.name} must allow only ${i.source} and needs shape { evidenceReference: text }`);continue}if(i.archetype==="premium_forward"&&i.endorsement){let y=ye.get(i.endorsement.port);y&&!y.fields.some(d=>d.name==="evidenceReference"&&d.type.kind==="text")&&n(y.origin,`premium_forward ${i.name} endorsement port ${y.name} needs shape { evidenceReference: text }`);continue}if(i.archetype!=="swap")continue;let m=new Set(i.sides.map(y=>y.party)),c=[{label:"release",portRef:i.release},...i.dispute?[{label:"dispute",portRef:i.dispute}]:[]];for(let y of c){let d=ye.get(y.portRef.port);if(d)for(let k of d.allowed)m.has(k)||n(d.origin,`swap ${i.name} ${y.label} port ${d.name} allows ${k}, but whole-trade decisions belong only to ${i.sides.map(L=>L.party).join(" or ")}`)}}let at=new Map(q.filter(i=>i.archetype==="scheduled"&&i.mode==="obligation").map(i=>[i.name,i])),kn=new Map;for(let i of q){if(i.archetype!=="credit_facility"&&i.archetype!=="recurring_collection")continue;let m=at.get(i.obligation.settlement),c=`settlement ${i.name}`;if(!m){n(i.obligation.origin,`${c} must compose with scheduled in mode: obligation; ${i.obligation.settlement} is not one`);continue}if(i.archetype==="credit_facility"){m.advanceTo&&n(i.obligation.origin,`${c} references ${m.name}, which already owns an advance; facility draws and obligation repayment must have one disbursement owner`),(m.payee!==i.lender||m.debtor!==i.borrower||m.amount.currency!==i.limit.currency)&&n(i.obligation.origin,`${c} must link an obligation whose payee is ${i.lender}, debtor is ${i.borrower}, and currency is ${i.limit.currency}`);continue}let y=ye.get(i.mandate.port),d=kn.get(m.name);d?n(i.obligation.origin,`${c} and settlement ${d} both collect ${m.name}; one obligation may have one collection policy owner`):kn.set(m.name,i.name),y&&(y.allowed.length!==1||y.allowed[0]!==m.payer)&&n(y.origin,`${c} mandate port ${y.name} must allow only the obligation payer ${m.payer}`)}let it=new Map(q.filter(i=>i.archetype==="held_payment").map(i=>[i.name,i])),_n=new Map;for(let i of q){if(i.archetype!=="advance"||i.source.kind!=="carve")continue;let m=`settlement ${i.name}`,c=i.source.settlement,y=i.source.origin;if(i.source.targetArchetype!=="held_payment"||i.source.exit!=="release"){n(y,`${m} can only carve held_payment.release; ${c}.${i.source.exit} is a ${i.source.targetArchetype} exit`);continue}let d=it.get(c);if(!d)continue;if(d.payee!==i.advanced){n(y,`${m} advances ${i.advanced}, but ${c} releases to ${d.payee}; an advance carves the release of the party it finances`);continue}if(d.amount.name!==i.amount.name){n(y,`${m} advances field ${i.amount.name}, but ${c}.release carries ${d.amount.name}; a carve must name the same money field`);continue}if(d.amount.currency!==i.amount.currency){n(y,`${m} advances ${i.amount.currency}, but ${c}.release carries ${d.amount.currency}; a carve must use one currency`);continue}if(i.feeBps>0){n(y,`${m} adds a fee to a carved advance, but ${c}.release can only prove repayment of the principal field; use a fee-free carve or a scheduled advance`);continue}if(d.fees.some(p=>p.bearer===d.payee&&p.bps>0)){n(y,`${m} carves ${c}.release after a payee fee reduces it; a carved hold must release the full principal field to the funder`);continue}if(d.payer===i.funder){n(y,`${i.funder} funds ${c} and finances it too; the party who pays the hold cannot be the funder its release repays`);continue}let k=_n.get(c);if(k){n(y,`${m} and settlement ${k} both draw against ${c}; one release repays one advance`);continue}if(_n.set(c,i.name),q.some(p=>p.archetype==="scheduled"&&p.mode==="transfer"&&p.payer===i.advanced&&p.payee===i.funder&&p.amount.name===i.amount.name&&p.amount.currency===i.amount.currency))continue;let j=`add a scheduled settlement collecting from the ${i.advanced.replaceAll("_"," ")} to the ${i.funder.replaceAll("_"," ")}`;if(d.onCancel){n(y,`${m} has no repayment path when ${c} is refunded instead of released; ${j}`);continue}r(y,`${m} has no repayment path if ${c} is abandoned before it funds; ${j}`)}for(let[i,m]of v)Z.has(i)||r(m.origin,`party ${i} is declared but no settlement or port involves them`);for(let i of _)C.has(i.name.name)&&!te.has(i.name.name)&&r(i.span,`port ${i.name.name} is declared but nothing releases through it`);for(let[i,m]of s)g.some(y=>y.archetype.name===i)||r(m,`${i} is imported but never instantiated`);return t.some(i=>i.severity==="error")||!l?{diagnostics:t}:{diagnostics:t,program:{assets:[...P.values()],derivedAmounts:o,name:l.name.name,parties:[...v.values()],ports:Ge,settlements:q,title:l.title?.value??ct(l.name.name)}}}function st(e){if(e.kind==="ident"&&e.name==="text")return{kind:"text"};if(e.kind==="ident"&&e.name==="date")return{kind:"date"};if(e.kind==="call"&&e.args.length===1&&e.args[0]?.kind==="ident"){let t=e.args[0].name;if(e.callee.name==="id")return{asset:t,kind:"asset_id"};if(e.callee.name==="money")return{currency:t,kind:"money"}}}function ct(e){let t=e.replaceAll("_"," ");return t.charAt(0).toUpperCase()+t.slice(1)}function En(e){let t=[0];for(let n=0;n<e.length;n+=1)e.charCodeAt(n)===10&&t.push(n+1);return{length:e.length,starts:t}}function Sn(e,t){let n=Math.max(0,Math.min(t,e.length)),r=0,o=e.starts.length-1;for(;r<o;){let a=Math.floor((r+o+1)/2);e.starts[a]<=n?r=a:o=a-1}return{column:n-e.starts[r]+1,line:r+1}}var Pn=20,In=48,en=10000n;function dt(e){if(!e)return{amountDependencies:[],amountMode:"fixed"};switch(e.kind){case"bounded_by_reference":return{amountDependencies:[U(e.reference)],amountMode:"runtime_bounded"};case"net_of_offsets":{if(e.offsets.length===0)throw new Error("net_of_offsets requires at least one offset event");return{amountDependencies:Tn(e.source,e.offsets),amountMode:"runtime_bounded"}}case"percent_of_reference":if(!Number.isInteger(e.bps)||e.bps<=0||e.bps>1e4)throw new Error("percent_of_reference bps must be an integer between 1 and 10000");return{amountDependencies:[U(e.reference)],amountMode:"runtime_bounded"};case"remainder":{if(e.consumed.length===0)throw new Error("remainder requires at least one consumed event");return{amountDependencies:Tn(e.source,e.consumed),amountMode:"remaining_balance"}}}}function Tn(e,t){let n=[e,...t].map(U);if(new Set(n).size!==n.length)throw new Error("amount dependency event keys must be distinct");return n}var Fn=160,lt=new Set(["amount","design","detail","headline","label","summary","title","trigger","why"]);function nn(e,t){return typeof e=="string"?t!==void 0&&lt.has(t)&&e.length>Fn?`${e.slice(0,Fn-3)}...`:e:Array.isArray(e)?e.map(n=>nn(n,t)):e!==null&&typeof e=="object"?Object.fromEntries(Object.entries(e).map(([n,r])=>[n,nn(r,n)])):e}function ut(e){return nn(e)}function U(e){if(e.length<=40)return e;let t=2166136261;for(let n=0;n<e.length;n+=1)t=Math.imul(t^e.charCodeAt(n),16777619);return`${e.slice(0,33)}_${(t>>>0).toString(36).slice(0,6)}`}function pt(e){let t=e.amountDependency;if(!t)return e.amount;switch(t.kind){case"bounded_by_reference":return`Bounded by ${t.reference}: ${e.amount}`;case"net_of_offsets":return`Net of ${t.source} after ${t.offsets.join(", ")}: ${e.amount}`;case"percent_of_reference":return`${W(t.bps)} of ${t.reference}: ${e.amount}`;case"remainder":return`Remainder of ${t.source} after ${t.consumed.join(", ")}: ${e.amount}`}}function V(e){return{allocationTotalBps:0,amount:pt(e),...dt(e.amountDependency),amountSchedule:[],distribution:"single",fromActor:e.fromActor,key:U(e.key),kind:e.kind,label:e.trigger,occurrence:e.occurrence??"once",timing:e.timing??"on_lifecycle",toActor:e.toActor,trigger:e.trigger}}function ge(e,t,n,r){return e.map((o,a)=>({from:a===0?t:`${r}_${a}`,to:a===e.length-1?n:`${r}_${a+1}`}))}function Ne(e,t,n,r){let o=new Set;for(let a of t){if(a==="create"||o.has(a))return r.push({message:`settlement ${e} generates two verbs named "${a}"; rename the colliding port`,span:n}),!1;o.add(a)}return!0}function $e(e,t){return t.length>=2?[{pieces:[...t],total:e}]:[]}function we(e){return e.length>0?{partitions:[...e]}:{}}function H(e){return{desc:e,type:"money"}}function se(e){return{desc:e,type:"date"}}function mt(e){return{desc:e,type:"date?"}}function ft(e){if(typeof e.prefix=="string")return e.prefix;let t=e.id,n=t.split("_");return(n.length>1?n.map(o=>o[0]).join(""):t.slice(0,4)).slice(0,8).padEnd(2,"x")}function yt(e,t){let n=new Set(e.filter(a=>!t.has(a.id)).map(ft)),r=0,o=()=>{for(;;){let a=String.fromCharCode(97+Math.floor(r/26)),l=String.fromCharCode(97+r%26);r+=1;let s=`zz${a}${l}`;if(!n.has(s))return n.add(s),s}};return e.map(a=>t.has(a.id)?{...a,prefix:o()}:a)}function Rn(e){let t=[],n=[],r=[],o=[],a=[],l=[],s=[],u=[],w=new Set,v=new Map,P=new Map(e.ports.map(h=>[h.name,h])),_=(h,T,J)=>{let A=P.get(T);return A||t.push({message:`settlement ${h.name} decides through an unknown port; the checker should have refused this program`,span:J}),A},g=new Map(e.settlements.flatMap(h=>h.archetype==="advance"&&h.source.kind==="carve"?[[h.source.settlement,h.funder]]:[])),C=new Map(e.settlements.flatMap(h=>{if(h.archetype!=="advance"||h.source.kind!=="carve")return[];let T=e.settlements.filter(J=>J.archetype==="scheduled"&&J.mode==="transfer"&&J.payer===h.advanced&&J.payee===h.funder&&J.amount.name===h.amount.name&&J.amount.currency===h.amount.currency);return[[h.name,T]]})),D=new Map(e.settlements.flatMap(h=>h.archetype==="recurring_collection"?[[h.obligation.settlement,h]]:[]));for(let h of e.settlements){let T;switch(h.archetype){case"held_payment":{let N=_(h,h.release.port,h.release.origin);if(!N)continue;T=At(h,N,g.get(h.name),t);break}case"captured_payment":{let N=_(h,h.correction.port,h.correction.origin),M=_(h,h.externalReversal.port,h.externalReversal.origin);if(!N||!M)continue;T=Et(h,N,M,t);break}case"settlement_batch":{let N=_(h,h.payoutAcknowledgement.port,h.payoutAcknowledgement.origin);if(!N)continue;T=St(h,N,t);break}case"funding_round":T=It(h);break;case"weighted_distribution":{let N=_(h,h.snapshot.port,h.snapshot.origin);if(!N)continue;T=Tt(h,N);break}case"credit_facility":T=Ft(h);break;case"recurring_collection":continue;case"conditional_disbursement":{let N=_(h,h.decision.port,h.decision.origin);if(!N)continue;T=Rt(h,N);break}case"rotating_pool":T=Dt(h);break;case"premium_forward":{let N=_(h,h.bind.port,h.bind.origin),M=h.endorsement?_(h,h.endorsement.port,h.endorsement.origin):void 0;if(!N||h.endorsement&&!M)continue;T=xt(h,N,M,t);break}case"deposit":{let N=_(h,h.claim.port,h.claim.origin),M=_(h,h.return.port,h.return.origin);if(!N||!M)continue;T=Pt(h,N,M,t);break}case"instant_transfer":T=Ct(h);break;case"scheduled":T=h.mode==="obligation"?Nt(h,D.get(h.name),D.has(h.name)?_(D.get(h.name),D.get(h.name).mandate.port,D.get(h.name).mandate.origin):void 0):Lt(h);break;case"advance":T=Ot(h,C.get(h.name)??[]);break;case"metered":T=Jt(h);break;case"pooled_split":T=qt(h);break;case"swap":{let N=_(h,h.release.port,h.release.origin),M=h.dispute?_(h,h.dispute.port,h.dispute.origin):void 0;if(!N||h.dispute&&!M)continue;T=_t(h,N,M);break}}if(!T)continue;let J=(e.derivedAmounts??[]).filter(N=>N.settlement===h.name);if(J.length>0&&(T=gt(T,h,J,t),!T))continue;let A=le[h.archetype].eventCap+J.length;if(T.moneyEvents.length>A){t.push({message:`settlement ${h.name} emits ${T.moneyEvents.length} money events, but ${h.archetype} carries a local cap of ${A}`,span:h.origin});continue}for(let N of[...T.moneyEvents,...T.rules]){let M=N.key,oe=v.get(M);oe&&t.push({message:`settlements ${oe} and ${h.name} both generate the internal key ${M}; rename one settlement (or its port or meter) so the generated keys stay distinct`,span:h.origin}),v.set(M,h.name)}n.push(T.settlement);let R=[T.noun,...T.extraNouns??[]];for(let N of R){let M=N.verbs;for(let[oe,de]of Object.entries(M)){if(Object.hasOwn(de,"due")||Object.hasOwn(de,"requiresSettlement"))continue;let pe=Dn(N.id,oe);pe.length<=In||t.push({message:`settlement ${h.name} generates public intent "${pe}" with ${pe.length} characters; rename the settlement so each public intent fits the ${In}-character camelName limit`,span:h.origin})}}r.push(...R);for(let N of T.generatedPrefixNounIds??[])w.add(N);o.push(...T.moneyEvents),a.push(...T.rules),l.push(...T.design),s.push(...T.feeLines),T.repeatableCounterparty&&u.push(T.repeatableCounterparty)}o.length>Pn&&t.push({message:`this program needs ${o.length} money events but a Business Frame carries at most ${Pn}; simplify the fee or cancellation terms, or drop a settlement`,span:e.settlements[0]?.origin??{end:0,start:0}}),t.push(...bt(o,e.settlements[0]?.origin??{end:0,start:0}));let I=$t(e,u);if(t.push(...I.issues),t.length>0)return{issues:t,ok:!1};let Z=ht(yt(r,w)),ee=e.assets.map(h=>({kind:h.name,title:B(h.name),value:"optional"})),te={hsx:1,nouns:Z,product:e.name,...ee.length>0?{subjects:ee}:{},title:e.title},q={actors:I.actors,confidence:"high",conservationGroups:[],design:l,feePolicy:s.length>0?"defined":"none",fees:s,headline:e.title,mechanics:kt(e.settlements),moneyEvents:o,offPlatform:e.assets.filter(h=>h.titleTransfer==="off_platform").map(h=>({label:`${B(h.name)} title transfer`,why:`Ownership of the ${h.name.replaceAll("_"," ")} changes hands outside the platform`})),openQuestions:[],rules:a,subjects:e.assets.map(h=>({kind:h.name,title:B(h.name)})),summary:Mt(e)};return{ok:!0,value:{document:te,frame:ut(q),settlements:n}}}function ht(e){return e.map(t=>{let n=t.verbs;return{...t,verbs:Object.fromEntries(Object.entries(n).map(([r,o])=>[r,Object.hasOwn(o,"due")||Object.hasOwn(o,"requiresSettlement")?o:{...o,publicIntent:Dn(t.id,r)}]))}})}function Dn(e,t){let n=Q(e),r=n.charAt(0).toUpperCase()+n.slice(1);return`${Q(t)}${r}`}function gt(e,t,n,r){let o=e.noun,a={...o.fields??{}},l={...o.verbs??{}},s={...l.create??{}},u=[...s.moves??[]],w={...o.actors??{}},v=[],P=[...e.moneyEvents],_=[...e.feeLines];for(let g of n){let C=a[g.baseField];if(C===void 0||C.type!=="money"){r.push({message:`settlement ${t.name} derives ${g.field} from ${C===void 0?"unknown ":"non-money "}field ${g.baseField}; from must name a stored money field on the settlement owner`,span:g.origin});return}if(a[g.field]!==void 0){r.push({message:`settlement ${t.name} derives into existing field ${g.field}; choose a new derived amount field`,span:g.origin});return}let D=U(`${t.name}_derived_amount`);a[g.field]=H(`Machine-computed ${W(g.bps)} of ${g.baseField}; callers never supply it`),w[g.bearer]===void 0&&(w[g.bearer]="payer"),w.platform="beneficiary",v.push({field:g.field,rounding:"floor",rule:{bps:g.bps,kind:"percentage_of"},sourceField:g.baseField}),u.push({amount:g.field,from:g.bearer,key:"derived_amount",moneyEvent:D,operation:"create",to:"platform"}),P.push(V({amount:`The machine-computed ${g.field}`,fromActor:g.bearer,key:D,kind:"charge",toActor:"platform",trigger:`Collect ${g.field} with settlement creation`})),_.push({label:B(g.field),on:`each ${t.name.replaceAll("_"," ")}`,structure:`${W(g.bps)} of stored ${g.baseField}, computed by the runtime`})}return s.moves=u,l.create=s,{...e,design:[...e.design,`${t.name}: derived amounts are machine-computed from stored source fields before create movements; fixed and tiered rules are refused`],feeLines:_,moneyEvents:P,noun:{...o,actors:w,derivedAmounts:v,fields:a,verbs:l}}}function $t(e,t=[]){let n=vt(e.settlements),r=new Set(e.parties.map(s=>s.name)),o=new Map,a=[];for(let s of t){if(!r.has(s.key)){a.push({message:`repeatable counterparty ${s.key} is not a declared party`,span:s.origin});continue}let u=n.get(s.key);if(!u){a.push({message:`repeatable counterparty ${s.key} is not used by any settlement`,span:s.origin});continue}if(u!==s.role){a.push({message:`repeatable counterparty ${s.key} declares role ${s.role}, but its settlement uses role ${u}`,span:s.origin});continue}if(s.label.trim().length===0||s.label.length>160){a.push({message:`repeatable counterparty ${s.key} label must contain 1 through 160 characters`,span:s.origin});continue}if(!Number.isInteger(s.minCount)||!Number.isInteger(s.maxCount)||s.minCount<1||s.maxCount>1e4){a.push({message:`repeatable counterparty ${s.key} counts must be integers from 1 through 10000`,span:s.origin});continue}if(s.minCount>s.maxCount){a.push({message:`repeatable counterparty ${s.key} has minCount ${s.minCount} above maxCount ${s.maxCount}`,span:s.origin});continue}if(o.has(s.key)){a.push({message:`repeatable counterparty ${s.key} is declared twice`,span:s.origin});continue}o.set(s.key,s)}return{actors:[...e.parties.filter(s=>n.has(s.name)).map(s=>{let u=o.get(s.name);return u?{key:u.key,label:u.label,maxCount:u.maxCount,minCount:u.minCount,role:u.role}:{key:s.name,label:B(s.name),maxCount:1,minCount:1,role:n.get(s.name)}}),{key:"platform",label:"Platform",maxCount:1,minCount:1,role:"platform"}],issues:a}}function bt(e,t){let n=[],r=new Map;for(let u of e){if(typeof u.key!="string")continue;let w=Array.isArray(u.amountDependencies)?u.amountDependencies.filter(v=>typeof v=="string"):[];r.set(u.key,w)}for(let[u,w]of r)for(let v of w){if(v===u){n.push({message:`money event ${u} cannot depend on itself`,span:t});continue}r.has(v)||n.push({message:`money event ${u} depends on missing money event ${v}`,span:t})}let o=new Set,a=new Set,l=new Set,s=u=>{if(!(a.has(u)||l.has(u))){if(o.has(u)){l.add(u);return}o.add(u);for(let w of r.get(u)??[])r.has(w)&&s(w),l.has(w)&&l.add(u);o.delete(u),a.add(u)}};for(let u of r.keys())s(u);return l.size>0&&n.push({message:`money event amount dependencies contain a cycle through ${[...l].sort().join(", ")}`,span:t}),n}function vt(e){let t=new Set,n=new Set,r=new Set,o=new Set;for(let s of e)switch(s.archetype){case"held_payment":case"captured_payment":case"instant_transfer":case"metered":t.add(s.payer),n.add(s.payee);break;case"scheduled":t.add(s.payer),n.add(s.payee),s.mode==="obligation"&&(t.add(s.debtor),s.advanceTo&&n.add(s.advanceTo));break;case"premium_forward":t.add(s.payer),r.add(s.carrier);break;case"deposit":t.add(s.payer),o.add(s.holder);break;case"advance":t.add(s.funder),n.add(s.advanced);break;case"pooled_split":t.add(s.payer);for(let u of s.shares)n.add(u.to);break;case"settlement_batch":t.add(s.settlementAccount),n.add(s.payoutDestination);break;case"funding_round":t.add(s.contributor),n.add(s.beneficiary);break;case"weighted_distribution":t.add(s.source),n.add(s.recipient);break;case"credit_facility":t.add(s.lender),n.add(s.borrower),n.add(s.drawDestination);break;case"recurring_collection":break;case"conditional_disbursement":t.add(s.source),n.add(s.destination);break;case"rotating_pool":for(let u of s.members)t.add(u),n.add(u);s.guarantor&&t.add(s.guarantor);break;case"swap":t.add(s.sides[0].party),n.add(s.sides[1].party);break}let a=new Map,l=(s,u)=>{for(let w of s)a.has(w)||a.set(w,u)};return l(t,"payer"),l(r,"provider"),l(o,"holder"),l(n,"beneficiary"),a}var wt={advance:"credit",captured_payment:"escrow",conditional_disbursement:"marketplace",credit_facility:"credit",deposit:"escrow",funding_round:"credit",held_payment:"escrow",instant_transfer:"marketplace",metered:"recurring_billing",pooled_split:"marketplace",premium_forward:"insurance",recurring_collection:"recurring_billing",rotating_pool:"recurring_billing",scheduled:"recurring_billing",settlement_batch:"marketplace",swap:"escrow",weighted_distribution:"marketplace"};function kt(e){let t=new Set(e.map(n=>n.archetype==="scheduled"&&n.mode==="obligation"?"credit":wt[n.archetype]));return t.size>0?[...t]:["escrow"]}function _t(e,t,n){let r=e.name,[o,a]=e.sides,l=e.dispute?.window,s=l!==void 0&&l.days>0,u=U(`${r}_clawback_maturity`),w=[],v=(R,N,M,oe,de,pe)=>{let me=U(`${r}_${R}`);return w.push(V({amount:M,fromActor:oe,key:me,kind:N,toActor:de,trigger:pe})),me},P=v("side_a_fund","charge",`The full ${o.amount.name}`,o.party,"escrow",`Fund ${o.amount.name} into the shared trade escrow`),_=v("side_b_fund","charge",`The full ${a.amount.name}`,a.party,"escrow",`Fund ${a.amount.name} into the shared trade escrow`),g=v("side_a_release","payout",`The full ${o.amount.name}`,"escrow",a.party,`Release ${o.amount.name} across to ${a.party.replaceAll("_"," ")}`),C=v("side_b_release","payout",`The full ${a.amount.name}`,"escrow",o.party,`Release ${a.amount.name} across to ${o.party.replaceAll("_"," ")}`),D=v("side_a_cancel","refund",`The full ${o.amount.name}`,"escrow",o.party,`Return ${o.amount.name} to its original funder on cancellation`),I=v("side_b_cancel","refund",`The full ${a.amount.name}`,"escrow",a.party,`Return ${a.amount.name} to its original funder on cancellation`),Z=s?v("side_a_clawback","refund",`The full ${o.amount.name}`,"escrow",o.party,`Return ${o.amount.name} after the whole trade is disputed`):void 0,ee=s?v("side_b_clawback","refund",`The full ${a.amount.name}`,"escrow",a.party,`Return ${a.amount.name} after the whole trade is disputed`):void 0,te={[o.amount.name]:H(`Side A amount in ${o.amount.currency} minor units, held against the whole trade`),[a.amount.name]:H(`Side B amount in ${a.amount.currency} minor units, held against the whole trade`),...s?{clawbackAt:{type:"date?",desc:`Machine-owned end of the ${l?.raw??"fixed"} whole-trade dispute window`}}:{}},q=[{amount:o.amount.name,from:o.party,key:"side_a_principal",moneyEvent:P,operation:"create",to:"escrow"},{amount:a.amount.name,from:a.party,key:"side_b_principal",moneyEvent:_,operation:"create",to:"escrow"}],h=[];for(let[R,N]of e.sides.entries()){if(!N.fee)continue;let M=N.fee.amount.name;te[M]=H(`Exact ${N.party.replaceAll("_"," ")} service fee in ${N.fee.amount.currency} minor units, charged on top and never held`);let oe=v(R===0?"side_a_service_fee":"side_b_service_fee","charge",`The exact ${M}, on top`,N.party,"platform",`Collect the ${N.party.replaceAll("_"," ")} custody fee at funding`);q.push({amount:M,from:N.party,key:R===0?"side_a_service_fee":"side_b_service_fee",moneyEvent:oe,operation:"create",to:"platform"}),h.push({label:`${B(N.party)} custody fee`,on:`each funded ${r.replaceAll("_"," ")}`,structure:`Exact ${M}, on top`})}let T=[{amount:o.amount.name,from:"escrow",key:"side_a",moneyEvent:g,operation:s?"reserve":"create",to:a.party},{amount:a.amount.name,from:"escrow",key:"side_b",moneyEvent:C,operation:s?"reserve":"create",to:o.party}],J={abandon:{from:["created"],requiresDrainedAccount:{path:"refs.escrowAccountId"},summary:"Abandon the trade before its atomic funding batch",to:"abandoned"},cancel:{from:["funded"],moves:[{amount:o.amount.name,from:"escrow",key:"side_a_refund",moneyEvent:D,operation:"create",to:o.party},{amount:a.amount.name,from:"escrow",key:"side_b_refund",moneyEvent:I,operation:"create",to:a.party}],summary:"Cancel and return both trade principals atomically",to:"cancelled"},create:{summary:`Create a ${B(r).toLowerCase()} atomic trade`,to:"created"},fund:{from:["created"],moves:q,summary:"Fund both trade sides and collect on-top fees atomically",to:"funded"},release:{from:["funded"],moves:T,port:{allowed:[...t.allowed]},...s?{setsAt:{field:"clawbackAt",offset:l?.raw}}:{},summary:s?"Reserve both cross-payments for the whole-trade clawback window":"Post both cross-payments atomically",to:s?"released":"settled"}};s&&e.dispute&&n&&Z&&ee&&(J.post={due:{field:"clawbackAt",rule:u},from:["released"],moves:[{key:"side_a",operation:"post",reservation:"release_side_a"},{key:"side_b",operation:"post",reservation:"release_side_b"}],summary:"Post both trade reservations when the clawback window matures",to:"settled"},J.dispute={deadline:{field:"clawbackAt"},from:["released"],moves:[{key:"side_a_void",operation:"void",reason:"Whole trade disputed inside the clawback window",reservation:"release_side_a"},{key:"side_b_void",operation:"void",reason:"Whole trade disputed inside the clawback window",reservation:"release_side_b"},{amount:o.amount.name,clawbackOf:"release_side_a",from:"escrow",key:"side_a_refund",moneyEvent:Z,operation:"create",to:o.party},{amount:a.amount.name,clawbackOf:"release_side_b",from:"escrow",key:"side_b_refund",moneyEvent:ee,operation:"create",to:a.party}],port:{allowed:[...n.allowed]},summary:"Void both reservations, then refund both principals atomically",to:"clawed_back"});let A=[{allowedActors:[...t.allowed],detail:`${t.allowed.map(B).join(" or ")} confirms the whole exchange through ${t.name}`,dueDriven:!1,enforcement:"tenant_app",gatesEvent:g,key:U(`${r}_${t.name}_gate`),kind:"release_condition",label:`Whole trade released through ${t.name}`,tenantTunable:!1}];return s&&e.dispute&&n&&A.push({allowedActors:[],detail:`Both pending trade payouts post together at the immutable ${e.dispute.window.raw} cutoff`,dueDriven:!0,enforcement:"platform",gatesEvent:null,key:u,kind:"deadline",label:"Whole trade posts when its clawback window matures",tenantTunable:!1},{allowedActors:[...n.allowed],detail:`${n.allowed.map(B).join(" or ")} may dispute only before the immutable cutoff`,dueDriven:!1,enforcement:"tenant_app",gatesEvent:Z??null,key:U(`${r}_${n.name}_gate`),kind:"release_condition",label:`Whole trade disputed through ${n.name}`,tenantTunable:!1}),{design:[`${r}: exactly two parties, two same-currency principals, one escrow, and one linked batch per phase`,s?`${r}: ${l?.raw} whole-trade clawback; release reserves both legs, then exactly one grouped post or grouped void-and-refund wins`:`${r}: no clawback window; release posts both legs directly and exposes no pending or dispute surface`],feeLines:h,moneyEvents:w,noun:{actors:{[o.party]:"payer",[a.party]:"beneficiary",...h.length>0?{platform:"party"}:{}},desc:`Atomic swap between ${o.party.replaceAll("_"," ")} and ${a.party.replaceAll("_"," ")}; half-funded and half-released states do not exist`,distinctParties:!0,escrow:!0,fields:te,id:r,summary:`Two-party atomic trade between ${o.party.replaceAll("_"," ")} and ${a.party.replaceAll("_"," ")}`,title:B(r),verbs:J},rules:A,settlement:{name:r,pieces:[{bps:1e4,cancelTo:o.party,field:o.amount.name,origin:o.amount.origin,releaseTo:a.party},{bps:1e4,cancelTo:a.party,field:a.amount.name,origin:a.amount.origin,releaseTo:o.party}]}}}function At(e,t,n,r){let o=e.fees.find(s=>s.bearer===e.payer),a=e.fees.find(s=>s.bearer===e.payee),l=Nn({amount:e.amount,carveTo:n,deadlineField:e.releaseDeadlineField,fundEventKind:"charge",fundTrigger:(s,u)=>`Fund piece ${s+1} of ${u} into escrow`,name:e.name,onCancel:e.onCancel,payee:e.payee,payeeFeeBps:a?.bps??0,payer:e.payer,payerFeeBps:o?.bps,port:t,releaseWord:"release"},r);if(l)return{...l,feeLines:[...o?[{label:`${B(e.payer)} service fee`,on:`each funded ${e.name.replaceAll("_"," ")}`,structure:`${W(o.bps)} of the ${e.amount.name}, on top`}]:[],...a?[{label:`${B(e.payee)} fee`,on:`each released ${e.name.replaceAll("_"," ")}`,structure:`${W(a.bps)} of the ${e.amount.name}, deducted from the payout`}]:[]],noun:{...l.noun,desc:`Held payment: the ${e.payer.replaceAll("_"," ")} funds ${e.amount.name} into this settlement's own escrow; ${t.allowed.map(s=>s.replaceAll("_"," ")).join(" or ")} confirms through ${t.name} to release${n?` to the ${n.replaceAll("_"," ")}, whose advance the ${e.payee.replaceAll("_"," ")} repays out of it`:""}`,summary:`Escrow-held payment from ${e.payer.replaceAll("_"," ")} to ${e.payee.replaceAll("_"," ")}`}}}function xt(e,t,n,r){let o=Nn({amount:e.amount,carveTo:void 0,deadlineField:void 0,fundEventKind:"premium",fundTrigger:(w,v)=>v===1?"Collect the premium into escrow":`Collect premium piece ${w+1} of ${v} into escrow`,name:e.name,onCancel:e.onCancel,payee:e.carrier,payeeFeeBps:e.commissionBps,payer:e.payer,payerFeeBps:void 0,port:t,releaseWord:"forward"},r);if(!o)return;let a=o.noun,l={...a.fields??{}},s={...a.verbs??{}},u=[...o.rules];if(e.policyReferenceField&&e.renewalDueField&&e.endorsement&&n){l[e.policyReferenceField]={desc:"Immutable external policy reference recorded with this forward",type:"text"},l[e.renewalDueField]=se("Stored renewal due condition for the forwarded policy"),s[e.endorsement.port]={captureInput:{endorsementEvidenceReference:"evidenceReference"},from:["released"],port:{allowed:n.allowed,fields:{evidenceReference:"text"}},summary:"Record one non-money endorsement from external evidence",to:"endorsed"};let w=U(`${e.name}_renewal_due`);s.lapse={due:{field:e.renewalDueField,rule:w},from:["released","endorsed"],requiresDrainedAccount:{path:"refs.escrowAccountId"},summary:"Mark the forwarded policy lapsed at its stored renewal due condition",to:"lapsed"},u.push({allowedActors:[],detail:"The stored renewal due condition changes policy state without moving money",dueDriven:!0,enforcement:"platform",gatesEvent:null,key:w,kind:"deadline",label:"Policy lapses at its stored renewal due condition",tenantTunable:!1})}return{...o,design:[`${e.name}: premium forwards to the ${e.carrier.replaceAll("_"," ")} exactly once on ${t.name}; ${W(e.commissionBps)} commission retained by the platform`,...e.policyReferenceField?[`${e.name}: extends premium_forward with stored policy reference, non-money endorsement evidence, and a due-only lapse; renewal creates a new forward`]:[]],feeLines:e.commissionBps>0?[{label:"Platform commission",on:`each bound ${e.name.replaceAll("_"," ")}`,structure:`${W(e.commissionBps)} of the ${e.amount.name}, deducted at forwarding`}]:[],noun:{...o.noun,fields:l,verbs:s,desc:`Premium forward: the ${e.payer.replaceAll("_"," ")} funds the ${e.amount.name} into this settlement's own escrow; binding through ${t.name} forwards it to the ${e.carrier.replaceAll("_"," ")} exactly once, minus the platform commission`,summary:`Premium held for the ${e.carrier.replaceAll("_"," ")} until the policy binds`},rules:u}}function Nn(e,t){let n=e.amount.name,r=Ln(e),o=r.length===1?r.map(A=>({...A,field:n})):r,a=e.name,l=e.carveTo??e.payee,s=l.replaceAll("_"," "),u={[n]:H(o.length===1?`The held amount in ${e.amount.currency} minor units, funded and paid out whole`:`The gross held amount in ${e.amount.currency} minor units; the piece fields below partition it exactly`)};for(let[A,R]of o.entries())R.field!==n&&(u[R.field]=H(On(R,A,n,e.amount.currency)));e.deadlineField&&(u[e.deadlineField]=se(`The date an undecided hold releases to the ${s} on; ${e.port.name} and cancellation decide only before it`)),e.payerFeeBps!==void 0&&(u.serviceFeeAmount=H(`${W(e.payerFeeBps)} of ${n}, the ${e.payer.replaceAll("_"," ")}-side service fee charged on top at funding; non-refundable`));let w=o.map((A,R)=>`fund_piece_${R+1}`);e.payerFeeBps!==void 0&&w.push("collect_service_fee");let v=o.map((A,R)=>R===0?e.port.name:`${e.releaseWord}_piece_${R+1}`),P=e.onCancel?o.map((A,R)=>R===0?"cancel":`refund_piece_${R+1}`):[],_=e.deadlineField?`${e.releaseWord}_on_deadline`:void 0,g=U(`${a}_${e.releaseWord}_deadline`),C=w.length-1,D=Array.from({length:C},(A,R)=>`unfund_piece_${R+1}`);if(!Ne(e.name,[...w,...v,..._?[_]:[],...P,"abandon",...D],e.port.origin,t))return;let I=ge(w,"created","funded","funding"),Z=ge(v,"funded","released","releasing"),ee=ge(P,"funded","cancelled","cancelling"),te=[],q={},h=`${a}_fund`;te.push(V({amount:o.length===1?`The full ${n}`:`The ${n}, funded piece by piece`,fromActor:e.payer,key:h,kind:e.fundEventKind,...o.length>1?{occurrence:"repeatable"}:{},toActor:"escrow",trigger:e.fundTrigger(0,o.length)}));for(let[A,R]of o.entries())q[w[A]]={from:[I[A]?.from],moneyEvent:h,moves:[{key:"transfer",operation:"create",amount:R.field,from:e.payer,to:"escrow"}],summary:`Fund piece ${A+1} of the held amount into escrow`,to:I[A]?.to};if(e.payerFeeBps!==void 0){let A=w.length-1,R=`${a}_service_fee`;te.push(V({amount:`${W(e.payerFeeBps)} of the ${n}, on top`,fromActor:e.payer,key:R,kind:"charge",toActor:"platform",trigger:"Collect the service fee at funding"})),q.collect_service_fee={from:[I[A]?.from],moneyEvent:R,moves:[{key:"transfer",operation:"create",amount:"serviceFeeAmount",from:e.payer,to:"platform"}],summary:"Collect the payer-side service fee",to:I[A]?.to}}let T=new Map;for(let A of o)T.set(A.releaseTo,(T.get(A.releaseTo)??0)+1);for(let[A,R]of T){let N=o.filter(M=>M.releaseTo===A).reduce((M,oe)=>M+oe.bps,0);te.push(V({amount:`${W(N)} of the ${n}`,fromActor:"escrow",key:`${a}_release_${A}`,kind:"payout",...R>1?{occurrence:"repeatable"}:{},toActor:A,trigger:`Release to the ${A.replaceAll("_"," ")}`}))}for(let[A,R]of o.entries())q[v[A]]={...A===0&&e.deadlineField?{deadline:{field:e.deadlineField}}:{},from:[Z[A]?.from],moneyEvent:U(`${a}_release_${R.releaseTo}`),moves:[{key:"transfer",operation:"create",amount:R.field,from:"escrow",to:R.releaseTo}],...A===0?{port:{allowed:[...e.port.allowed],fields:Object.fromEntries(e.port.fields.map(N=>[N.name,"text"]))}}:{},summary:A===0?`Confirm through ${e.port.name} and start the ${e.releaseWord} payout`:`${B(e.releaseWord)} piece ${A+1} of the held amount`,to:Z[A]?.to};if(_&&e.deadlineField){let A=o[0];q[_]={due:{field:e.deadlineField,rule:g},from:[Z[0]?.from],moneyEvent:U(`${a}_release_${A.releaseTo}`),moves:[{key:"transfer",operation:"create",amount:A.field,from:"escrow",to:A.releaseTo}],summary:`Release to the ${A.releaseTo.replaceAll("_"," ")} when ${e.deadlineField} arrives undecided`,to:Z[0]?.to}}if(e.onCancel){let A=new Map;for(let R of o){let N=R.cancelTo;A.set(N,(A.get(N)??0)+1)}for(let[R,N]of A){let M=o.filter(oe=>oe.cancelTo===R).reduce((oe,de)=>oe+de.bps,0);te.push(V({amount:`${W(M)} of the ${n}`,fromActor:"escrow",key:`${a}_cancel_${R}`,kind:R===e.payer?"refund":"penalty",...N>1?{occurrence:"repeatable"}:{},toActor:R,trigger:`Return to the ${R.replaceAll("_"," ")} on cancellation`}))}for(let[R,N]of o.entries())q[P[R]]={...R===0&&e.deadlineField?{deadline:{field:e.deadlineField}}:{},from:[ee[R]?.from],moneyEvent:U(`${a}_cancel_${N.cancelTo}`),moves:[{key:"transfer",operation:"create",amount:N.field,from:"escrow",to:N.cancelTo}],summary:R===0?"Cancel the settlement and start the unwind":`Return piece ${R+1} on cancellation`,to:ee[R]?.to}}if(D.length>0){let A=`${a}_abandon`;te.push(V({amount:`The funded pieces of the ${n}, returned exactly`,fromActor:"escrow",key:A,kind:"refund",...D.length>1?{occurrence:"repeatable"}:{},toActor:e.payer,trigger:`Return the held pieces to the ${e.payer.replaceAll("_"," ")} on abandonment`}));for(let[R,N]of D.entries()){let M=R+1;q[N]={from:[`funding_${M}`,...M<C?[`abandoning_${M}`]:[]],moneyEvent:U(A),moves:[{key:"transfer",operation:"create",amount:o[R].field,from:"escrow",to:e.payer}],summary:`Return piece ${M} to the ${e.payer.replaceAll("_"," ")} on abandonment`,to:M===1?"abandoned":`abandoning_${M-1}`}}}q.abandon={from:["created"],requiresDrainedAccount:{path:"refs.escrowAccountId"},summary:"Abandon the settlement before any money is held",to:"abandoned"},q.create={summary:`Create a ${B(e.name).toLowerCase()} settlement`,to:"created"};let J=[{allowedActors:[...e.port.allowed],detail:`${e.port.allowed.map(B).join(" or ")} confirms through the tenant backend before ${e.deadlineField?`${e.deadlineField}, to decide ahead of it`:"any payout"}`,dueDriven:!1,enforcement:"tenant_app",gatesEvent:U(`${a}_release_${o[0].releaseTo}`),key:U(`${a}_${e.port.name}_gate`),kind:"release_condition",label:`${B(e.releaseWord)} decided through ${e.port.name}`,tenantTunable:!1}];return e.deadlineField&&J.push({allowedActors:[],detail:`A hold nobody decided releases to the ${s} on its stored ${e.deadlineField}, exactly once`,dueDriven:!0,enforcement:"platform",gatesEvent:null,key:g,kind:"deadline",label:`Undecided holds release on ${e.deadlineField}`,tenantTunable:!1}),{design:[`${a}: own escrow; ${o.length}-piece partition of ${n} (${o.map(A=>W(A.bps)).join(" + ")}); every exit drains every piece; abandonable before funded (created closes directly, funding states unwind piece by piece to the ${e.payer})`,...e.deadlineField?[`${a}: undecided holds release to the ${l} on ${e.deadlineField}; the port and the cancel decide only before that anchor`]:[],...e.carveTo?[`${a}: the ${e.payee}'s whole release share is carved to the ${e.carveTo}, who financed it; the platform fee and the cancellation split are untouched`]:[],...e.payerFeeBps!==void 0?[`${a}: ${W(e.payerFeeBps)} ${e.payer} service fee on top, straight to platform at funding`]:[]],feeLines:[],moneyEvents:te,noun:{actors:{[e.payer]:"payer",[e.payee]:"beneficiary",...e.carveTo?{[e.carveTo]:"party"}:{},platform:"party"},desc:`Held amount from ${e.payer.replaceAll("_"," ")} to ${e.payee.replaceAll("_"," ")}${e.carveTo?`, released to the ${s} against the advance it secures`:""}`,escrow:!0,fields:u,id:e.name,...we($e(n,o.map(A=>A.field))),summary:`Escrow-held amount from ${e.payer.replaceAll("_"," ")}`,title:B(e.name),verbs:q},rules:J,settlement:{name:e.name,pieces:o,...e.payerFeeBps!==void 0?{serviceFee:{bps:e.payerFeeBps,field:"serviceFeeAmount"}}:{}}}}function Ct(e){let t=e.fees.find(g=>g.bearer===e.payer),n=e.fees.find(g=>g.bearer===e.payee),r=e.amount.name,o=Ln({amount:e.amount,payee:e.payee,payeeFeeBps:n?.bps??0}),a=o.length===1?o.map(g=>({...g,field:r})):o,l=e.name,s={[r]:H(a.length===1?`The amount in ${e.amount.currency} minor units, paid through whole`:`The gross amount in ${e.amount.currency} minor units; the piece fields below partition it exactly`)};for(let[g,C]of a.entries())C.field!==r&&(s[C.field]=H(On(C,g,r,e.amount.currency)));t&&(s.serviceFeeAmount=H(`${W(t.bps)} of ${r}, the ${e.payer.replaceAll("_"," ")}-side service fee charged on top; non-refundable`));let u=a.map((g,C)=>`pay_piece_${C+1}`);t&&u.push("collect_service_fee");let w=ge(u,"created","paid","paying"),v=[],P={create:{summary:`Create a ${B(l).toLowerCase()} payment`,to:"created"}};for(let[g,C]of a.entries()){let D=`${l}_pay_${g+1}`;v.push(V({amount:`${W(C.bps)} of the ${r}`,fromActor:e.payer,key:D,kind:"charge",toActor:C.releaseTo,trigger:`Pay piece ${g+1} straight to the ${C.releaseTo.replaceAll("_"," ")}`})),P[u[g]]={from:[w[g]?.from],moneyEvent:D,moves:[{key:"transfer",operation:"create",amount:C.field,from:e.payer,to:C.releaseTo}],summary:`Pay piece ${g+1} of the amount through`,to:w[g]?.to}}if(t){let g=u.length-1,C=`${l}_service_fee`;v.push(V({amount:`${W(t.bps)} of the ${r}, on top`,fromActor:e.payer,key:C,kind:"charge",toActor:"platform",trigger:"Collect the service fee with the payment"})),P.collect_service_fee={from:[w[g]?.from],moneyEvent:C,moves:[{key:"transfer",operation:"create",amount:"serviceFeeAmount",from:e.payer,to:"platform"}],summary:"Collect the payer-side service fee",to:w[g]?.to}}let _=t!==void 0||a.some(g=>g.releaseTo==="platform");return{design:[`${l}: instant pass-through; ${a.length}-piece partition of ${r} (${a.map(g=>W(g.bps)).join(" + ")}); no custody`],feeLines:[...t?[{label:`${B(e.payer)} service fee`,on:`each ${l.replaceAll("_"," ")}`,structure:`${W(t.bps)} of the ${r}, on top`}]:[],...n?[{label:`${B(e.payee)} fee`,on:`each ${l.replaceAll("_"," ")}`,structure:`${W(n.bps)} of the ${r}, deducted from the payout`}]:[]],moneyEvents:v,noun:{actors:{[e.payer]:"payer",[e.payee]:"beneficiary",..._?{platform:"party"}:{}},desc:`Instant transfer: the ${e.payer.replaceAll("_"," ")} pays ${r} straight through to the ${e.payee.replaceAll("_"," ")}, no custody`,fields:s,id:l,...we($e(r,a.map(g=>g.field))),summary:`Instant payment from ${e.payer.replaceAll("_"," ")} to ${e.payee.replaceAll("_"," ")}`,title:B(l),verbs:P},rules:[],settlement:{name:l,pieces:a,...t?{serviceFee:{bps:t.bps,field:"serviceFeeAmount"}}:{}}}}function Et(e,t,n,r){let o=e.name,a=e.amount.name,l="authorize_reservation",s="capturedAmount",u="reversalUntil",v=["authorize",...["capture","capture_more"],"settle","void","expire","settle_on_expiry",e.correction.port,e.externalReversal.port];if(!Ne(o,v,e.origin,r))return;let P=U(`${o}_reserve`),_=U(`${o}_capture`),g=U(`${o}_correction`),C=U(`${o}_external_reversal`),D=U(`${o}_reservation_expiry`),I=q=>({amount:"captureAmount",capture:{[s]:"postedAmount"},key:"post",operation:"post",...q?{partialOnly:!0}:{},reservation:l}),Z=()=>({amount:`refs.${s}`,clawbackOf:l,from:e.payee,key:"transfer",operation:"create",to:e.payer}),ee={create:{summary:`Create a ${B(o).toLowerCase()}`,to:"created"},authorize:{from:["created"],moneyEvent:P,moves:[{amount:a,from:e.payer,key:"reservation",operation:"reserve",to:e.payee}],summary:`Reserve the ${a} until ${e.reserveUntilField}`,to:"authorized"},capture:{deadline:{field:e.reserveUntilField},from:["authorized"],moneyEvent:_,moves:[I(!0)],summary:"Post one strict partial capture slice",to:"partially_captured"},capture_more:{deadline:{field:e.reserveUntilField},from:["partially_captured"],moneyEvent:_,moves:[I(!0)],summary:"Post another strict partial capture slice",to:"partially_captured"},settle:{deadline:{field:e.reserveUntilField},from:["authorized","partially_captured"],moneyEvent:_,moves:[{capture:{[s]:"postedAmount"},key:"post",operation:"post",reservation:l}],summary:"Post the full reserved remainder and settle",setsAt:{field:u,offset:e.externalReversal.window.raw},to:"settled"},void:{from:["authorized"],moves:[{key:"void",operation:"void",reason:"Reservation voided before any capture",reservation:l}],summary:"Release an entirely uncaptured reservation",to:"voided"},expire:{due:{field:e.reserveUntilField,rule:D},from:["authorized"],moves:[{key:"void",operation:"void",reason:"Uncaptured reservation expired",reservation:l}],summary:"Release an uncaptured reservation at expiry",to:"expired"},settle_on_expiry:{due:{field:e.reserveUntilField,rule:D},from:["partially_captured"],moves:[{key:"void",operation:"void",reason:"Uncaptured remainder released at expiry",reservation:l}],summary:"Release the uncaptured remainder and settle captured slices",setsAt:{field:u,offset:e.externalReversal.window.raw},to:"settled"},[e.correction.port]:{from:["settled"],moneyEvent:g,moves:[Z()],port:{allowed:t.allowed},summary:"Return the full captured amount on payee correction",to:"corrected"},[e.externalReversal.port]:{captureInput:{externalReference:"externalReference"},deadline:{field:u},from:["settled"],moneyEvent:C,moves:[Z()],port:{allowed:n.allowed,fields:{externalReference:"text"}},summary:"Return the full captured amount on an external reversal",to:"reversed"}},te=[V({amount:`The full ${a}`,fromActor:e.payer,key:P,kind:"hold",toActor:e.payee,trigger:`Reserve ${a} until ${e.reserveUntilField}`}),V({amount:`Each posted slice, never more than the remaining ${a}`,amountDependency:{kind:"bounded_by_reference",reference:P},fromActor:e.payer,key:_,kind:"payout",occurrence:"repeatable",toActor:e.payee,trigger:"Post a capture slice or the final remainder"}),V({amount:"100% of the cumulative captured amount",amountDependency:{bps:1e4,kind:"percent_of_reference",reference:_},fromActor:e.payee,key:g,kind:"refund",toActor:e.payer,trigger:"Apply one full payee correction"}),V({amount:"100% of the cumulative captured amount",amountDependency:{bps:1e4,kind:"percent_of_reference",reference:_},fromActor:e.payee,key:C,kind:"refund",toActor:e.payer,trigger:"Apply one full externally decided reversal"})];return{design:[`${o}: reserve ${a} until ${e.reserveUntilField}; capture in strict partial slices; post the remainder to settle; expiry releases only the uncaptured remainder`,`${o}: correction and external reversal each return the full captured amount once; insufficient payee funds reject the move instead of creating a negative position`],feeLines:[],moneyEvents:te,noun:{actors:{[e.payer]:"payer",[e.payee]:"beneficiary"},desc:"Payer reservation captured by the payee in slices within a fixed window",fields:{[a]:H(`Maximum captured amount in ${e.amount.currency} minor units`),[e.reserveUntilField]:se("Reservation expiry that releases any uncaptured remainder"),[u]:{desc:"Machine-owned external reversal cutoff anchored when settlement completes",type:"date?"}},id:o,summary:`Capture reservation from ${e.payer.replaceAll("_"," ")} to ${e.payee.replaceAll("_"," ")}`,title:B(o),verbs:ee},rules:[{allowedActors:[],detail:`At ${e.reserveUntilField}, the platform releases the uncaptured remainder and preserves any posted slices`,dueDriven:!0,enforcement:"platform",gatesEvent:null,key:D,kind:"deadline",label:`Uncaptured remainder releases on ${e.reserveUntilField}`,tenantTunable:!1},{allowedActors:[...t.allowed],detail:"The payee may return the full captured amount once",dueDriven:!1,enforcement:"tenant_app",gatesEvent:g,key:U(`${o}_${e.correction.port}_gate`),kind:"release_condition",label:"Full correction confirmed through the tenant backend",tenantTunable:!1},{allowedActors:[...n.allowed],detail:`A confirmed external decision may reverse the full captured amount within ${e.externalReversal.window.raw}; timeout moves nothing`,dueDriven:!1,enforcement:"tenant_app",gatesEvent:C,key:U(`${o}_${e.externalReversal.port}_gate`),kind:"release_condition",label:"External reversal confirmed through the tenant backend",tenantTunable:!1}],settlement:{name:o,pieces:[]}}}function St(e,t,n){let r=e.name,o=`${r}_capture_entry`,a=`${r}_credit_adjustment`,l=`${r}_debit_adjustment`,s=`${r.replaceAll(/_([a-z])/g,(C,D)=>D.toUpperCase())}Id`,u=U(`${r}_payout`),w=U(`${r}_close`);if(!Ne(r,["close","calculate","approve","instruct","reconcile",e.payoutAcknowledgement.port],e.origin,n))return;let v={[s]:{match:{"fields.currency":"fields.currency"},statuses:["open"]}},P={desc:"One gross capture entry linked to an open payout batch",fields:{amount:H("Gross captured amount in minor units"),currency:{desc:"ISO 4217 currency shared with the payout batch",type:"currency"},[s]:{desc:"Open batch this capture entry accrues into",type:`ref:${r}`},[e.sourceCaptureReferenceField]:{desc:"Immutable source capture reference",type:"text"}},id:o,summary:"Gross capture lineage entry",title:`${B(r)} Capture Entry`,verbs:{create:{requires:v,summary:"Create a capture lineage entry on an open batch",to:"created"},accrue:{from:["created"],requires:v,summary:"Accrue the capture entry into the open batch",to:"accrued"}}},_=(C,D)=>({desc:`One ${D} adjustment linked to an open payout batch; closed batches stay unchanged`,fields:{amount:H(`${B(D)} adjustment amount in minor units`),currency:{desc:"ISO 4217 currency shared with the payout batch",type:"currency"},adjustmentReference:{desc:"Immutable explicit adjustment reference",type:"text"},[s]:{desc:"Open batch this adjustment applies to",type:`ref:${r}`},[e.externalReversalReferenceField]:{desc:"Optional externally decided reversal reference",type:"text?"},[e.feeReferenceField]:{desc:"Optional fee entry reference",type:"text?"},[e.sourceCaptureReferenceField]:{desc:"Original capture reference that this adjustment corrects",type:"text"}},id:C,summary:`${B(D)} adjustment with capture lineage`,title:`${B(r)} ${B(D)} Adjustment`,verbs:{create:{requires:v,summary:`Create a ${D} adjustment on an open batch`,to:"created"},adjust:{from:["created"],requires:v,summary:`Apply the ${D} adjustment to the open batch`,to:"applied"},correct:{from:["created"],requires:v,summary:"Record a later correction on this open batch instead of changing the closed source batch",to:"applied"}}}),g={create:{summary:`Open a ${B(r).toLowerCase()}`,to:"open"},close:{due:{field:e.closeTriggerField,rule:w},from:["open"],summary:"Freeze the batch and stop all new entries",to:"closed"},calculate:{from:["closed"],signedSum:{amountRef:"netPayable",onNegative:"refuse",onZero:"refuse",sources:[{amountField:"amount",nounId:o,refField:s,sign:"add",statuses:["accrued"],subtotalRef:"grossCaptureAmount"},{amountField:"amount",nounId:a,refField:s,sign:"add",statuses:["applied"],subtotalRef:"creditAdjustmentAmount"},{amountField:"amount",nounId:l,refField:s,sign:"subtract",statuses:["applied"],subtotalRef:"debitAdjustmentAmount"}]},summary:"Prove and freeze the one signed net payable amount",to:"calculated"},approve:{from:["calculated"],summary:"Approve the frozen payable without recomputing it",to:"approved"},instruct:{from:["approved"],moneyEvent:u,payout:{amount:"refs.netPayable",beneficiaryField:e.payoutBeneficiaryReferenceField,beneficiaryPartyField:`${Q(e.payoutDestination)}AccountId`,capture:"payoutId",currencyField:"currency",sourceAccountField:`${Q(e.settlementAccount)}AccountId`,speed:"standard"},summary:"Create one idempotent payout from the frozen net payable",to:"instructed"},[e.payoutAcknowledgement.port]:{captureInput:{acknowledgementReference:"acknowledgementReference"},from:["instructed"],port:{allowed:t.allowed,fields:{acknowledgementReference:"text"}},summary:"Record the tenant's payout acknowledgement in the receipt",to:"acknowledged"},reconcile:{from:["instructed","acknowledged"],requiresSettlement:{capture:"settlementEvidenceId",payoutRef:"payoutId"},summary:"Record durable evidence that the payout settled",to:"reconciled"}};return{design:[`${r}: capture entries plus signed adjustments freeze at ${e.closeTriggerField}; calculate persists gross, credit, debit, and net refs; negative or zero net refuses`,`${r}: instruct creates one payout intent for the frozen refs.netPayable; only matched settlement evidence can reconcile it`],extraNouns:[P,_(a,"credit"),_(l,"debit")],feeLines:[],moneyEvents:[V({amount:"The frozen signed sum of gross capture entries plus credit adjustments minus debit adjustments",fromActor:e.settlementAccount,key:u,kind:"payout",toActor:e.payoutDestination,trigger:"Instruct the approved batch payout exactly once"})],noun:{actors:{[e.payoutDestination]:"beneficiary",[e.settlementAccount]:"payer"},desc:"Immutable batch of capture lineage and signed adjustments that creates one payout",fields:{[e.closeTriggerField]:se("Date the open batch freezes against later entries"),currency:{desc:"ISO 4217 currency shared by the batch and payout instruction",type:"currency"},[e.payoutBeneficiaryReferenceField]:{desc:"Beneficiary ID for the payout instruction",type:"beneficiary"}},id:r,summary:`Payout batch from ${e.settlementAccount.replaceAll("_"," ")} to ${e.payoutDestination.replaceAll("_"," ")}`,title:B(r),verbs:g},rules:[{allowedActors:[],detail:`At ${e.closeTriggerField}, the platform closes the batch and every child reference gate refuses later entries`,dueDriven:!0,enforcement:"platform",gatesEvent:null,key:w,kind:"deadline",label:`Batch freezes on ${e.closeTriggerField}`,tenantTunable:!1}],settlement:{name:r,pieces:[]}}}function Pt(e,t,n,r){let o=e.name,a=e.amount.name;if(!Ne(o,["place_deposit",t.name,n.name],e.origin,r))return;let l=`${o}_hold_1`,s=[V({amount:`The full ${a}`,fromActor:e.payer,key:l,kind:"hold",toActor:e.holder,trigger:`Reserve the ${a} in the ${e.holder.replaceAll("_"," ")}'s favor`})],u={create:{summary:`Create a ${B(o).toLowerCase()}`,to:"created"},place_deposit:{from:["created"],moves:[{key:"reservation",operation:"reserve",amount:a,from:e.payer,to:e.holder}],moneyEvent:l,summary:`Reserve the ${a} against the ${e.payer.replaceAll("_"," ")}'s account`,to:"held"},[t.name]:{from:["held"],moves:[{key:"post",operation:"post",reservation:"place_deposit_reservation"}],summary:`Claim the deposit for the ${e.holder.replaceAll("_"," ")} through ${t.name}`,to:"claimed"},[n.name]:{from:["held"],summary:`Return the deposit to the ${e.payer.replaceAll("_"," ")} through ${n.name}`,to:"returned",moves:[{key:"void",operation:"void",reason:"Deposit returned in full",reservation:"place_deposit_reservation"}]}},w=(v,P)=>({allowedActors:[...v.allowed],detail:`${v.allowed.map(B).join(" or ")} decides through the tenant backend`,dueDriven:!1,enforcement:"tenant_app",gatesEvent:null,key:U(`${o}_${v.name}_gate`),kind:"release_condition",label:`${P} decided through ${v.name}`,tenantTunable:!1});return{design:[`${o}: ${a} held as a reservation on the ${e.payer.replaceAll("_"," ")}'s account; claimed whole through ${t.name} or returned whole through ${n.name}`],feeLines:[],moneyEvents:s,noun:{actors:{[e.payer]:"payer",[e.holder]:"beneficiary"},desc:`Deposit: the ${a} is reserved against the ${e.payer.replaceAll("_"," ")}'s account in the ${e.holder.replaceAll("_"," ")}'s favor, then claimed or returned in full`,fields:{[a]:H(`The deposit amount in ${e.amount.currency} minor units, reserved in full and fully accounted on claim or return`)},id:o,summary:`Refundable deposit from ${e.payer.replaceAll("_"," ")} held for ${e.holder.replaceAll("_"," ")}`,title:B(o),verbs:u},rules:[w(t,"Claim"),w(n,"Return")],settlement:{name:o,pieces:[]}}}function tn(e){let t=Math.floor(Number(en)/e),n=Array.from({length:e},()=>t);return n[0]=Number(en)-t*(e-1),n}function It(e){let t=e.name,n=`${t}_commitment`,r=`${Q(t)}Id`,o=U(`${t}_commit`),a=U(`${t}_cancel`),l=U(`${t}_collect`),s=U(`${t}_refund`),u=U(`${t}_close`),w=_=>[{check:{amountField:"amount",kind:_,targetField:e.target.name},nounId:n,over:"children",refField:r,statuses:["committed"]}],v=_=>({[r]:{bind:{currency:"fields.currency",[`${Q(e.beneficiary)}AccountId`]:`fields.${Q(e.beneficiary)}AccountId`},statuses:_}}),P=_=>({[r]:{match:{"fields.currency":"fields.currency",[`fields.${Q(e.beneficiary)}AccountId`]:`fields.${Q(e.beneficiary)}AccountId`},statuses:_}});return{design:[`${t}: reuses the catalog funding round and commitment mechanism; the parent lock caps committed rows by target and contributor count`,`${t}: the stored close anchor chooses threshold activation or failure; each commitment then moves whole from its own custody`],extraNouns:[{actors:{[e.beneficiary]:"beneficiary",[e.contributor]:"payer"},desc:`One whole commitment linked to ${t}`,escrow:!0,fields:{amount:H("One whole commitment amount"),currency:{desc:"Currency derived from the funding round",type:"currency"},[r]:{desc:`The exact ${t}`,type:`ref:${t}`}},id:n,summary:`Whole commitment to ${t}`,title:`${B(t)} Commitment`,verbs:{create:{moneyEvent:o,moves:[{amount:"amount",from:e.contributor,key:"commit",operation:"create",to:"escrow"}],requires:v(["open"]),requiresExposure:[{amountField:"amount",anchorField:r,capField:e.target.name,capOnAnchor:!0,childNounId:n,statuses:["committed"]}],summary:"Store one whole commitment without exceeding the round target",to:"committed"},cancel:{from:["committed"],moneyEvent:a,moves:[{amount:"amount",from:"escrow",key:"cancel",operation:"create",to:e.contributor}],requires:P(["open"]),summary:"Cancel one commitment while the round is open",to:"cancelled"},collect:{from:["committed"],moneyEvent:l,moves:[{amount:"amount",from:"escrow",key:"collect",operation:"create",to:e.beneficiary}],requires:P(["active"]),summary:"Collect one successful commitment whole",to:"collected"},refund:{from:["committed"],moneyEvent:s,moves:[{amount:"amount",from:"escrow",key:"refund",operation:"create",to:e.contributor}],requires:P(["failed"]),summary:"Refund one failed-round commitment whole",to:"refunded"}}}],generatedPrefixNounIds:[n],feeLines:[],moneyEvents:[V({amount:"One stored commitment",fromActor:e.contributor,key:o,kind:"charge",occurrence:"repeatable",toActor:"escrow",trigger:"Create one target-capped commitment"}),V({amount:"One stored commitment whole",fromActor:"escrow",key:a,kind:"refund",occurrence:"repeatable",toActor:e.contributor,trigger:"Cancel before close"}),V({amount:"One stored commitment whole",fromActor:"escrow",key:l,kind:"payout",occurrence:"repeatable",toActor:e.beneficiary,trigger:"Collect after threshold close"}),V({amount:"One stored commitment whole",fromActor:"escrow",key:s,kind:"refund",occurrence:"repeatable",toActor:e.contributor,trigger:"Refund after failed close"})],noun:{actors:{[e.beneficiary]:"beneficiary"},aggregateInvariants:[{childField:"amount",childNounId:n,childRefField:r,childStatuses:["committed"],parentField:e.target.name},{count:!0,childNounId:n,childRefField:r,childStatuses:["committed"],parentField:"maxContributors"}],desc:"All-or-nothing aggregate funding threshold",fields:{currency:{desc:`Currency fixed to ${e.target.currency}`,type:"currency"},[e.target.name]:H(`Funding target in ${e.target.currency} minor units`),[e.closeByField]:se("Stored close anchor"),maxContributors:{desc:`Exactly ${e.maxContributors} admitted contributors`,type:`const:${e.maxContributors}`}},id:t,summary:`Threshold funding round for ${e.beneficiary.replaceAll("_"," ")}`,title:B(t),verbs:{create:{summary:"Open the funding round",to:"open"},activate:{due:{field:e.closeByField,rule:u},from:["open"],requiresAggregate:w("sum_at_least"),summary:"Activate when commitments meet the target",to:"active"},fail:{due:{field:e.closeByField,rule:u},from:["open"],requiresAggregate:w("sum_below"),summary:"Fail when commitments remain below target",to:"failed"},close:{from:["active"],requiresAggregate:[{check:{kind:"all_in"},nounId:n,over:"children",refField:r,statuses:["cancelled","collected"]}],summary:"Settle after every admitted row is collected or was cancelled before activation",to:"settled"}}},rules:[{allowedActors:[],detail:"The stored close anchor compares committed rows with the target",dueDriven:!0,enforcement:"platform",gatesEvent:null,key:u,kind:"deadline",label:"Round closes against its stored threshold",tenantTunable:!1}],settlement:{name:t,pieces:[]}}}function Tt(e,t){let n=e.name,r=`${n}_entitlement`,o=`${Q(n)}Id`,a=U(`${n}_payout`),l=s=>({[o]:{bind:{currency:"fields.currency",[`${Q(e.source)}AccountId`]:`fields.${Q(e.source)}AccountId`},statuses:s}});return{design:[`${n}: reuses the catalog largest-remainder distribution; the evidence port freezes the claimant set before any payout`],extraNouns:[{actors:{[e.recipient]:"beneficiary",[e.source]:"payer"},desc:`One frozen weighted entitlement in ${n}`,fields:{currency:{desc:"Currency derived from the distribution",type:"currency"},[o]:{desc:`The exact ${n}`,type:`ref:${n}`},[e.weight.name]:H("Stored non-negative entitlement weight")},id:r,summary:`Frozen entitlement in ${n}`,title:`${B(n)} Entitlement`,verbs:{create:{requires:l(["open"]),summary:"Record one entitlement before snapshot",to:"recorded"},payout:{distribute:{amountRef:"payoutShare",onZero:"skip_steps",pool:{from:"parent",path:`fields.${e.amount.name}`},refField:o,statuses:["recorded","paid"],weightField:e.weight.name},from:["recorded"],moneyEvent:a,moves:[{amount:"refs.payoutShare",from:e.source,key:"payout",operation:"create",to:e.recipient}],requires:{[o]:{match:{"fields.currency":"fields.currency",[`fields.${Q(e.source)}AccountId`]:`fields.${Q(e.source)}AccountId`},statuses:["snapshotted"]}},summary:"Pay the deterministic largest-remainder share once",to:"paid"}}}],generatedPrefixNounIds:[r],feeLines:[],moneyEvents:[V({amount:"A deterministic largest-remainder share of the stored pool",fromActor:e.source,key:a,kind:"payout",occurrence:"repeatable",toActor:e.recipient,trigger:"Pay one frozen entitlement"})],noun:{actors:{[e.source]:"payer"},aggregateInvariants:[{count:!0,childNounId:r,childRefField:o,childStatuses:["recorded","paid"],parentField:"maxRecipients"}],desc:"Evidence-frozen weighted distribution",fields:{currency:{desc:`Currency fixed to ${e.amount.currency}`,type:"currency"},[e.amount.name]:H(`Distribution pool in ${e.amount.currency} minor units`),[e.recordAtField]:se("Stored record date"),maxRecipients:{desc:`Exactly ${e.maxRecipients} frozen entitlement rows`,type:`const:${e.maxRecipients}`}},id:n,summary:"Frozen largest-remainder distribution",title:B(n),verbs:{create:{summary:"Open entitlement recording",to:"open"},[e.snapshot.port]:{captureInput:{snapshotEvidenceReference:"evidenceReference"},from:["open"],port:{allowed:t.allowed,fields:{evidenceReference:"text"}},summary:"Freeze the entitlement set from stored evidence",to:"snapshotted"}}},rules:[],settlement:{name:n,pieces:[]}}}function Ft(e){let t=e.name,n=`${t}_draw`,r=`${Q(t)}Id`,o=`${Q(e.obligation.settlement)}Id`,a=U(`${t}_draw`),l=U(`${t}_expiry`),s=e.availabilityPolicy==="revolving"?["drawn"]:["drawn","resolved"];return{design:[`${t}: owns reusable draw capacity only; ${e.obligation.settlement} remains the sole repayment and delinquency owner`],extraNouns:[{actors:{[e.drawDestination]:"beneficiary",[e.lender]:"payer"},desc:`One capacity-capped draw linked to ${e.obligation.settlement}`,fields:{amount:H("One draw amount"),currency:{desc:"Currency derived from the facility",type:"currency"},[r]:{desc:`The exact ${t}`,type:`ref:${t}`},[o]:{desc:"The sole repayment obligation",type:`ref:${e.obligation.settlement}`}},id:n,summary:`Draw from ${t}`,title:`${B(t)} Draw`,verbs:{create:{moneyEvent:a,moves:[{amount:"amount",from:e.lender,key:"draw",operation:"create",to:e.drawDestination}],requires:{[r]:{bind:{currency:"fields.currency",[`${Q(e.drawDestination)}AccountId`]:`fields.${Q(e.drawDestination)}AccountId`,[`${Q(e.lender)}AccountId`]:`fields.${Q(e.lender)}AccountId`},statuses:["active"]},[o]:{statuses:["active"],unique:!0}},requiresExposure:[{amountField:"amount",anchorField:r,capField:e.limit.name,capOnAnchor:!0,childNounId:n,statuses:s}],summary:"Create one draw under the locked facility capacity",to:"drawn"},resolve:{from:["drawn"],requires:{[o]:["repaid","written_off"]},summary:"Release revolving capacity only after the linked obligation resolves",to:"resolved"}}}],generatedPrefixNounIds:[n],feeLines:[],moneyEvents:[V({amount:"One draw under the stored facility limit",fromActor:e.lender,key:a,kind:"payout",occurrence:"repeatable",toActor:e.drawDestination,trigger:"Admit one linked draw"})],noun:{actors:{[e.borrower]:"party",[e.drawDestination]:"beneficiary",[e.lender]:"payer"},desc:"Reusable capacity with repayment delegated to one scheduled obligation",fields:{currency:{desc:`Currency fixed to ${e.limit.currency}`,type:"currency"},[e.limit.name]:H(`Facility limit in ${e.limit.currency} minor units`),[e.expiresAtField]:se("Stored draw expiry")},id:t,summary:`Draw capacity for ${e.borrower.replaceAll("_"," ")}`,title:B(t),verbs:{create:{summary:"Open the facility",to:"active"},freeze:{due:{field:e.expiresAtField,rule:l},from:["active"],summary:"Freeze new draws at expiry",to:"frozen"},close:{from:["active","frozen"],requiresAggregate:[{check:{kind:"all_in"},nounId:n,over:"children",refField:r,statuses:["resolved"]}],summary:"Close only when every admitted draw resolved",to:"closed"}}},rules:[{allowedActors:[],detail:"The stored expiry freezes new draws without changing repayment state",dueDriven:!0,enforcement:"platform",gatesEvent:null,key:l,kind:"deadline",label:"Facility freezes at expiry",tenantTunable:!1}],settlement:{name:t,pieces:[]}}}function Rt(e,t){let n=e.name,r=`${n}_approved_amount`,o=`${Q(n)}Id`,a=U(`${n}_payout`),l=`${Q(e.source)}AccountId`,s=`${Q(e.destination)}AccountId`,u={[o]:{match:{"fields.currency":"fields.currency",[`fields.${s}`]:`fields.${s}`,[`fields.${l}`]:`fields.${l}`},statuses:["submitted"]}};return{design:[`${n}: a stored external decision may approve one amount under the cap; recovery requires a separate transfer`],extraNouns:[{actors:{[e.destination]:"beneficiary",[e.source]:"payer"},desc:`One evidence-gated amount under ${n}`,fields:{amount:H("Approved amount under the parent cap"),currency:{desc:"Currency derived from the parent cap",type:"currency"},[o]:{desc:`The exact ${n}`,type:`ref:${n}`}},id:r,summary:`Approved amount under ${n}`,title:`${B(n)} Approved Amount`,verbs:{create:{requires:{[o]:{bind:{currency:"fields.currency",[s]:`fields.${s}`,[l]:`fields.${l}`},statuses:["submitted"],unique:!0}},summary:"Create one candidate amount under the parent",to:"created"},approve:{captureInput:{decisionEvidenceReference:"evidenceReference"},from:["created"],port:{allowed:t.allowed,fields:{evidenceReference:"text"}},requires:u,requiresExposure:[{amountField:"amount",anchorField:o,capField:e.cap.name,capOnAnchor:!0,childNounId:r,statuses:["approved","paid"]}],summary:"Store one externally approved amount under the cap",to:"approved"},pay:{from:["approved"],moneyEvent:a,moves:[{amount:"amount",from:e.source,key:"payout",operation:"create",to:e.destination}],requires:u,summary:"Pay the stored approved amount once",to:"paid"}}}],generatedPrefixNounIds:[r],feeLines:[],moneyEvents:[V({amount:"The stored approved amount under the cap",fromActor:e.source,key:a,kind:"payout",occurrence:"repeatable",toActor:e.destination,trigger:"Pay one approved amount"})],noun:{actors:{[e.destination]:"beneficiary",[e.source]:"payer"},desc:"Capped disbursement controlled by stored external evidence",fields:{currency:{desc:`Currency fixed to ${e.cap.currency}`,type:"currency"},[e.cap.name]:H(`Disbursement cap in ${e.cap.currency} minor units`)},id:n,summary:`Capped disbursement to ${e.destination.replaceAll("_"," ")}`,title:B(n),verbs:{create:{summary:"Submit the capped disbursement",to:"submitted"},deny:{captureInput:{decisionEvidenceReference:"evidenceReference"},from:["submitted"],port:{allowed:t.allowed,fields:{evidenceReference:"text"}},requiresAggregate:[{check:{kind:"all_in"},nounId:r,over:"children",refField:o,statuses:["created"]}],summary:"Record a denial without moving money",to:"denied"}}},rules:[],settlement:{name:n,pieces:[]}}}function Dt(e){let t=e.name,n=`${Q(t)}Id`,r=U(`${t}_contribution`),o=U(`${t}_guarantee_contribution`),a=U(`${t}_payout`),l=[...new Set([...e.members,...e.payoutOrder,...e.guarantor?[e.guarantor]:[]])],s=Object.fromEntries(l.map(P=>{let _=`${Q(P)}AccountId`;return[_,`fields.${_}`]})),u=e.members.map(P=>`${t}_${P}_contribution`),w=e.members.map((P,_)=>{let g=u[_],C={create:{requires:{[n]:{bind:{currency:"fields.currency",...s,[e.schedule.firstDueField]:`fields.${e.schedule.firstDueField}`,[e.contribution.name]:`fields.${e.contribution.name}`},statuses:["forming"],unique:!0}},summary:`Create the fixed contribution row for ${P.replaceAll("_"," ")}`,to:"cycle_1_due"}};for(let D=0;D<e.schedule.count;D+=1){let I=D+1,Z=`cycle_${I}_due`,ee=`cycle_${I}_defaulted`,te=`cycle_${I}_funded`,q=`cycle_${I}_guaranteed`,h=I===e.schedule.count?"final_paid":`cycle_${I+1}_due`,T=U(`${t}_cycle_${I}_due`),J=e.contribution.name,A=e.contribution.name,R={field:e.schedule.firstDueField,rule:T,...Ce(e.schedule,D)};C[`contribute_cycle_${I}`]={due:R,from:[Z],moneyEvent:r,moves:[{amount:J,from:P,key:"contribution",operation:"create",to:"escrow"}],requires:{[n]:[`active_cycle_${I}`]},summary:`Fund ${P.replaceAll("_"," ")}'s cycle ${I} contribution`,to:te},C[`mark_default_cycle_${I}`]={due:R,from:[Z],requires:{[n]:[`active_cycle_${I}`]},summary:`Mark the stored cycle ${I} due condition`,to:ee},e.guarantor&&(C[`guarantee_cycle_${I}`]={from:[ee],moneyEvent:o,moves:[{amount:A,from:e.guarantor,key:"guarantee",operation:"create",to:"escrow"}],requires:{[n]:[`active_cycle_${I}`]},summary:`Fund the defaulted cycle ${I} amount before payout`,to:q}),C[`pay_cycle_${I}`]={from:[te],moneyEvent:a,moves:[{amount:J,from:"escrow",key:"payout",operation:"create",to:e.payoutOrder[D]}],requires:{[n]:[`cycle_${I}_ready`]},summary:`Pay this member's stored contribution into cycle ${I}'s shared pot recipient`,to:h},e.guarantor&&(C[`pay_guaranteed_cycle_${I}`]={from:[q],moneyEvent:a,moves:[{amount:A,from:"escrow",key:"payout",operation:"create",to:e.payoutOrder[D]}],requires:{[n]:[`cycle_${I}_ready`]},summary:`Pay the funded default into cycle ${I}'s stored recipient`,to:h})}return C.close={from:["final_paid"],requiresDrainedAccount:{path:"refs.escrowAccountId"},summary:"Complete after the final payout drains this member custody",to:"completed"},{actors:Object.fromEntries([[P,"payer"],...e.guarantor?[[e.guarantor,"payer"]]:[],...e.payoutOrder.map(D=>[D,"beneficiary"])]),desc:`Fixed contribution row for ${P.replaceAll("_"," ")}`,escrow:!0,fields:{[e.contribution.name]:H("Exact contribution amount shared by every cycle"),currency:{desc:"Currency derived from the pool",type:"currency"},[e.schedule.firstDueField]:se("First due anchor derived from the pool"),[n]:{desc:`The exact ${t}`,type:`ref:${t}`}},id:g,summary:`${P.replaceAll("_"," ")} contribution row`,title:`${B(t)} ${B(P)} Contribution`,verbs:C}}),v={create:{summary:"Create the fixed roster before activation",to:"forming"},cancel:{from:["forming"],summary:"Cancel before activation without moving money",to:"cancelled"},activate:{from:["forming"],requiresAggregate:u.map(P=>({check:{kind:"count_equals_field",field:"one"},nounId:P,over:"children",refField:n,statuses:["cycle_1_due"]})),summary:"Activate only after every fixed member row exists once",to:"active_cycle_1"}};for(let P=0;P<e.schedule.count;P+=1){let _=P+1;v[`ready_cycle_${_}`]={from:[`active_cycle_${_}`],requiresAggregate:u.map(g=>({check:{kind:"all_in"},nounId:g,over:"children",refField:n,statuses:[`cycle_${_}_funded`,...e.guarantor?[`cycle_${_}_guaranteed`]:[]]})),summary:`Lock cycle ${_} only after every member row is funded or guaranteed`,to:`cycle_${_}_ready`},v[`advance_cycle_${_}`]={from:[`cycle_${_}_ready`],requiresAggregate:u.map(g=>({check:{kind:"all_in"},nounId:g,over:"children",refField:n,statuses:[_===e.schedule.count?"completed":`cycle_${_+1}_due`]})),summary:_===e.schedule.count?"Complete after the final shared pot pays":`Advance after every cycle ${_} contribution pays`,to:_===e.schedule.count?"completed":`active_cycle_${_+1}`}}return{design:[`${t}: fixed roster and stored payout order; one member-specific row per member avoids tuple identity and keeps each cycle idempotent`],extraNouns:w,generatedPrefixNounIds:u,feeLines:[],moneyEvents:[V({amount:"One exact member contribution",fromActor:e.members[0],key:r,kind:"charge",occurrence:"repeatable",toActor:"escrow",trigger:"Fund one member and cycle"}),...e.guarantor?[V({amount:"One exact defaulted contribution",fromActor:e.guarantor,key:o,kind:"charge",occurrence:"repeatable",toActor:"escrow",trigger:"Fund one defaulted member and cycle"})]:[],V({amount:"One exact member contribution from the cycle pot",fromActor:"escrow",key:a,kind:"payout",occurrence:"repeatable",toActor:e.payoutOrder[0],trigger:"Pay the stored cycle recipient"})],noun:{actors:Object.fromEntries([...e.members.map(P=>[P,"party"]),...e.guarantor?[[e.guarantor,"payer"]]:[]]),desc:"Fixed rotating contribution and payout order",fields:{currency:{desc:`Currency fixed to ${e.contribution.currency}`,type:"currency"},[e.contribution.name]:H(`Exact contribution in ${e.contribution.currency} minor units`),[e.schedule.firstDueField]:se("Stored first contribution due date"),one:{desc:"Exact fixed member-row count",type:"const:1"}},id:t,summary:`${e.members.length}-member rotating pool`,title:B(t),verbs:v},rules:Array.from({length:e.schedule.count},(P,_)=>({allowedActors:[],detail:`Cycle ${_+1} default follows its stored due condition`,dueDriven:!0,enforcement:"platform",gatesEvent:null,key:U(`${t}_cycle_${_+1}_due`),kind:"deadline",label:`Cycle ${_+1} due condition`,tenantTunable:!1})),settlement:{name:t,pieces:[]}}}function Ce(e,t){return t===0?{}:{offset:`P${e.every.days*t}D`}}function Nt(e,t,n){let r=e.name,o=e.amount.name,a=`${r.replaceAll(/_([a-z])/g,(T,J)=>J.toUpperCase())}Id`,l=tn(e.schedule.count),s=l.map((T,J)=>`installment${J+1}Amount`),u=l.map((T,J)=>`${r}_installment_${J+1}_payment`),w="active",v=T=>`installment_${T+1}_delinquent`,P=l.map((T,J)=>v(J)),_=[w,...P],g=U(`${r}_repayment`),C=U(`${r}_refund`),D=U(`${r}_advance`),I={currency:{desc:`Currency fixed to ${e.amount.currency}`,type:"currency"},[o]:H(`The principal in ${e.amount.currency} minor units; the stored installment anchors partition it exactly`),[e.schedule.firstDueField]:se(`Due date of the first installment; later anchors use fixed offsets of ${e.schedule.every.raw}`)};for(let[T,J]of s.entries())I[J]=H(`Stored amount for installment ${T+1} of ${e.schedule.count}${T===0?" (carries the integer-division remainder)":""}`),I[`installment${T+1}DelinquentAfter`]=mt(`Machine-set marker proving installment ${T+1} reached its stored due date while unpaid`);let Z=u.map((T,J)=>({childField:"amount",childNounId:T,childRefField:a,childStatuses:["paid"],parentField:s[J]})),ee={create:{summary:`Create a ${B(r).toLowerCase()} obligation`,to:"draft"},approve:{from:["draft"],summary:"Approve the immutable principal partition and stored anchors",to:e.advanceTo?"approved":w},...e.advanceTo?{advance:{from:["approved"],moneyEvent:D,moves:[{amount:o,from:e.payee,key:"advance",operation:"create",to:e.advanceTo}],summary:`Advance the principal to the ${e.advanceTo.replaceAll("_"," ")}; the internal ledger receipt is the confirmation`,to:w}}:{},write_off:{from:["draft",...e.advanceTo?["approved"]:[],..._],summary:"Write off the remaining exposure without moving money",to:"written_off"}},te=[];for(let[T,J]of u.entries()){let A=T+1,R=U(`${r}_installment_${A}_due`),N={field:e.schedule.firstDueField,rule:R,...Ce(e.schedule,T)},M=oe=>[{check:{amountField:"amount",kind:oe,targetField:s[T]},nounId:J,over:"children",refField:a,statuses:["paid"]}];ee[`mark_installment_${A}_delinquent`]={due:N,from:_.filter(oe=>oe!==v(T)),requiresAggregate:M("sum_below"),setsAt:{field:`installment${A}DelinquentAfter`,marker:!0,offset:"PT1S"},summary:`Mark installment ${A} delinquent only when its due anchor is unmet`,to:v(T)},ee[`collect_installment_${A}`]={due:N,from:P,requiresAggregate:M("sum_exactly"),summary:`Close delinquent installment ${A} after linked payments reach its stored amount`,to:w},te.push({allowedActors:[],detail:`At stored anchor ${A}, the platform compares paid child rows with ${s[T]} and chooses paid or delinquent`,dueDriven:!0,enforcement:"platform",gatesEvent:null,key:R,kind:"deadline",label:`Installment ${A} resolves from its stored due condition`,tenantTunable:!1})}let q=U(`${r}_completion_due`);ee.complete={due:{field:e.schedule.firstDueField,rule:q,...Ce(e.schedule,l.length-1)},from:_,requiresAggregate:u.map((T,J)=>({check:{amountField:"amount",kind:"sum_exactly",targetField:s[J]},nounId:T,over:"children",refField:a,statuses:["paid"]})),summary:"Close the obligation only after every stored anchor is paid exactly",to:"repaid"},te.push({allowedActors:[],detail:"After the final stored anchor, the platform closes only when every anchor is paid exactly",dueDriven:!0,enforcement:"platform",gatesEvent:null,key:q,kind:"deadline",label:"Obligation completion follows exact aggregate repayment",tenantTunable:!1});let h=T=>{let J=T+1,A=u[T],R=_,N=`${e.payer.replaceAll(/_([a-z])/g,(pe,me)=>me.toUpperCase())}AccountId`,M=`${e.payee.replaceAll(/_([a-z])/g,(pe,me)=>me.toUpperCase())}AccountId`,oe={[a]:{bind:{currency:"fields.currency",[N]:`fields.${N}`,[M]:`fields.${M}`},statuses:R}},de={[a]:{match:{"fields.currency":"fields.currency",[`fields.${N}`]:`fields.${N}`,[`fields.${M}`]:`fields.${M}`},statuses:R}};return{actors:{[e.payee]:"beneficiary",[e.payer]:"payer"},desc:`One partial or full payment bound to installment ${J} of ${r}; the operation name fixes the anchor and ${a} fixes the obligation`,fields:{amount:H(`Positive payment amount capped with its paid siblings at ${s[T]}`),currency:{desc:"ISO 4217 currency derived from the obligation",type:"currency"},[a]:{desc:`The exact ${r.replaceAll("_"," ")} this payment belongs to`,type:`ref:${r}`}},id:A,summary:`Anchor-bound payment for installment ${J}`,title:`${B(r)} Installment ${J} Payment`,verbs:{create:{requires:oe,summary:`Create a payment record for installment ${J}`,to:"created"},repay:{...t&&n?{captureInput:{mandateEvidenceReference:"evidenceReference"},port:{allowed:n.allowed,fields:{evidenceReference:"text"}}}:{},from:["created"],moneyEvent:g,moves:[{amount:"amount",from:e.payer,key:"repayment",operation:"create",to:e.payee}],requires:de,requiresExposure:[{amountField:"amount",anchorField:a,capField:s[T],capOnAnchor:!0,childNounId:A,statuses:["paid"]}],summary:`Pay a partial or full amount against installment ${J}`,to:"paid"},refund:{from:["paid"],moneyEvent:C,moves:[{amount:"amount",from:e.payee,key:"refund",operation:"create",to:e.payer}],requires:de,summary:`Refund this one stored installment ${J} payment whole`,to:"refunded"}}}};return{design:[`${r}: existing scheduled mechanism in obligation mode; principal partitions into ${e.schedule.count} stored anchors; each payment operation names one anchor and one obligation`,`${r}: partial and early payments serialize under per-anchor aggregate caps; each refund reverses one paid row whole; rescheduling is refused by the checker`,`${r}: due-only delinquency and write-off change state without money; ${e.advanceTo?"advance is an internal ledger movement with no provider claim":"no advance is emitted"}`,...t?[`${t.name}: explicit collection attempts reuse ${r}'s anchor-bound repayment verbs; mandate evidence is captured per attempt; failures remain receipted failures and delinquency stays on ${r}`]:[]],extraNouns:u.map((T,J)=>h(J)),generatedPrefixNounIds:u,feeLines:[],moneyEvents:[...e.advanceTo?[V({amount:`The full ${o}`,fromActor:e.payee,key:D,kind:"payout",toActor:e.advanceTo,trigger:"Advance the approved principal once"})]:[],V({amount:"A positive amount capped by its stored installment anchor",fromActor:e.payer,key:g,kind:"installment",occurrence:"repeatable",toActor:e.payee,trigger:"Pay one anchor-bound partial or full installment amount"}),V({amount:"Exactly one stored paid installment payment",fromActor:e.payee,key:C,kind:"refund",occurrence:"repeatable",toActor:e.payer,trigger:"Refund one linked paid installment payment whole"})],noun:{actors:{...e.advanceTo?{[e.advanceTo]:"beneficiary"}:{},[e.payee]:"beneficiary",[e.payer]:"payer",[e.debtor]:"party"},aggregateInvariants:Z,desc:`Installment obligation for ${e.debtor.replaceAll("_"," ")}; ${e.payer.replaceAll("_"," ")} pays ${e.payee.replaceAll("_"," ")} against exact stored anchors`,fields:I,id:r,...we($e(o,s)),summary:`${e.schedule.count}-anchor obligation for ${e.debtor.replaceAll("_"," ")}`,title:B(r),verbs:ee},rules:te,settlement:{name:r,pieces:[]}}}function Lt(e){let t=e.name,n=e.amount.name,{schedule:r}=e,o=`${t}_schedule`,a=tn(r.count),l={[n]:H(`The total scheduled amount in ${e.amount.currency} minor units; the installment fields below partition it exactly`),[r.firstDueField]:se(`Due date of the first installment; installment k falls ${r.every.raw} after its predecessor`)},s=a.map((g,C)=>{let D=`installment${C+1}Amount`;return l[D]=H(`Installment ${C+1} of ${r.count}${C===0?" (carries the integer-division remainder)":""}: about ${W(a[C])} of ${n}, collected on its own stored-date anchor`),D}),u=a.map((g,C)=>`pay_installment_${C+1}`),w=ge(u,"active","settled","collecting"),v=`${t}_installments`,P=[V({amount:`The ${n}, partitioned into ${r.count} installments`,fromActor:e.payer,key:v,kind:"installment",occurrence:"repeatable",toActor:e.payee,trigger:`Collect each of the ${r.count} installments on its stored due date`})],_={create:{summary:`Create a ${B(t).toLowerCase()} plan`,to:"active"}};for(let[g,C]of s.entries())_[u[g]]={due:{field:r.firstDueField,rule:o,...Ce(r,g)},from:[w[g]?.from],moneyEvent:v,moves:[{key:"transfer",operation:"create",amount:C,from:e.payer,to:e.payee}],summary:`Collect installment ${g+1} of ${r.count}`,to:w[g]?.to};return{design:[`${t}: ${r.count} installments every ${r.every.raw} from ${r.firstDueField}; finite by construction, one idempotent anchor per installment`],feeLines:[],moneyEvents:P,noun:{actors:{[e.payer]:"payer",[e.payee]:"beneficiary"},desc:`Scheduled payment: the ${e.payer.replaceAll("_"," ")} pays ${n} to the ${e.payee.replaceAll("_"," ")} in ${r.count} installments, one every ${r.every.raw}`,fields:l,id:t,...we($e(n,s)),summary:`${r.count}-installment schedule from ${e.payer.replaceAll("_"," ")} to ${e.payee.replaceAll("_"," ")}`,title:B(t),verbs:_},rules:[{allowedActors:[],detail:`Each of the ${r.count} installments is collected once from its stored due date`,dueDriven:!0,enforcement:"platform",gatesEvent:null,key:o,kind:"deadline",label:"Installments collected on their stored due dates",tenantTunable:!1}],settlement:{name:t,pieces:[]}}}function Ot(e,t){return e.source.kind==="carve"?Bt(e,e.source.settlement,t):jt(e,e.source.schedule)}function Bt(e,t,n){let r=e.name,o=e.amount.name,a=e.feeBps>0,l=e.advanced.replaceAll("_"," "),s=e.funder.replaceAll("_"," "),u=t.replaceAll("_"," "),v=[{field:"carveHoldId",statuses:["funded"],target:t},...n.map((_,g)=>({field:`carveRecourse${g+1}Id`,statuses:["active"],target:_.name}))],P={[o]:H(`The advanced amount in ${e.amount.currency} minor units, disbursed to the ${l} up front`),...Object.fromEntries(v.map(_=>[_.field,{desc:`The ${_.target.replaceAll("_"," ")} bound to this advance`,type:`ref:${_.target}`}])),...a?{feeAmount:H(`${W(e.feeBps)} of ${o}, the funder's discount owed on top of the advance`),repayableAmount:H(`${o} + feeAmount: what the ${u} release owes the ${s}`)}:{}};return{design:[`${r}: ${o} advanced to the ${e.advanced} up front and repaid by carving the ${t} release${a?`; repayableAmount = ${o} + ${W(e.feeBps)} fee`:""}`],feeLines:a?[{label:`${B(e.funder)} discount`,on:`each ${r.replaceAll("_"," ")}`,structure:`${W(e.feeBps)} of the ${o}, owed on top out of the ${u} release`}]:[],moneyEvents:[V({amount:`The full ${o}`,fromActor:e.funder,key:`${r}_disburse`,kind:"payout",toActor:e.advanced,trigger:`Disburse the advance to the ${l}`})],noun:{actors:{[e.advanced]:"beneficiary",[e.funder]:"payer"},desc:`Advance: the ${s} disburses ${o} to the ${l} and is repaid out of the ${u} release, which pays the ${s} in the ${l}'s place${a?", plus the funder's discount":""}`,fields:P,id:r,...we(a?$e("repayableAmount",[o,"feeAmount"]):[]),summary:`Advance to the ${l} repaid by carving the ${u} release`,title:B(r),verbs:{create:{summary:`Create a ${B(r).toLowerCase()}`,to:"created"},disburse:{from:["created"],moneyEvent:`${r}_disburse`,moves:[{key:"transfer",operation:"create",amount:o,from:e.funder,to:e.advanced}],requires:Object.fromEntries(v.map(_=>[_.field,{match:{[`fields.${o}`]:`fields.${o}`,"fields.currency":"fields.currency"},statuses:_.statuses}])),summary:`Disburse the ${o} to the ${l}`,to:"advanced"},settle:{from:["advanced"],summary:`Close the advance once the ${u} has released to the ${s}`,to:"repaid"}}},rules:[{allowedActors:[],detail:`The ${u} releases the ${l}'s whole share to the ${s} instead of to the ${l}; the advance is repaid out of that release and never out of new money`,dueDriven:!1,enforcement:"platform",gatesEvent:null,key:`${r}_carve`,kind:"release_condition",label:`Repaid by carving the ${u} release`,tenantTunable:!1}],settlement:{name:r,pieces:[]}}}function jt(e,t){let n=e.name,r=e.amount.name,o=`${n}_schedule`,a=tn(t.count),l=e.feeBps>0,s=l?"repayableAmount":r,u={[r]:H(`The advanced amount in ${e.amount.currency} minor units, disbursed to the ${e.advanced.replaceAll("_"," ")} up front`),...l?{feeAmount:H(`${W(e.feeBps)} of ${r}, the funder's discount repaid on top of the advance`),repayableAmount:H(`${r} + feeAmount: the total the repayment fields below partition exactly`)}:{},[t.firstDueField]:se(`Due date of the first repayment; repayment k falls ${t.every.raw} after its predecessor`)},w=a.map((D,I)=>{let Z=`repayment${I+1}Amount`;return u[Z]=H(`Repayment ${I+1} of ${t.count}${I===0?" (carries the integer-division remainder)":""}: about ${W(a[I])} of ${s}, collected on its own stored-date anchor`),Z}),v=a.map((D,I)=>`collect_repayment_${I+1}`),P=ge(v,"advanced","repaid","repaying"),_=[V({amount:`The full ${r}`,fromActor:e.funder,key:`${n}_disburse`,kind:"payout",toActor:e.advanced,trigger:`Disburse the advance to the ${e.advanced.replaceAll("_"," ")}`})],g={create:{summary:`Create a ${B(n).toLowerCase()}`,to:"created"},disburse:{from:["created"],moneyEvent:`${n}_disburse`,moves:[{key:"transfer",operation:"create",amount:r,from:e.funder,to:e.advanced}],summary:`Disburse the ${r} to the ${e.advanced.replaceAll("_"," ")}`,to:"advanced"}},C=`${n}_repayments`;_.push(V({amount:`The ${s}, partitioned into ${t.count} repayments`,fromActor:e.advanced,key:C,kind:"installment",occurrence:"repeatable",toActor:e.funder,trigger:`Collect each of the ${t.count} repayments on its stored due date`}));for(let[D,I]of w.entries()){let Z=C;g[v[D]]={due:{field:t.firstDueField,rule:o,...Ce(t,D)},from:[P[D]?.from],moneyEvent:Z,moves:[{key:"transfer",operation:"create",amount:I,from:e.advanced,to:e.funder}],summary:`Collect repayment ${D+1} of ${t.count}`,to:P[D]?.to}}return{design:[`${n}: ${r} advanced up front; ${t.count} repayments every ${t.every.raw} conserve against ${s}${l?` (advance + ${W(e.feeBps)} fee)`:""}`],feeLines:l?[{label:`${B(e.funder)} discount`,on:`each ${n.replaceAll("_"," ")}`,structure:`${W(e.feeBps)} of the ${r}, repaid on top of the advance`}]:[],moneyEvents:_,noun:{actors:{[e.funder]:"payer",[e.advanced]:"beneficiary"},desc:`Advance: the ${e.funder.replaceAll("_"," ")} disburses ${r} to the ${e.advanced.replaceAll("_"," ")}, repaid over ${t.count} scheduled repayments${l?" plus the funder's discount":""}`,fields:u,id:n,...we([...$e(s,w),...l?$e("repayableAmount",[r,"feeAmount"]):[]]),summary:`Advance to ${e.advanced.replaceAll("_"," ")} repaid over ${t.count} anchors`,title:B(n),verbs:g},rules:[{allowedActors:[],detail:`Each of the ${t.count} repayments is collected once from its stored due date`,dueDriven:!0,enforcement:"platform",gatesEvent:null,key:o,kind:"deadline",label:"Repayments collected on their stored due dates",tenantTunable:!1}],settlement:{name:n,pieces:[]}}}function Jt(e){let t=e.name,n=`${t}_period`,r=e.rates[0]?.field.currency??"SAR",o={[e.closeByField]:se("End of this metering period; the close makes further charges unreachable")};for(let s of e.rates)o[s.field.name]=H(`Per-unit price of ${s.meter.replaceAll("_"," ")} in ${r} minor units, committed at period open`);let a=[],l={close_period:{due:{field:e.closeByField,rule:n},from:["open"],summary:"Close the metering period; no further usage can be charged",to:"closed"},create:{summary:`Open a ${B(t).toLowerCase()} period with its committed rate card`,to:"open"}};for(let s of e.rates){let u=U(`${t}_${s.meter}`);a.push(V({amount:`The committed ${s.field.name} per unit`,fromActor:e.payer,key:u,kind:"charge",occurrence:"repeatable",timing:"external_schedule",toActor:e.payee,trigger:`Charge one ${s.meter.replaceAll("_"," ")} at the committed rate`})),l[`charge_${s.meter}`]={from:["open"],moneyEvent:u,moves:[{key:"transfer",operation:"create",amount:s.field.name,from:e.payer,to:e.payee}],summary:`Charge one metered ${s.meter.replaceAll("_"," ")}; the emission is the transfer itself`,to:"open"}}return{design:[`${t}: committed rate card (${e.rates.map(s=>s.meter).join(", ")}); each usage charge IS the ledger transfer; period closes on ${e.closeByField}`],feeLines:[],moneyEvents:a,noun:{actors:{[e.payer]:"payer",[e.payee]:"beneficiary"},desc:`Metered usage: the ${e.payer.replaceAll("_"," ")} is charged per unit at the committed rate card until the period closes on its stored end date`,fields:o,id:t,summary:`Metered charges from ${e.payer.replaceAll("_"," ")} on a committed rate card`,title:B(t),verbs:l},rules:[{allowedActors:[],detail:"The period closes once from its stored end date",dueDriven:!0,enforcement:"platform",gatesEvent:null,key:n,kind:"deadline",label:"Period closed on its stored end date",tenantTunable:!1}],settlement:{name:t,pieces:[]}}}function qt(e){let t=e.name,n=e.amount.name,r=`${t}_payout`,o=e.shares.findIndex(g=>g.to===e.remainderTo),a=e.shares.map(g=>({bps:g.bps,field:`${Q(g.to)}ShareAmount`,origin:g.origin,releaseTo:g.to})),l={[n]:H(`The pooled period total in ${e.amount.currency} minor units; the share fields below partition it exactly`),[e.distributeDueField]:se("The period's payout date; the pool distributes from it")};for(let[g,C]of a.entries()){let D=g===Math.max(o,0)?" (carries the integer-division remainder)":"";l[C.field]=H(`${W(C.bps)} of ${n}${D}: the ${C.releaseTo.replaceAll("_"," ")}'s share. Computed as floor(${n} * ${C.bps} / 10000) in ${e.amount.currency} minor units`)}let s=a.map((g,C)=>`fund_share_${C+1}`),u=a.map((g,C)=>`distribute_share_${C+1}`),w=ge(s,"created","pooled","pooling"),v=ge(u,"pooled","distributed","distributing"),P=[],_={create:{summary:`Open a ${B(t).toLowerCase()} period`,to:"created"}};for(let[g,C]of a.entries()){let D=`${t}_pool_${g+1}`;P.push(V({amount:`${W(C.bps)} of the ${n}`,fromActor:e.payer,key:D,kind:"charge",toActor:"escrow",trigger:`Pool the ${C.releaseTo.replaceAll("_"," ")}'s share for the period`})),_[s[g]]={from:[w[g]?.from],moneyEvent:D,moves:[{key:"transfer",operation:"create",amount:C.field,from:e.payer,to:"escrow"}],summary:`Pool share ${g+1} of the period total`,to:w[g]?.to}}for(let[g,C]of a.entries()){let D=`${t}_payout_${g+1}`;P.push(V({amount:`${W(C.bps)} of the ${n}`,fromActor:"escrow",key:D,kind:"payout",toActor:C.releaseTo,trigger:`Distribute the ${C.releaseTo.replaceAll("_"," ")}'s share on the payout date`})),_[u[g]]={due:{field:e.distributeDueField,rule:r},from:[v[g]?.from],moneyEvent:D,moves:[{key:"transfer",operation:"create",amount:C.field,from:"escrow",to:C.releaseTo}],summary:`Distribute the ${C.releaseTo.replaceAll("_"," ")}'s share of the pool`,to:v[g]?.to}}return{design:[`${t}: pool of ${n} partitioned ${a.map(g=>`${W(g.bps)} ${g.releaseTo}`).join(" + ")}; distributes in full on ${e.distributeDueField}; remainder to ${e.remainderTo}`],feeLines:[],moneyEvents:P,noun:{actors:{[e.payer]:"payer",...Object.fromEntries(e.shares.map(g=>[g.to,"beneficiary"]))},desc:`Pooled split: the ${e.payer.replaceAll("_"," ")} pools the period's ${n} share by share; the pool distributes to every recipient in full on the stored payout date`,escrow:!0,fields:l,id:t,...we($e(n,a.map(g=>g.field))),summary:`Period pool from ${e.payer.replaceAll("_"," ")} split ${e.shares.length} ways`,title:B(t),verbs:_},rules:[{allowedActors:[],detail:"Every share of the pool distributes once from the stored payout date",dueDriven:!0,enforcement:"platform",gatesEvent:null,key:r,kind:"deadline",label:"Pool distributed on its stored payout date",tenantTunable:!1}],settlement:{name:t,pieces:a}}}function Ln(e){let t=Number(en),n=e.carveTo??e.payee,r=[];e.payeeFeeBps<t&&r.push({end:t-e.payeeFeeBps,to:n}),e.payeeFeeBps>0&&r.push({end:t,to:"platform"});let o=[],a=0;for(let v of e.onCancel?.shares??[])a+=v.bps,o.push({end:a,origin:v.origin,to:v.to});let l=[...new Set([...r.map(v=>v.end),...o.map(v=>v.end),t])].sort((v,P)=>v-P),s=(v,P)=>v.find(_=>P<_.end),u=[],w=0;for(let v of l){if(v<=w)continue;let P=s(r,w),_=s(o,w);u.push({bps:v-w,..._?{cancelTo:_.to}:{},field:`piece${u.length+1}Amount`,origin:_?.origin??e.amount.origin,releaseTo:P?.to??n}),w=v}return u}function On(e,t,n,r){let o=e.cancelTo?`; on cancellation to the ${e.cancelTo.replaceAll("_"," ")}`:"",a=t===0?" (carries the integer-division remainder)":"";return`${W(e.bps)} of ${n}${a}: released to the ${e.releaseTo.replaceAll("_"," ")}${o}. Computed as floor(${n} * ${e.bps} / 10000) in ${r} minor units`}function W(e){let t=e/100;return`${Number.isInteger(t)?t:t.toFixed(2).replace(/0$/,"")}%`}function Mt(e){let t=new Map(e.settlements.flatMap(r=>r.archetype==="advance"&&r.source.kind==="carve"?[[r.source.settlement,r.funder]]:[]));return`${e.settlements.map(r=>{switch(r.archetype){case"held_payment":{let o=r.onCancel?`; cancellation splits the held amount ${r.onCancel.shares.map(s=>`${W(s.bps)} to the ${s.to.replaceAll("_"," ")}`).join(" and ")}`:"",a=t.get(r.name),l=a?`the ${a.replaceAll("_"," ")} is paid on confirmed release, in the ${r.payee.replaceAll("_"," ")}'s place`:`the ${r.payee.replaceAll("_"," ")} is paid on confirmed release`;return`The ${r.payer.replaceAll("_"," ")} funds ${r.amount.name} into escrow and ${l}${o}`}case"captured_payment":return`The ${r.payer.replaceAll("_"," ")}'s ${r.amount.name} is reserved until ${r.reserveUntilField}, captured by the ${r.payee.replaceAll("_"," ")} in strict partial slices, then settled or released`;case"instant_transfer":return`The ${r.payer.replaceAll("_"," ")} pays ${r.amount.name} straight through to the ${r.payee.replaceAll("_"," ")}`;case"premium_forward":return`The ${r.payer.replaceAll("_"," ")}'s ${r.amount.name} forwards to the ${r.carrier.replaceAll("_"," ")} exactly once on binding`;case"deposit":return`The ${r.payer.replaceAll("_"," ")}'s ${r.amount.name} is reserved for the ${r.holder.replaceAll("_"," ")} until claimed or returned`;case"scheduled":return r.mode==="obligation"?`The ${r.debtor.replaceAll("_"," ")} owes ${r.amount.name}; ${r.advanceTo?`the ${r.payee.replaceAll("_"," ")} advances it to the ${r.advanceTo.replaceAll("_"," ")}, then `:""}the ${r.payer.replaceAll("_"," ")} repays the ${r.payee.replaceAll("_"," ")} over ${r.schedule.count} anchor-bound installments`:`The ${r.payer.replaceAll("_"," ")} pays ${r.amount.name} to the ${r.payee.replaceAll("_"," ")} over ${r.schedule.count} scheduled installments`;case"advance":return r.source.kind==="carve"?`The ${r.funder.replaceAll("_"," ")} advances ${r.amount.name} to the ${r.advanced.replaceAll("_"," ")}, repaid out of the ${r.source.settlement.replaceAll("_"," ")} release`:`The ${r.funder.replaceAll("_"," ")} advances ${r.amount.name} to the ${r.advanced.replaceAll("_"," ")}, repaid over ${r.source.schedule.count} anchors`;case"metered":return`The ${r.payer.replaceAll("_"," ")} is charged per metered unit at a committed rate card until the period closes`;case"pooled_split":return`The ${r.payer.replaceAll("_"," ")} pools ${r.amount.name} and it distributes ${r.shares.length} ways on the payout date`;case"settlement_batch":return`The ${r.settlementAccount.replaceAll("_"," ")} freezes capture lineage and pays one signed net amount to the ${r.payoutDestination.replaceAll("_"," ")}`;case"funding_round":return`The ${r.contributor.replaceAll("_"," ")} commits under ${r.target.name} until the stored close anchor activates or fails the round`;case"weighted_distribution":return`The ${r.source.replaceAll("_"," ")} pays a frozen claimant set by deterministic largest remainder`;case"credit_facility":return`The ${r.lender.replaceAll("_"," ")} admits draws under ${r.limit.name}; ${r.obligation.settlement.replaceAll("_"," ")} owns repayment`;case"recurring_collection":return`${r.name.replaceAll("_"," ")} adds explicit mandate evidence to ${r.obligation.settlement.replaceAll("_"," ")} repayment attempts`;case"conditional_disbursement":return`The ${r.source.replaceAll("_"," ")} pays one evidence-approved amount under ${r.cap.name} to the ${r.destination.replaceAll("_"," ")}`;case"rotating_pool":return`${r.members.length} fixed members contribute one exact amount per cycle in a stored payout order`;case"swap":return`The ${r.sides[0].party.replaceAll("_"," ")} and ${r.sides[1].party.replaceAll("_"," ")} fund one shared escrow and the entire two-sided trade releases or reverses together`}}).join(". ")}.`.slice(0,400)}function Q(e){let[t,...n]=e.split("_");return(t??"")+n.map(r=>r.charAt(0).toUpperCase()+r.slice(1)).join("")}function B(e){let t=e.replaceAll("_"," ");return t.charAt(0).toUpperCase()+t.slice(1)}var Ut=["asset","from","import","party","port","program","settlement"],Bn=new Set(["{","}","(",")","[","]",":",",","=","|","."]),Kt=new Set(Ut),zt=e=>/[A-Za-z]/.test(e),Ht=e=>/[A-Za-z0-9_]/.test(e),Le=e=>e>="0"&&e<="9";function jn(e){let t=[],n=[],r=0,o=(a,l,s,u=s)=>{t.push({kind:a,span:{end:r,start:l},text:s,value:u})};for(;r<e.length;){let a=e[r];if(a===" "||a===" "||a==="\r"||a===`
3
- `){r+=1;continue}if(a==="/"&&e[r+1]==="/"){for(;r<e.length&&e[r]!==`
4
- `;)r+=1;continue}if(Bn.has(a)){let s=r;r+=1,o("punct",s,a);continue}if(a==='"'){let s=r;r+=1;let u="",w=!1;for(;r<e.length;){let v=e[r];if(v==='"'){r+=1,w=!0;break}if(v===`
5
- `)break;u+=v,r+=1}w||n.push({message:"this string never closes; add the ending double quote",span:{end:r,start:s}}),o("string",s,e.slice(s,r),u);continue}if(Le(a)){let s=r;for(;r<e.length&&Le(e[r]);)r+=1;if(e[r]==="."&&Le(e[r+1]??""))for(r+=1;r<e.length&&Le(e[r]);)r+=1;let u=e.slice(s,r);e[r]==="%"?(r+=1,o("percent",s,e.slice(s,r),u)):o("number",s,u,u);continue}if(zt(a)){let s=r;for(;r<e.length&&Ht(e[r]);)r+=1;let u=e.slice(s,r);o(Kt.has(u)?"keyword":"ident",s,u);continue}let l=r;for(;r<e.length&&!/[\sA-Za-z0-9_"]/.test(e[r])&&!Bn.has(e[r])&&!(e[r]==="/"&&e[r+1]==="/");)r+=1;r===l&&(r+=1),n.push({message:`"${e.slice(l,r)}" is not part of the HSX language`,span:{end:r,start:l}})}return t.push({kind:"eof",span:{end:e.length,start:e.length},text:"",value:""}),{diagnostics:n,tokens:t}}var Ee=Object.freeze({maxNestingDepth:64,maxSourceBytes:262144});function Jn(e){let t=new TextEncoder().encode(e).byteLength;if(t>Ee.maxSourceBytes)return{diagnostics:[{message:`this file is ${t} bytes; HSX reads at most ${Ee.maxSourceBytes}`,span:{end:0,start:0}}],program:{decls:[],span:{end:0,start:0}}};let n=jn(e),r=new rn(n.tokens,[...n.diagnostics]),o=r.parseProgram(e.length);return{diagnostics:r.diagnostics,program:o}}var rn=class{diagnostics;tokens;index=0;depth=0;constructor(t,n){this.tokens=t,this.diagnostics=n}parseProgram(t){let n=[];for(;!this.at("eof");){let r=this.parseDecl();if(r){n.push(r);continue}this.recoverToDecl()}return{decls:n,span:{end:t,start:0}}}parseDecl(){let t=this.peek();if(t.kind!=="keyword"||t.text==="from"){this.error(t.span,t.kind==="eof"?"the program ends unexpectedly":`expected a declaration (program, import, party, asset, settlement, or port), found "${t.text}"`);return}switch(t.text){case"program":return this.parseProgramDecl();case"import":return this.parseImportDecl();case"party":return this.parsePartyDecl();case"asset":return this.parseAssetDecl();case"settlement":return this.parseSettlementDecl();case"port":return this.parsePortDecl();default:this.error(t.span,`"${t.text}" cannot start a declaration`),this.advance();return}}parseProgramDecl(){let t=this.advance(),n=this.expectIdent("the program needs a snake_case name");if(!n)return;let r;if(this.at("string")){let o=this.advance();r={kind:"string",span:o.span,value:o.value}}return{kind:"program",name:n,span:this.spanFrom(t.span),...r?{title:r}:{}}}parseImportDecl(){let t=this.advance();if(!this.expectPunct("{",'import lists its names in braces: import { held_payment } from "settlement"'))return;let n=[];for(;!this.atPunct("}")&&!this.at("eof");){let o=this.expectIdent("expected an imported name");if(!o)return;n.push(o),this.atPunct(",")&&this.advance()}if(!this.expectPunct("}","the import name list never closes"))return;if(!this.at("keyword")||this.peek().text!=="from"){this.error(this.peek().span,'import needs from: import { held_payment } from "settlement"');return}if(this.advance(),!this.at("string")){this.error(this.peek().span,'the import source must be a quoted module name like "settlement"');return}let r=this.advance();return n.length===0&&this.error(t.span,"import brings in at least one name"),{from:{kind:"string",span:r.span,value:r.value},kind:"import",names:n,span:this.spanFrom(t.span)}}parsePartyDecl(){let t=this.advance(),n=this.expectIdent("the party needs a name, like: party buyer: person");if(!n||!this.expectPunct(":",`party ${n.name} needs a kind, like: party ${n.name}: person`))return;let r=this.expectIdent(`expected a kind for party ${n.name}`);if(!r)return;let o=this.atPunct("{")?this.parseBlock():void 0;return{...o?{attrs:o}:{},kind:"party",name:n,partyKind:r,span:this.spanFrom(t.span)}}parseAssetDecl(){let t=this.advance(),n=this.expectIdent("the asset needs a name, like: asset vehicle: good");if(!n||!this.expectPunct(":",`asset ${n.name} needs a kind, like: asset ${n.name}: good`))return;let r=this.expectIdent(`expected a kind for asset ${n.name}`);if(!r)return;let o=this.atPunct("{")?this.parseBlock():void 0;return{assetKind:r,...o?{attrs:o}:{},kind:"asset",name:n,span:this.spanFrom(t.span)}}parseSettlementDecl(){let t=this.advance(),n=this.expectIdent("the settlement needs a name, like: settlement sale = held_payment { ... }");if(!n||!this.expectPunct("=",`settlement ${n.name} instantiates an archetype: settlement ${n.name} = held_payment { ... }`))return;let r=this.expectIdent(`expected an archetype name for settlement ${n.name}`);if(!r)return;if(!this.atPunct("{")){this.error(this.peek().span,`settlement ${n.name} needs a body in braces`);return}let o=this.parseBlock();if(o)return{archetype:r,body:o,kind:"settlement",name:n,span:this.spanFrom(t.span)}}parsePortDecl(){let t=this.advance(),n=this.expectIdent("the port needs a name, like: port confirm_handover { ... }");if(!n)return;if(!this.atPunct("{")){this.error(this.peek().span,`port ${n.name} needs a body in braces`);return}let r=this.parseBlock();if(r)return{body:r,kind:"port",name:n,span:this.spanFrom(t.span)}}enterNesting(t){return this.depth>=Ee.maxNestingDepth?(this.error(t,`this nests past the parser's depth budget of ${Ee.maxNestingDepth}; flatten it`),!1):(this.depth+=1,!0)}parseBlock(){if(!this.enterNesting(this.peek().span))return;let t=this.parseBlockUnguarded();return this.depth-=1,t}parseBlockUnguarded(){let t=this.advance(),n=[];for(;!this.atPunct("}")&&!this.at("eof");){let r=this.index,o=this.parseEntry();if(!o){this.recoverInBlock(),this.index===r&&this.advance();continue}n.push(o),this.atPunct(",")&&this.advance()}return this.expectPunct("}","this block never closes; add the matching }")?{entries:n,kind:"block",span:this.spanFrom(t.span)}:{entries:n,kind:"block",span:this.spanFrom(t.span)}}parseEntry(){let t=this.expectIdent("expected an entry name here");if(!t)return;let n=[];if(this.atPunct("(")){for(this.advance();!this.atPunct(")")&&!this.at("eof");){let o=this.expectIdent(`expected a qualifier inside ${t.name}( ... )`);if(!o)return;n.push(o),this.atPunct(",")&&this.advance()}if(!this.expectPunct(")",`${t.name}( ... ) never closes`))return}let r;if(this.atPunct("{"))r=this.parseBlock();else if(this.atPunct(":"))this.advance(),r=this.parseExpr();else{this.error(this.peek().span,`entry ${t.name} needs a value: either "${t.name}: <value>" or "${t.name} { ... }"`);return}if(r)return{key:t,qualifiers:n,span:{end:r.span.end,start:t.span.start},value:r}}parseExpr(){if(!this.enterNesting(this.peek().span))return;let t=this.parseExprUnguarded();return this.depth-=1,t}parseExprUnguarded(){let t=this.peek();if(t.kind==="string")return this.advance(),{kind:"string",span:t.span,value:t.value};if(t.kind==="number")return this.advance(),{kind:"number",raw:t.value,span:t.span};if(t.kind==="percent"){this.advance();let n=Yt(t.value);return n===void 0?(this.error(t.span,`${t.text} is finer than the money system can settle; percents go down to a hundredth (basis point), like 99.75%`),{bps:0,kind:"percent",raw:t.value,span:t.span}):{bps:n,kind:"percent",raw:t.value,span:t.span}}if(this.atPunct("[")){let n=this.advance(),r=[];for(;!this.atPunct("]")&&!this.at("eof");){let o=this.parseExpr();if(!o)return;r.push(o),this.atPunct(",")&&this.advance()}return this.expectPunct("]","this list never closes; add the matching ]")?{items:r,kind:"list",span:this.spanFrom(n.span)}:void 0}if(this.atPunct("{"))return this.parseBlock();if(t.kind==="keyword"&&t.text==="port"){let n=this.advance(),r=this.expectIdent("expected a port name after the port keyword");if(!r)return;let o;if(this.at("ident")&&this.peek().text==="within"&&(this.advance(),o=this.expectIdent("expected a fixed duration after within, like P14D"),!o))return;let a;if(this.atPunct("|")){if(this.advance(),!this.at("ident")||this.peek().text!=="at"){this.error(this.peek().span,"after | comes the date the platform decides on, like: | at(releaseDueAt)");return}if(this.advance(),!this.expectPunct("(","at names its date field in parentheses: at(releaseDueAt)")||(a=this.expectIdent("expected a stored date field inside at( ... ), like at(releaseDueAt)"),!a)||!this.expectPunct(")","at( ... ) never closes"))return}return{...a?{deadline:a}:{},kind:"port_ref",name:r,span:this.spanFrom(n.span),...o?{within:o}:{}}}if(t.kind==="ident"){let n=this.parseIdent();if(this.atPunct(".")){this.advance();let r=this.expectIdent(`expected the exit after ${n.name}., like ${n.name}.release`);return r?{kind:"settlement_ref",member:r,owner:n,span:{end:r.span.end,start:n.span.start}}:void 0}if(this.atPunct("(")){this.advance();let r=[];for(;!this.atPunct(")")&&!this.at("eof");){let o=this.parseExpr();if(!o)return;r.push(o),this.atPunct(",")&&this.advance()}return this.expectPunct(")",`${n.name}( ... ) never closes`)?{args:r,callee:n,kind:"call",span:this.spanFrom(n.span)}:void 0}if(this.atPunct(":")){this.advance();let r=this.parseExpr();return r?{kind:"binding",name:n,span:{end:r.span.end,start:n.span.start},type:r}:void 0}return n}this.error(t.span,t.kind==="eof"?"the program ends where a value was expected":`"${t.text}" is not a value HSX understands here`)}recoverToDecl(){for(;!this.at("eof");){let t=this.peek();if(t.kind==="keyword"&&t.text!=="from")return;this.advance()}}recoverInBlock(){let t=0;for(;!this.at("eof");){let n=this.peek();if(n.kind==="punct"){if((n.text==="{"||n.text==="["||n.text==="(")&&(t+=1),n.text==="}"||n.text==="]"||n.text===")"){if(t===0)return;t-=1}if(n.text===","&&t===0){this.advance();return}}if(n.kind==="keyword"&&t===0)return;this.advance()}}peek(){return this.tokens[this.index]}previous(){return this.tokens[Math.max(0,this.index-1)]}advance(){let t=this.peek();return t.kind!=="eof"&&(this.index+=1),t}at(t){return this.peek().kind===t}atPunct(t){let n=this.peek();return n.kind==="punct"&&n.text===t}parseIdent(){let t=this.advance();return{kind:"ident",name:t.text,span:t.span}}expectIdent(t){if(this.at("ident"))return this.parseIdent();this.error(this.peek().span,t)}expectPunct(t,n){return this.atPunct(t)?(this.advance(),!0):(this.error(this.peek().span,n),!1)}spanFrom(t){return{end:this.previous().span.end,start:t.start}}error(t,n){this.diagnostics.push({message:n,span:t})}};function Yt(e){let[t="0",n=""]=e.split(".");if(n.length>2)return;let r=n.padEnd(2,"0");return Number(t)*100+Number(r===""?"0":r)}function on(e){let t=[],n=En(e),r=(s,u,w,v)=>{let P=Sn(n,v);t.push({column:P.column,line:P.line,message:w,severity:u,stage:s})},o=Jn(e);for(let s of o.diagnostics)r("parse","error",s.message,s.span.start);if(o.diagnostics.length>0)return{diagnostics:t,verdict:"invalid"};let a=Cn(o.program);for(let s of a.diagnostics)r("check",s.severity,s.message,s.span.start);if(!a.program)return{diagnostics:t,verdict:"invalid"};let l=Rn(a.program);if(!l.ok){for(let s of l.issues)r("lower","error",s.message,s.span.start);return{diagnostics:t,verdict:"invalid"}}return{artifacts:{document:l.value.document,frame:l.value.frame},diagnostics:t,verdict:t.length>0?"warning":"valid"}}import{spawn as Vt}from"node:child_process";import{createHash as Wt}from"node:crypto";import{chmod as an,mkdir as Gt,readdir as Xt,readFile as qe,rename as Zt,unlink as Qt,writeFile as er}from"node:fs/promises";import{homedir as nr}from"node:os";import{basename as tr,dirname as cn,join as Me}from"node:path";var Oe="https://hyperscale0.ai",un="sandbox",pn="hyperscale-cli-session",rr="/v1/personal-access-tokens/current",dn=process.platform==="darwin"?"/usr/bin/security":null,or="config.json",Un=3e4,ar=2e3,ir=`hyperscale <command> [options]
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]
6
3
 
7
4
  Commands:
8
- auth login Save a founder personal access token (PAT)
5
+ start Create a Product and run its first published journey step
6
+ auth login Sign in through the portal or save a founder PAT
9
7
  auth status Verify and show the active founder PAT
10
8
  auth logout [--revoke] Forget the local founder PAT, optionally revoke it
11
9
  blueprint list List public Blueprints without authentication
12
10
  blueprint show <id> Show one public Blueprint
13
- product create Create a Product from a Blueprint
11
+ product create Create a Product from a Blueprint or HSX source
14
12
  product list List Products in the signed-in company
15
13
  product show [id] Show a Product (default: selected Product)
16
- product verbs [operation-id]
17
- List frozen public verbs or describe one exactly
18
- product run <operation-id> Run one frozen public verb
14
+ product select <id> Select the default Product for later commands
15
+ product actions [operation-id]
16
+ List frozen public actions or describe one exactly
17
+ product run <operation-id> Run one frozen public action
19
18
  compose check <file.hsx> Compile and check an HSX program
20
19
  compose plan <file.hsx> Diff an HSX program against the selected Product
21
20
  compose apply <file.hsx> Recompose the selected Product from checked HSX
22
21
  key create Create a sandbox Product API key
23
22
  key list List keys for the selected Product
24
23
  key revoke <id> Revoke a Product API key
25
- team list List company members and pending invitations
26
- team invite Invite a company member
27
24
  activity list List company activity
28
25
  whoami Show the user and company this founder PAT resolves to
29
26
  ops list [filter] List the product's callable operations
@@ -32,70 +29,100 @@ Commands:
32
29
  Options:
33
30
  --token <pat> Founder PAT (default: $HYPERSCALE_TOKEN)
34
31
  --revoke Revoke the active founder PAT during auth logout
32
+ --no-browser Skip browser login and print the founder PAT path
35
33
  --api-key <key> Product API key (default: $HYPERSCALE_API_KEY)
36
- --base-url <url> API origin (default: $HYPERSCALE_BASE_URL, else ${Oe})
37
- --environment <name> sandbox or live (default: $HYPERSCALE_ENVIRONMENT, else ${un})
38
- --email <email> Email for team invite
39
- --role <role> Seeded role name or custom role id for team invite
40
- --blueprint <id> Blueprint for product create
34
+ --base-url <url> API origin (default: $HYPERSCALE_BASE_URL, else ${de})
35
+ --environment <name> sandbox or live (default: $HYPERSCALE_ENVIRONMENT, else ${pe})
36
+ --blueprint <slug> Blueprint for non-interactive start or product create
37
+ --source <file> HSX source file for product create
41
38
  --name <name> Product or key name
42
- --product <id> Product id for key commands and Product-key verbs
39
+ --product <id> Product id for key commands and Product-key actions
40
+ --catalog-revision <id> Tenant catalog revision for HSX composition
43
41
  --input <json> JSON input object for call or product run
44
42
  --input-file <path> Read call or product run input from a JSON file
45
- --idempotency-key <key> Idempotency key for a mutation or public verb (default: generated)
43
+ --idempotency-key <key> Idempotency key for a mutation or public action (default: generated)
46
44
  --confirm Confirm compose apply for a person
47
45
  --yes Confirm compose apply without a prompt for an agent
48
- --passkey Print the portal pointer for passkey login
49
46
  --json Print machine-readable JSON
50
47
  --version Print the CLI version
51
48
  --help Print this help
52
49
 
53
- Founder PATs drive Product setup and company control. Product API keys call the
54
- selected Product's tenant API. The two credential species are not interchangeable.
55
- Passkey login runs in the portal at ${Oe}/signin.
50
+ Founder PAT commands: auth, whoami, product create/list/show, compose check/plan/apply,
51
+ key, and activity. Product API key commands: product actions/run, ops list,
52
+ and call. The server compiles every compose command against the selected tenant
53
+ catalog revision. The two credential types are not interchangeable. Browser
54
+ login returns through a single-use localhost callback.
56
55
 
57
56
  compose check, plan, and apply exit 2 when the compiler or composer refuses the
58
57
  program. Command, credential, request, and server failures exit 1. compose apply
59
58
  requires --confirm, or --yes for an agent.
59
+ Compose check and plan JSON retain operationId and receiptId when the server
60
+ returns them. Plan JSON includes the prerequisite check result and its identifiers.
60
61
 
61
62
  Use HYPERSCALE_TOKEN for a founder PAT. Use HYPERSCALE_API_KEY for a Product API
62
- key. The explicit flag wins over its environment variable.
63
+ key. The explicit flag wins over its environment variable. Founder logins use
64
+ macOS Keychain when available. Set HYPERSCALE_CREDENTIAL_STORE=file to keep the
65
+ founder PAT in the owner-only CLI profile instead and skip Keychain access.
63
66
 
64
- Request access at https://hyperscale0.ai/request-access.
67
+ ${N}
68
+ Request access at ${_}.
65
69
 
66
70
  Examples:
71
+ hyperscale start
72
+ hyperscale start --blueprint vehicle-escrow-marketplace --json
67
73
  hyperscale whoami
74
+ hyperscale auth login
68
75
  hyperscale auth login --token hyperscale_pat_...
69
76
  hyperscale blueprint list
70
- hyperscale product create --blueprint vehicle-escrow-marketplace --name "Vehicle Escrow"
77
+ hyperscale product create --blueprint luxury-goods-consignment-escrow --name "Luxury Consignment"
78
+ hyperscale product create --source company.hsx --name "Company"
71
79
  hyperscale key create --name "Founder laptop"
72
- hyperscale product verbs
73
- hyperscale product verbs escrow.release --json
74
- hyperscale product run escrow.release --input '{"saleId":"sale_sandbox_..."}'
80
+ hyperscale product actions
81
+ hyperscale product actions escrow_order.placeBuyerHold --json
82
+ hyperscale product run escrow_order.placeBuyerHold --input '{"escrowOrderId":"eord_sandbox_..."}'
75
83
  hyperscale compose check product.hsx
76
84
  hyperscale compose plan product.hsx --json
77
85
  hyperscale compose apply product.hsx --yes
78
- hyperscale team list
79
- hyperscale team invite --email developer@example.com --role developer
80
86
  hyperscale activity list
81
87
  hyperscale ops list account
82
88
  hyperscale call account.list --input '{"limit":5}'
83
89
  hyperscale call account.list --input-file input.json
84
90
  printf '{"limit":5}' | hyperscale call account.list
85
91
  hyperscale call account.retrieve --input '{"accountId":"acct_sandbox_..."}'
86
- `,x=class extends Error{},Be=class extends x{constructor(t,n){super(t),this.code="check_failed",this.details=n,this.exitCode=2}},sr=new Set(["--api-key","--base-url","--blueprint","--environment","--email","--idempotency-key","--input","--input-file","--name","--product","--role","--token"]);function cr(e){let t=[],n={};for(let r=0;r<e.length;r+=1){let o=e[r];if(!o.startsWith("--")){t.push(o);continue}if(sr.has(o)){let a=e[r+1];if(a===void 0)throw new x(`${o} needs a value`);n[o]=a,r+=1;continue}if(o==="--help"||o==="--version"||o==="--json"||o==="--confirm"||o==="--yes"||o==="--passkey"||o==="--revoke"){n[o]=!0;continue}throw new x(`Unknown option: ${o}`)}return{flags:n,positional:t}}function dr(e,t){let n=e["--api-key"]??t.HYPERSCALE_API_KEY;if(!n)throw new x("No API key. Set HYPERSCALE_API_KEY, or pass --api-key. Request access at https://hyperscale0.ai/request-access.");let r=e["--environment"]??t.HYPERSCALE_ENVIRONMENT??un;if(r!=="sandbox"&&r!=="live")throw new x(`Unknown environment: ${r}. Use sandbox or live.`);let o=(e["--base-url"]??t.HYPERSCALE_BASE_URL??Oe).replace(/\/+$/,"");return{apiKey:n,baseUrl:o,environment:r}}function Ue(e,t,n={}){let r=e["--environment"]??t.HYPERSCALE_ENVIRONMENT??n.environment??un;if(r!=="sandbox"&&r!=="live")throw new x(`Unknown environment: ${r}. Use sandbox or live.`);let o=(e["--base-url"]??t.HYPERSCALE_BASE_URL??n.baseUrl??Oe).replace(/\/+$/,""),a;try{a=new URL(o)}catch{a=null}let l=a?.origin??null;if(!l||l!==o)throw new x(`Invalid API origin: ${o}. Use an origin such as https://hyperscale0.ai.`);let s=["localhost","127.0.0.1","[::1]","::1"].includes(a.hostname);if(a.protocol!=="https:"&&!(a.protocol==="http:"&&s))throw new x(`Refusing cleartext API origin ${o}. Use HTTPS unless the API runs on loopback.`);return{baseUrl:o,environment:r}}function Kn(e){return e.HYPERSCALE_CONFIG_DIR??Me(nr(),".config","hyperscale")}function zn(e){return Me(Kn(e),or)}function he(e,t){return Me(Kn(t),`session-${Ie(e)}.json`)}async function mn(e,t){let n=he(e,t),r=`${tr(n)}.`,o;try{o=await Xt(cn(n),{withFileTypes:!0})}catch(a){if(a&&a.code==="ENOENT")return;throw a}for(let a of o){if(!a.isFile()||!a.name.startsWith(r))continue;let l=a.name.slice(r.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(l)&&await Se(Me(cn(n),a.name))}}async function lr(e){try{return JSON.parse(await qe(e,"utf8"))}catch(t){if(t&&t.code==="ENOENT")return null;throw t instanceof SyntaxError?new x(`${e} is not valid JSON`):t}}async function je(e,t){let n=ur(e);await Gt(n,{mode:448,recursive:!0}),await an(n,448);let r=`${e}.${process.pid}.${globalThis.crypto.randomUUID()}.tmp`;await er(r,t,{flag:"wx",mode:384}),await an(r,384);try{await Zt(r,e),await an(e,384)}catch(o){throw await Se(r),o}}function ur(e){return cn(e)}async function Se(e){try{await Qt(e)}catch(t){if(!t||t.code!=="ENOENT")throw t}}function pr(e,t){if(!e||typeof e!="object"||Array.isArray(e))throw new x(`${t} does not contain a CLI profile`);let{baseUrl:n,email:r,environment:o,selectedProduct:a}=e;if(typeof n!="string"||typeof r!="string"||o!=="sandbox"&&o!=="live"||!(a===null||typeof a=="string"))throw new x(`${t} does not contain a valid CLI profile`);return{baseUrl:n,email:r,environment:o,selectedProduct:a}}async function Pe(e){let t=zn(e),n=await lr(t);return n===null?null:pr(n,t)}async function Hn(e,t){let n={email:t.email,baseUrl:t.baseUrl,environment:t.environment,selectedProduct:t.selectedProduct??null};await je(zn(e),`${JSON.stringify(n,null,2)}
87
- `)}function Ie(e){return Wt("sha256").update(`${e.baseUrl}\0${e.environment}\0${e.email}`).digest("hex")}async function Ke(e,t){return dn===null?{error:null,status:null,stdout:"",unavailable:!0}:await new Promise(n=>{let r={...process.env};delete r.HYPERSCALE_API_KEY,delete r.HYPERSCALE_TOKEN;let o=Vt(dn,e,{env:r,stdio:["pipe","pipe","pipe"]}),a=[],l=!1,s=w=>{l||(l=!0,clearTimeout(u),n(w))},u=setTimeout(()=>{o.kill("SIGKILL"),s({error:null,status:null,stdout:"",unavailable:!0})},ar);o.stdout.on("data",w=>a.push(w)),o.stderr.on("data",()=>{}),o.stdin.on("error",()=>{}),o.once("error",w=>s({error:w,status:null,stdout:"",unavailable:!0})),o.once("close",w=>s({error:null,status:w,stdout:Buffer.concat(a).toString("utf8"),unavailable:!1})),t===void 0?o.stdin.end():o.stdin.end(`${t}
88
- `)})}async function fn(){return(await Ke(["show-keychain-info"])).status===0}function Yn(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 mr(e,t,n){await mn(e,n);let r=Ie(e);if(await fn()){let o=JSON.stringify(t),a=["add-generic-password","-a",r,"-s",pn,"-U","-X",Buffer.from(o,"utf8").toString("hex")].join(" ");if((await Ke(["-i"],a)).status===0)return await Se(he(e,n)),"keychain"}return await je(he(e,n),`${JSON.stringify({account:r,activeStore:"file",credential:t})}
89
- `),"file"}async function fr(e,t){let n=Ie(e);try{let r=JSON.parse(await qe(he(e,t),"utf8"));if(!r||typeof r!="object"||Array.isArray(r)||r.account!==n)return{state:"invalid"};if(r.revoked===!0)return{state:"revoked"};let o=Yn(r.credential);return o?{activeStore:r.activeStore==="file"?"file":null,credential:o,state:"valid"}:{state:"invalid"}}catch(r){return r&&r.code==="ENOENT"?{state:"missing"}:{state:"invalid"}}}async function yn(e,t){await mn(e,t);let n=await fr(e,t);if(n.state==="revoked")return null;if(n.state==="valid"&&n.activeStore==="file")return n.credential;let r=null;if(await fn()){let o=await Ke(["find-generic-password","-a",Ie(e),"-s",pn,"-w"]);o.status===0&&(r=Yn(o.stdout.trim()))}return r||(n.state==="valid"?n.credential:null)}async function Vn(e,t){await mn(e,t);let n=Ie(e);if(dn===null)return await Se(he(e,t)),{keychainDeleted:!0};if(!await fn())return await je(he(e,t),`${JSON.stringify({account:n,revoked:!0})}
90
- `),{keychainDeleted:!1};let r=await Ke(["delete-generic-password","-a",n,"-s",pn]);return r.status!==0&&r.status!==44?(await je(he(e,t),`${JSON.stringify({account:n,revoked:!0})}
91
- `),{keychainDeleted:!1}):(await Se(he(e,t)),{keychainDeleted:!0})}async function ue(e,t){let n=await Pe(t);if(!n)throw new x('Not logged in. Run "hyperscale auth login".');let r=Ue(e,t,n);if(r.baseUrl!==n.baseUrl||r.environment!==n.environment)throw new x(`The active founder login belongs to ${n.baseUrl} (${n.environment}). Log in again to change it.`);let o=await yn(n,t);if(!o)throw new x('Founder PAT is missing. Run "hyperscale auth login".');return{...n,...o}}function Wn(e){return e.replace(new RegExp("\\p{Cc}","gu"),t=>`
92
- \r`.includes(t)?t:"")}function Je(e){try{return new URL(e).origin}catch{return null}}function ke(e,t){let n=e;for(let r of t)typeof r=="string"&&r.length>0&&(n=n.replaceAll(r,"[redacted]"));return n}async function yr(e,t,n={},r){let o=`${e.baseUrl}${t}`,a=Je(e.baseUrl);if(Je(o)!==a)throw new x(`The requested path ${t} leaves the ${a} origin; refusing the request.`);try{let l=await fetch(o,{...n,headers:{accept:"application/json",...r?{authorization:`Bearer ${r}`}:{},"x-hyperscale-environment":e.environment,...n.headers},signal:AbortSignal.timeout(Un),redirect:"manual"});if(l.status>=300&&l.status<400)throw new x(`${o} redirected, so no credential was sent on. Point --base-url at the origin the API answers on.`);return{response:l,text:Wn(await l.text())}}catch(l){throw l instanceof x?l:new x(`Could not reach ${o}: ${l.message}`)}}async function ce(e,t,n={},r,o=[]){let{response:a,text:l}=await yr(e,t,n,r);if(!a.ok)throw hn(a,l,o);try{return JSON.parse(l)}catch{throw new x(`HTTP ${a.status} returned invalid JSON`)}}function be(e,t=globalThis.crypto.randomUUID()){return{body:JSON.stringify(e),headers:{"content-type":"application/json","idempotency-key":t},method:"POST"}}async function hr(){let e=[];for await(let t of process.stdin)e.push(Buffer.from(t));return Buffer.concat(e).toString("utf8")}async function ze(e,t,n={}){let r=`${e.baseUrl}${t}`,o=Je(e.baseUrl);if(Je(r)!==o)throw new x(`The product document puts ${t} on another origin than the ${o} 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(Un),redirect:"manual"});if(a.status>=300&&a.status<400)throw new x(`${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{response:a,text:Wn(await a.text())}}catch(a){throw a instanceof x?a:new x(`Could not reach ${r}: ${a.message}`)}}async function Gn(e){let{response:t,text:n}=await ze(e,"/v1/llms.txt");if(!t.ok)throw hn(t,n,[e.apiKey]);let r=/^# (.+)$/m.exec(n),o=/^> Generated for composition (\S+) /m.exec(n),a=/^## Operations \((\d+)\)$/m.exec(n);if(!r||!a)throw new Error("The product document is not in the expected format; upgrade the CLI.");let l=[],s=/^- ([A-Z]+) (\S+) · (\S+) \((\S+); idempotency (\S+)\)\n {2}Summary: (".*")\n {2}Description: (".*")$/gm;for(let v of n.matchAll(s))l.push({description:JSON.parse(v[7]),idempotency:v[5],method:v[1],name:v[3],operationId:v[4],path:v[2],summary:JSON.parse(v[6])});let u=Number(a[1]);if(l.length!==u)throw new x(`The product document declares ${u} operations but ${l.length} parsed. The server descriptor predates operation prose. Redeploy the platform, then recompose the Product.`);let w=/^- Package: (.+)$/m.exec(n);return{compositionId:o?o[1]:null,operations:l,packageName:w?w[1].trim():null,title:r[1].trim()}}function hn(e,t,n=[]){let r=ke(t.trim(),n);try{let o=JSON.parse(t);o&&o.error&&typeof o.error.message=="string"&&(r=ke(`${o.error.code}: ${o.error.message}`,n))}catch{}return new x(`HTTP ${e.status}${r?` \xB7 ${r}`:""}`)}function gn(e,t){return{authenticated:!0,baseUrl:e.baseUrl,email:t.email,environment:e.environment,expiresAt:t.expiresAt,personalAccessTokenId:t.personalAccessTokenId,role:t.role,selectedProduct:e.selectedProduct,teamId:t.teamId,tenantId:t.tenantId,tokenName:t.name,userId:t.userId}}function gr(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"||typeof e.expiresAt!="string"||e.status!=="active")throw new x("personal_access_token.current returned invalid data");return e}async function He(e,t){return gr(await ce(e,rr,{},t,[t]))}async function $r(e,t){let n=Ue(e,t);if(e["--passkey"]){E(`Passkey login runs in the portal: ${n.baseUrl}/signin`);return}let r=e["--token"]??t.HYPERSCALE_TOKEN;if(!r)throw new x("No founder PAT. Set HYPERSCALE_TOKEN, or pass --token.");if(!r.startsWith("hyperscale_pat_"))throw new x("Founder PATs start with hyperscale_pat_. Product API keys belong in HYPERSCALE_API_KEY.");let o=await He(n,r),a=await Pe(t),l={email:o.email,...n,selectedProduct:a&&a.email===o.email&&a.baseUrl===n.baseUrl&&a.environment===n.environment?a.selectedProduct:null},s=await mr(l,{personalAccessTokenId:o.personalAccessTokenId,token:r,tokenName:o.name,tenantId:o.tenantId},t);try{await Hn(t,l)}catch(w){throw await Vn(l,t),w}s==="file"&&process.stderr.write(`macOS Keychain is unavailable. The founder PAT is in ${he(l,t)} with mode 0600.
93
- `);let u=gn(l,o);e["--json"]?re(u):E(`Logged in as ${o.email} with PAT ${o.name}.`)}async function br(e,t){let n=await Pe(t);if(!n){let l={authenticated:!1};e["--json"]?re(l):E("Not logged in.");return}let r=await yn(n,t);if(!r){let l={authenticated:!1};e["--json"]?re(l):E("Founder PAT missing.");return}let o=await He(n,r.token),a=gn(n,o);if(e["--json"]){re(a);return}E(`User: ${o.email}`),E(`Tenant: ${o.tenantId}`),E(`Role: ${o.role}`),E(`Token: ${o.name}`),E(`Expires: ${o.expiresAt}`),E(`API: ${n.baseUrl}`),E(`Environment: ${n.environment}`),E(`Product: ${n.selectedProduct??"not selected"}`)}async function vr(e,t){let n=await Pe(t);if(!n){e["--json"]?re({status:"signed_out"}):E("Already logged out.");return}let r=await yn(n,t);if(e["--revoke"]&&!r)throw new x("The local founder PAT is missing, so the CLI cannot revoke it.");let o=r?.personalAccessTokenId,a=r?.tokenName;if(e["--revoke"]&&r){if(!o||!a){let u=await He(n,r.token);o=u.personalAccessTokenId,a=u.name}await ce(n,`/v1/personal-access-tokens/${encodeURIComponent(o)}/revoke`,be({tenantId:r.tenantId,personalAccessTokenId:o}),r.token,[r.token])}let l=await Vn(n,t),s=e["--revoke"]===!0;wr(e,{cleanup:l,personalAccessTokenId:o,revoked:s,status:"signed_out",tokenName:a})}function wr(e,t){let n=t.cleanup.keychainDeleted?"complete":"tombstoned";if(e["--json"])re({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 r=t.tokenName&&t.personalAccessTokenId?`${t.tokenName} (${t.personalAccessTokenId})`:"with unavailable local metadata";t.revoked?E(`Revoked founder PAT ${r} and forgot local state.`):(E(`Forgot local founder PAT ${r}.`),E("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.
94
- `)}function Te(e,t){if(!e||typeof e!="object"||!Array.isArray(e.items))throw new x(`${t} returned an invalid collection`);return e.items}async function Ye(e,t,n,r,o,a=[]){let l=[],s=new Set,u,w;for(;;){let g=new URLSearchParams(n);u&&g.set("cursor",u);let C=g.size>0?`?${g}`:"",D=await ce(e,`${t}${C}`,{},o,a);w===void 0&&(w=D),l.push(...Te(D,r));let I=D.nextCursor;if(typeof I!="string"||I.length===0)break;if(s.has(I))throw new x(`${r} repeated cursor ${I}`);s.add(I),u=I}let{items:v,nextCursor:P,..._}=w;return{..._,items:l}}async function kr(e,t){let n=await Ye(e,"/v1/blueprints",{},"blueprint.list"),r=Te(n,"blueprint.list");if(t["--json"]){re(n);return}for(let o of r)E(`${o.id} ${o.name}${o.summary?` ${o.summary}`:""}`)}async function _r(e,t,n){if(!n)throw new x("blueprint show needs a Blueprint id");let r=await ce(e,`/v1/blueprints/${encodeURIComponent(n)}`);re(r)}async function Ar(e,t){let n=e["--blueprint"],r=e["--name"];if(!n)throw new x("product create needs --blueprint <id>");if(!r)throw new x("product create needs --name <name>");let o=await ue(e,t),a=await ce(o,"/v1/workspaces/blueprint-compose",be({blueprintId:n,name:r,tenantId:o.tenantId}),o.token,[o.token]);if(typeof a?.workspaceId!="string"||typeof a?.blueprintId!="string"||typeof a?.workspaceBuildId!="string")throw new x("workspace.blueprint.compose returned an invalid Product");await Hn(t,{...o,selectedProduct:a.workspaceId});let l={blueprintId:a.blueprintId,nextSteps:[`hyperscale product show ${a.workspaceId}`,'hyperscale key create --name "Founder CLI"'],workspaceBuildId:a.workspaceBuildId,workspaceId:a.workspaceId};if(e["--json"]){re(l);return}E(`Product: ${l.workspaceId}`),E(`Blueprint: ${l.blueprintId}`),E(`Build: ${l.workspaceBuildId}`),E("Next:");for(let s of l.nextSteps)E(` ${s}`)}function Xn(e){return new URLSearchParams({tenantId:e}).toString()}async function xr(e,t){let n=await ue(e,t),r=await Ye(n,"/v1/products",{tenantId:n.tenantId},"product.list",n.token,[n.token]),o=Te(r,"product.list");if(e["--json"]){re(r);return}for(let a of o){let l=a.workspaceId??a.id??"unknown",s=a.displayName??a.name??"unnamed";E(`${l} ${s}${a.status?` ${a.status}`:""}`)}}async function Cr(e,t,n){let r=await ue(e,t),o=n??r.selectedProduct;if(!o)throw new x("product show needs an id because no Product is selected. Create a Product first.");let a=await ce(r,`/v1/products/${encodeURIComponent(o)}?${Xn(r.tenantId)}`,{},r.token,[r.token]);re(a)}function Zn(e,t){return t.map(n=>`${e}:${n.line}:${n.column}: ${n.severity} [${n.stage}] ${n.message}`)}function Er(e){return e.map(t=>`${t.path}: error [composer] ${t.code}: ${t.message}`)}async function Sr(e){if(!e)throw new x("compose needs a .hsx file");if(!e.endsWith(".hsx"))throw new x(`compose reads a .hsx file, got ${e}`);let t;try{t=await qe(e,"utf8")}catch(r){throw new x(`Could not read ${e}: ${r.message}`)}let n=on(t);if(n.verdict==="invalid"||!n.artifacts){let r=[...n.diagnostics];throw new Be(["HSX compilation failed.",...Zn(e,r)].join(`
95
- `),{diagnostics:r,file:e,issues:[],verdict:n.verdict})}return{file:e,result:n,source:t}}function Pr(e){if(!e||typeof e!="object"||typeof e.ok!="boolean"||!Array.isArray(e.issues))throw new x("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 x("composer.check returned an invalid issue");return{code:n.code,message:n.message,path:n.path}}),ok:e.ok}}async function $n(e,t,n,r){let o=await Sr(n),a=await ue(e,t),l=r?Fe(a,e):void 0,s=Pr(await ce(a,"/v1/composer/check",be({tenantId:a.tenantId,document:o.result.artifacts.document}),a.token,[a.token]));if(!s.ok){let u=[...o.result.diagnostics];throw new Be(["composer.check refused the program.",...Er(s.issues)].join(`
96
- `),{diagnostics:u,file:n,issues:s.issues,verdict:o.result.verdict})}return{check:s,compiled:o,context:a,workspaceId:l}}function bn(e,t){for(let n of Zn(e,t.diagnostics))process.stderr.write(`${n}
97
- `)}async function Ir(e,t,n){let r=await $n(e,t,n,!1);if(e["--json"]){re({command:"composer.check",diagnostics:r.compiled.result.diagnostics,file:n,issues:r.check.issues,ok:!0,verdict:r.compiled.result.verdict});return}bn(n,r.compiled.result),E(`Check passed: ${n}`)}async function Tr(e,t,n){let r=await $n(e,t,n,!0),o=await ce(r.context,"/v1/composer/plan",be({document:r.compiled.result.artifacts.document,tenantId:r.context.tenantId,workspaceId:r.workspaceId}),r.context.token,[r.context.token]);if(!o||typeof o!="object"||typeof o.summary!="string"||!Array.isArray(o.actions)||!o.pricing||typeof o.pricing!="object")throw new x("composer.plan returned an invalid result");if(e["--json"]){re({command:"composer.plan",diagnostics:r.compiled.result.diagnostics,file:n,plan:o,workspaceId:r.workspaceId});return}bn(n,r.compiled.result),E(o.summary);for(let a of o.actions)E(`${a.kind} ${a.target} ${a.detail}`);E(`Monthly: SAR ${o.pricing.monthlySar}`),E(`Activation: SAR ${o.pricing.activationSar}`)}function Fr(e){if(!Array.isArray(e.nouns))throw new x("The HSX compiler returned no noun list");let t=e.nouns.map(n=>n&&typeof n=="object"?n.id:void 0);if(t.length===0||t.some(n=>typeof n!="string"||n.length===0)||new Set(t).size!==t.length)throw new x("The HSX compiler returned invalid noun identities");return t}async function Rr(e,t,n){if(!e["--confirm"]&&!e["--yes"])throw new x("compose apply changes the selected Product. Pass --confirm, or --yes for an agent.");let r=await $n(e,t,n,!0),o=r.compiled.result.artifacts.document,a=await ce(r.context,"/v1/workspaces/recompose",be({nounIds:Fr(o),program:{frame:r.compiled.result.artifacts.frame,source:JSON.stringify(o)},tenantId:r.context.tenantId,workspaceId:r.workspaceId},e["--idempotency-key"]),r.context.token,[r.context.token]);if(!a||typeof a.workspaceBuildId!="string")throw new x("workspace.recompose returned no new build identity");if(e["--json"]){re({command:"workspace.recompose",diagnostics:r.compiled.result.diagnostics,file:n,output:a});return}bn(n,r.compiled.result),E(`Product: ${a.workspaceId??r.workspaceId}`),E(`Build: ${a.workspaceBuildId}`),a.buildDigest&&E(`Digest: ${a.buildDigest}`)}function Fe(e,t){let n=t["--product"]??e.selectedProduct;if(!n)throw new x("No Product selected. Pass --product <id> or create a Product first.");return n}async function Qn(e,t){let n=await Pe(t),r=Fe(n??{},e),o=Ue(e,t,n??{});if(n&&(o.baseUrl!==n.baseUrl||o.environment!==n.environment))throw new x(`The selected Product belongs to ${n.baseUrl} (${n.environment}). Select a Product at the configured API origin first.`);let a=e["--api-key"]??t.HYPERSCALE_API_KEY;if(!a)throw new x("No API key. Set HYPERSCALE_API_KEY, or pass --api-key. Request access at https://hyperscale0.ai/request-access.");return{...o,apiKey:a,workspaceId:r}}async function Dr(e,t,n){let r=await Qn(e,t),o=`/v1/workspaces/${encodeURIComponent(r.workspaceId)}/operation-set`,{response:a,text:l}=await ze(r,o);if(!a.ok)throw nt(a,l,[r.apiKey]);let s=Lr(l,a.status);if(n){Nr(s,n,e);return}if(e["--json"]){re(s);return}if(s.status==="legacy"){E("This Product uses a legacy surface. It has no frozen public verbs yet."),E(`Build: ${s.workspaceBuildId}`);return}if(s.publicVerbs.length===0)E("No public verbs");else{E("Operation ID Input Kind");for(let u of s.publicVerbs){let w=u.idempotencyPolicy?.mode==="not_required"?"read-only":"mutation";E(`${u.noun}.${u.name} ${Or(u.inputSchema)} ${w}`)}}E(`Digest: ${s.tenantOperationSetDigest}`),E(`Build: ${s.workspaceBuildId}`),E(`Surface version: ${s.tenantSurfaceVersion}`)}function Nr(e,t,n){if(e.status==="legacy")throw new x(`This Product uses a legacy surface and has no frozen public verb named ${t}. Run "hyperscale product verbs" after rebuilding the Product.`);let r=e.publicVerbs.find(a=>a&&`${a.noun}.${a.name}`===t);if(!r)throw new x(`Unknown frozen public verb: ${t}. Run "hyperscale product verbs" to list exact names.`);let o={status:e.status,workspaceBuildId:e.workspaceBuildId,tenantSurfaceVersion:e.tenantSurfaceVersion,tenantOperationSetDigest:e.tenantOperationSetDigest,publicVerb:r};if(n["--json"]){re(o);return}E(`Operation ID: ${r.noun}.${r.name}`),E(`Noun: ${r.noun}`),E(`Input schema: ${JSON.stringify(r.inputSchema,null,2)}`),E(`Output schema: ${JSON.stringify(r.outputSchema,null,2)}`),E(`Actor policy: ${JSON.stringify(r.actorPolicy,null,2)}`),E(`Port policy: ${JSON.stringify(r.portPolicy,null,2)}`),E(`Idempotency policy: ${JSON.stringify(r.idempotencyPolicy,null,2)}`),E(`Receipt policy: ${JSON.stringify(r.receiptPolicy,null,2)}`),E(`Receipt evidence: ${JSON.stringify(r.receiptEvidence,null,2)}`),E(`Digest: ${e.tenantOperationSetDigest}`),E(`Build: ${e.workspaceBuildId}`),E(`Surface version: ${e.tenantSurfaceVersion}`)}function Lr(e,t){let n;try{n=JSON.parse(e)}catch{throw new x(`HTTP ${t} returned invalid JSON`)}if(!n||typeof n!="object"||n.status!=="legacy"&&n.status!=="frozen"||typeof n.workspaceBuildId!="string")throw new x("The Product operation set is not in the expected format. Upgrade the CLI.");if(n.status==="legacy")return n;if(typeof n.tenantSurfaceVersion!="number"||typeof n.tenantOperationSetDigest!="string"||!Array.isArray(n.publicVerbs))throw new x("The Product operation set is not in the expected format. Upgrade the CLI.");return n}function Or(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(o=>typeof o=="string"):[]),r=Object.entries(t).map(([o,a])=>`${o}${n.has(o)?"":"?"}: ${et(a)}`);return r.length===0?"no input":r.join(", ")}function et(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"?`${et(e.items)}[]`:typeof e.type=="string"?typeof e.format=="string"?`${e.type} (${e.format})`:e.type:"value"}async function Br(e,t,n){if(!n)throw new x("product run needs a public verb");let r=await Qn(e,t),o=await tt(e),{response:a,text:l}=await ze(r,`/v1/operations/${encodeURIComponent(n)}`,{body:JSON.stringify(o),headers:{"content-type":"application/json","idempotency-key":e["--idempotency-key"]??globalThis.crypto.randomUUID()},method:"POST"});if(!a.ok)throw nt(a,l,[r.apiKey]);let s=a.headers.get("hyperscale-operation-id"),u=a.headers.get("hyperscale-receipt-id");if(e["--json"]){re({operationId:s,receiptId:u,output:jr(l)});return}E(`Operation: ${s??"not returned"}`),E(`Receipt: ${u??"not returned"}`);let w=rt(l);w&&E(w)}function jr(e){if(e.trim()==="")return null;try{return JSON.parse(e)}catch{return e}}function nt(e,t,n=[]){let r=ke(t.trim(),n),o;try{o=JSON.parse(t)}catch{return new x(`HTTP ${e.status}${r?` \xB7 ${r}`:""}`)}if(!o?.error||typeof o.error.message!="string")return new x(`HTTP ${e.status}`);let a=typeof o.error.code=="string"?`${o.error.code}: `:"",l=ke(`HTTP ${e.status} \xB7 ${a}${o.error.message}`,n),s=Jr(o.error.details,n);return new x([l,...s].join(`
98
- `))}function Jr(e,t){if(!e||typeof e!="object")return[];if(Array.isArray(e.issues))return e.issues.flatMap(r=>{if(!r||typeof r!="object")return[];let a=(Array.isArray(r.path)?r.path.join("."):"input")||"input";return typeof r.message=="string"?[`${a}: ${ke(r.message,t)}`]:[]});let n=[];return ln(e,"",n,t),n}function ln(e,t,n,r){if(Array.isArray(e)){if(e.every(o=>o===null||typeof o!="object")){n.push(`${qn(t)}: ${ke(e.join(", "),r)}`);return}e.forEach((o,a)=>ln(o,`${t}[${a}]`,n,r));return}if(e&&typeof e=="object"){for(let[o,a]of Object.entries(e))ln(a,t?`${t}.${o}`:o,n,r);return}t&&n.push(`${qn(t)}: ${ke(String(e),r)}`)}function qn(e){let t=e.replace(/([a-z0-9])([A-Z])/g,"$1 $2").replaceAll("."," ");return t.charAt(0).toUpperCase()+t.slice(1)}async function qr(e,t){let n=await ue(e,t),r=Fe(n,e),o=await ce(n,"/v1/sandbox-api-keys",be({name:e["--name"]??"Founder CLI",tenantId:n.tenantId,workspaceId:r}),n.token,[n.token]);if(e["--json"]){re(o);return}E(`Key: ${o.apiKeyId??"unknown"}`),E(`Product: ${o.workspaceId??r}`),E(`Status: ${o.status??"unknown"}`),o.secret?(E(`Secret: ${o.secret}`),E("Store it now. Hyperscale will not return it again.")):E("The key already existed, so the one-time secret is unavailable.")}async function Mr(e,t){let n=await ue(e,t),r=Fe(n,e),o=await Ye(n,"/v1/api-keys",{tenantId:n.tenantId},"api_key.list",n.token,[n.token]),a=Te(o,"api_key.list").filter(s=>s.workspaceId===r),l={...o,items:a};if(e["--json"]){re(l);return}for(let s of a)E(`${s.apiKeyId} ${s.name??"unnamed"} ${s.status??"unknown"}`)}async function Ur(e,t,n){if(!n)throw new x("key revoke needs an API key id");let r=await ue(e,t),o=Fe(r,e),a=await ce(r,`/v1/api-keys/${encodeURIComponent(n)}/revoke`,be({tenantId:r.tenantId,workspaceId:o}),r.token,[r.token]);e["--json"]?re(a):E(`Key ${a.apiKeyId??n}: ${a.status??"revoked"}`)}async function Kr(e,t){let n=await ue(e,t),r=await He(n,n.token),o=gn(n,r);if(e["--json"]){re(o);return}E(`User: ${r.email}`),E(`Tenant: ${r.tenantId}`),E(`Role: ${r.role}`),E(`Token: ${r.name}`),E(`Expires: ${r.expiresAt}`)}async function zr(e,t,n){let r=await Gn(e),o=n?n.toLowerCase():null,a=o?r.operations.filter(s=>s.name.toLowerCase().includes(o)||s.path.toLowerCase().includes(o)):r.operations;if(t["--json"]){E(JSON.stringify(a,null,2));return}if(a.length===0){E(n?`No operation matches ${n}`:"No operations");return}let l=Math.max(...a.map(s=>s.name.length));for(let s of a)E(`${s.name.padEnd(l)} ${s.method.padEnd(6)}${s.path}`)}async function Hr(e,t){let n=await ue(e,t),r=await ce(n,`/v1/team/members?${Xn(n.tenantId)}`,{},n.token,[n.token]);if(!r||typeof r!="object"||!Array.isArray(r.members)||!Array.isArray(r.invitations))throw new x("team.member.list returned invalid data");if(e["--json"]){re(r);return}for(let o of r.members)E(`${o.email??"unknown"} ${o.role??"unknown"} ${o.status??"unknown"}`);for(let o of r.invitations)E(`${o.email??"unknown"} ${o.role??"unknown"} pending invitation`)}async function Yr(e,t){let n=e["--email"],r=e["--role"];if(!n)throw new x("team invite needs --email <email>");if(!r)throw new x("team invite needs --role <role>");let o=await ue(e,t),a=await ce(o,"/v1/team/members/invite",be({email:n,role:r,tenantId:o.tenantId}),o.token,[o.token]);if(e["--json"]){re(a);return}E(`Invitation: ${a.invitationId??"unknown"}`),E(`Email: ${a.email??n}`),E(`Role: ${a.role??r}`),E(`Expires: ${a.expiresAt??"unknown"}`),a.inviteToken&&(E(`Invite token: ${a.inviteToken}`),E("Share it now. Hyperscale will not return it again."))}async function Vr(e,t){let n=await ue(e,t),r=await Ye(n,"/v1/activity",{tenantId:n.tenantId},"activity.list",n.token,[n.token]),o=Te(r,"activity.list");if(e["--json"]){re(r);return}for(let a of o){let l=a.operation??a.auditEvent??"activity",s=a.operationId??a.auditEventId??"unknown";E(`${s} ${l} ${a.status??a.occurredAt??"unknown"}`)}}function Wr(e,t){let n={...t},r=[],o=e.path.replace(/\{([^}]+)\}/g,(a,l)=>{let s=n[l];return s==null?(r.push(l),""):(delete n[l],encodeURIComponent(String(s)))});if(r.length>0)throw new x(`${e.name} needs ${r.join(", ")} in --input`);return{path:o,remaining:n}}function Gr(e){let t=new URLSearchParams;for(let[r,o]of Object.entries(e))o!=null&&t.set(r,typeof o=="string"?o:JSON.stringify(o));let n=t.toString();return n?`?${n}`:""}function Mn(e,t){let n=Array.from({length:t.length+1},(r,o)=>o);for(let r=1;r<=e.length;r+=1){let o=[r];for(let a=1;a<=t.length;a+=1)o[a]=Math.min(o[a-1]+1,n[a]+1,n[a-1]+(e[r-1]===t[a-1]?0:1));n.splice(0,n.length,...o)}return n[t.length]}function Xr(e,t){let n=e.find(a=>a.name===t);if(n)return n;let r=e.filter(a=>a.operationId===t);if(r.length===1)return r[0];if(r.length>1)throw new x(`${t} matches more than one operation. Use one of: ${r.map(a=>a.name).join(", ")}.`);let o=e.map(a=>({candidate:a,distance:Math.min(Mn(t,a.name),Mn(t,a.operationId))})).sort((a,l)=>a.distance-l.distance||a.candidate.name.localeCompare(l.candidate.name)).slice(0,3).flatMap(({candidate:a})=>[a.name,a.operationId]);throw new x(`${t} is not an operation in the selected Product's machine document. Closest valid names: ${o.join(", ")}.`)}async function Zr(e,t,n){if(!n)throw new x("call needs an operation name");let r=await Gn(e),o=Xr(r.operations,n),a=await tt(t),{path:l,remaining:s}=Wr(o,a),u={method:o.method},w=l;o.method==="GET"?w+=Gr(s):(u.body=JSON.stringify(s),u.headers={"content-type":"application/json",...o.idempotency==="not_required"?{}:{"idempotency-key":t["--idempotency-key"]??globalThis.crypto.randomUUID()}});let{response:v,text:P}=await ze(e,w,u);if(!v.ok)throw hn(v,P,[e.apiKey]);E(rt(P))}async function tt(e){if(e["--input"]!==void 0&&e["--input-file"]!==void 0)throw new x("Use only one of --input and --input-file");if(e["--input"]!==void 0)return sn(e["--input"],"--input");if(e["--input-file"]!==void 0){let t;try{t=await qe(e["--input-file"],"utf8")}catch(n){throw new x(`Could not read ${e["--input-file"]}: ${n.message}`)}return sn(t,"--input-file")}if(!process.stdin.isTTY){let t=await hr();if(t.trim()!=="")return sn(t,"stdin")}return{}}function sn(e,t="--input"){if(e===void 0)return{};let n;try{n=JSON.parse(e)}catch(r){throw new x(`${t} is not valid JSON: ${r.message}`)}if(n===null||typeof n!="object"||Array.isArray(n))throw new x(`${t} must be a JSON object`);return n}function rt(e){if(e.trim()==="")return"";try{return JSON.stringify(JSON.parse(e),null,2)}catch{return e}}function E(e){process.stdout.write(`${e}
99
- `)}function re(e){E(JSON.stringify(e,null,2))}function Qr(e,t){if(!t.includes("--json")){process.stderr.write(`${e instanceof x?e.message:e.stack??String(e)}
100
- `);return}let n=e instanceof x,r=n&&typeof e.code=="string"?e.code:n?"user_error":"internal_error";process.stderr.write(`${JSON.stringify({error:{code:r,message:n?e.message:"The command failed unexpectedly.",...n&&e.details?{details:e.details}:{},fix:n?'Follow the message, or run "hyperscale --help" for command usage.':"Report the failure without including credentials."}})}
101
- `)}async function eo(){let{readFileSync:e}=await import("node:fs");return JSON.parse(e(new URL("./package.json",import.meta.url),"utf8")).version}async function no(e,t){let{flags:n,positional:r}=cr(e);if(n["--version"])return E(await eo()),0;if(n["--help"]||r.length===0){if(r.length===0&&!n["--help"]&&n["--json"])throw new x('No command. Run "hyperscale --help" to list commands.');return process.stdout.write(ir),r.length===0&&!n["--help"]?1:0}let[o,...a]=r;if(o==="auth"){if(a[0]==="login")await $r(n,t);else if(a[0]==="status")await br(n,t);else if(a[0]==="logout")await vr(n,t);else throw new x('Auth subcommands are "login", "status", and "logout"');return 0}if(o==="blueprint"){let s=Ue(n,t);if(a[0]==="list")await kr(s,n);else if(a[0]==="show")await _r(s,n,a[1]);else throw new x('Blueprint subcommands are "list" and "show"');return 0}if(o==="product"){if(a[0]==="create")await Ar(n,t);else if(a[0]==="list")await xr(n,t);else if(a[0]==="show")await Cr(n,t,a[1]);else if(a[0]==="verbs")await Dr(n,t,a[1]);else if(a[0]==="run")await Br(n,t,a[1]);else throw new x('Product subcommands are "create", "list", "show", "verbs", and "run"');return 0}if(o==="compose"){if(a[0]==="check")await Ir(n,t,a[1]);else if(a[0]==="plan")await Tr(n,t,a[1]);else if(a[0]==="apply")await Rr(n,t,a[1]);else throw new x('Compose subcommands are "check", "plan", and "apply"');return 0}if(o==="key"){if(a[0]==="create")await qr(n,t);else if(a[0]==="list")await Mr(n,t);else if(a[0]==="revoke")await Ur(n,t,a[1]);else throw new x('Key subcommands are "create", "list", and "revoke"');return 0}if(o==="whoami")return await Kr(n,t),0;if(o==="team"){if(a[0]==="list")await Hr(n,t);else if(a[0]==="invite")await Yr(n,t);else throw new x('Team subcommands are "list" and "invite"');return 0}if(o==="activity"){if(a[0]!=="list")throw new x('The only activity subcommand is "list"');return await Vr(n,t),0}let l=dr(n,t);if(o==="ops"){if(a[0]!=="list")throw new x('The only ops subcommand is "list"');return await zr(l,n,a[1]),0}if(o==="call")return await Zr(l,n,a[0]),0;throw new x(`Unknown command: ${o}`)}no(process.argv.slice(2),process.env).then(e=>{process.exitCode=e},e=>{Qr(e,process.argv.slice(2)),process.exitCode=e instanceof x&&Number.isInteger(e.exitCode)?e.exitCode:1});
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}
102
+ `),c&&process.stderr.write(`Receipt: ${c}
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(`
116
+ `).map(n=>`${t}${n}`).join(`
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}
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"?`
125
+ Fix: ${e.fix}`:"",p=r?`
126
+ Shown once Product API key: ${r}`:"";process.stderr.write(`${c}${d}${p}
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,7 +1,7 @@
1
1
  {
2
2
  "name": "@hyperscale0/cli",
3
- "version": "1.0.0-beta.2",
4
- "description": "The Hyperscale founder command line: compose Products, manage keys, and call Product operations.",
3
+ "version": "1.0.0-beta.21",
4
+ "description": "Hyperscale CLI: compose Products, manage keys, and call Product operations.",
5
5
  "license": "LicenseRef-Hyperscale-Proprietary",
6
6
  "author": "Hyperscale LLC",
7
7
  "contributors": [
@@ -19,5 +19,6 @@
19
19
  "homepage": "https://hyperscale0.ai",
20
20
  "publishConfig": {
21
21
  "access": "public"
22
- }
22
+ },
23
+ "gitHead": "15441e0688e4f3031c5560eba341be6d431e3d32"
23
24
  }