assistant-ui 0.0.121 → 0.0.122

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 (55) hide show
  1. package/dist/commands/add.d.ts.map +1 -1
  2. package/dist/commands/add.js +1 -2
  3. package/dist/commands/add.js.map +1 -1
  4. package/dist/commands/create.d.ts.map +1 -1
  5. package/dist/commands/create.js +2 -2
  6. package/dist/commands/create.js.map +1 -1
  7. package/dist/commands/info.js +1 -1
  8. package/dist/commands/init.d.ts.map +1 -1
  9. package/dist/commands/init.js +1 -2
  10. package/dist/commands/init.js.map +1 -1
  11. package/dist/commands/mcp.d.ts.map +1 -1
  12. package/dist/commands/mcp.js +95 -23
  13. package/dist/commands/mcp.js.map +1 -1
  14. package/dist/lib/agent-skill.d.ts.map +1 -1
  15. package/dist/lib/agent-skill.js +9 -27
  16. package/dist/lib/agent-skill.js.map +1 -1
  17. package/dist/lib/create-project.d.ts +0 -9
  18. package/dist/lib/create-project.d.ts.map +1 -1
  19. package/dist/lib/create-project.js +15 -46
  20. package/dist/lib/create-project.js.map +1 -1
  21. package/dist/lib/transform.d.ts +0 -4
  22. package/dist/lib/transform.d.ts.map +1 -1
  23. package/dist/lib/transform.js +7 -16
  24. package/dist/lib/transform.js.map +1 -1
  25. package/dist/lib/utils/download.d.ts +5 -0
  26. package/dist/lib/utils/download.d.ts.map +1 -0
  27. package/dist/lib/utils/download.js +41 -0
  28. package/dist/lib/utils/download.js.map +1 -0
  29. package/dist/lib/utils/file-scanner.d.ts +0 -1
  30. package/dist/lib/utils/file-scanner.d.ts.map +1 -1
  31. package/dist/lib/utils/file-scanner.js +1 -16
  32. package/dist/lib/utils/file-scanner.js.map +1 -1
  33. package/dist/lib/utils/package-manager.d.ts +7 -0
  34. package/dist/lib/utils/package-manager.d.ts.map +1 -1
  35. package/dist/lib/utils/package-manager.js +15 -1
  36. package/dist/lib/utils/package-manager.js.map +1 -1
  37. package/package.json +3 -3
  38. package/src/commands/add.ts +2 -1
  39. package/src/commands/create.ts +5 -3
  40. package/src/commands/init.ts +5 -2
  41. package/src/commands/mcp.ts +223 -56
  42. package/src/lib/agent-skill.ts +17 -43
  43. package/src/lib/create-project.test.ts +0 -17
  44. package/src/lib/create-project.ts +33 -98
  45. package/src/lib/transform-files.test.ts +1 -3
  46. package/src/lib/transform.ts +6 -20
  47. package/src/lib/utils/download.ts +57 -0
  48. package/src/lib/utils/file-scanner.ts +0 -26
  49. package/src/lib/utils/package-manager.ts +26 -0
  50. package/src/lib/utils/registry.test.ts +0 -6
  51. package/templates/cloud-harness/app/api/chat/route.ts +1 -0
  52. package/templates/cloud-harness/components/assistant-ui/elements/collapsible-root.tsx +19 -0
  53. package/templates/cloud-harness/components/assistant-ui/elements/markdown-text.tsx +1 -1
  54. package/templates/cloud-harness/components/assistant-ui/elements/tool-fallback.aui.tsx +198 -30
  55. package/templates/cloud-harness/package.json +12 -12
@@ -1,6 +1,14 @@
1
1
  "use client";
2
2
 
3
- import { memo, useCallback, useRef, useState } from "react";
3
+ import {
4
+ forwardRef,
5
+ memo,
6
+ useCallback,
7
+ useImperativeHandle,
8
+ useLayoutEffect,
9
+ useRef,
10
+ useState,
11
+ } from "react";
4
12
  import {
5
13
  AlertCircleIcon,
6
14
  CheckIcon,
@@ -22,12 +30,12 @@ import {
22
30
  type ToolCallMessagePartStatus,
23
31
  type ToolCallMessagePartComponent,
24
32
  } from "@assistant-ui/react";
33
+ import { cn } from "@/lib/utils";
25
34
  import {
26
- Collapsible,
35
+ CollapsibleRoot as Collapsible,
27
36
  CollapsibleContent,
28
37
  CollapsibleTrigger,
29
- } from "@/components/ui/collapsible";
30
- import { cn } from "@/lib/utils";
38
+ } from "./collapsible-root";
31
39
  import { Button } from "@/components/ui/button";
32
40
  import { Textarea } from "@/components/ui/textarea";
33
41
 
@@ -158,7 +166,7 @@ function ToolFallbackTrigger({
158
166
  <CollapsibleTrigger
159
167
  data-slot="tool-fallback-trigger"
160
168
  className={cn(
161
- "aui-tool-fallback-trigger group/trigger text-muted-foreground hover:text-foreground flex w-fit origin-left items-center gap-2 py-1.5 text-sm transition-[color,scale] active:scale-[0.98]",
169
+ "aui-tool-fallback-trigger group/trigger text-muted-foreground hover:text-foreground flex w-fit max-w-full origin-left items-center gap-2 py-1.5 text-sm transition-[color,scale] active:scale-[0.98]",
162
170
  className,
163
171
  )}
164
172
  {...props}
@@ -174,7 +182,7 @@ function ToolFallbackTrigger({
174
182
  <span
175
183
  data-slot="tool-fallback-trigger-label"
176
184
  className={cn(
177
- "aui-tool-fallback-trigger-label-wrapper inline-block text-start leading-none",
185
+ "aui-tool-fallback-trigger-label-wrapper inline-block min-w-0 text-start leading-none wrap-anywhere",
178
186
  isCancelled && "text-muted-foreground line-through",
179
187
  isRunning && "shimmer motion-reduce:animate-none",
180
188
  )}
@@ -245,7 +253,7 @@ function ToolFallbackArgs({
245
253
  className={cn("aui-tool-fallback-args", className)}
246
254
  {...props}
247
255
  >
248
- <pre className="aui-tool-fallback-args-value bg-muted/50 text-foreground/90 rounded-md p-2.5 text-xs whitespace-pre-wrap">
256
+ <pre className="aui-tool-fallback-args-value bg-muted/50 text-foreground/90 rounded-md p-2.5 text-xs break-words whitespace-pre-wrap">
249
257
  {argsText}
250
258
  </pre>
251
259
  </div>
@@ -287,7 +295,7 @@ function ToolFallbackResult({
287
295
  <p className="aui-tool-fallback-result-header text-muted-foreground text-xs font-medium">
288
296
  Result:
289
297
  </p>
290
- <pre className="aui-tool-fallback-result-content bg-muted/50 text-foreground/90 mt-1 rounded-md p-2.5 text-xs whitespace-pre-wrap">
298
+ <pre className="aui-tool-fallback-result-content bg-muted/50 text-foreground/90 mt-1 rounded-md p-2.5 text-xs break-words whitespace-pre-wrap">
291
299
  {formatUnknownValue(result, 2)}
292
300
  </pre>
293
301
  </div>
@@ -321,7 +329,7 @@ function ToolFallbackError({
321
329
  <p className="aui-tool-fallback-error-header text-muted-foreground font-semibold">
322
330
  {headerText}
323
331
  </p>
324
- <p className="aui-tool-fallback-error-reason text-muted-foreground whitespace-pre-line">
332
+ <p className="aui-tool-fallback-error-reason text-muted-foreground break-words whitespace-pre-line">
325
333
  {errorText}
326
334
  </p>
327
335
  </div>
@@ -436,10 +444,20 @@ const receiptIcons = {
436
444
  function ToolFallbackApprovalReceipt({
437
445
  approval,
438
446
  className,
447
+ focusReceiptRef,
448
+ receiptRef,
439
449
  ...props
440
- }: React.ComponentProps<"div"> & {
450
+ }: React.ComponentPropsWithoutRef<"div"> & {
441
451
  approval: NonNullable<ToolCallMessagePart["approval"]>;
452
+ focusReceiptRef: React.MutableRefObject<string | null | undefined>;
453
+ receiptRef: React.MutableRefObject<HTMLDivElement | null>;
442
454
  }) {
455
+ useLayoutEffect(() => {
456
+ const shouldFocus = focusReceiptRef.current === approval.id;
457
+ focusReceiptRef.current = null;
458
+ if (shouldFocus) receiptRef.current?.focus({ preventScroll: true });
459
+ }, [approval.id, focusReceiptRef, receiptRef]);
460
+
443
461
  const receipt = approvalReceipt(approval);
444
462
  const Icon = receiptIcons[receipt.outcome];
445
463
  const notes = [
@@ -452,8 +470,10 @@ function ToolFallbackApprovalReceipt({
452
470
 
453
471
  return (
454
472
  <div
473
+ ref={receiptRef}
455
474
  data-slot="tool-fallback-approval-receipt"
456
475
  data-outcome={receipt.outcome}
476
+ tabIndex={-1}
457
477
  className={cn(
458
478
  "aui-tool-fallback-approval-receipt flex flex-col gap-1.5 pt-1",
459
479
  className,
@@ -675,14 +695,36 @@ const offersInterruptAction = (
675
695
  approval != null ||
676
696
  interrupt != null;
677
697
 
678
- function ToolFallbackApproval(
679
- props: React.ComponentProps<typeof ToolFallbackApprovalImpl>,
680
- ) {
681
- return <ToolFallbackApprovalImpl key={props.approval?.id} {...props} />;
682
- }
698
+ type ToolFallbackApprovalProps = React.ComponentPropsWithoutRef<"div"> &
699
+ Partial<
700
+ Pick<
701
+ ToolCallMessagePartProps,
702
+ "addResult" | "resume" | "respondToApproval" | "status"
703
+ >
704
+ > & {
705
+ interrupt?: ToolCallMessagePart["interrupt"];
706
+ approval?: ToolCallMessagePart["approval"];
707
+ };
708
+
709
+ const ToolFallbackApproval = forwardRef<
710
+ HTMLDivElement,
711
+ ToolFallbackApprovalProps
712
+ >(function ToolFallbackApproval(props, ref) {
713
+ const carryFocusRef = useRef(false);
714
+ return (
715
+ <ToolFallbackApprovalImpl
716
+ key={props.approval?.id}
717
+ carryFocusRef={carryFocusRef}
718
+ forwardedRef={ref}
719
+ {...props}
720
+ />
721
+ );
722
+ });
683
723
 
684
724
  function ToolFallbackApprovalImpl({
685
725
  className,
726
+ forwardedRef,
727
+ carryFocusRef,
686
728
  addResult,
687
729
  resume,
688
730
  interrupt,
@@ -690,16 +732,10 @@ function ToolFallbackApprovalImpl({
690
732
  respondToApproval,
691
733
  status,
692
734
  ...props
693
- }: React.ComponentProps<"div"> &
694
- Partial<
695
- Pick<
696
- ToolCallMessagePartProps,
697
- "addResult" | "resume" | "respondToApproval" | "status"
698
- >
699
- > & {
700
- interrupt?: ToolCallMessagePart["interrupt"];
701
- approval?: ToolCallMessagePart["approval"];
702
- }) {
735
+ }: Omit<ToolFallbackApprovalProps, "ref"> & {
736
+ forwardedRef: React.ForwardedRef<HTMLDivElement>;
737
+ carryFocusRef: React.MutableRefObject<boolean>;
738
+ }) {
703
739
  const [submitted, setSubmitted] = useState(false);
704
740
  const voiceActive = useAuiState((s) => s.thread.voice !== undefined);
705
741
  const canAnswer = useAuiState((s) => s.thread.capabilities.answerToolCall);
@@ -707,17 +743,85 @@ function ToolFallbackApprovalImpl({
707
743
  const [confirmingId, setConfirmingId] = useState<string | null>(null);
708
744
  const [answer, setAnswer] = useState("");
709
745
  const [error, setError] = useState<string | null>(null);
746
+ const isRequiresAction = status?.type === "requires-action";
747
+ const [prevRequiresAction, setPrevRequiresAction] =
748
+ useState(isRequiresAction);
749
+ const [attempt, setAttempt] = useState(0);
750
+ const attemptRef = useRef(attempt);
751
+ useLayoutEffect(() => {
752
+ attemptRef.current = attempt;
753
+ }, [attempt]);
754
+ if (isRequiresAction !== prevRequiresAction) {
755
+ setPrevRequiresAction(isRequiresAction);
756
+ if (isRequiresAction) {
757
+ setSubmitted(false);
758
+ setConfirmingId(null);
759
+ setAnswer("");
760
+ setError(null);
761
+ setAttempt(attempt + 1);
762
+ }
763
+ }
764
+ const pendingGroupRef = useRef<HTMLDivElement | null>(null);
765
+ const receiptRef = useRef<HTMLDivElement | null>(null);
766
+ const focusReceiptRef = useRef<string | null | undefined>(null);
767
+ useLayoutEffect(() => {
768
+ if (carryFocusRef.current) {
769
+ carryFocusRef.current = false;
770
+ pendingGroupRef.current?.focus({ preventScroll: true });
771
+ }
772
+ return () => {
773
+ const element = pendingGroupRef.current ?? receiptRef.current;
774
+ carryFocusRef.current =
775
+ element?.contains(element.ownerDocument.activeElement) ?? false;
776
+ };
777
+ }, [carryFocusRef]);
778
+ useImperativeHandle<HTMLDivElement | null, HTMLDivElement | null>(
779
+ forwardedRef,
780
+ () => pendingGroupRef.current ?? receiptRef.current,
781
+ );
782
+ const setPendingGroup = useCallback(
783
+ (element: HTMLDivElement | null) => {
784
+ const group = pendingGroupRef.current;
785
+ focusReceiptRef.current =
786
+ !element && group?.contains(group.ownerDocument.activeElement)
787
+ ? approval?.id
788
+ : null;
789
+ pendingGroupRef.current = element;
790
+ },
791
+ [approval?.id],
792
+ );
793
+ const hidePendingApproval =
794
+ approval != null &&
795
+ !isSettled(approval) &&
796
+ status !== undefined &&
797
+ status.type !== "requires-action" &&
798
+ !(submitted && status.type === "running");
799
+ useLayoutEffect(() => {
800
+ if (hidePendingApproval) focusReceiptRef.current = null;
801
+ }, [hidePendingApproval]);
802
+ const focusPendingGroup = () => {
803
+ const group = pendingGroupRef.current;
804
+ if (group?.contains(group.ownerDocument.activeElement)) {
805
+ group.focus({ preventScroll: true });
806
+ }
807
+ };
710
808
 
711
809
  if (approval != null && isSettled(approval))
712
810
  return (
713
811
  <ToolFallbackApprovalReceipt
714
812
  approval={approval}
813
+ receiptRef={receiptRef}
814
+ focusReceiptRef={focusReceiptRef}
715
815
  className={className}
716
816
  {...props}
717
817
  />
718
818
  );
719
819
 
720
- if (!offersInterruptAction(status, approval, interrupt)) return null;
820
+ if (
821
+ hidePendingApproval ||
822
+ !offersInterruptAction(status, approval, interrupt)
823
+ )
824
+ return null;
721
825
 
722
826
  const promptText = approval?.prompt ? (
723
827
  <p className="aui-tool-fallback-approval-prompt text-foreground whitespace-pre-line">
@@ -730,11 +834,13 @@ function ToolFallbackApprovalImpl({
730
834
  promptText && (
731
835
  <div
732
836
  data-slot="tool-fallback-approval"
837
+ tabIndex={-1}
733
838
  className={cn(
734
839
  "aui-tool-fallback-approval flex flex-col gap-2 pt-1",
735
840
  className,
736
841
  )}
737
842
  {...props}
843
+ ref={setPendingGroup}
738
844
  >
739
845
  {promptText}
740
846
  </div>
@@ -753,12 +859,15 @@ function ToolFallbackApprovalImpl({
753
859
  // A refused response leaves the request open, so the controls come back
754
860
  // rather than staying spent on a decision the runtime never recorded.
755
861
  const submit = (send: () => Promise<void> | void) => {
862
+ focusPendingGroup();
756
863
  setSubmitted(true);
864
+ setConfirmingId(null);
757
865
  setError(null);
758
866
  void (async () => {
759
867
  try {
760
868
  await send();
761
869
  } catch (sendError) {
870
+ if (attemptRef.current !== attempt) return;
762
871
  setSubmitted(false);
763
872
  setError(
764
873
  sendError instanceof Error ? sendError.message : String(sendError),
@@ -789,7 +898,6 @@ function ToolFallbackApprovalImpl({
789
898
 
790
899
  const respondWithOption = (option: ToolApprovalOption) => {
791
900
  if (locked) return;
792
- setConfirmingId(null);
793
901
  // A custom kind has no decision class for the runtime to derive, and
794
902
  // responding without one throws; picking a declared option is an answer,
795
903
  // so it resolves as approved.
@@ -819,6 +927,7 @@ function ToolFallbackApprovalImpl({
819
927
 
820
928
  const handleOption = (option: ToolApprovalOption) => {
821
929
  if (option.confirm) {
930
+ focusPendingGroup();
822
931
  setConfirmingId(option.id);
823
932
  } else {
824
933
  respondWithOption(option);
@@ -886,11 +995,13 @@ function ToolFallbackApprovalImpl({
886
995
  return (
887
996
  <div
888
997
  data-slot="tool-fallback-approval"
998
+ tabIndex={-1}
889
999
  className={cn(
890
1000
  "aui-tool-fallback-approval flex flex-col gap-3 pt-1",
891
1001
  className,
892
1002
  )}
893
1003
  {...props}
1004
+ ref={setPendingGroup}
894
1005
  >
895
1006
  {promptText}
896
1007
  <ToolFallbackApprovalQuestions
@@ -913,11 +1024,13 @@ function ToolFallbackApprovalImpl({
913
1024
  return (
914
1025
  <div
915
1026
  data-slot="tool-fallback-approval-confirm"
1027
+ tabIndex={-1}
916
1028
  className={cn(
917
1029
  "aui-tool-fallback-approval-confirm flex flex-col gap-2 pt-1",
918
1030
  className,
919
1031
  )}
920
1032
  {...props}
1033
+ ref={setPendingGroup}
921
1034
  >
922
1035
  <p className="aui-tool-fallback-approval-confirm-title font-semibold">
923
1036
  {confirmMeta?.title ?? `${approvalOptionLabel(confirming)}?`}
@@ -951,7 +1064,10 @@ function ToolFallbackApprovalImpl({
951
1064
  size="sm"
952
1065
  variant="outline"
953
1066
  className={pressable}
954
- onClick={() => setConfirmingId(null)}
1067
+ onClick={() => {
1068
+ focusPendingGroup();
1069
+ setConfirmingId(null);
1070
+ }}
955
1071
  disabled={locked}
956
1072
  >
957
1073
  Back
@@ -970,11 +1086,13 @@ function ToolFallbackApprovalImpl({
970
1086
  return (
971
1087
  <div
972
1088
  data-slot="tool-fallback-approval"
1089
+ tabIndex={-1}
973
1090
  className={cn(
974
1091
  "aui-tool-fallback-approval flex flex-col gap-2 pt-1",
975
1092
  className,
976
1093
  )}
977
1094
  {...props}
1095
+ ref={setPendingGroup}
978
1096
  >
979
1097
  {promptText}
980
1098
  <div className="flex flex-wrap items-center gap-2">
@@ -1017,11 +1135,13 @@ function ToolFallbackApprovalImpl({
1017
1135
  return (
1018
1136
  <div
1019
1137
  data-slot="tool-fallback-approval"
1138
+ tabIndex={-1}
1020
1139
  className={cn(
1021
1140
  "aui-tool-fallback-approval flex flex-col gap-2 pt-1",
1022
1141
  className,
1023
1142
  )}
1024
1143
  {...props}
1144
+ ref={setPendingGroup}
1025
1145
  >
1026
1146
  {promptText}
1027
1147
  {answerField}
@@ -1036,11 +1156,13 @@ function ToolFallbackApprovalImpl({
1036
1156
  return (
1037
1157
  <div
1038
1158
  data-slot="tool-fallback-approval"
1159
+ tabIndex={-1}
1039
1160
  className={cn(
1040
1161
  "aui-tool-fallback-approval flex flex-col gap-2 pt-1",
1041
1162
  className,
1042
1163
  )}
1043
1164
  {...props}
1165
+ ref={setPendingGroup}
1044
1166
  >
1045
1167
  {promptText}
1046
1168
  <div className="flex items-center gap-2">
@@ -1083,7 +1205,8 @@ const ToolFallbackImpl: ToolCallMessagePartComponent = ({
1083
1205
  status?.type === "incomplete" && status.reason === "cancelled";
1084
1206
  const isRequiresAction = status?.type === "requires-action";
1085
1207
  const shouldRenderApproval =
1086
- isRequiresAction && offersInterruptAction(status, approval, interrupt);
1208
+ approval != null ||
1209
+ (isRequiresAction && offersInterruptAction(status, approval, interrupt));
1087
1210
 
1088
1211
  const [open, setOpen] = useState(isRequiresAction);
1089
1212
  const [prevRequiresAction, setPrevRequiresAction] =
@@ -1092,6 +1215,31 @@ const ToolFallbackImpl: ToolCallMessagePartComponent = ({
1092
1215
  setPrevRequiresAction(isRequiresAction);
1093
1216
  if (isRequiresAction) setOpen(true);
1094
1217
  }
1218
+ const approvalHadFocusRef = useRef(false);
1219
+ const approvalElementRef = useRef<HTMLDivElement | null>(null);
1220
+ const triggerRef = useRef<HTMLButtonElement | null>(null);
1221
+
1222
+ useLayoutEffect(() => {
1223
+ const focusedElement = approvalElementRef.current;
1224
+ if (
1225
+ !focusedElement ||
1226
+ focusedElement.isConnected ||
1227
+ isRequiresAction ||
1228
+ !approvalHadFocusRef.current
1229
+ ) {
1230
+ return;
1231
+ }
1232
+
1233
+ const shouldFocusTrigger = approval == null || !isSettled(approval);
1234
+ approvalHadFocusRef.current = false;
1235
+ const { activeElement, body } = focusedElement.ownerDocument;
1236
+ if (
1237
+ shouldFocusTrigger &&
1238
+ (activeElement == null || activeElement === body)
1239
+ ) {
1240
+ triggerRef.current?.focus({ preventScroll: true });
1241
+ }
1242
+ }, [approval, isRequiresAction, status?.type]);
1095
1243
 
1096
1244
  return (
1097
1245
  <ToolFallbackRoot open={open} onOpenChange={setOpen}>
@@ -1102,7 +1250,7 @@ const ToolFallbackImpl: ToolCallMessagePartComponent = ({
1102
1250
  argsText={argsText}
1103
1251
  className={cn(isCancelled && "opacity-60")}
1104
1252
  />
1105
- {(shouldRenderApproval || isSettled(approval)) && (
1253
+ {shouldRenderApproval && (
1106
1254
  <ToolFallbackApproval
1107
1255
  addResult={addResult}
1108
1256
  resume={resume}
@@ -1110,6 +1258,26 @@ const ToolFallbackImpl: ToolCallMessagePartComponent = ({
1110
1258
  approval={approval}
1111
1259
  respondToApproval={respondToApproval}
1112
1260
  status={status}
1261
+ onFocusCapture={(event) => {
1262
+ const root = event.currentTarget.closest(
1263
+ '[data-slot="tool-fallback-root"]',
1264
+ );
1265
+ triggerRef.current =
1266
+ root?.querySelector<HTMLButtonElement>(
1267
+ '[data-slot="tool-fallback-trigger"]',
1268
+ ) ?? null;
1269
+ approvalElementRef.current = event.currentTarget;
1270
+ approvalHadFocusRef.current = true;
1271
+ }}
1272
+ onBlurCapture={(event) => {
1273
+ const relatedTarget = event.relatedTarget;
1274
+ const stillFocused = relatedTarget
1275
+ ? event.currentTarget.contains(relatedTarget as Node)
1276
+ : event.currentTarget.contains(
1277
+ event.currentTarget.ownerDocument.activeElement,
1278
+ );
1279
+ if (!stillFocused) approvalHadFocusRef.current = false;
1280
+ }}
1113
1281
  />
1114
1282
  )}
1115
1283
  <ToolFallbackResult result={result} />
@@ -13,38 +13,38 @@
13
13
  "typecheck": "tsc --noEmit"
14
14
  },
15
15
  "dependencies": {
16
- "@ai-sdk/openai": "^4.0.82",
16
+ "@ai-sdk/openai": "^4.0.86",
17
17
  "@assistant-ui/ai-sdk": "workspace:*",
18
18
  "@assistant-ui/core": "workspace:*",
19
19
  "@assistant-ui/react": "workspace:*",
20
+ "@assistant-ui/react-harness-sdk": "file:vendor/assistant-ui-react-harness-sdk-0.0.2.tgz",
20
21
  "@assistant-ui/react-markdown": "workspace:*",
21
22
  "@assistant-ui/store": "workspace:*",
22
23
  "@assistant-ui/tap": "workspace:*",
23
24
  "@base-ui/react": "^1.8.0",
24
- "ai": "^7.0.123",
25
+ "ai": "^7.0.130",
26
+ "assistant-cloud": "workspace:*",
25
27
  "class-variance-authority": "^0.7.1",
26
28
  "cn": "^0.4.0",
27
- "lucide-react": "^1.49.0",
28
- "next": "^16.3.8",
29
+ "harness-sdk": "file:vendor/harness-sdk-0.3.1.tgz",
30
+ "lucide-react": "^1.52.0",
31
+ "next": "^16.4.0",
29
32
  "react": "^19.3.0",
30
33
  "react-dom": "^19.3.0",
31
34
  "remark-gfm": "^4.0.1",
35
+ "statewire": "file:vendor/statewire-0.19.3.tgz",
32
36
  "tw-animate-css": "^1.4.0",
33
37
  "tw-shimmer": "^0.4.13",
34
- "zustand": "^5.0.15",
35
- "assistant-cloud": "workspace:*",
36
- "@assistant-ui/react-harness-sdk": "file:vendor/assistant-ui-react-harness-sdk-0.0.2.tgz",
37
- "harness-sdk": "file:vendor/harness-sdk-0.3.1.tgz",
38
- "statewire": "file:vendor/statewire-0.19.3.tgz"
38
+ "zustand": "^5.0.15"
39
39
  },
40
40
  "devDependencies": {
41
41
  "@assistant-ui/next": "workspace:*",
42
42
  "@tailwindcss/postcss": "^4.3.3",
43
- "@types/node": "^26.6.3",
43
+ "@types/node": "^26.6.4",
44
44
  "@types/react": "^19.3.0",
45
45
  "@types/react-dom": "^19.3.0",
46
- "oxfmt": "^0.71.0",
47
- "oxlint": "^1.86.0",
46
+ "oxfmt": "^0.72.0",
47
+ "oxlint": "^1.87.0",
48
48
  "tailwindcss": "^4.3.3",
49
49
  "typescript": "^7.0.2"
50
50
  }