motion-cart 0.1.4 → 0.1.5

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.
Files changed (3) hide show
  1. package/README.md +18 -7
  2. package/dist/index.js +60 -5
  3. package/package.json +1 -1
package/README.md CHANGED
@@ -18,19 +18,30 @@ target, and a Claude agent edits your real source while the preview hot-reloads.
18
18
  ## Model provider (auth)
19
19
 
20
20
  By default the agent uses your existing **Claude Code login** (no key needed). You can instead
21
- point it at **any Anthropic-compatible gateway** — including **iO Bonzai** — with your own key:
21
+ point it at **any Anthropic-compatible gateway** — including **iO Bonzai** — with your own key.
22
+
23
+ **Set it once** (saved to `~/.motion-cart/config.json`, chmod 600) and every run reuses it:
24
+
25
+ ```bash
26
+ npx motion-cart config --base-url https://api-v2.bonzai.iodigital.com \
27
+ --api-key <your-bonzai-key> --model claude-4-5-sonnet
28
+ # then just:
29
+ npx motion-cart --target . --dev-url http://localhost:5173
30
+
31
+ npx motion-cart config # show current provider (key redacted)
32
+ npx motion-cart config --clear # reset to the Claude Code login
33
+ ```
34
+
35
+ Or pass per-run flags (these + `MOTION_CART_*` env override the saved config):
22
36
 
23
37
  ```bash
24
38
  npx motion-cart --target . --dev-url http://localhost:5173 \
25
- --base-url https://api-v2.bonzai.iodigital.com \
26
- --api-key <your-bonzai-key> \
27
- --model claude-4-5-sonnet
39
+ --base-url https://api-v2.bonzai.iodigital.com --api-key <key> --model claude-4-5-sonnet
28
40
  ```
29
41
 
30
42
  `--base-url`/`--api-key`/`--model` map to `ANTHROPIC_BASE_URL` / `ANTHROPIC_AUTH_TOKEN` / model for
31
- the agent (env equivalents: `MOTION_CART_BASE_URL` / `MOTION_CART_API_KEY` / `MOTION_CART_MODEL`).
32
- The gateway must expose the Anthropic **Messages** route (`<base-url>/v1/messages`) LiteLLM-based
33
- gateways like Bonzai do; a purely OpenAI-shaped endpoint won't work.
43
+ the agent. The gateway must expose the Anthropic **Messages** route (`<base-url>/v1/messages`)
44
+ LiteLLM-based gateways like Bonzai do; a purely OpenAI-shaped endpoint won't work.
34
45
 
35
46
  > Auth gotcha: an invalid `ANTHROPIC_API_KEY` in your shell **overrides** your Claude login and
36
47
  > causes `401 Invalid bearer token`. `unset` it, or pass `--api-key`/`--base-url` explicitly.
package/dist/index.js CHANGED
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env node
2
2
 
3
3
  // src/index.ts
4
- import path5 from "path";
4
+ import path6 from "path";
5
5
 
6
6
  // ../core/dist/chunk-YCZ2J2MA.js
7
7
  var MENU_GROUPS = [
@@ -1438,6 +1438,43 @@ function startControlServer(cfg, port2) {
1438
1438
  return { server, url: panelOrigin };
1439
1439
  }
1440
1440
 
1441
+ // src/config.ts
1442
+ import { promises as fs3 } from "fs";
1443
+ import os from "os";
1444
+ import path5 from "path";
1445
+ var DIR = path5.join(os.homedir(), ".motion-cart");
1446
+ var FILE = path5.join(DIR, "config.json");
1447
+ function configPath() {
1448
+ return FILE;
1449
+ }
1450
+ async function loadConfig() {
1451
+ try {
1452
+ return JSON.parse(await fs3.readFile(FILE, "utf8"));
1453
+ } catch {
1454
+ return {};
1455
+ }
1456
+ }
1457
+ async function saveConfig(patch) {
1458
+ const current = await loadConfig();
1459
+ const merged = { ...current };
1460
+ for (const [k, v] of Object.entries(patch)) {
1461
+ if (v != null && v !== "") merged[k] = v;
1462
+ }
1463
+ await fs3.mkdir(DIR, { recursive: true });
1464
+ await fs3.writeFile(FILE, JSON.stringify(merged, null, 2), { mode: 384 });
1465
+ try {
1466
+ await fs3.chmod(FILE, 384);
1467
+ } catch {
1468
+ }
1469
+ return merged;
1470
+ }
1471
+ async function clearConfig() {
1472
+ try {
1473
+ await fs3.rm(FILE);
1474
+ } catch {
1475
+ }
1476
+ }
1477
+
1441
1478
  // src/index.ts
1442
1479
  function arg(name, fallback) {
1443
1480
  const i = process.argv.indexOf(`--${name}`);
@@ -1447,20 +1484,38 @@ function arg(name, fallback) {
1447
1484
  }
1448
1485
  return fallback;
1449
1486
  }
1487
+ async function runConfig() {
1488
+ if (process.argv.includes("--clear")) {
1489
+ await clearConfig();
1490
+ console.log("motion-cart: provider config cleared.");
1491
+ return;
1492
+ }
1493
+ const patch = { baseUrl: arg("base-url"), apiKey: arg("api-key"), model: arg("model") };
1494
+ const cfg = Object.values(patch).some((v) => v) ? await saveConfig(patch) : await loadConfig();
1495
+ const key = cfg.apiKey ? `${cfg.apiKey.slice(0, 6)}\u2026 (set)` : "(unset)";
1496
+ console.log(`motion-cart provider config \u2014 ${configPath()}`);
1497
+ console.log(` base-url ${cfg.baseUrl || "(unset \u2192 Claude Code login)"}`);
1498
+ console.log(` api-key ${key}`);
1499
+ console.log(` model ${cfg.model || "(default)"}`);
1500
+ console.log(`
1501
+ Flags and MOTION_CART_* env vars override these per run.`);
1502
+ }
1450
1503
  function port(name, def) {
1451
1504
  const v = Number(arg(name, String(def)));
1452
1505
  return Number.isInteger(v) && v > 0 && v < 65536 ? v : def;
1453
1506
  }
1454
1507
  var LOOPBACK = /* @__PURE__ */ new Set(["localhost", "127.0.0.1", "0.0.0.0", "[::1]", "::1"]);
1455
1508
  async function main() {
1456
- const target = path5.resolve(arg("target", process.cwd()));
1509
+ if (process.argv[2] === "config") return runConfig();
1510
+ const saved = await loadConfig();
1511
+ const target = path6.resolve(arg("target", process.cwd()));
1457
1512
  const devUrl = arg("dev-url");
1458
1513
  const panelPort = port("port", 7100);
1459
1514
  const proxyPort = port("proxy-port", 7101);
1460
1515
  const token = arg("token", process.env.MOTION_PLUS_TOKEN);
1461
- const baseUrl = arg("base-url", process.env.MOTION_CART_BASE_URL);
1462
- const apiKey = arg("api-key", process.env.MOTION_CART_API_KEY);
1463
- const model = arg("model", process.env.MOTION_CART_MODEL);
1516
+ const baseUrl = arg("base-url", process.env.MOTION_CART_BASE_URL ?? saved.baseUrl);
1517
+ const apiKey = arg("api-key", process.env.MOTION_CART_API_KEY ?? saved.apiKey);
1518
+ const model = arg("model", process.env.MOTION_CART_MODEL ?? saved.model);
1464
1519
  if (!devUrl) {
1465
1520
  console.error(
1466
1521
  "Usage: motion-cart --dev-url <url> [--target <dir>] [--port 7100] [--proxy-port 7101] [--token <motion+ token>]\n --dev-url URL of your already-running LOCAL dev server (e.g. http://localhost:5173)\n --target project directory the agent will edit (default: cwd)"
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "motion-cart",
3
- "version": "0.1.4",
3
+ "version": "0.1.5",
4
4
  "description": "Shop for animations and let an AI agent add them to any React/Next/Vue/JS project — via an injecting dev proxy + element picker.",
5
5
  "keywords": ["motion", "animation", "ai", "agent", "framer-motion", "cli", "devtool"],
6
6
  "license": "MIT",