@i4ctime/q-ring 0.14.1 → 0.16.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 +114 -2
- package/dist/{chunk-C2TFJ2EH.js → chunk-5LFKBZ3Q.js} +383 -125
- package/dist/chunk-5LFKBZ3Q.js.map +1 -0
- package/dist/{chunk-NNIEXAW5.js → chunk-NCM5GHNW.js} +380 -122
- package/dist/chunk-NCM5GHNW.js.map +1 -0
- package/dist/{dashboard-KAUEPLXO.js → dashboard-A3GJQCJX.js} +2 -2
- package/dist/{dashboard-PYYAED45.js → dashboard-R3FWTFFW.js} +2 -2
- package/dist/index.js +930 -19
- package/dist/index.js.map +1 -1
- package/dist/mcp.js +110 -8
- package/dist/mcp.js.map +1 -1
- package/package.json +6 -4
- package/dist/chunk-C2TFJ2EH.js.map +0 -1
- package/dist/chunk-NNIEXAW5.js.map +0 -1
- /package/dist/{dashboard-KAUEPLXO.js.map → dashboard-A3GJQCJX.js.map} +0 -0
- /package/dist/{dashboard-PYYAED45.js.map → dashboard-R3FWTFFW.js.map} +0 -0
package/dist/mcp.js
CHANGED
|
@@ -32,6 +32,7 @@ import {
|
|
|
32
32
|
registry,
|
|
33
33
|
remember,
|
|
34
34
|
removeHook,
|
|
35
|
+
setAuditAgentLabel,
|
|
35
36
|
setPolicyRoot,
|
|
36
37
|
setSecret,
|
|
37
38
|
tunnelCreate,
|
|
@@ -39,7 +40,7 @@ import {
|
|
|
39
40
|
tunnelList,
|
|
40
41
|
tunnelRead,
|
|
41
42
|
verifyAuditChain
|
|
42
|
-
} from "./chunk-
|
|
43
|
+
} from "./chunk-NCM5GHNW.js";
|
|
43
44
|
|
|
44
45
|
// src/mcp.ts
|
|
45
46
|
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
|
|
@@ -805,6 +806,79 @@ var ProviderRegistry = class {
|
|
|
805
806
|
return [...this.providers.values()];
|
|
806
807
|
}
|
|
807
808
|
};
|
|
809
|
+
function livenessProvider(cfg) {
|
|
810
|
+
return {
|
|
811
|
+
name: cfg.name,
|
|
812
|
+
description: cfg.description,
|
|
813
|
+
prefixes: cfg.prefixes,
|
|
814
|
+
async validate(value) {
|
|
815
|
+
const start = Date.now();
|
|
816
|
+
try {
|
|
817
|
+
const { statusCode } = await makeRequest(cfg.url, {
|
|
818
|
+
"User-Agent": "q-ring-validator/1.0",
|
|
819
|
+
...cfg.headers(value)
|
|
820
|
+
});
|
|
821
|
+
const latencyMs = Date.now() - start;
|
|
822
|
+
if (statusCode === 200)
|
|
823
|
+
return { valid: true, status: "valid", message: "API key is valid", latencyMs, provider: cfg.name };
|
|
824
|
+
if (statusCode === 401 || statusCode === 403)
|
|
825
|
+
return { valid: false, status: "invalid", message: `Invalid or revoked API key (${statusCode})`, latencyMs, provider: cfg.name };
|
|
826
|
+
if (statusCode === 429)
|
|
827
|
+
return { valid: true, status: "error", message: "Rate limited \u2014 key may be valid", latencyMs, provider: cfg.name };
|
|
828
|
+
return { valid: false, status: "error", message: `Unexpected status ${statusCode}`, latencyMs, provider: cfg.name };
|
|
829
|
+
} catch (err) {
|
|
830
|
+
return { valid: false, status: "error", message: `${err instanceof Error ? err.message : "Network error"}`, latencyMs: Date.now() - start, provider: cfg.name };
|
|
831
|
+
}
|
|
832
|
+
}
|
|
833
|
+
};
|
|
834
|
+
}
|
|
835
|
+
var anthropicProvider = livenessProvider({
|
|
836
|
+
name: "anthropic",
|
|
837
|
+
description: "Anthropic API key validation",
|
|
838
|
+
prefixes: ["sk-ant-"],
|
|
839
|
+
url: "https://api.anthropic.com/v1/models?limit=1",
|
|
840
|
+
headers: (value) => ({ "x-api-key": value, "anthropic-version": "2023-06-01" })
|
|
841
|
+
});
|
|
842
|
+
var openrouterProvider = livenessProvider({
|
|
843
|
+
name: "openrouter",
|
|
844
|
+
description: "OpenRouter API key validation",
|
|
845
|
+
prefixes: ["sk-or-"],
|
|
846
|
+
url: "https://openrouter.ai/api/v1/key",
|
|
847
|
+
headers: (value) => ({ Authorization: `Bearer ${value}` })
|
|
848
|
+
});
|
|
849
|
+
var googleAiProvider = livenessProvider({
|
|
850
|
+
name: "google-ai",
|
|
851
|
+
description: "Google AI (Gemini) API key validation",
|
|
852
|
+
prefixes: ["AIza"],
|
|
853
|
+
url: "https://generativelanguage.googleapis.com/v1beta/models?pageSize=1",
|
|
854
|
+
headers: (value) => ({ "x-goog-api-key": value })
|
|
855
|
+
});
|
|
856
|
+
var groqProvider = livenessProvider({
|
|
857
|
+
name: "groq",
|
|
858
|
+
description: "Groq API key validation",
|
|
859
|
+
prefixes: ["gsk_"],
|
|
860
|
+
url: "https://api.groq.com/openai/v1/models",
|
|
861
|
+
headers: (value) => ({ Authorization: `Bearer ${value}` })
|
|
862
|
+
});
|
|
863
|
+
var huggingfaceProvider = livenessProvider({
|
|
864
|
+
name: "huggingface",
|
|
865
|
+
description: "Hugging Face token validation",
|
|
866
|
+
prefixes: ["hf_"],
|
|
867
|
+
url: "https://huggingface.co/api/whoami-v2",
|
|
868
|
+
headers: (value) => ({ Authorization: `Bearer ${value}` })
|
|
869
|
+
});
|
|
870
|
+
var elevenlabsProvider = livenessProvider({
|
|
871
|
+
name: "elevenlabs",
|
|
872
|
+
description: "ElevenLabs API key validation (explicit-only \u2014 set provider on the secret)",
|
|
873
|
+
url: "https://api.elevenlabs.io/v1/user",
|
|
874
|
+
headers: (value) => ({ "xi-api-key": value })
|
|
875
|
+
});
|
|
876
|
+
var vercelProvider = livenessProvider({
|
|
877
|
+
name: "vercel",
|
|
878
|
+
description: "Vercel token validation (explicit-only \u2014 set provider on the secret)",
|
|
879
|
+
url: "https://api.vercel.com/v2/user",
|
|
880
|
+
headers: (value) => ({ Authorization: `Bearer ${value}` })
|
|
881
|
+
});
|
|
808
882
|
var openaiProvider = {
|
|
809
883
|
name: "openai",
|
|
810
884
|
description: "OpenAI API key validation",
|
|
@@ -931,7 +1005,14 @@ var httpProvider = {
|
|
|
931
1005
|
}
|
|
932
1006
|
};
|
|
933
1007
|
var registry2 = new ProviderRegistry();
|
|
1008
|
+
registry2.register(anthropicProvider);
|
|
1009
|
+
registry2.register(openrouterProvider);
|
|
934
1010
|
registry2.register(openaiProvider);
|
|
1011
|
+
registry2.register(googleAiProvider);
|
|
1012
|
+
registry2.register(groqProvider);
|
|
1013
|
+
registry2.register(huggingfaceProvider);
|
|
1014
|
+
registry2.register(elevenlabsProvider);
|
|
1015
|
+
registry2.register(vercelProvider);
|
|
935
1016
|
registry2.register(stripeProvider);
|
|
936
1017
|
registry2.register(githubProvider);
|
|
937
1018
|
registry2.register(awsProvider);
|
|
@@ -1569,7 +1650,9 @@ function registerAuditTools(server2) {
|
|
|
1569
1650
|
"entangle",
|
|
1570
1651
|
"tunnel",
|
|
1571
1652
|
"teleport",
|
|
1572
|
-
"collapse"
|
|
1653
|
+
"collapse",
|
|
1654
|
+
"canary",
|
|
1655
|
+
"wrap"
|
|
1573
1656
|
]).optional().describe(
|
|
1574
1657
|
"Limit to a single action verb (e.g. 'read' to see only reads). Omit for all actions."
|
|
1575
1658
|
),
|
|
@@ -2148,10 +2231,9 @@ var RedactionTransform = class extends Transform {
|
|
|
2148
2231
|
callback();
|
|
2149
2232
|
}
|
|
2150
2233
|
};
|
|
2151
|
-
|
|
2152
|
-
const
|
|
2153
|
-
const
|
|
2154
|
-
const policyDecision = checkExecPolicy(fullCommand, opts2.projectPath);
|
|
2234
|
+
function enforceExecPolicy(profile, command, args, projectPath8) {
|
|
2235
|
+
const fullCommand = [command, ...args].join(" ");
|
|
2236
|
+
const policyDecision = checkExecPolicy(fullCommand, projectPath8);
|
|
2155
2237
|
if (!policyDecision.allowed) {
|
|
2156
2238
|
throw new Error(`Policy Denied: ${policyDecision.reason}`);
|
|
2157
2239
|
}
|
|
@@ -2167,9 +2249,13 @@ async function execCommand(opts2) {
|
|
|
2167
2249
|
if (profile.allowCommands) {
|
|
2168
2250
|
const allowed = profile.allowCommands.some((a) => fullCommand.startsWith(a));
|
|
2169
2251
|
if (!allowed) {
|
|
2170
|
-
throw new Error(`Exec profile "${profile.name}" does not allow command "${
|
|
2252
|
+
throw new Error(`Exec profile "${profile.name}" does not allow command "${command}"`);
|
|
2171
2253
|
}
|
|
2172
2254
|
}
|
|
2255
|
+
}
|
|
2256
|
+
async function execCommand(opts2) {
|
|
2257
|
+
const profile = getProfile(opts2.profile);
|
|
2258
|
+
enforceExecPolicy(profile, opts2.command, opts2.args, opts2.projectPath);
|
|
2173
2259
|
const envMap = {};
|
|
2174
2260
|
for (const [k, v] of Object.entries(process.env)) {
|
|
2175
2261
|
if (v !== void 0) envMap[k] = v;
|
|
@@ -2216,6 +2302,18 @@ async function execCommand(opts2) {
|
|
|
2216
2302
|
}
|
|
2217
2303
|
}
|
|
2218
2304
|
}
|
|
2305
|
+
return spawnRedacted({
|
|
2306
|
+
profile,
|
|
2307
|
+
command: opts2.command,
|
|
2308
|
+
args: opts2.args,
|
|
2309
|
+
envMap,
|
|
2310
|
+
secretsToRedact: [...secretsToRedact],
|
|
2311
|
+
captureOutput: opts2.captureOutput,
|
|
2312
|
+
projectPath: opts2.projectPath
|
|
2313
|
+
});
|
|
2314
|
+
}
|
|
2315
|
+
function spawnRedacted(opts2) {
|
|
2316
|
+
const { profile, secretsToRedact, envMap } = opts2;
|
|
2219
2317
|
const maxRuntime = profile.maxRuntimeSeconds ?? getExecMaxRuntime(opts2.projectPath);
|
|
2220
2318
|
return new Promise((resolve, reject) => {
|
|
2221
2319
|
const networkTools = /* @__PURE__ */ new Set([
|
|
@@ -2700,7 +2798,7 @@ ${result.stderr}`);
|
|
|
2700
2798
|
`Dashboard already running at ${dashboardInstance.url}`
|
|
2701
2799
|
);
|
|
2702
2800
|
}
|
|
2703
|
-
const { startDashboardServer } = await import("./dashboard-
|
|
2801
|
+
const { startDashboardServer } = await import("./dashboard-R3FWTFFW.js");
|
|
2704
2802
|
dashboardInstance = startDashboardServer({ port: params.port });
|
|
2705
2803
|
return text(
|
|
2706
2804
|
`Dashboard started at ${dashboardInstance.url}
|
|
@@ -2899,6 +2997,10 @@ function createMcpServer() {
|
|
|
2899
2997
|
version: PACKAGE_VERSION
|
|
2900
2998
|
});
|
|
2901
2999
|
registerMcpTools(server2);
|
|
3000
|
+
server2.server.oninitialized = () => {
|
|
3001
|
+
const info = server2.server.getClientVersion();
|
|
3002
|
+
if (info) setAuditAgentLabel(`${info.name}@${info.version}`);
|
|
3003
|
+
};
|
|
2902
3004
|
return server2;
|
|
2903
3005
|
}
|
|
2904
3006
|
|