assistant-ui 0.0.112 → 0.0.113

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 (90) hide show
  1. package/dist/codemods/v0-12/assistant-api-to-aui.d.ts.map +1 -1
  2. package/dist/codemods/v0-12/assistant-api-to-aui.js +87 -62
  3. package/dist/codemods/v0-12/assistant-api-to-aui.js.map +1 -1
  4. package/dist/codemods/v0-12/primitive-if-to-aui-if.d.ts.map +1 -1
  5. package/dist/codemods/v0-12/primitive-if-to-aui-if.js +31 -45
  6. package/dist/codemods/v0-12/primitive-if-to-aui-if.js.map +1 -1
  7. package/dist/commands/add.d.ts +1 -1
  8. package/dist/commands/add.d.ts.map +1 -1
  9. package/dist/commands/add.js +4 -2
  10. package/dist/commands/add.js.map +1 -1
  11. package/dist/commands/create.d.ts.map +1 -1
  12. package/dist/commands/create.js +33 -10
  13. package/dist/commands/create.js.map +1 -1
  14. package/dist/commands/info.d.ts.map +1 -1
  15. package/dist/commands/info.js +2 -1
  16. package/dist/commands/info.js.map +1 -1
  17. package/dist/commands/init.d.ts.map +1 -1
  18. package/dist/commands/init.js +4 -2
  19. package/dist/commands/init.js.map +1 -1
  20. package/dist/commands/mcp.d.ts.map +1 -1
  21. package/dist/commands/mcp.js +25 -28
  22. package/dist/commands/mcp.js.map +1 -1
  23. package/dist/commands/update.js +6 -7
  24. package/dist/commands/update.js.map +1 -1
  25. package/dist/commands/upgrade.d.ts.map +1 -1
  26. package/dist/commands/upgrade.js +5 -2
  27. package/dist/commands/upgrade.js.map +1 -1
  28. package/dist/index.js +2 -6
  29. package/dist/index.js.map +1 -1
  30. package/dist/lib/agent-skill.d.ts +1 -1
  31. package/dist/lib/agent-skill.d.ts.map +1 -1
  32. package/dist/lib/agent-skill.js.map +1 -1
  33. package/dist/lib/create-project.d.ts +2 -3
  34. package/dist/lib/create-project.d.ts.map +1 -1
  35. package/dist/lib/create-project.js +17 -42
  36. package/dist/lib/create-project.js.map +1 -1
  37. package/dist/lib/handle-cli-error.d.ts +5 -0
  38. package/dist/lib/handle-cli-error.d.ts.map +1 -0
  39. package/dist/lib/handle-cli-error.js +17 -0
  40. package/dist/lib/handle-cli-error.js.map +1 -0
  41. package/dist/lib/install-ai-sdk-lib.js +8 -1
  42. package/dist/lib/install-ai-sdk-lib.js.map +1 -1
  43. package/dist/lib/install-edge-lib.js +4 -8
  44. package/dist/lib/install-edge-lib.js.map +1 -1
  45. package/dist/lib/run-spawn.d.ts +16 -2
  46. package/dist/lib/run-spawn.d.ts.map +1 -1
  47. package/dist/lib/run-spawn.js +87 -9
  48. package/dist/lib/run-spawn.js.map +1 -1
  49. package/dist/lib/transform.d.ts +1 -1
  50. package/dist/lib/transform.d.ts.map +1 -1
  51. package/dist/lib/transform.js +12 -25
  52. package/dist/lib/transform.js.map +1 -1
  53. package/dist/lib/upgrade.js +20 -16
  54. package/dist/lib/upgrade.js.map +1 -1
  55. package/dist/lib/utils/file-scanner.d.ts +9 -1
  56. package/dist/lib/utils/file-scanner.d.ts.map +1 -1
  57. package/dist/lib/utils/file-scanner.js +22 -20
  58. package/dist/lib/utils/file-scanner.js.map +1 -1
  59. package/dist/lib/utils/package-installer.js +1 -1
  60. package/dist/lib/utils/package-manager.d.ts +3 -1
  61. package/dist/lib/utils/package-manager.d.ts.map +1 -1
  62. package/dist/lib/utils/package-manager.js +22 -10
  63. package/dist/lib/utils/package-manager.js.map +1 -1
  64. package/package.json +6 -6
  65. package/plugin/skills/assistant-ui/SKILL.md +3 -3
  66. package/src/codemods/v0-12/__tests__/assistant-api-to-aui.test.ts +370 -0
  67. package/src/codemods/v0-12/__tests__/primitive-if-to-aui-if.test.ts +100 -0
  68. package/src/codemods/v0-12/assistant-api-to-aui.ts +227 -134
  69. package/src/codemods/v0-12/primitive-if-to-aui-if.ts +44 -72
  70. package/src/commands/add.ts +5 -5
  71. package/src/commands/create.ts +41 -7
  72. package/src/commands/info.ts +1 -0
  73. package/src/commands/init.ts +4 -6
  74. package/src/commands/mcp.ts +20 -29
  75. package/src/commands/update.ts +6 -8
  76. package/src/commands/upgrade.ts +5 -2
  77. package/src/index.ts +2 -7
  78. package/src/lib/agent-skill.ts +2 -1
  79. package/src/lib/create-project.ts +24 -58
  80. package/src/lib/handle-cli-error.test.ts +67 -0
  81. package/src/lib/handle-cli-error.ts +17 -0
  82. package/src/lib/install-ai-sdk-lib.ts +13 -1
  83. package/src/lib/install-edge-lib.ts +7 -8
  84. package/src/lib/run-spawn.test.ts +148 -0
  85. package/src/lib/run-spawn.ts +121 -11
  86. package/src/lib/transform.test.ts +62 -0
  87. package/src/lib/transform.ts +21 -37
  88. package/src/lib/upgrade.ts +23 -19
  89. package/src/lib/utils/file-scanner.ts +26 -20
  90. package/src/lib/utils/package-manager.ts +29 -12
@@ -592,3 +592,373 @@ function MyComponent() {
592
592
  expect(output?.trim()).toBe(expected.trim());
593
593
  });
594
594
  });
595
+
596
+ describe("api bindings unrelated to useAssistantApi", () => {
597
+ it("does not rename a destructured api from another source", () => {
598
+ const input = `
599
+ import { useAssistantApi } from "@assistant-ui/react";
600
+
601
+ function MyComponent() {
602
+ const api = useAssistantApi();
603
+ return api.thread();
604
+ }
605
+
606
+ function loadData() {
607
+ const { api } = createClient();
608
+ return api.fetchStuff();
609
+ }
610
+ `;
611
+
612
+ const output = applyTransform(input);
613
+ expect(output).toContain("const { api } = createClient()");
614
+ expect(output).toContain("api.fetchStuff()");
615
+ expect(output).toContain("const aui = useAui()");
616
+ });
617
+
618
+ it("does not rename a function parameter named api", () => {
619
+ const input = `
620
+ import { useAssistantApi } from "@assistant-ui/react";
621
+
622
+ function MyComponent() {
623
+ const api = useAssistantApi();
624
+ return api.thread();
625
+ }
626
+
627
+ function callRemote(api: RemoteApi) {
628
+ return api.send();
629
+ }
630
+ `;
631
+
632
+ const output = applyTransform(input);
633
+ expect(output).toContain("function callRemote(api: RemoteApi)");
634
+ expect(output).toContain("return api.send()");
635
+ });
636
+
637
+ it("expands shorthand object properties instead of renaming the key", () => {
638
+ const input = `
639
+ import { useAssistantApi } from "@assistant-ui/react";
640
+
641
+ function MyComponent() {
642
+ const api = useAssistantApi();
643
+ return register({ api });
644
+ }
645
+ `;
646
+
647
+ const output = applyTransform(input);
648
+ expect(output).toContain("register({ api: aui })");
649
+ });
650
+ });
651
+
652
+ describe("JSX and export positions", () => {
653
+ it("does not rename JSX member properties or intrinsic tags", () => {
654
+ const input = `
655
+ import { useAssistantApi } from "@assistant-ui/react";
656
+
657
+ function MyComponent() {
658
+ const api = useAssistantApi();
659
+ void api.thread();
660
+ return (
661
+ <div>
662
+ <config.api />
663
+ <api />
664
+ </div>
665
+ );
666
+ }
667
+ `;
668
+
669
+ const output = applyTransform(input);
670
+ expect(output).toContain("<config.api />");
671
+ expect(output).toContain("<api />");
672
+ expect(output).toContain("void aui.thread()");
673
+ });
674
+
675
+ it("preserves the public name of a re-exported api", () => {
676
+ const input = `
677
+ import { useAssistantApi } from "@assistant-ui/react";
678
+
679
+ const api = useAssistantApi();
680
+
681
+ export { api };
682
+ `;
683
+
684
+ const output = applyTransform(input);
685
+ expect(output).toContain("export { aui as api }");
686
+ expect(output).toContain("const aui = useAui()");
687
+ });
688
+ });
689
+
690
+ describe("aliased and source-bearing exports", () => {
691
+ it("preserves aliased public names", () => {
692
+ const input = `
693
+ import { useAssistantApi } from "@assistant-ui/react";
694
+
695
+ const api = useAssistantApi();
696
+
697
+ export { api as default };
698
+ export { api as clientApi };
699
+ `;
700
+
701
+ const output = applyTransform(input);
702
+ expect(output).toContain("export { aui as default }");
703
+ expect(output).toContain("export { aui as clientApi }");
704
+ });
705
+
706
+ it("leaves source-bearing re-exports untouched", () => {
707
+ const input = `
708
+ import { useAssistantApi } from "@assistant-ui/react";
709
+
710
+ const api = useAssistantApi();
711
+ void api.thread();
712
+
713
+ export { api } from "./other-module";
714
+ `;
715
+
716
+ const output = applyTransform(input);
717
+ expect(output).toContain('export { api } from "./other-module"');
718
+ expect(output).toContain("void aui.thread()");
719
+ });
720
+
721
+ it("leaves type-only api exports untouched", () => {
722
+ const input = `
723
+ import { useAssistantApi } from "@assistant-ui/react";
724
+
725
+ const api = useAssistantApi();
726
+ void api.thread();
727
+
728
+ type api = { x: number };
729
+ export type { api };
730
+ export { type api as ApiType };
731
+ `;
732
+
733
+ const output = applyTransform(input);
734
+ expect(output).toContain("export type { api }");
735
+ expect(output).toContain("export { type api as ApiType }");
736
+ expect(output).toContain("void aui.thread()");
737
+ });
738
+ });
739
+
740
+ describe("block-scoped shadowing", () => {
741
+ it("does not rename a block-scoped api inside the same function", () => {
742
+ const input = `
743
+ import { useAssistantApi } from "@assistant-ui/react";
744
+
745
+ function MyComponent() {
746
+ const api = useAssistantApi();
747
+ void api.thread();
748
+ {
749
+ const api = createOther();
750
+ void api.other();
751
+ }
752
+ if (true) {
753
+ const { api } = createClient();
754
+ void api.fetchStuff();
755
+ }
756
+ return null;
757
+ }
758
+ `;
759
+
760
+ const output = applyTransform(input);
761
+ expect(output).toContain("void aui.thread()");
762
+ expect(output).toContain("const api = createOther()");
763
+ expect(output).toContain("void api.other()");
764
+ expect(output).toContain("const { api } = createClient()");
765
+ expect(output).toContain("void api.fetchStuff()");
766
+ });
767
+ });
768
+
769
+ describe("binding positions beyond plain declarations", () => {
770
+ it("does not rename method parameters named api", () => {
771
+ const input = `
772
+ import { useAssistantApi } from "@assistant-ui/react";
773
+
774
+ function MyComponent() {
775
+ const api = useAssistantApi();
776
+ void api.thread();
777
+ const handlers = {
778
+ load(api: RemoteApi) {
779
+ return api.send();
780
+ },
781
+ };
782
+ class Client {
783
+ call(api: RemoteApi) {
784
+ return api.send();
785
+ }
786
+ }
787
+ return handlers;
788
+ }
789
+ `;
790
+
791
+ const output = applyTransform(input);
792
+ expect(output).toContain("load(api: RemoteApi)");
793
+ expect(output).toContain("call(api: RemoteApi)");
794
+ expect(output?.match(/return api\.send\(\)/g)).toHaveLength(2);
795
+ expect(output).toContain("void aui.thread()");
796
+ });
797
+
798
+ it("does not rename constructor parameter properties named api", () => {
799
+ const input = `
800
+ import { useAssistantApi } from "@assistant-ui/react";
801
+
802
+ function MyComponent() {
803
+ const api = useAssistantApi();
804
+ void api.thread();
805
+ class Client {
806
+ constructor(public api: RemoteApi) {
807
+ return api.send();
808
+ }
809
+ }
810
+ return Client;
811
+ }
812
+ `;
813
+
814
+ const output = applyTransform(input);
815
+ expect(output).toContain("constructor(public api: RemoteApi)");
816
+ expect(output).toContain("return api.send()");
817
+ expect(output).toContain("void aui.thread()");
818
+ });
819
+
820
+ it("treats function and class declarations named api as shadows", () => {
821
+ const input = `
822
+ import { useAssistantApi } from "@assistant-ui/react";
823
+
824
+ const api = useAssistantApi();
825
+ void api.thread();
826
+
827
+ function outer() {
828
+ function api() {}
829
+ return api();
830
+ }
831
+
832
+ function other() {
833
+ class api {}
834
+ return new api();
835
+ }
836
+ `;
837
+
838
+ const output = applyTransform(input);
839
+ expect(output).toContain("void aui.thread()");
840
+ expect(output).toContain("function api() {}");
841
+ expect(output).toContain("return api()");
842
+ expect(output).toContain("class api {}");
843
+ expect(output).toContain("new api()");
844
+ });
845
+
846
+ it("recognizes for-initializer and switch-case declarations", () => {
847
+ const input = `
848
+ import { useAssistantApi } from "@assistant-ui/react";
849
+
850
+ function MyComponent() {
851
+ const api = useAssistantApi();
852
+ void api.thread();
853
+ for (let api = start(); api.more(); api = api.next()) {
854
+ use(api);
855
+ }
856
+ switch (kind) {
857
+ case "a": {
858
+ const api = other();
859
+ return api.load();
860
+ }
861
+ }
862
+ }
863
+ `;
864
+
865
+ const output = applyTransform(input);
866
+ expect(output).toContain("void aui.thread()");
867
+ expect(output).toContain(
868
+ "for (let api = start(); api.more(); api = api.next())",
869
+ );
870
+ expect(output).toContain("use(api)");
871
+ expect(output).toContain("const api = other()");
872
+ expect(output).toContain("return api.load()");
873
+ });
874
+
875
+ it("handles export const api declarations", () => {
876
+ const input = `
877
+ import { useAssistantApi } from "@assistant-ui/react";
878
+
879
+ export const api = useAssistantApi();
880
+
881
+ export function helper() {
882
+ return api.thread();
883
+ }
884
+ `;
885
+
886
+ const output = applyTransform(input);
887
+ expect(output).toContain("export const aui = useAui()");
888
+ expect(output).toContain("return aui.thread()");
889
+ });
890
+ });
891
+
892
+ describe("keys and type-only declarations", () => {
893
+ it("does not rename method or class-member keys named api", () => {
894
+ const input = `
895
+ import { useAssistantApi } from "@assistant-ui/react";
896
+
897
+ function MyComponent() {
898
+ const api = useAssistantApi();
899
+ void api.thread();
900
+ const handlers = {
901
+ api() {
902
+ return 1;
903
+ },
904
+ };
905
+ class Client {
906
+ api = 1;
907
+ api2() {
908
+ return this.api;
909
+ }
910
+ }
911
+ return { handlers, Client };
912
+ }
913
+ `;
914
+
915
+ const output = applyTransform(input);
916
+ expect(output).toContain("api() {");
917
+ expect(output).toContain("api = 1;");
918
+ expect(output).toContain("return this.api");
919
+ expect(output).toContain("void aui.thread()");
920
+ });
921
+
922
+ it("does not treat type-only declarations as value shadows", () => {
923
+ const input = `
924
+ import { useAssistantApi } from "@assistant-ui/react";
925
+
926
+ function MyComponent() {
927
+ const api = useAssistantApi();
928
+ type api2 = string;
929
+ {
930
+ type api = { x: number };
931
+ interface apiShape {}
932
+ void api.thread();
933
+ }
934
+ return null;
935
+ }
936
+ `;
937
+
938
+ const output = applyTransform(input);
939
+ expect(output).toContain("void aui.thread()");
940
+ expect(output).toContain("type api = { x: number }");
941
+ });
942
+ });
943
+
944
+ describe("named expressions", () => {
945
+ it("does not rename the self-reference of a named function expression", () => {
946
+ const input = `
947
+ import { useAssistantApi } from "@assistant-ui/react";
948
+
949
+ function MyComponent() {
950
+ const api = useAssistantApi();
951
+ void api.thread();
952
+ const run = function api() {
953
+ return api;
954
+ };
955
+ return run;
956
+ }
957
+ `;
958
+
959
+ const output = applyTransform(input);
960
+ expect(output).toContain("function api() {");
961
+ expect(output).toContain("return api;");
962
+ expect(output).toContain("void aui.thread()");
963
+ });
964
+ });
@@ -837,3 +837,103 @@ function MyComponent() {
837
837
  });
838
838
  });
839
839
  });
840
+
841
+ describe("elements that cannot be migrated stay intact", () => {
842
+ it.each([
843
+ [
844
+ "spread attributes",
845
+ `<ThreadPrimitive.If {...props}>
846
+ <div>Content</div>
847
+ </ThreadPrimitive.If>`,
848
+ ],
849
+ [
850
+ "unknown props",
851
+ `<MessagePrimitive.If user asChild>
852
+ <div>Content</div>
853
+ </MessagePrimitive.If>`,
854
+ ],
855
+ [
856
+ "no props",
857
+ `<ThreadPrimitive.If>
858
+ <div>Content</div>
859
+ </ThreadPrimitive.If>`,
860
+ ],
861
+ [
862
+ "dynamic prop values",
863
+ `<ThreadPrimitive.If running={someFlag}>
864
+ <div>Content</div>
865
+ </ThreadPrimitive.If>`,
866
+ ],
867
+ [
868
+ "namespaced attributes",
869
+ `<ThreadPrimitive.If empty xml:lang="en">
870
+ <div>Content</div>
871
+ </ThreadPrimitive.If>`,
872
+ ],
873
+ [
874
+ "fixed-condition components with props",
875
+ `<ThreadPrimitive.Empty asChild>
876
+ <div>Content</div>
877
+ </ThreadPrimitive.Empty>`,
878
+ ],
879
+ ])("leaves an element with %s unchanged", (_label, jsx) => {
880
+ const input = `
881
+ import { ThreadPrimitive, MessagePrimitive } from "@assistant-ui/react";
882
+
883
+ function MyComponent({ someFlag }: { someFlag: boolean }) {
884
+ return (
885
+ ${jsx}
886
+ );
887
+ }
888
+ `;
889
+
890
+ expect(applyTransform(input)).toBeNull();
891
+ });
892
+
893
+ it("converts only the migratable element and keeps the output parseable", () => {
894
+ const input = `
895
+ import { ThreadPrimitive } from "@assistant-ui/react";
896
+
897
+ function MyComponent(props: Record<string, unknown>) {
898
+ return (
899
+ <>
900
+ <ThreadPrimitive.If empty>
901
+ <div>Empty</div>
902
+ </ThreadPrimitive.If>
903
+ <ThreadPrimitive.If {...props}>
904
+ <div>Dynamic</div>
905
+ </ThreadPrimitive.If>
906
+ </>
907
+ );
908
+ }
909
+ `;
910
+
911
+ const output = applyTransform(input);
912
+ expect(output).not.toBeNull();
913
+ expect(() => j(output!)).not.toThrow();
914
+ expect(output).toContain("</AuiIf>");
915
+ expect(output).toContain("</ThreadPrimitive.If>");
916
+ expect(output).toContain("<ThreadPrimitive.If {...props}>");
917
+ });
918
+ });
919
+
920
+ describe("null literal prop values", () => {
921
+ it("maps submittedFeedback={null} to the null comparison", () => {
922
+ const input = `
923
+ import { MessagePrimitive } from "@assistant-ui/react";
924
+
925
+ function MyComponent() {
926
+ return (
927
+ <MessagePrimitive.If submittedFeedback={null}>
928
+ <div>Content</div>
929
+ </MessagePrimitive.If>
930
+ );
931
+ }
932
+ `;
933
+
934
+ const output = applyTransform(input);
935
+ expect(output).toContain(
936
+ "(s.message.metadata.submittedFeedback?.type ?? null) === null",
937
+ );
938
+ });
939
+ });