ccsini 0.1.58 → 0.1.60

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.
Files changed (2) hide show
  1. package/dist/index.js +113 -38
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -28005,6 +28005,42 @@ var init_auth = __esm(() => {
28005
28005
  init_src();
28006
28006
  });
28007
28007
 
28008
+ // src/core/schema.ts
28009
+ var exports_schema = {};
28010
+ __export(exports_schema, {
28011
+ saveDefaultSchema: () => saveDefaultSchema,
28012
+ loadSchema: () => loadSchema,
28013
+ getEnabledCategories: () => getEnabledCategories
28014
+ });
28015
+ import { readFile as readFile2, writeFile as writeFile2 } from "fs/promises";
28016
+ import { join as join2 } from "path";
28017
+ async function saveDefaultSchema(configDir) {
28018
+ const schema = buildDefaultSchema();
28019
+ await writeFile2(join2(configDir, "schema.yaml"), JSON.stringify(schema, null, 2));
28020
+ }
28021
+ async function loadSchema(configDir) {
28022
+ const raw = await readFile2(join2(configDir, "schema.yaml"), "utf-8");
28023
+ return JSON.parse(raw);
28024
+ }
28025
+ function getEnabledCategories(schema) {
28026
+ return Object.entries(schema.categories).filter(([, config]) => config.enabled).map(([name]) => name);
28027
+ }
28028
+ function buildDefaultSchema() {
28029
+ const categories = {};
28030
+ for (const [cat, patterns] of Object.entries(DEFAULT_CATEGORY_PATTERNS)) {
28031
+ const category = cat;
28032
+ categories[category] = {
28033
+ enabled: true,
28034
+ patterns,
28035
+ merge: MERGE_STRATEGIES[category]
28036
+ };
28037
+ }
28038
+ return { version: 1, categories };
28039
+ }
28040
+ var init_schema = __esm(() => {
28041
+ init_src();
28042
+ });
28043
+
28008
28044
  // ../../node_modules/.bun/commander@13.1.0/node_modules/commander/esm.mjs
28009
28045
  var import__ = __toESM(require_commander(), 1);
28010
28046
  var {
@@ -28022,7 +28058,7 @@ var {
28022
28058
  } = import__.default;
28023
28059
 
28024
28060
  // src/version.ts
28025
- var VERSION = "0.1.58";
28061
+ var VERSION = "0.1.60";
28026
28062
 
28027
28063
  // src/commands/init.ts
28028
28064
  init_source();
@@ -28765,26 +28801,8 @@ async function saveSessionConfig(configDir, sessionConfig) {
28765
28801
  await writeFile(configPath, JSON.stringify(config, null, 2));
28766
28802
  }
28767
28803
 
28768
- // src/core/schema.ts
28769
- init_src();
28770
- import { readFile as readFile2, writeFile as writeFile2 } from "fs/promises";
28771
- import { join as join2 } from "path";
28772
- async function saveDefaultSchema(configDir) {
28773
- const schema = buildDefaultSchema();
28774
- await writeFile2(join2(configDir, "schema.yaml"), JSON.stringify(schema, null, 2));
28775
- }
28776
- function buildDefaultSchema() {
28777
- const categories = {};
28778
- for (const [cat, patterns] of Object.entries(DEFAULT_CATEGORY_PATTERNS)) {
28779
- const category = cat;
28780
- categories[category] = {
28781
- enabled: true,
28782
- patterns,
28783
- merge: MERGE_STRATEGIES[category]
28784
- };
28785
- }
28786
- return { version: 1, categories };
28787
- }
28804
+ // src/commands/init.ts
28805
+ init_schema();
28788
28806
 
28789
28807
  // src/hooks/installer.ts
28790
28808
  import { readFile as readFile3, writeFile as writeFile3 } from "fs/promises";
@@ -29082,12 +29100,27 @@ class CcsiniClient {
29082
29100
  throw new Error("Failed to reset account data");
29083
29101
  return res.json();
29084
29102
  }
29085
- async heartbeat(mode) {
29086
- await fetch(`${this.apiUrl}/api/sync/heartbeat`, {
29103
+ async heartbeat(mode, stats) {
29104
+ const res = await fetch(`${this.apiUrl}/api/sync/heartbeat`, {
29087
29105
  method: "POST",
29088
29106
  headers: this.getHeaders(),
29089
- body: JSON.stringify({ mode: mode ?? "hook" })
29107
+ body: JSON.stringify({
29108
+ mode: mode ?? "hook",
29109
+ ...stats && {
29110
+ pushCount: stats.pushCount,
29111
+ pullCount: stats.pullCount,
29112
+ lastError: stats.lastError,
29113
+ conflicts: stats.conflicts,
29114
+ version: stats.version,
29115
+ categories: stats.categories,
29116
+ conflictFiles: stats.conflictFiles
29117
+ }
29118
+ })
29090
29119
  });
29120
+ if (res.ok) {
29121
+ return res.json();
29122
+ }
29123
+ return {};
29091
29124
  }
29092
29125
  async logSyncEvent(event) {
29093
29126
  await fetch(`${this.apiUrl}/api/sync/log`, {
@@ -31758,10 +31791,53 @@ async function runDaemon() {
31758
31791
  log(configDir, `Pull error: ${e.message}`);
31759
31792
  }
31760
31793
  }
31794
+ async function listConflictFiles() {
31795
+ try {
31796
+ const { readdir: readdir4 } = await import("fs/promises");
31797
+ const files = await readdir4(configDir);
31798
+ return files.filter((f) => f.endsWith(".conflict"));
31799
+ } catch {
31800
+ return [];
31801
+ }
31802
+ }
31803
+ async function getCategories() {
31804
+ try {
31805
+ const { loadSchema: loadSchema2, getEnabledCategories: getEnabledCategories2 } = await Promise.resolve().then(() => (init_schema(), exports_schema));
31806
+ const schema = await loadSchema2(configDir);
31807
+ return getEnabledCategories2(schema);
31808
+ } catch {
31809
+ return [];
31810
+ }
31811
+ }
31812
+ async function deleteConflictFiles() {
31813
+ try {
31814
+ const { unlink: unlink2 } = await import("fs/promises");
31815
+ const files = await listConflictFiles();
31816
+ for (const f of files) {
31817
+ await unlink2(join11(configDir, f)).catch(() => {});
31818
+ }
31819
+ if (files.length > 0) {
31820
+ log(configDir, `Resolved ${files.length} conflict file(s) via dashboard`);
31821
+ }
31822
+ } catch {}
31823
+ }
31761
31824
  async function doHeartbeat() {
31762
31825
  try {
31763
31826
  const client = await getAuthenticatedClient(configDir);
31764
- await client.heartbeat("daemon");
31827
+ const conflictFiles = await listConflictFiles();
31828
+ const categories = await getCategories();
31829
+ const result = await client.heartbeat("daemon", {
31830
+ pushCount: status.pushCount,
31831
+ pullCount: status.pullCount,
31832
+ lastError: status.lastError,
31833
+ conflicts: conflictFiles.length,
31834
+ version: VERSION,
31835
+ categories,
31836
+ conflictFiles
31837
+ });
31838
+ if (result.resolveConflicts) {
31839
+ await deleteConflictFiles();
31840
+ }
31765
31841
  } catch (e) {
31766
31842
  log(configDir, `Heartbeat error: ${e.message}`);
31767
31843
  }
@@ -32675,19 +32751,18 @@ function registerDaemonCommands(program2) {
32675
32751
  console.log("Daemon is not running (cleaned up stale PID file).");
32676
32752
  return;
32677
32753
  }
32678
- const isWin = platform5() === "win32";
32679
- if (isWin) {
32680
- const { execSync: execSync3 } = await import("child_process");
32681
- try {
32682
- execSync3(`taskkill /PID ${pid} /F`, { stdio: "ignore" });
32683
- } catch {
32684
- console.error(`Failed to stop daemon (PID ${pid}).`);
32685
- return;
32686
- }
32687
- } else {
32688
- try {
32689
- process.kill(pid, "SIGTERM");
32690
- } catch {
32754
+ try {
32755
+ process.kill(pid, "SIGTERM");
32756
+ } catch {
32757
+ if (platform5() === "win32") {
32758
+ const { execSync: execSync3 } = await import("child_process");
32759
+ try {
32760
+ execSync3(`taskkill /PID ${pid} /T /F`, { stdio: "ignore", timeout: 5000 });
32761
+ } catch {
32762
+ console.error(`Failed to stop daemon (PID ${pid}). Kill it manually via Task Manager.`);
32763
+ return;
32764
+ }
32765
+ } else {
32691
32766
  console.error(`Failed to stop daemon (PID ${pid}).`);
32692
32767
  return;
32693
32768
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ccsini",
3
- "version": "0.1.58",
3
+ "version": "0.1.60",
4
4
  "description": "Claude Code seamless sync across devices",
5
5
  "type": "module",
6
6
  "bin": {