@prooflane/inspector-beta 0.1.0-beta.6 → 0.1.0-beta.7

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/server.mjs CHANGED
@@ -4225,7 +4225,7 @@ function validateGovernedGateManifest(value) {
4225
4225
  if (!record2(value))
4226
4226
  return { ok: !1, error: "Gate manifest must be an object." };
4227
4227
  let forbidden = findForbiddenGateManifestMaterial(value);
4228
- return forbidden ? { ok: !1, error: `Gate manifest rejected: ${forbidden}.` } : exactKeys(value, ["schemaVersion", "suiteRef", "policyRef", "targetScope", "environment", "requiredPillars", "settings", "approvalRules"]) ? value.schemaVersion !== GATE_MANIFEST_VERSION ? { ok: !1, error: `Gate manifest must use ${GATE_MANIFEST_VERSION}.` } : validateSuiteReference(value.suiteRef) ? validatePolicyReference(value.policyRef) ? !record2(value.targetScope) || !exactKeys(value.targetScope, ["projectId"]) || !text2(value.targetScope.projectId, 2, 128, projectPattern) ? { ok: !1, error: "Gate targetScope must contain one stable projectId." } : text2(value.environment, 2, 64, slugPattern) ? !Array.isArray(value.requiredPillars) || value.requiredPillars.length < 1 || value.requiredPillars.length > POLICY_PILLARS.length ? { ok: !1, error: "Gate requiredPillars must contain at least one supported Policy pillar." } : value.requiredPillars.every((pillar) => POLICY_PILLARS.includes(pillar)) ? new Set(value.requiredPillars).size !== value.requiredPillars.length ? { ok: !1, error: "Gate requiredPillars must be unique." } : !record2(value.settings) || !exactKeys(value.settings, ["executionMode", "evidenceSync"]) || value.settings.executionMode !== "ALL_CONTROLS" || value.settings.evidenceSync !== "COMPACT_ONLY" ? { ok: !1, error: "Gate settings must execute all signed Suite controls and synchronize compact evidence only." } : !record2(value.approvalRules) || !exactKeys(value.approvalRules, ["minimumApprovals", "requireDistinctReviewer"]) || value.approvalRules.minimumApprovals !== 1 || value.approvalRules.requireDistinctReviewer !== !0 ? { ok: !1, error: "Gate approvalRules must require one approval from a distinct reviewer." } : { ok: !0, manifest: value } : { ok: !1, error: "Gate requiredPillars contains an unsupported pillar." } : { ok: !1, error: "Gate environment must be a bounded lowercase slug." } : { ok: !1, error: "Gate policyRef must pin an exact Policy identity, version ID, version, and SHA-256 hash." } : { ok: !1, error: "Gate suiteRef must pin an exact Suite identity, slug, version ID, version, and SHA-256 hash." } : { ok: !1, error: "Gate manifest must contain only the frozen v1 fields." };
4228
+ return forbidden ? { ok: !1, error: `Gate manifest rejected: ${forbidden}.` } : exactKeys(value, ["schemaVersion", "suiteRef", "policyRef", "targetScope", "environment", "requiredPillars", "settings", "approvalRules"]) ? value.schemaVersion !== GATE_MANIFEST_VERSION ? { ok: !1, error: `Gate manifest must use ${GATE_MANIFEST_VERSION}.` } : validateSuiteReference(value.suiteRef) ? validatePolicyReference(value.policyRef) ? !record2(value.targetScope) || !exactKeys(value.targetScope, ["projectId"]) || !text2(value.targetScope.projectId, 2, 128, projectPattern) ? { ok: !1, error: "Gate targetScope must contain one stable projectId." } : text2(value.environment, 2, 64, slugPattern) ? !Array.isArray(value.requiredPillars) || value.requiredPillars.length < 1 || value.requiredPillars.length > POLICY_PILLARS.length ? { ok: !1, error: "Gate requiredPillars must contain at least one supported Policy pillar." } : value.requiredPillars.every((pillar) => POLICY_PILLARS.includes(pillar)) ? new Set(value.requiredPillars).size !== value.requiredPillars.length ? { ok: !1, error: "Gate requiredPillars must be unique." } : !record2(value.settings) || !exactKeys(value.settings, ["executionMode", "evidenceSync"]) || value.settings.executionMode !== "ALL_CONTROLS" || value.settings.evidenceSync !== "COMPACT_ONLY" ? { ok: !1, error: "Gate settings must execute all signed Suite controls and synchronize compact evidence only." } : !record2(value.approvalRules) || !exactKeys(value.approvalRules, ["minimumApprovals", "requireDistinctReviewer"]) || value.approvalRules.minimumApprovals !== 1 || typeof value.approvalRules.requireDistinctReviewer != "boolean" ? { ok: !1, error: "Gate approvalRules must require one recorded approval and a boolean reviewer policy." } : { ok: !0, manifest: value } : { ok: !1, error: "Gate requiredPillars contains an unsupported pillar." } : { ok: !1, error: "Gate environment must be a bounded lowercase slug." } : { ok: !1, error: "Gate policyRef must pin an exact Policy identity, version ID, version, and SHA-256 hash." } : { ok: !1, error: "Gate suiteRef must pin an exact Suite identity, slug, version ID, version, and SHA-256 hash." } : { ok: !1, error: "Gate manifest must contain only the frozen v1 fields." };
4229
4229
  }
4230
4230
  function hashGovernedGateManifest(value) {
4231
4231
  let validated = validateGovernedGateManifest(value);
@@ -11624,8 +11624,8 @@ function publicServerError(path) {
11624
11624
  }
11625
11625
  var HOSTED_SAMMY_AUTHORIZATION = Symbol("prooflane.hosted-sammy-authorization");
11626
11626
  function buildApp() {
11627
- let app2 = Fastify({ logger: !1 });
11628
- app2.addHook("onSend", async (request, reply, payload) => !request.url.startsWith("/api") || reply.statusCode < 500 ? payload : (reply.header("cache-control", "no-store"), reply.type("application/json; charset=utf-8"), JSON.stringify({ error: publicServerError(request.url), reference: request.id })));
11627
+ let app = Fastify({ logger: !1 });
11628
+ app.addHook("onSend", async (request, reply, payload) => !request.url.startsWith("/api") || reply.statusCode < 500 ? payload : (reply.header("cache-control", "no-store"), reply.type("application/json; charset=utf-8"), JSON.stringify({ error: publicServerError(request.url), reference: request.id })));
11629
11629
  let store = new Store(dbPath()), svc = new InspectorService(store), mcpManager = new McpConnectionManager(() => new InspectorService(store), store), env = (process.env.KAWACH_ENV ?? process.env.NODE_ENV ?? "production").toLowerCase(), isDev = env === "dev" || env === "development", intelligenceMode = PUBLIC_RUNNER_BUILD || process.env.KAWACH_INTELLIGENCE_MODE === "hosted" ? "hosted" : "legacy", AUTH0_DOMAIN = process.env.AUTH0_DOMAIN, AUTH0_CLIENT_ID = process.env.AUTH0_CLIENT_ID, AUTH0_AUDIENCE = process.env.AUTH0_AUDIENCE, CONTROL_PLANE_URL = process.env.KAWACH_CONTROL_PLANE_URL?.replace(/\/$/, ""), PROOFLANE_PROJECT = (process.env.PROOFLANE_PROJECT ?? "default").trim(), configuredNumber = (name, fallback, minimum, maximum) => {
11630
11630
  let value = Number(process.env[name]);
11631
11631
  return Number.isFinite(value) ? Math.max(minimum, Math.min(maximum, value)) : fallback;
@@ -11725,10 +11725,19 @@ function buildApp() {
11725
11725
  method,
11726
11726
  headers: body === void 0 ? { authorization } : { authorization, "content-type": "application/json" },
11727
11727
  body: body === void 0 ? void 0 : JSON.stringify(body)
11728
- }), text6 = await response.text(), payload = text6 ? JSON.parse(text6) : null;
11729
- return response.ok && await onSuccess?.(payload), reply.code(response.status).send(payload);
11730
- } catch {
11731
- return reply.code(502).send({ error: "Prooflane Cloud Workspace could not be reached. Check KAWACH_CONTROL_PLANE_URL and your connection." });
11728
+ }), text6 = await response.text(), payload = null;
11729
+ if (text6)
11730
+ try {
11731
+ payload = JSON.parse(text6);
11732
+ } catch {
11733
+ if (response.ok)
11734
+ return reply.code(502).send({ error: "Prooflane Cloud Workspace returned an invalid response." });
11735
+ payload = response.status === 404 ? { error: "The deployed Prooflane control plane does not support this Inspector route yet. Deploy the matching control-plane build, then retry.", upgrade: !0 } : { error: `Prooflane Cloud request failed (${response.status}).` };
11736
+ }
11737
+ let upstreamError = payload && typeof payload == "object" && typeof payload.error == "string" ? String(payload.error).trim() : "";
11738
+ return !response.ok && response.status === 404 && (!upstreamError || /^not found$/i.test(upstreamError) || /route.*not found/i.test(upstreamError)) && (payload = { error: "The deployed Prooflane control plane does not support this Inspector route yet. Deploy the matching control-plane build, then retry.", upgrade: !0 }), response.ok && await onSuccess?.(payload), reply.code(response.status).send(payload);
11739
+ } catch (error) {
11740
+ return error instanceof SyntaxError ? reply.code(502).send({ error: "Prooflane Cloud Workspace returned an invalid response." }) : reply.code(502).send({ error: "Prooflane Cloud Workspace could not be reached. Check KAWACH_CONTROL_PLANE_URL and your connection." });
11732
11741
  }
11733
11742
  }
11734
11743
  async function requestControlPlaneJson(req, path, method = "GET", body, idempotencyKey) {
@@ -11745,9 +11754,19 @@ function buildApp() {
11745
11754
  } catch {
11746
11755
  throw new ControlPlaneRequestError(502, "Prooflane Cloud Workspace could not be reached.");
11747
11756
  }
11748
- let text6 = await response.text(), payload = text6 ? JSON.parse(text6) : {};
11749
- if (!response.ok)
11750
- throw new ControlPlaneRequestError(response.status, typeof payload.error == "string" ? String(payload.error).slice(0, 300) : "Prooflane Cloud request failed.");
11757
+ let text6 = await response.text(), payload;
11758
+ try {
11759
+ payload = text6 ? JSON.parse(text6) : {};
11760
+ } catch {
11761
+ if (response.ok)
11762
+ throw new ControlPlaneRequestError(502, "Prooflane Cloud Workspace returned an invalid response.");
11763
+ let message2 = response.status === 404 ? "The deployed Prooflane control plane does not support this Inspector route yet. Deploy the matching control-plane build, then retry." : `Prooflane Cloud request failed (${response.status}).`;
11764
+ throw new ControlPlaneRequestError(response.status, message2);
11765
+ }
11766
+ if (!response.ok) {
11767
+ let upstreamError = typeof payload.error == "string" ? String(payload.error).trim().slice(0, 300) : "", message2 = response.status === 404 && (!upstreamError || /^not found$/i.test(upstreamError) || /route.*not found/i.test(upstreamError)) ? "The deployed Prooflane control plane does not support this Inspector route yet. Deploy the matching control-plane build, then retry." : upstreamError || "Prooflane Cloud request failed.";
11768
+ throw new ControlPlaneRequestError(response.status, message2);
11769
+ }
11751
11770
  return payload;
11752
11771
  }
11753
11772
  async function cloudPlan(req) {
@@ -11792,7 +11811,7 @@ function buildApp() {
11792
11811
  async function resolvePlan(req) {
11793
11812
  return (await resolvePlanState(req)).plan;
11794
11813
  }
11795
- app2.addHook("preHandler", async (req, reply) => {
11814
+ app.addHook("preHandler", async (req, reply) => {
11796
11815
  if (req.method === "GET" || req.method === "HEAD" || req.method === "OPTIONS")
11797
11816
  return;
11798
11817
  let path = req.url.split("?", 1)[0] ?? req.url;
@@ -11838,17 +11857,54 @@ function buildApp() {
11838
11857
  let p = await resolvePlan(req);
11839
11858
  return { core: p.core, security: p.security, rag: p.rag, deployment: p.deployment, ci: p.ci };
11840
11859
  }
11841
- app2.addHook("onRequest", async (req, reply) => {
11842
- if (intelligenceMode === "hosted" && (/^\/api\/intelligence\/(?:analyze-options|surface|generations|datasets|native-artifacts|effectiveness|learning-candidates|usage)(?:\/|\?|$)/.test(req.url) || /^\/api\/(?:annotations|assurance|boundary)(?:\/|\?|$)/.test(req.url)) && req.raw.method !== "OPTIONS")
11843
- return reply.code(410).send({
11860
+ if (app.addHook("onRequest", async (req, reply) => {
11861
+ if (intelligenceMode === "hosted" && (/^\/api\/intelligence\/(?:effectiveness|learning-candidates)(?:\/|\?|$)/.test(req.url) || /^\/api\/(?:assurance|boundary)(?:\/|\?|$)/.test(req.url)) && req.raw.method !== "OPTIONS")
11862
+ return /^\/api\/assurance\/gates(?:\/|\?|$)/.test(req.url) && reply.header("cache-control", "no-store"), reply.code(410).send({
11844
11863
  ok: !1,
11845
11864
  error: "This feature uses Hosted Intelligence and is unavailable through the retired local route."
11846
11865
  });
11847
11866
  let plan = await resolvePlan(req);
11848
11867
  mcpManager.reconcileEntitlement(PROOFLANE_PROJECT, mcpEntitlementForPlan(plan)), svc.setToolLimit(plan.tools), mcpManager.setToolLimit(PROOFLANE_PROJECT, plan.tools), activeMcpConnectionId && mcpManager.getConnection(PROOFLANE_PROJECT, activeMcpConnectionId)?.status === "ENTITLEMENT_LOCKED" && svc.setToolLimit(0);
11849
- }), app2.addHook("onSend", async (_req, reply) => {
11868
+ }), intelligenceMode === "hosted") {
11869
+ let hostedSurfaceRefreshInFlight = null, relayHostedIntelligenceSurface = async (req, reply, refresh) => {
11870
+ try {
11871
+ refresh && svc.isConnected() && (hostedSurfaceRefreshInFlight ??= svc.refreshCapabilities().finally(() => {
11872
+ hostedSurfaceRefreshInFlight = null;
11873
+ }), await hostedSurfaceRefreshInFlight);
11874
+ let capabilities = svc.getCapabilities();
11875
+ return capabilities ? proxyControlPlane(req, reply, "/v1/intelligence/surface", { capabilities }) : { connected: !1 };
11876
+ } catch (error) {
11877
+ return reply.code(503).send({ error: `MCP discovery refresh failed: ${error instanceof Error ? error.message : String(error)}` });
11878
+ }
11879
+ };
11880
+ app.get("/api/intelligence/surface", async (req, reply) => (reply.header("cache-control", "no-store"), relayHostedIntelligenceSurface(req, reply, !1))), app.post("/api/intelligence/surface/refresh", async (req, reply) => relayHostedIntelligenceSurface(req, reply, !0));
11881
+ let hostedSammyPath = `/v1/projects/${encodeURIComponent(PROOFLANE_PROJECT)}/intelligence`, hostedCapabilities = (reply) => {
11882
+ let capabilities = svc.getCapabilities();
11883
+ return capabilities || (reply.code(409).send({ error: "Connect an MCP target before using Sammy Intelligence." }), null);
11884
+ }, selectedBody = (value, keys) => {
11885
+ if (!value || typeof value != "object" || Array.isArray(value))
11886
+ return {};
11887
+ let source = value;
11888
+ return Object.fromEntries(keys.filter((key) => source[key] !== void 0).map((key) => [key, source[key]]));
11889
+ };
11890
+ app.post("/api/intelligence/analyze-options", async (req, reply) => {
11891
+ let capabilities = hostedCapabilities(reply);
11892
+ if (capabilities)
11893
+ return proxyControlPlane(req, reply, `${hostedSammyPath}/analyze-options`, { ...selectedBody(req.body, ["graphVersion"]), capabilities });
11894
+ }), app.post("/api/intelligence/generations", async (req, reply) => {
11895
+ let capabilities = hostedCapabilities(reply);
11896
+ if (capabilities)
11897
+ return proxyControlPlane(req, reply, `${hostedSammyPath}/generations`, { ...selectedBody(req.body, ["idempotencyKey", "strategy", "sammyEnabled", "selectedRecommendationIds", "datasetVersionRefs", "promptBundleVersion"]), capabilities });
11898
+ }), app.get("/api/intelligence/generations/:id", async (req, reply) => proxyControlPlane(req, reply, `${hostedSammyPath}/generations/${encodeURIComponent(req.params.id)}`, void 0, "GET")), app.post("/api/intelligence/generations/:id/review", async (req, reply) => proxyControlPlane(req, reply, `${hostedSammyPath}/generations/${encodeURIComponent(req.params.id)}/review`, {})), app.post("/api/intelligence/generations/:id/approve", async (req, reply) => {
11899
+ let capabilities = hostedCapabilities(reply);
11900
+ if (capabilities)
11901
+ return proxyControlPlane(req, reply, `${hostedSammyPath}/generations/${encodeURIComponent(req.params.id)}/approve`, { ...selectedBody(req.body, ["gateId", "name", "policyVersion"]), capabilities });
11902
+ }), app.post("/api/intelligence/generations/:id/compile-suite", async (req, reply) => proxyControlPlane(req, reply, `${hostedSammyPath}/generations/${encodeURIComponent(req.params.id)}/compile-suite`, {})), app.get("/api/intelligence/usage", async (req, reply) => proxyControlPlane(req, reply, `${hostedSammyPath}/usage`, void 0, "GET")), app.get("/api/intelligence/datasets", async (req, reply) => proxyControlPlane(req, reply, `${hostedSammyPath}/datasets`, void 0, "GET")), app.post("/api/intelligence/datasets", async (req, reply) => proxyControlPlane(req, reply, `${hostedSammyPath}/datasets`, selectedBody(req.body, ["name", "format", "content"]))), app.get("/api/intelligence/native-artifacts", async (req, reply) => proxyControlPlane(req, reply, `${hostedSammyPath}/native-artifacts${req.query.pillar ? `?pillar=${encodeURIComponent(req.query.pillar)}` : ""}`, void 0, "GET")), app.post("/api/intelligence/native-artifacts/:generationId/:testId/review", async (req, reply) => proxyControlPlane(req, reply, `${hostedSammyPath}/native-artifacts/${encodeURIComponent(req.params.generationId)}/${encodeURIComponent(req.params.testId)}/review`, selectedBody(req.body, ["action", "replacement", "trustedGolden"]))), app.post("/api/annotations", async (req, reply) => proxyControlPlane(req, reply, `${hostedSammyPath}/annotations`, selectedBody(req.body, ["targetType", "targetId", "labels", "text", "resolution"]))), app.get("/api/annotations/context", async (req, reply) => proxyControlPlane(req, reply, `${hostedSammyPath}/annotations${req.query.targetId ? `?targetId=${encodeURIComponent(req.query.targetId)}` : ""}`, void 0, "GET"));
11903
+ }
11904
+ app.addHook("onSend", async (_req, reply) => {
11850
11905
  reply.header("x-content-type-options", "nosniff"), reply.header("x-frame-options", "SAMEORIGIN"), reply.header("referrer-policy", "no-referrer"), reply.header("x-permitted-cross-domain-policies", "none");
11851
- }), app2.get("/api/config", async (req) => {
11906
+ }), app.get("/api/config", async (req, reply) => {
11907
+ reply.header("cache-control", "no-store");
11852
11908
  let resolution = await resolvePlanState(req), plan = resolution.plan;
11853
11909
  return {
11854
11910
  env: isDev ? "dev" : "production",
@@ -11898,9 +11954,9 @@ function buildApp() {
11898
11954
  project: { id: PROOFLANE_PROJECT },
11899
11955
  intelligenceMode
11900
11956
  };
11901
- }), app2.post("/api/workspace/consent", async (req, reply) => proxyControlPlane(req, reply, "/v1/workspace/consent", req.body ?? {})), app2.post("/api/ci/token", async (req, reply) => proxyControlPlane(req, reply, "/v1/ci/token", { projectId: PROOFLANE_PROJECT }));
11957
+ }), app.post("/api/workspace/consent", async (req, reply) => proxyControlPlane(req, reply, "/v1/workspace/consent", req.body ?? {})), app.post("/api/ci/token", async (req, reply) => proxyControlPlane(req, reply, "/v1/ci/token", { projectId: PROOFLANE_PROJECT }));
11902
11958
  let githubOidcTrustPath = `/v1/projects/${encodeURIComponent(PROOFLANE_PROJECT)}/github-oidc-trust`;
11903
- app2.get("/api/governance/github-oidc-trust", async (req, reply) => proxyControlPlane(req, reply, githubOidcTrustPath, void 0, "GET")), app2.put("/api/governance/github-oidc-trust", async (req, reply) => proxyControlPlane(req, reply, githubOidcTrustPath, req.body ?? {}, "PUT")), app2.delete("/api/governance/github-oidc-trust", async (req, reply) => proxyControlPlane(req, reply, githubOidcTrustPath, void 0, "DELETE")), app2.post("/api/trial/start", async (req, reply) => proxyControlPlane(req, reply, "/v1/trial/start", {})), app2.get("/api/workspace/status", async (req, reply) => proxyControlPlane(req, reply, "/v1/workspace", void 0, "GET")), app2.get("/api/gate-runs", async (req, reply) => proxyControlPlane(req, reply, `/v1/gate-runs?limit=${encodeURIComponent(req.query.limit ?? "200")}`, void 0, "GET")), app2.post("/api/gate-runs", async (req, reply) => proxyControlPlane(req, reply, "/v1/gate-runs", req.body ?? {})), app2.get("/api/governed-runs", async (req, reply) => proxyControlPlane(req, reply, `/v1/projects/${encodeURIComponent(PROOFLANE_PROJECT)}/runs?limit=${encodeURIComponent(req.query.limit ?? "50")}`, void 0, "GET")), app2.post("/api/intelligence/infer", async (req, reply) => {
11959
+ app.get("/api/governance/github-oidc-trust", async (req, reply) => proxyControlPlane(req, reply, githubOidcTrustPath, void 0, "GET")), app.put("/api/governance/github-oidc-trust", async (req, reply) => proxyControlPlane(req, reply, githubOidcTrustPath, req.body ?? {}, "PUT")), app.delete("/api/governance/github-oidc-trust", async (req, reply) => proxyControlPlane(req, reply, githubOidcTrustPath, void 0, "DELETE")), app.post("/api/trial/start", async (req, reply) => proxyControlPlane(req, reply, "/v1/trial/start", {})), app.get("/api/workspace/status", async (req, reply) => proxyControlPlane(req, reply, "/v1/workspace", void 0, "GET")), app.get("/api/gate-runs", async (req, reply) => proxyControlPlane(req, reply, `/v1/gate-runs?limit=${encodeURIComponent(req.query.limit ?? "200")}`, void 0, "GET")), app.post("/api/gate-runs", async (req, reply) => proxyControlPlane(req, reply, "/v1/gate-runs", req.body ?? {})), app.get("/api/governed-runs", async (req, reply) => proxyControlPlane(req, reply, `/v1/projects/${encodeURIComponent(PROOFLANE_PROJECT)}/runs?limit=${encodeURIComponent(req.query.limit ?? "50")}`, void 0, "GET")), app.post("/api/intelligence/infer", async (req, reply) => {
11904
11960
  let result = await relaySammyInferenceBoundary({
11905
11961
  request: req.body,
11906
11962
  controlPlaneUrl: CONTROL_PLANE_URL,
@@ -11910,7 +11966,7 @@ function buildApp() {
11910
11966
  return reply.code(result.status).send(result.payload);
11911
11967
  });
11912
11968
  let suiteRegistryPath = `/v1/projects/${encodeURIComponent(PROOFLANE_PROJECT)}/suites`;
11913
- app2.get("/api/suites", async (req, reply) => proxyControlPlane(req, reply, suiteRegistryPath, void 0, "GET")), app2.post("/api/suites", async (req, reply) => proxyControlPlane(req, reply, suiteRegistryPath, req.body ?? {})), app2.post("/api/governance/suites/:slug/drift", async (req, reply) => {
11969
+ app.get("/api/suites", async (req, reply) => proxyControlPlane(req, reply, suiteRegistryPath, void 0, "GET")), app.post("/api/suites", async (req, reply) => proxyControlPlane(req, reply, suiteRegistryPath, req.body ?? {})), app.post("/api/governance/suites/:slug/drift", async (req, reply) => {
11914
11970
  try {
11915
11971
  let capabilities = svc.getCapabilities();
11916
11972
  if (!capabilities)
@@ -11939,7 +11995,7 @@ function buildApp() {
11939
11995
  } catch (error) {
11940
11996
  return error instanceof ControlPlaneRequestError ? reply.code(error.status).send({ error: error.message }) : reply.code(500).send({ error: "Governed surface drift assessment could not complete." });
11941
11997
  }
11942
- }), app2.get("/api/suites/:slug", async (req, reply) => proxyControlPlane(req, reply, `${suiteRegistryPath}/${encodeURIComponent(req.params.slug)}`, void 0, "GET")), app2.patch("/api/suites/:slug", async (req, reply) => proxyControlPlane(req, reply, `${suiteRegistryPath}/${encodeURIComponent(req.params.slug)}`, req.body ?? {}, "PATCH")), app2.delete("/api/suites/:slug", async (req, reply) => proxyControlPlane(req, reply, `${suiteRegistryPath}/${encodeURIComponent(req.params.slug)}`, void 0, "DELETE")), app2.post("/api/suites/:slug/versions", async (req, reply) => proxyControlPlane(req, reply, `${suiteRegistryPath}/${encodeURIComponent(req.params.slug)}/versions`, req.body ?? {})), app2.get("/api/suites/:slug/versions/:version", async (req, reply) => proxyControlPlane(req, reply, `${suiteRegistryPath}/${encodeURIComponent(req.params.slug)}/versions/${encodeURIComponent(req.params.version)}`, void 0, "GET")), app2.put("/api/suites/:slug/versions/:version", async (req, reply) => proxyControlPlane(req, reply, `${suiteRegistryPath}/${encodeURIComponent(req.params.slug)}/versions/${encodeURIComponent(req.params.version)}`, req.body ?? {}, "PUT")), app2.post("/api/suites/:slug/versions/:version/review", async (req, reply) => proxyControlPlane(req, reply, `${suiteRegistryPath}/${encodeURIComponent(req.params.slug)}/versions/${encodeURIComponent(req.params.version)}/review`, {})), app2.post("/api/suites/:slug/versions/:version/approve", async (req, reply) => proxyControlPlane(req, reply, `${suiteRegistryPath}/${encodeURIComponent(req.params.slug)}/versions/${encodeURIComponent(req.params.version)}/approve`, {})), app2.post("/api/suites/:slug/versions/:version/deprecate", async (req, reply) => proxyControlPlane(req, reply, `${suiteRegistryPath}/${encodeURIComponent(req.params.slug)}/versions/${encodeURIComponent(req.params.version)}/deprecate`, {})), app2.get("/api/suites/:slug/aliases", async (req, reply) => proxyControlPlane(req, reply, `${suiteRegistryPath}/${encodeURIComponent(req.params.slug)}/aliases`, void 0, "GET")), app2.get("/api/suite-signing-keys/:keyId", async (req, reply) => proxyControlPlane(req, reply, `/v1/projects/${encodeURIComponent(PROOFLANE_PROJECT)}/suite-signing-keys/${encodeURIComponent(req.params.keyId)}`, void 0, "GET"));
11998
+ }), app.get("/api/suites/:slug", async (req, reply) => proxyControlPlane(req, reply, `${suiteRegistryPath}/${encodeURIComponent(req.params.slug)}`, void 0, "GET")), app.patch("/api/suites/:slug", async (req, reply) => proxyControlPlane(req, reply, `${suiteRegistryPath}/${encodeURIComponent(req.params.slug)}`, req.body ?? {}, "PATCH")), app.delete("/api/suites/:slug", async (req, reply) => proxyControlPlane(req, reply, `${suiteRegistryPath}/${encodeURIComponent(req.params.slug)}`, void 0, "DELETE")), app.post("/api/suites/:slug/versions", async (req, reply) => proxyControlPlane(req, reply, `${suiteRegistryPath}/${encodeURIComponent(req.params.slug)}/versions`, req.body ?? {})), app.get("/api/suites/:slug/versions/:version", async (req, reply) => proxyControlPlane(req, reply, `${suiteRegistryPath}/${encodeURIComponent(req.params.slug)}/versions/${encodeURIComponent(req.params.version)}`, void 0, "GET")), app.put("/api/suites/:slug/versions/:version", async (req, reply) => proxyControlPlane(req, reply, `${suiteRegistryPath}/${encodeURIComponent(req.params.slug)}/versions/${encodeURIComponent(req.params.version)}`, req.body ?? {}, "PUT")), app.post("/api/suites/:slug/versions/:version/review", async (req, reply) => proxyControlPlane(req, reply, `${suiteRegistryPath}/${encodeURIComponent(req.params.slug)}/versions/${encodeURIComponent(req.params.version)}/review`, {})), app.post("/api/suites/:slug/versions/:version/approve", async (req, reply) => proxyControlPlane(req, reply, `${suiteRegistryPath}/${encodeURIComponent(req.params.slug)}/versions/${encodeURIComponent(req.params.version)}/approve`, {})), app.post("/api/suites/:slug/versions/:version/deprecate", async (req, reply) => proxyControlPlane(req, reply, `${suiteRegistryPath}/${encodeURIComponent(req.params.slug)}/versions/${encodeURIComponent(req.params.version)}/deprecate`, {})), app.get("/api/suites/:slug/aliases", async (req, reply) => proxyControlPlane(req, reply, `${suiteRegistryPath}/${encodeURIComponent(req.params.slug)}/aliases`, void 0, "GET")), app.get("/api/suite-signing-keys/:keyId", async (req, reply) => proxyControlPlane(req, reply, `/v1/projects/${encodeURIComponent(PROOFLANE_PROJECT)}/suite-signing-keys/${encodeURIComponent(req.params.keyId)}`, void 0, "GET"));
11943
11999
  let localMigrationInspection = async (req) => {
11944
12000
  let cloudResponse = await requestControlPlaneJson(req, suiteRegistryPath);
11945
12001
  if (cloudResponse.projectId !== PROOFLANE_PROJECT || !Array.isArray(cloudResponse.suites))
@@ -11955,14 +12011,14 @@ function buildApp() {
11955
12011
  let scan = discoverLegacyLocalSuites({ cwd: process.cwd() }), plan = planLegacyLocalSuiteMigration(scan.suites, cloud), suites = plan.map(safeLocalSuiteMigrationSummary);
11956
12012
  return { plan, response: { version: "prooflane-local-suite-migration-status-v1", projectId: PROOFLANE_PROJECT, suites, issues: scan.issues, pending: suites.filter((suite) => suite.action === "CREATE_SUITE_DRAFT" || suite.action === "CREATE_VERSION_DRAFT").length, conflicts: scan.issues.length + suites.filter((suite) => suite.action === "CONFLICT").length } };
11957
12013
  };
11958
- app2.get("/api/suite-migration/status", async (req, reply) => {
12014
+ app.get("/api/suite-migration/status", async (req, reply) => {
11959
12015
  try {
11960
12016
  return (await localMigrationInspection(req)).response;
11961
12017
  } catch (error) {
11962
12018
  let status = error instanceof ControlPlaneRequestError ? error.status : 400;
11963
12019
  return reply.code(status).send({ error: (error instanceof Error ? error.message : "Local Suite migration status failed.").slice(0, 300) });
11964
12020
  }
11965
- }), app2.post("/api/suite-migration/sync", async (req, reply) => {
12021
+ }), app.post("/api/suite-migration/sync", async (req, reply) => {
11966
12022
  try {
11967
12023
  if (!req.body || typeof req.body != "object" || Array.isArray(req.body))
11968
12024
  return reply.code(400).send({ error: "Migration sync request must be an object." });
@@ -12011,15 +12067,15 @@ ${item.artifact.localFingerprint}`));
12011
12067
  }
12012
12068
  });
12013
12069
  let gateRegistryPath = `/v1/projects/${encodeURIComponent(PROOFLANE_PROJECT)}/gates`;
12014
- app2.get("/api/governance/gates", async (req, reply) => proxyControlPlane(req, reply, gateRegistryPath, void 0, "GET")), app2.post("/api/governance/gates", async (req, reply) => proxyControlPlane(req, reply, gateRegistryPath, req.body ?? {})), app2.get("/api/governance/gates/:slug", async (req, reply) => proxyControlPlane(req, reply, `${gateRegistryPath}/${encodeURIComponent(req.params.slug)}`, void 0, "GET")), app2.post("/api/governance/gates/:slug/versions", async (req, reply) => proxyControlPlane(req, reply, `${gateRegistryPath}/${encodeURIComponent(req.params.slug)}/versions`, req.body ?? {})), app2.get("/api/governance/gates/:slug/versions/:version", async (req, reply) => proxyControlPlane(req, reply, `${gateRegistryPath}/${encodeURIComponent(req.params.slug)}/versions/${encodeURIComponent(req.params.version)}`, void 0, "GET")), app2.put("/api/governance/gates/:slug/versions/:version", async (req, reply) => proxyControlPlane(req, reply, `${gateRegistryPath}/${encodeURIComponent(req.params.slug)}/versions/${encodeURIComponent(req.params.version)}`, req.body ?? {}, "PUT"));
12070
+ app.get("/api/governance/gates", async (req, reply) => proxyControlPlane(req, reply, gateRegistryPath, void 0, "GET")), app.post("/api/governance/gates", async (req, reply) => proxyControlPlane(req, reply, gateRegistryPath, req.body ?? {})), app.get("/api/governance/gates/:slug", async (req, reply) => proxyControlPlane(req, reply, `${gateRegistryPath}/${encodeURIComponent(req.params.slug)}`, void 0, "GET")), app.post("/api/governance/gates/:slug/versions", async (req, reply) => proxyControlPlane(req, reply, `${gateRegistryPath}/${encodeURIComponent(req.params.slug)}/versions`, req.body ?? {})), app.get("/api/governance/gates/:slug/versions/:version", async (req, reply) => proxyControlPlane(req, reply, `${gateRegistryPath}/${encodeURIComponent(req.params.slug)}/versions/${encodeURIComponent(req.params.version)}`, void 0, "GET")), app.put("/api/governance/gates/:slug/versions/:version", async (req, reply) => proxyControlPlane(req, reply, `${gateRegistryPath}/${encodeURIComponent(req.params.slug)}/versions/${encodeURIComponent(req.params.version)}`, req.body ?? {}, "PUT"));
12015
12071
  for (let transition of ["review", "approve", "deprecate"])
12016
- app2.post(`/api/governance/gates/:slug/versions/:version/${transition}`, async (req, reply) => proxyControlPlane(req, reply, `${gateRegistryPath}/${encodeURIComponent(req.params.slug)}/versions/${encodeURIComponent(req.params.version)}/${transition}`, {}));
12017
- app2.get("/api/governance/gates/:slug/aliases", async (req, reply) => proxyControlPlane(req, reply, `${gateRegistryPath}/${encodeURIComponent(req.params.slug)}/aliases`, void 0, "GET")), app2.get("/api/governance/gates/:slug/audit", async (req, reply) => proxyControlPlane(req, reply, `${gateRegistryPath}/${encodeURIComponent(req.params.slug)}/audit?limit=${encodeURIComponent(req.query.limit ?? "50")}`, void 0, "GET")), app2.get("/api/governance/gates/:slug/resolve", async (req, reply) => proxyControlPlane(req, reply, `${gateRegistryPath}/${encodeURIComponent(req.params.slug)}/resolve`, void 0, "GET")), app2.get("/api/governance/gate-signing-keys/:keyId", async (req, reply) => proxyControlPlane(req, reply, `/v1/projects/${encodeURIComponent(PROOFLANE_PROJECT)}/gate-signing-keys/${encodeURIComponent(req.params.keyId)}`, void 0, "GET"));
12072
+ app.post(`/api/governance/gates/:slug/versions/:version/${transition}`, async (req, reply) => proxyControlPlane(req, reply, `${gateRegistryPath}/${encodeURIComponent(req.params.slug)}/versions/${encodeURIComponent(req.params.version)}/${transition}`, {}));
12073
+ app.get("/api/governance/gates/:slug/aliases", async (req, reply) => proxyControlPlane(req, reply, `${gateRegistryPath}/${encodeURIComponent(req.params.slug)}/aliases`, void 0, "GET")), app.get("/api/governance/gates/:slug/audit", async (req, reply) => proxyControlPlane(req, reply, `${gateRegistryPath}/${encodeURIComponent(req.params.slug)}/audit?limit=${encodeURIComponent(req.query.limit ?? "50")}`, void 0, "GET")), app.get("/api/governance/gates/:slug/resolve", async (req, reply) => proxyControlPlane(req, reply, `${gateRegistryPath}/${encodeURIComponent(req.params.slug)}/resolve`, void 0, "GET")), app.get("/api/governance/gate-signing-keys/:keyId", async (req, reply) => proxyControlPlane(req, reply, `/v1/projects/${encodeURIComponent(PROOFLANE_PROJECT)}/gate-signing-keys/${encodeURIComponent(req.params.keyId)}`, void 0, "GET"));
12018
12074
  let learningRegistryPath = `/v1/projects/${encodeURIComponent(PROOFLANE_PROJECT)}/learning`, learningMutationAuthorized = (req, reply) => typeof req.headers.authorization == "string" && req.headers.authorization.startsWith("Bearer ") ? !0 : (reply.code(401).send({ error: "Sign in to your Prooflane account first." }), !1);
12019
- app2.get("/api/governance/learning/runs/:runId/findings", async (req, reply) => proxyControlPlane(req, reply, `/v1/projects/${encodeURIComponent(PROOFLANE_PROJECT)}/runs/${encodeURIComponent(req.params.runId)}/learning-findings`, void 0, "GET")), app2.get("/api/governance/learning/runs/:runId/disposition", async (req, reply) => proxyControlPlane(req, reply, `/v1/projects/${encodeURIComponent(PROOFLANE_PROJECT)}/runs/${encodeURIComponent(req.params.runId)}/learning-disposition`, void 0, "GET")), app2.put("/api/governance/learning/runs/:runId/disposition", async (req, reply) => {
12075
+ app.get("/api/governance/learning/runs/:runId/findings", async (req, reply) => proxyControlPlane(req, reply, `/v1/projects/${encodeURIComponent(PROOFLANE_PROJECT)}/runs/${encodeURIComponent(req.params.runId)}/learning-findings`, void 0, "GET")), app.get("/api/governance/learning/runs/:runId/disposition", async (req, reply) => proxyControlPlane(req, reply, `/v1/projects/${encodeURIComponent(PROOFLANE_PROJECT)}/runs/${encodeURIComponent(req.params.runId)}/learning-disposition`, void 0, "GET")), app.put("/api/governance/learning/runs/:runId/disposition", async (req, reply) => {
12020
12076
  if (learningMutationAuthorized(req, reply))
12021
12077
  return !isApproveLearningDispositionRequest(req.body) || findSensitiveMaterial(req.body) ? reply.code(400).send({ error: "Expected a compact prooflane-learning-disposition-request-v1 envelope." }) : proxyControlPlane(req, reply, `/v1/projects/${encodeURIComponent(PROOFLANE_PROJECT)}/runs/${encodeURIComponent(req.params.runId)}/learning-disposition`, req.body, "PUT");
12022
- }), app2.get("/api/governance/learning/generations", async (req, reply) => proxyControlPlane(req, reply, `${learningRegistryPath}/generations?limit=${encodeURIComponent(req.query.limit ?? "50")}`, void 0, "GET")), app2.post("/api/governance/learning/generations", async (req, reply) => {
12078
+ }), app.get("/api/governance/learning/generations", async (req, reply) => proxyControlPlane(req, reply, `${learningRegistryPath}/generations?limit=${encodeURIComponent(req.query.limit ?? "50")}`, void 0, "GET")), app.post("/api/governance/learning/generations", async (req, reply) => {
12023
12079
  if (!learningMutationAuthorized(req, reply))
12024
12080
  return;
12025
12081
  if (!isCreateLearningGenerationRequest(req.body))
@@ -12033,15 +12089,15 @@ ${item.artifact.localFingerprint}`));
12033
12089
  let status = error instanceof ControlPlaneRequestError ? error.status : 502;
12034
12090
  return reply.code(status).send({ error: error instanceof Error ? error.message : "Governed learning generation failed." });
12035
12091
  }
12036
- }), app2.get("/api/governance/learning/tests", async (req, reply) => proxyControlPlane(req, reply, `${learningRegistryPath}/tests?limit=${encodeURIComponent(req.query.limit ?? "100")}`, void 0, "GET"));
12092
+ }), app.get("/api/governance/learning/tests", async (req, reply) => proxyControlPlane(req, reply, `${learningRegistryPath}/tests?limit=${encodeURIComponent(req.query.limit ?? "100")}`, void 0, "GET"));
12037
12093
  for (let transition of ["review", "approve"])
12038
- app2.post(`/api/governance/learning/tests/:testId/${transition}`, async (req, reply) => {
12094
+ app.post(`/api/governance/learning/tests/:testId/${transition}`, async (req, reply) => {
12039
12095
  if (learningMutationAuthorized(req, reply))
12040
12096
  return !req.body || typeof req.body != "object" || Array.isArray(req.body) || Object.keys(req.body).length !== 0 ? reply.code(400).send({ error: "Learning lifecycle transitions accept an empty body only." }) : proxyControlPlane(req, reply, `${learningRegistryPath}/tests/${encodeURIComponent(req.params.testId)}/${transition}`, {});
12041
12097
  });
12042
- app2.get("/api/governance/learning/audit", async (req, reply) => proxyControlPlane(req, reply, `${learningRegistryPath}/audit?limit=${encodeURIComponent(req.query.limit ?? "100")}`, void 0, "GET"));
12098
+ app.get("/api/governance/learning/audit", async (req, reply) => proxyControlPlane(req, reply, `${learningRegistryPath}/audit?limit=${encodeURIComponent(req.query.limit ?? "100")}`, void 0, "GET"));
12043
12099
  let runnerRegistryPath = `/v1/projects/${encodeURIComponent(PROOFLANE_PROJECT)}/runners`;
12044
- app2.get("/api/governance/runners", async (req, reply) => proxyControlPlane(req, reply, runnerRegistryPath, void 0, "GET")), app2.post("/api/governance/runners/:runnerId/revoke", async (req, reply) => proxyControlPlane(req, reply, `${runnerRegistryPath}/${encodeURIComponent(req.params.runnerId)}/revoke`, {})), app2.post("/api/governance/gates/:slug/remote-runs", async (req, reply) => proxyControlPlane(req, reply, `${gateRegistryPath}/${encodeURIComponent(req.params.slug)}/remote-runs`, req.body ?? {})), app2.get("/api/governance/runner-jobs/:jobId", async (req, reply) => proxyControlPlane(req, reply, `/v1/projects/${encodeURIComponent(PROOFLANE_PROJECT)}/runner-jobs/${encodeURIComponent(req.params.jobId)}`, void 0, "GET")), app2.post("/api/governance/runner-jobs/:jobId/cancel", async (req, reply) => proxyControlPlane(req, reply, `/v1/projects/${encodeURIComponent(PROOFLANE_PROJECT)}/runner-jobs/${encodeURIComponent(req.params.jobId)}/cancel`, {})), app2.post("/api/governance/gates/:slug/runs", async (req, reply) => {
12100
+ app.get("/api/governance/runners", async (req, reply) => proxyControlPlane(req, reply, runnerRegistryPath, void 0, "GET")), app.post("/api/governance/runners/:runnerId/revoke", async (req, reply) => proxyControlPlane(req, reply, `${runnerRegistryPath}/${encodeURIComponent(req.params.runnerId)}/revoke`, {})), app.post("/api/governance/gates/:slug/remote-runs", async (req, reply) => proxyControlPlane(req, reply, `${gateRegistryPath}/${encodeURIComponent(req.params.slug)}/remote-runs`, req.body ?? {})), app.get("/api/governance/runner-jobs/:jobId", async (req, reply) => proxyControlPlane(req, reply, `/v1/projects/${encodeURIComponent(PROOFLANE_PROJECT)}/runner-jobs/${encodeURIComponent(req.params.jobId)}`, void 0, "GET")), app.post("/api/governance/runner-jobs/:jobId/cancel", async (req, reply) => proxyControlPlane(req, reply, `/v1/projects/${encodeURIComponent(PROOFLANE_PROJECT)}/runner-jobs/${encodeURIComponent(req.params.jobId)}/cancel`, {})), app.post("/api/governance/gates/:slug/runs", async (req, reply) => {
12045
12101
  let projectPath = `/v1/projects/${encodeURIComponent(PROOFLANE_PROJECT)}`, run, startedAt = (/* @__PURE__ */ new Date()).toISOString(), startedMs = Date.now();
12046
12102
  try {
12047
12103
  let resolutionPayload = await requestControlPlaneJson(req, `${gateRegistryPath}/${encodeURIComponent(req.params.slug)}/resolve`), object = (value) => !!value && typeof value == "object" && !Array.isArray(value);
@@ -12151,7 +12207,7 @@ ${PROOFLANE_PROJECT}`, "utf8").digest("hex").slice(0, 24)}`, idempotencyKey = `l
12151
12207
  }
12152
12208
  });
12153
12209
  let policyRegistryPath = `/v1/projects/${encodeURIComponent(PROOFLANE_PROJECT)}/policies`;
12154
- app2.get("/api/policies", async (req, reply) => proxyControlPlane(req, reply, policyRegistryPath, void 0, "GET")), app2.post("/api/policies", async (req, reply) => proxyControlPlane(req, reply, policyRegistryPath, req.body ?? {})), app2.get("/api/policies/:policyId", async (req, reply) => proxyControlPlane(req, reply, `${policyRegistryPath}/${encodeURIComponent(req.params.policyId)}`, void 0, "GET")), app2.post("/api/policies/:policyId/versions", async (req, reply) => proxyControlPlane(req, reply, `${policyRegistryPath}/${encodeURIComponent(req.params.policyId)}/versions`, req.body ?? {})), app2.put("/api/policies/:policyId/versions/:version", async (req, reply) => proxyControlPlane(req, reply, `${policyRegistryPath}/${encodeURIComponent(req.params.policyId)}/versions/${encodeURIComponent(req.params.version)}`, req.body ?? {}, "PUT")), app2.post("/api/policies/:policyId/versions/:version/review", async (req, reply) => proxyControlPlane(req, reply, `${policyRegistryPath}/${encodeURIComponent(req.params.policyId)}/versions/${encodeURIComponent(req.params.version)}/review`, {})), app2.post("/api/policies/:policyId/versions/:version/approve", async (req, reply) => proxyControlPlane(req, reply, `${policyRegistryPath}/${encodeURIComponent(req.params.policyId)}/versions/${encodeURIComponent(req.params.version)}/approve`, {})), app2.post("/api/policies/:policyId/versions/:version/deprecate", async (req, reply) => proxyControlPlane(req, reply, `${policyRegistryPath}/${encodeURIComponent(req.params.policyId)}/versions/${encodeURIComponent(req.params.version)}/deprecate`, {})), app2.post("/api/assure/target-snapshot", async (req, reply) => proxyControlPlane(req, reply, "/v1/assure/target-snapshot", req.body ?? {})), app2.get("/api/assure/target-snapshot", async (req, reply) => proxyControlPlane(req, reply, "/v1/assure/target-snapshot", void 0, "GET")), app2.post("/api/workspace/backup-preference", async (req, reply) => proxyControlPlane(req, reply, "/v1/workspace/backup-preference", req.body ?? {})), app2.post("/api/workspace/backup", async (req, reply) => {
12210
+ app.get("/api/policies", async (req, reply) => proxyControlPlane(req, reply, policyRegistryPath, void 0, "GET")), app.post("/api/policies", async (req, reply) => proxyControlPlane(req, reply, policyRegistryPath, req.body ?? {})), app.get("/api/policies/:policyId", async (req, reply) => proxyControlPlane(req, reply, `${policyRegistryPath}/${encodeURIComponent(req.params.policyId)}`, void 0, "GET")), app.post("/api/policies/:policyId/versions", async (req, reply) => proxyControlPlane(req, reply, `${policyRegistryPath}/${encodeURIComponent(req.params.policyId)}/versions`, req.body ?? {})), app.put("/api/policies/:policyId/versions/:version", async (req, reply) => proxyControlPlane(req, reply, `${policyRegistryPath}/${encodeURIComponent(req.params.policyId)}/versions/${encodeURIComponent(req.params.version)}`, req.body ?? {}, "PUT")), app.post("/api/policies/:policyId/versions/:version/review", async (req, reply) => proxyControlPlane(req, reply, `${policyRegistryPath}/${encodeURIComponent(req.params.policyId)}/versions/${encodeURIComponent(req.params.version)}/review`, {})), app.post("/api/policies/:policyId/versions/:version/approve", async (req, reply) => proxyControlPlane(req, reply, `${policyRegistryPath}/${encodeURIComponent(req.params.policyId)}/versions/${encodeURIComponent(req.params.version)}/approve`, {})), app.post("/api/policies/:policyId/versions/:version/deprecate", async (req, reply) => proxyControlPlane(req, reply, `${policyRegistryPath}/${encodeURIComponent(req.params.policyId)}/versions/${encodeURIComponent(req.params.version)}/deprecate`, {})), app.post("/api/assure/target-snapshot", async (req, reply) => proxyControlPlane(req, reply, "/v1/assure/target-snapshot", req.body ?? {})), app.get("/api/assure/target-snapshot", async (req, reply) => proxyControlPlane(req, reply, "/v1/assure/target-snapshot", void 0, "GET")), app.post("/api/workspace/backup-preference", async (req, reply) => proxyControlPlane(req, reply, "/v1/workspace/backup-preference", req.body ?? {})), app.post("/api/workspace/backup", async (req, reply) => {
12155
12211
  let snapshots = svc.listSnapshots().map(({ id, createdAt, kind, origin, snapshot }) => ({ id, createdAt, kind, origin, snapshot })), backup = {
12156
12212
  version: "workspace-backup-v1",
12157
12213
  capturedAt: (/* @__PURE__ */ new Date()).toISOString(),
@@ -12167,7 +12223,7 @@ ${PROOFLANE_PROJECT}`, "utf8").digest("hex").slice(0, 24)}`, idempotencyKey = `l
12167
12223
  let capturedAt = payload && typeof payload == "object" && typeof payload.capturedAt == "string" ? payload.capturedAt : backup.capturedAt;
12168
12224
  svc.markCloudWorkspaceBackedUp(capturedAt);
12169
12225
  });
12170
- }), app2.get("/api/workspace/backup/latest", async (req, reply) => proxyControlPlane(req, reply, `/v1/workspace/backup/latest${req.query?.restorable ? "?restorable=1" : ""}`, void 0, "GET")), app2.get("/api/workspace/backup/versions", async (req, reply) => proxyControlPlane(req, reply, `/v1/workspace/backup/versions${req.query?.limit ? `?limit=${encodeURIComponent(req.query.limit)}` : ""}`, void 0, "GET")), app2.post("/api/workspace/restore", async (req, reply) => {
12226
+ }), app.get("/api/workspace/backup/latest", async (req, reply) => proxyControlPlane(req, reply, `/v1/workspace/backup/latest${req.query?.restorable ? "?restorable=1" : ""}`, void 0, "GET")), app.get("/api/workspace/backup/versions", async (req, reply) => proxyControlPlane(req, reply, `/v1/workspace/backup/versions${req.query?.limit ? `?limit=${encodeURIComponent(req.query.limit)}` : ""}`, void 0, "GET")), app.post("/api/workspace/restore", async (req, reply) => {
12171
12227
  if (!CONTROL_PLANE_URL)
12172
12228
  return reply.code(503).send({ error: "Prooflane Cloud Workspace is not configured for this Inspector." });
12173
12229
  let authorization = req.headers.authorization;
@@ -12186,20 +12242,20 @@ ${PROOFLANE_PROJECT}`, "utf8").digest("hex").slice(0, 24)}`, idempotencyKey = `l
12186
12242
  return reply.code(404).send({ ok: !1, error: "No cloud backup was found to restore." });
12187
12243
  let restored = svc.restoreFromBackup(backup.value), capturedAt = backup.value.capturedAt ?? backup.createdAt;
12188
12244
  return svc.markCloudWorkspaceBackedUp(capturedAt), reply.send({ ok: !0, restored, capturedAt, backupId: backup.id });
12189
- }), app2.post("/api/workspace/local/lifecycle", async (req, reply) => {
12245
+ }), app.post("/api/workspace/local/lifecycle", async (req, reply) => {
12190
12246
  if (req.headers["x-kawach-local-lifecycle"] !== localLifecycleKey)
12191
12247
  return reply.code(403).send({ error: "Invalid local workspace lifecycle request." });
12192
12248
  let subject = typeof req.body?.subject == "string" ? req.body.subject.slice(0, 320) : void 0;
12193
12249
  await mcpManager.clearWorkspace(PROOFLANE_PROJECT);
12194
12250
  let result = await svc.applyLocalWorkspaceLifecycle(subject);
12195
12251
  return svc = new InspectorService(store), activeMcpConnectionId = null, activeMcpAuthMode = "unknown", oauthFlows.clear(), { ok: !0, result, reason: req.body?.reason ?? "login" };
12196
- }), app2.post("/api/intelligence/leases", async (req, reply) => proxyControlPlane(req, reply, "/v1/intelligence/leases", req.body ?? {})), app2.post("/api/intelligence/evidence", async (req, reply) => proxyControlPlane(req, reply, "/v1/intelligence/evidence", req.body ?? {})), app2.post("/api/intelligence/evaluations", async (req, reply) => proxyControlPlane(req, reply, "/v1/intelligence/evaluations", req.body ?? {})), app2.get("/api/security/catalog", async (req, reply) => proxyControlPlane(req, reply, "/v1/security/catalog", void 0, "GET"));
12252
+ }), app.post("/api/intelligence/leases", async (req, reply) => proxyControlPlane(req, reply, "/v1/intelligence/leases", req.body ?? {})), app.post("/api/intelligence/evidence", async (req, reply) => proxyControlPlane(req, reply, "/v1/intelligence/evidence", req.body ?? {})), app.post("/api/intelligence/evaluations", async (req, reply) => proxyControlPlane(req, reply, "/v1/intelligence/evaluations", req.body ?? {})), app.get("/api/security/catalog", async (req, reply) => proxyControlPlane(req, reply, "/v1/security/catalog", void 0, "GET"));
12197
12253
  for (let pillar of ["security", "rag"])
12198
- app2.post(`/api/${pillar}/scans`, async (req, reply) => proxyControlPlane(req, reply, "/v1/scans", { pillar, ...req.body ?? {} })), app2.get(`/api/${pillar}/scans/:id`, async (req, reply) => proxyControlPlane(req, reply, `/v1/scans/${encodeURIComponent(req.params.id)}`, void 0, "GET")), app2.get(`/api/${pillar}/scans/:id/events`, async (req, reply) => {
12254
+ app.post(`/api/${pillar}/scans`, async (req, reply) => proxyControlPlane(req, reply, "/v1/scans", { pillar, ...req.body ?? {} })), app.get(`/api/${pillar}/scans/:id`, async (req, reply) => proxyControlPlane(req, reply, `/v1/scans/${encodeURIComponent(req.params.id)}`, void 0, "GET")), app.get(`/api/${pillar}/scans/:id/events`, async (req, reply) => {
12199
12255
  let after = Math.max(0, Math.trunc(Number(req.query.after)) || 0);
12200
12256
  return proxyControlPlane(req, reply, `/v1/scans/${encodeURIComponent(req.params.id)}/events?after=${after}`, void 0, "GET");
12201
- }), app2.post(`/api/${pillar}/scans/:id/next-task`, async (req, reply) => proxyControlPlane(req, reply, `/v1/scans/${encodeURIComponent(req.params.id)}/next-task`, {})), app2.post(`/api/${pillar}/scans/:id/evidence`, async (req, reply) => proxyControlPlane(req, reply, `/v1/scans/${encodeURIComponent(req.params.id)}/evidence`, req.body ?? {})), app2.post(`/api/${pillar}/scans/:id/stop`, async (req, reply) => proxyControlPlane(req, reply, `/v1/scans/${encodeURIComponent(req.params.id)}/cancel`, {})), app2.post(`/api/${pillar}/scans/:id/retry`, async (req, reply) => proxyControlPlane(req, reply, `/v1/scans/${encodeURIComponent(req.params.id)}/retry`, {}));
12202
- app2.post("/api/benchmark/evidence/generate", async (req, reply) => {
12257
+ }), app.post(`/api/${pillar}/scans/:id/next-task`, async (req, reply) => proxyControlPlane(req, reply, `/v1/scans/${encodeURIComponent(req.params.id)}/next-task`, {})), app.post(`/api/${pillar}/scans/:id/evidence`, async (req, reply) => proxyControlPlane(req, reply, `/v1/scans/${encodeURIComponent(req.params.id)}/evidence`, req.body ?? {})), app.post(`/api/${pillar}/scans/:id/stop`, async (req, reply) => proxyControlPlane(req, reply, `/v1/scans/${encodeURIComponent(req.params.id)}/cancel`, {})), app.post(`/api/${pillar}/scans/:id/retry`, async (req, reply) => proxyControlPlane(req, reply, `/v1/scans/${encodeURIComponent(req.params.id)}/retry`, {}));
12258
+ app.post("/api/benchmark/evidence/generate", async (req, reply) => {
12203
12259
  let generator = req.body?.generator, count = Math.min(20, Math.max(1, Math.trunc(req.body?.count ?? 4))), brief = req.body?.brief?.trim();
12204
12260
  if (!generator?.model?.trim() || !generator.apiKey?.trim())
12205
12261
  return reply.code(400).send({ error: "Configure the evidence-generator model and API key." });
@@ -12285,7 +12341,7 @@ ${existing.length ? existing.join(`
12285
12341
  (run?.status === "CANCELLED" || run?.status === "FAILED") && store.releaseBenchmarkEntitlement(workspaceId, entitlement.id, entitlement.reservationKey);
12286
12342
  }
12287
12343
  };
12288
- app2.get("/api/benchmark/entitlements", async () => {
12344
+ app.get("/api/benchmark/entitlements", async () => {
12289
12345
  let workspaceId = benchmarkWorkspaceId();
12290
12346
  ensureFreeFastBenchmarkEntitlement(), reconcileTerminalBenchmarkReservations(workspaceId);
12291
12347
  let entitlements = store.listBenchmarkEntitlements(workspaceId);
@@ -12297,7 +12353,7 @@ ${existing.length ? existing.join(`
12297
12353
  pricingPolicy: benchmarkPricingPolicy,
12298
12354
  purchase: { verification: "SERVER_REQUIRED", clientPaidFlagsAccepted: !1 }
12299
12355
  };
12300
- }), app2.post("/api/benchmark/purchases/verify", async (req, reply) => {
12356
+ }), app.post("/api/benchmark/purchases/verify", async (req, reply) => {
12301
12357
  let receipt = req.body?.receipt?.trim(), idempotencyKey = req.body?.idempotencyKey?.trim();
12302
12358
  return !receipt || receipt.length > 65536 || !idempotencyKey || idempotencyKey.length > 120 ? reply.code(400).send({ error: "A bounded purchase receipt and idempotency key are required." }) : proxyControlPlane(req, reply, "/v1/benchmark/purchases/verify", { ...req.body, receipt, idempotencyKey, projectId: PROOFLANE_PROJECT }, "POST", (payload) => {
12303
12359
  let response = payload, entitlement = response?.entitlement;
@@ -12305,7 +12361,7 @@ ${existing.length ? existing.join(`
12305
12361
  throw new Error("Prooflane returned an invalid Benchmark purchase entitlement.");
12306
12362
  store.saveBenchmarkEntitlement(entitlement);
12307
12363
  });
12308
- }), app2.post("/api/benchmark/plans", async (req, reply) => {
12364
+ }), app.post("/api/benchmark/plans", async (req, reply) => {
12309
12365
  if (intelligenceMode === "hosted")
12310
12366
  return proxyControlPlane(req, reply, "/v1/benchmark/plans", req.body ?? {});
12311
12367
  let body = req.body ?? {}, objective = body.objective?.trim(), targetType = body.targetType, mode = body.mode, targets = body.targets;
@@ -12402,7 +12458,7 @@ ${existing.length ? existing.join(`
12402
12458
  let message2 = error instanceof Error ? error.message : String(error), status = error instanceof ControlPlaneRequestError ? error.status : /allowance|locked|not enabled/i.test(message2) ? 403 : 502;
12403
12459
  return reply.code(status).send({ error: status < 500 ? message2 : publicIntelligenceGenerationError(message2) });
12404
12460
  }
12405
- }), app2.post("/api/benchmark/run", async (req, reply) => {
12461
+ }), app.post("/api/benchmark/run", async (req, reply) => {
12406
12462
  let suppliedCandidates = req.body?.candidates, workflowPlan = req.body?.plan, suppliedCases = req.body?.cases;
12407
12463
  if (!Array.isArray(suppliedCandidates) || suppliedCandidates.length < 2 || suppliedCandidates.length > 8)
12408
12464
  return reply.code(400).send({ error: "Choose between 2 and 8 benchmark candidates." });
@@ -12614,16 +12670,16 @@ ${existing.length ? existing.join(`
12614
12670
  } finally {
12615
12671
  keys.clear(), prices.clear();
12616
12672
  }
12617
- }), app2.get("/api/benchmark/history", async (req) => {
12673
+ }), app.get("/api/benchmark/history", async (req) => {
12618
12674
  let limit = Math.max(1, Math.min(100, Number(req.query.limit) || 25));
12619
12675
  return { runs: store.listBenchmarkRuns(benchmarkWorkspaceId(), limit).map((record6) => ({ runId: record6.runId, status: record6.status, planId: record6.plan.planId, planVersion: record6.plan.version, objective: record6.plan.objective, mode: record6.plan.mode, targetType: record6.plan.targetType, summary: record6.summary, createdAt: record6.createdAt, updatedAt: record6.updatedAt })) };
12620
- }), app2.get("/api/benchmark/runs/:id", async (req, reply) => {
12676
+ }), app.get("/api/benchmark/runs/:id", async (req, reply) => {
12621
12677
  let record6 = store.getBenchmarkRun(req.params.id);
12622
12678
  return !record6 || record6.workspaceId !== benchmarkWorkspaceId() ? reply.code(404).send({ error: "Benchmark Run not found." }) : { run: record6 };
12623
- }), app2.get("/api/benchmark/runs/:id/report.html", async (req, reply) => {
12679
+ }), app.get("/api/benchmark/runs/:id/report.html", async (req, reply) => {
12624
12680
  let record6 = store.getBenchmarkRun(req.params.id);
12625
12681
  return !record6 || record6.workspaceId !== benchmarkWorkspaceId() || !record6.reportHtml ? reply.code(404).send({ error: "Benchmark HTML report not found." }) : (reply.header("Content-Disposition", `attachment; filename="benchmark-report-${record6.runId}.html"`), reply.type("text/html; charset=utf-8"), record6.reportHtml);
12626
- }), app2.post("/api/intelligence/execute", async (req, reply) => {
12682
+ }), app.post("/api/intelligence/execute", async (req, reply) => {
12627
12683
  if (!req.body?.lease)
12628
12684
  return reply.code(400).send({ ok: !1, error: "A hosted Intelligence lease is required." });
12629
12685
  let claims;
@@ -12894,7 +12950,7 @@ ${answer}`
12894
12950
  let tagsFile = () => join4(process.cwd(), DEFAULT_TAGS_FILE), readTagsConfig = (file) => parseTagsConfig(existsSync2(file) ? readFileSync3(file, "utf8") : ""), writeTagsConfig = (file, config) => {
12895
12951
  mkdirSync2(dirname4(file), { recursive: !0 }), writeFileSync(file, serializeTagsConfig(config));
12896
12952
  };
12897
- app2.get("/api/tags", async () => ({ ok: !0, path: DEFAULT_TAGS_FILE, config: readTagsConfig(tagsFile()) })), app2.post("/api/tags", async (req, reply) => {
12953
+ app.get("/api/tags", async () => ({ ok: !0, path: DEFAULT_TAGS_FILE, config: readTagsConfig(tagsFile()) })), app.post("/api/tags", async (req, reply) => {
12898
12954
  let plan = await resolvePlan(req);
12899
12955
  if (!plan.gates)
12900
12956
  return reply.code(402).send({ ok: !1, upgrade: !0, feature: "gates", tier: plan.tier, error: "CI gates are part of the Scale plan. Upgrade to capture tagged tests for CI." });
@@ -12903,7 +12959,7 @@ ${answer}`
12903
12959
  return reply.code(400).send({ ok: !1, error: "A valid tagged test (id, pillar, tags[]) is required." });
12904
12960
  let file = tagsFile(), next = upsertTest(readTagsConfig(file), { ...test, createdAt: test.createdAt || (/* @__PURE__ */ new Date()).toISOString() });
12905
12961
  return writeTagsConfig(file, next), { ok: !0, path: DEFAULT_TAGS_FILE, config: next };
12906
- }), app2.delete("/api/tags/:id", async (req, reply) => {
12962
+ }), app.delete("/api/tags/:id", async (req, reply) => {
12907
12963
  let plan = await resolvePlan(req);
12908
12964
  if (!plan.gates)
12909
12965
  return reply.code(402).send({ ok: !1, upgrade: !0, feature: "gates", tier: plan.tier, error: "CI gates are part of the Scale plan." });
@@ -12927,7 +12983,7 @@ ${answer}`
12927
12983
  mkdirSync2(dirname4(file), { recursive: !0 }), writeFileSync(file, JSON.stringify({ version: "prooflane-gates-v1", gates }, null, 2) + `
12928
12984
  `, "utf8");
12929
12985
  };
12930
- app2.get("/api/gates", async () => ({ ok: !0, path: ".prooflane/gates.json", gates: readLegacyRegressionGroups() })), app2.put("/api/gates/:id", async (req, reply) => {
12986
+ app.get("/api/gates", async () => ({ ok: !0, path: ".prooflane/gates.json", gates: readLegacyRegressionGroups() })), app.put("/api/gates/:id", async (req, reply) => {
12931
12987
  let plan = await resolvePlan(req);
12932
12988
  if (!plan.gates)
12933
12989
  return reply.code(402).send({ ok: !1, upgrade: !0, feature: "gates", tier: plan.tier, error: "Legacy local regression groups are part of the Scale plan." });
@@ -12935,7 +12991,7 @@ ${answer}`
12935
12991
  return reply.code(400).send({ ok: !1, error: "A valid legacy local regression group with at least one tag is required." });
12936
12992
  let current = readLegacyRegressionGroups(), existing = current.find((gate2) => gate2.id === req.params.id), gate = { ...req.body.gate, createdAt: existing?.createdAt ?? req.body.gate.createdAt }, next = [...current.filter((item) => item.id !== gate.id), gate].sort((a, b) => a.name.localeCompare(b.name));
12937
12993
  return writeLegacyRegressionGroups(next), { ok: !0, path: ".prooflane/gates.json", gate, gates: next };
12938
- }), app2.delete("/api/gates/:id", async (req, reply) => {
12994
+ }), app.delete("/api/gates/:id", async (req, reply) => {
12939
12995
  let plan = await resolvePlan(req);
12940
12996
  if (!plan.gates)
12941
12997
  return reply.code(402).send({ ok: !1, upgrade: !0, feature: "gates", tier: plan.tier, error: "Legacy local regression groups are part of the Scale plan." });
@@ -12967,7 +13023,7 @@ ${answer}`
12967
13023
  throw new Error("Connected MCP runtime was not registered.");
12968
13024
  return runtime.setToolLimit?.(plan.tools), svc = runtime, activeMcpConnectionId = result.connection.id, activeMcpAuthMode = authModeFor(connection), result;
12969
13025
  }
12970
- app2.post("/api/connect", async (req, reply) => {
13026
+ app.post("/api/connect", async (req, reply) => {
12971
13027
  try {
12972
13028
  let disconnected = mcpManager.listConnections(PROOFLANE_PROJECT).filter((connection) => connection.status === "DISCONNECTED");
12973
13029
  if (!activeMcpConnectionId && disconnected.length === 1) {
@@ -12979,21 +13035,21 @@ ${answer}`
12979
13035
  } catch (error) {
12980
13036
  return sendMcpError(reply, error);
12981
13037
  }
12982
- }), app2.get("/api/mcp/connections", async (req) => {
13038
+ }), app.get("/api/mcp/connections", async (req) => {
12983
13039
  let entitlement = mcpEntitlementForPlan(await resolvePlan(req)), connections = mcpManager.reconcileEntitlement(PROOFLANE_PROJECT, entitlement);
12984
13040
  return {
12985
13041
  connections,
12986
13042
  entitlement,
12987
13043
  usage: { current: connections.length, allowed: entitlement.maxConnections }
12988
13044
  };
12989
- }), app2.post("/api/mcp/connections", async (req, reply) => {
13045
+ }), app.post("/api/mcp/connections", async (req, reply) => {
12990
13046
  try {
12991
13047
  let result = await connectMcp(req, req.body.connection, req.body.displayName ?? req.body.name);
12992
13048
  return reply.code(201).send({ ok: !0, ...result });
12993
13049
  } catch (error) {
12994
13050
  return sendMcpError(reply, error);
12995
13051
  }
12996
- }), app2.post("/api/mcp/connections/:id/reconnect", async (req, reply) => {
13052
+ }), app.post("/api/mcp/connections/:id/reconnect", async (req, reply) => {
12997
13053
  try {
12998
13054
  let plan = await resolvePlan(req);
12999
13055
  mcpManager.reconcileEntitlement(PROOFLANE_PROJECT, mcpEntitlementForPlan(plan));
@@ -13005,7 +13061,7 @@ ${answer}`
13005
13061
  } catch (error) {
13006
13062
  return sendMcpError(reply, error);
13007
13063
  }
13008
- }), app2.post("/api/mcp/connections/:id/activate", async (req, reply) => {
13064
+ }), app.post("/api/mcp/connections/:id/activate", async (req, reply) => {
13009
13065
  try {
13010
13066
  let plan = await resolvePlan(req);
13011
13067
  mcpManager.reconcileEntitlement(PROOFLANE_PROJECT, mcpEntitlementForPlan(plan));
@@ -13021,32 +13077,32 @@ ${answer}`
13021
13077
  } catch (error) {
13022
13078
  return sendMcpError(reply, error);
13023
13079
  }
13024
- }), app2.post("/api/mcp/connections/:id/refresh", async (req, reply) => {
13080
+ }), app.post("/api/mcp/connections/:id/refresh", async (req, reply) => {
13025
13081
  try {
13026
13082
  let plan = await resolvePlan(req);
13027
13083
  return mcpManager.reconcileEntitlement(PROOFLANE_PROJECT, mcpEntitlementForPlan(plan)), { ok: !0, tools: await mcpManager.refreshTools(PROOFLANE_PROJECT, req.params.id, await requestActor(req)), connection: mcpManager.getConnection(PROOFLANE_PROJECT, req.params.id) };
13028
13084
  } catch (error) {
13029
13085
  return sendMcpError(reply, error);
13030
13086
  }
13031
- }), app2.post("/api/mcp/connections/:id/disconnect", async (req, reply) => {
13087
+ }), app.post("/api/mcp/connections/:id/disconnect", async (req, reply) => {
13032
13088
  try {
13033
13089
  return await mcpManager.disconnectConnection(PROOFLANE_PROJECT, req.params.id, await requestActor(req)), activeMcpConnectionId === req.params.id && (activeMcpConnectionId = null, activeMcpAuthMode = "unknown", svc = new InspectorService(store)), { ok: !0 };
13034
13090
  } catch (error) {
13035
13091
  return sendMcpError(reply, error);
13036
13092
  }
13037
- }), app2.delete("/api/mcp/connections/:id", async (req, reply) => {
13093
+ }), app.delete("/api/mcp/connections/:id", async (req, reply) => {
13038
13094
  try {
13039
13095
  return await mcpManager.removeConnection(PROOFLANE_PROJECT, req.params.id, await requestActor(req)), activeMcpConnectionId === req.params.id && (activeMcpConnectionId = null, activeMcpAuthMode = "unknown", svc = new InspectorService(store)), { ok: !0 };
13040
13096
  } catch (error) {
13041
13097
  return sendMcpError(reply, error);
13042
13098
  }
13043
- }), app2.get("/api/mcp/tools", async (req) => {
13099
+ }), app.get("/api/mcp/tools", async (req) => {
13044
13100
  let entitlement = mcpEntitlementForPlan(await resolvePlan(req));
13045
13101
  return mcpManager.reconcileEntitlement(PROOFLANE_PROJECT, entitlement), { tools: mcpManager.listTools(PROOFLANE_PROJECT, req.query.connectionId) };
13046
- }), app2.get("/api/features/:featureType/:resourceId/mcp-binding", async (req, reply) => {
13102
+ }), app.get("/api/features/:featureType/:resourceId/mcp-binding", async (req, reply) => {
13047
13103
  let featureType = parseFeatureType(req.params.featureType);
13048
13104
  return !featureType || !validResourceId(req.params.resourceId) ? reply.code(400).send({ error: "A valid MCP feature type and resource ID are required." }) : { binding: mcpManager.getBinding(PROOFLANE_PROJECT, featureType, req.params.resourceId) };
13049
- }), app2.put("/api/features/:featureType/:resourceId/mcp-binding", async (req, reply) => {
13105
+ }), app.put("/api/features/:featureType/:resourceId/mcp-binding", async (req, reply) => {
13050
13106
  let featureType = parseFeatureType(req.params.featureType);
13051
13107
  if (!featureType || !validResourceId(req.params.resourceId))
13052
13108
  return reply.code(400).send({ error: "A valid MCP feature type and resource ID are required." });
@@ -13072,10 +13128,10 @@ ${answer}`
13072
13128
  } catch (error) {
13073
13129
  return sendMcpError(reply, error);
13074
13130
  }
13075
- }), app2.delete("/api/features/:featureType/:resourceId/mcp-binding", async (req, reply) => {
13131
+ }), app.delete("/api/features/:featureType/:resourceId/mcp-binding", async (req, reply) => {
13076
13132
  let featureType = parseFeatureType(req.params.featureType);
13077
13133
  return !featureType || !validResourceId(req.params.resourceId) ? reply.code(400).send({ error: "A valid MCP feature type and resource ID are required." }) : { ok: mcpManager.deleteBinding(PROOFLANE_PROJECT, featureType, req.params.resourceId, await requestActor(req)) };
13078
- }), app2.post("/api/features/:featureType/:resourceId/mcp-runs", async (req, reply) => {
13134
+ }), app.post("/api/features/:featureType/:resourceId/mcp-runs", async (req, reply) => {
13079
13135
  let featureType = parseFeatureType(req.params.featureType);
13080
13136
  if (!featureType || !validResourceId(req.params.resourceId))
13081
13137
  return reply.code(400).send({ error: "A valid MCP feature type and resource ID are required." });
@@ -13087,10 +13143,10 @@ ${answer}`
13087
13143
  } catch (error) {
13088
13144
  return sendMcpError(reply, error);
13089
13145
  }
13090
- }), app2.get("/api/mcp/runs/:runId", async (req, reply) => {
13146
+ }), app.get("/api/mcp/runs/:runId", async (req, reply) => {
13091
13147
  let snapshot = mcpManager.getRunSnapshot(PROOFLANE_PROJECT, req.params.runId);
13092
13148
  return snapshot ? { snapshot } : reply.code(404).send({ error: "MCP run snapshot was not found." });
13093
- }), app2.post("/api/mcp/runs/:runId/invoke", async (req, reply) => {
13149
+ }), app.post("/api/mcp/runs/:runId/invoke", async (req, reply) => {
13094
13150
  let controller = new AbortController(), cancel = () => controller.abort();
13095
13151
  req.raw.once("aborted", cancel);
13096
13152
  try {
@@ -13105,12 +13161,12 @@ ${answer}`
13105
13161
  } finally {
13106
13162
  req.raw.off("aborted", cancel);
13107
13163
  }
13108
- }), app2.get("/api/mcp/audit", async (req) => ({
13164
+ }), app.get("/api/mcp/audit", async (req) => ({
13109
13165
  events: mcpManager.listAuditEvents(PROOFLANE_PROJECT, Number(req.query.limit ?? 100))
13110
- })), app2.get("/api/capabilities", async () => {
13166
+ })), app.get("/api/capabilities", async () => {
13111
13167
  let capabilities = svc.getCapabilities(), searchable = capabilities ? JSON.stringify(capabilities).toLowerCase() : "", tools = capabilities?.tools ?? [], resources = capabilities?.resources ?? [], rag = tools.some((tool) => /rag|retriev|search|knowledge|vector|semantic/.test(`${tool.name} ${tool.description ?? ""}`.toLowerCase())) || resources.some((resource) => /knowledge|document|vector|search|rag/.test(`${resource.uri} ${resource.name ?? ""} ${resource.description ?? ""}`.toLowerCase())), notableTools = tools.filter((tool) => /create|update|write|delete|remove|execute|admin|push|merge|dispatch|upload/.test(`${tool.name} ${tool.description ?? ""}`.toLowerCase())).map((tool) => tool.name), sensitivitySignals = [...new Set((searchable.match(/email|phone|address|ssn|personal|secret|token|password|api[_ -]?key|user[_ -]?id|account[_ -]?id/g) ?? []).slice(0, 8))];
13112
13168
  return { connected: svc.isConnected(), connectionId: activeMcpConnectionId, capabilities, discovery: { toolCount: tools.length, auth: { mode: activeMcpAuthMode, status: activeMcpAuthMode === "unknown" ? "UNKNOWN" : "OBSERVED" }, rag: { present: rag, status: rag ? "OBSERVED" : "NOT_OBSERVED" }, notable: { tools: notableTools, status: notableTools.length ? "CLASSIFIED" : "NONE_CLASSIFIED" }, sensitivity: { signals: sensitivitySignals, status: sensitivitySignals.length ? "INFERRED" : "NOT_INFERRED" } } };
13113
- }), app2.post("/api/connect/oauth/start", async (req, reply) => {
13169
+ }), app.post("/api/connect/oauth/start", async (req, reply) => {
13114
13170
  let { url, name } = req.body, plan = await resolvePlan(req), entitlement = mcpEntitlementForPlan(plan), actor = await requestActor(req);
13115
13171
  try {
13116
13172
  mcpManager.assertCanAddMcpConnection(PROOFLANE_PROJECT, entitlement);
@@ -13137,10 +13193,10 @@ ${answer}`
13137
13193
  authUrl: flow.authUrl,
13138
13194
  redirectUri: flow.redirectUri
13139
13195
  };
13140
- }), app2.get("/api/connect/oauth/status", async (req) => {
13196
+ }), app.get("/api/connect/oauth/status", async (req) => {
13141
13197
  let rec = oauthFlows.get(req.query.flowId);
13142
13198
  return rec || { status: "error", error: "Unknown flow." };
13143
- }), app2.post("/api/disconnect", async () => (activeMcpConnectionId ? await mcpManager.disconnectConnection(PROOFLANE_PROJECT, activeMcpConnectionId, "local-user") : await svc.disconnect(), activeMcpConnectionId = null, activeMcpAuthMode = "unknown", svc = new InspectorService(store), { ok: !0 })), app2.post("/api/tools/:name/call", async (req) => svc.callTool(req.params.name, req.body?.input ?? {})), app2.post("/api/tools/:name/snapshot", async (req) => svc.snapshotTool(req.params.name, req.body?.input ?? {})), app2.post("/api/security/verify-capability", async (req, reply) => {
13199
+ }), app.post("/api/disconnect", async () => (activeMcpConnectionId ? await mcpManager.disconnectConnection(PROOFLANE_PROJECT, activeMcpConnectionId, "local-user") : await svc.disconnect(), activeMcpConnectionId = null, activeMcpAuthMode = "unknown", svc = new InspectorService(store), { ok: !0 })), app.post("/api/tools/:name/call", async (req) => svc.callTool(req.params.name, req.body?.input ?? {})), app.post("/api/tools/:name/snapshot", async (req) => svc.snapshotTool(req.params.name, req.body?.input ?? {})), app.post("/api/security/verify-capability", async (req, reply) => {
13144
13200
  let toolName = typeof req.body?.toolName == "string" ? req.body.toolName : "";
13145
13201
  if (!toolName)
13146
13202
  return reply.code(400).send({ error: "toolName is required." });
@@ -13193,19 +13249,19 @@ ${answer}`
13193
13249
  } catch (error) {
13194
13250
  return error instanceof ExecutionGateError ? reply.code(400).send({ error: error.message }) : reply.code(500).send({ error: error instanceof Error ? error.message : "Capability verification failed." });
13195
13251
  }
13196
- }), app2.post("/api/diff/snapshot", async (req) => svc.diffAgainst(req.body.snapshot)), app2.post("/api/diff/values", async (req) => diffTool(req.body.tool, req.body.expected, req.body.actual)), app2.post("/api/resources/read", async (req) => svc.readResource(req.body.uri)), app2.post("/api/prompts/:name/get", async (req) => svc.getPrompt(req.params.name, req.body?.args)), app2.post("/api/drift", async (req) => {
13252
+ }), app.post("/api/diff/snapshot", async (req) => svc.diffAgainst(req.body.snapshot)), app.post("/api/diff/values", async (req) => diffTool(req.body.tool, req.body.expected, req.body.actual)), app.post("/api/resources/read", async (req) => svc.readResource(req.body.uri)), app.post("/api/prompts/:name/get", async (req) => svc.getPrompt(req.params.name, req.body?.args)), app.post("/api/drift", async (req) => {
13197
13253
  let current = svc.getCapabilities();
13198
13254
  if (!current)
13199
13255
  throw new Error("Not connected.");
13200
13256
  return detectCapabilityDrift(req.body.baseline, current);
13201
- }), app2.post("/api/record/start", async (req) => (svc.startRecording(req.body?.label), { ok: !0, recording: !0 })), app2.get("/api/record/status", async () => ({ recording: svc.isRecording() })), app2.post("/api/record/stop", async () => svc.stopRecording()), app2.get("/api/sessions", async () => svc.listSessions()), app2.get("/api/sessions/:id", async (req) => {
13257
+ }), app.post("/api/record/start", async (req) => (svc.startRecording(req.body?.label), { ok: !0, recording: !0 })), app.get("/api/record/status", async () => ({ recording: svc.isRecording() })), app.post("/api/record/stop", async () => svc.stopRecording()), app.get("/api/sessions", async () => svc.listSessions()), app.get("/api/sessions/:id", async (req) => {
13202
13258
  let session = svc.getSession(req.params.id);
13203
13259
  if (!session)
13204
13260
  throw new Error(`Session not found: ${req.params.id}`);
13205
13261
  return session;
13206
- }), app2.post("/api/sessions/:id/golden", async (req) => (svc.markGolden(req.params.id, req.body?.golden ?? !0), { ok: !0 })), app2.post("/api/sessions/:id/automate", async (req) => svc.automate(req.params.id, req.body.format)), app2.post("/api/sessions/:id/fault", async (req) => svc.injectFault(req.params.id, req.body.step, req.body.type));
13262
+ }), app.post("/api/sessions/:id/golden", async (req) => (svc.markGolden(req.params.id, req.body?.golden ?? !0), { ok: !0 })), app.post("/api/sessions/:id/automate", async (req) => svc.automate(req.params.id, req.body.format)), app.post("/api/sessions/:id/fault", async (req) => svc.injectFault(req.params.id, req.body.step, req.body.type));
13207
13263
  let HTTP_TIMEOUT_MS = 3e4, HTTP_BODY_CAP = 2e6;
13208
- app2.post("/api/http/request", async (req) => {
13264
+ app.post("/api/http/request", async (req) => {
13209
13265
  let { method, url, headers, body } = req.body, start = Date.now(), controller = new AbortController(), timer = setTimeout(() => controller.abort(), HTTP_TIMEOUT_MS), hasBody = !["GET", "HEAD"].includes(method.toUpperCase());
13210
13266
  try {
13211
13267
  let res = await fetch(url, {
@@ -13236,9 +13292,9 @@ ${answer}`
13236
13292
  } finally {
13237
13293
  clearTimeout(timer);
13238
13294
  }
13239
- }), app2.post("/api/http/snapshot", async (req) => svc.saveHttpSnapshot(req.body.request, req.body.response, req.body.origin ?? "captured")), app2.get("/api/snapshots", async () => svc.listSnapshots()), app2.patch("/api/snapshots/:id", async (req, reply) => svc.updateSnapshot(req.params.id, req.body) ? { ok: !0 } : reply.code(404).send({ ok: !1, error: "Contract not found." })), app2.delete("/api/snapshots/:id", async (req) => (svc.deleteSnapshot(req.params.id), { ok: !0 })), app2.post("/api/automate/contracts", async (req) => svc.automateSnapshots(req.body.snapshotIds, req.body.format)), app2.post("/api/prompts/generate", async (req) => ({
13295
+ }), app.post("/api/http/snapshot", async (req) => svc.saveHttpSnapshot(req.body.request, req.body.response, req.body.origin ?? "captured")), app.get("/api/snapshots", async () => svc.listSnapshots()), app.patch("/api/snapshots/:id", async (req, reply) => svc.updateSnapshot(req.params.id, req.body) ? { ok: !0 } : reply.code(404).send({ ok: !1, error: "Contract not found." })), app.delete("/api/snapshots/:id", async (req) => (svc.deleteSnapshot(req.params.id), { ok: !0 })), app.post("/api/automate/contracts", async (req) => svc.automateSnapshots(req.body.snapshotIds, req.body.format)), app.post("/api/prompts/generate", async (req) => ({
13240
13296
  prompts: svc.generatePromptsForTool(req.body.tool)
13241
- })), app2.get("/api/prompts/custom", async () => svc.listCustomPrompts()), app2.post("/api/llm/run", async (req) => callLlm(req.body)), app2.post("/api/prompts/run-agent", async (req, reply) => {
13297
+ })), app.get("/api/prompts/custom", async () => svc.listCustomPrompts()), app.post("/api/llm/run", async (req) => callLlm(req.body)), app.post("/api/prompts/run-agent", async (req, reply) => {
13242
13298
  let { tool, prompt, llm } = req.body, t = svc.getCapabilities()?.tools.find((x) => x.name === tool);
13243
13299
  return t ? runAgent({
13244
13300
  ...llm,
@@ -13249,7 +13305,7 @@ ${answer}`
13249
13305
  return { output: r.output, isError: r.isError };
13250
13306
  }
13251
13307
  }) : reply.code(400).send({ ok: !1, toolCalls: [], error: `Tool "${tool}" isn't on the current connection \u2014 connect first.`, latencyMs: 0 });
13252
- }), app2.post("/api/rag/hosted-run", async (req, reply) => {
13308
+ }), app.post("/api/rag/hosted-run", async (req, reply) => {
13253
13309
  let cases = Array.isArray(req.body?.cases) ? req.body.cases.filter((candidate) => candidate && typeof candidate.id == "string" && hostedRagCaseQuery(candidate).trim()) : [], capabilities = svc.getCapabilities();
13254
13310
  if (!capabilities)
13255
13311
  return reply.code(400).send({ ok: !1, error: "Connect to an MCP server first \u2014 RAG Assurance runs against its retrieval tools." });
@@ -13432,7 +13488,7 @@ ${answer}`
13432
13488
  evidence: JSON.stringify(mcpSnapshot ? { ...snapshot, mcp: mcpSnapshot.mcp, hostedScanId: hostedScan.id } : { ...snapshot, hostedScanId: hostedScan.id })
13433
13489
  }), diff = previous ? hostedRagScoreDiff(previous, snapshot) : void 0;
13434
13490
  return finish({ ok: !0, report, diff, run, hostedScan });
13435
- }), app2.get("/api/rag/hosted-diff/:id", async (req, reply) => {
13491
+ }), app.get("/api/rag/hosted-diff/:id", async (req, reply) => {
13436
13492
  let runs = svc.listRuns(1e3).filter((record6) => record6.pillar === "rag"), index = runs.findIndex((record6) => record6.id === req.params.id);
13437
13493
  if (index === -1)
13438
13494
  return reply.code(404).send({ ok: !1, error: "Run not found." });
@@ -13472,7 +13528,7 @@ ${answer}`
13472
13528
  durationMs
13473
13529
  });
13474
13530
  }
13475
- app2.post("/api/perf/run", async (req, reply) => {
13531
+ app.post("/api/perf/run", async (req, reply) => {
13476
13532
  let { target, vus, durationS, targetMs } = req.body;
13477
13533
  if (vus > 5) {
13478
13534
  let plan = await resolvePlan(req);
@@ -13513,7 +13569,7 @@ ${answer}`
13513
13569
  };
13514
13570
  let metrics = await runLoadTest({ fire, vus: cappedVus, durationMs, targetMs });
13515
13571
  return mcpSnapshot ? { ok: !0, ...metrics, mcpSnapshot, mcpFact: recordBoundMcpFact(mcpSnapshot, metrics.errors === 0) } : { ok: !0, ...metrics };
13516
- }), app2.post("/api/prompts/generate-ai", async (req, reply) => {
13572
+ }), app.post("/api/prompts/generate-ai", async (req, reply) => {
13517
13573
  let plan = await resolvePlan(req);
13518
13574
  if (!plan.hosted)
13519
13575
  return reply.code(402).send({
@@ -13542,17 +13598,17 @@ Cover a mix of: positive (valid, useful requests), negative (misuse \u2014 missi
13542
13598
  skipped: parsed.length - saved.length,
13543
13599
  tokens: (res.usage?.inputTokens ?? 0) + (res.usage?.outputTokens ?? 0)
13544
13600
  };
13545
- }), app2.post("/api/prompts/custom/:id/golden", async (req) => (svc.setPromptGolden(req.params.id, req.body.expected, req.body.assert ?? "similar"), { ok: !0 })), app2.post("/api/prompts/custom/:id/checks", async (req) => (svc.setPromptChecks(req.params.id, {
13601
+ }), app.post("/api/prompts/custom/:id/golden", async (req) => (svc.setPromptGolden(req.params.id, req.body.expected, req.body.assert ?? "similar"), { ok: !0 })), app.post("/api/prompts/custom/:id/checks", async (req) => (svc.setPromptChecks(req.params.id, {
13546
13602
  input: req.body.input,
13547
13603
  assertions: req.body.assertions,
13548
13604
  checkSchema: req.body.checkSchema
13549
- }), { ok: !0 })), app2.post("/api/prompts/assert", async (req, reply) => {
13605
+ }), { ok: !0 })), app.post("/api/prompts/assert", async (req, reply) => {
13550
13606
  try {
13551
13607
  return { ok: !0, ...await svc.assertTool(req.body.tool, req.body.input ?? {}, req.body.assertions ?? [], req.body.checkSchema ?? !1) };
13552
13608
  } catch (e) {
13553
13609
  return reply.code(400).send({ ok: !1, error: e instanceof Error ? e.message : String(e) });
13554
13610
  }
13555
- }), app2.post("/api/prompts/custom", async (req, reply) => {
13611
+ }), app.post("/api/prompts/custom", async (req, reply) => {
13556
13612
  let plan = await resolvePlan(req);
13557
13613
  return !isUnlimited(plan.prompts) && svc.listCustomPrompts().length >= plan.prompts ? reply.code(402).send({
13558
13614
  ok: !1,
@@ -13562,7 +13618,7 @@ Cover a mix of: positive (valid, useful requests), negative (misuse \u2014 missi
13562
13618
  limit: plan.prompts,
13563
13619
  error: `Your ${plan.label} plan stores up to ${plan.prompts} test prompts. Delete one or upgrade to add more.`
13564
13620
  }) : svc.addCustomPrompt(req.body.name, req.body.content, req.body.tool);
13565
- }), app2.patch("/api/prompts/custom/:id", async (req) => (svc.updateCustomPrompt(req.params.id, req.body), { ok: !0 })), app2.delete("/api/prompts/custom/:id", async (req) => (svc.deleteCustomPrompt(req.params.id), { ok: !0 })), app2.post("/api/prompts/generate-cases", async (req, reply) => {
13621
+ }), app.patch("/api/prompts/custom/:id", async (req) => (svc.updateCustomPrompt(req.params.id, req.body), { ok: !0 })), app.delete("/api/prompts/custom/:id", async (req) => (svc.deleteCustomPrompt(req.params.id), { ok: !0 })), app.post("/api/prompts/generate-cases", async (req, reply) => {
13566
13622
  let plan = await resolvePlan(req);
13567
13623
  if (!plan.hosted)
13568
13624
  return reply.code(402).send({
@@ -13614,7 +13670,7 @@ Assertions must be objectively checkable against the tool's JSON response. Never
13614
13670
  errorKind: "hosted-generation",
13615
13671
  error: "The model did not return usable test cases. Retry, or choose a model that reliably follows structured-output instructions."
13616
13672
  });
13617
- }), app2.post("/api/prompts/custom/bulk", async (req, reply) => {
13673
+ }), app.post("/api/prompts/custom/bulk", async (req, reply) => {
13618
13674
  let cases = (req.body?.cases ?? []).filter((c) => c && typeof c.content == "string" && c.content.trim());
13619
13675
  if (!cases.length)
13620
13676
  return reply.code(400).send({ ok: !1, error: "Select at least one reviewed case to save." });
@@ -13666,7 +13722,7 @@ Assertions must be objectively checkable against the tool's JSON response. Never
13666
13722
  let all = svc.getCapabilities()?.tools ?? [], enabled = session.config.enabledTools;
13667
13723
  return enabled && enabled.length ? all.filter((t) => enabled.includes(t.name)) : all;
13668
13724
  };
13669
- app2.post("/api/prompt-studio/sessions", async (req) => {
13725
+ app.post("/api/prompt-studio/sessions", async (req) => {
13670
13726
  let body = req.body ?? {}, now = (/* @__PURE__ */ new Date()).toISOString(), session = {
13671
13727
  id: `ps-${randomUUID7().slice(0, 8)}`,
13672
13728
  name: (body.name ?? "").trim().slice(0, 120) || `Session ${(/* @__PURE__ */ new Date()).toLocaleString()}`,
@@ -13697,13 +13753,13 @@ Assertions must be objectively checkable against the tool's JSON response. Never
13697
13753
  oldest && studioSessions.delete(oldest.id);
13698
13754
  }
13699
13755
  return { ok: !0, session: studioSummary(session), events: [] };
13700
- }), app2.get("/api/prompt-studio/sessions", async () => ({
13756
+ }), app.get("/api/prompt-studio/sessions", async () => ({
13701
13757
  ok: !0,
13702
13758
  sessions: [...studioSessions.values()].sort((a, b) => b.updatedAt.localeCompare(a.updatedAt)).map(studioSummary)
13703
- })), app2.get("/api/prompt-studio/sessions/:id", async (req, reply) => {
13759
+ })), app.get("/api/prompt-studio/sessions/:id", async (req, reply) => {
13704
13760
  let session = studioSessions.get(req.params.id);
13705
13761
  return session ? { ok: !0, session: studioSummary(session), events: session.events } : reply.code(404).send({ ok: !1, error: "That Prompt Studio session is no longer available." });
13706
- }), app2.get("/api/prompt-studio/sessions/:id/suggestions", async (req, reply) => {
13762
+ }), app.get("/api/prompt-studio/sessions/:id/suggestions", async (req, reply) => {
13707
13763
  let session = studioSessions.get(req.params.id);
13708
13764
  if (!session)
13709
13765
  return reply.code(404).send({ ok: !1, error: "That Prompt Studio session is no longer available." });
@@ -13713,10 +13769,10 @@ Assertions must be objectively checkable against the tool's JSON response. Never
13713
13769
  observation: { prompt: observation.prompt, answer: observation.answer, toolCalls: observation.toolCalls },
13714
13770
  suggestions: suggestPromptTestChecks(observation)
13715
13771
  };
13716
- }), app2.delete("/api/prompt-studio/sessions/:id", async (req) => (studioSessions.delete(req.params.id), { ok: !0 })), app2.post("/api/prompt-studio/sessions/:id/stop", async (req, reply) => {
13772
+ }), app.delete("/api/prompt-studio/sessions/:id", async (req) => (studioSessions.delete(req.params.id), { ok: !0 })), app.post("/api/prompt-studio/sessions/:id/stop", async (req, reply) => {
13717
13773
  let session = studioSessions.get(req.params.id);
13718
13774
  return session ? (session.stopRequested = !0, { ok: !0, stopping: session.running }) : reply.code(404).send({ ok: !1, error: "That Prompt Studio session is no longer available." });
13719
- }), app2.post("/api/prompt-studio/sessions/:id/messages", async (req, reply) => {
13775
+ }), app.post("/api/prompt-studio/sessions/:id/messages", async (req, reply) => {
13720
13776
  let session = studioSessions.get(req.params.id);
13721
13777
  if (!session)
13722
13778
  return reply.code(404).send({ ok: !1, error: "That Prompt Studio session is no longer available. Start a new session." });
@@ -13795,7 +13851,7 @@ Assertions must be objectively checkable against the tool's JSON response. Never
13795
13851
  } finally {
13796
13852
  session.running = !1, session.stopRequested = !1;
13797
13853
  }
13798
- }), app2.post("/api/prompt-studio/sessions/:id/tools/:tool", async (req, reply) => {
13854
+ }), app.post("/api/prompt-studio/sessions/:id/tools/:tool", async (req, reply) => {
13799
13855
  let session = studioSessions.get(req.params.id);
13800
13856
  if (!session)
13801
13857
  return reply.code(404).send({ ok: !1, error: "That Prompt Studio session is no longer available." });
@@ -13840,7 +13896,7 @@ Assertions must be objectively checkable against the tool's JSON response. Never
13840
13896
  let attributed = attributeError(error instanceof Error ? error.message : String(error), "tool");
13841
13897
  return pushStudioEvent(session, turnId, "run-failed", { tool: tool.name, error: attributed.detail, errorKind: attributed.kind }), reply.code(502).send({ ok: !1, error: attributed.detail, errorKind: attributed.kind, errorTitle: attributed.title });
13842
13898
  }
13843
- }), app2.post("/api/model-scans/run", async (req, reply) => {
13899
+ }), app.post("/api/model-scans/run", async (req, reply) => {
13844
13900
  let target = req.body?.path?.trim();
13845
13901
  if (!target || target.length > 4096)
13846
13902
  return reply.code(400).send({ ok: !1, error: "A valid local model file or directory path is required." });
@@ -13852,7 +13908,7 @@ Assertions must be objectively checkable against the tool's JSON response. Never
13852
13908
  maxArchiveExpandedBytes: Math.round(maxArchiveMb * 1024 * 1024)
13853
13909
  });
13854
13910
  return store.saveModelScan(report), reply.header("Cache-Control", "no-store"), { ok: !0, report };
13855
- }), app2.get("/api/model-scans", async (req, reply) => {
13911
+ }), app.get("/api/model-scans", async (req, reply) => {
13856
13912
  let limit = Math.max(1, Math.min(200, Math.trunc(Number(req.query.limit) || 25)));
13857
13913
  return reply.header("Cache-Control", "no-store"), store.listModelScans(limit).map((report) => ({
13858
13914
  scanId: report.scanId,
@@ -13863,16 +13919,16 @@ Assertions must be objectively checkable against the tool's JSON response. Never
13863
13919
  summary: report.summary,
13864
13920
  artifactIdentity: report.artifactIdentity
13865
13921
  }));
13866
- }), app2.get("/api/model-scans/:id", async (req, reply) => {
13922
+ }), app.get("/api/model-scans/:id", async (req, reply) => {
13867
13923
  let report = store.getModelScan(req.params.id);
13868
13924
  return report ? (reply.header("Cache-Control", "no-store"), { ok: !0, report }) : reply.code(404).send({ ok: !1, error: "Model scan not found." });
13869
- }), app2.get("/api/model-scans/:id/export", async (req, reply) => {
13925
+ }), app.get("/api/model-scans/:id/export", async (req, reply) => {
13870
13926
  let report = store.getModelScan(req.params.id);
13871
13927
  if (!report)
13872
13928
  return reply.code(404).send({ ok: !1, error: "Model scan not found." });
13873
13929
  let safeName = report.target.displayName.replace(/[^A-Za-z0-9._-]+/g, "-").slice(0, 100) || "model", format = String(req.query.format ?? "json").toLowerCase();
13874
13930
  return reply.header("Cache-Control", "no-store"), format === "html" ? (reply.type("text/html; charset=utf-8").header("Content-Disposition", `attachment; filename="${safeName}-prooflane-model-scan.html"`), reply.send(modelScanToHtml(report))) : format === "sarif" ? (reply.type("application/sarif+json").header("Content-Disposition", `attachment; filename="${safeName}-prooflane-model-scan.sarif.json"`), reply.send(JSON.stringify(modelScanToSarif(report), null, 2))) : (reply.type("application/json").header("Content-Disposition", `attachment; filename="${safeName}-prooflane-model-scan.json"`), reply.send(JSON.stringify(report, null, 2)));
13875
- }), app2.delete("/api/model-scans/:id", async (req, reply) => store.deleteModelScan(req.params.id) ? { ok: !0 } : reply.code(404).send({ ok: !1, error: "Model scan not found." })), app2.get("/api/model-security/packs", async (_req, reply) => (reply.header("Cache-Control", "no-store"), {
13931
+ }), app.delete("/api/model-scans/:id", async (req, reply) => store.deleteModelScan(req.params.id) ? { ok: !0 } : reply.code(404).send({ ok: !1, error: "Model scan not found." })), app.get("/api/model-security/packs", async (_req, reply) => (reply.header("Cache-Control", "no-store"), {
13876
13932
  packs: MODEL_SECURITY_PACKS,
13877
13933
  checks: MODEL_SECURITY_RULES.map((rule) => ({
13878
13934
  id: rule.id,
@@ -13886,7 +13942,7 @@ Assertions must be objectively checkable against the tool's JSON response. Never
13886
13942
  stages: MODEL_SCAN_STAGES.map((stage) => ({ id: stage, label: MODEL_SCAN_STAGE_LABEL[stage] })),
13887
13943
  sourceTypes: SUPPORTED_MODEL_SOURCE_TYPES,
13888
13944
  evidenceClasses: MODEL_EVIDENCE_CLASSES.map((id) => ({ id, label: MODEL_EVIDENCE_LABEL[id] }))
13889
- })), app2.post("/api/model-security/run", async (req, reply) => {
13945
+ })), app.post("/api/model-security/run", async (req, reply) => {
13890
13946
  let target = req.body?.target;
13891
13947
  if (!target?.sourceType || !target.source?.trim())
13892
13948
  return reply.code(400).send({ ok: !1, error: "A model security scan needs a target source type and source." });
@@ -13929,19 +13985,19 @@ Assertions must be objectively checkable against the tool's JSON response. Never
13929
13985
  let message2 = error instanceof Error ? error.message : String(error);
13930
13986
  return wantStream && streamOpen ? (streamWrite({ t: "done", ok: !1, error: message2 }), reply.raw.end(), reply) : reply.code(400).send({ ok: !1, error: message2 });
13931
13987
  }
13932
- }), app2.get("/api/model-security", async (req, reply) => {
13988
+ }), app.get("/api/model-security", async (req, reply) => {
13933
13989
  let limit = Math.max(1, Math.min(200, Math.trunc(Number(req.query.limit) || 25)));
13934
13990
  return reply.header("Cache-Control", "no-store"), store.listModelSecurityScans(limit).map(modelSecuritySummary);
13935
- }), app2.get("/api/model-security/:id", async (req, reply) => {
13991
+ }), app.get("/api/model-security/:id", async (req, reply) => {
13936
13992
  let report = store.getModelSecurityScan(req.params.id);
13937
13993
  return report ? (reply.header("Cache-Control", "no-store"), { ok: !0, report }) : reply.code(404).send({ ok: !1, error: "Model security scan not found." });
13938
- }), app2.get("/api/model-security/:id/export", async (req, reply) => {
13994
+ }), app.get("/api/model-security/:id/export", async (req, reply) => {
13939
13995
  let report = store.getModelSecurityScan(req.params.id);
13940
13996
  if (!report)
13941
13997
  return reply.code(404).send({ ok: !1, error: "Model security scan not found." });
13942
13998
  let safeName = report.target.displayName.replace(/[^A-Za-z0-9._-]+/g, "-").slice(0, 100) || "model", format = String(req.query.format ?? "json").toLowerCase();
13943
13999
  return reply.header("Cache-Control", "no-store"), format === "html" ? (reply.type("text/html; charset=utf-8").header("Content-Disposition", `attachment; filename="${safeName}-model-supply-chain.html"`), reply.send(modelSecurityToHtml(report))) : format === "sarif" ? (reply.type("application/sarif+json").header("Content-Disposition", `attachment; filename="${safeName}-model-supply-chain.sarif.json"`), reply.send(JSON.stringify(modelSecurityToSarif(report), null, 2))) : (reply.type("application/json").header("Content-Disposition", `attachment; filename="${safeName}-model-supply-chain.json"`), reply.send(JSON.stringify(report, null, 2)));
13944
- }), app2.delete("/api/model-security/:id", async (req, reply) => store.deleteModelSecurityScan(req.params.id) ? { ok: !0 } : reply.code(404).send({ ok: !1, error: "Model security scan not found." })), app2.post("/api/runs", async (req) => svc.recordRun(req.body)), app2.get("/api/runs", async (req, reply) => {
14000
+ }), app.delete("/api/model-security/:id", async (req, reply) => store.deleteModelSecurityScan(req.params.id) ? { ok: !0 } : reply.code(404).send({ ok: !1, error: "Model security scan not found." })), app.post("/api/runs", async (req) => svc.recordRun(req.body)), app.get("/api/runs", async (req, reply) => {
13945
14001
  let plan = await resolvePlan(req), requestedLimit = Number(req.query.limit), limit = Number.isFinite(requestedLimit) && requestedLimit > 0 ? Math.min(1e3, Math.trunc(requestedLimit)) : void 0;
13946
14002
  reply.header("Cache-Control", "no-store");
13947
14003
  let runs = svc.listRuns(limit);
@@ -13951,26 +14007,32 @@ Assertions must be objectively checkable against the tool's JSON response. Never
13951
14007
  return runs.filter((run) => Date.parse(run.createdAt) >= oldest);
13952
14008
  });
13953
14009
  let uiDist = process.env.KAWACH_UI_DIST ?? join4(__dirname, "../../ui/dist");
13954
- return existsSync2(uiDist) && (app2.register(fastifyStatic, { root: uiDist }), app2.setNotFoundHandler((req, reply) => {
14010
+ return existsSync2(uiDist) && (app.register(fastifyStatic, { root: uiDist }), app.setNotFoundHandler((req, reply) => {
13955
14011
  if (req.url.startsWith("/api")) {
13956
14012
  reply.code(404).send({ error: "Not found" });
13957
14013
  return;
13958
14014
  }
13959
14015
  reply.sendFile("index.html");
13960
- })), app2.setErrorHandler((err, req, reply) => {
14016
+ })), app.setErrorHandler((err, req, reply) => {
13961
14017
  let upstream = err instanceof KawachError ? err.statusCode : void 0;
13962
14018
  req.log.error({ err, upstream }, "Inspector request failed"), reply.code(upstream ? 502 : 500).send({ error: publicServerError(req.url), reference: req.id });
13963
- }), app2.addHook("onClose", async () => store.close()), app2;
14019
+ }), app.addHook("onClose", async () => store.close()), app;
14020
+ }
14021
+
14022
+ // ../server/dist/start.js
14023
+ var PORT = Number(process.env.KAWACH_UI_PORT ?? 7357), HOST = "127.0.0.1";
14024
+ async function startServer(options = {}) {
14025
+ let app = buildApp();
14026
+ options.configureApp?.(app), await app.listen({ port: PORT, host: HOST }), console.log(`Kawach Inspector UI \u2192 http://localhost:${PORT}`);
14027
+ for (let sig of ["SIGINT", "SIGTERM"])
14028
+ process.once(sig, () => {
14029
+ app.close().finally(() => process.exit(0));
14030
+ });
14031
+ return app;
14032
+ }
14033
+ function failServerStart(error) {
14034
+ console.error("Failed to start Kawach Inspector server:", error), process.exit(1);
13964
14035
  }
13965
14036
 
13966
14037
  // ../server/dist/index.js
13967
- var PORT = Number(process.env.KAWACH_UI_PORT ?? 7357), HOST = "127.0.0.1", app = buildApp();
13968
- app.listen({ port: PORT, host: HOST }).then(() => {
13969
- console.log(`Kawach Inspector UI \u2192 http://localhost:${PORT}`);
13970
- }).catch((err) => {
13971
- console.error("Failed to start Kawach Inspector server:", err), process.exit(1);
13972
- });
13973
- for (let sig of ["SIGINT", "SIGTERM"])
13974
- process.on(sig, () => {
13975
- app.close().finally(() => process.exit(0));
13976
- });
14038
+ startServer().catch(failServerStart);