@blade-hq/agent-kit 0.5.30 → 0.5.31

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.
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  getClient
3
- } from "../../chunk-JWHBUVSM.js";
3
+ } from "../../chunk-OPMRX65X.js";
4
4
  import "../../chunk-J3XVFPOV.js";
5
5
  import "../../chunk-ZWO6YBLA.js";
6
6
  import "../../chunk-JCJFFJ42.js";
@@ -16,14 +16,14 @@ import {
16
16
  isErrorMessage,
17
17
  isUserMessage,
18
18
  useWhatIfQuoteContext
19
- } from "../../../chunk-UW55FYRL.js";
19
+ } from "../../../chunk-HFVB57MR.js";
20
20
  import {
21
21
  AskUserQuestionBlock
22
- } from "../../../chunk-S66X23O7.js";
22
+ } from "../../../chunk-BUQRNLEE.js";
23
23
  import "../../../chunk-2UP7MG3J.js";
24
24
  import "../../../chunk-H62LH2AG.js";
25
- import "../../../chunk-XTEHNSFN.js";
26
- import "../../../chunk-JWHBUVSM.js";
25
+ import "../../../chunk-KMQQDKGU.js";
26
+ import "../../../chunk-OPMRX65X.js";
27
27
  import "../../../chunk-J3XVFPOV.js";
28
28
  import "../../../chunk-ZWO6YBLA.js";
29
29
  import "../../../chunk-7LEKQI47.js";
@@ -3,10 +3,10 @@ import {
3
3
  PlanSummaryCard,
4
4
  extractLatestPlanMessages,
5
5
  parsePlanMessages
6
- } from "../../../chunk-S66X23O7.js";
6
+ } from "../../../chunk-BUQRNLEE.js";
7
7
  import "../../../chunk-2UP7MG3J.js";
8
- import "../../../chunk-XTEHNSFN.js";
9
- import "../../../chunk-JWHBUVSM.js";
8
+ import "../../../chunk-KMQQDKGU.js";
9
+ import "../../../chunk-OPMRX65X.js";
10
10
  import "../../../chunk-J3XVFPOV.js";
11
11
  import "../../../chunk-ZWO6YBLA.js";
12
12
  import {
@@ -1,12 +1,12 @@
1
1
  import {
2
2
  useSession
3
- } from "../../../chunk-EP5LVNO3.js";
3
+ } from "../../../chunk-4XBNTPVS.js";
4
4
  import {
5
5
  checkoutSession,
6
6
  getSessionCheckpoints,
7
7
  useChatStore,
8
8
  useSessionStore
9
- } from "../../../chunk-JWHBUVSM.js";
9
+ } from "../../../chunk-OPMRX65X.js";
10
10
  import "../../../chunk-J3XVFPOV.js";
11
11
  import "../../../chunk-ZWO6YBLA.js";
12
12
  import {
@@ -23,6 +23,8 @@ interface WorkspaceFilesPanelProps {
23
23
  title?: string;
24
24
  rootPath?: string;
25
25
  readOnly?: boolean;
26
+ expandedDirs?: Set<string>;
27
+ onExpandedDirsChange?: (dirs: Set<string>) => void;
26
28
  onShareFile?: (path: string, name: string) => Promise<void>;
27
29
  onSync?: () => Promise<void>;
28
30
  allowDelete?: boolean;
@@ -33,7 +35,7 @@ interface WorkspaceFilesPanelProps {
33
35
  listDir?: (sessionId: string, dirPath: string) => Promise<WorkspaceFileEntry[]>;
34
36
  queryKeyScope?: readonly unknown[];
35
37
  }
36
- declare function WorkspaceFilesPanel({ sessionId, enableEditor, className, treeContainerClassName, title, rootPath, readOnly, onShareFile, onSync, allowDelete, topSlot, onOpenFile, listDir, queryKeyScope, }: WorkspaceFilesPanelProps): react_jsx_runtime.JSX.Element;
38
+ declare function WorkspaceFilesPanel({ sessionId, enableEditor, className, treeContainerClassName, title, rootPath, readOnly, expandedDirs: controlledExpandedDirs, onExpandedDirsChange, onShareFile, onSync, allowDelete, topSlot, onOpenFile, listDir, queryKeyScope, }: WorkspaceFilesPanelProps): react_jsx_runtime.JSX.Element;
37
39
 
38
40
  type FileEntry = Awaited<ReturnType<typeof listDir>>[number];
39
41
  type ListDirFn = (sessionId: string, dirPath: string) => Promise<FileEntry[]>;
@@ -41,6 +43,8 @@ interface FileTreeProps {
41
43
  sessionId: string | null;
42
44
  checkActiveSession?: boolean;
43
45
  enableEditor?: boolean;
46
+ expandedDirs?: Set<string>;
47
+ defaultExpandedDirs?: Set<string>;
44
48
  onExpandedDirsChange?: (dirs: Set<string>) => void;
45
49
  rootPath?: string;
46
50
  readOnly?: boolean;
@@ -50,6 +54,6 @@ interface FileTreeProps {
50
54
  listDir?: ListDirFn;
51
55
  queryKeyScope?: readonly unknown[];
52
56
  }
53
- declare function FileTree({ sessionId, checkActiveSession, enableEditor, onExpandedDirsChange, rootPath, readOnly, onShareFile, allowDelete, onOpenFile, listDir, queryKeyScope, }: FileTreeProps): react_jsx_runtime.JSX.Element;
57
+ declare function FileTree({ sessionId, checkActiveSession, enableEditor, expandedDirs: controlledExpandedDirs, defaultExpandedDirs, onExpandedDirsChange, rootPath, readOnly, onShareFile, allowDelete, onOpenFile, listDir, queryKeyScope, }: FileTreeProps): react_jsx_runtime.JSX.Element;
54
58
 
55
59
  export { FileTree, WorkspaceFilesPanel };
@@ -5,7 +5,7 @@ import {
5
5
  } from "../../../chunk-H62LH2AG.js";
6
6
  import {
7
7
  resolveSessionFilePreviewTarget
8
- } from "../../../chunk-XTEHNSFN.js";
8
+ } from "../../../chunk-KMQQDKGU.js";
9
9
  import {
10
10
  apiFetchText,
11
11
  copyFile,
@@ -19,7 +19,7 @@ import {
19
19
  useChatStore,
20
20
  useSessionStore,
21
21
  useUiStore
22
- } from "../../../chunk-JWHBUVSM.js";
22
+ } from "../../../chunk-OPMRX65X.js";
23
23
  import "../../../chunk-J3XVFPOV.js";
24
24
  import "../../../chunk-ZWO6YBLA.js";
25
25
  import {
@@ -31,7 +31,13 @@ import "../../../chunk-PZ5AY32C.js";
31
31
  // src/react/components/workspace/WorkspaceFilesPanel.tsx
32
32
  import { useQueryClient as useQueryClient2 } from "@tanstack/react-query";
33
33
  import { FileText, FolderTree, FolderUp, Loader2 as Loader22, PanelRightOpen, RefreshCw, Upload } from "lucide-react";
34
- import { useEffect as useEffect2, useMemo as useMemo2, useRef as useRef2, useState as useState3 } from "react";
34
+ import {
35
+ useCallback as useCallback2,
36
+ useEffect as useEffect2,
37
+ useMemo as useMemo2,
38
+ useRef as useRef2,
39
+ useState as useState3
40
+ } from "react";
35
41
 
36
42
  // src/react/components/workspace/FileTree.tsx
37
43
  import { useQuery, useQueryClient } from "@tanstack/react-query";
@@ -284,6 +290,8 @@ function FileTree2({
284
290
  sessionId,
285
291
  checkActiveSession = true,
286
292
  enableEditor = false,
293
+ expandedDirs: controlledExpandedDirs,
294
+ defaultExpandedDirs,
287
295
  onExpandedDirsChange,
288
296
  rootPath = ROOT_PATH,
289
297
  readOnly = false,
@@ -294,14 +302,19 @@ function FileTree2({
294
302
  queryKeyScope
295
303
  }) {
296
304
  const pushArtifact = useUiStore((state) => state.pushArtifact);
297
- const [expandedDirs, setExpandedDirs] = useState2(/* @__PURE__ */ new Set([rootPath]));
305
+ const [internalExpandedDirs, setInternalExpandedDirs] = useState2(
306
+ () => new Set(defaultExpandedDirs ?? [rootPath])
307
+ );
308
+ const expandedDirs = controlledExpandedDirs ?? internalExpandedDirs;
298
309
  const [selectedPath, setSelectedPath] = useState2();
299
310
  const [openingFilePath, setOpeningFilePath] = useState2(null);
300
311
  const isStreaming = useChatStore((s) => sessionId ? s.isStreaming[sessionId] ?? false : false);
301
312
  const queryClient = useQueryClient();
302
313
  const prevStreamingRef = useRef(isStreaming);
303
314
  const applyExpandedDirs = useEffectEvent((dirs) => {
304
- setExpandedDirs(dirs);
315
+ if (!controlledExpandedDirs) {
316
+ setInternalExpandedDirs(dirs);
317
+ }
305
318
  onExpandedDirsChange?.(dirs);
306
319
  });
307
320
  useEffect(() => {
@@ -784,15 +797,34 @@ function FileNode({
784
797
  setActiveAction(null);
785
798
  }
786
799
  };
800
+ const openEntry = () => {
801
+ if (isRenaming) return;
802
+ onSelectPath(entry.path);
803
+ void onOpenFile(entry.path, entry.name);
804
+ };
787
805
  return /* @__PURE__ */ jsxs2(
788
806
  "div",
789
807
  {
790
- className: cn(TREE_ROW_CLASS, isSelected && "bg-muted"),
808
+ className: cn(
809
+ TREE_ROW_CLASS,
810
+ "items-center gap-1.5 py-1.5",
811
+ isSelected && "bg-muted"
812
+ ),
791
813
  draggable: !isRenaming,
814
+ role: !isRenaming ? "button" : void 0,
815
+ tabIndex: !isRenaming ? 0 : void 0,
816
+ onClick: openEntry,
792
817
  onDragStart: (e) => {
793
818
  e.dataTransfer.setData("application/blade-file-ref", JSON.stringify({ path: entry.path, name: entry.name }));
794
819
  e.dataTransfer.effectAllowed = "copy";
795
820
  },
821
+ onKeyDown: (event) => {
822
+ if (isRenaming) return;
823
+ if (event.key === "Enter" || event.key === " ") {
824
+ event.preventDefault();
825
+ openEntry();
826
+ }
827
+ },
796
828
  children: [
797
829
  /* @__PURE__ */ jsx2("span", { className: "size-5 shrink-0" }),
798
830
  /* @__PURE__ */ jsx2(FileTreeIcon, { children: getFileIcon(entry.name) }),
@@ -817,22 +849,12 @@ function FileNode({
817
849
  }
818
850
  }
819
851
  }
820
- ) : /* @__PURE__ */ jsxs2(
821
- "button",
822
- {
823
- type: "button",
824
- className: "flex min-w-0 flex-1 cursor-pointer items-center border-none bg-transparent p-0 text-left",
825
- onClick: () => {
826
- onSelectPath(entry.path);
827
- void onOpenFile(entry.path, entry.name);
828
- },
829
- children: [
830
- /* @__PURE__ */ jsx2(FileTreeName, { className: "min-w-0 flex-1", children: entry.name }),
831
- /* @__PURE__ */ jsx2(FileTagList, { tags: entry.tags })
832
- ]
833
- }
834
- ),
835
- 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: [
852
+ ) : /* @__PURE__ */ jsxs2("div", { className: "flex min-w-0 flex-1 items-center text-left", children: [
853
+ /* @__PURE__ */ jsx2(FileTreeName, { className: "min-w-0 flex-1", children: entry.name }),
854
+ /* @__PURE__ */ jsx2(FileTagList, { tags: entry.tags })
855
+ ] }),
856
+ isOpening ? /* @__PURE__ */ jsx2(Loader2, { size: 12, className: "ml-auto shrink-0 animate-spin text-[hsl(var(--muted-foreground))]" }) : null,
857
+ !isOpening && !readOnly ? /* @__PURE__ */ jsxs2(FileTreeActions, { className: "ml-auto hidden shrink-0 group-hover:flex group-focus-within:flex", children: [
836
858
  /* @__PURE__ */ jsx2(
837
859
  TreeActionButton,
838
860
  {
@@ -896,7 +918,7 @@ function FileNode({
896
918
  children: activeAction === "delete" ? /* @__PURE__ */ jsx2(Loader2, { size: 12, className: "animate-spin" }) : /* @__PURE__ */ jsx2(Trash2, { size: 12 })
897
919
  }
898
920
  )
899
- ] }) : allowDelete ? /* @__PURE__ */ jsx2(FileTreeActions, { className: "ml-auto hidden shrink-0 group-hover:flex", children: /* @__PURE__ */ jsx2(
921
+ ] }) : !isOpening && allowDelete ? /* @__PURE__ */ jsx2(FileTreeActions, { className: "ml-auto hidden shrink-0 group-hover:flex group-focus-within:flex", children: /* @__PURE__ */ jsx2(
900
922
  TreeActionButton,
901
923
  {
902
924
  disabled: activeAction !== null,
@@ -1031,7 +1053,12 @@ function TreeActionButton({
1031
1053
  {
1032
1054
  type: "button",
1033
1055
  disabled,
1034
- onClick,
1056
+ onPointerDown: (event) => event.stopPropagation(),
1057
+ onKeyDown: (event) => event.stopPropagation(),
1058
+ onClick: (event) => {
1059
+ event.stopPropagation();
1060
+ onClick();
1061
+ },
1035
1062
  title,
1036
1063
  className: "flex items-center rounded p-1 text-[hsl(var(--muted-foreground))] transition-colors hover:bg-[hsl(var(--muted-foreground))/10] hover:text-[hsl(var(--foreground))] disabled:cursor-not-allowed disabled:opacity-50",
1037
1064
  children
@@ -1181,6 +1208,8 @@ function WorkspaceFilesPanel({
1181
1208
  title = "\u5DE5\u4F5C\u533A",
1182
1209
  rootPath = ".",
1183
1210
  readOnly = false,
1211
+ expandedDirs: controlledExpandedDirs,
1212
+ onExpandedDirsChange,
1184
1213
  onShareFile,
1185
1214
  onSync,
1186
1215
  allowDelete = false,
@@ -1189,7 +1218,8 @@ function WorkspaceFilesPanel({
1189
1218
  listDir: listDir2,
1190
1219
  queryKeyScope
1191
1220
  }) {
1192
- const [expandedDirs, setExpandedDirs] = useState3(/* @__PURE__ */ new Set());
1221
+ const [internalExpandedDirs, setInternalExpandedDirs] = useState3(/* @__PURE__ */ new Set([rootPath]));
1222
+ const expandedDirs = controlledExpandedDirs ?? internalExpandedDirs;
1193
1223
  const [isUploading, setIsUploading] = useState3(false);
1194
1224
  const [uploadProgress, setUploadProgress] = useState3(null);
1195
1225
  const [uploadFileCount, setUploadFileCount] = useState3(0);
@@ -1202,6 +1232,15 @@ function WorkspaceFilesPanel({
1202
1232
  (state) => sessionId ? state.messages[sessionId] ?? EMPTY_MESSAGES : EMPTY_MESSAGES
1203
1233
  );
1204
1234
  const pushArtifact = useUiStore((state) => state.pushArtifact);
1235
+ const updateExpandedDirs = useCallback2(
1236
+ (dirs) => {
1237
+ if (!controlledExpandedDirs) {
1238
+ setInternalExpandedDirs(dirs);
1239
+ }
1240
+ onExpandedDirsChange?.(dirs);
1241
+ },
1242
+ [controlledExpandedDirs, onExpandedDirsChange]
1243
+ );
1205
1244
  const inlineResources = useMemo2(() => {
1206
1245
  if (!sessionId) return [];
1207
1246
  return messages.flatMap(
@@ -1290,11 +1329,9 @@ function WorkspaceFilesPanel({
1290
1329
  type: "active"
1291
1330
  });
1292
1331
  if (targetDir !== ".") {
1293
- setExpandedDirs((prev) => {
1294
- const next = new Set(prev);
1295
- next.add(targetDir);
1296
- return next;
1297
- });
1332
+ const next = new Set(expandedDirs);
1333
+ next.add(targetDir);
1334
+ updateExpandedDirs(next);
1298
1335
  }
1299
1336
  if (result.failed.length > 0) {
1300
1337
  alert(`\u90E8\u5206\u6587\u4EF6\u4E0A\u4F20\u5931\u8D25: ${result.failed.join(", ")}`);
@@ -1433,7 +1470,8 @@ function WorkspaceFilesPanel({
1433
1470
  {
1434
1471
  sessionId,
1435
1472
  enableEditor,
1436
- onExpandedDirsChange: setExpandedDirs,
1473
+ expandedDirs,
1474
+ onExpandedDirsChange: updateExpandedDirs,
1437
1475
  rootPath,
1438
1476
  readOnly,
1439
1477
  onShareFile,