@cookielab.io/klovi 1.0.0 → 2.0.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.
|
@@ -40924,7 +40924,7 @@ var init_all = __esm(() => {
|
|
|
40924
40924
|
var favicon_default = "./favicon-39pjvakn.svg";
|
|
40925
40925
|
|
|
40926
40926
|
// src/frontend/App.tsx
|
|
40927
|
-
var
|
|
40927
|
+
var import_react19 = __toESM(require_react(), 1);
|
|
40928
40928
|
var import_client = __toESM(require_client(), 1);
|
|
40929
40929
|
|
|
40930
40930
|
// src/frontend/hooks/useFetch.ts
|
|
@@ -40937,9 +40937,10 @@ function useFetch(url, deps) {
|
|
|
40937
40937
|
const retry = import_react.useCallback(() => setRetryCount((c) => c + 1), []);
|
|
40938
40938
|
import_react.useEffect(() => {
|
|
40939
40939
|
let cancelled = false;
|
|
40940
|
+
const controller = new AbortController;
|
|
40940
40941
|
setLoading(true);
|
|
40941
40942
|
setError(null);
|
|
40942
|
-
fetch(url).then((r) => {
|
|
40943
|
+
fetch(url, { signal: controller.signal }).then((r) => {
|
|
40943
40944
|
if (!r.ok)
|
|
40944
40945
|
throw new Error(`HTTP ${r.status}`);
|
|
40945
40946
|
return r.json();
|
|
@@ -40949,13 +40950,14 @@ function useFetch(url, deps) {
|
|
|
40949
40950
|
setLoading(false);
|
|
40950
40951
|
}
|
|
40951
40952
|
}).catch((e) => {
|
|
40952
|
-
if (!cancelled) {
|
|
40953
|
+
if (!cancelled && !controller.signal.aborted) {
|
|
40953
40954
|
setError(e instanceof Error ? e.message : String(e));
|
|
40954
40955
|
setLoading(false);
|
|
40955
40956
|
}
|
|
40956
40957
|
});
|
|
40957
40958
|
return () => {
|
|
40958
40959
|
cancelled = true;
|
|
40960
|
+
controller.abort();
|
|
40959
40961
|
};
|
|
40960
40962
|
}, [url, retryCount, ...deps]);
|
|
40961
40963
|
return { data, loading, error, retry };
|
|
@@ -41422,6 +41424,44 @@ function Layout({ sidebar, hideSidebar, onSearchClick, children }) {
|
|
|
41422
41424
|
}, undefined, true, undefined, this);
|
|
41423
41425
|
}
|
|
41424
41426
|
|
|
41427
|
+
// src/frontend/hooks/useSessionData.ts
|
|
41428
|
+
function buildSessionUrl(sessionId, project) {
|
|
41429
|
+
return `/api/sessions/${encodeURIComponent(sessionId)}?project=${encodeURIComponent(project)}`;
|
|
41430
|
+
}
|
|
41431
|
+
function buildSubAgentSessionUrl(sessionId, project, agentId) {
|
|
41432
|
+
return `/api/sessions/${encodeURIComponent(sessionId)}/subagents/${encodeURIComponent(agentId)}?project=${encodeURIComponent(project)}`;
|
|
41433
|
+
}
|
|
41434
|
+
function useSessionData(sessionId, project) {
|
|
41435
|
+
return useFetch(buildSessionUrl(sessionId, project), [sessionId, project]);
|
|
41436
|
+
}
|
|
41437
|
+
function useSubAgentSessionData(sessionId, project, agentId) {
|
|
41438
|
+
return useFetch(buildSubAgentSessionUrl(sessionId, project, agentId), [
|
|
41439
|
+
sessionId,
|
|
41440
|
+
project,
|
|
41441
|
+
agentId
|
|
41442
|
+
]);
|
|
41443
|
+
}
|
|
41444
|
+
|
|
41445
|
+
// src/frontend/components/ui/FetchError.tsx
|
|
41446
|
+
var jsx_dev_runtime5 = __toESM(require_jsx_dev_runtime(), 1);
|
|
41447
|
+
function FetchError({ error, onRetry, showPrefix = false }) {
|
|
41448
|
+
return /* @__PURE__ */ jsx_dev_runtime5.jsxDEV("div", {
|
|
41449
|
+
className: "fetch-error",
|
|
41450
|
+
children: [
|
|
41451
|
+
/* @__PURE__ */ jsx_dev_runtime5.jsxDEV("span", {
|
|
41452
|
+
className: "fetch-error-message",
|
|
41453
|
+
children: showPrefix ? `Error: ${error}` : error
|
|
41454
|
+
}, undefined, false, undefined, this),
|
|
41455
|
+
onRetry ? /* @__PURE__ */ jsx_dev_runtime5.jsxDEV("button", {
|
|
41456
|
+
type: "button",
|
|
41457
|
+
className: "btn btn-sm",
|
|
41458
|
+
onClick: onRetry,
|
|
41459
|
+
children: "Retry"
|
|
41460
|
+
}, undefined, false, undefined, this) : null
|
|
41461
|
+
]
|
|
41462
|
+
}, undefined, true, undefined, this);
|
|
41463
|
+
}
|
|
41464
|
+
|
|
41425
41465
|
// src/frontend/utils/time.ts
|
|
41426
41466
|
function formatTimestamp(iso) {
|
|
41427
41467
|
const date = new Date(iso);
|
|
@@ -41499,7 +41539,7 @@ function formatTime(iso) {
|
|
|
41499
41539
|
|
|
41500
41540
|
// src/frontend/components/ui/ErrorBoundary.tsx
|
|
41501
41541
|
var import_react3 = __toESM(require_react(), 1);
|
|
41502
|
-
var
|
|
41542
|
+
var jsx_dev_runtime6 = __toESM(require_jsx_dev_runtime(), 1);
|
|
41503
41543
|
|
|
41504
41544
|
class ErrorBoundary extends import_react3.Component {
|
|
41505
41545
|
state = { error: null };
|
|
@@ -41514,17 +41554,17 @@ class ErrorBoundary extends import_react3.Component {
|
|
|
41514
41554
|
if (!error)
|
|
41515
41555
|
return this.props.children;
|
|
41516
41556
|
if (this.props.inline) {
|
|
41517
|
-
return /* @__PURE__ */
|
|
41557
|
+
return /* @__PURE__ */ jsx_dev_runtime6.jsxDEV("div", {
|
|
41518
41558
|
className: "error-card",
|
|
41519
41559
|
children: [
|
|
41520
|
-
/* @__PURE__ */
|
|
41560
|
+
/* @__PURE__ */ jsx_dev_runtime6.jsxDEV("div", {
|
|
41521
41561
|
className: "error-card-header",
|
|
41522
41562
|
children: [
|
|
41523
|
-
/* @__PURE__ */
|
|
41563
|
+
/* @__PURE__ */ jsx_dev_runtime6.jsxDEV("span", {
|
|
41524
41564
|
className: "error-card-title",
|
|
41525
41565
|
children: "Failed to render"
|
|
41526
41566
|
}, undefined, false, undefined, this),
|
|
41527
|
-
/* @__PURE__ */
|
|
41567
|
+
/* @__PURE__ */ jsx_dev_runtime6.jsxDEV("button", {
|
|
41528
41568
|
type: "button",
|
|
41529
41569
|
className: "btn btn-sm",
|
|
41530
41570
|
onClick: this.retry,
|
|
@@ -41532,13 +41572,13 @@ class ErrorBoundary extends import_react3.Component {
|
|
|
41532
41572
|
}, undefined, false, undefined, this)
|
|
41533
41573
|
]
|
|
41534
41574
|
}, undefined, true, undefined, this),
|
|
41535
|
-
/* @__PURE__ */
|
|
41575
|
+
/* @__PURE__ */ jsx_dev_runtime6.jsxDEV("details", {
|
|
41536
41576
|
className: "error-card-details",
|
|
41537
41577
|
children: [
|
|
41538
|
-
/* @__PURE__ */
|
|
41578
|
+
/* @__PURE__ */ jsx_dev_runtime6.jsxDEV("summary", {
|
|
41539
41579
|
children: "Error details"
|
|
41540
41580
|
}, undefined, false, undefined, this),
|
|
41541
|
-
/* @__PURE__ */
|
|
41581
|
+
/* @__PURE__ */ jsx_dev_runtime6.jsxDEV("pre", {
|
|
41542
41582
|
children: error.stack || error.message
|
|
41543
41583
|
}, undefined, false, undefined, this)
|
|
41544
41584
|
]
|
|
@@ -41546,18 +41586,18 @@ class ErrorBoundary extends import_react3.Component {
|
|
|
41546
41586
|
]
|
|
41547
41587
|
}, undefined, true, undefined, this);
|
|
41548
41588
|
}
|
|
41549
|
-
return /* @__PURE__ */
|
|
41589
|
+
return /* @__PURE__ */ jsx_dev_runtime6.jsxDEV("div", {
|
|
41550
41590
|
className: "error-view",
|
|
41551
41591
|
children: [
|
|
41552
|
-
/* @__PURE__ */
|
|
41592
|
+
/* @__PURE__ */ jsx_dev_runtime6.jsxDEV("div", {
|
|
41553
41593
|
className: "error-view-title",
|
|
41554
41594
|
children: "Something went wrong"
|
|
41555
41595
|
}, undefined, false, undefined, this),
|
|
41556
|
-
/* @__PURE__ */
|
|
41596
|
+
/* @__PURE__ */ jsx_dev_runtime6.jsxDEV("div", {
|
|
41557
41597
|
className: "error-view-message",
|
|
41558
41598
|
children: error.message
|
|
41559
41599
|
}, undefined, false, undefined, this),
|
|
41560
|
-
/* @__PURE__ */
|
|
41600
|
+
/* @__PURE__ */ jsx_dev_runtime6.jsxDEV("button", {
|
|
41561
41601
|
type: "button",
|
|
41562
41602
|
className: "btn btn-primary",
|
|
41563
41603
|
onClick: this.retry,
|
|
@@ -41899,12 +41939,12 @@ function productionCreate(_, jsx, jsxs) {
|
|
|
41899
41939
|
return key ? fn(type, props, key) : fn(type, props);
|
|
41900
41940
|
}
|
|
41901
41941
|
}
|
|
41902
|
-
function developmentCreate(filePath,
|
|
41942
|
+
function developmentCreate(filePath, jsxDEV7) {
|
|
41903
41943
|
return create2;
|
|
41904
41944
|
function create2(node, type, props, key) {
|
|
41905
41945
|
const isStaticChildren = Array.isArray(props.children);
|
|
41906
41946
|
const point3 = pointStart(node);
|
|
41907
|
-
return
|
|
41947
|
+
return jsxDEV7(type, props, key, isStaticChildren, {
|
|
41908
41948
|
columnNumber: point3 ? point3.column - 1 : undefined,
|
|
41909
41949
|
fileName: filePath,
|
|
41910
41950
|
lineNumber: point3 ? point3.line : undefined
|
|
@@ -53821,23 +53861,23 @@ function useFontSize() {
|
|
|
53821
53861
|
}
|
|
53822
53862
|
|
|
53823
53863
|
// src/frontend/components/ui/CodeBlock.tsx
|
|
53824
|
-
var
|
|
53864
|
+
var jsx_dev_runtime7 = __toESM(require_jsx_dev_runtime(), 1);
|
|
53825
53865
|
function CodeBlock({ language, children }) {
|
|
53826
53866
|
const { resolved: theme } = useTheme();
|
|
53827
53867
|
const lang = language || "text";
|
|
53828
53868
|
const style2 = theme === "dark" ? one_dark_default : one_light_default;
|
|
53829
|
-
return /* @__PURE__ */
|
|
53869
|
+
return /* @__PURE__ */ jsx_dev_runtime7.jsxDEV("div", {
|
|
53830
53870
|
className: "code-block-wrapper",
|
|
53831
53871
|
children: [
|
|
53832
|
-
language && /* @__PURE__ */
|
|
53872
|
+
language && /* @__PURE__ */ jsx_dev_runtime7.jsxDEV("div", {
|
|
53833
53873
|
className: "code-block-header",
|
|
53834
|
-
children: /* @__PURE__ */
|
|
53874
|
+
children: /* @__PURE__ */ jsx_dev_runtime7.jsxDEV("span", {
|
|
53835
53875
|
children: language
|
|
53836
53876
|
}, undefined, false, undefined, this)
|
|
53837
53877
|
}, undefined, false, undefined, this),
|
|
53838
|
-
/* @__PURE__ */
|
|
53878
|
+
/* @__PURE__ */ jsx_dev_runtime7.jsxDEV("div", {
|
|
53839
53879
|
className: "code-block-content",
|
|
53840
|
-
children: /* @__PURE__ */
|
|
53880
|
+
children: /* @__PURE__ */ jsx_dev_runtime7.jsxDEV(prism_default2, {
|
|
53841
53881
|
language: lang,
|
|
53842
53882
|
style: style2,
|
|
53843
53883
|
customStyle: {
|
|
@@ -53855,7 +53895,7 @@ function CodeBlock({ language, children }) {
|
|
|
53855
53895
|
}
|
|
53856
53896
|
|
|
53857
53897
|
// src/frontend/components/ui/MarkdownRenderer.tsx
|
|
53858
|
-
var
|
|
53898
|
+
var jsx_dev_runtime8 = __toESM(require_jsx_dev_runtime(), 1);
|
|
53859
53899
|
var FILE_REF_RE = /@([\w./-]+\.\w+)/g;
|
|
53860
53900
|
function renderTextWithFileRefs(text7) {
|
|
53861
53901
|
const parts = [];
|
|
@@ -53866,7 +53906,7 @@ function renderTextWithFileRefs(text7) {
|
|
|
53866
53906
|
if (match.index > last) {
|
|
53867
53907
|
parts.push(text7.slice(last, match.index));
|
|
53868
53908
|
}
|
|
53869
|
-
parts.push(/* @__PURE__ */
|
|
53909
|
+
parts.push(/* @__PURE__ */ jsx_dev_runtime8.jsxDEV("code", {
|
|
53870
53910
|
className: "file-ref",
|
|
53871
53911
|
children: [
|
|
53872
53912
|
"@",
|
|
@@ -53880,18 +53920,18 @@ function renderTextWithFileRefs(text7) {
|
|
|
53880
53920
|
return text7;
|
|
53881
53921
|
if (last < text7.length)
|
|
53882
53922
|
parts.push(text7.slice(last));
|
|
53883
|
-
return /* @__PURE__ */
|
|
53923
|
+
return /* @__PURE__ */ jsx_dev_runtime8.jsxDEV(jsx_dev_runtime8.Fragment, {
|
|
53884
53924
|
children: parts
|
|
53885
53925
|
}, undefined, false, undefined, this);
|
|
53886
53926
|
}
|
|
53887
53927
|
function MarkdownRenderer({ content: content3 }) {
|
|
53888
|
-
return /* @__PURE__ */
|
|
53928
|
+
return /* @__PURE__ */ jsx_dev_runtime8.jsxDEV("div", {
|
|
53889
53929
|
className: "markdown-content",
|
|
53890
|
-
children: /* @__PURE__ */
|
|
53930
|
+
children: /* @__PURE__ */ jsx_dev_runtime8.jsxDEV(Markdown, {
|
|
53891
53931
|
remarkPlugins: [remarkGfm],
|
|
53892
53932
|
components: {
|
|
53893
53933
|
p({ children }) {
|
|
53894
|
-
return /* @__PURE__ */
|
|
53934
|
+
return /* @__PURE__ */ jsx_dev_runtime8.jsxDEV("p", {
|
|
53895
53935
|
children: import_react8.default.Children.map(children, (child) => typeof child === "string" ? renderTextWithFileRefs(child) : child)
|
|
53896
53936
|
}, undefined, false, undefined, this);
|
|
53897
53937
|
},
|
|
@@ -53900,19 +53940,19 @@ function MarkdownRenderer({ content: content3 }) {
|
|
|
53900
53940
|
const text7 = String(children).replace(/\n$/, "");
|
|
53901
53941
|
if (!match && !text7.includes(`
|
|
53902
53942
|
`)) {
|
|
53903
|
-
return /* @__PURE__ */
|
|
53943
|
+
return /* @__PURE__ */ jsx_dev_runtime8.jsxDEV("code", {
|
|
53904
53944
|
className,
|
|
53905
53945
|
...props,
|
|
53906
53946
|
children
|
|
53907
53947
|
}, undefined, false, undefined, this);
|
|
53908
53948
|
}
|
|
53909
|
-
return /* @__PURE__ */
|
|
53949
|
+
return /* @__PURE__ */ jsx_dev_runtime8.jsxDEV(CodeBlock, {
|
|
53910
53950
|
language: match?.[1],
|
|
53911
53951
|
children: text7
|
|
53912
53952
|
}, undefined, false, undefined, this);
|
|
53913
53953
|
},
|
|
53914
53954
|
a({ href, children, ...props }) {
|
|
53915
|
-
return /* @__PURE__ */
|
|
53955
|
+
return /* @__PURE__ */ jsx_dev_runtime8.jsxDEV("a", {
|
|
53916
53956
|
href,
|
|
53917
53957
|
target: "_blank",
|
|
53918
53958
|
rel: "noopener noreferrer",
|
|
@@ -53948,9 +53988,6 @@ function groupContentBlocks(blocks) {
|
|
|
53948
53988
|
}
|
|
53949
53989
|
|
|
53950
53990
|
// src/frontend/utils/model.ts
|
|
53951
|
-
function isClaudeModel(model) {
|
|
53952
|
-
return model.startsWith("claude-");
|
|
53953
|
-
}
|
|
53954
53991
|
function shortModel(model) {
|
|
53955
53992
|
const claudeMatch = model.match(/claude-(opus|sonnet|haiku)-(\d+)(?:-(\d{1,2}))?(?:-\d{8,})?$/);
|
|
53956
53993
|
if (claudeMatch) {
|
|
@@ -53980,29 +54017,29 @@ function shortModel(model) {
|
|
|
53980
54017
|
|
|
53981
54018
|
// src/frontend/components/ui/CollapsibleSection.tsx
|
|
53982
54019
|
var import_react9 = __toESM(require_react(), 1);
|
|
53983
|
-
var
|
|
54020
|
+
var jsx_dev_runtime9 = __toESM(require_jsx_dev_runtime(), 1);
|
|
53984
54021
|
function CollapsibleSection({
|
|
53985
54022
|
title,
|
|
53986
54023
|
defaultOpen = false,
|
|
53987
54024
|
children
|
|
53988
54025
|
}) {
|
|
53989
54026
|
const [open, setOpen] = import_react9.useState(defaultOpen);
|
|
53990
|
-
return /* @__PURE__ */
|
|
54027
|
+
return /* @__PURE__ */ jsx_dev_runtime9.jsxDEV("div", {
|
|
53991
54028
|
className: "collapsible",
|
|
53992
54029
|
children: [
|
|
53993
|
-
/* @__PURE__ */
|
|
54030
|
+
/* @__PURE__ */ jsx_dev_runtime9.jsxDEV("button", {
|
|
53994
54031
|
type: "button",
|
|
53995
54032
|
className: "collapsible-header",
|
|
53996
54033
|
onClick: () => setOpen(!open),
|
|
53997
54034
|
children: [
|
|
53998
|
-
/* @__PURE__ */
|
|
54035
|
+
/* @__PURE__ */ jsx_dev_runtime9.jsxDEV("span", {
|
|
53999
54036
|
className: `collapsible-chevron ${open ? "open" : ""}`,
|
|
54000
54037
|
children: "▶"
|
|
54001
54038
|
}, undefined, false, undefined, this),
|
|
54002
54039
|
title
|
|
54003
54040
|
]
|
|
54004
54041
|
}, undefined, true, undefined, this),
|
|
54005
|
-
open && /* @__PURE__ */
|
|
54042
|
+
open && /* @__PURE__ */ jsx_dev_runtime9.jsxDEV("div", {
|
|
54006
54043
|
className: "collapsible-content",
|
|
54007
54044
|
children
|
|
54008
54045
|
}, undefined, false, undefined, this)
|
|
@@ -54010,8 +54047,61 @@ function CollapsibleSection({
|
|
|
54010
54047
|
}, undefined, true, undefined, this);
|
|
54011
54048
|
}
|
|
54012
54049
|
|
|
54050
|
+
// src/server/plugins/shared/text-utils.ts
|
|
54051
|
+
function truncate(text7, maxLength) {
|
|
54052
|
+
return text7.length <= maxLength ? text7 : `${text7.slice(0, maxLength)}...`;
|
|
54053
|
+
}
|
|
54054
|
+
|
|
54055
|
+
// src/server/plugins/codex-cli/extractors.ts
|
|
54056
|
+
var codexSummaryExtractors = {
|
|
54057
|
+
command_execution: (i) => truncate(String(i.command || ""), 80),
|
|
54058
|
+
file_change: (i) => {
|
|
54059
|
+
const changes = i.changes;
|
|
54060
|
+
if (Array.isArray(changes) && changes.length > 0) {
|
|
54061
|
+
return String(changes[0].path || "");
|
|
54062
|
+
}
|
|
54063
|
+
return "";
|
|
54064
|
+
},
|
|
54065
|
+
web_search: (i) => truncate(String(i.query || ""), 60)
|
|
54066
|
+
};
|
|
54067
|
+
var codexInputFormatters = {
|
|
54068
|
+
command_execution: (i) => String(i.command || ""),
|
|
54069
|
+
file_change: (i) => {
|
|
54070
|
+
const changes = i.changes;
|
|
54071
|
+
if (Array.isArray(changes)) {
|
|
54072
|
+
return changes.map((c2) => `${c2.kind || "change"}: ${c2.path || ""}`).join(`
|
|
54073
|
+
`);
|
|
54074
|
+
}
|
|
54075
|
+
return JSON.stringify(i, null, 2);
|
|
54076
|
+
},
|
|
54077
|
+
web_search: (i) => `Query: ${String(i.query || "")}`
|
|
54078
|
+
};
|
|
54079
|
+
|
|
54080
|
+
// src/server/plugins/opencode/extractors.ts
|
|
54081
|
+
var openCodeSummaryExtractors = {};
|
|
54082
|
+
var openCodeInputFormatters = {};
|
|
54083
|
+
|
|
54084
|
+
// src/frontend/plugin-registry.ts
|
|
54085
|
+
var pluginRegistry = new Map;
|
|
54086
|
+
function registerFrontendPlugin(id, plugin) {
|
|
54087
|
+
pluginRegistry.set(id, plugin);
|
|
54088
|
+
}
|
|
54089
|
+
function getFrontendPlugin(id) {
|
|
54090
|
+
return pluginRegistry.get(id);
|
|
54091
|
+
}
|
|
54092
|
+
registerFrontendPlugin("codex-cli", {
|
|
54093
|
+
displayName: "Codex",
|
|
54094
|
+
summaryExtractors: codexSummaryExtractors,
|
|
54095
|
+
inputFormatters: codexInputFormatters
|
|
54096
|
+
});
|
|
54097
|
+
registerFrontendPlugin("opencode", {
|
|
54098
|
+
displayName: "OpenCode",
|
|
54099
|
+
summaryExtractors: openCodeSummaryExtractors,
|
|
54100
|
+
inputFormatters: openCodeInputFormatters
|
|
54101
|
+
});
|
|
54102
|
+
|
|
54013
54103
|
// src/frontend/components/ui/DiffView.tsx
|
|
54014
|
-
var
|
|
54104
|
+
var jsx_dev_runtime10 = __toESM(require_jsx_dev_runtime(), 1);
|
|
54015
54105
|
function formatDiff(oldString, newString) {
|
|
54016
54106
|
const lines = [];
|
|
54017
54107
|
if (oldString !== "") {
|
|
@@ -54033,18 +54123,18 @@ function DiffView({ filePath, oldString, newString }) {
|
|
|
54033
54123
|
const { resolved: theme } = useTheme();
|
|
54034
54124
|
const diff2 = formatDiff(oldString, newString);
|
|
54035
54125
|
const style2 = theme === "dark" ? one_dark_default : one_light_default;
|
|
54036
|
-
return /* @__PURE__ */
|
|
54126
|
+
return /* @__PURE__ */ jsx_dev_runtime10.jsxDEV("div", {
|
|
54037
54127
|
className: "diff-view-wrapper",
|
|
54038
54128
|
children: [
|
|
54039
|
-
/* @__PURE__ */
|
|
54129
|
+
/* @__PURE__ */ jsx_dev_runtime10.jsxDEV("div", {
|
|
54040
54130
|
className: "diff-view-header",
|
|
54041
|
-
children: /* @__PURE__ */
|
|
54131
|
+
children: /* @__PURE__ */ jsx_dev_runtime10.jsxDEV("span", {
|
|
54042
54132
|
children: filePath
|
|
54043
54133
|
}, undefined, false, undefined, this)
|
|
54044
54134
|
}, undefined, false, undefined, this),
|
|
54045
|
-
/* @__PURE__ */
|
|
54135
|
+
/* @__PURE__ */ jsx_dev_runtime10.jsxDEV("div", {
|
|
54046
54136
|
className: "diff-view-content",
|
|
54047
|
-
children: /* @__PURE__ */
|
|
54137
|
+
children: /* @__PURE__ */ jsx_dev_runtime10.jsxDEV(prism_default2, {
|
|
54048
54138
|
language: "diff",
|
|
54049
54139
|
style: style2,
|
|
54050
54140
|
customStyle: {
|
|
@@ -54061,6 +54151,9 @@ function DiffView({ filePath, oldString, newString }) {
|
|
|
54061
54151
|
}, undefined, true, undefined, this);
|
|
54062
54152
|
}
|
|
54063
54153
|
|
|
54154
|
+
// src/frontend/components/message/SmartToolOutput.tsx
|
|
54155
|
+
var import_react11 = __toESM(require_react(), 1);
|
|
54156
|
+
|
|
54064
54157
|
// src/frontend/utils/format-detector.ts
|
|
54065
54158
|
function detectOutputFormat(output) {
|
|
54066
54159
|
const trimmed = output.trim();
|
|
@@ -54155,68 +54248,103 @@ function hasCodeStructure(text7) {
|
|
|
54155
54248
|
return lines.length >= 2 && /^(export|import|const|let|var|function|class)\s/.test(text7);
|
|
54156
54249
|
}
|
|
54157
54250
|
|
|
54251
|
+
// src/frontend/components/ui/ImageLightbox.tsx
|
|
54252
|
+
var import_react10 = __toESM(require_react(), 1);
|
|
54253
|
+
var jsx_dev_runtime11 = __toESM(require_jsx_dev_runtime(), 1);
|
|
54254
|
+
function ImageLightbox({ src, onClose }) {
|
|
54255
|
+
const [visible, setVisible] = import_react10.useState(false);
|
|
54256
|
+
const handleClose = import_react10.useCallback(() => {
|
|
54257
|
+
setVisible(false);
|
|
54258
|
+
setTimeout(onClose, 200);
|
|
54259
|
+
}, [onClose]);
|
|
54260
|
+
import_react10.useEffect(() => {
|
|
54261
|
+
requestAnimationFrame(() => {
|
|
54262
|
+
requestAnimationFrame(() => setVisible(true));
|
|
54263
|
+
});
|
|
54264
|
+
}, []);
|
|
54265
|
+
import_react10.useEffect(() => {
|
|
54266
|
+
const handleKey = (e) => {
|
|
54267
|
+
if (e.key === "Escape")
|
|
54268
|
+
handleClose();
|
|
54269
|
+
};
|
|
54270
|
+
document.addEventListener("keydown", handleKey);
|
|
54271
|
+
return () => document.removeEventListener("keydown", handleKey);
|
|
54272
|
+
}, [handleClose]);
|
|
54273
|
+
return /* @__PURE__ */ jsx_dev_runtime11.jsxDEV("div", {
|
|
54274
|
+
className: `lightbox-overlay ${visible ? "lightbox-visible" : ""}`,
|
|
54275
|
+
onClick: handleClose,
|
|
54276
|
+
children: /* @__PURE__ */ jsx_dev_runtime11.jsxDEV("img", {
|
|
54277
|
+
className: "lightbox-image",
|
|
54278
|
+
src,
|
|
54279
|
+
alt: "Full size preview"
|
|
54280
|
+
}, undefined, false, undefined, this)
|
|
54281
|
+
}, undefined, false, undefined, this);
|
|
54282
|
+
}
|
|
54283
|
+
|
|
54158
54284
|
// src/frontend/components/message/SmartToolOutput.tsx
|
|
54159
|
-
var
|
|
54285
|
+
var jsx_dev_runtime12 = __toESM(require_jsx_dev_runtime(), 1);
|
|
54160
54286
|
function SmartToolOutput({ output, isError, resultImages }) {
|
|
54161
54287
|
const truncated = truncateOutput(output);
|
|
54162
54288
|
const wasTruncated = output.length > MAX_OUTPUT_LENGTH;
|
|
54163
54289
|
const detectedLang = truncated ? detectOutputFormat(truncated) : null;
|
|
54290
|
+
const [lightboxSrc, setLightboxSrc] = import_react11.useState(null);
|
|
54291
|
+
const closeLightbox = import_react11.useCallback(() => setLightboxSrc(null), []);
|
|
54164
54292
|
if (!output && (!resultImages || resultImages.length === 0))
|
|
54165
54293
|
return null;
|
|
54166
|
-
return /* @__PURE__ */
|
|
54294
|
+
return /* @__PURE__ */ jsx_dev_runtime12.jsxDEV("div", {
|
|
54167
54295
|
children: [
|
|
54168
|
-
/* @__PURE__ */
|
|
54296
|
+
/* @__PURE__ */ jsx_dev_runtime12.jsxDEV("div", {
|
|
54169
54297
|
className: "tool-section-label",
|
|
54170
54298
|
children: "Output"
|
|
54171
54299
|
}, undefined, false, undefined, this),
|
|
54172
|
-
output && (detectedLang && !isError ? /* @__PURE__ */
|
|
54300
|
+
output && (detectedLang && !isError ? /* @__PURE__ */ jsx_dev_runtime12.jsxDEV(CodeBlock, {
|
|
54173
54301
|
language: detectedLang,
|
|
54174
54302
|
children: truncated
|
|
54175
|
-
}, undefined, false, undefined, this) : /* @__PURE__ */
|
|
54303
|
+
}, undefined, false, undefined, this) : /* @__PURE__ */ jsx_dev_runtime12.jsxDEV("div", {
|
|
54176
54304
|
className: `tool-call-output ${isError ? "tool-call-error" : ""}`,
|
|
54177
54305
|
children: truncated
|
|
54178
54306
|
}, undefined, false, undefined, this)),
|
|
54179
|
-
wasTruncated && /* @__PURE__ */
|
|
54307
|
+
wasTruncated && /* @__PURE__ */ jsx_dev_runtime12.jsxDEV("div", {
|
|
54180
54308
|
className: "tool-call-truncated",
|
|
54181
54309
|
children: "... (truncated)"
|
|
54182
54310
|
}, undefined, false, undefined, this),
|
|
54183
|
-
resultImages && resultImages.length > 0 && /* @__PURE__ */
|
|
54311
|
+
resultImages && resultImages.length > 0 && /* @__PURE__ */ jsx_dev_runtime12.jsxDEV("div", {
|
|
54184
54312
|
className: "tool-result-images",
|
|
54185
|
-
children: resultImages.map((img, i) => /* @__PURE__ */
|
|
54186
|
-
|
|
54187
|
-
|
|
54188
|
-
|
|
54189
|
-
|
|
54190
|
-
className: "tool-result-image",
|
|
54191
|
-
src: `data:${img.mediaType};base64,${img.data}`,
|
|
54192
|
-
alt: `Tool result ${i + 1}`
|
|
54193
|
-
}, undefined, false, undefined, this)
|
|
54313
|
+
children: resultImages.map((img, i) => /* @__PURE__ */ jsx_dev_runtime12.jsxDEV("img", {
|
|
54314
|
+
className: "tool-result-image",
|
|
54315
|
+
src: `data:${img.mediaType};base64,${img.data}`,
|
|
54316
|
+
alt: `Tool result ${i + 1}`,
|
|
54317
|
+
onClick: () => setLightboxSrc(`data:${img.mediaType};base64,${img.data}`)
|
|
54194
54318
|
}, i, false, undefined, this))
|
|
54319
|
+
}, undefined, false, undefined, this),
|
|
54320
|
+
lightboxSrc && /* @__PURE__ */ jsx_dev_runtime12.jsxDEV(ImageLightbox, {
|
|
54321
|
+
src: lightboxSrc,
|
|
54322
|
+
onClose: closeLightbox
|
|
54195
54323
|
}, undefined, false, undefined, this)
|
|
54196
54324
|
]
|
|
54197
54325
|
}, undefined, true, undefined, this);
|
|
54198
54326
|
}
|
|
54199
54327
|
|
|
54200
54328
|
// src/frontend/components/message/BashToolContent.tsx
|
|
54201
|
-
var
|
|
54329
|
+
var jsx_dev_runtime13 = __toESM(require_jsx_dev_runtime(), 1);
|
|
54202
54330
|
function BashToolContent({ call }) {
|
|
54203
54331
|
const command = String(call.input.command || "");
|
|
54204
|
-
return /* @__PURE__ */
|
|
54332
|
+
return /* @__PURE__ */ jsx_dev_runtime13.jsxDEV(jsx_dev_runtime13.Fragment, {
|
|
54205
54333
|
children: [
|
|
54206
|
-
/* @__PURE__ */
|
|
54334
|
+
/* @__PURE__ */ jsx_dev_runtime13.jsxDEV("div", {
|
|
54207
54335
|
style: { marginBottom: 8 },
|
|
54208
54336
|
children: [
|
|
54209
|
-
/* @__PURE__ */
|
|
54337
|
+
/* @__PURE__ */ jsx_dev_runtime13.jsxDEV("div", {
|
|
54210
54338
|
className: "tool-section-label",
|
|
54211
54339
|
children: "Command"
|
|
54212
54340
|
}, undefined, false, undefined, this),
|
|
54213
|
-
/* @__PURE__ */
|
|
54341
|
+
/* @__PURE__ */ jsx_dev_runtime13.jsxDEV(CodeBlock, {
|
|
54214
54342
|
language: "bash",
|
|
54215
54343
|
children: command
|
|
54216
54344
|
}, undefined, false, undefined, this)
|
|
54217
54345
|
]
|
|
54218
54346
|
}, undefined, true, undefined, this),
|
|
54219
|
-
/* @__PURE__ */
|
|
54347
|
+
/* @__PURE__ */ jsx_dev_runtime13.jsxDEV(SmartToolOutput, {
|
|
54220
54348
|
output: call.result,
|
|
54221
54349
|
isError: call.isError,
|
|
54222
54350
|
resultImages: call.resultImages
|
|
@@ -54226,38 +54354,46 @@ function BashToolContent({ call }) {
|
|
|
54226
54354
|
}
|
|
54227
54355
|
|
|
54228
54356
|
// src/frontend/components/message/ToolCall.tsx
|
|
54229
|
-
var
|
|
54357
|
+
var jsx_dev_runtime14 = __toESM(require_jsx_dev_runtime(), 1);
|
|
54230
54358
|
var MAX_OUTPUT_LENGTH = 5000;
|
|
54231
54359
|
var MAX_CONTENT_LENGTH = 2000;
|
|
54232
54360
|
var MAX_THINKING_PREVIEW = 100;
|
|
54233
54361
|
function isEditWithDiff(call) {
|
|
54234
54362
|
return call.name === "Edit" && typeof call.input.old_string === "string" && typeof call.input.new_string === "string";
|
|
54235
54363
|
}
|
|
54236
|
-
function
|
|
54237
|
-
|
|
54364
|
+
function hasInputFormatter(call, pluginId) {
|
|
54365
|
+
if (pluginId) {
|
|
54366
|
+
const plugin = getFrontendPlugin(pluginId);
|
|
54367
|
+
if (plugin?.inputFormatters[call.name])
|
|
54368
|
+
return true;
|
|
54369
|
+
}
|
|
54370
|
+
return call.name in INPUT_FORMATTERS;
|
|
54371
|
+
}
|
|
54372
|
+
function isJsonFallbackInput(call, pluginId) {
|
|
54373
|
+
return !hasInputFormatter(call, pluginId);
|
|
54238
54374
|
}
|
|
54239
|
-
function DefaultToolContent({ call }) {
|
|
54240
|
-
const formattedInput = formatToolInput(call);
|
|
54241
|
-
const jsonInput = isJsonFallbackInput(call);
|
|
54242
|
-
return /* @__PURE__ */
|
|
54375
|
+
function DefaultToolContent({ call, pluginId }) {
|
|
54376
|
+
const formattedInput = formatToolInput(call, pluginId);
|
|
54377
|
+
const jsonInput = isJsonFallbackInput(call, pluginId);
|
|
54378
|
+
return /* @__PURE__ */ jsx_dev_runtime14.jsxDEV(jsx_dev_runtime14.Fragment, {
|
|
54243
54379
|
children: [
|
|
54244
|
-
/* @__PURE__ */
|
|
54380
|
+
/* @__PURE__ */ jsx_dev_runtime14.jsxDEV("div", {
|
|
54245
54381
|
style: { marginBottom: 8 },
|
|
54246
54382
|
children: [
|
|
54247
|
-
/* @__PURE__ */
|
|
54383
|
+
/* @__PURE__ */ jsx_dev_runtime14.jsxDEV("div", {
|
|
54248
54384
|
className: "tool-section-label",
|
|
54249
54385
|
children: "Input"
|
|
54250
54386
|
}, undefined, false, undefined, this),
|
|
54251
|
-
jsonInput ? /* @__PURE__ */
|
|
54387
|
+
jsonInput ? /* @__PURE__ */ jsx_dev_runtime14.jsxDEV(CodeBlock, {
|
|
54252
54388
|
language: "json",
|
|
54253
54389
|
children: formattedInput
|
|
54254
|
-
}, undefined, false, undefined, this) : /* @__PURE__ */
|
|
54390
|
+
}, undefined, false, undefined, this) : /* @__PURE__ */ jsx_dev_runtime14.jsxDEV("div", {
|
|
54255
54391
|
className: "tool-call-input",
|
|
54256
54392
|
children: formattedInput
|
|
54257
54393
|
}, undefined, false, undefined, this)
|
|
54258
54394
|
]
|
|
54259
54395
|
}, undefined, true, undefined, this),
|
|
54260
|
-
/* @__PURE__ */
|
|
54396
|
+
/* @__PURE__ */ jsx_dev_runtime14.jsxDEV(SmartToolOutput, {
|
|
54261
54397
|
output: call.result,
|
|
54262
54398
|
isError: call.isError,
|
|
54263
54399
|
resultImages: call.resultImages
|
|
@@ -54265,41 +54401,41 @@ function DefaultToolContent({ call }) {
|
|
|
54265
54401
|
]
|
|
54266
54402
|
}, undefined, true, undefined, this);
|
|
54267
54403
|
}
|
|
54268
|
-
function ToolCall({ call, sessionId, project }) {
|
|
54269
|
-
const summary = getToolSummary(call);
|
|
54404
|
+
function ToolCall({ call, sessionId, project, pluginId }) {
|
|
54405
|
+
const summary = getToolSummary(call, pluginId);
|
|
54270
54406
|
const mcpServer = getMcpServer(call.name);
|
|
54271
54407
|
const skillName = getSkillName(call);
|
|
54272
54408
|
const hasSubAgent = call.name === "Task" && call.subAgentId && sessionId && project;
|
|
54273
54409
|
const displayName = hasSubAgent ? "Sub-Agent" : mcpServer ? call.name.split("__").slice(1).join("__").replace(/__/g, " > ") : skillName ?? call.name;
|
|
54274
|
-
return /* @__PURE__ */
|
|
54410
|
+
return /* @__PURE__ */ jsx_dev_runtime14.jsxDEV("div", {
|
|
54275
54411
|
className: "tool-call",
|
|
54276
|
-
children: /* @__PURE__ */
|
|
54277
|
-
title: /* @__PURE__ */
|
|
54412
|
+
children: /* @__PURE__ */ jsx_dev_runtime14.jsxDEV(CollapsibleSection, {
|
|
54413
|
+
title: /* @__PURE__ */ jsx_dev_runtime14.jsxDEV("span", {
|
|
54278
54414
|
children: [
|
|
54279
|
-
mcpServer && /* @__PURE__ */
|
|
54415
|
+
mcpServer && /* @__PURE__ */ jsx_dev_runtime14.jsxDEV("span", {
|
|
54280
54416
|
className: "tool-mcp-server",
|
|
54281
54417
|
children: mcpServer
|
|
54282
54418
|
}, undefined, false, undefined, this),
|
|
54283
|
-
skillName && /* @__PURE__ */
|
|
54419
|
+
skillName && /* @__PURE__ */ jsx_dev_runtime14.jsxDEV("span", {
|
|
54284
54420
|
className: "tool-skill-badge",
|
|
54285
54421
|
children: "skill"
|
|
54286
54422
|
}, undefined, false, undefined, this),
|
|
54287
|
-
/* @__PURE__ */
|
|
54423
|
+
/* @__PURE__ */ jsx_dev_runtime14.jsxDEV("span", {
|
|
54288
54424
|
className: "tool-call-name",
|
|
54289
54425
|
children: displayName
|
|
54290
54426
|
}, undefined, false, undefined, this),
|
|
54291
|
-
summary && !skillName && /* @__PURE__ */
|
|
54427
|
+
summary && !skillName && /* @__PURE__ */ jsx_dev_runtime14.jsxDEV("span", {
|
|
54292
54428
|
className: "tool-call-summary",
|
|
54293
54429
|
children: [
|
|
54294
54430
|
" — ",
|
|
54295
54431
|
summary
|
|
54296
54432
|
]
|
|
54297
54433
|
}, undefined, true, undefined, this),
|
|
54298
|
-
call.isError && /* @__PURE__ */
|
|
54434
|
+
call.isError && /* @__PURE__ */ jsx_dev_runtime14.jsxDEV("span", {
|
|
54299
54435
|
className: "tool-call-error",
|
|
54300
54436
|
children: " (error)"
|
|
54301
54437
|
}, undefined, false, undefined, this),
|
|
54302
|
-
hasSubAgent && /* @__PURE__ */
|
|
54438
|
+
hasSubAgent && /* @__PURE__ */ jsx_dev_runtime14.jsxDEV("a", {
|
|
54303
54439
|
className: "subagent-link",
|
|
54304
54440
|
href: `#/${project}/${sessionId}/subagent/${call.subAgentId}`,
|
|
54305
54441
|
onClick: (e) => e.stopPropagation(),
|
|
@@ -54307,14 +54443,15 @@ function ToolCall({ call, sessionId, project }) {
|
|
|
54307
54443
|
}, undefined, false, undefined, this)
|
|
54308
54444
|
]
|
|
54309
54445
|
}, undefined, true, undefined, this),
|
|
54310
|
-
children: isEditWithDiff(call) ? /* @__PURE__ */
|
|
54446
|
+
children: isEditWithDiff(call) ? /* @__PURE__ */ jsx_dev_runtime14.jsxDEV(DiffView, {
|
|
54311
54447
|
filePath: String(call.input.file_path || ""),
|
|
54312
54448
|
oldString: String(call.input.old_string),
|
|
54313
54449
|
newString: String(call.input.new_string)
|
|
54314
|
-
}, undefined, false, undefined, this) : call.name === "Bash" ? /* @__PURE__ */
|
|
54315
|
-
call
|
|
54316
|
-
}, undefined, false, undefined, this) : /* @__PURE__ */ jsx_dev_runtime12.jsxDEV(DefaultToolContent, {
|
|
54450
|
+
}, undefined, false, undefined, this) : call.name === "Bash" ? /* @__PURE__ */ jsx_dev_runtime14.jsxDEV(BashToolContent, {
|
|
54317
54451
|
call
|
|
54452
|
+
}, undefined, false, undefined, this) : /* @__PURE__ */ jsx_dev_runtime14.jsxDEV(DefaultToolContent, {
|
|
54453
|
+
call,
|
|
54454
|
+
pluginId
|
|
54318
54455
|
}, undefined, false, undefined, this)
|
|
54319
54456
|
}, undefined, false, undefined, this)
|
|
54320
54457
|
}, undefined, false, undefined, this);
|
|
@@ -54333,7 +54470,7 @@ function getSkillName(call) {
|
|
|
54333
54470
|
function getAskUserQuestionSummary(input) {
|
|
54334
54471
|
if (Array.isArray(input.questions) && input.questions.length > 0) {
|
|
54335
54472
|
const q2 = input.questions[0];
|
|
54336
|
-
return
|
|
54473
|
+
return truncate2(String(q2.question || ""), 60);
|
|
54337
54474
|
}
|
|
54338
54475
|
return "";
|
|
54339
54476
|
}
|
|
@@ -54342,16 +54479,16 @@ var fileSummaryExtractors = {
|
|
|
54342
54479
|
Write: (i) => String(i.file_path || ""),
|
|
54343
54480
|
Edit: (i) => String(i.file_path || ""),
|
|
54344
54481
|
Glob: (i) => String(i.pattern || ""),
|
|
54345
|
-
Grep: (i) =>
|
|
54482
|
+
Grep: (i) => truncate2(String(i.pattern || ""), 60),
|
|
54346
54483
|
NotebookEdit: (i) => String(i.notebook_path || ""),
|
|
54347
54484
|
NotebookRead: (i) => String(i.notebook_path || "")
|
|
54348
54485
|
};
|
|
54349
54486
|
var shellSummaryExtractors = {
|
|
54350
|
-
Bash: (i) =>
|
|
54487
|
+
Bash: (i) => truncate2(String(i.command || ""), 80)
|
|
54351
54488
|
};
|
|
54352
54489
|
var agentSummaryExtractors = {
|
|
54353
|
-
Task: (i) =>
|
|
54354
|
-
TaskCreate: (i) =>
|
|
54490
|
+
Task: (i) => truncate2(String(i.description || ""), 60),
|
|
54491
|
+
TaskCreate: (i) => truncate2(String(i.subject || ""), 60),
|
|
54355
54492
|
TaskUpdate: (i) => `#${i.taskId || "?"}${i.status ? ` → ${i.status}` : ""}`,
|
|
54356
54493
|
TaskList: () => "List all tasks",
|
|
54357
54494
|
TaskGet: (i) => `#${i.taskId || "?"}`,
|
|
@@ -54360,11 +54497,11 @@ var agentSummaryExtractors = {
|
|
|
54360
54497
|
KillShell: (i) => String(i.task_id || i.shell_id || ""),
|
|
54361
54498
|
EnterPlanMode: () => "Enter plan mode",
|
|
54362
54499
|
ExitPlanMode: () => "Exit plan mode",
|
|
54363
|
-
TodoWrite: (i) =>
|
|
54500
|
+
TodoWrite: (i) => truncate2(String(i.subject || ""), 60)
|
|
54364
54501
|
};
|
|
54365
54502
|
var webSummaryExtractors = {
|
|
54366
|
-
WebFetch: (i) =>
|
|
54367
|
-
WebSearch: (i) =>
|
|
54503
|
+
WebFetch: (i) => truncate2(String(i.url || ""), 60),
|
|
54504
|
+
WebSearch: (i) => truncate2(String(i.query || ""), 60)
|
|
54368
54505
|
};
|
|
54369
54506
|
var interactionSummaryExtractors = {
|
|
54370
54507
|
AskUserQuestion: (i) => getAskUserQuestionSummary(i),
|
|
@@ -54377,7 +54514,13 @@ var SUMMARY_EXTRACTORS = {
|
|
|
54377
54514
|
...webSummaryExtractors,
|
|
54378
54515
|
...interactionSummaryExtractors
|
|
54379
54516
|
};
|
|
54380
|
-
function getToolSummary(call) {
|
|
54517
|
+
function getToolSummary(call, pluginId) {
|
|
54518
|
+
if (pluginId) {
|
|
54519
|
+
const plugin = getFrontendPlugin(pluginId);
|
|
54520
|
+
const pluginExtractor = plugin?.summaryExtractors[call.name];
|
|
54521
|
+
if (pluginExtractor)
|
|
54522
|
+
return pluginExtractor(call.input);
|
|
54523
|
+
}
|
|
54381
54524
|
if (call.name.startsWith("mcp__")) {
|
|
54382
54525
|
return call.name.split("__").slice(2).join(" > ") || "";
|
|
54383
54526
|
}
|
|
@@ -54413,7 +54556,7 @@ function formatWriteInput(input) {
|
|
|
54413
54556
|
parts.push(`File: ${input.file_path}`);
|
|
54414
54557
|
if (input.content)
|
|
54415
54558
|
parts.push(`Content:
|
|
54416
|
-
${
|
|
54559
|
+
${truncate2(String(input.content), MAX_CONTENT_LENGTH)}`);
|
|
54417
54560
|
return parts.join(`
|
|
54418
54561
|
|
|
54419
54562
|
`);
|
|
@@ -54452,7 +54595,7 @@ function formatNotebookEditInput(input) {
|
|
|
54452
54595
|
parts.push(`Mode: ${input.edit_mode}`);
|
|
54453
54596
|
if (input.new_source)
|
|
54454
54597
|
parts.push(`Source:
|
|
54455
|
-
${
|
|
54598
|
+
${truncate2(String(input.new_source), MAX_CONTENT_LENGTH)}`);
|
|
54456
54599
|
return parts.join(`
|
|
54457
54600
|
`) || JSON.stringify(input, null, 2);
|
|
54458
54601
|
}
|
|
@@ -54513,11 +54656,17 @@ var INPUT_FORMATTERS = {
|
|
|
54513
54656
|
...agentInputFormatters,
|
|
54514
54657
|
...interactionInputFormatters
|
|
54515
54658
|
};
|
|
54516
|
-
function formatToolInput(call) {
|
|
54659
|
+
function formatToolInput(call, pluginId) {
|
|
54660
|
+
if (pluginId) {
|
|
54661
|
+
const plugin = getFrontendPlugin(pluginId);
|
|
54662
|
+
const pluginFormatter = plugin?.inputFormatters[call.name];
|
|
54663
|
+
if (pluginFormatter)
|
|
54664
|
+
return pluginFormatter(call.input);
|
|
54665
|
+
}
|
|
54517
54666
|
const formatter = INPUT_FORMATTERS[call.name];
|
|
54518
54667
|
return formatter ? formatter(call.input) : JSON.stringify(call.input, null, 2);
|
|
54519
54668
|
}
|
|
54520
|
-
function
|
|
54669
|
+
function truncate2(s2, max) {
|
|
54521
54670
|
if (s2.length <= max)
|
|
54522
54671
|
return s2;
|
|
54523
54672
|
return `${s2.slice(0, max)}...`;
|
|
@@ -54529,28 +54678,28 @@ function truncateOutput(s2) {
|
|
|
54529
54678
|
}
|
|
54530
54679
|
|
|
54531
54680
|
// src/frontend/components/message/ThinkingBlock.tsx
|
|
54532
|
-
var
|
|
54681
|
+
var jsx_dev_runtime15 = __toESM(require_jsx_dev_runtime(), 1);
|
|
54533
54682
|
function ThinkingBlock({ block }) {
|
|
54534
54683
|
const preview = block.text.length > MAX_THINKING_PREVIEW ? `${block.text.slice(0, MAX_THINKING_PREVIEW)}...` : block.text;
|
|
54535
|
-
return /* @__PURE__ */
|
|
54684
|
+
return /* @__PURE__ */ jsx_dev_runtime15.jsxDEV("div", {
|
|
54536
54685
|
className: "thinking-block",
|
|
54537
|
-
children: /* @__PURE__ */
|
|
54538
|
-
title: /* @__PURE__ */
|
|
54686
|
+
children: /* @__PURE__ */ jsx_dev_runtime15.jsxDEV(CollapsibleSection, {
|
|
54687
|
+
title: /* @__PURE__ */ jsx_dev_runtime15.jsxDEV("span", {
|
|
54539
54688
|
children: [
|
|
54540
|
-
/* @__PURE__ */
|
|
54689
|
+
/* @__PURE__ */ jsx_dev_runtime15.jsxDEV("span", {
|
|
54541
54690
|
style: { color: "var(--text-muted)" },
|
|
54542
54691
|
children: "Thinking:"
|
|
54543
54692
|
}, undefined, false, undefined, this),
|
|
54544
54693
|
" ",
|
|
54545
|
-
/* @__PURE__ */
|
|
54694
|
+
/* @__PURE__ */ jsx_dev_runtime15.jsxDEV("span", {
|
|
54546
54695
|
className: "tool-call-summary",
|
|
54547
54696
|
children: preview
|
|
54548
54697
|
}, undefined, false, undefined, this)
|
|
54549
54698
|
]
|
|
54550
54699
|
}, undefined, true, undefined, this),
|
|
54551
|
-
children: /* @__PURE__ */
|
|
54700
|
+
children: /* @__PURE__ */ jsx_dev_runtime15.jsxDEV("div", {
|
|
54552
54701
|
className: "thinking-content",
|
|
54553
|
-
children: /* @__PURE__ */
|
|
54702
|
+
children: /* @__PURE__ */ jsx_dev_runtime15.jsxDEV(MarkdownRenderer, {
|
|
54554
54703
|
content: block.text
|
|
54555
54704
|
}, undefined, false, undefined, this)
|
|
54556
54705
|
}, undefined, false, undefined, this)
|
|
@@ -54559,42 +54708,43 @@ function ThinkingBlock({ block }) {
|
|
|
54559
54708
|
}
|
|
54560
54709
|
|
|
54561
54710
|
// src/frontend/components/message/AssistantMessage.tsx
|
|
54562
|
-
var
|
|
54563
|
-
function renderGroup(group, sessionId, project) {
|
|
54711
|
+
var jsx_dev_runtime16 = __toESM(require_jsx_dev_runtime(), 1);
|
|
54712
|
+
function renderGroup(group, sessionId, project, pluginId) {
|
|
54564
54713
|
return group.map((block, i) => {
|
|
54565
54714
|
if (block.type === "thinking") {
|
|
54566
|
-
return /* @__PURE__ */
|
|
54715
|
+
return /* @__PURE__ */ jsx_dev_runtime16.jsxDEV(ThinkingBlock, {
|
|
54567
54716
|
block: block.block
|
|
54568
54717
|
}, `thinking-${i}`, false, undefined, this);
|
|
54569
54718
|
}
|
|
54570
54719
|
if (block.type === "text") {
|
|
54571
|
-
return /* @__PURE__ */
|
|
54720
|
+
return /* @__PURE__ */ jsx_dev_runtime16.jsxDEV(MarkdownRenderer, {
|
|
54572
54721
|
content: block.text
|
|
54573
54722
|
}, `text-${i}`, false, undefined, this);
|
|
54574
54723
|
}
|
|
54575
|
-
return /* @__PURE__ */
|
|
54724
|
+
return /* @__PURE__ */ jsx_dev_runtime16.jsxDEV(ToolCall, {
|
|
54576
54725
|
call: block.call,
|
|
54577
54726
|
sessionId,
|
|
54578
|
-
project
|
|
54727
|
+
project,
|
|
54728
|
+
pluginId
|
|
54579
54729
|
}, `tool-${i}`, false, undefined, this);
|
|
54580
54730
|
});
|
|
54581
54731
|
}
|
|
54582
54732
|
function UsageFooter({ usage }) {
|
|
54583
|
-
return /* @__PURE__ */
|
|
54733
|
+
return /* @__PURE__ */ jsx_dev_runtime16.jsxDEV("div", {
|
|
54584
54734
|
className: "token-usage",
|
|
54585
54735
|
children: [
|
|
54586
54736
|
usage.inputTokens.toLocaleString(),
|
|
54587
54737
|
" in / ",
|
|
54588
54738
|
usage.outputTokens.toLocaleString(),
|
|
54589
54739
|
" out",
|
|
54590
|
-
usage.cacheReadTokens && usage.cacheReadTokens > 0 && /* @__PURE__ */
|
|
54740
|
+
usage.cacheReadTokens && usage.cacheReadTokens > 0 && /* @__PURE__ */ jsx_dev_runtime16.jsxDEV("span", {
|
|
54591
54741
|
children: [
|
|
54592
54742
|
" · ",
|
|
54593
54743
|
usage.cacheReadTokens.toLocaleString(),
|
|
54594
54744
|
" cache read"
|
|
54595
54745
|
]
|
|
54596
54746
|
}, undefined, true, undefined, this),
|
|
54597
|
-
usage.cacheCreationTokens && usage.cacheCreationTokens > 0 && /* @__PURE__ */
|
|
54747
|
+
usage.cacheCreationTokens && usage.cacheCreationTokens > 0 && /* @__PURE__ */ jsx_dev_runtime16.jsxDEV("span", {
|
|
54598
54748
|
children: [
|
|
54599
54749
|
" · ",
|
|
54600
54750
|
usage.cacheCreationTokens.toLocaleString(),
|
|
@@ -54608,7 +54758,8 @@ function AssistantMessage({
|
|
|
54608
54758
|
turn,
|
|
54609
54759
|
visibleSubSteps,
|
|
54610
54760
|
sessionId,
|
|
54611
|
-
project
|
|
54761
|
+
project,
|
|
54762
|
+
pluginId
|
|
54612
54763
|
}) {
|
|
54613
54764
|
const groups = groupContentBlocks(turn.contentBlocks);
|
|
54614
54765
|
const limit = visibleSubSteps !== undefined ? visibleSubSteps : groups.length;
|
|
@@ -54619,21 +54770,21 @@ function AssistantMessage({
|
|
|
54619
54770
|
const introGroup = hasNonText && firstIsText ? visibleGroups[0] : null;
|
|
54620
54771
|
const treeGroups = hasNonText ? introGroup ? visibleGroups.slice(1) : visibleGroups : [];
|
|
54621
54772
|
const flatGroups = hasNonText ? [] : visibleGroups;
|
|
54622
|
-
return /* @__PURE__ */
|
|
54773
|
+
return /* @__PURE__ */ jsx_dev_runtime16.jsxDEV("div", {
|
|
54623
54774
|
className: "turn",
|
|
54624
54775
|
children: [
|
|
54625
|
-
/* @__PURE__ */
|
|
54776
|
+
/* @__PURE__ */ jsx_dev_runtime16.jsxDEV("div", {
|
|
54626
54777
|
className: "turn-header",
|
|
54627
54778
|
children: [
|
|
54628
|
-
/* @__PURE__ */
|
|
54779
|
+
/* @__PURE__ */ jsx_dev_runtime16.jsxDEV("span", {
|
|
54629
54780
|
className: "turn-badge turn-badge-assistant",
|
|
54630
54781
|
children: "Assistant"
|
|
54631
54782
|
}, undefined, false, undefined, this),
|
|
54632
|
-
turn.model && /* @__PURE__ */
|
|
54783
|
+
turn.model && /* @__PURE__ */ jsx_dev_runtime16.jsxDEV("span", {
|
|
54633
54784
|
className: "turn-badge turn-badge-model",
|
|
54634
54785
|
children: shortModel(turn.model)
|
|
54635
54786
|
}, undefined, false, undefined, this),
|
|
54636
|
-
turn.timestamp && /* @__PURE__ */
|
|
54787
|
+
turn.timestamp && /* @__PURE__ */ jsx_dev_runtime16.jsxDEV("time", {
|
|
54637
54788
|
className: "turn-timestamp",
|
|
54638
54789
|
dateTime: turn.timestamp,
|
|
54639
54790
|
"data-tooltip": formatFullDateTime(turn.timestamp),
|
|
@@ -54641,25 +54792,25 @@ function AssistantMessage({
|
|
|
54641
54792
|
}, undefined, false, undefined, this)
|
|
54642
54793
|
]
|
|
54643
54794
|
}, undefined, true, undefined, this),
|
|
54644
|
-
/* @__PURE__ */
|
|
54795
|
+
/* @__PURE__ */ jsx_dev_runtime16.jsxDEV("div", {
|
|
54645
54796
|
className: "message message-assistant",
|
|
54646
54797
|
children: [
|
|
54647
|
-
introGroup && /* @__PURE__ */
|
|
54798
|
+
introGroup && /* @__PURE__ */ jsx_dev_runtime16.jsxDEV("div", {
|
|
54648
54799
|
className: isPresentation && treeGroups.length === 0 ? "step-enter" : "",
|
|
54649
|
-
children: renderGroup(introGroup, sessionId, project)
|
|
54800
|
+
children: renderGroup(introGroup, sessionId, project, pluginId)
|
|
54650
54801
|
}, undefined, false, undefined, this),
|
|
54651
|
-
treeGroups.length > 0 && /* @__PURE__ */
|
|
54802
|
+
treeGroups.length > 0 && /* @__PURE__ */ jsx_dev_runtime16.jsxDEV("div", {
|
|
54652
54803
|
className: "exec-tree",
|
|
54653
|
-
children: treeGroups.map((group, i) => /* @__PURE__ */
|
|
54804
|
+
children: treeGroups.map((group, i) => /* @__PURE__ */ jsx_dev_runtime16.jsxDEV("div", {
|
|
54654
54805
|
className: `tree-node${isPresentation && i === treeGroups.length - 1 ? " step-enter" : ""}`,
|
|
54655
|
-
children: renderGroup(group, sessionId, project)
|
|
54806
|
+
children: renderGroup(group, sessionId, project, pluginId)
|
|
54656
54807
|
}, i, false, undefined, this))
|
|
54657
54808
|
}, undefined, false, undefined, this),
|
|
54658
|
-
flatGroups.map((group, i) => /* @__PURE__ */
|
|
54809
|
+
flatGroups.map((group, i) => /* @__PURE__ */ jsx_dev_runtime16.jsxDEV("div", {
|
|
54659
54810
|
className: isPresentation && i === flatGroups.length - 1 ? "step-enter" : "",
|
|
54660
|
-
children: renderGroup(group, sessionId, project)
|
|
54811
|
+
children: renderGroup(group, sessionId, project, pluginId)
|
|
54661
54812
|
}, i, false, undefined, this)),
|
|
54662
|
-
turn.usage && /* @__PURE__ */
|
|
54813
|
+
turn.usage && /* @__PURE__ */ jsx_dev_runtime16.jsxDEV(UsageFooter, {
|
|
54663
54814
|
usage: turn.usage
|
|
54664
54815
|
}, undefined, false, undefined, this)
|
|
54665
54816
|
]
|
|
@@ -54669,7 +54820,7 @@ function AssistantMessage({
|
|
|
54669
54820
|
}
|
|
54670
54821
|
|
|
54671
54822
|
// src/frontend/components/message/UserMessage.tsx
|
|
54672
|
-
var
|
|
54823
|
+
var jsx_dev_runtime17 = __toESM(require_jsx_dev_runtime(), 1);
|
|
54673
54824
|
var STATUS_RE = /^\[.+\]$/;
|
|
54674
54825
|
var PLAN_PREFIX = "Implement the following plan";
|
|
54675
54826
|
function UserMessage({
|
|
@@ -54680,14 +54831,14 @@ function UserMessage({
|
|
|
54680
54831
|
project
|
|
54681
54832
|
}) {
|
|
54682
54833
|
if (turn.bashInput !== undefined) {
|
|
54683
|
-
return /* @__PURE__ */
|
|
54834
|
+
return /* @__PURE__ */ jsx_dev_runtime17.jsxDEV("div", {
|
|
54684
54835
|
className: "status-notice bash-input-notice",
|
|
54685
54836
|
children: [
|
|
54686
|
-
/* @__PURE__ */
|
|
54837
|
+
/* @__PURE__ */ jsx_dev_runtime17.jsxDEV("span", {
|
|
54687
54838
|
className: "bash-input-prompt",
|
|
54688
54839
|
children: "$"
|
|
54689
54840
|
}, undefined, false, undefined, this),
|
|
54690
|
-
/* @__PURE__ */
|
|
54841
|
+
/* @__PURE__ */ jsx_dev_runtime17.jsxDEV("code", {
|
|
54691
54842
|
className: "bash-input-command",
|
|
54692
54843
|
children: turn.bashInput
|
|
54693
54844
|
}, undefined, false, undefined, this)
|
|
@@ -54695,11 +54846,11 @@ function UserMessage({
|
|
|
54695
54846
|
}, undefined, true, undefined, this);
|
|
54696
54847
|
}
|
|
54697
54848
|
if (turn.ideOpenedFile !== undefined) {
|
|
54698
|
-
return /* @__PURE__ */
|
|
54849
|
+
return /* @__PURE__ */ jsx_dev_runtime17.jsxDEV("div", {
|
|
54699
54850
|
className: "status-notice ide-opened-file-notice",
|
|
54700
54851
|
children: [
|
|
54701
54852
|
"Opened ",
|
|
54702
|
-
/* @__PURE__ */
|
|
54853
|
+
/* @__PURE__ */ jsx_dev_runtime17.jsxDEV("code", {
|
|
54703
54854
|
className: "ide-opened-file-path",
|
|
54704
54855
|
children: turn.ideOpenedFile
|
|
54705
54856
|
}, undefined, false, undefined, this)
|
|
@@ -54708,7 +54859,7 @@ function UserMessage({
|
|
|
54708
54859
|
}
|
|
54709
54860
|
const isStatus = STATUS_RE.test(turn.text.trim());
|
|
54710
54861
|
if (isStatus) {
|
|
54711
|
-
return /* @__PURE__ */
|
|
54862
|
+
return /* @__PURE__ */ jsx_dev_runtime17.jsxDEV("div", {
|
|
54712
54863
|
className: "status-notice",
|
|
54713
54864
|
children: turn.text
|
|
54714
54865
|
}, undefined, false, undefined, this);
|
|
@@ -54718,27 +54869,27 @@ function UserMessage({
|
|
|
54718
54869
|
const showImplLink = implSessionId && project && !isPlanMessage;
|
|
54719
54870
|
const role = isSubAgent ? "Root Agent" : "User";
|
|
54720
54871
|
const badgeClass = isSubAgent ? "turn-badge-agent" : "turn-badge-user";
|
|
54721
|
-
return /* @__PURE__ */
|
|
54872
|
+
return /* @__PURE__ */ jsx_dev_runtime17.jsxDEV("div", {
|
|
54722
54873
|
className: "turn",
|
|
54723
54874
|
children: [
|
|
54724
|
-
/* @__PURE__ */
|
|
54875
|
+
/* @__PURE__ */ jsx_dev_runtime17.jsxDEV("div", {
|
|
54725
54876
|
className: "turn-header",
|
|
54726
54877
|
children: [
|
|
54727
|
-
/* @__PURE__ */
|
|
54878
|
+
/* @__PURE__ */ jsx_dev_runtime17.jsxDEV("span", {
|
|
54728
54879
|
className: `turn-badge ${badgeClass}`,
|
|
54729
54880
|
children: role
|
|
54730
54881
|
}, undefined, false, undefined, this),
|
|
54731
|
-
showPlanLink && /* @__PURE__ */
|
|
54882
|
+
showPlanLink && /* @__PURE__ */ jsx_dev_runtime17.jsxDEV("a", {
|
|
54732
54883
|
className: "subagent-link",
|
|
54733
54884
|
href: `#/${project}/${planSessionId}`,
|
|
54734
54885
|
children: "View planning session"
|
|
54735
54886
|
}, undefined, false, undefined, this),
|
|
54736
|
-
showImplLink && /* @__PURE__ */
|
|
54887
|
+
showImplLink && /* @__PURE__ */ jsx_dev_runtime17.jsxDEV("a", {
|
|
54737
54888
|
className: "subagent-link",
|
|
54738
54889
|
href: `#/${project}/${implSessionId}`,
|
|
54739
54890
|
children: "View implementation session"
|
|
54740
54891
|
}, undefined, false, undefined, this),
|
|
54741
|
-
turn.timestamp && /* @__PURE__ */
|
|
54892
|
+
turn.timestamp && /* @__PURE__ */ jsx_dev_runtime17.jsxDEV("time", {
|
|
54742
54893
|
className: "turn-timestamp",
|
|
54743
54894
|
dateTime: turn.timestamp,
|
|
54744
54895
|
"data-tooltip": formatFullDateTime(turn.timestamp),
|
|
@@ -54746,28 +54897,28 @@ function UserMessage({
|
|
|
54746
54897
|
}, undefined, false, undefined, this)
|
|
54747
54898
|
]
|
|
54748
54899
|
}, undefined, true, undefined, this),
|
|
54749
|
-
/* @__PURE__ */
|
|
54900
|
+
/* @__PURE__ */ jsx_dev_runtime17.jsxDEV("div", {
|
|
54750
54901
|
className: `message ${isSubAgent ? "message-root-agent" : "message-user"}`,
|
|
54751
54902
|
children: [
|
|
54752
|
-
turn.command && /* @__PURE__ */
|
|
54903
|
+
turn.command && /* @__PURE__ */ jsx_dev_runtime17.jsxDEV("div", {
|
|
54753
54904
|
className: "command-call",
|
|
54754
54905
|
children: [
|
|
54755
|
-
/* @__PURE__ */
|
|
54906
|
+
/* @__PURE__ */ jsx_dev_runtime17.jsxDEV("span", {
|
|
54756
54907
|
className: "tool-skill-badge",
|
|
54757
54908
|
children: "skill"
|
|
54758
54909
|
}, undefined, false, undefined, this),
|
|
54759
|
-
/* @__PURE__ */
|
|
54910
|
+
/* @__PURE__ */ jsx_dev_runtime17.jsxDEV("span", {
|
|
54760
54911
|
className: "command-call-label",
|
|
54761
54912
|
children: turn.command.name
|
|
54762
54913
|
}, undefined, false, undefined, this)
|
|
54763
54914
|
]
|
|
54764
54915
|
}, undefined, true, undefined, this),
|
|
54765
|
-
/* @__PURE__ */
|
|
54916
|
+
/* @__PURE__ */ jsx_dev_runtime17.jsxDEV(MarkdownRenderer, {
|
|
54766
54917
|
content: turn.text
|
|
54767
54918
|
}, undefined, false, undefined, this),
|
|
54768
|
-
turn.attachments && turn.attachments.length > 0 && /* @__PURE__ */
|
|
54919
|
+
turn.attachments && turn.attachments.length > 0 && /* @__PURE__ */ jsx_dev_runtime17.jsxDEV("div", {
|
|
54769
54920
|
className: "attachments",
|
|
54770
|
-
children: turn.attachments.map((a, i) => /* @__PURE__ */
|
|
54921
|
+
children: turn.attachments.map((a, i) => /* @__PURE__ */ jsx_dev_runtime17.jsxDEV("span", {
|
|
54771
54922
|
className: "attachment-badge",
|
|
54772
54923
|
children: [
|
|
54773
54924
|
"image/",
|
|
@@ -54782,14 +54933,14 @@ function UserMessage({
|
|
|
54782
54933
|
}
|
|
54783
54934
|
|
|
54784
54935
|
// src/frontend/components/message/MessageList.tsx
|
|
54785
|
-
var
|
|
54786
|
-
function renderTurn(turn, index2, isActive, visibleSubSteps, sessionId, project, isSubAgent, planSessionId, implSessionId) {
|
|
54936
|
+
var jsx_dev_runtime18 = __toESM(require_jsx_dev_runtime(), 1);
|
|
54937
|
+
function renderTurn(turn, index2, isActive, visibleSubSteps, sessionId, project, pluginId, isSubAgent, planSessionId, implSessionId) {
|
|
54787
54938
|
const activeClass = isActive ? "active-message" : "";
|
|
54788
54939
|
switch (turn.kind) {
|
|
54789
54940
|
case "user":
|
|
54790
|
-
return /* @__PURE__ */
|
|
54941
|
+
return /* @__PURE__ */ jsx_dev_runtime18.jsxDEV("div", {
|
|
54791
54942
|
className: isActive ? "active-message step-enter" : "",
|
|
54792
|
-
children: /* @__PURE__ */
|
|
54943
|
+
children: /* @__PURE__ */ jsx_dev_runtime18.jsxDEV(UserMessage, {
|
|
54793
54944
|
turn,
|
|
54794
54945
|
isSubAgent,
|
|
54795
54946
|
planSessionId,
|
|
@@ -54798,27 +54949,28 @@ function renderTurn(turn, index2, isActive, visibleSubSteps, sessionId, project,
|
|
|
54798
54949
|
}, undefined, false, undefined, this)
|
|
54799
54950
|
}, undefined, false, undefined, this);
|
|
54800
54951
|
case "assistant":
|
|
54801
|
-
return /* @__PURE__ */
|
|
54952
|
+
return /* @__PURE__ */ jsx_dev_runtime18.jsxDEV("div", {
|
|
54802
54953
|
className: activeClass,
|
|
54803
|
-
children: /* @__PURE__ */
|
|
54954
|
+
children: /* @__PURE__ */ jsx_dev_runtime18.jsxDEV(AssistantMessage, {
|
|
54804
54955
|
turn,
|
|
54805
54956
|
visibleSubSteps: visibleSubSteps?.get(index2),
|
|
54806
54957
|
sessionId,
|
|
54807
|
-
project
|
|
54958
|
+
project,
|
|
54959
|
+
pluginId
|
|
54808
54960
|
}, undefined, false, undefined, this)
|
|
54809
54961
|
}, undefined, false, undefined, this);
|
|
54810
54962
|
case "system":
|
|
54811
|
-
return /* @__PURE__ */
|
|
54963
|
+
return /* @__PURE__ */ jsx_dev_runtime18.jsxDEV("div", {
|
|
54812
54964
|
className: `turn ${activeClass}`,
|
|
54813
54965
|
children: [
|
|
54814
|
-
/* @__PURE__ */
|
|
54966
|
+
/* @__PURE__ */ jsx_dev_runtime18.jsxDEV("div", {
|
|
54815
54967
|
className: "turn-header",
|
|
54816
54968
|
children: [
|
|
54817
|
-
/* @__PURE__ */
|
|
54969
|
+
/* @__PURE__ */ jsx_dev_runtime18.jsxDEV("span", {
|
|
54818
54970
|
className: "turn-badge turn-badge-system",
|
|
54819
54971
|
children: "System"
|
|
54820
54972
|
}, undefined, false, undefined, this),
|
|
54821
|
-
turn.timestamp && /* @__PURE__ */
|
|
54973
|
+
turn.timestamp && /* @__PURE__ */ jsx_dev_runtime18.jsxDEV("time", {
|
|
54822
54974
|
className: "turn-timestamp",
|
|
54823
54975
|
dateTime: turn.timestamp,
|
|
54824
54976
|
"data-tooltip": formatFullDateTime(turn.timestamp),
|
|
@@ -54826,26 +54978,26 @@ function renderTurn(turn, index2, isActive, visibleSubSteps, sessionId, project,
|
|
|
54826
54978
|
}, undefined, false, undefined, this)
|
|
54827
54979
|
]
|
|
54828
54980
|
}, undefined, true, undefined, this),
|
|
54829
|
-
/* @__PURE__ */
|
|
54981
|
+
/* @__PURE__ */ jsx_dev_runtime18.jsxDEV("div", {
|
|
54830
54982
|
className: "message message-system",
|
|
54831
|
-
children: /* @__PURE__ */
|
|
54983
|
+
children: /* @__PURE__ */ jsx_dev_runtime18.jsxDEV(MarkdownRenderer, {
|
|
54832
54984
|
content: turn.text
|
|
54833
54985
|
}, undefined, false, undefined, this)
|
|
54834
54986
|
}, undefined, false, undefined, this)
|
|
54835
54987
|
]
|
|
54836
54988
|
}, undefined, true, undefined, this);
|
|
54837
54989
|
case "parse_error":
|
|
54838
|
-
return /* @__PURE__ */
|
|
54990
|
+
return /* @__PURE__ */ jsx_dev_runtime18.jsxDEV("div", {
|
|
54839
54991
|
className: `turn ${activeClass}`,
|
|
54840
54992
|
children: [
|
|
54841
|
-
/* @__PURE__ */
|
|
54993
|
+
/* @__PURE__ */ jsx_dev_runtime18.jsxDEV("div", {
|
|
54842
54994
|
className: "turn-header",
|
|
54843
54995
|
children: [
|
|
54844
|
-
/* @__PURE__ */
|
|
54996
|
+
/* @__PURE__ */ jsx_dev_runtime18.jsxDEV("span", {
|
|
54845
54997
|
className: "turn-badge turn-badge-error",
|
|
54846
54998
|
children: "Parse Error"
|
|
54847
54999
|
}, undefined, false, undefined, this),
|
|
54848
|
-
turn.lineNumber > 0 && /* @__PURE__ */
|
|
55000
|
+
turn.lineNumber > 0 && /* @__PURE__ */ jsx_dev_runtime18.jsxDEV("span", {
|
|
54849
55001
|
className: "parse-error-line",
|
|
54850
55002
|
children: [
|
|
54851
55003
|
"line ",
|
|
@@ -54854,24 +55006,24 @@ function renderTurn(turn, index2, isActive, visibleSubSteps, sessionId, project,
|
|
|
54854
55006
|
}, undefined, true, undefined, this)
|
|
54855
55007
|
]
|
|
54856
55008
|
}, undefined, true, undefined, this),
|
|
54857
|
-
/* @__PURE__ */
|
|
55009
|
+
/* @__PURE__ */ jsx_dev_runtime18.jsxDEV("div", {
|
|
54858
55010
|
className: "message message-parse-error",
|
|
54859
55011
|
children: [
|
|
54860
|
-
/* @__PURE__ */
|
|
55012
|
+
/* @__PURE__ */ jsx_dev_runtime18.jsxDEV("div", {
|
|
54861
55013
|
className: "parse-error-type",
|
|
54862
55014
|
children: turn.errorType === "json_parse" ? "Invalid JSON" : "Invalid Structure"
|
|
54863
55015
|
}, undefined, false, undefined, this),
|
|
54864
|
-
turn.errorDetails && /* @__PURE__ */
|
|
55016
|
+
turn.errorDetails && /* @__PURE__ */ jsx_dev_runtime18.jsxDEV("div", {
|
|
54865
55017
|
className: "parse-error-details",
|
|
54866
55018
|
children: turn.errorDetails
|
|
54867
55019
|
}, undefined, false, undefined, this),
|
|
54868
|
-
/* @__PURE__ */
|
|
55020
|
+
/* @__PURE__ */ jsx_dev_runtime18.jsxDEV("details", {
|
|
54869
55021
|
className: "parse-error-raw",
|
|
54870
55022
|
children: [
|
|
54871
|
-
/* @__PURE__ */
|
|
55023
|
+
/* @__PURE__ */ jsx_dev_runtime18.jsxDEV("summary", {
|
|
54872
55024
|
children: "Raw content"
|
|
54873
55025
|
}, undefined, false, undefined, this),
|
|
54874
|
-
/* @__PURE__ */
|
|
55026
|
+
/* @__PURE__ */ jsx_dev_runtime18.jsxDEV("pre", {
|
|
54875
55027
|
children: turn.rawLine
|
|
54876
55028
|
}, undefined, false, undefined, this)
|
|
54877
55029
|
]
|
|
@@ -54890,6 +55042,7 @@ function MessageList({
|
|
|
54890
55042
|
visibleSubSteps,
|
|
54891
55043
|
sessionId,
|
|
54892
55044
|
project,
|
|
55045
|
+
pluginId,
|
|
54893
55046
|
isSubAgent,
|
|
54894
55047
|
planSessionId,
|
|
54895
55048
|
implSessionId
|
|
@@ -54899,56 +55052,43 @@ function MessageList({
|
|
|
54899
55052
|
return false;
|
|
54900
55053
|
return !STATUS_RE2.test(t.text.trim());
|
|
54901
55054
|
});
|
|
54902
|
-
return /* @__PURE__ */
|
|
55055
|
+
return /* @__PURE__ */ jsx_dev_runtime18.jsxDEV("div", {
|
|
54903
55056
|
className: "message-list",
|
|
54904
55057
|
children: turns.map((turn, index2) => {
|
|
54905
55058
|
const isActive = visibleSubSteps ? index2 === turns.length - 1 : false;
|
|
54906
|
-
return /* @__PURE__ */
|
|
55059
|
+
return /* @__PURE__ */ jsx_dev_runtime18.jsxDEV(ErrorBoundary, {
|
|
54907
55060
|
inline: true,
|
|
54908
|
-
children: renderTurn(turn, index2, isActive, visibleSubSteps, sessionId, project, isSubAgent, planSessionId, index2 === firstUserTurnIndex ? implSessionId : undefined)
|
|
55061
|
+
children: renderTurn(turn, index2, isActive, visibleSubSteps, sessionId, project, pluginId, isSubAgent, planSessionId, index2 === firstUserTurnIndex ? implSessionId : undefined)
|
|
54909
55062
|
}, turn.uuid || index2, false, undefined, this);
|
|
54910
55063
|
})
|
|
54911
55064
|
}, undefined, false, undefined, this);
|
|
54912
55065
|
}
|
|
54913
55066
|
|
|
54914
55067
|
// src/frontend/components/message/SubAgentView.tsx
|
|
54915
|
-
var
|
|
55068
|
+
var jsx_dev_runtime19 = __toESM(require_jsx_dev_runtime(), 1);
|
|
54916
55069
|
function SubAgentView({ sessionId, project, agentId }) {
|
|
54917
|
-
const { data, loading, error, retry } =
|
|
55070
|
+
const { data, loading, error, retry } = useSubAgentSessionData(sessionId, project, agentId);
|
|
54918
55071
|
if (loading)
|
|
54919
|
-
return /* @__PURE__ */
|
|
55072
|
+
return /* @__PURE__ */ jsx_dev_runtime19.jsxDEV("div", {
|
|
54920
55073
|
className: "loading",
|
|
54921
55074
|
children: "Loading sub-agent conversation..."
|
|
54922
55075
|
}, undefined, false, undefined, this);
|
|
54923
|
-
if (error)
|
|
54924
|
-
return /* @__PURE__ */
|
|
54925
|
-
|
|
54926
|
-
|
|
54927
|
-
|
|
54928
|
-
|
|
54929
|
-
children: [
|
|
54930
|
-
"Error: ",
|
|
54931
|
-
error
|
|
54932
|
-
]
|
|
54933
|
-
}, undefined, true, undefined, this),
|
|
54934
|
-
/* @__PURE__ */ jsx_dev_runtime17.jsxDEV("button", {
|
|
54935
|
-
type: "button",
|
|
54936
|
-
className: "btn btn-sm",
|
|
54937
|
-
onClick: retry,
|
|
54938
|
-
children: "Retry"
|
|
54939
|
-
}, undefined, false, undefined, this)
|
|
54940
|
-
]
|
|
54941
|
-
}, undefined, true, undefined, this);
|
|
54942
|
-
}
|
|
55076
|
+
if (error)
|
|
55077
|
+
return /* @__PURE__ */ jsx_dev_runtime19.jsxDEV(FetchError, {
|
|
55078
|
+
error,
|
|
55079
|
+
onRetry: retry,
|
|
55080
|
+
showPrefix: true
|
|
55081
|
+
}, undefined, false, undefined, this);
|
|
54943
55082
|
if (!data?.session || data.session.turns.length === 0)
|
|
54944
|
-
return /* @__PURE__ */
|
|
55083
|
+
return /* @__PURE__ */ jsx_dev_runtime19.jsxDEV("div", {
|
|
54945
55084
|
className: "subagent-empty",
|
|
54946
55085
|
children: "No sub-agent conversation data available."
|
|
54947
55086
|
}, undefined, false, undefined, this);
|
|
54948
|
-
return /* @__PURE__ */
|
|
55087
|
+
return /* @__PURE__ */ jsx_dev_runtime19.jsxDEV(MessageList, {
|
|
54949
55088
|
turns: data.session.turns,
|
|
54950
55089
|
sessionId,
|
|
54951
55090
|
project,
|
|
55091
|
+
pluginId: data.session.pluginId,
|
|
54952
55092
|
isSubAgent: true
|
|
54953
55093
|
}, undefined, false, undefined, this);
|
|
54954
55094
|
}
|
|
@@ -54960,25 +55100,25 @@ function projectDisplayName(project) {
|
|
|
54960
55100
|
}
|
|
54961
55101
|
|
|
54962
55102
|
// src/frontend/components/project/HiddenProjectList.tsx
|
|
54963
|
-
var
|
|
55103
|
+
var jsx_dev_runtime20 = __toESM(require_jsx_dev_runtime(), 1);
|
|
54964
55104
|
function HiddenProjectList({ hiddenIds, onUnhide, onBack }) {
|
|
54965
55105
|
const { data, loading, error, retry } = useFetch("/api/projects", []);
|
|
54966
55106
|
const projects = data?.projects ?? [];
|
|
54967
55107
|
const hidden = projects.filter((p) => hiddenIds.has(p.encodedPath));
|
|
54968
55108
|
if (loading)
|
|
54969
|
-
return /* @__PURE__ */
|
|
55109
|
+
return /* @__PURE__ */ jsx_dev_runtime20.jsxDEV("div", {
|
|
54970
55110
|
className: "loading",
|
|
54971
55111
|
children: "Loading..."
|
|
54972
55112
|
}, undefined, false, undefined, this);
|
|
54973
55113
|
if (error) {
|
|
54974
|
-
return /* @__PURE__ */
|
|
55114
|
+
return /* @__PURE__ */ jsx_dev_runtime20.jsxDEV("div", {
|
|
54975
55115
|
className: "fetch-error",
|
|
54976
55116
|
children: [
|
|
54977
|
-
/* @__PURE__ */
|
|
55117
|
+
/* @__PURE__ */ jsx_dev_runtime20.jsxDEV("span", {
|
|
54978
55118
|
className: "fetch-error-message",
|
|
54979
55119
|
children: error
|
|
54980
55120
|
}, undefined, false, undefined, this),
|
|
54981
|
-
/* @__PURE__ */
|
|
55121
|
+
/* @__PURE__ */ jsx_dev_runtime20.jsxDEV("button", {
|
|
54982
55122
|
type: "button",
|
|
54983
55123
|
className: "btn btn-sm",
|
|
54984
55124
|
onClick: retry,
|
|
@@ -54987,40 +55127,40 @@ function HiddenProjectList({ hiddenIds, onUnhide, onBack }) {
|
|
|
54987
55127
|
]
|
|
54988
55128
|
}, undefined, true, undefined, this);
|
|
54989
55129
|
}
|
|
54990
|
-
return /* @__PURE__ */
|
|
55130
|
+
return /* @__PURE__ */ jsx_dev_runtime20.jsxDEV("div", {
|
|
54991
55131
|
className: "hidden-projects-page",
|
|
54992
55132
|
children: [
|
|
54993
|
-
/* @__PURE__ */
|
|
55133
|
+
/* @__PURE__ */ jsx_dev_runtime20.jsxDEV("div", {
|
|
54994
55134
|
className: "back-btn",
|
|
54995
55135
|
onClick: onBack,
|
|
54996
55136
|
children: "← Back to projects"
|
|
54997
55137
|
}, undefined, false, undefined, this),
|
|
54998
|
-
/* @__PURE__ */
|
|
55138
|
+
/* @__PURE__ */ jsx_dev_runtime20.jsxDEV("h2", {
|
|
54999
55139
|
style: { margin: "16px 0 12px", fontSize: "1.1rem", color: "var(--text-primary)" },
|
|
55000
55140
|
children: "Hidden Projects"
|
|
55001
55141
|
}, undefined, false, undefined, this),
|
|
55002
|
-
hidden.length === 0 ? /* @__PURE__ */
|
|
55142
|
+
hidden.length === 0 ? /* @__PURE__ */ jsx_dev_runtime20.jsxDEV("div", {
|
|
55003
55143
|
className: "empty-state",
|
|
55004
55144
|
children: [
|
|
55005
|
-
/* @__PURE__ */
|
|
55145
|
+
/* @__PURE__ */ jsx_dev_runtime20.jsxDEV("div", {
|
|
55006
55146
|
className: "empty-state-title",
|
|
55007
55147
|
children: "No hidden projects"
|
|
55008
55148
|
}, undefined, false, undefined, this),
|
|
55009
|
-
/* @__PURE__ */
|
|
55149
|
+
/* @__PURE__ */ jsx_dev_runtime20.jsxDEV("p", {
|
|
55010
55150
|
children: "Projects you hide will appear here"
|
|
55011
55151
|
}, undefined, false, undefined, this)
|
|
55012
55152
|
]
|
|
55013
|
-
}, undefined, true, undefined, this) : hidden.map((project) => /* @__PURE__ */
|
|
55153
|
+
}, undefined, true, undefined, this) : hidden.map((project) => /* @__PURE__ */ jsx_dev_runtime20.jsxDEV("div", {
|
|
55014
55154
|
className: "list-item list-item-with-action",
|
|
55015
55155
|
children: [
|
|
55016
|
-
/* @__PURE__ */
|
|
55156
|
+
/* @__PURE__ */ jsx_dev_runtime20.jsxDEV("div", {
|
|
55017
55157
|
className: "list-item-content",
|
|
55018
55158
|
children: [
|
|
55019
|
-
/* @__PURE__ */
|
|
55159
|
+
/* @__PURE__ */ jsx_dev_runtime20.jsxDEV("div", {
|
|
55020
55160
|
className: "list-item-title",
|
|
55021
55161
|
children: projectDisplayName(project)
|
|
55022
55162
|
}, undefined, false, undefined, this),
|
|
55023
|
-
/* @__PURE__ */
|
|
55163
|
+
/* @__PURE__ */ jsx_dev_runtime20.jsxDEV("div", {
|
|
55024
55164
|
className: "list-item-meta",
|
|
55025
55165
|
children: [
|
|
55026
55166
|
project.sessionCount,
|
|
@@ -55030,7 +55170,7 @@ function HiddenProjectList({ hiddenIds, onUnhide, onBack }) {
|
|
|
55030
55170
|
}, undefined, true, undefined, this)
|
|
55031
55171
|
]
|
|
55032
55172
|
}, undefined, true, undefined, this),
|
|
55033
|
-
/* @__PURE__ */
|
|
55173
|
+
/* @__PURE__ */ jsx_dev_runtime20.jsxDEV("button", {
|
|
55034
55174
|
type: "button",
|
|
55035
55175
|
className: "btn btn-sm",
|
|
55036
55176
|
onClick: () => onUnhide(project.encodedPath),
|
|
@@ -55042,198 +55182,20 @@ function HiddenProjectList({ hiddenIds, onUnhide, onBack }) {
|
|
|
55042
55182
|
}, undefined, true, undefined, this);
|
|
55043
55183
|
}
|
|
55044
55184
|
|
|
55045
|
-
// src/frontend/components/
|
|
55046
|
-
var
|
|
55047
|
-
|
|
55048
|
-
|
|
55049
|
-
|
|
55050
|
-
|
|
55051
|
-
|
|
55052
|
-
|
|
55053
|
-
|
|
55054
|
-
|
|
55055
|
-
|
|
55056
|
-
const [filter, setFilter] = import_react10.useState("");
|
|
55057
|
-
const projects = data?.projects ?? [];
|
|
55058
|
-
const filtered = projects.filter((p) => !hiddenIds.has(p.encodedPath) && (p.name.toLowerCase().includes(filter.toLowerCase()) || p.encodedPath.toLowerCase().includes(filter.toLowerCase())));
|
|
55059
|
-
if (loading)
|
|
55060
|
-
return /* @__PURE__ */ jsx_dev_runtime19.jsxDEV("div", {
|
|
55061
|
-
className: "loading",
|
|
55062
|
-
children: "Loading projects..."
|
|
55063
|
-
}, undefined, false, undefined, this);
|
|
55064
|
-
if (error) {
|
|
55065
|
-
return /* @__PURE__ */ jsx_dev_runtime19.jsxDEV("div", {
|
|
55066
|
-
className: "fetch-error",
|
|
55067
|
-
children: [
|
|
55068
|
-
/* @__PURE__ */ jsx_dev_runtime19.jsxDEV("span", {
|
|
55069
|
-
className: "fetch-error-message",
|
|
55070
|
-
children: error
|
|
55071
|
-
}, undefined, false, undefined, this),
|
|
55072
|
-
/* @__PURE__ */ jsx_dev_runtime19.jsxDEV("button", {
|
|
55073
|
-
type: "button",
|
|
55074
|
-
className: "btn btn-sm",
|
|
55075
|
-
onClick: retry,
|
|
55076
|
-
children: "Retry"
|
|
55077
|
-
}, undefined, false, undefined, this)
|
|
55078
|
-
]
|
|
55079
|
-
}, undefined, true, undefined, this);
|
|
55080
|
-
}
|
|
55081
|
-
return /* @__PURE__ */ jsx_dev_runtime19.jsxDEV("div", {
|
|
55082
|
-
children: [
|
|
55083
|
-
/* @__PURE__ */ jsx_dev_runtime19.jsxDEV("input", {
|
|
55084
|
-
className: "filter-input",
|
|
55085
|
-
placeholder: "Filter projects...",
|
|
55086
|
-
value: filter,
|
|
55087
|
-
onChange: (e) => setFilter(e.target.value)
|
|
55088
|
-
}, undefined, false, undefined, this),
|
|
55089
|
-
/* @__PURE__ */ jsx_dev_runtime19.jsxDEV("div", {
|
|
55090
|
-
className: "list-section-title",
|
|
55091
|
-
children: [
|
|
55092
|
-
"Projects (",
|
|
55093
|
-
filtered.length,
|
|
55094
|
-
")"
|
|
55095
|
-
]
|
|
55096
|
-
}, undefined, true, undefined, this),
|
|
55097
|
-
filtered.map((project) => /* @__PURE__ */ jsx_dev_runtime19.jsxDEV("div", {
|
|
55098
|
-
className: `list-item list-item-with-action ${selected === project.encodedPath ? "active" : ""}`,
|
|
55099
|
-
onClick: () => onSelect(project),
|
|
55100
|
-
children: [
|
|
55101
|
-
/* @__PURE__ */ jsx_dev_runtime19.jsxDEV("div", {
|
|
55102
|
-
className: "list-item-content",
|
|
55103
|
-
children: [
|
|
55104
|
-
/* @__PURE__ */ jsx_dev_runtime19.jsxDEV("div", {
|
|
55105
|
-
className: "list-item-title",
|
|
55106
|
-
children: projectDisplayName(project)
|
|
55107
|
-
}, undefined, false, undefined, this),
|
|
55108
|
-
/* @__PURE__ */ jsx_dev_runtime19.jsxDEV("div", {
|
|
55109
|
-
className: "list-item-meta",
|
|
55110
|
-
children: [
|
|
55111
|
-
project.sessionCount,
|
|
55112
|
-
" session",
|
|
55113
|
-
project.sessionCount !== 1 ? "s" : "",
|
|
55114
|
-
" · ",
|
|
55115
|
-
/* @__PURE__ */ jsx_dev_runtime19.jsxDEV("time", {
|
|
55116
|
-
dateTime: project.lastActivity,
|
|
55117
|
-
title: formatFullDateTime(project.lastActivity),
|
|
55118
|
-
children: formatRelativeTime(project.lastActivity)
|
|
55119
|
-
}, undefined, false, undefined, this)
|
|
55120
|
-
]
|
|
55121
|
-
}, undefined, true, undefined, this)
|
|
55122
|
-
]
|
|
55123
|
-
}, undefined, true, undefined, this),
|
|
55124
|
-
/* @__PURE__ */ jsx_dev_runtime19.jsxDEV("button", {
|
|
55125
|
-
type: "button",
|
|
55126
|
-
className: "btn-hide",
|
|
55127
|
-
title: "Hide project",
|
|
55128
|
-
onClick: (e) => {
|
|
55129
|
-
e.stopPropagation();
|
|
55130
|
-
onHide(project.encodedPath);
|
|
55131
|
-
},
|
|
55132
|
-
children: "×"
|
|
55133
|
-
}, undefined, false, undefined, this)
|
|
55134
|
-
]
|
|
55135
|
-
}, project.encodedPath, true, undefined, this)),
|
|
55136
|
-
filtered.length === 0 && /* @__PURE__ */ jsx_dev_runtime19.jsxDEV("div", {
|
|
55137
|
-
className: "empty-list-message",
|
|
55138
|
-
children: "No projects found"
|
|
55139
|
-
}, undefined, false, undefined, this),
|
|
55140
|
-
hiddenIds.size > 0 && /* @__PURE__ */ jsx_dev_runtime19.jsxDEV("div", {
|
|
55141
|
-
className: "hidden-projects-link",
|
|
55142
|
-
onClick: onShowHidden,
|
|
55143
|
-
children: [
|
|
55144
|
-
hiddenIds.size,
|
|
55145
|
-
" hidden project",
|
|
55146
|
-
hiddenIds.size !== 1 ? "s" : ""
|
|
55147
|
-
]
|
|
55148
|
-
}, undefined, true, undefined, this)
|
|
55149
|
-
]
|
|
55150
|
-
}, undefined, true, undefined, this);
|
|
55151
|
-
}
|
|
55152
|
-
|
|
55153
|
-
// src/frontend/components/project/SessionList.tsx
|
|
55154
|
-
var jsx_dev_runtime20 = __toESM(require_jsx_dev_runtime(), 1);
|
|
55155
|
-
function SessionList({ project, onSelect, onBack, selectedId }) {
|
|
55156
|
-
const { data, loading, error, retry } = useFetch(`/api/projects/${encodeURIComponent(project.encodedPath)}/sessions`, [project.encodedPath]);
|
|
55157
|
-
const sessions = data?.sessions ?? [];
|
|
55158
|
-
const parts = project.name.split("/").filter(Boolean);
|
|
55159
|
-
const displayName = parts.slice(-2).join("/");
|
|
55160
|
-
return /* @__PURE__ */ jsx_dev_runtime20.jsxDEV("div", {
|
|
55161
|
-
children: [
|
|
55162
|
-
/* @__PURE__ */ jsx_dev_runtime20.jsxDEV("div", {
|
|
55163
|
-
className: "back-btn",
|
|
55164
|
-
onClick: onBack,
|
|
55165
|
-
children: "← Projects"
|
|
55166
|
-
}, undefined, false, undefined, this),
|
|
55167
|
-
/* @__PURE__ */ jsx_dev_runtime20.jsxDEV("div", {
|
|
55168
|
-
className: "list-section-title",
|
|
55169
|
-
children: displayName
|
|
55170
|
-
}, undefined, false, undefined, this),
|
|
55171
|
-
loading && /* @__PURE__ */ jsx_dev_runtime20.jsxDEV("div", {
|
|
55172
|
-
className: "loading",
|
|
55173
|
-
children: "Loading sessions..."
|
|
55174
|
-
}, undefined, false, undefined, this),
|
|
55175
|
-
error && /* @__PURE__ */ jsx_dev_runtime20.jsxDEV("div", {
|
|
55176
|
-
className: "fetch-error",
|
|
55177
|
-
children: [
|
|
55178
|
-
/* @__PURE__ */ jsx_dev_runtime20.jsxDEV("span", {
|
|
55179
|
-
className: "fetch-error-message",
|
|
55180
|
-
children: error
|
|
55181
|
-
}, undefined, false, undefined, this),
|
|
55182
|
-
/* @__PURE__ */ jsx_dev_runtime20.jsxDEV("button", {
|
|
55183
|
-
type: "button",
|
|
55184
|
-
className: "btn btn-sm",
|
|
55185
|
-
onClick: retry,
|
|
55186
|
-
children: "Retry"
|
|
55187
|
-
}, undefined, false, undefined, this)
|
|
55188
|
-
]
|
|
55189
|
-
}, undefined, true, undefined, this),
|
|
55190
|
-
!loading && !error && sessions.map((session) => /* @__PURE__ */ jsx_dev_runtime20.jsxDEV("div", {
|
|
55191
|
-
className: `list-item ${selectedId === session.sessionId ? "active" : ""}${session.sessionType ? ` ${session.sessionType}` : ""}`,
|
|
55192
|
-
onClick: () => onSelect(session),
|
|
55193
|
-
children: [
|
|
55194
|
-
/* @__PURE__ */ jsx_dev_runtime20.jsxDEV("div", {
|
|
55195
|
-
className: "list-item-title",
|
|
55196
|
-
children: session.firstMessage || session.slug
|
|
55197
|
-
}, undefined, false, undefined, this),
|
|
55198
|
-
/* @__PURE__ */ jsx_dev_runtime20.jsxDEV("div", {
|
|
55199
|
-
className: "list-item-meta",
|
|
55200
|
-
children: [
|
|
55201
|
-
session.sessionType && /* @__PURE__ */ jsx_dev_runtime20.jsxDEV("span", {
|
|
55202
|
-
className: `session-type-badge ${session.sessionType}`,
|
|
55203
|
-
children: session.sessionType === "plan" ? "Plan" : "Impl"
|
|
55204
|
-
}, undefined, false, undefined, this),
|
|
55205
|
-
" ",
|
|
55206
|
-
session.model && /* @__PURE__ */ jsx_dev_runtime20.jsxDEV("span", {
|
|
55207
|
-
children: [
|
|
55208
|
-
shortModel(session.model),
|
|
55209
|
-
" · "
|
|
55210
|
-
]
|
|
55211
|
-
}, undefined, true, undefined, this),
|
|
55212
|
-
session.gitBranch && /* @__PURE__ */ jsx_dev_runtime20.jsxDEV("span", {
|
|
55213
|
-
children: [
|
|
55214
|
-
session.gitBranch,
|
|
55215
|
-
" · "
|
|
55216
|
-
]
|
|
55217
|
-
}, undefined, true, undefined, this),
|
|
55218
|
-
/* @__PURE__ */ jsx_dev_runtime20.jsxDEV("time", {
|
|
55219
|
-
dateTime: session.timestamp,
|
|
55220
|
-
title: formatFullDateTime(session.timestamp),
|
|
55221
|
-
children: formatTime(session.timestamp)
|
|
55222
|
-
}, undefined, false, undefined, this)
|
|
55223
|
-
]
|
|
55224
|
-
}, undefined, true, undefined, this)
|
|
55225
|
-
]
|
|
55226
|
-
}, session.sessionId, true, undefined, this)),
|
|
55227
|
-
!loading && !error && sessions.length === 0 && /* @__PURE__ */ jsx_dev_runtime20.jsxDEV("div", {
|
|
55228
|
-
className: "empty-list-message",
|
|
55229
|
-
children: "No sessions found"
|
|
55230
|
-
}, undefined, false, undefined, this)
|
|
55231
|
-
]
|
|
55232
|
-
}, undefined, true, undefined, this);
|
|
55185
|
+
// src/frontend/components/search/SearchModal.tsx
|
|
55186
|
+
var import_react12 = __toESM(require_react(), 1);
|
|
55187
|
+
|
|
55188
|
+
// src/frontend/utils/plugin.ts
|
|
55189
|
+
var PLUGIN_NAMES = {
|
|
55190
|
+
"claude-code": "Claude Code",
|
|
55191
|
+
"codex-cli": "Codex",
|
|
55192
|
+
opencode: "OpenCode"
|
|
55193
|
+
};
|
|
55194
|
+
function pluginDisplayName(pluginId) {
|
|
55195
|
+
return PLUGIN_NAMES[pluginId] ?? pluginId;
|
|
55233
55196
|
}
|
|
55234
55197
|
|
|
55235
55198
|
// src/frontend/components/search/SearchModal.tsx
|
|
55236
|
-
var import_react11 = __toESM(require_react(), 1);
|
|
55237
55199
|
var jsx_dev_runtime21 = __toESM(require_jsx_dev_runtime(), 1);
|
|
55238
55200
|
var MAX_RESULTS = 20;
|
|
55239
55201
|
function matchesQuery(result, query) {
|
|
@@ -55241,15 +55203,15 @@ function matchesQuery(result, query) {
|
|
|
55241
55203
|
return result.firstMessage.toLowerCase().includes(q2) || result.projectName.toLowerCase().includes(q2) || result.gitBranch.toLowerCase().includes(q2);
|
|
55242
55204
|
}
|
|
55243
55205
|
function SearchModal({ sessions, onSelect, onClose }) {
|
|
55244
|
-
const [query, setQuery] =
|
|
55245
|
-
const [highlightedIndex, setHighlightedIndex] =
|
|
55246
|
-
const inputRef =
|
|
55247
|
-
const resultsRef =
|
|
55206
|
+
const [query, setQuery] = import_react12.useState("");
|
|
55207
|
+
const [highlightedIndex, setHighlightedIndex] = import_react12.useState(0);
|
|
55208
|
+
const inputRef = import_react12.useRef(null);
|
|
55209
|
+
const resultsRef = import_react12.useRef(null);
|
|
55248
55210
|
const filtered = query ? sessions.filter((s2) => matchesQuery(s2, query)).slice(0, MAX_RESULTS) : sessions.slice(0, MAX_RESULTS);
|
|
55249
|
-
|
|
55211
|
+
import_react12.useEffect(() => {
|
|
55250
55212
|
inputRef.current?.focus();
|
|
55251
55213
|
}, []);
|
|
55252
|
-
|
|
55214
|
+
import_react12.useEffect(() => {
|
|
55253
55215
|
const container = resultsRef.current;
|
|
55254
55216
|
if (!container)
|
|
55255
55217
|
return;
|
|
@@ -55259,10 +55221,10 @@ function SearchModal({ sessions, onSelect, onClose }) {
|
|
|
55259
55221
|
item.scrollIntoView({ block: "nearest" });
|
|
55260
55222
|
}
|
|
55261
55223
|
}, [highlightedIndex]);
|
|
55262
|
-
const handleSelect =
|
|
55224
|
+
const handleSelect = import_react12.useCallback((result) => {
|
|
55263
55225
|
onSelect(result.encodedPath, result.sessionId);
|
|
55264
55226
|
}, [onSelect]);
|
|
55265
|
-
const handleKeyDown =
|
|
55227
|
+
const handleKeyDown = import_react12.useCallback((e) => {
|
|
55266
55228
|
switch (e.key) {
|
|
55267
55229
|
case "ArrowDown":
|
|
55268
55230
|
e.preventDefault();
|
|
@@ -55334,10 +55296,17 @@ function SearchModal({ sessions, onSelect, onClose }) {
|
|
|
55334
55296
|
className: "search-result-meta",
|
|
55335
55297
|
children: [
|
|
55336
55298
|
result.projectName,
|
|
55337
|
-
|
|
55338
|
-
|
|
55339
|
-
|
|
55340
|
-
|
|
55299
|
+
result.pluginId && /* @__PURE__ */ jsx_dev_runtime21.jsxDEV(jsx_dev_runtime21.Fragment, {
|
|
55300
|
+
children: [
|
|
55301
|
+
" ",
|
|
55302
|
+
/* @__PURE__ */ jsx_dev_runtime21.jsxDEV("span", {
|
|
55303
|
+
className: "plugin-badge",
|
|
55304
|
+
children: pluginDisplayName(result.pluginId)
|
|
55305
|
+
}, undefined, false, undefined, this)
|
|
55306
|
+
]
|
|
55307
|
+
}, undefined, true, undefined, this),
|
|
55308
|
+
" ",
|
|
55309
|
+
"·",
|
|
55341
55310
|
" ",
|
|
55342
55311
|
/* @__PURE__ */ jsx_dev_runtime21.jsxDEV("time", {
|
|
55343
55312
|
dateTime: result.timestamp,
|
|
@@ -55384,12 +55353,12 @@ function SearchModal({ sessions, onSelect, onClose }) {
|
|
|
55384
55353
|
}
|
|
55385
55354
|
|
|
55386
55355
|
// src/frontend/components/session/PresentationShell.tsx
|
|
55387
|
-
var
|
|
55356
|
+
var import_react15 = __toESM(require_react(), 1);
|
|
55388
55357
|
|
|
55389
55358
|
// src/frontend/hooks/useKeyboard.ts
|
|
55390
|
-
var
|
|
55359
|
+
var import_react13 = __toESM(require_react(), 1);
|
|
55391
55360
|
function useKeyboard(handlers2, active) {
|
|
55392
|
-
|
|
55361
|
+
import_react13.useEffect(() => {
|
|
55393
55362
|
if (!active)
|
|
55394
55363
|
return;
|
|
55395
55364
|
function handleKeyDown(e) {
|
|
@@ -55432,7 +55401,7 @@ function useKeyboard(handlers2, active) {
|
|
|
55432
55401
|
}
|
|
55433
55402
|
|
|
55434
55403
|
// src/frontend/hooks/usePresentationMode.ts
|
|
55435
|
-
var
|
|
55404
|
+
var import_react14 = __toESM(require_react(), 1);
|
|
55436
55405
|
function countSubSteps(turn) {
|
|
55437
55406
|
if (turn.kind !== "assistant")
|
|
55438
55407
|
return 1;
|
|
@@ -55440,10 +55409,10 @@ function countSubSteps(turn) {
|
|
|
55440
55409
|
return Math.max(groupContentBlocks(a.contentBlocks).length, 1);
|
|
55441
55410
|
}
|
|
55442
55411
|
function usePresentationMode(turns) {
|
|
55443
|
-
const [active, setActive] =
|
|
55444
|
-
const [fullscreen, setFullscreen] =
|
|
55445
|
-
const [currentStep, setCurrentStep] =
|
|
55446
|
-
const steps =
|
|
55412
|
+
const [active, setActive] = import_react14.useState(false);
|
|
55413
|
+
const [fullscreen, setFullscreen] = import_react14.useState(false);
|
|
55414
|
+
const [currentStep, setCurrentStep] = import_react14.useState(0);
|
|
55415
|
+
const steps = import_react14.useMemo(() => {
|
|
55447
55416
|
const result = [];
|
|
55448
55417
|
for (let i = 0;i < turns.length; i++) {
|
|
55449
55418
|
const sub = countSubSteps(turns[i]);
|
|
@@ -55454,7 +55423,7 @@ function usePresentationMode(turns) {
|
|
|
55454
55423
|
return result;
|
|
55455
55424
|
}, [turns]);
|
|
55456
55425
|
const totalSteps = steps.length;
|
|
55457
|
-
const turnBoundaries =
|
|
55426
|
+
const turnBoundaries = import_react14.useMemo(() => {
|
|
55458
55427
|
const boundaries = [];
|
|
55459
55428
|
for (let i = 0;i < steps.length; i++) {
|
|
55460
55429
|
const next2 = steps[i + 1];
|
|
@@ -55464,7 +55433,7 @@ function usePresentationMode(turns) {
|
|
|
55464
55433
|
}
|
|
55465
55434
|
return boundaries;
|
|
55466
55435
|
}, [steps]);
|
|
55467
|
-
const { visibleTurns, visibleSubSteps } =
|
|
55436
|
+
const { visibleTurns, visibleSubSteps } = import_react14.useMemo(() => {
|
|
55468
55437
|
if (!active || steps.length === 0) {
|
|
55469
55438
|
return { visibleTurns: turns, visibleSubSteps: new Map };
|
|
55470
55439
|
}
|
|
@@ -55478,22 +55447,22 @@ function usePresentationMode(turns) {
|
|
|
55478
55447
|
subSteps.set(maxTurnIndex, step.subStep + 1);
|
|
55479
55448
|
return { visibleTurns: visible, visibleSubSteps: subSteps };
|
|
55480
55449
|
}, [active, currentStep, steps, turns]);
|
|
55481
|
-
const enter =
|
|
55450
|
+
const enter = import_react14.useCallback(() => {
|
|
55482
55451
|
setActive(true);
|
|
55483
55452
|
setCurrentStep(0);
|
|
55484
55453
|
}, []);
|
|
55485
|
-
const exit3 =
|
|
55454
|
+
const exit3 = import_react14.useCallback(() => {
|
|
55486
55455
|
setActive(false);
|
|
55487
55456
|
setFullscreen(false);
|
|
55488
55457
|
setCurrentStep(0);
|
|
55489
55458
|
}, []);
|
|
55490
|
-
const next =
|
|
55459
|
+
const next = import_react14.useCallback(() => {
|
|
55491
55460
|
setCurrentStep((s2) => Math.min(s2 + 1, steps.length - 1));
|
|
55492
55461
|
}, [steps.length]);
|
|
55493
|
-
const prev =
|
|
55462
|
+
const prev = import_react14.useCallback(() => {
|
|
55494
55463
|
setCurrentStep((s2) => Math.max(s2 - 1, 0));
|
|
55495
55464
|
}, []);
|
|
55496
|
-
const nextTurn =
|
|
55465
|
+
const nextTurn = import_react14.useCallback(() => {
|
|
55497
55466
|
setCurrentStep((s2) => {
|
|
55498
55467
|
for (const b of turnBoundaries) {
|
|
55499
55468
|
if (b > s2)
|
|
@@ -55502,7 +55471,7 @@ function usePresentationMode(turns) {
|
|
|
55502
55471
|
return s2;
|
|
55503
55472
|
});
|
|
55504
55473
|
}, [turnBoundaries]);
|
|
55505
|
-
const prevTurn =
|
|
55474
|
+
const prevTurn = import_react14.useCallback(() => {
|
|
55506
55475
|
setCurrentStep((s2) => {
|
|
55507
55476
|
for (let i = turnBoundaries.length - 1;i >= 0; i--) {
|
|
55508
55477
|
if (turnBoundaries[i] < s2)
|
|
@@ -55511,7 +55480,7 @@ function usePresentationMode(turns) {
|
|
|
55511
55480
|
return s2;
|
|
55512
55481
|
});
|
|
55513
55482
|
}, [turnBoundaries]);
|
|
55514
|
-
const toggleFullscreen =
|
|
55483
|
+
const toggleFullscreen = import_react14.useCallback(() => {
|
|
55515
55484
|
setFullscreen((f) => !f);
|
|
55516
55485
|
}, []);
|
|
55517
55486
|
return {
|
|
@@ -55538,11 +55507,12 @@ function PresentationShell({
|
|
|
55538
55507
|
onExit,
|
|
55539
55508
|
sessionId,
|
|
55540
55509
|
project,
|
|
55510
|
+
pluginId,
|
|
55541
55511
|
isSubAgent
|
|
55542
55512
|
}) {
|
|
55543
|
-
const scrollRef =
|
|
55513
|
+
const scrollRef = import_react15.useRef(null);
|
|
55544
55514
|
const presentation = usePresentationMode(turns);
|
|
55545
|
-
|
|
55515
|
+
import_react15.useEffect(() => {
|
|
55546
55516
|
if (turns.length > 0 && !presentation.active) {
|
|
55547
55517
|
presentation.enter();
|
|
55548
55518
|
}
|
|
@@ -55556,7 +55526,7 @@ function PresentationShell({
|
|
|
55556
55526
|
onFullscreen: presentation.toggleFullscreen
|
|
55557
55527
|
}, presentation.active);
|
|
55558
55528
|
const currentStep = presentation.currentStep;
|
|
55559
|
-
|
|
55529
|
+
import_react15.useEffect(() => {
|
|
55560
55530
|
if (currentStep >= 0 && scrollRef.current) {
|
|
55561
55531
|
scrollRef.current.scrollTop = scrollRef.current.scrollHeight;
|
|
55562
55532
|
}
|
|
@@ -55572,6 +55542,7 @@ function PresentationShell({
|
|
|
55572
55542
|
visibleSubSteps: presentation.visibleSubSteps,
|
|
55573
55543
|
sessionId,
|
|
55574
55544
|
project,
|
|
55545
|
+
pluginId,
|
|
55575
55546
|
isSubAgent
|
|
55576
55547
|
}, undefined, false, undefined, this),
|
|
55577
55548
|
/* @__PURE__ */ jsx_dev_runtime22.jsxDEV("div", {
|
|
@@ -55605,81 +55576,70 @@ function PresentationShell({
|
|
|
55605
55576
|
// src/frontend/components/session/SessionPresentation.tsx
|
|
55606
55577
|
var jsx_dev_runtime23 = __toESM(require_jsx_dev_runtime(), 1);
|
|
55607
55578
|
function SessionPresentation({ sessionId, project, onExit }) {
|
|
55608
|
-
const { data, loading, error, retry } =
|
|
55579
|
+
const { data, loading, error, retry } = useSessionData(sessionId, project);
|
|
55609
55580
|
if (loading)
|
|
55610
55581
|
return /* @__PURE__ */ jsx_dev_runtime23.jsxDEV("div", {
|
|
55611
55582
|
className: "loading",
|
|
55612
55583
|
children: "Loading session..."
|
|
55613
55584
|
}, undefined, false, undefined, this);
|
|
55614
|
-
if (error)
|
|
55615
|
-
return /* @__PURE__ */ jsx_dev_runtime23.jsxDEV(
|
|
55616
|
-
|
|
55617
|
-
|
|
55618
|
-
|
|
55619
|
-
|
|
55620
|
-
children: [
|
|
55621
|
-
"Error: ",
|
|
55622
|
-
error
|
|
55623
|
-
]
|
|
55624
|
-
}, undefined, true, undefined, this),
|
|
55625
|
-
/* @__PURE__ */ jsx_dev_runtime23.jsxDEV("button", {
|
|
55626
|
-
type: "button",
|
|
55627
|
-
className: "btn btn-sm",
|
|
55628
|
-
onClick: retry,
|
|
55629
|
-
children: "Retry"
|
|
55630
|
-
}, undefined, false, undefined, this)
|
|
55631
|
-
]
|
|
55632
|
-
}, undefined, true, undefined, this);
|
|
55633
|
-
}
|
|
55585
|
+
if (error)
|
|
55586
|
+
return /* @__PURE__ */ jsx_dev_runtime23.jsxDEV(FetchError, {
|
|
55587
|
+
error,
|
|
55588
|
+
onRetry: retry,
|
|
55589
|
+
showPrefix: true
|
|
55590
|
+
}, undefined, false, undefined, this);
|
|
55634
55591
|
if (!data?.session)
|
|
55635
55592
|
return null;
|
|
55636
55593
|
return /* @__PURE__ */ jsx_dev_runtime23.jsxDEV(PresentationShell, {
|
|
55637
55594
|
turns: data.session.turns,
|
|
55638
55595
|
onExit,
|
|
55639
55596
|
sessionId,
|
|
55640
|
-
project
|
|
55597
|
+
project,
|
|
55598
|
+
pluginId: data.session.pluginId
|
|
55641
55599
|
}, undefined, false, undefined, this);
|
|
55642
55600
|
}
|
|
55643
55601
|
|
|
55644
55602
|
// src/frontend/components/session/SessionView.tsx
|
|
55645
55603
|
var jsx_dev_runtime24 = __toESM(require_jsx_dev_runtime(), 1);
|
|
55646
|
-
function SessionView({ sessionId, project }) {
|
|
55647
|
-
const { data, loading, error, retry } =
|
|
55604
|
+
function SessionView({ sessionId, project, gitBranch }) {
|
|
55605
|
+
const { data, loading, error, retry } = useSessionData(sessionId, project);
|
|
55648
55606
|
if (loading)
|
|
55649
55607
|
return /* @__PURE__ */ jsx_dev_runtime24.jsxDEV("div", {
|
|
55650
55608
|
className: "loading",
|
|
55651
55609
|
children: "Loading session..."
|
|
55652
55610
|
}, undefined, false, undefined, this);
|
|
55653
|
-
if (error)
|
|
55654
|
-
return /* @__PURE__ */ jsx_dev_runtime24.jsxDEV(
|
|
55655
|
-
|
|
55656
|
-
|
|
55657
|
-
|
|
55658
|
-
|
|
55659
|
-
children: [
|
|
55660
|
-
"Error: ",
|
|
55661
|
-
error
|
|
55662
|
-
]
|
|
55663
|
-
}, undefined, true, undefined, this),
|
|
55664
|
-
/* @__PURE__ */ jsx_dev_runtime24.jsxDEV("button", {
|
|
55665
|
-
type: "button",
|
|
55666
|
-
className: "btn btn-sm",
|
|
55667
|
-
onClick: retry,
|
|
55668
|
-
children: "Retry"
|
|
55669
|
-
}, undefined, false, undefined, this)
|
|
55670
|
-
]
|
|
55671
|
-
}, undefined, true, undefined, this);
|
|
55672
|
-
}
|
|
55611
|
+
if (error)
|
|
55612
|
+
return /* @__PURE__ */ jsx_dev_runtime24.jsxDEV(FetchError, {
|
|
55613
|
+
error,
|
|
55614
|
+
onRetry: retry,
|
|
55615
|
+
showPrefix: true
|
|
55616
|
+
}, undefined, false, undefined, this);
|
|
55673
55617
|
if (!data?.session)
|
|
55674
55618
|
return null;
|
|
55675
55619
|
const session = data.session;
|
|
55676
|
-
return /* @__PURE__ */ jsx_dev_runtime24.jsxDEV(
|
|
55677
|
-
|
|
55678
|
-
|
|
55679
|
-
|
|
55680
|
-
|
|
55681
|
-
|
|
55682
|
-
|
|
55620
|
+
return /* @__PURE__ */ jsx_dev_runtime24.jsxDEV(jsx_dev_runtime24.Fragment, {
|
|
55621
|
+
children: [
|
|
55622
|
+
gitBranch && /* @__PURE__ */ jsx_dev_runtime24.jsxDEV("div", {
|
|
55623
|
+
className: "session-branch-bar",
|
|
55624
|
+
children: [
|
|
55625
|
+
/* @__PURE__ */ jsx_dev_runtime24.jsxDEV("span", {
|
|
55626
|
+
className: "session-branch-icon",
|
|
55627
|
+
children: "⎇"
|
|
55628
|
+
}, undefined, false, undefined, this),
|
|
55629
|
+
" ",
|
|
55630
|
+
gitBranch
|
|
55631
|
+
]
|
|
55632
|
+
}, undefined, true, undefined, this),
|
|
55633
|
+
/* @__PURE__ */ jsx_dev_runtime24.jsxDEV(MessageList, {
|
|
55634
|
+
turns: session.turns,
|
|
55635
|
+
sessionId,
|
|
55636
|
+
project,
|
|
55637
|
+
pluginId: session.pluginId,
|
|
55638
|
+
planSessionId: session.planSessionId,
|
|
55639
|
+
implSessionId: session.implSessionId
|
|
55640
|
+
}, undefined, false, undefined, this)
|
|
55641
|
+
]
|
|
55642
|
+
}, undefined, true, undefined, this);
|
|
55683
55643
|
}
|
|
55684
55644
|
|
|
55685
55645
|
// src/frontend/components/session/SubAgentPresentation.tsx
|
|
@@ -55690,32 +55650,18 @@ function SubAgentPresentation({
|
|
|
55690
55650
|
agentId,
|
|
55691
55651
|
onExit
|
|
55692
55652
|
}) {
|
|
55693
|
-
const { data, loading, error, retry } =
|
|
55653
|
+
const { data, loading, error, retry } = useSubAgentSessionData(sessionId, project, agentId);
|
|
55694
55654
|
if (loading)
|
|
55695
55655
|
return /* @__PURE__ */ jsx_dev_runtime25.jsxDEV("div", {
|
|
55696
55656
|
className: "loading",
|
|
55697
55657
|
children: "Loading sub-agent conversation..."
|
|
55698
55658
|
}, undefined, false, undefined, this);
|
|
55699
|
-
if (error)
|
|
55700
|
-
return /* @__PURE__ */ jsx_dev_runtime25.jsxDEV(
|
|
55701
|
-
|
|
55702
|
-
|
|
55703
|
-
|
|
55704
|
-
|
|
55705
|
-
children: [
|
|
55706
|
-
"Error: ",
|
|
55707
|
-
error
|
|
55708
|
-
]
|
|
55709
|
-
}, undefined, true, undefined, this),
|
|
55710
|
-
/* @__PURE__ */ jsx_dev_runtime25.jsxDEV("button", {
|
|
55711
|
-
type: "button",
|
|
55712
|
-
className: "btn btn-sm",
|
|
55713
|
-
onClick: retry,
|
|
55714
|
-
children: "Retry"
|
|
55715
|
-
}, undefined, false, undefined, this)
|
|
55716
|
-
]
|
|
55717
|
-
}, undefined, true, undefined, this);
|
|
55718
|
-
}
|
|
55659
|
+
if (error)
|
|
55660
|
+
return /* @__PURE__ */ jsx_dev_runtime25.jsxDEV(FetchError, {
|
|
55661
|
+
error,
|
|
55662
|
+
onRetry: retry,
|
|
55663
|
+
showPrefix: true
|
|
55664
|
+
}, undefined, false, undefined, this);
|
|
55719
55665
|
if (!data?.session || data.session.turns.length === 0)
|
|
55720
55666
|
return null;
|
|
55721
55667
|
return /* @__PURE__ */ jsx_dev_runtime25.jsxDEV(PresentationShell, {
|
|
@@ -55723,12 +55669,13 @@ function SubAgentPresentation({
|
|
|
55723
55669
|
onExit,
|
|
55724
55670
|
sessionId,
|
|
55725
55671
|
project,
|
|
55672
|
+
pluginId: data.session.pluginId,
|
|
55726
55673
|
isSubAgent: true
|
|
55727
55674
|
}, undefined, false, undefined, this);
|
|
55728
55675
|
}
|
|
55729
55676
|
|
|
55730
55677
|
// src/frontend/hooks/useHiddenProjects.ts
|
|
55731
|
-
var
|
|
55678
|
+
var import_react16 = __toESM(require_react(), 1);
|
|
55732
55679
|
var STORAGE_KEY = "klovi-hidden-projects";
|
|
55733
55680
|
function loadHiddenIds() {
|
|
55734
55681
|
try {
|
|
@@ -55750,8 +55697,8 @@ function persistHiddenIds(ids) {
|
|
|
55750
55697
|
localStorage.setItem(STORAGE_KEY, JSON.stringify(store));
|
|
55751
55698
|
}
|
|
55752
55699
|
function useHiddenProjects() {
|
|
55753
|
-
const [hiddenIds, setHiddenIds] =
|
|
55754
|
-
const hide =
|
|
55700
|
+
const [hiddenIds, setHiddenIds] = import_react16.useState(() => loadHiddenIds());
|
|
55701
|
+
const hide = import_react16.useCallback((encodedPath) => {
|
|
55755
55702
|
setHiddenIds((prev) => {
|
|
55756
55703
|
const next = new Set(prev);
|
|
55757
55704
|
next.add(encodedPath);
|
|
@@ -55759,7 +55706,7 @@ function useHiddenProjects() {
|
|
|
55759
55706
|
return next;
|
|
55760
55707
|
});
|
|
55761
55708
|
}, []);
|
|
55762
|
-
const unhide =
|
|
55709
|
+
const unhide = import_react16.useCallback((encodedPath) => {
|
|
55763
55710
|
setHiddenIds((prev) => {
|
|
55764
55711
|
const next = new Set(prev);
|
|
55765
55712
|
next.delete(encodedPath);
|
|
@@ -55767,12 +55714,38 @@ function useHiddenProjects() {
|
|
|
55767
55714
|
return next;
|
|
55768
55715
|
});
|
|
55769
55716
|
}, []);
|
|
55770
|
-
const isHidden =
|
|
55717
|
+
const isHidden = import_react16.useCallback((encodedPath) => hiddenIds.has(encodedPath), [hiddenIds]);
|
|
55771
55718
|
return { hiddenIds, hide, unhide, isHidden };
|
|
55772
55719
|
}
|
|
55773
55720
|
|
|
55774
|
-
// src/frontend/
|
|
55775
|
-
var
|
|
55721
|
+
// src/frontend/hooks/useViewState.ts
|
|
55722
|
+
var import_react17 = __toESM(require_react(), 1);
|
|
55723
|
+
|
|
55724
|
+
// src/shared/session-id.ts
|
|
55725
|
+
var SESSION_ID_SEPARATOR = "::";
|
|
55726
|
+
function parseSessionId(sessionId) {
|
|
55727
|
+
const separatorIdx = sessionId.indexOf(SESSION_ID_SEPARATOR);
|
|
55728
|
+
if (separatorIdx === -1) {
|
|
55729
|
+
return { pluginId: null, rawSessionId: sessionId };
|
|
55730
|
+
}
|
|
55731
|
+
return {
|
|
55732
|
+
pluginId: sessionId.slice(0, separatorIdx),
|
|
55733
|
+
rawSessionId: sessionId.slice(separatorIdx + SESSION_ID_SEPARATOR.length)
|
|
55734
|
+
};
|
|
55735
|
+
}
|
|
55736
|
+
|
|
55737
|
+
// src/frontend/view-state.ts
|
|
55738
|
+
function getResumeCommand(pluginId, encodedSessionId) {
|
|
55739
|
+
const rawSessionId = parseSessionId(encodedSessionId).rawSessionId;
|
|
55740
|
+
switch (pluginId) {
|
|
55741
|
+
case "claude-code":
|
|
55742
|
+
return `claude --resume ${rawSessionId}`;
|
|
55743
|
+
case "codex-cli":
|
|
55744
|
+
return `codex resume ${rawSessionId}`;
|
|
55745
|
+
default:
|
|
55746
|
+
return;
|
|
55747
|
+
}
|
|
55748
|
+
}
|
|
55776
55749
|
function viewToHash(view) {
|
|
55777
55750
|
if (view.kind === "hidden")
|
|
55778
55751
|
return "#/hidden";
|
|
@@ -55784,6 +55757,33 @@ function viewToHash(view) {
|
|
|
55784
55757
|
return `#/${view.project.encodedPath}/${view.sessionId}/subagent/${view.agentId}`;
|
|
55785
55758
|
return "#/";
|
|
55786
55759
|
}
|
|
55760
|
+
async function loadProject(encodedPath) {
|
|
55761
|
+
const res = await fetch("/api/projects");
|
|
55762
|
+
if (!res.ok)
|
|
55763
|
+
return;
|
|
55764
|
+
const data = await res.json();
|
|
55765
|
+
return data.projects.find((p) => p.encodedPath === encodedPath);
|
|
55766
|
+
}
|
|
55767
|
+
async function loadProjectSession(project, sessionId) {
|
|
55768
|
+
const res = await fetch(`/api/projects/${encodeURIComponent(project.encodedPath)}/sessions`);
|
|
55769
|
+
if (!res.ok)
|
|
55770
|
+
return;
|
|
55771
|
+
const data = await res.json();
|
|
55772
|
+
return data.sessions.find((s2) => s2.sessionId === sessionId);
|
|
55773
|
+
}
|
|
55774
|
+
async function resolveProjectAndSession(encodedPath, sessionId) {
|
|
55775
|
+
try {
|
|
55776
|
+
const project = await loadProject(encodedPath);
|
|
55777
|
+
if (!project)
|
|
55778
|
+
return null;
|
|
55779
|
+
const session = await loadProjectSession(project, sessionId);
|
|
55780
|
+
if (!session)
|
|
55781
|
+
return null;
|
|
55782
|
+
return { project, session };
|
|
55783
|
+
} catch {
|
|
55784
|
+
return null;
|
|
55785
|
+
}
|
|
55786
|
+
}
|
|
55787
55787
|
async function restoreFromHash() {
|
|
55788
55788
|
const hash = window.location.hash.replace(/^#\/?/, "");
|
|
55789
55789
|
if (!hash)
|
|
@@ -55794,11 +55794,11 @@ async function restoreFromHash() {
|
|
|
55794
55794
|
const encodedPath = parts[0];
|
|
55795
55795
|
const sessionId = parts[1];
|
|
55796
55796
|
const isSubAgent = parts[2] === "subagent" && parts[3];
|
|
55797
|
+
if (!encodedPath)
|
|
55798
|
+
return { kind: "home" };
|
|
55797
55799
|
let project;
|
|
55798
55800
|
try {
|
|
55799
|
-
|
|
55800
|
-
const data = await res.json();
|
|
55801
|
-
project = data.projects.find((p) => p.encodedPath === encodedPath);
|
|
55801
|
+
project = await loadProject(encodedPath);
|
|
55802
55802
|
} catch {
|
|
55803
55803
|
return { kind: "home" };
|
|
55804
55804
|
}
|
|
@@ -55810,9 +55810,7 @@ async function restoreFromHash() {
|
|
|
55810
55810
|
return { kind: "subagent", project, sessionId, agentId: parts[3], presenting: false };
|
|
55811
55811
|
}
|
|
55812
55812
|
try {
|
|
55813
|
-
const
|
|
55814
|
-
const data = await res.json();
|
|
55815
|
-
const session = data.sessions.find((s2) => s2.sessionId === sessionId);
|
|
55813
|
+
const session = await loadProjectSession(project, sessionId);
|
|
55816
55814
|
if (session) {
|
|
55817
55815
|
return { kind: "session", project, session, presenting: false };
|
|
55818
55816
|
}
|
|
@@ -55843,111 +55841,328 @@ function getHeaderInfo(view) {
|
|
|
55843
55841
|
}
|
|
55844
55842
|
return { title: "Klovi", breadcrumb: "" };
|
|
55845
55843
|
}
|
|
55846
|
-
|
|
55844
|
+
|
|
55845
|
+
// src/frontend/hooks/useViewState.ts
|
|
55846
|
+
function useViewState() {
|
|
55847
|
+
const [view, setView] = import_react17.useState({ kind: "home" });
|
|
55848
|
+
const [ready, setReady] = import_react17.useState(false);
|
|
55849
|
+
import_react17.useEffect(() => {
|
|
55850
|
+
restoreFromHash().then((v2) => {
|
|
55851
|
+
setView(v2);
|
|
55852
|
+
setReady(true);
|
|
55853
|
+
});
|
|
55854
|
+
}, []);
|
|
55855
|
+
import_react17.useEffect(() => {
|
|
55856
|
+
if (!ready)
|
|
55857
|
+
return;
|
|
55858
|
+
const newHash = viewToHash(view);
|
|
55859
|
+
if (window.location.hash !== newHash) {
|
|
55860
|
+
history.pushState(null, "", newHash);
|
|
55861
|
+
}
|
|
55862
|
+
}, [view, ready]);
|
|
55863
|
+
import_react17.useEffect(() => {
|
|
55864
|
+
const handler = () => {
|
|
55865
|
+
restoreFromHash().then(setView);
|
|
55866
|
+
};
|
|
55867
|
+
window.addEventListener("popstate", handler);
|
|
55868
|
+
return () => window.removeEventListener("popstate", handler);
|
|
55869
|
+
}, []);
|
|
55870
|
+
const selectProject = import_react17.useCallback((project) => {
|
|
55871
|
+
setView({ kind: "project", project });
|
|
55872
|
+
}, []);
|
|
55873
|
+
const selectSession = import_react17.useCallback((session) => {
|
|
55874
|
+
setView((current) => {
|
|
55875
|
+
if (current.kind === "project" || current.kind === "session") {
|
|
55876
|
+
return {
|
|
55877
|
+
kind: "session",
|
|
55878
|
+
project: current.project,
|
|
55879
|
+
session,
|
|
55880
|
+
presenting: false
|
|
55881
|
+
};
|
|
55882
|
+
}
|
|
55883
|
+
return current;
|
|
55884
|
+
});
|
|
55885
|
+
}, []);
|
|
55886
|
+
const goHome = import_react17.useCallback(() => setView({ kind: "home" }), []);
|
|
55887
|
+
const goHidden = import_react17.useCallback(() => setView({ kind: "hidden" }), []);
|
|
55888
|
+
const canPresent = view.kind === "session" || view.kind === "subagent";
|
|
55889
|
+
const togglePresentation = import_react17.useCallback(() => {
|
|
55890
|
+
setView((current) => {
|
|
55891
|
+
if (current.kind === "session" || current.kind === "subagent") {
|
|
55892
|
+
return { ...current, presenting: !current.presenting };
|
|
55893
|
+
}
|
|
55894
|
+
return current;
|
|
55895
|
+
});
|
|
55896
|
+
}, []);
|
|
55897
|
+
return {
|
|
55898
|
+
view,
|
|
55899
|
+
ready,
|
|
55900
|
+
setView,
|
|
55901
|
+
selectProject,
|
|
55902
|
+
selectSession,
|
|
55903
|
+
goHome,
|
|
55904
|
+
goHidden,
|
|
55905
|
+
canPresent,
|
|
55906
|
+
togglePresentation
|
|
55907
|
+
};
|
|
55908
|
+
}
|
|
55909
|
+
|
|
55910
|
+
// src/frontend/components/project/ProjectList.tsx
|
|
55911
|
+
var import_react18 = __toESM(require_react(), 1);
|
|
55912
|
+
var jsx_dev_runtime26 = __toESM(require_jsx_dev_runtime(), 1);
|
|
55913
|
+
function ProjectList({
|
|
55914
|
+
onSelect,
|
|
55915
|
+
selected,
|
|
55916
|
+
hiddenIds,
|
|
55917
|
+
onHide,
|
|
55918
|
+
onShowHidden
|
|
55919
|
+
}) {
|
|
55920
|
+
const { data, loading, error, retry } = useFetch("/api/projects", []);
|
|
55921
|
+
const [filter, setFilter] = import_react18.useState("");
|
|
55922
|
+
const projects = data?.projects ?? [];
|
|
55923
|
+
const filtered = projects.filter((p) => !hiddenIds.has(p.encodedPath) && (p.name.toLowerCase().includes(filter.toLowerCase()) || p.encodedPath.toLowerCase().includes(filter.toLowerCase())));
|
|
55924
|
+
if (loading)
|
|
55925
|
+
return /* @__PURE__ */ jsx_dev_runtime26.jsxDEV("div", {
|
|
55926
|
+
className: "loading",
|
|
55927
|
+
children: "Loading projects..."
|
|
55928
|
+
}, undefined, false, undefined, this);
|
|
55929
|
+
if (error) {
|
|
55930
|
+
return /* @__PURE__ */ jsx_dev_runtime26.jsxDEV("div", {
|
|
55931
|
+
className: "fetch-error",
|
|
55932
|
+
children: [
|
|
55933
|
+
/* @__PURE__ */ jsx_dev_runtime26.jsxDEV("span", {
|
|
55934
|
+
className: "fetch-error-message",
|
|
55935
|
+
children: error
|
|
55936
|
+
}, undefined, false, undefined, this),
|
|
55937
|
+
/* @__PURE__ */ jsx_dev_runtime26.jsxDEV("button", {
|
|
55938
|
+
type: "button",
|
|
55939
|
+
className: "btn btn-sm",
|
|
55940
|
+
onClick: retry,
|
|
55941
|
+
children: "Retry"
|
|
55942
|
+
}, undefined, false, undefined, this)
|
|
55943
|
+
]
|
|
55944
|
+
}, undefined, true, undefined, this);
|
|
55945
|
+
}
|
|
55946
|
+
return /* @__PURE__ */ jsx_dev_runtime26.jsxDEV("div", {
|
|
55947
|
+
children: [
|
|
55948
|
+
/* @__PURE__ */ jsx_dev_runtime26.jsxDEV("input", {
|
|
55949
|
+
className: "filter-input",
|
|
55950
|
+
placeholder: "Filter projects...",
|
|
55951
|
+
value: filter,
|
|
55952
|
+
onChange: (e) => setFilter(e.target.value)
|
|
55953
|
+
}, undefined, false, undefined, this),
|
|
55954
|
+
/* @__PURE__ */ jsx_dev_runtime26.jsxDEV("div", {
|
|
55955
|
+
className: "list-section-title",
|
|
55956
|
+
children: [
|
|
55957
|
+
"Projects (",
|
|
55958
|
+
filtered.length,
|
|
55959
|
+
")"
|
|
55960
|
+
]
|
|
55961
|
+
}, undefined, true, undefined, this),
|
|
55962
|
+
filtered.map((project) => /* @__PURE__ */ jsx_dev_runtime26.jsxDEV("div", {
|
|
55963
|
+
className: `list-item list-item-with-action ${selected === project.encodedPath ? "active" : ""}`,
|
|
55964
|
+
onClick: () => onSelect(project),
|
|
55965
|
+
children: [
|
|
55966
|
+
/* @__PURE__ */ jsx_dev_runtime26.jsxDEV("div", {
|
|
55967
|
+
className: "list-item-content",
|
|
55968
|
+
children: [
|
|
55969
|
+
/* @__PURE__ */ jsx_dev_runtime26.jsxDEV("div", {
|
|
55970
|
+
className: "list-item-title",
|
|
55971
|
+
children: projectDisplayName(project)
|
|
55972
|
+
}, undefined, false, undefined, this),
|
|
55973
|
+
/* @__PURE__ */ jsx_dev_runtime26.jsxDEV("div", {
|
|
55974
|
+
className: "list-item-meta",
|
|
55975
|
+
children: [
|
|
55976
|
+
project.sessionCount,
|
|
55977
|
+
" session",
|
|
55978
|
+
project.sessionCount !== 1 ? "s" : "",
|
|
55979
|
+
" · ",
|
|
55980
|
+
/* @__PURE__ */ jsx_dev_runtime26.jsxDEV("time", {
|
|
55981
|
+
dateTime: project.lastActivity,
|
|
55982
|
+
title: formatFullDateTime(project.lastActivity),
|
|
55983
|
+
children: formatRelativeTime(project.lastActivity)
|
|
55984
|
+
}, undefined, false, undefined, this)
|
|
55985
|
+
]
|
|
55986
|
+
}, undefined, true, undefined, this)
|
|
55987
|
+
]
|
|
55988
|
+
}, undefined, true, undefined, this),
|
|
55989
|
+
/* @__PURE__ */ jsx_dev_runtime26.jsxDEV("button", {
|
|
55990
|
+
type: "button",
|
|
55991
|
+
className: "btn-hide",
|
|
55992
|
+
title: "Hide project",
|
|
55993
|
+
onClick: (e) => {
|
|
55994
|
+
e.stopPropagation();
|
|
55995
|
+
onHide(project.encodedPath);
|
|
55996
|
+
},
|
|
55997
|
+
children: "×"
|
|
55998
|
+
}, undefined, false, undefined, this)
|
|
55999
|
+
]
|
|
56000
|
+
}, project.encodedPath, true, undefined, this)),
|
|
56001
|
+
filtered.length === 0 && /* @__PURE__ */ jsx_dev_runtime26.jsxDEV("div", {
|
|
56002
|
+
className: "empty-list-message",
|
|
56003
|
+
children: "No projects found"
|
|
56004
|
+
}, undefined, false, undefined, this),
|
|
56005
|
+
hiddenIds.size > 0 && /* @__PURE__ */ jsx_dev_runtime26.jsxDEV("div", {
|
|
56006
|
+
className: "hidden-projects-link",
|
|
56007
|
+
onClick: onShowHidden,
|
|
56008
|
+
children: [
|
|
56009
|
+
hiddenIds.size,
|
|
56010
|
+
" hidden project",
|
|
56011
|
+
hiddenIds.size !== 1 ? "s" : ""
|
|
56012
|
+
]
|
|
56013
|
+
}, undefined, true, undefined, this)
|
|
56014
|
+
]
|
|
56015
|
+
}, undefined, true, undefined, this);
|
|
56016
|
+
}
|
|
56017
|
+
|
|
56018
|
+
// src/frontend/components/project/SessionList.tsx
|
|
56019
|
+
var jsx_dev_runtime27 = __toESM(require_jsx_dev_runtime(), 1);
|
|
56020
|
+
function SessionList({ project, onSelect, onBack, selectedId }) {
|
|
56021
|
+
const { data, loading, error, retry } = useFetch(`/api/projects/${encodeURIComponent(project.encodedPath)}/sessions`, [project.encodedPath]);
|
|
56022
|
+
const sessions = data?.sessions ?? [];
|
|
56023
|
+
const parts = project.name.split("/").filter(Boolean);
|
|
56024
|
+
const displayName = parts.slice(-2).join("/");
|
|
56025
|
+
return /* @__PURE__ */ jsx_dev_runtime27.jsxDEV("div", {
|
|
56026
|
+
children: [
|
|
56027
|
+
/* @__PURE__ */ jsx_dev_runtime27.jsxDEV("div", {
|
|
56028
|
+
className: "back-btn",
|
|
56029
|
+
onClick: onBack,
|
|
56030
|
+
children: "← Projects"
|
|
56031
|
+
}, undefined, false, undefined, this),
|
|
56032
|
+
/* @__PURE__ */ jsx_dev_runtime27.jsxDEV("div", {
|
|
56033
|
+
className: "list-section-title",
|
|
56034
|
+
children: displayName
|
|
56035
|
+
}, undefined, false, undefined, this),
|
|
56036
|
+
loading && /* @__PURE__ */ jsx_dev_runtime27.jsxDEV("div", {
|
|
56037
|
+
className: "loading",
|
|
56038
|
+
children: "Loading sessions..."
|
|
56039
|
+
}, undefined, false, undefined, this),
|
|
56040
|
+
error && /* @__PURE__ */ jsx_dev_runtime27.jsxDEV("div", {
|
|
56041
|
+
className: "fetch-error",
|
|
56042
|
+
children: [
|
|
56043
|
+
/* @__PURE__ */ jsx_dev_runtime27.jsxDEV("span", {
|
|
56044
|
+
className: "fetch-error-message",
|
|
56045
|
+
children: error
|
|
56046
|
+
}, undefined, false, undefined, this),
|
|
56047
|
+
/* @__PURE__ */ jsx_dev_runtime27.jsxDEV("button", {
|
|
56048
|
+
type: "button",
|
|
56049
|
+
className: "btn btn-sm",
|
|
56050
|
+
onClick: retry,
|
|
56051
|
+
children: "Retry"
|
|
56052
|
+
}, undefined, false, undefined, this)
|
|
56053
|
+
]
|
|
56054
|
+
}, undefined, true, undefined, this),
|
|
56055
|
+
!loading && !error && sessions.map((session) => /* @__PURE__ */ jsx_dev_runtime27.jsxDEV("div", {
|
|
56056
|
+
className: `list-item ${selectedId === session.sessionId ? "active" : ""}${session.sessionType ? ` ${session.sessionType}` : ""}`,
|
|
56057
|
+
onClick: () => onSelect(session),
|
|
56058
|
+
children: [
|
|
56059
|
+
/* @__PURE__ */ jsx_dev_runtime27.jsxDEV("div", {
|
|
56060
|
+
className: "list-item-title",
|
|
56061
|
+
children: session.firstMessage || session.slug
|
|
56062
|
+
}, undefined, false, undefined, this),
|
|
56063
|
+
/* @__PURE__ */ jsx_dev_runtime27.jsxDEV("div", {
|
|
56064
|
+
className: "list-item-meta",
|
|
56065
|
+
children: [
|
|
56066
|
+
session.pluginId && /* @__PURE__ */ jsx_dev_runtime27.jsxDEV("span", {
|
|
56067
|
+
className: "plugin-badge",
|
|
56068
|
+
children: pluginDisplayName(session.pluginId)
|
|
56069
|
+
}, undefined, false, undefined, this),
|
|
56070
|
+
" ",
|
|
56071
|
+
session.sessionType && /* @__PURE__ */ jsx_dev_runtime27.jsxDEV("span", {
|
|
56072
|
+
className: `session-type-badge ${session.sessionType}`,
|
|
56073
|
+
children: session.sessionType === "plan" ? "Plan" : "Impl"
|
|
56074
|
+
}, undefined, false, undefined, this),
|
|
56075
|
+
" ",
|
|
56076
|
+
/* @__PURE__ */ jsx_dev_runtime27.jsxDEV("time", {
|
|
56077
|
+
dateTime: session.timestamp,
|
|
56078
|
+
title: formatFullDateTime(session.timestamp),
|
|
56079
|
+
children: formatTime(session.timestamp)
|
|
56080
|
+
}, undefined, false, undefined, this)
|
|
56081
|
+
]
|
|
56082
|
+
}, undefined, true, undefined, this)
|
|
56083
|
+
]
|
|
56084
|
+
}, session.sessionId, true, undefined, this)),
|
|
56085
|
+
!loading && !error && sessions.length === 0 && /* @__PURE__ */ jsx_dev_runtime27.jsxDEV("div", {
|
|
56086
|
+
className: "empty-list-message",
|
|
56087
|
+
children: "No sessions found"
|
|
56088
|
+
}, undefined, false, undefined, this)
|
|
56089
|
+
]
|
|
56090
|
+
}, undefined, true, undefined, this);
|
|
56091
|
+
}
|
|
56092
|
+
|
|
56093
|
+
// src/frontend/sidebar-content.tsx
|
|
56094
|
+
var jsx_dev_runtime28 = __toESM(require_jsx_dev_runtime(), 1);
|
|
56095
|
+
function getSidebarContent(view, hiddenIds, actions) {
|
|
55847
56096
|
if (view.kind === "home" || view.kind === "hidden") {
|
|
55848
|
-
return /* @__PURE__ */
|
|
55849
|
-
onSelect: selectProject,
|
|
56097
|
+
return /* @__PURE__ */ jsx_dev_runtime28.jsxDEV(ProjectList, {
|
|
56098
|
+
onSelect: actions.selectProject,
|
|
55850
56099
|
hiddenIds,
|
|
55851
|
-
onHide: hide,
|
|
55852
|
-
onShowHidden: goHidden
|
|
56100
|
+
onHide: actions.hide,
|
|
56101
|
+
onShowHidden: actions.goHidden
|
|
55853
56102
|
}, undefined, false, undefined, this);
|
|
55854
56103
|
}
|
|
55855
56104
|
if (view.kind === "project") {
|
|
55856
|
-
return /* @__PURE__ */
|
|
56105
|
+
return /* @__PURE__ */ jsx_dev_runtime28.jsxDEV(SessionList, {
|
|
55857
56106
|
project: view.project,
|
|
55858
|
-
onSelect: selectSession,
|
|
55859
|
-
onBack: goHome
|
|
56107
|
+
onSelect: actions.selectSession,
|
|
56108
|
+
onBack: actions.goHome
|
|
55860
56109
|
}, undefined, false, undefined, this);
|
|
55861
56110
|
}
|
|
55862
56111
|
if (view.kind === "subagent") {
|
|
55863
|
-
return /* @__PURE__ */
|
|
56112
|
+
return /* @__PURE__ */ jsx_dev_runtime28.jsxDEV(SessionList, {
|
|
55864
56113
|
project: view.project,
|
|
55865
|
-
onSelect: selectSession,
|
|
55866
|
-
onBack: goHome,
|
|
56114
|
+
onSelect: actions.selectSession,
|
|
56115
|
+
onBack: actions.goHome,
|
|
55867
56116
|
selectedId: view.sessionId
|
|
55868
56117
|
}, undefined, false, undefined, this);
|
|
55869
56118
|
}
|
|
55870
|
-
return /* @__PURE__ */
|
|
56119
|
+
return /* @__PURE__ */ jsx_dev_runtime28.jsxDEV(SessionList, {
|
|
55871
56120
|
project: view.project,
|
|
55872
|
-
onSelect: selectSession,
|
|
55873
|
-
onBack: goHome,
|
|
56121
|
+
onSelect: actions.selectSession,
|
|
56122
|
+
onBack: actions.goHome,
|
|
55874
56123
|
selectedId: view.session.sessionId
|
|
55875
56124
|
}, undefined, false, undefined, this);
|
|
55876
56125
|
}
|
|
56126
|
+
|
|
56127
|
+
// src/frontend/App.tsx
|
|
56128
|
+
var jsx_dev_runtime29 = __toESM(require_jsx_dev_runtime(), 1);
|
|
55877
56129
|
function App() {
|
|
55878
56130
|
const { setting: themeSetting, cycle: cycleTheme } = useTheme();
|
|
55879
56131
|
const { size: fontSize, increase, decrease } = useFontSize();
|
|
55880
56132
|
const { hiddenIds, hide, unhide } = useHiddenProjects();
|
|
55881
|
-
const
|
|
55882
|
-
|
|
55883
|
-
|
|
55884
|
-
|
|
55885
|
-
|
|
55886
|
-
|
|
55887
|
-
|
|
55888
|
-
|
|
55889
|
-
|
|
55890
|
-
|
|
55891
|
-
|
|
55892
|
-
|
|
55893
|
-
|
|
55894
|
-
|
|
55895
|
-
if (window.location.hash !== newHash) {
|
|
55896
|
-
history.pushState(null, "", newHash);
|
|
55897
|
-
}
|
|
55898
|
-
}, [view, ready]);
|
|
55899
|
-
import_react16.useEffect(() => {
|
|
55900
|
-
const handler = () => {
|
|
55901
|
-
restoreFromHash().then(setView);
|
|
55902
|
-
};
|
|
55903
|
-
window.addEventListener("popstate", handler);
|
|
55904
|
-
return () => window.removeEventListener("popstate", handler);
|
|
55905
|
-
}, []);
|
|
55906
|
-
const selectProject = (project) => {
|
|
55907
|
-
setView({ kind: "project", project });
|
|
55908
|
-
};
|
|
55909
|
-
const selectSession = (session) => {
|
|
55910
|
-
if (view.kind === "project" || view.kind === "session") {
|
|
55911
|
-
setView({
|
|
55912
|
-
kind: "session",
|
|
55913
|
-
project: view.project,
|
|
55914
|
-
session,
|
|
55915
|
-
presenting: false
|
|
55916
|
-
});
|
|
55917
|
-
}
|
|
55918
|
-
};
|
|
55919
|
-
const goHome = () => setView({ kind: "home" });
|
|
55920
|
-
const goHidden = () => setView({ kind: "hidden" });
|
|
55921
|
-
const canPresent = view.kind === "session" || view.kind === "subagent";
|
|
55922
|
-
const togglePresentation = import_react16.useCallback(() => {
|
|
55923
|
-
if (view.kind === "session" || view.kind === "subagent") {
|
|
55924
|
-
setView({ ...view, presenting: !view.presenting });
|
|
55925
|
-
}
|
|
55926
|
-
}, [view]);
|
|
55927
|
-
const fetchSearchSessions = import_react16.useCallback(() => {
|
|
56133
|
+
const {
|
|
56134
|
+
view,
|
|
56135
|
+
ready,
|
|
56136
|
+
setView,
|
|
56137
|
+
selectProject,
|
|
56138
|
+
selectSession,
|
|
56139
|
+
goHome,
|
|
56140
|
+
goHidden,
|
|
56141
|
+
canPresent,
|
|
56142
|
+
togglePresentation
|
|
56143
|
+
} = useViewState();
|
|
56144
|
+
const [searchOpen, setSearchOpen] = import_react19.useState(false);
|
|
56145
|
+
const [searchSessions, setSearchSessions] = import_react19.useState([]);
|
|
56146
|
+
const fetchSearchSessions = import_react19.useCallback(() => {
|
|
55928
56147
|
fetch("/api/search/sessions").then((res) => res.json()).then((data) => setSearchSessions(data.sessions)).catch(() => {});
|
|
55929
56148
|
}, []);
|
|
55930
|
-
const openSearch =
|
|
56149
|
+
const openSearch = import_react19.useCallback(() => {
|
|
55931
56150
|
setSearchOpen(true);
|
|
55932
56151
|
fetchSearchSessions();
|
|
55933
56152
|
}, [fetchSearchSessions]);
|
|
55934
|
-
const handleSearchSelect =
|
|
56153
|
+
const handleSearchSelect = import_react19.useCallback(async (encodedPath, sessionId) => {
|
|
55935
56154
|
setSearchOpen(false);
|
|
55936
|
-
|
|
55937
|
-
|
|
55938
|
-
|
|
55939
|
-
|
|
55940
|
-
|
|
55941
|
-
|
|
55942
|
-
|
|
55943
|
-
|
|
55944
|
-
|
|
55945
|
-
|
|
55946
|
-
|
|
55947
|
-
}
|
|
55948
|
-
} catch {}
|
|
55949
|
-
}, []);
|
|
55950
|
-
import_react16.useEffect(() => {
|
|
56155
|
+
const resolved = await resolveProjectAndSession(encodedPath, sessionId);
|
|
56156
|
+
if (resolved) {
|
|
56157
|
+
setView({
|
|
56158
|
+
kind: "session",
|
|
56159
|
+
project: resolved.project,
|
|
56160
|
+
session: resolved.session,
|
|
56161
|
+
presenting: false
|
|
56162
|
+
});
|
|
56163
|
+
}
|
|
56164
|
+
}, [setView]);
|
|
56165
|
+
import_react19.useEffect(() => {
|
|
55951
56166
|
function handleCmdK(e) {
|
|
55952
56167
|
if ((e.metaKey || e.ctrlKey) && e.key === "k") {
|
|
55953
56168
|
e.preventDefault();
|
|
@@ -55961,7 +56176,7 @@ function App() {
|
|
|
55961
56176
|
window.addEventListener("keydown", handleCmdK);
|
|
55962
56177
|
return () => window.removeEventListener("keydown", handleCmdK);
|
|
55963
56178
|
}, [fetchSearchSessions]);
|
|
55964
|
-
|
|
56179
|
+
import_react19.useEffect(() => {
|
|
55965
56180
|
function handleKeyDown(e) {
|
|
55966
56181
|
if (e.target instanceof HTMLInputElement || e.target instanceof HTMLTextAreaElement)
|
|
55967
56182
|
return;
|
|
@@ -55989,30 +56204,36 @@ function App() {
|
|
|
55989
56204
|
return () => window.removeEventListener("keydown", handleKeyDown);
|
|
55990
56205
|
}, [canPresent, togglePresentation, increase, decrease]);
|
|
55991
56206
|
const { title: headerTitle, breadcrumb } = getHeaderInfo(view);
|
|
55992
|
-
const sidebarContent = getSidebarContent(view,
|
|
55993
|
-
|
|
56207
|
+
const sidebarContent = getSidebarContent(view, hiddenIds, {
|
|
56208
|
+
selectProject,
|
|
56209
|
+
selectSession,
|
|
56210
|
+
goHome,
|
|
56211
|
+
goHidden,
|
|
56212
|
+
hide
|
|
56213
|
+
});
|
|
56214
|
+
const isPresenting = view.kind === "session" || view.kind === "subagent" ? view.presenting : false;
|
|
55994
56215
|
if (!ready) {
|
|
55995
|
-
return /* @__PURE__ */
|
|
56216
|
+
return /* @__PURE__ */ jsx_dev_runtime29.jsxDEV("div", {
|
|
55996
56217
|
className: "loading",
|
|
55997
56218
|
children: "Loading..."
|
|
55998
56219
|
}, undefined, false, undefined, this);
|
|
55999
56220
|
}
|
|
56000
|
-
return /* @__PURE__ */
|
|
56221
|
+
return /* @__PURE__ */ jsx_dev_runtime29.jsxDEV(jsx_dev_runtime29.Fragment, {
|
|
56001
56222
|
children: [
|
|
56002
|
-
searchOpen && /* @__PURE__ */
|
|
56223
|
+
searchOpen && /* @__PURE__ */ jsx_dev_runtime29.jsxDEV(SearchModal, {
|
|
56003
56224
|
sessions: searchSessions,
|
|
56004
56225
|
onSelect: handleSearchSelect,
|
|
56005
56226
|
onClose: () => setSearchOpen(false)
|
|
56006
56227
|
}, undefined, false, undefined, this),
|
|
56007
|
-
/* @__PURE__ */
|
|
56228
|
+
/* @__PURE__ */ jsx_dev_runtime29.jsxDEV(Layout, {
|
|
56008
56229
|
sidebar: sidebarContent,
|
|
56009
56230
|
hideSidebar: isPresenting,
|
|
56010
56231
|
onSearchClick: openSearch,
|
|
56011
56232
|
children: [
|
|
56012
|
-
/* @__PURE__ */
|
|
56233
|
+
/* @__PURE__ */ jsx_dev_runtime29.jsxDEV(Header, {
|
|
56013
56234
|
title: headerTitle,
|
|
56014
56235
|
breadcrumb,
|
|
56015
|
-
copyCommand: view.kind === "session"
|
|
56236
|
+
copyCommand: view.kind === "session" ? getResumeCommand(view.session.pluginId, view.session.sessionId) : undefined,
|
|
56016
56237
|
backHref: view.kind === "subagent" ? `#/${view.project.encodedPath}/${view.sessionId}` : undefined,
|
|
56017
56238
|
sessionType: view.kind === "session" ? view.session.sessionType : undefined,
|
|
56018
56239
|
themeSetting,
|
|
@@ -56024,63 +56245,64 @@ function App() {
|
|
|
56024
56245
|
onTogglePresentation: togglePresentation,
|
|
56025
56246
|
showPresentationToggle: canPresent
|
|
56026
56247
|
}, undefined, false, undefined, this),
|
|
56027
|
-
/* @__PURE__ */
|
|
56248
|
+
/* @__PURE__ */ jsx_dev_runtime29.jsxDEV(ErrorBoundary, {
|
|
56028
56249
|
children: [
|
|
56029
|
-
view.kind === "home" && /* @__PURE__ */
|
|
56250
|
+
view.kind === "home" && /* @__PURE__ */ jsx_dev_runtime29.jsxDEV(jsx_dev_runtime29.Fragment, {
|
|
56030
56251
|
children: [
|
|
56031
|
-
/* @__PURE__ */
|
|
56252
|
+
/* @__PURE__ */ jsx_dev_runtime29.jsxDEV("div", {
|
|
56032
56253
|
className: "empty-state",
|
|
56033
56254
|
children: [
|
|
56034
|
-
/* @__PURE__ */
|
|
56255
|
+
/* @__PURE__ */ jsx_dev_runtime29.jsxDEV("img", {
|
|
56035
56256
|
src: favicon_default,
|
|
56036
56257
|
alt: "",
|
|
56037
56258
|
width: "64",
|
|
56038
56259
|
height: "64",
|
|
56039
56260
|
className: "empty-state-logo"
|
|
56040
56261
|
}, undefined, false, undefined, this),
|
|
56041
|
-
/* @__PURE__ */
|
|
56262
|
+
/* @__PURE__ */ jsx_dev_runtime29.jsxDEV("div", {
|
|
56042
56263
|
className: "empty-state-title",
|
|
56043
56264
|
children: "Welcome to Klovi"
|
|
56044
56265
|
}, undefined, false, undefined, this),
|
|
56045
|
-
/* @__PURE__ */
|
|
56266
|
+
/* @__PURE__ */ jsx_dev_runtime29.jsxDEV("p", {
|
|
56046
56267
|
children: "Select a project from the sidebar to browse your AI coding sessions"
|
|
56047
56268
|
}, undefined, false, undefined, this)
|
|
56048
56269
|
]
|
|
56049
56270
|
}, undefined, true, undefined, this),
|
|
56050
|
-
/* @__PURE__ */
|
|
56271
|
+
/* @__PURE__ */ jsx_dev_runtime29.jsxDEV(DashboardStats, {}, undefined, false, undefined, this)
|
|
56051
56272
|
]
|
|
56052
56273
|
}, undefined, true, undefined, this),
|
|
56053
|
-
view.kind === "hidden" && /* @__PURE__ */
|
|
56274
|
+
view.kind === "hidden" && /* @__PURE__ */ jsx_dev_runtime29.jsxDEV(HiddenProjectList, {
|
|
56054
56275
|
hiddenIds,
|
|
56055
56276
|
onUnhide: unhide,
|
|
56056
56277
|
onBack: goHome
|
|
56057
56278
|
}, undefined, false, undefined, this),
|
|
56058
|
-
view.kind === "project" && /* @__PURE__ */
|
|
56279
|
+
view.kind === "project" && /* @__PURE__ */ jsx_dev_runtime29.jsxDEV("div", {
|
|
56059
56280
|
className: "empty-state",
|
|
56060
56281
|
children: [
|
|
56061
|
-
/* @__PURE__ */
|
|
56282
|
+
/* @__PURE__ */ jsx_dev_runtime29.jsxDEV("div", {
|
|
56062
56283
|
className: "empty-state-title",
|
|
56063
56284
|
children: "Select a session"
|
|
56064
56285
|
}, undefined, false, undefined, this),
|
|
56065
|
-
/* @__PURE__ */
|
|
56286
|
+
/* @__PURE__ */ jsx_dev_runtime29.jsxDEV("p", {
|
|
56066
56287
|
children: "Choose a conversation from the sidebar"
|
|
56067
56288
|
}, undefined, false, undefined, this)
|
|
56068
56289
|
]
|
|
56069
56290
|
}, undefined, true, undefined, this),
|
|
56070
|
-
view.kind === "session" && (view.presenting ? /* @__PURE__ */
|
|
56291
|
+
view.kind === "session" && (view.presenting ? /* @__PURE__ */ jsx_dev_runtime29.jsxDEV(SessionPresentation, {
|
|
56071
56292
|
sessionId: view.session.sessionId,
|
|
56072
56293
|
project: view.project.encodedPath,
|
|
56073
56294
|
onExit: togglePresentation
|
|
56074
|
-
}, undefined, false, undefined, this) : /* @__PURE__ */
|
|
56295
|
+
}, undefined, false, undefined, this) : /* @__PURE__ */ jsx_dev_runtime29.jsxDEV(SessionView, {
|
|
56075
56296
|
sessionId: view.session.sessionId,
|
|
56076
|
-
project: view.project.encodedPath
|
|
56297
|
+
project: view.project.encodedPath,
|
|
56298
|
+
gitBranch: view.session.gitBranch
|
|
56077
56299
|
}, undefined, false, undefined, this)),
|
|
56078
|
-
view.kind === "subagent" && (view.presenting ? /* @__PURE__ */
|
|
56300
|
+
view.kind === "subagent" && (view.presenting ? /* @__PURE__ */ jsx_dev_runtime29.jsxDEV(SubAgentPresentation, {
|
|
56079
56301
|
sessionId: view.sessionId,
|
|
56080
56302
|
project: view.project.encodedPath,
|
|
56081
56303
|
agentId: view.agentId,
|
|
56082
56304
|
onExit: togglePresentation
|
|
56083
|
-
}, undefined, false, undefined, this) : /* @__PURE__ */
|
|
56305
|
+
}, undefined, false, undefined, this) : /* @__PURE__ */ jsx_dev_runtime29.jsxDEV(SubAgentView, {
|
|
56084
56306
|
sessionId: view.sessionId,
|
|
56085
56307
|
project: view.project.encodedPath,
|
|
56086
56308
|
agentId: view.agentId
|
|
@@ -56093,4 +56315,4 @@ function App() {
|
|
|
56093
56315
|
}, undefined, true, undefined, this);
|
|
56094
56316
|
}
|
|
56095
56317
|
var root4 = import_client.createRoot(document.getElementById("root"));
|
|
56096
|
-
root4.render(/* @__PURE__ */
|
|
56318
|
+
root4.render(/* @__PURE__ */ jsx_dev_runtime29.jsxDEV(App, {}, undefined, false, undefined, this));
|