@wenathlan/extension 1.1.62 → 1.1.64
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +5 -3
- package/dist/environments.d.ts +10 -0
- package/dist/environments.d.ts.map +1 -1
- package/dist/index.d.ts +4 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +956 -1
- package/dist/index.js.map +4 -4
- package/dist/memory.d.ts +126 -1
- package/dist/memory.d.ts.map +1 -1
- package/dist/planreview.d.ts +87 -0
- package/dist/planreview.d.ts.map +1 -0
- package/dist/policy.d.ts +101 -0
- package/dist/policy.d.ts.map +1 -1
- package/dist/protocol.d.ts +135 -0
- package/dist/protocol.d.ts.map +1 -1
- package/dist/sessioninterface.d.ts +213 -0
- package/dist/sessioninterface.d.ts.map +1 -0
- package/dist/surfaces.d.ts +59 -0
- package/dist/surfaces.d.ts.map +1 -0
- package/dist/types.d.ts +376 -3
- package/dist/types.d.ts.map +1 -1
- package/dist/version.d.ts +1 -1
- package/extension/dist/background.js +1394 -2
- package/extension/dist/background.js.map +4 -4
- package/extension/dist/dashboardpage.html +13 -0
- package/extension/dist/dashboardpage.js +129 -0
- package/extension/dist/dashboardpage.js.map +7 -0
- package/extension/dist/manifest.json +5 -2
- package/extension/dist/offscreen.js +5 -0
- package/extension/dist/offscreen.js.map +2 -2
- package/extension/dist/optionspage.html +14 -0
- package/extension/dist/optionspage.js +118 -0
- package/extension/dist/optionspage.js.map +7 -0
- package/extension/dist/pagebridge.js.map +1 -1
- package/extension/dist/popup.html +4 -1
- package/extension/dist/popup.js +193 -0
- package/extension/dist/popup.js.map +3 -3
- package/extension/dist/sidepanel.html +7 -2
- package/extension/dist/sidepanel.js +693 -219
- package/extension/dist/sidepanel.js.map +3 -3
- package/extension/dist/transparencypage.html +1 -0
- package/extension/dist/transparencypage.js +42 -0
- package/extension/dist/transparencypage.js.map +2 -2
- package/extension/manifest.json +5 -2
- package/package.json +1 -1
|
@@ -1,5 +1,8 @@
|
|
|
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</title><link rel="stylesheet" href="style.css"></head>
|
|
4
|
-
<body><main><header><p class="eyebrow">DEVTHINK 1.1.
|
|
4
|
+
<body><main><header><p class="eyebrow">DEVTHINK 1.1.64</p><h1>Browser bridge</h1><p>Consent is required before page access or action.</p></header><label for="endpoint">Optional agent endpoint</label><input id="endpoint" type="url" inputmode="url" placeholder="https://agent.example/proposal" autocomplete="off"><button id="connect">Approve endpoint origin</button><div class="actions"><button id="session">Start active tab session</button><button id="pause" class="secondary">Pause session</button><button id="openpanel" class="secondary">Review plans</button><button id="stop" class="danger">Stop</button></div>
|
|
5
|
+
<section id="onboardingcard" class="panel" hidden></section>
|
|
6
|
+
<section><h2>Task</h2><label for="taskinput">Describe a browser task in plain language</label><textarea id="taskinput" rows="3" placeholder="For example: collect the pricing table of this page into a dataset."></textarea><div class="actions"><button id="tasksubmit">Propose plan</button><span id="proposalstatus" class="muted">idle</span></div><div class="actions"><button id="runquick" class="secondary">Run</button><button id="cancelquick" class="secondary">Cancel run</button><button id="opendashboard" class="secondary">Open dashboard</button><button id="openoptions" class="secondary">Open options</button></div></section>
|
|
7
|
+
<section><h2>Command palette</h2><div class="actions"><input id="paletteinput" placeholder="Search commands (ctrl+.)" aria-label="Command palette search"><button id="paletteopen" class="secondary">Palette</button></div><div id="palettematches" class="panel"></div></section><p id="capabilities" role="status" class="muted">Optional capabilities: loading.</p><p id="livelogic" role="status" class="muted">Held keys: none · Open dialogs answered: none.</p><p id="navstate" role="status" class="muted">Navigation: unknown.</p><p id="windowlayout" role="status" class="muted">Window layout: unknown.</p><p id="captchastate" role="status" class="muted">Captcha handoff: none.</p><p id="datasetstate" role="status" class="muted">Datasets: none collected yet.</p><p id="downloadstate" role="status" class="muted">Downloads: none.</p><p id="clipboardstate" role="status" class="muted">Clipboard consent: none waiting.</p><p id="capturestate" role="status" class="muted">Captures: none.</p><p id="mediastate" role="status" class="muted">Media: none.</p><p id="callstate" role="status" class="muted">Outbound calls: none.</p><p id="netstate" role="status" class="muted">Observed requests: none.</p><p id="rulestate" role="status" class="muted">Traffic rules: none active.</p><p id="debugstate" role="status" class="muted">Timeline: no errors captured.</p><p id="emulationstate" role="status" class="muted">Emulation: no active layer.</p><p id="sessionstate" role="status" class="muted">Sessions: none saved yet.</p><p id="workflowstate" role="status" class="muted">Workflows: none running.</p><p id="triggerstate" role="status" class="muted">Triggers: none armed.</p><p id="mcpstate" role="status" class="muted">Mcp server: stopped.</p><p id="modelstate" role="status" class="muted">Models: none connected.</p><p id="swarmstate" role="status" class="muted">Swarm: no agents.</p><p id="environmentstate" role="status" class="muted">Environments: no run state.</p><p id="securitystate" role="status" class="muted">Security: denydefault posture.</p><p id="sessiongridstate" role="status" class="muted">Session grid: no run yet.</p><div id="workflowcontrols" class="actions"></div><div id="windowcontrols" class="actions"></div><div id="environmentcontrols" class="actions"></div><div id="securitycontrols" class="actions"></div><div id="sessiongridcontrols" class="actions"></div><p id="status" role="status">Loading session state.</p></main><script type="module" src="popup.js"></script></body>
|
|
5
8
|
</html>
|
package/extension/dist/popup.js
CHANGED
|
@@ -42,6 +42,8 @@ var swarmstatenode = document.querySelector("#swarmstate");
|
|
|
42
42
|
var environmentstatenode = document.querySelector("#environmentstate");
|
|
43
43
|
var securitystatenode = document.querySelector("#securitystate");
|
|
44
44
|
var securitycontrols = document.querySelector("#securitycontrols");
|
|
45
|
+
var sessiongridstatenode = document.querySelector("#sessiongridstate");
|
|
46
|
+
var sessiongridcontrols = document.querySelector("#sessiongridcontrols");
|
|
45
47
|
var environmentcontrols = document.querySelector("#environmentcontrols");
|
|
46
48
|
var workflowcontrols = document.querySelector("#workflowcontrols");
|
|
47
49
|
var windowcontrols = document.querySelector("#windowcontrols");
|
|
@@ -415,6 +417,7 @@ async function restore() {
|
|
|
415
417
|
renderswarmstate(context.swarm);
|
|
416
418
|
renderenvironmentstate(context.environments);
|
|
417
419
|
rendersecuritystate(context.security, context.session?.origin);
|
|
420
|
+
rendersessiongridstate(context.sessionview?.grid);
|
|
418
421
|
renderrulestate(context.activerules, (context.traffic?.blocks ?? []).filter((rule) => rule.revertedat === void 0).reduce((total, rule) => total + rule.hits, 0), (context.traffic?.mocks ?? []).filter((spec) => spec.revertedat === void 0).reduce((total, spec) => total + spec.hits, 0));
|
|
419
422
|
const active = context.session && !context.session.stoppedat && context.session.expiresat > Date.now();
|
|
420
423
|
if (pausebutton) {
|
|
@@ -475,4 +478,194 @@ stopbutton?.addEventListener("click", async () => {
|
|
|
475
478
|
});
|
|
476
479
|
openbutton?.addEventListener("click", () => chrome.sidePanel.open({ windowId: chrome.windows.WINDOW_ID_CURRENT }));
|
|
477
480
|
restore().catch((error) => status(error instanceof Error ? error.message : String(error), true));
|
|
481
|
+
function rendersessiongridstate(grid) {
|
|
482
|
+
if (!sessiongridstatenode) return;
|
|
483
|
+
if (!grid || grid.length === 0) {
|
|
484
|
+
sessiongridstatenode.textContent = "Session grid: no run yet.";
|
|
485
|
+
if (sessiongridcontrols) sessiongridcontrols.replaceChildren();
|
|
486
|
+
return;
|
|
487
|
+
}
|
|
488
|
+
const recent = grid.slice(0, 3);
|
|
489
|
+
sessiongridstatenode.textContent = `Session grid: ${grid.length} run${grid.length === 1 ? "" : "s"} \u2014 ${recent.map((row) => `${row.state} ${row.runid.slice(0, 8)} ${row.completed}/${row.steps} ${row.lock}`).join(" \xB7 ")}.`;
|
|
490
|
+
if (!sessiongridcontrols) return;
|
|
491
|
+
sessiongridcontrols.replaceChildren();
|
|
492
|
+
for (const row of recent) {
|
|
493
|
+
const deep = document.createElement("button");
|
|
494
|
+
deep.type = "button";
|
|
495
|
+
deep.className = "secondary";
|
|
496
|
+
deep.textContent = `Open ${row.state} run ${row.runid.slice(0, 8)}`;
|
|
497
|
+
deep.addEventListener("click", () => request({ kind: "sessions", grid: { open: { runid: row.runid } } }).then(() => {
|
|
498
|
+
status(`The session grid row of the run ${row.runid} opened in the sidepanel run view.`);
|
|
499
|
+
return restore();
|
|
500
|
+
}).catch((error) => status(error instanceof Error ? error.message : String(error), true)));
|
|
501
|
+
sessiongridcontrols.append(deep);
|
|
502
|
+
}
|
|
503
|
+
}
|
|
504
|
+
var taskinputnode = document.querySelector("#taskinput");
|
|
505
|
+
var tasksubmitbutton = document.querySelector("#tasksubmit");
|
|
506
|
+
var proposalstatusnode = document.querySelector("#proposalstatus");
|
|
507
|
+
var runquickbutton = document.querySelector("#runquick");
|
|
508
|
+
var cancelquickbutton = document.querySelector("#cancelquick");
|
|
509
|
+
var opendashboardbutton = document.querySelector("#opendashboard");
|
|
510
|
+
var openoptionsbutton = document.querySelector("#openoptions");
|
|
511
|
+
var paletteinput = document.querySelector("#paletteinput");
|
|
512
|
+
var paletteopenbutton = document.querySelector("#paletteopen");
|
|
513
|
+
var palettematchesnode = document.querySelector("#palettematches");
|
|
514
|
+
var onboardingcardnode = document.querySelector("#onboardingcard");
|
|
515
|
+
var surfacechannel = typeof BroadcastChannel === "function" ? new BroadcastChannel("devthinksurfaces") : void 0;
|
|
516
|
+
surfacechannel?.addEventListener("message", () => {
|
|
517
|
+
void restore().catch(() => {
|
|
518
|
+
});
|
|
519
|
+
void renderonboarding().catch(() => {
|
|
520
|
+
});
|
|
521
|
+
});
|
|
522
|
+
function proposalstatus(status2, detail = "") {
|
|
523
|
+
if (!proposalstatusnode) return;
|
|
524
|
+
proposalstatusnode.textContent = detail === "" ? status2 : `${status2} \u2014 ${detail}`;
|
|
525
|
+
proposalstatusnode.dataset.state = status2;
|
|
526
|
+
}
|
|
527
|
+
tasksubmitbutton?.addEventListener("click", async () => {
|
|
528
|
+
const text = taskinputnode?.value ?? "";
|
|
529
|
+
if (text.trim() === "") {
|
|
530
|
+
status("Describe the goal first; the proposal flow needs its natural language task.", true);
|
|
531
|
+
return;
|
|
532
|
+
}
|
|
533
|
+
proposalstatus("generating");
|
|
534
|
+
try {
|
|
535
|
+
const result = await request({ kind: "surface", task: { submit: { text, surface: "popup" } } });
|
|
536
|
+
proposalstatus("ready", `plan ${result.plan?.id ?? ""} awaits its plancard review`);
|
|
537
|
+
status(`The taskinput goal became the plan ${result.plan?.id ?? ""}; review its plancards in the side panel.`);
|
|
538
|
+
await restore();
|
|
539
|
+
} catch (error) {
|
|
540
|
+
proposalstatus("failed", error instanceof Error ? error.message : String(error));
|
|
541
|
+
status(error instanceof Error ? error.message : String(error), true);
|
|
542
|
+
}
|
|
543
|
+
});
|
|
544
|
+
async function busaction(command, payload = "", stepid) {
|
|
545
|
+
const action = { surface: "popup", command, ...payload !== "" ? { payload } : {}, ...stepid !== void 0 ? { stepid } : {} };
|
|
546
|
+
const route = await request({ kind: "surface", bus: { action } });
|
|
547
|
+
status(route.route.reason);
|
|
548
|
+
await restore();
|
|
549
|
+
}
|
|
550
|
+
runquickbutton?.addEventListener("click", () => {
|
|
551
|
+
void busaction("starttask", taskinputnode?.value ?? "").catch((error) => status(error instanceof Error ? error.message : String(error), true));
|
|
552
|
+
});
|
|
553
|
+
cancelquickbutton?.addEventListener("click", () => {
|
|
554
|
+
void busaction("cancelrun").catch((error) => status(error instanceof Error ? error.message : String(error), true));
|
|
555
|
+
});
|
|
556
|
+
opendashboardbutton?.addEventListener("click", () => {
|
|
557
|
+
void chrome.tabs.create({ url: chrome.runtime.getURL("dashboardpage.html") });
|
|
558
|
+
});
|
|
559
|
+
openoptionsbutton?.addEventListener("click", () => {
|
|
560
|
+
void chrome.tabs.create({ url: chrome.runtime.getURL("optionspage.html") });
|
|
561
|
+
});
|
|
562
|
+
async function renderpalette() {
|
|
563
|
+
if (!palettematchesnode) return;
|
|
564
|
+
const text = paletteinput?.value ?? "";
|
|
565
|
+
try {
|
|
566
|
+
const result = await request({ kind: "surface", palette: { query: { text } } });
|
|
567
|
+
palettematchesnode.replaceChildren();
|
|
568
|
+
for (const match of result.matches.slice(0, 6)) {
|
|
569
|
+
const item = document.createElement("button");
|
|
570
|
+
item.type = "button";
|
|
571
|
+
item.className = "secondary";
|
|
572
|
+
item.textContent = `${match.entry.label} (${match.entry.action.surface})`;
|
|
573
|
+
item.title = match.reason;
|
|
574
|
+
item.addEventListener("click", () => {
|
|
575
|
+
void runpalettecommand(match.entry.action.command).catch((error) => status(error instanceof Error ? error.message : String(error), true));
|
|
576
|
+
});
|
|
577
|
+
palettematchesnode.append(item, " ");
|
|
578
|
+
}
|
|
579
|
+
if (result.matches.length === 0) palettematchesnode.textContent = "No command matches; the palette lists only the actions the current capability set allows.";
|
|
580
|
+
} catch (error) {
|
|
581
|
+
palettematchesnode.textContent = error instanceof Error ? error.message : String(error);
|
|
582
|
+
}
|
|
583
|
+
}
|
|
584
|
+
async function runpalettecommand(command) {
|
|
585
|
+
await request({ kind: "surface", palette: { used: { command } } });
|
|
586
|
+
if (command === "opendashboardpage") {
|
|
587
|
+
await chrome.tabs.create({ url: chrome.runtime.getURL("dashboardpage.html") });
|
|
588
|
+
status("The dashboardpage opened in a new tab.");
|
|
589
|
+
return;
|
|
590
|
+
}
|
|
591
|
+
if (command === "openoptionspage") {
|
|
592
|
+
await chrome.tabs.create({ url: chrome.runtime.getURL("optionspage.html") });
|
|
593
|
+
status("The optionspage opened in a new tab.");
|
|
594
|
+
return;
|
|
595
|
+
}
|
|
596
|
+
if (command === "opentransparencypage") {
|
|
597
|
+
await chrome.tabs.create({ url: chrome.runtime.getURL("transparencypage.html") });
|
|
598
|
+
status("The transparencypage opened in a new tab.");
|
|
599
|
+
return;
|
|
600
|
+
}
|
|
601
|
+
if (command === "replayonboarding") {
|
|
602
|
+
await request({ kind: "surface", onboarding: { replay: true } });
|
|
603
|
+
await renderonboarding();
|
|
604
|
+
status("The onboarding walkthrough replays.");
|
|
605
|
+
return;
|
|
606
|
+
}
|
|
607
|
+
if (command === "historysearch") {
|
|
608
|
+
await chrome.tabs.create({ url: chrome.runtime.getURL("dashboardpage.html") });
|
|
609
|
+
status("The dashboardpage opened with the historysearch view.");
|
|
610
|
+
return;
|
|
611
|
+
}
|
|
612
|
+
if (command === "copyauditexcerpt") {
|
|
613
|
+
const result = await request({ kind: "surface", logstream: { excerpt: {} } });
|
|
614
|
+
await navigator.clipboard?.writeText(result.excerpt).catch(() => {
|
|
615
|
+
});
|
|
616
|
+
status("The verified range copied as an audit excerpt.");
|
|
617
|
+
return;
|
|
618
|
+
}
|
|
619
|
+
await busaction(command);
|
|
620
|
+
await renderpalette();
|
|
621
|
+
}
|
|
622
|
+
paletteinput?.addEventListener("input", () => {
|
|
623
|
+
void renderpalette();
|
|
624
|
+
});
|
|
625
|
+
paletteopenbutton?.addEventListener("click", () => {
|
|
626
|
+
paletteinput?.focus();
|
|
627
|
+
void renderpalette();
|
|
628
|
+
});
|
|
629
|
+
document.addEventListener("keydown", (event) => {
|
|
630
|
+
const shortcut = event.ctrlKey && event.key === ".";
|
|
631
|
+
if (!shortcut) return;
|
|
632
|
+
event.preventDefault();
|
|
633
|
+
paletteinput?.focus();
|
|
634
|
+
void renderpalette();
|
|
635
|
+
});
|
|
636
|
+
void renderpalette();
|
|
637
|
+
async function renderonboarding() {
|
|
638
|
+
if (!onboardingcardnode) return;
|
|
639
|
+
try {
|
|
640
|
+
const result = await request({ kind: "surface", onboarding: {} });
|
|
641
|
+
const steps = result.steps ?? [];
|
|
642
|
+
const state = result.state;
|
|
643
|
+
if (!state || state.done || steps.length === 0) {
|
|
644
|
+
onboardingcardnode.hidden = true;
|
|
645
|
+
onboardingcardnode.replaceChildren();
|
|
646
|
+
return;
|
|
647
|
+
}
|
|
648
|
+
const current = steps.find((step) => !state.stepscompleted.includes(step.id)) ?? steps[0];
|
|
649
|
+
if (current === void 0) {
|
|
650
|
+
onboardingcardnode.hidden = true;
|
|
651
|
+
return;
|
|
652
|
+
}
|
|
653
|
+
onboardingcardnode.hidden = false;
|
|
654
|
+
onboardingcardnode.replaceChildren();
|
|
655
|
+
const title = document.createElement("strong");
|
|
656
|
+
title.textContent = `Onboarding \u2014 ${current.title} (${state.stepscompleted.length}/${steps.length})`;
|
|
657
|
+
const body = document.createElement("p");
|
|
658
|
+
body.textContent = current.body;
|
|
659
|
+
const done = document.createElement("button");
|
|
660
|
+
done.type = "button";
|
|
661
|
+
done.textContent = `Mark ${current.title} done`;
|
|
662
|
+
done.addEventListener("click", () => {
|
|
663
|
+
void request({ kind: "surface", onboarding: { complete: { stepid: current.id } } }).then(() => renderonboarding()).then(() => restore()).catch((error) => status(error instanceof Error ? error.message : String(error), true));
|
|
664
|
+
});
|
|
665
|
+
onboardingcardnode.append(title, body, done);
|
|
666
|
+
} catch {
|
|
667
|
+
onboardingcardnode.hidden = true;
|
|
668
|
+
}
|
|
669
|
+
}
|
|
670
|
+
void renderonboarding();
|
|
478
671
|
//# sourceMappingURL=popup.js.map
|