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,69 @@
|
|
|
1
|
+
import { type CountReport, type LintReport, type MinifyReport, type ShrinkoAdapter, type ShrinkoResult } from './adapter.js';
|
|
2
|
+
/**
|
|
3
|
+
* The result of running one child process: its exit `code` (null when killed by
|
|
4
|
+
* a signal), captured `stdout`/`stderr`, and `spawnError` set when the binary
|
|
5
|
+
* could not be launched AT ALL (ENOENT etc.) rather than launched-and-exited.
|
|
6
|
+
* `spawnError` is how the shell adapter distinguishes "shrinko is not installed"
|
|
7
|
+
* from "shrinko ran and failed".
|
|
8
|
+
*/
|
|
9
|
+
export interface ChildResult {
|
|
10
|
+
readonly code: number | null;
|
|
11
|
+
readonly stdout: string;
|
|
12
|
+
readonly stderr: string;
|
|
13
|
+
readonly spawnError: NodeJS.ErrnoException | undefined;
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* The child-process seam. The real implementation shells out with the CALLER's
|
|
17
|
+
* `env` (so a test overrides the child's `PATH` and nothing else). Tests inject
|
|
18
|
+
* a stub runner to simulate shrinko present/absent WITHOUT ever requiring the
|
|
19
|
+
* real binary, and to assert exactly what argv/env the adapter would spawn.
|
|
20
|
+
*/
|
|
21
|
+
export type ChildRunner = (file: string, args: string[], env: NodeJS.ProcessEnv) => Promise<ChildResult>;
|
|
22
|
+
/**
|
|
23
|
+
* The default {@link ChildRunner}: an `execFile` that captures stdout/stderr and
|
|
24
|
+
* NEVER rejects. A failed spawn (ENOENT) becomes `spawnError`; a nonzero exit
|
|
25
|
+
* becomes a `code`, so both outcomes are data the adapter maps to a structured
|
|
26
|
+
* result. The child inherits ONLY the `env` it is handed (the command layer
|
|
27
|
+
* passes the incur-resolved env, whose `PATH` a test can override) so there is
|
|
28
|
+
* no ambient-environment leak.
|
|
29
|
+
*/
|
|
30
|
+
export declare const execFileRunner: ChildRunner;
|
|
31
|
+
/** Options for {@link ShellShrinkoAdapter}. */
|
|
32
|
+
export interface ShellShrinkoOptions {
|
|
33
|
+
/**
|
|
34
|
+
* The environment handed to the child process. The command layer passes the
|
|
35
|
+
* incur-resolved env here; its `PATH` is the isolation lever a test overrides
|
|
36
|
+
* (an empty/`PATH`-less env makes every invocation ENOENT ⇒ shrinko-absent).
|
|
37
|
+
*/
|
|
38
|
+
readonly env: NodeJS.ProcessEnv;
|
|
39
|
+
/** The child runner (defaults to {@link execFileRunner}); tests inject a stub. */
|
|
40
|
+
readonly run?: ChildRunner;
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* The v1 {@link ShrinkoAdapter}: shells out to a user-installed Python
|
|
44
|
+
* `shrinko8` (ADR-0001). It is the ONLY place that knows shrinko is an external
|
|
45
|
+
* process; every command talks to the {@link ShrinkoAdapter} interface, so a
|
|
46
|
+
* future native-TS adapter replaces this class without touching a command.
|
|
47
|
+
*
|
|
48
|
+
* Presence detection and invocation are the SAME act: the adapter tries each
|
|
49
|
+
* {@link SHRINKO_INVOCATIONS} candidate and uses the first that spawns. If every
|
|
50
|
+
* candidate ENOENTs, shrinko is absent and the method returns the structured
|
|
51
|
+
* {@link shrinkoNotFound} value (never a throw, never a hollow success).
|
|
52
|
+
*/
|
|
53
|
+
export declare class ShellShrinkoAdapter implements ShrinkoAdapter {
|
|
54
|
+
private readonly env;
|
|
55
|
+
private readonly run;
|
|
56
|
+
constructor(options: ShellShrinkoOptions);
|
|
57
|
+
count(cartPath: string): Promise<ShrinkoResult<CountReport>>;
|
|
58
|
+
lint(cartPath: string): Promise<ShrinkoResult<LintReport>>;
|
|
59
|
+
minify(cartPath: string, outPath: string): Promise<ShrinkoResult<MinifyReport>>;
|
|
60
|
+
exportSpritesheet(cartPath: string, pngPath: string): Promise<ShrinkoResult<void>>;
|
|
61
|
+
importSpritesheet(srcCartPath: string, pngPath: string, outCartPath: string): Promise<ShrinkoResult<void>>;
|
|
62
|
+
/**
|
|
63
|
+
* Runs shrinko with the given trailing args, trying each invocation candidate
|
|
64
|
+
* until one SPAWNS. Returns the {@link ChildResult} of the first candidate
|
|
65
|
+
* that launched, or `undefined` when every candidate ENOENTs (shrinko absent).
|
|
66
|
+
*/
|
|
67
|
+
private invoke;
|
|
68
|
+
}
|
|
69
|
+
//# sourceMappingURL=shell.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"shell.d.ts","sourceRoot":"","sources":["../../../src/engine/shrinko/shell.ts"],"names":[],"mappings":"AAEA,OAAO,EACN,KAAK,WAAW,EAChB,KAAK,UAAU,EACf,KAAK,YAAY,EAGjB,KAAK,cAAc,EACnB,KAAK,aAAa,EAElB,MAAM,cAAc,CAAC;AAEtB;;;;;;GAMG;AACH,MAAM,WAAW,WAAW;IAC3B,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC,cAAc,GAAG,SAAS,CAAC;CACvD;AAED;;;;;GAKG;AACH,MAAM,MAAM,WAAW,GAAG,CACzB,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,MAAM,EAAE,EACd,GAAG,EAAE,MAAM,CAAC,UAAU,KAClB,OAAO,CAAC,WAAW,CAAC,CAAC;AAE1B;;;;;;;GAOG;AACH,eAAO,MAAM,cAAc,EAAE,WAmB1B,CAAC;AAcJ,+CAA+C;AAC/C,MAAM,WAAW,mBAAmB;IACnC;;;;OAIG;IACH,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC,UAAU,CAAC;IAChC,kFAAkF;IAClF,QAAQ,CAAC,GAAG,CAAC,EAAE,WAAW,CAAC;CAC3B;AAED;;;;;;;;;;GAUG;AACH,qBAAa,mBAAoB,YAAW,cAAc;IACzD,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAoB;IACxC,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAc;gBAEtB,OAAO,EAAE,mBAAmB;IAKlC,KAAK,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,aAAa,CAAC,WAAW,CAAC,CAAC;IAa5D,IAAI,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,aAAa,CAAC,UAAU,CAAC,CAAC;IAe1D,MAAM,CACX,QAAQ,EAAE,MAAM,EAChB,OAAO,EAAE,MAAM,GACb,OAAO,CAAC,aAAa,CAAC,YAAY,CAAC,CAAC;IAgCjC,iBAAiB,CACtB,QAAQ,EAAE,MAAM,EAChB,OAAO,EAAE,MAAM,GACb,OAAO,CAAC,aAAa,CAAC,IAAI,CAAC,CAAC;IAOzB,iBAAiB,CACtB,WAAW,EAAE,MAAM,EACnB,OAAO,EAAE,MAAM,EACf,WAAW,EAAE,MAAM,GACjB,OAAO,CAAC,aAAa,CAAC,IAAI,CAAC,CAAC;IAgB/B;;;;OAIG;YACW,MAAM;CAapB"}
|
|
@@ -0,0 +1,156 @@
|
|
|
1
|
+
import { execFile } from 'node:child_process';
|
|
2
|
+
import { parseCount, parseLint, shrinkoNotFound, } from './adapter.js';
|
|
3
|
+
/**
|
|
4
|
+
* The default {@link ChildRunner}: an `execFile` that captures stdout/stderr and
|
|
5
|
+
* NEVER rejects. A failed spawn (ENOENT) becomes `spawnError`; a nonzero exit
|
|
6
|
+
* becomes a `code`, so both outcomes are data the adapter maps to a structured
|
|
7
|
+
* result. The child inherits ONLY the `env` it is handed (the command layer
|
|
8
|
+
* passes the incur-resolved env, whose `PATH` a test can override) so there is
|
|
9
|
+
* no ambient-environment leak.
|
|
10
|
+
*/
|
|
11
|
+
export const execFileRunner = (file, args, env) => new Promise((resolve) => {
|
|
12
|
+
execFile(file, args, { env, encoding: 'utf8' }, (error, stdout, stderr) => {
|
|
13
|
+
const err = error;
|
|
14
|
+
resolve({
|
|
15
|
+
// `execFile` sets error.code to the string 'ENOENT' on spawn failure and
|
|
16
|
+
// to the numeric exit code on a nonzero exit; separate the two.
|
|
17
|
+
code: err !== null && typeof err.code === 'number'
|
|
18
|
+
? err.code
|
|
19
|
+
: err === null
|
|
20
|
+
? 0
|
|
21
|
+
: null,
|
|
22
|
+
stdout,
|
|
23
|
+
stderr,
|
|
24
|
+
spawnError: err !== null && typeof err.code === 'string' ? err : undefined,
|
|
25
|
+
});
|
|
26
|
+
});
|
|
27
|
+
});
|
|
28
|
+
/**
|
|
29
|
+
* The candidate ways to invoke shrinko, tried in order. First the `shrinko8`
|
|
30
|
+
* entry-point on `PATH`, then `python -m shrinko8` / `python3 -m shrinko8` as
|
|
31
|
+
* fallbacks (the module is `shrinko8`; the pip package is `shrinko`). The first
|
|
32
|
+
* candidate that SPAWNS (does not ENOENT) is the one shrinko is reached through.
|
|
33
|
+
*/
|
|
34
|
+
const SHRINKO_INVOCATIONS = [
|
|
35
|
+
['shrinko8'],
|
|
36
|
+
['python', '-m', 'shrinko8'],
|
|
37
|
+
['python3', '-m', 'shrinko8'],
|
|
38
|
+
];
|
|
39
|
+
/**
|
|
40
|
+
* The v1 {@link ShrinkoAdapter}: shells out to a user-installed Python
|
|
41
|
+
* `shrinko8` (ADR-0001). It is the ONLY place that knows shrinko is an external
|
|
42
|
+
* process; every command talks to the {@link ShrinkoAdapter} interface, so a
|
|
43
|
+
* future native-TS adapter replaces this class without touching a command.
|
|
44
|
+
*
|
|
45
|
+
* Presence detection and invocation are the SAME act: the adapter tries each
|
|
46
|
+
* {@link SHRINKO_INVOCATIONS} candidate and uses the first that spawns. If every
|
|
47
|
+
* candidate ENOENTs, shrinko is absent and the method returns the structured
|
|
48
|
+
* {@link shrinkoNotFound} value (never a throw, never a hollow success).
|
|
49
|
+
*/
|
|
50
|
+
export class ShellShrinkoAdapter {
|
|
51
|
+
env;
|
|
52
|
+
run;
|
|
53
|
+
constructor(options) {
|
|
54
|
+
this.env = options.env;
|
|
55
|
+
this.run = options.run ?? execFileRunner;
|
|
56
|
+
}
|
|
57
|
+
async count(cartPath) {
|
|
58
|
+
const outcome = await this.invoke([cartPath, '--count']);
|
|
59
|
+
if (outcome === undefined) {
|
|
60
|
+
return shrinkoNotFound();
|
|
61
|
+
}
|
|
62
|
+
// shrinko prints the count report; some builds send it to stderr, so parse
|
|
63
|
+
// the combined stream. parseCount throws on unparseable output (ShrinkoParseError).
|
|
64
|
+
return {
|
|
65
|
+
ok: true,
|
|
66
|
+
value: parseCount(`${outcome.stdout}\n${outcome.stderr}`),
|
|
67
|
+
};
|
|
68
|
+
}
|
|
69
|
+
async lint(cartPath) {
|
|
70
|
+
// `-l` lints; it exits nonzero (2) WHEN it finds warnings, which is a normal
|
|
71
|
+
// result (findings are data), NOT a spawn failure. Only a spawnError means
|
|
72
|
+
// shrinko is absent, so we key absence off `outcome === undefined`, and parse
|
|
73
|
+
// the warnings regardless of the (0-or-2) exit code.
|
|
74
|
+
const outcome = await this.invoke([cartPath, '-l']);
|
|
75
|
+
if (outcome === undefined) {
|
|
76
|
+
return shrinkoNotFound();
|
|
77
|
+
}
|
|
78
|
+
return {
|
|
79
|
+
ok: true,
|
|
80
|
+
value: parseLint(`${outcome.stdout}\n${outcome.stderr}`),
|
|
81
|
+
};
|
|
82
|
+
}
|
|
83
|
+
async minify(cartPath, outPath) {
|
|
84
|
+
// Count the source first (the "before"): if shrinko is absent, this returns
|
|
85
|
+
// the not-found value and we never write anything.
|
|
86
|
+
const before = await this.count(cartPath);
|
|
87
|
+
if (!before.ok)
|
|
88
|
+
return before;
|
|
89
|
+
// Minify SAFE-only (ADR-0007): the three safe-only knobs keep rename/reorder/
|
|
90
|
+
// builtins behaviour-preserving. Output goes to a SEPARATE cart (outPath).
|
|
91
|
+
const out = await this.invoke([
|
|
92
|
+
cartPath,
|
|
93
|
+
'-m',
|
|
94
|
+
'--rename-safe-only',
|
|
95
|
+
'--reorder-safe-only',
|
|
96
|
+
'--builtins-safe-only',
|
|
97
|
+
outPath,
|
|
98
|
+
]);
|
|
99
|
+
if (out === undefined)
|
|
100
|
+
return shrinkoNotFound();
|
|
101
|
+
// Count the artifact (the "after"). It exists now, so this is a normal count.
|
|
102
|
+
const after = await this.count(outPath);
|
|
103
|
+
if (!after.ok)
|
|
104
|
+
return after;
|
|
105
|
+
return {
|
|
106
|
+
ok: true,
|
|
107
|
+
value: {
|
|
108
|
+
beforeTokens: before.value.tokens,
|
|
109
|
+
afterTokens: after.value.tokens,
|
|
110
|
+
outPath,
|
|
111
|
+
},
|
|
112
|
+
};
|
|
113
|
+
}
|
|
114
|
+
async exportSpritesheet(cartPath, pngPath) {
|
|
115
|
+
// `<cart> <out.png> -f spritesheet` writes the 128x128 spritesheet PNG.
|
|
116
|
+
const outcome = await this.invoke([cartPath, pngPath, '-f', 'spritesheet']);
|
|
117
|
+
if (outcome === undefined)
|
|
118
|
+
return shrinkoNotFound();
|
|
119
|
+
return { ok: true, value: undefined };
|
|
120
|
+
}
|
|
121
|
+
async importSpritesheet(srcCartPath, pngPath, outCartPath) {
|
|
122
|
+
// `<cart> <out.p8> --merge <png> gfx spritesheet` merges ONLY the gfx section
|
|
123
|
+
// from the PNG into the source cart, preserving code/map/sfx/music. (A plain
|
|
124
|
+
// `-F spritesheet` would drop everything but gfx, wiping the user's code.)
|
|
125
|
+
const outcome = await this.invoke([
|
|
126
|
+
srcCartPath,
|
|
127
|
+
outCartPath,
|
|
128
|
+
'--merge',
|
|
129
|
+
pngPath,
|
|
130
|
+
'gfx',
|
|
131
|
+
'spritesheet',
|
|
132
|
+
]);
|
|
133
|
+
if (outcome === undefined)
|
|
134
|
+
return shrinkoNotFound();
|
|
135
|
+
return { ok: true, value: undefined };
|
|
136
|
+
}
|
|
137
|
+
/**
|
|
138
|
+
* Runs shrinko with the given trailing args, trying each invocation candidate
|
|
139
|
+
* until one SPAWNS. Returns the {@link ChildResult} of the first candidate
|
|
140
|
+
* that launched, or `undefined` when every candidate ENOENTs (shrinko absent).
|
|
141
|
+
*/
|
|
142
|
+
async invoke(args) {
|
|
143
|
+
for (const inv of SHRINKO_INVOCATIONS) {
|
|
144
|
+
const [file, ...prefix] = inv;
|
|
145
|
+
const result = await this.run(file, [...prefix, ...args], this.env);
|
|
146
|
+
if (result.spawnError === undefined) {
|
|
147
|
+
return result;
|
|
148
|
+
}
|
|
149
|
+
// ENOENT on this candidate: fall through to the next. Any other spawn
|
|
150
|
+
// error (EACCES etc.) also falls through, so a broken candidate never
|
|
151
|
+
// masks a working one.
|
|
152
|
+
}
|
|
153
|
+
return undefined;
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
//# sourceMappingURL=shell.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"shell.js","sourceRoot":"","sources":["../../../src/engine/shrinko/shell.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,QAAQ,EAAC,MAAM,oBAAoB,CAAC;AAE5C,OAAO,EAIN,UAAU,EACV,SAAS,EAGT,eAAe,GACf,MAAM,cAAc,CAAC;AA4BtB;;;;;;;GAOG;AACH,MAAM,CAAC,MAAM,cAAc,GAAgB,CAAC,IAAI,EAAE,IAAI,EAAE,GAAG,EAAE,EAAE,CAC9D,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE;IACvB,QAAQ,CAAC,IAAI,EAAE,IAAI,EAAE,EAAC,GAAG,EAAE,QAAQ,EAAE,MAAM,EAAC,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,EAAE;QACvE,MAAM,GAAG,GAAG,KAAqC,CAAC;QAClD,OAAO,CAAC;YACP,yEAAyE;YACzE,gEAAgE;YAChE,IAAI,EACH,GAAG,KAAK,IAAI,IAAI,OAAO,GAAG,CAAC,IAAI,KAAK,QAAQ;gBAC3C,CAAC,CAAC,GAAG,CAAC,IAAI;gBACV,CAAC,CAAC,GAAG,KAAK,IAAI;oBACb,CAAC,CAAC,CAAC;oBACH,CAAC,CAAC,IAAI;YACT,MAAM;YACN,MAAM;YACN,UAAU,EACT,GAAG,KAAK,IAAI,IAAI,OAAO,GAAG,CAAC,IAAI,KAAK,QAAQ,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,SAAS;SAC/D,CAAC,CAAC;IACJ,CAAC,CAAC,CAAC;AACJ,CAAC,CAAC,CAAC;AAEJ;;;;;GAKG;AACH,MAAM,mBAAmB,GAAmC;IAC3D,CAAC,UAAU,CAAC;IACZ,CAAC,QAAQ,EAAE,IAAI,EAAE,UAAU,CAAC;IAC5B,CAAC,SAAS,EAAE,IAAI,EAAE,UAAU,CAAC;CAC7B,CAAC;AAcF;;;;;;;;;;GAUG;AACH,MAAM,OAAO,mBAAmB;IACd,GAAG,CAAoB;IACvB,GAAG,CAAc;IAElC,YAAY,OAA4B;QACvC,IAAI,CAAC,GAAG,GAAG,OAAO,CAAC,GAAG,CAAC;QACvB,IAAI,CAAC,GAAG,GAAG,OAAO,CAAC,GAAG,IAAI,cAAc,CAAC;IAC1C,CAAC;IAED,KAAK,CAAC,KAAK,CAAC,QAAgB;QAC3B,MAAM,OAAO,GAAG,MAAM,IAAI,CAAC,MAAM,CAAC,CAAC,QAAQ,EAAE,SAAS,CAAC,CAAC,CAAC;QACzD,IAAI,OAAO,KAAK,SAAS,EAAE,CAAC;YAC3B,OAAO,eAAe,EAAE,CAAC;QAC1B,CAAC;QACD,2EAA2E;QAC3E,oFAAoF;QACpF,OAAO;YACN,EAAE,EAAE,IAAI;YACR,KAAK,EAAE,UAAU,CAAC,GAAG,OAAO,CAAC,MAAM,KAAK,OAAO,CAAC,MAAM,EAAE,CAAC;SACzD,CAAC;IACH,CAAC;IAED,KAAK,CAAC,IAAI,CAAC,QAAgB;QAC1B,6EAA6E;QAC7E,2EAA2E;QAC3E,8EAA8E;QAC9E,qDAAqD;QACrD,MAAM,OAAO,GAAG,MAAM,IAAI,CAAC,MAAM,CAAC,CAAC,QAAQ,EAAE,IAAI,CAAC,CAAC,CAAC;QACpD,IAAI,OAAO,KAAK,SAAS,EAAE,CAAC;YAC3B,OAAO,eAAe,EAAE,CAAC;QAC1B,CAAC;QACD,OAAO;YACN,EAAE,EAAE,IAAI;YACR,KAAK,EAAE,SAAS,CAAC,GAAG,OAAO,CAAC,MAAM,KAAK,OAAO,CAAC,MAAM,EAAE,CAAC;SACxD,CAAC;IACH,CAAC;IAED,KAAK,CAAC,MAAM,CACX,QAAgB,EAChB,OAAe;QAEf,4EAA4E;QAC5E,mDAAmD;QACnD,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC;QAC1C,IAAI,CAAC,MAAM,CAAC,EAAE;YAAE,OAAO,MAAM,CAAC;QAE9B,8EAA8E;QAC9E,2EAA2E;QAC3E,MAAM,GAAG,GAAG,MAAM,IAAI,CAAC,MAAM,CAAC;YAC7B,QAAQ;YACR,IAAI;YACJ,oBAAoB;YACpB,qBAAqB;YACrB,sBAAsB;YACtB,OAAO;SACP,CAAC,CAAC;QACH,IAAI,GAAG,KAAK,SAAS;YAAE,OAAO,eAAe,EAAE,CAAC;QAEhD,8EAA8E;QAC9E,MAAM,KAAK,GAAG,MAAM,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;QACxC,IAAI,CAAC,KAAK,CAAC,EAAE;YAAE,OAAO,KAAK,CAAC;QAE5B,OAAO;YACN,EAAE,EAAE,IAAI;YACR,KAAK,EAAE;gBACN,YAAY,EAAE,MAAM,CAAC,KAAK,CAAC,MAAM;gBACjC,WAAW,EAAE,KAAK,CAAC,KAAK,CAAC,MAAM;gBAC/B,OAAO;aACP;SACD,CAAC;IACH,CAAC;IAED,KAAK,CAAC,iBAAiB,CACtB,QAAgB,EAChB,OAAe;QAEf,wEAAwE;QACxE,MAAM,OAAO,GAAG,MAAM,IAAI,CAAC,MAAM,CAAC,CAAC,QAAQ,EAAE,OAAO,EAAE,IAAI,EAAE,aAAa,CAAC,CAAC,CAAC;QAC5E,IAAI,OAAO,KAAK,SAAS;YAAE,OAAO,eAAe,EAAE,CAAC;QACpD,OAAO,EAAC,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE,SAAS,EAAC,CAAC;IACrC,CAAC;IAED,KAAK,CAAC,iBAAiB,CACtB,WAAmB,EACnB,OAAe,EACf,WAAmB;QAEnB,8EAA8E;QAC9E,6EAA6E;QAC7E,2EAA2E;QAC3E,MAAM,OAAO,GAAG,MAAM,IAAI,CAAC,MAAM,CAAC;YACjC,WAAW;YACX,WAAW;YACX,SAAS;YACT,OAAO;YACP,KAAK;YACL,aAAa;SACb,CAAC,CAAC;QACH,IAAI,OAAO,KAAK,SAAS;YAAE,OAAO,eAAe,EAAE,CAAC;QACpD,OAAO,EAAC,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE,SAAS,EAAC,CAAC;IACrC,CAAC;IAED;;;;OAIG;IACK,KAAK,CAAC,MAAM,CAAC,IAAc;QAClC,KAAK,MAAM,GAAG,IAAI,mBAAmB,EAAE,CAAC;YACvC,MAAM,CAAC,IAAI,EAAE,GAAG,MAAM,CAAC,GAAG,GAA4B,CAAC;YACvD,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,GAAG,CAAC,IAAI,EAAE,CAAC,GAAG,MAAM,EAAE,GAAG,IAAI,CAAC,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC;YACpE,IAAI,MAAM,CAAC,UAAU,KAAK,SAAS,EAAE,CAAC;gBACrC,OAAO,MAAM,CAAC;YACf,CAAC;YACD,sEAAsE;YACtE,sEAAsE;YACtE,uBAAuB;QACxB,CAAC;QACD,OAAO,SAAS,CAAC;IAClB,CAAC;CACD"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The skills-install engine behind `picopilot init --install-skills`, the one
|
|
3
|
+
* picopilot path that writes to a shared/global location. Every install-target
|
|
4
|
+
* knob is a parameter here so tests redirect it to a temp dir and the real agent
|
|
5
|
+
* skill dirs stay byte-untouched. See `skills.ts` for the isolation contract.
|
|
6
|
+
*/
|
|
7
|
+
export { installSkills, type InstallSkillsOptions, type InstallSkillsResult, SKILL_NAMES, skillsSourceDir, type WiredAgent, } from './skills.js';
|
|
8
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/engine/skills/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,OAAO,EACN,aAAa,EACb,KAAK,oBAAoB,EACzB,KAAK,mBAAmB,EACxB,WAAW,EACX,eAAe,EACf,KAAK,UAAU,GACf,MAAM,aAAa,CAAC"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The skills-install engine behind `picopilot init --install-skills`, the one
|
|
3
|
+
* picopilot path that writes to a shared/global location. Every install-target
|
|
4
|
+
* knob is a parameter here so tests redirect it to a temp dir and the real agent
|
|
5
|
+
* skill dirs stay byte-untouched. See `skills.ts` for the isolation contract.
|
|
6
|
+
*/
|
|
7
|
+
export { installSkills, SKILL_NAMES, skillsSourceDir, } from './skills.js';
|
|
8
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/engine/skills/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,OAAO,EACN,aAAa,EAGb,WAAW,EACX,eAAe,GAEf,MAAM,aAAa,CAAC"}
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
import { Cli } from 'incur';
|
|
2
|
+
/**
|
|
3
|
+
* The engine behind `picopilot init --install-skills`: the ONE picopilot path
|
|
4
|
+
* that writes to a SHARED/GLOBAL location. incur's `skills add` defaults to a
|
|
5
|
+
* GLOBAL install (into `~/.agents/skills` plus symlinks into detected agent
|
|
6
|
+
* dirs like `~/.claude/skills`), so this module is where the work-contract's
|
|
7
|
+
* shared-write isolation obligation is discharged: every knob that decides the
|
|
8
|
+
* install TARGET (`global`, `cwd`) is a parameter a test can redirect to a temp
|
|
9
|
+
* dir, so installing skills can never pollute the real environment in tests.
|
|
10
|
+
*
|
|
11
|
+
* The install runs IN-PROCESS through incur's `SyncSkills.sync`. NOTE (incur
|
|
12
|
+
* 0.4.10): `SyncSkills.sync` / the `skills add` built-in resolve their target
|
|
13
|
+
* from `os.homedir()` and `process.env` captured AT MODULE LOAD, NOT from the
|
|
14
|
+
* `env` DI you can pass to `cli.serve(argv, { env })`, so overriding the serve
|
|
15
|
+
* env does NOT move the install target. The effective in-process lever is
|
|
16
|
+
* `global: false` + `cwd: <temp dir>`, which installs under `<cwd>/.agents/skills`
|
|
17
|
+
* (and `<cwd>/.claude/skills` etc.) and leaves the real dirs byte-untouched.
|
|
18
|
+
*/
|
|
19
|
+
/**
|
|
20
|
+
* The authored picopilot skills (US #20 discipline skills + the game skills),
|
|
21
|
+
* as SKILL.md files under {@link skillsSourceDir}. They load on-demand by
|
|
22
|
+
* concern and carry the hard-won workflow knowledge (the `#include` discipline,
|
|
23
|
+
* the token breakdown, the `gfx render`→look→`gfx set`→fix loop incl. the
|
|
24
|
+
* non-multimodal fallback, composing in picopilot-MML) so an agent gets it
|
|
25
|
+
* without bloating every turn.
|
|
26
|
+
*
|
|
27
|
+
* The GAME skills are a composed pair (grilled design in
|
|
28
|
+
* work/notes/ideas/game-jam-design-skill.md): `game-jam` (model-invoked, the
|
|
29
|
+
* clock+theme discipline) POINTS AT `game-design-reference` (a user-invoked
|
|
30
|
+
* reference body of universal design principles, `disable-model-invocation`, so
|
|
31
|
+
* it costs no per-turn context and is reached only by pointer, not fired on a
|
|
32
|
+
* vague trigger). Both ship engine-packaged here; `game-design-reference`'s
|
|
33
|
+
* CONTENT is engine-agnostic.
|
|
34
|
+
*
|
|
35
|
+
* They ship ALONGSIDE the per-command skills incur auto-generates from the
|
|
36
|
+
* command surface (`sync: { depth: 1 }`), pulled in via an `include` glob; the
|
|
37
|
+
* command surface is still growing, so the named discipline skills are authored
|
|
38
|
+
* rather than tied to a command-group shape that does not exist yet.
|
|
39
|
+
*/
|
|
40
|
+
export declare const SKILL_NAMES: readonly ["picopilot-overview", "picopilot-code", "picopilot-art", "picopilot-audio", "picopilot-debug", "game-design-reference", "game-jam"];
|
|
41
|
+
/**
|
|
42
|
+
* Resolves the on-disk directory that holds the authored `picopilot-*` SKILL.md
|
|
43
|
+
* files (`<packageRoot>/src/skills`). The files ship in the npm package (the
|
|
44
|
+
* package `files` includes `src`), so the same path works from the built
|
|
45
|
+
* `dist/` runtime and from `src/` under tsx: we walk up from THIS module to the
|
|
46
|
+
* package root (the nearest ancestor with a `package.json`) and join `src/skills`,
|
|
47
|
+
* rather than a `dist`-relative path that would not exist (SKILL.md is not
|
|
48
|
+
* compiled).
|
|
49
|
+
*/
|
|
50
|
+
export declare function skillsSourceDir(): string;
|
|
51
|
+
/** One agent whose skill dir picopilot's install wired up (from incur's result). */
|
|
52
|
+
export interface WiredAgent {
|
|
53
|
+
readonly agent: string;
|
|
54
|
+
readonly path: string;
|
|
55
|
+
readonly mode: string;
|
|
56
|
+
}
|
|
57
|
+
/** The outcome of installing picopilot's skills. */
|
|
58
|
+
export interface InstallSkillsResult {
|
|
59
|
+
/** Canonical install paths (one per skill, under `<base>/.agents/skills`). */
|
|
60
|
+
readonly paths: string[];
|
|
61
|
+
/** Non-universal agents whose dirs were symlinked/copied to the canonical skills. */
|
|
62
|
+
readonly agents: WiredAgent[];
|
|
63
|
+
/** The skill names that were installed. */
|
|
64
|
+
readonly skills: string[];
|
|
65
|
+
}
|
|
66
|
+
/** Options controlling WHERE and HOW picopilot's skills are installed. */
|
|
67
|
+
export interface InstallSkillsOptions {
|
|
68
|
+
/**
|
|
69
|
+
* The picopilot CLI whose command surface the per-command skills are generated
|
|
70
|
+
* from. Its command map (via {@link Cli.toCommands}) is handed to incur.
|
|
71
|
+
*/
|
|
72
|
+
readonly cli: Cli.Cli;
|
|
73
|
+
/**
|
|
74
|
+
* Install globally (the real default, into `~/.agents/skills` + detected agent
|
|
75
|
+
* dirs) when true; install project-locally (into `<cwd>/.agents/skills`) when
|
|
76
|
+
* false. This is the shared-write isolation lever: tests pass `false`.
|
|
77
|
+
*/
|
|
78
|
+
readonly global: boolean;
|
|
79
|
+
/**
|
|
80
|
+
* The install base for a project-local (`global: false`) install and, when a
|
|
81
|
+
* non-universal agent is detected, the base its symlinks are written under.
|
|
82
|
+
* Ignored for a global install (that goes to the real home). Tests point this
|
|
83
|
+
* at a temp dir.
|
|
84
|
+
*/
|
|
85
|
+
readonly cwd?: string;
|
|
86
|
+
/**
|
|
87
|
+
* Override the authored-skills source dir. Defaults to {@link skillsSourceDir}.
|
|
88
|
+
* Exists so a test can prove isolation using its own fixture skills.
|
|
89
|
+
*/
|
|
90
|
+
readonly sourceDir?: string;
|
|
91
|
+
}
|
|
92
|
+
/**
|
|
93
|
+
* Installs picopilot's skills (the authored `picopilot-*` discipline skills plus
|
|
94
|
+
* the per-command skills incur generates from the CLI) via incur's
|
|
95
|
+
* `SyncSkills.sync`. This is the real work `init --install-skills` performs.
|
|
96
|
+
*
|
|
97
|
+
* The authored skills are pulled in with an ABSOLUTE `include` glob into
|
|
98
|
+
* {@link skillsSourceDir}, DECOUPLED from `cwd` on purpose: `cwd` selects the
|
|
99
|
+
* install TARGET, the include glob selects the skills SOURCE. That decoupling is
|
|
100
|
+
* what lets a test install to a temp `cwd` while still reading the real authored
|
|
101
|
+
* skills (or its own fixtures), the crux of the isolation contract.
|
|
102
|
+
*/
|
|
103
|
+
export declare function installSkills(options: InstallSkillsOptions): Promise<InstallSkillsResult>;
|
|
104
|
+
//# sourceMappingURL=skills.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"skills.d.ts","sourceRoot":"","sources":["../../../src/engine/skills/skills.ts"],"names":[],"mappings":"AAGA,OAAO,EAAC,GAAG,EAAa,MAAM,OAAO,CAAC;AAEtC;;;;;;;;;;;;;;;;GAgBG;AAEH;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,eAAO,MAAM,WAAW,+IAQd,CAAC;AAEX;;;;;;;;GAQG;AACH,wBAAgB,eAAe,IAAI,MAAM,CAcxC;AAED,oFAAoF;AACpF,MAAM,WAAW,UAAU;IAC1B,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;CACtB;AAED,oDAAoD;AACpD,MAAM,WAAW,mBAAmB;IACnC,8EAA8E;IAC9E,QAAQ,CAAC,KAAK,EAAE,MAAM,EAAE,CAAC;IACzB,qFAAqF;IACrF,QAAQ,CAAC,MAAM,EAAE,UAAU,EAAE,CAAC;IAC9B,2CAA2C;IAC3C,QAAQ,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC;CAC1B;AAED,0EAA0E;AAC1E,MAAM,WAAW,oBAAoB;IACpC;;;OAGG;IACH,QAAQ,CAAC,GAAG,EAAE,GAAG,CAAC,GAAG,CAAC;IACtB;;;;OAIG;IACH,QAAQ,CAAC,MAAM,EAAE,OAAO,CAAC;IACzB;;;;;OAKG;IACH,QAAQ,CAAC,GAAG,CAAC,EAAE,MAAM,CAAC;IACtB;;;OAGG;IACH,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAC;CAC5B;AAED;;;;;;;;;;GAUG;AACH,wBAAsB,aAAa,CAClC,OAAO,EAAE,oBAAoB,GAC3B,OAAO,CAAC,mBAAmB,CAAC,CA6C9B"}
|
|
@@ -0,0 +1,149 @@
|
|
|
1
|
+
import { cpSync, existsSync, readdirSync } from 'node:fs';
|
|
2
|
+
import { basename, dirname, join } from 'node:path';
|
|
3
|
+
import { fileURLToPath } from 'node:url';
|
|
4
|
+
import { Cli, SyncSkills } from 'incur';
|
|
5
|
+
/**
|
|
6
|
+
* The engine behind `picopilot init --install-skills`: the ONE picopilot path
|
|
7
|
+
* that writes to a SHARED/GLOBAL location. incur's `skills add` defaults to a
|
|
8
|
+
* GLOBAL install (into `~/.agents/skills` plus symlinks into detected agent
|
|
9
|
+
* dirs like `~/.claude/skills`), so this module is where the work-contract's
|
|
10
|
+
* shared-write isolation obligation is discharged: every knob that decides the
|
|
11
|
+
* install TARGET (`global`, `cwd`) is a parameter a test can redirect to a temp
|
|
12
|
+
* dir, so installing skills can never pollute the real environment in tests.
|
|
13
|
+
*
|
|
14
|
+
* The install runs IN-PROCESS through incur's `SyncSkills.sync`. NOTE (incur
|
|
15
|
+
* 0.4.10): `SyncSkills.sync` / the `skills add` built-in resolve their target
|
|
16
|
+
* from `os.homedir()` and `process.env` captured AT MODULE LOAD, NOT from the
|
|
17
|
+
* `env` DI you can pass to `cli.serve(argv, { env })`, so overriding the serve
|
|
18
|
+
* env does NOT move the install target. The effective in-process lever is
|
|
19
|
+
* `global: false` + `cwd: <temp dir>`, which installs under `<cwd>/.agents/skills`
|
|
20
|
+
* (and `<cwd>/.claude/skills` etc.) and leaves the real dirs byte-untouched.
|
|
21
|
+
*/
|
|
22
|
+
/**
|
|
23
|
+
* The authored picopilot skills (US #20 discipline skills + the game skills),
|
|
24
|
+
* as SKILL.md files under {@link skillsSourceDir}. They load on-demand by
|
|
25
|
+
* concern and carry the hard-won workflow knowledge (the `#include` discipline,
|
|
26
|
+
* the token breakdown, the `gfx render`→look→`gfx set`→fix loop incl. the
|
|
27
|
+
* non-multimodal fallback, composing in picopilot-MML) so an agent gets it
|
|
28
|
+
* without bloating every turn.
|
|
29
|
+
*
|
|
30
|
+
* The GAME skills are a composed pair (grilled design in
|
|
31
|
+
* work/notes/ideas/game-jam-design-skill.md): `game-jam` (model-invoked, the
|
|
32
|
+
* clock+theme discipline) POINTS AT `game-design-reference` (a user-invoked
|
|
33
|
+
* reference body of universal design principles, `disable-model-invocation`, so
|
|
34
|
+
* it costs no per-turn context and is reached only by pointer, not fired on a
|
|
35
|
+
* vague trigger). Both ship engine-packaged here; `game-design-reference`'s
|
|
36
|
+
* CONTENT is engine-agnostic.
|
|
37
|
+
*
|
|
38
|
+
* They ship ALONGSIDE the per-command skills incur auto-generates from the
|
|
39
|
+
* command surface (`sync: { depth: 1 }`), pulled in via an `include` glob; the
|
|
40
|
+
* command surface is still growing, so the named discipline skills are authored
|
|
41
|
+
* rather than tied to a command-group shape that does not exist yet.
|
|
42
|
+
*/
|
|
43
|
+
export const SKILL_NAMES = [
|
|
44
|
+
'picopilot-overview',
|
|
45
|
+
'picopilot-code',
|
|
46
|
+
'picopilot-art',
|
|
47
|
+
'picopilot-audio',
|
|
48
|
+
'picopilot-debug',
|
|
49
|
+
'game-design-reference',
|
|
50
|
+
'game-jam',
|
|
51
|
+
];
|
|
52
|
+
/**
|
|
53
|
+
* Resolves the on-disk directory that holds the authored `picopilot-*` SKILL.md
|
|
54
|
+
* files (`<packageRoot>/src/skills`). The files ship in the npm package (the
|
|
55
|
+
* package `files` includes `src`), so the same path works from the built
|
|
56
|
+
* `dist/` runtime and from `src/` under tsx: we walk up from THIS module to the
|
|
57
|
+
* package root (the nearest ancestor with a `package.json`) and join `src/skills`,
|
|
58
|
+
* rather than a `dist`-relative path that would not exist (SKILL.md is not
|
|
59
|
+
* compiled).
|
|
60
|
+
*/
|
|
61
|
+
export function skillsSourceDir() {
|
|
62
|
+
let dir = dirname(fileURLToPath(import.meta.url));
|
|
63
|
+
const seen = new Set();
|
|
64
|
+
while (!seen.has(dir)) {
|
|
65
|
+
seen.add(dir);
|
|
66
|
+
if (existsSync(join(dir, 'package.json'))) {
|
|
67
|
+
return join(dir, 'src', 'skills');
|
|
68
|
+
}
|
|
69
|
+
const parent = dirname(dir);
|
|
70
|
+
if (parent === dir)
|
|
71
|
+
break;
|
|
72
|
+
dir = parent;
|
|
73
|
+
}
|
|
74
|
+
// Fallback: two levels up from src/engine/skills is the package root.
|
|
75
|
+
return join(dirname(fileURLToPath(import.meta.url)), '..', '..', 'skills');
|
|
76
|
+
}
|
|
77
|
+
/**
|
|
78
|
+
* Installs picopilot's skills (the authored `picopilot-*` discipline skills plus
|
|
79
|
+
* the per-command skills incur generates from the CLI) via incur's
|
|
80
|
+
* `SyncSkills.sync`. This is the real work `init --install-skills` performs.
|
|
81
|
+
*
|
|
82
|
+
* The authored skills are pulled in with an ABSOLUTE `include` glob into
|
|
83
|
+
* {@link skillsSourceDir}, DECOUPLED from `cwd` on purpose: `cwd` selects the
|
|
84
|
+
* install TARGET, the include glob selects the skills SOURCE. That decoupling is
|
|
85
|
+
* what lets a test install to a temp `cwd` while still reading the real authored
|
|
86
|
+
* skills (or its own fixtures), the crux of the isolation contract.
|
|
87
|
+
*/
|
|
88
|
+
export async function installSkills(options) {
|
|
89
|
+
const commands = Cli.toCommands.get(options.cli);
|
|
90
|
+
if (commands === undefined) {
|
|
91
|
+
throw new Error('installSkills: the given CLI has no command map (was it built by Cli.create?)');
|
|
92
|
+
}
|
|
93
|
+
const source = options.sourceDir ?? skillsSourceDir();
|
|
94
|
+
const result = await SyncSkills.sync('picopilot', commands, {
|
|
95
|
+
depth: 1,
|
|
96
|
+
description: 'An agent-first toolchain for PICO-8 game development.',
|
|
97
|
+
global: options.global,
|
|
98
|
+
cwd: options.cwd,
|
|
99
|
+
// Absolute glob → resolves against `source`, independent of `cwd`.
|
|
100
|
+
include: [join(source, '*')],
|
|
101
|
+
});
|
|
102
|
+
// Ship skill RESOURCE files (everything a skill dir carries besides SKILL.md).
|
|
103
|
+
// incur 0.4.10's SyncSkills.sync copies ONLY SKILL.md and drops sibling files
|
|
104
|
+
// (see work/notes/observations/incur-syncskills-drops-skill-resource-files.md),
|
|
105
|
+
// so genre code references under e.g. `picopilot-code/reference/` would never
|
|
106
|
+
// reach the installed skill. We backfill them here: for each installed skill
|
|
107
|
+
// path (canonical + each wired agent), copy the matching source skill's
|
|
108
|
+
// non-SKILL.md contents in. This stays inside the already-isolated installSkills
|
|
109
|
+
// seam, so the shared-write isolation test still governs it, and it becomes a
|
|
110
|
+
// no-op (safe to delete) once incur copies full skill dirs.
|
|
111
|
+
const installPaths = [...result.paths, ...result.agents.map((a) => a.path)];
|
|
112
|
+
for (const installedSkillDir of installPaths) {
|
|
113
|
+
copySkillResources(join(source, basename(installedSkillDir)), installedSkillDir);
|
|
114
|
+
}
|
|
115
|
+
return {
|
|
116
|
+
paths: result.paths,
|
|
117
|
+
agents: result.agents.map((a) => ({
|
|
118
|
+
agent: a.agent,
|
|
119
|
+
path: a.path,
|
|
120
|
+
mode: a.mode,
|
|
121
|
+
})),
|
|
122
|
+
skills: result.skills.map((s) => s.name),
|
|
123
|
+
};
|
|
124
|
+
}
|
|
125
|
+
/**
|
|
126
|
+
* Copies a source skill directory's RESOURCE files (everything except SKILL.md)
|
|
127
|
+
* into an already-installed skill directory. This is the workaround for incur
|
|
128
|
+
* 0.4.10 shipping only SKILL.md (see the observation referenced in installSkills):
|
|
129
|
+
* SKILL.md is left to incur (it is already written and may be transformed), and
|
|
130
|
+
* only the sibling resources are backfilled, recursively, preserving structure.
|
|
131
|
+
*
|
|
132
|
+
* Both the source skill and any resources are optional: a skill with no resource
|
|
133
|
+
* files, or a source dir that does not exist (a command-generated skill with no
|
|
134
|
+
* authored source), is a silent no-op. Nothing here reaches outside `destDir`,
|
|
135
|
+
* which is one of the install paths SyncSkills already chose, so it inherits the
|
|
136
|
+
* shared-write isolation of installSkills (tests redirect those paths to a temp).
|
|
137
|
+
*/
|
|
138
|
+
function copySkillResources(sourceSkillDir, destDir) {
|
|
139
|
+
if (!existsSync(sourceSkillDir) || !existsSync(destDir))
|
|
140
|
+
return;
|
|
141
|
+
for (const entry of readdirSync(sourceSkillDir)) {
|
|
142
|
+
if (entry === 'SKILL.md')
|
|
143
|
+
continue; // incur owns the manifest; do not clobber it
|
|
144
|
+
cpSync(join(sourceSkillDir, entry), join(destDir, entry), {
|
|
145
|
+
recursive: true,
|
|
146
|
+
});
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
//# sourceMappingURL=skills.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"skills.js","sourceRoot":"","sources":["../../../src/engine/skills/skills.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { Cli } from 'incur';
|
|
2
|
+
export { createCli } from './cli.js';
|
|
3
|
+
export { VERSION } from './version.js';
|
|
4
|
+
/**
|
|
5
|
+
* The default CLI instance, exported for `incur gen` (typed CTAs) and for
|
|
6
|
+
* embedding picopilot as a Fetch API handler / MCP server.
|
|
7
|
+
*/
|
|
8
|
+
declare const cli: Cli.Cli;
|
|
9
|
+
export default cli;
|
|
10
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAC,GAAG,EAAC,MAAM,OAAO,CAAC;AAG/B,OAAO,EAAC,SAAS,EAAC,MAAM,UAAU,CAAC;AACnC,OAAO,EAAC,OAAO,EAAC,MAAM,cAAc,CAAC;AAErC;;;GAGG;AACH,QAAA,MAAM,GAAG,EAAE,GAAG,CAAC,GAAiB,CAAC;AAEjC,eAAe,GAAG,CAAC"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { createCli } from './cli.js';
|
|
2
|
+
export { createCli } from './cli.js';
|
|
3
|
+
export { VERSION } from './version.js';
|
|
4
|
+
/**
|
|
5
|
+
* The default CLI instance, exported for `incur gen` (typed CTAs) and for
|
|
6
|
+
* embedding picopilot as a Fetch API handler / MCP server.
|
|
7
|
+
*/
|
|
8
|
+
const cli = createCli();
|
|
9
|
+
export default cli;
|
|
10
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAC,SAAS,EAAC,MAAM,UAAU,CAAC;AAEnC,OAAO,EAAC,SAAS,EAAC,MAAM,UAAU,CAAC;AACnC,OAAO,EAAC,OAAO,EAAC,MAAM,cAAc,CAAC;AAErC;;;GAGG;AACH,MAAM,GAAG,GAAY,SAAS,EAAE,CAAC;AAEjC,eAAe,GAAG,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"version.d.ts","sourceRoot":"","sources":["../src/version.ts"],"names":[],"mappings":"AAqBA,eAAO,MAAM,OAAO,QAAgB,CAAC"}
|
package/dist/version.js
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { readFileSync } from 'node:fs';
|
|
2
|
+
import { dirname, join } from 'node:path';
|
|
3
|
+
import { fileURLToPath } from 'node:url';
|
|
4
|
+
/**
|
|
5
|
+
* The installed picopilot version, read from the package manifest at load time.
|
|
6
|
+
*
|
|
7
|
+
* Single source of truth: the version lives only in `package.json`. The manifest
|
|
8
|
+
* sits one level above the compiled module (`dist/version.js` → `package.json`)
|
|
9
|
+
* and one level above the source module (`src/version.ts` → `package.json`), so
|
|
10
|
+
* the same relative lookup works for both the built binary and `tsx` dev runs.
|
|
11
|
+
*/
|
|
12
|
+
function readVersion() {
|
|
13
|
+
const here = dirname(fileURLToPath(import.meta.url));
|
|
14
|
+
const manifestPath = join(here, '..', 'package.json');
|
|
15
|
+
const manifest = JSON.parse(readFileSync(manifestPath, 'utf8'));
|
|
16
|
+
return manifest.version ?? '0.0.0';
|
|
17
|
+
}
|
|
18
|
+
export const VERSION = readVersion();
|
|
19
|
+
//# sourceMappingURL=version.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"version.js","sourceRoot":"","sources":["../src/version.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,YAAY,EAAC,MAAM,SAAS,CAAC;AACrC,OAAO,EAAC,OAAO,EAAE,IAAI,EAAC,MAAM,WAAW,CAAC;AACxC,OAAO,EAAC,aAAa,EAAC,MAAM,UAAU,CAAC;AAEvC;;;;;;;GAOG;AACH,SAAS,WAAW;IACnB,MAAM,IAAI,GAAG,OAAO,CAAC,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC;IACrD,MAAM,YAAY,GAAG,IAAI,CAAC,IAAI,EAAE,IAAI,EAAE,cAAc,CAAC,CAAC;IACtD,MAAM,QAAQ,GAAG,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,YAAY,EAAE,MAAM,CAAC,CAE7D,CAAC;IACF,OAAO,QAAQ,CAAC,OAAO,IAAI,OAAO,CAAC;AACpC,CAAC;AAED,MAAM,CAAC,MAAM,OAAO,GAAG,WAAW,EAAE,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,4 +1,50 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "picopilot",
|
|
3
|
-
"version": "0.
|
|
4
|
-
|
|
3
|
+
"version": "0.1.1",
|
|
4
|
+
"description": "An agent-first toolchain for PICO-8 game development, built on the incur CLI framework.",
|
|
5
|
+
"license": "AGPL-3.0-only",
|
|
6
|
+
"repository": {
|
|
7
|
+
"type": "git",
|
|
8
|
+
"url": "git+https://github.com/wighawag/picopilot.git",
|
|
9
|
+
"directory": "packages/picopilot"
|
|
10
|
+
},
|
|
11
|
+
"homepage": "https://github.com/wighawag/picopilot#readme",
|
|
12
|
+
"bugs": "https://github.com/wighawag/picopilot/issues",
|
|
13
|
+
"type": "module",
|
|
14
|
+
"bin": {
|
|
15
|
+
"picopilot": "./dist/bin.js"
|
|
16
|
+
},
|
|
17
|
+
"main": "./dist/index.js",
|
|
18
|
+
"module": "./dist/index.js",
|
|
19
|
+
"types": "./dist/index.d.ts",
|
|
20
|
+
"exports": {
|
|
21
|
+
".": {
|
|
22
|
+
"types": "./dist/index.d.ts",
|
|
23
|
+
"default": "./dist/index.js"
|
|
24
|
+
}
|
|
25
|
+
},
|
|
26
|
+
"files": [
|
|
27
|
+
"dist",
|
|
28
|
+
"src"
|
|
29
|
+
],
|
|
30
|
+
"engines": {
|
|
31
|
+
"node": ">=22"
|
|
32
|
+
},
|
|
33
|
+
"dependencies": {
|
|
34
|
+
"incur": "0.4.10"
|
|
35
|
+
},
|
|
36
|
+
"devDependencies": {
|
|
37
|
+
"@types/node": "22.12.0",
|
|
38
|
+
"as-soon": "^0.1.5",
|
|
39
|
+
"tsx": "4.21.0",
|
|
40
|
+
"typescript": "5.9.3",
|
|
41
|
+
"vitest": "3.2.4"
|
|
42
|
+
},
|
|
43
|
+
"scripts": {
|
|
44
|
+
"build": "tsc -p tsconfig.build.json",
|
|
45
|
+
"dev": "as-soon -w src pnpm build",
|
|
46
|
+
"test": "vitest run",
|
|
47
|
+
"test:watch": "vitest",
|
|
48
|
+
"picopilot": "node --import tsx src/bin.ts"
|
|
49
|
+
}
|
|
50
|
+
}
|