@synkro-sh/cli 1.3.17 → 1.3.18
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 +60 -39
- 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`.");
|
|
@@ -3230,7 +3231,7 @@ function writeConfigEnv(opts) {
|
|
|
3230
3231
|
`SYNKRO_GATEWAY_URL=${shellQuoteSingle(safeGateway)}`,
|
|
3231
3232
|
`SYNKRO_CREDENTIALS_PATH=${shellQuoteSingle(credsPath)}`,
|
|
3232
3233
|
`SYNKRO_TIER=${shellQuoteSingle(safeTier)}`,
|
|
3233
|
-
`SYNKRO_VERSION=${shellQuoteSingle("1.3.
|
|
3234
|
+
`SYNKRO_VERSION=${shellQuoteSingle("1.3.18")}`
|
|
3234
3235
|
];
|
|
3235
3236
|
if (safeUserId) lines.push(`SYNKRO_USER_ID=${shellQuoteSingle(safeUserId)}`);
|
|
3236
3237
|
if (safeOrgId) lines.push(`SYNKRO_ORG_ID=${shellQuoteSingle(safeOrgId)}`);
|
|
@@ -3299,6 +3300,24 @@ async function installCommand(opts = {}) {
|
|
|
3299
3300
|
process.exit(1);
|
|
3300
3301
|
}
|
|
3301
3302
|
if (!opts.force && isAuthenticated() && isAlreadyInstalled()) {
|
|
3303
|
+
setApiBaseUrl(`${gatewayUrl}/api`);
|
|
3304
|
+
await ensureValidToken();
|
|
3305
|
+
const currentRepo = detectGitRepo2();
|
|
3306
|
+
if (currentRepo) {
|
|
3307
|
+
try {
|
|
3308
|
+
const projects = await listProjects();
|
|
3309
|
+
const alreadyLinked = projects.some(
|
|
3310
|
+
(p) => p.repos?.some((r) => r.full_name === currentRepo)
|
|
3311
|
+
);
|
|
3312
|
+
if (!alreadyLinked) {
|
|
3313
|
+
console.log(`Synkro is installed. This repo (${currentRepo}) is not linked yet.
|
|
3314
|
+
`);
|
|
3315
|
+
await promptRepoConnection();
|
|
3316
|
+
return;
|
|
3317
|
+
}
|
|
3318
|
+
} catch {
|
|
3319
|
+
}
|
|
3320
|
+
}
|
|
3302
3321
|
console.log("\u2713 Synkro is already installed and configured.");
|
|
3303
3322
|
console.log(" Run `synkro-cli update` to refresh hook scripts and judge prompts.");
|
|
3304
3323
|
console.log(" Run `synkro-cli install --force` to reinstall from scratch.");
|
|
@@ -3336,6 +3355,7 @@ async function installCommand(opts = {}) {
|
|
|
3336
3355
|
console.error("No access token available after auth.");
|
|
3337
3356
|
process.exit(1);
|
|
3338
3357
|
}
|
|
3358
|
+
setApiBaseUrl(`${gatewayUrl}/api`);
|
|
3339
3359
|
await promptRepoConnection({ linkRepo: opts.linkRepo });
|
|
3340
3360
|
const agents = detectAgents();
|
|
3341
3361
|
if (agents.length === 0) {
|
|
@@ -3683,6 +3703,7 @@ var init_install = __esm({
|
|
|
3683
3703
|
init_graderDaemon();
|
|
3684
3704
|
init_stub();
|
|
3685
3705
|
init_repoConnect();
|
|
3706
|
+
init_projects();
|
|
3686
3707
|
SYNKRO_DIR2 = join6(homedir5(), ".synkro");
|
|
3687
3708
|
HOOKS_DIR = join6(SYNKRO_DIR2, "hooks");
|
|
3688
3709
|
BIN_DIR = join6(SYNKRO_DIR2, "bin");
|
|
@@ -3796,21 +3817,21 @@ function statusCommand() {
|
|
|
3796
3817
|
console.log("Authentication: \u2717 not logged in (run: synkro-cli login)");
|
|
3797
3818
|
}
|
|
3798
3819
|
console.log();
|
|
3799
|
-
const
|
|
3820
|
+
const config = readConfigEnv();
|
|
3800
3821
|
console.log("Config:");
|
|
3801
|
-
console.log(` gateway: ${
|
|
3802
|
-
console.log(` credentials: ${
|
|
3803
|
-
console.log(` tier: ${
|
|
3822
|
+
console.log(` gateway: ${config.SYNKRO_GATEWAY_URL ?? "(unset)"}`);
|
|
3823
|
+
console.log(` credentials: ${config.SYNKRO_CREDENTIALS_PATH ?? "(unset)"}`);
|
|
3824
|
+
console.log(` tier: ${config.SYNKRO_TIER ?? "(unset)"}`);
|
|
3804
3825
|
const info2 = getUserInfo();
|
|
3805
|
-
const userId = info2?.id ??
|
|
3826
|
+
const userId = info2?.id ?? config.SYNKRO_USER_ID ?? "default";
|
|
3806
3827
|
const tierCacheFile = join7(SYNKRO_DIR3, `.tier-cache-${userId}`);
|
|
3807
|
-
let inferenceTier =
|
|
3828
|
+
let inferenceTier = config.SYNKRO_INFERENCE_TIER || null;
|
|
3808
3829
|
if (!inferenceTier && existsSync8(tierCacheFile)) {
|
|
3809
3830
|
inferenceTier = readFileSync6(tierCacheFile, "utf-8").trim() || null;
|
|
3810
3831
|
}
|
|
3811
3832
|
const tierLabel = inferenceTier === "fast" ? "'fast' (server-side grading)" : inferenceTier === "free" ? "'free' (local daemon grading)" : "(unknown \u2014 fires on next hook)";
|
|
3812
3833
|
console.log(` inference: ${tierLabel}`);
|
|
3813
|
-
console.log(` version: ${
|
|
3834
|
+
console.log(` version: ${config.SYNKRO_VERSION ?? "(unset)"}`);
|
|
3814
3835
|
console.log();
|
|
3815
3836
|
const agents = detectAgents();
|
|
3816
3837
|
console.log("Detected agents:");
|