picopilot 0.1.4 → 0.2.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.
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +111 -16
- package/dist/cli.js.map +1 -1
- package/dist/commands/audio.d.ts +3 -3
- package/dist/commands/audio.d.ts.map +1 -1
- package/dist/commands/audio.js +61 -44
- package/dist/commands/audio.js.map +1 -1
- package/dist/commands/cart-includes.d.ts +11 -0
- package/dist/commands/cart-includes.d.ts.map +1 -0
- package/dist/commands/cart-includes.js +26 -0
- package/dist/commands/cart-includes.js.map +1 -0
- package/dist/commands/doctor.d.ts +22 -0
- package/dist/commands/doctor.d.ts.map +1 -0
- package/dist/commands/doctor.js +222 -0
- package/dist/commands/doctor.js.map +1 -0
- package/dist/commands/export.d.ts +3 -4
- package/dist/commands/export.d.ts.map +1 -1
- package/dist/commands/export.js +66 -86
- package/dist/commands/export.js.map +1 -1
- package/dist/commands/gfx.d.ts +2 -2
- package/dist/commands/gfx.d.ts.map +1 -1
- package/dist/commands/gfx.js +3 -2
- package/dist/commands/gfx.js.map +1 -1
- package/dist/commands/label-cart.d.ts +72 -0
- package/dist/commands/label-cart.d.ts.map +1 -0
- package/dist/commands/label-cart.js +228 -0
- package/dist/commands/label-cart.js.map +1 -0
- package/dist/commands/lint.d.ts +2 -2
- package/dist/commands/lint.d.ts.map +1 -1
- package/dist/commands/lint.js +3 -2
- package/dist/commands/lint.js.map +1 -1
- package/dist/commands/minify.d.ts +2 -2
- package/dist/commands/minify.d.ts.map +1 -1
- package/dist/commands/minify.js +3 -2
- package/dist/commands/minify.js.map +1 -1
- package/dist/commands/pico8-env.d.ts +76 -0
- package/dist/commands/pico8-env.d.ts.map +1 -0
- package/dist/commands/pico8-env.js +71 -0
- package/dist/commands/pico8-env.js.map +1 -0
- package/dist/commands/playtest.d.ts +2 -2
- package/dist/commands/playtest.d.ts.map +1 -1
- package/dist/commands/playtest.js +6 -32
- package/dist/commands/playtest.js.map +1 -1
- package/dist/commands/run.d.ts +3 -4
- package/dist/commands/run.d.ts.map +1 -1
- package/dist/commands/run.js +46 -19
- package/dist/commands/run.js.map +1 -1
- package/dist/commands/serve.d.ts +2 -2
- package/dist/commands/serve.d.ts.map +1 -1
- package/dist/commands/serve.js +65 -19
- package/dist/commands/serve.js.map +1 -1
- package/dist/commands/shrinko-env.d.ts +22 -0
- package/dist/commands/shrinko-env.d.ts.map +1 -0
- package/dist/commands/shrinko-env.js +15 -0
- package/dist/commands/shrinko-env.js.map +1 -0
- package/dist/commands/tokens.d.ts +4 -4
- package/dist/commands/tokens.d.ts.map +1 -1
- package/dist/commands/tokens.js +3 -2
- package/dist/commands/tokens.js.map +1 -1
- package/dist/commands/verify.d.ts +2 -2
- package/dist/commands/verify.d.ts.map +1 -1
- package/dist/commands/verify.js +3 -2
- package/dist/commands/verify.js.map +1 -1
- package/dist/engine/child-env.d.ts +14 -0
- package/dist/engine/child-env.d.ts.map +1 -0
- package/dist/engine/child-env.js +21 -0
- package/dist/engine/child-env.js.map +1 -0
- package/dist/engine/gfx/label.d.ts +15 -9
- package/dist/engine/gfx/label.d.ts.map +1 -1
- package/dist/engine/gfx/label.js +130 -38
- package/dist/engine/gfx/label.js.map +1 -1
- package/dist/engine/pico8/adapter.d.ts +23 -3
- package/dist/engine/pico8/adapter.d.ts.map +1 -1
- package/dist/engine/pico8/adapter.js.map +1 -1
- package/dist/engine/pico8/cleanup.d.ts +16 -0
- package/dist/engine/pico8/cleanup.d.ts.map +1 -0
- package/dist/engine/pico8/cleanup.js +74 -0
- package/dist/engine/pico8/cleanup.js.map +1 -0
- package/dist/engine/pico8/display.d.ts +149 -0
- package/dist/engine/pico8/display.d.ts.map +1 -0
- package/dist/engine/pico8/display.js +311 -0
- package/dist/engine/pico8/display.js.map +1 -0
- package/dist/engine/pico8/drive.d.ts.map +1 -1
- package/dist/engine/pico8/drive.js +28 -2
- package/dist/engine/pico8/drive.js.map +1 -1
- package/dist/engine/pico8/harness.d.ts +8 -0
- package/dist/engine/pico8/harness.d.ts.map +1 -1
- package/dist/engine/pico8/harness.js +9 -1
- package/dist/engine/pico8/harness.js.map +1 -1
- package/dist/engine/pico8/index.d.ts +3 -0
- package/dist/engine/pico8/index.d.ts.map +1 -1
- package/dist/engine/pico8/index.js +3 -0
- package/dist/engine/pico8/index.js.map +1 -1
- package/dist/engine/pico8/session-daemon-entry.d.ts +1 -1
- package/dist/engine/pico8/session-daemon-entry.js +1 -1
- package/dist/engine/pico8/session-daemon-main.d.ts +1 -1
- package/dist/engine/pico8/session-daemon-main.js +1 -1
- package/dist/engine/pico8/session-daemon.d.ts +1 -1
- package/dist/engine/pico8/session-daemon.d.ts.map +1 -1
- package/dist/engine/pico8/session-daemon.js +19 -19
- package/dist/engine/pico8/session-daemon.js.map +1 -1
- package/dist/engine/pico8/session.d.ts +1 -1
- package/dist/engine/pico8/session.js +1 -1
- package/dist/engine/pico8/shell.d.ts +56 -3
- package/dist/engine/pico8/shell.d.ts.map +1 -1
- package/dist/engine/pico8/shell.js +188 -24
- package/dist/engine/pico8/shell.js.map +1 -1
- package/dist/engine/pico8/supervisor.d.ts +1 -1
- package/dist/engine/pico8/supervisor.js +1 -1
- package/dist/engine/shrinko/adapter.d.ts +1 -1
- package/dist/engine/shrinko/shell.d.ts +3 -3
- package/dist/engine/shrinko/shell.js +3 -3
- package/package.json +2 -1
- package/src/cli.test.ts +188 -0
- package/src/cli.ts +122 -16
- package/src/commands/audio.test.ts +76 -1
- package/src/commands/audio.ts +79 -57
- package/src/commands/cart-includes.ts +27 -0
- package/src/commands/doctor.test.ts +149 -0
- package/src/commands/doctor.ts +280 -0
- package/src/commands/export.test.ts +327 -3
- package/src/commands/export.ts +81 -99
- package/src/commands/gfx.ts +7 -6
- package/src/commands/label-cart.ts +304 -0
- package/src/commands/lint.test.ts +6 -0
- package/src/commands/lint.ts +7 -6
- package/src/commands/minify.test.ts +6 -0
- package/src/commands/minify.ts +7 -6
- package/src/commands/pico8-env.ts +124 -0
- package/src/commands/playtest.test.ts +3 -0
- package/src/commands/playtest.ts +10 -34
- package/src/commands/run.test.ts +116 -2
- package/src/commands/run.ts +62 -24
- package/src/commands/serve.test.ts +138 -2
- package/src/commands/serve.ts +80 -21
- package/src/commands/shrinko-env.test.ts +68 -0
- package/src/commands/shrinko-env.ts +40 -0
- package/src/commands/tokens.test.ts +19 -0
- package/src/commands/tokens.ts +9 -6
- package/src/commands/verify.test.ts +12 -0
- package/src/commands/verify.ts +7 -4
- package/src/engine/child-env.ts +22 -0
- package/src/engine/gfx/fixtures/pico8-screenshot-384.png +0 -0
- package/src/engine/gfx/label.test.ts +467 -1
- package/src/engine/gfx/label.ts +147 -41
- package/src/engine/pico8/adapter.ts +25 -3
- package/src/engine/pico8/cleanup.test.ts +28 -0
- package/src/engine/pico8/cleanup.ts +76 -0
- package/src/engine/pico8/display.test.ts +210 -0
- package/src/engine/pico8/display.ts +429 -0
- package/src/engine/pico8/drive.test.ts +20 -0
- package/src/engine/pico8/drive.ts +25 -2
- package/src/engine/pico8/fake-xvfb.test-support.ts +55 -0
- package/src/engine/pico8/harness.test.ts +26 -0
- package/src/engine/pico8/harness.ts +18 -2
- package/src/engine/pico8/index.ts +3 -0
- package/src/engine/pico8/session-daemon-entry.ts +1 -1
- package/src/engine/pico8/session-daemon-main.ts +1 -1
- package/src/engine/pico8/session-daemon.test.ts +32 -1
- package/src/engine/pico8/session-daemon.ts +25 -17
- package/src/engine/pico8/session.test.ts +1 -1
- package/src/engine/pico8/session.ts +1 -1
- package/src/engine/pico8/shell.test.ts +449 -10
- package/src/engine/pico8/shell.ts +255 -26
- package/src/engine/pico8/supervisor.ts +1 -1
- package/src/engine/pico8/virtual-display.process.test.ts +206 -0
- package/src/engine/shrinko/adapter.ts +1 -1
- package/src/engine/shrinko/shell.ts +3 -3
- package/src/engine/skills/skills.test.ts +10 -0
- package/src/skills/picopilot-audio/SKILL.md +4 -8
- package/src/skills/picopilot-debug/SKILL.md +18 -1
- package/src/skills/picopilot-overview/SKILL.md +9 -1
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
import { type DriveOptions, type Pico8DriveResult } from '../engine/pico8/index.js';
|
|
2
|
+
/**
|
|
3
|
+
* The remedy for both label-image errors (`label-wrong-size`,
|
|
4
|
+
* `label-unsupported-png`): the screenshot `run`/`playtest` already wrote is a
|
|
5
|
+
* valid label as-is, so point at that rather than at an external image tool.
|
|
6
|
+
*/
|
|
7
|
+
export declare const LABEL_FIX_CTA: {
|
|
8
|
+
description: string;
|
|
9
|
+
commands: {
|
|
10
|
+
command: string;
|
|
11
|
+
description: string;
|
|
12
|
+
}[];
|
|
13
|
+
};
|
|
14
|
+
/** Where the exported cart's `__label__` came from. */
|
|
15
|
+
export type LabelSource = 'cart' | 'image' | 'frame' | 'none';
|
|
16
|
+
/** A cart ready to hand to PICO-8's export, plus how to tidy up after it. */
|
|
17
|
+
export interface LabeledCart {
|
|
18
|
+
readonly ok: true;
|
|
19
|
+
/** The cart to export: the original, or a labeled throwaway copy. */
|
|
20
|
+
readonly cartPath: string;
|
|
21
|
+
/**
|
|
22
|
+
* Where the label comes from: the cart's own (`cart`), `--label` (`image`),
|
|
23
|
+
* `--label-frame` (`frame`), or nowhere (`none`, the cart stays labelless).
|
|
24
|
+
*/
|
|
25
|
+
readonly labelSource: LabelSource;
|
|
26
|
+
/** Removes the throwaway copy (if one was made). Best-effort, idempotent. */
|
|
27
|
+
readonly cleanup: () => void;
|
|
28
|
+
}
|
|
29
|
+
/** A label-preparation failure, shaped for incur's `error({...})`. */
|
|
30
|
+
export interface LabelCartFailure {
|
|
31
|
+
readonly ok: false;
|
|
32
|
+
readonly code: string;
|
|
33
|
+
readonly message: string;
|
|
34
|
+
readonly cta?: {
|
|
35
|
+
description: string;
|
|
36
|
+
commands: {
|
|
37
|
+
command: string;
|
|
38
|
+
description: string;
|
|
39
|
+
}[];
|
|
40
|
+
};
|
|
41
|
+
}
|
|
42
|
+
/** The label flags `export` and `serve` share. */
|
|
43
|
+
export interface LabelOptions {
|
|
44
|
+
/** `--label <png>`: an image (a run/playtest screenshot as-is, or 128x128). */
|
|
45
|
+
readonly label?: string;
|
|
46
|
+
/** `--label-frame <n>`: capture frame `n` of the running cart, no input. */
|
|
47
|
+
readonly labelFrame?: number;
|
|
48
|
+
/** The backstop for the `--label-frame` capture run. */
|
|
49
|
+
readonly backstopMs: number;
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* The `--label` / `--label-frame` step shared by `export` and `serve` (ADR-0013,
|
|
53
|
+
* ADR-0015, ADR-0016): give a labelless cart a `__label__` (the export splash)
|
|
54
|
+
* without an interactive F7 capture.
|
|
55
|
+
*
|
|
56
|
+
* - `--label <png>`: decode an image (a `run`/`playtest` screenshot as-is, any
|
|
57
|
+
* square integer multiple of 128x128, or any 128x128 PNG).
|
|
58
|
+
* - `--label-frame <n>`: RUN the cart headlessly through the playtest drive
|
|
59
|
+
* harness (ADR-0011) with NO input, advance `n` frames, screenshot that frame,
|
|
60
|
+
* and decode it. Needs PICO-8 (`drive`); an arbitrary cart does not have to
|
|
61
|
+
* cooperate, since the harness owns its frame loop.
|
|
62
|
+
*
|
|
63
|
+
* The two flags are mutually exclusive (`label-flags-conflict`). The user's cart
|
|
64
|
+
* is NEVER mutated: a labeled copy is written NEXT TO it (same dir, so
|
|
65
|
+
* `#include main.lua` still resolves) and the caller exports that, then calls
|
|
66
|
+
* `cleanup()`. A cart that ALREADY has a label wins (the flags are a fallback,
|
|
67
|
+
* not an override): it is returned untouched and nothing is run.
|
|
68
|
+
*
|
|
69
|
+
* @param drive the adapter's `drive`, only called for `--label-frame`.
|
|
70
|
+
*/
|
|
71
|
+
export declare function prepareLabeledCart(cartPath: string, options: LabelOptions, drive: (options: DriveOptions) => Promise<Pico8DriveResult>): Promise<LabeledCart | LabelCartFailure>;
|
|
72
|
+
//# sourceMappingURL=label-cart.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"label-cart.d.ts","sourceRoot":"","sources":["../../src/commands/label-cart.ts"],"names":[],"mappings":"AAWA,OAAO,EAGN,KAAK,YAAY,EACjB,KAAK,gBAAgB,EACrB,MAAM,0BAA0B,CAAC;AAGlC;;;;GAIG;AACH,eAAO,MAAM,aAAa;;;;;;CAezB,CAAC;AAEF,uDAAuD;AACvD,MAAM,MAAM,WAAW,GAAG,MAAM,GAAG,OAAO,GAAG,OAAO,GAAG,MAAM,CAAC;AAE9D,6EAA6E;AAC7E,MAAM,WAAW,WAAW;IAC3B,QAAQ,CAAC,EAAE,EAAE,IAAI,CAAC;IAClB,qEAAqE;IACrE,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B;;;OAGG;IACH,QAAQ,CAAC,WAAW,EAAE,WAAW,CAAC;IAClC,6EAA6E;IAC7E,QAAQ,CAAC,OAAO,EAAE,MAAM,IAAI,CAAC;CAC7B;AAED,sEAAsE;AACtE,MAAM,WAAW,gBAAgB;IAChC,QAAQ,CAAC,EAAE,EAAE,KAAK,CAAC;IACnB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,GAAG,CAAC,EAAE;QACd,WAAW,EAAE,MAAM,CAAC;QACpB,QAAQ,EAAE;YAAC,OAAO,EAAE,MAAM,CAAC;YAAC,WAAW,EAAE,MAAM,CAAA;SAAC,EAAE,CAAC;KACnD,CAAC;CACF;AAED,kDAAkD;AAClD,MAAM,WAAW,YAAY;IAC5B,+EAA+E;IAC/E,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IACxB,4EAA4E;IAC5E,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,CAAC;IAC7B,wDAAwD;IACxD,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;CAC5B;AAKD;;;;;;;;;;;;;;;;;;;GAmBG;AACH,wBAAsB,kBAAkB,CACvC,QAAQ,EAAE,MAAM,EAChB,OAAO,EAAE,YAAY,EACrB,KAAK,EAAE,CAAC,OAAO,EAAE,YAAY,KAAK,OAAO,CAAC,gBAAgB,CAAC,GACzD,OAAO,CAAC,WAAW,GAAG,gBAAgB,CAAC,CAwGzC"}
|
|
@@ -0,0 +1,228 @@
|
|
|
1
|
+
import { existsSync, mkdtempSync, readFileSync, rmSync, writeFileSync, } from 'node:fs';
|
|
2
|
+
import { tmpdir } from 'node:os';
|
|
3
|
+
import { dirname, isAbsolute, join, resolve } from 'node:path';
|
|
4
|
+
import { Cart, CartParseError } from '../engine/cart/index.js';
|
|
5
|
+
import { labelHexFromPng, LabelError } from '../engine/gfx/index.js';
|
|
6
|
+
import { buildDriveHarness, DriveError, } from '../engine/pico8/index.js';
|
|
7
|
+
import { makeReadInclude } from './cart-includes.js';
|
|
8
|
+
/**
|
|
9
|
+
* The remedy for both label-image errors (`label-wrong-size`,
|
|
10
|
+
* `label-unsupported-png`): the screenshot `run`/`playtest` already wrote is a
|
|
11
|
+
* valid label as-is, so point at that rather than at an external image tool.
|
|
12
|
+
*/
|
|
13
|
+
export const LABEL_FIX_CTA = {
|
|
14
|
+
description: 'Pass a picopilot screenshot directly; it is scaled for you (any 128*k square: 128x128, 256x256, 384x384, ...). No image tool needed:',
|
|
15
|
+
commands: [
|
|
16
|
+
{
|
|
17
|
+
command: 'run <cart> --shot-dir shots',
|
|
18
|
+
description: 'Capture a frame (the cart calls extcmd("screen")), then pass shots/<name>.png to --label unchanged.',
|
|
19
|
+
},
|
|
20
|
+
{
|
|
21
|
+
command: 'export <cart> <dest> --label shots/<name>.png',
|
|
22
|
+
description: 'Bake that screenshot in as the label splash (`serve --label` takes it the same way). playtest screenshots work too.',
|
|
23
|
+
},
|
|
24
|
+
],
|
|
25
|
+
};
|
|
26
|
+
/** The base filename the `--label-frame` capture names its screenshot. */
|
|
27
|
+
const LABEL_FRAME_BASENAME = 'label';
|
|
28
|
+
/**
|
|
29
|
+
* The `--label` / `--label-frame` step shared by `export` and `serve` (ADR-0013,
|
|
30
|
+
* ADR-0015, ADR-0016): give a labelless cart a `__label__` (the export splash)
|
|
31
|
+
* without an interactive F7 capture.
|
|
32
|
+
*
|
|
33
|
+
* - `--label <png>`: decode an image (a `run`/`playtest` screenshot as-is, any
|
|
34
|
+
* square integer multiple of 128x128, or any 128x128 PNG).
|
|
35
|
+
* - `--label-frame <n>`: RUN the cart headlessly through the playtest drive
|
|
36
|
+
* harness (ADR-0011) with NO input, advance `n` frames, screenshot that frame,
|
|
37
|
+
* and decode it. Needs PICO-8 (`drive`); an arbitrary cart does not have to
|
|
38
|
+
* cooperate, since the harness owns its frame loop.
|
|
39
|
+
*
|
|
40
|
+
* The two flags are mutually exclusive (`label-flags-conflict`). The user's cart
|
|
41
|
+
* is NEVER mutated: a labeled copy is written NEXT TO it (same dir, so
|
|
42
|
+
* `#include main.lua` still resolves) and the caller exports that, then calls
|
|
43
|
+
* `cleanup()`. A cart that ALREADY has a label wins (the flags are a fallback,
|
|
44
|
+
* not an override): it is returned untouched and nothing is run.
|
|
45
|
+
*
|
|
46
|
+
* @param drive the adapter's `drive`, only called for `--label-frame`.
|
|
47
|
+
*/
|
|
48
|
+
export async function prepareLabeledCart(cartPath, options, drive) {
|
|
49
|
+
const keep = (labelSource) => ({
|
|
50
|
+
ok: true,
|
|
51
|
+
cartPath,
|
|
52
|
+
labelSource,
|
|
53
|
+
cleanup: () => { },
|
|
54
|
+
});
|
|
55
|
+
if (options.label !== undefined && options.labelFrame !== undefined) {
|
|
56
|
+
return {
|
|
57
|
+
ok: false,
|
|
58
|
+
code: 'label-flags-conflict',
|
|
59
|
+
message: 'pass either --label <png> (an image) or --label-frame <n> (capture a frame of the running cart), not both',
|
|
60
|
+
};
|
|
61
|
+
}
|
|
62
|
+
// With no label flag the cart is only read to REPORT `labelSource`; anything
|
|
63
|
+
// odd about it (unreadable, unparseable) is left for PICO-8 to judge, exactly
|
|
64
|
+
// as before the label flags existed.
|
|
65
|
+
const noFlag = options.label === undefined && options.labelFrame === undefined;
|
|
66
|
+
let cart;
|
|
67
|
+
try {
|
|
68
|
+
cart = Cart.parse(readFileSync(cartPath, 'utf8'));
|
|
69
|
+
}
|
|
70
|
+
catch (e) {
|
|
71
|
+
if (noFlag)
|
|
72
|
+
return keep('none');
|
|
73
|
+
if (e instanceof CartParseError) {
|
|
74
|
+
return {
|
|
75
|
+
ok: false,
|
|
76
|
+
code: `cart-${e.code}`,
|
|
77
|
+
message: `could not parse the cart to inject a label: ${e.message}`,
|
|
78
|
+
};
|
|
79
|
+
}
|
|
80
|
+
throw e;
|
|
81
|
+
}
|
|
82
|
+
const existingLabel = cart.getSection('label');
|
|
83
|
+
if (existingLabel !== undefined && existingLabel.trim() !== '') {
|
|
84
|
+
return keep('cart');
|
|
85
|
+
}
|
|
86
|
+
let png;
|
|
87
|
+
let labelSource;
|
|
88
|
+
if (options.label !== undefined) {
|
|
89
|
+
const labelPath = isAbsolute(options.label)
|
|
90
|
+
? options.label
|
|
91
|
+
: resolve(process.cwd(), options.label);
|
|
92
|
+
if (!existsSync(labelPath)) {
|
|
93
|
+
return {
|
|
94
|
+
ok: false,
|
|
95
|
+
code: 'label-not-found',
|
|
96
|
+
message: `no label image at ${labelPath}`,
|
|
97
|
+
};
|
|
98
|
+
}
|
|
99
|
+
png = readFileSync(labelPath);
|
|
100
|
+
labelSource = 'image';
|
|
101
|
+
}
|
|
102
|
+
else if (options.labelFrame !== undefined) {
|
|
103
|
+
const captured = await captureFrame(cartPath, options.labelFrame, options.backstopMs, drive);
|
|
104
|
+
if (!captured.ok)
|
|
105
|
+
return captured;
|
|
106
|
+
png = captured.png;
|
|
107
|
+
labelSource = 'frame';
|
|
108
|
+
}
|
|
109
|
+
else {
|
|
110
|
+
return keep('none');
|
|
111
|
+
}
|
|
112
|
+
let hex;
|
|
113
|
+
try {
|
|
114
|
+
hex = labelHexFromPng(png);
|
|
115
|
+
}
|
|
116
|
+
catch (e) {
|
|
117
|
+
if (e instanceof LabelError) {
|
|
118
|
+
return {
|
|
119
|
+
ok: false,
|
|
120
|
+
code: `label-${e.code}`,
|
|
121
|
+
message: e.message,
|
|
122
|
+
cta: LABEL_FIX_CTA,
|
|
123
|
+
};
|
|
124
|
+
}
|
|
125
|
+
throw e;
|
|
126
|
+
}
|
|
127
|
+
cart.setSection('label', hex);
|
|
128
|
+
const copy = join(dirname(cartPath), `.picopilot-export-${process.pid}-${Date.now()}.p8`);
|
|
129
|
+
writeFileSync(copy, cart.serialize());
|
|
130
|
+
return {
|
|
131
|
+
ok: true,
|
|
132
|
+
cartPath: copy,
|
|
133
|
+
labelSource,
|
|
134
|
+
cleanup: () => {
|
|
135
|
+
try {
|
|
136
|
+
rmSync(copy, { force: true });
|
|
137
|
+
}
|
|
138
|
+
catch {
|
|
139
|
+
// A leftover dotfile is not fatal.
|
|
140
|
+
}
|
|
141
|
+
},
|
|
142
|
+
};
|
|
143
|
+
}
|
|
144
|
+
/**
|
|
145
|
+
* Runs the cart through the playtest drive harness with NO input for `frame + 1`
|
|
146
|
+
* frames, screenshotting after frame `frame` (0 = the first drawn frame), and
|
|
147
|
+
* returns that PNG. The driven cart and PICO-8's screenshot dir live in a temp
|
|
148
|
+
* dir that is removed before returning.
|
|
149
|
+
*/
|
|
150
|
+
async function captureFrame(cartPath, frame, backstopMs, drive) {
|
|
151
|
+
let harness;
|
|
152
|
+
try {
|
|
153
|
+
harness = buildDriveHarness(readFileSync(cartPath, 'utf8'), {
|
|
154
|
+
presses: [],
|
|
155
|
+
frames: frame + 1,
|
|
156
|
+
shotFrames: [frame],
|
|
157
|
+
shotBasename: LABEL_FRAME_BASENAME,
|
|
158
|
+
readInclude: makeReadInclude(cartPath),
|
|
159
|
+
});
|
|
160
|
+
}
|
|
161
|
+
catch (e) {
|
|
162
|
+
if (e instanceof DriveError) {
|
|
163
|
+
return { ok: false, code: e.code, message: e.message };
|
|
164
|
+
}
|
|
165
|
+
throw e;
|
|
166
|
+
}
|
|
167
|
+
const shotDir = mkdtempSync(join(tmpdir(), 'picopilot-label-frame-'));
|
|
168
|
+
try {
|
|
169
|
+
const drivenCart = join(shotDir, 'driven.p8');
|
|
170
|
+
writeFileSync(drivenCart, harness.cartText);
|
|
171
|
+
const result = await drive({
|
|
172
|
+
cartPath: drivenCart,
|
|
173
|
+
shotDir,
|
|
174
|
+
blocks: harness.blocks,
|
|
175
|
+
backstopMs,
|
|
176
|
+
});
|
|
177
|
+
if (!result.ok) {
|
|
178
|
+
return {
|
|
179
|
+
ok: false,
|
|
180
|
+
code: result.reason,
|
|
181
|
+
message: `PICO-8 is not installed, so --label-frame cannot capture a frame. ${result.remedy} (needs: ${result.needs.join(', ')})`,
|
|
182
|
+
};
|
|
183
|
+
}
|
|
184
|
+
const shot = result.value.screenshots[0];
|
|
185
|
+
if (shot === undefined) {
|
|
186
|
+
const { exitReason } = result.value;
|
|
187
|
+
const tail = result.value.printh.trim().split('\n').slice(-5).join('\n');
|
|
188
|
+
const commands = [
|
|
189
|
+
{
|
|
190
|
+
command: 'verify',
|
|
191
|
+
description: 'Run the static gate (tokens + lint + integrity).',
|
|
192
|
+
},
|
|
193
|
+
{
|
|
194
|
+
command: 'playtest start <cart>',
|
|
195
|
+
description: 'Reproduce the SAME no-input frame to look at it: start a paused session (nothing held), then step and shoot.',
|
|
196
|
+
},
|
|
197
|
+
{
|
|
198
|
+
command: `playtest step <id> --frames ${frame + 1}`,
|
|
199
|
+
description: `Advance to frame ${frame}, as --label-frame ${frame} does.`,
|
|
200
|
+
},
|
|
201
|
+
{
|
|
202
|
+
command: 'playtest shot <id>',
|
|
203
|
+
description: 'Screenshot it; if it looks right, pass that PNG with --label <png> (then `playtest stop <id>`).',
|
|
204
|
+
},
|
|
205
|
+
];
|
|
206
|
+
if (exitReason === 'timeout') {
|
|
207
|
+
commands.push({
|
|
208
|
+
command: `export <cart> --label-frame ${frame} --backstop-ms <more>`,
|
|
209
|
+
description: 'The capture hit the backstop (it runs about one frame per PICO-8 tick): allow more time, or pick an earlier frame.',
|
|
210
|
+
});
|
|
211
|
+
}
|
|
212
|
+
return {
|
|
213
|
+
ok: false,
|
|
214
|
+
code: 'label-frame-not-captured',
|
|
215
|
+
message: `the cart produced no frame ${frame} screenshot (exit: ${exitReason}).${tail === '' ? '' : ` Last output:\n${tail}`}`,
|
|
216
|
+
cta: {
|
|
217
|
+
description: 'The cart did not reach that frame. Check it boots, or look at the frame first:',
|
|
218
|
+
commands,
|
|
219
|
+
},
|
|
220
|
+
};
|
|
221
|
+
}
|
|
222
|
+
return { ok: true, png: readFileSync(shot) };
|
|
223
|
+
}
|
|
224
|
+
finally {
|
|
225
|
+
rmSync(shotDir, { recursive: true, force: true });
|
|
226
|
+
}
|
|
227
|
+
}
|
|
228
|
+
//# sourceMappingURL=label-cart.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"label-cart.js","sourceRoot":"","sources":["../../src/commands/label-cart.ts"],"names":[],"mappings":"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"}
|
package/dist/commands/lint.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { type Cli } from 'incur';
|
|
2
|
-
import { type
|
|
2
|
+
import { type ShrinkoAdapterFactory } from './shrinko-env.js';
|
|
3
3
|
/** See {@link import('./tokens.js').ShrinkoAdapterFactory}: lint reuses the same seam. */
|
|
4
|
-
export type ShrinkoAdapterFactory
|
|
4
|
+
export type { ShrinkoAdapterFactory } from './shrinko-env.js';
|
|
5
5
|
/**
|
|
6
6
|
* Registers `picopilot lint` (US #4): surface PICO-8-specific issues (undefined
|
|
7
7
|
* globals, unused/duplicate locals, and, via the parsed findings, the classic
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"lint.d.ts","sourceRoot":"","sources":["../../src/commands/lint.ts"],"names":[],"mappings":"AAEA,OAAO,EAAC,KAAK,GAAG,EAAI,MAAM,OAAO,CAAC;
|
|
1
|
+
{"version":3,"file":"lint.d.ts","sourceRoot":"","sources":["../../src/commands/lint.ts"],"names":[],"mappings":"AAEA,OAAO,EAAC,KAAK,GAAG,EAAI,MAAM,OAAO,CAAC;AAElC,OAAO,EAEN,KAAK,qBAAqB,EAC1B,MAAM,kBAAkB,CAAC;AAE1B,0FAA0F;AAC1F,YAAY,EAAC,qBAAqB,EAAC,MAAM,kBAAkB,CAAC;AAK5D;;;;;;;;;;;;;GAaG;AACH,wBAAgB,YAAY,CAC3B,GAAG,EAAE,GAAG,CAAC,GAAG,EACZ,cAAc,GAAE,qBAA6C,GAC3D,IAAI,CAqFN"}
|
package/dist/commands/lint.js
CHANGED
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
import { existsSync } from 'node:fs';
|
|
2
2
|
import { isAbsolute, resolve } from 'node:path';
|
|
3
3
|
import { z } from 'incur';
|
|
4
|
-
import {
|
|
5
|
-
|
|
4
|
+
import {} from '../engine/shrinko/index.js';
|
|
5
|
+
import { createShellShrinkoFactory, } from './shrinko-env.js';
|
|
6
|
+
const defaultAdapterFactory = createShellShrinkoFactory();
|
|
6
7
|
/**
|
|
7
8
|
* Registers `picopilot lint` (US #4): surface PICO-8-specific issues (undefined
|
|
8
9
|
* globals, unused/duplicate locals, and, via the parsed findings, the classic
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"lint.js","sourceRoot":"","sources":["../../src/commands/lint.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,UAAU,EAAC,MAAM,SAAS,CAAC;AACnC,OAAO,EAAC,UAAU,EAAE,OAAO,EAAC,MAAM,WAAW,CAAC;AAC9C,OAAO,EAAW,CAAC,EAAC,MAAM,OAAO,CAAC;AAClC,OAAO,
|
|
1
|
+
{"version":3,"file":"lint.js","sourceRoot":"","sources":["../../src/commands/lint.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { type Cli } from 'incur';
|
|
2
|
-
import { type
|
|
2
|
+
import { type ShrinkoAdapterFactory } from './shrinko-env.js';
|
|
3
3
|
/** See {@link import('./tokens.js').ShrinkoAdapterFactory}: minify reuses the same seam. */
|
|
4
|
-
export type ShrinkoAdapterFactory
|
|
4
|
+
export type { ShrinkoAdapterFactory } from './shrinko-env.js';
|
|
5
5
|
/**
|
|
6
6
|
* Registers `picopilot minify` (US #5, ADR-0007): run shrinko8's SAFE
|
|
7
7
|
* minification and write the result to a SEPARATE artifact (`<name>.min.p8` by
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"minify.d.ts","sourceRoot":"","sources":["../../src/commands/minify.ts"],"names":[],"mappings":"AAEA,OAAO,EAAC,KAAK,GAAG,EAAI,MAAM,OAAO,CAAC;
|
|
1
|
+
{"version":3,"file":"minify.d.ts","sourceRoot":"","sources":["../../src/commands/minify.ts"],"names":[],"mappings":"AAEA,OAAO,EAAC,KAAK,GAAG,EAAI,MAAM,OAAO,CAAC;AAElC,OAAO,EAEN,KAAK,qBAAqB,EAC1B,MAAM,kBAAkB,CAAC;AAE1B,4FAA4F;AAC5F,YAAY,EAAC,qBAAqB,EAAC,MAAM,kBAAkB,CAAC;AAoB5D;;;;;;;;;;;;;GAaG;AACH,wBAAgB,cAAc,CAC7B,GAAG,EAAE,GAAG,CAAC,GAAG,EACZ,cAAc,GAAE,qBAA6C,GAC3D,IAAI,CA6GN"}
|
package/dist/commands/minify.js
CHANGED
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
import { existsSync } from 'node:fs';
|
|
2
2
|
import { dirname, isAbsolute, join, resolve } from 'node:path';
|
|
3
3
|
import { z } from 'incur';
|
|
4
|
-
import {
|
|
5
|
-
|
|
4
|
+
import {} from '../engine/shrinko/index.js';
|
|
5
|
+
import { createShellShrinkoFactory, } from './shrinko-env.js';
|
|
6
|
+
const defaultAdapterFactory = createShellShrinkoFactory();
|
|
6
7
|
/**
|
|
7
8
|
* Derives the default output path `<name>.min.p8` next to the source cart:
|
|
8
9
|
* `main.p8` -> `main.min.p8`, `game.p8.png` -> `game.min.p8.png` is NOT the
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"minify.js","sourceRoot":"","sources":["../../src/commands/minify.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,UAAU,EAAC,MAAM,SAAS,CAAC;AACnC,OAAO,EAAC,OAAO,EAAE,UAAU,EAAE,IAAI,EAAE,OAAO,EAAC,MAAM,WAAW,CAAC;AAC7D,OAAO,EAAW,CAAC,EAAC,MAAM,OAAO,CAAC;AAClC,OAAO,
|
|
1
|
+
{"version":3,"file":"minify.js","sourceRoot":"","sources":["../../src/commands/minify.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
import { z } from 'incur';
|
|
2
|
+
import { type DisplayMode, type Pico8Adapter, type SpawnRunner, type VirtualDisplayDeps } from '../engine/pico8/index.js';
|
|
3
|
+
/**
|
|
4
|
+
* The env schema every PICO-8-gated command declares. These are the values
|
|
5
|
+
* picopilot itself RESOLVES (incur reads them from its env source, which tests
|
|
6
|
+
* override); they are NOT the whole child environment. The child gets the
|
|
7
|
+
* parent environment with these overlaid ({@link pico8ChildEnv}), so PICO-8
|
|
8
|
+
* still sees DISPLAY, HOME, XDG_RUNTIME_DIR, SDL_* and the rest.
|
|
9
|
+
*/
|
|
10
|
+
export declare const PICO8_ENV: z.ZodObject<{
|
|
11
|
+
PICO8_PATH: z.ZodOptional<z.ZodString>;
|
|
12
|
+
PATH: z.ZodOptional<z.ZodString>;
|
|
13
|
+
}, z.core.$strip>;
|
|
14
|
+
/** What a command knows beyond the env when it builds an adapter. */
|
|
15
|
+
export interface Pico8AdapterContext {
|
|
16
|
+
/** The resolved display mode for `-run` sessions (ADR-0017). */
|
|
17
|
+
readonly display: DisplayMode;
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* Injects the PICO-8 adapter a command uses. A test passes a stub to drive the
|
|
21
|
+
* sentinel/backstop/absent paths without the paid binary; the default is
|
|
22
|
+
* {@link createShellAdapterFactory}.
|
|
23
|
+
*/
|
|
24
|
+
export type Pico8AdapterFactory = (env: NodeJS.ProcessEnv, context?: Pico8AdapterContext) => Pico8Adapter;
|
|
25
|
+
/** Dependencies for {@link createShellAdapterFactory}, injectable for tests. */
|
|
26
|
+
export interface ShellAdapterFactoryDeps {
|
|
27
|
+
/** The parent environment PICO-8 inherits (defaults to `process.env`). */
|
|
28
|
+
readonly parentEnv?: NodeJS.ProcessEnv;
|
|
29
|
+
/** The PICO-8 spawn seam (defaults to the real spawn). */
|
|
30
|
+
readonly spawn?: SpawnRunner;
|
|
31
|
+
/** The virtual-display seam (Xvfb lookup + spawn). */
|
|
32
|
+
readonly virtualDisplay?: VirtualDisplayDeps;
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* The default adapter factory: the shell adapter over the user's PICO-8, with
|
|
36
|
+
* the child env = parent env + the command's resolved values, and the display
|
|
37
|
+
* mode from the context.
|
|
38
|
+
*/
|
|
39
|
+
export declare function createShellAdapterFactory(deps?: ShellAdapterFactoryDeps): Pico8AdapterFactory;
|
|
40
|
+
/**
|
|
41
|
+
* The display mode a command handler sees. The root middleware in `createCli`
|
|
42
|
+
* resolves it (flag > env > config > default) into the `display` var; a command
|
|
43
|
+
* mounted on a bare CLI (some tests) has no var and gets the default.
|
|
44
|
+
*/
|
|
45
|
+
export declare function displayModeOf(vars: unknown): DisplayMode;
|
|
46
|
+
/**
|
|
47
|
+
* The `error(...)` payload for a `display-unavailable` result (ADR-0017): the
|
|
48
|
+
* session needs a display, there is none, and no Xvfb is installed to provide a
|
|
49
|
+
* virtual one. The message and CTA name the fix, so the agent never has to
|
|
50
|
+
* discover it by a silent timeout.
|
|
51
|
+
*/
|
|
52
|
+
export declare function displayUnavailableError(what: string, result: {
|
|
53
|
+
detail: string;
|
|
54
|
+
remedy: string;
|
|
55
|
+
}): {
|
|
56
|
+
code: "display-unavailable";
|
|
57
|
+
message: string;
|
|
58
|
+
exitCode: number;
|
|
59
|
+
cta: {
|
|
60
|
+
description: string;
|
|
61
|
+
commands: {
|
|
62
|
+
command: string;
|
|
63
|
+
description: string;
|
|
64
|
+
}[];
|
|
65
|
+
};
|
|
66
|
+
};
|
|
67
|
+
/** The `error(...)` payload for a `pico8-not-found` result (the exact remedy + needs). */
|
|
68
|
+
export declare function pico8NotFoundError(result: {
|
|
69
|
+
remedy: string;
|
|
70
|
+
needs: readonly string[];
|
|
71
|
+
}): {
|
|
72
|
+
code: "pico8-not-found";
|
|
73
|
+
message: string;
|
|
74
|
+
exitCode: number;
|
|
75
|
+
};
|
|
76
|
+
//# sourceMappingURL=pico8-env.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pico8-env.d.ts","sourceRoot":"","sources":["../../src/commands/pico8-env.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,CAAC,EAAC,MAAM,OAAO,CAAC;AACxB,OAAO,EAEN,KAAK,WAAW,EAEhB,KAAK,YAAY,EAGjB,KAAK,WAAW,EAChB,KAAK,kBAAkB,EACvB,MAAM,0BAA0B,CAAC;AAElC;;;;;;GAMG;AACH,eAAO,MAAM,SAAS;;;iBAMpB,CAAC;AAEH,qEAAqE;AACrE,MAAM,WAAW,mBAAmB;IACnC,gEAAgE;IAChE,QAAQ,CAAC,OAAO,EAAE,WAAW,CAAC;CAC9B;AAED;;;;GAIG;AACH,MAAM,MAAM,mBAAmB,GAAG,CACjC,GAAG,EAAE,MAAM,CAAC,UAAU,EACtB,OAAO,CAAC,EAAE,mBAAmB,KACzB,YAAY,CAAC;AAElB,gFAAgF;AAChF,MAAM,WAAW,uBAAuB;IACvC,0EAA0E;IAC1E,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAC,UAAU,CAAC;IACvC,0DAA0D;IAC1D,QAAQ,CAAC,KAAK,CAAC,EAAE,WAAW,CAAC;IAC7B,sDAAsD;IACtD,QAAQ,CAAC,cAAc,CAAC,EAAE,kBAAkB,CAAC;CAC7C;AAED;;;;GAIG;AACH,wBAAgB,yBAAyB,CACxC,IAAI,GAAE,uBAA4B,GAChC,mBAAmB,CAWrB;AAED;;;;GAIG;AACH,wBAAgB,aAAa,CAAC,IAAI,EAAE,OAAO,GAAG,WAAW,CAMxD;AAED;;;;;GAKG;AACH,wBAAgB,uBAAuB,CACtC,IAAI,EAAE,MAAM,EACZ,MAAM,EAAE;IAAC,MAAM,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAC;;;;;;;;;;;EAiBxC;AAED,0FAA0F;AAC1F,wBAAgB,kBAAkB,CAAC,MAAM,EAAE;IAC1C,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,SAAS,MAAM,EAAE,CAAC;CACzB;;;;EAMA"}
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
import { z } from 'incur';
|
|
2
|
+
import { DEFAULT_DISPLAY_MODE, isDisplayMode, pico8ChildEnv, ShellPico8Adapter, } from '../engine/pico8/index.js';
|
|
3
|
+
/**
|
|
4
|
+
* The env schema every PICO-8-gated command declares. These are the values
|
|
5
|
+
* picopilot itself RESOLVES (incur reads them from its env source, which tests
|
|
6
|
+
* override); they are NOT the whole child environment. The child gets the
|
|
7
|
+
* parent environment with these overlaid ({@link pico8ChildEnv}), so PICO-8
|
|
8
|
+
* still sees DISPLAY, HOME, XDG_RUNTIME_DIR, SDL_* and the rest.
|
|
9
|
+
*/
|
|
10
|
+
export const PICO8_ENV = z.object({
|
|
11
|
+
PICO8_PATH: z
|
|
12
|
+
.string()
|
|
13
|
+
.optional()
|
|
14
|
+
.describe('Explicit path to the PICO-8 binary (else `pico8` on PATH).'),
|
|
15
|
+
PATH: z.string().optional().describe('Used to locate `pico8`.'),
|
|
16
|
+
});
|
|
17
|
+
/**
|
|
18
|
+
* The default adapter factory: the shell adapter over the user's PICO-8, with
|
|
19
|
+
* the child env = parent env + the command's resolved values, and the display
|
|
20
|
+
* mode from the context.
|
|
21
|
+
*/
|
|
22
|
+
export function createShellAdapterFactory(deps = {}) {
|
|
23
|
+
return (env, context) => new ShellPico8Adapter({
|
|
24
|
+
env: pico8ChildEnv(env, deps.parentEnv ?? process.env),
|
|
25
|
+
spawn: deps.spawn,
|
|
26
|
+
display: context?.display ?? DEFAULT_DISPLAY_MODE,
|
|
27
|
+
virtualDisplay: deps.virtualDisplay,
|
|
28
|
+
});
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* The display mode a command handler sees. The root middleware in `createCli`
|
|
32
|
+
* resolves it (flag > env > config > default) into the `display` var; a command
|
|
33
|
+
* mounted on a bare CLI (some tests) has no var and gets the default.
|
|
34
|
+
*/
|
|
35
|
+
export function displayModeOf(vars) {
|
|
36
|
+
const value = vars !== null && typeof vars === 'object'
|
|
37
|
+
? vars.display
|
|
38
|
+
: undefined;
|
|
39
|
+
return isDisplayMode(value) ? value : DEFAULT_DISPLAY_MODE;
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* The `error(...)` payload for a `display-unavailable` result (ADR-0017): the
|
|
43
|
+
* session needs a display, there is none, and no Xvfb is installed to provide a
|
|
44
|
+
* virtual one. The message and CTA name the fix, so the agent never has to
|
|
45
|
+
* discover it by a silent timeout.
|
|
46
|
+
*/
|
|
47
|
+
export function displayUnavailableError(what, result) {
|
|
48
|
+
return {
|
|
49
|
+
code: 'display-unavailable',
|
|
50
|
+
message: `${what} needs a display (a real audio+video -run session): ${result.detail}. Remedy: ${result.remedy}.`,
|
|
51
|
+
exitCode: 1,
|
|
52
|
+
cta: {
|
|
53
|
+
description: `No display and no Xvfb on this machine. Fix: ${result.remedy}. Then re-run; picopilot starts a private virtual display by itself (--display auto). Check what this machine can do:`,
|
|
54
|
+
commands: [
|
|
55
|
+
{
|
|
56
|
+
command: 'doctor',
|
|
57
|
+
description: 'Report PICO-8, shrinko8 and display capabilities, and which commands are available here.',
|
|
58
|
+
},
|
|
59
|
+
],
|
|
60
|
+
},
|
|
61
|
+
};
|
|
62
|
+
}
|
|
63
|
+
/** The `error(...)` payload for a `pico8-not-found` result (the exact remedy + needs). */
|
|
64
|
+
export function pico8NotFoundError(result) {
|
|
65
|
+
return {
|
|
66
|
+
code: 'pico8-not-found',
|
|
67
|
+
message: `PICO-8 is not installed. ${result.remedy} (needs: ${result.needs.join(', ')})`,
|
|
68
|
+
exitCode: 1,
|
|
69
|
+
};
|
|
70
|
+
}
|
|
71
|
+
//# sourceMappingURL=pico8-env.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pico8-env.js","sourceRoot":"","sources":["../../src/commands/pico8-env.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,CAAC,EAAC,MAAM,OAAO,CAAC;AACxB,OAAO,EACN,oBAAoB,EAEpB,aAAa,EAEb,aAAa,EACb,iBAAiB,GAGjB,MAAM,0BAA0B,CAAC;AAElC;;;;;;GAMG;AACH,MAAM,CAAC,MAAM,SAAS,GAAG,CAAC,CAAC,MAAM,CAAC;IACjC,UAAU,EAAE,CAAC;SACX,MAAM,EAAE;SACR,QAAQ,EAAE;SACV,QAAQ,CAAC,4DAA4D,CAAC;IACxE,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,yBAAyB,CAAC;CAC/D,CAAC,CAAC;AA4BH;;;;GAIG;AACH,MAAM,UAAU,yBAAyB,CACxC,OAAgC,EAAE;IAElC,OAAO,CAAC,GAAG,EAAE,OAAO,EAAE,EAAE,CACvB,IAAI,iBAAiB,CAAC;QACrB,GAAG,EAAE,aAAa,CACjB,GAAyC,EACzC,IAAI,CAAC,SAAS,IAAI,OAAO,CAAC,GAAG,CAC7B;QACD,KAAK,EAAE,IAAI,CAAC,KAAK;QACjB,OAAO,EAAE,OAAO,EAAE,OAAO,IAAI,oBAAoB;QACjD,cAAc,EAAE,IAAI,CAAC,cAAc;KACnC,CAAC,CAAC;AACL,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,aAAa,CAAC,IAAa;IAC1C,MAAM,KAAK,GACV,IAAI,KAAK,IAAI,IAAI,OAAO,IAAI,KAAK,QAAQ;QACxC,CAAC,CAAE,IAA4B,CAAC,OAAO;QACvC,CAAC,CAAC,SAAS,CAAC;IACd,OAAO,aAAa,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,oBAAoB,CAAC;AAC5D,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,uBAAuB,CACtC,IAAY,EACZ,MAAwC;IAExC,OAAO;QACN,IAAI,EAAE,qBAA8B;QACpC,OAAO,EAAE,GAAG,IAAI,uDAAuD,MAAM,CAAC,MAAM,aAAa,MAAM,CAAC,MAAM,GAAG;QACjH,QAAQ,EAAE,CAAC;QACX,GAAG,EAAE;YACJ,WAAW,EAAE,gDAAgD,MAAM,CAAC,MAAM,uHAAuH;YACjM,QAAQ,EAAE;gBACT;oBACC,OAAO,EAAE,QAAQ;oBACjB,WAAW,EACV,0FAA0F;iBAC3F;aACD;SACD;KACD,CAAC;AACH,CAAC;AAED,0FAA0F;AAC1F,MAAM,UAAU,kBAAkB,CAAC,MAGlC;IACA,OAAO;QACN,IAAI,EAAE,iBAA0B;QAChC,OAAO,EAAE,4BAA4B,MAAM,CAAC,MAAM,YAAY,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG;QACxF,QAAQ,EAAE,CAAC;KACX,CAAC;AACH,CAAC"}
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
import { type Cli } from 'incur';
|
|
2
|
-
import { type
|
|
2
|
+
import { type Pico8AdapterFactory } from './pico8-env.js';
|
|
3
3
|
/**
|
|
4
4
|
* Injects the PICO-8 adapter `playtest` uses (defaults to the shell adapter over
|
|
5
5
|
* native `pico8 -x`). Mirrors `run`'s `Pico8AdapterFactory` seam: a test passes a
|
|
6
6
|
* stub to drive the drive-orchestration + the absent path WITHOUT the paid
|
|
7
7
|
* binary, and to isolate the child `env` (its `PICO8_PATH`/`PATH`).
|
|
8
8
|
*/
|
|
9
|
-
export type Pico8AdapterFactory
|
|
9
|
+
export type { Pico8AdapterFactory } from './pico8-env.js';
|
|
10
10
|
/**
|
|
11
11
|
* Registers `picopilot playtest`, the driven-playtest command group (ADR-0011).
|
|
12
12
|
* The ROOT command (`playtest <cart>`) is the ONE-SHOT driver (US #1-5,7-11): it
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"playtest.d.ts","sourceRoot":"","sources":["../../src/commands/playtest.ts"],"names":[],"mappings":"AASA,OAAO,EAAC,KAAK,GAAG,EAAqB,MAAM,OAAO,CAAC;
|
|
1
|
+
{"version":3,"file":"playtest.d.ts","sourceRoot":"","sources":["../../src/commands/playtest.ts"],"names":[],"mappings":"AASA,OAAO,EAAC,KAAK,GAAG,EAAqB,MAAM,OAAO,CAAC;AAoBnD,OAAO,EAGN,KAAK,mBAAmB,EACxB,MAAM,gBAAgB,CAAC;AAGxB;;;;;GAKG;AACH,YAAY,EAAC,mBAAmB,EAAC,MAAM,gBAAgB,CAAC;AA0BxD;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,gBAAgB,CAC/B,GAAG,EAAE,GAAG,CAAC,GAAG,EACZ,cAAc,GAAE,mBAA2C,GACzD,IAAI,CAEN"}
|