@greenpandastudios/aug-cli 0.19.0 → 0.20.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (459) 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/compatibility.md +3 -3
  12. package/docs/contributing-benchmarks.md +38 -0
  13. package/docs/dev-containers.md +95 -0
  14. package/docs/diagnostics.md +15 -5
  15. package/docs/docker.md +174 -12
  16. package/docs/editor.md +35 -0
  17. package/docs/example-projects.json +206 -24
  18. package/docs/examples/approved-design/counters.md +34 -126
  19. package/docs/examples/approved-design/dependencies/august/0.20.1/io/contracts.md +178 -0
  20. package/docs/examples/approved-design/domain/app.md +13 -77
  21. package/docs/examples/approved-design/domain/export.md +5 -19
  22. package/docs/examples/approved-design/domain/models.md +4 -23
  23. package/docs/examples/approved-design/domain/numbers.md +24 -114
  24. package/docs/examples/approved-design/index.md +16 -7
  25. package/docs/examples/approved-design/main.md +19 -96
  26. package/docs/examples/benchmark/index.md +6 -5
  27. package/docs/examples/benchmark/main.md +7 -35
  28. package/docs/examples/cli-args/index.md +6 -5
  29. package/docs/examples/cli-args/main.md +6 -31
  30. package/docs/examples/collections/index.md +6 -5
  31. package/docs/examples/collections/main.md +7 -35
  32. package/docs/examples/collections-benchmark/index.md +6 -5
  33. package/docs/examples/collections-benchmark/main.md +7 -35
  34. package/docs/examples/cpu-benchmark/index.md +6 -5
  35. package/docs/examples/cpu-benchmark/main.md +5 -24
  36. package/docs/examples/developer-workflow/calculator.md +39 -186
  37. package/docs/examples/developer-workflow/dependencies/august/0.20.1/io/contracts.md +178 -0
  38. package/docs/examples/developer-workflow/index.md +16 -7
  39. package/docs/examples/developer-workflow/logging/console.md +10 -56
  40. package/docs/examples/developer-workflow/logging/export.md +4 -14
  41. package/docs/examples/developer-workflow/logging/logger.md +7 -43
  42. package/docs/examples/developer-workflow/main.md +17 -69
  43. package/docs/examples/drop/index.md +6 -5
  44. package/docs/examples/drop/main.md +7 -27
  45. package/docs/examples/drop/resource.md +7 -30
  46. package/docs/examples/errors/errors.md +7 -27
  47. package/docs/examples/errors/index.md +6 -5
  48. package/docs/examples/errors/main.md +7 -28
  49. package/docs/examples/ffi/index.md +6 -5
  50. package/docs/examples/ffi/main.md +6 -20
  51. package/docs/examples/ffi/native.md +8 -34
  52. package/docs/examples/generic-di/dependencies/august/0.20.1/io/contracts.md +178 -0
  53. package/docs/examples/generic-di/index.md +6 -5
  54. package/docs/examples/generic-di/main.md +9 -39
  55. package/docs/examples/generic-di/types.md +23 -92
  56. package/docs/examples/generics/index.md +6 -5
  57. package/docs/examples/generics/main.md +10 -47
  58. package/docs/examples/generics/types.md +25 -100
  59. package/docs/examples/hello/app/export.md +4 -12
  60. package/docs/examples/hello/app/greeter.md +13 -91
  61. package/docs/examples/hello/dependencies/august/0.20.1/io/contracts.md +178 -0
  62. package/docs/examples/hello/index.md +17 -6
  63. package/docs/examples/hello/logging/console.md +10 -54
  64. package/docs/examples/hello/logging/export.md +4 -14
  65. package/docs/examples/hello/logging/logger.md +7 -45
  66. package/docs/examples/hello/main.md +9 -39
  67. package/docs/examples/http-benchmark/index.md +6 -5
  68. package/docs/examples/http-benchmark/main.md +6 -20
  69. package/docs/examples/http-benchmark/routes.md +9 -31
  70. package/docs/examples/index.md +46 -29
  71. package/docs/examples/interceptors/app.md +20 -139
  72. package/docs/examples/interceptors/dependencies/august/0.20.1/io/contracts.md +178 -0
  73. package/docs/examples/interceptors/index.md +6 -5
  74. package/docs/examples/interceptors/interceptors.md +24 -148
  75. package/docs/examples/interceptors/logging.md +13 -76
  76. package/docs/examples/interceptors/main.md +10 -65
  77. package/docs/examples/json-benchmark/data.md +4 -20
  78. package/docs/examples/json-benchmark/dependencies/packages/@git/url_2d3c37c690c0fa115be1/0.0.0-git.a39fc582565d4fca40be4f75fa304d71adc69301/contracts.md +67 -0
  79. package/docs/examples/json-benchmark/index.md +7 -5
  80. package/docs/examples/json-benchmark/main-yaml.md +20 -0
  81. package/docs/examples/json-benchmark/main.md +10 -49
  82. package/docs/examples/new-syntax/console.md +10 -52
  83. package/docs/examples/new-syntax/dependencies/august/0.20.1/io/contracts.md +178 -0
  84. package/docs/examples/new-syntax/greeter.md +13 -71
  85. package/docs/examples/new-syntax/index.md +6 -5
  86. package/docs/examples/new-syntax/logger.md +7 -43
  87. package/docs/examples/new-syntax/main.md +10 -53
  88. package/docs/examples/new-syntax/math.md +6 -24
  89. package/docs/examples/oidc-login/client/contracts.md +10 -61
  90. package/docs/examples/oidc-login/client/endpoints.md +32 -154
  91. package/docs/examples/oidc-login/client/export.md +5 -23
  92. package/docs/examples/oidc-login/client/login.md +234 -344
  93. package/docs/examples/oidc-login/client/logout.md +38 -143
  94. package/docs/examples/oidc-login/client/protocol.md +183 -304
  95. package/docs/examples/oidc-login/client/session.md +41 -149
  96. package/docs/examples/oidc-login/client/views.md +13 -58
  97. package/docs/examples/oidc-login/common/export.md +6 -26
  98. package/docs/examples/oidc-login/common/headers.md +42 -72
  99. package/docs/examples/oidc-login/common/keys.md +40 -164
  100. package/docs/examples/oidc-login/common/settings.md +24 -40
  101. package/docs/examples/oidc-login/common/views.md +7 -28
  102. package/docs/examples/oidc-login/dependencies/packages/@git/url_0eb7c89453c87681ed15/0.0.0-git.a39fc582565d4fca40be4f75fa304d71adc69301/store.md +205 -0
  103. package/docs/examples/oidc-login/dependencies/packages/@git/url_2d3c37c690c0fa115be1/0.0.0-git.a39fc582565d4fca40be4f75fa304d71adc69301/contracts.md +67 -0
  104. package/docs/examples/oidc-login/dependencies/packages/@git/url_897efafd565158fc4908/0.0.0-git.a39fc582565d4fca40be4f75fa304d71adc69301/contracts.md +267 -0
  105. package/docs/examples/oidc-login/dependencies/packages/@git/url_9ef654c66d34ab8f5527/0.0.0-git.b14a0f9aa41f1ce58bd51133bcdc424033e40d40/contracts.md +415 -0
  106. package/docs/examples/oidc-login/dependencies/packages/@git/url_9ef654c66d34ab8f5527/0.0.0-git.b14a0f9aa41f1ce58bd51133bcdc424033e40d40/jose.md +271 -0
  107. package/docs/examples/oidc-login/dependencies/packages/@git/url_c092cd151499c4e1d8a1/0.0.0-git.a39fc582565d4fca40be4f75fa304d71adc69301/contracts.md +89 -0
  108. package/docs/examples/oidc-login/index.md +8 -7
  109. package/docs/examples/oidc-login/main-yaml.md +7 -0
  110. package/docs/examples/oidc-login/main.md +26 -153
  111. package/docs/examples/oidc-login/provider/authorization.md +232 -275
  112. package/docs/examples/oidc-login/provider/contracts.md +24 -146
  113. package/docs/examples/oidc-login/provider/credentials.md +24 -57
  114. package/docs/examples/oidc-login/provider/discovery.md +48 -122
  115. package/docs/examples/oidc-login/provider/export.md +11 -37
  116. package/docs/examples/oidc-login/provider/token.md +159 -237
  117. package/docs/examples/oidc-login/provider/userinfo.md +47 -102
  118. package/docs/examples/oidc-login/provider/views.md +13 -53
  119. package/docs/examples/ownership/counter.md +17 -63
  120. package/docs/examples/ownership/index.md +6 -5
  121. package/docs/examples/ownership/main.md +7 -30
  122. package/docs/examples/ownership-transfer/dependencies/august/0.20.1/io/contracts.md +178 -0
  123. package/docs/examples/ownership-transfer/index.md +6 -5
  124. package/docs/examples/ownership-transfer/main.md +10 -52
  125. package/docs/examples/ownership-transfer/resource.md +15 -67
  126. package/docs/examples/packages-app/dependencies/packages/@example/aug-math/0.1.0/arithmetic.md +12 -50
  127. package/docs/examples/packages-app/index.md +7 -6
  128. package/docs/examples/packages-app/main.md +7 -25
  129. package/docs/examples/packages-math/aug-package-json.md +1 -1
  130. package/docs/examples/packages-math/index.md +7 -6
  131. package/docs/examples/packages-math/src/arithmetic.md +12 -50
  132. package/docs/examples/packages-math/src/export.md +4 -12
  133. package/docs/examples/startup-benchmark/index.md +6 -5
  134. package/docs/examples/startup-benchmark/main.md +5 -17
  135. package/docs/examples/visibility/counter.md +19 -67
  136. package/docs/examples/visibility/index.md +6 -5
  137. package/docs/examples/visibility/main.md +7 -31
  138. package/docs/examples/weather-api/forecasts.md +168 -0
  139. package/docs/examples/weather-api/index.md +42 -0
  140. package/docs/examples/weather-api/main-yaml.md +21 -0
  141. package/docs/examples/weather-api/main.md +65 -0
  142. package/docs/examples.json +10 -0
  143. package/docs/getting-started.md +105 -2
  144. package/docs/grammar.md +6 -4
  145. package/docs/guides/change-a-module.md +64 -0
  146. package/docs/guides/index.md +27 -0
  147. package/docs/index.md +51 -29
  148. package/docs/language-conformance.md +1 -1
  149. package/docs/language-constructs.md +22 -22
  150. package/docs/language-design-audit.md +1 -1
  151. package/docs/learn/data-and-errors.md +77 -0
  152. package/docs/learn/index.md +30 -0
  153. package/docs/learn/modules-and-dependencies.md +73 -0
  154. package/docs/learn/state-and-tests.md +71 -0
  155. package/docs/learn/values-and-functions.md +62 -0
  156. package/docs/lesson-failures.json +8 -0
  157. package/docs/maintaining-docs.md +16 -4
  158. package/docs/packages.md +72 -126
  159. package/docs/performance.md +13 -41
  160. package/docs/production-readiness.md +5 -4
  161. package/docs/public/downloads/approved-design.zip +0 -0
  162. package/docs/public/downloads/benchmark.zip +0 -0
  163. package/docs/public/downloads/cli-args.zip +0 -0
  164. package/docs/public/downloads/collections-benchmark.zip +0 -0
  165. package/docs/public/downloads/collections.zip +0 -0
  166. package/docs/public/downloads/cpu-benchmark.zip +0 -0
  167. package/docs/public/downloads/developer-workflow.zip +0 -0
  168. package/docs/public/downloads/drop.zip +0 -0
  169. package/docs/public/downloads/errors.zip +0 -0
  170. package/docs/public/downloads/ffi.zip +0 -0
  171. package/docs/public/downloads/generic-di.zip +0 -0
  172. package/docs/public/downloads/generics.zip +0 -0
  173. package/docs/public/downloads/hello.zip +0 -0
  174. package/docs/public/downloads/http-benchmark.zip +0 -0
  175. package/docs/public/downloads/interceptors.zip +0 -0
  176. package/docs/public/downloads/json-benchmark.zip +0 -0
  177. package/docs/public/downloads/new-syntax.zip +0 -0
  178. package/docs/public/downloads/oidc-login.zip +0 -0
  179. package/docs/public/downloads/ownership-transfer.zip +0 -0
  180. package/docs/public/downloads/ownership.zip +0 -0
  181. package/docs/public/downloads/packages-app.zip +0 -0
  182. package/docs/public/downloads/packages-math.zip +0 -0
  183. package/docs/public/downloads/startup-benchmark.zip +0 -0
  184. package/docs/public/downloads/visibility.zip +0 -0
  185. package/docs/public/downloads/weather-api.zip +0 -0
  186. package/docs/reference.md +23 -17
  187. package/docs/releasing.md +29 -15
  188. package/docs/research/code-to-natural-language.md +108 -0
  189. package/docs/research/ecosystem-workflow.md +41 -0
  190. package/docs/research/wiki-editorial-design.md +71 -0
  191. package/docs/roadmap.md +1 -1
  192. package/docs/specifications.md +27 -11
  193. package/docs/testing.md +19 -5
  194. package/docs/tooling.md +25 -12
  195. package/docs/weather-api.md +65 -0
  196. package/docs/web.md +50 -18
  197. package/docs/writing-docs.md +49 -0
  198. package/examples/{hello/.aug-spec/august/0.19.0 → approved-design/.aug-spec/august/0.20.1}/io/contracts.aug +4 -3
  199. package/examples/approved-design/.aug-spec/august/0.20.1/io/contracts.aug.md +82 -0
  200. package/examples/approved-design/.aug-spec/manifest.json +3 -3
  201. package/examples/approved-design/counters.aug +5 -4
  202. package/examples/approved-design/counters.aug.md +25 -132
  203. package/examples/approved-design/domain/app.aug +2 -1
  204. package/examples/approved-design/domain/app.aug.md +10 -80
  205. package/examples/approved-design/domain/export.aug +1 -0
  206. package/examples/approved-design/domain/export.aug.md +4 -20
  207. package/examples/approved-design/domain/models.aug +1 -0
  208. package/examples/approved-design/domain/models.aug.md +3 -25
  209. package/examples/approved-design/domain/numbers.aug +3 -2
  210. package/examples/approved-design/domain/numbers.aug.md +19 -116
  211. package/examples/approved-design/main.aug +1 -0
  212. package/examples/approved-design/main.aug.md +12 -95
  213. package/examples/benchmark/.aug-spec/manifest.json +1 -1
  214. package/examples/benchmark/main.aug +1 -0
  215. package/examples/benchmark/main.aug.md +6 -36
  216. package/examples/cli-args/.aug-spec/manifest.json +1 -1
  217. package/examples/cli-args/main.aug +1 -0
  218. package/examples/cli-args/main.aug.md +5 -32
  219. package/examples/collections/.aug-spec/manifest.json +1 -1
  220. package/examples/collections/main.aug +1 -0
  221. package/examples/collections/main.aug.md +6 -36
  222. package/examples/{generic-di/.aug-spec/august/0.19.0 → developer-workflow/.aug-spec/august/0.20.1}/io/contracts.aug +4 -3
  223. package/examples/developer-workflow/.aug-spec/august/0.20.1/io/contracts.aug.md +82 -0
  224. package/examples/developer-workflow/.aug-spec/manifest.json +3 -3
  225. package/examples/developer-workflow/calculator.aug +3 -2
  226. package/examples/developer-workflow/calculator.aug.md +28 -189
  227. package/examples/developer-workflow/logging/console.aug +2 -1
  228. package/examples/developer-workflow/logging/console.aug.md +7 -57
  229. package/examples/developer-workflow/logging/export.aug +1 -0
  230. package/examples/developer-workflow/logging/export.aug.md +3 -15
  231. package/examples/developer-workflow/logging/logger.aug +1 -0
  232. package/examples/developer-workflow/logging/logger.aug.md +6 -46
  233. package/examples/developer-workflow/main.aug +1 -0
  234. package/examples/developer-workflow/main.aug.md +10 -68
  235. package/examples/drop/.aug-spec/manifest.json +1 -1
  236. package/examples/drop/main.aug +1 -0
  237. package/examples/drop/main.aug.md +6 -28
  238. package/examples/drop/resource.aug +1 -0
  239. package/examples/drop/resource.aug.md +6 -34
  240. package/examples/errors/.aug-spec/manifest.json +1 -1
  241. package/examples/errors/errors.aug +2 -1
  242. package/examples/errors/errors.aug.md +4 -27
  243. package/examples/errors/main.aug +1 -0
  244. package/examples/errors/main.aug.md +6 -29
  245. package/examples/ffi/.aug-spec/manifest.json +1 -1
  246. package/examples/ffi/main.aug +1 -0
  247. package/examples/ffi/main.aug.md +5 -21
  248. package/examples/ffi/native.aug +2 -1
  249. package/examples/ffi/native.aug.md +5 -35
  250. package/examples/{approved-design/.aug-spec/august/0.19.0 → generic-di/.aug-spec/august/0.20.1}/io/contracts.aug +4 -3
  251. package/examples/generic-di/.aug-spec/august/0.20.1/io/contracts.aug.md +82 -0
  252. package/examples/generic-di/.aug-spec/manifest.json +3 -3
  253. package/examples/generic-di/main.aug +1 -0
  254. package/examples/generic-di/main.aug.md +8 -40
  255. package/examples/generic-di/types.aug +3 -2
  256. package/examples/generic-di/types.aug.md +18 -97
  257. package/examples/generics/.aug-spec/manifest.json +1 -1
  258. package/examples/generics/main.aug +1 -0
  259. package/examples/generics/main.aug.md +9 -48
  260. package/examples/generics/types.aug +4 -3
  261. package/examples/generics/types.aug.md +18 -104
  262. package/examples/{developer-workflow/.aug-spec/august/0.19.0 → hello/.aug-spec/august/0.20.1}/io/contracts.aug +4 -3
  263. package/examples/hello/.aug-spec/august/0.20.1/io/contracts.aug.md +82 -0
  264. package/examples/hello/.aug-spec/manifest.json +3 -3
  265. package/examples/hello/app/export.aug +1 -0
  266. package/examples/hello/app/export.aug.md +3 -13
  267. package/examples/hello/app/greeter.aug +2 -1
  268. package/examples/hello/app/greeter.aug.md +10 -94
  269. package/examples/hello/logging/console.aug +2 -1
  270. package/examples/hello/logging/console.aug.md +7 -55
  271. package/examples/hello/logging/export.aug +1 -0
  272. package/examples/hello/logging/export.aug.md +3 -15
  273. package/examples/hello/logging/logger.aug +1 -0
  274. package/examples/hello/logging/logger.aug.md +6 -48
  275. package/examples/hello/main.aug +1 -0
  276. package/examples/hello/main.aug.md +8 -40
  277. package/examples/interceptors/.aug-spec/august/0.20.1/io/contracts.aug +37 -0
  278. package/examples/interceptors/.aug-spec/august/0.20.1/io/contracts.aug.md +82 -0
  279. package/examples/interceptors/.aug-spec/manifest.json +3 -3
  280. package/examples/interceptors/app.aug +3 -2
  281. package/examples/interceptors/app.aug.md +15 -141
  282. package/examples/interceptors/interceptors.aug +3 -2
  283. package/examples/interceptors/interceptors.aug.md +19 -152
  284. package/examples/interceptors/logging.aug +2 -1
  285. package/examples/interceptors/logging.aug.md +10 -79
  286. package/examples/interceptors/main.aug +1 -0
  287. package/examples/interceptors/main.aug.md +9 -66
  288. package/examples/new-syntax/.aug-spec/august/0.20.1/io/contracts.aug +37 -0
  289. package/examples/new-syntax/.aug-spec/august/0.20.1/io/contracts.aug.md +82 -0
  290. package/examples/new-syntax/.aug-spec/manifest.json +3 -3
  291. package/examples/new-syntax/console.aug +2 -1
  292. package/examples/new-syntax/console.aug.md +7 -53
  293. package/examples/new-syntax/greeter.aug +2 -1
  294. package/examples/new-syntax/greeter.aug.md +10 -74
  295. package/examples/new-syntax/logger.aug +1 -0
  296. package/examples/new-syntax/logger.aug.md +6 -46
  297. package/examples/new-syntax/main.aug +1 -0
  298. package/examples/new-syntax/main.aug.md +9 -54
  299. package/examples/new-syntax/math.aug +2 -1
  300. package/examples/new-syntax/math.aug.md +3 -24
  301. package/examples/oidc-login/.aug-spec/manifest.json +13 -13
  302. package/examples/oidc-login/.aug-spec/packages/@git/url_0eb7c89453c87681ed15/0.0.0-git.a39fc582565d4fca40be4f75fa304d71adc69301/store.aug.md +71 -0
  303. package/examples/oidc-login/.aug-spec/packages/@git/url_2d3c37c690c0fa115be1/0.0.0-git.a39fc582565d4fca40be4f75fa304d71adc69301/contracts.aug.md +17 -0
  304. package/examples/oidc-login/.aug-spec/packages/@git/url_897efafd565158fc4908/0.0.0-git.a39fc582565d4fca40be4f75fa304d71adc69301/contracts.aug.md +125 -0
  305. package/examples/oidc-login/.aug-spec/{august/0.19.0/crypto → packages/@git/url_9ef654c66d34ab8f5527/0.0.0-git.b14a0f9aa41f1ce58bd51133bcdc424033e40d40}/contracts.aug +12 -11
  306. package/examples/oidc-login/.aug-spec/packages/@git/url_9ef654c66d34ab8f5527/0.0.0-git.b14a0f9aa41f1ce58bd51133bcdc424033e40d40/contracts.aug.md +244 -0
  307. package/examples/oidc-login/.aug-spec/{august/0.19.0/crypto → packages/@git/url_9ef654c66d34ab8f5527/0.0.0-git.b14a0f9aa41f1ce58bd51133bcdc424033e40d40}/jose.aug +6 -5
  308. package/examples/oidc-login/.aug-spec/packages/@git/url_9ef654c66d34ab8f5527/0.0.0-git.b14a0f9aa41f1ce58bd51133bcdc424033e40d40/jose.aug.md +71 -0
  309. package/examples/oidc-login/.aug-spec/packages/@git/url_c092cd151499c4e1d8a1/0.0.0-git.a39fc582565d4fca40be4f75fa304d71adc69301/contracts.aug.md +30 -0
  310. package/examples/oidc-login/aug.lock.json +100 -0
  311. package/examples/oidc-login/client/contracts.aug +1 -0
  312. package/examples/oidc-login/client/contracts.aug.md +9 -66
  313. package/examples/oidc-login/client/endpoints.aug +6 -5
  314. package/examples/oidc-login/client/endpoints.aug.md +13 -145
  315. package/examples/oidc-login/client/export.aug +1 -0
  316. package/examples/oidc-login/client/export.aug.md +4 -24
  317. package/examples/oidc-login/client/login.aug +7 -6
  318. package/examples/oidc-login/client/login.aug.md +25 -303
  319. package/examples/oidc-login/client/logout.aug +5 -4
  320. package/examples/oidc-login/client/logout.aug.md +13 -135
  321. package/examples/oidc-login/client/protocol.aug +7 -6
  322. package/examples/oidc-login/client/protocol.aug.md +36 -283
  323. package/examples/oidc-login/client/session.aug +5 -4
  324. package/examples/oidc-login/client/session.aug.md +12 -139
  325. package/examples/oidc-login/client/views.aug +3 -2
  326. package/examples/oidc-login/client/views.aug.md +8 -57
  327. package/examples/oidc-login/common/export.aug +1 -0
  328. package/examples/oidc-login/common/export.aug.md +5 -27
  329. package/examples/oidc-login/common/headers.aug +4 -3
  330. package/examples/oidc-login/common/headers.aug.md +9 -67
  331. package/examples/oidc-login/common/keys.aug +6 -5
  332. package/examples/oidc-login/common/keys.aug.md +29 -165
  333. package/examples/oidc-login/common/settings.aug +2 -1
  334. package/examples/oidc-login/common/settings.aug.md +5 -39
  335. package/examples/oidc-login/common/views.aug +2 -1
  336. package/examples/oidc-login/common/views.aug.md +4 -28
  337. package/examples/oidc-login/main.aug +6 -16
  338. package/examples/oidc-login/main.aug.md +17 -146
  339. package/examples/oidc-login/main.yaml +7 -0
  340. package/examples/oidc-login/provider/authorization.aug +7 -6
  341. package/examples/oidc-login/provider/authorization.aug.md +23 -238
  342. package/examples/oidc-login/provider/contracts.aug +1 -0
  343. package/examples/oidc-login/provider/contracts.aug.md +23 -158
  344. package/examples/oidc-login/provider/credentials.aug +3 -2
  345. package/examples/oidc-login/provider/credentials.aug.md +9 -53
  346. package/examples/oidc-login/provider/discovery.aug +4 -3
  347. package/examples/oidc-login/provider/discovery.aug.md +11 -118
  348. package/examples/oidc-login/provider/export.aug +1 -0
  349. package/examples/oidc-login/provider/export.aug.md +6 -34
  350. package/examples/oidc-login/provider/token.aug +6 -5
  351. package/examples/oidc-login/provider/token.aug.md +16 -204
  352. package/examples/oidc-login/provider/userinfo.aug +4 -3
  353. package/examples/oidc-login/provider/userinfo.aug.md +10 -92
  354. package/examples/oidc-login/provider/views.aug +3 -2
  355. package/examples/oidc-login/provider/views.aug.md +8 -52
  356. package/examples/ownership/.aug-spec/manifest.json +1 -1
  357. package/examples/ownership/counter.aug +3 -2
  358. package/examples/ownership/counter.aug.md +12 -66
  359. package/examples/ownership/main.aug +1 -0
  360. package/examples/ownership/main.aug.md +6 -31
  361. package/examples/ownership-transfer/.aug-spec/august/0.20.1/io/contracts.aug +37 -0
  362. package/examples/ownership-transfer/.aug-spec/august/0.20.1/io/contracts.aug.md +82 -0
  363. package/examples/ownership-transfer/.aug-spec/manifest.json +3 -3
  364. package/examples/ownership-transfer/main.aug +1 -0
  365. package/examples/ownership-transfer/main.aug.md +9 -53
  366. package/examples/ownership-transfer/resource.aug +2 -1
  367. package/examples/ownership-transfer/resource.aug.md +12 -71
  368. package/examples/packages/app/.aug-spec/manifest.json +1 -1
  369. package/examples/packages/app/.aug-spec/packages/@example/aug-math/0.1.0/arithmetic.aug +2 -1
  370. package/examples/packages/app/.aug-spec/packages/@example/aug-math/0.1.0/arithmetic.aug.md +9 -51
  371. package/examples/packages/app/main.aug +1 -0
  372. package/examples/packages/app/main.aug.md +6 -26
  373. package/examples/packages/math/.aug-spec/manifest.json +1 -1
  374. package/examples/packages/math/aug-package.json +1 -1
  375. package/examples/packages/math/src/arithmetic.aug +2 -1
  376. package/examples/packages/math/src/arithmetic.aug.md +9 -51
  377. package/examples/packages/math/src/export.aug +1 -0
  378. package/examples/packages/math/src/export.aug.md +3 -13
  379. package/examples/visibility/.aug-spec/manifest.json +1 -1
  380. package/examples/visibility/counter.aug +4 -3
  381. package/examples/visibility/counter.aug.md +12 -68
  382. package/examples/visibility/main.aug +1 -0
  383. package/examples/visibility/main.aug.md +6 -32
  384. package/examples/weather-api/.aug-spec/manifest.json +8 -0
  385. package/examples/weather-api/AGENTS.md +17 -0
  386. package/examples/weather-api/README.md +19 -0
  387. package/examples/weather-api/forecasts.aug +47 -0
  388. package/examples/weather-api/forecasts.aug.md +32 -0
  389. package/examples/weather-api/main.aug +4 -0
  390. package/examples/weather-api/main.aug.md +15 -0
  391. package/examples/weather-api/main.yaml +5 -0
  392. package/examples/weather-api/weather.http +5 -0
  393. package/package.json +3 -4
  394. package/scripts/bootstrap-native.mjs +181 -106
  395. package/scripts/native-setup.mjs +98 -0
  396. package/scripts/native-toolchain.mjs +28 -0
  397. package/src/builtins.js +1 -1
  398. package/src/checker.js +259 -72
  399. package/src/cli.js +114 -20
  400. package/src/codegen.js +1 -1
  401. package/src/config.js +1 -1
  402. package/src/contracts.js +10 -0
  403. package/src/editor.js +71 -16
  404. package/src/fixes.js +90 -2
  405. package/src/formatter.js +19 -8
  406. package/src/git-packages.js +110 -0
  407. package/src/help.js +24 -23
  408. package/src/http-contracts.js +14 -0
  409. package/src/http-policies.js +5 -5
  410. package/src/libraries.js +1 -1
  411. package/src/lsp.js +14 -5
  412. package/src/native.js +19 -13
  413. package/src/navigation.js +4 -2
  414. package/src/openapi.js +5 -4
  415. package/src/package-locking.js +45 -0
  416. package/src/package-manager.js +251 -67
  417. package/src/parser.js +13 -5
  418. package/src/policies.js +3 -3
  419. package/src/project-init.js +78 -4
  420. package/src/project.js +9 -7
  421. package/src/semantic.js +46 -2
  422. package/src/snippets.js +59 -0
  423. package/src/spec-hints.js +56 -0
  424. package/src/spec-tree.js +241 -0
  425. package/src/spec.js +626 -303
  426. package/docs/examples/approved-design/dependencies/august/0.19.0/io/contracts.md +0 -395
  427. package/docs/examples/developer-workflow/dependencies/august/0.19.0/io/contracts.md +0 -395
  428. package/docs/examples/generic-di/dependencies/august/0.19.0/io/contracts.md +0 -395
  429. package/docs/examples/hello/dependencies/august/0.19.0/io/contracts.md +0 -395
  430. package/docs/examples/interceptors/dependencies/august/0.19.0/io/contracts.md +0 -395
  431. package/docs/examples/json-benchmark/dependencies/august/0.19.0/json/contracts.md +0 -103
  432. package/docs/examples/new-syntax/dependencies/august/0.19.0/io/contracts.md +0 -395
  433. package/docs/examples/oidc-login/dependencies/august/0.19.0/crypto/contracts.md +0 -925
  434. package/docs/examples/oidc-login/dependencies/august/0.19.0/crypto/jose.md +0 -434
  435. package/docs/examples/oidc-login/dependencies/august/0.19.0/json/contracts.md +0 -103
  436. package/docs/examples/oidc-login/dependencies/august/0.19.0/memory/store.md +0 -374
  437. package/docs/examples/oidc-login/dependencies/august/0.19.0/time/contracts.md +0 -150
  438. package/docs/examples/oidc-login/dependencies/august/0.19.0/web/contracts.md +0 -532
  439. package/docs/examples/ownership-transfer/dependencies/august/0.19.0/io/contracts.md +0 -395
  440. package/examples/approved-design/.aug-spec/august/0.19.0/io/contracts.aug.md +0 -316
  441. package/examples/developer-workflow/.aug-spec/august/0.19.0/io/contracts.aug.md +0 -316
  442. package/examples/generic-di/.aug-spec/august/0.19.0/io/contracts.aug.md +0 -316
  443. package/examples/hello/.aug-spec/august/0.19.0/io/contracts.aug.md +0 -316
  444. package/examples/interceptors/.aug-spec/august/0.19.0/io/contracts.aug +0 -36
  445. package/examples/interceptors/.aug-spec/august/0.19.0/io/contracts.aug.md +0 -316
  446. package/examples/new-syntax/.aug-spec/august/0.19.0/io/contracts.aug +0 -36
  447. package/examples/new-syntax/.aug-spec/august/0.19.0/io/contracts.aug.md +0 -316
  448. package/examples/oidc-login/.aug-spec/august/0.19.0/crypto/contracts.aug.md +0 -791
  449. package/examples/oidc-login/.aug-spec/august/0.19.0/crypto/jose.aug.md +0 -266
  450. package/examples/oidc-login/.aug-spec/august/0.19.0/json/contracts.aug.md +0 -55
  451. package/examples/oidc-login/.aug-spec/august/0.19.0/memory/store.aug.md +0 -250
  452. package/examples/oidc-login/.aug-spec/august/0.19.0/time/contracts.aug.md +0 -96
  453. package/examples/oidc-login/.aug-spec/august/0.19.0/web/contracts.aug.md +0 -420
  454. package/examples/ownership-transfer/.aug-spec/august/0.19.0/io/contracts.aug +0 -36
  455. package/examples/ownership-transfer/.aug-spec/august/0.19.0/io/contracts.aug.md +0 -316
  456. /package/examples/oidc-login/.aug-spec/{august/0.19.0/memory → packages/@git/url_0eb7c89453c87681ed15/0.0.0-git.a39fc582565d4fca40be4f75fa304d71adc69301}/store.aug +0 -0
  457. /package/examples/oidc-login/.aug-spec/{august/0.19.0/json → packages/@git/url_2d3c37c690c0fa115be1/0.0.0-git.a39fc582565d4fca40be4f75fa304d71adc69301}/contracts.aug +0 -0
  458. /package/examples/oidc-login/.aug-spec/{august/0.19.0/web → packages/@git/url_897efafd565158fc4908/0.0.0-git.a39fc582565d4fca40be4f75fa304d71adc69301}/contracts.aug +0 -0
  459. /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/cli.js CHANGED
@@ -11,26 +11,53 @@ import { checkUnitTests, discoverTests, mergeTestAnalysis, uniqueDiagnostics } f
11
11
  import { describe, SemanticWorkspace } from "./semantic.js";
12
12
  import { formatFile, migrateFile } from "./formatter.js";
13
13
  import { updateSpecs } from "./spec.js";
14
+ import { updateSpecHints } from "./spec-hints.js";
14
15
  import { runLanguageServer } from "./lsp.js";
15
16
  import { benchmark, compileNative, writeCoverage } from "./native.js";
16
17
  import { generateOpenApi } from "./openapi.js";
17
- import { initPackage, installPackages, preparePackage, packPackage } from "./package-manager.js";
18
+ import { addPackage, initPackage, installPackages, preparePackage, packPackage, prepareRunPackages } from "./package-manager.js";
18
19
  import { initProject } from "./project-init.js";
20
+ import { prepareNativeDependencies } from '../scripts/native-setup.mjs';
21
+ function failureMessage(error) {
22
+ const message = error instanceof Error ? error.message : String(error);
23
+ if (error instanceof Error && 'code' in error && ['EACCES', 'EPERM', 'EROFS'].includes(String(error.code)))
24
+ return `${message}\nAugust needs a writable project and native cache. Check the folder permissions, or set AUG_NATIVE_HOME to a directory you own.`;
25
+ if (error instanceof Error && 'code' in error && error.code === 'ENOSPC')
26
+ return `${message}\nThere is not enough disk space to compile or prepare dependencies. Free space and retry aug run.`;
27
+ return message;
28
+ }
19
29
  function printDiagnostics(diagnostics, json, root) {
20
30
  if (json) {
21
31
  process.stdout.write(JSON.stringify(diagnostics.map(issue => ({ ...issue,
22
32
  help: diagnosticHelp[issue.code] }))) + '\n');
23
33
  return;
24
34
  }
35
+ const sources = new Map();
25
36
  for (const issue of diagnostics) {
26
- const file = issue.file.startsWith(root) ? issue.file.slice(root.length + 1) : issue.file;
37
+ const file = relative(root, issue.file) || issue.file;
27
38
  process.stderr.write(`${file}:${issue.line}:${issue.column}: ${issue.code}: ${issue.message}\n`);
39
+ try {
40
+ if (!sources.has(issue.file))
41
+ sources.set(issue.file, readFileSync(issue.file, 'utf8').split(/\r?\n/));
42
+ const line = sources.get(issue.file)?.[issue.line - 1];
43
+ if (line !== undefined) {
44
+ const column = Math.max(0, Math.min(line.length, issue.column - 1));
45
+ const start = Math.max(0, column - 70), end = Math.min(line.length, start + 150);
46
+ const text = (start ? '…' : '') + line.slice(start, end).replace(/\t/g, ' ') + (end < line.length ? '…' : '');
47
+ const padding = (start ? 1 : 0) + line.slice(start, column).replace(/\t/g, ' ').length;
48
+ process.stderr.write(` ${issue.line} | ${text}\n ${' '.repeat(String(issue.line).length)} | ${' '.repeat(padding)}^\n`);
49
+ }
50
+ }
51
+ catch { /* Source may have been removed; the location and help remain useful. */ }
52
+ if (diagnosticHelp[issue.code])
53
+ process.stderr.write(` help: ${diagnosticHelp[issue.code]}\n`);
28
54
  }
29
55
  }
30
56
  function usage() {
31
57
  process.stdout.write(`AugScript compiler\n\n` +
32
58
  `Usage: aug <init|check|build|run|emit-c|test|openapi|format|migrate|spec|bench|explain|context|lsp|symbols|definition|complete|hover|fixes|semantic-tokens> [project directory] [options] [-- args]\n` +
33
- `New application: aug init DIRECTORY\n` +
59
+ `New application: aug init DIRECTORY [--template hello|weather]\n` +
60
+ `Run: aug run [project directory] [--offline] [-- args] — prepare dependencies, compile, and start\n` +
34
61
  `Tests: aug test [project directory] [GROUP_NAME] [--group GROUP_NAME] [--list] [--coverage] [--json] [--timeout milliseconds]\n` +
35
62
  `Format: aug format [project directory] [--file path] [--write]\n` +
36
63
  `Specifications: aug spec [project directory] [--check] [--json]\n` +
@@ -38,7 +65,7 @@ function usage() {
38
65
  `Context: aug context [project directory] [--file path] [--name declaration] [--budget characters]\n` +
39
66
  `Benchmark: aug bench [project directory] [--iterations 10] [--warmup 2] [--json] [-- args]\n` +
40
67
  `Packages: aug package init DIRECTORY --name @owner/name; aug package pack DIRECTORY\n` +
41
- `Dependencies: aug install [project directory] [--frozen] [--offline]\n` +
68
+ `Dependencies: aug add URL --as NAME [--project DIRECTORY]; aug install [project directory] [--frozen|--update] [--offline]\n` +
42
69
  `Entry point: main.aug at the project root.\n`);
43
70
  }
44
71
  export async function main(argv) {
@@ -53,18 +80,46 @@ export async function main(argv) {
53
80
  usage();
54
81
  return 0;
55
82
  }
83
+ if (command === 'add') {
84
+ const aliasIndex = argv.indexOf('--as'), projectIndex = argv.indexOf('--project');
85
+ if (!argv[1] || argv[1].startsWith('--') || aliasIndex < 0 || !argv[aliasIndex + 1]) {
86
+ process.stderr.write('Use aug add URL --as NAME [--project DIRECTORY] [--offline]\n');
87
+ return 2;
88
+ }
89
+ for (let index = 2; index < argv.length; index++) {
90
+ if (['--as', '--project'].includes(argv[index])) {
91
+ if (!argv[++index] || argv[index].startsWith('--'))
92
+ return 2;
93
+ }
94
+ else if (argv[index] !== '--offline') {
95
+ process.stderr.write('Unknown add option: ' + argv[index] + '\n');
96
+ return 2;
97
+ }
98
+ }
99
+ try {
100
+ const alias = argv[aliasIndex + 1], root = resolve(projectIndex < 0 ? process.cwd() : argv[projectIndex + 1]);
101
+ const lock = addPackage(root, argv[1], alias, argv.includes('--offline'));
102
+ process.stdout.write(`Added ${alias}; installed ${lock.packages.length} source package(s).\nImport public names with: import NAME from ${alias}\n`);
103
+ return 0;
104
+ }
105
+ catch (error) {
106
+ process.stderr.write(failureMessage(error) + '\n');
107
+ return 1;
108
+ }
109
+ }
56
110
  if (command === 'init') {
57
- if (argv.length !== 2 || !argv[1] || argv[1].startsWith('--')) {
58
- process.stderr.write('Use aug init DIRECTORY\n');
111
+ const template = argv.length === 2 ? 'hello' : argv[2] === '--template' && argv.length === 4 ? argv[3] : undefined;
112
+ if (!argv[1] || argv[1].startsWith('--') || !['hello', 'weather'].includes(template ?? '')) {
113
+ process.stderr.write('Use aug init DIRECTORY [--template hello|weather]\n');
59
114
  return 2;
60
115
  }
61
116
  try {
62
- const root = initProject(argv[1]);
63
- process.stdout.write(`Created August application in ${root}\nNext: cd ${argv[1]} && aug check . && aug test . && aug run .\n`);
117
+ const root = initProject(argv[1], template);
118
+ process.stdout.write(`Created August application in ${root}\nNext: cd ${argv[1]}\n aug run\n`);
64
119
  return 0;
65
120
  }
66
121
  catch (error) {
67
- process.stderr.write(error.message + '\n');
122
+ process.stderr.write(failureMessage(error) + '\n');
68
123
  return 1;
69
124
  }
70
125
  }
@@ -73,17 +128,18 @@ export async function main(argv) {
73
128
  const root = resolve((command === 'install' ? argv[1] : argv[2]) && !(command === 'install' ? argv[1] : argv[2]).startsWith('--')
74
129
  ? (command === 'install' ? argv[1] : argv[2]) : process.cwd());
75
130
  if (command === 'install') {
76
- const lock = installPackages(root, argv.includes('--frozen'), argv.includes('--offline'));
131
+ const lock = installPackages(root, argv.includes('--frozen'), argv.includes('--offline'), argv.includes('--update'));
77
132
  process.stdout.write(`Installed ${lock.packages.length} August package(s); aug.lock.json is current.\n`);
78
133
  }
79
134
  else if (argv[1] === 'init') {
80
- const name = argv[argv.indexOf('--name') + 1];
81
- if (!argv.includes('--name') || !name)
82
- throw new Error('Use aug package init DIRECTORY --name @owner/name');
83
- initPackage(root, name);
135
+ const name = argv.includes('--name') ? argv[argv.indexOf('--name') + 1] : root.split(/[\\/]/).at(-1);
136
+ if (!name)
137
+ throw new Error('Use aug package init DIRECTORY [--name @owner/name]');
138
+ initPackage(root, name, argv.includes('--name'));
84
139
  process.stdout.write(`Created August library ${name} in ${root}\n`);
85
140
  }
86
141
  else if (argv[1] === 'pack') {
142
+ prepareRunPackages(root);
87
143
  preparePackage(root);
88
144
  const project = loadProject(root), checked = checkProject(project);
89
145
  const tests = checkUnitTests(project, discoverTests(project).tests);
@@ -101,7 +157,7 @@ export async function main(argv) {
101
157
  return 0;
102
158
  }
103
159
  catch (error) {
104
- process.stderr.write(error.message + '\n');
160
+ process.stderr.write(failureMessage(error) + '\n');
105
161
  return 1;
106
162
  }
107
163
  }
@@ -116,6 +172,26 @@ export async function main(argv) {
116
172
  const separator = argv.indexOf('--');
117
173
  const options = separator >= 0 ? argv.slice(1, separator) : argv.slice(1);
118
174
  const programArgs = separator >= 0 ? argv.slice(separator + 1) : [];
175
+ if (options.includes('--help')) {
176
+ usage();
177
+ return 0;
178
+ }
179
+ const valueOptions = new Set(['--out', '--stdin-file', '--file', '--name', '--offset', '--budget', '--baseline', '--group', '--case', '--timeout', '--iterations', '--warmup']);
180
+ const booleanOptions = new Set(['--json', '--coverage', '--list', '--write', '--check', '--offline']);
181
+ for (let index = 0; index < options.length; index++) {
182
+ const option = options[index];
183
+ if (valueOptions.has(option)) {
184
+ if (!options[index + 1] || options[index + 1].startsWith('--')) {
185
+ process.stderr.write(`${option} needs a value. See aug ${command} --help.\n`);
186
+ return 2;
187
+ }
188
+ index++;
189
+ }
190
+ else if (option.startsWith('-') && !booleanOptions.has(option)) {
191
+ process.stderr.write(`Unknown option ${option}. See aug ${command} --help. To pass an option to your program, put it after --.\n`);
192
+ return 2;
193
+ }
194
+ }
119
195
  const json = options.includes('--json');
120
196
  const outIndex = options.indexOf('--out');
121
197
  const outputOption = outIndex >= 0 ? options[outIndex + 1] : undefined;
@@ -171,6 +247,10 @@ export async function main(argv) {
171
247
  process.stdout.write(JSON.stringify(result) + '\n');
172
248
  return 0;
173
249
  }
250
+ if (!existsSync(root) || !statSync(root).isDirectory())
251
+ throw new Error(`Project directory does not exist: ${root}\nUse aug init DIRECTORY to create a project, or run aug run from the folder containing main.aug.`);
252
+ if (command === 'run')
253
+ prepareRunPackages(root, options.includes('--offline'));
174
254
  const project = loadProject(root, overrides);
175
255
  if (project.library && ['build', 'run', 'bench', 'openapi'].includes(command))
176
256
  throw new Error('This is an August library; use check, test, or package pack. Import its exports from an application with main.aug to run it.');
@@ -217,7 +297,9 @@ export async function main(argv) {
217
297
  const results = [];
218
298
  const coverage = options.includes('--coverage'), reports = [];
219
299
  for (const [index, { unit, checked: testChecked }] of checks.entries()) {
220
- const native = compileNative(root, generateC(testChecked, { coverage }), { testIndex: index, checked: testChecked });
300
+ const generated = generateC(testChecked, { coverage });
301
+ await prepareNativeDependencies(generated, { offline: options.includes('--offline') });
302
+ const native = compileNative(root, generated, { testIndex: index, checked: testChecked });
221
303
  const report = join(root, '.aug-build', 'tests', `coverage-${index}.tsv`);
222
304
  reports.push(report);
223
305
  if (coverage)
@@ -244,7 +326,7 @@ export async function main(argv) {
244
326
  `${passed} passed, ${failed} failed\n` + (report ? `Coverage: ${report.covered}/${report.executable} statement lines (${report.percent.toFixed(1)}%); ${report.path}\n` : ''));
245
327
  return failed ? 1 : 0;
246
328
  }
247
- const checked = checkProject(project);
329
+ let checked = checkProject(project);
248
330
  const testChecks = checkUnitTests(project, discovered.tests);
249
331
  checked.diagnostics = uniqueDiagnostics([...checked.diagnostics, ...discovered.diagnostics,
250
332
  ...testChecks.flatMap(entry => entry.checked.diagnostics)]);
@@ -305,6 +387,13 @@ export async function main(argv) {
305
387
  process.stdout.write(json ? JSON.stringify(result) + '\n' : result.stale.length ? 'Stale specifications:\n' + result.stale.map(file => ' ' + file).join('\n') + '\n' : `${result.files} specification artifact(s) ${options.includes('--check') ? 'are current' : 'generated'}.\n`);
306
388
  return result.stale.length ? 1 : 0;
307
389
  }
390
+ if (['build', 'run', 'bench'].includes(command)) {
391
+ checked = updateSpecHints(checked);
392
+ if (checked.diagnostics.some(issue => issue.severity !== 'warning')) {
393
+ printDiagnostics(checked.diagnostics, json, root);
394
+ return 1;
395
+ }
396
+ }
308
397
  const generated = generateC(checked);
309
398
  if (command === 'emit-c') {
310
399
  process.stdout.write(generated);
@@ -313,6 +402,7 @@ export async function main(argv) {
313
402
  if (command === 'bench' && (!Number.isInteger(iterations) || iterations < 1 || iterations > 1000 ||
314
403
  !Number.isInteger(warmup) || warmup < 0 || warmup > 100 || !Number.isInteger(timeout) || timeout < 1))
315
404
  throw new Error('bench requires iterations 1–1000, warmup 0–100, and a positive timeout');
405
+ await prepareNativeDependencies(generated, { offline: options.includes('--offline') });
316
406
  const native = compileNative(root, generated, { output: outputOption, release: command === 'bench' ? true : undefined, checked });
317
407
  const output = native.output;
318
408
  if (native.status !== 0) {
@@ -334,11 +424,15 @@ export async function main(argv) {
334
424
  }
335
425
  const run = spawnSync(output, programArgs, { stdio: 'inherit', cwd: root });
336
426
  if (run.error)
337
- throw run.error;
427
+ throw new Error(`Cannot start the compiled program ${output}: ${run.error.message}.\nCheck executable permissions and the native shared-library paths.`);
428
+ if (run.signal)
429
+ process.stderr.write(`Program stopped by ${run.signal}. Check the runtime message above; aug run compiled and started ${output}.\n`);
430
+ else if (run.status !== 0)
431
+ process.stderr.write(`Program exited with status ${run.status}.\n`);
338
432
  return run.status ?? 1;
339
433
  }
340
434
  catch (error) {
341
- process.stderr.write(`${error instanceof Error ? error.message : String(error)}\n`);
342
- return 1;
435
+ process.stderr.write(failureMessage(error) + '\n');
436
+ return error instanceof Error && 'exitCode' in error && typeof error.exitCode === 'number' ? error.exitCode : 1;
343
437
  }
344
438
  }
package/src/codegen.js CHANGED
@@ -154,7 +154,7 @@ class CGenerator {
154
154
  ` aug_register_globals(aug_bindings, ${bindingCount});`,
155
155
  ` aug_set_cli_args(argc, argv);`,
156
156
  ...([...this.activeFiles].some(file => this.checked.project.files.get(file)?.items.some(item => item.kind === 'function' && !!item.endpoint) ||
157
- [...this.checked.project.definitions.values()].some(def => def.file === file && def.id.startsWith('august/web/'))) ? [this.httpConfiguration()] : []),
157
+ this.checked.project.files.get(file)?.items.some(item => item.kind === 'function' && item.externC && item.name.startsWith('_aug_http_'))) ? [this.httpConfiguration()] : []),
158
158
  ...[...this.coverage.values()].map(point => ` aug_coverage_register(${cString(point.file)}, ${point.line});`),
159
159
  initializeBindings,
160
160
  ` AugValue result = aug_main_body(NULL, 0);`,
package/src/config.js CHANGED
@@ -55,7 +55,7 @@ export function loadConfig(root) {
55
55
  seen.add(path);
56
56
  if (path.startsWith('packages.')) {
57
57
  if (!/^[a-z][a-z0-9_]*$/.test(entry[1]) || entry[1] === 'august' || !value)
58
- report(index + 1, 'Packages map lowercase public aliases to local paths or npm:name@exact-version');
58
+ report(index + 1, 'Packages map lowercase public aliases to repository URLs, local paths, or npm:name@exact-version');
59
59
  else
60
60
  config.packages[entry[1]] = value;
61
61
  continue;
@@ -0,0 +1,10 @@
1
+ import { schemaType } from "./schemas.js";
2
+ import { tyName } from "./types.js";
3
+ /** Checked contracts shared by the editor, documentation and wire schemas. */
4
+ export function callableResult(checked, method) {
5
+ return checked.callableContracts.get(method)?.result ?? schemaType(checked.project, method.returns, method.span.file);
6
+ }
7
+ export function callableErrors(checked, method) {
8
+ return [...new Set([...(checked.callableContracts.get(method)?.errors.map(tyName) ?? method.throws.map(type => tyName(schemaType(checked.project, type, method.span.file)))),
9
+ ...(checked.interceptorPlans.get(method) ?? []).flatMap(layer => layer.errors.map(tyName))])].sort();
10
+ }
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,8 @@ 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";
15
18
  const builtins = [
16
19
  ...builtinFunctions.map(operation => {
17
20
  const parameters = operation.parameters.map(param => `${param.label}=${param.type}`);
@@ -24,6 +27,8 @@ const builtins = [
24
27
  .map(([label, help]) => ({ label, kind: 'type', detail: help.detail, documentation: help.documentation })),
25
28
  ];
26
29
  const keywords = [
30
+ ...snippetCatalog.map(snippet => ({ label: snippet.prefix + ' template', kind: 'snippet', detail: snippet.description,
31
+ documentation: snippet.description, insertText: snippet.body })),
27
32
  { label: 'initialize block', kind: 'snippet', detail: 'Constructor initialization inside a class or record', documentation: languageHelp.initialize.documentation,
28
33
  insertText: 'initialize:\n $0' },
29
34
  ...Object.entries(languageHelp).filter(([label, help]) => help.category === 'keyword' &&
@@ -38,7 +43,7 @@ const keywords = [
38
43
  insertText: 'borrow ${1:value} {\n $0\n}' },
39
44
  { label: 'interceptor declaration', kind: 'snippet', detail: 'Generic interceptor wrapping any result type',
40
45
  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}' },
46
+ insertText: 'interceptor ${1:Audit}<T>() {\n around() {\n result = next()\n $0\n return result\n }\n}' },
42
47
  { label: 'test suite', kind: 'snippet', detail: 'Same-file class tests with fresh setup per case',
43
48
  documentation: languageHelp.test.documentation,
44
49
  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 +64,18 @@ function parameterText(param) {
59
64
  `${typeName(param.type)} ${param.label ?? param.name}${param.label && param.label !== param.name ? ` to ${param.name}` : ''}` +
60
65
  (param.source ? ` from ${param.source.kind}${param.source.name ? ' ' + JSON.stringify(param.source.name) : ''}` : '');
61
66
  }
62
- function signature(method, callSite = false, additionalErrors = []) {
67
+ function signature(method, callSite = false, additionalErrors = [], checked) {
63
68
  const generic = method.typeParams.length ? `<${method.typeParams.join(', ')}>` : '';
64
69
  const params = callSite ? method.params.filter(param => !param.injected)
65
70
  .map(param => `${param.label ?? param.name}=${typeName(param.type)}`) : method.params.map(parameterText);
66
- const errors = [...new Set([...method.throws.map(typeName), ...additionalErrors])];
71
+ const errors = checked ? callableErrors(checked, method) : [...new Set([...method.throws.map(typeName), ...additionalErrors])];
72
+ const contract = checked?.effectContracts.get(method);
73
+ const changes = contract?.changes ?? method.changes ?? [];
74
+ const uses = [...(contract?.uses.values() ?? method.uses ?? [])].map(use => `${use.source}.${use.operation}`);
67
75
  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 ')}` : '') +
76
+ `${method.returnOwnership === 'own' ? 'own ' : ''}${checked ? tyName(callableResult(checked, method)) : typeName(method.returns)}` +
77
+ (changes.length ? ` changes ${changes.join(' and ')}` : '') +
78
+ (uses.length ? ` uses ${uses.join(' and ')}` : '') +
71
79
  (errors.length ? ` unless ${errors.join(', ')}` : '') +
72
80
  (method.endpoint && method.endpoint.status !== 200 ? ` with status ${method.endpoint.status}` : '');
73
81
  }
@@ -117,14 +125,14 @@ function methodDocumentation(checked, method, owner) {
117
125
  }
118
126
  function methodItem(checked, method, kind, owner) {
119
127
  const errors = (checked.interceptorPlans.get(method) ?? []).flatMap(layer => layer.errors.map(tyName));
120
- const label = signature(method, false, errors);
128
+ const label = signature(method, false, errors, checked);
121
129
  const injected = method.params.filter(param => param.injected);
122
130
  const doc = methodDocumentation(checked, method, owner);
123
131
  const injectionHelp = injected.length ? `Injected from bindings: ${injected.map(parameterText).join(', ')}.` : '';
124
132
  const contract = checked.effectContracts.get(method);
125
133
  const effects = contract ? `${contract.inferred ? 'Inferred capabilities; effective' : 'Effective'} contract: changes ${contract.changes.join(', ') || 'nothing'}; capabilities ` +
126
134
  `${[...contract.uses.values()].map(effect => `${effect.source}.${effect.operation}`).join(', ') || 'none'}.` : '';
127
- return { label: method.name, kind, detail: label, signature: signature(method, true, errors),
135
+ return { label: method.name, kind, detail: label, signature: signature(method, true, errors, checked),
128
136
  documentation: [doc?.markdown, isPrivateName(method.name) ? 'Private to its declaring type.' : '',
129
137
  injectionHelp, effects, interceptorDescription(checked, method), 'Call arguments require labels; their order does not matter.']
130
138
  .filter(Boolean).join('\n\n'),
@@ -147,7 +155,7 @@ function definitionItem(checked, def) {
147
155
  const doc = around && methodDocumentation(checked, around, def);
148
156
  return { label: def.name, kind: 'interceptor',
149
157
  detail: `interceptor ${node.name}${node.typeParams.length ? `<${node.typeParams.join(', ')}>` : ''}` +
150
- `(${node.fields.map(parameterText).join(', ')})` + (around ? `\n${signature(around)}` : ''),
158
+ `(${node.fields.map(parameterText).join(', ')})` + (around ? `\n${signature(around, false, [], checked)}` : ''),
151
159
  signature: `${node.name}(${params.map(param => `${param.name}=targetLabel`).join(', ')})`,
152
160
  parameters: params.map(param => `${param.name}=targetLabel`),
153
161
  parameterDocumentation: params.map(param => [doc?.parameters.get(param.name),
@@ -292,7 +300,9 @@ export function importItems(checked, file) {
292
300
  if (isPrivateName(item.name))
293
301
  continue;
294
302
  items.push({ label: item.name, kind: 'snippet',
295
- detail: `import ${item.name} from ${from}`, insertText: `${item.name} from ${from};`,
303
+ detail: `import ${item.name} from ${from}`, insertText: `${item.name} from ${from}`,
304
+ signature: definitionItem(checked, project.scopes.get(sibling.path).get(item.name)).signature,
305
+ parameters: definitionItem(checked, project.scopes.get(sibling.path).get(item.name)).parameters,
296
306
  documentation: item.kind === 'interface' ? documentation(checked, sibling.path, item.span.start)?.markdown :
297
307
  declarationDocumentation(checked, item)?.markdown });
298
308
  }
@@ -335,7 +345,8 @@ export function importItems(checked, file) {
335
345
  continue;
336
346
  for (const prefix of prefixes)
337
347
  for (const item of exportFile.items) {
338
- const from = [...prefix, ...segments].join('.');
348
+ const specification = (owner?.specifications ?? project.packages.specifications)[prefix[0]];
349
+ const from = isGitSource(specification ?? '') && prefix[0] === sourceAlias(specification) ? importSource([specification, ...segments]) : [...prefix, ...segments].join('.');
339
350
  if (!from)
340
351
  continue;
341
352
  if (item.kind !== 'export' || item.folder)
@@ -344,13 +355,15 @@ export function importItems(checked, file) {
344
355
  continue;
345
356
  const exported = project.scopes.get(join(folder, `${item.from}.aug`))?.get(item.name);
346
357
  items.push({ label: item.name, kind: 'snippet',
347
- detail: `import ${item.name} from ${from}`, insertText: `${item.name} from ${from};`,
358
+ detail: `import ${item.name} from ${from}`, insertText: `${item.name} from ${from}`,
359
+ signature: exported && definitionItem(checked, exported).signature,
360
+ parameters: exported && definitionItem(checked, exported).parameters,
348
361
  documentation: exported && definitionItem(checked, exported).documentation });
349
362
  }
350
363
  }
351
364
  return items;
352
365
  }
353
- export function completions(checked, fileName, offset) {
366
+ function rawCompletions(checked, fileName, offset) {
354
367
  const file = checked.project.files.get(resolve(fileName));
355
368
  if (!file)
356
369
  return [];
@@ -364,12 +377,13 @@ export function completions(checked, fileName, offset) {
364
377
  const used = new Set(joined[1].split(/\s+and\s+/));
365
378
  return unique(imports.filter(item => !used.has(item.label)).map(item => ({ ...item, kind: 'snippet', insertText: item.label })));
366
379
  }
367
- const from = /^\s*import\s+(.+?)\s+from\s+[A-Za-z_0-9.]*$/.exec(line);
380
+ const from = /^\s*import\s+(.+?)\s+from\s+([A-Za-z_0-9.]*|"[^"\n]*"?(?:\.[A-Za-z_0-9.]*)?)$/.exec(line);
368
381
  if (from)
369
382
  return unique(imports.filter(item => from[1] === 'everything' || item.label === from[1].split(/\s+and\s+/)[0]).map(item => {
370
383
  const path = item.detail.slice(item.detail.lastIndexOf(' from ') + 6);
371
384
  return { label: path, kind: 'snippet', detail: item.detail,
372
- insertText: `${path};`, documentation: item.documentation };
385
+ insertText: path, documentation: item.documentation,
386
+ replacement: { start: offset - from[2].length, end: offset } };
373
387
  }));
374
388
  const annotation = /(?<=^|\n)[ \t]*\[\s*([A-Za-z_][A-Za-z0-9_]*|)(?:<[^\[\]()]*>)?(?:\(([^\n()]*))?$/.exec(prefix);
375
389
  if (annotation) {
@@ -463,7 +477,48 @@ export function completions(checked, fileName, offset) {
463
477
  return all.filter(item => item.kind === 'interface');
464
478
  if (/\b(?:returns|unless|catch)\s+[A-Za-z_0-9]*$/.test(prefix))
465
479
  return all.filter(item => ['class', 'interface', 'type'].includes(item.kind));
466
- return all;
480
+ const visible = new Set(all.map(item => item.label));
481
+ const importsEnd = file.items.filter(item => item.kind === 'import').at(-1)?.span.end ?? 0;
482
+ const insertion = importsEnd ? file.source.indexOf('\n', importsEnd) : 0;
483
+ return [...all, ...imports.filter(item => !visible.has(item.label)).map(item => ({ ...item,
484
+ kind: item.signature ? 'function' : 'type',
485
+ insertText: item.label, sortText: '2-' + item.label,
486
+ additionalEdits: [{ start: insertion < 0 ? file.source.length : insertion, end: insertion < 0 ? file.source.length : insertion,
487
+ text: `${importsEnd ? '\n' : ''}${item.detail}${importsEnd ? '' : '\n'}` }] }))];
488
+ }
489
+ /** Fill labeled calls, keep dependency imports visible, and replace only the token being completed. */
490
+ export function completions(checked, fileName, offset) {
491
+ const file = checked.project.files.get(resolve(fileName));
492
+ if (!file)
493
+ return [];
494
+ const prefix = file.source.slice(0, offset), line = prefix.slice(prefix.lastIndexOf('\n') + 1);
495
+ const typeContext = /\b(?:import|export|implement|implements|extends|returns|unless|catch|resolve)\b[^\n]*$/.test(line);
496
+ const token = /[A-Za-z_][A-Za-z0-9_]*$/.exec(prefix);
497
+ const start = token ? offset - token[0].length : offset;
498
+ const end = offset + (/^[A-Za-z0-9_]*/.exec(file.source.slice(offset))?.[0].length ?? 0);
499
+ const escape = (text) => text.replace(/[\\$}]/g, '\\$&');
500
+ const argument = (parameter, index) => {
501
+ const [name, type] = parameter.split('=');
502
+ const value = type === 'string' ? '""' : type === 'bool' ? 'false' : ['int', 'float', 'c_int'].includes(type) ? '0' : name;
503
+ return `${name}=\${${index + 1}:${escape(value)}}`;
504
+ };
505
+ return rawCompletions(checked, fileName, offset).map(item => {
506
+ const callable = !typeContext && ['function', 'method', 'class'].includes(item.kind) && item.signature &&
507
+ !/^\s*\(/.test(file.source.slice(offset));
508
+ let insertText = callable ? `${item.label}(${(item.parameters ?? []).map(argument).join(', ')})$0` : item.insertText;
509
+ const template = snippetCatalog.find(snippet => item.label === snippet.prefix + ' template');
510
+ if (template)
511
+ insertText = snippetBody(template.body, checked.project.config.block_style, checked.project.config.indentation === 'tabs');
512
+ if (item.kind === 'snippet' && insertText && checked.project.config.block_style === 'indent' && insertText.includes('{\n'))
513
+ insertText = insertText.replace(/^(\s*)\} catch /gm, '$1catch ').replace(/ \{\n/g, ':\n').replace(/^[ \t]*\}\n?/gm, '').trimEnd();
514
+ let additionalEdits = item.additionalEdits;
515
+ if (additionalEdits?.some(edit => edit.start >= start && edit.start <= end)) {
516
+ insertText = additionalEdits.map(edit => escape(edit.text)).join('') + (insertText ?? item.label);
517
+ additionalEdits = undefined;
518
+ }
519
+ return { ...item, insertText, additionalEdits, replacement: item.replacement ?? { start, end },
520
+ sortText: item.sortText ?? (['variable', 'parameter', 'property'].includes(item.kind) ? '0-' : '1-') + item.label };
521
+ });
467
522
  }
468
523
  /** Resolve exactly the token under the cursor, including syntax outside completion contexts. */
469
524
  export function hoverInfo(checked, fileName, offset) {
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);