@agimon-ai/po-file-edit 0.0.0-alpha.2 → 0.0.0-alpha.21
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +149 -21
- package/README.md +3 -3
- package/dist/apiContracts.cjs +1 -1
- package/dist/apiContracts.cjs.map +1 -1
- package/dist/apiContracts.mjs +1 -1
- package/dist/apiContracts.mjs.map +1 -1
- package/dist/extensions/native.mjs +10 -963
- package/dist/extensions/native.mjs.map +1 -1
- package/dist/extensions/server.cjs +337 -111
- package/dist/extensions/server.cjs.map +1 -1
- package/dist/extensions/server.d.mts +2 -2
- package/dist/extensions/server.d.mts.map +1 -1
- package/dist/extensions/server.mjs +363 -138
- package/dist/extensions/server.mjs.map +1 -1
- package/dist/extensions/web.mjs +44 -354
- package/dist/extensions/web.mjs.map +1 -1
- package/package.json +24 -23
package/dist/extensions/web.mjs
CHANGED
|
@@ -1,22 +1,13 @@
|
|
|
1
|
-
import { createApiClient,
|
|
2
|
-
import { Badge, Breadcrumb, Button,
|
|
1
|
+
import { createApiClient, defineChannelFile, defineFileLinks, defineSessionStore, defineWebPlugin, sessionApiAddress } from "@agimon-ai/po-core/web";
|
|
2
|
+
import { Badge, Breadcrumb, Button, CodeEditor, Dialog, DialogBody, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogTitle, DiffView, DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMenuTrigger, KebabIcon, Markdown, MediaPreview, ReviewCommentDraft, buildReviewPrompt, grammarKeyOf, mediaKindOf, reviewCommentAnchor } from "@agimon-ai/po-web-components";
|
|
3
3
|
import { useStore } from "@tanstack/react-store";
|
|
4
|
-
import {
|
|
4
|
+
import { useCallback, useEffect, useRef, useState } from "react";
|
|
5
5
|
import { sealedTransport } from "@agimon-ai/po-web-security/browser";
|
|
6
|
-
import { Fragment
|
|
6
|
+
import { Fragment, jsx, jsxs } from "react/jsx-runtime";
|
|
7
7
|
//#region src/types/webFiles.ts
|
|
8
8
|
/** The frame type the hub publishes and the web plugin claims; declared in the poWeb block too. */
|
|
9
9
|
const filesChannelType = "file_edits";
|
|
10
10
|
//#endregion
|
|
11
|
-
//#region src/extensions/workspaces/sessions/(frontend)/activity-group/files.web.ts
|
|
12
|
-
var files_web_default$2 = defineActivityGroup({
|
|
13
|
-
keys: "e f",
|
|
14
|
-
statusKey: "doom-file-edit-files",
|
|
15
|
-
hideWhenEmpty: true,
|
|
16
|
-
marksBackgroundWork: false,
|
|
17
|
-
order: 15
|
|
18
|
-
});
|
|
19
|
-
//#endregion
|
|
20
11
|
//#region src/extensions/workspaces/sessions/(frontend)/_lib/filesModel.ts
|
|
21
12
|
function isRecord$1(value) {
|
|
22
13
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
@@ -288,12 +279,6 @@ const TOOL_LABEL = {
|
|
|
288
279
|
bash: "command",
|
|
289
280
|
user: "you"
|
|
290
281
|
};
|
|
291
|
-
/** Filters visible relative paths without changing the timeline's newest-first order. */
|
|
292
|
-
function filterFileItems(items, query) {
|
|
293
|
-
const normalized = query.trim().toLocaleLowerCase();
|
|
294
|
-
if (normalized.length === 0) return [...items];
|
|
295
|
-
return items.filter((item) => item.relPath.toLocaleLowerCase().includes(normalized));
|
|
296
|
-
}
|
|
297
282
|
function previewModeOf(filePath, unavailable) {
|
|
298
283
|
if (mediaKindOf(filePath) !== "download") return "media";
|
|
299
284
|
if (unavailable) return "unavailable";
|
|
@@ -335,7 +320,7 @@ function DeleteFileDialog({ relPath, open, onConfirm, onCancel }) {
|
|
|
335
320
|
children: [/* @__PURE__ */ jsx(DialogHeader, { children: /* @__PURE__ */ jsx(DialogTitle, { children: "delete file" }) }), /* @__PURE__ */ jsxs(DialogBody, { children: [/* @__PURE__ */ jsxs(DialogDescription, { children: [
|
|
336
321
|
"this removes ",
|
|
337
322
|
/* @__PURE__ */ jsx("span", {
|
|
338
|
-
className: "font-semibold text-
|
|
323
|
+
className: "font-semibold text-po-hi",
|
|
339
324
|
children: relPath
|
|
340
325
|
}),
|
|
341
326
|
" from disk. the session keeps its record of the change, but the file itself is gone."
|
|
@@ -528,7 +513,7 @@ function FilePanel({ filePath, relPath, sessionId, sendSessionFrame, closeTransi
|
|
|
528
513
|
className: "flex min-h-0 flex-1 flex-col",
|
|
529
514
|
children: [
|
|
530
515
|
/* @__PURE__ */ jsxs("header", {
|
|
531
|
-
className: "flex shrink-0 items-center gap-2 border-b border-
|
|
516
|
+
className: "flex shrink-0 items-center gap-2 border-b border-po-border px-4 py-2",
|
|
532
517
|
children: [
|
|
533
518
|
/* @__PURE__ */ jsx(Breadcrumb, {
|
|
534
519
|
path: relPath,
|
|
@@ -542,7 +527,7 @@ function FilePanel({ filePath, relPath, sessionId, sendSessionFrame, closeTransi
|
|
|
542
527
|
children: "editing"
|
|
543
528
|
}) : null,
|
|
544
529
|
detail === void 0 ? null : /* @__PURE__ */ jsxs("span", {
|
|
545
|
-
className: "shrink-0 text-sm text-
|
|
530
|
+
className: "shrink-0 text-sm text-po-dim",
|
|
546
531
|
children: [
|
|
547
532
|
"+",
|
|
548
533
|
detail.cumulative.additions,
|
|
@@ -568,7 +553,7 @@ function FilePanel({ filePath, relPath, sessionId, sendSessionFrame, closeTransi
|
|
|
568
553
|
size: "icon",
|
|
569
554
|
"data-testid": "files-menu",
|
|
570
555
|
title: "file actions",
|
|
571
|
-
className: "shrink-0 text-
|
|
556
|
+
className: "shrink-0 text-po-faint hover:text-po-hi",
|
|
572
557
|
children: /* @__PURE__ */ jsx(KebabIcon, { className: "h-3 w-3" })
|
|
573
558
|
})
|
|
574
559
|
}), /* @__PURE__ */ jsxs(DropdownMenuContent, {
|
|
@@ -604,12 +589,12 @@ function FilePanel({ filePath, relPath, sessionId, sendSessionFrame, closeTransi
|
|
|
604
589
|
}),
|
|
605
590
|
loading && detail === void 0 ? /* @__PURE__ */ jsx("p", {
|
|
606
591
|
"data-testid": "files-loading",
|
|
607
|
-
className: "px-4 py-3 text-sm text-
|
|
592
|
+
className: "px-4 py-3 text-sm text-po-dim",
|
|
608
593
|
children: "reading this file's history…"
|
|
609
594
|
}) : null,
|
|
610
595
|
error === void 0 ? null : /* @__PURE__ */ jsx("p", {
|
|
611
596
|
"data-testid": "files-error",
|
|
612
|
-
className: "px-4 py-3 text-sm text-
|
|
597
|
+
className: "px-4 py-3 text-sm text-po-red",
|
|
613
598
|
children: error
|
|
614
599
|
}),
|
|
615
600
|
/* @__PURE__ */ jsx("div", {
|
|
@@ -619,7 +604,7 @@ function FilePanel({ filePath, relPath, sessionId, sendSessionFrame, closeTransi
|
|
|
619
604
|
children: [
|
|
620
605
|
detail.cumulative.note === void 0 ? null : /* @__PURE__ */ jsx("p", {
|
|
621
606
|
"data-testid": "files-cumulative-note",
|
|
622
|
-
className: "px-4 py-2 text-sm text-
|
|
607
|
+
className: "px-4 py-2 text-sm text-po-yellow",
|
|
623
608
|
children: detail.cumulative.note
|
|
624
609
|
}),
|
|
625
610
|
detail.cumulative.hunks === void 0 ? null : /* @__PURE__ */ jsx(DiffView, {
|
|
@@ -628,9 +613,9 @@ function FilePanel({ filePath, relPath, sessionId, sendSessionFrame, closeTransi
|
|
|
628
613
|
onSelect: (selection) => openDraft(selection)
|
|
629
614
|
}),
|
|
630
615
|
/* @__PURE__ */ jsxs("section", {
|
|
631
|
-
className: "mt-2 border-t border-
|
|
616
|
+
className: "mt-2 border-t border-po-border",
|
|
632
617
|
children: [/* @__PURE__ */ jsxs("h2", {
|
|
633
|
-
className: "px-4 py-2 text-lg font-semibold text-
|
|
618
|
+
className: "px-4 py-2 text-lg font-semibold text-po-hi ",
|
|
634
619
|
children: [
|
|
635
620
|
detail.versions.length,
|
|
636
621
|
" ",
|
|
@@ -644,16 +629,16 @@ function FilePanel({ filePath, relPath, sessionId, sendSessionFrame, closeTransi
|
|
|
644
629
|
size: "card",
|
|
645
630
|
"data-testid": `files-version-toggle-${version.index}`,
|
|
646
631
|
onClick: () => setExpanded(expanded === version.index ? void 0 : version.index),
|
|
647
|
-
className: "w-full gap-2 rounded-none px-4 py-1.5 hover:bg-
|
|
632
|
+
className: "w-full gap-2 rounded-none px-4 py-1.5 hover:bg-po-panel",
|
|
648
633
|
children: /* @__PURE__ */ jsxs("span", {
|
|
649
634
|
className: "flex w-full min-w-0 items-center gap-2",
|
|
650
635
|
children: [
|
|
651
636
|
/* @__PURE__ */ jsxs("span", {
|
|
652
|
-
className: "shrink-0 text-sm text-
|
|
637
|
+
className: "shrink-0 text-sm text-po-dim",
|
|
653
638
|
children: ["#", version.index]
|
|
654
639
|
}),
|
|
655
640
|
/* @__PURE__ */ jsx("span", {
|
|
656
|
-
className: "min-w-0 flex-1 truncate text-left text-base text-
|
|
641
|
+
className: "min-w-0 flex-1 truncate text-left text-base text-po-text",
|
|
657
642
|
children: versionSummary(version)
|
|
658
643
|
}),
|
|
659
644
|
version.origin === "scan" ? /* @__PURE__ */ jsx(Badge, {
|
|
@@ -662,13 +647,13 @@ function FilePanel({ filePath, relPath, sessionId, sendSessionFrame, closeTransi
|
|
|
662
647
|
children: "no baseline"
|
|
663
648
|
}) : null,
|
|
664
649
|
/* @__PURE__ */ jsx("span", {
|
|
665
|
-
className: "shrink-0 text-sm text-
|
|
650
|
+
className: "shrink-0 text-sm text-po-dim",
|
|
666
651
|
children: expanded === version.index ? "▾" : "▸"
|
|
667
652
|
})
|
|
668
653
|
]
|
|
669
654
|
})
|
|
670
655
|
}), expanded !== version.index ? null : version.hunks === void 0 ? /* @__PURE__ */ jsx("p", {
|
|
671
|
-
className: "px-4 py-1.5 text-sm text-
|
|
656
|
+
className: "px-4 py-1.5 text-sm text-po-dim",
|
|
672
657
|
children: version.note ?? "nothing to show"
|
|
673
658
|
}) : /* @__PURE__ */ jsx(DiffView, {
|
|
674
659
|
hunks: version.hunks,
|
|
@@ -682,9 +667,9 @@ function FilePanel({ filePath, relPath, sessionId, sendSessionFrame, closeTransi
|
|
|
682
667
|
className: "flex h-full flex-col gap-2 p-3",
|
|
683
668
|
children: working?.unavailable === true ? /* @__PURE__ */ jsx("p", {
|
|
684
669
|
"data-testid": "files-source-unavailable",
|
|
685
|
-
className: "text-sm text-
|
|
670
|
+
className: "text-sm text-po-dim",
|
|
686
671
|
children: working.reason ?? "this file cannot be shown"
|
|
687
|
-
}) : /* @__PURE__ */ jsxs(Fragment
|
|
672
|
+
}) : /* @__PURE__ */ jsxs(Fragment, { children: [/* @__PURE__ */ jsx("div", {
|
|
688
673
|
className: "min-h-[24rem] flex-1",
|
|
689
674
|
onMouseUp: openSelectionDraft,
|
|
690
675
|
onKeyUp: (event) => {
|
|
@@ -698,7 +683,7 @@ function FilePanel({ filePath, relPath, sessionId, sendSessionFrame, closeTransi
|
|
|
698
683
|
onSelect: (range) => {
|
|
699
684
|
selection.current = range;
|
|
700
685
|
},
|
|
701
|
-
className: "h-full rounded border border-
|
|
686
|
+
className: "h-full rounded border border-po-border"
|
|
702
687
|
})
|
|
703
688
|
}), /* @__PURE__ */ jsxs("div", {
|
|
704
689
|
className: "flex shrink-0 items-center gap-2",
|
|
@@ -723,7 +708,7 @@ function FilePanel({ filePath, relPath, sessionId, sendSessionFrame, closeTransi
|
|
|
723
708
|
}),
|
|
724
709
|
saveNote === void 0 ? null : /* @__PURE__ */ jsx("span", {
|
|
725
710
|
"data-testid": "files-save-note",
|
|
726
|
-
className: saveNote === "saved" ? "text-sm text-
|
|
711
|
+
className: saveNote === "saved" ? "text-sm text-po-green" : "text-sm text-po-red",
|
|
727
712
|
children: saveNote
|
|
728
713
|
})
|
|
729
714
|
]
|
|
@@ -731,7 +716,7 @@ function FilePanel({ filePath, relPath, sessionId, sendSessionFrame, closeTransi
|
|
|
731
716
|
}) : /* @__PURE__ */ jsxs("div", {
|
|
732
717
|
"data-testid": "files-preview",
|
|
733
718
|
"data-mode": previewMode,
|
|
734
|
-
className: previewMode === "code" ? "flex h-full flex-col gap-2 p-4 text-base text-
|
|
719
|
+
className: previewMode === "code" ? "flex h-full flex-col gap-2 p-4 text-base text-po-text" : "flex flex-col gap-2 p-4 text-base text-po-text",
|
|
735
720
|
onMouseUp: () => {
|
|
736
721
|
if (previewMode === "code") {
|
|
737
722
|
openSelectionDraft();
|
|
@@ -742,7 +727,7 @@ function FilePanel({ filePath, relPath, sessionId, sendSessionFrame, closeTransi
|
|
|
742
727
|
},
|
|
743
728
|
children: [previewMode === "unavailable" ? /* @__PURE__ */ jsx("p", {
|
|
744
729
|
"data-testid": "files-preview-unavailable",
|
|
745
|
-
className: "text-sm text-
|
|
730
|
+
className: "text-sm text-po-dim",
|
|
746
731
|
children: working?.reason ?? "this file cannot be shown"
|
|
747
732
|
}) : null, previewMode === "media" || previewMode === "unavailable" ? /* @__PURE__ */ jsx(SessionMediaPreview, {
|
|
748
733
|
src: mediaSrc,
|
|
@@ -756,7 +741,7 @@ function FilePanel({ filePath, relPath, sessionId, sendSessionFrame, closeTransi
|
|
|
756
741
|
title: relPath,
|
|
757
742
|
sandbox: "",
|
|
758
743
|
srcDoc: content,
|
|
759
|
-
className: "h-[36rem] w-full rounded border border-
|
|
744
|
+
className: "h-[36rem] w-full rounded border border-po-border bg-po-deep"
|
|
760
745
|
}) : previewMode === "code" ? /* @__PURE__ */ jsx(CodeEditor, {
|
|
761
746
|
"data-testid": "files-preview-code",
|
|
762
747
|
value: content,
|
|
@@ -765,10 +750,10 @@ function FilePanel({ filePath, relPath, sessionId, sendSessionFrame, closeTransi
|
|
|
765
750
|
onSelect: (range) => {
|
|
766
751
|
selection.current = range;
|
|
767
752
|
},
|
|
768
|
-
className: "min-h-[24rem] flex-1 rounded border border-
|
|
753
|
+
className: "min-h-[24rem] flex-1 rounded border border-po-border"
|
|
769
754
|
}) : /* @__PURE__ */ jsx("pre", {
|
|
770
755
|
"data-testid": "files-preview-text",
|
|
771
|
-
className: "whitespace-pre-wrap break-words font-mono text-sm leading-normal text-
|
|
756
|
+
className: "whitespace-pre-wrap break-words font-mono text-sm leading-normal text-po-text",
|
|
772
757
|
children: content
|
|
773
758
|
})]
|
|
774
759
|
})
|
|
@@ -784,12 +769,12 @@ function FilePanel({ filePath, relPath, sessionId, sendSessionFrame, closeTransi
|
|
|
784
769
|
}),
|
|
785
770
|
comments.length === 0 ? null : /* @__PURE__ */ jsxs("footer", {
|
|
786
771
|
"data-testid": "files-review",
|
|
787
|
-
className: "shrink-0 border-t border-
|
|
772
|
+
className: "shrink-0 border-t border-po-border px-3 py-2",
|
|
788
773
|
children: [
|
|
789
774
|
/* @__PURE__ */ jsxs("div", {
|
|
790
775
|
className: "flex items-center gap-2 pb-1",
|
|
791
776
|
children: [/* @__PURE__ */ jsxs("span", {
|
|
792
|
-
className: "flex-1 text-base font-semibold text-
|
|
777
|
+
className: "flex-1 text-base font-semibold text-po-hi",
|
|
793
778
|
children: [
|
|
794
779
|
comments.length,
|
|
795
780
|
" ",
|
|
@@ -807,7 +792,7 @@ function FilePanel({ filePath, relPath, sessionId, sendSessionFrame, closeTransi
|
|
|
807
792
|
reviewError === void 0 ? null : /* @__PURE__ */ jsxs("p", {
|
|
808
793
|
role: "alert",
|
|
809
794
|
"data-testid": "files-review-error",
|
|
810
|
-
className: "pb-1 text-sm text-
|
|
795
|
+
className: "pb-1 text-sm text-po-red",
|
|
811
796
|
children: ["review not sent: ", reviewError]
|
|
812
797
|
}),
|
|
813
798
|
comments.map((comment) => /* @__PURE__ */ jsxs("div", {
|
|
@@ -815,11 +800,11 @@ function FilePanel({ filePath, relPath, sessionId, sendSessionFrame, closeTransi
|
|
|
815
800
|
className: "flex items-start gap-2 py-0.5",
|
|
816
801
|
children: [
|
|
817
802
|
/* @__PURE__ */ jsx("span", {
|
|
818
|
-
className: "shrink-0 text-sm text-
|
|
803
|
+
className: "shrink-0 text-sm text-po-dim",
|
|
819
804
|
children: reviewCommentAnchor(comment)
|
|
820
805
|
}),
|
|
821
806
|
/* @__PURE__ */ jsx("span", {
|
|
822
|
-
className: "min-w-0 flex-1 truncate text-base text-
|
|
807
|
+
className: "min-w-0 flex-1 truncate text-base text-po-text",
|
|
823
808
|
children: comment.body
|
|
824
809
|
}),
|
|
825
810
|
/* @__PURE__ */ jsx(Button, {
|
|
@@ -888,7 +873,7 @@ function FilePreviewPanel({ filePath, sessionId, closeTransientTab }) {
|
|
|
888
873
|
className: "flex min-h-0 flex-1 flex-col",
|
|
889
874
|
children: [
|
|
890
875
|
/* @__PURE__ */ jsxs("header", {
|
|
891
|
-
className: "flex shrink-0 items-center gap-2 border-b border-
|
|
876
|
+
className: "flex shrink-0 items-center gap-2 border-b border-po-border px-4 py-2",
|
|
892
877
|
children: [
|
|
893
878
|
/* @__PURE__ */ jsx(Breadcrumb, {
|
|
894
879
|
path: relPath,
|
|
@@ -896,7 +881,7 @@ function FilePreviewPanel({ filePath, sessionId, closeTransientTab }) {
|
|
|
896
881
|
className: "min-w-0 flex-1"
|
|
897
882
|
}),
|
|
898
883
|
/* @__PURE__ */ jsx("span", {
|
|
899
|
-
className: "shrink-0 text-sm text-
|
|
884
|
+
className: "shrink-0 text-sm text-po-dim",
|
|
900
885
|
children: "unchanged"
|
|
901
886
|
}),
|
|
902
887
|
/* @__PURE__ */ jsx(Button, {
|
|
@@ -911,12 +896,12 @@ function FilePreviewPanel({ filePath, sessionId, closeTransientTab }) {
|
|
|
911
896
|
}),
|
|
912
897
|
error === void 0 ? null : /* @__PURE__ */ jsx("p", {
|
|
913
898
|
"data-testid": "files-preview-error",
|
|
914
|
-
className: "px-4 py-3 text-sm text-
|
|
899
|
+
className: "px-4 py-3 text-sm text-po-red",
|
|
915
900
|
children: error
|
|
916
901
|
}),
|
|
917
902
|
preview === void 0 && error === void 0 ? /* @__PURE__ */ jsx("p", {
|
|
918
903
|
"data-testid": "files-preview-loading",
|
|
919
|
-
className: "px-4 py-3 text-sm text-
|
|
904
|
+
className: "px-4 py-3 text-sm text-po-dim",
|
|
920
905
|
children: "reading this file…"
|
|
921
906
|
}) : null,
|
|
922
907
|
preview === void 0 ? null : /* @__PURE__ */ jsx("div", {
|
|
@@ -924,10 +909,10 @@ function FilePreviewPanel({ filePath, sessionId, closeTransientTab }) {
|
|
|
924
909
|
children: /* @__PURE__ */ jsxs("div", {
|
|
925
910
|
"data-testid": "files-preview",
|
|
926
911
|
"data-mode": previewMode,
|
|
927
|
-
className: "flex h-full flex-col gap-2 p-4 text-base text-
|
|
912
|
+
className: "flex h-full flex-col gap-2 p-4 text-base text-po-text",
|
|
928
913
|
children: [previewMode === "unavailable" ? /* @__PURE__ */ jsx("p", {
|
|
929
914
|
"data-testid": "files-preview-unavailable",
|
|
930
|
-
className: "text-sm text-
|
|
915
|
+
className: "text-sm text-po-dim",
|
|
931
916
|
children: working?.reason ?? "this file cannot be shown"
|
|
932
917
|
}) : null, previewMode === "media" || previewMode === "unavailable" ? /* @__PURE__ */ jsx(SessionMediaPreview, {
|
|
933
918
|
src: mediaSrc,
|
|
@@ -941,16 +926,16 @@ function FilePreviewPanel({ filePath, sessionId, closeTransientTab }) {
|
|
|
941
926
|
title: relPath,
|
|
942
927
|
sandbox: "",
|
|
943
928
|
srcDoc: content,
|
|
944
|
-
className: "h-[36rem] w-full rounded border border-
|
|
929
|
+
className: "h-[36rem] w-full rounded border border-po-border bg-po-deep"
|
|
945
930
|
}) : previewMode === "code" ? /* @__PURE__ */ jsx(CodeEditor, {
|
|
946
931
|
"data-testid": "files-preview-code",
|
|
947
932
|
value: content,
|
|
948
933
|
path: relPath,
|
|
949
934
|
readOnly: true,
|
|
950
|
-
className: "min-h-[24rem] flex-1 rounded border border-
|
|
935
|
+
className: "min-h-[24rem] flex-1 rounded border border-po-border"
|
|
951
936
|
}) : /* @__PURE__ */ jsx("pre", {
|
|
952
937
|
"data-testid": "files-preview-text",
|
|
953
|
-
className: "whitespace-pre-wrap break-words font-mono text-sm leading-normal text-
|
|
938
|
+
className: "whitespace-pre-wrap break-words font-mono text-sm leading-normal text-po-text",
|
|
954
939
|
children: content
|
|
955
940
|
})]
|
|
956
941
|
})
|
|
@@ -1001,7 +986,7 @@ function match(sessionId, path) {
|
|
|
1001
986
|
}
|
|
1002
987
|
//#endregion
|
|
1003
988
|
//#region src/extensions/workspaces/sessions/(frontend)/file-links/files.web.ts
|
|
1004
|
-
var files_web_default
|
|
989
|
+
var files_web_default = defineFileLinks({
|
|
1005
990
|
subscribe(listener) {
|
|
1006
991
|
const subscription = files.store.subscribe(listener);
|
|
1007
992
|
return () => subscription.unsubscribe();
|
|
@@ -1015,293 +1000,10 @@ var files_web_default$1 = defineFileLinks({
|
|
|
1015
1000
|
const item = match(sessionId, path);
|
|
1016
1001
|
if (item !== void 0) return fileTab(item.path, item.relPath);
|
|
1017
1002
|
const candidate = path.trim();
|
|
1018
|
-
return candidate === "" ? void 0 : filePreviewTab(candidate);
|
|
1003
|
+
return candidate === "" || candidate.startsWith("artifact:") ? void 0 : filePreviewTab(candidate);
|
|
1019
1004
|
}
|
|
1020
1005
|
});
|
|
1021
1006
|
//#endregion
|
|
1022
|
-
//#region src/extensions/workspaces/sessions/(frontend)/fill/_components/FilesBrowser.tsx
|
|
1023
|
-
function FileMetadata({ item, label, recent = false }) {
|
|
1024
|
-
return /* @__PURE__ */ jsxs("span", {
|
|
1025
|
-
className: "flex min-w-0 w-full items-center gap-1.5",
|
|
1026
|
-
children: [
|
|
1027
|
-
/* @__PURE__ */ jsx("span", {
|
|
1028
|
-
className: "min-w-0 flex-1 truncate text-left text-base font-semibold text-doom-hi",
|
|
1029
|
-
children: label ?? item.relPath
|
|
1030
|
-
}),
|
|
1031
|
-
recent ? /* @__PURE__ */ jsx("span", {
|
|
1032
|
-
"data-recent": "true",
|
|
1033
|
-
title: "most recent change",
|
|
1034
|
-
className: "shrink-0 text-2xs text-doom-blue",
|
|
1035
|
-
children: "●"
|
|
1036
|
-
}) : null,
|
|
1037
|
-
item.count > 1 ? /* @__PURE__ */ jsxs("span", {
|
|
1038
|
-
className: "shrink-0 text-2xs text-doom-faint",
|
|
1039
|
-
children: [item.count, "×"]
|
|
1040
|
-
}) : null,
|
|
1041
|
-
/* @__PURE__ */ jsx("span", {
|
|
1042
|
-
className: `shrink-0 text-sm ${item.diffable ? "text-doom-dim" : "text-doom-yellow"}`,
|
|
1043
|
-
children: TOOL_LABEL[item.tool] ?? item.tool
|
|
1044
|
-
})
|
|
1045
|
-
]
|
|
1046
|
-
});
|
|
1047
|
-
}
|
|
1048
|
-
function FileActivityRow({ item, onOpen }) {
|
|
1049
|
-
return /* @__PURE__ */ jsx(Button, {
|
|
1050
|
-
variant: "ghost",
|
|
1051
|
-
size: "card",
|
|
1052
|
-
"data-testid": `activity-file-${item.relPath}`,
|
|
1053
|
-
"data-file-diffable": item.diffable,
|
|
1054
|
-
title: item.diffable ? item.path : `${item.path} (changed by a command, so no diff was captured)`,
|
|
1055
|
-
onClick: onOpen,
|
|
1056
|
-
className: "min-w-0 gap-0.5 rounded-md px-1 py-1 hover:bg-doom-panel",
|
|
1057
|
-
children: /* @__PURE__ */ jsx(FileMetadata, { item })
|
|
1058
|
-
});
|
|
1059
|
-
}
|
|
1060
|
-
/**
|
|
1061
|
-
* The directory a run of rows shares.
|
|
1062
|
-
*
|
|
1063
|
-
* Deliberately not an option: the cursor counts files, and a header is a label
|
|
1064
|
-
* rather than something to open. Keeping it out of the listbox is what lets
|
|
1065
|
-
* arrow keys and Enter stay exactly what they were before the tree existed.
|
|
1066
|
-
*/
|
|
1067
|
-
function FileGroupHeader({ prefix }) {
|
|
1068
|
-
return /* @__PURE__ */ jsx("div", {
|
|
1069
|
-
"data-testid": `files-browser-group-${prefix}`,
|
|
1070
|
-
className: "truncate px-4 pt-2 pb-1 text-sm font-semibold text-doom-dim",
|
|
1071
|
-
children: prefix
|
|
1072
|
-
});
|
|
1073
|
-
}
|
|
1074
|
-
function BrowserFileRow({ item, label, indented = false, recent = false, selected, onSelect, onOpen }) {
|
|
1075
|
-
return /* @__PURE__ */ jsx("div", {
|
|
1076
|
-
role: "option",
|
|
1077
|
-
"aria-selected": selected,
|
|
1078
|
-
tabIndex: -1,
|
|
1079
|
-
"data-testid": `files-browser-file-${item.relPath}`,
|
|
1080
|
-
"data-file-diffable": item.diffable,
|
|
1081
|
-
"data-selected": selected,
|
|
1082
|
-
title: item.diffable ? item.path : `${item.path} (changed by a command, so no diff was captured)`,
|
|
1083
|
-
onMouseEnter: onSelect,
|
|
1084
|
-
onClick: onOpen,
|
|
1085
|
-
className: `flex min-w-0 cursor-pointer border-l-2 py-2 ${indented ? "pr-4 pl-8" : "px-4"} ${selected ? "border-doom-blue bg-doom-panel" : "border-transparent hover:bg-doom-panel/60"}`,
|
|
1086
|
-
children: /* @__PURE__ */ jsx(FileMetadata, {
|
|
1087
|
-
item,
|
|
1088
|
-
label,
|
|
1089
|
-
recent
|
|
1090
|
-
})
|
|
1091
|
-
});
|
|
1092
|
-
}
|
|
1093
|
-
/** The complete session file picker, ordered exactly as the file timeline supplies it. */
|
|
1094
|
-
function FilesBrowser({ items, onClose, onOpen }) {
|
|
1095
|
-
const [query, setQuery] = useState("");
|
|
1096
|
-
const [selectedIndex, setSelectedIndex] = useState(0);
|
|
1097
|
-
const inputRef = useRef(null);
|
|
1098
|
-
const listRef = useRef(null);
|
|
1099
|
-
const shown = filterFileItems(items, query);
|
|
1100
|
-
const grouped = query.trim() === "" ? groupByDirectory(shown, (item) => item.relPath) : void 0;
|
|
1101
|
-
const ordered = grouped === void 0 ? shown : grouped.flatMap((group) => group.items);
|
|
1102
|
-
const positions = new Map(ordered.map((item, index) => [item.path, index]));
|
|
1103
|
-
const selected = ordered[selectedIndex];
|
|
1104
|
-
const recentPath = items[0]?.path;
|
|
1105
|
-
const [lastShownLength, setLastShownLength] = useState(shown.length);
|
|
1106
|
-
if (lastShownLength !== shown.length) {
|
|
1107
|
-
setLastShownLength(shown.length);
|
|
1108
|
-
setSelectedIndex((current) => Math.min(current, Math.max(0, shown.length - 1)));
|
|
1109
|
-
}
|
|
1110
|
-
useEffect(() => {
|
|
1111
|
-
listRef.current?.querySelector("[aria-selected=\"true\"]")?.scrollIntoView({ block: "nearest" });
|
|
1112
|
-
}, [selectedIndex]);
|
|
1113
|
-
const move = (delta) => {
|
|
1114
|
-
if (ordered.length === 0) return;
|
|
1115
|
-
setSelectedIndex((current) => (current + delta + ordered.length) % ordered.length);
|
|
1116
|
-
};
|
|
1117
|
-
const onKeyDown = (event) => {
|
|
1118
|
-
if (event.key === "ArrowDown" || event.key === "ArrowUp") {
|
|
1119
|
-
event.preventDefault();
|
|
1120
|
-
move(event.key === "ArrowDown" ? 1 : -1);
|
|
1121
|
-
return;
|
|
1122
|
-
}
|
|
1123
|
-
if (event.key === "Escape") {
|
|
1124
|
-
event.preventDefault();
|
|
1125
|
-
onClose();
|
|
1126
|
-
return;
|
|
1127
|
-
}
|
|
1128
|
-
if (event.key === "Enter" && selected !== void 0 && (!(event.target instanceof Element) || event.target.closest("button") === null)) {
|
|
1129
|
-
event.preventDefault();
|
|
1130
|
-
onOpen(selected);
|
|
1131
|
-
}
|
|
1132
|
-
};
|
|
1133
|
-
return /* @__PURE__ */ jsxs("aside", {
|
|
1134
|
-
"data-testid": "files-browser",
|
|
1135
|
-
"aria-label": "changed files",
|
|
1136
|
-
tabIndex: -1,
|
|
1137
|
-
onKeyDown,
|
|
1138
|
-
className: "fixed inset-y-0 right-0 z-50 flex w-[min(440px,calc(100vw-24px))] flex-col overflow-hidden border-l border-doom-border bg-doom-rail outline-none",
|
|
1139
|
-
children: [
|
|
1140
|
-
/* @__PURE__ */ jsxs("div", {
|
|
1141
|
-
className: "flex h-11 shrink-0 items-center gap-2.5 border-b border-doom-border px-4",
|
|
1142
|
-
children: [
|
|
1143
|
-
/* @__PURE__ */ jsx("span", {
|
|
1144
|
-
className: "text-lg font-semibold text-doom-hi",
|
|
1145
|
-
children: "# files"
|
|
1146
|
-
}),
|
|
1147
|
-
/* @__PURE__ */ jsxs("span", {
|
|
1148
|
-
"data-testid": "files-browser-total",
|
|
1149
|
-
className: "text-sm text-doom-dim",
|
|
1150
|
-
children: [items.length, " changed"]
|
|
1151
|
-
}),
|
|
1152
|
-
/* @__PURE__ */ jsx("span", { className: "min-w-0 flex-1" }),
|
|
1153
|
-
/* @__PURE__ */ jsx(Button, {
|
|
1154
|
-
variant: "ghost",
|
|
1155
|
-
size: "icon",
|
|
1156
|
-
"data-testid": "files-browser-close",
|
|
1157
|
-
"aria-label": "close changed files",
|
|
1158
|
-
title: "close changed files",
|
|
1159
|
-
onClick: onClose,
|
|
1160
|
-
children: /* @__PURE__ */ jsx(CloseIcon, { className: "h-3 w-3" })
|
|
1161
|
-
})
|
|
1162
|
-
]
|
|
1163
|
-
}),
|
|
1164
|
-
/* @__PURE__ */ jsxs("div", {
|
|
1165
|
-
className: "flex items-center gap-2 px-4 pt-2.5 pb-1.5",
|
|
1166
|
-
children: [/* @__PURE__ */ jsx(Input, {
|
|
1167
|
-
ref: inputRef,
|
|
1168
|
-
"data-testid": "files-browser-search",
|
|
1169
|
-
"aria-label": "search changed file paths",
|
|
1170
|
-
value: query,
|
|
1171
|
-
placeholder: "search paths…",
|
|
1172
|
-
autoFocus: true,
|
|
1173
|
-
onChange: (event) => {
|
|
1174
|
-
setQuery(event.target.value);
|
|
1175
|
-
setSelectedIndex(0);
|
|
1176
|
-
}
|
|
1177
|
-
}), query.length > 0 ? /* @__PURE__ */ jsx(Button, {
|
|
1178
|
-
variant: "ghost",
|
|
1179
|
-
size: "xs",
|
|
1180
|
-
"data-testid": "files-browser-clear",
|
|
1181
|
-
"aria-label": "clear path search",
|
|
1182
|
-
onClick: () => {
|
|
1183
|
-
setQuery("");
|
|
1184
|
-
setSelectedIndex(0);
|
|
1185
|
-
inputRef.current?.focus();
|
|
1186
|
-
},
|
|
1187
|
-
children: "clear"
|
|
1188
|
-
}) : null]
|
|
1189
|
-
}),
|
|
1190
|
-
/* @__PURE__ */ jsxs("p", {
|
|
1191
|
-
"data-testid": "files-browser-matches",
|
|
1192
|
-
className: "shrink-0 px-4 pb-2 text-sm text-doom-dim",
|
|
1193
|
-
children: [
|
|
1194
|
-
shown.length,
|
|
1195
|
-
" matches · ",
|
|
1196
|
-
grouped === void 0 ? "newest change first" : "by path"
|
|
1197
|
-
]
|
|
1198
|
-
}),
|
|
1199
|
-
/* @__PURE__ */ jsxs("div", {
|
|
1200
|
-
ref: listRef,
|
|
1201
|
-
role: "listbox",
|
|
1202
|
-
"aria-label": "changed files",
|
|
1203
|
-
className: "flex min-h-0 flex-1 flex-col overflow-y-auto pb-2",
|
|
1204
|
-
children: [shown.length === 0 ? /* @__PURE__ */ jsx("p", {
|
|
1205
|
-
className: "px-4 py-3 text-sm text-doom-dim",
|
|
1206
|
-
children: "nothing matches the path"
|
|
1207
|
-
}) : null, grouped === void 0 ? shown.map((item) => /* @__PURE__ */ jsx(BrowserFileRow, {
|
|
1208
|
-
item,
|
|
1209
|
-
label: item.relPath,
|
|
1210
|
-
recent: item.path === recentPath,
|
|
1211
|
-
selected: positions.get(item.path) === selectedIndex,
|
|
1212
|
-
onSelect: () => setSelectedIndex(positions.get(item.path) ?? 0),
|
|
1213
|
-
onOpen: () => onOpen(item)
|
|
1214
|
-
}, item.path)) : grouped.map((group) => /* @__PURE__ */ jsxs(Fragment, { children: [group.prefix === "" ? null : /* @__PURE__ */ jsx(FileGroupHeader, { prefix: group.prefix }), group.items.map((item) => /* @__PURE__ */ jsx(BrowserFileRow, {
|
|
1215
|
-
item,
|
|
1216
|
-
label: groupRowLabel(group.prefix, item.relPath),
|
|
1217
|
-
indented: true,
|
|
1218
|
-
recent: item.path === recentPath,
|
|
1219
|
-
selected: positions.get(item.path) === selectedIndex,
|
|
1220
|
-
onSelect: () => setSelectedIndex(positions.get(item.path) ?? 0),
|
|
1221
|
-
onOpen: () => onOpen(item)
|
|
1222
|
-
}, item.path))] }, group.prefix))]
|
|
1223
|
-
}),
|
|
1224
|
-
/* @__PURE__ */ jsx("div", {
|
|
1225
|
-
className: "flex h-8 shrink-0 items-center border-t border-doom-border-soft bg-doom-deep px-4",
|
|
1226
|
-
children: /* @__PURE__ */ jsx("span", {
|
|
1227
|
-
className: "text-sm text-doom-dim",
|
|
1228
|
-
children: "↑↓ choose · enter open · esc close"
|
|
1229
|
-
})
|
|
1230
|
-
})
|
|
1231
|
-
]
|
|
1232
|
-
});
|
|
1233
|
-
}
|
|
1234
|
-
//#endregion
|
|
1235
|
-
//#region src/extensions/workspaces/sessions/(frontend)/fill/_components/FilesActivitySection.tsx
|
|
1236
|
-
/**
|
|
1237
|
-
* The files group's body in the activity dock: what this session has changed.
|
|
1238
|
-
*
|
|
1239
|
-
* Every recorded file is listed, not only the ones the agent named. A file
|
|
1240
|
-
* found by comparing the tree around a bash call is marked, because it is
|
|
1241
|
-
* openable and editable but has no baseline to diff against, and a row that
|
|
1242
|
-
* hid that distinction would promise a diff the tab cannot show.
|
|
1243
|
-
*/
|
|
1244
|
-
/** The most recent changes first, which is the order the timeline already folds to. */
|
|
1245
|
-
const VISIBLE_ROWS = 5;
|
|
1246
|
-
function FilesActivitySection({ sessionId, openTransientTab }) {
|
|
1247
|
-
const { items } = useStore(files.store, (state) => files.select(state, sessionId));
|
|
1248
|
-
const [browserOpen, setBrowserOpen] = useState(false);
|
|
1249
|
-
const openFile = (item) => {
|
|
1250
|
-
if (sessionId === null) return;
|
|
1251
|
-
openTransientTab(fileTab(item.path, item.relPath));
|
|
1252
|
-
setBrowserOpen(false);
|
|
1253
|
-
};
|
|
1254
|
-
if (items.length === 0) return /* @__PURE__ */ jsx("p", {
|
|
1255
|
-
"data-testid": "activity-summary-files",
|
|
1256
|
-
className: "px-1 text-sm text-doom-dim",
|
|
1257
|
-
children: "nothing changed yet"
|
|
1258
|
-
});
|
|
1259
|
-
const visible = items.slice(0, VISIBLE_ROWS);
|
|
1260
|
-
return /* @__PURE__ */ jsxs("div", {
|
|
1261
|
-
"data-testid": "activity-file-edits",
|
|
1262
|
-
className: "flex flex-col gap-0.5",
|
|
1263
|
-
children: [
|
|
1264
|
-
visible.map((item) => /* @__PURE__ */ jsx(FileActivityRow, {
|
|
1265
|
-
item,
|
|
1266
|
-
onOpen: () => openFile(item)
|
|
1267
|
-
}, item.path)),
|
|
1268
|
-
items.length > visible.length ? /* @__PURE__ */ jsxs(Button, {
|
|
1269
|
-
variant: "link",
|
|
1270
|
-
size: "xs",
|
|
1271
|
-
"data-testid": "activity-files-show-all",
|
|
1272
|
-
"aria-label": `show all ${items.length} changed files`,
|
|
1273
|
-
className: "self-start px-1 pt-0.5 text-doom-faint",
|
|
1274
|
-
onClick: () => setBrowserOpen(true),
|
|
1275
|
-
children: [
|
|
1276
|
-
"show all ",
|
|
1277
|
-
items.length,
|
|
1278
|
-
" files"
|
|
1279
|
-
]
|
|
1280
|
-
}) : null,
|
|
1281
|
-
browserOpen ? /* @__PURE__ */ jsx(FilesBrowser, {
|
|
1282
|
-
items,
|
|
1283
|
-
onClose: () => setBrowserOpen(false),
|
|
1284
|
-
onOpen: openFile
|
|
1285
|
-
}) : null
|
|
1286
|
-
]
|
|
1287
|
-
});
|
|
1288
|
-
}
|
|
1289
|
-
//#endregion
|
|
1290
|
-
//#region src/extensions/workspaces/sessions/(frontend)/fill/Files.activity.files.web.tsx
|
|
1291
|
-
var Files_activity_files_web_default = defineFill({ component: FilesActivitySection });
|
|
1292
|
-
var files_web_default = defineLeaderBinding({
|
|
1293
|
-
path: [{
|
|
1294
|
-
key: "e",
|
|
1295
|
-
label: "extension",
|
|
1296
|
-
detail: "tools, skills and config"
|
|
1297
|
-
}, {
|
|
1298
|
-
key: "f",
|
|
1299
|
-
label: "files",
|
|
1300
|
-
detail: "files this session changed"
|
|
1301
|
-
}],
|
|
1302
|
-
command: "file-edits"
|
|
1303
|
-
});
|
|
1304
|
-
//#endregion
|
|
1305
1007
|
//#region generated/web.ts
|
|
1306
1008
|
const via = (identity, value) => value === void 0 ? void 0 : {
|
|
1307
1009
|
...identity,
|
|
@@ -1310,23 +1012,11 @@ const via = (identity, value) => value === void 0 ? void 0 : {
|
|
|
1310
1012
|
const webPlugin = defineWebPlugin({
|
|
1311
1013
|
id: "files",
|
|
1312
1014
|
session: {
|
|
1313
|
-
get activityGroups() {
|
|
1314
|
-
return [via({ name: "files" }, files_web_default$2)];
|
|
1315
|
-
},
|
|
1316
1015
|
get channels() {
|
|
1317
1016
|
return [via({ channel: "file_edits" }, file_edits_web_default)];
|
|
1318
1017
|
},
|
|
1319
1018
|
get fileLinks() {
|
|
1320
|
-
return files_web_default
|
|
1321
|
-
},
|
|
1322
|
-
get fills() {
|
|
1323
|
-
return [via({
|
|
1324
|
-
slot: "activity.files",
|
|
1325
|
-
id: "files"
|
|
1326
|
-
}, Files_activity_files_web_default)];
|
|
1327
|
-
},
|
|
1328
|
-
get leaderBindings() {
|
|
1329
|
-
return [via({ id: "files.files" }, files_web_default)];
|
|
1019
|
+
return files_web_default;
|
|
1330
1020
|
}
|
|
1331
1021
|
}
|
|
1332
1022
|
});
|