claudekit-cli 3.34.1-dev.5 → 3.34.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js
CHANGED
|
@@ -29190,10 +29190,8 @@ var init_ck_config = __esm(() => {
|
|
|
29190
29190
|
CkHooksConfigSchema = exports_external.object({
|
|
29191
29191
|
"session-init": exports_external.boolean().optional(),
|
|
29192
29192
|
"subagent-init": exports_external.boolean().optional(),
|
|
29193
|
-
"descriptive-name": exports_external.boolean().optional(),
|
|
29194
29193
|
"dev-rules-reminder": exports_external.boolean().optional(),
|
|
29195
29194
|
"usage-context-awareness": exports_external.boolean().optional(),
|
|
29196
|
-
"context-tracking": exports_external.boolean().optional(),
|
|
29197
29195
|
"scout-block": exports_external.boolean().optional(),
|
|
29198
29196
|
"privacy-block": exports_external.boolean().optional(),
|
|
29199
29197
|
"post-edit-simplify-reminder": exports_external.boolean().optional()
|
|
@@ -29266,10 +29264,8 @@ var init_ck_config = __esm(() => {
|
|
|
29266
29264
|
hooks: {
|
|
29267
29265
|
"session-init": true,
|
|
29268
29266
|
"subagent-init": true,
|
|
29269
|
-
"descriptive-name": true,
|
|
29270
29267
|
"dev-rules-reminder": true,
|
|
29271
29268
|
"usage-context-awareness": true,
|
|
29272
|
-
"context-tracking": true,
|
|
29273
29269
|
"scout-block": true,
|
|
29274
29270
|
"privacy-block": true,
|
|
29275
29271
|
"post-edit-simplify-reminder": true
|
|
@@ -29278,10 +29274,8 @@ var init_ck_config = __esm(() => {
|
|
|
29278
29274
|
CK_HOOK_NAMES = [
|
|
29279
29275
|
"session-init",
|
|
29280
29276
|
"subagent-init",
|
|
29281
|
-
"descriptive-name",
|
|
29282
29277
|
"dev-rules-reminder",
|
|
29283
29278
|
"usage-context-awareness",
|
|
29284
|
-
"context-tracking",
|
|
29285
29279
|
"scout-block",
|
|
29286
29280
|
"privacy-block",
|
|
29287
29281
|
"post-edit-simplify-reminder"
|
|
@@ -29562,9 +29556,6 @@ function getNestedValue(obj, path2) {
|
|
|
29562
29556
|
}
|
|
29563
29557
|
function setNestedValue(obj, path2, value) {
|
|
29564
29558
|
const keys = path2.split(".");
|
|
29565
|
-
if (keys.some((k) => DANGEROUS_KEYS.includes(k))) {
|
|
29566
|
-
throw new Error("Invalid field path: dangerous key detected");
|
|
29567
|
-
}
|
|
29568
29559
|
let current = obj;
|
|
29569
29560
|
for (let i = 0;i < keys.length - 1; i++) {
|
|
29570
29561
|
const key = keys[i];
|
|
@@ -29578,8 +29569,6 @@ function setNestedValue(obj, path2, value) {
|
|
|
29578
29569
|
function deepMerge(target, source) {
|
|
29579
29570
|
const result = { ...target };
|
|
29580
29571
|
for (const key of Object.keys(source)) {
|
|
29581
|
-
if (DANGEROUS_KEYS.includes(key))
|
|
29582
|
-
continue;
|
|
29583
29572
|
const sourceVal = source[key];
|
|
29584
29573
|
const targetVal = result[key];
|
|
29585
29574
|
if (sourceVal !== null && typeof sourceVal === "object" && !Array.isArray(sourceVal) && targetVal !== null && typeof targetVal === "object" && !Array.isArray(targetVal)) {
|
|
@@ -29718,10 +29707,6 @@ class CkConfigManager {
|
|
|
29718
29707
|
return null;
|
|
29719
29708
|
return CkConfigManager.loadConfigFile(CkConfigManager.getProjectConfigPath(projectDir));
|
|
29720
29709
|
}
|
|
29721
|
-
static projectConfigExists(dir, isGlobal) {
|
|
29722
|
-
const configPath = isGlobal ? join3(dir, ".ck.json") : CkConfigManager.getProjectConfigPath(dir);
|
|
29723
|
-
return existsSync3(configPath);
|
|
29724
|
-
}
|
|
29725
29710
|
static configExists(scope, projectDir) {
|
|
29726
29711
|
if (scope === "global") {
|
|
29727
29712
|
return existsSync3(CkConfigManager.getGlobalConfigPath());
|
|
@@ -29742,11 +29727,10 @@ class CkConfigManager {
|
|
|
29742
29727
|
await CkConfigManager.saveFull(existing, scope, projectDir);
|
|
29743
29728
|
}
|
|
29744
29729
|
}
|
|
29745
|
-
var CK_CONFIG_FILE = ".ck.json"
|
|
29730
|
+
var CK_CONFIG_FILE = ".ck.json";
|
|
29746
29731
|
var init_ck_config_manager = __esm(() => {
|
|
29747
29732
|
init_logger();
|
|
29748
29733
|
init_types2();
|
|
29749
|
-
DANGEROUS_KEYS = ["__proto__", "constructor", "prototype"];
|
|
29750
29734
|
});
|
|
29751
29735
|
|
|
29752
29736
|
// src/shared/environment.ts
|
|
@@ -38125,12 +38109,17 @@ class FileWatcher {
|
|
|
38125
38109
|
if (this.isConfigFile(path2)) {
|
|
38126
38110
|
try {
|
|
38127
38111
|
const scope = this.getConfigScope(path2);
|
|
38128
|
-
|
|
38129
|
-
|
|
38130
|
-
|
|
38112
|
+
let config;
|
|
38113
|
+
if (scope === "global") {
|
|
38114
|
+
ConfigManager.setGlobalFlag(true);
|
|
38115
|
+
config = await ConfigManager.load();
|
|
38116
|
+
} else {
|
|
38117
|
+
const projectConfig = await ConfigManager.loadProjectConfig(process.cwd(), false);
|
|
38118
|
+
config = projectConfig ? { paths: projectConfig } : {};
|
|
38119
|
+
}
|
|
38131
38120
|
this.wsManager.broadcast({
|
|
38132
38121
|
type: "config:updated",
|
|
38133
|
-
payload: { scope, config
|
|
38122
|
+
payload: { scope, config }
|
|
38134
38123
|
});
|
|
38135
38124
|
} catch (error) {
|
|
38136
38125
|
logger.error(`Failed to reload config: ${error}`);
|
|
@@ -38888,9 +38877,6 @@ var init_projects_registry = __esm(() => {
|
|
|
38888
38877
|
});
|
|
38889
38878
|
|
|
38890
38879
|
// src/domains/web-server/routes/ck-config-routes.ts
|
|
38891
|
-
import { existsSync as existsSync6 } from "node:fs";
|
|
38892
|
-
import { readFile as readFile5 } from "node:fs/promises";
|
|
38893
|
-
import { join as join9 } from "node:path";
|
|
38894
38880
|
async function resolveProjectDir(projectId) {
|
|
38895
38881
|
if (!projectId)
|
|
38896
38882
|
return null;
|
|
@@ -39013,6 +38999,92 @@ function registerCkConfigRoutes(app) {
|
|
|
39013
38999
|
res.status(500).json({ error: "Failed to update field" });
|
|
39014
39000
|
}
|
|
39015
39001
|
});
|
|
39002
|
+
}
|
|
39003
|
+
var init_ck_config_routes = __esm(() => {
|
|
39004
|
+
init_config();
|
|
39005
|
+
init_ck_config_schema();
|
|
39006
|
+
init_logger();
|
|
39007
|
+
init_types2();
|
|
39008
|
+
});
|
|
39009
|
+
|
|
39010
|
+
// src/domains/web-server/routes/config-routes.ts
|
|
39011
|
+
import { existsSync as existsSync6 } from "node:fs";
|
|
39012
|
+
import { mkdir as mkdir4, readFile as readFile5, writeFile as writeFile6 } from "node:fs/promises";
|
|
39013
|
+
import { join as join9 } from "node:path";
|
|
39014
|
+
function registerConfigRoutes(app) {
|
|
39015
|
+
app.get("/api/config", async (_req, res) => {
|
|
39016
|
+
try {
|
|
39017
|
+
const projectDir = process.cwd();
|
|
39018
|
+
const globalConfigPath = getEngineerKitConfigPath();
|
|
39019
|
+
let globalConfig = {};
|
|
39020
|
+
if (existsSync6(globalConfigPath)) {
|
|
39021
|
+
const content = await readFile5(globalConfigPath, "utf-8");
|
|
39022
|
+
try {
|
|
39023
|
+
globalConfig = JSON.parse(content);
|
|
39024
|
+
} catch {}
|
|
39025
|
+
}
|
|
39026
|
+
const localConfig = await ConfigManager.loadProjectConfig(projectDir, false);
|
|
39027
|
+
const merged = deepMerge2(globalConfig, localConfig ? { paths: localConfig } : {});
|
|
39028
|
+
const response = {
|
|
39029
|
+
global: globalConfig,
|
|
39030
|
+
local: localConfig ? { paths: localConfig } : null,
|
|
39031
|
+
merged
|
|
39032
|
+
};
|
|
39033
|
+
res.json(response);
|
|
39034
|
+
} catch (error) {
|
|
39035
|
+
logger.error(`Failed to load config: ${error}`);
|
|
39036
|
+
res.status(500).json({ error: "Failed to load configuration" });
|
|
39037
|
+
}
|
|
39038
|
+
});
|
|
39039
|
+
app.get("/api/config/global", async (_req, res) => {
|
|
39040
|
+
try {
|
|
39041
|
+
const globalConfigPath = getEngineerKitConfigPath();
|
|
39042
|
+
let config = {};
|
|
39043
|
+
if (existsSync6(globalConfigPath)) {
|
|
39044
|
+
const content = await readFile5(globalConfigPath, "utf-8");
|
|
39045
|
+
try {
|
|
39046
|
+
config = JSON.parse(content);
|
|
39047
|
+
} catch {}
|
|
39048
|
+
}
|
|
39049
|
+
res.json(config);
|
|
39050
|
+
} catch (error) {
|
|
39051
|
+
res.status(500).json({ error: "Failed to load global config" });
|
|
39052
|
+
}
|
|
39053
|
+
});
|
|
39054
|
+
app.get("/api/config/local", async (_req, res) => {
|
|
39055
|
+
try {
|
|
39056
|
+
const projectDir = process.cwd();
|
|
39057
|
+
const config = await ConfigManager.loadProjectConfig(projectDir, false);
|
|
39058
|
+
res.json(config ? { paths: config } : {});
|
|
39059
|
+
} catch (error) {
|
|
39060
|
+
res.status(500).json({ error: "Failed to load local config" });
|
|
39061
|
+
}
|
|
39062
|
+
});
|
|
39063
|
+
app.post("/api/config", async (req, res) => {
|
|
39064
|
+
try {
|
|
39065
|
+
const { scope = "local", config } = req.body;
|
|
39066
|
+
if (!config || typeof config !== "object") {
|
|
39067
|
+
res.status(400).json({ error: "Invalid config payload" });
|
|
39068
|
+
return;
|
|
39069
|
+
}
|
|
39070
|
+
if (scope === "global") {
|
|
39071
|
+
const globalConfigPath = getEngineerKitConfigPath();
|
|
39072
|
+
const globalDir = PathResolver.getGlobalKitDir();
|
|
39073
|
+
if (!existsSync6(globalDir)) {
|
|
39074
|
+
await mkdir4(globalDir, { recursive: true });
|
|
39075
|
+
}
|
|
39076
|
+
await writeFile6(globalConfigPath, JSON.stringify(config, null, 2), "utf-8");
|
|
39077
|
+
logger.debug(`Engineer kit config saved to ${globalConfigPath}`);
|
|
39078
|
+
} else {
|
|
39079
|
+
const projectDir = process.cwd();
|
|
39080
|
+
await ConfigManager.saveProjectConfig(projectDir, config.paths || config, false);
|
|
39081
|
+
}
|
|
39082
|
+
res.json({ success: true, scope });
|
|
39083
|
+
} catch (error) {
|
|
39084
|
+
logger.error(`Failed to save config: ${error}`);
|
|
39085
|
+
res.status(500).json({ error: "Failed to save configuration" });
|
|
39086
|
+
}
|
|
39087
|
+
});
|
|
39016
39088
|
app.get("/api/metadata/global", async (_req, res) => {
|
|
39017
39089
|
try {
|
|
39018
39090
|
const metadataPath = join9(PathResolver.getGlobalKitDir(), "metadata.json");
|
|
@@ -39021,9 +39093,7 @@ function registerCkConfigRoutes(app) {
|
|
|
39021
39093
|
const content = await readFile5(metadataPath, "utf-8");
|
|
39022
39094
|
try {
|
|
39023
39095
|
metadata = JSON.parse(content);
|
|
39024
|
-
} catch
|
|
39025
|
-
logger.warning(`Invalid JSON in metadata.json: ${err}`);
|
|
39026
|
-
}
|
|
39096
|
+
} catch {}
|
|
39027
39097
|
}
|
|
39028
39098
|
res.json(metadata);
|
|
39029
39099
|
} catch (error) {
|
|
@@ -39031,13 +39101,92 @@ function registerCkConfigRoutes(app) {
|
|
|
39031
39101
|
res.status(500).json({ error: "Failed to load metadata" });
|
|
39032
39102
|
}
|
|
39033
39103
|
});
|
|
39104
|
+
app.get("/api/config/project/:id", async (req, res) => {
|
|
39105
|
+
try {
|
|
39106
|
+
const id = String(req.params.id);
|
|
39107
|
+
let projectDir;
|
|
39108
|
+
if (id.startsWith("discovered-")) {
|
|
39109
|
+
const encodedPath = id.slice("discovered-".length);
|
|
39110
|
+
projectDir = Buffer.from(encodedPath, "base64url").toString("utf-8");
|
|
39111
|
+
} else {
|
|
39112
|
+
const { ProjectsRegistryManager: ProjectsRegistryManager2 } = await Promise.resolve().then(() => (init_projects_registry(), exports_projects_registry));
|
|
39113
|
+
const project = await ProjectsRegistryManager2.getProject(id);
|
|
39114
|
+
if (!project) {
|
|
39115
|
+
res.status(404).json({ error: "Project not found" });
|
|
39116
|
+
return;
|
|
39117
|
+
}
|
|
39118
|
+
projectDir = project.path;
|
|
39119
|
+
}
|
|
39120
|
+
const globalConfigPath = getEngineerKitConfigPath();
|
|
39121
|
+
let globalConfig = {};
|
|
39122
|
+
if (existsSync6(globalConfigPath)) {
|
|
39123
|
+
const content = await readFile5(globalConfigPath, "utf-8");
|
|
39124
|
+
try {
|
|
39125
|
+
globalConfig = JSON.parse(content);
|
|
39126
|
+
} catch {}
|
|
39127
|
+
}
|
|
39128
|
+
const localConfig = await ConfigManager.loadProjectConfig(projectDir, false);
|
|
39129
|
+
const merged = deepMerge2(globalConfig, localConfig ? { paths: localConfig } : {});
|
|
39130
|
+
const response = {
|
|
39131
|
+
global: globalConfig,
|
|
39132
|
+
local: localConfig ? { paths: localConfig } : null,
|
|
39133
|
+
merged
|
|
39134
|
+
};
|
|
39135
|
+
res.json(response);
|
|
39136
|
+
} catch (error) {
|
|
39137
|
+
logger.error(`Failed to load project config: ${error}`);
|
|
39138
|
+
res.status(500).json({ error: "Failed to load project configuration" });
|
|
39139
|
+
}
|
|
39140
|
+
});
|
|
39141
|
+
app.post("/api/config/project/:id", async (req, res) => {
|
|
39142
|
+
try {
|
|
39143
|
+
const id = String(req.params.id);
|
|
39144
|
+
const { config } = req.body;
|
|
39145
|
+
if (!config || typeof config !== "object") {
|
|
39146
|
+
res.status(400).json({ error: "Invalid config payload" });
|
|
39147
|
+
return;
|
|
39148
|
+
}
|
|
39149
|
+
let projectDir;
|
|
39150
|
+
if (id.startsWith("discovered-")) {
|
|
39151
|
+
const encodedPath = id.slice("discovered-".length);
|
|
39152
|
+
projectDir = Buffer.from(encodedPath, "base64url").toString("utf-8");
|
|
39153
|
+
} else {
|
|
39154
|
+
const { ProjectsRegistryManager: ProjectsRegistryManager2 } = await Promise.resolve().then(() => (init_projects_registry(), exports_projects_registry));
|
|
39155
|
+
const project = await ProjectsRegistryManager2.getProject(id);
|
|
39156
|
+
if (!project) {
|
|
39157
|
+
res.status(404).json({ error: "Project not found" });
|
|
39158
|
+
return;
|
|
39159
|
+
}
|
|
39160
|
+
projectDir = project.path;
|
|
39161
|
+
}
|
|
39162
|
+
await ConfigManager.saveProjectConfig(projectDir, config.paths || config, false);
|
|
39163
|
+
res.json({ success: true });
|
|
39164
|
+
} catch (error) {
|
|
39165
|
+
logger.error(`Failed to save project config: ${error}`);
|
|
39166
|
+
res.status(500).json({ error: "Failed to save project configuration" });
|
|
39167
|
+
}
|
|
39168
|
+
});
|
|
39034
39169
|
}
|
|
39035
|
-
|
|
39170
|
+
function deepMerge2(target, source) {
|
|
39171
|
+
const result = { ...target };
|
|
39172
|
+
const dangerousKeys = ["__proto__", "constructor", "prototype"];
|
|
39173
|
+
for (const key of Object.keys(source)) {
|
|
39174
|
+
if (dangerousKeys.includes(key))
|
|
39175
|
+
continue;
|
|
39176
|
+
const sourceVal = source[key];
|
|
39177
|
+
if (sourceVal && typeof sourceVal === "object" && !Array.isArray(sourceVal)) {
|
|
39178
|
+
result[key] = deepMerge2(result[key] || {}, sourceVal);
|
|
39179
|
+
} else {
|
|
39180
|
+
result[key] = sourceVal;
|
|
39181
|
+
}
|
|
39182
|
+
}
|
|
39183
|
+
return result;
|
|
39184
|
+
}
|
|
39185
|
+
var getEngineerKitConfigPath = () => join9(PathResolver.getGlobalKitDir(), ".ck.json");
|
|
39186
|
+
var init_config_routes = __esm(() => {
|
|
39036
39187
|
init_config();
|
|
39037
|
-
init_ck_config_schema();
|
|
39038
39188
|
init_logger();
|
|
39039
39189
|
init_path_resolver();
|
|
39040
|
-
init_types2();
|
|
39041
39190
|
});
|
|
39042
39191
|
|
|
39043
39192
|
// src/domains/web-server/routes/health-routes.ts
|
|
@@ -43459,7 +43608,7 @@ async function buildProjectInfoFromRegistry(registered) {
|
|
|
43459
43608
|
} catch {}
|
|
43460
43609
|
}
|
|
43461
43610
|
} catch {}
|
|
43462
|
-
const hasLocalConfig = hasClaudeDir &&
|
|
43611
|
+
const hasLocalConfig = hasClaudeDir && ConfigManager.projectConfigExists(registered.path, false);
|
|
43463
43612
|
const settings = await readSettings();
|
|
43464
43613
|
const skills = await scanSkills();
|
|
43465
43614
|
const settingsPath = join17(homedir10(), ".claude", "settings.json");
|
|
@@ -43500,7 +43649,7 @@ async function detectAndBuildProjectInfo(path2, id) {
|
|
|
43500
43649
|
} catch {}
|
|
43501
43650
|
}
|
|
43502
43651
|
} catch {}
|
|
43503
|
-
const hasLocalConfig =
|
|
43652
|
+
const hasLocalConfig = ConfigManager.projectConfigExists(path2, id === "global");
|
|
43504
43653
|
const settings = await readSettings();
|
|
43505
43654
|
const skills = await scanSkills();
|
|
43506
43655
|
const settingsPath = join17(homedir10(), ".claude", "settings.json");
|
|
@@ -43849,7 +43998,7 @@ var init_skills_discovery = __esm(() => {
|
|
|
43849
43998
|
|
|
43850
43999
|
// src/commands/skills/skills-registry.ts
|
|
43851
44000
|
import { existsSync as existsSync14 } from "node:fs";
|
|
43852
|
-
import { mkdir as
|
|
44001
|
+
import { mkdir as mkdir5, readFile as readFile12, writeFile as writeFile7 } from "node:fs/promises";
|
|
43853
44002
|
import { homedir as homedir14 } from "node:os";
|
|
43854
44003
|
import { dirname as dirname6, join as join21 } from "node:path";
|
|
43855
44004
|
function getCliVersion() {
|
|
@@ -43886,9 +44035,9 @@ async function readRegistry() {
|
|
|
43886
44035
|
async function writeRegistry(registry) {
|
|
43887
44036
|
const dir = dirname6(REGISTRY_PATH);
|
|
43888
44037
|
if (!existsSync14(dir)) {
|
|
43889
|
-
await
|
|
44038
|
+
await mkdir5(dir, { recursive: true });
|
|
43890
44039
|
}
|
|
43891
|
-
await
|
|
44040
|
+
await writeFile7(REGISTRY_PATH, JSON.stringify(registry, null, 2), "utf-8");
|
|
43892
44041
|
}
|
|
43893
44042
|
async function addInstallation(skill, agent, global3, path2, sourcePath) {
|
|
43894
44043
|
const registry = await readRegistry();
|
|
@@ -43962,7 +44111,7 @@ var init_skills_registry = __esm(() => {
|
|
|
43962
44111
|
|
|
43963
44112
|
// src/commands/skills/skills-installer.ts
|
|
43964
44113
|
import { existsSync as existsSync15 } from "node:fs";
|
|
43965
|
-
import { cp, mkdir as
|
|
44114
|
+
import { cp, mkdir as mkdir6, stat as stat7 } from "node:fs/promises";
|
|
43966
44115
|
import { dirname as dirname7, resolve as resolve6 } from "node:path";
|
|
43967
44116
|
function isSamePath(path1, path2) {
|
|
43968
44117
|
try {
|
|
@@ -44007,7 +44156,7 @@ async function installSkillForAgent(skill, agent, options2) {
|
|
|
44007
44156
|
try {
|
|
44008
44157
|
const parentDir = dirname7(targetPath);
|
|
44009
44158
|
if (!existsSync15(parentDir)) {
|
|
44010
|
-
await
|
|
44159
|
+
await mkdir6(parentDir, { recursive: true });
|
|
44011
44160
|
}
|
|
44012
44161
|
if (existsSync15(targetPath)) {
|
|
44013
44162
|
const stats = await stat7(targetPath);
|
|
@@ -44585,38 +44734,10 @@ var init_pnpm_detector = __esm(() => {
|
|
|
44585
44734
|
});
|
|
44586
44735
|
|
|
44587
44736
|
// src/domains/installation/package-managers/detection-core.ts
|
|
44588
|
-
import { existsSync as existsSync17
|
|
44589
|
-
import { chmod as chmod2, mkdir as
|
|
44737
|
+
import { existsSync as existsSync17 } from "node:fs";
|
|
44738
|
+
import { chmod as chmod2, mkdir as mkdir7, readFile as readFile13, writeFile as writeFile8 } from "node:fs/promises";
|
|
44590
44739
|
import { platform as platform4 } from "node:os";
|
|
44591
|
-
import { join as join23
|
|
44592
|
-
function detectFromBinaryPath() {
|
|
44593
|
-
try {
|
|
44594
|
-
const scriptPath = process.argv[1];
|
|
44595
|
-
if (!scriptPath)
|
|
44596
|
-
return "unknown";
|
|
44597
|
-
let resolvedPath;
|
|
44598
|
-
try {
|
|
44599
|
-
resolvedPath = realpathSync(scriptPath);
|
|
44600
|
-
} catch {
|
|
44601
|
-
resolvedPath = scriptPath;
|
|
44602
|
-
}
|
|
44603
|
-
const normalized = resolvedPath.split(sep).join("/").toLowerCase();
|
|
44604
|
-
logger.verbose(`Binary path resolved: ${normalized}`);
|
|
44605
|
-
if (normalized.includes("/.bun/install/") || normalized.includes("/bun/install/global/")) {
|
|
44606
|
-
return "bun";
|
|
44607
|
-
}
|
|
44608
|
-
if (normalized.includes("/pnpm/global/") || normalized.includes("/.local/share/pnpm/")) {
|
|
44609
|
-
return "pnpm";
|
|
44610
|
-
}
|
|
44611
|
-
if (normalized.includes("/yarn/global/") || normalized.includes("/.config/yarn/")) {
|
|
44612
|
-
return "yarn";
|
|
44613
|
-
}
|
|
44614
|
-
if (normalized.includes("/npm/node_modules/") || normalized.includes("/usr/local/lib/node_modules/") || normalized.includes("/usr/lib/node_modules/") || normalized.includes("/opt/homebrew/lib/node_modules/") || normalized.includes("/.nvm/versions/node/") || normalized.includes("/n/versions/node/") || normalized.includes("/appdata/roaming/npm/")) {
|
|
44615
|
-
return "npm";
|
|
44616
|
-
}
|
|
44617
|
-
} catch {}
|
|
44618
|
-
return "unknown";
|
|
44619
|
-
}
|
|
44740
|
+
import { join as join23 } from "node:path";
|
|
44620
44741
|
function detectFromEnv() {
|
|
44621
44742
|
const userAgent = process.env.npm_config_user_agent;
|
|
44622
44743
|
if (userAgent) {
|
|
@@ -44633,14 +44754,13 @@ function detectFromEnv() {
|
|
|
44633
44754
|
const execPath = process.env.npm_execpath;
|
|
44634
44755
|
if (execPath) {
|
|
44635
44756
|
logger.debug(`Detected exec path: ${execPath}`);
|
|
44636
|
-
|
|
44637
|
-
if (/\/bun([/.]|$)/.test(normalizedExec) || normalizedExec.startsWith("bun"))
|
|
44757
|
+
if (execPath.includes("bun"))
|
|
44638
44758
|
return "bun";
|
|
44639
|
-
if (
|
|
44759
|
+
if (execPath.includes("yarn"))
|
|
44640
44760
|
return "yarn";
|
|
44641
|
-
if (
|
|
44761
|
+
if (execPath.includes("pnpm"))
|
|
44642
44762
|
return "pnpm";
|
|
44643
|
-
if (
|
|
44763
|
+
if (execPath.includes("npm"))
|
|
44644
44764
|
return "npm";
|
|
44645
44765
|
}
|
|
44646
44766
|
return "unknown";
|
|
@@ -44658,8 +44778,8 @@ async function readCachedPm() {
|
|
|
44658
44778
|
return null;
|
|
44659
44779
|
}
|
|
44660
44780
|
const age = Date.now() - data.detectedAt;
|
|
44661
|
-
if (age
|
|
44662
|
-
logger.debug(
|
|
44781
|
+
if (age > CACHE_TTL) {
|
|
44782
|
+
logger.debug("Cache expired, will re-detect");
|
|
44663
44783
|
return null;
|
|
44664
44784
|
}
|
|
44665
44785
|
const validPms = ["npm", "bun", "yarn", "pnpm"];
|
|
@@ -44680,7 +44800,7 @@ async function saveCachedPm(pm, getVersion) {
|
|
|
44680
44800
|
const configDir = PathResolver.getConfigDir(false);
|
|
44681
44801
|
const cacheFile = join23(configDir, CACHE_FILE);
|
|
44682
44802
|
if (!existsSync17(configDir)) {
|
|
44683
|
-
await
|
|
44803
|
+
await mkdir7(configDir, { recursive: true });
|
|
44684
44804
|
if (platform4() !== "win32") {
|
|
44685
44805
|
await chmod2(configDir, 448);
|
|
44686
44806
|
}
|
|
@@ -44691,7 +44811,7 @@ async function saveCachedPm(pm, getVersion) {
|
|
|
44691
44811
|
detectedAt: Date.now(),
|
|
44692
44812
|
version: version ?? undefined
|
|
44693
44813
|
};
|
|
44694
|
-
await
|
|
44814
|
+
await writeFile8(cacheFile, JSON.stringify(data, null, 2), "utf-8");
|
|
44695
44815
|
if (platform4() !== "win32") {
|
|
44696
44816
|
await chmod2(cacheFile, 384);
|
|
44697
44817
|
}
|
|
@@ -44768,18 +44888,6 @@ var init_package_manager_detector = __esm(() => {
|
|
|
44768
44888
|
PackageManagerDetector = class PackageManagerDetector {
|
|
44769
44889
|
static async detect() {
|
|
44770
44890
|
logger.verbose("PackageManagerDetector: Starting detection");
|
|
44771
|
-
const binaryPm = detectFromBinaryPath();
|
|
44772
|
-
if (binaryPm !== "unknown") {
|
|
44773
|
-
logger.verbose(`PackageManagerDetector: Detected from binary path: ${binaryPm}`);
|
|
44774
|
-
const cachedPm2 = await readCachedPm();
|
|
44775
|
-
if (cachedPm2 && cachedPm2 !== binaryPm) {
|
|
44776
|
-
logger.verbose(`PackageManagerDetector: Cache says ${cachedPm2}, binary says ${binaryPm} — updating cache`);
|
|
44777
|
-
await saveCachedPm(binaryPm, PackageManagerDetector.getVersion);
|
|
44778
|
-
} else if (!cachedPm2) {
|
|
44779
|
-
await saveCachedPm(binaryPm, PackageManagerDetector.getVersion);
|
|
44780
|
-
}
|
|
44781
|
-
return binaryPm;
|
|
44782
|
-
}
|
|
44783
44891
|
const envPm = detectFromEnv();
|
|
44784
44892
|
if (envPm !== "unknown") {
|
|
44785
44893
|
logger.verbose(`PackageManagerDetector: Detected from env: ${envPm}`);
|
|
@@ -45277,7 +45385,7 @@ var package_default;
|
|
|
45277
45385
|
var init_package = __esm(() => {
|
|
45278
45386
|
package_default = {
|
|
45279
45387
|
name: "claudekit-cli",
|
|
45280
|
-
version: "3.34.1
|
|
45388
|
+
version: "3.34.1",
|
|
45281
45389
|
description: "CLI tool for bootstrapping and updating ClaudeKit projects",
|
|
45282
45390
|
type: "module",
|
|
45283
45391
|
repository: {
|
|
@@ -45376,6 +45484,7 @@ var init_package = __esm(() => {
|
|
|
45376
45484
|
"@types/tar": "^6.1.13",
|
|
45377
45485
|
"@types/tmp": "^0.2.6",
|
|
45378
45486
|
"@types/ws": "^8.18.1",
|
|
45487
|
+
"conventional-changelog-conventionalcommits": "^9.1.0",
|
|
45379
45488
|
"semantic-release": "^24.2.0",
|
|
45380
45489
|
typescript: "^5.7.2"
|
|
45381
45490
|
}
|
|
@@ -45592,15 +45701,12 @@ Run 'ck update' to install`, "Update Check");
|
|
|
45592
45701
|
s.stop("Update failed");
|
|
45593
45702
|
const errorMessage = error instanceof Error ? error.message : "Unknown error";
|
|
45594
45703
|
if (errorMessage.includes("EACCES") || errorMessage.includes("EPERM") || errorMessage.includes("permission") || errorMessage.includes("Access is denied")) {
|
|
45595
|
-
|
|
45704
|
+
throw new CliUpdateError(`Permission denied. Try: sudo ${updateCmd}
|
|
45596
45705
|
|
|
45597
|
-
Or fix npm permissions: https://docs.npmjs.com/resolving-eacces-permissions-errors-when-installing-packages-globally`
|
|
45598
|
-
const isWindows3 = process.platform === "win32";
|
|
45599
|
-
const elevationHint = isWindows3 ? `Run your terminal as Administrator and retry: ${updateCmd}` : `sudo ${updateCmd}`;
|
|
45600
|
-
throw new CliUpdateError(`Permission denied. Try: ${elevationHint}${permHint}`);
|
|
45706
|
+
Or fix npm permissions: https://docs.npmjs.com/resolving-eacces-permissions-errors-when-installing-packages-globally`);
|
|
45601
45707
|
}
|
|
45602
45708
|
logger.error(`Update failed: ${errorMessage}`);
|
|
45603
|
-
logger.info(
|
|
45709
|
+
logger.info("Try running: npm install -g claudekit-cli@latest");
|
|
45604
45710
|
throw new CliUpdateError(`Update failed: ${errorMessage}
|
|
45605
45711
|
|
|
45606
45712
|
Manual update: ${updateCmd}`);
|
|
@@ -46094,7 +46200,7 @@ var init_error_handler2 = __esm(() => {
|
|
|
46094
46200
|
|
|
46095
46201
|
// src/domains/versioning/release-cache.ts
|
|
46096
46202
|
import { existsSync as existsSync18 } from "node:fs";
|
|
46097
|
-
import { mkdir as
|
|
46203
|
+
import { mkdir as mkdir8, readFile as readFile17, unlink as unlink3, writeFile as writeFile10 } from "node:fs/promises";
|
|
46098
46204
|
import { join as join27 } from "node:path";
|
|
46099
46205
|
var ReleaseCacheEntrySchema, ReleaseCache;
|
|
46100
46206
|
var init_release_cache = __esm(() => {
|
|
@@ -46140,12 +46246,12 @@ var init_release_cache = __esm(() => {
|
|
|
46140
46246
|
async set(key, releases) {
|
|
46141
46247
|
const cacheFile = this.getCachePath(key);
|
|
46142
46248
|
try {
|
|
46143
|
-
await
|
|
46249
|
+
await mkdir8(this.cacheDir, { recursive: true, mode: 448 });
|
|
46144
46250
|
const cacheEntry = {
|
|
46145
46251
|
timestamp: Date.now(),
|
|
46146
46252
|
releases
|
|
46147
46253
|
};
|
|
46148
|
-
await
|
|
46254
|
+
await writeFile10(cacheFile, JSON.stringify(cacheEntry, null, 2), "utf-8");
|
|
46149
46255
|
logger.debug(`Release cache set for key: ${key}, cached ${releases.length} releases`);
|
|
46150
46256
|
} catch (error) {
|
|
46151
46257
|
logger.debug(`Failed to set release cache for key ${key}: ${error}`);
|
|
@@ -46856,7 +46962,7 @@ var init_version_utils = __esm(() => {
|
|
|
46856
46962
|
|
|
46857
46963
|
// src/domains/versioning/version-cache.ts
|
|
46858
46964
|
import { existsSync as existsSync19 } from "node:fs";
|
|
46859
|
-
import { mkdir as
|
|
46965
|
+
import { mkdir as mkdir9, readFile as readFile18, writeFile as writeFile11 } from "node:fs/promises";
|
|
46860
46966
|
import { join as join28 } from "node:path";
|
|
46861
46967
|
var VersionCacheManager;
|
|
46862
46968
|
var init_version_cache = __esm(() => {
|
|
@@ -46894,9 +47000,9 @@ var init_version_cache = __esm(() => {
|
|
|
46894
47000
|
const cacheDir = PathResolver.getCacheDir(false);
|
|
46895
47001
|
try {
|
|
46896
47002
|
if (!existsSync19(cacheDir)) {
|
|
46897
|
-
await
|
|
47003
|
+
await mkdir9(cacheDir, { recursive: true, mode: 448 });
|
|
46898
47004
|
}
|
|
46899
|
-
await
|
|
47005
|
+
await writeFile11(cacheFile, JSON.stringify(cache3, null, 2), "utf-8");
|
|
46900
47006
|
logger.debug(`Version check cache saved to ${cacheFile}`);
|
|
46901
47007
|
} catch (error) {
|
|
46902
47008
|
logger.debug(`Failed to save version check cache: ${error}`);
|
|
@@ -47476,6 +47582,7 @@ var init_user_routes = __esm(() => {
|
|
|
47476
47582
|
function registerRoutes(app) {
|
|
47477
47583
|
registerHealthRoutes(app);
|
|
47478
47584
|
registerActionRoutes(app);
|
|
47585
|
+
registerConfigRoutes(app);
|
|
47479
47586
|
registerCkConfigRoutes(app);
|
|
47480
47587
|
registerProjectRoutes(app);
|
|
47481
47588
|
registerSkillRoutes(app);
|
|
@@ -47487,6 +47594,7 @@ function registerRoutes(app) {
|
|
|
47487
47594
|
var init_routes = __esm(() => {
|
|
47488
47595
|
init_action_routes();
|
|
47489
47596
|
init_ck_config_routes();
|
|
47597
|
+
init_config_routes();
|
|
47490
47598
|
init_project_routes();
|
|
47491
47599
|
init_session_routes();
|
|
47492
47600
|
init_settings_routes();
|
|
@@ -52939,7 +53047,7 @@ var init_skills_installer2 = __esm(() => {
|
|
|
52939
53047
|
|
|
52940
53048
|
// src/services/package-installer/gemini-mcp/config-manager.ts
|
|
52941
53049
|
import { existsSync as existsSync32 } from "node:fs";
|
|
52942
|
-
import { mkdir as
|
|
53050
|
+
import { mkdir as mkdir13, readFile as readFile26, writeFile as writeFile16 } from "node:fs/promises";
|
|
52943
53051
|
import { dirname as dirname11, join as join50 } from "node:path";
|
|
52944
53052
|
async function readJsonFile(filePath) {
|
|
52945
53053
|
try {
|
|
@@ -52970,7 +53078,7 @@ async function addGeminiToGitignore(projectDir) {
|
|
|
52970
53078
|
`) || content === "" ? "" : `
|
|
52971
53079
|
`;
|
|
52972
53080
|
const comment = "# Gemini CLI settings (contains user-specific config)";
|
|
52973
|
-
await
|
|
53081
|
+
await writeFile16(gitignorePath, `${content}${newLine}${comment}
|
|
52974
53082
|
${geminiPattern}
|
|
52975
53083
|
`, "utf-8");
|
|
52976
53084
|
logger.debug(`Added ${geminiPattern} to .gitignore`);
|
|
@@ -52982,7 +53090,7 @@ ${geminiPattern}
|
|
|
52982
53090
|
async function createNewSettingsWithMerge(geminiSettingsPath, mcpConfigPath) {
|
|
52983
53091
|
const linkDir = dirname11(geminiSettingsPath);
|
|
52984
53092
|
if (!existsSync32(linkDir)) {
|
|
52985
|
-
await
|
|
53093
|
+
await mkdir13(linkDir, { recursive: true });
|
|
52986
53094
|
logger.debug(`Created directory: ${linkDir}`);
|
|
52987
53095
|
}
|
|
52988
53096
|
const mcpConfig = await readJsonFile(mcpConfigPath);
|
|
@@ -52995,7 +53103,7 @@ async function createNewSettingsWithMerge(geminiSettingsPath, mcpConfigPath) {
|
|
|
52995
53103
|
}
|
|
52996
53104
|
const newSettings = { mcpServers };
|
|
52997
53105
|
try {
|
|
52998
|
-
await
|
|
53106
|
+
await writeFile16(geminiSettingsPath, JSON.stringify(newSettings, null, 2), "utf-8");
|
|
52999
53107
|
logger.debug(`Created new Gemini settings with mcpServers: ${geminiSettingsPath}`);
|
|
53000
53108
|
return { success: true, method: "merge", targetPath: mcpConfigPath };
|
|
53001
53109
|
} catch (error) {
|
|
@@ -53025,7 +53133,7 @@ async function mergeGeminiSettings(geminiSettingsPath, mcpConfigPath) {
|
|
|
53025
53133
|
mcpServers
|
|
53026
53134
|
};
|
|
53027
53135
|
try {
|
|
53028
|
-
await
|
|
53136
|
+
await writeFile16(geminiSettingsPath, JSON.stringify(mergedSettings, null, 2), "utf-8");
|
|
53029
53137
|
logger.debug(`Merged mcpServers into: ${geminiSettingsPath}`);
|
|
53030
53138
|
return { success: true, method: "merge", targetPath: mcpConfigPath };
|
|
53031
53139
|
} catch (error) {
|
|
@@ -53098,12 +53206,12 @@ var init_validation = __esm(() => {
|
|
|
53098
53206
|
|
|
53099
53207
|
// src/services/package-installer/gemini-mcp/linker-core.ts
|
|
53100
53208
|
import { existsSync as existsSync34 } from "node:fs";
|
|
53101
|
-
import { mkdir as
|
|
53209
|
+
import { mkdir as mkdir14, symlink as symlink2 } from "node:fs/promises";
|
|
53102
53210
|
import { dirname as dirname12, join as join52 } from "node:path";
|
|
53103
53211
|
async function createSymlink(targetPath, linkPath, projectDir, isGlobal) {
|
|
53104
53212
|
const linkDir = dirname12(linkPath);
|
|
53105
53213
|
if (!existsSync34(linkDir)) {
|
|
53106
|
-
await
|
|
53214
|
+
await mkdir14(linkDir, { recursive: true });
|
|
53107
53215
|
logger.debug(`Created directory: ${linkDir}`);
|
|
53108
53216
|
}
|
|
53109
53217
|
let symlinkTarget;
|
|
@@ -60907,7 +61015,7 @@ function checkComponentCounts(setup) {
|
|
|
60907
61015
|
// src/domains/health-checks/checkers/permissions-checker.ts
|
|
60908
61016
|
init_logger();
|
|
60909
61017
|
init_path_resolver();
|
|
60910
|
-
import { constants as constants2, access as access2, unlink as unlink4, writeFile as
|
|
61018
|
+
import { constants as constants2, access as access2, unlink as unlink4, writeFile as writeFile12 } from "node:fs/promises";
|
|
60911
61019
|
import { join as join34 } from "node:path";
|
|
60912
61020
|
|
|
60913
61021
|
// src/domains/health-checks/checkers/shared.ts
|
|
@@ -60978,7 +61086,7 @@ async function checkGlobalDirWritable() {
|
|
|
60978
61086
|
const random = Math.random().toString(36).substring(2);
|
|
60979
61087
|
const testFile = join34(globalDir, `.ck-write-test-${timestamp}-${random}`);
|
|
60980
61088
|
try {
|
|
60981
|
-
await
|
|
61089
|
+
await writeFile12(testFile, "test", { encoding: "utf-8", flag: "wx" });
|
|
60982
61090
|
} catch (error) {
|
|
60983
61091
|
return {
|
|
60984
61092
|
id: "ck-global-dir-writable",
|
|
@@ -62008,7 +62116,7 @@ import { platform as platform6 } from "node:os";
|
|
|
62008
62116
|
|
|
62009
62117
|
// src/domains/health-checks/platform/environment-checker.ts
|
|
62010
62118
|
init_path_resolver();
|
|
62011
|
-
import { constants as constants3, access as access3, mkdir as
|
|
62119
|
+
import { constants as constants3, access as access3, mkdir as mkdir10, readFile as readFile23, unlink as unlink5, writeFile as writeFile13 } from "node:fs/promises";
|
|
62012
62120
|
import { arch as arch2, homedir as homedir16, platform as platform5 } from "node:os";
|
|
62013
62121
|
import { join as join42, normalize as normalize6 } from "node:path";
|
|
62014
62122
|
var IS_WINDOWS = platform5() === "win32";
|
|
@@ -62106,8 +62214,8 @@ async function checkGlobalDirAccess() {
|
|
|
62106
62214
|
}
|
|
62107
62215
|
const testFile = join42(globalDir, ".ck-doctor-access-test");
|
|
62108
62216
|
try {
|
|
62109
|
-
await
|
|
62110
|
-
await
|
|
62217
|
+
await mkdir10(globalDir, { recursive: true });
|
|
62218
|
+
await writeFile13(testFile, "test", "utf-8");
|
|
62111
62219
|
const content = await readFile23(testFile, "utf-8");
|
|
62112
62220
|
await unlink5(testFile);
|
|
62113
62221
|
if (content !== "test")
|
|
@@ -62181,7 +62289,7 @@ async function checkWSLBoundary() {
|
|
|
62181
62289
|
|
|
62182
62290
|
// src/domains/health-checks/platform/windows-checker.ts
|
|
62183
62291
|
init_path_resolver();
|
|
62184
|
-
import { mkdir as
|
|
62292
|
+
import { mkdir as mkdir11, symlink, unlink as unlink6, writeFile as writeFile14 } from "node:fs/promises";
|
|
62185
62293
|
import { join as join43 } from "node:path";
|
|
62186
62294
|
async function checkLongPathSupport() {
|
|
62187
62295
|
if (shouldSkipExpensiveOperations4()) {
|
|
@@ -62237,8 +62345,8 @@ async function checkSymlinkSupport() {
|
|
|
62237
62345
|
const target = join43(testDir, ".ck-symlink-test-target");
|
|
62238
62346
|
const link = join43(testDir, ".ck-symlink-test-link");
|
|
62239
62347
|
try {
|
|
62240
|
-
await
|
|
62241
|
-
await
|
|
62348
|
+
await mkdir11(testDir, { recursive: true });
|
|
62349
|
+
await writeFile14(target, "test", "utf-8");
|
|
62242
62350
|
await symlink(target, link);
|
|
62243
62351
|
await unlink6(link);
|
|
62244
62352
|
await unlink6(target);
|
|
@@ -62992,7 +63100,7 @@ init_github_client();
|
|
|
62992
63100
|
init_logger();
|
|
62993
63101
|
init_path_resolver();
|
|
62994
63102
|
var import_compare_versions5 = __toESM(require_umd(), 1);
|
|
62995
|
-
import { mkdir as
|
|
63103
|
+
import { mkdir as mkdir12, readFile as readFile24, unlink as unlink7, writeFile as writeFile15 } from "node:fs/promises";
|
|
62996
63104
|
import { join as join45 } from "node:path";
|
|
62997
63105
|
var CACHE_TTL_HOURS = 24;
|
|
62998
63106
|
var DEFAULT_CACHE_TTL_MS = CACHE_TTL_HOURS * 60 * 60 * 1000;
|
|
@@ -63050,8 +63158,8 @@ class ConfigVersionChecker {
|
|
|
63050
63158
|
try {
|
|
63051
63159
|
const cachePath = ConfigVersionChecker.getCacheFilePath(kitType, global3);
|
|
63052
63160
|
const cacheDir = PathResolver.getCacheDir(global3);
|
|
63053
|
-
await
|
|
63054
|
-
await
|
|
63161
|
+
await mkdir12(cacheDir, { recursive: true });
|
|
63162
|
+
await writeFile15(cachePath, JSON.stringify(cache3, null, 2));
|
|
63055
63163
|
} catch (error) {
|
|
63056
63164
|
logger.debug(`Cache write failed: ${error instanceof Error ? error.message : "Unknown error"}`);
|
|
63057
63165
|
}
|
|
@@ -65712,7 +65820,7 @@ init_logger();
|
|
|
65712
65820
|
// src/shared/process-lock.ts
|
|
65713
65821
|
init_logger();
|
|
65714
65822
|
var import_proper_lockfile = __toESM(require_proper_lockfile(), 1);
|
|
65715
|
-
import { mkdir as
|
|
65823
|
+
import { mkdir as mkdir15 } from "node:fs/promises";
|
|
65716
65824
|
import os5 from "node:os";
|
|
65717
65825
|
import { join as join53 } from "node:path";
|
|
65718
65826
|
var LOCK_CONFIG = {
|
|
@@ -65745,7 +65853,7 @@ function registerCleanupHandlers() {
|
|
|
65745
65853
|
}
|
|
65746
65854
|
async function ensureLocksDir() {
|
|
65747
65855
|
const lockDir = getLocksDir();
|
|
65748
|
-
await
|
|
65856
|
+
await mkdir15(lockDir, { recursive: true });
|
|
65749
65857
|
}
|
|
65750
65858
|
async function withProcessLock(lockName, fn) {
|
|
65751
65859
|
registerCleanupHandlers();
|
|
@@ -65900,7 +66008,7 @@ init_github_client();
|
|
|
65900
66008
|
init_environment();
|
|
65901
66009
|
init_logger();
|
|
65902
66010
|
init_safe_spinner();
|
|
65903
|
-
import { mkdir as
|
|
66011
|
+
import { mkdir as mkdir21, stat as stat12 } from "node:fs/promises";
|
|
65904
66012
|
import { tmpdir as tmpdir3 } from "node:os";
|
|
65905
66013
|
import { join as join61 } from "node:path";
|
|
65906
66014
|
|
|
@@ -65920,7 +66028,7 @@ var import_ignore = __toESM(require_ignore(), 1);
|
|
|
65920
66028
|
init_logger();
|
|
65921
66029
|
init_output_manager();
|
|
65922
66030
|
import { createWriteStream as createWriteStream2, rmSync } from "node:fs";
|
|
65923
|
-
import { mkdir as
|
|
66031
|
+
import { mkdir as mkdir16 } from "node:fs/promises";
|
|
65924
66032
|
import { join as join55 } from "node:path";
|
|
65925
66033
|
|
|
65926
66034
|
// src/shared/progress-bar.ts
|
|
@@ -66085,7 +66193,7 @@ init_types2();
|
|
|
66085
66193
|
|
|
66086
66194
|
// src/domains/installation/utils/path-security.ts
|
|
66087
66195
|
init_types2();
|
|
66088
|
-
import { lstatSync as lstatSync2, realpathSync
|
|
66196
|
+
import { lstatSync as lstatSync2, realpathSync } from "node:fs";
|
|
66089
66197
|
import { relative as relative5, resolve as resolve10 } from "node:path";
|
|
66090
66198
|
var MAX_EXTRACTION_SIZE = 500 * 1024 * 1024;
|
|
66091
66199
|
function isPathSafe(basePath, targetPath) {
|
|
@@ -66093,7 +66201,7 @@ function isPathSafe(basePath, targetPath) {
|
|
|
66093
66201
|
try {
|
|
66094
66202
|
const stat10 = lstatSync2(targetPath);
|
|
66095
66203
|
if (stat10.isSymbolicLink()) {
|
|
66096
|
-
const realTarget =
|
|
66204
|
+
const realTarget = realpathSync(targetPath);
|
|
66097
66205
|
if (!realTarget.startsWith(resolvedBase)) {
|
|
66098
66206
|
return false;
|
|
66099
66207
|
}
|
|
@@ -66132,7 +66240,7 @@ class FileDownloader {
|
|
|
66132
66240
|
async downloadAsset(asset, destDir) {
|
|
66133
66241
|
try {
|
|
66134
66242
|
const destPath = join55(destDir, asset.name);
|
|
66135
|
-
await
|
|
66243
|
+
await mkdir16(destDir, { recursive: true });
|
|
66136
66244
|
output.info(`Downloading ${asset.name} (${formatBytes(asset.size)})...`);
|
|
66137
66245
|
logger.verbose("Download details", {
|
|
66138
66246
|
url: asset.browser_download_url,
|
|
@@ -66217,7 +66325,7 @@ class FileDownloader {
|
|
|
66217
66325
|
async downloadFile(params) {
|
|
66218
66326
|
const { url, name, size, destDir, token } = params;
|
|
66219
66327
|
const destPath = join55(destDir, name);
|
|
66220
|
-
await
|
|
66328
|
+
await mkdir16(destDir, { recursive: true });
|
|
66221
66329
|
output.info(`Downloading ${name}${size ? ` (${formatBytes(size)})` : ""}...`);
|
|
66222
66330
|
const headers = {};
|
|
66223
66331
|
if (token && url.includes("api.github.com")) {
|
|
@@ -66335,7 +66443,7 @@ async function validateExtraction(extractDir) {
|
|
|
66335
66443
|
|
|
66336
66444
|
// src/domains/installation/extraction/tar-extractor.ts
|
|
66337
66445
|
init_logger();
|
|
66338
|
-
import { copyFile as copyFile3, mkdir as
|
|
66446
|
+
import { copyFile as copyFile3, mkdir as mkdir19, readdir as readdir11, rm as rm3, stat as stat10 } from "node:fs/promises";
|
|
66339
66447
|
import { join as join59 } from "node:path";
|
|
66340
66448
|
|
|
66341
66449
|
// node_modules/@isaacs/fs-minipass/dist/esm/index.js
|
|
@@ -71965,7 +72073,7 @@ var checkCwd = (dir, cb) => {
|
|
|
71965
72073
|
cb(er);
|
|
71966
72074
|
});
|
|
71967
72075
|
};
|
|
71968
|
-
var
|
|
72076
|
+
var mkdir17 = (dir, opt, cb) => {
|
|
71969
72077
|
dir = normalizeWindowsPath(dir);
|
|
71970
72078
|
const umask = opt.umask ?? 18;
|
|
71971
72079
|
const mode = opt.mode | 448;
|
|
@@ -72488,7 +72596,7 @@ class Unpack extends Parser {
|
|
|
72488
72596
|
}
|
|
72489
72597
|
}
|
|
72490
72598
|
[MKDIR](dir, mode, cb) {
|
|
72491
|
-
|
|
72599
|
+
mkdir17(normalizeWindowsPath(dir), {
|
|
72492
72600
|
uid: this.uid,
|
|
72493
72601
|
gid: this.gid,
|
|
72494
72602
|
processUid: this.processUid,
|
|
@@ -73204,7 +73312,7 @@ function decodeFilePath(path10) {
|
|
|
73204
73312
|
// src/domains/installation/utils/file-utils.ts
|
|
73205
73313
|
init_logger();
|
|
73206
73314
|
init_types2();
|
|
73207
|
-
import { copyFile as copyFile2, lstat as lstat4, mkdir as
|
|
73315
|
+
import { copyFile as copyFile2, lstat as lstat4, mkdir as mkdir18, readdir as readdir10 } from "node:fs/promises";
|
|
73208
73316
|
import { join as join58, relative as relative6 } from "node:path";
|
|
73209
73317
|
async function withRetry(fn, retries = 3) {
|
|
73210
73318
|
for (let i = 0;i < retries; i++) {
|
|
@@ -73224,7 +73332,7 @@ var isRetryable = (e2) => {
|
|
|
73224
73332
|
};
|
|
73225
73333
|
var delay = (ms) => new Promise((r2) => setTimeout(r2, ms));
|
|
73226
73334
|
async function moveDirectoryContents(sourceDir, destDir, shouldExclude, sizeTracker) {
|
|
73227
|
-
await
|
|
73335
|
+
await mkdir18(destDir, { recursive: true });
|
|
73228
73336
|
const entries = await readdir10(sourceDir, { encoding: "utf8" });
|
|
73229
73337
|
for (const entry of entries) {
|
|
73230
73338
|
const sourcePath = join58(sourceDir, entry);
|
|
@@ -73252,7 +73360,7 @@ async function moveDirectoryContents(sourceDir, destDir, shouldExclude, sizeTrac
|
|
|
73252
73360
|
}
|
|
73253
73361
|
}
|
|
73254
73362
|
async function copyDirectory(sourceDir, destDir, shouldExclude, sizeTracker) {
|
|
73255
|
-
await
|
|
73363
|
+
await mkdir18(destDir, { recursive: true });
|
|
73256
73364
|
const entries = await readdir10(sourceDir, { encoding: "utf8" });
|
|
73257
73365
|
for (const entry of entries) {
|
|
73258
73366
|
const sourcePath = join58(sourceDir, entry);
|
|
@@ -73284,7 +73392,7 @@ async function copyDirectory(sourceDir, destDir, shouldExclude, sizeTracker) {
|
|
|
73284
73392
|
class TarExtractor {
|
|
73285
73393
|
async extract(archivePath, destDir, shouldExclude, sizeTracker) {
|
|
73286
73394
|
const tempExtractDir = `${destDir}-temp`;
|
|
73287
|
-
await
|
|
73395
|
+
await mkdir19(tempExtractDir, { recursive: true });
|
|
73288
73396
|
try {
|
|
73289
73397
|
await extract({
|
|
73290
73398
|
file: archivePath,
|
|
@@ -73319,7 +73427,7 @@ class TarExtractor {
|
|
|
73319
73427
|
await moveDirectoryContents(tempExtractDir, destDir, shouldExclude, sizeTracker);
|
|
73320
73428
|
}
|
|
73321
73429
|
} else {
|
|
73322
|
-
await
|
|
73430
|
+
await mkdir19(destDir, { recursive: true });
|
|
73323
73431
|
await copyFile3(rootPath, join59(destDir, rootEntry));
|
|
73324
73432
|
}
|
|
73325
73433
|
} else {
|
|
@@ -73342,7 +73450,7 @@ init_environment();
|
|
|
73342
73450
|
init_logger();
|
|
73343
73451
|
var import_extract_zip = __toESM(require_extract_zip(), 1);
|
|
73344
73452
|
import { execFile as execFile8 } from "node:child_process";
|
|
73345
|
-
import { copyFile as copyFile4, mkdir as
|
|
73453
|
+
import { copyFile as copyFile4, mkdir as mkdir20, readdir as readdir12, rm as rm4, stat as stat11 } from "node:fs/promises";
|
|
73346
73454
|
import { join as join60 } from "node:path";
|
|
73347
73455
|
class ZipExtractor {
|
|
73348
73456
|
async tryNativeUnzip(archivePath, destDir) {
|
|
@@ -73350,7 +73458,7 @@ class ZipExtractor {
|
|
|
73350
73458
|
return false;
|
|
73351
73459
|
}
|
|
73352
73460
|
return new Promise((resolve11) => {
|
|
73353
|
-
|
|
73461
|
+
mkdir20(destDir, { recursive: true }).then(() => {
|
|
73354
73462
|
execFile8("unzip", ["-o", "-q", archivePath, "-d", destDir], (error, _stdout, stderr) => {
|
|
73355
73463
|
if (error) {
|
|
73356
73464
|
logger.debug(`Native unzip failed: ${stderr || error.message}`);
|
|
@@ -73368,7 +73476,7 @@ class ZipExtractor {
|
|
|
73368
73476
|
}
|
|
73369
73477
|
async extract(archivePath, destDir, shouldExclude, sizeTracker) {
|
|
73370
73478
|
const tempExtractDir = `${destDir}-temp`;
|
|
73371
|
-
await
|
|
73479
|
+
await mkdir20(tempExtractDir, { recursive: true });
|
|
73372
73480
|
try {
|
|
73373
73481
|
const nativeSuccess = await this.tryNativeUnzip(archivePath, tempExtractDir);
|
|
73374
73482
|
if (!nativeSuccess) {
|
|
@@ -73406,7 +73514,7 @@ class ZipExtractor {
|
|
|
73406
73514
|
await moveDirectoryContents(tempExtractDir, destDir, shouldExclude, sizeTracker);
|
|
73407
73515
|
}
|
|
73408
73516
|
} else {
|
|
73409
|
-
await
|
|
73517
|
+
await mkdir20(destDir, { recursive: true });
|
|
73410
73518
|
await copyFile4(rootPath, join60(destDir, rootEntry));
|
|
73411
73519
|
}
|
|
73412
73520
|
} else {
|
|
@@ -73481,7 +73589,7 @@ class DownloadManager {
|
|
|
73481
73589
|
try {
|
|
73482
73590
|
this.sizeTracker.reset();
|
|
73483
73591
|
const detectedType = archiveType || detectArchiveType(archivePath);
|
|
73484
|
-
await
|
|
73592
|
+
await mkdir21(destDir, { recursive: true });
|
|
73485
73593
|
if (detectedType === "tar.gz") {
|
|
73486
73594
|
await this.tarExtractor.extract(archivePath, destDir, this.shouldExclude, this.sizeTracker);
|
|
73487
73595
|
} else if (detectedType === "zip") {
|
|
@@ -73508,7 +73616,7 @@ class DownloadManager {
|
|
|
73508
73616
|
const counter = DownloadManager.tempDirCounter++;
|
|
73509
73617
|
const primaryTempDir = join61(tmpdir3(), `claudekit-${timestamp}-${counter}`);
|
|
73510
73618
|
try {
|
|
73511
|
-
await
|
|
73619
|
+
await mkdir21(primaryTempDir, { recursive: true });
|
|
73512
73620
|
logger.debug(`Created temp directory: ${primaryTempDir}`);
|
|
73513
73621
|
registerTempDir(primaryTempDir);
|
|
73514
73622
|
return primaryTempDir;
|
|
@@ -73525,7 +73633,7 @@ Solutions:
|
|
|
73525
73633
|
}
|
|
73526
73634
|
const fallbackTempDir = join61(homeDir, ".claudekit", "tmp", `claudekit-${timestamp}-${counter}`);
|
|
73527
73635
|
try {
|
|
73528
|
-
await
|
|
73636
|
+
await mkdir21(fallbackTempDir, { recursive: true });
|
|
73529
73637
|
logger.debug(`Created temp directory (fallback): ${fallbackTempDir}`);
|
|
73530
73638
|
logger.warning(`Using fallback temp directory: ${fallbackTempDir}
|
|
73531
73639
|
(OS temp directory was not accessible)`);
|
|
@@ -73876,7 +73984,7 @@ import { join as join77 } from "node:path";
|
|
|
73876
73984
|
|
|
73877
73985
|
// src/domains/installation/deletion-handler.ts
|
|
73878
73986
|
import { existsSync as existsSync35, lstatSync as lstatSync3, readdirSync as readdirSync2, rmSync as rmSync2, rmdirSync, unlinkSync as unlinkSync3 } from "node:fs";
|
|
73879
|
-
import { dirname as dirname14, join as join64, relative as relative7, resolve as resolve12, sep
|
|
73987
|
+
import { dirname as dirname14, join as join64, relative as relative7, resolve as resolve12, sep } from "node:path";
|
|
73880
73988
|
|
|
73881
73989
|
// src/services/file-operations/manifest/manifest-reader.ts
|
|
73882
73990
|
init_metadata_migration();
|
|
@@ -74115,7 +74223,7 @@ function cleanupEmptyDirectories(filePath, claudeDir2) {
|
|
|
74115
74223
|
function deletePath(fullPath, claudeDir2) {
|
|
74116
74224
|
const normalizedPath = resolve12(fullPath);
|
|
74117
74225
|
const normalizedClaudeDir = resolve12(claudeDir2);
|
|
74118
|
-
if (!normalizedPath.startsWith(`${normalizedClaudeDir}${
|
|
74226
|
+
if (!normalizedPath.startsWith(`${normalizedClaudeDir}${sep}`) && normalizedPath !== normalizedClaudeDir) {
|
|
74119
74227
|
throw new Error(`Path traversal detected: ${fullPath}`);
|
|
74120
74228
|
}
|
|
74121
74229
|
try {
|
|
@@ -74189,7 +74297,7 @@ async function handleDeletions(sourceMetadata, claudeDir2) {
|
|
|
74189
74297
|
const fullPath = join64(claudeDir2, path11);
|
|
74190
74298
|
const normalizedPath = resolve12(fullPath);
|
|
74191
74299
|
const normalizedClaudeDir = resolve12(claudeDir2);
|
|
74192
|
-
if (!normalizedPath.startsWith(`${normalizedClaudeDir}${
|
|
74300
|
+
if (!normalizedPath.startsWith(`${normalizedClaudeDir}${sep}`)) {
|
|
74193
74301
|
logger.warning(`Skipping invalid path: ${path11}`);
|
|
74194
74302
|
result.errors.push(path11);
|
|
74195
74303
|
continue;
|
|
@@ -75212,8 +75320,8 @@ var path11 = {
|
|
|
75212
75320
|
win32: { sep: "\\" },
|
|
75213
75321
|
posix: { sep: "/" }
|
|
75214
75322
|
};
|
|
75215
|
-
var
|
|
75216
|
-
minimatch.sep =
|
|
75323
|
+
var sep2 = defaultPlatform === "win32" ? path11.win32.sep : path11.posix.sep;
|
|
75324
|
+
minimatch.sep = sep2;
|
|
75217
75325
|
var GLOBSTAR = Symbol("globstar **");
|
|
75218
75326
|
minimatch.GLOBSTAR = GLOBSTAR;
|
|
75219
75327
|
var qmark2 = "[^/]";
|
|
@@ -75894,13 +76002,10 @@ class FileScanner {
|
|
|
75894
76002
|
}
|
|
75895
76003
|
}
|
|
75896
76004
|
|
|
75897
|
-
// src/domains/installation/merger/settings-processor.ts
|
|
75898
|
-
import { execSync as execSync4 } from "node:child_process";
|
|
75899
|
-
|
|
75900
76005
|
// src/domains/config/installed-settings-tracker.ts
|
|
75901
76006
|
init_shared();
|
|
75902
76007
|
import { existsSync as existsSync36 } from "node:fs";
|
|
75903
|
-
import { mkdir as
|
|
76008
|
+
import { mkdir as mkdir22, readFile as readFile29, writeFile as writeFile18 } from "node:fs/promises";
|
|
75904
76009
|
import { dirname as dirname15, join as join66 } from "node:path";
|
|
75905
76010
|
var CK_JSON_FILE = ".ck.json";
|
|
75906
76011
|
|
|
@@ -75952,8 +76057,8 @@ class InstalledSettingsTracker {
|
|
|
75952
76057
|
data.kits[this.kitName] = {};
|
|
75953
76058
|
}
|
|
75954
76059
|
data.kits[this.kitName].installedSettings = settings;
|
|
75955
|
-
await
|
|
75956
|
-
await
|
|
76060
|
+
await mkdir22(dirname15(ckJsonPath), { recursive: true });
|
|
76061
|
+
await writeFile18(ckJsonPath, JSON.stringify(data, null, 2), "utf-8");
|
|
75957
76062
|
logger.debug(`Saved installed settings to ${ckJsonPath}`);
|
|
75958
76063
|
} catch (error) {
|
|
75959
76064
|
logger.warning(`Failed to save installed settings: ${error instanceof Error ? error.message : "Unknown error"}`);
|
|
@@ -75995,17 +76100,14 @@ init_settings_merger();
|
|
|
75995
76100
|
init_environment();
|
|
75996
76101
|
init_logger();
|
|
75997
76102
|
var import_fs_extra11 = __toESM(require_lib3(), 1);
|
|
75998
|
-
var import_semver2 = __toESM(require_semver2(), 1);
|
|
75999
76103
|
|
|
76000
76104
|
class SettingsProcessor {
|
|
76001
|
-
static MIN_TEAM_HOOKS_VERSION = "2.1.33";
|
|
76002
76105
|
isGlobal = false;
|
|
76003
76106
|
forceOverwriteSettings = false;
|
|
76004
76107
|
projectDir = "";
|
|
76005
76108
|
kitName = "engineer";
|
|
76006
76109
|
tracker = null;
|
|
76007
76110
|
installingKit;
|
|
76008
|
-
cachedVersion = undefined;
|
|
76009
76111
|
setGlobalFlag(isGlobal) {
|
|
76010
76112
|
this.isGlobal = isGlobal;
|
|
76011
76113
|
}
|
|
@@ -76051,9 +76153,8 @@ class SettingsProcessor {
|
|
|
76051
76153
|
} else {
|
|
76052
76154
|
const formattedContent = this.formatJsonContent(transformedSource);
|
|
76053
76155
|
await import_fs_extra11.writeFile(destFile, formattedContent, "utf-8");
|
|
76054
|
-
let parsedSettings;
|
|
76055
76156
|
try {
|
|
76056
|
-
parsedSettings = JSON.parse(formattedContent);
|
|
76157
|
+
const parsedSettings = JSON.parse(formattedContent);
|
|
76057
76158
|
if (this.forceOverwriteSettings && destExists) {
|
|
76058
76159
|
logger.debug("Force overwrite enabled, replaced settings.json completely");
|
|
76059
76160
|
if (this.tracker) {
|
|
@@ -76062,7 +76163,6 @@ class SettingsProcessor {
|
|
|
76062
76163
|
}
|
|
76063
76164
|
await this.trackInstalledSettings(parsedSettings);
|
|
76064
76165
|
} catch {}
|
|
76065
|
-
await this.injectTeamHooksIfSupported(destFile, parsedSettings);
|
|
76066
76166
|
}
|
|
76067
76167
|
} catch (error) {
|
|
76068
76168
|
logger.error(`Failed to process settings.json: ${error}`);
|
|
@@ -76123,7 +76223,6 @@ class SettingsProcessor {
|
|
|
76123
76223
|
}
|
|
76124
76224
|
await SettingsMerger.writeSettingsFile(destFile, mergeResult.merged);
|
|
76125
76225
|
logger.success("Merged settings.json (user customizations preserved)");
|
|
76126
|
-
await this.injectTeamHooksIfSupported(destFile, mergeResult.merged);
|
|
76127
76226
|
}
|
|
76128
76227
|
async trackInstalledSettings(settings) {
|
|
76129
76228
|
if (!this.tracker)
|
|
@@ -76195,80 +76294,6 @@ class SettingsProcessor {
|
|
|
76195
76294
|
}
|
|
76196
76295
|
return transformed;
|
|
76197
76296
|
}
|
|
76198
|
-
detectClaudeCodeVersion() {
|
|
76199
|
-
if (this.cachedVersion !== undefined)
|
|
76200
|
-
return this.cachedVersion;
|
|
76201
|
-
try {
|
|
76202
|
-
const output2 = execSync4("claude --version", {
|
|
76203
|
-
encoding: "utf-8",
|
|
76204
|
-
timeout: 5000,
|
|
76205
|
-
stdio: ["ignore", "pipe", "ignore"]
|
|
76206
|
-
});
|
|
76207
|
-
const match2 = output2.match(/(\d+\.\d+\.\d+)/);
|
|
76208
|
-
this.cachedVersion = match2 ? match2[1] : null;
|
|
76209
|
-
} catch {
|
|
76210
|
-
this.cachedVersion = null;
|
|
76211
|
-
}
|
|
76212
|
-
return this.cachedVersion;
|
|
76213
|
-
}
|
|
76214
|
-
isVersionAtLeast(version, minimum) {
|
|
76215
|
-
const coerced = import_semver2.default.coerce(version);
|
|
76216
|
-
if (!coerced)
|
|
76217
|
-
return false;
|
|
76218
|
-
return import_semver2.default.gte(coerced, minimum);
|
|
76219
|
-
}
|
|
76220
|
-
async injectTeamHooksIfSupported(destFile, existingSettings) {
|
|
76221
|
-
const version = this.detectClaudeCodeVersion();
|
|
76222
|
-
if (!version) {
|
|
76223
|
-
logger.debug("Claude Code version not detected, skipping team hooks injection");
|
|
76224
|
-
return;
|
|
76225
|
-
}
|
|
76226
|
-
if (!this.isVersionAtLeast(version, SettingsProcessor.MIN_TEAM_HOOKS_VERSION)) {
|
|
76227
|
-
logger.debug(`Claude Code ${version} does not support team hooks (requires >= 2.1.33), skipping injection`);
|
|
76228
|
-
return;
|
|
76229
|
-
}
|
|
76230
|
-
logger.debug(`Claude Code ${version} detected, checking team hooks`);
|
|
76231
|
-
const settings = existingSettings ?? await SettingsMerger.readSettingsFile(destFile);
|
|
76232
|
-
if (!settings) {
|
|
76233
|
-
logger.warning("Failed to read settings file for team hooks injection");
|
|
76234
|
-
return;
|
|
76235
|
-
}
|
|
76236
|
-
const prefix = this.isGlobal ? isWindows() ? "%USERPROFILE%" : "$HOME" : isWindows() ? "%CLAUDE_PROJECT_DIR%" : "$CLAUDE_PROJECT_DIR";
|
|
76237
|
-
if (!settings.hooks) {
|
|
76238
|
-
settings.hooks = {};
|
|
76239
|
-
}
|
|
76240
|
-
let injected = false;
|
|
76241
|
-
const installedSettings = this.tracker ? await this.tracker.loadInstalledSettings() : { hooks: [], mcpServers: [] };
|
|
76242
|
-
const teamHooks = [
|
|
76243
|
-
{ event: "TaskCompleted", handler: "task-completed-handler.cjs" },
|
|
76244
|
-
{ event: "TeammateIdle", handler: "teammate-idle-handler.cjs" }
|
|
76245
|
-
];
|
|
76246
|
-
for (const { event, handler } of teamHooks) {
|
|
76247
|
-
const hookCommand = `node ${prefix}/.claude/hooks/${handler}`;
|
|
76248
|
-
const eventHooks = settings.hooks[event];
|
|
76249
|
-
if (eventHooks && eventHooks.length > 0)
|
|
76250
|
-
continue;
|
|
76251
|
-
if (this.tracker?.wasHookInstalled(hookCommand, installedSettings)) {
|
|
76252
|
-
logger.debug(`Skipping ${event} hook injection (previously removed by user)`);
|
|
76253
|
-
continue;
|
|
76254
|
-
}
|
|
76255
|
-
settings.hooks[event] = [{ hooks: [{ type: "command", command: hookCommand }] }];
|
|
76256
|
-
logger.info(`Injected ${event} hook`);
|
|
76257
|
-
injected = true;
|
|
76258
|
-
if (this.tracker) {
|
|
76259
|
-
this.tracker.trackHook(hookCommand, installedSettings);
|
|
76260
|
-
}
|
|
76261
|
-
}
|
|
76262
|
-
if (injected) {
|
|
76263
|
-
await SettingsMerger.writeSettingsFile(destFile, settings);
|
|
76264
|
-
if (this.tracker) {
|
|
76265
|
-
await this.tracker.saveInstalledSettings(installedSettings);
|
|
76266
|
-
}
|
|
76267
|
-
logger.success("Team hooks injected successfully");
|
|
76268
|
-
} else {
|
|
76269
|
-
logger.debug("Team hooks already present, no injection needed");
|
|
76270
|
-
}
|
|
76271
|
-
}
|
|
76272
76297
|
}
|
|
76273
76298
|
|
|
76274
76299
|
// src/domains/installation/merger/copy-executor.ts
|
|
@@ -77205,12 +77230,12 @@ class FileScanner2 {
|
|
|
77205
77230
|
// src/services/transformers/commands-prefix/prefix-applier.ts
|
|
77206
77231
|
init_logger();
|
|
77207
77232
|
var import_fs_extra17 = __toESM(require_lib3(), 1);
|
|
77208
|
-
import { lstat as lstat7, mkdir as
|
|
77233
|
+
import { lstat as lstat7, mkdir as mkdir23, readdir as readdir17, stat as stat15 } from "node:fs/promises";
|
|
77209
77234
|
import { join as join74 } from "node:path";
|
|
77210
77235
|
|
|
77211
77236
|
// src/services/transformers/commands-prefix/content-transformer.ts
|
|
77212
77237
|
init_logger();
|
|
77213
|
-
import { readFile as readFile33, readdir as readdir16, writeFile as
|
|
77238
|
+
import { readFile as readFile33, readdir as readdir16, writeFile as writeFile22 } from "node:fs/promises";
|
|
77214
77239
|
import { join as join73 } from "node:path";
|
|
77215
77240
|
var TRANSFORMABLE_EXTENSIONS = new Set([
|
|
77216
77241
|
".md",
|
|
@@ -77286,7 +77311,7 @@ async function transformCommandReferences(directory, options2 = {}) {
|
|
|
77286
77311
|
if (options2.dryRun) {
|
|
77287
77312
|
logger.debug(`[dry-run] Would transform ${changes} command ref(s) in ${fullPath}`);
|
|
77288
77313
|
} else {
|
|
77289
|
-
await
|
|
77314
|
+
await writeFile22(fullPath, transformed, "utf-8");
|
|
77290
77315
|
if (options2.verbose) {
|
|
77291
77316
|
logger.verbose(`Transformed ${changes} command ref(s) in ${fullPath}`);
|
|
77292
77317
|
}
|
|
@@ -77371,9 +77396,9 @@ async function applyPrefix(extractDir) {
|
|
|
77371
77396
|
}
|
|
77372
77397
|
await import_fs_extra17.copy(commandsDir, backupDir);
|
|
77373
77398
|
logger.verbose("Created backup of commands directory");
|
|
77374
|
-
await
|
|
77399
|
+
await mkdir23(tempDir, { recursive: true });
|
|
77375
77400
|
const ckDir = join74(tempDir, "ck");
|
|
77376
|
-
await
|
|
77401
|
+
await mkdir23(ckDir, { recursive: true });
|
|
77377
77402
|
let processedCount = 0;
|
|
77378
77403
|
for (const entry of entries) {
|
|
77379
77404
|
const sourcePath = join74(commandsDir, entry);
|
|
@@ -77811,7 +77836,7 @@ init_skip_directories();
|
|
|
77811
77836
|
init_types2();
|
|
77812
77837
|
var import_fs_extra21 = __toESM(require_lib3(), 1);
|
|
77813
77838
|
import { createHash as createHash2 } from "node:crypto";
|
|
77814
|
-
import { readFile as readFile35, readdir as readdir20, writeFile as
|
|
77839
|
+
import { readFile as readFile35, readdir as readdir20, writeFile as writeFile23 } from "node:fs/promises";
|
|
77815
77840
|
import { join as join78, relative as relative12 } from "node:path";
|
|
77816
77841
|
|
|
77817
77842
|
class SkillsManifestManager {
|
|
@@ -77835,7 +77860,7 @@ class SkillsManifestManager {
|
|
|
77835
77860
|
}
|
|
77836
77861
|
static async writeManifest(skillsDir2, manifest) {
|
|
77837
77862
|
const manifestPath = join78(skillsDir2, SkillsManifestManager.MANIFEST_FILENAME);
|
|
77838
|
-
await
|
|
77863
|
+
await writeFile23(manifestPath, JSON.stringify(manifest, null, 2), "utf-8");
|
|
77839
77864
|
logger.debug(`Wrote manifest to: ${manifestPath}`);
|
|
77840
77865
|
}
|
|
77841
77866
|
static async readManifest(skillsDir2) {
|
|
@@ -78228,7 +78253,7 @@ import { join as join84 } from "node:path";
|
|
|
78228
78253
|
|
|
78229
78254
|
// src/domains/skills/migrator/migration-executor.ts
|
|
78230
78255
|
init_logger();
|
|
78231
|
-
import { copyFile as copyFile5, mkdir as
|
|
78256
|
+
import { copyFile as copyFile5, mkdir as mkdir24, readdir as readdir22, rm as rm5 } from "node:fs/promises";
|
|
78232
78257
|
import { join as join80 } from "node:path";
|
|
78233
78258
|
var import_fs_extra24 = __toESM(require_lib3(), 1);
|
|
78234
78259
|
|
|
@@ -78391,7 +78416,7 @@ Detected changes:`;
|
|
|
78391
78416
|
|
|
78392
78417
|
// src/domains/skills/migrator/migration-executor.ts
|
|
78393
78418
|
async function copySkillDirectory(sourceDir, destDir) {
|
|
78394
|
-
await
|
|
78419
|
+
await mkdir24(destDir, { recursive: true });
|
|
78395
78420
|
const entries = await readdir22(sourceDir, { withFileTypes: true });
|
|
78396
78421
|
for (const entry of entries) {
|
|
78397
78422
|
const sourcePath = join80(sourceDir, entry.name);
|
|
@@ -78411,7 +78436,7 @@ async function executeInternal(mappings, customizations, currentSkillsDir, inter
|
|
|
78411
78436
|
const preserved = [];
|
|
78412
78437
|
const errors2 = [];
|
|
78413
78438
|
const tempDir = join80(currentSkillsDir, "..", ".skills-migration-temp");
|
|
78414
|
-
await
|
|
78439
|
+
await mkdir24(tempDir, { recursive: true });
|
|
78415
78440
|
try {
|
|
78416
78441
|
for (const mapping of mappings) {
|
|
78417
78442
|
try {
|
|
@@ -78433,7 +78458,7 @@ async function executeInternal(mappings, customizations, currentSkillsDir, inter
|
|
|
78433
78458
|
const category = mapping.category;
|
|
78434
78459
|
const targetPath = category ? join80(tempDir, category, skillName) : join80(tempDir, skillName);
|
|
78435
78460
|
if (category) {
|
|
78436
|
-
await
|
|
78461
|
+
await mkdir24(join80(tempDir, category), { recursive: true });
|
|
78437
78462
|
}
|
|
78438
78463
|
await copySkillDirectory(currentSkillPath, targetPath);
|
|
78439
78464
|
migrated.push(skillName);
|
|
@@ -78452,7 +78477,7 @@ async function executeInternal(mappings, customizations, currentSkillsDir, inter
|
|
|
78452
78477
|
}
|
|
78453
78478
|
}
|
|
78454
78479
|
await rm5(currentSkillsDir, { recursive: true, force: true });
|
|
78455
|
-
await
|
|
78480
|
+
await mkdir24(currentSkillsDir, { recursive: true });
|
|
78456
78481
|
await copySkillDirectory(tempDir, currentSkillsDir);
|
|
78457
78482
|
await rm5(tempDir, { recursive: true, force: true });
|
|
78458
78483
|
return { migrated, preserved, errors: errors2 };
|
|
@@ -78499,7 +78524,7 @@ function validateMigrationPath(path12, paramName) {
|
|
|
78499
78524
|
init_logger();
|
|
78500
78525
|
init_types2();
|
|
78501
78526
|
var import_fs_extra25 = __toESM(require_lib3(), 1);
|
|
78502
|
-
import { copyFile as copyFile6, mkdir as
|
|
78527
|
+
import { copyFile as copyFile6, mkdir as mkdir25, readdir as readdir23, rm as rm6, stat as stat16 } from "node:fs/promises";
|
|
78503
78528
|
import { basename as basename8, join as join81, normalize as normalize8 } from "node:path";
|
|
78504
78529
|
function validatePath2(path12, paramName) {
|
|
78505
78530
|
if (!path12 || typeof path12 !== "string") {
|
|
@@ -78529,7 +78554,7 @@ class SkillsBackupManager {
|
|
|
78529
78554
|
const backupDir = parentDir ? join81(parentDir, backupDirName) : join81(skillsDir2, "..", backupDirName);
|
|
78530
78555
|
logger.info(`Creating backup at: ${backupDir}`);
|
|
78531
78556
|
try {
|
|
78532
|
-
await
|
|
78557
|
+
await mkdir25(backupDir, { recursive: true });
|
|
78533
78558
|
await SkillsBackupManager.copyDirectory(skillsDir2, backupDir);
|
|
78534
78559
|
logger.success("Backup created successfully");
|
|
78535
78560
|
return backupDir;
|
|
@@ -78551,7 +78576,7 @@ class SkillsBackupManager {
|
|
|
78551
78576
|
if (await import_fs_extra25.pathExists(targetDir)) {
|
|
78552
78577
|
await rm6(targetDir, { recursive: true, force: true });
|
|
78553
78578
|
}
|
|
78554
|
-
await
|
|
78579
|
+
await mkdir25(targetDir, { recursive: true });
|
|
78555
78580
|
await SkillsBackupManager.copyDirectory(backupDir, targetDir);
|
|
78556
78581
|
logger.success("Backup restored successfully");
|
|
78557
78582
|
} catch (error) {
|
|
@@ -78611,7 +78636,7 @@ class SkillsBackupManager {
|
|
|
78611
78636
|
continue;
|
|
78612
78637
|
}
|
|
78613
78638
|
if (entry.isDirectory()) {
|
|
78614
|
-
await
|
|
78639
|
+
await mkdir25(destPath, { recursive: true });
|
|
78615
78640
|
await SkillsBackupManager.copyDirectory(sourcePath, destPath);
|
|
78616
78641
|
} else if (entry.isFile()) {
|
|
78617
78642
|
await copyFile6(sourcePath, destPath);
|
|
@@ -79030,7 +79055,7 @@ import { join as join87 } from "node:path";
|
|
|
79030
79055
|
|
|
79031
79056
|
// src/services/transformers/opencode-path-transformer.ts
|
|
79032
79057
|
init_logger();
|
|
79033
|
-
import { readFile as readFile37, readdir as readdir26, writeFile as
|
|
79058
|
+
import { readFile as readFile37, readdir as readdir26, writeFile as writeFile24 } from "node:fs/promises";
|
|
79034
79059
|
import { platform as platform12 } from "node:os";
|
|
79035
79060
|
import { extname as extname3, join as join86 } from "node:path";
|
|
79036
79061
|
var IS_WINDOWS3 = platform12() === "win32";
|
|
@@ -79104,7 +79129,7 @@ async function transformPathsForGlobalOpenCode(directory, options2 = {}) {
|
|
|
79104
79129
|
const content = await readFile37(fullPath, "utf-8");
|
|
79105
79130
|
const { transformed, changes } = transformOpenCodeContent(content);
|
|
79106
79131
|
if (changes > 0) {
|
|
79107
|
-
await
|
|
79132
|
+
await writeFile24(fullPath, transformed, "utf-8");
|
|
79108
79133
|
filesTransformed++;
|
|
79109
79134
|
totalChanges += changes;
|
|
79110
79135
|
if (options2.verbose) {
|
|
@@ -79325,7 +79350,7 @@ async function handlePostInstall(ctx) {
|
|
|
79325
79350
|
// src/commands/init/phases/selection-handler.ts
|
|
79326
79351
|
init_config_manager();
|
|
79327
79352
|
init_github_client();
|
|
79328
|
-
import { mkdir as
|
|
79353
|
+
import { mkdir as mkdir26 } from "node:fs/promises";
|
|
79329
79354
|
import { join as join90, resolve as resolve15 } from "node:path";
|
|
79330
79355
|
|
|
79331
79356
|
// src/domains/github/kit-access-checker.ts
|
|
@@ -79848,7 +79873,7 @@ async function handleSelection(ctx) {
|
|
|
79848
79873
|
}
|
|
79849
79874
|
if (!await import_fs_extra32.pathExists(resolvedDir)) {
|
|
79850
79875
|
if (ctx.options.global) {
|
|
79851
|
-
await
|
|
79876
|
+
await mkdir26(resolvedDir, { recursive: true });
|
|
79852
79877
|
logger.info(`Created global directory: ${resolvedDir}`);
|
|
79853
79878
|
} else {
|
|
79854
79879
|
logger.error(`Directory does not exist: ${resolvedDir}`);
|
|
@@ -79983,7 +80008,7 @@ async function handleSelection(ctx) {
|
|
|
79983
80008
|
};
|
|
79984
80009
|
}
|
|
79985
80010
|
// src/commands/init/phases/sync-handler.ts
|
|
79986
|
-
import { copyFile as copyFile7, mkdir as
|
|
80011
|
+
import { copyFile as copyFile7, mkdir as mkdir27, open as open4, readFile as readFile39, rename as rename3, stat as stat17, unlink as unlink8, writeFile as writeFile26 } from "node:fs/promises";
|
|
79987
80012
|
import { dirname as dirname18, join as join91, resolve as resolve16 } from "node:path";
|
|
79988
80013
|
init_logger();
|
|
79989
80014
|
init_path_resolver();
|
|
@@ -80103,7 +80128,7 @@ async function acquireSyncLock(global3) {
|
|
|
80103
80128
|
const lockPath = join91(cacheDir, ".sync-lock");
|
|
80104
80129
|
const startTime = Date.now();
|
|
80105
80130
|
const lockTimeout = getLockTimeout();
|
|
80106
|
-
await
|
|
80131
|
+
await mkdir27(dirname18(lockPath), { recursive: true });
|
|
80107
80132
|
while (Date.now() - startTime < lockTimeout) {
|
|
80108
80133
|
try {
|
|
80109
80134
|
const handle = await open4(lockPath, "wx");
|
|
@@ -80183,7 +80208,7 @@ async function executeSyncMerge(ctx) {
|
|
|
80183
80208
|
const targetPath = await validateSyncPath(ctx.claudeDir, file.path);
|
|
80184
80209
|
const targetDir = join91(targetPath, "..");
|
|
80185
80210
|
try {
|
|
80186
|
-
await
|
|
80211
|
+
await mkdir27(targetDir, { recursive: true });
|
|
80187
80212
|
} catch (mkdirError) {
|
|
80188
80213
|
const errCode = mkdirError.code;
|
|
80189
80214
|
if (errCode === "ENOSPC") {
|
|
@@ -80262,7 +80287,7 @@ async function executeSyncMerge(ctx) {
|
|
|
80262
80287
|
try {
|
|
80263
80288
|
const tempPath = `${currentPath}.tmp.${Date.now()}`;
|
|
80264
80289
|
try {
|
|
80265
|
-
await
|
|
80290
|
+
await writeFile26(tempPath, result.result, "utf-8");
|
|
80266
80291
|
await rename3(tempPath, currentPath);
|
|
80267
80292
|
} catch (atomicError) {
|
|
80268
80293
|
await unlink8(tempPath).catch(() => {});
|
|
@@ -80346,14 +80371,14 @@ function displaySyncPlan(plan) {
|
|
|
80346
80371
|
console.log(import_picocolors21.default.dim("─".repeat(40)));
|
|
80347
80372
|
}
|
|
80348
80373
|
async function createBackup(claudeDir2, files, backupDir) {
|
|
80349
|
-
await
|
|
80374
|
+
await mkdir27(backupDir, { recursive: true });
|
|
80350
80375
|
for (const file of files) {
|
|
80351
80376
|
try {
|
|
80352
80377
|
const sourcePath = await validateSyncPath(claudeDir2, file.path);
|
|
80353
80378
|
if (await import_fs_extra33.pathExists(sourcePath)) {
|
|
80354
80379
|
const targetPath = await validateSyncPath(backupDir, file.path);
|
|
80355
80380
|
const targetDir = join91(targetPath, "..");
|
|
80356
|
-
await
|
|
80381
|
+
await mkdir27(targetDir, { recursive: true });
|
|
80357
80382
|
await copyFile7(sourcePath, targetPath);
|
|
80358
80383
|
}
|
|
80359
80384
|
} catch (error) {
|
|
@@ -80449,7 +80474,7 @@ async function renameFolders(dirsToRename, extractDir, options2) {
|
|
|
80449
80474
|
// src/services/transformers/folder-transform/path-replacer.ts
|
|
80450
80475
|
init_logger();
|
|
80451
80476
|
init_types2();
|
|
80452
|
-
import { readFile as readFile40, readdir as readdir28, writeFile as
|
|
80477
|
+
import { readFile as readFile40, readdir as readdir28, writeFile as writeFile27 } from "node:fs/promises";
|
|
80453
80478
|
import { join as join93, relative as relative16 } from "node:path";
|
|
80454
80479
|
var TRANSFORMABLE_FILE_PATTERNS = [
|
|
80455
80480
|
".md",
|
|
@@ -80532,7 +80557,7 @@ async function transformFileContents(dir, compiledReplacements, options2) {
|
|
|
80532
80557
|
if (options2.dryRun) {
|
|
80533
80558
|
logger.debug(`[dry-run] Would update ${relative16(dir, fullPath)}: ${changeCount} replacement(s)`);
|
|
80534
80559
|
} else {
|
|
80535
|
-
await
|
|
80560
|
+
await writeFile27(fullPath, newContent, "utf-8");
|
|
80536
80561
|
logger.debug(`Updated ${relative16(dir, fullPath)}: ${changeCount} replacement(s)`);
|
|
80537
80562
|
}
|
|
80538
80563
|
filesChanged++;
|
|
@@ -80638,7 +80663,7 @@ async function transformFolderPaths(extractDir, folders, options2 = {}) {
|
|
|
80638
80663
|
|
|
80639
80664
|
// src/services/transformers/global-path-transformer.ts
|
|
80640
80665
|
init_logger();
|
|
80641
|
-
import { readFile as readFile41, readdir as readdir29, writeFile as
|
|
80666
|
+
import { readFile as readFile41, readdir as readdir29, writeFile as writeFile28 } from "node:fs/promises";
|
|
80642
80667
|
import { platform as platform13 } from "node:os";
|
|
80643
80668
|
import { extname as extname4, join as join94 } from "node:path";
|
|
80644
80669
|
var IS_WINDOWS4 = platform13() === "win32";
|
|
@@ -80761,7 +80786,7 @@ async function transformPathsForGlobalInstall(directory, options2 = {}) {
|
|
|
80761
80786
|
const content = await readFile41(fullPath, "utf-8");
|
|
80762
80787
|
const { transformed, changes } = transformContent(content);
|
|
80763
80788
|
if (changes > 0) {
|
|
80764
|
-
await
|
|
80789
|
+
await writeFile28(fullPath, transformed, "utf-8");
|
|
80765
80790
|
filesTransformed++;
|
|
80766
80791
|
totalChanges += changes;
|
|
80767
80792
|
if (options2.verbose) {
|
|
@@ -81619,10 +81644,10 @@ init_dist2();
|
|
|
81619
81644
|
|
|
81620
81645
|
// src/commands/setup/phases/preflight-check.ts
|
|
81621
81646
|
init_dist2();
|
|
81622
|
-
import { execSync as
|
|
81647
|
+
import { execSync as execSync4 } from "node:child_process";
|
|
81623
81648
|
function isGhInstalled() {
|
|
81624
81649
|
try {
|
|
81625
|
-
|
|
81650
|
+
execSync4("gh --version", { stdio: "pipe" });
|
|
81626
81651
|
return true;
|
|
81627
81652
|
} catch {
|
|
81628
81653
|
return false;
|
|
@@ -81630,7 +81655,7 @@ function isGhInstalled() {
|
|
|
81630
81655
|
}
|
|
81631
81656
|
function checkGhAuth() {
|
|
81632
81657
|
try {
|
|
81633
|
-
|
|
81658
|
+
execSync4("gh auth status", { stdio: "pipe" });
|
|
81634
81659
|
return true;
|
|
81635
81660
|
} catch {
|
|
81636
81661
|
return false;
|
|
@@ -81647,11 +81672,11 @@ function checkNodeVersion() {
|
|
|
81647
81672
|
}
|
|
81648
81673
|
function checkPython() {
|
|
81649
81674
|
try {
|
|
81650
|
-
|
|
81675
|
+
execSync4("python3 --version", { stdio: "pipe" });
|
|
81651
81676
|
return true;
|
|
81652
81677
|
} catch {
|
|
81653
81678
|
try {
|
|
81654
|
-
|
|
81679
|
+
execSync4("python --version", { stdio: "pipe" });
|
|
81655
81680
|
return true;
|
|
81656
81681
|
} catch {
|
|
81657
81682
|
return false;
|
|
@@ -82374,7 +82399,7 @@ async function detectInstallations() {
|
|
|
82374
82399
|
|
|
82375
82400
|
// src/commands/uninstall/removal-handler.ts
|
|
82376
82401
|
import { readdirSync as readdirSync5, rmSync as rmSync5 } from "node:fs";
|
|
82377
|
-
import { join as join99, resolve as resolve19, sep as
|
|
82402
|
+
import { join as join99, resolve as resolve19, sep as sep3 } from "node:path";
|
|
82378
82403
|
init_logger();
|
|
82379
82404
|
init_safe_prompts();
|
|
82380
82405
|
init_safe_spinner();
|
|
@@ -82517,7 +82542,7 @@ async function isPathSafeToRemove(filePath, baseDir) {
|
|
|
82517
82542
|
try {
|
|
82518
82543
|
const resolvedPath = resolve19(filePath);
|
|
82519
82544
|
const resolvedBase = resolve19(baseDir);
|
|
82520
|
-
if (!resolvedPath.startsWith(resolvedBase +
|
|
82545
|
+
if (!resolvedPath.startsWith(resolvedBase + sep3) && resolvedPath !== resolvedBase) {
|
|
82521
82546
|
logger.debug(`Path outside installation directory: ${filePath}`);
|
|
82522
82547
|
return false;
|
|
82523
82548
|
}
|
|
@@ -82525,7 +82550,7 @@ async function isPathSafeToRemove(filePath, baseDir) {
|
|
|
82525
82550
|
if (stats.isSymbolicLink()) {
|
|
82526
82551
|
const realPath = await import_fs_extra37.realpath(filePath);
|
|
82527
82552
|
const resolvedReal = resolve19(realPath);
|
|
82528
|
-
if (!resolvedReal.startsWith(resolvedBase +
|
|
82553
|
+
if (!resolvedReal.startsWith(resolvedBase + sep3) && resolvedReal !== resolvedBase) {
|
|
82529
82554
|
logger.debug(`Symlink points outside installation directory: ${filePath} -> ${realPath}`);
|
|
82530
82555
|
return false;
|
|
82531
82556
|
}
|