chat: tag OpenCode sessions with officer metadata (cwd) + filter lists by it
OpenCode has no per-session directory (every session runs in the fixed server's cwd),
so sessions from every context (/chat pwd, email account, project) all landed in one
list. Now each session is tagged on creation with its logical cwd via the free-form
session `metadata`: { officer: { cwd } } — API-settable, round-trips on list+detail,
never touched by opencode core (confirmed by source dive + live test).
- client.createSession(metadata?) sends `metadata`; adds OfficerSessionMeta + officerMeta() helper.
- send-opencode tags new sessions with { officer: { cwd } } (the resolved chat cwd).
- websocket: pass the full resolved cwd for every context (not just non-/chat).
- listOpenCodeSessions(cwd?) filters by metadata.officer.cwd; chat.ts passes the request cwd.
Verified live: sessions tagged with distinct cwds list only under their own cwd.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -105,11 +105,12 @@ class ServerConnection {
|
||||
return (await res.json()) as T;
|
||||
}
|
||||
|
||||
async createSession(directory?: string, title?: string): Promise<string> {
|
||||
// `directory` binds the session's working dir (e.g. an email account dir). Omit it for the general
|
||||
// /chat, so the session lives in the fixed server's own project (its cwd).
|
||||
async createSession(metadata?: Record<string, unknown>, title?: string): Promise<string> {
|
||||
// OpenCode has no per-session `directory` (a session inherits the server's cwd). We instead tag
|
||||
// the session with our own free-form `metadata` (e.g. { officer: { cwd } }) — round-trips on the
|
||||
// list + detail endpoints and is never touched by opencode core — to know where it belongs.
|
||||
const body: Record<string, unknown> = {};
|
||||
if (directory) body.directory = directory;
|
||||
if (metadata) body.metadata = metadata;
|
||||
if (title) body.title = title;
|
||||
const session = await this.postJson<{ id?: string }>('/session', body);
|
||||
if (!session.id) throw new Error('opencode POST /session returned no id');
|
||||
@@ -162,8 +163,14 @@ export type OpenCodeSessionInfo = {
|
||||
title?: string;
|
||||
time?: { created?: number; updated?: number };
|
||||
location?: { directory?: string | null };
|
||||
metadata?: Record<string, unknown>;
|
||||
};
|
||||
|
||||
// Our own namespaced session metadata (stored under the free-form `metadata.officer` key).
|
||||
export type OfficerSessionMeta = { cwd?: string };
|
||||
export const officerMeta = (m?: Record<string, unknown>): OfficerSessionMeta =>
|
||||
(m?.officer as OfficerSessionMeta) ?? {};
|
||||
|
||||
export type OpenCodeStoredPart = {
|
||||
type?: string;
|
||||
text?: string;
|
||||
|
||||
Reference in New Issue
Block a user