picopilot 0.1.5 → 0.2.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/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +205 -17
- 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 +69 -44
- package/dist/commands/audio.js.map +1 -1
- package/dist/commands/doctor.d.ts +22 -0
- package/dist/commands/doctor.d.ts.map +1 -0
- package/dist/commands/doctor.js +226 -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 +4 -9
- 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 +14 -7
- package/dist/commands/gfx.js.map +1 -1
- 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 +112 -0
- package/dist/commands/pico8-env.d.ts.map +1 -0
- package/dist/commands/pico8-env.js +118 -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 +4 -9
- 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 +52 -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 +4 -9
- 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/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/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/shrinko/shell.d.ts +3 -3
- package/dist/engine/shrinko/shell.js +3 -3
- package/package.json +2 -2
- package/src/cli.test.ts +229 -0
- package/src/cli.ts +230 -18
- package/src/commands/audio.test.ts +64 -1
- package/src/commands/audio.ts +86 -57
- package/src/commands/doctor.test.ts +149 -0
- package/src/commands/doctor.ts +284 -0
- package/src/commands/export.ts +9 -13
- package/src/commands/gfx.ts +19 -15
- package/src/commands/lint.ts +7 -6
- package/src/commands/minify.ts +7 -6
- package/src/commands/pico8-env.ts +192 -0
- package/src/commands/playtest.ts +8 -11
- package/src/commands/run.test.ts +110 -2
- package/src/commands/run.ts +68 -24
- package/src/commands/serve.ts +8 -11
- package/src/commands/shrinko-env.test.ts +68 -0
- package/src/commands/shrinko-env.ts +40 -0
- package/src/commands/tokens.ts +9 -6
- package/src/commands/verify.ts +7 -4
- package/src/engine/child-env.ts +22 -0
- 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/shell.test.ts +448 -9
- package/src/engine/pico8/shell.ts +255 -26
- package/src/engine/pico8/virtual-display.process.test.ts +206 -0
- package/src/engine/shrinko/shell.ts +3 -3
- package/src/mcp.process.test.ts +219 -0
- package/src/skills/picopilot-audio/SKILL.md +4 -8
- package/src/skills/picopilot-overview/SKILL.md +9 -1
package/dist/cli.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"AAGA,OAAO,EAAC,GAAG,EAAI,MAAM,OAAO,CAAC;AA+I7B;;;;;;;;;;;GAWG;AACH,wBAAgB,SAAS,IAAI,GAAG,CAAC,GAAG,CAkHnC"}
|
package/dist/cli.js
CHANGED
|
@@ -1,5 +1,9 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { existsSync, readFileSync } from 'node:fs';
|
|
2
|
+
import { homedir } from 'node:os';
|
|
3
|
+
import { join, resolve } from 'node:path';
|
|
4
|
+
import { Cli, z } from 'incur';
|
|
2
5
|
import { registerAudio } from './commands/audio.js';
|
|
6
|
+
import { registerDoctor } from './commands/doctor.js';
|
|
3
7
|
import { registerExport } from './commands/export.js';
|
|
4
8
|
import { registerGfx } from './commands/gfx.js';
|
|
5
9
|
import { registerInit } from './commands/init.js';
|
|
@@ -13,7 +17,115 @@ import { registerSfx } from './commands/sfx.js';
|
|
|
13
17
|
import { registerTokens } from './commands/tokens.js';
|
|
14
18
|
import { registerVerify } from './commands/verify.js';
|
|
15
19
|
import { registerVersion } from './commands/version.js';
|
|
20
|
+
import { DEFAULT_DISPLAY_MODE, DISPLAY_CONFIG_KEY, DISPLAY_ENV_VAR, DISPLAY_MODES, resolveDisplayMode, } from './engine/pico8/display.js';
|
|
16
21
|
import { VERSION } from './version.js';
|
|
22
|
+
/** The config files picopilot searches (first existing wins), relative to the cwd. */
|
|
23
|
+
const CONFIG_FILES = ['picopilot.json'];
|
|
24
|
+
/**
|
|
25
|
+
* Removes every `--display <v>` / `--display=<v>` from argv and returns the last
|
|
26
|
+
* value. A `--display` with no value (last token, or followed by another flag)
|
|
27
|
+
* stays in argv, so incur rejects it instead of it silently eating the next flag.
|
|
28
|
+
*/
|
|
29
|
+
function takeDisplayFlag(argv) {
|
|
30
|
+
const rest = [];
|
|
31
|
+
let display;
|
|
32
|
+
for (let i = 0; i < argv.length; i++) {
|
|
33
|
+
const a = argv[i];
|
|
34
|
+
const next = argv[i + 1];
|
|
35
|
+
if (a === '--display' && next !== undefined && !next.startsWith('-')) {
|
|
36
|
+
display = next;
|
|
37
|
+
i++;
|
|
38
|
+
}
|
|
39
|
+
else if (a.startsWith('--display=') && a.length > '--display='.length) {
|
|
40
|
+
display = a.slice('--display='.length);
|
|
41
|
+
}
|
|
42
|
+
else {
|
|
43
|
+
rest.push(a);
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
return { argv: rest, display };
|
|
47
|
+
}
|
|
48
|
+
/** Resolves a config path the way incur does: `~` is the home dir, else relative to the cwd. */
|
|
49
|
+
function resolveConfigPath(path) {
|
|
50
|
+
return path === '~' || path.startsWith('~/')
|
|
51
|
+
? join(homedir(), path.slice(1))
|
|
52
|
+
: resolve(path);
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* For `--mcp`: the config file incur would have loaded on the CLI. Mirrors
|
|
56
|
+
* incur's own parsing: `--config <p>` / `--config=<p>` / `--no-config`, the last
|
|
57
|
+
* one wins, a missing value is an error; else the first existing default file.
|
|
58
|
+
*/
|
|
59
|
+
function loadMcpConfig(argv) {
|
|
60
|
+
let explicit;
|
|
61
|
+
let disabled = false;
|
|
62
|
+
for (let i = 0; i < argv.length; i++) {
|
|
63
|
+
const a = argv[i];
|
|
64
|
+
let value;
|
|
65
|
+
if (a === '--config')
|
|
66
|
+
value = argv[++i];
|
|
67
|
+
else if (a.startsWith('--config='))
|
|
68
|
+
value = a.slice('--config='.length);
|
|
69
|
+
else if (a === '--no-config') {
|
|
70
|
+
explicit = undefined;
|
|
71
|
+
disabled = true;
|
|
72
|
+
continue;
|
|
73
|
+
}
|
|
74
|
+
else
|
|
75
|
+
continue;
|
|
76
|
+
if (value === undefined || value === '') {
|
|
77
|
+
throw new Error('Missing value for flag: --config');
|
|
78
|
+
}
|
|
79
|
+
explicit = value;
|
|
80
|
+
disabled = false;
|
|
81
|
+
}
|
|
82
|
+
if (disabled)
|
|
83
|
+
return undefined;
|
|
84
|
+
const sink = {};
|
|
85
|
+
if (explicit !== undefined) {
|
|
86
|
+
return loadConfig(resolveConfigPath(explicit), sink);
|
|
87
|
+
}
|
|
88
|
+
for (const file of CONFIG_FILES) {
|
|
89
|
+
const path = resolveConfigPath(file);
|
|
90
|
+
if (existsSync(path))
|
|
91
|
+
return loadConfig(path, sink);
|
|
92
|
+
}
|
|
93
|
+
return undefined;
|
|
94
|
+
}
|
|
95
|
+
/**
|
|
96
|
+
* Reads a picopilot.json for incur's config layer AND captures its top-level
|
|
97
|
+
* {@link DISPLAY_CONFIG_KEY}. incur only maps per-command `options` from the
|
|
98
|
+
* config file; the display mode is a GLOBAL setting, so the loader hands the
|
|
99
|
+
* value to the display middleware through `sink`.
|
|
100
|
+
*/
|
|
101
|
+
function loadConfig(path, sink) {
|
|
102
|
+
sink.display = undefined;
|
|
103
|
+
if (path === undefined)
|
|
104
|
+
return undefined;
|
|
105
|
+
let raw;
|
|
106
|
+
try {
|
|
107
|
+
raw = readFileSync(path, 'utf8');
|
|
108
|
+
}
|
|
109
|
+
catch (e) {
|
|
110
|
+
// incur only hands the loader an existing file unless --config named one.
|
|
111
|
+
if (e.code === 'ENOENT') {
|
|
112
|
+
throw new Error(`Config file not found: ${path}`);
|
|
113
|
+
}
|
|
114
|
+
throw e;
|
|
115
|
+
}
|
|
116
|
+
let parsed;
|
|
117
|
+
try {
|
|
118
|
+
parsed = JSON.parse(raw);
|
|
119
|
+
}
|
|
120
|
+
catch {
|
|
121
|
+
throw new Error(`Invalid JSON config file: ${path}`);
|
|
122
|
+
}
|
|
123
|
+
if (parsed === null || typeof parsed !== 'object' || Array.isArray(parsed)) {
|
|
124
|
+
throw new Error(`Config file must hold a JSON object: ${path}`);
|
|
125
|
+
}
|
|
126
|
+
sink.display = parsed[DISPLAY_CONFIG_KEY];
|
|
127
|
+
return parsed;
|
|
128
|
+
}
|
|
17
129
|
/**
|
|
18
130
|
* Builds the root picopilot CLI.
|
|
19
131
|
*
|
|
@@ -27,6 +139,7 @@ import { VERSION } from './version.js';
|
|
|
27
139
|
* CLI and drive it with `cli.serve(argv, { stdout, exit, env })` DI overrides.
|
|
28
140
|
*/
|
|
29
141
|
export function createCli() {
|
|
142
|
+
const configSink = {};
|
|
30
143
|
const cli = Cli.create('picopilot', {
|
|
31
144
|
version: VERSION,
|
|
32
145
|
description: 'An agent-first toolchain for PICO-8 game development.',
|
|
@@ -37,23 +150,98 @@ export function createCli() {
|
|
|
37
150
|
// Per-cart policy config (e.g. `allowMapOverlap`); precedence argv > config > defaults.
|
|
38
151
|
config: {
|
|
39
152
|
flag: 'config',
|
|
40
|
-
files:
|
|
153
|
+
files: CONFIG_FILES,
|
|
154
|
+
loader: async (path) => loadConfig(path, configSink),
|
|
155
|
+
},
|
|
156
|
+
// The display mode (ADR-0017): `--display` (a per-command option on the
|
|
157
|
+
// commands that use it, also accepted anywhere on the command line and on
|
|
158
|
+
// `--mcp`) > PICOPILOT_DISPLAY > picopilot.json `display` > auto.
|
|
159
|
+
env: z.object({
|
|
160
|
+
[DISPLAY_ENV_VAR]: z
|
|
161
|
+
.string()
|
|
162
|
+
.optional()
|
|
163
|
+
.describe('Display mode: auto | xvfb | native (below --display).'),
|
|
164
|
+
}),
|
|
165
|
+
vars: z.object({
|
|
166
|
+
display: z.enum(DISPLAY_MODES).default(DEFAULT_DISPLAY_MODE),
|
|
167
|
+
displayError: z.string().optional(),
|
|
168
|
+
mcpConfig: z.record(z.string(), z.unknown()).optional(),
|
|
169
|
+
}),
|
|
170
|
+
mcp: {
|
|
171
|
+
// One MCP tool per command (incur's default is progressive discovery
|
|
172
|
+
// behind search/call meta-tools); picopilot's surface is small, and the
|
|
173
|
+
// skills name commands directly.
|
|
174
|
+
tools: { discovery: 'direct' },
|
|
41
175
|
},
|
|
42
176
|
});
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
177
|
+
const invocation = { mcp: false };
|
|
178
|
+
cli.use(async (c, next) => {
|
|
179
|
+
const configured = invocation.mcp
|
|
180
|
+
? invocation.mcpConfig?.[DISPLAY_CONFIG_KEY]
|
|
181
|
+
: configSink.display;
|
|
182
|
+
configSink.display = undefined; // never leak into a later invocation
|
|
183
|
+
const resolved = resolveDisplayMode({
|
|
184
|
+
flag: invocation.display,
|
|
185
|
+
env: c.env[DISPLAY_ENV_VAR],
|
|
186
|
+
config: configured,
|
|
187
|
+
});
|
|
188
|
+
if (resolved.ok) {
|
|
189
|
+
c.set('display', resolved.mode);
|
|
190
|
+
}
|
|
191
|
+
else {
|
|
192
|
+
// Not an error here: only the commands that USE the display mode fail
|
|
193
|
+
// on a bad value (see resolveCommandDisplay); the rest run as usual.
|
|
194
|
+
const where = resolved.source === 'flag'
|
|
195
|
+
? '--display'
|
|
196
|
+
: resolved.source === 'env'
|
|
197
|
+
? DISPLAY_ENV_VAR
|
|
198
|
+
: `picopilot.json "${DISPLAY_CONFIG_KEY}"`;
|
|
199
|
+
c.set('displayError', `${where} is "${resolved.value}"; expected one of: ${DISPLAY_MODES.join(', ')}.`);
|
|
200
|
+
}
|
|
201
|
+
if (invocation.mcp && invocation.mcpConfig !== undefined) {
|
|
202
|
+
c.set('mcpConfig', invocation.mcpConfig);
|
|
203
|
+
}
|
|
204
|
+
await next();
|
|
205
|
+
});
|
|
206
|
+
// Capture the top-level `--display` (and, for `--mcp`, the config) before
|
|
207
|
+
// incur parses argv; see {@link Invocation}.
|
|
208
|
+
const serve = cli.serve.bind(cli);
|
|
209
|
+
cli.serve = async (argv = process.argv.slice(2), options) => {
|
|
210
|
+
const taken = takeDisplayFlag(argv);
|
|
211
|
+
invocation.display = taken.display;
|
|
212
|
+
invocation.mcp = taken.argv.includes('--mcp');
|
|
213
|
+
invocation.mcpConfig = undefined;
|
|
214
|
+
if (invocation.mcp) {
|
|
215
|
+
try {
|
|
216
|
+
invocation.mcpConfig = loadMcpConfig(taken.argv);
|
|
217
|
+
}
|
|
218
|
+
catch (e) {
|
|
219
|
+
// A broken config must stop the server visibly, not serve without it.
|
|
220
|
+
process.stderr.write(`picopilot --mcp: ${e instanceof Error ? e.message : String(e)}\n`);
|
|
221
|
+
process.exitCode = 1;
|
|
222
|
+
return;
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
return serve(taken.argv, options);
|
|
226
|
+
};
|
|
227
|
+
// The register* helpers take the untyped Cli: the display var is read through
|
|
228
|
+
// `displayModeOf`, so they do not depend on this CLI's generics.
|
|
229
|
+
const root = cli;
|
|
230
|
+
registerVersion(root);
|
|
231
|
+
registerDoctor(root);
|
|
232
|
+
registerInit(root);
|
|
233
|
+
registerGfx(root);
|
|
234
|
+
registerTokens(root);
|
|
235
|
+
registerLint(root);
|
|
236
|
+
registerMinify(root);
|
|
237
|
+
registerVerify(root);
|
|
238
|
+
registerRun(root);
|
|
239
|
+
registerExport(root);
|
|
240
|
+
registerServe(root);
|
|
241
|
+
registerPlaytest(root);
|
|
242
|
+
registerSfx(root);
|
|
243
|
+
registerMusic(root);
|
|
244
|
+
registerAudio(root);
|
|
245
|
+
return root;
|
|
58
246
|
}
|
|
59
247
|
//# sourceMappingURL=cli.js.map
|
package/dist/cli.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,GAAG,EAAC,MAAM,OAAO,CAAC;
|
|
1
|
+
{"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"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"}
|
package/dist/commands/audio.d.ts
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
import { Cli } from 'incur';
|
|
2
|
-
import { type
|
|
2
|
+
import { type Pico8AdapterFactory } from './pico8-env.js';
|
|
3
3
|
/**
|
|
4
4
|
* Injects the PICO-8 adapter the audio commands use (defaults to the shell
|
|
5
5
|
* adapter over native `pico8 -run`). Mirrors `run`'s `Pico8AdapterFactory` seam:
|
|
6
6
|
* a test passes a fake to drive the record orchestration + the absent path
|
|
7
|
-
* WITHOUT the paid binary
|
|
7
|
+
* WITHOUT the paid binary.
|
|
8
8
|
*/
|
|
9
|
-
export type Pico8AdapterFactory
|
|
9
|
+
export type { Pico8AdapterFactory } from './pico8-env.js';
|
|
10
10
|
/**
|
|
11
11
|
* Registers the `audio` command group (`audio record`, `audio render`) on the
|
|
12
12
|
* root CLI. PICO-8-gated (ADR-0009): audio-to-WAV is a record of a running
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"audio.d.ts","sourceRoot":"","sources":["../../src/commands/audio.ts"],"names":[],"mappings":"AASA,OAAO,EAAC,GAAG,EAAI,MAAM,OAAO,CAAC;
|
|
1
|
+
{"version":3,"file":"audio.d.ts","sourceRoot":"","sources":["../../src/commands/audio.ts"],"names":[],"mappings":"AASA,OAAO,EAAC,GAAG,EAAI,MAAM,OAAO,CAAC;AAW7B,OAAO,EAKN,KAAK,mBAAmB,EAGxB,MAAM,gBAAgB,CAAC;AAExB;;;;;GAKG;AACH,YAAY,EAAC,mBAAmB,EAAC,MAAM,gBAAgB,CAAC;AAuYxD;;;;;GAKG;AACH,wBAAgB,aAAa,CAC5B,GAAG,EAAE,GAAG,CAAC,GAAG,EACZ,cAAc,GAAE,mBAA2C,GACzD,IAAI,CAEN"}
|
package/dist/commands/audio.js
CHANGED
|
@@ -2,8 +2,10 @@ import { existsSync, mkdirSync, mkdtempSync, readFileSync, writeFileSync, } from
|
|
|
2
2
|
import { tmpdir } from 'node:os';
|
|
3
3
|
import { isAbsolute, join, resolve } from 'node:path';
|
|
4
4
|
import { Cli, z } from 'incur';
|
|
5
|
-
import { buildRecordHarness, buildRenderHarness, DONE_SENTINEL, HarnessError,
|
|
6
|
-
|
|
5
|
+
import { buildRecordHarness, buildRenderHarness, DONE_SENTINEL, HarnessError, } from '../engine/pico8/index.js';
|
|
6
|
+
import { makeReadInclude } from './cart-includes.js';
|
|
7
|
+
import { createShellAdapterFactory, DISPLAY_OPTION, displayUnavailableError, PICO8_ENV, pico8NotFoundError, resolveCommandDisplay, } from './pico8-env.js';
|
|
8
|
+
const defaultAdapterFactory = createShellAdapterFactory();
|
|
7
9
|
/**
|
|
8
10
|
* The default record backstop: kill a capture that never signals after this many
|
|
9
11
|
* ms. Larger than `run`'s default because a record window is a real-time playback
|
|
@@ -11,7 +13,7 @@ const defaultAdapterFactory = (env) => new ShellPico8Adapter({ env });
|
|
|
11
13
|
*/
|
|
12
14
|
const DEFAULT_BACKSTOP_MS = 30_000;
|
|
13
15
|
/** The honest one-liner both `record` and `render` carry (ADR-0009): not offline. */
|
|
14
|
-
const HONEST_CAVEAT = 'This is a REAL-TIME recording of playback
|
|
16
|
+
const HONEST_CAVEAT = 'This is a REAL-TIME recording of playback in a -run session, NOT a deterministic offline export. Works headless: with no display, picopilot runs the session on a private virtual display (ADR-0017, --display).';
|
|
15
17
|
/** Resolves a path argument to an absolute path (relative to cwd). */
|
|
16
18
|
function resolvePath(p) {
|
|
17
19
|
return isAbsolute(p) ? p : resolve(process.cwd(), p);
|
|
@@ -33,20 +35,14 @@ function chooseWavDir(given) {
|
|
|
33
35
|
mkdirSync(dir, { recursive: true });
|
|
34
36
|
return dir;
|
|
35
37
|
}
|
|
36
|
-
/** The env schema both audio subcommands share (locates the binary
|
|
37
|
-
const AUDIO_ENV =
|
|
38
|
-
PICO8_PATH: z
|
|
39
|
-
.string()
|
|
40
|
-
.optional()
|
|
41
|
-
.describe('Explicit path to the PICO-8 binary (else `pico8` on PATH).'),
|
|
42
|
-
PATH: z.string().optional().describe('Used to locate `pico8`.'),
|
|
43
|
-
});
|
|
38
|
+
/** The env schema both audio subcommands share (locates the binary). */
|
|
39
|
+
const AUDIO_ENV = PICO8_ENV;
|
|
44
40
|
/** The structured output shape shared by `record` and `render`. */
|
|
45
41
|
const AUDIO_OUTPUT = z.object({
|
|
46
42
|
wav: z
|
|
47
43
|
.string()
|
|
48
44
|
.optional()
|
|
49
|
-
.describe('Absolute path of the recorded WAV, or omitted if no audio was captured (
|
|
45
|
+
.describe('Absolute path of the recorded WAV, or omitted if no audio was captured (see noAudioReason).'),
|
|
50
46
|
captured: z
|
|
51
47
|
.boolean()
|
|
52
48
|
.describe('Whether a non-empty WAV was captured (false = silent/empty run).'),
|
|
@@ -60,27 +56,44 @@ const AUDIO_OUTPUT = z.object({
|
|
|
60
56
|
.number()
|
|
61
57
|
.describe('The record window in seconds the capture ran for.'),
|
|
62
58
|
printh: z.string().describe('Captured stdout from the session.'),
|
|
59
|
+
display: z
|
|
60
|
+
.enum(['native', 'Xvfb', 'xvfb-run'])
|
|
61
|
+
.optional()
|
|
62
|
+
.describe('Which display the -run session used: native, or a private virtual display (Xvfb / xvfb-run).'),
|
|
63
|
+
noAudioReason: z
|
|
64
|
+
.string()
|
|
65
|
+
.optional()
|
|
66
|
+
.describe('When no WAV was captured: why (backstop fired / PICO-8 exited before the done-sentinel / empty capture).'),
|
|
67
|
+
pico8LogTail: z
|
|
68
|
+
.string()
|
|
69
|
+
.optional()
|
|
70
|
+
.describe("When no WAV was captured: the tail of PICO-8's own log.txt (load errors, SDL init failures)."),
|
|
63
71
|
});
|
|
64
|
-
/** The message a `pico8-not-found` error carries (mirrors `run`): exact remedy + needs. */
|
|
65
|
-
function pico8NotFoundMessage(notFound) {
|
|
66
|
-
return `PICO-8 is not installed. ${notFound.remedy} (needs: ${notFound.needs.join(', ')})`;
|
|
67
|
-
}
|
|
68
72
|
/**
|
|
69
|
-
* The advisory CTA when a record/render run captured NO audio
|
|
70
|
-
*
|
|
71
|
-
* hear (ADR-0009's live-tier caveat), so it is a nudge, not a hard error.
|
|
73
|
+
* The advisory CTA when a record/render run captured NO audio. The report's
|
|
74
|
+
* `noAudioReason` + `pico8LogTail` say why; this points at the next step.
|
|
72
75
|
*/
|
|
73
|
-
function noAudioCta(
|
|
76
|
+
function noAudioCta(reason) {
|
|
74
77
|
return {
|
|
75
|
-
description: `No audio was captured (${
|
|
78
|
+
description: `No audio was captured${reason !== undefined ? ` (${reason})` : ''}. Next:`,
|
|
76
79
|
commands: [
|
|
77
80
|
{
|
|
78
|
-
command: '
|
|
79
|
-
description: 'Run
|
|
81
|
+
command: 'verify',
|
|
82
|
+
description: 'Run the static gate: a cart that fails to load or errors never reaches audio_end.',
|
|
83
|
+
},
|
|
84
|
+
{
|
|
85
|
+
command: 'doctor',
|
|
86
|
+
description: 'Check PICO-8 and display capabilities on this machine.',
|
|
80
87
|
},
|
|
81
88
|
],
|
|
82
89
|
};
|
|
83
90
|
}
|
|
91
|
+
/** Maps a failed record result onto the structured `error(...)` payload. */
|
|
92
|
+
function recordFailure(what, result) {
|
|
93
|
+
return result.reason === 'display-unavailable'
|
|
94
|
+
? displayUnavailableError(what, result)
|
|
95
|
+
: pico8NotFoundError(result);
|
|
96
|
+
}
|
|
84
97
|
/** Shapes an adapter record report into the structured output object. */
|
|
85
98
|
function recordOutput(report, harness) {
|
|
86
99
|
return {
|
|
@@ -90,6 +103,13 @@ function recordOutput(report, harness) {
|
|
|
90
103
|
target: harness.description,
|
|
91
104
|
seconds: harness.seconds,
|
|
92
105
|
printh: report.printh,
|
|
106
|
+
...(report.display !== undefined ? { display: report.display } : {}),
|
|
107
|
+
...(report.noWavReason !== undefined
|
|
108
|
+
? { noAudioReason: report.noWavReason }
|
|
109
|
+
: {}),
|
|
110
|
+
...(report.pico8LogTail !== undefined
|
|
111
|
+
? { pico8LogTail: report.pico8LogTail }
|
|
112
|
+
: {}),
|
|
93
113
|
};
|
|
94
114
|
}
|
|
95
115
|
/**
|
|
@@ -100,7 +120,7 @@ function recordOutput(report, harness) {
|
|
|
100
120
|
*/
|
|
101
121
|
function buildAudioGroup(adapterFactory) {
|
|
102
122
|
const audio = Cli.create('audio', {
|
|
103
|
-
description: 'Get a WAV out of a cart by RECORDING a running session (ADR-0009). PICO-8 has no working offline WAV export, so both commands are REAL-TIME recordings
|
|
123
|
+
description: 'Get a WAV out of a cart by RECORDING a running session (ADR-0009). PICO-8 has no working offline WAV export, so both commands are REAL-TIME recordings of a -run session, NOT deterministic offline exports. They work headless: with no display, picopilot runs the session on a private virtual display (ADR-0017). Requires PICO-8.',
|
|
104
124
|
});
|
|
105
125
|
// --- audio record <cart> ---------------------------------------------------
|
|
106
126
|
audio.command('record', {
|
|
@@ -131,6 +151,7 @@ function buildAudioGroup(adapterFactory) {
|
|
|
131
151
|
.positive()
|
|
132
152
|
.default(DEFAULT_BACKSTOP_MS)
|
|
133
153
|
.describe('Safety backstop: kill PICO-8 after this many ms if it never signals.'),
|
|
154
|
+
display: DISPLAY_OPTION,
|
|
134
155
|
}),
|
|
135
156
|
env: AUDIO_ENV,
|
|
136
157
|
output: AUDIO_OUTPUT,
|
|
@@ -142,7 +163,7 @@ function buildAudioGroup(adapterFactory) {
|
|
|
142
163
|
options: { seconds: 4 },
|
|
143
164
|
},
|
|
144
165
|
],
|
|
145
|
-
async run({ args, options, env, error, ok }) {
|
|
166
|
+
async run({ args, options, env, error, ok, var: vars }) {
|
|
146
167
|
const cartPath = resolvePath(args.cart);
|
|
147
168
|
if (!existsSync(cartPath)) {
|
|
148
169
|
return error({
|
|
@@ -153,9 +174,12 @@ function buildAudioGroup(adapterFactory) {
|
|
|
153
174
|
}
|
|
154
175
|
let harness;
|
|
155
176
|
try {
|
|
177
|
+
// `#include`s are inlined against the SOURCE cart's folder: the harness
|
|
178
|
+
// runs from the isolated wavDir, where `main.lua` does not exist.
|
|
156
179
|
harness = buildRecordHarness(readFileSync(cartPath, 'utf8'), {
|
|
157
180
|
seconds: options.seconds,
|
|
158
181
|
sentinel: options.sentinel,
|
|
182
|
+
readInclude: makeReadInclude(cartPath),
|
|
159
183
|
});
|
|
160
184
|
}
|
|
161
185
|
catch (e) {
|
|
@@ -169,7 +193,12 @@ function buildAudioGroup(adapterFactory) {
|
|
|
169
193
|
const wavDir = chooseWavDir(options.wavDir);
|
|
170
194
|
const harnessCart = join(wavDir, 'record-harness.p8');
|
|
171
195
|
writeFileSync(harnessCart, harness.cartText);
|
|
172
|
-
const
|
|
196
|
+
const display = resolveCommandDisplay(options.display, vars);
|
|
197
|
+
if (!display.ok)
|
|
198
|
+
return error(display.error);
|
|
199
|
+
const adapter = adapterFactory(env, {
|
|
200
|
+
display: display.mode,
|
|
201
|
+
});
|
|
173
202
|
const result = await adapter.record({
|
|
174
203
|
cartPath: harnessCart,
|
|
175
204
|
wavDir,
|
|
@@ -177,15 +206,10 @@ function buildAudioGroup(adapterFactory) {
|
|
|
177
206
|
sentinel: options.sentinel,
|
|
178
207
|
backstopMs: options.backstopMs,
|
|
179
208
|
});
|
|
180
|
-
if (!result.ok)
|
|
181
|
-
return error(
|
|
182
|
-
code: 'pico8-not-found',
|
|
183
|
-
message: pico8NotFoundMessage(result),
|
|
184
|
-
exitCode: 1,
|
|
185
|
-
});
|
|
186
|
-
}
|
|
209
|
+
if (!result.ok)
|
|
210
|
+
return error(recordFailure('audio record', result));
|
|
187
211
|
const out = recordOutput(result.value, harness);
|
|
188
|
-
return ok(out, out.captured ? undefined : { cta: noAudioCta(
|
|
212
|
+
return ok(out, out.captured ? undefined : { cta: noAudioCta(out.noAudioReason) });
|
|
189
213
|
},
|
|
190
214
|
});
|
|
191
215
|
// --- audio render ----------------------------------------------------------
|
|
@@ -231,6 +255,7 @@ function buildAudioGroup(adapterFactory) {
|
|
|
231
255
|
.positive()
|
|
232
256
|
.default(DEFAULT_BACKSTOP_MS)
|
|
233
257
|
.describe('Safety backstop: kill PICO-8 after this many ms if it never signals.'),
|
|
258
|
+
display: DISPLAY_OPTION,
|
|
234
259
|
}),
|
|
235
260
|
env: AUDIO_ENV,
|
|
236
261
|
output: AUDIO_OUTPUT,
|
|
@@ -243,7 +268,7 @@ function buildAudioGroup(adapterFactory) {
|
|
|
243
268
|
options: { pattern: 2, seconds: 6 },
|
|
244
269
|
},
|
|
245
270
|
],
|
|
246
|
-
async run({ args, options, env, error, ok }) {
|
|
271
|
+
async run({ args, options, env, error, ok, var: vars }) {
|
|
247
272
|
if (options.sfx !== undefined && options.pattern !== undefined) {
|
|
248
273
|
return error({
|
|
249
274
|
code: 'ambiguous-target',
|
|
@@ -282,7 +307,12 @@ function buildAudioGroup(adapterFactory) {
|
|
|
282
307
|
const wavDir = chooseWavDir(options.wavDir);
|
|
283
308
|
const harnessCart = join(wavDir, 'render-harness.p8');
|
|
284
309
|
writeFileSync(harnessCart, harness.cartText);
|
|
285
|
-
const
|
|
310
|
+
const display = resolveCommandDisplay(options.display, vars);
|
|
311
|
+
if (!display.ok)
|
|
312
|
+
return error(display.error);
|
|
313
|
+
const adapter = adapterFactory(env, {
|
|
314
|
+
display: display.mode,
|
|
315
|
+
});
|
|
286
316
|
const result = await adapter.record({
|
|
287
317
|
cartPath: harnessCart,
|
|
288
318
|
wavDir,
|
|
@@ -290,15 +320,10 @@ function buildAudioGroup(adapterFactory) {
|
|
|
290
320
|
sentinel: options.sentinel,
|
|
291
321
|
backstopMs: options.backstopMs,
|
|
292
322
|
});
|
|
293
|
-
if (!result.ok)
|
|
294
|
-
return error(
|
|
295
|
-
code: 'pico8-not-found',
|
|
296
|
-
message: pico8NotFoundMessage(result),
|
|
297
|
-
exitCode: 1,
|
|
298
|
-
});
|
|
299
|
-
}
|
|
323
|
+
if (!result.ok)
|
|
324
|
+
return error(recordFailure('audio render', result));
|
|
300
325
|
const out = recordOutput(result.value, harness);
|
|
301
|
-
return ok(out, out.captured ? undefined : { cta: noAudioCta(
|
|
326
|
+
return ok(out, out.captured ? undefined : { cta: noAudioCta(out.noAudioReason) });
|
|
302
327
|
},
|
|
303
328
|
});
|
|
304
329
|
return audio;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"audio.js","sourceRoot":"","sources":["../../src/commands/audio.ts"],"names":[],"mappings":"AAAA,OAAO,EACN,UAAU,EACV,SAAS,EACT,WAAW,EACX,YAAY,EACZ,aAAa,GACb,MAAM,SAAS,CAAC;AACjB,OAAO,EAAC,MAAM,EAAC,MAAM,SAAS,CAAC;AAC/B,OAAO,EAAC,UAAU,EAAE,IAAI,EAAE,OAAO,EAAC,MAAM,WAAW,CAAC;AACpD,OAAO,EAAC,GAAG,EAAE,CAAC,EAAC,MAAM,OAAO,CAAC;AAE7B,OAAO,EACN,kBAAkB,EAClB,kBAAkB,EAClB,aAAa,EACb,YAAY,
|
|
1
|
+
{"version":3,"file":"audio.js","sourceRoot":"","sources":["../../src/commands/audio.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { type Cli } from 'incur';
|
|
2
|
+
import { type Pico8AdapterFactory } from './pico8-env.js';
|
|
3
|
+
import { type ShrinkoAdapterFactory } from './shrinko-env.js';
|
|
4
|
+
/** Dependencies for {@link registerDoctor}, injectable for tests. */
|
|
5
|
+
export interface DoctorDeps {
|
|
6
|
+
readonly pico8?: Pico8AdapterFactory;
|
|
7
|
+
readonly shrinko?: ShrinkoAdapterFactory;
|
|
8
|
+
/** The parent environment (defaults to `process.env`): DISPLAY etc. are read from it. */
|
|
9
|
+
readonly parentEnv?: NodeJS.ProcessEnv;
|
|
10
|
+
/** Executable lookup (defaults to a PATH search). */
|
|
11
|
+
readonly find?: (name: string, env: NodeJS.ProcessEnv) => string | undefined;
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* Registers `picopilot doctor`: what can THIS machine do? It reports whether
|
|
15
|
+
* PICO-8 is found (and runs headless, with its version), whether shrinko8 is
|
|
16
|
+
* found, how a PICO-8 `-run` session would get a display (native, a private
|
|
17
|
+
* virtual one via Xvfb, or none), and therefore which commands are available.
|
|
18
|
+
* An agent calls it first instead of discovering limits by failing. It never
|
|
19
|
+
* fails itself: a missing dependency is data in the report.
|
|
20
|
+
*/
|
|
21
|
+
export declare function registerDoctor(cli: Cli.Cli, deps?: DoctorDeps): void;
|
|
22
|
+
//# sourceMappingURL=doctor.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"doctor.d.ts","sourceRoot":"","sources":["../../src/commands/doctor.ts"],"names":[],"mappings":"AAGA,OAAO,EAAC,KAAK,GAAG,EAAI,MAAM,OAAO,CAAC;AAYlC,OAAO,EAKN,KAAK,mBAAmB,EACxB,MAAM,gBAAgB,CAAC;AACxB,OAAO,EAEN,KAAK,qBAAqB,EAC1B,MAAM,kBAAkB,CAAC;AA6D1B,qEAAqE;AACrE,MAAM,WAAW,UAAU;IAC1B,QAAQ,CAAC,KAAK,CAAC,EAAE,mBAAmB,CAAC;IACrC,QAAQ,CAAC,OAAO,CAAC,EAAE,qBAAqB,CAAC;IACzC,yFAAyF;IACzF,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAC,UAAU,CAAC;IACvC,qDAAqD;IACrD,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,CAAC,UAAU,KAAK,MAAM,GAAG,SAAS,CAAC;CAC7E;AAED;;;;;;;GAOG;AACH,wBAAgB,cAAc,CAAC,GAAG,EAAE,GAAG,CAAC,GAAG,EAAE,IAAI,GAAE,UAAe,GAAG,IAAI,CAmLxE"}
|