diff --git a/apps/canvas/front/src/components/node-app.tsx b/apps/canvas/front/src/components/node-app.tsx
index 3027f27..cfbbbde 100644
--- a/apps/canvas/front/src/components/node-app.tsx
+++ b/apps/canvas/front/src/components/node-app.tsx
@@ -1,13 +1,24 @@
 import { v4 as uuidv4 } from "uuid";
-import { NodeRect } from './node-rect';
-import { useStateStore, ServiceNode, ServiceTypes, nodeLabel, BoundEnvVar, AppState, nodeIsConnectable, GatewayTCPNode, GatewayHttpsNode, AppNode } from '@/lib/state';
-import { KeyboardEvent, FocusEvent, useCallback, useEffect, useMemo, useState } from 'react';
+import { NodeRect } from "./node-rect";
+import {
+	useStateStore,
+	ServiceNode,
+	ServiceTypes,
+	nodeLabel,
+	BoundEnvVar,
+	AppState,
+	nodeIsConnectable,
+	GatewayTCPNode,
+	GatewayHttpsNode,
+	AppNode,
+} from "@/lib/state";
+import { KeyboardEvent, FocusEvent, useCallback, useEffect, useMemo, useState } from "react";
 import { z } from "zod";
-import { DeepPartial, EventType, useForm, ControllerRenderProps, FieldPath } from 'react-hook-form';
-import { zodResolver } from '@hookform/resolvers/zod';
-import { Form, FormControl, FormField, FormItem, FormMessage } from './ui/form';
-import { Input } from './ui/input';
-import { Button } from './ui/button';
+import { DeepPartial, EventType, useForm, ControllerRenderProps, FieldPath } from "react-hook-form";
+import { zodResolver } from "@hookform/resolvers/zod";
+import { Form, FormControl, FormField, FormItem, FormMessage } from "./ui/form";
+import { Input } from "./ui/input";
+import { Button } from "./ui/button";
 import { Handle, Position, useNodes } from "@xyflow/react";
 import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "./ui/select";
 import { PencilIcon, XIcon } from "lucide-react";
@@ -15,480 +26,577 @@
 import { Textarea } from "./ui/textarea";
 
 export function NodeApp(node: ServiceNode) {
-  const { id, selected } = node;
-  const isConnectablePorts = useMemo(() => nodeIsConnectable(node, "ports"), [node]);
-  const isConnectableRepository = useMemo(() => nodeIsConnectable(node, "repository"), [node]);
-  return (
-    <NodeRect id={id} selected={selected} type={node.type} state={node.data.state}>
-      <div style={{ padding: '10px 20px' }}>
-        {nodeLabel(node)}
-        <Handle
-          id="repository"
-          type={"target"}
-          position={Position.Left}
-          isConnectableStart={isConnectableRepository}
-          isConnectableEnd={isConnectableRepository}
-          isConnectable={isConnectableRepository}
-        />
-        <Handle
-          id="ports"
-          type={"source"}
-          position={Position.Top}
-          isConnectableStart={isConnectablePorts}
-          isConnectableEnd={isConnectablePorts}
-          isConnectable={isConnectablePorts}
-        />
-        <Handle
-          id="env_var"
-          type={"target"}
-          position={Position.Bottom}
-          isConnectableStart={true}
-          isConnectableEnd={true}
-          isConnectable={true}
-        />
-      </div>
-    </NodeRect>
-  );
+	const { id, selected } = node;
+	const isConnectablePorts = useMemo(() => nodeIsConnectable(node, "ports"), [node]);
+	const isConnectableRepository = useMemo(() => nodeIsConnectable(node, "repository"), [node]);
+	return (
+		<NodeRect id={id} selected={selected} type={node.type} state={node.data.state}>
+			<div style={{ padding: "10px 20px" }}>
+				{nodeLabel(node)}
+				<Handle
+					id="repository"
+					type={"target"}
+					position={Position.Left}
+					isConnectableStart={isConnectableRepository}
+					isConnectableEnd={isConnectableRepository}
+					isConnectable={isConnectableRepository}
+				/>
+				<Handle
+					id="ports"
+					type={"source"}
+					position={Position.Top}
+					isConnectableStart={isConnectablePorts}
+					isConnectableEnd={isConnectablePorts}
+					isConnectable={isConnectablePorts}
+				/>
+				<Handle
+					id="env_var"
+					type={"target"}
+					position={Position.Bottom}
+					isConnectableStart={true}
+					isConnectableEnd={true}
+					isConnectable={true}
+				/>
+			</div>
+		</NodeRect>
+	);
 }
 
 const schema = z.object({
-  name: z.string().min(1, "requried"),
-  type: z.enum(ServiceTypes),
+	name: z.string().min(1, "requried"),
+	type: z.enum(ServiceTypes),
 });
 
 const portSchema = z.object({
-  name: z.string().min(1, "required"),
-  value: z.coerce.number().gt(0, "can not be negative"),
+	name: z.string().min(1, "required"),
+	value: z.coerce.number().gt(0, "can not be negative"),
 });
 
 const sourceSchema = z.object({
-  id: z.string().min(1, "required"),
-  branch: z.string(),
-  rootDir: z.string(),
+	id: z.string().min(1, "required"),
+	branch: z.string(),
+	rootDir: z.string(),
 });
 
 export function NodeAppDetails({ id, data }: ServiceNode) {
-  const store = useStateStore();
-  const nodes = useNodes<AppNode>();
-  const form = useForm<z.infer<typeof schema>>({
-    resolver: zodResolver(schema),
-    mode: "onChange",
-    defaultValues: {
-      name: data.label,
-      type: data.type,
-    }
-  });
-  const portForm = useForm<z.infer<typeof portSchema>>({
-    resolver: zodResolver(portSchema),
-    mode: "onSubmit",
-    defaultValues: {
-      name: "",
-      value: 0,
-    }
-  });
-  const onSubmit = useCallback((values: z.infer<typeof portSchema>) => {
-    const portId = uuidv4();
-    store.updateNodeData<"app">(id, {
-      ports: (data.ports || []).concat({
-        id: portId,
-        name: values.name,
-        value: values.value,
-      }),
-      envVars: (data.envVars || []).concat({
-        id: uuidv4(),
-        source: null,
-        portId,
-        name: `DODO_PORT_${values.name.toUpperCase()}`,
-      }),
-    });
-    portForm.reset();
-  }, [id, data, portForm, store]);
-  useEffect(() => {
-    const sub = form.watch((value: DeepPartial<z.infer<typeof schema>>, { name, type }: { name?: keyof z.infer<typeof schema> | undefined, type?: EventType | undefined }) => {
-      console.log({ name, type });
-      if (type !== "change") {
-        return;
-      }
-      switch (name) {
-        case "name":
-          if (!value.name) {
-            break;
-          }
-          store.updateNodeData<"app">(id, {
-            label: value.name,
-          });
-          break;
-        case "type":
-          if (!value.type) {
-            break;
-          }
-          store.updateNodeData<"app">(id, {
-            type: value.type,
-          })
-          break;
-      }
-    });
-    return () => sub.unsubscribe();
-  }, [id, form, store]);
-  const focus = useCallback((field: ControllerRenderProps<z.infer<typeof schema>, FieldPath<z.infer<typeof schema>>>, name: string) => {
-    return (e: HTMLElement | null) => {
-      field.ref(e);
-      if (e != null && name === data.activeField) {
-        console.log(e);
-        e.focus();
-        store.updateNodeData(id, {
-          activeField: undefined,
-        });
-      }
-    }
-  }, [id, data, store]);
-  const [typeProps, setTypeProps] = useState({});
-  useEffect(() => {
-    if (data.activeField === "type") {
-      setTypeProps({
-        open: true,
-        onOpenChange: () => store.updateNodeData(id, { activeField: undefined }),
-      });
-    } else {
-      setTypeProps({});
-    }
-  }, [id, data, store, setTypeProps]);
-  const editAlias = useCallback((e: BoundEnvVar) => {
-    return () => {
-      store.updateNodeData(id, {
-        ...data,
-        envVars: data.envVars!.map((o) => {
-          if (o.id !== e.id) {
-            return o;
-          } else return {
-            ...o,
-            isEditting: true,
-          }
-        }),
-      });
-    };
-  }, [id, data, store]);
-  const saveAlias = useCallback((e: BoundEnvVar, value: string, store: AppState) => {
-    store.updateNodeData(id, {
-      ...data,
-      envVars: data.envVars!.map((o) => {
-        if (o.id !== e.id) {
-          return o;
-        }
-        if (value) {
-          return {
-            ...o,
-            isEditting: false,
-            alias: value.toUpperCase(),
-          }
-        }
-        console.log(o);
-        if ("alias" in o) {
-          const { alias: _, ...rest } = o;
-          console.log(rest);
-          return {
-            ...rest,
-            isEditting: false,
-          };
-        }
-        return {
-          ...o,
-          isEditting: false,
-        };
-      }),
-    });
-  }, [id, data]);
-  const saveAliasOnEnter = useCallback((e: BoundEnvVar) => {
-    return (event: KeyboardEvent<HTMLInputElement>) => {
-      if (event.key === "Enter") {
-        event.preventDefault();
-        saveAlias(e, event.currentTarget.value, store);
-      }
-    }
-  }, [store, saveAlias]);
-  const saveAliasOnBlur = useCallback((e: BoundEnvVar) => {
-    return (event: FocusEvent<HTMLInputElement>) => {
-      saveAlias(e, event.currentTarget.value, store);
-    }
-  }, [store, saveAlias]);
-  const removePort = useCallback((portId: string) => {
-    // TODO(gio): this is ugly
-    const tcpRemoved = new Set<string>();
-    console.log(store.edges);
-    store.setEdges(store.edges.filter((e) => {
-      if (e.source !== id || e.sourceHandle !== "ports") {
-        return true;
-      }
-      const tn = store.nodes.find((n) => n.id == e.target)!;
-      if (e.targetHandle === "https") {
-        const t = tn as GatewayHttpsNode;
-        if (t.data.https?.serviceId === id && t.data.https.portId === portId) {
-          return false;
-        }
-      }
-      if (e.targetHandle === "tcp") {
-        const t = tn as GatewayTCPNode;
-        if (tcpRemoved.has(t.id)) {
-          return true;
-        }
-        if (t.data.exposed.find((e) => e.serviceId === id && e.portId === portId)) {
-          tcpRemoved.add(t.id);
-          return false;
-        }
-      }
-      if (e.targetHandle === "env_var") {
-        if (tn && (tn.data.envVars || []).find((ev) => ev.source === id && "portId" in ev && ev.portId === portId)) {
-          return false;
-        }
-      }
-      return true;
-    }));
-    store.nodes.filter((n) => n.type === "gateway-https" && n.data.https && n.data.https.serviceId === id && n.data.https.portId === portId).forEach((n) => {
-      store.updateNodeData<"gateway-https">(n.id, {
-        https: undefined,
-      });
-    });
-    store.nodes.filter((n) => n.type === "gateway-tcp").forEach((n) => {
-      const filtered = n.data.exposed.filter((e) => {
-        if (e.serviceId === id && e.portId === portId) {
-          return false;
-        } else {
-          return true;
-        }
-      })
-      if (filtered.length != n.data.exposed.length) {
-        store.updateNodeData<"gateway-tcp">(n.id, {
-          exposed: filtered,
-        });
-      }
-    });
-    store.nodes.filter((n) => n.type === "app" && n.data.envVars).forEach((n) => {
-      store.updateNodeData<"app">(n.id, {
-        envVars: n.data.envVars.filter((ev) => {
-          if (ev.source === id && "portId" in ev && ev.portId === portId) {
-            return false;
-          }
-          return true;
-        })
-      });
-    });
-    store.updateNodeData<"app">(id, {
-      ports: (data.ports || []).filter((p) => p.id !== portId),
-      envVars: (data.envVars || []).filter((ev) => !(ev.source === null && "portId" in ev && ev.portId === portId)),
-    });
-  }, [id, data, store]);
-  const setPreBuildCommands = useCallback((e: React.ChangeEvent<HTMLTextAreaElement>) => {
-    store.updateNodeData<"app">(id, {
-      preBuildCommands: e.currentTarget.value,
-    });
-  }, [id, store]);
+	const store = useStateStore();
+	const nodes = useNodes<AppNode>();
+	const form = useForm<z.infer<typeof schema>>({
+		resolver: zodResolver(schema),
+		mode: "onChange",
+		defaultValues: {
+			name: data.label,
+			type: data.type,
+		},
+	});
+	const portForm = useForm<z.infer<typeof portSchema>>({
+		resolver: zodResolver(portSchema),
+		mode: "onSubmit",
+		defaultValues: {
+			name: "",
+			value: 0,
+		},
+	});
+	const onSubmit = useCallback(
+		(values: z.infer<typeof portSchema>) => {
+			const portId = uuidv4();
+			store.updateNodeData<"app">(id, {
+				ports: (data.ports || []).concat({
+					id: portId,
+					name: values.name,
+					value: values.value,
+				}),
+				envVars: (data.envVars || []).concat({
+					id: uuidv4(),
+					source: null,
+					portId,
+					name: `DODO_PORT_${values.name.toUpperCase()}`,
+				}),
+			});
+			portForm.reset();
+		},
+		[id, data, portForm, store],
+	);
+	useEffect(() => {
+		const sub = form.watch(
+			(
+				value: DeepPartial<z.infer<typeof schema>>,
+				{ name, type }: { name?: keyof z.infer<typeof schema> | undefined; type?: EventType | undefined },
+			) => {
+				console.log({ name, type });
+				if (type !== "change") {
+					return;
+				}
+				switch (name) {
+					case "name":
+						if (!value.name) {
+							break;
+						}
+						store.updateNodeData<"app">(id, {
+							label: value.name,
+						});
+						break;
+					case "type":
+						if (!value.type) {
+							break;
+						}
+						store.updateNodeData<"app">(id, {
+							type: value.type,
+						});
+						break;
+				}
+			},
+		);
+		return () => sub.unsubscribe();
+	}, [id, form, store]);
+	const focus = useCallback(
+		(field: ControllerRenderProps<z.infer<typeof schema>, FieldPath<z.infer<typeof schema>>>, name: string) => {
+			return (e: HTMLElement | null) => {
+				field.ref(e);
+				if (e != null && name === data.activeField) {
+					console.log(e);
+					e.focus();
+					store.updateNodeData(id, {
+						activeField: undefined,
+					});
+				}
+			};
+		},
+		[id, data, store],
+	);
+	const [typeProps, setTypeProps] = useState({});
+	useEffect(() => {
+		if (data.activeField === "type") {
+			setTypeProps({
+				open: true,
+				onOpenChange: () => store.updateNodeData(id, { activeField: undefined }),
+			});
+		} else {
+			setTypeProps({});
+		}
+	}, [id, data, store, setTypeProps]);
+	const editAlias = useCallback(
+		(e: BoundEnvVar) => {
+			return () => {
+				store.updateNodeData(id, {
+					...data,
+					envVars: data.envVars!.map((o) => {
+						if (o.id !== e.id) {
+							return o;
+						} else
+							return {
+								...o,
+								isEditting: true,
+							};
+					}),
+				});
+			};
+		},
+		[id, data, store],
+	);
+	const saveAlias = useCallback(
+		(e: BoundEnvVar, value: string, store: AppState) => {
+			store.updateNodeData(id, {
+				...data,
+				envVars: data.envVars!.map((o) => {
+					if (o.id !== e.id) {
+						return o;
+					}
+					if (value) {
+						return {
+							...o,
+							isEditting: false,
+							alias: value.toUpperCase(),
+						};
+					}
+					console.log(o);
+					if ("alias" in o) {
+						const { alias: _, ...rest } = o;
+						console.log(rest);
+						return {
+							...rest,
+							isEditting: false,
+						};
+					}
+					return {
+						...o,
+						isEditting: false,
+					};
+				}),
+			});
+		},
+		[id, data],
+	);
+	const saveAliasOnEnter = useCallback(
+		(e: BoundEnvVar) => {
+			return (event: KeyboardEvent<HTMLInputElement>) => {
+				if (event.key === "Enter") {
+					event.preventDefault();
+					saveAlias(e, event.currentTarget.value, store);
+				}
+			};
+		},
+		[store, saveAlias],
+	);
+	const saveAliasOnBlur = useCallback(
+		(e: BoundEnvVar) => {
+			return (event: FocusEvent<HTMLInputElement>) => {
+				saveAlias(e, event.currentTarget.value, store);
+			};
+		},
+		[store, saveAlias],
+	);
+	const removePort = useCallback(
+		(portId: string) => {
+			// TODO(gio): this is ugly
+			const tcpRemoved = new Set<string>();
+			console.log(store.edges);
+			store.setEdges(
+				store.edges.filter((e) => {
+					if (e.source !== id || e.sourceHandle !== "ports") {
+						return true;
+					}
+					const tn = store.nodes.find((n) => n.id == e.target)!;
+					if (e.targetHandle === "https") {
+						const t = tn as GatewayHttpsNode;
+						if (t.data.https?.serviceId === id && t.data.https.portId === portId) {
+							return false;
+						}
+					}
+					if (e.targetHandle === "tcp") {
+						const t = tn as GatewayTCPNode;
+						if (tcpRemoved.has(t.id)) {
+							return true;
+						}
+						if (t.data.exposed.find((e) => e.serviceId === id && e.portId === portId)) {
+							tcpRemoved.add(t.id);
+							return false;
+						}
+					}
+					if (e.targetHandle === "env_var") {
+						if (
+							tn &&
+							(tn.data.envVars || []).find(
+								(ev) => ev.source === id && "portId" in ev && ev.portId === portId,
+							)
+						) {
+							return false;
+						}
+					}
+					return true;
+				}),
+			);
+			store.nodes
+				.filter(
+					(n) =>
+						n.type === "gateway-https" &&
+						n.data.https &&
+						n.data.https.serviceId === id &&
+						n.data.https.portId === portId,
+				)
+				.forEach((n) => {
+					store.updateNodeData<"gateway-https">(n.id, {
+						https: undefined,
+					});
+				});
+			store.nodes
+				.filter((n) => n.type === "gateway-tcp")
+				.forEach((n) => {
+					const filtered = n.data.exposed.filter((e) => {
+						if (e.serviceId === id && e.portId === portId) {
+							return false;
+						} else {
+							return true;
+						}
+					});
+					if (filtered.length != n.data.exposed.length) {
+						store.updateNodeData<"gateway-tcp">(n.id, {
+							exposed: filtered,
+						});
+					}
+				});
+			store.nodes
+				.filter((n) => n.type === "app" && n.data.envVars)
+				.forEach((n) => {
+					store.updateNodeData<"app">(n.id, {
+						envVars: n.data.envVars.filter((ev) => {
+							if (ev.source === id && "portId" in ev && ev.portId === portId) {
+								return false;
+							}
+							return true;
+						}),
+					});
+				});
+			store.updateNodeData<"app">(id, {
+				ports: (data.ports || []).filter((p) => p.id !== portId),
+				envVars: (data.envVars || []).filter(
+					(ev) => !(ev.source === null && "portId" in ev && ev.portId === portId),
+				),
+			});
+		},
+		[id, data, store],
+	);
+	const setPreBuildCommands = useCallback(
+		(e: React.ChangeEvent<HTMLTextAreaElement>) => {
+			store.updateNodeData<"app">(id, {
+				preBuildCommands: e.currentTarget.value,
+			});
+		},
+		[id, store],
+	);
 
-  const sourceForm = useForm<z.infer<typeof sourceSchema>>({
-    resolver: zodResolver(sourceSchema),
-    mode: "onChange",
-    defaultValues: {
-      id: data?.repository?.id,
-      branch: data.repository && "branch" in data.repository ? data.repository.branch : undefined,
-      rootDir: data.repository && "rootDir" in data.repository ? data.repository.rootDir : undefined,
-    },
-  });
-  useEffect(() => {
-    const sub = sourceForm.watch((value: DeepPartial<z.infer<typeof sourceSchema>>, { name }: { name?: keyof z.infer<typeof sourceSchema> | undefined, type?: EventType | undefined }) => {
-      console.log(value);
-      if (name === "id") {
-        let edges = store.edges;
-        if (data?.repository?.id !== undefined) {
-          edges = edges.filter((e) => {
-            if (e.target === id && e.targetHandle === "repository" && e.source === data.repository.id) {
-              return false;
-            } else {
-              return true;
-            }
-          });
-        }
-        if (value.id !== undefined) {
-          edges = edges.concat({
-            id: uuidv4(),
-            source: value.id,
-            sourceHandle: "repository",
-            target: id,
-            targetHandle: "repository",
-          });
-        }
-        store.setEdges(edges);
-        store.updateNodeData<"app">(id, {
-          repository: {
-            id: value.id,
-          },
-        });
-      } else if (name === "branch") {
-        store.updateNodeData<"app">(id, {
-          repository: {
-            ...data?.repository,
-            branch: value.branch,
-          },
-        });
-      } else if (name === "rootDir") {
-        store.updateNodeData<"app">(id, {
-          repository: {
-            ...data?.repository,
-            rootDir: value.rootDir,
-          },
-        });
-      }
-    });
-    return () => sub.unsubscribe();
-  }, [id, data, sourceForm, store]);
+	const sourceForm = useForm<z.infer<typeof sourceSchema>>({
+		resolver: zodResolver(sourceSchema),
+		mode: "onChange",
+		defaultValues: {
+			id: data?.repository?.id,
+			branch: data.repository && "branch" in data.repository ? data.repository.branch : undefined,
+			rootDir: data.repository && "rootDir" in data.repository ? data.repository.rootDir : undefined,
+		},
+	});
+	useEffect(() => {
+		const sub = sourceForm.watch(
+			(
+				value: DeepPartial<z.infer<typeof sourceSchema>>,
+				{ name }: { name?: keyof z.infer<typeof sourceSchema> | undefined; type?: EventType | undefined },
+			) => {
+				console.log(value);
+				if (name === "id") {
+					let edges = store.edges;
+					if (data?.repository?.id !== undefined) {
+						edges = edges.filter((e) => {
+							if (e.target === id && e.targetHandle === "repository" && e.source === data.repository.id) {
+								return false;
+							} else {
+								return true;
+							}
+						});
+					}
+					if (value.id !== undefined) {
+						edges = edges.concat({
+							id: uuidv4(),
+							source: value.id,
+							sourceHandle: "repository",
+							target: id,
+							targetHandle: "repository",
+						});
+					}
+					store.setEdges(edges);
+					store.updateNodeData<"app">(id, {
+						repository: {
+							id: value.id,
+						},
+					});
+				} else if (name === "branch") {
+					store.updateNodeData<"app">(id, {
+						repository: {
+							...data?.repository,
+							branch: value.branch,
+						},
+					});
+				} else if (name === "rootDir") {
+					store.updateNodeData<"app">(id, {
+						repository: {
+							...data?.repository,
+							rootDir: value.rootDir,
+						},
+					});
+				}
+			},
+		);
+		return () => sub.unsubscribe();
+	}, [id, data, sourceForm, store]);
 
-  return (
-    <>
-      <Form {...form}>
-        <form>
-          <FormField
-            control={form.control}
-            name="name"
-            render={({ field }) => (
-              <FormItem>
-                <FormControl>
-                  <Input placeholder="name" className="border border-black" {...field} ref={focus(field, "name")} />
-                </FormControl>
-                <FormMessage />
-              </FormItem>
-            )}
-          />
-          <FormField
-            control={form.control}
-            name="type"
-            render={({ field }) => (
-              <FormItem>
-                <Select onValueChange={field.onChange} defaultValue={field.value} {...typeProps}>
-                  <FormControl>
-                    <SelectTrigger>
-                      <SelectValue placeholder="Runtime" />
-                    </SelectTrigger>
-                  </FormControl>
-                  <SelectContent>
-                    {ServiceTypes.map((t) => (
-                      <SelectItem key={t} value={t}>{t}</SelectItem>
-                    ))}
-                  </SelectContent>
-                </Select>
-                <FormMessage />
-              </FormItem>
-            )}
-          />
-        </form>
-      </Form>
-      Source
-      <Form {...sourceForm}>
-        <form className="space-y-2">
-          <FormField
-            control={sourceForm.control}
-            name="id"
-            render={({ field }) => (
-              <FormItem>
-                <Select onValueChange={field.onChange} defaultValue={field.value}>
-                  <FormControl>
-                    <SelectTrigger>
-                      <SelectValue placeholder="Repository" />
-                    </SelectTrigger>
-                  </FormControl>
-                  <SelectContent>
-                    {(nodes.filter((n) => n.type === "github" && n.data.repository?.id !== undefined) as GithubNode[]).map((n) => (
-                      <SelectItem key={n.id} value={n.id}>{`${n.data.repository?.sshURL}`}</SelectItem>
-                    ))}
-                  </SelectContent>
-                </Select>
-                <FormMessage />
-              </FormItem>
-            )}
-          />
-          <FormField
-            control={sourceForm.control}
-            name="branch"
-            render={({ field }) => (
-              <FormItem>
-                <FormControl>
-                  <Input placeholder="master" className="border border-black" {...field} />
-                </FormControl>
-                <FormMessage />
-              </FormItem>
-            )}
-          />
-          <FormField
-            control={sourceForm.control}
-            name="rootDir"
-            render={({ field }) => (
-              <FormItem>
-                <FormControl>
-                  <Input placeholder="/" className="border border-black" {...field} />
-                </FormControl>
-                <FormMessage />
-              </FormItem>
-            )}
-          />
-        </form>
-      </Form>
-      Ports
-      <ul>
-        {data && data.ports && data.ports.map((p) => (<li key={p.id}><Button size={"icon"} variant={"ghost"} onClick={() => removePort(p.id)}><XIcon /></Button> {p.name} - {p.value}</li>))}
-      </ul>
-      <Form {...portForm}>
-        <form className="flex flex-row space-x-1" onSubmit={portForm.handleSubmit(onSubmit)}>
-          <FormField
-            control={portForm.control}
-            name="name"
-            render={({ field }) => (
-              <FormItem>
-                <FormControl>
-                  <Input placeholder="name" className="border border-black" {...field} />
-                </FormControl>
-                <FormMessage />
-              </FormItem>
-            )}
-          />
-          <FormField
-            control={portForm.control}
-            name="value"
-            render={({ field }) => (
-              <FormItem>
-                <FormControl>
-                  <Input placeholder="value" className="border border-black" {...field} />
-                </FormControl>
-                <FormMessage />
-              </FormItem>
-            )}
-          />
-          <Button type="submit">Add Port</Button>
-        </form>
-      </Form>
-      Env Vars
-      <ul>
-        {data && data.envVars && data.envVars.map((v) => {
-          if ("name" in v) {
-            const value = "alias" in v ? v.alias : v.name;
-            if (v.isEditting) {
-              return (<li key={v.id}><Input type="text" className="border border-black" defaultValue={value} onKeyUp={saveAliasOnEnter(v)} onBlur={saveAliasOnBlur(v)} autoFocus={true} /></li>);
-            }
-            return (
-              <li key={v.id} onClick={editAlias(v)}>
-                <TooltipProvider>
-                  <Tooltip>
-                    <TooltipTrigger>
-                      <Button size={"icon"} variant={"ghost"}><PencilIcon /></Button>
-                      {value}
-                    </TooltipTrigger>
-                    <TooltipContent>
-                      {v.name}
-                    </TooltipContent>
-                  </Tooltip>
-                </TooltipProvider>
-              </li>
-            );
-          }
-        })}
-      </ul>
-      Pre-Build Commands
-      <Textarea placeholder="new line separated list of commands to run before running the service" value={data.preBuildCommands} onChange={setPreBuildCommands} />
-    </>);
-}
\ No newline at end of file
+	return (
+		<>
+			<Form {...form}>
+				<form>
+					<FormField
+						control={form.control}
+						name="name"
+						render={({ field }) => (
+							<FormItem>
+								<FormControl>
+									<Input
+										placeholder="name"
+										className="border border-black"
+										{...field}
+										ref={focus(field, "name")}
+									/>
+								</FormControl>
+								<FormMessage />
+							</FormItem>
+						)}
+					/>
+					<FormField
+						control={form.control}
+						name="type"
+						render={({ field }) => (
+							<FormItem>
+								<Select onValueChange={field.onChange} defaultValue={field.value} {...typeProps}>
+									<FormControl>
+										<SelectTrigger>
+											<SelectValue placeholder="Runtime" />
+										</SelectTrigger>
+									</FormControl>
+									<SelectContent>
+										{ServiceTypes.map((t) => (
+											<SelectItem key={t} value={t}>
+												{t}
+											</SelectItem>
+										))}
+									</SelectContent>
+								</Select>
+								<FormMessage />
+							</FormItem>
+						)}
+					/>
+				</form>
+			</Form>
+			Source
+			<Form {...sourceForm}>
+				<form className="space-y-2">
+					<FormField
+						control={sourceForm.control}
+						name="id"
+						render={({ field }) => (
+							<FormItem>
+								<Select onValueChange={field.onChange} defaultValue={field.value}>
+									<FormControl>
+										<SelectTrigger>
+											<SelectValue placeholder="Repository" />
+										</SelectTrigger>
+									</FormControl>
+									<SelectContent>
+										{(
+											nodes.filter(
+												(n) => n.type === "github" && n.data.repository?.id !== undefined,
+											) as GithubNode[]
+										).map((n) => (
+											<SelectItem
+												key={n.id}
+												value={n.id}
+											>{`${n.data.repository?.sshURL}`}</SelectItem>
+										))}
+									</SelectContent>
+								</Select>
+								<FormMessage />
+							</FormItem>
+						)}
+					/>
+					<FormField
+						control={sourceForm.control}
+						name="branch"
+						render={({ field }) => (
+							<FormItem>
+								<FormControl>
+									<Input placeholder="master" className="border border-black" {...field} />
+								</FormControl>
+								<FormMessage />
+							</FormItem>
+						)}
+					/>
+					<FormField
+						control={sourceForm.control}
+						name="rootDir"
+						render={({ field }) => (
+							<FormItem>
+								<FormControl>
+									<Input placeholder="/" className="border border-black" {...field} />
+								</FormControl>
+								<FormMessage />
+							</FormItem>
+						)}
+					/>
+				</form>
+			</Form>
+			Ports
+			<ul>
+				{data &&
+					data.ports &&
+					data.ports.map((p) => (
+						<li key={p.id}>
+							<Button size={"icon"} variant={"ghost"} onClick={() => removePort(p.id)}>
+								<XIcon />
+							</Button>{" "}
+							{p.name} - {p.value}
+						</li>
+					))}
+			</ul>
+			<Form {...portForm}>
+				<form className="flex flex-row space-x-1" onSubmit={portForm.handleSubmit(onSubmit)}>
+					<FormField
+						control={portForm.control}
+						name="name"
+						render={({ field }) => (
+							<FormItem>
+								<FormControl>
+									<Input placeholder="name" className="border border-black" {...field} />
+								</FormControl>
+								<FormMessage />
+							</FormItem>
+						)}
+					/>
+					<FormField
+						control={portForm.control}
+						name="value"
+						render={({ field }) => (
+							<FormItem>
+								<FormControl>
+									<Input placeholder="value" className="border border-black" {...field} />
+								</FormControl>
+								<FormMessage />
+							</FormItem>
+						)}
+					/>
+					<Button type="submit">Add Port</Button>
+				</form>
+			</Form>
+			Env Vars
+			<ul>
+				{data &&
+					data.envVars &&
+					data.envVars.map((v) => {
+						if ("name" in v) {
+							const value = "alias" in v ? v.alias : v.name;
+							if (v.isEditting) {
+								return (
+									<li key={v.id}>
+										<Input
+											type="text"
+											className="border border-black"
+											defaultValue={value}
+											onKeyUp={saveAliasOnEnter(v)}
+											onBlur={saveAliasOnBlur(v)}
+											autoFocus={true}
+										/>
+									</li>
+								);
+							}
+							return (
+								<li key={v.id} onClick={editAlias(v)}>
+									<TooltipProvider>
+										<Tooltip>
+											<TooltipTrigger>
+												<Button size={"icon"} variant={"ghost"}>
+													<PencilIcon />
+												</Button>
+												{value}
+											</TooltipTrigger>
+											<TooltipContent>{v.name}</TooltipContent>
+										</Tooltip>
+									</TooltipProvider>
+								</li>
+							);
+						}
+					})}
+			</ul>
+			Pre-Build Commands
+			<Textarea
+				placeholder="new line separated list of commands to run before running the service"
+				value={data.preBuildCommands}
+				onChange={setPreBuildCommands}
+			/>
+		</>
+	);
+}
