| ... | @@ -739,48 +739,35 @@ export default function ChatView() { | ... | @@ -739,48 +739,35 @@ export default function ChatView() { |
| 739 | }, | 739 | }, |
| 740 | [activeProject, activeThread, activeThreadId, api, dispatch, gitCwd], | 740 | [activeProject, activeThread, activeThreadId, api, dispatch, gitCwd], |
| 741 | ); | 741 | ); |
| 742 | const saveProjectScript = useCallback( | 742 | const persistProjectScripts = useCallback( |
| 743 | async (input: NewProjectScriptInput) => { | 743 | async (input: { |
| 744 | if (!activeProject) return; | 744 | projectId: string; |
| 745 | const nextId = nextProjectScriptId( | 745 | projectCwd: string; |
| 746 | input.name, | 746 | previousScripts: ProjectScript[]; |
| 747 | activeProject.scripts.map((script) => script.id), | 747 | nextScripts: ProjectScript[]; |
| 748 | ); | 748 | keybinding?: string | null; |
| 749 | const nextScript: ProjectScript = { | 749 | keybindingCommand: string; |
| 750 | id: nextId, | 750 | }) => { |
| 751 | name: input.name, | | |
| 752 | command: input.command, | | |
| 753 | icon: input.icon, | | |
| 754 | runOnWorktreeCreate: input.runOnWorktreeCreate, | | |
| 755 | }; | | |
| 756 | const nextScripts = input.runOnWorktreeCreate | | |
| 757 | ? [ | | |
| 758 | ...activeProject.scripts.map((script) => | | |
| 759 | script.runOnWorktreeCreate ? { ...script, runOnWorktreeCreate: false } : script, | | |
| 760 | ), | | |
| 761 | nextScript, | | |
| 762 | ] | | |
| 763 | : [...activeProject.scripts, nextScript]; | | |
| 764 | | | |
| 765 | dispatch({ | 751 | dispatch({ |
| 766 | type: "SET_PROJECT_SCRIPTS", | 752 | type: "SET_PROJECT_SCRIPTS", |
| 767 | projectId: activeProject.id, | 753 | projectId: input.projectId, |
| 768 | scripts: nextScripts, | 754 | scripts: input.nextScripts, |
| 769 | }); | 755 | }); |
| 770 | | 756 | |
| 771 | if (!isElectron || !api) return; | 757 | if (!isElectron || !api) return; |
| | 758 | |
| 772 | let scriptsPersisted = false; | 759 | let scriptsPersisted = false; |
| 773 | try { | 760 | try { |
| 774 | const updated = await api.projects.updateScripts({ | 761 | const updated = await api.projects.updateScripts({ |
| 775 | id: activeProject.id, | 762 | id: input.projectId, |
| 776 | scripts: nextScripts, | 763 | scripts: input.nextScripts, |
| 777 | }); | 764 | }); |
| 778 | scriptsPersisted = true; | 765 | scriptsPersisted = true; |
| 779 | | 766 | |
| 780 | if (input.keybinding) { | 767 | if (input.keybinding) { |
| 781 | const keybindingUpdate = await api.server.upsertKeybinding({ | 768 | const keybindingUpdate = await api.server.upsertKeybinding({ |
| 782 | key: input.keybinding, | 769 | key: input.keybinding, |
| 783 | command: commandForProjectScript(nextId), | 770 | command: input.keybindingCommand, |
| 784 | }); | 771 | }); |
| 785 | queryClient.setQueryData( | 772 | queryClient.setQueryData( |
| 786 | serverQueryKeys.config(), | 773 | serverQueryKeys.config(), |
| ... | @@ -788,7 +775,7 @@ export default function ChatView() { | ... | @@ -788,7 +775,7 @@ export default function ChatView() { |
| 788 | current | 775 | current |
| 789 | ? { ...current, keybindings: keybindingUpdate.keybindings } | 776 | ? { ...current, keybindings: keybindingUpdate.keybindings } |
| 790 | : { | 777 | : { |
| 791 | cwd: activeProject.cwd, | 778 | cwd: input.projectCwd, |
| 792 | keybindings: keybindingUpdate.keybindings, | 779 | keybindings: keybindingUpdate.keybindings, |
| 793 | }, | 780 | }, |
| 794 | ); | 781 | ); |
| ... | @@ -803,20 +790,54 @@ export default function ChatView() { | ... | @@ -803,20 +790,54 @@ export default function ChatView() { |
| 803 | if (scriptsPersisted) { | 790 | if (scriptsPersisted) { |
| 804 | await api.projects | 791 | await api.projects |
| 805 | .updateScripts({ | 792 | .updateScripts({ |
| 806 | id: activeProject.id, | 793 | id: input.projectId, |
| 807 | scripts: activeProject.scripts, | 794 | scripts: input.previousScripts, |
| 808 | }) | 795 | }) |
| 809 | .catch(() => undefined); | 796 | .catch(() => undefined); |
| 810 | } | 797 | } |
| 811 | dispatch({ | 798 | dispatch({ |
| 812 | type: "SET_PROJECT_SCRIPTS", | 799 | type: "SET_PROJECT_SCRIPTS", |
| 813 | projectId: activeProject.id, | 800 | projectId: input.projectId, |
| 814 | scripts: activeProject.scripts, | 801 | scripts: input.previousScripts, |
| 815 | }); | 802 | }); |
| 816 | throw error; | 803 | throw error; |
| 817 | } | 804 | } |
| 818 | }, | 805 | }, |
| 819 | [activeProject, api, dispatch, queryClient], | 806 | [api, dispatch, queryClient], |
| | 807 | ); |
| | 808 | const saveProjectScript = useCallback( |
| | 809 | async (input: NewProjectScriptInput) => { |
| | 810 | if (!activeProject) return; |
| | 811 | const nextId = nextProjectScriptId( |
| | 812 | input.name, |
| | 813 | activeProject.scripts.map((script) => script.id), |
| | 814 | ); |
| | 815 | const nextScript: ProjectScript = { |
| | 816 | id: nextId, |
| | 817 | name: input.name, |
| | 818 | command: input.command, |
| | 819 | icon: input.icon, |
| | 820 | runOnWorktreeCreate: input.runOnWorktreeCreate, |
| | 821 | }; |
| | 822 | const nextScripts = input.runOnWorktreeCreate |
| | 823 | ? [ |
| | 824 | ...activeProject.scripts.map((script) => |
| | 825 | script.runOnWorktreeCreate ? { ...script, runOnWorktreeCreate: false } : script, |
| | 826 | ), |
| | 827 | nextScript, |
| | 828 | ] |
| | 829 | : [...activeProject.scripts, nextScript]; |
| | 830 | |
| | 831 | await persistProjectScripts({ |
| | 832 | projectId: activeProject.id, |
| | 833 | projectCwd: activeProject.cwd, |
| | 834 | previousScripts: activeProject.scripts, |
| | 835 | nextScripts, |
| | 836 | keybinding: input.keybinding, |
| | 837 | keybindingCommand: commandForProjectScript(nextId), |
| | 838 | }); |
| | 839 | }, |
| | 840 | [activeProject, persistProjectScripts], |
| 820 | ); | 841 | ); |
| 821 | const updateProjectScript = useCallback( | 842 | const updateProjectScript = useCallback( |
| 822 | async (scriptId: string, input: NewProjectScriptInput) => { | 843 | async (scriptId: string, input: NewProjectScriptInput) => { |
| ... | @@ -841,61 +862,16 @@ export default function ChatView() { | ... | @@ -841,61 +862,16 @@ export default function ChatView() { |
| 841 | : script, | 862 | : script, |
| 842 | ); | 863 | ); |
| 843 | | 864 | |
| 844 | dispatch({ | 865 | await persistProjectScripts({ |
| 845 | type: "SET_PROJECT_SCRIPTS", | | |
| 846 | projectId: activeProject.id, | 866 | projectId: activeProject.id, |
| 847 | scripts: nextScripts, | 867 | projectCwd: activeProject.cwd, |
| | 868 | previousScripts: activeProject.scripts, |
| | 869 | nextScripts, |
| | 870 | keybinding: input.keybinding, |
| | 871 | keybindingCommand: commandForProjectScript(scriptId), |
| 848 | }); | 872 | }); |
| 849 | | | |
| 850 | if (!isElectron || !api) return; | | |
| 851 | let scriptsPersisted = false; | | |
| 852 | try { | | |
| 853 | const updated = await api.projects.updateScripts({ | | |
| 854 | id: activeProject.id, | | |
| 855 | scripts: nextScripts, | | |
| 856 | }); | | |
| 857 | scriptsPersisted = true; | | |
| 858 | | | |
| 859 | if (input.keybinding) { | | |
| 860 | const keybindingUpdate = await api.server.upsertKeybinding({ | | |
| 861 | key: input.keybinding, | | |
| 862 | command: commandForProjectScript(scriptId), | | |
| 863 | }); | | |
| 864 | queryClient.setQueryData( | | |
| 865 | serverQueryKeys.config(), | | |
| 866 | (current: { cwd: string; keybindings: ResolvedKeybindingsConfig } | undefined) => | | |
| 867 | current | | |
| 868 | ? { ...current, keybindings: keybindingUpdate.keybindings } | | |
| 869 | : { | | |
| 870 | cwd: activeProject.cwd, | | |
| 871 | keybindings: keybindingUpdate.keybindings, | | |
| 872 | }, | | |
| 873 | ); | | |
| 874 | } | | |
| 875 | | | |
| 876 | dispatch({ | | |
| 877 | type: "SET_PROJECT_SCRIPTS", | | |
| 878 | projectId: updated.project.id, | | |
| 879 | scripts: updated.project.scripts, | | |
| 880 | }); | | |
| 881 | } catch (error) { | | |
| 882 | if (scriptsPersisted) { | | |
| 883 | await api.projects | | |
| 884 | .updateScripts({ | | |
| 885 | id: activeProject.id, | | |
| 886 | scripts: activeProject.scripts, | | |
| 887 | }) | | |
| 888 | .catch(() => undefined); | | |
| 889 | } | | |
| 890 | dispatch({ | | |
| 891 | type: "SET_PROJECT_SCRIPTS", | | |
| 892 | projectId: activeProject.id, | | |
| 893 | scripts: activeProject.scripts, | | |
| 894 | }); | | |
| 895 | throw error; | | |
| 896 | } | | |
| 897 | }, | 873 | }, |
| 898 | [activeProject, api, dispatch, queryClient], | 874 | [activeProject, persistProjectScripts], |
| 899 | ); | 875 | ); |
| 900 | | 876 | |
| 901 | const handleRuntimeModeChange = async (mode: "approval-required" | "full-access") => { | 877 | const handleRuntimeModeChange = async (mode: "approval-required" | "full-access") => { |