diff options
| author | Adam <[email protected]> | 2026-01-22 18:07:48 -0600 |
|---|---|---|
| committer | Adam <[email protected]> | 2026-01-22 18:07:57 -0600 |
| commit | bcf7a65e36af1437cda556577a275dd8531afd0d (patch) | |
| tree | a370d10879d11c8efcf161f1b73526a464c40ea8 /packages/app/src/context | |
| parent | 7c80ac072bd1b42e4ea962ad47b049606b015ebb (diff) | |
| download | opencode-bcf7a65e36af1437cda556577a275dd8531afd0d.tar.gz opencode-bcf7a65e36af1437cda556577a275dd8531afd0d.zip | |
fix(app): non-git projects should be renameable
Diffstat (limited to 'packages/app/src/context')
| -rw-r--r-- | packages/app/src/context/global-sync.tsx | 56 | ||||
| -rw-r--r-- | packages/app/src/context/layout.tsx | 21 |
2 files changed, 76 insertions, 1 deletions
diff --git a/packages/app/src/context/global-sync.tsx b/packages/app/src/context/global-sync.tsx index 4964ef6e4..ec072e7be 100644 --- a/packages/app/src/context/global-sync.tsx +++ b/packages/app/src/context/global-sync.tsx @@ -44,11 +44,23 @@ import { usePlatform } from "./platform" import { useLanguage } from "@/context/language" import { Persist, persisted } from "@/utils/persist" +type ProjectMeta = { + name?: string + icon?: { + override?: string + color?: string + } + commands?: { + start?: string + } +} + type State = { status: "loading" | "partial" | "complete" agent: Agent[] command: Command[] project: string + projectMeta: ProjectMeta | undefined provider: ProviderListResponse config: Config path: Path @@ -89,6 +101,12 @@ type VcsCache = { ready: Accessor<boolean> } +type MetaCache = { + store: Store<{ value: ProjectMeta | undefined }> + setStore: SetStoreFunction<{ value: ProjectMeta | undefined }> + ready: Accessor<boolean> +} + type ChildOptions = { bootstrap?: boolean } @@ -100,6 +118,7 @@ function createGlobalSync() { const owner = getOwner() if (!owner) throw new Error("GlobalSync must be created within owner") const vcsCache = new Map<string, VcsCache>() + const metaCache = new Map<string, MetaCache>() const [globalStore, setGlobalStore] = createStore<{ ready: boolean error?: InitError @@ -149,9 +168,19 @@ function createGlobalSync() { if (!cache) throw new Error("Failed to create persisted cache") vcsCache.set(directory, { store: cache[0], setStore: cache[1], ready: cache[3] }) + const meta = runWithOwner(owner, () => + persisted( + Persist.workspace(directory, "project", ["project.v1"]), + createStore({ value: undefined as ProjectMeta | undefined }), + ), + ) + if (!meta) throw new Error("Failed to create persisted project metadata") + metaCache.set(directory, { store: meta[0], setStore: meta[1], ready: meta[3] }) + const init = () => { children[directory] = createStore<State>({ project: "", + projectMeta: meta[0].value, provider: { all: [], connected: [], default: {} }, config: {}, path: { state: "", config: "", worktree: "", directory: "", home: "" }, @@ -253,6 +282,8 @@ function createGlobalSync() { const [store, setStore] = ensureChild(directory) const cache = vcsCache.get(directory) if (!cache) return + const meta = metaCache.get(directory) + if (!meta) return const sdk = createOpencodeClient({ baseUrl: globalSDK.url, fetch: platform.fetch, @@ -269,6 +300,13 @@ function createGlobalSync() { setStore("vcs", (value) => value ?? cached) }) + createEffect(() => { + if (!meta.ready()) return + const cached = meta.store.value + if (!cached) return + setStore("projectMeta", (value) => value ?? cached) + }) + const blockingRequests = { project: () => sdk.project.current().then((x) => setStore("project", x.data!.id)), provider: () => @@ -725,6 +763,23 @@ function createGlobalSync() { bootstrap() }) + function projectMeta(directory: string, patch: ProjectMeta) { + const [store, setStore] = ensureChild(directory) + const cached = metaCache.get(directory) + if (!cached) return + const previous = store.projectMeta ?? {} + const icon = patch.icon ? { ...(previous.icon ?? {}), ...patch.icon } : previous.icon + const commands = patch.commands ? { ...(previous.commands ?? {}), ...patch.commands } : previous.commands + const next = { + ...previous, + ...patch, + icon, + commands, + } + cached.setStore("value", next) + setStore("projectMeta", next) + } + return { data: globalStore, set: setGlobalStore, @@ -746,6 +801,7 @@ function createGlobalSync() { }, project: { loadSessions, + meta: projectMeta, }, } } diff --git a/packages/app/src/context/layout.tsx b/packages/app/src/context/layout.tsx index 7a3556290..3c544b069 100644 --- a/packages/app/src/context/layout.tsx +++ b/packages/app/src/context/layout.tsx @@ -222,7 +222,8 @@ export const { use: useLayout, provider: LayoutProvider } = createSimpleContext( const metadata = projectID ? globalSync.data.project.find((x) => x.id === projectID) : globalSync.data.project.find((x) => x.worktree === project.worktree) - return { + + const base = { ...(metadata ?? {}), ...project, icon: { @@ -231,6 +232,20 @@ export const { use: useLayout, provider: LayoutProvider } = createSimpleContext( color: metadata?.icon?.color, }, } + + if (projectID !== "global") return base + + const local = childStore.projectMeta + return { + ...base, + name: local?.name, + commands: local?.commands, + icon: { + url: base.icon?.url, + override: local?.icon?.override, + color: local?.icon?.color, + }, + } } const roots = createMemo(() => { @@ -296,6 +311,10 @@ export const { use: useLayout, provider: LayoutProvider } = createSimpleContext( used.add(color) setColors(project.worktree, color) if (!project.id) continue + if (project.id === "global") { + globalSync.project.meta(project.worktree, { icon: { color } }) + continue + } void globalSdk.client.project.update({ projectID: project.id, directory: project.worktree, icon: { color } }) } }) |
