ccsini 0.1.23 → 0.1.24
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 +126 -2
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -27996,7 +27996,7 @@ var {
|
|
|
27996
27996
|
} = import__.default;
|
|
27997
27997
|
|
|
27998
27998
|
// src/version.ts
|
|
27999
|
-
var VERSION = "0.1.
|
|
27999
|
+
var VERSION = "0.1.24";
|
|
28000
28000
|
|
|
28001
28001
|
// src/commands/init.ts
|
|
28002
28002
|
init_source();
|
|
@@ -28783,6 +28783,89 @@ async function hooksInstalled(claudeDir) {
|
|
|
28783
28783
|
return false;
|
|
28784
28784
|
}
|
|
28785
28785
|
}
|
|
28786
|
+
async function fixHooks(claudeDir) {
|
|
28787
|
+
const settingsPath = join3(claudeDir, "settings.json");
|
|
28788
|
+
const details = [];
|
|
28789
|
+
let fixed = 0;
|
|
28790
|
+
let raw;
|
|
28791
|
+
try {
|
|
28792
|
+
raw = await readFile3(settingsPath, "utf-8");
|
|
28793
|
+
} catch {
|
|
28794
|
+
return { fixed, details: ["No settings.json found"] };
|
|
28795
|
+
}
|
|
28796
|
+
let settings;
|
|
28797
|
+
try {
|
|
28798
|
+
settings = JSON.parse(raw);
|
|
28799
|
+
} catch {
|
|
28800
|
+
return { fixed, details: ["settings.json is not valid JSON"] };
|
|
28801
|
+
}
|
|
28802
|
+
if (!settings.hooks)
|
|
28803
|
+
return { fixed, details };
|
|
28804
|
+
for (const hookType of Object.keys(settings.hooks)) {
|
|
28805
|
+
if (!Array.isArray(settings.hooks[hookType]))
|
|
28806
|
+
continue;
|
|
28807
|
+
for (const hookEntry of settings.hooks[hookType]) {
|
|
28808
|
+
if (!JSON.stringify(hookEntry).includes(HOOK_MARKER))
|
|
28809
|
+
continue;
|
|
28810
|
+
if ("matcher" in hookEntry && typeof hookEntry.matcher !== "string") {
|
|
28811
|
+
delete hookEntry.matcher;
|
|
28812
|
+
details.push(`Removed invalid matcher from ${hookType} hook`);
|
|
28813
|
+
fixed++;
|
|
28814
|
+
}
|
|
28815
|
+
if (Array.isArray(hookEntry.hooks)) {
|
|
28816
|
+
for (const innerHook of hookEntry.hooks) {
|
|
28817
|
+
if ("matcher" in innerHook && typeof innerHook.matcher !== "string") {
|
|
28818
|
+
delete innerHook.matcher;
|
|
28819
|
+
details.push(`Removed invalid matcher from ${hookType} inner hook`);
|
|
28820
|
+
fixed++;
|
|
28821
|
+
}
|
|
28822
|
+
}
|
|
28823
|
+
}
|
|
28824
|
+
}
|
|
28825
|
+
}
|
|
28826
|
+
if (fixed > 0) {
|
|
28827
|
+
await writeFile3(settingsPath, JSON.stringify(settings, null, 2));
|
|
28828
|
+
}
|
|
28829
|
+
return { fixed, details };
|
|
28830
|
+
}
|
|
28831
|
+
async function checkHooksHealth(claudeDir) {
|
|
28832
|
+
const settingsPath = join3(claudeDir, "settings.json");
|
|
28833
|
+
const issues = [];
|
|
28834
|
+
let raw;
|
|
28835
|
+
try {
|
|
28836
|
+
raw = await readFile3(settingsPath, "utf-8");
|
|
28837
|
+
} catch {
|
|
28838
|
+
return { healthy: true, issues };
|
|
28839
|
+
}
|
|
28840
|
+
let settings;
|
|
28841
|
+
try {
|
|
28842
|
+
settings = JSON.parse(raw);
|
|
28843
|
+
} catch {
|
|
28844
|
+
issues.push("settings.json is not valid JSON");
|
|
28845
|
+
return { healthy: false, issues };
|
|
28846
|
+
}
|
|
28847
|
+
if (!settings.hooks)
|
|
28848
|
+
return { healthy: true, issues };
|
|
28849
|
+
for (const hookType of Object.keys(settings.hooks)) {
|
|
28850
|
+
if (!Array.isArray(settings.hooks[hookType]))
|
|
28851
|
+
continue;
|
|
28852
|
+
for (const hookEntry of settings.hooks[hookType]) {
|
|
28853
|
+
if (!JSON.stringify(hookEntry).includes(HOOK_MARKER))
|
|
28854
|
+
continue;
|
|
28855
|
+
if ("matcher" in hookEntry && typeof hookEntry.matcher !== "string") {
|
|
28856
|
+
issues.push(`${hookType}: matcher is ${typeof hookEntry.matcher}, expected string`);
|
|
28857
|
+
}
|
|
28858
|
+
if (Array.isArray(hookEntry.hooks)) {
|
|
28859
|
+
for (const innerHook of hookEntry.hooks) {
|
|
28860
|
+
if ("matcher" in innerHook && typeof innerHook.matcher !== "string") {
|
|
28861
|
+
issues.push(`${hookType} inner hook: matcher is ${typeof innerHook.matcher}, expected string`);
|
|
28862
|
+
}
|
|
28863
|
+
}
|
|
28864
|
+
}
|
|
28865
|
+
}
|
|
28866
|
+
}
|
|
28867
|
+
return { healthy: issues.length === 0, issues };
|
|
28868
|
+
}
|
|
28786
28869
|
|
|
28787
28870
|
// src/core/transport.ts
|
|
28788
28871
|
class CcsiniClient {
|
|
@@ -29483,7 +29566,17 @@ function registerDoctorCommand(program2) {
|
|
|
29483
29566
|
const config = await loadKeys(configDir);
|
|
29484
29567
|
console.log(source_default.green(` \u2713 Device: ${config.deviceName} (${config.deviceId.slice(0, 8)}...)`));
|
|
29485
29568
|
if (await hooksInstalled(claudeDir)) {
|
|
29486
|
-
console.log(source_default.green(" \u2713 Hooks installed
|
|
29569
|
+
console.log(source_default.green(" \u2713 Hooks installed"));
|
|
29570
|
+
const { healthy, issues } = await checkHooksHealth(claudeDir);
|
|
29571
|
+
if (healthy) {
|
|
29572
|
+
console.log(source_default.green(" \u2713 Hooks format valid"));
|
|
29573
|
+
} else {
|
|
29574
|
+
for (const issue of issues) {
|
|
29575
|
+
console.log(source_default.red(` \u2717 ${issue}`));
|
|
29576
|
+
}
|
|
29577
|
+
console.log(source_default.yellow(" Run 'ccsini hooks fix' to repair"));
|
|
29578
|
+
allGood = false;
|
|
29579
|
+
}
|
|
29487
29580
|
} else {
|
|
29488
29581
|
console.log(source_default.yellow(" \u26A0 Hooks not installed (run 'ccsini init')"));
|
|
29489
29582
|
allGood = false;
|
|
@@ -29556,6 +29649,12 @@ function registerSelfCommands(program2) {
|
|
|
29556
29649
|
execSync(cmd, { stdio: "inherit" });
|
|
29557
29650
|
console.log(`
|
|
29558
29651
|
Updated to v${latest}`);
|
|
29652
|
+
try {
|
|
29653
|
+
const { fixed } = await fixHooks(getClaudeDir());
|
|
29654
|
+
if (fixed > 0) {
|
|
29655
|
+
console.log(`Repaired ${fixed} hook issue${fixed > 1 ? "s" : ""} in Claude Code settings.`);
|
|
29656
|
+
}
|
|
29657
|
+
} catch {}
|
|
29559
29658
|
console.log("Restart your terminal to use the new version.");
|
|
29560
29659
|
} catch {
|
|
29561
29660
|
console.error(`
|
|
@@ -29822,6 +29921,30 @@ function registerSyncCommands(program2) {
|
|
|
29822
29921
|
});
|
|
29823
29922
|
}
|
|
29824
29923
|
|
|
29924
|
+
// src/commands/hooks.ts
|
|
29925
|
+
init_source();
|
|
29926
|
+
function registerHooksCommands(program2) {
|
|
29927
|
+
const hooksCmd = program2.command("hooks").description("Manage Claude Code hooks");
|
|
29928
|
+
hooksCmd.command("fix").description("Repair broken hook entries in Claude Code settings").action(async () => {
|
|
29929
|
+
const claudeDir = getClaudeDir();
|
|
29930
|
+
console.log(source_default.bold(`
|
|
29931
|
+
Checking hooks...
|
|
29932
|
+
`));
|
|
29933
|
+
const { fixed, details } = await fixHooks(claudeDir);
|
|
29934
|
+
if (fixed === 0) {
|
|
29935
|
+
console.log(source_default.green(` Hooks are already healthy. Nothing to fix.
|
|
29936
|
+
`));
|
|
29937
|
+
return;
|
|
29938
|
+
}
|
|
29939
|
+
for (const detail of details) {
|
|
29940
|
+
console.log(source_default.yellow(` Fixed: ${detail}`));
|
|
29941
|
+
}
|
|
29942
|
+
console.log(source_default.green(`
|
|
29943
|
+
Repaired ${fixed} hook issue${fixed > 1 ? "s" : ""}.
|
|
29944
|
+
`));
|
|
29945
|
+
});
|
|
29946
|
+
}
|
|
29947
|
+
|
|
29825
29948
|
// src/index.ts
|
|
29826
29949
|
var program2 = new Command;
|
|
29827
29950
|
program2.name("ccsini").description("Claude Code seamless sync across devices").version(VERSION);
|
|
@@ -29830,6 +29953,7 @@ registerAutoCommands(program2);
|
|
|
29830
29953
|
registerDoctorCommand(program2);
|
|
29831
29954
|
registerSelfCommands(program2);
|
|
29832
29955
|
registerSyncCommands(program2);
|
|
29956
|
+
registerHooksCommands(program2);
|
|
29833
29957
|
program2.command("version").description("Show current version").action(() => {
|
|
29834
29958
|
console.log(VERSION);
|
|
29835
29959
|
});
|