ccsini 0.1.22 → 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 +140 -9
- 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();
|
|
@@ -28750,18 +28750,25 @@ async function installHooks(claudeDir) {
|
|
|
28750
28750
|
...(settings.hooks.PreToolUse ?? []).filter((h) => !h.command?.includes(HOOK_MARKER))
|
|
28751
28751
|
];
|
|
28752
28752
|
settings.hooks.Stop = [
|
|
28753
|
-
...(settings.hooks.Stop ?? []).filter((h) => !h.
|
|
28753
|
+
...(settings.hooks.Stop ?? []).filter((h) => !JSON.stringify(h).includes(HOOK_MARKER)),
|
|
28754
28754
|
{
|
|
28755
|
-
|
|
28756
|
-
|
|
28755
|
+
hooks: [
|
|
28756
|
+
{
|
|
28757
|
+
type: "command",
|
|
28758
|
+
command: `ccsini auto-push # ${HOOK_MARKER}`
|
|
28759
|
+
}
|
|
28760
|
+
]
|
|
28757
28761
|
}
|
|
28758
28762
|
];
|
|
28759
28763
|
settings.hooks.Notification = [
|
|
28760
|
-
...(settings.hooks.Notification ?? []).filter((h) => !h.
|
|
28764
|
+
...(settings.hooks.Notification ?? []).filter((h) => !JSON.stringify(h).includes(HOOK_MARKER)),
|
|
28761
28765
|
{
|
|
28762
|
-
|
|
28763
|
-
|
|
28764
|
-
|
|
28766
|
+
hooks: [
|
|
28767
|
+
{
|
|
28768
|
+
type: "command",
|
|
28769
|
+
command: `ccsini auto-pull # ${HOOK_MARKER}`
|
|
28770
|
+
}
|
|
28771
|
+
]
|
|
28765
28772
|
}
|
|
28766
28773
|
];
|
|
28767
28774
|
await writeFile3(settingsPath, JSON.stringify(settings, null, 2));
|
|
@@ -28776,6 +28783,89 @@ async function hooksInstalled(claudeDir) {
|
|
|
28776
28783
|
return false;
|
|
28777
28784
|
}
|
|
28778
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
|
+
}
|
|
28779
28869
|
|
|
28780
28870
|
// src/core/transport.ts
|
|
28781
28871
|
class CcsiniClient {
|
|
@@ -29476,7 +29566,17 @@ function registerDoctorCommand(program2) {
|
|
|
29476
29566
|
const config = await loadKeys(configDir);
|
|
29477
29567
|
console.log(source_default.green(` \u2713 Device: ${config.deviceName} (${config.deviceId.slice(0, 8)}...)`));
|
|
29478
29568
|
if (await hooksInstalled(claudeDir)) {
|
|
29479
|
-
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
|
+
}
|
|
29480
29580
|
} else {
|
|
29481
29581
|
console.log(source_default.yellow(" \u26A0 Hooks not installed (run 'ccsini init')"));
|
|
29482
29582
|
allGood = false;
|
|
@@ -29549,6 +29649,12 @@ function registerSelfCommands(program2) {
|
|
|
29549
29649
|
execSync(cmd, { stdio: "inherit" });
|
|
29550
29650
|
console.log(`
|
|
29551
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 {}
|
|
29552
29658
|
console.log("Restart your terminal to use the new version.");
|
|
29553
29659
|
} catch {
|
|
29554
29660
|
console.error(`
|
|
@@ -29815,6 +29921,30 @@ function registerSyncCommands(program2) {
|
|
|
29815
29921
|
});
|
|
29816
29922
|
}
|
|
29817
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
|
+
|
|
29818
29948
|
// src/index.ts
|
|
29819
29949
|
var program2 = new Command;
|
|
29820
29950
|
program2.name("ccsini").description("Claude Code seamless sync across devices").version(VERSION);
|
|
@@ -29823,6 +29953,7 @@ registerAutoCommands(program2);
|
|
|
29823
29953
|
registerDoctorCommand(program2);
|
|
29824
29954
|
registerSelfCommands(program2);
|
|
29825
29955
|
registerSyncCommands(program2);
|
|
29956
|
+
registerHooksCommands(program2);
|
|
29826
29957
|
program2.command("version").description("Show current version").action(() => {
|
|
29827
29958
|
console.log(VERSION);
|
|
29828
29959
|
});
|