picopilot 0.0.0 → 0.1.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 (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 +224 -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 +259 -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 +482 -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 +264 -0
  243. package/src/commands/run.ts +285 -0
  244. package/src/commands/serve.test.ts +227 -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 +278 -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,521 @@
1
+ import { existsSync, readFileSync, writeFileSync } from 'node:fs';
2
+ import { basename, dirname, extname, isAbsolute, join, resolve } from 'node:path';
3
+ import { Cli, z } from 'incur';
4
+ import { Cart, CartParseError, GFX_WIDTH, GfxSheet, SPRITE_SIZE, spriteAliasesMap, } from '../engine/cart/index.js';
5
+ import { decideOverlap, GfxGridError, gridToNibbles, nibblesToGrid, renderSheetPng, renderSpritePng, SHEET_RENDER_SCALE, SPRITE_RENDER_SCALE, } from '../engine/gfx/index.js';
6
+ import { ShellShrinkoAdapter, } from '../engine/shrinko/index.js';
7
+ const defaultShrinkoFactory = (env) => new ShellShrinkoAdapter({ env });
8
+ /**
9
+ * The exit code for the `map-overlap` refusal. Chosen as 1 (a plain failure),
10
+ * matching every other picopilot structured refusal (`cart-not-found`,
11
+ * `already-initialised`, `verify-failed`): the refusal is a "you asked for
12
+ * something I won't do" failure, not a distinct capability-gap the way `verify`'s
13
+ * `gate-incapable` (exit 2) is. What makes it safe is not a special exit code
14
+ * but that it is NON-ZERO (an agent must not read it as done) AND the sprite's
15
+ * bytes are left untouched.
16
+ */
17
+ export const MAP_OVERLAP_EXIT = 1;
18
+ /** Resolves a cart argument to an absolute path (relative to cwd). */
19
+ function resolveCart(cart) {
20
+ return isAbsolute(cart) ? cart : resolve(process.cwd(), cart);
21
+ }
22
+ /**
23
+ * The default PNG output path for a `gfx render`: alongside the cart, named
24
+ * `<cart-stem>-sprite-<n>.png` or `<cart-stem>-sheet.png`. Predictable + stable
25
+ * so an agent can render → look → fix → re-render at the SAME path without
26
+ * juggling filenames.
27
+ */
28
+ function defaultRenderPath(cartPath, target) {
29
+ const stem = basename(cartPath, extname(cartPath));
30
+ const suffix = target === 'sheet' ? 'sheet' : `sprite-${target}`;
31
+ return join(dirname(cartPath), `${stem}-${suffix}.png`);
32
+ }
33
+ /**
34
+ * Loads + parses a cart from `cartPath`, returning either the parsed cart and
35
+ * its source text or a structured reason the caller turns into an `error(...)`.
36
+ * Keeps the fs + parse boilerplate out of both command handlers.
37
+ */
38
+ function loadCart(cartPath) {
39
+ if (!existsSync(cartPath)) {
40
+ return {
41
+ ok: false,
42
+ code: 'cart-not-found',
43
+ message: `no cart at ${cartPath}`,
44
+ };
45
+ }
46
+ const text = readFileSync(cartPath, 'utf8');
47
+ try {
48
+ return { ok: true, cart: Cart.parse(text), text };
49
+ }
50
+ catch (e) {
51
+ if (e instanceof CartParseError) {
52
+ return {
53
+ ok: false,
54
+ code: 'cart-parse-failed',
55
+ message: `cart at ${cartPath} does not parse (${e.code}): ${e.message}`,
56
+ };
57
+ }
58
+ throw e;
59
+ }
60
+ }
61
+ /**
62
+ * Builds the `gfx` command group: `gfx show` (read a sprite as a char grid),
63
+ * `gfx set` (write a char grid back into `__gfx__`, with the map-overlap
64
+ * smart-refuse), and `gfx render` (upscaled palette-accurate PNG, the JUDGE
65
+ * surface). Returned as its own `Cli` so it mounts under the root as a
66
+ * group, which also gives the `gfx.set.options.allowMapOverlap` config path its
67
+ * `picopilot.json` reads through (incur keys config by command path).
68
+ */
69
+ function buildGfxGroup(shrinkoFactory) {
70
+ const gfx = Cli.create('gfx', {
71
+ description: 'Read and write sprites as a readable char grid (the pixel-art EDIT surface).',
72
+ });
73
+ gfx.command('show', {
74
+ description: 'Render a sprite from __gfx__ into a readable char grid (. = transparent, 0-f = the 16 colours). CTAs to `gfx set`.',
75
+ args: z.object({
76
+ sprite: z.coerce
77
+ .number()
78
+ .int()
79
+ .min(0)
80
+ .max(255)
81
+ .describe('The sprite index 0-255 to render.'),
82
+ cart: z
83
+ .string()
84
+ .default('main.p8')
85
+ .describe('The .p8 cart to read. Defaults to main.p8 in the current folder.'),
86
+ }),
87
+ output: z.object({
88
+ sprite: z.number().describe('The sprite index that was rendered.'),
89
+ grid: z
90
+ .string()
91
+ .describe('The char grid: 8 lines of 8 chars, . = transparent, 0-f = colours 1-15.'),
92
+ aliasesMap: z
93
+ .boolean()
94
+ .describe('True for sprites 128-255, which alias the shared map region (see `gfx set`).'),
95
+ }),
96
+ examples: [
97
+ { description: 'Show sprite 1 of main.p8', args: { sprite: 1 } },
98
+ {
99
+ description: 'Show sprite 3 of a specific cart',
100
+ args: { sprite: 3, cart: 'game.p8' },
101
+ },
102
+ ],
103
+ run({ args, error, ok }) {
104
+ const cartPath = resolveCart(args.cart);
105
+ const loaded = loadCart(cartPath);
106
+ if (!loaded.ok) {
107
+ return error({ code: loaded.code, message: loaded.message, exitCode: 1 });
108
+ }
109
+ const sheet = GfxSheet.fromBody(loaded.cart.getSection('gfx'));
110
+ const grid = nibblesToGrid(sheet.getSprite(args.sprite));
111
+ // The read → fix → write loop: `gfx show` always CTAs to `gfx set` so an
112
+ // agent that sees a broken sprite is led straight to the edit surface.
113
+ return ok({
114
+ sprite: args.sprite,
115
+ grid,
116
+ aliasesMap: spriteAliasesMap(args.sprite),
117
+ }, {
118
+ cta: {
119
+ description: 'Edit the grid, then write it back with:',
120
+ commands: [
121
+ {
122
+ command: `gfx set ${args.sprite}`,
123
+ description: 'Write an edited char grid back into __gfx__.',
124
+ },
125
+ ],
126
+ },
127
+ });
128
+ },
129
+ });
130
+ gfx.command('set', {
131
+ description: 'Write a char grid back into a sprite in __gfx__. Sprites 128-255 alias the shared map region: a write that would clobber existing data is refused unless authorised (--allow-map-overlap / allowMapOverlap config).',
132
+ args: z.object({
133
+ sprite: z.coerce
134
+ .number()
135
+ .int()
136
+ .min(0)
137
+ .max(255)
138
+ .describe('The sprite index 0-255 to write.'),
139
+ grid: z
140
+ .string()
141
+ .describe('The char grid: 8 lines of 8 chars, . = transparent, 0-f = colours 1-15.'),
142
+ cart: z
143
+ .string()
144
+ .default('main.p8')
145
+ .describe('The .p8 cart to write. Defaults to main.p8 in the current folder.'),
146
+ }),
147
+ options: z.object({
148
+ allowMapOverlap: z
149
+ .boolean()
150
+ .default(false)
151
+ .describe('Authorise overwriting existing shared-region data when writing sprites 128-255 (ADR-0004). Also settable as allowMapOverlap in picopilot.json.'),
152
+ }),
153
+ output: z.object({
154
+ sprite: z.number().describe('The sprite index that was written.'),
155
+ cart: z
156
+ .string()
157
+ .describe('The absolute path of the cart that was written.'),
158
+ aliasesMap: z
159
+ .boolean()
160
+ .describe('True for sprites 128-255, which alias the shared map region.'),
161
+ overwroteSharedData: z
162
+ .boolean()
163
+ .describe('True when this write overwrote existing shared-region data (authorised).'),
164
+ note: z
165
+ .string()
166
+ .optional()
167
+ .describe('An advisory note (e.g. the shared-region aliasing) when relevant.'),
168
+ }),
169
+ examples: [
170
+ {
171
+ description: 'Write an edited grid into sprite 1',
172
+ args: {
173
+ sprite: 1,
174
+ grid: '........\n........\n........\n........\n........\n........\n........\n........',
175
+ },
176
+ },
177
+ ],
178
+ run({ args, options, error, ok }) {
179
+ const cartPath = resolveCart(args.cart);
180
+ // Decode the incoming grid FIRST: a malformed grid is a caller error and
181
+ // must never touch the cart. (No bytes change on a bad grid.)
182
+ let nibbles;
183
+ try {
184
+ nibbles = gridToNibbles(args.grid);
185
+ }
186
+ catch (e) {
187
+ if (e instanceof GfxGridError) {
188
+ return error({
189
+ code: 'invalid-grid',
190
+ message: `the char grid is malformed: ${e.message}`,
191
+ exitCode: 1,
192
+ });
193
+ }
194
+ throw e;
195
+ }
196
+ const loaded = loadCart(cartPath);
197
+ if (!loaded.ok) {
198
+ return error({ code: loaded.code, message: loaded.message, exitCode: 1 });
199
+ }
200
+ const sheet = GfxSheet.fromBody(loaded.cart.getSection('gfx'));
201
+ // The overlap decision reads the target sprite's CURRENT __gfx__ pixels
202
+ // (the shared-bank bytes at risk), NOT __map__ (ADR-0004). The flag and
203
+ // the picopilot.json config both feed `options.allowMapOverlap` (incur
204
+ // resolves argv > config > default), so both authorisation paths converge
205
+ // here.
206
+ const decision = decideOverlap(sheet, args.sprite, options.allowMapOverlap);
207
+ if (decision.kind === 'refused') {
208
+ // The silent-corruption guard: REFUSE and DO NOT write. The cart file is
209
+ // never opened for writing on this path, so the sprite's __gfx__ bytes
210
+ // stay byte-identical. Structured envelope (code + detail + remedy) with
211
+ // a nonzero exit so an agent stops rather than treating exit-0 as done.
212
+ return error({
213
+ code: 'map-overlap',
214
+ message: `sprite ${args.sprite} aliases the shared map region and its current __gfx__ pixels hold data (${decision.nonZeroPixels} non-zero); refusing to silently overwrite it. Remedy: pass --allow-map-overlap, set allowMapOverlap in picopilot.json, or target a sprite 0-127.`,
215
+ exitCode: MAP_OVERLAP_EXIT,
216
+ cta: {
217
+ description: 'To proceed anyway (this overwrites the shared data):',
218
+ commands: [
219
+ {
220
+ command: `gfx set ${args.sprite} --allow-map-overlap`,
221
+ description: 'Re-run authorising the shared-region overwrite.',
222
+ },
223
+ ],
224
+ },
225
+ });
226
+ }
227
+ // Allowed: write the sprite and persist. Preserve every other section by
228
+ // committing through the cart model (only __gfx__ changes).
229
+ sheet.setSprite(args.sprite, nibbles);
230
+ sheet.commit(loaded.cart);
231
+ writeFileSync(cartPath, loaded.cart.serialize());
232
+ const overwroteSharedData = decision.kind === 'allowed-shared' && decision.reason === 'authorised';
233
+ const note = decision.kind === 'allowed-shared'
234
+ ? decision.reason === 'authorised'
235
+ ? `sprite ${args.sprite} aliases the shared map region; overwrote existing shared data (authorised).`
236
+ : `sprite ${args.sprite} aliases the shared map region; it was empty, so the write is safe.`
237
+ : undefined;
238
+ return ok({
239
+ sprite: args.sprite,
240
+ cart: cartPath,
241
+ aliasesMap: spriteAliasesMap(args.sprite),
242
+ overwroteSharedData,
243
+ note,
244
+ });
245
+ },
246
+ });
247
+ gfx.command('render', {
248
+ description: 'Render a sprite (0-255) or the whole `sheet` to an UPSCALED, palette-accurate PNG a multimodal agent can LOOK at (the JUDGE surface). Always reports BOTH the PNG path AND the char grid. CTAs: render -> set -> render.',
249
+ args: z.object({
250
+ target: z
251
+ .string()
252
+ .describe('A sprite index 0-255 to render, or the literal `sheet` for the whole 128x128 spritesheet.'),
253
+ cart: z
254
+ .string()
255
+ .default('main.p8')
256
+ .describe('The .p8 cart to read. Defaults to main.p8 in the current folder.'),
257
+ }),
258
+ options: z.object({
259
+ out: z
260
+ .string()
261
+ .optional()
262
+ .describe('Output PNG path. Defaults to <cart-stem>-sprite-<n>.png / <cart-stem>-sheet.png next to the cart.'),
263
+ }),
264
+ output: z.object({
265
+ target: z
266
+ .string()
267
+ .describe('What was rendered: a sprite index (as a string) or `sheet`.'),
268
+ png: z
269
+ .string()
270
+ .describe('The absolute path of the PNG written (the JUDGE surface: LOOK at it).'),
271
+ width: z
272
+ .number()
273
+ .describe('The rendered PNG width in pixels (upscaled).'),
274
+ height: z
275
+ .number()
276
+ .describe('The rendered PNG height in pixels (upscaled).'),
277
+ grid: z
278
+ .string()
279
+ .optional()
280
+ .describe('The sprite char grid (. = transparent, 0-f = colours) so a non-multimodal agent can reason over it; absent for `sheet`.'),
281
+ aliasesMap: z
282
+ .boolean()
283
+ .describe('True for a single sprite 128-255, which aliases the shared map region (see `gfx set`).'),
284
+ }),
285
+ examples: [
286
+ { description: 'Render sprite 1 to a viewable PNG', args: { target: '1' } },
287
+ { description: 'Render the whole spritesheet', args: { target: 'sheet' } },
288
+ {
289
+ description: 'Render sprite 3 of a specific cart to a chosen path',
290
+ args: { target: '3', cart: 'game.p8' },
291
+ options: { out: 'sprite3.png' },
292
+ },
293
+ ],
294
+ run({ args, options, error, ok }) {
295
+ // Parse the target: the literal `sheet` or a sprite index 0-255. A bad
296
+ // target is a caller error and never opens the cart.
297
+ const isSheet = args.target === 'sheet';
298
+ let sprite = -1;
299
+ if (!isSheet) {
300
+ sprite = Number(args.target);
301
+ if (!Number.isInteger(sprite) || sprite < 0 || sprite > 255) {
302
+ return error({
303
+ code: 'invalid-target',
304
+ message: `render target must be \`sheet\` or a sprite index 0-255, got "${args.target}"`,
305
+ exitCode: 1,
306
+ });
307
+ }
308
+ }
309
+ const cartPath = resolveCart(args.cart);
310
+ const loaded = loadCart(cartPath);
311
+ if (!loaded.ok) {
312
+ return error({ code: loaded.code, message: loaded.message, exitCode: 1 });
313
+ }
314
+ const sheet = GfxSheet.fromBody(loaded.cart.getSection('gfx'));
315
+ // Render the palette-accurate, nearest-neighbour-upscaled PNG and write it
316
+ // to the known path. The encoder is shrinko-FREE (pure TS hex -> PNG).
317
+ const png = isSheet
318
+ ? renderSheetPng(sheet)
319
+ : renderSpritePng(sheet, sprite);
320
+ const outPath = options.out
321
+ ? resolveCart(options.out)
322
+ : defaultRenderPath(cartPath, isSheet ? 'sheet' : sprite);
323
+ writeFileSync(outPath, png);
324
+ // ALWAYS emit BOTH the PNG path and the grid (for a single sprite), so the
325
+ // picopilot-art skill can branch view-vs-imagine. A `sheet` render has no
326
+ // single 8x8 grid, so the grid is omitted there (use `gfx show <n>`).
327
+ const width = isSheet
328
+ ? GFX_WIDTH * SHEET_RENDER_SCALE
329
+ : SPRITE_SIZE * SPRITE_RENDER_SCALE;
330
+ const height = width;
331
+ const grid = isSheet ? undefined : nibblesToGrid(sheet.getSprite(sprite));
332
+ const aliasesMap = isSheet ? false : spriteAliasesMap(sprite);
333
+ // The see-and-fix loop: render (look) -> set (fix) -> render (re-look). A
334
+ // single sprite CTAs to `gfx set` then back to `gfx render` at the SAME
335
+ // target; `sheet` CTAs to `gfx show`/`gfx set` a specific sprite.
336
+ const cta = isSheet
337
+ ? {
338
+ description: 'To edit a specific sprite from the sheet, then re-render:',
339
+ commands: [
340
+ {
341
+ command: 'gfx show <n>',
342
+ description: 'Read sprite n as an editable char grid.',
343
+ },
344
+ {
345
+ command: 'gfx render sheet',
346
+ description: 'Re-render the sheet to re-look.',
347
+ },
348
+ ],
349
+ }
350
+ : {
351
+ description: 'Look at the PNG, then fix via the grid and re-render:',
352
+ commands: [
353
+ {
354
+ command: `gfx set ${sprite}`,
355
+ description: 'Write an edited char grid back into __gfx__.',
356
+ },
357
+ {
358
+ command: `gfx render ${sprite}`,
359
+ description: 'Re-render to re-look after the fix.',
360
+ },
361
+ ],
362
+ };
363
+ return ok({
364
+ target: isSheet ? 'sheet' : String(sprite),
365
+ png: outPath,
366
+ width,
367
+ height,
368
+ grid,
369
+ aliasesMap,
370
+ }, { cta });
371
+ },
372
+ });
373
+ // gfx export: the raw 128x128 spritesheet PNG round-trip for external tools
374
+ // (shrinko-backed; DISTINCT from `gfx render`'s upscaled JUDGE image).
375
+ gfx.command('export', {
376
+ description: 'Export the cart spritesheet as a raw 128x128 PNG for external tools (via shrinko). Requires shrinko.',
377
+ args: z.object({
378
+ cart: z
379
+ .string()
380
+ .default('main.p8')
381
+ .describe('The .p8 cart to export from. Defaults to main.p8.'),
382
+ }),
383
+ options: z.object({
384
+ out: z
385
+ .string()
386
+ .optional()
387
+ .describe('Output PNG path. Defaults to <name>-sheet.png next to the cart.'),
388
+ force: z
389
+ .boolean()
390
+ .default(false)
391
+ .describe('Overwrite an existing output PNG. Default off (no-clobber).'),
392
+ }),
393
+ env: z.object({
394
+ PATH: z.string().optional().describe('Used to locate shrinko8.'),
395
+ }),
396
+ output: z.object({
397
+ outPath: z
398
+ .string()
399
+ .describe('Absolute path of the spritesheet PNG written.'),
400
+ }),
401
+ examples: [{ description: 'Export main.p8 spritesheet to main-sheet.png' }],
402
+ async run({ args, options, env, error, ok }) {
403
+ const cartPath = isAbsolute(args.cart)
404
+ ? args.cart
405
+ : resolve(process.cwd(), args.cart);
406
+ if (!existsSync(cartPath)) {
407
+ return error({
408
+ code: 'cart-not-found',
409
+ message: `no cart at ${cartPath}`,
410
+ exitCode: 1,
411
+ });
412
+ }
413
+ const outPath = options.out !== undefined
414
+ ? isAbsolute(options.out)
415
+ ? options.out
416
+ : resolve(process.cwd(), options.out)
417
+ : join(dirname(cartPath), `${basename(cartPath, extname(cartPath))}-sheet.png`);
418
+ if (existsSync(outPath) && !options.force) {
419
+ return error({
420
+ code: 'output-exists',
421
+ message: `refusing to overwrite existing ${outPath}; pass --force to overwrite`,
422
+ exitCode: 1,
423
+ });
424
+ }
425
+ const result = await shrinkoFactory(env).exportSpritesheet(cartPath, outPath);
426
+ if (!result.ok) {
427
+ return error({
428
+ code: result.reason,
429
+ message: `shrinko is not installed. ${result.remedy} (needs: ${result.needs.join(', ')})`,
430
+ exitCode: 1,
431
+ });
432
+ }
433
+ return ok({ outPath });
434
+ },
435
+ });
436
+ // gfx import: merge an external spritesheet PNG back into the cart's __gfx__.
437
+ // MERGE (not replace): code/map/sfx/music are preserved; only gfx changes.
438
+ gfx.command('import', {
439
+ description: "Import a 128x128 spritesheet PNG into the cart's __gfx__ (merge; via shrinko). Requires shrinko.",
440
+ args: z.object({
441
+ png: z.string().describe('The spritesheet PNG to import.'),
442
+ cart: z
443
+ .string()
444
+ .default('main.p8')
445
+ .describe('The .p8 cart to import INTO. Defaults to main.p8.'),
446
+ }),
447
+ options: z.object({
448
+ out: z
449
+ .string()
450
+ .optional()
451
+ .describe('Output cart. Defaults to writing back into the cart in place (like `gfx set`).'),
452
+ }),
453
+ env: z.object({
454
+ PATH: z.string().optional().describe('Used to locate shrinko8.'),
455
+ }),
456
+ output: z.object({
457
+ outPath: z
458
+ .string()
459
+ .describe('The cart written (the source cart when in place).'),
460
+ }),
461
+ examples: [
462
+ { description: 'Import sheet.png into main.p8', args: { png: 'sheet.png' } },
463
+ ],
464
+ async run({ args, options, env, error, ok }) {
465
+ const cartPath = isAbsolute(args.cart)
466
+ ? args.cart
467
+ : resolve(process.cwd(), args.cart);
468
+ const pngPath = isAbsolute(args.png)
469
+ ? args.png
470
+ : resolve(process.cwd(), args.png);
471
+ if (!existsSync(cartPath)) {
472
+ return error({
473
+ code: 'cart-not-found',
474
+ message: `no cart at ${cartPath}`,
475
+ exitCode: 1,
476
+ });
477
+ }
478
+ if (!existsSync(pngPath)) {
479
+ return error({
480
+ code: 'png-not-found',
481
+ message: `no PNG at ${pngPath}`,
482
+ exitCode: 1,
483
+ });
484
+ }
485
+ // Default: write back into the cart in place, matching `gfx set` (import IS
486
+ // a gfx edit that produces the readable cart, not a build artifact). `--out`
487
+ // writes a separate cart instead.
488
+ const outPath = options.out !== undefined
489
+ ? isAbsolute(options.out)
490
+ ? options.out
491
+ : resolve(process.cwd(), options.out)
492
+ : cartPath;
493
+ const result = await shrinkoFactory(env).importSpritesheet(cartPath, pngPath, outPath);
494
+ if (!result.ok) {
495
+ return error({
496
+ code: result.reason,
497
+ message: `shrinko is not installed. ${result.remedy} (needs: ${result.needs.join(', ')})`,
498
+ exitCode: 1,
499
+ });
500
+ }
501
+ return ok({ outPath });
502
+ },
503
+ });
504
+ return gfx;
505
+ }
506
+ /**
507
+ * Registers the `gfx` command group (`gfx show` / `gfx set`) on the root CLI.
508
+ *
509
+ * `gfx` is a shrinko-FREE command group (ADR-0002): it reads/writes `__gfx__`
510
+ * entirely through the cart model + the TS char-grid codec, so it works with
511
+ * shrinko absent and never spawns a child process. `gfx set` carries the
512
+ * gfx/map overlap smart-refuse (ADR-0004): a write to a shared-bank sprite
513
+ * (128-255) whose current pixels hold data is refused unless authorised, so
514
+ * picopilot never SILENTLY destroys shared-region data. `gfx render` is likewise
515
+ * shrinko-free: a pure-TS hex->PNG encoder using PICO-8's fixed 16-colour palette
516
+ * (the eyes-loop stays dependency-light, ADR/US #7).
517
+ */
518
+ export function registerGfx(cli, shrinkoFactory = defaultShrinkoFactory) {
519
+ cli.command(buildGfxGroup(shrinkoFactory));
520
+ }
521
+ //# sourceMappingURL=gfx.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"gfx.js","sourceRoot":"","sources":["../../src/commands/gfx.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,34 @@
1
+ import { type Cli } from 'incur';
2
+ import { type InstallSkillsOptions, type InstallSkillsResult } from '../engine/skills/index.js';
3
+ /**
4
+ * Injects the skills installer `init --install-skills` calls (defaults to the
5
+ * real {@link installSkills}). This is the shared-write isolation SEAM, mirroring
6
+ * how `tokens`/`verify` inject their shrinko adapter: a test passes an installer
7
+ * that redirects the target to a temp dir (via `global: false` + a temp `cwd`),
8
+ * so the load-bearing install test can assert the real agent skill dirs are
9
+ * byte-untouched without ever performing a real global write.
10
+ */
11
+ export type SkillsInstaller = (options: InstallSkillsOptions) => Promise<InstallSkillsResult>;
12
+ /**
13
+ * Registers `picopilot init`, the scaffolder that turns a fresh folder into an
14
+ * agent-ready PICO-8 cart (US #1, #2).
15
+ *
16
+ * INSTRUCT-not-mutate (US #2): by default `init` writes ONLY inside the target
17
+ * cart folder, the `main.p8` (`__lua__` = `#include main.lua`), the editable
18
+ * `main.lua`, the curated `AGENTS.md` reference, and `picopilot.json`. It does
19
+ * NOT run `git init` and does NOT write to shared agent skill dirs; it PRINTS a
20
+ * skills-discovery tip and a `git init` tip instead. The global skills install
21
+ * is the opt-in `init --install-skills`, a SEPARATE task, so the default is a
22
+ * good citizen of `~/.claude` / agent dirs and of the user's VCS choice.
23
+ *
24
+ * The opt-in `init --install-skills` (US #2, #20) IS the shared write: it runs
25
+ * incur's skills install (which defaults to a GLOBAL write into `~/.agents/skills`
26
+ * + detected agent dirs) so the discipline skills are auto-discovered. It is the
27
+ * only picopilot path that touches a shared location, so the installer is an
28
+ * injected seam and its target is fully redirectable for isolation-testing.
29
+ *
30
+ * @param installer injects the skills installer (defaults to the real global
31
+ * install); tests pass one that redirects the target to a temp dir.
32
+ */
33
+ export declare function registerInit(cli: Cli.Cli, installer?: SkillsInstaller): void;
34
+ //# sourceMappingURL=init.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"init.d.ts","sourceRoot":"","sources":["../../src/commands/init.ts"],"names":[],"mappings":"AAEA,OAAO,EAAC,KAAK,GAAG,EAAI,MAAM,OAAO,CAAC;AAElC,OAAO,EACN,KAAK,oBAAoB,EACzB,KAAK,mBAAmB,EAExB,MAAM,2BAA2B,CAAC;AAEnC;;;;;;;GAOG;AACH,MAAM,MAAM,eAAe,GAAG,CAC7B,OAAO,EAAE,oBAAoB,KACzB,OAAO,CAAC,mBAAmB,CAAC,CAAC;AAElC;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,wBAAgB,YAAY,CAC3B,GAAG,EAAE,GAAG,CAAC,GAAG,EACZ,SAAS,GAAE,eAA+B,GACxC,IAAI,CAkJN"}