@64mb/freelens-power 2.1.0 → 2.2.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/README.md +4 -4
- package/out/main/common/power-logs.js.map +1 -1
- package/out/main/common/resource-search.js.map +1 -1
- package/out/main/power-logs-child.js +3 -3
- package/out/main/power-logs-child.js.map +1 -1
- package/out/main/power-logs-database.js +165 -7
- package/out/main/power-logs-database.js.map +1 -1
- package/out/main/power-logs-ipc.js +12 -3
- package/out/main/power-logs-ipc.js.map +1 -1
- package/out/main/power-logs-worker.js +29 -7
- package/out/main/power-logs-worker.js.map +1 -1
- package/out/main/resource-search-database.js +3 -2
- package/out/main/resource-search-database.js.map +1 -1
- package/out/main/resource-search.js +2 -1
- package/out/main/resource-search.js.map +1 -1
- package/out/renderer/_virtual/_global-external_react.js +2 -1
- package/out/renderer/ai-context-mutations.js +14 -0
- package/out/renderer/ai-context-mutations.js.map +1 -0
- package/out/renderer/ai-copy-answer.js +18 -15
- package/out/renderer/ai-copy-answer.js.map +1 -1
- package/out/renderer/ai-diagnostic-handoff.js +2 -2
- package/out/renderer/ai-diagnostic-handoff.js.map +1 -1
- package/out/renderer/ai-extras.js +41 -38
- package/out/renderer/ai-extras.js.map +1 -1
- package/out/renderer/ai-message.js +50 -39
- package/out/renderer/ai-message.js.map +1 -1
- package/out/renderer/ai-provider-icon.js +39 -32
- package/out/renderer/ai-provider-icon.js.map +1 -1
- package/out/renderer/ai-resize.js +40 -37
- package/out/renderer/ai-resize.js.map +1 -1
- package/out/renderer/ai-shortcuts.js +20 -17
- package/out/renderer/ai-shortcuts.js.map +1 -1
- package/out/renderer/ai-terminal-context.js +42 -48
- package/out/renderer/ai-terminal-context.js.map +1 -1
- package/out/renderer/ai.js +137 -111
- package/out/renderer/ai.js.map +1 -1
- package/out/renderer/cluster-icon-colors.js +10 -7
- package/out/renderer/cluster-icon-colors.js.map +1 -1
- package/out/renderer/cluster-icons.js +47 -40
- package/out/renderer/cluster-icons.js.map +1 -1
- package/out/renderer/details/service-diagnostics-details.js +25 -23
- package/out/renderer/details/service-diagnostics-details.js.map +1 -1
- package/out/renderer/diagnostic-explain-button.js +7 -4
- package/out/renderer/diagnostic-explain-button.js.map +1 -1
- package/out/renderer/diagnostics-screen-finding.js +51 -0
- package/out/renderer/diagnostics-screen-finding.js.map +1 -0
- package/out/renderer/diagnostics.css.js +1 -1
- package/out/renderer/diagnostics.css.js.map +1 -1
- package/out/renderer/diagnostics.js +146 -107
- package/out/renderer/diagnostics.js.map +1 -1
- package/out/renderer/incident-copy-button.js +24 -21
- package/out/renderer/incident-copy-button.js.map +1 -1
- package/out/renderer/index.js +2 -0
- package/out/renderer/index.js.map +1 -1
- package/out/renderer/monitoring.js +19 -22
- package/out/renderer/monitoring.js.map +1 -1
- package/out/renderer/native-tooltip.js +22 -0
- package/out/renderer/native-tooltip.js.map +1 -0
- package/out/renderer/pod-details-enhancements.js +106 -0
- package/out/renderer/pod-details-enhancements.js.map +1 -0
- package/out/renderer/power-log-json-cell.js +44 -38
- package/out/renderer/power-log-json-cell.js.map +1 -1
- package/out/renderer/power-log-json.js +17 -10
- package/out/renderer/power-log-json.js.map +1 -1
- package/out/renderer/power-log-sql-editor.js +31 -2
- package/out/renderer/power-log-sql-editor.js.map +1 -1
- package/out/renderer/power-logs-client.js +5 -0
- package/out/renderer/power-logs-client.js.map +1 -1
- package/out/renderer/power-logs-entrypoints.js +10 -36
- package/out/renderer/power-logs-entrypoints.js.map +1 -1
- package/out/renderer/power-logs.css.js +9 -2
- package/out/renderer/power-logs.css.js.map +1 -1
- package/out/renderer/power-logs.js +376 -214
- package/out/renderer/power-logs.js.map +1 -1
- package/out/renderer/preferences/dashboard-preferences.js +42 -35
- package/out/renderer/preferences/dashboard-preferences.js.map +1 -1
- package/out/renderer/preferences/logs-preferences.js +1 -1
- package/out/renderer/preferences/logs-preferences.js.map +1 -1
- package/out/renderer/preferences/monitoring-preferences.js +7 -4
- package/out/renderer/preferences/monitoring-preferences.js.map +1 -1
- package/out/renderer/preferences/preferences.js +2 -2
- package/out/renderer/preferences/preferences.js.map +1 -1
- package/out/renderer/preferences/settings-icon-action.js +12 -11
- package/out/renderer/preferences/settings-icon-action.js.map +1 -1
- package/out/renderer/relationship-map-finding.js +53 -0
- package/out/renderer/relationship-map-finding.js.map +1 -0
- package/out/renderer/resource-relationships.css.js +6 -0
- package/out/renderer/resource-relationships.css.js.map +1 -1
- package/out/renderer/resource-relationships.js +94 -47
- package/out/renderer/resource-relationships.js.map +1 -1
- package/out/renderer/resource-search-client.js.map +1 -1
- package/out/renderer/resource-search.js +88 -35
- package/out/renderer/resource-search.js.map +1 -1
- package/out/renderer/src/common/gateway-relationships.js +8 -7
- package/out/renderer/src/common/gateway-relationships.js.map +1 -1
- package/out/renderer/src/common/power-log-json-filter-sql.js +12 -0
- package/out/renderer/src/common/power-log-json-filter-sql.js.map +1 -1
- package/out/renderer/src/common/power-log-json-preset.js +2 -2
- package/out/renderer/src/common/power-log-json-preset.js.map +1 -1
- package/out/renderer/src/common/power-logs.js.map +1 -1
- package/out/renderer/src/common/resource-relationships.js +10 -8
- package/out/renderer/src/common/resource-relationships.js.map +1 -1
- package/out/renderer/src/common/resource-search.js.map +1 -1
- package/out/renderer/welcome.js +16 -1
- package/out/renderer/welcome.js.map +1 -1
- package/package.json +1 -1
|
@@ -2,6 +2,7 @@ const require__global_external_mobx_react = require("./_virtual/_global-external
|
|
|
2
2
|
const require_ai_shortcuts_store = require("./src/common/store/ai-shortcuts-store.js");
|
|
3
3
|
const require_jsx_runtime = require("./_virtual/_global-external_react/jsx-runtime.js");
|
|
4
4
|
const require_ai_icon = require("./ai-icon.js");
|
|
5
|
+
const require_native_tooltip = require("./native-tooltip.js");
|
|
5
6
|
//#region src/renderer/ai-shortcuts.tsx
|
|
6
7
|
var AiStarterPrompts = require__global_external_mobx_react.observer(({ onSelect, disabled = false }) => {
|
|
7
8
|
return /* @__PURE__ */ require_jsx_runtime.jsx("div", {
|
|
@@ -11,24 +12,26 @@ var AiStarterPrompts = require__global_external_mobx_react.observer(({ onSelect,
|
|
|
11
12
|
alignItems: "flex-start",
|
|
12
13
|
gap: 10
|
|
13
14
|
},
|
|
14
|
-
children: require_ai_shortcuts_store.AiShortcutsStore.getInstanceOrCreate().shortcuts.map((shortcut) => /* @__PURE__ */ require_jsx_runtime.
|
|
15
|
-
type: "button",
|
|
16
|
-
className: "Button",
|
|
17
|
-
style: {
|
|
18
|
-
display: "inline-flex",
|
|
19
|
-
alignItems: "center",
|
|
20
|
-
gap: 10,
|
|
21
|
-
padding: "6px 10px",
|
|
22
|
-
minHeight: 32
|
|
23
|
-
},
|
|
24
|
-
disabled,
|
|
15
|
+
children: require_ai_shortcuts_store.AiShortcutsStore.getInstanceOrCreate().shortcuts.map((shortcut) => /* @__PURE__ */ require_jsx_runtime.jsx(require_native_tooltip.NativeTooltip, {
|
|
25
16
|
title: `Insert /${shortcut.command}: ${shortcut.label}`,
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
17
|
+
children: /* @__PURE__ */ require_jsx_runtime.jsxs("button", {
|
|
18
|
+
type: "button",
|
|
19
|
+
className: "Button",
|
|
20
|
+
style: {
|
|
21
|
+
display: "inline-flex",
|
|
22
|
+
alignItems: "center",
|
|
23
|
+
gap: 10,
|
|
24
|
+
padding: "6px 10px",
|
|
25
|
+
minHeight: 32
|
|
26
|
+
},
|
|
27
|
+
disabled,
|
|
28
|
+
onClick: () => onSelect(shortcut.prompt),
|
|
29
|
+
children: [/* @__PURE__ */ require_jsx_runtime.jsx(require_ai_icon.AiIcon, { material: {
|
|
30
|
+
health: "favorite_border",
|
|
31
|
+
pods: "view_module",
|
|
32
|
+
logs: "subject"
|
|
33
|
+
}[shortcut.command] ?? "chat_bubble_outline" }), shortcut.label]
|
|
34
|
+
})
|
|
32
35
|
}, shortcut.id))
|
|
33
36
|
});
|
|
34
37
|
});
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ai-shortcuts.js","names":[],"sources":["../../src/renderer/ai-shortcuts.tsx"],"sourcesContent":["import { observer } from \"mobx-react\";\nimport { AiShortcutsStore } from \"../common/store/ai-shortcuts-store\";\nimport { AiIcon } from \"./ai-icon\";\n\nexport const AiStarterPrompts = observer(\n ({ onSelect, disabled = false }: { onSelect: (prompt: string) => void; disabled?: boolean }) => {\n const preferences = AiShortcutsStore.getInstanceOrCreate<AiShortcutsStore>();\n return (\n <div style={{ display: \"flex\", flexDirection: \"column\", alignItems: \"flex-start\", gap: 10 }}>\n {preferences.shortcuts.map((shortcut) => (\n <button\n
|
|
1
|
+
{"version":3,"file":"ai-shortcuts.js","names":[],"sources":["../../src/renderer/ai-shortcuts.tsx"],"sourcesContent":["import { observer } from \"mobx-react\";\nimport { AiShortcutsStore } from \"../common/store/ai-shortcuts-store\";\nimport { AiIcon } from \"./ai-icon\";\nimport { NativeTooltip } from \"./native-tooltip\";\n\nexport const AiStarterPrompts = observer(\n ({ onSelect, disabled = false }: { onSelect: (prompt: string) => void; disabled?: boolean }) => {\n const preferences = AiShortcutsStore.getInstanceOrCreate<AiShortcutsStore>();\n return (\n <div style={{ display: \"flex\", flexDirection: \"column\", alignItems: \"flex-start\", gap: 10 }}>\n {preferences.shortcuts.map((shortcut) => (\n <NativeTooltip key={shortcut.id} title={`Insert /${shortcut.command}: ${shortcut.label}`}>\n <button\n type=\"button\"\n className=\"Button\"\n style={{ display: \"inline-flex\", alignItems: \"center\", gap: 10, padding: \"6px 10px\", minHeight: 32 }}\n disabled={disabled}\n onClick={() => onSelect(shortcut.prompt)}\n >\n <AiIcon\n material={\n ({ health: \"favorite_border\", pods: \"view_module\", logs: \"subject\" } as Record<string, string>)[\n shortcut.command\n ] ?? \"chat_bubble_outline\"\n }\n />\n {shortcut.label}\n </button>\n </NativeTooltip>\n ))}\n </div>\n );\n },\n);\n"],"mappings":";;;;;;AAKA,IAAa,mBAAmB,oCAAA,UAC7B,EAAE,UAAU,WAAW,YAAwE;CAE9F,OACE,oCAAA,IAAC,OAAD;EAAK,OAAO;GAAE,SAAS;GAAQ,eAAe;GAAU,YAAY;GAAc,KAAK;EAAG;YAFxE,2BAAA,iBAAiB,oBAGhC,CAAA,CAAY,UAAU,KAAK,aAC1B,oCAAA,IAAC,uBAAA,eAAD;GAAiC,OAAO,WAAW,SAAS,QAAQ,IAAI,SAAS;aAC/E,oCAAA,KAAC,UAAD;IACE,MAAK;IACL,WAAU;IACV,OAAO;KAAE,SAAS;KAAe,YAAY;KAAU,KAAK;KAAI,SAAS;KAAY,WAAW;IAAG;IACzF;IACV,eAAe,SAAS,SAAS,MAAM;cALzC,CAOE,oCAAA,IAAC,gBAAA,QAAD,EACE,UACG;KAAE,QAAQ;KAAmB,MAAM;KAAe,MAAM;IAAU,EACjE,SAAS,YACN,sBAER,CAAA,GACA,SAAS,KACJ;;EACK,GAjBK,SAAS,EAiBd,CAChB;CACE,CAAA;AAET,CACF"}
|
|
@@ -2,10 +2,10 @@ const require_extensions = require("./_virtual/_global-external_@freelensapp/ext
|
|
|
2
2
|
const require__global_external_react = require("./_virtual/_global-external_react.js");
|
|
3
3
|
const require_jsx_runtime = require("./_virtual/_global-external_react/jsx-runtime.js");
|
|
4
4
|
const require_ai_icon = require("./ai-icon.js");
|
|
5
|
+
const require_native_tooltip = require("./native-tooltip.js");
|
|
5
6
|
const require_ai_terminal_context = require("./src/common/ai-terminal-context.js");
|
|
6
7
|
const require_date_time = require("./src/common/date-time.js");
|
|
7
8
|
//#region src/renderer/ai-terminal-context.tsx
|
|
8
|
-
var nextTerminalTooltip = 0;
|
|
9
9
|
function activeAiTerminal(clusterId) {
|
|
10
10
|
if (!clusterId || require_extensions.Renderer.Catalog.activeCluster.get()?.metadata.uid !== clusterId) return;
|
|
11
11
|
for (const element of document.querySelectorAll(`[data-testid^="dock-tab-content-for-"]`)) {
|
|
@@ -52,7 +52,6 @@ function captureAiTerminal(clusterId, expectedId) {
|
|
|
52
52
|
}
|
|
53
53
|
}
|
|
54
54
|
function AiTerminalContext({ clusterId, attachment, onChange, disabled }) {
|
|
55
|
-
const [tooltipId] = require__global_external_react.useState(() => `power-terminal-tooltip-${++nextTerminalTooltip}`);
|
|
56
55
|
const [terminalId, setTerminalId] = require__global_external_react.useState(() => activeAiTerminal(clusterId));
|
|
57
56
|
const [preview, setPreview] = require__global_external_react.useState();
|
|
58
57
|
const [unavailable, setUnavailable] = require__global_external_react.useState(false);
|
|
@@ -110,58 +109,53 @@ function AiTerminalContext({ clusterId, attachment, onChange, disabled }) {
|
|
|
110
109
|
clusterId,
|
|
111
110
|
onChange
|
|
112
111
|
]);
|
|
113
|
-
const tooltip = attached ? "Detach terminal output from this question" : terminalId ? "Attach terminal output to this question" : "Open a connected terminal in this cluster";
|
|
114
112
|
return /* @__PURE__ */ require_jsx_runtime.jsxs("div", {
|
|
115
113
|
className: "power-ai-terminal-context",
|
|
116
114
|
style: { fontSize: 11 },
|
|
117
115
|
children: [
|
|
118
|
-
/* @__PURE__ */ require_jsx_runtime.jsx("style", { children: `.power-ai-terminal-trigger{position:absolute;top:8px;right:8px;display:inline-flex}
|
|
119
|
-
/* @__PURE__ */ require_jsx_runtime.
|
|
116
|
+
/* @__PURE__ */ require_jsx_runtime.jsx("style", { children: `.power-ai-terminal-trigger{position:absolute;top:8px;right:8px;display:inline-flex}` }),
|
|
117
|
+
/* @__PURE__ */ require_jsx_runtime.jsx("span", {
|
|
120
118
|
className: "power-ai-terminal-trigger",
|
|
121
|
-
children:
|
|
122
|
-
|
|
123
|
-
"
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
119
|
+
children: /* @__PURE__ */ require_jsx_runtime.jsx(require_native_tooltip.NativeTooltip, {
|
|
120
|
+
title: attached ? "Detach terminal output from this question" : terminalId ? "Attach terminal output to this question" : "Open a connected terminal in this cluster",
|
|
121
|
+
children: /* @__PURE__ */ require_jsx_runtime.jsx("button", {
|
|
122
|
+
type: "button",
|
|
123
|
+
"aria-label": "Attach terminal output",
|
|
124
|
+
"aria-pressed": attached,
|
|
125
|
+
style: {
|
|
126
|
+
display: "inline-flex",
|
|
127
|
+
alignItems: "center",
|
|
128
|
+
justifyContent: "center",
|
|
129
|
+
width: 26,
|
|
130
|
+
height: 26,
|
|
131
|
+
minHeight: 26,
|
|
132
|
+
padding: 0,
|
|
133
|
+
color: "var(--textColorSecondary)",
|
|
134
|
+
borderColor: "var(--borderFaintColor)",
|
|
135
|
+
background: attached ? "color-mix(in srgb, var(--textColorPrimary) 8%, transparent)" : "transparent"
|
|
136
|
+
},
|
|
137
|
+
disabled: disabled || !terminalId,
|
|
138
|
+
onClick: () => {
|
|
139
|
+
if (attached) {
|
|
140
|
+
onChange(void 0);
|
|
141
|
+
setPreview(void 0);
|
|
142
|
+
return;
|
|
143
|
+
}
|
|
144
|
+
const snapshot = captureAiTerminal(clusterId, terminalId);
|
|
145
|
+
setUnavailable(!snapshot);
|
|
146
|
+
if (!snapshot || !clusterId || !terminalId) return;
|
|
147
|
+
setPreview(snapshot);
|
|
148
|
+
onChange({
|
|
149
|
+
clusterId,
|
|
150
|
+
terminalId
|
|
151
|
+
});
|
|
152
|
+
},
|
|
153
|
+
children: /* @__PURE__ */ require_jsx_runtime.jsx(require_ai_icon.AiIcon, {
|
|
154
|
+
material: "terminal",
|
|
155
|
+
size: 16
|
|
156
|
+
})
|
|
158
157
|
})
|
|
159
|
-
})
|
|
160
|
-
role: "tooltip",
|
|
161
|
-
id: tooltipId,
|
|
162
|
-
className: "power-ai-terminal-tooltip",
|
|
163
|
-
children: tooltip
|
|
164
|
-
})]
|
|
158
|
+
})
|
|
165
159
|
}),
|
|
166
160
|
attached && preview && /* @__PURE__ */ require_jsx_runtime.jsxs("details", {
|
|
167
161
|
style: {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ai-terminal-context.js","names":[],"sources":["../../src/renderer/ai-terminal-context.tsx"],"sourcesContent":["import { Renderer } from \"@freelensapp/extensions\";\nimport { useEffect, useState } from \"react\";\nimport { type AiTerminalSnapshot, sanitizeAiTerminalSnapshot } from \"../common/ai-terminal-context\";\nimport { formatDateTime } from \"../common/date-time\";\nimport { AiIcon } from \"./ai-icon\";\n\nlet nextTerminalTooltip = 0;\n\ntype TerminalBuffer = {\n length: number;\n baseY: number;\n cursorY: number;\n getLine(index: number): { isWrapped?: boolean; translateToString(trimRight?: boolean): string } | undefined;\n};\n\nexport function activeAiTerminal(clusterId?: string): string | undefined {\n if (!clusterId || Renderer.Catalog.activeCluster.get()?.metadata.uid !== clusterId) return;\n const prefix = \"dock-tab-content-for-\";\n for (const element of document.querySelectorAll<HTMLElement>(`[data-testid^=\"${prefix}\"]`)) {\n let visible = true;\n for (let node: HTMLElement | null = element; node; node = node.parentElement) {\n const style = getComputedStyle(node);\n if (\n node.hidden ||\n node.getAttribute(\"aria-hidden\") === \"true\" ||\n style.display === \"none\" ||\n style.visibility === \"hidden\" ||\n style.visibility === \"collapse\"\n ) {\n visible = false;\n break;\n }\n }\n const id = element.dataset.testid?.slice(prefix.length);\n if (!visible || !id || !Renderer.Component.terminalStore.isConnected(id)) continue;\n const api = Renderer.Component.terminalStore.getTerminalApi(id);\n if (api?.isReady && api.isConnected()) return id;\n }\n return;\n}\n\nexport function captureAiTerminal(clusterId?: string, expectedId?: string): AiTerminalSnapshot | undefined {\n const id = activeAiTerminal(clusterId);\n if (!id || (expectedId && id !== expectedId)) return;\n try {\n // [xterm] is a guarded host implementation detail with no public buffer accessor\n const terminal = Renderer.Component.terminalStore.getTerminal(id) as unknown as\n | {\n xterm?: { buffer?: { active?: TerminalBuffer } };\n }\n | undefined;\n const buffer = terminal?.xterm?.buffer?.active;\n if (!buffer || !Number.isSafeInteger(buffer.length) || buffer.length > 10_000 || buffer.length < 0) return;\n const end = buffer.length;\n if (!Number.isSafeInteger(end) || end < 0) return;\n const logical: string[] = [];\n let characters = 0;\n for (let index = 0; index < end; index++) {\n const line = buffer.getLine(index);\n if (!line || (index === 0 && line.isWrapped)) return;\n const text = line.translateToString(!buffer.getLine(index + 1)?.isWrapped);\n characters += text.length + 1;\n if (characters > 1_000_000) return;\n if (line.isWrapped && logical.length) logical[logical.length - 1] += text;\n else logical.push(text);\n }\n if (activeAiTerminal(clusterId) !== id) return;\n return sanitizeAiTerminalSnapshot({ text: logical.join(\"\\n\"), capturedAt: new Date().toISOString() });\n } catch {\n return;\n }\n}\n\nexport interface AiTerminalAttachment {\n clusterId: string;\n terminalId: string;\n}\n\nexport function AiTerminalContext({\n clusterId,\n attachment,\n onChange,\n disabled,\n}: {\n clusterId?: string;\n attachment?: AiTerminalAttachment;\n onChange(value: AiTerminalAttachment | undefined): void;\n disabled: boolean;\n}) {\n const [tooltipId] = useState(() => `power-terminal-tooltip-${++nextTerminalTooltip}`);\n const [terminalId, setTerminalId] = useState(() => activeAiTerminal(clusterId));\n const [preview, setPreview] = useState<AiTerminalSnapshot>();\n const [unavailable, setUnavailable] = useState(false);\n useEffect(() => {\n const update = () => setTerminalId(activeAiTerminal(clusterId));\n update();\n const timer = window.setInterval(update, 500);\n return () => window.clearInterval(timer);\n }, [clusterId]);\n const attached = Boolean(attachment && attachment.clusterId === clusterId && attachment.terminalId === terminalId);\n useEffect(() => {\n if (!attached) {\n if (attachment) onChange(undefined);\n setPreview(undefined);\n return;\n }\n let stopped = false;\n let scheduled: number | undefined;\n let polling: number | undefined;\n let subscription: { dispose(): void } | undefined;\n const stop = () => {\n stopped = true;\n window.clearTimeout(scheduled);\n window.clearInterval(polling);\n subscription?.dispose();\n subscription = undefined;\n };\n const update = () => {\n if (stopped) return;\n scheduled = undefined;\n const snapshot = captureAiTerminal(clusterId, attachment?.terminalId);\n setUnavailable(!snapshot);\n if (!snapshot) {\n setPreview(undefined);\n if (activeAiTerminal(clusterId) !== attachment?.terminalId) {\n stop();\n onChange(undefined);\n }\n return;\n }\n setPreview((previous) =>\n previous?.text === snapshot.text && previous.truncated === snapshot.truncated ? previous : snapshot,\n );\n };\n update();\n if (stopped) return stop;\n try {\n const terminal = Renderer.Component.terminalStore.getTerminal(attachment!.terminalId) as unknown as\n | {\n xterm?: { onWriteParsed?: (listener: () => void) => { dispose(): void } };\n }\n | undefined;\n subscription = terminal?.xterm?.onWriteParsed?.(() => {\n if (!stopped && scheduled === undefined) scheduled = window.setTimeout(update, 250);\n });\n } catch {}\n if (!subscription) polling = window.setInterval(update, 1000);\n return stop;\n }, [attached, attachment, clusterId, onChange]);\n const tooltip = attached\n ? \"Detach terminal output from this question\"\n : terminalId\n ? \"Attach terminal output to this question\"\n : \"Open a connected terminal in this cluster\";\n return (\n <div className=\"power-ai-terminal-context\" style={{ fontSize: 11 }}>\n <style>{`.power-ai-terminal-trigger{position:absolute;top:8px;right:8px;display:inline-flex}.power-ai-terminal-tooltip{position:absolute;right:0;bottom:calc(100% + 8px);z-index:20;width:max-content;max-width:240px;padding:6px 8px;border:1px solid var(--borderFaintColor);border-radius:4px;background:var(--mainBackground);color:var(--textColorPrimary);font-size:12px;line-height:1.4;visibility:hidden;opacity:0;pointer-events:none}.power-ai-terminal-trigger:hover .power-ai-terminal-tooltip,.power-ai-terminal-trigger:focus-within .power-ai-terminal-tooltip{visibility:visible;opacity:1}`}</style>\n <span className=\"power-ai-terminal-trigger\">\n <button\n type=\"button\"\n aria-describedby={tooltipId}\n aria-label=\"Attach terminal output\"\n aria-pressed={attached}\n style={{\n display: \"inline-flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n width: 26,\n height: 26,\n minHeight: 26,\n padding: 0,\n color: \"var(--textColorSecondary)\",\n borderColor: \"var(--borderFaintColor)\",\n background: attached ? \"color-mix(in srgb, var(--textColorPrimary) 8%, transparent)\" : \"transparent\",\n }}\n disabled={disabled || !terminalId}\n title={tooltip}\n onClick={() => {\n if (attached) {\n onChange(undefined);\n setPreview(undefined);\n return;\n }\n const snapshot = captureAiTerminal(clusterId, terminalId);\n setUnavailable(!snapshot);\n if (!snapshot || !clusterId || !terminalId) return;\n setPreview(snapshot);\n onChange({ clusterId, terminalId });\n }}\n >\n <AiIcon material=\"terminal\" size={16} />\n </button>\n <span role=\"tooltip\" id={tooltipId} className=\"power-ai-terminal-tooltip\">\n {tooltip}\n </span>\n </span>\n {attached && preview && (\n <details style={{ padding: \"0 16px 4px\", margin: 0 }}>\n <summary>\n Terminal · {preview.text.split(\"\\n\").length} rows{preview.truncated ? \" · truncated\" : \"\"}\n </summary>\n <p>\n Preview captured <span style={{ whiteSpace: \"pre-wrap\" }}>{formatDateTime(preview.capturedAt)}</span> ·\n captured again when sent · up to 300 rows / 32 KiB · Common credentials masked. Review before sending.\n </p>\n <pre style={{ maxHeight: 160, overflow: \"auto\", whiteSpace: \"pre-wrap\" }}>{preview.text}</pre>\n <p>The attachment is not stored in chat history. Assistant replies may quote it.</p>\n </details>\n )}\n {unavailable && (\n <div role=\"status\" style={{ padding: \"4px 16px 8px\" }}>\n Terminal output is unavailable or exceeds the safe capture limit\n </div>\n )}\n </div>\n );\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"ai-terminal-context.js","names":[],"sources":["../../src/renderer/ai-terminal-context.tsx"],"sourcesContent":["import { Renderer } from \"@freelensapp/extensions\";\nimport { useEffect, useState } from \"react\";\nimport { type AiTerminalSnapshot, sanitizeAiTerminalSnapshot } from \"../common/ai-terminal-context\";\nimport { formatDateTime } from \"../common/date-time\";\nimport { AiIcon } from \"./ai-icon\";\nimport { NativeTooltip } from \"./native-tooltip\";\n\ntype TerminalBuffer = {\n length: number;\n baseY: number;\n cursorY: number;\n getLine(index: number): { isWrapped?: boolean; translateToString(trimRight?: boolean): string } | undefined;\n};\n\nexport function activeAiTerminal(clusterId?: string): string | undefined {\n if (!clusterId || Renderer.Catalog.activeCluster.get()?.metadata.uid !== clusterId) return;\n const prefix = \"dock-tab-content-for-\";\n for (const element of document.querySelectorAll<HTMLElement>(`[data-testid^=\"${prefix}\"]`)) {\n let visible = true;\n for (let node: HTMLElement | null = element; node; node = node.parentElement) {\n const style = getComputedStyle(node);\n if (\n node.hidden ||\n node.getAttribute(\"aria-hidden\") === \"true\" ||\n style.display === \"none\" ||\n style.visibility === \"hidden\" ||\n style.visibility === \"collapse\"\n ) {\n visible = false;\n break;\n }\n }\n const id = element.dataset.testid?.slice(prefix.length);\n if (!visible || !id || !Renderer.Component.terminalStore.isConnected(id)) continue;\n const api = Renderer.Component.terminalStore.getTerminalApi(id);\n if (api?.isReady && api.isConnected()) return id;\n }\n return;\n}\n\nexport function captureAiTerminal(clusterId?: string, expectedId?: string): AiTerminalSnapshot | undefined {\n const id = activeAiTerminal(clusterId);\n if (!id || (expectedId && id !== expectedId)) return;\n try {\n // [xterm] is a guarded host implementation detail with no public buffer accessor\n const terminal = Renderer.Component.terminalStore.getTerminal(id) as unknown as\n | {\n xterm?: { buffer?: { active?: TerminalBuffer } };\n }\n | undefined;\n const buffer = terminal?.xterm?.buffer?.active;\n if (!buffer || !Number.isSafeInteger(buffer.length) || buffer.length > 10_000 || buffer.length < 0) return;\n const end = buffer.length;\n if (!Number.isSafeInteger(end) || end < 0) return;\n const logical: string[] = [];\n let characters = 0;\n for (let index = 0; index < end; index++) {\n const line = buffer.getLine(index);\n if (!line || (index === 0 && line.isWrapped)) return;\n const text = line.translateToString(!buffer.getLine(index + 1)?.isWrapped);\n characters += text.length + 1;\n if (characters > 1_000_000) return;\n if (line.isWrapped && logical.length) logical[logical.length - 1] += text;\n else logical.push(text);\n }\n if (activeAiTerminal(clusterId) !== id) return;\n return sanitizeAiTerminalSnapshot({ text: logical.join(\"\\n\"), capturedAt: new Date().toISOString() });\n } catch {\n return;\n }\n}\n\nexport interface AiTerminalAttachment {\n clusterId: string;\n terminalId: string;\n}\n\nexport function AiTerminalContext({\n clusterId,\n attachment,\n onChange,\n disabled,\n}: {\n clusterId?: string;\n attachment?: AiTerminalAttachment;\n onChange(value: AiTerminalAttachment | undefined): void;\n disabled: boolean;\n}) {\n const [terminalId, setTerminalId] = useState(() => activeAiTerminal(clusterId));\n const [preview, setPreview] = useState<AiTerminalSnapshot>();\n const [unavailable, setUnavailable] = useState(false);\n useEffect(() => {\n const update = () => setTerminalId(activeAiTerminal(clusterId));\n update();\n const timer = window.setInterval(update, 500);\n return () => window.clearInterval(timer);\n }, [clusterId]);\n const attached = Boolean(attachment && attachment.clusterId === clusterId && attachment.terminalId === terminalId);\n useEffect(() => {\n if (!attached) {\n if (attachment) onChange(undefined);\n setPreview(undefined);\n return;\n }\n let stopped = false;\n let scheduled: number | undefined;\n let polling: number | undefined;\n let subscription: { dispose(): void } | undefined;\n const stop = () => {\n stopped = true;\n window.clearTimeout(scheduled);\n window.clearInterval(polling);\n subscription?.dispose();\n subscription = undefined;\n };\n const update = () => {\n if (stopped) return;\n scheduled = undefined;\n const snapshot = captureAiTerminal(clusterId, attachment?.terminalId);\n setUnavailable(!snapshot);\n if (!snapshot) {\n setPreview(undefined);\n if (activeAiTerminal(clusterId) !== attachment?.terminalId) {\n stop();\n onChange(undefined);\n }\n return;\n }\n setPreview((previous) =>\n previous?.text === snapshot.text && previous.truncated === snapshot.truncated ? previous : snapshot,\n );\n };\n update();\n if (stopped) return stop;\n try {\n const terminal = Renderer.Component.terminalStore.getTerminal(attachment!.terminalId) as unknown as\n | {\n xterm?: { onWriteParsed?: (listener: () => void) => { dispose(): void } };\n }\n | undefined;\n subscription = terminal?.xterm?.onWriteParsed?.(() => {\n if (!stopped && scheduled === undefined) scheduled = window.setTimeout(update, 250);\n });\n } catch {}\n if (!subscription) polling = window.setInterval(update, 1000);\n return stop;\n }, [attached, attachment, clusterId, onChange]);\n const tooltip = attached\n ? \"Detach terminal output from this question\"\n : terminalId\n ? \"Attach terminal output to this question\"\n : \"Open a connected terminal in this cluster\";\n return (\n <div className=\"power-ai-terminal-context\" style={{ fontSize: 11 }}>\n <style>{`.power-ai-terminal-trigger{position:absolute;top:8px;right:8px;display:inline-flex}`}</style>\n <span className=\"power-ai-terminal-trigger\">\n <NativeTooltip title={tooltip}>\n <button\n type=\"button\"\n aria-label=\"Attach terminal output\"\n aria-pressed={attached}\n style={{\n display: \"inline-flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n width: 26,\n height: 26,\n minHeight: 26,\n padding: 0,\n color: \"var(--textColorSecondary)\",\n borderColor: \"var(--borderFaintColor)\",\n background: attached ? \"color-mix(in srgb, var(--textColorPrimary) 8%, transparent)\" : \"transparent\",\n }}\n disabled={disabled || !terminalId}\n onClick={() => {\n if (attached) {\n onChange(undefined);\n setPreview(undefined);\n return;\n }\n const snapshot = captureAiTerminal(clusterId, terminalId);\n setUnavailable(!snapshot);\n if (!snapshot || !clusterId || !terminalId) return;\n setPreview(snapshot);\n onChange({ clusterId, terminalId });\n }}\n >\n <AiIcon material=\"terminal\" size={16} />\n </button>\n </NativeTooltip>\n </span>\n {attached && preview && (\n <details style={{ padding: \"0 16px 4px\", margin: 0 }}>\n <summary>\n Terminal · {preview.text.split(\"\\n\").length} rows{preview.truncated ? \" · truncated\" : \"\"}\n </summary>\n <p>\n Preview captured <span style={{ whiteSpace: \"pre-wrap\" }}>{formatDateTime(preview.capturedAt)}</span> ·\n captured again when sent · up to 300 rows / 32 KiB · Common credentials masked. Review before sending.\n </p>\n <pre style={{ maxHeight: 160, overflow: \"auto\", whiteSpace: \"pre-wrap\" }}>{preview.text}</pre>\n <p>The attachment is not stored in chat history. Assistant replies may quote it.</p>\n </details>\n )}\n {unavailable && (\n <div role=\"status\" style={{ padding: \"4px 16px 8px\" }}>\n Terminal output is unavailable or exceeds the safe capture limit\n </div>\n )}\n </div>\n );\n}\n"],"mappings":"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"}
|
package/out/renderer/ai.js
CHANGED
|
@@ -8,8 +8,10 @@ const require_ai_shortcuts_store = require("./src/common/store/ai-shortcuts-stor
|
|
|
8
8
|
const require__global_external_react = require("./_virtual/_global-external_react.js");
|
|
9
9
|
const require__global_external_react_dom = require("./_virtual/_global-external_react-dom.js");
|
|
10
10
|
const require_ai = require("./src/common/ai.js");
|
|
11
|
+
const require_ai_context_mutations = require("./ai-context-mutations.js");
|
|
11
12
|
const require_jsx_runtime = require("./_virtual/_global-external_react/jsx-runtime.js");
|
|
12
13
|
const require_ai_icon = require("./ai-icon.js");
|
|
14
|
+
const require_native_tooltip = require("./native-tooltip.js");
|
|
13
15
|
const require_ai_copy_answer = require("./ai-copy-answer.js");
|
|
14
16
|
const require_ai_diagnostic_handoff = require("./ai-diagnostic-handoff.js");
|
|
15
17
|
const require_ai_extras$1 = require("./ai-extras.js");
|
|
@@ -220,6 +222,9 @@ var AiChat = require__global_external_mobx_react.observer(({ isClusterDocument }
|
|
|
220
222
|
composer.current?.focus();
|
|
221
223
|
};
|
|
222
224
|
const [context, setContext] = require__global_external_react.useState(readAiContext);
|
|
225
|
+
require__global_external_react.useEffect(() => {
|
|
226
|
+
if (open && !finding && !terminalAttachment) window.dispatchEvent(new Event("power-ai-request-screen-context"));
|
|
227
|
+
}, [open]);
|
|
223
228
|
const [pending, setPending] = require__global_external_react.useState([]);
|
|
224
229
|
const [error, setError] = require__global_external_react.useState("");
|
|
225
230
|
const [stopped, setStopped] = require__global_external_react.useState([]);
|
|
@@ -284,7 +289,9 @@ var AiChat = require__global_external_mobx_react.observer(({ isClusterDocument }
|
|
|
284
289
|
window.addEventListener("popstate", update);
|
|
285
290
|
update();
|
|
286
291
|
const timer = window.setInterval(update, 500);
|
|
287
|
-
const observer = new MutationObserver(
|
|
292
|
+
const observer = new MutationObserver((mutations) => {
|
|
293
|
+
if (require_ai_context_mutations.hasAiContextMutations(mutations)) update();
|
|
294
|
+
});
|
|
288
295
|
observer.observe(document.body, {
|
|
289
296
|
childList: true,
|
|
290
297
|
subtree: true,
|
|
@@ -301,7 +308,7 @@ var AiChat = require__global_external_mobx_react.observer(({ isClusterDocument }
|
|
|
301
308
|
if (!next || !preferences.enabled || !isClusterDocument() || next.clusterId !== readAiContext().clusterId) return;
|
|
302
309
|
update();
|
|
303
310
|
setFinding(next);
|
|
304
|
-
setDraft((previous) => previous || (preferences.conversations[next.clusterId]?.length ? "" : "Explain this finding and suggest the next read-only checks."));
|
|
311
|
+
setDraft((previous) => previous || (next.source === "relationships" || next.source === "diagnostics" || preferences.conversations[next.clusterId]?.length ? "" : "Explain this finding and suggest the next read-only checks."));
|
|
305
312
|
setOpen(true);
|
|
306
313
|
requestAnimationFrame(() => composer.current?.focus());
|
|
307
314
|
};
|
|
@@ -536,30 +543,32 @@ var AiChat = require__global_external_mobx_react.observer(({ isClusterDocument }
|
|
|
536
543
|
};
|
|
537
544
|
return /* @__PURE__ */ require_jsx_runtime.jsxs(require_jsx_runtime.Fragment, { children: [
|
|
538
545
|
/* @__PURE__ */ require_jsx_runtime.jsx("style", { children: styles }),
|
|
539
|
-
!open && /* @__PURE__ */ require_jsx_runtime.
|
|
540
|
-
type: "button",
|
|
541
|
-
className: `power-ai-launcher${launcherHidden ? " power-ai-launcher-hidden" : ""}`,
|
|
542
|
-
"aria-hidden": launcherHidden || void 0,
|
|
543
|
-
tabIndex: launcherHidden ? -1 : 0,
|
|
544
|
-
style: {
|
|
545
|
-
bottom: launcherBottom,
|
|
546
|
-
left: resourceDetailsOpen ? launcherLeft : "auto",
|
|
547
|
-
right: resourceDetailsOpen ? "auto" : 16
|
|
548
|
-
},
|
|
549
|
-
onClick: () => setOpen(true),
|
|
550
|
-
"aria-label": "Open AI assistant",
|
|
546
|
+
!open && /* @__PURE__ */ require_jsx_runtime.jsx(require_native_tooltip.NativeTooltip, {
|
|
551
547
|
title: "Open AI assistant",
|
|
552
|
-
children:
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
548
|
+
children: /* @__PURE__ */ require_jsx_runtime.jsxs("button", {
|
|
549
|
+
type: "button",
|
|
550
|
+
className: `power-ai-launcher${launcherHidden ? " power-ai-launcher-hidden" : ""}`,
|
|
551
|
+
"aria-hidden": launcherHidden || void 0,
|
|
552
|
+
tabIndex: launcherHidden ? -1 : 0,
|
|
553
|
+
style: {
|
|
554
|
+
bottom: launcherBottom,
|
|
555
|
+
left: resourceDetailsOpen ? launcherLeft : "auto",
|
|
556
|
+
right: resourceDetailsOpen ? "auto" : 16
|
|
557
|
+
},
|
|
558
|
+
onClick: () => setOpen(true),
|
|
559
|
+
"aria-label": "Open AI assistant",
|
|
560
|
+
children: [
|
|
561
|
+
/* @__PURE__ */ require_jsx_runtime.jsx("span", {
|
|
562
|
+
"aria-hidden": "true",
|
|
563
|
+
children: /* @__PURE__ */ require_jsx_runtime.jsx(require_ai_icon.AiIcon, {
|
|
564
|
+
material: "chat_bubble_outline",
|
|
565
|
+
size: 16
|
|
566
|
+
})
|
|
567
|
+
}),
|
|
568
|
+
" ",
|
|
569
|
+
"AI"
|
|
570
|
+
]
|
|
571
|
+
})
|
|
563
572
|
}),
|
|
564
573
|
open && /* @__PURE__ */ require_jsx_runtime.jsxs("aside", {
|
|
565
574
|
className: "power-ai-panel",
|
|
@@ -578,67 +587,75 @@ var AiChat = require__global_external_mobx_react.observer(({ isClusterDocument }
|
|
|
578
587
|
/* @__PURE__ */ require_jsx_runtime.jsxs("strong", {
|
|
579
588
|
className: "power-ai-title",
|
|
580
589
|
children: [
|
|
581
|
-
/* @__PURE__ */ require_jsx_runtime.
|
|
582
|
-
className: "power-ai-brand",
|
|
590
|
+
/* @__PURE__ */ require_jsx_runtime.jsx(require_native_tooltip.NativeTooltip, {
|
|
583
591
|
title: "AI assistant",
|
|
584
|
-
children:
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
|
|
592
|
+
children: /* @__PURE__ */ require_jsx_runtime.jsxs("span", {
|
|
593
|
+
className: "power-ai-brand",
|
|
594
|
+
children: [/* @__PURE__ */ require_jsx_runtime.jsx(require_ai_icon.AiIcon, {
|
|
595
|
+
material: "auto_awesome",
|
|
596
|
+
size: 18
|
|
597
|
+
}), " AI"]
|
|
598
|
+
})
|
|
588
599
|
}),
|
|
589
600
|
" ",
|
|
590
601
|
"Assistant"
|
|
591
602
|
]
|
|
592
603
|
}),
|
|
593
|
-
/* @__PURE__ */ require_jsx_runtime.
|
|
594
|
-
type: "button",
|
|
595
|
-
disabled: busy,
|
|
596
|
-
"aria-label": "New chat",
|
|
604
|
+
/* @__PURE__ */ require_jsx_runtime.jsx(require_native_tooltip.NativeTooltip, {
|
|
597
605
|
title: "Clear this conversation and start a new chat",
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
606
|
+
children: /* @__PURE__ */ require_jsx_runtime.jsxs("button", {
|
|
607
|
+
type: "button",
|
|
608
|
+
disabled: busy,
|
|
609
|
+
"aria-label": "New chat",
|
|
610
|
+
onClick: () => {
|
|
611
|
+
setTerminalAttachment(void 0);
|
|
612
|
+
setFinding(void 0);
|
|
613
|
+
preferences.setMessages(key, []);
|
|
614
|
+
setStopped((keys) => keys.filter((entry) => entry !== key));
|
|
615
|
+
setActivity({
|
|
616
|
+
key,
|
|
617
|
+
reads: []
|
|
618
|
+
});
|
|
619
|
+
setError("");
|
|
620
|
+
},
|
|
621
|
+
children: [/* @__PURE__ */ require_jsx_runtime.jsx(require_ai_icon.AiIcon, {
|
|
622
|
+
material: "add_comment",
|
|
623
|
+
size: 16
|
|
624
|
+
}), " New chat"]
|
|
625
|
+
})
|
|
613
626
|
}),
|
|
614
|
-
/* @__PURE__ */ require_jsx_runtime.jsx(
|
|
615
|
-
type: "button",
|
|
616
|
-
className: "power-ai-pin",
|
|
617
|
-
"aria-label": "Pin AI assistant",
|
|
618
|
-
"aria-pressed": pinned,
|
|
627
|
+
/* @__PURE__ */ require_jsx_runtime.jsx(require_native_tooltip.NativeTooltip, {
|
|
619
628
|
title: pinned ? "Unpin to close when clicking outside" : "Pin to keep the assistant open",
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
|
|
629
|
+
children: /* @__PURE__ */ require_jsx_runtime.jsx("button", {
|
|
630
|
+
type: "button",
|
|
631
|
+
className: "power-ai-pin",
|
|
632
|
+
"aria-label": "Pin AI assistant",
|
|
633
|
+
"aria-pressed": pinned,
|
|
634
|
+
onClick: () => setPinned((value) => !value),
|
|
635
|
+
children: /* @__PURE__ */ require_jsx_runtime.jsx(require_ai_icon.AiIcon, {
|
|
636
|
+
material: "push_pin",
|
|
637
|
+
size: 18
|
|
638
|
+
})
|
|
624
639
|
})
|
|
625
640
|
}),
|
|
626
|
-
/* @__PURE__ */ require_jsx_runtime.jsx(
|
|
627
|
-
type: "button",
|
|
628
|
-
onPointerDown: (event) => event.stopPropagation(),
|
|
629
|
-
onMouseDown: (event) => event.stopPropagation(),
|
|
630
|
-
onClick: (event) => {
|
|
631
|
-
event.stopPropagation();
|
|
632
|
-
setOpen(false);
|
|
633
|
-
},
|
|
634
|
-
className: "power-ai-close",
|
|
635
|
-
"aria-label": "Close AI assistant",
|
|
641
|
+
/* @__PURE__ */ require_jsx_runtime.jsx(require_native_tooltip.NativeTooltip, {
|
|
636
642
|
title: "Close AI assistant",
|
|
637
|
-
children: /* @__PURE__ */ require_jsx_runtime.jsx("
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
|
|
643
|
+
children: /* @__PURE__ */ require_jsx_runtime.jsx("button", {
|
|
644
|
+
type: "button",
|
|
645
|
+
onPointerDown: (event) => event.stopPropagation(),
|
|
646
|
+
onMouseDown: (event) => event.stopPropagation(),
|
|
647
|
+
onClick: (event) => {
|
|
648
|
+
event.stopPropagation();
|
|
649
|
+
setOpen(false);
|
|
650
|
+
},
|
|
651
|
+
className: "power-ai-close",
|
|
652
|
+
"aria-label": "Close AI assistant",
|
|
653
|
+
children: /* @__PURE__ */ require_jsx_runtime.jsx("span", {
|
|
654
|
+
"aria-hidden": "true",
|
|
655
|
+
children: /* @__PURE__ */ require_jsx_runtime.jsx(require_ai_icon.AiIcon, {
|
|
656
|
+
material: "close",
|
|
657
|
+
size: 18
|
|
658
|
+
})
|
|
642
659
|
})
|
|
643
660
|
})
|
|
644
661
|
})
|
|
@@ -679,12 +696,12 @@ var AiChat = require__global_external_mobx_react.observer(({ isClusterDocument }
|
|
|
679
696
|
className: `power-ai-message power-ai-message-${message.role}`,
|
|
680
697
|
children: [
|
|
681
698
|
/* @__PURE__ */ require_jsx_runtime.jsxs("strong", { children: [
|
|
682
|
-
message.role === "user" ? /* @__PURE__ */ require_jsx_runtime.jsx(
|
|
699
|
+
message.role === "user" ? /* @__PURE__ */ require_jsx_runtime.jsx(require_native_tooltip.NativeTooltip, {
|
|
683
700
|
title: "You",
|
|
684
|
-
children: /* @__PURE__ */ require_jsx_runtime.jsx(require_ai_icon.AiIcon, {
|
|
701
|
+
children: /* @__PURE__ */ require_jsx_runtime.jsx("span", { children: /* @__PURE__ */ require_jsx_runtime.jsx(require_ai_icon.AiIcon, {
|
|
685
702
|
material: "person_outline",
|
|
686
703
|
size: 16
|
|
687
|
-
})
|
|
704
|
+
}) })
|
|
688
705
|
}) : /* @__PURE__ */ require_jsx_runtime.jsx(require_ai_provider_icon.AiProviderIcon, { provider: message.provider === "claude" ? "claude" : "codex" }),
|
|
689
706
|
message.role === "user" ? "You" : message.provider === "claude" ? "Claude" : "Codex",
|
|
690
707
|
message.role === "assistant" && /* @__PURE__ */ require_jsx_runtime.jsx(require_ai_copy_answer.AiCopyAnswer, { text: message.text })
|
|
@@ -705,22 +722,24 @@ var AiChat = require__global_external_mobx_react.observer(({ isClusterDocument }
|
|
|
705
722
|
color: "var(--textColorSecondary)",
|
|
706
723
|
margin: "8px 16px"
|
|
707
724
|
},
|
|
708
|
-
children: readActivity.map((read, index) => /* @__PURE__ */ require_jsx_runtime.
|
|
725
|
+
children: readActivity.map((read, index) => /* @__PURE__ */ require_jsx_runtime.jsx(require_native_tooltip.NativeTooltip, {
|
|
709
726
|
title: `${read.method} · ${read.status === "reading" ? "reading" : read.status === "ok" ? "read" : "unavailable"}`,
|
|
710
|
-
|
|
711
|
-
|
|
712
|
-
|
|
713
|
-
|
|
714
|
-
|
|
715
|
-
|
|
716
|
-
|
|
717
|
-
|
|
718
|
-
|
|
719
|
-
|
|
720
|
-
|
|
721
|
-
|
|
722
|
-
|
|
723
|
-
|
|
727
|
+
children: /* @__PURE__ */ require_jsx_runtime.jsxs("span", {
|
|
728
|
+
"data-method": read.method,
|
|
729
|
+
"data-status": read.status,
|
|
730
|
+
style: { marginRight: 10 },
|
|
731
|
+
children: [
|
|
732
|
+
/* @__PURE__ */ require_jsx_runtime.jsx(require_ai_icon.AiIcon, {
|
|
733
|
+
material: read.status === "reading" ? "sync" : read.status === "ok" ? "check_circle_outline" : "info_outline",
|
|
734
|
+
size: 13
|
|
735
|
+
}),
|
|
736
|
+
" ",
|
|
737
|
+
read.method,
|
|
738
|
+
" ·",
|
|
739
|
+
" ",
|
|
740
|
+
read.status === "reading" ? "reading" : read.status === "ok" ? "read" : "unavailable"
|
|
741
|
+
]
|
|
742
|
+
})
|
|
724
743
|
}, index))
|
|
725
744
|
}),
|
|
726
745
|
busy && /* @__PURE__ */ require_jsx_runtime.jsxs("p", {
|
|
@@ -742,15 +761,17 @@ var AiChat = require__global_external_mobx_react.observer(({ isClusterDocument }
|
|
|
742
761
|
children: [
|
|
743
762
|
"Response stopped",
|
|
744
763
|
" ",
|
|
745
|
-
/* @__PURE__ */ require_jsx_runtime.jsx(
|
|
746
|
-
type: "button",
|
|
747
|
-
"aria-label": "Dismiss cancellation",
|
|
748
|
-
className: "power-ai-dismiss",
|
|
764
|
+
/* @__PURE__ */ require_jsx_runtime.jsx(require_native_tooltip.NativeTooltip, {
|
|
749
765
|
title: "Dismiss",
|
|
750
|
-
|
|
751
|
-
|
|
752
|
-
|
|
753
|
-
|
|
766
|
+
children: /* @__PURE__ */ require_jsx_runtime.jsx("button", {
|
|
767
|
+
type: "button",
|
|
768
|
+
"aria-label": "Dismiss cancellation",
|
|
769
|
+
className: "power-ai-dismiss",
|
|
770
|
+
onClick: () => setStopped((keys) => keys.filter((entry) => entry !== key)),
|
|
771
|
+
children: /* @__PURE__ */ require_jsx_runtime.jsx(require_ai_icon.AiIcon, {
|
|
772
|
+
material: "close",
|
|
773
|
+
size: 14
|
|
774
|
+
})
|
|
754
775
|
})
|
|
755
776
|
})
|
|
756
777
|
]
|
|
@@ -772,15 +793,17 @@ var AiChat = require__global_external_mobx_react.observer(({ isClusterDocument }
|
|
|
772
793
|
role: "listbox",
|
|
773
794
|
id: "power-ai-commands",
|
|
774
795
|
"aria-label": "Prompt shortcuts",
|
|
775
|
-
children: suggestions.map((shortcut, index) => /* @__PURE__ */ require_jsx_runtime.
|
|
776
|
-
type: "button",
|
|
777
|
-
role: "option",
|
|
778
|
-
id: `power-ai-command-${index}`,
|
|
779
|
-
"aria-selected": index === suggestionIndex % suggestions.length,
|
|
796
|
+
children: suggestions.map((shortcut, index) => /* @__PURE__ */ require_jsx_runtime.jsx(require_native_tooltip.NativeTooltip, {
|
|
780
797
|
title: `Insert /${shortcut.command}: ${shortcut.label}`,
|
|
781
|
-
|
|
782
|
-
|
|
783
|
-
|
|
798
|
+
children: /* @__PURE__ */ require_jsx_runtime.jsxs("button", {
|
|
799
|
+
type: "button",
|
|
800
|
+
role: "option",
|
|
801
|
+
id: `power-ai-command-${index}`,
|
|
802
|
+
"aria-selected": index === suggestionIndex % suggestions.length,
|
|
803
|
+
onMouseDown: (event) => event.preventDefault(),
|
|
804
|
+
onClick: () => selectSuggestion(index),
|
|
805
|
+
children: [/* @__PURE__ */ require_jsx_runtime.jsxs("span", { children: ["/", shortcut.command] }), /* @__PURE__ */ require_jsx_runtime.jsx("span", { children: shortcut.label })]
|
|
806
|
+
})
|
|
784
807
|
}, shortcut.id))
|
|
785
808
|
}),
|
|
786
809
|
/* @__PURE__ */ require_jsx_runtime.jsx(require_ai_extras$1.AiContextPreview, {
|
|
@@ -901,7 +924,7 @@ function startAiChat(isClusterDocument = isAiClusterDocument) {
|
|
|
901
924
|
const overviewButton = document.createElement("button");
|
|
902
925
|
overviewButton.type = "button";
|
|
903
926
|
overviewButton.setAttribute("aria-label", "Ask about cluster");
|
|
904
|
-
overviewButton.
|
|
927
|
+
overviewButton.id = "power-ai-overview-button";
|
|
905
928
|
overviewIcon = document.createElement("span");
|
|
906
929
|
overviewIcon.setAttribute("aria-hidden", "true");
|
|
907
930
|
overviewLabel = document.createElement("span");
|
|
@@ -914,10 +937,13 @@ function startAiChat(isClusterDocument = isAiClusterDocument) {
|
|
|
914
937
|
overviewResize = new ResizeObserver(updateOverviewLabel);
|
|
915
938
|
overviewResize.observe(overview);
|
|
916
939
|
}
|
|
917
|
-
require__global_external_react_dom.default.render(/* @__PURE__ */ require_jsx_runtime.jsx(require_ai_icon.AiIcon, {
|
|
940
|
+
require__global_external_react_dom.default.render(/* @__PURE__ */ require_jsx_runtime.jsxs(require_jsx_runtime.Fragment, { children: [/* @__PURE__ */ require_jsx_runtime.jsx(require_ai_icon.AiIcon, {
|
|
918
941
|
material: "auto_awesome",
|
|
919
942
|
size: 16
|
|
920
|
-
}),
|
|
943
|
+
}), /* @__PURE__ */ require_jsx_runtime.jsx(require_extensions.Renderer.Component.Tooltip, {
|
|
944
|
+
targetId: "power-ai-overview-button",
|
|
945
|
+
children: "Open the AI assistant to ask about this cluster"
|
|
946
|
+
})] }), overviewIcon);
|
|
921
947
|
};
|
|
922
948
|
const observer = new MutationObserver(reconcile);
|
|
923
949
|
const stop = require__global_external_mobx.autorun(() => {
|