@synkro-sh/cli 1.4.0 → 1.4.1
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 +215 -230
- package/dist/bootstrap.js.map +1 -1
- package/package.json +1 -1
package/dist/bootstrap.js
CHANGED
|
@@ -3370,87 +3370,6 @@ var init_promptFetcher = __esm({
|
|
|
3370
3370
|
}
|
|
3371
3371
|
});
|
|
3372
3372
|
|
|
3373
|
-
// cli/storage/local.ts
|
|
3374
|
-
import Database from "better-sqlite3";
|
|
3375
|
-
import { existsSync as existsSync8, mkdirSync as mkdirSync6 } from "fs";
|
|
3376
|
-
import { homedir as homedir6 } from "os";
|
|
3377
|
-
import { join as join7 } from "path";
|
|
3378
|
-
function getSetting(key) {
|
|
3379
|
-
const row = db.prepare("SELECT value FROM settings WHERE key = ?").get(key);
|
|
3380
|
-
return row?.value ?? null;
|
|
3381
|
-
}
|
|
3382
|
-
function setSetting(key, value) {
|
|
3383
|
-
db.prepare(
|
|
3384
|
-
`INSERT INTO settings (key, value, updated_at) VALUES (?, ?, datetime('now'))
|
|
3385
|
-
ON CONFLICT(key) DO UPDATE SET value = excluded.value, updated_at = excluded.updated_at`
|
|
3386
|
-
).run(key, value);
|
|
3387
|
-
}
|
|
3388
|
-
var SYNKRO_DIR2, DB_PATH, db;
|
|
3389
|
-
var init_local = __esm({
|
|
3390
|
-
"cli/storage/local.ts"() {
|
|
3391
|
-
"use strict";
|
|
3392
|
-
SYNKRO_DIR2 = join7(homedir6(), ".synkro");
|
|
3393
|
-
DB_PATH = join7(SYNKRO_DIR2, "sessions.db");
|
|
3394
|
-
if (!existsSync8(SYNKRO_DIR2)) {
|
|
3395
|
-
mkdirSync6(SYNKRO_DIR2, { recursive: true });
|
|
3396
|
-
}
|
|
3397
|
-
try {
|
|
3398
|
-
db = new Database(DB_PATH);
|
|
3399
|
-
} catch (err) {
|
|
3400
|
-
const msg = err instanceof Error ? err.message : String(err);
|
|
3401
|
-
console.error(`Failed to initialize database at ${DB_PATH}: ${msg}`);
|
|
3402
|
-
console.error("Check that ~/.synkro/ is writable and disk is not full.");
|
|
3403
|
-
process.exit(1);
|
|
3404
|
-
}
|
|
3405
|
-
db.exec(`
|
|
3406
|
-
CREATE TABLE IF NOT EXISTS command_history (
|
|
3407
|
-
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
3408
|
-
command TEXT NOT NULL,
|
|
3409
|
-
created_at TEXT DEFAULT (datetime('now'))
|
|
3410
|
-
);
|
|
3411
|
-
`);
|
|
3412
|
-
db.exec(`
|
|
3413
|
-
CREATE TABLE IF NOT EXISTS project_keys (
|
|
3414
|
-
slug TEXT PRIMARY KEY,
|
|
3415
|
-
project_id TEXT NOT NULL,
|
|
3416
|
-
project_name TEXT NOT NULL,
|
|
3417
|
-
api_key TEXT NOT NULL,
|
|
3418
|
-
created_at TEXT DEFAULT (datetime('now'))
|
|
3419
|
-
);
|
|
3420
|
-
`);
|
|
3421
|
-
db.exec(`
|
|
3422
|
-
CREATE TABLE IF NOT EXISTS settings (
|
|
3423
|
-
key TEXT PRIMARY KEY,
|
|
3424
|
-
value TEXT NOT NULL,
|
|
3425
|
-
updated_at TEXT DEFAULT (datetime('now'))
|
|
3426
|
-
);
|
|
3427
|
-
`);
|
|
3428
|
-
process.on("exit", () => {
|
|
3429
|
-
db.close();
|
|
3430
|
-
});
|
|
3431
|
-
}
|
|
3432
|
-
});
|
|
3433
|
-
|
|
3434
|
-
// cli/local-cc/settings.ts
|
|
3435
|
-
function getInferenceProvider() {
|
|
3436
|
-
const raw = getSetting(KEY);
|
|
3437
|
-
return raw === "local-cc" ? "local-cc" : "inngest";
|
|
3438
|
-
}
|
|
3439
|
-
function setInferenceProvider(value) {
|
|
3440
|
-
setSetting(KEY, value);
|
|
3441
|
-
}
|
|
3442
|
-
function isLocalCCEnabled() {
|
|
3443
|
-
return getInferenceProvider() === "local-cc";
|
|
3444
|
-
}
|
|
3445
|
-
var KEY;
|
|
3446
|
-
var init_settings = __esm({
|
|
3447
|
-
"cli/local-cc/settings.ts"() {
|
|
3448
|
-
"use strict";
|
|
3449
|
-
init_local();
|
|
3450
|
-
KEY = "inference_provider";
|
|
3451
|
-
}
|
|
3452
|
-
});
|
|
3453
|
-
|
|
3454
3373
|
// cli/local-cc/channelSource.ts
|
|
3455
3374
|
var CHANNEL_PLUGIN_SOURCE;
|
|
3456
3375
|
var init_channelSource = __esm({
|
|
@@ -3601,13 +3520,13 @@ await mcp.connect(new StdioServerTransport());
|
|
|
3601
3520
|
});
|
|
3602
3521
|
|
|
3603
3522
|
// cli/local-cc/install.ts
|
|
3604
|
-
import { existsSync as
|
|
3605
|
-
import { join as
|
|
3606
|
-
import { homedir as
|
|
3523
|
+
import { existsSync as existsSync8, mkdirSync as mkdirSync6, writeFileSync as writeFileSync6, readFileSync as readFileSync6, chmodSync, copyFileSync, renameSync as renameSync3, unlinkSync as unlinkSync4, openSync, fsyncSync, closeSync } from "fs";
|
|
3524
|
+
import { join as join7 } from "path";
|
|
3525
|
+
import { homedir as homedir6 } from "os";
|
|
3607
3526
|
import { spawnSync } from "child_process";
|
|
3608
3527
|
function writePluginFiles() {
|
|
3609
|
-
|
|
3610
|
-
|
|
3528
|
+
mkdirSync6(SESSION_DIR, { recursive: true });
|
|
3529
|
+
mkdirSync6(PLUGIN_SETTINGS_DIR, { recursive: true });
|
|
3611
3530
|
writeFileSync6(PLUGIN_PATH, CHANNEL_PLUGIN_SOURCE, "utf-8");
|
|
3612
3531
|
chmodSync(PLUGIN_PATH, 493);
|
|
3613
3532
|
writeFileSync6(PLUGIN_PKG_PATH, PLUGIN_PACKAGE_JSON, "utf-8");
|
|
@@ -3639,7 +3558,7 @@ function runBunInstall() {
|
|
|
3639
3558
|
}
|
|
3640
3559
|
}
|
|
3641
3560
|
function safelyMutateClaudeJson(mutator) {
|
|
3642
|
-
if (!
|
|
3561
|
+
if (!existsSync8(CLAUDE_JSON_PATH)) {
|
|
3643
3562
|
return;
|
|
3644
3563
|
}
|
|
3645
3564
|
const originalText = readFileSync6(CLAUDE_JSON_PATH, "utf-8");
|
|
@@ -3767,15 +3686,15 @@ var init_install = __esm({
|
|
|
3767
3686
|
"cli/local-cc/install.ts"() {
|
|
3768
3687
|
"use strict";
|
|
3769
3688
|
init_channelSource();
|
|
3770
|
-
CLAUDE_JSON_BACKUP_PATH =
|
|
3771
|
-
SESSION_DIR =
|
|
3772
|
-
PLUGIN_PATH =
|
|
3773
|
-
PLUGIN_PKG_PATH =
|
|
3774
|
-
PLUGIN_SETTINGS_DIR =
|
|
3775
|
-
PLUGIN_SETTINGS_PATH =
|
|
3776
|
-
PROJECT_MCP_PATH =
|
|
3777
|
-
CLAUDE_JSON_PATH =
|
|
3778
|
-
RUN_SCRIPT_PATH =
|
|
3689
|
+
CLAUDE_JSON_BACKUP_PATH = join7(homedir6(), ".claude.json.synkro-bak");
|
|
3690
|
+
SESSION_DIR = join7(homedir6(), ".synkro", "cc_sessions");
|
|
3691
|
+
PLUGIN_PATH = join7(SESSION_DIR, "synkro-channel.ts");
|
|
3692
|
+
PLUGIN_PKG_PATH = join7(SESSION_DIR, "package.json");
|
|
3693
|
+
PLUGIN_SETTINGS_DIR = join7(SESSION_DIR, ".claude");
|
|
3694
|
+
PLUGIN_SETTINGS_PATH = join7(PLUGIN_SETTINGS_DIR, "settings.json");
|
|
3695
|
+
PROJECT_MCP_PATH = join7(SESSION_DIR, ".mcp.json");
|
|
3696
|
+
CLAUDE_JSON_PATH = join7(homedir6(), ".claude.json");
|
|
3697
|
+
RUN_SCRIPT_PATH = join7(SESSION_DIR, "run-claude.sh");
|
|
3779
3698
|
TMUX_SESSION_NAME = "synkro-local-cc";
|
|
3780
3699
|
RUN_SCRIPT_SOURCE = `#!/usr/bin/env bash
|
|
3781
3700
|
# Auto-generated by \`synkro install\`. Do not edit.
|
|
@@ -3827,8 +3746,8 @@ done
|
|
|
3827
3746
|
|
|
3828
3747
|
// cli/local-cc/pueue.ts
|
|
3829
3748
|
import { execFileSync, spawnSync as spawnSync2 } from "child_process";
|
|
3830
|
-
import { homedir as
|
|
3831
|
-
import { join as
|
|
3749
|
+
import { homedir as homedir7 } from "os";
|
|
3750
|
+
import { join as join8 } from "path";
|
|
3832
3751
|
import { connect } from "net";
|
|
3833
3752
|
function pueueAvailable() {
|
|
3834
3753
|
const r = spawnSync2("pueue", ["--version"], { encoding: "utf-8" });
|
|
@@ -3883,7 +3802,7 @@ function startTask(opts = {}) {
|
|
|
3883
3802
|
if (existing) {
|
|
3884
3803
|
spawnSync2("pueue", ["remove", String(existing.id)], { encoding: "utf-8" });
|
|
3885
3804
|
}
|
|
3886
|
-
const runScript =
|
|
3805
|
+
const runScript = join8(cwd, "run-claude.sh");
|
|
3887
3806
|
const args2 = [
|
|
3888
3807
|
"add",
|
|
3889
3808
|
"--label",
|
|
@@ -3975,7 +3894,7 @@ var init_pueue = __esm({
|
|
|
3975
3894
|
"use strict";
|
|
3976
3895
|
TASK_LABEL = "synkro-local-cc";
|
|
3977
3896
|
TMUX_SESSION = "synkro-local-cc";
|
|
3978
|
-
SESSION_DIR2 =
|
|
3897
|
+
SESSION_DIR2 = join8(homedir7(), ".synkro", "cc_sessions");
|
|
3979
3898
|
PueueError = class extends Error {
|
|
3980
3899
|
constructor(message, cause) {
|
|
3981
3900
|
super(message);
|
|
@@ -3993,9 +3912,9 @@ __export(install_exports, {
|
|
|
3993
3912
|
installCommand: () => installCommand,
|
|
3994
3913
|
parseArgs: () => parseArgs
|
|
3995
3914
|
});
|
|
3996
|
-
import { existsSync as
|
|
3997
|
-
import { homedir as
|
|
3998
|
-
import { join as
|
|
3915
|
+
import { existsSync as existsSync9, mkdirSync as mkdirSync7, writeFileSync as writeFileSync7, chmodSync as chmodSync2, readFileSync as readFileSync7, readdirSync } from "fs";
|
|
3916
|
+
import { homedir as homedir8 } from "os";
|
|
3917
|
+
import { join as join9 } from "path";
|
|
3999
3918
|
import { execSync as execSync5 } from "child_process";
|
|
4000
3919
|
import { createInterface as createInterface3 } from "readline";
|
|
4001
3920
|
function sanitizeGatewayCandidate(raw) {
|
|
@@ -4032,19 +3951,19 @@ async function promptTranscriptConsent() {
|
|
|
4032
3951
|
});
|
|
4033
3952
|
}
|
|
4034
3953
|
function ensureSynkroDir() {
|
|
4035
|
-
|
|
4036
|
-
|
|
4037
|
-
|
|
4038
|
-
|
|
3954
|
+
mkdirSync7(SYNKRO_DIR2, { recursive: true });
|
|
3955
|
+
mkdirSync7(HOOKS_DIR, { recursive: true });
|
|
3956
|
+
mkdirSync7(BIN_DIR, { recursive: true });
|
|
3957
|
+
mkdirSync7(OFFSETS_DIR, { recursive: true });
|
|
4039
3958
|
}
|
|
4040
3959
|
function writeHookScripts() {
|
|
4041
|
-
const bashScriptPath =
|
|
4042
|
-
const bashFollowupScriptPath =
|
|
4043
|
-
const editCaptureScriptPath =
|
|
4044
|
-
const editPrecheckScriptPath =
|
|
4045
|
-
const stopSummaryScriptPath =
|
|
4046
|
-
const sessionStartScriptPath =
|
|
4047
|
-
const transcriptSyncScriptPath =
|
|
3960
|
+
const bashScriptPath = join9(HOOKS_DIR, "cc-bash-judge.sh");
|
|
3961
|
+
const bashFollowupScriptPath = join9(HOOKS_DIR, "cc-bash-followup.sh");
|
|
3962
|
+
const editCaptureScriptPath = join9(HOOKS_DIR, "cc-edit-capture.sh");
|
|
3963
|
+
const editPrecheckScriptPath = join9(HOOKS_DIR, "cc-edit-precheck.sh");
|
|
3964
|
+
const stopSummaryScriptPath = join9(HOOKS_DIR, "cc-stop-summary.sh");
|
|
3965
|
+
const sessionStartScriptPath = join9(HOOKS_DIR, "cc-session-start.sh");
|
|
3966
|
+
const transcriptSyncScriptPath = join9(HOOKS_DIR, "cc-transcript-sync.sh");
|
|
4048
3967
|
writeFileSync7(bashScriptPath, CC_BASH_JUDGE_SCRIPT, "utf-8");
|
|
4049
3968
|
writeFileSync7(bashFollowupScriptPath, CC_BASH_FOLLOWUP_SCRIPT, "utf-8");
|
|
4050
3969
|
writeFileSync7(editCaptureScriptPath, CC_EDIT_CAPTURE_SCRIPT, "utf-8");
|
|
@@ -4078,11 +3997,11 @@ function shellQuoteSingle(value) {
|
|
|
4078
3997
|
}
|
|
4079
3998
|
function resolveSynkroBundle() {
|
|
4080
3999
|
const scriptPath = process.argv[1];
|
|
4081
|
-
if (scriptPath &&
|
|
4000
|
+
if (scriptPath && existsSync9(scriptPath)) return scriptPath;
|
|
4082
4001
|
return null;
|
|
4083
4002
|
}
|
|
4084
4003
|
function writeConfigEnv(opts) {
|
|
4085
|
-
const credsPath =
|
|
4004
|
+
const credsPath = join9(SYNKRO_DIR2, "credentials.json");
|
|
4086
4005
|
const safeGateway = sanitizeConfigValue(opts.gatewayUrl);
|
|
4087
4006
|
const safeUserId = sanitizeConfigValue(opts.userId);
|
|
4088
4007
|
const safeOrgId = sanitizeConfigValue(opts.orgId);
|
|
@@ -4098,7 +4017,7 @@ function writeConfigEnv(opts) {
|
|
|
4098
4017
|
`SYNKRO_CREDENTIALS_PATH=${shellQuoteSingle(credsPath)}`,
|
|
4099
4018
|
`SYNKRO_TIER=${shellQuoteSingle(safeTier)}`,
|
|
4100
4019
|
`SYNKRO_INFERENCE=${shellQuoteSingle(safeInference)}`,
|
|
4101
|
-
`SYNKRO_VERSION=${shellQuoteSingle("1.4.
|
|
4020
|
+
`SYNKRO_VERSION=${shellQuoteSingle("1.4.1")}`
|
|
4102
4021
|
];
|
|
4103
4022
|
if (safeSynkroBin) lines.push(`SYNKRO_CLI_BIN=${shellQuoteSingle(safeSynkroBin)}`);
|
|
4104
4023
|
if (safeUserId) lines.push(`SYNKRO_USER_ID=${shellQuoteSingle(safeUserId)}`);
|
|
@@ -4107,6 +4026,7 @@ function writeConfigEnv(opts) {
|
|
|
4107
4026
|
if (opts.transcriptConsent !== void 0) {
|
|
4108
4027
|
lines.push(`SYNKRO_TRANSCRIPT_CONSENT=${shellQuoteSingle(opts.transcriptConsent ? "yes" : "no")}`);
|
|
4109
4028
|
}
|
|
4029
|
+
lines.push(`SYNKRO_LOCAL_INFERENCE=${shellQuoteSingle(opts.localInference ? "yes" : "no")}`);
|
|
4110
4030
|
lines.push("");
|
|
4111
4031
|
writeFileSync7(CONFIG_PATH2, lines.join("\n"), "utf-8");
|
|
4112
4032
|
chmodSync2(CONFIG_PATH2, 384);
|
|
@@ -4129,16 +4049,16 @@ function collectLocalMetadata() {
|
|
|
4129
4049
|
meta.cc_version = execSync5("claude --version", { encoding: "utf-8", timeout: 5e3 }).trim().split("\n")[0];
|
|
4130
4050
|
} catch {
|
|
4131
4051
|
}
|
|
4132
|
-
const claudeDir =
|
|
4052
|
+
const claudeDir = join9(homedir8(), ".claude");
|
|
4133
4053
|
try {
|
|
4134
|
-
const settings = JSON.parse(readFileSync7(
|
|
4054
|
+
const settings = JSON.parse(readFileSync7(join9(claudeDir, "settings.json"), "utf-8"));
|
|
4135
4055
|
const plugins = Object.keys(settings.enabledPlugins ?? {}).filter((k) => settings.enabledPlugins[k]);
|
|
4136
4056
|
if (plugins.length) meta.enabled_plugins = plugins;
|
|
4137
4057
|
if (settings.permissions?.defaultMode) meta.permissions_mode = settings.permissions.defaultMode;
|
|
4138
4058
|
} catch {
|
|
4139
4059
|
}
|
|
4140
4060
|
try {
|
|
4141
|
-
const mcpCache = JSON.parse(readFileSync7(
|
|
4061
|
+
const mcpCache = JSON.parse(readFileSync7(join9(claudeDir, "mcp-needs-auth-cache.json"), "utf-8"));
|
|
4142
4062
|
const mcpNames = Object.keys(mcpCache);
|
|
4143
4063
|
if (mcpNames.length) meta.mcp_servers = mcpNames;
|
|
4144
4064
|
} catch {
|
|
@@ -4150,10 +4070,10 @@ function collectLocalMetadata() {
|
|
|
4150
4070
|
} catch {
|
|
4151
4071
|
}
|
|
4152
4072
|
try {
|
|
4153
|
-
const sessionsDir =
|
|
4073
|
+
const sessionsDir = join9(claudeDir, "sessions");
|
|
4154
4074
|
const files = readdirSync(sessionsDir).filter((f) => f.endsWith(".json")).slice(-5);
|
|
4155
4075
|
for (const f of files) {
|
|
4156
|
-
const s = JSON.parse(readFileSync7(
|
|
4076
|
+
const s = JSON.parse(readFileSync7(join9(sessionsDir, f), "utf-8"));
|
|
4157
4077
|
if (s.version) {
|
|
4158
4078
|
meta.cc_version = meta.cc_version || s.version;
|
|
4159
4079
|
break;
|
|
@@ -4168,7 +4088,7 @@ async function fetchUserProfile(gatewayUrl, token) {
|
|
|
4168
4088
|
const resp = await fetch(`${gatewayUrl}/api/v1/cli/me`, {
|
|
4169
4089
|
headers: { "Authorization": `Bearer ${token}` }
|
|
4170
4090
|
});
|
|
4171
|
-
if (!resp.ok) return { tier: "pro", inference: "fast" };
|
|
4091
|
+
if (!resp.ok) return { tier: "pro", inference: "fast", localInference: false };
|
|
4172
4092
|
const data = await resp.json();
|
|
4173
4093
|
const meta = collectLocalMetadata();
|
|
4174
4094
|
fetch(`${gatewayUrl}/api/v1/cli/me`, {
|
|
@@ -4179,10 +4099,11 @@ async function fetchUserProfile(gatewayUrl, token) {
|
|
|
4179
4099
|
});
|
|
4180
4100
|
return {
|
|
4181
4101
|
tier: data.plan_tier ?? "pro",
|
|
4182
|
-
inference: data.fast_inference ? "fast" : "standard"
|
|
4102
|
+
inference: data.fast_inference ? "fast" : "standard",
|
|
4103
|
+
localInference: !!data.local_inference
|
|
4183
4104
|
};
|
|
4184
4105
|
} catch {
|
|
4185
|
-
return { tier: "pro", inference: "fast" };
|
|
4106
|
+
return { tier: "pro", inference: "fast", localInference: false };
|
|
4186
4107
|
}
|
|
4187
4108
|
}
|
|
4188
4109
|
function assertGatewayAllowed(gatewayUrl) {
|
|
@@ -4208,17 +4129,17 @@ function assertGatewayAllowed(gatewayUrl) {
|
|
|
4208
4129
|
}
|
|
4209
4130
|
function isAlreadyInstalled() {
|
|
4210
4131
|
const requiredScripts = [
|
|
4211
|
-
|
|
4212
|
-
|
|
4213
|
-
|
|
4214
|
-
|
|
4215
|
-
|
|
4216
|
-
|
|
4132
|
+
join9(HOOKS_DIR, "cc-bash-judge.sh"),
|
|
4133
|
+
join9(HOOKS_DIR, "cc-bash-followup.sh"),
|
|
4134
|
+
join9(HOOKS_DIR, "cc-edit-precheck.sh"),
|
|
4135
|
+
join9(HOOKS_DIR, "cc-edit-capture.sh"),
|
|
4136
|
+
join9(HOOKS_DIR, "cc-stop-summary.sh"),
|
|
4137
|
+
join9(HOOKS_DIR, "cc-session-start.sh")
|
|
4217
4138
|
];
|
|
4218
|
-
if (!requiredScripts.every((p) =>
|
|
4219
|
-
if (!
|
|
4220
|
-
const settingsPath =
|
|
4221
|
-
if (!
|
|
4139
|
+
if (!requiredScripts.every((p) => existsSync9(p))) return false;
|
|
4140
|
+
if (!existsSync9(CONFIG_PATH2)) return false;
|
|
4141
|
+
const settingsPath = join9(homedir8(), ".claude", "settings.json");
|
|
4142
|
+
if (!existsSync9(settingsPath)) return false;
|
|
4222
4143
|
try {
|
|
4223
4144
|
const settings = JSON.parse(readFileSync7(settingsPath, "utf-8"));
|
|
4224
4145
|
const hooks = settings?.hooks;
|
|
@@ -4328,7 +4249,7 @@ async function installCommand(opts = {}) {
|
|
|
4328
4249
|
console.log(` ${scripts.transcriptSyncScript}
|
|
4329
4250
|
`);
|
|
4330
4251
|
for (const mode of ["edit", "bash"]) {
|
|
4331
|
-
const pidFile =
|
|
4252
|
+
const pidFile = join9(SYNKRO_DIR2, "daemon", mode, "daemon.pid");
|
|
4332
4253
|
try {
|
|
4333
4254
|
const pid = parseInt(readFileSync7(pidFile, "utf-8").trim(), 10);
|
|
4334
4255
|
if (pid > 0) {
|
|
@@ -4338,20 +4259,6 @@ async function installCommand(opts = {}) {
|
|
|
4338
4259
|
} catch {
|
|
4339
4260
|
}
|
|
4340
4261
|
}
|
|
4341
|
-
if (isLocalCCEnabled()) {
|
|
4342
|
-
try {
|
|
4343
|
-
assertClaudeInstalled();
|
|
4344
|
-
assertPueueInstalled();
|
|
4345
|
-
const r = installLocalCC();
|
|
4346
|
-
console.log(`Installed local-CC channel plugin at ${r.pluginPath}`);
|
|
4347
|
-
const t = ensureRunning();
|
|
4348
|
-
console.log(`Local-CC pueue task: id=${t.id} status=${t.status}
|
|
4349
|
-
`);
|
|
4350
|
-
} catch (err) {
|
|
4351
|
-
console.warn(` \u26A0 Local-CC setup skipped: ${err.message}`);
|
|
4352
|
-
console.warn(" Run `synkro local-cc enable` after fixing the issue.\n");
|
|
4353
|
-
}
|
|
4354
|
-
}
|
|
4355
4262
|
let transcriptConsent = true;
|
|
4356
4263
|
if (process.stdin.isTTY) {
|
|
4357
4264
|
transcriptConsent = await promptTranscriptConsent();
|
|
@@ -4418,9 +4325,10 @@ async function installCommand(opts = {}) {
|
|
|
4418
4325
|
}
|
|
4419
4326
|
const profile = await fetchUserProfile(gatewayUrl, token);
|
|
4420
4327
|
const synkroBundle = resolveSynkroBundle();
|
|
4421
|
-
writeConfigEnv({ gatewayUrl, userId, orgId, email, tier: profile.tier, inference: profile.inference, synkroBin: synkroBundle, transcriptConsent });
|
|
4328
|
+
writeConfigEnv({ gatewayUrl, userId, orgId, email, tier: profile.tier, inference: profile.inference, synkroBin: synkroBundle, transcriptConsent, localInference: profile.localInference });
|
|
4422
4329
|
console.log(`Wrote config to ${CONFIG_PATH2}`);
|
|
4423
4330
|
console.log(` inference: ${profile.inference} (server-side grading)`);
|
|
4331
|
+
if (profile.localInference) console.log(` local inference: enabled (gradingProvider=claude-code)`);
|
|
4424
4332
|
if (synkroBundle) console.log(` SYNKRO_CLI_BIN=${synkroBundle}`);
|
|
4425
4333
|
else console.warn(" \u26A0 Could not resolve synkro bundle path; hooks will fall back to PATH lookup of `synkro`.");
|
|
4426
4334
|
try {
|
|
@@ -4430,6 +4338,20 @@ async function installCommand(opts = {}) {
|
|
|
4430
4338
|
console.warn(` \u26A0 Could not cache judge prompts: ${err.message}`);
|
|
4431
4339
|
}
|
|
4432
4340
|
console.log();
|
|
4341
|
+
if (profile.localInference) {
|
|
4342
|
+
try {
|
|
4343
|
+
assertClaudeInstalled();
|
|
4344
|
+
assertPueueInstalled();
|
|
4345
|
+
const r = installLocalCC();
|
|
4346
|
+
console.log(`Installed local-CC channel plugin at ${r.pluginPath}`);
|
|
4347
|
+
const t = ensureRunning();
|
|
4348
|
+
console.log(`Local-CC pueue task: id=${t.id} status=${t.status}
|
|
4349
|
+
`);
|
|
4350
|
+
} catch (err) {
|
|
4351
|
+
console.warn(` \u26A0 Local-CC setup skipped: ${err.message}`);
|
|
4352
|
+
console.warn(" Set gradingProvider in your inference settings and re-run install.\n");
|
|
4353
|
+
}
|
|
4354
|
+
}
|
|
4433
4355
|
if (transcriptConsent) {
|
|
4434
4356
|
try {
|
|
4435
4357
|
const repo = detectGitRepo2();
|
|
@@ -4476,15 +4398,15 @@ function detectGitRepo2() {
|
|
|
4476
4398
|
function getClaudeProjectsFolder() {
|
|
4477
4399
|
const cwd = process.cwd();
|
|
4478
4400
|
const sanitized = "-" + cwd.replace(/\//g, "-");
|
|
4479
|
-
const projectsDir =
|
|
4480
|
-
return
|
|
4401
|
+
const projectsDir = join9(homedir8(), ".claude", "projects", sanitized);
|
|
4402
|
+
return existsSync9(projectsDir) ? projectsDir : null;
|
|
4481
4403
|
}
|
|
4482
4404
|
function extractSessionInsights(projectsDir) {
|
|
4483
4405
|
const insights = [];
|
|
4484
4406
|
const files = readdirSync(projectsDir).filter((f) => f.endsWith(".jsonl"));
|
|
4485
4407
|
for (const file of files) {
|
|
4486
4408
|
const sessionId = file.replace(".jsonl", "");
|
|
4487
|
-
const filePath =
|
|
4409
|
+
const filePath = join9(projectsDir, file);
|
|
4488
4410
|
try {
|
|
4489
4411
|
const content = readFileSync7(filePath, "utf-8");
|
|
4490
4412
|
const lines = content.split("\n").filter(Boolean);
|
|
@@ -4613,7 +4535,7 @@ async function syncTranscriptsBulk(gatewayUrl, token, repo) {
|
|
|
4613
4535
|
const sessions = [];
|
|
4614
4536
|
for (const file of batch) {
|
|
4615
4537
|
const sessionId = file.replace(".jsonl", "");
|
|
4616
|
-
const filePath =
|
|
4538
|
+
const filePath = join9(projectsDir, file);
|
|
4617
4539
|
try {
|
|
4618
4540
|
const allMessages = parseTranscriptFile(filePath);
|
|
4619
4541
|
const messages = allMessages.length > maxMessagesPerSession ? allMessages.slice(-maxMessagesPerSession) : allMessages;
|
|
@@ -4642,18 +4564,18 @@ async function syncTranscriptsBulk(gatewayUrl, token, repo) {
|
|
|
4642
4564
|
}
|
|
4643
4565
|
for (const file of batch) {
|
|
4644
4566
|
const sessionId = file.replace(".jsonl", "");
|
|
4645
|
-
const filePath =
|
|
4567
|
+
const filePath = join9(projectsDir, file);
|
|
4646
4568
|
try {
|
|
4647
4569
|
const content = readFileSync7(filePath, "utf-8");
|
|
4648
4570
|
const lineCount = content.split("\n").filter(Boolean).length;
|
|
4649
|
-
writeFileSync7(
|
|
4571
|
+
writeFileSync7(join9(OFFSETS_DIR, sessionId), String(lineCount), "utf-8");
|
|
4650
4572
|
} catch {
|
|
4651
4573
|
}
|
|
4652
4574
|
}
|
|
4653
4575
|
}
|
|
4654
4576
|
return { sessions: totalSessions, messages: totalMessages };
|
|
4655
4577
|
}
|
|
4656
|
-
var
|
|
4578
|
+
var SYNKRO_DIR2, HOOKS_DIR, BIN_DIR, CONFIG_PATH2, OFFSETS_DIR;
|
|
4657
4579
|
var init_install2 = __esm({
|
|
4658
4580
|
"cli/commands/install.ts"() {
|
|
4659
4581
|
"use strict";
|
|
@@ -4666,14 +4588,13 @@ var init_install2 = __esm({
|
|
|
4666
4588
|
init_projects();
|
|
4667
4589
|
init_setupGithub();
|
|
4668
4590
|
init_promptFetcher();
|
|
4669
|
-
init_settings();
|
|
4670
4591
|
init_install();
|
|
4671
4592
|
init_pueue();
|
|
4672
|
-
|
|
4673
|
-
HOOKS_DIR =
|
|
4674
|
-
BIN_DIR =
|
|
4675
|
-
CONFIG_PATH2 =
|
|
4676
|
-
OFFSETS_DIR =
|
|
4593
|
+
SYNKRO_DIR2 = join9(homedir8(), ".synkro");
|
|
4594
|
+
HOOKS_DIR = join9(SYNKRO_DIR2, "hooks");
|
|
4595
|
+
BIN_DIR = join9(SYNKRO_DIR2, "bin");
|
|
4596
|
+
CONFIG_PATH2 = join9(SYNKRO_DIR2, "config.env");
|
|
4597
|
+
OFFSETS_DIR = join9(SYNKRO_DIR2, ".transcript-offsets");
|
|
4677
4598
|
}
|
|
4678
4599
|
});
|
|
4679
4600
|
|
|
@@ -4749,11 +4670,11 @@ var status_exports = {};
|
|
|
4749
4670
|
__export(status_exports, {
|
|
4750
4671
|
statusCommand: () => statusCommand
|
|
4751
4672
|
});
|
|
4752
|
-
import { existsSync as
|
|
4753
|
-
import { homedir as
|
|
4754
|
-
import { join as
|
|
4673
|
+
import { existsSync as existsSync10, readFileSync as readFileSync8 } from "fs";
|
|
4674
|
+
import { homedir as homedir9 } from "os";
|
|
4675
|
+
import { join as join10 } from "path";
|
|
4755
4676
|
function readConfigEnv() {
|
|
4756
|
-
if (!
|
|
4677
|
+
if (!existsSync10(CONFIG_PATH3)) return {};
|
|
4757
4678
|
const out = {};
|
|
4758
4679
|
const raw = readFileSync8(CONFIG_PATH3, "utf-8");
|
|
4759
4680
|
for (const line of raw.split("\n")) {
|
|
@@ -4828,19 +4749,19 @@ async function statusCommand() {
|
|
|
4828
4749
|
}
|
|
4829
4750
|
}
|
|
4830
4751
|
console.log();
|
|
4831
|
-
const bashScript =
|
|
4832
|
-
const bashFollowupScript =
|
|
4833
|
-
const editPrecheckScript =
|
|
4834
|
-
const editCaptureScript =
|
|
4835
|
-
const stopSummaryScript =
|
|
4836
|
-
const sessionStartScript =
|
|
4752
|
+
const bashScript = join10(SYNKRO_DIR3, "hooks", "cc-bash-judge.sh");
|
|
4753
|
+
const bashFollowupScript = join10(SYNKRO_DIR3, "hooks", "cc-bash-followup.sh");
|
|
4754
|
+
const editPrecheckScript = join10(SYNKRO_DIR3, "hooks", "cc-edit-precheck.sh");
|
|
4755
|
+
const editCaptureScript = join10(SYNKRO_DIR3, "hooks", "cc-edit-capture.sh");
|
|
4756
|
+
const stopSummaryScript = join10(SYNKRO_DIR3, "hooks", "cc-stop-summary.sh");
|
|
4757
|
+
const sessionStartScript = join10(SYNKRO_DIR3, "hooks", "cc-session-start.sh");
|
|
4837
4758
|
console.log("Hook scripts:");
|
|
4838
|
-
console.log(` ${
|
|
4839
|
-
console.log(` ${
|
|
4840
|
-
console.log(` ${
|
|
4841
|
-
console.log(` ${
|
|
4842
|
-
console.log(` ${
|
|
4843
|
-
console.log(` ${
|
|
4759
|
+
console.log(` ${existsSync10(bashScript) ? "\u2713" : "\u2717"} ${bashScript}`);
|
|
4760
|
+
console.log(` ${existsSync10(bashFollowupScript) ? "\u2713" : "\u2717"} ${bashFollowupScript}`);
|
|
4761
|
+
console.log(` ${existsSync10(editPrecheckScript) ? "\u2713" : "\u2717"} ${editPrecheckScript}`);
|
|
4762
|
+
console.log(` ${existsSync10(editCaptureScript) ? "\u2713" : "\u2717"} ${editCaptureScript}`);
|
|
4763
|
+
console.log(` ${existsSync10(stopSummaryScript) ? "\u2713" : "\u2717"} ${stopSummaryScript}`);
|
|
4764
|
+
console.log(` ${existsSync10(sessionStartScript) ? "\u2713" : "\u2717"} ${sessionStartScript}`);
|
|
4844
4765
|
console.log();
|
|
4845
4766
|
const mcp = inspectMcpConfig();
|
|
4846
4767
|
console.log("Guardrails MCP server (Claude Code):");
|
|
@@ -4852,7 +4773,7 @@ async function statusCommand() {
|
|
|
4852
4773
|
console.log(` expected at ${mcp.configPath} \u2192 mcpServers.synkro-guardrails`);
|
|
4853
4774
|
}
|
|
4854
4775
|
}
|
|
4855
|
-
var
|
|
4776
|
+
var SYNKRO_DIR3, CONFIG_PATH3;
|
|
4856
4777
|
var init_status = __esm({
|
|
4857
4778
|
"cli/commands/status.ts"() {
|
|
4858
4779
|
"use strict";
|
|
@@ -4860,8 +4781,8 @@ var init_status = __esm({
|
|
|
4860
4781
|
init_agentDetect();
|
|
4861
4782
|
init_ccHookConfig();
|
|
4862
4783
|
init_mcpConfig();
|
|
4863
|
-
|
|
4864
|
-
CONFIG_PATH3 =
|
|
4784
|
+
SYNKRO_DIR3 = join10(homedir9(), ".synkro");
|
|
4785
|
+
CONFIG_PATH3 = join10(SYNKRO_DIR3, "config.env");
|
|
4865
4786
|
}
|
|
4866
4787
|
});
|
|
4867
4788
|
|
|
@@ -4950,11 +4871,11 @@ var config_exports = {};
|
|
|
4950
4871
|
__export(config_exports, {
|
|
4951
4872
|
configCommand: () => configCommand
|
|
4952
4873
|
});
|
|
4953
|
-
import { readFileSync as readFileSync9, writeFileSync as writeFileSync8, existsSync as
|
|
4954
|
-
import { join as
|
|
4955
|
-
import { homedir as
|
|
4874
|
+
import { readFileSync as readFileSync9, writeFileSync as writeFileSync8, existsSync as existsSync11 } from "fs";
|
|
4875
|
+
import { join as join11 } from "path";
|
|
4876
|
+
import { homedir as homedir10 } from "os";
|
|
4956
4877
|
function readConfigEnv2() {
|
|
4957
|
-
if (!
|
|
4878
|
+
if (!existsSync11(CONFIG_PATH4)) return {};
|
|
4958
4879
|
const out = {};
|
|
4959
4880
|
for (const line of readFileSync9(CONFIG_PATH4, "utf-8").split("\n")) {
|
|
4960
4881
|
const t = line.trim();
|
|
@@ -4965,7 +4886,7 @@ function readConfigEnv2() {
|
|
|
4965
4886
|
return out;
|
|
4966
4887
|
}
|
|
4967
4888
|
function updateConfigValue(key, value) {
|
|
4968
|
-
if (!
|
|
4889
|
+
if (!existsSync11(CONFIG_PATH4)) {
|
|
4969
4890
|
console.error("No config found. Run `synkro install` first.");
|
|
4970
4891
|
process.exit(1);
|
|
4971
4892
|
}
|
|
@@ -5031,13 +4952,13 @@ To change: synkro config --inference fast|standard`);
|
|
|
5031
4952
|
updateConfigValue("SYNKRO_INFERENCE", inferenceValue);
|
|
5032
4953
|
console.log(`\u2713 Inference set to '${inferenceValue}'.`);
|
|
5033
4954
|
}
|
|
5034
|
-
var
|
|
4955
|
+
var SYNKRO_DIR4, CONFIG_PATH4;
|
|
5035
4956
|
var init_config = __esm({
|
|
5036
4957
|
"cli/commands/config.ts"() {
|
|
5037
4958
|
"use strict";
|
|
5038
4959
|
init_stub();
|
|
5039
|
-
|
|
5040
|
-
CONFIG_PATH4 =
|
|
4960
|
+
SYNKRO_DIR4 = join11(homedir10(), ".synkro");
|
|
4961
|
+
CONFIG_PATH4 = join11(SYNKRO_DIR4, "config.env");
|
|
5041
4962
|
}
|
|
5042
4963
|
});
|
|
5043
4964
|
|
|
@@ -5047,8 +4968,8 @@ __export(scanPr_exports, {
|
|
|
5047
4968
|
scanPrCommand: () => scanPrCommand
|
|
5048
4969
|
});
|
|
5049
4970
|
import { execSync as execSync6, spawn } from "child_process";
|
|
5050
|
-
import { readFileSync as readFileSync10, existsSync as
|
|
5051
|
-
import { join as
|
|
4971
|
+
import { readFileSync as readFileSync10, existsSync as existsSync12 } from "fs";
|
|
4972
|
+
import { join as join12 } from "path";
|
|
5052
4973
|
function parseMatchSpec(condition) {
|
|
5053
4974
|
if (!condition.startsWith("match_spec:")) return null;
|
|
5054
4975
|
try {
|
|
@@ -5527,8 +5448,8 @@ function shouldFail(findings, threshold) {
|
|
|
5527
5448
|
return findings.some((f) => order.indexOf(f.severity) >= thresholdIdx);
|
|
5528
5449
|
}
|
|
5529
5450
|
function readRepoDeps() {
|
|
5530
|
-
const pkgPath =
|
|
5531
|
-
if (!
|
|
5451
|
+
const pkgPath = join12(process.cwd(), "package.json");
|
|
5452
|
+
if (!existsSync12(pkgPath)) return {};
|
|
5532
5453
|
try {
|
|
5533
5454
|
const pkg = JSON.parse(readFileSync10(pkgPath, "utf-8"));
|
|
5534
5455
|
return { ...pkg.dependencies ?? {}, ...pkg.devDependencies ?? {} };
|
|
@@ -5792,9 +5713,9 @@ var disconnect_exports = {};
|
|
|
5792
5713
|
__export(disconnect_exports, {
|
|
5793
5714
|
disconnectCommand: () => disconnectCommand
|
|
5794
5715
|
});
|
|
5795
|
-
import { existsSync as
|
|
5796
|
-
import { homedir as
|
|
5797
|
-
import { join as
|
|
5716
|
+
import { existsSync as existsSync13, rmSync } from "fs";
|
|
5717
|
+
import { homedir as homedir11 } from "os";
|
|
5718
|
+
import { join as join13 } from "path";
|
|
5798
5719
|
function tearDownLocalCC() {
|
|
5799
5720
|
let hadTask = false;
|
|
5800
5721
|
try {
|
|
@@ -5824,18 +5745,18 @@ function disconnectCommand(args2 = []) {
|
|
|
5824
5745
|
console.log(`${mcpRemoved ? "\u2713" : "\xB7"} MCP guardrails server: ${mcpRemoved ? "removed entry from ~/.claude.json" : "no Synkro MCP entry found"}`);
|
|
5825
5746
|
}
|
|
5826
5747
|
if (purge) {
|
|
5827
|
-
if (
|
|
5828
|
-
rmSync(
|
|
5829
|
-
console.log(`\u2713 Removed ${
|
|
5748
|
+
if (existsSync13(SYNKRO_DIR5)) {
|
|
5749
|
+
rmSync(SYNKRO_DIR5, { recursive: true, force: true });
|
|
5750
|
+
console.log(`\u2713 Removed ${SYNKRO_DIR5}`);
|
|
5830
5751
|
} else {
|
|
5831
|
-
console.log(`\xB7 ${
|
|
5752
|
+
console.log(`\xB7 ${SYNKRO_DIR5} already gone, nothing to remove`);
|
|
5832
5753
|
}
|
|
5833
|
-
} else if (
|
|
5834
|
-
console.log(`Config preserved at ${
|
|
5754
|
+
} else if (existsSync13(SYNKRO_DIR5)) {
|
|
5755
|
+
console.log(`Config preserved at ${SYNKRO_DIR5}. Run with --purge to remove.`);
|
|
5835
5756
|
}
|
|
5836
5757
|
console.log("\nSynkro disconnected.");
|
|
5837
5758
|
}
|
|
5838
|
-
var
|
|
5759
|
+
var SYNKRO_DIR5;
|
|
5839
5760
|
var init_disconnect = __esm({
|
|
5840
5761
|
"cli/commands/disconnect.ts"() {
|
|
5841
5762
|
"use strict";
|
|
@@ -5844,7 +5765,7 @@ var init_disconnect = __esm({
|
|
|
5844
5765
|
init_mcpConfig();
|
|
5845
5766
|
init_pueue();
|
|
5846
5767
|
init_install();
|
|
5847
|
-
|
|
5768
|
+
SYNKRO_DIR5 = join13(homedir11(), ".synkro");
|
|
5848
5769
|
}
|
|
5849
5770
|
});
|
|
5850
5771
|
|
|
@@ -5886,9 +5807,9 @@ var init_reinstall = __esm({
|
|
|
5886
5807
|
});
|
|
5887
5808
|
|
|
5888
5809
|
// cli/local-cc/turnLog.ts
|
|
5889
|
-
import { appendFileSync, existsSync as
|
|
5890
|
-
import { dirname as dirname5, join as
|
|
5891
|
-
import { homedir as
|
|
5810
|
+
import { appendFileSync, existsSync as existsSync14, mkdirSync as mkdirSync8, openSync as openSync2, readFileSync as readFileSync11, readSync, closeSync as closeSync2, statSync, watchFile, unwatchFile } from "fs";
|
|
5811
|
+
import { dirname as dirname5, join as join14 } from "path";
|
|
5812
|
+
import { homedir as homedir12 } from "os";
|
|
5892
5813
|
function truncate(s, max = PREVIEW_MAX) {
|
|
5893
5814
|
if (s.length <= max) return s;
|
|
5894
5815
|
return s.slice(0, max) + "\u2026 [+" + (s.length - max) + " chars]";
|
|
@@ -5908,7 +5829,7 @@ function extractSeverity(result) {
|
|
|
5908
5829
|
}
|
|
5909
5830
|
function appendTurn(args2) {
|
|
5910
5831
|
try {
|
|
5911
|
-
|
|
5832
|
+
mkdirSync8(dirname5(TURN_LOG_PATH), { recursive: true });
|
|
5912
5833
|
const entry = {
|
|
5913
5834
|
ts: new Date(args2.startedAt).toISOString(),
|
|
5914
5835
|
role: args2.role,
|
|
@@ -5924,7 +5845,7 @@ function appendTurn(args2) {
|
|
|
5924
5845
|
}
|
|
5925
5846
|
}
|
|
5926
5847
|
function readRecentTurns(n = 20) {
|
|
5927
|
-
if (!
|
|
5848
|
+
if (!existsSync14(TURN_LOG_PATH)) return [];
|
|
5928
5849
|
try {
|
|
5929
5850
|
const size = statSync(TURN_LOG_PATH).size;
|
|
5930
5851
|
if (size === 0) return [];
|
|
@@ -5944,8 +5865,8 @@ function readRecentTurns(n = 20) {
|
|
|
5944
5865
|
}
|
|
5945
5866
|
function followTurns(onEntry) {
|
|
5946
5867
|
try {
|
|
5947
|
-
|
|
5948
|
-
if (!
|
|
5868
|
+
mkdirSync8(dirname5(TURN_LOG_PATH), { recursive: true });
|
|
5869
|
+
if (!existsSync14(TURN_LOG_PATH)) {
|
|
5949
5870
|
appendFileSync(TURN_LOG_PATH, "", "utf-8");
|
|
5950
5871
|
}
|
|
5951
5872
|
} catch {
|
|
@@ -6007,13 +5928,35 @@ var TURN_LOG_PATH, PREVIEW_MAX;
|
|
|
6007
5928
|
var init_turnLog = __esm({
|
|
6008
5929
|
"cli/local-cc/turnLog.ts"() {
|
|
6009
5930
|
"use strict";
|
|
6010
|
-
TURN_LOG_PATH =
|
|
5931
|
+
TURN_LOG_PATH = join14(homedir12(), ".synkro", "cc_sessions", "turns.log");
|
|
6011
5932
|
PREVIEW_MAX = 400;
|
|
6012
5933
|
}
|
|
6013
5934
|
});
|
|
6014
5935
|
|
|
5936
|
+
// cli/local-cc/settings.ts
|
|
5937
|
+
import { existsSync as existsSync15, readFileSync as readFileSync12 } from "fs";
|
|
5938
|
+
import { homedir as homedir13 } from "os";
|
|
5939
|
+
import { join as join15 } from "path";
|
|
5940
|
+
function isLocalCCEnabled() {
|
|
5941
|
+
if (!existsSync15(CONFIG_PATH5)) return false;
|
|
5942
|
+
try {
|
|
5943
|
+
const content = readFileSync12(CONFIG_PATH5, "utf-8");
|
|
5944
|
+
const match = content.match(/^SYNKRO_LOCAL_INFERENCE='([^']*)'/m);
|
|
5945
|
+
return match?.[1] === "yes";
|
|
5946
|
+
} catch {
|
|
5947
|
+
return false;
|
|
5948
|
+
}
|
|
5949
|
+
}
|
|
5950
|
+
var CONFIG_PATH5;
|
|
5951
|
+
var init_settings = __esm({
|
|
5952
|
+
"cli/local-cc/settings.ts"() {
|
|
5953
|
+
"use strict";
|
|
5954
|
+
CONFIG_PATH5 = join15(homedir13(), ".synkro", "config.env");
|
|
5955
|
+
}
|
|
5956
|
+
});
|
|
5957
|
+
|
|
6015
5958
|
// cli/local-cc/prompts.ts
|
|
6016
|
-
import { existsSync as existsSync16, readFileSync as
|
|
5959
|
+
import { existsSync as existsSync16, readFileSync as readFileSync13 } from "fs";
|
|
6017
5960
|
import { homedir as homedir14 } from "os";
|
|
6018
5961
|
import { join as join16 } from "path";
|
|
6019
5962
|
function loadCachedPrompts() {
|
|
@@ -6022,7 +5965,7 @@ function loadCachedPrompts() {
|
|
|
6022
5965
|
throw new Error("Prompts cache not found. Run `synkro install` or `synkro update` first.");
|
|
6023
5966
|
}
|
|
6024
5967
|
try {
|
|
6025
|
-
_cached = JSON.parse(
|
|
5968
|
+
_cached = JSON.parse(readFileSync13(CACHE_PATH2, "utf-8"));
|
|
6026
5969
|
return _cached;
|
|
6027
5970
|
} catch {
|
|
6028
5971
|
throw new Error("Prompts cache is corrupted. Run `synkro update` to refresh.");
|
|
@@ -6156,8 +6099,8 @@ __export(localCc_exports, {
|
|
|
6156
6099
|
import { spawnSync as spawnSync3 } from "child_process";
|
|
6157
6100
|
import { homedir as homedir15 } from "os";
|
|
6158
6101
|
import { join as join17 } from "path";
|
|
6102
|
+
import { existsSync as existsSync17, readFileSync as readFileSync14, writeFileSync as writeFileSync9 } from "fs";
|
|
6159
6103
|
function printHelp() {
|
|
6160
|
-
const dbPath = join17(homedir15(), ".synkro", "sessions.db");
|
|
6161
6104
|
console.log(`synkro local-cc \u2014 manage the local Claude Code inference session
|
|
6162
6105
|
|
|
6163
6106
|
OVERVIEW
|
|
@@ -6199,11 +6142,10 @@ SUBCOMMANDS
|
|
|
6199
6142
|
help Show this message
|
|
6200
6143
|
|
|
6201
6144
|
CONFIGURATION
|
|
6202
|
-
Provider toggle
|
|
6203
|
-
Stored in
|
|
6145
|
+
Provider toggle:
|
|
6146
|
+
Stored server-side in your inference settings (gradingProvider).
|
|
6204
6147
|
Toggle via: synkro local-cc enable / disable
|
|
6205
|
-
Or
|
|
6206
|
-
INSERT OR REPLACE INTO settings (key, value) VALUES ('inference_provider', 'local-cc');
|
|
6148
|
+
Or via dashboard inference settings (set grading provider to claude-code).
|
|
6207
6149
|
|
|
6208
6150
|
Claude Code session settings (scoped to ~/.synkro/cc_sessions only):
|
|
6209
6151
|
${PLUGIN_SETTINGS_PATH}
|
|
@@ -6246,8 +6188,44 @@ TROUBLESHOOTING
|
|
|
6246
6188
|
synkro local-cc attach
|
|
6247
6189
|
`);
|
|
6248
6190
|
}
|
|
6191
|
+
function readGatewayUrl() {
|
|
6192
|
+
if (existsSync17(CONFIG_PATH6)) {
|
|
6193
|
+
const m = readFileSync14(CONFIG_PATH6, "utf-8").match(/^SYNKRO_GATEWAY_URL='([^']*)'/m);
|
|
6194
|
+
if (m) return m[1];
|
|
6195
|
+
}
|
|
6196
|
+
return "https://api.synkro.sh";
|
|
6197
|
+
}
|
|
6198
|
+
function updateLocalInferenceFlag(enabled) {
|
|
6199
|
+
if (!existsSync17(CONFIG_PATH6)) return;
|
|
6200
|
+
let content = readFileSync14(CONFIG_PATH6, "utf-8");
|
|
6201
|
+
const flag = enabled ? "yes" : "no";
|
|
6202
|
+
if (content.includes("SYNKRO_LOCAL_INFERENCE=")) {
|
|
6203
|
+
content = content.replace(/^SYNKRO_LOCAL_INFERENCE='[^']*'/m, `SYNKRO_LOCAL_INFERENCE='${flag}'`);
|
|
6204
|
+
} else {
|
|
6205
|
+
content = content.trimEnd() + `
|
|
6206
|
+
SYNKRO_LOCAL_INFERENCE='${flag}'
|
|
6207
|
+
`;
|
|
6208
|
+
}
|
|
6209
|
+
writeFileSync9(CONFIG_PATH6, content, "utf-8");
|
|
6210
|
+
}
|
|
6211
|
+
async function setServerGradingProvider(provider) {
|
|
6212
|
+
await ensureValidToken();
|
|
6213
|
+
const jwt2 = getAccessToken();
|
|
6214
|
+
if (!jwt2) throw new Error("Not authenticated. Run `synkro install` first.");
|
|
6215
|
+
const gatewayUrl = readGatewayUrl();
|
|
6216
|
+
const body = provider ? { roles: { grading: { provider, model: "default" } } } : { roles: { grading: { provider: null, model: null } } };
|
|
6217
|
+
const resp = await fetch(`${gatewayUrl}/api/settings/inference?scope=user`, {
|
|
6218
|
+
method: "PUT",
|
|
6219
|
+
headers: { "Authorization": `Bearer ${jwt2}`, "Content-Type": "application/json" },
|
|
6220
|
+
body: JSON.stringify(body)
|
|
6221
|
+
});
|
|
6222
|
+
if (!resp.ok) {
|
|
6223
|
+
const text = await resp.text().catch(() => "");
|
|
6224
|
+
throw new Error(`Failed to update inference settings: ${resp.status} ${text.slice(0, 200)}`);
|
|
6225
|
+
}
|
|
6226
|
+
}
|
|
6249
6227
|
async function cmdStatus() {
|
|
6250
|
-
console.log(`
|
|
6228
|
+
console.log(`Local inference: ${isLocalCCEnabled() ? "enabled" : "disabled"}`);
|
|
6251
6229
|
try {
|
|
6252
6230
|
assertPueueInstalled();
|
|
6253
6231
|
} catch (err) {
|
|
@@ -6281,12 +6259,16 @@ async function cmdEnable() {
|
|
|
6281
6259
|
const ready = await waitForChannelReady(CHANNEL_PORT, 6e4, CHANNEL_HOST);
|
|
6282
6260
|
if (ready) console.log(` channel ready at ${CHANNEL_HOST}:${CHANNEL_PORT}`);
|
|
6283
6261
|
else console.warn(` \u26A0 channel did not come up within 60s \u2014 check \`synkro local-cc logs\``);
|
|
6284
|
-
|
|
6285
|
-
|
|
6262
|
+
console.log("Updating inference settings...");
|
|
6263
|
+
await setServerGradingProvider("claude-code");
|
|
6264
|
+
updateLocalInferenceFlag(true);
|
|
6265
|
+
console.log("Grading provider set to claude-code (local inference enabled).");
|
|
6286
6266
|
}
|
|
6287
|
-
function cmdDisable() {
|
|
6288
|
-
|
|
6289
|
-
|
|
6267
|
+
async function cmdDisable() {
|
|
6268
|
+
console.log("Updating inference settings...");
|
|
6269
|
+
await setServerGradingProvider(null);
|
|
6270
|
+
updateLocalInferenceFlag(false);
|
|
6271
|
+
console.log("Grading provider cleared (remote inference restored). Pueue task left running \u2014 use `synkro local-cc stop` to terminate.");
|
|
6290
6272
|
}
|
|
6291
6273
|
async function cmdStart() {
|
|
6292
6274
|
assertClaudeInstalled();
|
|
@@ -6489,6 +6471,7 @@ async function localCcCommand(args2) {
|
|
|
6489
6471
|
process.exit(1);
|
|
6490
6472
|
}
|
|
6491
6473
|
}
|
|
6474
|
+
var CONFIG_PATH6;
|
|
6492
6475
|
var init_localCc = __esm({
|
|
6493
6476
|
"cli/commands/localCc.ts"() {
|
|
6494
6477
|
"use strict";
|
|
@@ -6497,6 +6480,8 @@ var init_localCc = __esm({
|
|
|
6497
6480
|
init_pueue();
|
|
6498
6481
|
init_settings();
|
|
6499
6482
|
init_client();
|
|
6483
|
+
init_stub();
|
|
6484
|
+
CONFIG_PATH6 = join17(homedir15(), ".synkro", "config.env");
|
|
6500
6485
|
}
|
|
6501
6486
|
});
|
|
6502
6487
|
|
|
@@ -6548,15 +6533,15 @@ var init_grade = __esm({
|
|
|
6548
6533
|
});
|
|
6549
6534
|
|
|
6550
6535
|
// cli/bootstrap.js
|
|
6551
|
-
import { readFileSync as
|
|
6536
|
+
import { readFileSync as readFileSync15, existsSync as existsSync18 } from "fs";
|
|
6552
6537
|
import { resolve } from "path";
|
|
6553
6538
|
var envCandidates = [
|
|
6554
6539
|
resolve(process.cwd(), ".env"),
|
|
6555
6540
|
resolve(process.env.HOME ?? "", ".synkro", "config.env")
|
|
6556
6541
|
];
|
|
6557
6542
|
for (const envPath of envCandidates) {
|
|
6558
|
-
if (!
|
|
6559
|
-
const envContent =
|
|
6543
|
+
if (!existsSync18(envPath)) continue;
|
|
6544
|
+
const envContent = readFileSync15(envPath, "utf-8");
|
|
6560
6545
|
for (const line of envContent.split("\n")) {
|
|
6561
6546
|
const trimmed = line.trim();
|
|
6562
6547
|
if (!trimmed || trimmed.startsWith("#")) continue;
|