ccsini 0.1.63 → 0.1.65
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 +200 -47
- 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.
|
|
28061
|
+
var VERSION = "0.1.65";
|
|
28062
28062
|
|
|
28063
28063
|
// src/commands/init.ts
|
|
28064
28064
|
init_source();
|
|
@@ -29016,7 +29016,7 @@ class CcsiniClient {
|
|
|
29016
29016
|
headers: this.getHeaders()
|
|
29017
29017
|
});
|
|
29018
29018
|
if (!res.ok)
|
|
29019
|
-
throw new Error(
|
|
29019
|
+
throw new Error(`Failed to fetch manifest (HTTP ${res.status})`);
|
|
29020
29020
|
const data = await res.json();
|
|
29021
29021
|
if (!data.manifest)
|
|
29022
29022
|
return null;
|
|
@@ -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
|
|
30120
|
-
import { platform as
|
|
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
|
|
30126
|
-
import { platform as
|
|
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
|
-
|
|
31771
|
-
|
|
31772
|
-
|
|
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
|
|
31894
|
+
return join12(configDir, "daemon.status.json");
|
|
31788
31895
|
}
|
|
31789
31896
|
function getLogPath(configDir) {
|
|
31790
|
-
return
|
|
31897
|
+
return join12(configDir, "daemon.log");
|
|
31791
31898
|
}
|
|
31792
31899
|
function getPidPath(configDir) {
|
|
31793
|
-
return
|
|
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 =
|
|
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(
|
|
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
|
|
31959
|
-
await
|
|
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 (
|
|
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 =
|
|
32116
|
+
const cachedKeyPath = join13(configDir, ".cached-key");
|
|
31973
32117
|
try {
|
|
31974
32118
|
const cached = await readFile8(cachedKeyPath);
|
|
31975
32119
|
return new Uint8Array(cached);
|
|
@@ -31995,7 +32139,7 @@ async function ensureDaemon(configDir) {
|
|
|
31995
32139
|
}
|
|
31996
32140
|
} catch {}
|
|
31997
32141
|
try {
|
|
31998
|
-
const isWin =
|
|
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
|
|
@@ -32036,6 +32180,15 @@ function registerAutoCommands(program2) {
|
|
|
32036
32180
|
const configDir = getConfigDir();
|
|
32037
32181
|
if (!await configExists(configDir))
|
|
32038
32182
|
return;
|
|
32183
|
+
try {
|
|
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 {}
|
|
32039
32192
|
try {
|
|
32040
32193
|
const [masterKey, { client, config }, storedSession] = await Promise.all([
|
|
32041
32194
|
getMasterKey2(configDir),
|
|
@@ -32077,7 +32230,7 @@ function registerAutoCommands(program2) {
|
|
|
32077
32230
|
]);
|
|
32078
32231
|
const config = await loadKeys(configDir);
|
|
32079
32232
|
const masterKey = await deriveKeyFromPassphrase(password, config.salt);
|
|
32080
|
-
await writeFile9(
|
|
32233
|
+
await writeFile9(join13(configDir, ".cached-key"), masterKey, {
|
|
32081
32234
|
mode: 384
|
|
32082
32235
|
});
|
|
32083
32236
|
console.log("Unlocked. Auto-sync is now active.");
|
|
@@ -32093,9 +32246,9 @@ function registerAutoCommands(program2) {
|
|
|
32093
32246
|
});
|
|
32094
32247
|
program2.command("lock").description("Remove cached encryption key").action(async () => {
|
|
32095
32248
|
const configDir = getConfigDir();
|
|
32096
|
-
const { rm } = await import("fs/promises");
|
|
32249
|
+
const { rm: rm2 } = await import("fs/promises");
|
|
32097
32250
|
try {
|
|
32098
|
-
await
|
|
32251
|
+
await rm2(join13(configDir, ".cached-key"));
|
|
32099
32252
|
console.log("Locked. Auto-sync paused until next unlock.");
|
|
32100
32253
|
} catch {
|
|
32101
32254
|
console.log("Already locked.");
|
|
@@ -32106,7 +32259,7 @@ function registerAutoCommands(program2) {
|
|
|
32106
32259
|
// src/commands/doctor.ts
|
|
32107
32260
|
init_source();
|
|
32108
32261
|
import { access as access2 } from "fs/promises";
|
|
32109
|
-
import { join as
|
|
32262
|
+
import { join as join14 } from "path";
|
|
32110
32263
|
function registerDoctorCommand(program2) {
|
|
32111
32264
|
program2.command("doctor").description("Diagnose ccsini setup and connectivity").action(async () => {
|
|
32112
32265
|
const configDir = getConfigDir();
|
|
@@ -32148,7 +32301,7 @@ function registerDoctorCommand(program2) {
|
|
|
32148
32301
|
allGood = false;
|
|
32149
32302
|
}
|
|
32150
32303
|
try {
|
|
32151
|
-
await access2(
|
|
32304
|
+
await access2(join14(configDir, ".cached-key"));
|
|
32152
32305
|
console.log(source_default.green(" \u2713 Auto-sync unlocked"));
|
|
32153
32306
|
} catch {
|
|
32154
32307
|
console.log(source_default.yellow(" \u26A0 Auto-sync locked (run 'ccsini unlock')"));
|
|
@@ -32267,9 +32420,9 @@ Uninstall failed. Try manually:`);
|
|
|
32267
32420
|
init_auth();
|
|
32268
32421
|
init_src();
|
|
32269
32422
|
import { readFile as readFile9 } from "fs/promises";
|
|
32270
|
-
import { join as
|
|
32423
|
+
import { join as join15 } from "path";
|
|
32271
32424
|
async function getMasterKey3(configDir) {
|
|
32272
|
-
const cachedKeyPath =
|
|
32425
|
+
const cachedKeyPath = join15(configDir, ".cached-key");
|
|
32273
32426
|
try {
|
|
32274
32427
|
const cached = await readFile9(cachedKeyPath);
|
|
32275
32428
|
return new Uint8Array(cached);
|
|
@@ -32548,7 +32701,7 @@ function registerHooksCommands(program2) {
|
|
|
32548
32701
|
|
|
32549
32702
|
// src/commands/reset.ts
|
|
32550
32703
|
init_auth();
|
|
32551
|
-
import { rm } from "fs/promises";
|
|
32704
|
+
import { rm as rm2 } from "fs/promises";
|
|
32552
32705
|
function registerResetCommand(program2) {
|
|
32553
32706
|
program2.command("reset").description("Wipe all server data and local config (full account reset)").action(async () => {
|
|
32554
32707
|
const configDir = getConfigDir();
|
|
@@ -32590,7 +32743,7 @@ function registerResetCommand(program2) {
|
|
|
32590
32743
|
spinner.warn("Could not wipe server data (device may have been removed from dashboard)");
|
|
32591
32744
|
}
|
|
32592
32745
|
const localSpinner = ora2("Removing local config...").start();
|
|
32593
|
-
await
|
|
32746
|
+
await rm2(configDir, { recursive: true, force: true });
|
|
32594
32747
|
localSpinner.succeed("Local config removed");
|
|
32595
32748
|
console.log(chalk2.green(`
|
|
32596
32749
|
Account fully reset. Run 'ccsini init --token <token>' to start fresh.`));
|
|
@@ -32693,17 +32846,17 @@ function registerSessionsCommand(program2) {
|
|
|
32693
32846
|
|
|
32694
32847
|
// src/commands/conflicts.ts
|
|
32695
32848
|
import { readdir as readdir4, readFile as readFile10, unlink as unlink2, writeFile as writeFile10 } from "fs/promises";
|
|
32696
|
-
import { join as
|
|
32849
|
+
import { join as join16, relative as relative5 } from "path";
|
|
32697
32850
|
async function findConflictFiles(dir, base) {
|
|
32698
32851
|
base = base ?? dir;
|
|
32699
32852
|
const results = [];
|
|
32700
32853
|
const entries = await readdir4(dir, { withFileTypes: true });
|
|
32701
32854
|
for (const entry of entries) {
|
|
32702
|
-
const full =
|
|
32855
|
+
const full = join16(dir, entry.name);
|
|
32703
32856
|
if (entry.isDirectory()) {
|
|
32704
32857
|
results.push(...await findConflictFiles(full, base));
|
|
32705
32858
|
} else if (entry.name.endsWith(".conflict")) {
|
|
32706
|
-
results.push(
|
|
32859
|
+
results.push(relative5(base, full).split("\\").join("/"));
|
|
32707
32860
|
}
|
|
32708
32861
|
}
|
|
32709
32862
|
return results;
|
|
@@ -32728,14 +32881,14 @@ function registerConflictsCommand(program2) {
|
|
|
32728
32881
|
console.log();
|
|
32729
32882
|
if (opts.keep === "remote") {
|
|
32730
32883
|
for (const file of conflictFiles) {
|
|
32731
|
-
await unlink2(
|
|
32884
|
+
await unlink2(join16(claudeDir, file));
|
|
32732
32885
|
}
|
|
32733
32886
|
console.log(chalk2.green(`Resolved ${conflictFiles.length} conflict(s) \u2014 kept remote versions.`));
|
|
32734
32887
|
return;
|
|
32735
32888
|
}
|
|
32736
32889
|
if (opts.keep === "local") {
|
|
32737
32890
|
for (const file of conflictFiles) {
|
|
32738
|
-
const conflictPath =
|
|
32891
|
+
const conflictPath = join16(claudeDir, file);
|
|
32739
32892
|
const originalPath = conflictPath.replace(/\.conflict$/, "");
|
|
32740
32893
|
const conflictContent = await readFile10(conflictPath);
|
|
32741
32894
|
await writeFile10(originalPath, conflictContent);
|
|
@@ -32747,8 +32900,8 @@ function registerConflictsCommand(program2) {
|
|
|
32747
32900
|
const inquirer2 = await Promise.resolve().then(() => (init_dist16(), exports_dist));
|
|
32748
32901
|
for (const file of conflictFiles) {
|
|
32749
32902
|
const original = file.replace(/\.conflict$/, "");
|
|
32750
|
-
const conflictPath =
|
|
32751
|
-
const originalPath =
|
|
32903
|
+
const conflictPath = join16(claudeDir, file);
|
|
32904
|
+
const originalPath = join16(claudeDir, original);
|
|
32752
32905
|
const { action } = await inquirer2.default.prompt([
|
|
32753
32906
|
{
|
|
32754
32907
|
type: "list",
|
|
@@ -32784,8 +32937,8 @@ ${remaining.length} conflict(s) remaining.`));
|
|
|
32784
32937
|
|
|
32785
32938
|
// src/commands/daemon.ts
|
|
32786
32939
|
import { spawn as spawn4 } from "child_process";
|
|
32787
|
-
import { readFile as readFile11, rm as
|
|
32788
|
-
import { platform as
|
|
32940
|
+
import { readFile as readFile11, rm as rm3 } from "fs/promises";
|
|
32941
|
+
import { platform as platform6 } from "os";
|
|
32789
32942
|
function isProcessRunning(pid) {
|
|
32790
32943
|
try {
|
|
32791
32944
|
process.kill(pid, 0);
|
|
@@ -32822,10 +32975,10 @@ function registerDaemonCommands(program2) {
|
|
|
32822
32975
|
return;
|
|
32823
32976
|
}
|
|
32824
32977
|
if (existingPid !== null) {
|
|
32825
|
-
await
|
|
32826
|
-
await
|
|
32978
|
+
await rm3(getPidPath(configDir)).catch(() => {});
|
|
32979
|
+
await rm3(getStatusPath(configDir)).catch(() => {});
|
|
32827
32980
|
}
|
|
32828
|
-
const isWin =
|
|
32981
|
+
const isWin = platform6() === "win32";
|
|
32829
32982
|
const child = isWin ? spawn4("cmd", ["/c", "start", "/B", "ccsini", "daemon", "_run"], {
|
|
32830
32983
|
stdio: "ignore",
|
|
32831
32984
|
windowsHide: true
|
|
@@ -32850,15 +33003,15 @@ function registerDaemonCommands(program2) {
|
|
|
32850
33003
|
return;
|
|
32851
33004
|
}
|
|
32852
33005
|
if (!isProcessRunning(pid)) {
|
|
32853
|
-
await
|
|
32854
|
-
await
|
|
33006
|
+
await rm3(getPidPath(configDir)).catch(() => {});
|
|
33007
|
+
await rm3(getStatusPath(configDir)).catch(() => {});
|
|
32855
33008
|
console.log("Daemon is not running (cleaned up stale PID file).");
|
|
32856
33009
|
return;
|
|
32857
33010
|
}
|
|
32858
33011
|
try {
|
|
32859
33012
|
process.kill(pid, "SIGTERM");
|
|
32860
33013
|
} catch {
|
|
32861
|
-
if (
|
|
33014
|
+
if (platform6() === "win32") {
|
|
32862
33015
|
const { execSync: execSync3 } = await import("child_process");
|
|
32863
33016
|
try {
|
|
32864
33017
|
execSync3(`taskkill /PID ${pid} /T /F`, { stdio: "ignore", timeout: 5000 });
|
|
@@ -32871,8 +33024,8 @@ function registerDaemonCommands(program2) {
|
|
|
32871
33024
|
return;
|
|
32872
33025
|
}
|
|
32873
33026
|
}
|
|
32874
|
-
await
|
|
32875
|
-
await
|
|
33027
|
+
await rm3(getPidPath(configDir)).catch(() => {});
|
|
33028
|
+
await rm3(getStatusPath(configDir)).catch(() => {});
|
|
32876
33029
|
console.log("Daemon stopped.");
|
|
32877
33030
|
});
|
|
32878
33031
|
daemonCmd.command("status").description("Show daemon status").action(async () => {
|