@synkro-sh/cli 1.3.17 → 1.3.19
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 +238 -64
- package/dist/bootstrap.js.map +1 -1
- package/package.json +1 -1
package/dist/bootstrap.js
CHANGED
|
@@ -102,7 +102,7 @@ function removeSynkroEntries(events, eventName) {
|
|
|
102
102
|
if (!Array.isArray(arr)) return;
|
|
103
103
|
events[eventName] = arr.filter((entry) => !isSynkroEntry(entry));
|
|
104
104
|
}
|
|
105
|
-
function installCCHooks(settingsPath,
|
|
105
|
+
function installCCHooks(settingsPath, config) {
|
|
106
106
|
const settings = readSettings(settingsPath);
|
|
107
107
|
settings.hooks = settings.hooks ?? {};
|
|
108
108
|
removeSynkroEntries(settings.hooks, "PreToolUse");
|
|
@@ -119,7 +119,7 @@ function installCCHooks(settingsPath, config2) {
|
|
|
119
119
|
hooks: [
|
|
120
120
|
{
|
|
121
121
|
type: "command",
|
|
122
|
-
command:
|
|
122
|
+
command: config.bashJudgeScriptPath,
|
|
123
123
|
timeout: 15
|
|
124
124
|
}
|
|
125
125
|
],
|
|
@@ -130,7 +130,7 @@ function installCCHooks(settingsPath, config2) {
|
|
|
130
130
|
hooks: [
|
|
131
131
|
{
|
|
132
132
|
type: "command",
|
|
133
|
-
command:
|
|
133
|
+
command: config.editPrecheckScriptPath,
|
|
134
134
|
timeout: 15
|
|
135
135
|
}
|
|
136
136
|
],
|
|
@@ -141,7 +141,7 @@ function installCCHooks(settingsPath, config2) {
|
|
|
141
141
|
hooks: [
|
|
142
142
|
{
|
|
143
143
|
type: "command",
|
|
144
|
-
command:
|
|
144
|
+
command: config.editCaptureScriptPath,
|
|
145
145
|
timeout: 20
|
|
146
146
|
}
|
|
147
147
|
],
|
|
@@ -152,7 +152,7 @@ function installCCHooks(settingsPath, config2) {
|
|
|
152
152
|
hooks: [
|
|
153
153
|
{
|
|
154
154
|
type: "command",
|
|
155
|
-
command:
|
|
155
|
+
command: config.bashFollowupScriptPath
|
|
156
156
|
}
|
|
157
157
|
],
|
|
158
158
|
[SYNKRO_MARKER]: true
|
|
@@ -161,7 +161,7 @@ function installCCHooks(settingsPath, config2) {
|
|
|
161
161
|
hooks: [
|
|
162
162
|
{
|
|
163
163
|
type: "command",
|
|
164
|
-
command:
|
|
164
|
+
command: config.stopSummaryScriptPath
|
|
165
165
|
}
|
|
166
166
|
],
|
|
167
167
|
[SYNKRO_MARKER]: true
|
|
@@ -170,19 +170,19 @@ function installCCHooks(settingsPath, config2) {
|
|
|
170
170
|
hooks: [
|
|
171
171
|
{
|
|
172
172
|
type: "command",
|
|
173
|
-
command:
|
|
173
|
+
command: config.sessionStartScriptPath
|
|
174
174
|
}
|
|
175
175
|
],
|
|
176
176
|
[SYNKRO_MARKER]: true
|
|
177
177
|
});
|
|
178
|
-
if (!
|
|
178
|
+
if (!config.skipTranscriptSync) {
|
|
179
179
|
settings.hooks.Stop = settings.hooks.Stop ?? [];
|
|
180
180
|
removeSynkroEntries(settings.hooks, "Stop");
|
|
181
181
|
settings.hooks.Stop.push({
|
|
182
182
|
hooks: [
|
|
183
183
|
{
|
|
184
184
|
type: "command",
|
|
185
|
-
command:
|
|
185
|
+
command: config.transcriptSyncScriptPath,
|
|
186
186
|
timeout: 3
|
|
187
187
|
}
|
|
188
188
|
],
|
|
@@ -252,50 +252,50 @@ function readClaudeJson() {
|
|
|
252
252
|
throw new Error(`Failed to parse ${CC_CONFIG_PATH}: ${err.message}`);
|
|
253
253
|
}
|
|
254
254
|
}
|
|
255
|
-
function writeClaudeJsonAtomic(
|
|
255
|
+
function writeClaudeJsonAtomic(config) {
|
|
256
256
|
mkdirSync2(dirname2(CC_CONFIG_PATH), { recursive: true });
|
|
257
257
|
const tmpPath = `${CC_CONFIG_PATH}.synkro.tmp`;
|
|
258
|
-
writeFileSync2(tmpPath, JSON.stringify(
|
|
258
|
+
writeFileSync2(tmpPath, JSON.stringify(config, null, 2) + "\n", "utf-8");
|
|
259
259
|
renameSync2(tmpPath, CC_CONFIG_PATH);
|
|
260
260
|
}
|
|
261
261
|
function installMcpConfig(opts) {
|
|
262
|
-
const
|
|
263
|
-
|
|
264
|
-
for (const [name, entry] of Object.entries(
|
|
265
|
-
if (entry?.[SYNKRO_MARKER2] === true) delete
|
|
262
|
+
const config = readClaudeJson();
|
|
263
|
+
config.mcpServers = config.mcpServers ?? {};
|
|
264
|
+
for (const [name, entry] of Object.entries(config.mcpServers)) {
|
|
265
|
+
if (entry?.[SYNKRO_MARKER2] === true) delete config.mcpServers[name];
|
|
266
266
|
}
|
|
267
267
|
const url = `${opts.gatewayUrl.replace(/\/$/, "")}/api/v1/mcp/guardrails`;
|
|
268
|
-
|
|
268
|
+
config.mcpServers[SYNKRO_SERVER_NAME] = {
|
|
269
269
|
type: "http",
|
|
270
270
|
url,
|
|
271
271
|
headers: { Authorization: `Bearer ${opts.bearerToken}` },
|
|
272
272
|
[SYNKRO_MARKER2]: true
|
|
273
273
|
};
|
|
274
|
-
writeClaudeJsonAtomic(
|
|
274
|
+
writeClaudeJsonAtomic(config);
|
|
275
275
|
return { path: CC_CONFIG_PATH, url };
|
|
276
276
|
}
|
|
277
277
|
function uninstallMcpConfig() {
|
|
278
278
|
if (!existsSync3(CC_CONFIG_PATH)) return false;
|
|
279
|
-
const
|
|
280
|
-
if (!
|
|
279
|
+
const config = readClaudeJson();
|
|
280
|
+
if (!config.mcpServers || Object.keys(config.mcpServers).length === 0) return false;
|
|
281
281
|
let removed = false;
|
|
282
|
-
for (const [name, entry] of Object.entries(
|
|
282
|
+
for (const [name, entry] of Object.entries(config.mcpServers)) {
|
|
283
283
|
if (entry?.[SYNKRO_MARKER2] === true) {
|
|
284
|
-
delete
|
|
284
|
+
delete config.mcpServers[name];
|
|
285
285
|
removed = true;
|
|
286
286
|
}
|
|
287
287
|
}
|
|
288
288
|
if (!removed) return false;
|
|
289
|
-
if (Object.keys(
|
|
290
|
-
writeClaudeJsonAtomic(
|
|
289
|
+
if (Object.keys(config.mcpServers).length === 0) delete config.mcpServers;
|
|
290
|
+
writeClaudeJsonAtomic(config);
|
|
291
291
|
return true;
|
|
292
292
|
}
|
|
293
293
|
function inspectMcpConfig() {
|
|
294
294
|
if (!existsSync3(CC_CONFIG_PATH)) {
|
|
295
295
|
return { installed: false, configPath: CC_CONFIG_PATH };
|
|
296
296
|
}
|
|
297
|
-
const
|
|
298
|
-
const entry =
|
|
297
|
+
const config = readClaudeJson();
|
|
298
|
+
const entry = config.mcpServers?.[SYNKRO_SERVER_NAME];
|
|
299
299
|
if (!entry || entry[SYNKRO_MARKER2] !== true) {
|
|
300
300
|
return { installed: false, configPath: CC_CONFIG_PATH };
|
|
301
301
|
}
|
|
@@ -2440,10 +2440,12 @@ var init_auth = __esm({
|
|
|
2440
2440
|
});
|
|
2441
2441
|
|
|
2442
2442
|
// cli/api/projects.ts
|
|
2443
|
-
|
|
2443
|
+
function setApiBaseUrl(url) {
|
|
2444
|
+
API_URL = url;
|
|
2445
|
+
}
|
|
2444
2446
|
async function callApi(method, endpoint, body) {
|
|
2445
2447
|
if (!API_URL) {
|
|
2446
|
-
throw new Error("
|
|
2448
|
+
throw new Error("API URL not configured. Run `synkro install` first.");
|
|
2447
2449
|
}
|
|
2448
2450
|
const url = `${API_URL}${endpoint}`;
|
|
2449
2451
|
const accessToken = getAccessToken();
|
|
@@ -2480,8 +2482,7 @@ var init_projects = __esm({
|
|
|
2480
2482
|
"cli/api/projects.ts"() {
|
|
2481
2483
|
"use strict";
|
|
2482
2484
|
init_auth();
|
|
2483
|
-
|
|
2484
|
-
API_URL = process.env.SYNKRO_CRUD_URL || process.env.SYNKRO_API_URL;
|
|
2485
|
+
API_URL = "https://api.synkro.sh/api";
|
|
2485
2486
|
}
|
|
2486
2487
|
});
|
|
2487
2488
|
|
|
@@ -2935,8 +2936,8 @@ async function setupGithubCommand(opts = {}) {
|
|
|
2935
2936
|
console.error("Not authenticated. Run `synkro-cli login` first.");
|
|
2936
2937
|
process.exit(1);
|
|
2937
2938
|
}
|
|
2938
|
-
const
|
|
2939
|
-
const gatewayUrl = (
|
|
2939
|
+
const config = readConfig();
|
|
2940
|
+
const gatewayUrl = (config.SYNKRO_GATEWAY_URL || process.env.SYNKRO_GATEWAY_URL || "https://api.synkro.sh").replace(/\/$/, "");
|
|
2940
2941
|
const jwt2 = getAccessToken();
|
|
2941
2942
|
if (!jwt2) {
|
|
2942
2943
|
console.error("Could not load access token from ~/.synkro/credentials.json. Run `synkro-cli login`.");
|
|
@@ -3223,6 +3224,7 @@ function writeConfigEnv(opts) {
|
|
|
3223
3224
|
const safeOrgId = sanitizeConfigValue(opts.orgId);
|
|
3224
3225
|
const safeEmail = sanitizeConfigValue(opts.email);
|
|
3225
3226
|
const safeTier = sanitizeConfigValue(opts.tier ?? "pro", 32);
|
|
3227
|
+
const safeInference = sanitizeConfigValue(opts.inference ?? "fast", 16);
|
|
3226
3228
|
const lines = [
|
|
3227
3229
|
"# Synkro CLI config (managed by synkro install)",
|
|
3228
3230
|
"# JWT auth \u2014 the hook scripts read SYNKRO_CREDENTIALS_PATH at runtime",
|
|
@@ -3230,7 +3232,8 @@ function writeConfigEnv(opts) {
|
|
|
3230
3232
|
`SYNKRO_GATEWAY_URL=${shellQuoteSingle(safeGateway)}`,
|
|
3231
3233
|
`SYNKRO_CREDENTIALS_PATH=${shellQuoteSingle(credsPath)}`,
|
|
3232
3234
|
`SYNKRO_TIER=${shellQuoteSingle(safeTier)}`,
|
|
3233
|
-
`
|
|
3235
|
+
`SYNKRO_INFERENCE=${shellQuoteSingle(safeInference)}`,
|
|
3236
|
+
`SYNKRO_VERSION=${shellQuoteSingle("1.3.19")}`
|
|
3234
3237
|
];
|
|
3235
3238
|
if (safeUserId) lines.push(`SYNKRO_USER_ID=${shellQuoteSingle(safeUserId)}`);
|
|
3236
3239
|
if (safeOrgId) lines.push(`SYNKRO_ORG_ID=${shellQuoteSingle(safeOrgId)}`);
|
|
@@ -3242,6 +3245,42 @@ function writeConfigEnv(opts) {
|
|
|
3242
3245
|
writeFileSync5(CONFIG_PATH2, lines.join("\n"), "utf-8");
|
|
3243
3246
|
chmodSync(CONFIG_PATH2, 384);
|
|
3244
3247
|
}
|
|
3248
|
+
function collectLocalMetadata() {
|
|
3249
|
+
const meta = { platform: process.platform };
|
|
3250
|
+
try {
|
|
3251
|
+
meta.display_name = execSync4("git config user.name", { encoding: "utf-8", timeout: 3e3 }).trim();
|
|
3252
|
+
} catch {
|
|
3253
|
+
}
|
|
3254
|
+
try {
|
|
3255
|
+
const remote = execSync4("git remote get-url origin", { encoding: "utf-8", timeout: 3e3 }).trim();
|
|
3256
|
+
const m = remote.match(/(?:github\.com)[:/](.+?)(?:\.git)?$/);
|
|
3257
|
+
if (m) meta.active_repo = m[1];
|
|
3258
|
+
} catch {
|
|
3259
|
+
}
|
|
3260
|
+
return meta;
|
|
3261
|
+
}
|
|
3262
|
+
async function fetchUserProfile(gatewayUrl, token) {
|
|
3263
|
+
try {
|
|
3264
|
+
const resp = await fetch(`${gatewayUrl}/api/v1/cli/me`, {
|
|
3265
|
+
headers: { "Authorization": `Bearer ${token}` }
|
|
3266
|
+
});
|
|
3267
|
+
if (!resp.ok) return { tier: "pro", inference: "fast" };
|
|
3268
|
+
const data = await resp.json();
|
|
3269
|
+
const meta = collectLocalMetadata();
|
|
3270
|
+
fetch(`${gatewayUrl}/api/v1/cli/me`, {
|
|
3271
|
+
method: "PATCH",
|
|
3272
|
+
headers: { "Authorization": `Bearer ${token}`, "Content-Type": "application/json" },
|
|
3273
|
+
body: JSON.stringify(meta)
|
|
3274
|
+
}).catch(() => {
|
|
3275
|
+
});
|
|
3276
|
+
return {
|
|
3277
|
+
tier: data.plan_tier ?? "pro",
|
|
3278
|
+
inference: data.fast_inference ? "fast" : "standard"
|
|
3279
|
+
};
|
|
3280
|
+
} catch {
|
|
3281
|
+
return { tier: "pro", inference: "fast" };
|
|
3282
|
+
}
|
|
3283
|
+
}
|
|
3245
3284
|
function assertGatewayAllowed(gatewayUrl) {
|
|
3246
3285
|
let parsed;
|
|
3247
3286
|
try {
|
|
@@ -3299,6 +3338,24 @@ async function installCommand(opts = {}) {
|
|
|
3299
3338
|
process.exit(1);
|
|
3300
3339
|
}
|
|
3301
3340
|
if (!opts.force && isAuthenticated() && isAlreadyInstalled()) {
|
|
3341
|
+
setApiBaseUrl(`${gatewayUrl}/api`);
|
|
3342
|
+
await ensureValidToken();
|
|
3343
|
+
const currentRepo = detectGitRepo2();
|
|
3344
|
+
if (currentRepo) {
|
|
3345
|
+
try {
|
|
3346
|
+
const projects = await listProjects();
|
|
3347
|
+
const alreadyLinked = projects.some(
|
|
3348
|
+
(p) => p.repos?.some((r) => r.full_name === currentRepo)
|
|
3349
|
+
);
|
|
3350
|
+
if (!alreadyLinked) {
|
|
3351
|
+
console.log(`Synkro is installed. This repo (${currentRepo}) is not linked yet.
|
|
3352
|
+
`);
|
|
3353
|
+
await promptRepoConnection();
|
|
3354
|
+
return;
|
|
3355
|
+
}
|
|
3356
|
+
} catch {
|
|
3357
|
+
}
|
|
3358
|
+
}
|
|
3302
3359
|
console.log("\u2713 Synkro is already installed and configured.");
|
|
3303
3360
|
console.log(" Run `synkro-cli update` to refresh hook scripts and judge prompts.");
|
|
3304
3361
|
console.log(" Run `synkro-cli install --force` to reinstall from scratch.");
|
|
@@ -3336,6 +3393,7 @@ async function installCommand(opts = {}) {
|
|
|
3336
3393
|
console.error("No access token available after auth.");
|
|
3337
3394
|
process.exit(1);
|
|
3338
3395
|
}
|
|
3396
|
+
setApiBaseUrl(`${gatewayUrl}/api`);
|
|
3339
3397
|
await promptRepoConnection({ linkRepo: opts.linkRepo });
|
|
3340
3398
|
const agents = detectAgents();
|
|
3341
3399
|
if (agents.length === 0) {
|
|
@@ -3439,8 +3497,10 @@ async function installCommand(opts = {}) {
|
|
|
3439
3497
|
email = info.email;
|
|
3440
3498
|
} catch {
|
|
3441
3499
|
}
|
|
3442
|
-
|
|
3443
|
-
|
|
3500
|
+
const profile = await fetchUserProfile(gatewayUrl, token);
|
|
3501
|
+
writeConfigEnv({ gatewayUrl, userId, orgId, email, tier: profile.tier, inference: profile.inference, transcriptConsent });
|
|
3502
|
+
console.log(`Wrote config to ${CONFIG_PATH2}`);
|
|
3503
|
+
console.log(` inference: ${profile.inference} (server-side grading)
|
|
3444
3504
|
`);
|
|
3445
3505
|
if (transcriptConsent) {
|
|
3446
3506
|
try {
|
|
@@ -3683,6 +3743,7 @@ var init_install = __esm({
|
|
|
3683
3743
|
init_graderDaemon();
|
|
3684
3744
|
init_stub();
|
|
3685
3745
|
init_repoConnect();
|
|
3746
|
+
init_projects();
|
|
3686
3747
|
SYNKRO_DIR2 = join6(homedir5(), ".synkro");
|
|
3687
3748
|
HOOKS_DIR = join6(SYNKRO_DIR2, "hooks");
|
|
3688
3749
|
BIN_DIR = join6(SYNKRO_DIR2, "bin");
|
|
@@ -3785,7 +3846,7 @@ function readConfigEnv() {
|
|
|
3785
3846
|
}
|
|
3786
3847
|
return out;
|
|
3787
3848
|
}
|
|
3788
|
-
function statusCommand() {
|
|
3849
|
+
async function statusCommand() {
|
|
3789
3850
|
console.log("Synkro CLI status\n");
|
|
3790
3851
|
if (isAuthenticated()) {
|
|
3791
3852
|
const info = getUserInfo();
|
|
@@ -3796,21 +3857,32 @@ function statusCommand() {
|
|
|
3796
3857
|
console.log("Authentication: \u2717 not logged in (run: synkro-cli login)");
|
|
3797
3858
|
}
|
|
3798
3859
|
console.log();
|
|
3799
|
-
const
|
|
3860
|
+
const config = readConfigEnv();
|
|
3861
|
+
const gatewayUrl = (config.SYNKRO_GATEWAY_URL || "https://api.synkro.sh").replace(/^['"]|['"]$/g, "");
|
|
3862
|
+
let serverTier = config.SYNKRO_TIER || "(unset)";
|
|
3863
|
+
let serverInference = config.SYNKRO_INFERENCE || "fast";
|
|
3864
|
+
const token = getAccessToken();
|
|
3865
|
+
if (token) {
|
|
3866
|
+
try {
|
|
3867
|
+
const resp = await fetch(`${gatewayUrl}/api/v1/cli/me`, {
|
|
3868
|
+
headers: { "Authorization": `Bearer ${token}` },
|
|
3869
|
+
signal: AbortSignal.timeout(5e3)
|
|
3870
|
+
});
|
|
3871
|
+
if (resp.ok) {
|
|
3872
|
+
const data = await resp.json();
|
|
3873
|
+
serverInference = data.fast_inference ? "fast" : "standard";
|
|
3874
|
+
serverTier = data.plan_tier ?? data.tier ?? serverTier;
|
|
3875
|
+
}
|
|
3876
|
+
} catch {
|
|
3877
|
+
}
|
|
3878
|
+
}
|
|
3800
3879
|
console.log("Config:");
|
|
3801
|
-
console.log(` gateway: ${
|
|
3802
|
-
console.log(` credentials: ${
|
|
3803
|
-
console.log(` tier: ${
|
|
3804
|
-
const
|
|
3805
|
-
|
|
3806
|
-
|
|
3807
|
-
let inferenceTier = config2.SYNKRO_INFERENCE_TIER || null;
|
|
3808
|
-
if (!inferenceTier && existsSync8(tierCacheFile)) {
|
|
3809
|
-
inferenceTier = readFileSync6(tierCacheFile, "utf-8").trim() || null;
|
|
3810
|
-
}
|
|
3811
|
-
const tierLabel = inferenceTier === "fast" ? "'fast' (server-side grading)" : inferenceTier === "free" ? "'free' (local daemon grading)" : "(unknown \u2014 fires on next hook)";
|
|
3812
|
-
console.log(` inference: ${tierLabel}`);
|
|
3813
|
-
console.log(` version: ${config2.SYNKRO_VERSION ?? "(unset)"}`);
|
|
3880
|
+
console.log(` gateway: ${gatewayUrl}`);
|
|
3881
|
+
console.log(` credentials: ${config.SYNKRO_CREDENTIALS_PATH ?? "(unset)"}`);
|
|
3882
|
+
console.log(` tier: ${serverTier}`);
|
|
3883
|
+
const inferenceLabel = serverInference === "fast" ? "'fast' (server-side grading)" : "'standard' (local grading)";
|
|
3884
|
+
console.log(` inference: ${inferenceLabel}`);
|
|
3885
|
+
console.log(` version: ${config.SYNKRO_VERSION ?? "(unset)"}`);
|
|
3814
3886
|
console.log();
|
|
3815
3887
|
const agents = detectAgents();
|
|
3816
3888
|
console.log("Detected agents:");
|
|
@@ -3950,6 +4022,102 @@ var init_unlink = __esm({
|
|
|
3950
4022
|
}
|
|
3951
4023
|
});
|
|
3952
4024
|
|
|
4025
|
+
// cli/commands/config.ts
|
|
4026
|
+
var config_exports = {};
|
|
4027
|
+
__export(config_exports, {
|
|
4028
|
+
configCommand: () => configCommand
|
|
4029
|
+
});
|
|
4030
|
+
import { readFileSync as readFileSync7, writeFileSync as writeFileSync6, existsSync as existsSync9 } from "fs";
|
|
4031
|
+
import { join as join8 } from "path";
|
|
4032
|
+
import { homedir as homedir7 } from "os";
|
|
4033
|
+
function readConfigEnv2() {
|
|
4034
|
+
if (!existsSync9(CONFIG_PATH4)) return {};
|
|
4035
|
+
const out = {};
|
|
4036
|
+
for (const line of readFileSync7(CONFIG_PATH4, "utf-8").split("\n")) {
|
|
4037
|
+
const t = line.trim();
|
|
4038
|
+
if (!t || t.startsWith("#")) continue;
|
|
4039
|
+
const eq = t.indexOf("=");
|
|
4040
|
+
if (eq > 0) out[t.slice(0, eq).trim()] = t.slice(eq + 1).trim().replace(/^['"]|['"]$/g, "");
|
|
4041
|
+
}
|
|
4042
|
+
return out;
|
|
4043
|
+
}
|
|
4044
|
+
function updateConfigValue(key, value) {
|
|
4045
|
+
if (!existsSync9(CONFIG_PATH4)) {
|
|
4046
|
+
console.error("No config found. Run `synkro install` first.");
|
|
4047
|
+
process.exit(1);
|
|
4048
|
+
}
|
|
4049
|
+
const lines = readFileSync7(CONFIG_PATH4, "utf-8").split("\n");
|
|
4050
|
+
const pattern = new RegExp(`^${key}=`);
|
|
4051
|
+
let found = false;
|
|
4052
|
+
const updated = lines.map((line) => {
|
|
4053
|
+
if (pattern.test(line.trim())) {
|
|
4054
|
+
found = true;
|
|
4055
|
+
return `${key}='${value}'`;
|
|
4056
|
+
}
|
|
4057
|
+
return line;
|
|
4058
|
+
});
|
|
4059
|
+
if (!found) updated.splice(updated.length - 1, 0, `${key}='${value}'`);
|
|
4060
|
+
writeFileSync6(CONFIG_PATH4, updated.join("\n"), "utf-8");
|
|
4061
|
+
}
|
|
4062
|
+
async function configCommand(args2) {
|
|
4063
|
+
if (args2.length === 0) {
|
|
4064
|
+
const config2 = readConfigEnv2();
|
|
4065
|
+
console.log("Synkro config:\n");
|
|
4066
|
+
console.log(` inference: ${config2.SYNKRO_INFERENCE || "fast"}`);
|
|
4067
|
+
console.log(` tier: ${config2.SYNKRO_TIER || "pro"}`);
|
|
4068
|
+
console.log(` gateway: ${config2.SYNKRO_GATEWAY_URL || "https://api.synkro.sh"}`);
|
|
4069
|
+
console.log(` version: ${config2.SYNKRO_VERSION || "?"}`);
|
|
4070
|
+
console.log(`
|
|
4071
|
+
To change: synkro config --inference fast|standard`);
|
|
4072
|
+
return;
|
|
4073
|
+
}
|
|
4074
|
+
let inferenceValue;
|
|
4075
|
+
for (const a of args2) {
|
|
4076
|
+
if (a.startsWith("--inference=")) inferenceValue = a.slice("--inference=".length);
|
|
4077
|
+
else if (a === "--inference" && args2.indexOf(a) + 1 < args2.length) inferenceValue = args2[args2.indexOf(a) + 1];
|
|
4078
|
+
}
|
|
4079
|
+
if (!inferenceValue || !["fast", "standard"].includes(inferenceValue)) {
|
|
4080
|
+
console.error("Usage: synkro config --inference fast|standard");
|
|
4081
|
+
process.exit(1);
|
|
4082
|
+
}
|
|
4083
|
+
if (!isAuthenticated()) {
|
|
4084
|
+
console.error("Not authenticated. Run `synkro login` first.");
|
|
4085
|
+
process.exit(1);
|
|
4086
|
+
}
|
|
4087
|
+
const token = getAccessToken();
|
|
4088
|
+
const config = readConfigEnv2();
|
|
4089
|
+
const gatewayUrl = (config.SYNKRO_GATEWAY_URL || "https://api.synkro.sh").replace(/\/$/, "");
|
|
4090
|
+
try {
|
|
4091
|
+
const resp = await fetch(`${gatewayUrl}/api/v1/cli/me`, {
|
|
4092
|
+
method: "PATCH",
|
|
4093
|
+
headers: {
|
|
4094
|
+
"Authorization": `Bearer ${token}`,
|
|
4095
|
+
"Content-Type": "application/json"
|
|
4096
|
+
},
|
|
4097
|
+
body: JSON.stringify({ fast_inference: inferenceValue === "fast" })
|
|
4098
|
+
});
|
|
4099
|
+
if (!resp.ok) {
|
|
4100
|
+
const errText = await resp.text().catch(() => "");
|
|
4101
|
+
console.error(`Failed to update: ${resp.status} ${errText.slice(0, 200)}`);
|
|
4102
|
+
process.exit(1);
|
|
4103
|
+
}
|
|
4104
|
+
} catch (err) {
|
|
4105
|
+
console.error(`Failed to reach server: ${err.message}`);
|
|
4106
|
+
process.exit(1);
|
|
4107
|
+
}
|
|
4108
|
+
updateConfigValue("SYNKRO_INFERENCE", inferenceValue);
|
|
4109
|
+
console.log(`\u2713 Inference set to '${inferenceValue}'.`);
|
|
4110
|
+
}
|
|
4111
|
+
var SYNKRO_DIR4, CONFIG_PATH4;
|
|
4112
|
+
var init_config = __esm({
|
|
4113
|
+
"cli/commands/config.ts"() {
|
|
4114
|
+
"use strict";
|
|
4115
|
+
init_stub();
|
|
4116
|
+
SYNKRO_DIR4 = join8(homedir7(), ".synkro");
|
|
4117
|
+
CONFIG_PATH4 = join8(SYNKRO_DIR4, "config.env");
|
|
4118
|
+
}
|
|
4119
|
+
});
|
|
4120
|
+
|
|
3953
4121
|
// cli/commands/scanPr.ts
|
|
3954
4122
|
var scanPr_exports = {};
|
|
3955
4123
|
__export(scanPr_exports, {
|
|
@@ -4542,9 +4710,9 @@ var disconnect_exports = {};
|
|
|
4542
4710
|
__export(disconnect_exports, {
|
|
4543
4711
|
disconnectCommand: () => disconnectCommand
|
|
4544
4712
|
});
|
|
4545
|
-
import { existsSync as
|
|
4546
|
-
import { homedir as
|
|
4547
|
-
import { join as
|
|
4713
|
+
import { existsSync as existsSync10, rmSync } from "fs";
|
|
4714
|
+
import { homedir as homedir8 } from "os";
|
|
4715
|
+
import { join as join9 } from "path";
|
|
4548
4716
|
function disconnectCommand(args2 = []) {
|
|
4549
4717
|
const purge = args2.includes("--purge");
|
|
4550
4718
|
console.log("Synkro disconnect starting...\n");
|
|
@@ -4562,25 +4730,25 @@ function disconnectCommand(args2 = []) {
|
|
|
4562
4730
|
console.log(`${mcpRemoved ? "\u2713" : "\xB7"} MCP guardrails server: ${mcpRemoved ? "removed entry from ~/.claude.json" : "no Synkro MCP entry found"}`);
|
|
4563
4731
|
}
|
|
4564
4732
|
if (purge) {
|
|
4565
|
-
if (
|
|
4566
|
-
rmSync(
|
|
4567
|
-
console.log(`\u2713 Removed ${
|
|
4733
|
+
if (existsSync10(SYNKRO_DIR5)) {
|
|
4734
|
+
rmSync(SYNKRO_DIR5, { recursive: true, force: true });
|
|
4735
|
+
console.log(`\u2713 Removed ${SYNKRO_DIR5}`);
|
|
4568
4736
|
} else {
|
|
4569
|
-
console.log(`\xB7 ${
|
|
4737
|
+
console.log(`\xB7 ${SYNKRO_DIR5} already gone, nothing to remove`);
|
|
4570
4738
|
}
|
|
4571
|
-
} else if (
|
|
4572
|
-
console.log(`Config preserved at ${
|
|
4739
|
+
} else if (existsSync10(SYNKRO_DIR5)) {
|
|
4740
|
+
console.log(`Config preserved at ${SYNKRO_DIR5}. Run with --purge to remove.`);
|
|
4573
4741
|
}
|
|
4574
4742
|
console.log("\nSynkro disconnected.");
|
|
4575
4743
|
}
|
|
4576
|
-
var
|
|
4744
|
+
var SYNKRO_DIR5;
|
|
4577
4745
|
var init_disconnect = __esm({
|
|
4578
4746
|
"cli/commands/disconnect.ts"() {
|
|
4579
4747
|
"use strict";
|
|
4580
4748
|
init_agentDetect();
|
|
4581
4749
|
init_ccHookConfig();
|
|
4582
4750
|
init_mcpConfig();
|
|
4583
|
-
|
|
4751
|
+
SYNKRO_DIR5 = join9(homedir8(), ".synkro");
|
|
4584
4752
|
}
|
|
4585
4753
|
});
|
|
4586
4754
|
|
|
@@ -4622,15 +4790,15 @@ var init_reinstall = __esm({
|
|
|
4622
4790
|
});
|
|
4623
4791
|
|
|
4624
4792
|
// cli/bootstrap.js
|
|
4625
|
-
import { readFileSync as
|
|
4793
|
+
import { readFileSync as readFileSync8, existsSync as existsSync11 } from "fs";
|
|
4626
4794
|
import { resolve } from "path";
|
|
4627
4795
|
var envCandidates = [
|
|
4628
4796
|
resolve(process.cwd(), ".env"),
|
|
4629
4797
|
resolve(process.env.HOME ?? "", ".synkro", "config.env")
|
|
4630
4798
|
];
|
|
4631
4799
|
for (const envPath of envCandidates) {
|
|
4632
|
-
if (!
|
|
4633
|
-
const envContent =
|
|
4800
|
+
if (!existsSync11(envPath)) continue;
|
|
4801
|
+
const envContent = readFileSync8(envPath, "utf-8");
|
|
4634
4802
|
for (const line of envContent.split("\n")) {
|
|
4635
4803
|
const trimmed = line.trim();
|
|
4636
4804
|
if (!trimmed || trimmed.startsWith("#")) continue;
|
|
@@ -4658,6 +4826,7 @@ Commands:
|
|
|
4658
4826
|
status Show current setup state
|
|
4659
4827
|
link Link repos to a Synkro project (local git or GitHub OAuth)
|
|
4660
4828
|
unlink Remove repo links from Synkro projects
|
|
4829
|
+
config View or change settings (e.g. --inference fast|standard)
|
|
4661
4830
|
setup-github Configure GitHub PR scanning (push secrets + workflow file)
|
|
4662
4831
|
update Refresh hook configs and judge prompts
|
|
4663
4832
|
disconnect [--purge] Remove Synkro hooks from agents (--purge also removes ~/.synkro)
|
|
@@ -4692,7 +4861,7 @@ async function main() {
|
|
|
4692
4861
|
}
|
|
4693
4862
|
case "status": {
|
|
4694
4863
|
const { statusCommand: statusCommand2 } = await Promise.resolve().then(() => (init_status(), status_exports));
|
|
4695
|
-
statusCommand2();
|
|
4864
|
+
await statusCommand2();
|
|
4696
4865
|
break;
|
|
4697
4866
|
}
|
|
4698
4867
|
case "link": {
|
|
@@ -4705,6 +4874,11 @@ async function main() {
|
|
|
4705
4874
|
await unlinkCommand2();
|
|
4706
4875
|
break;
|
|
4707
4876
|
}
|
|
4877
|
+
case "config": {
|
|
4878
|
+
const { configCommand: configCommand2 } = await Promise.resolve().then(() => (init_config(), config_exports));
|
|
4879
|
+
await configCommand2(subArgs);
|
|
4880
|
+
break;
|
|
4881
|
+
}
|
|
4708
4882
|
case "setup-github": {
|
|
4709
4883
|
const { setupGithubCommand: setupGithubCommand2 } = await Promise.resolve().then(() => (init_setupGithub(), setupGithub_exports));
|
|
4710
4884
|
const ghOpts = {};
|