picopilot 0.0.0 → 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (334) hide show
  1. package/LICENSE +661 -0
  2. package/dist/bin.d.ts +3 -0
  3. package/dist/bin.d.ts.map +1 -0
  4. package/dist/bin.js +4 -0
  5. package/dist/bin.js.map +1 -0
  6. package/dist/cli.d.ts +15 -0
  7. package/dist/cli.d.ts.map +1 -0
  8. package/dist/cli.js +59 -0
  9. package/dist/cli.js.map +1 -0
  10. package/dist/commands/audio.d.ts +17 -0
  11. package/dist/commands/audio.d.ts.map +1 -0
  12. package/dist/commands/audio.js +315 -0
  13. package/dist/commands/audio.js.map +1 -0
  14. package/dist/commands/export.d.ts +36 -0
  15. package/dist/commands/export.d.ts.map +1 -0
  16. package/dist/commands/export.js +257 -0
  17. package/dist/commands/export.js.map +1 -0
  18. package/dist/commands/gfx.d.ts +28 -0
  19. package/dist/commands/gfx.d.ts.map +1 -0
  20. package/dist/commands/gfx.js +521 -0
  21. package/dist/commands/gfx.js.map +1 -0
  22. package/dist/commands/init.d.ts +34 -0
  23. package/dist/commands/init.d.ts.map +1 -0
  24. package/dist/commands/init.js +151 -0
  25. package/dist/commands/init.js.map +1 -0
  26. package/dist/commands/lint.d.ts +20 -0
  27. package/dist/commands/lint.d.ts.map +1 -0
  28. package/dist/commands/lint.js +90 -0
  29. package/dist/commands/lint.js.map +1 -0
  30. package/dist/commands/minify.d.ts +20 -0
  31. package/dist/commands/minify.d.ts.map +1 -0
  32. package/dist/commands/minify.js +129 -0
  33. package/dist/commands/minify.js.map +1 -0
  34. package/dist/commands/music.d.ts +13 -0
  35. package/dist/commands/music.d.ts.map +1 -0
  36. package/dist/commands/music.js +241 -0
  37. package/dist/commands/music.js.map +1 -0
  38. package/dist/commands/playtest.d.ts +29 -0
  39. package/dist/commands/playtest.d.ts.map +1 -0
  40. package/dist/commands/playtest.js +631 -0
  41. package/dist/commands/playtest.js.map +1 -0
  42. package/dist/commands/run.d.ts +30 -0
  43. package/dist/commands/run.d.ts.map +1 -0
  44. package/dist/commands/run.js +202 -0
  45. package/dist/commands/run.js.map +1 -0
  46. package/dist/commands/serve.d.ts +50 -0
  47. package/dist/commands/serve.d.ts.map +1 -0
  48. package/dist/commands/serve.js +213 -0
  49. package/dist/commands/serve.js.map +1 -0
  50. package/dist/commands/sfx.d.ts +13 -0
  51. package/dist/commands/sfx.d.ts.map +1 -0
  52. package/dist/commands/sfx.js +254 -0
  53. package/dist/commands/sfx.js.map +1 -0
  54. package/dist/commands/tokens.d.ts +36 -0
  55. package/dist/commands/tokens.d.ts.map +1 -0
  56. package/dist/commands/tokens.js +129 -0
  57. package/dist/commands/tokens.js.map +1 -0
  58. package/dist/commands/verify.d.ts +57 -0
  59. package/dist/commands/verify.d.ts.map +1 -0
  60. package/dist/commands/verify.js +213 -0
  61. package/dist/commands/verify.js.map +1 -0
  62. package/dist/commands/version.d.ts +12 -0
  63. package/dist/commands/version.d.ts.map +1 -0
  64. package/dist/commands/version.js +24 -0
  65. package/dist/commands/version.js.map +1 -0
  66. package/dist/engine/audio/index.d.ts +14 -0
  67. package/dist/engine/audio/index.d.ts.map +1 -0
  68. package/dist/engine/audio/index.js +14 -0
  69. package/dist/engine/audio/index.js.map +1 -0
  70. package/dist/engine/audio/music.d.ts +116 -0
  71. package/dist/engine/audio/music.d.ts.map +1 -0
  72. package/dist/engine/audio/music.js +138 -0
  73. package/dist/engine/audio/music.js.map +1 -0
  74. package/dist/engine/audio/section.d.ts +34 -0
  75. package/dist/engine/audio/section.d.ts.map +1 -0
  76. package/dist/engine/audio/section.js +67 -0
  77. package/dist/engine/audio/section.js.map +1 -0
  78. package/dist/engine/audio/sfx.d.ts +141 -0
  79. package/dist/engine/audio/sfx.d.ts.map +1 -0
  80. package/dist/engine/audio/sfx.js +506 -0
  81. package/dist/engine/audio/sfx.js.map +1 -0
  82. package/dist/engine/cart/cart.d.ts +75 -0
  83. package/dist/engine/cart/cart.d.ts.map +1 -0
  84. package/dist/engine/cart/cart.js +153 -0
  85. package/dist/engine/cart/cart.js.map +1 -0
  86. package/dist/engine/cart/errors.d.ts +29 -0
  87. package/dist/engine/cart/errors.d.ts.map +1 -0
  88. package/dist/engine/cart/errors.js +26 -0
  89. package/dist/engine/cart/errors.js.map +1 -0
  90. package/dist/engine/cart/gfx.d.ts +79 -0
  91. package/dist/engine/cart/gfx.d.ts.map +1 -0
  92. package/dist/engine/cart/gfx.js +171 -0
  93. package/dist/engine/cart/gfx.js.map +1 -0
  94. package/dist/engine/cart/index.d.ts +15 -0
  95. package/dist/engine/cart/index.d.ts.map +1 -0
  96. package/dist/engine/cart/index.js +15 -0
  97. package/dist/engine/cart/index.js.map +1 -0
  98. package/dist/engine/cart/map.d.ts +46 -0
  99. package/dist/engine/cart/map.d.ts.map +1 -0
  100. package/dist/engine/cart/map.js +118 -0
  101. package/dist/engine/cart/map.js.map +1 -0
  102. package/dist/engine/config/config.d.ts +74 -0
  103. package/dist/engine/config/config.d.ts.map +1 -0
  104. package/dist/engine/config/config.js +103 -0
  105. package/dist/engine/config/config.js.map +1 -0
  106. package/dist/engine/config/index.d.ts +7 -0
  107. package/dist/engine/config/index.d.ts.map +1 -0
  108. package/dist/engine/config/index.js +7 -0
  109. package/dist/engine/config/index.js.map +1 -0
  110. package/dist/engine/gfx/grid.d.ts +51 -0
  111. package/dist/engine/gfx/grid.d.ts.map +1 -0
  112. package/dist/engine/gfx/grid.js +116 -0
  113. package/dist/engine/gfx/grid.js.map +1 -0
  114. package/dist/engine/gfx/index.d.ts +17 -0
  115. package/dist/engine/gfx/index.d.ts.map +1 -0
  116. package/dist/engine/gfx/index.js +17 -0
  117. package/dist/engine/gfx/index.js.map +1 -0
  118. package/dist/engine/gfx/label.d.ts +34 -0
  119. package/dist/engine/gfx/label.d.ts.map +1 -0
  120. package/dist/engine/gfx/label.js +190 -0
  121. package/dist/engine/gfx/label.js.map +1 -0
  122. package/dist/engine/gfx/overlap.d.ts +42 -0
  123. package/dist/engine/gfx/overlap.d.ts.map +1 -0
  124. package/dist/engine/gfx/overlap.js +57 -0
  125. package/dist/engine/gfx/overlap.js.map +1 -0
  126. package/dist/engine/gfx/palette.d.ts +29 -0
  127. package/dist/engine/gfx/palette.d.ts.map +1 -0
  128. package/dist/engine/gfx/palette.js +46 -0
  129. package/dist/engine/gfx/palette.js.map +1 -0
  130. package/dist/engine/gfx/png.d.ts +31 -0
  131. package/dist/engine/gfx/png.d.ts.map +1 -0
  132. package/dist/engine/gfx/png.js +165 -0
  133. package/dist/engine/gfx/png.js.map +1 -0
  134. package/dist/engine/gfx/render.d.ts +42 -0
  135. package/dist/engine/gfx/render.d.ts.map +1 -0
  136. package/dist/engine/gfx/render.js +72 -0
  137. package/dist/engine/gfx/render.js.map +1 -0
  138. package/dist/engine/index.d.ts +22 -0
  139. package/dist/engine/index.d.ts.map +1 -0
  140. package/dist/engine/index.js +22 -0
  141. package/dist/engine/index.js.map +1 -0
  142. package/dist/engine/pico8/adapter.d.ts +267 -0
  143. package/dist/engine/pico8/adapter.d.ts.map +1 -0
  144. package/dist/engine/pico8/adapter.js +37 -0
  145. package/dist/engine/pico8/adapter.js.map +1 -0
  146. package/dist/engine/pico8/drive.d.ts +308 -0
  147. package/dist/engine/pico8/drive.d.ts.map +1 -0
  148. package/dist/engine/pico8/drive.js +581 -0
  149. package/dist/engine/pico8/drive.js.map +1 -0
  150. package/dist/engine/pico8/harness.d.ts +146 -0
  151. package/dist/engine/pico8/harness.d.ts.map +1 -0
  152. package/dist/engine/pico8/harness.js +251 -0
  153. package/dist/engine/pico8/harness.js.map +1 -0
  154. package/dist/engine/pico8/index.d.ts +21 -0
  155. package/dist/engine/pico8/index.d.ts.map +1 -0
  156. package/dist/engine/pico8/index.js +21 -0
  157. package/dist/engine/pico8/index.js.map +1 -0
  158. package/dist/engine/pico8/sentinel.d.ts +63 -0
  159. package/dist/engine/pico8/sentinel.d.ts.map +1 -0
  160. package/dist/engine/pico8/sentinel.js +86 -0
  161. package/dist/engine/pico8/sentinel.js.map +1 -0
  162. package/dist/engine/pico8/session-daemon-entry.d.ts +10 -0
  163. package/dist/engine/pico8/session-daemon-entry.d.ts.map +1 -0
  164. package/dist/engine/pico8/session-daemon-entry.js +11 -0
  165. package/dist/engine/pico8/session-daemon-entry.js.map +1 -0
  166. package/dist/engine/pico8/session-daemon-main.d.ts +44 -0
  167. package/dist/engine/pico8/session-daemon-main.d.ts.map +1 -0
  168. package/dist/engine/pico8/session-daemon-main.js +71 -0
  169. package/dist/engine/pico8/session-daemon-main.js.map +1 -0
  170. package/dist/engine/pico8/session-daemon.d.ts +68 -0
  171. package/dist/engine/pico8/session-daemon.d.ts.map +1 -0
  172. package/dist/engine/pico8/session-daemon.js +264 -0
  173. package/dist/engine/pico8/session-daemon.js.map +1 -0
  174. package/dist/engine/pico8/session.d.ts +140 -0
  175. package/dist/engine/pico8/session.d.ts.map +1 -0
  176. package/dist/engine/pico8/session.js +250 -0
  177. package/dist/engine/pico8/session.js.map +1 -0
  178. package/dist/engine/pico8/shell.d.ts +103 -0
  179. package/dist/engine/pico8/shell.d.ts.map +1 -0
  180. package/dist/engine/pico8/shell.js +324 -0
  181. package/dist/engine/pico8/shell.js.map +1 -0
  182. package/dist/engine/pico8/supervisor.d.ts +137 -0
  183. package/dist/engine/pico8/supervisor.d.ts.map +1 -0
  184. package/dist/engine/pico8/supervisor.js +140 -0
  185. package/dist/engine/pico8/supervisor.js.map +1 -0
  186. package/dist/engine/scaffold/index.d.ts +8 -0
  187. package/dist/engine/scaffold/index.d.ts.map +1 -0
  188. package/dist/engine/scaffold/index.js +8 -0
  189. package/dist/engine/scaffold/index.js.map +1 -0
  190. package/dist/engine/scaffold/scaffold.d.ts +49 -0
  191. package/dist/engine/scaffold/scaffold.d.ts.map +1 -0
  192. package/dist/engine/scaffold/scaffold.js +217 -0
  193. package/dist/engine/scaffold/scaffold.js.map +1 -0
  194. package/dist/engine/shrinko/adapter.d.ts +167 -0
  195. package/dist/engine/shrinko/adapter.d.ts.map +1 -0
  196. package/dist/engine/shrinko/adapter.js +107 -0
  197. package/dist/engine/shrinko/adapter.js.map +1 -0
  198. package/dist/engine/shrinko/index.d.ts +13 -0
  199. package/dist/engine/shrinko/index.d.ts.map +1 -0
  200. package/dist/engine/shrinko/index.js +13 -0
  201. package/dist/engine/shrinko/index.js.map +1 -0
  202. package/dist/engine/shrinko/shell.d.ts +69 -0
  203. package/dist/engine/shrinko/shell.d.ts.map +1 -0
  204. package/dist/engine/shrinko/shell.js +156 -0
  205. package/dist/engine/shrinko/shell.js.map +1 -0
  206. package/dist/engine/skills/index.d.ts +8 -0
  207. package/dist/engine/skills/index.d.ts.map +1 -0
  208. package/dist/engine/skills/index.js +8 -0
  209. package/dist/engine/skills/index.js.map +1 -0
  210. package/dist/engine/skills/skills.d.ts +104 -0
  211. package/dist/engine/skills/skills.d.ts.map +1 -0
  212. package/dist/engine/skills/skills.js +149 -0
  213. package/dist/engine/skills/skills.js.map +1 -0
  214. package/dist/index.d.ts +10 -0
  215. package/dist/index.d.ts.map +1 -0
  216. package/dist/index.js +10 -0
  217. package/dist/index.js.map +1 -0
  218. package/dist/version.d.ts +2 -0
  219. package/dist/version.d.ts.map +1 -0
  220. package/dist/version.js +19 -0
  221. package/dist/version.js.map +1 -0
  222. package/package.json +48 -2
  223. package/src/bin.ts +4 -0
  224. package/src/cli.ts +61 -0
  225. package/src/commands/audio.test.ts +280 -0
  226. package/src/commands/audio.ts +410 -0
  227. package/src/commands/export.test.ts +310 -0
  228. package/src/commands/export.ts +316 -0
  229. package/src/commands/gfx-io.test.ts +178 -0
  230. package/src/commands/gfx.test.ts +470 -0
  231. package/src/commands/gfx.ts +645 -0
  232. package/src/commands/init.test.ts +460 -0
  233. package/src/commands/init.ts +193 -0
  234. package/src/commands/lint.test.ts +137 -0
  235. package/src/commands/lint.ts +117 -0
  236. package/src/commands/minify.test.ts +166 -0
  237. package/src/commands/minify.ts +156 -0
  238. package/src/commands/music.test.ts +272 -0
  239. package/src/commands/music.ts +288 -0
  240. package/src/commands/playtest.test.ts +317 -0
  241. package/src/commands/playtest.ts +773 -0
  242. package/src/commands/run.test.ts +238 -0
  243. package/src/commands/run.ts +259 -0
  244. package/src/commands/serve.test.ts +218 -0
  245. package/src/commands/serve.ts +272 -0
  246. package/src/commands/sfx.test.ts +349 -0
  247. package/src/commands/sfx.ts +300 -0
  248. package/src/commands/tokens.test.ts +212 -0
  249. package/src/commands/tokens.ts +168 -0
  250. package/src/commands/verify.test.ts +238 -0
  251. package/src/commands/verify.ts +256 -0
  252. package/src/commands/version.test.ts +70 -0
  253. package/src/commands/version.ts +24 -0
  254. package/src/engine/audio/index.ts +47 -0
  255. package/src/engine/audio/music.test.ts +188 -0
  256. package/src/engine/audio/music.ts +218 -0
  257. package/src/engine/audio/section.test.ts +124 -0
  258. package/src/engine/audio/section.ts +79 -0
  259. package/src/engine/audio/sfx.test.ts +410 -0
  260. package/src/engine/audio/sfx.ts +694 -0
  261. package/src/engine/cart/cart.test.ts +304 -0
  262. package/src/engine/cart/cart.ts +211 -0
  263. package/src/engine/cart/errors.ts +39 -0
  264. package/src/engine/cart/fixtures/crlf.p8 +6 -0
  265. package/src/engine/cart/fixtures/full.p8 +174 -0
  266. package/src/engine/cart/fixtures/header-only.p8 +2 -0
  267. package/src/engine/cart/fixtures/malformed-no-header.p8 +2 -0
  268. package/src/engine/cart/fixtures/minimal.p8 +10 -0
  269. package/src/engine/cart/fixtures/no-trailing-newline.p8 +6 -0
  270. package/src/engine/cart/gfx.ts +195 -0
  271. package/src/engine/cart/index.ts +27 -0
  272. package/src/engine/cart/map.ts +134 -0
  273. package/src/engine/config/config.ts +115 -0
  274. package/src/engine/config/index.ts +12 -0
  275. package/src/engine/gfx/grid.test.ts +128 -0
  276. package/src/engine/gfx/grid.ts +136 -0
  277. package/src/engine/gfx/index.ts +34 -0
  278. package/src/engine/gfx/label.test.ts +105 -0
  279. package/src/engine/gfx/label.ts +229 -0
  280. package/src/engine/gfx/overlap.test.ts +71 -0
  281. package/src/engine/gfx/overlap.ts +66 -0
  282. package/src/engine/gfx/palette.test.ts +35 -0
  283. package/src/engine/gfx/palette.ts +54 -0
  284. package/src/engine/gfx/png.test.ts +111 -0
  285. package/src/engine/gfx/png.ts +196 -0
  286. package/src/engine/gfx/render.test.ts +180 -0
  287. package/src/engine/gfx/render.ts +106 -0
  288. package/src/engine/index.ts +21 -0
  289. package/src/engine/pico8/adapter.ts +303 -0
  290. package/src/engine/pico8/drive.test.ts +415 -0
  291. package/src/engine/pico8/drive.ts +729 -0
  292. package/src/engine/pico8/harness.test.ts +181 -0
  293. package/src/engine/pico8/harness.ts +354 -0
  294. package/src/engine/pico8/index.ts +20 -0
  295. package/src/engine/pico8/sentinel.test.ts +80 -0
  296. package/src/engine/pico8/sentinel.ts +93 -0
  297. package/src/engine/pico8/session-daemon-entry.ts +12 -0
  298. package/src/engine/pico8/session-daemon-main.ts +98 -0
  299. package/src/engine/pico8/session-daemon.test.ts +212 -0
  300. package/src/engine/pico8/session-daemon.ts +306 -0
  301. package/src/engine/pico8/session.test.ts +239 -0
  302. package/src/engine/pico8/session.ts +321 -0
  303. package/src/engine/pico8/shell.test.ts +583 -0
  304. package/src/engine/pico8/shell.ts +412 -0
  305. package/src/engine/pico8/supervisor.test.ts +105 -0
  306. package/src/engine/pico8/supervisor.ts +197 -0
  307. package/src/engine/scaffold/index.ts +15 -0
  308. package/src/engine/scaffold/scaffold.ts +236 -0
  309. package/src/engine/shrinko/adapter.ts +241 -0
  310. package/src/engine/shrinko/fixtures/count-no-compressed.txt +2 -0
  311. package/src/engine/shrinko/fixtures/count-over-budget.txt +3 -0
  312. package/src/engine/shrinko/fixtures/count-under-budget.txt +3 -0
  313. package/src/engine/shrinko/index.ts +33 -0
  314. package/src/engine/shrinko/shell.ts +224 -0
  315. package/src/engine/shrinko/shrinko.test.ts +182 -0
  316. package/src/engine/skills/index.ts +14 -0
  317. package/src/engine/skills/skills.test.ts +376 -0
  318. package/src/engine/skills/skills.ts +205 -0
  319. package/src/index.ts +13 -0
  320. package/src/skills/game-design-reference/SKILL.md +70 -0
  321. package/src/skills/game-jam/SKILL.md +45 -0
  322. package/src/skills/picopilot-art/SKILL.md +62 -0
  323. package/src/skills/picopilot-audio/SKILL.md +194 -0
  324. package/src/skills/picopilot-code/SKILL.md +97 -0
  325. package/src/skills/picopilot-code/reference/README.md +42 -0
  326. package/src/skills/picopilot-code/reference/mode7-racing.md +95 -0
  327. package/src/skills/picopilot-code/reference/platformer.md +119 -0
  328. package/src/skills/picopilot-code/reference/puzzle-grid.md +106 -0
  329. package/src/skills/picopilot-code/reference/rpg-menus-dialog.md +122 -0
  330. package/src/skills/picopilot-code/reference/top-down-adventure.md +117 -0
  331. package/src/skills/picopilot-code/reference/twin-stick-arcade.md +128 -0
  332. package/src/skills/picopilot-debug/SKILL.md +195 -0
  333. package/src/skills/picopilot-overview/SKILL.md +52 -0
  334. package/src/version.ts +22 -0
@@ -0,0 +1,257 @@
1
+ import { existsSync, mkdirSync, mkdtempSync, readdirSync, readFileSync, rmSync, writeFileSync, } from 'node:fs';
2
+ import { tmpdir } from 'node:os';
3
+ import { dirname, isAbsolute, join, resolve } from 'node:path';
4
+ import { z } from 'incur';
5
+ import { Cart, CartParseError } from '../engine/cart/index.js';
6
+ import { labelHexFromPng, LabelError } from '../engine/gfx/index.js';
7
+ import { EXPORT_HTML_NAME, ShellPico8Adapter, } from '../engine/pico8/index.js';
8
+ const defaultAdapterFactory = (env) => new ShellPico8Adapter({ env });
9
+ /** The default backstop: kill an export that never completes/exits after this many ms. */
10
+ const DEFAULT_BACKSTOP_MS = 30_000;
11
+ /**
12
+ * Registers `picopilot export`, the THIN structured wrapper over PICO-8's HTML
13
+ * export (`pico8 <cart> -export <name>.html -x`, the headless `-x` path, no
14
+ * display needed). It is NOT a `pico8` reimplementation: PICO-8 owns the bundle
15
+ * (an Emscripten runtime `.js` with the cart baked in, plus a shell `.html`).
16
+ * The value picopilot adds is the glue an agent should not hand-roll: resolve
17
+ * the cart, pick/create the output dir, name the pair `index.html` + `index.js`
18
+ * so a dest folder is directly serveable/showcase-ready, and return ONE
19
+ * structured result (output dir + file paths + the labelless-cart warning). It
20
+ * hard-requires PICO-8; absence is a first-class `pico8-not-found` value + a
21
+ * nonzero exit (mirrors `run`), never a crash or a hang. Live export is the
22
+ * manual/opt-in tier; the absent path is the CI-testable one.
23
+ *
24
+ * Two shapes, one command:
25
+ * - default (standalone): keep the `index.html` + `index.js` pair; the html
26
+ * references its sibling by name, so the dir plays directly (and `serve`
27
+ * uses this internally).
28
+ * - `--payload-only`: keep only the `.js` runtime payload; drop the shell page.
29
+ * For a website that provides its OWN player shell (a Svelte component that
30
+ * ports PICO-8's small bootstrap and loads the exported `.js`). The split is
31
+ * a post-export file op the command owns, never the PICO-8 binary's concern.
32
+ *
33
+ * @param adapterFactory injects the adapter (defaults to the shell adapter);
34
+ * tests pass a stub to drive present/absent without the real binary.
35
+ */
36
+ export function registerExport(cli, adapterFactory = defaultAdapterFactory) {
37
+ cli.command('export', {
38
+ description: "Export a cart to a playable HTML bundle (index.html + index.js) via the user's PICO-8. Requires PICO-8.",
39
+ args: z.object({
40
+ cart: z
41
+ .string()
42
+ .default('main.p8')
43
+ .describe('The .p8 cart to export. Defaults to main.p8 in the current folder.'),
44
+ dest: z
45
+ .string()
46
+ .optional()
47
+ .describe('Output folder (created if missing). Point it at a showcase dir (e.g. ./website/static/games/<slug>/). Defaults to an isolated temp dir.'),
48
+ }),
49
+ options: z.object({
50
+ label: z
51
+ .string()
52
+ .optional()
53
+ .describe('Path to a 128x128 PNG to bake in as the cart __label__ (the export splash), for a cart that has none. Ignored if the cart already has a label.'),
54
+ payloadOnly: z
55
+ .boolean()
56
+ .default(false)
57
+ .describe('Keep only the .js runtime payload (drop the shell .html), for a site that provides its own player component.'),
58
+ backstopMs: z
59
+ .number()
60
+ .int()
61
+ .positive()
62
+ .default(DEFAULT_BACKSTOP_MS)
63
+ .describe('Safety backstop: kill PICO-8 after this many ms if the export never completes.'),
64
+ }),
65
+ // incur resolves these from the (test-overridable) env source and hands
66
+ // them to the child, so PICO8_PATH/PATH locate the binary in isolation.
67
+ env: z.object({
68
+ PICO8_PATH: z
69
+ .string()
70
+ .optional()
71
+ .describe('Explicit path to the PICO-8 binary (else `pico8` on PATH).'),
72
+ PATH: z.string().optional().describe('Used to locate `pico8`.'),
73
+ }),
74
+ output: z.object({
75
+ outDir: z
76
+ .string()
77
+ .describe('Absolute path of the folder the bundle was written to.'),
78
+ html: z
79
+ .string()
80
+ .optional()
81
+ .describe('Absolute path of the shell index.html (omitted with --payload-only).'),
82
+ js: z.string().describe('Absolute path of the runtime payload index.js.'),
83
+ files: z
84
+ .array(z.string())
85
+ .describe('Absolute paths of every file the bundle contains.'),
86
+ labelWarning: z
87
+ .boolean()
88
+ .describe('True when the cart has no __label__: it exports with a blank/ugly splash.'),
89
+ }),
90
+ examples: [
91
+ { description: 'Export main.p8 to a temp dir' },
92
+ {
93
+ description: 'Export a cart into a showcase folder',
94
+ args: { cart: 'game.p8', dest: './website/static/games/my-game' },
95
+ },
96
+ {
97
+ description: 'Bake a PNG as the label splash for a labelless cart',
98
+ args: { cart: 'game.p8', dest: './website/static/games/my-game' },
99
+ options: { label: './label.png' },
100
+ },
101
+ {
102
+ description: 'Export only the runtime payload for a site player component',
103
+ args: { cart: 'game.p8', dest: './website/static/games/my-game' },
104
+ options: { payloadOnly: true },
105
+ },
106
+ ],
107
+ async run({ args, options, env, error, ok }) {
108
+ const cartPath = isAbsolute(args.cart)
109
+ ? args.cart
110
+ : resolve(process.cwd(), args.cart);
111
+ // A missing cart is a picopilot-side error, distinct from PICO-8 absence.
112
+ if (!existsSync(cartPath)) {
113
+ return error({
114
+ code: 'cart-not-found',
115
+ message: `no cart at ${cartPath}`,
116
+ exitCode: 1,
117
+ });
118
+ }
119
+ // --label <png>: bake a 128x128 PNG in as the cart's __label__ so a
120
+ // labelless cart gets a splash without an interactive F7 capture. We do
121
+ // NOT mutate the user's cart: we write a labeled copy NEXT TO it (same dir,
122
+ // so `#include main.lua` still resolves) and export that, then clean it up.
123
+ // A cart that ALREADY has a label wins (the flag is a fallback, not an
124
+ // override), matching the export precedence PICO-8 itself uses.
125
+ let exportCartPath = cartPath;
126
+ let labeledCopy;
127
+ if (options.label !== undefined) {
128
+ const labelPath = isAbsolute(options.label)
129
+ ? options.label
130
+ : resolve(process.cwd(), options.label);
131
+ if (!existsSync(labelPath)) {
132
+ return error({
133
+ code: 'label-not-found',
134
+ message: `no label image at ${labelPath}`,
135
+ exitCode: 1,
136
+ });
137
+ }
138
+ try {
139
+ const cart = Cart.parse(readFileSync(cartPath, 'utf8'));
140
+ const existingLabel = cart.getSection('label');
141
+ if (existingLabel === undefined || existingLabel.trim() === '') {
142
+ const hex = labelHexFromPng(readFileSync(labelPath));
143
+ cart.setSection('label', hex);
144
+ labeledCopy = join(dirname(cartPath), `.picopilot-export-${process.pid}-${Date.now()}.p8`);
145
+ writeFileSync(labeledCopy, cart.serialize());
146
+ exportCartPath = labeledCopy;
147
+ }
148
+ // else: cart already has a label; keep it, ignore --label.
149
+ }
150
+ catch (e) {
151
+ if (e instanceof LabelError) {
152
+ return error({
153
+ code: `label-${e.code}`,
154
+ message: e.message,
155
+ exitCode: 1,
156
+ });
157
+ }
158
+ if (e instanceof CartParseError) {
159
+ return error({
160
+ code: `cart-${e.code}`,
161
+ message: `could not parse the cart to inject a label: ${e.message}`,
162
+ exitCode: 1,
163
+ });
164
+ }
165
+ throw e;
166
+ }
167
+ }
168
+ // Output dir: a user-given dest (point it at the showcase), else an
169
+ // isolated temp dir. Create it so PICO-8 has somewhere to write.
170
+ const outDir = args.dest !== undefined
171
+ ? isAbsolute(args.dest)
172
+ ? args.dest
173
+ : resolve(process.cwd(), args.dest)
174
+ : mkdtempSync(join(tmpdir(), 'picopilot-export-'));
175
+ if (!existsSync(outDir))
176
+ mkdirSync(outDir, { recursive: true });
177
+ const adapter = adapterFactory(env);
178
+ const result = await adapter.export({
179
+ cartPath: exportCartPath,
180
+ outDir,
181
+ htmlName: EXPORT_HTML_NAME,
182
+ backstopMs: options.backstopMs,
183
+ });
184
+ // Remove the temporary labeled copy now that PICO-8 has read it (on every
185
+ // path below); best-effort, a leftover dotfile is not fatal.
186
+ if (labeledCopy !== undefined) {
187
+ try {
188
+ rmSync(labeledCopy);
189
+ }
190
+ catch {
191
+ // ignore
192
+ }
193
+ }
194
+ if (!result.ok) {
195
+ // The two-tier structured failure: PICO-8 absent. The message carries
196
+ // the exact remedy + needs; the code is the handle.
197
+ return error({
198
+ code: result.reason,
199
+ message: `PICO-8 is not installed. ${result.remedy} (needs: ${result.needs.join(', ')})`,
200
+ exitCode: 1,
201
+ });
202
+ }
203
+ let { htmlPath, jsPath, files, labelWarning } = result.value;
204
+ // PICO-8 must have produced the runtime payload; if not, the export failed
205
+ // (most often a labelless-cart bail that wrote nothing).
206
+ if (jsPath === undefined) {
207
+ return error({
208
+ code: 'export-failed',
209
+ message: labelWarning
210
+ ? 'PICO-8 produced no bundle (the cart has no __label__ to embed). Give it one with --label <128x128.png>, or capture a label in PICO-8 (F7), then re-export.'
211
+ : 'PICO-8 produced no export bundle. Check the cart runs without a boot error.',
212
+ exitCode: 1,
213
+ });
214
+ }
215
+ // --payload-only: drop the shell .html; keep just the runtime payload the
216
+ // site's own player component loads. A post-export file op we own, not the
217
+ // binary's concern.
218
+ if (options.payloadOnly && htmlPath !== undefined) {
219
+ try {
220
+ rmSync(htmlPath);
221
+ }
222
+ catch {
223
+ // A stubborn html is not fatal: the payload is what matters.
224
+ }
225
+ htmlPath = undefined;
226
+ files = listFiles(outDir);
227
+ }
228
+ const cta = labelWarning && !options.payloadOnly
229
+ ? {
230
+ description: 'The cart has no __label__, so the export splash is blank. Add one for a nicer bundle:',
231
+ commands: [
232
+ {
233
+ command: 'export --label <128x128.png>',
234
+ description: 'Bake a PNG in as the label splash, or capture one in PICO-8 (F7) before exporting.',
235
+ },
236
+ ],
237
+ }
238
+ : undefined;
239
+ return ok({
240
+ outDir,
241
+ html: htmlPath,
242
+ js: jsPath,
243
+ files: [...files],
244
+ labelWarning,
245
+ }, cta === undefined ? undefined : { cta });
246
+ },
247
+ });
248
+ }
249
+ /** Absolute, sorted file paths currently in `dir` (post file-op re-scan). */
250
+ function listFiles(dir) {
251
+ if (!existsSync(dir))
252
+ return [];
253
+ return readdirSync(dir)
254
+ .sort()
255
+ .map((f) => join(dir, f));
256
+ }
257
+ //# sourceMappingURL=export.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"export.js","sourceRoot":"","sources":["../../src/commands/export.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,28 @@
1
+ import { Cli } from 'incur';
2
+ import { type ShrinkoAdapter } from '../engine/shrinko/index.js';
3
+ /** Injects the shrinko adapter `gfx import`/`gfx export` use (the spritesheet round-trip). */
4
+ export type ShrinkoAdapterFactory = (env: NodeJS.ProcessEnv) => ShrinkoAdapter;
5
+ /**
6
+ * The exit code for the `map-overlap` refusal. Chosen as 1 (a plain failure),
7
+ * matching every other picopilot structured refusal (`cart-not-found`,
8
+ * `already-initialised`, `verify-failed`): the refusal is a "you asked for
9
+ * something I won't do" failure, not a distinct capability-gap the way `verify`'s
10
+ * `gate-incapable` (exit 2) is. What makes it safe is not a special exit code
11
+ * but that it is NON-ZERO (an agent must not read it as done) AND the sprite's
12
+ * bytes are left untouched.
13
+ */
14
+ export declare const MAP_OVERLAP_EXIT = 1;
15
+ /**
16
+ * Registers the `gfx` command group (`gfx show` / `gfx set`) on the root CLI.
17
+ *
18
+ * `gfx` is a shrinko-FREE command group (ADR-0002): it reads/writes `__gfx__`
19
+ * entirely through the cart model + the TS char-grid codec, so it works with
20
+ * shrinko absent and never spawns a child process. `gfx set` carries the
21
+ * gfx/map overlap smart-refuse (ADR-0004): a write to a shared-bank sprite
22
+ * (128-255) whose current pixels hold data is refused unless authorised, so
23
+ * picopilot never SILENTLY destroys shared-region data. `gfx render` is likewise
24
+ * shrinko-free: a pure-TS hex->PNG encoder using PICO-8's fixed 16-colour palette
25
+ * (the eyes-loop stays dependency-light, ADR/US #7).
26
+ */
27
+ export declare function registerGfx(cli: Cli.Cli, shrinkoFactory?: ShrinkoAdapterFactory): void;
28
+ //# sourceMappingURL=gfx.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"gfx.d.ts","sourceRoot":"","sources":["../../src/commands/gfx.ts"],"names":[],"mappings":"AAEA,OAAO,EAAC,GAAG,EAAI,MAAM,OAAO,CAAC;AAoB7B,OAAO,EACN,KAAK,cAAc,EAEnB,MAAM,4BAA4B,CAAC;AAEpC,8FAA8F;AAC9F,MAAM,MAAM,qBAAqB,GAAG,CAAC,GAAG,EAAE,MAAM,CAAC,UAAU,KAAK,cAAc,CAAC;AAK/E;;;;;;;;GAQG;AACH,eAAO,MAAM,gBAAgB,IAAI,CAAC;AAykBlC;;;;;;;;;;;GAWG;AACH,wBAAgB,WAAW,CAC1B,GAAG,EAAE,GAAG,CAAC,GAAG,EACZ,cAAc,GAAE,qBAA6C,GAC3D,IAAI,CAEN"}