@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.
- package/out/headless/index.mjs +13663 -385
- package/out/headless/index.mjs.map +4 -4
- package/out/main/index.js +11665 -286
- package/out/main/node-CUnQxFha.js +868 -0
- package/out/preload/index.js +17 -0
- package/out/renderer/assets/{cssMode-CsSLnKZ-.js → cssMode-7adWSORr.js} +3 -3
- package/out/renderer/assets/{freemarker2-C1XYRbOq.js → freemarker2-BkLLWnzk.js} +1 -1
- package/out/renderer/assets/{handlebars-BSdbbnMW.js → handlebars-Cinfm9fZ.js} +1 -1
- package/out/renderer/assets/{html-96igtyOz.js → html-vl9fkHKL.js} +1 -1
- package/out/renderer/assets/{htmlMode-BRnCcIzp.js → htmlMode-BtGqkTNI.js} +3 -3
- package/out/renderer/assets/{index-Cc-jDHm3.js → index-BhrV6ld-.js} +359 -23
- package/out/renderer/assets/{index-BEekQe3-.css → index-BpCORklm.css} +217 -0
- package/out/renderer/assets/{javascript-7MdRNHk9.js → javascript-B7CCdfuW.js} +2 -2
- package/out/renderer/assets/{jsonMode-oGam2go_.js → jsonMode-ut9LWBMJ.js} +3 -3
- package/out/renderer/assets/{liquid-DoKC7ba2.js → liquid-DVDJ0lKt.js} +1 -1
- package/out/renderer/assets/{lspLanguageFeatures-C2h5qGCv.js → lspLanguageFeatures-BbMj8Wsc.js} +1 -1
- package/out/renderer/assets/{mdx-0w8n1HGo.js → mdx-CcQzYB0J.js} +1 -1
- package/out/renderer/assets/{python-BfY4HssB.js → python-Byy7wKMv.js} +1 -1
- package/out/renderer/assets/{razor-BoDk9Ula.js → razor-D1xi_wMM.js} +1 -1
- package/out/renderer/assets/{tsMode-CX0oVKRt.js → tsMode-DJPzbn5i.js} +1 -1
- package/out/renderer/assets/{typescript-BqIU7abP.js → typescript-BuVaU7i3.js} +1 -1
- package/out/renderer/assets/{xml-BlSDnxFw.js → xml-rzc91O3d.js} +1 -1
- package/out/renderer/assets/{yaml-bVMmGUtU.js → yaml-fAOzQMge.js} +1 -1
- package/out/renderer/index.html +2 -2
- package/package.json +2 -1
- package/src/main/index.ts +36 -2
- package/src/main/observer/anthropic.ts +48 -0
- package/src/main/observer/budget.ts +79 -0
- package/src/main/observer/ledger.ts +61 -0
- package/src/main/observer/observer.ts +566 -0
- package/src/main/observer/spans.ts +170 -0
- package/src/main/observer/store.ts +200 -0
- package/src/main/observer/tier0.ts +234 -0
- package/src/main/observer/tier1.ts +306 -0
- package/src/main/observer/tier2.ts +125 -0
- package/src/main/observer/types.ts +224 -0
- package/src/main/orchestrator.ts +74 -0
- package/src/main/transcripts.ts +18 -0
- package/src/preload/index.ts +36 -0
- package/src/renderer/App.tsx +22 -0
- package/src/renderer/components/ObserverPanel.tsx +289 -0
- package/src/renderer/components/SettingsDialog.tsx +104 -0
- package/src/renderer/styles.css +217 -0
package/out/preload/index.js
CHANGED
|
@@ -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-
|
|
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-
|
|
3
|
-
import { h, i, j, t, k } from "./lspLanguageFeatures-
|
|
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,6 +1,6 @@
|
|
|
1
|
-
import { c as createWebWorker, l as languages } from "./index-
|
|
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-
|
|
3
|
-
import { a, e, d, R, i, j, t, k } from "./lspLanguageFeatures-
|
|
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-
|
|
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-
|
|
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-
|
|
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-
|
|
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-
|
|
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-
|
|
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-
|
|
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-
|
|
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-
|
|
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-
|
|
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-
|
|
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-
|
|
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-
|
|
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-
|
|
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-
|
|
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-
|
|
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-
|
|
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-
|
|
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-
|
|
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-
|
|
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-
|
|
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-
|
|
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
|
{
|