@wenathlan/extension 1.1.64 → 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 (49) hide show
  1. package/README.md +4 -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 +9 -1
  7. package/dist/index.d.ts.map +1 -1
  8. package/dist/index.js +752 -1
  9. package/dist/index.js.map +4 -4
  10. package/dist/memory.d.ts +38 -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/policy.d.ts +59 -1
  15. package/dist/policy.d.ts.map +1 -1
  16. package/dist/portability.d.ts +35 -0
  17. package/dist/portability.d.ts.map +1 -0
  18. package/dist/protocol.d.ts +114 -1
  19. package/dist/protocol.d.ts.map +1 -1
  20. package/dist/quickactions.d.ts +46 -0
  21. package/dist/quickactions.d.ts.map +1 -0
  22. package/dist/siteprefs.d.ts +45 -0
  23. package/dist/siteprefs.d.ts.map +1 -0
  24. package/dist/statusviews.d.ts +65 -0
  25. package/dist/statusviews.d.ts.map +1 -0
  26. package/dist/tourviews.d.ts +28 -0
  27. package/dist/tourviews.d.ts.map +1 -0
  28. package/dist/types.d.ts +252 -4
  29. package/dist/types.d.ts.map +1 -1
  30. package/dist/version.d.ts +1 -1
  31. package/extension/dist/background.js +900 -2
  32. package/extension/dist/background.js.map +4 -4
  33. package/extension/dist/dashboardpage.html +1 -0
  34. package/extension/dist/dashboardpage.js +18 -0
  35. package/extension/dist/dashboardpage.js.map +2 -2
  36. package/extension/dist/manifest.json +1 -1
  37. package/extension/dist/optionspage.html +4 -0
  38. package/extension/dist/optionspage.js +149 -0
  39. package/extension/dist/optionspage.js.map +2 -2
  40. package/extension/dist/pagebridge.js.map +1 -1
  41. package/extension/dist/popup.html +2 -2
  42. package/extension/dist/popup.js +90 -0
  43. package/extension/dist/popup.js.map +2 -2
  44. package/extension/dist/sidepanel.html +2 -2
  45. package/extension/dist/sidepanel.js +84 -3
  46. package/extension/dist/sidepanel.js.map +2 -2
  47. package/extension/dist/style.css +3 -1
  48. package/extension/manifest.json +1 -1
  49. package/package.json +1 -1
@@ -9,5 +9,6 @@
9
9
  <section><h2>Site notes</h2><div id="sitenotes" class="panel"></div></section>
10
10
  <section><h2>Transparency views</h2><div id="transparency" class="panel"></div></section>
11
11
  <section><h2>Onboarding</h2><div id="onboarding" class="panel"></div></section>
12
+ <section><h2>Drop import</h2><div id="dropzone" class="panel" role="region" aria-label="Drop csv, json or workflow files to import">Drop csv, json or workflow files here.</div><p id="dropstatus" class="muted">The dashboardpage accepts the same dropimport files as the optionspage.</p></section>
12
13
  </main><script type="module" src="dashboardpage.js"></script></body>
13
14
  </html>
@@ -126,4 +126,22 @@ surfacechannel?.addEventListener("message", () => {
126
126
  void render().catch((error) => status(error instanceof Error ? error.message : String(error), true));
127
127
  void renderhistorysearch("").catch(() => {
128
128
  });
129
+ var dropzonenode = document.querySelector("#dropzone");
130
+ var dropstatusnode = document.querySelector("#dropstatus");
131
+ if (dropzonenode) {
132
+ dropzonenode.addEventListener("dragover", (event) => {
133
+ event.preventDefault();
134
+ });
135
+ dropzonenode.addEventListener("drop", (event) => {
136
+ event.preventDefault();
137
+ const file = event.dataTransfer?.files[0];
138
+ if (file === void 0) return;
139
+ void file.text().then((head) => request({ kind: "views", dropimport: { file: { filename: file.name, bytes: file.size, head: head.slice(0, 2e3) } } })).then((result) => {
140
+ const session = result.session;
141
+ if (dropstatusnode) dropstatusnode.textContent = `The dropimport detected the ${session.kind} kind of ${session.filename} (${session.bytes} byte${session.bytes === 1 ? "" : "s"}); the import path takes the file from here.`;
142
+ }).catch((error) => {
143
+ if (dropstatusnode) dropstatusnode.textContent = error instanceof Error ? error.message : String(error);
144
+ });
145
+ });
146
+ }
129
147
  //# sourceMappingURL=dashboardpage.js.map
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../dashboardpage.ts"],
4
- "sourcesContent": ["export {};\n\n/**\n * Dashboardpage runtime of the 1.1.64 family.\n * The dashboardpage opens in a new tab from the popup and the sidepanel and aggregates the sessions, the runs, the notes and the transparency views of the profile workspace; it renders the sessiongrid and the historysearch of the 1.1.63 session interface beside the transparency report of the 1.1.62 family and the onboarding state, and it subscribes to session and run updates through the single broadcast channel so the view stays live without a reload.\n */\n\ntype sessionview = {\n grid: Array<{ sessionid: string; runid: string; origins: string[]; state: string; outcome: string; steps: number; completed: number; lock: string; tabid?: number; sealhash?: string; updatedat: number; actions: string[] }>;\n notes: Array<{ id: string; origin: string; title: string; body: string; author: string; sensitive: boolean; updatedat: number }>;\n summaries: Array<{ runid: string; origins: string[]; kinds: string[]; steps: number; provenance: string; distilledat: number }>;\n};\ntype transparencyview = {\n grants: Array<{ origin: string; scope: string; boundary: string; grantedat: number }>;\n windows: Array<{ id: string; origin: string; state: string; boundary: string; startedat: number; expiresat: number }>;\n permdiffs: Array<{ fromversion: string; toversion: string; added: string[]; removed: string[]; computedat: number }>;\n safedefaults: Array<{ origin: string; firstseenat: number }>;\n};\ntype dashboardview = { sessionview: sessionview; transparency: transparencyview; onboarding: { stepscompleted: string[]; done: boolean }; environments?: { offscreengranted: boolean; parseoffload: boolean; workers?: number }; security?: { posture?: string } };\n\nconst statusnode = document.querySelector<HTMLElement>(\"#status\");\nconst sessiongridroot = document.querySelector<HTMLElement>(\"#sessiongrid\");\nconst historyhitsroot = document.querySelector<HTMLElement>(\"#historyhits\");\nconst sitenotesroot = document.querySelector<HTMLElement>(\"#sitenotes\");\nconst transparencyroot = document.querySelector<HTMLElement>(\"#transparency\");\nconst onboardingroot = document.querySelector<HTMLElement>(\"#onboarding\");\nconst historyinput = document.querySelector<HTMLInputElement>(\"#historyquery\");\n\nfunction status(message: string, error = false): void { if (statusnode) { statusnode.textContent = message; statusnode.dataset.state = error ? \"error\" : \"ready\"; } }\nasync function request(message: unknown): Promise<unknown> { const response = await chrome.runtime.sendMessage(message) as { ok: boolean; value?: unknown; error?: string }; if (!response.ok) throw new Error(response.error); return response.value; }\nfunction button(label: string, action: () => Promise<void>): HTMLButtonElement { const element = document.createElement(\"button\"); element.type = \"button\"; element.className = \"secondary\"; element.textContent = label; element.addEventListener(\"click\", () => action().catch(error => status(error instanceof Error ? error.message : String(error), true))); return element; }\n\n/** Renders the sessiongrid rows of the 1.1.63 session interface with their resume, cancelrun and reopen actions as deep links. */\nfunction rendersessiongrid(view: sessionview): void {\n if (!sessiongridroot) return;\n sessiongridroot.replaceChildren();\n if (view.grid.length === 0) { sessiongridroot.textContent = \"No session exists yet; start the first run from the popup taskinput.\"; return; }\n const list = document.createElement(\"ol\");\n list.className = \"audit\";\n for (const row of view.grid) {\n const item = document.createElement(\"li\");\n item.textContent = `${row.state} ${row.runid} \u2014 ${row.origins.join(\", \")} \u2014 ${row.completed}/${row.steps} steps \u2014 ${row.outcome} \u2014 ${row.lock}${row.sealhash !== undefined ? ` \u2014 sealed ${row.sealhash.slice(0, 12)}` : \"\"}`;\n for (const action of row.actions) item.append(\" \", button(action === \"cancelrun\" ? \"Cancel run\" : action === \"resume\" ? \"Resume\" : \"Reopen\", async () => {\n await request({ kind: \"sessions\", grid: action === \"cancelrun\" ? { open: { runid: row.runid } } : action === \"resume\" ? { resume: { runid: row.runid } } : { reopen: { runid: row.runid } } });\n if (action === \"cancelrun\") await request({ kind: \"surface\", bus: { action: { surface: \"dashboardpage\", command: \"cancelrun\" } } });\n status(`The ${action} action of the run ${row.runid} routed through the command bus.`);\n await render();\n }));\n list.append(item);\n }\n sessiongridroot.append(list);\n}\n\n/** Renders the historysearch corpus of the 1.1.63 session interface with the matched terms highlighted. */\nasync function renderhistorysearch(text: string): Promise<void> {\n if (!historyhitsroot) return;\n try {\n const result = await request({ kind: \"sessions\", search: { query: { text } } }) as { hits: Array<{ source: string; title: string; excerpt: string; highlights: string[]; origin?: string; at: number }> };\n historyhitsroot.replaceChildren();\n if (result.hits.length === 0) { historyhitsroot.append(Object.assign(document.createElement(\"li\"), { textContent: \"No history matches yet.\" })); return; }\n for (const hit of result.hits) {\n const item = document.createElement(\"li\");\n item.textContent = `${hit.source} \u2014 ${hit.title}${hit.origin !== undefined ? ` (${hit.origin})` : \"\"}: ${hit.excerpt}${hit.highlights.length > 0 ? ` [${hit.highlights.join(\", \")}]` : \"\"}`;\n historyhitsroot.append(item);\n }\n } catch (error) { historyhitsroot.textContent = error instanceof Error ? error.message : String(error); }\n}\n\n/** Renders the site notes of the session interface with their author provenance. */\nfunction rendersitenotes(view: sessionview): void {\n if (!sitenotesroot) return;\n if (view.notes.length === 0) { sitenotesroot.textContent = \"No site note exists yet; write the first note from the sidepanel.\"; return; }\n sitenotesroot.replaceChildren();\n const list = document.createElement(\"ul\");\n list.className = \"audit\";\n for (const note of view.notes) list.append(Object.assign(document.createElement(\"li\"), { textContent: `${note.title} (${note.origin}, by ${note.author}${note.sensitive ? \", sealed at rest\" : \"\"}): ${note.body}` }));\n sitenotesroot.append(list);\n}\n\n/** Renders the transparency views of the 1.1.62 family: the grants with their boundaries, the window history, the permdiffs and the safedefaults applications. */\nfunction rendertransparency(view: transparencyview): void {\n if (!transparencyroot) return;\n transparencyroot.replaceChildren();\n const grants = document.createElement(\"p\");\n grants.textContent = `Grants: ${view.grants.length} grant row${view.grants.length === 1 ? \"\" : \"s\"}${view.grants.length > 0 ? ` (${view.grants.slice(0, 5).map(grant => `${grant.origin} \u2014 ${grant.scope} \u2014 ${grant.boundary}`).join(\" \u00B7 \")})` : \"\"}.`;\n const windows = document.createElement(\"p\");\n windows.textContent = `Consent windows: ${view.windows.length} recorded window${view.windows.length === 1 ? \"\" : \"s\"}.`;\n const permdiffs = document.createElement(\"p\");\n permdiffs.textContent = `Permdiffs: ${view.permdiffs.length} record${view.permdiffs.length === 1 ? \"\" : \"s\"}${view.permdiffs.length > 0 ? ` (latest ${view.permdiffs[0]?.fromversion} \u2192 ${view.permdiffs[0]?.toversion})` : \"\"}.`;\n const safedefaults = document.createElement(\"p\");\n safedefaults.textContent = `Safedefaults applications: ${view.safedefaults.length} origin${view.safedefaults.length === 1 ? \"\" : \"s\"} under the reads only posture.`;\n transparencyroot.append(grants, windows, permdiffs, safedefaults);\n}\n\n/** Renders the onboarding state with its replay offer on demand. */\nfunction renderonboarding(onboarding: { stepscompleted: string[]; done: boolean }): void {\n if (!onboardingroot) return;\n onboardingroot.replaceChildren();\n const state = document.createElement(\"p\");\n state.textContent = onboarding.done ? \"The onboarding walkthrough is done; replay it on demand from the optionspage.\" : `The onboarding walkthrough stands at ${onboarding.stepscompleted.length} completed step${onboarding.stepscompleted.length === 1 ? \"\" : \"s\"}.`;\n onboardingroot.append(state);\n}\n\n/** Loads the aggregated dashboard view: the sessionview of 1.1.63, the transparency report of 1.1.62 and the onboarding state. */\nasync function render(): Promise<void> {\n const view = await request({ kind: \"surface\", dashboard: { view: true } }) as dashboardview;\n rendersessiongrid(view.sessionview);\n rendersitenotes(view.sessionview);\n rendertransparency(view.transparency);\n renderonboarding(view.onboarding);\n status(`Dashboard view live: ${view.sessionview.grid.length} run${view.sessionview.grid.length === 1 ? \"\" : \"s\"}, ${view.sessionview.notes.length} note${view.sessionview.notes.length === 1 ? \"\" : \"s\"} and ${view.transparency.grants.length} grant row${view.transparency.grants.length === 1 ? \"\" : \"s\"}.`);\n}\n\ndocument.querySelector<HTMLButtonElement>(\"#openpanel\")?.addEventListener(\"click\", () => { void chrome.sidePanel.open({ windowId: chrome.windows.WINDOW_ID_CURRENT }).catch(() => { /* the panel opens beside the dashboard tab */ }); });\ndocument.querySelector<HTMLButtonElement>(\"#openoptions\")?.addEventListener(\"click\", () => { void chrome.tabs.create({ url: chrome.runtime.getURL(\"optionspage.html\") }); });\ndocument.querySelector<HTMLButtonElement>(\"#historyrun\")?.addEventListener(\"click\", () => { void renderhistorysearch(historyinput?.value ?? \"\").catch(error => status(error instanceof Error ? error.message : String(error), true)); });\nhistoryinput?.addEventListener(\"keydown\", event => { if (event.key === \"Enter\") document.querySelector<HTMLButtonElement>(\"#historyrun\")?.click(); });\n\n/** The dashboardpage subscribes to session and run updates through the single broadcast channel. */\nconst surfacechannel: BroadcastChannel | undefined = typeof BroadcastChannel === \"function\" ? new BroadcastChannel(\"devthinksurfaces\") : undefined;\nsurfacechannel?.addEventListener(\"message\", () => { void render().catch(() => { /* a failing refresh keeps the last rendered dashboard */ }); });\n\nvoid render().catch(error => status(error instanceof Error ? error.message : String(error), true));\nvoid renderhistorysearch(\"\").catch(() => { /* an empty first search shows the empty state */ });\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["export {};\n\n/**\n * Dashboardpage runtime of the 1.1.64 family.\n * The dashboardpage opens in a new tab from the popup and the sidepanel and aggregates the sessions, the runs, the notes and the transparency views of the profile workspace; it renders the sessiongrid and the historysearch of the 1.1.63 session interface beside the transparency report of the 1.1.62 family and the onboarding state, and it subscribes to session and run updates through the single broadcast channel so the view stays live without a reload.\n */\n\ntype sessionview = {\n grid: Array<{ sessionid: string; runid: string; origins: string[]; state: string; outcome: string; steps: number; completed: number; lock: string; tabid?: number; sealhash?: string; updatedat: number; actions: string[] }>;\n notes: Array<{ id: string; origin: string; title: string; body: string; author: string; sensitive: boolean; updatedat: number }>;\n summaries: Array<{ runid: string; origins: string[]; kinds: string[]; steps: number; provenance: string; distilledat: number }>;\n};\ntype transparencyview = {\n grants: Array<{ origin: string; scope: string; boundary: string; grantedat: number }>;\n windows: Array<{ id: string; origin: string; state: string; boundary: string; startedat: number; expiresat: number }>;\n permdiffs: Array<{ fromversion: string; toversion: string; added: string[]; removed: string[]; computedat: number }>;\n safedefaults: Array<{ origin: string; firstseenat: number }>;\n};\ntype dashboardview = { sessionview: sessionview; transparency: transparencyview; onboarding: { stepscompleted: string[]; done: boolean }; environments?: { offscreengranted: boolean; parseoffload: boolean; workers?: number }; security?: { posture?: string } };\n\nconst statusnode = document.querySelector<HTMLElement>(\"#status\");\nconst sessiongridroot = document.querySelector<HTMLElement>(\"#sessiongrid\");\nconst historyhitsroot = document.querySelector<HTMLElement>(\"#historyhits\");\nconst sitenotesroot = document.querySelector<HTMLElement>(\"#sitenotes\");\nconst transparencyroot = document.querySelector<HTMLElement>(\"#transparency\");\nconst onboardingroot = document.querySelector<HTMLElement>(\"#onboarding\");\nconst historyinput = document.querySelector<HTMLInputElement>(\"#historyquery\");\n\nfunction status(message: string, error = false): void { if (statusnode) { statusnode.textContent = message; statusnode.dataset.state = error ? \"error\" : \"ready\"; } }\nasync function request(message: unknown): Promise<unknown> { const response = await chrome.runtime.sendMessage(message) as { ok: boolean; value?: unknown; error?: string }; if (!response.ok) throw new Error(response.error); return response.value; }\nfunction button(label: string, action: () => Promise<void>): HTMLButtonElement { const element = document.createElement(\"button\"); element.type = \"button\"; element.className = \"secondary\"; element.textContent = label; element.addEventListener(\"click\", () => action().catch(error => status(error instanceof Error ? error.message : String(error), true))); return element; }\n\n/** Renders the sessiongrid rows of the 1.1.63 session interface with their resume, cancelrun and reopen actions as deep links. */\nfunction rendersessiongrid(view: sessionview): void {\n if (!sessiongridroot) return;\n sessiongridroot.replaceChildren();\n if (view.grid.length === 0) { sessiongridroot.textContent = \"No session exists yet; start the first run from the popup taskinput.\"; return; }\n const list = document.createElement(\"ol\");\n list.className = \"audit\";\n for (const row of view.grid) {\n const item = document.createElement(\"li\");\n item.textContent = `${row.state} ${row.runid} \u2014 ${row.origins.join(\", \")} \u2014 ${row.completed}/${row.steps} steps \u2014 ${row.outcome} \u2014 ${row.lock}${row.sealhash !== undefined ? ` \u2014 sealed ${row.sealhash.slice(0, 12)}` : \"\"}`;\n for (const action of row.actions) item.append(\" \", button(action === \"cancelrun\" ? \"Cancel run\" : action === \"resume\" ? \"Resume\" : \"Reopen\", async () => {\n await request({ kind: \"sessions\", grid: action === \"cancelrun\" ? { open: { runid: row.runid } } : action === \"resume\" ? { resume: { runid: row.runid } } : { reopen: { runid: row.runid } } });\n if (action === \"cancelrun\") await request({ kind: \"surface\", bus: { action: { surface: \"dashboardpage\", command: \"cancelrun\" } } });\n status(`The ${action} action of the run ${row.runid} routed through the command bus.`);\n await render();\n }));\n list.append(item);\n }\n sessiongridroot.append(list);\n}\n\n/** Renders the historysearch corpus of the 1.1.63 session interface with the matched terms highlighted. */\nasync function renderhistorysearch(text: string): Promise<void> {\n if (!historyhitsroot) return;\n try {\n const result = await request({ kind: \"sessions\", search: { query: { text } } }) as { hits: Array<{ source: string; title: string; excerpt: string; highlights: string[]; origin?: string; at: number }> };\n historyhitsroot.replaceChildren();\n if (result.hits.length === 0) { historyhitsroot.append(Object.assign(document.createElement(\"li\"), { textContent: \"No history matches yet.\" })); return; }\n for (const hit of result.hits) {\n const item = document.createElement(\"li\");\n item.textContent = `${hit.source} \u2014 ${hit.title}${hit.origin !== undefined ? ` (${hit.origin})` : \"\"}: ${hit.excerpt}${hit.highlights.length > 0 ? ` [${hit.highlights.join(\", \")}]` : \"\"}`;\n historyhitsroot.append(item);\n }\n } catch (error) { historyhitsroot.textContent = error instanceof Error ? error.message : String(error); }\n}\n\n/** Renders the site notes of the session interface with their author provenance. */\nfunction rendersitenotes(view: sessionview): void {\n if (!sitenotesroot) return;\n if (view.notes.length === 0) { sitenotesroot.textContent = \"No site note exists yet; write the first note from the sidepanel.\"; return; }\n sitenotesroot.replaceChildren();\n const list = document.createElement(\"ul\");\n list.className = \"audit\";\n for (const note of view.notes) list.append(Object.assign(document.createElement(\"li\"), { textContent: `${note.title} (${note.origin}, by ${note.author}${note.sensitive ? \", sealed at rest\" : \"\"}): ${note.body}` }));\n sitenotesroot.append(list);\n}\n\n/** Renders the transparency views of the 1.1.62 family: the grants with their boundaries, the window history, the permdiffs and the safedefaults applications. */\nfunction rendertransparency(view: transparencyview): void {\n if (!transparencyroot) return;\n transparencyroot.replaceChildren();\n const grants = document.createElement(\"p\");\n grants.textContent = `Grants: ${view.grants.length} grant row${view.grants.length === 1 ? \"\" : \"s\"}${view.grants.length > 0 ? ` (${view.grants.slice(0, 5).map(grant => `${grant.origin} \u2014 ${grant.scope} \u2014 ${grant.boundary}`).join(\" \u00B7 \")})` : \"\"}.`;\n const windows = document.createElement(\"p\");\n windows.textContent = `Consent windows: ${view.windows.length} recorded window${view.windows.length === 1 ? \"\" : \"s\"}.`;\n const permdiffs = document.createElement(\"p\");\n permdiffs.textContent = `Permdiffs: ${view.permdiffs.length} record${view.permdiffs.length === 1 ? \"\" : \"s\"}${view.permdiffs.length > 0 ? ` (latest ${view.permdiffs[0]?.fromversion} \u2192 ${view.permdiffs[0]?.toversion})` : \"\"}.`;\n const safedefaults = document.createElement(\"p\");\n safedefaults.textContent = `Safedefaults applications: ${view.safedefaults.length} origin${view.safedefaults.length === 1 ? \"\" : \"s\"} under the reads only posture.`;\n transparencyroot.append(grants, windows, permdiffs, safedefaults);\n}\n\n/** Renders the onboarding state with its replay offer on demand. */\nfunction renderonboarding(onboarding: { stepscompleted: string[]; done: boolean }): void {\n if (!onboardingroot) return;\n onboardingroot.replaceChildren();\n const state = document.createElement(\"p\");\n state.textContent = onboarding.done ? \"The onboarding walkthrough is done; replay it on demand from the optionspage.\" : `The onboarding walkthrough stands at ${onboarding.stepscompleted.length} completed step${onboarding.stepscompleted.length === 1 ? \"\" : \"s\"}.`;\n onboardingroot.append(state);\n}\n\n/** Loads the aggregated dashboard view: the sessionview of 1.1.63, the transparency report of 1.1.62 and the onboarding state. */\nasync function render(): Promise<void> {\n const view = await request({ kind: \"surface\", dashboard: { view: true } }) as dashboardview;\n rendersessiongrid(view.sessionview);\n rendersitenotes(view.sessionview);\n rendertransparency(view.transparency);\n renderonboarding(view.onboarding);\n status(`Dashboard view live: ${view.sessionview.grid.length} run${view.sessionview.grid.length === 1 ? \"\" : \"s\"}, ${view.sessionview.notes.length} note${view.sessionview.notes.length === 1 ? \"\" : \"s\"} and ${view.transparency.grants.length} grant row${view.transparency.grants.length === 1 ? \"\" : \"s\"}.`);\n}\n\ndocument.querySelector<HTMLButtonElement>(\"#openpanel\")?.addEventListener(\"click\", () => { void chrome.sidePanel.open({ windowId: chrome.windows.WINDOW_ID_CURRENT }).catch(() => { /* the panel opens beside the dashboard tab */ }); });\ndocument.querySelector<HTMLButtonElement>(\"#openoptions\")?.addEventListener(\"click\", () => { void chrome.tabs.create({ url: chrome.runtime.getURL(\"optionspage.html\") }); });\ndocument.querySelector<HTMLButtonElement>(\"#historyrun\")?.addEventListener(\"click\", () => { void renderhistorysearch(historyinput?.value ?? \"\").catch(error => status(error instanceof Error ? error.message : String(error), true)); });\nhistoryinput?.addEventListener(\"keydown\", event => { if (event.key === \"Enter\") document.querySelector<HTMLButtonElement>(\"#historyrun\")?.click(); });\n\n/** The dashboardpage subscribes to session and run updates through the single broadcast channel. */\nconst surfacechannel: BroadcastChannel | undefined = typeof BroadcastChannel === \"function\" ? new BroadcastChannel(\"devthinksurfaces\") : undefined;\nsurfacechannel?.addEventListener(\"message\", () => { void render().catch(() => { /* a failing refresh keeps the last rendered dashboard */ }); });\n\nvoid render().catch(error => status(error instanceof Error ? error.message : String(error), true));\nvoid renderhistorysearch(\"\").catch(() => { /* an empty first search shows the empty state */ });\n\n/**\n * Dropimport zone of the 1.1.65 family: the dashboardpage accepts the csv, json and workflow files the user drops with the same file kind detection and the same import path as the optionspage.\n */\nconst dropzonenode = document.querySelector<HTMLElement>(\"#dropzone\");\nconst dropstatusnode = document.querySelector<HTMLElement>(\"#dropstatus\");\nif (dropzonenode) {\n dropzonenode.addEventListener(\"dragover\", event => { event.preventDefault(); });\n dropzonenode.addEventListener(\"drop\", event => {\n event.preventDefault();\n const file = event.dataTransfer?.files[0];\n if (file === undefined) return;\n void file.text().then(head => request({ kind: \"views\", dropimport: { file: { filename: file.name, bytes: file.size, head: head.slice(0, 2000) } } })).then(result => {\n const session = (result as { session: { filename: string; kind: string; bytes: number } }).session;\n if (dropstatusnode) dropstatusnode.textContent = `The dropimport detected the ${session.kind} kind of ${session.filename} (${session.bytes} byte${session.bytes === 1 ? \"\" : \"s\"}); the import path takes the file from here.`;\n }).catch(error => { if (dropstatusnode) dropstatusnode.textContent = error instanceof Error ? error.message : String(error); });\n });\n}\n"],
5
+ "mappings": "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",
6
6
  "names": []
7
7
  }
@@ -2,7 +2,7 @@
2
2
  "manifest_version": 3,
3
3
  "key": "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAnOEjO8Z0PDgQyfvawGcaO2j+o0GLCFTLNj7TkYC/Avo9l2NenMRq7gp90Nfd7E9MViv/OMcCKSYZ5unv12QPRtv31C+a5UQWDFAOP/cH5mwMd6hsayElrSoW8ta+FwFqmr9dIFkn7cQEU3YhZr4Gcbs+ycUHOxVgDA4NBKB0rQ6e9VW5LvTw0isRYUrqM+M72vKxHk9zUIYYn/LGPvottKBYi2GLr0PHSeC2UE+Shmq7vcFIXj6hDjvD4kLJ5sKoUllEcZ1TPuBcnHUQ9ndKA5iktXDQOIJCUJmi7a0YJ2PGg7fvpYfT9k0ai/qZ+pIoRfoOEwE01bPoDn7NjeYnNQIDAQAB",
4
4
  "name": "Devthink",
5
- "version": "1.1.64",
5
+ "version": "1.1.65",
6
6
  "description": "A consent-first bridge for reviewed browser-agent tasks.",
7
7
  "permissions": [
8
8
  "activeTab",
@@ -9,6 +9,10 @@
9
9
  <section><h2>Task input</h2><div class="panel"><label for="taskinputretention">History retention (ms)</label><input id="taskinputretention" type="number" min="1" placeholder="keep every entry"><button id="taskinputsettings">Save taskinput options</button></div></section>
10
10
  <section><h2>Diff preview</h2><div class="panel"><label for="diffpreviewbytes">Offscreen offload byte ceiling</label><input id="diffpreviewbytes" type="number" min="1" placeholder="keep every diff inline"><button id="diffsettings">Save diffpreview options</button></div></section>
11
11
  <section><h2>Session interface options</h2><div class="panel"><label for="recallwindow">Recall window (ms)</label><input id="recallwindow" type="number" min="1" placeholder="keep every entry"><label for="noteretention">Note retention (ms)</label><input id="noteretention" type="number" min="1" placeholder="keep every note"><label for="summarywindow">Summary window (steps)</label><input id="summarywindow" type="number" min="0" placeholder="keep every step"><button id="sessionsettings">Save session options</button></div></section>
12
+ <section><h2>Interface finishing options</h2><div class="panel"><label for="themepreference">Theme preference</label><select id="themepreference" aria-label="Theme preference"><option value="">Follow the os preference</option><option value="light">Light</option><option value="dark">Dark</option></select><label for="uilanguage">Interface language</label><select id="uilanguage" aria-label="Interface language"><option value="">English (fallback)</option><option value="pt">Português</option></select><label for="recenttraydepth">Recent tray depth</label><input id="recenttraydepth" type="number" min="1" placeholder="keep every run"><label for="toastlivecount">Step toast live count</label><input id="toastlivecount" type="number" min="1" placeholder="keep every toast live"><label for="notifyconsent">Notification page content consent</label><input id="notifyconsent" type="checkbox"><label for="notifyenabled">Done and attention notifications</label><input id="notifyenabled" type="checkbox" checked><button id="finishingsettings">Save interface finishing options</button></div></section>
13
+ <section><h2>Shortcutkeys</h2><div class="panel"><div id="shortcutlist"></div><label for="shortcutedit">Edit a shortcut (command: combination)</label><input id="shortcutedit" type="text" placeholder="pauserun: alt+q"><button id="shortcutsettings">Save shortcut</button></div></section>
14
+ <section><h2>Import and export</h2><div class="panel"><div class="actions"><button id="exportbundle" class="secondary">Export settings bundle</button><button id="importbundle" class="secondary">Validate and apply an imported bundle</button></div><p id="bundlestatus" class="muted">The bundle never carries secretvault values or unmasked logs.</p><div id="dropzone" class="panel" role="region" aria-label="Drop csv, json or workflow files to import">Drop csv, json or workflow files here.</div></div></section>
15
+ <section><h2>Feature tour and guided tips</h2><div class="panel"><div class="actions"><button id="replaytour" class="secondary">Replay the feature tour</button><button id="recalltips" class="secondary">Recall guided tips</button></div><div id="tourstops" class="panel"></div></div></section>
12
16
  <section><h2>Transparency and consent options</h2><iframe src="transparencypage.html" title="Transparency, consent and security options" style="width:100%;min-height:24rem;border:0"></iframe></section>
13
17
  </main><script type="module" src="optionspage.js"></script></body>
14
18
  </html>
@@ -115,4 +115,153 @@ surfacechannel?.addEventListener("message", (event) => {
115
115
  });
116
116
  void load();
117
117
  void renderonboarding();
118
+ var themepreferenceselect = document.querySelector("#themepreference");
119
+ var uilanguageselect = document.querySelector("#uilanguage");
120
+ var recenttraydepthinput = document.querySelector("#recenttraydepth");
121
+ var toastlivecountinput = document.querySelector("#toastlivecount");
122
+ var notifyconsentinput = document.querySelector("#notifyconsent");
123
+ var notifyenabledinput = document.querySelector("#notifyenabled");
124
+ var shortcutlistnode = document.querySelector("#shortcutlist");
125
+ var shortcuteditinput = document.querySelector("#shortcutedit");
126
+ var bundlenode = document.querySelector("#bundlestatus");
127
+ var dropzonenode = document.querySelector("#dropzone");
128
+ var tourstopsnode = document.querySelector("#tourstops");
129
+ async function loadfinishing() {
130
+ try {
131
+ const context = await request({ kind: "context" });
132
+ const preferences = context.surfacepreferences ?? {};
133
+ if (preferences.themepreference !== void 0 && themepreferenceselect) themepreferenceselect.value = preferences.themepreference;
134
+ if (preferences.uilanguage !== void 0 && uilanguageselect) uilanguageselect.value = preferences.uilanguage;
135
+ if (preferences.recenttraydepth !== void 0 && recenttraydepthinput) recenttraydepthinput.value = String(preferences.recenttraydepth);
136
+ if (preferences.toastlivecount !== void 0 && toastlivecountinput) toastlivecountinput.value = String(preferences.toastlivecount);
137
+ if (notifyconsentinput) notifyconsentinput.checked = preferences.notifyconsent === true;
138
+ if (notifyenabledinput) notifyenabledinput.checked = preferences.notifyenabled !== false;
139
+ } catch (error) {
140
+ status(error instanceof Error ? error.message : String(error), true);
141
+ }
142
+ }
143
+ async function savefinishing() {
144
+ const themepreference = themepreferenceselect?.value ?? "";
145
+ const uilanguage = uilanguageselect?.value ?? "";
146
+ const recenttraydepth = recenttraydepthinput?.value.trim() ?? "";
147
+ const toastlivecount = toastlivecountinput?.value.trim() ?? "";
148
+ await request({ kind: "views", settings: { ...themepreference !== "" ? { themepreference } : {}, ...uilanguage !== "" ? { uilanguage } : {}, ...recenttraydepth !== "" ? { recenttraydepth: Number(recenttraydepth) } : {}, ...toastlivecount !== "" ? { toastlivecount: Number(toastlivecount) } : {}, notifyconsent: notifyconsentinput?.checked === true, notifyenabled: notifyenabledinput?.checked === true } });
149
+ await applythemelive();
150
+ status("The interface finishing options saved; the theme, the language, the tray depth and the toast live count take effect at once.");
151
+ }
152
+ async function applythemelive() {
153
+ try {
154
+ const result = await request({ kind: "views", theme: { resolve: true, preference: themepreferenceselect?.value ?? "" } });
155
+ for (const [name, value] of Object.entries(result.appearance.tokens)) document.documentElement.style.setProperty(`--theme-${name}`, value);
156
+ document.documentElement.style.setProperty("color-scheme", result.appearance.mode);
157
+ } catch {
158
+ }
159
+ }
160
+ async function rendershortcuts() {
161
+ if (!shortcutlistnode) return;
162
+ try {
163
+ const result = await request({ kind: "views", shortcut: { list: true } });
164
+ shortcutlistnode.replaceChildren();
165
+ const list = document.createElement("ul");
166
+ list.className = "audit";
167
+ for (const binding of result.bindings ?? []) {
168
+ const combination = [...binding.modifiers, binding.key].join("+");
169
+ list.append(Object.assign(document.createElement("li"), { textContent: `${binding.command}: ${binding.display ?? combination}` }));
170
+ }
171
+ shortcutlistnode.append(list);
172
+ } catch (error) {
173
+ shortcutlistnode.textContent = error instanceof Error ? error.message : String(error);
174
+ }
175
+ }
176
+ async function saveshortcut() {
177
+ const text = shortcuteditinput?.value.trim() ?? "";
178
+ const split = text.split(":");
179
+ const command = split[0]?.trim() ?? "";
180
+ const combination = split.slice(1).join(":").trim();
181
+ if (command === "" || combination === "") {
182
+ status("The shortcut edit needs its command and its combination, such as pauserun: alt+q.", true);
183
+ return;
184
+ }
185
+ await request({ kind: "views", shortcut: { edit: { command, text: combination } } });
186
+ status(`The ${command} shortcut now binds ${combination}; the command keeps its palette gates.`);
187
+ await rendershortcuts();
188
+ }
189
+ async function rendertourstops() {
190
+ if (!tourstopsnode) return;
191
+ try {
192
+ const result = await request({ kind: "views", tour: { stops: true } });
193
+ tourstopsnode.replaceChildren();
194
+ const list = document.createElement("ol");
195
+ list.className = "audit";
196
+ for (const stop of result.stops ?? []) list.append(Object.assign(document.createElement("li"), { textContent: `${stop.title} (${stop.surface}): ${stop.body}` }));
197
+ tourstopsnode.append(list);
198
+ } catch (error) {
199
+ tourstopsnode.textContent = error instanceof Error ? error.message : String(error);
200
+ }
201
+ }
202
+ async function exportbundle() {
203
+ const result = await request({ kind: "views", importexport: { export: true } });
204
+ if (bundlenode) bundlenode.textContent = `The bundle of the profile ${result.payload.profile} carries ${result.payload.contents.siteprofiles.length} site profile${result.payload.contents.siteprofiles.length === 1 ? "" : "s"} and ${result.payload.contents.notes.length} note${result.payload.contents.notes.length === 1 ? "" : "s"}; ${result.payload.exclusions.join(" and ")} never enter any bundle.`;
205
+ status("The settings bundle exported with its exclusion list.");
206
+ }
207
+ async function importbundle() {
208
+ const text = window.prompt("Paste the importexport bundle json") ?? "";
209
+ if (text.trim() === "") return;
210
+ const parsed = JSON.parse(text);
211
+ const validation = await request({ kind: "views", importexport: { validate: parsed } });
212
+ if (!validation.ok) {
213
+ status(validation.reason, true);
214
+ return;
215
+ }
216
+ const applied = await request({ kind: "views", importexport: { apply: { preferences: parsed.contents?.preferences ?? {} } } });
217
+ status(`The bundle applied ${applied.applied.length} preference key${applied.applied.length === 1 ? "" : "s"} after its validation passed.`);
218
+ await loadfinishing();
219
+ }
220
+ function wir(dropimportzone) {
221
+ dropimportzone.addEventListener("dragover", (event) => {
222
+ event.preventDefault();
223
+ });
224
+ dropimportzone.addEventListener("drop", (event) => {
225
+ event.preventDefault();
226
+ const file = event.dataTransfer?.files[0];
227
+ if (file === void 0) return;
228
+ void file.text().then((head) => request({ kind: "views", dropimport: { file: { filename: file.name, bytes: file.size, head: head.slice(0, 2e3) } } })).then((result) => {
229
+ const session = result.session;
230
+ status(`The dropimport detected the ${session.kind} kind of ${session.filename}; the import path takes the file from here.`);
231
+ }).catch((error) => status(error instanceof Error ? error.message : String(error), true));
232
+ });
233
+ }
234
+ if (dropzonenode) wir(dropzonenode);
235
+ document.querySelector("#finishingsettings")?.addEventListener("click", () => {
236
+ void savefinishing().catch((error) => status(error instanceof Error ? error.message : String(error), true));
237
+ });
238
+ document.querySelector("#shortcutsettings")?.addEventListener("click", () => {
239
+ void saveshortcut().catch((error) => status(error instanceof Error ? error.message : String(error), true));
240
+ });
241
+ document.querySelector("#exportbundle")?.addEventListener("click", () => {
242
+ void exportbundle().catch((error) => status(error instanceof Error ? error.message : String(error), true));
243
+ });
244
+ document.querySelector("#importbundle")?.addEventListener("click", () => {
245
+ void importbundle().catch((error) => status(error instanceof Error ? error.message : String(error), true));
246
+ });
247
+ document.querySelector("#replaytour")?.addEventListener("click", () => {
248
+ void (async () => {
249
+ await request({ kind: "views", tour: { replay: true } });
250
+ status("The featuretour replays with its datagrid, compareviewer and pickeroverlay stops.");
251
+ })().catch((error) => status(error instanceof Error ? error.message : String(error), true));
252
+ });
253
+ document.querySelector("#recalltips")?.addEventListener("click", () => {
254
+ void (async () => {
255
+ await request({ kind: "views", tips: { recall: true } });
256
+ status("The guidedtips recalled; they show again during the picker sessions.");
257
+ })().catch((error) => status(error instanceof Error ? error.message : String(error), true));
258
+ });
259
+ themepreferenceselect?.addEventListener("change", () => {
260
+ void applythemelive().catch(() => {
261
+ });
262
+ });
263
+ void loadfinishing();
264
+ void applythemelive();
265
+ void rendershortcuts();
266
+ void rendertourstops();
118
267
  //# sourceMappingURL=optionspage.js.map
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../optionspage.ts"],
4
- "sourcesContent": ["export {};\n\n/**\n * Optionspage runtime of the 1.1.64 family.\n * The optionspage gathers every setting into one page with sections: the onboarding replay, the commandpalette recent window and shortcut, the logstream live buffer bound, the taskinput history retention, the diffpreview offscreen offload ceiling and the session interface options of the 1.1.63 family, while the transparency, consent and security sections of the earlier releases import through the embedded transparencypage; every write takes effect without reloading the extension because the background reads its settings live on each decision.\n */\n\nconst statusnode = document.querySelector<HTMLElement>(\"#status\");\nconst onboardingroot = document.querySelector<HTMLElement>(\"#onboarding\");\nconst paletterecentsinput = document.querySelector<HTMLInputElement>(\"#paletterecents\");\nconst paletteshortcutinput = document.querySelector<HTMLInputElement>(\"#paletteshortcut\");\nconst logstreambufferinput = document.querySelector<HTMLInputElement>(\"#logstreambuffer\");\nconst taskinputretentioninput = document.querySelector<HTMLInputElement>(\"#taskinputretention\");\nconst diffpreviewbytesinput = document.querySelector<HTMLInputElement>(\"#diffpreviewbytes\");\nconst recallwindowinput = document.querySelector<HTMLInputElement>(\"#recallwindow\");\nconst noteretentioninput = document.querySelector<HTMLInputElement>(\"#noteretention\");\nconst summarywindowinput = document.querySelector<HTMLInputElement>(\"#summarywindow\");\n\nfunction status(message: string, error = false): void { if (statusnode) { statusnode.textContent = message; statusnode.dataset.state = error ? \"error\" : \"ready\"; } }\nasync function request(message: unknown): Promise<unknown> { const response = await chrome.runtime.sendMessage(message) as { ok: boolean; value?: unknown; error?: string }; if (!response.ok) throw new Error(response.error); return response.value; }\n\ntype surfacecontext = { sessionpreferences?: { recallwindow?: number; noteretention?: number; summarywindow?: number }; surfacepreferences?: { paletterecents?: number; paletteshortcut?: string; logstreambuffer?: number; taskinputretention?: number; diffpreviewbytes?: number } };\n\n/** Loads the stored surface options into the inputs; an absent value keeps the placeholder that names the documented default. */\nasync function load(): Promise<void> {\n try {\n const context = await request({ kind: \"context\" }) as surfacecontext;\n const preferences = context.surfacepreferences ?? {};\n const session = context.sessionpreferences ?? {};\n if (preferences.paletterecents !== undefined && paletterecentsinput) paletterecentsinput.value = String(preferences.paletterecents);\n if (preferences.paletteshortcut !== undefined && paletteshortcutinput) paletteshortcutinput.value = preferences.paletteshortcut;\n if (preferences.logstreambuffer !== undefined && logstreambufferinput) logstreambufferinput.value = String(preferences.logstreambuffer);\n if (preferences.taskinputretention !== undefined && taskinputretentioninput) taskinputretentioninput.value = String(preferences.taskinputretention);\n if (preferences.diffpreviewbytes !== undefined && diffpreviewbytesinput) diffpreviewbytesinput.value = String(preferences.diffpreviewbytes);\n if (session.recallwindow !== undefined && recallwindowinput) recallwindowinput.value = String(session.recallwindow);\n if (session.noteretention !== undefined && noteretentioninput) noteretentioninput.value = String(session.noteretention);\n if (session.summarywindow !== undefined && summarywindowinput) summarywindowinput.value = String(session.summarywindow);\n status(\"The surface options loaded; every write takes effect without reloading the extension.\");\n } catch (error) { status(error instanceof Error ? error.message : String(error), true); }\n}\n\n/** Writes the commandpalette options; the recent window and the shortcut stay user choices with no engine defaults forced. */\nasync function savepalette(): Promise<void> {\n const paletterecents = paletterecentsinput?.value.trim() ?? \"\";\n const paletteshortcut = paletteshortcutinput?.value.trim() ?? \"\";\n await request({ kind: \"surface\", settings: { ...(paletterecents !== \"\" ? { paletterecents: Number(paletterecents) } : {}), ...(paletteshortcut !== \"\" ? { paletteshortcut } : {}) } });\n status(`The palette options saved${paletterecents !== \"\" ? ` with the recent window of ${paletterecents}` : \"\"}${paletteshortcut !== \"\" ? ` and the shortcut ${paletteshortcut}` : \"\"}.`);\n}\n\n/** Writes the logstream live buffer bound; the full history stays in memory whatever the bound. */\nasync function savelogstream(): Promise<void> {\n const bound = logstreambufferinput?.value.trim() ?? \"\";\n await request({ kind: \"surface\", settings: { ...(bound !== \"\" ? { logstreambuffer: Number(bound) } : {}) } });\n status(bound === \"\" ? \"No bound configured; the live window keeps every event.\" : `The logstream live buffer bound of ${bound} saved; the full history stays in memory.`);\n}\n\n/** Writes the taskinput history retention. */\nasync function savetaskinput(): Promise<void> {\n const retention = taskinputretentioninput?.value.trim() ?? \"\";\n await request({ kind: \"surface\", settings: { ...(retention !== \"\" ? { taskinputretention: Number(retention) } : {}) } });\n status(retention === \"\" ? \"No retention configured; the taskinput history keeps every entry.\" : `The taskinput history retention of ${retention} milliseconds saved.`);\n}\n\n/** Writes the diffpreview offscreen offload byte ceiling. */\nasync function savediff(): Promise<void> {\n const bytes = diffpreviewbytesinput?.value.trim() ?? \"\";\n await request({ kind: \"surface\", settings: { ...(bytes !== \"\" ? { diffpreviewbytes: Number(bytes) } : {}) } });\n status(bytes === \"\" ? \"No ceiling configured; every diff stays inline.\" : `The diffpreview offload ceiling of ${bytes} bytes saved.`);\n}\n\n/** Writes the session interface options of the 1.1.63 family through the sessions settings seam. */\nasync function savesession(): Promise<void> {\n const recallwindow = recallwindowinput?.value.trim() ?? \"\";\n const noteretention = noteretentioninput?.value.trim() ?? \"\";\n const summarywindow = summarywindowinput?.value.trim() ?? \"\";\n await request({ kind: \"sessions\", settings: { ...(recallwindow !== \"\" ? { recallwindow: Number(recallwindow) } : {}), ...(noteretention !== \"\" ? { noteretention: Number(noteretention) } : {}), ...(summarywindow !== \"\" ? { summarywindow: Number(summarywindow) } : {}) } });\n status(\"The session interface options saved; the recall window, the note retention and the summary window take effect at once.\");\n}\n\n/** Renders the onboarding state and replays the walkthrough on demand. */\nasync function renderonboarding(): Promise<void> {\n if (!onboardingroot) return;\n try {\n const result = await request({ kind: \"surface\", onboarding: {} }) as { steps: Array<{ id: string; title: string; body: string; surface: string }>; state?: { stepscompleted: string[]; done: boolean } };\n onboardingroot.replaceChildren();\n const state = result.state;\n const line = document.createElement(\"p\");\n line.textContent = state === undefined ? \"The onboarding walkthrough never ran; it starts on the next popup open.\" : state.done ? `The walkthrough is done (${state.stepscompleted.length} steps); the replay restarts it on demand and writes no second consent event.` : `The walkthrough stands at ${state.stepscompleted.length} of ${result.steps.length} steps.`;\n onboardingroot.append(line);\n const list = document.createElement(\"ol\");\n list.className = \"audit\";\n for (const step of result.steps) list.append(Object.assign(document.createElement(\"li\"), { textContent: `${step.title} (${step.surface}): ${step.body}${state?.stepscompleted.includes(step.id) ? \" \u2014 done\" : \"\"}` }));\n onboardingroot.append(list);\n } catch (error) { onboardingroot.textContent = error instanceof Error ? error.message : String(error); }\n}\n\ndocument.querySelector<HTMLButtonElement>(\"#replayonboarding\")?.addEventListener(\"click\", () => { void (async () => { await request({ kind: \"surface\", onboarding: { replay: true } }); status(\"The onboarding walkthrough replays; it opens on the next popup open.\"); await renderonboarding(); })().catch(error => status(error instanceof Error ? error.message : String(error), true)); });\ndocument.querySelector<HTMLButtonElement>(\"#palettesettings\")?.addEventListener(\"click\", () => { void savepalette().catch(error => status(error instanceof Error ? error.message : String(error), true)); });\ndocument.querySelector<HTMLButtonElement>(\"#logstreamsettings\")?.addEventListener(\"click\", () => { void savelogstream().catch(error => status(error instanceof Error ? error.message : String(error), true)); });\ndocument.querySelector<HTMLButtonElement>(\"#taskinputsettings\")?.addEventListener(\"click\", () => { void savetaskinput().catch(error => status(error instanceof Error ? error.message : String(error), true)); });\ndocument.querySelector<HTMLButtonElement>(\"#diffsettings\")?.addEventListener(\"click\", () => { void savediff().catch(error => status(error instanceof Error ? error.message : String(error), true)); });\ndocument.querySelector<HTMLButtonElement>(\"#sessionsettings\")?.addEventListener(\"click\", () => { void savesession().catch(error => status(error instanceof Error ? error.message : String(error), true)); });\n\n/** The optionspage sees settings changes through the single broadcast channel so two open pages never drift. */\nconst surfacechannel: BroadcastChannel | undefined = typeof BroadcastChannel === \"function\" ? new BroadcastChannel(\"devthinksurfaces\") : undefined;\nsurfacechannel?.addEventListener(\"message\", (event: MessageEvent) => { const frame = event.data as { channel?: string }; if (frame?.channel === \"settings\") { void load().catch(() => { /* a failing reload keeps the last loaded options */ }); } });\n\nvoid load();\nvoid renderonboarding();\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["export {};\n\n/**\n * Optionspage runtime of the 1.1.64 family.\n * The optionspage gathers every setting into one page with sections: the onboarding replay, the commandpalette recent window and shortcut, the logstream live buffer bound, the taskinput history retention, the diffpreview offscreen offload ceiling and the session interface options of the 1.1.63 family, while the transparency, consent and security sections of the earlier releases import through the embedded transparencypage; every write takes effect without reloading the extension because the background reads its settings live on each decision.\n */\n\nconst statusnode = document.querySelector<HTMLElement>(\"#status\");\nconst onboardingroot = document.querySelector<HTMLElement>(\"#onboarding\");\nconst paletterecentsinput = document.querySelector<HTMLInputElement>(\"#paletterecents\");\nconst paletteshortcutinput = document.querySelector<HTMLInputElement>(\"#paletteshortcut\");\nconst logstreambufferinput = document.querySelector<HTMLInputElement>(\"#logstreambuffer\");\nconst taskinputretentioninput = document.querySelector<HTMLInputElement>(\"#taskinputretention\");\nconst diffpreviewbytesinput = document.querySelector<HTMLInputElement>(\"#diffpreviewbytes\");\nconst recallwindowinput = document.querySelector<HTMLInputElement>(\"#recallwindow\");\nconst noteretentioninput = document.querySelector<HTMLInputElement>(\"#noteretention\");\nconst summarywindowinput = document.querySelector<HTMLInputElement>(\"#summarywindow\");\n\nfunction status(message: string, error = false): void { if (statusnode) { statusnode.textContent = message; statusnode.dataset.state = error ? \"error\" : \"ready\"; } }\nasync function request(message: unknown): Promise<unknown> { const response = await chrome.runtime.sendMessage(message) as { ok: boolean; value?: unknown; error?: string }; if (!response.ok) throw new Error(response.error); return response.value; }\n\ntype surfacecontext = { sessionpreferences?: { recallwindow?: number; noteretention?: number; summarywindow?: number }; surfacepreferences?: { paletterecents?: number; paletteshortcut?: string; logstreambuffer?: number; taskinputretention?: number; diffpreviewbytes?: number } };\n\n/** Loads the stored surface options into the inputs; an absent value keeps the placeholder that names the documented default. */\nasync function load(): Promise<void> {\n try {\n const context = await request({ kind: \"context\" }) as surfacecontext;\n const preferences = context.surfacepreferences ?? {};\n const session = context.sessionpreferences ?? {};\n if (preferences.paletterecents !== undefined && paletterecentsinput) paletterecentsinput.value = String(preferences.paletterecents);\n if (preferences.paletteshortcut !== undefined && paletteshortcutinput) paletteshortcutinput.value = preferences.paletteshortcut;\n if (preferences.logstreambuffer !== undefined && logstreambufferinput) logstreambufferinput.value = String(preferences.logstreambuffer);\n if (preferences.taskinputretention !== undefined && taskinputretentioninput) taskinputretentioninput.value = String(preferences.taskinputretention);\n if (preferences.diffpreviewbytes !== undefined && diffpreviewbytesinput) diffpreviewbytesinput.value = String(preferences.diffpreviewbytes);\n if (session.recallwindow !== undefined && recallwindowinput) recallwindowinput.value = String(session.recallwindow);\n if (session.noteretention !== undefined && noteretentioninput) noteretentioninput.value = String(session.noteretention);\n if (session.summarywindow !== undefined && summarywindowinput) summarywindowinput.value = String(session.summarywindow);\n status(\"The surface options loaded; every write takes effect without reloading the extension.\");\n } catch (error) { status(error instanceof Error ? error.message : String(error), true); }\n}\n\n/** Writes the commandpalette options; the recent window and the shortcut stay user choices with no engine defaults forced. */\nasync function savepalette(): Promise<void> {\n const paletterecents = paletterecentsinput?.value.trim() ?? \"\";\n const paletteshortcut = paletteshortcutinput?.value.trim() ?? \"\";\n await request({ kind: \"surface\", settings: { ...(paletterecents !== \"\" ? { paletterecents: Number(paletterecents) } : {}), ...(paletteshortcut !== \"\" ? { paletteshortcut } : {}) } });\n status(`The palette options saved${paletterecents !== \"\" ? ` with the recent window of ${paletterecents}` : \"\"}${paletteshortcut !== \"\" ? ` and the shortcut ${paletteshortcut}` : \"\"}.`);\n}\n\n/** Writes the logstream live buffer bound; the full history stays in memory whatever the bound. */\nasync function savelogstream(): Promise<void> {\n const bound = logstreambufferinput?.value.trim() ?? \"\";\n await request({ kind: \"surface\", settings: { ...(bound !== \"\" ? { logstreambuffer: Number(bound) } : {}) } });\n status(bound === \"\" ? \"No bound configured; the live window keeps every event.\" : `The logstream live buffer bound of ${bound} saved; the full history stays in memory.`);\n}\n\n/** Writes the taskinput history retention. */\nasync function savetaskinput(): Promise<void> {\n const retention = taskinputretentioninput?.value.trim() ?? \"\";\n await request({ kind: \"surface\", settings: { ...(retention !== \"\" ? { taskinputretention: Number(retention) } : {}) } });\n status(retention === \"\" ? \"No retention configured; the taskinput history keeps every entry.\" : `The taskinput history retention of ${retention} milliseconds saved.`);\n}\n\n/** Writes the diffpreview offscreen offload byte ceiling. */\nasync function savediff(): Promise<void> {\n const bytes = diffpreviewbytesinput?.value.trim() ?? \"\";\n await request({ kind: \"surface\", settings: { ...(bytes !== \"\" ? { diffpreviewbytes: Number(bytes) } : {}) } });\n status(bytes === \"\" ? \"No ceiling configured; every diff stays inline.\" : `The diffpreview offload ceiling of ${bytes} bytes saved.`);\n}\n\n/** Writes the session interface options of the 1.1.63 family through the sessions settings seam. */\nasync function savesession(): Promise<void> {\n const recallwindow = recallwindowinput?.value.trim() ?? \"\";\n const noteretention = noteretentioninput?.value.trim() ?? \"\";\n const summarywindow = summarywindowinput?.value.trim() ?? \"\";\n await request({ kind: \"sessions\", settings: { ...(recallwindow !== \"\" ? { recallwindow: Number(recallwindow) } : {}), ...(noteretention !== \"\" ? { noteretention: Number(noteretention) } : {}), ...(summarywindow !== \"\" ? { summarywindow: Number(summarywindow) } : {}) } });\n status(\"The session interface options saved; the recall window, the note retention and the summary window take effect at once.\");\n}\n\n/** Renders the onboarding state and replays the walkthrough on demand. */\nasync function renderonboarding(): Promise<void> {\n if (!onboardingroot) return;\n try {\n const result = await request({ kind: \"surface\", onboarding: {} }) as { steps: Array<{ id: string; title: string; body: string; surface: string }>; state?: { stepscompleted: string[]; done: boolean } };\n onboardingroot.replaceChildren();\n const state = result.state;\n const line = document.createElement(\"p\");\n line.textContent = state === undefined ? \"The onboarding walkthrough never ran; it starts on the next popup open.\" : state.done ? `The walkthrough is done (${state.stepscompleted.length} steps); the replay restarts it on demand and writes no second consent event.` : `The walkthrough stands at ${state.stepscompleted.length} of ${result.steps.length} steps.`;\n onboardingroot.append(line);\n const list = document.createElement(\"ol\");\n list.className = \"audit\";\n for (const step of result.steps) list.append(Object.assign(document.createElement(\"li\"), { textContent: `${step.title} (${step.surface}): ${step.body}${state?.stepscompleted.includes(step.id) ? \" \u2014 done\" : \"\"}` }));\n onboardingroot.append(list);\n } catch (error) { onboardingroot.textContent = error instanceof Error ? error.message : String(error); }\n}\n\ndocument.querySelector<HTMLButtonElement>(\"#replayonboarding\")?.addEventListener(\"click\", () => { void (async () => { await request({ kind: \"surface\", onboarding: { replay: true } }); status(\"The onboarding walkthrough replays; it opens on the next popup open.\"); await renderonboarding(); })().catch(error => status(error instanceof Error ? error.message : String(error), true)); });\ndocument.querySelector<HTMLButtonElement>(\"#palettesettings\")?.addEventListener(\"click\", () => { void savepalette().catch(error => status(error instanceof Error ? error.message : String(error), true)); });\ndocument.querySelector<HTMLButtonElement>(\"#logstreamsettings\")?.addEventListener(\"click\", () => { void savelogstream().catch(error => status(error instanceof Error ? error.message : String(error), true)); });\ndocument.querySelector<HTMLButtonElement>(\"#taskinputsettings\")?.addEventListener(\"click\", () => { void savetaskinput().catch(error => status(error instanceof Error ? error.message : String(error), true)); });\ndocument.querySelector<HTMLButtonElement>(\"#diffsettings\")?.addEventListener(\"click\", () => { void savediff().catch(error => status(error instanceof Error ? error.message : String(error), true)); });\ndocument.querySelector<HTMLButtonElement>(\"#sessionsettings\")?.addEventListener(\"click\", () => { void savesession().catch(error => status(error instanceof Error ? error.message : String(error), true)); });\n\n/** The optionspage sees settings changes through the single broadcast channel so two open pages never drift. */\nconst surfacechannel: BroadcastChannel | undefined = typeof BroadcastChannel === \"function\" ? new BroadcastChannel(\"devthinksurfaces\") : undefined;\nsurfacechannel?.addEventListener(\"message\", (event: MessageEvent) => { const frame = event.data as { channel?: string }; if (frame?.channel === \"settings\") { void load().catch(() => { /* a failing reload keeps the last loaded options */ }); } });\n\nvoid load();\nvoid renderonboarding();\n\n/**\n * Interface finishing options of the 1.1.65 family: the darklight theme preference with its manual override, the interface language of the locale bundles, the recenttray depth, the step toast live count, the notification consent and preference, the user editable shortcutkeys, the importexport bundles with their dropimport zone and the featuretour replay with the guidedtip recall.\n */\nconst themepreferenceselect = document.querySelector<HTMLSelectElement>(\"#themepreference\");\nconst uilanguageselect = document.querySelector<HTMLSelectElement>(\"#uilanguage\");\nconst recenttraydepthinput = document.querySelector<HTMLInputElement>(\"#recenttraydepth\");\nconst toastlivecountinput = document.querySelector<HTMLInputElement>(\"#toastlivecount\");\nconst notifyconsentinput = document.querySelector<HTMLInputElement>(\"#notifyconsent\");\nconst notifyenabledinput = document.querySelector<HTMLInputElement>(\"#notifyenabled\");\nconst shortcutlistnode = document.querySelector<HTMLElement>(\"#shortcutlist\");\nconst shortcuteditinput = document.querySelector<HTMLInputElement>(\"#shortcutedit\");\nconst bundlenode = document.querySelector<HTMLElement>(\"#bundlestatus\");\nconst dropzonenode = document.querySelector<HTMLElement>(\"#dropzone\");\nconst tourstopsnode = document.querySelector<HTMLElement>(\"#tourstops\");\n\ntype finishingcontext = { surfacepreferences?: { recenttraydepth?: number; notifyconsent?: boolean; notifyenabled?: boolean; themepreference?: string; uilanguage?: string; toastlivecount?: number } };\n\n/** Loads the finishing options beside the surface options. */\nasync function loadfinishing(): Promise<void> {\n try {\n const context = await request({ kind: \"context\" }) as finishingcontext;\n const preferences = context.surfacepreferences ?? {};\n if (preferences.themepreference !== undefined && themepreferenceselect) themepreferenceselect.value = preferences.themepreference;\n if (preferences.uilanguage !== undefined && uilanguageselect) uilanguageselect.value = preferences.uilanguage;\n if (preferences.recenttraydepth !== undefined && recenttraydepthinput) recenttraydepthinput.value = String(preferences.recenttraydepth);\n if (preferences.toastlivecount !== undefined && toastlivecountinput) toastlivecountinput.value = String(preferences.toastlivecount);\n if (notifyconsentinput) notifyconsentinput.checked = preferences.notifyconsent === true;\n if (notifyenabledinput) notifyenabledinput.checked = preferences.notifyenabled !== false;\n } catch (error) { status(error instanceof Error ? error.message : String(error), true); }\n}\n\n/** Saves the finishing options: the theme preference, the language, the tray depth, the toast live count and the notification consent and preference. */\nasync function savefinishing(): Promise<void> {\n const themepreference = themepreferenceselect?.value ?? \"\";\n const uilanguage = uilanguageselect?.value ?? \"\";\n const recenttraydepth = recenttraydepthinput?.value.trim() ?? \"\";\n const toastlivecount = toastlivecountinput?.value.trim() ?? \"\";\n await request({ kind: \"views\", settings: { ...(themepreference !== \"\" ? { themepreference } : {}), ...(uilanguage !== \"\" ? { uilanguage } : {}), ...(recenttraydepth !== \"\" ? { recenttraydepth: Number(recenttraydepth) } : {}), ...(toastlivecount !== \"\" ? { toastlivecount: Number(toastlivecount) } : {}), notifyconsent: notifyconsentinput?.checked === true, notifyenabled: notifyenabledinput?.checked === true } });\n await applythemelive();\n status(\"The interface finishing options saved; the theme, the language, the tray depth and the toast live count take effect at once.\");\n}\n\n/** Resolves and applies the darklight tokens on the live document so the theme covers the optionspage too. */\nasync function applythemelive(): Promise<void> {\n try {\n const result = await request({ kind: \"views\", theme: { resolve: true, preference: themepreferenceselect?.value ?? \"\" } }) as { appearance: { mode: \"dark\" | \"light\"; tokens: Record<string, string>; source: string } };\n for (const [name, value] of Object.entries(result.appearance.tokens)) document.documentElement.style.setProperty(`--theme-${name}`, value);\n document.documentElement.style.setProperty(\"color-scheme\", result.appearance.mode);\n } catch { /* a failing theme read keeps the shipped light theme */ }\n}\n\n/** Renders the user editable shortcutkeys bindings with their display text. */\nasync function rendershortcuts(): Promise<void> {\n if (!shortcutlistnode) return;\n try {\n const result = await request({ kind: \"views\", shortcut: { list: true } }) as { bindings?: Array<{ command: string; key: string; modifiers: string[]; display?: string }> };\n shortcutlistnode.replaceChildren();\n const list = document.createElement(\"ul\");\n list.className = \"audit\";\n for (const binding of result.bindings ?? []) {\n const combination = [...binding.modifiers, binding.key].join(\"+\");\n list.append(Object.assign(document.createElement(\"li\"), { textContent: `${binding.command}: ${binding.display ?? combination}` }));\n }\n shortcutlistnode.append(list);\n } catch (error) { shortcutlistnode.textContent = error instanceof Error ? error.message : String(error); }\n}\n\n/** Saves one edited shortcut binding from its \"command: combination\" text. */\nasync function saveshortcut(): Promise<void> {\n const text = shortcuteditinput?.value.trim() ?? \"\";\n const split = text.split(\":\");\n const command = split[0]?.trim() ?? \"\";\n const combination = split.slice(1).join(\":\").trim();\n if (command === \"\" || combination === \"\") { status(\"The shortcut edit needs its command and its combination, such as pauserun: alt+q.\", true); return; }\n await request({ kind: \"views\", shortcut: { edit: { command, text: combination } } });\n status(`The ${command} shortcut now binds ${combination}; the command keeps its palette gates.`);\n await rendershortcuts();\n}\n\n/** Renders the featuretour stops so the replay walkthrough reads its route first. */\nasync function rendertourstops(): Promise<void> {\n if (!tourstopsnode) return;\n try {\n const result = await request({ kind: \"views\", tour: { stops: true } }) as { stops?: Array<{ id: string; surface: string; title: string; body: string }> };\n tourstopsnode.replaceChildren();\n const list = document.createElement(\"ol\");\n list.className = \"audit\";\n for (const stop of result.stops ?? []) list.append(Object.assign(document.createElement(\"li\"), { textContent: `${stop.title} (${stop.surface}): ${stop.body}` }));\n tourstopsnode.append(list);\n } catch (error) { tourstopsnode.textContent = error instanceof Error ? error.message : String(error); }\n}\n\n/** Exports the settings bundle and renders its honest exclusion list. */\nasync function exportbundle(): Promise<void> {\n const result = await request({ kind: \"views\", importexport: { export: true } }) as { payload: { profile: string; exclusions: string[]; contents: { originprofiles: unknown[]; siteprofiles: unknown[]; notes: unknown[] } } };\n if (bundlenode) bundlenode.textContent = `The bundle of the profile ${result.payload.profile} carries ${result.payload.contents.siteprofiles.length} site profile${result.payload.contents.siteprofiles.length === 1 ? \"\" : \"s\"} and ${result.payload.contents.notes.length} note${result.payload.contents.notes.length === 1 ? \"\" : \"s\"}; ${result.payload.exclusions.join(\" and \")} never enter any bundle.`;\n status(\"The settings bundle exported with its exclusion list.\");\n}\n\n/** Validates one pasted bundle and applies its preferences when the validation passes. */\nasync function importbundle(): Promise<void> {\n const text = window.prompt(\"Paste the importexport bundle json\") ?? \"\";\n if (text.trim() === \"\") return;\n const parsed = JSON.parse(text) as Record<string, unknown>;\n const validation = await request({ kind: \"views\", importexport: { validate: parsed } }) as { ok: boolean; reason: string };\n if (!validation.ok) { status(validation.reason, true); return; }\n const applied = await request({ kind: \"views\", importexport: { apply: { preferences: (parsed as { contents?: { preferences?: Record<string, unknown> } }).contents?.preferences ?? {} } } }) as { applied: string[] };\n status(`The bundle applied ${applied.applied.length} preference key${applied.applied.length === 1 ? \"\" : \"s\"} after its validation passed.`);\n await loadfinishing();\n}\n\n/** Accepts the csv, json and workflow files the user drops on the dropimport zone. */\nfunction wir(dropimportzone: HTMLElement): void {\n dropimportzone.addEventListener(\"dragover\", event => { event.preventDefault(); });\n dropimportzone.addEventListener(\"drop\", event => {\n event.preventDefault();\n const file = event.dataTransfer?.files[0];\n if (file === undefined) return;\n void file.text().then(head => request({ kind: \"views\", dropimport: { file: { filename: file.name, bytes: file.size, head: head.slice(0, 2000) } } })).then(result => {\n const session = (result as { session: { filename: string; kind: string } }).session;\n status(`The dropimport detected the ${session.kind} kind of ${session.filename}; the import path takes the file from here.`);\n }).catch(error => status(error instanceof Error ? error.message : String(error), true));\n });\n}\nif (dropzonenode) wir(dropzonenode);\n\ndocument.querySelector<HTMLButtonElement>(\"#finishingsettings\")?.addEventListener(\"click\", () => { void savefinishing().catch(error => status(error instanceof Error ? error.message : String(error), true)); });\ndocument.querySelector<HTMLButtonElement>(\"#shortcutsettings\")?.addEventListener(\"click\", () => { void saveshortcut().catch(error => status(error instanceof Error ? error.message : String(error), true)); });\ndocument.querySelector<HTMLButtonElement>(\"#exportbundle\")?.addEventListener(\"click\", () => { void exportbundle().catch(error => status(error instanceof Error ? error.message : String(error), true)); });\ndocument.querySelector<HTMLButtonElement>(\"#importbundle\")?.addEventListener(\"click\", () => { void importbundle().catch(error => status(error instanceof Error ? error.message : String(error), true)); });\ndocument.querySelector<HTMLButtonElement>(\"#replaytour\")?.addEventListener(\"click\", () => { void (async () => { await request({ kind: \"views\", tour: { replay: true } }); status(\"The featuretour replays with its datagrid, compareviewer and pickeroverlay stops.\"); })().catch(error => status(error instanceof Error ? error.message : String(error), true)); });\ndocument.querySelector<HTMLButtonElement>(\"#recalltips\")?.addEventListener(\"click\", () => { void (async () => { await request({ kind: \"views\", tips: { recall: true } }); status(\"The guidedtips recalled; they show again during the picker sessions.\"); })().catch(error => status(error instanceof Error ? error.message : String(error), true)); });\nthemepreferenceselect?.addEventListener(\"change\", () => { void applythemelive().catch(() => { /* a failing theme read keeps the shipped light theme */ }); });\n\nvoid loadfinishing();\nvoid applythemelive();\nvoid rendershortcuts();\nvoid rendertourstops();\n"],
5
+ "mappings": "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",
6
6
  "names": []
7
7
  }