@i4ctime/q-ring 0.14.0 → 0.15.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/dist/mcp.js CHANGED
@@ -39,7 +39,7 @@ import {
39
39
  tunnelList,
40
40
  tunnelRead,
41
41
  verifyAuditChain
42
- } from "./chunk-NNIEXAW5.js";
42
+ } from "./chunk-TPPPTL4J.js";
43
43
 
44
44
  // src/mcp.ts
45
45
  import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
@@ -805,6 +805,79 @@ var ProviderRegistry = class {
805
805
  return [...this.providers.values()];
806
806
  }
807
807
  };
808
+ function livenessProvider(cfg) {
809
+ return {
810
+ name: cfg.name,
811
+ description: cfg.description,
812
+ prefixes: cfg.prefixes,
813
+ async validate(value) {
814
+ const start = Date.now();
815
+ try {
816
+ const { statusCode } = await makeRequest(cfg.url, {
817
+ "User-Agent": "q-ring-validator/1.0",
818
+ ...cfg.headers(value)
819
+ });
820
+ const latencyMs = Date.now() - start;
821
+ if (statusCode === 200)
822
+ return { valid: true, status: "valid", message: "API key is valid", latencyMs, provider: cfg.name };
823
+ if (statusCode === 401 || statusCode === 403)
824
+ return { valid: false, status: "invalid", message: `Invalid or revoked API key (${statusCode})`, latencyMs, provider: cfg.name };
825
+ if (statusCode === 429)
826
+ return { valid: true, status: "error", message: "Rate limited \u2014 key may be valid", latencyMs, provider: cfg.name };
827
+ return { valid: false, status: "error", message: `Unexpected status ${statusCode}`, latencyMs, provider: cfg.name };
828
+ } catch (err) {
829
+ return { valid: false, status: "error", message: `${err instanceof Error ? err.message : "Network error"}`, latencyMs: Date.now() - start, provider: cfg.name };
830
+ }
831
+ }
832
+ };
833
+ }
834
+ var anthropicProvider = livenessProvider({
835
+ name: "anthropic",
836
+ description: "Anthropic API key validation",
837
+ prefixes: ["sk-ant-"],
838
+ url: "https://api.anthropic.com/v1/models?limit=1",
839
+ headers: (value) => ({ "x-api-key": value, "anthropic-version": "2023-06-01" })
840
+ });
841
+ var openrouterProvider = livenessProvider({
842
+ name: "openrouter",
843
+ description: "OpenRouter API key validation",
844
+ prefixes: ["sk-or-"],
845
+ url: "https://openrouter.ai/api/v1/key",
846
+ headers: (value) => ({ Authorization: `Bearer ${value}` })
847
+ });
848
+ var googleAiProvider = livenessProvider({
849
+ name: "google-ai",
850
+ description: "Google AI (Gemini) API key validation",
851
+ prefixes: ["AIza"],
852
+ url: "https://generativelanguage.googleapis.com/v1beta/models?pageSize=1",
853
+ headers: (value) => ({ "x-goog-api-key": value })
854
+ });
855
+ var groqProvider = livenessProvider({
856
+ name: "groq",
857
+ description: "Groq API key validation",
858
+ prefixes: ["gsk_"],
859
+ url: "https://api.groq.com/openai/v1/models",
860
+ headers: (value) => ({ Authorization: `Bearer ${value}` })
861
+ });
862
+ var huggingfaceProvider = livenessProvider({
863
+ name: "huggingface",
864
+ description: "Hugging Face token validation",
865
+ prefixes: ["hf_"],
866
+ url: "https://huggingface.co/api/whoami-v2",
867
+ headers: (value) => ({ Authorization: `Bearer ${value}` })
868
+ });
869
+ var elevenlabsProvider = livenessProvider({
870
+ name: "elevenlabs",
871
+ description: "ElevenLabs API key validation (explicit-only \u2014 set provider on the secret)",
872
+ url: "https://api.elevenlabs.io/v1/user",
873
+ headers: (value) => ({ "xi-api-key": value })
874
+ });
875
+ var vercelProvider = livenessProvider({
876
+ name: "vercel",
877
+ description: "Vercel token validation (explicit-only \u2014 set provider on the secret)",
878
+ url: "https://api.vercel.com/v2/user",
879
+ headers: (value) => ({ Authorization: `Bearer ${value}` })
880
+ });
808
881
  var openaiProvider = {
809
882
  name: "openai",
810
883
  description: "OpenAI API key validation",
@@ -931,7 +1004,14 @@ var httpProvider = {
931
1004
  }
932
1005
  };
933
1006
  var registry2 = new ProviderRegistry();
1007
+ registry2.register(anthropicProvider);
1008
+ registry2.register(openrouterProvider);
934
1009
  registry2.register(openaiProvider);
1010
+ registry2.register(googleAiProvider);
1011
+ registry2.register(groqProvider);
1012
+ registry2.register(huggingfaceProvider);
1013
+ registry2.register(elevenlabsProvider);
1014
+ registry2.register(vercelProvider);
935
1015
  registry2.register(stripeProvider);
936
1016
  registry2.register(githubProvider);
937
1017
  registry2.register(awsProvider);
@@ -2148,10 +2228,9 @@ var RedactionTransform = class extends Transform {
2148
2228
  callback();
2149
2229
  }
2150
2230
  };
2151
- async function execCommand(opts2) {
2152
- const profile = getProfile(opts2.profile);
2153
- const fullCommand = [opts2.command, ...opts2.args].join(" ");
2154
- const policyDecision = checkExecPolicy(fullCommand, opts2.projectPath);
2231
+ function enforceExecPolicy(profile, command, args, projectPath8) {
2232
+ const fullCommand = [command, ...args].join(" ");
2233
+ const policyDecision = checkExecPolicy(fullCommand, projectPath8);
2155
2234
  if (!policyDecision.allowed) {
2156
2235
  throw new Error(`Policy Denied: ${policyDecision.reason}`);
2157
2236
  }
@@ -2167,9 +2246,13 @@ async function execCommand(opts2) {
2167
2246
  if (profile.allowCommands) {
2168
2247
  const allowed = profile.allowCommands.some((a) => fullCommand.startsWith(a));
2169
2248
  if (!allowed) {
2170
- throw new Error(`Exec profile "${profile.name}" does not allow command "${opts2.command}"`);
2249
+ throw new Error(`Exec profile "${profile.name}" does not allow command "${command}"`);
2171
2250
  }
2172
2251
  }
2252
+ }
2253
+ async function execCommand(opts2) {
2254
+ const profile = getProfile(opts2.profile);
2255
+ enforceExecPolicy(profile, opts2.command, opts2.args, opts2.projectPath);
2173
2256
  const envMap = {};
2174
2257
  for (const [k, v] of Object.entries(process.env)) {
2175
2258
  if (v !== void 0) envMap[k] = v;
@@ -2216,6 +2299,18 @@ async function execCommand(opts2) {
2216
2299
  }
2217
2300
  }
2218
2301
  }
2302
+ return spawnRedacted({
2303
+ profile,
2304
+ command: opts2.command,
2305
+ args: opts2.args,
2306
+ envMap,
2307
+ secretsToRedact: [...secretsToRedact],
2308
+ captureOutput: opts2.captureOutput,
2309
+ projectPath: opts2.projectPath
2310
+ });
2311
+ }
2312
+ function spawnRedacted(opts2) {
2313
+ const { profile, secretsToRedact, envMap } = opts2;
2219
2314
  const maxRuntime = profile.maxRuntimeSeconds ?? getExecMaxRuntime(opts2.projectPath);
2220
2315
  return new Promise((resolve, reject) => {
2221
2316
  const networkTools = /* @__PURE__ */ new Set([
@@ -2700,7 +2795,7 @@ ${result.stderr}`);
2700
2795
  `Dashboard already running at ${dashboardInstance.url}`
2701
2796
  );
2702
2797
  }
2703
- const { startDashboardServer } = await import("./dashboard-KAUEPLXO.js");
2798
+ const { startDashboardServer } = await import("./dashboard-TFWCG23R.js");
2704
2799
  dashboardInstance = startDashboardServer({ port: params.port });
2705
2800
  return text(
2706
2801
  `Dashboard started at ${dashboardInstance.url}