@aipm-registry/cli 0.1.8 → 0.2.2
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 +319 -178
- 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
|
|
|
@@ -8040,14 +7989,14 @@ async function packStagedFiles(root) {
|
|
|
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,42 +8692,41 @@ 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
|
-
const manifest = {
|
|
8700
|
+
const manifest = PackageManifestSchema.parse({
|
|
8583
8701
|
schemaVersion: "0.1",
|
|
8584
8702
|
name: opts.name,
|
|
8585
8703
|
version: opts.version,
|
|
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
|
-
};
|
|
8592
|
-
PackageManifestSchema.parse(manifest);
|
|
8709
|
+
});
|
|
8593
8710
|
if (source) {
|
|
8594
8711
|
const sourceInfo = await (0, import_promises9.stat)(source);
|
|
8595
8712
|
if (sourceInfo.isDirectory()) {
|
|
8596
8713
|
await (0, import_promises9.cp)(source, root, { recursive: true, force: false, errorOnExist: true });
|
|
8597
8714
|
} else if (sourceInfo.isFile()) {
|
|
8598
|
-
await (0, import_promises9.cp)(source, (0,
|
|
8715
|
+
await (0, import_promises9.cp)(source, (0, import_node_path11.join)(root, (0, import_node_path11.basename)(source)), { force: false, errorOnExist: true });
|
|
8599
8716
|
} else {
|
|
8600
8717
|
throw new Error(`Unsupported source path: ${opts.from}`);
|
|
8601
8718
|
}
|
|
8602
8719
|
}
|
|
8603
|
-
await writeStarterFile((0,
|
|
8720
|
+
await writeStarterFile((0, import_node_path11.join)(root, "aipm.manifest.json"), JSON.stringify(manifest, null, 2) + "\n");
|
|
8604
8721
|
if (!opts.from) {
|
|
8605
8722
|
const template = parseSkillTemplate(opts.template ?? "blank");
|
|
8606
8723
|
await writeStarterFile(
|
|
8607
|
-
(0,
|
|
8724
|
+
(0, import_node_path11.join)(root, entry),
|
|
8608
8725
|
SKILL_TEMPLATES[template](opts.name)
|
|
8609
8726
|
);
|
|
8610
8727
|
}
|
|
8611
8728
|
await writeStarterFile(
|
|
8612
|
-
(0,
|
|
8729
|
+
(0, import_node_path11.join)(root, ".aipmignore"),
|
|
8613
8730
|
[
|
|
8614
8731
|
"# Files that should never be published with this skill",
|
|
8615
8732
|
".env*",
|
|
@@ -8627,34 +8744,37 @@ async function initSkill(opts) {
|
|
|
8627
8744
|
""
|
|
8628
8745
|
].join("\n")
|
|
8629
8746
|
);
|
|
8630
|
-
await (0, import_promises9.mkdir)((0,
|
|
8747
|
+
await (0, import_promises9.mkdir)((0, import_node_path11.join)(root, ".aipm"), { recursive: true });
|
|
8631
8748
|
console.log(`Created ${opts.name} skill folder: ${root}`);
|
|
8632
8749
|
printPublishGuide(
|
|
8633
8750
|
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
8751
|
cdTarget ? `Run cd ${cdTarget}, edit/review the files, then run aipm publish add .` : "Edit/review the files, then run aipm publish add ."
|
|
8635
8752
|
);
|
|
8636
8753
|
}
|
|
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
|
|
8754
|
+
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) => {
|
|
8755
|
+
const scope = { global: opts.global };
|
|
8756
|
+
const configRoot = resolveConfigRoot(scope);
|
|
8757
|
+
const existing = await readProjectPackageJson(configRoot);
|
|
8640
8758
|
if (existing) {
|
|
8641
|
-
console.log(
|
|
8759
|
+
console.log(`aipm.package.json already exists (${scopeLabel(scope)}).`);
|
|
8642
8760
|
return;
|
|
8643
8761
|
}
|
|
8644
|
-
|
|
8762
|
+
if (scope.global) await (0, import_promises9.mkdir)(configRoot, { recursive: true });
|
|
8763
|
+
const installRoot = resolveInstallRoot(scope);
|
|
8764
|
+
const detected = await detectToolsInProject(installRoot);
|
|
8645
8765
|
let preferredTools = detected;
|
|
8646
8766
|
if (detected.length === 0) {
|
|
8647
8767
|
const choice = await promptForTool();
|
|
8648
8768
|
preferredTools = [choice];
|
|
8649
8769
|
}
|
|
8650
8770
|
const registry = registryFromEnvOrDefault(opts.registry);
|
|
8651
|
-
await writeProjectPackageJson(
|
|
8771
|
+
await writeProjectPackageJson(configRoot, {
|
|
8652
8772
|
schemaVersion: "0.1",
|
|
8653
8773
|
registry,
|
|
8654
8774
|
preferredTools: preferredTools.length ? preferredTools : void 0,
|
|
8655
8775
|
packages: {}
|
|
8656
8776
|
});
|
|
8657
|
-
console.log(`Created aipm.package.json (registry: ${registry})`);
|
|
8777
|
+
console.log(`Created aipm.package.json (${scopeLabel(scope)}, registry: ${registry})`);
|
|
8658
8778
|
});
|
|
8659
8779
|
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
8780
|
const url = `${SITE_URL}/login`;
|
|
@@ -8663,17 +8783,22 @@ program2.command("login").description("Open the AIPM dashboard sign-in page").op
|
|
|
8663
8783
|
if (opts.open) await openUrl(url);
|
|
8664
8784
|
else console.log(`Open: ${url}`);
|
|
8665
8785
|
});
|
|
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
|
|
8786
|
+
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) => {
|
|
8787
|
+
const scope = { global: opts.global };
|
|
8788
|
+
const configRoot = resolveConfigRoot(scope);
|
|
8789
|
+
const installRoot = resolveInstallRoot(scope);
|
|
8790
|
+
const project = await readProjectPackageJson(configRoot);
|
|
8791
|
+
const lock = await readLockfile(configRoot);
|
|
8670
8792
|
const registry = resolveRegistryUrl(project, opts.registry, DEFAULT_REGISTRY);
|
|
8671
8793
|
const data = {
|
|
8672
8794
|
cliVersion: CLI_VERSION,
|
|
8673
8795
|
nodeVersion: process.versions.node,
|
|
8674
|
-
|
|
8796
|
+
scope: scopeLabel(scope),
|
|
8797
|
+
configRoot,
|
|
8798
|
+
installRoot,
|
|
8799
|
+
cwd: (0, import_node_process5.cwd)(),
|
|
8675
8800
|
registry,
|
|
8676
|
-
envRegistry:
|
|
8801
|
+
envRegistry: import_node_process5.env.AIPM_REGISTRY_URL ?? import_node_process5.env.AIPM_REGISTRY ?? null,
|
|
8677
8802
|
hasProjectConfig: Boolean(project),
|
|
8678
8803
|
projectPackages: project ? Object.keys(project.packages) : [],
|
|
8679
8804
|
hasLockfile: Boolean(lock),
|
|
@@ -8686,7 +8811,10 @@ program2.command("config").description("Show resolved AIPM CLI and project confi
|
|
|
8686
8811
|
}
|
|
8687
8812
|
console.log(`CLI: ${data.cliVersion}`);
|
|
8688
8813
|
console.log(`Node: ${data.nodeVersion}`);
|
|
8689
|
-
console.log(`
|
|
8814
|
+
console.log(`Scope: ${data.scope}`);
|
|
8815
|
+
console.log(`Config: ${data.configRoot}`);
|
|
8816
|
+
console.log(`Install root: ${data.installRoot}`);
|
|
8817
|
+
console.log(`Working directory: ${data.cwd}`);
|
|
8690
8818
|
console.log(`Registry: ${data.registry}`);
|
|
8691
8819
|
console.log(`Env registry: ${data.envRegistry ?? "not set"}`);
|
|
8692
8820
|
console.log(`Project config: ${data.hasProjectConfig ? "found" : "not found"}`);
|
|
@@ -8695,11 +8823,13 @@ program2.command("config").description("Show resolved AIPM CLI and project confi
|
|
|
8695
8823
|
console.log(`Installed packages: ${data.installedPackages.length}`);
|
|
8696
8824
|
console.log(`Publish guide: ${data.publishDoc}`);
|
|
8697
8825
|
});
|
|
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
|
|
8826
|
+
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
8827
|
const { name, version: requestedVersion } = parsePackageArg(pkgArg);
|
|
8700
|
-
const
|
|
8701
|
-
|
|
8702
|
-
|
|
8828
|
+
const scope = { global: opts.global };
|
|
8829
|
+
const configRoot = resolveConfigRoot(scope);
|
|
8830
|
+
const installRoot = resolveInstallRoot(scope);
|
|
8831
|
+
let project = await readProjectPackageJson(configRoot);
|
|
8832
|
+
if (!project) throw new Error(initRequiredMessage(scope));
|
|
8703
8833
|
const registry = resolveRegistryUrl(project, opts.registry, DEFAULT_REGISTRY);
|
|
8704
8834
|
const version = requestedVersion ?? project.packages[name] ?? await latestVersionForPackage(registry, name);
|
|
8705
8835
|
if (!version) throw new Error("Specify version: aipm add @scope/pkg@1.0.0");
|
|
@@ -8707,9 +8837,10 @@ program2.command("add <package>").description("Add and install a package @scope/
|
|
|
8707
8837
|
...project,
|
|
8708
8838
|
packages: { ...project.packages, [name]: version.replace(/^\^/, "") }
|
|
8709
8839
|
};
|
|
8710
|
-
await writeProjectPackageJson(
|
|
8840
|
+
await writeProjectPackageJson(configRoot, project);
|
|
8711
8841
|
await installOnePackage({
|
|
8712
|
-
|
|
8842
|
+
configRoot,
|
|
8843
|
+
installRoot,
|
|
8713
8844
|
registry,
|
|
8714
8845
|
name,
|
|
8715
8846
|
version: version.replace(/^\^/, ""),
|
|
@@ -8717,6 +8848,9 @@ program2.command("add <package>").description("Add and install a package @scope/
|
|
|
8717
8848
|
explicitTarget: parseTargetFlag(opts.target),
|
|
8718
8849
|
ci: opts.ci
|
|
8719
8850
|
});
|
|
8851
|
+
if (!opts.ci && !program2.opts().quiet) {
|
|
8852
|
+
await notifyCliUpdateIfNeeded(CLI_VERSION);
|
|
8853
|
+
}
|
|
8720
8854
|
});
|
|
8721
8855
|
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
8856
|
const registry = registryFromEnvOrDefault(opts.registry);
|
|
@@ -8737,15 +8871,18 @@ program2.command("search [query]").description("Search public registry packages"
|
|
|
8737
8871
|
console.log(` ${meta}`);
|
|
8738
8872
|
}
|
|
8739
8873
|
});
|
|
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
|
-
|
|
8874
|
+
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) => {
|
|
8875
|
+
const scope = { global: opts.global };
|
|
8876
|
+
const configRoot = resolveConfigRoot(scope);
|
|
8877
|
+
const installRoot = resolveInstallRoot(scope);
|
|
8878
|
+
const project = await readProjectPackageJson(configRoot);
|
|
8879
|
+
if (!project) throw new Error(initRequiredMessage(scope));
|
|
8744
8880
|
const registry = resolveRegistryUrl(project, opts.registry, DEFAULT_REGISTRY);
|
|
8745
8881
|
const target = parseTargetFlag(opts.target);
|
|
8746
8882
|
for (const [name, version] of Object.entries(project.packages)) {
|
|
8747
8883
|
await installOnePackage({
|
|
8748
|
-
|
|
8884
|
+
configRoot,
|
|
8885
|
+
installRoot,
|
|
8749
8886
|
registry,
|
|
8750
8887
|
name,
|
|
8751
8888
|
version: version.replace(/^\^/, ""),
|
|
@@ -8763,12 +8900,12 @@ var publish = program2.command("publish [dir]").description("Stage, validate, an
|
|
|
8763
8900
|
publish.help();
|
|
8764
8901
|
return;
|
|
8765
8902
|
}
|
|
8766
|
-
const abs = (0,
|
|
8767
|
-
const manifestRaw = await (0, import_promises9.readFile)((0,
|
|
8903
|
+
const abs = (0, import_node_path11.resolve)(dir);
|
|
8904
|
+
const manifestRaw = await (0, import_promises9.readFile)((0, import_node_path11.join)(abs, "aipm.manifest.json"), "utf8");
|
|
8768
8905
|
const manifest = PackageManifestSchema.parse(JSON.parse(manifestRaw));
|
|
8769
8906
|
const tarball = await packDirectory(abs);
|
|
8770
8907
|
const registry = registryFromEnvOrDefault(opts.registry);
|
|
8771
|
-
const result = await publishPackage(registry, manifest.name, tarball, opts.token ??
|
|
8908
|
+
const result = await publishPackage(registry, manifest.name, tarball, opts.token ?? import_node_process5.env.AIPM_TOKEN);
|
|
8772
8909
|
console.log(`Published ${manifest.name}@${result.version}`);
|
|
8773
8910
|
console.log(`View: ${registry.replace(/\/$/, "")}/packages/${manifest.name.replace(/^@/, "").replace("/", "/")}/${result.version}`);
|
|
8774
8911
|
console.log(`Install: aipm add ${manifest.name}@${result.version} --target ${manifest.targets[0]} --ci`);
|
|
@@ -8782,7 +8919,7 @@ publish.command("import <source>").description("Create a package folder from an
|
|
|
8782
8919
|
async (source, opts) => initSkill({ ...opts, from: source })
|
|
8783
8920
|
);
|
|
8784
8921
|
publish.command("add [files...]").description("Stage files for publishing").action(async (files) => {
|
|
8785
|
-
const state = await addPublishFiles((0,
|
|
8922
|
+
const state = await addPublishFiles((0, import_node_process5.cwd)(), files);
|
|
8786
8923
|
console.log(`Staged ${state.files.length} file${state.files.length === 1 ? "" : "s"}.`);
|
|
8787
8924
|
printPublishGuide(
|
|
8788
8925
|
`Added ${files.length > 0 ? files.join(", ") : "."} to the publish stage, respecting .aipmignore and secret-file exclusions.`,
|
|
@@ -8813,7 +8950,7 @@ publish.command("token").description("Open the dashboard page used to generate a
|
|
|
8813
8950
|
);
|
|
8814
8951
|
});
|
|
8815
8952
|
publish.command("remove <files...>").alias("rm").description("Remove files from the publish stage").action(async (files) => {
|
|
8816
|
-
const state = await removePublishFiles((0,
|
|
8953
|
+
const state = await removePublishFiles((0, import_node_process5.cwd)(), files);
|
|
8817
8954
|
console.log(`Staged ${state.files.length} file${state.files.length === 1 ? "" : "s"}.`);
|
|
8818
8955
|
printPublishGuide(
|
|
8819
8956
|
`Removed ${files.join(", ")} from the publish stage.`,
|
|
@@ -8821,7 +8958,7 @@ publish.command("remove <files...>").alias("rm").description("Remove files from
|
|
|
8821
8958
|
);
|
|
8822
8959
|
});
|
|
8823
8960
|
publish.command("reset").description("Clear staged publish files").action(async () => {
|
|
8824
|
-
await resetPublishState((0,
|
|
8961
|
+
await resetPublishState((0, import_node_process5.cwd)());
|
|
8825
8962
|
console.log("Cleared publish stage.");
|
|
8826
8963
|
printPublishGuide(
|
|
8827
8964
|
"Cleared all staged publish files.",
|
|
@@ -8829,7 +8966,7 @@ publish.command("reset").description("Clear staged publish files").action(async
|
|
|
8829
8966
|
);
|
|
8830
8967
|
});
|
|
8831
8968
|
publish.command("status").description("Show staged publish files").option("--json", "Print machine-readable JSON").action(async (opts) => {
|
|
8832
|
-
const rows = await statusPublishState((0,
|
|
8969
|
+
const rows = await statusPublishState((0, import_node_process5.cwd)());
|
|
8833
8970
|
if (opts.json) {
|
|
8834
8971
|
console.log(JSON.stringify({ files: rows }, null, 2));
|
|
8835
8972
|
return;
|
|
@@ -8852,7 +8989,7 @@ publish.command("status").description("Show staged publish files").option("--jso
|
|
|
8852
8989
|
);
|
|
8853
8990
|
});
|
|
8854
8991
|
publish.command("diff").description("Show staged files that changed since add").action(async () => {
|
|
8855
|
-
const rows = await statusPublishState((0,
|
|
8992
|
+
const rows = await statusPublishState((0, import_node_process5.cwd)());
|
|
8856
8993
|
const changed = rows.filter((row) => row.changed);
|
|
8857
8994
|
if (changed.length === 0) {
|
|
8858
8995
|
console.log("No staged files changed.");
|
|
@@ -8869,16 +9006,16 @@ publish.command("diff").description("Show staged files that changed since add").
|
|
|
8869
9006
|
);
|
|
8870
9007
|
});
|
|
8871
9008
|
publish.command("validate").description("Validate staged files before publish").action(async () => {
|
|
8872
|
-
const result = await validatePublishState((0,
|
|
9009
|
+
const result = await validatePublishState((0, import_node_process5.cwd)());
|
|
8873
9010
|
console.log(`Valid ${result.manifest.name}@${result.manifest.version} (${result.size} bytes staged).`);
|
|
8874
9011
|
printPublishGuide(
|
|
8875
9012
|
`Validated ${result.manifest.name}@${result.manifest.version}; manifest, entry file, staged hashes, ignored paths, package size, and obvious secrets passed.`,
|
|
8876
9013
|
"Generate a 5-minute token from the dashboard, then run AIPM_TOKEN=<token> aipm publish push."
|
|
8877
9014
|
);
|
|
8878
9015
|
});
|
|
8879
|
-
publish.command("preview").description("Preview exactly what will be uploaded").option("--json", "Print machine-readable JSON").action((opts) => printPublishPreview((0,
|
|
9016
|
+
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
9017
|
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,
|
|
9018
|
+
const root = (0, import_node_process5.cwd)();
|
|
8882
9019
|
const { manifest } = await validatePublishState(root);
|
|
8883
9020
|
const registry = registryFromEnvOrDefault(opts.registry);
|
|
8884
9021
|
const tarball = await packStagedFiles(root);
|
|
@@ -8889,7 +9026,7 @@ publish.command("push").description("Publish staged files").option("--registry <
|
|
|
8889
9026
|
}
|
|
8890
9027
|
console.log(`Uploading ${staged.length} file${staged.length === 1 ? "" : "s"} to ${registry}.`);
|
|
8891
9028
|
for (const entry of staged) console.log(` ${entry.path}`);
|
|
8892
|
-
const result = await publishPackage(registry, manifest.name, tarball, opts.token ??
|
|
9029
|
+
const result = await publishPackage(registry, manifest.name, tarball, opts.token ?? import_node_process5.env.AIPM_TOKEN);
|
|
8893
9030
|
const base = registry.replace(/\/$/, "");
|
|
8894
9031
|
console.log(`Published ${manifest.name}@${result.version}`);
|
|
8895
9032
|
console.log(`View: ${base}/packages/${manifest.name.replace(/^@/, "")}/${result.version}`);
|
|
@@ -8899,9 +9036,9 @@ publish.command("push").description("Publish staged files").option("--registry <
|
|
|
8899
9036
|
"Open the registry page, test the install command in a clean project, and share the package link."
|
|
8900
9037
|
);
|
|
8901
9038
|
});
|
|
8902
|
-
program2.command("list").description("List packages from aipm-lock.json").action(async () => {
|
|
8903
|
-
const
|
|
8904
|
-
const lock = await
|
|
9039
|
+
program2.command("list").description("List packages from aipm-lock.json").option(GLOBAL_OPTION, GLOBAL_OPTION_DESC).action(async (opts) => {
|
|
9040
|
+
const configRoot = resolveConfigRoot({ global: opts.global });
|
|
9041
|
+
const lock = await readLockfile(configRoot);
|
|
8905
9042
|
if (!lock || Object.keys(lock.packages).length === 0) {
|
|
8906
9043
|
console.log("No packages installed.");
|
|
8907
9044
|
return;
|
|
@@ -8910,27 +9047,30 @@ program2.command("list").description("List packages from aipm-lock.json").action
|
|
|
8910
9047
|
console.log(`${name}@${entry.version} [${entry.resolvedTools.join(", ")}]`);
|
|
8911
9048
|
}
|
|
8912
9049
|
});
|
|
8913
|
-
program2.command("remove <package>").alias("rm").description("Remove a package from aipm.package.json and aipm-lock.json").action(async (pkgArg) => {
|
|
9050
|
+
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
9051
|
const { name } = parsePackageArg(pkgArg);
|
|
8915
|
-
const
|
|
8916
|
-
const
|
|
8917
|
-
|
|
9052
|
+
const scope = { global: opts.global };
|
|
9053
|
+
const configRoot = resolveConfigRoot(scope);
|
|
9054
|
+
const project = await readProjectPackageJson(configRoot);
|
|
9055
|
+
if (!project) throw new Error(initRequiredMessage(scope));
|
|
8918
9056
|
const packages = { ...project.packages };
|
|
8919
9057
|
delete packages[name];
|
|
8920
|
-
await writeProjectPackageJson(
|
|
8921
|
-
const lock = await readLockfile(
|
|
9058
|
+
await writeProjectPackageJson(configRoot, { ...project, packages });
|
|
9059
|
+
const lock = await readLockfile(configRoot);
|
|
8922
9060
|
if (lock) {
|
|
8923
9061
|
const lockPackages = { ...lock.packages };
|
|
8924
9062
|
delete lockPackages[name];
|
|
8925
|
-
await writeLockfile(
|
|
9063
|
+
await writeLockfile(configRoot, { ...lock, packages: lockPackages });
|
|
8926
9064
|
}
|
|
8927
|
-
console.log(`Removed ${name} from AIPM
|
|
9065
|
+
console.log(`Removed ${name} from AIPM ${scopeLabel(scope)} files.`);
|
|
8928
9066
|
console.log("Adapter-written files are not deleted yet; review your project before committing.");
|
|
8929
9067
|
});
|
|
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
|
-
|
|
9068
|
+
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) => {
|
|
9069
|
+
const scope = { global: opts.global };
|
|
9070
|
+
const configRoot = resolveConfigRoot(scope);
|
|
9071
|
+
const installRoot = resolveInstallRoot(scope);
|
|
9072
|
+
let project = await readProjectPackageJson(configRoot);
|
|
9073
|
+
if (!project) throw new Error(initRequiredMessage(scope));
|
|
8934
9074
|
const registry = resolveRegistryUrl(project, opts.registry, DEFAULT_REGISTRY);
|
|
8935
9075
|
const names = pkgArg ? [parsePackageArg(pkgArg).name] : Object.keys(project.packages);
|
|
8936
9076
|
if (names.length === 0) {
|
|
@@ -8943,9 +9083,10 @@ program2.command("update [package]").description("Update one installed package,
|
|
|
8943
9083
|
...project,
|
|
8944
9084
|
packages: { ...project.packages, [name]: version }
|
|
8945
9085
|
};
|
|
8946
|
-
await writeProjectPackageJson(
|
|
9086
|
+
await writeProjectPackageJson(configRoot, project);
|
|
8947
9087
|
await installOnePackage({
|
|
8948
|
-
|
|
9088
|
+
configRoot,
|
|
9089
|
+
installRoot,
|
|
8949
9090
|
registry,
|
|
8950
9091
|
name,
|
|
8951
9092
|
version,
|
|
@@ -8955,7 +9096,7 @@ program2.command("update [package]").description("Update one installed package,
|
|
|
8955
9096
|
});
|
|
8956
9097
|
}
|
|
8957
9098
|
});
|
|
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));
|
|
9099
|
+
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
9100
|
program2.parseAsync(process.argv).catch((err) => {
|
|
8960
9101
|
console.error(err.message);
|
|
8961
9102
|
const message = err.message.toLowerCase();
|