@sunasteriskrnd/takumi 1.0.0-dev.25 → 1.0.0-dev.26
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 +365 -219
- 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.26",
|
|
8543
8543
|
description: "CLI tool for bootstrapping and managing Takumi projects",
|
|
8544
8544
|
type: "module",
|
|
8545
8545
|
repository: {
|
|
@@ -13598,6 +13598,7 @@ function globalSetupToInfo(g2) {
|
|
|
13598
13598
|
};
|
|
13599
13599
|
}
|
|
13600
13600
|
async function getTakumiSetup(projectDir = process.cwd()) {
|
|
13601
|
+
const { getInstaller, listSupportedProviders } = await Promise.resolve().then(() => (init_registry(), exports_registry));
|
|
13601
13602
|
const globalResults = await Promise.all(listSupportedProviders().map(async (p) => {
|
|
13602
13603
|
const inst = getInstaller(p);
|
|
13603
13604
|
return inst ? await inst.detectGlobalSetup() : null;
|
|
@@ -13622,7 +13623,6 @@ async function getTakumiSetup(projectDir = process.cwd()) {
|
|
|
13622
13623
|
var import_fs_extra5;
|
|
13623
13624
|
var init_takumi_scanner = __esm(() => {
|
|
13624
13625
|
init_paths();
|
|
13625
|
-
init_registry();
|
|
13626
13626
|
init_skip_directories();
|
|
13627
13627
|
init_manifest_path_resolver();
|
|
13628
13628
|
import_fs_extra5 = __toESM(require_lib(), 1);
|
|
@@ -33539,10 +33539,16 @@ function mergeHooksObject(current, incoming) {
|
|
|
33539
33539
|
const merged = deduplicateMerge(existingHooks, incoming);
|
|
33540
33540
|
return { ...current, hooks: merged };
|
|
33541
33541
|
}
|
|
33542
|
+
function isMalformedHookCommand(command) {
|
|
33543
|
+
return /(\$HOME|\$\{HOME\}|\$CLAUDE_PROJECT_DIR|\$\{CLAUDE_PROJECT_DIR\}|%USERPROFILE%|%CLAUDE_PROJECT_DIR%)\/\//.test(command);
|
|
33544
|
+
}
|
|
33542
33545
|
function deduplicateMerge(existing, incoming) {
|
|
33543
33546
|
const merged = {};
|
|
33544
33547
|
for (const [event, groups] of Object.entries(existing)) {
|
|
33545
|
-
merged[event] = groups.map((g2) => ({
|
|
33548
|
+
merged[event] = groups.map((g2) => ({
|
|
33549
|
+
...g2,
|
|
33550
|
+
hooks: g2.hooks.filter((h2) => !isMalformedHookCommand(h2.command))
|
|
33551
|
+
}));
|
|
33546
33552
|
}
|
|
33547
33553
|
for (const [event, incomingGroups] of Object.entries(incoming)) {
|
|
33548
33554
|
const existingGroups = merged[event] ?? [];
|
|
@@ -33562,7 +33568,13 @@ function deduplicateMerge(existing, incoming) {
|
|
|
33562
33568
|
}
|
|
33563
33569
|
merged[event] = existingGroups;
|
|
33564
33570
|
}
|
|
33565
|
-
|
|
33571
|
+
const cleaned = {};
|
|
33572
|
+
for (const [event, groups] of Object.entries(merged)) {
|
|
33573
|
+
const nonEmpty = groups.filter((g2) => g2.hooks.length > 0);
|
|
33574
|
+
if (nonEmpty.length > 0)
|
|
33575
|
+
cleaned[event] = nonEmpty;
|
|
33576
|
+
}
|
|
33577
|
+
return cleaned;
|
|
33566
33578
|
}
|
|
33567
33579
|
var init_hooks_settings_merger = __esm(() => {
|
|
33568
33580
|
init_provider_registry();
|
|
@@ -33755,6 +33767,9 @@ function scrubHookEntry(entry, event, capabilities, pathRewrite) {
|
|
|
33755
33767
|
if (pathRewrite) {
|
|
33756
33768
|
scrubbed.command = rewriteCommandPath(scrubbed.command, pathRewrite);
|
|
33757
33769
|
}
|
|
33770
|
+
if (typeof scrubbed.timeout === "number" && scrubbed.timeout < MIN_CODEX_HOOK_TIMEOUT_SECONDS) {
|
|
33771
|
+
scrubbed.timeout = MIN_CODEX_HOOK_TIMEOUT_SECONDS;
|
|
33772
|
+
}
|
|
33758
33773
|
const eventCaps = capabilities.events[event];
|
|
33759
33774
|
if (eventCaps?.permissionDecisionValues) {
|
|
33760
33775
|
const allowed = new Set(eventCaps.permissionDecisionValues);
|
|
@@ -33773,14 +33788,17 @@ function rewriteCommandPath(command, pathRewrite) {
|
|
|
33773
33788
|
if (pathRewrite.commandSubstitutions && pathRewrite.commandSubstitutions.size > 0) {
|
|
33774
33789
|
const home4 = homedir12();
|
|
33775
33790
|
const homeForward = normalizeSlashes(home4);
|
|
33791
|
+
const projectDirForward = pathRewrite.projectDir != null ? normalizeSlashes(pathRewrite.projectDir) : null;
|
|
33792
|
+
const relFrom = (absForward, baseForward) => {
|
|
33793
|
+
if (absForward.startsWith(`${baseForward}/`))
|
|
33794
|
+
return absForward.slice(baseForward.length + 1);
|
|
33795
|
+
if (absForward === baseForward)
|
|
33796
|
+
return "";
|
|
33797
|
+
return null;
|
|
33798
|
+
};
|
|
33776
33799
|
for (const [originalAbsPath, wrapperAbsPath] of pathRewrite.commandSubstitutions) {
|
|
33777
33800
|
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
|
-
}
|
|
33801
|
+
const relFromHome = relFrom(originalAbsForward, homeForward);
|
|
33784
33802
|
const candidates = [originalAbsForward, originalAbsPath];
|
|
33785
33803
|
if (relFromHome !== null && relFromHome !== "") {
|
|
33786
33804
|
candidates.push(`$HOME/${relFromHome}`);
|
|
@@ -33788,6 +33806,12 @@ function rewriteCommandPath(command, pathRewrite) {
|
|
|
33788
33806
|
candidates.push(`%USERPROFILE%/${relFromHome}`);
|
|
33789
33807
|
candidates.push(`\${HOME}/${relFromHome}`);
|
|
33790
33808
|
}
|
|
33809
|
+
const relFromProject = projectDirForward !== null ? relFrom(originalAbsForward, projectDirForward) : null;
|
|
33810
|
+
if (relFromProject !== null && relFromProject !== "") {
|
|
33811
|
+
candidates.push(`$CLAUDE_PROJECT_DIR/${relFromProject}`);
|
|
33812
|
+
candidates.push(`\${CLAUDE_PROJECT_DIR}/${relFromProject}`);
|
|
33813
|
+
candidates.push(`%CLAUDE_PROJECT_DIR%/${relFromProject}`);
|
|
33814
|
+
}
|
|
33791
33815
|
const wrapperForward = normalizeSlashes(wrapperAbsPath);
|
|
33792
33816
|
for (const candidate of candidates) {
|
|
33793
33817
|
const candidateNorm = normalizeSlashes(candidate);
|
|
@@ -33820,6 +33844,7 @@ function isRelativeCommandCandidate(candidate) {
|
|
|
33820
33844
|
function escapeRegExp(value) {
|
|
33821
33845
|
return value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
33822
33846
|
}
|
|
33847
|
+
var MIN_CODEX_HOOK_TIMEOUT_SECONDS = 10;
|
|
33823
33848
|
var init_claude_to_codex_hooks = () => {};
|
|
33824
33849
|
|
|
33825
33850
|
// src/domains/installers/codex/path-safety.ts
|
|
@@ -34371,7 +34396,8 @@ async function migrateCodexHooksSettings(options2) {
|
|
|
34371
34396
|
const wrapperPaths = [];
|
|
34372
34397
|
const commandSubstitutions = new Map;
|
|
34373
34398
|
if (targetHooksDir) {
|
|
34374
|
-
const
|
|
34399
|
+
const sourceHooksDirBase = isGlobal ? homedir14() : projectBase;
|
|
34400
|
+
const absSourceHooksDir = sourceHooksDir ? isAbsolute2(sourceHooksDir) ? sourceHooksDir : resolve12(sourceHooksDirBase, sourceHooksDir) : "";
|
|
34375
34401
|
const absTargetHooksDir = isAbsolute2(targetHooksDir) ? targetHooksDir : resolve12(projectBase, targetHooksDir);
|
|
34376
34402
|
const targetAbsolutePaths = installedHookAbsolutePaths && installedHookAbsolutePaths.length > 0 ? installedHookAbsolutePaths.filter(isCodexWrappableHookPath) : installedHookFiles.filter(isCodexWrappableHookPath).map((basenameOrPath) => basenameOrPath.includes("/") || basenameOrPath.includes("\\") ? basenameOrPath : join55(absTargetHooksDir, basenameOrPath));
|
|
34377
34403
|
const wrapperResults = generateCodexHookWrappers(targetAbsolutePaths, absTargetHooksDir, capabilities);
|
|
@@ -34395,7 +34421,8 @@ async function migrateCodexHooksSettings(options2) {
|
|
|
34395
34421
|
const converted = convertClaudeHooksToCodex(filtered, capabilities, {
|
|
34396
34422
|
sourceDir: sourceHooksDir,
|
|
34397
34423
|
targetDir: targetHooksDir || sourceHooksDir,
|
|
34398
|
-
commandSubstitutions: commandSubstitutions.size > 0 ? commandSubstitutions : undefined
|
|
34424
|
+
commandSubstitutions: commandSubstitutions.size > 0 ? commandSubstitutions : undefined,
|
|
34425
|
+
projectDir: isGlobal ? homedir14() : projectBase
|
|
34399
34426
|
});
|
|
34400
34427
|
let hooksRegistered = 0;
|
|
34401
34428
|
for (const groups of Object.values(converted)) {
|
|
@@ -34418,7 +34445,7 @@ async function migrateCodexHooksSettings(options2) {
|
|
|
34418
34445
|
}
|
|
34419
34446
|
let backupPath = null;
|
|
34420
34447
|
try {
|
|
34421
|
-
const mergeResult = await mergeHooksIntoSettings(resolvedTargetPath, converted);
|
|
34448
|
+
const mergeResult = await withCodexTargetLock2(resolvedTargetPath, () => mergeHooksIntoSettings(resolvedTargetPath, converted));
|
|
34422
34449
|
backupPath = mergeResult.backupPath;
|
|
34423
34450
|
} catch (err) {
|
|
34424
34451
|
return {
|
|
@@ -34436,7 +34463,13 @@ async function migrateCodexHooksSettings(options2) {
|
|
|
34436
34463
|
if (capabilities.requiresFeatureFlag) {
|
|
34437
34464
|
const configTomlPath = isGlobal ? join55(homedir14(), ".codex", "config.toml") : join55(projectBase, ".codex", "config.toml");
|
|
34438
34465
|
const flagResult = await ensureCodexHooksFeatureFlag(configTomlPath, isGlobal);
|
|
34439
|
-
featureFlagWritten = flagResult.status === "written" || flagResult.status === "updated";
|
|
34466
|
+
featureFlagWritten = flagResult.status === "written" || flagResult.status === "updated" || flagResult.status === "already-set";
|
|
34467
|
+
if (flagResult.status === "failed") {
|
|
34468
|
+
warnings.push({
|
|
34469
|
+
reason: "codex-feature-flag-write-failed",
|
|
34470
|
+
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\`.`
|
|
34471
|
+
});
|
|
34472
|
+
}
|
|
34440
34473
|
}
|
|
34441
34474
|
return {
|
|
34442
34475
|
status: "registered",
|
|
@@ -34460,6 +34493,7 @@ var init_hooks_merger = __esm(() => {
|
|
|
34460
34493
|
init_claude_to_codex_hooks();
|
|
34461
34494
|
init_features_flag();
|
|
34462
34495
|
init_hook_wrapper();
|
|
34496
|
+
init_path_safety();
|
|
34463
34497
|
CODEX_WRAPPABLE_HOOK_EXTENSIONS = new Set([".js", ".cjs", ".mjs", ".ts"]);
|
|
34464
34498
|
});
|
|
34465
34499
|
|
|
@@ -35985,12 +36019,25 @@ var init_installer2 = __esm(() => {
|
|
|
35985
36019
|
});
|
|
35986
36020
|
|
|
35987
36021
|
// src/domains/installers/registry.ts
|
|
36022
|
+
var exports_registry = {};
|
|
36023
|
+
__export(exports_registry, {
|
|
36024
|
+
unregisterInstaller: () => unregisterInstaller,
|
|
36025
|
+
registerInstaller: () => registerInstaller,
|
|
36026
|
+
listSupportedProviders: () => listSupportedProviders,
|
|
36027
|
+
getInstaller: () => getInstaller
|
|
36028
|
+
});
|
|
35988
36029
|
function getInstaller(provider) {
|
|
35989
36030
|
return installers[provider] ?? null;
|
|
35990
36031
|
}
|
|
35991
36032
|
function listSupportedProviders() {
|
|
35992
36033
|
return Object.keys(installers);
|
|
35993
36034
|
}
|
|
36035
|
+
function registerInstaller(installer) {
|
|
36036
|
+
installers[installer.provider] = installer;
|
|
36037
|
+
}
|
|
36038
|
+
function unregisterInstaller(provider) {
|
|
36039
|
+
delete installers[provider];
|
|
36040
|
+
}
|
|
35994
36041
|
var installers;
|
|
35995
36042
|
var init_registry = __esm(() => {
|
|
35996
36043
|
init_installer();
|
|
@@ -37485,6 +37532,24 @@ var init_kit_version_checker = __esm(() => {
|
|
|
37485
37532
|
});
|
|
37486
37533
|
|
|
37487
37534
|
// src/domains/github/npm-registry.ts
|
|
37535
|
+
function validateRegistryUrl(url) {
|
|
37536
|
+
if (!url || typeof url !== "string" || url.trim() === "") {
|
|
37537
|
+
throw new Error("Invalid registry URL: must be a non-empty string");
|
|
37538
|
+
}
|
|
37539
|
+
if (SHELL_METACHARACTERS.test(url)) {
|
|
37540
|
+
throw new Error("Invalid registry URL: contains disallowed characters");
|
|
37541
|
+
}
|
|
37542
|
+
let parsed;
|
|
37543
|
+
try {
|
|
37544
|
+
parsed = new URL(url);
|
|
37545
|
+
} catch {
|
|
37546
|
+
throw new Error(`Invalid registry URL: not a valid URL (${redactRegistryUrlForLog(url)})`);
|
|
37547
|
+
}
|
|
37548
|
+
if (parsed.protocol !== "https:" && parsed.protocol !== "http:") {
|
|
37549
|
+
throw new Error(`Invalid registry URL: unsupported protocol ${parsed.protocol}`);
|
|
37550
|
+
}
|
|
37551
|
+
return url;
|
|
37552
|
+
}
|
|
37488
37553
|
function redactRegistryUrlForLog(url) {
|
|
37489
37554
|
if (!url)
|
|
37490
37555
|
return url;
|
|
@@ -37633,9 +37698,10 @@ class NpmRegistryClient {
|
|
|
37633
37698
|
}
|
|
37634
37699
|
}
|
|
37635
37700
|
}
|
|
37636
|
-
var DEFAULT_REGISTRY_URL = "https://registry.npmjs.org", REQUEST_TIMEOUT = 5000, REDACTED_VALUE = "***";
|
|
37701
|
+
var DEFAULT_REGISTRY_URL = "https://registry.npmjs.org", REQUEST_TIMEOUT = 5000, REDACTED_VALUE = "***", SHELL_METACHARACTERS;
|
|
37637
37702
|
var init_npm_registry = __esm(() => {
|
|
37638
37703
|
init_logger();
|
|
37704
|
+
SHELL_METACHARACTERS = /[\s;|&$`<>()'"\\\n\r]/;
|
|
37639
37705
|
});
|
|
37640
37706
|
|
|
37641
37707
|
// src/domains/versioning/checking/cli-version-checker.ts
|
|
@@ -50384,11 +50450,11 @@ var exports_monorepo_resolver = {};
|
|
|
50384
50450
|
__export(exports_monorepo_resolver, {
|
|
50385
50451
|
resolveMonorepoRoot: () => resolveMonorepoRoot
|
|
50386
50452
|
});
|
|
50387
|
-
import { existsSync as
|
|
50388
|
-
import { dirname as dirname27, join as
|
|
50453
|
+
import { existsSync as existsSync49, readFileSync as readFileSync16 } from "node:fs";
|
|
50454
|
+
import { dirname as dirname27, join as join99, resolve as resolve22 } from "node:path";
|
|
50389
50455
|
import { fileURLToPath as fileURLToPath3 } from "node:url";
|
|
50390
50456
|
function parseMetadataAt(metadataPath) {
|
|
50391
|
-
if (!
|
|
50457
|
+
if (!existsSync49(metadataPath))
|
|
50392
50458
|
return null;
|
|
50393
50459
|
try {
|
|
50394
50460
|
const raw = readFileSync16(metadataPath, "utf-8");
|
|
@@ -50402,8 +50468,8 @@ function parseMetadataAt(metadataPath) {
|
|
|
50402
50468
|
}
|
|
50403
50469
|
}
|
|
50404
50470
|
function readSourceDirFromPackageJson(candidateRoot) {
|
|
50405
|
-
const packageJsonPath =
|
|
50406
|
-
if (!
|
|
50471
|
+
const packageJsonPath = join99(candidateRoot, "package.json");
|
|
50472
|
+
if (!existsSync49(packageJsonPath))
|
|
50407
50473
|
return null;
|
|
50408
50474
|
try {
|
|
50409
50475
|
const parsed = JSON.parse(readFileSync16(packageJsonPath, "utf-8"));
|
|
@@ -50425,7 +50491,7 @@ function tryReadAtCandidate(candidateRoot) {
|
|
|
50425
50491
|
};
|
|
50426
50492
|
}
|
|
50427
50493
|
const sourceDir = readSourceDirFromPackageJson(candidateRoot) ?? "claude";
|
|
50428
|
-
const sourceRoot =
|
|
50494
|
+
const sourceRoot = join99(candidateRoot, sourceDir);
|
|
50429
50495
|
const nestedMetadata = parseMetadataAt(getManifestPath(sourceRoot)) ?? parseMetadataAt(getLegacyManifestPath(sourceRoot));
|
|
50430
50496
|
if (nestedMetadata) {
|
|
50431
50497
|
return {
|
|
@@ -57051,17 +57117,102 @@ async function checkHooksExist(projectDir) {
|
|
|
57051
57117
|
autoFixable: false
|
|
57052
57118
|
};
|
|
57053
57119
|
}
|
|
57054
|
-
// src/domains/health-checks/checkers/
|
|
57055
|
-
init_paths();
|
|
57120
|
+
// src/domains/health-checks/checkers/codex-hook-health-checker.ts
|
|
57056
57121
|
init_registry();
|
|
57057
|
-
init_logger();
|
|
57058
57122
|
import { existsSync as existsSync39 } from "node:fs";
|
|
57059
57123
|
import { readFile as readFile33 } from "node:fs/promises";
|
|
57060
57124
|
import { join as join78 } from "node:path";
|
|
57125
|
+
async function checkCodexHooksHealth() {
|
|
57126
|
+
const codex = getInstaller("codex");
|
|
57127
|
+
if (!codex?.isInstalledGlobally())
|
|
57128
|
+
return [];
|
|
57129
|
+
const codexRoot = codex.globalRoot();
|
|
57130
|
+
const configTomlPath = join78(codexRoot, "config.toml");
|
|
57131
|
+
const hooksJsonPath = join78(codexRoot, "hooks.json");
|
|
57132
|
+
if (!existsSync39(hooksJsonPath))
|
|
57133
|
+
return [];
|
|
57134
|
+
const results = [];
|
|
57135
|
+
const flagPresent = existsSync39(configTomlPath) ? /(^|\n)\s*hooks\s*=\s*true/.test(await readFile33(configTomlPath, "utf8")) : false;
|
|
57136
|
+
results.push(flagPresent ? {
|
|
57137
|
+
id: "codex-hooks-feature-flag",
|
|
57138
|
+
name: "Codex hooks feature flag",
|
|
57139
|
+
group: "takumi",
|
|
57140
|
+
priority: "critical",
|
|
57141
|
+
status: "pass",
|
|
57142
|
+
message: "[features] hooks = true present",
|
|
57143
|
+
details: configTomlPath,
|
|
57144
|
+
autoFixable: false
|
|
57145
|
+
} : {
|
|
57146
|
+
id: "codex-hooks-feature-flag",
|
|
57147
|
+
name: "Codex hooks feature flag",
|
|
57148
|
+
group: "takumi",
|
|
57149
|
+
priority: "critical",
|
|
57150
|
+
status: "fail",
|
|
57151
|
+
message: "[features] hooks = true missing — Codex ignores all hooks. Add it to config.toml or run `tkm init -a codex`.",
|
|
57152
|
+
details: configTomlPath,
|
|
57153
|
+
autoFixable: false
|
|
57154
|
+
});
|
|
57155
|
+
const missing = await collectMissingWrapperTargets(hooksJsonPath);
|
|
57156
|
+
results.push(missing.length === 0 ? {
|
|
57157
|
+
id: "codex-hooks-command-targets",
|
|
57158
|
+
name: "Codex hook command targets",
|
|
57159
|
+
group: "takumi",
|
|
57160
|
+
priority: "standard",
|
|
57161
|
+
status: "pass",
|
|
57162
|
+
message: "All hook commands point to existing wrappers",
|
|
57163
|
+
details: hooksJsonPath,
|
|
57164
|
+
autoFixable: false
|
|
57165
|
+
} : {
|
|
57166
|
+
id: "codex-hooks-command-targets",
|
|
57167
|
+
name: "Codex hook command targets",
|
|
57168
|
+
group: "takumi",
|
|
57169
|
+
priority: "standard",
|
|
57170
|
+
status: "fail",
|
|
57171
|
+
message: `${missing.length} hook command(s) point to a missing wrapper. Re-run \`tkm init -a codex\` to regenerate.`,
|
|
57172
|
+
details: missing.join(", "),
|
|
57173
|
+
autoFixable: false
|
|
57174
|
+
});
|
|
57175
|
+
return results;
|
|
57176
|
+
}
|
|
57177
|
+
async function collectMissingWrapperTargets(hooksJsonPath) {
|
|
57178
|
+
let parsed;
|
|
57179
|
+
try {
|
|
57180
|
+
parsed = JSON.parse(await readFile33(hooksJsonPath, "utf8"));
|
|
57181
|
+
} catch {
|
|
57182
|
+
return [];
|
|
57183
|
+
}
|
|
57184
|
+
const hooks = parsed?.hooks;
|
|
57185
|
+
if (!hooks || typeof hooks !== "object")
|
|
57186
|
+
return [];
|
|
57187
|
+
const missing = [];
|
|
57188
|
+
const nodeCmd = /\bnode\s+"([^"]+\.cjs)"/;
|
|
57189
|
+
for (const groups of Object.values(hooks)) {
|
|
57190
|
+
if (!Array.isArray(groups))
|
|
57191
|
+
continue;
|
|
57192
|
+
for (const group of groups) {
|
|
57193
|
+
for (const entry of group?.hooks ?? []) {
|
|
57194
|
+
const command = entry?.command;
|
|
57195
|
+
if (typeof command !== "string")
|
|
57196
|
+
continue;
|
|
57197
|
+
const m2 = command.match(nodeCmd);
|
|
57198
|
+
if (m2 && !existsSync39(m2[1]))
|
|
57199
|
+
missing.push(m2[1]);
|
|
57200
|
+
}
|
|
57201
|
+
}
|
|
57202
|
+
}
|
|
57203
|
+
return missing;
|
|
57204
|
+
}
|
|
57205
|
+
// src/domains/health-checks/checkers/settings-checker.ts
|
|
57206
|
+
init_paths();
|
|
57207
|
+
init_registry();
|
|
57208
|
+
init_logger();
|
|
57209
|
+
import { existsSync as existsSync40 } from "node:fs";
|
|
57210
|
+
import { readFile as readFile34 } from "node:fs/promises";
|
|
57211
|
+
import { join as join79 } from "node:path";
|
|
57061
57212
|
async function checkSettingsValid(projectDir) {
|
|
57062
|
-
const globalSettings =
|
|
57063
|
-
const projectSettings =
|
|
57064
|
-
const settingsPath =
|
|
57213
|
+
const globalSettings = join79(getInstaller("claude-code")?.globalRoot() ?? "", "settings.json");
|
|
57214
|
+
const projectSettings = join79(getLocalClaudeDir(projectDir), "settings.json");
|
|
57215
|
+
const settingsPath = existsSync40(globalSettings) ? globalSettings : existsSync40(projectSettings) ? projectSettings : null;
|
|
57065
57216
|
if (!settingsPath) {
|
|
57066
57217
|
return {
|
|
57067
57218
|
id: "sk-settings-valid",
|
|
@@ -57074,7 +57225,7 @@ async function checkSettingsValid(projectDir) {
|
|
|
57074
57225
|
};
|
|
57075
57226
|
}
|
|
57076
57227
|
try {
|
|
57077
|
-
const content = await
|
|
57228
|
+
const content = await readFile34(settingsPath, "utf-8");
|
|
57078
57229
|
JSON.parse(content);
|
|
57079
57230
|
return {
|
|
57080
57231
|
id: "sk-settings-valid",
|
|
@@ -57131,14 +57282,14 @@ async function checkSettingsValid(projectDir) {
|
|
|
57131
57282
|
init_paths();
|
|
57132
57283
|
init_registry();
|
|
57133
57284
|
init_logger();
|
|
57134
|
-
import { existsSync as
|
|
57135
|
-
import { readFile as
|
|
57285
|
+
import { existsSync as existsSync41 } from "node:fs";
|
|
57286
|
+
import { readFile as readFile35 } from "node:fs/promises";
|
|
57136
57287
|
import { homedir as homedir24 } from "node:os";
|
|
57137
|
-
import { dirname as dirname19, join as
|
|
57288
|
+
import { dirname as dirname19, join as join80, normalize as normalize6, resolve as resolve17 } from "node:path";
|
|
57138
57289
|
async function checkPathRefsValid(projectDir) {
|
|
57139
|
-
const globalClaudeMd =
|
|
57140
|
-
const projectClaudeMd =
|
|
57141
|
-
const claudeMdPath =
|
|
57290
|
+
const globalClaudeMd = join80(getInstaller("claude-code")?.globalRoot() ?? "", "CLAUDE.md");
|
|
57291
|
+
const projectClaudeMd = join80(getLocalClaudeDir(projectDir), "CLAUDE.md");
|
|
57292
|
+
const claudeMdPath = existsSync41(globalClaudeMd) ? globalClaudeMd : existsSync41(projectClaudeMd) ? projectClaudeMd : null;
|
|
57142
57293
|
if (!claudeMdPath) {
|
|
57143
57294
|
return {
|
|
57144
57295
|
id: "sk-path-refs-valid",
|
|
@@ -57151,7 +57302,7 @@ async function checkPathRefsValid(projectDir) {
|
|
|
57151
57302
|
};
|
|
57152
57303
|
}
|
|
57153
57304
|
try {
|
|
57154
|
-
const content = await
|
|
57305
|
+
const content = await readFile35(claudeMdPath, "utf-8");
|
|
57155
57306
|
const refPattern = /@([^\s\)]+)/g;
|
|
57156
57307
|
const refs = [...content.matchAll(refPattern)].map((m2) => m2[1]);
|
|
57157
57308
|
if (refs.length === 0) {
|
|
@@ -57191,7 +57342,7 @@ async function checkPathRefsValid(projectDir) {
|
|
|
57191
57342
|
logger.verbose("Skipping potentially unsafe path reference", { ref, refPath });
|
|
57192
57343
|
continue;
|
|
57193
57344
|
}
|
|
57194
|
-
if (!
|
|
57345
|
+
if (!existsSync41(normalizedPath)) {
|
|
57195
57346
|
broken.push(ref);
|
|
57196
57347
|
}
|
|
57197
57348
|
}
|
|
@@ -57231,9 +57382,9 @@ async function checkPathRefsValid(projectDir) {
|
|
|
57231
57382
|
}
|
|
57232
57383
|
// src/domains/health-checks/checkers/config-completeness-checker.ts
|
|
57233
57384
|
init_paths();
|
|
57234
|
-
import { existsSync as
|
|
57385
|
+
import { existsSync as existsSync42 } from "node:fs";
|
|
57235
57386
|
import { readdir as readdir24 } from "node:fs/promises";
|
|
57236
|
-
import { join as
|
|
57387
|
+
import { join as join81 } from "node:path";
|
|
57237
57388
|
async function checkProjectConfigCompleteness(setup, projectDir) {
|
|
57238
57389
|
if (setup.globals.some((g2) => g2.path === setup.project.path)) {
|
|
57239
57390
|
return {
|
|
@@ -57250,12 +57401,12 @@ async function checkProjectConfigCompleteness(setup, projectDir) {
|
|
|
57250
57401
|
const requiredDirs = ["agents", "commands", "skills"];
|
|
57251
57402
|
const missingDirs = [];
|
|
57252
57403
|
for (const dir of requiredDirs) {
|
|
57253
|
-
const dirPath =
|
|
57254
|
-
if (!
|
|
57404
|
+
const dirPath = join81(projectClaudeDir, dir);
|
|
57405
|
+
if (!existsSync42(dirPath)) {
|
|
57255
57406
|
missingDirs.push(dir);
|
|
57256
57407
|
}
|
|
57257
57408
|
}
|
|
57258
|
-
const hasRulesOrWorkflows =
|
|
57409
|
+
const hasRulesOrWorkflows = existsSync42(join81(projectClaudeDir, "rules")) || existsSync42(join81(projectClaudeDir, "workflows"));
|
|
57259
57410
|
if (!hasRulesOrWorkflows) {
|
|
57260
57411
|
missingDirs.push("rules");
|
|
57261
57412
|
}
|
|
@@ -57335,6 +57486,8 @@ class TakumiChecker {
|
|
|
57335
57486
|
}
|
|
57336
57487
|
logger.verbose("TakumiChecker: Checking hooks directory");
|
|
57337
57488
|
results.push(await checkHooksExist(this.projectDir));
|
|
57489
|
+
logger.verbose("TakumiChecker: Checking Codex hook health");
|
|
57490
|
+
results.push(...await checkCodexHooksHealth());
|
|
57338
57491
|
logger.verbose("TakumiChecker: Checking settings.json validity");
|
|
57339
57492
|
results.push(await checkSettingsValid(this.projectDir));
|
|
57340
57493
|
logger.verbose("TakumiChecker: Checking path references");
|
|
@@ -57692,9 +57845,9 @@ import { platform as platform7 } from "node:os";
|
|
|
57692
57845
|
// src/domains/health-checks/platform/environment-checker.ts
|
|
57693
57846
|
init_registry();
|
|
57694
57847
|
init_environment();
|
|
57695
|
-
import { constants as constants2, access as access2, mkdir as mkdir19, readFile as
|
|
57848
|
+
import { constants as constants2, access as access2, mkdir as mkdir19, readFile as readFile36, unlink as unlink8, writeFile as writeFile24 } from "node:fs/promises";
|
|
57696
57849
|
import { arch as arch2, homedir as homedir25, platform as platform6 } from "node:os";
|
|
57697
|
-
import { join as
|
|
57850
|
+
import { join as join83, normalize as normalize7 } from "node:path";
|
|
57698
57851
|
function shouldSkipExpensiveOperations4() {
|
|
57699
57852
|
return shouldSkipExpensiveOperations();
|
|
57700
57853
|
}
|
|
@@ -57787,11 +57940,11 @@ async function checkGlobalDirAccess(provider) {
|
|
|
57787
57940
|
autoFixable: false
|
|
57788
57941
|
};
|
|
57789
57942
|
}
|
|
57790
|
-
const testFile =
|
|
57943
|
+
const testFile = join83(globalDir, ".sk-doctor-access-test");
|
|
57791
57944
|
try {
|
|
57792
57945
|
await mkdir19(globalDir, { recursive: true });
|
|
57793
57946
|
await writeFile24(testFile, "test", "utf-8");
|
|
57794
|
-
const content = await
|
|
57947
|
+
const content = await readFile36(testFile, "utf-8");
|
|
57795
57948
|
await unlink8(testFile);
|
|
57796
57949
|
if (content !== "test")
|
|
57797
57950
|
throw new Error("Read mismatch");
|
|
@@ -57865,7 +58018,7 @@ async function checkWSLBoundary() {
|
|
|
57865
58018
|
// src/domains/health-checks/platform/windows-checker.ts
|
|
57866
58019
|
init_registry();
|
|
57867
58020
|
import { mkdir as mkdir20, symlink as symlink2, unlink as unlink9, writeFile as writeFile25 } from "node:fs/promises";
|
|
57868
|
-
import { join as
|
|
58021
|
+
import { join as join84 } from "node:path";
|
|
57869
58022
|
async function checkLongPathSupport() {
|
|
57870
58023
|
if (shouldSkipExpensiveOperations4()) {
|
|
57871
58024
|
return {
|
|
@@ -57917,8 +58070,8 @@ async function checkSymlinkSupport() {
|
|
|
57917
58070
|
};
|
|
57918
58071
|
}
|
|
57919
58072
|
const testDir = getInstaller("claude-code")?.globalRoot() ?? "";
|
|
57920
|
-
const target =
|
|
57921
|
-
const link =
|
|
58073
|
+
const target = join84(testDir, ".sk-symlink-test-target");
|
|
58074
|
+
const link = join84(testDir, ".sk-symlink-test-link");
|
|
57922
58075
|
try {
|
|
57923
58076
|
await mkdir20(testDir, { recursive: true });
|
|
57924
58077
|
await writeFile25(target, "test", "utf-8");
|
|
@@ -58214,7 +58367,7 @@ class AutoHealer {
|
|
|
58214
58367
|
import { execSync as execSync4, spawnSync as spawnSync4 } from "node:child_process";
|
|
58215
58368
|
import { readFileSync as readFileSync11, unlinkSync as unlinkSync4, writeFileSync as writeFileSync6 } from "node:fs";
|
|
58216
58369
|
import { tmpdir as tmpdir2 } from "node:os";
|
|
58217
|
-
import { dirname as dirname20, join as
|
|
58370
|
+
import { dirname as dirname20, join as join85 } from "node:path";
|
|
58218
58371
|
import { fileURLToPath as fileURLToPath2 } from "node:url";
|
|
58219
58372
|
init_environment();
|
|
58220
58373
|
init_logger();
|
|
@@ -58222,7 +58375,7 @@ init_dist2();
|
|
|
58222
58375
|
function getCliVersion3() {
|
|
58223
58376
|
try {
|
|
58224
58377
|
const __dirname3 = dirname20(fileURLToPath2(import.meta.url));
|
|
58225
|
-
const pkgPath =
|
|
58378
|
+
const pkgPath = join85(__dirname3, "../../../package.json");
|
|
58226
58379
|
const pkg = JSON.parse(readFileSync11(pkgPath, "utf-8"));
|
|
58227
58380
|
return pkg.version || "unknown";
|
|
58228
58381
|
} catch (err) {
|
|
@@ -58361,7 +58514,7 @@ class ReportGenerator {
|
|
|
58361
58514
|
return null;
|
|
58362
58515
|
}
|
|
58363
58516
|
}
|
|
58364
|
-
const tmpFile =
|
|
58517
|
+
const tmpFile = join85(tmpdir2(), `sk-report-${Date.now()}.txt`);
|
|
58365
58518
|
writeFileSync6(tmpFile, report);
|
|
58366
58519
|
try {
|
|
58367
58520
|
const result = spawnSync4("gh", ["gist", "create", tmpFile, "--desc", "Takumi Diagnostic Report"], {
|
|
@@ -58674,7 +58827,7 @@ async function authedFetch(url, init) {
|
|
|
58674
58827
|
// src/commands/hooks/lib/detached-put.ts
|
|
58675
58828
|
import { spawn as spawn2 } from "node:child_process";
|
|
58676
58829
|
import { openSync as openSync4 } from "node:fs";
|
|
58677
|
-
import { dirname as dirname21, join as
|
|
58830
|
+
import { dirname as dirname21, join as join86 } from "node:path";
|
|
58678
58831
|
|
|
58679
58832
|
// src/commands/hooks/lib/hook-logger.ts
|
|
58680
58833
|
import { appendFileSync } from "node:fs";
|
|
@@ -58721,7 +58874,7 @@ function effectiveDetachMode(flags) {
|
|
|
58721
58874
|
return flags.noDetach ? "inline" : "detached";
|
|
58722
58875
|
}
|
|
58723
58876
|
function sessionDebugLogPath(sessionDir) {
|
|
58724
|
-
return
|
|
58877
|
+
return join86(sessionDir, DETACH_DEBUG_LOG_NAME);
|
|
58725
58878
|
}
|
|
58726
58879
|
var BUNFS_PREFIX = "/$bunfs/";
|
|
58727
58880
|
function resolveInvocationPrefix() {
|
|
@@ -58751,7 +58904,7 @@ function resolvePreloadScript(entryPath) {
|
|
|
58751
58904
|
try {
|
|
58752
58905
|
const srcDir = dirname21(entryPath);
|
|
58753
58906
|
const repoRoot = dirname21(srcDir);
|
|
58754
|
-
return
|
|
58907
|
+
return join86(repoRoot, "scripts", "preload-config-override.ts");
|
|
58755
58908
|
} catch {
|
|
58756
58909
|
return null;
|
|
58757
58910
|
}
|
|
@@ -58823,13 +58976,13 @@ import { promises as fs13 } from "node:fs";
|
|
|
58823
58976
|
|
|
58824
58977
|
// src/commands/hooks/lib/session-paths.ts
|
|
58825
58978
|
init_paths2();
|
|
58826
|
-
import { join as
|
|
58979
|
+
import { join as join88 } from "node:path";
|
|
58827
58980
|
|
|
58828
58981
|
// src/commands/hooks/lib/project-paths.ts
|
|
58829
58982
|
init_paths2();
|
|
58830
58983
|
import { createHash as createHash8 } from "node:crypto";
|
|
58831
58984
|
import { realpathSync as realpathSync2 } from "node:fs";
|
|
58832
|
-
import { basename as basename12, join as
|
|
58985
|
+
import { basename as basename12, join as join87 } from "node:path";
|
|
58833
58986
|
function encodeCwd(cwd2) {
|
|
58834
58987
|
const stripped = cwd2.replace(/^\/+/, "");
|
|
58835
58988
|
const sanitized = stripped.replace(/[^a-zA-Z0-9-]/g, "-");
|
|
@@ -58848,10 +59001,10 @@ function getProjectLabel(cwd2) {
|
|
|
58848
59001
|
return basename12(cwd2) || "";
|
|
58849
59002
|
}
|
|
58850
59003
|
function getProjectsRoot() {
|
|
58851
|
-
return
|
|
59004
|
+
return join87(getConfigDir(), "projects");
|
|
58852
59005
|
}
|
|
58853
59006
|
function getProjectDir(args) {
|
|
58854
|
-
return
|
|
59007
|
+
return join87(getProjectsRoot(), encodeCwd(args.cwd), args.agent);
|
|
58855
59008
|
}
|
|
58856
59009
|
|
|
58857
59010
|
// src/commands/hooks/lib/session-paths.ts
|
|
@@ -58863,25 +59016,25 @@ function safeSessionSegment(sessionId) {
|
|
|
58863
59016
|
return cleaned.length > 0 ? cleaned.slice(0, MAX_SESSION_ID_LEN) : null;
|
|
58864
59017
|
}
|
|
58865
59018
|
function getSessionsRoot() {
|
|
58866
|
-
return
|
|
59019
|
+
return join88(getConfigDir(), "sessions");
|
|
58867
59020
|
}
|
|
58868
59021
|
function getSessionDirV2(args) {
|
|
58869
59022
|
const segment = safeSessionSegment(args.sessionId);
|
|
58870
59023
|
if (!segment)
|
|
58871
59024
|
return null;
|
|
58872
|
-
return
|
|
59025
|
+
return join88(getProjectDir({ agent: args.agent, cwd: args.cwd }), "sessions", segment);
|
|
58873
59026
|
}
|
|
58874
59027
|
function getEventsFile(sessionDir) {
|
|
58875
|
-
return
|
|
59028
|
+
return join88(sessionDir, "events.jsonl");
|
|
58876
59029
|
}
|
|
58877
59030
|
function getSummaryFile(sessionDir) {
|
|
58878
|
-
return
|
|
59031
|
+
return join88(sessionDir, "summary.json");
|
|
58879
59032
|
}
|
|
58880
59033
|
function getLastPushFile(sessionDir) {
|
|
58881
|
-
return
|
|
59034
|
+
return join88(sessionDir, "last_push.txt");
|
|
58882
59035
|
}
|
|
58883
59036
|
function getMetaFile(sessionDir) {
|
|
58884
|
-
return
|
|
59037
|
+
return join88(sessionDir, "meta.json");
|
|
58885
59038
|
}
|
|
58886
59039
|
|
|
58887
59040
|
// src/commands/hooks/lib/throttle.ts
|
|
@@ -59499,9 +59652,9 @@ function resolveEndpoint() {
|
|
|
59499
59652
|
|
|
59500
59653
|
// src/commands/hooks/lib/manifest-versions.ts
|
|
59501
59654
|
init_manifest_path_resolver();
|
|
59502
|
-
import { existsSync as
|
|
59655
|
+
import { existsSync as existsSync44, readFileSync as readFileSync12 } from "node:fs";
|
|
59503
59656
|
import { homedir as homedir26 } from "node:os";
|
|
59504
|
-
import { dirname as dirname22, join as
|
|
59657
|
+
import { dirname as dirname22, join as join89, resolve as resolve18 } from "node:path";
|
|
59505
59658
|
var PROVIDER_DIRS = [".claude", ".codex"];
|
|
59506
59659
|
var MAX_WALK = 6;
|
|
59507
59660
|
function readManifestRaw(path10) {
|
|
@@ -59520,8 +59673,8 @@ function findManifest(cwd2) {
|
|
|
59520
59673
|
let dir = resolve18(cwd2);
|
|
59521
59674
|
for (let i = 0;i < MAX_WALK; i++) {
|
|
59522
59675
|
for (const provider of PROVIDER_DIRS) {
|
|
59523
|
-
const providerRoot =
|
|
59524
|
-
if (
|
|
59676
|
+
const providerRoot = join89(dir, provider);
|
|
59677
|
+
if (existsSync44(providerRoot)) {
|
|
59525
59678
|
const path10 = findManifestInProviderDir(providerRoot);
|
|
59526
59679
|
if (path10)
|
|
59527
59680
|
return path10;
|
|
@@ -59534,11 +59687,11 @@ function findManifest(cwd2) {
|
|
|
59534
59687
|
}
|
|
59535
59688
|
const pluginRoot = process.env.CLAUDE_PLUGIN_ROOT;
|
|
59536
59689
|
if (pluginRoot) {
|
|
59537
|
-
const pluginPath = findManifestInProviderDir(
|
|
59690
|
+
const pluginPath = findManifestInProviderDir(join89(pluginRoot, ".claude"));
|
|
59538
59691
|
if (pluginPath)
|
|
59539
59692
|
return pluginPath;
|
|
59540
59693
|
}
|
|
59541
|
-
const globalPath = findManifestInProviderDir(
|
|
59694
|
+
const globalPath = findManifestInProviderDir(join89(homedir26(), ".claude"));
|
|
59542
59695
|
if (globalPath)
|
|
59543
59696
|
return globalPath;
|
|
59544
59697
|
return null;
|
|
@@ -59653,8 +59806,8 @@ async function handleSessionEnd(agent, flags = {}) {
|
|
|
59653
59806
|
session_end_raw: data
|
|
59654
59807
|
};
|
|
59655
59808
|
const { promises: fs18 } = await import("node:fs");
|
|
59656
|
-
const { join:
|
|
59657
|
-
const target =
|
|
59809
|
+
const { join: join90 } = await import("node:path");
|
|
59810
|
+
const target = join90(sessionDir, "meta.json");
|
|
59658
59811
|
const tmp = `${target}.tmp`;
|
|
59659
59812
|
await fs18.writeFile(tmp, JSON.stringify(updated), "utf8");
|
|
59660
59813
|
await fs18.rename(tmp, target);
|
|
@@ -59725,7 +59878,7 @@ init_auth_client();
|
|
|
59725
59878
|
|
|
59726
59879
|
// src/commands/hooks/lib/retention.ts
|
|
59727
59880
|
import { promises as fs18 } from "node:fs";
|
|
59728
|
-
import { join as
|
|
59881
|
+
import { join as join90 } from "node:path";
|
|
59729
59882
|
async function hasLastPush(dir) {
|
|
59730
59883
|
try {
|
|
59731
59884
|
await fs18.access(getLastPushFile(dir));
|
|
@@ -59755,7 +59908,7 @@ async function decideDelete(dir, args) {
|
|
|
59755
59908
|
async function listChildren(dir) {
|
|
59756
59909
|
try {
|
|
59757
59910
|
const names = await fs18.readdir(dir);
|
|
59758
|
-
return names.map((n) =>
|
|
59911
|
+
return names.map((n) => join90(dir, n));
|
|
59759
59912
|
} catch {
|
|
59760
59913
|
return [];
|
|
59761
59914
|
}
|
|
@@ -59766,7 +59919,7 @@ async function collectV2Sessions() {
|
|
|
59766
59919
|
const sessions = [];
|
|
59767
59920
|
for (const projectDir of projects) {
|
|
59768
59921
|
for (const agentDir of await listChildren(projectDir)) {
|
|
59769
|
-
for (const sessionDir of await listChildren(
|
|
59922
|
+
for (const sessionDir of await listChildren(join90(agentDir, "sessions"))) {
|
|
59770
59923
|
sessions.push(sessionDir);
|
|
59771
59924
|
}
|
|
59772
59925
|
}
|
|
@@ -60166,7 +60319,7 @@ init_hooks_settings_merger();
|
|
|
60166
60319
|
|
|
60167
60320
|
// src/commands/portable/settings-write-with-confirm.ts
|
|
60168
60321
|
init_safe_prompts();
|
|
60169
|
-
import { existsSync as
|
|
60322
|
+
import { existsSync as existsSync45, mkdirSync as mkdirSync4, readFileSync as readFileSync13, renameSync as renameSync2, rmSync as rmSync3, writeFileSync as writeFileSync7 } from "node:fs";
|
|
60170
60323
|
import { dirname as dirname23 } from "node:path";
|
|
60171
60324
|
|
|
60172
60325
|
// node_modules/diff/libesm/diff/base.js
|
|
@@ -61339,7 +61492,7 @@ var EMPTY_RESULT = (status2) => ({
|
|
|
61339
61492
|
backupPath: null
|
|
61340
61493
|
});
|
|
61341
61494
|
function readCurrent(path10) {
|
|
61342
|
-
if (!
|
|
61495
|
+
if (!existsSync45(path10))
|
|
61343
61496
|
return { kind: "missing" };
|
|
61344
61497
|
let raw = "";
|
|
61345
61498
|
try {
|
|
@@ -61456,18 +61609,18 @@ init_dist2();
|
|
|
61456
61609
|
// src/commands/hooks/lib/agent-target-picker.ts
|
|
61457
61610
|
init_safe_prompts();
|
|
61458
61611
|
init_dist2();
|
|
61459
|
-
import { existsSync as
|
|
61612
|
+
import { existsSync as existsSync46 } from "node:fs";
|
|
61460
61613
|
|
|
61461
61614
|
// src/commands/hooks/lib/settings-path-resolver.ts
|
|
61462
61615
|
import { lstatSync as lstatSync3, realpathSync as realpathSync3 } from "node:fs";
|
|
61463
61616
|
import { homedir as homedir27 } from "node:os";
|
|
61464
|
-
import { join as
|
|
61617
|
+
import { join as join91 } from "node:path";
|
|
61465
61618
|
function rawPath(agent, global3) {
|
|
61466
61619
|
const root = global3 ? homedir27() : process.cwd();
|
|
61467
61620
|
if (agent === "claude") {
|
|
61468
|
-
return
|
|
61621
|
+
return join91(root, ".claude", "settings.json");
|
|
61469
61622
|
}
|
|
61470
|
-
return
|
|
61623
|
+
return join91(root, ".codex", "hooks.json");
|
|
61471
61624
|
}
|
|
61472
61625
|
function resolveSettingsPath(agent, options2 = {}) {
|
|
61473
61626
|
const originalPath = rawPath(agent, Boolean(options2.global));
|
|
@@ -61495,7 +61648,7 @@ function probe(global3) {
|
|
|
61495
61648
|
return {
|
|
61496
61649
|
agent,
|
|
61497
61650
|
path: location2.realPath,
|
|
61498
|
-
exists:
|
|
61651
|
+
exists: existsSync46(location2.realPath)
|
|
61499
61652
|
};
|
|
61500
61653
|
});
|
|
61501
61654
|
}
|
|
@@ -61540,7 +61693,7 @@ async function promptHookAgentTargets(options2) {
|
|
|
61540
61693
|
|
|
61541
61694
|
// src/commands/hooks/lib/entry-builder.ts
|
|
61542
61695
|
init_capabilities();
|
|
61543
|
-
var TIMEOUT_SECONDS =
|
|
61696
|
+
var TIMEOUT_SECONDS = 10;
|
|
61544
61697
|
var DEFAULT_HOOK_BIN = "tkm";
|
|
61545
61698
|
var CLAUDE_SESSION_START_MATCHER = "startup|resume|clear|compact";
|
|
61546
61699
|
var HOOK_EVENT_TO_CLAUDE_EVENT = {
|
|
@@ -61610,7 +61763,7 @@ function buildHookSection(agent, bin, flags = {}) {
|
|
|
61610
61763
|
|
|
61611
61764
|
// src/commands/hooks/uninstall-handler.ts
|
|
61612
61765
|
init_logger();
|
|
61613
|
-
import { existsSync as
|
|
61766
|
+
import { existsSync as existsSync47, mkdirSync as mkdirSync5, readFileSync as readFileSync14, renameSync as renameSync3, rmSync as rmSync4, writeFileSync as writeFileSync8 } from "node:fs";
|
|
61614
61767
|
import { dirname as dirname24 } from "node:path";
|
|
61615
61768
|
var AGENT_DISPLAY2 = {
|
|
61616
61769
|
claude: "Claude Code",
|
|
@@ -61665,7 +61818,7 @@ async function uninstallForAgent(agent, options2) {
|
|
|
61665
61818
|
removed: 0,
|
|
61666
61819
|
dryRun: Boolean(options2.dryRun)
|
|
61667
61820
|
};
|
|
61668
|
-
if (!
|
|
61821
|
+
if (!existsSync47(location2.realPath)) {
|
|
61669
61822
|
return result;
|
|
61670
61823
|
}
|
|
61671
61824
|
let parsed;
|
|
@@ -63219,7 +63372,7 @@ init_logger();
|
|
|
63219
63372
|
init_safe_spinner();
|
|
63220
63373
|
import { mkdir as mkdir25, stat as stat10 } from "node:fs/promises";
|
|
63221
63374
|
import { tmpdir as tmpdir3 } from "node:os";
|
|
63222
|
-
import { join as
|
|
63375
|
+
import { join as join97 } from "node:path";
|
|
63223
63376
|
|
|
63224
63377
|
// src/shared/temp-cleanup.ts
|
|
63225
63378
|
init_logger();
|
|
@@ -63238,7 +63391,7 @@ init_logger();
|
|
|
63238
63391
|
init_output_manager();
|
|
63239
63392
|
import { createWriteStream as createWriteStream2, rmSync as rmSync5 } from "node:fs";
|
|
63240
63393
|
import { mkdir as mkdir21 } from "node:fs/promises";
|
|
63241
|
-
import { join as
|
|
63394
|
+
import { join as join92 } from "node:path";
|
|
63242
63395
|
|
|
63243
63396
|
// src/shared/progress-bar.ts
|
|
63244
63397
|
init_output_manager();
|
|
@@ -63448,7 +63601,7 @@ var MAX_DOWNLOAD_SIZE = 500 * 1024 * 1024;
|
|
|
63448
63601
|
class FileDownloader {
|
|
63449
63602
|
async downloadAsset(asset, destDir) {
|
|
63450
63603
|
try {
|
|
63451
|
-
const destPath =
|
|
63604
|
+
const destPath = join92(destDir, asset.name);
|
|
63452
63605
|
await mkdir21(destDir, { recursive: true });
|
|
63453
63606
|
output.info(`Downloading ${asset.name} (${formatBytes(asset.size)})...`);
|
|
63454
63607
|
logger.verbose("Download details", {
|
|
@@ -63533,7 +63686,7 @@ class FileDownloader {
|
|
|
63533
63686
|
}
|
|
63534
63687
|
async downloadFile(params) {
|
|
63535
63688
|
const { url, name, size, destDir, token } = params;
|
|
63536
|
-
const destPath =
|
|
63689
|
+
const destPath = join92(destDir, name);
|
|
63537
63690
|
await mkdir21(destDir, { recursive: true });
|
|
63538
63691
|
output.info(`Downloading ${name}${size ? ` (${formatBytes(size)})` : ""}...`);
|
|
63539
63692
|
const headers = {};
|
|
@@ -63636,7 +63789,7 @@ init_logger();
|
|
|
63636
63789
|
init_types2();
|
|
63637
63790
|
import { constants as constants3 } from "node:fs";
|
|
63638
63791
|
import { access as access3, readdir as readdir25 } from "node:fs/promises";
|
|
63639
|
-
import { join as
|
|
63792
|
+
import { join as join93 } from "node:path";
|
|
63640
63793
|
async function validateExtraction(extractDir) {
|
|
63641
63794
|
try {
|
|
63642
63795
|
const entries = await readdir25(extractDir, { encoding: "utf8" });
|
|
@@ -63648,7 +63801,7 @@ async function validateExtraction(extractDir) {
|
|
|
63648
63801
|
const missingPaths = [];
|
|
63649
63802
|
for (const path10 of criticalPaths) {
|
|
63650
63803
|
try {
|
|
63651
|
-
await access3(
|
|
63804
|
+
await access3(join93(extractDir, path10), constants3.F_OK);
|
|
63652
63805
|
logger.debug(`Found: ${path10}`);
|
|
63653
63806
|
} catch {
|
|
63654
63807
|
logger.warning(`Expected path not found: ${path10}`);
|
|
@@ -63670,7 +63823,7 @@ async function validateExtraction(extractDir) {
|
|
|
63670
63823
|
// src/domains/installation/extraction/tar-extractor.ts
|
|
63671
63824
|
init_logger();
|
|
63672
63825
|
import { copyFile as copyFile5, mkdir as mkdir23, readdir as readdir27, rm as rm7, stat as stat8 } from "node:fs/promises";
|
|
63673
|
-
import { join as
|
|
63826
|
+
import { join as join95 } from "node:path";
|
|
63674
63827
|
|
|
63675
63828
|
// node_modules/tar/dist/esm/index.min.js
|
|
63676
63829
|
import Kr from "events";
|
|
@@ -66883,7 +67036,7 @@ function decodeFilePath(path10) {
|
|
|
66883
67036
|
init_logger();
|
|
66884
67037
|
init_types2();
|
|
66885
67038
|
import { copyFile as copyFile4, lstat as lstat6, mkdir as mkdir22, readdir as readdir26 } from "node:fs/promises";
|
|
66886
|
-
import { join as
|
|
67039
|
+
import { join as join94, relative as relative15 } from "node:path";
|
|
66887
67040
|
async function withRetry2(fn2, retries = 3) {
|
|
66888
67041
|
for (let i = 0;i < retries; i++) {
|
|
66889
67042
|
try {
|
|
@@ -66905,8 +67058,8 @@ async function moveDirectoryContents(sourceDir, destDir, shouldExclude, sizeTrac
|
|
|
66905
67058
|
await mkdir22(destDir, { recursive: true });
|
|
66906
67059
|
const entries = await readdir26(sourceDir, { encoding: "utf8" });
|
|
66907
67060
|
for (const entry of entries) {
|
|
66908
|
-
const sourcePath =
|
|
66909
|
-
const destPath =
|
|
67061
|
+
const sourcePath = join94(sourceDir, entry);
|
|
67062
|
+
const destPath = join94(destDir, entry);
|
|
66910
67063
|
const relativePath = relative15(sourceDir, sourcePath);
|
|
66911
67064
|
if (!isPathSafe(destDir, destPath)) {
|
|
66912
67065
|
logger.warning(`Skipping unsafe path: ${relativePath}`);
|
|
@@ -66933,8 +67086,8 @@ async function copyDirectory(sourceDir, destDir, shouldExclude, sizeTracker) {
|
|
|
66933
67086
|
await mkdir22(destDir, { recursive: true });
|
|
66934
67087
|
const entries = await readdir26(sourceDir, { encoding: "utf8" });
|
|
66935
67088
|
for (const entry of entries) {
|
|
66936
|
-
const sourcePath =
|
|
66937
|
-
const destPath =
|
|
67089
|
+
const sourcePath = join94(sourceDir, entry);
|
|
67090
|
+
const destPath = join94(destDir, entry);
|
|
66938
67091
|
const relativePath = relative15(sourceDir, sourcePath);
|
|
66939
67092
|
if (!isPathSafe(destDir, destPath)) {
|
|
66940
67093
|
logger.warning(`Skipping unsafe path: ${relativePath}`);
|
|
@@ -66989,7 +67142,7 @@ class TarExtractor {
|
|
|
66989
67142
|
logger.debug(`Root entries: ${entries.join(", ")}`);
|
|
66990
67143
|
if (entries.length === 1) {
|
|
66991
67144
|
const rootEntry = entries[0];
|
|
66992
|
-
const rootPath =
|
|
67145
|
+
const rootPath = join95(tempExtractDir, rootEntry);
|
|
66993
67146
|
const rootStat = await stat8(rootPath);
|
|
66994
67147
|
if (rootStat.isDirectory()) {
|
|
66995
67148
|
const rootContents = await readdir27(rootPath, { encoding: "utf8" });
|
|
@@ -67005,7 +67158,7 @@ class TarExtractor {
|
|
|
67005
67158
|
}
|
|
67006
67159
|
} else {
|
|
67007
67160
|
await mkdir23(destDir, { recursive: true });
|
|
67008
|
-
await copyFile5(rootPath,
|
|
67161
|
+
await copyFile5(rootPath, join95(destDir, rootEntry));
|
|
67009
67162
|
}
|
|
67010
67163
|
} else {
|
|
67011
67164
|
logger.debug("Multiple root entries - moving all");
|
|
@@ -67026,7 +67179,7 @@ class TarExtractor {
|
|
|
67026
67179
|
init_logger();
|
|
67027
67180
|
import { createWriteStream as createWriteStream3 } from "node:fs";
|
|
67028
67181
|
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
|
|
67182
|
+
import { dirname as dirname25, join as join96, resolve as resolve20 } from "node:path";
|
|
67030
67183
|
import { pipeline } from "node:stream/promises";
|
|
67031
67184
|
import yauzl from "yauzl-promise";
|
|
67032
67185
|
class ZipExtractor {
|
|
@@ -67040,7 +67193,7 @@ class ZipExtractor {
|
|
|
67040
67193
|
logger.debug(`Root entries: ${entries.join(", ")}`);
|
|
67041
67194
|
if (entries.length === 1) {
|
|
67042
67195
|
const rootEntry = entries[0];
|
|
67043
|
-
const rootPath =
|
|
67196
|
+
const rootPath = join96(tempExtractDir, rootEntry);
|
|
67044
67197
|
const rootStat = await stat9(rootPath);
|
|
67045
67198
|
if (rootStat.isDirectory()) {
|
|
67046
67199
|
const rootContents = await readdir28(rootPath, { encoding: "utf8" });
|
|
@@ -67056,7 +67209,7 @@ class ZipExtractor {
|
|
|
67056
67209
|
}
|
|
67057
67210
|
} else {
|
|
67058
67211
|
await mkdir24(destDir, { recursive: true });
|
|
67059
|
-
await copyFile6(rootPath,
|
|
67212
|
+
await copyFile6(rootPath, join96(destDir, rootEntry));
|
|
67060
67213
|
}
|
|
67061
67214
|
} else {
|
|
67062
67215
|
logger.debug("Multiple root entries - moving all");
|
|
@@ -67185,7 +67338,7 @@ class DownloadManager {
|
|
|
67185
67338
|
async createTempDir() {
|
|
67186
67339
|
const timestamp = Date.now();
|
|
67187
67340
|
const counter = DownloadManager.tempDirCounter++;
|
|
67188
|
-
const primaryTempDir =
|
|
67341
|
+
const primaryTempDir = join97(tmpdir3(), `takumi-${timestamp}-${counter}`);
|
|
67189
67342
|
try {
|
|
67190
67343
|
await mkdir25(primaryTempDir, { recursive: true });
|
|
67191
67344
|
logger.debug(`Created temp directory: ${primaryTempDir}`);
|
|
@@ -67202,7 +67355,7 @@ Solutions:
|
|
|
67202
67355
|
2. Set HOME environment variable
|
|
67203
67356
|
3. Try running from a different directory`);
|
|
67204
67357
|
}
|
|
67205
|
-
const fallbackTempDir =
|
|
67358
|
+
const fallbackTempDir = join97(homeDir, ".sunagentkit", "tmp", `takumi-${timestamp}-${counter}`);
|
|
67206
67359
|
try {
|
|
67207
67360
|
await mkdir25(fallbackTempDir, { recursive: true });
|
|
67208
67361
|
logger.debug(`Created temp directory (fallback): ${fallbackTempDir}`);
|
|
@@ -67908,7 +68061,7 @@ Re-run with explicit base kit, e.g. --kit ${BASE_KIT} --kit ${parsed2.join(" --k
|
|
|
67908
68061
|
}
|
|
67909
68062
|
// src/commands/init/phases/selection-handler.ts
|
|
67910
68063
|
import { mkdir as mkdir26 } from "node:fs/promises";
|
|
67911
|
-
import { join as
|
|
68064
|
+
import { join as join101, resolve as resolve24 } from "node:path";
|
|
67912
68065
|
|
|
67913
68066
|
// src/commands/shared/agent-selector.ts
|
|
67914
68067
|
init_registry();
|
|
@@ -68061,8 +68214,8 @@ init_logger();
|
|
|
68061
68214
|
init_safe_spinner();
|
|
68062
68215
|
init_takumi_constants();
|
|
68063
68216
|
var import_fs_extra31 = __toESM(require_lib(), 1);
|
|
68064
|
-
import { existsSync as
|
|
68065
|
-
import { dirname as dirname28, join as
|
|
68217
|
+
import { existsSync as existsSync50, readdirSync as readdirSync6, rmSync as rmSync6, rmdirSync as rmdirSync2, unlinkSync as unlinkSync5 } from "node:fs";
|
|
68218
|
+
import { dirname as dirname28, join as join100, resolve as resolve23 } from "node:path";
|
|
68066
68219
|
var TAKUMI_SUBDIRECTORIES = ["commands", "agents", "skills", "rules", "hooks"];
|
|
68067
68220
|
async function analyzeFreshInstallation(claudeDir) {
|
|
68068
68221
|
const metadata = await readManifest(claudeDir);
|
|
@@ -68132,9 +68285,9 @@ async function removeFilesByOwnership(claudeDir, analysis, includeModified) {
|
|
|
68132
68285
|
const filesToRemove = includeModified ? [...analysis.ckFiles, ...analysis.ckModifiedFiles] : analysis.ckFiles;
|
|
68133
68286
|
const filesToPreserve = includeModified ? analysis.userFiles : [...analysis.ckModifiedFiles, ...analysis.userFiles];
|
|
68134
68287
|
for (const file of filesToRemove) {
|
|
68135
|
-
const fullPath =
|
|
68288
|
+
const fullPath = join100(claudeDir, file.path);
|
|
68136
68289
|
try {
|
|
68137
|
-
if (
|
|
68290
|
+
if (existsSync50(fullPath)) {
|
|
68138
68291
|
unlinkSync5(fullPath);
|
|
68139
68292
|
removedFiles.push(file.path);
|
|
68140
68293
|
logger.debug(`Removed: ${file.path}`);
|
|
@@ -68206,7 +68359,7 @@ async function removeSubdirectoriesFallback(claudeDir) {
|
|
|
68206
68359
|
const removedFiles = [];
|
|
68207
68360
|
let removedDirCount = 0;
|
|
68208
68361
|
for (const subdir of TAKUMI_SUBDIRECTORIES) {
|
|
68209
|
-
const subdirPath =
|
|
68362
|
+
const subdirPath = join100(claudeDir, subdir);
|
|
68210
68363
|
if (await import_fs_extra31.pathExists(subdirPath)) {
|
|
68211
68364
|
rmSync6(subdirPath, { recursive: true, force: true });
|
|
68212
68365
|
removedDirCount++;
|
|
@@ -68431,7 +68584,7 @@ async function handleSelection(ctx) {
|
|
|
68431
68584
|
}
|
|
68432
68585
|
if (!ctx.options.fresh) {
|
|
68433
68586
|
const prefix = PathResolver.getPathPrefix(ctx.options.global);
|
|
68434
|
-
const claudeDir = prefix ?
|
|
68587
|
+
const claudeDir = prefix ? join101(resolvedDir, prefix) : resolvedDir;
|
|
68435
68588
|
try {
|
|
68436
68589
|
const existingMetadata = await readManifest(claudeDir);
|
|
68437
68590
|
if (existingMetadata?.kits) {
|
|
@@ -68464,7 +68617,7 @@ async function handleSelection(ctx) {
|
|
|
68464
68617
|
}
|
|
68465
68618
|
if (ctx.options.fresh) {
|
|
68466
68619
|
const prefix = PathResolver.getPathPrefix(ctx.options.global);
|
|
68467
|
-
const claudeDir = prefix ?
|
|
68620
|
+
const claudeDir = prefix ? join101(resolvedDir, prefix) : resolvedDir;
|
|
68468
68621
|
const canProceed = await handleFreshInstallation(claudeDir, ctx.prompts);
|
|
68469
68622
|
if (!canProceed) {
|
|
68470
68623
|
return { ...ctx, cancelled: true };
|
|
@@ -68484,7 +68637,7 @@ async function handleSelection(ctx) {
|
|
|
68484
68637
|
let currentVersion = null;
|
|
68485
68638
|
try {
|
|
68486
68639
|
const prefix = PathResolver.getPathPrefix(ctx.options.global);
|
|
68487
|
-
const claudeDir = prefix ?
|
|
68640
|
+
const claudeDir = prefix ? join101(resolvedDir, prefix) : resolvedDir;
|
|
68488
68641
|
const existingMetadata = await readManifest(claudeDir);
|
|
68489
68642
|
currentVersion = existingMetadata?.kits?.[kitType]?.version || null;
|
|
68490
68643
|
if (currentVersion) {
|
|
@@ -68572,7 +68725,7 @@ async function handleSelection(ctx) {
|
|
|
68572
68725
|
if (ctx.options.yes && !ctx.options.fresh && !ctx.options.force && releaseTag && !isOfflineMode) {
|
|
68573
68726
|
try {
|
|
68574
68727
|
const prefix = PathResolver.getPathPrefix(ctx.options.global);
|
|
68575
|
-
const claudeDir = prefix ?
|
|
68728
|
+
const claudeDir = prefix ? join101(resolvedDir, prefix) : resolvedDir;
|
|
68576
68729
|
const existingMetadata = await readManifest(claudeDir);
|
|
68577
68730
|
const installedKitVersion = existingMetadata?.kits?.[kitType]?.version;
|
|
68578
68731
|
if (installedKitVersion && versionsMatch(installedKitVersion, releaseTag)) {
|
|
@@ -68595,7 +68748,7 @@ async function handleSelection(ctx) {
|
|
|
68595
68748
|
let currentSecondaryVersion = null;
|
|
68596
68749
|
try {
|
|
68597
68750
|
const prefix = PathResolver.getPathPrefix(ctx.options.global);
|
|
68598
|
-
const claudeDir = prefix ?
|
|
68751
|
+
const claudeDir = prefix ? join101(resolvedDir, prefix) : resolvedDir;
|
|
68599
68752
|
const existingMetadata = await readManifest(claudeDir);
|
|
68600
68753
|
currentSecondaryVersion = existingMetadata?.kits?.[secondaryKit]?.version || null;
|
|
68601
68754
|
} catch {}
|
|
@@ -68678,13 +68831,13 @@ function resolveGlobalTargetDir(targetAgents2) {
|
|
|
68678
68831
|
}
|
|
68679
68832
|
// src/commands/init/phases/sync-handler.ts
|
|
68680
68833
|
init_paths();
|
|
68681
|
-
import { copyFile as copyFile7, mkdir as mkdir28, open as open2, readFile as
|
|
68682
|
-
import { dirname as dirname29, join as
|
|
68834
|
+
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";
|
|
68835
|
+
import { dirname as dirname29, join as join104, resolve as resolve25 } from "node:path";
|
|
68683
68836
|
|
|
68684
68837
|
// src/domains/sync/config-version-checker.ts
|
|
68685
68838
|
init_auth_client();
|
|
68686
|
-
import { mkdir as mkdir27, readFile as
|
|
68687
|
-
import { join as
|
|
68839
|
+
import { mkdir as mkdir27, readFile as readFile38, unlink as unlink10, writeFile as writeFile27 } from "node:fs/promises";
|
|
68840
|
+
import { join as join102 } from "node:path";
|
|
68688
68841
|
init_version_utils();
|
|
68689
68842
|
init_logger();
|
|
68690
68843
|
init_path_resolver();
|
|
@@ -68720,12 +68873,12 @@ var CACHE_FILENAME = "config-update-cache.json";
|
|
|
68720
68873
|
class ConfigVersionChecker {
|
|
68721
68874
|
static getCacheFilePath(kitType, global3) {
|
|
68722
68875
|
const cacheDir = PathResolver.getCacheDir(global3);
|
|
68723
|
-
return
|
|
68876
|
+
return join102(cacheDir, `${kitType}-${CACHE_FILENAME}`);
|
|
68724
68877
|
}
|
|
68725
68878
|
static async loadCache(kitType, global3) {
|
|
68726
68879
|
try {
|
|
68727
68880
|
const cachePath = ConfigVersionChecker.getCacheFilePath(kitType, global3);
|
|
68728
|
-
const data = await
|
|
68881
|
+
const data = await readFile38(cachePath, "utf8");
|
|
68729
68882
|
const parsed = JSON.parse(data);
|
|
68730
68883
|
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
68884
|
logger.debug("Invalid cache structure, ignoring");
|
|
@@ -68839,8 +68992,8 @@ class ConfigVersionChecker {
|
|
|
68839
68992
|
// src/domains/sync/sync-engine.ts
|
|
68840
68993
|
init_ownership_checker();
|
|
68841
68994
|
init_logger();
|
|
68842
|
-
import { lstat as lstat7, readFile as
|
|
68843
|
-
import { isAbsolute as isAbsolute3, join as
|
|
68995
|
+
import { lstat as lstat7, readFile as readFile39, readlink, realpath as realpath3, stat as stat11 } from "node:fs/promises";
|
|
68996
|
+
import { isAbsolute as isAbsolute3, join as join103, normalize as normalize8, relative as relative16 } from "node:path";
|
|
68844
68997
|
var MAX_SYNC_FILE_SIZE = 10 * 1024 * 1024;
|
|
68845
68998
|
var MAX_SYMLINK_DEPTH = 20;
|
|
68846
68999
|
async function validateSymlinkChain(path11, basePath, maxDepth = MAX_SYMLINK_DEPTH) {
|
|
@@ -68852,7 +69005,7 @@ async function validateSymlinkChain(path11, basePath, maxDepth = MAX_SYMLINK_DEP
|
|
|
68852
69005
|
if (!stats.isSymbolicLink())
|
|
68853
69006
|
break;
|
|
68854
69007
|
const target = await readlink(current);
|
|
68855
|
-
const resolvedTarget = isAbsolute3(target) ? target :
|
|
69008
|
+
const resolvedTarget = isAbsolute3(target) ? target : join103(current, "..", target);
|
|
68856
69009
|
const normalizedTarget = normalize8(resolvedTarget);
|
|
68857
69010
|
const rel = relative16(basePath, normalizedTarget);
|
|
68858
69011
|
if (rel.startsWith("..") || isAbsolute3(rel)) {
|
|
@@ -68888,7 +69041,7 @@ async function validateSyncPath(basePath, filePath) {
|
|
|
68888
69041
|
if (normalized.startsWith("..") || normalized.includes("/../")) {
|
|
68889
69042
|
throw new Error(`Path traversal not allowed: ${filePath}`);
|
|
68890
69043
|
}
|
|
68891
|
-
const fullPath =
|
|
69044
|
+
const fullPath = join103(basePath, normalized);
|
|
68892
69045
|
const rel = relative16(basePath, fullPath);
|
|
68893
69046
|
if (rel.startsWith("..") || isAbsolute3(rel)) {
|
|
68894
69047
|
throw new Error(`Path escapes base directory: ${filePath}`);
|
|
@@ -68903,7 +69056,7 @@ async function validateSyncPath(basePath, filePath) {
|
|
|
68903
69056
|
}
|
|
68904
69057
|
} catch (error) {
|
|
68905
69058
|
if (error.code === "ENOENT") {
|
|
68906
|
-
const parentPath =
|
|
69059
|
+
const parentPath = join103(fullPath, "..");
|
|
68907
69060
|
try {
|
|
68908
69061
|
const resolvedBase = await realpath3(basePath);
|
|
68909
69062
|
const resolvedParent = await realpath3(parentPath);
|
|
@@ -69074,7 +69227,7 @@ class SyncEngine {
|
|
|
69074
69227
|
if (lstats.size > MAX_SYNC_FILE_SIZE) {
|
|
69075
69228
|
throw new Error(`File too large for sync (${Math.round(lstats.size / 1024 / 1024)}MB > ${MAX_SYNC_FILE_SIZE / 1024 / 1024}MB limit)`);
|
|
69076
69229
|
}
|
|
69077
|
-
const buffer = await
|
|
69230
|
+
const buffer = await readFile39(filePath);
|
|
69078
69231
|
if (buffer.includes(0)) {
|
|
69079
69232
|
return { content: "", isBinary: true };
|
|
69080
69233
|
}
|
|
@@ -69394,7 +69547,7 @@ function getLockTimeout() {
|
|
|
69394
69547
|
var STALE_LOCK_THRESHOLD_MS = 5 * 60 * 1000;
|
|
69395
69548
|
async function acquireSyncLock(global3) {
|
|
69396
69549
|
const cacheDir = PathResolver.getCacheDir(global3);
|
|
69397
|
-
const lockPath =
|
|
69550
|
+
const lockPath = join104(cacheDir, ".sync-lock");
|
|
69398
69551
|
const startTime = Date.now();
|
|
69399
69552
|
const lockTimeout = getLockTimeout();
|
|
69400
69553
|
await mkdir28(dirname29(lockPath), { recursive: true });
|
|
@@ -69445,7 +69598,7 @@ async function executeSyncMerge(ctx) {
|
|
|
69445
69598
|
try {
|
|
69446
69599
|
const sourceManifest = await findManifestPath(upstreamDir);
|
|
69447
69600
|
if (sourceManifest) {
|
|
69448
|
-
const content = await
|
|
69601
|
+
const content = await readFile40(sourceManifest.path, "utf-8");
|
|
69449
69602
|
const sourceMetadata = JSON.parse(content);
|
|
69450
69603
|
deletions = sourceMetadata.deletions || [];
|
|
69451
69604
|
}
|
|
@@ -69475,7 +69628,7 @@ async function executeSyncMerge(ctx) {
|
|
|
69475
69628
|
try {
|
|
69476
69629
|
const sourcePath = await validateSyncPath(upstreamDir, file.path);
|
|
69477
69630
|
const targetPath = await validateSyncPath(ctx.claudeDir, file.path);
|
|
69478
|
-
const targetDir =
|
|
69631
|
+
const targetDir = join104(targetPath, "..");
|
|
69479
69632
|
try {
|
|
69480
69633
|
await mkdir28(targetDir, { recursive: true });
|
|
69481
69634
|
} catch (mkdirError) {
|
|
@@ -69646,7 +69799,7 @@ async function createBackup(claudeDir, files, backupDir) {
|
|
|
69646
69799
|
const sourcePath = await validateSyncPath(claudeDir, file.path);
|
|
69647
69800
|
if (await import_fs_extra33.pathExists(sourcePath)) {
|
|
69648
69801
|
const targetPath = await validateSyncPath(backupDir, file.path);
|
|
69649
|
-
const targetDir =
|
|
69802
|
+
const targetDir = join104(targetPath, "..");
|
|
69650
69803
|
await mkdir28(targetDir, { recursive: true });
|
|
69651
69804
|
await copyFile7(sourcePath, targetPath);
|
|
69652
69805
|
}
|
|
@@ -69672,38 +69825,38 @@ init_logger();
|
|
|
69672
69825
|
init_types2();
|
|
69673
69826
|
var import_fs_extra34 = __toESM(require_lib(), 1);
|
|
69674
69827
|
import { rename as rename8, rm as rm9 } from "node:fs/promises";
|
|
69675
|
-
import { join as
|
|
69828
|
+
import { join as join105, relative as relative17 } from "node:path";
|
|
69676
69829
|
async function collectDirsToRename(extractDir, folders) {
|
|
69677
69830
|
const dirsToRename = [];
|
|
69678
69831
|
if (folders.docs !== DEFAULT_FOLDERS.docs) {
|
|
69679
|
-
const docsPath =
|
|
69832
|
+
const docsPath = join105(extractDir, DEFAULT_FOLDERS.docs);
|
|
69680
69833
|
if (await import_fs_extra34.pathExists(docsPath)) {
|
|
69681
69834
|
dirsToRename.push({
|
|
69682
69835
|
from: docsPath,
|
|
69683
|
-
to:
|
|
69836
|
+
to: join105(extractDir, folders.docs)
|
|
69684
69837
|
});
|
|
69685
69838
|
}
|
|
69686
|
-
const claudeDocsPath =
|
|
69839
|
+
const claudeDocsPath = join105(extractDir, ".claude", DEFAULT_FOLDERS.docs);
|
|
69687
69840
|
if (await import_fs_extra34.pathExists(claudeDocsPath)) {
|
|
69688
69841
|
dirsToRename.push({
|
|
69689
69842
|
from: claudeDocsPath,
|
|
69690
|
-
to:
|
|
69843
|
+
to: join105(extractDir, ".claude", folders.docs)
|
|
69691
69844
|
});
|
|
69692
69845
|
}
|
|
69693
69846
|
}
|
|
69694
69847
|
if (folders.plans !== DEFAULT_FOLDERS.plans) {
|
|
69695
|
-
const plansPath =
|
|
69848
|
+
const plansPath = join105(extractDir, DEFAULT_FOLDERS.plans);
|
|
69696
69849
|
if (await import_fs_extra34.pathExists(plansPath)) {
|
|
69697
69850
|
dirsToRename.push({
|
|
69698
69851
|
from: plansPath,
|
|
69699
|
-
to:
|
|
69852
|
+
to: join105(extractDir, folders.plans)
|
|
69700
69853
|
});
|
|
69701
69854
|
}
|
|
69702
|
-
const claudePlansPath =
|
|
69855
|
+
const claudePlansPath = join105(extractDir, ".claude", DEFAULT_FOLDERS.plans);
|
|
69703
69856
|
if (await import_fs_extra34.pathExists(claudePlansPath)) {
|
|
69704
69857
|
dirsToRename.push({
|
|
69705
69858
|
from: claudePlansPath,
|
|
69706
|
-
to:
|
|
69859
|
+
to: join105(extractDir, ".claude", folders.plans)
|
|
69707
69860
|
});
|
|
69708
69861
|
}
|
|
69709
69862
|
}
|
|
@@ -69743,8 +69896,8 @@ async function renameFolders(dirsToRename, extractDir, options2) {
|
|
|
69743
69896
|
// src/services/transformers/folder-transform/path-replacer.ts
|
|
69744
69897
|
init_logger();
|
|
69745
69898
|
init_types2();
|
|
69746
|
-
import { readFile as
|
|
69747
|
-
import { join as
|
|
69899
|
+
import { readFile as readFile41, readdir as readdir29, writeFile as writeFile29 } from "node:fs/promises";
|
|
69900
|
+
import { join as join106, relative as relative18 } from "node:path";
|
|
69748
69901
|
var TRANSFORMABLE_FILE_PATTERNS = [
|
|
69749
69902
|
".md",
|
|
69750
69903
|
".txt",
|
|
@@ -69797,7 +69950,7 @@ async function transformFileContents(dir, compiledReplacements, options2) {
|
|
|
69797
69950
|
let replacementsCount = 0;
|
|
69798
69951
|
const entries = await readdir29(dir, { withFileTypes: true });
|
|
69799
69952
|
for (const entry of entries) {
|
|
69800
|
-
const fullPath =
|
|
69953
|
+
const fullPath = join106(dir, entry.name);
|
|
69801
69954
|
if (entry.isDirectory()) {
|
|
69802
69955
|
if (entry.name === "node_modules" || entry.name === ".git") {
|
|
69803
69956
|
continue;
|
|
@@ -69810,7 +69963,7 @@ async function transformFileContents(dir, compiledReplacements, options2) {
|
|
|
69810
69963
|
if (!shouldTransform)
|
|
69811
69964
|
continue;
|
|
69812
69965
|
try {
|
|
69813
|
-
const content = await
|
|
69966
|
+
const content = await readFile41(fullPath, "utf-8");
|
|
69814
69967
|
let newContent = content;
|
|
69815
69968
|
let changeCount = 0;
|
|
69816
69969
|
for (const { regex: regex2, replacement } of compiledReplacements) {
|
|
@@ -69932,11 +70085,11 @@ async function transformFolderPaths(extractDir, folders, options2 = {}) {
|
|
|
69932
70085
|
|
|
69933
70086
|
// src/services/transformers/global-path-transformer.ts
|
|
69934
70087
|
init_logger();
|
|
69935
|
-
import { readFile as
|
|
70088
|
+
import { readFile as readFile42, readdir as readdir30, writeFile as writeFile30 } from "node:fs/promises";
|
|
69936
70089
|
import { platform as platform9 } from "node:os";
|
|
69937
|
-
import { extname as extname6, join as
|
|
70090
|
+
import { extname as extname6, join as join107 } from "node:path";
|
|
69938
70091
|
var IS_WINDOWS3 = platform9() === "win32";
|
|
69939
|
-
var HOME_PREFIX =
|
|
70092
|
+
var HOME_PREFIX = "$HOME";
|
|
69940
70093
|
function getHomeDirPrefix() {
|
|
69941
70094
|
return HOME_PREFIX;
|
|
69942
70095
|
}
|
|
@@ -69959,24 +70112,14 @@ function transformContent(content) {
|
|
|
69959
70112
|
let transformed = content;
|
|
69960
70113
|
const homePrefix = getHomeDirPrefix();
|
|
69961
70114
|
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
|
-
}
|
|
70115
|
+
transformed = transformed.replace(/%USERPROFILE%\/\.claude\//g, () => {
|
|
70116
|
+
changes++;
|
|
70117
|
+
return claudePath;
|
|
70118
|
+
});
|
|
70119
|
+
transformed = transformed.replace(/%USERPROFILE%(?=\/|\\)/g, () => {
|
|
70120
|
+
changes++;
|
|
70121
|
+
return homePrefix;
|
|
70122
|
+
});
|
|
69980
70123
|
transformed = transformed.replace(/\$CLAUDE_PROJECT_DIR\/\.claude\//g, () => {
|
|
69981
70124
|
changes++;
|
|
69982
70125
|
return claudePath;
|
|
@@ -69989,12 +70132,10 @@ function transformContent(content) {
|
|
|
69989
70132
|
changes++;
|
|
69990
70133
|
return claudePath;
|
|
69991
70134
|
});
|
|
69992
|
-
|
|
69993
|
-
|
|
69994
|
-
|
|
69995
|
-
|
|
69996
|
-
});
|
|
69997
|
-
}
|
|
70135
|
+
transformed = transformed.replace(/%CLAUDE_PROJECT_DIR%\/\.claude\//g, () => {
|
|
70136
|
+
changes++;
|
|
70137
|
+
return claudePath;
|
|
70138
|
+
});
|
|
69998
70139
|
transformed = transformed.replace(/\.\/\.claude\//g, () => {
|
|
69999
70140
|
changes++;
|
|
70000
70141
|
return claudePath;
|
|
@@ -70046,7 +70187,7 @@ async function transformPathsForGlobalInstall(directory, options2 = {}) {
|
|
|
70046
70187
|
async function processDirectory2(dir) {
|
|
70047
70188
|
const entries = await readdir30(dir, { withFileTypes: true });
|
|
70048
70189
|
for (const entry of entries) {
|
|
70049
|
-
const fullPath =
|
|
70190
|
+
const fullPath = join107(dir, entry.name);
|
|
70050
70191
|
if (entry.isDirectory()) {
|
|
70051
70192
|
if (entry.name === "node_modules" || entry.name.startsWith(".") && entry.name !== ".claude") {
|
|
70052
70193
|
continue;
|
|
@@ -70054,7 +70195,7 @@ async function transformPathsForGlobalInstall(directory, options2 = {}) {
|
|
|
70054
70195
|
await processDirectory2(fullPath);
|
|
70055
70196
|
} else if (entry.isFile() && shouldTransformFile3(entry.name)) {
|
|
70056
70197
|
try {
|
|
70057
|
-
const content = await
|
|
70198
|
+
const content = await readFile42(fullPath, "utf-8");
|
|
70058
70199
|
const { transformed, changes } = transformContent(content);
|
|
70059
70200
|
if (changes > 0) {
|
|
70060
70201
|
await writeFile30(fullPath, transformed, "utf-8");
|
|
@@ -70313,12 +70454,12 @@ async function initCommand(options2) {
|
|
|
70313
70454
|
}
|
|
70314
70455
|
// src/commands/plan/plan-command.ts
|
|
70315
70456
|
init_output_manager();
|
|
70316
|
-
import { existsSync as
|
|
70317
|
-
import { dirname as dirname35, join as
|
|
70457
|
+
import { existsSync as existsSync55, statSync as statSync7 } from "node:fs";
|
|
70458
|
+
import { dirname as dirname35, join as join111, parse as parse4, resolve as resolve29 } from "node:path";
|
|
70318
70459
|
|
|
70319
70460
|
// src/commands/plan/plan-read-handlers.ts
|
|
70320
|
-
import { existsSync as
|
|
70321
|
-
import { basename as basename15, dirname as dirname34, join as
|
|
70461
|
+
import { existsSync as existsSync54, statSync as statSync6 } from "node:fs";
|
|
70462
|
+
import { basename as basename15, dirname as dirname34, join as join110, relative as relative19, resolve as resolve27 } from "node:path";
|
|
70322
70463
|
|
|
70323
70464
|
// src/domains/plan-parser/index.ts
|
|
70324
70465
|
import { dirname as dirname33 } from "node:path";
|
|
@@ -70698,20 +70839,20 @@ function parsePlanFile(planFilePath, options2) {
|
|
|
70698
70839
|
return { frontmatter, phases };
|
|
70699
70840
|
}
|
|
70700
70841
|
// src/domains/plan-parser/plan-scanner.ts
|
|
70701
|
-
import { existsSync as
|
|
70702
|
-
import { join as
|
|
70842
|
+
import { existsSync as existsSync51, readdirSync as readdirSync7 } from "node:fs";
|
|
70843
|
+
import { join as join108 } from "node:path";
|
|
70703
70844
|
function scanPlanDir(dir) {
|
|
70704
|
-
if (!
|
|
70845
|
+
if (!existsSync51(dir))
|
|
70705
70846
|
return [];
|
|
70706
70847
|
try {
|
|
70707
|
-
return readdirSync7(dir, { withFileTypes: true }).filter((entry) => entry.isDirectory()).map((entry) =>
|
|
70848
|
+
return readdirSync7(dir, { withFileTypes: true }).filter((entry) => entry.isDirectory()).map((entry) => join108(dir, entry.name, "plan.md")).filter(existsSync51);
|
|
70708
70849
|
} catch {
|
|
70709
70850
|
return [];
|
|
70710
70851
|
}
|
|
70711
70852
|
}
|
|
70712
70853
|
// src/domains/plan-parser/plan-validator.ts
|
|
70713
70854
|
var import_gray_matter6 = __toESM(require_gray_matter(), 1);
|
|
70714
|
-
import { existsSync as
|
|
70855
|
+
import { existsSync as existsSync52, readFileSync as readFileSync18 } from "node:fs";
|
|
70715
70856
|
import { basename as basename13, dirname as dirname31 } from "node:path";
|
|
70716
70857
|
function validatePlanFile(filePath, strict = false) {
|
|
70717
70858
|
const content = readFileSync18(filePath, "utf8");
|
|
@@ -70751,7 +70892,7 @@ function validatePlanFile(filePath, strict = false) {
|
|
|
70751
70892
|
});
|
|
70752
70893
|
}
|
|
70753
70894
|
for (const phase of phases) {
|
|
70754
|
-
if (phase.file && !
|
|
70895
|
+
if (phase.file && !existsSync52(phase.file)) {
|
|
70755
70896
|
const fileBasename = basename13(phase.file);
|
|
70756
70897
|
const refLine = lines.findIndex((l2) => l2.includes(fileBasename));
|
|
70757
70898
|
issues.push({
|
|
@@ -70772,8 +70913,8 @@ function validatePlanFile(filePath, strict = false) {
|
|
|
70772
70913
|
// src/domains/plan-parser/plan-writer.ts
|
|
70773
70914
|
var import_gray_matter7 = __toESM(require_gray_matter(), 1);
|
|
70774
70915
|
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
|
|
70916
|
+
import { existsSync as existsSync53 } from "node:fs";
|
|
70917
|
+
import { basename as basename14, dirname as dirname32, join as join109 } from "node:path";
|
|
70777
70918
|
function phaseNameToFilename(id, name) {
|
|
70778
70919
|
const numMatch = /^(\d+)([a-z]*)$/i.exec(id);
|
|
70779
70920
|
const num3 = numMatch ? numMatch[1] : id;
|
|
@@ -70881,12 +71022,12 @@ function scaffoldPlan(options2) {
|
|
|
70881
71022
|
mkdirSync6(dir, { recursive: true });
|
|
70882
71023
|
const resolvedPhases = resolvePhaseIds(options2.phases);
|
|
70883
71024
|
const optionsWithResolved = { ...options2, phases: resolvedPhases };
|
|
70884
|
-
const planFile =
|
|
71025
|
+
const planFile = join109(dir, "plan.md");
|
|
70885
71026
|
writeFileSync9(planFile, generatePlanMd(optionsWithResolved), "utf8");
|
|
70886
71027
|
const phaseFiles = [];
|
|
70887
71028
|
for (const phase of resolvedPhases) {
|
|
70888
71029
|
const filename = phaseNameToFilename(phase.id, phase.name);
|
|
70889
|
-
const phaseFile =
|
|
71030
|
+
const phaseFile = join109(dir, filename);
|
|
70890
71031
|
writeFileSync9(phaseFile, generatePhaseTemplate(phase), "utf8");
|
|
70891
71032
|
phaseFiles.push(phaseFile);
|
|
70892
71033
|
}
|
|
@@ -70954,7 +71095,7 @@ function updatePhaseStatus(planFile, phaseId, newStatus) {
|
|
|
70954
71095
|
writeFileSync9(planFile, updatedContent, "utf8");
|
|
70955
71096
|
const planDir = dirname32(planFile);
|
|
70956
71097
|
const phaseFilename = phaseNameFilenameFromTableRow(updatedBody, phaseId, planDir);
|
|
70957
|
-
if (phaseFilename &&
|
|
71098
|
+
if (phaseFilename && existsSync53(phaseFilename)) {
|
|
70958
71099
|
updatePhaseFileFrontmatter(phaseFilename, newStatus);
|
|
70959
71100
|
}
|
|
70960
71101
|
}
|
|
@@ -70966,7 +71107,7 @@ function phaseNameFilenameFromTableRow(body, phaseId, planDir) {
|
|
|
70966
71107
|
continue;
|
|
70967
71108
|
const linkMatch = /\[([^\]]+)\]\(\.\/([^)]+)\)/.exec(row);
|
|
70968
71109
|
if (linkMatch)
|
|
70969
|
-
return
|
|
71110
|
+
return join109(planDir, linkMatch[2]);
|
|
70970
71111
|
}
|
|
70971
71112
|
return null;
|
|
70972
71113
|
}
|
|
@@ -71047,7 +71188,7 @@ function addPhase(planFile, name, afterId) {
|
|
|
71047
71188
|
`);
|
|
71048
71189
|
}
|
|
71049
71190
|
writeFileSync9(planFile, import_gray_matter7.default.stringify(updatedBody, frontmatter), "utf8");
|
|
71050
|
-
const phaseFilePath =
|
|
71191
|
+
const phaseFilePath = join109(planDir, filename);
|
|
71051
71192
|
writeFileSync9(phaseFilePath, generatePhaseTemplate({ id: phaseId, name }), "utf8");
|
|
71052
71193
|
return { phaseId, phaseFile: phaseFilePath };
|
|
71053
71194
|
}
|
|
@@ -71151,7 +71292,7 @@ async function handleValidate(target, options2) {
|
|
|
71151
71292
|
}
|
|
71152
71293
|
async function handleStatus(target, options2) {
|
|
71153
71294
|
const t = target ? resolve27(target) : null;
|
|
71154
|
-
const plansDir = t &&
|
|
71295
|
+
const plansDir = t && existsSync54(t) && statSync6(t).isDirectory() && !existsSync54(join110(t, "plan.md")) ? t : null;
|
|
71155
71296
|
if (plansDir) {
|
|
71156
71297
|
const planFiles = scanPlanDir(plansDir);
|
|
71157
71298
|
if (planFiles.length === 0) {
|
|
@@ -71382,20 +71523,20 @@ async function handleAddPhase(target, options2) {
|
|
|
71382
71523
|
// src/commands/plan/plan-command.ts
|
|
71383
71524
|
function resolvePlanFile(target) {
|
|
71384
71525
|
const t = target ? resolve29(target) : process.cwd();
|
|
71385
|
-
if (
|
|
71526
|
+
if (existsSync55(t)) {
|
|
71386
71527
|
const stat13 = statSync7(t);
|
|
71387
71528
|
if (stat13.isFile())
|
|
71388
71529
|
return t;
|
|
71389
|
-
const candidate =
|
|
71390
|
-
if (
|
|
71530
|
+
const candidate = join111(t, "plan.md");
|
|
71531
|
+
if (existsSync55(candidate))
|
|
71391
71532
|
return candidate;
|
|
71392
71533
|
}
|
|
71393
71534
|
if (!target) {
|
|
71394
71535
|
let dir = process.cwd();
|
|
71395
71536
|
const root = parse4(dir).root;
|
|
71396
71537
|
while (dir !== root) {
|
|
71397
|
-
const candidate =
|
|
71398
|
-
if (
|
|
71538
|
+
const candidate = join111(dir, "plan.md");
|
|
71539
|
+
if (existsSync55(candidate))
|
|
71399
71540
|
return candidate;
|
|
71400
71541
|
dir = dirname35(dir);
|
|
71401
71542
|
}
|
|
@@ -71445,7 +71586,7 @@ async function planCommand(action, target, options2) {
|
|
|
71445
71586
|
let resolvedTarget = target;
|
|
71446
71587
|
if (resolvedAction && !knownActions.has(resolvedAction)) {
|
|
71447
71588
|
const looksLikePath = resolvedAction.includes("/") || resolvedAction.includes("\\") || resolvedAction.endsWith(".md") || resolvedAction === "." || resolvedAction === "..";
|
|
71448
|
-
const existsOnDisk = !looksLikePath &&
|
|
71589
|
+
const existsOnDisk = !looksLikePath && existsSync55(resolve29(resolvedAction));
|
|
71449
71590
|
if (looksLikePath || existsOnDisk) {
|
|
71450
71591
|
resolvedTarget = resolvedAction;
|
|
71451
71592
|
resolvedAction = undefined;
|
|
@@ -71489,22 +71630,22 @@ init_logger();
|
|
|
71489
71630
|
init_logger();
|
|
71490
71631
|
|
|
71491
71632
|
// src/commands/telemetry/shared.ts
|
|
71492
|
-
import { existsSync as
|
|
71633
|
+
import { existsSync as existsSync56, readFileSync as readFileSync20, readdirSync as readdirSync8 } from "node:fs";
|
|
71493
71634
|
import { homedir as homedir28 } from "node:os";
|
|
71494
|
-
import { join as
|
|
71635
|
+
import { join as join112 } from "node:path";
|
|
71495
71636
|
init_token_store();
|
|
71496
71637
|
init_manifest_path_resolver();
|
|
71497
71638
|
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 =
|
|
71639
|
+
var USER_CACHE_PATH = join112(homedir28(), ".claude", "sk-user.json");
|
|
71640
|
+
var EVENT_BUFFER_DIR = join112(homedir28(), ".claude", "sk-events");
|
|
71641
|
+
var RATE_STATE_PATH = join112(homedir28(), ".claude", "sk-rate-state.json");
|
|
71642
|
+
var TAKUMI_MANIFEST_PATH = join112(homedir28(), ".claude", MANIFEST_FILENAME);
|
|
71643
|
+
var LEGACY_METADATA_PATH = join112(homedir28(), ".claude", LEGACY_MANIFEST_FILENAME);
|
|
71503
71644
|
var TELEMETRY_HOOK_FIELD = "hooks.telemetry";
|
|
71504
71645
|
var TOKEN_PLACEHOLDER = "__INJECT_AT_RELEASE__";
|
|
71505
71646
|
function readUserCache() {
|
|
71506
71647
|
try {
|
|
71507
|
-
if (!
|
|
71648
|
+
if (!existsSync56(USER_CACHE_PATH))
|
|
71508
71649
|
return null;
|
|
71509
71650
|
const parsed = JSON.parse(readFileSync20(USER_CACHE_PATH, "utf8"));
|
|
71510
71651
|
if (!parsed || typeof parsed !== "object")
|
|
@@ -71516,7 +71657,7 @@ function readUserCache() {
|
|
|
71516
71657
|
}
|
|
71517
71658
|
function countBufferFiles() {
|
|
71518
71659
|
try {
|
|
71519
|
-
if (!
|
|
71660
|
+
if (!existsSync56(EVENT_BUFFER_DIR))
|
|
71520
71661
|
return 0;
|
|
71521
71662
|
return readdirSync8(EVENT_BUFFER_DIR).filter((f4) => f4.endsWith(".jsonl")).length;
|
|
71522
71663
|
} catch {
|
|
@@ -71528,7 +71669,7 @@ function readTelemetryConfig() {
|
|
|
71528
71669
|
const envToken = process.env.TAKUMI_TELEMETRY_TOKEN;
|
|
71529
71670
|
let metadata = null;
|
|
71530
71671
|
try {
|
|
71531
|
-
const resolved = findManifestPathSync(
|
|
71672
|
+
const resolved = findManifestPathSync(join112(homedir28(), ".claude"));
|
|
71532
71673
|
if (resolved) {
|
|
71533
71674
|
metadata = JSON.parse(readFileSync20(resolved.path, "utf8"));
|
|
71534
71675
|
}
|
|
@@ -71554,8 +71695,8 @@ function collectRuntimeContext() {
|
|
|
71554
71695
|
cacheSource: cache2?.source === "gh" || cache2?.source === "manual" ? cache2.source : null,
|
|
71555
71696
|
bufferFileCount: countBufferFiles(),
|
|
71556
71697
|
bufferDir: EVENT_BUFFER_DIR,
|
|
71557
|
-
rateStateExists:
|
|
71558
|
-
userCacheExists:
|
|
71698
|
+
rateStateExists: existsSync56(RATE_STATE_PATH),
|
|
71699
|
+
userCacheExists: existsSync56(USER_CACHE_PATH),
|
|
71559
71700
|
endpoint,
|
|
71560
71701
|
tokenConfigured: Boolean(token)
|
|
71561
71702
|
};
|
|
@@ -71706,7 +71847,7 @@ init_safe_prompts();
|
|
|
71706
71847
|
init_safe_spinner();
|
|
71707
71848
|
var import_fs_extra36 = __toESM(require_lib(), 1);
|
|
71708
71849
|
import { readdirSync as readdirSync10, rmSync as rmSync8 } from "node:fs";
|
|
71709
|
-
import { join as
|
|
71850
|
+
import { join as join114, resolve as resolve30, sep as sep10 } from "node:path";
|
|
71710
71851
|
|
|
71711
71852
|
// src/commands/uninstall/analysis-handler.ts
|
|
71712
71853
|
init_metadata_migration();
|
|
@@ -71716,13 +71857,13 @@ init_logger();
|
|
|
71716
71857
|
init_safe_prompts();
|
|
71717
71858
|
init_takumi_constants();
|
|
71718
71859
|
var import_picocolors27 = __toESM(require_picocolors(), 1);
|
|
71719
|
-
import { existsSync as
|
|
71720
|
-
import { dirname as dirname36, join as
|
|
71860
|
+
import { existsSync as existsSync57, readdirSync as readdirSync9, rmSync as rmSync7 } from "node:fs";
|
|
71861
|
+
import { dirname as dirname36, join as join113 } from "node:path";
|
|
71721
71862
|
function listPresentManifestNames(installPath) {
|
|
71722
71863
|
const present = [];
|
|
71723
|
-
if (
|
|
71864
|
+
if (existsSync57(getManifestPath(installPath)))
|
|
71724
71865
|
present.push(MANIFEST_FILENAME);
|
|
71725
|
-
if (
|
|
71866
|
+
if (existsSync57(getLegacyManifestPath(installPath)))
|
|
71726
71867
|
present.push(LEGACY_MANIFEST_FILENAME);
|
|
71727
71868
|
return present;
|
|
71728
71869
|
}
|
|
@@ -71770,7 +71911,7 @@ async function analyzeInstallation(installation, forceOverwrite, kit) {
|
|
|
71770
71911
|
if (uninstallManifest.isMultiKit && kit && metadata?.kits?.[kit]) {
|
|
71771
71912
|
const kitFiles = metadata.kits[kit].files || [];
|
|
71772
71913
|
for (const trackedFile of kitFiles) {
|
|
71773
|
-
const filePath =
|
|
71914
|
+
const filePath = join113(installation.path, trackedFile.path);
|
|
71774
71915
|
if (uninstallManifest.filesToPreserve.includes(trackedFile.path)) {
|
|
71775
71916
|
result.toPreserve.push({ path: trackedFile.path, reason: "shared with other kit" });
|
|
71776
71917
|
continue;
|
|
@@ -71802,7 +71943,7 @@ async function analyzeInstallation(installation, forceOverwrite, kit) {
|
|
|
71802
71943
|
return result;
|
|
71803
71944
|
}
|
|
71804
71945
|
for (const trackedFile of allTrackedFiles) {
|
|
71805
|
-
const filePath =
|
|
71946
|
+
const filePath = join113(installation.path, trackedFile.path);
|
|
71806
71947
|
const ownershipResult = await OwnershipChecker.checkOwnership(filePath, metadata, installation.path);
|
|
71807
71948
|
if (!ownershipResult.exists)
|
|
71808
71949
|
continue;
|
|
@@ -71901,7 +72042,7 @@ async function removeInstallations(installations, options2) {
|
|
|
71901
72042
|
let removedCount = 0;
|
|
71902
72043
|
let cleanedDirs = 0;
|
|
71903
72044
|
for (const item of analysis.toDelete) {
|
|
71904
|
-
const filePath =
|
|
72045
|
+
const filePath = join114(installation.path, item.path);
|
|
71905
72046
|
if (!await import_fs_extra36.pathExists(filePath))
|
|
71906
72047
|
continue;
|
|
71907
72048
|
if (!await isPathSafeToRemove(filePath, installation.path)) {
|
|
@@ -72374,6 +72515,8 @@ async function updateCliCommand(options2, deps = getDefaultUpdateCliCommandDeps(
|
|
|
72374
72515
|
logger.verbose(`Using npm configured registry: ${redactRegistryUrlForLog(registryUrl)}`);
|
|
72375
72516
|
}
|
|
72376
72517
|
}
|
|
72518
|
+
if (registryUrl)
|
|
72519
|
+
registryUrl = validateRegistryUrl(registryUrl);
|
|
72377
72520
|
s3.start("Checking for updates...");
|
|
72378
72521
|
let targetVersion = null;
|
|
72379
72522
|
const usePrereleaseChannel = opts.dev || opts.beta;
|
|
@@ -72422,6 +72565,9 @@ async function updateCliCommand(options2, deps = getDefaultUpdateCliCommandDeps(
|
|
|
72422
72565
|
const isDevChannelSwitch = (opts.dev || opts.beta) && isBetaVersion(targetVersion) && !isBetaVersion(currentVersion);
|
|
72423
72566
|
if (comparison > 0 && !opts.release && !isDevChannelSwitch) {
|
|
72424
72567
|
outro(`[+] Current version (${currentVersion}) is newer than latest (${targetVersion})`);
|
|
72568
|
+
if (isBetaVersion(currentVersion)) {
|
|
72569
|
+
note("You are on a prerelease build. `tkm update` tracks the stable channel.\nTo update within the dev/beta channel, run: tkm update --beta");
|
|
72570
|
+
}
|
|
72425
72571
|
await promptKitUpdateFn(targetIsPrerelease, opts.yes);
|
|
72426
72572
|
return;
|
|
72427
72573
|
}
|
|
@@ -72746,7 +72892,7 @@ init_manifest_path_resolver();
|
|
|
72746
72892
|
init_logger();
|
|
72747
72893
|
init_types2();
|
|
72748
72894
|
import { readFileSync as readFileSync21 } from "node:fs";
|
|
72749
|
-
import { join as
|
|
72895
|
+
import { join as join115 } from "node:path";
|
|
72750
72896
|
var PROVIDER_LOCAL_SUBDIRS = {
|
|
72751
72897
|
"claude-code": ".claude",
|
|
72752
72898
|
codex: ".codex"
|
|
@@ -72801,7 +72947,7 @@ async function displayVersion() {
|
|
|
72801
72947
|
const localSubdir = PROVIDER_LOCAL_SUBDIRS[provider];
|
|
72802
72948
|
if (!localSubdir)
|
|
72803
72949
|
continue;
|
|
72804
|
-
const localRoot =
|
|
72950
|
+
const localRoot = join115(process.cwd(), localSubdir);
|
|
72805
72951
|
if (localRoot === inst.globalRoot())
|
|
72806
72952
|
continue;
|
|
72807
72953
|
const resolved = findManifestPathSync(localRoot);
|