@sunasteriskrnd/takumi 1.0.0-dev.25 → 1.0.0-dev.27
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 +380 -220
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -8539,7 +8539,7 @@ var package_default;
|
|
|
8539
8539
|
var init_package = __esm(() => {
|
|
8540
8540
|
package_default = {
|
|
8541
8541
|
name: "@sunasteriskrnd/takumi",
|
|
8542
|
-
version: "1.0.0-dev.
|
|
8542
|
+
version: "1.0.0-dev.27",
|
|
8543
8543
|
description: "CLI tool for bootstrapping and managing Takumi projects",
|
|
8544
8544
|
type: "module",
|
|
8545
8545
|
repository: {
|
|
@@ -11227,7 +11227,7 @@ function normalizeTakumiConfigInput(value) {
|
|
|
11227
11227
|
}
|
|
11228
11228
|
return normalized;
|
|
11229
11229
|
}
|
|
11230
|
-
var PlanValidationModeSchema, PlanFocusAreaSchema, PlanResolutionOrderSchema, ProjectTypeSchema, PackageManagerSchema, FrameworkSchema, GEMINI_MODEL_VALUES, LEGACY_GEMINI_MODEL_ALIASES, GeminiModelSchema, StatuslineModeSchema, StatuslineSectionIdSchema, StatuslineSectionConfigSchema, StatuslineThemeSchema, StatuslineLayoutSchema, CodingLevelSchema, PlanResolutionSchema, PlanValidationSchema, SkPlanConfigSchema, SkDocsConfigSchema, SkPathsConfigSchema, SkLocaleConfigSchema, SkTrustConfigSchema, SkProjectConfigSchema, SkGeminiConfigSchema, SkSkillsConfigSchema, UpdatePipelineSchema, ResolvedModelConfigSchema, ModelTierMapSchema, SkModelTaxonomySchema, SkAssertionSchema, SkHooksConfigSchema, TakumiConfigSchema, DEFAULT_TAKUMI_CONFIG, TAKUMI_HOOK_NAMES;
|
|
11230
|
+
var PlanValidationModeSchema, PlanFocusAreaSchema, PlanResolutionOrderSchema, ProjectTypeSchema, PackageManagerSchema, FrameworkSchema, GEMINI_MODEL_VALUES, LEGACY_GEMINI_MODEL_ALIASES, GeminiModelSchema, StatuslineModeSchema, StatuslineSectionIdSchema, StatuslineSectionConfigSchema, StatuslineThemeSchema, StatuslineLayoutSchema, CodingLevelSchema, PlanResolutionSchema, PlanValidationSchema, SkPlanConfigSchema, SkDocsConfigSchema, SkPathsConfigSchema, SkLocaleConfigSchema, SkTrustConfigSchema, SkGraphifyConfigSchema, SkProjectConfigSchema, SkGeminiConfigSchema, SkSkillsConfigSchema, SkSkillExtensionsConfigSchema, UpdatePipelineSchema, ResolvedModelConfigSchema, ModelTierMapSchema, SkModelTaxonomySchema, SkAssertionSchema, SkHooksConfigSchema, TakumiConfigSchema, DEFAULT_TAKUMI_CONFIG, TAKUMI_HOOK_NAMES;
|
|
11231
11231
|
var init_takumi_config = __esm(() => {
|
|
11232
11232
|
init_zod();
|
|
11233
11233
|
PlanValidationModeSchema = exports_external.enum(["prompt", "auto", "strict", "none"]);
|
|
@@ -11349,6 +11349,9 @@ var init_takumi_config = __esm(() => {
|
|
|
11349
11349
|
passphrase: exports_external.string().nullable().optional(),
|
|
11350
11350
|
enabled: exports_external.boolean().optional()
|
|
11351
11351
|
});
|
|
11352
|
+
SkGraphifyConfigSchema = exports_external.object({
|
|
11353
|
+
enabled: exports_external.boolean().optional()
|
|
11354
|
+
});
|
|
11352
11355
|
SkProjectConfigSchema = exports_external.object({
|
|
11353
11356
|
type: ProjectTypeSchema.optional(),
|
|
11354
11357
|
packageManager: PackageManagerSchema.optional(),
|
|
@@ -11362,6 +11365,9 @@ var init_takumi_config = __esm(() => {
|
|
|
11362
11365
|
useGemini: exports_external.boolean().optional()
|
|
11363
11366
|
}).passthrough().optional()
|
|
11364
11367
|
}).passthrough();
|
|
11368
|
+
SkSkillExtensionsConfigSchema = exports_external.object({
|
|
11369
|
+
sharedDir: exports_external.string().optional()
|
|
11370
|
+
}).passthrough();
|
|
11365
11371
|
UpdatePipelineSchema = exports_external.object({
|
|
11366
11372
|
autoInitAfterUpdate: exports_external.boolean().default(false)
|
|
11367
11373
|
});
|
|
@@ -11404,9 +11410,11 @@ var init_takumi_config = __esm(() => {
|
|
|
11404
11410
|
paths: SkPathsConfigSchema.optional(),
|
|
11405
11411
|
locale: SkLocaleConfigSchema.optional(),
|
|
11406
11412
|
trust: SkTrustConfigSchema.optional(),
|
|
11413
|
+
graphify: SkGraphifyConfigSchema.optional(),
|
|
11407
11414
|
project: SkProjectConfigSchema.optional(),
|
|
11408
11415
|
gemini: SkGeminiConfigSchema.optional(),
|
|
11409
11416
|
skills: SkSkillsConfigSchema.optional(),
|
|
11417
|
+
skillExtensions: SkSkillExtensionsConfigSchema.optional(),
|
|
11410
11418
|
assertions: exports_external.array(SkAssertionSchema).optional(),
|
|
11411
11419
|
hooks: SkHooksConfigSchema.optional(),
|
|
11412
11420
|
updatePipeline: UpdatePipelineSchema.optional(),
|
|
@@ -11450,6 +11458,9 @@ var init_takumi_config = __esm(() => {
|
|
|
11450
11458
|
passphrase: null,
|
|
11451
11459
|
enabled: false
|
|
11452
11460
|
},
|
|
11461
|
+
graphify: {
|
|
11462
|
+
enabled: true
|
|
11463
|
+
},
|
|
11453
11464
|
project: {
|
|
11454
11465
|
type: "auto",
|
|
11455
11466
|
packageManager: "auto",
|
|
@@ -11463,6 +11474,9 @@ var init_takumi_config = __esm(() => {
|
|
|
11463
11474
|
useGemini: true
|
|
11464
11475
|
}
|
|
11465
11476
|
},
|
|
11477
|
+
skillExtensions: {
|
|
11478
|
+
sharedDir: ""
|
|
11479
|
+
},
|
|
11466
11480
|
assertions: [],
|
|
11467
11481
|
hooks: {
|
|
11468
11482
|
"session-init": true,
|
|
@@ -13598,6 +13612,7 @@ function globalSetupToInfo(g2) {
|
|
|
13598
13612
|
};
|
|
13599
13613
|
}
|
|
13600
13614
|
async function getTakumiSetup(projectDir = process.cwd()) {
|
|
13615
|
+
const { getInstaller, listSupportedProviders } = await Promise.resolve().then(() => (init_registry(), exports_registry));
|
|
13601
13616
|
const globalResults = await Promise.all(listSupportedProviders().map(async (p) => {
|
|
13602
13617
|
const inst = getInstaller(p);
|
|
13603
13618
|
return inst ? await inst.detectGlobalSetup() : null;
|
|
@@ -13622,7 +13637,6 @@ async function getTakumiSetup(projectDir = process.cwd()) {
|
|
|
13622
13637
|
var import_fs_extra5;
|
|
13623
13638
|
var init_takumi_scanner = __esm(() => {
|
|
13624
13639
|
init_paths();
|
|
13625
|
-
init_registry();
|
|
13626
13640
|
init_skip_directories();
|
|
13627
13641
|
init_manifest_path_resolver();
|
|
13628
13642
|
import_fs_extra5 = __toESM(require_lib(), 1);
|
|
@@ -33539,10 +33553,16 @@ function mergeHooksObject(current, incoming) {
|
|
|
33539
33553
|
const merged = deduplicateMerge(existingHooks, incoming);
|
|
33540
33554
|
return { ...current, hooks: merged };
|
|
33541
33555
|
}
|
|
33556
|
+
function isMalformedHookCommand(command) {
|
|
33557
|
+
return /(\$HOME|\$\{HOME\}|\$CLAUDE_PROJECT_DIR|\$\{CLAUDE_PROJECT_DIR\}|%USERPROFILE%|%CLAUDE_PROJECT_DIR%)\/\//.test(command);
|
|
33558
|
+
}
|
|
33542
33559
|
function deduplicateMerge(existing, incoming) {
|
|
33543
33560
|
const merged = {};
|
|
33544
33561
|
for (const [event, groups] of Object.entries(existing)) {
|
|
33545
|
-
merged[event] = groups.map((g2) => ({
|
|
33562
|
+
merged[event] = groups.map((g2) => ({
|
|
33563
|
+
...g2,
|
|
33564
|
+
hooks: g2.hooks.filter((h2) => !isMalformedHookCommand(h2.command))
|
|
33565
|
+
}));
|
|
33546
33566
|
}
|
|
33547
33567
|
for (const [event, incomingGroups] of Object.entries(incoming)) {
|
|
33548
33568
|
const existingGroups = merged[event] ?? [];
|
|
@@ -33562,7 +33582,13 @@ function deduplicateMerge(existing, incoming) {
|
|
|
33562
33582
|
}
|
|
33563
33583
|
merged[event] = existingGroups;
|
|
33564
33584
|
}
|
|
33565
|
-
|
|
33585
|
+
const cleaned = {};
|
|
33586
|
+
for (const [event, groups] of Object.entries(merged)) {
|
|
33587
|
+
const nonEmpty = groups.filter((g2) => g2.hooks.length > 0);
|
|
33588
|
+
if (nonEmpty.length > 0)
|
|
33589
|
+
cleaned[event] = nonEmpty;
|
|
33590
|
+
}
|
|
33591
|
+
return cleaned;
|
|
33566
33592
|
}
|
|
33567
33593
|
var init_hooks_settings_merger = __esm(() => {
|
|
33568
33594
|
init_provider_registry();
|
|
@@ -33755,6 +33781,9 @@ function scrubHookEntry(entry, event, capabilities, pathRewrite) {
|
|
|
33755
33781
|
if (pathRewrite) {
|
|
33756
33782
|
scrubbed.command = rewriteCommandPath(scrubbed.command, pathRewrite);
|
|
33757
33783
|
}
|
|
33784
|
+
if (typeof scrubbed.timeout === "number" && scrubbed.timeout < MIN_CODEX_HOOK_TIMEOUT_SECONDS) {
|
|
33785
|
+
scrubbed.timeout = MIN_CODEX_HOOK_TIMEOUT_SECONDS;
|
|
33786
|
+
}
|
|
33758
33787
|
const eventCaps = capabilities.events[event];
|
|
33759
33788
|
if (eventCaps?.permissionDecisionValues) {
|
|
33760
33789
|
const allowed = new Set(eventCaps.permissionDecisionValues);
|
|
@@ -33773,14 +33802,17 @@ function rewriteCommandPath(command, pathRewrite) {
|
|
|
33773
33802
|
if (pathRewrite.commandSubstitutions && pathRewrite.commandSubstitutions.size > 0) {
|
|
33774
33803
|
const home4 = homedir12();
|
|
33775
33804
|
const homeForward = normalizeSlashes(home4);
|
|
33805
|
+
const projectDirForward = pathRewrite.projectDir != null ? normalizeSlashes(pathRewrite.projectDir) : null;
|
|
33806
|
+
const relFrom = (absForward, baseForward) => {
|
|
33807
|
+
if (absForward.startsWith(`${baseForward}/`))
|
|
33808
|
+
return absForward.slice(baseForward.length + 1);
|
|
33809
|
+
if (absForward === baseForward)
|
|
33810
|
+
return "";
|
|
33811
|
+
return null;
|
|
33812
|
+
};
|
|
33776
33813
|
for (const [originalAbsPath, wrapperAbsPath] of pathRewrite.commandSubstitutions) {
|
|
33777
33814
|
const originalAbsForward = normalizeSlashes(originalAbsPath);
|
|
33778
|
-
|
|
33779
|
-
if (originalAbsForward.startsWith(`${homeForward}/`)) {
|
|
33780
|
-
relFromHome = originalAbsForward.slice(homeForward.length + 1);
|
|
33781
|
-
} else if (originalAbsForward === homeForward) {
|
|
33782
|
-
relFromHome = "";
|
|
33783
|
-
}
|
|
33815
|
+
const relFromHome = relFrom(originalAbsForward, homeForward);
|
|
33784
33816
|
const candidates = [originalAbsForward, originalAbsPath];
|
|
33785
33817
|
if (relFromHome !== null && relFromHome !== "") {
|
|
33786
33818
|
candidates.push(`$HOME/${relFromHome}`);
|
|
@@ -33788,6 +33820,12 @@ function rewriteCommandPath(command, pathRewrite) {
|
|
|
33788
33820
|
candidates.push(`%USERPROFILE%/${relFromHome}`);
|
|
33789
33821
|
candidates.push(`\${HOME}/${relFromHome}`);
|
|
33790
33822
|
}
|
|
33823
|
+
const relFromProject = projectDirForward !== null ? relFrom(originalAbsForward, projectDirForward) : null;
|
|
33824
|
+
if (relFromProject !== null && relFromProject !== "") {
|
|
33825
|
+
candidates.push(`$CLAUDE_PROJECT_DIR/${relFromProject}`);
|
|
33826
|
+
candidates.push(`\${CLAUDE_PROJECT_DIR}/${relFromProject}`);
|
|
33827
|
+
candidates.push(`%CLAUDE_PROJECT_DIR%/${relFromProject}`);
|
|
33828
|
+
}
|
|
33791
33829
|
const wrapperForward = normalizeSlashes(wrapperAbsPath);
|
|
33792
33830
|
for (const candidate of candidates) {
|
|
33793
33831
|
const candidateNorm = normalizeSlashes(candidate);
|
|
@@ -33820,6 +33858,7 @@ function isRelativeCommandCandidate(candidate) {
|
|
|
33820
33858
|
function escapeRegExp(value) {
|
|
33821
33859
|
return value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
33822
33860
|
}
|
|
33861
|
+
var MIN_CODEX_HOOK_TIMEOUT_SECONDS = 10;
|
|
33823
33862
|
var init_claude_to_codex_hooks = () => {};
|
|
33824
33863
|
|
|
33825
33864
|
// src/domains/installers/codex/path-safety.ts
|
|
@@ -34371,7 +34410,8 @@ async function migrateCodexHooksSettings(options2) {
|
|
|
34371
34410
|
const wrapperPaths = [];
|
|
34372
34411
|
const commandSubstitutions = new Map;
|
|
34373
34412
|
if (targetHooksDir) {
|
|
34374
|
-
const
|
|
34413
|
+
const sourceHooksDirBase = isGlobal ? homedir14() : projectBase;
|
|
34414
|
+
const absSourceHooksDir = sourceHooksDir ? isAbsolute2(sourceHooksDir) ? sourceHooksDir : resolve12(sourceHooksDirBase, sourceHooksDir) : "";
|
|
34375
34415
|
const absTargetHooksDir = isAbsolute2(targetHooksDir) ? targetHooksDir : resolve12(projectBase, targetHooksDir);
|
|
34376
34416
|
const targetAbsolutePaths = installedHookAbsolutePaths && installedHookAbsolutePaths.length > 0 ? installedHookAbsolutePaths.filter(isCodexWrappableHookPath) : installedHookFiles.filter(isCodexWrappableHookPath).map((basenameOrPath) => basenameOrPath.includes("/") || basenameOrPath.includes("\\") ? basenameOrPath : join55(absTargetHooksDir, basenameOrPath));
|
|
34377
34417
|
const wrapperResults = generateCodexHookWrappers(targetAbsolutePaths, absTargetHooksDir, capabilities);
|
|
@@ -34395,7 +34435,8 @@ async function migrateCodexHooksSettings(options2) {
|
|
|
34395
34435
|
const converted = convertClaudeHooksToCodex(filtered, capabilities, {
|
|
34396
34436
|
sourceDir: sourceHooksDir,
|
|
34397
34437
|
targetDir: targetHooksDir || sourceHooksDir,
|
|
34398
|
-
commandSubstitutions: commandSubstitutions.size > 0 ? commandSubstitutions : undefined
|
|
34438
|
+
commandSubstitutions: commandSubstitutions.size > 0 ? commandSubstitutions : undefined,
|
|
34439
|
+
projectDir: isGlobal ? homedir14() : projectBase
|
|
34399
34440
|
});
|
|
34400
34441
|
let hooksRegistered = 0;
|
|
34401
34442
|
for (const groups of Object.values(converted)) {
|
|
@@ -34418,7 +34459,7 @@ async function migrateCodexHooksSettings(options2) {
|
|
|
34418
34459
|
}
|
|
34419
34460
|
let backupPath = null;
|
|
34420
34461
|
try {
|
|
34421
|
-
const mergeResult = await mergeHooksIntoSettings(resolvedTargetPath, converted);
|
|
34462
|
+
const mergeResult = await withCodexTargetLock2(resolvedTargetPath, () => mergeHooksIntoSettings(resolvedTargetPath, converted));
|
|
34422
34463
|
backupPath = mergeResult.backupPath;
|
|
34423
34464
|
} catch (err) {
|
|
34424
34465
|
return {
|
|
@@ -34436,7 +34477,13 @@ async function migrateCodexHooksSettings(options2) {
|
|
|
34436
34477
|
if (capabilities.requiresFeatureFlag) {
|
|
34437
34478
|
const configTomlPath = isGlobal ? join55(homedir14(), ".codex", "config.toml") : join55(projectBase, ".codex", "config.toml");
|
|
34438
34479
|
const flagResult = await ensureCodexHooksFeatureFlag(configTomlPath, isGlobal);
|
|
34439
|
-
featureFlagWritten = flagResult.status === "written" || flagResult.status === "updated";
|
|
34480
|
+
featureFlagWritten = flagResult.status === "written" || flagResult.status === "updated" || flagResult.status === "already-set";
|
|
34481
|
+
if (flagResult.status === "failed") {
|
|
34482
|
+
warnings.push({
|
|
34483
|
+
reason: "codex-feature-flag-write-failed",
|
|
34484
|
+
message: `Could not write \`[features] hooks = true\` to ${configTomlPath}${flagResult.error ? ` (${flagResult.error})` : ""}. Codex will ignore installed hooks until this flag is set. Add it manually or re-run \`tkm init -a codex\`.`
|
|
34485
|
+
});
|
|
34486
|
+
}
|
|
34440
34487
|
}
|
|
34441
34488
|
return {
|
|
34442
34489
|
status: "registered",
|
|
@@ -34460,6 +34507,7 @@ var init_hooks_merger = __esm(() => {
|
|
|
34460
34507
|
init_claude_to_codex_hooks();
|
|
34461
34508
|
init_features_flag();
|
|
34462
34509
|
init_hook_wrapper();
|
|
34510
|
+
init_path_safety();
|
|
34463
34511
|
CODEX_WRAPPABLE_HOOK_EXTENSIONS = new Set([".js", ".cjs", ".mjs", ".ts"]);
|
|
34464
34512
|
});
|
|
34465
34513
|
|
|
@@ -35985,12 +36033,25 @@ var init_installer2 = __esm(() => {
|
|
|
35985
36033
|
});
|
|
35986
36034
|
|
|
35987
36035
|
// src/domains/installers/registry.ts
|
|
36036
|
+
var exports_registry = {};
|
|
36037
|
+
__export(exports_registry, {
|
|
36038
|
+
unregisterInstaller: () => unregisterInstaller,
|
|
36039
|
+
registerInstaller: () => registerInstaller,
|
|
36040
|
+
listSupportedProviders: () => listSupportedProviders,
|
|
36041
|
+
getInstaller: () => getInstaller
|
|
36042
|
+
});
|
|
35988
36043
|
function getInstaller(provider) {
|
|
35989
36044
|
return installers[provider] ?? null;
|
|
35990
36045
|
}
|
|
35991
36046
|
function listSupportedProviders() {
|
|
35992
36047
|
return Object.keys(installers);
|
|
35993
36048
|
}
|
|
36049
|
+
function registerInstaller(installer) {
|
|
36050
|
+
installers[installer.provider] = installer;
|
|
36051
|
+
}
|
|
36052
|
+
function unregisterInstaller(provider) {
|
|
36053
|
+
delete installers[provider];
|
|
36054
|
+
}
|
|
35994
36055
|
var installers;
|
|
35995
36056
|
var init_registry = __esm(() => {
|
|
35996
36057
|
init_installer();
|
|
@@ -37485,6 +37546,24 @@ var init_kit_version_checker = __esm(() => {
|
|
|
37485
37546
|
});
|
|
37486
37547
|
|
|
37487
37548
|
// src/domains/github/npm-registry.ts
|
|
37549
|
+
function validateRegistryUrl(url) {
|
|
37550
|
+
if (!url || typeof url !== "string" || url.trim() === "") {
|
|
37551
|
+
throw new Error("Invalid registry URL: must be a non-empty string");
|
|
37552
|
+
}
|
|
37553
|
+
if (SHELL_METACHARACTERS.test(url)) {
|
|
37554
|
+
throw new Error("Invalid registry URL: contains disallowed characters");
|
|
37555
|
+
}
|
|
37556
|
+
let parsed;
|
|
37557
|
+
try {
|
|
37558
|
+
parsed = new URL(url);
|
|
37559
|
+
} catch {
|
|
37560
|
+
throw new Error(`Invalid registry URL: not a valid URL (${redactRegistryUrlForLog(url)})`);
|
|
37561
|
+
}
|
|
37562
|
+
if (parsed.protocol !== "https:" && parsed.protocol !== "http:") {
|
|
37563
|
+
throw new Error(`Invalid registry URL: unsupported protocol ${parsed.protocol}`);
|
|
37564
|
+
}
|
|
37565
|
+
return url;
|
|
37566
|
+
}
|
|
37488
37567
|
function redactRegistryUrlForLog(url) {
|
|
37489
37568
|
if (!url)
|
|
37490
37569
|
return url;
|
|
@@ -37633,9 +37712,10 @@ class NpmRegistryClient {
|
|
|
37633
37712
|
}
|
|
37634
37713
|
}
|
|
37635
37714
|
}
|
|
37636
|
-
var DEFAULT_REGISTRY_URL = "https://registry.npmjs.org", REQUEST_TIMEOUT = 5000, REDACTED_VALUE = "***";
|
|
37715
|
+
var DEFAULT_REGISTRY_URL = "https://registry.npmjs.org", REQUEST_TIMEOUT = 5000, REDACTED_VALUE = "***", SHELL_METACHARACTERS;
|
|
37637
37716
|
var init_npm_registry = __esm(() => {
|
|
37638
37717
|
init_logger();
|
|
37718
|
+
SHELL_METACHARACTERS = /[\s;|&$`<>()'"\\\n\r]/;
|
|
37639
37719
|
});
|
|
37640
37720
|
|
|
37641
37721
|
// src/domains/versioning/checking/cli-version-checker.ts
|
|
@@ -50384,11 +50464,11 @@ var exports_monorepo_resolver = {};
|
|
|
50384
50464
|
__export(exports_monorepo_resolver, {
|
|
50385
50465
|
resolveMonorepoRoot: () => resolveMonorepoRoot
|
|
50386
50466
|
});
|
|
50387
|
-
import { existsSync as
|
|
50388
|
-
import { dirname as dirname27, join as
|
|
50467
|
+
import { existsSync as existsSync49, readFileSync as readFileSync16 } from "node:fs";
|
|
50468
|
+
import { dirname as dirname27, join as join99, resolve as resolve22 } from "node:path";
|
|
50389
50469
|
import { fileURLToPath as fileURLToPath3 } from "node:url";
|
|
50390
50470
|
function parseMetadataAt(metadataPath) {
|
|
50391
|
-
if (!
|
|
50471
|
+
if (!existsSync49(metadataPath))
|
|
50392
50472
|
return null;
|
|
50393
50473
|
try {
|
|
50394
50474
|
const raw = readFileSync16(metadataPath, "utf-8");
|
|
@@ -50402,8 +50482,8 @@ function parseMetadataAt(metadataPath) {
|
|
|
50402
50482
|
}
|
|
50403
50483
|
}
|
|
50404
50484
|
function readSourceDirFromPackageJson(candidateRoot) {
|
|
50405
|
-
const packageJsonPath =
|
|
50406
|
-
if (!
|
|
50485
|
+
const packageJsonPath = join99(candidateRoot, "package.json");
|
|
50486
|
+
if (!existsSync49(packageJsonPath))
|
|
50407
50487
|
return null;
|
|
50408
50488
|
try {
|
|
50409
50489
|
const parsed = JSON.parse(readFileSync16(packageJsonPath, "utf-8"));
|
|
@@ -50425,7 +50505,7 @@ function tryReadAtCandidate(candidateRoot) {
|
|
|
50425
50505
|
};
|
|
50426
50506
|
}
|
|
50427
50507
|
const sourceDir = readSourceDirFromPackageJson(candidateRoot) ?? "claude";
|
|
50428
|
-
const sourceRoot =
|
|
50508
|
+
const sourceRoot = join99(candidateRoot, sourceDir);
|
|
50429
50509
|
const nestedMetadata = parseMetadataAt(getManifestPath(sourceRoot)) ?? parseMetadataAt(getLegacyManifestPath(sourceRoot));
|
|
50430
50510
|
if (nestedMetadata) {
|
|
50431
50511
|
return {
|
|
@@ -57051,17 +57131,102 @@ async function checkHooksExist(projectDir) {
|
|
|
57051
57131
|
autoFixable: false
|
|
57052
57132
|
};
|
|
57053
57133
|
}
|
|
57054
|
-
// src/domains/health-checks/checkers/
|
|
57055
|
-
init_paths();
|
|
57134
|
+
// src/domains/health-checks/checkers/codex-hook-health-checker.ts
|
|
57056
57135
|
init_registry();
|
|
57057
|
-
init_logger();
|
|
57058
57136
|
import { existsSync as existsSync39 } from "node:fs";
|
|
57059
57137
|
import { readFile as readFile33 } from "node:fs/promises";
|
|
57060
57138
|
import { join as join78 } from "node:path";
|
|
57139
|
+
async function checkCodexHooksHealth() {
|
|
57140
|
+
const codex = getInstaller("codex");
|
|
57141
|
+
if (!codex?.isInstalledGlobally())
|
|
57142
|
+
return [];
|
|
57143
|
+
const codexRoot = codex.globalRoot();
|
|
57144
|
+
const configTomlPath = join78(codexRoot, "config.toml");
|
|
57145
|
+
const hooksJsonPath = join78(codexRoot, "hooks.json");
|
|
57146
|
+
if (!existsSync39(hooksJsonPath))
|
|
57147
|
+
return [];
|
|
57148
|
+
const results = [];
|
|
57149
|
+
const flagPresent = existsSync39(configTomlPath) ? /(^|\n)\s*hooks\s*=\s*true/.test(await readFile33(configTomlPath, "utf8")) : false;
|
|
57150
|
+
results.push(flagPresent ? {
|
|
57151
|
+
id: "codex-hooks-feature-flag",
|
|
57152
|
+
name: "Codex hooks feature flag",
|
|
57153
|
+
group: "takumi",
|
|
57154
|
+
priority: "critical",
|
|
57155
|
+
status: "pass",
|
|
57156
|
+
message: "[features] hooks = true present",
|
|
57157
|
+
details: configTomlPath,
|
|
57158
|
+
autoFixable: false
|
|
57159
|
+
} : {
|
|
57160
|
+
id: "codex-hooks-feature-flag",
|
|
57161
|
+
name: "Codex hooks feature flag",
|
|
57162
|
+
group: "takumi",
|
|
57163
|
+
priority: "critical",
|
|
57164
|
+
status: "fail",
|
|
57165
|
+
message: "[features] hooks = true missing — Codex ignores all hooks. Add it to config.toml or run `tkm init -a codex`.",
|
|
57166
|
+
details: configTomlPath,
|
|
57167
|
+
autoFixable: false
|
|
57168
|
+
});
|
|
57169
|
+
const missing = await collectMissingWrapperTargets(hooksJsonPath);
|
|
57170
|
+
results.push(missing.length === 0 ? {
|
|
57171
|
+
id: "codex-hooks-command-targets",
|
|
57172
|
+
name: "Codex hook command targets",
|
|
57173
|
+
group: "takumi",
|
|
57174
|
+
priority: "standard",
|
|
57175
|
+
status: "pass",
|
|
57176
|
+
message: "All hook commands point to existing wrappers",
|
|
57177
|
+
details: hooksJsonPath,
|
|
57178
|
+
autoFixable: false
|
|
57179
|
+
} : {
|
|
57180
|
+
id: "codex-hooks-command-targets",
|
|
57181
|
+
name: "Codex hook command targets",
|
|
57182
|
+
group: "takumi",
|
|
57183
|
+
priority: "standard",
|
|
57184
|
+
status: "fail",
|
|
57185
|
+
message: `${missing.length} hook command(s) point to a missing wrapper. Re-run \`tkm init -a codex\` to regenerate.`,
|
|
57186
|
+
details: missing.join(", "),
|
|
57187
|
+
autoFixable: false
|
|
57188
|
+
});
|
|
57189
|
+
return results;
|
|
57190
|
+
}
|
|
57191
|
+
async function collectMissingWrapperTargets(hooksJsonPath) {
|
|
57192
|
+
let parsed;
|
|
57193
|
+
try {
|
|
57194
|
+
parsed = JSON.parse(await readFile33(hooksJsonPath, "utf8"));
|
|
57195
|
+
} catch {
|
|
57196
|
+
return [];
|
|
57197
|
+
}
|
|
57198
|
+
const hooks = parsed?.hooks;
|
|
57199
|
+
if (!hooks || typeof hooks !== "object")
|
|
57200
|
+
return [];
|
|
57201
|
+
const missing = [];
|
|
57202
|
+
const nodeCmd = /\bnode\s+"([^"]+\.cjs)"/;
|
|
57203
|
+
for (const groups of Object.values(hooks)) {
|
|
57204
|
+
if (!Array.isArray(groups))
|
|
57205
|
+
continue;
|
|
57206
|
+
for (const group of groups) {
|
|
57207
|
+
for (const entry of group?.hooks ?? []) {
|
|
57208
|
+
const command = entry?.command;
|
|
57209
|
+
if (typeof command !== "string")
|
|
57210
|
+
continue;
|
|
57211
|
+
const m2 = command.match(nodeCmd);
|
|
57212
|
+
if (m2 && !existsSync39(m2[1]))
|
|
57213
|
+
missing.push(m2[1]);
|
|
57214
|
+
}
|
|
57215
|
+
}
|
|
57216
|
+
}
|
|
57217
|
+
return missing;
|
|
57218
|
+
}
|
|
57219
|
+
// src/domains/health-checks/checkers/settings-checker.ts
|
|
57220
|
+
init_paths();
|
|
57221
|
+
init_registry();
|
|
57222
|
+
init_logger();
|
|
57223
|
+
import { existsSync as existsSync40 } from "node:fs";
|
|
57224
|
+
import { readFile as readFile34 } from "node:fs/promises";
|
|
57225
|
+
import { join as join79 } from "node:path";
|
|
57061
57226
|
async function checkSettingsValid(projectDir) {
|
|
57062
|
-
const globalSettings =
|
|
57063
|
-
const projectSettings =
|
|
57064
|
-
const settingsPath =
|
|
57227
|
+
const globalSettings = join79(getInstaller("claude-code")?.globalRoot() ?? "", "settings.json");
|
|
57228
|
+
const projectSettings = join79(getLocalClaudeDir(projectDir), "settings.json");
|
|
57229
|
+
const settingsPath = existsSync40(globalSettings) ? globalSettings : existsSync40(projectSettings) ? projectSettings : null;
|
|
57065
57230
|
if (!settingsPath) {
|
|
57066
57231
|
return {
|
|
57067
57232
|
id: "sk-settings-valid",
|
|
@@ -57074,7 +57239,7 @@ async function checkSettingsValid(projectDir) {
|
|
|
57074
57239
|
};
|
|
57075
57240
|
}
|
|
57076
57241
|
try {
|
|
57077
|
-
const content = await
|
|
57242
|
+
const content = await readFile34(settingsPath, "utf-8");
|
|
57078
57243
|
JSON.parse(content);
|
|
57079
57244
|
return {
|
|
57080
57245
|
id: "sk-settings-valid",
|
|
@@ -57131,14 +57296,14 @@ async function checkSettingsValid(projectDir) {
|
|
|
57131
57296
|
init_paths();
|
|
57132
57297
|
init_registry();
|
|
57133
57298
|
init_logger();
|
|
57134
|
-
import { existsSync as
|
|
57135
|
-
import { readFile as
|
|
57299
|
+
import { existsSync as existsSync41 } from "node:fs";
|
|
57300
|
+
import { readFile as readFile35 } from "node:fs/promises";
|
|
57136
57301
|
import { homedir as homedir24 } from "node:os";
|
|
57137
|
-
import { dirname as dirname19, join as
|
|
57302
|
+
import { dirname as dirname19, join as join80, normalize as normalize6, resolve as resolve17 } from "node:path";
|
|
57138
57303
|
async function checkPathRefsValid(projectDir) {
|
|
57139
|
-
const globalClaudeMd =
|
|
57140
|
-
const projectClaudeMd =
|
|
57141
|
-
const claudeMdPath =
|
|
57304
|
+
const globalClaudeMd = join80(getInstaller("claude-code")?.globalRoot() ?? "", "CLAUDE.md");
|
|
57305
|
+
const projectClaudeMd = join80(getLocalClaudeDir(projectDir), "CLAUDE.md");
|
|
57306
|
+
const claudeMdPath = existsSync41(globalClaudeMd) ? globalClaudeMd : existsSync41(projectClaudeMd) ? projectClaudeMd : null;
|
|
57142
57307
|
if (!claudeMdPath) {
|
|
57143
57308
|
return {
|
|
57144
57309
|
id: "sk-path-refs-valid",
|
|
@@ -57151,7 +57316,7 @@ async function checkPathRefsValid(projectDir) {
|
|
|
57151
57316
|
};
|
|
57152
57317
|
}
|
|
57153
57318
|
try {
|
|
57154
|
-
const content = await
|
|
57319
|
+
const content = await readFile35(claudeMdPath, "utf-8");
|
|
57155
57320
|
const refPattern = /@([^\s\)]+)/g;
|
|
57156
57321
|
const refs = [...content.matchAll(refPattern)].map((m2) => m2[1]);
|
|
57157
57322
|
if (refs.length === 0) {
|
|
@@ -57191,7 +57356,7 @@ async function checkPathRefsValid(projectDir) {
|
|
|
57191
57356
|
logger.verbose("Skipping potentially unsafe path reference", { ref, refPath });
|
|
57192
57357
|
continue;
|
|
57193
57358
|
}
|
|
57194
|
-
if (!
|
|
57359
|
+
if (!existsSync41(normalizedPath)) {
|
|
57195
57360
|
broken.push(ref);
|
|
57196
57361
|
}
|
|
57197
57362
|
}
|
|
@@ -57231,9 +57396,9 @@ async function checkPathRefsValid(projectDir) {
|
|
|
57231
57396
|
}
|
|
57232
57397
|
// src/domains/health-checks/checkers/config-completeness-checker.ts
|
|
57233
57398
|
init_paths();
|
|
57234
|
-
import { existsSync as
|
|
57399
|
+
import { existsSync as existsSync42 } from "node:fs";
|
|
57235
57400
|
import { readdir as readdir24 } from "node:fs/promises";
|
|
57236
|
-
import { join as
|
|
57401
|
+
import { join as join81 } from "node:path";
|
|
57237
57402
|
async function checkProjectConfigCompleteness(setup, projectDir) {
|
|
57238
57403
|
if (setup.globals.some((g2) => g2.path === setup.project.path)) {
|
|
57239
57404
|
return {
|
|
@@ -57250,12 +57415,12 @@ async function checkProjectConfigCompleteness(setup, projectDir) {
|
|
|
57250
57415
|
const requiredDirs = ["agents", "commands", "skills"];
|
|
57251
57416
|
const missingDirs = [];
|
|
57252
57417
|
for (const dir of requiredDirs) {
|
|
57253
|
-
const dirPath =
|
|
57254
|
-
if (!
|
|
57418
|
+
const dirPath = join81(projectClaudeDir, dir);
|
|
57419
|
+
if (!existsSync42(dirPath)) {
|
|
57255
57420
|
missingDirs.push(dir);
|
|
57256
57421
|
}
|
|
57257
57422
|
}
|
|
57258
|
-
const hasRulesOrWorkflows =
|
|
57423
|
+
const hasRulesOrWorkflows = existsSync42(join81(projectClaudeDir, "rules")) || existsSync42(join81(projectClaudeDir, "workflows"));
|
|
57259
57424
|
if (!hasRulesOrWorkflows) {
|
|
57260
57425
|
missingDirs.push("rules");
|
|
57261
57426
|
}
|
|
@@ -57335,6 +57500,8 @@ class TakumiChecker {
|
|
|
57335
57500
|
}
|
|
57336
57501
|
logger.verbose("TakumiChecker: Checking hooks directory");
|
|
57337
57502
|
results.push(await checkHooksExist(this.projectDir));
|
|
57503
|
+
logger.verbose("TakumiChecker: Checking Codex hook health");
|
|
57504
|
+
results.push(...await checkCodexHooksHealth());
|
|
57338
57505
|
logger.verbose("TakumiChecker: Checking settings.json validity");
|
|
57339
57506
|
results.push(await checkSettingsValid(this.projectDir));
|
|
57340
57507
|
logger.verbose("TakumiChecker: Checking path references");
|
|
@@ -57692,9 +57859,9 @@ import { platform as platform7 } from "node:os";
|
|
|
57692
57859
|
// src/domains/health-checks/platform/environment-checker.ts
|
|
57693
57860
|
init_registry();
|
|
57694
57861
|
init_environment();
|
|
57695
|
-
import { constants as constants2, access as access2, mkdir as mkdir19, readFile as
|
|
57862
|
+
import { constants as constants2, access as access2, mkdir as mkdir19, readFile as readFile36, unlink as unlink8, writeFile as writeFile24 } from "node:fs/promises";
|
|
57696
57863
|
import { arch as arch2, homedir as homedir25, platform as platform6 } from "node:os";
|
|
57697
|
-
import { join as
|
|
57864
|
+
import { join as join83, normalize as normalize7 } from "node:path";
|
|
57698
57865
|
function shouldSkipExpensiveOperations4() {
|
|
57699
57866
|
return shouldSkipExpensiveOperations();
|
|
57700
57867
|
}
|
|
@@ -57787,11 +57954,11 @@ async function checkGlobalDirAccess(provider) {
|
|
|
57787
57954
|
autoFixable: false
|
|
57788
57955
|
};
|
|
57789
57956
|
}
|
|
57790
|
-
const testFile =
|
|
57957
|
+
const testFile = join83(globalDir, ".sk-doctor-access-test");
|
|
57791
57958
|
try {
|
|
57792
57959
|
await mkdir19(globalDir, { recursive: true });
|
|
57793
57960
|
await writeFile24(testFile, "test", "utf-8");
|
|
57794
|
-
const content = await
|
|
57961
|
+
const content = await readFile36(testFile, "utf-8");
|
|
57795
57962
|
await unlink8(testFile);
|
|
57796
57963
|
if (content !== "test")
|
|
57797
57964
|
throw new Error("Read mismatch");
|
|
@@ -57865,7 +58032,7 @@ async function checkWSLBoundary() {
|
|
|
57865
58032
|
// src/domains/health-checks/platform/windows-checker.ts
|
|
57866
58033
|
init_registry();
|
|
57867
58034
|
import { mkdir as mkdir20, symlink as symlink2, unlink as unlink9, writeFile as writeFile25 } from "node:fs/promises";
|
|
57868
|
-
import { join as
|
|
58035
|
+
import { join as join84 } from "node:path";
|
|
57869
58036
|
async function checkLongPathSupport() {
|
|
57870
58037
|
if (shouldSkipExpensiveOperations4()) {
|
|
57871
58038
|
return {
|
|
@@ -57917,8 +58084,8 @@ async function checkSymlinkSupport() {
|
|
|
57917
58084
|
};
|
|
57918
58085
|
}
|
|
57919
58086
|
const testDir = getInstaller("claude-code")?.globalRoot() ?? "";
|
|
57920
|
-
const target =
|
|
57921
|
-
const link =
|
|
58087
|
+
const target = join84(testDir, ".sk-symlink-test-target");
|
|
58088
|
+
const link = join84(testDir, ".sk-symlink-test-link");
|
|
57922
58089
|
try {
|
|
57923
58090
|
await mkdir20(testDir, { recursive: true });
|
|
57924
58091
|
await writeFile25(target, "test", "utf-8");
|
|
@@ -58214,7 +58381,7 @@ class AutoHealer {
|
|
|
58214
58381
|
import { execSync as execSync4, spawnSync as spawnSync4 } from "node:child_process";
|
|
58215
58382
|
import { readFileSync as readFileSync11, unlinkSync as unlinkSync4, writeFileSync as writeFileSync6 } from "node:fs";
|
|
58216
58383
|
import { tmpdir as tmpdir2 } from "node:os";
|
|
58217
|
-
import { dirname as dirname20, join as
|
|
58384
|
+
import { dirname as dirname20, join as join85 } from "node:path";
|
|
58218
58385
|
import { fileURLToPath as fileURLToPath2 } from "node:url";
|
|
58219
58386
|
init_environment();
|
|
58220
58387
|
init_logger();
|
|
@@ -58222,7 +58389,7 @@ init_dist2();
|
|
|
58222
58389
|
function getCliVersion3() {
|
|
58223
58390
|
try {
|
|
58224
58391
|
const __dirname3 = dirname20(fileURLToPath2(import.meta.url));
|
|
58225
|
-
const pkgPath =
|
|
58392
|
+
const pkgPath = join85(__dirname3, "../../../package.json");
|
|
58226
58393
|
const pkg = JSON.parse(readFileSync11(pkgPath, "utf-8"));
|
|
58227
58394
|
return pkg.version || "unknown";
|
|
58228
58395
|
} catch (err) {
|
|
@@ -58361,7 +58528,7 @@ class ReportGenerator {
|
|
|
58361
58528
|
return null;
|
|
58362
58529
|
}
|
|
58363
58530
|
}
|
|
58364
|
-
const tmpFile =
|
|
58531
|
+
const tmpFile = join85(tmpdir2(), `sk-report-${Date.now()}.txt`);
|
|
58365
58532
|
writeFileSync6(tmpFile, report);
|
|
58366
58533
|
try {
|
|
58367
58534
|
const result = spawnSync4("gh", ["gist", "create", tmpFile, "--desc", "Takumi Diagnostic Report"], {
|
|
@@ -58674,7 +58841,7 @@ async function authedFetch(url, init) {
|
|
|
58674
58841
|
// src/commands/hooks/lib/detached-put.ts
|
|
58675
58842
|
import { spawn as spawn2 } from "node:child_process";
|
|
58676
58843
|
import { openSync as openSync4 } from "node:fs";
|
|
58677
|
-
import { dirname as dirname21, join as
|
|
58844
|
+
import { dirname as dirname21, join as join86 } from "node:path";
|
|
58678
58845
|
|
|
58679
58846
|
// src/commands/hooks/lib/hook-logger.ts
|
|
58680
58847
|
import { appendFileSync } from "node:fs";
|
|
@@ -58721,7 +58888,7 @@ function effectiveDetachMode(flags) {
|
|
|
58721
58888
|
return flags.noDetach ? "inline" : "detached";
|
|
58722
58889
|
}
|
|
58723
58890
|
function sessionDebugLogPath(sessionDir) {
|
|
58724
|
-
return
|
|
58891
|
+
return join86(sessionDir, DETACH_DEBUG_LOG_NAME);
|
|
58725
58892
|
}
|
|
58726
58893
|
var BUNFS_PREFIX = "/$bunfs/";
|
|
58727
58894
|
function resolveInvocationPrefix() {
|
|
@@ -58751,7 +58918,7 @@ function resolvePreloadScript(entryPath) {
|
|
|
58751
58918
|
try {
|
|
58752
58919
|
const srcDir = dirname21(entryPath);
|
|
58753
58920
|
const repoRoot = dirname21(srcDir);
|
|
58754
|
-
return
|
|
58921
|
+
return join86(repoRoot, "scripts", "preload-config-override.ts");
|
|
58755
58922
|
} catch {
|
|
58756
58923
|
return null;
|
|
58757
58924
|
}
|
|
@@ -58823,13 +58990,13 @@ import { promises as fs13 } from "node:fs";
|
|
|
58823
58990
|
|
|
58824
58991
|
// src/commands/hooks/lib/session-paths.ts
|
|
58825
58992
|
init_paths2();
|
|
58826
|
-
import { join as
|
|
58993
|
+
import { join as join88 } from "node:path";
|
|
58827
58994
|
|
|
58828
58995
|
// src/commands/hooks/lib/project-paths.ts
|
|
58829
58996
|
init_paths2();
|
|
58830
58997
|
import { createHash as createHash8 } from "node:crypto";
|
|
58831
58998
|
import { realpathSync as realpathSync2 } from "node:fs";
|
|
58832
|
-
import { basename as basename12, join as
|
|
58999
|
+
import { basename as basename12, join as join87 } from "node:path";
|
|
58833
59000
|
function encodeCwd(cwd2) {
|
|
58834
59001
|
const stripped = cwd2.replace(/^\/+/, "");
|
|
58835
59002
|
const sanitized = stripped.replace(/[^a-zA-Z0-9-]/g, "-");
|
|
@@ -58848,10 +59015,10 @@ function getProjectLabel(cwd2) {
|
|
|
58848
59015
|
return basename12(cwd2) || "";
|
|
58849
59016
|
}
|
|
58850
59017
|
function getProjectsRoot() {
|
|
58851
|
-
return
|
|
59018
|
+
return join87(getConfigDir(), "projects");
|
|
58852
59019
|
}
|
|
58853
59020
|
function getProjectDir(args) {
|
|
58854
|
-
return
|
|
59021
|
+
return join87(getProjectsRoot(), encodeCwd(args.cwd), args.agent);
|
|
58855
59022
|
}
|
|
58856
59023
|
|
|
58857
59024
|
// src/commands/hooks/lib/session-paths.ts
|
|
@@ -58863,25 +59030,25 @@ function safeSessionSegment(sessionId) {
|
|
|
58863
59030
|
return cleaned.length > 0 ? cleaned.slice(0, MAX_SESSION_ID_LEN) : null;
|
|
58864
59031
|
}
|
|
58865
59032
|
function getSessionsRoot() {
|
|
58866
|
-
return
|
|
59033
|
+
return join88(getConfigDir(), "sessions");
|
|
58867
59034
|
}
|
|
58868
59035
|
function getSessionDirV2(args) {
|
|
58869
59036
|
const segment = safeSessionSegment(args.sessionId);
|
|
58870
59037
|
if (!segment)
|
|
58871
59038
|
return null;
|
|
58872
|
-
return
|
|
59039
|
+
return join88(getProjectDir({ agent: args.agent, cwd: args.cwd }), "sessions", segment);
|
|
58873
59040
|
}
|
|
58874
59041
|
function getEventsFile(sessionDir) {
|
|
58875
|
-
return
|
|
59042
|
+
return join88(sessionDir, "events.jsonl");
|
|
58876
59043
|
}
|
|
58877
59044
|
function getSummaryFile(sessionDir) {
|
|
58878
|
-
return
|
|
59045
|
+
return join88(sessionDir, "summary.json");
|
|
58879
59046
|
}
|
|
58880
59047
|
function getLastPushFile(sessionDir) {
|
|
58881
|
-
return
|
|
59048
|
+
return join88(sessionDir, "last_push.txt");
|
|
58882
59049
|
}
|
|
58883
59050
|
function getMetaFile(sessionDir) {
|
|
58884
|
-
return
|
|
59051
|
+
return join88(sessionDir, "meta.json");
|
|
58885
59052
|
}
|
|
58886
59053
|
|
|
58887
59054
|
// src/commands/hooks/lib/throttle.ts
|
|
@@ -59499,9 +59666,9 @@ function resolveEndpoint() {
|
|
|
59499
59666
|
|
|
59500
59667
|
// src/commands/hooks/lib/manifest-versions.ts
|
|
59501
59668
|
init_manifest_path_resolver();
|
|
59502
|
-
import { existsSync as
|
|
59669
|
+
import { existsSync as existsSync44, readFileSync as readFileSync12 } from "node:fs";
|
|
59503
59670
|
import { homedir as homedir26 } from "node:os";
|
|
59504
|
-
import { dirname as dirname22, join as
|
|
59671
|
+
import { dirname as dirname22, join as join89, resolve as resolve18 } from "node:path";
|
|
59505
59672
|
var PROVIDER_DIRS = [".claude", ".codex"];
|
|
59506
59673
|
var MAX_WALK = 6;
|
|
59507
59674
|
function readManifestRaw(path10) {
|
|
@@ -59520,8 +59687,8 @@ function findManifest(cwd2) {
|
|
|
59520
59687
|
let dir = resolve18(cwd2);
|
|
59521
59688
|
for (let i = 0;i < MAX_WALK; i++) {
|
|
59522
59689
|
for (const provider of PROVIDER_DIRS) {
|
|
59523
|
-
const providerRoot =
|
|
59524
|
-
if (
|
|
59690
|
+
const providerRoot = join89(dir, provider);
|
|
59691
|
+
if (existsSync44(providerRoot)) {
|
|
59525
59692
|
const path10 = findManifestInProviderDir(providerRoot);
|
|
59526
59693
|
if (path10)
|
|
59527
59694
|
return path10;
|
|
@@ -59534,11 +59701,11 @@ function findManifest(cwd2) {
|
|
|
59534
59701
|
}
|
|
59535
59702
|
const pluginRoot = process.env.CLAUDE_PLUGIN_ROOT;
|
|
59536
59703
|
if (pluginRoot) {
|
|
59537
|
-
const pluginPath = findManifestInProviderDir(
|
|
59704
|
+
const pluginPath = findManifestInProviderDir(join89(pluginRoot, ".claude"));
|
|
59538
59705
|
if (pluginPath)
|
|
59539
59706
|
return pluginPath;
|
|
59540
59707
|
}
|
|
59541
|
-
const globalPath = findManifestInProviderDir(
|
|
59708
|
+
const globalPath = findManifestInProviderDir(join89(homedir26(), ".claude"));
|
|
59542
59709
|
if (globalPath)
|
|
59543
59710
|
return globalPath;
|
|
59544
59711
|
return null;
|
|
@@ -59653,8 +59820,8 @@ async function handleSessionEnd(agent, flags = {}) {
|
|
|
59653
59820
|
session_end_raw: data
|
|
59654
59821
|
};
|
|
59655
59822
|
const { promises: fs18 } = await import("node:fs");
|
|
59656
|
-
const { join:
|
|
59657
|
-
const target =
|
|
59823
|
+
const { join: join90 } = await import("node:path");
|
|
59824
|
+
const target = join90(sessionDir, "meta.json");
|
|
59658
59825
|
const tmp = `${target}.tmp`;
|
|
59659
59826
|
await fs18.writeFile(tmp, JSON.stringify(updated), "utf8");
|
|
59660
59827
|
await fs18.rename(tmp, target);
|
|
@@ -59725,7 +59892,7 @@ init_auth_client();
|
|
|
59725
59892
|
|
|
59726
59893
|
// src/commands/hooks/lib/retention.ts
|
|
59727
59894
|
import { promises as fs18 } from "node:fs";
|
|
59728
|
-
import { join as
|
|
59895
|
+
import { join as join90 } from "node:path";
|
|
59729
59896
|
async function hasLastPush(dir) {
|
|
59730
59897
|
try {
|
|
59731
59898
|
await fs18.access(getLastPushFile(dir));
|
|
@@ -59755,7 +59922,7 @@ async function decideDelete(dir, args) {
|
|
|
59755
59922
|
async function listChildren(dir) {
|
|
59756
59923
|
try {
|
|
59757
59924
|
const names = await fs18.readdir(dir);
|
|
59758
|
-
return names.map((n) =>
|
|
59925
|
+
return names.map((n) => join90(dir, n));
|
|
59759
59926
|
} catch {
|
|
59760
59927
|
return [];
|
|
59761
59928
|
}
|
|
@@ -59766,7 +59933,7 @@ async function collectV2Sessions() {
|
|
|
59766
59933
|
const sessions = [];
|
|
59767
59934
|
for (const projectDir of projects) {
|
|
59768
59935
|
for (const agentDir of await listChildren(projectDir)) {
|
|
59769
|
-
for (const sessionDir of await listChildren(
|
|
59936
|
+
for (const sessionDir of await listChildren(join90(agentDir, "sessions"))) {
|
|
59770
59937
|
sessions.push(sessionDir);
|
|
59771
59938
|
}
|
|
59772
59939
|
}
|
|
@@ -60166,7 +60333,7 @@ init_hooks_settings_merger();
|
|
|
60166
60333
|
|
|
60167
60334
|
// src/commands/portable/settings-write-with-confirm.ts
|
|
60168
60335
|
init_safe_prompts();
|
|
60169
|
-
import { existsSync as
|
|
60336
|
+
import { existsSync as existsSync45, mkdirSync as mkdirSync4, readFileSync as readFileSync13, renameSync as renameSync2, rmSync as rmSync3, writeFileSync as writeFileSync7 } from "node:fs";
|
|
60170
60337
|
import { dirname as dirname23 } from "node:path";
|
|
60171
60338
|
|
|
60172
60339
|
// node_modules/diff/libesm/diff/base.js
|
|
@@ -61339,7 +61506,7 @@ var EMPTY_RESULT = (status2) => ({
|
|
|
61339
61506
|
backupPath: null
|
|
61340
61507
|
});
|
|
61341
61508
|
function readCurrent(path10) {
|
|
61342
|
-
if (!
|
|
61509
|
+
if (!existsSync45(path10))
|
|
61343
61510
|
return { kind: "missing" };
|
|
61344
61511
|
let raw = "";
|
|
61345
61512
|
try {
|
|
@@ -61456,18 +61623,18 @@ init_dist2();
|
|
|
61456
61623
|
// src/commands/hooks/lib/agent-target-picker.ts
|
|
61457
61624
|
init_safe_prompts();
|
|
61458
61625
|
init_dist2();
|
|
61459
|
-
import { existsSync as
|
|
61626
|
+
import { existsSync as existsSync46 } from "node:fs";
|
|
61460
61627
|
|
|
61461
61628
|
// src/commands/hooks/lib/settings-path-resolver.ts
|
|
61462
61629
|
import { lstatSync as lstatSync3, realpathSync as realpathSync3 } from "node:fs";
|
|
61463
61630
|
import { homedir as homedir27 } from "node:os";
|
|
61464
|
-
import { join as
|
|
61631
|
+
import { join as join91 } from "node:path";
|
|
61465
61632
|
function rawPath(agent, global3) {
|
|
61466
61633
|
const root = global3 ? homedir27() : process.cwd();
|
|
61467
61634
|
if (agent === "claude") {
|
|
61468
|
-
return
|
|
61635
|
+
return join91(root, ".claude", "settings.json");
|
|
61469
61636
|
}
|
|
61470
|
-
return
|
|
61637
|
+
return join91(root, ".codex", "hooks.json");
|
|
61471
61638
|
}
|
|
61472
61639
|
function resolveSettingsPath(agent, options2 = {}) {
|
|
61473
61640
|
const originalPath = rawPath(agent, Boolean(options2.global));
|
|
@@ -61495,7 +61662,7 @@ function probe(global3) {
|
|
|
61495
61662
|
return {
|
|
61496
61663
|
agent,
|
|
61497
61664
|
path: location2.realPath,
|
|
61498
|
-
exists:
|
|
61665
|
+
exists: existsSync46(location2.realPath)
|
|
61499
61666
|
};
|
|
61500
61667
|
});
|
|
61501
61668
|
}
|
|
@@ -61540,7 +61707,7 @@ async function promptHookAgentTargets(options2) {
|
|
|
61540
61707
|
|
|
61541
61708
|
// src/commands/hooks/lib/entry-builder.ts
|
|
61542
61709
|
init_capabilities();
|
|
61543
|
-
var TIMEOUT_SECONDS =
|
|
61710
|
+
var TIMEOUT_SECONDS = 10;
|
|
61544
61711
|
var DEFAULT_HOOK_BIN = "tkm";
|
|
61545
61712
|
var CLAUDE_SESSION_START_MATCHER = "startup|resume|clear|compact";
|
|
61546
61713
|
var HOOK_EVENT_TO_CLAUDE_EVENT = {
|
|
@@ -61610,7 +61777,7 @@ function buildHookSection(agent, bin, flags = {}) {
|
|
|
61610
61777
|
|
|
61611
61778
|
// src/commands/hooks/uninstall-handler.ts
|
|
61612
61779
|
init_logger();
|
|
61613
|
-
import { existsSync as
|
|
61780
|
+
import { existsSync as existsSync47, mkdirSync as mkdirSync5, readFileSync as readFileSync14, renameSync as renameSync3, rmSync as rmSync4, writeFileSync as writeFileSync8 } from "node:fs";
|
|
61614
61781
|
import { dirname as dirname24 } from "node:path";
|
|
61615
61782
|
var AGENT_DISPLAY2 = {
|
|
61616
61783
|
claude: "Claude Code",
|
|
@@ -61665,7 +61832,7 @@ async function uninstallForAgent(agent, options2) {
|
|
|
61665
61832
|
removed: 0,
|
|
61666
61833
|
dryRun: Boolean(options2.dryRun)
|
|
61667
61834
|
};
|
|
61668
|
-
if (!
|
|
61835
|
+
if (!existsSync47(location2.realPath)) {
|
|
61669
61836
|
return result;
|
|
61670
61837
|
}
|
|
61671
61838
|
let parsed;
|
|
@@ -63219,7 +63386,7 @@ init_logger();
|
|
|
63219
63386
|
init_safe_spinner();
|
|
63220
63387
|
import { mkdir as mkdir25, stat as stat10 } from "node:fs/promises";
|
|
63221
63388
|
import { tmpdir as tmpdir3 } from "node:os";
|
|
63222
|
-
import { join as
|
|
63389
|
+
import { join as join97 } from "node:path";
|
|
63223
63390
|
|
|
63224
63391
|
// src/shared/temp-cleanup.ts
|
|
63225
63392
|
init_logger();
|
|
@@ -63238,7 +63405,7 @@ init_logger();
|
|
|
63238
63405
|
init_output_manager();
|
|
63239
63406
|
import { createWriteStream as createWriteStream2, rmSync as rmSync5 } from "node:fs";
|
|
63240
63407
|
import { mkdir as mkdir21 } from "node:fs/promises";
|
|
63241
|
-
import { join as
|
|
63408
|
+
import { join as join92 } from "node:path";
|
|
63242
63409
|
|
|
63243
63410
|
// src/shared/progress-bar.ts
|
|
63244
63411
|
init_output_manager();
|
|
@@ -63448,7 +63615,7 @@ var MAX_DOWNLOAD_SIZE = 500 * 1024 * 1024;
|
|
|
63448
63615
|
class FileDownloader {
|
|
63449
63616
|
async downloadAsset(asset, destDir) {
|
|
63450
63617
|
try {
|
|
63451
|
-
const destPath =
|
|
63618
|
+
const destPath = join92(destDir, asset.name);
|
|
63452
63619
|
await mkdir21(destDir, { recursive: true });
|
|
63453
63620
|
output.info(`Downloading ${asset.name} (${formatBytes(asset.size)})...`);
|
|
63454
63621
|
logger.verbose("Download details", {
|
|
@@ -63533,7 +63700,7 @@ class FileDownloader {
|
|
|
63533
63700
|
}
|
|
63534
63701
|
async downloadFile(params) {
|
|
63535
63702
|
const { url, name, size, destDir, token } = params;
|
|
63536
|
-
const destPath =
|
|
63703
|
+
const destPath = join92(destDir, name);
|
|
63537
63704
|
await mkdir21(destDir, { recursive: true });
|
|
63538
63705
|
output.info(`Downloading ${name}${size ? ` (${formatBytes(size)})` : ""}...`);
|
|
63539
63706
|
const headers = {};
|
|
@@ -63636,7 +63803,7 @@ init_logger();
|
|
|
63636
63803
|
init_types2();
|
|
63637
63804
|
import { constants as constants3 } from "node:fs";
|
|
63638
63805
|
import { access as access3, readdir as readdir25 } from "node:fs/promises";
|
|
63639
|
-
import { join as
|
|
63806
|
+
import { join as join93 } from "node:path";
|
|
63640
63807
|
async function validateExtraction(extractDir) {
|
|
63641
63808
|
try {
|
|
63642
63809
|
const entries = await readdir25(extractDir, { encoding: "utf8" });
|
|
@@ -63648,7 +63815,7 @@ async function validateExtraction(extractDir) {
|
|
|
63648
63815
|
const missingPaths = [];
|
|
63649
63816
|
for (const path10 of criticalPaths) {
|
|
63650
63817
|
try {
|
|
63651
|
-
await access3(
|
|
63818
|
+
await access3(join93(extractDir, path10), constants3.F_OK);
|
|
63652
63819
|
logger.debug(`Found: ${path10}`);
|
|
63653
63820
|
} catch {
|
|
63654
63821
|
logger.warning(`Expected path not found: ${path10}`);
|
|
@@ -63670,7 +63837,7 @@ async function validateExtraction(extractDir) {
|
|
|
63670
63837
|
// src/domains/installation/extraction/tar-extractor.ts
|
|
63671
63838
|
init_logger();
|
|
63672
63839
|
import { copyFile as copyFile5, mkdir as mkdir23, readdir as readdir27, rm as rm7, stat as stat8 } from "node:fs/promises";
|
|
63673
|
-
import { join as
|
|
63840
|
+
import { join as join95 } from "node:path";
|
|
63674
63841
|
|
|
63675
63842
|
// node_modules/tar/dist/esm/index.min.js
|
|
63676
63843
|
import Kr from "events";
|
|
@@ -66883,7 +67050,7 @@ function decodeFilePath(path10) {
|
|
|
66883
67050
|
init_logger();
|
|
66884
67051
|
init_types2();
|
|
66885
67052
|
import { copyFile as copyFile4, lstat as lstat6, mkdir as mkdir22, readdir as readdir26 } from "node:fs/promises";
|
|
66886
|
-
import { join as
|
|
67053
|
+
import { join as join94, relative as relative15 } from "node:path";
|
|
66887
67054
|
async function withRetry2(fn2, retries = 3) {
|
|
66888
67055
|
for (let i = 0;i < retries; i++) {
|
|
66889
67056
|
try {
|
|
@@ -66905,8 +67072,8 @@ async function moveDirectoryContents(sourceDir, destDir, shouldExclude, sizeTrac
|
|
|
66905
67072
|
await mkdir22(destDir, { recursive: true });
|
|
66906
67073
|
const entries = await readdir26(sourceDir, { encoding: "utf8" });
|
|
66907
67074
|
for (const entry of entries) {
|
|
66908
|
-
const sourcePath =
|
|
66909
|
-
const destPath =
|
|
67075
|
+
const sourcePath = join94(sourceDir, entry);
|
|
67076
|
+
const destPath = join94(destDir, entry);
|
|
66910
67077
|
const relativePath = relative15(sourceDir, sourcePath);
|
|
66911
67078
|
if (!isPathSafe(destDir, destPath)) {
|
|
66912
67079
|
logger.warning(`Skipping unsafe path: ${relativePath}`);
|
|
@@ -66933,8 +67100,8 @@ async function copyDirectory(sourceDir, destDir, shouldExclude, sizeTracker) {
|
|
|
66933
67100
|
await mkdir22(destDir, { recursive: true });
|
|
66934
67101
|
const entries = await readdir26(sourceDir, { encoding: "utf8" });
|
|
66935
67102
|
for (const entry of entries) {
|
|
66936
|
-
const sourcePath =
|
|
66937
|
-
const destPath =
|
|
67103
|
+
const sourcePath = join94(sourceDir, entry);
|
|
67104
|
+
const destPath = join94(destDir, entry);
|
|
66938
67105
|
const relativePath = relative15(sourceDir, sourcePath);
|
|
66939
67106
|
if (!isPathSafe(destDir, destPath)) {
|
|
66940
67107
|
logger.warning(`Skipping unsafe path: ${relativePath}`);
|
|
@@ -66989,7 +67156,7 @@ class TarExtractor {
|
|
|
66989
67156
|
logger.debug(`Root entries: ${entries.join(", ")}`);
|
|
66990
67157
|
if (entries.length === 1) {
|
|
66991
67158
|
const rootEntry = entries[0];
|
|
66992
|
-
const rootPath =
|
|
67159
|
+
const rootPath = join95(tempExtractDir, rootEntry);
|
|
66993
67160
|
const rootStat = await stat8(rootPath);
|
|
66994
67161
|
if (rootStat.isDirectory()) {
|
|
66995
67162
|
const rootContents = await readdir27(rootPath, { encoding: "utf8" });
|
|
@@ -67005,7 +67172,7 @@ class TarExtractor {
|
|
|
67005
67172
|
}
|
|
67006
67173
|
} else {
|
|
67007
67174
|
await mkdir23(destDir, { recursive: true });
|
|
67008
|
-
await copyFile5(rootPath,
|
|
67175
|
+
await copyFile5(rootPath, join95(destDir, rootEntry));
|
|
67009
67176
|
}
|
|
67010
67177
|
} else {
|
|
67011
67178
|
logger.debug("Multiple root entries - moving all");
|
|
@@ -67026,7 +67193,7 @@ class TarExtractor {
|
|
|
67026
67193
|
init_logger();
|
|
67027
67194
|
import { createWriteStream as createWriteStream3 } from "node:fs";
|
|
67028
67195
|
import { chmod as chmod3, copyFile as copyFile6, mkdir as mkdir24, readdir as readdir28, rm as rm8, stat as stat9 } from "node:fs/promises";
|
|
67029
|
-
import { dirname as dirname25, join as
|
|
67196
|
+
import { dirname as dirname25, join as join96, resolve as resolve20 } from "node:path";
|
|
67030
67197
|
import { pipeline } from "node:stream/promises";
|
|
67031
67198
|
import yauzl from "yauzl-promise";
|
|
67032
67199
|
class ZipExtractor {
|
|
@@ -67040,7 +67207,7 @@ class ZipExtractor {
|
|
|
67040
67207
|
logger.debug(`Root entries: ${entries.join(", ")}`);
|
|
67041
67208
|
if (entries.length === 1) {
|
|
67042
67209
|
const rootEntry = entries[0];
|
|
67043
|
-
const rootPath =
|
|
67210
|
+
const rootPath = join96(tempExtractDir, rootEntry);
|
|
67044
67211
|
const rootStat = await stat9(rootPath);
|
|
67045
67212
|
if (rootStat.isDirectory()) {
|
|
67046
67213
|
const rootContents = await readdir28(rootPath, { encoding: "utf8" });
|
|
@@ -67056,7 +67223,7 @@ class ZipExtractor {
|
|
|
67056
67223
|
}
|
|
67057
67224
|
} else {
|
|
67058
67225
|
await mkdir24(destDir, { recursive: true });
|
|
67059
|
-
await copyFile6(rootPath,
|
|
67226
|
+
await copyFile6(rootPath, join96(destDir, rootEntry));
|
|
67060
67227
|
}
|
|
67061
67228
|
} else {
|
|
67062
67229
|
logger.debug("Multiple root entries - moving all");
|
|
@@ -67185,7 +67352,7 @@ class DownloadManager {
|
|
|
67185
67352
|
async createTempDir() {
|
|
67186
67353
|
const timestamp = Date.now();
|
|
67187
67354
|
const counter = DownloadManager.tempDirCounter++;
|
|
67188
|
-
const primaryTempDir =
|
|
67355
|
+
const primaryTempDir = join97(tmpdir3(), `takumi-${timestamp}-${counter}`);
|
|
67189
67356
|
try {
|
|
67190
67357
|
await mkdir25(primaryTempDir, { recursive: true });
|
|
67191
67358
|
logger.debug(`Created temp directory: ${primaryTempDir}`);
|
|
@@ -67202,7 +67369,7 @@ Solutions:
|
|
|
67202
67369
|
2. Set HOME environment variable
|
|
67203
67370
|
3. Try running from a different directory`);
|
|
67204
67371
|
}
|
|
67205
|
-
const fallbackTempDir =
|
|
67372
|
+
const fallbackTempDir = join97(homeDir, ".sunagentkit", "tmp", `takumi-${timestamp}-${counter}`);
|
|
67206
67373
|
try {
|
|
67207
67374
|
await mkdir25(fallbackTempDir, { recursive: true });
|
|
67208
67375
|
logger.debug(`Created temp directory (fallback): ${fallbackTempDir}`);
|
|
@@ -67908,7 +68075,7 @@ Re-run with explicit base kit, e.g. --kit ${BASE_KIT} --kit ${parsed2.join(" --k
|
|
|
67908
68075
|
}
|
|
67909
68076
|
// src/commands/init/phases/selection-handler.ts
|
|
67910
68077
|
import { mkdir as mkdir26 } from "node:fs/promises";
|
|
67911
|
-
import { join as
|
|
68078
|
+
import { join as join101, resolve as resolve24 } from "node:path";
|
|
67912
68079
|
|
|
67913
68080
|
// src/commands/shared/agent-selector.ts
|
|
67914
68081
|
init_registry();
|
|
@@ -68061,8 +68228,8 @@ init_logger();
|
|
|
68061
68228
|
init_safe_spinner();
|
|
68062
68229
|
init_takumi_constants();
|
|
68063
68230
|
var import_fs_extra31 = __toESM(require_lib(), 1);
|
|
68064
|
-
import { existsSync as
|
|
68065
|
-
import { dirname as dirname28, join as
|
|
68231
|
+
import { existsSync as existsSync50, readdirSync as readdirSync6, rmSync as rmSync6, rmdirSync as rmdirSync2, unlinkSync as unlinkSync5 } from "node:fs";
|
|
68232
|
+
import { dirname as dirname28, join as join100, resolve as resolve23 } from "node:path";
|
|
68066
68233
|
var TAKUMI_SUBDIRECTORIES = ["commands", "agents", "skills", "rules", "hooks"];
|
|
68067
68234
|
async function analyzeFreshInstallation(claudeDir) {
|
|
68068
68235
|
const metadata = await readManifest(claudeDir);
|
|
@@ -68132,9 +68299,9 @@ async function removeFilesByOwnership(claudeDir, analysis, includeModified) {
|
|
|
68132
68299
|
const filesToRemove = includeModified ? [...analysis.ckFiles, ...analysis.ckModifiedFiles] : analysis.ckFiles;
|
|
68133
68300
|
const filesToPreserve = includeModified ? analysis.userFiles : [...analysis.ckModifiedFiles, ...analysis.userFiles];
|
|
68134
68301
|
for (const file of filesToRemove) {
|
|
68135
|
-
const fullPath =
|
|
68302
|
+
const fullPath = join100(claudeDir, file.path);
|
|
68136
68303
|
try {
|
|
68137
|
-
if (
|
|
68304
|
+
if (existsSync50(fullPath)) {
|
|
68138
68305
|
unlinkSync5(fullPath);
|
|
68139
68306
|
removedFiles.push(file.path);
|
|
68140
68307
|
logger.debug(`Removed: ${file.path}`);
|
|
@@ -68206,7 +68373,7 @@ async function removeSubdirectoriesFallback(claudeDir) {
|
|
|
68206
68373
|
const removedFiles = [];
|
|
68207
68374
|
let removedDirCount = 0;
|
|
68208
68375
|
for (const subdir of TAKUMI_SUBDIRECTORIES) {
|
|
68209
|
-
const subdirPath =
|
|
68376
|
+
const subdirPath = join100(claudeDir, subdir);
|
|
68210
68377
|
if (await import_fs_extra31.pathExists(subdirPath)) {
|
|
68211
68378
|
rmSync6(subdirPath, { recursive: true, force: true });
|
|
68212
68379
|
removedDirCount++;
|
|
@@ -68431,7 +68598,7 @@ async function handleSelection(ctx) {
|
|
|
68431
68598
|
}
|
|
68432
68599
|
if (!ctx.options.fresh) {
|
|
68433
68600
|
const prefix = PathResolver.getPathPrefix(ctx.options.global);
|
|
68434
|
-
const claudeDir = prefix ?
|
|
68601
|
+
const claudeDir = prefix ? join101(resolvedDir, prefix) : resolvedDir;
|
|
68435
68602
|
try {
|
|
68436
68603
|
const existingMetadata = await readManifest(claudeDir);
|
|
68437
68604
|
if (existingMetadata?.kits) {
|
|
@@ -68464,7 +68631,7 @@ async function handleSelection(ctx) {
|
|
|
68464
68631
|
}
|
|
68465
68632
|
if (ctx.options.fresh) {
|
|
68466
68633
|
const prefix = PathResolver.getPathPrefix(ctx.options.global);
|
|
68467
|
-
const claudeDir = prefix ?
|
|
68634
|
+
const claudeDir = prefix ? join101(resolvedDir, prefix) : resolvedDir;
|
|
68468
68635
|
const canProceed = await handleFreshInstallation(claudeDir, ctx.prompts);
|
|
68469
68636
|
if (!canProceed) {
|
|
68470
68637
|
return { ...ctx, cancelled: true };
|
|
@@ -68484,7 +68651,7 @@ async function handleSelection(ctx) {
|
|
|
68484
68651
|
let currentVersion = null;
|
|
68485
68652
|
try {
|
|
68486
68653
|
const prefix = PathResolver.getPathPrefix(ctx.options.global);
|
|
68487
|
-
const claudeDir = prefix ?
|
|
68654
|
+
const claudeDir = prefix ? join101(resolvedDir, prefix) : resolvedDir;
|
|
68488
68655
|
const existingMetadata = await readManifest(claudeDir);
|
|
68489
68656
|
currentVersion = existingMetadata?.kits?.[kitType]?.version || null;
|
|
68490
68657
|
if (currentVersion) {
|
|
@@ -68572,7 +68739,7 @@ async function handleSelection(ctx) {
|
|
|
68572
68739
|
if (ctx.options.yes && !ctx.options.fresh && !ctx.options.force && releaseTag && !isOfflineMode) {
|
|
68573
68740
|
try {
|
|
68574
68741
|
const prefix = PathResolver.getPathPrefix(ctx.options.global);
|
|
68575
|
-
const claudeDir = prefix ?
|
|
68742
|
+
const claudeDir = prefix ? join101(resolvedDir, prefix) : resolvedDir;
|
|
68576
68743
|
const existingMetadata = await readManifest(claudeDir);
|
|
68577
68744
|
const installedKitVersion = existingMetadata?.kits?.[kitType]?.version;
|
|
68578
68745
|
if (installedKitVersion && versionsMatch(installedKitVersion, releaseTag)) {
|
|
@@ -68595,7 +68762,7 @@ async function handleSelection(ctx) {
|
|
|
68595
68762
|
let currentSecondaryVersion = null;
|
|
68596
68763
|
try {
|
|
68597
68764
|
const prefix = PathResolver.getPathPrefix(ctx.options.global);
|
|
68598
|
-
const claudeDir = prefix ?
|
|
68765
|
+
const claudeDir = prefix ? join101(resolvedDir, prefix) : resolvedDir;
|
|
68599
68766
|
const existingMetadata = await readManifest(claudeDir);
|
|
68600
68767
|
currentSecondaryVersion = existingMetadata?.kits?.[secondaryKit]?.version || null;
|
|
68601
68768
|
} catch {}
|
|
@@ -68678,13 +68845,13 @@ function resolveGlobalTargetDir(targetAgents2) {
|
|
|
68678
68845
|
}
|
|
68679
68846
|
// src/commands/init/phases/sync-handler.ts
|
|
68680
68847
|
init_paths();
|
|
68681
|
-
import { copyFile as copyFile7, mkdir as mkdir28, open as open2, readFile as
|
|
68682
|
-
import { dirname as dirname29, join as
|
|
68848
|
+
import { copyFile as copyFile7, mkdir as mkdir28, open as open2, readFile as readFile40, rename as rename7, stat as stat12, unlink as unlink11, writeFile as writeFile28 } from "node:fs/promises";
|
|
68849
|
+
import { dirname as dirname29, join as join104, resolve as resolve25 } from "node:path";
|
|
68683
68850
|
|
|
68684
68851
|
// src/domains/sync/config-version-checker.ts
|
|
68685
68852
|
init_auth_client();
|
|
68686
|
-
import { mkdir as mkdir27, readFile as
|
|
68687
|
-
import { join as
|
|
68853
|
+
import { mkdir as mkdir27, readFile as readFile38, unlink as unlink10, writeFile as writeFile27 } from "node:fs/promises";
|
|
68854
|
+
import { join as join102 } from "node:path";
|
|
68688
68855
|
init_version_utils();
|
|
68689
68856
|
init_logger();
|
|
68690
68857
|
init_path_resolver();
|
|
@@ -68720,12 +68887,12 @@ var CACHE_FILENAME = "config-update-cache.json";
|
|
|
68720
68887
|
class ConfigVersionChecker {
|
|
68721
68888
|
static getCacheFilePath(kitType, global3) {
|
|
68722
68889
|
const cacheDir = PathResolver.getCacheDir(global3);
|
|
68723
|
-
return
|
|
68890
|
+
return join102(cacheDir, `${kitType}-${CACHE_FILENAME}`);
|
|
68724
68891
|
}
|
|
68725
68892
|
static async loadCache(kitType, global3) {
|
|
68726
68893
|
try {
|
|
68727
68894
|
const cachePath = ConfigVersionChecker.getCacheFilePath(kitType, global3);
|
|
68728
|
-
const data = await
|
|
68895
|
+
const data = await readFile38(cachePath, "utf8");
|
|
68729
68896
|
const parsed = JSON.parse(data);
|
|
68730
68897
|
if (typeof parsed !== "object" || parsed === null || typeof parsed.lastCheck !== "number" || typeof parsed.latestVersion !== "string" || !parsed.latestVersion || parsed.lastCheck < 0 || parsed.lastCheck > Date.now() + 7 * 24 * 60 * 60 * 1000) {
|
|
68731
68898
|
logger.debug("Invalid cache structure, ignoring");
|
|
@@ -68839,8 +69006,8 @@ class ConfigVersionChecker {
|
|
|
68839
69006
|
// src/domains/sync/sync-engine.ts
|
|
68840
69007
|
init_ownership_checker();
|
|
68841
69008
|
init_logger();
|
|
68842
|
-
import { lstat as lstat7, readFile as
|
|
68843
|
-
import { isAbsolute as isAbsolute3, join as
|
|
69009
|
+
import { lstat as lstat7, readFile as readFile39, readlink, realpath as realpath3, stat as stat11 } from "node:fs/promises";
|
|
69010
|
+
import { isAbsolute as isAbsolute3, join as join103, normalize as normalize8, relative as relative16 } from "node:path";
|
|
68844
69011
|
var MAX_SYNC_FILE_SIZE = 10 * 1024 * 1024;
|
|
68845
69012
|
var MAX_SYMLINK_DEPTH = 20;
|
|
68846
69013
|
async function validateSymlinkChain(path11, basePath, maxDepth = MAX_SYMLINK_DEPTH) {
|
|
@@ -68852,7 +69019,7 @@ async function validateSymlinkChain(path11, basePath, maxDepth = MAX_SYMLINK_DEP
|
|
|
68852
69019
|
if (!stats.isSymbolicLink())
|
|
68853
69020
|
break;
|
|
68854
69021
|
const target = await readlink(current);
|
|
68855
|
-
const resolvedTarget = isAbsolute3(target) ? target :
|
|
69022
|
+
const resolvedTarget = isAbsolute3(target) ? target : join103(current, "..", target);
|
|
68856
69023
|
const normalizedTarget = normalize8(resolvedTarget);
|
|
68857
69024
|
const rel = relative16(basePath, normalizedTarget);
|
|
68858
69025
|
if (rel.startsWith("..") || isAbsolute3(rel)) {
|
|
@@ -68888,7 +69055,7 @@ async function validateSyncPath(basePath, filePath) {
|
|
|
68888
69055
|
if (normalized.startsWith("..") || normalized.includes("/../")) {
|
|
68889
69056
|
throw new Error(`Path traversal not allowed: ${filePath}`);
|
|
68890
69057
|
}
|
|
68891
|
-
const fullPath =
|
|
69058
|
+
const fullPath = join103(basePath, normalized);
|
|
68892
69059
|
const rel = relative16(basePath, fullPath);
|
|
68893
69060
|
if (rel.startsWith("..") || isAbsolute3(rel)) {
|
|
68894
69061
|
throw new Error(`Path escapes base directory: ${filePath}`);
|
|
@@ -68903,7 +69070,7 @@ async function validateSyncPath(basePath, filePath) {
|
|
|
68903
69070
|
}
|
|
68904
69071
|
} catch (error) {
|
|
68905
69072
|
if (error.code === "ENOENT") {
|
|
68906
|
-
const parentPath =
|
|
69073
|
+
const parentPath = join103(fullPath, "..");
|
|
68907
69074
|
try {
|
|
68908
69075
|
const resolvedBase = await realpath3(basePath);
|
|
68909
69076
|
const resolvedParent = await realpath3(parentPath);
|
|
@@ -69074,7 +69241,7 @@ class SyncEngine {
|
|
|
69074
69241
|
if (lstats.size > MAX_SYNC_FILE_SIZE) {
|
|
69075
69242
|
throw new Error(`File too large for sync (${Math.round(lstats.size / 1024 / 1024)}MB > ${MAX_SYNC_FILE_SIZE / 1024 / 1024}MB limit)`);
|
|
69076
69243
|
}
|
|
69077
|
-
const buffer = await
|
|
69244
|
+
const buffer = await readFile39(filePath);
|
|
69078
69245
|
if (buffer.includes(0)) {
|
|
69079
69246
|
return { content: "", isBinary: true };
|
|
69080
69247
|
}
|
|
@@ -69394,7 +69561,7 @@ function getLockTimeout() {
|
|
|
69394
69561
|
var STALE_LOCK_THRESHOLD_MS = 5 * 60 * 1000;
|
|
69395
69562
|
async function acquireSyncLock(global3) {
|
|
69396
69563
|
const cacheDir = PathResolver.getCacheDir(global3);
|
|
69397
|
-
const lockPath =
|
|
69564
|
+
const lockPath = join104(cacheDir, ".sync-lock");
|
|
69398
69565
|
const startTime = Date.now();
|
|
69399
69566
|
const lockTimeout = getLockTimeout();
|
|
69400
69567
|
await mkdir28(dirname29(lockPath), { recursive: true });
|
|
@@ -69445,7 +69612,7 @@ async function executeSyncMerge(ctx) {
|
|
|
69445
69612
|
try {
|
|
69446
69613
|
const sourceManifest = await findManifestPath(upstreamDir);
|
|
69447
69614
|
if (sourceManifest) {
|
|
69448
|
-
const content = await
|
|
69615
|
+
const content = await readFile40(sourceManifest.path, "utf-8");
|
|
69449
69616
|
const sourceMetadata = JSON.parse(content);
|
|
69450
69617
|
deletions = sourceMetadata.deletions || [];
|
|
69451
69618
|
}
|
|
@@ -69475,7 +69642,7 @@ async function executeSyncMerge(ctx) {
|
|
|
69475
69642
|
try {
|
|
69476
69643
|
const sourcePath = await validateSyncPath(upstreamDir, file.path);
|
|
69477
69644
|
const targetPath = await validateSyncPath(ctx.claudeDir, file.path);
|
|
69478
|
-
const targetDir =
|
|
69645
|
+
const targetDir = join104(targetPath, "..");
|
|
69479
69646
|
try {
|
|
69480
69647
|
await mkdir28(targetDir, { recursive: true });
|
|
69481
69648
|
} catch (mkdirError) {
|
|
@@ -69646,7 +69813,7 @@ async function createBackup(claudeDir, files, backupDir) {
|
|
|
69646
69813
|
const sourcePath = await validateSyncPath(claudeDir, file.path);
|
|
69647
69814
|
if (await import_fs_extra33.pathExists(sourcePath)) {
|
|
69648
69815
|
const targetPath = await validateSyncPath(backupDir, file.path);
|
|
69649
|
-
const targetDir =
|
|
69816
|
+
const targetDir = join104(targetPath, "..");
|
|
69650
69817
|
await mkdir28(targetDir, { recursive: true });
|
|
69651
69818
|
await copyFile7(sourcePath, targetPath);
|
|
69652
69819
|
}
|
|
@@ -69672,38 +69839,38 @@ init_logger();
|
|
|
69672
69839
|
init_types2();
|
|
69673
69840
|
var import_fs_extra34 = __toESM(require_lib(), 1);
|
|
69674
69841
|
import { rename as rename8, rm as rm9 } from "node:fs/promises";
|
|
69675
|
-
import { join as
|
|
69842
|
+
import { join as join105, relative as relative17 } from "node:path";
|
|
69676
69843
|
async function collectDirsToRename(extractDir, folders) {
|
|
69677
69844
|
const dirsToRename = [];
|
|
69678
69845
|
if (folders.docs !== DEFAULT_FOLDERS.docs) {
|
|
69679
|
-
const docsPath =
|
|
69846
|
+
const docsPath = join105(extractDir, DEFAULT_FOLDERS.docs);
|
|
69680
69847
|
if (await import_fs_extra34.pathExists(docsPath)) {
|
|
69681
69848
|
dirsToRename.push({
|
|
69682
69849
|
from: docsPath,
|
|
69683
|
-
to:
|
|
69850
|
+
to: join105(extractDir, folders.docs)
|
|
69684
69851
|
});
|
|
69685
69852
|
}
|
|
69686
|
-
const claudeDocsPath =
|
|
69853
|
+
const claudeDocsPath = join105(extractDir, ".claude", DEFAULT_FOLDERS.docs);
|
|
69687
69854
|
if (await import_fs_extra34.pathExists(claudeDocsPath)) {
|
|
69688
69855
|
dirsToRename.push({
|
|
69689
69856
|
from: claudeDocsPath,
|
|
69690
|
-
to:
|
|
69857
|
+
to: join105(extractDir, ".claude", folders.docs)
|
|
69691
69858
|
});
|
|
69692
69859
|
}
|
|
69693
69860
|
}
|
|
69694
69861
|
if (folders.plans !== DEFAULT_FOLDERS.plans) {
|
|
69695
|
-
const plansPath =
|
|
69862
|
+
const plansPath = join105(extractDir, DEFAULT_FOLDERS.plans);
|
|
69696
69863
|
if (await import_fs_extra34.pathExists(plansPath)) {
|
|
69697
69864
|
dirsToRename.push({
|
|
69698
69865
|
from: plansPath,
|
|
69699
|
-
to:
|
|
69866
|
+
to: join105(extractDir, folders.plans)
|
|
69700
69867
|
});
|
|
69701
69868
|
}
|
|
69702
|
-
const claudePlansPath =
|
|
69869
|
+
const claudePlansPath = join105(extractDir, ".claude", DEFAULT_FOLDERS.plans);
|
|
69703
69870
|
if (await import_fs_extra34.pathExists(claudePlansPath)) {
|
|
69704
69871
|
dirsToRename.push({
|
|
69705
69872
|
from: claudePlansPath,
|
|
69706
|
-
to:
|
|
69873
|
+
to: join105(extractDir, ".claude", folders.plans)
|
|
69707
69874
|
});
|
|
69708
69875
|
}
|
|
69709
69876
|
}
|
|
@@ -69743,8 +69910,8 @@ async function renameFolders(dirsToRename, extractDir, options2) {
|
|
|
69743
69910
|
// src/services/transformers/folder-transform/path-replacer.ts
|
|
69744
69911
|
init_logger();
|
|
69745
69912
|
init_types2();
|
|
69746
|
-
import { readFile as
|
|
69747
|
-
import { join as
|
|
69913
|
+
import { readFile as readFile41, readdir as readdir29, writeFile as writeFile29 } from "node:fs/promises";
|
|
69914
|
+
import { join as join106, relative as relative18 } from "node:path";
|
|
69748
69915
|
var TRANSFORMABLE_FILE_PATTERNS = [
|
|
69749
69916
|
".md",
|
|
69750
69917
|
".txt",
|
|
@@ -69797,7 +69964,7 @@ async function transformFileContents(dir, compiledReplacements, options2) {
|
|
|
69797
69964
|
let replacementsCount = 0;
|
|
69798
69965
|
const entries = await readdir29(dir, { withFileTypes: true });
|
|
69799
69966
|
for (const entry of entries) {
|
|
69800
|
-
const fullPath =
|
|
69967
|
+
const fullPath = join106(dir, entry.name);
|
|
69801
69968
|
if (entry.isDirectory()) {
|
|
69802
69969
|
if (entry.name === "node_modules" || entry.name === ".git") {
|
|
69803
69970
|
continue;
|
|
@@ -69810,7 +69977,7 @@ async function transformFileContents(dir, compiledReplacements, options2) {
|
|
|
69810
69977
|
if (!shouldTransform)
|
|
69811
69978
|
continue;
|
|
69812
69979
|
try {
|
|
69813
|
-
const content = await
|
|
69980
|
+
const content = await readFile41(fullPath, "utf-8");
|
|
69814
69981
|
let newContent = content;
|
|
69815
69982
|
let changeCount = 0;
|
|
69816
69983
|
for (const { regex: regex2, replacement } of compiledReplacements) {
|
|
@@ -69932,11 +70099,11 @@ async function transformFolderPaths(extractDir, folders, options2 = {}) {
|
|
|
69932
70099
|
|
|
69933
70100
|
// src/services/transformers/global-path-transformer.ts
|
|
69934
70101
|
init_logger();
|
|
69935
|
-
import { readFile as
|
|
70102
|
+
import { readFile as readFile42, readdir as readdir30, writeFile as writeFile30 } from "node:fs/promises";
|
|
69936
70103
|
import { platform as platform9 } from "node:os";
|
|
69937
|
-
import { extname as extname6, join as
|
|
70104
|
+
import { extname as extname6, join as join107 } from "node:path";
|
|
69938
70105
|
var IS_WINDOWS3 = platform9() === "win32";
|
|
69939
|
-
var HOME_PREFIX =
|
|
70106
|
+
var HOME_PREFIX = "$HOME";
|
|
69940
70107
|
function getHomeDirPrefix() {
|
|
69941
70108
|
return HOME_PREFIX;
|
|
69942
70109
|
}
|
|
@@ -69959,24 +70126,14 @@ function transformContent(content) {
|
|
|
69959
70126
|
let transformed = content;
|
|
69960
70127
|
const homePrefix = getHomeDirPrefix();
|
|
69961
70128
|
const claudePath = `${homePrefix}/.claude/`;
|
|
69962
|
-
|
|
69963
|
-
|
|
69964
|
-
|
|
69965
|
-
|
|
69966
|
-
|
|
69967
|
-
|
|
69968
|
-
|
|
69969
|
-
|
|
69970
|
-
});
|
|
69971
|
-
transformed = transformed.replace(/\$HOME(?=\/|\\)/g, () => {
|
|
69972
|
-
changes++;
|
|
69973
|
-
return homePrefix;
|
|
69974
|
-
});
|
|
69975
|
-
transformed = transformed.replace(/\$\{HOME\}(?=\/|\\)/g, () => {
|
|
69976
|
-
changes++;
|
|
69977
|
-
return homePrefix;
|
|
69978
|
-
});
|
|
69979
|
-
}
|
|
70129
|
+
transformed = transformed.replace(/%USERPROFILE%\/\.claude\//g, () => {
|
|
70130
|
+
changes++;
|
|
70131
|
+
return claudePath;
|
|
70132
|
+
});
|
|
70133
|
+
transformed = transformed.replace(/%USERPROFILE%(?=\/|\\)/g, () => {
|
|
70134
|
+
changes++;
|
|
70135
|
+
return homePrefix;
|
|
70136
|
+
});
|
|
69980
70137
|
transformed = transformed.replace(/\$CLAUDE_PROJECT_DIR\/\.claude\//g, () => {
|
|
69981
70138
|
changes++;
|
|
69982
70139
|
return claudePath;
|
|
@@ -69989,12 +70146,10 @@ function transformContent(content) {
|
|
|
69989
70146
|
changes++;
|
|
69990
70147
|
return claudePath;
|
|
69991
70148
|
});
|
|
69992
|
-
|
|
69993
|
-
|
|
69994
|
-
|
|
69995
|
-
|
|
69996
|
-
});
|
|
69997
|
-
}
|
|
70149
|
+
transformed = transformed.replace(/%CLAUDE_PROJECT_DIR%\/\.claude\//g, () => {
|
|
70150
|
+
changes++;
|
|
70151
|
+
return claudePath;
|
|
70152
|
+
});
|
|
69998
70153
|
transformed = transformed.replace(/\.\/\.claude\//g, () => {
|
|
69999
70154
|
changes++;
|
|
70000
70155
|
return claudePath;
|
|
@@ -70046,7 +70201,7 @@ async function transformPathsForGlobalInstall(directory, options2 = {}) {
|
|
|
70046
70201
|
async function processDirectory2(dir) {
|
|
70047
70202
|
const entries = await readdir30(dir, { withFileTypes: true });
|
|
70048
70203
|
for (const entry of entries) {
|
|
70049
|
-
const fullPath =
|
|
70204
|
+
const fullPath = join107(dir, entry.name);
|
|
70050
70205
|
if (entry.isDirectory()) {
|
|
70051
70206
|
if (entry.name === "node_modules" || entry.name.startsWith(".") && entry.name !== ".claude") {
|
|
70052
70207
|
continue;
|
|
@@ -70054,7 +70209,7 @@ async function transformPathsForGlobalInstall(directory, options2 = {}) {
|
|
|
70054
70209
|
await processDirectory2(fullPath);
|
|
70055
70210
|
} else if (entry.isFile() && shouldTransformFile3(entry.name)) {
|
|
70056
70211
|
try {
|
|
70057
|
-
const content = await
|
|
70212
|
+
const content = await readFile42(fullPath, "utf-8");
|
|
70058
70213
|
const { transformed, changes } = transformContent(content);
|
|
70059
70214
|
if (changes > 0) {
|
|
70060
70215
|
await writeFile30(fullPath, transformed, "utf-8");
|
|
@@ -70313,12 +70468,12 @@ async function initCommand(options2) {
|
|
|
70313
70468
|
}
|
|
70314
70469
|
// src/commands/plan/plan-command.ts
|
|
70315
70470
|
init_output_manager();
|
|
70316
|
-
import { existsSync as
|
|
70317
|
-
import { dirname as dirname35, join as
|
|
70471
|
+
import { existsSync as existsSync55, statSync as statSync7 } from "node:fs";
|
|
70472
|
+
import { dirname as dirname35, join as join111, parse as parse4, resolve as resolve29 } from "node:path";
|
|
70318
70473
|
|
|
70319
70474
|
// src/commands/plan/plan-read-handlers.ts
|
|
70320
|
-
import { existsSync as
|
|
70321
|
-
import { basename as basename15, dirname as dirname34, join as
|
|
70475
|
+
import { existsSync as existsSync54, statSync as statSync6 } from "node:fs";
|
|
70476
|
+
import { basename as basename15, dirname as dirname34, join as join110, relative as relative19, resolve as resolve27 } from "node:path";
|
|
70322
70477
|
|
|
70323
70478
|
// src/domains/plan-parser/index.ts
|
|
70324
70479
|
import { dirname as dirname33 } from "node:path";
|
|
@@ -70698,20 +70853,20 @@ function parsePlanFile(planFilePath, options2) {
|
|
|
70698
70853
|
return { frontmatter, phases };
|
|
70699
70854
|
}
|
|
70700
70855
|
// src/domains/plan-parser/plan-scanner.ts
|
|
70701
|
-
import { existsSync as
|
|
70702
|
-
import { join as
|
|
70856
|
+
import { existsSync as existsSync51, readdirSync as readdirSync7 } from "node:fs";
|
|
70857
|
+
import { join as join108 } from "node:path";
|
|
70703
70858
|
function scanPlanDir(dir) {
|
|
70704
|
-
if (!
|
|
70859
|
+
if (!existsSync51(dir))
|
|
70705
70860
|
return [];
|
|
70706
70861
|
try {
|
|
70707
|
-
return readdirSync7(dir, { withFileTypes: true }).filter((entry) => entry.isDirectory()).map((entry) =>
|
|
70862
|
+
return readdirSync7(dir, { withFileTypes: true }).filter((entry) => entry.isDirectory()).map((entry) => join108(dir, entry.name, "plan.md")).filter(existsSync51);
|
|
70708
70863
|
} catch {
|
|
70709
70864
|
return [];
|
|
70710
70865
|
}
|
|
70711
70866
|
}
|
|
70712
70867
|
// src/domains/plan-parser/plan-validator.ts
|
|
70713
70868
|
var import_gray_matter6 = __toESM(require_gray_matter(), 1);
|
|
70714
|
-
import { existsSync as
|
|
70869
|
+
import { existsSync as existsSync52, readFileSync as readFileSync18 } from "node:fs";
|
|
70715
70870
|
import { basename as basename13, dirname as dirname31 } from "node:path";
|
|
70716
70871
|
function validatePlanFile(filePath, strict = false) {
|
|
70717
70872
|
const content = readFileSync18(filePath, "utf8");
|
|
@@ -70751,7 +70906,7 @@ function validatePlanFile(filePath, strict = false) {
|
|
|
70751
70906
|
});
|
|
70752
70907
|
}
|
|
70753
70908
|
for (const phase of phases) {
|
|
70754
|
-
if (phase.file && !
|
|
70909
|
+
if (phase.file && !existsSync52(phase.file)) {
|
|
70755
70910
|
const fileBasename = basename13(phase.file);
|
|
70756
70911
|
const refLine = lines.findIndex((l2) => l2.includes(fileBasename));
|
|
70757
70912
|
issues.push({
|
|
@@ -70772,8 +70927,8 @@ function validatePlanFile(filePath, strict = false) {
|
|
|
70772
70927
|
// src/domains/plan-parser/plan-writer.ts
|
|
70773
70928
|
var import_gray_matter7 = __toESM(require_gray_matter(), 1);
|
|
70774
70929
|
import { mkdirSync as mkdirSync6, readFileSync as readFileSync19, writeFileSync as writeFileSync9 } from "node:fs";
|
|
70775
|
-
import { existsSync as
|
|
70776
|
-
import { basename as basename14, dirname as dirname32, join as
|
|
70930
|
+
import { existsSync as existsSync53 } from "node:fs";
|
|
70931
|
+
import { basename as basename14, dirname as dirname32, join as join109 } from "node:path";
|
|
70777
70932
|
function phaseNameToFilename(id, name) {
|
|
70778
70933
|
const numMatch = /^(\d+)([a-z]*)$/i.exec(id);
|
|
70779
70934
|
const num3 = numMatch ? numMatch[1] : id;
|
|
@@ -70881,12 +71036,12 @@ function scaffoldPlan(options2) {
|
|
|
70881
71036
|
mkdirSync6(dir, { recursive: true });
|
|
70882
71037
|
const resolvedPhases = resolvePhaseIds(options2.phases);
|
|
70883
71038
|
const optionsWithResolved = { ...options2, phases: resolvedPhases };
|
|
70884
|
-
const planFile =
|
|
71039
|
+
const planFile = join109(dir, "plan.md");
|
|
70885
71040
|
writeFileSync9(planFile, generatePlanMd(optionsWithResolved), "utf8");
|
|
70886
71041
|
const phaseFiles = [];
|
|
70887
71042
|
for (const phase of resolvedPhases) {
|
|
70888
71043
|
const filename = phaseNameToFilename(phase.id, phase.name);
|
|
70889
|
-
const phaseFile =
|
|
71044
|
+
const phaseFile = join109(dir, filename);
|
|
70890
71045
|
writeFileSync9(phaseFile, generatePhaseTemplate(phase), "utf8");
|
|
70891
71046
|
phaseFiles.push(phaseFile);
|
|
70892
71047
|
}
|
|
@@ -70954,7 +71109,7 @@ function updatePhaseStatus(planFile, phaseId, newStatus) {
|
|
|
70954
71109
|
writeFileSync9(planFile, updatedContent, "utf8");
|
|
70955
71110
|
const planDir = dirname32(planFile);
|
|
70956
71111
|
const phaseFilename = phaseNameFilenameFromTableRow(updatedBody, phaseId, planDir);
|
|
70957
|
-
if (phaseFilename &&
|
|
71112
|
+
if (phaseFilename && existsSync53(phaseFilename)) {
|
|
70958
71113
|
updatePhaseFileFrontmatter(phaseFilename, newStatus);
|
|
70959
71114
|
}
|
|
70960
71115
|
}
|
|
@@ -70966,7 +71121,7 @@ function phaseNameFilenameFromTableRow(body, phaseId, planDir) {
|
|
|
70966
71121
|
continue;
|
|
70967
71122
|
const linkMatch = /\[([^\]]+)\]\(\.\/([^)]+)\)/.exec(row);
|
|
70968
71123
|
if (linkMatch)
|
|
70969
|
-
return
|
|
71124
|
+
return join109(planDir, linkMatch[2]);
|
|
70970
71125
|
}
|
|
70971
71126
|
return null;
|
|
70972
71127
|
}
|
|
@@ -71047,7 +71202,7 @@ function addPhase(planFile, name, afterId) {
|
|
|
71047
71202
|
`);
|
|
71048
71203
|
}
|
|
71049
71204
|
writeFileSync9(planFile, import_gray_matter7.default.stringify(updatedBody, frontmatter), "utf8");
|
|
71050
|
-
const phaseFilePath =
|
|
71205
|
+
const phaseFilePath = join109(planDir, filename);
|
|
71051
71206
|
writeFileSync9(phaseFilePath, generatePhaseTemplate({ id: phaseId, name }), "utf8");
|
|
71052
71207
|
return { phaseId, phaseFile: phaseFilePath };
|
|
71053
71208
|
}
|
|
@@ -71151,7 +71306,7 @@ async function handleValidate(target, options2) {
|
|
|
71151
71306
|
}
|
|
71152
71307
|
async function handleStatus(target, options2) {
|
|
71153
71308
|
const t = target ? resolve27(target) : null;
|
|
71154
|
-
const plansDir = t &&
|
|
71309
|
+
const plansDir = t && existsSync54(t) && statSync6(t).isDirectory() && !existsSync54(join110(t, "plan.md")) ? t : null;
|
|
71155
71310
|
if (plansDir) {
|
|
71156
71311
|
const planFiles = scanPlanDir(plansDir);
|
|
71157
71312
|
if (planFiles.length === 0) {
|
|
@@ -71382,20 +71537,20 @@ async function handleAddPhase(target, options2) {
|
|
|
71382
71537
|
// src/commands/plan/plan-command.ts
|
|
71383
71538
|
function resolvePlanFile(target) {
|
|
71384
71539
|
const t = target ? resolve29(target) : process.cwd();
|
|
71385
|
-
if (
|
|
71540
|
+
if (existsSync55(t)) {
|
|
71386
71541
|
const stat13 = statSync7(t);
|
|
71387
71542
|
if (stat13.isFile())
|
|
71388
71543
|
return t;
|
|
71389
|
-
const candidate =
|
|
71390
|
-
if (
|
|
71544
|
+
const candidate = join111(t, "plan.md");
|
|
71545
|
+
if (existsSync55(candidate))
|
|
71391
71546
|
return candidate;
|
|
71392
71547
|
}
|
|
71393
71548
|
if (!target) {
|
|
71394
71549
|
let dir = process.cwd();
|
|
71395
71550
|
const root = parse4(dir).root;
|
|
71396
71551
|
while (dir !== root) {
|
|
71397
|
-
const candidate =
|
|
71398
|
-
if (
|
|
71552
|
+
const candidate = join111(dir, "plan.md");
|
|
71553
|
+
if (existsSync55(candidate))
|
|
71399
71554
|
return candidate;
|
|
71400
71555
|
dir = dirname35(dir);
|
|
71401
71556
|
}
|
|
@@ -71445,7 +71600,7 @@ async function planCommand(action, target, options2) {
|
|
|
71445
71600
|
let resolvedTarget = target;
|
|
71446
71601
|
if (resolvedAction && !knownActions.has(resolvedAction)) {
|
|
71447
71602
|
const looksLikePath = resolvedAction.includes("/") || resolvedAction.includes("\\") || resolvedAction.endsWith(".md") || resolvedAction === "." || resolvedAction === "..";
|
|
71448
|
-
const existsOnDisk = !looksLikePath &&
|
|
71603
|
+
const existsOnDisk = !looksLikePath && existsSync55(resolve29(resolvedAction));
|
|
71449
71604
|
if (looksLikePath || existsOnDisk) {
|
|
71450
71605
|
resolvedTarget = resolvedAction;
|
|
71451
71606
|
resolvedAction = undefined;
|
|
@@ -71489,22 +71644,22 @@ init_logger();
|
|
|
71489
71644
|
init_logger();
|
|
71490
71645
|
|
|
71491
71646
|
// src/commands/telemetry/shared.ts
|
|
71492
|
-
import { existsSync as
|
|
71647
|
+
import { existsSync as existsSync56, readFileSync as readFileSync20, readdirSync as readdirSync8 } from "node:fs";
|
|
71493
71648
|
import { homedir as homedir28 } from "node:os";
|
|
71494
|
-
import { join as
|
|
71649
|
+
import { join as join112 } from "node:path";
|
|
71495
71650
|
init_token_store();
|
|
71496
71651
|
init_manifest_path_resolver();
|
|
71497
71652
|
init_takumi_constants();
|
|
71498
|
-
var USER_CACHE_PATH =
|
|
71499
|
-
var EVENT_BUFFER_DIR =
|
|
71500
|
-
var RATE_STATE_PATH =
|
|
71501
|
-
var TAKUMI_MANIFEST_PATH =
|
|
71502
|
-
var LEGACY_METADATA_PATH =
|
|
71653
|
+
var USER_CACHE_PATH = join112(homedir28(), ".claude", "sk-user.json");
|
|
71654
|
+
var EVENT_BUFFER_DIR = join112(homedir28(), ".claude", "sk-events");
|
|
71655
|
+
var RATE_STATE_PATH = join112(homedir28(), ".claude", "sk-rate-state.json");
|
|
71656
|
+
var TAKUMI_MANIFEST_PATH = join112(homedir28(), ".claude", MANIFEST_FILENAME);
|
|
71657
|
+
var LEGACY_METADATA_PATH = join112(homedir28(), ".claude", LEGACY_MANIFEST_FILENAME);
|
|
71503
71658
|
var TELEMETRY_HOOK_FIELD = "hooks.telemetry";
|
|
71504
71659
|
var TOKEN_PLACEHOLDER = "__INJECT_AT_RELEASE__";
|
|
71505
71660
|
function readUserCache() {
|
|
71506
71661
|
try {
|
|
71507
|
-
if (!
|
|
71662
|
+
if (!existsSync56(USER_CACHE_PATH))
|
|
71508
71663
|
return null;
|
|
71509
71664
|
const parsed = JSON.parse(readFileSync20(USER_CACHE_PATH, "utf8"));
|
|
71510
71665
|
if (!parsed || typeof parsed !== "object")
|
|
@@ -71516,7 +71671,7 @@ function readUserCache() {
|
|
|
71516
71671
|
}
|
|
71517
71672
|
function countBufferFiles() {
|
|
71518
71673
|
try {
|
|
71519
|
-
if (!
|
|
71674
|
+
if (!existsSync56(EVENT_BUFFER_DIR))
|
|
71520
71675
|
return 0;
|
|
71521
71676
|
return readdirSync8(EVENT_BUFFER_DIR).filter((f4) => f4.endsWith(".jsonl")).length;
|
|
71522
71677
|
} catch {
|
|
@@ -71528,7 +71683,7 @@ function readTelemetryConfig() {
|
|
|
71528
71683
|
const envToken = process.env.TAKUMI_TELEMETRY_TOKEN;
|
|
71529
71684
|
let metadata = null;
|
|
71530
71685
|
try {
|
|
71531
|
-
const resolved = findManifestPathSync(
|
|
71686
|
+
const resolved = findManifestPathSync(join112(homedir28(), ".claude"));
|
|
71532
71687
|
if (resolved) {
|
|
71533
71688
|
metadata = JSON.parse(readFileSync20(resolved.path, "utf8"));
|
|
71534
71689
|
}
|
|
@@ -71554,8 +71709,8 @@ function collectRuntimeContext() {
|
|
|
71554
71709
|
cacheSource: cache2?.source === "gh" || cache2?.source === "manual" ? cache2.source : null,
|
|
71555
71710
|
bufferFileCount: countBufferFiles(),
|
|
71556
71711
|
bufferDir: EVENT_BUFFER_DIR,
|
|
71557
|
-
rateStateExists:
|
|
71558
|
-
userCacheExists:
|
|
71712
|
+
rateStateExists: existsSync56(RATE_STATE_PATH),
|
|
71713
|
+
userCacheExists: existsSync56(USER_CACHE_PATH),
|
|
71559
71714
|
endpoint,
|
|
71560
71715
|
tokenConfigured: Boolean(token)
|
|
71561
71716
|
};
|
|
@@ -71706,7 +71861,7 @@ init_safe_prompts();
|
|
|
71706
71861
|
init_safe_spinner();
|
|
71707
71862
|
var import_fs_extra36 = __toESM(require_lib(), 1);
|
|
71708
71863
|
import { readdirSync as readdirSync10, rmSync as rmSync8 } from "node:fs";
|
|
71709
|
-
import { join as
|
|
71864
|
+
import { join as join114, resolve as resolve30, sep as sep10 } from "node:path";
|
|
71710
71865
|
|
|
71711
71866
|
// src/commands/uninstall/analysis-handler.ts
|
|
71712
71867
|
init_metadata_migration();
|
|
@@ -71716,13 +71871,13 @@ init_logger();
|
|
|
71716
71871
|
init_safe_prompts();
|
|
71717
71872
|
init_takumi_constants();
|
|
71718
71873
|
var import_picocolors27 = __toESM(require_picocolors(), 1);
|
|
71719
|
-
import { existsSync as
|
|
71720
|
-
import { dirname as dirname36, join as
|
|
71874
|
+
import { existsSync as existsSync57, readdirSync as readdirSync9, rmSync as rmSync7 } from "node:fs";
|
|
71875
|
+
import { dirname as dirname36, join as join113 } from "node:path";
|
|
71721
71876
|
function listPresentManifestNames(installPath) {
|
|
71722
71877
|
const present = [];
|
|
71723
|
-
if (
|
|
71878
|
+
if (existsSync57(getManifestPath(installPath)))
|
|
71724
71879
|
present.push(MANIFEST_FILENAME);
|
|
71725
|
-
if (
|
|
71880
|
+
if (existsSync57(getLegacyManifestPath(installPath)))
|
|
71726
71881
|
present.push(LEGACY_MANIFEST_FILENAME);
|
|
71727
71882
|
return present;
|
|
71728
71883
|
}
|
|
@@ -71770,7 +71925,7 @@ async function analyzeInstallation(installation, forceOverwrite, kit) {
|
|
|
71770
71925
|
if (uninstallManifest.isMultiKit && kit && metadata?.kits?.[kit]) {
|
|
71771
71926
|
const kitFiles = metadata.kits[kit].files || [];
|
|
71772
71927
|
for (const trackedFile of kitFiles) {
|
|
71773
|
-
const filePath =
|
|
71928
|
+
const filePath = join113(installation.path, trackedFile.path);
|
|
71774
71929
|
if (uninstallManifest.filesToPreserve.includes(trackedFile.path)) {
|
|
71775
71930
|
result.toPreserve.push({ path: trackedFile.path, reason: "shared with other kit" });
|
|
71776
71931
|
continue;
|
|
@@ -71802,7 +71957,7 @@ async function analyzeInstallation(installation, forceOverwrite, kit) {
|
|
|
71802
71957
|
return result;
|
|
71803
71958
|
}
|
|
71804
71959
|
for (const trackedFile of allTrackedFiles) {
|
|
71805
|
-
const filePath =
|
|
71960
|
+
const filePath = join113(installation.path, trackedFile.path);
|
|
71806
71961
|
const ownershipResult = await OwnershipChecker.checkOwnership(filePath, metadata, installation.path);
|
|
71807
71962
|
if (!ownershipResult.exists)
|
|
71808
71963
|
continue;
|
|
@@ -71901,7 +72056,7 @@ async function removeInstallations(installations, options2) {
|
|
|
71901
72056
|
let removedCount = 0;
|
|
71902
72057
|
let cleanedDirs = 0;
|
|
71903
72058
|
for (const item of analysis.toDelete) {
|
|
71904
|
-
const filePath =
|
|
72059
|
+
const filePath = join114(installation.path, item.path);
|
|
71905
72060
|
if (!await import_fs_extra36.pathExists(filePath))
|
|
71906
72061
|
continue;
|
|
71907
72062
|
if (!await isPathSafeToRemove(filePath, installation.path)) {
|
|
@@ -72374,6 +72529,8 @@ async function updateCliCommand(options2, deps = getDefaultUpdateCliCommandDeps(
|
|
|
72374
72529
|
logger.verbose(`Using npm configured registry: ${redactRegistryUrlForLog(registryUrl)}`);
|
|
72375
72530
|
}
|
|
72376
72531
|
}
|
|
72532
|
+
if (registryUrl)
|
|
72533
|
+
registryUrl = validateRegistryUrl(registryUrl);
|
|
72377
72534
|
s3.start("Checking for updates...");
|
|
72378
72535
|
let targetVersion = null;
|
|
72379
72536
|
const usePrereleaseChannel = opts.dev || opts.beta;
|
|
@@ -72422,6 +72579,9 @@ async function updateCliCommand(options2, deps = getDefaultUpdateCliCommandDeps(
|
|
|
72422
72579
|
const isDevChannelSwitch = (opts.dev || opts.beta) && isBetaVersion(targetVersion) && !isBetaVersion(currentVersion);
|
|
72423
72580
|
if (comparison > 0 && !opts.release && !isDevChannelSwitch) {
|
|
72424
72581
|
outro(`[+] Current version (${currentVersion}) is newer than latest (${targetVersion})`);
|
|
72582
|
+
if (isBetaVersion(currentVersion)) {
|
|
72583
|
+
note("You are on a prerelease build. `tkm update` tracks the stable channel.\nTo update within the dev/beta channel, run: tkm update --beta");
|
|
72584
|
+
}
|
|
72425
72585
|
await promptKitUpdateFn(targetIsPrerelease, opts.yes);
|
|
72426
72586
|
return;
|
|
72427
72587
|
}
|
|
@@ -72746,7 +72906,7 @@ init_manifest_path_resolver();
|
|
|
72746
72906
|
init_logger();
|
|
72747
72907
|
init_types2();
|
|
72748
72908
|
import { readFileSync as readFileSync21 } from "node:fs";
|
|
72749
|
-
import { join as
|
|
72909
|
+
import { join as join115 } from "node:path";
|
|
72750
72910
|
var PROVIDER_LOCAL_SUBDIRS = {
|
|
72751
72911
|
"claude-code": ".claude",
|
|
72752
72912
|
codex: ".codex"
|
|
@@ -72801,7 +72961,7 @@ async function displayVersion() {
|
|
|
72801
72961
|
const localSubdir = PROVIDER_LOCAL_SUBDIRS[provider];
|
|
72802
72962
|
if (!localSubdir)
|
|
72803
72963
|
continue;
|
|
72804
|
-
const localRoot =
|
|
72964
|
+
const localRoot = join115(process.cwd(), localSubdir);
|
|
72805
72965
|
if (localRoot === inst.globalRoot())
|
|
72806
72966
|
continue;
|
|
72807
72967
|
const resolved = findManifestPathSync(localRoot);
|