MCPcopy Index your code
hub / github.com/coder/mux / useCoderWorkspace

Function useCoderWorkspace

src/browser/hooks/useCoderWorkspace.ts:94–420  ·  view source on GitHub ↗
({
  coderConfig,
  onCoderConfigChange,
  coderInfoRefreshPolicy,
}: UseCoderWorkspaceOptions)

Source from the content-addressed store, hash-verified

92 * This hook derives `enabled` from coderConfig and manages only async data.
93 */
94export function useCoderWorkspace({
95 coderConfig,
96 onCoderConfigChange,
97 coderInfoRefreshPolicy,
98}: UseCoderWorkspaceOptions): UseCoderWorkspaceReturn {
99 const { api } = useAPI();
100
101 // Async-fetched data (owned by this hook)
102 const [coderInfo, setCoderInfo] = useState<CoderInfo | null>(null);
103
104 // Derived state: enabled when coderConfig is present AND CLI is confirmed available
105 // Loading (null) and outdated/unavailable all result in enabled=false
106 const enabled = coderConfig != null && coderInfo?.state === "available";
107
108 // Refs to access current values in async callbacks (avoids stale closures)
109 const coderConfigRef = useRef(coderConfig);
110 const onCoderConfigChangeRef = useRef(onCoderConfigChange);
111 coderConfigRef.current = coderConfig;
112 onCoderConfigChangeRef.current = onCoderConfigChange;
113 const latestAuthSeqRef = useRef(0);
114 const [templates, setTemplates] = useState<CoderTemplate[]>([]);
115 const [templatesError, setTemplatesError] = useState<string | null>(null);
116 const [presets, setPresets] = useState<CoderPreset[]>([]);
117 const [presetsError, setPresetsError] = useState<string | null>(null);
118 const [existingWorkspaces, setExistingWorkspaces] = useState<CoderWorkspace[]>([]);
119 const [workspacesError, setWorkspacesError] = useState<string | null>(null);
120
121 // Loading states
122 const [loadingTemplates, setLoadingTemplates] = useState(false);
123 const [loadingPresets, setLoadingPresets] = useState(false);
124 const [loadingWorkspaces, setLoadingWorkspaces] = useState(false);
125
126 const fetchCoderInfo = useCallback(async () => {
127 // Advance sequence before the API guard so that an API context change
128 // (e.g., reconnecting -> api becomes null) invalidates any in-flight request.
129 const seq = ++latestAuthSeqRef.current;
130
131 if (!api) return;
132
133 try {
134 const info = await api.coder.getInfo();
135 if (seq !== latestAuthSeqRef.current) {
136 return;
137 }
138
139 setCoderInfo(info);
140 // Clear Coder config when CLI is not available (outdated or unavailable)
141 if (info.state !== "available" && coderConfigRef.current != null) {
142 onCoderConfigChangeRef.current(null);
143 }
144 } catch {
145 if (seq !== latestAuthSeqRef.current) {
146 return;
147 }
148
149 setCoderInfo({
150 state: "unavailable",
151 reason: { kind: "error", message: "Failed to fetch" },

Callers 3

ChatInputInnerFunction · 0.90
RuntimesSectionFunction · 0.90
renderUseCoderWorkspaceFunction · 0.90

Calls 8

useAPIFunction · 0.90
getInfoMethod · 0.80
removeEventListenerMethod · 0.80
listTemplatesMethod · 0.80
listWorkspacesMethod · 0.80
listPresetsMethod · 0.80
addEventListenerMethod · 0.45

Tested by 1

renderUseCoderWorkspaceFunction · 0.72