@phenx-inc/ctlsurf 0.13.6 → 0.14.0

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 (43) hide show
  1. package/out/headless/index.mjs +13663 -385
  2. package/out/headless/index.mjs.map +4 -4
  3. package/out/main/index.js +11665 -286
  4. package/out/main/node-CUnQxFha.js +868 -0
  5. package/out/preload/index.js +17 -0
  6. package/out/renderer/assets/{cssMode-CsSLnKZ-.js → cssMode-7adWSORr.js} +3 -3
  7. package/out/renderer/assets/{freemarker2-C1XYRbOq.js → freemarker2-BkLLWnzk.js} +1 -1
  8. package/out/renderer/assets/{handlebars-BSdbbnMW.js → handlebars-Cinfm9fZ.js} +1 -1
  9. package/out/renderer/assets/{html-96igtyOz.js → html-vl9fkHKL.js} +1 -1
  10. package/out/renderer/assets/{htmlMode-BRnCcIzp.js → htmlMode-BtGqkTNI.js} +3 -3
  11. package/out/renderer/assets/{index-Cc-jDHm3.js → index-BhrV6ld-.js} +359 -23
  12. package/out/renderer/assets/{index-BEekQe3-.css → index-BpCORklm.css} +217 -0
  13. package/out/renderer/assets/{javascript-7MdRNHk9.js → javascript-B7CCdfuW.js} +2 -2
  14. package/out/renderer/assets/{jsonMode-oGam2go_.js → jsonMode-ut9LWBMJ.js} +3 -3
  15. package/out/renderer/assets/{liquid-DoKC7ba2.js → liquid-DVDJ0lKt.js} +1 -1
  16. package/out/renderer/assets/{lspLanguageFeatures-C2h5qGCv.js → lspLanguageFeatures-BbMj8Wsc.js} +1 -1
  17. package/out/renderer/assets/{mdx-0w8n1HGo.js → mdx-CcQzYB0J.js} +1 -1
  18. package/out/renderer/assets/{python-BfY4HssB.js → python-Byy7wKMv.js} +1 -1
  19. package/out/renderer/assets/{razor-BoDk9Ula.js → razor-D1xi_wMM.js} +1 -1
  20. package/out/renderer/assets/{tsMode-CX0oVKRt.js → tsMode-DJPzbn5i.js} +1 -1
  21. package/out/renderer/assets/{typescript-BqIU7abP.js → typescript-BuVaU7i3.js} +1 -1
  22. package/out/renderer/assets/{xml-BlSDnxFw.js → xml-rzc91O3d.js} +1 -1
  23. package/out/renderer/assets/{yaml-bVMmGUtU.js → yaml-fAOzQMge.js} +1 -1
  24. package/out/renderer/index.html +2 -2
  25. package/package.json +2 -1
  26. package/src/main/index.ts +36 -2
  27. package/src/main/observer/anthropic.ts +48 -0
  28. package/src/main/observer/budget.ts +79 -0
  29. package/src/main/observer/ledger.ts +61 -0
  30. package/src/main/observer/observer.ts +566 -0
  31. package/src/main/observer/spans.ts +170 -0
  32. package/src/main/observer/store.ts +200 -0
  33. package/src/main/observer/tier0.ts +234 -0
  34. package/src/main/observer/tier1.ts +306 -0
  35. package/src/main/observer/tier2.ts +125 -0
  36. package/src/main/observer/types.ts +224 -0
  37. package/src/main/orchestrator.ts +74 -0
  38. package/src/main/transcripts.ts +18 -0
  39. package/src/preload/index.ts +36 -0
  40. package/src/renderer/App.tsx +22 -0
  41. package/src/renderer/components/ObserverPanel.tsx +289 -0
  42. package/src/renderer/components/SettingsDialog.tsx +104 -0
  43. package/src/renderer/styles.css +217 -0
@@ -76,6 +76,23 @@ const api = {
76
76
  // Speak agent replies (global, Electron-only)
77
77
  getSpeakReplies: () => electron.ipcRenderer.invoke("speak:get"),
78
78
  setSpeakReplies: (enabled) => electron.ipcRenderer.invoke("speak:set", enabled),
79
+ // Observer supervision layer (global). The API key is write-only over IPC:
80
+ // the getter reports only whether one is configured and from where.
81
+ getObserverSettings: () => electron.ipcRenderer.invoke("observer:get"),
82
+ setObserverSettings: (data) => electron.ipcRenderer.invoke("observer:set", data),
83
+ // Observer panel: feed snapshot, live on/off toggle, and push updates.
84
+ getObserverFeed: () => electron.ipcRenderer.invoke("observer:feed"),
85
+ toggleObserver: (enabled) => electron.ipcRenderer.invoke("observer:toggle", enabled),
86
+ onObserverUpdate: (callback) => {
87
+ const listener = (_event, item) => callback(item);
88
+ electron.ipcRenderer.on("observer:update", listener);
89
+ return () => electron.ipcRenderer.removeListener("observer:update", listener);
90
+ },
91
+ onObserverActivity: (callback) => {
92
+ const listener = (_event, reviewing) => callback(reviewing);
93
+ electron.ipcRenderer.on("observer:activity", listener);
94
+ return () => electron.ipcRenderer.removeListener("observer:activity", listener);
95
+ },
79
96
  onAgentMessage: (callback) => {
80
97
  const listener = (_event, text) => callback(text);
81
98
  electron.ipcRenderer.on("agent:message", listener);
@@ -1,6 +1,6 @@
1
- import { c as createWebWorker, l as languages } from "./index-Cc-jDHm3.js";
2
- import { C as CompletionAdapter, H as HoverAdapter, D as DocumentHighlightAdapter, a as DefinitionAdapter, R as ReferenceAdapter, b as DocumentSymbolAdapter, c as RenameAdapter, d as DocumentColorAdapter, F as FoldingRangeAdapter, e as DiagnosticsAdapter, S as SelectionRangeAdapter, f as DocumentFormattingEditProvider, g as DocumentRangeFormattingEditProvider } from "./lspLanguageFeatures-C2h5qGCv.js";
3
- import { h, i, j, t, k } from "./lspLanguageFeatures-C2h5qGCv.js";
1
+ import { c as createWebWorker, l as languages } from "./index-BhrV6ld-.js";
2
+ import { C as CompletionAdapter, H as HoverAdapter, D as DocumentHighlightAdapter, a as DefinitionAdapter, R as ReferenceAdapter, b as DocumentSymbolAdapter, c as RenameAdapter, d as DocumentColorAdapter, F as FoldingRangeAdapter, e as DiagnosticsAdapter, S as SelectionRangeAdapter, f as DocumentFormattingEditProvider, g as DocumentRangeFormattingEditProvider } from "./lspLanguageFeatures-BbMj8Wsc.js";
3
+ import { h, i, j, t, k } from "./lspLanguageFeatures-BbMj8Wsc.js";
4
4
  const STOP_WHEN_IDLE_FOR = 2 * 60 * 1e3;
5
5
  class WorkerManager {
6
6
  constructor(defaults) {
@@ -1,4 +1,4 @@
1
- import { l as languages } from "./index-Cc-jDHm3.js";
1
+ import { l as languages } from "./index-BhrV6ld-.js";
2
2
  const EMPTY_ELEMENTS = [
3
3
  "assign",
4
4
  "flush",
@@ -1,4 +1,4 @@
1
- import { l as languages } from "./index-Cc-jDHm3.js";
1
+ import { l as languages } from "./index-BhrV6ld-.js";
2
2
  const EMPTY_ELEMENTS = [
3
3
  "area",
4
4
  "base",
@@ -1,4 +1,4 @@
1
- import { l as languages } from "./index-Cc-jDHm3.js";
1
+ import { l as languages } from "./index-BhrV6ld-.js";
2
2
  const EMPTY_ELEMENTS = [
3
3
  "area",
4
4
  "base",
@@ -1,6 +1,6 @@
1
- import { c as createWebWorker, l as languages } from "./index-Cc-jDHm3.js";
2
- import { H as HoverAdapter, D as DocumentHighlightAdapter, h as DocumentLinkAdapter, F as FoldingRangeAdapter, b as DocumentSymbolAdapter, S as SelectionRangeAdapter, c as RenameAdapter, f as DocumentFormattingEditProvider, g as DocumentRangeFormattingEditProvider, C as CompletionAdapter } from "./lspLanguageFeatures-C2h5qGCv.js";
3
- import { a, e, d, R, i, j, t, k } from "./lspLanguageFeatures-C2h5qGCv.js";
1
+ import { c as createWebWorker, l as languages } from "./index-BhrV6ld-.js";
2
+ import { H as HoverAdapter, D as DocumentHighlightAdapter, h as DocumentLinkAdapter, F as FoldingRangeAdapter, b as DocumentSymbolAdapter, S as SelectionRangeAdapter, c as RenameAdapter, f as DocumentFormattingEditProvider, g as DocumentRangeFormattingEditProvider, C as CompletionAdapter } from "./lspLanguageFeatures-BbMj8Wsc.js";
3
+ import { a, e, d, R, i, j, t, k } from "./lspLanguageFeatures-BbMj8Wsc.js";
4
4
  const STOP_WHEN_IDLE_FOR = 2 * 60 * 1e3;
5
5
  class WorkerManager {
6
6
  constructor(defaults) {
@@ -1,4 +1,4 @@
1
- const __vite__mapDeps=(i,m=__vite__mapDeps,d=(m.f||(m.f=["./cssMode-CsSLnKZ-.js","./lspLanguageFeatures-C2h5qGCv.js","./htmlMode-BRnCcIzp.js","./jsonMode-oGam2go_.js","./javascript-7MdRNHk9.js","./typescript-BqIU7abP.js"])))=>i.map(i=>d[i]);
1
+ const __vite__mapDeps=(i,m=__vite__mapDeps,d=(m.f||(m.f=["./cssMode-7adWSORr.js","./lspLanguageFeatures-BbMj8Wsc.js","./htmlMode-BtGqkTNI.js","./jsonMode-ut9LWBMJ.js","./javascript-B7CCdfuW.js","./typescript-BuVaU7i3.js"])))=>i.map(i=>d[i]);
2
2
  function getDefaultExportFromCjs(x) {
3
3
  return x && x.__esModule && Object.prototype.hasOwnProperty.call(x, "default") ? x["default"] : x;
4
4
  }
@@ -208167,7 +208167,7 @@ const lessDefaults = new LanguageServiceDefaultsImpl$3(
208167
208167
  modeConfigurationDefault$2
208168
208168
  );
208169
208169
  function getMode$3() {
208170
- return __vitePreload(() => import("./cssMode-CsSLnKZ-.js"), true ? __vite__mapDeps([0,1]) : void 0, import.meta.url);
208170
+ return __vitePreload(() => import("./cssMode-7adWSORr.js"), true ? __vite__mapDeps([0,1]) : void 0, import.meta.url);
208171
208171
  }
208172
208172
  languages.onLanguage("less", () => {
208173
208173
  getMode$3().then((mode2) => mode2.setupMode(lessDefaults));
@@ -208272,7 +208272,7 @@ const razorLanguageService = registerHTMLLanguageService(
208272
208272
  );
208273
208273
  const razorDefaults = razorLanguageService.defaults;
208274
208274
  function getMode$2() {
208275
- return __vitePreload(() => import("./htmlMode-BRnCcIzp.js"), true ? __vite__mapDeps([2,1]) : void 0, import.meta.url);
208275
+ return __vitePreload(() => import("./htmlMode-BtGqkTNI.js"), true ? __vite__mapDeps([2,1]) : void 0, import.meta.url);
208276
208276
  }
208277
208277
  function registerHTMLLanguageService(languageId, options = optionsDefault, modeConfiguration = getConfigurationDefault(languageId)) {
208278
208278
  const defaults = new LanguageServiceDefaultsImpl$2(languageId, options, modeConfiguration);
@@ -208356,7 +208356,7 @@ const jsonDefaults = new LanguageServiceDefaultsImpl$1(
208356
208356
  );
208357
208357
  const getWorker$1 = () => getMode$1().then((mode2) => mode2.getWorker());
208358
208358
  function getMode$1() {
208359
- return __vitePreload(() => import("./jsonMode-oGam2go_.js"), true ? __vite__mapDeps([3,1]) : void 0, import.meta.url);
208359
+ return __vitePreload(() => import("./jsonMode-ut9LWBMJ.js"), true ? __vite__mapDeps([3,1]) : void 0, import.meta.url);
208360
208360
  }
208361
208361
  languages.register({
208362
208362
  id: "json",
@@ -208602,7 +208602,7 @@ const getJavaScriptWorker = () => {
208602
208602
  return getMode().then((mode) => mode.getJavaScriptWorker());
208603
208603
  };
208604
208604
  function getMode() {
208605
- return __vitePreload(() => import("./tsMode-CX0oVKRt.js"), true ? [] : void 0, import.meta.url);
208605
+ return __vitePreload(() => import("./tsMode-DJPzbn5i.js"), true ? [] : void 0, import.meta.url);
208606
208606
  }
208607
208607
  languages.onLanguage("typescript", () => {
208608
208608
  return getMode().then((mode) => mode.setupTypeScript(typescriptDefaults));
@@ -208797,49 +208797,49 @@ registerLanguage({
208797
208797
  extensions: [".ftl", ".ftlh", ".ftlx"],
208798
208798
  aliases: ["FreeMarker2", "Apache FreeMarker2"],
208799
208799
  loader: () => {
208800
- return __vitePreload(() => import("./freemarker2-C1XYRbOq.js"), true ? [] : void 0, import.meta.url).then((m) => m.TagAutoInterpolationDollar);
208800
+ return __vitePreload(() => import("./freemarker2-BkLLWnzk.js"), true ? [] : void 0, import.meta.url).then((m) => m.TagAutoInterpolationDollar);
208801
208801
  }
208802
208802
  });
208803
208803
  registerLanguage({
208804
208804
  id: "freemarker2.tag-angle.interpolation-dollar",
208805
208805
  aliases: ["FreeMarker2 (Angle/Dollar)", "Apache FreeMarker2 (Angle/Dollar)"],
208806
208806
  loader: () => {
208807
- return __vitePreload(() => import("./freemarker2-C1XYRbOq.js"), true ? [] : void 0, import.meta.url).then((m) => m.TagAngleInterpolationDollar);
208807
+ return __vitePreload(() => import("./freemarker2-BkLLWnzk.js"), true ? [] : void 0, import.meta.url).then((m) => m.TagAngleInterpolationDollar);
208808
208808
  }
208809
208809
  });
208810
208810
  registerLanguage({
208811
208811
  id: "freemarker2.tag-bracket.interpolation-dollar",
208812
208812
  aliases: ["FreeMarker2 (Bracket/Dollar)", "Apache FreeMarker2 (Bracket/Dollar)"],
208813
208813
  loader: () => {
208814
- return __vitePreload(() => import("./freemarker2-C1XYRbOq.js"), true ? [] : void 0, import.meta.url).then((m) => m.TagBracketInterpolationDollar);
208814
+ return __vitePreload(() => import("./freemarker2-BkLLWnzk.js"), true ? [] : void 0, import.meta.url).then((m) => m.TagBracketInterpolationDollar);
208815
208815
  }
208816
208816
  });
208817
208817
  registerLanguage({
208818
208818
  id: "freemarker2.tag-angle.interpolation-bracket",
208819
208819
  aliases: ["FreeMarker2 (Angle/Bracket)", "Apache FreeMarker2 (Angle/Bracket)"],
208820
208820
  loader: () => {
208821
- return __vitePreload(() => import("./freemarker2-C1XYRbOq.js"), true ? [] : void 0, import.meta.url).then((m) => m.TagAngleInterpolationBracket);
208821
+ return __vitePreload(() => import("./freemarker2-BkLLWnzk.js"), true ? [] : void 0, import.meta.url).then((m) => m.TagAngleInterpolationBracket);
208822
208822
  }
208823
208823
  });
208824
208824
  registerLanguage({
208825
208825
  id: "freemarker2.tag-bracket.interpolation-bracket",
208826
208826
  aliases: ["FreeMarker2 (Bracket/Bracket)", "Apache FreeMarker2 (Bracket/Bracket)"],
208827
208827
  loader: () => {
208828
- return __vitePreload(() => import("./freemarker2-C1XYRbOq.js"), true ? [] : void 0, import.meta.url).then((m) => m.TagBracketInterpolationBracket);
208828
+ return __vitePreload(() => import("./freemarker2-BkLLWnzk.js"), true ? [] : void 0, import.meta.url).then((m) => m.TagBracketInterpolationBracket);
208829
208829
  }
208830
208830
  });
208831
208831
  registerLanguage({
208832
208832
  id: "freemarker2.tag-auto.interpolation-dollar",
208833
208833
  aliases: ["FreeMarker2 (Auto/Dollar)", "Apache FreeMarker2 (Auto/Dollar)"],
208834
208834
  loader: () => {
208835
- return __vitePreload(() => import("./freemarker2-C1XYRbOq.js"), true ? [] : void 0, import.meta.url).then((m) => m.TagAutoInterpolationDollar);
208835
+ return __vitePreload(() => import("./freemarker2-BkLLWnzk.js"), true ? [] : void 0, import.meta.url).then((m) => m.TagAutoInterpolationDollar);
208836
208836
  }
208837
208837
  });
208838
208838
  registerLanguage({
208839
208839
  id: "freemarker2.tag-auto.interpolation-bracket",
208840
208840
  aliases: ["FreeMarker2 (Auto/Bracket)", "Apache FreeMarker2 (Auto/Bracket)"],
208841
208841
  loader: () => {
208842
- return __vitePreload(() => import("./freemarker2-C1XYRbOq.js"), true ? [] : void 0, import.meta.url).then((m) => m.TagAutoInterpolationBracket);
208842
+ return __vitePreload(() => import("./freemarker2-BkLLWnzk.js"), true ? [] : void 0, import.meta.url).then((m) => m.TagAutoInterpolationBracket);
208843
208843
  }
208844
208844
  });
208845
208845
  registerLanguage({
@@ -208860,7 +208860,7 @@ registerLanguage({
208860
208860
  extensions: [".handlebars", ".hbs"],
208861
208861
  aliases: ["Handlebars", "handlebars", "hbs"],
208862
208862
  mimetypes: ["text/x-handlebars-template"],
208863
- loader: () => __vitePreload(() => import("./handlebars-BSdbbnMW.js"), true ? [] : void 0, import.meta.url)
208863
+ loader: () => __vitePreload(() => import("./handlebars-Cinfm9fZ.js"), true ? [] : void 0, import.meta.url)
208864
208864
  });
208865
208865
  registerLanguage({
208866
208866
  id: "hcl",
@@ -208873,7 +208873,7 @@ registerLanguage({
208873
208873
  extensions: [".html", ".htm", ".shtml", ".xhtml", ".mdoc", ".jsp", ".asp", ".aspx", ".jshtm"],
208874
208874
  aliases: ["HTML", "htm", "html", "xhtml"],
208875
208875
  mimetypes: ["text/html", "text/x-jshtm", "text/template", "text/ng-template"],
208876
- loader: () => __vitePreload(() => import("./html-96igtyOz.js"), true ? [] : void 0, import.meta.url)
208876
+ loader: () => __vitePreload(() => import("./html-vl9fkHKL.js"), true ? [] : void 0, import.meta.url)
208877
208877
  });
208878
208878
  registerLanguage({
208879
208879
  id: "ini",
@@ -208896,7 +208896,7 @@ registerLanguage({
208896
208896
  filenames: ["jakefile"],
208897
208897
  aliases: ["JavaScript", "javascript", "js"],
208898
208898
  mimetypes: ["text/javascript"],
208899
- loader: () => __vitePreload(() => import("./javascript-7MdRNHk9.js"), true ? __vite__mapDeps([4,5]) : void 0, import.meta.url)
208899
+ loader: () => __vitePreload(() => import("./javascript-B7CCdfuW.js"), true ? __vite__mapDeps([4,5]) : void 0, import.meta.url)
208900
208900
  });
208901
208901
  registerLanguage({
208902
208902
  id: "julia",
@@ -208935,7 +208935,7 @@ registerLanguage({
208935
208935
  extensions: [".liquid", ".html.liquid"],
208936
208936
  aliases: ["Liquid", "liquid"],
208937
208937
  mimetypes: ["application/liquid"],
208938
- loader: () => __vitePreload(() => import("./liquid-DoKC7ba2.js"), true ? [] : void 0, import.meta.url)
208938
+ loader: () => __vitePreload(() => import("./liquid-DVDJ0lKt.js"), true ? [] : void 0, import.meta.url)
208939
208939
  });
208940
208940
  registerLanguage({
208941
208941
  id: "m3",
@@ -208953,7 +208953,7 @@ registerLanguage({
208953
208953
  id: "mdx",
208954
208954
  extensions: [".mdx"],
208955
208955
  aliases: ["MDX", "mdx"],
208956
- loader: () => __vitePreload(() => import("./mdx-0w8n1HGo.js"), true ? [] : void 0, import.meta.url)
208956
+ loader: () => __vitePreload(() => import("./mdx-CcQzYB0J.js"), true ? [] : void 0, import.meta.url)
208957
208957
  });
208958
208958
  registerLanguage({
208959
208959
  id: "mips",
@@ -209052,7 +209052,7 @@ registerLanguage({
209052
209052
  extensions: [".py", ".rpy", ".pyw", ".cpy", ".gyp", ".gypi"],
209053
209053
  aliases: ["Python", "py"],
209054
209054
  firstLine: "^#!/.*\\bpython[0-9.-]*\\b",
209055
- loader: () => __vitePreload(() => import("./python-BfY4HssB.js"), true ? [] : void 0, import.meta.url)
209055
+ loader: () => __vitePreload(() => import("./python-Byy7wKMv.js"), true ? [] : void 0, import.meta.url)
209056
209056
  });
209057
209057
  registerLanguage({
209058
209058
  id: "qsharp",
@@ -209071,7 +209071,7 @@ registerLanguage({
209071
209071
  extensions: [".cshtml"],
209072
209072
  aliases: ["Razor", "razor"],
209073
209073
  mimetypes: ["text/x-cshtml"],
209074
- loader: () => __vitePreload(() => import("./razor-BoDk9Ula.js"), true ? [] : void 0, import.meta.url)
209074
+ loader: () => __vitePreload(() => import("./razor-D1xi_wMM.js"), true ? [] : void 0, import.meta.url)
209075
209075
  });
209076
209076
  registerLanguage({
209077
209077
  id: "redis",
@@ -209204,7 +209204,7 @@ registerLanguage({
209204
209204
  aliases: ["TypeScript", "ts", "typescript"],
209205
209205
  mimetypes: ["text/typescript"],
209206
209206
  loader: () => {
209207
- return __vitePreload(() => import("./typescript-BqIU7abP.js"), true ? [] : void 0, import.meta.url);
209207
+ return __vitePreload(() => import("./typescript-BuVaU7i3.js"), true ? [] : void 0, import.meta.url);
209208
209208
  }
209209
209209
  });
209210
209210
  registerLanguage({
@@ -209249,14 +209249,14 @@ registerLanguage({
209249
209249
  firstLine: "(\\<\\?xml.*)|(\\<svg)|(\\<\\!doctype\\s+svg)",
209250
209250
  aliases: ["XML", "xml"],
209251
209251
  mimetypes: ["text/xml", "application/xml", "application/xaml+xml", "application/xml-dtd"],
209252
- loader: () => __vitePreload(() => import("./xml-BlSDnxFw.js"), true ? [] : void 0, import.meta.url)
209252
+ loader: () => __vitePreload(() => import("./xml-rzc91O3d.js"), true ? [] : void 0, import.meta.url)
209253
209253
  });
209254
209254
  registerLanguage({
209255
209255
  id: "yaml",
209256
209256
  extensions: [".yaml", ".yml"],
209257
209257
  aliases: ["YAML", "yaml", "YML", "yml"],
209258
209258
  mimetypes: ["application/x-yaml", "text/x-yaml"],
209259
- loader: () => __vitePreload(() => import("./yaml-bVMmGUtU.js"), true ? [] : void 0, import.meta.url)
209259
+ loader: () => __vitePreload(() => import("./yaml-fAOzQMge.js"), true ? [] : void 0, import.meta.url)
209260
209260
  });
209261
209261
  var __defProp = Object.defineProperty;
209262
209262
  var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
@@ -213549,20 +213549,54 @@ function SettingsDialog({ open, onClose }) {
213549
213549
  const [idleTimeoutMin, setIdleTimeoutMin] = reactExports.useState(15);
213550
213550
  const [saved, setSaved] = reactExports.useState(false);
213551
213551
  const [version, setVersion] = reactExports.useState("");
213552
+ const [obsEnabled, setObsEnabled] = reactExports.useState(false);
213553
+ const [obsApiKey, setObsApiKey] = reactExports.useState("");
213554
+ const [obsHasKey, setObsHasKey] = reactExports.useState(false);
213555
+ const [obsKeySource, setObsKeySource] = reactExports.useState(null);
213556
+ const [obsCapUsd, setObsCapUsd] = reactExports.useState(1);
213557
+ const [obsSaved, setObsSaved] = reactExports.useState(false);
213552
213558
  const loadProfiles = async () => {
213553
213559
  const data = await window.worker.listProfiles();
213554
213560
  setProfileList(data);
213555
213561
  setActiveProfileId(data.activeProfile);
213556
213562
  };
213563
+ const loadObserver = async () => {
213564
+ try {
213565
+ const o = await window.worker.getObserverSettings();
213566
+ setObsEnabled(o.enabled);
213567
+ setObsHasKey(o.hasApiKey);
213568
+ setObsKeySource(o.keySource);
213569
+ setObsCapUsd(o.dailyCapUsd);
213570
+ setObsApiKey("");
213571
+ } catch {
213572
+ }
213573
+ };
213557
213574
  reactExports.useEffect(() => {
213558
213575
  if (open) {
213559
213576
  loadProfiles();
213577
+ loadObserver();
213560
213578
  setEditingId(null);
213561
213579
  setSaved(false);
213580
+ setObsSaved(false);
213562
213581
  window.worker.getVersion().then(setVersion).catch(() => {
213563
213582
  });
213564
213583
  }
213565
213584
  }, [open]);
213585
+ const handleObserverSave = async () => {
213586
+ const data = {
213587
+ enabled: obsEnabled,
213588
+ dailyCapUsd: Math.max(0.05, obsCapUsd) || 1
213589
+ };
213590
+ if (obsApiKey.trim()) {
213591
+ data.anthropicApiKey = obsApiKey.trim();
213592
+ }
213593
+ const o = await window.worker.setObserverSettings(data);
213594
+ setObsHasKey(o.hasApiKey);
213595
+ setObsKeySource(o.keySource);
213596
+ setObsApiKey("");
213597
+ setObsSaved(true);
213598
+ setTimeout(() => setObsSaved(false), 900);
213599
+ };
213566
213600
  const startEditing = (profile) => {
213567
213601
  setEditingId(profile.id);
213568
213602
  setName(profile.name);
@@ -213732,6 +213766,51 @@ function SettingsDialog({ open, onClose }) {
213732
213766
  ] })
213733
213767
  ] })
213734
213768
  ),
213769
+ !editingId && // ─── Observer (global) ─────────────────
213770
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "settings-section", children: [
213771
+ /* @__PURE__ */ jsxRuntimeExports.jsx("h4", { children: "Observer" }),
213772
+ /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "settings-hint", children: "Reviews agent sessions for assumptions, unverified claims, and dependency/license risk, tracks time per work item, and posts a session digest to the project's Agent Datastore page." }),
213773
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("label", { className: "settings-checkbox", children: [
213774
+ /* @__PURE__ */ jsxRuntimeExports.jsx(
213775
+ "input",
213776
+ {
213777
+ type: "checkbox",
213778
+ checked: obsEnabled,
213779
+ onChange: (e) => setObsEnabled(e.target.checked)
213780
+ }
213781
+ ),
213782
+ /* @__PURE__ */ jsxRuntimeExports.jsx("span", { children: "Enable Observer" }),
213783
+ /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "settings-hint", children: "Applies to newly started agent tabs. Advisory only — never blocks or slows the agent." })
213784
+ ] }),
213785
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("label", { children: [
213786
+ "Anthropic API Key",
213787
+ /* @__PURE__ */ jsxRuntimeExports.jsx(
213788
+ "input",
213789
+ {
213790
+ type: "password",
213791
+ value: obsApiKey,
213792
+ onChange: (e) => setObsApiKey(e.target.value),
213793
+ placeholder: obsKeySource === "settings" ? "***configured*** (leave blank to keep)" : obsKeySource === "env" ? "using ANTHROPIC_API_KEY from environment" : "sk-ant-…"
213794
+ }
213795
+ ),
213796
+ /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "settings-hint", children: "Your own Anthropic key — separate from the ctlsurf profile key. Without one, the Observer still records the session ledger, Tier-0 tags, and spans, but skips model review and digests." })
213797
+ ] }),
213798
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("label", { children: [
213799
+ "Daily budget cap (USD)",
213800
+ /* @__PURE__ */ jsxRuntimeExports.jsx(
213801
+ "input",
213802
+ {
213803
+ type: "number",
213804
+ min: 0.05,
213805
+ step: 0.25,
213806
+ value: obsCapUsd,
213807
+ onChange: (e) => setObsCapUsd(parseFloat(e.target.value) || 1)
213808
+ }
213809
+ ),
213810
+ /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "settings-hint", children: "Model review pauses for the day once spend reaches the cap; Tier-0 tagging and spans continue." })
213811
+ ] }),
213812
+ /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "settings-actions", children: /* @__PURE__ */ jsxRuntimeExports.jsx("button", { className: "btn-primary", onClick: handleObserverSave, children: obsSaved ? "Saved!" : "Save Observer Settings" }) })
213813
+ ] }),
213735
213814
  /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "settings-section settings-about", children: [
213736
213815
  /* @__PURE__ */ jsxRuntimeExports.jsx("h4", { children: "About" }),
213737
213816
  /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "about-name", children: [
@@ -214086,6 +214165,232 @@ function TicketPane({ onSendToTerminal }) {
214086
214165
  ] })
214087
214166
  ] });
214088
214167
  }
214168
+ const SENSITIVITY_LEVELS = [
214169
+ { value: "severe", label: "Severe", hint: "Only high/critical findings — near silence" },
214170
+ { value: "balanced", label: "Balanced", hint: "Warn and above — clear signals only" },
214171
+ { value: "all", label: "All signals", hint: "Everything, including low-confidence observations" }
214172
+ ];
214173
+ const SEVERITY_COLORS = {
214174
+ info: "#7aa2f7",
214175
+ warn: "#e0af68",
214176
+ high: "#ff9e64",
214177
+ critical: "#f7768e"
214178
+ };
214179
+ const DIGEST_COLOR = "#bb9af7";
214180
+ function EyeIcon({ size: size2 = 16 }) {
214181
+ return /* @__PURE__ */ jsxRuntimeExports.jsxs(
214182
+ "svg",
214183
+ {
214184
+ viewBox: "0 0 24 24",
214185
+ width: size2,
214186
+ height: size2,
214187
+ fill: "none",
214188
+ stroke: "currentColor",
214189
+ strokeWidth: "2",
214190
+ strokeLinecap: "round",
214191
+ strokeLinejoin: "round",
214192
+ "aria-hidden": "true",
214193
+ children: [
214194
+ /* @__PURE__ */ jsxRuntimeExports.jsx("path", { d: "M1 12s4-8 11-8 11 8 11 8-4 8-11 8-11-8-11-8z" }),
214195
+ /* @__PURE__ */ jsxRuntimeExports.jsx("circle", { cx: "12", cy: "12", r: "3" })
214196
+ ]
214197
+ }
214198
+ );
214199
+ }
214200
+ function formatTime(iso) {
214201
+ const d = new Date(iso);
214202
+ if (Number.isNaN(d.getTime())) return "";
214203
+ return d.toLocaleTimeString("en-US", { hour: "numeric", minute: "2-digit" });
214204
+ }
214205
+ function Chip({ color, label }) {
214206
+ return /* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: "obs-chip", style: { color, borderColor: `${color}55`, background: `${color}14` }, children: [
214207
+ /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "obs-chip-dot", style: { background: color } }),
214208
+ label
214209
+ ] });
214210
+ }
214211
+ function FindingCard({ item }) {
214212
+ const [expanded2, setExpanded] = reactExports.useState(false);
214213
+ const color = SEVERITY_COLORS[item.severity || "info"] || SEVERITY_COLORS.info;
214214
+ return /* @__PURE__ */ jsxRuntimeExports.jsxs(
214215
+ "button",
214216
+ {
214217
+ type: "button",
214218
+ className: "obs-card",
214219
+ style: { borderLeftColor: color },
214220
+ onClick: () => setExpanded((v2) => !v2),
214221
+ "aria-expanded": expanded2,
214222
+ children: [
214223
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "obs-card-top", children: [
214224
+ /* @__PURE__ */ jsxRuntimeExports.jsx(Chip, { color, label: item.severity || "info" }),
214225
+ /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "obs-card-cat", children: (item.category || "").replace(/_/g, " ") }),
214226
+ /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "obs-card-time", children: formatTime(item.ts) })
214227
+ ] }),
214228
+ /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "obs-card-title", children: item.title }),
214229
+ expanded2 && /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "obs-card-body", children: [
214230
+ item.detail && /* @__PURE__ */ jsxRuntimeExports.jsx("p", { children: item.detail }),
214231
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "obs-card-facts", children: [
214232
+ typeof item.confidence === "number" && /* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: "obs-fact", children: [
214233
+ Math.round(item.confidence * 100),
214234
+ "% confidence"
214235
+ ] }),
214236
+ typeof item.tier === "number" && /* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: "obs-fact", children: [
214237
+ "tier ",
214238
+ item.tier
214239
+ ] }),
214240
+ item.receipts && item.receipts.length > 0 && /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "obs-fact", children: item.receipts.join(" · ") })
214241
+ ] })
214242
+ ] }),
214243
+ /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: `obs-card-caret ${expanded2 ? "open" : ""}`, "aria-hidden": "true", children: "▸" })
214244
+ ]
214245
+ }
214246
+ );
214247
+ }
214248
+ function DigestCard({ item }) {
214249
+ const [expanded2, setExpanded] = reactExports.useState(true);
214250
+ return /* @__PURE__ */ jsxRuntimeExports.jsxs(
214251
+ "button",
214252
+ {
214253
+ type: "button",
214254
+ className: "obs-card",
214255
+ style: { borderLeftColor: DIGEST_COLOR },
214256
+ onClick: () => setExpanded((v2) => !v2),
214257
+ "aria-expanded": expanded2,
214258
+ children: [
214259
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "obs-card-top", children: [
214260
+ /* @__PURE__ */ jsxRuntimeExports.jsx(Chip, { color: DIGEST_COLOR, label: "digest" }),
214261
+ /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "obs-card-time", children: formatTime(item.ts) })
214262
+ ] }),
214263
+ /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "obs-card-title", children: item.title }),
214264
+ expanded2 && item.detail && /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "obs-card-body", children: /* @__PURE__ */ jsxRuntimeExports.jsx("p", { children: item.detail }) }),
214265
+ /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: `obs-card-caret ${expanded2 ? "open" : ""}`, "aria-hidden": "true", children: "▸" })
214266
+ ]
214267
+ }
214268
+ );
214269
+ }
214270
+ function ObserverPane() {
214271
+ const [snapshot, setSnapshot] = reactExports.useState(null);
214272
+ const [toggling, setToggling] = reactExports.useState(false);
214273
+ const [reviewing, setReviewing] = reactExports.useState(false);
214274
+ const refresh = reactExports.useCallback(async () => {
214275
+ try {
214276
+ const s = await window.worker.getObserverFeed();
214277
+ setSnapshot(s);
214278
+ setReviewing(s.reviewing);
214279
+ } catch {
214280
+ }
214281
+ }, []);
214282
+ reactExports.useEffect(() => {
214283
+ void refresh();
214284
+ const unsub = window.worker.onObserverUpdate((item) => {
214285
+ setSnapshot((prev) => prev ? { ...prev, items: [...prev.items.filter((i2) => i2.id !== item.id), item].slice(-200) } : prev);
214286
+ });
214287
+ const unsubActivity = window.worker.onObserverActivity(setReviewing);
214288
+ const unsubCwd = window.worker.onCwdChanged(() => void refresh());
214289
+ return () => {
214290
+ unsub();
214291
+ unsubActivity();
214292
+ unsubCwd();
214293
+ };
214294
+ }, [refresh]);
214295
+ const handleToggle = reactExports.useCallback(async (enabled2) => {
214296
+ if (toggling) return;
214297
+ setToggling(true);
214298
+ try {
214299
+ const s = await window.worker.toggleObserver(enabled2);
214300
+ setSnapshot(s);
214301
+ } finally {
214302
+ setToggling(false);
214303
+ }
214304
+ }, [toggling]);
214305
+ const handleSensitivity = reactExports.useCallback(async (level) => {
214306
+ const current = snapshot;
214307
+ if (!current || current.sensitivity === level) return;
214308
+ setSnapshot({ ...current, sensitivity: level });
214309
+ try {
214310
+ await window.worker.setObserverSettings({ enabled: current.enabled, sensitivity: level });
214311
+ } catch {
214312
+ void refresh();
214313
+ }
214314
+ }, [snapshot, refresh]);
214315
+ const enabled = snapshot?.enabled ?? false;
214316
+ const items = [...snapshot?.items || []].reverse();
214317
+ const findings = items.filter((i2) => i2.kind === "finding");
214318
+ return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "ticket-pane observer-pane", role: "region", "aria-label": "Observer", children: [
214319
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "ticket-drawer-header", children: [
214320
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "ticket-drawer-heading", children: [
214321
+ /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: `ticket-drawer-badge obs-badge ${reviewing && enabled ? "reviewing" : ""}`, children: /* @__PURE__ */ jsxRuntimeExports.jsx(EyeIcon, { size: 16 }) }),
214322
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "ticket-drawer-headtext", children: [
214323
+ /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "ticket-drawer-title", children: "Observer" }),
214324
+ /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "ticket-drawer-subtitle", children: !snapshot ? "loading…" : !enabled ? "off" : !snapshot.hasApiKey ? /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "ticket-drawer-warn", children: "no Anthropic API key — Tier 0 only (add in Settings)" }) : snapshot.observing.length === 0 ? "on — waiting for an agent tab" : /* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [
214325
+ "watching ",
214326
+ /* @__PURE__ */ jsxRuntimeExports.jsx("strong", { children: snapshot.observing.map((o) => o.agentName).join(", ") })
214327
+ ] }) })
214328
+ ] })
214329
+ ] }),
214330
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("label", { className: "observer-switch", title: enabled ? "Turn Observer off" : "Turn Observer on", children: [
214331
+ /* @__PURE__ */ jsxRuntimeExports.jsx(
214332
+ "input",
214333
+ {
214334
+ type: "checkbox",
214335
+ checked: enabled,
214336
+ disabled: toggling || !snapshot,
214337
+ onChange: (e) => void handleToggle(e.target.checked)
214338
+ }
214339
+ ),
214340
+ /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "observer-switch-track", children: /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "observer-switch-thumb" }) })
214341
+ ] })
214342
+ ] }),
214343
+ enabled && snapshot && /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "obs-toolbar", children: [
214344
+ /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "obs-sensitivity", role: "radiogroup", "aria-label": "Detection threshold", children: SENSITIVITY_LEVELS.map((l2) => /* @__PURE__ */ jsxRuntimeExports.jsx(
214345
+ "button",
214346
+ {
214347
+ type: "button",
214348
+ className: `obs-sens-btn ${snapshot.sensitivity === l2.value ? "active" : ""}`,
214349
+ title: l2.hint,
214350
+ "aria-pressed": snapshot.sensitivity === l2.value,
214351
+ onClick: () => void handleSensitivity(l2.value),
214352
+ children: l2.label
214353
+ },
214354
+ l2.value
214355
+ )) }),
214356
+ reviewing && /* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: "obs-reviewing", "aria-live": "polite", children: [
214357
+ /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "obs-reviewing-dot" }),
214358
+ /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "obs-reviewing-dot" }),
214359
+ /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "obs-reviewing-dot" }),
214360
+ "reviewing"
214361
+ ] })
214362
+ ] }),
214363
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "ticket-list-body obs-feed", children: [
214364
+ !enabled && /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "ticket-empty", children: [
214365
+ /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "ticket-empty-icon", children: /* @__PURE__ */ jsxRuntimeExports.jsx(EyeIcon, { size: 26 }) }),
214366
+ /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "ticket-empty-title", children: "Observer is off" }),
214367
+ /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "ticket-empty-hint", children: "Flip the switch to review this session for assumptions, unverified claims, and dependency/license risk each time the agent hands control back to you." })
214368
+ ] }),
214369
+ enabled && items.length === 0 && /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "ticket-empty", children: [
214370
+ /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "ticket-empty-icon", children: /* @__PURE__ */ jsxRuntimeExports.jsx(EyeIcon, { size: 26 }) }),
214371
+ /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "ticket-empty-title", children: "Nothing yet" }),
214372
+ /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "ticket-empty-hint", children: "Reviews run when the agent finishes a turn. Results land here." })
214373
+ ] }),
214374
+ enabled && items.map((item) => {
214375
+ if (item.kind === "finding") return /* @__PURE__ */ jsxRuntimeExports.jsx(FindingCard, { item }, item.id);
214376
+ if (item.kind === "digest") return /* @__PURE__ */ jsxRuntimeExports.jsx(DigestCard, { item }, item.id);
214377
+ return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: `obs-line ${item.kind}`, children: [
214378
+ /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "obs-line-dot", "aria-hidden": "true" }),
214379
+ /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "obs-line-text", children: item.title }),
214380
+ /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "obs-line-time", children: formatTime(item.ts) })
214381
+ ] }, item.id);
214382
+ })
214383
+ ] }),
214384
+ snapshot && enabled && /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "ticket-drawer-footer", children: /* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: "ticket-drawer-hint", children: [
214385
+ findings.length,
214386
+ " finding",
214387
+ findings.length === 1 ? "" : "s",
214388
+ " · $",
214389
+ snapshot.spentTodayUsd.toFixed(2),
214390
+ " spent today"
214391
+ ] }) })
214392
+ ] });
214393
+ }
214089
214394
  const DEFAULT_LAYOUT = {
214090
214395
  type: "split",
214091
214396
  direction: "horizontal",
@@ -214438,7 +214743,8 @@ function App() {
214438
214743
  ] })
214439
214744
  },
214440
214745
  { id: "ctlsurf", label: "ctlsurf", content: /* @__PURE__ */ jsxRuntimeExports.jsx(CtlsurfPanel, { navigate: ctlsurfNav }) },
214441
- { id: "tickets", label: "Tickets", content: /* @__PURE__ */ jsxRuntimeExports.jsx(TicketPane, { onSendToTerminal: handleSendToTerminal }) }
214746
+ { id: "tickets", label: "Tickets", content: /* @__PURE__ */ jsxRuntimeExports.jsx(TicketPane, { onSendToTerminal: handleSendToTerminal }) },
214747
+ { id: "observer", label: "Observer", content: /* @__PURE__ */ jsxRuntimeExports.jsx(ObserverPane, {}) }
214442
214748
  ];
214443
214749
  return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "app", children: [
214444
214750
  /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "titlebar", children: [
@@ -214495,6 +214801,36 @@ function App() {
214495
214801
  ]
214496
214802
  }
214497
214803
  ),
214804
+ /* @__PURE__ */ jsxRuntimeExports.jsxs(
214805
+ "button",
214806
+ {
214807
+ className: `titlebar-btn titlebar-icon-btn ${visiblePaneIds.includes("observer") ? "active" : ""}`,
214808
+ onClick: () => togglePane("observer"),
214809
+ title: "Toggle Observer pane — live session review",
214810
+ "aria-label": "Observer",
214811
+ children: [
214812
+ /* @__PURE__ */ jsxRuntimeExports.jsxs(
214813
+ "svg",
214814
+ {
214815
+ viewBox: "0 0 24 24",
214816
+ width: "13",
214817
+ height: "13",
214818
+ fill: "none",
214819
+ stroke: "currentColor",
214820
+ strokeWidth: "2",
214821
+ strokeLinecap: "round",
214822
+ strokeLinejoin: "round",
214823
+ "aria-hidden": "true",
214824
+ children: [
214825
+ /* @__PURE__ */ jsxRuntimeExports.jsx("path", { d: "M1 12s4-8 11-8 11 8 11 8-4 8-11 8-11-8-11-8z" }),
214826
+ /* @__PURE__ */ jsxRuntimeExports.jsx("circle", { cx: "12", cy: "12", r: "3" })
214827
+ ]
214828
+ }
214829
+ ),
214830
+ /* @__PURE__ */ jsxRuntimeExports.jsx("span", { children: "Observer" })
214831
+ ]
214832
+ }
214833
+ ),
214498
214834
  /* @__PURE__ */ jsxRuntimeExports.jsx(
214499
214835
  "button",
214500
214836
  {