@sunasteriskrnd/takumi 1.0.0-dev.10 → 1.0.0-dev.11
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 +1214 -1208
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -34563,9 +34563,9 @@ __export(exports_worktree_manager, {
|
|
|
34563
34563
|
});
|
|
34564
34564
|
import { existsSync as existsSync60 } from "node:fs";
|
|
34565
34565
|
import { readFile as readFile49, writeFile as writeFile36 } from "node:fs/promises";
|
|
34566
|
-
import { join as
|
|
34566
|
+
import { join as join119 } from "node:path";
|
|
34567
34567
|
async function createWorktree(projectDir, issueNumber, baseBranch) {
|
|
34568
|
-
const worktreePath =
|
|
34568
|
+
const worktreePath = join119(projectDir, WORKTREE_DIR, `issue-${issueNumber}`);
|
|
34569
34569
|
const branchName = `sk-watch/issue-${issueNumber}`;
|
|
34570
34570
|
await spawnAndCollect("git", ["fetch", "origin", baseBranch], projectDir).catch(() => {
|
|
34571
34571
|
logger.warning(`[worktree] Could not fetch origin/${baseBranch}, using local`);
|
|
@@ -34583,7 +34583,7 @@ async function createWorktree(projectDir, issueNumber, baseBranch) {
|
|
|
34583
34583
|
return worktreePath;
|
|
34584
34584
|
}
|
|
34585
34585
|
async function removeWorktree(projectDir, issueNumber) {
|
|
34586
|
-
const worktreePath =
|
|
34586
|
+
const worktreePath = join119(projectDir, WORKTREE_DIR, `issue-${issueNumber}`);
|
|
34587
34587
|
const branchName = `sk-watch/issue-${issueNumber}`;
|
|
34588
34588
|
try {
|
|
34589
34589
|
await spawnAndCollect("git", ["worktree", "remove", worktreePath, "--force"], projectDir);
|
|
@@ -34597,7 +34597,7 @@ async function listActiveWorktrees(projectDir) {
|
|
|
34597
34597
|
try {
|
|
34598
34598
|
const output2 = await spawnAndCollect("git", ["worktree", "list", "--porcelain"], projectDir);
|
|
34599
34599
|
const issueNumbers = [];
|
|
34600
|
-
const worktreePrefix =
|
|
34600
|
+
const worktreePrefix = join119(projectDir, WORKTREE_DIR, "issue-").replace(/\\/g, "/");
|
|
34601
34601
|
for (const line of output2.split(`
|
|
34602
34602
|
`)) {
|
|
34603
34603
|
if (line.startsWith("worktree ")) {
|
|
@@ -34625,7 +34625,7 @@ async function cleanupAllWorktrees(projectDir) {
|
|
|
34625
34625
|
await spawnAndCollect("git", ["worktree", "prune"], projectDir).catch(() => {});
|
|
34626
34626
|
}
|
|
34627
34627
|
async function ensureGitignore(projectDir) {
|
|
34628
|
-
const gitignorePath =
|
|
34628
|
+
const gitignorePath = join119(projectDir, ".gitignore");
|
|
34629
34629
|
try {
|
|
34630
34630
|
const content = existsSync60(gitignorePath) ? await readFile49(gitignorePath, "utf-8") : "";
|
|
34631
34631
|
if (!content.includes(".worktrees")) {
|
|
@@ -34732,7 +34732,7 @@ import { createHash as createHash8 } from "node:crypto";
|
|
|
34732
34732
|
import { existsSync as existsSync66, mkdirSync as mkdirSync4, readFileSync as readFileSync16, readdirSync as readdirSync10, statSync as statSync7 } from "node:fs";
|
|
34733
34733
|
import { rename as rename10, writeFile as writeFile38 } from "node:fs/promises";
|
|
34734
34734
|
import { homedir as homedir32 } from "node:os";
|
|
34735
|
-
import { basename as basename17, join as
|
|
34735
|
+
import { basename as basename17, join as join126 } from "node:path";
|
|
34736
34736
|
function getCachedContext(repoPath) {
|
|
34737
34737
|
const cachePath = getCacheFilePath(repoPath);
|
|
34738
34738
|
if (!existsSync66(cachePath))
|
|
@@ -34775,25 +34775,25 @@ function computeSourceHash(repoPath) {
|
|
|
34775
34775
|
}
|
|
34776
34776
|
function getDocSourcePaths(repoPath) {
|
|
34777
34777
|
const paths = [];
|
|
34778
|
-
const docsDir =
|
|
34778
|
+
const docsDir = join126(repoPath, "docs");
|
|
34779
34779
|
if (existsSync66(docsDir)) {
|
|
34780
34780
|
try {
|
|
34781
34781
|
const files = readdirSync10(docsDir);
|
|
34782
34782
|
for (const f4 of files) {
|
|
34783
34783
|
if (f4.endsWith(".md"))
|
|
34784
|
-
paths.push(
|
|
34784
|
+
paths.push(join126(docsDir, f4));
|
|
34785
34785
|
}
|
|
34786
34786
|
} catch {}
|
|
34787
34787
|
}
|
|
34788
|
-
const readme =
|
|
34788
|
+
const readme = join126(repoPath, "README.md");
|
|
34789
34789
|
if (existsSync66(readme))
|
|
34790
34790
|
paths.push(readme);
|
|
34791
|
-
const stylesDir =
|
|
34791
|
+
const stylesDir = join126(repoPath, "assets", "writing-styles");
|
|
34792
34792
|
if (existsSync66(stylesDir)) {
|
|
34793
34793
|
try {
|
|
34794
34794
|
const files = readdirSync10(stylesDir);
|
|
34795
34795
|
for (const f4 of files) {
|
|
34796
|
-
paths.push(
|
|
34796
|
+
paths.push(join126(stylesDir, f4));
|
|
34797
34797
|
}
|
|
34798
34798
|
} catch {}
|
|
34799
34799
|
}
|
|
@@ -34802,11 +34802,11 @@ function getDocSourcePaths(repoPath) {
|
|
|
34802
34802
|
function getCacheFilePath(repoPath) {
|
|
34803
34803
|
const repoName = basename17(repoPath).replace(/[^a-zA-Z0-9_-]/g, "_");
|
|
34804
34804
|
const pathHash = createHash8("sha256").update(repoPath).digest("hex").slice(0, 8);
|
|
34805
|
-
return
|
|
34805
|
+
return join126(CACHE_DIR, `${repoName}-${pathHash}-context-cache.json`);
|
|
34806
34806
|
}
|
|
34807
34807
|
var CACHE_DIR, CACHE_TTL_MS3;
|
|
34808
34808
|
var init_context_cache_manager = __esm(() => {
|
|
34809
|
-
CACHE_DIR =
|
|
34809
|
+
CACHE_DIR = join126(homedir32(), ".sunagentkit", "cache");
|
|
34810
34810
|
CACHE_TTL_MS3 = 24 * 60 * 60 * 1000;
|
|
34811
34811
|
});
|
|
34812
34812
|
|
|
@@ -34987,7 +34987,7 @@ function extractContentFromResponse(response) {
|
|
|
34987
34987
|
// src/commands/content/phases/docs-summarizer.ts
|
|
34988
34988
|
import { execSync as execSync5 } from "node:child_process";
|
|
34989
34989
|
import { existsSync as existsSync67, readFileSync as readFileSync17, readdirSync as readdirSync11 } from "node:fs";
|
|
34990
|
-
import { join as
|
|
34990
|
+
import { join as join127 } from "node:path";
|
|
34991
34991
|
async function summarizeProjectDocs(repoPath, contentLogger) {
|
|
34992
34992
|
const rawContent = collectRawDocs(repoPath);
|
|
34993
34993
|
if (rawContent.total.length < 200) {
|
|
@@ -35041,12 +35041,12 @@ function collectRawDocs(repoPath) {
|
|
|
35041
35041
|
return capped;
|
|
35042
35042
|
};
|
|
35043
35043
|
const docsContent = [];
|
|
35044
|
-
const docsDir =
|
|
35044
|
+
const docsDir = join127(repoPath, "docs");
|
|
35045
35045
|
if (existsSync67(docsDir)) {
|
|
35046
35046
|
try {
|
|
35047
35047
|
const files = readdirSync11(docsDir).filter((f4) => f4.endsWith(".md")).sort();
|
|
35048
35048
|
for (const f4 of files) {
|
|
35049
|
-
const content = readCapped(
|
|
35049
|
+
const content = readCapped(join127(docsDir, f4), 5000);
|
|
35050
35050
|
if (content) {
|
|
35051
35051
|
docsContent.push(`### ${f4}
|
|
35052
35052
|
${content}`);
|
|
@@ -35060,21 +35060,21 @@ ${content}`);
|
|
|
35060
35060
|
let brand = "";
|
|
35061
35061
|
const brandCandidates = ["docs/brand-guidelines.md", "docs/design-guidelines.md"];
|
|
35062
35062
|
for (const p2 of brandCandidates) {
|
|
35063
|
-
brand = readCapped(
|
|
35063
|
+
brand = readCapped(join127(repoPath, p2), 3000);
|
|
35064
35064
|
if (brand)
|
|
35065
35065
|
break;
|
|
35066
35066
|
}
|
|
35067
35067
|
let styles3 = "";
|
|
35068
|
-
const stylesDir =
|
|
35068
|
+
const stylesDir = join127(repoPath, "assets", "writing-styles");
|
|
35069
35069
|
if (existsSync67(stylesDir)) {
|
|
35070
35070
|
try {
|
|
35071
35071
|
const files = readdirSync11(stylesDir).slice(0, 3);
|
|
35072
|
-
styles3 = files.map((f4) => readCapped(
|
|
35072
|
+
styles3 = files.map((f4) => readCapped(join127(stylesDir, f4), 1000)).filter(Boolean).join(`
|
|
35073
35073
|
|
|
35074
35074
|
`);
|
|
35075
35075
|
} catch {}
|
|
35076
35076
|
}
|
|
35077
|
-
const readme = readCapped(
|
|
35077
|
+
const readme = readCapped(join127(repoPath, "README.md"), 3000);
|
|
35078
35078
|
const total = [docs, brand, styles3, readme].join(`
|
|
35079
35079
|
`);
|
|
35080
35080
|
return { docs, brand, styles: styles3, readme, total };
|
|
@@ -35261,9 +35261,9 @@ IMPORTANT: Generate the image and output the path as JSON: {"imagePath": "/path/
|
|
|
35261
35261
|
import { execSync as execSync6 } from "node:child_process";
|
|
35262
35262
|
import { existsSync as existsSync68, mkdirSync as mkdirSync5, readdirSync as readdirSync12 } from "node:fs";
|
|
35263
35263
|
import { homedir as homedir33 } from "node:os";
|
|
35264
|
-
import { join as
|
|
35264
|
+
import { join as join128 } from "node:path";
|
|
35265
35265
|
async function generatePhoto(_content, context, config, platform10, contentId, contentLogger) {
|
|
35266
|
-
const mediaDir =
|
|
35266
|
+
const mediaDir = join128(config.contentDir.replace(/^~/, homedir33()), "media", String(contentId));
|
|
35267
35267
|
if (!existsSync68(mediaDir)) {
|
|
35268
35268
|
mkdirSync5(mediaDir, { recursive: true });
|
|
35269
35269
|
}
|
|
@@ -35288,7 +35288,7 @@ async function generatePhoto(_content, context, config, platform10, contentId, c
|
|
|
35288
35288
|
const imageFile = files.find((f4) => /\.(png|jpg|jpeg|webp)$/i.test(f4));
|
|
35289
35289
|
if (imageFile) {
|
|
35290
35290
|
const ext2 = imageFile.split(".").pop() ?? "png";
|
|
35291
|
-
return { path:
|
|
35291
|
+
return { path: join128(mediaDir, imageFile), ...dimensions, format: ext2 };
|
|
35292
35292
|
}
|
|
35293
35293
|
contentLogger.warn(`Photo generation produced no image for content ${contentId}`);
|
|
35294
35294
|
return null;
|
|
@@ -35378,7 +35378,7 @@ var init_content_creator = __esm(() => {
|
|
|
35378
35378
|
// src/commands/content/phases/content-logger.ts
|
|
35379
35379
|
import { createWriteStream as createWriteStream5, existsSync as existsSync69, mkdirSync as mkdirSync6, statSync as statSync8 } from "node:fs";
|
|
35380
35380
|
import { homedir as homedir34 } from "node:os";
|
|
35381
|
-
import { join as
|
|
35381
|
+
import { join as join129 } from "node:path";
|
|
35382
35382
|
|
|
35383
35383
|
class ContentLogger {
|
|
35384
35384
|
stream = null;
|
|
@@ -35386,7 +35386,7 @@ class ContentLogger {
|
|
|
35386
35386
|
logDir;
|
|
35387
35387
|
maxBytes;
|
|
35388
35388
|
constructor(maxBytes = 0) {
|
|
35389
|
-
this.logDir =
|
|
35389
|
+
this.logDir = join129(homedir34(), ".sunagentkit", "logs");
|
|
35390
35390
|
this.maxBytes = maxBytes;
|
|
35391
35391
|
}
|
|
35392
35392
|
init() {
|
|
@@ -35418,7 +35418,7 @@ class ContentLogger {
|
|
|
35418
35418
|
}
|
|
35419
35419
|
}
|
|
35420
35420
|
getLogPath() {
|
|
35421
|
-
return
|
|
35421
|
+
return join129(this.logDir, `content-${this.getDateStr()}.log`);
|
|
35422
35422
|
}
|
|
35423
35423
|
write(level, message) {
|
|
35424
35424
|
this.rotateIfNeeded();
|
|
@@ -35435,18 +35435,18 @@ class ContentLogger {
|
|
|
35435
35435
|
if (dateStr !== this.currentDate) {
|
|
35436
35436
|
this.close();
|
|
35437
35437
|
this.currentDate = dateStr;
|
|
35438
|
-
const logPath =
|
|
35438
|
+
const logPath = join129(this.logDir, `content-${dateStr}.log`);
|
|
35439
35439
|
this.stream = createWriteStream5(logPath, { flags: "a", mode: 384 });
|
|
35440
35440
|
return;
|
|
35441
35441
|
}
|
|
35442
35442
|
if (this.maxBytes > 0 && this.stream) {
|
|
35443
|
-
const logPath =
|
|
35443
|
+
const logPath = join129(this.logDir, `content-${this.currentDate}.log`);
|
|
35444
35444
|
try {
|
|
35445
35445
|
const stat16 = statSync8(logPath);
|
|
35446
35446
|
if (stat16.size >= this.maxBytes) {
|
|
35447
35447
|
this.close();
|
|
35448
35448
|
const suffix = Date.now();
|
|
35449
|
-
const rotatedPath =
|
|
35449
|
+
const rotatedPath = join129(this.logDir, `content-${this.currentDate}-${suffix}.log`);
|
|
35450
35450
|
import("node:fs/promises").then(({ rename: rename11 }) => rename11(logPath, rotatedPath).catch(() => {}));
|
|
35451
35451
|
this.stream = createWriteStream5(logPath, { flags: "w", mode: 384 });
|
|
35452
35452
|
}
|
|
@@ -35672,7 +35672,7 @@ function isNoiseCommit(title, author) {
|
|
|
35672
35672
|
// src/commands/content/phases/change-detector.ts
|
|
35673
35673
|
import { execSync as execSync8 } from "node:child_process";
|
|
35674
35674
|
import { existsSync as existsSync71, readFileSync as readFileSync18, readdirSync as readdirSync13, statSync as statSync9 } from "node:fs";
|
|
35675
|
-
import { join as
|
|
35675
|
+
import { join as join130 } from "node:path";
|
|
35676
35676
|
function detectCommits(repo, since) {
|
|
35677
35677
|
try {
|
|
35678
35678
|
const fetchUrl = sshToHttps(repo.remoteUrl);
|
|
@@ -35770,7 +35770,7 @@ function detectTags(repo, since) {
|
|
|
35770
35770
|
}
|
|
35771
35771
|
}
|
|
35772
35772
|
function detectCompletedPlans(repo, since) {
|
|
35773
|
-
const plansDir =
|
|
35773
|
+
const plansDir = join130(repo.path, "plans");
|
|
35774
35774
|
if (!existsSync71(plansDir))
|
|
35775
35775
|
return [];
|
|
35776
35776
|
const sinceMs = new Date(since).getTime();
|
|
@@ -35780,7 +35780,7 @@ function detectCompletedPlans(repo, since) {
|
|
|
35780
35780
|
for (const entry of entries) {
|
|
35781
35781
|
if (!entry.isDirectory())
|
|
35782
35782
|
continue;
|
|
35783
|
-
const planFile =
|
|
35783
|
+
const planFile = join130(plansDir, entry.name, "plan.md");
|
|
35784
35784
|
if (!existsSync71(planFile))
|
|
35785
35785
|
continue;
|
|
35786
35786
|
try {
|
|
@@ -35858,7 +35858,7 @@ function classifyCommit(event) {
|
|
|
35858
35858
|
// src/commands/content/phases/repo-discoverer.ts
|
|
35859
35859
|
import { execSync as execSync9 } from "node:child_process";
|
|
35860
35860
|
import { readdirSync as readdirSync14 } from "node:fs";
|
|
35861
|
-
import { join as
|
|
35861
|
+
import { join as join131 } from "node:path";
|
|
35862
35862
|
function discoverRepos2(cwd2) {
|
|
35863
35863
|
const repos = [];
|
|
35864
35864
|
if (isGitRepoRoot(cwd2)) {
|
|
@@ -35871,7 +35871,7 @@ function discoverRepos2(cwd2) {
|
|
|
35871
35871
|
for (const entry of entries) {
|
|
35872
35872
|
if (!entry.isDirectory() || entry.name.startsWith("."))
|
|
35873
35873
|
continue;
|
|
35874
|
-
const dirPath =
|
|
35874
|
+
const dirPath = join131(cwd2, entry.name);
|
|
35875
35875
|
if (isGitRepoRoot(dirPath)) {
|
|
35876
35876
|
const info = getRepoInfo(dirPath);
|
|
35877
35877
|
if (info)
|
|
@@ -36384,9 +36384,9 @@ function previewContent(content) {
|
|
|
36384
36384
|
const statusColor = getStatusColor(content.status);
|
|
36385
36385
|
console.log();
|
|
36386
36386
|
console.log(`${badge} ${statusColor(content.status.toUpperCase())} ID: ${content.id}`);
|
|
36387
|
-
console.log(
|
|
36387
|
+
console.log(import_picocolors38.default.dim("─".repeat(60)));
|
|
36388
36388
|
if (content.hookLine) {
|
|
36389
|
-
console.log(
|
|
36389
|
+
console.log(import_picocolors38.default.bold(import_picocolors38.default.cyan("Hook: ")) + content.hookLine);
|
|
36390
36390
|
}
|
|
36391
36391
|
console.log();
|
|
36392
36392
|
console.log(content.textContent);
|
|
@@ -36395,53 +36395,53 @@ function previewContent(content) {
|
|
|
36395
36395
|
try {
|
|
36396
36396
|
const tags = JSON.parse(content.hashtags);
|
|
36397
36397
|
if (tags.length > 0) {
|
|
36398
|
-
console.log(
|
|
36398
|
+
console.log(import_picocolors38.default.dim("Tags: ") + tags.map((t) => import_picocolors38.default.blue(`#${t}`)).join(" "));
|
|
36399
36399
|
}
|
|
36400
36400
|
} catch {}
|
|
36401
36401
|
}
|
|
36402
36402
|
if (content.callToAction) {
|
|
36403
|
-
console.log(
|
|
36403
|
+
console.log(import_picocolors38.default.dim("CTA: ") + content.callToAction);
|
|
36404
36404
|
}
|
|
36405
36405
|
if (content.mediaPath) {
|
|
36406
|
-
console.log(
|
|
36406
|
+
console.log(import_picocolors38.default.dim("Media: ") + content.mediaPath);
|
|
36407
36407
|
}
|
|
36408
36408
|
if (content.scheduledAt) {
|
|
36409
|
-
console.log(
|
|
36409
|
+
console.log(import_picocolors38.default.dim("Scheduled: ") + content.scheduledAt);
|
|
36410
36410
|
}
|
|
36411
|
-
console.log(
|
|
36411
|
+
console.log(import_picocolors38.default.dim("─".repeat(60)));
|
|
36412
36412
|
console.log();
|
|
36413
36413
|
}
|
|
36414
36414
|
function getPlatformBadge(platform10) {
|
|
36415
36415
|
switch (platform10) {
|
|
36416
36416
|
case "x":
|
|
36417
|
-
return
|
|
36417
|
+
return import_picocolors38.default.bgBlue(import_picocolors38.default.white(" X "));
|
|
36418
36418
|
case "x_thread":
|
|
36419
|
-
return
|
|
36419
|
+
return import_picocolors38.default.bgBlue(import_picocolors38.default.white(" X Thread "));
|
|
36420
36420
|
case "facebook":
|
|
36421
|
-
return
|
|
36421
|
+
return import_picocolors38.default.bgCyan(import_picocolors38.default.white(" Facebook "));
|
|
36422
36422
|
default:
|
|
36423
|
-
return
|
|
36423
|
+
return import_picocolors38.default.bgBlack(import_picocolors38.default.white(` ${platform10} `));
|
|
36424
36424
|
}
|
|
36425
36425
|
}
|
|
36426
36426
|
function getStatusColor(status2) {
|
|
36427
36427
|
switch (status2) {
|
|
36428
36428
|
case "published":
|
|
36429
|
-
return
|
|
36429
|
+
return import_picocolors38.default.green;
|
|
36430
36430
|
case "failed":
|
|
36431
|
-
return
|
|
36431
|
+
return import_picocolors38.default.red;
|
|
36432
36432
|
case "reviewing":
|
|
36433
|
-
return
|
|
36433
|
+
return import_picocolors38.default.yellow;
|
|
36434
36434
|
case "scheduled":
|
|
36435
|
-
return
|
|
36435
|
+
return import_picocolors38.default.blue;
|
|
36436
36436
|
case "draft":
|
|
36437
|
-
return
|
|
36437
|
+
return import_picocolors38.default.gray;
|
|
36438
36438
|
default:
|
|
36439
|
-
return
|
|
36439
|
+
return import_picocolors38.default.white;
|
|
36440
36440
|
}
|
|
36441
36441
|
}
|
|
36442
|
-
var
|
|
36442
|
+
var import_picocolors38;
|
|
36443
36443
|
var init_content_previewer = __esm(() => {
|
|
36444
|
-
|
|
36444
|
+
import_picocolors38 = __toESM(require_picocolors(), 1);
|
|
36445
36445
|
});
|
|
36446
36446
|
|
|
36447
36447
|
// src/commands/content/phases/review-manager.ts
|
|
@@ -36538,9 +36538,9 @@ var init_types3 = __esm(() => {
|
|
|
36538
36538
|
|
|
36539
36539
|
// src/commands/content/phases/state-manager.ts
|
|
36540
36540
|
import { readFile as readFile51, rename as rename11, writeFile as writeFile39 } from "node:fs/promises";
|
|
36541
|
-
import { join as
|
|
36541
|
+
import { join as join132 } from "node:path";
|
|
36542
36542
|
async function loadContentConfig(projectDir) {
|
|
36543
|
-
const configPath =
|
|
36543
|
+
const configPath = join132(projectDir, TAKUMI_CONFIG_FILE2);
|
|
36544
36544
|
try {
|
|
36545
36545
|
const raw = await readFile51(configPath, "utf-8");
|
|
36546
36546
|
const json = JSON.parse(raw);
|
|
@@ -36550,13 +36550,13 @@ async function loadContentConfig(projectDir) {
|
|
|
36550
36550
|
}
|
|
36551
36551
|
}
|
|
36552
36552
|
async function saveContentConfig(projectDir, config) {
|
|
36553
|
-
const configPath =
|
|
36553
|
+
const configPath = join132(projectDir, TAKUMI_CONFIG_FILE2);
|
|
36554
36554
|
const json = await readJsonSafe(configPath);
|
|
36555
36555
|
json.content = { ...json.content, ...config };
|
|
36556
36556
|
await atomicWrite3(configPath, json);
|
|
36557
36557
|
}
|
|
36558
36558
|
async function loadContentState(projectDir) {
|
|
36559
|
-
const configPath =
|
|
36559
|
+
const configPath = join132(projectDir, TAKUMI_CONFIG_FILE2);
|
|
36560
36560
|
try {
|
|
36561
36561
|
const raw = await readFile51(configPath, "utf-8");
|
|
36562
36562
|
const json = JSON.parse(raw);
|
|
@@ -36567,7 +36567,7 @@ async function loadContentState(projectDir) {
|
|
|
36567
36567
|
}
|
|
36568
36568
|
}
|
|
36569
36569
|
async function saveContentState(projectDir, state) {
|
|
36570
|
-
const configPath =
|
|
36570
|
+
const configPath = join132(projectDir, TAKUMI_CONFIG_FILE2);
|
|
36571
36571
|
const sevenDaysAgo = new Date(Date.now() - 7 * 24 * 60 * 60 * 1000).toISOString().slice(0, 10);
|
|
36572
36572
|
for (const key of Object.keys(state.dailyPostCounts)) {
|
|
36573
36573
|
const dateStr = key.slice(-10);
|
|
@@ -36849,10 +36849,10 @@ var init_platform_setup_x = __esm(() => {
|
|
|
36849
36849
|
|
|
36850
36850
|
// src/commands/content/phases/setup-wizard.ts
|
|
36851
36851
|
import { existsSync as existsSync72 } from "node:fs";
|
|
36852
|
-
import { join as
|
|
36852
|
+
import { join as join133 } from "node:path";
|
|
36853
36853
|
async function runSetupWizard2(cwd2, contentLogger) {
|
|
36854
36854
|
console.log();
|
|
36855
|
-
oe(
|
|
36855
|
+
oe(import_picocolors39.default.bgCyan(import_picocolors39.default.white(" SK Content — Multi-Channel Content Engine ")));
|
|
36856
36856
|
f2.info("This wizard will help you set up automated content publishing");
|
|
36857
36857
|
f2.info(`from your git activity to social media platforms.
|
|
36858
36858
|
`);
|
|
@@ -36911,14 +36911,14 @@ async function showRepoSummary(cwd2) {
|
|
|
36911
36911
|
f2.info(`Found ${repos.length} git repo(s) to monitor:`);
|
|
36912
36912
|
for (const repo of repos) {
|
|
36913
36913
|
const remote = repo.remoteUrl ? ` (${repo.remoteUrl})` : " (local only)";
|
|
36914
|
-
f2.info(` ${
|
|
36914
|
+
f2.info(` ${import_picocolors39.default.green("●")} ${repo.name}${remote}`);
|
|
36915
36915
|
}
|
|
36916
36916
|
}
|
|
36917
36917
|
function detectBrandAssets(cwd2, contentLogger) {
|
|
36918
36918
|
const repos = discoverRepos2(cwd2);
|
|
36919
36919
|
for (const repo of repos) {
|
|
36920
|
-
const hasGuidelines = existsSync72(
|
|
36921
|
-
const hasStyles = existsSync72(
|
|
36920
|
+
const hasGuidelines = existsSync72(join133(repo.path, "docs", "brand-guidelines.md"));
|
|
36921
|
+
const hasStyles = existsSync72(join133(repo.path, "assets", "writing-styles"));
|
|
36922
36922
|
if (!hasGuidelines) {
|
|
36923
36923
|
f2.warning(`${repo.name}: No docs/brand-guidelines.md — content will use generic tone.`);
|
|
36924
36924
|
contentLogger.warn(`${repo.name}: missing docs/brand-guidelines.md`);
|
|
@@ -36967,20 +36967,20 @@ async function configureReviewMode(config) {
|
|
|
36967
36967
|
function printSummary(selectedPlatforms, config) {
|
|
36968
36968
|
f2.success("Configuration saved!");
|
|
36969
36969
|
console.log();
|
|
36970
|
-
console.log(` ${
|
|
36971
|
-
console.log(` ${
|
|
36972
|
-
console.log(` ${
|
|
36973
|
-
console.log(` ${
|
|
36970
|
+
console.log(` ${import_picocolors39.default.dim("Platforms:")} ${selectedPlatforms.join(", ")}`);
|
|
36971
|
+
console.log(` ${import_picocolors39.default.dim("Review:")} ${config.reviewMode}`);
|
|
36972
|
+
console.log(` ${import_picocolors39.default.dim("Max/day:")} ${config.maxContentPerDay}`);
|
|
36973
|
+
console.log(` ${import_picocolors39.default.dim("Timezone:")} ${config.schedule.timezone}`);
|
|
36974
36974
|
console.log();
|
|
36975
36975
|
}
|
|
36976
|
-
var
|
|
36976
|
+
var import_picocolors39;
|
|
36977
36977
|
var init_setup_wizard = __esm(() => {
|
|
36978
36978
|
init_dist2();
|
|
36979
36979
|
init_platform_setup_facebook();
|
|
36980
36980
|
init_platform_setup_x();
|
|
36981
36981
|
init_repo_discoverer();
|
|
36982
36982
|
init_state_manager();
|
|
36983
|
-
|
|
36983
|
+
import_picocolors39 = __toESM(require_picocolors(), 1);
|
|
36984
36984
|
});
|
|
36985
36985
|
|
|
36986
36986
|
// src/commands/content/content-review-commands.ts
|
|
@@ -37060,9 +37060,9 @@ __export(exports_content_subcommands, {
|
|
|
37060
37060
|
});
|
|
37061
37061
|
import { existsSync as existsSync74, readFileSync as readFileSync19, unlinkSync as unlinkSync6 } from "node:fs";
|
|
37062
37062
|
import { homedir as homedir36 } from "node:os";
|
|
37063
|
-
import { join as
|
|
37063
|
+
import { join as join134 } from "node:path";
|
|
37064
37064
|
function isDaemonRunning() {
|
|
37065
|
-
const lockFile =
|
|
37065
|
+
const lockFile = join134(LOCK_DIR, `${LOCK_NAME2}.lock`);
|
|
37066
37066
|
if (!existsSync74(lockFile))
|
|
37067
37067
|
return { running: false, pid: null };
|
|
37068
37068
|
try {
|
|
@@ -37094,7 +37094,7 @@ async function startContent(options2) {
|
|
|
37094
37094
|
await contentCommand(options2);
|
|
37095
37095
|
}
|
|
37096
37096
|
async function stopContent() {
|
|
37097
|
-
const lockFile =
|
|
37097
|
+
const lockFile = join134(LOCK_DIR, `${LOCK_NAME2}.lock`);
|
|
37098
37098
|
if (!existsSync74(lockFile)) {
|
|
37099
37099
|
logger.info("Content daemon is not running.");
|
|
37100
37100
|
return;
|
|
@@ -37133,9 +37133,9 @@ async function statusContent() {
|
|
|
37133
37133
|
} catch {}
|
|
37134
37134
|
}
|
|
37135
37135
|
async function logsContent(options2) {
|
|
37136
|
-
const logDir =
|
|
37136
|
+
const logDir = join134(homedir36(), ".sunagentkit", "logs");
|
|
37137
37137
|
const dateStr = new Date().toISOString().slice(0, 10).replace(/-/g, "");
|
|
37138
|
-
const logPath =
|
|
37138
|
+
const logPath = join134(logDir, `content-${dateStr}.log`);
|
|
37139
37139
|
if (!existsSync74(logPath)) {
|
|
37140
37140
|
logger.info("No content logs found for today.");
|
|
37141
37141
|
return;
|
|
@@ -37167,13 +37167,13 @@ var init_content_subcommands = __esm(() => {
|
|
|
37167
37167
|
init_setup_wizard();
|
|
37168
37168
|
init_state_manager();
|
|
37169
37169
|
init_content_review_commands();
|
|
37170
|
-
LOCK_DIR =
|
|
37170
|
+
LOCK_DIR = join134(homedir36(), ".sunagentkit", "locks");
|
|
37171
37171
|
});
|
|
37172
37172
|
|
|
37173
37173
|
// src/commands/content/content-command.ts
|
|
37174
37174
|
import { existsSync as existsSync75, mkdirSync as mkdirSync8, unlinkSync as unlinkSync7, writeFileSync as writeFileSync6 } from "node:fs";
|
|
37175
37175
|
import { homedir as homedir37 } from "node:os";
|
|
37176
|
-
import { join as
|
|
37176
|
+
import { join as join135 } from "node:path";
|
|
37177
37177
|
async function contentCommand(options2) {
|
|
37178
37178
|
const cwd2 = process.cwd();
|
|
37179
37179
|
const contentLogger = new ContentLogger;
|
|
@@ -37351,8 +37351,8 @@ var init_content_command = __esm(() => {
|
|
|
37351
37351
|
init_publisher();
|
|
37352
37352
|
init_review_manager();
|
|
37353
37353
|
init_state_manager();
|
|
37354
|
-
LOCK_DIR2 =
|
|
37355
|
-
LOCK_FILE =
|
|
37354
|
+
LOCK_DIR2 = join135(homedir37(), ".sunagentkit", "locks");
|
|
37355
|
+
LOCK_FILE = join135(LOCK_DIR2, "sk-content.lock");
|
|
37356
37356
|
});
|
|
37357
37357
|
|
|
37358
37358
|
// src/commands/content/index.ts
|
|
@@ -37385,22 +37385,22 @@ function padEnd(text, width) {
|
|
|
37385
37385
|
const padding = Math.max(0, width - visibleLength);
|
|
37386
37386
|
return text + " ".repeat(padding);
|
|
37387
37387
|
}
|
|
37388
|
-
var
|
|
37388
|
+
var import_picocolors40, NO_COLOR, isColorSupported, identity = (text) => text, colors, defaultTheme;
|
|
37389
37389
|
var init_help_colors = __esm(() => {
|
|
37390
|
-
|
|
37390
|
+
import_picocolors40 = __toESM(require_picocolors(), 1);
|
|
37391
37391
|
NO_COLOR = process.env.NO_COLOR !== undefined;
|
|
37392
37392
|
isColorSupported = !NO_COLOR && Boolean(process.stdout.isTTY);
|
|
37393
37393
|
colors = {
|
|
37394
|
-
banner: isColorSupported ?
|
|
37395
|
-
command: isColorSupported ?
|
|
37396
|
-
heading: isColorSupported ?
|
|
37397
|
-
flag: isColorSupported ?
|
|
37398
|
-
description: isColorSupported ?
|
|
37399
|
-
example: isColorSupported ?
|
|
37400
|
-
warning: isColorSupported ?
|
|
37401
|
-
error: isColorSupported ?
|
|
37402
|
-
muted: isColorSupported ?
|
|
37403
|
-
success: isColorSupported ?
|
|
37394
|
+
banner: isColorSupported ? import_picocolors40.default.cyan : identity,
|
|
37395
|
+
command: isColorSupported ? import_picocolors40.default.bold : identity,
|
|
37396
|
+
heading: isColorSupported ? import_picocolors40.default.yellow : identity,
|
|
37397
|
+
flag: isColorSupported ? import_picocolors40.default.green : identity,
|
|
37398
|
+
description: isColorSupported ? import_picocolors40.default.gray : identity,
|
|
37399
|
+
example: isColorSupported ? import_picocolors40.default.blue : identity,
|
|
37400
|
+
warning: isColorSupported ? import_picocolors40.default.yellow : identity,
|
|
37401
|
+
error: isColorSupported ? import_picocolors40.default.red : identity,
|
|
37402
|
+
muted: isColorSupported ? import_picocolors40.default.dim : identity,
|
|
37403
|
+
success: isColorSupported ? import_picocolors40.default.green : identity
|
|
37404
37404
|
};
|
|
37405
37405
|
defaultTheme = {
|
|
37406
37406
|
banner: colors.banner,
|
|
@@ -48909,72 +48909,20 @@ function isSyncContext(ctx) {
|
|
|
48909
48909
|
return "syncInProgress" in ctx && ctx.syncInProgress === true && "syncTrackedFiles" in ctx && Array.isArray(ctx.syncTrackedFiles);
|
|
48910
48910
|
}
|
|
48911
48911
|
|
|
48912
|
-
// src/domains/installers/claude-code/installer.ts
|
|
48913
|
-
init_logger();
|
|
48914
|
-
|
|
48915
|
-
// src/domains/installers/claude-code/conflict-handler.ts
|
|
48916
|
-
init_logger();
|
|
48917
|
-
var import_fs_extra3 = __toESM(require_lib(), 1);
|
|
48918
|
-
import { join as join21 } from "node:path";
|
|
48919
|
-
async function handleConflicts(ctx) {
|
|
48920
|
-
if (ctx.cancelled)
|
|
48921
|
-
return ctx;
|
|
48922
|
-
if (!ctx.options.global)
|
|
48923
|
-
return ctx;
|
|
48924
|
-
if (isLocalSameAsGlobal()) {
|
|
48925
|
-
return ctx;
|
|
48926
|
-
}
|
|
48927
|
-
const localSettingsPath = join21(process.cwd(), ".claude", "settings.json");
|
|
48928
|
-
if (!await import_fs_extra3.pathExists(localSettingsPath)) {
|
|
48929
|
-
return ctx;
|
|
48930
|
-
}
|
|
48931
|
-
if (ctx.isNonInteractive) {
|
|
48932
|
-
logger.warning("Local .claude/settings.json detected. Local settings take precedence over global.");
|
|
48933
|
-
logger.warning("Consider removing local installation: rm -rf .claude");
|
|
48934
|
-
return ctx;
|
|
48935
|
-
}
|
|
48936
|
-
const choice = await ctx.prompts.promptLocalMigration();
|
|
48937
|
-
if (choice === "cancel") {
|
|
48938
|
-
ctx.prompts.outro("Installation cancelled.");
|
|
48939
|
-
return { ...ctx, cancelled: true };
|
|
48940
|
-
}
|
|
48941
|
-
if (choice === "remove") {
|
|
48942
|
-
const localClaudeDir = join21(process.cwd(), ".claude");
|
|
48943
|
-
try {
|
|
48944
|
-
await import_fs_extra3.remove(localClaudeDir);
|
|
48945
|
-
logger.success("Removed local .claude/ directory");
|
|
48946
|
-
} catch (error) {
|
|
48947
|
-
logger.error(`Failed to remove local installation: ${error instanceof Error ? error.message : "Unknown error"}`);
|
|
48948
|
-
logger.warning("Proceeding with global installation anyway.");
|
|
48949
|
-
}
|
|
48950
|
-
}
|
|
48951
|
-
if (choice === "keep") {
|
|
48952
|
-
logger.warning("Proceeding with global installation. Local settings will take precedence.");
|
|
48953
|
-
}
|
|
48954
|
-
return ctx;
|
|
48955
|
-
}
|
|
48956
|
-
|
|
48957
|
-
// src/domains/installers/claude-code/merge-handler.ts
|
|
48958
|
-
import { join as join37 } from "node:path";
|
|
48959
|
-
|
|
48960
|
-
// src/domains/installation/deletion-handler.ts
|
|
48961
|
-
import { existsSync as existsSync13, lstatSync, readdirSync as readdirSync2, rmSync, rmdirSync, unlinkSync } from "node:fs";
|
|
48962
|
-
import { dirname as dirname6, join as join24, relative as relative3, resolve as resolve3, sep as sep2 } from "node:path";
|
|
48963
|
-
|
|
48964
48912
|
// src/services/file-operations/manifest/manifest-reader.ts
|
|
48965
|
-
import { join as
|
|
48913
|
+
import { join as join22 } from "node:path";
|
|
48966
48914
|
|
|
48967
48915
|
// src/domains/migration/metadata-migration.ts
|
|
48968
48916
|
init_logger();
|
|
48969
|
-
var
|
|
48970
|
-
import { join as
|
|
48917
|
+
var import_fs_extra3 = __toESM(require_lib(), 1);
|
|
48918
|
+
import { join as join21 } from "node:path";
|
|
48971
48919
|
async function detectMetadataFormat(claudeDir) {
|
|
48972
|
-
const metadataPath =
|
|
48973
|
-
if (!await
|
|
48920
|
+
const metadataPath = join21(claudeDir, "metadata.json");
|
|
48921
|
+
if (!await import_fs_extra3.pathExists(metadataPath)) {
|
|
48974
48922
|
return { format: "none", metadata: null, detectedKit: null };
|
|
48975
48923
|
}
|
|
48976
48924
|
try {
|
|
48977
|
-
const content = await
|
|
48925
|
+
const content = await import_fs_extra3.readFile(metadataPath, "utf-8");
|
|
48978
48926
|
const trimmed = content.trim();
|
|
48979
48927
|
if (!trimmed) {
|
|
48980
48928
|
return { format: "none", metadata: null, detectedKit: null };
|
|
@@ -49023,7 +48971,7 @@ async function migrateToMultiKit(claudeDir) {
|
|
|
49023
48971
|
toFormat: "multi-kit"
|
|
49024
48972
|
};
|
|
49025
48973
|
}
|
|
49026
|
-
const metadataPath =
|
|
48974
|
+
const metadataPath = join21(claudeDir, "metadata.json");
|
|
49027
48975
|
const legacy = detection.metadata;
|
|
49028
48976
|
if (!legacy) {
|
|
49029
48977
|
return {
|
|
@@ -49060,7 +49008,7 @@ async function migrateToMultiKit(claudeDir) {
|
|
|
49060
49008
|
},
|
|
49061
49009
|
...legacy.deletions !== undefined && { deletions: legacy.deletions }
|
|
49062
49010
|
};
|
|
49063
|
-
await
|
|
49011
|
+
await import_fs_extra3.writeFile(metadataPath, JSON.stringify(multiKit, null, 2), "utf-8");
|
|
49064
49012
|
logger.info(`Migrated metadata from legacy format to multi-kit (detected: ${legacyKit})`);
|
|
49065
49013
|
return {
|
|
49066
49014
|
success: true,
|
|
@@ -49136,14 +49084,14 @@ function getInstalledKits(metadata) {
|
|
|
49136
49084
|
// src/services/file-operations/manifest/manifest-reader.ts
|
|
49137
49085
|
init_logger();
|
|
49138
49086
|
init_types2();
|
|
49139
|
-
var
|
|
49087
|
+
var import_fs_extra4 = __toESM(require_lib(), 1);
|
|
49140
49088
|
async function readManifest(providerRoot) {
|
|
49141
|
-
const metadataPath =
|
|
49142
|
-
if (!await
|
|
49089
|
+
const metadataPath = join22(providerRoot, "metadata.json");
|
|
49090
|
+
if (!await import_fs_extra4.pathExists(metadataPath)) {
|
|
49143
49091
|
return null;
|
|
49144
49092
|
}
|
|
49145
49093
|
try {
|
|
49146
|
-
const content = await
|
|
49094
|
+
const content = await import_fs_extra4.readFile(metadataPath, "utf-8");
|
|
49147
49095
|
const parsed = JSON.parse(content);
|
|
49148
49096
|
return MetadataSchema.parse(parsed);
|
|
49149
49097
|
} catch (error) {
|
|
@@ -49279,221 +49227,10 @@ async function getUninstallManifest(providerRoot, kit) {
|
|
|
49279
49227
|
remainingKits: []
|
|
49280
49228
|
};
|
|
49281
49229
|
}
|
|
49282
|
-
|
|
49283
|
-
|
|
49284
|
-
init_logger();
|
|
49285
|
-
init_path_resolver();
|
|
49286
|
-
var import_fs_extra6 = __toESM(require_lib(), 1);
|
|
49287
|
-
var import_picomatch = __toESM(require_picomatch2(), 1);
|
|
49288
|
-
function findFileInMetadata(metadata, path3) {
|
|
49289
|
-
if (!metadata)
|
|
49290
|
-
return { tracked: null, ownerKit: null };
|
|
49291
|
-
if (metadata.kits) {
|
|
49292
|
-
for (const [kitName, kitMeta] of Object.entries(metadata.kits)) {
|
|
49293
|
-
if (!kitMeta?.files)
|
|
49294
|
-
continue;
|
|
49295
|
-
const found = kitMeta.files.find((f3) => f3.path === path3);
|
|
49296
|
-
if (found)
|
|
49297
|
-
return { tracked: found, ownerKit: kitName };
|
|
49298
|
-
}
|
|
49299
|
-
}
|
|
49300
|
-
if (metadata.files) {
|
|
49301
|
-
const found = metadata.files.find((f3) => f3.path === path3);
|
|
49302
|
-
if (found)
|
|
49303
|
-
return { tracked: found, ownerKit: null };
|
|
49304
|
-
}
|
|
49305
|
-
return { tracked: null, ownerKit: null };
|
|
49306
|
-
}
|
|
49307
|
-
function shouldDeletePath(path3, metadata, installingKit) {
|
|
49308
|
-
const { tracked, ownerKit } = findFileInMetadata(metadata, path3);
|
|
49309
|
-
if (!tracked)
|
|
49310
|
-
return true;
|
|
49311
|
-
if (tracked.ownership === "user")
|
|
49312
|
-
return false;
|
|
49313
|
-
if (installingKit && ownerKit && ownerKit !== installingKit)
|
|
49314
|
-
return false;
|
|
49315
|
-
return true;
|
|
49316
|
-
}
|
|
49317
|
-
function collectFilesRecursively(dir, baseDir) {
|
|
49318
|
-
const results = [];
|
|
49319
|
-
if (!existsSync13(dir))
|
|
49320
|
-
return results;
|
|
49321
|
-
try {
|
|
49322
|
-
const entries = readdirSync2(dir, { withFileTypes: true });
|
|
49323
|
-
for (const entry of entries) {
|
|
49324
|
-
const fullPath = join24(dir, entry.name);
|
|
49325
|
-
const relativePath = relative3(baseDir, fullPath);
|
|
49326
|
-
if (entry.isDirectory()) {
|
|
49327
|
-
results.push(...collectFilesRecursively(fullPath, baseDir));
|
|
49328
|
-
} else {
|
|
49329
|
-
results.push(relativePath);
|
|
49330
|
-
}
|
|
49331
|
-
}
|
|
49332
|
-
} catch {}
|
|
49333
|
-
return results;
|
|
49334
|
-
}
|
|
49335
|
-
function expandGlobPatterns(patterns, claudeDir) {
|
|
49336
|
-
const expanded = [];
|
|
49337
|
-
const allFiles = collectFilesRecursively(claudeDir, claudeDir);
|
|
49338
|
-
for (const pattern of patterns) {
|
|
49339
|
-
if (PathResolver.isGlobPattern(pattern)) {
|
|
49340
|
-
const matcher = import_picomatch.default(pattern);
|
|
49341
|
-
const matches = allFiles.filter((file) => matcher(file));
|
|
49342
|
-
expanded.push(...matches);
|
|
49343
|
-
if (matches.length > 0) {
|
|
49344
|
-
logger.debug(`Pattern "${pattern}" matched ${matches.length} files`);
|
|
49345
|
-
}
|
|
49346
|
-
} else {
|
|
49347
|
-
expanded.push(pattern);
|
|
49348
|
-
}
|
|
49349
|
-
}
|
|
49350
|
-
return [...new Set(expanded)];
|
|
49351
|
-
}
|
|
49352
|
-
var MAX_CLEANUP_ITERATIONS = 50;
|
|
49353
|
-
function cleanupEmptyDirectories(filePath, claudeDir) {
|
|
49354
|
-
const normalizedClaudeDir = resolve3(claudeDir);
|
|
49355
|
-
let currentDir = resolve3(dirname6(filePath));
|
|
49356
|
-
let iterations = 0;
|
|
49357
|
-
while (currentDir !== normalizedClaudeDir && currentDir.startsWith(normalizedClaudeDir) && iterations < MAX_CLEANUP_ITERATIONS) {
|
|
49358
|
-
iterations++;
|
|
49359
|
-
try {
|
|
49360
|
-
const entries = readdirSync2(currentDir);
|
|
49361
|
-
if (entries.length === 0) {
|
|
49362
|
-
rmdirSync(currentDir);
|
|
49363
|
-
logger.debug(`Removed empty directory: ${currentDir}`);
|
|
49364
|
-
currentDir = resolve3(dirname6(currentDir));
|
|
49365
|
-
} else {
|
|
49366
|
-
break;
|
|
49367
|
-
}
|
|
49368
|
-
} catch {
|
|
49369
|
-
break;
|
|
49370
|
-
}
|
|
49371
|
-
}
|
|
49372
|
-
}
|
|
49373
|
-
function deletePath(fullPath, claudeDir) {
|
|
49374
|
-
const normalizedPath = resolve3(fullPath);
|
|
49375
|
-
const normalizedClaudeDir = resolve3(claudeDir);
|
|
49376
|
-
if (!normalizedPath.startsWith(`${normalizedClaudeDir}${sep2}`) && normalizedPath !== normalizedClaudeDir) {
|
|
49377
|
-
throw new Error(`Path traversal detected: ${fullPath}`);
|
|
49378
|
-
}
|
|
49379
|
-
try {
|
|
49380
|
-
const stat = lstatSync(fullPath);
|
|
49381
|
-
if (stat.isDirectory()) {
|
|
49382
|
-
rmSync(fullPath, { recursive: true, force: true });
|
|
49383
|
-
} else {
|
|
49384
|
-
unlinkSync(fullPath);
|
|
49385
|
-
cleanupEmptyDirectories(fullPath, claudeDir);
|
|
49386
|
-
}
|
|
49387
|
-
} catch (error) {
|
|
49388
|
-
throw new Error(`Failed to delete ${fullPath}: ${error instanceof Error ? error.message : String(error)}`);
|
|
49389
|
-
}
|
|
49390
|
-
}
|
|
49391
|
-
async function updateMetadataAfterDeletion(claudeDir, deletedPaths) {
|
|
49392
|
-
const metadataPath = join24(claudeDir, "metadata.json");
|
|
49393
|
-
if (!await import_fs_extra6.pathExists(metadataPath)) {
|
|
49394
|
-
return;
|
|
49395
|
-
}
|
|
49396
|
-
let content;
|
|
49397
|
-
try {
|
|
49398
|
-
content = await import_fs_extra6.readFile(metadataPath, "utf-8");
|
|
49399
|
-
} catch {
|
|
49400
|
-
logger.debug("Failed to read metadata.json for cleanup");
|
|
49401
|
-
return;
|
|
49402
|
-
}
|
|
49403
|
-
let metadata;
|
|
49404
|
-
try {
|
|
49405
|
-
metadata = JSON.parse(content);
|
|
49406
|
-
} catch {
|
|
49407
|
-
logger.debug("Failed to parse metadata.json for cleanup");
|
|
49408
|
-
return;
|
|
49409
|
-
}
|
|
49410
|
-
const deletedSet = new Set(deletedPaths);
|
|
49411
|
-
const isDeletedOrInDeletedDir = (path3) => {
|
|
49412
|
-
if (deletedSet.has(path3))
|
|
49413
|
-
return true;
|
|
49414
|
-
for (const deleted of deletedPaths) {
|
|
49415
|
-
if (path3.startsWith(`${deleted}/`))
|
|
49416
|
-
return true;
|
|
49417
|
-
}
|
|
49418
|
-
return false;
|
|
49419
|
-
};
|
|
49420
|
-
if (metadata.kits) {
|
|
49421
|
-
for (const kitName of Object.keys(metadata.kits)) {
|
|
49422
|
-
const kit = metadata.kits[kitName];
|
|
49423
|
-
if (kit?.files) {
|
|
49424
|
-
kit.files = kit.files.filter((f3) => !isDeletedOrInDeletedDir(f3.path));
|
|
49425
|
-
}
|
|
49426
|
-
}
|
|
49427
|
-
}
|
|
49428
|
-
if (metadata.files) {
|
|
49429
|
-
metadata.files = metadata.files.filter((f3) => !isDeletedOrInDeletedDir(f3.path));
|
|
49430
|
-
}
|
|
49431
|
-
try {
|
|
49432
|
-
await import_fs_extra6.writeFile(metadataPath, JSON.stringify(metadata, null, 2));
|
|
49433
|
-
logger.debug(`Updated metadata.json, removed ${deletedPaths.length} entries`);
|
|
49434
|
-
} catch {
|
|
49435
|
-
logger.debug("Failed to write updated metadata.json");
|
|
49436
|
-
}
|
|
49437
|
-
}
|
|
49438
|
-
async function handleDeletions(sourceMetadata, claudeDir, installingKit) {
|
|
49439
|
-
const deletionPatterns = sourceMetadata.deletions || [];
|
|
49440
|
-
if (deletionPatterns.length === 0) {
|
|
49441
|
-
return { deletedPaths: [], preservedPaths: [], errors: [] };
|
|
49442
|
-
}
|
|
49443
|
-
const deletions = expandGlobPatterns(deletionPatterns, claudeDir);
|
|
49444
|
-
const userMetadata = await readManifest(claudeDir);
|
|
49445
|
-
const result = { deletedPaths: [], preservedPaths: [], errors: [] };
|
|
49446
|
-
for (const path3 of deletions) {
|
|
49447
|
-
const fullPath = join24(claudeDir, path3);
|
|
49448
|
-
const normalizedPath = resolve3(fullPath);
|
|
49449
|
-
const normalizedClaudeDir = resolve3(claudeDir);
|
|
49450
|
-
if (!normalizedPath.startsWith(`${normalizedClaudeDir}${sep2}`)) {
|
|
49451
|
-
logger.warning(`Skipping invalid path: ${path3}`);
|
|
49452
|
-
result.errors.push(path3);
|
|
49453
|
-
continue;
|
|
49454
|
-
}
|
|
49455
|
-
if (!shouldDeletePath(path3, userMetadata, installingKit)) {
|
|
49456
|
-
result.preservedPaths.push(path3);
|
|
49457
|
-
logger.verbose(`Preserved file (cross-kit or user-owned): ${path3}`);
|
|
49458
|
-
continue;
|
|
49459
|
-
}
|
|
49460
|
-
if (existsSync13(fullPath)) {
|
|
49461
|
-
try {
|
|
49462
|
-
deletePath(fullPath, claudeDir);
|
|
49463
|
-
result.deletedPaths.push(path3);
|
|
49464
|
-
logger.verbose(`Deleted: ${path3}`);
|
|
49465
|
-
} catch (error) {
|
|
49466
|
-
result.errors.push(path3);
|
|
49467
|
-
logger.debug(`Failed to delete ${path3}: ${error}`);
|
|
49468
|
-
}
|
|
49469
|
-
}
|
|
49470
|
-
}
|
|
49471
|
-
if (result.deletedPaths.length > 0) {
|
|
49472
|
-
await updateMetadataAfterDeletion(claudeDir, result.deletedPaths);
|
|
49473
|
-
}
|
|
49474
|
-
return result;
|
|
49475
|
-
}
|
|
49476
|
-
|
|
49477
|
-
// src/domains/installation/file-merger.ts
|
|
49478
|
-
init_logger();
|
|
49479
|
-
init_types2();
|
|
49480
|
-
init_dist2();
|
|
49481
|
-
|
|
49482
|
-
// src/domains/installation/merger/copy-executor.ts
|
|
49230
|
+
// src/services/file-operations/manifest/manifest-tracker.ts
|
|
49231
|
+
init_environment();
|
|
49483
49232
|
init_logger();
|
|
49484
|
-
|
|
49485
|
-
var import_fs_extra9 = __toESM(require_lib(), 1);
|
|
49486
|
-
var import_ignore2 = __toESM(require_ignore(), 1);
|
|
49487
|
-
import { dirname as dirname8, join as join27, relative as relative6 } from "node:path";
|
|
49488
|
-
|
|
49489
|
-
// src/domains/installation/selective-merger.ts
|
|
49490
|
-
import { stat as stat2 } from "node:fs/promises";
|
|
49491
|
-
|
|
49492
|
-
// src/services/file-operations/ownership-checker.ts
|
|
49493
|
-
import { createHash as createHash4 } from "node:crypto";
|
|
49494
|
-
import { createReadStream } from "node:fs";
|
|
49495
|
-
import { stat } from "node:fs/promises";
|
|
49496
|
-
import { relative as relative4 } from "node:path";
|
|
49233
|
+
import { join as join24 } from "node:path";
|
|
49497
49234
|
|
|
49498
49235
|
// node_modules/yocto-queue/index.js
|
|
49499
49236
|
class Node {
|
|
@@ -49584,26 +49321,26 @@ function pLimit(concurrency) {
|
|
|
49584
49321
|
activeCount--;
|
|
49585
49322
|
resumeNext();
|
|
49586
49323
|
};
|
|
49587
|
-
const run = async (function_,
|
|
49324
|
+
const run = async (function_, resolve3, arguments_) => {
|
|
49588
49325
|
const result = (async () => function_(...arguments_))();
|
|
49589
|
-
|
|
49326
|
+
resolve3(result);
|
|
49590
49327
|
try {
|
|
49591
49328
|
await result;
|
|
49592
49329
|
} catch {}
|
|
49593
49330
|
next();
|
|
49594
49331
|
};
|
|
49595
|
-
const enqueue = (function_,
|
|
49332
|
+
const enqueue = (function_, resolve3, reject, arguments_) => {
|
|
49596
49333
|
const queueItem = { reject };
|
|
49597
49334
|
new Promise((internalResolve) => {
|
|
49598
49335
|
queueItem.run = internalResolve;
|
|
49599
49336
|
queue.enqueue(queueItem);
|
|
49600
|
-
}).then(run.bind(undefined, function_,
|
|
49337
|
+
}).then(run.bind(undefined, function_, resolve3, arguments_));
|
|
49601
49338
|
if (activeCount < concurrency) {
|
|
49602
49339
|
resumeNext();
|
|
49603
49340
|
}
|
|
49604
49341
|
};
|
|
49605
|
-
const generator = (function_, ...arguments_) => new Promise((
|
|
49606
|
-
enqueue(function_,
|
|
49342
|
+
const generator = (function_, ...arguments_) => new Promise((resolve3, reject) => {
|
|
49343
|
+
enqueue(function_, resolve3, reject, arguments_);
|
|
49607
49344
|
});
|
|
49608
49345
|
Object.defineProperties(generator, {
|
|
49609
49346
|
activeCount: {
|
|
@@ -49651,6 +49388,12 @@ function validateConcurrency(concurrency) {
|
|
|
49651
49388
|
}
|
|
49652
49389
|
}
|
|
49653
49390
|
|
|
49391
|
+
// src/services/file-operations/ownership-checker.ts
|
|
49392
|
+
import { createHash as createHash4 } from "node:crypto";
|
|
49393
|
+
import { createReadStream } from "node:fs";
|
|
49394
|
+
import { stat } from "node:fs/promises";
|
|
49395
|
+
import { relative as relative3 } from "node:path";
|
|
49396
|
+
|
|
49654
49397
|
// src/shared/concurrent-file-ops.ts
|
|
49655
49398
|
var DEFAULT_CONCURRENCY = 50;
|
|
49656
49399
|
async function mapWithLimit(items, fn, concurrency = DEFAULT_CONCURRENCY) {
|
|
@@ -49661,12 +49404,12 @@ async function mapWithLimit(items, fn, concurrency = DEFAULT_CONCURRENCY) {
|
|
|
49661
49404
|
// src/services/file-operations/ownership-checker.ts
|
|
49662
49405
|
class OwnershipChecker {
|
|
49663
49406
|
static async calculateChecksum(filePath) {
|
|
49664
|
-
return new Promise((
|
|
49407
|
+
return new Promise((resolve3, reject) => {
|
|
49665
49408
|
const hash = createHash4("sha256");
|
|
49666
49409
|
const stream = createReadStream(filePath);
|
|
49667
49410
|
stream.on("data", (chunk) => hash.update(chunk));
|
|
49668
49411
|
stream.on("end", () => {
|
|
49669
|
-
|
|
49412
|
+
resolve3(hash.digest("hex"));
|
|
49670
49413
|
});
|
|
49671
49414
|
stream.on("error", (err) => {
|
|
49672
49415
|
stream.destroy();
|
|
@@ -49684,7 +49427,7 @@ class OwnershipChecker {
|
|
|
49684
49427
|
if (!metadata || allTrackedFiles.length === 0) {
|
|
49685
49428
|
return { path: filePath, ownership: "user", exists: true };
|
|
49686
49429
|
}
|
|
49687
|
-
const relativePath =
|
|
49430
|
+
const relativePath = relative3(claudeDir, filePath).replace(/\\/g, "/");
|
|
49688
49431
|
const tracked = allTrackedFiles.find((f3) => f3.path === relativePath);
|
|
49689
49432
|
if (!tracked) {
|
|
49690
49433
|
return { path: filePath, ownership: "user", exists: true };
|
|
@@ -49713,7 +49456,623 @@ class OwnershipChecker {
|
|
|
49713
49456
|
}
|
|
49714
49457
|
}
|
|
49715
49458
|
|
|
49459
|
+
// src/services/file-operations/manifest/manifest-updater.ts
|
|
49460
|
+
import { join as join23 } from "node:path";
|
|
49461
|
+
init_logger();
|
|
49462
|
+
init_types2();
|
|
49463
|
+
var import_fs_extra5 = __toESM(require_lib(), 1);
|
|
49464
|
+
var import_proper_lockfile4 = __toESM(require_proper_lockfile(), 1);
|
|
49465
|
+
async function writeManifest(providerRoot, kitName, version3, scope, kitType, trackedFiles, userConfigFiles) {
|
|
49466
|
+
const metadataPath = join23(providerRoot, "metadata.json");
|
|
49467
|
+
const kit = kitType || "engineer";
|
|
49468
|
+
await import_fs_extra5.ensureFile(metadataPath);
|
|
49469
|
+
let release = null;
|
|
49470
|
+
try {
|
|
49471
|
+
release = await import_proper_lockfile4.lock(metadataPath, {
|
|
49472
|
+
retries: { retries: 5, minTimeout: 100, maxTimeout: 1000 },
|
|
49473
|
+
stale: 60000
|
|
49474
|
+
});
|
|
49475
|
+
logger.debug(`Acquired lock on ${metadataPath}`);
|
|
49476
|
+
const migrationResult = await migrateToMultiKit(providerRoot);
|
|
49477
|
+
if (!migrationResult.success) {
|
|
49478
|
+
logger.warning(`Metadata migration warning: ${migrationResult.error}`);
|
|
49479
|
+
}
|
|
49480
|
+
let existingMetadata = { kits: {} };
|
|
49481
|
+
if (await import_fs_extra5.pathExists(metadataPath)) {
|
|
49482
|
+
try {
|
|
49483
|
+
const content = await import_fs_extra5.readFile(metadataPath, "utf-8");
|
|
49484
|
+
const parsed = JSON.parse(content);
|
|
49485
|
+
if (parsed && typeof parsed === "object" && Object.keys(parsed).length > 0) {
|
|
49486
|
+
existingMetadata = parsed;
|
|
49487
|
+
}
|
|
49488
|
+
} catch (error) {
|
|
49489
|
+
logger.debug(`Could not read existing metadata: ${error}`);
|
|
49490
|
+
}
|
|
49491
|
+
}
|
|
49492
|
+
const existingKits = existingMetadata.kits || {};
|
|
49493
|
+
const otherKitsExist = Object.keys(existingKits).some((k2) => k2 !== kit);
|
|
49494
|
+
const installedAt = new Date().toISOString();
|
|
49495
|
+
const existingKitMeta = existingKits[kit];
|
|
49496
|
+
const kitMetadata = {
|
|
49497
|
+
...existingKitMeta ?? {},
|
|
49498
|
+
version: version3,
|
|
49499
|
+
installedAt,
|
|
49500
|
+
installState: "complete",
|
|
49501
|
+
files: trackedFiles.length > 0 ? trackedFiles : undefined
|
|
49502
|
+
};
|
|
49503
|
+
const metadata = {
|
|
49504
|
+
kits: {
|
|
49505
|
+
...existingKits,
|
|
49506
|
+
[kit]: kitMetadata
|
|
49507
|
+
},
|
|
49508
|
+
scope,
|
|
49509
|
+
name: otherKitsExist ? existingMetadata.name ?? kitName : kitName,
|
|
49510
|
+
version: otherKitsExist ? existingMetadata.version ?? version3 : version3,
|
|
49511
|
+
installedAt: otherKitsExist ? existingMetadata.installedAt ?? installedAt : installedAt,
|
|
49512
|
+
userConfigFiles: [...USER_CONFIG_PATTERNS, ...userConfigFiles],
|
|
49513
|
+
...existingMetadata.telemetry_endpoint !== undefined && {
|
|
49514
|
+
telemetry_endpoint: existingMetadata.telemetry_endpoint
|
|
49515
|
+
},
|
|
49516
|
+
...existingMetadata.telemetry_token_placeholder !== undefined && {
|
|
49517
|
+
telemetry_token_placeholder: existingMetadata.telemetry_token_placeholder
|
|
49518
|
+
},
|
|
49519
|
+
...existingMetadata.deletions !== undefined && {
|
|
49520
|
+
deletions: existingMetadata.deletions
|
|
49521
|
+
}
|
|
49522
|
+
};
|
|
49523
|
+
const validated = MetadataSchema.parse(metadata);
|
|
49524
|
+
await import_fs_extra5.writeFile(metadataPath, JSON.stringify(validated, null, 2), "utf-8");
|
|
49525
|
+
logger.debug(`Wrote manifest for kit "${kit}" with ${trackedFiles.length} tracked files`);
|
|
49526
|
+
} finally {
|
|
49527
|
+
if (release) {
|
|
49528
|
+
await release();
|
|
49529
|
+
logger.debug(`Released lock on ${metadataPath}`);
|
|
49530
|
+
}
|
|
49531
|
+
}
|
|
49532
|
+
}
|
|
49533
|
+
async function writeKitPending(providerRoot, kit, version3, scope) {
|
|
49534
|
+
const metadataPath = join23(providerRoot, "metadata.json");
|
|
49535
|
+
await import_fs_extra5.ensureFile(metadataPath);
|
|
49536
|
+
let release = null;
|
|
49537
|
+
try {
|
|
49538
|
+
release = await import_proper_lockfile4.lock(metadataPath, {
|
|
49539
|
+
retries: { retries: 5, minTimeout: 100, maxTimeout: 1000 },
|
|
49540
|
+
stale: 60000
|
|
49541
|
+
});
|
|
49542
|
+
logger.debug(`Acquired lock on ${metadataPath} for pending-state write`);
|
|
49543
|
+
const migrationResult = await migrateToMultiKit(providerRoot);
|
|
49544
|
+
if (!migrationResult.success) {
|
|
49545
|
+
logger.warning(`Metadata migration warning: ${migrationResult.error}`);
|
|
49546
|
+
}
|
|
49547
|
+
let existingMetadata = { kits: {} };
|
|
49548
|
+
if (await import_fs_extra5.pathExists(metadataPath)) {
|
|
49549
|
+
try {
|
|
49550
|
+
const content = await import_fs_extra5.readFile(metadataPath, "utf-8");
|
|
49551
|
+
const parsed = JSON.parse(content);
|
|
49552
|
+
if (parsed && typeof parsed === "object" && Object.keys(parsed).length > 0) {
|
|
49553
|
+
existingMetadata = parsed;
|
|
49554
|
+
}
|
|
49555
|
+
} catch (error) {
|
|
49556
|
+
logger.debug(`Could not read existing metadata: ${error}`);
|
|
49557
|
+
}
|
|
49558
|
+
}
|
|
49559
|
+
const existingKits = existingMetadata.kits || {};
|
|
49560
|
+
const pendingMetadata = {
|
|
49561
|
+
version: version3,
|
|
49562
|
+
installedAt: new Date().toISOString(),
|
|
49563
|
+
installState: "pending",
|
|
49564
|
+
files: []
|
|
49565
|
+
};
|
|
49566
|
+
const metadata = {
|
|
49567
|
+
...existingMetadata,
|
|
49568
|
+
kits: {
|
|
49569
|
+
...existingKits,
|
|
49570
|
+
[kit]: pendingMetadata
|
|
49571
|
+
},
|
|
49572
|
+
scope
|
|
49573
|
+
};
|
|
49574
|
+
const validated = MetadataSchema.parse(metadata);
|
|
49575
|
+
await import_fs_extra5.writeFile(metadataPath, JSON.stringify(validated, null, 2), "utf-8");
|
|
49576
|
+
logger.debug(`Wrote pending-state entry for kit "${kit}"`);
|
|
49577
|
+
} finally {
|
|
49578
|
+
if (release) {
|
|
49579
|
+
await release();
|
|
49580
|
+
logger.debug(`Released lock on ${metadataPath}`);
|
|
49581
|
+
}
|
|
49582
|
+
}
|
|
49583
|
+
}
|
|
49584
|
+
async function findPendingKits(providerRoot) {
|
|
49585
|
+
const metadata = await readManifest(providerRoot);
|
|
49586
|
+
if (!metadata?.kits)
|
|
49587
|
+
return [];
|
|
49588
|
+
const pending = [];
|
|
49589
|
+
for (const [kitName, kitMeta] of Object.entries(metadata.kits)) {
|
|
49590
|
+
if (kitMeta?.installState === "pending") {
|
|
49591
|
+
pending.push(kitName);
|
|
49592
|
+
}
|
|
49593
|
+
}
|
|
49594
|
+
return pending;
|
|
49595
|
+
}
|
|
49596
|
+
async function removeKitFromManifest(providerRoot, kit) {
|
|
49597
|
+
const metadataPath = join23(providerRoot, "metadata.json");
|
|
49598
|
+
if (!await import_fs_extra5.pathExists(metadataPath))
|
|
49599
|
+
return false;
|
|
49600
|
+
let release = null;
|
|
49601
|
+
try {
|
|
49602
|
+
release = await import_proper_lockfile4.lock(metadataPath, {
|
|
49603
|
+
retries: { retries: 5, minTimeout: 100, maxTimeout: 1000 },
|
|
49604
|
+
stale: 60000
|
|
49605
|
+
});
|
|
49606
|
+
logger.debug(`Acquired lock on ${metadataPath} for kit removal`);
|
|
49607
|
+
const metadata = await readManifest(providerRoot);
|
|
49608
|
+
if (!metadata?.kits?.[kit])
|
|
49609
|
+
return false;
|
|
49610
|
+
const { [kit]: _removed, ...remainingKits } = metadata.kits;
|
|
49611
|
+
if (Object.keys(remainingKits).length === 0) {
|
|
49612
|
+
logger.debug("No kits remaining, metadata.json will be cleaned up");
|
|
49613
|
+
return true;
|
|
49614
|
+
}
|
|
49615
|
+
const updated = {
|
|
49616
|
+
...metadata,
|
|
49617
|
+
kits: remainingKits
|
|
49618
|
+
};
|
|
49619
|
+
await import_fs_extra5.writeFile(metadataPath, JSON.stringify(updated, null, 2), "utf-8");
|
|
49620
|
+
logger.debug(`Removed kit "${kit}" from metadata, ${Object.keys(remainingKits).length} kit(s) remaining`);
|
|
49621
|
+
return true;
|
|
49622
|
+
} finally {
|
|
49623
|
+
if (release) {
|
|
49624
|
+
await release();
|
|
49625
|
+
logger.debug(`Released lock on ${metadataPath}`);
|
|
49626
|
+
}
|
|
49627
|
+
}
|
|
49628
|
+
}
|
|
49629
|
+
|
|
49630
|
+
// src/services/file-operations/manifest/manifest-tracker.ts
|
|
49631
|
+
class ManifestTracker {
|
|
49632
|
+
installedFiles = new Set;
|
|
49633
|
+
userConfigFiles = new Set;
|
|
49634
|
+
trackedFiles = new Map;
|
|
49635
|
+
addInstalledFile(relativePath) {
|
|
49636
|
+
const normalized = relativePath.replace(/\\/g, "/");
|
|
49637
|
+
this.installedFiles.add(normalized);
|
|
49638
|
+
}
|
|
49639
|
+
addInstalledFiles(relativePaths) {
|
|
49640
|
+
for (const path3 of relativePaths) {
|
|
49641
|
+
this.addInstalledFile(path3);
|
|
49642
|
+
}
|
|
49643
|
+
}
|
|
49644
|
+
addUserConfigFile(relativePath) {
|
|
49645
|
+
const normalized = relativePath.replace(/\\/g, "/");
|
|
49646
|
+
this.userConfigFiles.add(normalized);
|
|
49647
|
+
}
|
|
49648
|
+
getInstalledFiles() {
|
|
49649
|
+
return Array.from(this.installedFiles).sort();
|
|
49650
|
+
}
|
|
49651
|
+
getUserConfigFiles() {
|
|
49652
|
+
return Array.from(this.userConfigFiles).sort();
|
|
49653
|
+
}
|
|
49654
|
+
async addTrackedFile(filePath, relativePath, ownership, installedVersion, sourceTimestamp) {
|
|
49655
|
+
const checksum = await OwnershipChecker.calculateChecksum(filePath);
|
|
49656
|
+
const normalized = relativePath.replace(/\\/g, "/");
|
|
49657
|
+
this.trackedFiles.set(normalized, {
|
|
49658
|
+
path: normalized,
|
|
49659
|
+
checksum,
|
|
49660
|
+
ownership,
|
|
49661
|
+
installedVersion,
|
|
49662
|
+
sourceTimestamp,
|
|
49663
|
+
installedAt: new Date().toISOString()
|
|
49664
|
+
});
|
|
49665
|
+
this.installedFiles.add(normalized);
|
|
49666
|
+
}
|
|
49667
|
+
async addTrackedFilesBatch(files, options2 = {}) {
|
|
49668
|
+
const { concurrency = 20, onProgress } = options2;
|
|
49669
|
+
const limit = pLimit(concurrency);
|
|
49670
|
+
const total = files.length;
|
|
49671
|
+
const tasks = files.map((file) => limit(async () => {
|
|
49672
|
+
try {
|
|
49673
|
+
const checksum = await OwnershipChecker.calculateChecksum(file.filePath);
|
|
49674
|
+
const normalized = file.relativePath.replace(/\\/g, "/");
|
|
49675
|
+
this.trackedFiles.set(normalized, {
|
|
49676
|
+
path: normalized,
|
|
49677
|
+
checksum,
|
|
49678
|
+
ownership: file.ownership,
|
|
49679
|
+
installedVersion: file.installedVersion,
|
|
49680
|
+
sourceTimestamp: file.sourceTimestamp,
|
|
49681
|
+
installedAt: new Date().toISOString()
|
|
49682
|
+
});
|
|
49683
|
+
this.installedFiles.add(normalized);
|
|
49684
|
+
return true;
|
|
49685
|
+
} catch (error) {
|
|
49686
|
+
logger.debug(`Failed to track file ${file.relativePath}: ${error}`);
|
|
49687
|
+
return false;
|
|
49688
|
+
}
|
|
49689
|
+
}));
|
|
49690
|
+
const progressInterval = Math.max(1, Math.floor(total / 20));
|
|
49691
|
+
let reportedProgress = 0;
|
|
49692
|
+
const results = await Promise.all(tasks.map(async (task, index) => {
|
|
49693
|
+
const result = await task;
|
|
49694
|
+
const completed = index + 1;
|
|
49695
|
+
if (completed % progressInterval === 0 || completed === total) {
|
|
49696
|
+
if (completed > reportedProgress) {
|
|
49697
|
+
reportedProgress = completed;
|
|
49698
|
+
onProgress?.(completed, total);
|
|
49699
|
+
}
|
|
49700
|
+
}
|
|
49701
|
+
return result;
|
|
49702
|
+
}));
|
|
49703
|
+
const success = results.filter(Boolean).length;
|
|
49704
|
+
const failed = total - success;
|
|
49705
|
+
if (failed > 0) {
|
|
49706
|
+
logger.warning(`Failed to track ${failed} of ${total} files (check debug logs for details)`);
|
|
49707
|
+
}
|
|
49708
|
+
return { success, failed, total };
|
|
49709
|
+
}
|
|
49710
|
+
getTrackedFiles() {
|
|
49711
|
+
return Array.from(this.trackedFiles.values()).sort((a3, b3) => a3.path.localeCompare(b3.path));
|
|
49712
|
+
}
|
|
49713
|
+
}
|
|
49714
|
+
function buildFileTrackingList(options2) {
|
|
49715
|
+
const {
|
|
49716
|
+
installedFiles,
|
|
49717
|
+
providerRoot,
|
|
49718
|
+
ownershipResolver,
|
|
49719
|
+
installedVersion,
|
|
49720
|
+
isGlobal = false
|
|
49721
|
+
} = options2;
|
|
49722
|
+
const filesToTrack = [];
|
|
49723
|
+
for (const installedPath of installedFiles) {
|
|
49724
|
+
if (!isGlobal && installedPath.startsWith(".claude/")) {
|
|
49725
|
+
const relativePath2 = installedPath.replace(/^\.claude\//, "");
|
|
49726
|
+
const filePath2 = join24(providerRoot, relativePath2);
|
|
49727
|
+
const { ownership: ownership2, sourceTimestamp: sourceTimestamp2 } = ownershipResolver(installedPath);
|
|
49728
|
+
filesToTrack.push({
|
|
49729
|
+
filePath: filePath2,
|
|
49730
|
+
relativePath: relativePath2,
|
|
49731
|
+
ownership: ownership2,
|
|
49732
|
+
installedVersion,
|
|
49733
|
+
sourceTimestamp: sourceTimestamp2
|
|
49734
|
+
});
|
|
49735
|
+
continue;
|
|
49736
|
+
}
|
|
49737
|
+
if (!isGlobal && !installedPath.startsWith(".claude/")) {
|
|
49738
|
+
continue;
|
|
49739
|
+
}
|
|
49740
|
+
const relativePath = installedPath;
|
|
49741
|
+
const filePath = join24(providerRoot, relativePath);
|
|
49742
|
+
const { ownership, sourceTimestamp } = ownershipResolver(installedPath);
|
|
49743
|
+
filesToTrack.push({
|
|
49744
|
+
filePath,
|
|
49745
|
+
relativePath,
|
|
49746
|
+
ownership,
|
|
49747
|
+
installedVersion,
|
|
49748
|
+
sourceTimestamp
|
|
49749
|
+
});
|
|
49750
|
+
}
|
|
49751
|
+
return filesToTrack;
|
|
49752
|
+
}
|
|
49753
|
+
async function trackFilesWithProgress(filesToTrack, manifestOptions) {
|
|
49754
|
+
const tracker = new ManifestTracker;
|
|
49755
|
+
const trackingSpinner = createSpinner(`Tracking ${filesToTrack.length} installed files...`);
|
|
49756
|
+
trackingSpinner.start();
|
|
49757
|
+
const trackResult = await tracker.addTrackedFilesBatch(filesToTrack, {
|
|
49758
|
+
concurrency: getOptimalConcurrency(),
|
|
49759
|
+
onProgress: (processed, total) => {
|
|
49760
|
+
trackingSpinner.text = `Tracking files... (${processed}/${total})`;
|
|
49761
|
+
}
|
|
49762
|
+
});
|
|
49763
|
+
trackingSpinner.succeed(`Tracked ${trackResult.success} files`);
|
|
49764
|
+
await writeManifest(manifestOptions.providerRoot, manifestOptions.kitName, manifestOptions.releaseTag, manifestOptions.mode, manifestOptions.kitType, tracker.getTrackedFiles(), tracker.getUserConfigFiles());
|
|
49765
|
+
return trackResult;
|
|
49766
|
+
}
|
|
49767
|
+
// src/services/file-operations/manifest-writer.ts
|
|
49768
|
+
class ManifestWriter {
|
|
49769
|
+
tracker = new ManifestTracker;
|
|
49770
|
+
addInstalledFile(relativePath) {
|
|
49771
|
+
this.tracker.addInstalledFile(relativePath);
|
|
49772
|
+
}
|
|
49773
|
+
addInstalledFiles(relativePaths) {
|
|
49774
|
+
this.tracker.addInstalledFiles(relativePaths);
|
|
49775
|
+
}
|
|
49776
|
+
addUserConfigFile(relativePath) {
|
|
49777
|
+
this.tracker.addUserConfigFile(relativePath);
|
|
49778
|
+
}
|
|
49779
|
+
getInstalledFiles() {
|
|
49780
|
+
return this.tracker.getInstalledFiles();
|
|
49781
|
+
}
|
|
49782
|
+
getUserConfigFiles() {
|
|
49783
|
+
return this.tracker.getUserConfigFiles();
|
|
49784
|
+
}
|
|
49785
|
+
async addTrackedFile(filePath, relativePath, ownership, installedVersion, sourceTimestamp) {
|
|
49786
|
+
return this.tracker.addTrackedFile(filePath, relativePath, ownership, installedVersion, sourceTimestamp);
|
|
49787
|
+
}
|
|
49788
|
+
async addTrackedFilesBatch(files, options2 = {}) {
|
|
49789
|
+
return this.tracker.addTrackedFilesBatch(files, options2);
|
|
49790
|
+
}
|
|
49791
|
+
getTrackedFiles() {
|
|
49792
|
+
return this.tracker.getTrackedFiles();
|
|
49793
|
+
}
|
|
49794
|
+
async writeManifest(providerRoot, kitName, version3, scope, kitType) {
|
|
49795
|
+
return writeManifest(providerRoot, kitName, version3, scope, kitType, this.getTrackedFiles(), this.getUserConfigFiles());
|
|
49796
|
+
}
|
|
49797
|
+
static async writeKitPending(providerRoot, kit, version3, scope) {
|
|
49798
|
+
return writeKitPending(providerRoot, kit, version3, scope);
|
|
49799
|
+
}
|
|
49800
|
+
static async findPendingKits(providerRoot) {
|
|
49801
|
+
return findPendingKits(providerRoot);
|
|
49802
|
+
}
|
|
49803
|
+
static async readManifest(providerRoot) {
|
|
49804
|
+
return readManifest(providerRoot);
|
|
49805
|
+
}
|
|
49806
|
+
static async readKitManifest(providerRoot, kit) {
|
|
49807
|
+
return readKitManifest(providerRoot, kit);
|
|
49808
|
+
}
|
|
49809
|
+
static async getUninstallManifest(providerRoot, kit) {
|
|
49810
|
+
return getUninstallManifest(providerRoot, kit);
|
|
49811
|
+
}
|
|
49812
|
+
static async removeKitFromManifest(providerRoot, kit) {
|
|
49813
|
+
return removeKitFromManifest(providerRoot, kit);
|
|
49814
|
+
}
|
|
49815
|
+
}
|
|
49816
|
+
|
|
49817
|
+
// src/domains/installers/claude-code/installer.ts
|
|
49818
|
+
init_logger();
|
|
49819
|
+
init_path_resolver();
|
|
49820
|
+
|
|
49821
|
+
// src/domains/installers/claude-code/conflict-handler.ts
|
|
49822
|
+
init_logger();
|
|
49823
|
+
var import_fs_extra6 = __toESM(require_lib(), 1);
|
|
49824
|
+
import { join as join25 } from "node:path";
|
|
49825
|
+
async function handleConflicts(ctx) {
|
|
49826
|
+
if (ctx.cancelled)
|
|
49827
|
+
return ctx;
|
|
49828
|
+
if (!ctx.options.global)
|
|
49829
|
+
return ctx;
|
|
49830
|
+
if (isLocalSameAsGlobal()) {
|
|
49831
|
+
return ctx;
|
|
49832
|
+
}
|
|
49833
|
+
const localSettingsPath = join25(process.cwd(), ".claude", "settings.json");
|
|
49834
|
+
if (!await import_fs_extra6.pathExists(localSettingsPath)) {
|
|
49835
|
+
return ctx;
|
|
49836
|
+
}
|
|
49837
|
+
if (ctx.isNonInteractive) {
|
|
49838
|
+
logger.warning("Local .claude/settings.json detected. Local settings take precedence over global.");
|
|
49839
|
+
logger.warning("Consider removing local installation: rm -rf .claude");
|
|
49840
|
+
return ctx;
|
|
49841
|
+
}
|
|
49842
|
+
const choice = await ctx.prompts.promptLocalMigration();
|
|
49843
|
+
if (choice === "cancel") {
|
|
49844
|
+
ctx.prompts.outro("Installation cancelled.");
|
|
49845
|
+
return { ...ctx, cancelled: true };
|
|
49846
|
+
}
|
|
49847
|
+
if (choice === "remove") {
|
|
49848
|
+
const localClaudeDir = join25(process.cwd(), ".claude");
|
|
49849
|
+
try {
|
|
49850
|
+
await import_fs_extra6.remove(localClaudeDir);
|
|
49851
|
+
logger.success("Removed local .claude/ directory");
|
|
49852
|
+
} catch (error) {
|
|
49853
|
+
logger.error(`Failed to remove local installation: ${error instanceof Error ? error.message : "Unknown error"}`);
|
|
49854
|
+
logger.warning("Proceeding with global installation anyway.");
|
|
49855
|
+
}
|
|
49856
|
+
}
|
|
49857
|
+
if (choice === "keep") {
|
|
49858
|
+
logger.warning("Proceeding with global installation. Local settings will take precedence.");
|
|
49859
|
+
}
|
|
49860
|
+
return ctx;
|
|
49861
|
+
}
|
|
49862
|
+
|
|
49863
|
+
// src/domains/installers/claude-code/merge-handler.ts
|
|
49864
|
+
import { join as join37 } from "node:path";
|
|
49865
|
+
|
|
49866
|
+
// src/domains/installation/deletion-handler.ts
|
|
49867
|
+
import { existsSync as existsSync13, lstatSync, readdirSync as readdirSync2, rmSync, rmdirSync, unlinkSync } from "node:fs";
|
|
49868
|
+
import { dirname as dirname6, join as join26, relative as relative4, resolve as resolve3, sep as sep2 } from "node:path";
|
|
49869
|
+
init_logger();
|
|
49870
|
+
init_path_resolver();
|
|
49871
|
+
var import_fs_extra7 = __toESM(require_lib(), 1);
|
|
49872
|
+
var import_picomatch = __toESM(require_picomatch2(), 1);
|
|
49873
|
+
function findFileInMetadata(metadata, path3) {
|
|
49874
|
+
if (!metadata)
|
|
49875
|
+
return { tracked: null, ownerKit: null };
|
|
49876
|
+
if (metadata.kits) {
|
|
49877
|
+
for (const [kitName, kitMeta] of Object.entries(metadata.kits)) {
|
|
49878
|
+
if (!kitMeta?.files)
|
|
49879
|
+
continue;
|
|
49880
|
+
const found = kitMeta.files.find((f3) => f3.path === path3);
|
|
49881
|
+
if (found)
|
|
49882
|
+
return { tracked: found, ownerKit: kitName };
|
|
49883
|
+
}
|
|
49884
|
+
}
|
|
49885
|
+
if (metadata.files) {
|
|
49886
|
+
const found = metadata.files.find((f3) => f3.path === path3);
|
|
49887
|
+
if (found)
|
|
49888
|
+
return { tracked: found, ownerKit: null };
|
|
49889
|
+
}
|
|
49890
|
+
return { tracked: null, ownerKit: null };
|
|
49891
|
+
}
|
|
49892
|
+
function shouldDeletePath(path3, metadata, installingKit) {
|
|
49893
|
+
const { tracked, ownerKit } = findFileInMetadata(metadata, path3);
|
|
49894
|
+
if (!tracked)
|
|
49895
|
+
return true;
|
|
49896
|
+
if (tracked.ownership === "user")
|
|
49897
|
+
return false;
|
|
49898
|
+
if (installingKit && ownerKit && ownerKit !== installingKit)
|
|
49899
|
+
return false;
|
|
49900
|
+
return true;
|
|
49901
|
+
}
|
|
49902
|
+
function collectFilesRecursively(dir, baseDir) {
|
|
49903
|
+
const results = [];
|
|
49904
|
+
if (!existsSync13(dir))
|
|
49905
|
+
return results;
|
|
49906
|
+
try {
|
|
49907
|
+
const entries = readdirSync2(dir, { withFileTypes: true });
|
|
49908
|
+
for (const entry of entries) {
|
|
49909
|
+
const fullPath = join26(dir, entry.name);
|
|
49910
|
+
const relativePath = relative4(baseDir, fullPath);
|
|
49911
|
+
if (entry.isDirectory()) {
|
|
49912
|
+
results.push(...collectFilesRecursively(fullPath, baseDir));
|
|
49913
|
+
} else {
|
|
49914
|
+
results.push(relativePath);
|
|
49915
|
+
}
|
|
49916
|
+
}
|
|
49917
|
+
} catch {}
|
|
49918
|
+
return results;
|
|
49919
|
+
}
|
|
49920
|
+
function expandGlobPatterns(patterns, claudeDir) {
|
|
49921
|
+
const expanded = [];
|
|
49922
|
+
const allFiles = collectFilesRecursively(claudeDir, claudeDir);
|
|
49923
|
+
for (const pattern of patterns) {
|
|
49924
|
+
if (PathResolver.isGlobPattern(pattern)) {
|
|
49925
|
+
const matcher = import_picomatch.default(pattern);
|
|
49926
|
+
const matches = allFiles.filter((file) => matcher(file));
|
|
49927
|
+
expanded.push(...matches);
|
|
49928
|
+
if (matches.length > 0) {
|
|
49929
|
+
logger.debug(`Pattern "${pattern}" matched ${matches.length} files`);
|
|
49930
|
+
}
|
|
49931
|
+
} else {
|
|
49932
|
+
expanded.push(pattern);
|
|
49933
|
+
}
|
|
49934
|
+
}
|
|
49935
|
+
return [...new Set(expanded)];
|
|
49936
|
+
}
|
|
49937
|
+
var MAX_CLEANUP_ITERATIONS = 50;
|
|
49938
|
+
function cleanupEmptyDirectories(filePath, claudeDir) {
|
|
49939
|
+
const normalizedClaudeDir = resolve3(claudeDir);
|
|
49940
|
+
let currentDir = resolve3(dirname6(filePath));
|
|
49941
|
+
let iterations = 0;
|
|
49942
|
+
while (currentDir !== normalizedClaudeDir && currentDir.startsWith(normalizedClaudeDir) && iterations < MAX_CLEANUP_ITERATIONS) {
|
|
49943
|
+
iterations++;
|
|
49944
|
+
try {
|
|
49945
|
+
const entries = readdirSync2(currentDir);
|
|
49946
|
+
if (entries.length === 0) {
|
|
49947
|
+
rmdirSync(currentDir);
|
|
49948
|
+
logger.debug(`Removed empty directory: ${currentDir}`);
|
|
49949
|
+
currentDir = resolve3(dirname6(currentDir));
|
|
49950
|
+
} else {
|
|
49951
|
+
break;
|
|
49952
|
+
}
|
|
49953
|
+
} catch {
|
|
49954
|
+
break;
|
|
49955
|
+
}
|
|
49956
|
+
}
|
|
49957
|
+
}
|
|
49958
|
+
function deletePath(fullPath, claudeDir) {
|
|
49959
|
+
const normalizedPath = resolve3(fullPath);
|
|
49960
|
+
const normalizedClaudeDir = resolve3(claudeDir);
|
|
49961
|
+
if (!normalizedPath.startsWith(`${normalizedClaudeDir}${sep2}`) && normalizedPath !== normalizedClaudeDir) {
|
|
49962
|
+
throw new Error(`Path traversal detected: ${fullPath}`);
|
|
49963
|
+
}
|
|
49964
|
+
try {
|
|
49965
|
+
const stat2 = lstatSync(fullPath);
|
|
49966
|
+
if (stat2.isDirectory()) {
|
|
49967
|
+
rmSync(fullPath, { recursive: true, force: true });
|
|
49968
|
+
} else {
|
|
49969
|
+
unlinkSync(fullPath);
|
|
49970
|
+
cleanupEmptyDirectories(fullPath, claudeDir);
|
|
49971
|
+
}
|
|
49972
|
+
} catch (error) {
|
|
49973
|
+
throw new Error(`Failed to delete ${fullPath}: ${error instanceof Error ? error.message : String(error)}`);
|
|
49974
|
+
}
|
|
49975
|
+
}
|
|
49976
|
+
async function updateMetadataAfterDeletion(claudeDir, deletedPaths) {
|
|
49977
|
+
const metadataPath = join26(claudeDir, "metadata.json");
|
|
49978
|
+
if (!await import_fs_extra7.pathExists(metadataPath)) {
|
|
49979
|
+
return;
|
|
49980
|
+
}
|
|
49981
|
+
let content;
|
|
49982
|
+
try {
|
|
49983
|
+
content = await import_fs_extra7.readFile(metadataPath, "utf-8");
|
|
49984
|
+
} catch {
|
|
49985
|
+
logger.debug("Failed to read metadata.json for cleanup");
|
|
49986
|
+
return;
|
|
49987
|
+
}
|
|
49988
|
+
let metadata;
|
|
49989
|
+
try {
|
|
49990
|
+
metadata = JSON.parse(content);
|
|
49991
|
+
} catch {
|
|
49992
|
+
logger.debug("Failed to parse metadata.json for cleanup");
|
|
49993
|
+
return;
|
|
49994
|
+
}
|
|
49995
|
+
const deletedSet = new Set(deletedPaths);
|
|
49996
|
+
const isDeletedOrInDeletedDir = (path3) => {
|
|
49997
|
+
if (deletedSet.has(path3))
|
|
49998
|
+
return true;
|
|
49999
|
+
for (const deleted of deletedPaths) {
|
|
50000
|
+
if (path3.startsWith(`${deleted}/`))
|
|
50001
|
+
return true;
|
|
50002
|
+
}
|
|
50003
|
+
return false;
|
|
50004
|
+
};
|
|
50005
|
+
if (metadata.kits) {
|
|
50006
|
+
for (const kitName of Object.keys(metadata.kits)) {
|
|
50007
|
+
const kit = metadata.kits[kitName];
|
|
50008
|
+
if (kit?.files) {
|
|
50009
|
+
kit.files = kit.files.filter((f3) => !isDeletedOrInDeletedDir(f3.path));
|
|
50010
|
+
}
|
|
50011
|
+
}
|
|
50012
|
+
}
|
|
50013
|
+
if (metadata.files) {
|
|
50014
|
+
metadata.files = metadata.files.filter((f3) => !isDeletedOrInDeletedDir(f3.path));
|
|
50015
|
+
}
|
|
50016
|
+
try {
|
|
50017
|
+
await import_fs_extra7.writeFile(metadataPath, JSON.stringify(metadata, null, 2));
|
|
50018
|
+
logger.debug(`Updated metadata.json, removed ${deletedPaths.length} entries`);
|
|
50019
|
+
} catch {
|
|
50020
|
+
logger.debug("Failed to write updated metadata.json");
|
|
50021
|
+
}
|
|
50022
|
+
}
|
|
50023
|
+
async function handleDeletions(sourceMetadata, claudeDir, installingKit) {
|
|
50024
|
+
const deletionPatterns = sourceMetadata.deletions || [];
|
|
50025
|
+
if (deletionPatterns.length === 0) {
|
|
50026
|
+
return { deletedPaths: [], preservedPaths: [], errors: [] };
|
|
50027
|
+
}
|
|
50028
|
+
const deletions = expandGlobPatterns(deletionPatterns, claudeDir);
|
|
50029
|
+
const userMetadata = await readManifest(claudeDir);
|
|
50030
|
+
const result = { deletedPaths: [], preservedPaths: [], errors: [] };
|
|
50031
|
+
for (const path3 of deletions) {
|
|
50032
|
+
const fullPath = join26(claudeDir, path3);
|
|
50033
|
+
const normalizedPath = resolve3(fullPath);
|
|
50034
|
+
const normalizedClaudeDir = resolve3(claudeDir);
|
|
50035
|
+
if (!normalizedPath.startsWith(`${normalizedClaudeDir}${sep2}`)) {
|
|
50036
|
+
logger.warning(`Skipping invalid path: ${path3}`);
|
|
50037
|
+
result.errors.push(path3);
|
|
50038
|
+
continue;
|
|
50039
|
+
}
|
|
50040
|
+
if (!shouldDeletePath(path3, userMetadata, installingKit)) {
|
|
50041
|
+
result.preservedPaths.push(path3);
|
|
50042
|
+
logger.verbose(`Preserved file (cross-kit or user-owned): ${path3}`);
|
|
50043
|
+
continue;
|
|
50044
|
+
}
|
|
50045
|
+
if (existsSync13(fullPath)) {
|
|
50046
|
+
try {
|
|
50047
|
+
deletePath(fullPath, claudeDir);
|
|
50048
|
+
result.deletedPaths.push(path3);
|
|
50049
|
+
logger.verbose(`Deleted: ${path3}`);
|
|
50050
|
+
} catch (error) {
|
|
50051
|
+
result.errors.push(path3);
|
|
50052
|
+
logger.debug(`Failed to delete ${path3}: ${error}`);
|
|
50053
|
+
}
|
|
50054
|
+
}
|
|
50055
|
+
}
|
|
50056
|
+
if (result.deletedPaths.length > 0) {
|
|
50057
|
+
await updateMetadataAfterDeletion(claudeDir, result.deletedPaths);
|
|
50058
|
+
}
|
|
50059
|
+
return result;
|
|
50060
|
+
}
|
|
50061
|
+
|
|
50062
|
+
// src/domains/installation/file-merger.ts
|
|
50063
|
+
init_logger();
|
|
50064
|
+
init_types2();
|
|
50065
|
+
init_dist2();
|
|
50066
|
+
|
|
50067
|
+
// src/domains/installation/merger/copy-executor.ts
|
|
50068
|
+
init_logger();
|
|
50069
|
+
init_types2();
|
|
50070
|
+
var import_fs_extra10 = __toESM(require_lib(), 1);
|
|
50071
|
+
var import_ignore2 = __toESM(require_ignore(), 1);
|
|
50072
|
+
import { dirname as dirname8, join as join29, relative as relative6 } from "node:path";
|
|
50073
|
+
|
|
49716
50074
|
// src/domains/installation/selective-merger.ts
|
|
50075
|
+
import { stat as stat2 } from "node:fs/promises";
|
|
49717
50076
|
init_logger();
|
|
49718
50077
|
var import_semver = __toESM(require_semver2(), 1);
|
|
49719
50078
|
|
|
@@ -49886,10 +50245,10 @@ class SelectiveMerger {
|
|
|
49886
50245
|
|
|
49887
50246
|
// src/domains/installation/merger/file-scanner.ts
|
|
49888
50247
|
init_logger();
|
|
49889
|
-
var
|
|
50248
|
+
var import_fs_extra8 = __toESM(require_lib(), 1);
|
|
49890
50249
|
var import_ignore = __toESM(require_ignore(), 1);
|
|
49891
50250
|
import { relative as relative5 } from "node:path";
|
|
49892
|
-
import { join as
|
|
50251
|
+
import { join as join27 } from "node:path";
|
|
49893
50252
|
|
|
49894
50253
|
// node_modules/balanced-match/dist/esm/index.js
|
|
49895
50254
|
var balanced = (a3, b3, str2) => {
|
|
@@ -51588,12 +51947,12 @@ class FileScanner {
|
|
|
51588
51947
|
}
|
|
51589
51948
|
async getFiles(dir, baseDir = dir) {
|
|
51590
51949
|
const files = [];
|
|
51591
|
-
const entries = await
|
|
51950
|
+
const entries = await import_fs_extra8.readdir(dir, { encoding: "utf8" });
|
|
51592
51951
|
for (const entry of entries) {
|
|
51593
|
-
const fullPath =
|
|
51952
|
+
const fullPath = join27(dir, entry);
|
|
51594
51953
|
const relativePath = relative5(baseDir, fullPath);
|
|
51595
51954
|
const normalizedRelativePath = relativePath.replace(/\\/g, "/");
|
|
51596
|
-
const stats = await
|
|
51955
|
+
const stats = await import_fs_extra8.lstat(fullPath);
|
|
51597
51956
|
if (stats.isSymbolicLink()) {
|
|
51598
51957
|
logger.warning(`Skipping symbolic link: ${normalizedRelativePath}`);
|
|
51599
51958
|
continue;
|
|
@@ -51628,8 +51987,8 @@ import { execSync } from "node:child_process";
|
|
|
51628
51987
|
|
|
51629
51988
|
// src/domains/config/installed-settings-tracker.ts
|
|
51630
51989
|
import { existsSync as existsSync14 } from "node:fs";
|
|
51631
|
-
import { mkdir as mkdir6, readFile as
|
|
51632
|
-
import { dirname as dirname7, join as
|
|
51990
|
+
import { mkdir as mkdir6, readFile as readFile14, writeFile as writeFile12 } from "node:fs/promises";
|
|
51991
|
+
import { dirname as dirname7, join as join28 } from "node:path";
|
|
51633
51992
|
var TAKUMI_JSON_FILE = ".takumi.json";
|
|
51634
51993
|
|
|
51635
51994
|
class InstalledSettingsTracker {
|
|
@@ -51643,9 +52002,9 @@ class InstalledSettingsTracker {
|
|
|
51643
52002
|
}
|
|
51644
52003
|
getCkJsonPath() {
|
|
51645
52004
|
if (this.isGlobal) {
|
|
51646
|
-
return
|
|
52005
|
+
return join28(this.projectDir, TAKUMI_JSON_FILE);
|
|
51647
52006
|
}
|
|
51648
|
-
return
|
|
52007
|
+
return join28(this.projectDir, ".claude", TAKUMI_JSON_FILE);
|
|
51649
52008
|
}
|
|
51650
52009
|
async loadInstalledSettings() {
|
|
51651
52010
|
const ckJsonPath = this.getCkJsonPath();
|
|
@@ -51653,7 +52012,7 @@ class InstalledSettingsTracker {
|
|
|
51653
52012
|
return { hooks: [], mcpServers: [] };
|
|
51654
52013
|
}
|
|
51655
52014
|
try {
|
|
51656
|
-
const content = await
|
|
52015
|
+
const content = await readFile14(ckJsonPath, "utf-8");
|
|
51657
52016
|
const data = JSON.parse(content);
|
|
51658
52017
|
const installed = data.kits?.[this.kitName]?.installedSettings;
|
|
51659
52018
|
if (installed) {
|
|
@@ -51670,7 +52029,7 @@ class InstalledSettingsTracker {
|
|
|
51670
52029
|
try {
|
|
51671
52030
|
let data = {};
|
|
51672
52031
|
if (existsSync14(ckJsonPath)) {
|
|
51673
|
-
const content = await
|
|
52032
|
+
const content = await readFile14(ckJsonPath, "utf-8");
|
|
51674
52033
|
data = JSON.parse(content);
|
|
51675
52034
|
}
|
|
51676
52035
|
if (!data.kits) {
|
|
@@ -51681,7 +52040,7 @@ class InstalledSettingsTracker {
|
|
|
51681
52040
|
}
|
|
51682
52041
|
data.kits[this.kitName].installedSettings = settings;
|
|
51683
52042
|
await mkdir6(dirname7(ckJsonPath), { recursive: true });
|
|
51684
|
-
await
|
|
52043
|
+
await writeFile12(ckJsonPath, JSON.stringify(data, null, 2), "utf-8");
|
|
51685
52044
|
logger.debug(`Saved installed settings to ${ckJsonPath}`);
|
|
51686
52045
|
} catch (error) {
|
|
51687
52046
|
logger.warning(`Failed to save installed settings: ${error instanceof Error ? error.message : "Unknown error"}`);
|
|
@@ -51720,7 +52079,7 @@ class InstalledSettingsTracker {
|
|
|
51720
52079
|
|
|
51721
52080
|
// src/domains/installation/merger/settings-processor.ts
|
|
51722
52081
|
init_logger();
|
|
51723
|
-
var
|
|
52082
|
+
var import_fs_extra9 = __toESM(require_lib(), 1);
|
|
51724
52083
|
var import_semver2 = __toESM(require_semver2(), 1);
|
|
51725
52084
|
|
|
51726
52085
|
class SettingsProcessor {
|
|
@@ -51760,7 +52119,7 @@ class SettingsProcessor {
|
|
|
51760
52119
|
}
|
|
51761
52120
|
async processSettingsJson(sourceFile, destFile) {
|
|
51762
52121
|
try {
|
|
51763
|
-
const sourceContent = await
|
|
52122
|
+
const sourceContent = await import_fs_extra9.readFile(sourceFile, "utf-8");
|
|
51764
52123
|
let transformedSource = sourceContent;
|
|
51765
52124
|
if (this.isGlobal) {
|
|
51766
52125
|
const homeVar = '"$HOME"';
|
|
@@ -51774,7 +52133,7 @@ class SettingsProcessor {
|
|
|
51774
52133
|
logger.debug("Transformed paths to $CLAUDE_PROJECT_DIR/.claude/ in settings.json for local installation");
|
|
51775
52134
|
}
|
|
51776
52135
|
}
|
|
51777
|
-
const destExists = await
|
|
52136
|
+
const destExists = await import_fs_extra9.pathExists(destFile);
|
|
51778
52137
|
if (destExists && !this.forceOverwriteSettings) {
|
|
51779
52138
|
await this.selectiveMergeSettings(transformedSource, destFile);
|
|
51780
52139
|
} else {
|
|
@@ -51795,13 +52154,13 @@ class SettingsProcessor {
|
|
|
51795
52154
|
}
|
|
51796
52155
|
} catch {
|
|
51797
52156
|
const formattedContent = this.formatJsonContent(transformedSource);
|
|
51798
|
-
await
|
|
52157
|
+
await import_fs_extra9.writeFile(destFile, formattedContent, "utf-8");
|
|
51799
52158
|
}
|
|
51800
52159
|
await this.injectTeamHooksIfSupported(destFile);
|
|
51801
52160
|
}
|
|
51802
52161
|
} catch (error) {
|
|
51803
52162
|
logger.error(`Failed to process settings.json: ${error}`);
|
|
51804
|
-
await
|
|
52163
|
+
await import_fs_extra9.copy(sourceFile, destFile, { overwrite: true });
|
|
51805
52164
|
}
|
|
51806
52165
|
}
|
|
51807
52166
|
async selectiveMergeSettings(transformedSourceContent, destFile) {
|
|
@@ -51811,7 +52170,7 @@ class SettingsProcessor {
|
|
|
51811
52170
|
} catch {
|
|
51812
52171
|
logger.warning("Failed to parse source settings.json, falling back to overwrite");
|
|
51813
52172
|
const formattedContent = this.formatJsonContent(transformedSourceContent);
|
|
51814
|
-
await
|
|
52173
|
+
await import_fs_extra9.writeFile(destFile, formattedContent, "utf-8");
|
|
51815
52174
|
return;
|
|
51816
52175
|
}
|
|
51817
52176
|
let destSettings;
|
|
@@ -52003,7 +52362,7 @@ class SettingsProcessor {
|
|
|
52003
52362
|
}
|
|
52004
52363
|
async readAndNormalizeGlobalSettings(destFile) {
|
|
52005
52364
|
try {
|
|
52006
|
-
const content = await
|
|
52365
|
+
const content = await import_fs_extra9.readFile(destFile, "utf-8");
|
|
52007
52366
|
if (!content.trim())
|
|
52008
52367
|
return null;
|
|
52009
52368
|
const homeVar = "$HOME";
|
|
@@ -52289,8 +52648,8 @@ class CopyExecutor {
|
|
|
52289
52648
|
for (const file of files) {
|
|
52290
52649
|
const relativePath = relative6(sourceDir, file);
|
|
52291
52650
|
const normalizedRelativePath = relativePath.replace(/\\/g, "/");
|
|
52292
|
-
const destPath =
|
|
52293
|
-
if (await
|
|
52651
|
+
const destPath = join29(destDir, relativePath);
|
|
52652
|
+
if (await import_fs_extra10.pathExists(destPath)) {
|
|
52294
52653
|
if (this.fileScanner.shouldNeverCopy(normalizedRelativePath)) {
|
|
52295
52654
|
logger.debug(`Security-sensitive file exists but won't be overwritten: ${normalizedRelativePath}`);
|
|
52296
52655
|
continue;
|
|
@@ -52311,14 +52670,14 @@ class CopyExecutor {
|
|
|
52311
52670
|
for (const file of files) {
|
|
52312
52671
|
const relativePath = relative6(sourceDir, file);
|
|
52313
52672
|
const normalizedRelativePath = relativePath.replace(/\\/g, "/");
|
|
52314
|
-
const destPath =
|
|
52673
|
+
const destPath = join29(destDir, relativePath);
|
|
52315
52674
|
if (this.fileScanner.shouldNeverCopy(normalizedRelativePath)) {
|
|
52316
52675
|
logger.debug(`Skipping security-sensitive file: ${normalizedRelativePath}`);
|
|
52317
52676
|
skippedCount++;
|
|
52318
52677
|
continue;
|
|
52319
52678
|
}
|
|
52320
52679
|
if (this.userConfigChecker.ignores(normalizedRelativePath)) {
|
|
52321
|
-
const fileExists = await
|
|
52680
|
+
const fileExists = await import_fs_extra10.pathExists(destPath);
|
|
52322
52681
|
if (fileExists) {
|
|
52323
52682
|
logger.debug(`Preserving user config: ${normalizedRelativePath}`);
|
|
52324
52683
|
skippedCount++;
|
|
@@ -52349,7 +52708,7 @@ class CopyExecutor {
|
|
|
52349
52708
|
continue;
|
|
52350
52709
|
}
|
|
52351
52710
|
}
|
|
52352
|
-
await withRetry(() =>
|
|
52711
|
+
await withRetry(() => import_fs_extra10.copy(file, destPath, { overwrite: true }));
|
|
52353
52712
|
this.trackInstalledFile(normalizedRelativePath);
|
|
52354
52713
|
copiedCount++;
|
|
52355
52714
|
}
|
|
@@ -52485,370 +52844,6 @@ class FileMerger {
|
|
|
52485
52844
|
// src/domains/migration/legacy-migration.ts
|
|
52486
52845
|
import { readdir as readdir4, stat as stat3 } from "node:fs/promises";
|
|
52487
52846
|
import { join as join31, relative as relative7 } from "node:path";
|
|
52488
|
-
// src/services/file-operations/manifest/manifest-tracker.ts
|
|
52489
|
-
init_environment();
|
|
52490
|
-
init_logger();
|
|
52491
|
-
import { join as join29 } from "node:path";
|
|
52492
|
-
|
|
52493
|
-
// src/services/file-operations/manifest/manifest-updater.ts
|
|
52494
|
-
import { join as join28 } from "node:path";
|
|
52495
|
-
init_logger();
|
|
52496
|
-
init_types2();
|
|
52497
|
-
var import_fs_extra10 = __toESM(require_lib(), 1);
|
|
52498
|
-
var import_proper_lockfile4 = __toESM(require_proper_lockfile(), 1);
|
|
52499
|
-
async function writeManifest(providerRoot, kitName, version3, scope, kitType, trackedFiles, userConfigFiles) {
|
|
52500
|
-
const metadataPath = join28(providerRoot, "metadata.json");
|
|
52501
|
-
const kit = kitType || "engineer";
|
|
52502
|
-
await import_fs_extra10.ensureFile(metadataPath);
|
|
52503
|
-
let release = null;
|
|
52504
|
-
try {
|
|
52505
|
-
release = await import_proper_lockfile4.lock(metadataPath, {
|
|
52506
|
-
retries: { retries: 5, minTimeout: 100, maxTimeout: 1000 },
|
|
52507
|
-
stale: 60000
|
|
52508
|
-
});
|
|
52509
|
-
logger.debug(`Acquired lock on ${metadataPath}`);
|
|
52510
|
-
const migrationResult = await migrateToMultiKit(providerRoot);
|
|
52511
|
-
if (!migrationResult.success) {
|
|
52512
|
-
logger.warning(`Metadata migration warning: ${migrationResult.error}`);
|
|
52513
|
-
}
|
|
52514
|
-
let existingMetadata = { kits: {} };
|
|
52515
|
-
if (await import_fs_extra10.pathExists(metadataPath)) {
|
|
52516
|
-
try {
|
|
52517
|
-
const content = await import_fs_extra10.readFile(metadataPath, "utf-8");
|
|
52518
|
-
const parsed = JSON.parse(content);
|
|
52519
|
-
if (parsed && typeof parsed === "object" && Object.keys(parsed).length > 0) {
|
|
52520
|
-
existingMetadata = parsed;
|
|
52521
|
-
}
|
|
52522
|
-
} catch (error) {
|
|
52523
|
-
logger.debug(`Could not read existing metadata: ${error}`);
|
|
52524
|
-
}
|
|
52525
|
-
}
|
|
52526
|
-
const existingKits = existingMetadata.kits || {};
|
|
52527
|
-
const otherKitsExist = Object.keys(existingKits).some((k2) => k2 !== kit);
|
|
52528
|
-
const installedAt = new Date().toISOString();
|
|
52529
|
-
const existingKitMeta = existingKits[kit];
|
|
52530
|
-
const kitMetadata = {
|
|
52531
|
-
...existingKitMeta ?? {},
|
|
52532
|
-
version: version3,
|
|
52533
|
-
installedAt,
|
|
52534
|
-
installState: "complete",
|
|
52535
|
-
files: trackedFiles.length > 0 ? trackedFiles : undefined
|
|
52536
|
-
};
|
|
52537
|
-
const metadata = {
|
|
52538
|
-
kits: {
|
|
52539
|
-
...existingKits,
|
|
52540
|
-
[kit]: kitMetadata
|
|
52541
|
-
},
|
|
52542
|
-
scope,
|
|
52543
|
-
name: otherKitsExist ? existingMetadata.name ?? kitName : kitName,
|
|
52544
|
-
version: otherKitsExist ? existingMetadata.version ?? version3 : version3,
|
|
52545
|
-
installedAt: otherKitsExist ? existingMetadata.installedAt ?? installedAt : installedAt,
|
|
52546
|
-
userConfigFiles: [...USER_CONFIG_PATTERNS, ...userConfigFiles],
|
|
52547
|
-
...existingMetadata.telemetry_endpoint !== undefined && {
|
|
52548
|
-
telemetry_endpoint: existingMetadata.telemetry_endpoint
|
|
52549
|
-
},
|
|
52550
|
-
...existingMetadata.telemetry_token_placeholder !== undefined && {
|
|
52551
|
-
telemetry_token_placeholder: existingMetadata.telemetry_token_placeholder
|
|
52552
|
-
},
|
|
52553
|
-
...existingMetadata.deletions !== undefined && {
|
|
52554
|
-
deletions: existingMetadata.deletions
|
|
52555
|
-
}
|
|
52556
|
-
};
|
|
52557
|
-
const validated = MetadataSchema.parse(metadata);
|
|
52558
|
-
await import_fs_extra10.writeFile(metadataPath, JSON.stringify(validated, null, 2), "utf-8");
|
|
52559
|
-
logger.debug(`Wrote manifest for kit "${kit}" with ${trackedFiles.length} tracked files`);
|
|
52560
|
-
} finally {
|
|
52561
|
-
if (release) {
|
|
52562
|
-
await release();
|
|
52563
|
-
logger.debug(`Released lock on ${metadataPath}`);
|
|
52564
|
-
}
|
|
52565
|
-
}
|
|
52566
|
-
}
|
|
52567
|
-
async function writeKitPending(providerRoot, kit, version3, scope) {
|
|
52568
|
-
const metadataPath = join28(providerRoot, "metadata.json");
|
|
52569
|
-
await import_fs_extra10.ensureFile(metadataPath);
|
|
52570
|
-
let release = null;
|
|
52571
|
-
try {
|
|
52572
|
-
release = await import_proper_lockfile4.lock(metadataPath, {
|
|
52573
|
-
retries: { retries: 5, minTimeout: 100, maxTimeout: 1000 },
|
|
52574
|
-
stale: 60000
|
|
52575
|
-
});
|
|
52576
|
-
logger.debug(`Acquired lock on ${metadataPath} for pending-state write`);
|
|
52577
|
-
const migrationResult = await migrateToMultiKit(providerRoot);
|
|
52578
|
-
if (!migrationResult.success) {
|
|
52579
|
-
logger.warning(`Metadata migration warning: ${migrationResult.error}`);
|
|
52580
|
-
}
|
|
52581
|
-
let existingMetadata = { kits: {} };
|
|
52582
|
-
if (await import_fs_extra10.pathExists(metadataPath)) {
|
|
52583
|
-
try {
|
|
52584
|
-
const content = await import_fs_extra10.readFile(metadataPath, "utf-8");
|
|
52585
|
-
const parsed = JSON.parse(content);
|
|
52586
|
-
if (parsed && typeof parsed === "object" && Object.keys(parsed).length > 0) {
|
|
52587
|
-
existingMetadata = parsed;
|
|
52588
|
-
}
|
|
52589
|
-
} catch (error) {
|
|
52590
|
-
logger.debug(`Could not read existing metadata: ${error}`);
|
|
52591
|
-
}
|
|
52592
|
-
}
|
|
52593
|
-
const existingKits = existingMetadata.kits || {};
|
|
52594
|
-
const pendingMetadata = {
|
|
52595
|
-
version: version3,
|
|
52596
|
-
installedAt: new Date().toISOString(),
|
|
52597
|
-
installState: "pending",
|
|
52598
|
-
files: []
|
|
52599
|
-
};
|
|
52600
|
-
const metadata = {
|
|
52601
|
-
...existingMetadata,
|
|
52602
|
-
kits: {
|
|
52603
|
-
...existingKits,
|
|
52604
|
-
[kit]: pendingMetadata
|
|
52605
|
-
},
|
|
52606
|
-
scope
|
|
52607
|
-
};
|
|
52608
|
-
const validated = MetadataSchema.parse(metadata);
|
|
52609
|
-
await import_fs_extra10.writeFile(metadataPath, JSON.stringify(validated, null, 2), "utf-8");
|
|
52610
|
-
logger.debug(`Wrote pending-state entry for kit "${kit}"`);
|
|
52611
|
-
} finally {
|
|
52612
|
-
if (release) {
|
|
52613
|
-
await release();
|
|
52614
|
-
logger.debug(`Released lock on ${metadataPath}`);
|
|
52615
|
-
}
|
|
52616
|
-
}
|
|
52617
|
-
}
|
|
52618
|
-
async function findPendingKits(providerRoot) {
|
|
52619
|
-
const metadata = await readManifest(providerRoot);
|
|
52620
|
-
if (!metadata?.kits)
|
|
52621
|
-
return [];
|
|
52622
|
-
const pending = [];
|
|
52623
|
-
for (const [kitName, kitMeta] of Object.entries(metadata.kits)) {
|
|
52624
|
-
if (kitMeta?.installState === "pending") {
|
|
52625
|
-
pending.push(kitName);
|
|
52626
|
-
}
|
|
52627
|
-
}
|
|
52628
|
-
return pending;
|
|
52629
|
-
}
|
|
52630
|
-
async function removeKitFromManifest(providerRoot, kit) {
|
|
52631
|
-
const metadataPath = join28(providerRoot, "metadata.json");
|
|
52632
|
-
if (!await import_fs_extra10.pathExists(metadataPath))
|
|
52633
|
-
return false;
|
|
52634
|
-
let release = null;
|
|
52635
|
-
try {
|
|
52636
|
-
release = await import_proper_lockfile4.lock(metadataPath, {
|
|
52637
|
-
retries: { retries: 5, minTimeout: 100, maxTimeout: 1000 },
|
|
52638
|
-
stale: 60000
|
|
52639
|
-
});
|
|
52640
|
-
logger.debug(`Acquired lock on ${metadataPath} for kit removal`);
|
|
52641
|
-
const metadata = await readManifest(providerRoot);
|
|
52642
|
-
if (!metadata?.kits?.[kit])
|
|
52643
|
-
return false;
|
|
52644
|
-
const { [kit]: _removed, ...remainingKits } = metadata.kits;
|
|
52645
|
-
if (Object.keys(remainingKits).length === 0) {
|
|
52646
|
-
logger.debug("No kits remaining, metadata.json will be cleaned up");
|
|
52647
|
-
return true;
|
|
52648
|
-
}
|
|
52649
|
-
const updated = {
|
|
52650
|
-
...metadata,
|
|
52651
|
-
kits: remainingKits
|
|
52652
|
-
};
|
|
52653
|
-
await import_fs_extra10.writeFile(metadataPath, JSON.stringify(updated, null, 2), "utf-8");
|
|
52654
|
-
logger.debug(`Removed kit "${kit}" from metadata, ${Object.keys(remainingKits).length} kit(s) remaining`);
|
|
52655
|
-
return true;
|
|
52656
|
-
} finally {
|
|
52657
|
-
if (release) {
|
|
52658
|
-
await release();
|
|
52659
|
-
logger.debug(`Released lock on ${metadataPath}`);
|
|
52660
|
-
}
|
|
52661
|
-
}
|
|
52662
|
-
}
|
|
52663
|
-
|
|
52664
|
-
// src/services/file-operations/manifest/manifest-tracker.ts
|
|
52665
|
-
class ManifestTracker {
|
|
52666
|
-
installedFiles = new Set;
|
|
52667
|
-
userConfigFiles = new Set;
|
|
52668
|
-
trackedFiles = new Map;
|
|
52669
|
-
addInstalledFile(relativePath) {
|
|
52670
|
-
const normalized = relativePath.replace(/\\/g, "/");
|
|
52671
|
-
this.installedFiles.add(normalized);
|
|
52672
|
-
}
|
|
52673
|
-
addInstalledFiles(relativePaths) {
|
|
52674
|
-
for (const path4 of relativePaths) {
|
|
52675
|
-
this.addInstalledFile(path4);
|
|
52676
|
-
}
|
|
52677
|
-
}
|
|
52678
|
-
addUserConfigFile(relativePath) {
|
|
52679
|
-
const normalized = relativePath.replace(/\\/g, "/");
|
|
52680
|
-
this.userConfigFiles.add(normalized);
|
|
52681
|
-
}
|
|
52682
|
-
getInstalledFiles() {
|
|
52683
|
-
return Array.from(this.installedFiles).sort();
|
|
52684
|
-
}
|
|
52685
|
-
getUserConfigFiles() {
|
|
52686
|
-
return Array.from(this.userConfigFiles).sort();
|
|
52687
|
-
}
|
|
52688
|
-
async addTrackedFile(filePath, relativePath, ownership, installedVersion, sourceTimestamp) {
|
|
52689
|
-
const checksum = await OwnershipChecker.calculateChecksum(filePath);
|
|
52690
|
-
const normalized = relativePath.replace(/\\/g, "/");
|
|
52691
|
-
this.trackedFiles.set(normalized, {
|
|
52692
|
-
path: normalized,
|
|
52693
|
-
checksum,
|
|
52694
|
-
ownership,
|
|
52695
|
-
installedVersion,
|
|
52696
|
-
sourceTimestamp,
|
|
52697
|
-
installedAt: new Date().toISOString()
|
|
52698
|
-
});
|
|
52699
|
-
this.installedFiles.add(normalized);
|
|
52700
|
-
}
|
|
52701
|
-
async addTrackedFilesBatch(files, options2 = {}) {
|
|
52702
|
-
const { concurrency = 20, onProgress } = options2;
|
|
52703
|
-
const limit = pLimit(concurrency);
|
|
52704
|
-
const total = files.length;
|
|
52705
|
-
const tasks = files.map((file) => limit(async () => {
|
|
52706
|
-
try {
|
|
52707
|
-
const checksum = await OwnershipChecker.calculateChecksum(file.filePath);
|
|
52708
|
-
const normalized = file.relativePath.replace(/\\/g, "/");
|
|
52709
|
-
this.trackedFiles.set(normalized, {
|
|
52710
|
-
path: normalized,
|
|
52711
|
-
checksum,
|
|
52712
|
-
ownership: file.ownership,
|
|
52713
|
-
installedVersion: file.installedVersion,
|
|
52714
|
-
sourceTimestamp: file.sourceTimestamp,
|
|
52715
|
-
installedAt: new Date().toISOString()
|
|
52716
|
-
});
|
|
52717
|
-
this.installedFiles.add(normalized);
|
|
52718
|
-
return true;
|
|
52719
|
-
} catch (error) {
|
|
52720
|
-
logger.debug(`Failed to track file ${file.relativePath}: ${error}`);
|
|
52721
|
-
return false;
|
|
52722
|
-
}
|
|
52723
|
-
}));
|
|
52724
|
-
const progressInterval = Math.max(1, Math.floor(total / 20));
|
|
52725
|
-
let reportedProgress = 0;
|
|
52726
|
-
const results = await Promise.all(tasks.map(async (task, index) => {
|
|
52727
|
-
const result = await task;
|
|
52728
|
-
const completed = index + 1;
|
|
52729
|
-
if (completed % progressInterval === 0 || completed === total) {
|
|
52730
|
-
if (completed > reportedProgress) {
|
|
52731
|
-
reportedProgress = completed;
|
|
52732
|
-
onProgress?.(completed, total);
|
|
52733
|
-
}
|
|
52734
|
-
}
|
|
52735
|
-
return result;
|
|
52736
|
-
}));
|
|
52737
|
-
const success = results.filter(Boolean).length;
|
|
52738
|
-
const failed = total - success;
|
|
52739
|
-
if (failed > 0) {
|
|
52740
|
-
logger.warning(`Failed to track ${failed} of ${total} files (check debug logs for details)`);
|
|
52741
|
-
}
|
|
52742
|
-
return { success, failed, total };
|
|
52743
|
-
}
|
|
52744
|
-
getTrackedFiles() {
|
|
52745
|
-
return Array.from(this.trackedFiles.values()).sort((a3, b3) => a3.path.localeCompare(b3.path));
|
|
52746
|
-
}
|
|
52747
|
-
}
|
|
52748
|
-
function buildFileTrackingList(options2) {
|
|
52749
|
-
const {
|
|
52750
|
-
installedFiles,
|
|
52751
|
-
providerRoot,
|
|
52752
|
-
ownershipResolver,
|
|
52753
|
-
installedVersion,
|
|
52754
|
-
isGlobal = false
|
|
52755
|
-
} = options2;
|
|
52756
|
-
const filesToTrack = [];
|
|
52757
|
-
for (const installedPath of installedFiles) {
|
|
52758
|
-
if (!isGlobal && installedPath.startsWith(".claude/")) {
|
|
52759
|
-
const relativePath2 = installedPath.replace(/^\.claude\//, "");
|
|
52760
|
-
const filePath2 = join29(providerRoot, relativePath2);
|
|
52761
|
-
const { ownership: ownership2, sourceTimestamp: sourceTimestamp2 } = ownershipResolver(installedPath);
|
|
52762
|
-
filesToTrack.push({
|
|
52763
|
-
filePath: filePath2,
|
|
52764
|
-
relativePath: relativePath2,
|
|
52765
|
-
ownership: ownership2,
|
|
52766
|
-
installedVersion,
|
|
52767
|
-
sourceTimestamp: sourceTimestamp2
|
|
52768
|
-
});
|
|
52769
|
-
continue;
|
|
52770
|
-
}
|
|
52771
|
-
if (!isGlobal && !installedPath.startsWith(".claude/")) {
|
|
52772
|
-
continue;
|
|
52773
|
-
}
|
|
52774
|
-
const relativePath = installedPath;
|
|
52775
|
-
const filePath = join29(providerRoot, relativePath);
|
|
52776
|
-
const { ownership, sourceTimestamp } = ownershipResolver(installedPath);
|
|
52777
|
-
filesToTrack.push({
|
|
52778
|
-
filePath,
|
|
52779
|
-
relativePath,
|
|
52780
|
-
ownership,
|
|
52781
|
-
installedVersion,
|
|
52782
|
-
sourceTimestamp
|
|
52783
|
-
});
|
|
52784
|
-
}
|
|
52785
|
-
return filesToTrack;
|
|
52786
|
-
}
|
|
52787
|
-
async function trackFilesWithProgress(filesToTrack, manifestOptions) {
|
|
52788
|
-
const tracker = new ManifestTracker;
|
|
52789
|
-
const trackingSpinner = createSpinner(`Tracking ${filesToTrack.length} installed files...`);
|
|
52790
|
-
trackingSpinner.start();
|
|
52791
|
-
const trackResult = await tracker.addTrackedFilesBatch(filesToTrack, {
|
|
52792
|
-
concurrency: getOptimalConcurrency(),
|
|
52793
|
-
onProgress: (processed, total) => {
|
|
52794
|
-
trackingSpinner.text = `Tracking files... (${processed}/${total})`;
|
|
52795
|
-
}
|
|
52796
|
-
});
|
|
52797
|
-
trackingSpinner.succeed(`Tracked ${trackResult.success} files`);
|
|
52798
|
-
await writeManifest(manifestOptions.providerRoot, manifestOptions.kitName, manifestOptions.releaseTag, manifestOptions.mode, manifestOptions.kitType, tracker.getTrackedFiles(), tracker.getUserConfigFiles());
|
|
52799
|
-
return trackResult;
|
|
52800
|
-
}
|
|
52801
|
-
// src/services/file-operations/manifest-writer.ts
|
|
52802
|
-
class ManifestWriter {
|
|
52803
|
-
tracker = new ManifestTracker;
|
|
52804
|
-
addInstalledFile(relativePath) {
|
|
52805
|
-
this.tracker.addInstalledFile(relativePath);
|
|
52806
|
-
}
|
|
52807
|
-
addInstalledFiles(relativePaths) {
|
|
52808
|
-
this.tracker.addInstalledFiles(relativePaths);
|
|
52809
|
-
}
|
|
52810
|
-
addUserConfigFile(relativePath) {
|
|
52811
|
-
this.tracker.addUserConfigFile(relativePath);
|
|
52812
|
-
}
|
|
52813
|
-
getInstalledFiles() {
|
|
52814
|
-
return this.tracker.getInstalledFiles();
|
|
52815
|
-
}
|
|
52816
|
-
getUserConfigFiles() {
|
|
52817
|
-
return this.tracker.getUserConfigFiles();
|
|
52818
|
-
}
|
|
52819
|
-
async addTrackedFile(filePath, relativePath, ownership, installedVersion, sourceTimestamp) {
|
|
52820
|
-
return this.tracker.addTrackedFile(filePath, relativePath, ownership, installedVersion, sourceTimestamp);
|
|
52821
|
-
}
|
|
52822
|
-
async addTrackedFilesBatch(files, options2 = {}) {
|
|
52823
|
-
return this.tracker.addTrackedFilesBatch(files, options2);
|
|
52824
|
-
}
|
|
52825
|
-
getTrackedFiles() {
|
|
52826
|
-
return this.tracker.getTrackedFiles();
|
|
52827
|
-
}
|
|
52828
|
-
async writeManifest(providerRoot, kitName, version3, scope, kitType) {
|
|
52829
|
-
return writeManifest(providerRoot, kitName, version3, scope, kitType, this.getTrackedFiles(), this.getUserConfigFiles());
|
|
52830
|
-
}
|
|
52831
|
-
static async writeKitPending(providerRoot, kit, version3, scope) {
|
|
52832
|
-
return writeKitPending(providerRoot, kit, version3, scope);
|
|
52833
|
-
}
|
|
52834
|
-
static async findPendingKits(providerRoot) {
|
|
52835
|
-
return findPendingKits(providerRoot);
|
|
52836
|
-
}
|
|
52837
|
-
static async readManifest(providerRoot) {
|
|
52838
|
-
return readManifest(providerRoot);
|
|
52839
|
-
}
|
|
52840
|
-
static async readKitManifest(providerRoot, kit) {
|
|
52841
|
-
return readKitManifest(providerRoot, kit);
|
|
52842
|
-
}
|
|
52843
|
-
static async getUninstallManifest(providerRoot, kit) {
|
|
52844
|
-
return getUninstallManifest(providerRoot, kit);
|
|
52845
|
-
}
|
|
52846
|
-
static async removeKitFromManifest(providerRoot, kit) {
|
|
52847
|
-
return removeKitFromManifest(providerRoot, kit);
|
|
52848
|
-
}
|
|
52849
|
-
}
|
|
52850
|
-
|
|
52851
|
-
// src/domains/migration/legacy-migration.ts
|
|
52852
52847
|
init_logger();
|
|
52853
52848
|
var import_fs_extra12 = __toESM(require_lib(), 1);
|
|
52854
52849
|
|
|
@@ -55678,6 +55673,14 @@ async function handlePostInstall(ctx) {
|
|
|
55678
55673
|
}
|
|
55679
55674
|
|
|
55680
55675
|
// src/domains/installers/claude-code/installer.ts
|
|
55676
|
+
function resolveClaudeRoot(ctx) {
|
|
55677
|
+
if (!ctx.resolvedDir)
|
|
55678
|
+
return null;
|
|
55679
|
+
if (ctx.options.global)
|
|
55680
|
+
return getClaudeDir();
|
|
55681
|
+
const prefix = PathResolver.getPathPrefix(false);
|
|
55682
|
+
return prefix ? join57(ctx.resolvedDir, prefix) : ctx.resolvedDir;
|
|
55683
|
+
}
|
|
55681
55684
|
function cancelled() {
|
|
55682
55685
|
return { provider: "claude-code", success: true, installedFiles: [], cancelled: true };
|
|
55683
55686
|
}
|
|
@@ -55703,8 +55706,32 @@ var claudeCodeInstaller = {
|
|
|
55703
55706
|
async preInstall(ctx) {
|
|
55704
55707
|
if (isSyncContext(ctx))
|
|
55705
55708
|
return ctx;
|
|
55709
|
+
const claudeRoot = resolveClaudeRoot(ctx);
|
|
55710
|
+
if (claudeRoot) {
|
|
55711
|
+
try {
|
|
55712
|
+
const pending = await ManifestWriter.findPendingKits(claudeRoot);
|
|
55713
|
+
if (pending.length > 0) {
|
|
55714
|
+
logger.warning(`Previous claude-code install was interrupted for kit(s): ${pending.join(", ")}. Re-running install will overwrite the pending entry.`);
|
|
55715
|
+
}
|
|
55716
|
+
} catch (error) {
|
|
55717
|
+
logger.debug(`[claude-code] pending-kit check skipped: ${error}`);
|
|
55718
|
+
}
|
|
55719
|
+
}
|
|
55706
55720
|
return handleConflicts(ctx);
|
|
55707
55721
|
},
|
|
55722
|
+
async markKitPending(ctx, kit, version3) {
|
|
55723
|
+
if (isSyncContext(ctx))
|
|
55724
|
+
return;
|
|
55725
|
+
const claudeRoot = resolveClaudeRoot(ctx);
|
|
55726
|
+
if (!claudeRoot)
|
|
55727
|
+
return;
|
|
55728
|
+
const scope = ctx.options.global ? "global" : "local";
|
|
55729
|
+
try {
|
|
55730
|
+
await ManifestWriter.writeKitPending(claudeRoot, kit, version3, scope);
|
|
55731
|
+
} catch (error) {
|
|
55732
|
+
logger.debug(`[claude-code] writeKitPending skipped: ${error}`);
|
|
55733
|
+
}
|
|
55734
|
+
},
|
|
55708
55735
|
async install(ctx) {
|
|
55709
55736
|
if (isSyncContext(ctx)) {
|
|
55710
55737
|
return { provider: "claude-code", success: true, installedFiles: [] };
|
|
@@ -55758,7 +55785,6 @@ import { homedir as homedir22 } from "node:os";
|
|
|
55758
55785
|
import { join as join71 } from "node:path";
|
|
55759
55786
|
init_logger();
|
|
55760
55787
|
init_dist2();
|
|
55761
|
-
var import_picocolors16 = __toESM(require_picocolors(), 1);
|
|
55762
55788
|
|
|
55763
55789
|
// src/domains/installers/codex/install-pipeline.ts
|
|
55764
55790
|
import { basename as basename9 } from "node:path";
|
|
@@ -60543,8 +60569,15 @@ var codexInstaller = {
|
|
|
60543
60569
|
logger.warning("[init/codex] No items found in extracted kit; nothing to install");
|
|
60544
60570
|
return { provider: "codex", success: true, installedFiles: [], warnings: ["No items"] };
|
|
60545
60571
|
}
|
|
60546
|
-
|
|
60547
|
-
const installGlobally =
|
|
60572
|
+
let items = await discoverFromSources(sources);
|
|
60573
|
+
const installGlobally = Boolean(ctx.options.global);
|
|
60574
|
+
if (!installGlobally && items.commands.length > 0) {
|
|
60575
|
+
const codexCommandsConfig = providers.codex.commands;
|
|
60576
|
+
if (codexCommandsConfig?.projectPath === null) {
|
|
60577
|
+
logger.warning(`[init/codex] Skipping ${items.commands.length} command(s): codex commands are global-only (deprecated; use skills). Pass -g to install them globally.`);
|
|
60578
|
+
items = { ...items, commands: [] };
|
|
60579
|
+
}
|
|
60580
|
+
}
|
|
60548
60581
|
if (ctx.options.fresh) {
|
|
60549
60582
|
const confirmed = await confirmFresh(ctx, installGlobally);
|
|
60550
60583
|
if (!confirmed) {
|
|
@@ -60634,16 +60667,6 @@ var codexInstaller = {
|
|
|
60634
60667
|
}
|
|
60635
60668
|
}
|
|
60636
60669
|
};
|
|
60637
|
-
function computeEffectiveGlobal(ctx, hasCommands) {
|
|
60638
|
-
if (ctx.options.global)
|
|
60639
|
-
return true;
|
|
60640
|
-
const codexConfig = providers.codex;
|
|
60641
|
-
if (hasCommands && codexConfig.commands && codexConfig.commands.projectPath === null) {
|
|
60642
|
-
logger.info(import_picocolors16.default.dim("Codex commands are global-only; scope adjusted to global."));
|
|
60643
|
-
return true;
|
|
60644
|
-
}
|
|
60645
|
-
return false;
|
|
60646
|
-
}
|
|
60647
60670
|
async function confirmFresh(ctx, global3) {
|
|
60648
60671
|
if (ctx.options.yes)
|
|
60649
60672
|
return true;
|
|
@@ -63155,7 +63178,7 @@ class ReportGenerator {
|
|
|
63155
63178
|
}
|
|
63156
63179
|
// src/domains/health-checks/doctor-ui-renderer.ts
|
|
63157
63180
|
init_terminal_utils();
|
|
63158
|
-
var
|
|
63181
|
+
var import_picocolors16 = __toESM(require_picocolors(), 1);
|
|
63159
63182
|
|
|
63160
63183
|
class DoctorUIRenderer {
|
|
63161
63184
|
symbols = getStatusSymbols();
|
|
@@ -63167,8 +63190,8 @@ class DoctorUIRenderer {
|
|
|
63167
63190
|
const groups = this.groupChecks(summary.checks);
|
|
63168
63191
|
for (const [groupName, checks] of groups) {
|
|
63169
63192
|
console.log("│");
|
|
63170
|
-
console.log(`│ ${
|
|
63171
|
-
console.log(`│ ${
|
|
63193
|
+
console.log(`│ ${import_picocolors16.default.bold(import_picocolors16.default.cyan(groupName.toUpperCase()))}`);
|
|
63194
|
+
console.log(`│ ${import_picocolors16.default.dim("─".repeat(50))}`);
|
|
63172
63195
|
const maxNameLen = Math.max(...checks.map((c2) => c2.name.length));
|
|
63173
63196
|
const maxMsgLen = Math.max(...checks.map((c2) => c2.message.length));
|
|
63174
63197
|
for (const check of checks) {
|
|
@@ -63180,55 +63203,55 @@ class DoctorUIRenderer {
|
|
|
63180
63203
|
}
|
|
63181
63204
|
renderCheck(check, maxNameLen, maxMsgLen) {
|
|
63182
63205
|
const symbol = this.getColoredSymbol(check.status);
|
|
63183
|
-
const name =
|
|
63206
|
+
const name = import_picocolors16.default.bold(check.name.padEnd(maxNameLen));
|
|
63184
63207
|
const paddedMsg = check.message.padEnd(maxMsgLen);
|
|
63185
63208
|
const value = this.colorizeValue(check.status, paddedMsg);
|
|
63186
63209
|
if (this.verbose && check.command) {
|
|
63187
|
-
console.log(`│ ${
|
|
63210
|
+
console.log(`│ ${import_picocolors16.default.dim(`Running: ${check.command}`)}`);
|
|
63188
63211
|
}
|
|
63189
63212
|
let line = `│ ${symbol} ${name} ${value}`;
|
|
63190
63213
|
if (this.verbose && check.duration !== undefined) {
|
|
63191
|
-
line += ` ${
|
|
63214
|
+
line += ` ${import_picocolors16.default.dim(`(${check.duration}ms)`)}`;
|
|
63192
63215
|
}
|
|
63193
63216
|
if (check.details) {
|
|
63194
63217
|
const displayPath = this.verbose ? check.details : this.shortenPath(check.details);
|
|
63195
|
-
line += ` ${
|
|
63218
|
+
line += ` ${import_picocolors16.default.dim(displayPath)}`;
|
|
63196
63219
|
}
|
|
63197
63220
|
console.log(line);
|
|
63198
63221
|
if (this.verbose && check.status === "pass" && check.suggestion) {
|
|
63199
63222
|
const indent = " ".repeat(maxNameLen + 5);
|
|
63200
|
-
console.log(`│ ${indent}${
|
|
63223
|
+
console.log(`│ ${indent}${import_picocolors16.default.dim(`→ ${check.suggestion}`)}`);
|
|
63201
63224
|
}
|
|
63202
63225
|
if (check.status !== "pass" && check.suggestion) {
|
|
63203
63226
|
const indent = " ".repeat(maxNameLen + 5);
|
|
63204
|
-
console.log(`│ ${indent}${
|
|
63227
|
+
console.log(`│ ${indent}${import_picocolors16.default.dim(`→ ${check.suggestion}`)}`);
|
|
63205
63228
|
}
|
|
63206
63229
|
}
|
|
63207
63230
|
getColoredSymbol(status2) {
|
|
63208
63231
|
switch (status2) {
|
|
63209
63232
|
case "pass":
|
|
63210
|
-
return
|
|
63233
|
+
return import_picocolors16.default.green(this.symbols.pass);
|
|
63211
63234
|
case "warn":
|
|
63212
|
-
return
|
|
63235
|
+
return import_picocolors16.default.yellow(this.symbols.warn);
|
|
63213
63236
|
case "fail":
|
|
63214
|
-
return
|
|
63237
|
+
return import_picocolors16.default.red(this.symbols.fail);
|
|
63215
63238
|
default:
|
|
63216
|
-
return
|
|
63239
|
+
return import_picocolors16.default.blue(this.symbols.info);
|
|
63217
63240
|
}
|
|
63218
63241
|
}
|
|
63219
63242
|
renderHealingSummary(healSummary) {
|
|
63220
63243
|
console.log("│");
|
|
63221
|
-
console.log(`│ ${
|
|
63222
|
-
console.log(`│ ${
|
|
63244
|
+
console.log(`│ ${import_picocolors16.default.bold(import_picocolors16.default.cyan("AUTO-HEAL RESULTS"))}`);
|
|
63245
|
+
console.log(`│ ${import_picocolors16.default.dim("─".repeat(50))}`);
|
|
63223
63246
|
for (const fix of healSummary.fixes) {
|
|
63224
|
-
const symbol = fix.success ?
|
|
63225
|
-
console.log(`│ ${symbol} ${
|
|
63247
|
+
const symbol = fix.success ? import_picocolors16.default.green(this.symbols.pass) : import_picocolors16.default.red(this.symbols.fail);
|
|
63248
|
+
console.log(`│ ${symbol} ${import_picocolors16.default.bold(fix.checkName)} ${import_picocolors16.default.dim(fix.message)}`);
|
|
63226
63249
|
if (!fix.success && fix.error) {
|
|
63227
|
-
console.log(`│ ${
|
|
63250
|
+
console.log(`│ ${import_picocolors16.default.red(`Error: ${fix.error}`)}`);
|
|
63228
63251
|
}
|
|
63229
63252
|
}
|
|
63230
63253
|
console.log("│");
|
|
63231
|
-
console.log(`│ Fixed: ${
|
|
63254
|
+
console.log(`│ Fixed: ${import_picocolors16.default.green(String(healSummary.succeeded))}, Failed: ${import_picocolors16.default.red(String(healSummary.failed))}`);
|
|
63232
63255
|
}
|
|
63233
63256
|
groupChecks(checks) {
|
|
63234
63257
|
const groups = new Map;
|
|
@@ -63242,11 +63265,11 @@ class DoctorUIRenderer {
|
|
|
63242
63265
|
colorizeValue(status2, message) {
|
|
63243
63266
|
switch (status2) {
|
|
63244
63267
|
case "pass":
|
|
63245
|
-
return
|
|
63268
|
+
return import_picocolors16.default.green(message);
|
|
63246
63269
|
case "warn":
|
|
63247
|
-
return
|
|
63270
|
+
return import_picocolors16.default.yellow(message);
|
|
63248
63271
|
case "fail":
|
|
63249
|
-
return
|
|
63272
|
+
return import_picocolors16.default.red(message);
|
|
63250
63273
|
default:
|
|
63251
63274
|
return message;
|
|
63252
63275
|
}
|
|
@@ -63265,23 +63288,23 @@ class DoctorUIRenderer {
|
|
|
63265
63288
|
renderSummaryLine(summary) {
|
|
63266
63289
|
const parts = [];
|
|
63267
63290
|
if (summary.passed > 0) {
|
|
63268
|
-
parts.push(
|
|
63291
|
+
parts.push(import_picocolors16.default.green(`${summary.passed} ${this.symbols.pass}`));
|
|
63269
63292
|
}
|
|
63270
63293
|
if (summary.warnings > 0) {
|
|
63271
|
-
parts.push(
|
|
63294
|
+
parts.push(import_picocolors16.default.yellow(`${summary.warnings} ${this.symbols.warn}`));
|
|
63272
63295
|
}
|
|
63273
63296
|
if (summary.failed > 0) {
|
|
63274
|
-
parts.push(
|
|
63297
|
+
parts.push(import_picocolors16.default.red(`${summary.failed} ${this.symbols.fail}`));
|
|
63275
63298
|
}
|
|
63276
|
-
console.log(`│ ${
|
|
63299
|
+
console.log(`│ ${import_picocolors16.default.dim("─".repeat(50))}`);
|
|
63277
63300
|
console.log(`│ Summary: ${parts.join(" ")}`);
|
|
63278
63301
|
console.log("│");
|
|
63279
|
-
console.log(`│ ${
|
|
63280
|
-
console.log(`│ ${
|
|
63281
|
-
console.log(`│ ${
|
|
63282
|
-
console.log(`│ ${
|
|
63283
|
-
console.log(`│ ${
|
|
63284
|
-
console.log(`│ ${
|
|
63302
|
+
console.log(`│ ${import_picocolors16.default.dim("Quick Commands:")}`);
|
|
63303
|
+
console.log(`│ ${import_picocolors16.default.dim(" tkm init Install/update Takumi in project")}`);
|
|
63304
|
+
console.log(`│ ${import_picocolors16.default.dim(" tkm init -g Install/update Takumi globally")}`);
|
|
63305
|
+
console.log(`│ ${import_picocolors16.default.dim(" tkm update Update the CLI tool")}`);
|
|
63306
|
+
console.log(`│ ${import_picocolors16.default.dim(" tkm uninstall Remove Takumi from project/global")}`);
|
|
63307
|
+
console.log(`│ ${import_picocolors16.default.dim(" tkm --help Show all commands")}`);
|
|
63285
63308
|
}
|
|
63286
63309
|
}
|
|
63287
63310
|
// src/commands/doctor.ts
|
|
@@ -63362,9 +63385,6 @@ async function doctorCommand(options2 = {}) {
|
|
|
63362
63385
|
}
|
|
63363
63386
|
}
|
|
63364
63387
|
|
|
63365
|
-
// src/commands/init/init-command.ts
|
|
63366
|
-
import { join as join102 } from "node:path";
|
|
63367
|
-
|
|
63368
63388
|
// src/domains/ui/prompts.ts
|
|
63369
63389
|
init_package_installer();
|
|
63370
63390
|
init_logger();
|
|
@@ -63668,7 +63688,7 @@ function releaseEntryToGitHubRelease(entry, kit) {
|
|
|
63668
63688
|
init_logger();
|
|
63669
63689
|
init_dist2();
|
|
63670
63690
|
init_release_filter();
|
|
63671
|
-
var
|
|
63691
|
+
var import_picocolors19 = __toESM(require_picocolors(), 1);
|
|
63672
63692
|
|
|
63673
63693
|
// src/domains/versioning/selection/version-filter.ts
|
|
63674
63694
|
var VERSION_PATTERN = /^v?\d+\.\d+\.\d+(-[a-zA-Z0-9.]+)?$/;
|
|
@@ -63686,36 +63706,36 @@ function normalizeVersionTag(version3) {
|
|
|
63686
63706
|
init_environment();
|
|
63687
63707
|
init_logger();
|
|
63688
63708
|
init_dist2();
|
|
63689
|
-
var
|
|
63709
|
+
var import_picocolors18 = __toESM(require_picocolors(), 1);
|
|
63690
63710
|
|
|
63691
63711
|
// src/domains/versioning/version-display.ts
|
|
63692
|
-
var
|
|
63712
|
+
var import_picocolors17 = __toESM(require_picocolors(), 1);
|
|
63693
63713
|
|
|
63694
63714
|
class VersionDisplayFormatter {
|
|
63695
63715
|
static createBadges(release) {
|
|
63696
63716
|
const badges = [];
|
|
63697
63717
|
if (release.isLatestStable) {
|
|
63698
|
-
badges.push(
|
|
63718
|
+
badges.push(import_picocolors17.default.bold(import_picocolors17.default.yellow("[latest]")));
|
|
63699
63719
|
}
|
|
63700
63720
|
if (release.prerelease || release.isLatestBeta) {
|
|
63701
63721
|
if (release.isLatestBeta) {
|
|
63702
|
-
badges.push(
|
|
63722
|
+
badges.push(import_picocolors17.default.bold(import_picocolors17.default.magenta("[beta]")));
|
|
63703
63723
|
} else {
|
|
63704
|
-
badges.push(
|
|
63724
|
+
badges.push(import_picocolors17.default.magenta("[prerelease]"));
|
|
63705
63725
|
}
|
|
63706
63726
|
} else if (!release.draft) {
|
|
63707
|
-
badges.push(
|
|
63727
|
+
badges.push(import_picocolors17.default.blue("[stable]"));
|
|
63708
63728
|
}
|
|
63709
63729
|
if (release.draft) {
|
|
63710
|
-
badges.push(
|
|
63730
|
+
badges.push(import_picocolors17.default.gray("[draft]"));
|
|
63711
63731
|
}
|
|
63712
63732
|
return badges.length > 0 ? ` ${badges.join(" ")}` : "";
|
|
63713
63733
|
}
|
|
63714
63734
|
static formatChoiceLabel(release) {
|
|
63715
|
-
const version3 =
|
|
63735
|
+
const version3 = import_picocolors17.default.green(release.displayVersion);
|
|
63716
63736
|
const badges = VersionDisplayFormatter.createBadges(release);
|
|
63717
63737
|
const name = release.name || "Release";
|
|
63718
|
-
return `${version3}${badges} ${
|
|
63738
|
+
return `${version3}${badges} ${import_picocolors17.default.dim(name)}`;
|
|
63719
63739
|
}
|
|
63720
63740
|
static formatChoiceHint(release) {
|
|
63721
63741
|
const parts = [];
|
|
@@ -63737,7 +63757,7 @@ class VersionDisplayFormatter {
|
|
|
63737
63757
|
if (latestStable) {
|
|
63738
63758
|
options2.push({
|
|
63739
63759
|
value: latestStable.tag_name,
|
|
63740
|
-
label: `${
|
|
63760
|
+
label: `${import_picocolors17.default.bold(import_picocolors17.default.green("Latest Stable"))} (${latestStable.displayVersion})`,
|
|
63741
63761
|
hint: "recommended version",
|
|
63742
63762
|
isLatest: true,
|
|
63743
63763
|
isPrerelease: false
|
|
@@ -63747,7 +63767,7 @@ class VersionDisplayFormatter {
|
|
|
63747
63767
|
if (latestBeta) {
|
|
63748
63768
|
options2.push({
|
|
63749
63769
|
value: latestBeta.tag_name,
|
|
63750
|
-
label: `${
|
|
63770
|
+
label: `${import_picocolors17.default.bold(import_picocolors17.default.magenta("Latest Beta"))} (${latestBeta.displayVersion})`,
|
|
63751
63771
|
hint: "latest features, may be unstable",
|
|
63752
63772
|
isLatest: false,
|
|
63753
63773
|
isPrerelease: true
|
|
@@ -63758,7 +63778,7 @@ class VersionDisplayFormatter {
|
|
|
63758
63778
|
static createSeparator() {
|
|
63759
63779
|
return {
|
|
63760
63780
|
value: "separator",
|
|
63761
|
-
label:
|
|
63781
|
+
label: import_picocolors17.default.dim("─".repeat(50)),
|
|
63762
63782
|
hint: undefined,
|
|
63763
63783
|
isLatest: false,
|
|
63764
63784
|
isPrerelease: false
|
|
@@ -63767,7 +63787,7 @@ class VersionDisplayFormatter {
|
|
|
63767
63787
|
static createCancelOption() {
|
|
63768
63788
|
return {
|
|
63769
63789
|
value: "cancel",
|
|
63770
|
-
label:
|
|
63790
|
+
label: import_picocolors17.default.red("Cancel"),
|
|
63771
63791
|
hint: "exit version selection",
|
|
63772
63792
|
isLatest: false,
|
|
63773
63793
|
isPrerelease: false
|
|
@@ -63819,15 +63839,15 @@ class VersionDisplayFormatter {
|
|
|
63819
63839
|
return value !== "separator" && value !== "cancel" && value.trim().length > 0;
|
|
63820
63840
|
}
|
|
63821
63841
|
static formatError(message, suggestion) {
|
|
63822
|
-
let output2 =
|
|
63842
|
+
let output2 = import_picocolors17.default.red(`Error: ${message}`);
|
|
63823
63843
|
if (suggestion) {
|
|
63824
63844
|
output2 += `
|
|
63825
|
-
${
|
|
63845
|
+
${import_picocolors17.default.dim(suggestion)}`;
|
|
63826
63846
|
}
|
|
63827
63847
|
return output2;
|
|
63828
63848
|
}
|
|
63829
63849
|
static formatSuccess(version3, kitName) {
|
|
63830
|
-
return `${
|
|
63850
|
+
return `${import_picocolors17.default.green("✓")} Selected ${import_picocolors17.default.bold(version3)} for ${import_picocolors17.default.bold(kitName)}`;
|
|
63831
63851
|
}
|
|
63832
63852
|
}
|
|
63833
63853
|
|
|
@@ -63837,7 +63857,7 @@ async function handleNoReleases(kit, allowManualEntry) {
|
|
|
63837
63857
|
This could be due to:
|
|
63838
63858
|
• No releases published yet
|
|
63839
63859
|
• Network connectivity issues
|
|
63840
|
-
• Repository access permissions`,
|
|
63860
|
+
• Repository access permissions`, import_picocolors18.default.yellow("No Releases Available"));
|
|
63841
63861
|
if (!allowManualEntry) {
|
|
63842
63862
|
throw new Error(`No releases available for ${kit.name}`);
|
|
63843
63863
|
}
|
|
@@ -63897,34 +63917,34 @@ async function createVersionPrompt(kit, choices, _defaultIndex, allowManualEntry
|
|
|
63897
63917
|
if (latestStable) {
|
|
63898
63918
|
clackChoices.push({
|
|
63899
63919
|
value: latestStable.tag_name,
|
|
63900
|
-
label: `${
|
|
63920
|
+
label: `${import_picocolors18.default.bold(import_picocolors18.default.green("Latest Stable"))} (${latestStable.displayVersion})`,
|
|
63901
63921
|
hint: "recommended"
|
|
63902
63922
|
});
|
|
63903
63923
|
}
|
|
63904
63924
|
if (allowManualEntry) {
|
|
63905
63925
|
clackChoices.push({
|
|
63906
63926
|
value: "manual-entry",
|
|
63907
|
-
label:
|
|
63927
|
+
label: import_picocolors18.default.cyan("↳ Enter Version Manually"),
|
|
63908
63928
|
hint: "for older versions"
|
|
63909
63929
|
});
|
|
63910
63930
|
}
|
|
63911
63931
|
clackChoices.push({
|
|
63912
63932
|
value: "cancel",
|
|
63913
|
-
label:
|
|
63933
|
+
label: import_picocolors18.default.red("✕ Cancel")
|
|
63914
63934
|
});
|
|
63915
63935
|
const versionChoices = choices.filter((choice) => choice.value !== "separator" && choice.value !== "cancel");
|
|
63916
63936
|
for (const choice of versionChoices) {
|
|
63917
63937
|
const isCurrentlyInstalled = currentVersion && (choice.value === currentVersion || choice.value === `v${currentVersion}`);
|
|
63918
|
-
const installedMarker = isCurrentlyInstalled ?
|
|
63938
|
+
const installedMarker = isCurrentlyInstalled ? import_picocolors18.default.cyan(" (installed)") : "";
|
|
63919
63939
|
clackChoices.push({
|
|
63920
63940
|
value: choice.value,
|
|
63921
63941
|
label: `${choice.label}${installedMarker}`,
|
|
63922
63942
|
hint: choice.hint
|
|
63923
63943
|
});
|
|
63924
63944
|
}
|
|
63925
|
-
const currentVersionHint = currentVersion ?
|
|
63945
|
+
const currentVersionHint = currentVersion ? import_picocolors18.default.dim(` (current: ${currentVersion})`) : "";
|
|
63926
63946
|
const selected = await ie({
|
|
63927
|
-
message: `Select version for ${
|
|
63947
|
+
message: `Select version for ${import_picocolors18.default.bold(kit.name)}${currentVersionHint}:`,
|
|
63928
63948
|
options: clackChoices,
|
|
63929
63949
|
initialValue: latestStable?.tag_name
|
|
63930
63950
|
});
|
|
@@ -63949,15 +63969,15 @@ async function createVersionPrompt(kit, choices, _defaultIndex, allowManualEntry
|
|
|
63949
63969
|
async function handleSelectionError(error, kit, allowManualEntry, retryCallback) {
|
|
63950
63970
|
logger.error(`Version selection error: ${error.message}`);
|
|
63951
63971
|
if (error.message.includes("401") || error.message.includes("403")) {
|
|
63952
|
-
le(VersionDisplayFormatter.formatError("Authentication failed", "Please check your GitHub token with: sk auth"),
|
|
63972
|
+
le(VersionDisplayFormatter.formatError("Authentication failed", "Please check your GitHub token with: sk auth"), import_picocolors18.default.red("Authentication Error"));
|
|
63953
63973
|
} else if (error.message.includes("404")) {
|
|
63954
|
-
le(VersionDisplayFormatter.formatError("Repository access denied", "Make sure you have access to the repository"),
|
|
63974
|
+
le(VersionDisplayFormatter.formatError("Repository access denied", "Make sure you have access to the repository"), import_picocolors18.default.red("Access Error"));
|
|
63955
63975
|
} else if (error.message.includes("rate limit") || error.message.includes("403")) {
|
|
63956
|
-
le(VersionDisplayFormatter.formatError("GitHub API rate limit exceeded", "Please wait a moment and try again"),
|
|
63976
|
+
le(VersionDisplayFormatter.formatError("GitHub API rate limit exceeded", "Please wait a moment and try again"), import_picocolors18.default.yellow("Rate Limited"));
|
|
63957
63977
|
} else if (error.message.includes("network") || error.message.includes("ENOTFOUND")) {
|
|
63958
|
-
le(VersionDisplayFormatter.formatError("Network connection failed", "Please check your internet connection"),
|
|
63978
|
+
le(VersionDisplayFormatter.formatError("Network connection failed", "Please check your internet connection"), import_picocolors18.default.yellow("Network Error"));
|
|
63959
63979
|
} else {
|
|
63960
|
-
le(VersionDisplayFormatter.formatError(error.message || "Unknown error occurred", "Please try again or contact support"),
|
|
63980
|
+
le(VersionDisplayFormatter.formatError(error.message || "Unknown error occurred", "Please try again or contact support"), import_picocolors18.default.red("Error"));
|
|
63961
63981
|
}
|
|
63962
63982
|
if (isNonInteractive()) {
|
|
63963
63983
|
logger.warning("Non-interactive mode: version selection failed, cannot retry");
|
|
@@ -64019,7 +64039,7 @@ class VersionSelector {
|
|
|
64019
64039
|
} = options2;
|
|
64020
64040
|
try {
|
|
64021
64041
|
const loadingSpinner = de();
|
|
64022
|
-
loadingSpinner.start(`Fetching versions for ${
|
|
64042
|
+
loadingSpinner.start(`Fetching versions for ${import_picocolors19.default.bold(kit.name)}...`);
|
|
64023
64043
|
let releases;
|
|
64024
64044
|
if (useGh) {
|
|
64025
64045
|
releases = await this.githubClient.listReleasesWithCache(kit, {
|
|
@@ -64425,7 +64445,6 @@ class PromptsManager {
|
|
|
64425
64445
|
|
|
64426
64446
|
// src/commands/init/init-command.ts
|
|
64427
64447
|
init_logger();
|
|
64428
|
-
init_path_resolver();
|
|
64429
64448
|
init_types2();
|
|
64430
64449
|
|
|
64431
64450
|
// src/commands/init/context-factory.ts
|
|
@@ -64466,6 +64485,7 @@ function createInitContext(rawOptions, prompts) {
|
|
|
64466
64485
|
}
|
|
64467
64486
|
|
|
64468
64487
|
// src/commands/init/installer-dispatch.ts
|
|
64488
|
+
init_logger();
|
|
64469
64489
|
async function runPreInstallHooks(ctx, targetAgents) {
|
|
64470
64490
|
let updated = ctx;
|
|
64471
64491
|
for (const provider of targetAgents) {
|
|
@@ -64478,7 +64498,7 @@ async function runPreInstallHooks(ctx, targetAgents) {
|
|
|
64478
64498
|
}
|
|
64479
64499
|
return updated;
|
|
64480
64500
|
}
|
|
64481
|
-
async function dispatchInstallers(ctx, targetAgents) {
|
|
64501
|
+
async function dispatchInstallers(ctx, targetAgents, lifecycle) {
|
|
64482
64502
|
const results = [];
|
|
64483
64503
|
for (const provider of targetAgents) {
|
|
64484
64504
|
const installer = getInstaller(provider);
|
|
@@ -64492,6 +64512,13 @@ async function dispatchInstallers(ctx, targetAgents) {
|
|
|
64492
64512
|
continue;
|
|
64493
64513
|
}
|
|
64494
64514
|
try {
|
|
64515
|
+
if (lifecycle && installer.markKitPending) {
|
|
64516
|
+
try {
|
|
64517
|
+
await installer.markKitPending(ctx, lifecycle.kit, lifecycle.version);
|
|
64518
|
+
} catch (error) {
|
|
64519
|
+
logger.debug(`[${provider}] markKitPending failed: ${error}`);
|
|
64520
|
+
}
|
|
64521
|
+
}
|
|
64495
64522
|
results.push(await installer.install(ctx));
|
|
64496
64523
|
} catch (error) {
|
|
64497
64524
|
if (error instanceof Error && error.message === "Merge cancelled by user") {
|
|
@@ -64518,12 +64545,12 @@ import * as path8 from "node:path";
|
|
|
64518
64545
|
// src/domains/github/auth-prompt.ts
|
|
64519
64546
|
init_dist2();
|
|
64520
64547
|
init_github_auth();
|
|
64521
|
-
var
|
|
64548
|
+
var import_picocolors20 = __toESM(require_picocolors(), 1);
|
|
64522
64549
|
async function promptForAuth() {
|
|
64523
64550
|
const hasGit = GitCloneManager.isGitInstalled();
|
|
64524
64551
|
const hasSshKeys = hasGit && GitCloneManager.hasSshKeys();
|
|
64525
64552
|
const hasGhCli = AuthManager.isGhCliInstalled();
|
|
64526
|
-
oe(
|
|
64553
|
+
oe(import_picocolors20.default.yellow("No GitHub authentication found"));
|
|
64527
64554
|
const options2 = [];
|
|
64528
64555
|
if (hasGit) {
|
|
64529
64556
|
const hint = hasSshKeys ? "SSH keys detected" : "Will use HTTPS";
|
|
@@ -64576,7 +64603,7 @@ async function promptForAuth() {
|
|
|
64576
64603
|
return { method: "cancel" };
|
|
64577
64604
|
}
|
|
64578
64605
|
if (typeof token === "string" && token.startsWith("github_pat_")) {
|
|
64579
|
-
le(
|
|
64606
|
+
le(import_picocolors20.default.yellow(`⚠️ Fine-grained PATs cannot access repos where you're a collaborator.
|
|
64580
64607
|
` + " If you encounter access issues, use a Classic PAT instead."));
|
|
64581
64608
|
}
|
|
64582
64609
|
return { method: "token", token };
|
|
@@ -64617,7 +64644,7 @@ import { join as join86 } from "node:path";
|
|
|
64617
64644
|
// src/shared/progress-bar.ts
|
|
64618
64645
|
init_output_manager();
|
|
64619
64646
|
init_terminal_utils();
|
|
64620
|
-
var
|
|
64647
|
+
var import_picocolors21 = __toESM(require_picocolors(), 1);
|
|
64621
64648
|
var BAR_CHARS = {
|
|
64622
64649
|
unicode: { filled: "█", empty: "░" },
|
|
64623
64650
|
ascii: { filled: "=", empty: "-" }
|
|
@@ -64675,7 +64702,7 @@ class ProgressBar {
|
|
|
64675
64702
|
this.clearLine();
|
|
64676
64703
|
if (message) {
|
|
64677
64704
|
const symbols = output.getSymbols();
|
|
64678
|
-
console.log(`${
|
|
64705
|
+
console.log(`${import_picocolors21.default.green(symbols.success)} ${message}`);
|
|
64679
64706
|
}
|
|
64680
64707
|
}
|
|
64681
64708
|
clearLine() {
|
|
@@ -70506,7 +70533,7 @@ function filterDeletionPaths(trackedFiles, deletions) {
|
|
|
70506
70533
|
}
|
|
70507
70534
|
// src/domains/sync/merge-ui.ts
|
|
70508
70535
|
init_dist2();
|
|
70509
|
-
var
|
|
70536
|
+
var import_picocolors22 = __toESM(require_picocolors(), 1);
|
|
70510
70537
|
var HUNK_SEPARATOR_WIDTH = 50;
|
|
70511
70538
|
var EXTENDED_CONTEXT_LINES = 10;
|
|
70512
70539
|
var MAX_LINE_DISPLAY_LENGTH = 120;
|
|
@@ -70525,21 +70552,21 @@ class MergeUI {
|
|
|
70525
70552
|
static async promptHunk(hunk, hunkIndex, totalHunks, _filename) {
|
|
70526
70553
|
requireTTY();
|
|
70527
70554
|
const lineRange = `${hunk.oldStart}-${hunk.oldStart + hunk.oldLines - 1}`;
|
|
70528
|
-
console.log(
|
|
70555
|
+
console.log(import_picocolors22.default.cyan(`
|
|
70529
70556
|
Hunk ${hunkIndex + 1}/${totalHunks}: Lines ${lineRange}`));
|
|
70530
|
-
console.log(
|
|
70557
|
+
console.log(import_picocolors22.default.dim("─".repeat(HUNK_SEPARATOR_WIDTH)));
|
|
70531
70558
|
for (const line of hunk.lines) {
|
|
70532
70559
|
const displayLine = truncateLine(line);
|
|
70533
70560
|
const prefix = line[0];
|
|
70534
70561
|
if (prefix === "+") {
|
|
70535
|
-
console.log(
|
|
70562
|
+
console.log(import_picocolors22.default.green(displayLine));
|
|
70536
70563
|
} else if (prefix === "-") {
|
|
70537
|
-
console.log(
|
|
70564
|
+
console.log(import_picocolors22.default.red(displayLine));
|
|
70538
70565
|
} else {
|
|
70539
|
-
console.log(
|
|
70566
|
+
console.log(import_picocolors22.default.dim(displayLine));
|
|
70540
70567
|
}
|
|
70541
70568
|
}
|
|
70542
|
-
console.log(
|
|
70569
|
+
console.log(import_picocolors22.default.dim("─".repeat(HUNK_SEPARATOR_WIDTH)));
|
|
70543
70570
|
const action = await ie({
|
|
70544
70571
|
message: "Action?",
|
|
70545
70572
|
options: [
|
|
@@ -70559,21 +70586,21 @@ Hunk ${hunkIndex + 1}/${totalHunks}: Lines ${lineRange}`));
|
|
|
70559
70586
|
`);
|
|
70560
70587
|
const startLine = Math.max(0, hunk.oldStart - 1 - contextLines);
|
|
70561
70588
|
const endLine = Math.min(lines.length, hunk.oldStart + hunk.oldLines - 1 + contextLines);
|
|
70562
|
-
console.log(
|
|
70589
|
+
console.log(import_picocolors22.default.cyan(`
|
|
70563
70590
|
Extended context (lines ${startLine + 1}-${endLine}):`));
|
|
70564
|
-
console.log(
|
|
70591
|
+
console.log(import_picocolors22.default.dim("─".repeat(HUNK_SEPARATOR_WIDTH)));
|
|
70565
70592
|
for (let i = startLine;i < endLine; i++) {
|
|
70566
70593
|
const lineNum = String(i + 1).padStart(4, " ");
|
|
70567
70594
|
const isInHunk = i >= hunk.oldStart - 1 && i < hunk.oldStart - 1 + hunk.oldLines;
|
|
70568
|
-
const prefix = isInHunk ?
|
|
70569
|
-
console.log(`${
|
|
70595
|
+
const prefix = isInHunk ? import_picocolors22.default.yellow("*") : " ";
|
|
70596
|
+
console.log(`${import_picocolors22.default.dim(lineNum)} ${prefix} ${lines[i]}`);
|
|
70570
70597
|
}
|
|
70571
|
-
console.log(
|
|
70598
|
+
console.log(import_picocolors22.default.dim("─".repeat(HUNK_SEPARATOR_WIDTH)));
|
|
70572
70599
|
}
|
|
70573
70600
|
static async mergeFile(filename, currentContent, _newContent, hunks) {
|
|
70574
|
-
console.log(
|
|
70601
|
+
console.log(import_picocolors22.default.bold(`
|
|
70575
70602
|
━━━ ${filename} ━━━`));
|
|
70576
|
-
console.log(
|
|
70603
|
+
console.log(import_picocolors22.default.dim(`${hunks.length} change${hunks.length === 1 ? "" : "s"} to review
|
|
70577
70604
|
`));
|
|
70578
70605
|
const decisions = [];
|
|
70579
70606
|
for (let i = 0;i < hunks.length; i++) {
|
|
@@ -70596,19 +70623,19 @@ Extended context (lines ${startLine + 1}-${endLine}):`));
|
|
|
70596
70623
|
}
|
|
70597
70624
|
static displayMergeSummary(filename, applied, rejected) {
|
|
70598
70625
|
if (applied > 0 && rejected > 0) {
|
|
70599
|
-
console.log(
|
|
70626
|
+
console.log(import_picocolors22.default.dim(` ${filename}: `) + import_picocolors22.default.green(`${applied} applied`) + import_picocolors22.default.dim(", ") + import_picocolors22.default.yellow(`${rejected} rejected`));
|
|
70600
70627
|
} else if (applied > 0) {
|
|
70601
|
-
console.log(
|
|
70628
|
+
console.log(import_picocolors22.default.dim(` ${filename}: `) + import_picocolors22.default.green(`${applied} applied`));
|
|
70602
70629
|
} else {
|
|
70603
|
-
console.log(
|
|
70630
|
+
console.log(import_picocolors22.default.dim(` ${filename}: `) + import_picocolors22.default.yellow(`${rejected} rejected`));
|
|
70604
70631
|
}
|
|
70605
70632
|
}
|
|
70606
70633
|
static displaySkipped(filename) {
|
|
70607
|
-
console.log(
|
|
70634
|
+
console.log(import_picocolors22.default.dim(` ${filename}: `) + import_picocolors22.default.yellow("skipped"));
|
|
70608
70635
|
}
|
|
70609
70636
|
}
|
|
70610
70637
|
// src/domains/sync/notification-display.ts
|
|
70611
|
-
var
|
|
70638
|
+
var import_picocolors23 = __toESM(require_picocolors(), 1);
|
|
70612
70639
|
import { stdout } from "node:process";
|
|
70613
70640
|
function createNotificationBox(borderColor, boxWidth) {
|
|
70614
70641
|
const contentWidth = boxWidth - 2;
|
|
@@ -70632,19 +70659,19 @@ function displayConfigUpdateNotification(entries, isGlobal = false) {
|
|
|
70632
70659
|
const lines = entries.map(({ kit, currentVersion, latestVersion }) => {
|
|
70633
70660
|
const cur = currentVersion.replace(/^v/, "");
|
|
70634
70661
|
const latest = latestVersion.replace(/^v/, "");
|
|
70635
|
-
const text = `${
|
|
70662
|
+
const text = `${import_picocolors23.default.bold(kit)}: ${import_picocolors23.default.dim(cur)} ${import_picocolors23.default.white("→")} ${import_picocolors23.default.green(import_picocolors23.default.bold(latest))}`;
|
|
70636
70663
|
const visibleLen = kit.length + 2 + cur.length + 3 + latest.length;
|
|
70637
70664
|
return { text, visibleLen };
|
|
70638
70665
|
});
|
|
70639
70666
|
const updateCmd = isGlobal ? "tkm init -g --sync" : "tkm init --sync";
|
|
70640
|
-
const commandText = `Run: ${
|
|
70667
|
+
const commandText = `Run: ${import_picocolors23.default.cyan(import_picocolors23.default.bold(updateCmd))}`;
|
|
70641
70668
|
const commandLen = `Run: ${updateCmd}`.length;
|
|
70642
70669
|
const headerLabel = "\uD83D\uDCE6 Config Updates Available";
|
|
70643
|
-
const headerText =
|
|
70670
|
+
const headerText = import_picocolors23.default.bold(import_picocolors23.default.yellow(headerLabel));
|
|
70644
70671
|
const longestLine = Math.max(headerLabel.length, commandLen, ...lines.map((l2) => l2.visibleLen));
|
|
70645
70672
|
const terminalWidth = stdout.columns || 80;
|
|
70646
70673
|
const boxWidth = Math.min(Math.max(longestLine + 6, 52), terminalWidth - 4);
|
|
70647
|
-
const { topBorder, bottomBorder, emptyLine, padLine } = createNotificationBox(
|
|
70674
|
+
const { topBorder, bottomBorder, emptyLine, padLine } = createNotificationBox(import_picocolors23.default.cyan, boxWidth);
|
|
70648
70675
|
console.log("");
|
|
70649
70676
|
console.log(topBorder);
|
|
70650
70677
|
console.log(emptyLine);
|
|
@@ -70664,7 +70691,7 @@ init_logger();
|
|
|
70664
70691
|
init_logger();
|
|
70665
70692
|
init_path_resolver();
|
|
70666
70693
|
var import_fs_extra33 = __toESM(require_lib(), 1);
|
|
70667
|
-
var
|
|
70694
|
+
var import_picocolors24 = __toESM(require_picocolors(), 1);
|
|
70668
70695
|
async function handleSync(ctx) {
|
|
70669
70696
|
if (!ctx.options.sync) {
|
|
70670
70697
|
return ctx;
|
|
@@ -70849,7 +70876,7 @@ async function executeSyncMerge(ctx) {
|
|
|
70849
70876
|
}
|
|
70850
70877
|
const backupDir = PathResolver.getBackupDir();
|
|
70851
70878
|
await createBackup(ctx.claudeDir, trackedFiles, backupDir);
|
|
70852
|
-
logger.success(`Backup created at ${
|
|
70879
|
+
logger.success(`Backup created at ${import_picocolors24.default.dim(backupDir)}`);
|
|
70853
70880
|
if (plan.autoUpdate.length > 0) {
|
|
70854
70881
|
logger.info(`Auto-updating ${plan.autoUpdate.length} file(s)...`);
|
|
70855
70882
|
let updateSuccess = 0;
|
|
@@ -70959,22 +70986,22 @@ async function executeSyncMerge(ctx) {
|
|
|
70959
70986
|
totalRejected += result.rejected;
|
|
70960
70987
|
}
|
|
70961
70988
|
console.log("");
|
|
70962
|
-
console.log(
|
|
70963
|
-
console.log(
|
|
70989
|
+
console.log(import_picocolors24.default.bold("Sync Summary:"));
|
|
70990
|
+
console.log(import_picocolors24.default.dim("─".repeat(40)));
|
|
70964
70991
|
if (plan.autoUpdate.length > 0) {
|
|
70965
|
-
console.log(
|
|
70992
|
+
console.log(import_picocolors24.default.green(` ✓ ${plan.autoUpdate.length} file(s) auto-updated`));
|
|
70966
70993
|
}
|
|
70967
70994
|
if (totalApplied > 0) {
|
|
70968
|
-
console.log(
|
|
70995
|
+
console.log(import_picocolors24.default.green(` ✓ ${totalApplied} hunk(s) applied`));
|
|
70969
70996
|
}
|
|
70970
70997
|
if (totalRejected > 0) {
|
|
70971
|
-
console.log(
|
|
70998
|
+
console.log(import_picocolors24.default.yellow(` ○ ${totalRejected} hunk(s) rejected`));
|
|
70972
70999
|
}
|
|
70973
71000
|
if (skippedFiles > 0) {
|
|
70974
|
-
console.log(
|
|
71001
|
+
console.log(import_picocolors24.default.yellow(` ○ ${skippedFiles} file(s) skipped`));
|
|
70975
71002
|
}
|
|
70976
71003
|
if (plan.skipped.length > 0) {
|
|
70977
|
-
console.log(
|
|
71004
|
+
console.log(import_picocolors24.default.dim(` ─ ${plan.skipped.length} user-owned file(s) unchanged`));
|
|
70978
71005
|
}
|
|
70979
71006
|
} else if (plan.needsReview.length > 0 && ctx.isNonInteractive) {
|
|
70980
71007
|
logger.error(`Cannot complete sync: ${plan.needsReview.length} file(s) require interactive review`);
|
|
@@ -70997,30 +71024,30 @@ Options:
|
|
|
70997
71024
|
}
|
|
70998
71025
|
function displaySyncPlan(plan) {
|
|
70999
71026
|
console.log("");
|
|
71000
|
-
console.log(
|
|
71001
|
-
console.log(
|
|
71027
|
+
console.log(import_picocolors24.default.bold("Sync Plan:"));
|
|
71028
|
+
console.log(import_picocolors24.default.dim("─".repeat(40)));
|
|
71002
71029
|
if (plan.autoUpdate.length > 0) {
|
|
71003
|
-
console.log(
|
|
71030
|
+
console.log(import_picocolors24.default.green(` ${plan.autoUpdate.length} file(s) will be auto-updated`));
|
|
71004
71031
|
for (const file of plan.autoUpdate.slice(0, 5)) {
|
|
71005
|
-
console.log(
|
|
71032
|
+
console.log(import_picocolors24.default.dim(` • ${file.path}`));
|
|
71006
71033
|
}
|
|
71007
71034
|
if (plan.autoUpdate.length > 5) {
|
|
71008
|
-
console.log(
|
|
71035
|
+
console.log(import_picocolors24.default.dim(` ... and ${plan.autoUpdate.length - 5} more`));
|
|
71009
71036
|
}
|
|
71010
71037
|
}
|
|
71011
71038
|
if (plan.needsReview.length > 0) {
|
|
71012
|
-
console.log(
|
|
71039
|
+
console.log(import_picocolors24.default.yellow(` ${plan.needsReview.length} file(s) need interactive review`));
|
|
71013
71040
|
for (const file of plan.needsReview.slice(0, 5)) {
|
|
71014
|
-
console.log(
|
|
71041
|
+
console.log(import_picocolors24.default.dim(` • ${file.path}`));
|
|
71015
71042
|
}
|
|
71016
71043
|
if (plan.needsReview.length > 5) {
|
|
71017
|
-
console.log(
|
|
71044
|
+
console.log(import_picocolors24.default.dim(` ... and ${plan.needsReview.length - 5} more`));
|
|
71018
71045
|
}
|
|
71019
71046
|
}
|
|
71020
71047
|
if (plan.skipped.length > 0) {
|
|
71021
|
-
console.log(
|
|
71048
|
+
console.log(import_picocolors24.default.dim(` ${plan.skipped.length} user-owned file(s) will be skipped`));
|
|
71022
71049
|
}
|
|
71023
|
-
console.log(
|
|
71050
|
+
console.log(import_picocolors24.default.dim("─".repeat(40)));
|
|
71024
71051
|
}
|
|
71025
71052
|
async function createBackup(claudeDir, files, backupDir) {
|
|
71026
71053
|
await mkdir29(backupDir, { recursive: true });
|
|
@@ -71527,18 +71554,6 @@ async function executeInit(options2, prompts) {
|
|
|
71527
71554
|
ctx = await handleSelection(ctx);
|
|
71528
71555
|
if (ctx.cancelled)
|
|
71529
71556
|
return;
|
|
71530
|
-
if (ctx.resolvedDir && !isSyncMode) {
|
|
71531
|
-
try {
|
|
71532
|
-
const prefix = PathResolver.getPathPrefix(ctx.options.global);
|
|
71533
|
-
const claudeDir = prefix ? join102(ctx.resolvedDir, prefix) : ctx.resolvedDir;
|
|
71534
|
-
const pending = await ManifestWriter.findPendingKits(claudeDir);
|
|
71535
|
-
if (pending.length > 0) {
|
|
71536
|
-
logger.warning(`Previous install was interrupted for kit(s): ${pending.join(", ")}. Re-running install will overwrite the pending entry.`);
|
|
71537
|
-
}
|
|
71538
|
-
} catch (error) {
|
|
71539
|
-
logger.debug(`Pending-kit check skipped: ${error}`);
|
|
71540
|
-
}
|
|
71541
|
-
}
|
|
71542
71557
|
const selectedKits = ctx.selectedKits && ctx.selectedKits.length > 0 ? ctx.selectedKits : ctx.kitType ? [ctx.kitType] : [];
|
|
71543
71558
|
if (selectedKits.length === 0) {
|
|
71544
71559
|
logger.error("No kits resolved for installation");
|
|
@@ -71592,16 +71607,6 @@ async function executeInit(options2, prompts) {
|
|
|
71592
71607
|
}
|
|
71593
71608
|
lastCtx = { ...lastCtx, isLastKit };
|
|
71594
71609
|
}
|
|
71595
|
-
if (lastCtx.resolvedDir && lastCtx.release && !isSyncMode) {
|
|
71596
|
-
try {
|
|
71597
|
-
const prefix = PathResolver.getPathPrefix(lastCtx.options.global);
|
|
71598
|
-
const claudeDir = prefix ? join102(lastCtx.resolvedDir, prefix) : lastCtx.resolvedDir;
|
|
71599
|
-
const scope = lastCtx.options.global ? "global" : "local";
|
|
71600
|
-
await ManifestWriter.writeKitPending(claudeDir, currentKit, lastCtx.release.tag_name, scope);
|
|
71601
|
-
} catch (error) {
|
|
71602
|
-
logger.debug(`writeKitPending skipped: ${error}`);
|
|
71603
|
-
}
|
|
71604
|
-
}
|
|
71605
71610
|
lastCtx = await handleDownload(lastCtx);
|
|
71606
71611
|
if (lastCtx.cancelled)
|
|
71607
71612
|
return;
|
|
@@ -71615,7 +71620,8 @@ async function executeInit(options2, prompts) {
|
|
|
71615
71620
|
if (lastCtx.cancelled)
|
|
71616
71621
|
return;
|
|
71617
71622
|
}
|
|
71618
|
-
const
|
|
71623
|
+
const lifecycle = !isSyncMode && lastCtx.release ? { kit: currentKit, version: lastCtx.release.tag_name } : undefined;
|
|
71624
|
+
const kitResults = await dispatchInstallers(lastCtx, targetAgents, lifecycle);
|
|
71619
71625
|
aggregatedResults.push(...kitResults);
|
|
71620
71626
|
if (kitResults.some((r2) => r2.cancelled))
|
|
71621
71627
|
return;
|
|
@@ -71684,9 +71690,9 @@ async function initCommand(options2) {
|
|
|
71684
71690
|
import { existsSync as existsSync47 } from "node:fs";
|
|
71685
71691
|
import { readFile as readFile45, rm as rm13, unlink as unlink15 } from "node:fs/promises";
|
|
71686
71692
|
import { homedir as homedir25 } from "node:os";
|
|
71687
|
-
import { basename as basename12, join as
|
|
71693
|
+
import { basename as basename12, join as join102, resolve as resolve26 } from "node:path";
|
|
71688
71694
|
init_dist2();
|
|
71689
|
-
var
|
|
71695
|
+
var import_picocolors26 = __toESM(require_picocolors(), 1);
|
|
71690
71696
|
init_logger();
|
|
71691
71697
|
|
|
71692
71698
|
// src/commands/portable/migrated-hooks-cleanup.ts
|
|
@@ -71898,7 +71904,7 @@ function resolveProviderPath(pathValue) {
|
|
|
71898
71904
|
}
|
|
71899
71905
|
|
|
71900
71906
|
// src/commands/portable/plan-display.ts
|
|
71901
|
-
var
|
|
71907
|
+
var import_picocolors25 = __toESM(require_picocolors(), 1);
|
|
71902
71908
|
var DEFAULT_MAX_PLAN_GROUP_ITEMS = 20;
|
|
71903
71909
|
var TYPE_ORDER = ["agent", "command", "skill", "config", "rules", "hooks"];
|
|
71904
71910
|
var TYPE_LABELS = {
|
|
@@ -71971,7 +71977,7 @@ function printActionGroup(label, actions, prefix, colorName, options2) {
|
|
|
71971
71977
|
break;
|
|
71972
71978
|
const typeLabel = TYPE_LABELS[type];
|
|
71973
71979
|
const subHeader = ` ${typeLabel} (${typeActions.length})`;
|
|
71974
|
-
console.log(options2.color ?
|
|
71980
|
+
console.log(options2.color ? import_picocolors25.default.dim(subHeader) : subHeader);
|
|
71975
71981
|
const shown = typeActions.slice(0, remaining);
|
|
71976
71982
|
for (const action of shown) {
|
|
71977
71983
|
printAction(action, prefix, options2);
|
|
@@ -71980,7 +71986,7 @@ function printActionGroup(label, actions, prefix, colorName, options2) {
|
|
|
71980
71986
|
const hiddenInType = typeActions.length - shown.length;
|
|
71981
71987
|
if (hiddenInType > 0) {
|
|
71982
71988
|
const notice = ` ... and ${hiddenInType} more ${typeLabel.toLowerCase()}`;
|
|
71983
|
-
console.log(options2.color ?
|
|
71989
|
+
console.log(options2.color ? import_picocolors25.default.dim(notice) : notice);
|
|
71984
71990
|
}
|
|
71985
71991
|
}
|
|
71986
71992
|
}
|
|
@@ -71992,22 +71998,22 @@ function printAction(action, prefix, options2) {
|
|
|
71992
71998
|
if (action.reason) {
|
|
71993
71999
|
const reason = sanitizeSingleLineTerminalText(action.reason);
|
|
71994
72000
|
if (reason) {
|
|
71995
|
-
console.log(` ${options2.color ?
|
|
72001
|
+
console.log(` ${options2.color ? import_picocolors25.default.dim(reason) : reason}`);
|
|
71996
72002
|
}
|
|
71997
72003
|
}
|
|
71998
72004
|
}
|
|
71999
72005
|
function applyColor(text, colorName) {
|
|
72000
72006
|
switch (colorName) {
|
|
72001
72007
|
case "green":
|
|
72002
|
-
return
|
|
72008
|
+
return import_picocolors25.default.green(text);
|
|
72003
72009
|
case "yellow":
|
|
72004
|
-
return
|
|
72010
|
+
return import_picocolors25.default.yellow(text);
|
|
72005
72011
|
case "red":
|
|
72006
|
-
return
|
|
72012
|
+
return import_picocolors25.default.red(text);
|
|
72007
72013
|
case "magenta":
|
|
72008
|
-
return
|
|
72014
|
+
return import_picocolors25.default.magenta(text);
|
|
72009
72015
|
case "dim":
|
|
72010
|
-
return
|
|
72016
|
+
return import_picocolors25.default.dim(text);
|
|
72011
72017
|
default:
|
|
72012
72018
|
return text;
|
|
72013
72019
|
}
|
|
@@ -72041,19 +72047,19 @@ function displayMigrationSummary(plan, results, options2) {
|
|
|
72041
72047
|
const deleted = summary.delete;
|
|
72042
72048
|
const failed = resultSummary.failed;
|
|
72043
72049
|
if (installed > 0) {
|
|
72044
|
-
console.log(` ${options2.color ?
|
|
72050
|
+
console.log(` ${options2.color ? import_picocolors25.default.green("[OK]") : "[OK]"} ${installed} installed`);
|
|
72045
72051
|
}
|
|
72046
72052
|
if (updated > 0) {
|
|
72047
|
-
console.log(` ${options2.color ?
|
|
72053
|
+
console.log(` ${options2.color ? import_picocolors25.default.green("[OK]") : "[OK]"} ${updated} updated`);
|
|
72048
72054
|
}
|
|
72049
72055
|
if (skipped > 0) {
|
|
72050
|
-
console.log(` ${options2.color ?
|
|
72056
|
+
console.log(` ${options2.color ? import_picocolors25.default.dim("[i]") : "[i]"} ${skipped} skipped`);
|
|
72051
72057
|
}
|
|
72052
72058
|
if (deleted > 0) {
|
|
72053
|
-
console.log(` ${options2.color ?
|
|
72059
|
+
console.log(` ${options2.color ? import_picocolors25.default.dim("[-]") : "[-]"} ${deleted} deleted`);
|
|
72054
72060
|
}
|
|
72055
72061
|
if (failed > 0) {
|
|
72056
|
-
console.log(` ${options2.color ?
|
|
72062
|
+
console.log(` ${options2.color ? import_picocolors25.default.red("[X]") : "[X]"} ${failed} failed`);
|
|
72057
72063
|
}
|
|
72058
72064
|
const conflicts = plan.actions.filter((a3) => a3.action === "conflict");
|
|
72059
72065
|
if (conflicts.length > 0) {
|
|
@@ -72166,7 +72172,7 @@ async function executeDeleteAction(action, options2) {
|
|
|
72166
72172
|
async function processMetadataDeletions(skillSourcePath, installGlobally) {
|
|
72167
72173
|
if (!skillSourcePath)
|
|
72168
72174
|
return;
|
|
72169
|
-
const sourceMetadataPath =
|
|
72175
|
+
const sourceMetadataPath = join102(resolve26(skillSourcePath, ".."), "metadata.json");
|
|
72170
72176
|
if (!existsSync47(sourceMetadataPath))
|
|
72171
72177
|
return;
|
|
72172
72178
|
let sourceMetadata;
|
|
@@ -72179,7 +72185,7 @@ async function processMetadataDeletions(skillSourcePath, installGlobally) {
|
|
|
72179
72185
|
}
|
|
72180
72186
|
if (!sourceMetadata.deletions || sourceMetadata.deletions.length === 0)
|
|
72181
72187
|
return;
|
|
72182
|
-
const claudeDir = installGlobally ?
|
|
72188
|
+
const claudeDir = installGlobally ? join102(homedir25(), ".claude") : join102(process.cwd(), ".claude");
|
|
72183
72189
|
if (!existsSync47(claudeDir))
|
|
72184
72190
|
return;
|
|
72185
72191
|
try {
|
|
@@ -72193,7 +72199,7 @@ async function processMetadataDeletions(skillSourcePath, installGlobally) {
|
|
|
72193
72199
|
}
|
|
72194
72200
|
async function migrateCommand(options2) {
|
|
72195
72201
|
console.log();
|
|
72196
|
-
oe(
|
|
72202
|
+
oe(import_picocolors26.default.bgMagenta(import_picocolors26.default.black(" takumi migrate ")));
|
|
72197
72203
|
try {
|
|
72198
72204
|
const scope = resolveMigrationScope(process.argv.slice(2), options2);
|
|
72199
72205
|
const spinner = de();
|
|
@@ -72216,35 +72222,35 @@ async function migrateCommand(options2) {
|
|
|
72216
72222
|
const hasItems = agents.length > 0 || commands.length > 0 || skills.length > 0 || configItem !== null || ruleItems.length > 0 || hookItems.length > 0;
|
|
72217
72223
|
if (!hasItems) {
|
|
72218
72224
|
f2.error("Nothing to migrate.");
|
|
72219
|
-
f2.info(
|
|
72220
|
-
$e(
|
|
72225
|
+
f2.info(import_picocolors26.default.dim("Check .claude/agents/, .claude/commands/, .claude/skills/, .claude/rules/, .claude/hooks/, and CLAUDE.md (project or ~/.claude/)"));
|
|
72226
|
+
$e(import_picocolors26.default.red("Nothing to migrate"));
|
|
72221
72227
|
return;
|
|
72222
72228
|
}
|
|
72223
|
-
f2.info(
|
|
72229
|
+
f2.info(import_picocolors26.default.dim(` CWD: ${process.cwd()}`));
|
|
72224
72230
|
const parts = [];
|
|
72225
72231
|
if (agents.length > 0) {
|
|
72226
72232
|
const origin = resolveSourceOrigin(agentSource);
|
|
72227
|
-
parts.push(`${agents.length} agent(s) ${
|
|
72233
|
+
parts.push(`${agents.length} agent(s) ${import_picocolors26.default.dim(`<- ${origin}`)}`);
|
|
72228
72234
|
}
|
|
72229
72235
|
if (commands.length > 0) {
|
|
72230
72236
|
const origin = resolveSourceOrigin(commandSource);
|
|
72231
|
-
parts.push(`${commands.length} command(s) ${
|
|
72237
|
+
parts.push(`${commands.length} command(s) ${import_picocolors26.default.dim(`<- ${origin}`)}`);
|
|
72232
72238
|
}
|
|
72233
72239
|
if (skills.length > 0) {
|
|
72234
72240
|
const origin = resolveSourceOrigin(skillSource);
|
|
72235
|
-
parts.push(`${skills.length} skill(s) ${
|
|
72241
|
+
parts.push(`${skills.length} skill(s) ${import_picocolors26.default.dim(`<- ${origin}`)}`);
|
|
72236
72242
|
}
|
|
72237
72243
|
if (configItem) {
|
|
72238
72244
|
const origin = resolveSourceOrigin(configItem.sourcePath);
|
|
72239
|
-
parts.push(`config ${
|
|
72245
|
+
parts.push(`config ${import_picocolors26.default.dim(`<- ${origin}`)}`);
|
|
72240
72246
|
}
|
|
72241
72247
|
if (ruleItems.length > 0) {
|
|
72242
72248
|
const origin = resolveSourceOrigin(rulesSourcePath);
|
|
72243
|
-
parts.push(`${ruleItems.length} rule(s) ${
|
|
72249
|
+
parts.push(`${ruleItems.length} rule(s) ${import_picocolors26.default.dim(`<- ${origin}`)}`);
|
|
72244
72250
|
}
|
|
72245
72251
|
if (hookItems.length > 0) {
|
|
72246
72252
|
const origin = resolveSourceOrigin(hooksSource);
|
|
72247
|
-
parts.push(`${hookItems.length} hook(s) ${
|
|
72253
|
+
parts.push(`${hookItems.length} hook(s) ${import_picocolors26.default.dim(`<- ${origin}`)}`);
|
|
72248
72254
|
}
|
|
72249
72255
|
f2.info(`Found: ${parts.join(", ")}`);
|
|
72250
72256
|
const detectedProviders = await detectInstalledProviders();
|
|
@@ -72254,8 +72260,8 @@ async function migrateCommand(options2) {
|
|
|
72254
72260
|
const invalid = options2.agent.filter((a3) => !validProviders.includes(a3));
|
|
72255
72261
|
if (invalid.length > 0) {
|
|
72256
72262
|
f2.error(`Unknown provider(s): ${invalid.join(", ")}`);
|
|
72257
|
-
f2.info(
|
|
72258
|
-
$e(
|
|
72263
|
+
f2.info(import_picocolors26.default.dim(`Valid providers: ${validProviders.join(", ")}`));
|
|
72264
|
+
$e(import_picocolors26.default.red("Invalid provider"));
|
|
72259
72265
|
return;
|
|
72260
72266
|
}
|
|
72261
72267
|
selectedProviders = options2.agent;
|
|
@@ -72308,7 +72314,7 @@ async function migrateCommand(options2) {
|
|
|
72308
72314
|
}
|
|
72309
72315
|
} else if (detectedProviders.length === 1 || options2.yes) {
|
|
72310
72316
|
selectedProviders = detectedProviders;
|
|
72311
|
-
f2.info(`Migrating to: ${detectedProviders.map((a3) =>
|
|
72317
|
+
f2.info(`Migrating to: ${detectedProviders.map((a3) => import_picocolors26.default.cyan(providers[a3].displayName)).join(", ")}`);
|
|
72312
72318
|
} else {
|
|
72313
72319
|
const selected = await ae({
|
|
72314
72320
|
message: "Select providers to migrate to",
|
|
@@ -72327,8 +72333,8 @@ async function migrateCommand(options2) {
|
|
|
72327
72333
|
selectedProviders = Array.from(new Set(selectedProviders));
|
|
72328
72334
|
let installGlobally = options2.global ?? false;
|
|
72329
72335
|
if (options2.global === undefined && !options2.yes) {
|
|
72330
|
-
const projectTarget =
|
|
72331
|
-
const globalTarget =
|
|
72336
|
+
const projectTarget = join102(process.cwd(), ".claude");
|
|
72337
|
+
const globalTarget = join102(homedir25(), ".claude");
|
|
72332
72338
|
const scopeChoice = await ie({
|
|
72333
72339
|
message: "Installation scope",
|
|
72334
72340
|
options: [
|
|
@@ -72353,44 +72359,44 @@ async function migrateCommand(options2) {
|
|
|
72353
72359
|
const codexCommandsRequireGlobal = scope.commands && selectedProviders.includes("codex") && providers.codex.commands !== null && providers.codex.commands.projectPath === null;
|
|
72354
72360
|
if (codexCommandsRequireGlobal && !installGlobally) {
|
|
72355
72361
|
installGlobally = true;
|
|
72356
|
-
f2.info(
|
|
72362
|
+
f2.info(import_picocolors26.default.dim("Codex commands are global-only; scope adjusted to global."));
|
|
72357
72363
|
}
|
|
72358
72364
|
console.log();
|
|
72359
|
-
f2.step(
|
|
72365
|
+
f2.step(import_picocolors26.default.bold("Migrate Summary"));
|
|
72360
72366
|
if (agents.length > 0) {
|
|
72361
|
-
f2.message(` Agents: ${agents.map((a3) =>
|
|
72367
|
+
f2.message(` Agents: ${agents.map((a3) => import_picocolors26.default.cyan(a3.name)).join(", ")}`);
|
|
72362
72368
|
}
|
|
72363
72369
|
if (commands.length > 0) {
|
|
72364
|
-
const cmdNames = commands.map((c2) =>
|
|
72370
|
+
const cmdNames = commands.map((c2) => import_picocolors26.default.cyan(`/${c2.displayName || c2.name}`)).join(", ");
|
|
72365
72371
|
f2.message(` Commands: ${cmdNames}`);
|
|
72366
72372
|
}
|
|
72367
72373
|
if (skills.length > 0) {
|
|
72368
|
-
f2.message(` Skills: ${skills.map((s3) =>
|
|
72374
|
+
f2.message(` Skills: ${skills.map((s3) => import_picocolors26.default.cyan(s3.name)).join(", ")}`);
|
|
72369
72375
|
}
|
|
72370
72376
|
if (configItem) {
|
|
72371
72377
|
const lines = configItem.body.split(`
|
|
72372
72378
|
`).length;
|
|
72373
|
-
f2.message(` Config: ${
|
|
72379
|
+
f2.message(` Config: ${import_picocolors26.default.cyan("CLAUDE.md")} (${lines} lines)`);
|
|
72374
72380
|
}
|
|
72375
72381
|
if (ruleItems.length > 0) {
|
|
72376
|
-
f2.message(` Rules: ${
|
|
72382
|
+
f2.message(` Rules: ${import_picocolors26.default.cyan(`${ruleItems.length} file(s)`)}`);
|
|
72377
72383
|
}
|
|
72378
72384
|
if (hookItems.length > 0) {
|
|
72379
|
-
f2.message(` Hooks: ${
|
|
72385
|
+
f2.message(` Hooks: ${import_picocolors26.default.cyan(`${hookItems.length} file(s)`)}`);
|
|
72380
72386
|
}
|
|
72381
|
-
const providerNames = selectedProviders.map((prov) =>
|
|
72387
|
+
const providerNames = selectedProviders.map((prov) => import_picocolors26.default.cyan(providers[prov].displayName)).join(", ");
|
|
72382
72388
|
f2.message(` Providers: ${providerNames}`);
|
|
72383
|
-
const targetDir = installGlobally ?
|
|
72384
|
-
f2.message(` Scope: ${installGlobally ? "Global" : "Project"} ${
|
|
72389
|
+
const targetDir = installGlobally ? join102(homedir25(), ".claude") : join102(process.cwd(), ".claude");
|
|
72390
|
+
f2.message(` Scope: ${installGlobally ? "Global" : "Project"} ${import_picocolors26.default.dim(`-> ${targetDir}`)}`);
|
|
72385
72391
|
const cmdProviders = getProvidersSupporting("commands");
|
|
72386
72392
|
const unsupportedCmd = selectedProviders.filter((pv) => !cmdProviders.includes(pv));
|
|
72387
72393
|
if (commands.length > 0 && unsupportedCmd.length > 0) {
|
|
72388
|
-
f2.info(
|
|
72394
|
+
f2.info(import_picocolors26.default.dim(` [i] Commands skipped for: ${unsupportedCmd.map((pv) => providers[pv].displayName).join(", ")} (unsupported)`));
|
|
72389
72395
|
}
|
|
72390
72396
|
const hookProviders = getProvidersSupporting("hooks");
|
|
72391
72397
|
const unsupportedHooks = selectedProviders.filter((pv) => !hookProviders.includes(pv));
|
|
72392
72398
|
if (hookItems.length > 0 && unsupportedHooks.length > 0) {
|
|
72393
|
-
f2.info(
|
|
72399
|
+
f2.info(import_picocolors26.default.dim(` [i] Hooks skipped for: ${unsupportedHooks.map((pv) => providers[pv].displayName).join(", ")} (unsupported)`));
|
|
72394
72400
|
}
|
|
72395
72401
|
const { TakumiConfigManager: TakumiConfigManager2 } = await Promise.resolve().then(() => (init_takumi_config_manager(), exports_takumi_config_manager));
|
|
72396
72402
|
const ckConfigResult = await TakumiConfigManager2.loadFull(process.cwd());
|
|
@@ -72422,7 +72428,7 @@ async function migrateCommand(options2) {
|
|
|
72422
72428
|
displayReconcilePlan(plan, { color: useColor });
|
|
72423
72429
|
if (options2.dryRun) {
|
|
72424
72430
|
console.log();
|
|
72425
|
-
$e(
|
|
72431
|
+
$e(import_picocolors26.default.green("Dry run complete — no files written"));
|
|
72426
72432
|
return;
|
|
72427
72433
|
}
|
|
72428
72434
|
if (plan.hasConflicts) {
|
|
@@ -72640,14 +72646,14 @@ async function migrateCommand(options2) {
|
|
|
72640
72646
|
console.log();
|
|
72641
72647
|
displayResults3(allResults);
|
|
72642
72648
|
} else {
|
|
72643
|
-
$e(
|
|
72649
|
+
$e(import_picocolors26.default.green("Migration complete!"));
|
|
72644
72650
|
}
|
|
72645
72651
|
if (failed.length > 0 || hasEmbeddedPartialFailures) {
|
|
72646
72652
|
process.exitCode = 1;
|
|
72647
72653
|
}
|
|
72648
72654
|
} catch (error) {
|
|
72649
72655
|
logger.error(error instanceof Error ? error.message : "Unknown error");
|
|
72650
|
-
$e(
|
|
72656
|
+
$e(import_picocolors26.default.red("Migrate failed"));
|
|
72651
72657
|
process.exit(1);
|
|
72652
72658
|
}
|
|
72653
72659
|
}
|
|
@@ -72710,22 +72716,22 @@ function displayResults3(results) {
|
|
|
72710
72716
|
const failed = results.filter((r2) => !r2.success);
|
|
72711
72717
|
if (successful.length > 0) {
|
|
72712
72718
|
for (const r2 of successful) {
|
|
72713
|
-
f2.success(`${
|
|
72719
|
+
f2.success(`${import_picocolors26.default.green("[OK]")} ${r2.providerDisplayName}`);
|
|
72714
72720
|
if (r2.warnings) {
|
|
72715
72721
|
for (const w4 of r2.warnings) {
|
|
72716
|
-
f2.warn(` ${
|
|
72722
|
+
f2.warn(` ${import_picocolors26.default.yellow("[!]")} ${w4}`);
|
|
72717
72723
|
}
|
|
72718
72724
|
}
|
|
72719
72725
|
}
|
|
72720
72726
|
}
|
|
72721
72727
|
if (skipped.length > 0) {
|
|
72722
72728
|
for (const r2 of skipped) {
|
|
72723
|
-
f2.info(`${
|
|
72729
|
+
f2.info(`${import_picocolors26.default.yellow("[i]")} ${r2.providerDisplayName}: ${import_picocolors26.default.dim(r2.skipReason || "Skipped")}`);
|
|
72724
72730
|
}
|
|
72725
72731
|
}
|
|
72726
72732
|
if (failed.length > 0) {
|
|
72727
72733
|
for (const r2 of failed) {
|
|
72728
|
-
f2.error(`${
|
|
72734
|
+
f2.error(`${import_picocolors26.default.red("[X]")} ${r2.providerDisplayName}: ${import_picocolors26.default.dim(r2.error || "Failed")}`);
|
|
72729
72735
|
}
|
|
72730
72736
|
}
|
|
72731
72737
|
console.log();
|
|
@@ -72737,18 +72743,18 @@ function displayResults3(results) {
|
|
|
72737
72743
|
if (failed.length > 0)
|
|
72738
72744
|
summaryParts.push(`${failed.length} failed`);
|
|
72739
72745
|
if (summaryParts.length === 0) {
|
|
72740
|
-
$e(
|
|
72746
|
+
$e(import_picocolors26.default.yellow("No installations performed"));
|
|
72741
72747
|
} else if (failed.length > 0 && successful.length === 0) {
|
|
72742
|
-
$e(
|
|
72748
|
+
$e(import_picocolors26.default.red("Migrate failed"));
|
|
72743
72749
|
process.exit(1);
|
|
72744
72750
|
} else {
|
|
72745
|
-
$e(
|
|
72751
|
+
$e(import_picocolors26.default.green(`Done! ${summaryParts.join(", ")}`));
|
|
72746
72752
|
}
|
|
72747
72753
|
}
|
|
72748
72754
|
// src/commands/new/new-command.ts
|
|
72749
72755
|
init_logger();
|
|
72750
72756
|
init_types2();
|
|
72751
|
-
var
|
|
72757
|
+
var import_picocolors27 = __toESM(require_picocolors(), 1);
|
|
72752
72758
|
|
|
72753
72759
|
// src/commands/new/phases/directory-setup.ts
|
|
72754
72760
|
import { resolve as resolve27 } from "node:path";
|
|
@@ -72890,7 +72896,7 @@ async function handleDirectorySetup(ctx) {
|
|
|
72890
72896
|
};
|
|
72891
72897
|
}
|
|
72892
72898
|
// src/commands/new/phases/project-creation.ts
|
|
72893
|
-
import { join as
|
|
72899
|
+
import { join as join103 } from "node:path";
|
|
72894
72900
|
init_github_client();
|
|
72895
72901
|
init_logger();
|
|
72896
72902
|
init_output_manager();
|
|
@@ -73044,7 +73050,7 @@ async function projectCreation(kit, resolvedDir, validOptions, isNonInteractive2
|
|
|
73044
73050
|
output.section("Installing");
|
|
73045
73051
|
logger.verbose("Installation target", { directory: resolvedDir });
|
|
73046
73052
|
const merger = new FileMerger;
|
|
73047
|
-
const claudeDir =
|
|
73053
|
+
const claudeDir = join103(resolvedDir, ".claude");
|
|
73048
73054
|
merger.setMultiKitContext(claudeDir, kit);
|
|
73049
73055
|
if (validOptions.exclude && validOptions.exclude.length > 0) {
|
|
73050
73056
|
merger.addIgnorePatterns(validOptions.exclude);
|
|
@@ -73097,10 +73103,10 @@ async function handleProjectCreation(ctx) {
|
|
|
73097
73103
|
};
|
|
73098
73104
|
}
|
|
73099
73105
|
// src/commands/new/phases/post-setup.ts
|
|
73100
|
-
import { join as
|
|
73106
|
+
import { join as join105 } from "node:path";
|
|
73101
73107
|
|
|
73102
73108
|
// src/domains/installation/setup-wizard.ts
|
|
73103
|
-
import { join as
|
|
73109
|
+
import { join as join104 } from "node:path";
|
|
73104
73110
|
init_logger();
|
|
73105
73111
|
init_dist2();
|
|
73106
73112
|
var import_fs_extra36 = __toESM(require_lib(), 1);
|
|
@@ -73180,7 +73186,7 @@ async function parseEnvFile(path9) {
|
|
|
73180
73186
|
}
|
|
73181
73187
|
}
|
|
73182
73188
|
async function checkGlobalConfig() {
|
|
73183
|
-
const globalEnvPath =
|
|
73189
|
+
const globalEnvPath = join104(getClaudeDir(), ".env");
|
|
73184
73190
|
if (!await import_fs_extra36.pathExists(globalEnvPath))
|
|
73185
73191
|
return false;
|
|
73186
73192
|
const env2 = await parseEnvFile(globalEnvPath);
|
|
@@ -73196,7 +73202,7 @@ async function runSetupWizard(options2) {
|
|
|
73196
73202
|
let globalEnv = {};
|
|
73197
73203
|
const hasGlobalConfig = !isGlobal && await checkGlobalConfig();
|
|
73198
73204
|
if (!isGlobal) {
|
|
73199
|
-
const globalEnvPath =
|
|
73205
|
+
const globalEnvPath = join104(getClaudeDir(), ".env");
|
|
73200
73206
|
if (await import_fs_extra36.pathExists(globalEnvPath)) {
|
|
73201
73207
|
globalEnv = await parseEnvFile(globalEnvPath);
|
|
73202
73208
|
}
|
|
@@ -73259,7 +73265,7 @@ async function runSetupWizard(options2) {
|
|
|
73259
73265
|
}
|
|
73260
73266
|
}
|
|
73261
73267
|
await generateEnvFile(targetDir, values);
|
|
73262
|
-
f2.success(`Configuration saved to ${
|
|
73268
|
+
f2.success(`Configuration saved to ${join104(targetDir, ".env")}`);
|
|
73263
73269
|
return true;
|
|
73264
73270
|
}
|
|
73265
73271
|
async function promptForAdditionalGeminiKeys(primaryKey) {
|
|
@@ -73362,9 +73368,9 @@ async function postSetup(resolvedDir, validOptions, isNonInteractive2, prompts)
|
|
|
73362
73368
|
withSudo: validOptions.withSudo
|
|
73363
73369
|
});
|
|
73364
73370
|
}
|
|
73365
|
-
const claudeDir =
|
|
73371
|
+
const claudeDir = join105(resolvedDir, ".claude");
|
|
73366
73372
|
await promptSetupWizardIfNeeded({
|
|
73367
|
-
envPath:
|
|
73373
|
+
envPath: join105(claudeDir, ".env"),
|
|
73368
73374
|
claudeDir,
|
|
73369
73375
|
isGlobal: false,
|
|
73370
73376
|
isNonInteractive: isNonInteractive2,
|
|
@@ -73432,7 +73438,7 @@ Example: tkm new --use-git --release v2.1.0`);
|
|
|
73432
73438
|
if (ctx.cancelled)
|
|
73433
73439
|
return;
|
|
73434
73440
|
prompts.outro(`✨ Project created successfully at ${ctx.resolvedDir}`);
|
|
73435
|
-
log.info(`${
|
|
73441
|
+
log.info(`${import_picocolors27.default.dim("Tip:")} To update later: ${import_picocolors27.default.cyan("tkm update")} (CLI) + ${import_picocolors27.default.cyan("tkm init")} (kit content)`);
|
|
73436
73442
|
} catch (error) {
|
|
73437
73443
|
logger.error(error instanceof Error ? error.message : "Unknown error occurred");
|
|
73438
73444
|
process.exit(1);
|
|
@@ -73441,11 +73447,11 @@ Example: tkm new --use-git --release v2.1.0`);
|
|
|
73441
73447
|
// src/commands/plan/plan-command.ts
|
|
73442
73448
|
init_output_manager();
|
|
73443
73449
|
import { existsSync as existsSync52, statSync as statSync5 } from "node:fs";
|
|
73444
|
-
import { dirname as dirname33, join as
|
|
73450
|
+
import { dirname as dirname33, join as join109, parse as parse2, resolve as resolve31 } from "node:path";
|
|
73445
73451
|
|
|
73446
73452
|
// src/commands/plan/plan-read-handlers.ts
|
|
73447
73453
|
import { existsSync as existsSync51, statSync as statSync4 } from "node:fs";
|
|
73448
|
-
import { basename as basename15, dirname as dirname32, join as
|
|
73454
|
+
import { basename as basename15, dirname as dirname32, join as join108, relative as relative20, resolve as resolve29 } from "node:path";
|
|
73449
73455
|
|
|
73450
73456
|
// src/domains/plan-parser/index.ts
|
|
73451
73457
|
import { dirname as dirname31 } from "node:path";
|
|
@@ -73826,12 +73832,12 @@ function parsePlanFile(planFilePath, options2) {
|
|
|
73826
73832
|
}
|
|
73827
73833
|
// src/domains/plan-parser/plan-scanner.ts
|
|
73828
73834
|
import { existsSync as existsSync48, readdirSync as readdirSync5 } from "node:fs";
|
|
73829
|
-
import { join as
|
|
73835
|
+
import { join as join106 } from "node:path";
|
|
73830
73836
|
function scanPlanDir(dir) {
|
|
73831
73837
|
if (!existsSync48(dir))
|
|
73832
73838
|
return [];
|
|
73833
73839
|
try {
|
|
73834
|
-
return readdirSync5(dir, { withFileTypes: true }).filter((entry) => entry.isDirectory()).map((entry) =>
|
|
73840
|
+
return readdirSync5(dir, { withFileTypes: true }).filter((entry) => entry.isDirectory()).map((entry) => join106(dir, entry.name, "plan.md")).filter(existsSync48);
|
|
73835
73841
|
} catch {
|
|
73836
73842
|
return [];
|
|
73837
73843
|
}
|
|
@@ -73900,7 +73906,7 @@ function validatePlanFile(filePath, strict = false) {
|
|
|
73900
73906
|
var import_gray_matter7 = __toESM(require_gray_matter(), 1);
|
|
73901
73907
|
import { mkdirSync as mkdirSync3, readFileSync as readFileSync14, writeFileSync as writeFileSync5 } from "node:fs";
|
|
73902
73908
|
import { existsSync as existsSync50 } from "node:fs";
|
|
73903
|
-
import { basename as basename14, dirname as dirname30, join as
|
|
73909
|
+
import { basename as basename14, dirname as dirname30, join as join107 } from "node:path";
|
|
73904
73910
|
function phaseNameToFilename(id, name) {
|
|
73905
73911
|
const numMatch = /^(\d+)([a-z]*)$/i.exec(id);
|
|
73906
73912
|
const num = numMatch ? numMatch[1] : id;
|
|
@@ -74008,12 +74014,12 @@ function scaffoldPlan(options2) {
|
|
|
74008
74014
|
mkdirSync3(dir, { recursive: true });
|
|
74009
74015
|
const resolvedPhases = resolvePhaseIds(options2.phases);
|
|
74010
74016
|
const optionsWithResolved = { ...options2, phases: resolvedPhases };
|
|
74011
|
-
const planFile =
|
|
74017
|
+
const planFile = join107(dir, "plan.md");
|
|
74012
74018
|
writeFileSync5(planFile, generatePlanMd(optionsWithResolved), "utf8");
|
|
74013
74019
|
const phaseFiles = [];
|
|
74014
74020
|
for (const phase of resolvedPhases) {
|
|
74015
74021
|
const filename = phaseNameToFilename(phase.id, phase.name);
|
|
74016
|
-
const phaseFile =
|
|
74022
|
+
const phaseFile = join107(dir, filename);
|
|
74017
74023
|
writeFileSync5(phaseFile, generatePhaseTemplate(phase), "utf8");
|
|
74018
74024
|
phaseFiles.push(phaseFile);
|
|
74019
74025
|
}
|
|
@@ -74093,7 +74099,7 @@ function phaseNameFilenameFromTableRow(body, phaseId, planDir) {
|
|
|
74093
74099
|
continue;
|
|
74094
74100
|
const linkMatch = /\[([^\]]+)\]\(\.\/([^)]+)\)/.exec(row);
|
|
74095
74101
|
if (linkMatch)
|
|
74096
|
-
return
|
|
74102
|
+
return join107(planDir, linkMatch[2]);
|
|
74097
74103
|
}
|
|
74098
74104
|
return null;
|
|
74099
74105
|
}
|
|
@@ -74174,7 +74180,7 @@ function addPhase(planFile, name, afterId) {
|
|
|
74174
74180
|
`);
|
|
74175
74181
|
}
|
|
74176
74182
|
writeFileSync5(planFile, import_gray_matter7.default.stringify(updatedBody, frontmatter), "utf8");
|
|
74177
|
-
const phaseFilePath =
|
|
74183
|
+
const phaseFilePath = join107(planDir, filename);
|
|
74178
74184
|
writeFileSync5(phaseFilePath, generatePhaseTemplate({ id: phaseId, name }), "utf8");
|
|
74179
74185
|
return { phaseId, phaseFile: phaseFilePath };
|
|
74180
74186
|
}
|
|
@@ -74202,7 +74208,7 @@ function buildPlanSummary(planFile) {
|
|
|
74202
74208
|
// src/commands/plan/plan-read-handlers.ts
|
|
74203
74209
|
init_logger();
|
|
74204
74210
|
init_output_manager();
|
|
74205
|
-
var
|
|
74211
|
+
var import_picocolors28 = __toESM(require_picocolors(), 1);
|
|
74206
74212
|
async function handleParse(target, options2) {
|
|
74207
74213
|
const planFile = resolvePlanFile(target);
|
|
74208
74214
|
if (!planFile) {
|
|
@@ -74225,7 +74231,7 @@ async function handleParse(target, options2) {
|
|
|
74225
74231
|
}
|
|
74226
74232
|
const title = typeof frontmatter.title === "string" ? frontmatter.title : basename15(dirname32(planFile));
|
|
74227
74233
|
console.log();
|
|
74228
|
-
console.log(
|
|
74234
|
+
console.log(import_picocolors28.default.bold(` Plan: ${title}`));
|
|
74229
74235
|
console.log(` File: ${planFile}`);
|
|
74230
74236
|
console.log(` Phases found: ${phases.length}`);
|
|
74231
74237
|
console.log();
|
|
@@ -74256,7 +74262,7 @@ async function handleValidate(target, options2) {
|
|
|
74256
74262
|
return;
|
|
74257
74263
|
}
|
|
74258
74264
|
console.log();
|
|
74259
|
-
console.log(
|
|
74265
|
+
console.log(import_picocolors28.default.bold(` Validating: ${planFile}`));
|
|
74260
74266
|
console.log();
|
|
74261
74267
|
if (result.issues.length === 0) {
|
|
74262
74268
|
console.log(` [OK] No issues found — ${result.phases.length} phases detected`);
|
|
@@ -74270,7 +74276,7 @@ async function handleValidate(target, options2) {
|
|
|
74270
74276
|
}
|
|
74271
74277
|
}
|
|
74272
74278
|
console.log();
|
|
74273
|
-
const validStr = result.valid ?
|
|
74279
|
+
const validStr = result.valid ? import_picocolors28.default.green("[OK] Valid") : import_picocolors28.default.red("[X] Invalid");
|
|
74274
74280
|
console.log(` ${validStr} — ${result.issues.filter((i) => i.severity === "error").length} errors, ${result.issues.filter((i) => i.severity === "warning").length} warnings`);
|
|
74275
74281
|
console.log();
|
|
74276
74282
|
if (!result.valid)
|
|
@@ -74278,7 +74284,7 @@ async function handleValidate(target, options2) {
|
|
|
74278
74284
|
}
|
|
74279
74285
|
async function handleStatus(target, options2) {
|
|
74280
74286
|
const t = target ? resolve29(target) : null;
|
|
74281
|
-
const plansDir = t && existsSync51(t) && statSync4(t).isDirectory() && !existsSync51(
|
|
74287
|
+
const plansDir = t && existsSync51(t) && statSync4(t).isDirectory() && !existsSync51(join108(t, "plan.md")) ? t : null;
|
|
74282
74288
|
if (plansDir) {
|
|
74283
74289
|
const planFiles = scanPlanDir(plansDir);
|
|
74284
74290
|
if (planFiles.length === 0) {
|
|
@@ -74297,14 +74303,14 @@ async function handleStatus(target, options2) {
|
|
|
74297
74303
|
return;
|
|
74298
74304
|
}
|
|
74299
74305
|
console.log();
|
|
74300
|
-
console.log(
|
|
74306
|
+
console.log(import_picocolors28.default.bold(` Plans in: ${plansDir}`));
|
|
74301
74307
|
console.log();
|
|
74302
74308
|
for (const pf of planFiles) {
|
|
74303
74309
|
try {
|
|
74304
74310
|
const s3 = buildPlanSummary(pf);
|
|
74305
74311
|
const bar = progressBar(s3.completed, s3.totalPhases);
|
|
74306
74312
|
const title2 = s3.title ?? basename15(dirname32(pf));
|
|
74307
|
-
console.log(` ${
|
|
74313
|
+
console.log(` ${import_picocolors28.default.bold(title2)}`);
|
|
74308
74314
|
console.log(` ${bar}`);
|
|
74309
74315
|
if (s3.inProgress > 0)
|
|
74310
74316
|
console.log(` [~] ${s3.inProgress} in progress`);
|
|
@@ -74336,7 +74342,7 @@ async function handleStatus(target, options2) {
|
|
|
74336
74342
|
}
|
|
74337
74343
|
const title = summary.title ?? basename15(dirname32(planFile));
|
|
74338
74344
|
console.log();
|
|
74339
|
-
console.log(
|
|
74345
|
+
console.log(import_picocolors28.default.bold(` ${title}`));
|
|
74340
74346
|
if (summary.status)
|
|
74341
74347
|
console.log(` Status: ${summary.status}`);
|
|
74342
74348
|
console.log();
|
|
@@ -74362,7 +74368,7 @@ async function handleKanban(target, _options) {
|
|
|
74362
74368
|
// src/commands/plan/plan-write-handlers.ts
|
|
74363
74369
|
import { basename as basename16, relative as relative21, resolve as resolve30 } from "node:path";
|
|
74364
74370
|
init_output_manager();
|
|
74365
|
-
var
|
|
74371
|
+
var import_picocolors29 = __toESM(require_picocolors(), 1);
|
|
74366
74372
|
async function handleCreate(target, options2) {
|
|
74367
74373
|
if (!options2.title) {
|
|
74368
74374
|
output.error("[X] --title is required for create");
|
|
@@ -74409,7 +74415,7 @@ async function handleCreate(target, options2) {
|
|
|
74409
74415
|
return;
|
|
74410
74416
|
}
|
|
74411
74417
|
console.log();
|
|
74412
|
-
console.log(
|
|
74418
|
+
console.log(import_picocolors29.default.bold(` [OK] Plan created: ${options2.title}`));
|
|
74413
74419
|
console.log(` Directory: ${resolve30(dir)}`);
|
|
74414
74420
|
console.log(` Phases: ${result.phaseFiles.length}`);
|
|
74415
74421
|
for (const f4 of result.phaseFiles) {
|
|
@@ -74513,7 +74519,7 @@ function resolvePlanFile(target) {
|
|
|
74513
74519
|
const stat13 = statSync5(t);
|
|
74514
74520
|
if (stat13.isFile())
|
|
74515
74521
|
return t;
|
|
74516
|
-
const candidate =
|
|
74522
|
+
const candidate = join109(t, "plan.md");
|
|
74517
74523
|
if (existsSync52(candidate))
|
|
74518
74524
|
return candidate;
|
|
74519
74525
|
}
|
|
@@ -74521,7 +74527,7 @@ function resolvePlanFile(target) {
|
|
|
74521
74527
|
let dir = process.cwd();
|
|
74522
74528
|
const root = parse2(dir).root;
|
|
74523
74529
|
while (dir !== root) {
|
|
74524
|
-
const candidate =
|
|
74530
|
+
const candidate = join109(dir, "plan.md");
|
|
74525
74531
|
if (existsSync52(candidate))
|
|
74526
74532
|
return candidate;
|
|
74527
74533
|
dir = dirname33(dir);
|
|
@@ -74616,7 +74622,7 @@ import { resolve as resolve32 } from "node:path";
|
|
|
74616
74622
|
init_logger();
|
|
74617
74623
|
// src/commands/projects/add-handler.ts
|
|
74618
74624
|
init_logger();
|
|
74619
|
-
var
|
|
74625
|
+
var import_picocolors30 = __toESM(require_picocolors(), 1);
|
|
74620
74626
|
async function handleAdd(projectPath, options2) {
|
|
74621
74627
|
logger.debug(`Adding project: ${projectPath}, options: ${JSON.stringify(options2)}`);
|
|
74622
74628
|
intro("Add Project");
|
|
@@ -74632,10 +74638,10 @@ async function handleAdd(projectPath, options2) {
|
|
|
74632
74638
|
const existing = await ProjectsRegistryManager.getProject(absolutePath);
|
|
74633
74639
|
if (existing) {
|
|
74634
74640
|
console.log();
|
|
74635
|
-
console.log(
|
|
74636
|
-
console.log(
|
|
74637
|
-
console.log(
|
|
74638
|
-
console.log(
|
|
74641
|
+
console.log(import_picocolors30.default.dim(" Existing registration:"));
|
|
74642
|
+
console.log(import_picocolors30.default.dim(` Alias: ${import_picocolors30.default.cyan(existing.alias)}`));
|
|
74643
|
+
console.log(import_picocolors30.default.dim(` Path: ${existing.path}`));
|
|
74644
|
+
console.log(import_picocolors30.default.dim(` ID: ${existing.id}`));
|
|
74639
74645
|
console.log();
|
|
74640
74646
|
}
|
|
74641
74647
|
process.exitCode = 1;
|
|
@@ -74650,15 +74656,15 @@ async function handleAdd(projectPath, options2) {
|
|
|
74650
74656
|
});
|
|
74651
74657
|
log.success("Project registered successfully");
|
|
74652
74658
|
console.log();
|
|
74653
|
-
console.log(
|
|
74654
|
-
console.log(
|
|
74655
|
-
console.log(
|
|
74656
|
-
console.log(
|
|
74659
|
+
console.log(import_picocolors30.default.dim(" Details:"));
|
|
74660
|
+
console.log(import_picocolors30.default.dim(` Alias: ${import_picocolors30.default.cyan(project.alias)}`));
|
|
74661
|
+
console.log(import_picocolors30.default.dim(` Path: ${project.path}`));
|
|
74662
|
+
console.log(import_picocolors30.default.dim(` ID: ${project.id}`));
|
|
74657
74663
|
if (project.pinned) {
|
|
74658
|
-
console.log(
|
|
74664
|
+
console.log(import_picocolors30.default.dim(` Pinned: ${import_picocolors30.default.yellow("Yes")}`));
|
|
74659
74665
|
}
|
|
74660
74666
|
if (project.tags?.length) {
|
|
74661
|
-
console.log(
|
|
74667
|
+
console.log(import_picocolors30.default.dim(` Tags: ${project.tags.join(", ")}`));
|
|
74662
74668
|
}
|
|
74663
74669
|
console.log();
|
|
74664
74670
|
outro("Done!");
|
|
@@ -74670,7 +74676,7 @@ async function handleAdd(projectPath, options2) {
|
|
|
74670
74676
|
|
|
74671
74677
|
// src/commands/projects/list-handler.ts
|
|
74672
74678
|
init_logger();
|
|
74673
|
-
var
|
|
74679
|
+
var import_picocolors31 = __toESM(require_picocolors(), 1);
|
|
74674
74680
|
async function handleList(options2) {
|
|
74675
74681
|
logger.debug(`Listing projects: ${JSON.stringify(options2)}`);
|
|
74676
74682
|
const projects = await ProjectsRegistryManager.listProjects({
|
|
@@ -74682,25 +74688,25 @@ async function handleList(options2) {
|
|
|
74682
74688
|
}
|
|
74683
74689
|
if (projects.length === 0) {
|
|
74684
74690
|
console.log();
|
|
74685
|
-
console.log(
|
|
74691
|
+
console.log(import_picocolors31.default.yellow("No projects registered yet."));
|
|
74686
74692
|
console.log();
|
|
74687
|
-
console.log(
|
|
74688
|
-
console.log(
|
|
74693
|
+
console.log(import_picocolors31.default.dim(" Add a project with:"));
|
|
74694
|
+
console.log(import_picocolors31.default.dim(" takumi projects add <path>"));
|
|
74689
74695
|
console.log();
|
|
74690
74696
|
return;
|
|
74691
74697
|
}
|
|
74692
74698
|
console.log();
|
|
74693
|
-
console.log(
|
|
74699
|
+
console.log(import_picocolors31.default.bold(`Registered Projects (${projects.length})`));
|
|
74694
74700
|
console.log();
|
|
74695
74701
|
const aliasWidth = Math.max(5, ...projects.map((p2) => p2.alias.length));
|
|
74696
74702
|
const pathWidth = Math.max(4, ...projects.map((p2) => p2.path.length));
|
|
74697
|
-
console.log(
|
|
74698
|
-
console.log(
|
|
74703
|
+
console.log(import_picocolors31.default.dim(` ${"ALIAS".padEnd(aliasWidth)} ${"PATH".padEnd(pathWidth)} PINNED TAGS`));
|
|
74704
|
+
console.log(import_picocolors31.default.dim(` ${"-".repeat(aliasWidth + pathWidth + 20)}`));
|
|
74699
74705
|
for (const project of projects) {
|
|
74700
|
-
const alias =
|
|
74701
|
-
const path9 =
|
|
74702
|
-
const pinned = project.pinned ?
|
|
74703
|
-
const tags = project.tags?.length ?
|
|
74706
|
+
const alias = import_picocolors31.default.cyan(project.alias.padEnd(aliasWidth));
|
|
74707
|
+
const path9 = import_picocolors31.default.dim(project.path.padEnd(pathWidth));
|
|
74708
|
+
const pinned = project.pinned ? import_picocolors31.default.yellow("\uD83D\uDCCC") : " ";
|
|
74709
|
+
const tags = project.tags?.length ? import_picocolors31.default.gray(project.tags.join(", ")) : import_picocolors31.default.dim("-");
|
|
74704
74710
|
console.log(` ${alias} ${path9} ${pinned} ${tags}`);
|
|
74705
74711
|
}
|
|
74706
74712
|
console.log();
|
|
@@ -74708,7 +74714,7 @@ async function handleList(options2) {
|
|
|
74708
74714
|
|
|
74709
74715
|
// src/commands/projects/remove-handler.ts
|
|
74710
74716
|
init_logger();
|
|
74711
|
-
var
|
|
74717
|
+
var import_picocolors32 = __toESM(require_picocolors(), 1);
|
|
74712
74718
|
async function handleRemove(aliasOrPath, options2) {
|
|
74713
74719
|
logger.debug(`Removing project: ${aliasOrPath}, options: ${JSON.stringify(options2)}`);
|
|
74714
74720
|
intro("Remove Project");
|
|
@@ -74727,7 +74733,7 @@ async function handleRemove(aliasOrPath, options2) {
|
|
|
74727
74733
|
message: "Select a project to remove",
|
|
74728
74734
|
options: projects.map((p2) => ({
|
|
74729
74735
|
value: p2.id,
|
|
74730
|
-
label: `${
|
|
74736
|
+
label: `${import_picocolors32.default.cyan(p2.alias)} ${import_picocolors32.default.dim(`(${p2.path})`)}`
|
|
74731
74737
|
}))
|
|
74732
74738
|
});
|
|
74733
74739
|
if (lD(selected)) {
|
|
@@ -74744,10 +74750,10 @@ async function handleRemove(aliasOrPath, options2) {
|
|
|
74744
74750
|
return;
|
|
74745
74751
|
}
|
|
74746
74752
|
console.log();
|
|
74747
|
-
console.log(
|
|
74748
|
-
console.log(
|
|
74749
|
-
console.log(
|
|
74750
|
-
console.log(
|
|
74753
|
+
console.log(import_picocolors32.default.dim(" Project to remove:"));
|
|
74754
|
+
console.log(import_picocolors32.default.dim(` Alias: ${import_picocolors32.default.cyan(project.alias)}`));
|
|
74755
|
+
console.log(import_picocolors32.default.dim(` Path: ${project.path}`));
|
|
74756
|
+
console.log(import_picocolors32.default.dim(` ID: ${project.id}`));
|
|
74751
74757
|
console.log();
|
|
74752
74758
|
const confirmed = await se({
|
|
74753
74759
|
message: "Are you sure you want to remove this project?",
|
|
@@ -74788,117 +74794,117 @@ function registerProjectsCommand(cli) {
|
|
|
74788
74794
|
// src/commands/skills/skills-command.ts
|
|
74789
74795
|
init_dist2();
|
|
74790
74796
|
init_logger();
|
|
74791
|
-
var
|
|
74797
|
+
var import_picocolors33 = __toESM(require_picocolors(), 1);
|
|
74792
74798
|
|
|
74793
74799
|
// src/commands/skills/agents.ts
|
|
74794
74800
|
import { existsSync as existsSync54 } from "node:fs";
|
|
74795
74801
|
import { homedir as homedir26 } from "node:os";
|
|
74796
|
-
import { join as
|
|
74802
|
+
import { join as join110 } from "node:path";
|
|
74797
74803
|
var home6 = homedir26();
|
|
74798
74804
|
var agents = {
|
|
74799
74805
|
"claude-code": {
|
|
74800
74806
|
name: "claude-code",
|
|
74801
74807
|
displayName: "Claude Code",
|
|
74802
74808
|
projectPath: ".claude/skills",
|
|
74803
|
-
globalPath:
|
|
74804
|
-
detect: async () => existsSync54(
|
|
74809
|
+
globalPath: join110(home6, ".claude/skills"),
|
|
74810
|
+
detect: async () => existsSync54(join110(home6, ".claude"))
|
|
74805
74811
|
},
|
|
74806
74812
|
cursor: {
|
|
74807
74813
|
name: "cursor",
|
|
74808
74814
|
displayName: "Cursor",
|
|
74809
74815
|
projectPath: ".cursor/skills",
|
|
74810
|
-
globalPath:
|
|
74811
|
-
detect: async () => existsSync54(
|
|
74816
|
+
globalPath: join110(home6, ".cursor/skills"),
|
|
74817
|
+
detect: async () => existsSync54(join110(home6, ".cursor"))
|
|
74812
74818
|
},
|
|
74813
74819
|
codex: {
|
|
74814
74820
|
name: "codex",
|
|
74815
74821
|
displayName: "Codex",
|
|
74816
74822
|
projectPath: ".codex/skills",
|
|
74817
|
-
globalPath:
|
|
74818
|
-
detect: async () => existsSync54(
|
|
74823
|
+
globalPath: join110(home6, ".codex/skills"),
|
|
74824
|
+
detect: async () => existsSync54(join110(home6, ".codex"))
|
|
74819
74825
|
},
|
|
74820
74826
|
opencode: {
|
|
74821
74827
|
name: "opencode",
|
|
74822
74828
|
displayName: "OpenCode",
|
|
74823
74829
|
projectPath: ".opencode/skills",
|
|
74824
|
-
globalPath:
|
|
74825
|
-
detect: async () => existsSync54(
|
|
74830
|
+
globalPath: join110(home6, ".config/opencode/skills"),
|
|
74831
|
+
detect: async () => existsSync54(join110(home6, ".config/opencode"))
|
|
74826
74832
|
},
|
|
74827
74833
|
goose: {
|
|
74828
74834
|
name: "goose",
|
|
74829
74835
|
displayName: "Goose",
|
|
74830
74836
|
projectPath: ".goose/skills",
|
|
74831
|
-
globalPath:
|
|
74832
|
-
detect: async () => existsSync54(
|
|
74837
|
+
globalPath: join110(home6, ".config/goose/skills"),
|
|
74838
|
+
detect: async () => existsSync54(join110(home6, ".config/goose"))
|
|
74833
74839
|
},
|
|
74834
74840
|
"gemini-cli": {
|
|
74835
74841
|
name: "gemini-cli",
|
|
74836
74842
|
displayName: "Gemini CLI",
|
|
74837
74843
|
projectPath: ".agents/skills",
|
|
74838
|
-
globalPath:
|
|
74839
|
-
detect: async () => existsSync54(
|
|
74844
|
+
globalPath: join110(home6, ".agents/skills"),
|
|
74845
|
+
detect: async () => existsSync54(join110(home6, ".gemini"))
|
|
74840
74846
|
},
|
|
74841
74847
|
antigravity: {
|
|
74842
74848
|
name: "antigravity",
|
|
74843
74849
|
displayName: "Antigravity",
|
|
74844
74850
|
projectPath: ".agent/skills",
|
|
74845
|
-
globalPath:
|
|
74846
|
-
detect: async () => existsSync54(
|
|
74851
|
+
globalPath: join110(home6, ".gemini/antigravity/skills"),
|
|
74852
|
+
detect: async () => existsSync54(join110(process.cwd(), ".agent")) || existsSync54(join110(home6, ".gemini/antigravity"))
|
|
74847
74853
|
},
|
|
74848
74854
|
"github-copilot": {
|
|
74849
74855
|
name: "github-copilot",
|
|
74850
74856
|
displayName: "GitHub Copilot",
|
|
74851
74857
|
projectPath: ".github/skills",
|
|
74852
|
-
globalPath:
|
|
74853
|
-
detect: async () => existsSync54(
|
|
74858
|
+
globalPath: join110(home6, ".copilot/skills"),
|
|
74859
|
+
detect: async () => existsSync54(join110(home6, ".copilot"))
|
|
74854
74860
|
},
|
|
74855
74861
|
amp: {
|
|
74856
74862
|
name: "amp",
|
|
74857
74863
|
displayName: "Amp",
|
|
74858
74864
|
projectPath: ".agents/skills",
|
|
74859
|
-
globalPath:
|
|
74860
|
-
detect: async () => existsSync54(
|
|
74865
|
+
globalPath: join110(home6, ".config/agents/skills"),
|
|
74866
|
+
detect: async () => existsSync54(join110(home6, ".config/amp"))
|
|
74861
74867
|
},
|
|
74862
74868
|
kilo: {
|
|
74863
74869
|
name: "kilo",
|
|
74864
74870
|
displayName: "Kilo Code",
|
|
74865
74871
|
projectPath: ".kilocode/skills",
|
|
74866
|
-
globalPath:
|
|
74867
|
-
detect: async () => existsSync54(
|
|
74872
|
+
globalPath: join110(home6, ".kilocode/skills"),
|
|
74873
|
+
detect: async () => existsSync54(join110(home6, ".kilocode"))
|
|
74868
74874
|
},
|
|
74869
74875
|
roo: {
|
|
74870
74876
|
name: "roo",
|
|
74871
74877
|
displayName: "Roo Code",
|
|
74872
74878
|
projectPath: ".roo/skills",
|
|
74873
|
-
globalPath:
|
|
74874
|
-
detect: async () => existsSync54(
|
|
74879
|
+
globalPath: join110(home6, ".roo/skills"),
|
|
74880
|
+
detect: async () => existsSync54(join110(home6, ".roo"))
|
|
74875
74881
|
},
|
|
74876
74882
|
windsurf: {
|
|
74877
74883
|
name: "windsurf",
|
|
74878
74884
|
displayName: "Windsurf",
|
|
74879
74885
|
projectPath: ".windsurf/skills",
|
|
74880
|
-
globalPath:
|
|
74881
|
-
detect: async () => existsSync54(
|
|
74886
|
+
globalPath: join110(home6, ".codeium/windsurf/skills"),
|
|
74887
|
+
detect: async () => existsSync54(join110(home6, ".codeium/windsurf"))
|
|
74882
74888
|
},
|
|
74883
74889
|
cline: {
|
|
74884
74890
|
name: "cline",
|
|
74885
74891
|
displayName: "Cline",
|
|
74886
74892
|
projectPath: ".cline/skills",
|
|
74887
|
-
globalPath:
|
|
74888
|
-
detect: async () => existsSync54(
|
|
74893
|
+
globalPath: join110(home6, ".cline/skills"),
|
|
74894
|
+
detect: async () => existsSync54(join110(home6, ".cline"))
|
|
74889
74895
|
},
|
|
74890
74896
|
openhands: {
|
|
74891
74897
|
name: "openhands",
|
|
74892
74898
|
displayName: "OpenHands",
|
|
74893
74899
|
projectPath: ".openhands/skills",
|
|
74894
|
-
globalPath:
|
|
74895
|
-
detect: async () => existsSync54(
|
|
74900
|
+
globalPath: join110(home6, ".openhands/skills"),
|
|
74901
|
+
detect: async () => existsSync54(join110(home6, ".openhands"))
|
|
74896
74902
|
}
|
|
74897
74903
|
};
|
|
74898
74904
|
function getInstallPath(skillName, agent, options2) {
|
|
74899
74905
|
const config = agents[agent];
|
|
74900
74906
|
const basePath = options2.global ? config.globalPath : config.projectPath;
|
|
74901
|
-
return
|
|
74907
|
+
return join110(basePath, skillName);
|
|
74902
74908
|
}
|
|
74903
74909
|
function isSkillInstalled(skillName, agent, options2) {
|
|
74904
74910
|
const installPath = getInstallPath(skillName, agent, options2);
|
|
@@ -74909,16 +74915,16 @@ function isSkillInstalled(skillName, agent, options2) {
|
|
|
74909
74915
|
import { existsSync as existsSync56 } from "node:fs";
|
|
74910
74916
|
import { cp as cp4, mkdir as mkdir31, rm as rm14, stat as stat13 } from "node:fs/promises";
|
|
74911
74917
|
import { homedir as homedir28 } from "node:os";
|
|
74912
|
-
import { dirname as dirname35, join as
|
|
74918
|
+
import { dirname as dirname35, join as join112, resolve as resolve33 } from "node:path";
|
|
74913
74919
|
|
|
74914
74920
|
// src/commands/skills/skills-registry.ts
|
|
74915
74921
|
init_zod();
|
|
74916
74922
|
import { existsSync as existsSync55 } from "node:fs";
|
|
74917
74923
|
import { mkdir as mkdir30, readFile as readFile47, writeFile as writeFile35 } from "node:fs/promises";
|
|
74918
74924
|
import { homedir as homedir27 } from "node:os";
|
|
74919
|
-
import { dirname as dirname34, join as
|
|
74925
|
+
import { dirname as dirname34, join as join111, sep as sep9 } from "node:path";
|
|
74920
74926
|
var home7 = homedir27();
|
|
74921
|
-
var REGISTRY_PATH2 =
|
|
74927
|
+
var REGISTRY_PATH2 = join111(home7, ".sunagentkit", "skill-registry.json");
|
|
74922
74928
|
var SkillInstallationSchema = exports_external.object({
|
|
74923
74929
|
skill: exports_external.string(),
|
|
74924
74930
|
agent: exports_external.string(),
|
|
@@ -75056,7 +75062,7 @@ async function syncRegistry() {
|
|
|
75056
75062
|
var LEGACY_SKILL_PATHS = {
|
|
75057
75063
|
"gemini-cli": {
|
|
75058
75064
|
project: ".gemini/skills",
|
|
75059
|
-
global:
|
|
75065
|
+
global: join112(homedir28(), ".gemini/skills")
|
|
75060
75066
|
}
|
|
75061
75067
|
};
|
|
75062
75068
|
function isSamePath3(path1, path22) {
|
|
@@ -75090,7 +75096,7 @@ async function cleanupLegacySkillPath(skillName, agent, global3) {
|
|
|
75090
75096
|
if (!legacy)
|
|
75091
75097
|
return;
|
|
75092
75098
|
const legacyBase = global3 ? legacy.global : legacy.project;
|
|
75093
|
-
const legacyPath =
|
|
75099
|
+
const legacyPath = join112(legacyBase, skillName);
|
|
75094
75100
|
if (!existsSync56(legacyPath))
|
|
75095
75101
|
return;
|
|
75096
75102
|
await rm14(legacyPath, { recursive: true, force: true });
|
|
@@ -75100,7 +75106,7 @@ async function cleanupLegacySkillPath(skillName, agent, global3) {
|
|
|
75100
75106
|
if (entry.skill === skillName && entry.agent === agent && entry.global === global3) {
|
|
75101
75107
|
if (entry.path === legacyPath) {
|
|
75102
75108
|
const newBase = global3 ? agents[agent].globalPath : agents[agent].projectPath;
|
|
75103
|
-
entry.path =
|
|
75109
|
+
entry.path = join112(newBase, skillName);
|
|
75104
75110
|
changed = true;
|
|
75105
75111
|
}
|
|
75106
75112
|
}
|
|
@@ -75185,7 +75191,7 @@ function getInstallPreview(skill, targetAgents, options2) {
|
|
|
75185
75191
|
// src/commands/skills/skills-uninstaller.ts
|
|
75186
75192
|
import { existsSync as existsSync57 } from "node:fs";
|
|
75187
75193
|
import { rm as rm15 } from "node:fs/promises";
|
|
75188
|
-
import { join as
|
|
75194
|
+
import { join as join113 } from "node:path";
|
|
75189
75195
|
async function uninstallSkillFromAgent(skill, agent, global3) {
|
|
75190
75196
|
const agentConfig = agents[agent];
|
|
75191
75197
|
const registry = await readRegistry();
|
|
@@ -75233,7 +75239,7 @@ async function uninstallSkillFromAgent(skill, agent, global3) {
|
|
|
75233
75239
|
async function forceUninstallSkill(skill, agent, global3) {
|
|
75234
75240
|
const agentConfig = agents[agent];
|
|
75235
75241
|
const basePath = global3 ? agentConfig.globalPath : agentConfig.projectPath;
|
|
75236
|
-
const path9 =
|
|
75242
|
+
const path9 = join113(basePath, skill);
|
|
75237
75243
|
if (!existsSync57(path9)) {
|
|
75238
75244
|
return {
|
|
75239
75245
|
skill,
|
|
@@ -75328,7 +75334,7 @@ async function listSkills(showInstalled) {
|
|
|
75328
75334
|
return;
|
|
75329
75335
|
}
|
|
75330
75336
|
console.log();
|
|
75331
|
-
f2.step(
|
|
75337
|
+
f2.step(import_picocolors33.default.bold("Installed Skills"));
|
|
75332
75338
|
console.log();
|
|
75333
75339
|
const bySkill = new Map;
|
|
75334
75340
|
for (const inst of installations) {
|
|
@@ -75337,14 +75343,14 @@ async function listSkills(showInstalled) {
|
|
|
75337
75343
|
bySkill.set(inst.skill, list);
|
|
75338
75344
|
}
|
|
75339
75345
|
for (const [skill, installs] of bySkill) {
|
|
75340
|
-
console.log(` ${
|
|
75346
|
+
console.log(` ${import_picocolors33.default.cyan(skill)}`);
|
|
75341
75347
|
for (const inst of installs) {
|
|
75342
75348
|
const scope = inst.global ? "global" : "project";
|
|
75343
|
-
console.log(` ${
|
|
75349
|
+
console.log(` ${import_picocolors33.default.dim("→")} ${inst.agent} (${scope}): ${import_picocolors33.default.dim(inst.path)}`);
|
|
75344
75350
|
}
|
|
75345
75351
|
}
|
|
75346
75352
|
console.log();
|
|
75347
|
-
console.log(
|
|
75353
|
+
console.log(import_picocolors33.default.dim(` ${installations.length} installation(s) across ${bySkill.size} skill(s)`));
|
|
75348
75354
|
console.log();
|
|
75349
75355
|
return;
|
|
75350
75356
|
}
|
|
@@ -75359,15 +75365,15 @@ async function listSkills(showInstalled) {
|
|
|
75359
75365
|
return;
|
|
75360
75366
|
}
|
|
75361
75367
|
console.log();
|
|
75362
|
-
f2.step(
|
|
75368
|
+
f2.step(import_picocolors33.default.bold("Available Skills"));
|
|
75363
75369
|
console.log();
|
|
75364
75370
|
for (const skill of skills) {
|
|
75365
|
-
console.log(` ${
|
|
75366
|
-
console.log(` ${
|
|
75371
|
+
console.log(` ${import_picocolors33.default.cyan(skill.name)}`);
|
|
75372
|
+
console.log(` ${import_picocolors33.default.dim(skill.description)}`);
|
|
75367
75373
|
}
|
|
75368
75374
|
console.log();
|
|
75369
|
-
console.log(
|
|
75370
|
-
console.log(
|
|
75375
|
+
console.log(import_picocolors33.default.dim(` ${skills.length} skill(s) available`));
|
|
75376
|
+
console.log(import_picocolors33.default.dim(` Source: ${sourcePath}`));
|
|
75371
75377
|
console.log();
|
|
75372
75378
|
}
|
|
75373
75379
|
async function handleUninstall3(options2) {
|
|
@@ -75449,9 +75455,9 @@ async function handleUninstall3(options2) {
|
|
|
75449
75455
|
process.exit(1);
|
|
75450
75456
|
}
|
|
75451
75457
|
console.log();
|
|
75452
|
-
f2.step(
|
|
75458
|
+
f2.step(import_picocolors33.default.bold("Will uninstall:"));
|
|
75453
75459
|
for (const inst of toRemove) {
|
|
75454
|
-
f2.message(` ${
|
|
75460
|
+
f2.message(` ${import_picocolors33.default.red("✗")} ${inst.skill} → ${inst.agent}: ${import_picocolors33.default.dim(inst.path)}`);
|
|
75455
75461
|
}
|
|
75456
75462
|
console.log();
|
|
75457
75463
|
if (!options2.yes) {
|
|
@@ -75474,7 +75480,7 @@ async function handleUninstall3(options2) {
|
|
|
75474
75480
|
}
|
|
75475
75481
|
async function skillsCommand(options2) {
|
|
75476
75482
|
console.log();
|
|
75477
|
-
oe(
|
|
75483
|
+
oe(import_picocolors33.default.bgCyan(import_picocolors33.default.black(" takumi skills ")));
|
|
75478
75484
|
try {
|
|
75479
75485
|
const validOptions = SkillCommandOptionsSchema.parse(options2);
|
|
75480
75486
|
if (validOptions.sync) {
|
|
@@ -75487,29 +75493,29 @@ async function skillsCommand(options2) {
|
|
|
75487
75493
|
} else {
|
|
75488
75494
|
f2.info("Registry is in sync");
|
|
75489
75495
|
}
|
|
75490
|
-
$e(
|
|
75496
|
+
$e(import_picocolors33.default.green("Done!"));
|
|
75491
75497
|
return;
|
|
75492
75498
|
}
|
|
75493
75499
|
if (validOptions.uninstall) {
|
|
75494
75500
|
await handleUninstall3(validOptions);
|
|
75495
|
-
$e(
|
|
75501
|
+
$e(import_picocolors33.default.green("Done!"));
|
|
75496
75502
|
return;
|
|
75497
75503
|
}
|
|
75498
75504
|
if (validOptions.list) {
|
|
75499
75505
|
await listSkills(validOptions.installed ?? false);
|
|
75500
|
-
$e(
|
|
75506
|
+
$e(import_picocolors33.default.dim("Use --name <skill> to install a specific skill"));
|
|
75501
75507
|
return;
|
|
75502
75508
|
}
|
|
75503
75509
|
const sourcePath = getSkillSourcePath();
|
|
75504
75510
|
if (!sourcePath) {
|
|
75505
75511
|
f2.error("No skills found. Install Takumi Engineer first.");
|
|
75506
|
-
$e(
|
|
75512
|
+
$e(import_picocolors33.default.red("Installation failed"));
|
|
75507
75513
|
process.exit(1);
|
|
75508
75514
|
}
|
|
75509
75515
|
const availableSkills = await discoverSkills(sourcePath);
|
|
75510
75516
|
if (availableSkills.length === 0) {
|
|
75511
75517
|
f2.error("No valid skills found in source directory.");
|
|
75512
|
-
$e(
|
|
75518
|
+
$e(import_picocolors33.default.red("Installation failed"));
|
|
75513
75519
|
process.exit(1);
|
|
75514
75520
|
}
|
|
75515
75521
|
const ctx = {
|
|
@@ -75525,7 +75531,7 @@ async function skillsCommand(options2) {
|
|
|
75525
75531
|
const trimmedName = validOptions.name.trim();
|
|
75526
75532
|
if (!trimmedName) {
|
|
75527
75533
|
f2.error("Skill name cannot be empty");
|
|
75528
|
-
$e(
|
|
75534
|
+
$e(import_picocolors33.default.red("Installation failed"));
|
|
75529
75535
|
process.exit(1);
|
|
75530
75536
|
}
|
|
75531
75537
|
const skill = await findSkillByName(trimmedName, sourcePath);
|
|
@@ -75535,15 +75541,15 @@ async function skillsCommand(options2) {
|
|
|
75535
75541
|
for (const s3 of availableSkills) {
|
|
75536
75542
|
f2.message(` - ${s3.name}`);
|
|
75537
75543
|
}
|
|
75538
|
-
$e(
|
|
75544
|
+
$e(import_picocolors33.default.red("Installation failed"));
|
|
75539
75545
|
process.exit(1);
|
|
75540
75546
|
}
|
|
75541
75547
|
ctx.selectedSkills = [skill];
|
|
75542
|
-
f2.info(`Skill: ${
|
|
75543
|
-
f2.message(
|
|
75548
|
+
f2.info(`Skill: ${import_picocolors33.default.cyan(skill.name)}`);
|
|
75549
|
+
f2.message(import_picocolors33.default.dim(skill.description));
|
|
75544
75550
|
} else if (availableSkills.length === 1) {
|
|
75545
75551
|
ctx.selectedSkills = [availableSkills[0]];
|
|
75546
|
-
f2.info(`Skill: ${
|
|
75552
|
+
f2.info(`Skill: ${import_picocolors33.default.cyan(ctx.selectedSkills[0].name)}`);
|
|
75547
75553
|
} else if (validOptions.yes) {
|
|
75548
75554
|
f2.error("--name required in non-interactive mode with multiple skills");
|
|
75549
75555
|
process.exit(1);
|
|
@@ -75600,7 +75606,7 @@ async function skillsCommand(options2) {
|
|
|
75600
75606
|
}
|
|
75601
75607
|
} else if (ctx.detectedAgents.length === 1 || validOptions.yes) {
|
|
75602
75608
|
ctx.selectedAgents = ctx.detectedAgents;
|
|
75603
|
-
f2.info(`Installing to: ${ctx.detectedAgents.map((a3) =>
|
|
75609
|
+
f2.info(`Installing to: ${ctx.detectedAgents.map((a3) => import_picocolors33.default.cyan(agents[a3].displayName)).join(", ")}`);
|
|
75604
75610
|
} else {
|
|
75605
75611
|
const agentChoices = ctx.detectedAgents.map((a3) => ({
|
|
75606
75612
|
value: a3,
|
|
@@ -75646,15 +75652,15 @@ async function skillsCommand(options2) {
|
|
|
75646
75652
|
process.exit(1);
|
|
75647
75653
|
}
|
|
75648
75654
|
console.log();
|
|
75649
|
-
f2.step(
|
|
75655
|
+
f2.step(import_picocolors33.default.bold("Installation Summary"));
|
|
75650
75656
|
for (const skill of ctx.selectedSkills) {
|
|
75651
|
-
f2.message(` ${
|
|
75657
|
+
f2.message(` ${import_picocolors33.default.cyan(skill.name)}`);
|
|
75652
75658
|
const preview = getInstallPreview(skill, ctx.selectedAgents, {
|
|
75653
75659
|
global: ctx.installGlobally
|
|
75654
75660
|
});
|
|
75655
75661
|
for (const item of preview) {
|
|
75656
|
-
const status2 = item.exists ?
|
|
75657
|
-
f2.message(` ${
|
|
75662
|
+
const status2 = item.exists ? import_picocolors33.default.yellow(" (overwrite)") : "";
|
|
75663
|
+
f2.message(` ${import_picocolors33.default.dim("→")} ${item.displayName}${status2}`);
|
|
75658
75664
|
}
|
|
75659
75665
|
}
|
|
75660
75666
|
console.log();
|
|
@@ -75689,29 +75695,29 @@ async function skillsCommand(options2) {
|
|
|
75689
75695
|
const skipped = results.filter((r2) => r2.skipped);
|
|
75690
75696
|
const failed = results.filter((r2) => !r2.success);
|
|
75691
75697
|
if (successful.length > 0) {
|
|
75692
|
-
f2.success(`${
|
|
75698
|
+
f2.success(`${import_picocolors33.default.cyan(skill)} → ${successful.length} agent(s)`);
|
|
75693
75699
|
for (const r2 of successful) {
|
|
75694
|
-
f2.message(` ${
|
|
75700
|
+
f2.message(` ${import_picocolors33.default.green("✓")} ${r2.agentDisplayName}`);
|
|
75695
75701
|
}
|
|
75696
75702
|
}
|
|
75697
75703
|
if (skipped.length > 0) {
|
|
75698
|
-
f2.info(`${
|
|
75704
|
+
f2.info(`${import_picocolors33.default.cyan(skill)} → ${skipped.length} skipped`);
|
|
75699
75705
|
for (const r2 of skipped) {
|
|
75700
|
-
f2.message(` ${
|
|
75706
|
+
f2.message(` ${import_picocolors33.default.yellow("○")} ${r2.agentDisplayName}: ${import_picocolors33.default.dim(r2.skipReason || "Already at source location")}`);
|
|
75701
75707
|
}
|
|
75702
75708
|
}
|
|
75703
75709
|
if (failed.length > 0) {
|
|
75704
|
-
f2.error(`${
|
|
75710
|
+
f2.error(`${import_picocolors33.default.cyan(skill)} failed: ${failed.length} agent(s)`);
|
|
75705
75711
|
for (const r2 of failed) {
|
|
75706
|
-
f2.message(` ${
|
|
75712
|
+
f2.message(` ${import_picocolors33.default.red("✗")} ${r2.agentDisplayName}: ${import_picocolors33.default.dim(r2.error)}`);
|
|
75707
75713
|
}
|
|
75708
75714
|
}
|
|
75709
75715
|
}
|
|
75710
75716
|
console.log();
|
|
75711
75717
|
if (totalSuccessful === 0 && totalFailed === 0 && totalSkipped === 0) {
|
|
75712
|
-
$e(
|
|
75718
|
+
$e(import_picocolors33.default.yellow("No installations performed"));
|
|
75713
75719
|
} else if (totalFailed > 0 && totalSuccessful === 0) {
|
|
75714
|
-
$e(
|
|
75720
|
+
$e(import_picocolors33.default.red("Installation failed"));
|
|
75715
75721
|
process.exit(1);
|
|
75716
75722
|
} else {
|
|
75717
75723
|
const parts = [];
|
|
@@ -75721,11 +75727,11 @@ async function skillsCommand(options2) {
|
|
|
75721
75727
|
parts.push(`${totalSkipped} skipped`);
|
|
75722
75728
|
if (totalFailed > 0)
|
|
75723
75729
|
parts.push(`${totalFailed} failed`);
|
|
75724
|
-
$e(
|
|
75730
|
+
$e(import_picocolors33.default.green(`Done! ${parts.join(", ")}`));
|
|
75725
75731
|
}
|
|
75726
75732
|
} catch (error) {
|
|
75727
75733
|
logger.error(error instanceof Error ? error.message : "Unknown error");
|
|
75728
|
-
$e(
|
|
75734
|
+
$e(import_picocolors33.default.red("Installation failed"));
|
|
75729
75735
|
process.exit(1);
|
|
75730
75736
|
}
|
|
75731
75737
|
}
|
|
@@ -75738,12 +75744,12 @@ init_logger();
|
|
|
75738
75744
|
// src/commands/telemetry/shared.ts
|
|
75739
75745
|
import { existsSync as existsSync58, readFileSync as readFileSync15, readdirSync as readdirSync6 } from "node:fs";
|
|
75740
75746
|
import { homedir as homedir29 } from "node:os";
|
|
75741
|
-
import { join as
|
|
75747
|
+
import { join as join114 } from "node:path";
|
|
75742
75748
|
init_token_store();
|
|
75743
|
-
var USER_CACHE_PATH =
|
|
75744
|
-
var EVENT_BUFFER_DIR =
|
|
75745
|
-
var RATE_STATE_PATH =
|
|
75746
|
-
var METADATA_PATH =
|
|
75749
|
+
var USER_CACHE_PATH = join114(homedir29(), ".claude", "sk-user.json");
|
|
75750
|
+
var EVENT_BUFFER_DIR = join114(homedir29(), ".claude", "sk-events");
|
|
75751
|
+
var RATE_STATE_PATH = join114(homedir29(), ".claude", "sk-rate-state.json");
|
|
75752
|
+
var METADATA_PATH = join114(homedir29(), ".claude", "metadata.json");
|
|
75747
75753
|
var TELEMETRY_HOOK_FIELD = "hooks.telemetry";
|
|
75748
75754
|
var TOKEN_PLACEHOLDER = "__INJECT_AT_RELEASE__";
|
|
75749
75755
|
function readUserCache() {
|
|
@@ -75830,7 +75836,7 @@ async function handleDisable() {
|
|
|
75830
75836
|
// src/commands/telemetry/phases/purge-local-handler.ts
|
|
75831
75837
|
init_logger();
|
|
75832
75838
|
import { existsSync as existsSync59, readdirSync as readdirSync7, unlinkSync as unlinkSync5 } from "node:fs";
|
|
75833
|
-
import { join as
|
|
75839
|
+
import { join as join115 } from "node:path";
|
|
75834
75840
|
function removeIfExists(path9) {
|
|
75835
75841
|
try {
|
|
75836
75842
|
if (!existsSync59(path9))
|
|
@@ -75850,7 +75856,7 @@ function removeBufferFiles() {
|
|
|
75850
75856
|
if (!file.endsWith(".jsonl"))
|
|
75851
75857
|
continue;
|
|
75852
75858
|
try {
|
|
75853
|
-
unlinkSync5(
|
|
75859
|
+
unlinkSync5(join115(EVENT_BUFFER_DIR, file));
|
|
75854
75860
|
count += 1;
|
|
75855
75861
|
} catch {}
|
|
75856
75862
|
}
|
|
@@ -76033,7 +76039,7 @@ async function telemetryCommand(action, options2 = {}) {
|
|
|
76033
76039
|
// src/commands/uninstall/uninstall-command.ts
|
|
76034
76040
|
init_logger();
|
|
76035
76041
|
init_types2();
|
|
76036
|
-
var
|
|
76042
|
+
var import_picocolors35 = __toESM(require_picocolors(), 1);
|
|
76037
76043
|
|
|
76038
76044
|
// src/commands/uninstall/installation-detector.ts
|
|
76039
76045
|
var import_fs_extra37 = __toESM(require_lib(), 1);
|
|
@@ -76076,15 +76082,15 @@ async function detectInstallations() {
|
|
|
76076
76082
|
|
|
76077
76083
|
// src/commands/uninstall/removal-handler.ts
|
|
76078
76084
|
import { readdirSync as readdirSync9, rmSync as rmSync6 } from "node:fs";
|
|
76079
|
-
import { join as
|
|
76085
|
+
import { join as join117, resolve as resolve34, sep as sep10 } from "node:path";
|
|
76080
76086
|
init_logger();
|
|
76081
76087
|
var import_fs_extra38 = __toESM(require_lib(), 1);
|
|
76082
76088
|
|
|
76083
76089
|
// src/commands/uninstall/analysis-handler.ts
|
|
76084
76090
|
import { readdirSync as readdirSync8, rmSync as rmSync5 } from "node:fs";
|
|
76085
|
-
import { dirname as dirname36, join as
|
|
76091
|
+
import { dirname as dirname36, join as join116 } from "node:path";
|
|
76086
76092
|
init_logger();
|
|
76087
|
-
var
|
|
76093
|
+
var import_picocolors34 = __toESM(require_picocolors(), 1);
|
|
76088
76094
|
function classifyFileByOwnership(ownership, forceOverwrite, deleteReason) {
|
|
76089
76095
|
if (ownership === "takumi") {
|
|
76090
76096
|
return { action: "delete", reason: deleteReason };
|
|
@@ -76129,7 +76135,7 @@ async function analyzeInstallation(installation, forceOverwrite, kit) {
|
|
|
76129
76135
|
if (uninstallManifest.isMultiKit && kit && metadata?.kits?.[kit]) {
|
|
76130
76136
|
const kitFiles = metadata.kits[kit].files || [];
|
|
76131
76137
|
for (const trackedFile of kitFiles) {
|
|
76132
|
-
const filePath =
|
|
76138
|
+
const filePath = join116(installation.path, trackedFile.path);
|
|
76133
76139
|
if (uninstallManifest.filesToPreserve.includes(trackedFile.path)) {
|
|
76134
76140
|
result.toPreserve.push({ path: trackedFile.path, reason: "shared with other kit" });
|
|
76135
76141
|
continue;
|
|
@@ -76159,7 +76165,7 @@ async function analyzeInstallation(installation, forceOverwrite, kit) {
|
|
|
76159
76165
|
return result;
|
|
76160
76166
|
}
|
|
76161
76167
|
for (const trackedFile of allTrackedFiles) {
|
|
76162
|
-
const filePath =
|
|
76168
|
+
const filePath = join116(installation.path, trackedFile.path);
|
|
76163
76169
|
const ownershipResult = await OwnershipChecker.checkOwnership(filePath, metadata, installation.path);
|
|
76164
76170
|
if (!ownershipResult.exists)
|
|
76165
76171
|
continue;
|
|
@@ -76175,27 +76181,27 @@ async function analyzeInstallation(installation, forceOverwrite, kit) {
|
|
|
76175
76181
|
}
|
|
76176
76182
|
function displayDryRunPreview(analysis, installationType) {
|
|
76177
76183
|
console.log("");
|
|
76178
|
-
log.info(
|
|
76184
|
+
log.info(import_picocolors34.default.bold(`DRY RUN - Preview for ${installationType} installation:`));
|
|
76179
76185
|
console.log("");
|
|
76180
76186
|
if (analysis.toDelete.length > 0) {
|
|
76181
|
-
console.log(
|
|
76187
|
+
console.log(import_picocolors34.default.red(import_picocolors34.default.bold(`Files to DELETE (${analysis.toDelete.length}):`)));
|
|
76182
76188
|
const showDelete = analysis.toDelete.slice(0, 10);
|
|
76183
76189
|
for (const item of showDelete) {
|
|
76184
|
-
console.log(` ${
|
|
76190
|
+
console.log(` ${import_picocolors34.default.red("✖")} ${item.path}`);
|
|
76185
76191
|
}
|
|
76186
76192
|
if (analysis.toDelete.length > 10) {
|
|
76187
|
-
console.log(
|
|
76193
|
+
console.log(import_picocolors34.default.gray(` ... and ${analysis.toDelete.length - 10} more`));
|
|
76188
76194
|
}
|
|
76189
76195
|
console.log("");
|
|
76190
76196
|
}
|
|
76191
76197
|
if (analysis.toPreserve.length > 0) {
|
|
76192
|
-
console.log(
|
|
76198
|
+
console.log(import_picocolors34.default.green(import_picocolors34.default.bold(`Files to PRESERVE (${analysis.toPreserve.length}):`)));
|
|
76193
76199
|
const showPreserve = analysis.toPreserve.slice(0, 10);
|
|
76194
76200
|
for (const item of showPreserve) {
|
|
76195
|
-
console.log(` ${
|
|
76201
|
+
console.log(` ${import_picocolors34.default.green("✓")} ${item.path} ${import_picocolors34.default.gray(`(${item.reason})`)}`);
|
|
76196
76202
|
}
|
|
76197
76203
|
if (analysis.toPreserve.length > 10) {
|
|
76198
|
-
console.log(
|
|
76204
|
+
console.log(import_picocolors34.default.gray(` ... and ${analysis.toPreserve.length - 10} more`));
|
|
76199
76205
|
}
|
|
76200
76206
|
console.log("");
|
|
76201
76207
|
}
|
|
@@ -76256,7 +76262,7 @@ async function removeInstallations(installations, options2) {
|
|
|
76256
76262
|
let removedCount = 0;
|
|
76257
76263
|
let cleanedDirs = 0;
|
|
76258
76264
|
for (const item of analysis.toDelete) {
|
|
76259
|
-
const filePath =
|
|
76265
|
+
const filePath = join117(installation.path, item.path);
|
|
76260
76266
|
if (!await import_fs_extra38.pathExists(filePath))
|
|
76261
76267
|
continue;
|
|
76262
76268
|
if (!await isPathSafeToRemove(filePath, installation.path)) {
|
|
@@ -76317,15 +76323,15 @@ function displayInstallations(installations, scope) {
|
|
|
76317
76323
|
const hasLegacy = installations.some((i) => !i.hasMetadata);
|
|
76318
76324
|
const lines = installations.map((i) => {
|
|
76319
76325
|
const typeLabel = i.type === "local" ? "Local " : "Global";
|
|
76320
|
-
const legacyTag = !i.hasMetadata ?
|
|
76326
|
+
const legacyTag = !i.hasMetadata ? import_picocolors35.default.yellow(" [legacy]") : "";
|
|
76321
76327
|
const components = formatComponentSummary(i);
|
|
76322
76328
|
return ` ${typeLabel}: ${i.path}${legacyTag}${components}`;
|
|
76323
76329
|
});
|
|
76324
76330
|
prompts.note(lines.join(`
|
|
76325
76331
|
`), `Detected Takumi installations (${scopeLabel})`);
|
|
76326
76332
|
if (hasLegacy) {
|
|
76327
|
-
log.warn(
|
|
76328
|
-
`) +
|
|
76333
|
+
log.warn(import_picocolors35.default.yellow(`[!] Legacy installation(s) detected without metadata.json.
|
|
76334
|
+
`) + import_picocolors35.default.yellow(" These files cannot be selectively removed. Full directory cleanup will be performed."));
|
|
76329
76335
|
}
|
|
76330
76336
|
log.warn("[!] This will permanently delete Takumi files from the above paths.");
|
|
76331
76337
|
}
|
|
@@ -76385,7 +76391,7 @@ async function uninstallCommand(options2) {
|
|
|
76385
76391
|
}
|
|
76386
76392
|
const isAtHome = isLocalSameAsGlobal();
|
|
76387
76393
|
if (validOptions.local && !validOptions.global && isAtHome) {
|
|
76388
|
-
log.warn(
|
|
76394
|
+
log.warn(import_picocolors35.default.yellow("Cannot use --local at HOME directory (local path equals global path)."));
|
|
76389
76395
|
log.info("Use -g/--global or run from a project directory.");
|
|
76390
76396
|
return;
|
|
76391
76397
|
}
|
|
@@ -76397,7 +76403,7 @@ async function uninstallCommand(options2) {
|
|
|
76397
76403
|
} else if (validOptions.global) {
|
|
76398
76404
|
scope = "global";
|
|
76399
76405
|
} else if (isAtHome) {
|
|
76400
|
-
log.info(
|
|
76406
|
+
log.info(import_picocolors35.default.cyan("Running at HOME directory - targeting global installation"));
|
|
76401
76407
|
scope = "global";
|
|
76402
76408
|
} else {
|
|
76403
76409
|
const promptedScope = await promptScope(allInstallations);
|
|
@@ -76419,10 +76425,10 @@ async function uninstallCommand(options2) {
|
|
|
76419
76425
|
}
|
|
76420
76426
|
displayInstallations(installations, scope);
|
|
76421
76427
|
if (validOptions.kit) {
|
|
76422
|
-
log.info(
|
|
76428
|
+
log.info(import_picocolors35.default.cyan(`Kit-scoped uninstall: ${validOptions.kit} kit only`));
|
|
76423
76429
|
}
|
|
76424
76430
|
if (validOptions.dryRun) {
|
|
76425
|
-
log.info(
|
|
76431
|
+
log.info(import_picocolors35.default.yellow("DRY RUN MODE - No files will be deleted"));
|
|
76426
76432
|
await removeInstallations(installations, {
|
|
76427
76433
|
dryRun: true,
|
|
76428
76434
|
forceOverwrite: validOptions.forceOverwrite,
|
|
@@ -76432,8 +76438,8 @@ async function uninstallCommand(options2) {
|
|
|
76432
76438
|
return;
|
|
76433
76439
|
}
|
|
76434
76440
|
if (validOptions.forceOverwrite) {
|
|
76435
|
-
log.warn(`${
|
|
76436
|
-
${
|
|
76441
|
+
log.warn(`${import_picocolors35.default.yellow(import_picocolors35.default.bold("FORCE MODE ENABLED"))}
|
|
76442
|
+
${import_picocolors35.default.yellow("User modifications will be permanently deleted!")}`);
|
|
76437
76443
|
}
|
|
76438
76444
|
if (!validOptions.yes) {
|
|
76439
76445
|
const kitLabel = validOptions.kit ? ` (${validOptions.kit} kit only)` : "";
|
|
@@ -76458,7 +76464,7 @@ ${import_picocolors36.default.yellow("User modifications will be permanently del
|
|
|
76458
76464
|
// src/commands/update-cli.ts
|
|
76459
76465
|
init_takumi_config_manager();
|
|
76460
76466
|
import { exec as exec8, spawn as spawn2 } from "node:child_process";
|
|
76461
|
-
import { join as
|
|
76467
|
+
import { join as join118 } from "node:path";
|
|
76462
76468
|
import { promisify as promisify14 } from "node:util";
|
|
76463
76469
|
|
|
76464
76470
|
// src/domains/github/npm-registry.ts
|
|
@@ -76625,7 +76631,7 @@ var import_fs_extra39 = __toESM(require_lib(), 1);
|
|
|
76625
76631
|
// package.json
|
|
76626
76632
|
var package_default = {
|
|
76627
76633
|
name: "@sunasteriskrnd/takumi",
|
|
76628
|
-
version: "1.0.0-dev.
|
|
76634
|
+
version: "1.0.0-dev.11",
|
|
76629
76635
|
description: "CLI tool for bootstrapping and managing Takumi projects",
|
|
76630
76636
|
type: "module",
|
|
76631
76637
|
repository: {
|
|
@@ -76810,7 +76816,7 @@ function selectKitForUpdate(params) {
|
|
|
76810
76816
|
};
|
|
76811
76817
|
}
|
|
76812
76818
|
async function readMetadataFile(claudeDir) {
|
|
76813
|
-
const metadataPath =
|
|
76819
|
+
const metadataPath = join118(claudeDir, "metadata.json");
|
|
76814
76820
|
try {
|
|
76815
76821
|
if (!await import_fs_extra39.pathExists(metadataPath)) {
|
|
76816
76822
|
return null;
|
|
@@ -77212,7 +77218,7 @@ init_auth_client();
|
|
|
77212
77218
|
init_github_client();
|
|
77213
77219
|
init_logger();
|
|
77214
77220
|
init_types2();
|
|
77215
|
-
var
|
|
77221
|
+
var import_picocolors36 = __toESM(require_picocolors(), 1);
|
|
77216
77222
|
function formatRelativeTime(dateString) {
|
|
77217
77223
|
if (!dateString)
|
|
77218
77224
|
return "Unknown";
|
|
@@ -77234,21 +77240,21 @@ function formatRelativeTime(dateString) {
|
|
|
77234
77240
|
}
|
|
77235
77241
|
function displayKitReleases(kitName, releases) {
|
|
77236
77242
|
console.log(`
|
|
77237
|
-
${
|
|
77243
|
+
${import_picocolors36.default.bold(import_picocolors36.default.cyan(kitName))} - Available Versions:
|
|
77238
77244
|
`);
|
|
77239
77245
|
if (releases.length === 0) {
|
|
77240
|
-
console.log(
|
|
77246
|
+
console.log(import_picocolors36.default.dim(" No releases found"));
|
|
77241
77247
|
return;
|
|
77242
77248
|
}
|
|
77243
77249
|
for (const release of releases) {
|
|
77244
|
-
const version3 =
|
|
77250
|
+
const version3 = import_picocolors36.default.green(release.tag);
|
|
77245
77251
|
const publishedAt = formatRelativeTime(release.publishedAt);
|
|
77246
|
-
const badge = release.prerelease ? ` ${
|
|
77252
|
+
const badge = release.prerelease ? ` ${import_picocolors36.default.yellow("[prerelease]")}` : "";
|
|
77247
77253
|
const versionPart = version3.padEnd(20);
|
|
77248
|
-
const timePart =
|
|
77254
|
+
const timePart = import_picocolors36.default.dim(publishedAt.padEnd(20));
|
|
77249
77255
|
console.log(` ${versionPart} ${timePart}${badge}`);
|
|
77250
77256
|
}
|
|
77251
|
-
console.log(
|
|
77257
|
+
console.log(import_picocolors36.default.dim(`
|
|
77252
77258
|
Showing ${releases.length} ${releases.length === 1 ? "release" : "releases"}`));
|
|
77253
77259
|
}
|
|
77254
77260
|
async function fetchReleasesForKit(kitType, options2) {
|
|
@@ -77293,8 +77299,8 @@ async function versionCommand(options2) {
|
|
|
77293
77299
|
for (const result of results) {
|
|
77294
77300
|
if (result.error) {
|
|
77295
77301
|
console.log(`
|
|
77296
|
-
${
|
|
77297
|
-
console.log(
|
|
77302
|
+
${import_picocolors36.default.bold(import_picocolors36.default.cyan(result.kitConfig.name))} - ${import_picocolors36.default.red("Error")}`);
|
|
77303
|
+
console.log(import_picocolors36.default.dim(` ${result.error}`));
|
|
77298
77304
|
} else {
|
|
77299
77305
|
displayKitReleases(result.kitConfig.name, result.releases);
|
|
77300
77306
|
}
|
|
@@ -77311,8 +77317,8 @@ init_logger();
|
|
|
77311
77317
|
import { existsSync as existsSync65 } from "node:fs";
|
|
77312
77318
|
import { rm as rm16 } from "node:fs/promises";
|
|
77313
77319
|
import { homedir as homedir31 } from "node:os";
|
|
77314
|
-
import { join as
|
|
77315
|
-
var
|
|
77320
|
+
import { join as join125 } from "node:path";
|
|
77321
|
+
var import_picocolors37 = __toESM(require_picocolors(), 1);
|
|
77316
77322
|
|
|
77317
77323
|
// src/commands/watch/phases/implementation-runner.ts
|
|
77318
77324
|
init_logger();
|
|
@@ -77821,7 +77827,7 @@ function spawnAndCollect3(command, args) {
|
|
|
77821
77827
|
|
|
77822
77828
|
// src/commands/watch/phases/issue-processor.ts
|
|
77823
77829
|
import { mkdir as mkdir32, writeFile as writeFile37 } from "node:fs/promises";
|
|
77824
|
-
import { join as
|
|
77830
|
+
import { join as join121 } from "node:path";
|
|
77825
77831
|
|
|
77826
77832
|
// src/commands/watch/phases/approval-detector.ts
|
|
77827
77833
|
init_logger();
|
|
@@ -78196,9 +78202,9 @@ async function checkAwaitingApproval(state, setup, options2, watchLog, projectDi
|
|
|
78196
78202
|
|
|
78197
78203
|
// src/commands/watch/phases/plan-dir-finder.ts
|
|
78198
78204
|
import { readdir as readdir32, stat as stat14 } from "node:fs/promises";
|
|
78199
|
-
import { join as
|
|
78205
|
+
import { join as join120 } from "node:path";
|
|
78200
78206
|
async function findRecentPlanDir(cwd2, issueNumber, watchLog) {
|
|
78201
|
-
const plansRoot =
|
|
78207
|
+
const plansRoot = join120(cwd2, "plans");
|
|
78202
78208
|
try {
|
|
78203
78209
|
const entries = await readdir32(plansRoot);
|
|
78204
78210
|
const tenMinAgo = Date.now() - 10 * 60 * 1000;
|
|
@@ -78207,14 +78213,14 @@ async function findRecentPlanDir(cwd2, issueNumber, watchLog) {
|
|
|
78207
78213
|
for (const entry of entries) {
|
|
78208
78214
|
if (entry === "watch" || entry === "reports" || entry === "visuals")
|
|
78209
78215
|
continue;
|
|
78210
|
-
const dirPath =
|
|
78216
|
+
const dirPath = join120(plansRoot, entry);
|
|
78211
78217
|
const dirStat = await stat14(dirPath);
|
|
78212
78218
|
if (!dirStat.isDirectory())
|
|
78213
78219
|
continue;
|
|
78214
78220
|
if (dirStat.mtimeMs < tenMinAgo)
|
|
78215
78221
|
continue;
|
|
78216
78222
|
try {
|
|
78217
|
-
await stat14(
|
|
78223
|
+
await stat14(join120(dirPath, "plan.md"));
|
|
78218
78224
|
} catch {
|
|
78219
78225
|
continue;
|
|
78220
78226
|
}
|
|
@@ -78445,13 +78451,13 @@ async function handlePlanGeneration(issue, state, config, setup, options2, watch
|
|
|
78445
78451
|
stats.plansCreated++;
|
|
78446
78452
|
const detectedPlanDir = await findRecentPlanDir(projectDir, issue.number, watchLog);
|
|
78447
78453
|
if (detectedPlanDir) {
|
|
78448
|
-
state.activeIssues[numStr].planPath =
|
|
78454
|
+
state.activeIssues[numStr].planPath = join121(detectedPlanDir, "plan.md");
|
|
78449
78455
|
watchLog.info(`Plan directory detected: ${detectedPlanDir}`);
|
|
78450
78456
|
} else {
|
|
78451
78457
|
try {
|
|
78452
|
-
const planDir =
|
|
78458
|
+
const planDir = join121(projectDir, "plans", "watch");
|
|
78453
78459
|
await mkdir32(planDir, { recursive: true });
|
|
78454
|
-
const planFilePath =
|
|
78460
|
+
const planFilePath = join121(planDir, `issue-${issue.number}-plan.md`);
|
|
78455
78461
|
await writeFile37(planFilePath, planResult.planText, "utf-8");
|
|
78456
78462
|
state.activeIssues[numStr].planPath = planFilePath;
|
|
78457
78463
|
watchLog.info(`Plan saved (fallback) to ${planFilePath}`);
|
|
@@ -78756,18 +78762,18 @@ init_logger();
|
|
|
78756
78762
|
import { spawnSync as spawnSync5 } from "node:child_process";
|
|
78757
78763
|
import { existsSync as existsSync62 } from "node:fs";
|
|
78758
78764
|
import { readdir as readdir33, stat as stat15 } from "node:fs/promises";
|
|
78759
|
-
import { join as
|
|
78765
|
+
import { join as join122 } from "node:path";
|
|
78760
78766
|
async function scanForRepos(parentDir) {
|
|
78761
78767
|
const repos = [];
|
|
78762
78768
|
const entries = await readdir33(parentDir);
|
|
78763
78769
|
for (const entry of entries) {
|
|
78764
78770
|
if (entry.startsWith("."))
|
|
78765
78771
|
continue;
|
|
78766
|
-
const fullPath =
|
|
78772
|
+
const fullPath = join122(parentDir, entry);
|
|
78767
78773
|
const entryStat = await stat15(fullPath);
|
|
78768
78774
|
if (!entryStat.isDirectory())
|
|
78769
78775
|
continue;
|
|
78770
|
-
const gitDir =
|
|
78776
|
+
const gitDir = join122(fullPath, ".git");
|
|
78771
78777
|
if (!existsSync62(gitDir))
|
|
78772
78778
|
continue;
|
|
78773
78779
|
const result = spawnSync5("gh", ["repo", "view", "--json", "owner,name"], {
|
|
@@ -78794,7 +78800,7 @@ init_logger();
|
|
|
78794
78800
|
import { spawnSync as spawnSync6 } from "node:child_process";
|
|
78795
78801
|
import { existsSync as existsSync63 } from "node:fs";
|
|
78796
78802
|
import { homedir as homedir30 } from "node:os";
|
|
78797
|
-
import { join as
|
|
78803
|
+
import { join as join123 } from "node:path";
|
|
78798
78804
|
async function validateSetup(cwd2) {
|
|
78799
78805
|
const workDir = cwd2 ?? process.cwd();
|
|
78800
78806
|
const ghVersion = spawnSync6("gh", ["--version"], { encoding: "utf-8", timeout: 1e4 });
|
|
@@ -78825,7 +78831,7 @@ Run this command from a directory with a GitHub remote.`);
|
|
|
78825
78831
|
} catch {
|
|
78826
78832
|
throw new Error(`Failed to parse repository info: ${ghRepo.stdout}`);
|
|
78827
78833
|
}
|
|
78828
|
-
const skillsPath =
|
|
78834
|
+
const skillsPath = join123(homedir30(), ".claude", "skills");
|
|
78829
78835
|
const skillsAvailable = existsSync63(skillsPath);
|
|
78830
78836
|
if (!skillsAvailable) {
|
|
78831
78837
|
logger.warning(`Takumi Engineer skills not found at ${skillsPath}`);
|
|
@@ -78844,7 +78850,7 @@ init_path_resolver();
|
|
|
78844
78850
|
import { createWriteStream as createWriteStream4, statSync as statSync6 } from "node:fs";
|
|
78845
78851
|
import { existsSync as existsSync64 } from "node:fs";
|
|
78846
78852
|
import { mkdir as mkdir34, rename as rename9 } from "node:fs/promises";
|
|
78847
|
-
import { join as
|
|
78853
|
+
import { join as join124 } from "node:path";
|
|
78848
78854
|
|
|
78849
78855
|
class WatchLogger {
|
|
78850
78856
|
logStream = null;
|
|
@@ -78852,7 +78858,7 @@ class WatchLogger {
|
|
|
78852
78858
|
logPath = null;
|
|
78853
78859
|
maxBytes;
|
|
78854
78860
|
constructor(logDir, maxBytes = 0) {
|
|
78855
|
-
this.logDir = logDir ??
|
|
78861
|
+
this.logDir = logDir ?? join124(PathResolver.getTakumiDir(), "logs");
|
|
78856
78862
|
this.maxBytes = maxBytes;
|
|
78857
78863
|
}
|
|
78858
78864
|
async init() {
|
|
@@ -78861,7 +78867,7 @@ class WatchLogger {
|
|
|
78861
78867
|
await mkdir34(this.logDir, { recursive: true });
|
|
78862
78868
|
}
|
|
78863
78869
|
const dateStr = formatDate(new Date);
|
|
78864
|
-
this.logPath =
|
|
78870
|
+
this.logPath = join124(this.logDir, `watch-${dateStr}.log`);
|
|
78865
78871
|
this.logStream = createWriteStream4(this.logPath, { flags: "a", mode: 384 });
|
|
78866
78872
|
} catch (error) {
|
|
78867
78873
|
logger.warning(`Cannot create watch log file: ${error instanceof Error ? error.message : "Unknown"}`);
|
|
@@ -79041,7 +79047,7 @@ async function watchCommand(options2) {
|
|
|
79041
79047
|
}
|
|
79042
79048
|
async function discoverRepos(options2, watchLog) {
|
|
79043
79049
|
const cwd2 = process.cwd();
|
|
79044
|
-
const isGitRepo = existsSync65(
|
|
79050
|
+
const isGitRepo = existsSync65(join125(cwd2, ".git"));
|
|
79045
79051
|
if (options2.force) {
|
|
79046
79052
|
await forceRemoveLock(watchLog);
|
|
79047
79053
|
}
|
|
@@ -79111,7 +79117,7 @@ async function resetState(state, projectDir, watchLog) {
|
|
|
79111
79117
|
watchLog.info(`Watch state reset (--force) for ${projectDir}`);
|
|
79112
79118
|
}
|
|
79113
79119
|
async function forceRemoveLock(watchLog) {
|
|
79114
|
-
const lockPath =
|
|
79120
|
+
const lockPath = join125(homedir31(), ".sunagentkit", "locks", `${LOCK_NAME}.lock`);
|
|
79115
79121
|
try {
|
|
79116
79122
|
await rm16(lockPath, { recursive: true, force: true });
|
|
79117
79123
|
watchLog.info("Removed existing lock file (--force)");
|
|
@@ -79119,27 +79125,27 @@ async function forceRemoveLock(watchLog) {
|
|
|
79119
79125
|
}
|
|
79120
79126
|
function printBanner(repos, interval, options2) {
|
|
79121
79127
|
console.log();
|
|
79122
|
-
console.log(
|
|
79123
|
-
console.log(
|
|
79128
|
+
console.log(import_picocolors37.default.bold(" Takumi Watch"));
|
|
79129
|
+
console.log(import_picocolors37.default.dim(" ─────────────────────"));
|
|
79124
79130
|
if (repos.length === 1) {
|
|
79125
79131
|
const r2 = repos[0];
|
|
79126
79132
|
const queueInfo = formatQueueInfo(r2.state);
|
|
79127
|
-
console.log(` ${
|
|
79128
|
-
console.log(` ${
|
|
79133
|
+
console.log(` ${import_picocolors37.default.green("➜")} Repo: ${import_picocolors37.default.cyan(`${r2.setup.repoOwner}/${r2.setup.repoName}`)}`);
|
|
79134
|
+
console.log(` ${import_picocolors37.default.green("➜")} Queue: ${import_picocolors37.default.cyan(queueInfo)}`);
|
|
79129
79135
|
} else {
|
|
79130
|
-
console.log(` ${
|
|
79136
|
+
console.log(` ${import_picocolors37.default.green("➜")} Repos: ${import_picocolors37.default.cyan(String(repos.length))}`);
|
|
79131
79137
|
for (const r2 of repos) {
|
|
79132
79138
|
const queueInfo = formatQueueInfo(r2.state);
|
|
79133
|
-
console.log(` ${
|
|
79139
|
+
console.log(` ${import_picocolors37.default.dim("•")} ${import_picocolors37.default.cyan(`${r2.setup.repoOwner}/${r2.setup.repoName}`)} (${queueInfo})`);
|
|
79134
79140
|
}
|
|
79135
79141
|
}
|
|
79136
|
-
console.log(` ${
|
|
79142
|
+
console.log(` ${import_picocolors37.default.green("➜")} Poll: ${import_picocolors37.default.cyan(`${interval / 1000}s`)}`);
|
|
79137
79143
|
const skillsOk = repos.every((r2) => r2.setup.skillsAvailable);
|
|
79138
|
-
console.log(` ${
|
|
79144
|
+
console.log(` ${import_picocolors37.default.green("➜")} Skills: ${skillsOk ? import_picocolors37.default.green("available") : import_picocolors37.default.yellow("fallback mode")}`);
|
|
79139
79145
|
if (options2.dryRun) {
|
|
79140
|
-
console.log(` ${
|
|
79146
|
+
console.log(` ${import_picocolors37.default.yellow("➜")} Mode: ${import_picocolors37.default.yellow("DRY RUN (no responses posted)")}`);
|
|
79141
79147
|
}
|
|
79142
|
-
console.log(
|
|
79148
|
+
console.log(import_picocolors37.default.dim(" Press Ctrl+C to stop"));
|
|
79143
79149
|
console.log();
|
|
79144
79150
|
}
|
|
79145
79151
|
function formatQueueInfo(state) {
|
|
@@ -79316,7 +79322,7 @@ function registerCommands(cli) {
|
|
|
79316
79322
|
|
|
79317
79323
|
// src/cli/version-display.ts
|
|
79318
79324
|
import { existsSync as existsSync77, readFileSync as readFileSync20 } from "node:fs";
|
|
79319
|
-
import { join as
|
|
79325
|
+
import { join as join137 } from "node:path";
|
|
79320
79326
|
init_help_banner();
|
|
79321
79327
|
// src/domains/versioning/checking/kit-version-checker.ts
|
|
79322
79328
|
init_github_client();
|
|
@@ -79328,14 +79334,14 @@ init_logger();
|
|
|
79328
79334
|
init_path_resolver();
|
|
79329
79335
|
import { existsSync as existsSync76 } from "node:fs";
|
|
79330
79336
|
import { mkdir as mkdir35, readFile as readFile52, writeFile as writeFile40 } from "node:fs/promises";
|
|
79331
|
-
import { join as
|
|
79337
|
+
import { join as join136 } from "node:path";
|
|
79332
79338
|
|
|
79333
79339
|
class VersionCacheManager {
|
|
79334
79340
|
static CACHE_FILENAME = "version-check.json";
|
|
79335
79341
|
static CACHE_TTL_MS = 7 * 24 * 60 * 60 * 1000;
|
|
79336
79342
|
static getCacheFile() {
|
|
79337
79343
|
const cacheDir = PathResolver.getCacheDir(false);
|
|
79338
|
-
return
|
|
79344
|
+
return join136(cacheDir, VersionCacheManager.CACHE_FILENAME);
|
|
79339
79345
|
}
|
|
79340
79346
|
static async load() {
|
|
79341
79347
|
const cacheFile = VersionCacheManager.getCacheFile();
|
|
@@ -79485,7 +79491,7 @@ class CliVersionChecker {
|
|
|
79485
79491
|
}
|
|
79486
79492
|
}
|
|
79487
79493
|
// src/domains/versioning/checking/notification-display.ts
|
|
79488
|
-
var
|
|
79494
|
+
var import_picocolors41 = __toESM(require_picocolors(), 1);
|
|
79489
79495
|
function createNotificationBox2(borderColor, boxWidth) {
|
|
79490
79496
|
const contentWidth = boxWidth - 2;
|
|
79491
79497
|
const topBorder = borderColor(`╭${"─".repeat(contentWidth)}╮`);
|
|
@@ -79510,13 +79516,13 @@ function displayKitNotification(result, options2 = {}) {
|
|
|
79510
79516
|
const displayCurrent = normalizeVersion(currentVersion);
|
|
79511
79517
|
const displayLatest = normalizeVersion(latestVersion);
|
|
79512
79518
|
const boxWidth = 52;
|
|
79513
|
-
const { topBorder, bottomBorder, emptyLine, padLine } = createNotificationBox2(
|
|
79514
|
-
const headerText =
|
|
79519
|
+
const { topBorder, bottomBorder, emptyLine, padLine } = createNotificationBox2(import_picocolors41.default.cyan, boxWidth);
|
|
79520
|
+
const headerText = import_picocolors41.default.bold(import_picocolors41.default.yellow("⬆ Kit Update Available"));
|
|
79515
79521
|
const headerLen = "⬆ Kit Update Available".length;
|
|
79516
|
-
const versionText = `${
|
|
79522
|
+
const versionText = `${import_picocolors41.default.dim(displayCurrent)} ${import_picocolors41.default.white("→")} ${import_picocolors41.default.green(import_picocolors41.default.bold(displayLatest))}`;
|
|
79517
79523
|
const versionLen = displayCurrent.length + 3 + displayLatest.length;
|
|
79518
79524
|
const updateCmd = isGlobal ? "tkm init -g" : "tkm init";
|
|
79519
|
-
const commandText = `Run: ${
|
|
79525
|
+
const commandText = `Run: ${import_picocolors41.default.cyan(import_picocolors41.default.bold(updateCmd))}`;
|
|
79520
79526
|
const commandLen = `Run: ${updateCmd}`.length;
|
|
79521
79527
|
console.log("");
|
|
79522
79528
|
console.log(topBorder);
|
|
@@ -79534,12 +79540,12 @@ function displayCliNotification(result) {
|
|
|
79534
79540
|
return;
|
|
79535
79541
|
const { currentVersion, latestVersion } = result;
|
|
79536
79542
|
const boxWidth = 52;
|
|
79537
|
-
const { topBorder, bottomBorder, emptyLine, padLine } = createNotificationBox2(
|
|
79538
|
-
const headerText =
|
|
79543
|
+
const { topBorder, bottomBorder, emptyLine, padLine } = createNotificationBox2(import_picocolors41.default.magenta, boxWidth);
|
|
79544
|
+
const headerText = import_picocolors41.default.bold(import_picocolors41.default.yellow("⬆ CLI Update Available"));
|
|
79539
79545
|
const headerLen = "⬆ CLI Update Available".length;
|
|
79540
|
-
const versionText = `${
|
|
79546
|
+
const versionText = `${import_picocolors41.default.dim(currentVersion)} ${import_picocolors41.default.white("→")} ${import_picocolors41.default.green(import_picocolors41.default.bold(latestVersion))}`;
|
|
79541
79547
|
const versionLen = currentVersion.length + 3 + latestVersion.length;
|
|
79542
|
-
const commandText = `Run: ${
|
|
79548
|
+
const commandText = `Run: ${import_picocolors41.default.magenta(import_picocolors41.default.bold("tkm update"))}`;
|
|
79543
79549
|
const commandLen = "Run: tkm update".length;
|
|
79544
79550
|
console.log("");
|
|
79545
79551
|
console.log(topBorder);
|
|
@@ -79628,8 +79634,8 @@ async function displayVersion() {
|
|
|
79628
79634
|
const localSubdir = PROVIDER_LOCAL_SUBDIRS[provider];
|
|
79629
79635
|
if (!localSubdir)
|
|
79630
79636
|
continue;
|
|
79631
|
-
const localMeta =
|
|
79632
|
-
if (localMeta ===
|
|
79637
|
+
const localMeta = join137(process.cwd(), localSubdir, "metadata.json");
|
|
79638
|
+
if (localMeta === join137(inst.globalRoot(), "metadata.json"))
|
|
79633
79639
|
continue;
|
|
79634
79640
|
if (!existsSync77(localMeta))
|
|
79635
79641
|
continue;
|
|
@@ -79654,7 +79660,7 @@ async function displayVersion() {
|
|
|
79654
79660
|
}
|
|
79655
79661
|
const singleInstall = detectedGlobals.length === 1 && detectedGlobals[0]?.provider === "claude-code";
|
|
79656
79662
|
for (const { provider, path: installPath } of detectedGlobals) {
|
|
79657
|
-
const metadataPath =
|
|
79663
|
+
const metadataPath = join137(installPath, "metadata.json");
|
|
79658
79664
|
if (existsSync77(metadataPath)) {
|
|
79659
79665
|
try {
|
|
79660
79666
|
const rawMetadata = JSON.parse(readFileSync20(metadataPath, "utf-8"));
|
|
@@ -79708,7 +79714,7 @@ function getPackageVersion2() {
|
|
|
79708
79714
|
|
|
79709
79715
|
// src/shared/logger.ts
|
|
79710
79716
|
init_output_manager();
|
|
79711
|
-
var
|
|
79717
|
+
var import_picocolors42 = __toESM(require_picocolors(), 1);
|
|
79712
79718
|
import { createWriteStream as createWriteStream6 } from "node:fs";
|
|
79713
79719
|
|
|
79714
79720
|
class Logger2 {
|
|
@@ -79717,23 +79723,23 @@ class Logger2 {
|
|
|
79717
79723
|
exitHandlerRegistered = false;
|
|
79718
79724
|
info(message) {
|
|
79719
79725
|
const symbols = output.getSymbols();
|
|
79720
|
-
console.log(
|
|
79726
|
+
console.log(import_picocolors42.default.blue(symbols.info), message);
|
|
79721
79727
|
}
|
|
79722
79728
|
success(message) {
|
|
79723
79729
|
const symbols = output.getSymbols();
|
|
79724
|
-
console.log(
|
|
79730
|
+
console.log(import_picocolors42.default.green(symbols.success), message);
|
|
79725
79731
|
}
|
|
79726
79732
|
warning(message) {
|
|
79727
79733
|
const symbols = output.getSymbols();
|
|
79728
|
-
console.log(
|
|
79734
|
+
console.log(import_picocolors42.default.yellow(symbols.warning), message);
|
|
79729
79735
|
}
|
|
79730
79736
|
error(message) {
|
|
79731
79737
|
const symbols = output.getSymbols();
|
|
79732
|
-
console.error(
|
|
79738
|
+
console.error(import_picocolors42.default.red(symbols.error), message);
|
|
79733
79739
|
}
|
|
79734
79740
|
debug(message) {
|
|
79735
79741
|
if (process.env.DEBUG) {
|
|
79736
|
-
console.log(
|
|
79742
|
+
console.log(import_picocolors42.default.gray("[DEBUG]"), message);
|
|
79737
79743
|
}
|
|
79738
79744
|
}
|
|
79739
79745
|
verbose(message, context) {
|
|
@@ -79742,7 +79748,7 @@ class Logger2 {
|
|
|
79742
79748
|
const timestamp = this.getTimestamp();
|
|
79743
79749
|
const sanitizedMessage = this.sanitize(message);
|
|
79744
79750
|
const formattedContext = context ? this.formatContext(context) : "";
|
|
79745
|
-
const logLine = `${timestamp} ${
|
|
79751
|
+
const logLine = `${timestamp} ${import_picocolors42.default.gray("[VERBOSE]")} ${sanitizedMessage}${formattedContext}`;
|
|
79746
79752
|
console.error(logLine);
|
|
79747
79753
|
if (this.logFileStream) {
|
|
79748
79754
|
const plainLogLine = `${timestamp} [VERBOSE] ${sanitizedMessage}${formattedContext}`;
|
|
@@ -79845,7 +79851,7 @@ var logger3 = new Logger2;
|
|
|
79845
79851
|
|
|
79846
79852
|
// src/shared/output-manager.ts
|
|
79847
79853
|
init_terminal_utils();
|
|
79848
|
-
var
|
|
79854
|
+
var import_picocolors43 = __toESM(require_picocolors(), 1);
|
|
79849
79855
|
var SYMBOLS2 = {
|
|
79850
79856
|
unicode: {
|
|
79851
79857
|
prompt: "◇",
|
|
@@ -79926,7 +79932,7 @@ class OutputManager2 {
|
|
|
79926
79932
|
if (this.config.quiet)
|
|
79927
79933
|
return;
|
|
79928
79934
|
const symbol = this.getSymbols().success;
|
|
79929
|
-
console.log(
|
|
79935
|
+
console.log(import_picocolors43.default.green(`${symbol} ${message}`));
|
|
79930
79936
|
}
|
|
79931
79937
|
error(message, data) {
|
|
79932
79938
|
if (this.config.json) {
|
|
@@ -79934,7 +79940,7 @@ class OutputManager2 {
|
|
|
79934
79940
|
return;
|
|
79935
79941
|
}
|
|
79936
79942
|
const symbol = this.getSymbols().error;
|
|
79937
|
-
console.error(
|
|
79943
|
+
console.error(import_picocolors43.default.red(`${symbol} ${message}`));
|
|
79938
79944
|
}
|
|
79939
79945
|
warning(message, data) {
|
|
79940
79946
|
if (this.config.json) {
|
|
@@ -79944,7 +79950,7 @@ class OutputManager2 {
|
|
|
79944
79950
|
if (this.config.quiet)
|
|
79945
79951
|
return;
|
|
79946
79952
|
const symbol = this.getSymbols().warning;
|
|
79947
|
-
console.log(
|
|
79953
|
+
console.log(import_picocolors43.default.yellow(`${symbol} ${message}`));
|
|
79948
79954
|
}
|
|
79949
79955
|
info(message, data) {
|
|
79950
79956
|
if (this.config.json) {
|
|
@@ -79954,7 +79960,7 @@ class OutputManager2 {
|
|
|
79954
79960
|
if (this.config.quiet)
|
|
79955
79961
|
return;
|
|
79956
79962
|
const symbol = this.getSymbols().info;
|
|
79957
|
-
console.log(
|
|
79963
|
+
console.log(import_picocolors43.default.blue(`${symbol} ${message}`));
|
|
79958
79964
|
}
|
|
79959
79965
|
verbose(message, data) {
|
|
79960
79966
|
if (!this.config.verbose)
|
|
@@ -79963,7 +79969,7 @@ class OutputManager2 {
|
|
|
79963
79969
|
this.addJsonEntry({ type: "info", message, data });
|
|
79964
79970
|
return;
|
|
79965
79971
|
}
|
|
79966
|
-
console.log(
|
|
79972
|
+
console.log(import_picocolors43.default.dim(` ${message}`));
|
|
79967
79973
|
}
|
|
79968
79974
|
indent(message) {
|
|
79969
79975
|
if (this.config.json)
|
|
@@ -79988,7 +79994,7 @@ class OutputManager2 {
|
|
|
79988
79994
|
return;
|
|
79989
79995
|
const symbols = this.getSymbols();
|
|
79990
79996
|
console.log();
|
|
79991
|
-
console.log(
|
|
79997
|
+
console.log(import_picocolors43.default.bold(import_picocolors43.default.cyan(`${symbols.line} ${title}`)));
|
|
79992
79998
|
}
|
|
79993
79999
|
addJsonEntry(entry) {
|
|
79994
80000
|
this.jsonBuffer.push({
|