ccsini 0.1.62 → 0.1.64

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 +212 -57
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -27876,7 +27876,7 @@ function decodeProjectPath(encoded) {
27876
27876
  }
27877
27877
 
27878
27878
  // ../shared/src/constants.ts
27879
- var DEFAULT_CATEGORY_PATTERNS, MERGE_STRATEGIES, NEVER_SYNC_PATTERNS, SESSION_SYNC_DEFAULTS, JWT_EXPIRY_SECONDS = 900, DAEMON_DEBOUNCE_MS = 5000, DAEMON_INTERVAL_MS = 30000, MAX_CONCURRENT_TRANSFERS = 50, BATCH_DOWNLOAD_SIZE = 20;
27879
+ var DEFAULT_CATEGORY_PATTERNS, MERGE_STRATEGIES, NEVER_SYNC_PATTERNS, SESSION_SYNC_DEFAULTS, JWT_EXPIRY_SECONDS = 900, DAEMON_DEBOUNCE_MS = 5000, DAEMON_INTERVAL_MS = 30000, MAX_CONCURRENT_TRANSFERS = 50, BATCH_DOWNLOAD_SIZE = 20, IPC_TIMEOUT_MS = 60000, IPC_SOCKET_NAME = "daemon.sock", IPC_PIPE_NAME = "ccsini-daemon";
27880
27880
  var init_constants = __esm(() => {
27881
27881
  DEFAULT_CATEGORY_PATTERNS = {
27882
27882
  session: ["projects/**/*.jsonl"],
@@ -28058,7 +28058,7 @@ var {
28058
28058
  } = import__.default;
28059
28059
 
28060
28060
  // src/version.ts
28061
- var VERSION = "0.1.62";
28061
+ var VERSION = "0.1.64";
28062
28062
 
28063
28063
  // src/commands/init.ts
28064
28064
  init_source();
@@ -30116,14 +30116,14 @@ init_auth();
30116
30116
  init_auth();
30117
30117
  init_src();
30118
30118
  import { readFile as readFile8, writeFile as writeFile9 } from "fs/promises";
30119
- import { join as join12 } from "path";
30120
- import { platform as platform4 } from "os";
30119
+ import { join as join13 } from "path";
30120
+ import { platform as platform5 } from "os";
30121
30121
  import { spawn as spawn3 } from "child_process";
30122
30122
 
30123
30123
  // src/daemon/runner.ts
30124
30124
  import { readFile as readFile7, writeFile as writeFile8 } from "fs/promises";
30125
- import { join as join11 } from "path";
30126
- import { platform as platform3 } from "os";
30125
+ import { join as join12 } from "path";
30126
+ import { platform as platform4 } from "os";
30127
30127
  import { appendFileSync } from "fs";
30128
30128
  init_auth();
30129
30129
 
@@ -31739,11 +31739,13 @@ function watch(paths, options = {}) {
31739
31739
  }
31740
31740
 
31741
31741
  // src/daemon/watcher.ts
31742
+ import { relative as relative4 } from "path";
31742
31743
  init_src();
31743
31744
  function startWatcher(onSync) {
31744
31745
  const claudeDir = getClaudeDir();
31745
31746
  let debounceTimer = null;
31746
31747
  let syncing = false;
31748
+ const dirtyPaths = new Set;
31747
31749
  const watcher = watch(claudeDir, {
31748
31750
  ignored: NEVER_SYNC_PATTERNS.map((p) => `**/${p}`),
31749
31751
  persistent: true,
@@ -31767,30 +31769,135 @@ function startWatcher(onSync) {
31767
31769
  }
31768
31770
  }, DAEMON_DEBOUNCE_MS);
31769
31771
  };
31770
- watcher.on("change", triggerSync);
31771
- watcher.on("add", triggerSync);
31772
- watcher.on("unlink", triggerSync);
31772
+ const trackAndSync = (filePath) => {
31773
+ dirtyPaths.add(relative4(claudeDir, filePath));
31774
+ triggerSync();
31775
+ };
31776
+ watcher.on("change", trackAndSync);
31777
+ watcher.on("add", trackAndSync);
31778
+ watcher.on("unlink", trackAndSync);
31773
31779
  return {
31774
31780
  stop: () => {
31775
31781
  if (debounceTimer)
31776
31782
  clearTimeout(debounceTimer);
31777
31783
  watcher.close();
31784
+ },
31785
+ hasDirty: () => dirtyPaths.size > 0,
31786
+ getDirty: () => new Set(dirtyPaths),
31787
+ clearDirty: () => dirtyPaths.clear()
31788
+ };
31789
+ }
31790
+
31791
+ // src/daemon/ipc.ts
31792
+ init_src();
31793
+ import { createServer, createConnection } from "net";
31794
+ import { join as join11 } from "path";
31795
+ import { platform as platform3 } from "os";
31796
+ import { rm } from "fs/promises";
31797
+ function getSocketPath(configDir) {
31798
+ if (platform3() === "win32") {
31799
+ return `\\\\.\\pipe\\${IPC_PIPE_NAME}`;
31800
+ }
31801
+ return join11(configDir, IPC_SOCKET_NAME);
31802
+ }
31803
+ function startIpcServer(configDir, handler) {
31804
+ const socketPath = getSocketPath(configDir);
31805
+ const server = createServer((conn) => {
31806
+ let buffer = "";
31807
+ conn.on("data", (chunk) => {
31808
+ buffer += chunk.toString();
31809
+ let newlineIdx;
31810
+ while ((newlineIdx = buffer.indexOf(`
31811
+ `)) !== -1) {
31812
+ const line = buffer.slice(0, newlineIdx).trim();
31813
+ buffer = buffer.slice(newlineIdx + 1);
31814
+ if (!line)
31815
+ continue;
31816
+ let cmd;
31817
+ try {
31818
+ cmd = JSON.parse(line);
31819
+ } catch {
31820
+ conn.write(JSON.stringify({ ok: false, error: "invalid JSON" }) + `
31821
+ `);
31822
+ return;
31823
+ }
31824
+ handler(cmd).then((result) => {
31825
+ conn.write(JSON.stringify(result) + `
31826
+ `);
31827
+ }).catch((err) => {
31828
+ conn.write(JSON.stringify({ ok: false, error: err.message }) + `
31829
+ `);
31830
+ });
31831
+ }
31832
+ });
31833
+ conn.on("error", () => {});
31834
+ });
31835
+ server.on("error", (err) => {
31836
+ if (err.code === "EADDRINUSE") {
31837
+ rm(socketPath, { force: true }).then(() => server.listen(socketPath)).catch(() => {});
31838
+ }
31839
+ });
31840
+ server.listen(socketPath);
31841
+ return {
31842
+ close: async () => {
31843
+ return new Promise((resolve3) => {
31844
+ server.close(() => {
31845
+ rm(socketPath, { force: true }).then(() => resolve3()).catch(() => resolve3());
31846
+ });
31847
+ });
31778
31848
  }
31779
31849
  };
31780
31850
  }
31851
+ async function ipcPush(configDir) {
31852
+ const socketPath = getSocketPath(configDir);
31853
+ return new Promise((resolve3) => {
31854
+ const timeout = setTimeout(() => {
31855
+ conn.destroy();
31856
+ resolve3(null);
31857
+ }, IPC_TIMEOUT_MS);
31858
+ const conn = createConnection(socketPath);
31859
+ let buffer = "";
31860
+ conn.on("connect", () => {
31861
+ conn.write(JSON.stringify({ cmd: "push-now" }) + `
31862
+ `);
31863
+ });
31864
+ conn.on("data", (chunk) => {
31865
+ buffer += chunk.toString();
31866
+ const newlineIdx = buffer.indexOf(`
31867
+ `);
31868
+ if (newlineIdx !== -1) {
31869
+ const line = buffer.slice(0, newlineIdx).trim();
31870
+ clearTimeout(timeout);
31871
+ conn.destroy();
31872
+ try {
31873
+ resolve3(JSON.parse(line));
31874
+ } catch {
31875
+ resolve3(null);
31876
+ }
31877
+ }
31878
+ });
31879
+ conn.on("error", () => {
31880
+ clearTimeout(timeout);
31881
+ resolve3(null);
31882
+ });
31883
+ conn.on("close", () => {
31884
+ clearTimeout(timeout);
31885
+ });
31886
+ });
31887
+ }
31781
31888
 
31782
31889
  // src/daemon/runner.ts
31783
31890
  init_src();
31784
31891
  init_src();
31785
31892
  var HEARTBEAT_INTERVAL_MS = 3 * 60 * 1000;
31786
31893
  function getStatusPath(configDir) {
31787
- return join11(configDir, "daemon.status.json");
31894
+ return join12(configDir, "daemon.status.json");
31788
31895
  }
31789
31896
  function getLogPath(configDir) {
31790
- return join11(configDir, "daemon.log");
31897
+ return join12(configDir, "daemon.log");
31791
31898
  }
31792
31899
  function getPidPath(configDir) {
31793
- return join11(configDir, "daemon.pid");
31900
+ return join12(configDir, "daemon.pid");
31794
31901
  }
31795
31902
  function log(configDir, message2) {
31796
31903
  const ts = new Date().toISOString();
@@ -31801,7 +31908,7 @@ function log(configDir, message2) {
31801
31908
  } catch {}
31802
31909
  }
31803
31910
  async function getMasterKey(configDir) {
31804
- const cachedKeyPath = join11(configDir, ".cached-key");
31911
+ const cachedKeyPath = join12(configDir, ".cached-key");
31805
31912
  const cached = await readFile7(cachedKeyPath);
31806
31913
  return new Uint8Array(cached);
31807
31914
  }
@@ -31854,6 +31961,7 @@ async function runDaemon() {
31854
31961
  const config = await loadKeys(configDir);
31855
31962
  const sessionOptions = await getSessionOptions(configDir);
31856
31963
  const result = await pushSync(client, masterKey, config.deviceName, configDir, undefined, sessionOptions, { skipConflictBackup: true });
31964
+ watcher.clearDirty();
31857
31965
  status.lastPushAt = Date.now();
31858
31966
  status.pushCount++;
31859
31967
  status.lastError = null;
@@ -31916,7 +32024,7 @@ async function runDaemon() {
31916
32024
  const { unlink: unlink2 } = await import("fs/promises");
31917
32025
  const files = await listConflictFiles();
31918
32026
  for (const f of files) {
31919
- await unlink2(join11(configDir, f)).catch(() => {});
32027
+ await unlink2(join12(configDir, f)).catch(() => {});
31920
32028
  }
31921
32029
  if (files.length > 0) {
31922
32030
  log(configDir, `Resolved ${files.length} conflict file(s) via dashboard`);
@@ -31945,6 +32053,41 @@ async function runDaemon() {
31945
32053
  }
31946
32054
  }
31947
32055
  const watcher = startWatcher(doPush);
32056
+ const ipcServer = startIpcServer(configDir, async (cmd) => {
32057
+ if (cmd.cmd === "push-now") {
32058
+ if (!watcher.hasDirty()) {
32059
+ return { ok: true, filesChanged: 0, durationMs: 0 };
32060
+ }
32061
+ const start = Date.now();
32062
+ try {
32063
+ const masterKey = await getMasterKey(configDir);
32064
+ const client = await getAuthenticatedClient(configDir);
32065
+ const config = await loadKeys(configDir);
32066
+ const sessionOptions = await getSessionOptions(configDir);
32067
+ const result = await pushSync(client, masterKey, config.deviceName, configDir, undefined, sessionOptions, { skipConflictBackup: true });
32068
+ watcher.clearDirty();
32069
+ status.lastPushAt = Date.now();
32070
+ status.pushCount++;
32071
+ status.lastError = null;
32072
+ await writeStatus(configDir, status);
32073
+ if (result.filesChanged > 0) {
32074
+ log(configDir, `IPC Push: ${result.filesChanged} files (${result.durationMs}ms)`);
32075
+ }
32076
+ return {
32077
+ ok: true,
32078
+ filesChanged: result.filesChanged,
32079
+ durationMs: Date.now() - start
32080
+ };
32081
+ } catch (e) {
32082
+ status.lastError = e.message;
32083
+ await writeStatus(configDir, status).catch(() => {});
32084
+ log(configDir, `IPC Push error: ${e.message}`);
32085
+ return { ok: false, error: e.message };
32086
+ }
32087
+ }
32088
+ return { ok: false, error: "unknown command" };
32089
+ });
32090
+ log(configDir, "IPC server started");
31948
32091
  const pullInterval = setInterval(doPull, DAEMON_INTERVAL_MS);
31949
32092
  const heartbeatInterval = setInterval(doHeartbeat, HEARTBEAT_INTERVAL_MS);
31950
32093
  await doPull();
@@ -31952,24 +32095,25 @@ async function runDaemon() {
31952
32095
  const shutdown = async () => {
31953
32096
  log(configDir, "Daemon shutting down...");
31954
32097
  watcher.stop();
32098
+ await ipcServer.close();
31955
32099
  clearInterval(pullInterval);
31956
32100
  clearInterval(heartbeatInterval);
31957
- const { rm } = await import("fs/promises");
31958
- await rm(getPidPath(configDir)).catch(() => {});
31959
- await rm(getStatusPath(configDir)).catch(() => {});
32101
+ const { rm: rm2 } = await import("fs/promises");
32102
+ await rm2(getPidPath(configDir)).catch(() => {});
32103
+ await rm2(getStatusPath(configDir)).catch(() => {});
31960
32104
  log(configDir, "Daemon stopped");
31961
32105
  process.exit(0);
31962
32106
  };
31963
32107
  process.on("SIGTERM", shutdown);
31964
32108
  process.on("SIGINT", shutdown);
31965
- if (platform3() === "win32") {
32109
+ if (platform4() === "win32") {
31966
32110
  process.on("SIGBREAK", shutdown);
31967
32111
  }
31968
32112
  }
31969
32113
 
31970
32114
  // src/commands/auto.ts
31971
32115
  async function getMasterKey2(configDir) {
31972
- const cachedKeyPath = join12(configDir, ".cached-key");
32116
+ const cachedKeyPath = join13(configDir, ".cached-key");
31973
32117
  try {
31974
32118
  const cached = await readFile8(cachedKeyPath);
31975
32119
  return new Uint8Array(cached);
@@ -31981,7 +32125,7 @@ async function getAuthenticatedClient2(configDir) {
31981
32125
  const config = await loadKeys(configDir);
31982
32126
  const privateKey = await importPrivateKey(config.devicePrivateKey);
31983
32127
  const jwt = await createDeviceJWT(privateKey, config.deviceId);
31984
- return new CcsiniClient(config.apiUrl, jwt);
32128
+ return { client: new CcsiniClient(config.apiUrl, jwt), config };
31985
32129
  }
31986
32130
  async function ensureDaemon(configDir) {
31987
32131
  try {
@@ -31995,7 +32139,7 @@ async function ensureDaemon(configDir) {
31995
32139
  }
31996
32140
  } catch {}
31997
32141
  try {
31998
- const isWin = platform4() === "win32";
32142
+ const isWin = platform5() === "win32";
31999
32143
  const child = isWin ? spawn3("cmd", ["/c", "start", "/B", "ccsini", "daemon", "_run"], {
32000
32144
  stdio: "ignore",
32001
32145
  windowsHide: true
@@ -32011,12 +32155,13 @@ function registerAutoCommands(program2) {
32011
32155
  const configDir = getConfigDir();
32012
32156
  if (!await configExists(configDir))
32013
32157
  return;
32014
- await ensureDaemon(configDir);
32015
32158
  try {
32016
- const masterKey = await getMasterKey2(configDir);
32017
- const client = await getAuthenticatedClient2(configDir);
32018
- const config = await loadKeys(configDir);
32019
- const storedSession = await loadSessionConfig(configDir);
32159
+ const [, masterKey, { client, config }, storedSession] = await Promise.all([
32160
+ ensureDaemon(configDir),
32161
+ getMasterKey2(configDir),
32162
+ getAuthenticatedClient2(configDir),
32163
+ loadSessionConfig(configDir)
32164
+ ]);
32020
32165
  const sessionOptions = {
32021
32166
  enabled: storedSession.enabled,
32022
32167
  maxPerProject: storedSession.maxPerProject,
@@ -32036,10 +32181,20 @@ function registerAutoCommands(program2) {
32036
32181
  if (!await configExists(configDir))
32037
32182
  return;
32038
32183
  try {
32039
- const masterKey = await getMasterKey2(configDir);
32040
- const client = await getAuthenticatedClient2(configDir);
32041
- const config = await loadKeys(configDir);
32042
- const storedSession = await loadSessionConfig(configDir);
32184
+ const ipcResult = await ipcPush(configDir);
32185
+ if (ipcResult) {
32186
+ if (ipcResult.ok && ipcResult.filesChanged && ipcResult.filesChanged > 0) {
32187
+ console.log(`[ccsini] Pushed ${ipcResult.filesChanged} files (${ipcResult.durationMs}ms) [daemon]`);
32188
+ }
32189
+ return;
32190
+ }
32191
+ } catch {}
32192
+ try {
32193
+ const [masterKey, { client, config }, storedSession] = await Promise.all([
32194
+ getMasterKey2(configDir),
32195
+ getAuthenticatedClient2(configDir),
32196
+ loadSessionConfig(configDir)
32197
+ ]);
32043
32198
  const sessionOptions = {
32044
32199
  enabled: storedSession.enabled,
32045
32200
  maxPerProject: storedSession.maxPerProject,
@@ -32075,7 +32230,7 @@ function registerAutoCommands(program2) {
32075
32230
  ]);
32076
32231
  const config = await loadKeys(configDir);
32077
32232
  const masterKey = await deriveKeyFromPassphrase(password, config.salt);
32078
- await writeFile9(join12(configDir, ".cached-key"), masterKey, {
32233
+ await writeFile9(join13(configDir, ".cached-key"), masterKey, {
32079
32234
  mode: 384
32080
32235
  });
32081
32236
  console.log("Unlocked. Auto-sync is now active.");
@@ -32085,15 +32240,15 @@ function registerAutoCommands(program2) {
32085
32240
  if (!await configExists(configDir))
32086
32241
  return;
32087
32242
  try {
32088
- const client = await getAuthenticatedClient2(configDir);
32243
+ const { client } = await getAuthenticatedClient2(configDir);
32089
32244
  await client.heartbeat();
32090
32245
  } catch {}
32091
32246
  });
32092
32247
  program2.command("lock").description("Remove cached encryption key").action(async () => {
32093
32248
  const configDir = getConfigDir();
32094
- const { rm } = await import("fs/promises");
32249
+ const { rm: rm2 } = await import("fs/promises");
32095
32250
  try {
32096
- await rm(join12(configDir, ".cached-key"));
32251
+ await rm2(join13(configDir, ".cached-key"));
32097
32252
  console.log("Locked. Auto-sync paused until next unlock.");
32098
32253
  } catch {
32099
32254
  console.log("Already locked.");
@@ -32104,7 +32259,7 @@ function registerAutoCommands(program2) {
32104
32259
  // src/commands/doctor.ts
32105
32260
  init_source();
32106
32261
  import { access as access2 } from "fs/promises";
32107
- import { join as join13 } from "path";
32262
+ import { join as join14 } from "path";
32108
32263
  function registerDoctorCommand(program2) {
32109
32264
  program2.command("doctor").description("Diagnose ccsini setup and connectivity").action(async () => {
32110
32265
  const configDir = getConfigDir();
@@ -32146,7 +32301,7 @@ function registerDoctorCommand(program2) {
32146
32301
  allGood = false;
32147
32302
  }
32148
32303
  try {
32149
- await access2(join13(configDir, ".cached-key"));
32304
+ await access2(join14(configDir, ".cached-key"));
32150
32305
  console.log(source_default.green(" \u2713 Auto-sync unlocked"));
32151
32306
  } catch {
32152
32307
  console.log(source_default.yellow(" \u26A0 Auto-sync locked (run 'ccsini unlock')"));
@@ -32265,9 +32420,9 @@ Uninstall failed. Try manually:`);
32265
32420
  init_auth();
32266
32421
  init_src();
32267
32422
  import { readFile as readFile9 } from "fs/promises";
32268
- import { join as join14 } from "path";
32423
+ import { join as join15 } from "path";
32269
32424
  async function getMasterKey3(configDir) {
32270
- const cachedKeyPath = join14(configDir, ".cached-key");
32425
+ const cachedKeyPath = join15(configDir, ".cached-key");
32271
32426
  try {
32272
32427
  const cached = await readFile9(cachedKeyPath);
32273
32428
  return new Uint8Array(cached);
@@ -32546,7 +32701,7 @@ function registerHooksCommands(program2) {
32546
32701
 
32547
32702
  // src/commands/reset.ts
32548
32703
  init_auth();
32549
- import { rm } from "fs/promises";
32704
+ import { rm as rm2 } from "fs/promises";
32550
32705
  function registerResetCommand(program2) {
32551
32706
  program2.command("reset").description("Wipe all server data and local config (full account reset)").action(async () => {
32552
32707
  const configDir = getConfigDir();
@@ -32588,7 +32743,7 @@ function registerResetCommand(program2) {
32588
32743
  spinner.warn("Could not wipe server data (device may have been removed from dashboard)");
32589
32744
  }
32590
32745
  const localSpinner = ora2("Removing local config...").start();
32591
- await rm(configDir, { recursive: true, force: true });
32746
+ await rm2(configDir, { recursive: true, force: true });
32592
32747
  localSpinner.succeed("Local config removed");
32593
32748
  console.log(chalk2.green(`
32594
32749
  Account fully reset. Run 'ccsini init --token <token>' to start fresh.`));
@@ -32691,17 +32846,17 @@ function registerSessionsCommand(program2) {
32691
32846
 
32692
32847
  // src/commands/conflicts.ts
32693
32848
  import { readdir as readdir4, readFile as readFile10, unlink as unlink2, writeFile as writeFile10 } from "fs/promises";
32694
- import { join as join15, relative as relative4 } from "path";
32849
+ import { join as join16, relative as relative5 } from "path";
32695
32850
  async function findConflictFiles(dir, base) {
32696
32851
  base = base ?? dir;
32697
32852
  const results = [];
32698
32853
  const entries = await readdir4(dir, { withFileTypes: true });
32699
32854
  for (const entry of entries) {
32700
- const full = join15(dir, entry.name);
32855
+ const full = join16(dir, entry.name);
32701
32856
  if (entry.isDirectory()) {
32702
32857
  results.push(...await findConflictFiles(full, base));
32703
32858
  } else if (entry.name.endsWith(".conflict")) {
32704
- results.push(relative4(base, full).split("\\").join("/"));
32859
+ results.push(relative5(base, full).split("\\").join("/"));
32705
32860
  }
32706
32861
  }
32707
32862
  return results;
@@ -32726,14 +32881,14 @@ function registerConflictsCommand(program2) {
32726
32881
  console.log();
32727
32882
  if (opts.keep === "remote") {
32728
32883
  for (const file of conflictFiles) {
32729
- await unlink2(join15(claudeDir, file));
32884
+ await unlink2(join16(claudeDir, file));
32730
32885
  }
32731
32886
  console.log(chalk2.green(`Resolved ${conflictFiles.length} conflict(s) \u2014 kept remote versions.`));
32732
32887
  return;
32733
32888
  }
32734
32889
  if (opts.keep === "local") {
32735
32890
  for (const file of conflictFiles) {
32736
- const conflictPath = join15(claudeDir, file);
32891
+ const conflictPath = join16(claudeDir, file);
32737
32892
  const originalPath = conflictPath.replace(/\.conflict$/, "");
32738
32893
  const conflictContent = await readFile10(conflictPath);
32739
32894
  await writeFile10(originalPath, conflictContent);
@@ -32745,8 +32900,8 @@ function registerConflictsCommand(program2) {
32745
32900
  const inquirer2 = await Promise.resolve().then(() => (init_dist16(), exports_dist));
32746
32901
  for (const file of conflictFiles) {
32747
32902
  const original = file.replace(/\.conflict$/, "");
32748
- const conflictPath = join15(claudeDir, file);
32749
- const originalPath = join15(claudeDir, original);
32903
+ const conflictPath = join16(claudeDir, file);
32904
+ const originalPath = join16(claudeDir, original);
32750
32905
  const { action } = await inquirer2.default.prompt([
32751
32906
  {
32752
32907
  type: "list",
@@ -32782,8 +32937,8 @@ ${remaining.length} conflict(s) remaining.`));
32782
32937
 
32783
32938
  // src/commands/daemon.ts
32784
32939
  import { spawn as spawn4 } from "child_process";
32785
- import { readFile as readFile11, rm as rm2 } from "fs/promises";
32786
- import { platform as platform5 } from "os";
32940
+ import { readFile as readFile11, rm as rm3 } from "fs/promises";
32941
+ import { platform as platform6 } from "os";
32787
32942
  function isProcessRunning(pid) {
32788
32943
  try {
32789
32944
  process.kill(pid, 0);
@@ -32820,10 +32975,10 @@ function registerDaemonCommands(program2) {
32820
32975
  return;
32821
32976
  }
32822
32977
  if (existingPid !== null) {
32823
- await rm2(getPidPath(configDir)).catch(() => {});
32824
- await rm2(getStatusPath(configDir)).catch(() => {});
32978
+ await rm3(getPidPath(configDir)).catch(() => {});
32979
+ await rm3(getStatusPath(configDir)).catch(() => {});
32825
32980
  }
32826
- const isWin = platform5() === "win32";
32981
+ const isWin = platform6() === "win32";
32827
32982
  const child = isWin ? spawn4("cmd", ["/c", "start", "/B", "ccsini", "daemon", "_run"], {
32828
32983
  stdio: "ignore",
32829
32984
  windowsHide: true
@@ -32848,15 +33003,15 @@ function registerDaemonCommands(program2) {
32848
33003
  return;
32849
33004
  }
32850
33005
  if (!isProcessRunning(pid)) {
32851
- await rm2(getPidPath(configDir)).catch(() => {});
32852
- await rm2(getStatusPath(configDir)).catch(() => {});
33006
+ await rm3(getPidPath(configDir)).catch(() => {});
33007
+ await rm3(getStatusPath(configDir)).catch(() => {});
32853
33008
  console.log("Daemon is not running (cleaned up stale PID file).");
32854
33009
  return;
32855
33010
  }
32856
33011
  try {
32857
33012
  process.kill(pid, "SIGTERM");
32858
33013
  } catch {
32859
- if (platform5() === "win32") {
33014
+ if (platform6() === "win32") {
32860
33015
  const { execSync: execSync3 } = await import("child_process");
32861
33016
  try {
32862
33017
  execSync3(`taskkill /PID ${pid} /T /F`, { stdio: "ignore", timeout: 5000 });
@@ -32869,8 +33024,8 @@ function registerDaemonCommands(program2) {
32869
33024
  return;
32870
33025
  }
32871
33026
  }
32872
- await rm2(getPidPath(configDir)).catch(() => {});
32873
- await rm2(getStatusPath(configDir)).catch(() => {});
33027
+ await rm3(getPidPath(configDir)).catch(() => {});
33028
+ await rm3(getStatusPath(configDir)).catch(() => {});
32874
33029
  console.log("Daemon stopped.");
32875
33030
  });
32876
33031
  daemonCmd.command("status").description("Show daemon status").action(async () => {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ccsini",
3
- "version": "0.1.62",
3
+ "version": "0.1.64",
4
4
  "description": "Claude Code seamless sync across devices",
5
5
  "type": "module",
6
6
  "bin": {