@hyperscale0/hsx 1.0.0-rc.1 → 2.0.0

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 (188) hide show
  1. package/CHANGELOG.md +32 -4
  2. package/README.md +58 -36
  3. package/bin/hsx.ts +2 -0
  4. package/dist/bin/hsx.js +2 -0
  5. package/dist/bin/hsx.js.map +1 -1
  6. package/dist/src/ast.d.ts +10 -2
  7. package/dist/src/ast.d.ts.map +1 -1
  8. package/dist/src/ast.js +24 -0
  9. package/dist/src/ast.js.map +1 -1
  10. package/dist/src/cli.d.ts +3 -1
  11. package/dist/src/cli.d.ts.map +1 -1
  12. package/dist/src/cli.js +25 -5
  13. package/dist/src/cli.js.map +1 -1
  14. package/dist/src/compile.d.ts +9 -5
  15. package/dist/src/compile.d.ts.map +1 -1
  16. package/dist/src/compile.js +9 -3
  17. package/dist/src/compile.js.map +1 -1
  18. package/dist/src/cost.d.ts +3 -1
  19. package/dist/src/cost.d.ts.map +1 -1
  20. package/dist/src/cost.js +124 -94
  21. package/dist/src/cost.js.map +1 -1
  22. package/dist/src/diagnostics.d.ts.map +1 -1
  23. package/dist/src/diagnostics.js +89 -5
  24. package/dist/src/diagnostics.js.map +1 -1
  25. package/dist/src/emit.d.ts +4 -3
  26. package/dist/src/emit.d.ts.map +1 -1
  27. package/dist/src/emit.js +28 -233
  28. package/dist/src/emit.js.map +1 -1
  29. package/dist/src/format.js.map +1 -1
  30. package/dist/src/index.d.ts +4 -3
  31. package/dist/src/index.d.ts.map +1 -1
  32. package/dist/src/index.js +3 -1
  33. package/dist/src/index.js.map +1 -1
  34. package/dist/src/ir.d.ts.map +1 -1
  35. package/dist/src/lex.d.ts.map +1 -1
  36. package/dist/src/lsp/server.d.ts +32 -0
  37. package/dist/src/lsp/server.d.ts.map +1 -0
  38. package/dist/src/lsp/server.js +391 -0
  39. package/dist/src/lsp/server.js.map +1 -0
  40. package/dist/src/modules.d.ts +2 -0
  41. package/dist/src/modules.d.ts.map +1 -1
  42. package/dist/src/modules.js +14 -14
  43. package/dist/src/modules.js.map +1 -1
  44. package/dist/src/parse.js +3 -3
  45. package/dist/src/parse.js.map +1 -1
  46. package/dist/src/std-bundle.d.ts +2 -0
  47. package/dist/src/std-bundle.d.ts.map +1 -0
  48. package/dist/src/std-bundle.js +88 -0
  49. package/dist/src/std-bundle.js.map +1 -0
  50. package/dist/src/std-library.d.ts +5 -0
  51. package/dist/src/std-library.d.ts.map +1 -0
  52. package/dist/src/std-library.js +9 -0
  53. package/dist/src/std-library.js.map +1 -0
  54. package/dist/src/typecheck.d.ts.map +1 -1
  55. package/dist/src/typecheck.js +859 -156
  56. package/dist/src/typecheck.js.map +1 -1
  57. package/dist/src/version.d.ts +1 -1
  58. package/dist/src/version.d.ts.map +1 -1
  59. package/dist/src/version.js +1 -1
  60. package/dist/src/version.js.map +1 -1
  61. package/docs/README.md +12 -0
  62. package/docs/assets/hsx.svg +18 -0
  63. package/docs/guide/01-first-program.md +2 -2
  64. package/docs/guide/02-money.md +1 -1
  65. package/docs/guide/03-instruments.md +44 -3
  66. package/docs/guide/04-lifecycles.md +18 -3
  67. package/docs/guide/05-fees-and-splits.md +2 -2
  68. package/docs/guide/06-schedules.md +1 -1
  69. package/docs/guide/07-composition.md +8 -2
  70. package/docs/guide/08-writing-a-module.md +13 -2
  71. package/docs/guide/09-cost.md +3 -3
  72. package/docs/guide/10-diagnostics.md +1 -1
  73. package/docs/llms-full.txt +458 -194
  74. package/docs/llms.txt +2 -2
  75. package/docs/playground.md +55 -0
  76. package/docs/reference/cli.md +5 -3
  77. package/docs/reference/diagnostics.md +223 -37
  78. package/docs/reference/grammar.md +2 -2
  79. package/docs/reference/std/advance.md +2 -2
  80. package/docs/reference/std/cancellable_booking.md +10 -10
  81. package/docs/reference/std/captured_payment.md +14 -14
  82. package/docs/reference/std/conditional_disbursement.md +3 -3
  83. package/docs/reference/std/credit_facility.md +2 -2
  84. package/docs/reference/std/held_payment.md +37 -33
  85. package/docs/reference/std/instant_transfer.md +8 -8
  86. package/docs/reference/std/metered.md +2 -2
  87. package/docs/reference/std/pooled_split.md +2 -2
  88. package/docs/reference/std/premium_forward.md +13 -13
  89. package/docs/reference/std/reconciled_payout.md +2 -2
  90. package/docs/reference/std/recurring_collection.md +2 -2
  91. package/docs/reference/std/rotating_pool.md +2 -2
  92. package/docs/reference/std/scheduled.md +18 -18
  93. package/docs/reference/std/security_deposit.md +14 -14
  94. package/docs/reference/std/settlement_batch.md +2 -2
  95. package/docs/reference/std/swap.md +18 -18
  96. package/docs/reference/std/threshold_pool.md +2 -2
  97. package/docs/reference/std/weighted_distribution.md +2 -2
  98. package/docs/reference/types.md +1 -1
  99. package/docs/reference/udl-output.md +2 -3
  100. package/examples/01-first-program/README.md +1 -1
  101. package/examples/01-first-program/tip-jar.hsx +1 -1
  102. package/examples/02-imports-and-archetypes/README.md +1 -4
  103. package/examples/02-imports-and-archetypes/photo-booth.hsx +1 -1
  104. package/examples/03-diagnostics/corner-shop-fixed.hsx +1 -1
  105. package/examples/03-diagnostics/corner-shop.hsx +1 -1
  106. package/examples/04-complete-product/README.md +0 -3
  107. package/examples/04-complete-product/study-hall.hsx +1 -1
  108. package/examples/05-watch-club/README.md +0 -3
  109. package/examples/05-watch-club/watch-club.hsx +1 -1
  110. package/examples/README.md +35 -4
  111. package/examples/advance/advance.hsx +1 -1
  112. package/examples/advance/advance.udl +10 -5
  113. package/examples/cancellable_booking/cancellable_booking.hsx +1 -1
  114. package/examples/cancellable_booking/cancellable_booking.udl +3 -1
  115. package/examples/captured_payment/captured_payment.hsx +1 -1
  116. package/examples/captured_payment/captured_payment.udl +4 -1
  117. package/examples/conditional_disbursement/conditional_disbursement.hsx +1 -1
  118. package/examples/conditional_disbursement/conditional_disbursement.udl +5 -3
  119. package/examples/cost-table.json +1602 -382
  120. package/examples/credit_facility/credit_facility.hsx +1 -1
  121. package/examples/credit_facility/credit_facility.udl +16 -9
  122. package/examples/held_payment/held_payment.hsx +1 -1
  123. package/examples/held_payment/held_payment.udl +38 -3
  124. package/examples/instant_transfer/instant_transfer.hsx +1 -1
  125. package/examples/instant_transfer/instant_transfer.udl +11 -5
  126. package/examples/metered/metered.hsx +1 -1
  127. package/examples/metered/metered.udl +4 -2
  128. package/examples/pooled_split/pooled_split.hsx +1 -1
  129. package/examples/pooled_split/pooled_split.udl +6 -3
  130. package/examples/premium_forward/premium_forward.hsx +1 -1
  131. package/examples/premium_forward/premium_forward.udl +10 -4
  132. package/examples/reconciled_payout/reconciled_payout.hsx +1 -1
  133. package/examples/reconciled_payout/reconciled_payout.udl +4 -2
  134. package/examples/recurring_collection/recurring_collection.hsx +1 -1
  135. package/examples/recurring_collection/recurring_collection.udl +12 -7
  136. package/examples/rotating_pool/rotating_pool.hsx +1 -1
  137. package/examples/rotating_pool/rotating_pool.udl +14 -4
  138. package/examples/scheduled/scheduled.hsx +1 -1
  139. package/examples/scheduled/scheduled.udl +9 -4
  140. package/examples/security_deposit/security_deposit.hsx +1 -1
  141. package/examples/security_deposit/security_deposit.udl +17 -3
  142. package/examples/settlement_batch/settlement_batch.hsx +1 -1
  143. package/examples/swap/swap.hsx +1 -1
  144. package/examples/swap/swap.udl +12 -6
  145. package/examples/threshold_pool/threshold_pool.hsx +1 -1
  146. package/examples/threshold_pool/threshold_pool.udl +4 -2
  147. package/examples/weighted_distribution/weighted_distribution.hsx +1 -1
  148. package/examples/weighted_distribution/weighted_distribution.udl +4 -2
  149. package/package.json +15 -6
  150. package/skills/hsx/SKILL.md +26 -26
  151. package/src/ast.ts +34 -2
  152. package/src/cli.ts +32 -13
  153. package/src/compile.ts +15 -7
  154. package/src/cost.ts +176 -104
  155. package/src/diagnostics.ts +89 -4
  156. package/src/emit.ts +34 -266
  157. package/src/index.ts +10 -7
  158. package/src/lsp/server.ts +460 -0
  159. package/src/modules.ts +21 -13
  160. package/src/parse.ts +3 -3
  161. package/src/std-bundle.ts +91 -0
  162. package/src/std-library.ts +12 -0
  163. package/src/typecheck.ts +1147 -235
  164. package/src/version.ts +1 -1
  165. package/std/SEMANTICS.md +12 -3
  166. package/std/{settlements → money_flows}/advance.hsx +1 -1
  167. package/std/{settlements → money_flows}/cancellable_booking.hsx +4 -3
  168. package/std/{settlements → money_flows}/captured_payment.hsx +35 -6
  169. package/std/{settlements → money_flows}/conditional_disbursement.hsx +17 -16
  170. package/std/{settlements → money_flows}/credit_facility.hsx +1 -2
  171. package/std/{settlements → money_flows}/held_payment.hsx +59 -25
  172. package/std/money_flows/index.hsx +3 -0
  173. package/std/{settlements → money_flows}/instant_transfer.hsx +2 -3
  174. package/std/{settlements → money_flows}/metered.hsx +1 -1
  175. package/std/{settlements → money_flows}/pooled_split.hsx +3 -3
  176. package/std/{settlements → money_flows}/premium_forward.hsx +22 -23
  177. package/std/{settlements → money_flows}/reconciled_payout.hsx +3 -3
  178. package/std/{settlements → money_flows}/recurring_collection.hsx +1 -1
  179. package/std/{settlements → money_flows}/rotating_pool.hsx +8 -6
  180. package/std/{settlements → money_flows}/scheduled.hsx +22 -27
  181. package/std/{settlements → money_flows}/security_deposit.hsx +38 -14
  182. package/std/{settlements → money_flows}/settlement_batch.hsx +3 -3
  183. package/std/{settlements → money_flows}/swap.hsx +41 -16
  184. package/std/{settlements → money_flows}/threshold_pool.hsx +5 -5
  185. package/std/{settlements → money_flows}/weighted_distribution.hsx +6 -6
  186. package/docs/sessions/2026-09-02-two-instruments.hsx +0 -21
  187. package/docs/sessions/2026-09-02-two-instruments.md +0 -41
  188. package/std/settlements/index.hsx +0 -3
@@ -1,5 +1,5 @@
1
1
  program deposit_example "Deposit example"
2
- import { security_deposit } from "std/settlements"
2
+ import { security_deposit } from "std/money_flows"
3
3
  party renter: person
4
4
  party owner: business
5
5
  settlement security_deposit = security_deposit {
@@ -37,9 +37,10 @@
37
37
  "additionalProperties": false,
38
38
  "properties": {
39
39
  "damageAmount": {
40
- "description": "Caller-decided amount in minor units",
40
+ "description": "Decided amount in SAR minor units",
41
41
  "pattern": "^(0|[1-9][0-9]{0,17})$",
42
- "type": "string"
42
+ "type": "string",
43
+ "x-hyperscale-currency": "SAR"
43
44
  },
44
45
  "evidence": {
45
46
  "description": "Required decision reference retained in the operation receipt",
@@ -168,12 +169,19 @@
168
169
  }
169
170
  ],
170
171
  "publicAction": "placeDepositSecurityDeposit",
172
+ "sandboxFailurePoint": "funding",
171
173
  "steps": [],
172
174
  "summary": "Reserve the depositAmount against the renter's account"
173
175
  },
174
176
  "return_deposit": {
175
177
  "agentDescription": "Return the held deposit to the renter. The deposit must be in held and unclaimed. This releases the reservation whole and the owner receives nothing.",
176
178
  "effects": {
179
+ "decides": [
180
+ {
181
+ "signature": "decides.tenant_port",
182
+ "source": "port"
183
+ }
184
+ ],
177
185
  "moves": [
178
186
  {
179
187
  "signature": "moves.transfer.internal",
@@ -197,6 +205,11 @@
197
205
  "operation": "internal_transfer.void"
198
206
  }
199
207
  ],
208
+ "port": {
209
+ "allowedParties": [
210
+ "beneficiary"
211
+ ]
212
+ },
200
213
  "publicAction": "returnDepositSecurityDeposit",
201
214
  "steps": [],
202
215
  "summary": "Return the deposit to the renter through return_deposit"
@@ -215,7 +228,8 @@
215
228
  "depositAmount": {
216
229
  "description": "The deposit amount in SAR minor units, reserved in full and fully accounted on claim or return",
217
230
  "pattern": "^[1-9][0-9]{0,17}$",
218
- "type": "string"
231
+ "type": "string",
232
+ "x-hyperscale-currency": "SAR"
219
233
  },
220
234
  "ownerAccountId": {
221
235
  "description": "The owner account",
@@ -1,5 +1,5 @@
1
1
  program settlement_batch_example "Settlement batch example"
2
- import { settlement_batch } from "std/settlements"
2
+ import { settlement_batch } from "std/money_flows"
3
3
  party settlement_account: business
4
4
  party payout_destination: business
5
5
  settlement batch = settlement_batch {
@@ -1,5 +1,5 @@
1
1
  program swap_example "Swap example"
2
- import { swap } from "std/settlements"
2
+ import { swap } from "std/money_flows"
3
3
  party buyer: business
4
4
  party seller: business
5
5
  settlement exchange = swap {
@@ -160,7 +160,7 @@
160
160
  "summary": "Create a exchange atomic trade"
161
161
  },
162
162
  "dispute": {
163
- "agentDescription": "Claw back a released trade inside its dispute window. Both cross-payment reservations void and both principals return from escrow in one batch. The trade must be released and the clawback moment must not have passed. Either trading party may call it.",
163
+ "agentDescription": "Claw back a released trade inside its dispute window. Both cross-payment reservations void and both principals return from escrow in one batch. The trade must be released and the clawback moment must not have passed. The dispute port's declared parties may call it.",
164
164
  "deadline": {
165
165
  "field": "clawbackAt"
166
166
  },
@@ -515,6 +515,7 @@
515
515
  }
516
516
  ],
517
517
  "publicAction": "fundExchange",
518
+ "sandboxFailurePoint": "funding",
518
519
  "steps": [],
519
520
  "summary": "Fund both trade sides and collect on-top fees atomically"
520
521
  },
@@ -566,7 +567,7 @@
566
567
  "summary": "Post both trade reservations when the clawback window matures"
567
568
  },
568
569
  "release": {
569
- "agentDescription": "Reserve each side's principal for the other side and start the dispute window. The trade must be funded. Money is reserved, not settled. It posts on its own when the window matures, and dispute unwinds it before then. Either trading party may call it.",
570
+ "agentDescription": "Reserve each side's principal for the other side and start the dispute window. The trade must be funded. Money is reserved, not settled. It posts on its own when the window matures, and dispute unwinds it before then. The release port's declared parties may call it.",
570
571
  "effects": {
571
572
  "decides": [
572
573
  {
@@ -694,6 +695,7 @@
694
695
  ]
695
696
  },
696
697
  "publicAction": "releaseExchange",
698
+ "sandboxFailurePoint": "release",
697
699
  "setsAt": {
698
700
  "field": "clawbackAt",
699
701
  "offset": "P7D"
@@ -744,12 +746,14 @@
744
746
  "buyerAmount": {
745
747
  "description": "Side A amount in SAR minor units, held against the whole trade",
746
748
  "pattern": "^[1-9][0-9]{0,17}$",
747
- "type": "string"
749
+ "type": "string",
750
+ "x-hyperscale-currency": "SAR"
748
751
  },
749
752
  "buyerFee": {
750
753
  "description": "Immutable exact buyer service fee in SAR minor units",
751
754
  "pattern": "^[1-9][0-9]{0,17}$",
752
- "type": "string"
755
+ "type": "string",
756
+ "x-hyperscale-currency": "SAR"
753
757
  },
754
758
  "clawbackAt": {
755
759
  "description": "Machine-owned end of the P7D whole-trade dispute window",
@@ -790,12 +794,14 @@
790
794
  "sellerAmount": {
791
795
  "description": "Side B amount in SAR minor units, held against the whole trade",
792
796
  "pattern": "^[1-9][0-9]{0,17}$",
793
- "type": "string"
797
+ "type": "string",
798
+ "x-hyperscale-currency": "SAR"
794
799
  },
795
800
  "sellerFee": {
796
801
  "description": "Immutable exact seller service fee in SAR minor units",
797
802
  "pattern": "^[1-9][0-9]{0,17}$",
798
- "type": "string"
803
+ "type": "string",
804
+ "x-hyperscale-currency": "SAR"
799
805
  }
800
806
  },
801
807
  "id": "exchange",
@@ -1,5 +1,5 @@
1
1
  program capital_pool_example "Capital pool example"
2
- import { threshold_pool } from "std/settlements"
2
+ import { threshold_pool } from "std/money_flows"
3
3
  party contributor: person
4
4
  party company: business
5
5
  settlement round = threshold_pool {
@@ -173,7 +173,8 @@
173
173
  "targetAmount": {
174
174
  "description": "Funding target in SAR minor units",
175
175
  "pattern": "^[1-9][0-9]{0,17}$",
176
- "type": "string"
176
+ "type": "string",
177
+ "x-hyperscale-currency": "SAR"
177
178
  }
178
179
  },
179
180
  "id": "round",
@@ -576,7 +577,8 @@
576
577
  "amount": {
577
578
  "description": "One whole commitment amount",
578
579
  "pattern": "^[1-9][0-9]{0,17}$",
579
- "type": "string"
580
+ "type": "string",
581
+ "x-hyperscale-currency": "SAR"
580
582
  },
581
583
  "companyAccountId": {
582
584
  "description": "The company account",
@@ -1,5 +1,5 @@
1
1
  program weighted_distribution_example "Weighted distribution example"
2
- import { weighted_distribution } from "std/settlements"
2
+ import { weighted_distribution } from "std/money_flows"
3
3
  party distribution_source: business
4
4
  party recipient: business
5
5
  settlement proceeds = weighted_distribution {
@@ -77,7 +77,8 @@
77
77
  "distributableAmount": {
78
78
  "description": "Distribution pool in SAR minor units",
79
79
  "pattern": "^[1-9][0-9]{0,17}$",
80
- "type": "string"
80
+ "type": "string",
81
+ "x-hyperscale-currency": "SAR"
81
82
  },
82
83
  "distributionSourceAccountId": {
83
84
  "description": "The distribution source account",
@@ -278,7 +279,8 @@
278
279
  "entitlementWeight": {
279
280
  "description": "Stored non-negative entitlement weight",
280
281
  "pattern": "^[1-9][0-9]{0,17}$",
281
- "type": "string"
282
+ "type": "string",
283
+ "x-hyperscale-currency": "SAR"
282
284
  },
283
285
  "proceedsId": {
284
286
  "description": "The exact proceeds",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hyperscale0/hsx",
3
- "version": "1.0.0-rc.1",
3
+ "version": "2.0.0",
4
4
  "description": "The strictly typed HSX language: compile total financial programs into canonical UDL.",
5
5
  "keywords": [
6
6
  "hsx",
@@ -40,6 +40,10 @@
40
40
  "types": "./dist/src/cost.d.ts",
41
41
  "default": "./dist/src/cost.js"
42
42
  },
43
+ "./lsp": {
44
+ "types": "./dist/src/lsp/server.d.ts",
45
+ "default": "./dist/src/lsp/server.js"
46
+ },
43
47
  "./package.json": "./package.json",
44
48
  "./std/*": "./std/*"
45
49
  },
@@ -67,25 +71,30 @@
67
71
  },
68
72
  "scripts": {
69
73
  "build": "tsc -p tsconfig.build.json",
70
- "check": "bun test && bun run docs:check && tsc -p tsconfig.json && bun run build && bun scripts/check-bin.ts",
74
+ "check": "bun test && bun run docs:check && bun run std:check && bun run playground:check && tsc -p tsconfig.json && bun run build && bun scripts/check-bin.ts",
71
75
  "docs:build": "bun scripts/docs/build.ts",
72
76
  "docs:check": "bun scripts/docs/check.ts",
73
77
  "examples:build": "bun scripts/examples/build.ts",
78
+ "playground:build": "bun scripts/build-playground.ts",
79
+ "playground:check": "bun scripts/build-playground.ts --check",
74
80
  "postpack": "bun scripts/pack-exports.ts restore",
75
81
  "prepack": "bun run build && bun scripts/pack-exports.ts apply",
82
+ "std:bundle": "bun scripts/bundle-std.ts",
83
+ "std:check": "bun scripts/bundle-std.ts --check",
76
84
  "test": "bun test",
77
85
  "typecheck": "tsc -p tsconfig.json"
78
86
  },
79
87
  "dependencies": {
80
- "@hyperscale0/udl": "1.0.0-rc.1"
88
+ "@hyperscale0/udl": "2.0.0"
81
89
  },
82
90
  "devDependencies": {
83
- "@types/bun": "1.4.0",
84
- "typescript": "6.0.3"
91
+ "bun-types": "1.4.2",
92
+ "typescript": "7.0.2"
85
93
  },
86
94
  "contributors": [
87
95
  "Meshael AlBakaawi",
88
96
  "Amir Ayub",
89
97
  "Sara AlBakaawi"
90
- ]
98
+ ],
99
+ "gitHead": "e557d602bb119778f75346179eef480b6e3deb8a"
91
100
  }
@@ -5,15 +5,15 @@ description: Write, review, and repair HSX programs that compile financial-produ
5
5
 
6
6
  # Write HSX
7
7
 
8
- Use this skill when a task creates or changes an `.hsx` program, chooses a standard-library settlement form, explains an HSX diagnostic, or reviews authored money rules. Do not use it to hand-edit canonical UDL or runtime state.
8
+ Use this skill when a task creates or changes an `.hsx` program, chooses a money flow from the money flows library (open/hsx/std), explains an HSX diagnostic, or reviews authored money rules. Do not use it to hand-edit canonical UDL or runtime state.
9
9
 
10
10
  ## Program shape
11
11
 
12
- One file declares one `program`. Declare parties and assets before using them. Import standard-library instruments from `std/settlements`. Apply each selected instrument as a `settlement`, and declare every decision port it names. A program may also declare general instruments and subjects.
12
+ One file declares one `program`. Declare parties and assets before using them. Import money flows from `std/money_flows`. Apply each selected instrument as a `settlement`, and declare every decision port it names. A program may also declare general instruments and subjects.
13
13
 
14
- Start with [the first-program guide](https://github.com/hyperscale0/hyperscale-hsx/blob/main/docs/guide/01-first-program.md). Read the generated [grammar](https://github.com/hyperscale0/hyperscale-hsx/blob/main/docs/reference/grammar.md), [types](https://github.com/hyperscale0/hyperscale-hsx/blob/main/docs/reference/types.md), and [standard-library pages](https://github.com/hyperscale0/hyperscale-hsx/tree/main/docs/reference/std) for the exact surface.
14
+ Start with [the first-program guide](https://github.com/hyperscale0/hyperscale-hsx/blob/main/docs/guide/01-first-program.md). Read the generated [grammar](https://github.com/hyperscale0/hyperscale-hsx/blob/main/docs/reference/grammar.md), [types](https://github.com/hyperscale0/hyperscale-hsx/blob/main/docs/reference/types.md), and [money flows reference](https://github.com/hyperscale0/hyperscale-hsx/tree/main/docs/reference/std) for the exact surface.
15
15
 
16
- ## Choose a standard instrument
16
+ ## Choose a money flow
17
17
 
18
18
  Choose the module whose lifecycle and money path already match the product. Do not copy its emitted mechanics into a custom instrument.
19
19
 
@@ -35,7 +35,7 @@ Choose the module whose lifecycle and money path already match the product. Do n
35
35
  - `settlement_batch` closes, calculates, approves, instructs, acknowledges, and reconciles a batch.
36
36
  - `swap` exchanges two independently typed sides.
37
37
 
38
- The standard library forms are demonstrated below. The marker before each program lets the repository test read the module list from disk and compile one matching example per module.
38
+ The money flows are demonstrated below. The marker before each program lets the repository test read the module list from disk and compile one matching example per module.
39
39
 
40
40
  ## Diagnostic loop
41
41
 
@@ -54,13 +54,13 @@ Run `hsx check` after each coherent edit. Read the first error code, open the [d
54
54
 
55
55
  The [money](https://github.com/hyperscale0/hyperscale-hsx/blob/main/docs/guide/02-money.md), [fees and splits](https://github.com/hyperscale0/hyperscale-hsx/blob/main/docs/guide/05-fees-and-splits.md), [schedules](https://github.com/hyperscale0/hyperscale-hsx/blob/main/docs/guide/06-schedules.md), and [cost](https://github.com/hyperscale0/hyperscale-hsx/blob/main/docs/guide/09-cost.md) chapters explain these rules.
56
56
 
57
- ## Standard-library witnesses
57
+ ## Money flow witnesses
58
58
 
59
59
  <!-- hsx-brick: advance -->
60
60
 
61
61
  ```hsx
62
62
  program advance_example "Advance example"
63
- import { advance } from "std/settlements"
63
+ import { advance } from "std/money_flows"
64
64
  party funder: business
65
65
  party recipient: business
66
66
  settlement advance_payment = advance {
@@ -78,7 +78,7 @@ settlement advance_payment = advance {
78
78
 
79
79
  ```hsx
80
80
  program cancellable_booking_example "Cancellable booking example"
81
- import { cancellable_booking } from "std/settlements"
81
+ import { cancellable_booking } from "std/money_flows"
82
82
  party guest: person
83
83
  party studio: business
84
84
  settlement studio_session = cancellable_booking {
@@ -97,7 +97,7 @@ settlement studio_session = cancellable_booking {
97
97
 
98
98
  ```hsx
99
99
  program captured_payment_example "Captured payment example"
100
- import { captured_payment } from "std/settlements"
100
+ import { captured_payment } from "std/money_flows"
101
101
  party payer: person
102
102
  party payee: business
103
103
  settlement card_payment = captured_payment {
@@ -123,7 +123,7 @@ port reverse_capture {
123
123
 
124
124
  ```hsx
125
125
  program conditional_disbursement_example "Conditional disbursement example"
126
- import { conditional_disbursement } from "std/settlements"
126
+ import { conditional_disbursement } from "std/money_flows"
127
127
  party source: business
128
128
  party claimant: person
129
129
  settlement claim_payment = conditional_disbursement {
@@ -145,7 +145,7 @@ port approve_claim {
145
145
 
146
146
  ```hsx
147
147
  program credit_facility_example "Credit facility example"
148
- import { credit_facility, scheduled } from "std/settlements"
148
+ import { credit_facility, scheduled } from "std/money_flows"
149
149
  party lender: business
150
150
  party borrower: business
151
151
  party draw_destination: business
@@ -177,7 +177,7 @@ settlement facility = credit_facility {
177
177
 
178
178
  ```hsx
179
179
  program deposit_example "Deposit example"
180
- import { security_deposit } from "std/settlements"
180
+ import { security_deposit } from "std/money_flows"
181
181
  party renter: person
182
182
  party owner: business
183
183
  settlement security_deposit = security_deposit {
@@ -203,7 +203,7 @@ port return_deposit { allowed: [owner] }
203
203
 
204
204
  ```hsx
205
205
  program capital_pool_example "Capital pool example"
206
- import { threshold_pool } from "std/settlements"
206
+ import { threshold_pool } from "std/money_flows"
207
207
  party contributor: person
208
208
  party company: business
209
209
  settlement round = threshold_pool {
@@ -224,7 +224,7 @@ settlement round = threshold_pool {
224
224
 
225
225
  ```hsx
226
226
  program held_payment_example "Held payment example"
227
- import { held_payment } from "std/settlements"
227
+ import { held_payment } from "std/money_flows"
228
228
  party buyer: person
229
229
  party seller: business
230
230
  settlement sale = held_payment {
@@ -242,7 +242,7 @@ port confirm_delivery { allowed: [buyer] }
242
242
 
243
243
  ```hsx
244
244
  program instant_transfer_example "Instant transfer example"
245
- import { instant_transfer } from "std/settlements"
245
+ import { instant_transfer } from "std/money_flows"
246
246
  party customer: person
247
247
  party merchant: business
248
248
  settlement transfer = instant_transfer {
@@ -263,7 +263,7 @@ settlement transfer = instant_transfer {
263
263
 
264
264
  ```hsx
265
265
  program metered_example "Metered example"
266
- import { metered } from "std/settlements"
266
+ import { metered } from "std/money_flows"
267
267
  party customer: business
268
268
  party provider: business
269
269
  settlement usage = metered {
@@ -281,7 +281,7 @@ settlement usage = metered {
281
281
 
282
282
  ```hsx
283
283
  program pooled_split_example "Pooled split example"
284
- import { pooled_split } from "std/settlements"
284
+ import { pooled_split } from "std/money_flows"
285
285
  party payer: business
286
286
  party first_recipient: business
287
287
  party second_recipient: business
@@ -301,7 +301,7 @@ settlement pool = pooled_split {
301
301
 
302
302
  ```hsx
303
303
  program premium_forward_example "Premium forward example"
304
- import { premium_forward } from "std/settlements"
304
+ import { premium_forward } from "std/money_flows"
305
305
  party policyholder: person
306
306
  party carrier: business
307
307
  settlement premium = premium_forward {
@@ -325,7 +325,7 @@ port record_endorsement {
325
325
 
326
326
  ```hsx
327
327
  program reconciled_payout_example "Reconciled payout example"
328
- import { reconciled_payout } from "std/settlements"
328
+ import { reconciled_payout } from "std/money_flows"
329
329
  party treasury: business
330
330
  party supplier: business
331
331
  settlement supplier_payout = reconciled_payout {
@@ -343,7 +343,7 @@ settlement supplier_payout = reconciled_payout {
343
343
 
344
344
  ```hsx
345
345
  program recurring_collection_example "Recurring collection example"
346
- import { recurring_collection, scheduled } from "std/settlements"
346
+ import { recurring_collection, scheduled } from "std/money_flows"
347
347
  party debtor: person
348
348
  party repayment_source: business
349
349
  party recipient: business
@@ -369,7 +369,7 @@ port mandate_evidence {
369
369
 
370
370
  ```hsx
371
371
  program rotating_pool_example "Rotating pool example"
372
- import { rotating_pool } from "std/settlements"
372
+ import { rotating_pool } from "std/money_flows"
373
373
  party member_a: person
374
374
  party member_b: person
375
375
  party member_c: person
@@ -392,7 +392,7 @@ settlement pool = rotating_pool {
392
392
 
393
393
  ```hsx
394
394
  program scheduled_example "Scheduled example"
395
- import { scheduled } from "std/settlements"
395
+ import { scheduled } from "std/money_flows"
396
396
  party payer: business
397
397
  party payee: business
398
398
  settlement installments = scheduled {
@@ -409,7 +409,7 @@ settlement installments = scheduled {
409
409
 
410
410
  ```hsx
411
411
  program settlement_batch_example "Settlement batch example"
412
- import { settlement_batch } from "std/settlements"
412
+ import { settlement_batch } from "std/money_flows"
413
413
  party settlement_account: business
414
414
  party payout_destination: business
415
415
  settlement batch = settlement_batch {
@@ -433,7 +433,7 @@ port acknowledge_payout {
433
433
 
434
434
  ```hsx
435
435
  program swap_example "Swap example"
436
- import { swap } from "std/settlements"
436
+ import { swap } from "std/money_flows"
437
437
  party buyer: business
438
438
  party seller: business
439
439
  settlement exchange = swap {
@@ -457,7 +457,7 @@ port dispute_exchange { allowed: [buyer, seller] }
457
457
 
458
458
  ```hsx
459
459
  program weighted_distribution_example "Weighted distribution example"
460
- import { weighted_distribution } from "std/settlements"
460
+ import { weighted_distribution } from "std/money_flows"
461
461
  party distribution_source: business
462
462
  party recipient: business
463
463
  settlement proceeds = weighted_distribution {
@@ -480,4 +480,4 @@ port snapshot_entitlements {
480
480
 
481
481
  ## Output boundary
482
482
 
483
- Use `compile` or the CLI to obtain canonical UDL, the Business Frame, the origin map, and the cost manifest. The engine reads UDL and never HSX. When a task needs direct UDL work, use the UDL skill instead.
483
+ Use `compile` or the Hyperscale CLI to obtain canonical UDL, the origin map, and the cost manifest. The engine reads UDL and never HSX. When a task needs direct UDL work, use the UDL skill instead.
package/src/ast.ts CHANGED
@@ -35,6 +35,36 @@ export function lineColAt(source: string, offset: number): LineCol {
35
35
  return { column: clamped - lineStart + 1, line };
36
36
  }
37
37
 
38
+ const utf8Encoder = new TextEncoder();
39
+
40
+ /**
41
+ * Convert a UTF-8 byte offset to a UTF-16 code-unit offset over a string.
42
+ * Walks Unicode code points, counting UTF-8 bytes and UTF-16 code units.
43
+ * Clamps to [0, source.length].
44
+ */
45
+ export function byteOffsetToCodeUnit(
46
+ source: string,
47
+ byteOffset: number,
48
+ ): number {
49
+ if (byteOffset <= 0) return 0;
50
+ let currentByte = 0;
51
+ let codeUnit = 0;
52
+
53
+ for (const char of source) {
54
+ const charBytes = utf8Encoder.encode(char).length;
55
+ if (currentByte + charBytes > byteOffset) {
56
+ return codeUnit;
57
+ }
58
+ currentByte += charBytes;
59
+ codeUnit += char.length;
60
+ if (currentByte === byteOffset) {
61
+ return codeUnit;
62
+ }
63
+ }
64
+
65
+ return source.length;
66
+ }
67
+
38
68
  /**
39
69
  * One source scanned once, so many offsets resolve without rescanning it.
40
70
  * `lineColAt` walks from offset zero every time, which turns a run of d
@@ -238,6 +268,8 @@ export type Expr =
238
268
  * and `on_cancel(funded) { ... }` (key + qualifiers + block value).
239
269
  */
240
270
  export interface Entry {
271
+ /** Port dependencies retained through compile-time selection and substitution. */
272
+ readonly conditionPorts?: readonly string[];
241
273
  /** `for item in bound { ... }`, expanded before binding or UDL lowering. */
242
274
  readonly iteration?: {
243
275
  readonly binding: IdentExpr;
@@ -275,7 +307,7 @@ export interface ExposeDecl {
275
307
  readonly span: Span;
276
308
  }
277
309
 
278
- /** `import { held_payment } from "std/settlements"`. */
310
+ /** `import { held_payment } from "std/money_flows"`. */
279
311
  export interface ImportDecl {
280
312
  readonly from: StringExpr;
281
313
  readonly kind: "import";
@@ -317,7 +349,7 @@ export interface PortDecl {
317
349
  readonly span: Span;
318
350
  }
319
351
 
320
- /** `module std.settlements` gives a file its importable module name. */
352
+ /** `module std.money_flows` gives a file its importable module name. */
321
353
  export interface ModuleDecl {
322
354
  readonly kind: "module";
323
355
  readonly name: PathExpr;
package/src/cli.ts CHANGED
@@ -12,9 +12,10 @@
12
12
 
13
13
  import { fileURLToPath } from "node:url";
14
14
  import { compile, type CompileResult } from "./compile.ts";
15
- import type { UdlCostManifest, UdlCostTable } from "./cost.ts";
15
+ import type { UdlCostManifest, UdlCostTables } from "./cost.ts";
16
16
  import { hsxDiagnostics } from "./diagnostics.ts";
17
17
  import { format } from "./format.ts";
18
+ import { startLspServer } from "./lsp/server.ts";
18
19
  import { HSX_TARGET_UDL_VERSION, HSX_VERSION } from "./version.ts";
19
20
 
20
21
  /** Filesystem and streams, injected so the CLI stays testable. */
@@ -23,6 +24,8 @@ export interface Io {
23
24
  readonly out: (line: string) => void;
24
25
  readonly readFile: (path: string) => Promise<string>;
25
26
  readonly writeFile: (path: string, contents: string) => Promise<void>;
27
+ readonly stdin?: NodeJS.ReadableStream;
28
+ readonly stdout?: NodeJS.WritableStream;
26
29
  }
27
30
 
28
31
  /**
@@ -41,15 +44,17 @@ Usage:
41
44
  hsx cost <file.hsx> [--json] [--out <file.json>] [--strict]
42
45
  hsx explain <HSX####>
43
46
  hsx format <file.hsx>
47
+ hsx lsp
44
48
  hsx --version
45
49
  hsx --help
46
50
 
47
51
  Commands:
48
52
  check Compile and report diagnostics. Prints nothing when the program is clean.
49
- build Compile and write canonical UDL and its Business Frame as JSON.
53
+ build Compile and write canonical UDL as JSON.
50
54
  cost Compile and print the version-pinned cost manifest as a table or JSON.
51
55
  explain Print one diagnostic title, fix, and source example.
52
56
  format Print the source in the one canonical HSX style.
57
+ lsp Run the language server over stdin and stdout.
53
58
 
54
59
  Options:
55
60
  --json Print the cost manifest as JSON instead of a table.
@@ -73,6 +78,15 @@ export async function runCli(argv: readonly string[], io: Io): Promise<number> {
73
78
  return OK;
74
79
  }
75
80
  if (command === "explain") return explainDiagnostic(rest, io);
81
+ if (command === "lsp") {
82
+ const input = io.stdin ?? process.stdin;
83
+ const output = io.stdout ?? process.stdout;
84
+ return new Promise<number>((resolve) => {
85
+ startLspServer(input, output, {
86
+ onExit: resolve,
87
+ });
88
+ });
89
+ }
76
90
  if (
77
91
  command !== "check" &&
78
92
  command !== "build" &&
@@ -110,7 +124,7 @@ export async function runCli(argv: readonly string[], io: Io): Promise<number> {
110
124
  return OK;
111
125
  }
112
126
 
113
- let costTable: UdlCostTable;
127
+ let costTable: UdlCostTables;
114
128
  try {
115
129
  costTable = await readDefaultCostTable(io);
116
130
  } catch (cause) {
@@ -142,14 +156,7 @@ export async function runCli(argv: readonly string[], io: Io): Promise<number> {
142
156
  );
143
157
  return refused ? REFUSED : OK;
144
158
  }
145
- const json = `${JSON.stringify(
146
- {
147
- document: result.artifacts.document,
148
- frame: result.artifacts.frame,
149
- },
150
- null,
151
- 2,
152
- )}\n`;
159
+ const json = `${JSON.stringify(result.artifacts.document, null, 2)}\n`;
153
160
  if (parsed.out === undefined) {
154
161
  io.out(json.trimEnd());
155
162
  } else {
@@ -293,7 +300,7 @@ async function writeOutput(
293
300
  return OK;
294
301
  }
295
302
 
296
- async function readDefaultCostTable(io: Io): Promise<UdlCostTable> {
303
+ async function readDefaultCostTable(io: Io): Promise<UdlCostTables> {
297
304
  const candidates = [
298
305
  fileURLToPath(new URL("../examples/cost-table.json", import.meta.url)),
299
306
  fileURLToPath(new URL("../../examples/cost-table.json", import.meta.url)),
@@ -301,7 +308,7 @@ async function readDefaultCostTable(io: Io): Promise<UdlCostTable> {
301
308
  let lastError: unknown;
302
309
  for (const path of candidates) {
303
310
  try {
304
- return JSON.parse(await io.readFile(path)) as UdlCostTable;
311
+ return JSON.parse(await io.readFile(path)) as UdlCostTables;
305
312
  } catch (cause) {
306
313
  lastError = cause;
307
314
  }
@@ -323,3 +330,15 @@ function diagnosticLines(
323
330
  function messageOf(cause: unknown): string {
324
331
  return cause instanceof Error ? cause.message : String(cause);
325
332
  }
333
+
334
+ if (import.meta.main) {
335
+ const { readFile, writeFile } = await import("node:fs/promises");
336
+ process.exitCode = await runCli(process.argv.slice(2), {
337
+ err: (line) => process.stderr.write(`${line}\n`),
338
+ out: (line) => process.stdout.write(`${line}\n`),
339
+ readFile: (path) => readFile(path, "utf8"),
340
+ writeFile: (path, contents) => writeFile(path, contents, "utf8"),
341
+ stdin: process.stdin,
342
+ stdout: process.stdout,
343
+ });
344
+ }