@hyperscale0/cli 1.0.0-alpha.5 → 1.0.0-beta.1

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 +31 -9
  2. package/hyperscale.js +58 -30
  3. package/package.json +1 -1
package/README.md CHANGED
@@ -9,27 +9,49 @@ frozen public verbs.
9
9
  Request access at https://hyperscale0.ai/request-access.
10
10
 
11
11
  ```bash
12
- bunx @hyperscale0/cli auth login --email founder@example.com
12
+ export HYPERSCALE_TOKEN=<your founder PAT>
13
+ bunx @hyperscale0/cli auth login
14
+ bunx @hyperscale0/cli whoami
13
15
  bunx @hyperscale0/cli blueprint list
14
16
  bunx @hyperscale0/cli product create --blueprint vehicle-escrow-marketplace --name "Vehicle Escrow"
15
17
  bunx @hyperscale0/cli key create --name "Founder laptop"
18
+ bunx @hyperscale0/cli compose check product.hsx
19
+ bunx @hyperscale0/cli compose plan product.hsx
20
+ 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
+ bunx @hyperscale0/cli activity list
24
+ bunx @hyperscale0/cli ops list payment
16
25
 
17
26
  export HYPERSCALE_API_KEY=<your Product API key>
18
27
  bunx @hyperscale0/cli product verbs
28
+ bunx @hyperscale0/cli product verbs escrow.release --json
19
29
  bunx @hyperscale0/cli product run escrow.release --input '{"saleId":"sale_sandbox_..."}'
20
- bunx @hyperscale0/cli whoami
21
- bunx @hyperscale0/cli ops list account
22
30
  bunx @hyperscale0/cli call account.list --input '{"limit":5}'
23
31
  ```
24
32
 
25
- `npx @hyperscale0/cli` runs the same command. Add `--json` to any of them for
26
- machine-readable output.
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.
36
+ `compose check` compiles textual HSX and runs the independent composer check.
37
+ `compose plan` diffs it against the selected Product. `compose apply`
38
+ recomposes that Product and requires `--confirm`, or `--yes` for an agent.
39
+ Compiler or composer refusal exits 2. Transport and server failure exit 1.
40
+ `npx @hyperscale0/cli` runs the same commands. Add
41
+ `--json` for machine-readable success and failure output.
42
+
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
47
+ `--environment` when their defaults do not name the Product's plane.
27
48
 
28
49
  Point it at another host with `--base-url`, and at the live plane with
29
50
  `--environment live`. Live keys and sandbox keys are never interchangeable.
30
- Password, MFA code, and user-session bearer never use arguments or environment
31
- variables. The CLI stores the session in macOS Keychain, with a 0600 file
32
- fallback on systems where Keychain is unavailable. Passkey login stays in the
33
- portal at https://hyperscale0.ai/signin.
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
55
+ https://hyperscale0.ai/signin.
34
56
 
35
57
  Run `bunx @hyperscale0/cli --help` for the full option list.
package/hyperscale.js CHANGED
@@ -1,72 +1,100 @@
1
1
  #!/usr/bin/env node
2
- import{spawn as he}from"node:child_process";import{createHash as me}from"node:crypto";import{chmod as j,mkdir as ye,readdir as ge,readFile as _,rename as be,unlink as $e,writeFile as ke}from"node:fs/promises";import{homedir as Se}from"node:os";import{basename as Pe,dirname as J,join as v}from"node:path";const E="https://hyperscale0.ai",B="sandbox",F="hyperscale-cli-session",Z=process.platform==="darwin"?"/usr/bin/security":null,Ie="config.json",X=3e4,Ae=`hyperscale <command> [options]
2
+ var xe=["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 We=["business","person"],Ge=["access","claim","good","service","ticket"];var kn=["count","every","first_due"],Xe=/^[a-z][a-z0-9]*(?:_[a-z0-9]+)*$/,be=/^[a-z][A-Za-z0-9]*$/,_n=/^[A-Z]{3}$/,Ce=1e4;function An(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&&!Xe.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(!xe.includes(m.name)){n(m.span,`"settlement" has no archetype named ${m.name}; it offers ${xe.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,_=(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):Xe.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(!_(i.name,"party"))continue;if(!We.includes(i.partyKind.name)){n(i.partyKind.span,`a party is a ${We.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(!_(i.name,"asset"))continue;if(!Ge.includes(i.assetKind.name)){n(i.assetKind.span,`an asset is one of ${Ge.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 w=e.decls.filter(i=>i.kind==="port"),g=e.decls.filter(i=>i.kind==="settlement");for(let i of g)_(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,J=[],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$/],q=(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(!be.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(!_n.test(y))n(c.type.args[0].span,`"${y}" is not a currency code; use three capital letters like SAR`);else if(!q(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(!be.test(d.deadline.name)){n(d.deadline.span,`at( ... ) names a camelCase date field, like at(releaseDueAt); "${d.deadline.name}" is not`);return}if(q(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>=Ce){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>=Ce){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!==Ce&&(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"&&be.test(i.value.name))return q(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`)}},Ae=(i,m)=>{if(i){if(I(i,m),i.value.kind==="ident"&&be.test(i.value.name))return q(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,$n=(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}`)},bn=(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},He=(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}},Ye=(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(!xe.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}},tt=(i,m,c)=>{let y=i.get("against"),d=kn.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 kn)i.has(j)||n(c,`${m} is missing ${j}`);let L=He(i,m,c);return L?{kind:"schedule",schedule:L}:void 0}let k=Ye(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,xe.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>=Ce)&&n($.span,"derived amount percentage must be above 0% and below 100%"),S&&!be.test(S)&&n(f.span,`derived amount field ${S} must be camelCase`),O&&!be.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<Ce&&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&&J.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`),$=Ae(d.get("source_capture_refs"),c),F=Ae(d.get("fee_entries"),c),S=Ae(d.get("external_reversal_offsets"),c),O=fe(d.get("close_trigger"),c),z=R(d.get("payout_acknowledgement"),c,"payout acknowledgement"),K=Ae(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&&J.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=$n(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&&J.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=$n(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&&J.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?Ye(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&&J.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?Ye(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&&$&&J.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&&J.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=bn(d.get("members"),c,"members",2,5),f=bn(d.get("payout_order"),c,"payout_order",2,5),b=A(d.get("contribution"),c),$=He(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&&J.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);J.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&&J.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&&J.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?Ae(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};J.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&&J.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=He(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(Re=>d.has(Re));if(!z&&X){n(i.span,`${c} uses obligation policies without mode: obligation`);break}if(!z){p&&f&&$&&O&&b&&J.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 Re of ae)d.has(Re)||n(i.span,`${c} is missing ${Re}`);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),Fe=[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&&Fe&&J.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=tt(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&&J.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(!Xe.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&&J.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(Fe=>Fe.charAt(0).toUpperCase()+Fe.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&&J.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 Ve=[];for(let i of w){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(!be.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=at(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"&&!_n.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&&Ve.push({allowed:y,fields:k,name:i.name.name,origin:i.span})}let ye=new Map(Ve.map(i=>[i.name,i]));for(let i of J){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 rt=new Map(J.filter(i=>i.archetype==="scheduled"&&i.mode==="obligation").map(i=>[i.name,i])),vn=new Map;for(let i of J){if(i.archetype!=="credit_facility"&&i.archetype!=="recurring_collection")continue;let m=rt.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=vn.get(m.name);d?n(i.obligation.origin,`${c} and settlement ${d} both collect ${m.name}; one obligation may have one collection policy owner`):vn.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 ot=new Map(J.filter(i=>i.archetype==="held_payment").map(i=>[i.name,i])),wn=new Map;for(let i of J){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=ot.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=wn.get(c);if(k){n(y,`${m} and settlement ${k} both draw against ${c}; one release repays one advance`);continue}if(wn.set(c,i.name),J.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 w)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:Ve,settlements:J,title:l.title?.value??it(l.name.name)}}}function at(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 it(e){let t=e.replaceAll("_"," ");return t.charAt(0).toUpperCase()+t.slice(1)}function xn(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 Cn(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 En=20,Sn=48,Ze=10000n;function st(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:Pn(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:Pn(e.source,e.consumed),amountMode:"remaining_balance"}}}}function Pn(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 In=160,ct=new Set(["amount","design","detail","headline","label","summary","title","trigger","why"]);function Qe(e,t){return typeof e=="string"?t!==void 0&&ct.has(t)&&e.length>In?`${e.slice(0,In-3)}...`:e:Array.isArray(e)?e.map(n=>Qe(n,t)):e!==null&&typeof e=="object"?Object.fromEntries(Object.entries(e).map(([n,r])=>[n,Qe(r,n)])):e}function dt(e){return Qe(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 lt(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:lt(e),...st(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 he(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 De(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 ge(e,t){return t.length>=2?[{pieces:[...t],total:e}]:[]}function ve(e){return e.length>0?{partitions:[...e]}:{}}function H(e){return{desc:e,type:"money"}}function se(e){return{desc:e,type:"date"}}function ut(e){return{desc:e,type:"date?"}}function pt(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 mt(e,t){let n=new Set(e.filter(a=>!t.has(a.id)).map(pt)),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 Tn(e){let t=[],n=[],r=[],o=[],a=[],l=[],s=[],u=[],_=new Set,v=new Map,P=new Map(e.ports.map(h=>[h.name,h])),w=(h,T,q)=>{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:q}),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(q=>q.archetype==="scheduled"&&q.mode==="transfer"&&q.payer===h.advanced&&q.payee===h.funder&&q.amount.name===h.amount.name&&q.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=w(h,h.release.port,h.release.origin);if(!N)continue;T=kt(h,N,g.get(h.name),t);break}case"captured_payment":{let N=w(h,h.correction.port,h.correction.origin),M=w(h,h.externalReversal.port,h.externalReversal.origin);if(!N||!M)continue;T=xt(h,N,M,t);break}case"settlement_batch":{let N=w(h,h.payoutAcknowledgement.port,h.payoutAcknowledgement.origin);if(!N)continue;T=Ct(h,N,t);break}case"funding_round":T=St(h);break;case"weighted_distribution":{let N=w(h,h.snapshot.port,h.snapshot.origin);if(!N)continue;T=Pt(h,N);break}case"credit_facility":T=It(h);break;case"recurring_collection":continue;case"conditional_disbursement":{let N=w(h,h.decision.port,h.decision.origin);if(!N)continue;T=Tt(h,N);break}case"rotating_pool":T=Ft(h);break;case"premium_forward":{let N=w(h,h.bind.port,h.bind.origin),M=h.endorsement?w(h,h.endorsement.port,h.endorsement.origin):void 0;if(!N||h.endorsement&&!M)continue;T=_t(h,N,M,t);break}case"deposit":{let N=w(h,h.claim.port,h.claim.origin),M=w(h,h.return.port,h.return.origin);if(!N||!M)continue;T=Et(h,N,M,t);break}case"instant_transfer":T=At(h);break;case"scheduled":T=h.mode==="obligation"?Rt(h,D.get(h.name),D.has(h.name)?w(D.get(h.name),D.get(h.name).mandate.port,D.get(h.name).mandate.origin):void 0):Dt(h);break;case"advance":T=Nt(h,C.get(h.name)??[]);break;case"metered":T=Bt(h);break;case"pooled_split":T=jt(h);break;case"swap":{let N=w(h,h.release.port,h.release.origin),M=h.dispute?w(h,h.dispute.port,h.dispute.origin):void 0;if(!N||h.dispute&&!M)continue;T=wt(h,N,M);break}}if(!T)continue;let q=(e.derivedAmounts??[]).filter(N=>N.settlement===h.name);if(q.length>0&&(T=yt(T,h,q,t),!T))continue;let A=le[h.archetype].eventCap+q.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=Fn(N.id,oe);pe.length<=Sn||t.push({message:`settlement ${h.name} generates public intent "${pe}" with ${pe.length} characters; rename the settlement so each public intent fits the ${Sn}-character camelName limit`,span:h.origin})}}r.push(...R);for(let N of T.generatedPrefixNounIds??[])_.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>En&&t.push({message:`this program needs ${o.length} money events but a Business Frame carries at most ${En}; simplify the fee or cancellation terms, or drop a settlement`,span:e.settlements[0]?.origin??{end:0,start:0}}),t.push(...gt(o,e.settlements[0]?.origin??{end:0,start:0}));let I=ht(e,u);if(t.push(...I.issues),t.length>0)return{issues:t,ok:!1};let Z=ft(mt(r,_)),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},J={actors:I.actors,confidence:"high",conservationGroups:[],design:l,feePolicy:s.length>0?"defined":"none",fees:s,headline:e.title,mechanics:vt(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:qt(e)};return{ok:!0,value:{document:te,frame:dt(J),settlements:n}}}function ft(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:Fn(t.id,r)}]))}})}function Fn(e,t){let n=Q(e),r=n.charAt(0).toUpperCase()+n.slice(1);return`${Q(t)}${r}`}function yt(e,t,n,r){let o=e.noun,a={...o.fields??{}},l={...o.verbs??{}},s={...l.create??{}},u=[...s.moves??[]],_={...o.actors??{}},v=[],P=[...e.moneyEvents],w=[...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`),_[g.bearer]===void 0&&(_[g.bearer]="payer"),_.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`})),w.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:w,moneyEvents:P,noun:{...o,actors:_,derivedAmounts:v,fields:a,verbs:l}}}function ht(e,t=[]){let n=$t(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 gt(e,t){let n=[],r=new Map;for(let u of e){if(typeof u.key!="string")continue;let _=Array.isArray(u.amountDependencies)?u.amountDependencies.filter(v=>typeof v=="string"):[];r.set(u.key,_)}for(let[u,_]of r)for(let v of _){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 _ of r.get(u)??[])r.has(_)&&s(_),l.has(_)&&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 $t(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 _ of s)a.has(_)||a.set(_,u)};return l(t,"payer"),l(r,"provider"),l(o,"holder"),l(n,"beneficiary"),a}var bt={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 vt(e){let t=new Set(e.map(n=>n.archetype==="scheduled"&&n.mode==="obligation"?"credit":bt[n.archetype]));return t.size>0?[...t]:["escrow"]}function wt(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`),_=[],v=(R,N,M,oe,de,pe)=>{let me=U(`${r}_${R}`);return _.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`),w=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`}}:{}},J=[{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:w,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`);J.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}],q={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:J,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&&(q.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"},q.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:_,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:q},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 kt(e,t,n,r){let o=e.fees.find(s=>s.bearer===e.payer),a=e.fees.find(s=>s.bearer===e.payee),l=Rn({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 _t(e,t,n,r){let o=Rn({amount:e.amount,carveTo:void 0,deadlineField:void 0,fundEventKind:"premium",fundTrigger:(_,v)=>v===1?"Collect the premium into escrow":`Collect premium piece ${_+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 _=U(`${e.name}_renewal_due`);s.lapse={due:{field:e.renewalDueField,rule:_},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:_,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 Rn(e,t){let n=e.amount.name,r=Dn(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(Nn(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 _=o.map((A,R)=>`fund_piece_${R+1}`);e.payerFeeBps!==void 0&&_.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}`):[],w=e.deadlineField?`${e.releaseWord}_on_deadline`:void 0,g=U(`${a}_${e.releaseWord}_deadline`),C=_.length-1,D=Array.from({length:C},(A,R)=>`unfund_piece_${R+1}`);if(!De(e.name,[..._,...v,...w?[w]:[],...P,"abandon",...D],e.port.origin,t))return;let I=he(_,"created","funded","funding"),Z=he(v,"funded","released","releasing"),ee=he(P,"funded","cancelled","cancelling"),te=[],J={},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())J[_[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=_.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"})),J.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())J[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(w&&e.deadlineField){let A=o[0];J[w]={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())J[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;J[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}`}}}J.abandon={from:["created"],requiresDrainedAccount:{path:"refs.escrowAccountId"},summary:"Abandon the settlement before any money is held",to:"abandoned"},J.create={summary:`Create a ${B(e.name).toLowerCase()} settlement`,to:"created"};let q=[{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&&q.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,...ve(ge(n,o.map(A=>A.field))),summary:`Escrow-held amount from ${e.payer.replaceAll("_"," ")}`,title:B(e.name),verbs:J},rules:q,settlement:{name:e.name,pieces:o,...e.payerFeeBps!==void 0?{serviceFee:{bps:e.payerFeeBps,field:"serviceFeeAmount"}}:{}}}}function At(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=Dn({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(Nn(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 _=he(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:[_[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:_[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:[_[g]?.from],moneyEvent:C,moves:[{key:"transfer",operation:"create",amount:"serviceFeeAmount",from:e.payer,to:"platform"}],summary:"Collect the payer-side service fee",to:_[g]?.to}}let w=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",...w?{platform:"party"}:{}},desc:`Instant transfer: the ${e.payer.replaceAll("_"," ")} pays ${r} straight through to the ${e.payee.replaceAll("_"," ")}, no custody`,fields:s,id:l,...ve(ge(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 xt(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(!De(o,v,e.origin,r))return;let P=U(`${o}_reserve`),w=U(`${o}_capture`),g=U(`${o}_correction`),C=U(`${o}_external_reversal`),D=U(`${o}_reservation_expiry`),I=J=>({amount:"captureAmount",capture:{[s]:"postedAmount"},key:"post",operation:"post",...J?{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:w,moves:[I(!0)],summary:"Post one strict partial capture slice",to:"partially_captured"},capture_more:{deadline:{field:e.reserveUntilField},from:["partially_captured"],moneyEvent:w,moves:[I(!0)],summary:"Post another strict partial capture slice",to:"partially_captured"},settle:{deadline:{field:e.reserveUntilField},from:["authorized","partially_captured"],moneyEvent:w,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:w,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:w},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:w},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 Ct(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`),_=U(`${r}_close`);if(!De(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"}}},w=(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:_},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,w(a,"credit"),w(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:_,kind:"deadline",label:`Batch freezes on ${e.closeTriggerField}`,tenantTunable:!1}],settlement:{name:r,pieces:[]}}}function Et(e,t,n,r){let o=e.name,a=e.amount.name;if(!De(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"}]}},_=(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:[_(t,"Claim"),_(n,"Return")],settlement:{name:o,pieces:[]}}}function en(e){let t=Math.floor(Number(Ze)/e),n=Array.from({length:e},()=>t);return n[0]=Number(Ze)-t*(e-1),n}function St(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:w,targetField:e.target.name},nounId:n,over:"children",refField:r,statuses:["committed"]}],v=w=>({[r]:{bind:{currency:"fields.currency",[`${Q(e.beneficiary)}AccountId`]:`fields.${Q(e.beneficiary)}AccountId`},statuses:w}}),P=w=>({[r]:{match:{"fields.currency":"fields.currency",[`fields.${Q(e.beneficiary)}AccountId`]:`fields.${Q(e.beneficiary)}AccountId`},statuses:w}});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:_("sum_at_least"),summary:"Activate when commitments meet the target",to:"active"},fail:{due:{field:e.closeByField,rule:u},from:["open"],requiresAggregate:_("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 Pt(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 It(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 Tt(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 Ft(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 w=`${Q(P)}AccountId`;return[w,`fields.${w}`]})),u=e.members.map(P=>`${t}_${P}_contribution`),_=e.members.map((P,w)=>{let g=u[w],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`,J=`cycle_${I}_guaranteed`,h=I===e.schedule.count?"final_paid":`cycle_${I+1}_due`,T=U(`${t}_cycle_${I}_due`),q=e.contribution.name,A=e.contribution.name,R={field:e.schedule.firstDueField,rule:T,...Ee(e.schedule,D)};C[`contribute_cycle_${I}`]={due:R,from:[Z],moneyEvent:r,moves:[{amount:q,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:J}),C[`pay_cycle_${I}`]={from:[te],moneyEvent:a,moves:[{amount:q,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:[J],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 w=P+1;v[`ready_cycle_${w}`]={from:[`active_cycle_${w}`],requiresAggregate:u.map(g=>({check:{kind:"all_in"},nounId:g,over:"children",refField:n,statuses:[`cycle_${w}_funded`,...e.guarantor?[`cycle_${w}_guaranteed`]:[]]})),summary:`Lock cycle ${w} only after every member row is funded or guaranteed`,to:`cycle_${w}_ready`},v[`advance_cycle_${w}`]={from:[`cycle_${w}_ready`],requiresAggregate:u.map(g=>({check:{kind:"all_in"},nounId:g,over:"children",refField:n,statuses:[w===e.schedule.count?"completed":`cycle_${w+1}_due`]})),summary:w===e.schedule.count?"Complete after the final shared pot pays":`Advance after every cycle ${w} contribution pays`,to:w===e.schedule.count?"completed":`active_cycle_${w+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:_,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,w)=>({allowedActors:[],detail:`Cycle ${w+1} default follows its stored due condition`,dueDriven:!0,enforcement:"platform",gatesEvent:null,key:U(`${t}_cycle_${w+1}_due`),kind:"deadline",label:`Cycle ${w+1} due condition`,tenantTunable:!1})),settlement:{name:t,pieces:[]}}}function Ee(e,t){return t===0?{}:{offset:`P${e.every.days*t}D`}}function Rt(e,t,n){let r=e.name,o=e.amount.name,a=`${r.replaceAll(/_([a-z])/g,(T,q)=>q.toUpperCase())}Id`,l=en(e.schedule.count),s=l.map((T,q)=>`installment${q+1}Amount`),u=l.map((T,q)=>`${r}_installment_${q+1}_payment`),_="active",v=T=>`installment_${T+1}_delinquent`,P=l.map((T,q)=>v(q)),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,q]of s.entries())I[q]=H(`Stored amount for installment ${T+1} of ${e.schedule.count}${T===0?" (carries the integer-division remainder)":""}`),I[`installment${T+1}DelinquentAfter`]=ut(`Machine-set marker proving installment ${T+1} reached its stored due date while unpaid`);let Z=u.map((T,q)=>({childField:"amount",childNounId:T,childRefField:a,childStatuses:["paid"],parentField:s[q]})),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":_},...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:_}}:{},write_off:{from:["draft",...e.advanceTo?["approved"]:[],...w],summary:"Write off the remaining exposure without moving money",to:"written_off"}},te=[];for(let[T,q]of u.entries()){let A=T+1,R=U(`${r}_installment_${A}_due`),N={field:e.schedule.firstDueField,rule:R,...Ee(e.schedule,T)},M=oe=>[{check:{amountField:"amount",kind:oe,targetField:s[T]},nounId:q,over:"children",refField:a,statuses:["paid"]}];ee[`mark_installment_${A}_delinquent`]={due:N,from:w.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:_},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 J=U(`${r}_completion_due`);ee.complete={due:{field:e.schedule.firstDueField,rule:J,...Ee(e.schedule,l.length-1)},from:w,requiresAggregate:u.map((T,q)=>({check:{amountField:"amount",kind:"sum_exactly",targetField:s[q]},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:J,kind:"deadline",label:"Obligation completion follows exact aggregate repayment",tenantTunable:!1});let h=T=>{let q=T+1,A=u[T],R=w,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 ${q} 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 ${q}`,title:`${B(r)} Installment ${q} Payment`,verbs:{create:{requires:oe,summary:`Create a payment record for installment ${q}`,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 ${q}`,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 ${q} 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,q)=>h(q)),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,...ve(ge(o,s)),summary:`${e.schedule.count}-anchor obligation for ${e.debtor.replaceAll("_"," ")}`,title:B(r),verbs:ee},rules:te,settlement:{name:r,pieces:[]}}}function Dt(e){let t=e.name,n=e.amount.name,{schedule:r}=e,o=`${t}_schedule`,a=en(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}`),_=he(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`})],w={create:{summary:`Create a ${B(t).toLowerCase()} plan`,to:"active"}};for(let[g,C]of s.entries())w[u[g]]={due:{field:r.firstDueField,rule:o,...Ee(r,g)},from:[_[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:_[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,...ve(ge(n,s)),summary:`${r.count}-installment schedule from ${e.payer.replaceAll("_"," ")} to ${e.payee.replaceAll("_"," ")}`,title:B(t),verbs:w},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 Nt(e,t){return e.source.kind==="carve"?Lt(e,e.source.settlement,t):Ot(e,e.source.schedule)}function Lt(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((w,g)=>({field:`carveRecourse${g+1}Id`,statuses:["active"],target:w.name}))],P={[o]:H(`The advanced amount in ${e.amount.currency} minor units, disbursed to the ${l} up front`),...Object.fromEntries(v.map(w=>[w.field,{desc:`The ${w.target.replaceAll("_"," ")} bound to this advance`,type:`ref:${w.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,...ve(a?ge("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(w=>[w.field,{match:{[`fields.${o}`]:`fields.${o}`,"fields.currency":"fields.currency"},statuses:w.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 Ot(e,t){let n=e.name,r=e.amount.name,o=`${n}_schedule`,a=en(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`)},_=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=he(v,"advanced","repaid","repaying"),w=[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`;w.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 _.entries()){let Z=C;g[v[D]]={due:{field:t.firstDueField,rule:o,...Ee(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:w,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,...ve([...ge(s,_),...l?ge("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 Bt(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 jt(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}`),_=he(s,"created","pooled","pooling"),v=he(u,"pooled","distributed","distributing"),P=[],w={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`})),w[s[g]]={from:[_[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:_[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`})),w[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,...ve(ge(n,a.map(g=>g.field))),summary:`Period pool from ${e.payer.replaceAll("_"," ")} split ${e.shares.length} ways`,title:B(t),verbs:w},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 Dn(e){let t=Number(Ze),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(w=>P<w.end),u=[],_=0;for(let v of l){if(v<=_)continue;let P=s(r,_),w=s(o,_);u.push({bps:v-_,...w?{cancelTo:w.to}:{},field:`piece${u.length+1}Amount`,origin:w?.origin??e.amount.origin,releaseTo:P?.to??n}),_=v}return u}function Nn(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 qt(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 Jt=["asset","from","import","party","port","program","settlement"],Ln=new Set(["{","}","(",")","[","]",":",",","=","|","."]),Mt=new Set(Jt),Ut=e=>/[A-Za-z]/.test(e),Kt=e=>/[A-Za-z0-9_]/.test(e),Ne=e=>e>="0"&&e<="9";function On(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(Ln.has(a)){let s=r;r+=1,o("punct",s,a);continue}if(a==='"'){let s=r;r+=1;let u="",_=!1;for(;r<e.length;){let v=e[r];if(v==='"'){r+=1,_=!0;break}if(v===`
5
+ `)break;u+=v,r+=1}_||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(Ne(a)){let s=r;for(;r<e.length&&Ne(e[r]);)r+=1;if(e[r]==="."&&Ne(e[r+1]??""))for(r+=1;r<e.length&&Ne(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(Ut(a)){let s=r;for(;r<e.length&&Kt(e[r]);)r+=1;let u=e.slice(s,r);o(Mt.has(u)?"keyword":"ident",s,u);continue}let l=r;for(;r<e.length&&!/[\sA-Za-z0-9_"]/.test(e[r])&&!Ln.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 Se=Object.freeze({maxNestingDepth:64,maxSourceBytes:262144});function Bn(e){let t=new TextEncoder().encode(e).byteLength;if(t>Se.maxSourceBytes)return{diagnostics:[{message:`this file is ${t} bytes; HSX reads at most ${Se.maxSourceBytes}`,span:{end:0,start:0}}],program:{decls:[],span:{end:0,start:0}}};let n=On(e),r=new nn(n.tokens,[...n.diagnostics]),o=r.parseProgram(e.length);return{diagnostics:r.diagnostics,program:o}}var nn=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>=Se.maxNestingDepth?(this.error(t,`this nests past the parser's depth budget of ${Se.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=zt(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 zt(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 tn(e){let t=[],n=xn(e),r=(s,u,_,v)=>{let P=Cn(n,v);t.push({column:P.column,line:P.line,message:_,severity:u,stage:s})},o=Bn(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=An(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=Tn(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 Ht}from"node:child_process";import{createHash as Yt}from"node:crypto";import{chmod as rn,mkdir as Vt,readdir as Wt,readFile as je,rename as Gt,unlink as Xt,writeFile as Zt}from"node:fs/promises";import{homedir as Qt}from"node:os";import{basename as er,dirname as an,join as qe}from"node:path";var Le="https://hyperscale0.ai",cn="sandbox",dn="hyperscale-cli-session",nr="/v1/personal-access-tokens/current",jn=process.platform==="darwin"?"/usr/bin/security":null,tr="config.json",Jn=3e4,rr=`hyperscale <command> [options]
3
6
 
4
7
  Commands:
5
- auth login Log in with email, password, and MFA when required
6
- auth status Show the active nonsecret profile
7
- auth logout Revoke and remove the active user session
8
+ auth login Save a founder personal access token (PAT)
9
+ auth status Verify and show the active founder PAT
10
+ auth logout [--revoke] Forget the local founder PAT, optionally revoke it
8
11
  blueprint list List public Blueprints without authentication
9
12
  blueprint show <id> Show one public Blueprint
10
13
  product create Create a Product from a Blueprint
11
14
  product list List Products in the signed-in company
12
15
  product show [id] Show a Product (default: selected Product)
13
- product verbs Show the selected Product's frozen public verbs
14
- product run <verb> Run one frozen public verb
16
+ product verbs [operation-id]
17
+ List frozen public verbs or describe one exactly
18
+ product run <operation-id> Run one frozen public verb
19
+ compose check <file.hsx> Compile and check an HSX program
20
+ compose plan <file.hsx> Diff an HSX program against the selected Product
21
+ compose apply <file.hsx> Recompose the selected Product from checked HSX
15
22
  key create Create a sandbox Product API key
16
23
  key list List keys for the selected Product
17
24
  key revoke <id> Revoke a Product API key
18
- whoami Show the product this API key resolves to
25
+ team list List company members and pending invitations
26
+ team invite Invite a company member
27
+ activity list List company activity
28
+ whoami Show the user and company this founder PAT resolves to
19
29
  ops list [filter] List the product's callable operations
20
30
  call <operation> Call one operation by name or operation id
21
31
 
22
32
  Options:
33
+ --token <pat> Founder PAT (default: $HYPERSCALE_TOKEN)
34
+ --revoke Revoke the active founder PAT during auth logout
23
35
  --api-key <key> Product API key (default: $HYPERSCALE_API_KEY)
24
- --base-url <url> API origin (default: $HYPERSCALE_BASE_URL, else ${E})
25
- --environment <name> sandbox or live (default: $HYPERSCALE_ENVIRONMENT, else ${B})
26
- --email <email> Login email (password and MFA stay on hidden stdin)
36
+ --base-url <url> API origin (default: $HYPERSCALE_BASE_URL, else ${Le})
37
+ --environment <name> sandbox or live (default: $HYPERSCALE_ENVIRONMENT, else ${cn})
38
+ --email <email> Email for team invite
39
+ --role <role> Seeded role name or custom role id for team invite
27
40
  --blueprint <id> Blueprint for product create
28
41
  --name <name> Product or key name
29
- --product <id> Product override for key commands
42
+ --product <id> Product id for key commands and Product-key verbs
30
43
  --input <json> JSON input object for call or product run
31
44
  --input-file <path> Read call or product run input from a JSON file
32
45
  --idempotency-key <key> Idempotency key for a mutation or public verb (default: generated)
46
+ --confirm Confirm compose apply for a person
47
+ --yes Confirm compose apply without a prompt for an agent
33
48
  --passkey Print the portal pointer for passkey login
34
49
  --json Print machine-readable JSON
35
50
  --version Print the CLI version
36
51
  --help Print this help
37
52
 
38
- Password, MFA code, and user-session bearer never ride in arguments or
39
- environment variables. Passkey login runs in the portal at ${E}/signin.
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 ${Le}/signin.
40
56
 
41
- The Product key rides in the environment, never on the command line, unless
42
- you are pasting a one-off into a throwaway shell.
57
+ compose check, plan, and apply exit 2 when the compiler or composer refuses the
58
+ program. Command, credential, request, and server failures exit 1. compose apply
59
+ requires --confirm, or --yes for an agent.
60
+
61
+ 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.
43
63
 
44
64
  Request access at https://hyperscale0.ai/request-access.
45
65
 
46
66
  Examples:
47
67
  hyperscale whoami
48
- hyperscale auth login --email founder@example.com
68
+ hyperscale auth login --token hyperscale_pat_...
49
69
  hyperscale blueprint list
50
70
  hyperscale product create --blueprint vehicle-escrow-marketplace --name "Vehicle Escrow"
51
71
  hyperscale key create --name "Founder laptop"
52
72
  hyperscale product verbs
73
+ hyperscale product verbs escrow.release --json
53
74
  hyperscale product run escrow.release --input '{"saleId":"sale_sandbox_..."}'
75
+ hyperscale compose check product.hsx
76
+ hyperscale compose plan product.hsx --json
77
+ hyperscale compose apply product.hsx --yes
78
+ hyperscale team list
79
+ hyperscale team invite --email developer@example.com --role developer
80
+ hyperscale activity list
54
81
  hyperscale ops list account
55
82
  hyperscale call account.list --input '{"limit":5}'
56
83
  hyperscale call account.list --input-file input.json
57
84
  printf '{"limit":5}' | hyperscale call account.list
58
85
  hyperscale call account.retrieve --input '{"accountId":"acct_sandbox_..."}'
59
- `;class c extends Error{}const ve=new Set(["--api-key","--base-url","--blueprint","--email","--environment","--idempotency-key","--input","--input-file","--name","--product"]);function Ee(e){const n=[],t={};for(let r=0;r<e.length;r+=1){const o=e[r];if(!o.startsWith("--")){n.push(o);continue}if(ve.has(o)){const s=e[r+1];if(s===void 0)throw new c(`${o} needs a value`);t[o]=s,r+=1;continue}if(o==="--help"||o==="--version"||o==="--json"||o==="--passkey"){t[o]=!0;continue}throw new c(`Unknown option: ${o}`)}return{flags:t,positional:n}}function Te(e,n){const t=e["--api-key"]??n.HYPERSCALE_API_KEY;if(!t)throw new c("No API key. Set HYPERSCALE_API_KEY, or pass --api-key. Request access at https://hyperscale0.ai/request-access.");const r=e["--environment"]??n.HYPERSCALE_ENVIRONMENT??B;if(r!=="sandbox"&&r!=="live")throw new c(`Unknown environment: ${r}. Use sandbox or live.`);const o=(e["--base-url"]??n.HYPERSCALE_BASE_URL??E).replace(/\/+$/,"");return{apiKey:t,baseUrl:o,environment:r}}function T(e,n,t={}){const r=e["--environment"]??n.HYPERSCALE_ENVIRONMENT??t.environment??B;if(r!=="sandbox"&&r!=="live")throw new c(`Unknown environment: ${r}. Use sandbox or live.`);const o=(e["--base-url"]??n.HYPERSCALE_BASE_URL??t.baseUrl??E).replace(/\/+$/,"");let s;try{s=new URL(o)}catch{s=null}const i=s?.origin??null;if(!i||i!==o)throw new c(`Invalid API origin: ${o}. Use an origin such as https://hyperscale0.ai.`);const a=["localhost","127.0.0.1","[::1]","::1"].includes(s.hostname);if(s.protocol!=="https:"&&!(s.protocol==="http:"&&a))throw new c(`Refusing cleartext API origin ${o}. Use HTTPS unless the API runs on loopback.`);return{baseUrl:o,environment:r}}function ee(e){return e.HYPERSCALE_CONFIG_DIR??v(Se(),".config","hyperscale")}function te(e){return v(ee(e),Ie)}function b(e,n){return v(ee(n),`session-${S(e)}.json`)}async function K(e,n){const t=b(e,n),r=`${Pe(t)}.`;let o;try{o=await ge(J(t),{withFileTypes:!0})}catch(s){if(s&&s.code==="ENOENT")return;throw s}for(const s of o){if(!s.isFile()||!s.name.startsWith(r))continue;const i=s.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(i)&&await U(v(J(t),s.name))}}async function Ue(e){try{return JSON.parse(await _(e,"utf8"))}catch(n){if(n&&n.code==="ENOENT")return null;throw n instanceof SyntaxError?new c(`${e} is not valid JSON`):n}}async function H(e,n){const t=Ne(e);await ye(t,{mode:448,recursive:!0}),await j(t,448);const r=`${e}.${process.pid}.${globalThis.crypto.randomUUID()}.tmp`;await ke(r,n,{flag:"wx",mode:384}),await j(r,384);try{await be(r,e),await j(e,384)}catch(o){throw await U(r),o}}function Ne(e){return J(e)}async function U(e){try{await $e(e)}catch(n){if(!n||n.code!=="ENOENT")throw n}}function Ce(e,n){if(!e||typeof e!="object"||Array.isArray(e))throw new c(`${n} does not contain a CLI profile`);const{baseUrl:t,email:r,environment:o,selectedProduct:s}=e;if(typeof t!="string"||typeof r!="string"||o!=="sandbox"&&o!=="live"||!(s===null||typeof s=="string"))throw new c(`${n} does not contain a valid CLI profile`);return{baseUrl:t,email:r,environment:o,selectedProduct:s}}async function A(e){const n=te(e),t=await Ue(n);return t===null?null:Ce(t,n)}async function ne(e,n){const t={email:n.email,baseUrl:n.baseUrl,environment:n.environment,selectedProduct:n.selectedProduct??null};await H(te(e),`${JSON.stringify(t,null,2)}
60
- `)}function S(e){return me("sha256").update(`${e.baseUrl}\0${e.environment}\0${e.email}`).digest("hex")}async function q(e,n){return Z===null?{error:null,status:null,stdout:"",unavailable:!0}:await new Promise(t=>{const r=he(Z,e,{stdio:["pipe","pipe","pipe"]}),o=[];r.stdout.on("data",s=>o.push(s)),r.stderr.on("data",()=>{}),r.once("error",s=>t({error:s,status:null,stdout:"",unavailable:s?.code==="ENOENT"})),r.once("close",s=>t({error:null,status:s,stdout:Buffer.concat(o).toString("utf8"),unavailable:!1})),n===void 0?r.stdin.end():r.stdin.end(`${n}
61
- `)})}function oe(e){try{const n=typeof e=="string"?JSON.parse(e):e;if(n&&typeof n=="object"&&!Array.isArray(n)&&typeof n.sessionToken=="string"&&typeof n.tenantId=="string")return{sessionToken:n.sessionToken,tenantId:n.tenantId}}catch{}return null}async function xe(e,n,t){await K(e,t);const r=S(e),o=JSON.stringify(n),s=["add-generic-password","-a",r,"-s",F,"-U","-X",Buffer.from(o,"utf8").toString("hex")].join(" ");return(await q(["-i"],s)).status===0?(await U(b(e,t)),"keychain"):(await H(b(e,t),`${JSON.stringify({account:r,credential:n})}
62
- `),"file")}async function Le(e,n){const t=S(e);try{const r=JSON.parse(await _(b(e,n),"utf8"));if(!r||typeof r!="object"||Array.isArray(r)||r.account!==t)return{state:"invalid"};const o=oe(r.credential);return o?{credential:o,state:"valid"}:{state:"invalid"}}catch(r){return r&&r.code==="ENOENT"?{state:"missing"}:{state:"invalid"}}}async function D(e,n){await K(e,n);const t=await Le(e,n);if(t.state==="valid")return t.credential;if(t.state==="invalid")return null;const r=await q(["find-generic-password","-a",S(e),"-s",F,"-w"]);if(r.status===0){const o=oe(r.stdout.trim());if(o)return o}return null}async function M(e,n){await K(e,n);const t=S(e),r=await q(["delete-generic-password","-a",S(e),"-s",F]);return!r.unavailable&&r.status!==0&&r.status!==44?(await H(b(e,n),`${JSON.stringify({account:t,revoked:!0})}
63
- `),{keychainDeleted:!1}):(await U(b(e,n)),{keychainDeleted:!0})}async function P(e,n){const t=await A(n);if(!t)throw new c('Not logged in. Run "hyperscale auth login".');const r=T(e,n,t);if(r.baseUrl!==t.baseUrl||r.environment!==t.environment)throw new c(`The active session belongs to ${t.baseUrl} (${t.environment}). Log in again to change it.`);const o=await D(t,n);if(!o)throw new c('Session credential is missing. Run "hyperscale auth login".');return{...t,...o}}function re(e){return e.replace(/\p{Cc}/gu,n=>`
64
- \r`.includes(n)?n:"")}function N(e){try{return new URL(e).origin}catch{return null}}function $(e,n){let t=e;for(const r of n)typeof r=="string"&&r.length>0&&(t=t.replaceAll(r,"[redacted]"));return t}async function se(e,n,t={},r){const o=`${e.baseUrl}${n}`,s=N(e.baseUrl);if(N(o)!==s)throw new c(`The requested path ${n} leaves the ${s} origin; refusing the request.`);try{const i=await fetch(o,{...t,headers:{accept:"application/json",...r?{authorization:`Bearer ${r}`}:{},"x-hyperscale-environment":e.environment,...t.headers},signal:AbortSignal.timeout(X),redirect:"manual"});if(i.status>=300&&i.status<400)throw new c(`${o} redirected, so no credential was sent on. Point --base-url at the origin the API answers on.`);return{response:i,text:re(await i.text())}}catch(i){throw i instanceof c?i:new c(`Could not reach ${o}: ${i.message}`)}}async function y(e,n,t={},r,o=[]){const{response:s,text:i}=await se(e,n,t,r);if(!s.ok)throw x(s,i,o);try{return JSON.parse(i)}catch{throw new c(`HTTP ${s.status} returned invalid JSON`)}}function I(e){return{body:JSON.stringify(e),headers:{"content-type":"application/json","idempotency-key":globalThis.crypto.randomUUID()},method:"POST"}}let h="";async function Y(e,n=!1){return process.stderr.write(e),process.stdin.isTTY&&typeof process.stdin.setRawMode=="function"?await Re(n):await Oe()}async function Oe(){const e=ie();if(e!==null)return e;if(process.stdin.readableEnded){const n=h.replace(/\r$/,"");return h="",n}return await new Promise((n,t)=>{const r=a=>{h+=a.toString("utf8");const d=ie();d!==null&&(i(),n(d))},o=()=>{const a=h.replace(/\r$/,"");h="",i(),n(a)},s=a=>{i(),t(a)},i=()=>{process.stdin.off("data",r),process.stdin.off("end",o),process.stdin.off("error",s),process.stdin.pause()};process.stdin.on("data",r),process.stdin.once("end",o),process.stdin.once("error",s),process.stdin.resume()})}function ie(){const e=/\r?\n/.exec(h);if(!e||e.index===void 0)return null;const n=h.slice(0,e.index);return h=h.slice(e.index+e[0].length),n}async function Re(e){return await new Promise((n,t)=>{const r=process.stdin.isRaw;let o="";const s=(d,l)=>{process.stdin.off("data",a),process.stdin.off("error",i),process.stdin.setRawMode(!!r),process.stdin.pause(),process.stderr.write(`
65
- `),l?t(l):n(d)},i=d=>s("",d),a=d=>{for(const l of d.toString("utf8")){if(l===""){s("",new c("Login cancelled"));return}if(l==="\r"||l===`
66
- `){s(o);return}if(l==="\x7F"||l==="\b"){if(o.length===0)continue;o=o.slice(0,-1),e||process.stderr.write("\b \b");continue}o+=l,e||process.stderr.write(l)}};process.stdin.setRawMode(!0),process.stdin.on("data",a),process.stdin.once("error",i),process.stdin.resume()})}async function je(){const e=[];for await(const n of process.stdin)e.push(Buffer.from(n));return Buffer.concat(e).toString("utf8")}async function C(e,n,t={}){const r=`${e.baseUrl}${n}`,o=N(e.baseUrl);if(N(r)!==o)throw new c(`The product document puts ${n} on another origin than the ${o} you configured; refusing to send the key there.`);try{const s=await fetch(r,{...t,headers:{accept:"application/json",authorization:`Bearer ${e.apiKey}`,"x-hyperscale-environment":e.environment,...t.headers},signal:AbortSignal.timeout(X),redirect:"manual"});if(s.status>=300&&s.status<400)throw new c(`${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:s,text:re(await s.text())}}catch(s){throw s instanceof c?s:new c(`Could not reach ${r}: ${s.message}`)}}async function V(e){const{response:n,text:t}=await C(e,"/v1/llms.txt");if(!n.ok)throw x(n,t,[e.apiKey]);const r=/^# (.+)$/m.exec(t),o=/^> Generated for composition (\S+) /m.exec(t),s=/^## Operations \((\d+)\)$/m.exec(t);if(!r||!s)throw new Error("The product document is not in the expected format; upgrade the CLI.");const i=[],a=/^- ([A-Z]+) (\S+) · (\S+) \((\S+); idempotency (\S+)\)$/gm;for(const f of t.matchAll(a))i.push({idempotency:f[5],method:f[1],name:f[3],operationId:f[4],path:f[2]});const d=Number(s[1]);if(i.length!==d)throw new Error(`The product document declares ${d} operations but ${i.length} parsed; upgrade the CLI.`);const l=/^- Package: (.+)$/m.exec(t);return{compositionId:o?o[1]:null,operations:i,packageName:l?l[1].trim():null,title:r[1].trim()}}function x(e,n,t=[]){let r=$(n.trim(),t);try{const o=JSON.parse(n);o&&o.error&&typeof o.error.message=="string"&&(r=$(`${o.error.code}: ${o.error.message}`,t))}catch{}return new c(`HTTP ${e.status}${r?` \xB7 ${r}`:""}`)}function ae(e,n){return{authenticated:n,baseUrl:e.baseUrl,email:e.email,environment:e.environment,selectedProduct:e.selectedProduct}}function _e(e,n){if(!e||typeof e!="object"||e.status!=="authenticated"||typeof e.sessionToken!="string"||typeof e.tenantId!="string")throw new c(`Login did not return a new session. Use the portal at ${n}/signin.`);return e}async function Je(e,n){const t=T(e,n);if(e["--passkey"]){u(`Passkey login runs in the portal: ${t.baseUrl}/signin`);return}const r=e["--email"]??(await Y("Email: ",!1)).trim();if(!r)throw new c("Login email is required");const o=await Y("Password: ",!0);if(!o)throw new c("Password is required");let s=await y(t,"/v1/identity/login",I({email:r,password:o}),void 0,[o]);if(s?.status==="mfa_required"){const w=s.mfaChallengeToken;if(typeof w!="string"||w.length===0)throw new c(`MFA must continue in the portal: ${t.baseUrl}/signin`);for(;s?.status!=="authenticated";){const m=await Y("MFA code: ",!0);if(!m)throw new c("MFA code is required");if(s=await y(t,"/v1/identity/login/mfa/verify",I({code:m,mfaChallengeToken:w}),void 0,[o,w,m]),s?.status==="denied"){const g=s.attemptsRemaining;if(typeof g!="number"||g<=0)throw new c(`MFA was denied. Continue in the portal: ${t.baseUrl}/signin`);process.stderr.write(`MFA denied. ${g} attempts remain.
67
- `)}}}const i=_e(s,t.baseUrl),a=await A(n),d={email:r,...t,selectedProduct:a&&a.email===r&&a.baseUrl===t.baseUrl&&a.environment===t.environment?a.selectedProduct:null},l=await xe(d,{sessionToken:i.sessionToken,tenantId:i.tenantId},n);try{await ne(n,d)}catch(w){throw await M(d,n),w}l==="file"&&process.stderr.write(`macOS Keychain is unavailable. The session is in ${b(d,n)} with mode 0600.
68
- `);const f=ae(d,!0);e["--json"]?p(f):u(`Logged in as ${r} to ${t.baseUrl} (${t.environment}).`)}async function Be(e,n){const t=await A(n);if(!t){const s={authenticated:!1};e["--json"]?p(s):u("Not logged in.");return}const r=await D(t,n),o=ae(t,r!==null);if(e["--json"]){p(o);return}u(r?`Logged in as ${t.email}.`:"Session credential missing."),u(`API: ${t.baseUrl}`),u(`Environment: ${t.environment}`),u(`Product: ${t.selectedProduct??"not selected"}`)}async function Fe(e,n){const t=await A(n);if(!t){e["--json"]?p({status:"signed_out"}):u("Already logged out.");return}const r=await D(t,n);if(!r){const d=await M(t,n);z(e,{cleanup:d,message:"Already logged out.",status:"signed_out"});return}const{response:o,text:s}=await se(t,"/v1/identity/logout",I({}),r.sessionToken);if(!o.ok&&o.status!==401&&o.status!==403)throw x(o,s,[r.sessionToken]);const i=await M(t,n);if(o.status===401||o.status===403){z(e,{cleanup:i,message:"The server had already rejected this session.",serverStatus:o.status,status:"signed_out"});return}let a={};try{a=JSON.parse(s)}catch{}z(e,{cleanup:i,message:"The server revoked the session.",revokedAt:a.revokedAt??null,status:a.status??"revoked"})}function z(e,n){const t=n.cleanup.keychainDeleted?"complete":"tombstoned";e["--json"]?p({credentialCleanup:t,...n.revokedAt!==void 0?{revokedAt:n.revokedAt}:{},...n.serverStatus!==void 0?{serverStatus:n.serverStatus}:{},status:n.status}):u(n.message),n.cleanup.keychainDeleted||process.stderr.write(`Keychain cleanup failed. A 0600 profile tombstone blocks the stale session.
69
- `)}function L(e,n){if(!e||typeof e!="object"||!Array.isArray(e.items))throw new c(`${n} returned an invalid collection`);return e.items}async function G(e,n,t,r,o,s=[]){const i=[],a=new Set;let d,l;for(;;){const g=new URLSearchParams(t);d&&g.set("cursor",d);const we=g.size>0?`?${g}`:"",R=await y(e,`${n}${we}`,{},o,s);l===void 0&&(l=R),i.push(...L(R,r));const k=R.nextCursor;if(typeof k!="string"||k.length===0)break;if(a.has(k))throw new c(`${r} repeated cursor ${k}`);a.add(k),d=k}const{items:f,nextCursor:w,...m}=l;return{...m,items:i}}async function Ke(e,n){const t=await G(e,"/v1/blueprints",{},"blueprint.list"),r=L(t,"blueprint.list");if(n["--json"]){p(t);return}for(const o of r)u(`${o.id} ${o.name}${o.summary?` ${o.summary}`:""}`)}async function He(e,n,t){if(!t)throw new c("blueprint show needs a Blueprint id");const r=await y(e,`/v1/blueprints/${encodeURIComponent(t)}`);p(r)}async function qe(e,n){const t=e["--blueprint"],r=e["--name"];if(!t)throw new c("product create needs --blueprint <id>");if(!r)throw new c("product create needs --name <name>");const o=await P(e,n),s=await y(o,"/v1/workspaces/blueprint-compose",I({blueprintId:t,name:r,tenantId:o.tenantId}),o.sessionToken,[o.sessionToken]);if(typeof s?.workspaceId!="string"||typeof s?.blueprintId!="string"||typeof s?.workspaceBuildId!="string")throw new c("workspace.blueprint.compose returned an invalid Product");await ne(n,{...o,selectedProduct:s.workspaceId});const i={blueprintId:s.blueprintId,nextSteps:[`hyperscale product show ${s.workspaceId}`,'hyperscale key create --name "Founder CLI"'],workspaceBuildId:s.workspaceBuildId,workspaceId:s.workspaceId};if(e["--json"]){p(i);return}u(`Product: ${i.workspaceId}`),u(`Blueprint: ${i.blueprintId}`),u(`Build: ${i.workspaceBuildId}`),u("Next:");for(const a of i.nextSteps)u(` ${a}`)}function De(e){return new URLSearchParams({tenantId:e}).toString()}async function Me(e,n){const t=await P(e,n),r=await G(t,"/v1/products",{tenantId:t.tenantId},"product.list",t.sessionToken,[t.sessionToken]),o=L(r,"product.list");if(e["--json"]){p(r);return}for(const s of o){const i=s.workspaceId??s.id??"unknown",a=s.displayName??s.name??"unnamed";u(`${i} ${a}${s.status?` ${s.status}`:""}`)}}async function Ye(e,n,t){const r=await P(e,n),o=t??r.selectedProduct;if(!o)throw new c("product show needs an id because no Product is selected. Create a Product first.");const s=await y(r,`/v1/products/${encodeURIComponent(o)}?${De(r.tenantId)}`,{},r.sessionToken,[r.sessionToken]);p(s)}function O(e,n){const t=n["--product"]??e.selectedProduct;if(!t)throw new c("No Product selected. Pass --product <id> or create a Product first.");return t}async function ce(e,n){const t=await A(n);if(!t)throw new c("No Product selected. Log in and create or select a Product first.");const r=O(t,e),o=T(e,n,t);if(o.baseUrl!==t.baseUrl||o.environment!==t.environment)throw new c(`The selected Product belongs to ${t.baseUrl} (${t.environment}). Select a Product at the configured API origin first.`);const s=e["--api-key"]??n.HYPERSCALE_API_KEY;if(!s)throw new c("No API key. Set HYPERSCALE_API_KEY, or pass --api-key. Request access at https://hyperscale0.ai/request-access.");return{...o,apiKey:s,workspaceId:r}}async function Ve(e,n){const t=await ce(e,n),r=`/v1/workspaces/${encodeURIComponent(t.workspaceId)}/operation-set`,{response:o,text:s}=await C(t,r);if(!o.ok)throw de(o,s,[t.apiKey]);const i=ze(s,o.status);if(e["--json"]){p(i);return}if(i.status==="legacy"){u("This Product uses a legacy surface. It has no frozen public verbs yet."),u(`Build: ${i.workspaceBuildId}`);return}if(i.publicVerbs.length===0)u("No public verbs");else{u("Verb Noun Input Kind");for(const a of i.publicVerbs){const d=a.idempotencyPolicy?.mode==="not_required"?"read-only":"mutation";u(`${a.name} ${a.noun} ${Ge(a.inputSchema)} ${d}`)}}u(`Digest: ${i.tenantOperationSetDigest}`),u(`Build: ${i.workspaceBuildId}`),u(`Surface version: ${i.tenantSurfaceVersion}`)}function ze(e,n){let t;try{t=JSON.parse(e)}catch{throw new c(`HTTP ${n} returned invalid JSON`)}if(!t||typeof t!="object"||t.status!=="legacy"&&t.status!=="frozen"||typeof t.workspaceBuildId!="string")throw new c("The Product operation set is not in the expected format. Upgrade the CLI.");if(t.status==="legacy")return t;if(typeof t.tenantSurfaceVersion!="number"||typeof t.tenantOperationSetDigest!="string"||!Array.isArray(t.publicVerbs))throw new c("The Product operation set is not in the expected format. Upgrade the CLI.");return t}function Ge(e){if(!e||typeof e!="object")return"input schema unavailable";const n=e.properties&&typeof e.properties=="object"&&!Array.isArray(e.properties)?e.properties:{},t=new Set(Array.isArray(e.required)?e.required.filter(o=>typeof o=="string"):[]),r=Object.entries(n).map(([o,s])=>`${o}${t.has(o)?"":"?"}: ${ue(s)}`);return r.length===0?"no input":r.join(", ")}function ue(e){return!e||typeof e!="object"?"value":Array.isArray(e.enum)&&e.enum.length>0?e.enum.map(n=>String(n)).join(" | "):e.type==="array"?`${ue(e.items)}[]`:typeof e.type=="string"?typeof e.format=="string"?`${e.type} (${e.format})`:e.type:"value"}async function We(e,n,t){if(!t)throw new c("product run needs a public verb");const r=await ce(e,n),o=await pe(e),{response:s,text:i}=await C(r,`/v1/operations/${encodeURIComponent(t)}`,{body:JSON.stringify(o),headers:{"content-type":"application/json","idempotency-key":e["--idempotency-key"]??globalThis.crypto.randomUUID()},method:"POST"});if(!s.ok)throw de(s,i,[r.apiKey]);const a=s.headers.get("hyperscale-operation-id"),d=s.headers.get("hyperscale-receipt-id");if(e["--json"]){p({operationId:a,receiptId:d,output:Qe(i)});return}u(`Operation: ${a??"not returned"}`),u(`Receipt: ${d??"not returned"}`);const l=fe(i);l&&u(l)}function Qe(e){if(e.trim()==="")return null;try{return JSON.parse(e)}catch{return e}}function de(e,n,t=[]){const r=$(n.trim(),t);let o;try{o=JSON.parse(n)}catch{return new c(`HTTP ${e.status}${r?` \xB7 ${r}`:""}`)}if(!o?.error||typeof o.error.message!="string")return new c(`HTTP ${e.status}`);const s=typeof o.error.code=="string"?`${o.error.code}: `:"",i=$(`HTTP ${e.status} \xB7 ${s}${o.error.message}`,t),a=Ze(o.error.details,t);return new c([i,...a].join(`
70
- `))}function Ze(e,n){if(!e||typeof e!="object")return[];if(Array.isArray(e.issues))return e.issues.flatMap(r=>{if(!r||typeof r!="object")return[];const s=(Array.isArray(r.path)?r.path.join("."):"input")||"input";return typeof r.message=="string"?[`${s}: ${$(r.message,n)}`]:[]});const t=[];return W(e,"",t,n),t}function W(e,n,t,r){if(Array.isArray(e)){if(e.every(o=>o===null||typeof o!="object")){t.push(`${le(n)}: ${$(e.join(", "),r)}`);return}e.forEach((o,s)=>W(o,`${n}[${s}]`,t,r));return}if(e&&typeof e=="object"){for(const[o,s]of Object.entries(e))W(s,n?`${n}.${o}`:o,t,r);return}n&&t.push(`${le(n)}: ${$(String(e),r)}`)}function le(e){const n=e.replace(/([a-z0-9])([A-Z])/g,"$1 $2").replaceAll("."," ");return n.charAt(0).toUpperCase()+n.slice(1)}async function Xe(e,n){const t=await P(e,n),r=O(t,e),o=await y(t,"/v1/sandbox-api-keys",I({name:e["--name"]??"Founder CLI",tenantId:t.tenantId,workspaceId:r}),t.sessionToken,[t.sessionToken]);if(e["--json"]){p(o);return}u(`Key: ${o.apiKeyId??"unknown"}`),u(`Product: ${o.workspaceId??r}`),u(`Status: ${o.status??"unknown"}`),o.secret?(u(`Secret: ${o.secret}`),u("Store it now. Hyperscale will not return it again.")):u("The key already existed, so the one-time secret is unavailable.")}async function et(e,n){const t=await P(e,n),r=O(t,e),o=await G(t,"/v1/api-keys",{tenantId:t.tenantId},"api_key.list",t.sessionToken,[t.sessionToken]),s=L(o,"api_key.list").filter(a=>a.workspaceId===r),i={...o,items:s};if(e["--json"]){p(i);return}for(const a of s)u(`${a.apiKeyId} ${a.name??"unnamed"} ${a.status??"unknown"}`)}async function tt(e,n,t){if(!t)throw new c("key revoke needs an API key id");const r=await P(e,n),o=O(r,e),s=await y(r,`/v1/api-keys/${encodeURIComponent(t)}/revoke`,I({tenantId:r.tenantId,workspaceId:o}),r.sessionToken,[r.sessionToken]);e["--json"]?p(s):u(`Key ${s.apiKeyId??t}: ${s.status??"revoked"}`)}async function nt(e,n){const t=await V(e);if(n["--json"]){u(JSON.stringify({baseUrl:e.baseUrl,compositionId:t.compositionId,environment:e.environment,operationCount:t.operations.length,packageName:t.packageName,product:t.title},null,2));return}const r=[["Product",t.title],["Composition",t.compositionId??"unknown"],["Environment",e.environment],["API",e.baseUrl],["Operations",String(t.operations.length)],["SDK package",t.packageName??"not published"]],o=Math.max(...r.map(([s])=>s.length));for(const[s,i]of r)u(`${s.padEnd(o)} ${i}`)}async function ot(e,n,t){const r=await V(e),o=t?t.toLowerCase():null,s=o?r.operations.filter(a=>a.name.toLowerCase().includes(o)||a.path.toLowerCase().includes(o)):r.operations;if(n["--json"]){u(JSON.stringify(s,null,2));return}if(s.length===0){u(t?`No operation matches ${t}`:"No operations");return}const i=Math.max(...s.map(a=>a.name.length));for(const a of s)u(`${a.name.padEnd(i)} ${a.method.padEnd(6)}${a.path}`)}function rt(e,n){const t={...n},r=[],o=e.path.replace(/\{([^}]+)\}/g,(s,i)=>{const a=t[i];return a==null?(r.push(i),""):(delete t[i],encodeURIComponent(String(a)))});if(r.length>0)throw new c(`${e.name} needs ${r.join(", ")} in --input`);return{path:o,remaining:t}}function st(e){const n=new URLSearchParams;for(const[r,o]of Object.entries(e))o!=null&&n.set(r,typeof o=="string"?o:JSON.stringify(o));const t=n.toString();return t?`?${t}`:""}async function it(e,n,t){if(!t)throw new c("call needs an operation name");const o=(await V(e)).operations.find(m=>m.name===t||m.operationId===t);if(!o)throw new c(`${t} is not an operation of this product. Run "hyperscale ops list" to see them.`);const s=await pe(n),{path:i,remaining:a}=rt(o,s),d={method:o.method};let l=i;o.method==="GET"?l+=st(a):(d.body=JSON.stringify(a),d.headers={"content-type":"application/json",...o.idempotency==="not_required"?{}:{"idempotency-key":n["--idempotency-key"]??globalThis.crypto.randomUUID()}});const{response:f,text:w}=await C(e,l,d);if(!f.ok)throw x(f,w,[e.apiKey]);u(fe(w))}async function pe(e){if(e["--input"]!==void 0&&e["--input-file"]!==void 0)throw new c("Use only one of --input and --input-file");if(e["--input"]!==void 0)return Q(e["--input"],"--input");if(e["--input-file"]!==void 0){let n;try{n=await _(e["--input-file"],"utf8")}catch(t){throw new c(`Could not read ${e["--input-file"]}: ${t.message}`)}return Q(n,"--input-file")}if(!process.stdin.isTTY){const n=await je();if(n.trim()!=="")return Q(n,"stdin")}return{}}function Q(e,n="--input"){if(e===void 0)return{};let t;try{t=JSON.parse(e)}catch(r){throw new c(`${n} is not valid JSON: ${r.message}`)}if(t===null||typeof t!="object"||Array.isArray(t))throw new c(`${n} must be a JSON object`);return t}function fe(e){if(e.trim()==="")return"";try{return JSON.stringify(JSON.parse(e),null,2)}catch{return e}}function u(e){process.stdout.write(`${e}
71
- `)}function p(e){u(JSON.stringify(e,null,2))}async function at(){const{readFileSync:e}=await import("node:fs");return JSON.parse(e(new URL("./package.json",import.meta.url),"utf8")).version}async function ct(e,n){const{flags:t,positional:r}=Ee(e);if(t["--version"])return u(await at()),0;if(t["--help"]||r.length===0)return process.stdout.write(Ae),r.length===0&&!t["--help"]?1:0;const[o,...s]=r;if(o==="auth"){if(s[0]==="login")await Je(t,n);else if(s[0]==="status")await Be(t,n);else if(s[0]==="logout")await Fe(t,n);else throw new c('Auth subcommands are "login", "status", and "logout"');return 0}if(o==="blueprint"){const a=T(t,n);if(s[0]==="list")await Ke(a,t);else if(s[0]==="show")await He(a,t,s[1]);else throw new c('Blueprint subcommands are "list" and "show"');return 0}if(o==="product"){if(s[0]==="create")await qe(t,n);else if(s[0]==="list")await Me(t,n);else if(s[0]==="show")await Ye(t,n,s[1]);else if(s[0]==="verbs")await Ve(t,n);else if(s[0]==="run")await We(t,n,s[1]);else throw new c('Product subcommands are "create", "list", "show", "verbs", and "run"');return 0}if(o==="key"){if(s[0]==="create")await Xe(t,n);else if(s[0]==="list")await et(t,n);else if(s[0]==="revoke")await tt(t,n,s[1]);else throw new c('Key subcommands are "create", "list", and "revoke"');return 0}const i=Te(t,n);if(o==="whoami")return await nt(i,t),0;if(o==="ops"){if(s[0]!=="list")throw new c('The only ops subcommand is "list"');return await ot(i,t,s[1]),0}if(o==="call")return await it(i,t,s[0]),0;throw new c(`Unknown command: ${o}`)}ct(process.argv.slice(2),process.env).then(e=>{process.exitCode=e},e=>{process.stderr.write(`${e instanceof c?e.message:e.stack??String(e)}
72
- `),process.exitCode=1});
86
+ `,x=class extends Error{},Oe=class extends x{constructor(t,n){super(t),this.code="check_failed",this.details=n,this.exitCode=2}},or=new Set(["--api-key","--base-url","--blueprint","--environment","--email","--idempotency-key","--input","--input-file","--name","--product","--role","--token"]);function ar(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(or.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 ir(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??cn;if(r!=="sandbox"&&r!=="live")throw new x(`Unknown environment: ${r}. Use sandbox or live.`);let o=(e["--base-url"]??t.HYPERSCALE_BASE_URL??Le).replace(/\/+$/,"");return{apiKey:n,baseUrl:o,environment:r}}function Je(e,t,n={}){let r=e["--environment"]??t.HYPERSCALE_ENVIRONMENT??n.environment??cn;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??Le).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 Mn(e){return e.HYPERSCALE_CONFIG_DIR??qe(Qt(),".config","hyperscale")}function Un(e){return qe(Mn(e),tr)}function we(e,t){return qe(Mn(t),`session-${_e(e)}.json`)}async function ln(e,t){let n=we(e,t),r=`${er(n)}.`,o;try{o=await Wt(an(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 Me(qe(an(n),a.name))}}async function sr(e){try{return JSON.parse(await je(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 un(e,t){let n=cr(e);await Vt(n,{mode:448,recursive:!0}),await rn(n,448);let r=`${e}.${process.pid}.${globalThis.crypto.randomUUID()}.tmp`;await Zt(r,t,{flag:"wx",mode:384}),await rn(r,384);try{await Gt(r,e),await rn(e,384)}catch(o){throw await Me(r),o}}function cr(e){return an(e)}async function Me(e){try{await Xt(e)}catch(t){if(!t||t.code!=="ENOENT")throw t}}function dr(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=Un(e),n=await sr(t);return n===null?null:dr(n,t)}async function Kn(e,t){let n={email:t.email,baseUrl:t.baseUrl,environment:t.environment,selectedProduct:t.selectedProduct??null};await un(Un(e),`${JSON.stringify(n,null,2)}
87
+ `)}function _e(e){return Yt("sha256").update(`${e.baseUrl}\0${e.environment}\0${e.email}`).digest("hex")}async function pn(e,t){return jn===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=Ht(jn,e,{env:r,stdio:["pipe","pipe","pipe"]}),a=[];o.stdout.on("data",l=>a.push(l)),o.stderr.on("data",()=>{}),o.once("error",l=>n({error:l,status:null,stdout:"",unavailable:l?.code==="ENOENT"})),o.once("close",l=>n({error:null,status:l,stdout:Buffer.concat(a).toString("utf8"),unavailable:!1})),t===void 0?o.stdin.end():o.stdin.end(`${t}
88
+ `)})}function zn(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 lr(e,t,n){await ln(e,n);let r=_e(e),o=JSON.stringify(t),a=["add-generic-password","-a",r,"-s",dn,"-U","-X",Buffer.from(o,"utf8").toString("hex")].join(" ");return(await pn(["-i"],a)).status===0?(await Me(we(e,n)),"keychain"):(await un(we(e,n),`${JSON.stringify({account:r,credential:t})}
89
+ `),"file")}async function ur(e,t){let n=_e(e);try{let r=JSON.parse(await je(we(e,t),"utf8"));if(!r||typeof r!="object"||Array.isArray(r)||r.account!==n)return{state:"invalid"};let o=zn(r.credential);return o?{credential:o,state:"valid"}:{state:"invalid"}}catch(r){return r&&r.code==="ENOENT"?{state:"missing"}:{state:"invalid"}}}async function mn(e,t){await ln(e,t);let n=await ur(e,t);if(n.state==="valid")return n.credential;if(n.state==="invalid")return null;let r=await pn(["find-generic-password","-a",_e(e),"-s",dn,"-w"]);if(r.status===0){let o=zn(r.stdout.trim());if(o)return o}return null}async function Hn(e,t){await ln(e,t);let n=_e(e),r=await pn(["delete-generic-password","-a",_e(e),"-s",dn]);return!r.unavailable&&r.status!==0&&r.status!==44?(await un(we(e,t),`${JSON.stringify({account:n,revoked:!0})}
90
+ `),{keychainDeleted:!1}):(await Me(we(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=Je(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 mn(n,t);if(!o)throw new x('Founder PAT is missing. Run "hyperscale auth login".');return{...n,...o}}function Yn(e){return e.replace(new RegExp("\\p{Cc}","gu"),t=>`
91
+ \r`.includes(t)?t:"")}function Be(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 pr(e,t,n={},r){let o=`${e.baseUrl}${t}`,a=Be(e.baseUrl);if(Be(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(Jn),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:Yn(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 pr(e,t,n,r);if(!a.ok)throw fn(a,l,o);try{return JSON.parse(l)}catch{throw new x(`HTTP ${a.status} returned invalid JSON`)}}function $e(e,t=globalThis.crypto.randomUUID()){return{body:JSON.stringify(e),headers:{"content-type":"application/json","idempotency-key":t},method:"POST"}}async function mr(){let e=[];for await(let t of process.stdin)e.push(Buffer.from(t));return Buffer.concat(e).toString("utf8")}async function Ue(e,t,n={}){let r=`${e.baseUrl}${t}`,o=Be(e.baseUrl);if(Be(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(Jn),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:Yn(await a.text())}}catch(a){throw a instanceof x?a:new x(`Could not reach ${r}: ${a.message}`)}}async function Vn(e){let{response:t,text:n}=await Ue(e,"/v1/llms.txt");if(!t.ok)throw fn(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 _=/^- Package: (.+)$/m.exec(n);return{compositionId:o?o[1]:null,operations:l,packageName:_?_[1].trim():null,title:r[1].trim()}}function fn(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 yn(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 fr(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 Ke(e,t){return fr(await ce(e,nr,{},t,[t]))}async function yr(e,t){let n=Je(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 Ke(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 lr(l,{personalAccessTokenId:o.personalAccessTokenId,token:r,tokenName:o.name,tenantId:o.tenantId},t);try{await Kn(t,l)}catch(_){throw await Hn(l,t),_}s==="file"&&process.stderr.write(`macOS Keychain is unavailable. The founder PAT is in ${we(l,t)} with mode 0600.
92
+ `);let u=yn(l,o);e["--json"]?re(u):E(`Logged in as ${o.email} with PAT ${o.name}.`)}async function hr(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 mn(n,t);if(!r){let l={authenticated:!1};e["--json"]?re(l):E("Founder PAT missing.");return}let o=await Ke(n,r.token),a=yn(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 gr(e,t){let n=await Pe(t);if(!n){e["--json"]?re({status:"signed_out"}):E("Already logged out.");return}let r=await mn(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 Ke(n,r.token);o=u.personalAccessTokenId,a=u.name}await ce(n,`/v1/personal-access-tokens/${encodeURIComponent(o)}/revoke`,$e({tenantId:r.tenantId,personalAccessTokenId:o}),r.token,[r.token])}let l=await Hn(n,t),s=e["--revoke"]===!0;$r(e,{cleanup:l,personalAccessTokenId:o,revoked:s,status:"signed_out",tokenName:a})}function $r(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.
93
+ `)}function Ie(e,t){if(!e||typeof e!="object"||!Array.isArray(e.items))throw new x(`${t} returned an invalid collection`);return e.items}async function ze(e,t,n,r,o,a=[]){let l=[],s=new Set,u,_;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);_===void 0&&(_=D),l.push(...Ie(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{...w,items:l}}async function br(e,t){let n=await ze(e,"/v1/blueprints",{},"blueprint.list"),r=Ie(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 vr(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 wr(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",$e({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 Kn(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 Wn(e){return new URLSearchParams({tenantId:e}).toString()}async function kr(e,t){let n=await ue(e,t),r=await ze(n,"/v1/products",{tenantId:n.tenantId},"product.list",n.token,[n.token]),o=Ie(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 _r(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)}?${Wn(r.tenantId)}`,{},r.token,[r.token]);re(a)}function Gn(e,t){return t.map(n=>`${e}:${n.line}:${n.column}: ${n.severity} [${n.stage}] ${n.message}`)}function Ar(e){return e.map(t=>`${t.path}: error [composer] ${t.code}: ${t.message}`)}async function xr(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 je(e,"utf8")}catch(r){throw new x(`Could not read ${e}: ${r.message}`)}let n=tn(t);if(n.verdict==="invalid"||!n.artifacts){let r=[...n.diagnostics];throw new Oe(["HSX compilation failed.",...Gn(e,r)].join(`
94
+ `),{diagnostics:r,file:e,issues:[],verdict:n.verdict})}return{file:e,result:n,source:t}}function Cr(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 hn(e,t,n,r){let o=await xr(n),a=await ue(e,t),l=r?Te(a,e):void 0,s=Cr(await ce(a,"/v1/composer/check",$e({tenantId:a.tenantId,document:o.result.artifacts.document}),a.token,[a.token]));if(!s.ok){let u=[...o.result.diagnostics];throw new Oe(["composer.check refused the program.",...Ar(s.issues)].join(`
95
+ `),{diagnostics:u,file:n,issues:s.issues,verdict:o.result.verdict})}return{check:s,compiled:o,context:a,workspaceId:l}}function gn(e,t){for(let n of Gn(e,t.diagnostics))process.stderr.write(`${n}
96
+ `)}async function Er(e,t,n){let r=await hn(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}gn(n,r.compiled.result),E(`Check passed: ${n}`)}async function Sr(e,t,n){let r=await hn(e,t,n,!0),o=await ce(r.context,"/v1/composer/plan",$e({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}gn(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 Pr(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 Ir(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 hn(e,t,n,!0),o=r.compiled.result.artifacts.document,a=await ce(r.context,"/v1/workspaces/recompose",$e({nounIds:Pr(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}gn(n,r.compiled.result),E(`Product: ${a.workspaceId??r.workspaceId}`),E(`Build: ${a.workspaceBuildId}`),a.buildDigest&&E(`Digest: ${a.buildDigest}`)}function Te(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 Xn(e,t){let n=await Pe(t),r=Te(n??{},e),o=Je(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 Tr(e,t,n){let r=await Xn(e,t),o=`/v1/workspaces/${encodeURIComponent(r.workspaceId)}/operation-set`,{response:a,text:l}=await Ue(r,o);if(!a.ok)throw Qn(a,l,[r.apiKey]);let s=Rr(l,a.status);if(n){Fr(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 _=u.idempotencyPolicy?.mode==="not_required"?"read-only":"mutation";E(`${u.noun}.${u.name} ${Dr(u.inputSchema)} ${_}`)}}E(`Digest: ${s.tenantOperationSetDigest}`),E(`Build: ${s.workspaceBuildId}`),E(`Surface version: ${s.tenantSurfaceVersion}`)}function Fr(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 Rr(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 Dr(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)?"":"?"}: ${Zn(a)}`);return r.length===0?"no input":r.join(", ")}function Zn(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"?`${Zn(e.items)}[]`:typeof e.type=="string"?typeof e.format=="string"?`${e.type} (${e.format})`:e.type:"value"}async function Nr(e,t,n){if(!n)throw new x("product run needs a public verb");let r=await Xn(e,t),o=await et(e),{response:a,text:l}=await Ue(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 Qn(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:Lr(l)});return}E(`Operation: ${s??"not returned"}`),E(`Receipt: ${u??"not returned"}`);let _=nt(l);_&&E(_)}function Lr(e){if(e.trim()==="")return null;try{return JSON.parse(e)}catch{return e}}function Qn(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=Or(o.error.details,n);return new x([l,...s].join(`
97
+ `))}function Or(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 sn(e,"",n,t),n}function sn(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)=>sn(o,`${t}[${a}]`,n,r));return}if(e&&typeof e=="object"){for(let[o,a]of Object.entries(e))sn(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 Br(e,t){let n=await ue(e,t),r=Te(n,e),o=await ce(n,"/v1/sandbox-api-keys",$e({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 jr(e,t){let n=await ue(e,t),r=Te(n,e),o=await ze(n,"/v1/api-keys",{tenantId:n.tenantId},"api_key.list",n.token,[n.token]),a=Ie(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 qr(e,t,n){if(!n)throw new x("key revoke needs an API key id");let r=await ue(e,t),o=Te(r,e),a=await ce(r,`/v1/api-keys/${encodeURIComponent(n)}/revoke`,$e({tenantId:r.tenantId,workspaceId:o}),r.token,[r.token]);e["--json"]?re(a):E(`Key ${a.apiKeyId??n}: ${a.status??"revoked"}`)}async function Jr(e,t){let n=await ue(e,t),r=await Ke(n,n.token),o=yn(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 Mr(e,t,n){let r=await Vn(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 Ur(e,t){let n=await ue(e,t),r=await ce(n,`/v1/team/members?${Wn(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 Kr(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",$e({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 zr(e,t){let n=await ue(e,t),r=await ze(n,"/v1/activity",{tenantId:n.tenantId},"activity.list",n.token,[n.token]),o=Ie(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 Hr(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 Yr(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}`:""}async function Vr(e,t,n){if(!n)throw new x("call needs an operation name");let o=(await Vn(e)).operations.find(w=>w.name===n||w.operationId===n);if(!o)throw new x(`${n} is not an operation in the selected Product's machine document.`);let a=await et(t),{path:l,remaining:s}=Hr(o,a),u={method:o.method},_=l;o.method==="GET"?_+=Yr(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 Ue(e,_,u);if(!v.ok)throw fn(v,P,[e.apiKey]);E(nt(P))}async function et(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 on(e["--input"],"--input");if(e["--input-file"]!==void 0){let t;try{t=await je(e["--input-file"],"utf8")}catch(n){throw new x(`Could not read ${e["--input-file"]}: ${n.message}`)}return on(t,"--input-file")}if(!process.stdin.isTTY){let t=await mr();if(t.trim()!=="")return on(t,"stdin")}return{}}function on(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 nt(e){if(e.trim()==="")return"";try{return JSON.stringify(JSON.parse(e),null,2)}catch{return e}}function E(e){process.stdout.write(`${e}
98
+ `)}function re(e){E(JSON.stringify(e,null,2))}function Wr(e,t){if(!t.includes("--json")){process.stderr.write(`${e instanceof x?e.message:e.stack??String(e)}
99
+ `);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."}})}
100
+ `)}async function Gr(){let{readFileSync:e}=await import("node:fs");return JSON.parse(e(new URL("./package.json",import.meta.url),"utf8")).version}async function Xr(e,t){let{flags:n,positional:r}=ar(e);if(n["--version"])return E(await Gr()),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(rr),r.length===0&&!n["--help"]?1:0}let[o,...a]=r;if(o==="auth"){if(a[0]==="login")await yr(n,t);else if(a[0]==="status")await hr(n,t);else if(a[0]==="logout")await gr(n,t);else throw new x('Auth subcommands are "login", "status", and "logout"');return 0}if(o==="blueprint"){let s=Je(n,t);if(a[0]==="list")await br(s,n);else if(a[0]==="show")await vr(s,n,a[1]);else throw new x('Blueprint subcommands are "list" and "show"');return 0}if(o==="product"){if(a[0]==="create")await wr(n,t);else if(a[0]==="list")await kr(n,t);else if(a[0]==="show")await _r(n,t,a[1]);else if(a[0]==="verbs")await Tr(n,t,a[1]);else if(a[0]==="run")await Nr(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 Er(n,t,a[1]);else if(a[0]==="plan")await Sr(n,t,a[1]);else if(a[0]==="apply")await Ir(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 Br(n,t);else if(a[0]==="list")await jr(n,t);else if(a[0]==="revoke")await qr(n,t,a[1]);else throw new x('Key subcommands are "create", "list", and "revoke"');return 0}if(o==="whoami")return await Jr(n,t),0;if(o==="team"){if(a[0]==="list")await Ur(n,t);else if(a[0]==="invite")await Kr(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 zr(n,t),0}let l=ir(n,t);if(o==="ops"){if(a[0]!=="list")throw new x('The only ops subcommand is "list"');return await Mr(l,n,a[1]),0}if(o==="call")return await Vr(l,n,a[0]),0;throw new x(`Unknown command: ${o}`)}Xr(process.argv.slice(2),process.env).then(e=>{process.exitCode=e},e=>{Wr(e,process.argv.slice(2)),process.exitCode=e instanceof x&&Number.isInteger(e.exitCode)?e.exitCode:1});
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hyperscale0/cli",
3
- "version": "1.0.0-alpha.5",
3
+ "version": "1.0.0-beta.1",
4
4
  "description": "The Hyperscale founder command line: compose Products, manage keys, and call Product operations.",
5
5
  "license": "LicenseRef-Hyperscale-Proprietary",
6
6
  "author": "Hyperscale LLC",