@blade-hq/agent-kit 0.5.14 → 0.5.17

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.
Files changed (30) hide show
  1. package/dist/{SkillStatusBar-OXJL7P7N.d.ts → SkillStatusBar-DR-R6Mpa.d.ts} +3 -1
  2. package/dist/{chunk-E2N6KY4N.js → chunk-GIY3MV6F.js} +2 -2
  3. package/dist/{chunk-HBC6FK3D.js → chunk-MEAVJOEQ.js} +2 -2
  4. package/dist/{chunk-6M5XXG3W.js → chunk-RQUD3FGD.js} +170 -30
  5. package/dist/chunk-RQUD3FGD.js.map +1 -0
  6. package/dist/{chunk-SZSTLXEP.js → chunk-SPHQXYME.js} +89 -137
  7. package/dist/chunk-SPHQXYME.js.map +1 -0
  8. package/dist/{chunk-7I7AMUCI.js → chunk-SZKVEYL6.js} +2 -2
  9. package/dist/chunk-SZKVEYL6.js.map +1 -0
  10. package/dist/{chunk-RA4Q3QSE.js → chunk-XKP32HXH.js} +15 -91
  11. package/dist/chunk-XKP32HXH.js.map +1 -0
  12. package/dist/client/index.d.ts +332 -0
  13. package/dist/client/index.js +1 -1
  14. package/dist/react/api/vibe-coding.js +2 -2
  15. package/dist/react/components/chat/index.d.ts +2 -2
  16. package/dist/react/components/chat/index.js +5 -5
  17. package/dist/react/components/plan/index.d.ts +2 -3
  18. package/dist/react/components/plan/index.js +3 -3
  19. package/dist/react/components/session/index.js +3 -3
  20. package/dist/react/components/workspace/index.js +3 -3
  21. package/dist/react/index.d.ts +8 -2
  22. package/dist/react/index.js +6 -6
  23. package/dist/style.css +1 -1
  24. package/package.json +1 -1
  25. package/dist/chunk-6M5XXG3W.js.map +0 -1
  26. package/dist/chunk-7I7AMUCI.js.map +0 -1
  27. package/dist/chunk-RA4Q3QSE.js.map +0 -1
  28. package/dist/chunk-SZSTLXEP.js.map +0 -1
  29. /package/dist/{chunk-E2N6KY4N.js.map → chunk-GIY3MV6F.js.map} +0 -0
  30. /package/dist/{chunk-HBC6FK3D.js.map → chunk-MEAVJOEQ.js.map} +0 -0
@@ -3,7 +3,7 @@ import {
3
3
  } from "./chunk-J3XVFPOV.js";
4
4
  import {
5
5
  BladeClient
6
- } from "./chunk-7I7AMUCI.js";
6
+ } from "./chunk-SZKVEYL6.js";
7
7
  import {
8
8
  createClientActions,
9
9
  useCardStateStore
@@ -693,15 +693,11 @@ var TOOL_NAME_ALIASES = {
693
693
  file_read: "Read",
694
694
  file_write: "Write",
695
695
  finish_task: "FinishTask",
696
- get_skill_content: "GetSkillContent",
697
696
  glob: "Glob",
698
697
  grep: "Grep",
699
- list_skill_tools: "ListSkillTools",
700
- load_skill_tools: "LoadSkillTools",
701
698
  ls: "Ls",
702
699
  read: "Read",
703
- run_skill_tool: "RunSkillTool",
704
- search_skills: "SearchSkills",
700
+ read_skill: "ReadSkill",
705
701
  web_fetch: "WebFetch",
706
702
  web_search: "WebSearch",
707
703
  write: "Write"
@@ -719,11 +715,7 @@ var TOOL_DISPLAY_LABELS = {
719
715
  WebFetch: "\u6574\u7406\u7F51\u9875\u5185\u5BB9",
720
716
  Agent: "\u6D3E\u751F\u5B50\u667A\u80FD\u4F53",
721
717
  AskUserQuestion: "\u5411\u7528\u6237\u63D0\u95EE",
722
- SearchSkills: "\u641C\u7D22\u6280\u80FD",
723
- GetSkillContent: "\u8BFB\u53D6\u6280\u80FD",
724
- ListSkillTools: "\u67E5\u770B\u5DE5\u5177\u5217\u8868",
725
- LoadSkillTools: "\u52A0\u8F7D\u6280\u80FD",
726
- RunSkillTool: "\u6267\u884C\u6280\u80FD\u5DE5\u5177",
718
+ ReadSkill: "\u8BFB\u53D6\u6280\u80FD",
727
719
  FinishTask: "\u4EFB\u52A1\u5B8C\u6210",
728
720
  ExitPlanMode: "\u63D0\u4EA4\u8BA1\u5212",
729
721
  ListSessions: "\u5217\u51FA\u5386\u53F2\u4F1A\u8BDD",
@@ -743,7 +735,6 @@ var PRIORITY_FILE_KEYS = [
743
735
  "destination",
744
736
  "filename"
745
737
  ];
746
- var FILE_PATH_PATTERN = /(?:^|[\s"'`::])([^\s"'`,;:)\]},。;、]+?\.[a-z0-9]{1,8})(?=$|[\s"'`,.;:)\]},。;、])/i;
747
738
  function safeParseJson(value) {
748
739
  if (!value) return null;
749
740
  try {
@@ -759,18 +750,6 @@ function getStringArgValue(args, key) {
759
750
  const value = args?.[key];
760
751
  return typeof value === "string" ? value.trim() : "";
761
752
  }
762
- var GENERIC_DISPLAY_NAMES = new Set(Object.values(TOOL_DISPLAY_LABELS));
763
- function getRunSkillDisplayName(toolCall, args) {
764
- const argDisplayName = getStringArgValue(args, "display_name");
765
- if (argDisplayName) return argDisplayName;
766
- const displayName = toolCall.display_name?.trim() ?? "";
767
- if (displayName && (displayName === "\u5199\u5165\u6587\u4EF6" || !GENERIC_DISPLAY_NAMES.has(displayName))) {
768
- return displayName;
769
- }
770
- const argToolName = getStringArgValue(args, "tool_name");
771
- if (argToolName) return argToolName;
772
- return "";
773
- }
774
753
  function getCommandDescription(args) {
775
754
  return getStringArgValue(args, "description");
776
755
  }
@@ -803,44 +782,6 @@ function findFileLikeValue(value, depth = 0, allowPlainString = false) {
803
782
  }
804
783
  return null;
805
784
  }
806
- function extractFilePathFromText(text) {
807
- return text.match(FILE_PATH_PATTERN)?.[1] ?? null;
808
- }
809
- function extractFilePathFromResult(result) {
810
- if (typeof result === "string") {
811
- const parsed = safeParseJson(result);
812
- if (parsed != null && parsed !== result) {
813
- const found = extractFilePathFromResult(parsed);
814
- if (found) return found;
815
- }
816
- return extractFilePathFromText(result);
817
- }
818
- if (Array.isArray(result)) {
819
- for (const item of result) {
820
- const found = extractFilePathFromResult(item);
821
- if (found) return found;
822
- }
823
- return null;
824
- }
825
- if (isPlainObject(result)) {
826
- for (const key of PRIORITY_FILE_KEYS) {
827
- const direct = findFileLikeValue(result[key], 0, true);
828
- if (direct) return direct;
829
- }
830
- for (const nested of Object.values(result)) {
831
- const found = extractFilePathFromResult(nested);
832
- if (found) return found;
833
- }
834
- }
835
- return null;
836
- }
837
- function isWriteLikeRunSkillTool(label, args) {
838
- const normalizedLabel = label.trim();
839
- if (normalizedLabel === "\u5199\u5165\u6587\u4EF6" || /write/i.test(normalizedLabel)) return true;
840
- const toolName = getStringArgValue(args, "tool_name");
841
- if (/write/i.test(toolName)) return true;
842
- return false;
843
- }
844
785
  function formatFileName(filePath) {
845
786
  return filePath.split("/").pop() ?? filePath;
846
787
  }
@@ -864,70 +805,15 @@ function getToolDisplayLabel(toolCall) {
864
805
  if (metaDisplayName) {
865
806
  return metaDisplayName;
866
807
  }
867
- switch (normalized) {
868
- case "RunSkillTool": {
869
- const runSkillDisplayName = getRunSkillDisplayName(toolCall, args);
870
- if (runSkillDisplayName) {
871
- const filePath = extractToolFilePath(toolCall);
872
- if (filePath && isWriteLikeRunSkillTool(runSkillDisplayName, args)) {
873
- return `${runSkillDisplayName}\u300C${formatFileName(filePath)}\u300D`;
874
- }
875
- return runSkillDisplayName;
876
- }
877
- return "\u6267\u884C\u6280\u80FD\u5DE5\u5177";
878
- }
879
- case "Bash": {
880
- const description = getCommandDescription(args);
881
- return description || "\u6267\u884C\u547D\u4EE4\u884C\u64CD\u4F5C";
882
- }
883
- case "BgBash": {
884
- const description = getCommandDescription(args);
885
- return description ? `\u540E\u53F0\u6267\u884C\uFF1A${description}` : "\u540E\u53F0\u6267\u884C\u547D\u4EE4";
886
- }
887
- case "Read":
888
- case "Write":
889
- case "Edit": {
890
- const description = getCommandDescription(args);
891
- return description || baseLabel;
892
- }
893
- case "Ls": {
894
- const path = args && typeof args.path === "string" ? args.path : "";
895
- return path ? `${baseLabel}\u300C${path}\u300D` : baseLabel;
896
- }
897
- case "Glob": {
898
- const pattern = args && typeof args.pattern === "string" ? args.pattern : "";
899
- return pattern ? `${baseLabel}\u300C${pattern}\u300D` : baseLabel;
900
- }
901
- case "Grep": {
902
- const pattern = args && typeof args.pattern === "string" ? args.pattern : "";
903
- return pattern ? `${baseLabel}\u300C${pattern}\u300D` : baseLabel;
904
- }
905
- case "WebSearch":
906
- case "WebFetch": {
907
- const query = args && typeof args.query === "string" ? args.query : "";
908
- return query ? `${baseLabel}\u300C${query}\u300D` : baseLabel;
909
- }
910
- case "GetSkillContent": {
911
- const skillName = args && typeof args.skill_id === "string" ? args.skill_id : args && typeof args.skill_name === "string" ? args.skill_name : "";
912
- return skillName ? `${baseLabel}\u300C${skillName}\u300D` : baseLabel;
913
- }
914
- case "SearchSkills": {
915
- const query = args && typeof args.query === "string" ? args.query : "";
916
- return query ? `${baseLabel}\u300C${query}\u300D` : baseLabel;
917
- }
918
- case "ListSkillTools": {
919
- const skillId = args && typeof args.skill_id === "string" ? args.skill_id : "";
920
- return skillId ? `${baseLabel}\u300C${skillId}\u300D` : baseLabel;
921
- }
922
- case "LoadSkillTools":
923
- return "\u52A0\u8F7D\u6280\u80FD";
924
- case "FinishTask": {
925
- const title = args && typeof args.title === "string" ? args.title : "";
926
- return title ? `${baseLabel}\uFF1A${title}` : baseLabel;
927
- }
928
- default:
929
- return baseLabel;
808
+ const description = getCommandDescription(args);
809
+ if (normalized === "BgBash") {
810
+ return description ? `\u540E\u53F0\u6267\u884C\uFF1A${description}` : "\u540E\u53F0\u6267\u884C\u547D\u4EE4";
811
+ }
812
+ if (normalized === "FinishTask") {
813
+ const title = args && typeof args.title === "string" ? args.title : "";
814
+ return title ? `${baseLabel}\uFF1A${title}` : baseLabel;
930
815
  }
816
+ return description || baseLabel;
931
817
  }
932
818
  function getToolTone(status) {
933
819
  if (status === "error" || status === "cancelled") return "red";
@@ -948,8 +834,6 @@ function extractToolFilePath(toolCall) {
948
834
  let filePath = null;
949
835
  if (formattedName === "Read" || formattedName === "Write" || formattedName === "Edit") {
950
836
  filePath = findFileLikeValue(argsValue);
951
- } else if (formattedName === "RunSkillTool") {
952
- filePath = findFileLikeValue(argsValue) ?? extractFilePathFromResult(toolCall.result);
953
837
  }
954
838
  if (!filePath || isInternalStatusFile(filePath)) return null;
955
839
  return filePath;
@@ -1607,13 +1491,14 @@ function extractAskAnswers(turns) {
1607
1491
  }
1608
1492
  return answers;
1609
1493
  }
1610
- function registerCreatedSessionState(set, session, mode = DEFAULT_SESSION_MODE) {
1494
+ function registerCreatedSessionState(set, session, mode = DEFAULT_SESSION_MODE, options = {}) {
1495
+ const fresh = options.fresh ?? true;
1611
1496
  useChatStore.getState().setTurns(session.id, []);
1612
1497
  useTaskStore.getState().setTasks(session.id, []);
1613
1498
  set((state) => ({
1614
1499
  sessions: [session, ...state.sessions.filter((item) => item.id !== session.id)],
1615
1500
  modes: { ...state.modes, [session.id]: state.modes[session.id] ?? mode },
1616
- _freshSessions: new Set(state._freshSessions).add(session.id)
1501
+ _freshSessions: fresh ? new Set(state._freshSessions).add(session.id) : new Set([...state._freshSessions].filter((id) => id !== session.id))
1617
1502
  }));
1618
1503
  }
1619
1504
  async function revalidateViewerSessions(existingSessions) {
@@ -1715,8 +1600,8 @@ var useSessionStore = create5()((set, get) => ({
1715
1600
  });
1716
1601
  return session_id;
1717
1602
  },
1718
- registerCreatedSession: (session, mode = DEFAULT_SESSION_MODE) => {
1719
- registerCreatedSessionState(set, session, mode);
1603
+ registerCreatedSession: (session, mode = DEFAULT_SESSION_MODE, options = {}) => {
1604
+ registerCreatedSessionState(set, session, mode, options);
1720
1605
  },
1721
1606
  upsertSession: (session) => {
1722
1607
  set((state) => ({
@@ -2386,6 +2271,9 @@ var AgentSocket = class {
2386
2271
  pendingReplayModes = /* @__PURE__ */ new Map();
2387
2272
  oomNotifiedKeys = /* @__PURE__ */ new Set();
2388
2273
  pendingTurnPatches = /* @__PURE__ */ new Map();
2274
+ joinedSessions = /* @__PURE__ */ new Set();
2275
+ requestedJoins = /* @__PURE__ */ new Set();
2276
+ pendingJoins = /* @__PURE__ */ new Map();
2389
2277
  patchFlushHandle = null;
2390
2278
  patchFlushCancel = null;
2391
2279
  _ensureConnected() {
@@ -2508,6 +2396,7 @@ var AgentSocket = class {
2508
2396
  }
2509
2397
  useChatStore.getState().setStreaming(sessionId, false);
2510
2398
  invalidateContextStats(sessionId);
2399
+ void this._syncSessionTurnsFromHistory(sessionId);
2511
2400
  useRuntimeStore.getState().addEvent(sessionId, {
2512
2401
  type: "chat:end",
2513
2402
  title: status === "paused" ? "Waiting for input" : status === "interrupted" ? "\u8FD0\u884C\u5DF2\u4E2D\u65AD" : status === "failed" ? "Run failed" : "Run completed",
@@ -2694,10 +2583,13 @@ var AgentSocket = class {
2694
2583
  this.socket.on("connect", () => {
2695
2584
  useConnectionStore.getState().markConnected();
2696
2585
  console.log("[agent-socket] connected, id:", this.socket.id);
2586
+ this.joinedSessions.clear();
2587
+ this.requestedJoins.clear();
2588
+ this.pendingJoins.clear();
2697
2589
  const sessionId = this.subscribedSession;
2698
2590
  if (sessionId) {
2699
2591
  useSessionStore.getState().setActiveSession(sessionId);
2700
- this.socket.emit("session:subscribe", { session_id: sessionId });
2592
+ void this._ensureJoined(sessionId);
2701
2593
  }
2702
2594
  });
2703
2595
  this.socket.on("connect_error", (err) => {
@@ -2803,6 +2695,14 @@ var AgentSocket = class {
2803
2695
  detail: OOM_MESSAGE
2804
2696
  });
2805
2697
  }
2698
+ async _syncSessionTurnsFromHistory(sessionId) {
2699
+ try {
2700
+ const turns = await this.client.sessions.getSessionTurns(sessionId);
2701
+ if (turns.length === 0) return;
2702
+ useChatStore.getState().setTurns(sessionId, turns);
2703
+ } catch {
2704
+ }
2705
+ }
2806
2706
  _applySystemNotification(sessionId, loopId, notification) {
2807
2707
  const notificationType = notification.notification_type ?? "system_notification";
2808
2708
  const title = notification.title ?? notificationType;
@@ -2844,7 +2744,7 @@ var AgentSocket = class {
2844
2744
  useUiStore.getState().clearArtifacts();
2845
2745
  useCardStateStore.getState().clearAllStates();
2846
2746
  }
2847
- this.socket.emit("session:subscribe", { session_id: sessionId });
2747
+ void this._ensureJoined(sessionId);
2848
2748
  }
2849
2749
  unsubscribe() {
2850
2750
  const previousSessionId = this.subscribedSession;
@@ -2852,6 +2752,9 @@ var AgentSocket = class {
2852
2752
  this.socket.emit("session:unsubscribe", { session_id: previousSessionId });
2853
2753
  useUiBridgeStore.getState().clearSession(previousSessionId);
2854
2754
  this.subscribedSession = null;
2755
+ this.requestedJoins.delete(previousSessionId);
2756
+ this.joinedSessions.delete(previousSessionId);
2757
+ this.pendingJoins.delete(previousSessionId);
2855
2758
  }
2856
2759
  this.previewArtifactsByToolCall.clear();
2857
2760
  }
@@ -2865,7 +2768,44 @@ var AgentSocket = class {
2865
2768
  * 幂等:后端 session:subscribe handler 只做 enter_room,重复 emit 无副作用。
2866
2769
  */
2867
2770
  attachSession(sessionId) {
2868
- this.socket.emit("session:subscribe", { session_id: sessionId });
2771
+ void this._ensureJoined(sessionId);
2772
+ }
2773
+ _ensureJoined(sessionId) {
2774
+ if (this.joinedSessions.has(sessionId)) {
2775
+ return Promise.resolve();
2776
+ }
2777
+ this.requestedJoins.add(sessionId);
2778
+ const pending = this.pendingJoins.get(sessionId);
2779
+ if (pending) {
2780
+ return pending;
2781
+ }
2782
+ const join = new Promise((resolve, reject) => {
2783
+ this.socket.timeout(5e3).emit(
2784
+ "session:subscribe",
2785
+ { session_id: sessionId },
2786
+ (err, response) => {
2787
+ if (err) {
2788
+ reject(err);
2789
+ return;
2790
+ }
2791
+ if (response && response.ok === false) {
2792
+ reject(new Error(response.message || "Session subscription failed"));
2793
+ return;
2794
+ }
2795
+ if (this.requestedJoins.has(sessionId)) {
2796
+ this.joinedSessions.add(sessionId);
2797
+ }
2798
+ resolve();
2799
+ }
2800
+ );
2801
+ }).finally(() => {
2802
+ this.pendingJoins.delete(sessionId);
2803
+ });
2804
+ this.pendingJoins.set(sessionId, join);
2805
+ return join;
2806
+ }
2807
+ _shouldWaitForJoinBeforeSend(sessionId) {
2808
+ return this.subscribedSession === sessionId || this.joinedSessions.has(sessionId) || this.pendingJoins.has(sessionId) || this.requestedJoins.has(sessionId);
2869
2809
  }
2870
2810
  send(sessionId, message, mode, askuserAnswer, extras) {
2871
2811
  this._ensureConnected();
@@ -2897,7 +2837,7 @@ var AgentSocket = class {
2897
2837
  this.pendingReplayMessages.set(sessionId, message);
2898
2838
  this.pendingReplayModes.set(sessionId, mode);
2899
2839
  }
2900
- this.socket.emit("chat:send", {
2840
+ const payload = {
2901
2841
  session_id: sessionId,
2902
2842
  message,
2903
2843
  mode,
@@ -2905,7 +2845,19 @@ var AgentSocket = class {
2905
2845
  model: extras?.model,
2906
2846
  whatif: extras?.whatif,
2907
2847
  replay_decision: extras?.replay_decision
2908
- });
2848
+ };
2849
+ const sendPayload = () => {
2850
+ this.socket.emit("chat:send", payload);
2851
+ };
2852
+ if (this._shouldWaitForJoinBeforeSend(sessionId)) {
2853
+ void this._ensureJoined(sessionId).then(sendPayload).catch((error) => {
2854
+ useChatStore.getState().setStreaming(sessionId, false);
2855
+ useSessionStore.getState().updateSessionStatus(sessionId, "failed");
2856
+ useChatStore.getState().addErrorMessage(sessionId, error.message || "\u4F1A\u8BDD\u8BA2\u9605\u5931\u8D25\uFF0C\u6D88\u606F\u672A\u53D1\u9001");
2857
+ });
2858
+ } else {
2859
+ sendPayload();
2860
+ }
2909
2861
  const skillId = extractSkillIdForAnalytics(message);
2910
2862
  trackEvent("message_sent", {
2911
2863
  session_id: sessionId,
@@ -3189,4 +3141,4 @@ export {
3189
3141
  bootstrapBladeClient,
3190
3142
  getBootstrappedClient
3191
3143
  };
3192
- //# sourceMappingURL=chunk-SZSTLXEP.js.map
3144
+ //# sourceMappingURL=chunk-SPHQXYME.js.map