repowisestage 0.0.75 → 0.0.76
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/bin/repowise.js +106 -28
- package/package.json +1 -1
package/dist/bin/repowise.js
CHANGED
|
@@ -4535,21 +4535,38 @@ async function storeCredentials(credentials) {
|
|
|
4535
4535
|
}
|
|
4536
4536
|
}
|
|
4537
4537
|
var refreshInFlight = null;
|
|
4538
|
+
var refreshInFlightToken = null;
|
|
4539
|
+
var terminalRefreshTokens = /* @__PURE__ */ new Set();
|
|
4540
|
+
var lastSeenRefreshToken = null;
|
|
4538
4541
|
async function getValidCredentials(options) {
|
|
4539
4542
|
const creds = await getStoredCredentials();
|
|
4540
4543
|
if (!creds) {
|
|
4541
4544
|
lastRefreshOutcome = "no-creds";
|
|
4542
4545
|
return null;
|
|
4543
4546
|
}
|
|
4547
|
+
if (creds.refreshToken !== lastSeenRefreshToken) {
|
|
4548
|
+
terminalRefreshTokens.clear();
|
|
4549
|
+
lastSeenRefreshToken = creds.refreshToken;
|
|
4550
|
+
}
|
|
4544
4551
|
const now = Date.now();
|
|
4545
4552
|
const needsRefresh = options?.forceRefresh || now > creds.expiresAt - 5 * 60 * 1e3;
|
|
4546
4553
|
if (!needsRefresh) {
|
|
4547
4554
|
lastRefreshOutcome = "success";
|
|
4548
4555
|
return creds;
|
|
4549
4556
|
}
|
|
4550
|
-
if (
|
|
4551
|
-
|
|
4552
|
-
|
|
4557
|
+
if (terminalRefreshTokens.has(creds.refreshToken)) {
|
|
4558
|
+
lastRefreshOutcome = "terminal";
|
|
4559
|
+
return null;
|
|
4560
|
+
}
|
|
4561
|
+
if (!refreshInFlight || refreshInFlightToken !== creds.refreshToken) {
|
|
4562
|
+
const inflight = doRefresh(creds);
|
|
4563
|
+
refreshInFlight = inflight;
|
|
4564
|
+
refreshInFlightToken = creds.refreshToken;
|
|
4565
|
+
void inflight.finally(() => {
|
|
4566
|
+
if (refreshInFlight === inflight) {
|
|
4567
|
+
refreshInFlight = null;
|
|
4568
|
+
refreshInFlightToken = null;
|
|
4569
|
+
}
|
|
4553
4570
|
});
|
|
4554
4571
|
}
|
|
4555
4572
|
return refreshInFlight;
|
|
@@ -4566,6 +4583,7 @@ async function doRefresh(creds) {
|
|
|
4566
4583
|
const message = err instanceof Error ? err.message : String(err);
|
|
4567
4584
|
if (kind === "terminal") {
|
|
4568
4585
|
lastRefreshOutcome = "terminal";
|
|
4586
|
+
terminalRefreshTokens.add(creds.refreshToken);
|
|
4569
4587
|
console.warn(`Token refresh rejected (terminal): ${message}`);
|
|
4570
4588
|
return null;
|
|
4571
4589
|
}
|
|
@@ -7657,7 +7675,20 @@ async function startMcpServer(options) {
|
|
|
7657
7675
|
throw err;
|
|
7658
7676
|
}
|
|
7659
7677
|
},
|
|
7660
|
-
resumeEndpoint: () =>
|
|
7678
|
+
resumeEndpoint: async () => {
|
|
7679
|
+
let lastErr;
|
|
7680
|
+
for (let attempt = 1; attempt <= 3; attempt++) {
|
|
7681
|
+
try {
|
|
7682
|
+
await writeEndpointFile(endpointFilePath, endpoint, secretState.value.current);
|
|
7683
|
+
return;
|
|
7684
|
+
} catch (err) {
|
|
7685
|
+
lastErr = err;
|
|
7686
|
+
if (attempt < 3)
|
|
7687
|
+
await new Promise((r) => setTimeout(r, 100 * attempt));
|
|
7688
|
+
}
|
|
7689
|
+
}
|
|
7690
|
+
throw lastErr;
|
|
7691
|
+
}
|
|
7661
7692
|
};
|
|
7662
7693
|
}
|
|
7663
7694
|
function handleRequest(req, res, options, sessions, secretCtx) {
|
|
@@ -8514,6 +8545,9 @@ import { join as join25 } from "path";
|
|
|
8514
8545
|
// ../listener/dist/mcp/auto-config/markers.js
|
|
8515
8546
|
import { promises as fs5 } from "fs";
|
|
8516
8547
|
import { dirname as dirname15 } from "path";
|
|
8548
|
+
function repoWiseServerName(ctx) {
|
|
8549
|
+
return `RepoWise MCP for ${ctx.repoName}${ctx.envSuffix ?? ""}`;
|
|
8550
|
+
}
|
|
8517
8551
|
async function writeMergedConfig(params) {
|
|
8518
8552
|
const current = await readConfig(params.path);
|
|
8519
8553
|
const servers = { ...current.mcpServers ?? {} };
|
|
@@ -8596,14 +8630,14 @@ var claudeCodeWriter = {
|
|
|
8596
8630
|
await removeFromConfig(path, `repowise-${ctx.repoId}`);
|
|
8597
8631
|
const status2 = await writeMergedConfig({
|
|
8598
8632
|
path,
|
|
8599
|
-
serverName:
|
|
8633
|
+
serverName: repoWiseServerName(ctx),
|
|
8600
8634
|
spec: { command: ctx.shimCmd, args: ["mcp-shim", "--repo-id", ctx.repoId] }
|
|
8601
8635
|
});
|
|
8602
8636
|
return { status: status2, path };
|
|
8603
8637
|
},
|
|
8604
8638
|
async remove(ctx) {
|
|
8605
8639
|
const path = join25(ctx.repoRoot, ".mcp.json");
|
|
8606
|
-
await removeFromConfig(path,
|
|
8640
|
+
await removeFromConfig(path, repoWiseServerName(ctx));
|
|
8607
8641
|
await removeFromConfig(path, `repowise-${ctx.repoId}`);
|
|
8608
8642
|
}
|
|
8609
8643
|
};
|
|
@@ -8657,14 +8691,14 @@ var clineWriter = {
|
|
|
8657
8691
|
await removeFromConfig(path, `repowise-${ctx.repoId}`);
|
|
8658
8692
|
const status2 = await writeMergedConfig({
|
|
8659
8693
|
path,
|
|
8660
|
-
serverName:
|
|
8694
|
+
serverName: repoWiseServerName(ctx),
|
|
8661
8695
|
spec: { command: ctx.shimCmd, args: ["mcp-shim", "--repo-id", ctx.repoId] }
|
|
8662
8696
|
});
|
|
8663
8697
|
return { status: status2, path };
|
|
8664
8698
|
},
|
|
8665
8699
|
async remove(ctx) {
|
|
8666
8700
|
const path = join27(ctx.home, ".cline", "mcp.json");
|
|
8667
|
-
await removeFromConfig(path,
|
|
8701
|
+
await removeFromConfig(path, repoWiseServerName(ctx));
|
|
8668
8702
|
await removeFromConfig(path, `repowise-${ctx.repoId}`);
|
|
8669
8703
|
}
|
|
8670
8704
|
};
|
|
@@ -8765,14 +8799,14 @@ var codexWriter = {
|
|
|
8765
8799
|
await removeFromConfig(path, `repowise-${ctx.repoId}`);
|
|
8766
8800
|
const status2 = await writeMergedConfig({
|
|
8767
8801
|
path,
|
|
8768
|
-
serverName:
|
|
8802
|
+
serverName: repoWiseServerName(ctx),
|
|
8769
8803
|
spec: { command: ctx.shimCmd, args: ["mcp-shim", "--repo-id", ctx.repoId] }
|
|
8770
8804
|
});
|
|
8771
8805
|
return { status: status2, path };
|
|
8772
8806
|
},
|
|
8773
8807
|
async remove(ctx) {
|
|
8774
8808
|
const path = join29(ctx.home, ".codex", "mcp.json");
|
|
8775
|
-
await removeFromConfig(path,
|
|
8809
|
+
await removeFromConfig(path, repoWiseServerName(ctx));
|
|
8776
8810
|
await removeFromConfig(path, `repowise-${ctx.repoId}`);
|
|
8777
8811
|
}
|
|
8778
8812
|
};
|
|
@@ -8865,14 +8899,14 @@ var copilotWriter = {
|
|
|
8865
8899
|
await removeFromConfig(path, `repowise-${ctx.repoId}`);
|
|
8866
8900
|
const status2 = await writeMergedConfig({
|
|
8867
8901
|
path,
|
|
8868
|
-
serverName:
|
|
8902
|
+
serverName: repoWiseServerName(ctx),
|
|
8869
8903
|
spec: { command: ctx.shimCmd, args: ["mcp-shim", "--repo-id", ctx.repoId] }
|
|
8870
8904
|
});
|
|
8871
8905
|
return { status: status2, path };
|
|
8872
8906
|
},
|
|
8873
8907
|
async remove(ctx) {
|
|
8874
8908
|
const path = join31(ctx.repoRoot, ".vscode", "mcp.json");
|
|
8875
|
-
await removeFromConfig(path,
|
|
8909
|
+
await removeFromConfig(path, repoWiseServerName(ctx));
|
|
8876
8910
|
await removeFromConfig(path, `repowise-${ctx.repoId}`);
|
|
8877
8911
|
}
|
|
8878
8912
|
};
|
|
@@ -8959,14 +8993,14 @@ var cursorWriter = {
|
|
|
8959
8993
|
await removeFromConfig(path, `repowise-${ctx.repoId}`);
|
|
8960
8994
|
const status2 = await writeMergedConfig({
|
|
8961
8995
|
path,
|
|
8962
|
-
serverName:
|
|
8996
|
+
serverName: repoWiseServerName(ctx),
|
|
8963
8997
|
spec: { command: ctx.shimCmd, args: ["mcp-shim", "--repo-id", ctx.repoId] }
|
|
8964
8998
|
});
|
|
8965
8999
|
return { status: status2, path };
|
|
8966
9000
|
},
|
|
8967
9001
|
async remove(ctx) {
|
|
8968
9002
|
const path = join33(ctx.repoRoot, ".cursor", "mcp.json");
|
|
8969
|
-
await removeFromConfig(path,
|
|
9003
|
+
await removeFromConfig(path, repoWiseServerName(ctx));
|
|
8970
9004
|
await removeFromConfig(path, `repowise-${ctx.repoId}`);
|
|
8971
9005
|
}
|
|
8972
9006
|
};
|
|
@@ -8992,14 +9026,14 @@ var geminiCliWriter = {
|
|
|
8992
9026
|
await removeFromConfig(path, `repowise-${ctx.repoId}`);
|
|
8993
9027
|
const status2 = await writeMergedConfig({
|
|
8994
9028
|
path,
|
|
8995
|
-
serverName:
|
|
9029
|
+
serverName: repoWiseServerName(ctx),
|
|
8996
9030
|
spec: { command: ctx.shimCmd, args: ["mcp-shim", "--repo-id", ctx.repoId] }
|
|
8997
9031
|
});
|
|
8998
9032
|
return { status: status2, path };
|
|
8999
9033
|
},
|
|
9000
9034
|
async remove(ctx) {
|
|
9001
9035
|
const path = join34(ctx.home, ".gemini", "settings.json");
|
|
9002
|
-
await removeFromConfig(path,
|
|
9036
|
+
await removeFromConfig(path, repoWiseServerName(ctx));
|
|
9003
9037
|
await removeFromConfig(path, `repowise-${ctx.repoId}`);
|
|
9004
9038
|
}
|
|
9005
9039
|
};
|
|
@@ -9102,7 +9136,7 @@ var rooWriter = {
|
|
|
9102
9136
|
const homeConfig = join36(ctx.home, ".roo", "mcp.json");
|
|
9103
9137
|
const homeSettings = join36(ctx.home, ".roo", "settings.json");
|
|
9104
9138
|
for (const path of [repoConfig, homeConfig, homeSettings]) {
|
|
9105
|
-
await removeFromConfig(path,
|
|
9139
|
+
await removeFromConfig(path, repoWiseServerName(ctx)).catch(() => {
|
|
9106
9140
|
});
|
|
9107
9141
|
await removeFromConfig(path, `repowise-${ctx.repoId}`).catch(() => {
|
|
9108
9142
|
});
|
|
@@ -9138,14 +9172,14 @@ var windsurfWriter = {
|
|
|
9138
9172
|
await removeFromConfig(path, `repowise-${ctx.repoId}`);
|
|
9139
9173
|
const status2 = await writeMergedConfig({
|
|
9140
9174
|
path,
|
|
9141
|
-
serverName:
|
|
9175
|
+
serverName: repoWiseServerName(ctx),
|
|
9142
9176
|
spec: { command: ctx.shimCmd, args: ["mcp-shim", "--repo-id", ctx.repoId] }
|
|
9143
9177
|
});
|
|
9144
9178
|
return { status: status2, path };
|
|
9145
9179
|
},
|
|
9146
9180
|
async remove(ctx) {
|
|
9147
9181
|
const path = join37(ctx.home, ".codeium", "windsurf", "mcp_config.json");
|
|
9148
|
-
await removeFromConfig(path,
|
|
9182
|
+
await removeFromConfig(path, repoWiseServerName(ctx));
|
|
9149
9183
|
await removeFromConfig(path, `repowise-${ctx.repoId}`);
|
|
9150
9184
|
}
|
|
9151
9185
|
};
|
|
@@ -9205,7 +9239,8 @@ async function runAutoConfig(opts) {
|
|
|
9205
9239
|
home,
|
|
9206
9240
|
contextFolder: opts.contextFolder,
|
|
9207
9241
|
selectedTools: opts.selectedTools,
|
|
9208
|
-
variant: opts.variant
|
|
9242
|
+
variant: opts.variant,
|
|
9243
|
+
envSuffix: opts.envSuffix
|
|
9209
9244
|
});
|
|
9210
9245
|
results.push({ tool: writer.tool, detected: true, outcome });
|
|
9211
9246
|
} catch (err) {
|
|
@@ -11302,6 +11337,7 @@ function mcpAiToolsKey(aiTools) {
|
|
|
11302
11337
|
}
|
|
11303
11338
|
async function reconcileMcpConfigs(repos, packageName) {
|
|
11304
11339
|
const shimCmd = packageName;
|
|
11340
|
+
const envSuffix = getConfigDir().endsWith("-staging") ? " (staging)" : "";
|
|
11305
11341
|
const { contextFolder, aiTools, graphOnly } = await readRawToolConfig();
|
|
11306
11342
|
for (const repo of repos) {
|
|
11307
11343
|
if (!repo.localPath)
|
|
@@ -11322,7 +11358,8 @@ async function reconcileMcpConfigs(repos, packageName) {
|
|
|
11322
11358
|
shimCmd,
|
|
11323
11359
|
contextFolder,
|
|
11324
11360
|
selectedTools: aiTools,
|
|
11325
|
-
variant
|
|
11361
|
+
variant,
|
|
11362
|
+
envSuffix
|
|
11326
11363
|
});
|
|
11327
11364
|
const written = results.filter((r) => r.detected && r.outcome?.status === "written");
|
|
11328
11365
|
if (written.length > 0) {
|
|
@@ -11744,10 +11781,25 @@ async function startListener() {
|
|
|
11744
11781
|
proactiveRefreshTimer.unref();
|
|
11745
11782
|
}
|
|
11746
11783
|
let lastCycleAt = Date.now();
|
|
11784
|
+
let endpointResumeFailed = false;
|
|
11785
|
+
let endpointResumeRetries = 0;
|
|
11747
11786
|
while (running) {
|
|
11748
11787
|
const wakeDrift = Date.now() - lastCycleAt;
|
|
11749
11788
|
await maybeRefreshOnWake(wakeDrift, pollIntervalMs);
|
|
11750
11789
|
lastCycleAt = Date.now();
|
|
11790
|
+
if (endpointResumeFailed) {
|
|
11791
|
+
try {
|
|
11792
|
+
await mcpRuntime?.server?.resumeEndpoint();
|
|
11793
|
+
endpointResumeFailed = false;
|
|
11794
|
+
endpointResumeRetries = 0;
|
|
11795
|
+
console.log("[mcp] endpoint file restored on retry");
|
|
11796
|
+
} catch {
|
|
11797
|
+
endpointResumeRetries++;
|
|
11798
|
+
if (endpointResumeRetries % 12 === 0) {
|
|
11799
|
+
console.warn(`[mcp] endpoint file still not restored after ${endpointResumeRetries.toString()} retries \u2014 MCP remains unreachable`);
|
|
11800
|
+
}
|
|
11801
|
+
}
|
|
11802
|
+
}
|
|
11751
11803
|
let anyAuthError = null;
|
|
11752
11804
|
let authErrorGroup = null;
|
|
11753
11805
|
let minPollInterval = pollIntervalMs;
|
|
@@ -12097,7 +12149,9 @@ async function startListener() {
|
|
|
12097
12149
|
try {
|
|
12098
12150
|
await mcpRuntime?.server?.resumeEndpoint();
|
|
12099
12151
|
} catch (err) {
|
|
12100
|
-
console.warn("[mcp] resumeEndpoint failed:", err instanceof Error ? err.message : String(err));
|
|
12152
|
+
console.warn("[mcp] resumeEndpoint failed (will retry each poll cycle):", err instanceof Error ? err.message : String(err));
|
|
12153
|
+
endpointResumeFailed = true;
|
|
12154
|
+
endpointResumeRetries = 0;
|
|
12101
12155
|
}
|
|
12102
12156
|
}
|
|
12103
12157
|
continue;
|
|
@@ -16773,8 +16827,10 @@ async function mcpShim(opts) {
|
|
|
16773
16827
|
const message = authState === "logged-out" ? (
|
|
16774
16828
|
// Agent-directed: the calling LLM can run this itself for a smoother UX
|
|
16775
16829
|
// (it auto-opens the browser; the user still completes sign-in). The
|
|
16776
|
-
// command is a fixed, argument-free string (nothing injectable).
|
|
16777
|
-
|
|
16830
|
+
// command is a fixed, argument-free string (nothing injectable). Use the
|
|
16831
|
+
// build-flavor binary (`repowise` vs `repowisestage`) so staging users
|
|
16832
|
+
// get the command that matches their install.
|
|
16833
|
+
`RepoWise isn't authenticated (this is rare \u2014 the session lasts about a year). To fix it, run the shell command \`${getPackageName()} login\` on the user's behalf \u2014 it opens a browser for them to sign in and blocks until they finish. Run it once, wait for it to complete, then retry this request. Do not repeat the command.`
|
|
16778
16834
|
) : "listener endpoint unavailable \u2014 is the listener running?";
|
|
16779
16835
|
writeJson(stdout, {
|
|
16780
16836
|
jsonrpc: "2.0",
|
|
@@ -16796,16 +16852,24 @@ async function mcpShim(opts) {
|
|
|
16796
16852
|
);
|
|
16797
16853
|
writeJson(stdout, response);
|
|
16798
16854
|
} catch (err) {
|
|
16799
|
-
stderr.write(`mcp-shim: ${err.message}
|
|
16800
|
-
`);
|
|
16801
16855
|
const name = err.name;
|
|
16802
16856
|
const detail = err.message;
|
|
16803
16857
|
const isTimeout = name === "TimeoutError" || name === "AbortError" || /timeout|aborted|abort/i.test(detail);
|
|
16858
|
+
if (!isTimeout && isConnectionError(err)) {
|
|
16859
|
+
stderr.write(
|
|
16860
|
+
`mcp-shim: listener unreachable (${detail}) \u2014 exiting so the client respawns a fresh shim.
|
|
16861
|
+
`,
|
|
16862
|
+
() => process.exit(1)
|
|
16863
|
+
);
|
|
16864
|
+
return;
|
|
16865
|
+
}
|
|
16866
|
+
stderr.write(`mcp-shim: ${detail}
|
|
16867
|
+
`);
|
|
16804
16868
|
writeJson(stdout, {
|
|
16805
16869
|
jsonrpc: "2.0",
|
|
16806
16870
|
error: isTimeout ? {
|
|
16807
16871
|
code: -32001,
|
|
16808
|
-
message:
|
|
16872
|
+
message: `RepoWise listener did not respond in time \u2014 it may be stuck. Restart it with \`${getPackageName()} restart\`, then retry.`,
|
|
16809
16873
|
data: { detail }
|
|
16810
16874
|
} : {
|
|
16811
16875
|
code: -32001,
|
|
@@ -16816,6 +16880,20 @@ async function mcpShim(opts) {
|
|
|
16816
16880
|
}
|
|
16817
16881
|
}
|
|
16818
16882
|
}
|
|
16883
|
+
function isConnectionError(err) {
|
|
16884
|
+
const CONN_CODES = /* @__PURE__ */ new Set([
|
|
16885
|
+
"ECONNREFUSED",
|
|
16886
|
+
"ECONNRESET",
|
|
16887
|
+
"EHOSTUNREACH",
|
|
16888
|
+
"ENETUNREACH",
|
|
16889
|
+
"ECONNABORTED"
|
|
16890
|
+
]);
|
|
16891
|
+
const e = err;
|
|
16892
|
+
if (e && typeof e.code === "string" && CONN_CODES.has(e.code)) return true;
|
|
16893
|
+
if (e && e.cause && typeof e.cause.code === "string" && CONN_CODES.has(e.cause.code)) return true;
|
|
16894
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
16895
|
+
return /ECONNREFUSED|ECONNRESET|EHOSTUNREACH|ENETUNREACH|fetch failed|socket hang up/i.test(msg);
|
|
16896
|
+
}
|
|
16819
16897
|
async function readEndpoint(path) {
|
|
16820
16898
|
try {
|
|
16821
16899
|
const raw = (await fs30.readFile(path, "utf-8")).trim();
|
|
@@ -16866,7 +16944,7 @@ async function routeMessage(endpoint, repoId, message, postJson, getJson, header
|
|
|
16866
16944
|
id: rpcId,
|
|
16867
16945
|
result: {
|
|
16868
16946
|
protocolVersion: "2024-11-05",
|
|
16869
|
-
serverInfo: { name:
|
|
16947
|
+
serverInfo: { name: getPackageName(), version: "0.0.0" },
|
|
16870
16948
|
capabilities: { tools: { listChanged: false } }
|
|
16871
16949
|
}
|
|
16872
16950
|
};
|