@blade-hq/agent-kit 0.4.21 → 0.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{SkillStatusBar-DCOlTYcT.d.ts → SkillStatusBar-B7-EU8A4.d.ts} +1 -1
- package/dist/{blade-client-BEjbedNc.d.ts → blade-client-BKiP6U73.d.ts} +6 -1
- package/dist/{chunk-WZT2DOBJ.js → chunk-2FTEBWEM.js} +2 -2
- package/dist/{chunk-LKNU4NUC.js → chunk-C7VSMOXN.js} +20 -2
- package/dist/chunk-C7VSMOXN.js.map +1 -0
- package/dist/{chunk-47YVQZQ7.js → chunk-CFZDKYT3.js} +2 -2
- package/dist/{chunk-WQYDTSSV.js → chunk-M2ZCTKY7.js} +2 -2
- package/dist/{chunk-RMLZ4ZBY.js → chunk-ZGM3H24C.js} +23 -4
- package/dist/chunk-ZGM3H24C.js.map +1 -0
- package/dist/client/index.d.ts +24 -5
- package/dist/react/api/vibe-coding.d.ts +2 -2
- package/dist/react/api/vibe-coding.js +1 -1
- package/dist/react/components/chat/index.d.ts +3 -3
- package/dist/react/components/chat/index.js +4 -4
- package/dist/react/components/plan/index.js +2 -2
- package/dist/react/components/session/index.js +2 -2
- package/dist/react/components/workspace/index.js +281 -143
- package/dist/react/components/workspace/index.js.map +1 -1
- package/dist/react/index.d.ts +4 -4
- package/dist/react/index.js +5 -5
- package/dist/style.css +1 -1
- package/package.json +1 -1
- package/dist/chunk-LKNU4NUC.js.map +0 -1
- package/dist/chunk-RMLZ4ZBY.js.map +0 -1
- /package/dist/{chunk-WZT2DOBJ.js.map → chunk-2FTEBWEM.js.map} +0 -0
- /package/dist/{chunk-47YVQZQ7.js.map → chunk-CFZDKYT3.js.map} +0 -0
- /package/dist/{chunk-WQYDTSSV.js.map → chunk-M2ZCTKY7.js.map} +0 -0
|
@@ -3,7 +3,7 @@ import {
|
|
|
3
3
|
CollapsibleContent,
|
|
4
4
|
CollapsibleTrigger,
|
|
5
5
|
resolveSessionFilePreviewTarget
|
|
6
|
-
} from "../../../chunk-
|
|
6
|
+
} from "../../../chunk-CFZDKYT3.js";
|
|
7
7
|
import {
|
|
8
8
|
apiFetchText,
|
|
9
9
|
copyFile,
|
|
@@ -17,7 +17,7 @@ import {
|
|
|
17
17
|
useChatStore,
|
|
18
18
|
useSessionStore,
|
|
19
19
|
useUiStore
|
|
20
|
-
} from "../../../chunk-
|
|
20
|
+
} from "../../../chunk-C7VSMOXN.js";
|
|
21
21
|
import "../../../chunk-J3XVFPOV.js";
|
|
22
22
|
import "../../../chunk-ROGNJYST.js";
|
|
23
23
|
import {
|
|
@@ -277,7 +277,7 @@ var GENERIC_FILE_ICON_ASSET = new URL("../../assets/file-icons/generic-file.png"
|
|
|
277
277
|
// src/react/components/workspace/FileTree.tsx
|
|
278
278
|
import { Fragment as Fragment2, jsx as jsx2, jsxs as jsxs2 } from "react/jsx-runtime";
|
|
279
279
|
var ROOT_PATH = ".";
|
|
280
|
-
var TREE_ROW_CLASS = "group flex w-full items-center gap-1 rounded px-2 py-1 text-left transition-colors hover:bg-muted/50";
|
|
280
|
+
var TREE_ROW_CLASS = "group flex w-full items-center gap-1.5 rounded-md px-2 py-1.5 text-left transition-colors hover:bg-muted/50";
|
|
281
281
|
function FileTree2({
|
|
282
282
|
sessionId,
|
|
283
283
|
checkActiveSession = true,
|
|
@@ -473,6 +473,7 @@ function FolderNode({
|
|
|
473
473
|
const queryClient = useQueryClient();
|
|
474
474
|
const isExpanded = expandedDirs.has(entry.path);
|
|
475
475
|
const isSelected = selectedPath === entry.path;
|
|
476
|
+
const isCurrentSessionDir = entry.name === sessionId;
|
|
476
477
|
const renameInputRef = useRef(null);
|
|
477
478
|
const [isRenaming, setIsRenaming] = useState2(false);
|
|
478
479
|
const [renamingValue, setRenamingValue] = useState2(entry.name);
|
|
@@ -549,7 +550,7 @@ function FolderNode({
|
|
|
549
550
|
ChevronRight,
|
|
550
551
|
{
|
|
551
552
|
className: cn(
|
|
552
|
-
"size-
|
|
553
|
+
"size-5 shrink-0 text-[hsl(var(--muted-foreground))] transition-transform",
|
|
553
554
|
isExpanded && "rotate-90"
|
|
554
555
|
)
|
|
555
556
|
}
|
|
@@ -591,7 +592,8 @@ function FolderNode({
|
|
|
591
592
|
},
|
|
592
593
|
children: [
|
|
593
594
|
/* @__PURE__ */ jsx2(FileTreeIcon, { children: getFolderIcon() }),
|
|
594
|
-
/* @__PURE__ */ jsx2(FileTreeName, { className: "min-w-0 flex-1", children: entry.name })
|
|
595
|
+
/* @__PURE__ */ jsx2(FileTreeName, { className: "min-w-0 flex-1", children: entry.name }),
|
|
596
|
+
isCurrentSessionDir ? /* @__PURE__ */ jsx2("span", { className: "shrink-0 rounded-full bg-emerald-100 px-2 py-[2px] text-[11px] font-medium leading-[14px] text-emerald-700", children: "\u5F53\u524D\u5BF9\u8BDD" }) : null
|
|
595
597
|
]
|
|
596
598
|
}
|
|
597
599
|
),
|
|
@@ -631,12 +633,11 @@ function FolderNode({
|
|
|
631
633
|
children: activeAction === "copy" ? /* @__PURE__ */ jsx2(Loader2, { size: 12, className: "animate-spin" }) : /* @__PURE__ */ jsx2(Copy, { size: 12 })
|
|
632
634
|
}
|
|
633
635
|
),
|
|
634
|
-
/* @__PURE__ */ jsx2(
|
|
636
|
+
onShareFile ? /* @__PURE__ */ jsx2(
|
|
635
637
|
TreeActionButton,
|
|
636
638
|
{
|
|
637
|
-
disabled: activeAction !== null
|
|
639
|
+
disabled: activeAction !== null,
|
|
638
640
|
onClick: async () => {
|
|
639
|
-
if (!onShareFile) return;
|
|
640
641
|
setActiveAction("share");
|
|
641
642
|
try {
|
|
642
643
|
await onShareFile(entry.path, entry.name);
|
|
@@ -647,10 +648,10 @@ function FolderNode({
|
|
|
647
648
|
setActiveAction(null);
|
|
648
649
|
}
|
|
649
650
|
},
|
|
650
|
-
title: "\u5171\u4EAB\u5230
|
|
651
|
+
title: "\u5171\u4EAB\u5230\u4EA7\u7269\u533A",
|
|
651
652
|
children: activeAction === "share" ? /* @__PURE__ */ jsx2(Loader2, { size: 12, className: "animate-spin" }) : /* @__PURE__ */ jsx2(Link2, { size: 12 })
|
|
652
653
|
}
|
|
653
|
-
),
|
|
654
|
+
) : null,
|
|
654
655
|
/* @__PURE__ */ jsx2(
|
|
655
656
|
TreeActionButton,
|
|
656
657
|
{
|
|
@@ -773,120 +774,130 @@ function FileNode({
|
|
|
773
774
|
setActiveAction(null);
|
|
774
775
|
}
|
|
775
776
|
};
|
|
776
|
-
return /* @__PURE__ */ jsxs2(
|
|
777
|
-
|
|
778
|
-
|
|
779
|
-
|
|
780
|
-
|
|
781
|
-
{
|
|
782
|
-
ref:
|
|
783
|
-
|
|
784
|
-
|
|
785
|
-
|
|
786
|
-
|
|
787
|
-
|
|
788
|
-
|
|
789
|
-
|
|
790
|
-
|
|
791
|
-
|
|
792
|
-
|
|
793
|
-
|
|
794
|
-
|
|
795
|
-
|
|
796
|
-
|
|
777
|
+
return /* @__PURE__ */ jsxs2(
|
|
778
|
+
"div",
|
|
779
|
+
{
|
|
780
|
+
className: cn(TREE_ROW_CLASS, isSelected && "bg-muted"),
|
|
781
|
+
draggable: !isRenaming,
|
|
782
|
+
onDragStart: (e) => {
|
|
783
|
+
e.dataTransfer.setData("application/blade-file-ref", JSON.stringify({ path: entry.path, name: entry.name }));
|
|
784
|
+
e.dataTransfer.effectAllowed = "copy";
|
|
785
|
+
},
|
|
786
|
+
children: [
|
|
787
|
+
/* @__PURE__ */ jsx2("span", { className: "size-5 shrink-0" }),
|
|
788
|
+
/* @__PURE__ */ jsx2(FileTreeIcon, { children: getFileIcon(entry.name) }),
|
|
789
|
+
isRenaming ? /* @__PURE__ */ jsx2(
|
|
790
|
+
"input",
|
|
791
|
+
{
|
|
792
|
+
ref: renameInputRef,
|
|
793
|
+
value: renamingValue,
|
|
794
|
+
className: "h-6 min-w-0 flex-1 rounded border border-[hsl(var(--border))] bg-background px-2 text-xs outline-none ring-offset-background focus-visible:ring-1 focus-visible:ring-[hsl(var(--ring))]",
|
|
795
|
+
disabled: activeAction === "rename",
|
|
796
|
+
onBlur: () => void finishRename(),
|
|
797
|
+
onChange: (event) => setRenamingValue(event.target.value),
|
|
798
|
+
onClick: (event) => event.stopPropagation(),
|
|
799
|
+
onKeyDown: (event) => {
|
|
800
|
+
event.stopPropagation();
|
|
801
|
+
if (event.key === "Enter") {
|
|
802
|
+
event.preventDefault();
|
|
803
|
+
void finishRename();
|
|
804
|
+
} else if (event.key === "Escape") {
|
|
805
|
+
event.preventDefault();
|
|
806
|
+
cancelRename();
|
|
807
|
+
}
|
|
808
|
+
}
|
|
797
809
|
}
|
|
798
|
-
|
|
799
|
-
|
|
800
|
-
|
|
801
|
-
|
|
802
|
-
|
|
803
|
-
|
|
804
|
-
|
|
805
|
-
|
|
806
|
-
|
|
807
|
-
|
|
808
|
-
|
|
809
|
-
|
|
810
|
-
|
|
811
|
-
|
|
812
|
-
|
|
813
|
-
|
|
814
|
-
|
|
815
|
-
|
|
816
|
-
|
|
817
|
-
|
|
818
|
-
|
|
819
|
-
|
|
820
|
-
|
|
821
|
-
|
|
822
|
-
|
|
823
|
-
|
|
824
|
-
|
|
825
|
-
title: "\u4E0B\u8F7D\u6587\u4EF6",
|
|
826
|
-
children: /* @__PURE__ */ jsx2(Download, { size: 12 })
|
|
827
|
-
}
|
|
828
|
-
),
|
|
829
|
-
/* @__PURE__ */ jsx2(
|
|
830
|
-
TreeActionButton,
|
|
831
|
-
{
|
|
832
|
-
disabled: activeAction !== null,
|
|
833
|
-
onClick: () => {
|
|
834
|
-
onSelectPath(entry.path);
|
|
835
|
-
setRenamingValue(entry.name);
|
|
836
|
-
setIsRenaming(true);
|
|
837
|
-
},
|
|
838
|
-
title: "\u91CD\u547D\u540D",
|
|
839
|
-
children: activeAction === "rename" ? /* @__PURE__ */ jsx2(Loader2, { size: 12, className: "animate-spin" }) : /* @__PURE__ */ jsx2(Pencil, { size: 12 })
|
|
840
|
-
}
|
|
841
|
-
),
|
|
842
|
-
/* @__PURE__ */ jsx2(
|
|
843
|
-
TreeActionButton,
|
|
844
|
-
{
|
|
845
|
-
disabled: activeAction !== null,
|
|
846
|
-
onClick: () => void handleCopy(),
|
|
847
|
-
title: "\u590D\u5236\u6587\u4EF6",
|
|
848
|
-
children: activeAction === "copy" ? /* @__PURE__ */ jsx2(Loader2, { size: 12, className: "animate-spin" }) : /* @__PURE__ */ jsx2(Copy, { size: 12 })
|
|
849
|
-
}
|
|
850
|
-
),
|
|
851
|
-
/* @__PURE__ */ jsx2(
|
|
852
|
-
TreeActionButton,
|
|
853
|
-
{
|
|
854
|
-
disabled: activeAction !== null || !onShareFile,
|
|
855
|
-
onClick: async () => {
|
|
856
|
-
if (!onShareFile) return;
|
|
857
|
-
setActiveAction("share");
|
|
858
|
-
try {
|
|
859
|
-
await onShareFile(entry.path, entry.name);
|
|
860
|
-
await queryClient.invalidateQueries({ queryKey: ["file-tree", sessionId] });
|
|
861
|
-
} catch (error) {
|
|
862
|
-
alert(getErrorMessage(error, "\u5171\u4EAB\u5931\u8D25"));
|
|
863
|
-
} finally {
|
|
864
|
-
setActiveAction(null);
|
|
810
|
+
) : /* @__PURE__ */ jsxs2(
|
|
811
|
+
"button",
|
|
812
|
+
{
|
|
813
|
+
type: "button",
|
|
814
|
+
className: "flex min-w-0 flex-1 cursor-pointer items-center border-none bg-transparent p-0 text-left",
|
|
815
|
+
onClick: () => {
|
|
816
|
+
onSelectPath(entry.path);
|
|
817
|
+
void onOpenFile(entry.path, entry.name);
|
|
818
|
+
},
|
|
819
|
+
children: [
|
|
820
|
+
/* @__PURE__ */ jsx2(FileTreeName, { className: "min-w-0 flex-1", children: entry.name }),
|
|
821
|
+
/* @__PURE__ */ jsx2(FileTagList, { tags: entry.tags })
|
|
822
|
+
]
|
|
823
|
+
}
|
|
824
|
+
),
|
|
825
|
+
isOpening ? /* @__PURE__ */ jsx2(Loader2, { size: 12, className: "ml-auto shrink-0 animate-spin text-[hsl(var(--muted-foreground))]" }) : !readOnly ? /* @__PURE__ */ jsxs2(FileTreeActions, { className: "ml-auto hidden shrink-0 group-hover:flex", children: [
|
|
826
|
+
/* @__PURE__ */ jsx2(
|
|
827
|
+
TreeActionButton,
|
|
828
|
+
{
|
|
829
|
+
onClick: () => {
|
|
830
|
+
const anchor = document.createElement("a");
|
|
831
|
+
anchor.href = downloadUrl;
|
|
832
|
+
anchor.download = entry.name;
|
|
833
|
+
anchor.click();
|
|
834
|
+
},
|
|
835
|
+
title: "\u4E0B\u8F7D\u6587\u4EF6",
|
|
836
|
+
children: /* @__PURE__ */ jsx2(Download, { size: 12 })
|
|
865
837
|
}
|
|
866
|
-
|
|
867
|
-
|
|
868
|
-
|
|
869
|
-
|
|
870
|
-
|
|
871
|
-
|
|
872
|
-
|
|
873
|
-
|
|
874
|
-
|
|
875
|
-
|
|
876
|
-
|
|
877
|
-
|
|
878
|
-
|
|
879
|
-
|
|
880
|
-
|
|
881
|
-
|
|
882
|
-
|
|
883
|
-
|
|
884
|
-
|
|
885
|
-
|
|
886
|
-
|
|
887
|
-
|
|
888
|
-
|
|
889
|
-
|
|
838
|
+
),
|
|
839
|
+
/* @__PURE__ */ jsx2(
|
|
840
|
+
TreeActionButton,
|
|
841
|
+
{
|
|
842
|
+
disabled: activeAction !== null,
|
|
843
|
+
onClick: () => {
|
|
844
|
+
onSelectPath(entry.path);
|
|
845
|
+
setRenamingValue(entry.name);
|
|
846
|
+
setIsRenaming(true);
|
|
847
|
+
},
|
|
848
|
+
title: "\u91CD\u547D\u540D",
|
|
849
|
+
children: activeAction === "rename" ? /* @__PURE__ */ jsx2(Loader2, { size: 12, className: "animate-spin" }) : /* @__PURE__ */ jsx2(Pencil, { size: 12 })
|
|
850
|
+
}
|
|
851
|
+
),
|
|
852
|
+
/* @__PURE__ */ jsx2(
|
|
853
|
+
TreeActionButton,
|
|
854
|
+
{
|
|
855
|
+
disabled: activeAction !== null,
|
|
856
|
+
onClick: () => void handleCopy(),
|
|
857
|
+
title: "\u590D\u5236\u6587\u4EF6",
|
|
858
|
+
children: activeAction === "copy" ? /* @__PURE__ */ jsx2(Loader2, { size: 12, className: "animate-spin" }) : /* @__PURE__ */ jsx2(Copy, { size: 12 })
|
|
859
|
+
}
|
|
860
|
+
),
|
|
861
|
+
onShareFile ? /* @__PURE__ */ jsx2(
|
|
862
|
+
TreeActionButton,
|
|
863
|
+
{
|
|
864
|
+
disabled: activeAction !== null,
|
|
865
|
+
onClick: async () => {
|
|
866
|
+
setActiveAction("share");
|
|
867
|
+
try {
|
|
868
|
+
await onShareFile(entry.path, entry.name);
|
|
869
|
+
await queryClient.invalidateQueries({ queryKey: ["file-tree", sessionId] });
|
|
870
|
+
} catch (error) {
|
|
871
|
+
alert(getErrorMessage(error, "\u5171\u4EAB\u5931\u8D25"));
|
|
872
|
+
} finally {
|
|
873
|
+
setActiveAction(null);
|
|
874
|
+
}
|
|
875
|
+
},
|
|
876
|
+
title: "\u5171\u4EAB\u5230\u4EA7\u7269\u533A",
|
|
877
|
+
children: activeAction === "share" ? /* @__PURE__ */ jsx2(Loader2, { size: 12, className: "animate-spin" }) : /* @__PURE__ */ jsx2(Link2, { size: 12 })
|
|
878
|
+
}
|
|
879
|
+
) : null,
|
|
880
|
+
/* @__PURE__ */ jsx2(
|
|
881
|
+
TreeActionButton,
|
|
882
|
+
{
|
|
883
|
+
disabled: activeAction !== null,
|
|
884
|
+
onClick: () => void handleDelete(),
|
|
885
|
+
title: "\u5220\u9664\u6587\u4EF6",
|
|
886
|
+
children: activeAction === "delete" ? /* @__PURE__ */ jsx2(Loader2, { size: 12, className: "animate-spin" }) : /* @__PURE__ */ jsx2(Trash2, { size: 12 })
|
|
887
|
+
}
|
|
888
|
+
)
|
|
889
|
+
] }) : allowDelete ? /* @__PURE__ */ jsx2(FileTreeActions, { className: "ml-auto hidden shrink-0 group-hover:flex", children: /* @__PURE__ */ jsx2(
|
|
890
|
+
TreeActionButton,
|
|
891
|
+
{
|
|
892
|
+
disabled: activeAction !== null,
|
|
893
|
+
onClick: () => void handleDelete(),
|
|
894
|
+
title: "\u5220\u9664\u6587\u4EF6",
|
|
895
|
+
children: activeAction === "delete" ? /* @__PURE__ */ jsx2(Loader2, { size: 12, className: "animate-spin" }) : /* @__PURE__ */ jsx2(Trash2, { size: 12 })
|
|
896
|
+
}
|
|
897
|
+
) }) : null
|
|
898
|
+
]
|
|
899
|
+
}
|
|
900
|
+
);
|
|
890
901
|
}
|
|
891
902
|
function LazyDirChildren({
|
|
892
903
|
dirPath,
|
|
@@ -961,18 +972,40 @@ function LazyDirChildren({
|
|
|
961
972
|
)
|
|
962
973
|
) });
|
|
963
974
|
}
|
|
975
|
+
var TAG_STYLES = {
|
|
976
|
+
"AI \u751F\u6210": "bg-[hsl(var(--muted))] text-[hsl(var(--muted-foreground))]",
|
|
977
|
+
"\u7528\u6237\u4E0A\u4F20": "bg-[hsl(var(--muted))] text-[hsl(var(--muted-foreground))]",
|
|
978
|
+
\u4EA7\u7269: "bg-[hsl(var(--muted))] text-[hsl(var(--muted-foreground))]"
|
|
979
|
+
};
|
|
980
|
+
var DEFAULT_TAG_STYLE = "bg-[hsl(var(--muted))] text-[hsl(var(--muted-foreground))]";
|
|
964
981
|
function FileTagList({ tags }) {
|
|
965
|
-
|
|
966
|
-
|
|
982
|
+
const normalizedTags = normalizeDisplayTags(tags);
|
|
983
|
+
if (normalizedTags.length === 0) return null;
|
|
984
|
+
return /* @__PURE__ */ jsx2("span", { className: "ml-1 flex min-w-0 shrink-0 items-center gap-1", children: normalizedTags.map((tag) => /* @__PURE__ */ jsx2(
|
|
967
985
|
"span",
|
|
968
986
|
{
|
|
969
|
-
className:
|
|
987
|
+
className: `max-w-20 truncate rounded-full px-2 py-[2px] text-[11px] font-medium leading-[14px] ${TAG_STYLES[tag] ?? DEFAULT_TAG_STYLE}`,
|
|
970
988
|
title: tag,
|
|
971
989
|
children: tag
|
|
972
990
|
},
|
|
973
991
|
tag
|
|
974
992
|
)) });
|
|
975
993
|
}
|
|
994
|
+
function normalizeDisplayTags(tags) {
|
|
995
|
+
if (!tags) return [];
|
|
996
|
+
return tags.flatMap((tag) => {
|
|
997
|
+
const trimmed = tag.trim();
|
|
998
|
+
if (!trimmed.startsWith("[") || !trimmed.endsWith("]")) {
|
|
999
|
+
return trimmed ? [trimmed] : [];
|
|
1000
|
+
}
|
|
1001
|
+
try {
|
|
1002
|
+
const parsed = JSON.parse(trimmed);
|
|
1003
|
+
return Array.isArray(parsed) ? parsed.filter((item) => typeof item === "string") : [trimmed];
|
|
1004
|
+
} catch {
|
|
1005
|
+
return [trimmed];
|
|
1006
|
+
}
|
|
1007
|
+
});
|
|
1008
|
+
}
|
|
976
1009
|
function TreeActionButton({
|
|
977
1010
|
children,
|
|
978
1011
|
disabled = false,
|
|
@@ -1000,25 +1033,121 @@ function EmptyState({ title, description }) {
|
|
|
1000
1033
|
] })
|
|
1001
1034
|
] });
|
|
1002
1035
|
}
|
|
1036
|
+
var ICO_DOC = /* @__PURE__ */ jsxs2("svg", { "aria-hidden": "true", width: "18", height: "18", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: [
|
|
1037
|
+
/* @__PURE__ */ jsx2("path", { d: "M14.5 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V7.5L14.5 2z" }),
|
|
1038
|
+
/* @__PURE__ */ jsx2("polyline", { points: "14 2 14 8 20 8" })
|
|
1039
|
+
] });
|
|
1040
|
+
var ICO_CODE = /* @__PURE__ */ jsxs2("svg", { "aria-hidden": "true", width: "18", height: "18", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: [
|
|
1041
|
+
/* @__PURE__ */ jsx2("polyline", { points: "16 18 22 12 16 6" }),
|
|
1042
|
+
/* @__PURE__ */ jsx2("polyline", { points: "8 6 2 12 8 18" })
|
|
1043
|
+
] });
|
|
1044
|
+
var ICO_TABLE = /* @__PURE__ */ jsxs2("svg", { "aria-hidden": "true", width: "18", height: "18", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: [
|
|
1045
|
+
/* @__PURE__ */ jsx2("rect", { x: "3", y: "3", width: "18", height: "18", rx: "2" }),
|
|
1046
|
+
/* @__PURE__ */ jsx2("path", { d: "M3 9h18" }),
|
|
1047
|
+
/* @__PURE__ */ jsx2("path", { d: "M3 15h18" }),
|
|
1048
|
+
/* @__PURE__ */ jsx2("path", { d: "M9 3v18" })
|
|
1049
|
+
] });
|
|
1050
|
+
var ICO_SLIDES = /* @__PURE__ */ jsxs2("svg", { "aria-hidden": "true", width: "18", height: "18", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: [
|
|
1051
|
+
/* @__PURE__ */ jsx2("rect", { x: "2", y: "3", width: "20", height: "14", rx: "2" }),
|
|
1052
|
+
/* @__PURE__ */ jsx2("path", { d: "M8 21h8" }),
|
|
1053
|
+
/* @__PURE__ */ jsx2("path", { d: "M12 17v4" })
|
|
1054
|
+
] });
|
|
1055
|
+
var ICO_PDF = /* @__PURE__ */ jsxs2("svg", { "aria-hidden": "true", width: "18", height: "18", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: [
|
|
1056
|
+
/* @__PURE__ */ jsx2("path", { d: "M14.5 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V7.5L14.5 2z" }),
|
|
1057
|
+
/* @__PURE__ */ jsx2("path", { d: "M8 13h8" }),
|
|
1058
|
+
/* @__PURE__ */ jsx2("path", { d: "M8 17h5" })
|
|
1059
|
+
] });
|
|
1060
|
+
var ICO_IMAGE = /* @__PURE__ */ jsxs2("svg", { "aria-hidden": "true", width: "18", height: "18", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: [
|
|
1061
|
+
/* @__PURE__ */ jsx2("rect", { x: "3", y: "3", width: "18", height: "18", rx: "2" }),
|
|
1062
|
+
/* @__PURE__ */ jsx2("circle", { cx: "9", cy: "9", r: "2" }),
|
|
1063
|
+
/* @__PURE__ */ jsx2("path", { d: "m21 15-3.09-3.09a2 2 0 0 0-2.82 0L6 21" })
|
|
1064
|
+
] });
|
|
1065
|
+
var ICO_AUDIO = /* @__PURE__ */ jsxs2("svg", { "aria-hidden": "true", width: "18", height: "18", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: [
|
|
1066
|
+
/* @__PURE__ */ jsx2("path", { d: "M9 18V5l12-2v13" }),
|
|
1067
|
+
/* @__PURE__ */ jsx2("circle", { cx: "6", cy: "18", r: "3" }),
|
|
1068
|
+
/* @__PURE__ */ jsx2("circle", { cx: "18", cy: "16", r: "3" })
|
|
1069
|
+
] });
|
|
1070
|
+
var ICO_VIDEO = /* @__PURE__ */ jsxs2("svg", { "aria-hidden": "true", width: "18", height: "18", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: [
|
|
1071
|
+
/* @__PURE__ */ jsx2("rect", { x: "2", y: "2", width: "20", height: "20", rx: "2" }),
|
|
1072
|
+
/* @__PURE__ */ jsx2("path", { d: "m10 8 6 4-6 4V8z" })
|
|
1073
|
+
] });
|
|
1074
|
+
var ICO_ARCHIVE = /* @__PURE__ */ jsxs2("svg", { "aria-hidden": "true", width: "18", height: "18", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: [
|
|
1075
|
+
/* @__PURE__ */ jsx2("rect", { x: "2", y: "4", width: "20", height: "16", rx: "2" }),
|
|
1076
|
+
/* @__PURE__ */ jsx2("path", { d: "M12 4v16" }),
|
|
1077
|
+
/* @__PURE__ */ jsx2("path", { d: "m10 10 4 4" }),
|
|
1078
|
+
/* @__PURE__ */ jsx2("path", { d: "m14 10-4 4" })
|
|
1079
|
+
] });
|
|
1080
|
+
var ICO_CONFIG = /* @__PURE__ */ jsxs2("svg", { "aria-hidden": "true", width: "18", height: "18", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: [
|
|
1081
|
+
/* @__PURE__ */ jsx2("path", { d: "M14.5 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V7.5L14.5 2z" }),
|
|
1082
|
+
/* @__PURE__ */ jsx2("circle", { cx: "12", cy: "15", r: "2" }),
|
|
1083
|
+
/* @__PURE__ */ jsx2("path", { d: "M12 11v2" })
|
|
1084
|
+
] });
|
|
1085
|
+
var ICO_TEXT = /* @__PURE__ */ jsxs2("svg", { "aria-hidden": "true", width: "18", height: "18", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: [
|
|
1086
|
+
/* @__PURE__ */ jsx2("path", { d: "M14.5 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V7.5L14.5 2z" }),
|
|
1087
|
+
/* @__PURE__ */ jsx2("path", { d: "M8 13h8" }),
|
|
1088
|
+
/* @__PURE__ */ jsx2("path", { d: "M8 17h8" }),
|
|
1089
|
+
/* @__PURE__ */ jsx2("path", { d: "M8 9h3" })
|
|
1090
|
+
] });
|
|
1091
|
+
var ICO_DB = /* @__PURE__ */ jsxs2("svg", { "aria-hidden": "true", width: "18", height: "18", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: [
|
|
1092
|
+
/* @__PURE__ */ jsx2("ellipse", { cx: "12", cy: "5", rx: "9", ry: "3" }),
|
|
1093
|
+
/* @__PURE__ */ jsx2("path", { d: "M3 5v14a9 3 0 0 0 18 0V5" }),
|
|
1094
|
+
/* @__PURE__ */ jsx2("path", { d: "M3 12a9 3 0 0 0 18 0" })
|
|
1095
|
+
] });
|
|
1096
|
+
var ICO_FOLDER = /* @__PURE__ */ jsx2("svg", { "aria-hidden": "true", width: "18", height: "18", viewBox: "0 0 24 24", fill: "currentColor", opacity: "0.85", children: /* @__PURE__ */ jsx2("path", { d: "M20 6h-8l-2-2H4a2 2 0 0 0-2 2v12a2 2 0 0 0 2 2h16a2 2 0 0 0 2-2V8a2 2 0 0 0-2-2z" }) });
|
|
1097
|
+
var ICO_DESIGN = /* @__PURE__ */ jsxs2("svg", { "aria-hidden": "true", width: "18", height: "18", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: [
|
|
1098
|
+
/* @__PURE__ */ jsx2("path", { d: "m12 19 7-7 3 3-7 7-3-3z" }),
|
|
1099
|
+
/* @__PURE__ */ jsx2("path", { d: "m18 13-1.5-7.5L2 2l3.5 14.5L13 18l5-5z" }),
|
|
1100
|
+
/* @__PURE__ */ jsx2("path", { d: "m2 2 7.586 7.586" }),
|
|
1101
|
+
/* @__PURE__ */ jsx2("circle", { cx: "11", cy: "11", r: "2" })
|
|
1102
|
+
] });
|
|
1103
|
+
var EXT_ICON = {};
|
|
1104
|
+
function reg(exts, icon, color) {
|
|
1105
|
+
for (const ext of exts) EXT_ICON[ext] = { icon, color };
|
|
1106
|
+
}
|
|
1107
|
+
reg(["py"], ICO_CODE, "text-[hsl(210,70%,58%)]");
|
|
1108
|
+
reg(["js", "jsx"], ICO_CODE, "text-[hsl(48,90%,50%)]");
|
|
1109
|
+
reg(["ts", "tsx"], ICO_CODE, "text-[hsl(210,80%,55%)]");
|
|
1110
|
+
reg(["go"], ICO_CODE, "text-[hsl(195,70%,50%)]");
|
|
1111
|
+
reg(["rs"], ICO_CODE, "text-[hsl(25,80%,55%)]");
|
|
1112
|
+
reg(["java", "kt"], ICO_CODE, "text-[hsl(20,85%,52%)]");
|
|
1113
|
+
reg(["rb"], ICO_CODE, "text-[hsl(0,70%,55%)]");
|
|
1114
|
+
reg(["c", "cpp", "h", "hpp"], ICO_CODE, "text-[hsl(210,60%,55%)]");
|
|
1115
|
+
reg(["cs"], ICO_CODE, "text-[hsl(265,55%,55%)]");
|
|
1116
|
+
reg(["swift"], ICO_CODE, "text-[hsl(20,90%,55%)]");
|
|
1117
|
+
reg(["html"], ICO_CODE, "text-[hsl(15,85%,55%)]");
|
|
1118
|
+
reg(["css", "scss"], ICO_CODE, "text-[hsl(210,70%,55%)]");
|
|
1119
|
+
reg(["vue"], ICO_CODE, "text-[hsl(153,60%,48%)]");
|
|
1120
|
+
reg(["svelte"], ICO_CODE, "text-[hsl(15,90%,55%)]");
|
|
1121
|
+
reg(["php"], ICO_CODE, "text-[hsl(240,40%,58%)]");
|
|
1122
|
+
reg(["sh", "zsh"], ICO_CODE, "text-[hsl(var(--muted-foreground))]");
|
|
1123
|
+
reg(["sql"], ICO_CODE, "text-[hsl(210,50%,55%)]");
|
|
1124
|
+
reg(["json", "jsonl", "ndjson"], ICO_CONFIG, "text-[hsl(158,55%,48%)]");
|
|
1125
|
+
reg(["yaml", "yml", "toml", "ini", "conf", "env", "lock"], ICO_CONFIG, "text-[hsl(var(--muted-foreground))]");
|
|
1126
|
+
reg(["xml"], ICO_CODE, "text-[hsl(25,65%,52%)]");
|
|
1127
|
+
reg(["db", "sqlite"], ICO_DB, "text-[hsl(210,50%,55%)]");
|
|
1128
|
+
reg(["parquet"], ICO_DB, "text-[hsl(158,50%,45%)]");
|
|
1129
|
+
reg(["doc", "docx", "odt", "rtf", "pages"], ICO_TEXT, "text-[hsl(210,65%,52%)]");
|
|
1130
|
+
reg(["xls", "xlsx", "csv", "tsv", "ods", "numbers"], ICO_TABLE, "text-[hsl(140,55%,42%)]");
|
|
1131
|
+
reg(["ppt", "pptx", "odp", "key"], ICO_SLIDES, "text-[hsl(15,80%,52%)]");
|
|
1132
|
+
reg(["pdf"], ICO_PDF, "text-[hsl(0,65%,50%)]");
|
|
1133
|
+
reg(["md", "markdown", "txt", "log", "tex", "epub"], ICO_TEXT, "text-[hsl(var(--muted-foreground))]");
|
|
1134
|
+
reg(["png", "jpg", "jpeg", "gif", "webp", "bmp", "ico", "heic", "heif", "avif", "tif", "tiff", "svg"], ICO_IMAGE, "text-[hsl(280,55%,58%)]");
|
|
1135
|
+
reg(["psd"], ICO_DESIGN, "text-[hsl(210,60%,55%)]");
|
|
1136
|
+
reg(["ai"], ICO_DESIGN, "text-[hsl(25,85%,52%)]");
|
|
1137
|
+
reg(["fig", "sketch", "xd", "blend"], ICO_DESIGN, "text-[hsl(280,50%,55%)]");
|
|
1138
|
+
reg(["mp3", "wav", "flac", "ogg", "aac", "aiff", "m4a", "mid"], ICO_AUDIO, "text-[hsl(330,60%,55%)]");
|
|
1139
|
+
reg(["mp4", "mov", "mkv", "avi", "webm", "wmv", "flv", "m4v"], ICO_VIDEO, "text-[hsl(340,65%,52%)]");
|
|
1140
|
+
reg(["zip", "tar", "gz", "rar", "7z", "bz2", "xz", "tgz", "dmg", "iso", "pkg"], ICO_ARCHIVE, "text-[hsl(30,50%,48%)]");
|
|
1141
|
+
reg(["ttf", "otf", "woff", "woff2"], ICO_DOC, "text-[hsl(var(--muted-foreground))]");
|
|
1142
|
+
var DEFAULT_ICON = { icon: ICO_DOC, color: "text-[hsl(var(--muted-foreground))]" };
|
|
1143
|
+
var FOLDER_COLOR = "text-[hsl(38,80%,55%)]";
|
|
1003
1144
|
function getFileIcon(fileName) {
|
|
1004
1145
|
const ext = fileName.split(".").pop()?.toLowerCase() ?? "";
|
|
1005
|
-
const
|
|
1006
|
-
return /* @__PURE__ */ jsx2(
|
|
1146
|
+
const entry = EXT_ICON[ext] ?? DEFAULT_ICON;
|
|
1147
|
+
return /* @__PURE__ */ jsx2("span", { className: `flex size-5 shrink-0 items-center justify-center ${entry.color}`, children: entry.icon });
|
|
1007
1148
|
}
|
|
1008
1149
|
function getFolderIcon() {
|
|
1009
|
-
return /* @__PURE__ */ jsx2(
|
|
1010
|
-
}
|
|
1011
|
-
function FileTypeIcon({ src, alt }) {
|
|
1012
|
-
return /* @__PURE__ */ jsx2(
|
|
1013
|
-
"img",
|
|
1014
|
-
{
|
|
1015
|
-
src,
|
|
1016
|
-
alt,
|
|
1017
|
-
className: "size-4 shrink-0 object-contain",
|
|
1018
|
-
draggable: false,
|
|
1019
|
-
loading: "lazy"
|
|
1020
|
-
}
|
|
1021
|
-
);
|
|
1150
|
+
return /* @__PURE__ */ jsx2("span", { className: `flex size-5 shrink-0 items-center justify-center ${FOLDER_COLOR}`, children: ICO_FOLDER });
|
|
1022
1151
|
}
|
|
1023
1152
|
function getErrorMessage(error, fallback) {
|
|
1024
1153
|
if (error instanceof Error && error.message) {
|
|
@@ -1090,16 +1219,25 @@ function WorkspaceFilesPanel({
|
|
|
1090
1219
|
}
|
|
1091
1220
|
}, [activeTab, inlineResources.length]);
|
|
1092
1221
|
const uploadTargetDir = () => {
|
|
1093
|
-
const candidates = Array.from(expandedDirs).filter((path) => path !== ".").filter((path) => {
|
|
1222
|
+
const candidates = Array.from(expandedDirs).filter((path) => path !== ".").filter((path) => path !== rootPath).filter((path) => {
|
|
1094
1223
|
const parts = path.split("/").filter(Boolean);
|
|
1224
|
+
const rootParts = rootPath.split("/").filter(Boolean);
|
|
1225
|
+
const ancestorPrefix = path.startsWith("/") ? "/" : "";
|
|
1226
|
+
if (rootParts.length === 0 && path.startsWith("/")) {
|
|
1227
|
+
return false;
|
|
1228
|
+
}
|
|
1229
|
+
if (rootParts.length > 0 && !rootParts.every((part, index) => parts[index] === part)) {
|
|
1230
|
+
return false;
|
|
1231
|
+
}
|
|
1095
1232
|
for (let index = 1; index < parts.length; index += 1) {
|
|
1096
|
-
const ancestor = parts.slice(0, index).join("/")
|
|
1233
|
+
const ancestor = `${ancestorPrefix}${parts.slice(0, index).join("/")}`;
|
|
1234
|
+
if (rootParts.length > 0 && index < rootParts.length) continue;
|
|
1097
1235
|
if (!expandedDirs.has(ancestor)) return false;
|
|
1098
1236
|
}
|
|
1099
1237
|
return true;
|
|
1100
1238
|
});
|
|
1101
1239
|
if (candidates.length === 0) {
|
|
1102
|
-
return
|
|
1240
|
+
return rootPath;
|
|
1103
1241
|
}
|
|
1104
1242
|
return candidates.reduce((deepestPath, currentPath) => {
|
|
1105
1243
|
const deepestDepth = deepestPath.split("/").filter(Boolean).length;
|