@pebbly/aseprite-ai-artist 0.1.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/CHANGELOG.md +170 -0
- package/LICENSE +21 -0
- package/README.md +169 -0
- package/agents/animation-director.md +65 -0
- package/agents/palette-smith.md +57 -0
- package/agents/pixel-critic.md +69 -0
- package/agents/rig-builder.md +46 -0
- package/bin/aseprite-ai-artist +6 -0
- package/bin/aseprite-ai-artist.mjs +44 -0
- package/dist/bridge/bridge.d.ts +52 -0
- package/dist/bridge/bridge.js +230 -0
- package/dist/bridge/bridge.js.map +1 -0
- package/dist/bridge/client.d.ts +54 -0
- package/dist/bridge/client.js +214 -0
- package/dist/bridge/client.js.map +1 -0
- package/dist/cli.d.ts +10 -0
- package/dist/cli.js +272 -0
- package/dist/cli.js.map +1 -0
- package/dist/extension.d.ts +21 -0
- package/dist/extension.js +65 -0
- package/dist/extension.js.map +1 -0
- package/dist/install.d.ts +35 -0
- package/dist/install.js +185 -0
- package/dist/install.js.map +1 -0
- package/dist/lib/color.d.ts +66 -0
- package/dist/lib/color.js +170 -0
- package/dist/lib/color.js.map +1 -0
- package/dist/lib/protocol.d.ts +78 -0
- package/dist/lib/protocol.js +72 -0
- package/dist/lib/protocol.js.map +1 -0
- package/dist/lib/render.d.ts +62 -0
- package/dist/lib/render.js +134 -0
- package/dist/lib/render.js.map +1 -0
- package/dist/lib/skills.d.ts +43 -0
- package/dist/lib/skills.js +112 -0
- package/dist/lib/skills.js.map +1 -0
- package/dist/lib/version.d.ts +4 -0
- package/dist/lib/version.js +25 -0
- package/dist/lib/version.js.map +1 -0
- package/dist/server.d.ts +15 -0
- package/dist/server.js +144 -0
- package/dist/server.js.map +1 -0
- package/dist/tools/assets.d.ts +3 -0
- package/dist/tools/assets.js +181 -0
- package/dist/tools/assets.js.map +1 -0
- package/dist/tools/craft.d.ts +12 -0
- package/dist/tools/craft.js +143 -0
- package/dist/tools/craft.js.map +1 -0
- package/dist/tools/draw.d.ts +3 -0
- package/dist/tools/draw.js +256 -0
- package/dist/tools/draw.js.map +1 -0
- package/dist/tools/escape.d.ts +12 -0
- package/dist/tools/escape.js +49 -0
- package/dist/tools/escape.js.map +1 -0
- package/dist/tools/kit.d.ts +29 -0
- package/dist/tools/kit.js +85 -0
- package/dist/tools/kit.js.map +1 -0
- package/dist/tools/look.d.ts +7 -0
- package/dist/tools/look.js +215 -0
- package/dist/tools/look.js.map +1 -0
- package/dist/tools/palette.d.ts +3 -0
- package/dist/tools/palette.js +232 -0
- package/dist/tools/palette.js.map +1 -0
- package/dist/tools/session.d.ts +3 -0
- package/dist/tools/session.js +231 -0
- package/dist/tools/session.js.map +1 -0
- package/dist/tools/structure.d.ts +3 -0
- package/dist/tools/structure.js +218 -0
- package/dist/tools/structure.js.map +1 -0
- package/examples/mcp-configs/claude-code.json +9 -0
- package/examples/mcp-configs/codex.toml +13 -0
- package/examples/mcp-configs/cursor.json +9 -0
- package/examples/mcp-configs/gemini-cli.json +9 -0
- package/examples/mcp-configs/vscode.json +10 -0
- package/extension/ai-artist.lua +3291 -0
- package/extension/package.json +14 -0
- package/hooks/hooks.json +25 -0
- package/hooks/look-nudge.mjs +46 -0
- package/hooks/session-status.mjs +47 -0
- package/knowledge/palettes.json +60 -0
- package/package.json +69 -0
- package/rules/00-core-principles.md +57 -0
- package/rules/01-palette-and-color.md +51 -0
- package/rules/02-shading-and-light.md +56 -0
- package/rules/03-silhouette-and-form.md +60 -0
- package/rules/04-outlines-and-edges.md +46 -0
- package/rules/05-animation.md +62 -0
- package/rules/06-layers-and-rigging.md +52 -0
- package/rules/07-review-checklist.md +51 -0
- package/rules/README.md +16 -0
- package/skills/README.md +29 -0
- package/skills/pixel-animate/SKILL.md +91 -0
- package/skills/pixel-brief/SKILL.md +61 -0
- package/skills/pixel-draw/SKILL.md +93 -0
- package/skills/pixel-export/SKILL.md +80 -0
- package/skills/pixel-fix/SKILL.md +91 -0
- package/skills/pixel-new/SKILL.md +70 -0
- package/skills/pixel-palette/SKILL.md +80 -0
- package/skills/pixel-review/SKILL.md +81 -0
- package/skills/pixel-rig/SKILL.md +76 -0
- package/skills/pixel-shade/SKILL.md +77 -0
- package/skills/pixel-tileset/SKILL.md +104 -0
- package/templates/AGENTS.section.md +33 -0
package/dist/cli.js
ADDED
|
@@ -0,0 +1,272 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* One binary, several jobs:
|
|
4
|
+
* serve (default) speak MCP over stdio
|
|
5
|
+
* bridge run the singleton WebSocket relay
|
|
6
|
+
* install <client…> wire this server into an agent's config
|
|
7
|
+
* install-extension copy the Lua extension into Aseprite
|
|
8
|
+
* doctor tell the user exactly what is broken
|
|
9
|
+
*/
|
|
10
|
+
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
|
|
11
|
+
import { Bridge } from "./bridge/bridge.js";
|
|
12
|
+
import { LiveClient } from "./bridge/client.js";
|
|
13
|
+
import { createServer } from "./server.js";
|
|
14
|
+
import { CLIENTS, configPath, install, mergeAgentsFile, } from "./install.js";
|
|
15
|
+
import { installExtension, findAsepriteConfigDir } from "./extension.js";
|
|
16
|
+
import { DEFAULT_CONTROL_PORT, DEFAULT_PLUGIN_PORT } from "./lib/protocol.js";
|
|
17
|
+
import { packageVersion } from "./lib/version.js";
|
|
18
|
+
function parseArgs(argv) {
|
|
19
|
+
const flags = {};
|
|
20
|
+
const positional = [];
|
|
21
|
+
for (let i = 0; i < argv.length; i++) {
|
|
22
|
+
const arg = argv[i];
|
|
23
|
+
if (!arg.startsWith("--")) {
|
|
24
|
+
positional.push(arg);
|
|
25
|
+
continue;
|
|
26
|
+
}
|
|
27
|
+
const key = arg.slice(2);
|
|
28
|
+
const next = argv[i + 1];
|
|
29
|
+
if (next !== undefined && !next.startsWith("--")) {
|
|
30
|
+
flags[key] = next;
|
|
31
|
+
i++;
|
|
32
|
+
}
|
|
33
|
+
else {
|
|
34
|
+
flags[key] = true;
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
const command = positional.shift() ?? "serve";
|
|
38
|
+
return { command, positional, flags };
|
|
39
|
+
}
|
|
40
|
+
function num(flags, key, fallback) {
|
|
41
|
+
const raw = flags[key];
|
|
42
|
+
if (typeof raw !== "string")
|
|
43
|
+
return fallback;
|
|
44
|
+
const parsed = Number(raw);
|
|
45
|
+
return Number.isInteger(parsed) ? parsed : fallback;
|
|
46
|
+
}
|
|
47
|
+
async function main() {
|
|
48
|
+
const { command, positional, flags } = parseArgs(process.argv.slice(2));
|
|
49
|
+
if (flags.version || command === "version") {
|
|
50
|
+
process.stdout.write(`${packageVersion()}\n`);
|
|
51
|
+
return;
|
|
52
|
+
}
|
|
53
|
+
if (flags.help || command === "help") {
|
|
54
|
+
printHelp();
|
|
55
|
+
return;
|
|
56
|
+
}
|
|
57
|
+
const pluginPort = num(flags, "plugin-port", envPort("ASEPRITE_AI_PLUGIN_PORT", DEFAULT_PLUGIN_PORT));
|
|
58
|
+
const controlPort = num(flags, "control-port", envPort("ASEPRITE_AI_CONTROL_PORT", pluginPort + 1));
|
|
59
|
+
switch (command) {
|
|
60
|
+
case "serve":
|
|
61
|
+
return serve({ pluginPort, controlPort, allowLua: truthy(flags.allowLua ?? process.env.ASEPRITE_AI_ALLOW_LUA) });
|
|
62
|
+
case "bridge":
|
|
63
|
+
return runBridge({ pluginPort, controlPort });
|
|
64
|
+
case "install":
|
|
65
|
+
return runInstall(positional, flags);
|
|
66
|
+
case "install-extension":
|
|
67
|
+
return runInstallExtension(flags);
|
|
68
|
+
case "doctor":
|
|
69
|
+
return doctor({ pluginPort, controlPort });
|
|
70
|
+
default:
|
|
71
|
+
process.stderr.write(`Unknown command '${command}'.\n\n`);
|
|
72
|
+
printHelp();
|
|
73
|
+
process.exitCode = 2;
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
async function serve(opts) {
|
|
77
|
+
const { server, live } = createServer({
|
|
78
|
+
pluginPort: opts.pluginPort,
|
|
79
|
+
controlPort: opts.controlPort,
|
|
80
|
+
allowLua: opts.allowLua,
|
|
81
|
+
});
|
|
82
|
+
const transport = new StdioServerTransport();
|
|
83
|
+
await server.connect(transport);
|
|
84
|
+
const shutdown = () => {
|
|
85
|
+
live.close();
|
|
86
|
+
// .finally() forwards a rejection, and nothing would catch it. Exit on both
|
|
87
|
+
// paths explicitly rather than relying on process.exit winning the race.
|
|
88
|
+
server.close().then(() => process.exit(0), () => process.exit(1));
|
|
89
|
+
};
|
|
90
|
+
process.on("SIGINT", shutdown);
|
|
91
|
+
process.on("SIGTERM", shutdown);
|
|
92
|
+
}
|
|
93
|
+
async function runBridge(opts) {
|
|
94
|
+
const bridge = new Bridge({
|
|
95
|
+
pluginPort: opts.pluginPort,
|
|
96
|
+
controlPort: opts.controlPort,
|
|
97
|
+
version: packageVersion(),
|
|
98
|
+
log: (msg) => process.stderr.write(`[bridge] ${msg}\n`),
|
|
99
|
+
});
|
|
100
|
+
const started = await bridge.start();
|
|
101
|
+
if (!started) {
|
|
102
|
+
// Losing the race is the normal outcome when a bridge already runs.
|
|
103
|
+
process.stderr.write("[bridge] another bridge already owns these ports; exiting\n");
|
|
104
|
+
return;
|
|
105
|
+
}
|
|
106
|
+
const stop = () => bridge.stop().then(() => process.exit(0), () => process.exit(1));
|
|
107
|
+
process.on("SIGINT", stop);
|
|
108
|
+
process.on("SIGTERM", stop);
|
|
109
|
+
// Hold the process open; the WebSocket servers keep the loop alive anyway.
|
|
110
|
+
await new Promise(() => { });
|
|
111
|
+
}
|
|
112
|
+
async function runInstall(positional, flags) {
|
|
113
|
+
const requested = positional.length > 0 ? positional : (flags.all ? CLIENTS : []);
|
|
114
|
+
if (requested.length === 0) {
|
|
115
|
+
process.stderr.write(`Name at least one client, or pass --all.\nAvailable: ${CLIENTS.join(", ")}\n`);
|
|
116
|
+
process.exitCode = 2;
|
|
117
|
+
return;
|
|
118
|
+
}
|
|
119
|
+
const scope = flags.project ? "project" : "user";
|
|
120
|
+
const projectDir = typeof flags.dir === "string" ? flags.dir : process.cwd();
|
|
121
|
+
const dryRun = truthy(flags["dry-run"]);
|
|
122
|
+
const env = {};
|
|
123
|
+
if (typeof flags.aseprite === "string")
|
|
124
|
+
env.ASEPRITE_PATH = flags.aseprite;
|
|
125
|
+
if (truthy(flags.allowLua))
|
|
126
|
+
env.ASEPRITE_AI_ALLOW_LUA = "1";
|
|
127
|
+
const opts = {
|
|
128
|
+
scope: scope,
|
|
129
|
+
projectDir,
|
|
130
|
+
command: "npx",
|
|
131
|
+
args: ["-y", "@pebbly/aseprite-ai-artist@latest", "serve"],
|
|
132
|
+
env,
|
|
133
|
+
dryRun,
|
|
134
|
+
};
|
|
135
|
+
for (const name of requested) {
|
|
136
|
+
if (!CLIENTS.includes(name)) {
|
|
137
|
+
process.stderr.write(`Unknown client '${name}'. Available: ${CLIENTS.join(", ")}\n`);
|
|
138
|
+
process.exitCode = 2;
|
|
139
|
+
return;
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
for (const name of requested) {
|
|
143
|
+
try {
|
|
144
|
+
const result = install(name, opts);
|
|
145
|
+
if (dryRun) {
|
|
146
|
+
process.stdout.write(`\n# ${name} → ${result.file}\n${result.note ?? ""}\n`);
|
|
147
|
+
}
|
|
148
|
+
else {
|
|
149
|
+
process.stdout.write(`✓ ${name.padEnd(9)} ${result.file}\n`);
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
catch (err) {
|
|
153
|
+
process.stdout.write(`✗ ${name.padEnd(9)} ${err.message}\n`);
|
|
154
|
+
process.exitCode = 1;
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
if (truthy(flags.agents)) {
|
|
158
|
+
const target = typeof flags.agents === "string" ? flags.agents : `${projectDir}/AGENTS.md`;
|
|
159
|
+
const res = mergeAgentsFile(target, dryRun);
|
|
160
|
+
process.stdout.write(`${res.written ? "✓" : "·"} AGENTS.md ${res.file}\n`);
|
|
161
|
+
}
|
|
162
|
+
if (!dryRun) {
|
|
163
|
+
process.stdout.write("\nRestart the agent so it picks up the new server, then run `install-extension` if you have not already.\n");
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
async function runInstallExtension(flags) {
|
|
167
|
+
try {
|
|
168
|
+
const result = installExtension({
|
|
169
|
+
dryRun: truthy(flags["dry-run"]),
|
|
170
|
+
configDir: typeof flags.dir === "string" ? flags.dir : undefined,
|
|
171
|
+
});
|
|
172
|
+
process.stdout.write(`✓ extension → ${result.target}\n`);
|
|
173
|
+
process.stdout.write("Restart Aseprite. The extension connects on startup; check Edit ▸ Preferences ▸ Extensions if it does not appear.\n");
|
|
174
|
+
}
|
|
175
|
+
catch (err) {
|
|
176
|
+
process.stdout.write(`✗ ${err.message}\n`);
|
|
177
|
+
process.exitCode = 1;
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
async function doctor(opts) {
|
|
181
|
+
const lines = [`aseprite-ai-artist ${packageVersion()}`, ""];
|
|
182
|
+
const configDir = findAsepriteConfigDir();
|
|
183
|
+
lines.push(configDir
|
|
184
|
+
? `✓ Aseprite config dir ${configDir}`
|
|
185
|
+
: "✗ Aseprite config dir not found — is Aseprite installed and has it been run once?");
|
|
186
|
+
const live = new LiveClient({
|
|
187
|
+
controlPort: opts.controlPort,
|
|
188
|
+
pluginPort: opts.pluginPort,
|
|
189
|
+
autoSpawnBridge: true,
|
|
190
|
+
log: () => { },
|
|
191
|
+
});
|
|
192
|
+
const bridgeUp = await live.waitForBridge(4_000);
|
|
193
|
+
lines.push(bridgeUp
|
|
194
|
+
? `✓ Bridge ws://127.0.0.1:${opts.controlPort}`
|
|
195
|
+
: `✗ Bridge could not reach or start it on :${opts.controlPort}`);
|
|
196
|
+
const pluginUp = bridgeUp ? await live.waitForPlugin(4_000) : false;
|
|
197
|
+
lines.push(pluginUp
|
|
198
|
+
? `✓ Aseprite extension ${live.hello?.extensionVersion ?? "?"} on Aseprite ${live.hello?.asepriteVersion ?? "?"}`
|
|
199
|
+
: "✗ Aseprite extension not connected — open Aseprite, or run `install-extension` and restart it");
|
|
200
|
+
if (pluginUp) {
|
|
201
|
+
lines.push(` features ${live.features.join(", ") || "(none)"}`);
|
|
202
|
+
try {
|
|
203
|
+
const site = await live.call("session.site");
|
|
204
|
+
lines.push(site.sprite
|
|
205
|
+
? `✓ Active sprite ${site.sprite.name ?? "untitled"}`
|
|
206
|
+
: "· Active sprite none open (that is fine)");
|
|
207
|
+
}
|
|
208
|
+
catch (err) {
|
|
209
|
+
lines.push(`✗ Round trip ${err.message}`);
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
lines.push("");
|
|
213
|
+
lines.push("Client config locations:");
|
|
214
|
+
for (const client of CLIENTS) {
|
|
215
|
+
lines.push(` ${client.padEnd(9)} ${configPath(client, {
|
|
216
|
+
scope: "user",
|
|
217
|
+
projectDir: process.cwd(),
|
|
218
|
+
command: "",
|
|
219
|
+
args: [],
|
|
220
|
+
env: {},
|
|
221
|
+
dryRun: true,
|
|
222
|
+
})}`);
|
|
223
|
+
}
|
|
224
|
+
live.close();
|
|
225
|
+
process.stdout.write(lines.join("\n") + "\n");
|
|
226
|
+
process.exitCode = pluginUp ? 0 : 1;
|
|
227
|
+
}
|
|
228
|
+
function printHelp() {
|
|
229
|
+
process.stdout.write(`aseprite-ai-artist ${packageVersion()} — agent control layer for Aseprite
|
|
230
|
+
|
|
231
|
+
Usage:
|
|
232
|
+
aseprite-ai-artist [serve] Speak MCP over stdio (what agents run)
|
|
233
|
+
aseprite-ai-artist bridge Run the WebSocket relay (usually auto-started)
|
|
234
|
+
aseprite-ai-artist install <client…> Write MCP config for an agent
|
|
235
|
+
aseprite-ai-artist install-extension Install the Aseprite Lua extension
|
|
236
|
+
aseprite-ai-artist doctor Diagnose a broken setup
|
|
237
|
+
|
|
238
|
+
Clients: ${CLIENTS.join(", ")}
|
|
239
|
+
|
|
240
|
+
Options:
|
|
241
|
+
--all Install for every supported client
|
|
242
|
+
--project Write project-scoped config instead of user-scoped
|
|
243
|
+
--dir <path> Project directory (default: cwd)
|
|
244
|
+
--agents [path] Also write an AGENTS.md section (default: ./AGENTS.md)
|
|
245
|
+
--aseprite <path> Path to the Aseprite executable
|
|
246
|
+
--allowLua Enable the run_lua escape hatch (arbitrary code in Aseprite)
|
|
247
|
+
--plugin-port <n> Port the Aseprite extension dials (default ${DEFAULT_PLUGIN_PORT})
|
|
248
|
+
--control-port <n> Port MCP servers dial (default ${DEFAULT_CONTROL_PORT})
|
|
249
|
+
--dry-run Print what would change, write nothing
|
|
250
|
+
--version, --help
|
|
251
|
+
|
|
252
|
+
Examples:
|
|
253
|
+
npx @pebbly/aseprite-ai-artist install --all --agents
|
|
254
|
+
npx @pebbly/aseprite-ai-artist install codex cursor --project
|
|
255
|
+
npx @pebbly/aseprite-ai-artist doctor
|
|
256
|
+
`);
|
|
257
|
+
}
|
|
258
|
+
function truthy(value) {
|
|
259
|
+
return value === true || value === "1" || value === "true" || value === "yes";
|
|
260
|
+
}
|
|
261
|
+
function envPort(name, fallback) {
|
|
262
|
+
const raw = process.env[name];
|
|
263
|
+
if (!raw)
|
|
264
|
+
return fallback;
|
|
265
|
+
const parsed = Number(raw);
|
|
266
|
+
return Number.isInteger(parsed) ? parsed : fallback;
|
|
267
|
+
}
|
|
268
|
+
main().catch((err) => {
|
|
269
|
+
process.stderr.write(`${err.stack ?? String(err)}\n`);
|
|
270
|
+
process.exit(1);
|
|
271
|
+
});
|
|
272
|
+
//# sourceMappingURL=cli.js.map
|
package/dist/cli.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Installing the Aseprite side.
|
|
3
|
+
*
|
|
4
|
+
* Aseprite loads extensions from a per-user config directory whose location
|
|
5
|
+
* differs on every platform and moves between the store and standalone builds.
|
|
6
|
+
* Getting this wrong is the single most common reason a setup "does nothing",
|
|
7
|
+
* so the search order is explicit and `doctor` reports what it found.
|
|
8
|
+
*/
|
|
9
|
+
/** Candidate Aseprite user-config directories, most likely first. */
|
|
10
|
+
export declare function asepriteConfigCandidates(): string[];
|
|
11
|
+
export declare function findAsepriteConfigDir(): string | null;
|
|
12
|
+
export interface InstallExtensionOptions {
|
|
13
|
+
dryRun?: boolean;
|
|
14
|
+
/** Override the Aseprite config directory. */
|
|
15
|
+
configDir?: string | undefined;
|
|
16
|
+
}
|
|
17
|
+
export interface InstallExtensionResult {
|
|
18
|
+
target: string;
|
|
19
|
+
files: string[];
|
|
20
|
+
}
|
|
21
|
+
export declare function installExtension(opts?: InstallExtensionOptions): InstallExtensionResult;
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Installing the Aseprite side.
|
|
3
|
+
*
|
|
4
|
+
* Aseprite loads extensions from a per-user config directory whose location
|
|
5
|
+
* differs on every platform and moves between the store and standalone builds.
|
|
6
|
+
* Getting this wrong is the single most common reason a setup "does nothing",
|
|
7
|
+
* so the search order is explicit and `doctor` reports what it found.
|
|
8
|
+
*/
|
|
9
|
+
import { cpSync, existsSync, mkdirSync, readdirSync } from "node:fs";
|
|
10
|
+
import { homedir, platform } from "node:os";
|
|
11
|
+
import path from "node:path";
|
|
12
|
+
import { packageRoot } from "./lib/version.js";
|
|
13
|
+
const EXTENSION_DIR_NAME = "aseprite-ai-artist";
|
|
14
|
+
/** Candidate Aseprite user-config directories, most likely first. */
|
|
15
|
+
export function asepriteConfigCandidates() {
|
|
16
|
+
const home = homedir();
|
|
17
|
+
const env = process.env.ASEPRITE_USER_FOLDER;
|
|
18
|
+
const candidates = [];
|
|
19
|
+
if (env)
|
|
20
|
+
candidates.push(env);
|
|
21
|
+
switch (platform()) {
|
|
22
|
+
case "darwin":
|
|
23
|
+
candidates.push(path.join(home, "Library", "Application Support", "Aseprite"));
|
|
24
|
+
break;
|
|
25
|
+
case "win32": {
|
|
26
|
+
const appData = process.env.APPDATA ?? path.join(home, "AppData", "Roaming");
|
|
27
|
+
candidates.push(path.join(appData, "Aseprite"));
|
|
28
|
+
break;
|
|
29
|
+
}
|
|
30
|
+
default: {
|
|
31
|
+
const xdg = process.env.XDG_CONFIG_HOME ?? path.join(home, ".config");
|
|
32
|
+
candidates.push(path.join(xdg, "aseprite"));
|
|
33
|
+
// Steam and some distro builds keep a dotfile directory instead.
|
|
34
|
+
candidates.push(path.join(home, ".aseprite"));
|
|
35
|
+
break;
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
return candidates;
|
|
39
|
+
}
|
|
40
|
+
export function findAsepriteConfigDir() {
|
|
41
|
+
for (const dir of asepriteConfigCandidates()) {
|
|
42
|
+
if (existsSync(dir))
|
|
43
|
+
return dir;
|
|
44
|
+
}
|
|
45
|
+
return null;
|
|
46
|
+
}
|
|
47
|
+
export function installExtension(opts = {}) {
|
|
48
|
+
const configDir = opts.configDir ?? findAsepriteConfigDir();
|
|
49
|
+
if (!configDir) {
|
|
50
|
+
throw new Error(`Could not find Aseprite's config directory. Looked in:\n ${asepriteConfigCandidates().join("\n ")}\n` +
|
|
51
|
+
`Run Aseprite once so it creates the directory, or pass --dir <path>.`);
|
|
52
|
+
}
|
|
53
|
+
const source = path.join(packageRoot(), "extension");
|
|
54
|
+
if (!existsSync(source)) {
|
|
55
|
+
throw new Error(`Bundled extension is missing from the package at ${source}.`);
|
|
56
|
+
}
|
|
57
|
+
const target = path.join(configDir, "extensions", EXTENSION_DIR_NAME);
|
|
58
|
+
const files = readdirSync(source);
|
|
59
|
+
if (opts.dryRun)
|
|
60
|
+
return { target, files };
|
|
61
|
+
mkdirSync(path.dirname(target), { recursive: true });
|
|
62
|
+
cpSync(source, target, { recursive: true });
|
|
63
|
+
return { target, files };
|
|
64
|
+
}
|
|
65
|
+
//# sourceMappingURL=extension.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"extension.js","sourceRoot":"","sources":["../src/extension.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Client configuration writer.
|
|
3
|
+
*
|
|
4
|
+
* The four target agents disagree on file format (JSON vs TOML), file location,
|
|
5
|
+
* and key names — and getting any of them wrong produces a silent no-op rather
|
|
6
|
+
* than an error. Encoding that here means a user types one command instead of
|
|
7
|
+
* reading four sets of docs.
|
|
8
|
+
*/
|
|
9
|
+
export type ClientId = "claude" | "codex" | "gemini" | "cursor" | "vscode" | "windsurf";
|
|
10
|
+
export declare const CLIENTS: ClientId[];
|
|
11
|
+
export interface InstallOptions {
|
|
12
|
+
scope: "user" | "project";
|
|
13
|
+
projectDir: string;
|
|
14
|
+
command: string;
|
|
15
|
+
args: string[];
|
|
16
|
+
env: Record<string, string>;
|
|
17
|
+
dryRun: boolean;
|
|
18
|
+
}
|
|
19
|
+
export interface InstallResult {
|
|
20
|
+
client: ClientId;
|
|
21
|
+
file: string;
|
|
22
|
+
written: boolean;
|
|
23
|
+
note?: string;
|
|
24
|
+
}
|
|
25
|
+
export declare function configPath(client: ClientId, opts: InstallOptions): string;
|
|
26
|
+
export declare function install(client: ClientId, opts: InstallOptions): InstallResult;
|
|
27
|
+
/**
|
|
28
|
+
* Write AGENTS.md guidance for clients with no plugin or skill system.
|
|
29
|
+
* Returns the block so callers can show it rather than write it.
|
|
30
|
+
*/
|
|
31
|
+
export declare function agentsMarkdown(): string;
|
|
32
|
+
export declare function mergeAgentsFile(target: string, dryRun: boolean): {
|
|
33
|
+
written: boolean;
|
|
34
|
+
file: string;
|
|
35
|
+
};
|
package/dist/install.js
ADDED
|
@@ -0,0 +1,185 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Client configuration writer.
|
|
3
|
+
*
|
|
4
|
+
* The four target agents disagree on file format (JSON vs TOML), file location,
|
|
5
|
+
* and key names — and getting any of them wrong produces a silent no-op rather
|
|
6
|
+
* than an error. Encoding that here means a user types one command instead of
|
|
7
|
+
* reading four sets of docs.
|
|
8
|
+
*/
|
|
9
|
+
import { existsSync, mkdirSync, readFileSync, writeFileSync, copyFileSync, renameSync, unlinkSync } from "node:fs";
|
|
10
|
+
import { homedir } from "node:os";
|
|
11
|
+
import path from "node:path";
|
|
12
|
+
import { packageRoot } from "./lib/version.js";
|
|
13
|
+
export const CLIENTS = ["claude", "codex", "gemini", "cursor", "vscode", "windsurf"];
|
|
14
|
+
export function configPath(client, opts) {
|
|
15
|
+
const home = homedir();
|
|
16
|
+
const project = opts.projectDir;
|
|
17
|
+
switch (client) {
|
|
18
|
+
case "claude":
|
|
19
|
+
return opts.scope === "user"
|
|
20
|
+
? path.join(home, ".claude.json")
|
|
21
|
+
: path.join(project, ".mcp.json");
|
|
22
|
+
case "codex":
|
|
23
|
+
return opts.scope === "user"
|
|
24
|
+
? path.join(home, ".codex", "config.toml")
|
|
25
|
+
: path.join(project, ".codex", "config.toml");
|
|
26
|
+
case "gemini":
|
|
27
|
+
return opts.scope === "user"
|
|
28
|
+
? path.join(home, ".gemini", "settings.json")
|
|
29
|
+
: path.join(project, ".gemini", "settings.json");
|
|
30
|
+
case "cursor":
|
|
31
|
+
return opts.scope === "user"
|
|
32
|
+
? path.join(home, ".cursor", "mcp.json")
|
|
33
|
+
: path.join(project, ".cursor", "mcp.json");
|
|
34
|
+
case "vscode":
|
|
35
|
+
return path.join(project, ".vscode", "mcp.json");
|
|
36
|
+
case "windsurf":
|
|
37
|
+
return path.join(home, ".codeium", "windsurf", "mcp_config.json");
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
const SERVER_KEY = "aseprite-ai-artist";
|
|
41
|
+
export function install(client, opts) {
|
|
42
|
+
const file = configPath(client, opts);
|
|
43
|
+
if (client === "codex")
|
|
44
|
+
return installToml(file, opts);
|
|
45
|
+
return installJson(client, file, opts);
|
|
46
|
+
}
|
|
47
|
+
function installJson(client, file, opts) {
|
|
48
|
+
const existing = readJson(file);
|
|
49
|
+
// VS Code's mcp.json uses `servers`; everyone else uses `mcpServers`.
|
|
50
|
+
const key = client === "vscode" ? "servers" : "mcpServers";
|
|
51
|
+
const servers = existing[key] ?? {};
|
|
52
|
+
const entry = {
|
|
53
|
+
command: opts.command,
|
|
54
|
+
args: opts.args,
|
|
55
|
+
};
|
|
56
|
+
if (Object.keys(opts.env).length > 0)
|
|
57
|
+
entry.env = opts.env;
|
|
58
|
+
// VS Code wants an explicit transport marker.
|
|
59
|
+
if (client === "vscode")
|
|
60
|
+
entry.type = "stdio";
|
|
61
|
+
const next = { ...existing, [key]: { ...servers, [SERVER_KEY]: entry } };
|
|
62
|
+
if (opts.dryRun) {
|
|
63
|
+
return { client, file, written: false, note: JSON.stringify(next[key], null, 2) };
|
|
64
|
+
}
|
|
65
|
+
backup(file);
|
|
66
|
+
writeAtomic(file, JSON.stringify(next, null, 2) + "\n");
|
|
67
|
+
return { client, file, written: true };
|
|
68
|
+
}
|
|
69
|
+
/**
|
|
70
|
+
* Codex uses TOML. Rewriting a whole TOML document without a parser risks
|
|
71
|
+
* mangling comments and unrelated tables, so this only ever appends or replaces
|
|
72
|
+
* the one `[mcp_servers.aseprite-ai-artist]` block and leaves the rest byte
|
|
73
|
+
* for byte as it was.
|
|
74
|
+
*/
|
|
75
|
+
function installToml(file, opts) {
|
|
76
|
+
const header = `[mcp_servers.${SERVER_KEY}]`;
|
|
77
|
+
const lines = [
|
|
78
|
+
header,
|
|
79
|
+
`command = ${tomlString(opts.command)}`,
|
|
80
|
+
`args = [${opts.args.map(tomlString).join(", ")}]`,
|
|
81
|
+
];
|
|
82
|
+
if (Object.keys(opts.env).length > 0) {
|
|
83
|
+
lines.push("");
|
|
84
|
+
lines.push(`[mcp_servers.${SERVER_KEY}.env]`);
|
|
85
|
+
for (const [k, v] of Object.entries(opts.env))
|
|
86
|
+
lines.push(`${k} = ${tomlString(v)}`);
|
|
87
|
+
}
|
|
88
|
+
const block = lines.join("\n") + "\n";
|
|
89
|
+
if (opts.dryRun)
|
|
90
|
+
return { client: "codex", file, written: false, note: block };
|
|
91
|
+
let existing = existsSync(file) ? readFileSync(file, "utf8") : "";
|
|
92
|
+
// Anchored to the start of a line: a bare indexOf would also match the header
|
|
93
|
+
// text inside a comment or a string value and splice around the wrong offset.
|
|
94
|
+
const headerAt = new RegExp(`^\\s*${header.replace(/[.*+?^${}()|[\]\\]/g, "\\$&")}\\s*$`, "m").exec(existing);
|
|
95
|
+
const start = headerAt?.index ?? -1;
|
|
96
|
+
if (start !== -1) {
|
|
97
|
+
// Replace from our header up to the next top-level table that is not ours.
|
|
98
|
+
const rest = existing.slice(start + header.length);
|
|
99
|
+
const nextTable = rest.search(/\n\[(?!mcp_servers\.aseprite-ai-artist)/);
|
|
100
|
+
const end = nextTable === -1 ? existing.length : start + header.length + nextTable + 1;
|
|
101
|
+
existing = existing.slice(0, start) + existing.slice(end);
|
|
102
|
+
}
|
|
103
|
+
backup(file);
|
|
104
|
+
const separator = existing.length > 0 && !existing.endsWith("\n\n") ? "\n" : "";
|
|
105
|
+
writeAtomic(file, existing.trimEnd() + "\n" + separator + block);
|
|
106
|
+
return { client: "codex", file, written: true };
|
|
107
|
+
}
|
|
108
|
+
/**
|
|
109
|
+
* Write AGENTS.md guidance for clients with no plugin or skill system.
|
|
110
|
+
* Returns the block so callers can show it rather than write it.
|
|
111
|
+
*/
|
|
112
|
+
export function agentsMarkdown() {
|
|
113
|
+
const file = path.join(packageRoot(), "templates", "AGENTS.section.md");
|
|
114
|
+
if (existsSync(file))
|
|
115
|
+
return readFileSync(file, "utf8");
|
|
116
|
+
return "";
|
|
117
|
+
}
|
|
118
|
+
export function mergeAgentsFile(target, dryRun) {
|
|
119
|
+
const block = agentsMarkdown();
|
|
120
|
+
const marker = "<!-- aseprite-ai-artist:start -->";
|
|
121
|
+
const endMarker = "<!-- aseprite-ai-artist:end -->";
|
|
122
|
+
const wrapped = `${marker}\n${block.trim()}\n${endMarker}\n`;
|
|
123
|
+
let content = existsSync(target) ? readFileSync(target, "utf8") : "";
|
|
124
|
+
const start = content.indexOf(marker);
|
|
125
|
+
if (start !== -1) {
|
|
126
|
+
const end = content.indexOf(endMarker);
|
|
127
|
+
if (end !== -1)
|
|
128
|
+
content = content.slice(0, start) + content.slice(end + endMarker.length + 1);
|
|
129
|
+
}
|
|
130
|
+
const next = content.trimEnd() + (content.trim() ? "\n\n" : "") + wrapped;
|
|
131
|
+
if (dryRun)
|
|
132
|
+
return { written: false, file: target };
|
|
133
|
+
backup(target);
|
|
134
|
+
writeAtomic(target, next);
|
|
135
|
+
return { written: true, file: target };
|
|
136
|
+
}
|
|
137
|
+
function readJson(file) {
|
|
138
|
+
if (!existsSync(file))
|
|
139
|
+
return {};
|
|
140
|
+
try {
|
|
141
|
+
const parsed = JSON.parse(readFileSync(file, "utf8"));
|
|
142
|
+
return typeof parsed === "object" && parsed !== null ? parsed : {};
|
|
143
|
+
}
|
|
144
|
+
catch (err) {
|
|
145
|
+
throw new Error(`${file} is not valid JSON, so it cannot be edited safely. Fix or move it, then retry. (${err.message})`);
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
/**
|
|
149
|
+
* Write through a sibling temp file and rename over the target.
|
|
150
|
+
*
|
|
151
|
+
* `~/.claude.json` is ~128KB and holds Claude Code's own project list, session
|
|
152
|
+
* and auth state. A plain writeFileSync that dies part-way — full disk, killed
|
|
153
|
+
* process — leaves that truncated and the user's whole setup broken. A rename
|
|
154
|
+
* on the same filesystem is atomic, so the file is either the old one or the
|
|
155
|
+
* new one, never half of either.
|
|
156
|
+
*/
|
|
157
|
+
function writeAtomic(file, contents) {
|
|
158
|
+
const dir = path.dirname(file);
|
|
159
|
+
mkdirSync(dir, { recursive: true });
|
|
160
|
+
const temp = path.join(dir, `.${path.basename(file)}.${process.pid}.tmp`);
|
|
161
|
+
try {
|
|
162
|
+
writeFileSync(temp, contents, "utf8");
|
|
163
|
+
renameSync(temp, file);
|
|
164
|
+
}
|
|
165
|
+
catch (err) {
|
|
166
|
+
try {
|
|
167
|
+
unlinkSync(temp);
|
|
168
|
+
}
|
|
169
|
+
catch {
|
|
170
|
+
/* the temp file may never have been created */
|
|
171
|
+
}
|
|
172
|
+
throw err;
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
/** Never overwrite someone's config without leaving them a way back. */
|
|
176
|
+
function backup(file) {
|
|
177
|
+
if (!existsSync(file))
|
|
178
|
+
return;
|
|
179
|
+
const stamp = new Date().toISOString().replace(/[:.]/g, "-");
|
|
180
|
+
copyFileSync(file, `${file}.bak-${stamp}`);
|
|
181
|
+
}
|
|
182
|
+
function tomlString(value) {
|
|
183
|
+
return `"${value.replace(/\\/g, "\\\\").replace(/"/g, '\\"')}"`;
|
|
184
|
+
}
|
|
185
|
+
//# sourceMappingURL=install.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"install.js","sourceRoot":"","sources":["../src/install.ts"],"names":[],"mappings":"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"}
|