@sunasteriskrnd/takumi 0.5.0 → 0.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +605 -227
- package/package.json +2 -1
package/dist/index.js
CHANGED
|
@@ -11225,12 +11225,12 @@ function isSafeRelativeLayoutPath(value) {
|
|
|
11225
11225
|
return segments.every((segment) => segment.length > 0 && segment !== "." && segment !== "..");
|
|
11226
11226
|
}
|
|
11227
11227
|
function isValidKitType(value) {
|
|
11228
|
-
return value === "engineer";
|
|
11228
|
+
return value === "engineer" || value === "extras";
|
|
11229
11229
|
}
|
|
11230
|
-
var KitType, KitConfigSchema, KitLayoutSchema, TakumiPackageMetadataSchema, DEFAULT_KIT_LAYOUT, AVAILABLE_KITS, NEVER_COPY_PATTERNS, USER_CONFIG_PATTERNS, PROTECTED_PATTERNS;
|
|
11230
|
+
var KitType, KitConfigSchema, KitLayoutSchema, TakumiPackageMetadataSchema, DEFAULT_KIT_LAYOUT, AVAILABLE_KITS, BASE_KIT = "engineer", NEVER_COPY_PATTERNS, USER_CONFIG_PATTERNS, PROTECTED_PATTERNS;
|
|
11231
11231
|
var init_kit = __esm(() => {
|
|
11232
11232
|
init_zod();
|
|
11233
|
-
KitType = exports_external.enum(["engineer"]);
|
|
11233
|
+
KitType = exports_external.enum(["engineer", "extras"]);
|
|
11234
11234
|
KitConfigSchema = exports_external.object({
|
|
11235
11235
|
id: KitType,
|
|
11236
11236
|
name: exports_external.string(),
|
|
@@ -11256,6 +11256,13 @@ var init_kit = __esm(() => {
|
|
|
11256
11256
|
repo: "takumi",
|
|
11257
11257
|
owner: "sun-asterisk-internal",
|
|
11258
11258
|
description: "Engineering toolkit for building with Claude"
|
|
11259
|
+
},
|
|
11260
|
+
extras: {
|
|
11261
|
+
id: "extras",
|
|
11262
|
+
name: "Takumi Extras",
|
|
11263
|
+
repo: "takumi-extras",
|
|
11264
|
+
owner: "sun-asterisk-internal",
|
|
11265
|
+
description: "Extras agent kit"
|
|
11259
11266
|
}
|
|
11260
11267
|
};
|
|
11261
11268
|
NEVER_COPY_PATTERNS = [
|
|
@@ -11444,13 +11451,14 @@ var init_metadata = __esm(() => {
|
|
|
11444
11451
|
KitMetadataSchema = exports_external.object({
|
|
11445
11452
|
version: exports_external.string(),
|
|
11446
11453
|
installedAt: exports_external.string(),
|
|
11454
|
+
installState: exports_external.enum(["pending", "complete"]).optional(),
|
|
11447
11455
|
files: exports_external.array(TrackedFileSchema).optional(),
|
|
11448
11456
|
lastUpdateCheck: exports_external.string().optional(),
|
|
11449
11457
|
dismissedVersion: exports_external.string().optional(),
|
|
11450
11458
|
installedSettings: InstalledSettingsSchema.optional()
|
|
11451
11459
|
});
|
|
11452
11460
|
MultiKitMetadataSchema = exports_external.object({
|
|
11453
|
-
kits: exports_external.record(
|
|
11461
|
+
kits: exports_external.record(exports_external.string(), KitMetadataSchema).optional(),
|
|
11454
11462
|
scope: exports_external.enum(["local", "global"]).optional(),
|
|
11455
11463
|
name: exports_external.string().optional(),
|
|
11456
11464
|
version: exports_external.string().optional(),
|
|
@@ -12116,6 +12124,7 @@ __export(exports_types, {
|
|
|
12116
12124
|
DEFAULT_FOLDERS: () => DEFAULT_FOLDERS,
|
|
12117
12125
|
ConfigSchema: () => ConfigSchema,
|
|
12118
12126
|
CodingLevelSchema: () => CodingLevelSchema,
|
|
12127
|
+
BASE_KIT: () => BASE_KIT,
|
|
12119
12128
|
AuthenticationError: () => AuthenticationError,
|
|
12120
12129
|
ApiStatusOptionsSchema: () => ApiStatusOptionsSchema,
|
|
12121
12130
|
ApiSetupOptionsSchema: () => ApiSetupOptionsSchema,
|
|
@@ -34554,9 +34563,9 @@ __export(exports_worktree_manager, {
|
|
|
34554
34563
|
});
|
|
34555
34564
|
import { existsSync as existsSync60 } from "node:fs";
|
|
34556
34565
|
import { readFile as readFile49, writeFile as writeFile36 } from "node:fs/promises";
|
|
34557
|
-
import { join as
|
|
34566
|
+
import { join as join120 } from "node:path";
|
|
34558
34567
|
async function createWorktree(projectDir, issueNumber, baseBranch) {
|
|
34559
|
-
const worktreePath =
|
|
34568
|
+
const worktreePath = join120(projectDir, WORKTREE_DIR, `issue-${issueNumber}`);
|
|
34560
34569
|
const branchName = `sk-watch/issue-${issueNumber}`;
|
|
34561
34570
|
await spawnAndCollect("git", ["fetch", "origin", baseBranch], projectDir).catch(() => {
|
|
34562
34571
|
logger.warning(`[worktree] Could not fetch origin/${baseBranch}, using local`);
|
|
@@ -34574,7 +34583,7 @@ async function createWorktree(projectDir, issueNumber, baseBranch) {
|
|
|
34574
34583
|
return worktreePath;
|
|
34575
34584
|
}
|
|
34576
34585
|
async function removeWorktree(projectDir, issueNumber) {
|
|
34577
|
-
const worktreePath =
|
|
34586
|
+
const worktreePath = join120(projectDir, WORKTREE_DIR, `issue-${issueNumber}`);
|
|
34578
34587
|
const branchName = `sk-watch/issue-${issueNumber}`;
|
|
34579
34588
|
try {
|
|
34580
34589
|
await spawnAndCollect("git", ["worktree", "remove", worktreePath, "--force"], projectDir);
|
|
@@ -34588,7 +34597,7 @@ async function listActiveWorktrees(projectDir) {
|
|
|
34588
34597
|
try {
|
|
34589
34598
|
const output2 = await spawnAndCollect("git", ["worktree", "list", "--porcelain"], projectDir);
|
|
34590
34599
|
const issueNumbers = [];
|
|
34591
|
-
const worktreePrefix =
|
|
34600
|
+
const worktreePrefix = join120(projectDir, WORKTREE_DIR, "issue-").replace(/\\/g, "/");
|
|
34592
34601
|
for (const line of output2.split(`
|
|
34593
34602
|
`)) {
|
|
34594
34603
|
if (line.startsWith("worktree ")) {
|
|
@@ -34616,7 +34625,7 @@ async function cleanupAllWorktrees(projectDir) {
|
|
|
34616
34625
|
await spawnAndCollect("git", ["worktree", "prune"], projectDir).catch(() => {});
|
|
34617
34626
|
}
|
|
34618
34627
|
async function ensureGitignore(projectDir) {
|
|
34619
|
-
const gitignorePath =
|
|
34628
|
+
const gitignorePath = join120(projectDir, ".gitignore");
|
|
34620
34629
|
try {
|
|
34621
34630
|
const content = existsSync60(gitignorePath) ? await readFile49(gitignorePath, "utf-8") : "";
|
|
34622
34631
|
if (!content.includes(".worktrees")) {
|
|
@@ -34723,7 +34732,7 @@ import { createHash as createHash8 } from "node:crypto";
|
|
|
34723
34732
|
import { existsSync as existsSync66, mkdirSync as mkdirSync4, readFileSync as readFileSync16, readdirSync as readdirSync10, statSync as statSync7 } from "node:fs";
|
|
34724
34733
|
import { rename as rename10, writeFile as writeFile38 } from "node:fs/promises";
|
|
34725
34734
|
import { homedir as homedir32 } from "node:os";
|
|
34726
|
-
import { basename as basename17, join as
|
|
34735
|
+
import { basename as basename17, join as join127 } from "node:path";
|
|
34727
34736
|
function getCachedContext(repoPath) {
|
|
34728
34737
|
const cachePath = getCacheFilePath(repoPath);
|
|
34729
34738
|
if (!existsSync66(cachePath))
|
|
@@ -34766,25 +34775,25 @@ function computeSourceHash(repoPath) {
|
|
|
34766
34775
|
}
|
|
34767
34776
|
function getDocSourcePaths(repoPath) {
|
|
34768
34777
|
const paths = [];
|
|
34769
|
-
const docsDir =
|
|
34778
|
+
const docsDir = join127(repoPath, "docs");
|
|
34770
34779
|
if (existsSync66(docsDir)) {
|
|
34771
34780
|
try {
|
|
34772
34781
|
const files = readdirSync10(docsDir);
|
|
34773
34782
|
for (const f4 of files) {
|
|
34774
34783
|
if (f4.endsWith(".md"))
|
|
34775
|
-
paths.push(
|
|
34784
|
+
paths.push(join127(docsDir, f4));
|
|
34776
34785
|
}
|
|
34777
34786
|
} catch {}
|
|
34778
34787
|
}
|
|
34779
|
-
const readme =
|
|
34788
|
+
const readme = join127(repoPath, "README.md");
|
|
34780
34789
|
if (existsSync66(readme))
|
|
34781
34790
|
paths.push(readme);
|
|
34782
|
-
const stylesDir =
|
|
34791
|
+
const stylesDir = join127(repoPath, "assets", "writing-styles");
|
|
34783
34792
|
if (existsSync66(stylesDir)) {
|
|
34784
34793
|
try {
|
|
34785
34794
|
const files = readdirSync10(stylesDir);
|
|
34786
34795
|
for (const f4 of files) {
|
|
34787
|
-
paths.push(
|
|
34796
|
+
paths.push(join127(stylesDir, f4));
|
|
34788
34797
|
}
|
|
34789
34798
|
} catch {}
|
|
34790
34799
|
}
|
|
@@ -34793,11 +34802,11 @@ function getDocSourcePaths(repoPath) {
|
|
|
34793
34802
|
function getCacheFilePath(repoPath) {
|
|
34794
34803
|
const repoName = basename17(repoPath).replace(/[^a-zA-Z0-9_-]/g, "_");
|
|
34795
34804
|
const pathHash = createHash8("sha256").update(repoPath).digest("hex").slice(0, 8);
|
|
34796
|
-
return
|
|
34805
|
+
return join127(CACHE_DIR, `${repoName}-${pathHash}-context-cache.json`);
|
|
34797
34806
|
}
|
|
34798
34807
|
var CACHE_DIR, CACHE_TTL_MS3;
|
|
34799
34808
|
var init_context_cache_manager = __esm(() => {
|
|
34800
|
-
CACHE_DIR =
|
|
34809
|
+
CACHE_DIR = join127(homedir32(), ".sunagentkit", "cache");
|
|
34801
34810
|
CACHE_TTL_MS3 = 24 * 60 * 60 * 1000;
|
|
34802
34811
|
});
|
|
34803
34812
|
|
|
@@ -34978,7 +34987,7 @@ function extractContentFromResponse(response) {
|
|
|
34978
34987
|
// src/commands/content/phases/docs-summarizer.ts
|
|
34979
34988
|
import { execSync as execSync5 } from "node:child_process";
|
|
34980
34989
|
import { existsSync as existsSync67, readFileSync as readFileSync17, readdirSync as readdirSync11 } from "node:fs";
|
|
34981
|
-
import { join as
|
|
34990
|
+
import { join as join128 } from "node:path";
|
|
34982
34991
|
async function summarizeProjectDocs(repoPath, contentLogger) {
|
|
34983
34992
|
const rawContent = collectRawDocs(repoPath);
|
|
34984
34993
|
if (rawContent.total.length < 200) {
|
|
@@ -35032,12 +35041,12 @@ function collectRawDocs(repoPath) {
|
|
|
35032
35041
|
return capped;
|
|
35033
35042
|
};
|
|
35034
35043
|
const docsContent = [];
|
|
35035
|
-
const docsDir =
|
|
35044
|
+
const docsDir = join128(repoPath, "docs");
|
|
35036
35045
|
if (existsSync67(docsDir)) {
|
|
35037
35046
|
try {
|
|
35038
35047
|
const files = readdirSync11(docsDir).filter((f4) => f4.endsWith(".md")).sort();
|
|
35039
35048
|
for (const f4 of files) {
|
|
35040
|
-
const content = readCapped(
|
|
35049
|
+
const content = readCapped(join128(docsDir, f4), 5000);
|
|
35041
35050
|
if (content) {
|
|
35042
35051
|
docsContent.push(`### ${f4}
|
|
35043
35052
|
${content}`);
|
|
@@ -35051,21 +35060,21 @@ ${content}`);
|
|
|
35051
35060
|
let brand = "";
|
|
35052
35061
|
const brandCandidates = ["docs/brand-guidelines.md", "docs/design-guidelines.md"];
|
|
35053
35062
|
for (const p2 of brandCandidates) {
|
|
35054
|
-
brand = readCapped(
|
|
35063
|
+
brand = readCapped(join128(repoPath, p2), 3000);
|
|
35055
35064
|
if (brand)
|
|
35056
35065
|
break;
|
|
35057
35066
|
}
|
|
35058
35067
|
let styles3 = "";
|
|
35059
|
-
const stylesDir =
|
|
35068
|
+
const stylesDir = join128(repoPath, "assets", "writing-styles");
|
|
35060
35069
|
if (existsSync67(stylesDir)) {
|
|
35061
35070
|
try {
|
|
35062
35071
|
const files = readdirSync11(stylesDir).slice(0, 3);
|
|
35063
|
-
styles3 = files.map((f4) => readCapped(
|
|
35072
|
+
styles3 = files.map((f4) => readCapped(join128(stylesDir, f4), 1000)).filter(Boolean).join(`
|
|
35064
35073
|
|
|
35065
35074
|
`);
|
|
35066
35075
|
} catch {}
|
|
35067
35076
|
}
|
|
35068
|
-
const readme = readCapped(
|
|
35077
|
+
const readme = readCapped(join128(repoPath, "README.md"), 3000);
|
|
35069
35078
|
const total = [docs, brand, styles3, readme].join(`
|
|
35070
35079
|
`);
|
|
35071
35080
|
return { docs, brand, styles: styles3, readme, total };
|
|
@@ -35252,9 +35261,9 @@ IMPORTANT: Generate the image and output the path as JSON: {"imagePath": "/path/
|
|
|
35252
35261
|
import { execSync as execSync6 } from "node:child_process";
|
|
35253
35262
|
import { existsSync as existsSync68, mkdirSync as mkdirSync5, readdirSync as readdirSync12 } from "node:fs";
|
|
35254
35263
|
import { homedir as homedir33 } from "node:os";
|
|
35255
|
-
import { join as
|
|
35264
|
+
import { join as join129 } from "node:path";
|
|
35256
35265
|
async function generatePhoto(_content, context, config, platform10, contentId, contentLogger) {
|
|
35257
|
-
const mediaDir =
|
|
35266
|
+
const mediaDir = join129(config.contentDir.replace(/^~/, homedir33()), "media", String(contentId));
|
|
35258
35267
|
if (!existsSync68(mediaDir)) {
|
|
35259
35268
|
mkdirSync5(mediaDir, { recursive: true });
|
|
35260
35269
|
}
|
|
@@ -35279,7 +35288,7 @@ async function generatePhoto(_content, context, config, platform10, contentId, c
|
|
|
35279
35288
|
const imageFile = files.find((f4) => /\.(png|jpg|jpeg|webp)$/i.test(f4));
|
|
35280
35289
|
if (imageFile) {
|
|
35281
35290
|
const ext2 = imageFile.split(".").pop() ?? "png";
|
|
35282
|
-
return { path:
|
|
35291
|
+
return { path: join129(mediaDir, imageFile), ...dimensions, format: ext2 };
|
|
35283
35292
|
}
|
|
35284
35293
|
contentLogger.warn(`Photo generation produced no image for content ${contentId}`);
|
|
35285
35294
|
return null;
|
|
@@ -35369,7 +35378,7 @@ var init_content_creator = __esm(() => {
|
|
|
35369
35378
|
// src/commands/content/phases/content-logger.ts
|
|
35370
35379
|
import { createWriteStream as createWriteStream5, existsSync as existsSync69, mkdirSync as mkdirSync6, statSync as statSync8 } from "node:fs";
|
|
35371
35380
|
import { homedir as homedir34 } from "node:os";
|
|
35372
|
-
import { join as
|
|
35381
|
+
import { join as join130 } from "node:path";
|
|
35373
35382
|
|
|
35374
35383
|
class ContentLogger {
|
|
35375
35384
|
stream = null;
|
|
@@ -35377,7 +35386,7 @@ class ContentLogger {
|
|
|
35377
35386
|
logDir;
|
|
35378
35387
|
maxBytes;
|
|
35379
35388
|
constructor(maxBytes = 0) {
|
|
35380
|
-
this.logDir =
|
|
35389
|
+
this.logDir = join130(homedir34(), ".sunagentkit", "logs");
|
|
35381
35390
|
this.maxBytes = maxBytes;
|
|
35382
35391
|
}
|
|
35383
35392
|
init() {
|
|
@@ -35409,7 +35418,7 @@ class ContentLogger {
|
|
|
35409
35418
|
}
|
|
35410
35419
|
}
|
|
35411
35420
|
getLogPath() {
|
|
35412
|
-
return
|
|
35421
|
+
return join130(this.logDir, `content-${this.getDateStr()}.log`);
|
|
35413
35422
|
}
|
|
35414
35423
|
write(level, message) {
|
|
35415
35424
|
this.rotateIfNeeded();
|
|
@@ -35426,18 +35435,18 @@ class ContentLogger {
|
|
|
35426
35435
|
if (dateStr !== this.currentDate) {
|
|
35427
35436
|
this.close();
|
|
35428
35437
|
this.currentDate = dateStr;
|
|
35429
|
-
const logPath =
|
|
35438
|
+
const logPath = join130(this.logDir, `content-${dateStr}.log`);
|
|
35430
35439
|
this.stream = createWriteStream5(logPath, { flags: "a", mode: 384 });
|
|
35431
35440
|
return;
|
|
35432
35441
|
}
|
|
35433
35442
|
if (this.maxBytes > 0 && this.stream) {
|
|
35434
|
-
const logPath =
|
|
35443
|
+
const logPath = join130(this.logDir, `content-${this.currentDate}.log`);
|
|
35435
35444
|
try {
|
|
35436
35445
|
const stat16 = statSync8(logPath);
|
|
35437
35446
|
if (stat16.size >= this.maxBytes) {
|
|
35438
35447
|
this.close();
|
|
35439
35448
|
const suffix = Date.now();
|
|
35440
|
-
const rotatedPath =
|
|
35449
|
+
const rotatedPath = join130(this.logDir, `content-${this.currentDate}-${suffix}.log`);
|
|
35441
35450
|
import("node:fs/promises").then(({ rename: rename11 }) => rename11(logPath, rotatedPath).catch(() => {}));
|
|
35442
35451
|
this.stream = createWriteStream5(logPath, { flags: "w", mode: 384 });
|
|
35443
35452
|
}
|
|
@@ -35663,7 +35672,7 @@ function isNoiseCommit(title, author) {
|
|
|
35663
35672
|
// src/commands/content/phases/change-detector.ts
|
|
35664
35673
|
import { execSync as execSync8 } from "node:child_process";
|
|
35665
35674
|
import { existsSync as existsSync71, readFileSync as readFileSync18, readdirSync as readdirSync13, statSync as statSync9 } from "node:fs";
|
|
35666
|
-
import { join as
|
|
35675
|
+
import { join as join131 } from "node:path";
|
|
35667
35676
|
function detectCommits(repo, since) {
|
|
35668
35677
|
try {
|
|
35669
35678
|
const fetchUrl = sshToHttps(repo.remoteUrl);
|
|
@@ -35761,7 +35770,7 @@ function detectTags(repo, since) {
|
|
|
35761
35770
|
}
|
|
35762
35771
|
}
|
|
35763
35772
|
function detectCompletedPlans(repo, since) {
|
|
35764
|
-
const plansDir =
|
|
35773
|
+
const plansDir = join131(repo.path, "plans");
|
|
35765
35774
|
if (!existsSync71(plansDir))
|
|
35766
35775
|
return [];
|
|
35767
35776
|
const sinceMs = new Date(since).getTime();
|
|
@@ -35771,7 +35780,7 @@ function detectCompletedPlans(repo, since) {
|
|
|
35771
35780
|
for (const entry of entries) {
|
|
35772
35781
|
if (!entry.isDirectory())
|
|
35773
35782
|
continue;
|
|
35774
|
-
const planFile =
|
|
35783
|
+
const planFile = join131(plansDir, entry.name, "plan.md");
|
|
35775
35784
|
if (!existsSync71(planFile))
|
|
35776
35785
|
continue;
|
|
35777
35786
|
try {
|
|
@@ -35849,7 +35858,7 @@ function classifyCommit(event) {
|
|
|
35849
35858
|
// src/commands/content/phases/repo-discoverer.ts
|
|
35850
35859
|
import { execSync as execSync9 } from "node:child_process";
|
|
35851
35860
|
import { readdirSync as readdirSync14 } from "node:fs";
|
|
35852
|
-
import { join as
|
|
35861
|
+
import { join as join132 } from "node:path";
|
|
35853
35862
|
function discoverRepos2(cwd2) {
|
|
35854
35863
|
const repos = [];
|
|
35855
35864
|
if (isGitRepoRoot(cwd2)) {
|
|
@@ -35862,7 +35871,7 @@ function discoverRepos2(cwd2) {
|
|
|
35862
35871
|
for (const entry of entries) {
|
|
35863
35872
|
if (!entry.isDirectory() || entry.name.startsWith("."))
|
|
35864
35873
|
continue;
|
|
35865
|
-
const dirPath =
|
|
35874
|
+
const dirPath = join132(cwd2, entry.name);
|
|
35866
35875
|
if (isGitRepoRoot(dirPath)) {
|
|
35867
35876
|
const info = getRepoInfo(dirPath);
|
|
35868
35877
|
if (info)
|
|
@@ -36529,9 +36538,9 @@ var init_types3 = __esm(() => {
|
|
|
36529
36538
|
|
|
36530
36539
|
// src/commands/content/phases/state-manager.ts
|
|
36531
36540
|
import { readFile as readFile51, rename as rename11, writeFile as writeFile39 } from "node:fs/promises";
|
|
36532
|
-
import { join as
|
|
36541
|
+
import { join as join133 } from "node:path";
|
|
36533
36542
|
async function loadContentConfig(projectDir) {
|
|
36534
|
-
const configPath =
|
|
36543
|
+
const configPath = join133(projectDir, TAKUMI_CONFIG_FILE2);
|
|
36535
36544
|
try {
|
|
36536
36545
|
const raw = await readFile51(configPath, "utf-8");
|
|
36537
36546
|
const json = JSON.parse(raw);
|
|
@@ -36541,13 +36550,13 @@ async function loadContentConfig(projectDir) {
|
|
|
36541
36550
|
}
|
|
36542
36551
|
}
|
|
36543
36552
|
async function saveContentConfig(projectDir, config) {
|
|
36544
|
-
const configPath =
|
|
36553
|
+
const configPath = join133(projectDir, TAKUMI_CONFIG_FILE2);
|
|
36545
36554
|
const json = await readJsonSafe(configPath);
|
|
36546
36555
|
json.content = { ...json.content, ...config };
|
|
36547
36556
|
await atomicWrite3(configPath, json);
|
|
36548
36557
|
}
|
|
36549
36558
|
async function loadContentState(projectDir) {
|
|
36550
|
-
const configPath =
|
|
36559
|
+
const configPath = join133(projectDir, TAKUMI_CONFIG_FILE2);
|
|
36551
36560
|
try {
|
|
36552
36561
|
const raw = await readFile51(configPath, "utf-8");
|
|
36553
36562
|
const json = JSON.parse(raw);
|
|
@@ -36558,7 +36567,7 @@ async function loadContentState(projectDir) {
|
|
|
36558
36567
|
}
|
|
36559
36568
|
}
|
|
36560
36569
|
async function saveContentState(projectDir, state) {
|
|
36561
|
-
const configPath =
|
|
36570
|
+
const configPath = join133(projectDir, TAKUMI_CONFIG_FILE2);
|
|
36562
36571
|
const sevenDaysAgo = new Date(Date.now() - 7 * 24 * 60 * 60 * 1000).toISOString().slice(0, 10);
|
|
36563
36572
|
for (const key of Object.keys(state.dailyPostCounts)) {
|
|
36564
36573
|
const dateStr = key.slice(-10);
|
|
@@ -36840,7 +36849,7 @@ var init_platform_setup_x = __esm(() => {
|
|
|
36840
36849
|
|
|
36841
36850
|
// src/commands/content/phases/setup-wizard.ts
|
|
36842
36851
|
import { existsSync as existsSync72 } from "node:fs";
|
|
36843
|
-
import { join as
|
|
36852
|
+
import { join as join134 } from "node:path";
|
|
36844
36853
|
async function runSetupWizard2(cwd2, contentLogger) {
|
|
36845
36854
|
console.log();
|
|
36846
36855
|
oe(import_picocolors40.default.bgCyan(import_picocolors40.default.white(" SK Content — Multi-Channel Content Engine ")));
|
|
@@ -36908,8 +36917,8 @@ async function showRepoSummary(cwd2) {
|
|
|
36908
36917
|
function detectBrandAssets(cwd2, contentLogger) {
|
|
36909
36918
|
const repos = discoverRepos2(cwd2);
|
|
36910
36919
|
for (const repo of repos) {
|
|
36911
|
-
const hasGuidelines = existsSync72(
|
|
36912
|
-
const hasStyles = existsSync72(
|
|
36920
|
+
const hasGuidelines = existsSync72(join134(repo.path, "docs", "brand-guidelines.md"));
|
|
36921
|
+
const hasStyles = existsSync72(join134(repo.path, "assets", "writing-styles"));
|
|
36913
36922
|
if (!hasGuidelines) {
|
|
36914
36923
|
f2.warning(`${repo.name}: No docs/brand-guidelines.md — content will use generic tone.`);
|
|
36915
36924
|
contentLogger.warn(`${repo.name}: missing docs/brand-guidelines.md`);
|
|
@@ -37051,9 +37060,9 @@ __export(exports_content_subcommands, {
|
|
|
37051
37060
|
});
|
|
37052
37061
|
import { existsSync as existsSync74, readFileSync as readFileSync19, unlinkSync as unlinkSync6 } from "node:fs";
|
|
37053
37062
|
import { homedir as homedir36 } from "node:os";
|
|
37054
|
-
import { join as
|
|
37063
|
+
import { join as join135 } from "node:path";
|
|
37055
37064
|
function isDaemonRunning() {
|
|
37056
|
-
const lockFile =
|
|
37065
|
+
const lockFile = join135(LOCK_DIR, `${LOCK_NAME2}.lock`);
|
|
37057
37066
|
if (!existsSync74(lockFile))
|
|
37058
37067
|
return { running: false, pid: null };
|
|
37059
37068
|
try {
|
|
@@ -37085,7 +37094,7 @@ async function startContent(options2) {
|
|
|
37085
37094
|
await contentCommand(options2);
|
|
37086
37095
|
}
|
|
37087
37096
|
async function stopContent() {
|
|
37088
|
-
const lockFile =
|
|
37097
|
+
const lockFile = join135(LOCK_DIR, `${LOCK_NAME2}.lock`);
|
|
37089
37098
|
if (!existsSync74(lockFile)) {
|
|
37090
37099
|
logger.info("Content daemon is not running.");
|
|
37091
37100
|
return;
|
|
@@ -37124,9 +37133,9 @@ async function statusContent() {
|
|
|
37124
37133
|
} catch {}
|
|
37125
37134
|
}
|
|
37126
37135
|
async function logsContent(options2) {
|
|
37127
|
-
const logDir =
|
|
37136
|
+
const logDir = join135(homedir36(), ".sunagentkit", "logs");
|
|
37128
37137
|
const dateStr = new Date().toISOString().slice(0, 10).replace(/-/g, "");
|
|
37129
|
-
const logPath =
|
|
37138
|
+
const logPath = join135(logDir, `content-${dateStr}.log`);
|
|
37130
37139
|
if (!existsSync74(logPath)) {
|
|
37131
37140
|
logger.info("No content logs found for today.");
|
|
37132
37141
|
return;
|
|
@@ -37158,13 +37167,13 @@ var init_content_subcommands = __esm(() => {
|
|
|
37158
37167
|
init_setup_wizard();
|
|
37159
37168
|
init_state_manager();
|
|
37160
37169
|
init_content_review_commands();
|
|
37161
|
-
LOCK_DIR =
|
|
37170
|
+
LOCK_DIR = join135(homedir36(), ".sunagentkit", "locks");
|
|
37162
37171
|
});
|
|
37163
37172
|
|
|
37164
37173
|
// src/commands/content/content-command.ts
|
|
37165
37174
|
import { existsSync as existsSync75, mkdirSync as mkdirSync8, unlinkSync as unlinkSync7, writeFileSync as writeFileSync6 } from "node:fs";
|
|
37166
37175
|
import { homedir as homedir37 } from "node:os";
|
|
37167
|
-
import { join as
|
|
37176
|
+
import { join as join136 } from "node:path";
|
|
37168
37177
|
async function contentCommand(options2) {
|
|
37169
37178
|
const cwd2 = process.cwd();
|
|
37170
37179
|
const contentLogger = new ContentLogger;
|
|
@@ -37342,8 +37351,8 @@ var init_content_command = __esm(() => {
|
|
|
37342
37351
|
init_publisher();
|
|
37343
37352
|
init_review_manager();
|
|
37344
37353
|
init_state_manager();
|
|
37345
|
-
LOCK_DIR2 =
|
|
37346
|
-
LOCK_FILE =
|
|
37354
|
+
LOCK_DIR2 = join136(homedir37(), ".sunagentkit", "locks");
|
|
37355
|
+
LOCK_FILE = join136(LOCK_DIR2, "sk-content.lock");
|
|
37347
37356
|
});
|
|
37348
37357
|
|
|
37349
37358
|
// src/commands/content/index.ts
|
|
@@ -49278,28 +49287,32 @@ var import_fs_extra6 = __toESM(require_lib(), 1);
|
|
|
49278
49287
|
var import_picomatch = __toESM(require_picomatch2(), 1);
|
|
49279
49288
|
function findFileInMetadata(metadata, path3) {
|
|
49280
49289
|
if (!metadata)
|
|
49281
|
-
return null;
|
|
49290
|
+
return { tracked: null, ownerKit: null };
|
|
49282
49291
|
if (metadata.kits) {
|
|
49283
|
-
for (const kitMeta of Object.
|
|
49284
|
-
if (kitMeta?.files)
|
|
49285
|
-
|
|
49286
|
-
|
|
49287
|
-
|
|
49288
|
-
|
|
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 };
|
|
49289
49298
|
}
|
|
49290
49299
|
}
|
|
49291
49300
|
if (metadata.files) {
|
|
49292
49301
|
const found = metadata.files.find((f3) => f3.path === path3);
|
|
49293
49302
|
if (found)
|
|
49294
|
-
return found;
|
|
49303
|
+
return { tracked: found, ownerKit: null };
|
|
49295
49304
|
}
|
|
49296
|
-
return null;
|
|
49305
|
+
return { tracked: null, ownerKit: null };
|
|
49297
49306
|
}
|
|
49298
|
-
function shouldDeletePath(path3, metadata) {
|
|
49299
|
-
const tracked = findFileInMetadata(metadata, path3);
|
|
49307
|
+
function shouldDeletePath(path3, metadata, installingKit) {
|
|
49308
|
+
const { tracked, ownerKit } = findFileInMetadata(metadata, path3);
|
|
49300
49309
|
if (!tracked)
|
|
49301
49310
|
return true;
|
|
49302
|
-
|
|
49311
|
+
if (tracked.ownership === "user")
|
|
49312
|
+
return false;
|
|
49313
|
+
if (installingKit && ownerKit && ownerKit !== installingKit)
|
|
49314
|
+
return false;
|
|
49315
|
+
return true;
|
|
49303
49316
|
}
|
|
49304
49317
|
function collectFilesRecursively(dir, baseDir) {
|
|
49305
49318
|
const results = [];
|
|
@@ -49422,7 +49435,7 @@ async function updateMetadataAfterDeletion(claudeDir, deletedPaths) {
|
|
|
49422
49435
|
logger.debug("Failed to write updated metadata.json");
|
|
49423
49436
|
}
|
|
49424
49437
|
}
|
|
49425
|
-
async function handleDeletions(sourceMetadata, claudeDir) {
|
|
49438
|
+
async function handleDeletions(sourceMetadata, claudeDir, installingKit) {
|
|
49426
49439
|
const deletionPatterns = sourceMetadata.deletions || [];
|
|
49427
49440
|
if (deletionPatterns.length === 0) {
|
|
49428
49441
|
return { deletedPaths: [], preservedPaths: [], errors: [] };
|
|
@@ -49439,9 +49452,9 @@ async function handleDeletions(sourceMetadata, claudeDir) {
|
|
|
49439
49452
|
result.errors.push(path3);
|
|
49440
49453
|
continue;
|
|
49441
49454
|
}
|
|
49442
|
-
if (!shouldDeletePath(path3, userMetadata)) {
|
|
49455
|
+
if (!shouldDeletePath(path3, userMetadata, installingKit)) {
|
|
49443
49456
|
result.preservedPaths.push(path3);
|
|
49444
|
-
logger.verbose(`Preserved user
|
|
49457
|
+
logger.verbose(`Preserved file (cross-kit or user-owned): ${path3}`);
|
|
49445
49458
|
continue;
|
|
49446
49459
|
}
|
|
49447
49460
|
if (existsSync13(fullPath)) {
|
|
@@ -52510,14 +52523,17 @@ async function writeManifest(providerRoot, kitName, version3, scope, kitType, tr
|
|
|
52510
52523
|
logger.debug(`Could not read existing metadata: ${error}`);
|
|
52511
52524
|
}
|
|
52512
52525
|
}
|
|
52526
|
+
const existingKits = existingMetadata.kits || {};
|
|
52527
|
+
const otherKitsExist = Object.keys(existingKits).some((k2) => k2 !== kit);
|
|
52513
52528
|
const installedAt = new Date().toISOString();
|
|
52529
|
+
const existingKitMeta = existingKits[kit];
|
|
52514
52530
|
const kitMetadata = {
|
|
52531
|
+
...existingKitMeta ?? {},
|
|
52515
52532
|
version: version3,
|
|
52516
52533
|
installedAt,
|
|
52534
|
+
installState: "complete",
|
|
52517
52535
|
files: trackedFiles.length > 0 ? trackedFiles : undefined
|
|
52518
52536
|
};
|
|
52519
|
-
const existingKits = existingMetadata.kits || {};
|
|
52520
|
-
const otherKitsExist = Object.keys(existingKits).some((k2) => k2 !== kit);
|
|
52521
52537
|
const metadata = {
|
|
52522
52538
|
kits: {
|
|
52523
52539
|
...existingKits,
|
|
@@ -52548,6 +52564,69 @@ async function writeManifest(providerRoot, kitName, version3, scope, kitType, tr
|
|
|
52548
52564
|
}
|
|
52549
52565
|
}
|
|
52550
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
|
+
}
|
|
52551
52630
|
async function removeKitFromManifest(providerRoot, kit) {
|
|
52552
52631
|
const metadataPath = join28(providerRoot, "metadata.json");
|
|
52553
52632
|
if (!await import_fs_extra10.pathExists(metadataPath))
|
|
@@ -52749,6 +52828,12 @@ class ManifestWriter {
|
|
|
52749
52828
|
async writeManifest(providerRoot, kitName, version3, scope, kitType) {
|
|
52750
52829
|
return writeManifest(providerRoot, kitName, version3, scope, kitType, this.getTrackedFiles(), this.getUserConfigFiles());
|
|
52751
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
|
+
}
|
|
52752
52837
|
static async readManifest(providerRoot) {
|
|
52753
52838
|
return readManifest(providerRoot);
|
|
52754
52839
|
}
|
|
@@ -53716,7 +53801,7 @@ async function handleMerge(ctx) {
|
|
|
53716
53801
|
}
|
|
53717
53802
|
try {
|
|
53718
53803
|
if (sourceMetadata?.deletions && sourceMetadata.deletions.length > 0) {
|
|
53719
|
-
const deletionResult = await handleDeletions(sourceMetadata, ctx.claudeDir);
|
|
53804
|
+
const deletionResult = await handleDeletions(sourceMetadata, ctx.claudeDir, ctx.kitType);
|
|
53720
53805
|
if (deletionResult.deletedPaths.length > 0) {
|
|
53721
53806
|
logger.info(`Removed ${deletionResult.deletedPaths.length} deprecated file(s)`);
|
|
53722
53807
|
for (const path4 of deletionResult.deletedPaths) {
|
|
@@ -63269,6 +63354,9 @@ async function doctorCommand(options2 = {}) {
|
|
|
63269
63354
|
}
|
|
63270
63355
|
}
|
|
63271
63356
|
|
|
63357
|
+
// src/commands/init/init-command.ts
|
|
63358
|
+
import { join as join102 } from "node:path";
|
|
63359
|
+
|
|
63272
63360
|
// src/domains/sync/config-version-checker.ts
|
|
63273
63361
|
init_auth_client();
|
|
63274
63362
|
import { mkdir as mkdir22, readFile as readFile38, unlink as unlink12, writeFile as writeFile29 } from "node:fs/promises";
|
|
@@ -64049,7 +64137,96 @@ async function maybeShowConfigUpdateNotification(claudeDir, global3) {
|
|
|
64049
64137
|
init_package_installer();
|
|
64050
64138
|
init_logger();
|
|
64051
64139
|
|
|
64140
|
+
// src/domains/ui/prompts/agent-selection-prompts.ts
|
|
64141
|
+
init_provider_registry();
|
|
64142
|
+
|
|
64143
|
+
// src/services/package-installer/agent-cli-detector.ts
|
|
64144
|
+
init_process_executor();
|
|
64145
|
+
var DETECT_TIMEOUT_MS = 5000;
|
|
64146
|
+
var BINARY_CANDIDATES = {
|
|
64147
|
+
"claude-code": process.platform === "win32" ? ["claude.exe", "claude.cmd", "claude"] : ["claude"],
|
|
64148
|
+
codex: process.platform === "win32" ? ["codex.exe", "codex.cmd", "codex"] : ["codex"]
|
|
64149
|
+
};
|
|
64150
|
+
async function probeBinary(candidates) {
|
|
64151
|
+
for (const bin of candidates) {
|
|
64152
|
+
const needsShell = process.platform === "win32" && /\.(cmd|bat)$/i.test(bin);
|
|
64153
|
+
try {
|
|
64154
|
+
const { stdout: stdout2 } = await execFileAsync5(bin, ["--version"], {
|
|
64155
|
+
timeout: DETECT_TIMEOUT_MS,
|
|
64156
|
+
encoding: "utf8",
|
|
64157
|
+
shell: needsShell
|
|
64158
|
+
});
|
|
64159
|
+
return typeof stdout2 === "string" ? stdout2 : String(stdout2);
|
|
64160
|
+
} catch {}
|
|
64161
|
+
}
|
|
64162
|
+
return null;
|
|
64163
|
+
}
|
|
64164
|
+
function extractVersion(stdout2) {
|
|
64165
|
+
const match2 = stdout2.match(/(\d+\.\d+\.\d+(?:[-+][\w.]+)?)/);
|
|
64166
|
+
return match2 ? match2[1] : undefined;
|
|
64167
|
+
}
|
|
64168
|
+
async function detectAgentInstallations(providers2) {
|
|
64169
|
+
const probes = providers2.filter((p) => (p in BINARY_CANDIDATES)).map(async (provider) => {
|
|
64170
|
+
const candidates = BINARY_CANDIDATES[provider];
|
|
64171
|
+
if (!candidates) {
|
|
64172
|
+
return [provider, { installed: false }];
|
|
64173
|
+
}
|
|
64174
|
+
const stdout2 = await probeBinary(candidates);
|
|
64175
|
+
const detection = stdout2 ? { installed: true, version: extractVersion(stdout2) } : { installed: false };
|
|
64176
|
+
return [provider, detection];
|
|
64177
|
+
});
|
|
64178
|
+
const entries = await Promise.all(probes);
|
|
64179
|
+
const result = {};
|
|
64180
|
+
for (const [provider, detection] of entries) {
|
|
64181
|
+
result[provider] = detection;
|
|
64182
|
+
}
|
|
64183
|
+
return result;
|
|
64184
|
+
}
|
|
64185
|
+
|
|
64186
|
+
// src/domains/ui/prompts/agent-selection-prompts.ts
|
|
64187
|
+
function buildDetectionNote(supported, detections) {
|
|
64188
|
+
const lines = supported.map((provider) => {
|
|
64189
|
+
const detection = detections[provider];
|
|
64190
|
+
const label = providers[provider]?.displayName ?? provider;
|
|
64191
|
+
if (detection?.installed) {
|
|
64192
|
+
const version3 = detection.version ? ` v${detection.version}` : "";
|
|
64193
|
+
return ` ✓ ${label}${version3} detected on PATH`;
|
|
64194
|
+
}
|
|
64195
|
+
return ` ✗ ${label} not detected on PATH`;
|
|
64196
|
+
});
|
|
64197
|
+
lines.push("");
|
|
64198
|
+
lines.push("Init writes config files regardless — detection only informs defaults.");
|
|
64199
|
+
return lines.join(`
|
|
64200
|
+
`);
|
|
64201
|
+
}
|
|
64202
|
+
function computeInitialSelection(supported, detections) {
|
|
64203
|
+
if (detections["claude-code"]?.installed)
|
|
64204
|
+
return ["claude-code"];
|
|
64205
|
+
const firstInstalled = supported.find((p) => detections[p]?.installed);
|
|
64206
|
+
return firstInstalled ? [firstInstalled] : [];
|
|
64207
|
+
}
|
|
64208
|
+
async function promptAgentSelection(supported) {
|
|
64209
|
+
const detections = await detectAgentInstallations(supported);
|
|
64210
|
+
note(buildDetectionNote(supported, detections), "Detected agent CLIs");
|
|
64211
|
+
const options2 = supported.map((provider) => {
|
|
64212
|
+
const detection = detections[provider];
|
|
64213
|
+
const label = providers[provider]?.displayName ?? provider;
|
|
64214
|
+
const hint = detection?.installed ? detection.version ? `installed v${detection.version}` : "installed" : "not detected — config will still be written";
|
|
64215
|
+
return { value: provider, label, hint };
|
|
64216
|
+
});
|
|
64217
|
+
const initialValues = computeInitialSelection(supported, detections);
|
|
64218
|
+
const selected = await ae({
|
|
64219
|
+
message: "Select agent(s) to initialize",
|
|
64220
|
+
options: options2,
|
|
64221
|
+
required: true,
|
|
64222
|
+
initialValues
|
|
64223
|
+
});
|
|
64224
|
+
if (lD(selected))
|
|
64225
|
+
return null;
|
|
64226
|
+
return selected;
|
|
64227
|
+
}
|
|
64052
64228
|
// src/domains/ui/prompts/kit-prompts.ts
|
|
64229
|
+
init_logger();
|
|
64053
64230
|
init_types2();
|
|
64054
64231
|
async function selectKit(defaultKit, accessibleKits) {
|
|
64055
64232
|
const kits = accessibleKits ?? Object.keys(AVAILABLE_KITS);
|
|
@@ -64067,6 +64244,39 @@ async function selectKit(defaultKit, accessibleKits) {
|
|
|
64067
64244
|
}
|
|
64068
64245
|
return kit;
|
|
64069
64246
|
}
|
|
64247
|
+
async function selectKits(accessibleKits, defaults2) {
|
|
64248
|
+
const kits = accessibleKits ?? Object.keys(AVAILABLE_KITS);
|
|
64249
|
+
const options2 = kits.map((key) => {
|
|
64250
|
+
const isBase = key === BASE_KIT;
|
|
64251
|
+
const cfg = AVAILABLE_KITS[key];
|
|
64252
|
+
return {
|
|
64253
|
+
value: key,
|
|
64254
|
+
label: isBase ? `${cfg.name} (base, required)` : cfg.name,
|
|
64255
|
+
hint: cfg.description
|
|
64256
|
+
};
|
|
64257
|
+
});
|
|
64258
|
+
const initialValues = defaults2 && defaults2.length > 0 ? Array.from(new Set([BASE_KIT, ...defaults2])).filter((k2) => kits.includes(k2)) : kits;
|
|
64259
|
+
const selected = await ae({
|
|
64260
|
+
message: "Select kit(s) to install:",
|
|
64261
|
+
options: options2,
|
|
64262
|
+
initialValues,
|
|
64263
|
+
required: true
|
|
64264
|
+
});
|
|
64265
|
+
if (lD(selected)) {
|
|
64266
|
+
throw new Error("Kit selection cancelled");
|
|
64267
|
+
}
|
|
64268
|
+
const result = selected;
|
|
64269
|
+
if (!result.includes(BASE_KIT) && kits.includes(BASE_KIT)) {
|
|
64270
|
+
logger.info(`"${AVAILABLE_KITS[BASE_KIT].name}" is the base kit and was added back automatically.`);
|
|
64271
|
+
result.unshift(BASE_KIT);
|
|
64272
|
+
}
|
|
64273
|
+
const idx = result.indexOf(BASE_KIT);
|
|
64274
|
+
if (idx > 0) {
|
|
64275
|
+
result.splice(idx, 1);
|
|
64276
|
+
result.unshift(BASE_KIT);
|
|
64277
|
+
}
|
|
64278
|
+
return result;
|
|
64279
|
+
}
|
|
64070
64280
|
async function getDirectory(defaultDir = ".") {
|
|
64071
64281
|
const dir = await te({
|
|
64072
64282
|
message: "Enter target directory:",
|
|
@@ -64730,6 +64940,9 @@ class PromptsManager {
|
|
|
64730
64940
|
async selectKit(defaultKit, accessibleKits) {
|
|
64731
64941
|
return selectKit(defaultKit, accessibleKits);
|
|
64732
64942
|
}
|
|
64943
|
+
async selectKits(accessibleKits, defaults2) {
|
|
64944
|
+
return selectKits(accessibleKits, defaults2);
|
|
64945
|
+
}
|
|
64733
64946
|
async selectVersion(versions, defaultVersion) {
|
|
64734
64947
|
return selectVersion(versions, defaultVersion);
|
|
64735
64948
|
}
|
|
@@ -64805,6 +65018,9 @@ class PromptsManager {
|
|
|
64805
65018
|
async promptSkillsInstallation() {
|
|
64806
65019
|
return promptSkillsInstallation();
|
|
64807
65020
|
}
|
|
65021
|
+
async promptAgentSelection(supported) {
|
|
65022
|
+
return promptAgentSelection(supported);
|
|
65023
|
+
}
|
|
64808
65024
|
showPackageInstallationResults(results) {
|
|
64809
65025
|
const successfulInstalls = [];
|
|
64810
65026
|
const failedInstalls = [];
|
|
@@ -64868,6 +65084,8 @@ class PromptsManager {
|
|
|
64868
65084
|
|
|
64869
65085
|
// src/commands/init/init-command.ts
|
|
64870
65086
|
init_logger();
|
|
65087
|
+
init_path_resolver();
|
|
65088
|
+
init_types2();
|
|
64871
65089
|
|
|
64872
65090
|
// src/commands/init/context-factory.ts
|
|
64873
65091
|
function createInitContext(rawOptions, prompts) {
|
|
@@ -69545,8 +69763,28 @@ async function handleDownload(ctx) {
|
|
|
69545
69763
|
// src/commands/init/phases/options-resolver.ts
|
|
69546
69764
|
init_logger();
|
|
69547
69765
|
init_types2();
|
|
69766
|
+
function parseKitFlag(raw) {
|
|
69767
|
+
const tokens = raw.split(",").map((s3) => s3.trim()).filter((s3) => s3.length > 0);
|
|
69768
|
+
if (tokens.length === 0)
|
|
69769
|
+
return null;
|
|
69770
|
+
if (tokens.length === 1 && tokens[0] === "all") {
|
|
69771
|
+
return Object.keys(AVAILABLE_KITS);
|
|
69772
|
+
}
|
|
69773
|
+
const seen = new Set;
|
|
69774
|
+
const out = [];
|
|
69775
|
+
for (const tok of tokens) {
|
|
69776
|
+
if (!isValidKitType(tok))
|
|
69777
|
+
return null;
|
|
69778
|
+
if (!seen.has(tok)) {
|
|
69779
|
+
seen.add(tok);
|
|
69780
|
+
out.push(tok);
|
|
69781
|
+
}
|
|
69782
|
+
}
|
|
69783
|
+
return out;
|
|
69784
|
+
}
|
|
69548
69785
|
async function resolveOptions(ctx) {
|
|
69549
69786
|
const explicitDir = ctx.rawOptions.dir !== undefined;
|
|
69787
|
+
const explicitAgents = Array.isArray(ctx.rawOptions.agents) && ctx.rawOptions.agents.length > 0;
|
|
69550
69788
|
const parsed = UpdateCommandOptionsSchema.parse(ctx.rawOptions);
|
|
69551
69789
|
const validOptions = {
|
|
69552
69790
|
kit: parsed.kit,
|
|
@@ -69589,8 +69827,6 @@ async function resolveOptions(ctx) {
|
|
|
69589
69827
|
` + "For other agents, run init without --sync to perform a fresh install.");
|
|
69590
69828
|
}
|
|
69591
69829
|
validOptions.agents = Array.from(new Set(validOptions.agents));
|
|
69592
|
-
} else {
|
|
69593
|
-
validOptions.agents = ["claude-code"];
|
|
69594
69830
|
}
|
|
69595
69831
|
ConfigManager.setGlobalFlag(validOptions.global);
|
|
69596
69832
|
if (validOptions.global) {
|
|
@@ -69635,10 +69871,52 @@ Example: takumi init --use-git --release v2.1.0`);
|
|
|
69635
69871
|
Choose one approach.`);
|
|
69636
69872
|
}
|
|
69637
69873
|
const isNonInteractive2 = validOptions.yes || !process.stdin.isTTY || process.env.CI === "true" || process.env.NON_INTERACTIVE === "true";
|
|
69874
|
+
if (validOptions.kit) {
|
|
69875
|
+
const parsed2 = parseKitFlag(validOptions.kit);
|
|
69876
|
+
if (!parsed2 || parsed2.length === 0) {
|
|
69877
|
+
throw new Error(`Invalid --kit value: "${validOptions.kit}".
|
|
69878
|
+
Valid kits: ${Object.keys(AVAILABLE_KITS).join(", ")}`);
|
|
69879
|
+
}
|
|
69880
|
+
if (!parsed2.includes(BASE_KIT)) {
|
|
69881
|
+
if (isNonInteractive2) {
|
|
69882
|
+
throw new Error(`The "${BASE_KIT}" kit is required when installing additional kits.
|
|
69883
|
+
Re-run with explicit base kit, e.g. --kit ${BASE_KIT} --kit ${parsed2.join(" --kit ")}`);
|
|
69884
|
+
}
|
|
69885
|
+
logger.info(`"${BASE_KIT}" is the required base kit — adding it automatically.`);
|
|
69886
|
+
parsed2.unshift(BASE_KIT);
|
|
69887
|
+
} else {
|
|
69888
|
+
const idx = parsed2.indexOf(BASE_KIT);
|
|
69889
|
+
if (idx > 0) {
|
|
69890
|
+
parsed2.splice(idx, 1);
|
|
69891
|
+
parsed2.unshift(BASE_KIT);
|
|
69892
|
+
}
|
|
69893
|
+
}
|
|
69894
|
+
validOptions.selectedKits = parsed2;
|
|
69895
|
+
}
|
|
69638
69896
|
if (validOptions.yes) {
|
|
69639
69897
|
logger.info("Running in non-interactive mode (--yes flag)");
|
|
69640
69898
|
}
|
|
69641
69899
|
const initialInstallSkills = validOptions.installSkills ? true : undefined;
|
|
69900
|
+
if (!explicitAgents) {
|
|
69901
|
+
if (isNonInteractive2) {
|
|
69902
|
+
validOptions.agents = ["claude-code"];
|
|
69903
|
+
} else {
|
|
69904
|
+
const supported = listSupportedProviders();
|
|
69905
|
+
const selected = await ctx.prompts.promptAgentSelection(supported);
|
|
69906
|
+
if (selected === null) {
|
|
69907
|
+
logger.warning("Agent selection cancelled");
|
|
69908
|
+
return {
|
|
69909
|
+
...ctx,
|
|
69910
|
+
options: validOptions,
|
|
69911
|
+
explicitDir,
|
|
69912
|
+
isNonInteractive: isNonInteractive2,
|
|
69913
|
+
installSkills: initialInstallSkills,
|
|
69914
|
+
cancelled: true
|
|
69915
|
+
};
|
|
69916
|
+
}
|
|
69917
|
+
validOptions.agents = selected;
|
|
69918
|
+
}
|
|
69919
|
+
}
|
|
69642
69920
|
return {
|
|
69643
69921
|
...ctx,
|
|
69644
69922
|
options: validOptions,
|
|
@@ -70052,48 +70330,58 @@ async function handleSelection(ctx) {
|
|
|
70052
70330
|
return { ...ctx, cancelled: true };
|
|
70053
70331
|
}
|
|
70054
70332
|
}
|
|
70055
|
-
let
|
|
70056
|
-
|
|
70057
|
-
if (kitOption) {
|
|
70333
|
+
let selectedKits = ctx.options.selectedKits;
|
|
70334
|
+
if (!selectedKits || selectedKits.length === 0) {
|
|
70058
70335
|
const allKitTypes = Object.keys(AVAILABLE_KITS);
|
|
70059
|
-
|
|
70060
|
-
|
|
70061
|
-
if (
|
|
70062
|
-
|
|
70063
|
-
|
|
70064
|
-
}
|
|
70065
|
-
kitType = kitsToInstall[0];
|
|
70066
|
-
logger.info(`Using kit: ${AVAILABLE_KITS[kitType].name}`);
|
|
70067
|
-
} else {
|
|
70068
|
-
if (!isValidKitType(kitOption)) {
|
|
70336
|
+
const kitOption = ctx.options.kit || config.defaults?.kit;
|
|
70337
|
+
if (kitOption) {
|
|
70338
|
+
if (kitOption === "all") {
|
|
70339
|
+
selectedKits = accessibleKits ?? allKitTypes;
|
|
70340
|
+
} else if (!isValidKitType(kitOption)) {
|
|
70069
70341
|
logger.error(`Invalid kit: ${kitOption}`);
|
|
70070
70342
|
logger.info(`Valid kits: ${allKitTypes.join(", ")}`);
|
|
70071
70343
|
return { ...ctx, cancelled: true };
|
|
70344
|
+
} else {
|
|
70345
|
+
selectedKits = [kitOption];
|
|
70072
70346
|
}
|
|
70073
|
-
|
|
70074
|
-
|
|
70075
|
-
|
|
70076
|
-
|
|
70077
|
-
|
|
70347
|
+
}
|
|
70348
|
+
if (!selectedKits || selectedKits.length === 0) {
|
|
70349
|
+
if (ctx.isNonInteractive) {
|
|
70350
|
+
if (!accessibleKits || accessibleKits.length === 0) {
|
|
70351
|
+
throw new Error("Kit must be specified via --kit flag in non-interactive mode (no accessible kits detected)");
|
|
70352
|
+
}
|
|
70353
|
+
selectedKits = [accessibleKits[0]];
|
|
70354
|
+
logger.info(`Auto-selected: ${AVAILABLE_KITS[selectedKits[0]].name}`);
|
|
70355
|
+
} else if (accessibleKits?.length === 1) {
|
|
70356
|
+
selectedKits = [accessibleKits[0]];
|
|
70357
|
+
logger.info(`Using ${AVAILABLE_KITS[selectedKits[0]].name} (only accessible kit)`);
|
|
70358
|
+
} else {
|
|
70359
|
+
selectedKits = await ctx.prompts.selectKits(accessibleKits);
|
|
70078
70360
|
}
|
|
70079
70361
|
}
|
|
70080
70362
|
}
|
|
70081
|
-
if (
|
|
70082
|
-
|
|
70083
|
-
|
|
70084
|
-
|
|
70085
|
-
|
|
70086
|
-
|
|
70087
|
-
|
|
70088
|
-
|
|
70089
|
-
|
|
70090
|
-
|
|
70091
|
-
|
|
70092
|
-
|
|
70363
|
+
if (accessibleKits) {
|
|
70364
|
+
const inaccessible = selectedKits.filter((k3) => !accessibleKits.includes(k3));
|
|
70365
|
+
if (inaccessible.length > 0) {
|
|
70366
|
+
logger.error(`No access to: ${inaccessible.map((k3) => AVAILABLE_KITS[k3].name).join(", ")}`);
|
|
70367
|
+
logger.info("Request access from your team lead or check your GitHub invitation");
|
|
70368
|
+
return { ...ctx, cancelled: true };
|
|
70369
|
+
}
|
|
70370
|
+
}
|
|
70371
|
+
if (selectedKits.includes(BASE_KIT)) {
|
|
70372
|
+
const idx = selectedKits.indexOf(BASE_KIT);
|
|
70373
|
+
if (idx > 0) {
|
|
70374
|
+
selectedKits.splice(idx, 1);
|
|
70375
|
+
selectedKits.unshift(BASE_KIT);
|
|
70093
70376
|
}
|
|
70094
70377
|
}
|
|
70378
|
+
const kitType = selectedKits[0];
|
|
70095
70379
|
const kit = AVAILABLE_KITS[kitType];
|
|
70096
|
-
|
|
70380
|
+
if (selectedKits.length > 1) {
|
|
70381
|
+
logger.info(`Selected kits: ${selectedKits.map((k3) => AVAILABLE_KITS[k3].name).join(", ")} (installed in order)`);
|
|
70382
|
+
} else {
|
|
70383
|
+
logger.info(`Selected kit: ${kit.name}`);
|
|
70384
|
+
}
|
|
70097
70385
|
let targetDir;
|
|
70098
70386
|
if (ctx.explicitDir) {
|
|
70099
70387
|
targetDir = ctx.options.dir;
|
|
@@ -70302,12 +70590,30 @@ async function handleSelection(ctx) {
|
|
|
70302
70590
|
...ctx,
|
|
70303
70591
|
kit,
|
|
70304
70592
|
kitType,
|
|
70593
|
+
selectedKits,
|
|
70305
70594
|
resolvedDir,
|
|
70306
70595
|
release,
|
|
70307
70596
|
selectedVersion,
|
|
70308
70597
|
accessibleKits
|
|
70309
70598
|
};
|
|
70310
70599
|
}
|
|
70600
|
+
async function resolveReleaseForKit(ctx, kitType) {
|
|
70601
|
+
const isOfflineMode = !!(ctx.options.kitPath || ctx.options.archive);
|
|
70602
|
+
if (isOfflineMode)
|
|
70603
|
+
return;
|
|
70604
|
+
const kit = AVAILABLE_KITS[kitType];
|
|
70605
|
+
if (ctx.options.useGit) {
|
|
70606
|
+
throw new Error(`--use-git is not supported for multi-kit installs (secondary kit: ${kitType}). Run kits individually.`);
|
|
70607
|
+
}
|
|
70608
|
+
if (ctx.options.useGh) {
|
|
70609
|
+
const github = new GitHubClient;
|
|
70610
|
+
const release = await github.getLatestRelease(kit, ctx.options.beta);
|
|
70611
|
+
return release;
|
|
70612
|
+
}
|
|
70613
|
+
const worker = new WorkerSource(getServerUrl(), kitType);
|
|
70614
|
+
const entry = await worker.fetchLatest(ctx.options.beta);
|
|
70615
|
+
return releaseEntryToGitHubRelease(entry, kit);
|
|
70616
|
+
}
|
|
70311
70617
|
function resolveGlobalTargetDir(targetAgents) {
|
|
70312
70618
|
const primary = targetAgents[0];
|
|
70313
70619
|
if (primary) {
|
|
@@ -70348,7 +70654,7 @@ async function handleSync(ctx) {
|
|
|
70348
70654
|
Run 'takumi init' to update.`, "Legacy Installation");
|
|
70349
70655
|
return { ...ctx, cancelled: true };
|
|
70350
70656
|
}
|
|
70351
|
-
let kitType = ctx.options.
|
|
70657
|
+
let kitType = ctx.options.selectedKits?.[0];
|
|
70352
70658
|
if (!kitType) {
|
|
70353
70659
|
const engineerMeta = await readKitManifest(claudeDir, "engineer");
|
|
70354
70660
|
if (engineerMeta) {
|
|
@@ -71181,23 +71487,91 @@ async function executeInit(options2, prompts) {
|
|
|
71181
71487
|
ctx = await handleSelection(ctx);
|
|
71182
71488
|
if (ctx.cancelled)
|
|
71183
71489
|
return;
|
|
71184
|
-
ctx
|
|
71185
|
-
|
|
71490
|
+
if (ctx.resolvedDir && !isSyncMode) {
|
|
71491
|
+
try {
|
|
71492
|
+
const prefix = PathResolver.getPathPrefix(ctx.options.global);
|
|
71493
|
+
const claudeDir = prefix ? join102(ctx.resolvedDir, prefix) : ctx.resolvedDir;
|
|
71494
|
+
const pending = await ManifestWriter.findPendingKits(claudeDir);
|
|
71495
|
+
if (pending.length > 0) {
|
|
71496
|
+
logger.warning(`Previous install was interrupted for kit(s): ${pending.join(", ")}. Re-running install will overwrite the pending entry.`);
|
|
71497
|
+
}
|
|
71498
|
+
} catch (error) {
|
|
71499
|
+
logger.debug(`Pending-kit check skipped: ${error}`);
|
|
71500
|
+
}
|
|
71501
|
+
}
|
|
71502
|
+
const selectedKits = ctx.selectedKits && ctx.selectedKits.length > 0 ? ctx.selectedKits : ctx.kitType ? [ctx.kitType] : [];
|
|
71503
|
+
if (selectedKits.length === 0) {
|
|
71504
|
+
logger.error("No kits resolved for installation");
|
|
71186
71505
|
return;
|
|
71187
|
-
if (!isSyncMode) {
|
|
71188
|
-
ctx = await handleTransforms(ctx);
|
|
71189
|
-
if (ctx.cancelled)
|
|
71190
|
-
return;
|
|
71191
71506
|
}
|
|
71192
|
-
|
|
71193
|
-
|
|
71194
|
-
|
|
71507
|
+
const aggregatedResults = [];
|
|
71508
|
+
let lastCtx = ctx;
|
|
71509
|
+
for (let i = 0;i < selectedKits.length; i++) {
|
|
71510
|
+
const currentKit = selectedKits[i];
|
|
71511
|
+
if (i > 0) {
|
|
71512
|
+
logger.info(`Installing kit ${i + 1}/${selectedKits.length}: ${AVAILABLE_KITS[currentKit].name}`);
|
|
71513
|
+
if (lastCtx.options.release) {
|
|
71514
|
+
logger.info(`Secondary kit "${currentKit}" uses latest channel — --release applies only to the primary kit.`);
|
|
71515
|
+
}
|
|
71516
|
+
let nextRelease;
|
|
71517
|
+
try {
|
|
71518
|
+
nextRelease = await resolveReleaseForKit(lastCtx, currentKit);
|
|
71519
|
+
} catch (error) {
|
|
71520
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
71521
|
+
logger.error(`Failed to resolve release for ${currentKit}: ${message}`);
|
|
71522
|
+
aggregatedResults.push({
|
|
71523
|
+
provider: targetAgents[0] ?? "claude-code",
|
|
71524
|
+
success: false,
|
|
71525
|
+
cancelled: false,
|
|
71526
|
+
installedFiles: [],
|
|
71527
|
+
error: `Release fetch failed for kit "${currentKit}": ${message}`
|
|
71528
|
+
});
|
|
71529
|
+
continue;
|
|
71530
|
+
}
|
|
71531
|
+
lastCtx = {
|
|
71532
|
+
...lastCtx,
|
|
71533
|
+
kit: AVAILABLE_KITS[currentKit],
|
|
71534
|
+
kitType: currentKit,
|
|
71535
|
+
release: nextRelease,
|
|
71536
|
+
selectedVersion: nextRelease?.tag_name,
|
|
71537
|
+
tempDir: undefined,
|
|
71538
|
+
extractDir: undefined,
|
|
71539
|
+
archivePath: undefined
|
|
71540
|
+
};
|
|
71541
|
+
} else if (selectedKits.length > 1) {
|
|
71542
|
+
logger.info(`Installing kit ${i + 1}/${selectedKits.length}: ${AVAILABLE_KITS[currentKit].name}`);
|
|
71543
|
+
}
|
|
71544
|
+
if (lastCtx.resolvedDir && lastCtx.release && !isSyncMode) {
|
|
71545
|
+
try {
|
|
71546
|
+
const prefix = PathResolver.getPathPrefix(lastCtx.options.global);
|
|
71547
|
+
const claudeDir = prefix ? join102(lastCtx.resolvedDir, prefix) : lastCtx.resolvedDir;
|
|
71548
|
+
const scope = lastCtx.options.global ? "global" : "local";
|
|
71549
|
+
await ManifestWriter.writeKitPending(claudeDir, currentKit, lastCtx.release.tag_name, scope);
|
|
71550
|
+
} catch (error) {
|
|
71551
|
+
logger.debug(`writeKitPending skipped: ${error}`);
|
|
71552
|
+
}
|
|
71553
|
+
}
|
|
71554
|
+
lastCtx = await handleDownload(lastCtx);
|
|
71555
|
+
if (lastCtx.cancelled)
|
|
71556
|
+
return;
|
|
71557
|
+
if (!isSyncMode) {
|
|
71558
|
+
lastCtx = await handleTransforms(lastCtx);
|
|
71559
|
+
if (lastCtx.cancelled)
|
|
71560
|
+
return;
|
|
71561
|
+
}
|
|
71562
|
+
if (isSyncMode) {
|
|
71563
|
+
lastCtx = await executeSyncMerge(lastCtx);
|
|
71564
|
+
if (lastCtx.cancelled)
|
|
71565
|
+
return;
|
|
71566
|
+
}
|
|
71567
|
+
const kitResults = await dispatchInstallers(lastCtx, targetAgents);
|
|
71568
|
+
aggregatedResults.push(...kitResults);
|
|
71569
|
+
if (kitResults.some((r2) => r2.cancelled))
|
|
71195
71570
|
return;
|
|
71196
71571
|
}
|
|
71197
|
-
|
|
71572
|
+
ctx = lastCtx;
|
|
71573
|
+
const results = aggregatedResults;
|
|
71198
71574
|
ctx.installerResults = results;
|
|
71199
|
-
if (results.some((r2) => r2.cancelled))
|
|
71200
|
-
return;
|
|
71201
71575
|
if (targetAgents.length > 1) {
|
|
71202
71576
|
displayMultiInstallerSummary(results);
|
|
71203
71577
|
}
|
|
@@ -71258,7 +71632,7 @@ async function initCommand(options2) {
|
|
|
71258
71632
|
import { existsSync as existsSync47 } from "node:fs";
|
|
71259
71633
|
import { readFile as readFile45, rm as rm13, unlink as unlink15 } from "node:fs/promises";
|
|
71260
71634
|
import { homedir as homedir25 } from "node:os";
|
|
71261
|
-
import { basename as basename12, join as
|
|
71635
|
+
import { basename as basename12, join as join103, resolve as resolve26 } from "node:path";
|
|
71262
71636
|
init_dist2();
|
|
71263
71637
|
var import_picocolors27 = __toESM(require_picocolors(), 1);
|
|
71264
71638
|
init_logger();
|
|
@@ -71740,7 +72114,7 @@ async function executeDeleteAction(action, options2) {
|
|
|
71740
72114
|
async function processMetadataDeletions(skillSourcePath, installGlobally) {
|
|
71741
72115
|
if (!skillSourcePath)
|
|
71742
72116
|
return;
|
|
71743
|
-
const sourceMetadataPath =
|
|
72117
|
+
const sourceMetadataPath = join103(resolve26(skillSourcePath, ".."), "metadata.json");
|
|
71744
72118
|
if (!existsSync47(sourceMetadataPath))
|
|
71745
72119
|
return;
|
|
71746
72120
|
let sourceMetadata;
|
|
@@ -71753,11 +72127,11 @@ async function processMetadataDeletions(skillSourcePath, installGlobally) {
|
|
|
71753
72127
|
}
|
|
71754
72128
|
if (!sourceMetadata.deletions || sourceMetadata.deletions.length === 0)
|
|
71755
72129
|
return;
|
|
71756
|
-
const claudeDir = installGlobally ?
|
|
72130
|
+
const claudeDir = installGlobally ? join103(homedir25(), ".claude") : join103(process.cwd(), ".claude");
|
|
71757
72131
|
if (!existsSync47(claudeDir))
|
|
71758
72132
|
return;
|
|
71759
72133
|
try {
|
|
71760
|
-
const result = await handleDeletions(sourceMetadata, claudeDir);
|
|
72134
|
+
const result = await handleDeletions(sourceMetadata, claudeDir, undefined);
|
|
71761
72135
|
if (result.deletedPaths.length > 0) {
|
|
71762
72136
|
logger.verbose(`[migrate] Cleaned up ${result.deletedPaths.length} deprecated path(s): ${result.deletedPaths.join(", ")}`);
|
|
71763
72137
|
}
|
|
@@ -71901,8 +72275,8 @@ async function migrateCommand(options2) {
|
|
|
71901
72275
|
selectedProviders = Array.from(new Set(selectedProviders));
|
|
71902
72276
|
let installGlobally = options2.global ?? false;
|
|
71903
72277
|
if (options2.global === undefined && !options2.yes) {
|
|
71904
|
-
const projectTarget =
|
|
71905
|
-
const globalTarget =
|
|
72278
|
+
const projectTarget = join103(process.cwd(), ".claude");
|
|
72279
|
+
const globalTarget = join103(homedir25(), ".claude");
|
|
71906
72280
|
const scopeChoice = await ie({
|
|
71907
72281
|
message: "Installation scope",
|
|
71908
72282
|
options: [
|
|
@@ -71954,7 +72328,7 @@ async function migrateCommand(options2) {
|
|
|
71954
72328
|
}
|
|
71955
72329
|
const providerNames = selectedProviders.map((prov) => import_picocolors27.default.cyan(providers[prov].displayName)).join(", ");
|
|
71956
72330
|
f2.message(` Providers: ${providerNames}`);
|
|
71957
|
-
const targetDir = installGlobally ?
|
|
72331
|
+
const targetDir = installGlobally ? join103(homedir25(), ".claude") : join103(process.cwd(), ".claude");
|
|
71958
72332
|
f2.message(` Scope: ${installGlobally ? "Global" : "Project"} ${import_picocolors27.default.dim(`-> ${targetDir}`)}`);
|
|
71959
72333
|
const cmdProviders = getProvidersSupporting("commands");
|
|
71960
72334
|
const unsupportedCmd = selectedProviders.filter((pv) => !cmdProviders.includes(pv));
|
|
@@ -72464,7 +72838,7 @@ async function handleDirectorySetup(ctx) {
|
|
|
72464
72838
|
};
|
|
72465
72839
|
}
|
|
72466
72840
|
// src/commands/new/phases/project-creation.ts
|
|
72467
|
-
import { join as
|
|
72841
|
+
import { join as join104 } from "node:path";
|
|
72468
72842
|
init_github_client();
|
|
72469
72843
|
init_logger();
|
|
72470
72844
|
init_output_manager();
|
|
@@ -72618,7 +72992,7 @@ async function projectCreation(kit, resolvedDir, validOptions, isNonInteractive2
|
|
|
72618
72992
|
output.section("Installing");
|
|
72619
72993
|
logger.verbose("Installation target", { directory: resolvedDir });
|
|
72620
72994
|
const merger = new FileMerger;
|
|
72621
|
-
const claudeDir =
|
|
72995
|
+
const claudeDir = join104(resolvedDir, ".claude");
|
|
72622
72996
|
merger.setMultiKitContext(claudeDir, kit);
|
|
72623
72997
|
if (validOptions.exclude && validOptions.exclude.length > 0) {
|
|
72624
72998
|
merger.addIgnorePatterns(validOptions.exclude);
|
|
@@ -72671,10 +73045,10 @@ async function handleProjectCreation(ctx) {
|
|
|
72671
73045
|
};
|
|
72672
73046
|
}
|
|
72673
73047
|
// src/commands/new/phases/post-setup.ts
|
|
72674
|
-
import { join as
|
|
73048
|
+
import { join as join106 } from "node:path";
|
|
72675
73049
|
|
|
72676
73050
|
// src/domains/installation/setup-wizard.ts
|
|
72677
|
-
import { join as
|
|
73051
|
+
import { join as join105 } from "node:path";
|
|
72678
73052
|
init_logger();
|
|
72679
73053
|
init_dist2();
|
|
72680
73054
|
var import_fs_extra36 = __toESM(require_lib(), 1);
|
|
@@ -72754,7 +73128,7 @@ async function parseEnvFile(path9) {
|
|
|
72754
73128
|
}
|
|
72755
73129
|
}
|
|
72756
73130
|
async function checkGlobalConfig() {
|
|
72757
|
-
const globalEnvPath =
|
|
73131
|
+
const globalEnvPath = join105(getClaudeDir(), ".env");
|
|
72758
73132
|
if (!await import_fs_extra36.pathExists(globalEnvPath))
|
|
72759
73133
|
return false;
|
|
72760
73134
|
const env2 = await parseEnvFile(globalEnvPath);
|
|
@@ -72770,7 +73144,7 @@ async function runSetupWizard(options2) {
|
|
|
72770
73144
|
let globalEnv = {};
|
|
72771
73145
|
const hasGlobalConfig = !isGlobal && await checkGlobalConfig();
|
|
72772
73146
|
if (!isGlobal) {
|
|
72773
|
-
const globalEnvPath =
|
|
73147
|
+
const globalEnvPath = join105(getClaudeDir(), ".env");
|
|
72774
73148
|
if (await import_fs_extra36.pathExists(globalEnvPath)) {
|
|
72775
73149
|
globalEnv = await parseEnvFile(globalEnvPath);
|
|
72776
73150
|
}
|
|
@@ -72833,7 +73207,7 @@ async function runSetupWizard(options2) {
|
|
|
72833
73207
|
}
|
|
72834
73208
|
}
|
|
72835
73209
|
await generateEnvFile(targetDir, values);
|
|
72836
|
-
f2.success(`Configuration saved to ${
|
|
73210
|
+
f2.success(`Configuration saved to ${join105(targetDir, ".env")}`);
|
|
72837
73211
|
return true;
|
|
72838
73212
|
}
|
|
72839
73213
|
async function promptForAdditionalGeminiKeys(primaryKey) {
|
|
@@ -72936,9 +73310,9 @@ async function postSetup(resolvedDir, validOptions, isNonInteractive2, prompts)
|
|
|
72936
73310
|
withSudo: validOptions.withSudo
|
|
72937
73311
|
});
|
|
72938
73312
|
}
|
|
72939
|
-
const claudeDir =
|
|
73313
|
+
const claudeDir = join106(resolvedDir, ".claude");
|
|
72940
73314
|
await promptSetupWizardIfNeeded({
|
|
72941
|
-
envPath:
|
|
73315
|
+
envPath: join106(claudeDir, ".env"),
|
|
72942
73316
|
claudeDir,
|
|
72943
73317
|
isGlobal: false,
|
|
72944
73318
|
isNonInteractive: isNonInteractive2,
|
|
@@ -73015,11 +73389,11 @@ Example: tkm new --use-git --release v2.1.0`);
|
|
|
73015
73389
|
// src/commands/plan/plan-command.ts
|
|
73016
73390
|
init_output_manager();
|
|
73017
73391
|
import { existsSync as existsSync52, statSync as statSync5 } from "node:fs";
|
|
73018
|
-
import { dirname as dirname33, join as
|
|
73392
|
+
import { dirname as dirname33, join as join110, parse as parse2, resolve as resolve31 } from "node:path";
|
|
73019
73393
|
|
|
73020
73394
|
// src/commands/plan/plan-read-handlers.ts
|
|
73021
73395
|
import { existsSync as existsSync51, statSync as statSync4 } from "node:fs";
|
|
73022
|
-
import { basename as basename15, dirname as dirname32, join as
|
|
73396
|
+
import { basename as basename15, dirname as dirname32, join as join109, relative as relative20, resolve as resolve29 } from "node:path";
|
|
73023
73397
|
|
|
73024
73398
|
// src/domains/plan-parser/index.ts
|
|
73025
73399
|
import { dirname as dirname31 } from "node:path";
|
|
@@ -73400,12 +73774,12 @@ function parsePlanFile(planFilePath, options2) {
|
|
|
73400
73774
|
}
|
|
73401
73775
|
// src/domains/plan-parser/plan-scanner.ts
|
|
73402
73776
|
import { existsSync as existsSync48, readdirSync as readdirSync5 } from "node:fs";
|
|
73403
|
-
import { join as
|
|
73777
|
+
import { join as join107 } from "node:path";
|
|
73404
73778
|
function scanPlanDir(dir) {
|
|
73405
73779
|
if (!existsSync48(dir))
|
|
73406
73780
|
return [];
|
|
73407
73781
|
try {
|
|
73408
|
-
return readdirSync5(dir, { withFileTypes: true }).filter((entry) => entry.isDirectory()).map((entry) =>
|
|
73782
|
+
return readdirSync5(dir, { withFileTypes: true }).filter((entry) => entry.isDirectory()).map((entry) => join107(dir, entry.name, "plan.md")).filter(existsSync48);
|
|
73409
73783
|
} catch {
|
|
73410
73784
|
return [];
|
|
73411
73785
|
}
|
|
@@ -73474,7 +73848,7 @@ function validatePlanFile(filePath, strict = false) {
|
|
|
73474
73848
|
var import_gray_matter7 = __toESM(require_gray_matter(), 1);
|
|
73475
73849
|
import { mkdirSync as mkdirSync3, readFileSync as readFileSync14, writeFileSync as writeFileSync5 } from "node:fs";
|
|
73476
73850
|
import { existsSync as existsSync50 } from "node:fs";
|
|
73477
|
-
import { basename as basename14, dirname as dirname30, join as
|
|
73851
|
+
import { basename as basename14, dirname as dirname30, join as join108 } from "node:path";
|
|
73478
73852
|
function phaseNameToFilename(id, name) {
|
|
73479
73853
|
const numMatch = /^(\d+)([a-z]*)$/i.exec(id);
|
|
73480
73854
|
const num = numMatch ? numMatch[1] : id;
|
|
@@ -73582,12 +73956,12 @@ function scaffoldPlan(options2) {
|
|
|
73582
73956
|
mkdirSync3(dir, { recursive: true });
|
|
73583
73957
|
const resolvedPhases = resolvePhaseIds(options2.phases);
|
|
73584
73958
|
const optionsWithResolved = { ...options2, phases: resolvedPhases };
|
|
73585
|
-
const planFile =
|
|
73959
|
+
const planFile = join108(dir, "plan.md");
|
|
73586
73960
|
writeFileSync5(planFile, generatePlanMd(optionsWithResolved), "utf8");
|
|
73587
73961
|
const phaseFiles = [];
|
|
73588
73962
|
for (const phase of resolvedPhases) {
|
|
73589
73963
|
const filename = phaseNameToFilename(phase.id, phase.name);
|
|
73590
|
-
const phaseFile =
|
|
73964
|
+
const phaseFile = join108(dir, filename);
|
|
73591
73965
|
writeFileSync5(phaseFile, generatePhaseTemplate(phase), "utf8");
|
|
73592
73966
|
phaseFiles.push(phaseFile);
|
|
73593
73967
|
}
|
|
@@ -73667,7 +74041,7 @@ function phaseNameFilenameFromTableRow(body, phaseId, planDir) {
|
|
|
73667
74041
|
continue;
|
|
73668
74042
|
const linkMatch = /\[([^\]]+)\]\(\.\/([^)]+)\)/.exec(row);
|
|
73669
74043
|
if (linkMatch)
|
|
73670
|
-
return
|
|
74044
|
+
return join108(planDir, linkMatch[2]);
|
|
73671
74045
|
}
|
|
73672
74046
|
return null;
|
|
73673
74047
|
}
|
|
@@ -73748,7 +74122,7 @@ function addPhase(planFile, name, afterId) {
|
|
|
73748
74122
|
`);
|
|
73749
74123
|
}
|
|
73750
74124
|
writeFileSync5(planFile, import_gray_matter7.default.stringify(updatedBody, frontmatter), "utf8");
|
|
73751
|
-
const phaseFilePath =
|
|
74125
|
+
const phaseFilePath = join108(planDir, filename);
|
|
73752
74126
|
writeFileSync5(phaseFilePath, generatePhaseTemplate({ id: phaseId, name }), "utf8");
|
|
73753
74127
|
return { phaseId, phaseFile: phaseFilePath };
|
|
73754
74128
|
}
|
|
@@ -73852,7 +74226,7 @@ async function handleValidate(target, options2) {
|
|
|
73852
74226
|
}
|
|
73853
74227
|
async function handleStatus(target, options2) {
|
|
73854
74228
|
const t = target ? resolve29(target) : null;
|
|
73855
|
-
const plansDir = t && existsSync51(t) && statSync4(t).isDirectory() && !existsSync51(
|
|
74229
|
+
const plansDir = t && existsSync51(t) && statSync4(t).isDirectory() && !existsSync51(join109(t, "plan.md")) ? t : null;
|
|
73856
74230
|
if (plansDir) {
|
|
73857
74231
|
const planFiles = scanPlanDir(plansDir);
|
|
73858
74232
|
if (planFiles.length === 0) {
|
|
@@ -74087,7 +74461,7 @@ function resolvePlanFile(target) {
|
|
|
74087
74461
|
const stat13 = statSync5(t);
|
|
74088
74462
|
if (stat13.isFile())
|
|
74089
74463
|
return t;
|
|
74090
|
-
const candidate =
|
|
74464
|
+
const candidate = join110(t, "plan.md");
|
|
74091
74465
|
if (existsSync52(candidate))
|
|
74092
74466
|
return candidate;
|
|
74093
74467
|
}
|
|
@@ -74095,7 +74469,7 @@ function resolvePlanFile(target) {
|
|
|
74095
74469
|
let dir = process.cwd();
|
|
74096
74470
|
const root = parse2(dir).root;
|
|
74097
74471
|
while (dir !== root) {
|
|
74098
|
-
const candidate =
|
|
74472
|
+
const candidate = join110(dir, "plan.md");
|
|
74099
74473
|
if (existsSync52(candidate))
|
|
74100
74474
|
return candidate;
|
|
74101
74475
|
dir = dirname33(dir);
|
|
@@ -74367,112 +74741,112 @@ var import_picocolors34 = __toESM(require_picocolors(), 1);
|
|
|
74367
74741
|
// src/commands/skills/agents.ts
|
|
74368
74742
|
import { existsSync as existsSync54 } from "node:fs";
|
|
74369
74743
|
import { homedir as homedir26 } from "node:os";
|
|
74370
|
-
import { join as
|
|
74744
|
+
import { join as join111 } from "node:path";
|
|
74371
74745
|
var home6 = homedir26();
|
|
74372
74746
|
var agents = {
|
|
74373
74747
|
"claude-code": {
|
|
74374
74748
|
name: "claude-code",
|
|
74375
74749
|
displayName: "Claude Code",
|
|
74376
74750
|
projectPath: ".claude/skills",
|
|
74377
|
-
globalPath:
|
|
74378
|
-
detect: async () => existsSync54(
|
|
74751
|
+
globalPath: join111(home6, ".claude/skills"),
|
|
74752
|
+
detect: async () => existsSync54(join111(home6, ".claude"))
|
|
74379
74753
|
},
|
|
74380
74754
|
cursor: {
|
|
74381
74755
|
name: "cursor",
|
|
74382
74756
|
displayName: "Cursor",
|
|
74383
74757
|
projectPath: ".cursor/skills",
|
|
74384
|
-
globalPath:
|
|
74385
|
-
detect: async () => existsSync54(
|
|
74758
|
+
globalPath: join111(home6, ".cursor/skills"),
|
|
74759
|
+
detect: async () => existsSync54(join111(home6, ".cursor"))
|
|
74386
74760
|
},
|
|
74387
74761
|
codex: {
|
|
74388
74762
|
name: "codex",
|
|
74389
74763
|
displayName: "Codex",
|
|
74390
74764
|
projectPath: ".codex/skills",
|
|
74391
|
-
globalPath:
|
|
74392
|
-
detect: async () => existsSync54(
|
|
74765
|
+
globalPath: join111(home6, ".codex/skills"),
|
|
74766
|
+
detect: async () => existsSync54(join111(home6, ".codex"))
|
|
74393
74767
|
},
|
|
74394
74768
|
opencode: {
|
|
74395
74769
|
name: "opencode",
|
|
74396
74770
|
displayName: "OpenCode",
|
|
74397
74771
|
projectPath: ".opencode/skills",
|
|
74398
|
-
globalPath:
|
|
74399
|
-
detect: async () => existsSync54(
|
|
74772
|
+
globalPath: join111(home6, ".config/opencode/skills"),
|
|
74773
|
+
detect: async () => existsSync54(join111(home6, ".config/opencode"))
|
|
74400
74774
|
},
|
|
74401
74775
|
goose: {
|
|
74402
74776
|
name: "goose",
|
|
74403
74777
|
displayName: "Goose",
|
|
74404
74778
|
projectPath: ".goose/skills",
|
|
74405
|
-
globalPath:
|
|
74406
|
-
detect: async () => existsSync54(
|
|
74779
|
+
globalPath: join111(home6, ".config/goose/skills"),
|
|
74780
|
+
detect: async () => existsSync54(join111(home6, ".config/goose"))
|
|
74407
74781
|
},
|
|
74408
74782
|
"gemini-cli": {
|
|
74409
74783
|
name: "gemini-cli",
|
|
74410
74784
|
displayName: "Gemini CLI",
|
|
74411
74785
|
projectPath: ".agents/skills",
|
|
74412
|
-
globalPath:
|
|
74413
|
-
detect: async () => existsSync54(
|
|
74786
|
+
globalPath: join111(home6, ".agents/skills"),
|
|
74787
|
+
detect: async () => existsSync54(join111(home6, ".gemini"))
|
|
74414
74788
|
},
|
|
74415
74789
|
antigravity: {
|
|
74416
74790
|
name: "antigravity",
|
|
74417
74791
|
displayName: "Antigravity",
|
|
74418
74792
|
projectPath: ".agent/skills",
|
|
74419
|
-
globalPath:
|
|
74420
|
-
detect: async () => existsSync54(
|
|
74793
|
+
globalPath: join111(home6, ".gemini/antigravity/skills"),
|
|
74794
|
+
detect: async () => existsSync54(join111(process.cwd(), ".agent")) || existsSync54(join111(home6, ".gemini/antigravity"))
|
|
74421
74795
|
},
|
|
74422
74796
|
"github-copilot": {
|
|
74423
74797
|
name: "github-copilot",
|
|
74424
74798
|
displayName: "GitHub Copilot",
|
|
74425
74799
|
projectPath: ".github/skills",
|
|
74426
|
-
globalPath:
|
|
74427
|
-
detect: async () => existsSync54(
|
|
74800
|
+
globalPath: join111(home6, ".copilot/skills"),
|
|
74801
|
+
detect: async () => existsSync54(join111(home6, ".copilot"))
|
|
74428
74802
|
},
|
|
74429
74803
|
amp: {
|
|
74430
74804
|
name: "amp",
|
|
74431
74805
|
displayName: "Amp",
|
|
74432
74806
|
projectPath: ".agents/skills",
|
|
74433
|
-
globalPath:
|
|
74434
|
-
detect: async () => existsSync54(
|
|
74807
|
+
globalPath: join111(home6, ".config/agents/skills"),
|
|
74808
|
+
detect: async () => existsSync54(join111(home6, ".config/amp"))
|
|
74435
74809
|
},
|
|
74436
74810
|
kilo: {
|
|
74437
74811
|
name: "kilo",
|
|
74438
74812
|
displayName: "Kilo Code",
|
|
74439
74813
|
projectPath: ".kilocode/skills",
|
|
74440
|
-
globalPath:
|
|
74441
|
-
detect: async () => existsSync54(
|
|
74814
|
+
globalPath: join111(home6, ".kilocode/skills"),
|
|
74815
|
+
detect: async () => existsSync54(join111(home6, ".kilocode"))
|
|
74442
74816
|
},
|
|
74443
74817
|
roo: {
|
|
74444
74818
|
name: "roo",
|
|
74445
74819
|
displayName: "Roo Code",
|
|
74446
74820
|
projectPath: ".roo/skills",
|
|
74447
|
-
globalPath:
|
|
74448
|
-
detect: async () => existsSync54(
|
|
74821
|
+
globalPath: join111(home6, ".roo/skills"),
|
|
74822
|
+
detect: async () => existsSync54(join111(home6, ".roo"))
|
|
74449
74823
|
},
|
|
74450
74824
|
windsurf: {
|
|
74451
74825
|
name: "windsurf",
|
|
74452
74826
|
displayName: "Windsurf",
|
|
74453
74827
|
projectPath: ".windsurf/skills",
|
|
74454
|
-
globalPath:
|
|
74455
|
-
detect: async () => existsSync54(
|
|
74828
|
+
globalPath: join111(home6, ".codeium/windsurf/skills"),
|
|
74829
|
+
detect: async () => existsSync54(join111(home6, ".codeium/windsurf"))
|
|
74456
74830
|
},
|
|
74457
74831
|
cline: {
|
|
74458
74832
|
name: "cline",
|
|
74459
74833
|
displayName: "Cline",
|
|
74460
74834
|
projectPath: ".cline/skills",
|
|
74461
|
-
globalPath:
|
|
74462
|
-
detect: async () => existsSync54(
|
|
74835
|
+
globalPath: join111(home6, ".cline/skills"),
|
|
74836
|
+
detect: async () => existsSync54(join111(home6, ".cline"))
|
|
74463
74837
|
},
|
|
74464
74838
|
openhands: {
|
|
74465
74839
|
name: "openhands",
|
|
74466
74840
|
displayName: "OpenHands",
|
|
74467
74841
|
projectPath: ".openhands/skills",
|
|
74468
|
-
globalPath:
|
|
74469
|
-
detect: async () => existsSync54(
|
|
74842
|
+
globalPath: join111(home6, ".openhands/skills"),
|
|
74843
|
+
detect: async () => existsSync54(join111(home6, ".openhands"))
|
|
74470
74844
|
}
|
|
74471
74845
|
};
|
|
74472
74846
|
function getInstallPath(skillName, agent, options2) {
|
|
74473
74847
|
const config = agents[agent];
|
|
74474
74848
|
const basePath = options2.global ? config.globalPath : config.projectPath;
|
|
74475
|
-
return
|
|
74849
|
+
return join111(basePath, skillName);
|
|
74476
74850
|
}
|
|
74477
74851
|
function isSkillInstalled(skillName, agent, options2) {
|
|
74478
74852
|
const installPath = getInstallPath(skillName, agent, options2);
|
|
@@ -74483,16 +74857,16 @@ function isSkillInstalled(skillName, agent, options2) {
|
|
|
74483
74857
|
import { existsSync as existsSync56 } from "node:fs";
|
|
74484
74858
|
import { cp as cp4, mkdir as mkdir31, rm as rm14, stat as stat13 } from "node:fs/promises";
|
|
74485
74859
|
import { homedir as homedir28 } from "node:os";
|
|
74486
|
-
import { dirname as dirname35, join as
|
|
74860
|
+
import { dirname as dirname35, join as join113, resolve as resolve33 } from "node:path";
|
|
74487
74861
|
|
|
74488
74862
|
// src/commands/skills/skills-registry.ts
|
|
74489
74863
|
init_zod();
|
|
74490
74864
|
import { existsSync as existsSync55 } from "node:fs";
|
|
74491
74865
|
import { mkdir as mkdir30, readFile as readFile47, writeFile as writeFile35 } from "node:fs/promises";
|
|
74492
74866
|
import { homedir as homedir27 } from "node:os";
|
|
74493
|
-
import { dirname as dirname34, join as
|
|
74867
|
+
import { dirname as dirname34, join as join112, sep as sep9 } from "node:path";
|
|
74494
74868
|
var home7 = homedir27();
|
|
74495
|
-
var REGISTRY_PATH2 =
|
|
74869
|
+
var REGISTRY_PATH2 = join112(home7, ".sunagentkit", "skill-registry.json");
|
|
74496
74870
|
var SkillInstallationSchema = exports_external.object({
|
|
74497
74871
|
skill: exports_external.string(),
|
|
74498
74872
|
agent: exports_external.string(),
|
|
@@ -74630,7 +75004,7 @@ async function syncRegistry() {
|
|
|
74630
75004
|
var LEGACY_SKILL_PATHS = {
|
|
74631
75005
|
"gemini-cli": {
|
|
74632
75006
|
project: ".gemini/skills",
|
|
74633
|
-
global:
|
|
75007
|
+
global: join113(homedir28(), ".gemini/skills")
|
|
74634
75008
|
}
|
|
74635
75009
|
};
|
|
74636
75010
|
function isSamePath3(path1, path22) {
|
|
@@ -74664,7 +75038,7 @@ async function cleanupLegacySkillPath(skillName, agent, global3) {
|
|
|
74664
75038
|
if (!legacy)
|
|
74665
75039
|
return;
|
|
74666
75040
|
const legacyBase = global3 ? legacy.global : legacy.project;
|
|
74667
|
-
const legacyPath =
|
|
75041
|
+
const legacyPath = join113(legacyBase, skillName);
|
|
74668
75042
|
if (!existsSync56(legacyPath))
|
|
74669
75043
|
return;
|
|
74670
75044
|
await rm14(legacyPath, { recursive: true, force: true });
|
|
@@ -74674,7 +75048,7 @@ async function cleanupLegacySkillPath(skillName, agent, global3) {
|
|
|
74674
75048
|
if (entry.skill === skillName && entry.agent === agent && entry.global === global3) {
|
|
74675
75049
|
if (entry.path === legacyPath) {
|
|
74676
75050
|
const newBase = global3 ? agents[agent].globalPath : agents[agent].projectPath;
|
|
74677
|
-
entry.path =
|
|
75051
|
+
entry.path = join113(newBase, skillName);
|
|
74678
75052
|
changed = true;
|
|
74679
75053
|
}
|
|
74680
75054
|
}
|
|
@@ -74759,7 +75133,7 @@ function getInstallPreview(skill, targetAgents, options2) {
|
|
|
74759
75133
|
// src/commands/skills/skills-uninstaller.ts
|
|
74760
75134
|
import { existsSync as existsSync57 } from "node:fs";
|
|
74761
75135
|
import { rm as rm15 } from "node:fs/promises";
|
|
74762
|
-
import { join as
|
|
75136
|
+
import { join as join114 } from "node:path";
|
|
74763
75137
|
async function uninstallSkillFromAgent(skill, agent, global3) {
|
|
74764
75138
|
const agentConfig = agents[agent];
|
|
74765
75139
|
const registry = await readRegistry();
|
|
@@ -74807,7 +75181,7 @@ async function uninstallSkillFromAgent(skill, agent, global3) {
|
|
|
74807
75181
|
async function forceUninstallSkill(skill, agent, global3) {
|
|
74808
75182
|
const agentConfig = agents[agent];
|
|
74809
75183
|
const basePath = global3 ? agentConfig.globalPath : agentConfig.projectPath;
|
|
74810
|
-
const path9 =
|
|
75184
|
+
const path9 = join114(basePath, skill);
|
|
74811
75185
|
if (!existsSync57(path9)) {
|
|
74812
75186
|
return {
|
|
74813
75187
|
skill,
|
|
@@ -75312,12 +75686,12 @@ init_logger();
|
|
|
75312
75686
|
// src/commands/telemetry/shared.ts
|
|
75313
75687
|
import { existsSync as existsSync58, readFileSync as readFileSync15, readdirSync as readdirSync6 } from "node:fs";
|
|
75314
75688
|
import { homedir as homedir29 } from "node:os";
|
|
75315
|
-
import { join as
|
|
75689
|
+
import { join as join115 } from "node:path";
|
|
75316
75690
|
init_token_store();
|
|
75317
|
-
var USER_CACHE_PATH =
|
|
75318
|
-
var EVENT_BUFFER_DIR =
|
|
75319
|
-
var RATE_STATE_PATH =
|
|
75320
|
-
var METADATA_PATH =
|
|
75691
|
+
var USER_CACHE_PATH = join115(homedir29(), ".claude", "sk-user.json");
|
|
75692
|
+
var EVENT_BUFFER_DIR = join115(homedir29(), ".claude", "sk-events");
|
|
75693
|
+
var RATE_STATE_PATH = join115(homedir29(), ".claude", "sk-rate-state.json");
|
|
75694
|
+
var METADATA_PATH = join115(homedir29(), ".claude", "metadata.json");
|
|
75321
75695
|
var TELEMETRY_HOOK_FIELD = "hooks.telemetry";
|
|
75322
75696
|
var TOKEN_PLACEHOLDER = "__INJECT_AT_RELEASE__";
|
|
75323
75697
|
function readUserCache() {
|
|
@@ -75404,7 +75778,7 @@ async function handleDisable() {
|
|
|
75404
75778
|
// src/commands/telemetry/phases/purge-local-handler.ts
|
|
75405
75779
|
init_logger();
|
|
75406
75780
|
import { existsSync as existsSync59, readdirSync as readdirSync7, unlinkSync as unlinkSync5 } from "node:fs";
|
|
75407
|
-
import { join as
|
|
75781
|
+
import { join as join116 } from "node:path";
|
|
75408
75782
|
function removeIfExists(path9) {
|
|
75409
75783
|
try {
|
|
75410
75784
|
if (!existsSync59(path9))
|
|
@@ -75424,7 +75798,7 @@ function removeBufferFiles() {
|
|
|
75424
75798
|
if (!file.endsWith(".jsonl"))
|
|
75425
75799
|
continue;
|
|
75426
75800
|
try {
|
|
75427
|
-
unlinkSync5(
|
|
75801
|
+
unlinkSync5(join116(EVENT_BUFFER_DIR, file));
|
|
75428
75802
|
count += 1;
|
|
75429
75803
|
} catch {}
|
|
75430
75804
|
}
|
|
@@ -75650,13 +76024,13 @@ async function detectInstallations() {
|
|
|
75650
76024
|
|
|
75651
76025
|
// src/commands/uninstall/removal-handler.ts
|
|
75652
76026
|
import { readdirSync as readdirSync9, rmSync as rmSync6 } from "node:fs";
|
|
75653
|
-
import { join as
|
|
76027
|
+
import { join as join118, resolve as resolve34, sep as sep10 } from "node:path";
|
|
75654
76028
|
init_logger();
|
|
75655
76029
|
var import_fs_extra38 = __toESM(require_lib(), 1);
|
|
75656
76030
|
|
|
75657
76031
|
// src/commands/uninstall/analysis-handler.ts
|
|
75658
76032
|
import { readdirSync as readdirSync8, rmSync as rmSync5 } from "node:fs";
|
|
75659
|
-
import { dirname as dirname36, join as
|
|
76033
|
+
import { dirname as dirname36, join as join117 } from "node:path";
|
|
75660
76034
|
init_logger();
|
|
75661
76035
|
var import_picocolors35 = __toESM(require_picocolors(), 1);
|
|
75662
76036
|
function classifyFileByOwnership(ownership, forceOverwrite, deleteReason) {
|
|
@@ -75703,7 +76077,7 @@ async function analyzeInstallation(installation, forceOverwrite, kit) {
|
|
|
75703
76077
|
if (uninstallManifest.isMultiKit && kit && metadata?.kits?.[kit]) {
|
|
75704
76078
|
const kitFiles = metadata.kits[kit].files || [];
|
|
75705
76079
|
for (const trackedFile of kitFiles) {
|
|
75706
|
-
const filePath =
|
|
76080
|
+
const filePath = join117(installation.path, trackedFile.path);
|
|
75707
76081
|
if (uninstallManifest.filesToPreserve.includes(trackedFile.path)) {
|
|
75708
76082
|
result.toPreserve.push({ path: trackedFile.path, reason: "shared with other kit" });
|
|
75709
76083
|
continue;
|
|
@@ -75733,7 +76107,7 @@ async function analyzeInstallation(installation, forceOverwrite, kit) {
|
|
|
75733
76107
|
return result;
|
|
75734
76108
|
}
|
|
75735
76109
|
for (const trackedFile of allTrackedFiles) {
|
|
75736
|
-
const filePath =
|
|
76110
|
+
const filePath = join117(installation.path, trackedFile.path);
|
|
75737
76111
|
const ownershipResult = await OwnershipChecker.checkOwnership(filePath, metadata, installation.path);
|
|
75738
76112
|
if (!ownershipResult.exists)
|
|
75739
76113
|
continue;
|
|
@@ -75830,7 +76204,7 @@ async function removeInstallations(installations, options2) {
|
|
|
75830
76204
|
let removedCount = 0;
|
|
75831
76205
|
let cleanedDirs = 0;
|
|
75832
76206
|
for (const item of analysis.toDelete) {
|
|
75833
|
-
const filePath =
|
|
76207
|
+
const filePath = join118(installation.path, item.path);
|
|
75834
76208
|
if (!await import_fs_extra38.pathExists(filePath))
|
|
75835
76209
|
continue;
|
|
75836
76210
|
if (!await isPathSafeToRemove(filePath, installation.path)) {
|
|
@@ -76032,7 +76406,7 @@ ${import_picocolors36.default.yellow("User modifications will be permanently del
|
|
|
76032
76406
|
// src/commands/update-cli.ts
|
|
76033
76407
|
init_takumi_config_manager();
|
|
76034
76408
|
import { exec as exec8, spawn as spawn2 } from "node:child_process";
|
|
76035
|
-
import { join as
|
|
76409
|
+
import { join as join119 } from "node:path";
|
|
76036
76410
|
import { promisify as promisify14 } from "node:util";
|
|
76037
76411
|
|
|
76038
76412
|
// src/domains/github/npm-registry.ts
|
|
@@ -76199,7 +76573,7 @@ var import_fs_extra39 = __toESM(require_lib(), 1);
|
|
|
76199
76573
|
// package.json
|
|
76200
76574
|
var package_default = {
|
|
76201
76575
|
name: "@sunasteriskrnd/takumi",
|
|
76202
|
-
version: "0.
|
|
76576
|
+
version: "0.6.0",
|
|
76203
76577
|
description: "CLI tool for bootstrapping and managing Takumi projects",
|
|
76204
76578
|
type: "module",
|
|
76205
76579
|
repository: {
|
|
@@ -76222,6 +76596,7 @@ var package_default = {
|
|
|
76222
76596
|
build: `bun build src/index.ts --outdir dist --target node --external @octokit/rest --external better-sqlite3 --external yauzl-promise --external @node-rs/crc32 && node -e "const fs=require('fs'),f='dist/index.js',c=fs.readFileSync(f,'utf-8');fs.writeFileSync(f,c.replace(/^#!.*\\n\\/\\/ @bun\\n/,''))"`,
|
|
76223
76597
|
"verify:package": "node scripts/prepublish-check.js",
|
|
76224
76598
|
test: "bun test",
|
|
76599
|
+
"test:ci": "NON_INTERACTIVE=true CI_SAFE_MODE=true bun test",
|
|
76225
76600
|
"test:integration": "CK_RUN_CLI_INTEGRATION=1 bun test tests/integration/cli.test.ts",
|
|
76226
76601
|
"test:watch": "bun test --watch",
|
|
76227
76602
|
"test:quick": "./scripts/dev-quick-start.sh test",
|
|
@@ -76383,7 +76758,7 @@ function selectKitForUpdate(params) {
|
|
|
76383
76758
|
};
|
|
76384
76759
|
}
|
|
76385
76760
|
async function readMetadataFile(claudeDir) {
|
|
76386
|
-
const metadataPath =
|
|
76761
|
+
const metadataPath = join119(claudeDir, "metadata.json");
|
|
76387
76762
|
try {
|
|
76388
76763
|
if (!await import_fs_extra39.pathExists(metadataPath)) {
|
|
76389
76764
|
return null;
|
|
@@ -76884,7 +77259,7 @@ init_logger();
|
|
|
76884
77259
|
import { existsSync as existsSync65 } from "node:fs";
|
|
76885
77260
|
import { rm as rm16 } from "node:fs/promises";
|
|
76886
77261
|
import { homedir as homedir31 } from "node:os";
|
|
76887
|
-
import { join as
|
|
77262
|
+
import { join as join126 } from "node:path";
|
|
76888
77263
|
var import_picocolors38 = __toESM(require_picocolors(), 1);
|
|
76889
77264
|
|
|
76890
77265
|
// src/commands/watch/phases/implementation-runner.ts
|
|
@@ -77394,7 +77769,7 @@ function spawnAndCollect3(command, args) {
|
|
|
77394
77769
|
|
|
77395
77770
|
// src/commands/watch/phases/issue-processor.ts
|
|
77396
77771
|
import { mkdir as mkdir32, writeFile as writeFile37 } from "node:fs/promises";
|
|
77397
|
-
import { join as
|
|
77772
|
+
import { join as join122 } from "node:path";
|
|
77398
77773
|
|
|
77399
77774
|
// src/commands/watch/phases/approval-detector.ts
|
|
77400
77775
|
init_logger();
|
|
@@ -77769,9 +78144,9 @@ async function checkAwaitingApproval(state, setup, options2, watchLog, projectDi
|
|
|
77769
78144
|
|
|
77770
78145
|
// src/commands/watch/phases/plan-dir-finder.ts
|
|
77771
78146
|
import { readdir as readdir32, stat as stat14 } from "node:fs/promises";
|
|
77772
|
-
import { join as
|
|
78147
|
+
import { join as join121 } from "node:path";
|
|
77773
78148
|
async function findRecentPlanDir(cwd2, issueNumber, watchLog) {
|
|
77774
|
-
const plansRoot =
|
|
78149
|
+
const plansRoot = join121(cwd2, "plans");
|
|
77775
78150
|
try {
|
|
77776
78151
|
const entries = await readdir32(plansRoot);
|
|
77777
78152
|
const tenMinAgo = Date.now() - 10 * 60 * 1000;
|
|
@@ -77780,14 +78155,14 @@ async function findRecentPlanDir(cwd2, issueNumber, watchLog) {
|
|
|
77780
78155
|
for (const entry of entries) {
|
|
77781
78156
|
if (entry === "watch" || entry === "reports" || entry === "visuals")
|
|
77782
78157
|
continue;
|
|
77783
|
-
const dirPath =
|
|
78158
|
+
const dirPath = join121(plansRoot, entry);
|
|
77784
78159
|
const dirStat = await stat14(dirPath);
|
|
77785
78160
|
if (!dirStat.isDirectory())
|
|
77786
78161
|
continue;
|
|
77787
78162
|
if (dirStat.mtimeMs < tenMinAgo)
|
|
77788
78163
|
continue;
|
|
77789
78164
|
try {
|
|
77790
|
-
await stat14(
|
|
78165
|
+
await stat14(join121(dirPath, "plan.md"));
|
|
77791
78166
|
} catch {
|
|
77792
78167
|
continue;
|
|
77793
78168
|
}
|
|
@@ -78018,13 +78393,13 @@ async function handlePlanGeneration(issue, state, config, setup, options2, watch
|
|
|
78018
78393
|
stats.plansCreated++;
|
|
78019
78394
|
const detectedPlanDir = await findRecentPlanDir(projectDir, issue.number, watchLog);
|
|
78020
78395
|
if (detectedPlanDir) {
|
|
78021
|
-
state.activeIssues[numStr].planPath =
|
|
78396
|
+
state.activeIssues[numStr].planPath = join122(detectedPlanDir, "plan.md");
|
|
78022
78397
|
watchLog.info(`Plan directory detected: ${detectedPlanDir}`);
|
|
78023
78398
|
} else {
|
|
78024
78399
|
try {
|
|
78025
|
-
const planDir =
|
|
78400
|
+
const planDir = join122(projectDir, "plans", "watch");
|
|
78026
78401
|
await mkdir32(planDir, { recursive: true });
|
|
78027
|
-
const planFilePath =
|
|
78402
|
+
const planFilePath = join122(planDir, `issue-${issue.number}-plan.md`);
|
|
78028
78403
|
await writeFile37(planFilePath, planResult.planText, "utf-8");
|
|
78029
78404
|
state.activeIssues[numStr].planPath = planFilePath;
|
|
78030
78405
|
watchLog.info(`Plan saved (fallback) to ${planFilePath}`);
|
|
@@ -78329,18 +78704,18 @@ init_logger();
|
|
|
78329
78704
|
import { spawnSync as spawnSync5 } from "node:child_process";
|
|
78330
78705
|
import { existsSync as existsSync62 } from "node:fs";
|
|
78331
78706
|
import { readdir as readdir33, stat as stat15 } from "node:fs/promises";
|
|
78332
|
-
import { join as
|
|
78707
|
+
import { join as join123 } from "node:path";
|
|
78333
78708
|
async function scanForRepos(parentDir) {
|
|
78334
78709
|
const repos = [];
|
|
78335
78710
|
const entries = await readdir33(parentDir);
|
|
78336
78711
|
for (const entry of entries) {
|
|
78337
78712
|
if (entry.startsWith("."))
|
|
78338
78713
|
continue;
|
|
78339
|
-
const fullPath =
|
|
78714
|
+
const fullPath = join123(parentDir, entry);
|
|
78340
78715
|
const entryStat = await stat15(fullPath);
|
|
78341
78716
|
if (!entryStat.isDirectory())
|
|
78342
78717
|
continue;
|
|
78343
|
-
const gitDir =
|
|
78718
|
+
const gitDir = join123(fullPath, ".git");
|
|
78344
78719
|
if (!existsSync62(gitDir))
|
|
78345
78720
|
continue;
|
|
78346
78721
|
const result = spawnSync5("gh", ["repo", "view", "--json", "owner,name"], {
|
|
@@ -78367,7 +78742,7 @@ init_logger();
|
|
|
78367
78742
|
import { spawnSync as spawnSync6 } from "node:child_process";
|
|
78368
78743
|
import { existsSync as existsSync63 } from "node:fs";
|
|
78369
78744
|
import { homedir as homedir30 } from "node:os";
|
|
78370
|
-
import { join as
|
|
78745
|
+
import { join as join124 } from "node:path";
|
|
78371
78746
|
async function validateSetup(cwd2) {
|
|
78372
78747
|
const workDir = cwd2 ?? process.cwd();
|
|
78373
78748
|
const ghVersion = spawnSync6("gh", ["--version"], { encoding: "utf-8", timeout: 1e4 });
|
|
@@ -78398,7 +78773,7 @@ Run this command from a directory with a GitHub remote.`);
|
|
|
78398
78773
|
} catch {
|
|
78399
78774
|
throw new Error(`Failed to parse repository info: ${ghRepo.stdout}`);
|
|
78400
78775
|
}
|
|
78401
|
-
const skillsPath =
|
|
78776
|
+
const skillsPath = join124(homedir30(), ".claude", "skills");
|
|
78402
78777
|
const skillsAvailable = existsSync63(skillsPath);
|
|
78403
78778
|
if (!skillsAvailable) {
|
|
78404
78779
|
logger.warning(`Takumi Engineer skills not found at ${skillsPath}`);
|
|
@@ -78417,7 +78792,7 @@ init_path_resolver();
|
|
|
78417
78792
|
import { createWriteStream as createWriteStream4, statSync as statSync6 } from "node:fs";
|
|
78418
78793
|
import { existsSync as existsSync64 } from "node:fs";
|
|
78419
78794
|
import { mkdir as mkdir34, rename as rename9 } from "node:fs/promises";
|
|
78420
|
-
import { join as
|
|
78795
|
+
import { join as join125 } from "node:path";
|
|
78421
78796
|
|
|
78422
78797
|
class WatchLogger {
|
|
78423
78798
|
logStream = null;
|
|
@@ -78425,7 +78800,7 @@ class WatchLogger {
|
|
|
78425
78800
|
logPath = null;
|
|
78426
78801
|
maxBytes;
|
|
78427
78802
|
constructor(logDir, maxBytes = 0) {
|
|
78428
|
-
this.logDir = logDir ??
|
|
78803
|
+
this.logDir = logDir ?? join125(PathResolver.getTakumiDir(), "logs");
|
|
78429
78804
|
this.maxBytes = maxBytes;
|
|
78430
78805
|
}
|
|
78431
78806
|
async init() {
|
|
@@ -78434,7 +78809,7 @@ class WatchLogger {
|
|
|
78434
78809
|
await mkdir34(this.logDir, { recursive: true });
|
|
78435
78810
|
}
|
|
78436
78811
|
const dateStr = formatDate(new Date);
|
|
78437
|
-
this.logPath =
|
|
78812
|
+
this.logPath = join125(this.logDir, `watch-${dateStr}.log`);
|
|
78438
78813
|
this.logStream = createWriteStream4(this.logPath, { flags: "a", mode: 384 });
|
|
78439
78814
|
} catch (error) {
|
|
78440
78815
|
logger.warning(`Cannot create watch log file: ${error instanceof Error ? error.message : "Unknown"}`);
|
|
@@ -78614,7 +78989,7 @@ async function watchCommand(options2) {
|
|
|
78614
78989
|
}
|
|
78615
78990
|
async function discoverRepos(options2, watchLog) {
|
|
78616
78991
|
const cwd2 = process.cwd();
|
|
78617
|
-
const isGitRepo = existsSync65(
|
|
78992
|
+
const isGitRepo = existsSync65(join126(cwd2, ".git"));
|
|
78618
78993
|
if (options2.force) {
|
|
78619
78994
|
await forceRemoveLock(watchLog);
|
|
78620
78995
|
}
|
|
@@ -78684,7 +79059,7 @@ async function resetState(state, projectDir, watchLog) {
|
|
|
78684
79059
|
watchLog.info(`Watch state reset (--force) for ${projectDir}`);
|
|
78685
79060
|
}
|
|
78686
79061
|
async function forceRemoveLock(watchLog) {
|
|
78687
|
-
const lockPath =
|
|
79062
|
+
const lockPath = join126(homedir31(), ".sunagentkit", "locks", `${LOCK_NAME}.lock`);
|
|
78688
79063
|
try {
|
|
78689
79064
|
await rm16(lockPath, { recursive: true, force: true });
|
|
78690
79065
|
watchLog.info("Removed existing lock file (--force)");
|
|
@@ -78728,13 +79103,13 @@ function sleep2(ms2) {
|
|
|
78728
79103
|
// src/cli/command-registry.ts
|
|
78729
79104
|
init_logger();
|
|
78730
79105
|
function registerCommands(cli) {
|
|
78731
|
-
cli.command("new", "Bootstrap a new Takumi project (with interactive version selection)").option("--dir <dir>", "Target directory (default: .)").option("--kit <kit>", "Kit to
|
|
79106
|
+
cli.command("new", "Bootstrap a new Takumi project (with interactive version selection)").option("--dir <dir>", "Target directory (default: .)").option("--kit <kit>", "Kit(s) to install (engineer, extras). Repeat the flag to install multiple kits, e.g. --kit engineer --kit extras.").option("-r, --release <version>", "Skip version selection, use specific version (e.g., latest, v1.0.0)").option("--force", "Overwrite existing files without confirmation").option("--exclude <pattern>", "Exclude files matching glob pattern (can be used multiple times)").option("--opencode", "Install OpenCode CLI package (non-interactive mode)").option("--gemini", "Install Google Gemini CLI package (non-interactive mode)").option("--install-skills", "Install skills dependencies (non-interactive mode)").option("--with-sudo", "Include system packages requiring sudo (Linux: ffmpeg, imagemagick)").option("--prefix", "Add /sk: prefix to all slash commands by moving them to commands/sk/ subdirectory").option("--beta", "Show beta versions in selection prompt").option("--refresh", "Bypass release cache to fetch latest versions from GitHub").option("--docs-dir <name>", "Custom docs folder name (default: docs)").option("--plans-dir <name>", "Custom plans folder name (default: plans)").option("-y, --yes", "Non-interactive mode with sensible defaults (skip all prompts)").option("--use-git", "Use git clone instead of GitHub API (uses SSH/HTTPS credentials)").option("--archive <path>", "Use local archive file instead of downloading (zip/tar.gz)").option("--kit-path <path>", "Use local kit directory instead of downloading").option("--local", "Use local monorepo as kit source (auto-detects from CLI location)").option("--use-gh", "Force GitHub release source (bypass Worker R2 proxy; default uses Worker)").action(async (options2) => {
|
|
78732
79107
|
if (options2.exclude && !Array.isArray(options2.exclude)) {
|
|
78733
79108
|
options2.exclude = [options2.exclude];
|
|
78734
79109
|
}
|
|
78735
79110
|
await newCommand(options2);
|
|
78736
79111
|
});
|
|
78737
|
-
cli.command("init", "Initialize or update Takumi project (with interactive version selection)").option("--dir <dir>", "Target directory (default: .)").option("--kit <kit>", "Kit to
|
|
79112
|
+
cli.command("init", "Initialize or update Takumi project (with interactive version selection)").option("--dir <dir>", "Target directory (default: .)").option("--kit <kit>", "Kit(s) to install (engineer, extras). Repeat the flag to install multiple kits, e.g. --kit engineer --kit extras.").option("-r, --release <version>", "Skip version selection, use specific version (e.g., latest, v1.0.0)").option("--exclude <pattern>", "Exclude files matching glob pattern (can be used multiple times)").option("--only <pattern>", "Include only files matching glob pattern (can be used multiple times)").option("-g, --global", "Use platform-specific user configuration directory").option("--fresh", "Full reset: remove SK files, replace settings.json and CLAUDE.md, reinstall from scratch").option("--force", "Force reinstall even if already at latest version (use with --yes; re-onboards missing files without full reset)").option("--install-skills", "Install skills dependencies (non-interactive mode)").option("--with-sudo", "Include system packages requiring sudo (Linux: ffmpeg, imagemagick)").option("--prefix", "Add /sk: prefix to all slash commands by moving them to commands/sk/ subdirectory").option("--beta", "Show beta versions in selection prompt").option("--refresh", "Bypass release cache to fetch latest versions from GitHub").option("--dry-run", "Preview changes without applying them (requires --prefix)").option("--force-overwrite", "Override ownership protections and delete user-modified files (requires --prefix)").option("--force-overwrite-settings", "Fully replace settings.json instead of selective merge (destroys user customizations)").option("--skip-setup", "Skip interactive configuration wizard").option("--docs-dir <name>", "Custom docs folder name (default: docs)").option("--plans-dir <name>", "Custom plans folder name (default: plans)").option("-y, --yes", "Non-interactive mode with sensible defaults (skip all prompts)").option("--sync", "Sync config files from upstream with interactive hunk-by-hunk merge").option("--use-git", "Use git clone instead of GitHub API (uses SSH/HTTPS credentials)").option("--archive <path>", "Use local archive file instead of downloading (zip/tar.gz)").option("--kit-path <path>", "Use local kit directory instead of downloading").option("--local", "Use local monorepo as kit source (auto-detects from CLI location)").option("--use-gh", "Force GitHub release source (bypass Worker R2 proxy; default uses Worker)").option("-a, --agent <agents...>", "Target agents (claude-code, codex). Default: claude-code").action(async (options2) => {
|
|
78738
79113
|
if (options2.exclude && !Array.isArray(options2.exclude)) {
|
|
78739
79114
|
options2.exclude = [options2.exclude];
|
|
78740
79115
|
}
|
|
@@ -78747,6 +79122,9 @@ function registerCommands(cli) {
|
|
|
78747
79122
|
if (options2.agent) {
|
|
78748
79123
|
options2.agents = options2.agent;
|
|
78749
79124
|
}
|
|
79125
|
+
if (options2.kit && Array.isArray(options2.kit)) {
|
|
79126
|
+
options2.kit = options2.kit.join(",");
|
|
79127
|
+
}
|
|
78750
79128
|
await initCommand(options2);
|
|
78751
79129
|
});
|
|
78752
79130
|
cli.command("update", "Update Takumi CLI to the latest version").option("-r, --release <version>", "Update to a specific version").option("--check", "Check for updates without installing").option("-y, --yes", "Non-interactive mode with sensible defaults (skip all prompts)").option("-d, --dev", "Update to the latest dev version").option("--beta", "Alias for --dev (deprecated)").option("--registry <url>", "Custom npm registry URL").option("--kit <kit>", "[DEPRECATED] Use 'takumi init --kit <kit>' instead").option("-g, --global", "[DEPRECATED] Use 'takumi init --global' instead").action(async (options2) => {
|
|
@@ -78886,7 +79264,7 @@ function registerCommands(cli) {
|
|
|
78886
79264
|
|
|
78887
79265
|
// src/cli/version-display.ts
|
|
78888
79266
|
import { existsSync as existsSync77, readFileSync as readFileSync20 } from "node:fs";
|
|
78889
|
-
import { join as
|
|
79267
|
+
import { join as join138 } from "node:path";
|
|
78890
79268
|
init_help_banner();
|
|
78891
79269
|
// src/domains/versioning/checking/kit-version-checker.ts
|
|
78892
79270
|
init_github_client();
|
|
@@ -78898,14 +79276,14 @@ init_logger();
|
|
|
78898
79276
|
init_path_resolver();
|
|
78899
79277
|
import { existsSync as existsSync76 } from "node:fs";
|
|
78900
79278
|
import { mkdir as mkdir35, readFile as readFile52, writeFile as writeFile40 } from "node:fs/promises";
|
|
78901
|
-
import { join as
|
|
79279
|
+
import { join as join137 } from "node:path";
|
|
78902
79280
|
|
|
78903
79281
|
class VersionCacheManager {
|
|
78904
79282
|
static CACHE_FILENAME = "version-check.json";
|
|
78905
79283
|
static CACHE_TTL_MS = 7 * 24 * 60 * 60 * 1000;
|
|
78906
79284
|
static getCacheFile() {
|
|
78907
79285
|
const cacheDir = PathResolver.getCacheDir(false);
|
|
78908
|
-
return
|
|
79286
|
+
return join137(cacheDir, VersionCacheManager.CACHE_FILENAME);
|
|
78909
79287
|
}
|
|
78910
79288
|
static async load() {
|
|
78911
79289
|
const cacheFile = VersionCacheManager.getCacheFile();
|
|
@@ -79198,8 +79576,8 @@ async function displayVersion() {
|
|
|
79198
79576
|
const localSubdir = PROVIDER_LOCAL_SUBDIRS[provider];
|
|
79199
79577
|
if (!localSubdir)
|
|
79200
79578
|
continue;
|
|
79201
|
-
const localMeta =
|
|
79202
|
-
if (localMeta ===
|
|
79579
|
+
const localMeta = join138(process.cwd(), localSubdir, "metadata.json");
|
|
79580
|
+
if (localMeta === join138(inst.globalRoot(), "metadata.json"))
|
|
79203
79581
|
continue;
|
|
79204
79582
|
if (!existsSync77(localMeta))
|
|
79205
79583
|
continue;
|
|
@@ -79224,7 +79602,7 @@ async function displayVersion() {
|
|
|
79224
79602
|
}
|
|
79225
79603
|
const singleInstall = detectedGlobals.length === 1 && detectedGlobals[0]?.provider === "claude-code";
|
|
79226
79604
|
for (const { provider, path: installPath } of detectedGlobals) {
|
|
79227
|
-
const metadataPath =
|
|
79605
|
+
const metadataPath = join138(installPath, "metadata.json");
|
|
79228
79606
|
if (existsSync77(metadataPath)) {
|
|
79229
79607
|
try {
|
|
79230
79608
|
const rawMetadata = JSON.parse(readFileSync20(metadataPath, "utf-8"));
|