@synkro-sh/cli 1.4.88 → 1.4.90
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/bootstrap.js +118 -188
- package/dist/bootstrap.js.map +1 -1
- package/package.json +1 -1
package/dist/bootstrap.js
CHANGED
|
@@ -508,7 +508,7 @@ function installCursorMcpConfig(opts) {
|
|
|
508
508
|
if (entry?.[SYNKRO_MARKER3] === true) delete config.mcpServers[name];
|
|
509
509
|
}
|
|
510
510
|
if (opts.local) {
|
|
511
|
-
const port = process.env.SYNKRO_MCP_PORT || "
|
|
511
|
+
const port = process.env.SYNKRO_MCP_PORT || "18931";
|
|
512
512
|
const url2 = `http://127.0.0.1:${port}/`;
|
|
513
513
|
const jwtPath = join2(homedir3(), ".synkro", ".mcp-jwt");
|
|
514
514
|
let jwt2 = "";
|
|
@@ -986,7 +986,7 @@ export function detectRepo(cwd: string, transcriptPath?: string): string {
|
|
|
986
986
|
|
|
987
987
|
// \u2500\u2500\u2500 Channel Health \u2500\u2500\u2500
|
|
988
988
|
|
|
989
|
-
export async function channelUp(port =
|
|
989
|
+
export async function channelUp(port = 18929): Promise<boolean> {
|
|
990
990
|
return new Promise(resolve => {
|
|
991
991
|
const sock = require('node:net').connect(port, '127.0.0.1');
|
|
992
992
|
const done = (ok: boolean) => { try { sock.destroy(); } catch {} resolve(ok); };
|
|
@@ -997,7 +997,7 @@ export async function channelUp(port = 8929): Promise<boolean> {
|
|
|
997
997
|
}
|
|
998
998
|
|
|
999
999
|
export async function cweChannelUp(): Promise<boolean> {
|
|
1000
|
-
return channelUp(
|
|
1000
|
+
return channelUp(18930);
|
|
1001
1001
|
}
|
|
1002
1002
|
|
|
1003
1003
|
// \u2500\u2500\u2500 Config Loading \u2500\u2500\u2500
|
|
@@ -1030,7 +1030,7 @@ export async function loadConfig(jwt: string, query?: string): Promise<HookConfi
|
|
|
1030
1030
|
};
|
|
1031
1031
|
|
|
1032
1032
|
// Local-first: fetch from the local MCP server (PGLite-backed) \u2014 zero network egress.
|
|
1033
|
-
const mcpPort = process.env.SYNKRO_MCP_PORT || '
|
|
1033
|
+
const mcpPort = process.env.SYNKRO_MCP_PORT || '18931';
|
|
1034
1034
|
try {
|
|
1035
1035
|
const resp = await fetch('http://127.0.0.1:' + mcpPort + '/api/local/hook-config', {
|
|
1036
1036
|
signal: AbortSignal.timeout(1500),
|
|
@@ -1146,13 +1146,13 @@ export async function localGrade(surface: string, prompt: string, timeoutMs = 20
|
|
|
1146
1146
|
if (!(await channelUp())) throw new Error('SYNKRO_CHANNEL_DOWN');
|
|
1147
1147
|
const jwt = loadJwt();
|
|
1148
1148
|
if (!jwt) throw new Error('NO_JWT');
|
|
1149
|
-
return channelGrade(ROLE_MAP[surface] || 'grade-edit', prompt, jwt,
|
|
1149
|
+
return channelGrade(ROLE_MAP[surface] || 'grade-edit', prompt, jwt, 18929, timeoutMs);
|
|
1150
1150
|
}
|
|
1151
1151
|
|
|
1152
1152
|
export async function localGradeCwe(prompt: string): Promise<string> {
|
|
1153
1153
|
const jwt = loadJwt();
|
|
1154
1154
|
if (!jwt) throw new Error('NO_JWT');
|
|
1155
|
-
return channelGrade('grade-cwe', prompt, jwt,
|
|
1155
|
+
return channelGrade('grade-cwe', prompt, jwt, 18930, 45000);
|
|
1156
1156
|
}
|
|
1157
1157
|
|
|
1158
1158
|
// \u2500\u2500\u2500 Session Action Log \u2500\u2500\u2500
|
|
@@ -1273,6 +1273,13 @@ export function parseVerdict(resp: string): Verdict {
|
|
|
1273
1273
|
const okMatch = inner.match(/<ok>(.*?)<\\/ok>/);
|
|
1274
1274
|
if (okMatch) verdict.ok = okMatch[1].trim() !== 'false';
|
|
1275
1275
|
|
|
1276
|
+
const decisionMatch = inner.match(/<decision>(.*?)<\\/decision>/);
|
|
1277
|
+
if (decisionMatch) {
|
|
1278
|
+
const d = decisionMatch[1].trim().toLowerCase();
|
|
1279
|
+
if (d === 'block' || d === 'deny' || d === 'fail') verdict.ok = false;
|
|
1280
|
+
else if (d === 'allow' || d === 'pass' || d === 'approve') verdict.ok = true;
|
|
1281
|
+
}
|
|
1282
|
+
|
|
1276
1283
|
const reasonMatch = inner.match(/<reason>(.*?)<\\/reason>/) || inner.match(/<reasoning>(.*?)<\\/reasoning>/);
|
|
1277
1284
|
if (reasonMatch) verdict.reason = reasonMatch[1].trim();
|
|
1278
1285
|
|
|
@@ -1401,7 +1408,7 @@ export function dispatchCapture(
|
|
|
1401
1408
|
|
|
1402
1409
|
export function appendLocalTelemetry(body: Record<string, any>): void {
|
|
1403
1410
|
const event = { ...body, _ts: new Date().toISOString() };
|
|
1404
|
-
const mcpPort = process.env.SYNKRO_MCP_PORT || '
|
|
1411
|
+
const mcpPort = process.env.SYNKRO_MCP_PORT || '18931';
|
|
1405
1412
|
let mcpToken = '';
|
|
1406
1413
|
try { mcpToken = readFileSync(join(HOME, '.synkro', '.mcp-jwt'), 'utf-8').trim(); } catch {}
|
|
1407
1414
|
if (!mcpToken) return;
|
|
@@ -1992,7 +1999,7 @@ async function main() {
|
|
|
1992
1999
|
}
|
|
1993
2000
|
|
|
1994
2001
|
if (rt === 'local') {
|
|
1995
|
-
// \u2500\u2500\u2500 Local grading: org rules ONLY (channel 1, port
|
|
2002
|
+
// \u2500\u2500\u2500 Local grading: org rules ONLY (channel 1, port 18929) \u2500\u2500\u2500
|
|
1996
2003
|
const proposedShort = proposed.slice(0, 4000);
|
|
1997
2004
|
const sessionLog = compressSessionLog(readSessionLog(sessionId));
|
|
1998
2005
|
const graderPrompt = [
|
|
@@ -3481,7 +3488,7 @@ async function main() {
|
|
|
3481
3488
|
|
|
3482
3489
|
const fakeConfig: HookConfig = { captureDepth: 'local_only', tier: 'standard', silent, policyName, rules: [] };
|
|
3483
3490
|
const tagStr = tag(rt, fakeConfig);
|
|
3484
|
-
const routeLine = tagStr + ' inference: ' + (isChannelUp ? 'local-cc (channel reachable on 127.0.0.1:
|
|
3491
|
+
const routeLine = tagStr + ' inference: ' + (isChannelUp ? 'local-cc (channel reachable on 127.0.0.1:18929)' : 'cloud (local-cc channel not reachable)');
|
|
3485
3492
|
|
|
3486
3493
|
if (!jwt) {
|
|
3487
3494
|
outputJson({ systemMessage: routeLine });
|
|
@@ -5353,6 +5360,18 @@ var init_macKeychain = __esm({
|
|
|
5353
5360
|
});
|
|
5354
5361
|
|
|
5355
5362
|
// cli/local-cc/dockerInstall.ts
|
|
5363
|
+
var dockerInstall_exports = {};
|
|
5364
|
+
__export(dockerInstall_exports, {
|
|
5365
|
+
DockerInstallError: () => DockerInstallError,
|
|
5366
|
+
SYNKRO_DIR: () => SYNKRO_DIR3,
|
|
5367
|
+
assertDockerAvailable: () => assertDockerAvailable,
|
|
5368
|
+
dockerInstall: () => dockerInstall,
|
|
5369
|
+
dockerStatus: () => dockerStatus,
|
|
5370
|
+
dockerStop: () => dockerStop,
|
|
5371
|
+
dockerUpdate: () => dockerUpdate,
|
|
5372
|
+
imageTag: () => imageTag,
|
|
5373
|
+
waitForContainerReady: () => waitForContainerReady
|
|
5374
|
+
});
|
|
5356
5375
|
import { existsSync as existsSync8, mkdirSync as mkdirSync7 } from "fs";
|
|
5357
5376
|
import { homedir as homedir7 } from "os";
|
|
5358
5377
|
import { join as join7 } from "path";
|
|
@@ -5432,6 +5451,10 @@ async function dockerInstall(opts = {}) {
|
|
|
5432
5451
|
`${MCP_JWT_PATH}:/data/.mcp-jwt:ro`,
|
|
5433
5452
|
"-v",
|
|
5434
5453
|
`${credsDir}:/home/synkro/.claude:rw`,
|
|
5454
|
+
"-v",
|
|
5455
|
+
`${join7(homedir7(), ".claude")}:/data/claude-host:ro`,
|
|
5456
|
+
"-v",
|
|
5457
|
+
`${join7(homedir7(), ".claude.json")}:/home/synkro/.claude.json:rw`,
|
|
5435
5458
|
"-e",
|
|
5436
5459
|
`WORKERS_PER_POOL=${workers}`,
|
|
5437
5460
|
image
|
|
@@ -5459,6 +5482,10 @@ function dockerStop() {
|
|
|
5459
5482
|
spawnSync2("docker", ["stop", CONTAINER_NAME], { encoding: "utf-8", timeout: 3e4 });
|
|
5460
5483
|
spawnSync2("docker", ["rm", "-f", CONTAINER_NAME], { encoding: "utf-8", timeout: 3e4 });
|
|
5461
5484
|
}
|
|
5485
|
+
async function dockerUpdate(workersPerPool) {
|
|
5486
|
+
dockerStop();
|
|
5487
|
+
await dockerInstall({ workersPerPool });
|
|
5488
|
+
}
|
|
5462
5489
|
function dockerStatus() {
|
|
5463
5490
|
const r = spawnSync2("docker", ["inspect", "--format", "{{.State.Status}}", CONTAINER_NAME], {
|
|
5464
5491
|
encoding: "utf-8",
|
|
@@ -5642,7 +5669,7 @@ function writeConfigEnv(opts) {
|
|
|
5642
5669
|
`SYNKRO_CREDENTIALS_PATH=${shellQuoteSingle(credsPath)}`,
|
|
5643
5670
|
`SYNKRO_TIER=${shellQuoteSingle(safeTier)}`,
|
|
5644
5671
|
`SYNKRO_INFERENCE=${shellQuoteSingle(safeInference)}`,
|
|
5645
|
-
`SYNKRO_VERSION=${shellQuoteSingle("1.4.
|
|
5672
|
+
`SYNKRO_VERSION=${shellQuoteSingle("1.4.90")}`
|
|
5646
5673
|
];
|
|
5647
5674
|
if (safeSynkroBin) lines.push(`SYNKRO_CLI_BIN=${shellQuoteSingle(safeSynkroBin)}`);
|
|
5648
5675
|
if (safeUserId) lines.push(`SYNKRO_USER_ID=${shellQuoteSingle(safeUserId)}`);
|
|
@@ -6080,24 +6107,29 @@ async function installCommand(opts = {}) {
|
|
|
6080
6107
|
}
|
|
6081
6108
|
console.log();
|
|
6082
6109
|
if (profile.localInference) {
|
|
6110
|
+
const { assertDockerAvailable: assertDockerAvailable2 } = await Promise.resolve().then(() => (init_dockerInstall(), dockerInstall_exports));
|
|
6083
6111
|
try {
|
|
6084
|
-
|
|
6085
|
-
const workersPerPool = parseInt(process.env.SYNKRO_WORKERS_PER_POOL || "4", 10);
|
|
6086
|
-
const { image, hostMcpPort, hostGraderPort, hostCwePort } = await dockerInstall({ workersPerPool });
|
|
6087
|
-
console.log(` pulled ${image}`);
|
|
6088
|
-
console.log(` container started \u2014 MCP=${hostMcpPort} general=${hostGraderPort} CWE=${hostCwePort}`);
|
|
6089
|
-
console.log(" waiting for container /healthz...");
|
|
6090
|
-
const ready = await waitForContainerReady(6e4);
|
|
6091
|
-
if (ready) {
|
|
6092
|
-
console.log(" \u2713 container ready");
|
|
6093
|
-
} else {
|
|
6094
|
-
console.warn(" \u26A0 container did not become healthy within 60s \u2014 check `docker logs synkro-server`");
|
|
6095
|
-
}
|
|
6096
|
-
console.log();
|
|
6112
|
+
assertDockerAvailable2();
|
|
6097
6113
|
} catch (err) {
|
|
6098
|
-
console.
|
|
6099
|
-
`);
|
|
6114
|
+
console.error(`
|
|
6115
|
+
\u2717 ${err.message}`);
|
|
6116
|
+
process.exit(1);
|
|
6117
|
+
}
|
|
6118
|
+
console.log("Installing Synkro server container...");
|
|
6119
|
+
const workersPerPool = parseInt(process.env.SYNKRO_WORKERS_PER_POOL || "4", 10);
|
|
6120
|
+
const { image, hostMcpPort, hostGraderPort, hostCwePort } = await dockerInstall({ workersPerPool });
|
|
6121
|
+
console.log(` \u2713 pulled ${image}`);
|
|
6122
|
+
console.log(` container started \u2014 MCP=${hostMcpPort} general=${hostGraderPort} CWE=${hostCwePort}`);
|
|
6123
|
+
console.log(" waiting for container to be ready...");
|
|
6124
|
+
const ready = await waitForContainerReady(6e4);
|
|
6125
|
+
if (ready) {
|
|
6126
|
+
console.log(" \u2713 container ready");
|
|
6127
|
+
} else {
|
|
6128
|
+
console.error(" \u2717 container did not become healthy within 60s");
|
|
6129
|
+
console.error(" Run `docker logs synkro-server` to debug.");
|
|
6130
|
+
process.exit(1);
|
|
6100
6131
|
}
|
|
6132
|
+
console.log();
|
|
6101
6133
|
}
|
|
6102
6134
|
if (transcriptConsent) {
|
|
6103
6135
|
try {
|
|
@@ -6352,7 +6384,7 @@ import { createInterface } from 'node:readline';
|
|
|
6352
6384
|
|
|
6353
6385
|
const HOME = homedir();
|
|
6354
6386
|
const TOKEN_PATH = join(HOME, '.synkro', '.mcp-jwt');
|
|
6355
|
-
const PORT = parseInt(process.env.SYNKRO_MCP_PORT || '
|
|
6387
|
+
const PORT = parseInt(process.env.SYNKRO_MCP_PORT || '18931', 10);
|
|
6356
6388
|
const URL = \`http://127.0.0.1:\${PORT}\`;
|
|
6357
6389
|
|
|
6358
6390
|
let token = '';
|
|
@@ -6394,105 +6426,6 @@ rl.on('line', async (line) => {
|
|
|
6394
6426
|
}
|
|
6395
6427
|
});
|
|
6396
6428
|
|
|
6397
|
-
// cli/local-cc/pueue.ts
|
|
6398
|
-
import { execFileSync, spawnSync as spawnSync3, spawn } from "child_process";
|
|
6399
|
-
import { homedir as homedir9 } from "os";
|
|
6400
|
-
import { join as join9 } from "path";
|
|
6401
|
-
import { connect } from "net";
|
|
6402
|
-
function pueueAvailable() {
|
|
6403
|
-
const r = spawnSync3("pueue", ["--version"], { encoding: "utf-8" });
|
|
6404
|
-
if (r.status !== 0) {
|
|
6405
|
-
throw new PueueError("pueue CLI not found on PATH. Install pueue (https://github.com/Nukesor/pueue) and start `pueued`.");
|
|
6406
|
-
}
|
|
6407
|
-
}
|
|
6408
|
-
function statusJson() {
|
|
6409
|
-
pueueAvailable();
|
|
6410
|
-
const r = spawnSync3("pueue", ["status", "--json"], { encoding: "utf-8" });
|
|
6411
|
-
if (r.status !== 0) {
|
|
6412
|
-
throw new PueueError(`pueue status failed: ${r.stderr || r.stdout || "unknown error"} \u2014 is pueued running?`);
|
|
6413
|
-
}
|
|
6414
|
-
try {
|
|
6415
|
-
return JSON.parse(r.stdout);
|
|
6416
|
-
} catch (err) {
|
|
6417
|
-
throw new PueueError(`pueue status returned non-JSON output: ${r.stdout.slice(0, 200)}`, err);
|
|
6418
|
-
}
|
|
6419
|
-
}
|
|
6420
|
-
function statusName(s) {
|
|
6421
|
-
if (typeof s === "string") return s;
|
|
6422
|
-
if (s && typeof s === "object") {
|
|
6423
|
-
if ("Running" in s) return "Running";
|
|
6424
|
-
if ("Done" in s) {
|
|
6425
|
-
const result = s.Done?.result;
|
|
6426
|
-
if (typeof result === "string") return `Done (${result})`;
|
|
6427
|
-
if (result && typeof result === "object") return `Done (${Object.keys(result)[0] ?? "unknown"})`;
|
|
6428
|
-
return "Done";
|
|
6429
|
-
}
|
|
6430
|
-
return Object.keys(s)[0] ?? "unknown";
|
|
6431
|
-
}
|
|
6432
|
-
return "unknown";
|
|
6433
|
-
}
|
|
6434
|
-
function findTask(channel = CHANNEL_PRIMARY) {
|
|
6435
|
-
const data = statusJson();
|
|
6436
|
-
for (const [id, t] of Object.entries(data.tasks)) {
|
|
6437
|
-
if (t.label === channel.taskLabel) {
|
|
6438
|
-
return {
|
|
6439
|
-
id: Number(id),
|
|
6440
|
-
label: t.label,
|
|
6441
|
-
status: statusName(t.status),
|
|
6442
|
-
command: t.command,
|
|
6443
|
-
cwd: t.path
|
|
6444
|
-
};
|
|
6445
|
-
}
|
|
6446
|
-
}
|
|
6447
|
-
return null;
|
|
6448
|
-
}
|
|
6449
|
-
function stopTask(channel = CHANNEL_PRIMARY) {
|
|
6450
|
-
spawnSync3("tmux", ["kill-session", "-t", `=${channel.tmuxSession}`], { encoding: "utf-8" });
|
|
6451
|
-
let t = findTask(channel);
|
|
6452
|
-
while (t) {
|
|
6453
|
-
if (t.status === "Running" || t.status === "Queued") {
|
|
6454
|
-
spawnSync3("pueue", ["kill", String(t.id)], { encoding: "utf-8" });
|
|
6455
|
-
for (let i = 0; i < 10; i++) {
|
|
6456
|
-
const check = findTask(channel);
|
|
6457
|
-
if (!check || check.id !== t.id || check.status !== "Running" && check.status !== "Queued") break;
|
|
6458
|
-
spawnSync3("sleep", ["0.5"], { encoding: "utf-8" });
|
|
6459
|
-
}
|
|
6460
|
-
}
|
|
6461
|
-
spawnSync3("pueue", ["remove", String(t.id)], { encoding: "utf-8" });
|
|
6462
|
-
t = findTask(channel);
|
|
6463
|
-
}
|
|
6464
|
-
}
|
|
6465
|
-
var TASK_LABEL, TMUX_SESSION, SESSION_DIR, TASK_LABEL_2, TMUX_SESSION_2, SESSION_DIR_2, TASK_LABEL_3, TMUX_SESSION_3, SESSION_DIR_3, TASK_LABEL_4, TMUX_SESSION_4, SESSION_DIR_4, PueueError, CHANNEL_PRIMARY, CHANNEL_SECONDARY, CHANNEL_TERTIARY, CHANNEL_QUATERNARY;
|
|
6466
|
-
var init_pueue = __esm({
|
|
6467
|
-
"cli/local-cc/pueue.ts"() {
|
|
6468
|
-
"use strict";
|
|
6469
|
-
TASK_LABEL = "synkro-local-cc";
|
|
6470
|
-
TMUX_SESSION = "synkro-local-cc";
|
|
6471
|
-
SESSION_DIR = join9(homedir9(), ".synkro", "cc_sessions");
|
|
6472
|
-
TASK_LABEL_2 = "synkro-local-cc-2";
|
|
6473
|
-
TMUX_SESSION_2 = "synkro-local-cc-2";
|
|
6474
|
-
SESSION_DIR_2 = join9(homedir9(), ".synkro", "cc_sessions_2");
|
|
6475
|
-
TASK_LABEL_3 = "synkro-local-cc-3";
|
|
6476
|
-
TMUX_SESSION_3 = "synkro-local-cc-3";
|
|
6477
|
-
SESSION_DIR_3 = join9(homedir9(), ".synkro", "cc_sessions_3");
|
|
6478
|
-
TASK_LABEL_4 = "synkro-local-cc-4";
|
|
6479
|
-
TMUX_SESSION_4 = "synkro-local-cc-4";
|
|
6480
|
-
SESSION_DIR_4 = join9(homedir9(), ".synkro", "cc_sessions_4");
|
|
6481
|
-
PueueError = class extends Error {
|
|
6482
|
-
constructor(message, cause) {
|
|
6483
|
-
super(message);
|
|
6484
|
-
this.cause = cause;
|
|
6485
|
-
this.name = "PueueError";
|
|
6486
|
-
}
|
|
6487
|
-
cause;
|
|
6488
|
-
};
|
|
6489
|
-
CHANNEL_PRIMARY = { taskLabel: TASK_LABEL, tmuxSession: TMUX_SESSION, sessionDir: SESSION_DIR };
|
|
6490
|
-
CHANNEL_SECONDARY = { taskLabel: TASK_LABEL_2, tmuxSession: TMUX_SESSION_2, sessionDir: SESSION_DIR_2 };
|
|
6491
|
-
CHANNEL_TERTIARY = { taskLabel: TASK_LABEL_3, tmuxSession: TMUX_SESSION_3, sessionDir: SESSION_DIR_3 };
|
|
6492
|
-
CHANNEL_QUATERNARY = { taskLabel: TASK_LABEL_4, tmuxSession: TMUX_SESSION_4, sessionDir: SESSION_DIR_4 };
|
|
6493
|
-
}
|
|
6494
|
-
});
|
|
6495
|
-
|
|
6496
6429
|
// cli/local-cc/channelSource.ts
|
|
6497
6430
|
var init_channelSource = __esm({
|
|
6498
6431
|
"cli/local-cc/channelSource.ts"() {
|
|
@@ -6502,9 +6435,9 @@ var init_channelSource = __esm({
|
|
|
6502
6435
|
|
|
6503
6436
|
// cli/local-cc/install.ts
|
|
6504
6437
|
import { existsSync as existsSync10, mkdirSync as mkdirSync9, writeFileSync as writeFileSync8, readFileSync as readFileSync8, chmodSync as chmodSync3, copyFileSync, renameSync as renameSync4, unlinkSync as unlinkSync4, openSync, fsyncSync, closeSync } from "fs";
|
|
6505
|
-
import { join as
|
|
6506
|
-
import { homedir as
|
|
6507
|
-
import { spawnSync as
|
|
6438
|
+
import { join as join9 } from "path";
|
|
6439
|
+
import { homedir as homedir9 } from "os";
|
|
6440
|
+
import { spawnSync as spawnSync3 } from "child_process";
|
|
6508
6441
|
function safelyMutateClaudeJson(mutator) {
|
|
6509
6442
|
if (!existsSync10(CLAUDE_JSON_PATH)) {
|
|
6510
6443
|
return;
|
|
@@ -6580,47 +6513,47 @@ function uninstallLocalCC() {
|
|
|
6580
6513
|
return dirty;
|
|
6581
6514
|
});
|
|
6582
6515
|
}
|
|
6583
|
-
var CLAUDE_JSON_BACKUP_PATH,
|
|
6516
|
+
var CLAUDE_JSON_BACKUP_PATH, SESSION_DIR, PLUGIN_PATH, PLUGIN_PKG_PATH, PLUGIN_SETTINGS_DIR, PLUGIN_SETTINGS_PATH, PROJECT_MCP_PATH, CLAUDE_JSON_PATH, RUN_SCRIPT_PATH, TMUX_SESSION_NAME, CHANNEL_1_PORT, SESSION_DIR_2, PLUGIN_PATH_2, PLUGIN_PKG_PATH_2, PLUGIN_SETTINGS_DIR_2, PLUGIN_SETTINGS_PATH_2, PROJECT_MCP_PATH_2, RUN_SCRIPT_PATH_2, TMUX_SESSION_NAME_2, CHANNEL_2_PORT, SESSION_DIR_3, PLUGIN_PATH_3, PLUGIN_PKG_PATH_3, PLUGIN_SETTINGS_DIR_3, PLUGIN_SETTINGS_PATH_3, PROJECT_MCP_PATH_3, RUN_SCRIPT_PATH_3, TMUX_SESSION_NAME_3, CHANNEL_3_PORT, SESSION_DIR_4, PLUGIN_PATH_4, PLUGIN_PKG_PATH_4, PLUGIN_SETTINGS_DIR_4, PLUGIN_SETTINGS_PATH_4, PROJECT_MCP_PATH_4, RUN_SCRIPT_PATH_4, TMUX_SESSION_NAME_4, CHANNEL_4_PORT, RUN_SCRIPT_SOURCE, RUN_SCRIPT_SOURCE_2, RUN_SCRIPT_SOURCE_3, RUN_SCRIPT_SOURCE_4, MCP_SERVER_NAME, PLUGIN_PACKAGE_JSON, LocalCCInstallError, CHANNELS;
|
|
6584
6517
|
var init_install2 = __esm({
|
|
6585
6518
|
"cli/local-cc/install.ts"() {
|
|
6586
6519
|
"use strict";
|
|
6587
6520
|
init_channelSource();
|
|
6588
|
-
CLAUDE_JSON_BACKUP_PATH =
|
|
6589
|
-
|
|
6590
|
-
PLUGIN_PATH =
|
|
6591
|
-
PLUGIN_PKG_PATH =
|
|
6592
|
-
PLUGIN_SETTINGS_DIR =
|
|
6593
|
-
PLUGIN_SETTINGS_PATH =
|
|
6594
|
-
PROJECT_MCP_PATH =
|
|
6595
|
-
CLAUDE_JSON_PATH =
|
|
6596
|
-
RUN_SCRIPT_PATH =
|
|
6521
|
+
CLAUDE_JSON_BACKUP_PATH = join9(homedir9(), ".claude.json.synkro-bak");
|
|
6522
|
+
SESSION_DIR = join9(homedir9(), ".synkro", "cc_sessions");
|
|
6523
|
+
PLUGIN_PATH = join9(SESSION_DIR, "synkro-channel.ts");
|
|
6524
|
+
PLUGIN_PKG_PATH = join9(SESSION_DIR, "package.json");
|
|
6525
|
+
PLUGIN_SETTINGS_DIR = join9(SESSION_DIR, ".claude");
|
|
6526
|
+
PLUGIN_SETTINGS_PATH = join9(PLUGIN_SETTINGS_DIR, "settings.json");
|
|
6527
|
+
PROJECT_MCP_PATH = join9(SESSION_DIR, ".mcp.json");
|
|
6528
|
+
CLAUDE_JSON_PATH = join9(homedir9(), ".claude.json");
|
|
6529
|
+
RUN_SCRIPT_PATH = join9(SESSION_DIR, "run-claude.sh");
|
|
6597
6530
|
TMUX_SESSION_NAME = "synkro-local-cc";
|
|
6598
6531
|
CHANNEL_1_PORT = 8941;
|
|
6599
|
-
|
|
6600
|
-
PLUGIN_PATH_2 =
|
|
6601
|
-
PLUGIN_PKG_PATH_2 =
|
|
6602
|
-
PLUGIN_SETTINGS_DIR_2 =
|
|
6603
|
-
PLUGIN_SETTINGS_PATH_2 =
|
|
6604
|
-
PROJECT_MCP_PATH_2 =
|
|
6605
|
-
RUN_SCRIPT_PATH_2 =
|
|
6532
|
+
SESSION_DIR_2 = join9(homedir9(), ".synkro", "cc_sessions_2");
|
|
6533
|
+
PLUGIN_PATH_2 = join9(SESSION_DIR_2, "synkro-channel.ts");
|
|
6534
|
+
PLUGIN_PKG_PATH_2 = join9(SESSION_DIR_2, "package.json");
|
|
6535
|
+
PLUGIN_SETTINGS_DIR_2 = join9(SESSION_DIR_2, ".claude");
|
|
6536
|
+
PLUGIN_SETTINGS_PATH_2 = join9(PLUGIN_SETTINGS_DIR_2, "settings.json");
|
|
6537
|
+
PROJECT_MCP_PATH_2 = join9(SESSION_DIR_2, ".mcp.json");
|
|
6538
|
+
RUN_SCRIPT_PATH_2 = join9(SESSION_DIR_2, "run-claude.sh");
|
|
6606
6539
|
TMUX_SESSION_NAME_2 = "synkro-local-cc-2";
|
|
6607
6540
|
CHANNEL_2_PORT = 8951;
|
|
6608
|
-
|
|
6609
|
-
PLUGIN_PATH_3 =
|
|
6610
|
-
PLUGIN_PKG_PATH_3 =
|
|
6611
|
-
PLUGIN_SETTINGS_DIR_3 =
|
|
6612
|
-
PLUGIN_SETTINGS_PATH_3 =
|
|
6613
|
-
PROJECT_MCP_PATH_3 =
|
|
6614
|
-
RUN_SCRIPT_PATH_3 =
|
|
6541
|
+
SESSION_DIR_3 = join9(homedir9(), ".synkro", "cc_sessions_3");
|
|
6542
|
+
PLUGIN_PATH_3 = join9(SESSION_DIR_3, "synkro-channel.ts");
|
|
6543
|
+
PLUGIN_PKG_PATH_3 = join9(SESSION_DIR_3, "package.json");
|
|
6544
|
+
PLUGIN_SETTINGS_DIR_3 = join9(SESSION_DIR_3, ".claude");
|
|
6545
|
+
PLUGIN_SETTINGS_PATH_3 = join9(PLUGIN_SETTINGS_DIR_3, "settings.json");
|
|
6546
|
+
PROJECT_MCP_PATH_3 = join9(SESSION_DIR_3, ".mcp.json");
|
|
6547
|
+
RUN_SCRIPT_PATH_3 = join9(SESSION_DIR_3, "run-claude.sh");
|
|
6615
6548
|
TMUX_SESSION_NAME_3 = "synkro-local-cc-3";
|
|
6616
6549
|
CHANNEL_3_PORT = 8942;
|
|
6617
|
-
|
|
6618
|
-
PLUGIN_PATH_4 =
|
|
6619
|
-
PLUGIN_PKG_PATH_4 =
|
|
6620
|
-
PLUGIN_SETTINGS_DIR_4 =
|
|
6621
|
-
PLUGIN_SETTINGS_PATH_4 =
|
|
6622
|
-
PROJECT_MCP_PATH_4 =
|
|
6623
|
-
RUN_SCRIPT_PATH_4 =
|
|
6550
|
+
SESSION_DIR_4 = join9(homedir9(), ".synkro", "cc_sessions_4");
|
|
6551
|
+
PLUGIN_PATH_4 = join9(SESSION_DIR_4, "synkro-channel.ts");
|
|
6552
|
+
PLUGIN_PKG_PATH_4 = join9(SESSION_DIR_4, "package.json");
|
|
6553
|
+
PLUGIN_SETTINGS_DIR_4 = join9(SESSION_DIR_4, ".claude");
|
|
6554
|
+
PLUGIN_SETTINGS_PATH_4 = join9(PLUGIN_SETTINGS_DIR_4, "settings.json");
|
|
6555
|
+
PROJECT_MCP_PATH_4 = join9(SESSION_DIR_4, ".mcp.json");
|
|
6556
|
+
RUN_SCRIPT_PATH_4 = join9(SESSION_DIR_4, "run-claude.sh");
|
|
6624
6557
|
TMUX_SESSION_NAME_4 = "synkro-local-cc-4";
|
|
6625
6558
|
CHANNEL_4_PORT = 8952;
|
|
6626
6559
|
RUN_SCRIPT_SOURCE = `#!/usr/bin/env bash
|
|
@@ -6881,10 +6814,10 @@ log "tmux session ended."
|
|
|
6881
6814
|
cause;
|
|
6882
6815
|
};
|
|
6883
6816
|
CHANNELS = [
|
|
6884
|
-
{ sessionDir:
|
|
6885
|
-
{ sessionDir:
|
|
6886
|
-
{ sessionDir:
|
|
6887
|
-
{ sessionDir:
|
|
6817
|
+
{ sessionDir: SESSION_DIR, pluginPath: PLUGIN_PATH, pluginPkgPath: PLUGIN_PKG_PATH, pluginSettingsDir: PLUGIN_SETTINGS_DIR, pluginSettingsPath: PLUGIN_SETTINGS_PATH, projectMcpPath: PROJECT_MCP_PATH, runScriptPath: RUN_SCRIPT_PATH, runScriptSource: RUN_SCRIPT_SOURCE },
|
|
6818
|
+
{ sessionDir: SESSION_DIR_2, pluginPath: PLUGIN_PATH_2, pluginPkgPath: PLUGIN_PKG_PATH_2, pluginSettingsDir: PLUGIN_SETTINGS_DIR_2, pluginSettingsPath: PLUGIN_SETTINGS_PATH_2, projectMcpPath: PROJECT_MCP_PATH_2, runScriptPath: RUN_SCRIPT_PATH_2, runScriptSource: RUN_SCRIPT_SOURCE_2 },
|
|
6819
|
+
{ sessionDir: SESSION_DIR_3, pluginPath: PLUGIN_PATH_3, pluginPkgPath: PLUGIN_PKG_PATH_3, pluginSettingsDir: PLUGIN_SETTINGS_DIR_3, pluginSettingsPath: PLUGIN_SETTINGS_PATH_3, projectMcpPath: PROJECT_MCP_PATH_3, runScriptPath: RUN_SCRIPT_PATH_3, runScriptSource: RUN_SCRIPT_SOURCE_3 },
|
|
6820
|
+
{ sessionDir: SESSION_DIR_4, pluginPath: PLUGIN_PATH_4, pluginPkgPath: PLUGIN_PKG_PATH_4, pluginSettingsDir: PLUGIN_SETTINGS_DIR_4, pluginSettingsPath: PLUGIN_SETTINGS_PATH_4, projectMcpPath: PROJECT_MCP_PATH_4, runScriptPath: RUN_SCRIPT_PATH_4, runScriptSource: RUN_SCRIPT_SOURCE_4 }
|
|
6888
6821
|
];
|
|
6889
6822
|
}
|
|
6890
6823
|
});
|
|
@@ -6895,26 +6828,24 @@ __export(disconnect_exports, {
|
|
|
6895
6828
|
disconnectCommand: () => disconnectCommand
|
|
6896
6829
|
});
|
|
6897
6830
|
import { existsSync as existsSync11, rmSync } from "fs";
|
|
6898
|
-
import { homedir as
|
|
6899
|
-
import { join as
|
|
6900
|
-
|
|
6831
|
+
import { homedir as homedir10 } from "os";
|
|
6832
|
+
import { join as join10 } from "path";
|
|
6833
|
+
import { spawnSync as spawnSync4 } from "child_process";
|
|
6834
|
+
function tearDownLocalCC(purge) {
|
|
6901
6835
|
const docker = dockerStatus();
|
|
6902
6836
|
if (docker.running) {
|
|
6903
6837
|
dockerStop();
|
|
6904
|
-
console.log("\u2713
|
|
6905
|
-
}
|
|
6906
|
-
|
|
6907
|
-
try {
|
|
6908
|
-
const tasks = [findTask(), findTask(CHANNEL_SECONDARY), findTask(CHANNEL_TERTIARY), findTask(CHANNEL_QUATERNARY)];
|
|
6909
|
-
hadTask = tasks.some((t) => !!t);
|
|
6910
|
-
stopTask();
|
|
6911
|
-
stopTask(CHANNEL_SECONDARY);
|
|
6912
|
-
stopTask(CHANNEL_TERTIARY);
|
|
6913
|
-
stopTask(CHANNEL_QUATERNARY);
|
|
6914
|
-
} catch {
|
|
6838
|
+
console.log("\u2713 stopped synkro-server container");
|
|
6839
|
+
} else {
|
|
6840
|
+
console.log("\xB7 no synkro-server container running");
|
|
6915
6841
|
}
|
|
6916
|
-
if (
|
|
6917
|
-
|
|
6842
|
+
if (purge) {
|
|
6843
|
+
try {
|
|
6844
|
+
const image = imageTag();
|
|
6845
|
+
spawnSync4("docker", ["rmi", image], { encoding: "utf-8", timeout: 3e4 });
|
|
6846
|
+
console.log(`\u2713 removed Docker image ${image}`);
|
|
6847
|
+
} catch {
|
|
6848
|
+
}
|
|
6918
6849
|
}
|
|
6919
6850
|
if (needsKeychainBridge()) {
|
|
6920
6851
|
try {
|
|
@@ -6924,12 +6855,12 @@ function tearDownLocalCC() {
|
|
|
6924
6855
|
}
|
|
6925
6856
|
}
|
|
6926
6857
|
uninstallLocalCC();
|
|
6927
|
-
console.log("\u2713
|
|
6858
|
+
console.log("\u2713 cleaned ~/.claude.json entries");
|
|
6928
6859
|
}
|
|
6929
6860
|
function disconnectCommand(args2 = []) {
|
|
6930
6861
|
const purge = args2.includes("--purge");
|
|
6931
6862
|
console.log("Synkro disconnect starting...\n");
|
|
6932
|
-
tearDownLocalCC();
|
|
6863
|
+
tearDownLocalCC(purge);
|
|
6933
6864
|
const agents = detectAgents();
|
|
6934
6865
|
let sawClaudeCode = false;
|
|
6935
6866
|
for (const agent of agents) {
|
|
@@ -6970,18 +6901,17 @@ var init_disconnect = __esm({
|
|
|
6970
6901
|
init_ccHookConfig();
|
|
6971
6902
|
init_cursorHookConfig();
|
|
6972
6903
|
init_mcpConfig();
|
|
6973
|
-
init_pueue();
|
|
6974
6904
|
init_install2();
|
|
6975
6905
|
init_dockerInstall();
|
|
6976
6906
|
init_macKeychain();
|
|
6977
|
-
SYNKRO_DIR5 =
|
|
6907
|
+
SYNKRO_DIR5 = join10(homedir10(), ".synkro");
|
|
6978
6908
|
}
|
|
6979
6909
|
});
|
|
6980
6910
|
|
|
6981
6911
|
// cli/local-cc/turnLog.ts
|
|
6982
6912
|
import { appendFileSync, existsSync as existsSync12, mkdirSync as mkdirSync10, openSync as openSync2, readFileSync as readFileSync9, readSync, closeSync as closeSync2, statSync as statSync2, watchFile, unwatchFile } from "fs";
|
|
6983
|
-
import { dirname as dirname5, join as
|
|
6984
|
-
import { homedir as
|
|
6913
|
+
import { dirname as dirname5, join as join11 } from "path";
|
|
6914
|
+
import { homedir as homedir11 } from "os";
|
|
6985
6915
|
function truncate(s, max = PREVIEW_MAX) {
|
|
6986
6916
|
if (s.length <= max) return s;
|
|
6987
6917
|
return s.slice(0, max) + "\u2026 [+" + (s.length - max) + " chars]";
|
|
@@ -7020,14 +6950,14 @@ var TURN_LOG_PATH, PREVIEW_MAX;
|
|
|
7020
6950
|
var init_turnLog = __esm({
|
|
7021
6951
|
"cli/local-cc/turnLog.ts"() {
|
|
7022
6952
|
"use strict";
|
|
7023
|
-
TURN_LOG_PATH =
|
|
6953
|
+
TURN_LOG_PATH = join11(homedir11(), ".synkro", "cc_sessions", "turns.log");
|
|
7024
6954
|
PREVIEW_MAX = 400;
|
|
7025
6955
|
}
|
|
7026
6956
|
});
|
|
7027
6957
|
|
|
7028
6958
|
// cli/local-cc/client.ts
|
|
7029
6959
|
import { request as httpRequest } from "http";
|
|
7030
|
-
import { connect
|
|
6960
|
+
import { connect } from "net";
|
|
7031
6961
|
async function submitToChannel(role, payload, opts = {}) {
|
|
7032
6962
|
const body = JSON.stringify({ role, payload, content: payload });
|
|
7033
6963
|
const timeoutMs = opts.timeoutMs ?? DEFAULT_TIMEOUT_MS;
|
|
@@ -7177,7 +7107,7 @@ var args = process.argv.slice(2);
|
|
|
7177
7107
|
var cmd = args[0] || "";
|
|
7178
7108
|
var subArgs = args.slice(1);
|
|
7179
7109
|
function printVersion() {
|
|
7180
|
-
console.log("1.4.
|
|
7110
|
+
console.log("1.4.90");
|
|
7181
7111
|
}
|
|
7182
7112
|
function printHelp() {
|
|
7183
7113
|
console.log(`Synkro CLI \u2014 runtime safety for AI coding agents
|