@cybedefend/vibedefend 1.5.0 → 1.7.0
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/README.md +71 -2
- package/dist/api/gateway-request.js +49 -0
- package/dist/api/gateway-request.js.map +1 -0
- package/dist/api/projects.js +67 -0
- package/dist/api/projects.js.map +1 -1
- package/dist/api/repository-link.js +157 -0
- package/dist/api/repository-link.js.map +1 -0
- package/dist/auth/auth-store.js +107 -25
- package/dist/auth/auth-store.js.map +1 -1
- package/dist/auth/auth.js +21 -0
- package/dist/auth/auth.js.map +1 -1
- package/dist/clients/cursor.js +5 -1
- package/dist/clients/cursor.js.map +1 -1
- package/dist/clients/vscode.js +38 -29
- package/dist/clients/vscode.js.map +1 -1
- package/dist/commands/mcp/allow.js +219 -0
- package/dist/commands/mcp/allow.js.map +1 -0
- package/dist/commands/mcp/connect.js +337 -0
- package/dist/commands/mcp/connect.js.map +1 -0
- package/dist/commands/mcp/index.js +170 -0
- package/dist/commands/mcp/index.js.map +1 -0
- package/dist/commands/mcp/proxy.js +320 -0
- package/dist/commands/mcp/proxy.js.map +1 -0
- package/dist/commands/mcp/scan.js +349 -0
- package/dist/commands/mcp/scan.js.map +1 -0
- package/dist/commands/mcp/sync.js +215 -0
- package/dist/commands/mcp/sync.js.map +1 -0
- package/dist/config.js +6 -0
- package/dist/config.js.map +1 -1
- package/dist/diagnostics.js +78 -12
- package/dist/diagnostics.js.map +1 -1
- package/dist/doctor.js +19 -0
- package/dist/doctor.js.map +1 -1
- package/dist/guards-evaluator/analysis-types.js +27 -0
- package/dist/guards-evaluator/analysis-types.js.map +1 -0
- package/dist/guards-evaluator/command-analysis.js +572 -0
- package/dist/guards-evaluator/command-analysis.js.map +1 -0
- package/dist/guards-evaluator/command-view.js +586 -0
- package/dist/guards-evaluator/command-view.js.map +1 -0
- package/dist/guards-evaluator/env.js +11 -0
- package/dist/guards-evaluator/env.js.map +1 -0
- package/dist/guards-evaluator/evaluate.js +91 -41
- package/dist/guards-evaluator/evaluate.js.map +1 -1
- package/dist/guards-evaluator/index.js +2 -1
- package/dist/guards-evaluator/index.js.map +1 -1
- package/dist/guards-evaluator/inline-code.js +259 -0
- package/dist/guards-evaluator/inline-code.js.map +1 -0
- package/dist/guards-evaluator/normalize.js +716 -0
- package/dist/guards-evaluator/normalize.js.map +1 -0
- package/dist/guards-evaluator/preprocess.js +13 -5
- package/dist/guards-evaluator/preprocess.js.map +1 -1
- package/dist/guards-evaluator/redact.js +19 -0
- package/dist/guards-evaluator/redact.js.map +1 -1
- package/dist/guards-evaluator/regex.js +25 -3
- package/dist/guards-evaluator/regex.js.map +1 -1
- package/dist/guards-evaluator/safe-commands.js +155 -0
- package/dist/guards-evaluator/safe-commands.js.map +1 -0
- package/dist/guards-evaluator/triage.js +315 -0
- package/dist/guards-evaluator/triage.js.map +1 -0
- package/dist/hook-runner.js +24679 -5079
- package/dist/hooks/install.js +38 -0
- package/dist/hooks/install.js.map +1 -1
- package/dist/hooks/runtime/config.js +38 -0
- package/dist/hooks/runtime/config.js.map +1 -1
- package/dist/hooks/runtime/emit.js +94 -61
- package/dist/hooks/runtime/emit.js.map +1 -1
- package/dist/hooks/runtime/fetch-rules.js +22 -7
- package/dist/hooks/runtime/fetch-rules.js.map +1 -1
- package/dist/hooks/runtime/gateway-http-error.js +34 -0
- package/dist/hooks/runtime/gateway-http-error.js.map +1 -0
- package/dist/hooks/runtime/guard-rules-cache.js +139 -17
- package/dist/hooks/runtime/guard-rules-cache.js.map +1 -1
- package/dist/hooks/runtime/guard-violations-buffer.js +321 -48
- package/dist/hooks/runtime/guard-violations-buffer.js.map +1 -1
- package/dist/hooks/runtime/judge-cache.js +6 -0
- package/dist/hooks/runtime/judge-cache.js.map +1 -1
- package/dist/hooks/runtime/judge-triage.js +193 -0
- package/dist/hooks/runtime/judge-triage.js.map +1 -0
- package/dist/hooks/runtime/judge.js +7 -1
- package/dist/hooks/runtime/judge.js.map +1 -1
- package/dist/hooks/runtime/pre-compact.js +12 -6
- package/dist/hooks/runtime/pre-compact.js.map +1 -1
- package/dist/hooks/runtime/resolve.js +90 -8
- package/dist/hooks/runtime/resolve.js.map +1 -1
- package/dist/hooks/runtime/retry-policy.js +57 -0
- package/dist/hooks/runtime/retry-policy.js.map +1 -0
- package/dist/hooks/runtime/review-sessions.js +74 -0
- package/dist/hooks/runtime/review-sessions.js.map +1 -0
- package/dist/hooks/runtime/script-resolve.js +695 -0
- package/dist/hooks/runtime/script-resolve.js.map +1 -0
- package/dist/hooks/runtime/session-activation.js +5 -1
- package/dist/hooks/runtime/session-activation.js.map +1 -1
- package/dist/hooks/runtime/session-review.js +163 -45
- package/dist/hooks/runtime/session-review.js.map +1 -1
- package/dist/hooks/runtime/session-start.js +2 -1
- package/dist/hooks/runtime/session-start.js.map +1 -1
- package/dist/hooks/runtime/session-writes.js +232 -0
- package/dist/hooks/runtime/session-writes.js.map +1 -0
- package/dist/hooks/runtime/sniff.js +26 -7
- package/dist/hooks/runtime/sniff.js.map +1 -1
- package/dist/hooks/runtime/target-resolve.js +336 -0
- package/dist/hooks/runtime/target-resolve.js.map +1 -0
- package/dist/hooks/runtime/unmapped-tools.js +93 -0
- package/dist/hooks/runtime/unmapped-tools.js.map +1 -0
- package/dist/hooks/runtime/usage-block.js +4 -0
- package/dist/hooks/runtime/usage-block.js.map +1 -1
- package/dist/hooks/runtime/user-prompt-submit.js +2 -1
- package/dist/hooks/runtime/user-prompt-submit.js.map +1 -1
- package/dist/hooks/runtime/wire-text.js +41 -0
- package/dist/hooks/runtime/wire-text.js.map +1 -0
- package/dist/hooks/runtime/work-dir.js +84 -0
- package/dist/hooks/runtime/work-dir.js.map +1 -0
- package/dist/index.js +45 -12
- package/dist/index.js.map +1 -1
- package/dist/install.js +174 -11
- package/dist/install.js.map +1 -1
- package/dist/link.js +74 -48
- package/dist/link.js.map +1 -1
- package/dist/login.js +77 -11
- package/dist/login.js.map +1 -1
- package/dist/mcp/auth/agent-sign-ins.js +174 -0
- package/dist/mcp/auth/agent-sign-ins.js.map +1 -0
- package/dist/mcp/auth/callback.js +200 -0
- package/dist/mcp/auth/callback.js.map +1 -0
- package/dist/mcp/auth/connect.js +392 -0
- package/dist/mcp/auth/connect.js.map +1 -0
- package/dist/mcp/auth/discovery.js +399 -0
- package/dist/mcp/auth/discovery.js.map +1 -0
- package/dist/mcp/auth/oauth.js +326 -0
- package/dist/mcp/auth/oauth.js.map +1 -0
- package/dist/mcp/auth/probe.js +128 -0
- package/dist/mcp/auth/probe.js.map +1 -0
- package/dist/mcp/auth/secrets.js +446 -0
- package/dist/mcp/auth/secrets.js.map +1 -0
- package/dist/mcp/auth/store.js +260 -0
- package/dist/mcp/auth/store.js.map +1 -0
- package/dist/mcp/auth/tokenSource.js +55 -0
- package/dist/mcp/auth/tokenSource.js.map +1 -0
- package/dist/mcp/config/atomicWrite.js +98 -0
- package/dist/mcp/config/atomicWrite.js.map +1 -0
- package/dist/mcp/config/clients.js +171 -0
- package/dist/mcp/config/clients.js.map +1 -0
- package/dist/mcp/config/cybedefend-servers.js +48 -0
- package/dist/mcp/config/cybedefend-servers.js.map +1 -0
- package/dist/mcp/config/discover.js +114 -0
- package/dist/mcp/config/discover.js.map +1 -0
- package/dist/mcp/config/hook.js +123 -0
- package/dist/mcp/config/hook.js.map +1 -0
- package/dist/mcp/config/index.js +11 -0
- package/dist/mcp/config/index.js.map +1 -0
- package/dist/mcp/config/install.js +132 -0
- package/dist/mcp/config/install.js.map +1 -0
- package/dist/mcp/config/installed.js +37 -0
- package/dist/mcp/config/installed.js.map +1 -0
- package/dist/mcp/config/jsonEdit.js +119 -0
- package/dist/mcp/config/jsonEdit.js.map +1 -0
- package/dist/mcp/config/lock.js +102 -0
- package/dist/mcp/config/lock.js.map +1 -0
- package/dist/mcp/config/proxyBinary.js +211 -0
- package/dist/mcp/config/proxyBinary.js.map +1 -0
- package/dist/mcp/config/rewrite.js +388 -0
- package/dist/mcp/config/rewrite.js.map +1 -0
- package/dist/mcp/config/types.js +34 -0
- package/dist/mcp/config/types.js.map +1 -0
- package/dist/mcp/proxy/audit.js +83 -0
- package/dist/mcp/proxy/audit.js.map +1 -0
- package/dist/mcp/proxy/authInterceptor.js +119 -0
- package/dist/mcp/proxy/authInterceptor.js.map +1 -0
- package/dist/mcp/proxy/expand.js +93 -0
- package/dist/mcp/proxy/expand.js.map +1 -0
- package/dist/mcp/proxy/inject.js +412 -0
- package/dist/mcp/proxy/inject.js.map +1 -0
- package/dist/mcp/proxy/intercept.js +63 -0
- package/dist/mcp/proxy/intercept.js.map +1 -0
- package/dist/mcp/proxy/jsonrpc.js +153 -0
- package/dist/mcp/proxy/jsonrpc.js.map +1 -0
- package/dist/mcp/proxy/log.js +109 -0
- package/dist/mcp/proxy/log.js.map +1 -0
- package/dist/mcp/proxy/paths.js +57 -0
- package/dist/mcp/proxy/paths.js.map +1 -0
- package/dist/mcp/proxy/proxy.js +520 -0
- package/dist/mcp/proxy/proxy.js.map +1 -0
- package/dist/mcp/proxy/serverCheckTimer.js +75 -0
- package/dist/mcp/proxy/serverCheckTimer.js.map +1 -0
- package/dist/mcp/proxy/sessionLifecycle.js +29 -0
- package/dist/mcp/proxy/sessionLifecycle.js.map +1 -0
- package/dist/mcp/proxy/spec.js +203 -0
- package/dist/mcp/proxy/spec.js.map +1 -0
- package/dist/mcp/proxy/sse.js +77 -0
- package/dist/mcp/proxy/sse.js.map +1 -0
- package/dist/mcp/proxy/upstream.js +2 -0
- package/dist/mcp/proxy/upstream.js.map +1 -0
- package/dist/mcp/proxy/upstreamHttp.js +499 -0
- package/dist/mcp/proxy/upstreamHttp.js.map +1 -0
- package/dist/mcp/proxy/upstreamStdio.js +188 -0
- package/dist/mcp/proxy/upstreamStdio.js.map +1 -0
- package/dist/mcp/proxy/upstreams.js +143 -0
- package/dist/mcp/proxy/upstreams.js.map +1 -0
- package/dist/mcp/proxy/verifyInterceptor.js +718 -0
- package/dist/mcp/proxy/verifyInterceptor.js.map +1 -0
- package/dist/mcp/proxy/windowsCommand.js +99 -0
- package/dist/mcp/proxy/windowsCommand.js.map +1 -0
- package/dist/mcp/report/buffer.js +351 -0
- package/dist/mcp/report/buffer.js.map +1 -0
- package/dist/mcp/report/coalesce.js +165 -0
- package/dist/mcp/report/coalesce.js.map +1 -0
- package/dist/mcp/report/constants.js +51 -0
- package/dist/mcp/report/constants.js.map +1 -0
- package/dist/mcp/report/project.js +83 -0
- package/dist/mcp/report/project.js.map +1 -0
- package/dist/mcp/report/reporter.js +443 -0
- package/dist/mcp/report/reporter.js.map +1 -0
- package/dist/mcp/report/types.js +3 -0
- package/dist/mcp/report/types.js.map +1 -0
- package/dist/mcp/report/validate.js +179 -0
- package/dist/mcp/report/validate.js.map +1 -0
- package/dist/mcp/scan/args.js +228 -0
- package/dist/mcp/scan/args.js.map +1 -0
- package/dist/mcp/scan/results.js +253 -0
- package/dist/mcp/scan/results.js.map +1 -0
- package/dist/mcp/scan/types.js +40 -0
- package/dist/mcp/scan/types.js.map +1 -0
- package/dist/mcp/verify/api.js +514 -0
- package/dist/mcp/verify/api.js.map +1 -0
- package/dist/mcp/verify/backend.js +143 -0
- package/dist/mcp/verify/backend.js.map +1 -0
- package/dist/mcp/verify/cache.js +200 -0
- package/dist/mcp/verify/cache.js.map +1 -0
- package/dist/mcp/verify/contract-errors.js +198 -0
- package/dist/mcp/verify/contract-errors.js.map +1 -0
- package/dist/mcp/verify/digest.js +91 -0
- package/dist/mcp/verify/digest.js.map +1 -0
- package/dist/mcp/verify/factory.js +56 -0
- package/dist/mcp/verify/factory.js.map +1 -0
- package/dist/mcp/verify/identity.js +286 -0
- package/dist/mcp/verify/identity.js.map +1 -0
- package/dist/mcp/verify/policy-store.js +63 -0
- package/dist/mcp/verify/policy-store.js.map +1 -0
- package/dist/mcp/verify/policy.js +160 -0
- package/dist/mcp/verify/policy.js.map +1 -0
- package/dist/mcp/verify/pool.js +27 -0
- package/dist/mcp/verify/pool.js.map +1 -0
- package/dist/mcp/verify/token-refresh.js +44 -0
- package/dist/mcp/verify/token-refresh.js.map +1 -0
- package/dist/mcp/verify/token.js +67 -0
- package/dist/mcp/verify/token.js.map +1 -0
- package/dist/mcp/verify/verifier.js +1166 -0
- package/dist/mcp/verify/verifier.js.map +1 -0
- package/dist/org-gate.js +1 -1
- package/dist/org-gate.js.map +1 -1
- package/dist/org.js +146 -0
- package/dist/org.js.map +1 -0
- package/dist/project-create.js +129 -0
- package/dist/project-create.js.map +1 -0
- package/dist/prompts.js +21 -0
- package/dist/prompts.js.map +1 -1
- package/dist/re2.wasm +0 -0
- package/dist/status.js +61 -0
- package/dist/status.js.map +1 -1
- package/dist/uninstall.js +49 -4
- package/dist/uninstall.js.map +1 -1
- package/dist/utils.js +62 -6
- package/dist/utils.js.map +1 -1
- package/package.json +10 -3
|
@@ -0,0 +1,349 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `vibedefend scan` — talk to every upstream once, with no agent in the loop.
|
|
3
|
+
*
|
|
4
|
+
* `initialize` plus `tools/list` against each server in `upstreams.json`, and
|
|
5
|
+
* a line per server. It is the command you run when something is wrong and
|
|
6
|
+
* you want to know which server it is, and it is what a CI job runs to find
|
|
7
|
+
* out whether the park changed under it.
|
|
8
|
+
*
|
|
9
|
+
* It is also the AUDIT. An agent session buys a judgement only for the tool
|
|
10
|
+
* it calls; `scan` buys one for every tool of every reachable server
|
|
11
|
+
* (`Verifier.judgeAll`), because the user who typed it asked exactly that
|
|
12
|
+
* question. The `verdict` column is the worst verdict on the server, the
|
|
13
|
+
* flagged tools are listed under it, and a `malicious` server exits
|
|
14
|
+
* non-zero. Without a credential the column reads `unverified`, which is
|
|
15
|
+
* honest: nobody could be asked. `VIBEDEFEND_MCP_NO_VERIFY=1` skips it.
|
|
16
|
+
*/
|
|
17
|
+
import { spawn } from 'node:child_process';
|
|
18
|
+
import { probeMcpHttp } from '../../mcp/auth/probe.js';
|
|
19
|
+
import { ensureMcpAccessToken } from '../../mcp/auth/store.js';
|
|
20
|
+
import { createNullLogger } from '../../mcp/proxy/log.js';
|
|
21
|
+
import { encodeMessage, LineFramer } from '../../mcp/proxy/jsonrpc.js';
|
|
22
|
+
import { PROXY_ENV_PREFIX } from '../../mcp/proxy/paths.js';
|
|
23
|
+
import { describeUpstream, upstreamEnvironment } from '../../mcp/proxy/spec.js';
|
|
24
|
+
import { planSpawn } from '../../mcp/proxy/windowsCommand.js';
|
|
25
|
+
import { expandedSpecOf, readUpstreams, specOf } from '../../mcp/proxy/upstreams.js';
|
|
26
|
+
import { resolveBackendConfig } from '../../mcp/verify/backend.js';
|
|
27
|
+
import { createJsonVerifyCache } from '../../mcp/verify/cache.js';
|
|
28
|
+
import { buildVerifier } from '../../mcp/verify/factory.js';
|
|
29
|
+
import { runPool } from '../../mcp/verify/pool.js';
|
|
30
|
+
import { log } from '../../utils.js';
|
|
31
|
+
export const EXIT_OK = 0;
|
|
32
|
+
export const EXIT_PROBLEM = 1;
|
|
33
|
+
export const EXIT_USAGE = 2;
|
|
34
|
+
const DEFAULT_TIMEOUT_MS = 20_000;
|
|
35
|
+
/** A judge takes about a second per tool; a catalogue of a hundred is a coffee. */
|
|
36
|
+
const DEFAULT_VERIFY_TIMEOUT_MS = 180_000;
|
|
37
|
+
/**
|
|
38
|
+
* Servers judged side by side. Probing stays sequential — a stdio server is
|
|
39
|
+
* a process, and spawning the whole park at once is the wrong kind of
|
|
40
|
+
* fast — but a judgement is a network call that waits on a backend, and
|
|
41
|
+
* four of them waiting together cost the backend nothing it does not cap.
|
|
42
|
+
*/
|
|
43
|
+
const JUDGE_CONCURRENCY = 4;
|
|
44
|
+
export async function runMcpScanCommand(options, runtime) {
|
|
45
|
+
const stdout = runtime.stdout ?? process.stdout;
|
|
46
|
+
const stderr = runtime.stderr ?? process.stderr;
|
|
47
|
+
const upstreams = readUpstreams(runtime.env);
|
|
48
|
+
let entries = Object.values(upstreams.servers);
|
|
49
|
+
if (options.name) {
|
|
50
|
+
const one = upstreams.servers[options.name];
|
|
51
|
+
if (!one) {
|
|
52
|
+
stderr.write(`vibedefend scan: no upstream named "${options.name}". Known: ${Object.keys(upstreams.servers).join(', ') || '(none)'}.\n`);
|
|
53
|
+
return EXIT_USAGE;
|
|
54
|
+
}
|
|
55
|
+
entries = [one];
|
|
56
|
+
}
|
|
57
|
+
if (entries.length === 0) {
|
|
58
|
+
if (options.json)
|
|
59
|
+
stdout.write(`${JSON.stringify({ servers: [] }, null, 2)}\n`);
|
|
60
|
+
else
|
|
61
|
+
log.info('No MCP server is registered. Run `vibedefend sync` after configuring one.');
|
|
62
|
+
return EXIT_OK;
|
|
63
|
+
}
|
|
64
|
+
const prepared = await prepareRuntime(runtime, stderr);
|
|
65
|
+
// Two phases. Reach every server, one at a time; then judge the ones that
|
|
66
|
+
// answered, a few at a time. The rows stay in the order of the entries
|
|
67
|
+
// whatever finishes first.
|
|
68
|
+
const probed = [];
|
|
69
|
+
for (const entry of entries) {
|
|
70
|
+
probed.push(await probeOne(entry, options, prepared));
|
|
71
|
+
}
|
|
72
|
+
const judge = prepared.judge ?? judgeWithBackend;
|
|
73
|
+
await runPool(probed.filter((server) => server.tools !== undefined), JUDGE_CONCURRENCY, async (server) => {
|
|
74
|
+
const started = Date.now();
|
|
75
|
+
const judged = await judge(server.spec, server.tools ?? [], options, prepared, server.row.name);
|
|
76
|
+
Object.assign(server.row, judged);
|
|
77
|
+
server.row.ms += elapsed(started);
|
|
78
|
+
});
|
|
79
|
+
const rows = probed.map((server) => server.row);
|
|
80
|
+
if (options.json) {
|
|
81
|
+
stdout.write(`${JSON.stringify({ servers: rows }, null, 2)}\n`);
|
|
82
|
+
}
|
|
83
|
+
else {
|
|
84
|
+
writeTable(rows);
|
|
85
|
+
}
|
|
86
|
+
// A server that wants a login is not a failure of the scan: it is
|
|
87
|
+
// information, and `vibedefend connect` is the answer. A malicious server
|
|
88
|
+
// is, and so is one that could not be reached.
|
|
89
|
+
return rows.some((row) => row.status === 'unreachable' ||
|
|
90
|
+
row.status === 'unusable' ||
|
|
91
|
+
row.verdict === 'malicious' ||
|
|
92
|
+
row.override === 'deny')
|
|
93
|
+
? EXIT_PROBLEM
|
|
94
|
+
: EXIT_OK;
|
|
95
|
+
}
|
|
96
|
+
/**
|
|
97
|
+
* Resolves what every judgement of this scan shares — backend, cache — once.
|
|
98
|
+
*
|
|
99
|
+
* Only when the real judge will run: an injected judge never touches them,
|
|
100
|
+
* and `VIBEDEFEND_MCP_NO_VERIFY=1` means nobody is asked at all.
|
|
101
|
+
*/
|
|
102
|
+
async function prepareRuntime(runtime, stderr) {
|
|
103
|
+
if (runtime.judge || runtime.env[`${PROXY_ENV_PREFIX}NO_VERIFY`] === '1')
|
|
104
|
+
return runtime;
|
|
105
|
+
const backend = runtime.backend !== undefined
|
|
106
|
+
? runtime.backend
|
|
107
|
+
: await (runtime.resolveBackendConfigFn ?? resolveBackendConfig)({
|
|
108
|
+
env: runtime.env,
|
|
109
|
+
// Typed by a human: the reason nothing is verified goes to them.
|
|
110
|
+
warn: (message) => stderr.write(`vibedefend scan: ${message}\n`),
|
|
111
|
+
});
|
|
112
|
+
return {
|
|
113
|
+
...runtime,
|
|
114
|
+
backend,
|
|
115
|
+
cache: runtime.cache ?? createJsonVerifyCache({ env: runtime.env }),
|
|
116
|
+
};
|
|
117
|
+
}
|
|
118
|
+
async function probeOne(entry, options, runtime) {
|
|
119
|
+
const started = Date.now();
|
|
120
|
+
const timeoutMs = options.timeoutMs ?? DEFAULT_TIMEOUT_MS;
|
|
121
|
+
const base = { name: entry.name, transport: entry.transport, verdict: 'unverified' };
|
|
122
|
+
// TWO specs, as in the proxy (`runMcpProxyCommand`). The expanded one is
|
|
123
|
+
// what the server is REACHED with — a `${VAR}` in a url, a header or an
|
|
124
|
+
// argument must resolve here too, or `scan` reports a server the proxy
|
|
125
|
+
// would reach as unreachable. The stored one is what the verdict is FILED
|
|
126
|
+
// under: `upstreamServerId` hashes `command` + `args` (or the url), and
|
|
127
|
+
// that hash keys the cache and the user's `allow`/`deny`, which the proxy
|
|
128
|
+
// and `vibedefend allow` compute from the stored entry. Judging under the
|
|
129
|
+
// expanded spec would open a second cache file per server (with the
|
|
130
|
+
// resolved value in its name), bill every tool twice, and hide the
|
|
131
|
+
// override from `scan`.
|
|
132
|
+
const identitySpec = specOf(entry);
|
|
133
|
+
const failed = (status) => ({
|
|
134
|
+
row: { ...base, status, ms: elapsed(started) },
|
|
135
|
+
spec: identitySpec,
|
|
136
|
+
});
|
|
137
|
+
try {
|
|
138
|
+
if (entry.transport === 'http') {
|
|
139
|
+
const spec = expandedSpecOf(entry, runtime.env).value;
|
|
140
|
+
if (spec.transport !== 'http')
|
|
141
|
+
return failed('unusable');
|
|
142
|
+
const common = {
|
|
143
|
+
timeoutMs,
|
|
144
|
+
headers: spec.headers,
|
|
145
|
+
clientInfo: { name: 'vibedefend', version: runtime.version },
|
|
146
|
+
};
|
|
147
|
+
// Bare first. Most servers want no token, and asking the credential
|
|
148
|
+
// store for one costs a keychain round trip — and, on a locked macOS
|
|
149
|
+
// keychain, a dialog — for a lookup that was never going to find
|
|
150
|
+
// anything.
|
|
151
|
+
let probe = await probeMcpHttp(spec.url, { ...common, token: null });
|
|
152
|
+
if (probe.verdict === 'refused') {
|
|
153
|
+
// Renewed if it expired, and persisted: a token that ran out in the
|
|
154
|
+
// last hour used to send the user to `vibedefend connect --all` with
|
|
155
|
+
// the refresh token that would have fixed it sitting in the store
|
|
156
|
+
// (2026-09-16, three servers at once). A dead refresh token is erased
|
|
157
|
+
// on the way, and the row honestly reads `needs-auth`.
|
|
158
|
+
const token = await ensureMcpAccessToken(spec.url, { env: runtime.env });
|
|
159
|
+
if (token)
|
|
160
|
+
probe = await probeMcpHttp(spec.url, { ...common, token });
|
|
161
|
+
}
|
|
162
|
+
if (probe.verdict === 'open') {
|
|
163
|
+
return {
|
|
164
|
+
row: { ...base, status: 'ok', toolCount: probe.toolCount, ms: elapsed(started) },
|
|
165
|
+
spec: identitySpec,
|
|
166
|
+
tools: probe.tools ?? [],
|
|
167
|
+
};
|
|
168
|
+
}
|
|
169
|
+
if (probe.verdict === 'refused')
|
|
170
|
+
return failed('needs-auth');
|
|
171
|
+
if (probe.verdict === 'unreachable')
|
|
172
|
+
return failed('unreachable');
|
|
173
|
+
return failed('unusable');
|
|
174
|
+
}
|
|
175
|
+
const tools = await listStdioTools(entry, timeoutMs, runtime.env);
|
|
176
|
+
if (tools === null)
|
|
177
|
+
return failed('unreachable');
|
|
178
|
+
return {
|
|
179
|
+
row: { ...base, status: 'ok', toolCount: tools.length, ms: elapsed(started) },
|
|
180
|
+
spec: identitySpec,
|
|
181
|
+
tools,
|
|
182
|
+
};
|
|
183
|
+
}
|
|
184
|
+
catch {
|
|
185
|
+
return failed('unreachable');
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
function elapsed(started) {
|
|
189
|
+
return Date.now() - started;
|
|
190
|
+
}
|
|
191
|
+
/**
|
|
192
|
+
* Buys the judgement of every tool listed, and reads the verdicts back.
|
|
193
|
+
*
|
|
194
|
+
* Wired exactly like the proxy (`buildVerifier`): same cache, same identity,
|
|
195
|
+
* same name on the finding and same credential path, so what `scan` buys is
|
|
196
|
+
* what the next agent session finds, and vice versa. Without a credential
|
|
197
|
+
* nothing is asked and the row says `unverified`.
|
|
198
|
+
*/
|
|
199
|
+
export const judgeWithBackend = async (spec, listed, options, runtime, name) => {
|
|
200
|
+
if (runtime.env[`${PROXY_ENV_PREFIX}NO_VERIFY`] === '1')
|
|
201
|
+
return { verdict: 'unverified' };
|
|
202
|
+
const tools = listed.filter((tool) => typeof tool === 'object' && tool !== null && typeof tool.name === 'string');
|
|
203
|
+
// Resolved once by `runMcpScanCommand`; a direct caller gets it here.
|
|
204
|
+
const backend = runtime.backend !== undefined
|
|
205
|
+
? runtime.backend
|
|
206
|
+
: await (runtime.resolveBackendConfigFn ?? resolveBackendConfig)({ env: runtime.env });
|
|
207
|
+
if (!backend)
|
|
208
|
+
return { verdict: 'unverified' };
|
|
209
|
+
const { verifier } = buildVerifier(spec, name ?? describeUpstream(spec), createNullLogger(), runtime.env, {
|
|
210
|
+
backend,
|
|
211
|
+
cache: runtime.cache,
|
|
212
|
+
});
|
|
213
|
+
try {
|
|
214
|
+
const outcome = await verifier.judgeAll(tools, {
|
|
215
|
+
timeoutMs: options.verifyTimeoutMs ?? DEFAULT_VERIFY_TIMEOUT_MS,
|
|
216
|
+
});
|
|
217
|
+
return rowFromOutcome(outcome);
|
|
218
|
+
}
|
|
219
|
+
catch {
|
|
220
|
+
return { verdict: 'unverified' };
|
|
221
|
+
}
|
|
222
|
+
};
|
|
223
|
+
/**
|
|
224
|
+
* The row, from the outcome — and from the DECISION, not the verdict alone.
|
|
225
|
+
*
|
|
226
|
+
* The flagged tools come from `outcome.tools`, which is scoped to the tools
|
|
227
|
+
* listed now; the cache file is never pruned and walking it would show a
|
|
228
|
+
* tool the server dropped last month. The user's override is read off the
|
|
229
|
+
* decision's rationale, the one place `vibedefend allow` / `deny` surfaces.
|
|
230
|
+
*/
|
|
231
|
+
export function rowFromOutcome(outcome) {
|
|
232
|
+
const flagged = [];
|
|
233
|
+
for (const tool of outcome.tools ?? []) {
|
|
234
|
+
if (tool.verdict === 'malicious' || tool.verdict === 'suspicious') {
|
|
235
|
+
flagged.push({ name: tool.name, verdict: tool.verdict, ...(tool.reason ? { reason: tool.reason } : {}) });
|
|
236
|
+
}
|
|
237
|
+
}
|
|
238
|
+
const judged = outcome.verdict === 'malicious' || outcome.verdict === 'suspicious' || outcome.verdict === 'ok'
|
|
239
|
+
? outcome.verdict
|
|
240
|
+
: 'unverified';
|
|
241
|
+
const override = outcome.decision.rationale === 'allowed-by-user'
|
|
242
|
+
? 'allow'
|
|
243
|
+
: outcome.decision.rationale === 'denied-by-user'
|
|
244
|
+
? 'deny'
|
|
245
|
+
: undefined;
|
|
246
|
+
return {
|
|
247
|
+
verdict: override === 'allow' ? 'ok' : judged,
|
|
248
|
+
...(flagged.length > 0 ? { flagged } : {}),
|
|
249
|
+
...(override ? { override } : {}),
|
|
250
|
+
};
|
|
251
|
+
}
|
|
252
|
+
/**
|
|
253
|
+
* Spawns a stdio server, does the handshake, counts its tools and stops it.
|
|
254
|
+
*
|
|
255
|
+
* The proxy's own transport is not reused here: it exists to forward, and
|
|
256
|
+
* what this needs is a two-message conversation with a hard deadline and no
|
|
257
|
+
* session to keep. `null` means the server never got that far.
|
|
258
|
+
*/
|
|
259
|
+
async function listStdioTools(entry, timeoutMs, env) {
|
|
260
|
+
const spec = expandedSpecOf(entry, env).value;
|
|
261
|
+
if (spec.transport !== 'stdio')
|
|
262
|
+
return null;
|
|
263
|
+
void createNullLogger();
|
|
264
|
+
const plan = planSpawn(spec.command, spec.args, process.platform, env);
|
|
265
|
+
const child = spawn(plan.command, plan.args, {
|
|
266
|
+
env: upstreamEnvironment(env, spec.env),
|
|
267
|
+
cwd: spec.cwd,
|
|
268
|
+
stdio: ['pipe', 'pipe', 'ignore'],
|
|
269
|
+
windowsVerbatimArguments: plan.windowsVerbatimArguments,
|
|
270
|
+
shell: false,
|
|
271
|
+
});
|
|
272
|
+
return new Promise((resolve) => {
|
|
273
|
+
const framer = new LineFramer();
|
|
274
|
+
let settled = false;
|
|
275
|
+
const finish = (value) => {
|
|
276
|
+
if (settled)
|
|
277
|
+
return;
|
|
278
|
+
settled = true;
|
|
279
|
+
clearTimeout(timer);
|
|
280
|
+
try {
|
|
281
|
+
child.stdin.end();
|
|
282
|
+
child.kill();
|
|
283
|
+
}
|
|
284
|
+
catch {
|
|
285
|
+
/* already gone */
|
|
286
|
+
}
|
|
287
|
+
resolve(value);
|
|
288
|
+
};
|
|
289
|
+
const timer = setTimeout(() => finish(null), timeoutMs);
|
|
290
|
+
if (typeof timer.unref === 'function')
|
|
291
|
+
timer.unref();
|
|
292
|
+
child.once('error', () => finish(null));
|
|
293
|
+
child.once('exit', () => finish(null));
|
|
294
|
+
child.stdout?.on('data', (chunk) => {
|
|
295
|
+
for (const message of framer.push(chunk).messages) {
|
|
296
|
+
const typed = message;
|
|
297
|
+
if (typed.id === 1) {
|
|
298
|
+
child.stdin.write(encodeMessage({ jsonrpc: '2.0', method: 'notifications/initialized' }));
|
|
299
|
+
child.stdin.write(encodeMessage({ jsonrpc: '2.0', id: 2, method: 'tools/list' }));
|
|
300
|
+
continue;
|
|
301
|
+
}
|
|
302
|
+
if (typed.id === 2) {
|
|
303
|
+
const result = typed.result;
|
|
304
|
+
finish(Array.isArray(result?.tools) ? result.tools : []);
|
|
305
|
+
}
|
|
306
|
+
}
|
|
307
|
+
});
|
|
308
|
+
child.stdin.write(encodeMessage({
|
|
309
|
+
jsonrpc: '2.0',
|
|
310
|
+
id: 1,
|
|
311
|
+
method: 'initialize',
|
|
312
|
+
params: {
|
|
313
|
+
protocolVersion: '2025-06-18',
|
|
314
|
+
capabilities: {},
|
|
315
|
+
clientInfo: { name: 'vibedefend-scan', version: '1.0.0' },
|
|
316
|
+
},
|
|
317
|
+
}));
|
|
318
|
+
});
|
|
319
|
+
}
|
|
320
|
+
function writeTable(rows) {
|
|
321
|
+
const width = Math.max(6, ...rows.map((row) => row.name.length));
|
|
322
|
+
log.step('MCP servers');
|
|
323
|
+
for (const row of rows) {
|
|
324
|
+
const name = row.name.padEnd(width);
|
|
325
|
+
const tools = row.toolCount === undefined ? '' : `${row.toolCount} tools`;
|
|
326
|
+
const verdict = row.status === 'ok' ? row.verdict : '';
|
|
327
|
+
const said = row.override === 'allow' ? ' [allowed by you]' : row.override === 'deny' ? ' [denied by you]' : '';
|
|
328
|
+
const line = `${name} ${row.transport.padEnd(5)} ${row.status.padEnd(11)} ${tools.padEnd(9)} ${verdict.padEnd(10)} ${row.ms} ms${said}`;
|
|
329
|
+
if (row.verdict === 'malicious' || row.override === 'deny')
|
|
330
|
+
log.err(line);
|
|
331
|
+
else if (row.verdict === 'suspicious')
|
|
332
|
+
log.warn(line);
|
|
333
|
+
else if (row.status === 'ok')
|
|
334
|
+
log.ok(line);
|
|
335
|
+
else if (row.status === 'needs-auth')
|
|
336
|
+
log.warn(`${line} → vibedefend connect ${row.name}`);
|
|
337
|
+
else
|
|
338
|
+
log.err(line);
|
|
339
|
+
for (const tool of row.flagged ?? []) {
|
|
340
|
+
const reason = tool.reason ? ` — ${tool.reason}` : '';
|
|
341
|
+
const detail = ` ${tool.verdict.padEnd(10)} ${tool.name}${reason}`;
|
|
342
|
+
if (tool.verdict === 'malicious')
|
|
343
|
+
log.err(detail);
|
|
344
|
+
else
|
|
345
|
+
log.warn(detail);
|
|
346
|
+
}
|
|
347
|
+
}
|
|
348
|
+
}
|
|
349
|
+
//# sourceMappingURL=scan.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"scan.js","sourceRoot":"","sources":["../../../src/commands/mcp/scan.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,215 @@
|
|
|
1
|
+
import { isMcpClientId, MCP_CLIENT_ADAPTERS } from '../../mcp/config/clients.js';
|
|
2
|
+
import { installSyncHook, removeSyncHook } from '../../mcp/config/hook.js';
|
|
3
|
+
import { installProxy, installRefusalMessage, installRefusalSentence, uninstallProxy, } from '../../mcp/config/install.js';
|
|
4
|
+
import { log } from '../../utils.js';
|
|
5
|
+
export const EXIT_OK = 0;
|
|
6
|
+
export const EXIT_PROBLEM = 1;
|
|
7
|
+
export const EXIT_USAGE = 2;
|
|
8
|
+
export async function runMcpSyncCommand(options, runtime, mode = 'sync') {
|
|
9
|
+
const stdout = runtime.stdout ?? process.stdout;
|
|
10
|
+
const stderr = runtime.stderr ?? process.stderr;
|
|
11
|
+
if (options.hook !== undefined) {
|
|
12
|
+
return runHook(options, runtime, stdout, stderr);
|
|
13
|
+
}
|
|
14
|
+
let clients;
|
|
15
|
+
if (options.client) {
|
|
16
|
+
if (!isMcpClientId(options.client)) {
|
|
17
|
+
stderr.write(`vibedefend ${mode}: unknown client "${options.client}". Known: ${MCP_CLIENT_ADAPTERS.map((adapter) => adapter.id).join(', ')}.\n`);
|
|
18
|
+
return EXIT_USAGE;
|
|
19
|
+
}
|
|
20
|
+
clients = [options.client];
|
|
21
|
+
}
|
|
22
|
+
// The original entry is recorded in `upstreams.json`, which is what
|
|
23
|
+
// `uninstall` restores from; the backup is for the user, not for us.
|
|
24
|
+
const shared = {
|
|
25
|
+
env: runtime.env,
|
|
26
|
+
clients,
|
|
27
|
+
dryRun: options.dryRun,
|
|
28
|
+
backup: !options.noBackup,
|
|
29
|
+
now: runtime.now,
|
|
30
|
+
platform: runtime.platform,
|
|
31
|
+
};
|
|
32
|
+
let plan;
|
|
33
|
+
let result;
|
|
34
|
+
if (mode === 'uninstall') {
|
|
35
|
+
({ plan, result } = uninstallProxy(shared));
|
|
36
|
+
}
|
|
37
|
+
else {
|
|
38
|
+
const outcome = installProxy({
|
|
39
|
+
...shared,
|
|
40
|
+
argv1: runtime.argv1 ?? process.argv[1],
|
|
41
|
+
execFileFn: runtime.execFileFn,
|
|
42
|
+
});
|
|
43
|
+
if (outcome.refused) {
|
|
44
|
+
writeRefusal(outcome.refused, options, stdout, stderr);
|
|
45
|
+
return EXIT_PROBLEM;
|
|
46
|
+
}
|
|
47
|
+
plan = outcome.plan;
|
|
48
|
+
result = outcome.result;
|
|
49
|
+
}
|
|
50
|
+
const report = buildReport(plan, result, options.dryRun === true);
|
|
51
|
+
if (options.json) {
|
|
52
|
+
stdout.write(`${JSON.stringify(report, null, 2)}\n`);
|
|
53
|
+
}
|
|
54
|
+
else if (options.quiet) {
|
|
55
|
+
writeQuiet(report, stdout);
|
|
56
|
+
}
|
|
57
|
+
else {
|
|
58
|
+
writeVerbose(report, mode, stdout);
|
|
59
|
+
}
|
|
60
|
+
return report.problems.length > 0 || report.failed.length > 0 ? EXIT_PROBLEM : EXIT_OK;
|
|
61
|
+
}
|
|
62
|
+
function runHook(options, runtime, stdout, stderr) {
|
|
63
|
+
if (options.hook !== 'claude-code') {
|
|
64
|
+
stderr.write(`vibedefend sync: --hook only knows claude-code for now (got "${String(options.hook)}").\n`);
|
|
65
|
+
return EXIT_USAGE;
|
|
66
|
+
}
|
|
67
|
+
const result = options.removeHook
|
|
68
|
+
? removeSyncHook({ env: runtime.env })
|
|
69
|
+
: installSyncHook({ env: runtime.env });
|
|
70
|
+
if (result.outcome === 'unreadable') {
|
|
71
|
+
stderr.write(`vibedefend sync: cannot read ${result.file}. It may contain comments, which cannot be edited without dropping them; add the hook by hand.\n`);
|
|
72
|
+
return EXIT_PROBLEM;
|
|
73
|
+
}
|
|
74
|
+
if (options.json) {
|
|
75
|
+
stdout.write(`${JSON.stringify(result, null, 2)}\n`);
|
|
76
|
+
}
|
|
77
|
+
else if (!options.quiet) {
|
|
78
|
+
log.ok(options.removeHook
|
|
79
|
+
? `SessionStart hook removed from ${result.file}`
|
|
80
|
+
: result.outcome === 'already-installed'
|
|
81
|
+
? `SessionStart hook already in ${result.file}`
|
|
82
|
+
: `SessionStart hook added to ${result.file}`);
|
|
83
|
+
}
|
|
84
|
+
return EXIT_OK;
|
|
85
|
+
}
|
|
86
|
+
/**
|
|
87
|
+
* Sync did nothing, and says why in the mode's own voice: a JSON block for a
|
|
88
|
+
* program, one sentence on stdout for the hook (it lands in the agent's
|
|
89
|
+
* context, and the user has to hear about it from somewhere), the full
|
|
90
|
+
* explanation on stderr for a human.
|
|
91
|
+
*/
|
|
92
|
+
function writeRefusal(refusal, options, stdout, stderr) {
|
|
93
|
+
if (options.json) {
|
|
94
|
+
stdout.write(`${JSON.stringify({ refused: refusal }, null, 2)}\n`);
|
|
95
|
+
return;
|
|
96
|
+
}
|
|
97
|
+
if (options.quiet) {
|
|
98
|
+
stdout.write(`${installRefusalSentence(refusal)}\n`);
|
|
99
|
+
return;
|
|
100
|
+
}
|
|
101
|
+
stderr.write(`${installRefusalMessage(refusal)}\n`);
|
|
102
|
+
}
|
|
103
|
+
function buildReport(plan, result, dryRun) {
|
|
104
|
+
const failedChanges = new Set(result.failed.map((failure) => failure.change));
|
|
105
|
+
const applied = plan.changes.filter((change) => !failedChanges.has(change));
|
|
106
|
+
return {
|
|
107
|
+
wrapped: applied
|
|
108
|
+
.filter((change) => change.kind === 'wrap')
|
|
109
|
+
.map((change) => ({
|
|
110
|
+
name: change.upstreamName,
|
|
111
|
+
client: change.entry.location.client,
|
|
112
|
+
from: change.entry.kind,
|
|
113
|
+
})),
|
|
114
|
+
unwrapped: applied
|
|
115
|
+
.filter((change) => change.kind === 'unwrap')
|
|
116
|
+
.map((change) => ({ name: change.upstreamName, client: change.location.client })),
|
|
117
|
+
forgotten: applied
|
|
118
|
+
.filter((change) => change.kind === 'forget')
|
|
119
|
+
.map((change) => change.upstreamName),
|
|
120
|
+
skipped: plan.skipped.map((entry) => ({
|
|
121
|
+
name: entry.entry.name,
|
|
122
|
+
client: entry.entry.location.client,
|
|
123
|
+
reason: entry.reason,
|
|
124
|
+
})),
|
|
125
|
+
problems: plan.problems.map((problem) => ({
|
|
126
|
+
file: problem.location.file,
|
|
127
|
+
problem: problem.problem,
|
|
128
|
+
})),
|
|
129
|
+
failed: result.failed.map((failure) => ({ reason: failure.reason })),
|
|
130
|
+
files: result.written,
|
|
131
|
+
backups: result.backups,
|
|
132
|
+
dryRun,
|
|
133
|
+
};
|
|
134
|
+
}
|
|
135
|
+
/**
|
|
136
|
+
* The hook's output, which lands in the agent's context.
|
|
137
|
+
*
|
|
138
|
+
* Silence when nothing happened. One sentence when something did — naming the
|
|
139
|
+
* servers, because "1 server was wrapped" tells the agent nothing it can act
|
|
140
|
+
* on.
|
|
141
|
+
*/
|
|
142
|
+
function writeQuiet(report, stdout) {
|
|
143
|
+
const lines = [];
|
|
144
|
+
if (report.wrapped.length > 0) {
|
|
145
|
+
lines.push(`VibeDefend is now proxying ${report.wrapped.length === 1 ? 'a new MCP server' : `${report.wrapped.length} new MCP servers`}: ${report.wrapped.map((entry) => entry.name).join(', ')}.`);
|
|
146
|
+
}
|
|
147
|
+
if (report.problems.length > 0) {
|
|
148
|
+
lines.push(`VibeDefend could not read ${report.problems.length === 1 ? 'an MCP config file' : `${report.problems.length} MCP config files`}: ${report.problems.map((problem) => problem.file).join(', ')}.`);
|
|
149
|
+
}
|
|
150
|
+
// Loud even in quiet mode: this one is not "nothing happened", it is a
|
|
151
|
+
// server deliberately left alone, and the user has to know which.
|
|
152
|
+
const interactive = report.skipped.filter((entry) => entry.reason === 'needs-interactive-input');
|
|
153
|
+
if (interactive.length > 0) {
|
|
154
|
+
lines.push(`VibeDefend left ${interactive.map((entry) => entry.name).join(', ')} untouched: ${interactive.length === 1 ? 'it uses' : 'they use'} a \${input:…} placeholder, which only the client can resolve by asking you.`);
|
|
155
|
+
}
|
|
156
|
+
if (lines.length > 0)
|
|
157
|
+
stdout.write(`${lines.join(' ')}\n`);
|
|
158
|
+
}
|
|
159
|
+
function writeVerbose(report, mode, stdout) {
|
|
160
|
+
void stdout;
|
|
161
|
+
const prefix = report.dryRun ? '[dry-run] ' : '';
|
|
162
|
+
for (const entry of report.wrapped) {
|
|
163
|
+
log.ok(`${prefix}${entry.client}: ${entry.name} is now behind the proxy`);
|
|
164
|
+
}
|
|
165
|
+
for (const entry of report.unwrapped) {
|
|
166
|
+
log.ok(`${prefix}${entry.client}: ${entry.name} restored to its original entry`);
|
|
167
|
+
}
|
|
168
|
+
for (const name of report.forgotten) {
|
|
169
|
+
log.info(`${prefix}forgot ${name}, which no client lists any more`);
|
|
170
|
+
}
|
|
171
|
+
for (const entry of report.skipped) {
|
|
172
|
+
const explanation = explainSkip(entry.reason);
|
|
173
|
+
if (explanation)
|
|
174
|
+
log.warn(`${entry.client}: ${entry.name} ${explanation}`);
|
|
175
|
+
}
|
|
176
|
+
for (const problem of report.problems) {
|
|
177
|
+
log.warn(`${problem.file}: ${explainProblem(problem.problem)}`);
|
|
178
|
+
}
|
|
179
|
+
for (const failure of report.failed) {
|
|
180
|
+
log.err(failure.reason);
|
|
181
|
+
}
|
|
182
|
+
if (report.wrapped.length === 0 && report.unwrapped.length === 0 && report.forgotten.length === 0) {
|
|
183
|
+
log.info(mode === 'uninstall' ? 'Nothing was behind the proxy.' : 'Everything is already in order.');
|
|
184
|
+
}
|
|
185
|
+
if (report.backups.length > 0) {
|
|
186
|
+
log.hint(`Backups: ${report.backups.join(', ')}`);
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
/**
|
|
190
|
+
* Why an entry was left alone, when that is worth a line. `null` for the
|
|
191
|
+
* reasons that are business as usual — an already-wrapped server is not news.
|
|
192
|
+
*/
|
|
193
|
+
function explainSkip(reason) {
|
|
194
|
+
if (reason === 'needs-interactive-input') {
|
|
195
|
+
return ('was left untouched: it references a ${input:…} placeholder, whose value ' +
|
|
196
|
+
'the client obtains by asking you. The proxy has no way to ask, so ' +
|
|
197
|
+
'wrapping it would break a server that works today. Replace the ' +
|
|
198
|
+
'placeholder with an environment variable to put it behind the proxy.');
|
|
199
|
+
}
|
|
200
|
+
if (reason === 'unreadable-transport') {
|
|
201
|
+
return 'was left untouched: its transport could not be read';
|
|
202
|
+
}
|
|
203
|
+
return null;
|
|
204
|
+
}
|
|
205
|
+
function explainProblem(problem) {
|
|
206
|
+
if (problem === 'jsonc') {
|
|
207
|
+
return 'contains comments or trailing commas, which cannot be rewritten without dropping them — wrap its servers by hand, or remove the comments';
|
|
208
|
+
}
|
|
209
|
+
if (problem === 'unparseable')
|
|
210
|
+
return 'is not valid JSON; left untouched';
|
|
211
|
+
if (problem === 'not-an-object')
|
|
212
|
+
return 'is valid JSON but not an object; left untouched';
|
|
213
|
+
return 'could not be read; left untouched';
|
|
214
|
+
}
|
|
215
|
+
//# sourceMappingURL=sync.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sync.js","sourceRoot":"","sources":["../../../src/commands/mcp/sync.ts"],"names":[],"mappings":"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"}
|
package/dist/config.js
CHANGED
|
@@ -48,5 +48,11 @@ export const HOOK_DEFAULTS = {
|
|
|
48
48
|
// the files it changed (cybe_scan_diff) before the user commits. Opt-out at
|
|
49
49
|
// install. Rides on session-review, so it only fires when that hook is on.
|
|
50
50
|
enableDiffScan: true,
|
|
51
|
+
// BACK-174 — `auto` keeps git-origin auto-discovery (VibeDefend lights up on
|
|
52
|
+
// every repo of the machine that is a CybeDefend project). `opt-in` limits
|
|
53
|
+
// the hooks to repos that carry `.cybedefend/config.json` (or
|
|
54
|
+
// CYBEDEFEND_PROJECT_ID). Default stays `auto` so existing installs keep
|
|
55
|
+
// their behaviour; the installer asks.
|
|
56
|
+
activation: 'auto',
|
|
51
57
|
};
|
|
52
58
|
//# sourceMappingURL=config.js.map
|
package/dist/config.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AA0CA,MAAM,CAAC,MAAM,OAAO,GAA4B;IAC9C;QACE,EAAE,EAAE,IAAI;QACR,KAAK,EAAE,iBAAiB;QACxB,WAAW,EACT,kFAAkF;QACpF,MAAM,EAAE,mCAAmC;QAC3C,OAAO,EAAE,+BAA+B;QACxC,OAAO,EAAE,YAAY;QACrB,GAAG,EAAE,KAAK;QACV,YAAY,EAAE,2BAA2B;KAC1C;IACD;QACE,EAAE,EAAE,IAAI;QACR,KAAK,EAAE,iBAAiB;QACxB,WAAW,EACT,0EAA0E;QAC5E,MAAM,EAAE,mCAAmC;QAC3C,OAAO,EAAE,+BAA+B;QACxC,OAAO,EAAE,YAAY;QACrB,GAAG,EAAE,KAAK;QACV,YAAY,EAAE,2BAA2B;KAC1C;CACO,CAAC;AAEX;;;;;;;;;;;;;GAaG;AACH,MAAM,CAAC,MAAM,aAAa,GAAG;IAC3B,mBAAmB,EAAE,IAAI;IACzB,eAAe,EAAE,CAAC;IAClB,eAAe,EAAE,KAAK;IACtB,4EAA4E;IAC5E,6EAA6E;IAC7E,6EAA6E;IAC7E,sEAAsE;IACtE,eAAe,EAAE,KAAK;IACtB,UAAU,EAAE,IAAI;IAChB,2EAA2E;IAC3E,4EAA4E;IAC5E,2EAA2E;IAC3E,cAAc,EAAE,IAAI;IACpB,6EAA6E;IAC7E,2EAA2E;IAC3E,8DAA8D;IAC9D,yEAAyE;IACzE,uCAAuC;IACvC,UAAU,EAAE,MAAwB;CAC5B,CAAC"}
|