@greenpandastudios/aug-cli 0.19.0 → 0.21.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 (628) hide show
  1. package/README.md +9 -6
  2. package/THIRD_PARTY_NOTICES.md +4 -0
  3. package/bin/aug.mjs +12 -2
  4. package/docs/about.md +27 -0
  5. package/docs/api/crypto.md +103 -69
  6. package/docs/api/io.md +35 -33
  7. package/docs/api/json.md +3 -3
  8. package/docs/api/memory.md +23 -19
  9. package/docs/api/time.md +10 -9
  10. package/docs/api/web.md +33 -38
  11. package/docs/assets/benchmarks/execution.svg +774 -637
  12. package/docs/assets/benchmarks/http.svg +278 -249
  13. package/docs/assets/benchmarks/improvements.svg +66 -66
  14. package/docs/assets/benchmarks/kernels-mobile.svg +1 -0
  15. package/docs/assets/benchmarks/kernels.svg +1 -0
  16. package/docs/assets/benchmarks/memory.svg +153 -153
  17. package/docs/benchmark-results.json +227089 -90363
  18. package/docs/compatibility.md +8 -8
  19. package/docs/contributing-benchmarks.md +68 -0
  20. package/docs/dev-containers.md +88 -0
  21. package/docs/dgx-consumers.json +122 -0
  22. package/docs/dgx-gyms.json +784 -0
  23. package/docs/dgx-kernels.json +1170 -0
  24. package/docs/dgx-performance.json +227849 -0
  25. package/docs/dgx-spark.md +64 -0
  26. package/docs/diagnostics.md +15 -5
  27. package/docs/docker.md +173 -12
  28. package/docs/editor.md +35 -0
  29. package/docs/example-projects.json +238 -24
  30. package/docs/examples/approved-design/counters.md +34 -126
  31. package/docs/examples/approved-design/dependencies/august/0.21.0/io/contracts.md +178 -0
  32. package/docs/examples/approved-design/domain/app.md +13 -77
  33. package/docs/examples/approved-design/domain/export.md +5 -19
  34. package/docs/examples/approved-design/domain/models.md +4 -23
  35. package/docs/examples/approved-design/domain/numbers.md +24 -114
  36. package/docs/examples/approved-design/index.md +16 -7
  37. package/docs/examples/approved-design/main.md +19 -96
  38. package/docs/examples/benchmark/index.md +6 -5
  39. package/docs/examples/benchmark/main.md +7 -35
  40. package/docs/examples/calls-benchmark/index.md +36 -0
  41. package/docs/examples/calls-benchmark/main.md +78 -0
  42. package/docs/examples/calls-benchmark/operations.md +60 -0
  43. package/docs/examples/cli-args/index.md +6 -5
  44. package/docs/examples/cli-args/main.md +6 -31
  45. package/docs/examples/collections/index.md +6 -5
  46. package/docs/examples/collections/main.md +7 -35
  47. package/docs/examples/collections-benchmark/index.md +6 -5
  48. package/docs/examples/collections-benchmark/main.md +7 -35
  49. package/docs/examples/cpu-benchmark/index.md +6 -5
  50. package/docs/examples/cpu-benchmark/main.md +5 -24
  51. package/docs/examples/developer-workflow/calculator.md +39 -186
  52. package/docs/examples/developer-workflow/dependencies/august/0.21.0/io/contracts.md +178 -0
  53. package/docs/examples/developer-workflow/index.md +16 -7
  54. package/docs/examples/developer-workflow/logging/console.md +10 -56
  55. package/docs/examples/developer-workflow/logging/export.md +4 -14
  56. package/docs/examples/developer-workflow/logging/logger.md +7 -43
  57. package/docs/examples/developer-workflow/main.md +17 -69
  58. package/docs/examples/drop/index.md +6 -5
  59. package/docs/examples/drop/main.md +7 -27
  60. package/docs/examples/drop/resource.md +7 -30
  61. package/docs/examples/errors/errors.md +7 -27
  62. package/docs/examples/errors/index.md +6 -5
  63. package/docs/examples/errors/main.md +7 -28
  64. package/docs/examples/errors-benchmark/index.md +36 -0
  65. package/docs/examples/errors-benchmark/main.md +92 -0
  66. package/docs/examples/errors-benchmark/operations.md +65 -0
  67. package/docs/examples/ffi/index.md +6 -5
  68. package/docs/examples/ffi/main.md +6 -20
  69. package/docs/examples/ffi/native.md +8 -34
  70. package/docs/examples/float-benchmark/index.md +35 -0
  71. package/docs/examples/float-benchmark/main.md +75 -0
  72. package/docs/examples/generic-di/dependencies/august/0.21.0/io/contracts.md +178 -0
  73. package/docs/examples/generic-di/index.md +6 -5
  74. package/docs/examples/generic-di/main.md +9 -39
  75. package/docs/examples/generic-di/types.md +23 -92
  76. package/docs/examples/generics/index.md +6 -5
  77. package/docs/examples/generics/main.md +10 -47
  78. package/docs/examples/generics/types.md +25 -100
  79. package/docs/examples/hello/app/export.md +4 -12
  80. package/docs/examples/hello/app/greeter.md +13 -91
  81. package/docs/examples/hello/dependencies/august/0.21.0/io/contracts.md +178 -0
  82. package/docs/examples/hello/index.md +17 -6
  83. package/docs/examples/hello/logging/console.md +10 -54
  84. package/docs/examples/hello/logging/export.md +4 -14
  85. package/docs/examples/hello/logging/logger.md +7 -45
  86. package/docs/examples/hello/main.md +9 -39
  87. package/docs/examples/http-benchmark/index.md +6 -5
  88. package/docs/examples/http-benchmark/main.md +6 -20
  89. package/docs/examples/http-benchmark/routes.md +9 -31
  90. package/docs/examples/index.md +63 -29
  91. package/docs/examples/interceptors/app.md +20 -139
  92. package/docs/examples/interceptors/dependencies/august/0.21.0/io/contracts.md +178 -0
  93. package/docs/examples/interceptors/index.md +6 -5
  94. package/docs/examples/interceptors/interceptors.md +24 -148
  95. package/docs/examples/interceptors/logging.md +13 -76
  96. package/docs/examples/interceptors/main.md +10 -65
  97. package/docs/examples/json-benchmark/data.md +4 -20
  98. package/docs/examples/json-benchmark/dependencies/packages/@git/url_2d3c37c690c0fa115be1/0.0.0-git.a39fc582565d4fca40be4f75fa304d71adc69301/contracts.md +67 -0
  99. package/docs/examples/json-benchmark/index.md +7 -5
  100. package/docs/examples/json-benchmark/main-yaml.md +20 -0
  101. package/docs/examples/json-benchmark/main.md +10 -49
  102. package/docs/examples/list-benchmark/index.md +35 -0
  103. package/docs/examples/list-benchmark/main.md +78 -0
  104. package/docs/examples/map-churn-benchmark/index.md +35 -0
  105. package/docs/examples/map-churn-benchmark/main.md +106 -0
  106. package/docs/examples/native-blake3/dependencies/packages/@greenpandastudios/aug-blake3/0.1.3/api.md +104 -0
  107. package/docs/examples/native-blake3/dependencies/packages/@greenpandastudios/aug-blake3/0.1.3/contracts.md +54 -0
  108. package/docs/examples/native-blake3/dependencies/packages/@greenpandastudios/aug-blake3/0.1.3/native.abi-json.md +48 -0
  109. package/docs/examples/native-blake3/hashing.md +93 -0
  110. package/docs/examples/native-blake3/index.md +38 -0
  111. package/docs/examples/native-blake3/main.md +73 -0
  112. package/docs/examples/native-pytorch/dependencies/packages/@greenpandastudios/aug-pytorch/0.1.4/api.md +406 -0
  113. package/docs/examples/native-pytorch/dependencies/packages/@greenpandastudios/aug-pytorch/0.1.4/bindings.md +51 -0
  114. package/docs/examples/native-pytorch/dependencies/packages/@greenpandastudios/aug-pytorch/0.1.4/contracts.md +63 -0
  115. package/docs/examples/native-pytorch/dependencies/packages/@greenpandastudios/aug-pytorch/0.1.4/native.abi-json.md +161 -0
  116. package/docs/examples/native-pytorch/index.md +38 -0
  117. package/docs/examples/native-pytorch/main.md +73 -0
  118. package/docs/examples/native-pytorch/tensors.md +123 -0
  119. package/docs/examples/native-sqlite/database.md +116 -0
  120. package/docs/examples/native-sqlite/dependencies/packages/@greenpandastudios/aug-sqlite/0.1.3/api.md +284 -0
  121. package/docs/examples/native-sqlite/dependencies/packages/@greenpandastudios/aug-sqlite/0.1.3/bindings.md +51 -0
  122. package/docs/examples/native-sqlite/dependencies/packages/@greenpandastudios/aug-sqlite/0.1.3/contracts.md +75 -0
  123. package/docs/examples/native-sqlite/dependencies/packages/@greenpandastudios/aug-sqlite/0.1.3/native.abi-json.md +119 -0
  124. package/docs/examples/native-sqlite/index.md +38 -0
  125. package/docs/examples/native-sqlite/main.md +73 -0
  126. package/docs/examples/native-zlib/compression.md +99 -0
  127. package/docs/examples/native-zlib/dependencies/packages/@greenpandastudios/aug-zlib/0.1.3/api.md +153 -0
  128. package/docs/examples/native-zlib/dependencies/packages/@greenpandastudios/aug-zlib/0.1.3/contracts.md +54 -0
  129. package/docs/examples/native-zlib/dependencies/packages/@greenpandastudios/aug-zlib/0.1.3/native.abi-json.md +76 -0
  130. package/docs/examples/native-zlib/index.md +38 -0
  131. package/docs/examples/native-zlib/main.md +78 -0
  132. package/docs/examples/new-syntax/console.md +10 -52
  133. package/docs/examples/new-syntax/dependencies/august/0.21.0/io/contracts.md +178 -0
  134. package/docs/examples/new-syntax/greeter.md +13 -71
  135. package/docs/examples/new-syntax/index.md +6 -5
  136. package/docs/examples/new-syntax/logger.md +7 -43
  137. package/docs/examples/new-syntax/main.md +10 -53
  138. package/docs/examples/new-syntax/math.md +6 -24
  139. package/docs/examples/oidc-login/client/contracts.md +10 -61
  140. package/docs/examples/oidc-login/client/endpoints.md +32 -154
  141. package/docs/examples/oidc-login/client/export.md +5 -23
  142. package/docs/examples/oidc-login/client/login.md +234 -344
  143. package/docs/examples/oidc-login/client/logout.md +38 -143
  144. package/docs/examples/oidc-login/client/protocol.md +183 -304
  145. package/docs/examples/oidc-login/client/session.md +41 -149
  146. package/docs/examples/oidc-login/client/views.md +13 -58
  147. package/docs/examples/oidc-login/common/export.md +6 -26
  148. package/docs/examples/oidc-login/common/headers.md +42 -72
  149. package/docs/examples/oidc-login/common/keys.md +40 -164
  150. package/docs/examples/oidc-login/common/settings.md +24 -40
  151. package/docs/examples/oidc-login/common/views.md +7 -28
  152. package/docs/examples/oidc-login/dependencies/packages/@git/url_0eb7c89453c87681ed15/0.0.0-git.a39fc582565d4fca40be4f75fa304d71adc69301/store.md +205 -0
  153. package/docs/examples/oidc-login/dependencies/packages/@git/url_2d3c37c690c0fa115be1/0.0.0-git.a39fc582565d4fca40be4f75fa304d71adc69301/contracts.md +67 -0
  154. package/docs/examples/oidc-login/dependencies/packages/@git/url_897efafd565158fc4908/0.0.0-git.a39fc582565d4fca40be4f75fa304d71adc69301/contracts.md +267 -0
  155. package/docs/examples/oidc-login/dependencies/packages/@git/url_9ef654c66d34ab8f5527/0.0.0-git.b14a0f9aa41f1ce58bd51133bcdc424033e40d40/contracts.md +415 -0
  156. package/docs/examples/oidc-login/dependencies/packages/@git/url_9ef654c66d34ab8f5527/0.0.0-git.b14a0f9aa41f1ce58bd51133bcdc424033e40d40/jose.md +271 -0
  157. package/docs/examples/oidc-login/dependencies/packages/@git/url_c092cd151499c4e1d8a1/0.0.0-git.a39fc582565d4fca40be4f75fa304d71adc69301/contracts.md +89 -0
  158. package/docs/examples/oidc-login/index.md +8 -7
  159. package/docs/examples/oidc-login/main-yaml.md +7 -0
  160. package/docs/examples/oidc-login/main.md +26 -153
  161. package/docs/examples/oidc-login/provider/authorization.md +232 -275
  162. package/docs/examples/oidc-login/provider/contracts.md +24 -146
  163. package/docs/examples/oidc-login/provider/credentials.md +24 -57
  164. package/docs/examples/oidc-login/provider/discovery.md +48 -122
  165. package/docs/examples/oidc-login/provider/export.md +11 -37
  166. package/docs/examples/oidc-login/provider/token.md +159 -237
  167. package/docs/examples/oidc-login/provider/userinfo.md +47 -102
  168. package/docs/examples/oidc-login/provider/views.md +13 -53
  169. package/docs/examples/ownership/counter.md +17 -63
  170. package/docs/examples/ownership/index.md +6 -5
  171. package/docs/examples/ownership/main.md +7 -30
  172. package/docs/examples/ownership-transfer/dependencies/august/0.21.0/io/contracts.md +178 -0
  173. package/docs/examples/ownership-transfer/index.md +6 -5
  174. package/docs/examples/ownership-transfer/main.md +10 -52
  175. package/docs/examples/ownership-transfer/resource.md +15 -67
  176. package/docs/examples/packages-app/dependencies/packages/@example/aug-math/0.1.0/arithmetic.md +12 -50
  177. package/docs/examples/packages-app/index.md +7 -6
  178. package/docs/examples/packages-app/main.md +7 -25
  179. package/docs/examples/packages-math/aug-package-json.md +1 -1
  180. package/docs/examples/packages-math/index.md +7 -6
  181. package/docs/examples/packages-math/src/arithmetic.md +12 -50
  182. package/docs/examples/packages-math/src/export.md +4 -12
  183. package/docs/examples/records-benchmark/data.md +55 -0
  184. package/docs/examples/records-benchmark/index.md +36 -0
  185. package/docs/examples/records-benchmark/main.md +85 -0
  186. package/docs/examples/startup-benchmark/index.md +6 -5
  187. package/docs/examples/startup-benchmark/main.md +5 -17
  188. package/docs/examples/strings-benchmark/index.md +35 -0
  189. package/docs/examples/strings-benchmark/main.md +76 -0
  190. package/docs/examples/tasks-benchmark/index.md +36 -0
  191. package/docs/examples/tasks-benchmark/main.md +89 -0
  192. package/docs/examples/tasks-benchmark/operations.md +58 -0
  193. package/docs/examples/visibility/counter.md +19 -67
  194. package/docs/examples/visibility/index.md +6 -5
  195. package/docs/examples/visibility/main.md +7 -31
  196. package/docs/examples/weather-api/forecasts.md +168 -0
  197. package/docs/examples/weather-api/index.md +42 -0
  198. package/docs/examples/weather-api/main-yaml.md +21 -0
  199. package/docs/examples/weather-api/main.md +65 -0
  200. package/docs/examples.json +10 -0
  201. package/docs/getting-started.md +105 -2
  202. package/docs/grammar.md +7 -5
  203. package/docs/guides/change-a-module.md +64 -0
  204. package/docs/guides/index.md +27 -0
  205. package/docs/gym-results.json +784 -0
  206. package/docs/implementation-map.md +6 -0
  207. package/docs/index.md +51 -29
  208. package/docs/kernel-results.json +1170 -0
  209. package/docs/language-conformance.md +7 -1
  210. package/docs/language-constructs.md +30 -22
  211. package/docs/language-design-audit.md +1 -1
  212. package/docs/learn/data-and-errors.md +77 -0
  213. package/docs/learn/index.md +30 -0
  214. package/docs/learn/modules-and-dependencies.md +73 -0
  215. package/docs/learn/state-and-tests.md +71 -0
  216. package/docs/learn/values-and-functions.md +62 -0
  217. package/docs/lesson-failures.json +8 -0
  218. package/docs/maintaining-docs.md +16 -4
  219. package/docs/native-implementation.md +276 -0
  220. package/docs/native-interop-llvm-plan.md +342 -0
  221. package/docs/native-package-examples.md +684 -0
  222. package/docs/native-packages.md +179 -0
  223. package/docs/packages.md +72 -126
  224. package/docs/performance.md +61 -68
  225. package/docs/production-readiness.md +16 -5
  226. package/docs/public/downloads/approved-design.zip +0 -0
  227. package/docs/public/downloads/benchmark.zip +0 -0
  228. package/docs/public/downloads/calls-benchmark.zip +0 -0
  229. package/docs/public/downloads/cli-args.zip +0 -0
  230. package/docs/public/downloads/collections-benchmark.zip +0 -0
  231. package/docs/public/downloads/collections.zip +0 -0
  232. package/docs/public/downloads/cpu-benchmark.zip +0 -0
  233. package/docs/public/downloads/developer-workflow.zip +0 -0
  234. package/docs/public/downloads/drop.zip +0 -0
  235. package/docs/public/downloads/errors-benchmark.zip +0 -0
  236. package/docs/public/downloads/errors.zip +0 -0
  237. package/docs/public/downloads/ffi.zip +0 -0
  238. package/docs/public/downloads/float-benchmark.zip +0 -0
  239. package/docs/public/downloads/generic-di.zip +0 -0
  240. package/docs/public/downloads/generics.zip +0 -0
  241. package/docs/public/downloads/hello.zip +0 -0
  242. package/docs/public/downloads/http-benchmark.zip +0 -0
  243. package/docs/public/downloads/interceptors.zip +0 -0
  244. package/docs/public/downloads/json-benchmark.zip +0 -0
  245. package/docs/public/downloads/list-benchmark.zip +0 -0
  246. package/docs/public/downloads/map-churn-benchmark.zip +0 -0
  247. package/docs/public/downloads/native-blake3.zip +0 -0
  248. package/docs/public/downloads/native-pytorch.zip +0 -0
  249. package/docs/public/downloads/native-sqlite.zip +0 -0
  250. package/docs/public/downloads/native-zlib.zip +0 -0
  251. package/docs/public/downloads/new-syntax.zip +0 -0
  252. package/docs/public/downloads/oidc-login.zip +0 -0
  253. package/docs/public/downloads/ownership-transfer.zip +0 -0
  254. package/docs/public/downloads/ownership.zip +0 -0
  255. package/docs/public/downloads/packages-app.zip +0 -0
  256. package/docs/public/downloads/packages-math.zip +0 -0
  257. package/docs/public/downloads/records-benchmark.zip +0 -0
  258. package/docs/public/downloads/startup-benchmark.zip +0 -0
  259. package/docs/public/downloads/strings-benchmark.zip +0 -0
  260. package/docs/public/downloads/tasks-benchmark.zip +0 -0
  261. package/docs/public/downloads/visibility.zip +0 -0
  262. package/docs/public/downloads/weather-api.zip +0 -0
  263. package/docs/qualification-results.md +66 -0
  264. package/docs/reference.md +47 -17
  265. package/docs/releasing.md +105 -16
  266. package/docs/research/code-to-natural-language.md +108 -0
  267. package/docs/research/ecosystem-workflow.md +41 -0
  268. package/docs/research/libtorch-native-qualification.md +115 -0
  269. package/docs/research/native-interop-llvm.md +197 -0
  270. package/docs/research/qualification-methods.md +15 -0
  271. package/docs/research/wiki-editorial-design.md +71 -0
  272. package/docs/roadmap.md +2 -1
  273. package/docs/safety-gyms.md +41 -0
  274. package/docs/specifications.md +27 -11
  275. package/docs/testing.md +19 -5
  276. package/docs/tooling.md +36 -22
  277. package/docs/weather-api.md +65 -0
  278. package/docs/web-library-gaps.md +1 -1
  279. package/docs/web.md +54 -18
  280. package/docs/writing-docs.md +49 -0
  281. package/examples/{hello/.aug-spec/august/0.19.0 → approved-design/.aug-spec/august/0.21.0}/io/contracts.aug +4 -3
  282. package/examples/approved-design/.aug-spec/august/0.21.0/io/contracts.aug.md +82 -0
  283. package/examples/approved-design/.aug-spec/manifest.json +3 -3
  284. package/examples/approved-design/counters.aug +5 -4
  285. package/examples/approved-design/counters.aug.md +25 -132
  286. package/examples/approved-design/domain/app.aug +2 -1
  287. package/examples/approved-design/domain/app.aug.md +10 -80
  288. package/examples/approved-design/domain/export.aug +1 -0
  289. package/examples/approved-design/domain/export.aug.md +4 -20
  290. package/examples/approved-design/domain/models.aug +1 -0
  291. package/examples/approved-design/domain/models.aug.md +3 -25
  292. package/examples/approved-design/domain/numbers.aug +3 -2
  293. package/examples/approved-design/domain/numbers.aug.md +19 -116
  294. package/examples/approved-design/main.aug +1 -0
  295. package/examples/approved-design/main.aug.md +12 -95
  296. package/examples/benchmark/.aug-spec/manifest.json +1 -1
  297. package/examples/benchmark/main.aug +1 -0
  298. package/examples/benchmark/main.aug.md +6 -36
  299. package/examples/cli-args/.aug-spec/manifest.json +1 -1
  300. package/examples/cli-args/main.aug +1 -0
  301. package/examples/cli-args/main.aug.md +5 -32
  302. package/examples/collections/.aug-spec/manifest.json +1 -1
  303. package/examples/collections/main.aug +1 -0
  304. package/examples/collections/main.aug.md +6 -36
  305. package/examples/{generic-di/.aug-spec/august/0.19.0 → developer-workflow/.aug-spec/august/0.21.0}/io/contracts.aug +4 -3
  306. package/examples/developer-workflow/.aug-spec/august/0.21.0/io/contracts.aug.md +82 -0
  307. package/examples/developer-workflow/.aug-spec/manifest.json +3 -3
  308. package/examples/developer-workflow/calculator.aug +3 -2
  309. package/examples/developer-workflow/calculator.aug.md +28 -189
  310. package/examples/developer-workflow/logging/console.aug +2 -1
  311. package/examples/developer-workflow/logging/console.aug.md +7 -57
  312. package/examples/developer-workflow/logging/export.aug +1 -0
  313. package/examples/developer-workflow/logging/export.aug.md +3 -15
  314. package/examples/developer-workflow/logging/logger.aug +1 -0
  315. package/examples/developer-workflow/logging/logger.aug.md +6 -46
  316. package/examples/developer-workflow/main.aug +1 -0
  317. package/examples/developer-workflow/main.aug.md +10 -68
  318. package/examples/drop/.aug-spec/manifest.json +1 -1
  319. package/examples/drop/main.aug +1 -0
  320. package/examples/drop/main.aug.md +6 -28
  321. package/examples/drop/resource.aug +1 -0
  322. package/examples/drop/resource.aug.md +6 -34
  323. package/examples/errors/.aug-spec/manifest.json +1 -1
  324. package/examples/errors/errors.aug +2 -1
  325. package/examples/errors/errors.aug.md +4 -27
  326. package/examples/errors/main.aug +1 -0
  327. package/examples/errors/main.aug.md +6 -29
  328. package/examples/ffi/.aug-spec/manifest.json +1 -1
  329. package/examples/ffi/main.aug +1 -0
  330. package/examples/ffi/main.aug.md +5 -21
  331. package/examples/ffi/native.aug +2 -1
  332. package/examples/ffi/native.aug.md +5 -35
  333. package/examples/{approved-design/.aug-spec/august/0.19.0 → generic-di/.aug-spec/august/0.21.0}/io/contracts.aug +4 -3
  334. package/examples/generic-di/.aug-spec/august/0.21.0/io/contracts.aug.md +82 -0
  335. package/examples/generic-di/.aug-spec/manifest.json +3 -3
  336. package/examples/generic-di/main.aug +1 -0
  337. package/examples/generic-di/main.aug.md +8 -40
  338. package/examples/generic-di/types.aug +3 -2
  339. package/examples/generic-di/types.aug.md +18 -97
  340. package/examples/generics/.aug-spec/manifest.json +1 -1
  341. package/examples/generics/main.aug +1 -0
  342. package/examples/generics/main.aug.md +9 -48
  343. package/examples/generics/types.aug +4 -3
  344. package/examples/generics/types.aug.md +18 -104
  345. package/examples/{developer-workflow/.aug-spec/august/0.19.0 → hello/.aug-spec/august/0.21.0}/io/contracts.aug +4 -3
  346. package/examples/hello/.aug-spec/august/0.21.0/io/contracts.aug.md +82 -0
  347. package/examples/hello/.aug-spec/manifest.json +3 -3
  348. package/examples/hello/app/export.aug +1 -0
  349. package/examples/hello/app/export.aug.md +3 -13
  350. package/examples/hello/app/greeter.aug +2 -1
  351. package/examples/hello/app/greeter.aug.md +10 -94
  352. package/examples/hello/logging/console.aug +2 -1
  353. package/examples/hello/logging/console.aug.md +7 -55
  354. package/examples/hello/logging/export.aug +1 -0
  355. package/examples/hello/logging/export.aug.md +3 -15
  356. package/examples/hello/logging/logger.aug +1 -0
  357. package/examples/hello/logging/logger.aug.md +6 -48
  358. package/examples/hello/main.aug +1 -0
  359. package/examples/hello/main.aug.md +8 -40
  360. package/examples/interceptors/.aug-spec/august/0.21.0/io/contracts.aug +37 -0
  361. package/examples/interceptors/.aug-spec/august/0.21.0/io/contracts.aug.md +82 -0
  362. package/examples/interceptors/.aug-spec/manifest.json +3 -3
  363. package/examples/interceptors/app.aug +3 -2
  364. package/examples/interceptors/app.aug.md +15 -141
  365. package/examples/interceptors/interceptors.aug +3 -2
  366. package/examples/interceptors/interceptors.aug.md +19 -152
  367. package/examples/interceptors/logging.aug +2 -1
  368. package/examples/interceptors/logging.aug.md +10 -79
  369. package/examples/interceptors/main.aug +1 -0
  370. package/examples/interceptors/main.aug.md +9 -66
  371. package/examples/native-blake3/.aug-spec/manifest.json +16 -0
  372. package/examples/native-blake3/.aug-spec/packages/@greenpandastudios/aug-blake3/0.1.1/native.abi.json +29 -0
  373. package/examples/native-blake3/.aug-spec/packages/@greenpandastudios/aug-blake3/0.1.3/api.aug +14 -0
  374. package/examples/native-blake3/.aug-spec/packages/@greenpandastudios/aug-blake3/0.1.3/api.aug.md +34 -0
  375. package/examples/native-blake3/.aug-spec/packages/@greenpandastudios/aug-blake3/0.1.3/contracts.aug +4 -0
  376. package/examples/native-blake3/.aug-spec/packages/@greenpandastudios/aug-blake3/0.1.3/contracts.aug.md +8 -0
  377. package/examples/native-blake3/.aug-spec/packages/@greenpandastudios/aug-blake3/0.1.3/native.abi.json +29 -0
  378. package/examples/native-blake3/AGENTS.md +5 -0
  379. package/examples/native-blake3/aug.lock.json +253 -0
  380. package/examples/native-blake3/hashing.aug +11 -0
  381. package/examples/native-blake3/hashing.aug.md +25 -0
  382. package/examples/native-blake3/main.aug +8 -0
  383. package/examples/native-blake3/main.aug.md +13 -0
  384. package/examples/native-pytorch/.aug-spec/manifest.json +18 -0
  385. package/examples/native-pytorch/.aug-spec/packages/@greenpandastudios/aug-pytorch/0.1.1/native.abi.json +142 -0
  386. package/examples/native-pytorch/.aug-spec/packages/@greenpandastudios/aug-pytorch/0.1.3/native.abi.json +142 -0
  387. package/examples/native-pytorch/.aug-spec/packages/@greenpandastudios/aug-pytorch/0.1.4/api.aug +101 -0
  388. package/examples/native-pytorch/.aug-spec/packages/@greenpandastudios/aug-pytorch/0.1.4/api.aug.md +160 -0
  389. package/examples/native-pytorch/.aug-spec/packages/@greenpandastudios/aug-pytorch/0.1.4/bindings.aug +3 -0
  390. package/examples/native-pytorch/.aug-spec/packages/@greenpandastudios/aug-pytorch/0.1.4/bindings.aug.md +8 -0
  391. package/examples/native-pytorch/.aug-spec/packages/@greenpandastudios/aug-pytorch/0.1.4/contracts.aug +6 -0
  392. package/examples/native-pytorch/.aug-spec/packages/@greenpandastudios/aug-pytorch/0.1.4/contracts.aug.md +13 -0
  393. package/examples/native-pytorch/.aug-spec/packages/@greenpandastudios/aug-pytorch/0.1.4/native.abi.json +142 -0
  394. package/examples/native-pytorch/AGENTS.md +5 -0
  395. package/examples/native-pytorch/aug.lock.json +309 -0
  396. package/examples/native-pytorch/main.aug +8 -0
  397. package/examples/native-pytorch/main.aug.md +13 -0
  398. package/examples/native-pytorch/tensors.aug +23 -0
  399. package/examples/native-pytorch/tensors.aug.md +35 -0
  400. package/examples/native-sqlite/.aug-spec/manifest.json +18 -0
  401. package/examples/native-sqlite/.aug-spec/packages/@greenpandastudios/aug-sqlite/0.1.2/native.abi.json +100 -0
  402. package/examples/native-sqlite/.aug-spec/packages/@greenpandastudios/aug-sqlite/0.1.3/api.aug +48 -0
  403. package/examples/native-sqlite/.aug-spec/packages/@greenpandastudios/aug-sqlite/0.1.3/api.aug.md +91 -0
  404. package/examples/native-sqlite/.aug-spec/packages/@greenpandastudios/aug-sqlite/0.1.3/bindings.aug +3 -0
  405. package/examples/native-sqlite/.aug-spec/packages/@greenpandastudios/aug-sqlite/0.1.3/bindings.aug.md +8 -0
  406. package/examples/native-sqlite/.aug-spec/packages/@greenpandastudios/aug-sqlite/0.1.3/contracts.aug +8 -0
  407. package/examples/native-sqlite/.aug-spec/packages/@greenpandastudios/aug-sqlite/0.1.3/contracts.aug.md +22 -0
  408. package/examples/native-sqlite/.aug-spec/packages/@greenpandastudios/aug-sqlite/0.1.3/native.abi.json +100 -0
  409. package/examples/native-sqlite/AGENTS.md +5 -0
  410. package/examples/native-sqlite/aug.lock.json +236 -0
  411. package/examples/native-sqlite/database.aug +15 -0
  412. package/examples/native-sqlite/database.aug.md +27 -0
  413. package/examples/native-sqlite/main.aug +8 -0
  414. package/examples/native-sqlite/main.aug.md +13 -0
  415. package/examples/native-zlib/.aug-spec/manifest.json +16 -0
  416. package/examples/native-zlib/.aug-spec/packages/@greenpandastudios/aug-zlib/0.1.1/native.abi.json +57 -0
  417. package/examples/native-zlib/.aug-spec/packages/@greenpandastudios/aug-zlib/0.1.3/api.aug +29 -0
  418. package/examples/native-zlib/.aug-spec/packages/@greenpandastudios/aug-zlib/0.1.3/api.aug.md +54 -0
  419. package/examples/native-zlib/.aug-spec/packages/@greenpandastudios/aug-zlib/0.1.3/contracts.aug +4 -0
  420. package/examples/native-zlib/.aug-spec/packages/@greenpandastudios/aug-zlib/0.1.3/contracts.aug.md +8 -0
  421. package/examples/native-zlib/.aug-spec/packages/@greenpandastudios/aug-zlib/0.1.3/native.abi.json +57 -0
  422. package/examples/native-zlib/AGENTS.md +5 -0
  423. package/examples/native-zlib/aug.lock.json +236 -0
  424. package/examples/native-zlib/compression.aug +15 -0
  425. package/examples/native-zlib/compression.aug.md +27 -0
  426. package/examples/native-zlib/main.aug +10 -0
  427. package/examples/native-zlib/main.aug.md +13 -0
  428. package/examples/new-syntax/.aug-spec/august/0.21.0/io/contracts.aug +37 -0
  429. package/examples/new-syntax/.aug-spec/august/0.21.0/io/contracts.aug.md +82 -0
  430. package/examples/new-syntax/.aug-spec/manifest.json +3 -3
  431. package/examples/new-syntax/console.aug +2 -1
  432. package/examples/new-syntax/console.aug.md +7 -53
  433. package/examples/new-syntax/greeter.aug +2 -1
  434. package/examples/new-syntax/greeter.aug.md +10 -74
  435. package/examples/new-syntax/logger.aug +1 -0
  436. package/examples/new-syntax/logger.aug.md +6 -46
  437. package/examples/new-syntax/main.aug +1 -0
  438. package/examples/new-syntax/main.aug.md +9 -54
  439. package/examples/new-syntax/math.aug +2 -1
  440. package/examples/new-syntax/math.aug.md +3 -24
  441. package/examples/oidc-login/.aug-spec/manifest.json +13 -13
  442. package/examples/oidc-login/.aug-spec/packages/@git/url_0eb7c89453c87681ed15/0.0.0-git.a39fc582565d4fca40be4f75fa304d71adc69301/store.aug.md +71 -0
  443. package/examples/oidc-login/.aug-spec/packages/@git/url_2d3c37c690c0fa115be1/0.0.0-git.a39fc582565d4fca40be4f75fa304d71adc69301/contracts.aug.md +17 -0
  444. package/examples/oidc-login/.aug-spec/packages/@git/url_897efafd565158fc4908/0.0.0-git.a39fc582565d4fca40be4f75fa304d71adc69301/contracts.aug.md +125 -0
  445. package/examples/oidc-login/.aug-spec/{august/0.19.0/crypto → packages/@git/url_9ef654c66d34ab8f5527/0.0.0-git.b14a0f9aa41f1ce58bd51133bcdc424033e40d40}/contracts.aug +12 -11
  446. package/examples/oidc-login/.aug-spec/packages/@git/url_9ef654c66d34ab8f5527/0.0.0-git.b14a0f9aa41f1ce58bd51133bcdc424033e40d40/contracts.aug.md +244 -0
  447. package/examples/oidc-login/.aug-spec/{august/0.19.0/crypto → packages/@git/url_9ef654c66d34ab8f5527/0.0.0-git.b14a0f9aa41f1ce58bd51133bcdc424033e40d40}/jose.aug +6 -5
  448. package/examples/oidc-login/.aug-spec/packages/@git/url_9ef654c66d34ab8f5527/0.0.0-git.b14a0f9aa41f1ce58bd51133bcdc424033e40d40/jose.aug.md +71 -0
  449. package/examples/oidc-login/.aug-spec/packages/@git/url_c092cd151499c4e1d8a1/0.0.0-git.a39fc582565d4fca40be4f75fa304d71adc69301/contracts.aug.md +30 -0
  450. package/examples/oidc-login/aug.lock.json +100 -0
  451. package/examples/oidc-login/client/contracts.aug +1 -0
  452. package/examples/oidc-login/client/contracts.aug.md +9 -66
  453. package/examples/oidc-login/client/endpoints.aug +6 -5
  454. package/examples/oidc-login/client/endpoints.aug.md +13 -145
  455. package/examples/oidc-login/client/export.aug +1 -0
  456. package/examples/oidc-login/client/export.aug.md +4 -24
  457. package/examples/oidc-login/client/login.aug +7 -6
  458. package/examples/oidc-login/client/login.aug.md +25 -303
  459. package/examples/oidc-login/client/logout.aug +5 -4
  460. package/examples/oidc-login/client/logout.aug.md +13 -135
  461. package/examples/oidc-login/client/protocol.aug +7 -6
  462. package/examples/oidc-login/client/protocol.aug.md +36 -283
  463. package/examples/oidc-login/client/session.aug +5 -4
  464. package/examples/oidc-login/client/session.aug.md +12 -139
  465. package/examples/oidc-login/client/views.aug +3 -2
  466. package/examples/oidc-login/client/views.aug.md +8 -57
  467. package/examples/oidc-login/common/export.aug +1 -0
  468. package/examples/oidc-login/common/export.aug.md +5 -27
  469. package/examples/oidc-login/common/headers.aug +4 -3
  470. package/examples/oidc-login/common/headers.aug.md +9 -67
  471. package/examples/oidc-login/common/keys.aug +6 -5
  472. package/examples/oidc-login/common/keys.aug.md +29 -165
  473. package/examples/oidc-login/common/settings.aug +2 -1
  474. package/examples/oidc-login/common/settings.aug.md +5 -39
  475. package/examples/oidc-login/common/views.aug +2 -1
  476. package/examples/oidc-login/common/views.aug.md +4 -28
  477. package/examples/oidc-login/main.aug +6 -16
  478. package/examples/oidc-login/main.aug.md +17 -146
  479. package/examples/oidc-login/main.yaml +7 -0
  480. package/examples/oidc-login/provider/authorization.aug +7 -6
  481. package/examples/oidc-login/provider/authorization.aug.md +23 -238
  482. package/examples/oidc-login/provider/contracts.aug +1 -0
  483. package/examples/oidc-login/provider/contracts.aug.md +23 -158
  484. package/examples/oidc-login/provider/credentials.aug +3 -2
  485. package/examples/oidc-login/provider/credentials.aug.md +9 -53
  486. package/examples/oidc-login/provider/discovery.aug +4 -3
  487. package/examples/oidc-login/provider/discovery.aug.md +11 -118
  488. package/examples/oidc-login/provider/export.aug +1 -0
  489. package/examples/oidc-login/provider/export.aug.md +6 -34
  490. package/examples/oidc-login/provider/token.aug +6 -5
  491. package/examples/oidc-login/provider/token.aug.md +16 -204
  492. package/examples/oidc-login/provider/userinfo.aug +4 -3
  493. package/examples/oidc-login/provider/userinfo.aug.md +10 -92
  494. package/examples/oidc-login/provider/views.aug +3 -2
  495. package/examples/oidc-login/provider/views.aug.md +8 -52
  496. package/examples/ownership/.aug-spec/manifest.json +1 -1
  497. package/examples/ownership/counter.aug +3 -2
  498. package/examples/ownership/counter.aug.md +12 -66
  499. package/examples/ownership/main.aug +1 -0
  500. package/examples/ownership/main.aug.md +6 -31
  501. package/examples/ownership-transfer/.aug-spec/august/0.21.0/io/contracts.aug +37 -0
  502. package/examples/ownership-transfer/.aug-spec/august/0.21.0/io/contracts.aug.md +82 -0
  503. package/examples/ownership-transfer/.aug-spec/manifest.json +3 -3
  504. package/examples/ownership-transfer/main.aug +1 -0
  505. package/examples/ownership-transfer/main.aug.md +9 -53
  506. package/examples/ownership-transfer/resource.aug +2 -1
  507. package/examples/ownership-transfer/resource.aug.md +12 -71
  508. package/examples/packages/app/.aug-spec/manifest.json +1 -1
  509. package/examples/packages/app/.aug-spec/packages/@example/aug-math/0.1.0/arithmetic.aug +2 -1
  510. package/examples/packages/app/.aug-spec/packages/@example/aug-math/0.1.0/arithmetic.aug.md +9 -51
  511. package/examples/packages/app/main.aug +1 -0
  512. package/examples/packages/app/main.aug.md +6 -26
  513. package/examples/packages/math/.aug-spec/manifest.json +1 -1
  514. package/examples/packages/math/aug-package.json +1 -1
  515. package/examples/packages/math/src/arithmetic.aug +2 -1
  516. package/examples/packages/math/src/arithmetic.aug.md +9 -51
  517. package/examples/packages/math/src/export.aug +1 -0
  518. package/examples/packages/math/src/export.aug.md +3 -13
  519. package/examples/visibility/.aug-spec/manifest.json +1 -1
  520. package/examples/visibility/counter.aug +4 -3
  521. package/examples/visibility/counter.aug.md +12 -68
  522. package/examples/visibility/main.aug +1 -0
  523. package/examples/visibility/main.aug.md +6 -32
  524. package/examples/weather-api/.aug-spec/manifest.json +8 -0
  525. package/examples/weather-api/AGENTS.md +17 -0
  526. package/examples/weather-api/README.md +19 -0
  527. package/examples/weather-api/forecasts.aug +47 -0
  528. package/examples/weather-api/forecasts.aug.md +32 -0
  529. package/examples/weather-api/main.aug +4 -0
  530. package/examples/weather-api/main.aug.md +15 -0
  531. package/examples/weather-api/main.yaml +5 -0
  532. package/examples/weather-api/weather.http +5 -0
  533. package/native/compiler-packs.json +43 -0
  534. package/package.json +4 -4
  535. package/runtime/aug_http.c +48 -21
  536. package/runtime/aug_http_ir.c +30 -0
  537. package/runtime/aug_http_ir.h +18 -0
  538. package/runtime/aug_ir.c +209 -0
  539. package/runtime/aug_ir.h +89 -0
  540. package/runtime/aug_json.c +6 -1
  541. package/runtime/aug_runtime.c +82 -16
  542. package/runtime/aug_runtime.h +16 -2
  543. package/runtime/aug_tasks.c +38 -7
  544. package/runtime/aug_values.c +12 -6
  545. package/scripts/bootstrap-native.mjs +184 -106
  546. package/scripts/native-setup.mjs +98 -0
  547. package/scripts/native-toolchain.mjs +28 -0
  548. package/src/ast.js +1 -1
  549. package/src/builtins.js +1 -1
  550. package/src/checker.js +369 -100
  551. package/src/cli.js +198 -26
  552. package/src/codegen.js +32 -7
  553. package/src/compiler-packs.js +66 -0
  554. package/src/config.js +3 -3
  555. package/src/contracts.js +10 -0
  556. package/src/editor.js +86 -22
  557. package/src/fixes.js +90 -2
  558. package/src/formatter.js +23 -10
  559. package/src/git-http.js +137 -0
  560. package/src/git-packages.js +118 -0
  561. package/src/help.js +33 -24
  562. package/src/http-contracts.js +14 -0
  563. package/src/http-policies.js +5 -5
  564. package/src/ir-types.js +5 -0
  565. package/src/ir-verify.js +277 -0
  566. package/src/ir.js +962 -0
  567. package/src/libraries.js +1 -1
  568. package/src/llvm-debug.js +101 -0
  569. package/src/llvm-native.js +152 -0
  570. package/src/llvm-platform.js +20 -0
  571. package/src/llvm.js +781 -0
  572. package/src/lsp.js +14 -5
  573. package/src/native-artifacts.js +207 -0
  574. package/src/native-bindings.js +189 -0
  575. package/src/native-contracts.js +295 -0
  576. package/src/native-declarations.js +68 -0
  577. package/src/native-facts.js +63 -0
  578. package/src/native.js +19 -13
  579. package/src/navigation.js +4 -2
  580. package/src/openapi.js +5 -4
  581. package/src/package-locking.js +88 -0
  582. package/src/package-manager.js +267 -68
  583. package/src/parser.js +32 -6
  584. package/src/policies.js +3 -3
  585. package/src/project-init.js +78 -4
  586. package/src/project.js +11 -9
  587. package/src/runtime-abi.js +23 -0
  588. package/src/runtime-adapters.js +18 -0
  589. package/src/schemas.js +24 -17
  590. package/src/semantic.js +54 -5
  591. package/src/snippets.js +60 -0
  592. package/src/spec-hints.js +56 -0
  593. package/src/spec-tree.js +241 -0
  594. package/src/spec.js +669 -305
  595. package/docs/examples/approved-design/dependencies/august/0.19.0/io/contracts.md +0 -395
  596. package/docs/examples/developer-workflow/dependencies/august/0.19.0/io/contracts.md +0 -395
  597. package/docs/examples/generic-di/dependencies/august/0.19.0/io/contracts.md +0 -395
  598. package/docs/examples/hello/dependencies/august/0.19.0/io/contracts.md +0 -395
  599. package/docs/examples/interceptors/dependencies/august/0.19.0/io/contracts.md +0 -395
  600. package/docs/examples/json-benchmark/dependencies/august/0.19.0/json/contracts.md +0 -103
  601. package/docs/examples/new-syntax/dependencies/august/0.19.0/io/contracts.md +0 -395
  602. package/docs/examples/oidc-login/dependencies/august/0.19.0/crypto/contracts.md +0 -925
  603. package/docs/examples/oidc-login/dependencies/august/0.19.0/crypto/jose.md +0 -434
  604. package/docs/examples/oidc-login/dependencies/august/0.19.0/json/contracts.md +0 -103
  605. package/docs/examples/oidc-login/dependencies/august/0.19.0/memory/store.md +0 -374
  606. package/docs/examples/oidc-login/dependencies/august/0.19.0/time/contracts.md +0 -150
  607. package/docs/examples/oidc-login/dependencies/august/0.19.0/web/contracts.md +0 -532
  608. package/docs/examples/ownership-transfer/dependencies/august/0.19.0/io/contracts.md +0 -395
  609. package/examples/approved-design/.aug-spec/august/0.19.0/io/contracts.aug.md +0 -316
  610. package/examples/developer-workflow/.aug-spec/august/0.19.0/io/contracts.aug.md +0 -316
  611. package/examples/generic-di/.aug-spec/august/0.19.0/io/contracts.aug.md +0 -316
  612. package/examples/hello/.aug-spec/august/0.19.0/io/contracts.aug.md +0 -316
  613. package/examples/interceptors/.aug-spec/august/0.19.0/io/contracts.aug +0 -36
  614. package/examples/interceptors/.aug-spec/august/0.19.0/io/contracts.aug.md +0 -316
  615. package/examples/new-syntax/.aug-spec/august/0.19.0/io/contracts.aug +0 -36
  616. package/examples/new-syntax/.aug-spec/august/0.19.0/io/contracts.aug.md +0 -316
  617. package/examples/oidc-login/.aug-spec/august/0.19.0/crypto/contracts.aug.md +0 -791
  618. package/examples/oidc-login/.aug-spec/august/0.19.0/crypto/jose.aug.md +0 -266
  619. package/examples/oidc-login/.aug-spec/august/0.19.0/json/contracts.aug.md +0 -55
  620. package/examples/oidc-login/.aug-spec/august/0.19.0/memory/store.aug.md +0 -250
  621. package/examples/oidc-login/.aug-spec/august/0.19.0/time/contracts.aug.md +0 -96
  622. package/examples/oidc-login/.aug-spec/august/0.19.0/web/contracts.aug.md +0 -420
  623. package/examples/ownership-transfer/.aug-spec/august/0.19.0/io/contracts.aug +0 -36
  624. package/examples/ownership-transfer/.aug-spec/august/0.19.0/io/contracts.aug.md +0 -316
  625. /package/examples/oidc-login/.aug-spec/{august/0.19.0/memory → packages/@git/url_0eb7c89453c87681ed15/0.0.0-git.a39fc582565d4fca40be4f75fa304d71adc69301}/store.aug +0 -0
  626. /package/examples/oidc-login/.aug-spec/{august/0.19.0/json → packages/@git/url_2d3c37c690c0fa115be1/0.0.0-git.a39fc582565d4fca40be4f75fa304d71adc69301}/contracts.aug +0 -0
  627. /package/examples/oidc-login/.aug-spec/{august/0.19.0/web → packages/@git/url_897efafd565158fc4908/0.0.0-git.a39fc582565d4fca40be4f75fa304d71adc69301}/contracts.aug +0 -0
  628. /package/examples/oidc-login/.aug-spec/{august/0.19.0/time → packages/@git/url_c092cd151499c4e1d8a1/0.0.0-git.a39fc582565d4fca40be4f75fa304d71adc69301}/contracts.aug +0 -0
package/src/editor.js CHANGED
@@ -1,3 +1,4 @@
1
+ import { callableResult, callableErrors } from "./contracts.js";
1
2
  import { dirname, join, relative, resolve, sep } from 'node:path';
2
3
  import { fieldsOf, typeName } from "./ast.js";
3
4
  import { tyName } from "./checker.js";
@@ -12,6 +13,10 @@ import { interceptorBehavior } from "./interceptors.js";
12
13
  import { httpPolicyNames, httpPolicyOptions, httpPolicyOptionHelp } from "./http-policies.js";
13
14
  import { builtinTypes } from "./builtins.js";
14
15
  import { libraryChild, libraryRelative } from "./libraries.js";
16
+ import { importSource, isGitSource, sourceAlias } from "./git-packages.js";
17
+ import { snippetBody, snippetCatalog } from "./snippets.js";
18
+ import { nativeFact, nativeDependencies, nativeDescription } from "./native-facts.js";
19
+ import { pathToFileURL } from 'node:url';
15
20
  const builtins = [
16
21
  ...builtinFunctions.map(operation => {
17
22
  const parameters = operation.parameters.map(param => `${param.label}=${param.type}`);
@@ -24,6 +29,8 @@ const builtins = [
24
29
  .map(([label, help]) => ({ label, kind: 'type', detail: help.detail, documentation: help.documentation })),
25
30
  ];
26
31
  const keywords = [
32
+ ...snippetCatalog.map(snippet => ({ label: snippet.prefix + ' template', kind: 'snippet', detail: snippet.description,
33
+ documentation: snippet.description, insertText: snippet.body })),
27
34
  { label: 'initialize block', kind: 'snippet', detail: 'Constructor initialization inside a class or record', documentation: languageHelp.initialize.documentation,
28
35
  insertText: 'initialize:\n $0' },
29
36
  ...Object.entries(languageHelp).filter(([label, help]) => help.category === 'keyword' &&
@@ -38,7 +45,7 @@ const keywords = [
38
45
  insertText: 'borrow ${1:value} {\n $0\n}' },
39
46
  { label: 'interceptor declaration', kind: 'snippet', detail: 'Generic interceptor wrapping any result type',
40
47
  documentation: languageHelp.interceptor.documentation,
41
- insertText: 'interceptor ${1:Audit}<T>() {\n around() returns T {\n T result to next()\n $0\n return result\n }\n}' },
48
+ insertText: 'interceptor ${1:Audit}<T>() {\n around() {\n result = next()\n $0\n return result\n }\n}' },
42
49
  { label: 'test suite', kind: 'snippet', detail: 'Same-file class tests with fresh setup per case',
43
50
  documentation: languageHelp.test.documentation,
44
51
  insertText: 'test ${1:Worker} ${2:worker} {\n when ${3:ready} {\n ${2:worker} = ${1:Worker}()\n it ${4:works} {\n assert(${5:true})\n }\n }\n}' },
@@ -59,15 +66,18 @@ function parameterText(param) {
59
66
  `${typeName(param.type)} ${param.label ?? param.name}${param.label && param.label !== param.name ? ` to ${param.name}` : ''}` +
60
67
  (param.source ? ` from ${param.source.kind}${param.source.name ? ' ' + JSON.stringify(param.source.name) : ''}` : '');
61
68
  }
62
- function signature(method, callSite = false, additionalErrors = []) {
69
+ function signature(method, callSite = false, additionalErrors = [], checked) {
63
70
  const generic = method.typeParams.length ? `<${method.typeParams.join(', ')}>` : '';
64
71
  const params = callSite ? method.params.filter(param => !param.injected)
65
72
  .map(param => `${param.label ?? param.name}=${typeName(param.type)}`) : method.params.map(parameterText);
66
- const errors = [...new Set([...method.throws.map(typeName), ...additionalErrors])];
73
+ const errors = checked ? callableErrors(checked, method) : [...new Set([...method.throws.map(typeName), ...additionalErrors])];
74
+ const contract = checked?.effectContracts.get(method);
75
+ const changes = contract?.changes ?? method.changes ?? [];
76
+ const uses = [...(contract?.uses.values() ?? method.uses ?? [])].map(use => `${use.source}.${use.operation}`);
67
77
  return (method.endpoint ? `endpoint ${method.endpoint.method} ${JSON.stringify(method.endpoint.path)} as ` : '') + `${method.name}${generic}(${params.join(', ')}) ${method.endpoint?.streams ? 'streams' : 'returns'} ` +
68
- `${method.returnOwnership === 'own' ? 'own ' : ''}${typeName(method.returns)}` +
69
- (method.changes?.length ? ` changes ${method.changes.join(' and ')}` : '') +
70
- (method.uses?.length ? ` uses ${method.uses.map(use => `${use.source}.${use.operation}`).join(' and ')}` : '') +
78
+ `${method.returnOwnership === 'own' ? 'own ' : ''}${checked ? tyName(callableResult(checked, method)) : typeName(method.returns)}` +
79
+ (changes.length ? ` changes ${changes.join(' and ')}` : '') +
80
+ (uses.length ? ` uses ${uses.join(' and ')}` : '') +
71
81
  (errors.length ? ` unless ${errors.join(', ')}` : '') +
72
82
  (method.endpoint && method.endpoint.status !== 200 ? ` with status ${method.endpoint.status}` : '');
73
83
  }
@@ -117,16 +127,17 @@ function methodDocumentation(checked, method, owner) {
117
127
  }
118
128
  function methodItem(checked, method, kind, owner) {
119
129
  const errors = (checked.interceptorPlans.get(method) ?? []).flatMap(layer => layer.errors.map(tyName));
120
- const label = signature(method, false, errors);
130
+ const label = signature(method, false, errors, checked);
121
131
  const injected = method.params.filter(param => param.injected);
122
132
  const doc = methodDocumentation(checked, method, owner);
123
133
  const injectionHelp = injected.length ? `Injected from bindings: ${injected.map(parameterText).join(', ')}.` : '';
124
134
  const contract = checked.effectContracts.get(method);
125
135
  const effects = contract ? `${contract.inferred ? 'Inferred capabilities; effective' : 'Effective'} contract: changes ${contract.changes.join(', ') || 'nothing'}; capabilities ` +
126
136
  `${[...contract.uses.values()].map(effect => `${effect.source}.${effect.operation}`).join(', ') || 'none'}.` : '';
127
- return { label: method.name, kind, detail: label, signature: signature(method, true, errors),
137
+ const native = nativeDependencies(checked, method).map(fact => nativeDescription(fact, '[`native.abi.json`](' + pathToFileURL(checked.native.providerDescriptors.get(fact.provider)).href + ')')).join('\n\n');
138
+ return { label: method.name, kind, detail: label, signature: signature(method, true, errors, checked),
128
139
  documentation: [doc?.markdown, isPrivateName(method.name) ? 'Private to its declaring type.' : '',
129
- injectionHelp, effects, interceptorDescription(checked, method), 'Call arguments require labels; their order does not matter.']
140
+ injectionHelp, effects, native, interceptorDescription(checked, method), 'Call arguments require labels; their order does not matter.']
130
141
  .filter(Boolean).join('\n\n'),
131
142
  parameters: method.params.filter(param => !param.injected)
132
143
  .map(param => `${param.label ?? param.name}=${typeName(param.type)}`),
@@ -135,6 +146,11 @@ function methodItem(checked, method, kind, owner) {
135
146
  }
136
147
  function definitionItem(checked, def) {
137
148
  const node = def.node;
149
+ if (node.kind === 'resource') {
150
+ const native = nativeFact(checked, node);
151
+ return { label: def.name, kind: 'type', detail: 'extern C resource ' + def.name,
152
+ documentation: native ? nativeDescription(native, '[`native.abi.json`](' + pathToFileURL(checked.native.providerDescriptors.get(native.provider)).href + ')') : 'Opaque native resource. Its package must declare a release identity.' };
153
+ }
138
154
  if (node.kind === 'function')
139
155
  return methodItem(checked, node, 'function');
140
156
  if (node.kind === 'interface')
@@ -147,7 +163,7 @@ function definitionItem(checked, def) {
147
163
  const doc = around && methodDocumentation(checked, around, def);
148
164
  return { label: def.name, kind: 'interceptor',
149
165
  detail: `interceptor ${node.name}${node.typeParams.length ? `<${node.typeParams.join(', ')}>` : ''}` +
150
- `(${node.fields.map(parameterText).join(', ')})` + (around ? `\n${signature(around)}` : ''),
166
+ `(${node.fields.map(parameterText).join(', ')})` + (around ? `\n${signature(around, false, [], checked)}` : ''),
151
167
  signature: `${node.name}(${params.map(param => `${param.name}=targetLabel`).join(', ')})`,
152
168
  parameters: params.map(param => `${param.name}=targetLabel`),
153
169
  parameterDocumentation: params.map(param => [doc?.parameters.get(param.name),
@@ -167,10 +183,11 @@ function definitionItem(checked, def) {
167
183
  const explicit = node.fields.filter(field => !field.injected);
168
184
  const callSignature = `${def.name}${node.typeParams.length ? `<${node.typeParams.join(', ')}>` : ''}` +
169
185
  `(${explicit.map(field => `${field.label ?? field.name}=${typeName(field.type)}`).join(', ')})`;
170
- const errors = [...new Set((checked.interceptorPlans.get(node) ?? []).flatMap(layer => layer.errors.map(tyName)))];
186
+ const errors = [...new Set([...(checked.constructorContracts.get(node)?.errors.map(tyName) ?? node.validationErrors?.map(typeName) ?? []),
187
+ ...(checked.interceptorPlans.get(node) ?? []).flatMap(layer => layer.errors.map(tyName))])];
171
188
  return { label: def.name, kind: 'class', detail: `${node.record ? 'record ' : ''}${label}` +
172
- (node.implements.length ? ` implements ${node.implements.map(typeName).join(' and ')}` : '') +
173
- (errors.length ? ` unless ${errors.join(', ')}` : ''),
189
+ (errors.length ? ` unless ${errors.join(' and ')}` : '') +
190
+ (node.implements.length ? ` implements ${node.implements.map(typeName).join(', ')}` : ''),
174
191
  signature: callSignature + (errors.length ? ` unless ${errors.join(', ')}` : ''), parameters: explicit.map(field => `${field.label ?? field.name}=${typeName(field.type)}`),
175
192
  documentation: [doc?.markdown,
176
193
  node.fields.some(field => field.injected) ? `Injected from bindings: ${node.fields.filter(field => field.injected).map(parameterText).join(', ')}.` : '',
@@ -181,7 +198,7 @@ function definitionItem(checked, def) {
181
198
  function typeFromRef(checked, file, ref) {
182
199
  const def = checked.project.scopes.get(file)?.get(ref.name);
183
200
  return { id: def?.id ?? `builtin:${ref.name}`, name: ref.name,
184
- kind: def?.node.kind === 'class' || def?.node.kind === 'interface' || def?.node.kind === 'interceptor' ? def.node.kind : 'builtin',
201
+ kind: def?.node.kind === 'class' || def?.node.kind === 'interface' || def?.node.kind === 'interceptor' || def?.node.kind === 'resource' ? def.node.kind : 'builtin',
185
202
  args: ref.args.map(arg => typeFromRef(checked, file, arg)), nullable: ref.nullable, def };
186
203
  }
187
204
  function collectLocals(checked, file, offset) {
@@ -292,7 +309,9 @@ export function importItems(checked, file) {
292
309
  if (isPrivateName(item.name))
293
310
  continue;
294
311
  items.push({ label: item.name, kind: 'snippet',
295
- detail: `import ${item.name} from ${from}`, insertText: `${item.name} from ${from};`,
312
+ detail: `import ${item.name} from ${from}`, insertText: `${item.name} from ${from}`,
313
+ signature: definitionItem(checked, project.scopes.get(sibling.path).get(item.name)).signature,
314
+ parameters: definitionItem(checked, project.scopes.get(sibling.path).get(item.name)).parameters,
296
315
  documentation: item.kind === 'interface' ? documentation(checked, sibling.path, item.span.start)?.markdown :
297
316
  declarationDocumentation(checked, item)?.markdown });
298
317
  }
@@ -335,7 +354,8 @@ export function importItems(checked, file) {
335
354
  continue;
336
355
  for (const prefix of prefixes)
337
356
  for (const item of exportFile.items) {
338
- const from = [...prefix, ...segments].join('.');
357
+ const specification = (owner?.specifications ?? project.packages.specifications)[prefix[0]];
358
+ const from = isGitSource(specification ?? '') && prefix[0] === sourceAlias(specification) ? importSource([specification, ...segments]) : [...prefix, ...segments].join('.');
339
359
  if (!from)
340
360
  continue;
341
361
  if (item.kind !== 'export' || item.folder)
@@ -344,13 +364,15 @@ export function importItems(checked, file) {
344
364
  continue;
345
365
  const exported = project.scopes.get(join(folder, `${item.from}.aug`))?.get(item.name);
346
366
  items.push({ label: item.name, kind: 'snippet',
347
- detail: `import ${item.name} from ${from}`, insertText: `${item.name} from ${from};`,
367
+ detail: `import ${item.name} from ${from}`, insertText: `${item.name} from ${from}`,
368
+ signature: exported && definitionItem(checked, exported).signature,
369
+ parameters: exported && definitionItem(checked, exported).parameters,
348
370
  documentation: exported && definitionItem(checked, exported).documentation });
349
371
  }
350
372
  }
351
373
  return items;
352
374
  }
353
- export function completions(checked, fileName, offset) {
375
+ function rawCompletions(checked, fileName, offset) {
354
376
  const file = checked.project.files.get(resolve(fileName));
355
377
  if (!file)
356
378
  return [];
@@ -364,12 +386,13 @@ export function completions(checked, fileName, offset) {
364
386
  const used = new Set(joined[1].split(/\s+and\s+/));
365
387
  return unique(imports.filter(item => !used.has(item.label)).map(item => ({ ...item, kind: 'snippet', insertText: item.label })));
366
388
  }
367
- const from = /^\s*import\s+(.+?)\s+from\s+[A-Za-z_0-9.]*$/.exec(line);
389
+ const from = /^\s*import\s+(.+?)\s+from\s+([A-Za-z_0-9.]*|"[^"\n]*"?(?:\.[A-Za-z_0-9.]*)?)$/.exec(line);
368
390
  if (from)
369
391
  return unique(imports.filter(item => from[1] === 'everything' || item.label === from[1].split(/\s+and\s+/)[0]).map(item => {
370
392
  const path = item.detail.slice(item.detail.lastIndexOf(' from ') + 6);
371
393
  return { label: path, kind: 'snippet', detail: item.detail,
372
- insertText: `${path};`, documentation: item.documentation };
394
+ insertText: path, documentation: item.documentation,
395
+ replacement: { start: offset - from[2].length, end: offset } };
373
396
  }));
374
397
  const annotation = /(?<=^|\n)[ \t]*\[\s*([A-Za-z_][A-Za-z0-9_]*|)(?:<[^\[\]()]*>)?(?:\(([^\n()]*))?$/.exec(prefix);
375
398
  if (annotation) {
@@ -463,7 +486,48 @@ export function completions(checked, fileName, offset) {
463
486
  return all.filter(item => item.kind === 'interface');
464
487
  if (/\b(?:returns|unless|catch)\s+[A-Za-z_0-9]*$/.test(prefix))
465
488
  return all.filter(item => ['class', 'interface', 'type'].includes(item.kind));
466
- return all;
489
+ const visible = new Set(all.map(item => item.label));
490
+ const importsEnd = file.items.filter(item => item.kind === 'import').at(-1)?.span.end ?? 0;
491
+ const insertion = importsEnd ? file.source.indexOf('\n', importsEnd) : 0;
492
+ return [...all, ...imports.filter(item => !visible.has(item.label)).map(item => ({ ...item,
493
+ kind: item.signature ? 'function' : 'type',
494
+ insertText: item.label, sortText: '2-' + item.label,
495
+ additionalEdits: [{ start: insertion < 0 ? file.source.length : insertion, end: insertion < 0 ? file.source.length : insertion,
496
+ text: `${importsEnd ? '\n' : ''}${item.detail}${importsEnd ? '' : '\n'}` }] }))];
497
+ }
498
+ /** Fill labeled calls, keep dependency imports visible, and replace only the token being completed. */
499
+ export function completions(checked, fileName, offset) {
500
+ const file = checked.project.files.get(resolve(fileName));
501
+ if (!file)
502
+ return [];
503
+ const prefix = file.source.slice(0, offset), line = prefix.slice(prefix.lastIndexOf('\n') + 1);
504
+ const typeContext = /\b(?:import|export|implement|implements|extends|returns|unless|catch|resolve)\b[^\n]*$/.test(line);
505
+ const token = /[A-Za-z_][A-Za-z0-9_]*$/.exec(prefix);
506
+ const start = token ? offset - token[0].length : offset;
507
+ const end = offset + (/^[A-Za-z0-9_]*/.exec(file.source.slice(offset))?.[0].length ?? 0);
508
+ const escape = (text) => text.replace(/[\\$}]/g, '\\$&');
509
+ const argument = (parameter, index) => {
510
+ const [name, type] = parameter.split('=');
511
+ const value = type === 'string' ? '""' : type === 'bool' ? 'false' : ['int', 'float', 'c_int'].includes(type) ? '0' : name;
512
+ return `${name}=\${${index + 1}:${escape(value)}}`;
513
+ };
514
+ return rawCompletions(checked, fileName, offset).map(item => {
515
+ const callable = !typeContext && ['function', 'method', 'class'].includes(item.kind) && item.signature &&
516
+ !/^\s*\(/.test(file.source.slice(offset));
517
+ let insertText = callable ? `${item.label}(${(item.parameters ?? []).map(argument).join(', ')})$0` : item.insertText;
518
+ const template = snippetCatalog.find(snippet => item.label === snippet.prefix + ' template');
519
+ if (template)
520
+ insertText = snippetBody(template.body, checked.project.config.block_style, checked.project.config.indentation === 'tabs');
521
+ if (item.kind === 'snippet' && insertText && checked.project.config.block_style === 'indent' && insertText.includes('{\n'))
522
+ insertText = insertText.replace(/^(\s*)\} catch /gm, '$1catch ').replace(/ \{\n/g, ':\n').replace(/^[ \t]*\}\n?/gm, '').trimEnd();
523
+ let additionalEdits = item.additionalEdits;
524
+ if (additionalEdits?.some(edit => edit.start >= start && edit.start <= end)) {
525
+ insertText = additionalEdits.map(edit => escape(edit.text)).join('') + (insertText ?? item.label);
526
+ additionalEdits = undefined;
527
+ }
528
+ return { ...item, insertText, additionalEdits, replacement: item.replacement ?? { start, end },
529
+ sortText: item.sortText ?? (['variable', 'parameter', 'property'].includes(item.kind) ? '0-' : '1-') + item.label };
530
+ });
467
531
  }
468
532
  /** Resolve exactly the token under the cursor, including syntax outside completion contexts. */
469
533
  export function hoverInfo(checked, fileName, offset) {
@@ -771,7 +835,7 @@ export function semanticTokens(checked, fileName) {
771
835
  else {
772
836
  const def = scope?.get(token.value);
773
837
  if (def)
774
- type = def.node.kind === 'interceptor' ? 'decorator' : def.node.kind === 'composition' ? 'function' : def.node.kind;
838
+ type = def.node.kind === 'resource' ? 'type' : def.node.kind === 'interceptor' ? 'decorator' : def.node.kind === 'composition' ? 'function' : def.node.kind;
775
839
  }
776
840
  if (type)
777
841
  result.push({ line: token.span.line - 1, start: token.span.column - 1,
package/src/fixes.js CHANGED
@@ -1,5 +1,7 @@
1
1
  import { resolve } from 'node:path';
2
- import { importItems } from "./editor.js";
2
+ import { typeName } from "./ast.js";
3
+ import { completions, hoverInfo, importItems } from "./editor.js";
4
+ import { importSource } from "./git-packages.js";
3
5
  import { languageHelp } from "./help.js";
4
6
  import { lex } from "./lexer.js";
5
7
  import { tyName } from "./types.js";
@@ -74,6 +76,24 @@ function containingStatement(file, offset) {
74
76
  }
75
77
  return result.at(-1);
76
78
  }
79
+ function callsIn(file) {
80
+ const result = [];
81
+ const visit = (value) => {
82
+ if (!value || typeof value !== 'object')
83
+ return;
84
+ if (Array.isArray(value)) {
85
+ value.forEach(visit);
86
+ return;
87
+ }
88
+ if ('kind' in value && value.kind === 'call')
89
+ result.push(value);
90
+ for (const [key, child] of Object.entries(value))
91
+ if (key !== 'span')
92
+ visit(child);
93
+ };
94
+ visit(file.items);
95
+ return result;
96
+ }
77
97
  function wrappedStatement(file, issue, opener, closer = '}') {
78
98
  const stmt = containingStatement(file, offsetAt(file.source, issue.line, issue.column));
79
99
  // A declaration moved into a new block would become invisible afterward.
@@ -108,7 +128,7 @@ export function suggestedFixes(checked, fileName) {
108
128
  if (names.length)
109
129
  fixes.push({ title: 'Expand to named imports', issue: { code: 'IMPORT', line: item.span.line, column: item.span.column,
110
130
  message: 'Make imported dependencies explicit' }, edits: [{ file: file.path, start: item.span.start, end: item.span.end,
111
- text: `import ${names.join(' and ')} from ${item.from.join('.')}` }] });
131
+ text: `import ${names.join(' and ')} from ${importSource(item.from)}` }] });
112
132
  }
113
133
  for (const issue of checked.diagnostics.filter(issue => issue.file === file.path)) {
114
134
  const add = (title, edit) => {
@@ -118,6 +138,43 @@ export function suggestedFixes(checked, fileName) {
118
138
  const unknown = /^(?:Unknown name|Unknown type|Unknown interceptor) ([A-Za-z_][A-Za-z0-9_]*)$/.exec(issue.message);
119
139
  const mistyped = /^Expected ([A-Za-z_]+), found "([A-Za-z_]+)"$/.exec(issue.message);
120
140
  const redundant = /^Remove (class|function|fuction); declarations start with their name$/.exec(issue.message);
141
+ const missing = /^([A-Za-z_][A-Za-z0-9_]*) must implement ([A-Za-z_][A-Za-z0-9_]*)$/.exec(issue.message);
142
+ if (issue.code === 'INTERFACE' && missing) {
143
+ const owner = file.items.find(item => item.kind === 'class' && item.name === missing[1]);
144
+ if (owner?.kind === 'class') {
145
+ const seen = new Set();
146
+ const substitute = (ref, types) => types.get(ref.name) ?? { ...ref, args: ref.args.map(arg => substitute(arg, types)) };
147
+ const find = (ref, source) => {
148
+ const def = checked.project.scopes.get(source)?.get(ref.name);
149
+ if (!def || def.node.kind !== 'interface' || seen.has(def.id))
150
+ return;
151
+ seen.add(def.id);
152
+ const types = new Map(def.node.typeParams.map((name, index) => [name, ref.args[index]]).filter((entry) => !!entry[1]));
153
+ const method = def.node.methods.find(method => method.name === missing[2]);
154
+ if (method)
155
+ return { method, types };
156
+ for (const parent of def.node.extends) {
157
+ const found = find(substitute(parent, types), def.file);
158
+ if (found)
159
+ return found;
160
+ }
161
+ };
162
+ const contract = owner.implements.map(ref => find(ref, file.path)).find(Boolean);
163
+ if (contract) {
164
+ const params = contract.method.params.map(param => `${param.injected ? 'resolve ' : ''}${param.ownership === 'managed' ? '' : param.ownership + ' '}${typeName(substitute(param.type, contract.types))} ${param.name}`);
165
+ const generic = contract.method.typeParams.length ? '<' + contract.method.typeParams.join(', ') + '>' : '';
166
+ const header = `${missing[2]}${generic}(${params.join(', ')}) returns ${contract.method.returnOwnership === 'own' ? 'own ' : ''}${typeName(substitute(contract.method.returns, contract.types))}` +
167
+ (contract.method.throws.length ? ' unless ' + contract.method.throws.map(ref => typeName(substitute(ref, contract.types))).join(', ') : '');
168
+ const unit = checked.project.config.indentation === 'tabs' ? '\t' : ' ';
169
+ const start = owner.headerEnd ?? owner.span.start;
170
+ const braces = file.source[start] === '{' || file.source.slice(owner.span.start, start + 1).trimEnd().endsWith('{');
171
+ const insertion = braces ? file.source.lastIndexOf('}', owner.span.end - 1) : owner.span.end;
172
+ if (insertion >= owner.span.start)
173
+ add(`Implement ${missing[2]} in ${owner.name}`, { file: file.path, start: insertion, end: insertion,
174
+ text: braces ? `\n${unit}${header} {\n${unit}${unit}// TODO: implement ${missing[2]}\n${unit}}\n` : `\n${unit}${header}:\n${unit}${unit}// TODO: implement ${missing[2]}\n${unit}${unit}pass\n` });
175
+ }
176
+ }
177
+ }
121
178
  if (issue.code === 'PARSE' && redundant) {
122
179
  const start = offsetAt(file.source, issue.line, issue.column);
123
180
  if (file.source.slice(start, start + redundant[1].length) === redundant[1])
@@ -140,6 +197,37 @@ export function suggestedFixes(checked, fileName) {
140
197
  seen.add(declaration);
141
198
  add(`Import ${unknown[1]} from ${item.detail.split(' from ')[1]}`, { file: file.path, start: 0, end: 0, text: `${declaration}\n` });
142
199
  }
200
+ const start = offsetAt(file.source, issue.line, issue.column);
201
+ const candidates = completions(checked, file.path, start + unknown[1].length).filter(item => !item.additionalEdits && ['variable', 'parameter', 'property', 'function', 'class', 'interface', 'type'].includes(item.kind) &&
202
+ item.label !== unknown[1] && distance(item.label, unknown[1]) <= Math.min(2, Math.floor(unknown[1].length / 3)));
203
+ for (const candidate of candidates.slice(0, 3))
204
+ fixes.push({ title: `Replace ${unknown[1]} with ${candidate.label}`, issue,
205
+ preferred: candidates.length === 1, edits: [{ file: file.path, start, end: start + unknown[1].length, text: candidate.label }] });
206
+ }
207
+ const badMember = / has no (?:member|method) ([A-Za-z_][A-Za-z0-9_]*)$/.exec(issue.message);
208
+ if (badMember) {
209
+ const start = offsetAt(file.source, issue.line, issue.column), tokens = lex(file.path, file.source).tokens;
210
+ const member = tokens.find(token => token.value === badMember[1] && token.span.start >= start && token.span.line === issue.line);
211
+ if (member) {
212
+ const candidates = completions(checked, file.path, member.span.end).filter(item => item.label !== member.value && distance(item.label, member.value) <= 2);
213
+ for (const candidate of candidates.slice(0, 3))
214
+ fixes.push({ title: `Replace ${member.value} with ${candidate.label}`, issue,
215
+ preferred: candidates.length === 1, edits: [{ file: file.path, start: member.span.start, end: member.span.end, text: candidate.label }] });
216
+ }
217
+ }
218
+ const badLabel = / has no parameter ([A-Za-z_][A-Za-z0-9_]*)$/.exec(issue.message);
219
+ if (issue.code === 'CALL' && badLabel) {
220
+ const start = offsetAt(file.source, issue.line, issue.column);
221
+ const calls = callsIn(file).filter(call => call.span.start <= start && start < call.span.end)
222
+ .sort((a, b) => a.span.end - a.span.start - (b.span.end - b.span.start));
223
+ const call = calls[0], entry = call && hoverInfo(checked, file.path, call.callee.span.end - 1);
224
+ const tokens = call && lex(file.path, file.source).tokens.filter(token => call.span.start < token.span.start && token.span.end <= start);
225
+ const label = tokens?.findLast(token => token.value === badLabel[1]);
226
+ const candidates = entry?.parameters?.map(parameter => parameter.split('=')[0]).filter(name => !call.argLabels.includes(name) && distance(name, badLabel[1]) <= 2) ?? [];
227
+ if (label)
228
+ for (const name of candidates)
229
+ fixes.push({ title: `Use argument label ${name}`, issue, preferred: candidates.length === 1,
230
+ edits: [{ file: file.path, start: label.span.start, end: label.span.end, text: name }] });
143
231
  }
144
232
  if (issue.code === 'INTERCEPTOR' && /constructor parameter .* must be marked resolve/.test(issue.message)) {
145
233
  const start = offsetAt(file.source, issue.line, issue.column);
package/src/formatter.js CHANGED
@@ -1,6 +1,7 @@
1
1
  import { typeName } from "./ast.js";
2
2
  import { lex } from "./lexer.js";
3
3
  import { parse } from "./parser.js";
4
+ import { importSource } from "./git-packages.js";
4
5
  /** Canonical syntax comes from the parsed program; comments stay with their lexical owner. */
5
6
  export function formatFile(project, file) {
6
7
  return printFile(project, file, false);
@@ -43,7 +44,7 @@ function printFile(project, file, migrate) {
43
44
  if (!value || typeof value !== 'object')
44
45
  return value;
45
46
  const node = value;
46
- return Object.fromEntries(Object.entries(node).filter(([key, value]) => !['span', 'nameSpan', 'sourceSpan'].includes(key) && value !== undefined)
47
+ return Object.fromEntries(Object.entries(node).filter(([key, value]) => !['span', 'nameSpan', 'sourceSpan', 'headerEnd'].includes(key) && value !== undefined)
47
48
  .sort(([a], [b]) => a.localeCompare(b)).map(([key, value]) => [key, shape(value)]));
48
49
  };
49
50
  if (JSON.stringify(shape(parsed.file.items)) !== JSON.stringify(shape(verified.file.items)))
@@ -67,7 +68,15 @@ class Printer {
67
68
  this.indent = project.config.block_style === 'indent';
68
69
  this.assign = project.config.assignment === 'to' ? 'to' : '=';
69
70
  }
70
- line(text = '') { this.lines.push(text ? this.step.repeat(this.level) + text : ''); }
71
+ line(text = '') {
72
+ this.lines.push(...text.split('\n').map(line => line ? this.step.repeat(this.level) + line : ''));
73
+ }
74
+ delimited(open, values, close, trailing = '') {
75
+ const flat = open + values.join(', ') + trailing + close;
76
+ if (!values.length || (!flat.includes('\n') && flat.length <= 80 - this.level * 4))
77
+ return flat;
78
+ return open + '\n' + values.map(value => this.step + value.replaceAll('\n', '\n' + this.step)).join(',\n') + trailing + '\n' + close;
79
+ }
71
80
  before(offset, parentColumn) {
72
81
  while (this.comments[0]?.span.start < offset) {
73
82
  if (parentColumn !== undefined && this.comments[0].span.column <= parentColumn)
@@ -123,7 +132,7 @@ class Printer {
123
132
  this.annotations(method.annotations);
124
133
  const header = `${method.endpoint ? `endpoint ${method.endpoint.method} ${JSON.stringify(method.endpoint.path)} as ` : ''}${method.fixture ? 'fixture ' : ''}${method.externC ? 'extern C ' + (method.valueAbi ? 'value ' : '') + (method.nativePure ? 'pure ' : '') : ''}${method.name}${this.generics(method)}` +
125
134
  `(${method.params.map(param => this.param(param)).join(', ')})` +
126
- (method.returns.name !== 'void' ? ` ${method.endpoint?.streams ? 'streams' : 'returns'} ${method.returnOwnership === 'own' ? 'own ' : ''}${typeName(method.returns)}` : '') +
135
+ (method.returns.name !== 'void' || method.declared?.returns ? ` ${method.endpoint?.streams ? 'streams' : 'returns'} ${method.returnOwnership === 'own' ? 'own ' : ''}${typeName(method.returns)}` : '') +
127
136
  (method.endpoint && method.endpoint.status !== 200 ? ` with status ${method.endpoint.status}` : '') +
128
137
  (method.changes?.length ? ` changes ${method.changes.join(' and ')}` : '') +
129
138
  (method.uses?.length ? ` uses ${method.uses.map(use => `${use.source}.${use.operation}`).join(' and ')}` : '') +
@@ -159,14 +168,16 @@ class Printer {
159
168
  value = `resolve ${expr.name}` + (expr.typeArgs.length ? '<' + expr.typeArgs.map(typeName).join(', ') + '>' : '');
160
169
  else if (expr.kind === 'member')
161
170
  value = `${this.expression(expr.object, 8)}.${expr.name}`;
162
- else if (expr.kind === 'call')
163
- value = this.expression(expr.callee, 8) + (expr.typeArgs.length ? '<' + expr.typeArgs.map(typeName).join(', ') + '>' : '') +
164
- '(' + expr.args.map((arg, index) => (expr.argLabels[index] ? expr.argLabels[index] + '=' : '') + this.expression(arg)).join(', ') + this.inline(expr.span.end) + ')';
171
+ else if (expr.kind === 'call') {
172
+ const open = this.expression(expr.callee, 8) + (expr.typeArgs.length ? '<' + expr.typeArgs.map(typeName).join(', ') + '>' : '') + '(';
173
+ const values = expr.args.map((arg, index) => (expr.argLabels[index] ? expr.argLabels[index] + '=' : '') + this.expression(arg));
174
+ value = this.delimited(open, values, ')', this.inline(expr.span.end));
175
+ }
165
176
  else if (expr.kind === 'collection') {
166
177
  const open = expr.collection === 'List' ? '[' : expr.collection === 'Tuple' ? '(' : '{';
167
178
  const close = open === '[' ? ']' : open === '(' ? ')' : '}';
168
179
  const values = expr.collection === 'Map' ? expr.items.filter((_, index) => index % 2 === 0).map((item, index) => `${this.expression(item)}: ${this.expression(expr.items[index * 2 + 1])}`) : expr.items.map(item => this.expression(item));
169
- value = open + values.join(', ') + (expr.collection === 'Tuple' && values.length === 1 ? ',' : '') + this.inline(expr.span.end) + close;
180
+ value = this.delimited(open, values, close, (expr.collection === 'Tuple' && values.length === 1 ? ',' : '') + this.inline(expr.span.end));
170
181
  }
171
182
  else if (expr.kind === 'unary') {
172
183
  const power = expr.op === '!' ? 2.5 : 7;
@@ -232,7 +243,7 @@ class Printer {
232
243
  item(item) {
233
244
  this.before('annotations' in item ? item.annotations?.[0]?.span.start ?? item.span.start : item.span.start);
234
245
  if (item.kind === 'import') {
235
- this.line(`import ${item.everything ? 'everything' : item.names.join(' and ')} from ${item.from.join('.')}`);
246
+ this.line(`import ${item.everything ? 'everything' : item.names.join(' and ')} from ${importSource(item.from)}`);
236
247
  }
237
248
  else if (item.kind === 'export')
238
249
  this.line('export ' + (item.folder ? 'folder ' + item.name : `${item.name} from ${item.from}`));
@@ -243,20 +254,22 @@ class Printer {
243
254
  (item.lifetime ? ' ' + item.lifetime : '') + (item.sharedMutation ? ' mutable' : ''));
244
255
  else if (item.kind === 'composition')
245
256
  this.block('composition ' + item.name, () => item.bindings.forEach(binding => this.item(binding)), item.span);
257
+ else if (item.kind === 'resource')
258
+ this.line('extern C resource ' + item.name);
246
259
  else if (item.kind === 'function')
247
260
  this.method(item);
248
261
  else if (item.kind === 'class') {
249
262
  this.annotations(item.annotations);
250
263
  const header = `${item.record ? 'record ' : ''}${item.name}${this.generics(item)}(${item.fields.map(field => this.param(field, true)).join(', ')})`;
264
+ const errors = item.validationErrors?.length ? ` unless ${item.validationErrors.map(typeName).join(' and ')}` : '';
251
265
  if (item.record) {
252
- const errors = item.validationErrors?.length ? ` unless ${item.validationErrors.map(typeName).join(' and ')}` : '';
253
266
  if (item.constructorBody)
254
267
  this.block(header + errors, () => this.initializer(item), item.span);
255
268
  else
256
269
  this.line(header + errors);
257
270
  }
258
271
  else {
259
- this.block(header + ' implements ' + item.implements.map(typeName).join(', '), () => {
272
+ this.block(header + errors + ' implements ' + item.implements.map(typeName).join(', '), () => {
260
273
  for (const field of item.stateFields ?? []) {
261
274
  this.before(field.span.start);
262
275
  this.line(`${field.mutable ? 'mutable ' : ''}${typeName(field.type)} ${field.name} = ${this.expression(field.initializer)}`);
@@ -0,0 +1,137 @@
1
+ import { createHash } from 'node:crypto';
2
+ import { cpSync, existsSync, lstatSync, mkdirSync, mkdtempSync, readFileSync, readdirSync, renameSync, rmSync, writeFileSync } from 'node:fs';
3
+ import { dirname, join, resolve } from 'node:path';
4
+ import { homedir } from 'node:os';
5
+ import { fileURLToPath } from 'node:url';
6
+ import { gitReference, sourceAlias } from "./git-packages.js";
7
+ import { withPackageLockAsync } from "./package-locking.js";
8
+ const selected = (name) => !name.split('/').some(part => part.startsWith('.')) && (name.endsWith('.aug') || ['aug-package.json', 'package.json', 'main.yaml', 'README.md', 'LICENSE', 'native.abi.json', 'THIRD_PARTY_NOTICES.md'].includes(name));
9
+ async function bytes(url, maximum) {
10
+ const address = new URL(url);
11
+ if (address.protocol !== 'https:' || !['api.github.com', 'raw.githubusercontent.com'].includes(address.hostname) || address.username || address.password)
12
+ throw new Error('Invalid source transport URL');
13
+ const headers = { Accept: 'application/vnd.github+json', 'User-Agent': 'August-source-packages' };
14
+ // Only the API receives an explicitly supplied token. Raw downloads and
15
+ // redirects cannot carry it, and it never enters package metadata or logs.
16
+ if (address.hostname === 'api.github.com' && process.env.AUG_GITHUB_TOKEN)
17
+ headers.Authorization = 'Bearer ' + process.env.AUG_GITHUB_TOKEN;
18
+ const response = await fetch(address, { redirect: 'error', signal: AbortSignal.timeout(60000), headers });
19
+ if (!response.ok || !response.body)
20
+ throw new Error(`Cannot read public GitHub source (${response.status}). Check the repository/revision. For API rate limits, retry later or supply AUG_GITHUB_TOKEN for authenticated public reads.`);
21
+ if (Number(response.headers.get('content-length') ?? 0) > maximum)
22
+ throw new Error('GitHub source response exceeds its size limit');
23
+ const chunks = [];
24
+ let length = 0;
25
+ for await (const chunk of response.body) {
26
+ length += chunk.length;
27
+ if (length > maximum)
28
+ throw new Error('GitHub source response exceeds its size limit');
29
+ chunks.push(Buffer.from(chunk));
30
+ }
31
+ return Buffer.concat(chunks);
32
+ }
33
+ /** Public GitHub snapshots use HTTPS objects, so consumers do not need Git or an SDK. */
34
+ export async function materializeGitHub(request, destination, offline, locked) {
35
+ const reference = gitReference(request), url = new URL(reference.repository), parts = url.pathname.split('/').filter(Boolean), owner = parts[0], repo = parts[1]?.replace(/\.git$/, '');
36
+ if (url.hostname !== 'github.com' || parts.length !== 2 || !owner || !repo)
37
+ throw new Error('GitHub transport requires an owner/repository URL');
38
+ if (locked && (locked.repository !== reference.repository || locked.folder !== reference.folder || locked.revision !== reference.revision || !/^[0-9a-f]{40}$/.test(locked.commit)))
39
+ throw new Error('Invalid locked GitHub source identity');
40
+ const cache = resolve(process.env.AUG_PACKAGE_CACHE ?? join(homedir(), '.cache/augscript/packages'));
41
+ const base = join(cache, 'https-' + sourceAlias(reference.repository) + '-' + sourceAlias(reference.folder));
42
+ mkdirSync(base, { recursive: true });
43
+ return withPackageLockAsync(base + '.lock', async () => {
44
+ let commit = locked?.commit;
45
+ const revisionCache = join(base, 'revision-' + sourceAlias(reference.revision) + '.json');
46
+ if (!commit && offline && existsSync(revisionCache))
47
+ commit = JSON.parse(readFileSync(revisionCache, 'utf8')).commit;
48
+ if (!commit) {
49
+ if (offline)
50
+ throw new Error('GitHub revision is not cached. Run aug install online once: ' + request);
51
+ const value = JSON.parse((await bytes(`https://api.github.com/repos/${encodeURIComponent(owner)}/${encodeURIComponent(repo)}/commits/${encodeURIComponent(reference.revision)}`, 4 * 1024 * 1024)).toString());
52
+ commit = value.sha;
53
+ if (!/^[0-9a-f]{40}$/.test(commit))
54
+ throw new Error('GitHub did not resolve an exact commit');
55
+ }
56
+ if (!/^[0-9a-f]{40}$/.test(commit))
57
+ throw new Error('Invalid cached GitHub revision');
58
+ const snapshot = join(base, commit), metadata = join(base, commit + '.json');
59
+ if (!existsSync(snapshot) || !existsSync(metadata)) {
60
+ if (offline)
61
+ throw new Error('Locked GitHub source is not cached: ' + commit);
62
+ // An interrupted installation may leave either half of the cache entry.
63
+ // The exclusive writer discards that incomplete entry before retrying.
64
+ rmSync(snapshot, { recursive: true, force: true });
65
+ rmSync(metadata, { force: true });
66
+ const tree = JSON.parse((await bytes(`https://api.github.com/repos/${encodeURIComponent(owner)}/${encodeURIComponent(repo)}/git/trees/${commit}?recursive=1`, 16 * 1024 * 1024)).toString());
67
+ if (tree.truncated || !Array.isArray(tree.tree))
68
+ throw new Error('GitHub source tree coverage is incomplete; installation stopped');
69
+ const prefix = reference.folder ? reference.folder + '/' : '';
70
+ const entries = tree.tree.filter((e) => e.type === 'blob' && typeof e.path === 'string' && e.path.startsWith(prefix) && selected(e.path.slice(prefix.length)));
71
+ if (!entries.length || entries.length > 10000)
72
+ throw new Error('GitHub package has no source files or exceeds its file limit');
73
+ const stage = mkdtempSync(join(base, '.snapshot-'));
74
+ let total = 0;
75
+ const digests = {};
76
+ try {
77
+ // Bounded concurrency avoids one network round trip per source file.
78
+ for (let i = 0; i < entries.length; i += 8) {
79
+ const batch = await Promise.allSettled(entries.slice(i, i + 8).map(async (entry) => {
80
+ const name = entry.path.slice(prefix.length);
81
+ if (!['100644', '100755'].includes(entry.mode) || name.includes('\\') || name.split('/').some((p) => !p || p === '.' || p === '..' || p.startsWith('.')) || !/^[0-9a-f]{40}$/.test(entry.sha))
82
+ throw new Error('GitHub package source must be regular files inside its folder: ' + name);
83
+ const content = await bytes(`https://raw.githubusercontent.com/${encodeURIComponent(owner)}/${encodeURIComponent(repo)}/${commit}/${entry.path.split('/').map(encodeURIComponent).join('/')}`, 32 * 1024 * 1024);
84
+ total += content.length;
85
+ if (total > 32 * 1024 * 1024)
86
+ throw new Error('GitHub source package exceeds 32 MiB');
87
+ const actual = createHash('sha1').update('blob ' + content.length + '\0').update(content).digest('hex');
88
+ if (actual !== entry.sha)
89
+ throw new Error('GitHub source blob identity differs from the resolved tree');
90
+ digests[name] = createHash('sha256').update(content).digest('hex');
91
+ mkdirSync(dirname(join(stage, name)), { recursive: true });
92
+ writeFileSync(join(stage, name), content);
93
+ }));
94
+ const rejected = batch.find(r => r.status === 'rejected');
95
+ if (rejected?.status === 'rejected')
96
+ throw rejected.reason;
97
+ }
98
+ renameSync(stage, snapshot);
99
+ writeFileSync(metadata, JSON.stringify({ format: 1, commit, files: digests }));
100
+ }
101
+ finally {
102
+ rmSync(stage, { recursive: true, force: true });
103
+ }
104
+ }
105
+ const facts = JSON.parse(readFileSync(metadata, 'utf8'));
106
+ if (facts.format !== 1 || facts.commit !== commit || !facts.files)
107
+ throw new Error('Invalid cached GitHub source metadata');
108
+ const list = (folder, prefix = '') => readdirSync(folder, { withFileTypes: true }).flatMap(entry => {
109
+ if (entry.isSymbolicLink())
110
+ throw new Error('Cached GitHub source cannot contain symbolic links');
111
+ const path = prefix + entry.name;
112
+ return entry.isDirectory() ? list(join(folder, entry.name), path + '/') : entry.isFile() ? [path] : (() => { throw new Error('Cached GitHub source requires regular files'); })();
113
+ });
114
+ if (lstatSync(snapshot).isSymbolicLink() || JSON.stringify(list(snapshot).sort()) !== JSON.stringify(Object.keys(facts.files).sort()))
115
+ throw new Error('Cached GitHub source file set differs from the resolved snapshot');
116
+ for (const [name, digest] of Object.entries(facts.files)) {
117
+ if (name.includes('\\') || name.split('/').some(p => !p || p === '.' || p === '..' || p.startsWith('.')))
118
+ throw new Error('Cached source path escapes its snapshot');
119
+ if (createHash('sha256').update(readFileSync(join(snapshot, name))).digest('hex') !== digest)
120
+ throw new Error('Cached GitHub source changed: ' + name);
121
+ }
122
+ cpSync(snapshot, destination, { recursive: true });
123
+ writeFileSync(revisionCache, JSON.stringify({ commit }));
124
+ return { ...reference, commit: commit };
125
+ });
126
+ }
127
+ if (process.argv[1] && resolve(process.argv[1]) === fileURLToPath(import.meta.url) && process.argv[2] === '--materialize') {
128
+ try {
129
+ const input = JSON.parse(process.argv[3]);
130
+ const result = await materializeGitHub(input.request, input.destination, input.offline, input.locked);
131
+ process.stdout.write(JSON.stringify(result));
132
+ }
133
+ catch (error) {
134
+ process.stderr.write((error instanceof Error ? error.message : String(error)) + '\n');
135
+ process.exitCode = 1;
136
+ }
137
+ }