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
package/dist/cli.d.ts ADDED
@@ -0,0 +1,15 @@
1
+ import { Cli } from 'incur';
2
+ /**
3
+ * Builds the root picopilot CLI.
4
+ *
5
+ * One `Cli.create()` definition yields the CLI, an MCP server, auto-installable
6
+ * skills, TOON output, Zod schemas, CTAs, and the structured error envelope.
7
+ * Command groups are mounted here through their `register*` helpers; each group
8
+ * owns its own module under `src/commands/` and its engine under `src/engine/`,
9
+ * so later tasks add a line here without restructuring.
10
+ *
11
+ * Exposed as a factory (not a module-level singleton) so tests can build a fresh
12
+ * CLI and drive it with `cli.serve(argv, { stdout, exit, env })` DI overrides.
13
+ */
14
+ export declare function createCli(): Cli.Cli;
15
+ //# sourceMappingURL=cli.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,GAAG,EAAC,MAAM,OAAO,CAAC;AAiB1B;;;;;;;;;;;GAWG;AACH,wBAAgB,SAAS,IAAI,GAAG,CAAC,GAAG,CA+BnC"}
package/dist/cli.js ADDED
@@ -0,0 +1,59 @@
1
+ import { Cli } from 'incur';
2
+ import { registerAudio } from './commands/audio.js';
3
+ import { registerExport } from './commands/export.js';
4
+ import { registerGfx } from './commands/gfx.js';
5
+ import { registerInit } from './commands/init.js';
6
+ import { registerLint } from './commands/lint.js';
7
+ import { registerMinify } from './commands/minify.js';
8
+ import { registerMusic } from './commands/music.js';
9
+ import { registerPlaytest } from './commands/playtest.js';
10
+ import { registerRun } from './commands/run.js';
11
+ import { registerServe } from './commands/serve.js';
12
+ import { registerSfx } from './commands/sfx.js';
13
+ import { registerTokens } from './commands/tokens.js';
14
+ import { registerVerify } from './commands/verify.js';
15
+ import { registerVersion } from './commands/version.js';
16
+ import { VERSION } from './version.js';
17
+ /**
18
+ * Builds the root picopilot CLI.
19
+ *
20
+ * One `Cli.create()` definition yields the CLI, an MCP server, auto-installable
21
+ * skills, TOON output, Zod schemas, CTAs, and the structured error envelope.
22
+ * Command groups are mounted here through their `register*` helpers; each group
23
+ * owns its own module under `src/commands/` and its engine under `src/engine/`,
24
+ * so later tasks add a line here without restructuring.
25
+ *
26
+ * Exposed as a factory (not a module-level singleton) so tests can build a fresh
27
+ * CLI and drive it with `cli.serve(argv, { stdout, exit, env })` DI overrides.
28
+ */
29
+ export function createCli() {
30
+ const cli = Cli.create('picopilot', {
31
+ version: VERSION,
32
+ description: 'An agent-first toolchain for PICO-8 game development.',
33
+ // `depth: 1` yields one skill file per top-level command group (US #20).
34
+ sync: {
35
+ depth: 1,
36
+ },
37
+ // Per-cart policy config (e.g. `allowMapOverlap`); precedence argv > config > defaults.
38
+ config: {
39
+ flag: 'config',
40
+ files: ['picopilot.json'],
41
+ },
42
+ });
43
+ registerVersion(cli);
44
+ registerInit(cli);
45
+ registerGfx(cli);
46
+ registerTokens(cli);
47
+ registerLint(cli);
48
+ registerMinify(cli);
49
+ registerVerify(cli);
50
+ registerRun(cli);
51
+ registerExport(cli);
52
+ registerServe(cli);
53
+ registerPlaytest(cli);
54
+ registerSfx(cli);
55
+ registerMusic(cli);
56
+ registerAudio(cli);
57
+ return cli;
58
+ }
59
+ //# sourceMappingURL=cli.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,GAAG,EAAC,MAAM,OAAO,CAAC;AAC1B,OAAO,EAAC,aAAa,EAAC,MAAM,qBAAqB,CAAC;AAClD,OAAO,EAAC,cAAc,EAAC,MAAM,sBAAsB,CAAC;AACpD,OAAO,EAAC,WAAW,EAAC,MAAM,mBAAmB,CAAC;AAC9C,OAAO,EAAC,YAAY,EAAC,MAAM,oBAAoB,CAAC;AAChD,OAAO,EAAC,YAAY,EAAC,MAAM,oBAAoB,CAAC;AAChD,OAAO,EAAC,cAAc,EAAC,MAAM,sBAAsB,CAAC;AACpD,OAAO,EAAC,aAAa,EAAC,MAAM,qBAAqB,CAAC;AAClD,OAAO,EAAC,gBAAgB,EAAC,MAAM,wBAAwB,CAAC;AACxD,OAAO,EAAC,WAAW,EAAC,MAAM,mBAAmB,CAAC;AAC9C,OAAO,EAAC,aAAa,EAAC,MAAM,qBAAqB,CAAC;AAClD,OAAO,EAAC,WAAW,EAAC,MAAM,mBAAmB,CAAC;AAC9C,OAAO,EAAC,cAAc,EAAC,MAAM,sBAAsB,CAAC;AACpD,OAAO,EAAC,cAAc,EAAC,MAAM,sBAAsB,CAAC;AACpD,OAAO,EAAC,eAAe,EAAC,MAAM,uBAAuB,CAAC;AACtD,OAAO,EAAC,OAAO,EAAC,MAAM,cAAc,CAAC;AAErC;;;;;;;;;;;GAWG;AACH,MAAM,UAAU,SAAS;IACxB,MAAM,GAAG,GAAG,GAAG,CAAC,MAAM,CAAC,WAAW,EAAE;QACnC,OAAO,EAAE,OAAO;QAChB,WAAW,EAAE,uDAAuD;QACpE,yEAAyE;QACzE,IAAI,EAAE;YACL,KAAK,EAAE,CAAC;SACR;QACD,wFAAwF;QACxF,MAAM,EAAE;YACP,IAAI,EAAE,QAAQ;YACd,KAAK,EAAE,CAAC,gBAAgB,CAAC;SACzB;KACD,CAAC,CAAC;IAEH,eAAe,CAAC,GAAG,CAAC,CAAC;IACrB,YAAY,CAAC,GAAG,CAAC,CAAC;IAClB,WAAW,CAAC,GAAG,CAAC,CAAC;IACjB,cAAc,CAAC,GAAG,CAAC,CAAC;IACpB,YAAY,CAAC,GAAG,CAAC,CAAC;IAClB,cAAc,CAAC,GAAG,CAAC,CAAC;IACpB,cAAc,CAAC,GAAG,CAAC,CAAC;IACpB,WAAW,CAAC,GAAG,CAAC,CAAC;IACjB,cAAc,CAAC,GAAG,CAAC,CAAC;IACpB,aAAa,CAAC,GAAG,CAAC,CAAC;IACnB,gBAAgB,CAAC,GAAG,CAAC,CAAC;IACtB,WAAW,CAAC,GAAG,CAAC,CAAC;IACjB,aAAa,CAAC,GAAG,CAAC,CAAC;IACnB,aAAa,CAAC,GAAG,CAAC,CAAC;IAEnB,OAAO,GAAG,CAAC;AACZ,CAAC"}
@@ -0,0 +1,17 @@
1
+ import { Cli } from 'incur';
2
+ import { type Pico8Adapter } from '../engine/pico8/index.js';
3
+ /**
4
+ * Injects the PICO-8 adapter the audio commands use (defaults to the shell
5
+ * adapter over native `pico8 -run`). Mirrors `run`'s `Pico8AdapterFactory` seam:
6
+ * a test passes a fake to drive the record orchestration + the absent path
7
+ * WITHOUT the paid binary, and to isolate the child `env`.
8
+ */
9
+ export type Pico8AdapterFactory = (env: NodeJS.ProcessEnv) => Pico8Adapter;
10
+ /**
11
+ * Registers the `audio` command group (`audio record`, `audio render`) on the
12
+ * root CLI. PICO-8-gated (ADR-0009): audio-to-WAV is a record of a running
13
+ * session, never an offline export. `adapterFactory` is injected so tests drive
14
+ * the orchestration against a fake runner (no paid binary in CI).
15
+ */
16
+ export declare function registerAudio(cli: Cli.Cli, adapterFactory?: Pico8AdapterFactory): void;
17
+ //# sourceMappingURL=audio.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"audio.d.ts","sourceRoot":"","sources":["../../src/commands/audio.ts"],"names":[],"mappings":"AASA,OAAO,EAAC,GAAG,EAAI,MAAM,OAAO,CAAC;AAE7B,OAAO,EAKN,KAAK,YAAY,EAGjB,MAAM,0BAA0B,CAAC;AAElC;;;;;GAKG;AACH,MAAM,MAAM,mBAAmB,GAAG,CAAC,GAAG,EAAE,MAAM,CAAC,UAAU,KAAK,YAAY,CAAC;AAmX3E;;;;;GAKG;AACH,wBAAgB,aAAa,CAC5B,GAAG,EAAE,GAAG,CAAC,GAAG,EACZ,cAAc,GAAE,mBAA2C,GACzD,IAAI,CAEN"}
@@ -0,0 +1,315 @@
1
+ import { existsSync, mkdirSync, mkdtempSync, readFileSync, writeFileSync, } from 'node:fs';
2
+ import { tmpdir } from 'node:os';
3
+ import { isAbsolute, join, resolve } from 'node:path';
4
+ import { Cli, z } from 'incur';
5
+ import { buildRecordHarness, buildRenderHarness, DONE_SENTINEL, HarnessError, ShellPico8Adapter, } from '../engine/pico8/index.js';
6
+ const defaultAdapterFactory = (env) => new ShellPico8Adapter({ env });
7
+ /**
8
+ * The default record backstop: kill a capture that never signals after this many
9
+ * ms. Larger than `run`'s default because a record window is a real-time playback
10
+ * (up to several seconds) plus PICO-8 startup, not a quick screenshot pass.
11
+ */
12
+ const DEFAULT_BACKSTOP_MS = 30_000;
13
+ /** The honest one-liner both `record` and `render` carry (ADR-0009): not offline. */
14
+ const HONEST_CAVEAT = 'This is a REAL-TIME recording of playback (needs a real audio+video session, not headless), NOT a deterministic offline export.';
15
+ /** Resolves a path argument to an absolute path (relative to cwd). */
16
+ function resolvePath(p) {
17
+ return isAbsolute(p) ? p : resolve(process.cwd(), p);
18
+ }
19
+ /**
20
+ * Chooses (and creates) the isolated dir PICO-8 records the WAV into. Because
21
+ * `extcmd("audio_end", 1)` writes to PICO-8's CURRENT folder (steered via
22
+ * `-root_path`), the WAV MUST land here, never `~/Desktop` or the carts root
23
+ * (the shared-write discipline, the `audio_end(1)` trap). A user-given path is
24
+ * honoured; otherwise a fresh temp dir.
25
+ */
26
+ function chooseWavDir(given) {
27
+ const dir = given !== undefined
28
+ ? isAbsolute(given)
29
+ ? given
30
+ : resolve(process.cwd(), given)
31
+ : mkdtempSync(join(tmpdir(), 'picopilot-audio-'));
32
+ if (!existsSync(dir))
33
+ mkdirSync(dir, { recursive: true });
34
+ return dir;
35
+ }
36
+ /** The env schema both audio subcommands share (locates the binary, in isolation). */
37
+ const AUDIO_ENV = z.object({
38
+ PICO8_PATH: z
39
+ .string()
40
+ .optional()
41
+ .describe('Explicit path to the PICO-8 binary (else `pico8` on PATH).'),
42
+ PATH: z.string().optional().describe('Used to locate `pico8`.'),
43
+ });
44
+ /** The structured output shape shared by `record` and `render`. */
45
+ const AUDIO_OUTPUT = z.object({
46
+ wav: z
47
+ .string()
48
+ .optional()
49
+ .describe('Absolute path of the recorded WAV, or omitted if no audio was captured (e.g. a headless session with no audio device).'),
50
+ captured: z
51
+ .boolean()
52
+ .describe('Whether a non-empty WAV was captured (false = silent/empty run).'),
53
+ exitReason: z
54
+ .enum(['sentinel', 'timeout', 'exit'])
55
+ .describe('sentinel = the harness signalled done; timeout = backstop fired; exit = PICO-8 quit.'),
56
+ target: z
57
+ .string()
58
+ .describe('What was recorded (the running cart, or the render target).'),
59
+ seconds: z
60
+ .number()
61
+ .describe('The record window in seconds the capture ran for.'),
62
+ printh: z.string().describe('Captured stdout from the session.'),
63
+ });
64
+ /** The message a `pico8-not-found` error carries (mirrors `run`): exact remedy + needs. */
65
+ function pico8NotFoundMessage(notFound) {
66
+ return `PICO-8 is not installed. ${notFound.remedy} (needs: ${notFound.needs.join(', ')})`;
67
+ }
68
+ /**
69
+ * The advisory CTA when a record/render run captured NO audio (a headless /
70
+ * no-audio-device session): the orchestration worked, there is just nothing to
71
+ * hear (ADR-0009's live-tier caveat), so it is a nudge, not a hard error.
72
+ */
73
+ function noAudioCta(caveat) {
74
+ return {
75
+ description: `No audio was captured (${caveat}) Recording needs a real audio+video session:`,
76
+ commands: [
77
+ {
78
+ command: 'audio render --sfx <n>',
79
+ description: 'Run on a developer machine with a display + audio device (not headless CI).',
80
+ },
81
+ ],
82
+ };
83
+ }
84
+ /** Shapes an adapter record report into the structured output object. */
85
+ function recordOutput(report, harness) {
86
+ return {
87
+ wav: report.wavPath,
88
+ captured: report.wavPath !== undefined,
89
+ exitReason: report.exitReason,
90
+ target: harness.description,
91
+ seconds: harness.seconds,
92
+ printh: report.printh,
93
+ };
94
+ }
95
+ /**
96
+ * Builds the `audio` command group: `audio record <cart>` (the record primitive)
97
+ * and `audio render` (US #13, the convenience harness over it). Both are
98
+ * PICO-8-gated (ADR-0009): PICO-8 absent returns the structured `pico8-not-found`
99
+ * + nonzero exit. Both are record-based, real-time captures, NOT offline exports.
100
+ */
101
+ function buildAudioGroup(adapterFactory) {
102
+ const audio = Cli.create('audio', {
103
+ description: 'Get a WAV out of a cart by RECORDING a running session (ADR-0009). PICO-8 has no working offline WAV export, so both commands are REAL-TIME recordings that need a real audio+video session (not headless), NOT deterministic offline exports. Requires PICO-8.',
104
+ });
105
+ // --- audio record <cart> ---------------------------------------------------
106
+ audio.command('record', {
107
+ description: `Record a running cart's own audio to a WAV. Injects a throwaway cooperative recorder (audio_rec/audio_end) around the cart, runs it in a real A/V session, and returns the WAV path. ${HONEST_CAVEAT} Requires PICO-8.`,
108
+ args: z.object({
109
+ cart: z
110
+ .string()
111
+ .default('main.p8')
112
+ .describe('The .p8 cart to run and record. Defaults to main.p8 in the current folder.'),
113
+ }),
114
+ options: z.object({
115
+ seconds: z.coerce
116
+ .number()
117
+ .positive()
118
+ .default(8)
119
+ .describe('How long (seconds) to record the running cart.'),
120
+ wavDir: z
121
+ .string()
122
+ .optional()
123
+ .describe('Where PICO-8 writes the WAV. Defaults to an isolated temp dir; NEVER ~/Desktop or the carts root.'),
124
+ sentinel: z
125
+ .string()
126
+ .default(DONE_SENTINEL)
127
+ .describe('The stdout line that ends the recording.'),
128
+ backstopMs: z
129
+ .number()
130
+ .int()
131
+ .positive()
132
+ .default(DEFAULT_BACKSTOP_MS)
133
+ .describe('Safety backstop: kill PICO-8 after this many ms if it never signals.'),
134
+ }),
135
+ env: AUDIO_ENV,
136
+ output: AUDIO_OUTPUT,
137
+ examples: [
138
+ { description: 'Record 8 seconds of main.p8' },
139
+ {
140
+ description: 'Record a specific cart for 4 seconds',
141
+ args: { cart: 'game.p8' },
142
+ options: { seconds: 4 },
143
+ },
144
+ ],
145
+ async run({ args, options, env, error, ok }) {
146
+ const cartPath = resolvePath(args.cart);
147
+ if (!existsSync(cartPath)) {
148
+ return error({
149
+ code: 'cart-not-found',
150
+ message: `no cart at ${cartPath}`,
151
+ exitCode: 1,
152
+ });
153
+ }
154
+ let harness;
155
+ try {
156
+ harness = buildRecordHarness(readFileSync(cartPath, 'utf8'), {
157
+ seconds: options.seconds,
158
+ sentinel: options.sentinel,
159
+ });
160
+ }
161
+ catch (e) {
162
+ if (e instanceof HarnessError) {
163
+ return error({ code: e.code, message: e.message, exitCode: 1 });
164
+ }
165
+ throw e;
166
+ }
167
+ // The throwaway harness cart + the WAV both live in the isolated dir, so a
168
+ // record run never mutates the user's cart or writes outside the temp dir.
169
+ const wavDir = chooseWavDir(options.wavDir);
170
+ const harnessCart = join(wavDir, 'record-harness.p8');
171
+ writeFileSync(harnessCart, harness.cartText);
172
+ const adapter = adapterFactory(env);
173
+ const result = await adapter.record({
174
+ cartPath: harnessCart,
175
+ wavDir,
176
+ wavBasename: harness.wavBasename,
177
+ sentinel: options.sentinel,
178
+ backstopMs: options.backstopMs,
179
+ });
180
+ if (!result.ok) {
181
+ return error({
182
+ code: 'pico8-not-found',
183
+ message: pico8NotFoundMessage(result),
184
+ exitCode: 1,
185
+ });
186
+ }
187
+ const out = recordOutput(result.value, harness);
188
+ return ok(out, out.captured ? undefined : { cta: noAudioCta(HONEST_CAVEAT) });
189
+ },
190
+ });
191
+ // --- audio render ----------------------------------------------------------
192
+ audio.command('render', {
193
+ description: `Render an authored target (sfx / music pattern / the whole song) to a WAV by injecting a play-harness, recording it, and returning the WAV path (US #13). The author writes NO playback code. ${HONEST_CAVEAT} With no --sfx/--pattern it renders the whole song (music 0). Requires PICO-8.`,
194
+ args: z.object({
195
+ cart: z
196
+ .string()
197
+ .default('main.p8')
198
+ .describe('The .p8 cart whose authored __sfx__/__music__ to render. Defaults to main.p8.'),
199
+ }),
200
+ options: z.object({
201
+ sfx: z.coerce
202
+ .number()
203
+ .int()
204
+ .min(0)
205
+ .max(63)
206
+ .optional()
207
+ .describe('Render this SFX slot (0-63). Mutually exclusive with --pattern.'),
208
+ pattern: z.coerce
209
+ .number()
210
+ .int()
211
+ .min(0)
212
+ .max(63)
213
+ .optional()
214
+ .describe('Render this music pattern (0-63). Mutually exclusive with --sfx.'),
215
+ seconds: z.coerce
216
+ .number()
217
+ .positive()
218
+ .optional()
219
+ .describe('Override the record window (seconds). Default: derived from the SFX speed+rows for --sfx, else 8s for a pattern/song.'),
220
+ wavDir: z
221
+ .string()
222
+ .optional()
223
+ .describe('Where PICO-8 writes the WAV. Defaults to an isolated temp dir; NEVER ~/Desktop or the carts root.'),
224
+ sentinel: z
225
+ .string()
226
+ .default(DONE_SENTINEL)
227
+ .describe('The stdout line that ends the recording.'),
228
+ backstopMs: z
229
+ .number()
230
+ .int()
231
+ .positive()
232
+ .default(DEFAULT_BACKSTOP_MS)
233
+ .describe('Safety backstop: kill PICO-8 after this many ms if it never signals.'),
234
+ }),
235
+ env: AUDIO_ENV,
236
+ output: AUDIO_OUTPUT,
237
+ examples: [
238
+ { description: 'Render the whole song (music 0) of main.p8' },
239
+ { description: 'Render SFX slot 5', options: { sfx: 5 } },
240
+ {
241
+ description: 'Render music pattern 2 of a cart for 6 seconds',
242
+ args: { cart: 'game.p8' },
243
+ options: { pattern: 2, seconds: 6 },
244
+ },
245
+ ],
246
+ async run({ args, options, env, error, ok }) {
247
+ if (options.sfx !== undefined && options.pattern !== undefined) {
248
+ return error({
249
+ code: 'ambiguous-target',
250
+ message: 'pass EITHER --sfx OR --pattern, not both (a render targets one of: an SFX slot, a music pattern, or the whole song).',
251
+ exitCode: 1,
252
+ });
253
+ }
254
+ const target = options.sfx !== undefined
255
+ ? { kind: 'sfx', index: options.sfx }
256
+ : options.pattern !== undefined
257
+ ? { kind: 'pattern', index: options.pattern }
258
+ : { kind: 'song' };
259
+ const cartPath = resolvePath(args.cart);
260
+ if (!existsSync(cartPath)) {
261
+ return error({
262
+ code: 'cart-not-found',
263
+ message: `no cart at ${cartPath}`,
264
+ exitCode: 1,
265
+ });
266
+ }
267
+ let harness;
268
+ try {
269
+ harness = buildRenderHarness(readFileSync(cartPath, 'utf8'), target, {
270
+ seconds: options.seconds,
271
+ sentinel: options.sentinel,
272
+ });
273
+ }
274
+ catch (e) {
275
+ if (e instanceof HarnessError) {
276
+ // A target refusal (out-of-range / empty slot / bad cart): structured,
277
+ // never a silent recording of silence.
278
+ return error({ code: e.code, message: e.message, exitCode: 1 });
279
+ }
280
+ throw e;
281
+ }
282
+ const wavDir = chooseWavDir(options.wavDir);
283
+ const harnessCart = join(wavDir, 'render-harness.p8');
284
+ writeFileSync(harnessCart, harness.cartText);
285
+ const adapter = adapterFactory(env);
286
+ const result = await adapter.record({
287
+ cartPath: harnessCart,
288
+ wavDir,
289
+ wavBasename: harness.wavBasename,
290
+ sentinel: options.sentinel,
291
+ backstopMs: options.backstopMs,
292
+ });
293
+ if (!result.ok) {
294
+ return error({
295
+ code: 'pico8-not-found',
296
+ message: pico8NotFoundMessage(result),
297
+ exitCode: 1,
298
+ });
299
+ }
300
+ const out = recordOutput(result.value, harness);
301
+ return ok(out, out.captured ? undefined : { cta: noAudioCta(HONEST_CAVEAT) });
302
+ },
303
+ });
304
+ return audio;
305
+ }
306
+ /**
307
+ * Registers the `audio` command group (`audio record`, `audio render`) on the
308
+ * root CLI. PICO-8-gated (ADR-0009): audio-to-WAV is a record of a running
309
+ * session, never an offline export. `adapterFactory` is injected so tests drive
310
+ * the orchestration against a fake runner (no paid binary in CI).
311
+ */
312
+ export function registerAudio(cli, adapterFactory = defaultAdapterFactory) {
313
+ cli.command(buildAudioGroup(adapterFactory));
314
+ }
315
+ //# sourceMappingURL=audio.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"audio.js","sourceRoot":"","sources":["../../src/commands/audio.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,36 @@
1
+ import { type Cli } from 'incur';
2
+ import { type Pico8Adapter } from '../engine/pico8/index.js';
3
+ /**
4
+ * Injects the PICO-8 adapter `export` uses (defaults to the shell adapter over
5
+ * native `pico8 <cart> -export <name>.html -x`). Mirrors the `run` seam: a test
6
+ * passes a stub to drive the present/absent paths without the paid binary, and
7
+ * to isolate the child `env` (its `PICO8_PATH`/`PATH`).
8
+ */
9
+ export type Pico8AdapterFactory = (env: NodeJS.ProcessEnv) => Pico8Adapter;
10
+ /**
11
+ * Registers `picopilot export`, the THIN structured wrapper over PICO-8's HTML
12
+ * export (`pico8 <cart> -export <name>.html -x`, the headless `-x` path, no
13
+ * display needed). It is NOT a `pico8` reimplementation: PICO-8 owns the bundle
14
+ * (an Emscripten runtime `.js` with the cart baked in, plus a shell `.html`).
15
+ * The value picopilot adds is the glue an agent should not hand-roll: resolve
16
+ * the cart, pick/create the output dir, name the pair `index.html` + `index.js`
17
+ * so a dest folder is directly serveable/showcase-ready, and return ONE
18
+ * structured result (output dir + file paths + the labelless-cart warning). It
19
+ * hard-requires PICO-8; absence is a first-class `pico8-not-found` value + a
20
+ * nonzero exit (mirrors `run`), never a crash or a hang. Live export is the
21
+ * manual/opt-in tier; the absent path is the CI-testable one.
22
+ *
23
+ * Two shapes, one command:
24
+ * - default (standalone): keep the `index.html` + `index.js` pair; the html
25
+ * references its sibling by name, so the dir plays directly (and `serve`
26
+ * uses this internally).
27
+ * - `--payload-only`: keep only the `.js` runtime payload; drop the shell page.
28
+ * For a website that provides its OWN player shell (a Svelte component that
29
+ * ports PICO-8's small bootstrap and loads the exported `.js`). The split is
30
+ * a post-export file op the command owns, never the PICO-8 binary's concern.
31
+ *
32
+ * @param adapterFactory injects the adapter (defaults to the shell adapter);
33
+ * tests pass a stub to drive present/absent without the real binary.
34
+ */
35
+ export declare function registerExport(cli: Cli.Cli, adapterFactory?: Pico8AdapterFactory): void;
36
+ //# sourceMappingURL=export.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"export.d.ts","sourceRoot":"","sources":["../../src/commands/export.ts"],"names":[],"mappings":"AAWA,OAAO,EAAC,KAAK,GAAG,EAAI,MAAM,OAAO,CAAC;AAGlC,OAAO,EAEN,KAAK,YAAY,EAEjB,MAAM,0BAA0B,CAAC;AAElC;;;;;GAKG;AACH,MAAM,MAAM,mBAAmB,GAAG,CAAC,GAAG,EAAE,MAAM,CAAC,UAAU,KAAK,YAAY,CAAC;AAQ3E;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,wBAAgB,cAAc,CAC7B,GAAG,EAAE,GAAG,CAAC,GAAG,EACZ,cAAc,GAAE,mBAA2C,GACzD,IAAI,CAqPN"}