@impractical-ai/motion 0.1.3 → 0.1.4

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.
@@ -0,0 +1,30 @@
1
+ #!/usr/bin/env node
2
+ import {
3
+ ApiContractError,
4
+ ApiError,
5
+ admitMcpCall,
6
+ delay,
7
+ invoke,
8
+ invokeAt,
9
+ jobStatus,
10
+ studioLink,
11
+ validateApiResponse,
12
+ waitForJobs,
13
+ withAdmissionReceipt,
14
+ withMeteredCall
15
+ } from "./chunk-M77TS5RO.js";
16
+ import "./chunk-EFP4P3WA.js";
17
+ export {
18
+ ApiContractError,
19
+ ApiError,
20
+ admitMcpCall,
21
+ delay,
22
+ invoke,
23
+ invokeAt,
24
+ jobStatus,
25
+ studioLink,
26
+ validateApiResponse,
27
+ waitForJobs,
28
+ withAdmissionReceipt,
29
+ withMeteredCall
30
+ };
@@ -0,0 +1,98 @@
1
+ #!/usr/bin/env node
2
+ var __create = Object.create;
3
+ var __defProp = Object.defineProperty;
4
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
+ var __getOwnPropNames = Object.getOwnPropertyNames;
6
+ var __getProtoOf = Object.getPrototypeOf;
7
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
8
+ var __commonJS = (cb, mod) => function __require() {
9
+ return mod || (0, cb[__getOwnPropNames(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports;
10
+ };
11
+ var __export = (target, all) => {
12
+ for (var name in all)
13
+ __defProp(target, name, { get: all[name], enumerable: true });
14
+ };
15
+ var __copyProps = (to, from, except, desc) => {
16
+ if (from && typeof from === "object" || typeof from === "function") {
17
+ for (let key of __getOwnPropNames(from))
18
+ if (!__hasOwnProp.call(to, key) && key !== except)
19
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
20
+ }
21
+ return to;
22
+ };
23
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
24
+ // If the importer is in node compatibility mode or this is not an ESM
25
+ // file that has been converted to a CommonJS file using a Babel-
26
+ // compatible transform (i.e. "__esModule" has not been set), then set
27
+ // "default" to the CommonJS "module.exports" for node compatibility.
28
+ isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
29
+ mod
30
+ ));
31
+
32
+ // package.json
33
+ var package_default = {
34
+ name: "@impractical-ai/motion",
35
+ version: "0.1.4",
36
+ private: false,
37
+ description: "Create and refine Impractical Motion videos from coding agents and the terminal.",
38
+ homepage: "https://github.com/Openpod/impractical-motion#readme",
39
+ repository: {
40
+ type: "git",
41
+ url: "git+https://github.com/Openpod/impractical-motion.git"
42
+ },
43
+ bugs: {
44
+ url: "https://github.com/Openpod/impractical-motion/issues"
45
+ },
46
+ license: "UNLICENSED",
47
+ type: "module",
48
+ files: [
49
+ "dist",
50
+ "assets",
51
+ "README.md"
52
+ ],
53
+ bin: {
54
+ impractical: "dist/index.js"
55
+ },
56
+ engines: {
57
+ node: ">=22"
58
+ },
59
+ scripts: {
60
+ build: 'node ../scripts/build-engine-dts.mjs && rm -rf dist && esbuild src/index.ts --bundle --platform=node --format=esm --target=node22 --splitting --outdir=dist --external:playwright-core --banner:js="#!/usr/bin/env node" && chmod +x dist/index.js',
61
+ typecheck: "tsc --noEmit",
62
+ test: "npm run build && esbuild tests/onboarding.test.ts tests/mcp-tools.test.ts tests/mcp-frames.test.ts tests/engine-dts.test.ts tests/mcp-connect.test.ts tests/mcp-longpoll.test.ts --bundle --platform=node --format=esm --packages=external --outdir=dist --out-extension:.js=.mjs && node --test dist/onboarding.test.mjs dist/mcp-tools.test.mjs dist/mcp-frames.test.mjs dist/engine-dts.test.mjs dist/mcp-connect.test.mjs dist/mcp-longpoll.test.mjs",
63
+ prepack: "npm run build"
64
+ },
65
+ publishConfig: {
66
+ access: "public"
67
+ },
68
+ devDependencies: {
69
+ esbuild: "^0.25.0",
70
+ typescript: "^5.6.3"
71
+ },
72
+ dependencies: {
73
+ "@modelcontextprotocol/sdk": "^1.30.0",
74
+ "playwright-core": "^1.55.1",
75
+ zod: "^4.4.3"
76
+ }
77
+ };
78
+
79
+ // src/constants.ts
80
+ if (package_default.name !== "@impractical-ai/motion" || typeof package_default.version !== "string" || !package_default.version) {
81
+ throw new Error("The packaged CLI manifest is missing valid release metadata");
82
+ }
83
+ var PRODUCTION_APP_URL = "https://motion.impractical.ai";
84
+ var PRODUCTION_SUPABASE_URL = "https://uaxjweednprtbhbceify.supabase.co";
85
+ var PACKAGE_NAME = "@impractical-ai/motion";
86
+ var PACKAGE_VERSION = package_default.version;
87
+ var PACKAGE_COMMAND = `npx --yes ${PACKAGE_NAME}`;
88
+
89
+ export {
90
+ __commonJS,
91
+ __export,
92
+ __toESM,
93
+ PRODUCTION_APP_URL,
94
+ PRODUCTION_SUPABASE_URL,
95
+ PACKAGE_NAME,
96
+ PACKAGE_VERSION,
97
+ PACKAGE_COMMAND
98
+ };
@@ -1,260 +1,32 @@
1
1
  #!/usr/bin/env node
2
- var __create = Object.create;
3
- var __defProp = Object.defineProperty;
4
- var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
- var __getOwnPropNames = Object.getOwnPropertyNames;
6
- var __getProtoOf = Object.getPrototypeOf;
7
- var __hasOwnProp = Object.prototype.hasOwnProperty;
8
- var __commonJS = (cb, mod) => function __require() {
9
- return mod || (0, cb[__getOwnPropNames(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports;
10
- };
11
- var __export = (target, all) => {
12
- for (var name in all)
13
- __defProp(target, name, { get: all[name], enumerable: true });
14
- };
15
- var __copyProps = (to, from, except, desc) => {
16
- if (from && typeof from === "object" || typeof from === "function") {
17
- for (let key of __getOwnPropNames(from))
18
- if (!__hasOwnProp.call(to, key) && key !== except)
19
- __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
20
- }
21
- return to;
22
- };
23
- var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
24
- // If the importer is in node compatibility mode or this is not an ESM
25
- // file that has been converted to a CommonJS file using a Babel-
26
- // compatible transform (i.e. "__esModule" has not been set), then set
27
- // "default" to the CommonJS "module.exports" for node compatibility.
28
- isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
29
- mod
30
- ));
31
-
32
- // src/constants.ts
33
- var PRODUCTION_APP_URL = "https://motion.impractical.ai";
34
- var PRODUCTION_SUPABASE_URL = "https://uaxjweednprtbhbceify.supabase.co";
35
- var PACKAGE_NAME = "@impractical-ai/motion";
36
- var PACKAGE_VERSION = "0.1.2";
37
- var PACKAGE_COMMAND = `npx --yes ${PACKAGE_NAME}`;
38
-
39
- // src/config.ts
40
- import { readFileSync, writeFileSync, mkdirSync, chmodSync, existsSync, renameSync } from "node:fs";
41
- import { homedir } from "node:os";
42
- import { join } from "node:path";
43
- var configDir = () => join(homedir(), ".impractical");
44
- var configPath = () => join(configDir(), "config.json");
45
- function recoverCorruptConfig() {
46
- const path = configPath();
47
- if (!existsSync(path)) return null;
48
- try {
49
- const parsed = JSON.parse(readFileSync(path, "utf8"));
50
- if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) {
51
- throw new SyntaxError("the root value must be an object");
52
- }
53
- return null;
54
- } catch (error) {
55
- if (!(error instanceof SyntaxError)) {
56
- throw new Error(
57
- `Could not inspect ${path}: ${error instanceof Error ? error.message : String(error)}`
58
- );
59
- }
60
- let backupPath = `${path}.corrupt-${Date.now()}`;
61
- let suffix = 1;
62
- while (existsSync(backupPath)) backupPath = `${path}.corrupt-${Date.now()}-${suffix++}`;
63
- renameSync(path, backupPath);
64
- return backupPath;
65
- }
66
- }
67
- function readStoredConfig() {
68
- try {
69
- const parsed = JSON.parse(readFileSync(configPath(), "utf8"));
70
- if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) {
71
- throw new SyntaxError("the root value must be an object");
72
- }
73
- return parsed;
74
- } catch (error) {
75
- if (error?.code === "ENOENT") return {};
76
- if (error instanceof SyntaxError) {
77
- throw new Error(`Invalid JSON in ${configPath()}: ${error.message}`);
78
- }
79
- throw new Error(
80
- `Could not read ${configPath()}: ${error instanceof Error ? error.message : String(error)}`
81
- );
82
- }
83
- }
84
- function loadConfig() {
85
- const stored = readStoredConfig();
86
- return {
87
- apiKey: process.env.IMPRACTICAL_API_KEY ?? stored.apiKey,
88
- supabaseUrl: process.env.IMPRACTICAL_SUPABASE_URL ?? stored.supabaseUrl ?? PRODUCTION_SUPABASE_URL,
89
- appUrl: process.env.IMPRACTICAL_APP_URL ?? stored.appUrl ?? PRODUCTION_APP_URL
90
- };
91
- }
92
- function saveConfig(patch) {
93
- const stored = readStoredConfig();
94
- const next = { ...stored, ...patch };
95
- mkdirSync(configDir(), { recursive: true });
96
- writeFileSync(configPath(), JSON.stringify(next, null, 2) + "\n");
97
- chmodSync(configPath(), 384);
98
- return next;
99
- }
100
- function requireConfig() {
101
- const config = loadConfig();
102
- if (!config.supabaseUrl) {
103
- throw new Error("Not configured. Run: npx --yes @impractical-ai/motion setup --claude");
104
- }
105
- if (!config.apiKey) {
106
- throw new Error("Not connected. Run: npx --yes @impractical-ai/motion setup --claude");
107
- }
108
- return config;
109
- }
110
-
111
- // src/api.ts
112
- import { AsyncLocalStorage } from "node:async_hooks";
113
- import { randomUUID } from "node:crypto";
114
- var admissionContext = new AsyncLocalStorage();
115
- var ApiError = class extends Error {
116
- constructor(status, message, fn, details) {
117
- super(message);
118
- this.status = status;
119
- this.fn = fn;
120
- this.details = details;
121
- }
122
- };
123
- var ApiContractError = class extends Error {
124
- constructor(fn, expected) {
125
- super(`${fn} returned an invalid response: expected ${expected}. Please retry; if this persists, update Impractical Motion or contact support.`);
126
- this.fn = fn;
127
- }
128
- };
129
- function isRecord(value) {
130
- return typeof value === "object" && value !== null && !Array.isArray(value);
131
- }
132
- function bodyRecord(body) {
133
- return isRecord(body) ? body : {};
134
- }
135
- function validateApiResponse(name, body, data) {
136
- if (!isRecord(data)) throw new ApiContractError(name, "a JSON object");
137
- const input = bodyRecord(body);
138
- if (name === "workspace-bootstrap") {
139
- const billing = data.billing;
140
- if (typeof data.orgId !== "string" || typeof data.plan !== "string" || typeof data.hasAccess !== "boolean" || !isRecord(billing) || typeof billing.status !== "string") {
141
- throw new ApiContractError(
142
- name,
143
- "an orgId, plan, hasAccess flag, and billing status"
144
- );
145
- }
146
- }
147
- if (name === "list-projects") {
148
- const key = input.projectId ? "project" : "projects";
149
- const value = data[key];
150
- if (key === "projects" ? !Array.isArray(value) : !isRecord(value)) {
151
- throw new ApiContractError(name, `an object with a ${key} ${key === "projects" ? "array" : "object"}`);
152
- }
153
- }
154
- if (name === "prepare-generation") {
155
- if (typeof data.projectId !== "string" || !Array.isArray(data.drafts) || data.drafts.length === 0 || !isRecord(data.drafts[0]) || typeof data.drafts[0].id !== "string") {
156
- throw new ApiContractError(
157
- name,
158
- "a projectId and at least one draft with an id"
159
- );
160
- }
161
- }
162
- if (name === "get-draft" && (!isRecord(data.files) || typeof data.draftId !== "string")) {
163
- throw new ApiContractError(name, "draft metadata and a files object");
164
- }
165
- if (name === "save-draft" && typeof data.revision !== "number") {
166
- throw new ApiContractError(name, "a numeric revision");
167
- }
168
- if (name === "job-status" && !Array.isArray(data.jobs)) {
169
- throw new ApiContractError(name, "an object with a jobs array");
170
- }
171
- if (name === "start-export" && typeof data.jobId !== "string") {
172
- throw new ApiContractError(name, "an object with a jobId");
173
- }
174
- if (name === "brand-kits") {
175
- const key = input.action === "list" ? "brands" : input.action === "get" ? "brand" : null;
176
- if (key && (key === "brands" ? !Array.isArray(data[key]) : !isRecord(data[key]))) {
177
- throw new ApiContractError(name, `an object with a ${key} ${key === "brands" ? "array" : "object"}`);
178
- }
179
- }
180
- return data;
181
- }
182
- async function invoke(name, body = {}) {
183
- const { apiKey, supabaseUrl } = requireConfig();
184
- const receipt = admissionContext.getStore();
185
- return invokeAt(supabaseUrl, name, body, apiKey, receipt);
186
- }
187
- async function invokeAt(supabaseUrl, name, body = {}, apiKey, admissionReceipt) {
188
- const response = await fetch(`${supabaseUrl.replace(/\/$/, "")}/functions/v1/${name}`, {
189
- method: "POST",
190
- headers: {
191
- ...apiKey ? { authorization: `Bearer ${apiKey}` } : {},
192
- ...admissionReceipt ? { "x-impractical-admission": admissionReceipt } : {},
193
- "content-type": "application/json"
194
- },
195
- body: JSON.stringify(body)
196
- });
197
- const text = await response.text();
198
- let data = null;
199
- try {
200
- data = text ? JSON.parse(text) : null;
201
- } catch {
202
- }
203
- if (!response.ok) {
204
- const details = isRecord(data) ? data : void 0;
205
- const message = typeof details?.message === "string" && details.message || typeof details?.error === "string" && details.error || text || `${name} failed (${response.status})`;
206
- throw new ApiError(response.status, message, name, details);
207
- }
208
- return validateApiResponse(name, body, data);
209
- }
210
- async function admitMcpCall(toolName, callId = randomUUID()) {
211
- const { apiKey, supabaseUrl } = requireConfig();
212
- return invokeAt(supabaseUrl, "mcp-admission", { callId, toolName }, apiKey);
213
- }
214
- function withAdmissionReceipt(receipt, task) {
215
- return admissionContext.run(receipt, task);
216
- }
217
- async function withMeteredCall(toolName, task) {
218
- const admission = await admitMcpCall(toolName);
219
- return withAdmissionReceipt(admission.receipt, task);
220
- }
221
- var delay = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
222
- async function jobStatus(jobIds) {
223
- const result = await invoke("job-status", { jobIds });
224
- return result.jobs;
225
- }
226
- async function waitForJobs(jobIds, onTick, deadlineMs = 72e5) {
227
- const deadline = Date.now() + deadlineMs;
228
- const terminal = /* @__PURE__ */ new Set();
229
- let latest = [];
230
- while (terminal.size < jobIds.length) {
231
- if (Date.now() >= deadline) throw new Error("Timed out waiting for jobs");
232
- latest = await jobStatus(jobIds);
233
- for (const row of latest) {
234
- if (row.status === "completed" || row.status === "failed" || row.status === "canceled") {
235
- terminal.add(row.id);
236
- }
237
- }
238
- onTick(latest);
239
- if (terminal.size < jobIds.length) await delay(2e3);
240
- }
241
- return latest;
242
- }
243
- function studioLink(appUrl, projectId, slug) {
244
- const base = (appUrl ?? "http://localhost:5173").replace(/\/$/, "");
245
- return `${base}/projects/${projectId}/studio${slug ? `?scene=${slug}` : ""}`;
246
- }
2
+ import {
3
+ ApiError,
4
+ delay,
5
+ invokeAt,
6
+ loadConfig,
7
+ recoverCorruptConfig,
8
+ saveConfig
9
+ } from "./chunk-M77TS5RO.js";
10
+ import {
11
+ PACKAGE_COMMAND,
12
+ PACKAGE_NAME,
13
+ PACKAGE_VERSION,
14
+ PRODUCTION_APP_URL,
15
+ PRODUCTION_SUPABASE_URL
16
+ } from "./chunk-EFP4P3WA.js";
247
17
 
248
18
  // src/onboarding.ts
249
- import { existsSync as existsSync2, mkdirSync as mkdirSync2, readFileSync as readFileSync2, writeFileSync as writeFileSync2 } from "node:fs";
250
- import { homedir as homedir2 } from "node:os";
251
- import { dirname, join as join2 } from "node:path";
19
+ import { existsSync, mkdirSync, readFileSync, writeFileSync } from "node:fs";
20
+ import { homedir } from "node:os";
21
+ import { dirname, join } from "node:path";
252
22
  import { fileURLToPath } from "node:url";
253
23
  import { spawnSync } from "node:child_process";
254
24
  var CLAUDE_MARKETPLACE = "Openpod/impractical-agent-plugins";
255
25
  var CLAUDE_PLUGIN = "impractical-motion@impractical";
256
26
  var CLAUDE_MARKETPLACE_NAME = "impractical";
257
27
  var AUTH_VERIFY_MIN_VERSION = "0.1.2";
28
+ var CLAUDE_INSTALL_COMMAND = "npm install -g @anthropic-ai/claude-code";
29
+ var CLAUDE_INSTALL_URL = "https://code.claude.com/docs/en/installation";
258
30
  function parseSemver(value) {
259
31
  const match = value.trim().match(
260
32
  /^v?(0|[1-9]\d*)\.(0|[1-9]\d*)\.(0|[1-9]\d*)(?:-([0-9A-Za-z.-]+))?(?:\+[0-9A-Za-z.-]+)?$/
@@ -294,20 +66,20 @@ function compareSemver(left, right) {
294
66
  return 0;
295
67
  }
296
68
  function readJson(path) {
297
- if (!existsSync2(path)) return void 0;
69
+ if (!existsSync(path)) return void 0;
298
70
  try {
299
- return JSON.parse(readFileSync2(path, "utf8"));
71
+ return JSON.parse(readFileSync(path, "utf8"));
300
72
  } catch {
301
73
  return void 0;
302
74
  }
303
75
  }
304
- var claudeConfigDir = () => process.env.CLAUDE_CONFIG_DIR?.trim() || join2(homedir2(), ".claude");
305
- function marketplaceRecord(configDir2) {
306
- const value = readJson(join2(configDir2, "plugins", "known_marketplaces.json"));
76
+ var claudeConfigDir = () => process.env.CLAUDE_CONFIG_DIR?.trim() || join(homedir(), ".claude");
77
+ function marketplaceRecord(configDir) {
78
+ const value = readJson(join(configDir, "plugins", "known_marketplaces.json"));
307
79
  return value?.impractical;
308
80
  }
309
- function installedPluginVersion(configDir2) {
310
- const value = readJson(join2(configDir2, "plugins", "installed_plugins.json"));
81
+ function installedPluginVersion(configDir) {
82
+ const value = readJson(join(configDir, "plugins", "installed_plugins.json"));
311
83
  const entries = value?.plugins?.[CLAUDE_PLUGIN];
312
84
  if (!Array.isArray(entries)) return void 0;
313
85
  const versions = entries.filter((entry) => entry?.scope === "user" && typeof entry.version === "string").map((entry) => entry.version);
@@ -317,10 +89,10 @@ function installedPluginVersion(configDir2) {
317
89
  return comparison !== void 0 && comparison > 0 ? version : highest;
318
90
  }, void 0);
319
91
  }
320
- function marketplacePluginVersion(configDir2) {
321
- const record = marketplaceRecord(configDir2);
322
- const location = typeof record?.installLocation === "string" ? record.installLocation : join2(configDir2, "plugins", "marketplaces", CLAUDE_MARKETPLACE_NAME);
323
- const value = readJson(join2(location, ".claude-plugin", "marketplace.json"));
92
+ function marketplacePluginVersion(configDir) {
93
+ const record = marketplaceRecord(configDir);
94
+ const location = typeof record?.installLocation === "string" ? record.installLocation : join(configDir, "plugins", "marketplaces", CLAUDE_MARKETPLACE_NAME);
95
+ const value = readJson(join(location, ".claude-plugin", "marketplace.json"));
324
96
  return value?.plugins?.find((plugin) => plugin.name === "impractical-motion")?.version;
325
97
  }
326
98
  function expectedMarketplace(record) {
@@ -337,6 +109,13 @@ function commandResult(command, args) {
337
109
  function requireCommand(command, label) {
338
110
  const result = commandResult(command, ["--version"]);
339
111
  if (result.error || result.status !== 0) {
112
+ if (command === "claude") {
113
+ throw new Error(
114
+ `${label} is not installed. Install it, then rerun setup:
115
+ ${CLAUDE_INSTALL_COMMAND}
116
+ Official setup guide: ${CLAUDE_INSTALL_URL}`
117
+ );
118
+ }
340
119
  throw new Error(`${label} is required before setup can continue.`);
341
120
  }
342
121
  }
@@ -345,7 +124,7 @@ function hasChrome() {
345
124
  "/Applications/Google Chrome.app/Contents/MacOS/Google Chrome",
346
125
  "/Applications/Chromium.app/Contents/MacOS/Chromium"
347
126
  ];
348
- if (macPaths.some(existsSync2)) return true;
127
+ if (macPaths.some(existsSync)) return true;
349
128
  return ["google-chrome", "google-chrome-stable", "chromium", "chromium-browser"].some((command) => {
350
129
  const result = spawnSync(command, ["--version"], { stdio: "ignore", windowsHide: true });
351
130
  return !result.error && result.status === 0;
@@ -381,9 +160,9 @@ ${result.stderr ?? ""}`.trim();
381
160
  }
382
161
  function installClaudePlugin(log = () => {
383
162
  }) {
384
- const configDir2 = claudeConfigDir();
385
- const beforeVersion = installedPluginVersion(configDir2);
386
- let record = marketplaceRecord(configDir2);
163
+ const configDir = claudeConfigDir();
164
+ const beforeVersion = installedPluginVersion(configDir);
165
+ let record = marketplaceRecord(configDir);
387
166
  const preserveSource = Boolean(record && !expectedMarketplace(record));
388
167
  if (preserveSource) {
389
168
  log(
@@ -391,12 +170,12 @@ function installClaudePlugin(log = () => {
391
170
  );
392
171
  } else if (!record) {
393
172
  runClaude(["plugin", "marketplace", "add", CLAUDE_MARKETPLACE], log, true);
394
- record = marketplaceRecord(configDir2);
173
+ record = marketplaceRecord(configDir);
395
174
  }
396
175
  if (!beforeVersion) {
397
176
  runClaude(["plugin", "install", CLAUDE_PLUGIN, "--scope", "user"], log, true);
398
177
  } else if (!preserveSource) {
399
- const advertisedVersion = marketplacePluginVersion(configDir2);
178
+ const advertisedVersion = marketplacePluginVersion(configDir);
400
179
  const comparison = advertisedVersion ? compareSemver(beforeVersion, advertisedVersion) : void 0;
401
180
  if (comparison === void 0) {
402
181
  log(
@@ -408,8 +187,8 @@ function installClaudePlugin(log = () => {
408
187
  );
409
188
  } else {
410
189
  runClaude(["plugin", "marketplace", "update", CLAUDE_MARKETPLACE_NAME], log, true);
411
- const refreshedVersion = marketplacePluginVersion(configDir2);
412
- const currentVersion = installedPluginVersion(configDir2) ?? beforeVersion;
190
+ const refreshedVersion = marketplacePluginVersion(configDir);
191
+ const currentVersion = installedPluginVersion(configDir) ?? beforeVersion;
413
192
  const refreshedComparison = refreshedVersion ? compareSemver(currentVersion, refreshedVersion) : void 0;
414
193
  if (refreshedComparison !== void 0 && refreshedComparison < 0) {
415
194
  runClaude(["plugin", "update", CLAUDE_PLUGIN], log, true);
@@ -420,7 +199,7 @@ function installClaudePlugin(log = () => {
420
199
  }
421
200
  }
422
201
  }
423
- const afterVersion = installedPluginVersion(configDir2);
202
+ const afterVersion = installedPluginVersion(configDir);
424
203
  const change = beforeVersion && afterVersion ? compareSemver(afterVersion, beforeVersion) : void 0;
425
204
  if (change !== void 0 && change < 0) {
426
205
  log(`WARNING: ${CLAUDE_PLUGIN} resolved to ${afterVersion}, below its prior ${beforeVersion}.`);
@@ -454,44 +233,44 @@ function pluginResultLine(result) {
454
233
  return `${CLAUDE_PLUGIN} already at ${result.afterVersion}; left unchanged.`;
455
234
  }
456
235
  var skillSourcePath = () => fileURLToPath(new URL("../assets/impractical/SKILL.md", import.meta.url));
457
- function installSkills(home = homedir2(), sourcePath = skillSourcePath()) {
458
- const source = readFileSync2(sourcePath, "utf8");
236
+ function installSkills(home = homedir(), sourcePath = skillSourcePath()) {
237
+ const source = readFileSync(sourcePath, "utf8");
459
238
  const targets = [
460
239
  {
461
240
  harness: "Claude Code",
462
- path: join2(home, ".claude", "skills", "impractical", "SKILL.md")
241
+ path: join(home, ".claude", "skills", "impractical", "SKILL.md")
463
242
  },
464
243
  {
465
244
  harness: "Codex",
466
- path: join2(home, ".codex", "skills", "impractical", "SKILL.md")
245
+ path: join(home, ".codex", "skills", "impractical", "SKILL.md")
467
246
  }
468
247
  ];
469
248
  for (const target of targets) {
470
- mkdirSync2(dirname(target.path), { recursive: true, mode: 448 });
471
- writeFileSync2(target.path, source, { mode: 420 });
249
+ mkdirSync(dirname(target.path), { recursive: true, mode: 448 });
250
+ writeFileSync(target.path, source, { mode: 420 });
472
251
  }
473
252
  return targets;
474
253
  }
475
- function reconcileLegacySkills(home = homedir2(), sourcePath = skillSourcePath()) {
476
- const source = readFileSync2(sourcePath, "utf8");
254
+ function reconcileLegacySkills(home = homedir(), sourcePath = skillSourcePath()) {
255
+ const source = readFileSync(sourcePath, "utf8");
477
256
  const targets = [
478
257
  {
479
258
  harness: "Claude Code",
480
- path: join2(home, ".claude", "skills", "impractical", "SKILL.md")
259
+ path: join(home, ".claude", "skills", "impractical", "SKILL.md")
481
260
  },
482
261
  {
483
262
  harness: "Codex",
484
- path: join2(home, ".codex", "skills", "impractical", "SKILL.md")
263
+ path: join(home, ".codex", "skills", "impractical", "SKILL.md")
485
264
  }
486
265
  ];
487
266
  const reconciled = [];
488
267
  for (const target of targets) {
489
- if (!existsSync2(target.path)) continue;
490
- const previous = readFileSync2(target.path, "utf8");
268
+ if (!existsSync(target.path)) continue;
269
+ const previous = readFileSync(target.path, "utf8");
491
270
  if (previous === source) continue;
492
271
  const backupPath = `${target.path}.pre-plugin`;
493
- if (!existsSync2(backupPath)) writeFileSync2(backupPath, previous, { mode: 420 });
494
- writeFileSync2(target.path, source, { mode: 420 });
272
+ if (!existsSync(backupPath)) writeFileSync(backupPath, previous, { mode: 420 });
273
+ writeFileSync(target.path, source, { mode: 420 });
495
274
  reconciled.push({ ...target, backupPath });
496
275
  }
497
276
  return reconciled;
@@ -593,25 +372,6 @@ async function setup(options) {
593
372
  }
594
373
 
595
374
  export {
596
- __commonJS,
597
- __export,
598
- __toESM,
599
- PRODUCTION_APP_URL,
600
- PRODUCTION_SUPABASE_URL,
601
- PACKAGE_VERSION,
602
- loadConfig,
603
- saveConfig,
604
- requireConfig,
605
- ApiError,
606
- validateApiResponse,
607
- invoke,
608
- invokeAt,
609
- admitMcpCall,
610
- withAdmissionReceipt,
611
- withMeteredCall,
612
- jobStatus,
613
- waitForJobs,
614
- studioLink,
615
375
  openBrowser,
616
376
  setup
617
377
  };