pixelmuse 0.2.0 → 0.3.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/README.md
CHANGED
|
@@ -29,19 +29,14 @@
|
|
|
29
29
|
- **Built for developer workflows.** Pipe from stdin, JSON output for scripting, watch mode for prompt iteration, MCP server for AI agents.
|
|
30
30
|
- **Predictable credit pricing.** 1-3 credits per generation, no surprises. Free credits on signup.
|
|
31
31
|
|
|
32
|
-
##
|
|
32
|
+
## Get Started
|
|
33
33
|
|
|
34
34
|
```bash
|
|
35
35
|
npm install -g pixelmuse
|
|
36
|
+
pixelmuse setup
|
|
36
37
|
```
|
|
37
38
|
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
```bash
|
|
41
|
-
pixelmuse login
|
|
42
|
-
```
|
|
43
|
-
|
|
44
|
-
Sign up at [pixelmuse.studio/sign-up](https://www.pixelmuse.studio/sign-up) — new accounts include free credits.
|
|
39
|
+
The setup wizard creates your account (opens browser), configures your API key, and optionally sets up the MCP server for Claude Code, Cursor, or Windsurf. New accounts include **15 free credits**.
|
|
45
40
|
|
|
46
41
|
> Requires Node.js 20+. For terminal image previews, install [chafa](https://hpjansson.org/chafa/) (`brew install chafa` / `sudo apt install chafa`).
|
|
47
42
|
|
|
@@ -212,6 +207,7 @@ Pixelmuse ships four interfaces. Pick the one that fits your workflow — they a
|
|
|
212
207
|
|
|
213
208
|
| Command | Description |
|
|
214
209
|
|---------|-------------|
|
|
210
|
+
| `pixelmuse setup` | First-time setup wizard (account, MCP, defaults) |
|
|
215
211
|
| `pixelmuse "prompt"` | Generate an image (default command) |
|
|
216
212
|
| `pixelmuse models` | List available models with costs |
|
|
217
213
|
| `pixelmuse account` | Account balance and usage stats |
|
|
@@ -4,9 +4,6 @@ import {
|
|
|
4
4
|
ensureDirs
|
|
5
5
|
} from "./chunk-7ARYEFAH.js";
|
|
6
6
|
|
|
7
|
-
// src/core/client.ts
|
|
8
|
-
import { createRequire } from "module";
|
|
9
|
-
|
|
10
7
|
// src/core/types.ts
|
|
11
8
|
var ApiError = class extends Error {
|
|
12
9
|
constructor(message, status, code, rateLimitRemaining, retryAfter) {
|
|
@@ -20,8 +17,7 @@ var ApiError = class extends Error {
|
|
|
20
17
|
};
|
|
21
18
|
|
|
22
19
|
// src/core/client.ts
|
|
23
|
-
var
|
|
24
|
-
var CLI_VERSION = require2("../../package.json").version;
|
|
20
|
+
var CLI_VERSION = "0.3.0";
|
|
25
21
|
var BASE_URL = "https://www.pixelmuse.studio/api/v1";
|
|
26
22
|
var CLIENT_HEADERS = {
|
|
27
23
|
"User-Agent": `pixelmuse-cli/${CLI_VERSION}`,
|
package/dist/cli.js
CHANGED
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import {
|
|
3
3
|
generateImage
|
|
4
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-4DZUZTTL.js";
|
|
5
5
|
import {
|
|
6
|
+
CLI_VERSION,
|
|
6
7
|
PixelmuseClient,
|
|
7
8
|
deleteApiKey,
|
|
8
9
|
extractVariables,
|
|
@@ -14,19 +15,20 @@ import {
|
|
|
14
15
|
saveApiKey,
|
|
15
16
|
saveTemplate,
|
|
16
17
|
slugify
|
|
17
|
-
} from "./chunk-
|
|
18
|
+
} from "./chunk-H6VI5DLX.js";
|
|
18
19
|
import {
|
|
19
20
|
renderImageDirect
|
|
20
21
|
} from "./chunk-MZZY4JXW.js";
|
|
21
22
|
import {
|
|
22
|
-
readSettings
|
|
23
|
+
readSettings,
|
|
24
|
+
writeSettings
|
|
23
25
|
} from "./chunk-7ARYEFAH.js";
|
|
24
26
|
|
|
25
27
|
// src/cli.ts
|
|
26
28
|
import meow from "meow";
|
|
27
29
|
import chalk from "chalk";
|
|
28
30
|
import ora from "ora";
|
|
29
|
-
import { readFileSync, watchFile, unwatchFile } from "fs";
|
|
31
|
+
import { readFileSync as readFileSync2, watchFile, unwatchFile } from "fs";
|
|
30
32
|
import { resolve } from "path";
|
|
31
33
|
|
|
32
34
|
// src/core/utils.ts
|
|
@@ -39,6 +41,128 @@ function timeAgo(date) {
|
|
|
39
41
|
return date.toLocaleDateString();
|
|
40
42
|
}
|
|
41
43
|
|
|
44
|
+
// src/core/device-auth.ts
|
|
45
|
+
var BASE_URL = "https://www.pixelmuse.studio/api/v1";
|
|
46
|
+
async function initiateDeviceAuth() {
|
|
47
|
+
const res = await fetch(`${BASE_URL}/auth/device`, {
|
|
48
|
+
method: "POST",
|
|
49
|
+
headers: {
|
|
50
|
+
"Content-Type": "application/json",
|
|
51
|
+
"User-Agent": `pixelmuse-cli/${CLI_VERSION}`
|
|
52
|
+
},
|
|
53
|
+
body: JSON.stringify({
|
|
54
|
+
client_info: {
|
|
55
|
+
platform: process.platform,
|
|
56
|
+
cli_version: CLI_VERSION
|
|
57
|
+
}
|
|
58
|
+
})
|
|
59
|
+
});
|
|
60
|
+
if (!res.ok) {
|
|
61
|
+
const body = await res.text().catch(() => "");
|
|
62
|
+
throw new Error(`Failed to initiate device auth (HTTP ${res.status}): ${body}`);
|
|
63
|
+
}
|
|
64
|
+
const data = await res.json();
|
|
65
|
+
return {
|
|
66
|
+
deviceCode: data.device_code,
|
|
67
|
+
userCode: data.user_code,
|
|
68
|
+
verificationUri: data.verification_uri,
|
|
69
|
+
verificationUriComplete: data.verification_uri_complete,
|
|
70
|
+
expiresIn: data.expires_in,
|
|
71
|
+
interval: data.interval
|
|
72
|
+
};
|
|
73
|
+
}
|
|
74
|
+
async function pollForToken(deviceCode, options) {
|
|
75
|
+
const deadline = Date.now() + options.expiresIn * 1e3;
|
|
76
|
+
let intervalMs = options.interval * 1e3;
|
|
77
|
+
while (Date.now() < deadline) {
|
|
78
|
+
await new Promise((r) => setTimeout(r, intervalMs));
|
|
79
|
+
options.onPoll?.();
|
|
80
|
+
try {
|
|
81
|
+
const res = await fetch(`${BASE_URL}/auth/device/token`, {
|
|
82
|
+
method: "POST",
|
|
83
|
+
headers: {
|
|
84
|
+
"Content-Type": "application/json",
|
|
85
|
+
"User-Agent": `pixelmuse-cli/${CLI_VERSION}`
|
|
86
|
+
},
|
|
87
|
+
body: JSON.stringify({
|
|
88
|
+
device_code: deviceCode,
|
|
89
|
+
grant_type: "urn:ietf:params:oauth:grant-type:device_code"
|
|
90
|
+
})
|
|
91
|
+
});
|
|
92
|
+
const data = await res.json();
|
|
93
|
+
if (data.api_key) {
|
|
94
|
+
return {
|
|
95
|
+
apiKey: data.api_key,
|
|
96
|
+
keyPrefix: data.key_prefix
|
|
97
|
+
};
|
|
98
|
+
}
|
|
99
|
+
if (data.error === "slow_down") {
|
|
100
|
+
intervalMs = (data.interval ?? 10) * 1e3;
|
|
101
|
+
continue;
|
|
102
|
+
}
|
|
103
|
+
if (data.error === "expired_token") {
|
|
104
|
+
throw new Error("Authorization timed out. Run `pixelmuse setup` to try again.");
|
|
105
|
+
}
|
|
106
|
+
if (data.error === "access_denied") {
|
|
107
|
+
throw new Error("Authorization was denied.");
|
|
108
|
+
}
|
|
109
|
+
} catch (err) {
|
|
110
|
+
if (err instanceof Error && (err.message.includes("timed out") || err.message.includes("denied"))) {
|
|
111
|
+
throw err;
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
throw new Error("Authorization timed out. Run `pixelmuse setup` to try again.");
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
// src/core/mcp-config.ts
|
|
119
|
+
import { existsSync, readFileSync, writeFileSync, mkdirSync } from "fs";
|
|
120
|
+
import { dirname, join } from "path";
|
|
121
|
+
import { homedir } from "os";
|
|
122
|
+
var HOME = homedir();
|
|
123
|
+
var EDITORS = [
|
|
124
|
+
{
|
|
125
|
+
name: "Claude Code",
|
|
126
|
+
id: "claude-code",
|
|
127
|
+
configPath: join(HOME, ".claude", "mcp.json")
|
|
128
|
+
},
|
|
129
|
+
{
|
|
130
|
+
name: "Cursor",
|
|
131
|
+
id: "cursor",
|
|
132
|
+
configPath: join(HOME, ".cursor", "mcp.json")
|
|
133
|
+
},
|
|
134
|
+
{
|
|
135
|
+
name: "Windsurf",
|
|
136
|
+
id: "windsurf",
|
|
137
|
+
configPath: join(HOME, ".codeium", "windsurf", "mcp_config.json")
|
|
138
|
+
}
|
|
139
|
+
];
|
|
140
|
+
function detectEditors() {
|
|
141
|
+
return EDITORS.map((editor) => ({
|
|
142
|
+
...editor,
|
|
143
|
+
installed: existsSync(dirname(editor.configPath))
|
|
144
|
+
}));
|
|
145
|
+
}
|
|
146
|
+
function configureMcp(editor, apiKey) {
|
|
147
|
+
const entry = {
|
|
148
|
+
command: "npx",
|
|
149
|
+
args: ["-y", "pixelmuse-mcp"],
|
|
150
|
+
env: { PIXELMUSE_API_KEY: apiKey }
|
|
151
|
+
};
|
|
152
|
+
let config = {};
|
|
153
|
+
if (existsSync(editor.configPath)) {
|
|
154
|
+
try {
|
|
155
|
+
config = JSON.parse(readFileSync(editor.configPath, "utf-8"));
|
|
156
|
+
} catch {
|
|
157
|
+
}
|
|
158
|
+
} else {
|
|
159
|
+
mkdirSync(dirname(editor.configPath), { recursive: true });
|
|
160
|
+
}
|
|
161
|
+
config.mcpServers = config.mcpServers ?? {};
|
|
162
|
+
config.mcpServers.pixelmuse = entry;
|
|
163
|
+
writeFileSync(editor.configPath, JSON.stringify(config, null, 2) + "\n", "utf-8");
|
|
164
|
+
}
|
|
165
|
+
|
|
42
166
|
// src/cli.ts
|
|
43
167
|
var cli = meow(
|
|
44
168
|
`
|
|
@@ -50,6 +174,7 @@ var cli = meow(
|
|
|
50
174
|
$ echo "prompt" | pixelmuse Pipe from stdin
|
|
51
175
|
|
|
52
176
|
${chalk.bold("Commands")}
|
|
177
|
+
pixelmuse setup First-time setup wizard
|
|
53
178
|
pixelmuse models List available models
|
|
54
179
|
pixelmuse account View balance & usage
|
|
55
180
|
pixelmuse history Recent generations
|
|
@@ -220,7 +345,7 @@ async function handleWatch(filePath) {
|
|
|
220
345
|
const generate = async () => {
|
|
221
346
|
if (generating) return;
|
|
222
347
|
generating = true;
|
|
223
|
-
const prompt =
|
|
348
|
+
const prompt = readFileSync2(absPath, "utf-8").trim();
|
|
224
349
|
if (!prompt) {
|
|
225
350
|
generating = false;
|
|
226
351
|
return;
|
|
@@ -333,9 +458,9 @@ async function handleOpen(id) {
|
|
|
333
458
|
if (gen.output?.[0]) {
|
|
334
459
|
const { imageToBuffer: imageToBuffer2, saveImage: saveImage2 } = await import("./image-2H3GUQI6.js");
|
|
335
460
|
const { PATHS: PATHS2 } = await import("./config-RMVFR3GN.js");
|
|
336
|
-
const { join } = await import("path");
|
|
461
|
+
const { join: join2 } = await import("path");
|
|
337
462
|
const buf = await imageToBuffer2(gen.output[0]);
|
|
338
|
-
const path =
|
|
463
|
+
const path = join2(PATHS2.generations, `${gen.id}.png`);
|
|
339
464
|
saveImage2(buf, path);
|
|
340
465
|
const { default: open } = await import("open");
|
|
341
466
|
await open(path);
|
|
@@ -349,10 +474,53 @@ async function handleOpen(id) {
|
|
|
349
474
|
}
|
|
350
475
|
}
|
|
351
476
|
async function handleLogin() {
|
|
477
|
+
console.log(chalk.bold("Pixelmuse Login"));
|
|
478
|
+
console.log();
|
|
479
|
+
const spinner = ora("Preparing login...").start();
|
|
480
|
+
try {
|
|
481
|
+
const init = await initiateDeviceAuth();
|
|
482
|
+
spinner.stop();
|
|
483
|
+
console.log(` Your code: ${chalk.bold.cyan(init.userCode)}`);
|
|
484
|
+
console.log();
|
|
485
|
+
console.log(` Opening ${chalk.underline(init.verificationUriComplete)}`);
|
|
486
|
+
console.log(` ${chalk.gray("Or visit")} ${chalk.underline(init.verificationUri)} ${chalk.gray("and enter the code manually")}`);
|
|
487
|
+
console.log();
|
|
488
|
+
const { default: open } = await import("open");
|
|
489
|
+
await open(init.verificationUriComplete);
|
|
490
|
+
const pollSpinner = ora("Waiting for authorization...").start();
|
|
491
|
+
let dots = 0;
|
|
492
|
+
const result = await pollForToken(init.deviceCode, {
|
|
493
|
+
interval: init.interval,
|
|
494
|
+
expiresIn: init.expiresIn,
|
|
495
|
+
onPoll: () => {
|
|
496
|
+
dots = (dots + 1) % 4;
|
|
497
|
+
pollSpinner.text = `Waiting for authorization${".".repeat(dots)}`;
|
|
498
|
+
}
|
|
499
|
+
});
|
|
500
|
+
await saveApiKey(result.apiKey);
|
|
501
|
+
pollSpinner.stop();
|
|
502
|
+
const client = new PixelmuseClient(result.apiKey);
|
|
503
|
+
const account = await client.getAccount();
|
|
504
|
+
console.log(chalk.green("\u2713") + ` Authenticated as ${chalk.bold(account.email)} (${chalk.green(`${account.credits.total} credits`)})`);
|
|
505
|
+
return result.apiKey;
|
|
506
|
+
} catch (err) {
|
|
507
|
+
spinner.stop();
|
|
508
|
+
if (err instanceof Error && !err.message.includes("timed out") && !err.message.includes("denied")) {
|
|
509
|
+
console.log(chalk.gray("Browser login unavailable. Enter your API key manually."));
|
|
510
|
+
} else if (err instanceof Error) {
|
|
511
|
+
console.log(chalk.yellow(err.message));
|
|
512
|
+
}
|
|
513
|
+
return handleManualLogin();
|
|
514
|
+
}
|
|
515
|
+
}
|
|
516
|
+
async function handleManualLogin() {
|
|
517
|
+
console.log();
|
|
518
|
+
console.log(` Get your key at: ${chalk.underline("https://www.pixelmuse.studio/settings/api-keys")}`);
|
|
519
|
+
console.log();
|
|
352
520
|
const { createInterface } = await import("readline");
|
|
353
521
|
const rl = createInterface({ input: process.stdin, output: process.stdout });
|
|
354
522
|
const key = await new Promise((resolve2) => {
|
|
355
|
-
rl.question("API key
|
|
523
|
+
rl.question("API key: ", (answer) => {
|
|
356
524
|
rl.close();
|
|
357
525
|
resolve2(answer.trim());
|
|
358
526
|
});
|
|
@@ -367,11 +535,103 @@ async function handleLogin() {
|
|
|
367
535
|
const account = await client.getAccount();
|
|
368
536
|
await saveApiKey(key);
|
|
369
537
|
spinner.succeed(`Authenticated as ${chalk.bold(account.email)} (${chalk.green(`${account.credits.total} credits`)})`);
|
|
538
|
+
return key;
|
|
370
539
|
} catch (err) {
|
|
371
540
|
spinner.fail(err instanceof Error ? err.message : "Authentication failed");
|
|
372
541
|
process.exit(1);
|
|
373
542
|
}
|
|
374
543
|
}
|
|
544
|
+
async function handleSetup() {
|
|
545
|
+
console.log();
|
|
546
|
+
console.log(chalk.bold(" Pixelmuse Setup"));
|
|
547
|
+
console.log(chalk.gray(" AI image generation from the terminal"));
|
|
548
|
+
console.log();
|
|
549
|
+
const existingKey = await getApiKey();
|
|
550
|
+
let apiKey;
|
|
551
|
+
if (existingKey) {
|
|
552
|
+
const spinner = ora("Checking existing credentials...").start();
|
|
553
|
+
try {
|
|
554
|
+
const client = new PixelmuseClient(existingKey);
|
|
555
|
+
const account = await client.getAccount();
|
|
556
|
+
spinner.succeed(`Already authenticated as ${chalk.bold(account.email)} (${chalk.green(`${account.credits.total} credits`)})`);
|
|
557
|
+
apiKey = existingKey;
|
|
558
|
+
} catch {
|
|
559
|
+
spinner.warn("Existing credentials invalid. Re-authenticating...");
|
|
560
|
+
apiKey = await handleLogin();
|
|
561
|
+
}
|
|
562
|
+
} else {
|
|
563
|
+
console.log(chalk.bold("Step 1:") + " Authenticate");
|
|
564
|
+
console.log();
|
|
565
|
+
apiKey = await handleLogin();
|
|
566
|
+
}
|
|
567
|
+
console.log();
|
|
568
|
+
const editors = detectEditors();
|
|
569
|
+
const available = editors.filter((e) => e.installed);
|
|
570
|
+
if (available.length > 0) {
|
|
571
|
+
console.log(chalk.bold("Step 2:") + " MCP Server (AI agent integration)");
|
|
572
|
+
console.log();
|
|
573
|
+
const { createInterface } = await import("readline");
|
|
574
|
+
for (const editor of available) {
|
|
575
|
+
const rl2 = createInterface({ input: process.stdin, output: process.stdout });
|
|
576
|
+
const answer = await new Promise((resolve2) => {
|
|
577
|
+
rl2.question(` Configure ${chalk.bold(editor.name)}? ${chalk.gray("[Y/n]")} `, (a) => {
|
|
578
|
+
rl2.close();
|
|
579
|
+
resolve2(a.trim().toLowerCase());
|
|
580
|
+
});
|
|
581
|
+
});
|
|
582
|
+
if (answer === "" || answer === "y" || answer === "yes") {
|
|
583
|
+
configureMcp(editor, apiKey);
|
|
584
|
+
console.log(chalk.green(" \u2713") + ` ${editor.name} MCP configured`);
|
|
585
|
+
} else {
|
|
586
|
+
console.log(chalk.gray(` Skipped ${editor.name}`));
|
|
587
|
+
}
|
|
588
|
+
}
|
|
589
|
+
console.log();
|
|
590
|
+
}
|
|
591
|
+
console.log(chalk.bold(available.length > 0 ? "Step 3:" : "Step 2:") + " Defaults");
|
|
592
|
+
console.log();
|
|
593
|
+
const { createInterface: createRl } = await import("readline");
|
|
594
|
+
const rl = createRl({ input: process.stdin, output: process.stdout });
|
|
595
|
+
const customize = await new Promise((resolve2) => {
|
|
596
|
+
rl.question(` Customize default model and settings? ${chalk.gray("[y/N]")} `, (a) => {
|
|
597
|
+
rl.close();
|
|
598
|
+
resolve2(a.trim().toLowerCase());
|
|
599
|
+
});
|
|
600
|
+
});
|
|
601
|
+
if (customize === "y" || customize === "yes") {
|
|
602
|
+
const settings = readSettings();
|
|
603
|
+
const updated = {};
|
|
604
|
+
const models = ["nano-banana-2", "nano-banana-pro", "flux-schnell", "imagen-3", "recraft-v4", "recraft-v4-pro"];
|
|
605
|
+
const aspects = ["1:1", "16:9", "9:16", "4:3", "3:4", "21:9"];
|
|
606
|
+
const styles = ["none", "realistic", "anime", "artistic"];
|
|
607
|
+
const pick = async (label, options, current) => {
|
|
608
|
+
const { createInterface } = await import("readline");
|
|
609
|
+
const rl2 = createInterface({ input: process.stdin, output: process.stdout });
|
|
610
|
+
console.log(` ${label}: ${options.map((o) => o === current ? chalk.bold.cyan(o) : chalk.gray(o)).join(" | ")}`);
|
|
611
|
+
const answer = await new Promise((resolve2) => {
|
|
612
|
+
rl2.question(` Choice ${chalk.gray(`[${current}]`)}: `, (a) => {
|
|
613
|
+
rl2.close();
|
|
614
|
+
resolve2(a.trim() || current);
|
|
615
|
+
});
|
|
616
|
+
});
|
|
617
|
+
return options.includes(answer) ? answer : current;
|
|
618
|
+
};
|
|
619
|
+
updated.defaultModel = await pick("Model", models, settings.defaultModel);
|
|
620
|
+
updated.defaultAspectRatio = await pick("Aspect ratio", aspects, settings.defaultAspectRatio);
|
|
621
|
+
updated.defaultStyle = await pick("Style", styles, settings.defaultStyle);
|
|
622
|
+
writeSettings({ ...settings, ...updated });
|
|
623
|
+
console.log(chalk.green(" \u2713") + " Defaults saved");
|
|
624
|
+
} else {
|
|
625
|
+
console.log(chalk.gray(" Using defaults (nano-banana-2, 1:1, no style)"));
|
|
626
|
+
}
|
|
627
|
+
console.log();
|
|
628
|
+
console.log(chalk.green.bold(" Setup complete!"));
|
|
629
|
+
console.log();
|
|
630
|
+
console.log(` Try it: ${chalk.cyan('pixelmuse "a cat floating through space"')}`);
|
|
631
|
+
console.log(` TUI: ${chalk.cyan("pixelmuse ui")}`);
|
|
632
|
+
console.log(` Help: ${chalk.cyan("pixelmuse --help")}`);
|
|
633
|
+
console.log();
|
|
634
|
+
}
|
|
375
635
|
async function handleTemplate() {
|
|
376
636
|
const [, templateCmd, ...templateArgs] = cli.input;
|
|
377
637
|
switch (templateCmd) {
|
|
@@ -490,8 +750,11 @@ async function main() {
|
|
|
490
750
|
process.exit(1);
|
|
491
751
|
}
|
|
492
752
|
return handleOpen(rest[0]);
|
|
753
|
+
case "setup":
|
|
754
|
+
return handleSetup();
|
|
493
755
|
case "login":
|
|
494
|
-
|
|
756
|
+
await handleLogin();
|
|
757
|
+
return;
|
|
495
758
|
case "logout":
|
|
496
759
|
await deleteApiKey();
|
|
497
760
|
console.log("Logged out.");
|
package/dist/mcp/server.js
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import {
|
|
3
3
|
generateImage
|
|
4
|
-
} from "../chunk-
|
|
4
|
+
} from "../chunk-4DZUZTTL.js";
|
|
5
5
|
import {
|
|
6
6
|
CLI_VERSION,
|
|
7
7
|
PixelmuseClient,
|
|
8
8
|
getApiKey
|
|
9
|
-
} from "../chunk-
|
|
9
|
+
} from "../chunk-H6VI5DLX.js";
|
|
10
10
|
import "../chunk-MZZY4JXW.js";
|
|
11
11
|
import {
|
|
12
12
|
readSettings
|
package/dist/tui.js
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "pixelmuse",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.3.0",
|
|
4
4
|
"description": "AI image generation from the terminal — CLI, TUI, and MCP server for text-to-image with Flux, Imagen, Recraft, and more",
|
|
5
5
|
"homepage": "https://pixelmuse.studio",
|
|
6
6
|
"repository": {
|