@synkro-sh/cli 1.6.36 → 1.6.38
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 +86 -94
- package/dist/bootstrap.js.map +1 -1
- package/package.json +1 -1
package/dist/bootstrap.js
CHANGED
|
@@ -602,54 +602,14 @@ var init_mcpConfig = __esm({
|
|
|
602
602
|
});
|
|
603
603
|
|
|
604
604
|
// cli/installer/skillParser.ts
|
|
605
|
-
import {
|
|
606
|
-
import { resolve as resolve2
|
|
607
|
-
function parseSection(heading, body) {
|
|
608
|
-
const lines = body.split("\n");
|
|
609
|
-
const meta = {};
|
|
610
|
-
const textLines = [];
|
|
611
|
-
for (const line of lines) {
|
|
612
|
-
const m = line.match(/^(mode|severity|category)\s*:\s*(.+)/i);
|
|
613
|
-
if (m && META_KEYS.has(m[1].toLowerCase())) {
|
|
614
|
-
meta[m[1].toLowerCase()] = m[2].trim();
|
|
615
|
-
} else if (line.trim()) {
|
|
616
|
-
textLines.push(line.trim());
|
|
617
|
-
}
|
|
618
|
-
}
|
|
619
|
-
const description = textLines.join(" ").trim();
|
|
620
|
-
const text = description ? `${heading}: ${description}` : heading;
|
|
621
|
-
return {
|
|
622
|
-
text,
|
|
623
|
-
mode: meta.mode || "ask",
|
|
624
|
-
severity: meta.severity || "medium",
|
|
625
|
-
category: meta.category || "custom"
|
|
626
|
-
};
|
|
627
|
-
}
|
|
628
|
-
function parseSkillFile(filePath) {
|
|
629
|
-
if (!existsSync4(filePath)) return null;
|
|
630
|
-
const content = readFileSync4(filePath, "utf-8");
|
|
631
|
-
const source = `skill:${basename(filePath)}`;
|
|
632
|
-
const sections = content.split(/^## /m).slice(1);
|
|
633
|
-
if (sections.length === 0) return null;
|
|
634
|
-
const rules = [];
|
|
635
|
-
for (const section of sections) {
|
|
636
|
-
const newlineIdx = section.indexOf("\n");
|
|
637
|
-
if (newlineIdx === -1) continue;
|
|
638
|
-
const heading = section.slice(0, newlineIdx).trim();
|
|
639
|
-
const body = section.slice(newlineIdx + 1);
|
|
640
|
-
if (!heading) continue;
|
|
641
|
-
rules.push(parseSection(heading, body));
|
|
642
|
-
}
|
|
643
|
-
return rules.length > 0 ? { source, rules } : null;
|
|
644
|
-
}
|
|
605
|
+
import { existsSync as existsSync4 } from "fs";
|
|
606
|
+
import { resolve as resolve2 } from "path";
|
|
645
607
|
function resolveSkillPaths(skills, repoRoot) {
|
|
646
608
|
return skills.filter((s) => s.endsWith(".md")).map((s) => resolve2(repoRoot, s)).filter((p) => existsSync4(p));
|
|
647
609
|
}
|
|
648
|
-
var META_KEYS;
|
|
649
610
|
var init_skillParser = __esm({
|
|
650
611
|
"cli/installer/skillParser.ts"() {
|
|
651
612
|
"use strict";
|
|
652
|
-
META_KEYS = /* @__PURE__ */ new Set(["mode", "severity", "category"]);
|
|
653
613
|
}
|
|
654
614
|
});
|
|
655
615
|
|
|
@@ -6056,7 +6016,7 @@ __export(stub_exports, {
|
|
|
6056
6016
|
saveCredentials: () => saveCredentials
|
|
6057
6017
|
});
|
|
6058
6018
|
import { createServer } from "http";
|
|
6059
|
-
import { writeFileSync as writeFileSync4, readFileSync as
|
|
6019
|
+
import { writeFileSync as writeFileSync4, readFileSync as readFileSync4, existsSync as existsSync5, mkdirSync as mkdirSync4, unlinkSync as unlinkSync2 } from "fs";
|
|
6060
6020
|
import { homedir as homedir4, platform } from "os";
|
|
6061
6021
|
import { join as join3, dirname as dirname4 } from "path";
|
|
6062
6022
|
import { execFile } from "child_process";
|
|
@@ -6097,7 +6057,7 @@ function loadCredentials() {
|
|
|
6097
6057
|
return null;
|
|
6098
6058
|
}
|
|
6099
6059
|
try {
|
|
6100
|
-
const content =
|
|
6060
|
+
const content = readFileSync4(AUTH_FILE, "utf8");
|
|
6101
6061
|
return JSON.parse(content);
|
|
6102
6062
|
} catch (error) {
|
|
6103
6063
|
return null;
|
|
@@ -6955,7 +6915,7 @@ __export(macKeychain_exports, {
|
|
|
6955
6915
|
writeCursorApiKey: () => writeCursorApiKey,
|
|
6956
6916
|
writeRefreshAgent: () => writeRefreshAgent
|
|
6957
6917
|
});
|
|
6958
|
-
import { existsSync as existsSync7, mkdirSync as mkdirSync6, writeFileSync as writeFileSync6, chmodSync, readFileSync as
|
|
6918
|
+
import { existsSync as existsSync7, mkdirSync as mkdirSync6, writeFileSync as writeFileSync6, chmodSync, readFileSync as readFileSync5, statSync } from "fs";
|
|
6959
6919
|
import { homedir as homedir5, platform as platform2 } from "os";
|
|
6960
6920
|
import { join as join5 } from "path";
|
|
6961
6921
|
import { spawnSync } from "child_process";
|
|
@@ -6983,7 +6943,7 @@ function exportKeychainCreds() {
|
|
|
6983
6943
|
}
|
|
6984
6944
|
function cursorApiKeyConfigured() {
|
|
6985
6945
|
try {
|
|
6986
|
-
return existsSync7(CURSOR_API_KEY_FILE) &&
|
|
6946
|
+
return existsSync7(CURSOR_API_KEY_FILE) && readFileSync5(CURSOR_API_KEY_FILE, "utf-8").trim().length > 0;
|
|
6987
6947
|
} catch {
|
|
6988
6948
|
return false;
|
|
6989
6949
|
}
|
|
@@ -6999,7 +6959,7 @@ function writeCursorApiKey(key) {
|
|
|
6999
6959
|
async function validateCursorApiKey() {
|
|
7000
6960
|
let key;
|
|
7001
6961
|
try {
|
|
7002
|
-
key =
|
|
6962
|
+
key = readFileSync5(CURSOR_API_KEY_FILE, "utf-8").trim();
|
|
7003
6963
|
} catch {
|
|
7004
6964
|
return null;
|
|
7005
6965
|
}
|
|
@@ -7093,7 +7053,7 @@ function refreshCreds() {
|
|
|
7093
7053
|
}
|
|
7094
7054
|
function readExportedCreds() {
|
|
7095
7055
|
try {
|
|
7096
|
-
return
|
|
7056
|
+
return readFileSync5(CLAUDE_CREDS_FILE, "utf-8");
|
|
7097
7057
|
} catch {
|
|
7098
7058
|
return null;
|
|
7099
7059
|
}
|
|
@@ -7140,9 +7100,10 @@ __export(dockerInstall_exports, {
|
|
|
7140
7100
|
readContainerConfig: () => readContainerConfig,
|
|
7141
7101
|
resolveWorkerConfig: () => resolveWorkerConfig,
|
|
7142
7102
|
splitWorkers: () => splitWorkers,
|
|
7143
|
-
waitForContainerReady: () => waitForContainerReady
|
|
7103
|
+
waitForContainerReady: () => waitForContainerReady,
|
|
7104
|
+
waitForWorkersReady: () => waitForWorkersReady
|
|
7144
7105
|
});
|
|
7145
|
-
import { copyFileSync, existsSync as existsSync8, mkdirSync as mkdirSync7, readFileSync as
|
|
7106
|
+
import { copyFileSync, existsSync as existsSync8, mkdirSync as mkdirSync7, readFileSync as readFileSync6, readdirSync as readdirSync2 } from "fs";
|
|
7146
7107
|
import { homedir as homedir6 } from "os";
|
|
7147
7108
|
import { join as join6 } from "path";
|
|
7148
7109
|
import { execSync as execSync4, spawnSync as spawnSync2 } from "child_process";
|
|
@@ -7212,7 +7173,7 @@ function readSynkroFileConfig() {
|
|
|
7212
7173
|
if (!root) return { pool: "auto" };
|
|
7213
7174
|
const fp = join6(root, ".synkro");
|
|
7214
7175
|
if (!existsSync8(fp)) return { pool: "auto" };
|
|
7215
|
-
const raw =
|
|
7176
|
+
const raw = readFileSync6(fp, "utf-8");
|
|
7216
7177
|
const parsed = raw.trimStart().startsWith("{") ? JSON.parse(raw) : parseSynkroYaml(raw);
|
|
7217
7178
|
const pool = ["auto", "claude", "cursor"].includes(parsed?.grader?.pool) ? parsed.grader.pool : "auto";
|
|
7218
7179
|
const cw = typeof parsed?.workers?.claude === "number" ? Math.max(0, Math.floor(parsed.workers.claude)) : void 0;
|
|
@@ -7467,6 +7428,22 @@ async function waitForContainerReady(timeoutMs = 6e4) {
|
|
|
7467
7428
|
}
|
|
7468
7429
|
return false;
|
|
7469
7430
|
}
|
|
7431
|
+
async function waitForWorkersReady(timeoutMs = 6e4) {
|
|
7432
|
+
const start = Date.now();
|
|
7433
|
+
const url = `http://127.0.0.1:${HOST_GRADER_PORT}/healthz`;
|
|
7434
|
+
while (Date.now() - start < timeoutMs) {
|
|
7435
|
+
try {
|
|
7436
|
+
const r = await fetch(url, { signal: AbortSignal.timeout(2e3) });
|
|
7437
|
+
if (r.ok) {
|
|
7438
|
+
const data = await r.json();
|
|
7439
|
+
if ((data.healthy || 0) > 0) return true;
|
|
7440
|
+
}
|
|
7441
|
+
} catch {
|
|
7442
|
+
}
|
|
7443
|
+
await new Promise((r) => setTimeout(r, 1e3));
|
|
7444
|
+
}
|
|
7445
|
+
return false;
|
|
7446
|
+
}
|
|
7470
7447
|
function dockerRemove() {
|
|
7471
7448
|
spawnSync2("docker", ["rm", CONTAINER_NAME], { encoding: "utf-8", timeout: 3e4 });
|
|
7472
7449
|
}
|
|
@@ -7674,14 +7651,14 @@ __export(setupGithub_exports, {
|
|
|
7674
7651
|
import { createInterface as createInterface2 } from "readline/promises";
|
|
7675
7652
|
import { stdin as input, stdout as output } from "process";
|
|
7676
7653
|
import { execSync as execSync5, spawn as nodeSpawn } from "child_process";
|
|
7677
|
-
import { existsSync as existsSync9, readFileSync as
|
|
7654
|
+
import { existsSync as existsSync9, readFileSync as readFileSync7, unlinkSync as unlinkSync3 } from "fs";
|
|
7678
7655
|
import { homedir as homedir7, platform as platform3 } from "os";
|
|
7679
7656
|
import { join as join7 } from "path";
|
|
7680
7657
|
import { execFile as execFile2 } from "child_process";
|
|
7681
7658
|
function readConfig() {
|
|
7682
7659
|
if (!existsSync9(CONFIG_PATH)) return {};
|
|
7683
7660
|
const out = {};
|
|
7684
|
-
for (const line of
|
|
7661
|
+
for (const line of readFileSync7(CONFIG_PATH, "utf-8").split("\n")) {
|
|
7685
7662
|
const t = line.trim();
|
|
7686
7663
|
if (!t || t.startsWith("#")) continue;
|
|
7687
7664
|
const eq = t.indexOf("=");
|
|
@@ -7751,7 +7728,7 @@ function captureClaudeSetupToken() {
|
|
|
7751
7728
|
proc.on("close", (code) => {
|
|
7752
7729
|
let raw = "";
|
|
7753
7730
|
try {
|
|
7754
|
-
raw =
|
|
7731
|
+
raw = readFileSync7(tmpFile, "utf-8");
|
|
7755
7732
|
} catch (e) {
|
|
7756
7733
|
reject(new Error(`Could not read script output file: ${e.message}`));
|
|
7757
7734
|
return;
|
|
@@ -8038,7 +8015,7 @@ __export(install_exports, {
|
|
|
8038
8015
|
syncSkillFiles: () => syncSkillFiles,
|
|
8039
8016
|
writeHookScripts: () => writeHookScripts
|
|
8040
8017
|
});
|
|
8041
|
-
import { existsSync as existsSync10, mkdirSync as mkdirSync8, writeFileSync as writeFileSync7, chmodSync as chmodSync2, readFileSync as
|
|
8018
|
+
import { existsSync as existsSync10, mkdirSync as mkdirSync8, writeFileSync as writeFileSync7, chmodSync as chmodSync2, readFileSync as readFileSync8, readdirSync as readdirSync3 } from "fs";
|
|
8042
8019
|
import { homedir as homedir8 } from "os";
|
|
8043
8020
|
import { join as join8 } from "path";
|
|
8044
8021
|
import { execSync as execSync6, spawnSync as spawnSync3 } from "child_process";
|
|
@@ -8284,7 +8261,7 @@ function writeConfigEnv(opts) {
|
|
|
8284
8261
|
`SYNKRO_CREDENTIALS_PATH=${shellQuoteSingle(credsPath)}`,
|
|
8285
8262
|
`SYNKRO_TIER=${shellQuoteSingle(safeTier)}`,
|
|
8286
8263
|
`SYNKRO_INFERENCE=${shellQuoteSingle(safeInference)}`,
|
|
8287
|
-
`SYNKRO_VERSION=${shellQuoteSingle("1.6.
|
|
8264
|
+
`SYNKRO_VERSION=${shellQuoteSingle("1.6.38")}`
|
|
8288
8265
|
];
|
|
8289
8266
|
if (safeSynkroBin) lines.push(`SYNKRO_CLI_BIN=${shellQuoteSingle(safeSynkroBin)}`);
|
|
8290
8267
|
if (safeUserId) lines.push(`SYNKRO_USER_ID=${shellQuoteSingle(safeUserId)}`);
|
|
@@ -8307,7 +8284,7 @@ function resolveDeploymentMode() {
|
|
|
8307
8284
|
if (envOverride === "bare-host" || envOverride === "docker") return envOverride;
|
|
8308
8285
|
try {
|
|
8309
8286
|
if (existsSync10(CONFIG_PATH2)) {
|
|
8310
|
-
const m =
|
|
8287
|
+
const m = readFileSync8(CONFIG_PATH2, "utf-8").match(/^SYNKRO_DEPLOYMENT_MODE='([^']*)'/m);
|
|
8311
8288
|
const val = m?.[1]?.toLowerCase();
|
|
8312
8289
|
if (val === "bare-host" || val === "docker") return val;
|
|
8313
8290
|
}
|
|
@@ -8336,14 +8313,14 @@ function collectLocalMetadata(includeClaudeCode = true) {
|
|
|
8336
8313
|
}
|
|
8337
8314
|
const claudeDir = join8(homedir8(), ".claude");
|
|
8338
8315
|
try {
|
|
8339
|
-
const settings = JSON.parse(
|
|
8316
|
+
const settings = JSON.parse(readFileSync8(join8(claudeDir, "settings.json"), "utf-8"));
|
|
8340
8317
|
const plugins = Object.keys(settings.enabledPlugins ?? {}).filter((k) => settings.enabledPlugins[k]);
|
|
8341
8318
|
if (plugins.length) meta.enabled_plugins = plugins;
|
|
8342
8319
|
if (settings.permissions?.defaultMode) meta.permissions_mode = settings.permissions.defaultMode;
|
|
8343
8320
|
} catch {
|
|
8344
8321
|
}
|
|
8345
8322
|
try {
|
|
8346
|
-
const mcpCache = JSON.parse(
|
|
8323
|
+
const mcpCache = JSON.parse(readFileSync8(join8(claudeDir, "mcp-needs-auth-cache.json"), "utf-8"));
|
|
8347
8324
|
const mcpNames = Object.keys(mcpCache);
|
|
8348
8325
|
if (mcpNames.length) meta.mcp_servers = mcpNames;
|
|
8349
8326
|
} catch {
|
|
@@ -8358,7 +8335,7 @@ function collectLocalMetadata(includeClaudeCode = true) {
|
|
|
8358
8335
|
const sessionsDir = join8(claudeDir, "sessions");
|
|
8359
8336
|
const files = readdirSync3(sessionsDir).filter((f) => f.endsWith(".json")).slice(-5);
|
|
8360
8337
|
for (const f of files) {
|
|
8361
|
-
const s = JSON.parse(
|
|
8338
|
+
const s = JSON.parse(readFileSync8(join8(sessionsDir, f), "utf-8"));
|
|
8362
8339
|
if (s.version) {
|
|
8363
8340
|
meta.cc_version = meta.cc_version || s.version;
|
|
8364
8341
|
break;
|
|
@@ -8490,7 +8467,7 @@ async function installCommand(opts = {}) {
|
|
|
8490
8467
|
for (const mode of ["edit", "bash"]) {
|
|
8491
8468
|
const pidFile = join8(SYNKRO_DIR4, "daemon", mode, "daemon.pid");
|
|
8492
8469
|
try {
|
|
8493
|
-
const pid = parseInt(
|
|
8470
|
+
const pid = parseInt(readFileSync8(pidFile, "utf-8").trim(), 10);
|
|
8494
8471
|
if (pid > 0) {
|
|
8495
8472
|
process.kill(pid, "SIGTERM");
|
|
8496
8473
|
console.log(`Stopped stale ${mode} grader daemon (pid ${pid})`);
|
|
@@ -8727,7 +8704,7 @@ async function installCommand(opts = {}) {
|
|
|
8727
8704
|
const ready = await waitForContainerReady(6e4);
|
|
8728
8705
|
if (ready) {
|
|
8729
8706
|
console.log(" \u2713 container ready");
|
|
8730
|
-
const mcpJwt =
|
|
8707
|
+
const mcpJwt = readFileSync8(join8(SYNKRO_DIR4, ".mcp-jwt"), "utf-8").trim();
|
|
8731
8708
|
try {
|
|
8732
8709
|
const ingestResp = await fetch(`http://127.0.0.1:${hostMcpPort}/api/ingest`, {
|
|
8733
8710
|
method: "POST",
|
|
@@ -8744,7 +8721,13 @@ async function installCommand(opts = {}) {
|
|
|
8744
8721
|
} catch {
|
|
8745
8722
|
console.warn(" \u26A0 ingest endpoint unreachable \u2014 telemetry spool may not drain.");
|
|
8746
8723
|
}
|
|
8747
|
-
await
|
|
8724
|
+
const workersUp = await waitForWorkersReady(3e4);
|
|
8725
|
+
if (workersUp) {
|
|
8726
|
+
console.log(" \u2713 workers ready");
|
|
8727
|
+
await syncSkillFiles();
|
|
8728
|
+
} else {
|
|
8729
|
+
console.warn(" \u26A0 workers did not register within 30s \u2014 skill sync skipped");
|
|
8730
|
+
}
|
|
8748
8731
|
} else {
|
|
8749
8732
|
console.error(" \u2717 container did not become healthy within 60s");
|
|
8750
8733
|
console.error(" Run `docker logs synkro-server` to debug.");
|
|
@@ -8759,7 +8742,7 @@ async function installCommand(opts = {}) {
|
|
|
8759
8742
|
try {
|
|
8760
8743
|
let mcpToken = "";
|
|
8761
8744
|
try {
|
|
8762
|
-
mcpToken =
|
|
8745
|
+
mcpToken = readFileSync8(join8(SYNKRO_DIR4, ".mcp-jwt"), "utf-8").trim();
|
|
8763
8746
|
} catch {
|
|
8764
8747
|
}
|
|
8765
8748
|
if (mcpToken) {
|
|
@@ -8919,7 +8902,7 @@ function readSynkroFilePool() {
|
|
|
8919
8902
|
if (!root) return "auto";
|
|
8920
8903
|
const fp = join8(root, ".synkro");
|
|
8921
8904
|
if (!existsSync10(fp)) return "auto";
|
|
8922
|
-
const parsed = parseSynkroFileRaw(
|
|
8905
|
+
const parsed = parseSynkroFileRaw(readFileSync8(fp, "utf-8"));
|
|
8923
8906
|
const pool = parsed?.grader?.pool;
|
|
8924
8907
|
if (pool === "cursor" || pool === "claude") return pool;
|
|
8925
8908
|
} catch {
|
|
@@ -8932,7 +8915,7 @@ function readFullSynkroFile() {
|
|
|
8932
8915
|
if (!root) return null;
|
|
8933
8916
|
const fp = join8(root, ".synkro");
|
|
8934
8917
|
if (!existsSync10(fp)) return null;
|
|
8935
|
-
const parsed = parseSynkroFileRaw(
|
|
8918
|
+
const parsed = parseSynkroFileRaw(readFileSync8(fp, "utf-8"));
|
|
8936
8919
|
const valid = ["claude-code", "cursor"];
|
|
8937
8920
|
const harness = Array.isArray(parsed.harness) ? parsed.harness.filter((h) => valid.includes(h)) : ["claude-code", "cursor"];
|
|
8938
8921
|
return {
|
|
@@ -8983,7 +8966,7 @@ function reconcileHarness() {
|
|
|
8983
8966
|
});
|
|
8984
8967
|
console.log(" \u2713 Claude Code hooks registered");
|
|
8985
8968
|
try {
|
|
8986
|
-
const mcpJwt =
|
|
8969
|
+
const mcpJwt = readFileSync8(join8(SYNKRO_DIR4, ".mcp-jwt"), "utf-8").trim();
|
|
8987
8970
|
if (mcpJwt) {
|
|
8988
8971
|
installMcpConfig({ gatewayUrl: "", bearerToken: mcpJwt, local: true });
|
|
8989
8972
|
console.log(" \u2713 Claude Code MCP registered");
|
|
@@ -9047,23 +9030,28 @@ async function syncSkillFiles() {
|
|
|
9047
9030
|
if (resolved.length === 0) return;
|
|
9048
9031
|
const mcpPort = process.env.SYNKRO_MCP_PORT || "18931";
|
|
9049
9032
|
for (const fp of resolved) {
|
|
9050
|
-
const
|
|
9051
|
-
if (!
|
|
9033
|
+
const content = readFileSync8(fp, "utf-8");
|
|
9034
|
+
if (!content.trim()) continue;
|
|
9035
|
+
const source = `skill:${fp.split("/").pop()}`;
|
|
9052
9036
|
try {
|
|
9053
9037
|
const resp = await fetch(`http://127.0.0.1:${mcpPort}/api/local/skills/sync`, {
|
|
9054
9038
|
method: "POST",
|
|
9055
9039
|
headers: { "Content-Type": "application/json" },
|
|
9056
|
-
body: JSON.stringify(
|
|
9057
|
-
signal: AbortSignal.timeout(
|
|
9040
|
+
body: JSON.stringify({ source, content }),
|
|
9041
|
+
signal: AbortSignal.timeout(65e3)
|
|
9058
9042
|
});
|
|
9059
9043
|
if (resp.ok) {
|
|
9060
9044
|
const result = await resp.json();
|
|
9061
|
-
|
|
9045
|
+
if (result.created > 0) {
|
|
9046
|
+
console.log(` \u2713 skill ${source}: ${result.created} new rules added`);
|
|
9047
|
+
} else {
|
|
9048
|
+
console.log(` \u2713 skill ${source}: ${result.message || "up to date"}`);
|
|
9049
|
+
}
|
|
9062
9050
|
} else {
|
|
9063
|
-
console.warn(` \u26A0 skill ${
|
|
9051
|
+
console.warn(` \u26A0 skill ${source}: sync failed (${resp.status})`);
|
|
9064
9052
|
}
|
|
9065
9053
|
} catch (e) {
|
|
9066
|
-
console.warn(` \u26A0 skill ${
|
|
9054
|
+
console.warn(` \u26A0 skill ${source}: ${e.message}`);
|
|
9067
9055
|
}
|
|
9068
9056
|
}
|
|
9069
9057
|
}
|
|
@@ -9095,7 +9083,7 @@ function extractSessionInsights(projectsDir) {
|
|
|
9095
9083
|
const sessionId = file.replace(".jsonl", "");
|
|
9096
9084
|
const filePath = join8(projectsDir, file);
|
|
9097
9085
|
try {
|
|
9098
|
-
const content =
|
|
9086
|
+
const content = readFileSync8(filePath, "utf-8");
|
|
9099
9087
|
const lines = content.split("\n").filter(Boolean);
|
|
9100
9088
|
for (let i = 0; i < lines.length; i++) {
|
|
9101
9089
|
try {
|
|
@@ -9171,7 +9159,7 @@ function extractTextContent(content) {
|
|
|
9171
9159
|
return "";
|
|
9172
9160
|
}
|
|
9173
9161
|
function parseTranscriptFile(filePath) {
|
|
9174
|
-
const content =
|
|
9162
|
+
const content = readFileSync8(filePath, "utf-8");
|
|
9175
9163
|
const lines = content.split("\n").filter(Boolean);
|
|
9176
9164
|
const messages = [];
|
|
9177
9165
|
for (let i = 0; i < lines.length; i++) {
|
|
@@ -9241,7 +9229,7 @@ async function syncTranscriptsLocal(mcpPort, mcpToken, repo) {
|
|
|
9241
9229
|
process.stdout.write(`\r Progress: ${i + 1}/${files.length} sessions (${totalMessages} messages embedded) `);
|
|
9242
9230
|
}
|
|
9243
9231
|
try {
|
|
9244
|
-
const content =
|
|
9232
|
+
const content = readFileSync8(join8(projectsDir, file), "utf-8");
|
|
9245
9233
|
const lineCount = content.split("\n").filter(Boolean).length;
|
|
9246
9234
|
writeFileSync7(join8(OFFSETS_DIR, sessionId), String(lineCount), "utf-8");
|
|
9247
9235
|
} catch {
|
|
@@ -9295,7 +9283,7 @@ async function syncTranscriptsBulk(gatewayUrl, token, repo) {
|
|
|
9295
9283
|
const sessionId = file.replace(".jsonl", "");
|
|
9296
9284
|
const filePath = join8(projectsDir, file);
|
|
9297
9285
|
try {
|
|
9298
|
-
const content =
|
|
9286
|
+
const content = readFileSync8(filePath, "utf-8");
|
|
9299
9287
|
const lineCount = content.split("\n").filter(Boolean).length;
|
|
9300
9288
|
writeFileSync7(join8(OFFSETS_DIR, sessionId), String(lineCount), "utf-8");
|
|
9301
9289
|
} catch {
|
|
@@ -9375,7 +9363,7 @@ rl.on('line', async (line) => {
|
|
|
9375
9363
|
});
|
|
9376
9364
|
|
|
9377
9365
|
// cli/local-cc/install.ts
|
|
9378
|
-
import { existsSync as existsSync11, mkdirSync as mkdirSync9, writeFileSync as writeFileSync8, readFileSync as
|
|
9366
|
+
import { existsSync as existsSync11, mkdirSync as mkdirSync9, writeFileSync as writeFileSync8, readFileSync as readFileSync9, chmodSync as chmodSync3, copyFileSync as copyFileSync2, renameSync as renameSync4, unlinkSync as unlinkSync4, openSync, fsyncSync, closeSync } from "fs";
|
|
9379
9367
|
import { join as join9 } from "path";
|
|
9380
9368
|
import { homedir as homedir9 } from "os";
|
|
9381
9369
|
import { spawnSync as spawnSync4 } from "child_process";
|
|
@@ -9414,7 +9402,7 @@ function safelyMutateClaudeJson(mutator) {
|
|
|
9414
9402
|
if (!existsSync11(CLAUDE_JSON_PATH)) {
|
|
9415
9403
|
return;
|
|
9416
9404
|
}
|
|
9417
|
-
const originalText =
|
|
9405
|
+
const originalText = readFileSync9(CLAUDE_JSON_PATH, "utf-8");
|
|
9418
9406
|
let parsed;
|
|
9419
9407
|
try {
|
|
9420
9408
|
parsed = JSON.parse(originalText);
|
|
@@ -9984,7 +9972,7 @@ var init_disconnect = __esm({
|
|
|
9984
9972
|
});
|
|
9985
9973
|
|
|
9986
9974
|
// cli/local-cc/turnLog.ts
|
|
9987
|
-
import { appendFileSync, existsSync as existsSync13, mkdirSync as mkdirSync10, openSync as openSync2, readFileSync as
|
|
9975
|
+
import { appendFileSync, existsSync as existsSync13, mkdirSync as mkdirSync10, openSync as openSync2, readFileSync as readFileSync10, readSync, closeSync as closeSync2, statSync as statSync2, watchFile, unwatchFile } from "fs";
|
|
9988
9976
|
import { dirname as dirname6, join as join11 } from "path";
|
|
9989
9977
|
import { homedir as homedir11 } from "os";
|
|
9990
9978
|
function truncate(s, max = PREVIEW_MAX) {
|
|
@@ -10026,7 +10014,7 @@ function readRecentTurns(n = 20) {
|
|
|
10026
10014
|
try {
|
|
10027
10015
|
const size = statSync2(TURN_LOG_PATH).size;
|
|
10028
10016
|
if (size === 0) return [];
|
|
10029
|
-
const text =
|
|
10017
|
+
const text = readFileSync10(TURN_LOG_PATH, "utf-8");
|
|
10030
10018
|
const lines = text.split("\n").filter(Boolean);
|
|
10031
10019
|
const lastN = lines.slice(-n).reverse();
|
|
10032
10020
|
return lastN.map((line) => {
|
|
@@ -10472,13 +10460,13 @@ var init_pueue = __esm({
|
|
|
10472
10460
|
});
|
|
10473
10461
|
|
|
10474
10462
|
// cli/local-cc/settings.ts
|
|
10475
|
-
import { existsSync as existsSync14, readFileSync as
|
|
10463
|
+
import { existsSync as existsSync14, readFileSync as readFileSync11 } from "fs";
|
|
10476
10464
|
import { homedir as homedir13 } from "os";
|
|
10477
10465
|
import { join as join13 } from "path";
|
|
10478
10466
|
function isLocalCCEnabled() {
|
|
10479
10467
|
if (!existsSync14(CONFIG_PATH3)) return false;
|
|
10480
10468
|
try {
|
|
10481
|
-
const content =
|
|
10469
|
+
const content = readFileSync11(CONFIG_PATH3, "utf-8");
|
|
10482
10470
|
const match = content.match(/^SYNKRO_LOCAL_INFERENCE='([^']*)'/m);
|
|
10483
10471
|
return match?.[1] === "yes";
|
|
10484
10472
|
} catch {
|
|
@@ -10502,7 +10490,7 @@ import { spawnSync as spawnSync7 } from "child_process";
|
|
|
10502
10490
|
import { homedir as homedir14 } from "os";
|
|
10503
10491
|
import { join as join14 } from "path";
|
|
10504
10492
|
import { readFileSync as fsReadFileSync, existsSync as fsExistsSync } from "fs";
|
|
10505
|
-
import { existsSync as existsSync15, readFileSync as
|
|
10493
|
+
import { existsSync as existsSync15, readFileSync as readFileSync12, writeFileSync as writeFileSync9 } from "fs";
|
|
10506
10494
|
function deploymentMode() {
|
|
10507
10495
|
const env = (process.env.SYNKRO_DEPLOYMENT_MODE || "").toLowerCase();
|
|
10508
10496
|
if (env === "docker") return "docker";
|
|
@@ -10609,14 +10597,14 @@ TROUBLESHOOTING
|
|
|
10609
10597
|
}
|
|
10610
10598
|
function readGatewayUrl() {
|
|
10611
10599
|
if (existsSync15(CONFIG_PATH4)) {
|
|
10612
|
-
const m =
|
|
10600
|
+
const m = readFileSync12(CONFIG_PATH4, "utf-8").match(/^SYNKRO_GATEWAY_URL='([^']*)'/m);
|
|
10613
10601
|
if (m) return m[1];
|
|
10614
10602
|
}
|
|
10615
10603
|
return "https://api.synkro.sh";
|
|
10616
10604
|
}
|
|
10617
10605
|
function updateLocalInferenceFlag(enabled) {
|
|
10618
10606
|
if (!existsSync15(CONFIG_PATH4)) return;
|
|
10619
|
-
let content =
|
|
10607
|
+
let content = readFileSync12(CONFIG_PATH4, "utf-8");
|
|
10620
10608
|
const flag = enabled ? "yes" : "no";
|
|
10621
10609
|
if (content.includes("SYNKRO_LOCAL_INFERENCE=")) {
|
|
10622
10610
|
content = content.replace(/^SYNKRO_LOCAL_INFERENCE='[^']*'/m, `SYNKRO_LOCAL_INFERENCE='${flag}'`);
|
|
@@ -10808,7 +10796,11 @@ async function cmdRestart(rest = []) {
|
|
|
10808
10796
|
await dockerUpdate({ claudeWorkers, cursorWorkers });
|
|
10809
10797
|
const ready = await waitForContainerReady(6e4);
|
|
10810
10798
|
console.log(ready ? "\u2713 container ready" : "\u26A0 container did not pass /healthz within 60s");
|
|
10811
|
-
if (ready)
|
|
10799
|
+
if (ready) {
|
|
10800
|
+
const workersUp = await waitForWorkersReady(3e4);
|
|
10801
|
+
console.log(workersUp ? "\u2713 workers ready" : "\u26A0 workers did not register within 30s");
|
|
10802
|
+
if (workersUp) await syncSkillFiles();
|
|
10803
|
+
}
|
|
10812
10804
|
return;
|
|
10813
10805
|
}
|
|
10814
10806
|
stopTask(CHANNEL_PRIMARY);
|
|
@@ -11159,13 +11151,13 @@ var config_exports = {};
|
|
|
11159
11151
|
__export(config_exports, {
|
|
11160
11152
|
configCommand: () => configCommand
|
|
11161
11153
|
});
|
|
11162
|
-
import { readFileSync as
|
|
11154
|
+
import { readFileSync as readFileSync13, writeFileSync as writeFileSync10, existsSync as existsSync16 } from "fs";
|
|
11163
11155
|
import { join as join15 } from "path";
|
|
11164
11156
|
import { homedir as homedir15 } from "os";
|
|
11165
11157
|
function readConfigEnv() {
|
|
11166
11158
|
if (!existsSync16(CONFIG_PATH5)) return {};
|
|
11167
11159
|
const out = {};
|
|
11168
|
-
for (const line of
|
|
11160
|
+
for (const line of readFileSync13(CONFIG_PATH5, "utf-8").split("\n")) {
|
|
11169
11161
|
const t = line.trim();
|
|
11170
11162
|
if (!t || t.startsWith("#")) continue;
|
|
11171
11163
|
const eq = t.indexOf("=");
|
|
@@ -11178,7 +11170,7 @@ function updateConfigValue(key, value) {
|
|
|
11178
11170
|
console.error("No config found. Run `synkro install` first.");
|
|
11179
11171
|
process.exit(1);
|
|
11180
11172
|
}
|
|
11181
|
-
const lines =
|
|
11173
|
+
const lines = readFileSync13(CONFIG_PATH5, "utf-8").split("\n");
|
|
11182
11174
|
const pattern = new RegExp(`^${key}=`);
|
|
11183
11175
|
let found = false;
|
|
11184
11176
|
const updated = lines.map((line) => {
|
|
@@ -11305,14 +11297,14 @@ var init_config = __esm({
|
|
|
11305
11297
|
});
|
|
11306
11298
|
|
|
11307
11299
|
// cli/bootstrap.js
|
|
11308
|
-
import { readFileSync as
|
|
11300
|
+
import { readFileSync as readFileSync14, existsSync as existsSync17 } from "fs";
|
|
11309
11301
|
import { resolve as resolve3 } from "path";
|
|
11310
11302
|
var envCandidates = [
|
|
11311
11303
|
resolve3(process.env.HOME ?? "", ".synkro", "config.env")
|
|
11312
11304
|
];
|
|
11313
11305
|
for (const envPath of envCandidates) {
|
|
11314
11306
|
if (!existsSync17(envPath)) continue;
|
|
11315
|
-
const envContent =
|
|
11307
|
+
const envContent = readFileSync14(envPath, "utf-8");
|
|
11316
11308
|
for (const line of envContent.split("\n")) {
|
|
11317
11309
|
const trimmed = line.trim();
|
|
11318
11310
|
if (!trimmed || trimmed.startsWith("#")) continue;
|
|
@@ -11327,7 +11319,7 @@ var args = process.argv.slice(2);
|
|
|
11327
11319
|
var cmd = args[0] || "";
|
|
11328
11320
|
var subArgs = args.slice(1);
|
|
11329
11321
|
function printVersion() {
|
|
11330
|
-
console.log("1.6.
|
|
11322
|
+
console.log("1.6.38");
|
|
11331
11323
|
}
|
|
11332
11324
|
function printHelp2() {
|
|
11333
11325
|
console.log(`Synkro CLI \u2014 runtime safety for AI coding agents
|