@synkro-sh/cli 1.4.2 → 1.4.4
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 +184 -147
- package/dist/bootstrap.js.map +1 -1
- package/package.json +1 -1
package/dist/bootstrap.js
CHANGED
|
@@ -3370,6 +3370,28 @@ var init_promptFetcher = __esm({
|
|
|
3370
3370
|
}
|
|
3371
3371
|
});
|
|
3372
3372
|
|
|
3373
|
+
// cli/local-cc/settings.ts
|
|
3374
|
+
import { existsSync as existsSync8, readFileSync as readFileSync6 } from "fs";
|
|
3375
|
+
import { homedir as homedir6 } from "os";
|
|
3376
|
+
import { join as join7 } from "path";
|
|
3377
|
+
function isLocalCCEnabled() {
|
|
3378
|
+
if (!existsSync8(CONFIG_PATH2)) return false;
|
|
3379
|
+
try {
|
|
3380
|
+
const content = readFileSync6(CONFIG_PATH2, "utf-8");
|
|
3381
|
+
const match = content.match(/^SYNKRO_LOCAL_INFERENCE='([^']*)'/m);
|
|
3382
|
+
return match?.[1] === "yes";
|
|
3383
|
+
} catch {
|
|
3384
|
+
return false;
|
|
3385
|
+
}
|
|
3386
|
+
}
|
|
3387
|
+
var CONFIG_PATH2;
|
|
3388
|
+
var init_settings = __esm({
|
|
3389
|
+
"cli/local-cc/settings.ts"() {
|
|
3390
|
+
"use strict";
|
|
3391
|
+
CONFIG_PATH2 = join7(homedir6(), ".synkro", "config.env");
|
|
3392
|
+
}
|
|
3393
|
+
});
|
|
3394
|
+
|
|
3373
3395
|
// cli/local-cc/channelSource.ts
|
|
3374
3396
|
var CHANNEL_PLUGIN_SOURCE;
|
|
3375
3397
|
var init_channelSource = __esm({
|
|
@@ -3520,9 +3542,9 @@ await mcp.connect(new StdioServerTransport());
|
|
|
3520
3542
|
});
|
|
3521
3543
|
|
|
3522
3544
|
// cli/local-cc/install.ts
|
|
3523
|
-
import { existsSync as
|
|
3524
|
-
import { join as
|
|
3525
|
-
import { homedir as
|
|
3545
|
+
import { existsSync as existsSync9, mkdirSync as mkdirSync6, writeFileSync as writeFileSync6, readFileSync as readFileSync7, chmodSync, copyFileSync, renameSync as renameSync3, unlinkSync as unlinkSync4, openSync, fsyncSync, closeSync } from "fs";
|
|
3546
|
+
import { join as join8 } from "path";
|
|
3547
|
+
import { homedir as homedir7 } from "os";
|
|
3526
3548
|
import { spawnSync } from "child_process";
|
|
3527
3549
|
function writePluginFiles() {
|
|
3528
3550
|
mkdirSync6(SESSION_DIR, { recursive: true });
|
|
@@ -3558,10 +3580,10 @@ function runBunInstall() {
|
|
|
3558
3580
|
}
|
|
3559
3581
|
}
|
|
3560
3582
|
function safelyMutateClaudeJson(mutator) {
|
|
3561
|
-
if (!
|
|
3583
|
+
if (!existsSync9(CLAUDE_JSON_PATH)) {
|
|
3562
3584
|
return;
|
|
3563
3585
|
}
|
|
3564
|
-
const originalText =
|
|
3586
|
+
const originalText = readFileSync7(CLAUDE_JSON_PATH, "utf-8");
|
|
3565
3587
|
let parsed;
|
|
3566
3588
|
try {
|
|
3567
3589
|
parsed = JSON.parse(originalText);
|
|
@@ -3686,15 +3708,15 @@ var init_install = __esm({
|
|
|
3686
3708
|
"cli/local-cc/install.ts"() {
|
|
3687
3709
|
"use strict";
|
|
3688
3710
|
init_channelSource();
|
|
3689
|
-
CLAUDE_JSON_BACKUP_PATH =
|
|
3690
|
-
SESSION_DIR =
|
|
3691
|
-
PLUGIN_PATH =
|
|
3692
|
-
PLUGIN_PKG_PATH =
|
|
3693
|
-
PLUGIN_SETTINGS_DIR =
|
|
3694
|
-
PLUGIN_SETTINGS_PATH =
|
|
3695
|
-
PROJECT_MCP_PATH =
|
|
3696
|
-
CLAUDE_JSON_PATH =
|
|
3697
|
-
RUN_SCRIPT_PATH =
|
|
3711
|
+
CLAUDE_JSON_BACKUP_PATH = join8(homedir7(), ".claude.json.synkro-bak");
|
|
3712
|
+
SESSION_DIR = join8(homedir7(), ".synkro", "cc_sessions");
|
|
3713
|
+
PLUGIN_PATH = join8(SESSION_DIR, "synkro-channel.ts");
|
|
3714
|
+
PLUGIN_PKG_PATH = join8(SESSION_DIR, "package.json");
|
|
3715
|
+
PLUGIN_SETTINGS_DIR = join8(SESSION_DIR, ".claude");
|
|
3716
|
+
PLUGIN_SETTINGS_PATH = join8(PLUGIN_SETTINGS_DIR, "settings.json");
|
|
3717
|
+
PROJECT_MCP_PATH = join8(SESSION_DIR, ".mcp.json");
|
|
3718
|
+
CLAUDE_JSON_PATH = join8(homedir7(), ".claude.json");
|
|
3719
|
+
RUN_SCRIPT_PATH = join8(SESSION_DIR, "run-claude.sh");
|
|
3698
3720
|
TMUX_SESSION_NAME = "synkro-local-cc";
|
|
3699
3721
|
RUN_SCRIPT_SOURCE = `#!/usr/bin/env bash
|
|
3700
3722
|
# Auto-generated by \`synkro install\`. Do not edit.
|
|
@@ -3746,8 +3768,8 @@ done
|
|
|
3746
3768
|
|
|
3747
3769
|
// cli/local-cc/pueue.ts
|
|
3748
3770
|
import { execFileSync, spawnSync as spawnSync2 } from "child_process";
|
|
3749
|
-
import { homedir as
|
|
3750
|
-
import { join as
|
|
3771
|
+
import { homedir as homedir8 } from "os";
|
|
3772
|
+
import { join as join9 } from "path";
|
|
3751
3773
|
import { connect } from "net";
|
|
3752
3774
|
function pueueAvailable() {
|
|
3753
3775
|
const r = spawnSync2("pueue", ["--version"], { encoding: "utf-8" });
|
|
@@ -3802,7 +3824,7 @@ function startTask(opts = {}) {
|
|
|
3802
3824
|
if (existing) {
|
|
3803
3825
|
spawnSync2("pueue", ["remove", String(existing.id)], { encoding: "utf-8" });
|
|
3804
3826
|
}
|
|
3805
|
-
const runScript =
|
|
3827
|
+
const runScript = join9(cwd, "run-claude.sh");
|
|
3806
3828
|
const args2 = [
|
|
3807
3829
|
"add",
|
|
3808
3830
|
"--label",
|
|
@@ -3894,7 +3916,7 @@ var init_pueue = __esm({
|
|
|
3894
3916
|
"use strict";
|
|
3895
3917
|
TASK_LABEL = "synkro-local-cc";
|
|
3896
3918
|
TMUX_SESSION = "synkro-local-cc";
|
|
3897
|
-
SESSION_DIR2 =
|
|
3919
|
+
SESSION_DIR2 = join9(homedir8(), ".synkro", "cc_sessions");
|
|
3898
3920
|
PueueError = class extends Error {
|
|
3899
3921
|
constructor(message, cause) {
|
|
3900
3922
|
super(message);
|
|
@@ -3907,16 +3929,16 @@ var init_pueue = __esm({
|
|
|
3907
3929
|
});
|
|
3908
3930
|
|
|
3909
3931
|
// cli/local-cc/prompts.ts
|
|
3910
|
-
import { existsSync as
|
|
3911
|
-
import { homedir as
|
|
3912
|
-
import { join as
|
|
3932
|
+
import { existsSync as existsSync10, readFileSync as readFileSync8 } from "fs";
|
|
3933
|
+
import { homedir as homedir9 } from "os";
|
|
3934
|
+
import { join as join10 } from "path";
|
|
3913
3935
|
function loadCachedPrompts() {
|
|
3914
3936
|
if (_cached) return _cached;
|
|
3915
|
-
if (!
|
|
3937
|
+
if (!existsSync10(CACHE_PATH2)) {
|
|
3916
3938
|
throw new Error("Prompts cache not found. Run `synkro install` or `synkro update` first.");
|
|
3917
3939
|
}
|
|
3918
3940
|
try {
|
|
3919
|
-
_cached = JSON.parse(
|
|
3941
|
+
_cached = JSON.parse(readFileSync8(CACHE_PATH2, "utf-8"));
|
|
3920
3942
|
return _cached;
|
|
3921
3943
|
} catch {
|
|
3922
3944
|
throw new Error("Prompts cache is corrupted. Run `synkro update` to refresh.");
|
|
@@ -3942,15 +3964,15 @@ var CACHE_PATH2, _cached;
|
|
|
3942
3964
|
var init_prompts = __esm({
|
|
3943
3965
|
"cli/local-cc/prompts.ts"() {
|
|
3944
3966
|
"use strict";
|
|
3945
|
-
CACHE_PATH2 =
|
|
3967
|
+
CACHE_PATH2 = join10(homedir9(), ".synkro", "prompts", "judge-prompts.json");
|
|
3946
3968
|
_cached = null;
|
|
3947
3969
|
}
|
|
3948
3970
|
});
|
|
3949
3971
|
|
|
3950
3972
|
// cli/local-cc/turnLog.ts
|
|
3951
|
-
import { appendFileSync, existsSync as
|
|
3952
|
-
import { dirname as dirname4, join as
|
|
3953
|
-
import { homedir as
|
|
3973
|
+
import { appendFileSync, existsSync as existsSync11, mkdirSync as mkdirSync7, openSync as openSync2, readFileSync as readFileSync9, readSync, closeSync as closeSync2, statSync, watchFile, unwatchFile } from "fs";
|
|
3974
|
+
import { dirname as dirname4, join as join11 } from "path";
|
|
3975
|
+
import { homedir as homedir10 } from "os";
|
|
3954
3976
|
function truncate(s, max = PREVIEW_MAX) {
|
|
3955
3977
|
if (s.length <= max) return s;
|
|
3956
3978
|
return s.slice(0, max) + "\u2026 [+" + (s.length - max) + " chars]";
|
|
@@ -3986,11 +4008,11 @@ function appendTurn(args2) {
|
|
|
3986
4008
|
}
|
|
3987
4009
|
}
|
|
3988
4010
|
function readRecentTurns(n = 20) {
|
|
3989
|
-
if (!
|
|
4011
|
+
if (!existsSync11(TURN_LOG_PATH)) return [];
|
|
3990
4012
|
try {
|
|
3991
4013
|
const size = statSync(TURN_LOG_PATH).size;
|
|
3992
4014
|
if (size === 0) return [];
|
|
3993
|
-
const text =
|
|
4015
|
+
const text = readFileSync9(TURN_LOG_PATH, "utf-8");
|
|
3994
4016
|
const lines = text.split("\n").filter(Boolean);
|
|
3995
4017
|
const lastN = lines.slice(-n).reverse();
|
|
3996
4018
|
return lastN.map((line) => {
|
|
@@ -4007,7 +4029,7 @@ function readRecentTurns(n = 20) {
|
|
|
4007
4029
|
function followTurns(onEntry) {
|
|
4008
4030
|
try {
|
|
4009
4031
|
mkdirSync7(dirname4(TURN_LOG_PATH), { recursive: true });
|
|
4010
|
-
if (!
|
|
4032
|
+
if (!existsSync11(TURN_LOG_PATH)) {
|
|
4011
4033
|
appendFileSync(TURN_LOG_PATH, "", "utf-8");
|
|
4012
4034
|
}
|
|
4013
4035
|
} catch {
|
|
@@ -4069,7 +4091,7 @@ var TURN_LOG_PATH, PREVIEW_MAX;
|
|
|
4069
4091
|
var init_turnLog = __esm({
|
|
4070
4092
|
"cli/local-cc/turnLog.ts"() {
|
|
4071
4093
|
"use strict";
|
|
4072
|
-
TURN_LOG_PATH =
|
|
4094
|
+
TURN_LOG_PATH = join11(homedir10(), ".synkro", "cc_sessions", "turns.log");
|
|
4073
4095
|
PREVIEW_MAX = 400;
|
|
4074
4096
|
}
|
|
4075
4097
|
});
|
|
@@ -4175,9 +4197,9 @@ __export(install_exports, {
|
|
|
4175
4197
|
installCommand: () => installCommand,
|
|
4176
4198
|
parseArgs: () => parseArgs
|
|
4177
4199
|
});
|
|
4178
|
-
import { existsSync as
|
|
4179
|
-
import { homedir as
|
|
4180
|
-
import { join as
|
|
4200
|
+
import { existsSync as existsSync12, mkdirSync as mkdirSync8, writeFileSync as writeFileSync7, chmodSync as chmodSync2, readFileSync as readFileSync10, readdirSync } from "fs";
|
|
4201
|
+
import { homedir as homedir11 } from "os";
|
|
4202
|
+
import { join as join12 } from "path";
|
|
4181
4203
|
import { execSync as execSync5 } from "child_process";
|
|
4182
4204
|
import { createInterface as createInterface3 } from "readline";
|
|
4183
4205
|
function sanitizeGatewayCandidate(raw) {
|
|
@@ -4220,13 +4242,13 @@ function ensureSynkroDir() {
|
|
|
4220
4242
|
mkdirSync8(OFFSETS_DIR, { recursive: true });
|
|
4221
4243
|
}
|
|
4222
4244
|
function writeHookScripts() {
|
|
4223
|
-
const bashScriptPath =
|
|
4224
|
-
const bashFollowupScriptPath =
|
|
4225
|
-
const editCaptureScriptPath =
|
|
4226
|
-
const editPrecheckScriptPath =
|
|
4227
|
-
const stopSummaryScriptPath =
|
|
4228
|
-
const sessionStartScriptPath =
|
|
4229
|
-
const transcriptSyncScriptPath =
|
|
4245
|
+
const bashScriptPath = join12(HOOKS_DIR, "cc-bash-judge.sh");
|
|
4246
|
+
const bashFollowupScriptPath = join12(HOOKS_DIR, "cc-bash-followup.sh");
|
|
4247
|
+
const editCaptureScriptPath = join12(HOOKS_DIR, "cc-edit-capture.sh");
|
|
4248
|
+
const editPrecheckScriptPath = join12(HOOKS_DIR, "cc-edit-precheck.sh");
|
|
4249
|
+
const stopSummaryScriptPath = join12(HOOKS_DIR, "cc-stop-summary.sh");
|
|
4250
|
+
const sessionStartScriptPath = join12(HOOKS_DIR, "cc-session-start.sh");
|
|
4251
|
+
const transcriptSyncScriptPath = join12(HOOKS_DIR, "cc-transcript-sync.sh");
|
|
4230
4252
|
writeFileSync7(bashScriptPath, CC_BASH_JUDGE_SCRIPT, "utf-8");
|
|
4231
4253
|
writeFileSync7(bashFollowupScriptPath, CC_BASH_FOLLOWUP_SCRIPT, "utf-8");
|
|
4232
4254
|
writeFileSync7(editCaptureScriptPath, CC_EDIT_CAPTURE_SCRIPT, "utf-8");
|
|
@@ -4260,11 +4282,11 @@ function shellQuoteSingle(value) {
|
|
|
4260
4282
|
}
|
|
4261
4283
|
function resolveSynkroBundle() {
|
|
4262
4284
|
const scriptPath = process.argv[1];
|
|
4263
|
-
if (scriptPath &&
|
|
4285
|
+
if (scriptPath && existsSync12(scriptPath)) return scriptPath;
|
|
4264
4286
|
return null;
|
|
4265
4287
|
}
|
|
4266
4288
|
function writeConfigEnv(opts) {
|
|
4267
|
-
const credsPath =
|
|
4289
|
+
const credsPath = join12(SYNKRO_DIR2, "credentials.json");
|
|
4268
4290
|
const safeGateway = sanitizeConfigValue(opts.gatewayUrl);
|
|
4269
4291
|
const safeUserId = sanitizeConfigValue(opts.userId);
|
|
4270
4292
|
const safeOrgId = sanitizeConfigValue(opts.orgId);
|
|
@@ -4280,7 +4302,7 @@ function writeConfigEnv(opts) {
|
|
|
4280
4302
|
`SYNKRO_CREDENTIALS_PATH=${shellQuoteSingle(credsPath)}`,
|
|
4281
4303
|
`SYNKRO_TIER=${shellQuoteSingle(safeTier)}`,
|
|
4282
4304
|
`SYNKRO_INFERENCE=${shellQuoteSingle(safeInference)}`,
|
|
4283
|
-
`SYNKRO_VERSION=${shellQuoteSingle("1.4.
|
|
4305
|
+
`SYNKRO_VERSION=${shellQuoteSingle("1.4.4")}`
|
|
4284
4306
|
];
|
|
4285
4307
|
if (safeSynkroBin) lines.push(`SYNKRO_CLI_BIN=${shellQuoteSingle(safeSynkroBin)}`);
|
|
4286
4308
|
if (safeUserId) lines.push(`SYNKRO_USER_ID=${shellQuoteSingle(safeUserId)}`);
|
|
@@ -4291,8 +4313,21 @@ function writeConfigEnv(opts) {
|
|
|
4291
4313
|
}
|
|
4292
4314
|
lines.push(`SYNKRO_LOCAL_INFERENCE=${shellQuoteSingle(opts.localInference ? "yes" : "no")}`);
|
|
4293
4315
|
lines.push("");
|
|
4294
|
-
writeFileSync7(
|
|
4295
|
-
chmodSync2(
|
|
4316
|
+
writeFileSync7(CONFIG_PATH3, lines.join("\n"), "utf-8");
|
|
4317
|
+
chmodSync2(CONFIG_PATH3, 384);
|
|
4318
|
+
}
|
|
4319
|
+
function updateLocalInferenceFlag(enabled) {
|
|
4320
|
+
if (!existsSync12(CONFIG_PATH3)) return;
|
|
4321
|
+
let content = readFileSync10(CONFIG_PATH3, "utf-8");
|
|
4322
|
+
const flag = enabled ? "yes" : "no";
|
|
4323
|
+
if (content.includes("SYNKRO_LOCAL_INFERENCE=")) {
|
|
4324
|
+
content = content.replace(/^SYNKRO_LOCAL_INFERENCE='[^']*'/m, `SYNKRO_LOCAL_INFERENCE='${flag}'`);
|
|
4325
|
+
} else {
|
|
4326
|
+
content = content.trimEnd() + `
|
|
4327
|
+
SYNKRO_LOCAL_INFERENCE='${flag}'
|
|
4328
|
+
`;
|
|
4329
|
+
}
|
|
4330
|
+
writeFileSync7(CONFIG_PATH3, content, "utf-8");
|
|
4296
4331
|
}
|
|
4297
4332
|
function collectLocalMetadata() {
|
|
4298
4333
|
const meta = { platform: process.platform };
|
|
@@ -4312,16 +4347,16 @@ function collectLocalMetadata() {
|
|
|
4312
4347
|
meta.cc_version = execSync5("claude --version", { encoding: "utf-8", timeout: 5e3 }).trim().split("\n")[0];
|
|
4313
4348
|
} catch {
|
|
4314
4349
|
}
|
|
4315
|
-
const claudeDir =
|
|
4350
|
+
const claudeDir = join12(homedir11(), ".claude");
|
|
4316
4351
|
try {
|
|
4317
|
-
const settings = JSON.parse(
|
|
4352
|
+
const settings = JSON.parse(readFileSync10(join12(claudeDir, "settings.json"), "utf-8"));
|
|
4318
4353
|
const plugins = Object.keys(settings.enabledPlugins ?? {}).filter((k) => settings.enabledPlugins[k]);
|
|
4319
4354
|
if (plugins.length) meta.enabled_plugins = plugins;
|
|
4320
4355
|
if (settings.permissions?.defaultMode) meta.permissions_mode = settings.permissions.defaultMode;
|
|
4321
4356
|
} catch {
|
|
4322
4357
|
}
|
|
4323
4358
|
try {
|
|
4324
|
-
const mcpCache = JSON.parse(
|
|
4359
|
+
const mcpCache = JSON.parse(readFileSync10(join12(claudeDir, "mcp-needs-auth-cache.json"), "utf-8"));
|
|
4325
4360
|
const mcpNames = Object.keys(mcpCache);
|
|
4326
4361
|
if (mcpNames.length) meta.mcp_servers = mcpNames;
|
|
4327
4362
|
} catch {
|
|
@@ -4333,10 +4368,10 @@ function collectLocalMetadata() {
|
|
|
4333
4368
|
} catch {
|
|
4334
4369
|
}
|
|
4335
4370
|
try {
|
|
4336
|
-
const sessionsDir =
|
|
4371
|
+
const sessionsDir = join12(claudeDir, "sessions");
|
|
4337
4372
|
const files = readdirSync(sessionsDir).filter((f) => f.endsWith(".json")).slice(-5);
|
|
4338
4373
|
for (const f of files) {
|
|
4339
|
-
const s = JSON.parse(
|
|
4374
|
+
const s = JSON.parse(readFileSync10(join12(sessionsDir, f), "utf-8"));
|
|
4340
4375
|
if (s.version) {
|
|
4341
4376
|
meta.cc_version = meta.cc_version || s.version;
|
|
4342
4377
|
break;
|
|
@@ -4392,19 +4427,19 @@ function assertGatewayAllowed(gatewayUrl) {
|
|
|
4392
4427
|
}
|
|
4393
4428
|
function isAlreadyInstalled() {
|
|
4394
4429
|
const requiredScripts = [
|
|
4395
|
-
|
|
4396
|
-
|
|
4397
|
-
|
|
4398
|
-
|
|
4399
|
-
|
|
4400
|
-
|
|
4430
|
+
join12(HOOKS_DIR, "cc-bash-judge.sh"),
|
|
4431
|
+
join12(HOOKS_DIR, "cc-bash-followup.sh"),
|
|
4432
|
+
join12(HOOKS_DIR, "cc-edit-precheck.sh"),
|
|
4433
|
+
join12(HOOKS_DIR, "cc-edit-capture.sh"),
|
|
4434
|
+
join12(HOOKS_DIR, "cc-stop-summary.sh"),
|
|
4435
|
+
join12(HOOKS_DIR, "cc-session-start.sh")
|
|
4401
4436
|
];
|
|
4402
|
-
if (!requiredScripts.every((p) =>
|
|
4403
|
-
if (!
|
|
4404
|
-
const settingsPath =
|
|
4405
|
-
if (!
|
|
4437
|
+
if (!requiredScripts.every((p) => existsSync12(p))) return false;
|
|
4438
|
+
if (!existsSync12(CONFIG_PATH3)) return false;
|
|
4439
|
+
const settingsPath = join12(homedir11(), ".claude", "settings.json");
|
|
4440
|
+
if (!existsSync12(settingsPath)) return false;
|
|
4406
4441
|
try {
|
|
4407
|
-
const settings = JSON.parse(
|
|
4442
|
+
const settings = JSON.parse(readFileSync10(settingsPath, "utf-8"));
|
|
4408
4443
|
const hooks = settings?.hooks;
|
|
4409
4444
|
if (!hooks || typeof hooks !== "object") return false;
|
|
4410
4445
|
const hasManaged = (kind) => Array.isArray(hooks[kind]) && hooks[kind].some((entry) => entry?.__synkro_managed__ === true);
|
|
@@ -4444,6 +4479,29 @@ async function installCommand(opts = {}) {
|
|
|
4444
4479
|
} catch {
|
|
4445
4480
|
}
|
|
4446
4481
|
}
|
|
4482
|
+
const token2 = getAccessToken();
|
|
4483
|
+
if (token2) {
|
|
4484
|
+
const profile2 = await fetchUserProfile(gatewayUrl, token2);
|
|
4485
|
+
if (profile2.localInference && !isLocalCCEnabled()) {
|
|
4486
|
+
console.log("Local inference enabled in your profile \u2014 setting up local-CC channel...");
|
|
4487
|
+
try {
|
|
4488
|
+
assertClaudeInstalled();
|
|
4489
|
+
assertPueueInstalled();
|
|
4490
|
+
assertTmuxInstalled();
|
|
4491
|
+
installLocalCC();
|
|
4492
|
+
const t = ensureRunning();
|
|
4493
|
+
console.log(` pueue task: id=${t.id} status=${t.status}`);
|
|
4494
|
+
console.log(" Waiting for channel...");
|
|
4495
|
+
const ready = await waitForChannelReady(CHANNEL_PORT, 6e4, CHANNEL_HOST);
|
|
4496
|
+
if (ready) console.log(` channel ready at ${CHANNEL_HOST}:${CHANNEL_PORT}`);
|
|
4497
|
+
else console.warn(" \u26A0 channel did not come up within 60s \u2014 check `synkro local-cc logs`");
|
|
4498
|
+
updateLocalInferenceFlag(true);
|
|
4499
|
+
} catch (err) {
|
|
4500
|
+
console.warn(` \u26A0 Local-CC setup skipped: ${err.message}`);
|
|
4501
|
+
console.warn(" Install pueue, tmux, and claude, then re-run install.");
|
|
4502
|
+
}
|
|
4503
|
+
}
|
|
4504
|
+
}
|
|
4447
4505
|
console.log("\u2713 Synkro is already installed and configured.");
|
|
4448
4506
|
console.log(" Run `synkro-cli update` to refresh hook scripts and judge prompts.");
|
|
4449
4507
|
console.log(" Run `synkro-cli install --force` to reinstall from scratch.");
|
|
@@ -4512,9 +4570,9 @@ async function installCommand(opts = {}) {
|
|
|
4512
4570
|
console.log(` ${scripts.transcriptSyncScript}
|
|
4513
4571
|
`);
|
|
4514
4572
|
for (const mode of ["edit", "bash"]) {
|
|
4515
|
-
const pidFile =
|
|
4573
|
+
const pidFile = join12(SYNKRO_DIR2, "daemon", mode, "daemon.pid");
|
|
4516
4574
|
try {
|
|
4517
|
-
const pid = parseInt(
|
|
4575
|
+
const pid = parseInt(readFileSync10(pidFile, "utf-8").trim(), 10);
|
|
4518
4576
|
if (pid > 0) {
|
|
4519
4577
|
process.kill(pid, "SIGTERM");
|
|
4520
4578
|
console.log(`Stopped stale ${mode} grader daemon (pid ${pid})`);
|
|
@@ -4589,7 +4647,7 @@ async function installCommand(opts = {}) {
|
|
|
4589
4647
|
const profile = await fetchUserProfile(gatewayUrl, token);
|
|
4590
4648
|
const synkroBundle = resolveSynkroBundle();
|
|
4591
4649
|
writeConfigEnv({ gatewayUrl, userId, orgId, email, tier: profile.tier, inference: profile.inference, synkroBin: synkroBundle, transcriptConsent, localInference: profile.localInference });
|
|
4592
|
-
console.log(`Wrote config to ${
|
|
4650
|
+
console.log(`Wrote config to ${CONFIG_PATH3}`);
|
|
4593
4651
|
console.log(` inference: ${profile.inference} (server-side grading)`);
|
|
4594
4652
|
if (profile.localInference) console.log(` local inference: enabled (gradingProvider=claude-code)`);
|
|
4595
4653
|
if (synkroBundle) console.log(` SYNKRO_CLI_BIN=${synkroBundle}`);
|
|
@@ -4667,17 +4725,17 @@ function detectGitRepo2() {
|
|
|
4667
4725
|
function getClaudeProjectsFolder() {
|
|
4668
4726
|
const cwd = process.cwd();
|
|
4669
4727
|
const sanitized = "-" + cwd.replace(/\//g, "-");
|
|
4670
|
-
const projectsDir =
|
|
4671
|
-
return
|
|
4728
|
+
const projectsDir = join12(homedir11(), ".claude", "projects", sanitized);
|
|
4729
|
+
return existsSync12(projectsDir) ? projectsDir : null;
|
|
4672
4730
|
}
|
|
4673
4731
|
function extractSessionInsights(projectsDir) {
|
|
4674
4732
|
const insights = [];
|
|
4675
4733
|
const files = readdirSync(projectsDir).filter((f) => f.endsWith(".jsonl"));
|
|
4676
4734
|
for (const file of files) {
|
|
4677
4735
|
const sessionId = file.replace(".jsonl", "");
|
|
4678
|
-
const filePath =
|
|
4736
|
+
const filePath = join12(projectsDir, file);
|
|
4679
4737
|
try {
|
|
4680
|
-
const content =
|
|
4738
|
+
const content = readFileSync10(filePath, "utf-8");
|
|
4681
4739
|
const lines = content.split("\n").filter(Boolean);
|
|
4682
4740
|
for (let i = 0; i < lines.length; i++) {
|
|
4683
4741
|
try {
|
|
@@ -4753,7 +4811,7 @@ function extractTextContent(content) {
|
|
|
4753
4811
|
return "";
|
|
4754
4812
|
}
|
|
4755
4813
|
function parseTranscriptFile(filePath) {
|
|
4756
|
-
const content =
|
|
4814
|
+
const content = readFileSync10(filePath, "utf-8");
|
|
4757
4815
|
const lines = content.split("\n").filter(Boolean);
|
|
4758
4816
|
const messages = [];
|
|
4759
4817
|
for (let i = 0; i < lines.length; i++) {
|
|
@@ -4804,7 +4862,7 @@ async function syncTranscriptsBulk(gatewayUrl, token, repo) {
|
|
|
4804
4862
|
const sessions = [];
|
|
4805
4863
|
for (const file of batch) {
|
|
4806
4864
|
const sessionId = file.replace(".jsonl", "");
|
|
4807
|
-
const filePath =
|
|
4865
|
+
const filePath = join12(projectsDir, file);
|
|
4808
4866
|
try {
|
|
4809
4867
|
const allMessages = parseTranscriptFile(filePath);
|
|
4810
4868
|
const messages = allMessages.length > maxMessagesPerSession ? allMessages.slice(-maxMessagesPerSession) : allMessages;
|
|
@@ -4833,18 +4891,18 @@ async function syncTranscriptsBulk(gatewayUrl, token, repo) {
|
|
|
4833
4891
|
}
|
|
4834
4892
|
for (const file of batch) {
|
|
4835
4893
|
const sessionId = file.replace(".jsonl", "");
|
|
4836
|
-
const filePath =
|
|
4894
|
+
const filePath = join12(projectsDir, file);
|
|
4837
4895
|
try {
|
|
4838
|
-
const content =
|
|
4896
|
+
const content = readFileSync10(filePath, "utf-8");
|
|
4839
4897
|
const lineCount = content.split("\n").filter(Boolean).length;
|
|
4840
|
-
writeFileSync7(
|
|
4898
|
+
writeFileSync7(join12(OFFSETS_DIR, sessionId), String(lineCount), "utf-8");
|
|
4841
4899
|
} catch {
|
|
4842
4900
|
}
|
|
4843
4901
|
}
|
|
4844
4902
|
}
|
|
4845
4903
|
return { sessions: totalSessions, messages: totalMessages };
|
|
4846
4904
|
}
|
|
4847
|
-
var SYNKRO_DIR2, HOOKS_DIR, BIN_DIR,
|
|
4905
|
+
var SYNKRO_DIR2, HOOKS_DIR, BIN_DIR, CONFIG_PATH3, OFFSETS_DIR;
|
|
4848
4906
|
var init_install2 = __esm({
|
|
4849
4907
|
"cli/commands/install.ts"() {
|
|
4850
4908
|
"use strict";
|
|
@@ -4857,14 +4915,15 @@ var init_install2 = __esm({
|
|
|
4857
4915
|
init_projects();
|
|
4858
4916
|
init_setupGithub();
|
|
4859
4917
|
init_promptFetcher();
|
|
4918
|
+
init_settings();
|
|
4860
4919
|
init_install();
|
|
4861
4920
|
init_pueue();
|
|
4862
4921
|
init_client();
|
|
4863
|
-
SYNKRO_DIR2 =
|
|
4864
|
-
HOOKS_DIR =
|
|
4865
|
-
BIN_DIR =
|
|
4866
|
-
|
|
4867
|
-
OFFSETS_DIR =
|
|
4922
|
+
SYNKRO_DIR2 = join12(homedir11(), ".synkro");
|
|
4923
|
+
HOOKS_DIR = join12(SYNKRO_DIR2, "hooks");
|
|
4924
|
+
BIN_DIR = join12(SYNKRO_DIR2, "bin");
|
|
4925
|
+
CONFIG_PATH3 = join12(SYNKRO_DIR2, "config.env");
|
|
4926
|
+
OFFSETS_DIR = join12(SYNKRO_DIR2, ".transcript-offsets");
|
|
4868
4927
|
}
|
|
4869
4928
|
});
|
|
4870
4929
|
|
|
@@ -4940,13 +4999,13 @@ var status_exports = {};
|
|
|
4940
4999
|
__export(status_exports, {
|
|
4941
5000
|
statusCommand: () => statusCommand
|
|
4942
5001
|
});
|
|
4943
|
-
import { existsSync as
|
|
4944
|
-
import { homedir as
|
|
4945
|
-
import { join as
|
|
5002
|
+
import { existsSync as existsSync13, readFileSync as readFileSync11 } from "fs";
|
|
5003
|
+
import { homedir as homedir12 } from "os";
|
|
5004
|
+
import { join as join13 } from "path";
|
|
4946
5005
|
function readConfigEnv() {
|
|
4947
|
-
if (!
|
|
5006
|
+
if (!existsSync13(CONFIG_PATH4)) return {};
|
|
4948
5007
|
const out = {};
|
|
4949
|
-
const raw =
|
|
5008
|
+
const raw = readFileSync11(CONFIG_PATH4, "utf-8");
|
|
4950
5009
|
for (const line of raw.split("\n")) {
|
|
4951
5010
|
const trimmed = line.trim();
|
|
4952
5011
|
if (!trimmed || trimmed.startsWith("#")) continue;
|
|
@@ -5019,19 +5078,19 @@ async function statusCommand() {
|
|
|
5019
5078
|
}
|
|
5020
5079
|
}
|
|
5021
5080
|
console.log();
|
|
5022
|
-
const bashScript =
|
|
5023
|
-
const bashFollowupScript =
|
|
5024
|
-
const editPrecheckScript =
|
|
5025
|
-
const editCaptureScript =
|
|
5026
|
-
const stopSummaryScript =
|
|
5027
|
-
const sessionStartScript =
|
|
5081
|
+
const bashScript = join13(SYNKRO_DIR3, "hooks", "cc-bash-judge.sh");
|
|
5082
|
+
const bashFollowupScript = join13(SYNKRO_DIR3, "hooks", "cc-bash-followup.sh");
|
|
5083
|
+
const editPrecheckScript = join13(SYNKRO_DIR3, "hooks", "cc-edit-precheck.sh");
|
|
5084
|
+
const editCaptureScript = join13(SYNKRO_DIR3, "hooks", "cc-edit-capture.sh");
|
|
5085
|
+
const stopSummaryScript = join13(SYNKRO_DIR3, "hooks", "cc-stop-summary.sh");
|
|
5086
|
+
const sessionStartScript = join13(SYNKRO_DIR3, "hooks", "cc-session-start.sh");
|
|
5028
5087
|
console.log("Hook scripts:");
|
|
5029
|
-
console.log(` ${
|
|
5030
|
-
console.log(` ${
|
|
5031
|
-
console.log(` ${
|
|
5032
|
-
console.log(` ${
|
|
5033
|
-
console.log(` ${
|
|
5034
|
-
console.log(` ${
|
|
5088
|
+
console.log(` ${existsSync13(bashScript) ? "\u2713" : "\u2717"} ${bashScript}`);
|
|
5089
|
+
console.log(` ${existsSync13(bashFollowupScript) ? "\u2713" : "\u2717"} ${bashFollowupScript}`);
|
|
5090
|
+
console.log(` ${existsSync13(editPrecheckScript) ? "\u2713" : "\u2717"} ${editPrecheckScript}`);
|
|
5091
|
+
console.log(` ${existsSync13(editCaptureScript) ? "\u2713" : "\u2717"} ${editCaptureScript}`);
|
|
5092
|
+
console.log(` ${existsSync13(stopSummaryScript) ? "\u2713" : "\u2717"} ${stopSummaryScript}`);
|
|
5093
|
+
console.log(` ${existsSync13(sessionStartScript) ? "\u2713" : "\u2717"} ${sessionStartScript}`);
|
|
5035
5094
|
console.log();
|
|
5036
5095
|
const mcp = inspectMcpConfig();
|
|
5037
5096
|
console.log("Guardrails MCP server (Claude Code):");
|
|
@@ -5043,7 +5102,7 @@ async function statusCommand() {
|
|
|
5043
5102
|
console.log(` expected at ${mcp.configPath} \u2192 mcpServers.synkro-guardrails`);
|
|
5044
5103
|
}
|
|
5045
5104
|
}
|
|
5046
|
-
var SYNKRO_DIR3,
|
|
5105
|
+
var SYNKRO_DIR3, CONFIG_PATH4;
|
|
5047
5106
|
var init_status = __esm({
|
|
5048
5107
|
"cli/commands/status.ts"() {
|
|
5049
5108
|
"use strict";
|
|
@@ -5051,8 +5110,8 @@ var init_status = __esm({
|
|
|
5051
5110
|
init_agentDetect();
|
|
5052
5111
|
init_ccHookConfig();
|
|
5053
5112
|
init_mcpConfig();
|
|
5054
|
-
SYNKRO_DIR3 =
|
|
5055
|
-
|
|
5113
|
+
SYNKRO_DIR3 = join13(homedir12(), ".synkro");
|
|
5114
|
+
CONFIG_PATH4 = join13(SYNKRO_DIR3, "config.env");
|
|
5056
5115
|
}
|
|
5057
5116
|
});
|
|
5058
5117
|
|
|
@@ -5141,13 +5200,13 @@ var config_exports = {};
|
|
|
5141
5200
|
__export(config_exports, {
|
|
5142
5201
|
configCommand: () => configCommand
|
|
5143
5202
|
});
|
|
5144
|
-
import { readFileSync as
|
|
5145
|
-
import { join as
|
|
5146
|
-
import { homedir as
|
|
5203
|
+
import { readFileSync as readFileSync12, writeFileSync as writeFileSync8, existsSync as existsSync14 } from "fs";
|
|
5204
|
+
import { join as join14 } from "path";
|
|
5205
|
+
import { homedir as homedir13 } from "os";
|
|
5147
5206
|
function readConfigEnv2() {
|
|
5148
|
-
if (!
|
|
5207
|
+
if (!existsSync14(CONFIG_PATH5)) return {};
|
|
5149
5208
|
const out = {};
|
|
5150
|
-
for (const line of
|
|
5209
|
+
for (const line of readFileSync12(CONFIG_PATH5, "utf-8").split("\n")) {
|
|
5151
5210
|
const t = line.trim();
|
|
5152
5211
|
if (!t || t.startsWith("#")) continue;
|
|
5153
5212
|
const eq = t.indexOf("=");
|
|
@@ -5156,11 +5215,11 @@ function readConfigEnv2() {
|
|
|
5156
5215
|
return out;
|
|
5157
5216
|
}
|
|
5158
5217
|
function updateConfigValue(key, value) {
|
|
5159
|
-
if (!
|
|
5218
|
+
if (!existsSync14(CONFIG_PATH5)) {
|
|
5160
5219
|
console.error("No config found. Run `synkro install` first.");
|
|
5161
5220
|
process.exit(1);
|
|
5162
5221
|
}
|
|
5163
|
-
const lines =
|
|
5222
|
+
const lines = readFileSync12(CONFIG_PATH5, "utf-8").split("\n");
|
|
5164
5223
|
const pattern = new RegExp(`^${key}=`);
|
|
5165
5224
|
let found = false;
|
|
5166
5225
|
const updated = lines.map((line) => {
|
|
@@ -5171,7 +5230,7 @@ function updateConfigValue(key, value) {
|
|
|
5171
5230
|
return line;
|
|
5172
5231
|
});
|
|
5173
5232
|
if (!found) updated.splice(updated.length - 1, 0, `${key}='${value}'`);
|
|
5174
|
-
writeFileSync8(
|
|
5233
|
+
writeFileSync8(CONFIG_PATH5, updated.join("\n"), "utf-8");
|
|
5175
5234
|
}
|
|
5176
5235
|
async function configCommand(args2) {
|
|
5177
5236
|
if (args2.length === 0) {
|
|
@@ -5222,13 +5281,13 @@ To change: synkro config --inference fast|standard`);
|
|
|
5222
5281
|
updateConfigValue("SYNKRO_INFERENCE", inferenceValue);
|
|
5223
5282
|
console.log(`\u2713 Inference set to '${inferenceValue}'.`);
|
|
5224
5283
|
}
|
|
5225
|
-
var SYNKRO_DIR4,
|
|
5284
|
+
var SYNKRO_DIR4, CONFIG_PATH5;
|
|
5226
5285
|
var init_config = __esm({
|
|
5227
5286
|
"cli/commands/config.ts"() {
|
|
5228
5287
|
"use strict";
|
|
5229
5288
|
init_stub();
|
|
5230
|
-
SYNKRO_DIR4 =
|
|
5231
|
-
|
|
5289
|
+
SYNKRO_DIR4 = join14(homedir13(), ".synkro");
|
|
5290
|
+
CONFIG_PATH5 = join14(SYNKRO_DIR4, "config.env");
|
|
5232
5291
|
}
|
|
5233
5292
|
});
|
|
5234
5293
|
|
|
@@ -5238,8 +5297,8 @@ __export(scanPr_exports, {
|
|
|
5238
5297
|
scanPrCommand: () => scanPrCommand
|
|
5239
5298
|
});
|
|
5240
5299
|
import { execSync as execSync6, spawn } from "child_process";
|
|
5241
|
-
import { readFileSync as
|
|
5242
|
-
import { join as
|
|
5300
|
+
import { readFileSync as readFileSync13, existsSync as existsSync15 } from "fs";
|
|
5301
|
+
import { join as join15 } from "path";
|
|
5243
5302
|
function parseMatchSpec(condition) {
|
|
5244
5303
|
if (!condition.startsWith("match_spec:")) return null;
|
|
5245
5304
|
try {
|
|
@@ -5718,10 +5777,10 @@ function shouldFail(findings, threshold) {
|
|
|
5718
5777
|
return findings.some((f) => order.indexOf(f.severity) >= thresholdIdx);
|
|
5719
5778
|
}
|
|
5720
5779
|
function readRepoDeps() {
|
|
5721
|
-
const pkgPath =
|
|
5722
|
-
if (!
|
|
5780
|
+
const pkgPath = join15(process.cwd(), "package.json");
|
|
5781
|
+
if (!existsSync15(pkgPath)) return {};
|
|
5723
5782
|
try {
|
|
5724
|
-
const pkg = JSON.parse(
|
|
5783
|
+
const pkg = JSON.parse(readFileSync13(pkgPath, "utf-8"));
|
|
5725
5784
|
return { ...pkg.dependencies ?? {}, ...pkg.devDependencies ?? {} };
|
|
5726
5785
|
} catch {
|
|
5727
5786
|
return {};
|
|
@@ -5983,9 +6042,9 @@ var disconnect_exports = {};
|
|
|
5983
6042
|
__export(disconnect_exports, {
|
|
5984
6043
|
disconnectCommand: () => disconnectCommand
|
|
5985
6044
|
});
|
|
5986
|
-
import { existsSync as
|
|
5987
|
-
import { homedir as
|
|
5988
|
-
import { join as
|
|
6045
|
+
import { existsSync as existsSync16, rmSync } from "fs";
|
|
6046
|
+
import { homedir as homedir14 } from "os";
|
|
6047
|
+
import { join as join16 } from "path";
|
|
5989
6048
|
function tearDownLocalCC() {
|
|
5990
6049
|
let hadTask = false;
|
|
5991
6050
|
try {
|
|
@@ -6015,13 +6074,13 @@ function disconnectCommand(args2 = []) {
|
|
|
6015
6074
|
console.log(`${mcpRemoved ? "\u2713" : "\xB7"} MCP guardrails server: ${mcpRemoved ? "removed entry from ~/.claude.json" : "no Synkro MCP entry found"}`);
|
|
6016
6075
|
}
|
|
6017
6076
|
if (purge) {
|
|
6018
|
-
if (
|
|
6077
|
+
if (existsSync16(SYNKRO_DIR5)) {
|
|
6019
6078
|
rmSync(SYNKRO_DIR5, { recursive: true, force: true });
|
|
6020
6079
|
console.log(`\u2713 Removed ${SYNKRO_DIR5}`);
|
|
6021
6080
|
} else {
|
|
6022
6081
|
console.log(`\xB7 ${SYNKRO_DIR5} already gone, nothing to remove`);
|
|
6023
6082
|
}
|
|
6024
|
-
} else if (
|
|
6083
|
+
} else if (existsSync16(SYNKRO_DIR5)) {
|
|
6025
6084
|
console.log(`Config preserved at ${SYNKRO_DIR5}. Run with --purge to remove.`);
|
|
6026
6085
|
}
|
|
6027
6086
|
console.log("\nSynkro disconnected.");
|
|
@@ -6035,7 +6094,7 @@ var init_disconnect = __esm({
|
|
|
6035
6094
|
init_mcpConfig();
|
|
6036
6095
|
init_pueue();
|
|
6037
6096
|
init_install();
|
|
6038
|
-
SYNKRO_DIR5 =
|
|
6097
|
+
SYNKRO_DIR5 = join16(homedir14(), ".synkro");
|
|
6039
6098
|
}
|
|
6040
6099
|
});
|
|
6041
6100
|
|
|
@@ -6076,28 +6135,6 @@ var init_reinstall = __esm({
|
|
|
6076
6135
|
}
|
|
6077
6136
|
});
|
|
6078
6137
|
|
|
6079
|
-
// cli/local-cc/settings.ts
|
|
6080
|
-
import { existsSync as existsSync16, readFileSync as readFileSync13 } from "fs";
|
|
6081
|
-
import { homedir as homedir14 } from "os";
|
|
6082
|
-
import { join as join16 } from "path";
|
|
6083
|
-
function isLocalCCEnabled() {
|
|
6084
|
-
if (!existsSync16(CONFIG_PATH5)) return false;
|
|
6085
|
-
try {
|
|
6086
|
-
const content = readFileSync13(CONFIG_PATH5, "utf-8");
|
|
6087
|
-
const match = content.match(/^SYNKRO_LOCAL_INFERENCE='([^']*)'/m);
|
|
6088
|
-
return match?.[1] === "yes";
|
|
6089
|
-
} catch {
|
|
6090
|
-
return false;
|
|
6091
|
-
}
|
|
6092
|
-
}
|
|
6093
|
-
var CONFIG_PATH5;
|
|
6094
|
-
var init_settings = __esm({
|
|
6095
|
-
"cli/local-cc/settings.ts"() {
|
|
6096
|
-
"use strict";
|
|
6097
|
-
CONFIG_PATH5 = join16(homedir14(), ".synkro", "config.env");
|
|
6098
|
-
}
|
|
6099
|
-
});
|
|
6100
|
-
|
|
6101
6138
|
// cli/commands/localCc.ts
|
|
6102
6139
|
var localCc_exports = {};
|
|
6103
6140
|
__export(localCc_exports, {
|
|
@@ -6202,7 +6239,7 @@ function readGatewayUrl() {
|
|
|
6202
6239
|
}
|
|
6203
6240
|
return "https://api.synkro.sh";
|
|
6204
6241
|
}
|
|
6205
|
-
function
|
|
6242
|
+
function updateLocalInferenceFlag2(enabled) {
|
|
6206
6243
|
if (!existsSync17(CONFIG_PATH6)) return;
|
|
6207
6244
|
let content = readFileSync14(CONFIG_PATH6, "utf-8");
|
|
6208
6245
|
const flag = enabled ? "yes" : "no";
|
|
@@ -6268,13 +6305,13 @@ async function cmdEnable() {
|
|
|
6268
6305
|
else console.warn(` \u26A0 channel did not come up within 60s \u2014 check \`synkro local-cc logs\``);
|
|
6269
6306
|
console.log("Updating inference settings...");
|
|
6270
6307
|
await setServerGradingProvider("claude-code");
|
|
6271
|
-
|
|
6308
|
+
updateLocalInferenceFlag2(true);
|
|
6272
6309
|
console.log("Grading provider set to claude-code (local inference enabled).");
|
|
6273
6310
|
}
|
|
6274
6311
|
async function cmdDisable() {
|
|
6275
6312
|
console.log("Updating inference settings...");
|
|
6276
6313
|
await setServerGradingProvider(null);
|
|
6277
|
-
|
|
6314
|
+
updateLocalInferenceFlag2(false);
|
|
6278
6315
|
console.log("Grading provider cleared (remote inference restored). Pueue task left running \u2014 use `synkro local-cc stop` to terminate.");
|
|
6279
6316
|
}
|
|
6280
6317
|
async function cmdStart() {
|