@aipm-registry/cli 0.1.7 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/bin.cjs +318 -176
- package/dist/bin.cjs.map +4 -4
- package/package.json +9 -3
package/dist/bin.cjs
CHANGED
|
@@ -4155,13 +4155,19 @@ var init_zod = __esm({
|
|
|
4155
4155
|
});
|
|
4156
4156
|
|
|
4157
4157
|
// ../../packages/schemas/dist/manifest.js
|
|
4158
|
-
|
|
4158
|
+
function expandTargets(targets) {
|
|
4159
|
+
if (targets.includes("*"))
|
|
4160
|
+
return [...ALL_TOOLS];
|
|
4161
|
+
return targets.filter((t) => t !== "*");
|
|
4162
|
+
}
|
|
4163
|
+
var AiToolSchema, ALL_TOOLS, PackageManifestSchema;
|
|
4159
4164
|
var init_manifest = __esm({
|
|
4160
4165
|
"../../packages/schemas/dist/manifest.js"() {
|
|
4161
4166
|
"use strict";
|
|
4162
4167
|
init_zod();
|
|
4163
4168
|
init_scope_name();
|
|
4164
|
-
AiToolSchema = external_exports.enum(["cursor", "claude"]);
|
|
4169
|
+
AiToolSchema = external_exports.enum(["cursor", "claude", "*"]);
|
|
4170
|
+
ALL_TOOLS = ["cursor", "claude"];
|
|
4165
4171
|
PackageManifestSchema = external_exports.object({
|
|
4166
4172
|
schemaVersion: external_exports.literal("0.1"),
|
|
4167
4173
|
name: external_exports.string().regex(SCOPE_NAME_REGEX, "name must be @scope/name"),
|
|
@@ -4245,26 +4251,36 @@ async function detectToolsInProject(projectRoot) {
|
|
|
4245
4251
|
detected.push("claude");
|
|
4246
4252
|
return detected;
|
|
4247
4253
|
}
|
|
4254
|
+
function manifestAllowsTool(manifest, tool) {
|
|
4255
|
+
if (manifest.targets.includes("*"))
|
|
4256
|
+
return true;
|
|
4257
|
+
return manifest.targets.includes(tool);
|
|
4258
|
+
}
|
|
4248
4259
|
async function resolveInstallTools(options) {
|
|
4249
4260
|
const { manifest } = options;
|
|
4250
|
-
const
|
|
4261
|
+
const expandedAllowed = expandTargets(manifest.targets);
|
|
4251
4262
|
if (options.explicitTarget) {
|
|
4252
|
-
if (
|
|
4263
|
+
if (options.explicitTarget === "*") {
|
|
4264
|
+
return [...ALL_TOOLS];
|
|
4265
|
+
}
|
|
4266
|
+
if (!manifestAllowsTool(manifest, options.explicitTarget)) {
|
|
4253
4267
|
throw new Error(`Package ${manifest.name} does not target "${options.explicitTarget}". Targets: ${manifest.targets.join(", ")}`);
|
|
4254
4268
|
}
|
|
4255
4269
|
return [options.explicitTarget];
|
|
4256
4270
|
}
|
|
4257
4271
|
const detected = await detectToolsInProject(options.projectRoot);
|
|
4258
4272
|
if (detected.length > 0) {
|
|
4259
|
-
const intersection = detected.filter((t) =>
|
|
4273
|
+
const intersection = detected.filter((t) => manifestAllowsTool(manifest, t));
|
|
4260
4274
|
if (intersection.length === 0) {
|
|
4261
4275
|
throw new Error(`Package ${manifest.name} targets [${manifest.targets.join(", ")}] but project only has [${detected.join(", ")}].`);
|
|
4262
4276
|
}
|
|
4263
4277
|
return intersection;
|
|
4264
4278
|
}
|
|
4265
|
-
const preferred = (options.preferredTools ?? []).filter((t) =>
|
|
4279
|
+
const preferred = expandTargets(options.preferredTools ?? []).filter((t) => manifestAllowsTool(manifest, t));
|
|
4266
4280
|
if (preferred.length > 0)
|
|
4267
4281
|
return preferred;
|
|
4282
|
+
if (manifest.targets.includes("*"))
|
|
4283
|
+
return expandedAllowed;
|
|
4268
4284
|
return [];
|
|
4269
4285
|
}
|
|
4270
4286
|
var import_promises, import_node_path2;
|
|
@@ -4273,6 +4289,7 @@ var init_detect_tools = __esm({
|
|
|
4273
4289
|
"use strict";
|
|
4274
4290
|
import_promises = require("node:fs/promises");
|
|
4275
4291
|
import_node_path2 = require("node:path");
|
|
4292
|
+
init_dist();
|
|
4276
4293
|
}
|
|
4277
4294
|
});
|
|
4278
4295
|
|
|
@@ -4331,7 +4348,7 @@ async function installSkillPackage(options) {
|
|
|
4331
4348
|
explicitTarget: options.explicitTarget
|
|
4332
4349
|
});
|
|
4333
4350
|
if (tools.length === 0) {
|
|
4334
|
-
throw new Error("No AI tool detected (.cursor/ or .claude/). Use --target cursor|claude or set preferredTools in aipm.package.json.");
|
|
4351
|
+
throw new Error("No AI tool detected (.cursor/ or .claude/). Use --target cursor|claude|* or set preferredTools in aipm.package.json.");
|
|
4335
4352
|
}
|
|
4336
4353
|
const installed = {};
|
|
4337
4354
|
for (const tool of tools) {
|
|
@@ -4375,74 +4392,6 @@ var init_dist4 = __esm({
|
|
|
4375
4392
|
}
|
|
4376
4393
|
});
|
|
4377
4394
|
|
|
4378
|
-
// src/project-files.ts
|
|
4379
|
-
var project_files_exports = {};
|
|
4380
|
-
__export(project_files_exports, {
|
|
4381
|
-
parseTargetFlag: () => parseTargetFlag,
|
|
4382
|
-
readLockfile: () => readLockfile,
|
|
4383
|
-
readProjectPackageJson: () => readProjectPackageJson,
|
|
4384
|
-
resolveRegistryUrl: () => resolveRegistryUrl,
|
|
4385
|
-
upsertLockEntry: () => upsertLockEntry,
|
|
4386
|
-
writeLockfile: () => writeLockfile,
|
|
4387
|
-
writeProjectPackageJson: () => writeProjectPackageJson
|
|
4388
|
-
});
|
|
4389
|
-
async function readProjectPackageJson(projectRoot) {
|
|
4390
|
-
try {
|
|
4391
|
-
const raw = await (0, import_promises7.readFile)((0, import_node_path7.join)(projectRoot, PACKAGE_JSON), "utf8");
|
|
4392
|
-
return ProjectPackageJsonSchema.parse(JSON.parse(raw));
|
|
4393
|
-
} catch {
|
|
4394
|
-
return null;
|
|
4395
|
-
}
|
|
4396
|
-
}
|
|
4397
|
-
async function writeProjectPackageJson(projectRoot, data) {
|
|
4398
|
-
await (0, import_promises7.writeFile)(
|
|
4399
|
-
(0, import_node_path7.join)(projectRoot, PACKAGE_JSON),
|
|
4400
|
-
JSON.stringify(data, null, 2) + "\n",
|
|
4401
|
-
"utf8"
|
|
4402
|
-
);
|
|
4403
|
-
}
|
|
4404
|
-
async function readLockfile(projectRoot) {
|
|
4405
|
-
try {
|
|
4406
|
-
const raw = await (0, import_promises7.readFile)((0, import_node_path7.join)(projectRoot, LOCKFILE), "utf8");
|
|
4407
|
-
return LockfileSchema.parse(JSON.parse(raw));
|
|
4408
|
-
} catch {
|
|
4409
|
-
return null;
|
|
4410
|
-
}
|
|
4411
|
-
}
|
|
4412
|
-
async function writeLockfile(projectRoot, data) {
|
|
4413
|
-
await (0, import_promises7.writeFile)((0, import_node_path7.join)(projectRoot, LOCKFILE), JSON.stringify(data, null, 2) + "\n", "utf8");
|
|
4414
|
-
}
|
|
4415
|
-
function upsertLockEntry(lock, name, entry) {
|
|
4416
|
-
return {
|
|
4417
|
-
...lock,
|
|
4418
|
-
packages: { ...lock.packages, [name]: entry }
|
|
4419
|
-
};
|
|
4420
|
-
}
|
|
4421
|
-
function resolveRegistryUrl(project, flag, fallback) {
|
|
4422
|
-
const fromEnv = process.env.AIPM_REGISTRY_URL ?? process.env.AIPM_REGISTRY;
|
|
4423
|
-
if (flag) return flag.replace(/\/$/, "");
|
|
4424
|
-
if (project?.registry) return project.registry.replace(/\/$/, "");
|
|
4425
|
-
if (fromEnv) return fromEnv.replace(/\/$/, "");
|
|
4426
|
-
if (fallback) return fallback.replace(/\/$/, "");
|
|
4427
|
-
throw new Error("Registry URL required: set registry in aipm.package.json or AIPM_REGISTRY_URL");
|
|
4428
|
-
}
|
|
4429
|
-
function parseTargetFlag(target) {
|
|
4430
|
-
if (!target) return void 0;
|
|
4431
|
-
if (target === "cursor" || target === "claude") return target;
|
|
4432
|
-
throw new Error('--target must be "cursor" or "claude"');
|
|
4433
|
-
}
|
|
4434
|
-
var import_promises7, import_node_path7, PACKAGE_JSON, LOCKFILE;
|
|
4435
|
-
var init_project_files = __esm({
|
|
4436
|
-
"src/project-files.ts"() {
|
|
4437
|
-
"use strict";
|
|
4438
|
-
import_promises7 = require("node:fs/promises");
|
|
4439
|
-
import_node_path7 = require("node:path");
|
|
4440
|
-
init_dist();
|
|
4441
|
-
PACKAGE_JSON = "aipm.package.json";
|
|
4442
|
-
LOCKFILE = "aipm-lock.json";
|
|
4443
|
-
}
|
|
4444
|
-
});
|
|
4445
|
-
|
|
4446
4395
|
// ../../node_modules/.pnpm/commander@15.0.0/node_modules/commander/lib/error.js
|
|
4447
4396
|
var CommanderError = class extends Error {
|
|
4448
4397
|
/**
|
|
@@ -7814,8 +7763,8 @@ var program = new Command();
|
|
|
7814
7763
|
// src/bin.ts
|
|
7815
7764
|
var import_node_child_process4 = require("node:child_process");
|
|
7816
7765
|
var import_promises9 = require("node:fs/promises");
|
|
7817
|
-
var
|
|
7818
|
-
var
|
|
7766
|
+
var import_node_path11 = require("node:path");
|
|
7767
|
+
var import_node_process5 = require("node:process");
|
|
7819
7768
|
init_dist();
|
|
7820
7769
|
init_dist4();
|
|
7821
7770
|
|
|
@@ -8033,21 +7982,21 @@ async function packStagedFiles(root) {
|
|
|
8033
7982
|
const tempDir = await (0, import_promises6.mkdtemp)((0, import_node_path6.join)((0, import_node_os.tmpdir)(), "aipm-publish-stage-"));
|
|
8034
7983
|
try {
|
|
8035
7984
|
await copyStagedFiles(root, tempDir);
|
|
8036
|
-
return packDirectory(tempDir);
|
|
7985
|
+
return await packDirectory(tempDir);
|
|
8037
7986
|
} finally {
|
|
8038
7987
|
await (0, import_promises6.rm)(tempDir, { recursive: true, force: true });
|
|
8039
7988
|
}
|
|
8040
7989
|
}
|
|
8041
7990
|
async function unpackTarballToBuffer(tarball, entry) {
|
|
8042
7991
|
const { mkdtemp: mkdtemp2, rm: rm3, writeFile: writeFile6 } = await import("node:fs/promises");
|
|
8043
|
-
const { join:
|
|
7992
|
+
const { join: join11 } = await import("node:path");
|
|
8044
7993
|
const { tmpdir: tmpdir2 } = await import("node:os");
|
|
8045
|
-
const tempDir = await mkdtemp2(
|
|
8046
|
-
const tgzPath =
|
|
7994
|
+
const tempDir = await mkdtemp2(join11(tmpdir2(), "aipm-install-"));
|
|
7995
|
+
const tgzPath = join11(tempDir, "pkg.tgz");
|
|
8047
7996
|
try {
|
|
8048
7997
|
await writeFile6(tgzPath, tarball);
|
|
8049
7998
|
await execFileAsync("tar", ["-xzf", tgzPath, "-C", tempDir]);
|
|
8050
|
-
return (0, import_promises5.readFile)(
|
|
7999
|
+
return (0, import_promises5.readFile)(join11(tempDir, entry), "utf8");
|
|
8051
8000
|
} finally {
|
|
8052
8001
|
await rm3(tempDir, { recursive: true, force: true });
|
|
8053
8002
|
}
|
|
@@ -8123,7 +8072,70 @@ async function fetchPackageTarball(registry, name, version) {
|
|
|
8123
8072
|
|
|
8124
8073
|
// src/install-one.ts
|
|
8125
8074
|
init_dist4();
|
|
8126
|
-
|
|
8075
|
+
|
|
8076
|
+
// src/project-files.ts
|
|
8077
|
+
var import_promises7 = require("node:fs/promises");
|
|
8078
|
+
var import_node_path7 = require("node:path");
|
|
8079
|
+
init_dist();
|
|
8080
|
+
var PACKAGE_JSON = "aipm.package.json";
|
|
8081
|
+
var LOCKFILE = "aipm-lock.json";
|
|
8082
|
+
async function readProjectPackageJson(projectRoot) {
|
|
8083
|
+
try {
|
|
8084
|
+
const raw = await (0, import_promises7.readFile)((0, import_node_path7.join)(projectRoot, PACKAGE_JSON), "utf8");
|
|
8085
|
+
return ProjectPackageJsonSchema.parse(JSON.parse(raw));
|
|
8086
|
+
} catch {
|
|
8087
|
+
return null;
|
|
8088
|
+
}
|
|
8089
|
+
}
|
|
8090
|
+
async function writeProjectPackageJson(projectRoot, data) {
|
|
8091
|
+
await (0, import_promises7.writeFile)(
|
|
8092
|
+
(0, import_node_path7.join)(projectRoot, PACKAGE_JSON),
|
|
8093
|
+
JSON.stringify(data, null, 2) + "\n",
|
|
8094
|
+
"utf8"
|
|
8095
|
+
);
|
|
8096
|
+
}
|
|
8097
|
+
async function readLockfile(projectRoot) {
|
|
8098
|
+
try {
|
|
8099
|
+
const raw = await (0, import_promises7.readFile)((0, import_node_path7.join)(projectRoot, LOCKFILE), "utf8");
|
|
8100
|
+
return LockfileSchema.parse(JSON.parse(raw));
|
|
8101
|
+
} catch {
|
|
8102
|
+
return null;
|
|
8103
|
+
}
|
|
8104
|
+
}
|
|
8105
|
+
async function writeLockfile(projectRoot, data) {
|
|
8106
|
+
await (0, import_promises7.writeFile)((0, import_node_path7.join)(projectRoot, LOCKFILE), JSON.stringify(data, null, 2) + "\n", "utf8");
|
|
8107
|
+
}
|
|
8108
|
+
function upsertLockEntry(lock, name, entry) {
|
|
8109
|
+
return {
|
|
8110
|
+
...lock,
|
|
8111
|
+
packages: { ...lock.packages, [name]: entry }
|
|
8112
|
+
};
|
|
8113
|
+
}
|
|
8114
|
+
function resolveRegistryUrl(project, flag, fallback) {
|
|
8115
|
+
const fromEnv = process.env.AIPM_REGISTRY_URL ?? process.env.AIPM_REGISTRY;
|
|
8116
|
+
if (flag) return flag.replace(/\/$/, "");
|
|
8117
|
+
if (project?.registry) return project.registry.replace(/\/$/, "");
|
|
8118
|
+
if (fromEnv) return fromEnv.replace(/\/$/, "");
|
|
8119
|
+
if (fallback) return fallback.replace(/\/$/, "");
|
|
8120
|
+
throw new Error("Registry URL required: set registry in aipm.package.json or AIPM_REGISTRY_URL");
|
|
8121
|
+
}
|
|
8122
|
+
function parseTargetFlag(target) {
|
|
8123
|
+
if (!target) return void 0;
|
|
8124
|
+
if (target === "cursor" || target === "claude" || target === "*") return target;
|
|
8125
|
+
throw new Error('--target must be "cursor", "claude", or "*"');
|
|
8126
|
+
}
|
|
8127
|
+
function parseTargetsFlag(value) {
|
|
8128
|
+
const targets = value.split(",").map((target) => target.trim()).filter(Boolean);
|
|
8129
|
+
if (targets.length === 0) throw new Error("At least one target is required.");
|
|
8130
|
+
for (const target of targets) {
|
|
8131
|
+
if (target !== "cursor" && target !== "claude" && target !== "*") {
|
|
8132
|
+
throw new Error('--targets must contain only "cursor", "claude", and/or "*"');
|
|
8133
|
+
}
|
|
8134
|
+
}
|
|
8135
|
+
const unique = [...new Set(targets)];
|
|
8136
|
+
if (unique.includes("*")) return ["*"];
|
|
8137
|
+
return unique;
|
|
8138
|
+
}
|
|
8127
8139
|
|
|
8128
8140
|
// src/prompt.ts
|
|
8129
8141
|
var readline = __toESM(require("node:readline/promises"), 1);
|
|
@@ -8148,6 +8160,8 @@ async function promptForTool() {
|
|
|
8148
8160
|
|
|
8149
8161
|
// src/install-one.ts
|
|
8150
8162
|
async function installOnePackage(options) {
|
|
8163
|
+
const configRoot = options.configRoot;
|
|
8164
|
+
const installRoot = options.installRoot ?? configRoot;
|
|
8151
8165
|
await assertRegistryReachable(options.registry);
|
|
8152
8166
|
const { manifest, integrity: remoteIntegrity } = await fetchPackageMetadata(
|
|
8153
8167
|
options.registry,
|
|
@@ -8158,7 +8172,7 @@ async function installOnePackage(options) {
|
|
|
8158
8172
|
let preferredTools = options.project.preferredTools;
|
|
8159
8173
|
const { resolveInstallTools: resolveInstallTools2 } = await Promise.resolve().then(() => (init_dist4(), dist_exports));
|
|
8160
8174
|
let tools = await resolveInstallTools2({
|
|
8161
|
-
projectRoot:
|
|
8175
|
+
projectRoot: installRoot,
|
|
8162
8176
|
manifest,
|
|
8163
8177
|
preferredTools,
|
|
8164
8178
|
explicitTarget
|
|
@@ -8166,14 +8180,14 @@ async function installOnePackage(options) {
|
|
|
8166
8180
|
if (tools.length === 0) {
|
|
8167
8181
|
if (options.ci) {
|
|
8168
8182
|
throw new Error(
|
|
8169
|
-
"No tool detected. Use --target cursor|claude in CI mode."
|
|
8183
|
+
"No tool detected. Use --target cursor|claude|* in CI mode."
|
|
8170
8184
|
);
|
|
8171
8185
|
}
|
|
8172
8186
|
const choice = await promptForTool();
|
|
8173
8187
|
explicitTarget = choice;
|
|
8174
8188
|
preferredTools = [choice];
|
|
8175
8189
|
tools = await resolveInstallTools2({
|
|
8176
|
-
projectRoot:
|
|
8190
|
+
projectRoot: installRoot,
|
|
8177
8191
|
manifest,
|
|
8178
8192
|
preferredTools,
|
|
8179
8193
|
explicitTarget
|
|
@@ -8186,13 +8200,13 @@ async function installOnePackage(options) {
|
|
|
8186
8200
|
);
|
|
8187
8201
|
const skillMarkdown = await unpackTarballToBuffer(tarball, manifest.entry);
|
|
8188
8202
|
const result = await installSkillPackage({
|
|
8189
|
-
projectRoot:
|
|
8203
|
+
projectRoot: installRoot,
|
|
8190
8204
|
manifest,
|
|
8191
8205
|
skillMarkdown,
|
|
8192
8206
|
preferredTools,
|
|
8193
8207
|
explicitTarget
|
|
8194
8208
|
});
|
|
8195
|
-
const lock = await readLockfile(
|
|
8209
|
+
const lock = await readLockfile(configRoot) ?? {
|
|
8196
8210
|
schemaVersion: "0.1",
|
|
8197
8211
|
packages: {}
|
|
8198
8212
|
};
|
|
@@ -8202,7 +8216,7 @@ async function installOnePackage(options) {
|
|
|
8202
8216
|
if (paths) installed[tool] = paths;
|
|
8203
8217
|
}
|
|
8204
8218
|
await writeLockfile(
|
|
8205
|
-
|
|
8219
|
+
configRoot,
|
|
8206
8220
|
upsertLockEntry(lock, options.name, {
|
|
8207
8221
|
version: options.version,
|
|
8208
8222
|
integrity: remoteIntegrity,
|
|
@@ -8217,9 +8231,31 @@ async function installOnePackage(options) {
|
|
|
8217
8231
|
// src/doctor.ts
|
|
8218
8232
|
var import_node_child_process3 = require("node:child_process");
|
|
8219
8233
|
var import_promises8 = require("node:fs/promises");
|
|
8220
|
-
var
|
|
8234
|
+
var import_node_path9 = require("node:path");
|
|
8221
8235
|
var import_node_util4 = require("node:util");
|
|
8222
|
-
|
|
8236
|
+
|
|
8237
|
+
// src/project-root.ts
|
|
8238
|
+
var import_node_os2 = require("node:os");
|
|
8239
|
+
var import_node_path8 = require("node:path");
|
|
8240
|
+
var import_node_process3 = require("node:process");
|
|
8241
|
+
function globalConfigDir(env2 = process.env) {
|
|
8242
|
+
const fromEnv = env2.AIPM_HOME?.trim();
|
|
8243
|
+
return fromEnv ? fromEnv.replace(/\/$/, "") : (0, import_node_path8.join)((0, import_node_os2.homedir)(), ".aipm");
|
|
8244
|
+
}
|
|
8245
|
+
function resolveConfigRoot(options = {}) {
|
|
8246
|
+
return options.global ? globalConfigDir() : (0, import_node_process3.cwd)();
|
|
8247
|
+
}
|
|
8248
|
+
function resolveInstallRoot(options = {}) {
|
|
8249
|
+
return options.global ? (0, import_node_os2.homedir)() : (0, import_node_process3.cwd)();
|
|
8250
|
+
}
|
|
8251
|
+
function scopeLabel(options) {
|
|
8252
|
+
return options.global ? "global" : "project";
|
|
8253
|
+
}
|
|
8254
|
+
function initRequiredMessage(options) {
|
|
8255
|
+
return options.global ? "Run aipm init -g first" : "Run aipm init first";
|
|
8256
|
+
}
|
|
8257
|
+
|
|
8258
|
+
// src/doctor.ts
|
|
8223
8259
|
var execFileAsync2 = (0, import_node_util4.promisify)(import_node_child_process3.execFile);
|
|
8224
8260
|
var MIN_NODE_MAJOR = 20;
|
|
8225
8261
|
async function commandOutput(command, args) {
|
|
@@ -8235,11 +8271,11 @@ async function commandOutput(command, args) {
|
|
|
8235
8271
|
}
|
|
8236
8272
|
function npmGlobalBin(prefix) {
|
|
8237
8273
|
if (!prefix) return null;
|
|
8238
|
-
return process.platform === "win32" ? prefix : `${prefix}${
|
|
8274
|
+
return process.platform === "win32" ? prefix : `${prefix}${import_node_path9.sep}bin`;
|
|
8239
8275
|
}
|
|
8240
8276
|
function pathIncludes(pathDir) {
|
|
8241
8277
|
if (!pathDir) return false;
|
|
8242
|
-
return (process.env.PATH ?? "").split(
|
|
8278
|
+
return (process.env.PATH ?? "").split(import_node_path9.delimiter).includes(pathDir);
|
|
8243
8279
|
}
|
|
8244
8280
|
function shellPathHint(binDir) {
|
|
8245
8281
|
if (!binDir) return "Run npm prefix -g and add its bin folder to PATH.";
|
|
@@ -8253,8 +8289,10 @@ async function commandExists(command) {
|
|
|
8253
8289
|
return await commandOutput(probe, args) !== null;
|
|
8254
8290
|
}
|
|
8255
8291
|
async function runDoctor(options) {
|
|
8292
|
+
const scope = { global: options.global };
|
|
8293
|
+
const configRoot = resolveConfigRoot(scope);
|
|
8256
8294
|
const root = process.cwd();
|
|
8257
|
-
const project = await readProjectPackageJson(
|
|
8295
|
+
const project = await readProjectPackageJson(configRoot);
|
|
8258
8296
|
const registry = resolveRegistryUrl(project, options.registry, "https://api.aipm-registry.com");
|
|
8259
8297
|
const nodeMajor = Number(process.versions.node.split(".")[0]);
|
|
8260
8298
|
const npmPrefix = await commandOutput("npm", ["prefix", "-g"]);
|
|
@@ -8288,11 +8326,20 @@ async function runDoctor(options) {
|
|
|
8288
8326
|
});
|
|
8289
8327
|
}
|
|
8290
8328
|
if (!options.publish) {
|
|
8329
|
+
const configLabel = options.global ? "Global config" : "Project config";
|
|
8291
8330
|
try {
|
|
8292
|
-
await (0, import_promises8.access)("aipm.package.json");
|
|
8293
|
-
checks.push({
|
|
8331
|
+
await (0, import_promises8.access)((0, import_node_path9.join)(configRoot, "aipm.package.json"));
|
|
8332
|
+
checks.push({
|
|
8333
|
+
name: configLabel,
|
|
8334
|
+
ok: true,
|
|
8335
|
+
detail: `${(0, import_node_path9.join)(configRoot, "aipm.package.json")} exists (${scopeLabel(scope)}).`
|
|
8336
|
+
});
|
|
8294
8337
|
} catch {
|
|
8295
|
-
checks.push({
|
|
8338
|
+
checks.push({
|
|
8339
|
+
name: configLabel,
|
|
8340
|
+
ok: false,
|
|
8341
|
+
detail: initRequiredMessage(scope)
|
|
8342
|
+
});
|
|
8296
8343
|
}
|
|
8297
8344
|
}
|
|
8298
8345
|
try {
|
|
@@ -8353,18 +8400,95 @@ async function runDoctor(options) {
|
|
|
8353
8400
|
}
|
|
8354
8401
|
}
|
|
8355
8402
|
|
|
8356
|
-
// src/bin.ts
|
|
8357
|
-
init_project_files();
|
|
8358
|
-
|
|
8359
8403
|
// src/version.ts
|
|
8360
8404
|
var import_node_fs2 = require("node:fs");
|
|
8361
|
-
var
|
|
8405
|
+
var import_node_path10 = require("node:path");
|
|
8362
8406
|
function getCliVersion() {
|
|
8363
|
-
const pkgPath = (0,
|
|
8407
|
+
const pkgPath = (0, import_node_path10.join)(__dirname, "..", "package.json");
|
|
8364
8408
|
const pkg = JSON.parse((0, import_node_fs2.readFileSync)(pkgPath, "utf8"));
|
|
8365
8409
|
return pkg.version;
|
|
8366
8410
|
}
|
|
8367
8411
|
|
|
8412
|
+
// src/cli-update-check.ts
|
|
8413
|
+
var import_node_process4 = require("node:process");
|
|
8414
|
+
var CLI_PACKAGE_NAME = "@aipm-registry/cli";
|
|
8415
|
+
var CLI_UPDATE_COMMAND = `npm install -g ${CLI_PACKAGE_NAME}`;
|
|
8416
|
+
var NPM_REGISTRY = "https://registry.npmjs.org";
|
|
8417
|
+
var FETCH_TIMEOUT_MS = 3e3;
|
|
8418
|
+
function parseSemVer(version) {
|
|
8419
|
+
const match = version.trim().match(/^(\d+)\.(\d+)\.(\d+)/);
|
|
8420
|
+
if (!match) return null;
|
|
8421
|
+
return {
|
|
8422
|
+
major: Number(match[1]),
|
|
8423
|
+
minor: Number(match[2]),
|
|
8424
|
+
patch: Number(match[3])
|
|
8425
|
+
};
|
|
8426
|
+
}
|
|
8427
|
+
function isSemVerNewer(current, latest) {
|
|
8428
|
+
if (latest.major !== current.major) return latest.major > current.major;
|
|
8429
|
+
if (latest.minor !== current.minor) return latest.minor > current.minor;
|
|
8430
|
+
return latest.patch > current.patch;
|
|
8431
|
+
}
|
|
8432
|
+
function classifyCliUpdate(current, latest) {
|
|
8433
|
+
const cur = parseSemVer(current);
|
|
8434
|
+
const lat = parseSemVer(latest);
|
|
8435
|
+
if (!cur || !lat || !isSemVerNewer(cur, lat)) return "none";
|
|
8436
|
+
if (lat.major > cur.major) return "major";
|
|
8437
|
+
return "patch-minor";
|
|
8438
|
+
}
|
|
8439
|
+
async function fetchLatestCliVersion(fetchImpl = fetch) {
|
|
8440
|
+
try {
|
|
8441
|
+
const response = await fetchImpl(
|
|
8442
|
+
`${NPM_REGISTRY}/${encodeURIComponent(CLI_PACKAGE_NAME)}/latest`,
|
|
8443
|
+
{
|
|
8444
|
+
headers: { Accept: "application/json" },
|
|
8445
|
+
signal: AbortSignal.timeout(FETCH_TIMEOUT_MS)
|
|
8446
|
+
}
|
|
8447
|
+
);
|
|
8448
|
+
if (!response.ok) return null;
|
|
8449
|
+
const data = await response.json();
|
|
8450
|
+
return data.version ?? null;
|
|
8451
|
+
} catch {
|
|
8452
|
+
return null;
|
|
8453
|
+
}
|
|
8454
|
+
}
|
|
8455
|
+
function formatCliUpdateNotice(options) {
|
|
8456
|
+
const { currentVersion, latestVersion, level } = options;
|
|
8457
|
+
const cmd = CLI_UPDATE_COMMAND;
|
|
8458
|
+
if (level === "major") {
|
|
8459
|
+
return `AIPM CLI ${latestVersion} is available (you have ${currentVersion}). Update now: ${cmd}`;
|
|
8460
|
+
}
|
|
8461
|
+
return `A new AIPM CLI version is available (${currentVersion} \u2192 ${latestVersion}). Run: ${cmd}`;
|
|
8462
|
+
}
|
|
8463
|
+
function printCliUpdateNotice(options) {
|
|
8464
|
+
const useColor2 = options.useColor ?? import_node_process4.stderr.isTTY;
|
|
8465
|
+
const writeInfo = options.writeInfo ?? ((message2) => console.log(message2));
|
|
8466
|
+
const writeWarn = options.writeWarn ?? ((message2) => console.error(message2));
|
|
8467
|
+
const message = formatCliUpdateNotice(options);
|
|
8468
|
+
if (options.level === "major") {
|
|
8469
|
+
const red = useColor2 ? "\x1B[31m" : "";
|
|
8470
|
+
const reset = useColor2 ? "\x1B[0m" : "";
|
|
8471
|
+
writeWarn(`${red}${message}${reset}`);
|
|
8472
|
+
return;
|
|
8473
|
+
}
|
|
8474
|
+
writeInfo(message);
|
|
8475
|
+
}
|
|
8476
|
+
async function notifyCliUpdateIfNeeded(currentVersion, options) {
|
|
8477
|
+
const latestVersion = await (options?.fetchLatest ?? fetchLatestCliVersion)();
|
|
8478
|
+
if (!latestVersion) return "none";
|
|
8479
|
+
const level = classifyCliUpdate(currentVersion, latestVersion);
|
|
8480
|
+
if (level === "none") return "none";
|
|
8481
|
+
printCliUpdateNotice({
|
|
8482
|
+
currentVersion,
|
|
8483
|
+
latestVersion,
|
|
8484
|
+
level,
|
|
8485
|
+
useColor: options?.useColor,
|
|
8486
|
+
writeInfo: options?.writeInfo,
|
|
8487
|
+
writeWarn: options?.writeWarn
|
|
8488
|
+
});
|
|
8489
|
+
return level;
|
|
8490
|
+
}
|
|
8491
|
+
|
|
8368
8492
|
// src/bin.ts
|
|
8369
8493
|
var CLI_VERSION = getCliVersion();
|
|
8370
8494
|
var program2 = new Command();
|
|
@@ -8372,6 +8496,8 @@ var DEFAULT_REGISTRY = "https://api.aipm-registry.com";
|
|
|
8372
8496
|
var SITE_URL = "https://aipm-registry.com";
|
|
8373
8497
|
var PUBLISH_DOC_URL = "https://aipm-registry.com/publish";
|
|
8374
8498
|
var DASHBOARD_URL = "https://aipm-registry.com/dashboard";
|
|
8499
|
+
var GLOBAL_OPTION = "-g, --global";
|
|
8500
|
+
var GLOBAL_OPTION_DESC = "Use global config (~/.aipm) and install skills under your home directory";
|
|
8375
8501
|
program2.name("aipm").description("AI package manager").enablePositionalOptions().version(CLI_VERSION, "-v, --version", "output the current version").option("--verbose", "Print extra diagnostic output").option("--quiet", "Reduce non-essential output").addHelpText(
|
|
8376
8502
|
"after",
|
|
8377
8503
|
`
|
|
@@ -8380,8 +8506,10 @@ Examples:
|
|
|
8380
8506
|
$ npm install -g @aipm-registry/cli
|
|
8381
8507
|
$ aipm doctor
|
|
8382
8508
|
$ aipm init
|
|
8509
|
+
$ aipm init -g
|
|
8383
8510
|
$ aipm search sentry
|
|
8384
8511
|
$ aipm add @scope/name@1.0.0 --target cursor --ci
|
|
8512
|
+
$ aipm add @scope/name -g
|
|
8385
8513
|
$ aipm publish init --name @org/skill
|
|
8386
8514
|
$ cd skill
|
|
8387
8515
|
$ aipm publish add .
|
|
@@ -8409,7 +8537,7 @@ async function writeStarterFile(path2, content) {
|
|
|
8409
8537
|
}
|
|
8410
8538
|
async function inferEntryFromSource(source, fallback) {
|
|
8411
8539
|
const sourceInfo = await (0, import_promises9.stat)(source);
|
|
8412
|
-
if (sourceInfo.isFile()) return (0,
|
|
8540
|
+
if (sourceInfo.isFile()) return (0, import_node_path11.basename)(source);
|
|
8413
8541
|
if (!sourceInfo.isDirectory()) return fallback;
|
|
8414
8542
|
const entries = await (0, import_promises9.readdir)(source);
|
|
8415
8543
|
if (entries.includes(fallback)) return fallback;
|
|
@@ -8506,16 +8634,6 @@ async function printPublishPreview(root, json) {
|
|
|
8506
8634
|
preview.warnings.length > 0 ? "Fix the warnings, then run aipm publish preview again." : "Run aipm publish validate."
|
|
8507
8635
|
);
|
|
8508
8636
|
}
|
|
8509
|
-
function parseTargets(value) {
|
|
8510
|
-
const targets = value.split(",").map((target) => target.trim()).filter(Boolean);
|
|
8511
|
-
if (targets.length === 0) throw new Error("At least one target is required.");
|
|
8512
|
-
for (const target of targets) {
|
|
8513
|
-
if (target !== "cursor" && target !== "claude") {
|
|
8514
|
-
throw new Error('--targets must contain only "cursor" and/or "claude"');
|
|
8515
|
-
}
|
|
8516
|
-
}
|
|
8517
|
-
return [...new Set(targets)];
|
|
8518
|
-
}
|
|
8519
8637
|
var SKILL_TEMPLATES = {
|
|
8520
8638
|
blank: (name) => `# ${name}
|
|
8521
8639
|
|
|
@@ -8574,10 +8692,10 @@ function parseSkillTemplate(value) {
|
|
|
8574
8692
|
}
|
|
8575
8693
|
async function initSkill(opts) {
|
|
8576
8694
|
if (!isValidScopeName(opts.name)) throw new Error("Invalid @scope/name");
|
|
8577
|
-
const root = opts.here ? (0,
|
|
8695
|
+
const root = opts.here ? (0, import_node_process5.cwd)() : (0, import_node_path11.resolve)((0, import_node_process5.cwd)(), opts.dir ?? skillFolderName(opts.name));
|
|
8578
8696
|
const cdTarget = opts.here ? null : opts.dir ?? skillFolderName(opts.name);
|
|
8579
8697
|
await (0, import_promises9.mkdir)(root, { recursive: true });
|
|
8580
|
-
const source = opts.from ? (0,
|
|
8698
|
+
const source = opts.from ? (0, import_node_path11.resolve)(opts.from) : null;
|
|
8581
8699
|
const entry = source ? await inferEntryFromSource(source, opts.entry) : opts.entry;
|
|
8582
8700
|
const manifest = {
|
|
8583
8701
|
schemaVersion: "0.1",
|
|
@@ -8586,7 +8704,7 @@ async function initSkill(opts) {
|
|
|
8586
8704
|
type: "skill",
|
|
8587
8705
|
description: opts.description,
|
|
8588
8706
|
entry,
|
|
8589
|
-
targets:
|
|
8707
|
+
targets: parseTargetsFlag(opts.targets),
|
|
8590
8708
|
license: "Apache-2.0"
|
|
8591
8709
|
};
|
|
8592
8710
|
PackageManifestSchema.parse(manifest);
|
|
@@ -8595,21 +8713,21 @@ async function initSkill(opts) {
|
|
|
8595
8713
|
if (sourceInfo.isDirectory()) {
|
|
8596
8714
|
await (0, import_promises9.cp)(source, root, { recursive: true, force: false, errorOnExist: true });
|
|
8597
8715
|
} else if (sourceInfo.isFile()) {
|
|
8598
|
-
await (0, import_promises9.cp)(source, (0,
|
|
8716
|
+
await (0, import_promises9.cp)(source, (0, import_node_path11.join)(root, (0, import_node_path11.basename)(source)), { force: false, errorOnExist: true });
|
|
8599
8717
|
} else {
|
|
8600
8718
|
throw new Error(`Unsupported source path: ${opts.from}`);
|
|
8601
8719
|
}
|
|
8602
8720
|
}
|
|
8603
|
-
await writeStarterFile((0,
|
|
8721
|
+
await writeStarterFile((0, import_node_path11.join)(root, "aipm.manifest.json"), JSON.stringify(manifest, null, 2) + "\n");
|
|
8604
8722
|
if (!opts.from) {
|
|
8605
8723
|
const template = parseSkillTemplate(opts.template ?? "blank");
|
|
8606
8724
|
await writeStarterFile(
|
|
8607
|
-
(0,
|
|
8725
|
+
(0, import_node_path11.join)(root, entry),
|
|
8608
8726
|
SKILL_TEMPLATES[template](opts.name)
|
|
8609
8727
|
);
|
|
8610
8728
|
}
|
|
8611
8729
|
await writeStarterFile(
|
|
8612
|
-
(0,
|
|
8730
|
+
(0, import_node_path11.join)(root, ".aipmignore"),
|
|
8613
8731
|
[
|
|
8614
8732
|
"# Files that should never be published with this skill",
|
|
8615
8733
|
".env*",
|
|
@@ -8627,34 +8745,37 @@ async function initSkill(opts) {
|
|
|
8627
8745
|
""
|
|
8628
8746
|
].join("\n")
|
|
8629
8747
|
);
|
|
8630
|
-
await (0, import_promises9.mkdir)((0,
|
|
8748
|
+
await (0, import_promises9.mkdir)((0, import_node_path11.join)(root, ".aipm"), { recursive: true });
|
|
8631
8749
|
console.log(`Created ${opts.name} skill folder: ${root}`);
|
|
8632
8750
|
printPublishGuide(
|
|
8633
8751
|
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.`,
|
|
8634
8752
|
cdTarget ? `Run cd ${cdTarget}, edit/review the files, then run aipm publish add .` : "Edit/review the files, then run aipm publish add ."
|
|
8635
8753
|
);
|
|
8636
8754
|
}
|
|
8637
|
-
program2.command("init").description("Create aipm.package.json in the current project").option("--registry <url>", "Default registry URL").action(async (opts) => {
|
|
8638
|
-
const
|
|
8639
|
-
const
|
|
8755
|
+
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").action(async (opts) => {
|
|
8756
|
+
const scope = { global: opts.global };
|
|
8757
|
+
const configRoot = resolveConfigRoot(scope);
|
|
8758
|
+
const existing = await readProjectPackageJson(configRoot);
|
|
8640
8759
|
if (existing) {
|
|
8641
|
-
console.log(
|
|
8760
|
+
console.log(`aipm.package.json already exists (${scopeLabel(scope)}).`);
|
|
8642
8761
|
return;
|
|
8643
8762
|
}
|
|
8644
|
-
|
|
8763
|
+
if (scope.global) await (0, import_promises9.mkdir)(configRoot, { recursive: true });
|
|
8764
|
+
const installRoot = resolveInstallRoot(scope);
|
|
8765
|
+
const detected = await detectToolsInProject(installRoot);
|
|
8645
8766
|
let preferredTools = detected;
|
|
8646
8767
|
if (detected.length === 0) {
|
|
8647
8768
|
const choice = await promptForTool();
|
|
8648
8769
|
preferredTools = [choice];
|
|
8649
8770
|
}
|
|
8650
8771
|
const registry = registryFromEnvOrDefault(opts.registry);
|
|
8651
|
-
await writeProjectPackageJson(
|
|
8772
|
+
await writeProjectPackageJson(configRoot, {
|
|
8652
8773
|
schemaVersion: "0.1",
|
|
8653
8774
|
registry,
|
|
8654
8775
|
preferredTools: preferredTools.length ? preferredTools : void 0,
|
|
8655
8776
|
packages: {}
|
|
8656
8777
|
});
|
|
8657
|
-
console.log(`Created aipm.package.json (registry: ${registry})`);
|
|
8778
|
+
console.log(`Created aipm.package.json (${scopeLabel(scope)}, registry: ${registry})`);
|
|
8658
8779
|
});
|
|
8659
8780
|
program2.command("login").description("Open the AIPM dashboard sign-in page").option("--no-open", "Print the URL without opening a browser").action(async (opts) => {
|
|
8660
8781
|
const url = `${SITE_URL}/login`;
|
|
@@ -8663,17 +8784,22 @@ program2.command("login").description("Open the AIPM dashboard sign-in page").op
|
|
|
8663
8784
|
if (opts.open) await openUrl(url);
|
|
8664
8785
|
else console.log(`Open: ${url}`);
|
|
8665
8786
|
});
|
|
8666
|
-
program2.command("config").description("Show resolved AIPM CLI and project configuration").option("--registry <url>", "Registry base URL").option("--json", "Print machine-readable JSON").action(async (opts) => {
|
|
8667
|
-
const
|
|
8668
|
-
const
|
|
8669
|
-
const
|
|
8787
|
+
program2.command("config").description("Show resolved AIPM CLI and project configuration").option(GLOBAL_OPTION, GLOBAL_OPTION_DESC).option("--registry <url>", "Registry base URL").option("--json", "Print machine-readable JSON").action(async (opts) => {
|
|
8788
|
+
const scope = { global: opts.global };
|
|
8789
|
+
const configRoot = resolveConfigRoot(scope);
|
|
8790
|
+
const installRoot = resolveInstallRoot(scope);
|
|
8791
|
+
const project = await readProjectPackageJson(configRoot);
|
|
8792
|
+
const lock = await readLockfile(configRoot);
|
|
8670
8793
|
const registry = resolveRegistryUrl(project, opts.registry, DEFAULT_REGISTRY);
|
|
8671
8794
|
const data = {
|
|
8672
8795
|
cliVersion: CLI_VERSION,
|
|
8673
8796
|
nodeVersion: process.versions.node,
|
|
8674
|
-
|
|
8797
|
+
scope: scopeLabel(scope),
|
|
8798
|
+
configRoot,
|
|
8799
|
+
installRoot,
|
|
8800
|
+
cwd: (0, import_node_process5.cwd)(),
|
|
8675
8801
|
registry,
|
|
8676
|
-
envRegistry:
|
|
8802
|
+
envRegistry: import_node_process5.env.AIPM_REGISTRY_URL ?? import_node_process5.env.AIPM_REGISTRY ?? null,
|
|
8677
8803
|
hasProjectConfig: Boolean(project),
|
|
8678
8804
|
projectPackages: project ? Object.keys(project.packages) : [],
|
|
8679
8805
|
hasLockfile: Boolean(lock),
|
|
@@ -8686,7 +8812,10 @@ program2.command("config").description("Show resolved AIPM CLI and project confi
|
|
|
8686
8812
|
}
|
|
8687
8813
|
console.log(`CLI: ${data.cliVersion}`);
|
|
8688
8814
|
console.log(`Node: ${data.nodeVersion}`);
|
|
8689
|
-
console.log(`
|
|
8815
|
+
console.log(`Scope: ${data.scope}`);
|
|
8816
|
+
console.log(`Config: ${data.configRoot}`);
|
|
8817
|
+
console.log(`Install root: ${data.installRoot}`);
|
|
8818
|
+
console.log(`Working directory: ${data.cwd}`);
|
|
8690
8819
|
console.log(`Registry: ${data.registry}`);
|
|
8691
8820
|
console.log(`Env registry: ${data.envRegistry ?? "not set"}`);
|
|
8692
8821
|
console.log(`Project config: ${data.hasProjectConfig ? "found" : "not found"}`);
|
|
@@ -8695,11 +8824,13 @@ program2.command("config").description("Show resolved AIPM CLI and project confi
|
|
|
8695
8824
|
console.log(`Installed packages: ${data.installedPackages.length}`);
|
|
8696
8825
|
console.log(`Publish guide: ${data.publishDoc}`);
|
|
8697
8826
|
});
|
|
8698
|
-
program2.command("add <package>").description("Add and install a package @scope/name[@version]").option("--registry <url>", "Registry base URL").option("--target <tool>", "cursor or
|
|
8827
|
+
program2.command("add <package>").description("Add and install a package @scope/name[@version]").option(GLOBAL_OPTION, GLOBAL_OPTION_DESC).option("--registry <url>", "Registry base URL").option("--target <tool>", "cursor, claude, or *").option("--ci", "Non-interactive; fail if prompt needed").action(async (pkgArg, opts) => {
|
|
8699
8828
|
const { name, version: requestedVersion } = parsePackageArg(pkgArg);
|
|
8700
|
-
const
|
|
8701
|
-
|
|
8702
|
-
|
|
8829
|
+
const scope = { global: opts.global };
|
|
8830
|
+
const configRoot = resolveConfigRoot(scope);
|
|
8831
|
+
const installRoot = resolveInstallRoot(scope);
|
|
8832
|
+
let project = await readProjectPackageJson(configRoot);
|
|
8833
|
+
if (!project) throw new Error(initRequiredMessage(scope));
|
|
8703
8834
|
const registry = resolveRegistryUrl(project, opts.registry, DEFAULT_REGISTRY);
|
|
8704
8835
|
const version = requestedVersion ?? project.packages[name] ?? await latestVersionForPackage(registry, name);
|
|
8705
8836
|
if (!version) throw new Error("Specify version: aipm add @scope/pkg@1.0.0");
|
|
@@ -8707,9 +8838,10 @@ program2.command("add <package>").description("Add and install a package @scope/
|
|
|
8707
8838
|
...project,
|
|
8708
8839
|
packages: { ...project.packages, [name]: version.replace(/^\^/, "") }
|
|
8709
8840
|
};
|
|
8710
|
-
await writeProjectPackageJson(
|
|
8841
|
+
await writeProjectPackageJson(configRoot, project);
|
|
8711
8842
|
await installOnePackage({
|
|
8712
|
-
|
|
8843
|
+
configRoot,
|
|
8844
|
+
installRoot,
|
|
8713
8845
|
registry,
|
|
8714
8846
|
name,
|
|
8715
8847
|
version: version.replace(/^\^/, ""),
|
|
@@ -8717,6 +8849,9 @@ program2.command("add <package>").description("Add and install a package @scope/
|
|
|
8717
8849
|
explicitTarget: parseTargetFlag(opts.target),
|
|
8718
8850
|
ci: opts.ci
|
|
8719
8851
|
});
|
|
8852
|
+
if (!opts.ci && !program2.opts().quiet) {
|
|
8853
|
+
await notifyCliUpdateIfNeeded(CLI_VERSION);
|
|
8854
|
+
}
|
|
8720
8855
|
});
|
|
8721
8856
|
program2.command("search [query]").description("Search public registry packages").option("--registry <url>", "Registry base URL").option("--limit <number>", "Maximum results", "20").option("--json", "Print machine-readable JSON").action(async (query = "", opts) => {
|
|
8722
8857
|
const registry = registryFromEnvOrDefault(opts.registry);
|
|
@@ -8737,15 +8872,18 @@ program2.command("search [query]").description("Search public registry packages"
|
|
|
8737
8872
|
console.log(` ${meta}`);
|
|
8738
8873
|
}
|
|
8739
8874
|
});
|
|
8740
|
-
program2.command("install").description("Install all packages from aipm.package.json").option("--registry <url>", "Registry base URL").option("--target <tool>", "cursor or
|
|
8741
|
-
const
|
|
8742
|
-
const
|
|
8743
|
-
|
|
8875
|
+
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("--ci", "Non-interactive").action(async (opts) => {
|
|
8876
|
+
const scope = { global: opts.global };
|
|
8877
|
+
const configRoot = resolveConfigRoot(scope);
|
|
8878
|
+
const installRoot = resolveInstallRoot(scope);
|
|
8879
|
+
const project = await readProjectPackageJson(configRoot);
|
|
8880
|
+
if (!project) throw new Error(initRequiredMessage(scope));
|
|
8744
8881
|
const registry = resolveRegistryUrl(project, opts.registry, DEFAULT_REGISTRY);
|
|
8745
8882
|
const target = parseTargetFlag(opts.target);
|
|
8746
8883
|
for (const [name, version] of Object.entries(project.packages)) {
|
|
8747
8884
|
await installOnePackage({
|
|
8748
|
-
|
|
8885
|
+
configRoot,
|
|
8886
|
+
installRoot,
|
|
8749
8887
|
registry,
|
|
8750
8888
|
name,
|
|
8751
8889
|
version: version.replace(/^\^/, ""),
|
|
@@ -8763,12 +8901,12 @@ var publish = program2.command("publish [dir]").description("Stage, validate, an
|
|
|
8763
8901
|
publish.help();
|
|
8764
8902
|
return;
|
|
8765
8903
|
}
|
|
8766
|
-
const abs = (0,
|
|
8767
|
-
const manifestRaw = await (0, import_promises9.readFile)((0,
|
|
8904
|
+
const abs = (0, import_node_path11.resolve)(dir);
|
|
8905
|
+
const manifestRaw = await (0, import_promises9.readFile)((0, import_node_path11.join)(abs, "aipm.manifest.json"), "utf8");
|
|
8768
8906
|
const manifest = PackageManifestSchema.parse(JSON.parse(manifestRaw));
|
|
8769
8907
|
const tarball = await packDirectory(abs);
|
|
8770
8908
|
const registry = registryFromEnvOrDefault(opts.registry);
|
|
8771
|
-
const result = await publishPackage(registry, manifest.name, tarball, opts.token ??
|
|
8909
|
+
const result = await publishPackage(registry, manifest.name, tarball, opts.token ?? import_node_process5.env.AIPM_TOKEN);
|
|
8772
8910
|
console.log(`Published ${manifest.name}@${result.version}`);
|
|
8773
8911
|
console.log(`View: ${registry.replace(/\/$/, "")}/packages/${manifest.name.replace(/^@/, "").replace("/", "/")}/${result.version}`);
|
|
8774
8912
|
console.log(`Install: aipm add ${manifest.name}@${result.version} --target ${manifest.targets[0]} --ci`);
|
|
@@ -8782,7 +8920,7 @@ publish.command("import <source>").description("Create a package folder from an
|
|
|
8782
8920
|
async (source, opts) => initSkill({ ...opts, from: source })
|
|
8783
8921
|
);
|
|
8784
8922
|
publish.command("add [files...]").description("Stage files for publishing").action(async (files) => {
|
|
8785
|
-
const state = await addPublishFiles((0,
|
|
8923
|
+
const state = await addPublishFiles((0, import_node_process5.cwd)(), files);
|
|
8786
8924
|
console.log(`Staged ${state.files.length} file${state.files.length === 1 ? "" : "s"}.`);
|
|
8787
8925
|
printPublishGuide(
|
|
8788
8926
|
`Added ${files.length > 0 ? files.join(", ") : "."} to the publish stage, respecting .aipmignore and secret-file exclusions.`,
|
|
@@ -8813,7 +8951,7 @@ publish.command("token").description("Open the dashboard page used to generate a
|
|
|
8813
8951
|
);
|
|
8814
8952
|
});
|
|
8815
8953
|
publish.command("remove <files...>").alias("rm").description("Remove files from the publish stage").action(async (files) => {
|
|
8816
|
-
const state = await removePublishFiles((0,
|
|
8954
|
+
const state = await removePublishFiles((0, import_node_process5.cwd)(), files);
|
|
8817
8955
|
console.log(`Staged ${state.files.length} file${state.files.length === 1 ? "" : "s"}.`);
|
|
8818
8956
|
printPublishGuide(
|
|
8819
8957
|
`Removed ${files.join(", ")} from the publish stage.`,
|
|
@@ -8821,7 +8959,7 @@ publish.command("remove <files...>").alias("rm").description("Remove files from
|
|
|
8821
8959
|
);
|
|
8822
8960
|
});
|
|
8823
8961
|
publish.command("reset").description("Clear staged publish files").action(async () => {
|
|
8824
|
-
await resetPublishState((0,
|
|
8962
|
+
await resetPublishState((0, import_node_process5.cwd)());
|
|
8825
8963
|
console.log("Cleared publish stage.");
|
|
8826
8964
|
printPublishGuide(
|
|
8827
8965
|
"Cleared all staged publish files.",
|
|
@@ -8829,7 +8967,7 @@ publish.command("reset").description("Clear staged publish files").action(async
|
|
|
8829
8967
|
);
|
|
8830
8968
|
});
|
|
8831
8969
|
publish.command("status").description("Show staged publish files").option("--json", "Print machine-readable JSON").action(async (opts) => {
|
|
8832
|
-
const rows = await statusPublishState((0,
|
|
8970
|
+
const rows = await statusPublishState((0, import_node_process5.cwd)());
|
|
8833
8971
|
if (opts.json) {
|
|
8834
8972
|
console.log(JSON.stringify({ files: rows }, null, 2));
|
|
8835
8973
|
return;
|
|
@@ -8852,7 +8990,7 @@ publish.command("status").description("Show staged publish files").option("--jso
|
|
|
8852
8990
|
);
|
|
8853
8991
|
});
|
|
8854
8992
|
publish.command("diff").description("Show staged files that changed since add").action(async () => {
|
|
8855
|
-
const rows = await statusPublishState((0,
|
|
8993
|
+
const rows = await statusPublishState((0, import_node_process5.cwd)());
|
|
8856
8994
|
const changed = rows.filter((row) => row.changed);
|
|
8857
8995
|
if (changed.length === 0) {
|
|
8858
8996
|
console.log("No staged files changed.");
|
|
@@ -8869,16 +9007,16 @@ publish.command("diff").description("Show staged files that changed since add").
|
|
|
8869
9007
|
);
|
|
8870
9008
|
});
|
|
8871
9009
|
publish.command("validate").description("Validate staged files before publish").action(async () => {
|
|
8872
|
-
const result = await validatePublishState((0,
|
|
9010
|
+
const result = await validatePublishState((0, import_node_process5.cwd)());
|
|
8873
9011
|
console.log(`Valid ${result.manifest.name}@${result.manifest.version} (${result.size} bytes staged).`);
|
|
8874
9012
|
printPublishGuide(
|
|
8875
9013
|
`Validated ${result.manifest.name}@${result.manifest.version}; manifest, entry file, staged hashes, ignored paths, package size, and obvious secrets passed.`,
|
|
8876
9014
|
"Generate a 5-minute token from the dashboard, then run AIPM_TOKEN=<token> aipm publish push."
|
|
8877
9015
|
);
|
|
8878
9016
|
});
|
|
8879
|
-
publish.command("preview").description("Preview exactly what will be uploaded").option("--json", "Print machine-readable JSON").action((opts) => printPublishPreview((0,
|
|
9017
|
+
publish.command("preview").description("Preview exactly what will be uploaded").option("--json", "Print machine-readable JSON").action((opts) => printPublishPreview((0, import_node_process5.cwd)(), opts.json));
|
|
8880
9018
|
publish.command("push").description("Publish staged files").option("--registry <url>", "Registry base URL").option("--token <token>", "Publish token").option("--yes", "Confirm upload without an extra reminder").action(async (opts) => {
|
|
8881
|
-
const root = (0,
|
|
9019
|
+
const root = (0, import_node_process5.cwd)();
|
|
8882
9020
|
const { manifest } = await validatePublishState(root);
|
|
8883
9021
|
const registry = registryFromEnvOrDefault(opts.registry);
|
|
8884
9022
|
const tarball = await packStagedFiles(root);
|
|
@@ -8889,7 +9027,7 @@ publish.command("push").description("Publish staged files").option("--registry <
|
|
|
8889
9027
|
}
|
|
8890
9028
|
console.log(`Uploading ${staged.length} file${staged.length === 1 ? "" : "s"} to ${registry}.`);
|
|
8891
9029
|
for (const entry of staged) console.log(` ${entry.path}`);
|
|
8892
|
-
const result = await publishPackage(registry, manifest.name, tarball, opts.token ??
|
|
9030
|
+
const result = await publishPackage(registry, manifest.name, tarball, opts.token ?? import_node_process5.env.AIPM_TOKEN);
|
|
8893
9031
|
const base = registry.replace(/\/$/, "");
|
|
8894
9032
|
console.log(`Published ${manifest.name}@${result.version}`);
|
|
8895
9033
|
console.log(`View: ${base}/packages/${manifest.name.replace(/^@/, "")}/${result.version}`);
|
|
@@ -8899,9 +9037,9 @@ publish.command("push").description("Publish staged files").option("--registry <
|
|
|
8899
9037
|
"Open the registry page, test the install command in a clean project, and share the package link."
|
|
8900
9038
|
);
|
|
8901
9039
|
});
|
|
8902
|
-
program2.command("list").description("List packages from aipm-lock.json").action(async () => {
|
|
8903
|
-
const
|
|
8904
|
-
const lock = await
|
|
9040
|
+
program2.command("list").description("List packages from aipm-lock.json").option(GLOBAL_OPTION, GLOBAL_OPTION_DESC).action(async (opts) => {
|
|
9041
|
+
const configRoot = resolveConfigRoot({ global: opts.global });
|
|
9042
|
+
const lock = await readLockfile(configRoot);
|
|
8905
9043
|
if (!lock || Object.keys(lock.packages).length === 0) {
|
|
8906
9044
|
console.log("No packages installed.");
|
|
8907
9045
|
return;
|
|
@@ -8910,27 +9048,30 @@ program2.command("list").description("List packages from aipm-lock.json").action
|
|
|
8910
9048
|
console.log(`${name}@${entry.version} [${entry.resolvedTools.join(", ")}]`);
|
|
8911
9049
|
}
|
|
8912
9050
|
});
|
|
8913
|
-
program2.command("remove <package>").alias("rm").description("Remove a package from aipm.package.json and aipm-lock.json").action(async (pkgArg) => {
|
|
9051
|
+
program2.command("remove <package>").alias("rm").description("Remove a package from aipm.package.json and aipm-lock.json").option(GLOBAL_OPTION, GLOBAL_OPTION_DESC).action(async (pkgArg, opts) => {
|
|
8914
9052
|
const { name } = parsePackageArg(pkgArg);
|
|
8915
|
-
const
|
|
8916
|
-
const
|
|
8917
|
-
|
|
9053
|
+
const scope = { global: opts.global };
|
|
9054
|
+
const configRoot = resolveConfigRoot(scope);
|
|
9055
|
+
const project = await readProjectPackageJson(configRoot);
|
|
9056
|
+
if (!project) throw new Error(initRequiredMessage(scope));
|
|
8918
9057
|
const packages = { ...project.packages };
|
|
8919
9058
|
delete packages[name];
|
|
8920
|
-
await writeProjectPackageJson(
|
|
8921
|
-
const lock = await readLockfile(
|
|
9059
|
+
await writeProjectPackageJson(configRoot, { ...project, packages });
|
|
9060
|
+
const lock = await readLockfile(configRoot);
|
|
8922
9061
|
if (lock) {
|
|
8923
9062
|
const lockPackages = { ...lock.packages };
|
|
8924
9063
|
delete lockPackages[name];
|
|
8925
|
-
await writeLockfile(
|
|
9064
|
+
await writeLockfile(configRoot, { ...lock, packages: lockPackages });
|
|
8926
9065
|
}
|
|
8927
|
-
console.log(`Removed ${name} from AIPM
|
|
9066
|
+
console.log(`Removed ${name} from AIPM ${scopeLabel(scope)} files.`);
|
|
8928
9067
|
console.log("Adapter-written files are not deleted yet; review your project before committing.");
|
|
8929
9068
|
});
|
|
8930
|
-
program2.command("update [package]").description("Update one installed package, or all installed packages, to the latest registry version").option("--registry <url>", "Registry base URL").option("--target <tool>", "cursor or
|
|
8931
|
-
const
|
|
8932
|
-
|
|
8933
|
-
|
|
9069
|
+
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("--ci", "Non-interactive").action(async (pkgArg, opts) => {
|
|
9070
|
+
const scope = { global: opts.global };
|
|
9071
|
+
const configRoot = resolveConfigRoot(scope);
|
|
9072
|
+
const installRoot = resolveInstallRoot(scope);
|
|
9073
|
+
let project = await readProjectPackageJson(configRoot);
|
|
9074
|
+
if (!project) throw new Error(initRequiredMessage(scope));
|
|
8934
9075
|
const registry = resolveRegistryUrl(project, opts.registry, DEFAULT_REGISTRY);
|
|
8935
9076
|
const names = pkgArg ? [parsePackageArg(pkgArg).name] : Object.keys(project.packages);
|
|
8936
9077
|
if (names.length === 0) {
|
|
@@ -8943,9 +9084,10 @@ program2.command("update [package]").description("Update one installed package,
|
|
|
8943
9084
|
...project,
|
|
8944
9085
|
packages: { ...project.packages, [name]: version }
|
|
8945
9086
|
};
|
|
8946
|
-
await writeProjectPackageJson(
|
|
9087
|
+
await writeProjectPackageJson(configRoot, project);
|
|
8947
9088
|
await installOnePackage({
|
|
8948
|
-
|
|
9089
|
+
configRoot,
|
|
9090
|
+
installRoot,
|
|
8949
9091
|
registry,
|
|
8950
9092
|
name,
|
|
8951
9093
|
version,
|
|
@@ -8955,7 +9097,7 @@ program2.command("update [package]").description("Update one installed package,
|
|
|
8955
9097
|
});
|
|
8956
9098
|
}
|
|
8957
9099
|
});
|
|
8958
|
-
program2.command("doctor").description("Check PATH, Node, registry, project config, and publish readiness").option("--registry <url>", "Registry base URL").option("--json", "Print machine-readable JSON").option("--publish", "Only show publish-readiness checks").action((opts) => runDoctor(opts));
|
|
9100
|
+
program2.command("doctor").description("Check PATH, Node, registry, project config, and publish readiness").option(GLOBAL_OPTION, GLOBAL_OPTION_DESC).option("--registry <url>", "Registry base URL").option("--json", "Print machine-readable JSON").option("--publish", "Only show publish-readiness checks").action((opts) => runDoctor(opts));
|
|
8959
9101
|
program2.parseAsync(process.argv).catch((err) => {
|
|
8960
9102
|
console.error(err.message);
|
|
8961
9103
|
const message = err.message.toLowerCase();
|