@aipm-registry/cli 0.4.0 → 0.4.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/dist/bin.cjs CHANGED
@@ -4178,8 +4178,8 @@ var init_manifest = __esm({
4178
4178
  "use strict";
4179
4179
  init_zod();
4180
4180
  init_scope_name();
4181
- AiToolSchema = external_exports.enum(["cursor", "claude", "*"]);
4182
- ALL_TOOLS = ["cursor", "claude"];
4181
+ AiToolSchema = external_exports.enum(["cursor", "claude", "codex", "*"]);
4182
+ ALL_TOOLS = ["cursor", "claude", "codex"];
4183
4183
  PackageExampleSchema = external_exports.object({
4184
4184
  title: external_exports.string().trim().min(1).max(80),
4185
4185
  description: external_exports.string().trim().min(1).max(240).optional(),
@@ -4326,6 +4326,8 @@ async function detectToolsInProject(projectRoot) {
4326
4326
  detected.push("cursor");
4327
4327
  if (await pathExists((0, import_node_path2.join)(projectRoot, ".claude")))
4328
4328
  detected.push("claude");
4329
+ if (await pathExists((0, import_node_path2.join)(projectRoot, ".codex")))
4330
+ detected.push("codex");
4329
4331
  return detected;
4330
4332
  }
4331
4333
  function manifestAllowsTool(manifest, tool) {
@@ -4416,6 +4418,29 @@ var init_dist3 = __esm({
4416
4418
  }
4417
4419
  });
4418
4420
 
4421
+ // ../../packages/adapter-codex/dist/index.js
4422
+ var import_promises4, import_node_path5, CodexSkillAdapter, codexSkillAdapter;
4423
+ var init_dist4 = __esm({
4424
+ "../../packages/adapter-codex/dist/index.js"() {
4425
+ "use strict";
4426
+ import_promises4 = require("node:fs/promises");
4427
+ import_node_path5 = require("node:path");
4428
+ init_dist();
4429
+ CodexSkillAdapter = class {
4430
+ tool = "codex";
4431
+ async installSkill(input2) {
4432
+ const short = shortNameFromScopeName(input2.packageName);
4433
+ const skillDir = (0, import_node_path5.join)(input2.projectRoot, ".agents", "skills", short);
4434
+ await (0, import_promises4.mkdir)(skillDir, { recursive: true });
4435
+ const filePath = (0, import_node_path5.join)(skillDir, "SKILL.md");
4436
+ await (0, import_promises4.writeFile)(filePath, input2.skillMarkdown, "utf8");
4437
+ return { writtenPaths: [filePath] };
4438
+ }
4439
+ };
4440
+ codexSkillAdapter = new CodexSkillAdapter();
4441
+ }
4442
+ });
4443
+
4419
4444
  // ../../packages/engine/dist/install-skill.js
4420
4445
  async function installSkillPackage(options) {
4421
4446
  const tools = await resolveInstallTools({
@@ -4425,7 +4450,7 @@ async function installSkillPackage(options) {
4425
4450
  explicitTarget: options.explicitTarget
4426
4451
  });
4427
4452
  if (tools.length === 0) {
4428
- throw new Error("No AI tool detected (.cursor/ or .claude/). Use --target cursor|claude|* or set preferredTools in aipm.package.json.");
4453
+ throw new Error("No AI tool detected (.cursor/, .claude/, or .codex/). Use --target cursor|claude|codex|* or set preferredTools in aipm.package.json.");
4429
4454
  }
4430
4455
  const installed = {};
4431
4456
  for (const tool of tools) {
@@ -4446,10 +4471,12 @@ var init_install_skill = __esm({
4446
4471
  "use strict";
4447
4472
  init_dist2();
4448
4473
  init_dist3();
4474
+ init_dist4();
4449
4475
  init_detect_tools();
4450
4476
  adapters = {
4451
4477
  cursor: cursorSkillAdapter,
4452
- claude: claudeSkillAdapter
4478
+ claude: claudeSkillAdapter,
4479
+ codex: codexSkillAdapter
4453
4480
  };
4454
4481
  }
4455
4482
  });
@@ -4461,7 +4488,7 @@ __export(dist_exports, {
4461
4488
  installSkillPackage: () => installSkillPackage,
4462
4489
  resolveInstallTools: () => resolveInstallTools
4463
4490
  });
4464
- var init_dist4 = __esm({
4491
+ var init_dist5 = __esm({
4465
4492
  "../../packages/engine/dist/index.js"() {
4466
4493
  "use strict";
4467
4494
  init_detect_tools();
@@ -7841,25 +7868,25 @@ var program = new Command();
7841
7868
  var import_node_crypto3 = require("node:crypto");
7842
7869
  var import_node_child_process4 = require("node:child_process");
7843
7870
  var import_node_http = require("node:http");
7844
- var import_promises11 = require("node:fs/promises");
7845
- var import_node_path14 = require("node:path");
7871
+ var import_promises12 = require("node:fs/promises");
7872
+ var import_node_path15 = require("node:path");
7846
7873
  var import_node_process5 = require("node:process");
7847
7874
  init_dist();
7848
- init_dist4();
7875
+ init_dist5();
7849
7876
 
7850
7877
  // src/pack.ts
7851
7878
  var import_node_child_process2 = require("node:child_process");
7852
7879
  var import_node_util3 = require("node:util");
7853
- var import_promises5 = require("node:fs/promises");
7854
- var import_node_path6 = require("node:path");
7880
+ var import_promises6 = require("node:fs/promises");
7881
+ var import_node_path7 = require("node:path");
7855
7882
  var import_node_os = require("node:os");
7856
7883
 
7857
7884
  // src/publish-state.ts
7858
7885
  var import_node_crypto = require("node:crypto");
7859
- var import_promises4 = require("node:fs/promises");
7860
- var import_node_path5 = require("node:path");
7886
+ var import_promises5 = require("node:fs/promises");
7887
+ var import_node_path6 = require("node:path");
7861
7888
  init_dist();
7862
- var STATE_PATH = (0, import_node_path5.join)(".aipm", "publish-state.json");
7889
+ var STATE_PATH = (0, import_node_path6.join)(".aipm", "publish-state.json");
7863
7890
  var IGNORE_FILE = ".aipmignore";
7864
7891
  var MAX_PACKAGE_BYTES = 50 * 1024 * 1024;
7865
7892
  var EXCLUDED_SEGMENTS = /* @__PURE__ */ new Set([".aipm", ".git", "node_modules", "dist", ".next"]);
@@ -7874,11 +7901,11 @@ var SECRET_PATTERNS = [
7874
7901
  /<publishData/i
7875
7902
  ];
7876
7903
  function publishStatePath(root) {
7877
- return (0, import_node_path5.join)(root, STATE_PATH);
7904
+ return (0, import_node_path6.join)(root, STATE_PATH);
7878
7905
  }
7879
7906
  function normalizePublishPath(root, filePath) {
7880
- const abs = (0, import_node_path5.resolve)(root, filePath);
7881
- const rel = (0, import_node_path5.normalize)((0, import_node_path5.relative)(root, abs)).split(import_node_path5.sep).join("/");
7907
+ const abs = (0, import_node_path6.resolve)(root, filePath);
7908
+ const rel = (0, import_node_path6.normalize)((0, import_node_path6.relative)(root, abs)).split(import_node_path6.sep).join("/");
7882
7909
  if (!rel || rel === ".") return ".";
7883
7910
  if (rel.startsWith("../") || rel === ".." || rel.startsWith("/")) {
7884
7911
  throw new Error(`Path is outside the skill folder: ${filePath}`);
@@ -7895,7 +7922,7 @@ function isExcludedPublishPath(rel) {
7895
7922
  }
7896
7923
  async function readAipmIgnore(root) {
7897
7924
  try {
7898
- const raw = await (0, import_promises4.readFile)((0, import_node_path5.join)(root, IGNORE_FILE), "utf8");
7925
+ const raw = await (0, import_promises5.readFile)((0, import_node_path6.join)(root, IGNORE_FILE), "utf8");
7899
7926
  return raw.split(/\r?\n/).map((line) => line.trim()).filter((line) => line && !line.startsWith("#"));
7900
7927
  } catch {
7901
7928
  return [];
@@ -7916,7 +7943,7 @@ async function isIgnoredByAipmIgnore(root, rel) {
7916
7943
  return rules.some((rule) => matchesIgnoreRule(rel, rule));
7917
7944
  }
7918
7945
  async function assertNoObviousSecrets(path2, rel) {
7919
- const data = await (0, import_promises4.readFile)(path2);
7946
+ const data = await (0, import_promises5.readFile)(path2);
7920
7947
  if (data.includes(0)) return;
7921
7948
  const text = data.toString("utf8");
7922
7949
  if (SECRET_PATTERNS.some((pattern) => pattern.test(text))) {
@@ -7924,7 +7951,7 @@ async function assertNoObviousSecrets(path2, rel) {
7924
7951
  }
7925
7952
  }
7926
7953
  async function fileHash(path2) {
7927
- const data = await (0, import_promises4.readFile)(path2);
7954
+ const data = await (0, import_promises5.readFile)(path2);
7928
7955
  return {
7929
7956
  hash: (0, import_node_crypto.createHash)("sha256").update(data).digest("hex"),
7930
7957
  size: data.length
@@ -7932,7 +7959,7 @@ async function fileHash(path2) {
7932
7959
  }
7933
7960
  async function readPublishState(root) {
7934
7961
  try {
7935
- const raw = await (0, import_promises4.readFile)(publishStatePath(root), "utf8");
7962
+ const raw = await (0, import_promises5.readFile)(publishStatePath(root), "utf8");
7936
7963
  const parsed = JSON.parse(raw);
7937
7964
  return {
7938
7965
  schemaVersion: "0.1",
@@ -7944,18 +7971,18 @@ async function readPublishState(root) {
7944
7971
  }
7945
7972
  async function writePublishState(root, state) {
7946
7973
  const path2 = publishStatePath(root);
7947
- await (0, import_promises4.mkdir)((0, import_node_path5.dirname)(path2), { recursive: true });
7974
+ await (0, import_promises5.mkdir)((0, import_node_path6.dirname)(path2), { recursive: true });
7948
7975
  const files = [...state.files].sort((a, b) => a.path.localeCompare(b.path));
7949
- await (0, import_promises4.writeFile)(path2, JSON.stringify({ schemaVersion: "0.1", files }, null, 2) + "\n", "utf8");
7976
+ await (0, import_promises5.writeFile)(path2, JSON.stringify({ schemaVersion: "0.1", files }, null, 2) + "\n", "utf8");
7950
7977
  }
7951
7978
  async function expandPublishPath(root, rel) {
7952
7979
  if (isExcludedPublishPath(rel)) return [];
7953
7980
  if (await isIgnoredByAipmIgnore(root, rel)) return [];
7954
- const abs = (0, import_node_path5.join)(root, rel);
7955
- const info = await (0, import_promises4.stat)(abs);
7981
+ const abs = (0, import_node_path6.join)(root, rel);
7982
+ const info = await (0, import_promises5.stat)(abs);
7956
7983
  if (info.isFile()) return [rel];
7957
7984
  if (!info.isDirectory()) return [];
7958
- const entries = await (0, import_promises4.readdir)(abs);
7985
+ const entries = await (0, import_promises5.readdir)(abs);
7959
7986
  const nested = await Promise.all(
7960
7987
  entries.map((entry) => expandPublishPath(root, `${rel === "." ? "" : `${rel}/`}${entry}`))
7961
7988
  );
@@ -7971,7 +7998,7 @@ async function addPublishFiles(root, paths) {
7971
7998
  for (const rel of files) {
7972
7999
  if (isExcludedPublishPath(rel)) continue;
7973
8000
  if (await isIgnoredByAipmIgnore(root, rel)) continue;
7974
- const hashed = await fileHash((0, import_node_path5.join)(root, rel));
8001
+ const hashed = await fileHash((0, import_node_path6.join)(root, rel));
7975
8002
  byPath.set(rel, { path: rel, ...hashed });
7976
8003
  }
7977
8004
  }
@@ -7990,11 +8017,11 @@ async function removePublishFiles(root, paths) {
7990
8017
  return next;
7991
8018
  }
7992
8019
  async function resetPublishState(root) {
7993
- await (0, import_promises4.rm)(publishStatePath(root), { force: true });
8020
+ await (0, import_promises5.rm)(publishStatePath(root), { force: true });
7994
8021
  }
7995
8022
  async function readManifest(root) {
7996
8023
  try {
7997
- const raw = await (0, import_promises4.readFile)((0, import_node_path5.join)(root, "aipm.manifest.json"), "utf8");
8024
+ const raw = await (0, import_promises5.readFile)((0, import_node_path6.join)(root, "aipm.manifest.json"), "utf8");
7998
8025
  return PackageManifestSchema.parse(JSON.parse(raw));
7999
8026
  } catch (error) {
8000
8027
  if (error && typeof error === "object" && "code" in error && error.code === "ENOENT") {
@@ -8027,8 +8054,8 @@ async function validatePublishState(root) {
8027
8054
  if (await isIgnoredByAipmIgnore(root, entry.path)) {
8028
8055
  throw new Error(`Refusing to publish ignored path: ${entry.path}`);
8029
8056
  }
8030
- const abs = (0, import_node_path5.join)(root, entry.path);
8031
- const info = await (0, import_promises4.stat)(abs).catch(() => null);
8057
+ const abs = (0, import_node_path6.join)(root, entry.path);
8058
+ const info = await (0, import_promises5.stat)(abs).catch(() => null);
8032
8059
  if (!info?.isFile()) throw new Error(`Staged file is missing: ${entry.path}`);
8033
8060
  const hashed = await fileHash(abs);
8034
8061
  if (hashed.hash !== entry.hash) {
@@ -8044,7 +8071,7 @@ async function statusPublishState(root) {
8044
8071
  const state = await readPublishState(root);
8045
8072
  const rows = [];
8046
8073
  for (const entry of state.files) {
8047
- const current = await fileHash((0, import_node_path5.join)(root, entry.path)).catch(() => null);
8074
+ const current = await fileHash((0, import_node_path6.join)(root, entry.path)).catch(() => null);
8048
8075
  rows.push({ ...entry, changed: !current || current.hash !== entry.hash });
8049
8076
  }
8050
8077
  return rows;
@@ -8052,9 +8079,9 @@ async function statusPublishState(root) {
8052
8079
  async function copyStagedFiles(root, destination) {
8053
8080
  const state = await readPublishState(root);
8054
8081
  for (const entry of state.files) {
8055
- const target = (0, import_node_path5.join)(destination, entry.path);
8056
- await (0, import_promises4.mkdir)((0, import_node_path5.dirname)(target), { recursive: true });
8057
- await (0, import_promises4.cp)((0, import_node_path5.join)(root, entry.path), target);
8082
+ const target = (0, import_node_path6.join)(destination, entry.path);
8083
+ await (0, import_promises5.mkdir)((0, import_node_path6.dirname)(target), { recursive: true });
8084
+ await (0, import_promises5.cp)((0, import_node_path6.join)(root, entry.path), target);
8058
8085
  }
8059
8086
  }
8060
8087
 
@@ -8068,21 +8095,21 @@ async function packDirectory(dir) {
8068
8095
  return Buffer.isBuffer(stdout) ? stdout : Buffer.from(stdout);
8069
8096
  }
8070
8097
  async function packStagedFiles(root) {
8071
- const tempDir = await (0, import_promises5.mkdtemp)((0, import_node_path6.join)((0, import_node_os.tmpdir)(), "aipm-publish-stage-"));
8098
+ const tempDir = await (0, import_promises6.mkdtemp)((0, import_node_path7.join)((0, import_node_os.tmpdir)(), "aipm-publish-stage-"));
8072
8099
  try {
8073
8100
  await copyStagedFiles(root, tempDir);
8074
8101
  return await packDirectory(tempDir);
8075
8102
  } finally {
8076
- await (0, import_promises5.rm)(tempDir, { recursive: true, force: true });
8103
+ await (0, import_promises6.rm)(tempDir, { recursive: true, force: true });
8077
8104
  }
8078
8105
  }
8079
8106
  async function unpackTarballToDirectory(tarball) {
8080
- const { mkdtemp: mkdtemp2, writeFile: writeFile8 } = await import("node:fs/promises");
8081
- const { join: join14 } = await import("node:path");
8107
+ const { mkdtemp: mkdtemp2, writeFile: writeFile9 } = await import("node:fs/promises");
8108
+ const { join: join15 } = await import("node:path");
8082
8109
  const { tmpdir: tmpdir2 } = await import("node:os");
8083
- const tempDir = await mkdtemp2(join14(tmpdir2(), "aipm-install-"));
8084
- const tgzPath = join14(tempDir, "pkg.tgz");
8085
- await writeFile8(tgzPath, tarball);
8110
+ const tempDir = await mkdtemp2(join15(tmpdir2(), "aipm-install-"));
8111
+ const tgzPath = join15(tempDir, "pkg.tgz");
8112
+ await writeFile9(tgzPath, tarball);
8086
8113
  await execFileAsync("tar", ["-xzf", tgzPath, "-C", tempDir]);
8087
8114
  return tempDir;
8088
8115
  }
@@ -8278,16 +8305,16 @@ async function publishPrompt(registry, input2, accessToken, sampleImage) {
8278
8305
  }
8279
8306
 
8280
8307
  // src/auth-store.ts
8281
- var import_promises6 = require("node:fs/promises");
8308
+ var import_promises7 = require("node:fs/promises");
8282
8309
  var import_node_os2 = require("node:os");
8283
- var import_node_path7 = require("node:path");
8284
- var AUTH_FILE = (0, import_node_path7.join)((0, import_node_os2.homedir)(), ".aipm", "auth.json");
8310
+ var import_node_path8 = require("node:path");
8311
+ var AUTH_FILE = (0, import_node_path8.join)((0, import_node_os2.homedir)(), ".aipm", "auth.json");
8285
8312
  function normalizeRegistry(registry) {
8286
8313
  return registry.replace(/\/$/, "");
8287
8314
  }
8288
8315
  async function readAuthStore() {
8289
8316
  try {
8290
- const raw = await (0, import_promises6.readFile)(AUTH_FILE, "utf8");
8317
+ const raw = await (0, import_promises7.readFile)(AUTH_FILE, "utf8");
8291
8318
  const parsed = JSON.parse(raw);
8292
8319
  return { registries: parsed.registries ?? {} };
8293
8320
  } catch {
@@ -8295,9 +8322,9 @@ async function readAuthStore() {
8295
8322
  }
8296
8323
  }
8297
8324
  async function writeAuthStore(store) {
8298
- await (0, import_promises6.mkdir)((0, import_node_path7.dirname)(AUTH_FILE), { recursive: true });
8299
- await (0, import_promises6.writeFile)(AUTH_FILE, JSON.stringify(store, null, 2) + "\n", "utf8");
8300
- await (0, import_promises6.chmod)(AUTH_FILE, 384).catch(() => void 0);
8325
+ await (0, import_promises7.mkdir)((0, import_node_path8.dirname)(AUTH_FILE), { recursive: true });
8326
+ await (0, import_promises7.writeFile)(AUTH_FILE, JSON.stringify(store, null, 2) + "\n", "utf8");
8327
+ await (0, import_promises7.chmod)(AUTH_FILE, 384).catch(() => void 0);
8301
8328
  }
8302
8329
  async function getStoredRegistryAuth(registry) {
8303
8330
  const store = await readAuthStore();
@@ -8326,41 +8353,41 @@ function isAccessTokenFresh(auth, skewMs = 6e4) {
8326
8353
  }
8327
8354
 
8328
8355
  // src/install-one.ts
8329
- init_dist4();
8330
- var import_promises8 = require("node:fs/promises");
8331
- var import_node_path9 = require("node:path");
8356
+ init_dist5();
8357
+ var import_promises9 = require("node:fs/promises");
8358
+ var import_node_path10 = require("node:path");
8332
8359
 
8333
8360
  // src/project-files.ts
8334
- var import_promises7 = require("node:fs/promises");
8335
- var import_node_path8 = require("node:path");
8361
+ var import_promises8 = require("node:fs/promises");
8362
+ var import_node_path9 = require("node:path");
8336
8363
  init_dist();
8337
8364
  var PACKAGE_JSON = "aipm.package.json";
8338
8365
  var LOCKFILE = "aipm-lock.json";
8339
8366
  async function readProjectPackageJson(projectRoot) {
8340
8367
  try {
8341
- const raw = await (0, import_promises7.readFile)((0, import_node_path8.join)(projectRoot, PACKAGE_JSON), "utf8");
8368
+ const raw = await (0, import_promises8.readFile)((0, import_node_path9.join)(projectRoot, PACKAGE_JSON), "utf8");
8342
8369
  return ProjectPackageJsonSchema.parse(JSON.parse(raw));
8343
8370
  } catch {
8344
8371
  return null;
8345
8372
  }
8346
8373
  }
8347
8374
  async function writeProjectPackageJson(projectRoot, data) {
8348
- await (0, import_promises7.writeFile)(
8349
- (0, import_node_path8.join)(projectRoot, PACKAGE_JSON),
8375
+ await (0, import_promises8.writeFile)(
8376
+ (0, import_node_path9.join)(projectRoot, PACKAGE_JSON),
8350
8377
  JSON.stringify(data, null, 2) + "\n",
8351
8378
  "utf8"
8352
8379
  );
8353
8380
  }
8354
8381
  async function readLockfile(projectRoot) {
8355
8382
  try {
8356
- const raw = await (0, import_promises7.readFile)((0, import_node_path8.join)(projectRoot, LOCKFILE), "utf8");
8383
+ const raw = await (0, import_promises8.readFile)((0, import_node_path9.join)(projectRoot, LOCKFILE), "utf8");
8357
8384
  return LockfileSchema.parse(JSON.parse(raw));
8358
8385
  } catch {
8359
8386
  return null;
8360
8387
  }
8361
8388
  }
8362
8389
  async function writeLockfile(projectRoot, data) {
8363
- await (0, import_promises7.writeFile)((0, import_node_path8.join)(projectRoot, LOCKFILE), JSON.stringify(data, null, 2) + "\n", "utf8");
8390
+ await (0, import_promises8.writeFile)((0, import_node_path9.join)(projectRoot, LOCKFILE), JSON.stringify(data, null, 2) + "\n", "utf8");
8364
8391
  }
8365
8392
  function upsertLockEntry(lock, name, entry) {
8366
8393
  return {
@@ -8384,15 +8411,17 @@ function resolveRegistryUrl(project, flag, fallback) {
8384
8411
  }
8385
8412
  function parseTargetFlag(target) {
8386
8413
  if (!target) return void 0;
8387
- if (target === "cursor" || target === "claude" || target === "*") return target;
8388
- throw new Error('--target must be "cursor", "claude", or "*"');
8414
+ if (target === "cursor" || target === "claude" || target === "codex" || target === "*") {
8415
+ return target;
8416
+ }
8417
+ throw new Error('--target must be "cursor", "claude", "codex", or "*"');
8389
8418
  }
8390
8419
  function parseTargetsFlag(value) {
8391
8420
  const targets = value.split(",").map((target) => target.trim()).filter(Boolean);
8392
8421
  if (targets.length === 0) throw new Error("At least one target is required.");
8393
8422
  for (const target of targets) {
8394
- if (target !== "cursor" && target !== "claude" && target !== "*") {
8395
- throw new Error('--targets must contain only "cursor", "claude", and/or "*"');
8423
+ if (target !== "cursor" && target !== "claude" && target !== "codex" && target !== "*") {
8424
+ throw new Error('--targets must contain only "cursor", "claude", "codex", and/or "*"');
8396
8425
  }
8397
8426
  }
8398
8427
  const unique = [...new Set(targets)];
@@ -8408,13 +8437,13 @@ async function promptForTool() {
8408
8437
  try {
8409
8438
  while (true) {
8410
8439
  const answer = await rl.question(
8411
- "Which AI tool should this skill be installed for? (cursor/claude): "
8440
+ "Which AI tool should this skill be installed for? (cursor/claude/codex): "
8412
8441
  );
8413
8442
  const normalized = answer.trim().toLowerCase();
8414
- if (normalized === "cursor" || normalized === "claude") {
8443
+ if (normalized === "cursor" || normalized === "claude" || normalized === "codex") {
8415
8444
  return normalized;
8416
8445
  }
8417
- console.log('Please enter "cursor" or "claude".');
8446
+ console.log('Please enter "cursor", "claude", or "codex".');
8418
8447
  }
8419
8448
  } finally {
8420
8449
  rl.close();
@@ -8433,7 +8462,7 @@ async function promptForConfirmation(question) {
8433
8462
 
8434
8463
  // src/install-one.ts
8435
8464
  function normalizeRelativePath(path2) {
8436
- return (0, import_node_path9.normalize)(path2).split(import_node_path9.sep).join("/");
8465
+ return (0, import_node_path10.normalize)(path2).split(import_node_path10.sep).join("/");
8437
8466
  }
8438
8467
  function assertSafeRelativePath(path2) {
8439
8468
  const rel = normalizeRelativePath(path2.trim());
@@ -8444,8 +8473,8 @@ function assertSafeRelativePath(path2) {
8444
8473
  }
8445
8474
  function safeJoin(root, relPath) {
8446
8475
  const rel = assertSafeRelativePath(relPath);
8447
- const target = (0, import_node_path9.resolve)(root, rel);
8448
- const fromRoot = normalizeRelativePath((0, import_node_path9.relative)(root, target));
8476
+ const target = (0, import_node_path10.resolve)(root, rel);
8477
+ const fromRoot = normalizeRelativePath((0, import_node_path10.relative)(root, target));
8449
8478
  if (fromRoot === ".." || fromRoot.startsWith("../") || fromRoot.startsWith("/")) {
8450
8479
  throw new Error(`Unsafe install path: ${relPath}`);
8451
8480
  }
@@ -8456,12 +8485,12 @@ function packageHelperSlug(name) {
8456
8485
  return `${scope}__${pkg}`;
8457
8486
  }
8458
8487
  function helperRootFor(configRoot, packageName, version) {
8459
- const base = (0, import_node_path9.basename)(configRoot) === ".aipm" ? (0, import_node_path9.join)(configRoot, "helpers") : (0, import_node_path9.join)(configRoot, ".aipm", "helpers");
8460
- return (0, import_node_path9.join)(base, packageHelperSlug(packageName), version);
8488
+ const base = (0, import_node_path10.basename)(configRoot) === ".aipm" ? (0, import_node_path10.join)(configRoot, "helpers") : (0, import_node_path10.join)(configRoot, ".aipm", "helpers");
8489
+ return (0, import_node_path10.join)(base, packageHelperSlug(packageName), version);
8461
8490
  }
8462
8491
  async function assertSourceFile(packageRoot, relPath) {
8463
8492
  const source = safeJoin(packageRoot, relPath);
8464
- const info = await (0, import_promises8.stat)(source).catch(() => null);
8493
+ const info = await (0, import_promises9.stat)(source).catch(() => null);
8465
8494
  if (!info?.isFile()) throw new Error(`Package install file not found: ${relPath}`);
8466
8495
  return source;
8467
8496
  }
@@ -8469,20 +8498,20 @@ async function copyMainFile(input2) {
8469
8498
  const source = await assertSourceFile(input2.packageRoot, input2.file.from);
8470
8499
  const target = safeJoin(input2.installRoot, input2.file.to);
8471
8500
  const overwrite = input2.file.overwrite ?? "fail";
8472
- const exists = await (0, import_promises8.stat)(target).catch(() => null);
8501
+ const exists = await (0, import_promises9.stat)(target).catch(() => null);
8473
8502
  if (exists) {
8474
8503
  if (overwrite === "skip") return null;
8475
8504
  if (overwrite === "fail") throw new Error(`Install target already exists: ${target}`);
8476
8505
  }
8477
- await (0, import_promises8.mkdir)((0, import_node_path9.dirname)(target), { recursive: true });
8478
- await (0, import_promises8.cp)(source, target, { force: overwrite === "replace" });
8506
+ await (0, import_promises9.mkdir)((0, import_node_path10.dirname)(target), { recursive: true });
8507
+ await (0, import_promises9.cp)(source, target, { force: overwrite === "replace" });
8479
8508
  return target;
8480
8509
  }
8481
8510
  async function copyHelperFile(input2) {
8482
8511
  const source = await assertSourceFile(input2.packageRoot, input2.file.from);
8483
- const target = safeJoin(input2.helperRoot, input2.file.to ?? (0, import_node_path9.basename)(input2.file.from));
8484
- await (0, import_promises8.mkdir)((0, import_node_path9.dirname)(target), { recursive: true });
8485
- await (0, import_promises8.cp)(source, target, { force: true });
8512
+ const target = safeJoin(input2.helperRoot, input2.file.to ?? (0, import_node_path10.basename)(input2.file.from));
8513
+ await (0, import_promises9.mkdir)((0, import_node_path10.dirname)(target), { recursive: true });
8514
+ await (0, import_promises9.cp)(source, target, { force: true });
8486
8515
  return target;
8487
8516
  }
8488
8517
  async function installPackageAssets(options) {
@@ -8499,7 +8528,7 @@ async function installPackageAssets(options) {
8499
8528
  }
8500
8529
  const helperRoot = helperRootFor(options.configRoot, options.packageName, options.version);
8501
8530
  if ((install.helperFiles ?? []).length > 0) {
8502
- await (0, import_promises8.rm)(helperRoot, { recursive: true, force: true });
8531
+ await (0, import_promises9.rm)(helperRoot, { recursive: true, force: true });
8503
8532
  }
8504
8533
  for (const file of install.helperFiles ?? []) {
8505
8534
  assets.helper.push(await copyHelperFile({ packageRoot: options.packageRoot, helperRoot, file }));
@@ -8544,7 +8573,7 @@ async function installOnePackage(options) {
8544
8573
  }
8545
8574
  let explicitTarget = options.explicitTarget;
8546
8575
  let preferredTools = options.project.preferredTools;
8547
- const { resolveInstallTools: resolveInstallTools2 } = await Promise.resolve().then(() => (init_dist4(), dist_exports));
8576
+ const { resolveInstallTools: resolveInstallTools2 } = await Promise.resolve().then(() => (init_dist5(), dist_exports));
8548
8577
  let tools = await resolveInstallTools2({
8549
8578
  projectRoot: installRoot,
8550
8579
  manifest,
@@ -8554,7 +8583,7 @@ async function installOnePackage(options) {
8554
8583
  if (tools.length === 0) {
8555
8584
  if (options.ci) {
8556
8585
  throw new Error(
8557
- "No tool detected. Use --target cursor|claude|* in CI mode."
8586
+ "No tool detected. Use --target cursor|claude|codex|* in CI mode."
8558
8587
  );
8559
8588
  }
8560
8589
  const choice = await promptForTool();
@@ -8575,7 +8604,7 @@ async function installOnePackage(options) {
8575
8604
  );
8576
8605
  const packageRoot = await unpackTarballToDirectory(tarball);
8577
8606
  try {
8578
- const skillMarkdown = await (0, import_promises8.readFile)(safeJoin(packageRoot, manifest.entry), "utf8");
8607
+ const skillMarkdown = await (0, import_promises9.readFile)(safeJoin(packageRoot, manifest.entry), "utf8");
8579
8608
  const result = await installSkillPackage({
8580
8609
  projectRoot: installRoot,
8581
8610
  manifest,
@@ -8616,23 +8645,23 @@ async function installOnePackage(options) {
8616
8645
  console.log(`Installed ${options.name}@${options.version} \u2192 ${result.resolvedTools.join(", ")}`);
8617
8646
  printPostInstallNotice(options.name, postInstall);
8618
8647
  } finally {
8619
- await (0, import_promises8.rm)(packageRoot, { recursive: true, force: true });
8648
+ await (0, import_promises9.rm)(packageRoot, { recursive: true, force: true });
8620
8649
  }
8621
8650
  }
8622
8651
 
8623
8652
  // src/doctor.ts
8624
8653
  var import_node_child_process3 = require("node:child_process");
8625
- var import_promises9 = require("node:fs/promises");
8626
- var import_node_path11 = require("node:path");
8654
+ var import_promises10 = require("node:fs/promises");
8655
+ var import_node_path12 = require("node:path");
8627
8656
  var import_node_util4 = require("node:util");
8628
8657
 
8629
8658
  // src/project-root.ts
8630
8659
  var import_node_os3 = require("node:os");
8631
- var import_node_path10 = require("node:path");
8660
+ var import_node_path11 = require("node:path");
8632
8661
  var import_node_process3 = require("node:process");
8633
8662
  function globalConfigDir(env2 = process.env) {
8634
8663
  const fromEnv = env2.AIPM_HOME?.trim();
8635
- return fromEnv ? fromEnv.replace(/\/$/, "") : (0, import_node_path10.join)((0, import_node_os3.homedir)(), ".aipm");
8664
+ return fromEnv ? fromEnv.replace(/\/$/, "") : (0, import_node_path11.join)((0, import_node_os3.homedir)(), ".aipm");
8636
8665
  }
8637
8666
  function resolveConfigRoot(options = {}) {
8638
8667
  return options.global ? globalConfigDir() : (0, import_node_process3.cwd)();
@@ -8663,11 +8692,11 @@ async function commandOutput(command, args) {
8663
8692
  }
8664
8693
  function npmGlobalBin(prefix) {
8665
8694
  if (!prefix) return null;
8666
- return process.platform === "win32" ? prefix : `${prefix}${import_node_path11.sep}bin`;
8695
+ return process.platform === "win32" ? prefix : `${prefix}${import_node_path12.sep}bin`;
8667
8696
  }
8668
8697
  function pathIncludes(pathDir) {
8669
8698
  if (!pathDir) return false;
8670
- return (process.env.PATH ?? "").split(import_node_path11.delimiter).includes(pathDir);
8699
+ return (process.env.PATH ?? "").split(import_node_path12.delimiter).includes(pathDir);
8671
8700
  }
8672
8701
  function shellPathHint(binDir) {
8673
8702
  if (!binDir) return "Run npm prefix -g and add its bin folder to PATH.";
@@ -8720,11 +8749,11 @@ async function runDoctor(options) {
8720
8749
  if (!options.publish) {
8721
8750
  const configLabel = options.global ? "Global config" : "Project config";
8722
8751
  try {
8723
- await (0, import_promises9.access)((0, import_node_path11.join)(configRoot, "aipm.package.json"));
8752
+ await (0, import_promises10.access)((0, import_node_path12.join)(configRoot, "aipm.package.json"));
8724
8753
  checks.push({
8725
8754
  name: configLabel,
8726
8755
  ok: true,
8727
- detail: `${(0, import_node_path11.join)(configRoot, "aipm.package.json")} exists (${scopeLabel(scope)}).`
8756
+ detail: `${(0, import_node_path12.join)(configRoot, "aipm.package.json")} exists (${scopeLabel(scope)}).`
8728
8757
  });
8729
8758
  } catch {
8730
8759
  checks.push({
@@ -8794,8 +8823,8 @@ async function runDoctor(options) {
8794
8823
 
8795
8824
  // src/prompt-install.ts
8796
8825
  var import_node_crypto2 = require("node:crypto");
8797
- var import_promises10 = require("node:fs/promises");
8798
- var import_node_path12 = require("node:path");
8826
+ var import_promises11 = require("node:fs/promises");
8827
+ var import_node_path13 = require("node:path");
8799
8828
  var PROMPT_SITE_ORIGIN = "https://www.aipm-registry.com";
8800
8829
  function parsePromptUrl(value) {
8801
8830
  let url;
@@ -8820,10 +8849,10 @@ function parsePromptUrl(value) {
8820
8849
  };
8821
8850
  }
8822
8851
  function promptDirectory(configRoot) {
8823
- return (0, import_node_path12.basename)(configRoot) === ".aipm" ? (0, import_node_path12.join)(configRoot, "prompts") : (0, import_node_path12.join)(configRoot, ".aipm", "prompts");
8852
+ return (0, import_node_path13.basename)(configRoot) === ".aipm" ? (0, import_node_path13.join)(configRoot, "prompts") : (0, import_node_path13.join)(configRoot, ".aipm", "prompts");
8824
8853
  }
8825
8854
  function promptSnapshotPath(configRoot, reference) {
8826
- return (0, import_node_path12.join)(promptDirectory(configRoot), `${reference.publisher}--${reference.slug}.md`);
8855
+ return (0, import_node_path13.join)(promptDirectory(configRoot), `${reference.publisher}--${reference.slug}.md`);
8827
8856
  }
8828
8857
  function canonicalPromptContent(prompt) {
8829
8858
  return JSON.stringify({
@@ -8882,7 +8911,7 @@ function emptyLock() {
8882
8911
  return { schemaVersion: "0.1", packages: {}, prompts: {} };
8883
8912
  }
8884
8913
  function installedRelativePath(configRoot, absolutePath) {
8885
- return (0, import_node_path12.relative)(configRoot, absolutePath).split("\\").join("/");
8914
+ return (0, import_node_path13.relative)(configRoot, absolutePath).split("\\").join("/");
8886
8915
  }
8887
8916
  async function installTrackedPrompt(input2) {
8888
8917
  const prompt = await fetchPromptDetail(
@@ -8900,11 +8929,11 @@ async function installTrackedPrompt(input2) {
8900
8929
  const contentHash = promptContentHash(prompt);
8901
8930
  const lock = await readLockfile(input2.configRoot) ?? emptyLock();
8902
8931
  const existing = lock.prompts[input2.reference.alias];
8903
- const fileExists = Boolean(await (0, import_promises10.stat)(outputPath).catch(() => null));
8932
+ const fileExists = Boolean(await (0, import_promises11.stat)(outputPath).catch(() => null));
8904
8933
  const changed = !existing || existing.contentHash !== contentHash || !fileExists;
8905
8934
  if (!input2.updateOnly || changed) {
8906
- await (0, import_promises10.mkdir)((0, import_node_path12.dirname)(outputPath), { recursive: true });
8907
- await (0, import_promises10.writeFile)(outputPath, renderPromptMarkdown(prompt, canonicalReference.url), "utf8");
8935
+ await (0, import_promises11.mkdir)((0, import_node_path13.dirname)(outputPath), { recursive: true });
8936
+ await (0, import_promises11.writeFile)(outputPath, renderPromptMarkdown(prompt, canonicalReference.url), "utf8");
8908
8937
  }
8909
8938
  if (input2.track) {
8910
8939
  const currentUrl = input2.project.prompts[input2.reference.alias];
@@ -8946,12 +8975,12 @@ function resolveTrackedPrompt(project, value) {
8946
8975
  return parsed ? { ...parsed, alias: value } : null;
8947
8976
  }
8948
8977
  async function readInstalledPrompt(configRoot, entry) {
8949
- return (0, import_promises10.readFile)((0, import_node_path12.join)(configRoot, entry.installedPath), "utf8");
8978
+ return (0, import_promises11.readFile)((0, import_node_path13.join)(configRoot, entry.installedPath), "utf8");
8950
8979
  }
8951
8980
  async function removeTrackedPrompt(input2) {
8952
8981
  const lock = await readLockfile(input2.configRoot);
8953
8982
  const entry = lock?.prompts[input2.reference.alias];
8954
- if (entry) await (0, import_promises10.rm)((0, import_node_path12.join)(input2.configRoot, entry.installedPath), { force: true });
8983
+ if (entry) await (0, import_promises11.rm)((0, import_node_path13.join)(input2.configRoot, entry.installedPath), { force: true });
8955
8984
  const prompts = { ...input2.project.prompts };
8956
8985
  delete prompts[input2.reference.alias];
8957
8986
  await writeProjectPackageJson(input2.configRoot, { ...input2.project, prompts });
@@ -8964,9 +8993,9 @@ async function removeTrackedPrompt(input2) {
8964
8993
 
8965
8994
  // src/version.ts
8966
8995
  var import_node_fs2 = require("node:fs");
8967
- var import_node_path13 = require("node:path");
8996
+ var import_node_path14 = require("node:path");
8968
8997
  function getCliVersion() {
8969
- const pkgPath = (0, import_node_path13.join)(__dirname, "..", "package.json");
8998
+ const pkgPath = (0, import_node_path14.join)(__dirname, "..", "package.json");
8970
8999
  const pkg = JSON.parse((0, import_node_fs2.readFileSync)(pkgPath, "utf8"));
8971
9000
  return pkg.version;
8972
9001
  }
@@ -9108,23 +9137,23 @@ function skillFolderName(name) {
9108
9137
  return folder;
9109
9138
  }
9110
9139
  async function writeStarterFile(path2, content) {
9111
- await (0, import_promises11.writeFile)(path2, content, { encoding: "utf8", flag: "wx" });
9140
+ await (0, import_promises12.writeFile)(path2, content, { encoding: "utf8", flag: "wx" });
9112
9141
  }
9113
9142
  async function inferEntryFromSource(source, fallback) {
9114
- const sourceInfo = await (0, import_promises11.stat)(source);
9115
- if (sourceInfo.isFile()) return (0, import_node_path14.basename)(source);
9143
+ const sourceInfo = await (0, import_promises12.stat)(source);
9144
+ if (sourceInfo.isFile()) return (0, import_node_path15.basename)(source);
9116
9145
  if (!sourceInfo.isDirectory()) return fallback;
9117
- const entries = await (0, import_promises11.readdir)(source);
9146
+ const entries = await (0, import_promises12.readdir)(source);
9118
9147
  if (entries.includes(fallback)) return fallback;
9119
9148
  return entries.find((entry) => entry.endsWith(".md")) ?? entries.find((entry) => entry.endsWith(".mdc")) ?? fallback;
9120
9149
  }
9121
9150
  async function copySourceIntoSkillRoot(source, root, sourceLabel) {
9122
- const sourceInfo = await (0, import_promises11.stat)(source);
9123
- await (0, import_promises11.mkdir)(root, { recursive: true });
9151
+ const sourceInfo = await (0, import_promises12.stat)(source);
9152
+ await (0, import_promises12.mkdir)(root, { recursive: true });
9124
9153
  if (sourceInfo.isDirectory()) {
9125
- const entries = await (0, import_promises11.readdir)(source);
9154
+ const entries = await (0, import_promises12.readdir)(source);
9126
9155
  for (const entry of entries) {
9127
- await (0, import_promises11.cp)((0, import_node_path14.join)(source, entry), (0, import_node_path14.join)(root, entry), {
9156
+ await (0, import_promises12.cp)((0, import_node_path15.join)(source, entry), (0, import_node_path15.join)(root, entry), {
9128
9157
  recursive: true,
9129
9158
  force: false,
9130
9159
  errorOnExist: true
@@ -9133,7 +9162,7 @@ async function copySourceIntoSkillRoot(source, root, sourceLabel) {
9133
9162
  return;
9134
9163
  }
9135
9164
  if (sourceInfo.isFile()) {
9136
- await (0, import_promises11.cp)(source, (0, import_node_path14.join)(root, (0, import_node_path14.basename)(source)), { force: false, errorOnExist: true });
9165
+ await (0, import_promises12.cp)(source, (0, import_node_path15.join)(root, (0, import_node_path15.basename)(source)), { force: false, errorOnExist: true });
9137
9166
  return;
9138
9167
  }
9139
9168
  throw new Error(`Unsupported source path: ${sourceLabel}`);
@@ -9167,11 +9196,11 @@ function packageDashboardUrl(name) {
9167
9196
  return `${DASHBOARD_URL}/packages/${name.replace(/^@/, "")}`;
9168
9197
  }
9169
9198
  function helperRootFromTrackedPath(path2) {
9170
- const parts = path2.split(import_node_path14.sep).filter(Boolean);
9199
+ const parts = path2.split(import_node_path15.sep).filter(Boolean);
9171
9200
  const helpersIndex = parts.lastIndexOf("helpers");
9172
9201
  if (helpersIndex === -1 || parts.length <= helpersIndex + 2) return null;
9173
- const prefix = path2.startsWith(import_node_path14.sep) ? import_node_path14.sep : "";
9174
- return (0, import_node_path14.join)(prefix, ...parts.slice(0, helpersIndex + 3));
9202
+ const prefix = path2.startsWith(import_node_path15.sep) ? import_node_path15.sep : "";
9203
+ return (0, import_node_path15.join)(prefix, ...parts.slice(0, helpersIndex + 3));
9175
9204
  }
9176
9205
  async function showInstalledPrompt(configRoot, packageArg) {
9177
9206
  const { name } = parsePackageArg(packageArg);
@@ -9184,7 +9213,7 @@ async function showInstalledPrompt(configRoot, packageArg) {
9184
9213
  if (entry.postInstall.status === "cleaned") {
9185
9214
  throw new Error(`Setup helper files were cleaned for ${name}. Reinstall the package to restore them.`);
9186
9215
  }
9187
- const content = await (0, import_promises11.readFile)(entry.postInstall.promptFile, "utf8").catch(() => {
9216
+ const content = await (0, import_promises12.readFile)(entry.postInstall.promptFile, "utf8").catch(() => {
9188
9217
  throw new Error(`Setup prompt file is missing: ${entry.postInstall?.promptFile}`);
9189
9218
  });
9190
9219
  console.log(`Prompt file: ${entry.postInstall.promptFile}`);
@@ -9217,9 +9246,9 @@ async function cleanupInstalledHelpers(options) {
9217
9246
  entry.installedAssets.helper.map((path2) => helperRootFromTrackedPath(path2)).filter((path2) => Boolean(path2))
9218
9247
  );
9219
9248
  if (roots.size > 0) {
9220
- for (const root of roots) await (0, import_promises11.rm)(root, { recursive: true, force: true });
9249
+ for (const root of roots) await (0, import_promises12.rm)(root, { recursive: true, force: true });
9221
9250
  } else {
9222
- for (const helperPath of entry.installedAssets.helper) await (0, import_promises11.rm)(helperPath, { force: true });
9251
+ for (const helperPath of entry.installedAssets.helper) await (0, import_promises12.rm)(helperPath, { force: true });
9223
9252
  }
9224
9253
  await writeLockfile(options.configRoot, {
9225
9254
  ...lock,
@@ -9513,9 +9542,9 @@ function buildStarterQualityMetadata(options) {
9513
9542
  }
9514
9543
  async function initSkill(opts) {
9515
9544
  if (!isValidScopeName(opts.name)) throw new Error("Invalid @scope/name");
9516
- const root = opts.here ? (0, import_node_process5.cwd)() : (0, import_node_path14.resolve)((0, import_node_process5.cwd)(), opts.dir ?? skillFolderName(opts.name));
9545
+ const root = opts.here ? (0, import_node_process5.cwd)() : (0, import_node_path15.resolve)((0, import_node_process5.cwd)(), opts.dir ?? skillFolderName(opts.name));
9517
9546
  const cdTarget = opts.here ? null : opts.dir ?? skillFolderName(opts.name);
9518
- const source = opts.from ? (0, import_node_path14.resolve)(opts.from) : null;
9547
+ const source = opts.from ? (0, import_node_path15.resolve)(opts.from) : null;
9519
9548
  const entry = source ? await inferEntryFromSource(source, opts.entry) : opts.entry;
9520
9549
  const template = parseSkillTemplate(opts.template ?? "blank");
9521
9550
  const manifest = PackageManifestSchema.parse({
@@ -9536,17 +9565,17 @@ async function initSkill(opts) {
9536
9565
  if (source) {
9537
9566
  await copySourceIntoSkillRoot(source, root, source);
9538
9567
  } else {
9539
- await (0, import_promises11.mkdir)(root, { recursive: true });
9568
+ await (0, import_promises12.mkdir)(root, { recursive: true });
9540
9569
  }
9541
- await writeStarterFile((0, import_node_path14.join)(root, "aipm.manifest.json"), JSON.stringify(manifest, null, 2) + "\n");
9570
+ await writeStarterFile((0, import_node_path15.join)(root, "aipm.manifest.json"), JSON.stringify(manifest, null, 2) + "\n");
9542
9571
  if (!opts.from) {
9543
9572
  await writeStarterFile(
9544
- (0, import_node_path14.join)(root, entry),
9573
+ (0, import_node_path15.join)(root, entry),
9545
9574
  SKILL_TEMPLATES[template](opts.name)
9546
9575
  );
9547
9576
  }
9548
9577
  await writeStarterFile(
9549
- (0, import_node_path14.join)(root, ".aipmignore"),
9578
+ (0, import_node_path15.join)(root, ".aipmignore"),
9550
9579
  [
9551
9580
  "# Files that should never be published with this skill",
9552
9581
  ".env*",
@@ -9564,14 +9593,14 @@ async function initSkill(opts) {
9564
9593
  ""
9565
9594
  ].join("\n")
9566
9595
  );
9567
- await (0, import_promises11.mkdir)((0, import_node_path14.join)(root, ".aipm"), { recursive: true });
9596
+ await (0, import_promises12.mkdir)((0, import_node_path15.join)(root, ".aipm"), { recursive: true });
9568
9597
  console.log(`Created ${opts.name} skill folder: ${root}`);
9569
9598
  printPublishGuide(
9570
9599
  opts.from ? `Copied ${opts.from} into ${root} and created aipm.manifest.json, .aipmignore, and the local publish state folder.` : `Created ${root} with aipm.manifest.json, ${entry}, .aipmignore, and the local publish state folder.`,
9571
9600
  cdTarget ? `Run cd ${cdTarget}, edit/review the files, then run aipm publish add .` : "Edit/review the files, then run aipm publish add ."
9572
9601
  );
9573
9602
  }
9574
- program2.command("init").description("Create aipm.package.json in the current project or globally").option(GLOBAL_OPTION, GLOBAL_OPTION_DESC).option("--registry <url>", "Default registry URL").option("--target <tool>", "Preferred install target: cursor, claude, or *").action(async (opts) => {
9603
+ program2.command("init").description("Create aipm.package.json in the current project or globally").option(GLOBAL_OPTION, GLOBAL_OPTION_DESC).option("--registry <url>", "Default registry URL").option("--target <tool>", "Preferred install target: cursor, claude, codex, or *").action(async (opts) => {
9575
9604
  const scope = { global: opts.global };
9576
9605
  const configRoot = resolveConfigRoot(scope);
9577
9606
  const existing = await readProjectPackageJson(configRoot);
@@ -9579,7 +9608,7 @@ program2.command("init").description("Create aipm.package.json in the current pr
9579
9608
  console.log(`aipm.package.json already exists (${scopeLabel(scope)}).`);
9580
9609
  return;
9581
9610
  }
9582
- if (scope.global) await (0, import_promises11.mkdir)(configRoot, { recursive: true });
9611
+ if (scope.global) await (0, import_promises12.mkdir)(configRoot, { recursive: true });
9583
9612
  const installRoot = resolveInstallRoot(scope);
9584
9613
  const detected = await detectToolsInProject(installRoot);
9585
9614
  const parsedTarget = parseTargetFlag(opts.target);
@@ -9682,7 +9711,7 @@ program2.command("config").description("Show resolved AIPM CLI and project confi
9682
9711
  console.log(`Auth file: ${data.authFile}`);
9683
9712
  console.log(`Publish guide: ${data.publishDoc}`);
9684
9713
  });
9685
- program2.command("add <package-or-prompt>").description("Add a skill package or an AIPM prompt URL").option(GLOBAL_OPTION, GLOBAL_OPTION_DESC).option("--registry <url>", "Registry base URL").option("--target <tool>", "cursor, claude, or *").option("--token <token>", "Install token for private packages").option("--ci", "Non-interactive; fail if prompt needed").action(async (pkgArg, opts) => {
9714
+ program2.command("add <package-or-prompt>").description("Add a skill package or an AIPM prompt URL").option(GLOBAL_OPTION, GLOBAL_OPTION_DESC).option("--registry <url>", "Registry base URL").option("--target <tool>", "cursor, claude, codex, or *").option("--token <token>", "Install token for private packages").option("--ci", "Non-interactive; fail if prompt needed").action(async (pkgArg, opts) => {
9686
9715
  const scope = { global: opts.global };
9687
9716
  const configRoot = resolveConfigRoot(scope);
9688
9717
  const installRoot = resolveInstallRoot(scope);
@@ -9754,7 +9783,7 @@ program2.command("search [query]").description("Search public registry packages"
9754
9783
  console.log(` ${meta}`);
9755
9784
  }
9756
9785
  });
9757
- program2.command("install").description("Install all packages from aipm.package.json").option(GLOBAL_OPTION, GLOBAL_OPTION_DESC).option("--registry <url>", "Registry base URL").option("--target <tool>", "cursor, claude, or *").option("--token <token>", "Install token for private packages").option("--ci", "Non-interactive").action(async (opts) => {
9786
+ program2.command("install").description("Install all packages from aipm.package.json").option(GLOBAL_OPTION, GLOBAL_OPTION_DESC).option("--registry <url>", "Registry base URL").option("--target <tool>", "cursor, claude, codex, or *").option("--token <token>", "Install token for private packages").option("--ci", "Non-interactive").action(async (opts) => {
9758
9787
  const scope = { global: opts.global };
9759
9788
  const configRoot = resolveConfigRoot(scope);
9760
9789
  const installRoot = resolveInstallRoot(scope);
@@ -9811,7 +9840,7 @@ program2.command("show-prompt <package>").description("Show the manual setup pro
9811
9840
  await showInstalledPrompt(resolveConfigRoot({ global: opts.global }), pkgArg);
9812
9841
  });
9813
9842
  function promptImageContentType(path2) {
9814
- const extension = (0, import_node_path14.extname)(path2).toLowerCase();
9843
+ const extension = (0, import_node_path15.extname)(path2).toLowerCase();
9815
9844
  if (extension === ".png") return "image/png";
9816
9845
  if (extension === ".jpg" || extension === ".jpeg") return "image/jpeg";
9817
9846
  if (extension === ".webp") return "image/webp";
@@ -9822,8 +9851,8 @@ promptCommand.command("publish <file>").description("Publish one prompt or a bat
9822
9851
  const registry = registryFromEnvOrDefault(opts.registry);
9823
9852
  const accessToken = await authTokenForRegistry(registry, { throwOnFailure: true });
9824
9853
  if (!accessToken) throw new Error("Run aipm login before publishing prompts.");
9825
- const absoluteFile = (0, import_node_path14.resolve)(file);
9826
- const parsed = JSON.parse(await (0, import_promises11.readFile)(absoluteFile, "utf8"));
9854
+ const absoluteFile = (0, import_node_path15.resolve)(file);
9855
+ const parsed = JSON.parse(await (0, import_promises12.readFile)(absoluteFile, "utf8"));
9827
9856
  const rows = Array.isArray(parsed) ? parsed : "prompts" in parsed ? parsed.prompts : [parsed];
9828
9857
  if (rows.length === 0) throw new Error("Prompt publish file contains no prompts.");
9829
9858
  if (!opts.yes) {
@@ -9834,10 +9863,10 @@ promptCommand.command("publish <file>").description("Publish one prompt or a bat
9834
9863
  const { sampleImagePath, ...input2 } = row;
9835
9864
  let sampleImage;
9836
9865
  if (sampleImagePath) {
9837
- const imagePath = (0, import_node_path14.resolve)((0, import_node_path14.dirname)(absoluteFile), sampleImagePath);
9866
+ const imagePath = (0, import_node_path15.resolve)((0, import_node_path15.dirname)(absoluteFile), sampleImagePath);
9838
9867
  sampleImage = {
9839
- data: await (0, import_promises11.readFile)(imagePath),
9840
- filename: (0, import_node_path14.basename)(imagePath),
9868
+ data: await (0, import_promises12.readFile)(imagePath),
9869
+ filename: (0, import_node_path15.basename)(imagePath),
9841
9870
  contentType: promptImageContentType(imagePath)
9842
9871
  };
9843
9872
  }
@@ -9860,8 +9889,8 @@ var publish = program2.command("publish [dir]").description("Stage, validate, an
9860
9889
  publish.help();
9861
9890
  return;
9862
9891
  }
9863
- const abs = (0, import_node_path14.resolve)(dir);
9864
- const manifestRaw = await (0, import_promises11.readFile)((0, import_node_path14.join)(abs, "aipm.manifest.json"), "utf8");
9892
+ const abs = (0, import_node_path15.resolve)(dir);
9893
+ const manifestRaw = await (0, import_promises12.readFile)((0, import_node_path15.join)(abs, "aipm.manifest.json"), "utf8");
9865
9894
  const manifest = PackageManifestSchema.parse(JSON.parse(manifestRaw));
9866
9895
  const tarball = await packDirectory(abs);
9867
9896
  const registry = registryFromEnvOrDefault(opts.registry);
@@ -10047,7 +10076,7 @@ program2.command("remove <package-or-prompt>").alias("rm").description("Remove a
10047
10076
  console.log(`Removed ${name} from AIPM ${scopeLabel(scope)} files.`);
10048
10077
  console.log("Adapter-written files are not deleted yet; review your project before committing.");
10049
10078
  });
10050
- program2.command("update [package]").description("Update one installed package, or all installed packages, to the latest registry version").option(GLOBAL_OPTION, GLOBAL_OPTION_DESC).option("--registry <url>", "Registry base URL").option("--target <tool>", "cursor, claude, or *").option("--token <token>", "Install token for private packages").option("--ci", "Non-interactive").action(async (pkgArg, opts) => {
10079
+ program2.command("update [package]").description("Update one installed package, or all installed packages, to the latest registry version").option(GLOBAL_OPTION, GLOBAL_OPTION_DESC).option("--registry <url>", "Registry base URL").option("--target <tool>", "cursor, claude, codex, or *").option("--token <token>", "Install token for private packages").option("--ci", "Non-interactive").action(async (pkgArg, opts) => {
10051
10080
  const scope = { global: opts.global };
10052
10081
  const configRoot = resolveConfigRoot(scope);
10053
10082
  const installRoot = resolveInstallRoot(scope);