diff --git a/v2/src-tauri/src/ctx.rs b/v2/src-tauri/src/ctx.rs index f20c731..1f07fc1 100644 --- a/v2/src-tauri/src/ctx.rs +++ b/v2/src-tauri/src/ctx.rs @@ -141,6 +141,24 @@ impl CtxDb { Ok(()) } + /// Register a project in the ctx database (creates if not exists). + pub fn register_project(&self, name: &str, description: &str, work_dir: Option<&str>) -> Result<(), String> { + let db_path = Self::db_path(); + if !db_path.exists() { + return Err("ctx database not found".to_string()); + } + + let conn = Connection::open(&db_path) + .map_err(|e| format!("Failed to open database: {e}"))?; + + conn.execute( + "INSERT OR IGNORE INTO sessions (name, description, work_dir) VALUES (?1, ?2, ?3)", + rusqlite::params![name, description, work_dir], + ).map_err(|e| format!("Failed to register project: {e}"))?; + + Ok(()) + } + pub fn list_projects(&self) -> Result, String> { let lock = self.conn.lock().unwrap(); let conn = lock.as_ref().ok_or("ctx database not found")?; diff --git a/v2/src-tauri/src/lib.rs b/v2/src-tauri/src/lib.rs index c7989f5..239e017 100644 --- a/v2/src-tauri/src/lib.rs +++ b/v2/src-tauri/src/lib.rs @@ -187,6 +187,11 @@ fn ctx_init_db(state: State<'_, AppState>) -> Result<(), String> { state.ctx_db.init_db() } +#[tauri::command] +fn ctx_register_project(state: State<'_, AppState>, name: String, description: String, work_dir: Option) -> Result<(), String> { + state.ctx_db.register_project(&name, &description, work_dir.as_deref()) +} + #[tauri::command] fn ctx_list_projects(state: State<'_, AppState>) -> Result, String> { state.ctx_db.list_projects() @@ -545,6 +550,7 @@ pub fn run() { ssh_session_save, ssh_session_delete, ctx_init_db, + ctx_register_project, ctx_list_projects, ctx_get_context, ctx_get_shared, diff --git a/v2/src/lib/adapters/ctx-bridge.ts b/v2/src/lib/adapters/ctx-bridge.ts index ad435fa..66e2212 100644 --- a/v2/src/lib/adapters/ctx-bridge.ts +++ b/v2/src/lib/adapters/ctx-bridge.ts @@ -24,6 +24,10 @@ export async function ctxInitDb(): Promise { return invoke('ctx_init_db'); } +export async function ctxRegisterProject(name: string, description: string, workDir?: string): Promise { + return invoke('ctx_register_project', { name, description, workDir: workDir ?? null }); +} + export async function ctxListProjects(): Promise { return invoke('ctx_list_projects'); } diff --git a/v2/src/lib/components/Context/ContextPane.svelte b/v2/src/lib/components/Context/ContextPane.svelte index 10958a5..9679ada 100644 --- a/v2/src/lib/components/Context/ContextPane.svelte +++ b/v2/src/lib/components/Context/ContextPane.svelte @@ -2,24 +2,22 @@ import { onMount } from 'svelte'; import { ctxInitDb, - ctxListProjects, + ctxRegisterProject, ctxGetContext, ctxGetShared, ctxGetSummaries, ctxSearch, - type CtxProject, type CtxEntry, type CtxSummary, } from '../../adapters/ctx-bridge'; interface Props { - onExit?: () => void; + projectName: string; + projectCwd: string; } - let { onExit }: Props = $props(); + let { projectName, projectCwd }: Props = $props(); - let projects = $state([]); - let selectedProject = $state(null); let entries = $state([]); let sharedEntries = $state([]); let summaries = $state([]); @@ -30,15 +28,27 @@ let dbMissing = $state(false); let initializing = $state(false); - async function loadData() { + async function loadProjectContext() { + loading = true; try { - projects = await ctxListProjects(); - sharedEntries = await ctxGetShared(); + // Register project if not already (INSERT OR IGNORE) + await ctxRegisterProject(projectName, `BTerminal project: ${projectName}`, projectCwd); + + const [ctx, shared, sums] = await Promise.all([ + ctxGetContext(projectName), + ctxGetShared(), + ctxGetSummaries(projectName, 5), + ]); + entries = ctx; + sharedEntries = shared; + summaries = sums; error = ''; dbMissing = false; } catch (e) { error = `${e}`; dbMissing = error.includes('not found'); + } finally { + loading = false; } } @@ -46,7 +56,7 @@ initializing = true; try { await ctxInitDb(); - await loadData(); + await loadProjectContext(); } catch (e) { error = `Failed to initialize database: ${e}`; } finally { @@ -54,24 +64,6 @@ } } - onMount(loadData); - - async function selectProject(name: string) { - selectedProject = name; - loading = true; - try { - [entries, summaries] = await Promise.all([ - ctxGetContext(name), - ctxGetSummaries(name, 5), - ]); - error = ''; - } catch (e) { - error = `Failed to load context: ${e}`; - } finally { - loading = false; - } - } - async function handleSearch() { if (!searchQuery.trim()) { searchResults = []; @@ -83,11 +75,13 @@ error = `Search failed: ${e}`; } } + + onMount(loadProjectContext);
-

Context Manager

+

{projectName}

{/if} -
- {#if searchResults.length > 0} -
-

Search Results

- {#each searchResults as result} -
-
- {result.project} - {result.key} + {#if !error} +
+ {#if loading} +
Loading...
+ {:else if searchResults.length > 0} +
+

Search Results

+ {#each searchResults as result} +
+
+ {result.project} + {result.key} +
+
{result.value}
-
{result.value}
+ {/each} + +
+ {:else} + {#if entries.length > 0} +
+

Project Context

+ {#each entries as entry} +
+
+ {entry.key} + +
+
{entry.value}
+
+ {/each}
- {/each} - -
- {:else} -
-

Projects

- {#if projects.length === 0} -

No projects registered. Use ctx init to add one.

{/if} - {#each projects as project} - - {/each} -
- {#if sharedEntries.length > 0} -
-

Shared Context

- {#each sharedEntries as entry} -
-
- {entry.key} + {#if sharedEntries.length > 0} +
+

Shared Context

+ {#each sharedEntries as entry} +
+
+ {entry.key} +
+
{entry.value}
-
{entry.value}
-
- {/each} -
- {/if} - - {#if selectedProject && !loading} -
-

{selectedProject} Context

- {#if entries.length === 0} -

No context entries for this project.

- {/if} - {#each entries as entry} -
-
- {entry.key} - -
-
{entry.value}
-
- {/each} -
+ {/each} +
+ {/if} {#if summaries.length > 0}
@@ -201,13 +179,16 @@ {/each}
{/if} - {/if} - {#if loading} -
Loading...
+ {#if entries.length === 0 && sharedEntries.length === 0 && summaries.length === 0} +
+

No context stored yet.

+

Use ctx set {projectName} <key> <value> to add context entries.

+
+ {/if} {/if} - {/if} -
+
+ {/if}
diff --git a/v2/src/lib/components/Workspace/ProjectBox.svelte b/v2/src/lib/components/Workspace/ProjectBox.svelte index 16deefa..529f108 100644 --- a/v2/src/lib/components/Workspace/ProjectBox.svelte +++ b/v2/src/lib/components/Workspace/ProjectBox.svelte @@ -77,7 +77,7 @@
{:else if activeTab === 'context'}
- {}} /> +
{/if}