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.
- package/LICENSE +661 -0
- package/dist/bin.d.ts +3 -0
- package/dist/bin.d.ts.map +1 -0
- package/dist/bin.js +4 -0
- package/dist/bin.js.map +1 -0
- package/dist/cli.d.ts +15 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +59 -0
- package/dist/cli.js.map +1 -0
- package/dist/commands/audio.d.ts +17 -0
- package/dist/commands/audio.d.ts.map +1 -0
- package/dist/commands/audio.js +315 -0
- package/dist/commands/audio.js.map +1 -0
- package/dist/commands/export.d.ts +36 -0
- package/dist/commands/export.d.ts.map +1 -0
- package/dist/commands/export.js +257 -0
- package/dist/commands/export.js.map +1 -0
- package/dist/commands/gfx.d.ts +28 -0
- package/dist/commands/gfx.d.ts.map +1 -0
- package/dist/commands/gfx.js +521 -0
- package/dist/commands/gfx.js.map +1 -0
- package/dist/commands/init.d.ts +34 -0
- package/dist/commands/init.d.ts.map +1 -0
- package/dist/commands/init.js +151 -0
- package/dist/commands/init.js.map +1 -0
- package/dist/commands/lint.d.ts +20 -0
- package/dist/commands/lint.d.ts.map +1 -0
- package/dist/commands/lint.js +90 -0
- package/dist/commands/lint.js.map +1 -0
- package/dist/commands/minify.d.ts +20 -0
- package/dist/commands/minify.d.ts.map +1 -0
- package/dist/commands/minify.js +129 -0
- package/dist/commands/minify.js.map +1 -0
- package/dist/commands/music.d.ts +13 -0
- package/dist/commands/music.d.ts.map +1 -0
- package/dist/commands/music.js +241 -0
- package/dist/commands/music.js.map +1 -0
- package/dist/commands/playtest.d.ts +29 -0
- package/dist/commands/playtest.d.ts.map +1 -0
- package/dist/commands/playtest.js +631 -0
- package/dist/commands/playtest.js.map +1 -0
- package/dist/commands/run.d.ts +30 -0
- package/dist/commands/run.d.ts.map +1 -0
- package/dist/commands/run.js +224 -0
- package/dist/commands/run.js.map +1 -0
- package/dist/commands/serve.d.ts +50 -0
- package/dist/commands/serve.d.ts.map +1 -0
- package/dist/commands/serve.js +213 -0
- package/dist/commands/serve.js.map +1 -0
- package/dist/commands/sfx.d.ts +13 -0
- package/dist/commands/sfx.d.ts.map +1 -0
- package/dist/commands/sfx.js +254 -0
- package/dist/commands/sfx.js.map +1 -0
- package/dist/commands/tokens.d.ts +36 -0
- package/dist/commands/tokens.d.ts.map +1 -0
- package/dist/commands/tokens.js +129 -0
- package/dist/commands/tokens.js.map +1 -0
- package/dist/commands/verify.d.ts +57 -0
- package/dist/commands/verify.d.ts.map +1 -0
- package/dist/commands/verify.js +213 -0
- package/dist/commands/verify.js.map +1 -0
- package/dist/commands/version.d.ts +12 -0
- package/dist/commands/version.d.ts.map +1 -0
- package/dist/commands/version.js +24 -0
- package/dist/commands/version.js.map +1 -0
- package/dist/engine/audio/index.d.ts +14 -0
- package/dist/engine/audio/index.d.ts.map +1 -0
- package/dist/engine/audio/index.js +14 -0
- package/dist/engine/audio/index.js.map +1 -0
- package/dist/engine/audio/music.d.ts +116 -0
- package/dist/engine/audio/music.d.ts.map +1 -0
- package/dist/engine/audio/music.js +138 -0
- package/dist/engine/audio/music.js.map +1 -0
- package/dist/engine/audio/section.d.ts +34 -0
- package/dist/engine/audio/section.d.ts.map +1 -0
- package/dist/engine/audio/section.js +67 -0
- package/dist/engine/audio/section.js.map +1 -0
- package/dist/engine/audio/sfx.d.ts +141 -0
- package/dist/engine/audio/sfx.d.ts.map +1 -0
- package/dist/engine/audio/sfx.js +506 -0
- package/dist/engine/audio/sfx.js.map +1 -0
- package/dist/engine/cart/cart.d.ts +75 -0
- package/dist/engine/cart/cart.d.ts.map +1 -0
- package/dist/engine/cart/cart.js +153 -0
- package/dist/engine/cart/cart.js.map +1 -0
- package/dist/engine/cart/errors.d.ts +29 -0
- package/dist/engine/cart/errors.d.ts.map +1 -0
- package/dist/engine/cart/errors.js +26 -0
- package/dist/engine/cart/errors.js.map +1 -0
- package/dist/engine/cart/gfx.d.ts +79 -0
- package/dist/engine/cart/gfx.d.ts.map +1 -0
- package/dist/engine/cart/gfx.js +171 -0
- package/dist/engine/cart/gfx.js.map +1 -0
- package/dist/engine/cart/index.d.ts +15 -0
- package/dist/engine/cart/index.d.ts.map +1 -0
- package/dist/engine/cart/index.js +15 -0
- package/dist/engine/cart/index.js.map +1 -0
- package/dist/engine/cart/map.d.ts +46 -0
- package/dist/engine/cart/map.d.ts.map +1 -0
- package/dist/engine/cart/map.js +118 -0
- package/dist/engine/cart/map.js.map +1 -0
- package/dist/engine/config/config.d.ts +74 -0
- package/dist/engine/config/config.d.ts.map +1 -0
- package/dist/engine/config/config.js +103 -0
- package/dist/engine/config/config.js.map +1 -0
- package/dist/engine/config/index.d.ts +7 -0
- package/dist/engine/config/index.d.ts.map +1 -0
- package/dist/engine/config/index.js +7 -0
- package/dist/engine/config/index.js.map +1 -0
- package/dist/engine/gfx/grid.d.ts +51 -0
- package/dist/engine/gfx/grid.d.ts.map +1 -0
- package/dist/engine/gfx/grid.js +116 -0
- package/dist/engine/gfx/grid.js.map +1 -0
- package/dist/engine/gfx/index.d.ts +17 -0
- package/dist/engine/gfx/index.d.ts.map +1 -0
- package/dist/engine/gfx/index.js +17 -0
- package/dist/engine/gfx/index.js.map +1 -0
- package/dist/engine/gfx/label.d.ts +34 -0
- package/dist/engine/gfx/label.d.ts.map +1 -0
- package/dist/engine/gfx/label.js +190 -0
- package/dist/engine/gfx/label.js.map +1 -0
- package/dist/engine/gfx/overlap.d.ts +42 -0
- package/dist/engine/gfx/overlap.d.ts.map +1 -0
- package/dist/engine/gfx/overlap.js +57 -0
- package/dist/engine/gfx/overlap.js.map +1 -0
- package/dist/engine/gfx/palette.d.ts +29 -0
- package/dist/engine/gfx/palette.d.ts.map +1 -0
- package/dist/engine/gfx/palette.js +46 -0
- package/dist/engine/gfx/palette.js.map +1 -0
- package/dist/engine/gfx/png.d.ts +31 -0
- package/dist/engine/gfx/png.d.ts.map +1 -0
- package/dist/engine/gfx/png.js +165 -0
- package/dist/engine/gfx/png.js.map +1 -0
- package/dist/engine/gfx/render.d.ts +42 -0
- package/dist/engine/gfx/render.d.ts.map +1 -0
- package/dist/engine/gfx/render.js +72 -0
- package/dist/engine/gfx/render.js.map +1 -0
- package/dist/engine/index.d.ts +22 -0
- package/dist/engine/index.d.ts.map +1 -0
- package/dist/engine/index.js +22 -0
- package/dist/engine/index.js.map +1 -0
- package/dist/engine/pico8/adapter.d.ts +267 -0
- package/dist/engine/pico8/adapter.d.ts.map +1 -0
- package/dist/engine/pico8/adapter.js +37 -0
- package/dist/engine/pico8/adapter.js.map +1 -0
- package/dist/engine/pico8/drive.d.ts +308 -0
- package/dist/engine/pico8/drive.d.ts.map +1 -0
- package/dist/engine/pico8/drive.js +581 -0
- package/dist/engine/pico8/drive.js.map +1 -0
- package/dist/engine/pico8/harness.d.ts +146 -0
- package/dist/engine/pico8/harness.d.ts.map +1 -0
- package/dist/engine/pico8/harness.js +251 -0
- package/dist/engine/pico8/harness.js.map +1 -0
- package/dist/engine/pico8/index.d.ts +21 -0
- package/dist/engine/pico8/index.d.ts.map +1 -0
- package/dist/engine/pico8/index.js +21 -0
- package/dist/engine/pico8/index.js.map +1 -0
- package/dist/engine/pico8/sentinel.d.ts +63 -0
- package/dist/engine/pico8/sentinel.d.ts.map +1 -0
- package/dist/engine/pico8/sentinel.js +86 -0
- package/dist/engine/pico8/sentinel.js.map +1 -0
- package/dist/engine/pico8/session-daemon-entry.d.ts +10 -0
- package/dist/engine/pico8/session-daemon-entry.d.ts.map +1 -0
- package/dist/engine/pico8/session-daemon-entry.js +11 -0
- package/dist/engine/pico8/session-daemon-entry.js.map +1 -0
- package/dist/engine/pico8/session-daemon-main.d.ts +44 -0
- package/dist/engine/pico8/session-daemon-main.d.ts.map +1 -0
- package/dist/engine/pico8/session-daemon-main.js +71 -0
- package/dist/engine/pico8/session-daemon-main.js.map +1 -0
- package/dist/engine/pico8/session-daemon.d.ts +68 -0
- package/dist/engine/pico8/session-daemon.d.ts.map +1 -0
- package/dist/engine/pico8/session-daemon.js +264 -0
- package/dist/engine/pico8/session-daemon.js.map +1 -0
- package/dist/engine/pico8/session.d.ts +140 -0
- package/dist/engine/pico8/session.d.ts.map +1 -0
- package/dist/engine/pico8/session.js +250 -0
- package/dist/engine/pico8/session.js.map +1 -0
- package/dist/engine/pico8/shell.d.ts +103 -0
- package/dist/engine/pico8/shell.d.ts.map +1 -0
- package/dist/engine/pico8/shell.js +324 -0
- package/dist/engine/pico8/shell.js.map +1 -0
- package/dist/engine/pico8/supervisor.d.ts +137 -0
- package/dist/engine/pico8/supervisor.d.ts.map +1 -0
- package/dist/engine/pico8/supervisor.js +140 -0
- package/dist/engine/pico8/supervisor.js.map +1 -0
- package/dist/engine/scaffold/index.d.ts +8 -0
- package/dist/engine/scaffold/index.d.ts.map +1 -0
- package/dist/engine/scaffold/index.js +8 -0
- package/dist/engine/scaffold/index.js.map +1 -0
- package/dist/engine/scaffold/scaffold.d.ts +49 -0
- package/dist/engine/scaffold/scaffold.d.ts.map +1 -0
- package/dist/engine/scaffold/scaffold.js +259 -0
- package/dist/engine/scaffold/scaffold.js.map +1 -0
- package/dist/engine/shrinko/adapter.d.ts +167 -0
- package/dist/engine/shrinko/adapter.d.ts.map +1 -0
- package/dist/engine/shrinko/adapter.js +107 -0
- package/dist/engine/shrinko/adapter.js.map +1 -0
- package/dist/engine/shrinko/index.d.ts +13 -0
- package/dist/engine/shrinko/index.d.ts.map +1 -0
- package/dist/engine/shrinko/index.js +13 -0
- package/dist/engine/shrinko/index.js.map +1 -0
- package/dist/engine/shrinko/shell.d.ts +69 -0
- package/dist/engine/shrinko/shell.d.ts.map +1 -0
- package/dist/engine/shrinko/shell.js +156 -0
- package/dist/engine/shrinko/shell.js.map +1 -0
- package/dist/engine/skills/index.d.ts +8 -0
- package/dist/engine/skills/index.d.ts.map +1 -0
- package/dist/engine/skills/index.js +8 -0
- package/dist/engine/skills/index.js.map +1 -0
- package/dist/engine/skills/skills.d.ts +104 -0
- package/dist/engine/skills/skills.d.ts.map +1 -0
- package/dist/engine/skills/skills.js +149 -0
- package/dist/engine/skills/skills.js.map +1 -0
- package/dist/index.d.ts +10 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +10 -0
- package/dist/index.js.map +1 -0
- package/dist/version.d.ts +2 -0
- package/dist/version.d.ts.map +1 -0
- package/dist/version.js +19 -0
- package/dist/version.js.map +1 -0
- package/package.json +48 -2
- package/src/bin.ts +4 -0
- package/src/cli.ts +61 -0
- package/src/commands/audio.test.ts +280 -0
- package/src/commands/audio.ts +410 -0
- package/src/commands/export.test.ts +310 -0
- package/src/commands/export.ts +316 -0
- package/src/commands/gfx-io.test.ts +178 -0
- package/src/commands/gfx.test.ts +470 -0
- package/src/commands/gfx.ts +645 -0
- package/src/commands/init.test.ts +482 -0
- package/src/commands/init.ts +193 -0
- package/src/commands/lint.test.ts +137 -0
- package/src/commands/lint.ts +117 -0
- package/src/commands/minify.test.ts +166 -0
- package/src/commands/minify.ts +156 -0
- package/src/commands/music.test.ts +272 -0
- package/src/commands/music.ts +288 -0
- package/src/commands/playtest.test.ts +317 -0
- package/src/commands/playtest.ts +773 -0
- package/src/commands/run.test.ts +264 -0
- package/src/commands/run.ts +285 -0
- package/src/commands/serve.test.ts +227 -0
- package/src/commands/serve.ts +272 -0
- package/src/commands/sfx.test.ts +349 -0
- package/src/commands/sfx.ts +300 -0
- package/src/commands/tokens.test.ts +212 -0
- package/src/commands/tokens.ts +168 -0
- package/src/commands/verify.test.ts +238 -0
- package/src/commands/verify.ts +256 -0
- package/src/commands/version.test.ts +70 -0
- package/src/commands/version.ts +24 -0
- package/src/engine/audio/index.ts +47 -0
- package/src/engine/audio/music.test.ts +188 -0
- package/src/engine/audio/music.ts +218 -0
- package/src/engine/audio/section.test.ts +124 -0
- package/src/engine/audio/section.ts +79 -0
- package/src/engine/audio/sfx.test.ts +410 -0
- package/src/engine/audio/sfx.ts +694 -0
- package/src/engine/cart/cart.test.ts +304 -0
- package/src/engine/cart/cart.ts +211 -0
- package/src/engine/cart/errors.ts +39 -0
- package/src/engine/cart/fixtures/crlf.p8 +6 -0
- package/src/engine/cart/fixtures/full.p8 +174 -0
- package/src/engine/cart/fixtures/header-only.p8 +2 -0
- package/src/engine/cart/fixtures/malformed-no-header.p8 +2 -0
- package/src/engine/cart/fixtures/minimal.p8 +10 -0
- package/src/engine/cart/fixtures/no-trailing-newline.p8 +6 -0
- package/src/engine/cart/gfx.ts +195 -0
- package/src/engine/cart/index.ts +27 -0
- package/src/engine/cart/map.ts +134 -0
- package/src/engine/config/config.ts +115 -0
- package/src/engine/config/index.ts +12 -0
- package/src/engine/gfx/grid.test.ts +128 -0
- package/src/engine/gfx/grid.ts +136 -0
- package/src/engine/gfx/index.ts +34 -0
- package/src/engine/gfx/label.test.ts +105 -0
- package/src/engine/gfx/label.ts +229 -0
- package/src/engine/gfx/overlap.test.ts +71 -0
- package/src/engine/gfx/overlap.ts +66 -0
- package/src/engine/gfx/palette.test.ts +35 -0
- package/src/engine/gfx/palette.ts +54 -0
- package/src/engine/gfx/png.test.ts +111 -0
- package/src/engine/gfx/png.ts +196 -0
- package/src/engine/gfx/render.test.ts +180 -0
- package/src/engine/gfx/render.ts +106 -0
- package/src/engine/index.ts +21 -0
- package/src/engine/pico8/adapter.ts +303 -0
- package/src/engine/pico8/drive.test.ts +415 -0
- package/src/engine/pico8/drive.ts +729 -0
- package/src/engine/pico8/harness.test.ts +181 -0
- package/src/engine/pico8/harness.ts +354 -0
- package/src/engine/pico8/index.ts +20 -0
- package/src/engine/pico8/sentinel.test.ts +80 -0
- package/src/engine/pico8/sentinel.ts +93 -0
- package/src/engine/pico8/session-daemon-entry.ts +12 -0
- package/src/engine/pico8/session-daemon-main.ts +98 -0
- package/src/engine/pico8/session-daemon.test.ts +212 -0
- package/src/engine/pico8/session-daemon.ts +306 -0
- package/src/engine/pico8/session.test.ts +239 -0
- package/src/engine/pico8/session.ts +321 -0
- package/src/engine/pico8/shell.test.ts +583 -0
- package/src/engine/pico8/shell.ts +412 -0
- package/src/engine/pico8/supervisor.test.ts +105 -0
- package/src/engine/pico8/supervisor.ts +197 -0
- package/src/engine/scaffold/index.ts +15 -0
- package/src/engine/scaffold/scaffold.ts +278 -0
- package/src/engine/shrinko/adapter.ts +241 -0
- package/src/engine/shrinko/fixtures/count-no-compressed.txt +2 -0
- package/src/engine/shrinko/fixtures/count-over-budget.txt +3 -0
- package/src/engine/shrinko/fixtures/count-under-budget.txt +3 -0
- package/src/engine/shrinko/index.ts +33 -0
- package/src/engine/shrinko/shell.ts +224 -0
- package/src/engine/shrinko/shrinko.test.ts +182 -0
- package/src/engine/skills/index.ts +14 -0
- package/src/engine/skills/skills.test.ts +376 -0
- package/src/engine/skills/skills.ts +205 -0
- package/src/index.ts +13 -0
- package/src/skills/game-design-reference/SKILL.md +70 -0
- package/src/skills/game-jam/SKILL.md +45 -0
- package/src/skills/picopilot-art/SKILL.md +62 -0
- package/src/skills/picopilot-audio/SKILL.md +194 -0
- package/src/skills/picopilot-code/SKILL.md +97 -0
- package/src/skills/picopilot-code/reference/README.md +42 -0
- package/src/skills/picopilot-code/reference/mode7-racing.md +95 -0
- package/src/skills/picopilot-code/reference/platformer.md +119 -0
- package/src/skills/picopilot-code/reference/puzzle-grid.md +106 -0
- package/src/skills/picopilot-code/reference/rpg-menus-dialog.md +122 -0
- package/src/skills/picopilot-code/reference/top-down-adventure.md +117 -0
- package/src/skills/picopilot-code/reference/twin-stick-arcade.md +128 -0
- package/src/skills/picopilot-debug/SKILL.md +195 -0
- package/src/skills/picopilot-overview/SKILL.md +52 -0
- package/src/version.ts +22 -0
|
@@ -0,0 +1,303 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The PICO-8 adapter SEAM: the typed interface `picopilot run` talks to, plus
|
|
3
|
+
* the structured result shapes. Mirrors the `engine/shrinko` seam (ADR-0002):
|
|
4
|
+
* the command layer never knows HOW PICO-8 is launched; it talks to
|
|
5
|
+
* {@link Pico8Adapter}, and PICO-8 being ABSENT is a first-class value
|
|
6
|
+
* (`{ok:false, reason:'pico8-not-found', ...}`), never a throw or a hollow
|
|
7
|
+
* success. The v1 implementation shells out to the user's native `pico8 -x`
|
|
8
|
+
* (see `shell.ts` and ADR-0006, native path first); a future web-export /
|
|
9
|
+
* headless-browser implementation can satisfy the SAME interface.
|
|
10
|
+
*
|
|
11
|
+
* PICO-8 is a licensed, paid binary with no pip/npm install path, so absence is
|
|
12
|
+
* a normal, well-signposted boundary (US #14, #19), mirroring shrinko-not-found.
|
|
13
|
+
*/
|
|
14
|
+
|
|
15
|
+
/** The remedy string in a pico8-not-found result: how the user makes `run` work. */
|
|
16
|
+
export const PICO8_REMEDY = 'set PICO8_PATH or install PICO-8' as const;
|
|
17
|
+
|
|
18
|
+
/** What `run` needs: the PICO-8 binary (a paid, licensed download; no package manager). */
|
|
19
|
+
export const PICO8_NEEDS = ['pico8'] as const;
|
|
20
|
+
|
|
21
|
+
/** The default done-sentinel: the cart prints this via `printh` to signal it is finished. */
|
|
22
|
+
export const DONE_SENTINEL = '__PICOPILOT_DONE__' as const;
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* The structured "PICO-8 is not installed" failure (US #19, ADR-0006). Shape
|
|
26
|
+
* mirrors {@link import('../shrinko/adapter.js').ShrinkoNotFound}: `ok:false`, a
|
|
27
|
+
* machine-readable `reason`, the EXACT `remedy`, and the `needs` list. A command
|
|
28
|
+
* maps it onto incur's `error({ code: reason, ... })` with a nonzero exit.
|
|
29
|
+
*/
|
|
30
|
+
export interface Pico8NotFound {
|
|
31
|
+
readonly ok: false;
|
|
32
|
+
readonly reason: 'pico8-not-found';
|
|
33
|
+
readonly remedy: typeof PICO8_REMEDY;
|
|
34
|
+
readonly needs: readonly string[];
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
/** Why a run ended: the cart signalled done, the backstop fired, or PICO-8 exited on its own. */
|
|
38
|
+
export type ExitReason = 'sentinel' | 'timeout' | 'exit';
|
|
39
|
+
|
|
40
|
+
/**
|
|
41
|
+
* A completed run's collected results. `screenshots` are the PNG paths PICO-8
|
|
42
|
+
* wrote into the run-controlled `-desktop` dir (via the cart's `extcmd("screen")`);
|
|
43
|
+
* `printh` is the captured stdout (the cart's `printh` output plus PICO-8's own
|
|
44
|
+
* lines); `exitReason` says how it ended.
|
|
45
|
+
*/
|
|
46
|
+
export interface RunReport {
|
|
47
|
+
readonly screenshots: readonly string[];
|
|
48
|
+
readonly printh: string;
|
|
49
|
+
readonly exitReason: ExitReason;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
/** A successful adapter call carrying the run report. */
|
|
53
|
+
export interface Pico8Ok {
|
|
54
|
+
readonly ok: true;
|
|
55
|
+
readonly value: RunReport;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
/**
|
|
59
|
+
* The result {@link Pico8Adapter.run} returns: either a {@link RunReport} or the
|
|
60
|
+
* structured {@link Pico8NotFound}. Absence is a value, not a throw, so the
|
|
61
|
+
* two-tier capability contract is total and type-checked at the call site.
|
|
62
|
+
*/
|
|
63
|
+
export type Pico8Result = Pico8Ok | Pico8NotFound;
|
|
64
|
+
|
|
65
|
+
/**
|
|
66
|
+
* A completed audio-RECORDING run's results (ADR-0009). `wavPath` is the WAV the
|
|
67
|
+
* cart wrote via `extcmd("audio_end", 1)` into the run-controlled folder (the
|
|
68
|
+
* `audio_end(1)`-to-current-folder quirk, isolated to a temp `wavDir`), or
|
|
69
|
+
* `undefined` if none was produced (e.g. a headless `-x` capture, which yields a
|
|
70
|
+
* silent 0-frame file we treat as "no usable WAV", or a run that never recorded).
|
|
71
|
+
* `printh` + `exitReason` mirror {@link RunReport}, so a recording is a run with a
|
|
72
|
+
* WAV alongside the same run state.
|
|
73
|
+
*/
|
|
74
|
+
export interface RecordReport {
|
|
75
|
+
readonly wavPath: string | undefined;
|
|
76
|
+
readonly printh: string;
|
|
77
|
+
readonly exitReason: ExitReason;
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
/** A successful audio-record call carrying the {@link RecordReport}. */
|
|
81
|
+
export interface Pico8RecordOk {
|
|
82
|
+
readonly ok: true;
|
|
83
|
+
readonly value: RecordReport;
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
/**
|
|
87
|
+
* A completed DRIVE run's results (ADR-0011, `playtest`). Same shape family as
|
|
88
|
+
* {@link RunReport}: `screenshots` are the PNGs the driven cart wrote at the SHOT
|
|
89
|
+
* points (named `<basename>0.png`, ...), `printh` is the captured stdout (the
|
|
90
|
+
* cart's ACKs + the done-sentinel + any cart printh), `exitReason` says how it
|
|
91
|
+
* ended. A driven run is a run whose input + frame loop the harness owned.
|
|
92
|
+
*/
|
|
93
|
+
export interface DriveReport {
|
|
94
|
+
readonly screenshots: readonly string[];
|
|
95
|
+
readonly printh: string;
|
|
96
|
+
readonly exitReason: ExitReason;
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
/** A successful drive call carrying the {@link DriveReport}. */
|
|
100
|
+
export interface Pico8DriveOk {
|
|
101
|
+
readonly ok: true;
|
|
102
|
+
readonly value: DriveReport;
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
/**
|
|
106
|
+
* The result {@link Pico8Adapter.drive} returns: a {@link DriveReport} or the
|
|
107
|
+
* structured {@link Pico8NotFound} (PICO-8 absent), mirroring {@link Pico8Result}.
|
|
108
|
+
*/
|
|
109
|
+
export type Pico8DriveResult = Pico8DriveOk | Pico8NotFound;
|
|
110
|
+
|
|
111
|
+
/**
|
|
112
|
+
* Options for a single {@link Pico8Adapter.drive} (ADR-0011). The cart is the
|
|
113
|
+
* THROWAWAY driven cart the drive-transform produced; `blocks` are the encoded
|
|
114
|
+
* FIXED-SIZE command blocks piped to its live `-x` stdin (the load-bearing
|
|
115
|
+
* transport: small unpadded writes coalesce/drop, so the whole block stream is
|
|
116
|
+
* written up front for the one-shot). Screenshots land in `shotDir` (`-desktop`).
|
|
117
|
+
*/
|
|
118
|
+
export interface DriveOptions {
|
|
119
|
+
/** Absolute path to the throwaway driven `.p8` cart to run. */
|
|
120
|
+
readonly cartPath: string;
|
|
121
|
+
/** The run-controlled dir PICO-8 writes screenshots into (`-desktop <dir>`). */
|
|
122
|
+
readonly shotDir: string;
|
|
123
|
+
/** The encoded fixed-size command blocks to pipe to the cart's stdin. */
|
|
124
|
+
readonly blocks: Uint8Array;
|
|
125
|
+
/** The stdout line that ends the run when matched (defaults to {@link DONE_SENTINEL}). */
|
|
126
|
+
readonly sentinel?: string;
|
|
127
|
+
/** The hard backstop in ms: kill PICO-8 if it neither signals nor exits by then. */
|
|
128
|
+
readonly backstopMs: number;
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
/**
|
|
132
|
+
* The result {@link Pico8Adapter.record} returns: a {@link RecordReport} or the
|
|
133
|
+
* structured {@link Pico8NotFound} (PICO-8 absent), mirroring {@link Pico8Result}.
|
|
134
|
+
*/
|
|
135
|
+
export type Pico8RecordResult = Pico8RecordOk | Pico8NotFound;
|
|
136
|
+
|
|
137
|
+
/**
|
|
138
|
+
* Options for a single {@link Pico8Adapter.record} (ADR-0009). The recorded cart
|
|
139
|
+
* is expected to COOPERATE: at start it does `extcmd("set_filename", <base>)` +
|
|
140
|
+
* `extcmd("audio_rec")`, and when finished `extcmd("audio_end", 1)` (save to the
|
|
141
|
+
* current folder) then `printh` the sentinel. For `audio record <cart>` the
|
|
142
|
+
* caller injects that harness around the user's cart; for `audio render` the
|
|
143
|
+
* whole harness cart is built by {@link import('./harness.js')}.
|
|
144
|
+
*/
|
|
145
|
+
export interface RecordOptions {
|
|
146
|
+
/** Absolute path to the `.p8` cart to run and record. */
|
|
147
|
+
readonly cartPath: string;
|
|
148
|
+
/**
|
|
149
|
+
* The run-controlled folder PICO-8 records the WAV into. Because
|
|
150
|
+
* `extcmd("audio_end", 1)` saves to PICO-8's CURRENT folder (NOT `-desktop`),
|
|
151
|
+
* the adapter points PICO-8's `root_path` here so the WAV lands in an isolated
|
|
152
|
+
* temp dir, never `~/Desktop` or the carts root (the shared-write discipline).
|
|
153
|
+
*/
|
|
154
|
+
readonly wavDir: string;
|
|
155
|
+
/**
|
|
156
|
+
* The base filename (no extension) the cart passed to `extcmd("set_filename")`,
|
|
157
|
+
* so the adapter knows which `<base>.wav` to collect. Defaults to
|
|
158
|
+
* {@link RECORD_WAV_BASENAME} when omitted.
|
|
159
|
+
*/
|
|
160
|
+
readonly wavBasename?: string;
|
|
161
|
+
/** The stdout line that ends the run when matched (defaults to {@link DONE_SENTINEL}). */
|
|
162
|
+
readonly sentinel?: string;
|
|
163
|
+
/** The hard backstop in ms: kill PICO-8 if it neither signals nor exits by then. */
|
|
164
|
+
readonly backstopMs: number;
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
/**
|
|
168
|
+
* A completed EXPORT run's results (the PICO-8 HTML export, `pico8 <cart>
|
|
169
|
+
* -export <name>.html -x`). PICO-8 writes a pair into the output dir: the shell
|
|
170
|
+
* page (`<name>.html`, which references its sibling by name) and the
|
|
171
|
+
* Emscripten runtime + baked-in cart payload (`<name>.js`). `htmlPath` is the
|
|
172
|
+
* shell page (undefined for a payload-only export that keeps only the runtime);
|
|
173
|
+
* `jsPath` is the runtime payload; `files` lists every produced file (absolute).
|
|
174
|
+
* `labelWarning` surfaces PICO-8's "please capture a label first" notice: a
|
|
175
|
+
* labelless cart exports with an ugly/blank splash (a soft warning, not a
|
|
176
|
+
* failure).
|
|
177
|
+
*/
|
|
178
|
+
export interface ExportReport {
|
|
179
|
+
readonly htmlPath: string | undefined;
|
|
180
|
+
readonly jsPath: string | undefined;
|
|
181
|
+
readonly files: readonly string[];
|
|
182
|
+
readonly labelWarning: boolean;
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
/** A successful export call carrying the {@link ExportReport}. */
|
|
186
|
+
export interface Pico8ExportOk {
|
|
187
|
+
readonly ok: true;
|
|
188
|
+
readonly value: ExportReport;
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
/**
|
|
192
|
+
* The result {@link Pico8Adapter.export} returns: an {@link ExportReport} or the
|
|
193
|
+
* structured {@link Pico8NotFound} (PICO-8 absent), mirroring {@link Pico8Result}.
|
|
194
|
+
*/
|
|
195
|
+
export type Pico8ExportResult = Pico8ExportOk | Pico8NotFound;
|
|
196
|
+
|
|
197
|
+
/**
|
|
198
|
+
* Options for a single {@link Pico8Adapter.export}. PICO-8 derives the produced
|
|
199
|
+
* file names from `htmlName` (`game.html` -> `game.html` + `game.js`), so the
|
|
200
|
+
* command passes `index.html` to get a directly-serveable `index.html` +
|
|
201
|
+
* `index.js` pair in `outDir`. `payloadOnly` keeps only the `.js` runtime
|
|
202
|
+
* payload (dropping the shell page) for a website that provides its OWN player
|
|
203
|
+
* shell (a Svelte component), never the PICO-8 binary's concern: the split is a
|
|
204
|
+
* post-export file operation the command owns.
|
|
205
|
+
*/
|
|
206
|
+
export interface ExportOptions {
|
|
207
|
+
/** Absolute path to the `.p8` cart to export. */
|
|
208
|
+
readonly cartPath: string;
|
|
209
|
+
/** The run-controlled dir PICO-8 writes the export pair into. */
|
|
210
|
+
readonly outDir: string;
|
|
211
|
+
/**
|
|
212
|
+
* The `.html` name handed to `-export` (e.g. `index.html`); PICO-8 derives the
|
|
213
|
+
* sibling `.js` from it. Defaults to {@link EXPORT_HTML_NAME}.
|
|
214
|
+
*/
|
|
215
|
+
readonly htmlName?: string;
|
|
216
|
+
/** The hard backstop in ms: kill PICO-8 if the export neither completes nor exits. */
|
|
217
|
+
readonly backstopMs: number;
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
/** The default `.html` name `export` hands to `-export`: yields a serveable `index.html` + `index.js`. */
|
|
221
|
+
export const EXPORT_HTML_NAME = 'index.html' as const;
|
|
222
|
+
|
|
223
|
+
/** Options for a single {@link Pico8Adapter.run}. */
|
|
224
|
+
export interface RunOptions {
|
|
225
|
+
/** Absolute path to the `.p8` cart to run. */
|
|
226
|
+
readonly cartPath: string;
|
|
227
|
+
/** The run-controlled dir PICO-8 writes screenshots into (`-desktop <dir>`). */
|
|
228
|
+
readonly shotDir: string;
|
|
229
|
+
/** The stdout line that ends the run when matched (defaults to {@link DONE_SENTINEL}). */
|
|
230
|
+
readonly sentinel?: string;
|
|
231
|
+
/** The hard backstop in ms: kill PICO-8 if it neither signals nor exits by then. */
|
|
232
|
+
readonly backstopMs: number;
|
|
233
|
+
/**
|
|
234
|
+
* Optional one-shot scripted input passed as `-p <input>`; the cart reads it
|
|
235
|
+
* via `stat(6)` and replays it (the canned-playtest channel). The cart must
|
|
236
|
+
* cooperate by decoding `stat(6)` (taught in the `picopilot-debug` skill).
|
|
237
|
+
* Absent = no input passed.
|
|
238
|
+
*/
|
|
239
|
+
readonly input?: string;
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
/**
|
|
243
|
+
* The PICO-8 capability seam. One method for now: {@link run}. Later PICO-8-gated
|
|
244
|
+
* operations (`audio render`, `export`) extend THIS interface rather than forking.
|
|
245
|
+
*/
|
|
246
|
+
export interface Pico8Adapter {
|
|
247
|
+
/**
|
|
248
|
+
* Launches PICO-8 on `cartPath`, streams stdout, ends the run on the sentinel
|
|
249
|
+
* (with the backstop as the safety net), and collects screenshots + printh +
|
|
250
|
+
* exit reason. Returns {@link Pico8NotFound} when PICO-8 is not installed.
|
|
251
|
+
*/
|
|
252
|
+
run(options: RunOptions): Promise<Pico8Result>;
|
|
253
|
+
|
|
254
|
+
/**
|
|
255
|
+
* Launches PICO-8 on `cartPath` in a REAL audio+video session (NOT headless
|
|
256
|
+
* `-x`, which mixes no audio and yields an empty WAV, ADR-0009), streams
|
|
257
|
+
* stdout, ends on the sentinel (backstop as the net), and collects the WAV the
|
|
258
|
+
* cooperating cart wrote via `audio_rec`/`audio_end(1)`. Returns
|
|
259
|
+
* {@link Pico8NotFound} when PICO-8 is not installed. Live capture is a
|
|
260
|
+
* manual/opt-in tier; CI drives a fake runner + the absent boundary.
|
|
261
|
+
*/
|
|
262
|
+
record(options: RecordOptions): Promise<Pico8RecordResult>;
|
|
263
|
+
|
|
264
|
+
/**
|
|
265
|
+
* Launches PICO-8 on the THROWAWAY driven cart (`-desktop <shotDir> -x`),
|
|
266
|
+
* pipes the encoded FIXED-SIZE command blocks to its live stdin (the input +
|
|
267
|
+
* frame-loop transport, ADR-0011), ends on the sentinel (backstop as the net),
|
|
268
|
+
* and collects the SHOT screenshots + printh + exit reason. Returns
|
|
269
|
+
* {@link Pico8NotFound} when PICO-8 is absent. Live drive-and-capture is a
|
|
270
|
+
* manual/opt-in tier; CI drives a fake runner + the absent boundary.
|
|
271
|
+
*/
|
|
272
|
+
drive(options: DriveOptions): Promise<Pico8DriveResult>;
|
|
273
|
+
|
|
274
|
+
/**
|
|
275
|
+
* Exports `cartPath` as a PICO-8 HTML bundle (`pico8 <cart> -export
|
|
276
|
+
* <outDir>/<htmlName> -x`, the HEADLESS `-x` path, no display needed) and
|
|
277
|
+
* collects the produced `.html` + `.js` pair from `outDir`. Returns
|
|
278
|
+
* {@link Pico8NotFound} when PICO-8 is absent (the CI-testable boundary). Live
|
|
279
|
+
* export is a manual/opt-in tier: it hard-requires the paid binary, and a
|
|
280
|
+
* labelless cart exports with a `labelWarning` set (a soft warning, not a
|
|
281
|
+
* failure). The command owns any post-export payload-only file split.
|
|
282
|
+
*/
|
|
283
|
+
export(options: ExportOptions): Promise<Pico8ExportResult>;
|
|
284
|
+
}
|
|
285
|
+
|
|
286
|
+
/** The default WAV basename a recorded cart passes to `extcmd("set_filename")`. */
|
|
287
|
+
export const RECORD_WAV_BASENAME = 'picopilot-audio' as const;
|
|
288
|
+
|
|
289
|
+
/** The 60 audio ticks PICO-8 advances per second: the record-duration unit (finding). */
|
|
290
|
+
export const PICO8_TICKS_PER_SECOND = 120;
|
|
291
|
+
|
|
292
|
+
/** The video frames PICO-8 runs per second (`_update` at 30fps; `t` counts frames). */
|
|
293
|
+
export const PICO8_FRAMES_PER_SECOND = 30;
|
|
294
|
+
|
|
295
|
+
/** The frozen {@link Pico8NotFound} value, so every call site returns the same shape. */
|
|
296
|
+
export function pico8NotFound(): Pico8NotFound {
|
|
297
|
+
return {
|
|
298
|
+
ok: false,
|
|
299
|
+
reason: 'pico8-not-found',
|
|
300
|
+
remedy: PICO8_REMEDY,
|
|
301
|
+
needs: [...PICO8_NEEDS],
|
|
302
|
+
};
|
|
303
|
+
}
|