@4pm/cli 1.8.4-b → 1.9.0-b
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/index.js +115 -38
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -29506,17 +29506,38 @@ MCowBQYDK2VwAyEARlfzjaFhe5bhRrMp/ZuH6sVqg/S7f8B1dliuF21iDTw=
|
|
|
29506
29506
|
`;
|
|
29507
29507
|
|
|
29508
29508
|
// src/version.ts
|
|
29509
|
+
import { execFileSync } from "child_process";
|
|
29509
29510
|
import { readFileSync as readFileSync4 } from "fs";
|
|
29510
29511
|
import { dirname, join as join4 } from "path";
|
|
29511
29512
|
import { fileURLToPath } from "url";
|
|
29513
|
+
function gitDescribeVersion(cwd2) {
|
|
29514
|
+
try {
|
|
29515
|
+
const out = execFileSync("git", ["describe", "--tags", "--match", "cli-v*"], {
|
|
29516
|
+
cwd: cwd2,
|
|
29517
|
+
timeout: 3e3,
|
|
29518
|
+
stdio: ["ignore", "pipe", "ignore"]
|
|
29519
|
+
}).toString().trim();
|
|
29520
|
+
const stripped = out.replace(/^cli-v/, "");
|
|
29521
|
+
return stripped || null;
|
|
29522
|
+
} catch {
|
|
29523
|
+
return null;
|
|
29524
|
+
}
|
|
29525
|
+
}
|
|
29512
29526
|
function readCliVersion() {
|
|
29527
|
+
const envVersion = process.env.FOURPM_CLI_VERSION?.trim();
|
|
29528
|
+
if (envVersion) return envVersion.replace(/^cli-v/, "");
|
|
29529
|
+
let version = "0.0.0";
|
|
29513
29530
|
try {
|
|
29514
29531
|
const here = dirname(fileURLToPath(import.meta.url));
|
|
29515
29532
|
const pkg = JSON.parse(readFileSync4(join4(here, "..", "package.json"), "utf8"));
|
|
29516
|
-
|
|
29533
|
+
version = pkg.version ?? "0.0.0";
|
|
29534
|
+
if (version === "0.0.0") {
|
|
29535
|
+
const dev = gitDescribeVersion(here);
|
|
29536
|
+
if (dev) version = dev;
|
|
29537
|
+
}
|
|
29517
29538
|
} catch {
|
|
29518
|
-
return "0.0.0";
|
|
29519
29539
|
}
|
|
29540
|
+
return version;
|
|
29520
29541
|
}
|
|
29521
29542
|
var CLI_VERSION = readCliVersion();
|
|
29522
29543
|
|
|
@@ -33965,6 +33986,14 @@ var issueProvisioningTokenRequestSchema = external_exports.object({
|
|
|
33965
33986
|
/** TTL seconds (0/absent ⇒ a default short TTL applied server-side). */
|
|
33966
33987
|
ttlSec: external_exports.number().int().min(0).max(2592e3).optional()
|
|
33967
33988
|
});
|
|
33989
|
+
var provisionRequestSchema = external_exports.object({
|
|
33990
|
+
mode: external_exports.enum(["sync", "force"]).optional().default("sync")
|
|
33991
|
+
});
|
|
33992
|
+
var provisionForUserRequestSchema = external_exports.object({
|
|
33993
|
+
userId: external_exports.string().uuid(),
|
|
33994
|
+
projectId: external_exports.string().uuid(),
|
|
33995
|
+
mode: external_exports.enum(["sync", "force"]).optional().default("sync")
|
|
33996
|
+
});
|
|
33968
33997
|
var listWorkersQuerySchema = baseRequestSchema.extend({
|
|
33969
33998
|
status: external_exports.enum(["online", "offline"]).optional(),
|
|
33970
33999
|
/** Only workers whose live CPU/memory/disk usage % ≥ the given threshold (0–100). */
|
|
@@ -34240,7 +34269,13 @@ var repoSpecSchema = external_exports.object({
|
|
|
34240
34269
|
/** Clone url — `https` or `ssh` (required; ADR-0172). */
|
|
34241
34270
|
url: external_exports.string().max(500).regex(GIT_URL_RE, "must be an https or ssh git url"),
|
|
34242
34271
|
/** Sub-repo subfolder under the target root (empty ⇒ derived from role/name). */
|
|
34243
|
-
subdir: external_exports.string().max(120).optional().default("")
|
|
34272
|
+
subdir: external_exports.string().max(120).optional().default(""),
|
|
34273
|
+
/**
|
|
34274
|
+
* Primary branch to clone / check out (ADR-0292). Empty ⇒ the repo's default branch. The
|
|
34275
|
+
* worker clones with `-b <branch>` and the on-demand "update repos" action checks it out +
|
|
34276
|
+
* fast-forward pulls it.
|
|
34277
|
+
*/
|
|
34278
|
+
branch: external_exports.string().max(200).optional().default("")
|
|
34244
34279
|
});
|
|
34245
34280
|
function repoName(url) {
|
|
34246
34281
|
const last = (url || "").trim().replace(/\/+$/, "").split(/[/:]/).pop() ?? "";
|
|
@@ -34368,7 +34403,7 @@ var activityHeartbeatSchema = external_exports.object({
|
|
|
34368
34403
|
});
|
|
34369
34404
|
|
|
34370
34405
|
// src/core/scaffold.ts
|
|
34371
|
-
import { cp, mkdir, writeFile } from "fs/promises";
|
|
34406
|
+
import { cp, mkdir, readdir, rename, rm, writeFile } from "fs/promises";
|
|
34372
34407
|
import { existsSync as existsSync4 } from "fs";
|
|
34373
34408
|
import { execFile as execFile2 } from "child_process";
|
|
34374
34409
|
import { dirname as dirname3, join as join6, resolve } from "path";
|
|
@@ -34457,16 +34492,47 @@ function subDirName(repo) {
|
|
|
34457
34492
|
const raw = (repo.subdir || repo.role || repoName(repo.url ?? "") || "repo").trim();
|
|
34458
34493
|
return raw.replace(/[^\w.-]+/g, "-").replace(/^-+|-+$/g, "") || "repo";
|
|
34459
34494
|
}
|
|
34495
|
+
function cloneArgs(url, dest, branch) {
|
|
34496
|
+
const b = (branch ?? "").trim();
|
|
34497
|
+
return b ? ["clone", "-b", b, url, dest] : ["clone", url, dest];
|
|
34498
|
+
}
|
|
34499
|
+
async function updateRepo(dir2, label, branch, emit) {
|
|
34500
|
+
const b = (branch ?? "").trim();
|
|
34501
|
+
emit("git", `Updating ${label} (fetch + ${b ? `checkout ${b} + ` : ""}fast-forward pull)\u2026`);
|
|
34502
|
+
await run2("git", ["fetch", "origin", "--prune"], { cwd: dir2, timeout: 12e4 });
|
|
34503
|
+
if (b) await run2("git", ["checkout", b], { cwd: dir2, timeout: 6e4 });
|
|
34504
|
+
await run2("git", ["pull", "--ff-only"], { cwd: dir2, timeout: 12e4 });
|
|
34505
|
+
}
|
|
34460
34506
|
async function provisionRepos(target, repos, emit, opts = {}) {
|
|
34507
|
+
const mode = opts.mode ?? "clone";
|
|
34508
|
+
const subDirsToKeep = new Set(repos.filter((r) => !r.primary && r.url).map((r) => subDirName(r)));
|
|
34461
34509
|
for (const repo of repos) {
|
|
34462
34510
|
if (repo.primary) {
|
|
34463
34511
|
if (opts.clonePrimary && repo.url) {
|
|
34464
34512
|
if (existsSync4(join6(target, ".git"))) {
|
|
34465
|
-
|
|
34513
|
+
if (mode === "sync") {
|
|
34514
|
+
await updateRepo(target, "primary repo", repo.branch, emit);
|
|
34515
|
+
} else if (mode === "force") {
|
|
34516
|
+
emit("git", `Re-cloning ${repo.url} (force)\u2026`);
|
|
34517
|
+
const tmp = `${target}.4pm-reclone`;
|
|
34518
|
+
await rm(tmp, { recursive: true, force: true });
|
|
34519
|
+
await run2("git", cloneArgs(repo.url, tmp, repo.branch), { timeout: 12e4 });
|
|
34520
|
+
for (const entry of await readdir(target)) {
|
|
34521
|
+
if (subDirsToKeep.has(entry)) continue;
|
|
34522
|
+
await rm(join6(target, entry), { recursive: true, force: true });
|
|
34523
|
+
}
|
|
34524
|
+
for (const entry of await readdir(tmp)) {
|
|
34525
|
+
if (subDirsToKeep.has(entry)) continue;
|
|
34526
|
+
await rename(join6(tmp, entry), join6(target, entry));
|
|
34527
|
+
}
|
|
34528
|
+
await rm(tmp, { recursive: true, force: true });
|
|
34529
|
+
} else {
|
|
34530
|
+
emit("git", `Primary repo already present \u2014 skipping clone.`);
|
|
34531
|
+
}
|
|
34466
34532
|
continue;
|
|
34467
34533
|
}
|
|
34468
34534
|
emit("git", `Cloning ${repo.url}\u2026`);
|
|
34469
|
-
await run2("git",
|
|
34535
|
+
await run2("git", cloneArgs(repo.url, target, repo.branch), { timeout: 12e4 });
|
|
34470
34536
|
continue;
|
|
34471
34537
|
}
|
|
34472
34538
|
emit("git", "Initializing the primary repo\u2026");
|
|
@@ -34481,11 +34547,19 @@ async function provisionRepos(target, repos, emit, opts = {}) {
|
|
|
34481
34547
|
const dir2 = join6(target, subDirName(repo));
|
|
34482
34548
|
if (repo.url) {
|
|
34483
34549
|
if (existsSync4(join6(dir2, ".git"))) {
|
|
34484
|
-
|
|
34550
|
+
if (mode === "sync") {
|
|
34551
|
+
await updateRepo(dir2, `sub-repo ${subDirName(repo)}`, repo.branch, emit);
|
|
34552
|
+
} else if (mode === "force") {
|
|
34553
|
+
emit("git", `Re-cloning sub-repo ${repo.url} (force)\u2026`);
|
|
34554
|
+
await rm(dir2, { recursive: true, force: true });
|
|
34555
|
+
await run2("git", cloneArgs(repo.url, dir2, repo.branch), { timeout: 12e4 });
|
|
34556
|
+
} else {
|
|
34557
|
+
emit("git", `Sub-repo ${subDirName(repo)} already present \u2014 skipping clone.`);
|
|
34558
|
+
}
|
|
34485
34559
|
continue;
|
|
34486
34560
|
}
|
|
34487
34561
|
emit("git", `Cloning sub-repo ${repo.url}\u2026`);
|
|
34488
|
-
await run2("git",
|
|
34562
|
+
await run2("git", cloneArgs(repo.url, dir2, repo.branch), { timeout: 12e4 });
|
|
34489
34563
|
} else {
|
|
34490
34564
|
emit("git", `Initializing sub-repo ${subDirName(repo)}\u2026`);
|
|
34491
34565
|
await mkdir(dir2, { recursive: true });
|
|
@@ -34590,11 +34664,14 @@ async function addProject(payload, profileDir2, onProgress) {
|
|
|
34590
34664
|
const target = join6(root, payload.projectName);
|
|
34591
34665
|
await mkdir(target, { recursive: true });
|
|
34592
34666
|
const repos = payload.repos ?? [];
|
|
34593
|
-
|
|
34667
|
+
const mode = payload.mode ?? "clone";
|
|
34668
|
+
if (repos.length > 0) await provisionRepos(target, repos, emit, { clonePrimary: true, mode });
|
|
34594
34669
|
onProgress?.({ projectId: payload.projectId, step: "done", message: "Project added.", done: true });
|
|
34595
34670
|
return { ok: true, path: target };
|
|
34596
34671
|
} catch (err) {
|
|
34597
|
-
|
|
34672
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
34673
|
+
onProgress?.({ projectId: payload.projectId, step: "error", message: `Failed: ${message}`, done: true });
|
|
34674
|
+
return { ok: false, error: message, step: lastStep };
|
|
34598
34675
|
}
|
|
34599
34676
|
}
|
|
34600
34677
|
|
|
@@ -35082,7 +35159,7 @@ function decryptPayload(key, payloadBase64, nonceBase64) {
|
|
|
35082
35159
|
import { spawn as spawn2 } from "child_process";
|
|
35083
35160
|
|
|
35084
35161
|
// src/common/logger/logger.ts
|
|
35085
|
-
import { appendFile, mkdir as mkdir2, readdir, unlink } from "fs/promises";
|
|
35162
|
+
import { appendFile, mkdir as mkdir2, readdir as readdir2, unlink } from "fs/promises";
|
|
35086
35163
|
import { readdirSync as readdirSync2, readFileSync as readFileSync6, statSync } from "fs";
|
|
35087
35164
|
import { join as join7 } from "path";
|
|
35088
35165
|
var LEVEL_ORDER = { error: 0, warn: 1, info: 2, debug: 3 };
|
|
@@ -35142,7 +35219,7 @@ var CliLogger = class {
|
|
|
35142
35219
|
async cleanupOldLogs() {
|
|
35143
35220
|
const dir2 = this.dir;
|
|
35144
35221
|
if (!dir2) return;
|
|
35145
|
-
const files = await
|
|
35222
|
+
const files = await readdir2(dir2).catch(() => []);
|
|
35146
35223
|
const cutoff = Date.now() - this.retentionDays * DAY_MS;
|
|
35147
35224
|
for (const file of files) {
|
|
35148
35225
|
const match = /^cli-(\d{4}-\d{2}-\d{2})\.jsonl$/.exec(file);
|
|
@@ -38123,7 +38200,7 @@ function rejectByReview(ctx, commandId, origin, prompt, reasons) {
|
|
|
38123
38200
|
}
|
|
38124
38201
|
|
|
38125
38202
|
// src/core/fs-browse.ts
|
|
38126
|
-
import { readdir as
|
|
38203
|
+
import { readdir as readdir3 } from "fs/promises";
|
|
38127
38204
|
import { resolve as resolve2, sep as sep2 } from "path";
|
|
38128
38205
|
async function listDir(path, root) {
|
|
38129
38206
|
if (!root) return { path: "", entries: [] };
|
|
@@ -38131,7 +38208,7 @@ async function listDir(path, root) {
|
|
|
38131
38208
|
const requested = resolve2(base, path && path.trim() ? path : ".");
|
|
38132
38209
|
const target = requested === base || requested.startsWith(base + sep2) ? requested : base;
|
|
38133
38210
|
try {
|
|
38134
|
-
const dirents = await
|
|
38211
|
+
const dirents = await readdir3(target, { withFileTypes: true });
|
|
38135
38212
|
const entries2 = dirents.map((d) => ({
|
|
38136
38213
|
name: d.name,
|
|
38137
38214
|
type: d.isDirectory() ? "dir" : "file"
|
|
@@ -38199,7 +38276,7 @@ async function writeWorkerFile(root, relPath, content) {
|
|
|
38199
38276
|
}
|
|
38200
38277
|
|
|
38201
38278
|
// src/core/fs-mutate.ts
|
|
38202
|
-
import { mkdir as mkdir4, writeFile as writeFile4, rename, rm, stat } from "fs/promises";
|
|
38279
|
+
import { mkdir as mkdir4, writeFile as writeFile4, rename as rename2, rm as rm2, stat } from "fs/promises";
|
|
38203
38280
|
import { basename as basename3, dirname as dirname5, resolve as resolve5, sep as sep5 } from "path";
|
|
38204
38281
|
var MAX_BYTES3 = 2 * 1024 * 1024;
|
|
38205
38282
|
function resolveInRoot3(root, rel) {
|
|
@@ -38254,14 +38331,14 @@ async function mutateFs(root, req) {
|
|
|
38254
38331
|
if (to !== resolve5(root) && !to.startsWith(resolve5(root) + sep5)) return escaped(req.to ?? "");
|
|
38255
38332
|
if (await exists(to)) return { ok: false, path: to, error: "destination already exists" };
|
|
38256
38333
|
await mkdir4(dirname5(to), { recursive: true });
|
|
38257
|
-
await
|
|
38334
|
+
await rename2(from, to);
|
|
38258
38335
|
return { ok: true, path: to };
|
|
38259
38336
|
}
|
|
38260
38337
|
case "delete": {
|
|
38261
38338
|
const target = resolveInRoot3(root, req.path ?? "");
|
|
38262
38339
|
if (!target) return escaped(req.path ?? "");
|
|
38263
38340
|
if (target === resolve5(root)) return { ok: false, path: target, error: "cannot delete the project root" };
|
|
38264
|
-
await
|
|
38341
|
+
await rm2(target, { recursive: true, force: true });
|
|
38265
38342
|
return { ok: true, path: target };
|
|
38266
38343
|
}
|
|
38267
38344
|
default:
|
|
@@ -38486,7 +38563,7 @@ ${stderr}`;
|
|
|
38486
38563
|
|
|
38487
38564
|
// src/core/git-ssh-key.ts
|
|
38488
38565
|
import { execFile as execFile8 } from "child_process";
|
|
38489
|
-
import { readFile as readFile6, rm as
|
|
38566
|
+
import { readFile as readFile6, rm as rm3, mkdir as mkdir6 } from "fs/promises";
|
|
38490
38567
|
import { join as join18 } from "path";
|
|
38491
38568
|
import { promisify as promisify8 } from "util";
|
|
38492
38569
|
var run8 = promisify8(execFile8);
|
|
@@ -38520,8 +38597,8 @@ async function configureGit(key) {
|
|
|
38520
38597
|
async function generate(profileDir2) {
|
|
38521
38598
|
const { dir: dir2, key, pub } = keyPaths(profileDir2);
|
|
38522
38599
|
await mkdir6(dir2, { recursive: true });
|
|
38523
|
-
await
|
|
38524
|
-
await
|
|
38600
|
+
await rm3(key, { force: true });
|
|
38601
|
+
await rm3(pub, { force: true });
|
|
38525
38602
|
await run8("ssh-keygen", ["-t", "ed25519", "-f", key, "-N", "", "-C", "4pm-deploy-key"], {
|
|
38526
38603
|
timeout: 15e3
|
|
38527
38604
|
});
|
|
@@ -38530,8 +38607,8 @@ async function generate(profileDir2) {
|
|
|
38530
38607
|
}
|
|
38531
38608
|
async function remove(profileDir2) {
|
|
38532
38609
|
const { key, pub } = keyPaths(profileDir2);
|
|
38533
|
-
await
|
|
38534
|
-
await
|
|
38610
|
+
await rm3(key, { force: true });
|
|
38611
|
+
await rm3(pub, { force: true });
|
|
38535
38612
|
await run8("git", ["config", "--global", "--unset", "core.sshCommand"], { timeout: 5e3 }).catch(
|
|
38536
38613
|
() => void 0
|
|
38537
38614
|
);
|
|
@@ -38553,7 +38630,7 @@ async function manageSshKey(op, profileDir2) {
|
|
|
38553
38630
|
}
|
|
38554
38631
|
|
|
38555
38632
|
// src/core/git-history.ts
|
|
38556
|
-
import { readdir as
|
|
38633
|
+
import { readdir as readdir4 } from "fs/promises";
|
|
38557
38634
|
import { execFile as execFile9 } from "child_process";
|
|
38558
38635
|
import { resolve as resolve8, sep as sep8 } from "path";
|
|
38559
38636
|
import { promisify as promisify9 } from "util";
|
|
@@ -38594,13 +38671,13 @@ async function gitRepos(root) {
|
|
|
38594
38671
|
};
|
|
38595
38672
|
await add(base);
|
|
38596
38673
|
try {
|
|
38597
|
-
const lvl1 = await
|
|
38674
|
+
const lvl1 = await readdir4(base, { withFileTypes: true });
|
|
38598
38675
|
for (const d of lvl1) {
|
|
38599
38676
|
if (!d.isDirectory() || d.name === ".git" || d.name === "node_modules") continue;
|
|
38600
38677
|
const p1 = resolve8(base, d.name);
|
|
38601
38678
|
await add(p1);
|
|
38602
38679
|
try {
|
|
38603
|
-
const lvl2 = await
|
|
38680
|
+
const lvl2 = await readdir4(p1, { withFileTypes: true });
|
|
38604
38681
|
for (const d2 of lvl2) {
|
|
38605
38682
|
if (!d2.isDirectory() || d2.name === ".git" || d2.name === "node_modules") continue;
|
|
38606
38683
|
await add(resolve8(p1, d2.name));
|
|
@@ -39130,7 +39207,7 @@ function handleToolsChannels(ctx, message, payload) {
|
|
|
39130
39207
|
}
|
|
39131
39208
|
|
|
39132
39209
|
// src/core/agents.ts
|
|
39133
|
-
import { readFile as readFile7, writeFile as writeFile6, mkdir as mkdir7, readdir as
|
|
39210
|
+
import { readFile as readFile7, writeFile as writeFile6, mkdir as mkdir7, readdir as readdir5, rm as rm4 } from "fs/promises";
|
|
39134
39211
|
import { join as join21 } from "path";
|
|
39135
39212
|
var AGENTS_REL = ".claude/agents";
|
|
39136
39213
|
var SKILLS_REL = ".claude/skills";
|
|
@@ -39155,7 +39232,7 @@ async function listAgents(root) {
|
|
|
39155
39232
|
const subagents = [];
|
|
39156
39233
|
const skills = [];
|
|
39157
39234
|
try {
|
|
39158
|
-
for (const e of await
|
|
39235
|
+
for (const e of await readdir5(join21(root, AGENTS_REL), { withFileTypes: true })) {
|
|
39159
39236
|
if (!e.isFile() || !e.name.endsWith(".md") || MEMORY_DIRS.has(e.name)) continue;
|
|
39160
39237
|
const fm = frontmatter(await readText2(join21(root, AGENTS_REL, e.name)));
|
|
39161
39238
|
subagents.push({ name: e.name.replace(/\.md$/, ""), description: fm.description });
|
|
@@ -39163,7 +39240,7 @@ async function listAgents(root) {
|
|
|
39163
39240
|
} catch {
|
|
39164
39241
|
}
|
|
39165
39242
|
try {
|
|
39166
|
-
for (const e of await
|
|
39243
|
+
for (const e of await readdir5(join21(root, SKILLS_REL), { withFileTypes: true })) {
|
|
39167
39244
|
if (!e.isDirectory()) continue;
|
|
39168
39245
|
const fm = frontmatter(await readText2(join21(root, SKILLS_REL, e.name, "SKILL.md")));
|
|
39169
39246
|
skills.push({ name: e.name, description: fm.description });
|
|
@@ -39193,8 +39270,8 @@ async function writeAgent(root, req) {
|
|
|
39193
39270
|
if (!n) return { ok: false, error: "invalid name" };
|
|
39194
39271
|
try {
|
|
39195
39272
|
if (req.action === "delete") {
|
|
39196
|
-
if (req.kind === "subagent") await
|
|
39197
|
-
else await
|
|
39273
|
+
if (req.kind === "subagent") await rm4(itemPath(root, "subagent", n), { force: true });
|
|
39274
|
+
else await rm4(join21(root, SKILLS_REL, n), { recursive: true, force: true });
|
|
39198
39275
|
return { ok: true };
|
|
39199
39276
|
}
|
|
39200
39277
|
if (req.content === void 0) return { ok: false, error: "content is required" };
|
|
@@ -39315,7 +39392,7 @@ async function writeAgentTools(root, scope, permissions) {
|
|
|
39315
39392
|
|
|
39316
39393
|
// src/core/packages.ts
|
|
39317
39394
|
import { createHash as createHash4 } from "crypto";
|
|
39318
|
-
import { readFile as readFile10, writeFile as writeFile9, mkdir as mkdir9, readdir as
|
|
39395
|
+
import { readFile as readFile10, writeFile as writeFile9, mkdir as mkdir9, readdir as readdir6, rm as rm5, stat as stat3 } from "fs/promises";
|
|
39319
39396
|
import { dirname as dirname9, join as join24, relative } from "path";
|
|
39320
39397
|
var AGENTS_REL2 = ".claude/agents";
|
|
39321
39398
|
var SKILLS_REL2 = ".claude/skills";
|
|
@@ -39335,7 +39412,7 @@ async function listFilesRel(dir2) {
|
|
|
39335
39412
|
async function walk2(d) {
|
|
39336
39413
|
let entries2;
|
|
39337
39414
|
try {
|
|
39338
|
-
entries2 = await
|
|
39415
|
+
entries2 = await readdir6(d, { withFileTypes: true });
|
|
39339
39416
|
} catch {
|
|
39340
39417
|
return;
|
|
39341
39418
|
}
|
|
@@ -39488,11 +39565,11 @@ async function removePackage(root, slug) {
|
|
|
39488
39565
|
const entry = manifest[n];
|
|
39489
39566
|
if (!entry) return { ok: false, error: "not installed" };
|
|
39490
39567
|
if (entry.kind === "subagent") {
|
|
39491
|
-
await
|
|
39492
|
-
await
|
|
39493
|
-
await
|
|
39568
|
+
await rm5(join24(root, AGENTS_REL2, `${n}.md`), { force: true });
|
|
39569
|
+
await rm5(join24(root, AGENTS_REL2, "short-memory", `${n}.md`), { force: true });
|
|
39570
|
+
await rm5(join24(root, AGENTS_REL2, "long-memory", `${n}.md`), { force: true });
|
|
39494
39571
|
} else {
|
|
39495
|
-
await
|
|
39572
|
+
await rm5(join24(root, SKILLS_REL2, n), { recursive: true, force: true });
|
|
39496
39573
|
}
|
|
39497
39574
|
delete manifest[n];
|
|
39498
39575
|
await writeManifest(root, manifest);
|
|
@@ -39503,7 +39580,7 @@ async function removePackage(root, slug) {
|
|
|
39503
39580
|
}
|
|
39504
39581
|
|
|
39505
39582
|
// src/core/graph.ts
|
|
39506
|
-
import { readFile as readFile11, readdir as
|
|
39583
|
+
import { readFile as readFile11, readdir as readdir7 } from "fs/promises";
|
|
39507
39584
|
import { join as join25, relative as relative2, dirname as dirname10, resolve as resolve9, extname as extname2, basename as basename6 } from "path";
|
|
39508
39585
|
var MAX_FILES = 2e3;
|
|
39509
39586
|
var MAX_NODES = 3e3;
|
|
@@ -39516,7 +39593,7 @@ async function walk(root, accept) {
|
|
|
39516
39593
|
const dir2 = stack.pop();
|
|
39517
39594
|
let entries2;
|
|
39518
39595
|
try {
|
|
39519
|
-
entries2 = await
|
|
39596
|
+
entries2 = await readdir7(dir2, { withFileTypes: true });
|
|
39520
39597
|
} catch {
|
|
39521
39598
|
continue;
|
|
39522
39599
|
}
|