@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
|
@@ -3,6 +3,7 @@ const require_ai_extras = require("./src/common/ai-extras.js");
|
|
|
3
3
|
const require__global_external_react = require("./_virtual/_global-external_react.js");
|
|
4
4
|
const require_jsx_runtime = require("./_virtual/_global-external_react/jsx-runtime.js");
|
|
5
5
|
const require_ai_icon = require("./ai-icon.js");
|
|
6
|
+
const require_native_tooltip = require("./native-tooltip.js");
|
|
6
7
|
//#region src/renderer/ai-extras.tsx
|
|
7
8
|
function AiContextPreview({ context, finding, onRemoveFinding }) {
|
|
8
9
|
const [removeFindingId] = require__global_external_react.useState(() => `power-ai-remove-finding-${crypto.randomUUID()}`);
|
|
@@ -17,13 +18,13 @@ function AiContextPreview({ context, finding, onRemoveFinding }) {
|
|
|
17
18
|
"aria-label": "Selected diagnostic finding",
|
|
18
19
|
children: [
|
|
19
20
|
/* @__PURE__ */ require_jsx_runtime.jsx(require_ai_icon.AiIcon, {
|
|
20
|
-
material: finding.source === "logs" ? "subject" : "insights",
|
|
21
|
+
material: finding.source === "logs" ? "subject" : finding.source === "relationships" ? "account_tree" : "insights",
|
|
21
22
|
size: 14
|
|
22
23
|
}),
|
|
23
24
|
/* @__PURE__ */ require_jsx_runtime.jsxs("details", { children: [
|
|
24
|
-
/* @__PURE__ */ require_jsx_runtime.jsx(
|
|
25
|
+
/* @__PURE__ */ require_jsx_runtime.jsx(require_native_tooltip.NativeTooltip, {
|
|
25
26
|
title: "Review the selected evidence attached to your next message",
|
|
26
|
-
children: finding.title
|
|
27
|
+
children: /* @__PURE__ */ require_jsx_runtime.jsx("summary", { children: finding.title })
|
|
27
28
|
}),
|
|
28
29
|
/* @__PURE__ */ require_jsx_runtime.jsx("pre", {
|
|
29
30
|
style: {
|
|
@@ -53,9 +54,9 @@ function AiContextPreview({ context, finding, onRemoveFinding }) {
|
|
|
53
54
|
})
|
|
54
55
|
]
|
|
55
56
|
}), /* @__PURE__ */ require_jsx_runtime.jsxs("details", { children: [
|
|
56
|
-
/* @__PURE__ */ require_jsx_runtime.jsx(
|
|
57
|
+
/* @__PURE__ */ require_jsx_runtime.jsx(require_native_tooltip.NativeTooltip, {
|
|
57
58
|
title: "Show the screen and resource metadata attached to your next message",
|
|
58
|
-
children: "Attached context"
|
|
59
|
+
children: /* @__PURE__ */ require_jsx_runtime.jsx("summary", { children: "Attached context" })
|
|
59
60
|
}),
|
|
60
61
|
/* @__PURE__ */ require_jsx_runtime.jsx("pre", {
|
|
61
62
|
style: {
|
|
@@ -106,43 +107,45 @@ function AiResourceReferences({ clusterId, references, text, onOpened }) {
|
|
|
106
107
|
gap: 6,
|
|
107
108
|
marginTop: 6
|
|
108
109
|
},
|
|
109
|
-
children: items.map((reference) => /* @__PURE__ */ require_jsx_runtime.
|
|
110
|
-
type: "button",
|
|
111
|
-
className: "power-ai-resource-reference",
|
|
112
|
-
style: {
|
|
113
|
-
display: "inline-flex",
|
|
114
|
-
alignItems: "center",
|
|
115
|
-
gap: 6,
|
|
116
|
-
maxWidth: "100%",
|
|
117
|
-
minWidth: 0,
|
|
118
|
-
padding: "4px 8px",
|
|
119
|
-
fontSize: 12,
|
|
120
|
-
lineHeight: 1.4,
|
|
121
|
-
border: "1px solid var(--borderFaintColor)",
|
|
122
|
-
borderRadius: 6
|
|
123
|
-
},
|
|
110
|
+
children: items.map((reference) => /* @__PURE__ */ require_jsx_runtime.jsx(require_native_tooltip.NativeTooltip, {
|
|
124
111
|
title: `Open ${reference.kind}/${reference.name} details · ${reference.namespace ?? "cluster scoped"}`,
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
},
|
|
129
|
-
children: [/* @__PURE__ */ require_jsx_runtime.jsxs("span", {
|
|
112
|
+
children: /* @__PURE__ */ require_jsx_runtime.jsxs("button", {
|
|
113
|
+
type: "button",
|
|
114
|
+
className: "power-ai-resource-reference",
|
|
130
115
|
style: {
|
|
116
|
+
display: "inline-flex",
|
|
117
|
+
alignItems: "center",
|
|
118
|
+
gap: 6,
|
|
119
|
+
maxWidth: "100%",
|
|
131
120
|
minWidth: 0,
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
121
|
+
padding: "4px 8px",
|
|
122
|
+
fontSize: 12,
|
|
123
|
+
lineHeight: 1.4,
|
|
124
|
+
border: "1px solid var(--borderFaintColor)",
|
|
125
|
+
borderRadius: 6
|
|
135
126
|
},
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
"
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
127
|
+
onClick: () => {
|
|
128
|
+
setError("");
|
|
129
|
+
openAiResourceReference(clusterId, reference).then(onOpened).catch(() => setError("Unable to open this resource. Check the selected cluster and your access."));
|
|
130
|
+
},
|
|
131
|
+
children: [/* @__PURE__ */ require_jsx_runtime.jsxs("span", {
|
|
132
|
+
style: {
|
|
133
|
+
minWidth: 0,
|
|
134
|
+
overflow: "hidden",
|
|
135
|
+
textOverflow: "ellipsis",
|
|
136
|
+
whiteSpace: "nowrap"
|
|
137
|
+
},
|
|
138
|
+
children: [
|
|
139
|
+
reference.kind,
|
|
140
|
+
"/",
|
|
141
|
+
reference.name,
|
|
142
|
+
reference.namespace ? ` · ${reference.namespace}` : ""
|
|
143
|
+
]
|
|
144
|
+
}), /* @__PURE__ */ require_jsx_runtime.jsx(require_ai_icon.AiIcon, {
|
|
145
|
+
material: "arrow_forward",
|
|
146
|
+
size: 14
|
|
147
|
+
})]
|
|
148
|
+
})
|
|
146
149
|
}, JSON.stringify(reference)))
|
|
147
150
|
}),
|
|
148
151
|
error && /* @__PURE__ */ require_jsx_runtime.jsx("p", {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ai-extras.js","names":[],"sources":["../../src/renderer/ai-extras.tsx"],"sourcesContent":["import { Renderer } from \"@freelensapp/extensions\";\nimport { useState } from \"react\";\nimport { type AiResourceReference, referencedAiResources, validAiResourceReference } from \"../common/ai-extras\";\nimport { AiIcon } from \"./ai-icon\";\n\nimport type { AiChatRequest } from \"../common/ai\";\nimport type { DiagnosticFinding } from \"./ai-diagnostic-handoff\";\n\nexport function AiContextPreview({\n context,\n finding,\n onRemoveFinding,\n}: {\n context: AiChatRequest[\"context\"];\n finding?: DiagnosticFinding;\n onRemoveFinding?: () => void;\n}) {\n const [removeFindingId] = useState(() => `power-ai-remove-finding-${crypto.randomUUID()}`);\n return (\n <div className=\"power-ai-context-preview\" style={{ padding: \"8px 16px\", fontSize: 11 }}>\n {finding && (\n <div className=\"power-ai-context-finding\" aria-label=\"Selected diagnostic finding\">\n <AiIcon
|
|
1
|
+
{"version":3,"file":"ai-extras.js","names":[],"sources":["../../src/renderer/ai-extras.tsx"],"sourcesContent":["import { Renderer } from \"@freelensapp/extensions\";\nimport { useState } from \"react\";\nimport { type AiResourceReference, referencedAiResources, validAiResourceReference } from \"../common/ai-extras\";\nimport { AiIcon } from \"./ai-icon\";\nimport { NativeTooltip } from \"./native-tooltip\";\n\nimport type { AiChatRequest } from \"../common/ai\";\nimport type { DiagnosticFinding } from \"./ai-diagnostic-handoff\";\n\nexport function AiContextPreview({\n context,\n finding,\n onRemoveFinding,\n}: {\n context: AiChatRequest[\"context\"];\n finding?: DiagnosticFinding;\n onRemoveFinding?: () => void;\n}) {\n const [removeFindingId] = useState(() => `power-ai-remove-finding-${crypto.randomUUID()}`);\n return (\n <div className=\"power-ai-context-preview\" style={{ padding: \"8px 16px\", fontSize: 11 }}>\n {finding && (\n <div className=\"power-ai-context-finding\" aria-label=\"Selected diagnostic finding\">\n <AiIcon\n material={\n finding.source === \"logs\" ? \"subject\" : finding.source === \"relationships\" ? \"account_tree\" : \"insights\"\n }\n size={14}\n />\n <details key={`${finding.clusterId}:${finding.title}:${finding.summary}`}>\n <NativeTooltip title=\"Review the selected evidence attached to your next message\">\n <summary>{finding.title}</summary>\n </NativeTooltip>\n <pre style={{ whiteSpace: \"pre-wrap\", overflowWrap: \"anywhere\", maxHeight: 140, overflow: \"auto\" }}>\n {finding.summary}\n </pre>\n <p>Selected snapshot · sent with your next message</p>\n </details>\n <button\n type=\"button\"\n className=\"power-ai-remove-context\"\n aria-label=\"Remove diagnostic finding\"\n id={removeFindingId}\n onClick={onRemoveFinding}\n >\n <AiIcon material=\"close\" size={14} />\n </button>\n <Renderer.Component.Tooltip targetId={removeFindingId}>Remove attached finding</Renderer.Component.Tooltip>\n </div>\n )}\n <details>\n <NativeTooltip title=\"Show the screen and resource metadata attached to your next message\">\n <summary>Attached context</summary>\n </NativeTooltip>\n <pre style={{ whiteSpace: \"pre-wrap\", overflowWrap: \"anywhere\", maxHeight: 160, overflowY: \"auto\" }}>\n {JSON.stringify(context, null, 2)}\n </pre>\n <p>Screen and resource metadata only. Resource reads happen after sending.</p>\n </details>\n </div>\n );\n}\n\nexport async function openAiResourceReference(clusterId: string, reference: AiResourceReference): Promise<void> {\n if (!validAiResourceReference(reference) || Renderer.Catalog.activeCluster.get()?.metadata.uid !== clusterId)\n throw new Error(\"Select the original cluster to open this resource\");\n const api = Renderer.K8sApi.apiManager.getApiByKind(reference.kind, reference.apiVersion);\n if (!api || api.isNamespaced !== Boolean(reference.namespace)) throw new Error(\"Resource details are unavailable\");\n const resource = await api.get({ name: reference.name, namespace: reference.namespace });\n if (!resource || Renderer.Catalog.activeCluster.get()?.metadata.uid !== clusterId)\n throw new Error(\"Resource details are unavailable\");\n await Renderer.Navigation.showDetails(api.getUrl({ name: reference.name, namespace: reference.namespace }));\n}\n\nexport function AiResourceReferences({\n clusterId,\n references,\n text,\n onOpened,\n}: {\n clusterId: string;\n references: unknown;\n text: string;\n onOpened?: () => void;\n}) {\n const [error, setError] = useState(\"\");\n const items = referencedAiResources(text, references);\n if (!items.length) return null;\n return (\n <div className=\"power-ai-resource-references\" style={{ marginTop: 12 }}>\n <style>{`.power-ai-resource-references button.power-ai-resource-reference:hover { color: var(--primary); border-color: var(--primary); background: color-mix(in srgb, var(--primary) 10%, var(--contentColor)); } .power-ai-resource-references button.power-ai-resource-reference:focus-visible { outline: 2px solid var(--primary); outline-offset: 2px; }`}</style>\n <span style={{ fontSize: 11, color: \"var(--textColorSecondary)\" }}>Related resources</span>\n <div style={{ display: \"flex\", flexWrap: \"wrap\", gap: 6, marginTop: 6 }}>\n {items.map((reference) => (\n <NativeTooltip\n key={JSON.stringify(reference)}\n title={`Open ${reference.kind}/${reference.name} details · ${reference.namespace ?? \"cluster scoped\"}`}\n >\n <button\n type=\"button\"\n className=\"power-ai-resource-reference\"\n style={{\n display: \"inline-flex\",\n alignItems: \"center\",\n gap: 6,\n maxWidth: \"100%\",\n minWidth: 0,\n padding: \"4px 8px\",\n fontSize: 12,\n lineHeight: 1.4,\n border: \"1px solid var(--borderFaintColor)\",\n borderRadius: 6,\n }}\n onClick={() => {\n setError(\"\");\n void openAiResourceReference(clusterId, reference)\n .then(onOpened)\n .catch(() => setError(\"Unable to open this resource. Check the selected cluster and your access.\"));\n }}\n >\n <span style={{ minWidth: 0, overflow: \"hidden\", textOverflow: \"ellipsis\", whiteSpace: \"nowrap\" }}>\n {reference.kind}/{reference.name}\n {reference.namespace ? ` · ${reference.namespace}` : \"\"}\n </span>\n <AiIcon material=\"arrow_forward\" size={14} />\n </button>\n </NativeTooltip>\n ))}\n </div>\n {error && <p role=\"alert\">{error}</p>}\n </div>\n );\n}\n"],"mappings":"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"}
|
|
@@ -3,6 +3,7 @@ const require__global_external_mobx = require("./_virtual/_global-external_mobx.
|
|
|
3
3
|
const require__global_external_react = require("./_virtual/_global-external_react.js");
|
|
4
4
|
const require_jsx_runtime = require("./_virtual/_global-external_react/jsx-runtime.js");
|
|
5
5
|
const require_ai_icon = require("./ai-icon.js");
|
|
6
|
+
const require_native_tooltip = require("./native-tooltip.js");
|
|
6
7
|
const require_ai_logs_sql = require("./ai-logs-sql.js");
|
|
7
8
|
const require_markdown_it = require("./node_modules/.pnpm/markdown-it@15.0.2/node_modules/markdown-it/dist/markdown-it.js");
|
|
8
9
|
let electron = require("electron");
|
|
@@ -72,7 +73,6 @@ function renderTokens(tokens) {
|
|
|
72
73
|
if (!href) tag = require__global_external_react.Fragment;
|
|
73
74
|
else {
|
|
74
75
|
props.href = href;
|
|
75
|
-
props.title = opening.attrGet("title") ?? void 0;
|
|
76
76
|
props.rel = "noopener noreferrer";
|
|
77
77
|
props.target = "_blank";
|
|
78
78
|
const open = (event) => {
|
|
@@ -92,7 +92,12 @@ function renderTokens(tokens) {
|
|
|
92
92
|
const alignment = String(opening.attrGet("style") ?? "").match(/^text-align:(left|right|center)$/)?.[1];
|
|
93
93
|
if (alignment) props.style = { textAlign: alignment };
|
|
94
94
|
}
|
|
95
|
-
|
|
95
|
+
const element = require__global_external_react.createElement(tag, props, ...container.children);
|
|
96
|
+
const title = tag === "a" ? opening.attrGet("title") : void 0;
|
|
97
|
+
append(title ? /* @__PURE__ */ require_jsx_runtime.jsx(require_native_tooltip.NativeTooltip, {
|
|
98
|
+
title,
|
|
99
|
+
children: element
|
|
100
|
+
}, container.key) : element);
|
|
96
101
|
return;
|
|
97
102
|
}
|
|
98
103
|
switch (token.type) {
|
|
@@ -210,48 +215,54 @@ function CodeBlock({ text, language }) {
|
|
|
210
215
|
/* @__PURE__ */ require_jsx_runtime.jsxs("div", {
|
|
211
216
|
className: "power-ai-code-toolbar",
|
|
212
217
|
children: [/* @__PURE__ */ require_jsx_runtime.jsx("span", { children: language || "code" }), /* @__PURE__ */ require_jsx_runtime.jsxs("div", { children: [
|
|
213
|
-
/* @__PURE__ */ require_jsx_runtime.
|
|
214
|
-
type: "button",
|
|
215
|
-
"aria-label": "Copy code",
|
|
218
|
+
/* @__PURE__ */ require_jsx_runtime.jsx(require_native_tooltip.NativeTooltip, {
|
|
216
219
|
title: "Copy code to clipboard",
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
220
|
+
children: /* @__PURE__ */ require_jsx_runtime.jsxs("button", {
|
|
221
|
+
type: "button",
|
|
222
|
+
"aria-label": "Copy code",
|
|
223
|
+
onClick: () => {
|
|
224
|
+
try {
|
|
225
|
+
electron.clipboard.writeText(text);
|
|
226
|
+
setFeedback("Copied");
|
|
227
|
+
} catch {
|
|
228
|
+
setFeedback("Unable to copy code.");
|
|
229
|
+
}
|
|
230
|
+
},
|
|
231
|
+
children: [/* @__PURE__ */ require_jsx_runtime.jsx(require_ai_icon.AiIcon, {
|
|
232
|
+
material: "content_copy",
|
|
233
|
+
size: 14
|
|
234
|
+
}), " Copy"]
|
|
235
|
+
})
|
|
229
236
|
}),
|
|
230
|
-
sqlDraft && /* @__PURE__ */ require_jsx_runtime.
|
|
231
|
-
type: "button",
|
|
232
|
-
"aria-label": "Insert into SQL",
|
|
237
|
+
sqlDraft && /* @__PURE__ */ require_jsx_runtime.jsx(require_native_tooltip.NativeTooltip, {
|
|
233
238
|
title: "Insert into the SQL editor without running",
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
239
|
+
children: /* @__PURE__ */ require_jsx_runtime.jsxs("button", {
|
|
240
|
+
type: "button",
|
|
241
|
+
"aria-label": "Insert into SQL",
|
|
242
|
+
disabled: !text.trim() || text.length > 65536,
|
|
243
|
+
onClick: () => {
|
|
244
|
+
if (!require_ai_logs_sql.isPowerLogsWorkspace() || !text.trim() || text.length > 65536) return;
|
|
245
|
+
window.dispatchEvent(new CustomEvent("power-logs-sql-draft", { detail: { sql: text } }));
|
|
246
|
+
window.dispatchEvent(new Event("power-ai-close"));
|
|
247
|
+
},
|
|
248
|
+
children: [/* @__PURE__ */ require_jsx_runtime.jsx(require_ai_icon.AiIcon, {
|
|
249
|
+
material: "post_add",
|
|
250
|
+
size: 14
|
|
251
|
+
}), " Insert into SQL"]
|
|
252
|
+
})
|
|
244
253
|
}),
|
|
245
|
-
shell && terminalId && /* @__PURE__ */ require_jsx_runtime.
|
|
246
|
-
type: "button",
|
|
247
|
-
"aria-label": "Insert into terminal",
|
|
248
|
-
disabled: !command || !terminalId || inserting,
|
|
254
|
+
shell && terminalId && /* @__PURE__ */ require_jsx_runtime.jsx(require_native_tooltip.NativeTooltip, {
|
|
249
255
|
title: !command ? "Only a single line without control characters can be inserted" : !terminalId ? "Focus an open terminal tab to insert" : "Insert without running",
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
256
|
+
children: /* @__PURE__ */ require_jsx_runtime.jsxs("button", {
|
|
257
|
+
type: "button",
|
|
258
|
+
"aria-label": "Insert into terminal",
|
|
259
|
+
disabled: !command || !terminalId || inserting,
|
|
260
|
+
onClick: () => void insert(),
|
|
261
|
+
children: [/* @__PURE__ */ require_jsx_runtime.jsx(require_ai_icon.AiIcon, {
|
|
262
|
+
material: "terminal",
|
|
263
|
+
size: 14
|
|
264
|
+
}), " Insert"]
|
|
265
|
+
})
|
|
255
266
|
})
|
|
256
267
|
] })]
|
|
257
268
|
}),
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ai-message.js","names":[],"sources":["../../src/renderer/ai-message.tsx"],"sourcesContent":["import { Renderer } from \"@freelensapp/extensions\";\nimport { clipboard, shell } from \"electron\";\nimport MarkdownIt, { type Token } from \"markdown-it\";\nimport { autorun } from \"mobx\";\nimport { createElement, Fragment, type ReactNode, useEffect, useMemo, useState } from \"react\";\nimport { AiIcon } from \"./ai-icon\";\nimport { isPowerLogsWorkspace, usePowerLogsWorkspace } from \"./ai-logs-sql\";\n\nconst markdown = new MarkdownIt({ html: false, linkify: true, breaks: true });\nconst markdownTags = new Set([\n \"p\",\n \"h1\",\n \"h2\",\n \"h3\",\n \"h4\",\n \"h5\",\n \"h6\",\n \"ul\",\n \"ol\",\n \"li\",\n \"blockquote\",\n \"table\",\n \"thead\",\n \"tbody\",\n \"tr\",\n \"th\",\n \"td\",\n \"strong\",\n \"em\",\n \"s\",\n \"a\",\n]);\n\nfunction externalLink(value: string | number | null): string | undefined {\n if (typeof value !== \"string\" || !value) return;\n try {\n const url = new URL(value);\n if ([\"https:\", \"http:\", \"mailto:\"].includes(url.protocol) && !url.username && !url.password) return url.href;\n } catch {}\n return;\n}\n\nfunction renderTokens(tokens: Token[]): ReactNode[] {\n type Container = { token?: Token; key: number; children: ReactNode[] };\n const stack: Container[] = [{ key: 0, children: [] }];\n const append = (node: ReactNode) => stack[stack.length - 1].children.push(node);\n tokens.forEach((token, index) => {\n if (token.nesting === 1) {\n stack.push({ token, key: index, children: [] });\n return;\n }\n if (token.nesting === -1) {\n if (stack.length === 1) return;\n const container = stack.pop()!;\n const opening = container.token!;\n const props: Record<string, unknown> = { key: container.key };\n let tag = markdownTags.has(opening.tag) && !opening.hidden ? opening.tag : Fragment;\n if (tag === \"a\") {\n const href = externalLink(opening.attrGet(\"href\"));\n if (!href) tag = Fragment;\n else {\n props.href = href;\n props.title = opening.attrGet(\"title\") ?? undefined;\n props.rel = \"noopener noreferrer\";\n props.target = \"_blank\";\n const open = (event: React.MouseEvent<HTMLAnchorElement>) => {\n event.preventDefault();\n if (event.type === \"auxclick\" && event.button !== 1) return;\n void shell.openExternal(href).catch(() => {});\n };\n props.onClick = open;\n props.onAuxClick = open;\n }\n }\n if (tag === \"ol\") {\n const start = Number(opening.attrGet(\"start\"));\n if (Number.isSafeInteger(start) && start > 0) props.start = start;\n }\n if (tag === \"th\" || tag === \"td\") {\n const alignment = String(opening.attrGet(\"style\") ?? \"\").match(/^text-align:(left|right|center)$/)?.[1];\n if (alignment) props.style = { textAlign: alignment };\n }\n append(createElement(tag, props, ...container.children));\n return;\n }\n switch (token.type) {\n case \"inline\":\n append(<Fragment key={index}>{renderTokens(token.children ?? [])}</Fragment>);\n break;\n case \"code_inline\":\n append(<code key={index}>{token.content}</code>);\n break;\n case \"fence\":\n case \"code_block\":\n append(<CodeBlock key={index} language={token.info.trim().split(/\\s+/)[0]} text={token.content} />);\n break;\n case \"hardbreak\":\n case \"softbreak\":\n append(<br key={index} />);\n break;\n case \"hr\":\n append(<hr key={index} />);\n break;\n default:\n append(<Fragment key={index}>{token.content}</Fragment>);\n }\n });\n return stack[0].children;\n}\n\nexport function terminalInsertText(text: string): string | undefined {\n const command = text.replace(/^[\\r\\n]+|[\\r\\n]+$/g, \"\");\n // surrounding line endings are formatting, embedded control characters must never reach the terminal\n if (!command.trim() || /[\\u0000-\\u001f\\u007f-\\u009f\\u2028\\u2029]/u.test(command)) return undefined;\n return command;\n}\n\nfunction visibleTerminalId(): string | undefined {\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 if (!visible) continue;\n const id = element.dataset.testid?.slice(prefix.length);\n if (!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\nfunction useActiveTerminalId(): string | undefined {\n const [terminalId, setTerminalId] = useState<string>();\n useEffect(() => {\n let stop: (() => void) | undefined;\n const update = () => {\n stop?.();\n stop = autorun(() => setTerminalId(visibleTerminalId()));\n };\n update();\n const observer = new MutationObserver(update);\n observer.observe(document.body, {\n childList: true,\n subtree: true,\n attributes: true,\n attributeFilter: [\"class\", \"style\", \"hidden\", \"aria-hidden\", \"data-testid\"],\n });\n return () => {\n observer.disconnect();\n stop?.();\n };\n }, []);\n return terminalId;\n}\n\nfunction CodeBlock({ text, language }: { text: string; language: string }) {\n const [feedback, setFeedback] = useState(\"\");\n const terminalId = useActiveTerminalId();\n const [inserting, setInserting] = useState(false);\n const shell = [\"\", \"bash\", \"sh\", \"shell\", \"zsh\", \"console\", \"terminal\"].includes(language.toLowerCase());\n const command = terminalInsertText(text);\n const logsWorkspace = usePowerLogsWorkspace();\n const sqlDraft = [\"sql\", \"sqlite\"].includes(language.toLowerCase()) && logsWorkspace;\n const insert = async () => {\n const activeTerminal = visibleTerminalId();\n if (!shell || !command || !activeTerminal || inserting) return;\n setInserting(true);\n try {\n await Renderer.Component.terminalStore.sendCommand(command, { enter: false, tabId: activeTerminal });\n setFeedback(\"Inserted into terminal. Review the command before running it.\");\n } catch {\n setFeedback(\"Unable to insert into terminal.\");\n } finally {\n setInserting(false);\n }\n };\n return (\n <div className=\"power-ai-code\">\n <div className=\"power-ai-code-toolbar\">\n <span>{language || \"code\"}</span>\n <div>\n <button\n type=\"button\"\n aria-label=\"Copy code\"\n title=\"Copy code to clipboard\"\n onClick={() => {\n try {\n clipboard.writeText(text);\n setFeedback(\"Copied\");\n } catch {\n setFeedback(\"Unable to copy code.\");\n }\n }}\n >\n <AiIcon material=\"content_copy\" size={14} /> Copy\n </button>\n {sqlDraft && (\n <button\n type=\"button\"\n aria-label=\"Insert into SQL\"\n title=\"Insert into the SQL editor without running\"\n disabled={!text.trim() || text.length > 65536}\n onClick={() => {\n if (!isPowerLogsWorkspace() || !text.trim() || text.length > 65536) return;\n window.dispatchEvent(new CustomEvent(\"power-logs-sql-draft\", { detail: { sql: text } }));\n window.dispatchEvent(new Event(\"power-ai-close\"));\n }}\n >\n <AiIcon material=\"post_add\" size={14} /> Insert into SQL\n </button>\n )}\n {shell && terminalId && (\n <button\n type=\"button\"\n aria-label=\"Insert into terminal\"\n disabled={!command || !terminalId || inserting}\n title={\n !command\n ? \"Only a single line without control characters can be inserted\"\n : !terminalId\n ? \"Focus an open terminal tab to insert\"\n : \"Insert without running\"\n }\n onClick={() => void insert()}\n >\n <AiIcon material=\"terminal\" size={14} /> Insert\n </button>\n )}\n </div>\n </div>\n <pre>\n <code>{text}</code>\n </pre>\n {shell && !command && (\n <div className=\"power-ai-code-hint\">Terminal insertion requires a single line without control characters.</div>\n )}\n <div role=\"status\" className=\"power-ai-code-feedback\">\n {feedback}\n </div>\n </div>\n );\n}\n\nexport function AiMessageContent({ text }: { text: string }) {\n const content = useMemo(() => renderTokens(markdown.parse(text, {})), [text]);\n return <div className=\"power-ai-markdown\">{content}</div>;\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"ai-message.js","names":[],"sources":["../../src/renderer/ai-message.tsx"],"sourcesContent":["import { Renderer } from \"@freelensapp/extensions\";\nimport { clipboard, shell } from \"electron\";\nimport MarkdownIt, { type Token } from \"markdown-it\";\nimport { autorun } from \"mobx\";\nimport { createElement, Fragment, type ReactNode, useEffect, useMemo, useState } from \"react\";\nimport { AiIcon } from \"./ai-icon\";\nimport { isPowerLogsWorkspace, usePowerLogsWorkspace } from \"./ai-logs-sql\";\nimport { NativeTooltip } from \"./native-tooltip\";\n\nconst markdown = new MarkdownIt({ html: false, linkify: true, breaks: true });\nconst markdownTags = new Set([\n \"p\",\n \"h1\",\n \"h2\",\n \"h3\",\n \"h4\",\n \"h5\",\n \"h6\",\n \"ul\",\n \"ol\",\n \"li\",\n \"blockquote\",\n \"table\",\n \"thead\",\n \"tbody\",\n \"tr\",\n \"th\",\n \"td\",\n \"strong\",\n \"em\",\n \"s\",\n \"a\",\n]);\n\nfunction externalLink(value: string | number | null): string | undefined {\n if (typeof value !== \"string\" || !value) return;\n try {\n const url = new URL(value);\n if ([\"https:\", \"http:\", \"mailto:\"].includes(url.protocol) && !url.username && !url.password) return url.href;\n } catch {}\n return;\n}\n\nfunction renderTokens(tokens: Token[]): ReactNode[] {\n type Container = { token?: Token; key: number; children: ReactNode[] };\n const stack: Container[] = [{ key: 0, children: [] }];\n const append = (node: ReactNode) => stack[stack.length - 1].children.push(node);\n tokens.forEach((token, index) => {\n if (token.nesting === 1) {\n stack.push({ token, key: index, children: [] });\n return;\n }\n if (token.nesting === -1) {\n if (stack.length === 1) return;\n const container = stack.pop()!;\n const opening = container.token!;\n const props: Record<string, unknown> = { key: container.key };\n let tag = markdownTags.has(opening.tag) && !opening.hidden ? opening.tag : Fragment;\n if (tag === \"a\") {\n const href = externalLink(opening.attrGet(\"href\"));\n if (!href) tag = Fragment;\n else {\n props.href = href;\n props.rel = \"noopener noreferrer\";\n props.target = \"_blank\";\n const open = (event: React.MouseEvent<HTMLAnchorElement>) => {\n event.preventDefault();\n if (event.type === \"auxclick\" && event.button !== 1) return;\n void shell.openExternal(href).catch(() => {});\n };\n props.onClick = open;\n props.onAuxClick = open;\n }\n }\n if (tag === \"ol\") {\n const start = Number(opening.attrGet(\"start\"));\n if (Number.isSafeInteger(start) && start > 0) props.start = start;\n }\n if (tag === \"th\" || tag === \"td\") {\n const alignment = String(opening.attrGet(\"style\") ?? \"\").match(/^text-align:(left|right|center)$/)?.[1];\n if (alignment) props.style = { textAlign: alignment };\n }\n const element = createElement(tag, props, ...container.children);\n const title = tag === \"a\" ? opening.attrGet(\"title\") : undefined;\n append(\n title ? (\n <NativeTooltip key={container.key} title={title}>\n {element}\n </NativeTooltip>\n ) : (\n element\n ),\n );\n return;\n }\n switch (token.type) {\n case \"inline\":\n append(<Fragment key={index}>{renderTokens(token.children ?? [])}</Fragment>);\n break;\n case \"code_inline\":\n append(<code key={index}>{token.content}</code>);\n break;\n case \"fence\":\n case \"code_block\":\n append(<CodeBlock key={index} language={token.info.trim().split(/\\s+/)[0]} text={token.content} />);\n break;\n case \"hardbreak\":\n case \"softbreak\":\n append(<br key={index} />);\n break;\n case \"hr\":\n append(<hr key={index} />);\n break;\n default:\n append(<Fragment key={index}>{token.content}</Fragment>);\n }\n });\n return stack[0].children;\n}\n\nexport function terminalInsertText(text: string): string | undefined {\n const command = text.replace(/^[\\r\\n]+|[\\r\\n]+$/g, \"\");\n // surrounding line endings are formatting, embedded control characters must never reach the terminal\n if (!command.trim() || /[\\u0000-\\u001f\\u007f-\\u009f\\u2028\\u2029]/u.test(command)) return undefined;\n return command;\n}\n\nfunction visibleTerminalId(): string | undefined {\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 if (!visible) continue;\n const id = element.dataset.testid?.slice(prefix.length);\n if (!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\nfunction useActiveTerminalId(): string | undefined {\n const [terminalId, setTerminalId] = useState<string>();\n useEffect(() => {\n let stop: (() => void) | undefined;\n const update = () => {\n stop?.();\n stop = autorun(() => setTerminalId(visibleTerminalId()));\n };\n update();\n const observer = new MutationObserver(update);\n observer.observe(document.body, {\n childList: true,\n subtree: true,\n attributes: true,\n attributeFilter: [\"class\", \"style\", \"hidden\", \"aria-hidden\", \"data-testid\"],\n });\n return () => {\n observer.disconnect();\n stop?.();\n };\n }, []);\n return terminalId;\n}\n\nfunction CodeBlock({ text, language }: { text: string; language: string }) {\n const [feedback, setFeedback] = useState(\"\");\n const terminalId = useActiveTerminalId();\n const [inserting, setInserting] = useState(false);\n const shell = [\"\", \"bash\", \"sh\", \"shell\", \"zsh\", \"console\", \"terminal\"].includes(language.toLowerCase());\n const command = terminalInsertText(text);\n const logsWorkspace = usePowerLogsWorkspace();\n const sqlDraft = [\"sql\", \"sqlite\"].includes(language.toLowerCase()) && logsWorkspace;\n const insert = async () => {\n const activeTerminal = visibleTerminalId();\n if (!shell || !command || !activeTerminal || inserting) return;\n setInserting(true);\n try {\n await Renderer.Component.terminalStore.sendCommand(command, { enter: false, tabId: activeTerminal });\n setFeedback(\"Inserted into terminal. Review the command before running it.\");\n } catch {\n setFeedback(\"Unable to insert into terminal.\");\n } finally {\n setInserting(false);\n }\n };\n return (\n <div className=\"power-ai-code\">\n <div className=\"power-ai-code-toolbar\">\n <span>{language || \"code\"}</span>\n <div>\n <NativeTooltip title=\"Copy code to clipboard\">\n <button\n type=\"button\"\n aria-label=\"Copy code\"\n onClick={() => {\n try {\n clipboard.writeText(text);\n setFeedback(\"Copied\");\n } catch {\n setFeedback(\"Unable to copy code.\");\n }\n }}\n >\n <AiIcon material=\"content_copy\" size={14} /> Copy\n </button>\n </NativeTooltip>\n {sqlDraft && (\n <NativeTooltip title=\"Insert into the SQL editor without running\">\n <button\n type=\"button\"\n aria-label=\"Insert into SQL\"\n disabled={!text.trim() || text.length > 65536}\n onClick={() => {\n if (!isPowerLogsWorkspace() || !text.trim() || text.length > 65536) return;\n window.dispatchEvent(new CustomEvent(\"power-logs-sql-draft\", { detail: { sql: text } }));\n window.dispatchEvent(new Event(\"power-ai-close\"));\n }}\n >\n <AiIcon material=\"post_add\" size={14} /> Insert into SQL\n </button>\n </NativeTooltip>\n )}\n {shell && terminalId && (\n <NativeTooltip\n title={\n !command\n ? \"Only a single line without control characters can be inserted\"\n : !terminalId\n ? \"Focus an open terminal tab to insert\"\n : \"Insert without running\"\n }\n >\n <button\n type=\"button\"\n aria-label=\"Insert into terminal\"\n disabled={!command || !terminalId || inserting}\n onClick={() => void insert()}\n >\n <AiIcon material=\"terminal\" size={14} /> Insert\n </button>\n </NativeTooltip>\n )}\n </div>\n </div>\n <pre>\n <code>{text}</code>\n </pre>\n {shell && !command && (\n <div className=\"power-ai-code-hint\">Terminal insertion requires a single line without control characters.</div>\n )}\n <div role=\"status\" className=\"power-ai-code-feedback\">\n {feedback}\n </div>\n </div>\n );\n}\n\nexport function AiMessageContent({ text }: { text: string }) {\n const content = useMemo(() => renderTokens(markdown.parse(text, {})), [text]);\n return <div className=\"power-ai-markdown\">{content}</div>;\n}\n"],"mappings":"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"}
|
|
@@ -1,41 +1,48 @@
|
|
|
1
1
|
const require_jsx_runtime = require("./_virtual/_global-external_react/jsx-runtime.js");
|
|
2
|
+
const require_native_tooltip = require("./native-tooltip.js");
|
|
2
3
|
const require_claude = require("./assets/claude.js");
|
|
3
4
|
//#region src/renderer/ai-provider-icon.tsx
|
|
4
5
|
function AiProviderIcon({ provider, size = 16 }) {
|
|
5
|
-
if (provider === "codex") return /* @__PURE__ */ require_jsx_runtime.
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
6
|
+
if (provider === "codex") return /* @__PURE__ */ require_jsx_runtime.jsx(require_native_tooltip.NativeTooltip, {
|
|
7
|
+
title: "Codex",
|
|
8
|
+
children: /* @__PURE__ */ require_jsx_runtime.jsx("svg", {
|
|
9
|
+
className: "power-ai-provider-icon",
|
|
10
|
+
"data-provider": "codex",
|
|
11
|
+
width: size,
|
|
12
|
+
height: size,
|
|
13
|
+
viewBox: "0 0 24 24",
|
|
14
|
+
role: "img",
|
|
15
|
+
"aria-label": "Codex",
|
|
16
|
+
fill: "currentColor",
|
|
17
|
+
style: {
|
|
18
|
+
color: "var(--textColorPrimary)",
|
|
19
|
+
flexShrink: 0,
|
|
20
|
+
verticalAlign: "middle"
|
|
21
|
+
},
|
|
22
|
+
children: /* @__PURE__ */ require_jsx_runtime.jsx("path", {
|
|
23
|
+
fillRule: "evenodd",
|
|
24
|
+
d: "M9.205 8.658v-2.26c0-.19.072-.333.238-.428l4.543-2.616c.619-.357 1.356-.523 2.117-.523 2.854 0 4.662 2.212 4.662 4.566 0 .167 0 .357-.024.547l-4.71-2.759a.797.797 0 00-.856 0l-5.97 3.473zm10.609 8.8V12.06c0-.333-.143-.57-.429-.737l-5.97-3.473 1.95-1.118a.433.433 0 01.476 0l4.543 2.617c1.309.76 2.189 2.378 2.189 3.948 0 1.808-1.07 3.473-2.76 4.163zM7.802 12.703l-1.95-1.142c-.167-.095-.239-.238-.239-.428V5.899c0-2.545 1.95-4.472 4.591-4.472 1 0 1.927.333 2.712.928L8.23 5.067c-.285.166-.428.404-.428.737v6.898zM12 15.128l-2.795-1.57v-3.33L12 8.658l2.795 1.57v3.33L12 15.128zm1.796 7.23c-1 0-1.927-.332-2.712-.927l4.686-2.712c.285-.166.428-.404.428-.737v-6.898l1.974 1.142c.167.095.238.238.238.428v5.233c0 2.545-1.974 4.472-4.614 4.472zm-5.637-5.303l-4.544-2.617c-1.308-.761-2.188-2.378-2.188-3.948A4.482 4.482 0 014.21 6.327v5.423c0 .333.143.571.428.738l5.947 3.449-1.95 1.118a.432.432 0 01-.476 0zm-.262 3.9c-2.688 0-4.662-2.021-4.662-4.519 0-.19.024-.38.047-.57l4.686 2.71c.286.167.571.167.856 0l5.97-3.448v2.26c0 .19-.07.333-.237.428l-4.543 2.616c-.619.357-1.356.523-2.117.523zm5.899 2.83a5.947 5.947 0 005.827-4.756C22.287 18.339 24 15.84 24 13.296c0-1.665-.713-3.282-1.998-4.448.119-.5.19-.999.19-1.498 0-3.401-2.759-5.947-5.946-5.947-.642 0-1.26.095-1.88.31A5.962 5.962 0 0010.205 0a5.947 5.947 0 00-5.827 4.757C1.713 5.447 0 7.945 0 10.49c0 1.666.713 3.283 1.998 4.448-.119.5-.19 1-.19 1.499 0 3.401 2.759 5.946 5.946 5.946.642 0 1.26-.095 1.88-.309a5.96 5.96 0 004.162 1.713z"
|
|
25
|
+
})
|
|
26
|
+
})
|
|
22
27
|
});
|
|
23
|
-
return /* @__PURE__ */ require_jsx_runtime.jsx(
|
|
24
|
-
className: "power-ai-provider-icon",
|
|
25
|
-
"data-provider": provider,
|
|
26
|
-
src: require_claude.default,
|
|
27
|
-
width: size,
|
|
28
|
-
height: size,
|
|
28
|
+
return /* @__PURE__ */ require_jsx_runtime.jsx(require_native_tooltip.NativeTooltip, {
|
|
29
29
|
title: provider === "claude" ? "Claude" : "Codex",
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
30
|
+
children: /* @__PURE__ */ require_jsx_runtime.jsx("img", {
|
|
31
|
+
className: "power-ai-provider-icon",
|
|
32
|
+
"data-provider": provider,
|
|
33
|
+
src: require_claude.default,
|
|
34
|
+
width: size,
|
|
35
|
+
height: size,
|
|
36
|
+
alt: "",
|
|
37
|
+
"aria-hidden": "true",
|
|
38
|
+
draggable: false,
|
|
39
|
+
style: {
|
|
40
|
+
display: "inline-block",
|
|
41
|
+
flexShrink: 0,
|
|
42
|
+
objectFit: "contain",
|
|
43
|
+
verticalAlign: "middle"
|
|
44
|
+
}
|
|
45
|
+
})
|
|
39
46
|
});
|
|
40
47
|
}
|
|
41
48
|
//#endregion
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ai-provider-icon.js","names":[],"sources":["../../src/renderer/ai-provider-icon.tsx"],"sourcesContent":["import claudeIcon from \"./assets/claude.svg?inline\";\n\nexport function AiProviderIcon({ provider, size = 16 }: { provider: \"codex\" | \"claude\"; size?: number }) {\n if (provider === \"codex\")\n return (\n <svg\n
|
|
1
|
+
{"version":3,"file":"ai-provider-icon.js","names":[],"sources":["../../src/renderer/ai-provider-icon.tsx"],"sourcesContent":["import claudeIcon from \"./assets/claude.svg?inline\";\nimport { NativeTooltip } from \"./native-tooltip\";\n\nexport function AiProviderIcon({ provider, size = 16 }: { provider: \"codex\" | \"claude\"; size?: number }) {\n if (provider === \"codex\")\n return (\n <NativeTooltip title=\"Codex\">\n <svg\n className=\"power-ai-provider-icon\"\n data-provider=\"codex\"\n width={size}\n height={size}\n viewBox=\"0 0 24 24\"\n role=\"img\"\n aria-label=\"Codex\"\n fill=\"currentColor\"\n style={{ color: \"var(--textColorPrimary)\", flexShrink: 0, verticalAlign: \"middle\" }}\n >\n <path\n fillRule=\"evenodd\"\n d=\"M9.205 8.658v-2.26c0-.19.072-.333.238-.428l4.543-2.616c.619-.357 1.356-.523 2.117-.523 2.854 0 4.662 2.212 4.662 4.566 0 .167 0 .357-.024.547l-4.71-2.759a.797.797 0 00-.856 0l-5.97 3.473zm10.609 8.8V12.06c0-.333-.143-.57-.429-.737l-5.97-3.473 1.95-1.118a.433.433 0 01.476 0l4.543 2.617c1.309.76 2.189 2.378 2.189 3.948 0 1.808-1.07 3.473-2.76 4.163zM7.802 12.703l-1.95-1.142c-.167-.095-.239-.238-.239-.428V5.899c0-2.545 1.95-4.472 4.591-4.472 1 0 1.927.333 2.712.928L8.23 5.067c-.285.166-.428.404-.428.737v6.898zM12 15.128l-2.795-1.57v-3.33L12 8.658l2.795 1.57v3.33L12 15.128zm1.796 7.23c-1 0-1.927-.332-2.712-.927l4.686-2.712c.285-.166.428-.404.428-.737v-6.898l1.974 1.142c.167.095.238.238.238.428v5.233c0 2.545-1.974 4.472-4.614 4.472zm-5.637-5.303l-4.544-2.617c-1.308-.761-2.188-2.378-2.188-3.948A4.482 4.482 0 014.21 6.327v5.423c0 .333.143.571.428.738l5.947 3.449-1.95 1.118a.432.432 0 01-.476 0zm-.262 3.9c-2.688 0-4.662-2.021-4.662-4.519 0-.19.024-.38.047-.57l4.686 2.71c.286.167.571.167.856 0l5.97-3.448v2.26c0 .19-.07.333-.237.428l-4.543 2.616c-.619.357-1.356.523-2.117.523zm5.899 2.83a5.947 5.947 0 005.827-4.756C22.287 18.339 24 15.84 24 13.296c0-1.665-.713-3.282-1.998-4.448.119-.5.19-.999.19-1.498 0-3.401-2.759-5.947-5.946-5.947-.642 0-1.26.095-1.88.31A5.962 5.962 0 0010.205 0a5.947 5.947 0 00-5.827 4.757C1.713 5.447 0 7.945 0 10.49c0 1.666.713 3.283 1.998 4.448-.119.5-.19 1-.19 1.499 0 3.401 2.759 5.946 5.946 5.946.642 0 1.26-.095 1.88-.309a5.96 5.96 0 004.162 1.713z\"\n />\n </svg>\n </NativeTooltip>\n );\n return (\n <NativeTooltip title={provider === \"claude\" ? \"Claude\" : \"Codex\"}>\n <img\n className=\"power-ai-provider-icon\"\n data-provider={provider}\n src={claudeIcon}\n width={size}\n height={size}\n alt=\"\"\n aria-hidden=\"true\"\n draggable={false}\n style={{ display: \"inline-block\", flexShrink: 0, objectFit: \"contain\", verticalAlign: \"middle\" }}\n />\n </NativeTooltip>\n );\n}\n"],"mappings":";;;;AAGA,SAAgB,eAAe,EAAE,UAAU,OAAO,MAAuD;CACvG,IAAI,aAAa,SACf,OACE,oCAAA,IAAC,uBAAA,eAAD;EAAe,OAAM;YACnB,oCAAA,IAAC,OAAD;GACE,WAAU;GACV,iBAAc;GACd,OAAO;GACP,QAAQ;GACR,SAAQ;GACR,MAAK;GACL,cAAW;GACX,MAAK;GACL,OAAO;IAAE,OAAO;IAA2B,YAAY;IAAG,eAAe;GAAS;aAElF,oCAAA,IAAC,QAAD;IACE,UAAS;IACT,GAAE;GACH,CAAA;EACE,CAAA;CACQ,CAAA;CAEnB,OACE,oCAAA,IAAC,uBAAA,eAAD;EAAe,OAAO,aAAa,WAAW,WAAW;YACvD,oCAAA,IAAC,OAAD;GACE,WAAU;GACV,iBAAe;GACf,KAAK,eAAA;GACL,OAAO;GACP,QAAQ;GACR,KAAI;GACJ,eAAY;GACZ,WAAW;GACX,OAAO;IAAE,SAAS;IAAgB,YAAY;IAAG,WAAW;IAAW,eAAe;GAAS;EAChG,CAAA;CACY,CAAA;AAEnB"}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
const require__global_external_react = require("./_virtual/_global-external_react.js");
|
|
2
2
|
const require_jsx_runtime = require("./_virtual/_global-external_react/jsx-runtime.js");
|
|
3
|
+
const require_native_tooltip = require("./native-tooltip.js");
|
|
3
4
|
function clampAiPanelWidth(width, available) {
|
|
4
5
|
const maximum = Math.max(1, available);
|
|
5
6
|
return Math.min(maximum, Math.max(Math.min(360, maximum), Number.isFinite(width) ? width : 560));
|
|
@@ -40,44 +41,46 @@ function AiResizeHandle({ width, available, onChange }) {
|
|
|
40
41
|
window.removeEventListener("blur", cancel);
|
|
41
42
|
};
|
|
42
43
|
}, []);
|
|
43
|
-
return /* @__PURE__ */ require_jsx_runtime.jsx(
|
|
44
|
-
role: "separator",
|
|
45
|
-
tabIndex: 0,
|
|
46
|
-
"aria-label": "Resize AI assistant",
|
|
47
|
-
"aria-orientation": "vertical",
|
|
48
|
-
"aria-valuemin": Math.min(360, available),
|
|
49
|
-
"aria-valuemax": Math.max(1, available),
|
|
50
|
-
"aria-valuenow": width,
|
|
44
|
+
return /* @__PURE__ */ require_jsx_runtime.jsx(require_native_tooltip.NativeTooltip, {
|
|
51
45
|
title: "Drag to resize · Click to reset width",
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
46
|
+
children: /* @__PURE__ */ require_jsx_runtime.jsx("div", {
|
|
47
|
+
role: "separator",
|
|
48
|
+
tabIndex: 0,
|
|
49
|
+
"aria-label": "Resize AI assistant",
|
|
50
|
+
"aria-orientation": "vertical",
|
|
51
|
+
"aria-valuemin": Math.min(360, available),
|
|
52
|
+
"aria-valuemax": Math.max(1, available),
|
|
53
|
+
"aria-valuenow": width,
|
|
54
|
+
className: "power-ai-resize-handle",
|
|
55
|
+
onPointerDown: (event) => {
|
|
56
|
+
if (event.button !== 0 || drag.current) return;
|
|
57
|
+
event.preventDefault();
|
|
58
|
+
event.stopPropagation();
|
|
59
|
+
drag.current = {
|
|
60
|
+
x: event.clientX,
|
|
61
|
+
y: event.clientY,
|
|
62
|
+
width,
|
|
63
|
+
movement: 0,
|
|
64
|
+
pointerId: event.pointerId
|
|
65
|
+
};
|
|
66
|
+
event.currentTarget.focus();
|
|
67
|
+
event.currentTarget.setPointerCapture?.(event.pointerId);
|
|
68
|
+
},
|
|
69
|
+
onClick: (event) => {
|
|
70
|
+
event.preventDefault();
|
|
71
|
+
event.stopPropagation();
|
|
72
|
+
},
|
|
73
|
+
onKeyDown: (event) => {
|
|
74
|
+
if (![
|
|
75
|
+
"ArrowLeft",
|
|
76
|
+
"ArrowRight",
|
|
77
|
+
"Home"
|
|
78
|
+
].includes(event.key)) return;
|
|
79
|
+
event.preventDefault();
|
|
80
|
+
event.stopPropagation();
|
|
81
|
+
onChange(event.key === "Home" ? 560 : clampAiPanelWidth(width + (event.key === "ArrowLeft" ? 20 : -20), available));
|
|
82
|
+
}
|
|
83
|
+
})
|
|
81
84
|
});
|
|
82
85
|
}
|
|
83
86
|
//#endregion
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ai-resize.js","names":[],"sources":["../../src/renderer/ai-resize.tsx"],"sourcesContent":["import { useEffect, useRef } from \"react\";\n\nexport const DEFAULT_AI_PANEL_WIDTH = 560;\nexport const MIN_AI_PANEL_WIDTH = 360;\n\nexport function clampAiPanelWidth(width: number, available: number): number {\n const maximum = Math.max(1, available);\n return Math.min(\n maximum,\n Math.max(Math.min(MIN_AI_PANEL_WIDTH, maximum), Number.isFinite(width) ? width : DEFAULT_AI_PANEL_WIDTH),\n );\n}\n\nexport function AiResizeHandle({\n width,\n available,\n onChange,\n}: {\n width: number;\n available: number;\n onChange: (width: number) => void;\n}) {\n const drag = useRef<{ x: number; y: number; width: number; movement: number; pointerId: number }>();\n const change = useRef(onChange);\n const limit = useRef(available);\n change.current = onChange;\n limit.current = available;\n useEffect(() => {\n const move = (event: PointerEvent) => {\n const start = drag.current;\n if (!start || event.pointerId !== start.pointerId) return;\n const delta = start.x - event.clientX;\n start.movement = Math.max(start.movement, Math.hypot(delta, start.y - event.clientY));\n if (start.movement > 4) change.current(clampAiPanelWidth(start.width + delta, limit.current));\n };\n const end = (event: PointerEvent) => {\n const start = drag.current;\n if (!start || event.pointerId !== start.pointerId) return;\n start.movement = Math.max(start.movement, Math.hypot(start.x - event.clientX, start.y - event.clientY));\n if (start.movement <= 4) change.current(DEFAULT_AI_PANEL_WIDTH);\n else change.current(clampAiPanelWidth(start.width + start.x - event.clientX, limit.current));\n drag.current = undefined;\n };\n const cancel = () => {\n drag.current = undefined;\n };\n window.addEventListener(\"pointermove\", move);\n window.addEventListener(\"pointerup\", end);\n window.addEventListener(\"pointercancel\", cancel);\n window.addEventListener(\"blur\", cancel);\n return () => {\n window.removeEventListener(\"pointermove\", move);\n window.removeEventListener(\"pointerup\", end);\n window.removeEventListener(\"pointercancel\", cancel);\n window.removeEventListener(\"blur\", cancel);\n };\n }, []);\n return (\n <div\n
|
|
1
|
+
{"version":3,"file":"ai-resize.js","names":[],"sources":["../../src/renderer/ai-resize.tsx"],"sourcesContent":["import { useEffect, useRef } from \"react\";\nimport { NativeTooltip } from \"./native-tooltip\";\n\nexport const DEFAULT_AI_PANEL_WIDTH = 560;\nexport const MIN_AI_PANEL_WIDTH = 360;\n\nexport function clampAiPanelWidth(width: number, available: number): number {\n const maximum = Math.max(1, available);\n return Math.min(\n maximum,\n Math.max(Math.min(MIN_AI_PANEL_WIDTH, maximum), Number.isFinite(width) ? width : DEFAULT_AI_PANEL_WIDTH),\n );\n}\n\nexport function AiResizeHandle({\n width,\n available,\n onChange,\n}: {\n width: number;\n available: number;\n onChange: (width: number) => void;\n}) {\n const drag = useRef<{ x: number; y: number; width: number; movement: number; pointerId: number }>();\n const change = useRef(onChange);\n const limit = useRef(available);\n change.current = onChange;\n limit.current = available;\n useEffect(() => {\n const move = (event: PointerEvent) => {\n const start = drag.current;\n if (!start || event.pointerId !== start.pointerId) return;\n const delta = start.x - event.clientX;\n start.movement = Math.max(start.movement, Math.hypot(delta, start.y - event.clientY));\n if (start.movement > 4) change.current(clampAiPanelWidth(start.width + delta, limit.current));\n };\n const end = (event: PointerEvent) => {\n const start = drag.current;\n if (!start || event.pointerId !== start.pointerId) return;\n start.movement = Math.max(start.movement, Math.hypot(start.x - event.clientX, start.y - event.clientY));\n if (start.movement <= 4) change.current(DEFAULT_AI_PANEL_WIDTH);\n else change.current(clampAiPanelWidth(start.width + start.x - event.clientX, limit.current));\n drag.current = undefined;\n };\n const cancel = () => {\n drag.current = undefined;\n };\n window.addEventListener(\"pointermove\", move);\n window.addEventListener(\"pointerup\", end);\n window.addEventListener(\"pointercancel\", cancel);\n window.addEventListener(\"blur\", cancel);\n return () => {\n window.removeEventListener(\"pointermove\", move);\n window.removeEventListener(\"pointerup\", end);\n window.removeEventListener(\"pointercancel\", cancel);\n window.removeEventListener(\"blur\", cancel);\n };\n }, []);\n return (\n <NativeTooltip title=\"Drag to resize · Click to reset width\">\n <div\n role=\"separator\"\n tabIndex={0}\n aria-label=\"Resize AI assistant\"\n aria-orientation=\"vertical\"\n aria-valuemin={Math.min(MIN_AI_PANEL_WIDTH, available)}\n aria-valuemax={Math.max(1, available)}\n aria-valuenow={width}\n className=\"power-ai-resize-handle\"\n onPointerDown={(event) => {\n if (event.button !== 0 || drag.current) return;\n event.preventDefault();\n event.stopPropagation();\n drag.current = { x: event.clientX, y: event.clientY, width, movement: 0, pointerId: event.pointerId };\n event.currentTarget.focus();\n event.currentTarget.setPointerCapture?.(event.pointerId);\n }}\n onClick={(event) => {\n event.preventDefault();\n event.stopPropagation();\n }}\n onKeyDown={(event) => {\n if (![\"ArrowLeft\", \"ArrowRight\", \"Home\"].includes(event.key)) return;\n event.preventDefault();\n event.stopPropagation();\n onChange(\n event.key === \"Home\"\n ? DEFAULT_AI_PANEL_WIDTH\n : clampAiPanelWidth(width + (event.key === \"ArrowLeft\" ? 20 : -20), available),\n );\n }}\n />\n </NativeTooltip>\n );\n}\n"],"mappings":";;;AAMA,SAAgB,kBAAkB,OAAe,WAA2B;CAC1E,MAAM,UAAU,KAAK,IAAI,GAAG,SAAS;CACrC,OAAO,KAAK,IACV,SACA,KAAK,IAAI,KAAK,IAAA,KAAwB,OAAO,GAAG,OAAO,SAAS,KAAK,IAAI,QAAA,GAA8B,CACzG;AACF;AAEA,SAAgB,eAAe,EAC7B,OACA,WACA,YAKC;CACD,MAAM,OAAO,+BAAA,OAAqF;CAClG,MAAM,SAAS,+BAAA,OAAO,QAAQ;CAC9B,MAAM,QAAQ,+BAAA,OAAO,SAAS;CAC9B,OAAO,UAAU;CACjB,MAAM,UAAU;CAChB,+BAAA,gBAAgB;EACd,MAAM,QAAQ,UAAwB;GACpC,MAAM,QAAQ,KAAK;GACnB,IAAI,CAAC,SAAS,MAAM,cAAc,MAAM,WAAW;GACnD,MAAM,QAAQ,MAAM,IAAI,MAAM;GAC9B,MAAM,WAAW,KAAK,IAAI,MAAM,UAAU,KAAK,MAAM,OAAO,MAAM,IAAI,MAAM,OAAO,CAAC;GACpF,IAAI,MAAM,WAAW,GAAG,OAAO,QAAQ,kBAAkB,MAAM,QAAQ,OAAO,MAAM,OAAO,CAAC;EAC9F;EACA,MAAM,OAAO,UAAwB;GACnC,MAAM,QAAQ,KAAK;GACnB,IAAI,CAAC,SAAS,MAAM,cAAc,MAAM,WAAW;GACnD,MAAM,WAAW,KAAK,IAAI,MAAM,UAAU,KAAK,MAAM,MAAM,IAAI,MAAM,SAAS,MAAM,IAAI,MAAM,OAAO,CAAC;GACtG,IAAI,MAAM,YAAY,GAAG,OAAO,QAAA,GAA8B;QACzD,OAAO,QAAQ,kBAAkB,MAAM,QAAQ,MAAM,IAAI,MAAM,SAAS,MAAM,OAAO,CAAC;GAC3F,KAAK,UAAU,KAAA;EACjB;EACA,MAAM,eAAe;GACnB,KAAK,UAAU,KAAA;EACjB;EACA,OAAO,iBAAiB,eAAe,IAAI;EAC3C,OAAO,iBAAiB,aAAa,GAAG;EACxC,OAAO,iBAAiB,iBAAiB,MAAM;EAC/C,OAAO,iBAAiB,QAAQ,MAAM;EACtC,aAAa;GACX,OAAO,oBAAoB,eAAe,IAAI;GAC9C,OAAO,oBAAoB,aAAa,GAAG;GAC3C,OAAO,oBAAoB,iBAAiB,MAAM;GAClD,OAAO,oBAAoB,QAAQ,MAAM;EAC3C;CACF,GAAG,CAAC,CAAC;CACL,OACE,oCAAA,IAAC,uBAAA,eAAD;EAAe,OAAM;YACnB,oCAAA,IAAC,OAAD;GACE,MAAK;GACL,UAAU;GACV,cAAW;GACX,oBAAiB;GACjB,iBAAe,KAAK,IAAA,KAAwB,SAAS;GACrD,iBAAe,KAAK,IAAI,GAAG,SAAS;GACpC,iBAAe;GACf,WAAU;GACV,gBAAgB,UAAU;IACxB,IAAI,MAAM,WAAW,KAAK,KAAK,SAAS;IACxC,MAAM,eAAe;IACrB,MAAM,gBAAgB;IACtB,KAAK,UAAU;KAAE,GAAG,MAAM;KAAS,GAAG,MAAM;KAAS;KAAO,UAAU;KAAG,WAAW,MAAM;IAAU;IACpG,MAAM,cAAc,MAAM;IAC1B,MAAM,cAAc,oBAAoB,MAAM,SAAS;GACzD;GACA,UAAU,UAAU;IAClB,MAAM,eAAe;IACrB,MAAM,gBAAgB;GACxB;GACA,YAAY,UAAU;IACpB,IAAI,CAAC;KAAC;KAAa;KAAc;IAAM,CAAC,CAAC,SAAS,MAAM,GAAG,GAAG;IAC9D,MAAM,eAAe;IACrB,MAAM,gBAAgB;IACtB,SACE,MAAM,QAAQ,SAAA,MAEV,kBAAkB,SAAS,MAAM,QAAQ,cAAc,KAAK,MAAM,SAAS,CACjF;GACF;EACD,CAAA;CACY,CAAA;AAEnB"}
|