cluaupp 1.4.1 → 1.5.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 (340) hide show
  1. package/CHANGELOG.md +55 -0
  2. package/README.md +10 -5
  3. package/api/CHANGELOG.md +3 -0
  4. package/api/chat.js +74 -0
  5. package/api/fixtures/roblox/README.md +6 -0
  6. package/api/fixtures/roblox/aux/sample.d.luau +6 -0
  7. package/api/fixtures/roblox/mini/Mini-API-Dump.json +72 -0
  8. package/api/generated/bench-latest.json +39 -0
  9. package/api/generated/capability-profile.json +76 -0
  10. package/api/generated/lsp-index.json +1 -0
  11. package/api/generated/luau/classes.d.luau +11221 -0
  12. package/api/generated/luau/datatypes.d.luau +327 -0
  13. package/api/generated/luau/enums.d.luau +4918 -0
  14. package/api/generated/luau/globals.d.luau +12 -0
  15. package/api/manifests/roblox-target.manifest.json +22 -0
  16. package/api/normalized/roblox-target.profile.json +237461 -0
  17. package/api/overrides/classes.json +8 -0
  18. package/api/overrides/compatibility.json +9 -0
  19. package/api/overrides/datatypes.json +1579 -0
  20. package/api/overrides/enums.json +8 -0
  21. package/api/overrides/globals.json +8 -0
  22. package/api/overrides/type-mappings.json +9 -0
  23. package/api/roblox-api.lock.json +9 -0
  24. package/data/Mini-API-Dump.json +1 -0
  25. package/editors/vscode/README.md +19 -0
  26. package/editors/vscode/extension.js +222 -21
  27. package/editors/vscode/icons/axiom.svg +4 -0
  28. package/editors/vscode/icons/bloom.svg +5 -0
  29. package/editors/vscode/icons/flare.svg +5 -0
  30. package/editors/vscode/icons/helm.svg +4 -0
  31. package/editors/vscode/icons/hive.svg +5 -0
  32. package/editors/vscode/icons/mint.svg +4 -0
  33. package/editors/vscode/icons/shift.svg +6 -0
  34. package/editors/vscode/language-configuration-schema.json +24 -0
  35. package/editors/vscode/language-configuration.json +21 -0
  36. package/editors/vscode/package.json +220 -6
  37. package/editors/vscode/snippets/axiom.json +12 -0
  38. package/editors/vscode/snippets/bloom.json +12 -0
  39. package/editors/vscode/snippets/flare.json +27 -0
  40. package/editors/vscode/snippets/helm.json +12 -0
  41. package/editors/vscode/snippets/hive.json +12 -0
  42. package/editors/vscode/snippets/mint.json +12 -0
  43. package/editors/vscode/snippets/shift.json +17 -0
  44. package/editors/vscode/syntaxes/axiom.tmLanguage.json +5 -0
  45. package/editors/vscode/syntaxes/bloom.tmLanguage.json +5 -0
  46. package/editors/vscode/syntaxes/flare.tmLanguage.json +75 -0
  47. package/editors/vscode/syntaxes/helm.tmLanguage.json +5 -0
  48. package/editors/vscode/syntaxes/hive.tmLanguage.json +5 -0
  49. package/editors/vscode/syntaxes/mint.tmLanguage.json +5 -0
  50. package/editors/vscode/syntaxes/schema.tmLanguage.json +89 -0
  51. package/editors/vscode/syntaxes/shift.tmLanguage.json +5 -0
  52. package/examples/game/.cluaupp/compile-cache/ReplicatedStorage__Shared__Constants__Datas__TemplateData.clh.json +1 -0
  53. package/examples/game/.cluaupp/compile-cache/ServerScriptService__Boot__DataBoot.server.clpp.json +1 -0
  54. package/examples/game/.cluaupp/compile-cache/ServerScriptService__Configuration__ServerConfig.clp.json +1 -0
  55. package/examples/game/.cluaupp/compile-cache/ServerScriptService__Handlers__Guard.server.clpp.json +1 -0
  56. package/examples/game/.cluaupp/compile-cache/ServerScriptService__Handlers__PlayerHandler.server.clpp.json +1 -0
  57. package/examples/game/.cluaupp/compile-cache/StarterPlayer__StarterCharacterScripts__Character__CharacterReady.client.clpp.json +1 -0
  58. package/examples/game/.cluaupp/compile-cache/StarterPlayer__StarterPlayerScripts__Controllers__DataController.client.clpp.json +1 -0
  59. package/examples/game/.cluaupp/compile-cache/index.json +12 -0
  60. package/examples/game/.cluaupp/datamodel-profile.json +94 -0
  61. package/examples/game/.vscode/extensions.json +3 -1
  62. package/examples/game/.vscode/settings.json +13 -1
  63. package/examples/game/include/clpp/datatypes.clh +337 -373
  64. package/examples/game/include/clpp/generated/datamodel.clh +25 -0
  65. package/examples/game/include/clpp/generated/enums.clh +1 -1
  66. package/examples/game/include/clpp/generated/instances.clh +41135 -41064
  67. package/examples/game/include/clpp/libs/axiom.clh +1 -1
  68. package/examples/game/include/clpp/libs/math.clh +14 -0
  69. package/examples/game/include/clpp/libs/roster.clh +6 -0
  70. package/examples/game/include/clpp/libs/spring.clh +17 -0
  71. package/examples/game/include/clpp/libs/ward.clh +1 -0
  72. package/examples/game/include/clpp/roblox.clh +3 -4
  73. package/examples/game/libs/ArrayIndexer/init.luau +209 -0
  74. package/examples/game/libs/Axiom/init.luau +608 -0
  75. package/examples/game/libs/Bloom/init.luau +433 -0
  76. package/examples/game/libs/Coil/init.luau +215 -0
  77. package/examples/game/libs/Crest/init.luau +426 -0
  78. package/examples/game/libs/Echo/init.luau +417 -0
  79. package/examples/game/libs/Ember/init.luau +365 -0
  80. package/examples/game/libs/Flare/init.luau +717 -0
  81. package/examples/game/libs/Gleam/init.luau +729 -0
  82. package/examples/game/libs/Guide/init.luau +215 -0
  83. package/examples/game/libs/Helm/init.luau +377 -0
  84. package/examples/game/libs/Hive/init.luau +241 -0
  85. package/examples/game/libs/Keep/Client.luau +114 -0
  86. package/examples/game/libs/Keep/Data.luau +883 -0
  87. package/examples/game/libs/Keep/Engine.luau +211 -0
  88. package/examples/game/libs/Keep/Enum.luau +6 -0
  89. package/examples/game/libs/Keep/Enums.luau +10 -0
  90. package/examples/game/libs/Keep/Path.luau +236 -0
  91. package/examples/game/libs/Keep/Replicator.luau +298 -0
  92. package/examples/game/libs/Keep/Server.luau +251 -0
  93. package/examples/game/libs/Keep/Store.luau +652 -0
  94. package/examples/game/libs/Keep/Trade.luau +455 -0
  95. package/examples/game/libs/Keep/init.luau +205 -0
  96. package/examples/game/libs/Lens/init.luau +609 -0
  97. package/examples/game/libs/Mint/init.luau +279 -0
  98. package/examples/game/libs/Net/init.luau +156 -0
  99. package/examples/game/libs/Net/src/codec.luau +224 -0
  100. package/examples/game/libs/Occlude/init.luau +117 -0
  101. package/examples/game/libs/Pin/init.luau +309 -0
  102. package/examples/game/libs/Promise/LICENSE +21 -0
  103. package/examples/game/libs/Promise/_impl/LICENSE +21 -0
  104. package/examples/game/libs/Promise/_impl/init.lua +1991 -0
  105. package/examples/game/libs/Promise/init.lua +1990 -0
  106. package/examples/game/libs/Promise/init.luau +13 -0
  107. package/examples/game/libs/Promise/types.luau +46 -0
  108. package/examples/game/libs/Roster/init.luau +686 -0
  109. package/examples/game/libs/SOURCES.md +31 -0
  110. package/examples/game/libs/Shift/init.luau +238 -0
  111. package/examples/game/libs/Spark/init.luau +487 -0
  112. package/examples/game/libs/Stage/init.luau +178 -0
  113. package/examples/game/libs/Sweep/init.luau +259 -0
  114. package/examples/game/libs/Trace/init.luau +213 -0
  115. package/examples/game/libs/Ward/init.luau +211 -0
  116. package/examples/game/out/ReplicatedStorage/Shared/Constants/Datas/TemplateData.luau +29 -0
  117. package/examples/game/out/ReplicatedStorage/Shared/Constants/Datas/TemplateData.luau.map.json +13 -0
  118. package/examples/game/out/ReplicatedStorage/Shared/Net/Net.luau +83 -0
  119. package/examples/game/out/ReplicatedStorage/Shared/Net/Net.luau.map.json +13 -0
  120. package/examples/game/out/ServerScriptService/Boot/DataBoot.server.luau +18 -0
  121. package/examples/game/out/ServerScriptService/Boot/DataBoot.server.luau.map.json +13 -0
  122. package/examples/game/out/ServerScriptService/Configuration/ServerConfig.luau +14 -0
  123. package/examples/game/out/ServerScriptService/Configuration/ServerConfig.luau.map.json +13 -0
  124. package/examples/game/out/ServerScriptService/Handlers/Guard.server.luau +15 -0
  125. package/examples/game/out/ServerScriptService/Handlers/Guard.server.luau.map.json +13 -0
  126. package/examples/game/out/ServerScriptService/Handlers/PlayerHandler.server.luau +50 -0
  127. package/examples/game/out/ServerScriptService/Handlers/PlayerHandler.server.luau.map.json +13 -0
  128. package/examples/game/out/StarterPlayer/StarterCharacterScripts/Character/CharacterReady.client.luau +12 -0
  129. package/examples/game/out/StarterPlayer/StarterCharacterScripts/Character/CharacterReady.client.luau.map.json +13 -0
  130. package/examples/game/out/StarterPlayer/StarterPlayerScripts/Controllers/DataController.client.luau +16 -0
  131. package/examples/game/out/StarterPlayer/StarterPlayerScripts/Controllers/DataController.client.luau.map.json +13 -0
  132. package/examples/game/src/ReplicatedStorage/Shared/Net/Net.clh +26 -0
  133. package/examples/game/src/ReplicatedStorage/Shared/Net/Net.flare +5 -0
  134. package/examples/game/src/ServerScriptService/Boot/DataBoot.server.clpp +2 -2
  135. package/examples/game/src/ServerScriptService/Handlers/PlayerHandler.server.clpp +1 -1
  136. package/examples/game/stylua.toml +9 -0
  137. package/generated/api/build-profile.js +115 -0
  138. package/generated/api/cache.js +44 -0
  139. package/generated/api/coverage.js +32 -0
  140. package/generated/api/diff.js +125 -0
  141. package/generated/api/generators/clpp-headers.js +353 -0
  142. package/generated/api/generators/docs-reference.js +7 -0
  143. package/generated/api/generators/lsp-index.js +81 -0
  144. package/generated/api/generators/luau-defs.js +94 -0
  145. package/generated/api/ide.js +76 -0
  146. package/generated/api/identifier.js +47 -0
  147. package/generated/api/index.js +324 -0
  148. package/generated/api/loader.js +57 -0
  149. package/generated/api/merge.js +88 -0
  150. package/generated/api/model.js +5 -0
  151. package/generated/api/normalize.js +231 -0
  152. package/generated/api/overrides-validate.js +58 -0
  153. package/generated/api/perf.js +12 -0
  154. package/generated/api/registry.js +136 -0
  155. package/generated/api/release.js +44 -0
  156. package/generated/api/resolver.js +250 -0
  157. package/generated/api/sources/aux-types-diff.js +75 -0
  158. package/generated/api/sources/client-tracker.js +11 -0
  159. package/generated/api/sources/creator-docs.js +42 -0
  160. package/generated/api/sources/luau-types.js +34 -0
  161. package/generated/api/sources/mini-dump.js +17 -0
  162. package/generated/api/sources/studio-api.js +8 -0
  163. package/generated/api/sources/studio-apiv2.js +11 -0
  164. package/generated/api/sources/studio-full-api.js +8 -0
  165. package/generated/api/studio-smoke.js +80 -0
  166. package/generated/api/type-parse.js +49 -0
  167. package/generated/api/understander.js +51 -0
  168. package/generated/api/validate.js +135 -0
  169. package/generated/api-cli.js +421 -0
  170. package/generated/cli.js +17 -6
  171. package/generated/clpp/contract.js +3 -3
  172. package/generated/clpp/format-luau.js +236 -0
  173. package/generated/clpp/index.js +13 -1
  174. package/generated/clpp/modules.js +227 -0
  175. package/generated/clpp/postprocess.js +86 -5
  176. package/generated/clpp/rewrite-janitor.js +145 -0
  177. package/generated/clpp/runner.js +14 -2
  178. package/generated/compile.js +82 -0
  179. package/generated/flare/index.js +15 -3
  180. package/generated/flare/language.js +561 -0
  181. package/generated/flare/parse.js +19 -7
  182. package/generated/intellisense.js +76 -2
  183. package/generated/lsp.js +118 -7
  184. package/generated/native/index.js +217 -16
  185. package/generated/target/authority-check.js +136 -0
  186. package/generated/target/authority-graph.js +74 -0
  187. package/generated/target/build-cache.js +112 -0
  188. package/generated/target/capabilities.js +89 -0
  189. package/generated/target/capability-profile.js +30 -0
  190. package/generated/target/component-contracts.js +60 -0
  191. package/generated/target/context-check.js +160 -0
  192. package/generated/target/datamodel-check.js +170 -0
  193. package/generated/target/datamodel-generate.js +74 -0
  194. package/generated/target/datamodel.js +233 -0
  195. package/generated/target/diagnostics.js +63 -0
  196. package/generated/target/doctor.js +152 -0
  197. package/generated/target/flare-version.js +58 -0
  198. package/generated/target/get-service.js +69 -0
  199. package/generated/target/lifetime-check.js +47 -0
  200. package/generated/target/luau-stamp.js +39 -0
  201. package/generated/target/optimizer-advise.js +88 -0
  202. package/generated/target/optimizer-apply.js +44 -0
  203. package/generated/target/optimizer-soa.js +254 -0
  204. package/generated/target/parallel-check.js +136 -0
  205. package/generated/target/pgo.js +148 -0
  206. package/generated/target/project-docs.js +69 -0
  207. package/generated/target/project-graph.js +71 -0
  208. package/generated/target/roblox.js +63 -0
  209. package/generated/target/security-check.js +41 -0
  210. package/generated/target/source-map.js +25 -0
  211. package/generated/target/studio-bridge.js +112 -0
  212. package/generated/utils/project.js +178 -8
  213. package/generated/utils/rojo-mapper.js +11 -3
  214. package/include/clpp/datatypes.clh +337 -373
  215. package/include/clpp/generated/enums.clh +1 -1
  216. package/include/clpp/generated/instances.clh +41135 -41064
  217. package/include/clpp/libs/axiom.clh +1 -1
  218. package/include/clpp/libs/hive.clh +1 -0
  219. package/include/clpp/libs/keep.clh +2 -0
  220. package/include/clpp/libs/math.clh +14 -0
  221. package/include/clpp/libs/roster.clh +6 -0
  222. package/include/clpp/libs/spring.clh +17 -0
  223. package/include/clpp/libs/ward.clh +1 -0
  224. package/include/clpp/roblox.clh +3 -4
  225. package/package.json +10 -3
  226. package/plugins/CluauppNav/Plugin.luau +207 -0
  227. package/plugins/CluauppNav/ProfileLogger.luau +27 -0
  228. package/plugins/CluauppNav/README.md +24 -0
  229. package/runtime/Axiom/init.luau +10 -7
  230. package/runtime/Coil/init.luau +8 -2
  231. package/runtime/Crest/init.luau +1 -0
  232. package/runtime/Flare/init.luau +2 -1
  233. package/runtime/Gleam/init.luau +15 -4
  234. package/runtime/Hive/init.luau +36 -14
  235. package/runtime/Pin/init.luau +5 -2
  236. package/runtime/Roster/init.luau +8 -0
  237. package/runtime/Spark/init.luau +3 -0
  238. package/runtime/Sweep/init.luau +2 -0
  239. package/runtime/Trace/init.luau +3 -0
  240. package/runtime/Ward/init.luau +38 -5
  241. package/scripts/postinstall-editor.js +17 -0
  242. package/skills/README.md +13 -0
  243. package/skills/clpp-hive-flare/SKILL.md +79 -0
  244. package/skills/clpp-language/SKILL.md +123 -0
  245. package/skills/clpp-language/compiler.md +89 -0
  246. package/skills/clpp-style/SKILL.md +95 -0
  247. package/src/api/build-profile.ts +138 -0
  248. package/src/api/cache.ts +45 -0
  249. package/src/api/coverage.ts +46 -0
  250. package/src/api/diff.ts +143 -0
  251. package/src/api/generators/clpp-headers.ts +377 -0
  252. package/src/api/generators/docs-reference.ts +11 -0
  253. package/src/api/generators/lsp-index.ts +106 -0
  254. package/src/api/generators/luau-defs.ts +98 -0
  255. package/src/api/ide.ts +87 -0
  256. package/src/api/identifier.ts +47 -0
  257. package/src/api/index.ts +269 -0
  258. package/src/api/loader.ts +60 -0
  259. package/src/api/merge.ts +126 -0
  260. package/src/api/model.ts +283 -0
  261. package/src/api/normalize.ts +257 -0
  262. package/src/api/overrides-validate.ts +58 -0
  263. package/src/api/perf.ts +15 -0
  264. package/src/api/registry.ts +162 -0
  265. package/src/api/release.ts +47 -0
  266. package/src/api/resolver.ts +255 -0
  267. package/src/api/sources/aux-types-diff.ts +81 -0
  268. package/src/api/sources/client-tracker.ts +10 -0
  269. package/src/api/sources/creator-docs.ts +37 -0
  270. package/src/api/sources/luau-types.ts +30 -0
  271. package/src/api/sources/mini-dump.ts +50 -0
  272. package/src/api/sources/studio-api.ts +7 -0
  273. package/src/api/sources/studio-apiv2.ts +10 -0
  274. package/src/api/sources/studio-full-api.ts +7 -0
  275. package/src/api/studio-smoke.ts +82 -0
  276. package/src/api/type-parse.ts +48 -0
  277. package/src/api/understander.ts +72 -0
  278. package/src/api/validate.ts +160 -0
  279. package/src/api-cli.ts +493 -0
  280. package/src/api.generated.js +37 -22
  281. package/src/cli.ts +22 -7
  282. package/src/clpp/contract.ts +34 -3
  283. package/src/clpp/format-luau.ts +262 -0
  284. package/src/clpp/index.ts +13 -2
  285. package/src/clpp/modules.ts +252 -0
  286. package/src/clpp/postprocess.ts +100 -5
  287. package/src/clpp/rewrite-janitor.ts +156 -0
  288. package/src/clpp/runner.ts +14 -2
  289. package/src/compile.ts +87 -0
  290. package/src/flare/index.ts +20 -1
  291. package/src/flare/language.ts +708 -0
  292. package/src/flare/parse.ts +20 -7
  293. package/src/flare/types.ts +2 -0
  294. package/src/intellisense.ts +76 -2
  295. package/src/lsp.ts +151 -8
  296. package/src/native/index.ts +225 -16
  297. package/src/target/authority-check.ts +162 -0
  298. package/src/target/authority-graph.ts +80 -0
  299. package/src/target/build-cache.ts +129 -0
  300. package/src/target/capabilities.ts +115 -0
  301. package/src/target/capability-profile.ts +25 -0
  302. package/src/target/component-contracts.ts +64 -0
  303. package/src/target/context-check.ts +177 -0
  304. package/src/target/datamodel-check.ts +188 -0
  305. package/src/target/datamodel-generate.ts +78 -0
  306. package/src/target/datamodel.ts +261 -0
  307. package/src/target/diagnostics.ts +67 -0
  308. package/src/target/doctor.ts +171 -0
  309. package/src/target/flare-version.ts +61 -0
  310. package/src/target/get-service.ts +85 -0
  311. package/src/target/lifetime-check.ts +45 -0
  312. package/src/target/luau-stamp.ts +33 -0
  313. package/src/target/optimizer-advise.ts +93 -0
  314. package/src/target/optimizer-apply.ts +63 -0
  315. package/src/target/optimizer-soa.ts +270 -0
  316. package/src/target/parallel-check.ts +135 -0
  317. package/src/target/pgo.ts +157 -0
  318. package/src/target/project-docs.ts +68 -0
  319. package/src/target/project-graph.ts +75 -0
  320. package/src/target/roblox.ts +78 -0
  321. package/src/target/security-check.ts +40 -0
  322. package/src/target/source-map.ts +36 -0
  323. package/src/target/studio-bridge.ts +140 -0
  324. package/src/types.ts +14 -0
  325. package/src/utils/project.ts +183 -9
  326. package/src/utils/rojo-mapper.ts +12 -3
  327. package/stylua.toml +9 -0
  328. package/templates/game/.vscode/extensions.json +3 -1
  329. package/templates/game/.vscode/settings.json +8 -1
  330. package/templates/game/include/clpp/datatypes.clh +337 -373
  331. package/templates/game/include/clpp/generated/enums.clh +1 -1
  332. package/templates/game/include/clpp/generated/instances.clh +41135 -41064
  333. package/templates/game/include/clpp/libs/axiom.clh +1 -1
  334. package/templates/game/include/clpp/libs/roster.clh +6 -0
  335. package/templates/game/include/clpp/libs/ward.clh +1 -0
  336. package/templates/game/include/clpp/roblox.clh +3 -4
  337. package/templates/game/src/ReplicatedStorage/Shared/Net/Net.flare +5 -0
  338. package/templates/game/src/ServerScriptService/Boot/DataBoot.server.clpp +2 -2
  339. package/templates/game/src/ServerScriptService/Handlers/PlayerHandler.server.clpp +1 -1
  340. package/templates/game/stylua.toml +9 -0
@@ -0,0 +1,135 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.validateProfile = validateProfile;
4
+ exports.assertValid = assertValid;
5
+ function validateProfile(profile) {
6
+ const issues = [];
7
+ const classNames = new Set(Object.keys(profile.classes));
8
+ const enumNames = new Set(Object.keys(profile.enums));
9
+ const datatypeNames = new Set(Object.keys(profile.datatypes));
10
+ for (const cls of Object.values(profile.classes)) {
11
+ if (cls.superclass && !classNames.has(cls.superclass)) {
12
+ issues.push({
13
+ severity: "warning",
14
+ code: "ORPHAN_SUPERCLASS",
15
+ message: `Class ${cls.name} references missing superclass ${cls.superclass}`,
16
+ symbol: cls.name,
17
+ });
18
+ }
19
+ detectCycle(cls, profile.classes, issues);
20
+ for (const prop of cls.properties) {
21
+ checkTypeRefs(prop.valueType, `property ${cls.name}.${prop.name}`, classNames, enumNames, datatypeNames, issues);
22
+ }
23
+ for (const method of cls.methods) {
24
+ for (const p of method.parameters) {
25
+ checkTypeRefs(p.type, `method ${cls.name}.${method.name}`, classNames, enumNames, datatypeNames, issues);
26
+ }
27
+ }
28
+ }
29
+ const seenEnums = new Set();
30
+ for (const e of Object.values(profile.enums)) {
31
+ if (seenEnums.has(e.name)) {
32
+ issues.push({
33
+ severity: "error",
34
+ code: "DUPLICATE_ENUM",
35
+ message: `Duplicate enum ${e.name}`,
36
+ symbol: e.name,
37
+ });
38
+ }
39
+ seenEnums.add(e.name);
40
+ const itemNames = new Set();
41
+ for (const item of e.items) {
42
+ if (itemNames.has(item.name)) {
43
+ issues.push({
44
+ severity: "warning",
45
+ code: "DUPLICATE_ENUM_ITEM",
46
+ message: `Duplicate enum item ${e.name}.${item.name}`,
47
+ symbol: `${e.name}.${item.name}`,
48
+ });
49
+ }
50
+ itemNames.add(item.name);
51
+ }
52
+ }
53
+ for (const u of profile.unsupported) {
54
+ if (u.severity === "error") {
55
+ issues.push({
56
+ severity: "error",
57
+ code: "UNSUPPORTED",
58
+ message: u.reason,
59
+ symbol: u.symbol,
60
+ });
61
+ }
62
+ }
63
+ return issues;
64
+ }
65
+ function detectCycle(cls, classes, issues) {
66
+ const seen = new Set();
67
+ let current = cls.name;
68
+ while (current) {
69
+ if (seen.has(current)) {
70
+ issues.push({
71
+ severity: "error",
72
+ code: "INHERITANCE_CYCLE",
73
+ message: `Inheritance cycle involving ${cls.name}`,
74
+ symbol: cls.name,
75
+ });
76
+ return;
77
+ }
78
+ seen.add(current);
79
+ const nextCls = classes[current];
80
+ current = nextCls?.superclass || null;
81
+ }
82
+ }
83
+ function checkTypeRefs(type, context, classes, enums, datatypes, issues) {
84
+ switch (type.kind) {
85
+ case "Class":
86
+ if (!classes.has(type.name) && !datatypes.has(type.name)) {
87
+ issues.push({
88
+ severity: "warning",
89
+ code: "UNRESOLVED_CLASS",
90
+ message: `Unresolved class type ${type.name} in ${context}`,
91
+ symbol: type.name,
92
+ });
93
+ }
94
+ break;
95
+ case "Enum":
96
+ if (!enums.has(type.name)) {
97
+ issues.push({
98
+ severity: "warning",
99
+ code: "UNRESOLVED_ENUM",
100
+ message: `Unresolved enum ${type.name} in ${context}`,
101
+ symbol: type.name,
102
+ });
103
+ }
104
+ break;
105
+ case "Datatype":
106
+ if (!datatypes.has(type.name) && !classes.has(type.name)) {
107
+ issues.push({
108
+ severity: "warning",
109
+ code: "UNRESOLVED_DATATYPE",
110
+ message: `Unresolved datatype ${type.name} in ${context}`,
111
+ symbol: type.name,
112
+ });
113
+ }
114
+ break;
115
+ case "Optional":
116
+ checkTypeRefs(type.inner, context, classes, enums, datatypes, issues);
117
+ break;
118
+ case "Array":
119
+ checkTypeRefs(type.element, context, classes, enums, datatypes, issues);
120
+ break;
121
+ case "Dictionary":
122
+ case "Map":
123
+ checkTypeRefs(type.key, context, classes, enums, datatypes, issues);
124
+ checkTypeRefs(type.value, context, classes, enums, datatypes, issues);
125
+ break;
126
+ default:
127
+ break;
128
+ }
129
+ }
130
+ function assertValid(profile) {
131
+ const errors = validateProfile(profile).filter((i) => i.severity === "error");
132
+ if (errors.length) {
133
+ throw new Error(`RobloxTargetProfile invalid:\n${errors.map((e) => `- ${e.code}: ${e.message}`).join("\n")}`);
134
+ }
135
+ }
@@ -0,0 +1,421 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.registerApiCommands = registerApiCommands;
7
+ exports.registerTargetCommands = registerTargetCommands;
8
+ exports.registerPlatformCommands = registerPlatformCommands;
9
+ const node_path_1 = __importDefault(require("node:path"));
10
+ const index_js_1 = require("./api/index.js");
11
+ const package_info_js_1 = require("./package-info.js");
12
+ const node_fs_1 = __importDefault(require("node:fs"));
13
+ const paths_js_1 = require("./clpp/paths.js");
14
+ const node_child_process_1 = require("node:child_process");
15
+ const optimizer_apply_js_1 = require("./target/optimizer-apply.js");
16
+ const pgo_js_1 = require("./target/pgo.js");
17
+ const project_docs_js_1 = require("./target/project-docs.js");
18
+ const studio_bridge_js_1 = require("./target/studio-bridge.js");
19
+ const optimizer_soa_js_1 = require("./target/optimizer-soa.js");
20
+ function registerApiCommands(program) {
21
+ const api = program.command("api").description("Roblox API registry (Cluaupp target)");
22
+ api
23
+ .command("update")
24
+ .description("Rebuild profile from dump + overrides (alias of generate)")
25
+ .option("--dump <path>", "Mini-API-Dump.json path")
26
+ .action((opts) => {
27
+ runGenerate(opts.dump);
28
+ });
29
+ api
30
+ .command("generate")
31
+ .description("Build RobloxTargetProfile and regenerate CL++ / Luau projections")
32
+ .option("--dump <path>", "Mini-API-Dump.json path")
33
+ .option("--skip-headers", "Skip CL++ header generation")
34
+ .option("--skip-luau", "Skip .d.luau generation")
35
+ .option("--docs", "No-op retained for CLI compat (Creator Docs are not mirrored)")
36
+ .action((opts) => {
37
+ runGenerate(opts.dump, opts.skipHeaders, opts.skipLuau, true);
38
+ });
39
+ api
40
+ .command("verify")
41
+ .description("Verify roblox-api.lock.json against current sources")
42
+ .action(() => {
43
+ const result = (0, index_js_1.verifyLock)();
44
+ if (!result.ok) {
45
+ console.error("cluaupp api verify: FAILED");
46
+ for (const m of result.messages) {
47
+ console.error(" -", m);
48
+ }
49
+ process.exit(1);
50
+ }
51
+ console.log("cluaupp api verify: OK");
52
+ });
53
+ api
54
+ .command("diff")
55
+ .description("Diff current profile against a snapshot")
56
+ .argument("<snapshot>", "path to previous profile JSON")
57
+ .action((snapshot) => {
58
+ const entries = (0, index_js_1.apiDiffAgainstSnapshot)(node_path_1.default.resolve(snapshot));
59
+ console.log(JSON.stringify(entries, null, "\t"));
60
+ console.log(`cluaupp api diff: ${entries.length} change(s)`);
61
+ });
62
+ api
63
+ .command("inspect")
64
+ .description("Inspect a class, enum, datatype, or member")
65
+ .argument("<symbol>", "e.g. Players, Players.PlayerAdded, Vector3")
66
+ .action((symbol) => {
67
+ console.log(JSON.stringify((0, index_js_1.inspectSymbol)(symbol), null, "\t"));
68
+ });
69
+ api
70
+ .command("search")
71
+ .description("Search registry symbols")
72
+ .argument("<query>", "substring query")
73
+ .action((query) => {
74
+ const profile = (0, index_js_1.buildRobloxTargetProfile)({ skipValidate: true });
75
+ console.log(JSON.stringify((0, index_js_1.searchRegistry)((0, index_js_1.buildRegistry)(profile), query), null, "\t"));
76
+ });
77
+ api
78
+ .command("coverage")
79
+ .description("Report API surface coverage and UnsupportedRepresentation gaps")
80
+ .action(() => {
81
+ console.log(JSON.stringify((0, index_js_1.apiCoverage)(), null, "\t"));
82
+ });
83
+ api
84
+ .command("snapshot")
85
+ .description("Write api/snapshots/latest.profile.json")
86
+ .option("-o, --output <path>", "output path")
87
+ .action((opts) => {
88
+ const p = (0, index_js_1.writeSnapshot)(opts.output);
89
+ console.log("cluaupp api snapshot:", p);
90
+ });
91
+ api
92
+ .command("validate")
93
+ .description("Validate current RobloxTargetProfile")
94
+ .action(() => {
95
+ const issues = (0, index_js_1.validateCurrent)();
96
+ const errors = issues.filter((i) => i.severity === "error");
97
+ console.log(JSON.stringify(issues, null, "\t"));
98
+ if (errors.length) {
99
+ process.exit(1);
100
+ }
101
+ });
102
+ api
103
+ .command("analyze-luau")
104
+ .description("Run luau-analyze on generated .d.luau if available")
105
+ .action(() => {
106
+ const results = (0, index_js_1.analyzeLuauOutput)();
107
+ console.log(JSON.stringify(results, null, "\t"));
108
+ });
109
+ api
110
+ .command("aux-diff")
111
+ .description("Coverage cross-check vs local @rbxts/types or LuauTypes (not on compile path)")
112
+ .argument("<path>", "file or directory of auxiliary types")
113
+ .action((auxPath) => {
114
+ const profile = (0, index_js_1.buildRobloxTargetProfile)({ skipValidate: true });
115
+ const names = [
116
+ ...Object.keys(profile.classes),
117
+ ...Object.keys(profile.enums),
118
+ ...Object.keys(profile.datatypes),
119
+ ];
120
+ const report = (0, index_js_1.diffAgainstAuxTypes)(names, node_path_1.default.resolve(auxPath));
121
+ console.log(JSON.stringify({
122
+ source: report.source,
123
+ auxSymbols: report.auxSymbols,
124
+ registrySymbols: report.registrySymbols,
125
+ onlyInAuxCount: report.onlyInAux.length,
126
+ onlyInRegistryCount: report.onlyInRegistry.length,
127
+ onlyInAuxSample: report.onlyInAux.slice(0, 40),
128
+ onlyInRegistrySample: report.onlyInRegistry.slice(0, 40),
129
+ }, null, "\t"));
130
+ });
131
+ }
132
+ function registerTargetCommands(program) {
133
+ const target = program.command("target").description("Cluaupp Roblox target profile");
134
+ target
135
+ .command("info")
136
+ .description("Print target identity and schema version")
137
+ .action(() => {
138
+ const profile = (0, index_js_1.buildRobloxTargetProfile)({ skipValidate: true });
139
+ console.log(JSON.stringify({
140
+ target: "roblox",
141
+ schemaVersion: index_js_1.ROBLOX_TARGET_SCHEMA_VERSION,
142
+ cluaupp: package_info_js_1.pkg.version,
143
+ robloxApiVersion: profile.robloxApiVersion,
144
+ classes: Object.keys(profile.classes).length,
145
+ enums: Object.keys(profile.enums).length,
146
+ datatypes: Object.keys(profile.datatypes).length,
147
+ services: Object.keys(profile.services).length,
148
+ unsupported: profile.unsupported.length,
149
+ }, null, "\t"));
150
+ });
151
+ target
152
+ .command("doctor")
153
+ .description("Full platform check: registry, lock, DataModel, parallel, authority, security, graph, Flare")
154
+ .argument("[folder]", "game root", ".")
155
+ .action((folder) => {
156
+ const root = node_path_1.default.resolve(folder);
157
+ const report = (0, index_js_1.runDoctor)(root);
158
+ console.log(JSON.stringify(report, null, "\t"));
159
+ if (!report.ok) {
160
+ process.exit(1);
161
+ }
162
+ });
163
+ target
164
+ .command("capabilities")
165
+ .description("Print Context Safety capability profile (runContext rules)")
166
+ .action(() => {
167
+ const pathOut = (0, index_js_1.writeCapabilityProfile)();
168
+ console.log(JSON.stringify((0, index_js_1.builtinCapabilityProfile)(), null, "\t"));
169
+ console.log("wrote", pathOut);
170
+ });
171
+ target
172
+ .command("check-context")
173
+ .description("Scan a .clpp file for Context Safety violations")
174
+ .argument("<file>", "CL++ source path")
175
+ .action((file) => {
176
+ const abs = node_path_1.default.resolve(file);
177
+ const source = node_fs_1.default.readFileSync(abs, "utf8");
178
+ const violations = (0, index_js_1.checkContextSafety)(source, abs);
179
+ console.log(JSON.stringify(violations, null, "\t"));
180
+ if (violations.some((v) => v.severity === "error")) {
181
+ process.exit(1);
182
+ }
183
+ });
184
+ target
185
+ .command("datamodel")
186
+ .description("Build Typed DataModel profile + generated datamodel.clh from Rojo project")
187
+ .argument("[folder]", "game root with default.project.json", ".")
188
+ .option("-r, --rojo <path>", "Rojo project json")
189
+ .action((folder, options) => {
190
+ const root = node_path_1.default.resolve(folder);
191
+ const result = (0, index_js_1.writeDatamodelArtifacts)(root, { projectJson: options.rojo });
192
+ if (!result) {
193
+ console.error("cluaupp target datamodel: no default.project.json in", root);
194
+ process.exit(1);
195
+ }
196
+ const paths = Object.keys(result.profile.byPath).filter((p) => p !== "DataModel");
197
+ console.log(JSON.stringify({
198
+ project: result.profile.projectName,
199
+ nodes: paths.length,
200
+ profile: result.profilePath,
201
+ header: result.headerPath,
202
+ sample: paths.slice(0, 20),
203
+ }, null, "\t"));
204
+ });
205
+ target
206
+ .command("check-datamodel")
207
+ .description("Scan a .clpp file for Typed DataModel path violations")
208
+ .argument("<file>", "CL++ source path")
209
+ .option("-r, --rojo <folder>", "game root with default.project.json", ".")
210
+ .action((file, options) => {
211
+ const abs = node_path_1.default.resolve(file);
212
+ const root = node_path_1.default.resolve(options.rojo || ".");
213
+ const profile = (0, index_js_1.buildDatamodelProfile)(root);
214
+ if (!profile) {
215
+ console.error("cluaupp target check-datamodel: no default.project.json in", root);
216
+ process.exit(1);
217
+ }
218
+ const source = node_fs_1.default.readFileSync(abs, "utf8");
219
+ const violations = (0, index_js_1.checkDatamodelPaths)(source, profile);
220
+ console.log(JSON.stringify(violations, null, "\t"));
221
+ if (violations.some((v) => v.severity === "error")) {
222
+ process.exit(1);
223
+ }
224
+ });
225
+ target
226
+ .command("check-parallel")
227
+ .description("Scan a .clpp file for Unsafe API use in parallel regions")
228
+ .argument("<file>", "CL++ source path")
229
+ .action((file) => {
230
+ const abs = node_path_1.default.resolve(file);
231
+ const source = node_fs_1.default.readFileSync(abs, "utf8");
232
+ const diags = (0, index_js_1.checkParallelSafety)(source, abs);
233
+ console.log(JSON.stringify(diags, null, "\t"));
234
+ if (diags.some((d) => d.severity === "error"))
235
+ process.exit(1);
236
+ });
237
+ target
238
+ .command("graph")
239
+ .description("Print project include graph and cycles")
240
+ .argument("[folder]", "game root", ".")
241
+ .action((folder) => {
242
+ console.log(JSON.stringify((0, index_js_1.buildProjectGraph)(node_path_1.default.resolve(folder)), null, "\t"));
243
+ });
244
+ target
245
+ .command("verify")
246
+ .description("Alias of api verify + profile validate")
247
+ .action(() => {
248
+ const issues = (0, index_js_1.validateCurrent)().filter((i) => i.severity === "error");
249
+ const lock = (0, index_js_1.verifyLock)();
250
+ if (issues.length || !lock.ok) {
251
+ console.error("cluaupp target verify: FAILED");
252
+ process.exit(1);
253
+ }
254
+ console.log("cluaupp target verify: OK");
255
+ });
256
+ target
257
+ .command("diff")
258
+ .argument("<snapshot>", "previous profile JSON")
259
+ .action((snapshot) => {
260
+ console.log(JSON.stringify((0, index_js_1.apiDiffAgainstSnapshot)(node_path_1.default.resolve(snapshot)), null, "\t"));
261
+ });
262
+ target
263
+ .command("lock")
264
+ .description("Regenerate lock from current sources (via api generate)")
265
+ .action(() => {
266
+ runGenerate();
267
+ });
268
+ }
269
+ function registerPlatformCommands(program) {
270
+ program
271
+ .command("optimize")
272
+ .description("Advisor + optional apply: native pragmas, SoA layout codegen")
273
+ .argument("[folder]", "game root", ".")
274
+ .option("--profile <file>", "Rank advice with cluaupp.profile.json (PGO)")
275
+ .option("--apply", "Write #pragma native (and --layout pragmas) into sources")
276
+ .option("--layout", "With --apply: #pragma layout soa + emit .cluaupp/generated/soa/*Soa.luau")
277
+ .option("--buffer", "With --layout: pack f32/i32 columns into buffer")
278
+ .action((folder, opts) => {
279
+ const root = node_path_1.default.resolve(folder);
280
+ const src = node_path_1.default.join(root, "src");
281
+ const files = node_fs_1.default.existsSync(src) ? (0, paths_js_1.collectSources)(src) : [];
282
+ const profilePath = opts.profile ? node_path_1.default.resolve(root, opts.profile) : (0, pgo_js_1.defaultProfilePath)(root);
283
+ const profile = (0, pgo_js_1.loadProfile)(profilePath);
284
+ const advice = [];
285
+ let appliedCount = 0;
286
+ for (const file of files) {
287
+ const rel = node_path_1.default.relative(root, file).replace(/\\/g, "/");
288
+ const source = node_fs_1.default.readFileSync(file, "utf8");
289
+ const ranked = (0, pgo_js_1.rankAdvice)((0, index_js_1.adviseOptimizer)(source, rel), profile);
290
+ for (const a of ranked) {
291
+ advice.push({ file: rel, ...a });
292
+ }
293
+ if (opts.apply) {
294
+ const result = (0, optimizer_apply_js_1.applyOptimizerHints)(source, rel, profile, {
295
+ layout: opts.layout === true,
296
+ useBuffer: opts.buffer === true,
297
+ projectRoot: root,
298
+ });
299
+ if (result.changed) {
300
+ node_fs_1.default.writeFileSync(file, result.source, "utf8");
301
+ appliedCount += result.applied.length;
302
+ console.error(`cluaupp optimize --apply: ${rel}: ${result.applied.join(", ")}`);
303
+ }
304
+ }
305
+ }
306
+ if (opts.apply && opts.layout) {
307
+ const plans = (0, optimizer_soa_js_1.collectSoaPlansFromProject)(root);
308
+ (0, optimizer_soa_js_1.writeSoaArtifacts)(root, plans, { useBuffer: opts.buffer === true });
309
+ }
310
+ if (opts.apply) {
311
+ console.error(`cluaupp optimize --apply: ${appliedCount} hint(s)`);
312
+ }
313
+ console.log(JSON.stringify(advice, null, "\t"));
314
+ });
315
+ program
316
+ .command("bridge")
317
+ .description("Studio↔IDE HTTP bridge (default :3847) — Open IDE from CluauppNav plugin")
318
+ .argument("[folder]", "game root", ".")
319
+ .option("-p, --port <n>", "Port", String(studio_bridge_js_1.BRIDGE_DEFAULT_PORT))
320
+ .action((folder, opts) => {
321
+ const root = node_path_1.default.resolve(folder);
322
+ const port = Number(opts.port) || studio_bridge_js_1.BRIDGE_DEFAULT_PORT;
323
+ const server = (0, studio_bridge_js_1.startStudioBridge)({
324
+ port,
325
+ projectRoot: root,
326
+ onEvent: (ev) => {
327
+ console.log(`cluaupp bridge: ${ev.type}`, ev.path || ev.message || "", ev.line ? `:${ev.line}` : "");
328
+ },
329
+ });
330
+ console.log(`cluaupp bridge: http://127.0.0.1:${server.port} (project ${root})`);
331
+ console.log("Keep this process running. Studio plugin → Open IDE / errors POST here.");
332
+ });
333
+ program
334
+ .command("profile")
335
+ .description("PGO: write template, or ingest Studio/playtest JSONL into cluaupp.profile.json")
336
+ .argument("[folder]", "game root", ".")
337
+ .option("--ingest <file>", "Merge JSON/JSONL profile events into cluaupp.profile.json")
338
+ .action((folder, opts) => {
339
+ const root = node_path_1.default.resolve(folder);
340
+ if (opts.ingest) {
341
+ const { profilePath, merged, profile } = (0, index_js_1.ingestProfile)(root, opts.ingest);
342
+ console.log(`cluaupp profile ingest: ${merged} event(s) → ${profilePath}`);
343
+ console.log(JSON.stringify({ hot: profile.hot, structs: profile.structs }, null, "\t"));
344
+ return;
345
+ }
346
+ const file = (0, pgo_js_1.writeProfileTemplate)(root);
347
+ console.log("cluaupp profile:", file);
348
+ });
349
+ program
350
+ .command("check-authority")
351
+ .description("Authority rules + call-graph (CLUAU-AUTH*)")
352
+ .argument("[folder]", "game root", ".")
353
+ .action((folder) => {
354
+ const root = node_path_1.default.resolve(folder);
355
+ const src = node_path_1.default.join(root, "src");
356
+ const files = node_fs_1.default.existsSync(src) ? (0, paths_js_1.collectSources)(src) : [];
357
+ const policy = (0, index_js_1.loadPlatformPolicy)(root);
358
+ const all = [...(0, index_js_1.checkAuthorityGraph)(root, "src", policy)];
359
+ for (const file of files) {
360
+ const rel = node_path_1.default.relative(root, file).replace(/\\/g, "/");
361
+ all.push(...(0, index_js_1.checkAuthority)(node_fs_1.default.readFileSync(file, "utf8"), rel, policy));
362
+ }
363
+ console.log(JSON.stringify(all, null, "\t"));
364
+ if (all.some((d) => d.severity === "error"))
365
+ process.exit(1);
366
+ });
367
+ program
368
+ .command("docs")
369
+ .description("Generate .cluaupp/PROJECT.md from DataModel + graph + Flare + optimizer advice")
370
+ .argument("[folder]", "game root", ".")
371
+ .action((folder) => {
372
+ const { outPath } = (0, project_docs_js_1.generateProjectDocs)(node_path_1.default.resolve(folder));
373
+ console.log("cluaupp docs:", outPath);
374
+ });
375
+ program
376
+ .command("security")
377
+ .description("Static security pattern scan (warnings)")
378
+ .argument("[folder]", "game root", ".")
379
+ .action((folder) => {
380
+ const root = node_path_1.default.resolve(folder);
381
+ const src = node_path_1.default.join(root, "src");
382
+ const files = node_fs_1.default.existsSync(src) ? (0, paths_js_1.collectSources)(src) : [];
383
+ const all = [];
384
+ for (const file of files) {
385
+ const rel = node_path_1.default.relative(root, file).replace(/\\/g, "/");
386
+ all.push(...(0, index_js_1.checkSecurity)(node_fs_1.default.readFileSync(file, "utf8"), rel));
387
+ }
388
+ console.log(JSON.stringify(all, null, "\t"));
389
+ });
390
+ program
391
+ .command("analyze")
392
+ .description("Alias of target doctor (full platform analysis)")
393
+ .argument("[folder]", "game root", ".")
394
+ .action((folder) => {
395
+ const report = (0, index_js_1.runDoctor)(node_path_1.default.resolve(folder));
396
+ console.log(JSON.stringify(report, null, "\t"));
397
+ if (!report.ok)
398
+ process.exit(1);
399
+ });
400
+ program
401
+ .command("add")
402
+ .description("Thin Wally wrapper: runs `wally add` when wally is on PATH")
403
+ .argument("<package>", "wally package spec")
404
+ .action((pkgName) => {
405
+ const r = (0, node_child_process_1.spawnSync)("wally", ["add", pkgName], { stdio: "inherit", shell: true });
406
+ if (r.error || (r.status ?? 1) !== 0) {
407
+ console.error("cluaupp add: install Wally and retry, or edit wally.toml by hand");
408
+ process.exit(r.status ?? 1);
409
+ }
410
+ });
411
+ }
412
+ function runGenerate(dump, skipHeaders, skipLuau, skipDocs = true) {
413
+ const started = Date.now();
414
+ const result = (0, index_js_1.generateAll)({ dumpPath: dump, skipHeaders, skipLuau, skipDocs });
415
+ console.log(`cluaupp api generate: schema v${result.profile.schemaVersion}, ${Object.keys(result.profile.classes).length} classes, ${Object.keys(result.profile.enums).length} enums, ${Object.keys(result.profile.datatypes).length} datatypes (${Date.now() - started}ms)`);
416
+ console.log("manifest:", result.manifestPath);
417
+ console.log("lock:", result.lockPath);
418
+ if (result.lspIndexPath) {
419
+ console.log("lsp-index:", result.lspIndexPath);
420
+ }
421
+ }
package/generated/cli.js CHANGED
@@ -22,6 +22,7 @@ const project_js_1 = require("./utils/project.js");
22
22
  Object.defineProperty(exports, "init", { enumerable: true, get: function () { return project_js_1.init; } });
23
23
  Object.defineProperty(exports, "watch", { enumerable: true, get: function () { return project_js_1.watch; } });
24
24
  const transpile_js_1 = require("./transpile.js");
25
+ const api_cli_js_1 = require("./api-cli.js");
25
26
  const program = new commander_1.Command();
26
27
  exports.program = program;
27
28
  program
@@ -53,20 +54,27 @@ program
53
54
  .option("-o, --output <path>", "Luau file or directory")
54
55
  .option("-r, --rojo <path>", "Path to Rojo default.project.json", "./default.project.json")
55
56
  .option("--strict", "Emit --!strict")
56
- .option("--format", "Run StyLua on output")
57
+ .option("--format", "Also run StyLua if it is on PATH")
57
58
  .option("--analyze", "Run luau-analyze on output")
59
+ .option("--frozen", "Hermetic: fail if API lock / Flare versions / component contracts drift")
60
+ .option("--no-incremental", "Disable compile cache under .cluaupp/compile-cache")
61
+ .option("-j, --jobs <n>", "Parallel transpile workers (default: CPU-bounded; env CLUAUPP_JOBS)", (v) => Number(v))
58
62
  .action(async (folder, options) => {
59
63
  if (options.input) {
60
64
  await buildInput(options);
61
65
  return;
62
66
  }
63
67
  try {
64
- (0, project_js_1.build)(node_path_1.default.resolve(process.cwd(), folder), {
68
+ const opts = {
65
69
  format: options.format === true,
66
70
  analyze: options.analyze === true,
67
71
  rojo: options.rojo,
68
72
  strict: options.strict === true,
69
- });
73
+ frozen: options.frozen === true,
74
+ incremental: options.incremental !== false,
75
+ jobs: Number.isFinite(options.jobs) && options.jobs > 0 ? options.jobs : undefined,
76
+ };
77
+ await (0, project_js_1.buildAsync)(node_path_1.default.resolve(process.cwd(), folder), opts);
70
78
  }
71
79
  catch (err) {
72
80
  console.error(err instanceof Error ? err.message : err);
@@ -78,7 +86,7 @@ program
78
86
  .description("rebuild on save")
79
87
  .argument("[folder]", "project folder", ".")
80
88
  .option("-r, --rojo <path>", "Path to Rojo default.project.json", "./default.project.json")
81
- .option("--format", "Run StyLua on output")
89
+ .option("--format", "Also run StyLua if it is on PATH")
82
90
  .action((folder, options) => {
83
91
  try {
84
92
  (0, project_js_1.watch)(node_path_1.default.resolve(process.cwd(), folder), {
@@ -93,7 +101,7 @@ program
93
101
  });
94
102
  program
95
103
  .command("lsp")
96
- .description("Language server stdio (JSON-RPC). Use `clpp install` for CL++ IntelliSense.")
104
+ .description("Language server stdio — Flare `.flare` IntelliSense. CL++ still uses `clpp setup`.")
97
105
  .argument("[folder]", "project folder", ".")
98
106
  .action((folder) => {
99
107
  (0, lsp_js_1.start)({ projectRoot: node_path_1.default.resolve(process.cwd(), folder) });
@@ -101,7 +109,7 @@ program
101
109
  program
102
110
  .command("intellisense")
103
111
  .alias("intelisense")
104
- .description("Point the editor at CL++ (`clpp install`)")
112
+ .description("Install schema IntelliSense (.flare .hive .mint .bloom .helm .shift .axiom) + sync .vscode; CL++ via clpp install")
105
113
  .argument("[folder]", "project folder", ".")
106
114
  .action(async (folder) => {
107
115
  try {
@@ -138,6 +146,9 @@ program
138
146
  process.exit(1);
139
147
  }
140
148
  });
149
+ (0, api_cli_js_1.registerApiCommands)(program);
150
+ (0, api_cli_js_1.registerTargetCommands)(program);
151
+ (0, api_cli_js_1.registerPlatformCommands)(program);
141
152
  async function buildInput(options) {
142
153
  if (!options.input || !options.output) {
143
154
  console.error("[Erro] --input e --output são obrigatórios neste modo.");
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
- /** Stable CL++ ↔ Cluaupp contract (CL++ 0.3.2 / 0.3.3). Cluaupp invokes the `clpp` binary. */
2
+ /** Stable CL++ ↔ Cluaupp contract (CL++ 0.8.x). Cluaupp invokes the `clpp` binary. */
3
3
  Object.defineProperty(exports, "__esModule", { value: true });
4
4
  exports.CLPP_INSTALL_HINT = exports.MIN_CLPP_VERSION = void 0;
5
- exports.MIN_CLPP_VERSION = "0.3.2";
6
- exports.CLPP_INSTALL_HINT = "Install CL++ 0.3.2 or newer (clpp-setup.exe or `clpp setup`) and put `clpp` on PATH. 0.3.3 is the same JSON contract. Instances are class names (`Player player`, not `Player*`). Override with CLPP or CLPP_PATH.";
5
+ exports.MIN_CLPP_VERSION = "0.8.0";
6
+ exports.CLPP_INSTALL_HINT = "Install CL++ 0.8.0+ (`clpp` from https://github.com/KartzRbx/CLPP/releases). Put it on PATH. Prefer `import { Name } from \"./x.clh\"` for language modules; angle `#include <clpp/…>` stays for host prelude. Override with CLPP or CLPP_PATH.";