@wenathlan/extension 1.1.63 → 1.1.65

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.
Files changed (55) hide show
  1. package/README.md +5 -3
  2. package/dist/datagrid.d.ts +46 -0
  3. package/dist/datagrid.d.ts.map +1 -0
  4. package/dist/evidenceviews.d.ts +45 -0
  5. package/dist/evidenceviews.d.ts.map +1 -0
  6. package/dist/index.d.ts +11 -1
  7. package/dist/index.d.ts.map +1 -1
  8. package/dist/index.js +1155 -1
  9. package/dist/index.js.map +4 -4
  10. package/dist/memory.d.ts +65 -1
  11. package/dist/memory.d.ts.map +1 -1
  12. package/dist/pickerviews.d.ts +72 -0
  13. package/dist/pickerviews.d.ts.map +1 -0
  14. package/dist/planreview.d.ts +87 -0
  15. package/dist/planreview.d.ts.map +1 -0
  16. package/dist/policy.d.ts +105 -0
  17. package/dist/policy.d.ts.map +1 -1
  18. package/dist/portability.d.ts +35 -0
  19. package/dist/portability.d.ts.map +1 -0
  20. package/dist/protocol.d.ts +248 -0
  21. package/dist/protocol.d.ts.map +1 -1
  22. package/dist/quickactions.d.ts +46 -0
  23. package/dist/quickactions.d.ts.map +1 -0
  24. package/dist/siteprefs.d.ts +45 -0
  25. package/dist/siteprefs.d.ts.map +1 -0
  26. package/dist/statusviews.d.ts +65 -0
  27. package/dist/statusviews.d.ts.map +1 -0
  28. package/dist/surfaces.d.ts +59 -0
  29. package/dist/surfaces.d.ts.map +1 -0
  30. package/dist/tourviews.d.ts +28 -0
  31. package/dist/tourviews.d.ts.map +1 -0
  32. package/dist/types.d.ts +429 -3
  33. package/dist/types.d.ts.map +1 -1
  34. package/dist/version.d.ts +1 -1
  35. package/extension/dist/background.js +1567 -2
  36. package/extension/dist/background.js.map +4 -4
  37. package/extension/dist/dashboardpage.html +14 -0
  38. package/extension/dist/dashboardpage.js +147 -0
  39. package/extension/dist/dashboardpage.js.map +7 -0
  40. package/extension/dist/manifest.json +5 -2
  41. package/extension/dist/offscreen.js +1 -0
  42. package/extension/dist/offscreen.js.map +2 -2
  43. package/extension/dist/optionspage.html +18 -0
  44. package/extension/dist/optionspage.js +267 -0
  45. package/extension/dist/optionspage.js.map +7 -0
  46. package/extension/dist/pagebridge.js.map +1 -1
  47. package/extension/dist/popup.html +4 -1
  48. package/extension/dist/popup.js +257 -0
  49. package/extension/dist/popup.js.map +3 -3
  50. package/extension/dist/sidepanel.html +7 -2
  51. package/extension/dist/sidepanel.js +360 -0
  52. package/extension/dist/sidepanel.js.map +2 -2
  53. package/extension/dist/style.css +3 -1
  54. package/extension/manifest.json +5 -2
  55. package/package.json +1 -1
@@ -1,7 +1,12 @@
1
1
  <!doctype html>
2
2
  <html lang="en">
3
3
  <head><meta charset="utf-8"><meta name="viewport" content="width=device-width,initial-scale=1"><title>Devthink review</title><link rel="stylesheet" href="style.css"></head>
4
- <body><main class="wide"><header><p class="eyebrow">REVIEW GATE</p><h1>Plan before action</h1><p>Every browser operation remains blocked until the user reviews and approves it here.</p></header><label for="objective">Objective</label><textarea id="objective" rows="4" placeholder="Describe a browser task to turn into a reviewable plan."></textarea><div class="actions"><button id="localplan">Create local observation plan</button><button id="remoteplan" class="secondary">Ask configured endpoint</button><button id="diagnostic" class="secondary">Capture local diagnostics</button></div>
5
- <div class="actions"><input id="command" placeholder="Ask any connected model in plain language" aria-label="Natural language command"><button id="commandsend" class="secondary">Ask model</button><span id="intentbadge" class="muted"></span></div><p id="status" role="status">Loading session state.</p><p id="capabilitiestext" role="status" class="muted">Optional capabilities unknown.</p><section><h2>Current plan</h2><progress id="planprogress" max="1" value="0"></progress><div id="plan" class="panel"></div></section><section><h2>Clickable map</h2><ol id="map" class="audit maplist"></ol></section><section><h2>Navigation trail</h2><ol id="trail" class="audit"></ol></section><section><h2>Navigation state</h2><div id="navigation" class="panel"></div></section><section><h2>Tabs and windows</h2><div id="tabswindows" class="panel"></div></section><section><h2>Forms and data</h2><div id="forms" class="panel"></div></section><section><h2>Files and downloads</h2><div id="files" class="panel"></div></section><section><h2>Capture gallery</h2><div id="captures" class="panel"></div></section><section><h2>Media</h2><div id="media" class="panel"></div></section><section><h2>Network calls</h2><div id="calls" class="panel"></div></section><section><h2>Network view</h2><div id="netview" class="panel"></div></section><section><h2>Traffic control</h2><div id="traffic" class="panel"></div></section><section><h2>Run timeline</h2><div id="timeline" class="panel"></div></section><section><h2>Debugger</h2><div id="debugger" class="panel"></div></section><section><h2>Profiling</h2><div id="profiling" class="panel"></div></section><section><h2>Emulation</h2><div id="emulation" class="panel"></div></section><section><h2>Session grid</h2><div id="sessiongrid" class="panel"></div></section><section><h2>History search</h2><div id="historysearch" class="panel"></div></section><section><h2>Site notes</h2><div id="sitenotes" class="panel"></div></section><section><h2>Scratchpad</h2><div id="scratchpad" class="panel"></div></section><section><h2>Session memory</h2><div id="sessionmemory" class="panel"></div></section><section><h2>Workflows</h2><div id="workflows" class="panel"></div></section><section><h2>Workflow editor</h2><div id="workfloweditor" class="panel"></div></section><section><h2>Triggers</h2><div id="triggers" class="panel"></div></section><section><h2>Agent protocol</h2><div id="agentprotocol" class="panel"></div></section>
4
+ <body><main class="wide"><header><p class="eyebrow">REVIEW GATE</p><h1>Plan before action</h1><p>Every browser operation remains blocked until the user reviews and approves it here.</p></header><label for="objective">Objective</label><textarea id="objective" rows="4" placeholder="Describe a browser task to turn into a reviewable plan."></textarea><div class="actions"><button id="localplan">Create local observation plan</button><button id="remoteplan" class="secondary">Ask configured endpoint</button><button id="tasksubmit" class="secondary">Submit task goal</button><button id="diagnostic" class="secondary">Capture local diagnostics</button></div>
5
+ <nav class="actions" id="workspacetabs" aria-label="Workspace tabs"><button id="tabplan" data-tab="plan">Plan</button><button id="tabrun" data-tab="run" class="secondary">Run</button><button id="tabreview" data-tab="review" class="secondary">Review</button><button id="tabdata" data-tab="data" class="secondary">Data</button></nav>
6
+ <div class="actions"><input id="command" placeholder="Ask any connected model in plain language" aria-label="Natural language command"><button id="commandsend" class="secondary">Ask model</button><span id="intentbadge" class="muted"></span></div>
7
+ <div class="actions"><input id="paletteinput" placeholder="Command palette (ctrl+.)" aria-label="Command palette search"><button id="paletteopen" class="secondary">Palette</button></div><div id="palettematches" class="panel"></div><p id="status" role="status">Loading session state.</p><p id="capabilitiestext" role="status" class="muted">Optional capabilities unknown.</p><section><h2>Current plan</h2><progress id="planprogress" max="1" value="0"></progress><div id="plan" class="panel"></div></section>
8
+ <section><h2>Plan cards</h2><div id="plancards" class="panel"></div></section>
9
+ <section><h2>Steps timeline</h2><div id="stepstimeline" class="panel"></div></section>
10
+ <section><h2>Data grid</h2><div class="actions"><input id="gridquery" placeholder="Filter rows locally" aria-label="Filter the datagrid rows locally"><button id="gridbuild" class="secondary">Preview extraction</button><button id="gridexport" class="secondary">Export csv</button></div><div id="datagrid" class="panel" role="table" aria-label="Extraction preview"></div></section><section><h2>Compare viewer</h2><div id="compareviewer" class="panel"></div></section><section><h2>Shot panel</h2><div id="shotpanel" class="panel"></div></section><section><h2>Picker overlay</h2><div class="actions"><button id="pickerstart" class="secondary">Start picker session</button></div><div id="picker" class="panel"></div></section><section><h2>Log stream</h2><div id="logstream" class="panel"></div></section><section><h2>Clickable map</h2><ol id="map" class="audit maplist"></ol></section><section><h2>Navigation trail</h2><ol id="trail" class="audit"></ol></section><section><h2>Navigation state</h2><div id="navigation" class="panel"></div></section><section><h2>Tabs and windows</h2><div id="tabswindows" class="panel"></div></section><section><h2>Forms and data</h2><div id="forms" class="panel"></div></section><section><h2>Files and downloads</h2><div id="files" class="panel"></div></section><section><h2>Capture gallery</h2><div id="captures" class="panel"></div></section><section><h2>Media</h2><div id="media" class="panel"></div></section><section><h2>Network calls</h2><div id="calls" class="panel"></div></section><section><h2>Network view</h2><div id="netview" class="panel"></div></section><section><h2>Traffic control</h2><div id="traffic" class="panel"></div></section><section><h2>Run timeline</h2><div id="timeline" class="panel"></div></section><section><h2>Debugger</h2><div id="debugger" class="panel"></div></section><section><h2>Profiling</h2><div id="profiling" class="panel"></div></section><section><h2>Emulation</h2><div id="emulation" class="panel"></div></section><section><h2>Session grid</h2><div id="sessiongrid" class="panel"></div></section><section><h2>History search</h2><div id="historysearch" class="panel"></div></section><section><h2>Site notes</h2><div id="sitenotes" class="panel"></div></section><section><h2>Scratchpad</h2><div id="scratchpad" class="panel"></div></section><section><h2>Session memory</h2><div id="sessionmemory" class="panel"></div></section><section><h2>Workflows</h2><div id="workflows" class="panel"></div></section><section><h2>Workflow editor</h2><div id="workfloweditor" class="panel"></div></section><section><h2>Triggers</h2><div id="triggers" class="panel"></div></section><section><h2>Agent protocol</h2><div id="agentprotocol" class="panel"></div></section>
6
11
  <section><h2>Models</h2><div id="models" class="panel"></div></section><section><h2>Agents</h2><div id="agents" class="panel"></div></section><section><h2>Execution environments</h2><div id="environments" class="panel"></div></section><section><h2>Security</h2><div id="security" class="panel"></div></section><section><h2>Console diff</h2><div id="consolediff" class="panel"></div></section><section><h2>Datasets</h2><div id="datasets" class="panel"></div></section><section><h2>Consent banners</h2><div id="banners" class="panel"></div></section><section><h2>Accessibility tree</h2><div id="a11y" class="panel"></div></section><section><h2>Reader view</h2><div id="reader" class="panel"></div></section><section><h2>Detected shapes</h2><ol id="detections" class="audit maplist"></ol></section><section><h2>Watch stream</h2><ol id="stream" class="audit"></ol></section><section><h2>Snapshot diffs</h2><div id="diffs" class="panel"></div></section><section><h2>Derived selectors</h2><ol id="selectors" class="audit maplist"></ol></section><section><h2>Structured diagnostics</h2><ul id="diagnostics" class="audit"></ul></section><section><h2>Local audit</h2><ol id="audit" class="audit"></ol></section></main><script type="module" src="sidepanel.js"></script></body>
7
12
  </html>
@@ -7249,4 +7249,364 @@ function rendersessioninterface(context) {
7249
7249
  renderscratchpad(view);
7250
7250
  rendersessionmemory(view);
7251
7251
  }
7252
+ var tasksubmitbutton = document.querySelector("#tasksubmit");
7253
+ var plancardsroot = document.querySelector("#plancards");
7254
+ var stepstimelineroot = document.querySelector("#stepstimeline");
7255
+ var logstreamroot = document.querySelector("#logstream");
7256
+ var logstreampaused = false;
7257
+ var logstreamfilter = {};
7258
+ function applyworkspacetabs(active) {
7259
+ const plantitles = ["Current plan", "Clickable map", "Detected shapes", "Derived selectors", "Structured diagnostics"];
7260
+ const reviewtitles = ["Plan cards", "Steps timeline", "Log stream", "Local audit", "Session grid", "History search", "Site notes", "Scratchpad", "Session memory", "Security", "Console diff", "Datasets", "Consent banners", "Accessibility tree", "Reader view", "Snapshot diffs", "Agent protocol", "Models"];
7261
+ const datatitles = ["Data grid", "Compare viewer", "Shot panel", "Picker overlay"];
7262
+ for (const section of Array.from(document.querySelectorAll("main > section"))) {
7263
+ const title = section.querySelector("h2")?.textContent?.trim() ?? "";
7264
+ const tab = plantitles.includes(title) ? "plan" : reviewtitles.includes(title) ? "review" : datatitles.includes(title) ? "data" : "run";
7265
+ section.hidden = tab !== active;
7266
+ }
7267
+ for (const tab of ["plan", "run", "review", "data"]) {
7268
+ const element = document.querySelector(`#tab${tab}`);
7269
+ if (element) element.className = tab === active ? "" : "secondary";
7270
+ }
7271
+ }
7272
+ for (const tab of ["plan", "run", "review", "data"]) {
7273
+ document.querySelector(`#tab${tab}`)?.addEventListener("click", () => applyworkspacetabs(tab));
7274
+ }
7275
+ applyworkspacetabs("plan");
7276
+ tasksubmitbutton?.addEventListener("click", () => {
7277
+ const text = objective?.value ?? "";
7278
+ if (text.trim() === "") {
7279
+ status("Describe the goal first; the proposal flow needs its natural language task.", true);
7280
+ return;
7281
+ }
7282
+ void (async () => {
7283
+ status("The taskinput goal routes through the proposal flow; the plan generates.");
7284
+ const result = await request({ kind: "surface", task: { submit: { text, surface: "sidepanel" } } });
7285
+ status(`The taskinput goal became the plan ${result.plan?.id ?? ""}; review its plancards below.`);
7286
+ await refresh();
7287
+ await rendersurfacereview();
7288
+ })().catch((error) => status(error instanceof Error ? error.message : String(error), true));
7289
+ });
7290
+ async function renderplancards() {
7291
+ if (!plancardsroot) return;
7292
+ try {
7293
+ const result = await request({ kind: "surface", review: { groups: true } });
7294
+ plancardsroot.replaceChildren();
7295
+ if (result.cards.length === 0) {
7296
+ plancardsroot.textContent = "No plan exists yet; submit a task goal and the proposed steps render their cards here.";
7297
+ return;
7298
+ }
7299
+ for (const group of result.groups) {
7300
+ const heading = document.createElement("h3");
7301
+ heading.textContent = `${group.risk} steps${group.expanded ? " (expanded)" : ""}`;
7302
+ plancardsroot.append(heading);
7303
+ for (const card of group.cards) {
7304
+ const item = document.createElement("div");
7305
+ item.className = "panel";
7306
+ const label = document.createElement("strong");
7307
+ label.textContent = `${card.stepid} \xB7 ${card.kind} \xB7 ${card.environment}`;
7308
+ const summary = document.createElement("p");
7309
+ summary.textContent = card.summary;
7310
+ const options2 = document.createElement("p");
7311
+ options2.className = "muted";
7312
+ options2.textContent = card.options === "" ? "No reviewed options." : `Options: ${card.options}`;
7313
+ item.append(label, summary, options2);
7314
+ for (const correction of card.corrections) item.append(Object.assign(document.createElement("p"), { className: "muted", textContent: `Correction memory (${correction.source}): ${correction.reason}` }));
7315
+ if (card.editable) {
7316
+ item.append(button("Approve step", () => resolveStep(card.stepid, "approve")));
7317
+ item.append(" ", button("Reject step", () => resolveStep(card.stepid, "reject")));
7318
+ item.append(" ", button("Edit step", () => editStep(card.stepid)));
7319
+ }
7320
+ if (card.risk === "sensitive") item.append(" ", button("Diff preview", () => diffPreview(card.stepid)));
7321
+ plancardsroot.append(item);
7322
+ }
7323
+ }
7324
+ } catch (error) {
7325
+ plancardsroot.textContent = error instanceof Error ? error.message : String(error);
7326
+ }
7327
+ }
7328
+ async function resolveStep(stepid, resolution) {
7329
+ const result = await request({ kind: "surface", approve: { resolve: { stepid, resolution, surface: "sidepanel" } } });
7330
+ status(`The step ${result.resolution.stepid} resolved with a ${result.resolution.resolution}; the resolution landed in the immutable log.`);
7331
+ await refresh();
7332
+ await rendersurfacereview();
7333
+ }
7334
+ async function editStep(stepid) {
7335
+ if (!plancardsroot) return;
7336
+ const editor = document.createElement("div");
7337
+ editor.className = "panel";
7338
+ const input = document.createElement("textarea");
7339
+ input.rows = 4;
7340
+ input.value = '{ "kind": "click", "summary": "Describe the corrected step." }';
7341
+ const save = button("Save edit", async () => {
7342
+ const result = await request({ kind: "surface", approve: { resolve: { stepid, resolution: "edit", edited: input.value, surface: "sidepanel" } } });
7343
+ status(`The step ${result.resolution.stepid} carries the edited shape and the correction memory recorded the change.`);
7344
+ editor.remove();
7345
+ await refresh();
7346
+ await rendersurfacereview();
7347
+ });
7348
+ editor.append(input, save);
7349
+ plancardsroot.append(editor);
7350
+ }
7351
+ async function diffPreview(stepid) {
7352
+ const before = {};
7353
+ try {
7354
+ const preview = await request({ kind: "preview", stepid });
7355
+ if (preview.resolvedtarget?.selector !== void 0) before.selector = preview.resolvedtarget.selector;
7356
+ if (preview.resolvedtarget?.text !== void 0) before.text = preview.resolvedtarget.text;
7357
+ if (preview.resolvedtarget?.mode !== void 0) before.mode = preview.resolvedtarget.mode;
7358
+ } catch {
7359
+ }
7360
+ const result = await request({ kind: "surface", diff: { preview: { stepid, before } } });
7361
+ const detail = result.preview.changes.map((change) => `${change.kind} ${change.field}${change.before !== void 0 ? ` from ${change.before}` : ""}${change.after !== void 0 ? ` to ${change.after}` : ""}`).join("; ");
7362
+ const masked = Object.entries(result.preview.maskverdicts).map(([field, verdict]) => `${field}: ${verdict}`).join("; ");
7363
+ status(`Diff preview of ${stepid} (${result.preview.provenance}): ${detail === "" ? "no field changes" : detail}${masked === "" ? "" : ` \u2014 masked: ${masked}`}`);
7364
+ }
7365
+ async function renderstepstimeline() {
7366
+ if (!stepstimelineroot) return;
7367
+ try {
7368
+ const result = await request({ kind: "surface", timeline: { nodes: true } });
7369
+ stepstimelineroot.replaceChildren();
7370
+ if (result.nodes.length === 0) {
7371
+ stepstimelineroot.textContent = "No plan runs yet; the timeline derives its nodes from progress records with no new state.";
7372
+ return;
7373
+ }
7374
+ const list = document.createElement("ol");
7375
+ list.className = "audit";
7376
+ for (const node of result.nodes) {
7377
+ const item = document.createElement("li");
7378
+ item.id = node.anchor.slice(1);
7379
+ const badge = node.active ? " \u25B6" : "";
7380
+ const duration = node.durationms !== void 0 ? ` \xB7 ${node.durationms}ms` : "";
7381
+ const environment = node.environment !== void 0 ? ` \xB7 ${node.environment}` : "";
7382
+ item.textContent = `${node.stepid} ${node.kind} \u2014 ${node.status}${duration}${environment}${badge}${node.resultsummary !== void 0 ? ` \u2014 ${node.resultsummary}` : ""}`;
7383
+ if (node.status === "waiting") item.append(" ", button("Diff preview at the gate wait", () => diffPreview(node.stepid)));
7384
+ if (node.active) item.scrollIntoView({ block: "nearest" });
7385
+ list.append(item);
7386
+ }
7387
+ stepstimelineroot.append(list);
7388
+ } catch (error) {
7389
+ stepstimelineroot.textContent = error instanceof Error ? error.message : String(error);
7390
+ }
7391
+ }
7392
+ async function renderlogstream() {
7393
+ if (!logstreamroot) return;
7394
+ try {
7395
+ const result = await request({ kind: "surface", logstream: { read: { filters: logstreamfilter } } });
7396
+ logstreamroot.replaceChildren();
7397
+ const controls = document.createElement("div");
7398
+ controls.className = "actions";
7399
+ const pause = button(logstreampaused ? "Resume stream" : "Pause stream", async () => {
7400
+ logstreampaused = !logstreampaused;
7401
+ await renderlogstream();
7402
+ });
7403
+ const levelselect = document.createElement("select");
7404
+ for (const level of ["", "error", "warn", "info", "log", "debug", "trace"]) {
7405
+ const option = document.createElement("option");
7406
+ option.value = level;
7407
+ option.textContent = level === "" ? "all levels" : level;
7408
+ levelselect.append(option);
7409
+ }
7410
+ levelselect.value = logstreamfilter.level ?? "";
7411
+ levelselect.addEventListener("change", () => {
7412
+ const level = levelselect.value;
7413
+ logstreamfilter = { ...logstreamfilter, ...level !== "" ? { level } : {} };
7414
+ void renderlogstream();
7415
+ });
7416
+ const copy = button("Copy verified excerpt", async () => {
7417
+ const excerpt = await request({ kind: "surface", logstream: { excerpt: {} } });
7418
+ await navigator.clipboard?.writeText(excerpt.excerpt).catch(() => {
7419
+ });
7420
+ status(excerpt.reason);
7421
+ });
7422
+ const chain = document.createElement("span");
7423
+ chain.className = "muted";
7424
+ chain.textContent = result.chain.valid ? `chain verified \xB7 ${result.total} events` : `chain broken: ${result.chain.reason}`;
7425
+ controls.append(pause, levelselect, copy, chain);
7426
+ const list = document.createElement("ol");
7427
+ list.className = "audit";
7428
+ for (const event of logstreampaused ? [] : result.events) {
7429
+ const item = document.createElement("li");
7430
+ item.textContent = `[${new Date(event.at).toLocaleTimeString()}] ${event.level} ${event.source}${event.stepid !== void 0 ? ` step ${event.stepid}` : ""} ${event.origin} \u2014 ${event.summary}${event.masked ? ` (${event.maskverdict})` : ""}`;
7431
+ list.append(item);
7432
+ }
7433
+ if (logstreampaused) list.append(Object.assign(document.createElement("li"), { textContent: "The live stream pauses while the run continues; the full history stays in memory." }));
7434
+ logstreamroot.append(controls, list);
7435
+ } catch (error) {
7436
+ logstreamroot.textContent = error instanceof Error ? error.message : String(error);
7437
+ }
7438
+ }
7439
+ async function rendersurfacereview() {
7440
+ await renderplancards();
7441
+ await renderstepstimeline();
7442
+ await renderlogstream();
7443
+ }
7444
+ void rendersurfacereview().catch(() => {
7445
+ });
7446
+ var surfacechannel = typeof BroadcastChannel === "function" ? new BroadcastChannel("devthinksurfaces") : void 0;
7447
+ surfacechannel?.addEventListener("message", (event) => {
7448
+ const frame = event.data;
7449
+ if (frame?.channel === "logstream") {
7450
+ if (!logstreampaused) void renderlogstream().catch(() => {
7451
+ });
7452
+ return;
7453
+ }
7454
+ void refresh().catch(() => {
7455
+ });
7456
+ void rendersurfacereview().catch(() => {
7457
+ });
7458
+ });
7459
+ var paletteinputnode = document.querySelector("#paletteinput");
7460
+ var palettematchespanel = document.querySelector("#palettematches");
7461
+ async function renderworkspacepalette() {
7462
+ if (!palettematchespanel) return;
7463
+ try {
7464
+ const result = await request({ kind: "surface", palette: { query: { text: paletteinputnode?.value ?? "" } } });
7465
+ palettematchespanel.replaceChildren();
7466
+ for (const match of result.matches.slice(0, 6)) {
7467
+ const item = document.createElement("button");
7468
+ item.type = "button";
7469
+ item.className = "secondary";
7470
+ item.textContent = `${match.entry.label} (${match.entry.action.surface})`;
7471
+ item.title = match.reason;
7472
+ item.addEventListener("click", () => {
7473
+ void runworkspacepalette(match.entry.action.command).catch((error) => status(error instanceof Error ? error.message : String(error), true));
7474
+ });
7475
+ palettematchespanel.append(item, " ");
7476
+ }
7477
+ if (result.matches.length === 0) palettematchespanel.textContent = "No command matches; the palette lists only the actions the current capability set allows.";
7478
+ } catch (error) {
7479
+ palettematchespanel.textContent = error instanceof Error ? error.message : String(error);
7480
+ }
7481
+ }
7482
+ async function runworkspacepalette(command) {
7483
+ await request({ kind: "surface", palette: { used: { command } } });
7484
+ if (command === "opendashboardpage" || command === "historysearch") {
7485
+ await chrome.tabs.create({ url: chrome.runtime.getURL("dashboardpage.html") });
7486
+ status("The dashboardpage opened in a new tab.");
7487
+ return;
7488
+ }
7489
+ if (command === "openoptionspage") {
7490
+ await chrome.tabs.create({ url: chrome.runtime.getURL("optionspage.html") });
7491
+ status("The optionspage opened in a new tab.");
7492
+ return;
7493
+ }
7494
+ if (command === "opentransparencypage") {
7495
+ await chrome.tabs.create({ url: chrome.runtime.getURL("transparencypage.html") });
7496
+ status("The transparencypage opened in a new tab.");
7497
+ return;
7498
+ }
7499
+ if (command === "replayonboarding") {
7500
+ await request({ kind: "surface", onboarding: { replay: true } });
7501
+ status("The onboarding walkthrough replays on the next popup open.");
7502
+ return;
7503
+ }
7504
+ if (command === "copyauditexcerpt") {
7505
+ const result = await request({ kind: "surface", logstream: { excerpt: {} } });
7506
+ await navigator.clipboard?.writeText(result.excerpt).catch(() => {
7507
+ });
7508
+ status("The verified range copied as an audit excerpt.");
7509
+ return;
7510
+ }
7511
+ const route = await request({ kind: "surface", bus: { action: { surface: "sidepanel", command } } });
7512
+ status(route.route.reason);
7513
+ await refresh();
7514
+ await rendersurfacereview();
7515
+ }
7516
+ paletteinputnode?.addEventListener("input", () => {
7517
+ void renderworkspacepalette();
7518
+ });
7519
+ document.querySelector("#paletteopen")?.addEventListener("click", () => {
7520
+ paletteinputnode?.focus();
7521
+ void renderworkspacepalette();
7522
+ });
7523
+ document.addEventListener("keydown", (event) => {
7524
+ if (event.ctrlKey && event.key === ".") {
7525
+ event.preventDefault();
7526
+ paletteinputnode?.focus();
7527
+ void renderworkspacepalette();
7528
+ }
7529
+ });
7530
+ void renderworkspacepalette().catch(() => {
7531
+ });
7532
+ var gridnode = document.querySelector("#datagrid");
7533
+ var gridqueryinput = document.querySelector("#gridquery");
7534
+ var comparenode = document.querySelector("#compareviewer");
7535
+ var shotpanelnode = document.querySelector("#shotpanel");
7536
+ var pickernode = document.querySelector("#picker");
7537
+ var opengrid;
7538
+ async function renderdatagrid() {
7539
+ if (!gridnode) return;
7540
+ try {
7541
+ const view = await request({ kind: "context" });
7542
+ const rows = view.datasets?.[0]?.rows ?? [];
7543
+ if (rows.length === 0) {
7544
+ gridnode.textContent = "No extracted rows yet; run a read step and the grid previews its result.";
7545
+ return;
7546
+ }
7547
+ const result = await request({ kind: "views", datagrid: { view: { title: view.datasets?.[0]?.name ?? "Extraction result", rows } } });
7548
+ opengrid = result.view;
7549
+ rendergridrows(result.view, gridqueryinput?.value ?? "");
7550
+ } catch (error) {
7551
+ gridnode.textContent = error instanceof Error ? error.message : String(error);
7552
+ }
7553
+ }
7554
+ function rendergridrows(view, query) {
7555
+ if (!gridnode) return;
7556
+ const text = query.trim().toLowerCase();
7557
+ const rows = text === "" ? view.rows : view.rows.filter((row) => Object.values(row.values).some((value) => value.toLowerCase().includes(text)));
7558
+ gridnode.replaceChildren();
7559
+ const header = document.createElement("p");
7560
+ header.textContent = `${view.columns.length} inferred column${view.columns.length === 1 ? "" : "s"} (${view.columns.map((column) => `${column.field}:${column.type}`).join(", ")}) \u2014 ${rows.length} row${rows.length === 1 ? "" : "s"}.`;
7561
+ gridnode.append(header);
7562
+ const list = document.createElement("ul");
7563
+ list.className = "audit";
7564
+ for (const row of rows) list.append(Object.assign(document.createElement("li"), { textContent: view.columns.map((column) => `${column.field}=${row.values[column.field] ?? ""}`).join(" \xB7 ") }));
7565
+ gridnode.append(list);
7566
+ }
7567
+ async function exportgrid() {
7568
+ if (opengrid === void 0) {
7569
+ status("Open the datagrid preview first; the export runs on the grid view.", true);
7570
+ return;
7571
+ }
7572
+ const result = await request({ kind: "views", export: { run: { format: "csv", scope: "run" } } });
7573
+ status(`The ${result.format} export of the ${result.scope} scope runs with masked values only; the surface module renders the payload.`);
7574
+ }
7575
+ async function startpicker() {
7576
+ if (!pickernode) return;
7577
+ try {
7578
+ const result = await request({ kind: "views", picker: { start: { candidates: [] } } });
7579
+ const picker = result.picker;
7580
+ if (picker === void 0 || picker.candidates.length === 0) {
7581
+ pickernode.textContent = "The picker session started with no candidate yet; the observed elements of the granted origin join the session as the read steps run.";
7582
+ return;
7583
+ }
7584
+ pickernode.replaceChildren();
7585
+ const list = document.createElement("ol");
7586
+ list.className = "audit";
7587
+ for (const candidate of picker.candidates) list.append(Object.assign(document.createElement("li"), { textContent: `${candidate.selector} (stability ${candidate.stabilityscore}) \u2014 ${candidate.reason}` }));
7588
+ pickernode.append(list);
7589
+ } catch (error) {
7590
+ pickernode.textContent = error instanceof Error ? error.message : String(error);
7591
+ }
7592
+ }
7593
+ async function renderevidence() {
7594
+ if (comparenode) comparenode.textContent = "Every executed write step pairs its before and after captures here; the slider overlays the two captures so you see exactly what the step changed.";
7595
+ if (shotpanelnode) shotpanelnode.textContent = "The shotpanel previews the capture of a step with its redaction verdicts once a capture exists; the zoom and pan stay inside this surface.";
7596
+ }
7597
+ gridqueryinput?.addEventListener("input", () => {
7598
+ if (opengrid !== void 0) rendergridrows(opengrid, gridqueryinput?.value ?? "");
7599
+ });
7600
+ document.querySelector("#gridbuild")?.addEventListener("click", () => {
7601
+ void renderdatagrid().catch((error) => status(error instanceof Error ? error.message : String(error), true));
7602
+ });
7603
+ document.querySelector("#gridexport")?.addEventListener("click", () => {
7604
+ void exportgrid().catch((error) => status(error instanceof Error ? error.message : String(error), true));
7605
+ });
7606
+ document.querySelector("#pickerstart")?.addEventListener("click", () => {
7607
+ void startpicker().catch((error) => status(error instanceof Error ? error.message : String(error), true));
7608
+ });
7609
+ void renderdatagrid().catch(() => {
7610
+ });
7611
+ void renderevidence();
7252
7612
  //# sourceMappingURL=sidepanel.js.map