@hyperscale0/cli 1.0.0-alpha.6 → 1.0.0-beta.2

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