claudekit-cli 4.3.1-dev.1 → 4.3.1-dev.3
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/cli-manifest.json +8 -2
- package/dist/index.js +672 -409
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -12564,6 +12564,16 @@ import { existsSync as existsSync2 } from "node:fs";
|
|
|
12564
12564
|
import { mkdir, readFile as readFile2, rename, unlink, writeFile } from "node:fs/promises";
|
|
12565
12565
|
import { homedir as homedir3 } from "node:os";
|
|
12566
12566
|
import { dirname, join as join2, resolve } from "node:path";
|
|
12567
|
+
function getPortableRegistryPaths() {
|
|
12568
|
+
const home2 = homedir3();
|
|
12569
|
+
const claudekitDir = join2(home2, ".claudekit");
|
|
12570
|
+
return {
|
|
12571
|
+
registryPath: join2(claudekitDir, "portable-registry.json"),
|
|
12572
|
+
registryLockPath: join2(claudekitDir, "portable-registry.lock"),
|
|
12573
|
+
legacyRegistryPath: join2(claudekitDir, "skill-registry.json"),
|
|
12574
|
+
migrationLockPath: join2(claudekitDir, ".migration.lock")
|
|
12575
|
+
};
|
|
12576
|
+
}
|
|
12567
12577
|
function isErrnoCode(error, code) {
|
|
12568
12578
|
return typeof error === "object" && error !== null && "code" in error && error.code === code;
|
|
12569
12579
|
}
|
|
@@ -12597,8 +12607,9 @@ function getCliVersion() {
|
|
|
12597
12607
|
}
|
|
12598
12608
|
}
|
|
12599
12609
|
async function migrateLegacyRegistry() {
|
|
12610
|
+
const { legacyRegistryPath } = getPortableRegistryPaths();
|
|
12600
12611
|
try {
|
|
12601
|
-
const content = await readFile2(
|
|
12612
|
+
const content = await readFile2(legacyRegistryPath, "utf-8");
|
|
12602
12613
|
const data = JSON.parse(content);
|
|
12603
12614
|
const legacy = LegacyRegistrySchema.parse(data);
|
|
12604
12615
|
const installations = legacy.installations.map((i) => ({
|
|
@@ -12707,9 +12718,10 @@ async function repairStaleRegistryV3(registry) {
|
|
|
12707
12718
|
}
|
|
12708
12719
|
async function persistCurrentStaleRegistryV3Repair(preparedRepair) {
|
|
12709
12720
|
return withRegistryLock(async () => {
|
|
12721
|
+
const { registryPath } = getPortableRegistryPaths();
|
|
12710
12722
|
let content;
|
|
12711
12723
|
try {
|
|
12712
|
-
content = await readFile2(
|
|
12724
|
+
content = await readFile2(registryPath, "utf-8");
|
|
12713
12725
|
} catch (error) {
|
|
12714
12726
|
if (isErrnoCode(error, "ENOENT")) {
|
|
12715
12727
|
return readPortableRegistryInternal({ persistStaleV3Repair: false });
|
|
@@ -12741,8 +12753,9 @@ async function persistCurrentStaleRegistryV3Repair(preparedRepair) {
|
|
|
12741
12753
|
});
|
|
12742
12754
|
}
|
|
12743
12755
|
async function isMigrationLocked() {
|
|
12756
|
+
const { migrationLockPath } = getPortableRegistryPaths();
|
|
12744
12757
|
try {
|
|
12745
|
-
const lockContent = await readFile2(
|
|
12758
|
+
const lockContent = await readFile2(migrationLockPath, "utf-8");
|
|
12746
12759
|
const lockTime = Number.parseInt(lockContent, 10);
|
|
12747
12760
|
if (Number.isNaN(lockTime)) {
|
|
12748
12761
|
logger.verbose("Migration lock timestamp is invalid, treating lock as active");
|
|
@@ -12754,7 +12767,7 @@ async function isMigrationLocked() {
|
|
|
12754
12767
|
return true;
|
|
12755
12768
|
}
|
|
12756
12769
|
logger.verbose("Removing stale migration lock");
|
|
12757
|
-
await unlink(
|
|
12770
|
+
await unlink(migrationLockPath);
|
|
12758
12771
|
return false;
|
|
12759
12772
|
} catch (error) {
|
|
12760
12773
|
if (isErrnoCode(error, "ENOENT")) {
|
|
@@ -12765,23 +12778,26 @@ async function isMigrationLocked() {
|
|
|
12765
12778
|
}
|
|
12766
12779
|
}
|
|
12767
12780
|
async function createMigrationLock() {
|
|
12768
|
-
const
|
|
12781
|
+
const { migrationLockPath } = getPortableRegistryPaths();
|
|
12782
|
+
const lockDir = dirname(migrationLockPath);
|
|
12769
12783
|
if (!existsSync2(lockDir)) {
|
|
12770
12784
|
await mkdir(lockDir, { recursive: true });
|
|
12771
12785
|
}
|
|
12772
|
-
await writeFile(
|
|
12786
|
+
await writeFile(migrationLockPath, Date.now().toString(), "utf-8");
|
|
12773
12787
|
}
|
|
12774
12788
|
async function removeMigrationLock() {
|
|
12789
|
+
const { migrationLockPath } = getPortableRegistryPaths();
|
|
12775
12790
|
try {
|
|
12776
|
-
await unlink(
|
|
12791
|
+
await unlink(migrationLockPath);
|
|
12777
12792
|
} catch {}
|
|
12778
12793
|
}
|
|
12779
12794
|
async function readPortableRegistry() {
|
|
12780
12795
|
return readPortableRegistryInternal({ persistStaleV3Repair: true });
|
|
12781
12796
|
}
|
|
12782
12797
|
async function readPortableRegistryInternal(options2) {
|
|
12798
|
+
const { registryPath } = getPortableRegistryPaths();
|
|
12783
12799
|
try {
|
|
12784
|
-
const content = await readFile2(
|
|
12800
|
+
const content = await readFile2(registryPath, "utf-8");
|
|
12785
12801
|
let data;
|
|
12786
12802
|
try {
|
|
12787
12803
|
data = JSON.parse(content);
|
|
@@ -12850,15 +12866,16 @@ async function readPortableRegistryWithinRegistryLock() {
|
|
|
12850
12866
|
return readPortableRegistryInternal({ persistStaleV3Repair: false });
|
|
12851
12867
|
}
|
|
12852
12868
|
async function writePortableRegistry(registry) {
|
|
12853
|
-
const
|
|
12869
|
+
const { registryPath } = getPortableRegistryPaths();
|
|
12870
|
+
const dir = dirname(registryPath);
|
|
12854
12871
|
if (!existsSync2(dir)) {
|
|
12855
12872
|
await mkdir(dir, { recursive: true });
|
|
12856
12873
|
}
|
|
12857
12874
|
const normalizedRegistry = normalizePortableRegistryChecksums(registry);
|
|
12858
|
-
const tempPath = `${
|
|
12875
|
+
const tempPath = `${registryPath}.tmp-${process.pid}-${Date.now()}`;
|
|
12859
12876
|
try {
|
|
12860
12877
|
await writeFile(tempPath, JSON.stringify(normalizedRegistry, null, 2), "utf-8");
|
|
12861
|
-
await rename(tempPath,
|
|
12878
|
+
await rename(tempPath, registryPath);
|
|
12862
12879
|
} catch (error) {
|
|
12863
12880
|
try {
|
|
12864
12881
|
await unlink(tempPath);
|
|
@@ -12867,14 +12884,15 @@ async function writePortableRegistry(registry) {
|
|
|
12867
12884
|
}
|
|
12868
12885
|
}
|
|
12869
12886
|
async function withRegistryLock(operation) {
|
|
12870
|
-
const
|
|
12887
|
+
const { registryLockPath } = getPortableRegistryPaths();
|
|
12888
|
+
const lockDir = dirname(registryLockPath);
|
|
12871
12889
|
if (!existsSync2(lockDir)) {
|
|
12872
12890
|
await mkdir(lockDir, { recursive: true });
|
|
12873
12891
|
}
|
|
12874
|
-
if (!existsSync2(
|
|
12875
|
-
await writeFile(
|
|
12892
|
+
if (!existsSync2(registryLockPath)) {
|
|
12893
|
+
await writeFile(registryLockPath, "", "utf-8");
|
|
12876
12894
|
}
|
|
12877
|
-
const release = await import_proper_lockfile.default.lock(
|
|
12895
|
+
const release = await import_proper_lockfile.default.lock(registryLockPath, {
|
|
12878
12896
|
realpath: false,
|
|
12879
12897
|
retries: {
|
|
12880
12898
|
retries: 5,
|
|
@@ -12975,17 +12993,12 @@ async function syncPortableRegistry() {
|
|
|
12975
12993
|
return { removed };
|
|
12976
12994
|
});
|
|
12977
12995
|
}
|
|
12978
|
-
var import_proper_lockfile,
|
|
12996
|
+
var import_proper_lockfile, PortableInstallationSchema, PortableRegistrySchema, PortableInstallationSchemaV3, PortableRegistrySchemaV3, RepairablePortableRegistrySchemaV3, LegacyInstallationSchema, LegacyRegistrySchema;
|
|
12979
12997
|
var init_portable_registry = __esm(() => {
|
|
12980
12998
|
init_zod();
|
|
12981
12999
|
init_logger();
|
|
12982
13000
|
init_checksum_utils();
|
|
12983
13001
|
import_proper_lockfile = __toESM(require_proper_lockfile(), 1);
|
|
12984
|
-
home2 = homedir3();
|
|
12985
|
-
REGISTRY_PATH = join2(home2, ".claudekit", "portable-registry.json");
|
|
12986
|
-
REGISTRY_LOCK_PATH = join2(home2, ".claudekit", "portable-registry.lock");
|
|
12987
|
-
LEGACY_REGISTRY_PATH = join2(home2, ".claudekit", "skill-registry.json");
|
|
12988
|
-
MIGRATION_LOCK_PATH = join2(home2, ".claudekit", ".migration.lock");
|
|
12989
13002
|
PortableInstallationSchema = exports_external.object({
|
|
12990
13003
|
item: exports_external.string(),
|
|
12991
13004
|
type: exports_external.enum(["agent", "command", "skill", "config", "rules", "hooks"]),
|
|
@@ -13046,6 +13059,12 @@ import { existsSync as existsSync3 } from "node:fs";
|
|
|
13046
13059
|
import { mkdir as mkdir2, readFile as readFile3, realpath, unlink as unlink2, writeFile as writeFile2 } from "node:fs/promises";
|
|
13047
13060
|
import { homedir as homedir4 } from "node:os";
|
|
13048
13061
|
import { basename, dirname as dirname2, isAbsolute, join as join3, relative, resolve as resolve2 } from "node:path";
|
|
13062
|
+
function resolveCodexTomlRegistryDeps(deps) {
|
|
13063
|
+
return {
|
|
13064
|
+
...defaultCodexTomlRegistryDeps,
|
|
13065
|
+
...deps
|
|
13066
|
+
};
|
|
13067
|
+
}
|
|
13049
13068
|
async function ensureDir(filePath) {
|
|
13050
13069
|
const dir = dirname2(filePath);
|
|
13051
13070
|
if (!existsSync3(dir)) {
|
|
@@ -13299,12 +13318,13 @@ async function restoreFileSnapshots(snapshots) {
|
|
|
13299
13318
|
await restoreFileSnapshot(snapshots[index]);
|
|
13300
13319
|
}
|
|
13301
13320
|
}
|
|
13302
|
-
async function rollbackRegistryEntries(entries, portableType, provider, global2) {
|
|
13321
|
+
async function rollbackRegistryEntries(entries, portableType, provider, global2, registryDeps) {
|
|
13303
13322
|
for (let index = entries.length - 1;index >= 0; index -= 1) {
|
|
13304
|
-
await removePortableInstallation(entries[index].itemName, portableType, provider, global2);
|
|
13323
|
+
await registryDeps.removePortableInstallation(entries[index].itemName, portableType, provider, global2);
|
|
13305
13324
|
}
|
|
13306
13325
|
}
|
|
13307
|
-
async function installCodexToml(items, provider, portableType, options2) {
|
|
13326
|
+
async function installCodexToml(items, provider, portableType, options2, deps) {
|
|
13327
|
+
const registryDeps = resolveCodexTomlRegistryDeps(deps);
|
|
13308
13328
|
const config = providers[provider];
|
|
13309
13329
|
const pathConfig = config.agents;
|
|
13310
13330
|
if (!pathConfig) {
|
|
@@ -13487,7 +13507,7 @@ async function installCodexToml(items, provider, portableType, options2) {
|
|
|
13487
13507
|
}
|
|
13488
13508
|
await writeFile2(configTomlPath, mergeResult.content, "utf-8");
|
|
13489
13509
|
for (const install of pendingInstalls) {
|
|
13490
|
-
await addPortableInstallation(install.itemName, portableType, provider, options2.global, install.agentTomlPath, install.sourcePath, {
|
|
13510
|
+
await registryDeps.addPortableInstallation(install.itemName, portableType, provider, options2.global, install.agentTomlPath, install.sourcePath, {
|
|
13491
13511
|
sourceChecksum: install.sourceChecksum,
|
|
13492
13512
|
targetChecksum: install.targetChecksum,
|
|
13493
13513
|
ownedSections: [install.slug],
|
|
@@ -13506,7 +13526,7 @@ async function installCodexToml(items, provider, portableType, options2) {
|
|
|
13506
13526
|
let message = error instanceof Error ? error.message : "Unknown error";
|
|
13507
13527
|
if (addedRegistryEntries.length > 0) {
|
|
13508
13528
|
try {
|
|
13509
|
-
await rollbackRegistryEntries(addedRegistryEntries, portableType, provider, options2.global);
|
|
13529
|
+
await rollbackRegistryEntries(addedRegistryEntries, portableType, provider, options2.global, registryDeps);
|
|
13510
13530
|
} catch (rollbackRegistryError) {
|
|
13511
13531
|
const rollbackMessage = rollbackRegistryError instanceof Error ? rollbackRegistryError.message : "Unknown registry rollback error";
|
|
13512
13532
|
message = `${message}; registry rollback failed: ${rollbackMessage}`;
|
|
@@ -13632,7 +13652,7 @@ async function cleanupStaleCodexConfigEntries(options2) {
|
|
|
13632
13652
|
return [];
|
|
13633
13653
|
}
|
|
13634
13654
|
}
|
|
13635
|
-
var import_proper_lockfile2, SENTINEL_START = "# --- ck-managed-agents-start ---", SENTINEL_END = "# --- ck-managed-agents-end ---", MAX_WINDOWS_PATH_LENGTH = 240;
|
|
13655
|
+
var import_proper_lockfile2, SENTINEL_START = "# --- ck-managed-agents-start ---", SENTINEL_END = "# --- ck-managed-agents-end ---", MAX_WINDOWS_PATH_LENGTH = 240, defaultCodexTomlRegistryDeps;
|
|
13636
13656
|
var init_codex_toml_installer = __esm(() => {
|
|
13637
13657
|
init_logger();
|
|
13638
13658
|
init_checksum_utils();
|
|
@@ -13641,6 +13661,10 @@ var init_codex_toml_installer = __esm(() => {
|
|
|
13641
13661
|
init_portable_registry();
|
|
13642
13662
|
init_provider_registry();
|
|
13643
13663
|
import_proper_lockfile2 = __toESM(require_proper_lockfile(), 1);
|
|
13664
|
+
defaultCodexTomlRegistryDeps = {
|
|
13665
|
+
addPortableInstallation,
|
|
13666
|
+
removePortableInstallation
|
|
13667
|
+
};
|
|
13644
13668
|
});
|
|
13645
13669
|
|
|
13646
13670
|
// src/commands/portable/merge-single-sections.ts
|
|
@@ -13888,6 +13912,12 @@ function validateStrategyTargetPath(targetPath, options2) {
|
|
|
13888
13912
|
}
|
|
13889
13913
|
return null;
|
|
13890
13914
|
}
|
|
13915
|
+
function resolvePortableInstallerRegistryDeps(deps) {
|
|
13916
|
+
return {
|
|
13917
|
+
...defaultPortableInstallerRegistryDeps,
|
|
13918
|
+
...deps
|
|
13919
|
+
};
|
|
13920
|
+
}
|
|
13891
13921
|
function resolvePerFileOutputFilename(filename, pathConfig) {
|
|
13892
13922
|
if (pathConfig.nestedCommands !== false || !filename.includes("/")) {
|
|
13893
13923
|
return filename;
|
|
@@ -14049,7 +14079,7 @@ function buildPerFileCollisionSkips(items, provider, configDisplayName, basePath
|
|
|
14049
14079
|
}
|
|
14050
14080
|
return skipped;
|
|
14051
14081
|
}
|
|
14052
|
-
async function installPerFileItems(items, provider, portableType, pathConfig, options2) {
|
|
14082
|
+
async function installPerFileItems(items, provider, portableType, pathConfig, options2, registryDeps) {
|
|
14053
14083
|
const config = providers[provider];
|
|
14054
14084
|
const results = [];
|
|
14055
14085
|
let aggregateChars = 0;
|
|
@@ -14101,7 +14131,7 @@ async function installPerFileItems(items, provider, portableType, pathConfig, op
|
|
|
14101
14131
|
continue;
|
|
14102
14132
|
}
|
|
14103
14133
|
}
|
|
14104
|
-
const result = await installPerFile(item, provider, portableType, options2);
|
|
14134
|
+
const result = await installPerFile(item, provider, portableType, options2, registryDeps);
|
|
14105
14135
|
if (totalCharLimit && result.success && !result.skipped) {
|
|
14106
14136
|
aggregateChars += itemSize;
|
|
14107
14137
|
}
|
|
@@ -14189,7 +14219,7 @@ function parseYamlModesFile(content) {
|
|
|
14189
14219
|
}
|
|
14190
14220
|
return modes;
|
|
14191
14221
|
}
|
|
14192
|
-
async function installPerFile(item, provider, portableType, options2) {
|
|
14222
|
+
async function installPerFile(item, provider, portableType, options2, registryDeps) {
|
|
14193
14223
|
const config = providers[provider];
|
|
14194
14224
|
const typeKey = getProviderPathKeyForPortableType(portableType);
|
|
14195
14225
|
const pathConfig = config[typeKey];
|
|
@@ -14274,7 +14304,7 @@ async function installPerFile(item, provider, portableType, options2) {
|
|
|
14274
14304
|
await writeFile3(targetPath, result.content, "utf-8");
|
|
14275
14305
|
const sourceChecksum = computeContentChecksum(result.content);
|
|
14276
14306
|
const targetChecksum = sourceChecksum;
|
|
14277
|
-
await addPortableInstallation(item.name, portableType, provider, options2.global, targetPath, item.sourcePath, {
|
|
14307
|
+
await registryDeps.addPortableInstallation(item.name, portableType, provider, options2.global, targetPath, item.sourcePath, {
|
|
14278
14308
|
sourceChecksum,
|
|
14279
14309
|
targetChecksum,
|
|
14280
14310
|
installSource: "kit"
|
|
@@ -14307,7 +14337,7 @@ async function installPerFile(item, provider, portableType, options2) {
|
|
|
14307
14337
|
};
|
|
14308
14338
|
}
|
|
14309
14339
|
}
|
|
14310
|
-
async function installMergeSingle(items, provider, portableType, options2) {
|
|
14340
|
+
async function installMergeSingle(items, provider, portableType, options2, registryDeps) {
|
|
14311
14341
|
const config = providers[provider];
|
|
14312
14342
|
const typeKey = getProviderPathKeyForPortableType(portableType);
|
|
14313
14343
|
const pathConfig = config[typeKey];
|
|
@@ -14479,7 +14509,7 @@ ${sections.join(`
|
|
|
14479
14509
|
const sectionContent = newOwnedSections.get(sectionKey) || "";
|
|
14480
14510
|
const sourceChecksum = newSourceChecksums.get(sectionKey) ?? computeContentChecksum(item.body);
|
|
14481
14511
|
const targetChecksum = computeContentChecksum(sectionContent);
|
|
14482
|
-
await addPortableInstallation(item.name, portableType, provider, options2.global, targetPath, item.sourcePath, {
|
|
14512
|
+
await registryDeps.addPortableInstallation(item.name, portableType, provider, options2.global, targetPath, item.sourcePath, {
|
|
14483
14513
|
sourceChecksum,
|
|
14484
14514
|
targetChecksum,
|
|
14485
14515
|
ownedSections: [sectionKey],
|
|
@@ -14522,7 +14552,7 @@ ${sections.join(`
|
|
|
14522
14552
|
};
|
|
14523
14553
|
}
|
|
14524
14554
|
}
|
|
14525
|
-
async function installYamlMerge(items, provider, portableType, options2) {
|
|
14555
|
+
async function installYamlMerge(items, provider, portableType, options2, registryDeps) {
|
|
14526
14556
|
const config = providers[provider];
|
|
14527
14557
|
const typeKey = getProviderPathKeyForPortableType(portableType);
|
|
14528
14558
|
const pathConfig = config[typeKey];
|
|
@@ -14628,7 +14658,7 @@ async function installYamlMerge(items, provider, portableType, options2) {
|
|
|
14628
14658
|
for (const item of items) {
|
|
14629
14659
|
const result = convertItem(item, pathConfig.format, provider, { global: options2.global });
|
|
14630
14660
|
const sourceChecksum = computeContentChecksum(result.content);
|
|
14631
|
-
await addPortableInstallation(item.name, portableType, provider, options2.global, targetPath, item.sourcePath, {
|
|
14661
|
+
await registryDeps.addPortableInstallation(item.name, portableType, provider, options2.global, targetPath, item.sourcePath, {
|
|
14632
14662
|
sourceChecksum,
|
|
14633
14663
|
targetChecksum,
|
|
14634
14664
|
ownedSections,
|
|
@@ -14660,7 +14690,7 @@ async function installYamlMerge(items, provider, portableType, options2) {
|
|
|
14660
14690
|
};
|
|
14661
14691
|
}
|
|
14662
14692
|
}
|
|
14663
|
-
async function installJsonMerge(items, provider, portableType, options2) {
|
|
14693
|
+
async function installJsonMerge(items, provider, portableType, options2, registryDeps) {
|
|
14664
14694
|
const config = providers[provider];
|
|
14665
14695
|
const typeKey = getProviderPathKeyForPortableType(portableType);
|
|
14666
14696
|
const pathConfig = config[typeKey];
|
|
@@ -14838,7 +14868,7 @@ ${item.body}
|
|
|
14838
14868
|
for (const item of items) {
|
|
14839
14869
|
const result = convertItem(item, pathConfig.format, provider, { global: options2.global });
|
|
14840
14870
|
const sourceChecksum = computeContentChecksum(result.content);
|
|
14841
|
-
await addPortableInstallation(item.name, portableType, provider, options2.global, modesPath, item.sourcePath, {
|
|
14871
|
+
await registryDeps.addPortableInstallation(item.name, portableType, provider, options2.global, modesPath, item.sourcePath, {
|
|
14842
14872
|
sourceChecksum,
|
|
14843
14873
|
targetChecksum,
|
|
14844
14874
|
ownedSections,
|
|
@@ -14870,7 +14900,8 @@ ${item.body}
|
|
|
14870
14900
|
};
|
|
14871
14901
|
}
|
|
14872
14902
|
}
|
|
14873
|
-
async function installPortableItem(items, provider, portableType, options2) {
|
|
14903
|
+
async function installPortableItem(items, provider, portableType, options2, deps) {
|
|
14904
|
+
const registryDeps = resolvePortableInstallerRegistryDeps(deps);
|
|
14874
14905
|
const config = providers[provider];
|
|
14875
14906
|
const typeKey = getProviderPathKeyForPortableType(portableType);
|
|
14876
14907
|
const pathConfig = config[typeKey];
|
|
@@ -14885,17 +14916,17 @@ async function installPortableItem(items, provider, portableType, options2) {
|
|
|
14885
14916
|
}
|
|
14886
14917
|
switch (pathConfig.writeStrategy) {
|
|
14887
14918
|
case "merge-single":
|
|
14888
|
-
return installMergeSingle(items, provider, portableType, options2);
|
|
14919
|
+
return installMergeSingle(items, provider, portableType, options2, registryDeps);
|
|
14889
14920
|
case "yaml-merge":
|
|
14890
|
-
return installYamlMerge(items, provider, portableType, options2);
|
|
14921
|
+
return installYamlMerge(items, provider, portableType, options2, registryDeps);
|
|
14891
14922
|
case "json-merge":
|
|
14892
|
-
return installJsonMerge(items, provider, portableType, options2);
|
|
14923
|
+
return installJsonMerge(items, provider, portableType, options2, registryDeps);
|
|
14893
14924
|
case "codex-toml":
|
|
14894
|
-
return installCodexToml(items, provider, portableType, options2);
|
|
14925
|
+
return installCodexToml(items, provider, portableType, options2, registryDeps);
|
|
14895
14926
|
case "single-file":
|
|
14896
|
-
return installPerFile(items[0], provider, portableType, options2);
|
|
14927
|
+
return installPerFile(items[0], provider, portableType, options2, registryDeps);
|
|
14897
14928
|
case "codex-hooks":
|
|
14898
|
-
return installPerFile(items[0], provider, portableType, options2);
|
|
14929
|
+
return installPerFile(items[0], provider, portableType, options2, registryDeps);
|
|
14899
14930
|
case "per-file": {
|
|
14900
14931
|
const results = [];
|
|
14901
14932
|
let aggregateChars = 0;
|
|
@@ -14943,7 +14974,7 @@ async function installPortableItem(items, provider, portableType, options2) {
|
|
|
14943
14974
|
continue;
|
|
14944
14975
|
}
|
|
14945
14976
|
}
|
|
14946
|
-
const result = await installPerFile(item, provider, portableType, options2);
|
|
14977
|
+
const result = await installPerFile(item, provider, portableType, options2, registryDeps);
|
|
14947
14978
|
if (totalCharLimit && result.success && !result.skipped) {
|
|
14948
14979
|
aggregateChars += itemSize;
|
|
14949
14980
|
}
|
|
@@ -14979,7 +15010,8 @@ async function installPortableItem(items, provider, portableType, options2) {
|
|
|
14979
15010
|
}
|
|
14980
15011
|
}
|
|
14981
15012
|
}
|
|
14982
|
-
async function installPortableItems(items, targetProviders, portableType, options2) {
|
|
15013
|
+
async function installPortableItems(items, targetProviders, portableType, options2, deps) {
|
|
15014
|
+
const registryDeps = resolvePortableInstallerRegistryDeps(deps);
|
|
14983
15015
|
const uniqueProviders = Array.from(new Set(targetProviders));
|
|
14984
15016
|
const results = [];
|
|
14985
15017
|
for (const provider of uniqueProviders) {
|
|
@@ -14988,14 +15020,14 @@ async function installPortableItems(items, targetProviders, portableType, option
|
|
|
14988
15020
|
const pathConfig = config[typeKey];
|
|
14989
15021
|
const providerOptions = { ...options2 };
|
|
14990
15022
|
if (pathConfig?.writeStrategy === "per-file") {
|
|
14991
|
-
results.push(...await installPerFileItems(items, provider, portableType, pathConfig, providerOptions));
|
|
15023
|
+
results.push(...await installPerFileItems(items, provider, portableType, pathConfig, providerOptions, registryDeps));
|
|
14992
15024
|
continue;
|
|
14993
15025
|
}
|
|
14994
|
-
results.push(await installPortableItem(items, provider, portableType, providerOptions));
|
|
15026
|
+
results.push(await installPortableItem(items, provider, portableType, providerOptions, registryDeps));
|
|
14995
15027
|
}
|
|
14996
15028
|
return results;
|
|
14997
15029
|
}
|
|
14998
|
-
var import_proper_lockfile3, ClineCustomModeSchema, ClineCustomModesFileSchema;
|
|
15030
|
+
var import_proper_lockfile3, ClineCustomModeSchema, ClineCustomModesFileSchema, defaultPortableInstallerRegistryDeps;
|
|
14999
15031
|
var init_portable_installer = __esm(() => {
|
|
15000
15032
|
init_zod();
|
|
15001
15033
|
init_checksum_utils();
|
|
@@ -15018,6 +15050,9 @@ var init_portable_installer = __esm(() => {
|
|
|
15018
15050
|
ClineCustomModesFileSchema = exports_external.object({
|
|
15019
15051
|
customModes: exports_external.array(ClineCustomModeSchema).optional()
|
|
15020
15052
|
});
|
|
15053
|
+
defaultPortableInstallerRegistryDeps = {
|
|
15054
|
+
addPortableInstallation
|
|
15055
|
+
};
|
|
15021
15056
|
});
|
|
15022
15057
|
|
|
15023
15058
|
// src/commands/portable/types.ts
|
|
@@ -49406,7 +49441,7 @@ function resolveAgentDirs() {
|
|
|
49406
49441
|
dirs.push({ path: candidate, label: rel });
|
|
49407
49442
|
}
|
|
49408
49443
|
}
|
|
49409
|
-
const globalPath = join28(
|
|
49444
|
+
const globalPath = join28(home2, ".claude", "agents");
|
|
49410
49445
|
dirs.push({ path: globalPath, label: "~/.claude/agents" });
|
|
49411
49446
|
const seen = new Set;
|
|
49412
49447
|
return dirs.filter(({ path: path3 }) => {
|
|
@@ -49495,11 +49530,11 @@ function registerAgentsBrowserRoutes(app) {
|
|
|
49495
49530
|
res.status(404).json({ error: "Agent not found" });
|
|
49496
49531
|
});
|
|
49497
49532
|
}
|
|
49498
|
-
var
|
|
49533
|
+
var home2;
|
|
49499
49534
|
var init_agents_routes = __esm(() => {
|
|
49500
49535
|
init_frontmatter_parser();
|
|
49501
49536
|
init_kit_layout();
|
|
49502
|
-
|
|
49537
|
+
home2 = homedir15();
|
|
49503
49538
|
});
|
|
49504
49539
|
|
|
49505
49540
|
// src/schemas/ck-config.schema.json
|
|
@@ -51551,10 +51586,10 @@ function mergeServers(lists) {
|
|
|
51551
51586
|
function isSafeProjectPath(projectPath) {
|
|
51552
51587
|
if (projectPath.includes(".."))
|
|
51553
51588
|
return false;
|
|
51554
|
-
const
|
|
51589
|
+
const home3 = homedir23();
|
|
51555
51590
|
try {
|
|
51556
51591
|
const resolved = resolve14(projectPath);
|
|
51557
|
-
if (!resolved.startsWith(
|
|
51592
|
+
if (!resolved.startsWith(home3))
|
|
51558
51593
|
return false;
|
|
51559
51594
|
return existsSync21(resolved);
|
|
51560
51595
|
} catch {
|
|
@@ -51918,9 +51953,9 @@ async function copyHooksCompanionDirs(sourceDir, targetDir) {
|
|
|
51918
51953
|
function resolveSourceOrigin(sourcePath) {
|
|
51919
51954
|
if (!sourcePath)
|
|
51920
51955
|
return "global";
|
|
51921
|
-
const
|
|
51956
|
+
const home3 = homedir24();
|
|
51922
51957
|
const cwd2 = process.cwd();
|
|
51923
|
-
if (cwd2 ===
|
|
51958
|
+
if (cwd2 === home3)
|
|
51924
51959
|
return "global";
|
|
51925
51960
|
const cwdPrefix = cwd2.endsWith(sep6) ? cwd2 : `${cwd2}${sep6}`;
|
|
51926
51961
|
if (sourcePath === cwd2 || sourcePath.startsWith(cwdPrefix))
|
|
@@ -53856,22 +53891,29 @@ async function detectCodexCapabilities() {
|
|
|
53856
53891
|
if (process.env.CK_CODEX_COMPAT === "strict") {
|
|
53857
53892
|
return CODEX_CAPABILITY_TABLE[CODEX_CAPABILITY_TABLE.length - 1];
|
|
53858
53893
|
}
|
|
53859
|
-
|
|
53860
|
-
|
|
53861
|
-
|
|
53862
|
-
|
|
53863
|
-
|
|
53864
|
-
|
|
53894
|
+
const binaryCandidates = process.platform === "win32" ? ["codex.exe", "codex"] : ["codex"];
|
|
53895
|
+
let rawStdout = null;
|
|
53896
|
+
for (const bin of binaryCandidates) {
|
|
53897
|
+
try {
|
|
53898
|
+
const { stdout } = await execFileAsync5(bin, ["--version"], {
|
|
53899
|
+
timeout: 5000,
|
|
53900
|
+
encoding: "utf8"
|
|
53901
|
+
});
|
|
53902
|
+
rawStdout = stdout;
|
|
53903
|
+
break;
|
|
53904
|
+
} catch {}
|
|
53905
|
+
}
|
|
53906
|
+
if (rawStdout !== null) {
|
|
53907
|
+
const raw = rawStdout.trim();
|
|
53865
53908
|
const version = raw.replace(/^(codex\s+)?v?/i, "").trim();
|
|
53866
53909
|
const match = findCapabilitiesForVersion(version);
|
|
53867
53910
|
if (match)
|
|
53868
53911
|
return match;
|
|
53869
53912
|
logger.warning(`[!] Codex version ${version} not found in ck capability table; using most-restrictive baseline. Set CK_CODEX_COMPAT=optimistic to use newest known capabilities instead.`);
|
|
53870
53913
|
return process.env.CK_CODEX_COMPAT === "optimistic" ? CODEX_CAPABILITY_TABLE[0] : FALLBACK_CAPABILITIES;
|
|
53871
|
-
} catch {
|
|
53872
|
-
logger.warning("[!] Could not detect Codex version; using most-restrictive capability baseline. Set CK_CODEX_COMPAT=optimistic to use newest known capabilities instead.");
|
|
53873
|
-
return process.env.CK_CODEX_COMPAT === "optimistic" ? CODEX_CAPABILITY_TABLE[0] : FALLBACK_CAPABILITIES;
|
|
53874
53914
|
}
|
|
53915
|
+
logger.warning("[!] Could not detect Codex version; using most-restrictive capability baseline. Set CK_CODEX_COMPAT=optimistic to use newest known capabilities instead.");
|
|
53916
|
+
return process.env.CK_CODEX_COMPAT === "optimistic" ? CODEX_CAPABILITY_TABLE[0] : FALLBACK_CAPABILITIES;
|
|
53875
53917
|
}
|
|
53876
53918
|
function findCapabilitiesForVersion(version) {
|
|
53877
53919
|
const exact = CODEX_CAPABILITY_TABLE.find((entry) => entry.version === version);
|
|
@@ -54234,11 +54276,12 @@ function buildWrapperScript(originalPath, capabilities, hookTimeoutMs) {
|
|
|
54234
54276
|
const escapedOriginalPath = JSON.stringify(originalPath);
|
|
54235
54277
|
const scrubRulesJson = JSON.stringify(scrubRules);
|
|
54236
54278
|
const effectiveTimeout = hookTimeoutMs ?? 30000;
|
|
54237
|
-
return
|
|
54238
|
-
// AUTO-GENERATED by claudekit ck migrate — DO NOT EDIT
|
|
54279
|
+
return `// AUTO-GENERATED by claudekit ck migrate — DO NOT EDIT
|
|
54239
54280
|
// Codex hook compatibility wrapper for:
|
|
54240
54281
|
// ${originalPath}
|
|
54241
54282
|
//
|
|
54283
|
+
// INVOCATION: always call as \`node "<this-file>"\` — no shebang (Windows portability).
|
|
54284
|
+
// The hooks.json command field must prefix this wrapper with \`node\`.
|
|
54242
54285
|
// This wrapper spawns the original hook, sanitizes its JSON output
|
|
54243
54286
|
// to remove fields that Codex does not support, then re-emits to stdout.
|
|
54244
54287
|
// To regenerate: run \`ck migrate\` again.
|
|
@@ -54450,25 +54493,46 @@ function scrubHookEntry(entry, event, capabilities, pathRewrite) {
|
|
|
54450
54493
|
}
|
|
54451
54494
|
function rewriteCommandPath(command, pathRewrite) {
|
|
54452
54495
|
if (pathRewrite.commandSubstitutions && pathRewrite.commandSubstitutions.size > 0) {
|
|
54453
|
-
const
|
|
54496
|
+
const home3 = homedir26();
|
|
54497
|
+
const homeForward = home3.replace(/\\/g, "/");
|
|
54498
|
+
const normalizeSlashesStr = (s) => s.replace(/\\/g, "/");
|
|
54454
54499
|
for (const [originalAbsPath, wrapperAbsPath] of pathRewrite.commandSubstitutions) {
|
|
54455
|
-
const
|
|
54456
|
-
|
|
54457
|
-
|
|
54458
|
-
|
|
54459
|
-
|
|
54500
|
+
const originalAbsForward = normalizeSlashesStr(originalAbsPath);
|
|
54501
|
+
let relFromHome = null;
|
|
54502
|
+
if (originalAbsForward.startsWith(`${homeForward}/`)) {
|
|
54503
|
+
relFromHome = originalAbsForward.slice(homeForward.length + 1);
|
|
54504
|
+
} else if (originalAbsForward === homeForward) {
|
|
54505
|
+
relFromHome = "";
|
|
54506
|
+
}
|
|
54507
|
+
const candidates = [
|
|
54508
|
+
originalAbsForward,
|
|
54509
|
+
originalAbsPath
|
|
54510
|
+
];
|
|
54511
|
+
if (relFromHome !== null && relFromHome !== "") {
|
|
54512
|
+
candidates.push(`$HOME/${relFromHome}`);
|
|
54513
|
+
candidates.push(`~/${relFromHome}`);
|
|
54514
|
+
candidates.push(`%USERPROFILE%/${relFromHome}`);
|
|
54515
|
+
candidates.push(`\${HOME}/${relFromHome}`);
|
|
54516
|
+
}
|
|
54517
|
+
const commandNorm = normalizeSlashesStr(command);
|
|
54460
54518
|
for (const candidate of candidates) {
|
|
54461
|
-
|
|
54462
|
-
|
|
54519
|
+
const candidateNorm = normalizeSlashesStr(candidate);
|
|
54520
|
+
if (commandNorm.includes(candidateNorm)) {
|
|
54521
|
+
const wrapperForward = normalizeSlashesStr(wrapperAbsPath);
|
|
54522
|
+
return commandNorm.replaceAll(candidateNorm, wrapperForward);
|
|
54463
54523
|
}
|
|
54464
54524
|
}
|
|
54465
54525
|
}
|
|
54466
54526
|
}
|
|
54467
|
-
const
|
|
54468
|
-
const
|
|
54527
|
+
const normalizeSlashes = (s) => s.replace(/\\/g, "/");
|
|
54528
|
+
const src = normalizeSlashes(pathRewrite.sourceDir.endsWith("/") || pathRewrite.sourceDir.endsWith("\\") ? pathRewrite.sourceDir : `${pathRewrite.sourceDir}/`);
|
|
54529
|
+
const tgt = normalizeSlashes(pathRewrite.targetDir.endsWith("/") || pathRewrite.targetDir.endsWith("\\") ? pathRewrite.targetDir : `${pathRewrite.targetDir}/`);
|
|
54469
54530
|
if (src === tgt)
|
|
54470
54531
|
return command;
|
|
54471
|
-
|
|
54532
|
+
const normalizedCommand = normalizeSlashes(command);
|
|
54533
|
+
if (!normalizedCommand.includes(src))
|
|
54534
|
+
return command;
|
|
54535
|
+
return normalizedCommand.replaceAll(src, tgt);
|
|
54472
54536
|
}
|
|
54473
54537
|
var init_claude_to_codex_hooks = () => {};
|
|
54474
54538
|
|
|
@@ -54897,17 +54961,6 @@ async function migrateHooksSettingsForCodex(options2) {
|
|
|
54897
54961
|
installedHookAbsolutePaths,
|
|
54898
54962
|
global: isGlobal
|
|
54899
54963
|
} = options2;
|
|
54900
|
-
if (process.platform === "win32") {
|
|
54901
|
-
return {
|
|
54902
|
-
status: "skipped-windows",
|
|
54903
|
-
success: true,
|
|
54904
|
-
backupPath: null,
|
|
54905
|
-
hooksRegistered: 0,
|
|
54906
|
-
message: "[!] Codex hook installation skipped: Codex CLI hooks are temporarily disabled on Windows.",
|
|
54907
|
-
sourceSettingsPath: null,
|
|
54908
|
-
targetSettingsPath: null
|
|
54909
|
-
};
|
|
54910
|
-
}
|
|
54911
54964
|
if (installedHookFiles.length === 0) {
|
|
54912
54965
|
return {
|
|
54913
54966
|
status: "no-installed-files",
|
|
@@ -55432,14 +55485,15 @@ var init_portable_manifest = __esm(() => {
|
|
|
55432
55485
|
function shouldBackfillRegistry(action) {
|
|
55433
55486
|
return action.action === "skip" && action.backfillRegistry === true && typeof action.targetPath === "string" && action.targetPath.length > 0 && typeof action.sourceChecksum === "string" && !isUnknownChecksum(action.sourceChecksum) && typeof action.currentTargetChecksum === "string" && !isUnknownChecksum(action.currentTargetChecksum);
|
|
55434
55487
|
}
|
|
55435
|
-
async function backfillRegistryChecksums(actions, registry) {
|
|
55488
|
+
async function backfillRegistryChecksums(actions, registry, deps) {
|
|
55489
|
+
const addInstallation = deps?.addPortableInstallation ?? addPortableInstallation;
|
|
55436
55490
|
for (const action of actions) {
|
|
55437
55491
|
if (!shouldBackfillRegistry(action))
|
|
55438
55492
|
continue;
|
|
55439
55493
|
const registryEntry = registry.installations.find((entry) => entry.item === action.item && entry.type === action.type && entry.provider === action.provider && entry.global === action.global);
|
|
55440
55494
|
if (!registryEntry)
|
|
55441
55495
|
continue;
|
|
55442
|
-
await
|
|
55496
|
+
await addInstallation(action.item, action.type, action.provider, action.global, action.targetPath, registryEntry.sourcePath, {
|
|
55443
55497
|
sourceChecksum: action.sourceChecksum,
|
|
55444
55498
|
targetChecksum: action.currentTargetChecksum,
|
|
55445
55499
|
ownedSections: registryEntry.ownedSections,
|
|
@@ -56728,6 +56782,12 @@ import { existsSync as existsSync30 } from "node:fs";
|
|
|
56728
56782
|
import { readFile as readFile26, rm as rm8 } from "node:fs/promises";
|
|
56729
56783
|
import { homedir as homedir29 } from "node:os";
|
|
56730
56784
|
import { basename as basename17, join as join46, resolve as resolve23 } from "node:path";
|
|
56785
|
+
function resolveRegistryDeps(deps) {
|
|
56786
|
+
return {
|
|
56787
|
+
...defaultRegistryDeps,
|
|
56788
|
+
...deps?.registry
|
|
56789
|
+
};
|
|
56790
|
+
}
|
|
56731
56791
|
function isDisallowedControlCode(codePoint) {
|
|
56732
56792
|
return codePoint >= 0 && codePoint <= 8 || codePoint >= 11 && codePoint <= 31 || codePoint >= 127 && codePoint <= 159;
|
|
56733
56793
|
}
|
|
@@ -56962,7 +57022,7 @@ async function executePlanDeleteAction(action, options2) {
|
|
|
56962
57022
|
if (!shouldPreserveTarget && action.targetPath && existsSync30(action.targetPath)) {
|
|
56963
57023
|
await rm8(action.targetPath, { recursive: true, force: true });
|
|
56964
57024
|
}
|
|
56965
|
-
await removePortableInstallation(action.item, action.type, action.provider, action.global, action.targetPath ? { path: action.targetPath } : undefined);
|
|
57025
|
+
await (options2?.removePortableInstallation ?? removePortableInstallation)(action.item, action.type, action.provider, action.global, action.targetPath ? { path: action.targetPath } : undefined);
|
|
56966
57026
|
return {
|
|
56967
57027
|
provider: action.provider,
|
|
56968
57028
|
providerDisplayName: providers[action.provider]?.displayName || action.provider,
|
|
@@ -57333,7 +57393,8 @@ function getCapabilities(provider) {
|
|
|
57333
57393
|
hooks: config.hooks !== null
|
|
57334
57394
|
};
|
|
57335
57395
|
}
|
|
57336
|
-
function registerMigrationRoutes(app) {
|
|
57396
|
+
function registerMigrationRoutes(app, deps) {
|
|
57397
|
+
const registryDeps = resolveRegistryDeps(deps);
|
|
57337
57398
|
app.get("/api/migrate/providers", async (_req, res) => {
|
|
57338
57399
|
try {
|
|
57339
57400
|
const detected = new Set(await detectInstalledProviders());
|
|
@@ -57367,12 +57428,12 @@ function registerMigrationRoutes(app) {
|
|
|
57367
57428
|
};
|
|
57368
57429
|
const discovered = await discoverMigrationItems(includeAll);
|
|
57369
57430
|
const cwd2 = process.cwd();
|
|
57370
|
-
const
|
|
57431
|
+
const home3 = homedir29();
|
|
57371
57432
|
res.status(200).json({
|
|
57372
57433
|
cwd: cwd2,
|
|
57373
57434
|
targetPaths: {
|
|
57374
57435
|
project: join46(cwd2, ".claude"),
|
|
57375
|
-
global: join46(
|
|
57436
|
+
global: join46(home3, ".claude")
|
|
57376
57437
|
},
|
|
57377
57438
|
sourcePaths: discovered.sourcePaths,
|
|
57378
57439
|
sourceOrigins: {
|
|
@@ -57541,7 +57602,7 @@ function registerMigrationRoutes(app) {
|
|
|
57541
57602
|
warnReadFailure("hook", hook.name, error);
|
|
57542
57603
|
}
|
|
57543
57604
|
}
|
|
57544
|
-
const registry = await readPortableRegistry();
|
|
57605
|
+
const registry = await registryDeps.readPortableRegistry();
|
|
57545
57606
|
const targetStates = await buildTargetStates(registry.installations, {
|
|
57546
57607
|
onReadFailure: (entryPath, error) => warnReadFailure("registry-target", entryPath, error)
|
|
57547
57608
|
});
|
|
@@ -57650,7 +57711,7 @@ function registerMigrationRoutes(app) {
|
|
|
57650
57711
|
}
|
|
57651
57712
|
const configSource = sourceParsed.value;
|
|
57652
57713
|
const discovered = await discoverMigrationItems(include, configSource);
|
|
57653
|
-
const registry = await readPortableRegistry();
|
|
57714
|
+
const registry = await registryDeps.readPortableRegistry();
|
|
57654
57715
|
const candidates = [];
|
|
57655
57716
|
if (include.agents) {
|
|
57656
57717
|
addCandidates(discovered.agents.map((a3) => ({
|
|
@@ -57903,15 +57964,18 @@ function registerMigrationRoutes(app) {
|
|
|
57903
57964
|
const writtenPaths = new Set(allResults.filter((r2) => r2.success && !r2.skipped && r2.path.length > 0).map((r2) => resolve23(r2.path)));
|
|
57904
57965
|
for (const deleteAction of deleteActions) {
|
|
57905
57966
|
const deleteResult = await executePlanDeleteAction(deleteAction, {
|
|
57906
|
-
preservePaths: writtenPaths
|
|
57967
|
+
preservePaths: writtenPaths,
|
|
57968
|
+
removePortableInstallation: registryDeps.removePortableInstallation
|
|
57907
57969
|
});
|
|
57908
57970
|
deleteResult.portableType = deleteAction.type;
|
|
57909
57971
|
deleteResult.itemName = deleteAction.item;
|
|
57910
57972
|
allResults.push(deleteResult);
|
|
57911
57973
|
}
|
|
57912
57974
|
try {
|
|
57913
|
-
const registry = await readPortableRegistry();
|
|
57914
|
-
await backfillRegistryChecksums(plan.actions, registry
|
|
57975
|
+
const registry = await registryDeps.readPortableRegistry();
|
|
57976
|
+
await backfillRegistryChecksums(plan.actions, registry, {
|
|
57977
|
+
addPortableInstallation: registryDeps.addPortableInstallation
|
|
57978
|
+
});
|
|
57915
57979
|
} catch {}
|
|
57916
57980
|
for (const provider of allPlanProviders) {
|
|
57917
57981
|
if (providers[provider]?.agents?.writeStrategy !== "codex-toml")
|
|
@@ -57928,7 +57992,7 @@ function registerMigrationRoutes(app) {
|
|
|
57928
57992
|
});
|
|
57929
57993
|
if (staleSlugs.length > 0) {
|
|
57930
57994
|
const staleSlugSet = new Set(staleSlugs.map((s) => `${s}.toml`));
|
|
57931
|
-
await removeInstallationsByFilter((i) => i.type === "agent" && i.provider === provider && i.global === scope && staleSlugSet.has(basename17(i.path)));
|
|
57995
|
+
await registryDeps.removeInstallationsByFilter((i) => i.type === "agent" && i.provider === provider && i.global === scope && staleSlugSet.has(basename17(i.path)));
|
|
57932
57996
|
}
|
|
57933
57997
|
}
|
|
57934
57998
|
}
|
|
@@ -57939,7 +58003,7 @@ function registerMigrationRoutes(app) {
|
|
|
57939
58003
|
const kitRoot = (agentSrc ? resolve23(agentSrc, "..") : null) ?? (cmdSrc ? resolve23(cmdSrc, "..") : null) ?? (skillSrc ? resolve23(skillSrc, "..") : null) ?? null;
|
|
57940
58004
|
const manifest = kitRoot ? await loadPortableManifest(kitRoot) : null;
|
|
57941
58005
|
if (manifest?.cliVersion) {
|
|
57942
|
-
await updateAppliedManifestVersion(manifest.cliVersion);
|
|
58006
|
+
await registryDeps.updateAppliedManifestVersion(manifest.cliVersion);
|
|
57943
58007
|
}
|
|
57944
58008
|
} catch {}
|
|
57945
58009
|
const responseResults2 = [...allResults, ...hookRegistrationResults2];
|
|
@@ -58141,7 +58205,7 @@ function registerMigrationRoutes(app) {
|
|
|
58141
58205
|
}
|
|
58142
58206
|
});
|
|
58143
58207
|
}
|
|
58144
|
-
var MIGRATION_TYPES, MAX_PROVIDER_COUNT = 20, MAX_PLAN_ACTIONS = 5000, ALLOWED_CONFIG_SOURCE_KEYS, CONFLICT_RESOLUTION_SCHEMA, RECONCILE_ACTION_SCHEMA, RECONCILE_BANNER_SCHEMA, RECONCILE_PLAN_SCHEMA, PLAN_EXECUTE_PAYLOAD_SCHEMA, PLURAL_TO_SINGULAR, shellHookWarningShown = false;
|
|
58208
|
+
var defaultRegistryDeps, MIGRATION_TYPES, MAX_PROVIDER_COUNT = 20, MAX_PLAN_ACTIONS = 5000, ALLOWED_CONFIG_SOURCE_KEYS, CONFLICT_RESOLUTION_SCHEMA, RECONCILE_ACTION_SCHEMA, RECONCILE_BANNER_SCHEMA, RECONCILE_PLAN_SCHEMA, PLAN_EXECUTE_PAYLOAD_SCHEMA, PLURAL_TO_SINGULAR, shellHookWarningShown = false;
|
|
58145
58209
|
var init_migration_routes = __esm(() => {
|
|
58146
58210
|
init_agents_discovery();
|
|
58147
58211
|
init_commands_discovery();
|
|
@@ -58163,6 +58227,13 @@ var init_migration_routes = __esm(() => {
|
|
|
58163
58227
|
init_logger();
|
|
58164
58228
|
init_zod();
|
|
58165
58229
|
init_migration_result_utils();
|
|
58230
|
+
defaultRegistryDeps = {
|
|
58231
|
+
addPortableInstallation,
|
|
58232
|
+
readPortableRegistry,
|
|
58233
|
+
removeInstallationsByFilter,
|
|
58234
|
+
removePortableInstallation,
|
|
58235
|
+
updateAppliedManifestVersion
|
|
58236
|
+
};
|
|
58166
58237
|
MIGRATION_TYPES = [
|
|
58167
58238
|
"agents",
|
|
58168
58239
|
"commands",
|
|
@@ -60998,8 +61069,8 @@ function toDateStr(d3) {
|
|
|
60998
61069
|
return `${y3}-${m2}-${day}`;
|
|
60999
61070
|
}
|
|
61000
61071
|
async function scanActivityMetrics(periodDays) {
|
|
61001
|
-
const
|
|
61002
|
-
const projectsDir2 = join56(
|
|
61072
|
+
const home3 = homedir33();
|
|
61073
|
+
const projectsDir2 = join56(home3, ".claude", "projects");
|
|
61003
61074
|
const cutoff = new Date;
|
|
61004
61075
|
cutoff.setDate(cutoff.getDate() - periodDays);
|
|
61005
61076
|
const dailyMap = new Map;
|
|
@@ -61069,29 +61140,29 @@ async function scanActivityMetrics(periodDays) {
|
|
|
61069
61140
|
return { totalSessions, projects: projectActivities, dailyCounts };
|
|
61070
61141
|
}
|
|
61071
61142
|
async function resolveSessionDir(projectId) {
|
|
61072
|
-
const
|
|
61143
|
+
const home3 = homedir33();
|
|
61073
61144
|
if (projectId.startsWith("discovered-")) {
|
|
61074
61145
|
try {
|
|
61075
61146
|
const encodedPathB64 = projectId.slice("discovered-".length);
|
|
61076
61147
|
const projectPath = Buffer.from(encodedPathB64, "base64url").toString("utf-8");
|
|
61077
61148
|
const claudeEncoded = encodePath(projectPath);
|
|
61078
|
-
return join56(
|
|
61149
|
+
return join56(home3, ".claude", "projects", claudeEncoded);
|
|
61079
61150
|
} catch {
|
|
61080
61151
|
return null;
|
|
61081
61152
|
}
|
|
61082
61153
|
}
|
|
61083
61154
|
if (projectId === "current") {
|
|
61084
61155
|
const cwdEncoded = encodePath(process.cwd());
|
|
61085
|
-
return join56(
|
|
61156
|
+
return join56(home3, ".claude", "projects", cwdEncoded);
|
|
61086
61157
|
}
|
|
61087
61158
|
if (projectId === "global") {
|
|
61088
|
-
const globalEncoded = encodePath(join56(
|
|
61089
|
-
return join56(
|
|
61159
|
+
const globalEncoded = encodePath(join56(home3, ".claude"));
|
|
61160
|
+
return join56(home3, ".claude", "projects", globalEncoded);
|
|
61090
61161
|
}
|
|
61091
61162
|
const registered = await ProjectsRegistryManager.getProject(projectId);
|
|
61092
61163
|
if (registered) {
|
|
61093
61164
|
const claudeEncoded = encodePath(registered.path);
|
|
61094
|
-
return join56(
|
|
61165
|
+
return join56(home3, ".claude", "projects", claudeEncoded);
|
|
61095
61166
|
}
|
|
61096
61167
|
return null;
|
|
61097
61168
|
}
|
|
@@ -61243,8 +61314,8 @@ async function parseSessionDetail(filePath, limit, offset) {
|
|
|
61243
61314
|
}
|
|
61244
61315
|
function registerSessionRoutes(app) {
|
|
61245
61316
|
app.get("/api/sessions", async (_req, res) => {
|
|
61246
|
-
const
|
|
61247
|
-
const projectsDir2 = join56(
|
|
61317
|
+
const home3 = homedir33();
|
|
61318
|
+
const projectsDir2 = join56(home3, ".claude", "projects");
|
|
61248
61319
|
if (!existsSync38(projectsDir2)) {
|
|
61249
61320
|
res.json({ projects: [] });
|
|
61250
61321
|
return;
|
|
@@ -61927,10 +61998,10 @@ function hasOpenCodeInstallSignal2() {
|
|
|
61927
61998
|
join59(process.cwd(), "opencode.jsonc"),
|
|
61928
61999
|
join59(process.cwd(), ".opencode/agents"),
|
|
61929
62000
|
join59(process.cwd(), ".opencode/commands"),
|
|
61930
|
-
join59(
|
|
61931
|
-
join59(
|
|
61932
|
-
join59(
|
|
61933
|
-
join59(
|
|
62001
|
+
join59(home3, ".config/opencode/AGENTS.md"),
|
|
62002
|
+
join59(home3, ".config/opencode/agents"),
|
|
62003
|
+
join59(home3, ".config/opencode/commands"),
|
|
62004
|
+
join59(home3, ".opencode", "bin", OPENCODE_BINARY_NAME2)
|
|
61934
62005
|
]);
|
|
61935
62006
|
}
|
|
61936
62007
|
async function detectInstalledAgents() {
|
|
@@ -61954,108 +62025,108 @@ function isSkillInstalled(skillName, agent, options2) {
|
|
|
61954
62025
|
const installPath = getInstallPath(skillName, agent, options2);
|
|
61955
62026
|
return existsSync39(installPath);
|
|
61956
62027
|
}
|
|
61957
|
-
var
|
|
62028
|
+
var home3, OPENCODE_BINARY_NAME2, agents;
|
|
61958
62029
|
var init_agents = __esm(() => {
|
|
61959
|
-
|
|
62030
|
+
home3 = homedir37();
|
|
61960
62031
|
OPENCODE_BINARY_NAME2 = platform5() === "win32" ? "opencode.exe" : "opencode";
|
|
61961
62032
|
agents = {
|
|
61962
62033
|
"claude-code": {
|
|
61963
62034
|
name: "claude-code",
|
|
61964
62035
|
displayName: "Claude Code",
|
|
61965
62036
|
projectPath: ".claude/skills",
|
|
61966
|
-
globalPath: join59(
|
|
61967
|
-
detect: async () => existsSync39(join59(
|
|
62037
|
+
globalPath: join59(home3, ".claude/skills"),
|
|
62038
|
+
detect: async () => existsSync39(join59(home3, ".claude"))
|
|
61968
62039
|
},
|
|
61969
62040
|
cursor: {
|
|
61970
62041
|
name: "cursor",
|
|
61971
62042
|
displayName: "Cursor",
|
|
61972
62043
|
projectPath: ".cursor/skills",
|
|
61973
|
-
globalPath: join59(
|
|
61974
|
-
detect: async () => existsSync39(join59(
|
|
62044
|
+
globalPath: join59(home3, ".cursor/skills"),
|
|
62045
|
+
detect: async () => existsSync39(join59(home3, ".cursor"))
|
|
61975
62046
|
},
|
|
61976
62047
|
codex: {
|
|
61977
62048
|
name: "codex",
|
|
61978
62049
|
displayName: "Codex",
|
|
61979
62050
|
projectPath: ".codex/skills",
|
|
61980
|
-
globalPath: join59(
|
|
61981
|
-
detect: async () => existsSync39(join59(
|
|
62051
|
+
globalPath: join59(home3, ".codex/skills"),
|
|
62052
|
+
detect: async () => existsSync39(join59(home3, ".codex"))
|
|
61982
62053
|
},
|
|
61983
62054
|
opencode: {
|
|
61984
62055
|
name: "opencode",
|
|
61985
62056
|
displayName: "OpenCode",
|
|
61986
62057
|
projectPath: ".claude/skills",
|
|
61987
|
-
globalPath: join59(
|
|
62058
|
+
globalPath: join59(home3, ".claude/skills"),
|
|
61988
62059
|
detect: async () => hasOpenCodeInstallSignal2()
|
|
61989
62060
|
},
|
|
61990
62061
|
goose: {
|
|
61991
62062
|
name: "goose",
|
|
61992
62063
|
displayName: "Goose",
|
|
61993
62064
|
projectPath: ".goose/skills",
|
|
61994
|
-
globalPath: join59(
|
|
61995
|
-
detect: async () => existsSync39(join59(
|
|
62065
|
+
globalPath: join59(home3, ".config/goose/skills"),
|
|
62066
|
+
detect: async () => existsSync39(join59(home3, ".config/goose"))
|
|
61996
62067
|
},
|
|
61997
62068
|
"gemini-cli": {
|
|
61998
62069
|
name: "gemini-cli",
|
|
61999
62070
|
displayName: "Gemini CLI",
|
|
62000
62071
|
projectPath: ".agents/skills",
|
|
62001
|
-
globalPath: join59(
|
|
62002
|
-
detect: async () => existsSync39(join59(
|
|
62072
|
+
globalPath: join59(home3, ".agents/skills"),
|
|
62073
|
+
detect: async () => existsSync39(join59(home3, ".gemini"))
|
|
62003
62074
|
},
|
|
62004
62075
|
antigravity: {
|
|
62005
62076
|
name: "antigravity",
|
|
62006
62077
|
displayName: "Antigravity",
|
|
62007
62078
|
projectPath: ".agent/skills",
|
|
62008
|
-
globalPath: join59(
|
|
62009
|
-
detect: async () => existsSync39(join59(process.cwd(), ".agent")) || existsSync39(join59(
|
|
62079
|
+
globalPath: join59(home3, ".gemini/antigravity/skills"),
|
|
62080
|
+
detect: async () => existsSync39(join59(process.cwd(), ".agent")) || existsSync39(join59(home3, ".gemini/antigravity"))
|
|
62010
62081
|
},
|
|
62011
62082
|
"github-copilot": {
|
|
62012
62083
|
name: "github-copilot",
|
|
62013
62084
|
displayName: "GitHub Copilot",
|
|
62014
62085
|
projectPath: ".github/skills",
|
|
62015
|
-
globalPath: join59(
|
|
62016
|
-
detect: async () => existsSync39(join59(
|
|
62086
|
+
globalPath: join59(home3, ".copilot/skills"),
|
|
62087
|
+
detect: async () => existsSync39(join59(home3, ".copilot"))
|
|
62017
62088
|
},
|
|
62018
62089
|
amp: {
|
|
62019
62090
|
name: "amp",
|
|
62020
62091
|
displayName: "Amp",
|
|
62021
62092
|
projectPath: ".agents/skills",
|
|
62022
|
-
globalPath: join59(
|
|
62023
|
-
detect: async () => existsSync39(join59(
|
|
62093
|
+
globalPath: join59(home3, ".config/agents/skills"),
|
|
62094
|
+
detect: async () => existsSync39(join59(home3, ".config/amp"))
|
|
62024
62095
|
},
|
|
62025
62096
|
kilo: {
|
|
62026
62097
|
name: "kilo",
|
|
62027
62098
|
displayName: "Kilo Code",
|
|
62028
62099
|
projectPath: ".kilocode/skills",
|
|
62029
|
-
globalPath: join59(
|
|
62030
|
-
detect: async () => existsSync39(join59(
|
|
62100
|
+
globalPath: join59(home3, ".kilocode/skills"),
|
|
62101
|
+
detect: async () => existsSync39(join59(home3, ".kilocode"))
|
|
62031
62102
|
},
|
|
62032
62103
|
roo: {
|
|
62033
62104
|
name: "roo",
|
|
62034
62105
|
displayName: "Roo Code",
|
|
62035
62106
|
projectPath: ".roo/skills",
|
|
62036
|
-
globalPath: join59(
|
|
62037
|
-
detect: async () => existsSync39(join59(
|
|
62107
|
+
globalPath: join59(home3, ".roo/skills"),
|
|
62108
|
+
detect: async () => existsSync39(join59(home3, ".roo"))
|
|
62038
62109
|
},
|
|
62039
62110
|
windsurf: {
|
|
62040
62111
|
name: "windsurf",
|
|
62041
62112
|
displayName: "Windsurf",
|
|
62042
62113
|
projectPath: ".windsurf/skills",
|
|
62043
|
-
globalPath: join59(
|
|
62044
|
-
detect: async () => existsSync39(join59(
|
|
62114
|
+
globalPath: join59(home3, ".codeium/windsurf/skills"),
|
|
62115
|
+
detect: async () => existsSync39(join59(home3, ".codeium/windsurf"))
|
|
62045
62116
|
},
|
|
62046
62117
|
cline: {
|
|
62047
62118
|
name: "cline",
|
|
62048
62119
|
displayName: "Cline",
|
|
62049
62120
|
projectPath: ".cline/skills",
|
|
62050
|
-
globalPath: join59(
|
|
62051
|
-
detect: async () => existsSync39(join59(
|
|
62121
|
+
globalPath: join59(home3, ".cline/skills"),
|
|
62122
|
+
detect: async () => existsSync39(join59(home3, ".cline"))
|
|
62052
62123
|
},
|
|
62053
62124
|
openhands: {
|
|
62054
62125
|
name: "openhands",
|
|
62055
62126
|
displayName: "OpenHands",
|
|
62056
62127
|
projectPath: ".openhands/skills",
|
|
62057
|
-
globalPath: join59(
|
|
62058
|
-
detect: async () => existsSync39(join59(
|
|
62128
|
+
globalPath: join59(home3, ".openhands/skills"),
|
|
62129
|
+
detect: async () => existsSync39(join59(home3, ".openhands"))
|
|
62059
62130
|
}
|
|
62060
62131
|
};
|
|
62061
62132
|
});
|
|
@@ -62096,15 +62167,15 @@ function migrateRegistryPaths(registry) {
|
|
|
62096
62167
|
}
|
|
62097
62168
|
async function readRegistry2() {
|
|
62098
62169
|
try {
|
|
62099
|
-
if (!existsSync40(
|
|
62170
|
+
if (!existsSync40(REGISTRY_PATH)) {
|
|
62100
62171
|
return { version: "1.0", installations: [] };
|
|
62101
62172
|
}
|
|
62102
|
-
const content = await readFile31(
|
|
62173
|
+
const content = await readFile31(REGISTRY_PATH, "utf-8");
|
|
62103
62174
|
const data = JSON.parse(content);
|
|
62104
62175
|
const registry = SkillRegistrySchema.parse(data);
|
|
62105
62176
|
if (migrateRegistryPaths(registry)) {
|
|
62106
62177
|
try {
|
|
62107
|
-
await writeFile15(
|
|
62178
|
+
await writeFile15(REGISTRY_PATH, JSON.stringify(registry, null, 2), "utf-8");
|
|
62108
62179
|
} catch {}
|
|
62109
62180
|
}
|
|
62110
62181
|
return registry;
|
|
@@ -62116,11 +62187,11 @@ async function readRegistry2() {
|
|
|
62116
62187
|
}
|
|
62117
62188
|
}
|
|
62118
62189
|
async function writeRegistry2(registry) {
|
|
62119
|
-
const dir = dirname25(
|
|
62190
|
+
const dir = dirname25(REGISTRY_PATH);
|
|
62120
62191
|
if (!existsSync40(dir)) {
|
|
62121
62192
|
await mkdir15(dir, { recursive: true });
|
|
62122
62193
|
}
|
|
62123
|
-
await writeFile15(
|
|
62194
|
+
await writeFile15(REGISTRY_PATH, JSON.stringify(registry, null, 2), "utf-8");
|
|
62124
62195
|
}
|
|
62125
62196
|
async function addInstallation(skill, agent, global3, path6, sourcePath) {
|
|
62126
62197
|
const registry = await readRegistry2();
|
|
@@ -62172,11 +62243,11 @@ async function syncRegistry() {
|
|
|
62172
62243
|
}
|
|
62173
62244
|
return { removed };
|
|
62174
62245
|
}
|
|
62175
|
-
var
|
|
62246
|
+
var home4, REGISTRY_PATH, SkillInstallationSchema, SkillRegistrySchema, REGISTRY_PATH_MIGRATIONS;
|
|
62176
62247
|
var init_skills_registry = __esm(() => {
|
|
62177
62248
|
init_zod();
|
|
62178
|
-
|
|
62179
|
-
|
|
62249
|
+
home4 = homedir38();
|
|
62250
|
+
REGISTRY_PATH = join60(home4, ".claudekit", "skill-registry.json");
|
|
62180
62251
|
SkillInstallationSchema = exports_external.object({
|
|
62181
62252
|
skill: exports_external.string(),
|
|
62182
62253
|
agent: exports_external.string(),
|
|
@@ -63287,7 +63358,7 @@ var package_default;
|
|
|
63287
63358
|
var init_package = __esm(() => {
|
|
63288
63359
|
package_default = {
|
|
63289
63360
|
name: "claudekit-cli",
|
|
63290
|
-
version: "4.3.1-dev.
|
|
63361
|
+
version: "4.3.1-dev.3",
|
|
63291
63362
|
description: "CLI tool for bootstrapping and updating ClaudeKit projects",
|
|
63292
63363
|
type: "module",
|
|
63293
63364
|
repository: {
|
|
@@ -65804,12 +65875,12 @@ function extractHookReferencePaths(cmd) {
|
|
|
65804
65875
|
}
|
|
65805
65876
|
function resolveHookScriptPath(scriptPath, projectDir) {
|
|
65806
65877
|
let resolved = scriptPath.replace(/\\/g, "/");
|
|
65807
|
-
const
|
|
65808
|
-
resolved = resolved.replace(/^\$\{?HOME\}?/,
|
|
65878
|
+
const home5 = homedir40();
|
|
65879
|
+
resolved = resolved.replace(/^\$\{?HOME\}?/, home5);
|
|
65809
65880
|
resolved = resolved.replace(/^\$\{?CLAUDE_PROJECT_DIR\}?/, projectDir);
|
|
65810
|
-
resolved = resolved.replace(/^%USERPROFILE%/,
|
|
65881
|
+
resolved = resolved.replace(/^%USERPROFILE%/, home5);
|
|
65811
65882
|
resolved = resolved.replace(/^%CLAUDE_PROJECT_DIR%/, projectDir);
|
|
65812
|
-
resolved = resolved.replace(/^~\//, `${
|
|
65883
|
+
resolved = resolved.replace(/^~\//, `${home5}/`);
|
|
65813
65884
|
if (resolved.startsWith(".claude/") || resolved === ".claude") {
|
|
65814
65885
|
resolved = join67(projectDir, resolved);
|
|
65815
65886
|
}
|
|
@@ -75826,7 +75897,7 @@ __export(exports_worktree_manager, {
|
|
|
75826
75897
|
createWorktree: () => createWorktree,
|
|
75827
75898
|
cleanupAllWorktrees: () => cleanupAllWorktrees
|
|
75828
75899
|
});
|
|
75829
|
-
import { existsSync as
|
|
75900
|
+
import { existsSync as existsSync72 } from "node:fs";
|
|
75830
75901
|
import { readFile as readFile67, writeFile as writeFile38 } from "node:fs/promises";
|
|
75831
75902
|
import { join as join153 } from "node:path";
|
|
75832
75903
|
async function createWorktree(projectDir, issueNumber, baseBranch) {
|
|
@@ -75892,7 +75963,7 @@ async function cleanupAllWorktrees(projectDir) {
|
|
|
75892
75963
|
async function ensureGitignore(projectDir) {
|
|
75893
75964
|
const gitignorePath = join153(projectDir, ".gitignore");
|
|
75894
75965
|
try {
|
|
75895
|
-
const content =
|
|
75966
|
+
const content = existsSync72(gitignorePath) ? await readFile67(gitignorePath, "utf-8") : "";
|
|
75896
75967
|
if (!content.includes(".worktrees")) {
|
|
75897
75968
|
const newContent = content.endsWith(`
|
|
75898
75969
|
`) ? `${content}.worktrees/
|
|
@@ -75994,13 +76065,13 @@ var init_content_validator = __esm(() => {
|
|
|
75994
76065
|
|
|
75995
76066
|
// src/commands/content/phases/context-cache-manager.ts
|
|
75996
76067
|
import { createHash as createHash9 } from "node:crypto";
|
|
75997
|
-
import { existsSync as
|
|
76068
|
+
import { existsSync as existsSync78, mkdirSync as mkdirSync5, readFileSync as readFileSync18, readdirSync as readdirSync12, statSync as statSync14 } from "node:fs";
|
|
75998
76069
|
import { rename as rename16, writeFile as writeFile40 } from "node:fs/promises";
|
|
75999
|
-
import { homedir as
|
|
76000
|
-
import { basename as
|
|
76070
|
+
import { homedir as homedir55 } from "node:os";
|
|
76071
|
+
import { basename as basename34, join as join160 } from "node:path";
|
|
76001
76072
|
function getCachedContext(repoPath) {
|
|
76002
76073
|
const cachePath = getCacheFilePath(repoPath);
|
|
76003
|
-
if (!
|
|
76074
|
+
if (!existsSync78(cachePath))
|
|
76004
76075
|
return null;
|
|
76005
76076
|
try {
|
|
76006
76077
|
const raw2 = readFileSync18(cachePath, "utf-8");
|
|
@@ -76017,7 +76088,7 @@ function getCachedContext(repoPath) {
|
|
|
76017
76088
|
}
|
|
76018
76089
|
}
|
|
76019
76090
|
async function saveCachedContext(repoPath, cache5) {
|
|
76020
|
-
if (!
|
|
76091
|
+
if (!existsSync78(CACHE_DIR)) {
|
|
76021
76092
|
mkdirSync5(CACHE_DIR, { recursive: true });
|
|
76022
76093
|
}
|
|
76023
76094
|
const cachePath = getCacheFilePath(repoPath);
|
|
@@ -76041,9 +76112,9 @@ function computeSourceHash(repoPath) {
|
|
|
76041
76112
|
function getDocSourcePaths(repoPath) {
|
|
76042
76113
|
const paths = [];
|
|
76043
76114
|
const docsDir = join160(repoPath, "docs");
|
|
76044
|
-
if (
|
|
76115
|
+
if (existsSync78(docsDir)) {
|
|
76045
76116
|
try {
|
|
76046
|
-
const files =
|
|
76117
|
+
const files = readdirSync12(docsDir);
|
|
76047
76118
|
for (const f3 of files) {
|
|
76048
76119
|
if (f3.endsWith(".md"))
|
|
76049
76120
|
paths.push(join160(docsDir, f3));
|
|
@@ -76051,12 +76122,12 @@ function getDocSourcePaths(repoPath) {
|
|
|
76051
76122
|
} catch {}
|
|
76052
76123
|
}
|
|
76053
76124
|
const readme = join160(repoPath, "README.md");
|
|
76054
|
-
if (
|
|
76125
|
+
if (existsSync78(readme))
|
|
76055
76126
|
paths.push(readme);
|
|
76056
76127
|
const stylesDir = join160(repoPath, "assets", "writing-styles");
|
|
76057
|
-
if (
|
|
76128
|
+
if (existsSync78(stylesDir)) {
|
|
76058
76129
|
try {
|
|
76059
|
-
const files =
|
|
76130
|
+
const files = readdirSync12(stylesDir);
|
|
76060
76131
|
for (const f3 of files) {
|
|
76061
76132
|
paths.push(join160(stylesDir, f3));
|
|
76062
76133
|
}
|
|
@@ -76065,13 +76136,13 @@ function getDocSourcePaths(repoPath) {
|
|
|
76065
76136
|
return paths.sort();
|
|
76066
76137
|
}
|
|
76067
76138
|
function getCacheFilePath(repoPath) {
|
|
76068
|
-
const repoName =
|
|
76139
|
+
const repoName = basename34(repoPath).replace(/[^a-zA-Z0-9_-]/g, "_");
|
|
76069
76140
|
const pathHash = createHash9("sha256").update(repoPath).digest("hex").slice(0, 8);
|
|
76070
76141
|
return join160(CACHE_DIR, `${repoName}-${pathHash}-context-cache.json`);
|
|
76071
76142
|
}
|
|
76072
76143
|
var CACHE_DIR, CACHE_TTL_MS5;
|
|
76073
76144
|
var init_context_cache_manager = __esm(() => {
|
|
76074
|
-
CACHE_DIR = join160(
|
|
76145
|
+
CACHE_DIR = join160(homedir55(), ".claudekit", "cache");
|
|
76075
76146
|
CACHE_TTL_MS5 = 24 * 60 * 60 * 1000;
|
|
76076
76147
|
});
|
|
76077
76148
|
|
|
@@ -76251,7 +76322,7 @@ function extractContentFromResponse(response) {
|
|
|
76251
76322
|
|
|
76252
76323
|
// src/commands/content/phases/docs-summarizer.ts
|
|
76253
76324
|
import { execSync as execSync7 } from "node:child_process";
|
|
76254
|
-
import { existsSync as
|
|
76325
|
+
import { existsSync as existsSync79, readFileSync as readFileSync19, readdirSync as readdirSync13 } from "node:fs";
|
|
76255
76326
|
import { join as join161 } from "node:path";
|
|
76256
76327
|
async function summarizeProjectDocs(repoPath, contentLogger) {
|
|
76257
76328
|
const rawContent = collectRawDocs(repoPath);
|
|
@@ -76296,7 +76367,7 @@ async function summarizeProjectDocs(repoPath, contentLogger) {
|
|
|
76296
76367
|
function collectRawDocs(repoPath) {
|
|
76297
76368
|
let totalChars = 0;
|
|
76298
76369
|
const readCapped = (filePath, maxChars) => {
|
|
76299
|
-
if (!
|
|
76370
|
+
if (!existsSync79(filePath))
|
|
76300
76371
|
return "";
|
|
76301
76372
|
if (totalChars >= MAX_RAW_CONTENT_CHARS)
|
|
76302
76373
|
return "";
|
|
@@ -76307,9 +76378,9 @@ function collectRawDocs(repoPath) {
|
|
|
76307
76378
|
};
|
|
76308
76379
|
const docsContent = [];
|
|
76309
76380
|
const docsDir = join161(repoPath, "docs");
|
|
76310
|
-
if (
|
|
76381
|
+
if (existsSync79(docsDir)) {
|
|
76311
76382
|
try {
|
|
76312
|
-
const files =
|
|
76383
|
+
const files = readdirSync13(docsDir).filter((f3) => f3.endsWith(".md")).sort();
|
|
76313
76384
|
for (const f3 of files) {
|
|
76314
76385
|
const content = readCapped(join161(docsDir, f3), 5000);
|
|
76315
76386
|
if (content) {
|
|
@@ -76331,9 +76402,9 @@ ${content}`);
|
|
|
76331
76402
|
}
|
|
76332
76403
|
let styles3 = "";
|
|
76333
76404
|
const stylesDir = join161(repoPath, "assets", "writing-styles");
|
|
76334
|
-
if (
|
|
76405
|
+
if (existsSync79(stylesDir)) {
|
|
76335
76406
|
try {
|
|
76336
|
-
const files =
|
|
76407
|
+
const files = readdirSync13(stylesDir).slice(0, 3);
|
|
76337
76408
|
styles3 = files.map((f3) => readCapped(join161(stylesDir, f3), 1000)).filter(Boolean).join(`
|
|
76338
76409
|
|
|
76339
76410
|
`);
|
|
@@ -76524,12 +76595,12 @@ IMPORTANT: Generate the image and output the path as JSON: {"imagePath": "/path/
|
|
|
76524
76595
|
|
|
76525
76596
|
// src/commands/content/phases/photo-generator.ts
|
|
76526
76597
|
import { execSync as execSync8 } from "node:child_process";
|
|
76527
|
-
import { existsSync as
|
|
76528
|
-
import { homedir as
|
|
76598
|
+
import { existsSync as existsSync80, mkdirSync as mkdirSync6, readdirSync as readdirSync14 } from "node:fs";
|
|
76599
|
+
import { homedir as homedir56 } from "node:os";
|
|
76529
76600
|
import { join as join162 } from "node:path";
|
|
76530
76601
|
async function generatePhoto(_content, context, config, platform18, contentId, contentLogger) {
|
|
76531
|
-
const mediaDir = join162(config.contentDir.replace(/^~/,
|
|
76532
|
-
if (!
|
|
76602
|
+
const mediaDir = join162(config.contentDir.replace(/^~/, homedir56()), "media", String(contentId));
|
|
76603
|
+
if (!existsSync80(mediaDir)) {
|
|
76533
76604
|
mkdirSync6(mediaDir, { recursive: true });
|
|
76534
76605
|
}
|
|
76535
76606
|
const prompt = buildPhotoPrompt(context, platform18);
|
|
@@ -76545,11 +76616,11 @@ async function generatePhoto(_content, context, config, platform18, contentId, c
|
|
|
76545
76616
|
const parsed = parseClaudeJsonOutput(result);
|
|
76546
76617
|
if (parsed && typeof parsed === "object" && "imagePath" in parsed) {
|
|
76547
76618
|
const imagePath = String(parsed.imagePath);
|
|
76548
|
-
if (
|
|
76619
|
+
if (existsSync80(imagePath)) {
|
|
76549
76620
|
return { path: imagePath, ...dimensions, format: "png" };
|
|
76550
76621
|
}
|
|
76551
76622
|
}
|
|
76552
|
-
const files =
|
|
76623
|
+
const files = readdirSync14(mediaDir);
|
|
76553
76624
|
const imageFile = files.find((f3) => /\.(png|jpg|jpeg|webp)$/i.test(f3));
|
|
76554
76625
|
if (imageFile) {
|
|
76555
76626
|
const ext2 = imageFile.split(".").pop() ?? "png";
|
|
@@ -76641,8 +76712,8 @@ var init_content_creator = __esm(() => {
|
|
|
76641
76712
|
});
|
|
76642
76713
|
|
|
76643
76714
|
// src/commands/content/phases/content-logger.ts
|
|
76644
|
-
import { createWriteStream as createWriteStream4, existsSync as
|
|
76645
|
-
import { homedir as
|
|
76715
|
+
import { createWriteStream as createWriteStream4, existsSync as existsSync81, mkdirSync as mkdirSync7, statSync as statSync15 } from "node:fs";
|
|
76716
|
+
import { homedir as homedir57 } from "node:os";
|
|
76646
76717
|
import { join as join163 } from "node:path";
|
|
76647
76718
|
|
|
76648
76719
|
class ContentLogger {
|
|
@@ -76651,11 +76722,11 @@ class ContentLogger {
|
|
|
76651
76722
|
logDir;
|
|
76652
76723
|
maxBytes;
|
|
76653
76724
|
constructor(maxBytes = 0) {
|
|
76654
|
-
this.logDir = join163(
|
|
76725
|
+
this.logDir = join163(homedir57(), ".claudekit", "logs");
|
|
76655
76726
|
this.maxBytes = maxBytes;
|
|
76656
76727
|
}
|
|
76657
76728
|
init() {
|
|
76658
|
-
if (!
|
|
76729
|
+
if (!existsSync81(this.logDir)) {
|
|
76659
76730
|
mkdirSync7(this.logDir, { recursive: true });
|
|
76660
76731
|
}
|
|
76661
76732
|
this.rotateIfNeeded();
|
|
@@ -76748,8 +76819,8 @@ function openDatabase(dbPath) {
|
|
|
76748
76819
|
var init_sqlite_client = () => {};
|
|
76749
76820
|
|
|
76750
76821
|
// src/commands/content/phases/db-manager.ts
|
|
76751
|
-
import { existsSync as
|
|
76752
|
-
import { dirname as
|
|
76822
|
+
import { existsSync as existsSync82, mkdirSync as mkdirSync8 } from "node:fs";
|
|
76823
|
+
import { dirname as dirname50 } from "node:path";
|
|
76753
76824
|
function initDatabase(dbPath) {
|
|
76754
76825
|
ensureParentDir(dbPath);
|
|
76755
76826
|
const db = openDatabase(dbPath);
|
|
@@ -76770,8 +76841,8 @@ function runRetentionCleanup(db, retentionDays = 90) {
|
|
|
76770
76841
|
db.prepare("DELETE FROM git_events WHERE processed = 1 AND created_at < ?").run(cutoff);
|
|
76771
76842
|
}
|
|
76772
76843
|
function ensureParentDir(dbPath) {
|
|
76773
|
-
const dir =
|
|
76774
|
-
if (dir && !
|
|
76844
|
+
const dir = dirname50(dbPath);
|
|
76845
|
+
if (dir && !existsSync82(dir)) {
|
|
76775
76846
|
mkdirSync8(dir, { recursive: true });
|
|
76776
76847
|
}
|
|
76777
76848
|
}
|
|
@@ -76936,7 +77007,7 @@ function isNoiseCommit(title, author) {
|
|
|
76936
77007
|
|
|
76937
77008
|
// src/commands/content/phases/change-detector.ts
|
|
76938
77009
|
import { execSync as execSync10, spawnSync as spawnSync9 } from "node:child_process";
|
|
76939
|
-
import { existsSync as
|
|
77010
|
+
import { existsSync as existsSync83, readFileSync as readFileSync20, readdirSync as readdirSync15, statSync as statSync16 } from "node:fs";
|
|
76940
77011
|
import { join as join164 } from "node:path";
|
|
76941
77012
|
function detectCommits(repo, since) {
|
|
76942
77013
|
try {
|
|
@@ -77047,17 +77118,17 @@ function detectTags(repo, since) {
|
|
|
77047
77118
|
}
|
|
77048
77119
|
function detectCompletedPlans(repo, since) {
|
|
77049
77120
|
const plansDir = join164(repo.path, "plans");
|
|
77050
|
-
if (!
|
|
77121
|
+
if (!existsSync83(plansDir))
|
|
77051
77122
|
return [];
|
|
77052
77123
|
const sinceMs = new Date(since).getTime();
|
|
77053
77124
|
const events = [];
|
|
77054
77125
|
try {
|
|
77055
|
-
const entries =
|
|
77126
|
+
const entries = readdirSync15(plansDir, { withFileTypes: true });
|
|
77056
77127
|
for (const entry of entries) {
|
|
77057
77128
|
if (!entry.isDirectory())
|
|
77058
77129
|
continue;
|
|
77059
77130
|
const planFile = join164(plansDir, entry.name, "plan.md");
|
|
77060
|
-
if (!
|
|
77131
|
+
if (!existsSync83(planFile))
|
|
77061
77132
|
continue;
|
|
77062
77133
|
try {
|
|
77063
77134
|
const stat26 = statSync16(planFile);
|
|
@@ -77133,7 +77204,7 @@ function classifyCommit(event) {
|
|
|
77133
77204
|
|
|
77134
77205
|
// src/commands/content/phases/repo-discoverer.ts
|
|
77135
77206
|
import { execSync as execSync11 } from "node:child_process";
|
|
77136
|
-
import { readdirSync as
|
|
77207
|
+
import { readdirSync as readdirSync16 } from "node:fs";
|
|
77137
77208
|
import { join as join165 } from "node:path";
|
|
77138
77209
|
function discoverRepos2(cwd2) {
|
|
77139
77210
|
const repos = [];
|
|
@@ -77143,7 +77214,7 @@ function discoverRepos2(cwd2) {
|
|
|
77143
77214
|
repos.push(info);
|
|
77144
77215
|
}
|
|
77145
77216
|
try {
|
|
77146
|
-
const entries =
|
|
77217
|
+
const entries = readdirSync16(cwd2, { withFileTypes: true });
|
|
77147
77218
|
for (const entry of entries) {
|
|
77148
77219
|
if (!entry.isDirectory() || entry.name.startsWith("."))
|
|
77149
77220
|
continue;
|
|
@@ -78125,7 +78196,7 @@ var init_platform_setup_x = __esm(() => {
|
|
|
78125
78196
|
});
|
|
78126
78197
|
|
|
78127
78198
|
// src/commands/content/phases/setup-wizard.ts
|
|
78128
|
-
import { existsSync as
|
|
78199
|
+
import { existsSync as existsSync84 } from "node:fs";
|
|
78129
78200
|
import { join as join167 } from "node:path";
|
|
78130
78201
|
async function runSetupWizard2(cwd2, contentLogger) {
|
|
78131
78202
|
console.log();
|
|
@@ -78194,8 +78265,8 @@ async function showRepoSummary(cwd2) {
|
|
|
78194
78265
|
function detectBrandAssets(cwd2, contentLogger) {
|
|
78195
78266
|
const repos = discoverRepos2(cwd2);
|
|
78196
78267
|
for (const repo of repos) {
|
|
78197
|
-
const hasGuidelines =
|
|
78198
|
-
const hasStyles =
|
|
78268
|
+
const hasGuidelines = existsSync84(join167(repo.path, "docs", "brand-guidelines.md"));
|
|
78269
|
+
const hasStyles = existsSync84(join167(repo.path, "assets", "writing-styles"));
|
|
78199
78270
|
if (!hasGuidelines) {
|
|
78200
78271
|
f2.warning(`${repo.name}: No docs/brand-guidelines.md — content will use generic tone.`);
|
|
78201
78272
|
contentLogger.warn(`${repo.name}: missing docs/brand-guidelines.md`);
|
|
@@ -78261,13 +78332,13 @@ var init_setup_wizard = __esm(() => {
|
|
|
78261
78332
|
});
|
|
78262
78333
|
|
|
78263
78334
|
// src/commands/content/content-review-commands.ts
|
|
78264
|
-
import { existsSync as
|
|
78265
|
-
import { homedir as
|
|
78335
|
+
import { existsSync as existsSync85 } from "node:fs";
|
|
78336
|
+
import { homedir as homedir58 } from "node:os";
|
|
78266
78337
|
async function queueContent() {
|
|
78267
78338
|
const cwd2 = process.cwd();
|
|
78268
78339
|
const config = await loadContentConfig(cwd2);
|
|
78269
|
-
const dbPath = config.dbPath.replace(/^~/,
|
|
78270
|
-
if (!
|
|
78340
|
+
const dbPath = config.dbPath.replace(/^~/, homedir58());
|
|
78341
|
+
if (!existsSync85(dbPath)) {
|
|
78271
78342
|
logger.info("No content database found. Run 'ck content setup' first.");
|
|
78272
78343
|
return;
|
|
78273
78344
|
}
|
|
@@ -78293,7 +78364,7 @@ async function queueContent() {
|
|
|
78293
78364
|
async function approveContentCmd(id) {
|
|
78294
78365
|
const cwd2 = process.cwd();
|
|
78295
78366
|
const config = await loadContentConfig(cwd2);
|
|
78296
|
-
const dbPath = config.dbPath.replace(/^~/,
|
|
78367
|
+
const dbPath = config.dbPath.replace(/^~/, homedir58());
|
|
78297
78368
|
const db = initDatabase(dbPath);
|
|
78298
78369
|
try {
|
|
78299
78370
|
approveContent(db, Number.parseInt(id, 10));
|
|
@@ -78305,7 +78376,7 @@ async function approveContentCmd(id) {
|
|
|
78305
78376
|
async function rejectContentCmd(id, reason) {
|
|
78306
78377
|
const cwd2 = process.cwd();
|
|
78307
78378
|
const config = await loadContentConfig(cwd2);
|
|
78308
|
-
const dbPath = config.dbPath.replace(/^~/,
|
|
78379
|
+
const dbPath = config.dbPath.replace(/^~/, homedir58());
|
|
78309
78380
|
const db = initDatabase(dbPath);
|
|
78310
78381
|
try {
|
|
78311
78382
|
rejectContent(db, Number.parseInt(id, 10), reason);
|
|
@@ -78335,12 +78406,12 @@ __export(exports_content_subcommands, {
|
|
|
78335
78406
|
logsContent: () => logsContent,
|
|
78336
78407
|
approveContentCmd: () => approveContentCmd
|
|
78337
78408
|
});
|
|
78338
|
-
import { existsSync as
|
|
78339
|
-
import { homedir as
|
|
78409
|
+
import { existsSync as existsSync86, readFileSync as readFileSync21, unlinkSync as unlinkSync6 } from "node:fs";
|
|
78410
|
+
import { homedir as homedir59 } from "node:os";
|
|
78340
78411
|
import { join as join168 } from "node:path";
|
|
78341
78412
|
function isDaemonRunning() {
|
|
78342
78413
|
const lockFile = join168(LOCK_DIR, `${LOCK_NAME2}.lock`);
|
|
78343
|
-
if (!
|
|
78414
|
+
if (!existsSync86(lockFile))
|
|
78344
78415
|
return { running: false, pid: null };
|
|
78345
78416
|
try {
|
|
78346
78417
|
const pidStr = readFileSync21(lockFile, "utf-8").trim();
|
|
@@ -78372,7 +78443,7 @@ async function startContent(options2) {
|
|
|
78372
78443
|
}
|
|
78373
78444
|
async function stopContent() {
|
|
78374
78445
|
const lockFile = join168(LOCK_DIR, `${LOCK_NAME2}.lock`);
|
|
78375
|
-
if (!
|
|
78446
|
+
if (!existsSync86(lockFile)) {
|
|
78376
78447
|
logger.info("Content daemon is not running.");
|
|
78377
78448
|
return;
|
|
78378
78449
|
}
|
|
@@ -78410,10 +78481,10 @@ async function statusContent() {
|
|
|
78410
78481
|
} catch {}
|
|
78411
78482
|
}
|
|
78412
78483
|
async function logsContent(options2) {
|
|
78413
|
-
const logDir = join168(
|
|
78484
|
+
const logDir = join168(homedir59(), ".claudekit", "logs");
|
|
78414
78485
|
const dateStr = new Date().toISOString().slice(0, 10).replace(/-/g, "");
|
|
78415
78486
|
const logPath = join168(logDir, `content-${dateStr}.log`);
|
|
78416
|
-
if (!
|
|
78487
|
+
if (!existsSync86(logPath)) {
|
|
78417
78488
|
logger.info("No content logs found for today.");
|
|
78418
78489
|
return;
|
|
78419
78490
|
}
|
|
@@ -78444,12 +78515,12 @@ var init_content_subcommands = __esm(() => {
|
|
|
78444
78515
|
init_setup_wizard();
|
|
78445
78516
|
init_state_manager();
|
|
78446
78517
|
init_content_review_commands();
|
|
78447
|
-
LOCK_DIR = join168(
|
|
78518
|
+
LOCK_DIR = join168(homedir59(), ".claudekit", "locks");
|
|
78448
78519
|
});
|
|
78449
78520
|
|
|
78450
78521
|
// src/commands/content/content-command.ts
|
|
78451
|
-
import { existsSync as
|
|
78452
|
-
import { homedir as
|
|
78522
|
+
import { existsSync as existsSync87, mkdirSync as mkdirSync9, unlinkSync as unlinkSync7, writeFileSync as writeFileSync7 } from "node:fs";
|
|
78523
|
+
import { homedir as homedir60 } from "node:os";
|
|
78453
78524
|
import { join as join169 } from "node:path";
|
|
78454
78525
|
async function contentCommand(options2) {
|
|
78455
78526
|
const cwd2 = process.cwd();
|
|
@@ -78479,10 +78550,10 @@ async function contentCommand(options2) {
|
|
|
78479
78550
|
}
|
|
78480
78551
|
contentLogger.info("Setup complete. Starting daemon...");
|
|
78481
78552
|
}
|
|
78482
|
-
if (!
|
|
78553
|
+
if (!existsSync87(LOCK_DIR2))
|
|
78483
78554
|
mkdirSync9(LOCK_DIR2, { recursive: true });
|
|
78484
78555
|
writeFileSync7(LOCK_FILE, String(process.pid), "utf-8");
|
|
78485
|
-
const dbPath = config.dbPath.replace(/^~/,
|
|
78556
|
+
const dbPath = config.dbPath.replace(/^~/, homedir60());
|
|
78486
78557
|
const db = initDatabase(dbPath);
|
|
78487
78558
|
contentLogger.info(`Database initialised at ${dbPath}`);
|
|
78488
78559
|
const adapters = initializeAdapters(config);
|
|
@@ -78628,7 +78699,7 @@ var init_content_command = __esm(() => {
|
|
|
78628
78699
|
init_publisher();
|
|
78629
78700
|
init_review_manager();
|
|
78630
78701
|
init_state_manager();
|
|
78631
|
-
LOCK_DIR2 = join169(
|
|
78702
|
+
LOCK_DIR2 = join169(homedir60(), ".claudekit", "locks");
|
|
78632
78703
|
LOCK_FILE = join169(LOCK_DIR2, "ck-content.lock");
|
|
78633
78704
|
});
|
|
78634
78705
|
|
|
@@ -80168,6 +80239,12 @@ var init_plan_command_help = __esm(() => {
|
|
|
80168
80239
|
title: "Scope Options",
|
|
80169
80240
|
options: [{ flags: "-g, --global", description: "Create plan in global plans scope" }]
|
|
80170
80241
|
}
|
|
80242
|
+
],
|
|
80243
|
+
sections: [
|
|
80244
|
+
{
|
|
80245
|
+
title: "Agent Editing Reminder",
|
|
80246
|
+
content: "After creating a plan, Claude Code agents should read `plan.md` and every generated `phase-*.md` before editing. The files already exist; Write/Edit without Read can be rejected after wasting tokens."
|
|
80247
|
+
}
|
|
80171
80248
|
]
|
|
80172
80249
|
},
|
|
80173
80250
|
{
|
|
@@ -84596,6 +84673,16 @@ init_provider_registry();
|
|
|
84596
84673
|
import { existsSync as existsSync9 } from "node:fs";
|
|
84597
84674
|
import { lstat as lstat3, rm as rm2 } from "node:fs/promises";
|
|
84598
84675
|
import { basename as basename5, dirname as dirname6, join as join17, relative as relative4, resolve as resolve8, sep as sep4 } from "node:path";
|
|
84676
|
+
var defaultCommandRegistryDeps = {
|
|
84677
|
+
readPortableRegistry,
|
|
84678
|
+
removePortableInstallation
|
|
84679
|
+
};
|
|
84680
|
+
function resolveCommandRegistryDeps(deps) {
|
|
84681
|
+
return {
|
|
84682
|
+
...defaultCommandRegistryDeps,
|
|
84683
|
+
...deps
|
|
84684
|
+
};
|
|
84685
|
+
}
|
|
84599
84686
|
function isPathWithinBase(targetPath, basePath) {
|
|
84600
84687
|
const resolvedTarget = resolve8(targetPath);
|
|
84601
84688
|
const resolvedBase = resolve8(basePath);
|
|
@@ -84727,8 +84814,9 @@ async function removeCommandTarget(targetPath, provider, basePath) {
|
|
|
84727
84814
|
}
|
|
84728
84815
|
await rm2(targetPath, { recursive: true, force: true });
|
|
84729
84816
|
}
|
|
84730
|
-
async function uninstallCommandFromProvider(commandName, provider, global3) {
|
|
84731
|
-
const
|
|
84817
|
+
async function uninstallCommandFromProvider(commandName, provider, global3, deps) {
|
|
84818
|
+
const registryDeps = resolveCommandRegistryDeps(deps);
|
|
84819
|
+
const registry = await registryDeps.readPortableRegistry();
|
|
84732
84820
|
const installations = findPortableInstallations(registry, commandName, "command", provider, global3);
|
|
84733
84821
|
if (installations.length === 0) {
|
|
84734
84822
|
return {
|
|
@@ -84749,7 +84837,7 @@ async function uninstallCommandFromProvider(commandName, provider, global3) {
|
|
|
84749
84837
|
if (fileExists) {
|
|
84750
84838
|
await removeCommandTarget(installation.path, provider, basePath);
|
|
84751
84839
|
}
|
|
84752
|
-
await removePortableInstallation(commandName, "command", provider, global3);
|
|
84840
|
+
await registryDeps.removePortableInstallation(commandName, "command", provider, global3);
|
|
84753
84841
|
return {
|
|
84754
84842
|
item: commandName,
|
|
84755
84843
|
provider,
|
|
@@ -84771,7 +84859,8 @@ async function uninstallCommandFromProvider(commandName, provider, global3) {
|
|
|
84771
84859
|
};
|
|
84772
84860
|
}
|
|
84773
84861
|
}
|
|
84774
|
-
async function forceUninstallCommandFromProvider(commandName, provider, global3) {
|
|
84862
|
+
async function forceUninstallCommandFromProvider(commandName, provider, global3, deps) {
|
|
84863
|
+
const registryDeps = resolveCommandRegistryDeps(deps);
|
|
84775
84864
|
const config = providers[provider];
|
|
84776
84865
|
const pathConfig = config.commands;
|
|
84777
84866
|
if (!pathConfig) {
|
|
@@ -84841,7 +84930,7 @@ async function forceUninstallCommandFromProvider(commandName, provider, global3)
|
|
|
84841
84930
|
}
|
|
84842
84931
|
try {
|
|
84843
84932
|
await removeCommandTarget(targetPath, provider, basePath);
|
|
84844
|
-
await removePortableInstallation(commandName, "command", provider, global3);
|
|
84933
|
+
await registryDeps.removePortableInstallation(commandName, "command", provider, global3);
|
|
84845
84934
|
return {
|
|
84846
84935
|
item: commandName,
|
|
84847
84936
|
provider,
|
|
@@ -84862,8 +84951,9 @@ async function forceUninstallCommandFromProvider(commandName, provider, global3)
|
|
|
84862
84951
|
};
|
|
84863
84952
|
}
|
|
84864
84953
|
}
|
|
84865
|
-
async function getInstalledCommands(provider, global3) {
|
|
84866
|
-
const
|
|
84954
|
+
async function getInstalledCommands(provider, global3, deps) {
|
|
84955
|
+
const registryDeps = resolveCommandRegistryDeps(deps);
|
|
84956
|
+
const registry = await registryDeps.readPortableRegistry();
|
|
84867
84957
|
return registry.installations.filter((i) => {
|
|
84868
84958
|
if (i.type !== "command")
|
|
84869
84959
|
return false;
|
|
@@ -84876,9 +84966,20 @@ async function getInstalledCommands(provider, global3) {
|
|
|
84876
84966
|
}
|
|
84877
84967
|
|
|
84878
84968
|
// src/commands/commands/commands-command.ts
|
|
84879
|
-
|
|
84969
|
+
var defaultCommandsRegistryDeps = {
|
|
84970
|
+
readPortableRegistry,
|
|
84971
|
+
removePortableInstallation,
|
|
84972
|
+
syncPortableRegistry
|
|
84973
|
+
};
|
|
84974
|
+
function resolveCommandsRegistryDeps(options2) {
|
|
84975
|
+
return {
|
|
84976
|
+
...defaultCommandsRegistryDeps,
|
|
84977
|
+
...options2?.registry
|
|
84978
|
+
};
|
|
84979
|
+
}
|
|
84980
|
+
async function listCommands(showInstalled, registryDeps) {
|
|
84880
84981
|
if (showInstalled) {
|
|
84881
|
-
const installations = await getInstalledCommands();
|
|
84982
|
+
const installations = await getInstalledCommands(undefined, undefined, registryDeps);
|
|
84882
84983
|
if (installations.length === 0) {
|
|
84883
84984
|
f2.warn("No commands installed via ck commands.");
|
|
84884
84985
|
return;
|
|
@@ -84930,9 +85031,9 @@ async function listCommands(showInstalled) {
|
|
|
84930
85031
|
console.log(import_picocolors13.default.dim(` Source: ${sourcePath}`));
|
|
84931
85032
|
console.log();
|
|
84932
85033
|
}
|
|
84933
|
-
async function handleUninstall2(options2) {
|
|
85034
|
+
async function handleUninstall2(options2, registryDeps) {
|
|
84934
85035
|
if (!options2.name) {
|
|
84935
|
-
const installations = await getInstalledCommands();
|
|
85036
|
+
const installations = await getInstalledCommands(undefined, undefined, registryDeps);
|
|
84936
85037
|
if (installations.length === 0) {
|
|
84937
85038
|
f2.warn("No commands installed via ck commands.");
|
|
84938
85039
|
return;
|
|
@@ -84964,7 +85065,7 @@ async function handleUninstall2(options2) {
|
|
|
84964
85065
|
const spinner2 = de();
|
|
84965
85066
|
spinner2.start("Uninstalling...");
|
|
84966
85067
|
for (const inst of toUninstall) {
|
|
84967
|
-
await uninstallCommandFromProvider(inst.item, inst.provider, inst.global);
|
|
85068
|
+
await uninstallCommandFromProvider(inst.item, inst.provider, inst.global, registryDeps);
|
|
84968
85069
|
}
|
|
84969
85070
|
spinner2.stop("Uninstall complete");
|
|
84970
85071
|
f2.success(`Removed ${toUninstall.length} command(s)`);
|
|
@@ -84990,7 +85091,7 @@ async function handleUninstall2(options2) {
|
|
|
84990
85091
|
const spinner2 = de();
|
|
84991
85092
|
spinner2.start("Force uninstalling...");
|
|
84992
85093
|
const targets = options2.agent;
|
|
84993
|
-
const results = await Promise.all(targets.map((provider) => forceUninstallCommandFromProvider(trimmedName, provider, options2.global ?? false)));
|
|
85094
|
+
const results = await Promise.all(targets.map((provider) => forceUninstallCommandFromProvider(trimmedName, provider, options2.global ?? false, registryDeps)));
|
|
84994
85095
|
const successCount2 = results.filter((result) => result.success).length;
|
|
84995
85096
|
spinner2.stop("Force uninstall complete");
|
|
84996
85097
|
for (const result of results) {
|
|
@@ -85005,7 +85106,7 @@ async function handleUninstall2(options2) {
|
|
|
85005
85106
|
}
|
|
85006
85107
|
return true;
|
|
85007
85108
|
};
|
|
85008
|
-
const registry = await readPortableRegistry();
|
|
85109
|
+
const registry = await registryDeps.readPortableRegistry();
|
|
85009
85110
|
const matches = registry.installations.filter((i) => i.type === "command" && i.item.toLowerCase() === trimmedName.toLowerCase());
|
|
85010
85111
|
if (matches.length === 0) {
|
|
85011
85112
|
if (options2.force) {
|
|
@@ -85048,7 +85149,7 @@ async function handleUninstall2(options2) {
|
|
|
85048
85149
|
spinner.start("Uninstalling...");
|
|
85049
85150
|
let successCount = 0;
|
|
85050
85151
|
for (const inst of toRemove) {
|
|
85051
|
-
const result = await uninstallCommandFromProvider(inst.item, inst.provider, inst.global);
|
|
85152
|
+
const result = await uninstallCommandFromProvider(inst.item, inst.provider, inst.global, registryDeps);
|
|
85052
85153
|
if (result.success)
|
|
85053
85154
|
successCount++;
|
|
85054
85155
|
}
|
|
@@ -85059,11 +85160,12 @@ async function commandsCommand(options2) {
|
|
|
85059
85160
|
console.log();
|
|
85060
85161
|
oe(import_picocolors13.default.bgCyan(import_picocolors13.default.black(" ck commands ")));
|
|
85061
85162
|
try {
|
|
85163
|
+
const registryDeps = resolveCommandsRegistryDeps(options2);
|
|
85062
85164
|
const validOptions = PortableCommandOptionsSchema.parse(options2);
|
|
85063
85165
|
if (validOptions.sync) {
|
|
85064
85166
|
const spinner2 = de();
|
|
85065
85167
|
spinner2.start("Syncing registry...");
|
|
85066
|
-
const { removed } = await syncPortableRegistry();
|
|
85168
|
+
const { removed } = await registryDeps.syncPortableRegistry();
|
|
85067
85169
|
spinner2.stop("Sync complete");
|
|
85068
85170
|
if (removed.length > 0) {
|
|
85069
85171
|
const cmdRemoved = removed.filter((r2) => r2.type === "command");
|
|
@@ -85075,12 +85177,12 @@ async function commandsCommand(options2) {
|
|
|
85075
85177
|
return;
|
|
85076
85178
|
}
|
|
85077
85179
|
if (validOptions.uninstall) {
|
|
85078
|
-
await handleUninstall2(validOptions);
|
|
85180
|
+
await handleUninstall2(validOptions, registryDeps);
|
|
85079
85181
|
$e(import_picocolors13.default.green("Done!"));
|
|
85080
85182
|
return;
|
|
85081
85183
|
}
|
|
85082
85184
|
if (validOptions.list) {
|
|
85083
|
-
await listCommands(validOptions.installed ?? false);
|
|
85185
|
+
await listCommands(validOptions.installed ?? false, registryDeps);
|
|
85084
85186
|
$e(import_picocolors13.default.dim("Use --name <command> to install a specific command"));
|
|
85085
85187
|
return;
|
|
85086
85188
|
}
|
|
@@ -87266,16 +87368,16 @@ async function checkPathRefsValid(projectDir) {
|
|
|
87266
87368
|
};
|
|
87267
87369
|
}
|
|
87268
87370
|
const baseDir = dirname28(claudeMdPath);
|
|
87269
|
-
const
|
|
87371
|
+
const home5 = homedir42();
|
|
87270
87372
|
const broken = [];
|
|
87271
87373
|
for (const ref of refs) {
|
|
87272
87374
|
let refPath;
|
|
87273
87375
|
if (ref.startsWith("$HOME") || ref.startsWith("${HOME}") || ref.startsWith("%USERPROFILE%")) {
|
|
87274
|
-
refPath = normalize6(ref.replace(/^\$\{?HOME\}?/,
|
|
87376
|
+
refPath = normalize6(ref.replace(/^\$\{?HOME\}?/, home5).replace("%USERPROFILE%", home5));
|
|
87275
87377
|
} else if (ref.startsWith("$CLAUDE_PROJECT_DIR") || ref.startsWith("${CLAUDE_PROJECT_DIR}") || ref.startsWith("%CLAUDE_PROJECT_DIR%")) {
|
|
87276
87378
|
refPath = normalize6(ref.replace(/^\$\{?CLAUDE_PROJECT_DIR\}?/, projectDir).replace("%CLAUDE_PROJECT_DIR%", projectDir));
|
|
87277
87379
|
} else if (ref.startsWith("~")) {
|
|
87278
|
-
refPath = normalize6(ref.replace(/^~/,
|
|
87380
|
+
refPath = normalize6(ref.replace(/^~/, home5));
|
|
87279
87381
|
} else if (ref.startsWith("/")) {
|
|
87280
87382
|
refPath = normalize6(ref);
|
|
87281
87383
|
} else if (/^[A-Za-z]:/.test(ref)) {
|
|
@@ -87284,7 +87386,7 @@ async function checkPathRefsValid(projectDir) {
|
|
|
87284
87386
|
refPath = resolve35(baseDir, ref);
|
|
87285
87387
|
}
|
|
87286
87388
|
const normalizedPath = normalize6(refPath);
|
|
87287
|
-
const isWithinHome = normalizedPath.startsWith(
|
|
87389
|
+
const isWithinHome = normalizedPath.startsWith(home5);
|
|
87288
87390
|
const isWithinBase2 = normalizedPath.startsWith(normalize6(baseDir));
|
|
87289
87391
|
const isAbsoluteAllowed = ref.startsWith("/") || /^[A-Za-z]:/.test(ref);
|
|
87290
87392
|
if (!isWithinHome && !isWithinBase2 && !isAbsoluteAllowed) {
|
|
@@ -89271,8 +89373,8 @@ class ReportGenerator {
|
|
|
89271
89373
|
};
|
|
89272
89374
|
}
|
|
89273
89375
|
scrubPath(path7) {
|
|
89274
|
-
const
|
|
89275
|
-
return
|
|
89376
|
+
const home5 = process.env.HOME || process.env.USERPROFILE || "";
|
|
89377
|
+
return home5 ? path7.replace(home5, "~") : path7;
|
|
89276
89378
|
}
|
|
89277
89379
|
getStatusIcon(status) {
|
|
89278
89380
|
switch (status) {
|
|
@@ -89386,8 +89488,8 @@ class DoctorUIRenderer {
|
|
|
89386
89488
|
}
|
|
89387
89489
|
}
|
|
89388
89490
|
shortenPath(path7) {
|
|
89389
|
-
const
|
|
89390
|
-
let shortened =
|
|
89491
|
+
const home5 = process.env.HOME || process.env.USERPROFILE || "";
|
|
89492
|
+
let shortened = home5 ? path7.replace(home5, "~") : path7;
|
|
89391
89493
|
const maxLen = 50;
|
|
89392
89494
|
if (shortened.length > maxLen) {
|
|
89393
89495
|
const start = shortened.slice(0, 20);
|
|
@@ -100668,7 +100770,7 @@ init_logger();
|
|
|
100668
100770
|
init_types3();
|
|
100669
100771
|
var import_fs_extra15 = __toESM(require_lib(), 1);
|
|
100670
100772
|
var import_ignore3 = __toESM(require_ignore(), 1);
|
|
100671
|
-
import { dirname as
|
|
100773
|
+
import { dirname as dirname38, join as join110, relative as relative23 } from "node:path";
|
|
100672
100774
|
|
|
100673
100775
|
// src/domains/installation/selective-merger.ts
|
|
100674
100776
|
import { stat as stat18 } from "node:fs/promises";
|
|
@@ -102338,8 +102440,8 @@ class FileScanner {
|
|
|
102338
102440
|
|
|
102339
102441
|
// src/domains/installation/merger/settings-processor.ts
|
|
102340
102442
|
import { execSync as execSync5 } from "node:child_process";
|
|
102341
|
-
import { homedir as
|
|
102342
|
-
import { dirname as
|
|
102443
|
+
import { homedir as homedir46 } from "node:os";
|
|
102444
|
+
import { dirname as dirname37, join as join109 } from "node:path";
|
|
102343
102445
|
|
|
102344
102446
|
// src/domains/config/installed-settings-tracker.ts
|
|
102345
102447
|
init_shared();
|
|
@@ -102436,6 +102538,136 @@ class InstalledSettingsTracker {
|
|
|
102436
102538
|
|
|
102437
102539
|
// src/domains/installation/merger/settings-processor.ts
|
|
102438
102540
|
init_settings_merger();
|
|
102541
|
+
|
|
102542
|
+
// src/domains/installation/merger/zombie-wirings-pruner.ts
|
|
102543
|
+
import { existsSync as existsSync65, readdirSync as readdirSync8 } from "node:fs";
|
|
102544
|
+
import { homedir as homedir45 } from "node:os";
|
|
102545
|
+
import { basename as basename26, dirname as dirname36, isAbsolute as isAbsolute12, resolve as resolve41, sep as sep13 } from "node:path";
|
|
102546
|
+
function pruneZombieEngineerWirings(settings, hookDir) {
|
|
102547
|
+
const pruned = [];
|
|
102548
|
+
if (!existsSync65(hookDir)) {
|
|
102549
|
+
return { settings, pruned };
|
|
102550
|
+
}
|
|
102551
|
+
const hookFiles = readdirSync8(hookDir);
|
|
102552
|
+
const hasHookFiles = hookFiles.some((f3) => f3.endsWith(".cjs") || f3.endsWith(".sh"));
|
|
102553
|
+
if (!hasHookFiles) {
|
|
102554
|
+
return { settings, pruned };
|
|
102555
|
+
}
|
|
102556
|
+
if (!settings.hooks) {
|
|
102557
|
+
return { settings, pruned };
|
|
102558
|
+
}
|
|
102559
|
+
const eventKeysToDelete = [];
|
|
102560
|
+
const events = settings.hooks;
|
|
102561
|
+
for (const eventName of Object.keys(events)) {
|
|
102562
|
+
const groups = events[eventName];
|
|
102563
|
+
const keptGroups = [];
|
|
102564
|
+
for (const group of groups) {
|
|
102565
|
+
if (!("hooks" in group) || !Array.isArray(group.hooks)) {
|
|
102566
|
+
const entry = group;
|
|
102567
|
+
if (shouldPruneEntry(entry, hookDir, pruned)) {
|
|
102568
|
+
continue;
|
|
102569
|
+
}
|
|
102570
|
+
keptGroups.push(group);
|
|
102571
|
+
continue;
|
|
102572
|
+
}
|
|
102573
|
+
const keptHooks = group.hooks.filter((h2) => {
|
|
102574
|
+
return !shouldPruneEntry(h2, hookDir, pruned);
|
|
102575
|
+
});
|
|
102576
|
+
if (keptHooks.length > 0) {
|
|
102577
|
+
keptGroups.push({ ...group, hooks: keptHooks });
|
|
102578
|
+
}
|
|
102579
|
+
}
|
|
102580
|
+
if (keptGroups.length > 0) {
|
|
102581
|
+
events[eventName] = keptGroups;
|
|
102582
|
+
} else {
|
|
102583
|
+
eventKeysToDelete.push(eventName);
|
|
102584
|
+
}
|
|
102585
|
+
}
|
|
102586
|
+
for (const key of eventKeysToDelete) {
|
|
102587
|
+
delete events[key];
|
|
102588
|
+
}
|
|
102589
|
+
return { settings, pruned };
|
|
102590
|
+
}
|
|
102591
|
+
function shouldPruneEntry(entry, hookDir, pruned) {
|
|
102592
|
+
if (entry._origin !== "engineer")
|
|
102593
|
+
return false;
|
|
102594
|
+
const filePath = extractHookFilePath(entry.command, hookDir);
|
|
102595
|
+
if (!filePath)
|
|
102596
|
+
return false;
|
|
102597
|
+
if (existsSync65(filePath))
|
|
102598
|
+
return false;
|
|
102599
|
+
pruned.push(basename26(filePath));
|
|
102600
|
+
return true;
|
|
102601
|
+
}
|
|
102602
|
+
function extractHookFilePath(command, hookDir) {
|
|
102603
|
+
if (!command)
|
|
102604
|
+
return null;
|
|
102605
|
+
if (/&&|\|\||;|(?<!["|'])\|(?!["|'])/.test(command))
|
|
102606
|
+
return null;
|
|
102607
|
+
const home5 = homedir45().replace(/\\/g, "/");
|
|
102608
|
+
const hookDirNorm = hookDir.replace(/\\/g, "/");
|
|
102609
|
+
function resolveEnvPath(prefix, rest) {
|
|
102610
|
+
const normRest = rest.replace(/\\/g, "/");
|
|
102611
|
+
let resolved;
|
|
102612
|
+
if (prefix === "$HOME" || prefix === "${HOME}" || prefix === "%USERPROFILE%") {
|
|
102613
|
+
resolved = `${home5}/${normRest}`;
|
|
102614
|
+
} else if (prefix === "$CLAUDE_PROJECT_DIR" || prefix === "%CLAUDE_PROJECT_DIR%") {
|
|
102615
|
+
const projectRoot = dirname36(dirname36(hookDirNorm));
|
|
102616
|
+
resolved = `${projectRoot}/${normRest}`;
|
|
102617
|
+
} else {
|
|
102618
|
+
resolved = `${prefix}/${normRest}`;
|
|
102619
|
+
}
|
|
102620
|
+
return resolved;
|
|
102621
|
+
}
|
|
102622
|
+
if (/^bash\s/.test(command)) {
|
|
102623
|
+
const bashMatch = command.match(/^bash\s+["']([^"']+\.sh)["']/);
|
|
102624
|
+
if (bashMatch) {
|
|
102625
|
+
const rawPath = bashMatch[1].replace(/\\/g, "/");
|
|
102626
|
+
const resolved = isAbsolute12(rawPath) || /^[A-Za-z]:[\\/]/.test(rawPath) ? rawPath : resolve41(hookDir, rawPath);
|
|
102627
|
+
return process.platform === "win32" ? resolved.replace(/\//g, sep13) : resolved;
|
|
102628
|
+
}
|
|
102629
|
+
return null;
|
|
102630
|
+
}
|
|
102631
|
+
if (!/(?:^|\s)node\s/.test(command))
|
|
102632
|
+
return null;
|
|
102633
|
+
const varOnlyQuoted = command.match(/(?:^|\s)node\s+["'](\$\w+|\$\{\w+\}|%\w+%)["'][/\\](\.claude[/\\]\S+)/);
|
|
102634
|
+
if (varOnlyQuoted) {
|
|
102635
|
+
const [, envVar, rest] = varOnlyQuoted;
|
|
102636
|
+
const resolved = resolveEnvPath(envVar, rest);
|
|
102637
|
+
return process.platform === "win32" ? resolved.replace(/\//g, sep13) : resolved;
|
|
102638
|
+
}
|
|
102639
|
+
const quotedMatch = command.match(/(?:^|\s)node\s+["']([^"']+)["']/);
|
|
102640
|
+
if (quotedMatch) {
|
|
102641
|
+
const rawArg = quotedMatch[1].trim().replace(/\\/g, "/");
|
|
102642
|
+
const envPrefixMatch = rawArg.match(/^(\$HOME|\$\{HOME\}|%USERPROFILE%|\$CLAUDE_PROJECT_DIR|%CLAUDE_PROJECT_DIR%)[/\\](.*)/);
|
|
102643
|
+
if (envPrefixMatch) {
|
|
102644
|
+
const resolved = resolveEnvPath(envPrefixMatch[1], envPrefixMatch[2]);
|
|
102645
|
+
return process.platform === "win32" ? resolved.replace(/\//g, sep13) : resolved;
|
|
102646
|
+
}
|
|
102647
|
+
const tildeResolved = rawArg.replace(/^~(?=\/)/, home5);
|
|
102648
|
+
if (isAbsolute12(tildeResolved) || /^[A-Za-z]:[\\/]/.test(tildeResolved)) {
|
|
102649
|
+
return process.platform === "win32" ? tildeResolved.replace(/\//g, sep13) : tildeResolved;
|
|
102650
|
+
}
|
|
102651
|
+
return resolve41(hookDir, tildeResolved);
|
|
102652
|
+
}
|
|
102653
|
+
const unquotedMatch = command.match(/(?:^|\s)node\s+(\S+\.(?:cjs|sh|mjs|js))/);
|
|
102654
|
+
if (unquotedMatch) {
|
|
102655
|
+
const rawArg = unquotedMatch[1].replace(/\\/g, "/");
|
|
102656
|
+
const envPrefixMatch = rawArg.match(/^(\$HOME|\$\{HOME\}|%USERPROFILE%|\$CLAUDE_PROJECT_DIR|%CLAUDE_PROJECT_DIR%)[/\\](.*)/);
|
|
102657
|
+
if (envPrefixMatch) {
|
|
102658
|
+
const resolved = resolveEnvPath(envPrefixMatch[1], envPrefixMatch[2]);
|
|
102659
|
+
return process.platform === "win32" ? resolved.replace(/\//g, sep13) : resolved;
|
|
102660
|
+
}
|
|
102661
|
+
const tildeResolved = rawArg.replace(/^~(?=\/)/, home5);
|
|
102662
|
+
if (isAbsolute12(tildeResolved) || /^[A-Za-z]:[\\/]/.test(tildeResolved)) {
|
|
102663
|
+
return process.platform === "win32" ? tildeResolved.replace(/\//g, sep13) : tildeResolved;
|
|
102664
|
+
}
|
|
102665
|
+
return resolve41(hookDir, tildeResolved);
|
|
102666
|
+
}
|
|
102667
|
+
return null;
|
|
102668
|
+
}
|
|
102669
|
+
|
|
102670
|
+
// src/domains/installation/merger/settings-processor.ts
|
|
102439
102671
|
init_command_normalizer();
|
|
102440
102672
|
init_logger();
|
|
102441
102673
|
init_path_resolver();
|
|
@@ -102452,6 +102684,7 @@ class SettingsProcessor {
|
|
|
102452
102684
|
installingKit;
|
|
102453
102685
|
cachedVersion = undefined;
|
|
102454
102686
|
deletionPatterns = [];
|
|
102687
|
+
zombiePrunerHookDir = null;
|
|
102455
102688
|
setGlobalFlag(isGlobal) {
|
|
102456
102689
|
this.isGlobal = isGlobal;
|
|
102457
102690
|
}
|
|
@@ -102472,6 +102705,9 @@ class SettingsProcessor {
|
|
|
102472
102705
|
setDeletions(deletions) {
|
|
102473
102706
|
this.deletionPatterns = deletions;
|
|
102474
102707
|
}
|
|
102708
|
+
setZombiePrunerHookDir(hookDir) {
|
|
102709
|
+
this.zombiePrunerHookDir = hookDir;
|
|
102710
|
+
}
|
|
102475
102711
|
initTracker() {
|
|
102476
102712
|
if (this.projectDir) {
|
|
102477
102713
|
this.tracker = new InstalledSettingsTracker(this.projectDir, this.isGlobal, this.kitName);
|
|
@@ -102582,6 +102818,12 @@ class SettingsProcessor {
|
|
|
102582
102818
|
if (hooksPruned > 0) {
|
|
102583
102819
|
logger.info(`Pruned ${hooksPruned} stale hook(s) referencing deleted files`);
|
|
102584
102820
|
}
|
|
102821
|
+
if (this.zombiePrunerHookDir) {
|
|
102822
|
+
const { pruned: zombiePruned } = pruneZombieEngineerWirings(mergeResult.merged, this.zombiePrunerHookDir);
|
|
102823
|
+
if (zombiePruned.length > 0) {
|
|
102824
|
+
logger.info(`Pruned ${zombiePruned.length} zombie hook entries: ${zombiePruned.join(", ")}`);
|
|
102825
|
+
}
|
|
102826
|
+
}
|
|
102585
102827
|
await SettingsMerger.writeSettingsFile(destFile, mergeResult.merged);
|
|
102586
102828
|
logger.success("Merged settings.json (user customizations preserved)");
|
|
102587
102829
|
await this.injectTeamHooksIfSupported(destFile, mergeResult.merged);
|
|
@@ -102827,7 +103069,7 @@ class SettingsProcessor {
|
|
|
102827
103069
|
return false;
|
|
102828
103070
|
}
|
|
102829
103071
|
const configuredGlobalDir = PathResolver.getGlobalKitDir().replace(/\\/g, "/").replace(/\/+$/, "");
|
|
102830
|
-
const defaultGlobalDir = join109(
|
|
103072
|
+
const defaultGlobalDir = join109(homedir46(), ".claude").replace(/\\/g, "/");
|
|
102831
103073
|
return configuredGlobalDir !== defaultGlobalDir;
|
|
102832
103074
|
}
|
|
102833
103075
|
getClaudeCommandRoot() {
|
|
@@ -102847,7 +103089,7 @@ class SettingsProcessor {
|
|
|
102847
103089
|
return true;
|
|
102848
103090
|
}
|
|
102849
103091
|
async repairSiblingSettingsLocal(destFile) {
|
|
102850
|
-
const settingsLocalPath = join109(
|
|
103092
|
+
const settingsLocalPath = join109(dirname37(destFile), "settings.local.json");
|
|
102851
103093
|
if (settingsLocalPath === destFile || !await import_fs_extra14.pathExists(settingsLocalPath)) {
|
|
102852
103094
|
return;
|
|
102853
103095
|
}
|
|
@@ -102987,6 +103229,9 @@ class CopyExecutor {
|
|
|
102987
103229
|
setKitName(kit) {
|
|
102988
103230
|
this.settingsProcessor.setKitName(kit);
|
|
102989
103231
|
}
|
|
103232
|
+
setZombiePrunerHookDir(hookDir) {
|
|
103233
|
+
this.settingsProcessor.setZombiePrunerHookDir(hookDir);
|
|
103234
|
+
}
|
|
102990
103235
|
setManifest(manifest) {
|
|
102991
103236
|
this.selectiveMerger = manifest ? new SelectiveMerger(manifest) : null;
|
|
102992
103237
|
if (manifest && this.selectiveMerger?.hasManifest()) {
|
|
@@ -103107,10 +103352,10 @@ class CopyExecutor {
|
|
|
103107
103352
|
}
|
|
103108
103353
|
trackInstalledFile(relativePath) {
|
|
103109
103354
|
this.installedFiles.add(relativePath);
|
|
103110
|
-
let dir =
|
|
103355
|
+
let dir = dirname38(relativePath);
|
|
103111
103356
|
while (dir && dir !== "." && dir !== "/") {
|
|
103112
103357
|
this.installedDirectories.add(`${dir}/`);
|
|
103113
|
-
dir =
|
|
103358
|
+
dir = dirname38(dir);
|
|
103114
103359
|
}
|
|
103115
103360
|
}
|
|
103116
103361
|
}
|
|
@@ -103156,6 +103401,9 @@ class FileMerger {
|
|
|
103156
103401
|
setDeletions(deletions) {
|
|
103157
103402
|
this.copyExecutor.setDeletions(deletions);
|
|
103158
103403
|
}
|
|
103404
|
+
setZombiePrunerHookDir(hookDir) {
|
|
103405
|
+
this.copyExecutor.setZombiePrunerHookDir(hookDir);
|
|
103406
|
+
}
|
|
103159
103407
|
setManifest(manifest) {
|
|
103160
103408
|
this.copyExecutor.setManifest(manifest);
|
|
103161
103409
|
}
|
|
@@ -103867,7 +104115,7 @@ function buildConflictSummary(fileConflicts, hookConflicts, mcpConflicts) {
|
|
|
103867
104115
|
init_logger();
|
|
103868
104116
|
init_skip_directories();
|
|
103869
104117
|
var import_fs_extra19 = __toESM(require_lib(), 1);
|
|
103870
|
-
import { join as join115, relative as relative25, resolve as
|
|
104118
|
+
import { join as join115, relative as relative25, resolve as resolve43 } from "node:path";
|
|
103871
104119
|
|
|
103872
104120
|
class FileScanner2 {
|
|
103873
104121
|
static async getFiles(dirPath, relativeTo) {
|
|
@@ -103947,8 +104195,8 @@ class FileScanner2 {
|
|
|
103947
104195
|
return customFiles;
|
|
103948
104196
|
}
|
|
103949
104197
|
static isSafePath(basePath, targetPath) {
|
|
103950
|
-
const resolvedBase =
|
|
103951
|
-
const resolvedTarget =
|
|
104198
|
+
const resolvedBase = resolve43(basePath);
|
|
104199
|
+
const resolvedTarget = resolve43(targetPath);
|
|
103952
104200
|
return resolvedTarget.startsWith(resolvedBase);
|
|
103953
104201
|
}
|
|
103954
104202
|
static toPosixPath(path16) {
|
|
@@ -104469,6 +104717,7 @@ async function handleMerge(ctx) {
|
|
|
104469
104717
|
merger.setForceOverwriteSettings(ctx.options.forceOverwriteSettings);
|
|
104470
104718
|
merger.setProjectDir(ctx.resolvedDir);
|
|
104471
104719
|
merger.setKitName(ctx.kit.name);
|
|
104720
|
+
merger.setZombiePrunerHookDir(join120(ctx.claudeDir, "hooks"));
|
|
104472
104721
|
if (ctx.kitType) {
|
|
104473
104722
|
merger.setMultiKitContext(ctx.claudeDir, ctx.kitType);
|
|
104474
104723
|
}
|
|
@@ -105259,7 +105508,7 @@ init_logger();
|
|
|
105259
105508
|
init_types3();
|
|
105260
105509
|
var import_fs_extra28 = __toESM(require_lib(), 1);
|
|
105261
105510
|
import { copyFile as copyFile7, mkdir as mkdir34, readdir as readdir36, rm as rm14, stat as stat21 } from "node:fs/promises";
|
|
105262
|
-
import { basename as
|
|
105511
|
+
import { basename as basename27, join as join124, normalize as normalize9 } from "node:path";
|
|
105263
105512
|
function validatePath2(path16, paramName) {
|
|
105264
105513
|
if (!path16 || typeof path16 !== "string") {
|
|
105265
105514
|
throw new SkillsMigrationError(`${paramName} must be a non-empty string`);
|
|
@@ -105395,7 +105644,7 @@ class SkillsBackupManager {
|
|
|
105395
105644
|
return size;
|
|
105396
105645
|
}
|
|
105397
105646
|
static extractBackupTimestamp(backupPath) {
|
|
105398
|
-
const dirName =
|
|
105647
|
+
const dirName = basename27(backupPath);
|
|
105399
105648
|
if (!dirName.startsWith(SkillsBackupManager.BACKUP_PREFIX)) {
|
|
105400
105649
|
return null;
|
|
105401
105650
|
}
|
|
@@ -105436,12 +105685,12 @@ async function getAllFiles(dirPath) {
|
|
|
105436
105685
|
return files;
|
|
105437
105686
|
}
|
|
105438
105687
|
async function hashFile(filePath) {
|
|
105439
|
-
return new Promise((
|
|
105688
|
+
return new Promise((resolve44, reject) => {
|
|
105440
105689
|
const hash = createHash8("sha256");
|
|
105441
105690
|
const stream = createReadStream2(filePath);
|
|
105442
105691
|
stream.on("data", (chunk) => hash.update(chunk));
|
|
105443
105692
|
stream.on("end", () => {
|
|
105444
|
-
|
|
105693
|
+
resolve44(hash.digest("hex"));
|
|
105445
105694
|
});
|
|
105446
105695
|
stream.on("error", (error) => {
|
|
105447
105696
|
stream.destroy();
|
|
@@ -106090,7 +106339,7 @@ async function handlePostInstall(ctx) {
|
|
|
106090
106339
|
init_config_manager();
|
|
106091
106340
|
init_github_client();
|
|
106092
106341
|
import { mkdir as mkdir36 } from "node:fs/promises";
|
|
106093
|
-
import { join as join134, resolve as
|
|
106342
|
+
import { join as join134, resolve as resolve47 } from "node:path";
|
|
106094
106343
|
|
|
106095
106344
|
// src/domains/github/kit-access-checker.ts
|
|
106096
106345
|
init_error2();
|
|
@@ -106259,8 +106508,8 @@ async function runPreflightChecks() {
|
|
|
106259
106508
|
|
|
106260
106509
|
// src/domains/installation/fresh-installer.ts
|
|
106261
106510
|
init_metadata_migration();
|
|
106262
|
-
import { existsSync as
|
|
106263
|
-
import { basename as
|
|
106511
|
+
import { existsSync as existsSync66, readdirSync as readdirSync9, rmSync as rmSync3, rmdirSync as rmdirSync2, unlinkSync as unlinkSync5 } from "node:fs";
|
|
106512
|
+
import { basename as basename28, dirname as dirname39, join as join132, resolve as resolve45 } from "node:path";
|
|
106264
106513
|
init_logger();
|
|
106265
106514
|
init_safe_spinner();
|
|
106266
106515
|
var import_fs_extra34 = __toESM(require_lib(), 1);
|
|
@@ -106312,15 +106561,15 @@ async function analyzeFreshInstallation(claudeDir3) {
|
|
|
106312
106561
|
};
|
|
106313
106562
|
}
|
|
106314
106563
|
function cleanupEmptyDirectories2(filePath, claudeDir3) {
|
|
106315
|
-
const normalizedClaudeDir =
|
|
106316
|
-
let currentDir =
|
|
106564
|
+
const normalizedClaudeDir = resolve45(claudeDir3);
|
|
106565
|
+
let currentDir = resolve45(dirname39(filePath));
|
|
106317
106566
|
while (currentDir !== normalizedClaudeDir && currentDir.startsWith(normalizedClaudeDir)) {
|
|
106318
106567
|
try {
|
|
106319
|
-
const entries =
|
|
106568
|
+
const entries = readdirSync9(currentDir);
|
|
106320
106569
|
if (entries.length === 0) {
|
|
106321
106570
|
rmdirSync2(currentDir);
|
|
106322
106571
|
logger.debug(`Removed empty directory: ${currentDir}`);
|
|
106323
|
-
currentDir =
|
|
106572
|
+
currentDir = resolve45(dirname39(currentDir));
|
|
106324
106573
|
} else {
|
|
106325
106574
|
break;
|
|
106326
106575
|
}
|
|
@@ -106343,7 +106592,7 @@ async function removeFilesByOwnership(claudeDir3, analysis, includeModified) {
|
|
|
106343
106592
|
}
|
|
106344
106593
|
for (const file of filesToRemove) {
|
|
106345
106594
|
const fullPath = join132(claudeDir3, file.path);
|
|
106346
|
-
if (!
|
|
106595
|
+
if (!existsSync66(fullPath)) {
|
|
106347
106596
|
continue;
|
|
106348
106597
|
}
|
|
106349
106598
|
try {
|
|
@@ -106401,8 +106650,8 @@ function getFreshBackupTargets(claudeDir3, analysis, includeModified) {
|
|
|
106401
106650
|
mutatePaths: filesToRemove.length > 0 ? ["metadata.json"] : []
|
|
106402
106651
|
};
|
|
106403
106652
|
}
|
|
106404
|
-
const deletePaths = CLAUDEKIT_SUBDIRECTORIES.filter((subdir) =>
|
|
106405
|
-
if (
|
|
106653
|
+
const deletePaths = CLAUDEKIT_SUBDIRECTORIES.filter((subdir) => existsSync66(join132(claudeDir3, subdir)));
|
|
106654
|
+
if (existsSync66(join132(claudeDir3, "metadata.json"))) {
|
|
106406
106655
|
deletePaths.push("metadata.json");
|
|
106407
106656
|
}
|
|
106408
106657
|
return {
|
|
@@ -106471,7 +106720,7 @@ async function handleFreshInstallation(claudeDir3, prompts) {
|
|
|
106471
106720
|
mutatePaths: backupTargets.mutatePaths,
|
|
106472
106721
|
scope: "claude"
|
|
106473
106722
|
});
|
|
106474
|
-
await cleanupOldDestructiveOperationBackups(undefined,
|
|
106723
|
+
await cleanupOldDestructiveOperationBackups(undefined, basename28(backup.backupDir));
|
|
106475
106724
|
backupSpinner.succeed(`Recovery backup saved to ${backup.backupDir}`);
|
|
106476
106725
|
} catch (error) {
|
|
106477
106726
|
backupSpinner.fail("Failed to create recovery backup");
|
|
@@ -106509,8 +106758,8 @@ async function handleFreshInstallation(claudeDir3, prompts) {
|
|
|
106509
106758
|
// src/domains/installation/global-kit-legacy-repair.ts
|
|
106510
106759
|
var import_fs_extra35 = __toESM(require_lib(), 1);
|
|
106511
106760
|
import { cp as cp5, mkdir as mkdir35, readdir as readdir41, rename as rename11, rm as rm16, stat as stat22 } from "node:fs/promises";
|
|
106512
|
-
import { homedir as
|
|
106513
|
-
import { dirname as
|
|
106761
|
+
import { homedir as homedir47 } from "node:os";
|
|
106762
|
+
import { dirname as dirname40, join as join133, normalize as normalize11, resolve as resolve46 } from "node:path";
|
|
106514
106763
|
var LEGACY_KIT_MARKERS = [
|
|
106515
106764
|
"metadata.json",
|
|
106516
106765
|
".ck.json",
|
|
@@ -106536,7 +106785,7 @@ function uniqueNormalizedPaths(paths) {
|
|
|
106536
106785
|
const seen = new Set;
|
|
106537
106786
|
const result = [];
|
|
106538
106787
|
for (const path16 of paths) {
|
|
106539
|
-
const normalized = normalize11(
|
|
106788
|
+
const normalized = normalize11(resolve46(path16));
|
|
106540
106789
|
if (seen.has(normalized))
|
|
106541
106790
|
continue;
|
|
106542
106791
|
seen.add(normalized);
|
|
@@ -106544,7 +106793,7 @@ function uniqueNormalizedPaths(paths) {
|
|
|
106544
106793
|
}
|
|
106545
106794
|
return result;
|
|
106546
106795
|
}
|
|
106547
|
-
function getLegacyWindowsGlobalKitDirCandidates(env2 = process.env, homeDir =
|
|
106796
|
+
function getLegacyWindowsGlobalKitDirCandidates(env2 = process.env, homeDir = homedir47()) {
|
|
106548
106797
|
const candidates = [];
|
|
106549
106798
|
const localAppData = safeEnvPath(env2.LOCALAPPDATA);
|
|
106550
106799
|
const appData = safeEnvPath(env2.APPDATA);
|
|
@@ -106601,8 +106850,8 @@ async function repairLegacyWindowsGlobalKitDir(options2) {
|
|
|
106601
106850
|
if (safeEnvPath(env2.CLAUDE_CONFIG_DIR)) {
|
|
106602
106851
|
return { status: "skipped", reason: "custom-global-dir", candidateDirs: [] };
|
|
106603
106852
|
}
|
|
106604
|
-
const targetDir = normalize11(
|
|
106605
|
-
const candidateDirs = getLegacyWindowsGlobalKitDirCandidates(env2, options2.homeDir).filter((candidate) => normalize11(
|
|
106853
|
+
const targetDir = normalize11(resolve46(options2.targetDir));
|
|
106854
|
+
const candidateDirs = getLegacyWindowsGlobalKitDirCandidates(env2, options2.homeDir).filter((candidate) => normalize11(resolve46(candidate)) !== targetDir);
|
|
106606
106855
|
const legacyDirs = [];
|
|
106607
106856
|
for (const candidate of candidateDirs) {
|
|
106608
106857
|
if (await hasKitMarkers(candidate)) {
|
|
@@ -106623,7 +106872,7 @@ async function repairLegacyWindowsGlobalKitDir(options2) {
|
|
|
106623
106872
|
if (targetExists) {
|
|
106624
106873
|
await rm16(targetDir, { recursive: true, force: true });
|
|
106625
106874
|
}
|
|
106626
|
-
await mkdir35(
|
|
106875
|
+
await mkdir35(dirname40(targetDir), { recursive: true });
|
|
106627
106876
|
await moveDirectory(legacyDir, targetDir);
|
|
106628
106877
|
return { status: "repaired", reason: "repaired", legacyDir, candidateDirs };
|
|
106629
106878
|
}
|
|
@@ -106825,7 +107074,7 @@ async function handleSelection(ctx) {
|
|
|
106825
107074
|
}
|
|
106826
107075
|
}
|
|
106827
107076
|
}
|
|
106828
|
-
const resolvedDir =
|
|
107077
|
+
const resolvedDir = resolve47(targetDir);
|
|
106829
107078
|
if (ctx.options.global) {
|
|
106830
107079
|
try {
|
|
106831
107080
|
const repairResult = await repairLegacyWindowsGlobalKitDir({ targetDir: resolvedDir });
|
|
@@ -107022,7 +107271,7 @@ async function handleSelection(ctx) {
|
|
|
107022
107271
|
}
|
|
107023
107272
|
// src/commands/init/phases/sync-handler.ts
|
|
107024
107273
|
import { copyFile as copyFile8, mkdir as mkdir37, open as open5, readFile as readFile59, rename as rename12, stat as stat23, unlink as unlink13, writeFile as writeFile33 } from "node:fs/promises";
|
|
107025
|
-
import { dirname as
|
|
107274
|
+
import { dirname as dirname41, join as join135, resolve as resolve48 } from "node:path";
|
|
107026
107275
|
init_logger();
|
|
107027
107276
|
init_path_resolver();
|
|
107028
107277
|
var import_fs_extra37 = __toESM(require_lib(), 1);
|
|
@@ -107031,7 +107280,7 @@ async function handleSync(ctx) {
|
|
|
107031
107280
|
if (!ctx.options.sync) {
|
|
107032
107281
|
return ctx;
|
|
107033
107282
|
}
|
|
107034
|
-
const resolvedDir = ctx.options.global ? PathResolver.getGlobalKitDir() :
|
|
107283
|
+
const resolvedDir = ctx.options.global ? PathResolver.getGlobalKitDir() : resolve48(ctx.options.dir || ".");
|
|
107035
107284
|
const claudeDir3 = ctx.options.global ? resolvedDir : join135(resolvedDir, ".claude");
|
|
107036
107285
|
if (!await import_fs_extra37.pathExists(claudeDir3)) {
|
|
107037
107286
|
logger.error("Cannot sync: no .claude directory found");
|
|
@@ -107141,7 +107390,7 @@ async function acquireSyncLock(global3) {
|
|
|
107141
107390
|
const lockPath = join135(cacheDir, ".sync-lock");
|
|
107142
107391
|
const startTime = Date.now();
|
|
107143
107392
|
const lockTimeout = getLockTimeout();
|
|
107144
|
-
await mkdir37(
|
|
107393
|
+
await mkdir37(dirname41(lockPath), { recursive: true });
|
|
107145
107394
|
while (Date.now() - startTime < lockTimeout) {
|
|
107146
107395
|
try {
|
|
107147
107396
|
const handle = await open5(lockPath, "wx");
|
|
@@ -107677,7 +107926,7 @@ async function transformFolderPaths(extractDir, folders, options2 = {}) {
|
|
|
107677
107926
|
// src/services/transformers/global-path-transformer.ts
|
|
107678
107927
|
init_logger();
|
|
107679
107928
|
import { readFile as readFile61, readdir as readdir43, writeFile as writeFile35 } from "node:fs/promises";
|
|
107680
|
-
import { homedir as
|
|
107929
|
+
import { homedir as homedir48, platform as platform15 } from "node:os";
|
|
107681
107930
|
import { extname as extname6, join as join138 } from "node:path";
|
|
107682
107931
|
var IS_WINDOWS3 = platform15() === "win32";
|
|
107683
107932
|
var HOME_PREFIX = "$HOME";
|
|
@@ -107688,7 +107937,7 @@ function normalizeInstallPath(path16) {
|
|
|
107688
107937
|
return path16.replace(/\\/g, "/").replace(/\/+$/, "");
|
|
107689
107938
|
}
|
|
107690
107939
|
function getDefaultGlobalClaudeDir() {
|
|
107691
|
-
return normalizeInstallPath(join138(
|
|
107940
|
+
return normalizeInstallPath(join138(homedir48(), ".claude"));
|
|
107692
107941
|
}
|
|
107693
107942
|
function getCustomGlobalClaudeDir(targetClaudeDir) {
|
|
107694
107943
|
if (!targetClaudeDir)
|
|
@@ -107808,8 +108057,8 @@ function transformContent(content, options2 = {}) {
|
|
|
107808
108057
|
}
|
|
107809
108058
|
function shouldTransformFile3(filename) {
|
|
107810
108059
|
const ext2 = extname6(filename).toLowerCase();
|
|
107811
|
-
const
|
|
107812
|
-
return TRANSFORMABLE_EXTENSIONS3.has(ext2) || ALWAYS_TRANSFORM_FILES.has(
|
|
108060
|
+
const basename29 = filename.split("/").pop() || filename;
|
|
108061
|
+
return TRANSFORMABLE_EXTENSIONS3.has(ext2) || ALWAYS_TRANSFORM_FILES.has(basename29);
|
|
107813
108062
|
}
|
|
107814
108063
|
async function transformPathsForGlobalInstall(directory, options2 = {}) {
|
|
107815
108064
|
let filesTransformed = 0;
|
|
@@ -108087,16 +108336,16 @@ async function initCommand(options2) {
|
|
|
108087
108336
|
// src/commands/migrate/migrate-command.ts
|
|
108088
108337
|
init_dist2();
|
|
108089
108338
|
var import_picocolors30 = __toESM(require_picocolors(), 1);
|
|
108090
|
-
import { existsSync as
|
|
108339
|
+
import { existsSync as existsSync67 } from "node:fs";
|
|
108091
108340
|
import { readFile as readFile65, rm as rm18, unlink as unlink14 } from "node:fs/promises";
|
|
108092
|
-
import { homedir as
|
|
108093
|
-
import { basename as
|
|
108341
|
+
import { homedir as homedir53 } from "node:os";
|
|
108342
|
+
import { basename as basename30, join as join143, resolve as resolve50 } from "node:path";
|
|
108094
108343
|
init_logger();
|
|
108095
108344
|
|
|
108096
108345
|
// src/ui/ck-cli-design/tokens.ts
|
|
108097
108346
|
var import_picocolors27 = __toESM(require_picocolors(), 1);
|
|
108098
|
-
import { homedir as
|
|
108099
|
-
import { resolve as
|
|
108347
|
+
import { homedir as homedir49, platform as platform16 } from "node:os";
|
|
108348
|
+
import { resolve as resolve49, win32 as win322 } from "node:path";
|
|
108100
108349
|
var PANEL_MIN_WIDTH = 60;
|
|
108101
108350
|
var PANEL_MAX_WIDTH = 72;
|
|
108102
108351
|
var DEFAULT_WIDTH = PANEL_MAX_WIDTH;
|
|
@@ -108253,11 +108502,11 @@ function wrapText(value, width) {
|
|
|
108253
108502
|
}
|
|
108254
108503
|
function formatDisplayPath(value) {
|
|
108255
108504
|
const normalized = value.replace(/\\/g, "/");
|
|
108256
|
-
const
|
|
108257
|
-
if (normalized ===
|
|
108505
|
+
const home5 = homedir49().replace(/\\/g, "/");
|
|
108506
|
+
if (normalized === home5)
|
|
108258
108507
|
return "~";
|
|
108259
|
-
if (normalized.startsWith(`${
|
|
108260
|
-
return normalized.replace(
|
|
108508
|
+
if (normalized.startsWith(`${home5}/`)) {
|
|
108509
|
+
return normalized.replace(home5, "~");
|
|
108261
108510
|
}
|
|
108262
108511
|
return normalized;
|
|
108263
108512
|
}
|
|
@@ -108266,7 +108515,7 @@ function formatCdHint(value, currentPlatform = platform16()) {
|
|
|
108266
108515
|
const absolutePath2 = win322.resolve(value);
|
|
108267
108516
|
return `cd /d "${absolutePath2}"`;
|
|
108268
108517
|
}
|
|
108269
|
-
const absolutePath =
|
|
108518
|
+
const absolutePath = resolve49(value);
|
|
108270
108519
|
const displayPath = formatDisplayPath(absolutePath);
|
|
108271
108520
|
if (displayPath.includes(" ")) {
|
|
108272
108521
|
return `cd "${displayPath}"`;
|
|
@@ -108567,13 +108816,13 @@ init_logger();
|
|
|
108567
108816
|
init_dist2();
|
|
108568
108817
|
init_model_taxonomy();
|
|
108569
108818
|
import { mkdir as mkdir39, readFile as readFile64, writeFile as writeFile37 } from "node:fs/promises";
|
|
108570
|
-
import { homedir as
|
|
108571
|
-
import { dirname as
|
|
108819
|
+
import { homedir as homedir52 } from "node:os";
|
|
108820
|
+
import { dirname as dirname42, join as join142 } from "node:path";
|
|
108572
108821
|
|
|
108573
108822
|
// src/commands/portable/models-dev-cache.ts
|
|
108574
108823
|
init_logger();
|
|
108575
108824
|
import { mkdir as mkdir38, readFile as readFile62, rename as rename14, writeFile as writeFile36 } from "node:fs/promises";
|
|
108576
|
-
import { homedir as
|
|
108825
|
+
import { homedir as homedir50 } from "node:os";
|
|
108577
108826
|
import { join as join140 } from "node:path";
|
|
108578
108827
|
|
|
108579
108828
|
class ModelsDevUnavailableError extends Error {
|
|
@@ -108586,7 +108835,7 @@ var MODELS_DEV_URL = "https://models.dev/api.json";
|
|
|
108586
108835
|
var CACHE_TTL_MS3 = 24 * 60 * 60 * 1000;
|
|
108587
108836
|
var FETCH_TIMEOUT_MS = 1e4;
|
|
108588
108837
|
function defaultCacheDir() {
|
|
108589
|
-
return join140(
|
|
108838
|
+
return join140(homedir50(), ".config", "claudekit", "cache");
|
|
108590
108839
|
}
|
|
108591
108840
|
function cacheFilePath(cacheDir) {
|
|
108592
108841
|
return join140(cacheDir, "models-dev.json");
|
|
@@ -108666,7 +108915,7 @@ async function getModelsDevCatalog(opts = {}) {
|
|
|
108666
108915
|
// src/commands/portable/opencode-model-discovery.ts
|
|
108667
108916
|
init_logger();
|
|
108668
108917
|
import { readFile as readFile63 } from "node:fs/promises";
|
|
108669
|
-
import { homedir as
|
|
108918
|
+
import { homedir as homedir51, platform as platform17 } from "node:os";
|
|
108670
108919
|
import { join as join141 } from "node:path";
|
|
108671
108920
|
function resolveOpenCodeAuthPath(homeDir) {
|
|
108672
108921
|
if (platform17() === "win32") {
|
|
@@ -108712,8 +108961,8 @@ function pickGenericModel(models) {
|
|
|
108712
108961
|
return sorted[0] ?? null;
|
|
108713
108962
|
}
|
|
108714
108963
|
async function resolveOpenCodeDefaultModel(opts = {}) {
|
|
108715
|
-
const
|
|
108716
|
-
const authedProviders = await readAuthedProviders(
|
|
108964
|
+
const home5 = opts.homeDir ?? homedir51();
|
|
108965
|
+
const authedProviders = await readAuthedProviders(home5);
|
|
108717
108966
|
if (authedProviders.length === 0) {
|
|
108718
108967
|
return { ok: false, reason: "no-auth", authedProviders: [] };
|
|
108719
108968
|
}
|
|
@@ -108776,7 +109025,7 @@ function messageForReason(reason) {
|
|
|
108776
109025
|
}
|
|
108777
109026
|
function getOpenCodeConfigPath(options2) {
|
|
108778
109027
|
if (options2.global) {
|
|
108779
|
-
return join142(options2.homeDir ??
|
|
109028
|
+
return join142(options2.homeDir ?? homedir52(), ".config", "opencode", "opencode.json");
|
|
108780
109029
|
}
|
|
108781
109030
|
return join142(options2.cwd ?? process.cwd(), "opencode.json");
|
|
108782
109031
|
}
|
|
@@ -108921,7 +109170,7 @@ async function ensureOpenCodeModel(options2) {
|
|
|
108921
109170
|
}
|
|
108922
109171
|
const chosenModel2 = response2.action === "custom" ? response2.value : suggestion2.model;
|
|
108923
109172
|
const next2 = { ...existing, model: chosenModel2 };
|
|
108924
|
-
await mkdir39(
|
|
109173
|
+
await mkdir39(dirname42(configPath), { recursive: true });
|
|
108925
109174
|
await writeFile37(configPath, `${JSON.stringify(next2, null, 2)}
|
|
108926
109175
|
`, "utf-8");
|
|
108927
109176
|
return { path: configPath, action: "added", model: chosenModel2, reason: suggestion2.reason };
|
|
@@ -108932,7 +109181,7 @@ async function ensureOpenCodeModel(options2) {
|
|
|
108932
109181
|
throw new OpenCodeAuthRequiredError(suggestion.failure);
|
|
108933
109182
|
}
|
|
108934
109183
|
const next2 = { ...existing ?? {}, model: suggestion.model };
|
|
108935
|
-
await mkdir39(
|
|
109184
|
+
await mkdir39(dirname42(configPath), { recursive: true });
|
|
108936
109185
|
await writeFile37(configPath, `${JSON.stringify(next2, null, 2)}
|
|
108937
109186
|
`, "utf-8");
|
|
108938
109187
|
return {
|
|
@@ -108954,7 +109203,7 @@ async function ensureOpenCodeModel(options2) {
|
|
|
108954
109203
|
}
|
|
108955
109204
|
const chosenModel = response.action === "custom" ? response.value : suggestion.ok ? suggestion.model : "";
|
|
108956
109205
|
const next = { ...existing ?? {}, model: chosenModel };
|
|
108957
|
-
await mkdir39(
|
|
109206
|
+
await mkdir39(dirname42(configPath), { recursive: true });
|
|
108958
109207
|
await writeFile37(configPath, `${JSON.stringify(next, null, 2)}
|
|
108959
109208
|
`, "utf-8");
|
|
108960
109209
|
return {
|
|
@@ -108967,7 +109216,7 @@ async function ensureOpenCodeModel(options2) {
|
|
|
108967
109216
|
|
|
108968
109217
|
// src/commands/portable/plan-display.ts
|
|
108969
109218
|
var import_picocolors28 = __toESM(require_picocolors(), 1);
|
|
108970
|
-
import { basename as
|
|
109219
|
+
import { basename as basename29, dirname as dirname43, extname as extname7 } from "node:path";
|
|
108971
109220
|
var DEFAULT_MAX_PLAN_GROUP_ITEMS = 20;
|
|
108972
109221
|
var TYPE_ORDER = [
|
|
108973
109222
|
"agent",
|
|
@@ -109193,21 +109442,21 @@ function collectPlannedWhereLines(plan) {
|
|
|
109193
109442
|
return destinations.map((destination) => `${formatDisplayPath(destination)} -> ${formatCdHint(resolveCdTarget(destination))}`);
|
|
109194
109443
|
}
|
|
109195
109444
|
function resolveCdTarget(destination) {
|
|
109196
|
-
return extname7(destination).length > 0 ?
|
|
109445
|
+
return extname7(destination).length > 0 ? dirname43(destination) : destination;
|
|
109197
109446
|
}
|
|
109198
109447
|
function normalizeWhereDestination(path16, portableType) {
|
|
109199
109448
|
if (portableType === "agent" || portableType === "command" || portableType === "skill") {
|
|
109200
|
-
return
|
|
109449
|
+
return dirname43(path16);
|
|
109201
109450
|
}
|
|
109202
109451
|
if (portableType === "hooks") {
|
|
109203
|
-
return
|
|
109452
|
+
return dirname43(path16);
|
|
109204
109453
|
}
|
|
109205
109454
|
if (portableType === "rules") {
|
|
109206
|
-
const fileName =
|
|
109455
|
+
const fileName = basename29(path16).toLowerCase();
|
|
109207
109456
|
if (fileName === "agents.md" || fileName === "gemini.md" || fileName === ".goosehints" || fileName === "custom_modes.yaml" || fileName === "custom_modes.yml") {
|
|
109208
109457
|
return path16;
|
|
109209
109458
|
}
|
|
109210
|
-
return
|
|
109459
|
+
return dirname43(path16);
|
|
109211
109460
|
}
|
|
109212
109461
|
return path16;
|
|
109213
109462
|
}
|
|
@@ -109728,9 +109977,9 @@ function shouldExecuteAction2(action) {
|
|
|
109728
109977
|
}
|
|
109729
109978
|
async function executeDeleteAction(action, options2) {
|
|
109730
109979
|
const preservePaths = options2?.preservePaths ?? new Set;
|
|
109731
|
-
const shouldPreserveTarget = action.targetPath.length > 0 && preservePaths.has(
|
|
109980
|
+
const shouldPreserveTarget = action.targetPath.length > 0 && preservePaths.has(resolve50(action.targetPath));
|
|
109732
109981
|
try {
|
|
109733
|
-
if (!shouldPreserveTarget && action.targetPath &&
|
|
109982
|
+
if (!shouldPreserveTarget && action.targetPath && existsSync67(action.targetPath)) {
|
|
109734
109983
|
await rm18(action.targetPath, { recursive: true, force: true });
|
|
109735
109984
|
}
|
|
109736
109985
|
await removePortableInstallation(action.item, action.type, action.provider, action.global, action.targetPath ? { path: action.targetPath } : undefined);
|
|
@@ -109761,8 +110010,8 @@ async function executeDeleteAction(action, options2) {
|
|
|
109761
110010
|
async function processMetadataDeletions(skillSourcePath, installGlobally) {
|
|
109762
110011
|
if (!skillSourcePath)
|
|
109763
110012
|
return;
|
|
109764
|
-
const sourceMetadataPath = join143(
|
|
109765
|
-
if (!
|
|
110013
|
+
const sourceMetadataPath = join143(resolve50(skillSourcePath, ".."), "metadata.json");
|
|
110014
|
+
if (!existsSync67(sourceMetadataPath))
|
|
109766
110015
|
return;
|
|
109767
110016
|
let sourceMetadata;
|
|
109768
110017
|
try {
|
|
@@ -109774,8 +110023,8 @@ async function processMetadataDeletions(skillSourcePath, installGlobally) {
|
|
|
109774
110023
|
}
|
|
109775
110024
|
if (!sourceMetadata.deletions || sourceMetadata.deletions.length === 0)
|
|
109776
110025
|
return;
|
|
109777
|
-
const claudeDir3 = installGlobally ? join143(
|
|
109778
|
-
if (!
|
|
110026
|
+
const claudeDir3 = installGlobally ? join143(homedir53(), ".claude") : join143(process.cwd(), ".claude");
|
|
110027
|
+
if (!existsSync67(claudeDir3))
|
|
109779
110028
|
return;
|
|
109780
110029
|
try {
|
|
109781
110030
|
const result = await handleDeletions(sourceMetadata, claudeDir3, inferKitTypeFromSourceMetadata(sourceMetadata));
|
|
@@ -109903,7 +110152,7 @@ async function migrateCommand(options2) {
|
|
|
109903
110152
|
let installGlobally = requestedGlobal;
|
|
109904
110153
|
if (options2.global === undefined && !options2.yes) {
|
|
109905
110154
|
const projectTarget = join143(process.cwd(), ".claude");
|
|
109906
|
-
const globalTarget = join143(
|
|
110155
|
+
const globalTarget = join143(homedir53(), ".claude");
|
|
109907
110156
|
const scopeChoice = await ie({
|
|
109908
110157
|
message: "Installation scope",
|
|
109909
110158
|
options: [
|
|
@@ -109976,7 +110225,7 @@ async function migrateCommand(options2) {
|
|
|
109976
110225
|
}).join(`
|
|
109977
110226
|
`));
|
|
109978
110227
|
if (sourceGlobalOnly) {
|
|
109979
|
-
f2.info(import_picocolors30.default.dim(` Scope: global (--global / -g) - reading from ${formatDisplayPath(join143(
|
|
110228
|
+
f2.info(import_picocolors30.default.dim(` Scope: global (--global / -g) - reading from ${formatDisplayPath(join143(homedir53(), ".claude"))}`));
|
|
109980
110229
|
} else {
|
|
109981
110230
|
f2.info(import_picocolors30.default.dim(` CWD: ${process.cwd()}`));
|
|
109982
110231
|
}
|
|
@@ -110067,7 +110316,7 @@ async function migrateCommand(options2) {
|
|
|
110067
110316
|
const interactive = process.stdout.isTTY && !options2.yes;
|
|
110068
110317
|
const conflictActions = plan.actions.filter((a3) => a3.action === "conflict");
|
|
110069
110318
|
for (const action of conflictActions) {
|
|
110070
|
-
if (!action.diff && action.targetPath &&
|
|
110319
|
+
if (!action.diff && action.targetPath && existsSync67(action.targetPath)) {
|
|
110071
110320
|
try {
|
|
110072
110321
|
const targetContent = await readFile65(action.targetPath, "utf-8");
|
|
110073
110322
|
const sourceItem = effectiveAgents.find((a3) => a3.name === action.item) || effectiveCommands.find((c2) => c2.name === action.item) || (effectiveConfigItem?.name === action.item ? effectiveConfigItem : null) || effectiveRuleItems.find((r2) => r2.name === action.item) || effectiveHookItems.find((h2) => h2.name === action.item);
|
|
@@ -110182,18 +110431,18 @@ async function migrateCommand(options2) {
|
|
|
110182
110431
|
const recordSuccessfulWrites = (task, taskResults) => {
|
|
110183
110432
|
for (const result of taskResults.filter((entry) => entry.success && !entry.skipped)) {
|
|
110184
110433
|
if (result.path.length > 0) {
|
|
110185
|
-
writtenPaths.add(
|
|
110434
|
+
writtenPaths.add(resolve50(result.path));
|
|
110186
110435
|
}
|
|
110187
110436
|
if (task.type === "hooks") {
|
|
110188
110437
|
const existing = successfulHookFiles.get(task.provider) ?? {
|
|
110189
110438
|
files: [],
|
|
110190
110439
|
global: task.global
|
|
110191
110440
|
};
|
|
110192
|
-
existing.files.push(
|
|
110441
|
+
existing.files.push(basename30(result.path));
|
|
110193
110442
|
successfulHookFiles.set(task.provider, existing);
|
|
110194
110443
|
if (result.path.length > 0) {
|
|
110195
110444
|
const absExisting = successfulHookAbsPaths.get(task.provider) ?? [];
|
|
110196
|
-
absExisting.push(
|
|
110445
|
+
absExisting.push(resolve50(result.path));
|
|
110197
110446
|
successfulHookAbsPaths.set(task.provider, absExisting);
|
|
110198
110447
|
}
|
|
110199
110448
|
}
|
|
@@ -110327,7 +110576,7 @@ async function migrateCommand(options2) {
|
|
|
110327
110576
|
});
|
|
110328
110577
|
if (staleSlugs.length > 0) {
|
|
110329
110578
|
const staleSlugSet = new Set(staleSlugs.map((s) => `${s}.toml`));
|
|
110330
|
-
const removed = await removeInstallationsByFilter((i) => i.type === "agent" && i.provider === provider && i.global === scope2 && staleSlugSet.has(
|
|
110579
|
+
const removed = await removeInstallationsByFilter((i) => i.type === "agent" && i.provider === provider && i.global === scope2 && staleSlugSet.has(basename30(i.path)));
|
|
110331
110580
|
for (const entry of removed) {
|
|
110332
110581
|
logger.verbose(`[migrate] Cleaned stale registry entry: ${entry.item} (${provider})`);
|
|
110333
110582
|
}
|
|
@@ -110335,7 +110584,7 @@ async function migrateCommand(options2) {
|
|
|
110335
110584
|
}
|
|
110336
110585
|
}
|
|
110337
110586
|
try {
|
|
110338
|
-
const kitRoot = (agentSource ?
|
|
110587
|
+
const kitRoot = (agentSource ? resolve50(agentSource, "..") : null) ?? (commandSource ? resolve50(commandSource, "..") : null) ?? (skillSource ? resolve50(skillSource, "..") : null) ?? null;
|
|
110339
110588
|
const manifest = kitRoot ? await loadPortableManifest(kitRoot) : null;
|
|
110340
110589
|
if (manifest?.cliVersion) {
|
|
110341
110590
|
await updateAppliedManifestVersion(manifest.cliVersion);
|
|
@@ -110383,7 +110632,7 @@ async function migrateCommand(options2) {
|
|
|
110383
110632
|
async function rollbackResults(results) {
|
|
110384
110633
|
const rolledBackPaths = new Set;
|
|
110385
110634
|
for (const result of results) {
|
|
110386
|
-
if (!result.path || !
|
|
110635
|
+
if (!result.path || !existsSync67(result.path))
|
|
110387
110636
|
continue;
|
|
110388
110637
|
try {
|
|
110389
110638
|
if (result.overwritten)
|
|
@@ -110532,7 +110781,7 @@ var import_picocolors31 = __toESM(require_picocolors(), 1);
|
|
|
110532
110781
|
|
|
110533
110782
|
// src/commands/new/phases/directory-setup.ts
|
|
110534
110783
|
init_config_manager();
|
|
110535
|
-
import { resolve as
|
|
110784
|
+
import { resolve as resolve51 } from "node:path";
|
|
110536
110785
|
init_logger();
|
|
110537
110786
|
init_path_resolver();
|
|
110538
110787
|
init_types3();
|
|
@@ -110617,7 +110866,7 @@ async function directorySetup(validOptions, prompts) {
|
|
|
110617
110866
|
targetDir = await prompts.getDirectory(targetDir);
|
|
110618
110867
|
}
|
|
110619
110868
|
}
|
|
110620
|
-
const resolvedDir =
|
|
110869
|
+
const resolvedDir = resolve51(targetDir);
|
|
110621
110870
|
logger.info(`Target directory: ${resolvedDir}`);
|
|
110622
110871
|
if (PathResolver.isLocalSameAsGlobal(resolvedDir)) {
|
|
110623
110872
|
logger.warning("You're creating a project at HOME directory.");
|
|
@@ -110950,8 +111199,8 @@ Please use only one download method.`);
|
|
|
110950
111199
|
}
|
|
110951
111200
|
// src/commands/plan/plan-command.ts
|
|
110952
111201
|
init_output_manager();
|
|
110953
|
-
import { existsSync as
|
|
110954
|
-
import { dirname as
|
|
111202
|
+
import { existsSync as existsSync70, statSync as statSync12 } from "node:fs";
|
|
111203
|
+
import { dirname as dirname47, isAbsolute as isAbsolute14, join as join148, parse as parse7, resolve as resolve55 } from "node:path";
|
|
110955
111204
|
|
|
110956
111205
|
// src/commands/plan/plan-read-handlers.ts
|
|
110957
111206
|
init_config();
|
|
@@ -110960,19 +111209,19 @@ init_plans_registry();
|
|
|
110960
111209
|
init_logger();
|
|
110961
111210
|
init_output_manager();
|
|
110962
111211
|
var import_picocolors32 = __toESM(require_picocolors(), 1);
|
|
110963
|
-
import { existsSync as
|
|
110964
|
-
import { basename as
|
|
111212
|
+
import { existsSync as existsSync69, statSync as statSync11 } from "node:fs";
|
|
111213
|
+
import { basename as basename31, dirname as dirname45, join as join147, relative as relative31, resolve as resolve53 } from "node:path";
|
|
110965
111214
|
|
|
110966
111215
|
// src/commands/plan/plan-dependencies.ts
|
|
110967
111216
|
init_config();
|
|
110968
111217
|
init_plan_parser();
|
|
110969
111218
|
init_plans_registry();
|
|
110970
|
-
import { existsSync as
|
|
110971
|
-
import { dirname as
|
|
111219
|
+
import { existsSync as existsSync68 } from "node:fs";
|
|
111220
|
+
import { dirname as dirname44, join as join146 } from "node:path";
|
|
110972
111221
|
async function resolvePlanDependencies(references, currentPlanFile, options2 = {}) {
|
|
110973
111222
|
if (references.length === 0)
|
|
110974
111223
|
return [];
|
|
110975
|
-
const currentPlanDir =
|
|
111224
|
+
const currentPlanDir = dirname44(currentPlanFile);
|
|
110976
111225
|
const projectRoot = findProjectRoot(currentPlanDir);
|
|
110977
111226
|
const config = options2.preloadedConfig ?? (await CkConfigManager.loadFull(projectRoot)).config;
|
|
110978
111227
|
const defaultScope = inferPlanScopeForDir(currentPlanDir, config);
|
|
@@ -110990,7 +111239,7 @@ async function resolvePlanDependencies(references, currentPlanFile, options2 = {
|
|
|
110990
111239
|
const scopeRoot = resolvePlanDirForScope(scope, projectRoot, config);
|
|
110991
111240
|
const planFile = join146(scopeRoot, planId, "plan.md");
|
|
110992
111241
|
const isSelfReference = planFile === currentPlanFile;
|
|
110993
|
-
if (!
|
|
111242
|
+
if (!existsSync68(planFile)) {
|
|
110994
111243
|
return {
|
|
110995
111244
|
reference,
|
|
110996
111245
|
scope,
|
|
@@ -111019,14 +111268,14 @@ init_config();
|
|
|
111019
111268
|
init_plan_parser();
|
|
111020
111269
|
init_plan_scope();
|
|
111021
111270
|
init_plans_registry();
|
|
111022
|
-
import { isAbsolute as
|
|
111271
|
+
import { isAbsolute as isAbsolute13, resolve as resolve52 } from "node:path";
|
|
111023
111272
|
async function getGlobalPlansDirFromCwd() {
|
|
111024
111273
|
const projectRoot = findProjectRoot(process.cwd());
|
|
111025
111274
|
const { config } = await CkConfigManager.loadFull(projectRoot);
|
|
111026
111275
|
return resolveGlobalPlansDir(config);
|
|
111027
111276
|
}
|
|
111028
111277
|
function resolveTargetFromBase(target, baseDir) {
|
|
111029
|
-
const resolvedTarget =
|
|
111278
|
+
const resolvedTarget = isAbsolute13(target) ? resolve52(target) : resolve52(baseDir, target);
|
|
111030
111279
|
return isWithinDir(resolvedTarget, baseDir) ? resolvedTarget : null;
|
|
111031
111280
|
}
|
|
111032
111281
|
|
|
@@ -111059,7 +111308,7 @@ async function handleParse(target, options2) {
|
|
|
111059
111308
|
console.log(JSON.stringify({ file: relative31(process.cwd(), planFile), frontmatter, phases }, null, 2));
|
|
111060
111309
|
return;
|
|
111061
111310
|
}
|
|
111062
|
-
const title = typeof frontmatter.title === "string" ? frontmatter.title :
|
|
111311
|
+
const title = typeof frontmatter.title === "string" ? frontmatter.title : basename31(dirname45(planFile));
|
|
111063
111312
|
console.log();
|
|
111064
111313
|
console.log(import_picocolors32.default.bold(` Plan: ${title}`));
|
|
111065
111314
|
console.log(` File: ${planFile}`);
|
|
@@ -111129,8 +111378,8 @@ async function handleStatus(target, options2) {
|
|
|
111129
111378
|
return;
|
|
111130
111379
|
}
|
|
111131
111380
|
const effectiveTarget = !resolvedTarget && globalBaseDir ? globalBaseDir : resolvedTarget;
|
|
111132
|
-
const t = effectiveTarget ?
|
|
111133
|
-
const plansDir = t &&
|
|
111381
|
+
const t = effectiveTarget ? resolve53(effectiveTarget) : null;
|
|
111382
|
+
const plansDir = t && existsSync69(t) && statSync11(t).isDirectory() && !existsSync69(join147(t, "plan.md")) ? t : null;
|
|
111134
111383
|
if (plansDir) {
|
|
111135
111384
|
const planFiles = scanPlanDir(plansDir);
|
|
111136
111385
|
if (planFiles.length === 0) {
|
|
@@ -111170,7 +111419,7 @@ async function handleStatus(target, options2) {
|
|
|
111170
111419
|
const blockedBy2 = await resolvePlanDependencies(s.blockedBy, pf, { preloadedConfig });
|
|
111171
111420
|
const blocks2 = await resolvePlanDependencies(s.blocks, pf, { preloadedConfig });
|
|
111172
111421
|
const bar = progressBar(s.completed, s.totalPhases);
|
|
111173
|
-
const title2 = s.title ??
|
|
111422
|
+
const title2 = s.title ?? basename31(dirname45(pf));
|
|
111174
111423
|
console.log(` ${import_picocolors32.default.bold(title2)}`);
|
|
111175
111424
|
console.log(` ${bar}`);
|
|
111176
111425
|
if (s.inProgress > 0)
|
|
@@ -111189,7 +111438,7 @@ async function handleStatus(target, options2) {
|
|
|
111189
111438
|
}
|
|
111190
111439
|
console.log();
|
|
111191
111440
|
} catch {
|
|
111192
|
-
console.log(` [X] Failed to read: ${
|
|
111441
|
+
console.log(` [X] Failed to read: ${basename31(dirname45(pf))}`);
|
|
111193
111442
|
console.log();
|
|
111194
111443
|
}
|
|
111195
111444
|
}
|
|
@@ -111216,7 +111465,7 @@ async function handleStatus(target, options2) {
|
|
|
111216
111465
|
console.log(JSON.stringify({ ...summary, dependencyStatus: { blockedBy, blocks } }, null, 2));
|
|
111217
111466
|
return;
|
|
111218
111467
|
}
|
|
111219
|
-
const title = summary.title ??
|
|
111468
|
+
const title = summary.title ?? basename31(dirname45(planFile));
|
|
111220
111469
|
console.log();
|
|
111221
111470
|
console.log(import_picocolors32.default.bold(` ${title}`));
|
|
111222
111471
|
if (summary.status)
|
|
@@ -111279,7 +111528,7 @@ async function handleKanban(target, options2) {
|
|
|
111279
111528
|
process.exitCode = 1;
|
|
111280
111529
|
return;
|
|
111281
111530
|
}
|
|
111282
|
-
const route = `/plans?dir=${encodeURIComponent(
|
|
111531
|
+
const route = `/plans?dir=${encodeURIComponent(dirname45(dirname45(planFile)))}&view=kanban`;
|
|
111283
111532
|
const url = `http://localhost:${server.port}${route}`;
|
|
111284
111533
|
console.log();
|
|
111285
111534
|
console.log(import_picocolors32.default.bold(" ClaudeKit Dashboard — Plans"));
|
|
@@ -111314,7 +111563,18 @@ init_plan_parser();
|
|
|
111314
111563
|
init_plans_registry();
|
|
111315
111564
|
init_output_manager();
|
|
111316
111565
|
var import_picocolors33 = __toESM(require_picocolors(), 1);
|
|
111317
|
-
import { basename as
|
|
111566
|
+
import { basename as basename32, dirname as dirname46, relative as relative32, resolve as resolve54 } from "node:path";
|
|
111567
|
+
function quoteReadTarget(filePath) {
|
|
111568
|
+
return `"${filePath.replace(/\\/g, "/").replace(/"/g, "\\\"")}"`;
|
|
111569
|
+
}
|
|
111570
|
+
function buildPlanCreateReadReminder(planFile, phaseFiles, cwd2 = process.cwd()) {
|
|
111571
|
+
const files = [planFile, ...phaseFiles].map((file) => quoteReadTarget(relative32(cwd2, file)));
|
|
111572
|
+
return [
|
|
111573
|
+
" [i] Claude Code agents: read plan.md and every phase-*.md before editing.",
|
|
111574
|
+
" These files already exist; Write/Edit without Read may be rejected after wasting tokens.",
|
|
111575
|
+
` cat ${files.join(" ")}`
|
|
111576
|
+
];
|
|
111577
|
+
}
|
|
111318
111578
|
async function handleCreate(target, options2) {
|
|
111319
111579
|
if (!options2.title) {
|
|
111320
111580
|
output.error("[X] --title is required for create");
|
|
@@ -111346,13 +111606,13 @@ async function handleCreate(target, options2) {
|
|
|
111346
111606
|
return;
|
|
111347
111607
|
}
|
|
111348
111608
|
const globalBaseDir = options2.global ? await getGlobalPlansDirFromCwd() : undefined;
|
|
111349
|
-
const resolvedDir = globalBaseDir ? resolveTargetFromBase(dir, globalBaseDir) :
|
|
111609
|
+
const resolvedDir = globalBaseDir ? resolveTargetFromBase(dir, globalBaseDir) : resolve54(dir);
|
|
111350
111610
|
if (globalBaseDir && !resolvedDir) {
|
|
111351
111611
|
output.error("[X] Target directory must stay within the configured global plans root");
|
|
111352
111612
|
process.exitCode = 1;
|
|
111353
111613
|
return;
|
|
111354
111614
|
}
|
|
111355
|
-
const safeResolvedDir = resolvedDir ??
|
|
111615
|
+
const safeResolvedDir = resolvedDir ?? resolve54(dir);
|
|
111356
111616
|
const result = scaffoldPlan({
|
|
111357
111617
|
title: options2.title,
|
|
111358
111618
|
phases: phaseNames.map((name2) => ({ name: name2 })),
|
|
@@ -111390,7 +111650,10 @@ async function handleCreate(target, options2) {
|
|
|
111390
111650
|
console.log(` Directory: ${safeResolvedDir}`);
|
|
111391
111651
|
console.log(` Phases: ${result.phaseFiles.length}`);
|
|
111392
111652
|
for (const f3 of result.phaseFiles) {
|
|
111393
|
-
console.log(` [ ] ${
|
|
111653
|
+
console.log(` [ ] ${basename32(f3)}`);
|
|
111654
|
+
}
|
|
111655
|
+
for (const line of buildPlanCreateReadReminder(result.planFile, result.phaseFiles)) {
|
|
111656
|
+
console.log(line);
|
|
111394
111657
|
}
|
|
111395
111658
|
console.log();
|
|
111396
111659
|
}
|
|
@@ -111414,7 +111677,7 @@ async function handleCheck(target, options2) {
|
|
|
111414
111677
|
process.exitCode = 1;
|
|
111415
111678
|
return;
|
|
111416
111679
|
}
|
|
111417
|
-
const planDir =
|
|
111680
|
+
const planDir = dirname46(planFile);
|
|
111418
111681
|
let planStatus = "pending";
|
|
111419
111682
|
try {
|
|
111420
111683
|
const projectRoot = findProjectRoot(planDir);
|
|
@@ -111463,7 +111726,7 @@ async function handleUncheck(target, options2) {
|
|
|
111463
111726
|
process.exitCode = 1;
|
|
111464
111727
|
return;
|
|
111465
111728
|
}
|
|
111466
|
-
const planDir =
|
|
111729
|
+
const planDir = dirname46(planFile);
|
|
111467
111730
|
try {
|
|
111468
111731
|
const projectRoot = findProjectRoot(planDir);
|
|
111469
111732
|
const summary = buildPlanSummary(planFile);
|
|
@@ -111502,7 +111765,7 @@ async function handleAddPhase(target, options2) {
|
|
|
111502
111765
|
try {
|
|
111503
111766
|
const result = addPhase(planFile, target, options2.after);
|
|
111504
111767
|
try {
|
|
111505
|
-
const planDir =
|
|
111768
|
+
const planDir = dirname46(planFile);
|
|
111506
111769
|
const projectRoot = findProjectRoot(planDir);
|
|
111507
111770
|
updateRegistryAddPhase({
|
|
111508
111771
|
planDir,
|
|
@@ -111528,25 +111791,25 @@ async function handleAddPhase(target, options2) {
|
|
|
111528
111791
|
// src/commands/plan/plan-command.ts
|
|
111529
111792
|
function resolveTargetPath(target, baseDir) {
|
|
111530
111793
|
if (!baseDir) {
|
|
111531
|
-
return
|
|
111794
|
+
return resolve55(target);
|
|
111532
111795
|
}
|
|
111533
|
-
if (
|
|
111534
|
-
return
|
|
111796
|
+
if (isAbsolute14(target)) {
|
|
111797
|
+
return resolve55(target);
|
|
111535
111798
|
}
|
|
111536
|
-
const cwdCandidate =
|
|
111537
|
-
if (
|
|
111799
|
+
const cwdCandidate = resolve55(target);
|
|
111800
|
+
if (existsSync70(cwdCandidate)) {
|
|
111538
111801
|
return cwdCandidate;
|
|
111539
111802
|
}
|
|
111540
|
-
return
|
|
111803
|
+
return resolve55(baseDir, target);
|
|
111541
111804
|
}
|
|
111542
111805
|
function resolvePlanFile(target, baseDir) {
|
|
111543
|
-
const t = target ? resolveTargetPath(target, baseDir) : baseDir ?
|
|
111544
|
-
if (
|
|
111806
|
+
const t = target ? resolveTargetPath(target, baseDir) : baseDir ? resolve55(baseDir) : process.cwd();
|
|
111807
|
+
if (existsSync70(t)) {
|
|
111545
111808
|
const stat24 = statSync12(t);
|
|
111546
111809
|
if (stat24.isFile())
|
|
111547
111810
|
return t;
|
|
111548
111811
|
const candidate = join148(t, "plan.md");
|
|
111549
|
-
if (
|
|
111812
|
+
if (existsSync70(candidate))
|
|
111550
111813
|
return candidate;
|
|
111551
111814
|
}
|
|
111552
111815
|
if (!target && !baseDir) {
|
|
@@ -111554,9 +111817,9 @@ function resolvePlanFile(target, baseDir) {
|
|
|
111554
111817
|
const root = parse7(dir).root;
|
|
111555
111818
|
while (dir !== root) {
|
|
111556
111819
|
const candidate = join148(dir, "plan.md");
|
|
111557
|
-
if (
|
|
111820
|
+
if (existsSync70(candidate))
|
|
111558
111821
|
return candidate;
|
|
111559
|
-
dir =
|
|
111822
|
+
dir = dirname47(dir);
|
|
111560
111823
|
}
|
|
111561
111824
|
}
|
|
111562
111825
|
return null;
|
|
@@ -111604,7 +111867,7 @@ async function planCommand(action, target, options2) {
|
|
|
111604
111867
|
let resolvedTarget = target;
|
|
111605
111868
|
if (resolvedAction && !knownActions.has(resolvedAction)) {
|
|
111606
111869
|
const looksLikePath = resolvedAction.includes("/") || resolvedAction.includes("\\") || resolvedAction.endsWith(".md") || resolvedAction === "." || resolvedAction === "..";
|
|
111607
|
-
const existsOnDisk = !looksLikePath &&
|
|
111870
|
+
const existsOnDisk = !looksLikePath && existsSync70(resolve55(resolvedAction));
|
|
111608
111871
|
if (looksLikePath || existsOnDisk) {
|
|
111609
111872
|
resolvedTarget = resolvedAction;
|
|
111610
111873
|
resolvedAction = undefined;
|
|
@@ -111646,13 +111909,13 @@ init_claudekit_data2();
|
|
|
111646
111909
|
init_logger();
|
|
111647
111910
|
init_safe_prompts();
|
|
111648
111911
|
var import_picocolors34 = __toESM(require_picocolors(), 1);
|
|
111649
|
-
import { existsSync as
|
|
111650
|
-
import { resolve as
|
|
111912
|
+
import { existsSync as existsSync71 } from "node:fs";
|
|
111913
|
+
import { resolve as resolve56 } from "node:path";
|
|
111651
111914
|
async function handleAdd(projectPath, options2) {
|
|
111652
111915
|
logger.debug(`Adding project: ${projectPath}, options: ${JSON.stringify(options2)}`);
|
|
111653
111916
|
intro("Add Project");
|
|
111654
|
-
const absolutePath =
|
|
111655
|
-
if (!
|
|
111917
|
+
const absolutePath = resolve56(projectPath);
|
|
111918
|
+
if (!existsSync71(absolutePath)) {
|
|
111656
111919
|
log.error(`Path does not exist: ${absolutePath}`);
|
|
111657
111920
|
process.exitCode = 1;
|
|
111658
111921
|
return;
|
|
@@ -112075,7 +112338,7 @@ import { readFile as readFile66 } from "node:fs/promises";
|
|
|
112075
112338
|
import { join as join150 } from "node:path";
|
|
112076
112339
|
|
|
112077
112340
|
// src/commands/skills/installed-skills-inventory.ts
|
|
112078
|
-
import { join as join149, resolve as
|
|
112341
|
+
import { join as join149, resolve as resolve57 } from "node:path";
|
|
112079
112342
|
init_path_resolver();
|
|
112080
112343
|
var SCOPE_SORT_ORDER = {
|
|
112081
112344
|
project: 0,
|
|
@@ -112083,8 +112346,8 @@ var SCOPE_SORT_ORDER = {
|
|
|
112083
112346
|
};
|
|
112084
112347
|
async function getActiveClaudeSkillInstallations(options2 = {}) {
|
|
112085
112348
|
const projectDir = options2.projectDir ?? process.cwd();
|
|
112086
|
-
const globalDir =
|
|
112087
|
-
const projectClaudeDir =
|
|
112349
|
+
const globalDir = resolve57(options2.globalDir ?? PathResolver.getGlobalKitDir());
|
|
112350
|
+
const projectClaudeDir = resolve57(projectDir, ".claude");
|
|
112088
112351
|
const projectScopeAliasesGlobal = projectClaudeDir === globalDir;
|
|
112089
112352
|
const [projectSkills, globalSkills] = await Promise.all([
|
|
112090
112353
|
projectScopeAliasesGlobal ? Promise.resolve([]) : scanSkills2(join149(projectClaudeDir, "skills")),
|
|
@@ -112830,8 +113093,8 @@ async function detectInstallations() {
|
|
|
112830
113093
|
}
|
|
112831
113094
|
|
|
112832
113095
|
// src/commands/uninstall/removal-handler.ts
|
|
112833
|
-
import { readdirSync as
|
|
112834
|
-
import { basename as
|
|
113096
|
+
import { readdirSync as readdirSync11, rmSync as rmSync5 } from "node:fs";
|
|
113097
|
+
import { basename as basename33, join as join152, resolve as resolve58, sep as sep14 } from "node:path";
|
|
112835
113098
|
init_logger();
|
|
112836
113099
|
init_safe_prompts();
|
|
112837
113100
|
init_safe_spinner();
|
|
@@ -112839,8 +113102,8 @@ var import_fs_extra42 = __toESM(require_lib(), 1);
|
|
|
112839
113102
|
|
|
112840
113103
|
// src/commands/uninstall/analysis-handler.ts
|
|
112841
113104
|
init_metadata_migration();
|
|
112842
|
-
import { readdirSync as
|
|
112843
|
-
import { dirname as
|
|
113105
|
+
import { readdirSync as readdirSync10, rmSync as rmSync4 } from "node:fs";
|
|
113106
|
+
import { dirname as dirname48, join as join151 } from "node:path";
|
|
112844
113107
|
init_logger();
|
|
112845
113108
|
init_safe_prompts();
|
|
112846
113109
|
var import_fs_extra41 = __toESM(require_lib(), 1);
|
|
@@ -112862,15 +113125,15 @@ function classifyFileByOwnership(ownership, forceOverwrite, deleteReason) {
|
|
|
112862
113125
|
}
|
|
112863
113126
|
async function cleanupEmptyDirectories3(filePath, installationRoot) {
|
|
112864
113127
|
let cleaned = 0;
|
|
112865
|
-
let currentDir =
|
|
113128
|
+
let currentDir = dirname48(filePath);
|
|
112866
113129
|
while (currentDir !== installationRoot && currentDir.startsWith(installationRoot)) {
|
|
112867
113130
|
try {
|
|
112868
|
-
const entries =
|
|
113131
|
+
const entries = readdirSync10(currentDir);
|
|
112869
113132
|
if (entries.length === 0) {
|
|
112870
113133
|
rmSync4(currentDir, { recursive: true });
|
|
112871
113134
|
cleaned++;
|
|
112872
113135
|
logger.debug(`Removed empty directory: ${currentDir}`);
|
|
112873
|
-
currentDir =
|
|
113136
|
+
currentDir = dirname48(currentDir);
|
|
112874
113137
|
} else {
|
|
112875
113138
|
break;
|
|
112876
113139
|
}
|
|
@@ -113015,17 +113278,17 @@ async function restoreUninstallBackup(backup) {
|
|
|
113015
113278
|
}
|
|
113016
113279
|
async function isPathSafeToRemove(filePath, baseDir) {
|
|
113017
113280
|
try {
|
|
113018
|
-
const resolvedPath =
|
|
113019
|
-
const resolvedBase =
|
|
113020
|
-
if (!resolvedPath.startsWith(resolvedBase +
|
|
113281
|
+
const resolvedPath = resolve58(filePath);
|
|
113282
|
+
const resolvedBase = resolve58(baseDir);
|
|
113283
|
+
if (!resolvedPath.startsWith(resolvedBase + sep14) && resolvedPath !== resolvedBase) {
|
|
113021
113284
|
logger.debug(`Path outside installation directory: ${filePath}`);
|
|
113022
113285
|
return false;
|
|
113023
113286
|
}
|
|
113024
113287
|
const stats = await import_fs_extra42.lstat(filePath);
|
|
113025
113288
|
if (stats.isSymbolicLink()) {
|
|
113026
113289
|
const realPath = await import_fs_extra42.realpath(filePath);
|
|
113027
|
-
const resolvedReal =
|
|
113028
|
-
if (!resolvedReal.startsWith(resolvedBase +
|
|
113290
|
+
const resolvedReal = resolve58(realPath);
|
|
113291
|
+
if (!resolvedReal.startsWith(resolvedBase + sep14) && resolvedReal !== resolvedBase) {
|
|
113029
113292
|
logger.debug(`Symlink points outside installation directory: ${filePath} -> ${realPath}`);
|
|
113030
113293
|
return false;
|
|
113031
113294
|
}
|
|
@@ -113070,7 +113333,7 @@ async function removeInstallations(installations, options2) {
|
|
|
113070
113333
|
scope: installation.type,
|
|
113071
113334
|
kit: options2.kit
|
|
113072
113335
|
});
|
|
113073
|
-
await cleanupOldDestructiveOperationBackups(undefined,
|
|
113336
|
+
await cleanupOldDestructiveOperationBackups(undefined, basename33(backup.backupDir));
|
|
113074
113337
|
backupSpinner.succeed(`Recovery backup saved to ${backup.backupDir}`);
|
|
113075
113338
|
} catch (error) {
|
|
113076
113339
|
backupSpinner.fail("Failed to create recovery backup");
|
|
@@ -113109,7 +113372,7 @@ async function removeInstallations(installations, options2) {
|
|
|
113109
113372
|
}
|
|
113110
113373
|
}
|
|
113111
113374
|
try {
|
|
113112
|
-
const remaining =
|
|
113375
|
+
const remaining = readdirSync11(installation.path);
|
|
113113
113376
|
if (remaining.length === 0) {
|
|
113114
113377
|
rmSync5(installation.path, { recursive: true });
|
|
113115
113378
|
logger.debug(`Removed empty installation directory: ${installation.path}`);
|
|
@@ -113491,7 +113754,7 @@ ${import_picocolors40.default.bold(import_picocolors40.default.cyan(result.kitCo
|
|
|
113491
113754
|
|
|
113492
113755
|
// src/commands/watch/watch-command.ts
|
|
113493
113756
|
init_logger();
|
|
113494
|
-
import { existsSync as
|
|
113757
|
+
import { existsSync as existsSync77 } from "node:fs";
|
|
113495
113758
|
import { rm as rm19 } from "node:fs/promises";
|
|
113496
113759
|
import { join as join159 } from "node:path";
|
|
113497
113760
|
var import_picocolors41 = __toESM(require_picocolors(), 1);
|
|
@@ -114790,14 +115053,14 @@ function cleanExpiredIssues(state, ttlDays) {
|
|
|
114790
115053
|
init_ck_config_manager();
|
|
114791
115054
|
init_file_io();
|
|
114792
115055
|
init_logger();
|
|
114793
|
-
import { existsSync as
|
|
115056
|
+
import { existsSync as existsSync73 } from "node:fs";
|
|
114794
115057
|
import { mkdir as mkdir41, readFile as readFile68 } from "node:fs/promises";
|
|
114795
|
-
import { dirname as
|
|
115058
|
+
import { dirname as dirname49 } from "node:path";
|
|
114796
115059
|
var PROCESSED_ISSUES_CAP = 500;
|
|
114797
115060
|
async function readCkJson(projectDir) {
|
|
114798
115061
|
const configPath = CkConfigManager.getProjectConfigPath(projectDir);
|
|
114799
115062
|
try {
|
|
114800
|
-
if (!
|
|
115063
|
+
if (!existsSync73(configPath))
|
|
114801
115064
|
return {};
|
|
114802
115065
|
const content = await readFile68(configPath, "utf-8");
|
|
114803
115066
|
return JSON.parse(content);
|
|
@@ -114822,8 +115085,8 @@ async function loadWatchState(projectDir) {
|
|
|
114822
115085
|
}
|
|
114823
115086
|
async function saveWatchState(projectDir, state) {
|
|
114824
115087
|
const configPath = CkConfigManager.getProjectConfigPath(projectDir);
|
|
114825
|
-
const configDir =
|
|
114826
|
-
if (!
|
|
115088
|
+
const configDir = dirname49(configPath);
|
|
115089
|
+
if (!existsSync73(configDir)) {
|
|
114827
115090
|
await mkdir41(configDir, { recursive: true });
|
|
114828
115091
|
}
|
|
114829
115092
|
const raw2 = await readCkJson(projectDir);
|
|
@@ -114950,7 +115213,7 @@ async function processImplementationQueue(state, config, setup, options2, watchL
|
|
|
114950
115213
|
// src/commands/watch/phases/repo-scanner.ts
|
|
114951
115214
|
init_logger();
|
|
114952
115215
|
import { spawnSync as spawnSync7 } from "node:child_process";
|
|
114953
|
-
import { existsSync as
|
|
115216
|
+
import { existsSync as existsSync74 } from "node:fs";
|
|
114954
115217
|
import { readdir as readdir46, stat as stat25 } from "node:fs/promises";
|
|
114955
115218
|
import { join as join156 } from "node:path";
|
|
114956
115219
|
async function scanForRepos(parentDir) {
|
|
@@ -114964,7 +115227,7 @@ async function scanForRepos(parentDir) {
|
|
|
114964
115227
|
if (!entryStat.isDirectory())
|
|
114965
115228
|
continue;
|
|
114966
115229
|
const gitDir = join156(fullPath, ".git");
|
|
114967
|
-
if (!
|
|
115230
|
+
if (!existsSync74(gitDir))
|
|
114968
115231
|
continue;
|
|
114969
115232
|
const result = spawnSync7("gh", ["repo", "view", "--json", "owner,name"], {
|
|
114970
115233
|
encoding: "utf-8",
|
|
@@ -114988,8 +115251,8 @@ async function scanForRepos(parentDir) {
|
|
|
114988
115251
|
// src/commands/watch/phases/setup-validator.ts
|
|
114989
115252
|
init_logger();
|
|
114990
115253
|
import { spawnSync as spawnSync8 } from "node:child_process";
|
|
114991
|
-
import { existsSync as
|
|
114992
|
-
import { homedir as
|
|
115254
|
+
import { existsSync as existsSync75 } from "node:fs";
|
|
115255
|
+
import { homedir as homedir54 } from "node:os";
|
|
114993
115256
|
import { join as join157 } from "node:path";
|
|
114994
115257
|
async function validateSetup(cwd2) {
|
|
114995
115258
|
const workDir = cwd2 ?? process.cwd();
|
|
@@ -115021,8 +115284,8 @@ Run this command from a directory with a GitHub remote.`);
|
|
|
115021
115284
|
} catch {
|
|
115022
115285
|
throw new Error(`Failed to parse repository info: ${ghRepo.stdout}`);
|
|
115023
115286
|
}
|
|
115024
|
-
const skillsPath = join157(
|
|
115025
|
-
const skillsAvailable =
|
|
115287
|
+
const skillsPath = join157(homedir54(), ".claude", "skills");
|
|
115288
|
+
const skillsAvailable = existsSync75(skillsPath);
|
|
115026
115289
|
if (!skillsAvailable) {
|
|
115027
115290
|
logger.warning(`ClaudeKit Engineer skills not found at ${skillsPath}`);
|
|
115028
115291
|
}
|
|
@@ -115038,7 +115301,7 @@ Run this command from a directory with a GitHub remote.`);
|
|
|
115038
115301
|
init_logger();
|
|
115039
115302
|
init_path_resolver();
|
|
115040
115303
|
import { createWriteStream as createWriteStream3, statSync as statSync13 } from "node:fs";
|
|
115041
|
-
import { existsSync as
|
|
115304
|
+
import { existsSync as existsSync76 } from "node:fs";
|
|
115042
115305
|
import { mkdir as mkdir42, rename as rename15 } from "node:fs/promises";
|
|
115043
115306
|
import { join as join158 } from "node:path";
|
|
115044
115307
|
|
|
@@ -115053,7 +115316,7 @@ class WatchLogger {
|
|
|
115053
115316
|
}
|
|
115054
115317
|
async init() {
|
|
115055
115318
|
try {
|
|
115056
|
-
if (!
|
|
115319
|
+
if (!existsSync76(this.logDir)) {
|
|
115057
115320
|
await mkdir42(this.logDir, { recursive: true });
|
|
115058
115321
|
}
|
|
115059
115322
|
const dateStr = formatDate(new Date);
|
|
@@ -115239,7 +115502,7 @@ async function watchCommand(options2) {
|
|
|
115239
115502
|
}
|
|
115240
115503
|
async function discoverRepos(options2, watchLog) {
|
|
115241
115504
|
const cwd2 = process.cwd();
|
|
115242
|
-
const isGitRepo =
|
|
115505
|
+
const isGitRepo = existsSync77(join159(cwd2, ".git"));
|
|
115243
115506
|
if (options2.force) {
|
|
115244
115507
|
await forceRemoveLock(watchLog);
|
|
115245
115508
|
}
|
|
@@ -115496,7 +115759,7 @@ function registerCommands(cli) {
|
|
|
115496
115759
|
// src/cli/version-display.ts
|
|
115497
115760
|
init_package();
|
|
115498
115761
|
init_config_version_checker();
|
|
115499
|
-
import { existsSync as
|
|
115762
|
+
import { existsSync as existsSync89, readFileSync as readFileSync22 } from "node:fs";
|
|
115500
115763
|
import { join as join171 } from "node:path";
|
|
115501
115764
|
|
|
115502
115765
|
// src/domains/versioning/version-checker.ts
|
|
@@ -115510,7 +115773,7 @@ init_types3();
|
|
|
115510
115773
|
// src/domains/versioning/version-cache.ts
|
|
115511
115774
|
init_logger();
|
|
115512
115775
|
init_path_resolver();
|
|
115513
|
-
import { existsSync as
|
|
115776
|
+
import { existsSync as existsSync88 } from "node:fs";
|
|
115514
115777
|
import { mkdir as mkdir43, readFile as readFile70, writeFile as writeFile42 } from "node:fs/promises";
|
|
115515
115778
|
import { join as join170 } from "node:path";
|
|
115516
115779
|
|
|
@@ -115524,7 +115787,7 @@ class VersionCacheManager {
|
|
|
115524
115787
|
static async load() {
|
|
115525
115788
|
const cacheFile = VersionCacheManager.getCacheFile();
|
|
115526
115789
|
try {
|
|
115527
|
-
if (!
|
|
115790
|
+
if (!existsSync88(cacheFile)) {
|
|
115528
115791
|
logger.debug("Version check cache not found");
|
|
115529
115792
|
return null;
|
|
115530
115793
|
}
|
|
@@ -115545,7 +115808,7 @@ class VersionCacheManager {
|
|
|
115545
115808
|
const cacheFile = VersionCacheManager.getCacheFile();
|
|
115546
115809
|
const cacheDir = PathResolver.getCacheDir(false);
|
|
115547
115810
|
try {
|
|
115548
|
-
if (!
|
|
115811
|
+
if (!existsSync88(cacheDir)) {
|
|
115549
115812
|
await mkdir43(cacheDir, { recursive: true, mode: 448 });
|
|
115550
115813
|
}
|
|
115551
115814
|
await writeFile42(cacheFile, JSON.stringify(cache5, null, 2), "utf-8");
|
|
@@ -115567,7 +115830,7 @@ class VersionCacheManager {
|
|
|
115567
115830
|
static async clear() {
|
|
115568
115831
|
const cacheFile = VersionCacheManager.getCacheFile();
|
|
115569
115832
|
try {
|
|
115570
|
-
if (
|
|
115833
|
+
if (existsSync88(cacheFile)) {
|
|
115571
115834
|
const fs20 = await import("node:fs/promises");
|
|
115572
115835
|
await fs20.unlink(cacheFile);
|
|
115573
115836
|
logger.debug("Version check cache cleared");
|
|
@@ -115834,7 +116097,7 @@ async function displayVersion() {
|
|
|
115834
116097
|
const prefix = PathResolver.getPathPrefix(false);
|
|
115835
116098
|
const localMetadataPath = prefix ? join171(process.cwd(), prefix, "metadata.json") : join171(process.cwd(), "metadata.json");
|
|
115836
116099
|
const isLocalSameAsGlobal = localMetadataPath === globalMetadataPath;
|
|
115837
|
-
if (!isLocalSameAsGlobal &&
|
|
116100
|
+
if (!isLocalSameAsGlobal && existsSync89(localMetadataPath)) {
|
|
115838
116101
|
try {
|
|
115839
116102
|
const rawMetadata = JSON.parse(readFileSync22(localMetadataPath, "utf-8"));
|
|
115840
116103
|
const metadata = MetadataSchema.parse(rawMetadata);
|
|
@@ -115848,7 +116111,7 @@ async function displayVersion() {
|
|
|
115848
116111
|
logger.verbose("Failed to parse local metadata.json", { error });
|
|
115849
116112
|
}
|
|
115850
116113
|
}
|
|
115851
|
-
if (
|
|
116114
|
+
if (existsSync89(globalMetadataPath)) {
|
|
115852
116115
|
try {
|
|
115853
116116
|
const rawMetadata = JSON.parse(readFileSync22(globalMetadataPath, "utf-8"));
|
|
115854
116117
|
const metadata = MetadataSchema.parse(rawMetadata);
|