claudekit-cli 4.5.0-dev.8 → 4.5.0-dev.9
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 +2 -2
- package/dist/index.js +825 -524
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -15619,12 +15619,16 @@ function detectLegacyState(claudeDir) {
|
|
|
15619
15619
|
const metadata = readJsonSafe(join6(claudeDir, "metadata.json"));
|
|
15620
15620
|
if (!isRecord(metadata))
|
|
15621
15621
|
return { installed: false, version: null };
|
|
15622
|
+
const hasLegacyPayload = hasTrackedPluginSuppliedLegacyFiles(claudeDir);
|
|
15622
15623
|
if (isRecord(metadata.kits) && isRecord(metadata.kits[ENGINEER_KIT_KEY])) {
|
|
15623
15624
|
const kit = metadata.kits[ENGINEER_KIT_KEY];
|
|
15624
|
-
return {
|
|
15625
|
+
return {
|
|
15626
|
+
installed: hasLegacyPayload,
|
|
15627
|
+
version: hasLegacyPayload && typeof kit.version === "string" ? kit.version : null
|
|
15628
|
+
};
|
|
15625
15629
|
}
|
|
15626
15630
|
const hasFiles = Array.isArray(metadata.files) && metadata.files.length > 0 || Array.isArray(metadata.installedFiles) && metadata.installedFiles.length > 0;
|
|
15627
|
-
if (typeof metadata.version === "string" && hasFiles) {
|
|
15631
|
+
if (typeof metadata.version === "string" && hasFiles && hasLegacyPayload) {
|
|
15628
15632
|
return { installed: true, version: metadata.version };
|
|
15629
15633
|
}
|
|
15630
15634
|
return { installed: false, version: null };
|
|
@@ -15980,11 +15984,12 @@ var init_github = __esm(() => {
|
|
|
15980
15984
|
});
|
|
15981
15985
|
|
|
15982
15986
|
// src/types/metadata.ts
|
|
15983
|
-
var TrackedFileSchema, InstalledSettingsSchema, KitMetadataSchema, MultiKitMetadataSchema, LegacyMetadataSchema, MetadataSchema, DownloadMethodSchema, ConfigSchema;
|
|
15987
|
+
var InstallModePreferenceSchema, TrackedFileSchema, InstalledSettingsSchema, KitMetadataSchema, MultiKitMetadataSchema, LegacyMetadataSchema, MetadataSchema, DownloadMethodSchema, ConfigSchema;
|
|
15984
15988
|
var init_metadata = __esm(() => {
|
|
15985
15989
|
init_zod();
|
|
15986
15990
|
init_commands();
|
|
15987
15991
|
init_kit();
|
|
15992
|
+
InstallModePreferenceSchema = exports_external.enum(["auto", "plugin", "legacy"]);
|
|
15988
15993
|
TrackedFileSchema = exports_external.object({
|
|
15989
15994
|
path: exports_external.string(),
|
|
15990
15995
|
checksum: exports_external.string().regex(/^[a-f0-9]{64}$/, "Invalid SHA-256 checksum"),
|
|
@@ -16005,6 +16010,7 @@ var init_metadata = __esm(() => {
|
|
|
16005
16010
|
installedAt: exports_external.string(),
|
|
16006
16011
|
files: exports_external.array(TrackedFileSchema).optional(),
|
|
16007
16012
|
ignoredSkills: exports_external.array(exports_external.string()).optional(),
|
|
16013
|
+
installModePreference: InstallModePreferenceSchema.optional(),
|
|
16008
16014
|
lastUpdateCheck: exports_external.string().optional(),
|
|
16009
16015
|
dismissedVersion: exports_external.string().optional(),
|
|
16010
16016
|
installedSettings: InstalledSettingsSchema.optional()
|
|
@@ -16688,6 +16694,7 @@ __export(exports_types, {
|
|
|
16688
16694
|
KitLayoutSchema: () => KitLayoutSchema,
|
|
16689
16695
|
KitConfigSchema: () => KitConfigSchema,
|
|
16690
16696
|
InstalledSettingsSchema: () => InstalledSettingsSchema,
|
|
16697
|
+
InstallModePreferenceSchema: () => InstallModePreferenceSchema,
|
|
16691
16698
|
GitHubReleaseSchema: () => GitHubReleaseSchema,
|
|
16692
16699
|
GitHubReleaseAssetSchema: () => GitHubReleaseAssetSchema,
|
|
16693
16700
|
GitHubError: () => GitHubError,
|
|
@@ -64573,7 +64580,7 @@ var package_default;
|
|
|
64573
64580
|
var init_package = __esm(() => {
|
|
64574
64581
|
package_default = {
|
|
64575
64582
|
name: "claudekit-cli",
|
|
64576
|
-
version: "4.5.0-dev.
|
|
64583
|
+
version: "4.5.0-dev.9",
|
|
64577
64584
|
description: "CLI tool for bootstrapping and updating ClaudeKit projects",
|
|
64578
64585
|
type: "module",
|
|
64579
64586
|
repository: {
|
|
@@ -66815,36 +66822,148 @@ class CodexPluginInstaller {
|
|
|
66815
66822
|
return this.run(["plugin", "list"], this.opts(15000));
|
|
66816
66823
|
}
|
|
66817
66824
|
async verifyInstalled() {
|
|
66818
|
-
const
|
|
66819
|
-
|
|
66820
|
-
const text = await this.listText();
|
|
66821
|
-
return text.ok && parseTextPluginList(text.stdout + text.stderr);
|
|
66822
|
-
}
|
|
66823
|
-
try {
|
|
66824
|
-
const parsed = JSON.parse(r2.stdout);
|
|
66825
|
-
return (parsed.installed ?? []).some((plugin) => plugin.pluginId === `${CK_PLUGIN_NAME}@${CK_MARKETPLACE_NAME}` && plugin.installed === true && plugin.enabled === true);
|
|
66826
|
-
} catch {
|
|
66827
|
-
const text = await this.listText();
|
|
66828
|
-
return text.ok && parseTextPluginList(text.stdout + text.stderr);
|
|
66829
|
-
}
|
|
66825
|
+
const state = await detectCodexPluginListState(this);
|
|
66826
|
+
return state.status === "installed-current" || state.status === "installed-stale-version" || state.status === "installed-stale-source";
|
|
66830
66827
|
}
|
|
66831
66828
|
}
|
|
66829
|
+
function createState(status, entry, options2 = {}, error) {
|
|
66830
|
+
const pluginId = `${CK_PLUGIN_NAME}@${CK_MARKETPLACE_NAME}`;
|
|
66831
|
+
return {
|
|
66832
|
+
status,
|
|
66833
|
+
pluginId,
|
|
66834
|
+
enabled: entry?.enabled ?? false,
|
|
66835
|
+
installed: entry?.installed ?? false,
|
|
66836
|
+
installedVersion: entry?.version ?? null,
|
|
66837
|
+
expectedVersion: options2.expectedVersion ?? null,
|
|
66838
|
+
marketplace: entry?.marketplace ?? null,
|
|
66839
|
+
expectedMarketplace: options2.expectedMarketplace ?? CK_MARKETPLACE_NAME,
|
|
66840
|
+
source: entry?.source ?? null,
|
|
66841
|
+
expectedSource: options2.expectedSource ?? null,
|
|
66842
|
+
shouldRefresh: status === "missing" || status === "disabled" || status === "installed-stale-version" || status === "installed-stale-source",
|
|
66843
|
+
...error ? { error } : {}
|
|
66844
|
+
};
|
|
66845
|
+
}
|
|
66846
|
+
function classifyCodexPluginEntry(entry, options2 = {}) {
|
|
66847
|
+
if (!entry)
|
|
66848
|
+
return createState("missing", null, options2);
|
|
66849
|
+
if (!entry.enabled || !entry.installed)
|
|
66850
|
+
return createState("disabled", entry, options2);
|
|
66851
|
+
const expectedMarketplace = options2.expectedMarketplace ?? CK_MARKETPLACE_NAME;
|
|
66852
|
+
if (entry.marketplace && entry.marketplace !== expectedMarketplace) {
|
|
66853
|
+
return createState("installed-stale-source", entry, options2);
|
|
66854
|
+
}
|
|
66855
|
+
if (options2.expectedSource && entry.source && entry.source !== options2.expectedSource) {
|
|
66856
|
+
return createState("installed-stale-source", entry, options2);
|
|
66857
|
+
}
|
|
66858
|
+
if (options2.expectedVersion && entry.version && !versionsMatch(entry.version, options2.expectedVersion)) {
|
|
66859
|
+
return createState("installed-stale-version", entry, options2);
|
|
66860
|
+
}
|
|
66861
|
+
return createState("installed-current", entry, options2);
|
|
66862
|
+
}
|
|
66832
66863
|
function parseTextPluginList(output2) {
|
|
66833
66864
|
const pluginId = `${CK_PLUGIN_NAME}@${CK_MARKETPLACE_NAME}`.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
66834
|
-
const row = new RegExp(`^\\s
|
|
66835
|
-
|
|
66865
|
+
const row = new RegExp(`^\\s*(${pluginId})\\s+(.*)$`, "im").exec(output2);
|
|
66866
|
+
if (!row)
|
|
66867
|
+
return null;
|
|
66868
|
+
const details = row[2] ?? "";
|
|
66869
|
+
const versionMatch = details.match(/\b(v?\d+\.\d+\.\d+(?:[-+][^\s]+)?)\b/);
|
|
66870
|
+
return {
|
|
66871
|
+
pluginId: `${CK_PLUGIN_NAME}@${CK_MARKETPLACE_NAME}`,
|
|
66872
|
+
installed: /\binstalled\b/i.test(details),
|
|
66873
|
+
enabled: /\benabled\b/i.test(details) && !/\bdisabled\b/i.test(details),
|
|
66874
|
+
version: versionMatch?.[1] ?? null,
|
|
66875
|
+
marketplace: CK_MARKETPLACE_NAME,
|
|
66876
|
+
source: null
|
|
66877
|
+
};
|
|
66878
|
+
}
|
|
66879
|
+
function isRecord3(value) {
|
|
66880
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
66881
|
+
}
|
|
66882
|
+
function stringField(source, keys) {
|
|
66883
|
+
for (const key of keys) {
|
|
66884
|
+
const value = source[key];
|
|
66885
|
+
if (typeof value === "string" && value.trim() !== "")
|
|
66886
|
+
return value;
|
|
66887
|
+
}
|
|
66888
|
+
return null;
|
|
66889
|
+
}
|
|
66890
|
+
function sourceField(source, keys) {
|
|
66891
|
+
for (const key of keys) {
|
|
66892
|
+
const value = source[key];
|
|
66893
|
+
if (typeof value === "string" && value.trim() !== "")
|
|
66894
|
+
return value;
|
|
66895
|
+
if (isRecord3(value)) {
|
|
66896
|
+
const nested = stringField(value, ["path", "sourcePath", "url"]);
|
|
66897
|
+
if (nested)
|
|
66898
|
+
return nested;
|
|
66899
|
+
}
|
|
66900
|
+
}
|
|
66901
|
+
return null;
|
|
66902
|
+
}
|
|
66903
|
+
function booleanField(source, key, defaultValue) {
|
|
66904
|
+
const value = source[key];
|
|
66905
|
+
return typeof value === "boolean" ? value : defaultValue;
|
|
66906
|
+
}
|
|
66907
|
+
function parseJsonPluginList(output2) {
|
|
66908
|
+
let parsed;
|
|
66909
|
+
try {
|
|
66910
|
+
parsed = JSON.parse(output2);
|
|
66911
|
+
} catch {
|
|
66912
|
+
return null;
|
|
66913
|
+
}
|
|
66914
|
+
const rawEntries = Array.isArray(parsed) ? parsed : isRecord3(parsed) ? parsed.installed ?? parsed.plugins ?? parsed.entries : null;
|
|
66915
|
+
if (!Array.isArray(rawEntries))
|
|
66916
|
+
return null;
|
|
66917
|
+
return rawEntries.flatMap((entry) => {
|
|
66918
|
+
if (!isRecord3(entry))
|
|
66919
|
+
return [];
|
|
66920
|
+
const pluginId = stringField(entry, ["pluginId", "id"]) ?? (stringField(entry, ["name"]) === CK_PLUGIN_NAME ? `${CK_PLUGIN_NAME}@${stringField(entry, ["marketplace", "marketplaceName"]) ?? CK_MARKETPLACE_NAME}` : null);
|
|
66921
|
+
if (pluginId !== `${CK_PLUGIN_NAME}@${CK_MARKETPLACE_NAME}`)
|
|
66922
|
+
return [];
|
|
66923
|
+
return [
|
|
66924
|
+
{
|
|
66925
|
+
pluginId,
|
|
66926
|
+
installed: booleanField(entry, "installed", true),
|
|
66927
|
+
enabled: booleanField(entry, "enabled", false),
|
|
66928
|
+
version: stringField(entry, ["version", "pluginVersion", "manifestVersion"]),
|
|
66929
|
+
marketplace: stringField(entry, ["marketplace", "marketplaceName"]),
|
|
66930
|
+
source: sourceField(entry, ["source", "path", "sourcePath"])
|
|
66931
|
+
}
|
|
66932
|
+
];
|
|
66933
|
+
});
|
|
66934
|
+
}
|
|
66935
|
+
async function detectCodexPluginState(installer = new CodexPluginInstaller, options2 = {}) {
|
|
66936
|
+
if (!await installer.isCodexAvailable()) {
|
|
66937
|
+
return createState("codex-unavailable", null, options2);
|
|
66938
|
+
}
|
|
66939
|
+
if (!await installer.isPluginSupported()) {
|
|
66940
|
+
return createState("plugins-unsupported", null, options2);
|
|
66941
|
+
}
|
|
66942
|
+
return detectCodexPluginListState(installer, options2);
|
|
66943
|
+
}
|
|
66944
|
+
async function detectCodexPluginListState(installer, options2 = {}) {
|
|
66945
|
+
const json = await installer.listJson();
|
|
66946
|
+
if (json.ok) {
|
|
66947
|
+
const entries = parseJsonPluginList(json.stdout);
|
|
66948
|
+
if (entries)
|
|
66949
|
+
return classifyCodexPluginEntry(entries[0] ?? null, options2);
|
|
66950
|
+
}
|
|
66951
|
+
const text = await installer.listText();
|
|
66952
|
+
if (text.ok)
|
|
66953
|
+
return classifyCodexPluginEntry(parseTextPluginList(text.stdout + text.stderr), options2);
|
|
66954
|
+
return createState("unknown", null, options2, json.stderr || text.stderr || "codex plugin list failed");
|
|
66836
66955
|
}
|
|
66837
66956
|
async function installCodexPlugin(opts) {
|
|
66838
66957
|
const installer = opts.installer ?? new CodexPluginInstaller(undefined, opts.codexHome);
|
|
66839
66958
|
if (!await installer.isCodexAvailable() || !await installer.isPluginSupported()) {
|
|
66840
66959
|
return { action: "skipped-codex-unsupported", pluginVerified: false };
|
|
66841
66960
|
}
|
|
66842
|
-
const added = await installer
|
|
66961
|
+
const added = await addOrReplaceMarketplace(installer, opts.pluginSourceDir);
|
|
66843
66962
|
if (!added.ok) {
|
|
66844
66963
|
return {
|
|
66845
66964
|
action: "install-failed",
|
|
66846
66965
|
pluginVerified: false,
|
|
66847
|
-
error:
|
|
66966
|
+
error: added.error
|
|
66848
66967
|
};
|
|
66849
66968
|
}
|
|
66850
66969
|
const installed = await installer.add();
|
|
@@ -66865,6 +66984,26 @@ async function installCodexPlugin(opts) {
|
|
|
66865
66984
|
}
|
|
66866
66985
|
return { action: "installed", pluginVerified: true };
|
|
66867
66986
|
}
|
|
66987
|
+
async function addOrReplaceMarketplace(installer, pluginSourceDir) {
|
|
66988
|
+
const added = await installer.marketplaceAdd(pluginSourceDir);
|
|
66989
|
+
if (added.ok)
|
|
66990
|
+
return { ok: true };
|
|
66991
|
+
const error = added.stderr.trim();
|
|
66992
|
+
if (!isReplaceableMarketplaceAddFailure(error)) {
|
|
66993
|
+
return { ok: false, error: `codex marketplace add failed: ${error}` };
|
|
66994
|
+
}
|
|
66995
|
+
await installer.marketplaceRemove(CK_MARKETPLACE_NAME);
|
|
66996
|
+
const readded = await installer.marketplaceAdd(pluginSourceDir);
|
|
66997
|
+
if (readded.ok)
|
|
66998
|
+
return { ok: true };
|
|
66999
|
+
return {
|
|
67000
|
+
ok: false,
|
|
67001
|
+
error: `codex marketplace refresh failed: ${readded.stderr.trim() || error}`
|
|
67002
|
+
};
|
|
67003
|
+
}
|
|
67004
|
+
function isReplaceableMarketplaceAddFailure(error) {
|
|
67005
|
+
return /\balready\b/i.test(error) && /\bmarketplace\b/i.test(error);
|
|
67006
|
+
}
|
|
66868
67007
|
async function removeCodexPlugin(opts = {}) {
|
|
66869
67008
|
const installer = opts.installer ?? new CodexPluginInstaller(undefined, opts.codexHome);
|
|
66870
67009
|
if (!await installer.isCodexAvailable() || !await installer.isPluginSupported()) {
|
|
@@ -66872,16 +67011,16 @@ async function removeCodexPlugin(opts = {}) {
|
|
|
66872
67011
|
}
|
|
66873
67012
|
const removed = await installer.remove();
|
|
66874
67013
|
const marketplaceRemoved = await installer.marketplaceRemove();
|
|
67014
|
+
const state = await detectCodexPluginListState(installer);
|
|
66875
67015
|
return {
|
|
66876
67016
|
removed: removed.ok,
|
|
66877
|
-
marketplaceRemoved: marketplaceRemoved.ok
|
|
67017
|
+
marketplaceRemoved: marketplaceRemoved.ok,
|
|
67018
|
+
pluginStillInstalled: state.installed,
|
|
67019
|
+
...state.installed ? { error: `codex plugin still installed after removal (${state.status})` } : {}
|
|
66878
67020
|
};
|
|
66879
67021
|
}
|
|
66880
|
-
async function shouldRefreshCodexPlugin(installer = new CodexPluginInstaller) {
|
|
66881
|
-
|
|
66882
|
-
return false;
|
|
66883
|
-
}
|
|
66884
|
-
return !await installer.verifyInstalled();
|
|
67022
|
+
async function shouldRefreshCodexPlugin(installer = new CodexPluginInstaller, options2 = {}) {
|
|
67023
|
+
return (await detectCodexPluginState(installer, options2)).shouldRefresh;
|
|
66885
67024
|
}
|
|
66886
67025
|
var execFileAsync6, DEFAULT_TIMEOUT_MS2 = 120000, defaultCodexRunner = async (args, opts) => {
|
|
66887
67026
|
const env2 = { ...process.env };
|
|
@@ -66916,13 +67055,41 @@ var execFileAsync6, DEFAULT_TIMEOUT_MS2 = 120000, defaultCodexRunner = async (ar
|
|
|
66916
67055
|
};
|
|
66917
67056
|
var init_codex_plugin_installer = __esm(() => {
|
|
66918
67057
|
init_install_mode_detector();
|
|
67058
|
+
init_version_utils();
|
|
66919
67059
|
execFileAsync6 = promisify9(execFile8);
|
|
66920
67060
|
});
|
|
66921
67061
|
|
|
66922
|
-
// src/domains/
|
|
67062
|
+
// src/domains/installation/plugin/install-mode-preference.ts
|
|
67063
|
+
import { readFileSync as readFileSync16 } from "node:fs";
|
|
66923
67064
|
import { join as join66 } from "node:path";
|
|
67065
|
+
function normalizeInstallModePreference(value) {
|
|
67066
|
+
if (value === "auto" || value === "plugin" || value === "legacy")
|
|
67067
|
+
return value;
|
|
67068
|
+
return null;
|
|
67069
|
+
}
|
|
67070
|
+
function readInstallModePreferenceFromMetadata(metadata, kit = "engineer") {
|
|
67071
|
+
return normalizeInstallModePreference(metadata?.kits?.[kit]?.installModePreference);
|
|
67072
|
+
}
|
|
67073
|
+
function resolveInstallModePreferenceForUpdate(metadata, kit) {
|
|
67074
|
+
if (kit !== "engineer")
|
|
67075
|
+
return;
|
|
67076
|
+
return readInstallModePreferenceFromMetadata(metadata, kit) ?? DEFAULT_INSTALL_MODE_PREFERENCE;
|
|
67077
|
+
}
|
|
67078
|
+
function readInstallModePreferenceFromClaudeDir(claudeDir3, kit = "engineer") {
|
|
67079
|
+
try {
|
|
67080
|
+
const parsed = JSON.parse(readFileSync16(join66(claudeDir3, "metadata.json"), "utf-8"));
|
|
67081
|
+
return readInstallModePreferenceFromMetadata(parsed, kit);
|
|
67082
|
+
} catch {
|
|
67083
|
+
return null;
|
|
67084
|
+
}
|
|
67085
|
+
}
|
|
67086
|
+
var DEFAULT_INSTALL_MODE_PREFERENCE = "auto";
|
|
67087
|
+
var init_install_mode_preference = () => {};
|
|
67088
|
+
|
|
67089
|
+
// src/domains/migration/metadata-migration.ts
|
|
67090
|
+
import { join as join67 } from "node:path";
|
|
66924
67091
|
async function detectMetadataFormat(claudeDir3) {
|
|
66925
|
-
const metadataPath =
|
|
67092
|
+
const metadataPath = join67(claudeDir3, "metadata.json");
|
|
66926
67093
|
if (!await import_fs_extra6.pathExists(metadataPath)) {
|
|
66927
67094
|
return { format: "none", metadata: null, detectedKit: null };
|
|
66928
67095
|
}
|
|
@@ -66974,7 +67141,7 @@ async function migrateToMultiKit(claudeDir3) {
|
|
|
66974
67141
|
toFormat: "multi-kit"
|
|
66975
67142
|
};
|
|
66976
67143
|
}
|
|
66977
|
-
const metadataPath =
|
|
67144
|
+
const metadataPath = join67(claudeDir3, "metadata.json");
|
|
66978
67145
|
const legacy = detection.metadata;
|
|
66979
67146
|
if (!legacy) {
|
|
66980
67147
|
return {
|
|
@@ -67086,7 +67253,7 @@ var init_metadata_migration = __esm(() => {
|
|
|
67086
67253
|
});
|
|
67087
67254
|
|
|
67088
67255
|
// src/services/file-operations/claudekit-scanner.ts
|
|
67089
|
-
import { join as
|
|
67256
|
+
import { join as join68 } from "node:path";
|
|
67090
67257
|
async function scanClaudeKitDirectory(directoryPath) {
|
|
67091
67258
|
const counts = {
|
|
67092
67259
|
agents: 0,
|
|
@@ -67100,33 +67267,33 @@ async function scanClaudeKitDirectory(directoryPath) {
|
|
|
67100
67267
|
}
|
|
67101
67268
|
const items = await import_fs_extra7.readdir(directoryPath);
|
|
67102
67269
|
if (items.includes("agents")) {
|
|
67103
|
-
const agentsPath =
|
|
67270
|
+
const agentsPath = join68(directoryPath, "agents");
|
|
67104
67271
|
const agentFiles = await import_fs_extra7.readdir(agentsPath);
|
|
67105
67272
|
counts.agents = agentFiles.filter((file) => file.endsWith(".md")).length;
|
|
67106
67273
|
}
|
|
67107
67274
|
if (items.includes("commands")) {
|
|
67108
|
-
const commandsPath =
|
|
67275
|
+
const commandsPath = join68(directoryPath, "commands");
|
|
67109
67276
|
const commandFiles = await import_fs_extra7.readdir(commandsPath);
|
|
67110
67277
|
counts.commands = commandFiles.filter((file) => file.endsWith(".md")).length;
|
|
67111
67278
|
}
|
|
67112
67279
|
if (items.includes("rules")) {
|
|
67113
|
-
const rulesPath =
|
|
67280
|
+
const rulesPath = join68(directoryPath, "rules");
|
|
67114
67281
|
const ruleFiles = await import_fs_extra7.readdir(rulesPath);
|
|
67115
67282
|
counts.rules = ruleFiles.filter((file) => file.endsWith(".md")).length;
|
|
67116
67283
|
} else if (items.includes("workflows")) {
|
|
67117
|
-
const workflowsPath =
|
|
67284
|
+
const workflowsPath = join68(directoryPath, "workflows");
|
|
67118
67285
|
const workflowFiles = await import_fs_extra7.readdir(workflowsPath);
|
|
67119
67286
|
counts.rules = workflowFiles.filter((file) => file.endsWith(".md")).length;
|
|
67120
67287
|
}
|
|
67121
67288
|
if (items.includes("skills")) {
|
|
67122
|
-
const skillsPath =
|
|
67289
|
+
const skillsPath = join68(directoryPath, "skills");
|
|
67123
67290
|
const skillItems = await import_fs_extra7.readdir(skillsPath);
|
|
67124
67291
|
let skillCount = 0;
|
|
67125
67292
|
for (const item of skillItems) {
|
|
67126
67293
|
if (SKIP_DIRS_CLAUDE_INTERNAL.includes(item)) {
|
|
67127
67294
|
continue;
|
|
67128
67295
|
}
|
|
67129
|
-
const itemPath =
|
|
67296
|
+
const itemPath = join68(skillsPath, item);
|
|
67130
67297
|
const stat13 = await import_fs_extra7.readdir(itemPath).catch(() => null);
|
|
67131
67298
|
if (stat13?.includes("SKILL.md")) {
|
|
67132
67299
|
skillCount++;
|
|
@@ -67168,14 +67335,14 @@ async function getClaudeKitSetup(projectDir = process.cwd()) {
|
|
|
67168
67335
|
const globalDir = getGlobalInstallDir();
|
|
67169
67336
|
if (await import_fs_extra7.pathExists(globalDir)) {
|
|
67170
67337
|
setup.global.path = globalDir;
|
|
67171
|
-
setup.global.metadata = await readClaudeKitMetadata(
|
|
67338
|
+
setup.global.metadata = await readClaudeKitMetadata(join68(globalDir, "metadata.json"));
|
|
67172
67339
|
setup.global.components = await scanClaudeKitDirectory(globalDir);
|
|
67173
67340
|
}
|
|
67174
|
-
const projectClaudeDir =
|
|
67341
|
+
const projectClaudeDir = join68(projectDir, ".claude");
|
|
67175
67342
|
const isLocalSameAsGlobal = projectClaudeDir === globalDir;
|
|
67176
67343
|
if (!isLocalSameAsGlobal && await import_fs_extra7.pathExists(projectClaudeDir)) {
|
|
67177
67344
|
setup.project.path = projectClaudeDir;
|
|
67178
|
-
setup.project.metadata = await readClaudeKitMetadata(
|
|
67345
|
+
setup.project.metadata = await readClaudeKitMetadata(join68(projectClaudeDir, "metadata.json"));
|
|
67179
67346
|
setup.project.components = await scanClaudeKitDirectory(projectClaudeDir);
|
|
67180
67347
|
}
|
|
67181
67348
|
return setup;
|
|
@@ -67945,7 +68112,7 @@ var init_error_handler2 = __esm(() => {
|
|
|
67945
68112
|
// src/domains/versioning/release-cache.ts
|
|
67946
68113
|
import { existsSync as existsSync47 } from "node:fs";
|
|
67947
68114
|
import { mkdir as mkdir18, readFile as readFile37, unlink as unlink8, writeFile as writeFile20 } from "node:fs/promises";
|
|
67948
|
-
import { join as
|
|
68115
|
+
import { join as join69 } from "node:path";
|
|
67949
68116
|
var ReleaseCacheEntrySchema, ReleaseCache;
|
|
67950
68117
|
var init_release_cache = __esm(() => {
|
|
67951
68118
|
init_logger();
|
|
@@ -67960,7 +68127,7 @@ var init_release_cache = __esm(() => {
|
|
|
67960
68127
|
static CACHE_TTL_SECONDS = Number(process.env.CK_CACHE_TTL) || 3600;
|
|
67961
68128
|
cacheDir;
|
|
67962
68129
|
constructor() {
|
|
67963
|
-
this.cacheDir =
|
|
68130
|
+
this.cacheDir = join69(PathResolver.getCacheDir(false), ReleaseCache.CACHE_DIR);
|
|
67964
68131
|
}
|
|
67965
68132
|
async get(key) {
|
|
67966
68133
|
const cacheFile = this.getCachePath(key);
|
|
@@ -68018,7 +68185,7 @@ var init_release_cache = __esm(() => {
|
|
|
68018
68185
|
const files = await readdir19(this.cacheDir);
|
|
68019
68186
|
for (const file of files) {
|
|
68020
68187
|
if (file.endsWith(".json")) {
|
|
68021
|
-
await unlink8(
|
|
68188
|
+
await unlink8(join69(this.cacheDir, file));
|
|
68022
68189
|
}
|
|
68023
68190
|
}
|
|
68024
68191
|
logger.debug("All release cache cleared");
|
|
@@ -68029,7 +68196,7 @@ var init_release_cache = __esm(() => {
|
|
|
68029
68196
|
}
|
|
68030
68197
|
getCachePath(key) {
|
|
68031
68198
|
const safeKey = key.replace(/[^a-zA-Z0-9_-]/g, "_");
|
|
68032
|
-
return
|
|
68199
|
+
return join69(this.cacheDir, `${safeKey}.json`);
|
|
68033
68200
|
}
|
|
68034
68201
|
isExpired(timestamp) {
|
|
68035
68202
|
const now = Date.now();
|
|
@@ -68687,7 +68854,7 @@ import { exec as exec2, spawn as spawn2 } from "node:child_process";
|
|
|
68687
68854
|
import { existsSync as existsSync48 } from "node:fs";
|
|
68688
68855
|
import { readdir as readdir19 } from "node:fs/promises";
|
|
68689
68856
|
import { builtinModules } from "node:module";
|
|
68690
|
-
import { dirname as dirname30, join as
|
|
68857
|
+
import { dirname as dirname30, join as join70 } from "node:path";
|
|
68691
68858
|
import { promisify as promisify10 } from "node:util";
|
|
68692
68859
|
function selectKitForUpdate(params) {
|
|
68693
68860
|
const { hasLocal, hasGlobal, localKits, globalKits } = params;
|
|
@@ -68719,7 +68886,7 @@ function selectKitForUpdate(params) {
|
|
|
68719
68886
|
};
|
|
68720
68887
|
}
|
|
68721
68888
|
async function readMetadataFile(claudeDir3) {
|
|
68722
|
-
const metadataPath =
|
|
68889
|
+
const metadataPath = join70(claudeDir3, "metadata.json");
|
|
68723
68890
|
try {
|
|
68724
68891
|
if (!await import_fs_extra8.pathExists(metadataPath))
|
|
68725
68892
|
return null;
|
|
@@ -68769,7 +68936,7 @@ function collectSettingsHookRegistrations(settings, options2 = {}) {
|
|
|
68769
68936
|
return registrations;
|
|
68770
68937
|
}
|
|
68771
68938
|
async function readManagedHookNames(claudeDir3) {
|
|
68772
|
-
const manifestPath =
|
|
68939
|
+
const manifestPath = join70(claudeDir3, "hooks", MANAGED_HOOKS_MANIFEST);
|
|
68773
68940
|
if (!existsSync48(manifestPath))
|
|
68774
68941
|
return [];
|
|
68775
68942
|
try {
|
|
@@ -68783,7 +68950,7 @@ async function readManagedHookNames(claudeDir3) {
|
|
|
68783
68950
|
}
|
|
68784
68951
|
}
|
|
68785
68952
|
async function readDisabledHookNames(claudeDir3) {
|
|
68786
|
-
const configPath =
|
|
68953
|
+
const configPath = join70(claudeDir3, ".ck.json");
|
|
68787
68954
|
if (!existsSync48(configPath))
|
|
68788
68955
|
return new Set;
|
|
68789
68956
|
try {
|
|
@@ -68795,7 +68962,7 @@ async function readDisabledHookNames(claudeDir3) {
|
|
|
68795
68962
|
}
|
|
68796
68963
|
}
|
|
68797
68964
|
async function countMissingCkHookRegistrations(claudeDir3, kit, options2 = {}) {
|
|
68798
|
-
const settingsPath =
|
|
68965
|
+
const settingsPath = join70(claudeDir3, "settings.json");
|
|
68799
68966
|
if (!existsSync48(settingsPath))
|
|
68800
68967
|
return 0;
|
|
68801
68968
|
const managedHooks = await readManagedHookNames(claudeDir3);
|
|
@@ -68804,19 +68971,19 @@ async function countMissingCkHookRegistrations(claudeDir3, kit, options2 = {}) {
|
|
|
68804
68971
|
const settings = parseJsonContent(await import_fs_extra8.readFile(settingsPath, "utf-8"));
|
|
68805
68972
|
const liveHookRegistrations = collectSettingsHookRegistrations(settings, options2);
|
|
68806
68973
|
const disabledHooks = await readDisabledHookNames(claudeDir3);
|
|
68807
|
-
const hooksDir =
|
|
68974
|
+
const hooksDir = join70(claudeDir3, "hooks");
|
|
68808
68975
|
let missing = 0;
|
|
68809
68976
|
for (const name of managedHooks) {
|
|
68810
68977
|
if (disabledHooks.has(name))
|
|
68811
68978
|
continue;
|
|
68812
|
-
if (!existsSync48(
|
|
68979
|
+
if (!existsSync48(join70(hooksDir, `${name}.cjs`)))
|
|
68813
68980
|
continue;
|
|
68814
68981
|
if (!liveHookRegistrations.get(name)?.hasCorrectScope)
|
|
68815
68982
|
missing++;
|
|
68816
68983
|
}
|
|
68817
68984
|
return missing;
|
|
68818
68985
|
}
|
|
68819
|
-
function buildInitCommand(isGlobal, kit, beta, yes, restoreCkHooks) {
|
|
68986
|
+
function buildInitCommand(isGlobal, kit, beta, yes, restoreCkHooks, installMode) {
|
|
68820
68987
|
const parts = ["ck init"];
|
|
68821
68988
|
if (isGlobal)
|
|
68822
68989
|
parts.push("-g");
|
|
@@ -68826,6 +68993,8 @@ function buildInitCommand(isGlobal, kit, beta, yes, restoreCkHooks) {
|
|
|
68826
68993
|
parts.push("--yes");
|
|
68827
68994
|
if (restoreCkHooks)
|
|
68828
68995
|
parts.push("--restore-ck-hooks");
|
|
68996
|
+
if (installMode && isGlobal && kit === "engineer")
|
|
68997
|
+
parts.push(`--install-mode ${installMode}`);
|
|
68829
68998
|
parts.push("--install-skills");
|
|
68830
68999
|
if (beta)
|
|
68831
69000
|
parts.push("--beta");
|
|
@@ -68862,7 +69031,7 @@ async function fetchLatestReleaseTag(kit, beta) {
|
|
|
68862
69031
|
}
|
|
68863
69032
|
}
|
|
68864
69033
|
async function findMissingHookDependencies(claudeDir3) {
|
|
68865
|
-
const hooksDir =
|
|
69034
|
+
const hooksDir = join70(claudeDir3, "hooks");
|
|
68866
69035
|
if (!existsSync48(hooksDir))
|
|
68867
69036
|
return [];
|
|
68868
69037
|
const files = await readdir19(hooksDir);
|
|
@@ -68873,14 +69042,14 @@ async function findMissingHookDependencies(claudeDir3) {
|
|
|
68873
69042
|
...builtinModules.map((name) => `node:${name}`)
|
|
68874
69043
|
]);
|
|
68875
69044
|
for (const file of cjsFiles) {
|
|
68876
|
-
const content = await import_fs_extra8.readFile(
|
|
69045
|
+
const content = await import_fs_extra8.readFile(join70(hooksDir, file), "utf8");
|
|
68877
69046
|
const requireRegex = /require\(['"]([^'"]+)['"]\)/g;
|
|
68878
69047
|
for (let match = requireRegex.exec(content);match; match = requireRegex.exec(content)) {
|
|
68879
69048
|
const depPath = match[1];
|
|
68880
69049
|
if (!depPath || nodeBuiltins.has(depPath) || !depPath.startsWith("."))
|
|
68881
69050
|
continue;
|
|
68882
|
-
const resolvedPath =
|
|
68883
|
-
const exists = existsSync48(resolvedPath) || HOOK_DEPENDENCY_EXTENSIONS.some((ext) => existsSync48(resolvedPath + ext)) || existsSync48(
|
|
69051
|
+
const resolvedPath = join70(hooksDir, depPath);
|
|
69052
|
+
const exists = existsSync48(resolvedPath) || HOOK_DEPENDENCY_EXTENSIONS.some((ext) => existsSync48(resolvedPath + ext)) || existsSync48(join70(resolvedPath, "index.js")) || existsSync48(join70(resolvedPath, "index.cjs")) || existsSync48(join70(resolvedPath, "index.mjs"));
|
|
68884
69053
|
if (!exists)
|
|
68885
69054
|
missing.push(`${file}: ${depPath}`);
|
|
68886
69055
|
}
|
|
@@ -68897,7 +69066,7 @@ async function promptKitUpdate(beta, yes, deps) {
|
|
|
68897
69066
|
const findMissingHookDepsFn = deps?.findMissingHookDependenciesFn ?? findMissingHookDependencies;
|
|
68898
69067
|
const detectInstallModeFn = deps?.detectInstallModeFn ?? detectInstallMode;
|
|
68899
69068
|
const hasTrackedPluginSuppliedLegacyFilesFn = deps?.hasTrackedPluginSuppliedLegacyFilesFn ?? hasTrackedPluginSuppliedLegacyFiles;
|
|
68900
|
-
const shouldRefreshCodexPluginFn = deps?.shouldRefreshCodexPluginFn ?? shouldRefreshCodexPlugin;
|
|
69069
|
+
const shouldRefreshCodexPluginFn = deps?.shouldRefreshCodexPluginFn ?? ((options2) => shouldRefreshCodexPlugin(undefined, options2));
|
|
68901
69070
|
const setup = await getSetupFn();
|
|
68902
69071
|
const hasLocal = !!setup.project.metadata;
|
|
68903
69072
|
const hasGlobal = !!setup.global.metadata;
|
|
@@ -68940,6 +69109,8 @@ async function promptKitUpdate(beta, yes, deps) {
|
|
|
68940
69109
|
};
|
|
68941
69110
|
}
|
|
68942
69111
|
}
|
|
69112
|
+
let kitVersion = selection.kit ? selection.isGlobal ? globalMetadata?.kits?.[selection.kit]?.version : localMetadata?.kits?.[selection.kit]?.version : undefined;
|
|
69113
|
+
let installModePreference = selection.isGlobal ? resolveInstallModePreferenceForUpdate(globalMetadata, selection.kit) : undefined;
|
|
68943
69114
|
const selectedClaudeDir = selection.isGlobal ? setup.global.path : setup.project.path;
|
|
68944
69115
|
if (selectedClaudeDir) {
|
|
68945
69116
|
try {
|
|
@@ -68963,13 +69134,20 @@ async function promptKitUpdate(beta, yes, deps) {
|
|
|
68963
69134
|
try {
|
|
68964
69135
|
if (selection.isGlobal && selection.kit === "engineer") {
|
|
68965
69136
|
const installMode = detectInstallModeFn(selectedClaudeDir);
|
|
68966
|
-
|
|
68967
|
-
|
|
68968
|
-
|
|
68969
|
-
|
|
69137
|
+
if (installModePreference === "legacy") {
|
|
69138
|
+
if (installMode.plugin.installed || installMode.plugin.staleCache) {
|
|
69139
|
+
logger.warning("Detected plugin state for legacy global Engineer preference; reinstalling legacy mode");
|
|
69140
|
+
forceKitReinstall = true;
|
|
69141
|
+
}
|
|
69142
|
+
} else {
|
|
69143
|
+
const needsPluginMigration = installMode.mode === "legacy" || installMode.mode === "mixed" && hasTrackedPluginSuppliedLegacyFilesFn(selectedClaudeDir);
|
|
69144
|
+
if (needsPluginMigration) {
|
|
69145
|
+
logger.warning(`Detected ${installMode.mode} global Engineer install; migrating to plugin format`);
|
|
69146
|
+
forceKitReinstall = true;
|
|
69147
|
+
}
|
|
68970
69148
|
}
|
|
68971
|
-
if (await shouldRefreshCodexPluginFn()) {
|
|
68972
|
-
logger.warning("Detected
|
|
69149
|
+
if (installModePreference !== "legacy" && await shouldRefreshCodexPluginFn({ expectedVersion: kitVersion })) {
|
|
69150
|
+
logger.warning("Detected Codex ClaudeKit plugin state requiring refresh; reinstalling global Engineer content");
|
|
68973
69151
|
forceKitReinstall = true;
|
|
68974
69152
|
}
|
|
68975
69153
|
}
|
|
@@ -68977,7 +69155,6 @@ async function promptKitUpdate(beta, yes, deps) {
|
|
|
68977
69155
|
logger.verbose(`Plugin install-mode self-heal check skipped: ${error instanceof Error ? error.message : "unknown"}`);
|
|
68978
69156
|
}
|
|
68979
69157
|
}
|
|
68980
|
-
let kitVersion = selection.kit ? selection.isGlobal ? globalMetadata?.kits?.[selection.kit]?.version : localMetadata?.kits?.[selection.kit]?.version : undefined;
|
|
68981
69158
|
const isBetaInstalled = isBetaVersion(kitVersion);
|
|
68982
69159
|
const promptMessage = selection.promptMessage;
|
|
68983
69160
|
if (selection.kit && kitVersion) {
|
|
@@ -69022,6 +69199,7 @@ async function promptKitUpdate(beta, yes, deps) {
|
|
|
69022
69199
|
promptMessage: `Update local project ClaudeKit content${localKits[0] || selection.kit ? ` (${localKits[0] || selection.kit})` : ""}?`
|
|
69023
69200
|
};
|
|
69024
69201
|
kitVersion = selection.kit ? localMetadata?.kits?.[selection.kit]?.version : undefined;
|
|
69202
|
+
installModePreference = undefined;
|
|
69025
69203
|
}
|
|
69026
69204
|
}
|
|
69027
69205
|
} catch (error) {
|
|
@@ -69051,7 +69229,7 @@ async function promptKitUpdate(beta, yes, deps) {
|
|
|
69051
69229
|
}
|
|
69052
69230
|
const useBeta = beta || isBetaInstalled;
|
|
69053
69231
|
if (yes) {
|
|
69054
|
-
const initCmd = buildInitCommand(selection.isGlobal, selection.kit, useBeta, true, forceKitReinstall);
|
|
69232
|
+
const initCmd = buildInitCommand(selection.isGlobal, selection.kit, useBeta, true, forceKitReinstall, installModePreference);
|
|
69055
69233
|
logger.info(`Running: ${initCmd}`);
|
|
69056
69234
|
const s = (deps?.spinnerFn ?? de)();
|
|
69057
69235
|
s.start("Updating ClaudeKit content...");
|
|
@@ -69073,6 +69251,9 @@ async function promptKitUpdate(beta, yes, deps) {
|
|
|
69073
69251
|
} catch (error) {
|
|
69074
69252
|
s.stop("Kit update finished");
|
|
69075
69253
|
const errorMsg = error instanceof Error ? error.message : "unknown";
|
|
69254
|
+
if (installModePreference === "plugin") {
|
|
69255
|
+
throw new StrictPluginUpdateError(`Strict plugin kit update failed: ${errorMsg}`);
|
|
69256
|
+
}
|
|
69076
69257
|
if (errorMsg.includes("exit code") && !errorMsg.includes("exit code 0")) {
|
|
69077
69258
|
logger.warning("Kit content update may have encountered issues");
|
|
69078
69259
|
logger.verbose(`Error: ${errorMsg}`);
|
|
@@ -69084,8 +69265,12 @@ async function promptKitUpdate(beta, yes, deps) {
|
|
|
69084
69265
|
const args = ["init"];
|
|
69085
69266
|
if (selection.isGlobal)
|
|
69086
69267
|
args.push("-g");
|
|
69268
|
+
if (selection.kit)
|
|
69269
|
+
args.push("--kit", selection.kit);
|
|
69087
69270
|
if (forceKitReinstall)
|
|
69088
69271
|
args.push("--restore-ck-hooks");
|
|
69272
|
+
if (installModePreference)
|
|
69273
|
+
args.push("--install-mode", installModePreference);
|
|
69089
69274
|
args.push("--install-skills");
|
|
69090
69275
|
if (useBeta)
|
|
69091
69276
|
args.push("--beta");
|
|
@@ -69102,10 +69287,15 @@ async function promptKitUpdate(beta, yes, deps) {
|
|
|
69102
69287
|
}));
|
|
69103
69288
|
const exitCode = await spawnFn(args);
|
|
69104
69289
|
if (exitCode !== 0) {
|
|
69290
|
+
if (installModePreference === "plugin") {
|
|
69291
|
+
throw new StrictPluginUpdateError(`Strict plugin kit update failed with exit code ${exitCode}`);
|
|
69292
|
+
}
|
|
69105
69293
|
logger.warning("Kit content update may have encountered issues");
|
|
69106
69294
|
}
|
|
69107
69295
|
}
|
|
69108
69296
|
} catch (error) {
|
|
69297
|
+
if (error instanceof StrictPluginUpdateError)
|
|
69298
|
+
throw error;
|
|
69109
69299
|
logger.verbose(`Failed to prompt for kit update: ${error instanceof Error ? error.message : "unknown error"}`);
|
|
69110
69300
|
}
|
|
69111
69301
|
}
|
|
@@ -69258,12 +69448,13 @@ async function promptMigrateUpdate(deps) {
|
|
|
69258
69448
|
logger.verbose(`Migrate step skipped: ${error instanceof Error ? error.message : "unknown"}`);
|
|
69259
69449
|
}
|
|
69260
69450
|
}
|
|
69261
|
-
var import_fs_extra8, execAsync2, SAFE_PROVIDER_NAME, HOOK_DEPENDENCY_EXTENSIONS, MANAGED_HOOKS_MANIFEST = "managed-hooks.json";
|
|
69451
|
+
var import_fs_extra8, execAsync2, SAFE_PROVIDER_NAME, HOOK_DEPENDENCY_EXTENSIONS, MANAGED_HOOKS_MANIFEST = "managed-hooks.json", StrictPluginUpdateError;
|
|
69262
69452
|
var init_post_update_handler = __esm(() => {
|
|
69263
69453
|
init_ck_config_manager();
|
|
69264
69454
|
init_hook_health_checker();
|
|
69265
69455
|
init_codex_plugin_installer();
|
|
69266
69456
|
init_install_mode_detector();
|
|
69457
|
+
init_install_mode_preference();
|
|
69267
69458
|
init_metadata_migration();
|
|
69268
69459
|
init_version_utils();
|
|
69269
69460
|
init_claudekit_scanner();
|
|
@@ -69276,6 +69467,12 @@ var init_post_update_handler = __esm(() => {
|
|
|
69276
69467
|
execAsync2 = promisify10(exec2);
|
|
69277
69468
|
SAFE_PROVIDER_NAME = /^[a-z0-9-]+$/;
|
|
69278
69469
|
HOOK_DEPENDENCY_EXTENSIONS = [".js", ".cjs", ".mjs", ".json"];
|
|
69470
|
+
StrictPluginUpdateError = class StrictPluginUpdateError extends Error {
|
|
69471
|
+
constructor(message) {
|
|
69472
|
+
super(message);
|
|
69473
|
+
this.name = "StrictPluginUpdateError";
|
|
69474
|
+
}
|
|
69475
|
+
};
|
|
69279
69476
|
});
|
|
69280
69477
|
|
|
69281
69478
|
// src/commands/update-cli.ts
|
|
@@ -69409,7 +69606,7 @@ var init_update_cli = __esm(() => {
|
|
|
69409
69606
|
|
|
69410
69607
|
// src/domains/sync/config-version-checker.ts
|
|
69411
69608
|
import { mkdir as mkdir19, readFile as readFile39, unlink as unlink9, writeFile as writeFile21 } from "node:fs/promises";
|
|
69412
|
-
import { join as
|
|
69609
|
+
import { join as join71 } from "node:path";
|
|
69413
69610
|
function parseCacheTtl() {
|
|
69414
69611
|
const envValue = process.env.CK_SYNC_CACHE_TTL;
|
|
69415
69612
|
if (!envValue) {
|
|
@@ -69435,11 +69632,11 @@ function parseCacheTtl() {
|
|
|
69435
69632
|
class ConfigVersionChecker {
|
|
69436
69633
|
static getLegacyCacheFilePath(kitType, global3) {
|
|
69437
69634
|
const cacheDir = PathResolver.getCacheDir(global3);
|
|
69438
|
-
return
|
|
69635
|
+
return join71(cacheDir, `${kitType}-${CACHE_FILENAME}`);
|
|
69439
69636
|
}
|
|
69440
69637
|
static getCacheFilePath(kitType, global3, channel) {
|
|
69441
69638
|
const cacheDir = PathResolver.getCacheDir(global3);
|
|
69442
|
-
return
|
|
69639
|
+
return join71(cacheDir, `${kitType}-${channel}-${CACHE_FILENAME}`);
|
|
69443
69640
|
}
|
|
69444
69641
|
static resolveChannel(currentVersion, override) {
|
|
69445
69642
|
if (override) {
|
|
@@ -69675,7 +69872,7 @@ import { execFile as execFile9 } from "node:child_process";
|
|
|
69675
69872
|
import { existsSync as existsSync49 } from "node:fs";
|
|
69676
69873
|
import { readFile as readFile40 } from "node:fs/promises";
|
|
69677
69874
|
import { cpus, homedir as homedir42, totalmem } from "node:os";
|
|
69678
|
-
import { join as
|
|
69875
|
+
import { join as join72 } from "node:path";
|
|
69679
69876
|
function runCommand(cmd, args, fallback2) {
|
|
69680
69877
|
return new Promise((resolve36) => {
|
|
69681
69878
|
execFile9(cmd, args, { timeout: 5000 }, (err, stdout) => {
|
|
@@ -69961,7 +70158,7 @@ async function getPackageJson() {
|
|
|
69961
70158
|
}
|
|
69962
70159
|
async function getKitMetadata2(kitName) {
|
|
69963
70160
|
try {
|
|
69964
|
-
const metadataPath =
|
|
70161
|
+
const metadataPath = join72(PathResolver.getGlobalKitDir(), "metadata.json");
|
|
69965
70162
|
if (!existsSync49(metadataPath))
|
|
69966
70163
|
return null;
|
|
69967
70164
|
const content = await readFile40(metadataPath, "utf-8");
|
|
@@ -70119,7 +70316,7 @@ var init_routes = __esm(() => {
|
|
|
70119
70316
|
|
|
70120
70317
|
// src/domains/web-server/static-server.ts
|
|
70121
70318
|
import { existsSync as existsSync50 } from "node:fs";
|
|
70122
|
-
import { basename as basename24, dirname as dirname31, join as
|
|
70319
|
+
import { basename as basename24, dirname as dirname31, join as join73, resolve as resolve36 } from "node:path";
|
|
70123
70320
|
import { fileURLToPath as fileURLToPath2 } from "node:url";
|
|
70124
70321
|
function addRuntimeUiCandidate(candidates, runtimePath) {
|
|
70125
70322
|
if (!runtimePath) {
|
|
@@ -70131,22 +70328,22 @@ function addRuntimeUiCandidate(candidates, runtimePath) {
|
|
|
70131
70328
|
}
|
|
70132
70329
|
const entryDir = dirname31(resolve36(runtimePath));
|
|
70133
70330
|
if (basename24(entryDir) === "dist") {
|
|
70134
|
-
candidates.add(
|
|
70331
|
+
candidates.add(join73(entryDir, "ui"));
|
|
70135
70332
|
}
|
|
70136
|
-
candidates.add(
|
|
70333
|
+
candidates.add(join73(entryDir, "..", "dist", "ui"));
|
|
70137
70334
|
}
|
|
70138
70335
|
function resolveUiDistPath() {
|
|
70139
70336
|
const candidates = new Set;
|
|
70140
70337
|
addRuntimeUiCandidate(candidates, process.argv[1]);
|
|
70141
|
-
candidates.add(
|
|
70142
|
-
candidates.add(
|
|
70143
|
-
candidates.add(
|
|
70338
|
+
candidates.add(join73(__dirname3, "ui"));
|
|
70339
|
+
candidates.add(join73(process.cwd(), "dist", "ui"));
|
|
70340
|
+
candidates.add(join73(process.cwd(), "src", "ui", "dist"));
|
|
70144
70341
|
for (const path7 of candidates) {
|
|
70145
|
-
if (existsSync50(
|
|
70342
|
+
if (existsSync50(join73(path7, "index.html"))) {
|
|
70146
70343
|
return path7;
|
|
70147
70344
|
}
|
|
70148
70345
|
}
|
|
70149
|
-
return Array.from(candidates)[0] ??
|
|
70346
|
+
return Array.from(candidates)[0] ?? join73(process.cwd(), "dist", "ui");
|
|
70150
70347
|
}
|
|
70151
70348
|
function serveStatic(app) {
|
|
70152
70349
|
const uiDistPath = resolveUiDistPath();
|
|
@@ -70182,7 +70379,7 @@ function serveStatic(app) {
|
|
|
70182
70379
|
if (req.path.startsWith("/assets/") || req.path.match(/\.(js|css|ico|png|jpg|svg|woff2?)$/)) {
|
|
70183
70380
|
return next();
|
|
70184
70381
|
}
|
|
70185
|
-
res.sendFile(
|
|
70382
|
+
res.sendFile(join73(uiDistPath, "index.html"), { dotfiles: "allow" });
|
|
70186
70383
|
});
|
|
70187
70384
|
logger.debug(`Serving static files from ${uiDistPath}`);
|
|
70188
70385
|
}
|
|
@@ -74988,7 +75185,7 @@ var init_process_executor = __esm(() => {
|
|
|
74988
75185
|
});
|
|
74989
75186
|
|
|
74990
75187
|
// src/services/package-installer/agy-installer.ts
|
|
74991
|
-
import { join as
|
|
75188
|
+
import { join as join92 } from "node:path";
|
|
74992
75189
|
async function isAgyInstalled() {
|
|
74993
75190
|
try {
|
|
74994
75191
|
await execAsync7("agy --version", { timeout: 1e4 });
|
|
@@ -75000,7 +75197,7 @@ async function isAgyInstalled() {
|
|
|
75000
75197
|
async function installAgyUnix() {
|
|
75001
75198
|
const { unlink: unlink13 } = await import("node:fs/promises");
|
|
75002
75199
|
const { tmpdir: tmpdir4 } = await import("node:os");
|
|
75003
|
-
const tempScriptPath =
|
|
75200
|
+
const tempScriptPath = join92(tmpdir4(), "agy-install.sh");
|
|
75004
75201
|
try {
|
|
75005
75202
|
logger.info("Downloading Antigravity CLI installation script...");
|
|
75006
75203
|
await execFileAsync7("curl", ["-fsSL", AGY_INSTALL_SH_URL, "-o", tempScriptPath], {
|
|
@@ -75072,7 +75269,7 @@ var init_agy_installer = __esm(() => {
|
|
|
75072
75269
|
});
|
|
75073
75270
|
|
|
75074
75271
|
// src/services/package-installer/opencode-installer.ts
|
|
75075
|
-
import { join as
|
|
75272
|
+
import { join as join93 } from "node:path";
|
|
75076
75273
|
async function isOpenCodeInstalled() {
|
|
75077
75274
|
try {
|
|
75078
75275
|
await execAsync7("opencode --version", { timeout: 5000 });
|
|
@@ -75095,7 +75292,7 @@ async function installOpenCode() {
|
|
|
75095
75292
|
logger.info(`Installing ${displayName}...`);
|
|
75096
75293
|
const { unlink: unlink13 } = await import("node:fs/promises");
|
|
75097
75294
|
const { tmpdir: tmpdir4 } = await import("node:os");
|
|
75098
|
-
const tempScriptPath =
|
|
75295
|
+
const tempScriptPath = join93(tmpdir4(), "opencode-install.sh");
|
|
75099
75296
|
try {
|
|
75100
75297
|
logger.info("Downloading OpenCode installation script...");
|
|
75101
75298
|
await execFileAsync7("curl", ["-fsSL", "https://opencode.ai/install", "-o", tempScriptPath], {
|
|
@@ -75330,8 +75527,8 @@ var init_npm_package_manager = __esm(() => {
|
|
|
75330
75527
|
});
|
|
75331
75528
|
|
|
75332
75529
|
// src/services/package-installer/install-error-handler.ts
|
|
75333
|
-
import { existsSync as existsSync62, readFileSync as
|
|
75334
|
-
import { join as
|
|
75530
|
+
import { existsSync as existsSync62, readFileSync as readFileSync22, unlinkSync as unlinkSync3 } from "node:fs";
|
|
75531
|
+
import { join as join94 } from "node:path";
|
|
75335
75532
|
function parseNameReason(str2) {
|
|
75336
75533
|
const colonIndex = str2.indexOf(":");
|
|
75337
75534
|
if (colonIndex === -1) {
|
|
@@ -75394,14 +75591,14 @@ function getSystemPackageCommands(summary, systemFailures) {
|
|
|
75394
75591
|
return summary.remediation.sudo_packages ? [summary.remediation.sudo_packages] : [];
|
|
75395
75592
|
}
|
|
75396
75593
|
function displayInstallErrors(skillsDir2) {
|
|
75397
|
-
const summaryPath =
|
|
75594
|
+
const summaryPath = join94(skillsDir2, ".install-error-summary.json");
|
|
75398
75595
|
if (!existsSync62(summaryPath)) {
|
|
75399
75596
|
logger.error("Skills installation failed. Run with --verbose for details.");
|
|
75400
75597
|
return;
|
|
75401
75598
|
}
|
|
75402
75599
|
let summary;
|
|
75403
75600
|
try {
|
|
75404
|
-
summary = JSON.parse(
|
|
75601
|
+
summary = JSON.parse(readFileSync22(summaryPath, "utf-8"));
|
|
75405
75602
|
} catch (parseError) {
|
|
75406
75603
|
logger.error("Failed to parse error summary. File may be corrupted.");
|
|
75407
75604
|
logger.debug(`Parse error: ${parseError instanceof Error ? parseError.message : String(parseError)}`);
|
|
@@ -75493,7 +75690,7 @@ async function checkNeedsSudoPackages() {
|
|
|
75493
75690
|
}
|
|
75494
75691
|
}
|
|
75495
75692
|
function hasInstallState(skillsDir2) {
|
|
75496
|
-
const stateFilePath =
|
|
75693
|
+
const stateFilePath = join94(skillsDir2, ".install-state.json");
|
|
75497
75694
|
return existsSync62(stateFilePath);
|
|
75498
75695
|
}
|
|
75499
75696
|
var WHICH_COMMAND_TIMEOUT_MS = 5000, WINDOWS_SYSTEM_PACKAGES, SYSTEM_TOOL_KEYS, WINDOWS_RSVG_COMMANDS;
|
|
@@ -75511,7 +75708,7 @@ var init_install_error_handler = __esm(() => {
|
|
|
75511
75708
|
});
|
|
75512
75709
|
|
|
75513
75710
|
// src/services/package-installer/skills-installer.ts
|
|
75514
|
-
import { join as
|
|
75711
|
+
import { join as join95 } from "node:path";
|
|
75515
75712
|
async function installSkillsDependencies(skillsDir2, options2 = {}) {
|
|
75516
75713
|
const { skipConfirm = false, withSudo = false } = options2;
|
|
75517
75714
|
const displayName = "Skills Dependencies";
|
|
@@ -75537,7 +75734,7 @@ async function installSkillsDependencies(skillsDir2, options2 = {}) {
|
|
|
75537
75734
|
const clack = await Promise.resolve().then(() => (init_dist2(), exports_dist));
|
|
75538
75735
|
const platform10 = process.platform;
|
|
75539
75736
|
const scriptName = platform10 === "win32" ? "install.ps1" : "install.sh";
|
|
75540
|
-
const scriptPath =
|
|
75737
|
+
const scriptPath = join95(skillsDir2, scriptName);
|
|
75541
75738
|
try {
|
|
75542
75739
|
validateScriptPath(skillsDir2, scriptPath);
|
|
75543
75740
|
} catch (error) {
|
|
@@ -75553,7 +75750,7 @@ async function installSkillsDependencies(skillsDir2, options2 = {}) {
|
|
|
75553
75750
|
logger.warning(`Skills installation script not found: ${scriptPath}`);
|
|
75554
75751
|
logger.info("");
|
|
75555
75752
|
logger.info("\uD83D\uDCD6 Manual Installation Instructions:");
|
|
75556
|
-
logger.info(` See: ${
|
|
75753
|
+
logger.info(` See: ${join95(skillsDir2, "INSTALLATION.md")}`);
|
|
75557
75754
|
logger.info("");
|
|
75558
75755
|
logger.info("Quick start:");
|
|
75559
75756
|
logger.info(" cd .claude/skills/ai-multimodal/scripts");
|
|
@@ -75600,7 +75797,7 @@ async function installSkillsDependencies(skillsDir2, options2 = {}) {
|
|
|
75600
75797
|
logger.info(` ${platform10 === "win32" ? `powershell -File "${scriptPath}"` : `bash ${scriptPath}`}`);
|
|
75601
75798
|
logger.info("");
|
|
75602
75799
|
logger.info("Or see complete guide:");
|
|
75603
|
-
logger.info(` ${
|
|
75800
|
+
logger.info(` ${join95(skillsDir2, "INSTALLATION.md")}`);
|
|
75604
75801
|
return {
|
|
75605
75802
|
success: false,
|
|
75606
75803
|
package: displayName,
|
|
@@ -75721,7 +75918,7 @@ async function installSkillsDependencies(skillsDir2, options2 = {}) {
|
|
|
75721
75918
|
logger.info("\uD83D\uDCD6 Manual Installation Instructions:");
|
|
75722
75919
|
logger.info("");
|
|
75723
75920
|
logger.info("See complete guide:");
|
|
75724
|
-
logger.info(` cat ${
|
|
75921
|
+
logger.info(` cat ${join95(skillsDir2, "INSTALLATION.md")}`);
|
|
75725
75922
|
logger.info("");
|
|
75726
75923
|
logger.info("Quick start:");
|
|
75727
75924
|
logger.info(" cd .claude/skills/ai-multimodal/scripts");
|
|
@@ -75767,7 +75964,7 @@ var init_skills_installer2 = __esm(() => {
|
|
|
75767
75964
|
// src/services/package-installer/agy-mcp/config-manager.ts
|
|
75768
75965
|
import { existsSync as existsSync63 } from "node:fs";
|
|
75769
75966
|
import { mkdir as mkdir23, readFile as readFile49, writeFile as writeFile25 } from "node:fs/promises";
|
|
75770
|
-
import { dirname as dirname34, join as
|
|
75967
|
+
import { dirname as dirname34, join as join96 } from "node:path";
|
|
75771
75968
|
async function readJsonFile(filePath) {
|
|
75772
75969
|
try {
|
|
75773
75970
|
const content = await readFile49(filePath, "utf-8");
|
|
@@ -75779,7 +75976,7 @@ async function readJsonFile(filePath) {
|
|
|
75779
75976
|
}
|
|
75780
75977
|
}
|
|
75781
75978
|
async function addAgyToGitignore(projectDir) {
|
|
75782
|
-
const gitignorePath =
|
|
75979
|
+
const gitignorePath = join96(projectDir, ".gitignore");
|
|
75783
75980
|
try {
|
|
75784
75981
|
let content = "";
|
|
75785
75982
|
if (existsSync63(gitignorePath)) {
|
|
@@ -75879,12 +76076,12 @@ var init_config_manager2 = __esm(() => {
|
|
|
75879
76076
|
// src/services/package-installer/agy-mcp/validation.ts
|
|
75880
76077
|
import { existsSync as existsSync64, lstatSync, readlinkSync } from "node:fs";
|
|
75881
76078
|
import { homedir as homedir45 } from "node:os";
|
|
75882
|
-
import { join as
|
|
76079
|
+
import { join as join97 } from "node:path";
|
|
75883
76080
|
function getGlobalMcpConfigPath() {
|
|
75884
|
-
return
|
|
76081
|
+
return join97(homedir45(), ".claude", ".mcp.json");
|
|
75885
76082
|
}
|
|
75886
76083
|
function getLocalMcpConfigPath(projectDir) {
|
|
75887
|
-
return
|
|
76084
|
+
return join97(projectDir, ".mcp.json");
|
|
75888
76085
|
}
|
|
75889
76086
|
function findMcpConfigPath(projectDir) {
|
|
75890
76087
|
const localPath = getLocalMcpConfigPath(projectDir);
|
|
@@ -75902,9 +76099,9 @@ function findMcpConfigPath(projectDir) {
|
|
|
75902
76099
|
}
|
|
75903
76100
|
function getAgyMcpConfigPath(projectDir, isGlobal) {
|
|
75904
76101
|
if (isGlobal) {
|
|
75905
|
-
return
|
|
76102
|
+
return join97(homedir45(), ".gemini", "config", "mcp_config.json");
|
|
75906
76103
|
}
|
|
75907
|
-
return
|
|
76104
|
+
return join97(projectDir, ".agents", "mcp_config.json");
|
|
75908
76105
|
}
|
|
75909
76106
|
function checkExistingAgyConfig(projectDir, isGlobal = false) {
|
|
75910
76107
|
const agyConfigPath = getAgyMcpConfigPath(projectDir, isGlobal);
|
|
@@ -75934,7 +76131,7 @@ var init_validation = __esm(() => {
|
|
|
75934
76131
|
// src/services/package-installer/agy-mcp/linker-core.ts
|
|
75935
76132
|
import { existsSync as existsSync65 } from "node:fs";
|
|
75936
76133
|
import { mkdir as mkdir24, symlink as symlink3 } from "node:fs/promises";
|
|
75937
|
-
import { dirname as dirname35, join as
|
|
76134
|
+
import { dirname as dirname35, join as join98 } from "node:path";
|
|
75938
76135
|
async function createSymlink(targetPath, linkPath, projectDir, isGlobal) {
|
|
75939
76136
|
const linkDir = dirname35(linkPath);
|
|
75940
76137
|
if (!existsSync65(linkDir)) {
|
|
@@ -75945,7 +76142,7 @@ async function createSymlink(targetPath, linkPath, projectDir, isGlobal) {
|
|
|
75945
76142
|
if (isGlobal) {
|
|
75946
76143
|
symlinkTarget = getGlobalMcpConfigPath();
|
|
75947
76144
|
} else {
|
|
75948
|
-
const localMcpPath =
|
|
76145
|
+
const localMcpPath = join98(projectDir, ".mcp.json");
|
|
75949
76146
|
const isLocalConfig = targetPath === localMcpPath;
|
|
75950
76147
|
symlinkTarget = isLocalConfig ? "../.mcp.json" : targetPath;
|
|
75951
76148
|
}
|
|
@@ -78363,9 +78560,9 @@ __export(exports_worktree_manager, {
|
|
|
78363
78560
|
});
|
|
78364
78561
|
import { existsSync as existsSync77 } from "node:fs";
|
|
78365
78562
|
import { readFile as readFile70, writeFile as writeFile41 } from "node:fs/promises";
|
|
78366
|
-
import { join as
|
|
78563
|
+
import { join as join162 } from "node:path";
|
|
78367
78564
|
async function createWorktree(projectDir, issueNumber, baseBranch) {
|
|
78368
|
-
const worktreePath =
|
|
78565
|
+
const worktreePath = join162(projectDir, WORKTREE_DIR, `issue-${issueNumber}`);
|
|
78369
78566
|
const branchName = `ck-watch/issue-${issueNumber}`;
|
|
78370
78567
|
await spawnAndCollect("git", ["fetch", "origin", baseBranch], projectDir).catch(() => {
|
|
78371
78568
|
logger.warning(`[worktree] Could not fetch origin/${baseBranch}, using local`);
|
|
@@ -78383,7 +78580,7 @@ async function createWorktree(projectDir, issueNumber, baseBranch) {
|
|
|
78383
78580
|
return worktreePath;
|
|
78384
78581
|
}
|
|
78385
78582
|
async function removeWorktree(projectDir, issueNumber) {
|
|
78386
|
-
const worktreePath =
|
|
78583
|
+
const worktreePath = join162(projectDir, WORKTREE_DIR, `issue-${issueNumber}`);
|
|
78387
78584
|
const branchName = `ck-watch/issue-${issueNumber}`;
|
|
78388
78585
|
try {
|
|
78389
78586
|
await spawnAndCollect("git", ["worktree", "remove", worktreePath, "--force"], projectDir);
|
|
@@ -78397,7 +78594,7 @@ async function listActiveWorktrees(projectDir) {
|
|
|
78397
78594
|
try {
|
|
78398
78595
|
const output2 = await spawnAndCollect("git", ["worktree", "list", "--porcelain"], projectDir);
|
|
78399
78596
|
const issueNumbers = [];
|
|
78400
|
-
const worktreePrefix =
|
|
78597
|
+
const worktreePrefix = join162(projectDir, WORKTREE_DIR, "issue-").replace(/\\/g, "/");
|
|
78401
78598
|
for (const line of output2.split(`
|
|
78402
78599
|
`)) {
|
|
78403
78600
|
if (line.startsWith("worktree ")) {
|
|
@@ -78425,7 +78622,7 @@ async function cleanupAllWorktrees(projectDir) {
|
|
|
78425
78622
|
await spawnAndCollect("git", ["worktree", "prune"], projectDir).catch(() => {});
|
|
78426
78623
|
}
|
|
78427
78624
|
async function ensureGitignore(projectDir) {
|
|
78428
|
-
const gitignorePath =
|
|
78625
|
+
const gitignorePath = join162(projectDir, ".gitignore");
|
|
78429
78626
|
try {
|
|
78430
78627
|
const content = existsSync77(gitignorePath) ? await readFile70(gitignorePath, "utf-8") : "";
|
|
78431
78628
|
if (!content.includes(".worktrees")) {
|
|
@@ -78529,16 +78726,16 @@ var init_content_validator = __esm(() => {
|
|
|
78529
78726
|
|
|
78530
78727
|
// src/commands/content/phases/context-cache-manager.ts
|
|
78531
78728
|
import { createHash as createHash11 } from "node:crypto";
|
|
78532
|
-
import { existsSync as existsSync83, mkdirSync as mkdirSync7, readFileSync as
|
|
78729
|
+
import { existsSync as existsSync83, mkdirSync as mkdirSync7, readFileSync as readFileSync25, readdirSync as readdirSync15, statSync as statSync15 } from "node:fs";
|
|
78533
78730
|
import { rename as rename16, writeFile as writeFile43 } from "node:fs/promises";
|
|
78534
78731
|
import { homedir as homedir54 } from "node:os";
|
|
78535
|
-
import { basename as basename34, join as
|
|
78732
|
+
import { basename as basename34, join as join169 } from "node:path";
|
|
78536
78733
|
function getCachedContext(repoPath) {
|
|
78537
78734
|
const cachePath = getCacheFilePath(repoPath);
|
|
78538
78735
|
if (!existsSync83(cachePath))
|
|
78539
78736
|
return null;
|
|
78540
78737
|
try {
|
|
78541
|
-
const raw2 =
|
|
78738
|
+
const raw2 = readFileSync25(cachePath, "utf-8");
|
|
78542
78739
|
const cache5 = JSON.parse(raw2);
|
|
78543
78740
|
const age = Date.now() - new Date(cache5.createdAt).getTime();
|
|
78544
78741
|
if (age >= CACHE_TTL_MS5)
|
|
@@ -78575,25 +78772,25 @@ function computeSourceHash(repoPath) {
|
|
|
78575
78772
|
}
|
|
78576
78773
|
function getDocSourcePaths(repoPath) {
|
|
78577
78774
|
const paths = [];
|
|
78578
|
-
const docsDir =
|
|
78775
|
+
const docsDir = join169(repoPath, "docs");
|
|
78579
78776
|
if (existsSync83(docsDir)) {
|
|
78580
78777
|
try {
|
|
78581
78778
|
const files = readdirSync15(docsDir);
|
|
78582
78779
|
for (const f3 of files) {
|
|
78583
78780
|
if (f3.endsWith(".md"))
|
|
78584
|
-
paths.push(
|
|
78781
|
+
paths.push(join169(docsDir, f3));
|
|
78585
78782
|
}
|
|
78586
78783
|
} catch {}
|
|
78587
78784
|
}
|
|
78588
|
-
const readme =
|
|
78785
|
+
const readme = join169(repoPath, "README.md");
|
|
78589
78786
|
if (existsSync83(readme))
|
|
78590
78787
|
paths.push(readme);
|
|
78591
|
-
const stylesDir =
|
|
78788
|
+
const stylesDir = join169(repoPath, "assets", "writing-styles");
|
|
78592
78789
|
if (existsSync83(stylesDir)) {
|
|
78593
78790
|
try {
|
|
78594
78791
|
const files = readdirSync15(stylesDir);
|
|
78595
78792
|
for (const f3 of files) {
|
|
78596
|
-
paths.push(
|
|
78793
|
+
paths.push(join169(stylesDir, f3));
|
|
78597
78794
|
}
|
|
78598
78795
|
} catch {}
|
|
78599
78796
|
}
|
|
@@ -78602,11 +78799,11 @@ function getDocSourcePaths(repoPath) {
|
|
|
78602
78799
|
function getCacheFilePath(repoPath) {
|
|
78603
78800
|
const repoName = basename34(repoPath).replace(/[^a-zA-Z0-9_-]/g, "_");
|
|
78604
78801
|
const pathHash = createHash11("sha256").update(repoPath).digest("hex").slice(0, 8);
|
|
78605
|
-
return
|
|
78802
|
+
return join169(CACHE_DIR, `${repoName}-${pathHash}-context-cache.json`);
|
|
78606
78803
|
}
|
|
78607
78804
|
var CACHE_DIR, CACHE_TTL_MS5;
|
|
78608
78805
|
var init_context_cache_manager = __esm(() => {
|
|
78609
|
-
CACHE_DIR =
|
|
78806
|
+
CACHE_DIR = join169(homedir54(), ".claudekit", "cache");
|
|
78610
78807
|
CACHE_TTL_MS5 = 24 * 60 * 60 * 1000;
|
|
78611
78808
|
});
|
|
78612
78809
|
|
|
@@ -78786,8 +78983,8 @@ function extractContentFromResponse(response) {
|
|
|
78786
78983
|
|
|
78787
78984
|
// src/commands/content/phases/docs-summarizer.ts
|
|
78788
78985
|
import { execSync as execSync7 } from "node:child_process";
|
|
78789
|
-
import { existsSync as existsSync84, readFileSync as
|
|
78790
|
-
import { join as
|
|
78986
|
+
import { existsSync as existsSync84, readFileSync as readFileSync26, readdirSync as readdirSync16 } from "node:fs";
|
|
78987
|
+
import { join as join170 } from "node:path";
|
|
78791
78988
|
async function summarizeProjectDocs(repoPath, contentLogger) {
|
|
78792
78989
|
const rawContent = collectRawDocs(repoPath);
|
|
78793
78990
|
if (rawContent.total.length < 200) {
|
|
@@ -78835,18 +79032,18 @@ function collectRawDocs(repoPath) {
|
|
|
78835
79032
|
return "";
|
|
78836
79033
|
if (totalChars >= MAX_RAW_CONTENT_CHARS)
|
|
78837
79034
|
return "";
|
|
78838
|
-
const content =
|
|
79035
|
+
const content = readFileSync26(filePath, "utf-8");
|
|
78839
79036
|
const capped = content.slice(0, Math.min(maxChars, MAX_RAW_CONTENT_CHARS - totalChars));
|
|
78840
79037
|
totalChars += capped.length;
|
|
78841
79038
|
return capped;
|
|
78842
79039
|
};
|
|
78843
79040
|
const docsContent = [];
|
|
78844
|
-
const docsDir =
|
|
79041
|
+
const docsDir = join170(repoPath, "docs");
|
|
78845
79042
|
if (existsSync84(docsDir)) {
|
|
78846
79043
|
try {
|
|
78847
79044
|
const files = readdirSync16(docsDir).filter((f3) => f3.endsWith(".md")).sort();
|
|
78848
79045
|
for (const f3 of files) {
|
|
78849
|
-
const content = readCapped(
|
|
79046
|
+
const content = readCapped(join170(docsDir, f3), 5000);
|
|
78850
79047
|
if (content) {
|
|
78851
79048
|
docsContent.push(`### ${f3}
|
|
78852
79049
|
${content}`);
|
|
@@ -78860,21 +79057,21 @@ ${content}`);
|
|
|
78860
79057
|
let brand = "";
|
|
78861
79058
|
const brandCandidates = ["docs/brand-guidelines.md", "docs/design-guidelines.md"];
|
|
78862
79059
|
for (const p of brandCandidates) {
|
|
78863
|
-
brand = readCapped(
|
|
79060
|
+
brand = readCapped(join170(repoPath, p), 3000);
|
|
78864
79061
|
if (brand)
|
|
78865
79062
|
break;
|
|
78866
79063
|
}
|
|
78867
79064
|
let styles3 = "";
|
|
78868
|
-
const stylesDir =
|
|
79065
|
+
const stylesDir = join170(repoPath, "assets", "writing-styles");
|
|
78869
79066
|
if (existsSync84(stylesDir)) {
|
|
78870
79067
|
try {
|
|
78871
79068
|
const files = readdirSync16(stylesDir).slice(0, 3);
|
|
78872
|
-
styles3 = files.map((f3) => readCapped(
|
|
79069
|
+
styles3 = files.map((f3) => readCapped(join170(stylesDir, f3), 1000)).filter(Boolean).join(`
|
|
78873
79070
|
|
|
78874
79071
|
`);
|
|
78875
79072
|
} catch {}
|
|
78876
79073
|
}
|
|
78877
|
-
const readme = readCapped(
|
|
79074
|
+
const readme = readCapped(join170(repoPath, "README.md"), 3000);
|
|
78878
79075
|
const total = [docs, brand, styles3, readme].join(`
|
|
78879
79076
|
`);
|
|
78880
79077
|
return { docs, brand, styles: styles3, readme, total };
|
|
@@ -79061,9 +79258,9 @@ IMPORTANT: Generate the image and output the path as JSON: {"imagePath": "/path/
|
|
|
79061
79258
|
import { execSync as execSync8 } from "node:child_process";
|
|
79062
79259
|
import { existsSync as existsSync85, mkdirSync as mkdirSync8, readdirSync as readdirSync17 } from "node:fs";
|
|
79063
79260
|
import { homedir as homedir55 } from "node:os";
|
|
79064
|
-
import { join as
|
|
79261
|
+
import { join as join171 } from "node:path";
|
|
79065
79262
|
async function generatePhoto(_content, context, config, platform18, contentId, contentLogger) {
|
|
79066
|
-
const mediaDir =
|
|
79263
|
+
const mediaDir = join171(config.contentDir.replace(/^~/, homedir55()), "media", String(contentId));
|
|
79067
79264
|
if (!existsSync85(mediaDir)) {
|
|
79068
79265
|
mkdirSync8(mediaDir, { recursive: true });
|
|
79069
79266
|
}
|
|
@@ -79088,7 +79285,7 @@ async function generatePhoto(_content, context, config, platform18, contentId, c
|
|
|
79088
79285
|
const imageFile = files.find((f3) => /\.(png|jpg|jpeg|webp)$/i.test(f3));
|
|
79089
79286
|
if (imageFile) {
|
|
79090
79287
|
const ext2 = imageFile.split(".").pop() ?? "png";
|
|
79091
|
-
return { path:
|
|
79288
|
+
return { path: join171(mediaDir, imageFile), ...dimensions, format: ext2 };
|
|
79092
79289
|
}
|
|
79093
79290
|
contentLogger.warn(`Photo generation produced no image for content ${contentId}`);
|
|
79094
79291
|
return null;
|
|
@@ -79178,7 +79375,7 @@ var init_content_creator = __esm(() => {
|
|
|
79178
79375
|
// src/commands/content/phases/content-logger.ts
|
|
79179
79376
|
import { createWriteStream as createWriteStream4, existsSync as existsSync86, mkdirSync as mkdirSync9, statSync as statSync16 } from "node:fs";
|
|
79180
79377
|
import { homedir as homedir56 } from "node:os";
|
|
79181
|
-
import { join as
|
|
79378
|
+
import { join as join172 } from "node:path";
|
|
79182
79379
|
|
|
79183
79380
|
class ContentLogger {
|
|
79184
79381
|
stream = null;
|
|
@@ -79186,7 +79383,7 @@ class ContentLogger {
|
|
|
79186
79383
|
logDir;
|
|
79187
79384
|
maxBytes;
|
|
79188
79385
|
constructor(maxBytes = 0) {
|
|
79189
|
-
this.logDir =
|
|
79386
|
+
this.logDir = join172(homedir56(), ".claudekit", "logs");
|
|
79190
79387
|
this.maxBytes = maxBytes;
|
|
79191
79388
|
}
|
|
79192
79389
|
init() {
|
|
@@ -79218,7 +79415,7 @@ class ContentLogger {
|
|
|
79218
79415
|
}
|
|
79219
79416
|
}
|
|
79220
79417
|
getLogPath() {
|
|
79221
|
-
return
|
|
79418
|
+
return join172(this.logDir, `content-${this.getDateStr()}.log`);
|
|
79222
79419
|
}
|
|
79223
79420
|
write(level, message) {
|
|
79224
79421
|
this.rotateIfNeeded();
|
|
@@ -79235,18 +79432,18 @@ class ContentLogger {
|
|
|
79235
79432
|
if (dateStr !== this.currentDate) {
|
|
79236
79433
|
this.close();
|
|
79237
79434
|
this.currentDate = dateStr;
|
|
79238
|
-
const logPath =
|
|
79435
|
+
const logPath = join172(this.logDir, `content-${dateStr}.log`);
|
|
79239
79436
|
this.stream = createWriteStream4(logPath, { flags: "a", mode: 384 });
|
|
79240
79437
|
return;
|
|
79241
79438
|
}
|
|
79242
79439
|
if (this.maxBytes > 0 && this.stream) {
|
|
79243
|
-
const logPath =
|
|
79440
|
+
const logPath = join172(this.logDir, `content-${this.currentDate}.log`);
|
|
79244
79441
|
try {
|
|
79245
79442
|
const stat26 = statSync16(logPath);
|
|
79246
79443
|
if (stat26.size >= this.maxBytes) {
|
|
79247
79444
|
this.close();
|
|
79248
79445
|
const suffix = Date.now();
|
|
79249
|
-
const rotatedPath =
|
|
79446
|
+
const rotatedPath = join172(this.logDir, `content-${this.currentDate}-${suffix}.log`);
|
|
79250
79447
|
import("node:fs/promises").then(({ rename: rename17 }) => rename17(logPath, rotatedPath).catch(() => {}));
|
|
79251
79448
|
this.stream = createWriteStream4(logPath, { flags: "w", mode: 384 });
|
|
79252
79449
|
}
|
|
@@ -79516,8 +79713,8 @@ function isNoiseCommit(title, author) {
|
|
|
79516
79713
|
|
|
79517
79714
|
// src/commands/content/phases/change-detector.ts
|
|
79518
79715
|
import { execSync as execSync10, spawnSync as spawnSync9 } from "node:child_process";
|
|
79519
|
-
import { existsSync as existsSync88, readFileSync as
|
|
79520
|
-
import { join as
|
|
79716
|
+
import { existsSync as existsSync88, readFileSync as readFileSync27, readdirSync as readdirSync18, statSync as statSync17 } from "node:fs";
|
|
79717
|
+
import { join as join173 } from "node:path";
|
|
79521
79718
|
function detectCommits(repo, since) {
|
|
79522
79719
|
try {
|
|
79523
79720
|
const fetchUrl = sshToHttps(repo.remoteUrl);
|
|
@@ -79626,7 +79823,7 @@ function detectTags(repo, since) {
|
|
|
79626
79823
|
}
|
|
79627
79824
|
}
|
|
79628
79825
|
function detectCompletedPlans(repo, since) {
|
|
79629
|
-
const plansDir =
|
|
79826
|
+
const plansDir = join173(repo.path, "plans");
|
|
79630
79827
|
if (!existsSync88(plansDir))
|
|
79631
79828
|
return [];
|
|
79632
79829
|
const sinceMs = new Date(since).getTime();
|
|
@@ -79636,14 +79833,14 @@ function detectCompletedPlans(repo, since) {
|
|
|
79636
79833
|
for (const entry of entries) {
|
|
79637
79834
|
if (!entry.isDirectory())
|
|
79638
79835
|
continue;
|
|
79639
|
-
const planFile =
|
|
79836
|
+
const planFile = join173(plansDir, entry.name, "plan.md");
|
|
79640
79837
|
if (!existsSync88(planFile))
|
|
79641
79838
|
continue;
|
|
79642
79839
|
try {
|
|
79643
79840
|
const stat26 = statSync17(planFile);
|
|
79644
79841
|
if (stat26.mtimeMs < sinceMs)
|
|
79645
79842
|
continue;
|
|
79646
|
-
const content =
|
|
79843
|
+
const content = readFileSync27(planFile, "utf-8");
|
|
79647
79844
|
const frontmatterMatch = content.match(/^---\r?\n([\s\S]*?)\r?\n---/);
|
|
79648
79845
|
if (!frontmatterMatch)
|
|
79649
79846
|
continue;
|
|
@@ -79714,7 +79911,7 @@ function classifyCommit(event) {
|
|
|
79714
79911
|
// src/commands/content/phases/repo-discoverer.ts
|
|
79715
79912
|
import { execSync as execSync11 } from "node:child_process";
|
|
79716
79913
|
import { readdirSync as readdirSync19 } from "node:fs";
|
|
79717
|
-
import { join as
|
|
79914
|
+
import { join as join174 } from "node:path";
|
|
79718
79915
|
function discoverRepos2(cwd2) {
|
|
79719
79916
|
const repos = [];
|
|
79720
79917
|
if (isGitRepoRoot(cwd2)) {
|
|
@@ -79727,7 +79924,7 @@ function discoverRepos2(cwd2) {
|
|
|
79727
79924
|
for (const entry of entries) {
|
|
79728
79925
|
if (!entry.isDirectory() || entry.name.startsWith("."))
|
|
79729
79926
|
continue;
|
|
79730
|
-
const dirPath =
|
|
79927
|
+
const dirPath = join174(cwd2, entry.name);
|
|
79731
79928
|
if (isGitRepoRoot(dirPath)) {
|
|
79732
79929
|
const info = getRepoInfo(dirPath);
|
|
79733
79930
|
if (info)
|
|
@@ -80395,9 +80592,9 @@ var init_types6 = __esm(() => {
|
|
|
80395
80592
|
|
|
80396
80593
|
// src/commands/content/phases/state-manager.ts
|
|
80397
80594
|
import { readFile as readFile72, rename as rename17, writeFile as writeFile44 } from "node:fs/promises";
|
|
80398
|
-
import { join as
|
|
80595
|
+
import { join as join175 } from "node:path";
|
|
80399
80596
|
async function loadContentConfig(projectDir) {
|
|
80400
|
-
const configPath =
|
|
80597
|
+
const configPath = join175(projectDir, CK_CONFIG_FILE2);
|
|
80401
80598
|
try {
|
|
80402
80599
|
const raw2 = await readFile72(configPath, "utf-8");
|
|
80403
80600
|
const json = JSON.parse(raw2);
|
|
@@ -80407,13 +80604,13 @@ async function loadContentConfig(projectDir) {
|
|
|
80407
80604
|
}
|
|
80408
80605
|
}
|
|
80409
80606
|
async function saveContentConfig(projectDir, config) {
|
|
80410
|
-
const configPath =
|
|
80607
|
+
const configPath = join175(projectDir, CK_CONFIG_FILE2);
|
|
80411
80608
|
const json = await readJsonSafe5(configPath);
|
|
80412
80609
|
json.content = { ...json.content, ...config };
|
|
80413
80610
|
await atomicWrite3(configPath, json);
|
|
80414
80611
|
}
|
|
80415
80612
|
async function loadContentState(projectDir) {
|
|
80416
|
-
const configPath =
|
|
80613
|
+
const configPath = join175(projectDir, CK_CONFIG_FILE2);
|
|
80417
80614
|
try {
|
|
80418
80615
|
const raw2 = await readFile72(configPath, "utf-8");
|
|
80419
80616
|
const json = JSON.parse(raw2);
|
|
@@ -80424,7 +80621,7 @@ async function loadContentState(projectDir) {
|
|
|
80424
80621
|
}
|
|
80425
80622
|
}
|
|
80426
80623
|
async function saveContentState(projectDir, state) {
|
|
80427
|
-
const configPath =
|
|
80624
|
+
const configPath = join175(projectDir, CK_CONFIG_FILE2);
|
|
80428
80625
|
const sevenDaysAgo = new Date(Date.now() - 7 * 24 * 60 * 60 * 1000).toISOString().slice(0, 10);
|
|
80429
80626
|
for (const key of Object.keys(state.dailyPostCounts)) {
|
|
80430
80627
|
const dateStr = key.slice(-10);
|
|
@@ -80706,7 +80903,7 @@ var init_platform_setup_x = __esm(() => {
|
|
|
80706
80903
|
|
|
80707
80904
|
// src/commands/content/phases/setup-wizard.ts
|
|
80708
80905
|
import { existsSync as existsSync89 } from "node:fs";
|
|
80709
|
-
import { join as
|
|
80906
|
+
import { join as join176 } from "node:path";
|
|
80710
80907
|
async function runSetupWizard2(cwd2, contentLogger) {
|
|
80711
80908
|
console.log();
|
|
80712
80909
|
oe(import_picocolors43.default.bgCyan(import_picocolors43.default.white(" CK Content — Multi-Channel Content Engine ")));
|
|
@@ -80774,8 +80971,8 @@ async function showRepoSummary(cwd2) {
|
|
|
80774
80971
|
function detectBrandAssets(cwd2, contentLogger) {
|
|
80775
80972
|
const repos = discoverRepos2(cwd2);
|
|
80776
80973
|
for (const repo of repos) {
|
|
80777
|
-
const hasGuidelines = existsSync89(
|
|
80778
|
-
const hasStyles = existsSync89(
|
|
80974
|
+
const hasGuidelines = existsSync89(join176(repo.path, "docs", "brand-guidelines.md"));
|
|
80975
|
+
const hasStyles = existsSync89(join176(repo.path, "assets", "writing-styles"));
|
|
80779
80976
|
if (!hasGuidelines) {
|
|
80780
80977
|
f2.warning(`${repo.name}: No docs/brand-guidelines.md — content will use generic tone.`);
|
|
80781
80978
|
contentLogger.warn(`${repo.name}: missing docs/brand-guidelines.md`);
|
|
@@ -80915,15 +81112,15 @@ __export(exports_content_subcommands, {
|
|
|
80915
81112
|
logsContent: () => logsContent,
|
|
80916
81113
|
approveContentCmd: () => approveContentCmd
|
|
80917
81114
|
});
|
|
80918
|
-
import { existsSync as existsSync91, readFileSync as
|
|
81115
|
+
import { existsSync as existsSync91, readFileSync as readFileSync28, unlinkSync as unlinkSync6 } from "node:fs";
|
|
80919
81116
|
import { homedir as homedir58 } from "node:os";
|
|
80920
|
-
import { join as
|
|
81117
|
+
import { join as join177 } from "node:path";
|
|
80921
81118
|
function isDaemonRunning() {
|
|
80922
|
-
const lockFile =
|
|
81119
|
+
const lockFile = join177(LOCK_DIR, `${LOCK_NAME2}.lock`);
|
|
80923
81120
|
if (!existsSync91(lockFile))
|
|
80924
81121
|
return { running: false, pid: null };
|
|
80925
81122
|
try {
|
|
80926
|
-
const pidStr =
|
|
81123
|
+
const pidStr = readFileSync28(lockFile, "utf-8").trim();
|
|
80927
81124
|
const pid = Number.parseInt(pidStr, 10);
|
|
80928
81125
|
if (Number.isNaN(pid)) {
|
|
80929
81126
|
unlinkSync6(lockFile);
|
|
@@ -80951,13 +81148,13 @@ async function startContent(options2) {
|
|
|
80951
81148
|
await contentCommand(options2);
|
|
80952
81149
|
}
|
|
80953
81150
|
async function stopContent() {
|
|
80954
|
-
const lockFile =
|
|
81151
|
+
const lockFile = join177(LOCK_DIR, `${LOCK_NAME2}.lock`);
|
|
80955
81152
|
if (!existsSync91(lockFile)) {
|
|
80956
81153
|
logger.info("Content daemon is not running.");
|
|
80957
81154
|
return;
|
|
80958
81155
|
}
|
|
80959
81156
|
try {
|
|
80960
|
-
const pidStr =
|
|
81157
|
+
const pidStr = readFileSync28(lockFile, "utf-8").trim();
|
|
80961
81158
|
const pid = Number.parseInt(pidStr, 10);
|
|
80962
81159
|
if (!Number.isNaN(pid)) {
|
|
80963
81160
|
process.kill(pid, "SIGTERM");
|
|
@@ -80990,9 +81187,9 @@ async function statusContent() {
|
|
|
80990
81187
|
} catch {}
|
|
80991
81188
|
}
|
|
80992
81189
|
async function logsContent(options2) {
|
|
80993
|
-
const logDir =
|
|
81190
|
+
const logDir = join177(homedir58(), ".claudekit", "logs");
|
|
80994
81191
|
const dateStr = new Date().toISOString().slice(0, 10).replace(/-/g, "");
|
|
80995
|
-
const logPath =
|
|
81192
|
+
const logPath = join177(logDir, `content-${dateStr}.log`);
|
|
80996
81193
|
if (!existsSync91(logPath)) {
|
|
80997
81194
|
logger.info("No content logs found for today.");
|
|
80998
81195
|
return;
|
|
@@ -81005,7 +81202,7 @@ async function logsContent(options2) {
|
|
|
81005
81202
|
process.exit(0);
|
|
81006
81203
|
});
|
|
81007
81204
|
} else {
|
|
81008
|
-
const content =
|
|
81205
|
+
const content = readFileSync28(logPath, "utf-8");
|
|
81009
81206
|
console.log(content);
|
|
81010
81207
|
}
|
|
81011
81208
|
}
|
|
@@ -81024,13 +81221,13 @@ var init_content_subcommands = __esm(() => {
|
|
|
81024
81221
|
init_setup_wizard();
|
|
81025
81222
|
init_state_manager();
|
|
81026
81223
|
init_content_review_commands();
|
|
81027
|
-
LOCK_DIR =
|
|
81224
|
+
LOCK_DIR = join177(homedir58(), ".claudekit", "locks");
|
|
81028
81225
|
});
|
|
81029
81226
|
|
|
81030
81227
|
// src/commands/content/content-command.ts
|
|
81031
81228
|
import { existsSync as existsSync92, mkdirSync as mkdirSync11, unlinkSync as unlinkSync7, writeFileSync as writeFileSync9 } from "node:fs";
|
|
81032
81229
|
import { homedir as homedir59 } from "node:os";
|
|
81033
|
-
import { join as
|
|
81230
|
+
import { join as join178 } from "node:path";
|
|
81034
81231
|
async function contentCommand(options2) {
|
|
81035
81232
|
const cwd2 = process.cwd();
|
|
81036
81233
|
const contentLogger = new ContentLogger;
|
|
@@ -81208,8 +81405,8 @@ var init_content_command = __esm(() => {
|
|
|
81208
81405
|
init_publisher();
|
|
81209
81406
|
init_review_manager();
|
|
81210
81407
|
init_state_manager();
|
|
81211
|
-
LOCK_DIR2 =
|
|
81212
|
-
LOCK_FILE =
|
|
81408
|
+
LOCK_DIR2 = join178(homedir59(), ".claudekit", "locks");
|
|
81409
|
+
LOCK_FILE = join178(LOCK_DIR2, "ck-content.lock");
|
|
81213
81410
|
});
|
|
81214
81411
|
|
|
81215
81412
|
// src/commands/content/index.ts
|
|
@@ -88384,7 +88581,7 @@ import { promisify as promisify14 } from "node:util";
|
|
|
88384
88581
|
// src/domains/github/gh-cli-utils.ts
|
|
88385
88582
|
init_environment();
|
|
88386
88583
|
init_logger();
|
|
88387
|
-
import { readFileSync as
|
|
88584
|
+
import { readFileSync as readFileSync17 } from "node:fs";
|
|
88388
88585
|
var MIN_GH_CLI_VERSION = "2.20.0";
|
|
88389
88586
|
var GH_COMMAND_TIMEOUT_MS = 1e4;
|
|
88390
88587
|
function compareVersions6(a3, b3) {
|
|
@@ -88405,7 +88602,7 @@ function isWSL2() {
|
|
|
88405
88602
|
if (process.platform !== "linux")
|
|
88406
88603
|
return false;
|
|
88407
88604
|
try {
|
|
88408
|
-
const release =
|
|
88605
|
+
const release = readFileSync17("/proc/version", "utf-8").toLowerCase();
|
|
88409
88606
|
return release.includes("microsoft") || release.includes("wsl");
|
|
88410
88607
|
} catch (error) {
|
|
88411
88608
|
logger.debug(`WSL detection skipped: ${error instanceof Error ? error.message : "unknown error"}`);
|
|
@@ -89169,14 +89366,14 @@ async function checkCliInstallMethod() {
|
|
|
89169
89366
|
}
|
|
89170
89367
|
// src/domains/health-checks/checkers/claude-md-checker.ts
|
|
89171
89368
|
import { existsSync as existsSync52, statSync as statSync11 } from "node:fs";
|
|
89172
|
-
import { join as
|
|
89369
|
+
import { join as join74 } from "node:path";
|
|
89173
89370
|
function checkClaudeMd(setup, projectDir) {
|
|
89174
89371
|
const results = [];
|
|
89175
89372
|
if (setup.global.path) {
|
|
89176
|
-
const globalClaudeMd =
|
|
89373
|
+
const globalClaudeMd = join74(setup.global.path, "CLAUDE.md");
|
|
89177
89374
|
results.push(checkClaudeMdFile(globalClaudeMd, "Global CLAUDE.md", "ck-global-claude-md"));
|
|
89178
89375
|
}
|
|
89179
|
-
const projectClaudeMd =
|
|
89376
|
+
const projectClaudeMd = join74(projectDir, ".claude", "CLAUDE.md");
|
|
89180
89377
|
results.push(checkClaudeMdFile(projectClaudeMd, "Project CLAUDE.md", "ck-project-claude-md"));
|
|
89181
89378
|
return results;
|
|
89182
89379
|
}
|
|
@@ -89234,10 +89431,10 @@ function checkClaudeMdFile(path7, name, id) {
|
|
|
89234
89431
|
}
|
|
89235
89432
|
}
|
|
89236
89433
|
// src/domains/health-checks/checkers/active-plan-checker.ts
|
|
89237
|
-
import { existsSync as existsSync53, readFileSync as
|
|
89238
|
-
import { join as
|
|
89434
|
+
import { existsSync as existsSync53, readFileSync as readFileSync19 } from "node:fs";
|
|
89435
|
+
import { join as join75 } from "node:path";
|
|
89239
89436
|
function checkActivePlan(projectDir) {
|
|
89240
|
-
const activePlanPath =
|
|
89437
|
+
const activePlanPath = join75(projectDir, ".claude", "active-plan");
|
|
89241
89438
|
if (!existsSync53(activePlanPath)) {
|
|
89242
89439
|
return {
|
|
89243
89440
|
id: "ck-active-plan",
|
|
@@ -89250,8 +89447,8 @@ function checkActivePlan(projectDir) {
|
|
|
89250
89447
|
};
|
|
89251
89448
|
}
|
|
89252
89449
|
try {
|
|
89253
|
-
const targetPath =
|
|
89254
|
-
const fullPath =
|
|
89450
|
+
const targetPath = readFileSync19(activePlanPath, "utf-8").trim();
|
|
89451
|
+
const fullPath = join75(projectDir, targetPath);
|
|
89255
89452
|
if (!existsSync53(fullPath)) {
|
|
89256
89453
|
return {
|
|
89257
89454
|
id: "ck-active-plan",
|
|
@@ -89289,13 +89486,13 @@ function checkActivePlan(projectDir) {
|
|
|
89289
89486
|
}
|
|
89290
89487
|
// src/domains/health-checks/checkers/skills-checker.ts
|
|
89291
89488
|
import { existsSync as existsSync54 } from "node:fs";
|
|
89292
|
-
import { join as
|
|
89489
|
+
import { join as join76 } from "node:path";
|
|
89293
89490
|
function checkSkillsScripts(setup) {
|
|
89294
89491
|
const results = [];
|
|
89295
89492
|
const platform8 = process.platform;
|
|
89296
89493
|
const scriptName = platform8 === "win32" ? "install.ps1" : "install.sh";
|
|
89297
89494
|
if (setup.global.path) {
|
|
89298
|
-
const globalScriptPath =
|
|
89495
|
+
const globalScriptPath = join76(setup.global.path, "skills", scriptName);
|
|
89299
89496
|
const hasGlobalScript = existsSync54(globalScriptPath);
|
|
89300
89497
|
results.push({
|
|
89301
89498
|
id: "ck-global-skills-script",
|
|
@@ -89310,7 +89507,7 @@ function checkSkillsScripts(setup) {
|
|
|
89310
89507
|
});
|
|
89311
89508
|
}
|
|
89312
89509
|
if (setup.project.metadata) {
|
|
89313
|
-
const projectScriptPath =
|
|
89510
|
+
const projectScriptPath = join76(setup.project.path, "skills", scriptName);
|
|
89314
89511
|
const hasProjectScript = existsSync54(projectScriptPath);
|
|
89315
89512
|
results.push({
|
|
89316
89513
|
id: "ck-project-skills-script",
|
|
@@ -89347,13 +89544,13 @@ function checkComponentCounts(setup) {
|
|
|
89347
89544
|
}
|
|
89348
89545
|
// src/domains/health-checks/checkers/skill-budget-checker.ts
|
|
89349
89546
|
init_path_resolver();
|
|
89350
|
-
import { join as
|
|
89547
|
+
import { join as join78, resolve as resolve37 } from "node:path";
|
|
89351
89548
|
|
|
89352
89549
|
// src/domains/health-checks/checkers/skill-budget-scanner.ts
|
|
89353
89550
|
var import_gray_matter11 = __toESM(require_gray_matter(), 1);
|
|
89354
89551
|
import { existsSync as existsSync55 } from "node:fs";
|
|
89355
89552
|
import { readFile as readFile41, readdir as readdir20 } from "node:fs/promises";
|
|
89356
|
-
import { basename as basename25, join as
|
|
89553
|
+
import { basename as basename25, join as join77, relative as relative17 } from "node:path";
|
|
89357
89554
|
var SKIP_DIRS5 = new Set([".git", ".venv", "__pycache__", "node_modules", "scripts", "common"]);
|
|
89358
89555
|
async function scanSkills2(skillsDir2) {
|
|
89359
89556
|
if (!existsSync55(skillsDir2))
|
|
@@ -89361,7 +89558,7 @@ async function scanSkills2(skillsDir2) {
|
|
|
89361
89558
|
const skillDirs = await findSkillDirs(skillsDir2);
|
|
89362
89559
|
const skills = [];
|
|
89363
89560
|
for (const dir of skillDirs) {
|
|
89364
|
-
const file =
|
|
89561
|
+
const file = join77(dir, "SKILL.md");
|
|
89365
89562
|
try {
|
|
89366
89563
|
const content = await readFile41(file, "utf8");
|
|
89367
89564
|
const { data } = import_gray_matter11.default(content, { engines: { javascript: { parse: () => ({}) } } });
|
|
@@ -89387,8 +89584,8 @@ async function findSkillDirs(dir) {
|
|
|
89387
89584
|
}
|
|
89388
89585
|
const results = [];
|
|
89389
89586
|
for (const entry of entries) {
|
|
89390
|
-
const child =
|
|
89391
|
-
if (existsSync55(
|
|
89587
|
+
const child = join77(dir, entry.name);
|
|
89588
|
+
if (existsSync55(join77(child, "SKILL.md"))) {
|
|
89392
89589
|
results.push(child);
|
|
89393
89590
|
continue;
|
|
89394
89591
|
}
|
|
@@ -89470,12 +89667,12 @@ async function checkSkillBudget(setup, projectDir) {
|
|
|
89470
89667
|
const globalClaudeDir = resolve37(PathResolver.getGlobalKitDir());
|
|
89471
89668
|
const projectScopeAliasesGlobal = projectClaudeDir === globalClaudeDir;
|
|
89472
89669
|
const [projectSkills, globalSkills] = await Promise.all([
|
|
89473
|
-
projectScopeAliasesGlobal ? Promise.resolve([]) : scanSkills2(
|
|
89474
|
-
scanSkills2(
|
|
89670
|
+
projectScopeAliasesGlobal ? Promise.resolve([]) : scanSkills2(join78(projectClaudeDir, "skills")),
|
|
89671
|
+
scanSkills2(join78(globalClaudeDir, "skills"))
|
|
89475
89672
|
]);
|
|
89476
89673
|
if (!isEngineerLikeProject(setup, [...projectSkills, ...globalSkills]))
|
|
89477
89674
|
return [];
|
|
89478
|
-
const settingsPath =
|
|
89675
|
+
const settingsPath = join78(projectClaudeDir, "settings.json");
|
|
89479
89676
|
const settings = await readProjectSettings(settingsPath);
|
|
89480
89677
|
const activeSkills = [...projectSkills, ...globalSkills];
|
|
89481
89678
|
const listingSkills = uniqueSkills(activeSkills);
|
|
@@ -89633,7 +89830,7 @@ init_logger();
|
|
|
89633
89830
|
init_path_resolver();
|
|
89634
89831
|
init_shared2();
|
|
89635
89832
|
import { constants as constants2, access as access3, unlink as unlink10, writeFile as writeFile22 } from "node:fs/promises";
|
|
89636
|
-
import { join as
|
|
89833
|
+
import { join as join79 } from "node:path";
|
|
89637
89834
|
async function checkGlobalDirReadable() {
|
|
89638
89835
|
const globalDir = PathResolver.getGlobalKitDir();
|
|
89639
89836
|
if (shouldSkipExpensiveOperations2()) {
|
|
@@ -89690,7 +89887,7 @@ async function checkGlobalDirWritable() {
|
|
|
89690
89887
|
}
|
|
89691
89888
|
const timestamp = Date.now();
|
|
89692
89889
|
const random = Math.random().toString(36).substring(2);
|
|
89693
|
-
const testFile =
|
|
89890
|
+
const testFile = join79(globalDir, `.ck-write-test-${timestamp}-${random}`);
|
|
89694
89891
|
try {
|
|
89695
89892
|
await writeFile22(testFile, "test", { encoding: "utf-8", flag: "wx" });
|
|
89696
89893
|
} catch (error) {
|
|
@@ -89726,7 +89923,7 @@ async function checkGlobalDirWritable() {
|
|
|
89726
89923
|
init_path_resolver();
|
|
89727
89924
|
import { existsSync as existsSync57 } from "node:fs";
|
|
89728
89925
|
import { readdir as readdir21 } from "node:fs/promises";
|
|
89729
|
-
import { join as
|
|
89926
|
+
import { join as join80 } from "node:path";
|
|
89730
89927
|
|
|
89731
89928
|
// src/domains/health-checks/utils/path-normalizer.ts
|
|
89732
89929
|
import { normalize as normalize5 } from "node:path";
|
|
@@ -89739,8 +89936,8 @@ function normalizePath2(filePath) {
|
|
|
89739
89936
|
// src/domains/health-checks/checkers/hooks-checker.ts
|
|
89740
89937
|
init_shared2();
|
|
89741
89938
|
async function checkHooksExist(projectDir) {
|
|
89742
|
-
const globalHooksDir =
|
|
89743
|
-
const projectHooksDir =
|
|
89939
|
+
const globalHooksDir = join80(PathResolver.getGlobalKitDir(), "hooks");
|
|
89940
|
+
const projectHooksDir = join80(projectDir, ".claude", "hooks");
|
|
89744
89941
|
const globalExists = existsSync57(globalHooksDir);
|
|
89745
89942
|
const projectExists = existsSync57(projectHooksDir);
|
|
89746
89943
|
let hookCount = 0;
|
|
@@ -89749,7 +89946,7 @@ async function checkHooksExist(projectDir) {
|
|
|
89749
89946
|
const files = await readdir21(globalHooksDir, { withFileTypes: false });
|
|
89750
89947
|
const hooks = files.filter((f3) => HOOK_EXTENSIONS2.some((ext) => f3.endsWith(ext)));
|
|
89751
89948
|
hooks.forEach((hook) => {
|
|
89752
|
-
const fullPath =
|
|
89949
|
+
const fullPath = join80(globalHooksDir, hook);
|
|
89753
89950
|
checkedFiles.add(normalizePath2(fullPath));
|
|
89754
89951
|
});
|
|
89755
89952
|
}
|
|
@@ -89759,7 +89956,7 @@ async function checkHooksExist(projectDir) {
|
|
|
89759
89956
|
const files = await readdir21(projectHooksDir, { withFileTypes: false });
|
|
89760
89957
|
const hooks = files.filter((f3) => HOOK_EXTENSIONS2.some((ext) => f3.endsWith(ext)));
|
|
89761
89958
|
hooks.forEach((hook) => {
|
|
89762
|
-
const fullPath =
|
|
89959
|
+
const fullPath = join80(projectHooksDir, hook);
|
|
89763
89960
|
checkedFiles.add(normalizePath2(fullPath));
|
|
89764
89961
|
});
|
|
89765
89962
|
}
|
|
@@ -89791,10 +89988,10 @@ init_logger();
|
|
|
89791
89988
|
init_path_resolver();
|
|
89792
89989
|
import { existsSync as existsSync58 } from "node:fs";
|
|
89793
89990
|
import { readFile as readFile43 } from "node:fs/promises";
|
|
89794
|
-
import { join as
|
|
89991
|
+
import { join as join81 } from "node:path";
|
|
89795
89992
|
async function checkSettingsValid(projectDir) {
|
|
89796
|
-
const globalSettings =
|
|
89797
|
-
const projectSettings =
|
|
89993
|
+
const globalSettings = join81(PathResolver.getGlobalKitDir(), "settings.json");
|
|
89994
|
+
const projectSettings = join81(projectDir, ".claude", "settings.json");
|
|
89798
89995
|
const settingsPath = existsSync58(globalSettings) ? globalSettings : existsSync58(projectSettings) ? projectSettings : null;
|
|
89799
89996
|
if (!settingsPath) {
|
|
89800
89997
|
return {
|
|
@@ -89867,10 +90064,10 @@ init_path_resolver();
|
|
|
89867
90064
|
import { existsSync as existsSync59 } from "node:fs";
|
|
89868
90065
|
import { readFile as readFile44 } from "node:fs/promises";
|
|
89869
90066
|
import { homedir as homedir43 } from "node:os";
|
|
89870
|
-
import { dirname as dirname32, join as
|
|
90067
|
+
import { dirname as dirname32, join as join82, normalize as normalize6, resolve as resolve38 } from "node:path";
|
|
89871
90068
|
async function checkPathRefsValid(projectDir) {
|
|
89872
|
-
const globalClaudeMd =
|
|
89873
|
-
const projectClaudeMd =
|
|
90069
|
+
const globalClaudeMd = join82(PathResolver.getGlobalKitDir(), "CLAUDE.md");
|
|
90070
|
+
const projectClaudeMd = join82(projectDir, ".claude", "CLAUDE.md");
|
|
89874
90071
|
const claudeMdPath = existsSync59(globalClaudeMd) ? globalClaudeMd : existsSync59(projectClaudeMd) ? projectClaudeMd : null;
|
|
89875
90072
|
if (!claudeMdPath) {
|
|
89876
90073
|
return {
|
|
@@ -89965,7 +90162,7 @@ async function checkPathRefsValid(projectDir) {
|
|
|
89965
90162
|
// src/domains/health-checks/checkers/config-completeness-checker.ts
|
|
89966
90163
|
import { existsSync as existsSync60 } from "node:fs";
|
|
89967
90164
|
import { readdir as readdir22 } from "node:fs/promises";
|
|
89968
|
-
import { join as
|
|
90165
|
+
import { join as join83 } from "node:path";
|
|
89969
90166
|
async function checkProjectConfigCompleteness(setup, projectDir) {
|
|
89970
90167
|
const baseResult = {
|
|
89971
90168
|
id: "ck-project-config-complete",
|
|
@@ -89999,15 +90196,15 @@ async function checkProjectConfigCompleteness(setup, projectDir) {
|
|
|
89999
90196
|
suggestion: "Run 'ck init' (choose global or project scope when prompted)"
|
|
90000
90197
|
};
|
|
90001
90198
|
}
|
|
90002
|
-
const projectClaudeDir =
|
|
90199
|
+
const projectClaudeDir = join83(projectDir, ".claude");
|
|
90003
90200
|
const requiredDirs = ["agents", "commands", "skills"];
|
|
90004
90201
|
const missingDirs = [];
|
|
90005
90202
|
for (const dir of requiredDirs) {
|
|
90006
|
-
if (!existsSync60(
|
|
90203
|
+
if (!existsSync60(join83(projectClaudeDir, dir))) {
|
|
90007
90204
|
missingDirs.push(dir);
|
|
90008
90205
|
}
|
|
90009
90206
|
}
|
|
90010
|
-
const hasRulesOrWorkflows = existsSync60(
|
|
90207
|
+
const hasRulesOrWorkflows = existsSync60(join83(projectClaudeDir, "rules")) || existsSync60(join83(projectClaudeDir, "workflows"));
|
|
90011
90208
|
if (!hasRulesOrWorkflows) {
|
|
90012
90209
|
missingDirs.push("rules");
|
|
90013
90210
|
}
|
|
@@ -90040,7 +90237,7 @@ async function checkProjectConfigCompleteness(setup, projectDir) {
|
|
|
90040
90237
|
};
|
|
90041
90238
|
}
|
|
90042
90239
|
// src/domains/health-checks/checkers/env-keys-checker.ts
|
|
90043
|
-
import { join as
|
|
90240
|
+
import { join as join85 } from "node:path";
|
|
90044
90241
|
|
|
90045
90242
|
// src/domains/installation/setup-wizard.ts
|
|
90046
90243
|
init_config_generator();
|
|
@@ -90049,7 +90246,7 @@ init_logger();
|
|
|
90049
90246
|
init_path_resolver();
|
|
90050
90247
|
init_dist2();
|
|
90051
90248
|
var import_fs_extra9 = __toESM(require_lib(), 1);
|
|
90052
|
-
import { join as
|
|
90249
|
+
import { join as join84 } from "node:path";
|
|
90053
90250
|
var IMAGE_PROVIDER_ENV_KEYS = [
|
|
90054
90251
|
"GEMINI_API_KEY",
|
|
90055
90252
|
"OPENROUTER_API_KEY",
|
|
@@ -90222,7 +90419,7 @@ function normalizeParsedEnvValue(key, value) {
|
|
|
90222
90419
|
return trimmed;
|
|
90223
90420
|
}
|
|
90224
90421
|
async function checkGlobalConfig() {
|
|
90225
|
-
const globalEnvPath =
|
|
90422
|
+
const globalEnvPath = join84(PathResolver.getGlobalKitDir(), ".env");
|
|
90226
90423
|
if (!await import_fs_extra9.pathExists(globalEnvPath))
|
|
90227
90424
|
return false;
|
|
90228
90425
|
const env2 = await parseEnvFile(globalEnvPath);
|
|
@@ -90238,7 +90435,7 @@ async function runSetupWizard(options2) {
|
|
|
90238
90435
|
let globalEnv = {};
|
|
90239
90436
|
const hasGlobalConfig = !isGlobal && await checkGlobalConfig();
|
|
90240
90437
|
if (!isGlobal) {
|
|
90241
|
-
const globalEnvPath =
|
|
90438
|
+
const globalEnvPath = join84(PathResolver.getGlobalKitDir(), ".env");
|
|
90242
90439
|
if (await import_fs_extra9.pathExists(globalEnvPath)) {
|
|
90243
90440
|
globalEnv = await parseEnvFile(globalEnvPath);
|
|
90244
90441
|
}
|
|
@@ -90338,7 +90535,7 @@ async function runSetupWizard(options2) {
|
|
|
90338
90535
|
f2.info(`Set IMAGE_GEN_PROVIDER=${selectedProvider}`);
|
|
90339
90536
|
}
|
|
90340
90537
|
await generateEnvFile(targetDir, values);
|
|
90341
|
-
f2.success(`Configuration saved to ${
|
|
90538
|
+
f2.success(`Configuration saved to ${join84(targetDir, ".env")}`);
|
|
90342
90539
|
return true;
|
|
90343
90540
|
}
|
|
90344
90541
|
async function promptForAdditionalGeminiKeys(primaryKey) {
|
|
@@ -90433,7 +90630,7 @@ function formatConfiguredProviderMessage(providers2) {
|
|
|
90433
90630
|
async function checkEnvKeys(setup) {
|
|
90434
90631
|
const results = [];
|
|
90435
90632
|
if (setup.global.path) {
|
|
90436
|
-
const globalEnvPath =
|
|
90633
|
+
const globalEnvPath = join85(setup.global.path, ".env");
|
|
90437
90634
|
const globalCheck = await checkRequiredKeysExist(globalEnvPath);
|
|
90438
90635
|
if (!globalCheck.allPresent) {
|
|
90439
90636
|
const missingKeys = globalCheck.missing.map((m2) => m2.label).join(", ");
|
|
@@ -90462,7 +90659,7 @@ async function checkEnvKeys(setup) {
|
|
|
90462
90659
|
}
|
|
90463
90660
|
}
|
|
90464
90661
|
if (setup.project.metadata) {
|
|
90465
|
-
const projectEnvPath =
|
|
90662
|
+
const projectEnvPath = join85(setup.project.path, ".env");
|
|
90466
90663
|
const projectCheck = await checkRequiredKeysExist(projectEnvPath);
|
|
90467
90664
|
if (!projectCheck.allPresent) {
|
|
90468
90665
|
const missingKeys = projectCheck.missing.map((m2) => m2.label).join(", ");
|
|
@@ -90566,28 +90763,40 @@ class ClaudekitChecker {
|
|
|
90566
90763
|
}
|
|
90567
90764
|
}
|
|
90568
90765
|
// src/domains/health-checks/plugin-install-mode-checker.ts
|
|
90766
|
+
init_codex_plugin_installer();
|
|
90569
90767
|
init_install_mode_detector();
|
|
90768
|
+
init_install_mode_preference();
|
|
90769
|
+
init_path_resolver();
|
|
90770
|
+
import { readFileSync as readFileSync20 } from "node:fs";
|
|
90771
|
+
import { join as join86 } from "node:path";
|
|
90570
90772
|
|
|
90571
90773
|
class PluginInstallModeChecker {
|
|
90572
90774
|
claudeDir;
|
|
90775
|
+
deps;
|
|
90573
90776
|
group = "claudekit";
|
|
90574
|
-
constructor(claudeDir3) {
|
|
90777
|
+
constructor(claudeDir3, deps = {}) {
|
|
90575
90778
|
this.claudeDir = claudeDir3;
|
|
90779
|
+
this.deps = deps;
|
|
90576
90780
|
}
|
|
90577
90781
|
async run() {
|
|
90578
90782
|
const r2 = detectInstallMode(this.claudeDir);
|
|
90783
|
+
const readPreference = this.deps.readInstallModePreference ?? readInstallModePreferenceFromClaudeDir;
|
|
90784
|
+
const preference = readPreference(r2.claudeDir) ?? DEFAULT_INSTALL_MODE_PREFERENCE;
|
|
90785
|
+
const codexState = await this.readCodexState(expectedCodexPluginOptions(r2.claudeDir));
|
|
90579
90786
|
const detail = [];
|
|
90787
|
+
detail.push(`preference: ${preference}`);
|
|
90580
90788
|
if (r2.plugin.installed) {
|
|
90581
90789
|
const bits = [r2.plugin.enabled ? "enabled" : "disabled"];
|
|
90582
90790
|
if (r2.plugin.version)
|
|
90583
90791
|
bits.push(r2.plugin.version);
|
|
90584
90792
|
if (r2.plugin.marketplace)
|
|
90585
90793
|
bits.push(`via ${r2.plugin.marketplace}`);
|
|
90586
|
-
detail.push(`plugin: ${bits.join(", ")}`);
|
|
90794
|
+
detail.push(`Claude plugin: ${bits.join(", ")}`);
|
|
90587
90795
|
}
|
|
90588
90796
|
if (r2.legacy.installed) {
|
|
90589
90797
|
detail.push(`legacy copy${r2.legacy.version ? ` (${r2.legacy.version})` : ""}`);
|
|
90590
90798
|
}
|
|
90799
|
+
detail.push(formatCodexDetail(codexState));
|
|
90591
90800
|
const suffix = detail.length > 0 ? ` — ${detail.join("; ")}` : "";
|
|
90592
90801
|
let status = "pass";
|
|
90593
90802
|
let message = `Install mode: ${r2.mode}${suffix}`;
|
|
@@ -90597,9 +90806,18 @@ class PluginInstallModeChecker {
|
|
|
90597
90806
|
} else if (r2.mode === "plugin" && !r2.plugin.enabled) {
|
|
90598
90807
|
status = "warn";
|
|
90599
90808
|
message = `Install mode: plugin, but the plugin is disabled. Run \`claude plugin enable ck\`.${suffix}`;
|
|
90809
|
+
} else if (preference === "legacy" && (r2.plugin.installed || r2.plugin.staleCache || codexState.installed)) {
|
|
90810
|
+
status = "warn";
|
|
90811
|
+
message = `Install mode: ${r2.mode}, but preference is legacy. Run \`ck init -g --kit engineer --install-mode legacy\`.${suffix}`;
|
|
90812
|
+
} else if (preference === "plugin" && (r2.mode === "legacy" || r2.mode === "fresh" || !r2.plugin.enabled)) {
|
|
90813
|
+
status = "warn";
|
|
90814
|
+
message = `Install mode: ${r2.mode}, but preference is plugin. Run \`ck init -g --kit engineer --install-mode plugin\`.${suffix}`;
|
|
90815
|
+
} else if (codexState.shouldRefresh && preference !== "legacy") {
|
|
90816
|
+
status = "warn";
|
|
90817
|
+
message = `Install mode: ${r2.mode}; Codex plugin requires refresh. Run \`ck update\`.${suffix}`;
|
|
90600
90818
|
} else if (r2.mode === "fresh") {
|
|
90601
90819
|
status = "info";
|
|
90602
|
-
message =
|
|
90820
|
+
message = `Install mode: fresh (ClaudeKit Engineer not installed). Run \`ck init\` to install.${suffix}`;
|
|
90603
90821
|
}
|
|
90604
90822
|
return [
|
|
90605
90823
|
{
|
|
@@ -90612,6 +90830,62 @@ class PluginInstallModeChecker {
|
|
|
90612
90830
|
}
|
|
90613
90831
|
];
|
|
90614
90832
|
}
|
|
90833
|
+
async readCodexState(options2) {
|
|
90834
|
+
try {
|
|
90835
|
+
if (this.deps.detectCodexPluginState)
|
|
90836
|
+
return await this.deps.detectCodexPluginState(options2);
|
|
90837
|
+
return await detectCodexPluginState(undefined, options2);
|
|
90838
|
+
} catch (error) {
|
|
90839
|
+
return {
|
|
90840
|
+
status: "unknown",
|
|
90841
|
+
pluginId: "ck@claudekit",
|
|
90842
|
+
enabled: false,
|
|
90843
|
+
installed: false,
|
|
90844
|
+
installedVersion: null,
|
|
90845
|
+
expectedVersion: options2.expectedVersion ?? null,
|
|
90846
|
+
marketplace: null,
|
|
90847
|
+
expectedMarketplace: options2.expectedMarketplace ?? "claudekit",
|
|
90848
|
+
source: null,
|
|
90849
|
+
expectedSource: options2.expectedSource ?? null,
|
|
90850
|
+
shouldRefresh: false,
|
|
90851
|
+
error: error instanceof Error ? error.message : "unknown"
|
|
90852
|
+
};
|
|
90853
|
+
}
|
|
90854
|
+
}
|
|
90855
|
+
}
|
|
90856
|
+
function formatCodexDetail(state) {
|
|
90857
|
+
const bits = [state.status];
|
|
90858
|
+
if (state.installedVersion)
|
|
90859
|
+
bits.push(state.installedVersion);
|
|
90860
|
+
if (state.marketplace)
|
|
90861
|
+
bits.push(`via ${state.marketplace}`);
|
|
90862
|
+
if (state.source)
|
|
90863
|
+
bits.push(`source ${state.source}`);
|
|
90864
|
+
if (state.error)
|
|
90865
|
+
bits.push(state.error);
|
|
90866
|
+
return `Codex plugin: ${bits.join(", ")}`;
|
|
90867
|
+
}
|
|
90868
|
+
function expectedCodexPluginOptions(claudeDir3) {
|
|
90869
|
+
return {
|
|
90870
|
+
expectedVersion: readEngineerKitVersion(claudeDir3),
|
|
90871
|
+
expectedMarketplace: "claudekit",
|
|
90872
|
+
expectedSource: join86(PathResolver.getCacheDir(true), "ck-plugin-source")
|
|
90873
|
+
};
|
|
90874
|
+
}
|
|
90875
|
+
function readEngineerKitVersion(claudeDir3) {
|
|
90876
|
+
try {
|
|
90877
|
+
const parsed = JSON.parse(readFileSync20(join86(claudeDir3, "metadata.json"), "utf-8"));
|
|
90878
|
+
if (!isRecord4(parsed) || !isRecord4(parsed.kits) || !isRecord4(parsed.kits.engineer)) {
|
|
90879
|
+
return null;
|
|
90880
|
+
}
|
|
90881
|
+
const version = parsed.kits.engineer.version;
|
|
90882
|
+
return typeof version === "string" && version.trim() !== "" ? version : null;
|
|
90883
|
+
} catch {
|
|
90884
|
+
return null;
|
|
90885
|
+
}
|
|
90886
|
+
}
|
|
90887
|
+
function isRecord4(value) {
|
|
90888
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
90615
90889
|
}
|
|
90616
90890
|
// src/domains/health-checks/auth-checker.ts
|
|
90617
90891
|
init_github_auth();
|
|
@@ -90962,7 +91236,7 @@ init_environment();
|
|
|
90962
91236
|
init_path_resolver();
|
|
90963
91237
|
import { constants as constants3, access as access4, mkdir as mkdir21, readFile as readFile46, unlink as unlink11, writeFile as writeFile23 } from "node:fs/promises";
|
|
90964
91238
|
import { arch as arch2, homedir as homedir44, platform as platform8 } from "node:os";
|
|
90965
|
-
import { join as
|
|
91239
|
+
import { join as join88, normalize as normalize7 } from "node:path";
|
|
90966
91240
|
function shouldSkipExpensiveOperations4() {
|
|
90967
91241
|
return shouldSkipExpensiveOperations();
|
|
90968
91242
|
}
|
|
@@ -91053,7 +91327,7 @@ async function checkGlobalDirAccess() {
|
|
|
91053
91327
|
autoFixable: false
|
|
91054
91328
|
};
|
|
91055
91329
|
}
|
|
91056
|
-
const testFile =
|
|
91330
|
+
const testFile = join88(globalDir, ".ck-doctor-access-test");
|
|
91057
91331
|
try {
|
|
91058
91332
|
await mkdir21(globalDir, { recursive: true });
|
|
91059
91333
|
await writeFile23(testFile, "test", "utf-8");
|
|
@@ -91131,7 +91405,7 @@ async function checkWSLBoundary() {
|
|
|
91131
91405
|
// src/domains/health-checks/platform/windows-checker.ts
|
|
91132
91406
|
init_path_resolver();
|
|
91133
91407
|
import { mkdir as mkdir22, symlink as symlink2, unlink as unlink12, writeFile as writeFile24 } from "node:fs/promises";
|
|
91134
|
-
import { join as
|
|
91408
|
+
import { join as join89 } from "node:path";
|
|
91135
91409
|
async function checkLongPathSupport() {
|
|
91136
91410
|
if (shouldSkipExpensiveOperations4()) {
|
|
91137
91411
|
return {
|
|
@@ -91183,8 +91457,8 @@ async function checkSymlinkSupport() {
|
|
|
91183
91457
|
};
|
|
91184
91458
|
}
|
|
91185
91459
|
const testDir = PathResolver.getGlobalKitDir();
|
|
91186
|
-
const target =
|
|
91187
|
-
const link =
|
|
91460
|
+
const target = join89(testDir, ".ck-symlink-test-target");
|
|
91461
|
+
const link = join89(testDir, ".ck-symlink-test-link");
|
|
91188
91462
|
try {
|
|
91189
91463
|
await mkdir22(testDir, { recursive: true });
|
|
91190
91464
|
await writeFile24(target, "test", "utf-8");
|
|
@@ -91801,9 +92075,9 @@ class AutoHealer {
|
|
|
91801
92075
|
}
|
|
91802
92076
|
// src/domains/health-checks/report-generator.ts
|
|
91803
92077
|
import { execSync as execSync4, spawnSync as spawnSync6 } from "node:child_process";
|
|
91804
|
-
import { readFileSync as
|
|
92078
|
+
import { readFileSync as readFileSync21, unlinkSync as unlinkSync2, writeFileSync as writeFileSync6 } from "node:fs";
|
|
91805
92079
|
import { tmpdir as tmpdir3 } from "node:os";
|
|
91806
|
-
import { dirname as dirname33, join as
|
|
92080
|
+
import { dirname as dirname33, join as join90 } from "node:path";
|
|
91807
92081
|
import { fileURLToPath as fileURLToPath4 } from "node:url";
|
|
91808
92082
|
init_environment();
|
|
91809
92083
|
init_logger();
|
|
@@ -91811,8 +92085,8 @@ init_dist2();
|
|
|
91811
92085
|
function getCliVersion4() {
|
|
91812
92086
|
try {
|
|
91813
92087
|
const __dirname4 = dirname33(fileURLToPath4(import.meta.url));
|
|
91814
|
-
const pkgPath =
|
|
91815
|
-
const pkg = JSON.parse(
|
|
92088
|
+
const pkgPath = join90(__dirname4, "../../../package.json");
|
|
92089
|
+
const pkg = JSON.parse(readFileSync21(pkgPath, "utf-8"));
|
|
91816
92090
|
return pkg.version || "unknown";
|
|
91817
92091
|
} catch (err) {
|
|
91818
92092
|
logger.debug(`Failed to read CLI version: ${err}`);
|
|
@@ -91950,7 +92224,7 @@ class ReportGenerator {
|
|
|
91950
92224
|
return null;
|
|
91951
92225
|
}
|
|
91952
92226
|
}
|
|
91953
|
-
const tmpFile =
|
|
92227
|
+
const tmpFile = join90(tmpdir3(), `ck-report-${Date.now()}.txt`);
|
|
91954
92228
|
writeFileSync6(tmpFile, report);
|
|
91955
92229
|
try {
|
|
91956
92230
|
const result = spawnSync6("gh", ["gist", "create", tmpFile, "--desc", "ClaudeKit Diagnostic Report"], {
|
|
@@ -92292,7 +92566,7 @@ init_config_version_checker();
|
|
|
92292
92566
|
|
|
92293
92567
|
// src/domains/sync/sync-engine.ts
|
|
92294
92568
|
import { lstat as lstat6, readFile as readFile48, readlink as readlink2, realpath as realpath8, stat as stat14 } from "node:fs/promises";
|
|
92295
|
-
import { isAbsolute as isAbsolute12, join as
|
|
92569
|
+
import { isAbsolute as isAbsolute12, join as join91, normalize as normalize8, relative as relative19 } from "node:path";
|
|
92296
92570
|
|
|
92297
92571
|
// src/services/file-operations/ownership-checker.ts
|
|
92298
92572
|
init_metadata_migration();
|
|
@@ -93507,7 +93781,7 @@ async function validateSymlinkChain(path8, basePath, maxDepth = MAX_SYMLINK_DEPT
|
|
|
93507
93781
|
if (!stats.isSymbolicLink())
|
|
93508
93782
|
break;
|
|
93509
93783
|
const target = await readlink2(current);
|
|
93510
|
-
const resolvedTarget = isAbsolute12(target) ? target :
|
|
93784
|
+
const resolvedTarget = isAbsolute12(target) ? target : join91(current, "..", target);
|
|
93511
93785
|
const normalizedTarget = normalize8(resolvedTarget);
|
|
93512
93786
|
const rel = relative19(basePath, normalizedTarget);
|
|
93513
93787
|
if (rel.startsWith("..") || isAbsolute12(rel)) {
|
|
@@ -93543,7 +93817,7 @@ async function validateSyncPath(basePath, filePath) {
|
|
|
93543
93817
|
if (normalized.startsWith("..") || normalized.includes("/../")) {
|
|
93544
93818
|
throw new Error(`Path traversal not allowed: ${filePath}`);
|
|
93545
93819
|
}
|
|
93546
|
-
const fullPath =
|
|
93820
|
+
const fullPath = join91(basePath, normalized);
|
|
93547
93821
|
const rel = relative19(basePath, fullPath);
|
|
93548
93822
|
if (rel.startsWith("..") || isAbsolute12(rel)) {
|
|
93549
93823
|
throw new Error(`Path escapes base directory: ${filePath}`);
|
|
@@ -93558,7 +93832,7 @@ async function validateSyncPath(basePath, filePath) {
|
|
|
93558
93832
|
}
|
|
93559
93833
|
} catch (error) {
|
|
93560
93834
|
if (error.code === "ENOENT") {
|
|
93561
|
-
const parentPath =
|
|
93835
|
+
const parentPath = join91(fullPath, "..");
|
|
93562
93836
|
try {
|
|
93563
93837
|
const resolvedBase = await realpath8(basePath);
|
|
93564
93838
|
const resolvedParent = await realpath8(parentPath);
|
|
@@ -94467,7 +94741,7 @@ async function getLatestVersion(kit, includePrereleases = false) {
|
|
|
94467
94741
|
init_logger();
|
|
94468
94742
|
init_path_resolver();
|
|
94469
94743
|
init_safe_prompts();
|
|
94470
|
-
import { join as
|
|
94744
|
+
import { join as join99 } from "node:path";
|
|
94471
94745
|
async function promptUpdateMode() {
|
|
94472
94746
|
const updateEverything = await se({
|
|
94473
94747
|
message: "Do you want to update everything?"
|
|
@@ -94509,7 +94783,7 @@ async function promptDirectorySelection(global3 = false) {
|
|
|
94509
94783
|
return selectedCategories;
|
|
94510
94784
|
}
|
|
94511
94785
|
async function promptFreshConfirmation(targetPath, analysis) {
|
|
94512
|
-
const backupRoot =
|
|
94786
|
+
const backupRoot = join99(PathResolver.getConfigDir(false), "backups");
|
|
94513
94787
|
logger.warning("[!] Fresh installation will remove ClaudeKit files:");
|
|
94514
94788
|
logger.info(`Path: ${targetPath}`);
|
|
94515
94789
|
logger.info(`Recovery backup: ${backupRoot}`);
|
|
@@ -94786,7 +95060,7 @@ init_logger();
|
|
|
94786
95060
|
init_logger();
|
|
94787
95061
|
init_path_resolver();
|
|
94788
95062
|
var import_fs_extra10 = __toESM(require_lib(), 1);
|
|
94789
|
-
import { join as
|
|
95063
|
+
import { join as join100 } from "node:path";
|
|
94790
95064
|
async function handleConflicts(ctx) {
|
|
94791
95065
|
if (ctx.cancelled)
|
|
94792
95066
|
return ctx;
|
|
@@ -94795,7 +95069,7 @@ async function handleConflicts(ctx) {
|
|
|
94795
95069
|
if (PathResolver.isLocalSameAsGlobal()) {
|
|
94796
95070
|
return ctx;
|
|
94797
95071
|
}
|
|
94798
|
-
const localSettingsPath =
|
|
95072
|
+
const localSettingsPath = join100(process.cwd(), ".claude", "settings.json");
|
|
94799
95073
|
if (!await import_fs_extra10.pathExists(localSettingsPath)) {
|
|
94800
95074
|
return ctx;
|
|
94801
95075
|
}
|
|
@@ -94810,7 +95084,7 @@ async function handleConflicts(ctx) {
|
|
|
94810
95084
|
return { ...ctx, cancelled: true };
|
|
94811
95085
|
}
|
|
94812
95086
|
if (choice === "remove") {
|
|
94813
|
-
const localClaudeDir =
|
|
95087
|
+
const localClaudeDir = join100(process.cwd(), ".claude");
|
|
94814
95088
|
try {
|
|
94815
95089
|
await import_fs_extra10.remove(localClaudeDir);
|
|
94816
95090
|
logger.success("Removed local .claude/ directory");
|
|
@@ -94907,7 +95181,7 @@ init_logger();
|
|
|
94907
95181
|
init_safe_spinner();
|
|
94908
95182
|
import { mkdir as mkdir30, stat as stat17 } from "node:fs/promises";
|
|
94909
95183
|
import { tmpdir as tmpdir4 } from "node:os";
|
|
94910
|
-
import { join as
|
|
95184
|
+
import { join as join107 } from "node:path";
|
|
94911
95185
|
|
|
94912
95186
|
// src/shared/temp-cleanup.ts
|
|
94913
95187
|
init_logger();
|
|
@@ -94926,7 +95200,7 @@ init_logger();
|
|
|
94926
95200
|
init_output_manager();
|
|
94927
95201
|
import { createWriteStream as createWriteStream2, rmSync } from "node:fs";
|
|
94928
95202
|
import { mkdir as mkdir25 } from "node:fs/promises";
|
|
94929
|
-
import { join as
|
|
95203
|
+
import { join as join101 } from "node:path";
|
|
94930
95204
|
|
|
94931
95205
|
// src/shared/progress-bar.ts
|
|
94932
95206
|
init_output_manager();
|
|
@@ -95136,7 +95410,7 @@ var MAX_DOWNLOAD_SIZE = 500 * 1024 * 1024;
|
|
|
95136
95410
|
class FileDownloader {
|
|
95137
95411
|
async downloadAsset(asset, destDir) {
|
|
95138
95412
|
try {
|
|
95139
|
-
const destPath =
|
|
95413
|
+
const destPath = join101(destDir, asset.name);
|
|
95140
95414
|
await mkdir25(destDir, { recursive: true });
|
|
95141
95415
|
output.info(`Downloading ${asset.name} (${formatBytes2(asset.size)})...`);
|
|
95142
95416
|
logger.verbose("Download details", {
|
|
@@ -95221,7 +95495,7 @@ class FileDownloader {
|
|
|
95221
95495
|
}
|
|
95222
95496
|
async downloadFile(params) {
|
|
95223
95497
|
const { url, name, size, destDir, token } = params;
|
|
95224
|
-
const destPath =
|
|
95498
|
+
const destPath = join101(destDir, name);
|
|
95225
95499
|
await mkdir25(destDir, { recursive: true });
|
|
95226
95500
|
output.info(`Downloading ${name}${size ? ` (${formatBytes2(size)})` : ""}...`);
|
|
95227
95501
|
const headers = {};
|
|
@@ -95307,7 +95581,7 @@ init_logger();
|
|
|
95307
95581
|
init_types3();
|
|
95308
95582
|
import { constants as constants4 } from "node:fs";
|
|
95309
95583
|
import { access as access5, readdir as readdir23 } from "node:fs/promises";
|
|
95310
|
-
import { join as
|
|
95584
|
+
import { join as join102 } from "node:path";
|
|
95311
95585
|
async function pathExists11(path8) {
|
|
95312
95586
|
try {
|
|
95313
95587
|
await access5(path8, constants4.F_OK);
|
|
@@ -95326,7 +95600,7 @@ async function validateExtraction(extractDir) {
|
|
|
95326
95600
|
const criticalPaths = [".claude"];
|
|
95327
95601
|
const missingPaths = [];
|
|
95328
95602
|
for (const path8 of criticalPaths) {
|
|
95329
|
-
if (await pathExists11(
|
|
95603
|
+
if (await pathExists11(join102(extractDir, path8))) {
|
|
95330
95604
|
logger.debug(`Found: ${path8}`);
|
|
95331
95605
|
continue;
|
|
95332
95606
|
}
|
|
@@ -95336,7 +95610,7 @@ async function validateExtraction(extractDir) {
|
|
|
95336
95610
|
const guidancePaths = ["CLAUDE.md", ".claude/CLAUDE.md", ".claude/rules/CLAUDE.md"];
|
|
95337
95611
|
let guidancePath = null;
|
|
95338
95612
|
for (const path8 of guidancePaths) {
|
|
95339
|
-
if (await pathExists11(
|
|
95613
|
+
if (await pathExists11(join102(extractDir, path8))) {
|
|
95340
95614
|
guidancePath = path8;
|
|
95341
95615
|
break;
|
|
95342
95616
|
}
|
|
@@ -95361,7 +95635,7 @@ async function validateExtraction(extractDir) {
|
|
|
95361
95635
|
// src/domains/installation/extraction/tar-extractor.ts
|
|
95362
95636
|
init_logger();
|
|
95363
95637
|
import { copyFile as copyFile4, mkdir as mkdir28, readdir as readdir25, rm as rm11, stat as stat15 } from "node:fs/promises";
|
|
95364
|
-
import { join as
|
|
95638
|
+
import { join as join105 } from "node:path";
|
|
95365
95639
|
|
|
95366
95640
|
// node_modules/@isaacs/fs-minipass/dist/esm/index.js
|
|
95367
95641
|
import EE from "events";
|
|
@@ -101123,7 +101397,7 @@ var mkdirSync4 = (dir, opt) => {
|
|
|
101123
101397
|
};
|
|
101124
101398
|
|
|
101125
101399
|
// node_modules/tar/dist/esm/path-reservations.js
|
|
101126
|
-
import { join as
|
|
101400
|
+
import { join as join103 } from "node:path";
|
|
101127
101401
|
|
|
101128
101402
|
// node_modules/tar/dist/esm/normalize-unicode.js
|
|
101129
101403
|
var normalizeCache = Object.create(null);
|
|
@@ -101156,7 +101430,7 @@ var getDirs = (path13) => {
|
|
|
101156
101430
|
const dirs = path13.split("/").slice(0, -1).reduce((set, path14) => {
|
|
101157
101431
|
const s = set[set.length - 1];
|
|
101158
101432
|
if (s !== undefined) {
|
|
101159
|
-
path14 =
|
|
101433
|
+
path14 = join103(s, path14);
|
|
101160
101434
|
}
|
|
101161
101435
|
set.push(path14 || "/");
|
|
101162
101436
|
return set;
|
|
@@ -101170,7 +101444,7 @@ class PathReservations {
|
|
|
101170
101444
|
#running = new Set;
|
|
101171
101445
|
reserve(paths, fn) {
|
|
101172
101446
|
paths = isWindows4 ? ["win32 parallelization disabled"] : paths.map((p) => {
|
|
101173
|
-
return stripTrailingSlashes(
|
|
101447
|
+
return stripTrailingSlashes(join103(normalizeUnicode(p))).toLowerCase();
|
|
101174
101448
|
});
|
|
101175
101449
|
const dirs = new Set(paths.map((path13) => getDirs(path13)).reduce((a3, b3) => a3.concat(b3)));
|
|
101176
101450
|
this.#reservations.set(fn, { dirs, paths });
|
|
@@ -102230,7 +102504,7 @@ function decodeFilePath(path15) {
|
|
|
102230
102504
|
init_logger();
|
|
102231
102505
|
init_types3();
|
|
102232
102506
|
import { copyFile as copyFile3, lstat as lstat7, mkdir as mkdir27, readdir as readdir24 } from "node:fs/promises";
|
|
102233
|
-
import { join as
|
|
102507
|
+
import { join as join104, relative as relative21 } from "node:path";
|
|
102234
102508
|
async function withRetry(fn, retries = 3) {
|
|
102235
102509
|
for (let i = 0;i < retries; i++) {
|
|
102236
102510
|
try {
|
|
@@ -102252,8 +102526,8 @@ async function moveDirectoryContents(sourceDir, destDir, shouldExclude, sizeTrac
|
|
|
102252
102526
|
await mkdir27(destDir, { recursive: true });
|
|
102253
102527
|
const entries = await readdir24(sourceDir, { encoding: "utf8" });
|
|
102254
102528
|
for (const entry of entries) {
|
|
102255
|
-
const sourcePath =
|
|
102256
|
-
const destPath =
|
|
102529
|
+
const sourcePath = join104(sourceDir, entry);
|
|
102530
|
+
const destPath = join104(destDir, entry);
|
|
102257
102531
|
const relativePath = relative21(sourceDir, sourcePath);
|
|
102258
102532
|
if (!isPathSafe(destDir, destPath)) {
|
|
102259
102533
|
logger.warning(`Skipping unsafe path: ${relativePath}`);
|
|
@@ -102280,8 +102554,8 @@ async function copyDirectory(sourceDir, destDir, shouldExclude, sizeTracker) {
|
|
|
102280
102554
|
await mkdir27(destDir, { recursive: true });
|
|
102281
102555
|
const entries = await readdir24(sourceDir, { encoding: "utf8" });
|
|
102282
102556
|
for (const entry of entries) {
|
|
102283
|
-
const sourcePath =
|
|
102284
|
-
const destPath =
|
|
102557
|
+
const sourcePath = join104(sourceDir, entry);
|
|
102558
|
+
const destPath = join104(destDir, entry);
|
|
102285
102559
|
const relativePath = relative21(sourceDir, sourcePath);
|
|
102286
102560
|
if (!isPathSafe(destDir, destPath)) {
|
|
102287
102561
|
logger.warning(`Skipping unsafe path: ${relativePath}`);
|
|
@@ -102329,7 +102603,7 @@ class TarExtractor {
|
|
|
102329
102603
|
logger.debug(`Root entries: ${entries.join(", ")}`);
|
|
102330
102604
|
if (entries.length === 1) {
|
|
102331
102605
|
const rootEntry = entries[0];
|
|
102332
|
-
const rootPath =
|
|
102606
|
+
const rootPath = join105(tempExtractDir, rootEntry);
|
|
102333
102607
|
const rootStat = await stat15(rootPath);
|
|
102334
102608
|
if (rootStat.isDirectory()) {
|
|
102335
102609
|
const rootContents = await readdir25(rootPath, { encoding: "utf8" });
|
|
@@ -102345,7 +102619,7 @@ class TarExtractor {
|
|
|
102345
102619
|
}
|
|
102346
102620
|
} else {
|
|
102347
102621
|
await mkdir28(destDir, { recursive: true });
|
|
102348
|
-
await copyFile4(rootPath,
|
|
102622
|
+
await copyFile4(rootPath, join105(destDir, rootEntry));
|
|
102349
102623
|
}
|
|
102350
102624
|
} else {
|
|
102351
102625
|
logger.debug("Multiple root entries - moving all");
|
|
@@ -102367,7 +102641,7 @@ init_logger();
|
|
|
102367
102641
|
var import_extract_zip = __toESM(require_extract_zip(), 1);
|
|
102368
102642
|
import { execFile as execFile11 } from "node:child_process";
|
|
102369
102643
|
import { copyFile as copyFile5, mkdir as mkdir29, readdir as readdir26, rm as rm12, stat as stat16 } from "node:fs/promises";
|
|
102370
|
-
import { join as
|
|
102644
|
+
import { join as join106 } from "node:path";
|
|
102371
102645
|
import { promisify as promisify16 } from "node:util";
|
|
102372
102646
|
|
|
102373
102647
|
// src/domains/installation/extraction/native-zip-commands.ts
|
|
@@ -102459,7 +102733,7 @@ class ZipExtractor {
|
|
|
102459
102733
|
logger.debug(`Root entries: ${entries.join(", ")}`);
|
|
102460
102734
|
if (entries.length === 1) {
|
|
102461
102735
|
const rootEntry = entries[0];
|
|
102462
|
-
const rootPath =
|
|
102736
|
+
const rootPath = join106(tempExtractDir, rootEntry);
|
|
102463
102737
|
const rootStat = await stat16(rootPath);
|
|
102464
102738
|
if (rootStat.isDirectory()) {
|
|
102465
102739
|
const rootContents = await readdir26(rootPath, { encoding: "utf8" });
|
|
@@ -102475,7 +102749,7 @@ class ZipExtractor {
|
|
|
102475
102749
|
}
|
|
102476
102750
|
} else {
|
|
102477
102751
|
await mkdir29(destDir, { recursive: true });
|
|
102478
|
-
await copyFile5(rootPath,
|
|
102752
|
+
await copyFile5(rootPath, join106(destDir, rootEntry));
|
|
102479
102753
|
}
|
|
102480
102754
|
} else {
|
|
102481
102755
|
logger.debug("Multiple root entries - moving all");
|
|
@@ -102576,7 +102850,7 @@ class DownloadManager {
|
|
|
102576
102850
|
async createTempDir() {
|
|
102577
102851
|
const timestamp = Date.now();
|
|
102578
102852
|
const counter = DownloadManager.tempDirCounter++;
|
|
102579
|
-
const primaryTempDir =
|
|
102853
|
+
const primaryTempDir = join107(tmpdir4(), `claudekit-${timestamp}-${counter}`);
|
|
102580
102854
|
try {
|
|
102581
102855
|
await mkdir30(primaryTempDir, { recursive: true });
|
|
102582
102856
|
logger.debug(`Created temp directory: ${primaryTempDir}`);
|
|
@@ -102593,7 +102867,7 @@ Solutions:
|
|
|
102593
102867
|
2. Set HOME environment variable
|
|
102594
102868
|
3. Try running from a different directory`);
|
|
102595
102869
|
}
|
|
102596
|
-
const fallbackTempDir =
|
|
102870
|
+
const fallbackTempDir = join107(homeDir, ".claudekit", "tmp", `claudekit-${timestamp}-${counter}`);
|
|
102597
102871
|
try {
|
|
102598
102872
|
await mkdir30(fallbackTempDir, { recursive: true });
|
|
102599
102873
|
logger.debug(`Created temp directory (fallback): ${fallbackTempDir}`);
|
|
@@ -103053,20 +103327,20 @@ async function handleDownload(ctx) {
|
|
|
103053
103327
|
};
|
|
103054
103328
|
}
|
|
103055
103329
|
// src/commands/init/phases/merge-handler.ts
|
|
103056
|
-
import { join as
|
|
103330
|
+
import { join as join125 } from "node:path";
|
|
103057
103331
|
|
|
103058
103332
|
// src/domains/installation/deletion-handler.ts
|
|
103059
103333
|
import { existsSync as existsSync66, lstatSync as lstatSync3, readdirSync as readdirSync10, rmSync as rmSync2, rmdirSync, unlinkSync as unlinkSync4 } from "node:fs";
|
|
103060
|
-
import { dirname as dirname38, join as
|
|
103334
|
+
import { dirname as dirname38, join as join110, relative as relative22, resolve as resolve43, sep as sep12 } from "node:path";
|
|
103061
103335
|
|
|
103062
103336
|
// src/services/file-operations/manifest/manifest-reader.ts
|
|
103063
103337
|
init_metadata_migration();
|
|
103064
103338
|
init_logger();
|
|
103065
103339
|
init_types3();
|
|
103066
103340
|
var import_fs_extra11 = __toESM(require_lib(), 1);
|
|
103067
|
-
import { join as
|
|
103341
|
+
import { join as join109 } from "node:path";
|
|
103068
103342
|
async function readManifest(claudeDir3) {
|
|
103069
|
-
const metadataPath =
|
|
103343
|
+
const metadataPath = join109(claudeDir3, "metadata.json");
|
|
103070
103344
|
if (!await import_fs_extra11.pathExists(metadataPath)) {
|
|
103071
103345
|
return null;
|
|
103072
103346
|
}
|
|
@@ -103252,7 +103526,7 @@ function collectFilesRecursively(dir, baseDir) {
|
|
|
103252
103526
|
try {
|
|
103253
103527
|
const entries = readdirSync10(dir, { withFileTypes: true });
|
|
103254
103528
|
for (const entry of entries) {
|
|
103255
|
-
const fullPath =
|
|
103529
|
+
const fullPath = join110(dir, entry.name);
|
|
103256
103530
|
const relativePath = relative22(baseDir, fullPath);
|
|
103257
103531
|
if (entry.isDirectory()) {
|
|
103258
103532
|
results.push(...collectFilesRecursively(fullPath, baseDir));
|
|
@@ -103320,7 +103594,7 @@ function deletePath(fullPath, claudeDir3) {
|
|
|
103320
103594
|
}
|
|
103321
103595
|
}
|
|
103322
103596
|
async function updateMetadataAfterDeletion(claudeDir3, deletedPaths) {
|
|
103323
|
-
const metadataPath =
|
|
103597
|
+
const metadataPath = join110(claudeDir3, "metadata.json");
|
|
103324
103598
|
if (!await import_fs_extra12.pathExists(metadataPath)) {
|
|
103325
103599
|
return;
|
|
103326
103600
|
}
|
|
@@ -103375,7 +103649,7 @@ async function handleDeletions(sourceMetadata, claudeDir3, kitType) {
|
|
|
103375
103649
|
const userMetadata = await readManifest(claudeDir3);
|
|
103376
103650
|
const result = { deletedPaths: [], preservedPaths: [], errors: [] };
|
|
103377
103651
|
for (const path16 of deletions) {
|
|
103378
|
-
const fullPath =
|
|
103652
|
+
const fullPath = join110(claudeDir3, path16);
|
|
103379
103653
|
const normalizedPath = resolve43(fullPath);
|
|
103380
103654
|
const normalizedClaudeDir = resolve43(claudeDir3);
|
|
103381
103655
|
if (!normalizedPath.startsWith(`${normalizedClaudeDir}${sep12}`)) {
|
|
@@ -103415,7 +103689,7 @@ init_logger();
|
|
|
103415
103689
|
init_types3();
|
|
103416
103690
|
var import_fs_extra16 = __toESM(require_lib(), 1);
|
|
103417
103691
|
var import_ignore3 = __toESM(require_ignore(), 1);
|
|
103418
|
-
import { dirname as dirname42, join as
|
|
103692
|
+
import { dirname as dirname42, join as join115, relative as relative25 } from "node:path";
|
|
103419
103693
|
|
|
103420
103694
|
// src/domains/installation/selective-merger.ts
|
|
103421
103695
|
import { stat as stat18 } from "node:fs/promises";
|
|
@@ -103591,7 +103865,7 @@ class SelectiveMerger {
|
|
|
103591
103865
|
|
|
103592
103866
|
// src/domains/installation/merger/deleted-skill-preservation.ts
|
|
103593
103867
|
init_metadata_migration();
|
|
103594
|
-
import { dirname as dirname39, join as
|
|
103868
|
+
import { dirname as dirname39, join as join111, relative as relative23 } from "node:path";
|
|
103595
103869
|
var import_fs_extra13 = __toESM(require_lib(), 1);
|
|
103596
103870
|
async function findIgnoredSkillDirectories({
|
|
103597
103871
|
files,
|
|
@@ -103619,7 +103893,7 @@ async function findIgnoredSkillDirectories({
|
|
|
103619
103893
|
return root ? [root] : [];
|
|
103620
103894
|
}));
|
|
103621
103895
|
for (const [metadataRoot, sourceRoot] of sourceSkillRoots) {
|
|
103622
|
-
const destSkillRoot =
|
|
103896
|
+
const destSkillRoot = join111(destDir, ...sourceRoot.split("/"));
|
|
103623
103897
|
const skillExists = await import_fs_extra13.pathExists(destSkillRoot);
|
|
103624
103898
|
if (existingIgnoredRoots.has(metadataRoot) || !skillExists && previouslyTrackedRoots.has(metadataRoot)) {
|
|
103625
103899
|
ignoredSkillDirectories.add(metadataRoot);
|
|
@@ -103669,7 +103943,7 @@ init_logger();
|
|
|
103669
103943
|
var import_fs_extra14 = __toESM(require_lib(), 1);
|
|
103670
103944
|
var import_ignore2 = __toESM(require_ignore(), 1);
|
|
103671
103945
|
import { relative as relative24 } from "node:path";
|
|
103672
|
-
import { join as
|
|
103946
|
+
import { join as join112 } from "node:path";
|
|
103673
103947
|
|
|
103674
103948
|
// node_modules/@isaacs/balanced-match/dist/esm/index.js
|
|
103675
103949
|
var balanced = (a3, b3, str2) => {
|
|
@@ -105125,7 +105399,7 @@ class FileScanner {
|
|
|
105125
105399
|
const files = [];
|
|
105126
105400
|
const entries = await import_fs_extra14.readdir(dir, { encoding: "utf8" });
|
|
105127
105401
|
for (const entry of entries) {
|
|
105128
|
-
const fullPath =
|
|
105402
|
+
const fullPath = join112(dir, entry);
|
|
105129
105403
|
const relativePath = relative24(baseDir, fullPath);
|
|
105130
105404
|
const normalizedRelativePath = relativePath.replace(/\\/g, "/");
|
|
105131
105405
|
const stats = await import_fs_extra14.lstat(fullPath);
|
|
@@ -105161,13 +105435,13 @@ class FileScanner {
|
|
|
105161
105435
|
// src/domains/installation/merger/settings-processor.ts
|
|
105162
105436
|
import { execSync as execSync5 } from "node:child_process";
|
|
105163
105437
|
import { homedir as homedir46 } from "node:os";
|
|
105164
|
-
import { dirname as dirname41, join as
|
|
105438
|
+
import { dirname as dirname41, join as join114 } from "node:path";
|
|
105165
105439
|
|
|
105166
105440
|
// src/domains/config/installed-settings-tracker.ts
|
|
105167
105441
|
init_shared();
|
|
105168
105442
|
import { existsSync as existsSync67 } from "node:fs";
|
|
105169
105443
|
import { mkdir as mkdir31, readFile as readFile52, writeFile as writeFile27 } from "node:fs/promises";
|
|
105170
|
-
import { dirname as dirname40, join as
|
|
105444
|
+
import { dirname as dirname40, join as join113 } from "node:path";
|
|
105171
105445
|
var CK_JSON_FILE = ".ck.json";
|
|
105172
105446
|
|
|
105173
105447
|
class InstalledSettingsTracker {
|
|
@@ -105181,9 +105455,9 @@ class InstalledSettingsTracker {
|
|
|
105181
105455
|
}
|
|
105182
105456
|
getCkJsonPath() {
|
|
105183
105457
|
if (this.isGlobal) {
|
|
105184
|
-
return
|
|
105458
|
+
return join113(this.projectDir, CK_JSON_FILE);
|
|
105185
105459
|
}
|
|
105186
|
-
return
|
|
105460
|
+
return join113(this.projectDir, ".claude", CK_JSON_FILE);
|
|
105187
105461
|
}
|
|
105188
105462
|
async loadInstalledSettings() {
|
|
105189
105463
|
const ckJsonPath = this.getCkJsonPath();
|
|
@@ -105451,10 +105725,10 @@ class SettingsProcessor {
|
|
|
105451
105725
|
};
|
|
105452
105726
|
try {
|
|
105453
105727
|
if (this.isGlobal) {
|
|
105454
|
-
await addFromConfig(
|
|
105728
|
+
await addFromConfig(join114(this.projectDir, ".ck.json"));
|
|
105455
105729
|
} else {
|
|
105456
|
-
await addFromConfig(
|
|
105457
|
-
await addFromConfig(
|
|
105730
|
+
await addFromConfig(join114(PathResolver.getGlobalKitDir(), ".ck.json"));
|
|
105731
|
+
await addFromConfig(join114(this.projectDir, ".claude", ".ck.json"));
|
|
105458
105732
|
}
|
|
105459
105733
|
} catch (error) {
|
|
105460
105734
|
logger.debug(`Failed to load .ck.json hook preferences: ${error instanceof Error ? error.message : "unknown"}`);
|
|
@@ -105841,7 +106115,7 @@ class SettingsProcessor {
|
|
|
105841
106115
|
return false;
|
|
105842
106116
|
}
|
|
105843
106117
|
const configuredGlobalDir = PathResolver.getGlobalKitDir().replace(/\\/g, "/").replace(/\/+$/, "");
|
|
105844
|
-
const defaultGlobalDir =
|
|
106118
|
+
const defaultGlobalDir = join114(homedir46(), ".claude").replace(/\\/g, "/");
|
|
105845
106119
|
return configuredGlobalDir !== defaultGlobalDir;
|
|
105846
106120
|
}
|
|
105847
106121
|
getClaudeCommandRoot() {
|
|
@@ -105861,7 +106135,7 @@ class SettingsProcessor {
|
|
|
105861
106135
|
return true;
|
|
105862
106136
|
}
|
|
105863
106137
|
async repairSiblingSettingsLocal(destFile) {
|
|
105864
|
-
const settingsLocalPath =
|
|
106138
|
+
const settingsLocalPath = join114(dirname41(destFile), "settings.local.json");
|
|
105865
106139
|
if (settingsLocalPath === destFile || !await import_fs_extra15.pathExists(settingsLocalPath)) {
|
|
105866
106140
|
return;
|
|
105867
106141
|
}
|
|
@@ -105958,7 +106232,7 @@ class SettingsProcessor {
|
|
|
105958
106232
|
}
|
|
105959
106233
|
}
|
|
105960
106234
|
async dynamicTeamHookHandlerExists(destFile, handler) {
|
|
105961
|
-
return import_fs_extra15.pathExists(
|
|
106235
|
+
return import_fs_extra15.pathExists(join114(dirname41(destFile), "hooks", handler));
|
|
105962
106236
|
}
|
|
105963
106237
|
removeDynamicTeamHookRegistrations(settings) {
|
|
105964
106238
|
let removed = 0;
|
|
@@ -106099,7 +106373,7 @@ class CopyExecutor {
|
|
|
106099
106373
|
for (const file of files) {
|
|
106100
106374
|
const relativePath = relative25(sourceDir, file);
|
|
106101
106375
|
const normalizedRelativePath = relativePath.replace(/\\/g, "/");
|
|
106102
|
-
const destPath =
|
|
106376
|
+
const destPath = join115(destDir, relativePath);
|
|
106103
106377
|
if (await import_fs_extra16.pathExists(destPath)) {
|
|
106104
106378
|
if (this.fileScanner.shouldNeverCopy(normalizedRelativePath)) {
|
|
106105
106379
|
logger.debug(`Security-sensitive file exists but won't be overwritten: ${normalizedRelativePath}`);
|
|
@@ -106123,7 +106397,7 @@ class CopyExecutor {
|
|
|
106123
106397
|
for (const file of files) {
|
|
106124
106398
|
const relativePath = relative25(sourceDir, file);
|
|
106125
106399
|
const normalizedRelativePath = relativePath.replace(/\\/g, "/");
|
|
106126
|
-
const destPath =
|
|
106400
|
+
const destPath = join115(destDir, relativePath);
|
|
106127
106401
|
if (this.fileScanner.shouldNeverCopy(normalizedRelativePath)) {
|
|
106128
106402
|
logger.debug(`Skipping security-sensitive file: ${normalizedRelativePath}`);
|
|
106129
106403
|
skippedCount++;
|
|
@@ -106335,15 +106609,15 @@ class FileMerger {
|
|
|
106335
106609
|
|
|
106336
106610
|
// src/domains/migration/legacy-migration.ts
|
|
106337
106611
|
import { readdir as readdir28, stat as stat19 } from "node:fs/promises";
|
|
106338
|
-
import { join as
|
|
106612
|
+
import { join as join119, relative as relative26 } from "node:path";
|
|
106339
106613
|
// src/services/file-operations/manifest/manifest-tracker.ts
|
|
106340
|
-
import { join as
|
|
106614
|
+
import { join as join118 } from "node:path";
|
|
106341
106615
|
|
|
106342
106616
|
// src/domains/migration/release-manifest.ts
|
|
106343
106617
|
init_logger();
|
|
106344
106618
|
init_zod();
|
|
106345
106619
|
var import_fs_extra17 = __toESM(require_lib(), 1);
|
|
106346
|
-
import { join as
|
|
106620
|
+
import { join as join116 } from "node:path";
|
|
106347
106621
|
var ReleaseManifestFileSchema = exports_external.object({
|
|
106348
106622
|
path: exports_external.string(),
|
|
106349
106623
|
checksum: exports_external.string().regex(/^[a-f0-9]{64}$/),
|
|
@@ -106358,7 +106632,7 @@ var ReleaseManifestSchema = exports_external.object({
|
|
|
106358
106632
|
|
|
106359
106633
|
class ReleaseManifestLoader {
|
|
106360
106634
|
static async load(extractDir) {
|
|
106361
|
-
const manifestPath =
|
|
106635
|
+
const manifestPath = join116(extractDir, "release-manifest.json");
|
|
106362
106636
|
try {
|
|
106363
106637
|
const content = await import_fs_extra17.readFile(manifestPath, "utf-8");
|
|
106364
106638
|
const parsed = JSON.parse(content);
|
|
@@ -106381,12 +106655,12 @@ init_p_limit();
|
|
|
106381
106655
|
|
|
106382
106656
|
// src/services/file-operations/manifest/manifest-updater.ts
|
|
106383
106657
|
init_metadata_migration();
|
|
106384
|
-
import { join as
|
|
106658
|
+
import { join as join117 } from "node:path";
|
|
106385
106659
|
init_logger();
|
|
106386
106660
|
init_types3();
|
|
106387
106661
|
var import_fs_extra18 = __toESM(require_lib(), 1);
|
|
106388
|
-
async function writeManifest(claudeDir3, kitName, version, scope, kitType, trackedFiles, userConfigFiles, ignoredSkills = []) {
|
|
106389
|
-
const metadataPath =
|
|
106662
|
+
async function writeManifest(claudeDir3, kitName, version, scope, kitType, trackedFiles, userConfigFiles, ignoredSkills = [], installModePreference) {
|
|
106663
|
+
const metadataPath = join117(claudeDir3, "metadata.json");
|
|
106390
106664
|
const kit = kitType || (/\bmarketing\b/i.test(kitName) ? "marketing" : "engineer");
|
|
106391
106665
|
await import_fs_extra18.ensureFile(metadataPath);
|
|
106392
106666
|
let release = null;
|
|
@@ -106411,6 +106685,7 @@ async function writeManifest(claudeDir3, kitName, version, scope, kitType, track
|
|
|
106411
106685
|
const existingKits = existingMetadata.kits || {};
|
|
106412
106686
|
const normalizedTrackedPaths = trackedFiles.map((file) => normalizeMetadataPath(file.path));
|
|
106413
106687
|
const existingIgnoredSkills = existingKits[kit]?.ignoredSkills ?? [];
|
|
106688
|
+
const existingInstallModePreference = existingKits[kit]?.installModePreference;
|
|
106414
106689
|
const mergedIgnoredSkills = uniqueNormalizedSkillRoots([
|
|
106415
106690
|
...existingIgnoredSkills,
|
|
106416
106691
|
...ignoredSkills
|
|
@@ -106420,7 +106695,8 @@ async function writeManifest(claudeDir3, kitName, version, scope, kitType, track
|
|
|
106420
106695
|
version,
|
|
106421
106696
|
installedAt,
|
|
106422
106697
|
files: trackedFiles.length > 0 ? trackedFiles : undefined,
|
|
106423
|
-
ignoredSkills: mergedIgnoredSkills.length > 0 ? mergedIgnoredSkills : undefined
|
|
106698
|
+
ignoredSkills: mergedIgnoredSkills.length > 0 ? mergedIgnoredSkills : undefined,
|
|
106699
|
+
installModePreference: installModePreference ?? existingInstallModePreference
|
|
106424
106700
|
};
|
|
106425
106701
|
const otherKitsExist = Object.keys(existingKits).some((k2) => k2 !== kit);
|
|
106426
106702
|
const metadata = {
|
|
@@ -106458,7 +106734,7 @@ function uniqueNormalizedSkillRoots(paths) {
|
|
|
106458
106734
|
}))).sort();
|
|
106459
106735
|
}
|
|
106460
106736
|
async function removeKitFromManifest(claudeDir3, kit, options2) {
|
|
106461
|
-
const metadataPath =
|
|
106737
|
+
const metadataPath = join117(claudeDir3, "metadata.json");
|
|
106462
106738
|
if (!await import_fs_extra18.pathExists(metadataPath))
|
|
106463
106739
|
return false;
|
|
106464
106740
|
let release = null;
|
|
@@ -106490,7 +106766,7 @@ async function removeKitFromManifest(claudeDir3, kit, options2) {
|
|
|
106490
106766
|
}
|
|
106491
106767
|
}
|
|
106492
106768
|
async function retainTrackedFilesInManifest(claudeDir3, retainedPaths, options2) {
|
|
106493
|
-
const metadataPath =
|
|
106769
|
+
const metadataPath = join117(claudeDir3, "metadata.json");
|
|
106494
106770
|
if (!await import_fs_extra18.pathExists(metadataPath))
|
|
106495
106771
|
return false;
|
|
106496
106772
|
const normalizedPaths = new Set(retainedPaths.map((path17) => path17.replace(/\\/g, "/")));
|
|
@@ -106671,7 +106947,7 @@ function buildFileTrackingList(options2) {
|
|
|
106671
106947
|
if (!isGlobal && !installedPath.startsWith(".claude/"))
|
|
106672
106948
|
continue;
|
|
106673
106949
|
const relativePath = isGlobal ? installedPath : installedPath.replace(/^\.claude\//, "");
|
|
106674
|
-
const filePath =
|
|
106950
|
+
const filePath = join118(claudeDir3, relativePath);
|
|
106675
106951
|
const manifestEntry = releaseManifest ? ReleaseManifestLoader.findFile(releaseManifest, installedPath) : null;
|
|
106676
106952
|
const ownership = manifestEntry ? "ck" : "user";
|
|
106677
106953
|
filesToTrack.push({
|
|
@@ -106695,7 +106971,7 @@ async function trackFilesWithProgress(filesToTrack, manifestOptions) {
|
|
|
106695
106971
|
}
|
|
106696
106972
|
});
|
|
106697
106973
|
trackingSpinner.succeed(`Tracked ${trackResult.success} files`);
|
|
106698
|
-
await writeManifest(manifestOptions.claudeDir, manifestOptions.kitName, manifestOptions.releaseTag, manifestOptions.mode, manifestOptions.kitType, tracker.getTrackedFiles(), tracker.getUserConfigFiles(), manifestOptions.ignoredSkills);
|
|
106974
|
+
await writeManifest(manifestOptions.claudeDir, manifestOptions.kitName, manifestOptions.releaseTag, manifestOptions.mode, manifestOptions.kitType, tracker.getTrackedFiles(), tracker.getUserConfigFiles(), manifestOptions.ignoredSkills, manifestOptions.installModePreference);
|
|
106699
106975
|
return trackResult;
|
|
106700
106976
|
}
|
|
106701
106977
|
// src/services/file-operations/manifest-writer.ts
|
|
@@ -106725,8 +107001,8 @@ class ManifestWriter {
|
|
|
106725
107001
|
getTrackedFiles() {
|
|
106726
107002
|
return this.tracker.getTrackedFiles();
|
|
106727
107003
|
}
|
|
106728
|
-
async writeManifest(claudeDir3, kitName, version, scope, kitType, ignoredSkills) {
|
|
106729
|
-
return writeManifest(claudeDir3, kitName, version, scope, kitType, this.getTrackedFiles(), this.getUserConfigFiles(), ignoredSkills);
|
|
107004
|
+
async writeManifest(claudeDir3, kitName, version, scope, kitType, ignoredSkills, installModePreference) {
|
|
107005
|
+
return writeManifest(claudeDir3, kitName, version, scope, kitType, this.getTrackedFiles(), this.getUserConfigFiles(), ignoredSkills, installModePreference);
|
|
106730
107006
|
}
|
|
106731
107007
|
static async readManifest(claudeDir3) {
|
|
106732
107008
|
return readManifest(claudeDir3);
|
|
@@ -106782,7 +107058,7 @@ class LegacyMigration {
|
|
|
106782
107058
|
continue;
|
|
106783
107059
|
if (SKIP_DIRS_ALL.includes(entry))
|
|
106784
107060
|
continue;
|
|
106785
|
-
const fullPath =
|
|
107061
|
+
const fullPath = join119(dir, entry);
|
|
106786
107062
|
let stats;
|
|
106787
107063
|
try {
|
|
106788
107064
|
stats = await stat19(fullPath);
|
|
@@ -106892,7 +107168,7 @@ User-created files (sample):`);
|
|
|
106892
107168
|
];
|
|
106893
107169
|
if (filesToChecksum.length > 0) {
|
|
106894
107170
|
const checksumResults = await mapWithLimit(filesToChecksum, async ({ relativePath, ownership }) => {
|
|
106895
|
-
const fullPath =
|
|
107171
|
+
const fullPath = join119(claudeDir3, relativePath);
|
|
106896
107172
|
const checksum = await OwnershipChecker.calculateChecksum(fullPath);
|
|
106897
107173
|
return { relativePath, checksum, ownership };
|
|
106898
107174
|
}, getOptimalConcurrency());
|
|
@@ -106913,7 +107189,7 @@ User-created files (sample):`);
|
|
|
106913
107189
|
installedAt: new Date().toISOString(),
|
|
106914
107190
|
files: trackedFiles
|
|
106915
107191
|
};
|
|
106916
|
-
const metadataPath =
|
|
107192
|
+
const metadataPath = join119(claudeDir3, "metadata.json");
|
|
106917
107193
|
await import_fs_extra19.writeFile(metadataPath, JSON.stringify(updatedMetadata, null, 2));
|
|
106918
107194
|
logger.success(`Migration complete: tracked ${trackedFiles.length} files`);
|
|
106919
107195
|
return true;
|
|
@@ -107019,7 +107295,7 @@ function buildConflictSummary(fileConflicts, hookConflicts, mcpConflicts) {
|
|
|
107019
107295
|
init_logger();
|
|
107020
107296
|
init_skip_directories();
|
|
107021
107297
|
var import_fs_extra20 = __toESM(require_lib(), 1);
|
|
107022
|
-
import { join as
|
|
107298
|
+
import { join as join120, relative as relative27, resolve as resolve44 } from "node:path";
|
|
107023
107299
|
|
|
107024
107300
|
class FileScanner2 {
|
|
107025
107301
|
static async getFiles(dirPath, relativeTo) {
|
|
@@ -107035,7 +107311,7 @@ class FileScanner2 {
|
|
|
107035
107311
|
logger.debug(`Skipping directory: ${entry}`);
|
|
107036
107312
|
continue;
|
|
107037
107313
|
}
|
|
107038
|
-
const fullPath =
|
|
107314
|
+
const fullPath = join120(dirPath, entry);
|
|
107039
107315
|
if (!FileScanner2.isSafePath(basePath, fullPath)) {
|
|
107040
107316
|
logger.warning(`Skipping potentially unsafe path: ${entry}`);
|
|
107041
107317
|
continue;
|
|
@@ -107070,8 +107346,8 @@ class FileScanner2 {
|
|
|
107070
107346
|
return files;
|
|
107071
107347
|
}
|
|
107072
107348
|
static async findCustomFiles(destDir, sourceDir, subPath) {
|
|
107073
|
-
const destSubDir =
|
|
107074
|
-
const sourceSubDir =
|
|
107349
|
+
const destSubDir = join120(destDir, subPath);
|
|
107350
|
+
const sourceSubDir = join120(sourceDir, subPath);
|
|
107075
107351
|
logger.debug(`findCustomFiles - destDir: ${destDir}`);
|
|
107076
107352
|
logger.debug(`findCustomFiles - sourceDir: ${sourceDir}`);
|
|
107077
107353
|
logger.debug(`findCustomFiles - subPath: "${subPath}"`);
|
|
@@ -107112,12 +107388,12 @@ class FileScanner2 {
|
|
|
107112
107388
|
init_logger();
|
|
107113
107389
|
var import_fs_extra21 = __toESM(require_lib(), 1);
|
|
107114
107390
|
import { lstat as lstat10, mkdir as mkdir32, readdir as readdir31, stat as stat20 } from "node:fs/promises";
|
|
107115
|
-
import { join as
|
|
107391
|
+
import { join as join122 } from "node:path";
|
|
107116
107392
|
|
|
107117
107393
|
// src/services/transformers/commands-prefix/content-transformer.ts
|
|
107118
107394
|
init_logger();
|
|
107119
107395
|
import { readFile as readFile56, readdir as readdir30, writeFile as writeFile31 } from "node:fs/promises";
|
|
107120
|
-
import { join as
|
|
107396
|
+
import { join as join121 } from "node:path";
|
|
107121
107397
|
var TRANSFORMABLE_EXTENSIONS = new Set([
|
|
107122
107398
|
".md",
|
|
107123
107399
|
".txt",
|
|
@@ -107177,7 +107453,7 @@ async function transformCommandReferences(directory, options2 = {}) {
|
|
|
107177
107453
|
async function processDirectory(dir) {
|
|
107178
107454
|
const entries = await readdir30(dir, { withFileTypes: true });
|
|
107179
107455
|
for (const entry of entries) {
|
|
107180
|
-
const fullPath =
|
|
107456
|
+
const fullPath = join121(dir, entry.name);
|
|
107181
107457
|
if (entry.isDirectory()) {
|
|
107182
107458
|
if (entry.name === "node_modules" || entry.name.startsWith(".") && entry.name !== ".claude") {
|
|
107183
107459
|
continue;
|
|
@@ -107252,14 +107528,14 @@ function shouldApplyPrefix(options2) {
|
|
|
107252
107528
|
// src/services/transformers/commands-prefix/prefix-applier.ts
|
|
107253
107529
|
async function applyPrefix(extractDir) {
|
|
107254
107530
|
validatePath(extractDir, "extractDir");
|
|
107255
|
-
const commandsDir =
|
|
107531
|
+
const commandsDir = join122(extractDir, ".claude", "commands");
|
|
107256
107532
|
if (!await import_fs_extra21.pathExists(commandsDir)) {
|
|
107257
107533
|
logger.verbose("No commands directory found, skipping prefix application");
|
|
107258
107534
|
return;
|
|
107259
107535
|
}
|
|
107260
107536
|
logger.info("Applying /ck: prefix to slash commands...");
|
|
107261
|
-
const backupDir =
|
|
107262
|
-
const tempDir =
|
|
107537
|
+
const backupDir = join122(extractDir, ".commands-backup");
|
|
107538
|
+
const tempDir = join122(extractDir, ".commands-prefix-temp");
|
|
107263
107539
|
try {
|
|
107264
107540
|
const entries = await readdir31(commandsDir);
|
|
107265
107541
|
if (entries.length === 0) {
|
|
@@ -107267,7 +107543,7 @@ async function applyPrefix(extractDir) {
|
|
|
107267
107543
|
return;
|
|
107268
107544
|
}
|
|
107269
107545
|
if (entries.length === 1 && entries[0] === "ck") {
|
|
107270
|
-
const ckDir2 =
|
|
107546
|
+
const ckDir2 = join122(commandsDir, "ck");
|
|
107271
107547
|
const ckStat = await stat20(ckDir2);
|
|
107272
107548
|
if (ckStat.isDirectory()) {
|
|
107273
107549
|
logger.verbose("Commands already have /ck: prefix, skipping");
|
|
@@ -107277,17 +107553,17 @@ async function applyPrefix(extractDir) {
|
|
|
107277
107553
|
await import_fs_extra21.copy(commandsDir, backupDir);
|
|
107278
107554
|
logger.verbose("Created backup of commands directory");
|
|
107279
107555
|
await mkdir32(tempDir, { recursive: true });
|
|
107280
|
-
const ckDir =
|
|
107556
|
+
const ckDir = join122(tempDir, "ck");
|
|
107281
107557
|
await mkdir32(ckDir, { recursive: true });
|
|
107282
107558
|
let processedCount = 0;
|
|
107283
107559
|
for (const entry of entries) {
|
|
107284
|
-
const sourcePath =
|
|
107560
|
+
const sourcePath = join122(commandsDir, entry);
|
|
107285
107561
|
const stats = await lstat10(sourcePath);
|
|
107286
107562
|
if (stats.isSymbolicLink()) {
|
|
107287
107563
|
logger.warning(`Skipping symlink for security: ${entry}`);
|
|
107288
107564
|
continue;
|
|
107289
107565
|
}
|
|
107290
|
-
const destPath =
|
|
107566
|
+
const destPath = join122(ckDir, entry);
|
|
107291
107567
|
await import_fs_extra21.copy(sourcePath, destPath, {
|
|
107292
107568
|
overwrite: false,
|
|
107293
107569
|
errorOnExist: true
|
|
@@ -107305,7 +107581,7 @@ async function applyPrefix(extractDir) {
|
|
|
107305
107581
|
await import_fs_extra21.move(tempDir, commandsDir);
|
|
107306
107582
|
await import_fs_extra21.remove(backupDir);
|
|
107307
107583
|
logger.success("Successfully reorganized commands to /ck: prefix");
|
|
107308
|
-
const claudeDir3 =
|
|
107584
|
+
const claudeDir3 = join122(extractDir, ".claude");
|
|
107309
107585
|
logger.info("Transforming command references in file contents...");
|
|
107310
107586
|
const transformResult = await transformCommandReferences(claudeDir3, {
|
|
107311
107587
|
verbose: logger.isVerbose()
|
|
@@ -107343,20 +107619,20 @@ async function applyPrefix(extractDir) {
|
|
|
107343
107619
|
// src/services/transformers/commands-prefix/prefix-cleaner.ts
|
|
107344
107620
|
init_metadata_migration();
|
|
107345
107621
|
import { lstat as lstat12, readdir as readdir33 } from "node:fs/promises";
|
|
107346
|
-
import { join as
|
|
107622
|
+
import { join as join124 } from "node:path";
|
|
107347
107623
|
init_logger();
|
|
107348
107624
|
var import_fs_extra23 = __toESM(require_lib(), 1);
|
|
107349
107625
|
|
|
107350
107626
|
// src/services/transformers/commands-prefix/file-processor.ts
|
|
107351
107627
|
import { lstat as lstat11, readdir as readdir32 } from "node:fs/promises";
|
|
107352
|
-
import { join as
|
|
107628
|
+
import { join as join123 } from "node:path";
|
|
107353
107629
|
init_logger();
|
|
107354
107630
|
var import_fs_extra22 = __toESM(require_lib(), 1);
|
|
107355
107631
|
async function scanDirectoryFiles(dir) {
|
|
107356
107632
|
const files = [];
|
|
107357
107633
|
const entries = await readdir32(dir);
|
|
107358
107634
|
for (const entry of entries) {
|
|
107359
|
-
const fullPath =
|
|
107635
|
+
const fullPath = join123(dir, entry);
|
|
107360
107636
|
const stats = await lstat11(fullPath);
|
|
107361
107637
|
if (stats.isSymbolicLink()) {
|
|
107362
107638
|
continue;
|
|
@@ -107484,8 +107760,8 @@ function isDifferentKitDirectory(dirName, currentKit) {
|
|
|
107484
107760
|
async function cleanupCommandsDirectory(targetDir, isGlobal, options2 = {}) {
|
|
107485
107761
|
const { dryRun = false } = options2;
|
|
107486
107762
|
validatePath(targetDir, "targetDir");
|
|
107487
|
-
const claudeDir3 = isGlobal ? targetDir :
|
|
107488
|
-
const commandsDir =
|
|
107763
|
+
const claudeDir3 = isGlobal ? targetDir : join124(targetDir, ".claude");
|
|
107764
|
+
const commandsDir = join124(claudeDir3, "commands");
|
|
107489
107765
|
const accumulator = {
|
|
107490
107766
|
results: [],
|
|
107491
107767
|
deletedCount: 0,
|
|
@@ -107527,7 +107803,7 @@ async function cleanupCommandsDirectory(targetDir, isGlobal, options2 = {}) {
|
|
|
107527
107803
|
}
|
|
107528
107804
|
const metadataForChecks = options2.kitType ? createKitSpecificMetadata(metadata, options2.kitType) : metadata;
|
|
107529
107805
|
for (const entry of entries) {
|
|
107530
|
-
const entryPath =
|
|
107806
|
+
const entryPath = join124(commandsDir, entry);
|
|
107531
107807
|
const stats = await lstat12(entryPath);
|
|
107532
107808
|
if (stats.isSymbolicLink()) {
|
|
107533
107809
|
addSymlinkSkip(entry, accumulator);
|
|
@@ -107576,6 +107852,18 @@ class CommandsPrefix {
|
|
|
107576
107852
|
init_logger();
|
|
107577
107853
|
init_output_manager();
|
|
107578
107854
|
var import_fs_extra24 = __toESM(require_lib(), 1);
|
|
107855
|
+
function normalizeManifestPath(path17) {
|
|
107856
|
+
return path17.replace(/\\/g, "/").replace(/^\/+/, "").replace(/\/+$/, "");
|
|
107857
|
+
}
|
|
107858
|
+
function filterDeletedInstalledFiles(installedFiles, deletedPaths) {
|
|
107859
|
+
if (deletedPaths.length === 0)
|
|
107860
|
+
return installedFiles;
|
|
107861
|
+
const deleted = deletedPaths.map((path17) => normalizeManifestPath(path17)).filter(Boolean);
|
|
107862
|
+
return installedFiles.filter((file) => {
|
|
107863
|
+
const normalized = normalizeManifestPath(file);
|
|
107864
|
+
return !deleted.some((path17) => normalized === path17 || normalized.startsWith(`${path17}/`) || normalized === `.claude/${path17}` || normalized.startsWith(`.claude/${path17}/`));
|
|
107865
|
+
});
|
|
107866
|
+
}
|
|
107579
107867
|
async function handleMerge(ctx) {
|
|
107580
107868
|
if (ctx.cancelled || !ctx.extractDir || !ctx.resolvedDir || !ctx.claudeDir || !ctx.kit || !ctx.kitType) {
|
|
107581
107869
|
return ctx;
|
|
@@ -107584,7 +107872,7 @@ async function handleMerge(ctx) {
|
|
|
107584
107872
|
let customClaudeFiles = [];
|
|
107585
107873
|
if (!ctx.options.fresh) {
|
|
107586
107874
|
logger.info("Scanning for custom .claude files...");
|
|
107587
|
-
const scanSourceDir = ctx.options.global ?
|
|
107875
|
+
const scanSourceDir = ctx.options.global ? join125(ctx.extractDir, ".claude") : ctx.extractDir;
|
|
107588
107876
|
const scanTargetSubdir = ctx.options.global ? "" : ".claude";
|
|
107589
107877
|
customClaudeFiles = await FileScanner2.findCustomFiles(ctx.resolvedDir, scanSourceDir, scanTargetSubdir);
|
|
107590
107878
|
} else {
|
|
@@ -107623,7 +107911,7 @@ async function handleMerge(ctx) {
|
|
|
107623
107911
|
merger.setRestoreCkHooks(ctx.options.restoreCkHooks);
|
|
107624
107912
|
merger.setProjectDir(ctx.resolvedDir);
|
|
107625
107913
|
merger.setKitName(ctx.kit.name);
|
|
107626
|
-
merger.setZombiePrunerHookDir(
|
|
107914
|
+
merger.setZombiePrunerHookDir(join125(ctx.claudeDir, "hooks"));
|
|
107627
107915
|
if (ctx.kitType) {
|
|
107628
107916
|
merger.setMultiKitContext(ctx.claudeDir, ctx.kitType);
|
|
107629
107917
|
}
|
|
@@ -107652,8 +107940,8 @@ async function handleMerge(ctx) {
|
|
|
107652
107940
|
return { ...ctx, cancelled: true };
|
|
107653
107941
|
}
|
|
107654
107942
|
}
|
|
107655
|
-
const sourceDir = ctx.options.global ?
|
|
107656
|
-
const sourceMetadataPath = ctx.options.global ?
|
|
107943
|
+
const sourceDir = ctx.options.global ? join125(ctx.extractDir, ".claude") : ctx.extractDir;
|
|
107944
|
+
const sourceMetadataPath = ctx.options.global ? join125(sourceDir, "metadata.json") : join125(sourceDir, ".claude", "metadata.json");
|
|
107657
107945
|
let sourceMetadata = null;
|
|
107658
107946
|
try {
|
|
107659
107947
|
if (await import_fs_extra24.pathExists(sourceMetadataPath)) {
|
|
@@ -107672,9 +107960,11 @@ async function handleMerge(ctx) {
|
|
|
107672
107960
|
const summary = buildConflictSummary(fileConflicts, [], []);
|
|
107673
107961
|
displayConflictSummary(summary);
|
|
107674
107962
|
}
|
|
107963
|
+
let deletedPaths = [];
|
|
107675
107964
|
try {
|
|
107676
107965
|
if (sourceMetadata?.deletions && sourceMetadata.deletions.length > 0) {
|
|
107677
107966
|
const deletionResult = await handleDeletions(sourceMetadata, ctx.claudeDir, ctx.kitType);
|
|
107967
|
+
deletedPaths = deletionResult.deletedPaths;
|
|
107678
107968
|
if (deletionResult.deletedPaths.length > 0) {
|
|
107679
107969
|
logger.info(`Removed ${deletionResult.deletedPaths.length} deprecated file(s)`);
|
|
107680
107970
|
for (const path17 of deletionResult.deletedPaths) {
|
|
@@ -107688,7 +107978,7 @@ async function handleMerge(ctx) {
|
|
|
107688
107978
|
} catch (error) {
|
|
107689
107979
|
logger.debug(`Cleanup of deprecated files failed: ${error}`);
|
|
107690
107980
|
}
|
|
107691
|
-
const installedFiles = merger.getAllInstalledFiles();
|
|
107981
|
+
const installedFiles = filterDeletedInstalledFiles(merger.getAllInstalledFiles(), deletedPaths);
|
|
107692
107982
|
const filesToTrack = buildFileTrackingList({
|
|
107693
107983
|
installedFiles,
|
|
107694
107984
|
claudeDir: ctx.claudeDir,
|
|
@@ -107702,7 +107992,8 @@ async function handleMerge(ctx) {
|
|
|
107702
107992
|
releaseTag: installedVersion,
|
|
107703
107993
|
mode: ctx.options.global ? "global" : "local",
|
|
107704
107994
|
kitType: ctx.kitType,
|
|
107705
|
-
ignoredSkills: merger.getIgnoredSkillDirectories()
|
|
107995
|
+
ignoredSkills: merger.getIgnoredSkillDirectories(),
|
|
107996
|
+
installModePreference: ctx.options.global && ctx.kitType === "engineer" ? ctx.options.installMode : undefined
|
|
107706
107997
|
});
|
|
107707
107998
|
return {
|
|
107708
107999
|
...ctx,
|
|
@@ -107711,7 +108002,7 @@ async function handleMerge(ctx) {
|
|
|
107711
108002
|
};
|
|
107712
108003
|
}
|
|
107713
108004
|
// src/commands/init/phases/migration-handler.ts
|
|
107714
|
-
import { join as
|
|
108005
|
+
import { join as join133 } from "node:path";
|
|
107715
108006
|
|
|
107716
108007
|
// src/domains/skills/skills-detector.ts
|
|
107717
108008
|
init_logger();
|
|
@@ -107727,7 +108018,7 @@ init_types3();
|
|
|
107727
108018
|
var import_fs_extra25 = __toESM(require_lib(), 1);
|
|
107728
108019
|
import { createHash as createHash8 } from "node:crypto";
|
|
107729
108020
|
import { readFile as readFile58, readdir as readdir34, writeFile as writeFile32 } from "node:fs/promises";
|
|
107730
|
-
import { join as
|
|
108021
|
+
import { join as join126, relative as relative28 } from "node:path";
|
|
107731
108022
|
|
|
107732
108023
|
class SkillsManifestManager {
|
|
107733
108024
|
static MANIFEST_FILENAME = ".skills-manifest.json";
|
|
@@ -107749,12 +108040,12 @@ class SkillsManifestManager {
|
|
|
107749
108040
|
return manifest;
|
|
107750
108041
|
}
|
|
107751
108042
|
static async writeManifest(skillsDir2, manifest) {
|
|
107752
|
-
const manifestPath =
|
|
108043
|
+
const manifestPath = join126(skillsDir2, SkillsManifestManager.MANIFEST_FILENAME);
|
|
107753
108044
|
await writeFile32(manifestPath, JSON.stringify(manifest, null, 2), "utf-8");
|
|
107754
108045
|
logger.debug(`Wrote manifest to: ${manifestPath}`);
|
|
107755
108046
|
}
|
|
107756
108047
|
static async readManifest(skillsDir2) {
|
|
107757
|
-
const manifestPath =
|
|
108048
|
+
const manifestPath = join126(skillsDir2, SkillsManifestManager.MANIFEST_FILENAME);
|
|
107758
108049
|
if (!await import_fs_extra25.pathExists(manifestPath)) {
|
|
107759
108050
|
logger.debug(`No manifest found at: ${manifestPath}`);
|
|
107760
108051
|
return null;
|
|
@@ -107777,7 +108068,7 @@ class SkillsManifestManager {
|
|
|
107777
108068
|
return "flat";
|
|
107778
108069
|
}
|
|
107779
108070
|
for (const dir of dirs.slice(0, 3)) {
|
|
107780
|
-
const dirPath =
|
|
108071
|
+
const dirPath = join126(skillsDir2, dir.name);
|
|
107781
108072
|
const subEntries = await readdir34(dirPath, { withFileTypes: true });
|
|
107782
108073
|
const hasSubdirs = subEntries.some((entry) => entry.isDirectory());
|
|
107783
108074
|
if (hasSubdirs) {
|
|
@@ -107796,7 +108087,7 @@ class SkillsManifestManager {
|
|
|
107796
108087
|
const entries = await readdir34(skillsDir2, { withFileTypes: true });
|
|
107797
108088
|
for (const entry of entries) {
|
|
107798
108089
|
if (entry.isDirectory() && !BUILD_ARTIFACT_DIRS.includes(entry.name) && !entry.name.startsWith(".")) {
|
|
107799
|
-
const skillPath =
|
|
108090
|
+
const skillPath = join126(skillsDir2, entry.name);
|
|
107800
108091
|
const hash = await SkillsManifestManager.hashDirectory(skillPath);
|
|
107801
108092
|
skills.push({
|
|
107802
108093
|
name: entry.name,
|
|
@@ -107808,11 +108099,11 @@ class SkillsManifestManager {
|
|
|
107808
108099
|
const categories = await readdir34(skillsDir2, { withFileTypes: true });
|
|
107809
108100
|
for (const category of categories) {
|
|
107810
108101
|
if (category.isDirectory() && !BUILD_ARTIFACT_DIRS.includes(category.name) && !category.name.startsWith(".")) {
|
|
107811
|
-
const categoryPath =
|
|
108102
|
+
const categoryPath = join126(skillsDir2, category.name);
|
|
107812
108103
|
const skillEntries = await readdir34(categoryPath, { withFileTypes: true });
|
|
107813
108104
|
for (const skillEntry of skillEntries) {
|
|
107814
108105
|
if (skillEntry.isDirectory() && !skillEntry.name.startsWith(".")) {
|
|
107815
|
-
const skillPath =
|
|
108106
|
+
const skillPath = join126(categoryPath, skillEntry.name);
|
|
107816
108107
|
const hash = await SkillsManifestManager.hashDirectory(skillPath);
|
|
107817
108108
|
skills.push({
|
|
107818
108109
|
name: skillEntry.name,
|
|
@@ -107842,7 +108133,7 @@ class SkillsManifestManager {
|
|
|
107842
108133
|
const files = [];
|
|
107843
108134
|
const entries = await readdir34(dirPath, { withFileTypes: true });
|
|
107844
108135
|
for (const entry of entries) {
|
|
107845
|
-
const fullPath =
|
|
108136
|
+
const fullPath = join126(dirPath, entry.name);
|
|
107846
108137
|
if (entry.name.startsWith(".") || BUILD_ARTIFACT_DIRS.includes(entry.name)) {
|
|
107847
108138
|
continue;
|
|
107848
108139
|
}
|
|
@@ -107964,7 +108255,7 @@ function getPathMapping(skillName, oldBasePath, newBasePath) {
|
|
|
107964
108255
|
// src/domains/skills/detection/script-detector.ts
|
|
107965
108256
|
var import_fs_extra26 = __toESM(require_lib(), 1);
|
|
107966
108257
|
import { readdir as readdir35 } from "node:fs/promises";
|
|
107967
|
-
import { join as
|
|
108258
|
+
import { join as join127 } from "node:path";
|
|
107968
108259
|
async function scanDirectory(skillsDir2) {
|
|
107969
108260
|
if (!await import_fs_extra26.pathExists(skillsDir2)) {
|
|
107970
108261
|
return ["flat", []];
|
|
@@ -107977,12 +108268,12 @@ async function scanDirectory(skillsDir2) {
|
|
|
107977
108268
|
let totalSkillLikeCount = 0;
|
|
107978
108269
|
const allSkills = [];
|
|
107979
108270
|
for (const dir of dirs) {
|
|
107980
|
-
const dirPath =
|
|
108271
|
+
const dirPath = join127(skillsDir2, dir.name);
|
|
107981
108272
|
const subEntries = await readdir35(dirPath, { withFileTypes: true });
|
|
107982
108273
|
const subdirs = subEntries.filter((entry) => entry.isDirectory() && !entry.name.startsWith("."));
|
|
107983
108274
|
if (subdirs.length > 0) {
|
|
107984
108275
|
for (const subdir of subdirs.slice(0, 3)) {
|
|
107985
|
-
const subdirPath =
|
|
108276
|
+
const subdirPath = join127(dirPath, subdir.name);
|
|
107986
108277
|
const subdirFiles = await readdir35(subdirPath, { withFileTypes: true });
|
|
107987
108278
|
const hasSkillMarker = subdirFiles.some((file) => file.isFile() && (file.name === "skill.md" || file.name === "README.md" || file.name === "readme.md" || file.name === "config.json" || file.name === "package.json"));
|
|
107988
108279
|
if (hasSkillMarker) {
|
|
@@ -108139,12 +108430,12 @@ class SkillsMigrationDetector {
|
|
|
108139
108430
|
// src/domains/skills/skills-migrator.ts
|
|
108140
108431
|
init_logger();
|
|
108141
108432
|
init_types3();
|
|
108142
|
-
import { join as
|
|
108433
|
+
import { join as join132 } from "node:path";
|
|
108143
108434
|
|
|
108144
108435
|
// src/domains/skills/migrator/migration-executor.ts
|
|
108145
108436
|
init_logger();
|
|
108146
108437
|
import { copyFile as copyFile6, mkdir as mkdir33, readdir as readdir36, rm as rm13 } from "node:fs/promises";
|
|
108147
|
-
import { join as
|
|
108438
|
+
import { join as join128 } from "node:path";
|
|
108148
108439
|
var import_fs_extra28 = __toESM(require_lib(), 1);
|
|
108149
108440
|
|
|
108150
108441
|
// src/domains/skills/skills-migration-prompts.ts
|
|
@@ -108309,8 +108600,8 @@ async function copySkillDirectory(sourceDir, destDir) {
|
|
|
108309
108600
|
await mkdir33(destDir, { recursive: true });
|
|
108310
108601
|
const entries = await readdir36(sourceDir, { withFileTypes: true });
|
|
108311
108602
|
for (const entry of entries) {
|
|
108312
|
-
const sourcePath =
|
|
108313
|
-
const destPath =
|
|
108603
|
+
const sourcePath = join128(sourceDir, entry.name);
|
|
108604
|
+
const destPath = join128(destDir, entry.name);
|
|
108314
108605
|
if (entry.name.startsWith(".") || entry.name === "node_modules" || entry.isSymbolicLink()) {
|
|
108315
108606
|
continue;
|
|
108316
108607
|
}
|
|
@@ -108325,7 +108616,7 @@ async function executeInternal(mappings, customizations, currentSkillsDir, inter
|
|
|
108325
108616
|
const migrated = [];
|
|
108326
108617
|
const preserved = [];
|
|
108327
108618
|
const errors2 = [];
|
|
108328
|
-
const tempDir =
|
|
108619
|
+
const tempDir = join128(currentSkillsDir, "..", ".skills-migration-temp");
|
|
108329
108620
|
await mkdir33(tempDir, { recursive: true });
|
|
108330
108621
|
try {
|
|
108331
108622
|
for (const mapping of mappings) {
|
|
@@ -108346,9 +108637,9 @@ async function executeInternal(mappings, customizations, currentSkillsDir, inter
|
|
|
108346
108637
|
}
|
|
108347
108638
|
}
|
|
108348
108639
|
const category = mapping.category;
|
|
108349
|
-
const targetPath = category ?
|
|
108640
|
+
const targetPath = category ? join128(tempDir, category, skillName) : join128(tempDir, skillName);
|
|
108350
108641
|
if (category) {
|
|
108351
|
-
await mkdir33(
|
|
108642
|
+
await mkdir33(join128(tempDir, category), { recursive: true });
|
|
108352
108643
|
}
|
|
108353
108644
|
await copySkillDirectory(currentSkillPath, targetPath);
|
|
108354
108645
|
migrated.push(skillName);
|
|
@@ -108415,7 +108706,7 @@ init_logger();
|
|
|
108415
108706
|
init_types3();
|
|
108416
108707
|
var import_fs_extra29 = __toESM(require_lib(), 1);
|
|
108417
108708
|
import { copyFile as copyFile7, mkdir as mkdir34, readdir as readdir37, rm as rm14, stat as stat21 } from "node:fs/promises";
|
|
108418
|
-
import { basename as basename27, join as
|
|
108709
|
+
import { basename as basename27, join as join129, normalize as normalize9 } from "node:path";
|
|
108419
108710
|
function validatePath2(path17, paramName) {
|
|
108420
108711
|
if (!path17 || typeof path17 !== "string") {
|
|
108421
108712
|
throw new SkillsMigrationError(`${paramName} must be a non-empty string`);
|
|
@@ -108441,7 +108732,7 @@ class SkillsBackupManager {
|
|
|
108441
108732
|
const timestamp = Date.now();
|
|
108442
108733
|
const randomSuffix = Math.random().toString(36).substring(2, 8);
|
|
108443
108734
|
const backupDirName = `${SkillsBackupManager.BACKUP_PREFIX}${timestamp}-${randomSuffix}`;
|
|
108444
|
-
const backupDir = parentDir ?
|
|
108735
|
+
const backupDir = parentDir ? join129(parentDir, backupDirName) : join129(skillsDir2, "..", backupDirName);
|
|
108445
108736
|
logger.info(`Creating backup at: ${backupDir}`);
|
|
108446
108737
|
try {
|
|
108447
108738
|
await mkdir34(backupDir, { recursive: true });
|
|
@@ -108492,7 +108783,7 @@ class SkillsBackupManager {
|
|
|
108492
108783
|
}
|
|
108493
108784
|
try {
|
|
108494
108785
|
const entries = await readdir37(parentDir, { withFileTypes: true });
|
|
108495
|
-
const backups = entries.filter((entry) => entry.isDirectory() && entry.name.startsWith(SkillsBackupManager.BACKUP_PREFIX)).map((entry) =>
|
|
108786
|
+
const backups = entries.filter((entry) => entry.isDirectory() && entry.name.startsWith(SkillsBackupManager.BACKUP_PREFIX)).map((entry) => join129(parentDir, entry.name));
|
|
108496
108787
|
backups.sort().reverse();
|
|
108497
108788
|
return backups;
|
|
108498
108789
|
} catch (error) {
|
|
@@ -108520,8 +108811,8 @@ class SkillsBackupManager {
|
|
|
108520
108811
|
static async copyDirectory(sourceDir, destDir) {
|
|
108521
108812
|
const entries = await readdir37(sourceDir, { withFileTypes: true });
|
|
108522
108813
|
for (const entry of entries) {
|
|
108523
|
-
const sourcePath =
|
|
108524
|
-
const destPath =
|
|
108814
|
+
const sourcePath = join129(sourceDir, entry.name);
|
|
108815
|
+
const destPath = join129(destDir, entry.name);
|
|
108525
108816
|
if (entry.name.startsWith(".") || entry.name === "node_modules" || entry.isSymbolicLink()) {
|
|
108526
108817
|
continue;
|
|
108527
108818
|
}
|
|
@@ -108537,7 +108828,7 @@ class SkillsBackupManager {
|
|
|
108537
108828
|
let size = 0;
|
|
108538
108829
|
const entries = await readdir37(dirPath, { withFileTypes: true });
|
|
108539
108830
|
for (const entry of entries) {
|
|
108540
|
-
const fullPath =
|
|
108831
|
+
const fullPath = join129(dirPath, entry.name);
|
|
108541
108832
|
if (entry.isSymbolicLink()) {
|
|
108542
108833
|
continue;
|
|
108543
108834
|
}
|
|
@@ -108573,12 +108864,12 @@ init_skip_directories();
|
|
|
108573
108864
|
import { createHash as createHash9 } from "node:crypto";
|
|
108574
108865
|
import { createReadStream as createReadStream2 } from "node:fs";
|
|
108575
108866
|
import { readFile as readFile59, readdir as readdir38 } from "node:fs/promises";
|
|
108576
|
-
import { join as
|
|
108867
|
+
import { join as join130, relative as relative29 } from "node:path";
|
|
108577
108868
|
async function getAllFiles(dirPath) {
|
|
108578
108869
|
const files = [];
|
|
108579
108870
|
const entries = await readdir38(dirPath, { withFileTypes: true });
|
|
108580
108871
|
for (const entry of entries) {
|
|
108581
|
-
const fullPath =
|
|
108872
|
+
const fullPath = join130(dirPath, entry.name);
|
|
108582
108873
|
if (entry.name.startsWith(".") || BUILD_ARTIFACT_DIRS.includes(entry.name) || entry.isSymbolicLink()) {
|
|
108583
108874
|
continue;
|
|
108584
108875
|
}
|
|
@@ -108705,7 +108996,7 @@ async function detectFileChanges(currentSkillPath, baselineSkillPath) {
|
|
|
108705
108996
|
init_types3();
|
|
108706
108997
|
var import_fs_extra31 = __toESM(require_lib(), 1);
|
|
108707
108998
|
import { readdir as readdir39 } from "node:fs/promises";
|
|
108708
|
-
import { join as
|
|
108999
|
+
import { join as join131, normalize as normalize10 } from "node:path";
|
|
108709
109000
|
function validatePath3(path17, paramName) {
|
|
108710
109001
|
if (!path17 || typeof path17 !== "string") {
|
|
108711
109002
|
throw new SkillsMigrationError(`${paramName} must be a non-empty string`);
|
|
@@ -108726,13 +109017,13 @@ async function scanSkillsDirectory(skillsDir2) {
|
|
|
108726
109017
|
if (dirs.length === 0) {
|
|
108727
109018
|
return ["flat", []];
|
|
108728
109019
|
}
|
|
108729
|
-
const firstDirPath =
|
|
109020
|
+
const firstDirPath = join131(skillsDir2, dirs[0].name);
|
|
108730
109021
|
const subEntries = await readdir39(firstDirPath, { withFileTypes: true });
|
|
108731
109022
|
const subdirs = subEntries.filter((entry) => entry.isDirectory() && !entry.name.startsWith("."));
|
|
108732
109023
|
if (subdirs.length > 0) {
|
|
108733
109024
|
let skillLikeCount = 0;
|
|
108734
109025
|
for (const subdir of subdirs.slice(0, 3)) {
|
|
108735
|
-
const subdirPath =
|
|
109026
|
+
const subdirPath = join131(firstDirPath, subdir.name);
|
|
108736
109027
|
const subdirFiles = await readdir39(subdirPath, { withFileTypes: true });
|
|
108737
109028
|
const hasSkillMarker = subdirFiles.some((file) => file.isFile() && (file.name === "skill.md" || file.name === "README.md" || file.name === "readme.md" || file.name === "config.json" || file.name === "package.json"));
|
|
108738
109029
|
if (hasSkillMarker) {
|
|
@@ -108742,7 +109033,7 @@ async function scanSkillsDirectory(skillsDir2) {
|
|
|
108742
109033
|
if (skillLikeCount > 0) {
|
|
108743
109034
|
const skills = [];
|
|
108744
109035
|
for (const dir of dirs) {
|
|
108745
|
-
const categoryPath =
|
|
109036
|
+
const categoryPath = join131(skillsDir2, dir.name);
|
|
108746
109037
|
const skillDirs = await readdir39(categoryPath, { withFileTypes: true });
|
|
108747
109038
|
skills.push(...skillDirs.filter((entry) => entry.isDirectory() && !entry.name.startsWith(".")).map((entry) => entry.name));
|
|
108748
109039
|
}
|
|
@@ -108752,7 +109043,7 @@ async function scanSkillsDirectory(skillsDir2) {
|
|
|
108752
109043
|
return ["flat", dirs.map((dir) => dir.name)];
|
|
108753
109044
|
}
|
|
108754
109045
|
async function findSkillPath(skillsDir2, skillName) {
|
|
108755
|
-
const flatPath =
|
|
109046
|
+
const flatPath = join131(skillsDir2, skillName);
|
|
108756
109047
|
if (await import_fs_extra31.pathExists(flatPath)) {
|
|
108757
109048
|
return { path: flatPath, category: undefined };
|
|
108758
109049
|
}
|
|
@@ -108761,8 +109052,8 @@ async function findSkillPath(skillsDir2, skillName) {
|
|
|
108761
109052
|
if (!entry.isDirectory() || entry.name.startsWith(".") || entry.name === "node_modules") {
|
|
108762
109053
|
continue;
|
|
108763
109054
|
}
|
|
108764
|
-
const categoryPath =
|
|
108765
|
-
const skillPath =
|
|
109055
|
+
const categoryPath = join131(skillsDir2, entry.name);
|
|
109056
|
+
const skillPath = join131(categoryPath, skillName);
|
|
108766
109057
|
if (await import_fs_extra31.pathExists(skillPath)) {
|
|
108767
109058
|
return { path: skillPath, category: entry.name };
|
|
108768
109059
|
}
|
|
@@ -108856,7 +109147,7 @@ class SkillsMigrator {
|
|
|
108856
109147
|
}
|
|
108857
109148
|
}
|
|
108858
109149
|
if (options2.backup && !options2.dryRun) {
|
|
108859
|
-
const claudeDir3 =
|
|
109150
|
+
const claudeDir3 = join132(currentSkillsDir, "..");
|
|
108860
109151
|
result.backupPath = await SkillsBackupManager.createBackup(currentSkillsDir, claudeDir3);
|
|
108861
109152
|
logger.success(`Backup created at: ${result.backupPath}`);
|
|
108862
109153
|
}
|
|
@@ -108917,7 +109208,7 @@ async function handleMigration(ctx) {
|
|
|
108917
109208
|
logger.debug("Skipping skills migration (fresh installation)");
|
|
108918
109209
|
return ctx;
|
|
108919
109210
|
}
|
|
108920
|
-
const newSkillsDir =
|
|
109211
|
+
const newSkillsDir = join133(ctx.extractDir, ".claude", "skills");
|
|
108921
109212
|
const currentSkillsDir = PathResolver.buildSkillsPath(ctx.resolvedDir, ctx.options.global);
|
|
108922
109213
|
if (!await import_fs_extra32.pathExists(newSkillsDir) || !await import_fs_extra32.pathExists(currentSkillsDir)) {
|
|
108923
109214
|
return ctx;
|
|
@@ -108941,13 +109232,13 @@ async function handleMigration(ctx) {
|
|
|
108941
109232
|
}
|
|
108942
109233
|
// src/commands/init/phases/opencode-handler.ts
|
|
108943
109234
|
import { cp as cp4, readdir as readdir41, rm as rm15 } from "node:fs/promises";
|
|
108944
|
-
import { join as
|
|
109235
|
+
import { join as join135 } from "node:path";
|
|
108945
109236
|
|
|
108946
109237
|
// src/services/transformers/opencode-path-transformer.ts
|
|
108947
109238
|
init_logger();
|
|
108948
109239
|
import { readFile as readFile60, readdir as readdir40, writeFile as writeFile33 } from "node:fs/promises";
|
|
108949
109240
|
import { platform as platform15 } from "node:os";
|
|
108950
|
-
import { extname as extname6, join as
|
|
109241
|
+
import { extname as extname6, join as join134 } from "node:path";
|
|
108951
109242
|
var IS_WINDOWS2 = platform15() === "win32";
|
|
108952
109243
|
function getOpenCodeGlobalPath() {
|
|
108953
109244
|
return "$HOME/.config/opencode/";
|
|
@@ -109008,7 +109299,7 @@ async function transformPathsForGlobalOpenCode(directory, options2 = {}) {
|
|
|
109008
109299
|
async function processDirectory2(dir) {
|
|
109009
109300
|
const entries = await readdir40(dir, { withFileTypes: true });
|
|
109010
109301
|
for (const entry of entries) {
|
|
109011
|
-
const fullPath =
|
|
109302
|
+
const fullPath = join134(dir, entry.name);
|
|
109012
109303
|
if (entry.isDirectory()) {
|
|
109013
109304
|
if (entry.name === "node_modules" || entry.name.startsWith(".")) {
|
|
109014
109305
|
continue;
|
|
@@ -109047,7 +109338,7 @@ async function handleOpenCode(ctx) {
|
|
|
109047
109338
|
if (ctx.cancelled || !ctx.extractDir || !ctx.resolvedDir) {
|
|
109048
109339
|
return ctx;
|
|
109049
109340
|
}
|
|
109050
|
-
const openCodeSource =
|
|
109341
|
+
const openCodeSource = join135(ctx.extractDir, ".opencode");
|
|
109051
109342
|
if (!await import_fs_extra33.pathExists(openCodeSource)) {
|
|
109052
109343
|
logger.debug("No .opencode directory in archive, skipping");
|
|
109053
109344
|
return ctx;
|
|
@@ -109065,8 +109356,8 @@ async function handleOpenCode(ctx) {
|
|
|
109065
109356
|
await import_fs_extra33.ensureDir(targetDir);
|
|
109066
109357
|
const entries = await readdir41(openCodeSource, { withFileTypes: true });
|
|
109067
109358
|
for (const entry of entries) {
|
|
109068
|
-
const sourcePath =
|
|
109069
|
-
const targetPath =
|
|
109359
|
+
const sourcePath = join135(openCodeSource, entry.name);
|
|
109360
|
+
const targetPath = join135(targetDir, entry.name);
|
|
109070
109361
|
if (await import_fs_extra33.pathExists(targetPath)) {
|
|
109071
109362
|
if (!ctx.options.forceOverwrite) {
|
|
109072
109363
|
logger.verbose(`Skipping existing: ${entry.name}`);
|
|
@@ -109166,7 +109457,7 @@ Please use only one download method.`);
|
|
|
109166
109457
|
}
|
|
109167
109458
|
// src/commands/init/phases/post-install-handler.ts
|
|
109168
109459
|
init_projects_registry();
|
|
109169
|
-
import { join as
|
|
109460
|
+
import { join as join136 } from "node:path";
|
|
109170
109461
|
init_logger();
|
|
109171
109462
|
init_path_resolver();
|
|
109172
109463
|
var import_fs_extra34 = __toESM(require_lib(), 1);
|
|
@@ -109175,8 +109466,8 @@ async function handlePostInstall(ctx) {
|
|
|
109175
109466
|
return ctx;
|
|
109176
109467
|
}
|
|
109177
109468
|
if (ctx.options.global) {
|
|
109178
|
-
const claudeMdSource =
|
|
109179
|
-
const claudeMdDest =
|
|
109469
|
+
const claudeMdSource = join136(ctx.extractDir, "CLAUDE.md");
|
|
109470
|
+
const claudeMdDest = join136(ctx.resolvedDir, "CLAUDE.md");
|
|
109180
109471
|
if (await import_fs_extra34.pathExists(claudeMdSource)) {
|
|
109181
109472
|
if (ctx.options.fresh || !await import_fs_extra34.pathExists(claudeMdDest)) {
|
|
109182
109473
|
await import_fs_extra34.copy(claudeMdSource, claudeMdDest);
|
|
@@ -109224,7 +109515,7 @@ async function handlePostInstall(ctx) {
|
|
|
109224
109515
|
}
|
|
109225
109516
|
if (!ctx.options.skipSetup) {
|
|
109226
109517
|
await promptSetupWizardIfNeeded({
|
|
109227
|
-
envPath:
|
|
109518
|
+
envPath: join136(ctx.claudeDir, ".env"),
|
|
109228
109519
|
claudeDir: ctx.claudeDir,
|
|
109229
109520
|
isGlobal: ctx.options.global,
|
|
109230
109521
|
isNonInteractive: ctx.isNonInteractive,
|
|
@@ -109246,8 +109537,8 @@ async function handlePostInstall(ctx) {
|
|
|
109246
109537
|
}
|
|
109247
109538
|
// src/commands/init/phases/plugin-install-handler.ts
|
|
109248
109539
|
init_codex_plugin_installer();
|
|
109249
|
-
import { cpSync as cpSync2, existsSync as existsSync70, mkdirSync as mkdirSync6, readFileSync as
|
|
109250
|
-
import { join as
|
|
109540
|
+
import { cpSync as cpSync2, existsSync as existsSync70, mkdirSync as mkdirSync6, readFileSync as readFileSync24, rmSync as rmSync5, writeFileSync as writeFileSync8 } from "node:fs";
|
|
109541
|
+
import { join as join139 } from "node:path";
|
|
109251
109542
|
|
|
109252
109543
|
// src/domains/installation/plugin/migrate-legacy-to-plugin.ts
|
|
109253
109544
|
init_install_mode_detector();
|
|
@@ -109256,12 +109547,12 @@ import {
|
|
|
109256
109547
|
cpSync,
|
|
109257
109548
|
existsSync as existsSync68,
|
|
109258
109549
|
mkdirSync as mkdirSync5,
|
|
109259
|
-
readFileSync as
|
|
109550
|
+
readFileSync as readFileSync23,
|
|
109260
109551
|
readdirSync as readdirSync11,
|
|
109261
109552
|
rmSync as rmSync3,
|
|
109262
109553
|
writeFileSync as writeFileSync7
|
|
109263
109554
|
} from "node:fs";
|
|
109264
|
-
import { dirname as dirname43, join as
|
|
109555
|
+
import { dirname as dirname43, join as join137, relative as relative31, resolve as resolve45 } from "node:path";
|
|
109265
109556
|
|
|
109266
109557
|
// src/domains/installation/plugin/plugin-installer.ts
|
|
109267
109558
|
init_install_mode_detector();
|
|
@@ -109321,10 +109612,10 @@ class PluginInstaller {
|
|
|
109321
109612
|
return this.run(["plugin", "install", `${CK_PLUGIN_NAME}@${CK_MARKETPLACE_NAME}`, "--scope", scope], this.opts());
|
|
109322
109613
|
}
|
|
109323
109614
|
async enable() {
|
|
109324
|
-
return this.run(["plugin", "enable", CK_PLUGIN_NAME], this.opts());
|
|
109615
|
+
return this.run(["plugin", "enable", `${CK_PLUGIN_NAME}@${CK_MARKETPLACE_NAME}`], this.opts());
|
|
109325
109616
|
}
|
|
109326
109617
|
async update() {
|
|
109327
|
-
return this.run(["plugin", "update", CK_PLUGIN_NAME], this.opts());
|
|
109618
|
+
return this.run(["plugin", "update", `${CK_PLUGIN_NAME}@${CK_MARKETPLACE_NAME}`], this.opts());
|
|
109328
109619
|
}
|
|
109329
109620
|
async uninstall() {
|
|
109330
109621
|
return this.run(["plugin", "uninstall", CK_PLUGIN_NAME], this.opts());
|
|
@@ -109386,7 +109677,7 @@ async function migrateLegacyToPlugin(opts) {
|
|
|
109386
109677
|
let backupDir = null;
|
|
109387
109678
|
let removedPaths = [];
|
|
109388
109679
|
if (before.legacy.installed) {
|
|
109389
|
-
backupDir =
|
|
109680
|
+
backupDir = join137(claudeDir3, "backups", `ck-legacy-${ts.replace(/[:.]/g, "-")}`);
|
|
109390
109681
|
mkdirSync5(backupDir, { recursive: true });
|
|
109391
109682
|
removedPaths = removeLegacy(claudeDir3, backupDir);
|
|
109392
109683
|
}
|
|
@@ -109421,7 +109712,7 @@ function base(action, modeBefore, pluginVerified) {
|
|
|
109421
109712
|
var PLUGIN_SUPPLIED_LEGACY_PREFIXES2 = ["agents/", "skills/"];
|
|
109422
109713
|
var LEGACY_SENTINEL_FILENAMES = new Set([".gitignore"]);
|
|
109423
109714
|
function defaultLegacyRemover(claudeDir3, backupDir) {
|
|
109424
|
-
const meta = readJsonSafe3(
|
|
109715
|
+
const meta = readJsonSafe3(join137(claudeDir3, "metadata.json"));
|
|
109425
109716
|
const files = collectTrackedFiles2(meta);
|
|
109426
109717
|
const removed = [];
|
|
109427
109718
|
for (const file of files) {
|
|
@@ -109459,7 +109750,7 @@ function removeOrphanLegacySentinels(claudeDir3, backupDir, removedTrackedPaths)
|
|
|
109459
109750
|
}
|
|
109460
109751
|
const removed = [];
|
|
109461
109752
|
for (const root of [...rootsToSweep].sort(compareLegacyPaths)) {
|
|
109462
|
-
const rootAbs =
|
|
109753
|
+
const rootAbs = join137(claudeDir3, root);
|
|
109463
109754
|
if (!existsSync68(rootAbs))
|
|
109464
109755
|
continue;
|
|
109465
109756
|
const sentinels = findLegacySentinels(rootAbs).sort((a3, b3) => compareLegacyPaths(relative31(claudeDir3, a3), relative31(claudeDir3, b3)));
|
|
@@ -109483,7 +109774,7 @@ function findLegacySentinels(dir) {
|
|
|
109483
109774
|
return out;
|
|
109484
109775
|
}
|
|
109485
109776
|
for (const entry of entries.sort((a3, b3) => compareLegacyPaths(a3.name, b3.name))) {
|
|
109486
|
-
const abs =
|
|
109777
|
+
const abs = join137(dir, entry.name);
|
|
109487
109778
|
if (entry.isDirectory()) {
|
|
109488
109779
|
out.push(...findLegacySentinels(abs));
|
|
109489
109780
|
} else if (entry.isFile() && LEGACY_SENTINEL_FILENAMES.has(entry.name)) {
|
|
@@ -109511,7 +109802,7 @@ function directoryContainsOnlySentinels(dir) {
|
|
|
109511
109802
|
return false;
|
|
109512
109803
|
}
|
|
109513
109804
|
for (const entry of entries) {
|
|
109514
|
-
const abs =
|
|
109805
|
+
const abs = join137(dir, entry.name);
|
|
109515
109806
|
if (entry.isDirectory()) {
|
|
109516
109807
|
if (!directoryContainsOnlySentinels(abs))
|
|
109517
109808
|
return false;
|
|
@@ -109532,7 +109823,7 @@ function checksumMatches2(filePath, expected) {
|
|
|
109532
109823
|
return false;
|
|
109533
109824
|
}
|
|
109534
109825
|
try {
|
|
109535
|
-
const actual = createHash10("sha256").update(
|
|
109826
|
+
const actual = createHash10("sha256").update(readFileSync23(filePath)).digest("hex");
|
|
109536
109827
|
return actual.toLowerCase() === expected.toLowerCase();
|
|
109537
109828
|
} catch {
|
|
109538
109829
|
return false;
|
|
@@ -109586,14 +109877,14 @@ function compareLegacyPaths(a3, b3) {
|
|
|
109586
109877
|
return 0;
|
|
109587
109878
|
}
|
|
109588
109879
|
function collectTrackedFiles2(meta) {
|
|
109589
|
-
if (!
|
|
109880
|
+
if (!isRecord5(meta))
|
|
109590
109881
|
return [];
|
|
109591
109882
|
const out = [];
|
|
109592
109883
|
const push2 = (arr) => {
|
|
109593
109884
|
if (!Array.isArray(arr))
|
|
109594
109885
|
return;
|
|
109595
109886
|
for (const f3 of arr) {
|
|
109596
|
-
if (
|
|
109887
|
+
if (isRecord5(f3) && typeof f3.path === "string") {
|
|
109597
109888
|
const ownership = f3.ownership === "user" || f3.ownership === "ck-modified" ? f3.ownership : "ck";
|
|
109598
109889
|
out.push({
|
|
109599
109890
|
path: f3.path,
|
|
@@ -109603,9 +109894,9 @@ function collectTrackedFiles2(meta) {
|
|
|
109603
109894
|
}
|
|
109604
109895
|
}
|
|
109605
109896
|
};
|
|
109606
|
-
if (
|
|
109897
|
+
if (isRecord5(meta.kits)) {
|
|
109607
109898
|
const engineer = meta.kits[ENGINEER_KIT_KEY];
|
|
109608
|
-
if (
|
|
109899
|
+
if (isRecord5(engineer))
|
|
109609
109900
|
push2(engineer.files);
|
|
109610
109901
|
} else {
|
|
109611
109902
|
push2(meta.files);
|
|
@@ -109613,7 +109904,7 @@ function collectTrackedFiles2(meta) {
|
|
|
109613
109904
|
return out;
|
|
109614
109905
|
}
|
|
109615
109906
|
function writeReceipt(claudeDir3, receipt) {
|
|
109616
|
-
const receiptPath =
|
|
109907
|
+
const receiptPath = join137(claudeDir3, ".ck-migration-log.json");
|
|
109617
109908
|
const existing = readJsonSafe3(receiptPath);
|
|
109618
109909
|
const history = Array.isArray(existing) ? existing : [];
|
|
109619
109910
|
history.push(receipt);
|
|
@@ -109623,7 +109914,7 @@ function writeReceipt(claudeDir3, receipt) {
|
|
|
109623
109914
|
}
|
|
109624
109915
|
function readJsonSafe3(filePath) {
|
|
109625
109916
|
try {
|
|
109626
|
-
return JSON.parse(
|
|
109917
|
+
return JSON.parse(readFileSync23(filePath, "utf-8"));
|
|
109627
109918
|
} catch {
|
|
109628
109919
|
return null;
|
|
109629
109920
|
}
|
|
@@ -109662,14 +109953,14 @@ async function refreshExistingPlugin(installer, pluginSourceDir, enabled) {
|
|
|
109662
109953
|
}
|
|
109663
109954
|
return { ok: true };
|
|
109664
109955
|
}
|
|
109665
|
-
function
|
|
109956
|
+
function isRecord5(value) {
|
|
109666
109957
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
109667
109958
|
}
|
|
109668
109959
|
|
|
109669
109960
|
// src/domains/installation/plugin/uninstall-plugin.ts
|
|
109670
109961
|
init_install_mode_detector();
|
|
109671
109962
|
import { existsSync as existsSync69, rmSync as rmSync4 } from "node:fs";
|
|
109672
|
-
import { join as
|
|
109963
|
+
import { join as join138 } from "node:path";
|
|
109673
109964
|
init_path_resolver();
|
|
109674
109965
|
async function uninstallEnginePlugin(opts = {}) {
|
|
109675
109966
|
const claudeDir3 = opts.claudeDir ?? PathResolver.getGlobalKitDir();
|
|
@@ -109691,7 +109982,7 @@ async function uninstallEnginePlugin(opts = {}) {
|
|
|
109691
109982
|
}
|
|
109692
109983
|
let staleCacheRemoved = false;
|
|
109693
109984
|
const marketplace = state.marketplace ?? CK_MARKETPLACE_NAME;
|
|
109694
|
-
const cacheDir =
|
|
109985
|
+
const cacheDir = join138(claudeDir3, "plugins", "cache", marketplace, CK_PLUGIN_NAME);
|
|
109695
109986
|
if (existsSync69(cacheDir)) {
|
|
109696
109987
|
rmSync4(cacheDir, { recursive: true, force: true });
|
|
109697
109988
|
staleCacheRemoved = true;
|
|
@@ -109735,8 +110026,12 @@ async function handlePluginInstall(ctx, deps = {}) {
|
|
|
109735
110026
|
try {
|
|
109736
110027
|
const result = await removeCodex();
|
|
109737
110028
|
logCodexPluginCleanup(result);
|
|
110029
|
+
if (result.pluginStillInstalled) {
|
|
110030
|
+
cleanupError = new Error(`Codex plugin cleanup failed for legacy install mode: ${result.error ?? "plugin remains registered"}`);
|
|
110031
|
+
}
|
|
109738
110032
|
} catch (err) {
|
|
109739
110033
|
logger.verbose(`Codex plugin cleanup skipped: ${err.message}`);
|
|
110034
|
+
cleanupError = err;
|
|
109740
110035
|
}
|
|
109741
110036
|
if (cleanupError) {
|
|
109742
110037
|
throw cleanupError;
|
|
@@ -109760,7 +110055,13 @@ async function handlePluginInstall(ctx, deps = {}) {
|
|
|
109760
110055
|
try {
|
|
109761
110056
|
const result = await installCodex({ pluginSourceDir });
|
|
109762
110057
|
logCodexPluginResult(result);
|
|
110058
|
+
if (ctx.options.installMode === "plugin" && result.action === "install-failed") {
|
|
110059
|
+
throw new Error(`Codex plugin install failed: ${result.error ?? result.action}`);
|
|
110060
|
+
}
|
|
109763
110061
|
} catch (err) {
|
|
110062
|
+
if (ctx.options.installMode === "plugin") {
|
|
110063
|
+
throw err;
|
|
110064
|
+
}
|
|
109764
110065
|
logger.verbose(`Codex plugin install skipped: ${err.message}`);
|
|
109765
110066
|
}
|
|
109766
110067
|
} catch (err) {
|
|
@@ -109779,14 +110080,14 @@ function logLegacyPluginCleanup(result) {
|
|
|
109779
110080
|
}
|
|
109780
110081
|
}
|
|
109781
110082
|
function stagePluginSource(extractDir, stageBaseDir) {
|
|
109782
|
-
const base2 = stageBaseDir ??
|
|
109783
|
-
const payloadSrc =
|
|
110083
|
+
const base2 = stageBaseDir ?? join139(PathResolver.getCacheDir(true), "ck-plugin-source");
|
|
110084
|
+
const payloadSrc = join139(extractDir, ".claude");
|
|
109784
110085
|
if (!existsSync70(payloadSrc)) {
|
|
109785
110086
|
throw new Error(`plugin payload not found in archive: ${payloadSrc}`);
|
|
109786
110087
|
}
|
|
109787
110088
|
rmSync5(base2, { recursive: true, force: true });
|
|
109788
110089
|
mkdirSync6(base2, { recursive: true });
|
|
109789
|
-
const stagedPayload =
|
|
110090
|
+
const stagedPayload = join139(base2, ".claude");
|
|
109790
110091
|
cpSync2(payloadSrc, stagedPayload, { recursive: true });
|
|
109791
110092
|
ensureCodexPluginManifest(stagedPayload);
|
|
109792
110093
|
const claudeMarketplace = {
|
|
@@ -109794,8 +110095,8 @@ function stagePluginSource(extractDir, stageBaseDir) {
|
|
|
109794
110095
|
owner: { name: "ClaudeKit" },
|
|
109795
110096
|
plugins: [{ name: "ck", source: "./.claude", description: "ClaudeKit Engineer" }]
|
|
109796
110097
|
};
|
|
109797
|
-
mkdirSync6(
|
|
109798
|
-
writeFileSync8(
|
|
110098
|
+
mkdirSync6(join139(base2, ".claude-plugin"), { recursive: true });
|
|
110099
|
+
writeFileSync8(join139(base2, ".claude-plugin", "marketplace.json"), `${JSON.stringify(claudeMarketplace, null, 2)}
|
|
109799
110100
|
`, "utf-8");
|
|
109800
110101
|
const codexMarketplace = {
|
|
109801
110102
|
name: "claudekit",
|
|
@@ -109809,24 +110110,24 @@ function stagePluginSource(extractDir, stageBaseDir) {
|
|
|
109809
110110
|
}
|
|
109810
110111
|
]
|
|
109811
110112
|
};
|
|
109812
|
-
mkdirSync6(
|
|
109813
|
-
writeFileSync8(
|
|
110113
|
+
mkdirSync6(join139(base2, ".agents", "plugins"), { recursive: true });
|
|
110114
|
+
writeFileSync8(join139(base2, ".agents", "plugins", "marketplace.json"), `${JSON.stringify(codexMarketplace, null, 2)}
|
|
109814
110115
|
`, "utf-8");
|
|
109815
110116
|
return base2;
|
|
109816
110117
|
}
|
|
109817
110118
|
function ensureCodexPluginManifest(pluginRoot) {
|
|
109818
|
-
const manifestPath =
|
|
110119
|
+
const manifestPath = join139(pluginRoot, ".codex-plugin", "plugin.json");
|
|
109819
110120
|
if (existsSync70(manifestPath))
|
|
109820
110121
|
return;
|
|
109821
|
-
const claudeManifest = readJsonSafe4(
|
|
110122
|
+
const claudeManifest = readJsonSafe4(join139(pluginRoot, ".claude-plugin", "plugin.json"));
|
|
109822
110123
|
const manifest = pruneUndefined({
|
|
109823
|
-
name:
|
|
109824
|
-
version:
|
|
109825
|
-
description:
|
|
110124
|
+
name: stringField2(claudeManifest, "name") ?? "ck",
|
|
110125
|
+
version: stringField2(claudeManifest, "version") ?? "0.0.0",
|
|
110126
|
+
description: stringField2(claudeManifest, "description") ?? "ClaudeKit Engineer — multi-agent planning, code review, debugging, and workflow skills for Codex.",
|
|
109826
110127
|
author: authorField(claudeManifest),
|
|
109827
|
-
homepage:
|
|
109828
|
-
repository:
|
|
109829
|
-
license:
|
|
110128
|
+
homepage: stringField2(claudeManifest, "homepage"),
|
|
110129
|
+
repository: stringField2(claudeManifest, "repository"),
|
|
110130
|
+
license: stringField2(claudeManifest, "license"),
|
|
109830
110131
|
keywords: ["claudekit", "codex", "skills", "agents", "workflow"],
|
|
109831
110132
|
skills: "./skills/",
|
|
109832
110133
|
interface: {
|
|
@@ -109839,25 +110140,25 @@ function ensureCodexPluginManifest(pluginRoot) {
|
|
|
109839
110140
|
websiteURL: "https://github.com/claudekit/claudekit-engineer"
|
|
109840
110141
|
}
|
|
109841
110142
|
});
|
|
109842
|
-
mkdirSync6(
|
|
110143
|
+
mkdirSync6(join139(pluginRoot, ".codex-plugin"), { recursive: true });
|
|
109843
110144
|
writeFileSync8(manifestPath, `${JSON.stringify(manifest, null, 2)}
|
|
109844
110145
|
`, "utf-8");
|
|
109845
110146
|
}
|
|
109846
110147
|
function readJsonSafe4(filePath) {
|
|
109847
110148
|
try {
|
|
109848
|
-
const parsed = JSON.parse(
|
|
109849
|
-
return
|
|
110149
|
+
const parsed = JSON.parse(readFileSync24(filePath, "utf-8"));
|
|
110150
|
+
return isRecord6(parsed) ? parsed : null;
|
|
109850
110151
|
} catch {
|
|
109851
110152
|
return null;
|
|
109852
110153
|
}
|
|
109853
110154
|
}
|
|
109854
|
-
function
|
|
110155
|
+
function stringField2(source, key) {
|
|
109855
110156
|
const value = source?.[key];
|
|
109856
110157
|
return typeof value === "string" && value.trim() !== "" ? value : undefined;
|
|
109857
110158
|
}
|
|
109858
110159
|
function authorField(source) {
|
|
109859
110160
|
const author = source?.author;
|
|
109860
|
-
if (
|
|
110161
|
+
if (isRecord6(author) && typeof author.name === "string" && author.name.trim() !== "") {
|
|
109861
110162
|
return { name: author.name };
|
|
109862
110163
|
}
|
|
109863
110164
|
return { name: "ClaudeKit" };
|
|
@@ -109865,7 +110166,7 @@ function authorField(source) {
|
|
|
109865
110166
|
function pruneUndefined(value) {
|
|
109866
110167
|
return Object.fromEntries(Object.entries(value).filter(([, entry]) => entry !== undefined));
|
|
109867
110168
|
}
|
|
109868
|
-
function
|
|
110169
|
+
function isRecord6(value) {
|
|
109869
110170
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
109870
110171
|
}
|
|
109871
110172
|
function logPluginResult(result) {
|
|
@@ -109911,7 +110212,7 @@ function logCodexPluginCleanup(result) {
|
|
|
109911
110212
|
init_config_manager();
|
|
109912
110213
|
init_github_client();
|
|
109913
110214
|
import { mkdir as mkdir36 } from "node:fs/promises";
|
|
109914
|
-
import { join as
|
|
110215
|
+
import { join as join142, resolve as resolve48 } from "node:path";
|
|
109915
110216
|
|
|
109916
110217
|
// src/domains/github/kit-access-checker.ts
|
|
109917
110218
|
init_error2();
|
|
@@ -110084,7 +110385,7 @@ init_hook_health_checker();
|
|
|
110084
110385
|
// src/domains/installation/fresh-installer.ts
|
|
110085
110386
|
init_metadata_migration();
|
|
110086
110387
|
import { existsSync as existsSync71, readdirSync as readdirSync12, rmSync as rmSync6, rmdirSync as rmdirSync2, unlinkSync as unlinkSync5 } from "node:fs";
|
|
110087
|
-
import { basename as basename28, dirname as dirname44, join as
|
|
110388
|
+
import { basename as basename28, dirname as dirname44, join as join140, resolve as resolve46 } from "node:path";
|
|
110088
110389
|
init_logger();
|
|
110089
110390
|
init_safe_spinner();
|
|
110090
110391
|
var import_fs_extra35 = __toESM(require_lib(), 1);
|
|
@@ -110166,7 +110467,7 @@ async function removeFilesByOwnership(claudeDir3, analysis, includeModified) {
|
|
|
110166
110467
|
logger.debug(`${KIT_MANIFEST_FILE} was self-tracked; skipping from delete loop — will be rewritten by updateMetadataAfterFresh`);
|
|
110167
110468
|
}
|
|
110168
110469
|
for (const file of filesToRemove) {
|
|
110169
|
-
const fullPath =
|
|
110470
|
+
const fullPath = join140(claudeDir3, file.path);
|
|
110170
110471
|
if (!existsSync71(fullPath)) {
|
|
110171
110472
|
continue;
|
|
110172
110473
|
}
|
|
@@ -110194,7 +110495,7 @@ async function removeFilesByOwnership(claudeDir3, analysis, includeModified) {
|
|
|
110194
110495
|
};
|
|
110195
110496
|
}
|
|
110196
110497
|
async function updateMetadataAfterFresh(claudeDir3, removedFiles, metadata) {
|
|
110197
|
-
const metadataPath =
|
|
110498
|
+
const metadataPath = join140(claudeDir3, KIT_MANIFEST_FILE);
|
|
110198
110499
|
const removedSet = new Set(removedFiles);
|
|
110199
110500
|
if (metadata.kits) {
|
|
110200
110501
|
for (const kitName of Object.keys(metadata.kits)) {
|
|
@@ -110225,8 +110526,8 @@ function getFreshBackupTargets(claudeDir3, analysis, includeModified) {
|
|
|
110225
110526
|
mutatePaths: filesToRemove.length > 0 ? ["metadata.json"] : []
|
|
110226
110527
|
};
|
|
110227
110528
|
}
|
|
110228
|
-
const deletePaths = CLAUDEKIT_SUBDIRECTORIES.filter((subdir) => existsSync71(
|
|
110229
|
-
if (existsSync71(
|
|
110529
|
+
const deletePaths = CLAUDEKIT_SUBDIRECTORIES.filter((subdir) => existsSync71(join140(claudeDir3, subdir)));
|
|
110530
|
+
if (existsSync71(join140(claudeDir3, "metadata.json"))) {
|
|
110230
110531
|
deletePaths.push("metadata.json");
|
|
110231
110532
|
}
|
|
110232
110533
|
return {
|
|
@@ -110248,7 +110549,7 @@ async function removeSubdirectoriesFallback(claudeDir3) {
|
|
|
110248
110549
|
const removedFiles = [];
|
|
110249
110550
|
let removedDirCount = 0;
|
|
110250
110551
|
for (const subdir of CLAUDEKIT_SUBDIRECTORIES) {
|
|
110251
|
-
const subdirPath =
|
|
110552
|
+
const subdirPath = join140(claudeDir3, subdir);
|
|
110252
110553
|
if (await import_fs_extra35.pathExists(subdirPath)) {
|
|
110253
110554
|
rmSync6(subdirPath, { recursive: true, force: true });
|
|
110254
110555
|
removedDirCount++;
|
|
@@ -110256,7 +110557,7 @@ async function removeSubdirectoriesFallback(claudeDir3) {
|
|
|
110256
110557
|
logger.debug(`Removed subdirectory: ${subdir}/`);
|
|
110257
110558
|
}
|
|
110258
110559
|
}
|
|
110259
|
-
const metadataPath =
|
|
110560
|
+
const metadataPath = join140(claudeDir3, "metadata.json");
|
|
110260
110561
|
if (await import_fs_extra35.pathExists(metadataPath)) {
|
|
110261
110562
|
unlinkSync5(metadataPath);
|
|
110262
110563
|
removedFiles.push("metadata.json");
|
|
@@ -110334,7 +110635,7 @@ async function handleFreshInstallation(claudeDir3, prompts) {
|
|
|
110334
110635
|
var import_fs_extra36 = __toESM(require_lib(), 1);
|
|
110335
110636
|
import { cp as cp5, mkdir as mkdir35, readdir as readdir42, rename as rename11, rm as rm16, stat as stat22 } from "node:fs/promises";
|
|
110336
110637
|
import { homedir as homedir47 } from "node:os";
|
|
110337
|
-
import { dirname as dirname45, join as
|
|
110638
|
+
import { dirname as dirname45, join as join141, normalize as normalize11, resolve as resolve47 } from "node:path";
|
|
110338
110639
|
var LEGACY_KIT_MARKERS = [
|
|
110339
110640
|
"metadata.json",
|
|
110340
110641
|
".ck.json",
|
|
@@ -110373,10 +110674,10 @@ function getLegacyWindowsGlobalKitDirCandidates(env2 = process.env, homeDir = ho
|
|
|
110373
110674
|
const localAppData = safeEnvPath(env2.LOCALAPPDATA);
|
|
110374
110675
|
const appData = safeEnvPath(env2.APPDATA);
|
|
110375
110676
|
if (localAppData) {
|
|
110376
|
-
candidates.push(
|
|
110677
|
+
candidates.push(join141(localAppData, ".claude"));
|
|
110377
110678
|
}
|
|
110378
110679
|
if (appData) {
|
|
110379
|
-
candidates.push(
|
|
110680
|
+
candidates.push(join141(appData, ".claude"));
|
|
110380
110681
|
}
|
|
110381
110682
|
if (homeDir) {
|
|
110382
110683
|
candidates.push(`${withoutTrailingSeparators(homeDir)}.claude`);
|
|
@@ -110394,7 +110695,7 @@ async function hasKitMarkers(dir) {
|
|
|
110394
110695
|
if (!await isDirectory(dir))
|
|
110395
110696
|
return false;
|
|
110396
110697
|
for (const marker of LEGACY_KIT_MARKERS) {
|
|
110397
|
-
if (await import_fs_extra36.pathExists(
|
|
110698
|
+
if (await import_fs_extra36.pathExists(join141(dir, marker))) {
|
|
110398
110699
|
return true;
|
|
110399
110700
|
}
|
|
110400
110701
|
}
|
|
@@ -110696,7 +110997,7 @@ async function handleSelection(ctx) {
|
|
|
110696
110997
|
}
|
|
110697
110998
|
if (!ctx.options.fresh) {
|
|
110698
110999
|
const prefix = PathResolver.getPathPrefix(ctx.options.global);
|
|
110699
|
-
const claudeDir3 = prefix ?
|
|
111000
|
+
const claudeDir3 = prefix ? join142(resolvedDir, prefix) : resolvedDir;
|
|
110700
111001
|
try {
|
|
110701
111002
|
const existingMetadata = await readManifest(claudeDir3);
|
|
110702
111003
|
if (existingMetadata?.kits) {
|
|
@@ -110733,7 +111034,7 @@ async function handleSelection(ctx) {
|
|
|
110733
111034
|
}
|
|
110734
111035
|
if (ctx.options.fresh) {
|
|
110735
111036
|
const prefix = PathResolver.getPathPrefix(ctx.options.global);
|
|
110736
|
-
const claudeDir3 = prefix ?
|
|
111037
|
+
const claudeDir3 = prefix ? join142(resolvedDir, prefix) : resolvedDir;
|
|
110737
111038
|
const canProceed = await handleFreshInstallation(claudeDir3, ctx.prompts);
|
|
110738
111039
|
if (!canProceed) {
|
|
110739
111040
|
return { ...ctx, cancelled: true };
|
|
@@ -110753,7 +111054,7 @@ async function handleSelection(ctx) {
|
|
|
110753
111054
|
let currentVersion = null;
|
|
110754
111055
|
try {
|
|
110755
111056
|
const prefix = PathResolver.getPathPrefix(ctx.options.global);
|
|
110756
|
-
const claudeDir3 = prefix ?
|
|
111057
|
+
const claudeDir3 = prefix ? join142(resolvedDir, prefix) : resolvedDir;
|
|
110757
111058
|
const existingMetadata = await readManifest(claudeDir3);
|
|
110758
111059
|
currentVersion = existingMetadata?.kits?.[kitType]?.version || null;
|
|
110759
111060
|
if (currentVersion) {
|
|
@@ -110822,7 +111123,7 @@ async function handleSelection(ctx) {
|
|
|
110822
111123
|
if (ctx.options.yes && !ctx.options.fresh && !ctx.options.force && !ctx.options.restoreCkHooks && releaseTag && !isOfflineMode && !pendingKits?.length) {
|
|
110823
111124
|
try {
|
|
110824
111125
|
const prefix = PathResolver.getPathPrefix(ctx.options.global);
|
|
110825
|
-
const claudeDir3 = prefix ?
|
|
111126
|
+
const claudeDir3 = prefix ? join142(resolvedDir, prefix) : resolvedDir;
|
|
110826
111127
|
const existingMetadata = await readManifest(claudeDir3);
|
|
110827
111128
|
const installedKitVersion = existingMetadata?.kits?.[kitType]?.version;
|
|
110828
111129
|
if (installedKitVersion && versionsMatch(installedKitVersion, releaseTag)) {
|
|
@@ -110851,7 +111152,7 @@ async function handleSelection(ctx) {
|
|
|
110851
111152
|
}
|
|
110852
111153
|
// src/commands/init/phases/sync-handler.ts
|
|
110853
111154
|
import { copyFile as copyFile8, mkdir as mkdir37, open as open5, readFile as readFile61, rename as rename12, stat as stat23, unlink as unlink13, writeFile as writeFile35 } from "node:fs/promises";
|
|
110854
|
-
import { dirname as dirname46, join as
|
|
111155
|
+
import { dirname as dirname46, join as join143, resolve as resolve49 } from "node:path";
|
|
110855
111156
|
init_logger();
|
|
110856
111157
|
init_path_resolver();
|
|
110857
111158
|
var import_fs_extra38 = __toESM(require_lib(), 1);
|
|
@@ -110861,13 +111162,13 @@ async function handleSync(ctx) {
|
|
|
110861
111162
|
return ctx;
|
|
110862
111163
|
}
|
|
110863
111164
|
const resolvedDir = ctx.options.global ? PathResolver.getGlobalKitDir() : resolve49(ctx.options.dir || ".");
|
|
110864
|
-
const claudeDir3 = ctx.options.global ? resolvedDir :
|
|
111165
|
+
const claudeDir3 = ctx.options.global ? resolvedDir : join143(resolvedDir, ".claude");
|
|
110865
111166
|
if (!await import_fs_extra38.pathExists(claudeDir3)) {
|
|
110866
111167
|
logger.error("Cannot sync: no .claude directory found");
|
|
110867
111168
|
ctx.prompts.note("Run 'ck init' without --sync to install first.", "No Installation Found");
|
|
110868
111169
|
return { ...ctx, cancelled: true };
|
|
110869
111170
|
}
|
|
110870
|
-
const metadataPath =
|
|
111171
|
+
const metadataPath = join143(claudeDir3, "metadata.json");
|
|
110871
111172
|
if (!await import_fs_extra38.pathExists(metadataPath)) {
|
|
110872
111173
|
logger.error("Cannot sync: no metadata.json found");
|
|
110873
111174
|
ctx.prompts.note(`Your installation may be from an older version.
|
|
@@ -110967,7 +111268,7 @@ function getLockTimeout() {
|
|
|
110967
111268
|
var STALE_LOCK_THRESHOLD_MS = 5 * 60 * 1000;
|
|
110968
111269
|
async function acquireSyncLock(global3) {
|
|
110969
111270
|
const cacheDir = PathResolver.getCacheDir(global3);
|
|
110970
|
-
const lockPath =
|
|
111271
|
+
const lockPath = join143(cacheDir, ".sync-lock");
|
|
110971
111272
|
const startTime = Date.now();
|
|
110972
111273
|
const lockTimeout = getLockTimeout();
|
|
110973
111274
|
await mkdir37(dirname46(lockPath), { recursive: true });
|
|
@@ -111013,11 +111314,11 @@ async function executeSyncMerge(ctx) {
|
|
|
111013
111314
|
const releaseLock = await acquireSyncLock(ctx.options.global);
|
|
111014
111315
|
try {
|
|
111015
111316
|
const trackedFiles = ctx.syncTrackedFiles;
|
|
111016
|
-
const upstreamDir = ctx.options.global ?
|
|
111317
|
+
const upstreamDir = ctx.options.global ? join143(ctx.extractDir, ".claude") : ctx.extractDir;
|
|
111017
111318
|
let sourceMetadata = null;
|
|
111018
111319
|
let deletions = [];
|
|
111019
111320
|
try {
|
|
111020
|
-
const sourceMetadataPath =
|
|
111321
|
+
const sourceMetadataPath = join143(upstreamDir, "metadata.json");
|
|
111021
111322
|
if (await import_fs_extra38.pathExists(sourceMetadataPath)) {
|
|
111022
111323
|
const content = await readFile61(sourceMetadataPath, "utf-8");
|
|
111023
111324
|
sourceMetadata = JSON.parse(content);
|
|
@@ -111079,7 +111380,7 @@ async function executeSyncMerge(ctx) {
|
|
|
111079
111380
|
try {
|
|
111080
111381
|
const sourcePath = await validateSyncPath(upstreamDir, file.path);
|
|
111081
111382
|
const targetPath = await validateSyncPath(ctx.claudeDir, file.path);
|
|
111082
|
-
const targetDir =
|
|
111383
|
+
const targetDir = join143(targetPath, "..");
|
|
111083
111384
|
try {
|
|
111084
111385
|
await mkdir37(targetDir, { recursive: true });
|
|
111085
111386
|
} catch (mkdirError) {
|
|
@@ -111250,7 +111551,7 @@ async function createBackup(claudeDir3, files, backupDir) {
|
|
|
111250
111551
|
const sourcePath = await validateSyncPath(claudeDir3, file.path);
|
|
111251
111552
|
if (await import_fs_extra38.pathExists(sourcePath)) {
|
|
111252
111553
|
const targetPath = await validateSyncPath(backupDir, file.path);
|
|
111253
|
-
const targetDir =
|
|
111554
|
+
const targetDir = join143(targetPath, "..");
|
|
111254
111555
|
await mkdir37(targetDir, { recursive: true });
|
|
111255
111556
|
await copyFile8(sourcePath, targetPath);
|
|
111256
111557
|
}
|
|
@@ -111265,7 +111566,7 @@ async function createBackup(claudeDir3, files, backupDir) {
|
|
|
111265
111566
|
}
|
|
111266
111567
|
// src/commands/init/phases/transform-handler.ts
|
|
111267
111568
|
init_config_manager();
|
|
111268
|
-
import { join as
|
|
111569
|
+
import { join as join147 } from "node:path";
|
|
111269
111570
|
|
|
111270
111571
|
// src/services/transformers/folder-path-transformer.ts
|
|
111271
111572
|
init_logger();
|
|
@@ -111276,38 +111577,38 @@ init_logger();
|
|
|
111276
111577
|
init_types3();
|
|
111277
111578
|
var import_fs_extra39 = __toESM(require_lib(), 1);
|
|
111278
111579
|
import { rename as rename13, rm as rm17 } from "node:fs/promises";
|
|
111279
|
-
import { join as
|
|
111580
|
+
import { join as join144, relative as relative32 } from "node:path";
|
|
111280
111581
|
async function collectDirsToRename(extractDir, folders) {
|
|
111281
111582
|
const dirsToRename = [];
|
|
111282
111583
|
if (folders.docs !== DEFAULT_FOLDERS.docs) {
|
|
111283
|
-
const docsPath =
|
|
111584
|
+
const docsPath = join144(extractDir, DEFAULT_FOLDERS.docs);
|
|
111284
111585
|
if (await import_fs_extra39.pathExists(docsPath)) {
|
|
111285
111586
|
dirsToRename.push({
|
|
111286
111587
|
from: docsPath,
|
|
111287
|
-
to:
|
|
111588
|
+
to: join144(extractDir, folders.docs)
|
|
111288
111589
|
});
|
|
111289
111590
|
}
|
|
111290
|
-
const claudeDocsPath =
|
|
111591
|
+
const claudeDocsPath = join144(extractDir, ".claude", DEFAULT_FOLDERS.docs);
|
|
111291
111592
|
if (await import_fs_extra39.pathExists(claudeDocsPath)) {
|
|
111292
111593
|
dirsToRename.push({
|
|
111293
111594
|
from: claudeDocsPath,
|
|
111294
|
-
to:
|
|
111595
|
+
to: join144(extractDir, ".claude", folders.docs)
|
|
111295
111596
|
});
|
|
111296
111597
|
}
|
|
111297
111598
|
}
|
|
111298
111599
|
if (folders.plans !== DEFAULT_FOLDERS.plans) {
|
|
111299
|
-
const plansPath =
|
|
111600
|
+
const plansPath = join144(extractDir, DEFAULT_FOLDERS.plans);
|
|
111300
111601
|
if (await import_fs_extra39.pathExists(plansPath)) {
|
|
111301
111602
|
dirsToRename.push({
|
|
111302
111603
|
from: plansPath,
|
|
111303
|
-
to:
|
|
111604
|
+
to: join144(extractDir, folders.plans)
|
|
111304
111605
|
});
|
|
111305
111606
|
}
|
|
111306
|
-
const claudePlansPath =
|
|
111607
|
+
const claudePlansPath = join144(extractDir, ".claude", DEFAULT_FOLDERS.plans);
|
|
111307
111608
|
if (await import_fs_extra39.pathExists(claudePlansPath)) {
|
|
111308
111609
|
dirsToRename.push({
|
|
111309
111610
|
from: claudePlansPath,
|
|
111310
|
-
to:
|
|
111611
|
+
to: join144(extractDir, ".claude", folders.plans)
|
|
111311
111612
|
});
|
|
111312
111613
|
}
|
|
111313
111614
|
}
|
|
@@ -111348,7 +111649,7 @@ async function renameFolders(dirsToRename, extractDir, options2) {
|
|
|
111348
111649
|
init_logger();
|
|
111349
111650
|
init_types3();
|
|
111350
111651
|
import { readFile as readFile62, readdir as readdir43, writeFile as writeFile36 } from "node:fs/promises";
|
|
111351
|
-
import { join as
|
|
111652
|
+
import { join as join145, relative as relative33 } from "node:path";
|
|
111352
111653
|
var TRANSFORMABLE_FILE_PATTERNS = [
|
|
111353
111654
|
".md",
|
|
111354
111655
|
".txt",
|
|
@@ -111401,7 +111702,7 @@ async function transformFileContents(dir, compiledReplacements, options2) {
|
|
|
111401
111702
|
let replacementsCount = 0;
|
|
111402
111703
|
const entries = await readdir43(dir, { withFileTypes: true });
|
|
111403
111704
|
for (const entry of entries) {
|
|
111404
|
-
const fullPath =
|
|
111705
|
+
const fullPath = join145(dir, entry.name);
|
|
111405
111706
|
if (entry.isDirectory()) {
|
|
111406
111707
|
if (entry.name === "node_modules" || entry.name === ".git") {
|
|
111407
111708
|
continue;
|
|
@@ -111538,7 +111839,7 @@ async function transformFolderPaths(extractDir, folders, options2 = {}) {
|
|
|
111538
111839
|
init_logger();
|
|
111539
111840
|
import { readFile as readFile63, readdir as readdir44, writeFile as writeFile37 } from "node:fs/promises";
|
|
111540
111841
|
import { homedir as homedir48, platform as platform16 } from "node:os";
|
|
111541
|
-
import { extname as extname7, join as
|
|
111842
|
+
import { extname as extname7, join as join146 } from "node:path";
|
|
111542
111843
|
var IS_WINDOWS3 = platform16() === "win32";
|
|
111543
111844
|
var HOME_PREFIX = "$HOME";
|
|
111544
111845
|
function getHomeDirPrefix() {
|
|
@@ -111548,7 +111849,7 @@ function normalizeInstallPath(path17) {
|
|
|
111548
111849
|
return path17.replace(/\\/g, "/").replace(/\/+$/, "");
|
|
111549
111850
|
}
|
|
111550
111851
|
function getDefaultGlobalClaudeDir() {
|
|
111551
|
-
return normalizeInstallPath(
|
|
111852
|
+
return normalizeInstallPath(join146(homedir48(), ".claude"));
|
|
111552
111853
|
}
|
|
111553
111854
|
function getCustomGlobalClaudeDir(targetClaudeDir) {
|
|
111554
111855
|
if (!targetClaudeDir)
|
|
@@ -111679,7 +111980,7 @@ async function transformPathsForGlobalInstall(directory, options2 = {}) {
|
|
|
111679
111980
|
async function processDirectory2(dir) {
|
|
111680
111981
|
const entries = await readdir44(dir, { withFileTypes: true });
|
|
111681
111982
|
for (const entry of entries) {
|
|
111682
|
-
const fullPath =
|
|
111983
|
+
const fullPath = join146(dir, entry.name);
|
|
111683
111984
|
if (entry.isDirectory()) {
|
|
111684
111985
|
if (entry.name === "node_modules" || entry.name.startsWith(".") && entry.name !== ".claude") {
|
|
111685
111986
|
continue;
|
|
@@ -111758,7 +112059,7 @@ async function handleTransforms(ctx) {
|
|
|
111758
112059
|
logger.debug(ctx.options.global ? "Saved folder configuration to ~/.claude/.ck.json" : "Saved folder configuration to .claude/.ck.json");
|
|
111759
112060
|
}
|
|
111760
112061
|
}
|
|
111761
|
-
const claudeDir3 = ctx.options.global ? ctx.resolvedDir :
|
|
112062
|
+
const claudeDir3 = ctx.options.global ? ctx.resolvedDir : join147(ctx.resolvedDir, ".claude");
|
|
111762
112063
|
return {
|
|
111763
112064
|
...ctx,
|
|
111764
112065
|
foldersConfig,
|
|
@@ -111986,7 +112287,7 @@ var import_picocolors30 = __toESM(require_picocolors(), 1);
|
|
|
111986
112287
|
import { existsSync as existsSync72 } from "node:fs";
|
|
111987
112288
|
import { readFile as readFile67, rm as rm18, unlink as unlink14 } from "node:fs/promises";
|
|
111988
112289
|
import { homedir as homedir52 } from "node:os";
|
|
111989
|
-
import { basename as basename30, dirname as dirname49, join as
|
|
112290
|
+
import { basename as basename30, dirname as dirname49, join as join151, resolve as resolve50 } from "node:path";
|
|
111990
112291
|
init_logger();
|
|
111991
112292
|
|
|
111992
112293
|
// src/ui/ck-cli-design/next-steps-footer.ts
|
|
@@ -112201,13 +112502,13 @@ init_dist2();
|
|
|
112201
112502
|
init_model_taxonomy();
|
|
112202
112503
|
import { mkdir as mkdir39, readFile as readFile66, writeFile as writeFile39 } from "node:fs/promises";
|
|
112203
112504
|
import { homedir as homedir51 } from "node:os";
|
|
112204
|
-
import { dirname as dirname47, join as
|
|
112505
|
+
import { dirname as dirname47, join as join150 } from "node:path";
|
|
112205
112506
|
|
|
112206
112507
|
// src/commands/portable/models-dev-cache.ts
|
|
112207
112508
|
init_logger();
|
|
112208
112509
|
import { mkdir as mkdir38, readFile as readFile64, rename as rename14, writeFile as writeFile38 } from "node:fs/promises";
|
|
112209
112510
|
import { homedir as homedir49 } from "node:os";
|
|
112210
|
-
import { join as
|
|
112511
|
+
import { join as join148 } from "node:path";
|
|
112211
112512
|
|
|
112212
112513
|
class ModelsDevUnavailableError extends Error {
|
|
112213
112514
|
constructor(message, cause) {
|
|
@@ -112219,13 +112520,13 @@ var MODELS_DEV_URL = "https://models.dev/api.json";
|
|
|
112219
112520
|
var CACHE_TTL_MS3 = 24 * 60 * 60 * 1000;
|
|
112220
112521
|
var FETCH_TIMEOUT_MS = 1e4;
|
|
112221
112522
|
function defaultCacheDir() {
|
|
112222
|
-
return
|
|
112523
|
+
return join148(homedir49(), ".config", "claudekit", "cache");
|
|
112223
112524
|
}
|
|
112224
112525
|
function cacheFilePath(cacheDir) {
|
|
112225
|
-
return
|
|
112526
|
+
return join148(cacheDir, "models-dev.json");
|
|
112226
112527
|
}
|
|
112227
112528
|
function tmpFilePath(cacheDir) {
|
|
112228
|
-
return
|
|
112529
|
+
return join148(cacheDir, "models-dev.json.tmp");
|
|
112229
112530
|
}
|
|
112230
112531
|
async function readCacheEntry(cacheDir) {
|
|
112231
112532
|
const filePath = cacheFilePath(cacheDir);
|
|
@@ -112300,14 +112601,14 @@ async function getModelsDevCatalog(opts = {}) {
|
|
|
112300
112601
|
init_logger();
|
|
112301
112602
|
import { readFile as readFile65 } from "node:fs/promises";
|
|
112302
112603
|
import { homedir as homedir50, platform as platform17 } from "node:os";
|
|
112303
|
-
import { join as
|
|
112604
|
+
import { join as join149 } from "node:path";
|
|
112304
112605
|
function resolveOpenCodeAuthPath(homeDir) {
|
|
112305
112606
|
if (platform17() === "win32") {
|
|
112306
|
-
const dataRoot2 = process.env.LOCALAPPDATA ??
|
|
112307
|
-
return
|
|
112607
|
+
const dataRoot2 = process.env.LOCALAPPDATA ?? join149(homeDir, "AppData", "Local");
|
|
112608
|
+
return join149(dataRoot2, "opencode", "auth.json");
|
|
112308
112609
|
}
|
|
112309
|
-
const dataRoot = process.env.XDG_DATA_HOME ??
|
|
112310
|
-
return
|
|
112610
|
+
const dataRoot = process.env.XDG_DATA_HOME ?? join149(homeDir, ".local", "share");
|
|
112611
|
+
return join149(dataRoot, "opencode", "auth.json");
|
|
112311
112612
|
}
|
|
112312
112613
|
async function readAuthedProviders(homeDir) {
|
|
112313
112614
|
const authPath = resolveOpenCodeAuthPath(homeDir);
|
|
@@ -112409,9 +112710,9 @@ function messageForReason(reason) {
|
|
|
112409
112710
|
}
|
|
112410
112711
|
function getOpenCodeConfigPath(options2) {
|
|
112411
112712
|
if (options2.global) {
|
|
112412
|
-
return
|
|
112713
|
+
return join150(options2.homeDir ?? homedir51(), ".config", "opencode", "opencode.json");
|
|
112413
112714
|
}
|
|
112414
|
-
return
|
|
112715
|
+
return join150(options2.cwd ?? process.cwd(), "opencode.json");
|
|
112415
112716
|
}
|
|
112416
112717
|
function makeCatalogOpts(options2) {
|
|
112417
112718
|
return {
|
|
@@ -113284,7 +113585,7 @@ function appendFallbackSkillActionsToPlan(plan, skills, selectedProviders, insta
|
|
|
113284
113585
|
reason: "New item, not previously installed",
|
|
113285
113586
|
reasonCode: "new-item",
|
|
113286
113587
|
reasonCopy: "New - not previously installed",
|
|
113287
|
-
targetPath:
|
|
113588
|
+
targetPath: join151(basePath, skill.name),
|
|
113288
113589
|
type: "skill"
|
|
113289
113590
|
});
|
|
113290
113591
|
}
|
|
@@ -113512,7 +113813,7 @@ function resolveHookTargetPath(item, provider, global3) {
|
|
|
113512
113813
|
const converted = convertItem(item, pathConfig.format, provider, { global: global3 });
|
|
113513
113814
|
if (converted.error)
|
|
113514
113815
|
return null;
|
|
113515
|
-
const targetPath = pathConfig.writeStrategy === "single-file" ? basePath :
|
|
113816
|
+
const targetPath = pathConfig.writeStrategy === "single-file" ? basePath : join151(basePath, converted.filename);
|
|
113516
113817
|
const resolvedTarget = resolve50(targetPath).replace(/\\/g, "/");
|
|
113517
113818
|
const resolvedBase = resolve50(basePath).replace(/\\/g, "/").replace(/\/+$/, "");
|
|
113518
113819
|
if (resolvedTarget !== resolvedBase && !resolvedTarget.startsWith(`${resolvedBase}/`)) {
|
|
@@ -113523,7 +113824,7 @@ function resolveHookTargetPath(item, provider, global3) {
|
|
|
113523
113824
|
async function processMetadataDeletions(skillSourcePath, installGlobally) {
|
|
113524
113825
|
if (!skillSourcePath)
|
|
113525
113826
|
return;
|
|
113526
|
-
const sourceMetadataPath =
|
|
113827
|
+
const sourceMetadataPath = join151(resolve50(skillSourcePath, ".."), "metadata.json");
|
|
113527
113828
|
if (!existsSync72(sourceMetadataPath))
|
|
113528
113829
|
return;
|
|
113529
113830
|
let sourceMetadata;
|
|
@@ -113536,7 +113837,7 @@ async function processMetadataDeletions(skillSourcePath, installGlobally) {
|
|
|
113536
113837
|
}
|
|
113537
113838
|
if (!sourceMetadata.deletions || sourceMetadata.deletions.length === 0)
|
|
113538
113839
|
return;
|
|
113539
|
-
const claudeDir3 = installGlobally ?
|
|
113840
|
+
const claudeDir3 = installGlobally ? join151(homedir52(), ".claude") : join151(process.cwd(), ".claude");
|
|
113540
113841
|
if (!existsSync72(claudeDir3))
|
|
113541
113842
|
return;
|
|
113542
113843
|
try {
|
|
@@ -113664,8 +113965,8 @@ async function migrateCommand(options2) {
|
|
|
113664
113965
|
let requestedGlobal = options2.global ?? false;
|
|
113665
113966
|
let installGlobally = requestedGlobal;
|
|
113666
113967
|
if (options2.global === undefined && !options2.yes) {
|
|
113667
|
-
const projectTarget =
|
|
113668
|
-
const globalTarget =
|
|
113968
|
+
const projectTarget = join151(process.cwd(), ".claude");
|
|
113969
|
+
const globalTarget = join151(homedir52(), ".claude");
|
|
113669
113970
|
const scopeChoice = await ie({
|
|
113670
113971
|
message: "Installation scope",
|
|
113671
113972
|
options: [
|
|
@@ -113738,7 +114039,7 @@ async function migrateCommand(options2) {
|
|
|
113738
114039
|
}).join(`
|
|
113739
114040
|
`));
|
|
113740
114041
|
if (sourceGlobalOnly) {
|
|
113741
|
-
f2.info(import_picocolors30.default.dim(` Scope: global (--global / -g) - reading from ${formatDisplayPath(
|
|
114042
|
+
f2.info(import_picocolors30.default.dim(` Scope: global (--global / -g) - reading from ${formatDisplayPath(join151(homedir52(), ".claude"))}`));
|
|
113742
114043
|
} else {
|
|
113743
114044
|
f2.info(import_picocolors30.default.dim(` CWD: ${process.cwd()}`));
|
|
113744
114045
|
}
|
|
@@ -114047,7 +114348,7 @@ async function migrateCommand(options2) {
|
|
|
114047
114348
|
for (const [hooksProvider, entry] of successfulHookFiles) {
|
|
114048
114349
|
if (entry.files.length === 0)
|
|
114049
114350
|
continue;
|
|
114050
|
-
const sourceSettingsPath = hooksSource ?
|
|
114351
|
+
const sourceSettingsPath = hooksSource ? join151(dirname49(hooksSource), "settings.json") : undefined;
|
|
114051
114352
|
const mergeResult = await migrateHooksSettings({
|
|
114052
114353
|
sourceProvider: "claude-code",
|
|
114053
114354
|
targetProvider: hooksProvider,
|
|
@@ -114425,7 +114726,7 @@ async function handleDirectorySetup(ctx) {
|
|
|
114425
114726
|
// src/commands/new/phases/project-creation.ts
|
|
114426
114727
|
init_config_manager();
|
|
114427
114728
|
init_github_client();
|
|
114428
|
-
import { join as
|
|
114729
|
+
import { join as join152 } from "node:path";
|
|
114429
114730
|
init_logger();
|
|
114430
114731
|
init_output_manager();
|
|
114431
114732
|
init_types3();
|
|
@@ -114551,7 +114852,7 @@ async function projectCreation(kit, resolvedDir, validOptions, isNonInteractive2
|
|
|
114551
114852
|
output.section("Installing");
|
|
114552
114853
|
logger.verbose("Installation target", { directory: resolvedDir });
|
|
114553
114854
|
const merger = new FileMerger;
|
|
114554
|
-
const claudeDir3 =
|
|
114855
|
+
const claudeDir3 = join152(resolvedDir, ".claude");
|
|
114555
114856
|
merger.setMultiKitContext(claudeDir3, kit);
|
|
114556
114857
|
if (validOptions.exclude && validOptions.exclude.length > 0) {
|
|
114557
114858
|
merger.addIgnorePatterns(validOptions.exclude);
|
|
@@ -114598,7 +114899,7 @@ async function handleProjectCreation(ctx) {
|
|
|
114598
114899
|
}
|
|
114599
114900
|
// src/commands/new/phases/post-setup.ts
|
|
114600
114901
|
init_projects_registry();
|
|
114601
|
-
import { join as
|
|
114902
|
+
import { join as join153 } from "node:path";
|
|
114602
114903
|
init_package_installer();
|
|
114603
114904
|
init_logger();
|
|
114604
114905
|
init_path_resolver();
|
|
@@ -114630,9 +114931,9 @@ async function postSetup(resolvedDir, validOptions, isNonInteractive2, prompts)
|
|
|
114630
114931
|
withSudo: validOptions.withSudo
|
|
114631
114932
|
});
|
|
114632
114933
|
}
|
|
114633
|
-
const claudeDir3 =
|
|
114934
|
+
const claudeDir3 = join153(resolvedDir, ".claude");
|
|
114634
114935
|
await promptSetupWizardIfNeeded({
|
|
114635
|
-
envPath:
|
|
114936
|
+
envPath: join153(claudeDir3, ".env"),
|
|
114636
114937
|
claudeDir: claudeDir3,
|
|
114637
114938
|
isGlobal: false,
|
|
114638
114939
|
isNonInteractive: isNonInteractive2,
|
|
@@ -114702,7 +115003,7 @@ Please use only one download method.`);
|
|
|
114702
115003
|
// src/commands/plan/plan-command.ts
|
|
114703
115004
|
init_output_manager();
|
|
114704
115005
|
import { existsSync as existsSync75, statSync as statSync13 } from "node:fs";
|
|
114705
|
-
import { dirname as dirname53, isAbsolute as isAbsolute15, join as
|
|
115006
|
+
import { dirname as dirname53, isAbsolute as isAbsolute15, join as join156, parse as parse7, resolve as resolve55 } from "node:path";
|
|
114706
115007
|
|
|
114707
115008
|
// src/commands/plan/plan-read-handlers.ts
|
|
114708
115009
|
init_config();
|
|
@@ -114712,14 +115013,14 @@ init_logger();
|
|
|
114712
115013
|
init_output_manager();
|
|
114713
115014
|
var import_picocolors32 = __toESM(require_picocolors(), 1);
|
|
114714
115015
|
import { existsSync as existsSync74, statSync as statSync12 } from "node:fs";
|
|
114715
|
-
import { basename as basename31, dirname as dirname51, join as
|
|
115016
|
+
import { basename as basename31, dirname as dirname51, join as join155, relative as relative34, resolve as resolve53 } from "node:path";
|
|
114716
115017
|
|
|
114717
115018
|
// src/commands/plan/plan-dependencies.ts
|
|
114718
115019
|
init_config();
|
|
114719
115020
|
init_plan_parser();
|
|
114720
115021
|
init_plans_registry();
|
|
114721
115022
|
import { existsSync as existsSync73 } from "node:fs";
|
|
114722
|
-
import { dirname as dirname50, join as
|
|
115023
|
+
import { dirname as dirname50, join as join154 } from "node:path";
|
|
114723
115024
|
async function resolvePlanDependencies(references, currentPlanFile, options2 = {}) {
|
|
114724
115025
|
if (references.length === 0)
|
|
114725
115026
|
return [];
|
|
@@ -114739,7 +115040,7 @@ async function resolvePlanDependencies(references, currentPlanFile, options2 = {
|
|
|
114739
115040
|
};
|
|
114740
115041
|
}
|
|
114741
115042
|
const scopeRoot = resolvePlanDirForScope(scope, projectRoot, config);
|
|
114742
|
-
const planFile =
|
|
115043
|
+
const planFile = join154(scopeRoot, planId, "plan.md");
|
|
114743
115044
|
const isSelfReference = planFile === currentPlanFile;
|
|
114744
115045
|
if (!existsSync73(planFile)) {
|
|
114745
115046
|
return {
|
|
@@ -114881,7 +115182,7 @@ async function handleStatus(target, options2) {
|
|
|
114881
115182
|
}
|
|
114882
115183
|
const effectiveTarget = !resolvedTarget && globalBaseDir ? globalBaseDir : resolvedTarget;
|
|
114883
115184
|
const t = effectiveTarget ? resolve53(effectiveTarget) : null;
|
|
114884
|
-
const plansDir = t && existsSync74(t) && statSync12(t).isDirectory() && !existsSync74(
|
|
115185
|
+
const plansDir = t && existsSync74(t) && statSync12(t).isDirectory() && !existsSync74(join155(t, "plan.md")) ? t : null;
|
|
114885
115186
|
if (plansDir) {
|
|
114886
115187
|
const planFiles = scanPlanDir(plansDir);
|
|
114887
115188
|
if (planFiles.length === 0) {
|
|
@@ -115310,7 +115611,7 @@ function resolvePlanFile(target, baseDir) {
|
|
|
115310
115611
|
const stat24 = statSync13(t);
|
|
115311
115612
|
if (stat24.isFile())
|
|
115312
115613
|
return t;
|
|
115313
|
-
const candidate =
|
|
115614
|
+
const candidate = join156(t, "plan.md");
|
|
115314
115615
|
if (existsSync75(candidate))
|
|
115315
115616
|
return candidate;
|
|
115316
115617
|
}
|
|
@@ -115318,7 +115619,7 @@ function resolvePlanFile(target, baseDir) {
|
|
|
115318
115619
|
let dir = process.cwd();
|
|
115319
115620
|
const root = parse7(dir).root;
|
|
115320
115621
|
while (dir !== root) {
|
|
115321
|
-
const candidate =
|
|
115622
|
+
const candidate = join156(dir, "plan.md");
|
|
115322
115623
|
if (existsSync75(candidate))
|
|
115323
115624
|
return candidate;
|
|
115324
115625
|
dir = dirname53(dir);
|
|
@@ -115839,10 +116140,10 @@ init_agents();
|
|
|
115839
116140
|
var import_gray_matter12 = __toESM(require_gray_matter(), 1);
|
|
115840
116141
|
var import_picocolors37 = __toESM(require_picocolors(), 1);
|
|
115841
116142
|
import { readFile as readFile68 } from "node:fs/promises";
|
|
115842
|
-
import { join as
|
|
116143
|
+
import { join as join158 } from "node:path";
|
|
115843
116144
|
|
|
115844
116145
|
// src/commands/skills/installed-skills-inventory.ts
|
|
115845
|
-
import { join as
|
|
116146
|
+
import { join as join157, resolve as resolve57 } from "node:path";
|
|
115846
116147
|
init_path_resolver();
|
|
115847
116148
|
var SCOPE_SORT_ORDER = {
|
|
115848
116149
|
project: 0,
|
|
@@ -115854,8 +116155,8 @@ async function getActiveClaudeSkillInstallations(options2 = {}) {
|
|
|
115854
116155
|
const projectClaudeDir = resolve57(projectDir, ".claude");
|
|
115855
116156
|
const projectScopeAliasesGlobal = projectClaudeDir === globalDir;
|
|
115856
116157
|
const [projectSkills, globalSkills] = await Promise.all([
|
|
115857
|
-
projectScopeAliasesGlobal ? Promise.resolve([]) : scanSkills2(
|
|
115858
|
-
scanSkills2(
|
|
116158
|
+
projectScopeAliasesGlobal ? Promise.resolve([]) : scanSkills2(join157(projectClaudeDir, "skills")),
|
|
116159
|
+
scanSkills2(join157(globalDir, "skills"))
|
|
115859
116160
|
]);
|
|
115860
116161
|
const projectIds = new Set(projectSkills.map((skill) => skill.id));
|
|
115861
116162
|
const globalIds = new Set(globalSkills.map((skill) => skill.id));
|
|
@@ -116016,7 +116317,7 @@ async function handleValidate2(sourcePath) {
|
|
|
116016
116317
|
spinner.stop(`Checked ${skills.length} skill(s)`);
|
|
116017
116318
|
let hasIssues = false;
|
|
116018
116319
|
for (const skill of skills) {
|
|
116019
|
-
const skillMdPath =
|
|
116320
|
+
const skillMdPath = join158(skill.path, "SKILL.md");
|
|
116020
116321
|
try {
|
|
116021
116322
|
const content = await readFile68(skillMdPath, "utf-8");
|
|
116022
116323
|
const { data } = import_gray_matter12.default(content, {
|
|
@@ -116599,7 +116900,7 @@ async function detectInstallations() {
|
|
|
116599
116900
|
|
|
116600
116901
|
// src/commands/uninstall/removal-handler.ts
|
|
116601
116902
|
import { readdirSync as readdirSync14, rmSync as rmSync8 } from "node:fs";
|
|
116602
|
-
import { basename as basename33, join as
|
|
116903
|
+
import { basename as basename33, join as join161, resolve as resolve58, sep as sep14 } from "node:path";
|
|
116603
116904
|
init_logger();
|
|
116604
116905
|
init_safe_prompts();
|
|
116605
116906
|
init_safe_spinner();
|
|
@@ -116608,7 +116909,7 @@ var import_fs_extra44 = __toESM(require_lib(), 1);
|
|
|
116608
116909
|
// src/commands/uninstall/analysis-handler.ts
|
|
116609
116910
|
init_metadata_migration();
|
|
116610
116911
|
import { readdirSync as readdirSync13, rmSync as rmSync7 } from "node:fs";
|
|
116611
|
-
import { dirname as dirname54, join as
|
|
116912
|
+
import { dirname as dirname54, join as join159 } from "node:path";
|
|
116612
116913
|
init_logger();
|
|
116613
116914
|
init_safe_prompts();
|
|
116614
116915
|
var import_fs_extra42 = __toESM(require_lib(), 1);
|
|
@@ -116668,7 +116969,7 @@ async function analyzeInstallation(installation, forceOverwrite, kit) {
|
|
|
116668
116969
|
const remainingFiles = metadata.kits?.[remainingKit]?.files || [];
|
|
116669
116970
|
for (const file of remainingFiles) {
|
|
116670
116971
|
const relativePath = normalizeTrackedPath(file.path);
|
|
116671
|
-
if (await import_fs_extra42.pathExists(
|
|
116972
|
+
if (await import_fs_extra42.pathExists(join159(installation.path, relativePath))) {
|
|
116672
116973
|
result.retainedManifestPaths.push(relativePath);
|
|
116673
116974
|
}
|
|
116674
116975
|
}
|
|
@@ -116676,7 +116977,7 @@ async function analyzeInstallation(installation, forceOverwrite, kit) {
|
|
|
116676
116977
|
const kitFiles = metadata.kits[kit].files || [];
|
|
116677
116978
|
for (const trackedFile of kitFiles) {
|
|
116678
116979
|
const relativePath = normalizeTrackedPath(trackedFile.path);
|
|
116679
|
-
const filePath =
|
|
116980
|
+
const filePath = join159(installation.path, relativePath);
|
|
116680
116981
|
if (preservedPaths.has(relativePath)) {
|
|
116681
116982
|
result.toPreserve.push({ path: relativePath, reason: "shared with other kit" });
|
|
116682
116983
|
continue;
|
|
@@ -116709,7 +117010,7 @@ async function analyzeInstallation(installation, forceOverwrite, kit) {
|
|
|
116709
117010
|
}
|
|
116710
117011
|
for (const trackedFile of allTrackedFiles) {
|
|
116711
117012
|
const relativePath = normalizeTrackedPath(trackedFile.path);
|
|
116712
|
-
const filePath =
|
|
117013
|
+
const filePath = join159(installation.path, relativePath);
|
|
116713
117014
|
const ownershipResult = await OwnershipChecker.checkOwnership(filePath, metadata, installation.path);
|
|
116714
117015
|
if (!ownershipResult.exists)
|
|
116715
117016
|
continue;
|
|
@@ -116760,7 +117061,7 @@ init_settings_merger();
|
|
|
116760
117061
|
init_command_normalizer();
|
|
116761
117062
|
init_logger();
|
|
116762
117063
|
var import_fs_extra43 = __toESM(require_lib(), 1);
|
|
116763
|
-
import { join as
|
|
117064
|
+
import { join as join160 } from "node:path";
|
|
116764
117065
|
var CK_JSON_FILE2 = ".ck.json";
|
|
116765
117066
|
var SETTINGS_FILE = "settings.json";
|
|
116766
117067
|
var EMPTY_RESULT = {
|
|
@@ -116882,7 +117183,7 @@ async function cleanupCkJson(ckJsonPath, data, removedKitNames, dryRun) {
|
|
|
116882
117183
|
return false;
|
|
116883
117184
|
}
|
|
116884
117185
|
async function cleanupUninstalledSettings(installationPath, options2) {
|
|
116885
|
-
const ckJsonPath =
|
|
117186
|
+
const ckJsonPath = join160(installationPath, CK_JSON_FILE2);
|
|
116886
117187
|
if (!await import_fs_extra43.pathExists(ckJsonPath)) {
|
|
116887
117188
|
return { ...EMPTY_RESULT };
|
|
116888
117189
|
}
|
|
@@ -116897,7 +117198,7 @@ async function cleanupUninstalledSettings(installationPath, options2) {
|
|
|
116897
117198
|
const removedKitNames = options2.kit ? [options2.kit] : Object.keys(kits);
|
|
116898
117199
|
const { hooks, servers } = resolveRemovalTargets(kits, removedKitNames, options2.remainingKits);
|
|
116899
117200
|
const result = { ...EMPTY_RESULT };
|
|
116900
|
-
const settingsPath =
|
|
117201
|
+
const settingsPath = join160(installationPath, SETTINGS_FILE);
|
|
116901
117202
|
const settings = await SettingsMerger.readSettingsFile(settingsPath);
|
|
116902
117203
|
if (settings) {
|
|
116903
117204
|
result.hooksRemoved = removeHooksFromSettings(settings, hooks);
|
|
@@ -117011,8 +117312,8 @@ async function removeInstallations(installations, options2) {
|
|
|
117011
117312
|
}
|
|
117012
117313
|
const mutatePaths = getUninstallMutatePaths({
|
|
117013
117314
|
retainedManifestPaths: analysis.retainedManifestPaths,
|
|
117014
|
-
settingsFileExists: await import_fs_extra44.pathExists(
|
|
117015
|
-
ckJsonExists: await import_fs_extra44.pathExists(
|
|
117315
|
+
settingsFileExists: await import_fs_extra44.pathExists(join161(installation.path, "settings.json")),
|
|
117316
|
+
ckJsonExists: await import_fs_extra44.pathExists(join161(installation.path, ".ck.json"))
|
|
117016
117317
|
});
|
|
117017
117318
|
let backup = null;
|
|
117018
117319
|
if (analysis.toDelete.length > 0 || mutatePaths.length > 0) {
|
|
@@ -117040,7 +117341,7 @@ async function removeInstallations(installations, options2) {
|
|
|
117040
117341
|
let removedCount = 0;
|
|
117041
117342
|
let cleanedDirs = 0;
|
|
117042
117343
|
for (const item of analysis.toDelete) {
|
|
117043
|
-
const filePath =
|
|
117344
|
+
const filePath = join161(installation.path, item.path);
|
|
117044
117345
|
if (!await import_fs_extra44.pathExists(filePath))
|
|
117045
117346
|
continue;
|
|
117046
117347
|
if (!await isPathSafeToRemove(filePath, installation.path)) {
|
|
@@ -117467,7 +117768,7 @@ ${import_picocolors40.default.bold(import_picocolors40.default.cyan(result.kitCo
|
|
|
117467
117768
|
init_logger();
|
|
117468
117769
|
import { existsSync as existsSync82 } from "node:fs";
|
|
117469
117770
|
import { rm as rm19 } from "node:fs/promises";
|
|
117470
|
-
import { join as
|
|
117771
|
+
import { join as join168 } from "node:path";
|
|
117471
117772
|
var import_picocolors41 = __toESM(require_picocolors(), 1);
|
|
117472
117773
|
|
|
117473
117774
|
// src/commands/watch/phases/implementation-runner.ts
|
|
@@ -117986,7 +118287,7 @@ function spawnAndCollect3(command, args) {
|
|
|
117986
118287
|
|
|
117987
118288
|
// src/commands/watch/phases/issue-processor.ts
|
|
117988
118289
|
import { mkdir as mkdir40, writeFile as writeFile42 } from "node:fs/promises";
|
|
117989
|
-
import { join as
|
|
118290
|
+
import { join as join164 } from "node:path";
|
|
117990
118291
|
|
|
117991
118292
|
// src/commands/watch/phases/approval-detector.ts
|
|
117992
118293
|
init_logger();
|
|
@@ -118364,9 +118665,9 @@ async function checkAwaitingApproval(state, setup, options2, watchLog, projectDi
|
|
|
118364
118665
|
|
|
118365
118666
|
// src/commands/watch/phases/plan-dir-finder.ts
|
|
118366
118667
|
import { readdir as readdir46, stat as stat24 } from "node:fs/promises";
|
|
118367
|
-
import { join as
|
|
118668
|
+
import { join as join163 } from "node:path";
|
|
118368
118669
|
async function findRecentPlanDir(cwd2, issueNumber, watchLog) {
|
|
118369
|
-
const plansRoot =
|
|
118670
|
+
const plansRoot = join163(cwd2, "plans");
|
|
118370
118671
|
try {
|
|
118371
118672
|
const entries = await readdir46(plansRoot);
|
|
118372
118673
|
const tenMinAgo = Date.now() - 10 * 60 * 1000;
|
|
@@ -118375,14 +118676,14 @@ async function findRecentPlanDir(cwd2, issueNumber, watchLog) {
|
|
|
118375
118676
|
for (const entry of entries) {
|
|
118376
118677
|
if (entry === "watch" || entry === "reports" || entry === "visuals")
|
|
118377
118678
|
continue;
|
|
118378
|
-
const dirPath =
|
|
118679
|
+
const dirPath = join163(plansRoot, entry);
|
|
118379
118680
|
const dirStat = await stat24(dirPath);
|
|
118380
118681
|
if (!dirStat.isDirectory())
|
|
118381
118682
|
continue;
|
|
118382
118683
|
if (dirStat.mtimeMs < tenMinAgo)
|
|
118383
118684
|
continue;
|
|
118384
118685
|
try {
|
|
118385
|
-
await stat24(
|
|
118686
|
+
await stat24(join163(dirPath, "plan.md"));
|
|
118386
118687
|
} catch {
|
|
118387
118688
|
continue;
|
|
118388
118689
|
}
|
|
@@ -118613,13 +118914,13 @@ async function handlePlanGeneration(issue, state, config, setup, options2, watch
|
|
|
118613
118914
|
stats.plansCreated++;
|
|
118614
118915
|
const detectedPlanDir = await findRecentPlanDir(projectDir, issue.number, watchLog);
|
|
118615
118916
|
if (detectedPlanDir) {
|
|
118616
|
-
state.activeIssues[numStr].planPath =
|
|
118917
|
+
state.activeIssues[numStr].planPath = join164(detectedPlanDir, "plan.md");
|
|
118617
118918
|
watchLog.info(`Plan directory detected: ${detectedPlanDir}`);
|
|
118618
118919
|
} else {
|
|
118619
118920
|
try {
|
|
118620
|
-
const planDir =
|
|
118921
|
+
const planDir = join164(projectDir, "plans", "watch");
|
|
118621
118922
|
await mkdir40(planDir, { recursive: true });
|
|
118622
|
-
const planFilePath =
|
|
118923
|
+
const planFilePath = join164(planDir, `issue-${issue.number}-plan.md`);
|
|
118623
118924
|
await writeFile42(planFilePath, planResult.planText, "utf-8");
|
|
118624
118925
|
state.activeIssues[numStr].planPath = planFilePath;
|
|
118625
118926
|
watchLog.info(`Plan saved (fallback) to ${planFilePath}`);
|
|
@@ -118926,18 +119227,18 @@ init_logger();
|
|
|
118926
119227
|
import { spawnSync as spawnSync7 } from "node:child_process";
|
|
118927
119228
|
import { existsSync as existsSync79 } from "node:fs";
|
|
118928
119229
|
import { readdir as readdir47, stat as stat25 } from "node:fs/promises";
|
|
118929
|
-
import { join as
|
|
119230
|
+
import { join as join165 } from "node:path";
|
|
118930
119231
|
async function scanForRepos(parentDir) {
|
|
118931
119232
|
const repos = [];
|
|
118932
119233
|
const entries = await readdir47(parentDir);
|
|
118933
119234
|
for (const entry of entries) {
|
|
118934
119235
|
if (entry.startsWith("."))
|
|
118935
119236
|
continue;
|
|
118936
|
-
const fullPath =
|
|
119237
|
+
const fullPath = join165(parentDir, entry);
|
|
118937
119238
|
const entryStat = await stat25(fullPath);
|
|
118938
119239
|
if (!entryStat.isDirectory())
|
|
118939
119240
|
continue;
|
|
118940
|
-
const gitDir =
|
|
119241
|
+
const gitDir = join165(fullPath, ".git");
|
|
118941
119242
|
if (!existsSync79(gitDir))
|
|
118942
119243
|
continue;
|
|
118943
119244
|
const result = spawnSync7("gh", ["repo", "view", "--json", "owner,name"], {
|
|
@@ -118964,7 +119265,7 @@ init_logger();
|
|
|
118964
119265
|
import { spawnSync as spawnSync8 } from "node:child_process";
|
|
118965
119266
|
import { existsSync as existsSync80 } from "node:fs";
|
|
118966
119267
|
import { homedir as homedir53 } from "node:os";
|
|
118967
|
-
import { join as
|
|
119268
|
+
import { join as join166 } from "node:path";
|
|
118968
119269
|
async function validateSetup(cwd2) {
|
|
118969
119270
|
const workDir = cwd2 ?? process.cwd();
|
|
118970
119271
|
const ghVersion = spawnSync8("gh", ["--version"], { encoding: "utf-8", timeout: 1e4 });
|
|
@@ -118995,7 +119296,7 @@ Run this command from a directory with a GitHub remote.`);
|
|
|
118995
119296
|
} catch {
|
|
118996
119297
|
throw new Error(`Failed to parse repository info: ${ghRepo.stdout}`);
|
|
118997
119298
|
}
|
|
118998
|
-
const skillsPath =
|
|
119299
|
+
const skillsPath = join166(homedir53(), ".claude", "skills");
|
|
118999
119300
|
const skillsAvailable = existsSync80(skillsPath);
|
|
119000
119301
|
if (!skillsAvailable) {
|
|
119001
119302
|
logger.warning(`ClaudeKit Engineer skills not found at ${skillsPath}`);
|
|
@@ -119014,7 +119315,7 @@ init_path_resolver();
|
|
|
119014
119315
|
import { createWriteStream as createWriteStream3, statSync as statSync14 } from "node:fs";
|
|
119015
119316
|
import { existsSync as existsSync81 } from "node:fs";
|
|
119016
119317
|
import { mkdir as mkdir42, rename as rename15 } from "node:fs/promises";
|
|
119017
|
-
import { join as
|
|
119318
|
+
import { join as join167 } from "node:path";
|
|
119018
119319
|
|
|
119019
119320
|
class WatchLogger {
|
|
119020
119321
|
logStream = null;
|
|
@@ -119022,7 +119323,7 @@ class WatchLogger {
|
|
|
119022
119323
|
logPath = null;
|
|
119023
119324
|
maxBytes;
|
|
119024
119325
|
constructor(logDir, maxBytes = 0) {
|
|
119025
|
-
this.logDir = logDir ??
|
|
119326
|
+
this.logDir = logDir ?? join167(PathResolver.getClaudeKitDir(), "logs");
|
|
119026
119327
|
this.maxBytes = maxBytes;
|
|
119027
119328
|
}
|
|
119028
119329
|
async init() {
|
|
@@ -119031,7 +119332,7 @@ class WatchLogger {
|
|
|
119031
119332
|
await mkdir42(this.logDir, { recursive: true });
|
|
119032
119333
|
}
|
|
119033
119334
|
const dateStr = formatDate(new Date);
|
|
119034
|
-
this.logPath =
|
|
119335
|
+
this.logPath = join167(this.logDir, `watch-${dateStr}.log`);
|
|
119035
119336
|
this.logStream = createWriteStream3(this.logPath, { flags: "a", mode: 384 });
|
|
119036
119337
|
} catch (error) {
|
|
119037
119338
|
logger.warning(`Cannot create watch log file: ${error instanceof Error ? error.message : "Unknown"}`);
|
|
@@ -119213,7 +119514,7 @@ async function watchCommand(options2) {
|
|
|
119213
119514
|
}
|
|
119214
119515
|
async function discoverRepos(options2, watchLog) {
|
|
119215
119516
|
const cwd2 = process.cwd();
|
|
119216
|
-
const isGitRepo = existsSync82(
|
|
119517
|
+
const isGitRepo = existsSync82(join168(cwd2, ".git"));
|
|
119217
119518
|
if (options2.force) {
|
|
119218
119519
|
await forceRemoveLock(watchLog);
|
|
119219
119520
|
}
|
|
@@ -119470,8 +119771,8 @@ function registerCommands(cli) {
|
|
|
119470
119771
|
// src/cli/version-display.ts
|
|
119471
119772
|
init_package();
|
|
119472
119773
|
init_config_version_checker();
|
|
119473
|
-
import { existsSync as existsSync94, readFileSync as
|
|
119474
|
-
import { join as
|
|
119774
|
+
import { existsSync as existsSync94, readFileSync as readFileSync29 } from "node:fs";
|
|
119775
|
+
import { join as join180 } from "node:path";
|
|
119475
119776
|
|
|
119476
119777
|
// src/domains/versioning/version-checker.ts
|
|
119477
119778
|
init_version_utils();
|
|
@@ -119486,14 +119787,14 @@ init_logger();
|
|
|
119486
119787
|
init_path_resolver();
|
|
119487
119788
|
import { existsSync as existsSync93 } from "node:fs";
|
|
119488
119789
|
import { mkdir as mkdir43, readFile as readFile73, writeFile as writeFile45 } from "node:fs/promises";
|
|
119489
|
-
import { join as
|
|
119790
|
+
import { join as join179 } from "node:path";
|
|
119490
119791
|
|
|
119491
119792
|
class VersionCacheManager {
|
|
119492
119793
|
static CACHE_FILENAME = "version-check.json";
|
|
119493
119794
|
static CACHE_TTL_MS = 7 * 24 * 60 * 60 * 1000;
|
|
119494
119795
|
static getCacheFile() {
|
|
119495
119796
|
const cacheDir = PathResolver.getCacheDir(false);
|
|
119496
|
-
return
|
|
119797
|
+
return join179(cacheDir, VersionCacheManager.CACHE_FILENAME);
|
|
119497
119798
|
}
|
|
119498
119799
|
static async load() {
|
|
119499
119800
|
const cacheFile = VersionCacheManager.getCacheFile();
|
|
@@ -119804,13 +120105,13 @@ async function displayVersion() {
|
|
|
119804
120105
|
let localInstalledKits = [];
|
|
119805
120106
|
let globalInstalledKits = [];
|
|
119806
120107
|
const globalKitDir = PathResolver.getGlobalKitDir();
|
|
119807
|
-
const globalMetadataPath =
|
|
120108
|
+
const globalMetadataPath = join180(globalKitDir, "metadata.json");
|
|
119808
120109
|
const prefix = PathResolver.getPathPrefix(false);
|
|
119809
|
-
const localMetadataPath = prefix ?
|
|
120110
|
+
const localMetadataPath = prefix ? join180(process.cwd(), prefix, "metadata.json") : join180(process.cwd(), "metadata.json");
|
|
119810
120111
|
const isLocalSameAsGlobal = localMetadataPath === globalMetadataPath;
|
|
119811
120112
|
if (!isLocalSameAsGlobal && existsSync94(localMetadataPath)) {
|
|
119812
120113
|
try {
|
|
119813
|
-
const rawMetadata = JSON.parse(
|
|
120114
|
+
const rawMetadata = JSON.parse(readFileSync29(localMetadataPath, "utf-8"));
|
|
119814
120115
|
const metadata = MetadataSchema.parse(rawMetadata);
|
|
119815
120116
|
const kitsDisplay = formatInstalledKits(metadata);
|
|
119816
120117
|
if (kitsDisplay) {
|
|
@@ -119824,7 +120125,7 @@ async function displayVersion() {
|
|
|
119824
120125
|
}
|
|
119825
120126
|
if (existsSync94(globalMetadataPath)) {
|
|
119826
120127
|
try {
|
|
119827
|
-
const rawMetadata = JSON.parse(
|
|
120128
|
+
const rawMetadata = JSON.parse(readFileSync29(globalMetadataPath, "utf-8"));
|
|
119828
120129
|
const metadata = MetadataSchema.parse(rawMetadata);
|
|
119829
120130
|
const kitsDisplay = formatInstalledKits(metadata);
|
|
119830
120131
|
if (kitsDisplay) {
|