@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 +166 -137
- package/dist/bin.cjs.map +4 -4
- package/package.json +3 -3
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
|
|
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
|
|
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
|
|
7845
|
-
var
|
|
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
|
-
|
|
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
|
|
7854
|
-
var
|
|
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
|
|
7860
|
-
var
|
|
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,
|
|
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,
|
|
7904
|
+
return (0, import_node_path6.join)(root, STATE_PATH);
|
|
7878
7905
|
}
|
|
7879
7906
|
function normalizePublishPath(root, filePath) {
|
|
7880
|
-
const abs = (0,
|
|
7881
|
-
const rel = (0,
|
|
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,
|
|
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,
|
|
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,
|
|
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,
|
|
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,
|
|
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,
|
|
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,
|
|
7955
|
-
const info = await (0,
|
|
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,
|
|
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,
|
|
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,
|
|
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,
|
|
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,
|
|
8031
|
-
const info = await (0,
|
|
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,
|
|
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,
|
|
8056
|
-
await (0,
|
|
8057
|
-
await (0,
|
|
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,
|
|
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,
|
|
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:
|
|
8081
|
-
const { join:
|
|
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(
|
|
8084
|
-
const tgzPath =
|
|
8085
|
-
await
|
|
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
|
|
8308
|
+
var import_promises7 = require("node:fs/promises");
|
|
8282
8309
|
var import_node_os2 = require("node:os");
|
|
8283
|
-
var
|
|
8284
|
-
var AUTH_FILE = (0,
|
|
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,
|
|
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,
|
|
8299
|
-
await (0,
|
|
8300
|
-
await (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
|
-
|
|
8330
|
-
var
|
|
8331
|
-
var
|
|
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
|
|
8335
|
-
var
|
|
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,
|
|
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,
|
|
8349
|
-
(0,
|
|
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,
|
|
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,
|
|
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 === "*")
|
|
8388
|
-
|
|
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 "
|
|
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,
|
|
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,
|
|
8448
|
-
const fromRoot = normalizeRelativePath((0,
|
|
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,
|
|
8460
|
-
return (0,
|
|
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,
|
|
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,
|
|
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,
|
|
8478
|
-
await (0,
|
|
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,
|
|
8484
|
-
await (0,
|
|
8485
|
-
await (0,
|
|
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,
|
|
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(() => (
|
|
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,
|
|
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,
|
|
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
|
|
8626
|
-
var
|
|
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
|
|
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,
|
|
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}${
|
|
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(
|
|
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,
|
|
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,
|
|
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
|
|
8798
|
-
var
|
|
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,
|
|
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,
|
|
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,
|
|
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,
|
|
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,
|
|
8907
|
-
await (0,
|
|
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,
|
|
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,
|
|
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
|
|
8996
|
+
var import_node_path14 = require("node:path");
|
|
8968
8997
|
function getCliVersion() {
|
|
8969
|
-
const pkgPath = (0,
|
|
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,
|
|
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,
|
|
9115
|
-
if (sourceInfo.isFile()) return (0,
|
|
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,
|
|
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,
|
|
9123
|
-
await (0,
|
|
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,
|
|
9154
|
+
const entries = await (0, import_promises12.readdir)(source);
|
|
9126
9155
|
for (const entry of entries) {
|
|
9127
|
-
await (0,
|
|
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,
|
|
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(
|
|
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(
|
|
9174
|
-
return (0,
|
|
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,
|
|
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,
|
|
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,
|
|
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,
|
|
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,
|
|
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,
|
|
9568
|
+
await (0, import_promises12.mkdir)(root, { recursive: true });
|
|
9540
9569
|
}
|
|
9541
|
-
await writeStarterFile((0,
|
|
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,
|
|
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,
|
|
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,
|
|
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,
|
|
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,
|
|
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,
|
|
9826
|
-
const parsed = JSON.parse(await (0,
|
|
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,
|
|
9866
|
+
const imagePath = (0, import_node_path15.resolve)((0, import_node_path15.dirname)(absoluteFile), sampleImagePath);
|
|
9838
9867
|
sampleImage = {
|
|
9839
|
-
data: await (0,
|
|
9840
|
-
filename: (0,
|
|
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,
|
|
9864
|
-
const manifestRaw = await (0,
|
|
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);
|