56 lines
2.3 KiB
TypeScript
56 lines
2.3 KiB
TypeScript
// SPEC: PJ2026-010401 Web工作台 draft-2026-06-17-r0; PJ2026-010403 API契约 draft-2026-06-17-r0.
|
|
// Responsibility: Read-only helper for capturing and redacting Workbench fixture seeds from a controlled runtime.
|
|
|
|
const baseUrl = (process.env.HWLAB_WORKBENCH_CAPTURE_BASE_URL ?? "https://hwlab.pikapython.com").replace(/\/+$/u, "");
|
|
const projectId = process.env.HWLAB_WORKBENCH_CAPTURE_PROJECT_ID ?? "prj_hwpod_workbench";
|
|
const conversationId = process.env.HWLAB_WORKBENCH_CAPTURE_CONVERSATION_ID ?? "";
|
|
const authorization = process.env.HWLAB_API_KEY ? `Bearer ${process.env.HWLAB_API_KEY}` : "";
|
|
|
|
const headers: Record<string, string> = { accept: "application/json" };
|
|
if (authorization) headers.authorization = authorization;
|
|
|
|
const paths = [
|
|
`/v1/workbench/workspace?projectId=${encodeURIComponent(projectId)}`,
|
|
`/v1/agent/conversations?projectId=${encodeURIComponent(projectId)}${conversationId ? `&includeConversationId=${encodeURIComponent(conversationId)}` : ""}`,
|
|
conversationId ? `/v1/agent/conversations/${encodeURIComponent(conversationId)}?projectId=${encodeURIComponent(projectId)}` : ""
|
|
].filter(Boolean);
|
|
|
|
const captured: Record<string, unknown> = {
|
|
metadata: {
|
|
capturedFrom: { origin: baseUrl, projectId, conversationId: conversationId || null },
|
|
capturedAt: new Date().toISOString(),
|
|
schemaVersion: "workbench-e2e-capture.v1",
|
|
redactionVersion: "redact-stable-pseudo-ids.v1",
|
|
valuesPrinted: false
|
|
},
|
|
responses: {}
|
|
};
|
|
|
|
for (const path of paths) {
|
|
const response = await fetch(`${baseUrl}${path}`, { headers });
|
|
const body = await response.json().catch(() => null);
|
|
(captured.responses as Record<string, unknown>)[path] = {
|
|
status: response.status,
|
|
ok: response.ok,
|
|
body: redact(body)
|
|
};
|
|
}
|
|
|
|
console.log(JSON.stringify(captured, null, 2));
|
|
|
|
function redact(value: unknown): unknown {
|
|
if (Array.isArray(value)) return value.map(redact);
|
|
if (!value || typeof value !== "object") return value;
|
|
const output: Record<string, unknown> = {};
|
|
for (const [key, raw] of Object.entries(value as Record<string, unknown>)) {
|
|
if (/api[-_]?key|authorization|cookie|token|secret|password|dsn|credential/iu.test(key)) {
|
|
output[key] = "<redacted>";
|
|
continue;
|
|
}
|
|
output[key] = redact(raw);
|
|
}
|
|
return output;
|
|
}
|
|
|
|
export {};
|