dynamic claude.md regeneration and email db env for claude code

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-03-07 12:45:41 +00:00
co-authored by Claude Opus 4.6
parent 49cd559c8a
commit ecd83dc1ec
3 changed files with 17 additions and 4 deletions
@@ -1,6 +1,6 @@
import { EmbeddableChat, usePiChat } from 'officerdev'; import { EmbeddableChat, usePiChat } from 'officerdev';
const PROMPT_PREFIX = `You are an email assistant. The user has a local SQLite email database available via the "email-db" tool — use it for all email queries (search, count, stats, aggregations, deletions) unless the user explicitly asks you to use Gmail. Do not use the Gmail integration for questions about existing emails.`; const PROMPT_PREFIX = `You are an email assistant. The user has a local SQLite email database available via the "email_db" tool — use it for all email queries (search, count, stats, aggregations, deletions) unless the user explicitly asks you to use Gmail. Do not use the Gmail integration for questions about existing emails.`;
export const EmailChat = () => { export const EmailChat = () => {
const chat = usePiChat(undefined, undefined, { replaceUrl: false }); const chat = usePiChat(undefined, undefined, { replaceUrl: false });
@@ -9,7 +9,7 @@ import { defaultLayout } from './defaultLayout';
import { EmailList } from './EmailList'; import { EmailList } from './EmailList';
import { EmailReader } from './EmailReader'; import { EmailReader } from './EmailReader';
const PROMPT_PREFIX = `You are an email assistant. The user has a local SQLite email database available via the "email-db" tool — use it for all email queries (search, count, stats, aggregations, deletions) unless the user explicitly asks you to use Gmail. Do not use the Gmail integration for questions about existing emails.`; const PROMPT_PREFIX = `You are an email assistant. The user has a local SQLite email database available via the "email_db" tool — use it for all email queries (search, count, stats, aggregations, deletions) unless the user explicitly asks you to use Gmail. Do not use the Gmail integration for questions about existing emails.`;
export const EmailScreen = () => { export const EmailScreen = () => {
const isMobile = useIsMobile(); const isMobile = useIsMobile();
+15 -2
View File
@@ -1,3 +1,4 @@
import { existsSync, mkdirSync, readFileSync, writeFileSync } from 'node:fs';
import { join } from 'node:path'; import { join } from 'node:path';
import type { Subprocess } from 'bun'; import type { Subprocess } from 'bun';
import type { PiEvent, MessageCost } from '../../api/pi/types'; import type { PiEvent, MessageCost } from '../../api/pi/types';
@@ -6,12 +7,18 @@ import { getState, setClaudeSession, clearClaudeSession, getClaudeSession } from
import { getProxySecret } from './proxy'; import { getProxySecret } from './proxy';
import { discoverTools } from '../../tool-registry'; import { discoverTools } from '../../tool-registry';
import type { ToolDefinition } from '../../tool-registry'; import type { ToolDefinition } from '../../tool-registry';
import { DATA_PATH, getHomeDir } from '../../data-path';
import { generateContainerContext } from '../../generate-container-context';
const SEND_TIMEOUT_MS = 5 * 60 * 1000; const SEND_TIMEOUT_MS = 5 * 60 * 1000;
const PROXY_PORT = process.env.ANTHROPIC_PROXY_PORT ?? '5051'; const PROXY_PORT = process.env.ANTHROPIC_PROXY_PORT ?? '5051';
const DATA_PATH = process.env.DATA_PATH ?? join(process.cwd(), 'data');
const getHomeDir = (email: string) => join(DATA_PATH, email, 'home'); function refreshClaudeMd(email: string): void {
const claudeDir = join(getHomeDir(email), '.claude');
if (!existsSync(claudeDir)) mkdirSync(claudeDir, { recursive: true });
const contextFile = generateContainerContext(email);
writeFileSync(join(claudeDir, 'CLAUDE.md'), readFileSync(contextFile, 'utf-8'));
}
function buildToolContext(email: string): string { function buildToolContext(email: string): string {
const tools = discoverTools(email); const tools = discoverTools(email);
@@ -89,6 +96,8 @@ export async function spawnClaude(params: ClaudeSpawnParams): Promise<ClaudeCode
const homeDir = getHomeDir(email); const homeDir = getHomeDir(email);
const shellUsername = toShellUsername(username, email); const shellUsername = toShellUsername(username, email);
refreshClaudeMd(email);
const existingSession = getClaudeSession(sessionKey); const existingSession = getClaudeSession(sessionKey);
const isResume = !!existingSession; const isResume = !!existingSession;
@@ -110,6 +119,7 @@ export async function spawnClaude(params: ClaudeSpawnParams): Promise<ClaudeCode
...authEnv, ...authEnv,
PATH: process.env.PATH ?? '', PATH: process.env.PATH ?? '',
TERM: 'xterm-256color', TERM: 'xterm-256color',
OFFICER_EMAIL_DB: join(DATA_PATH, email, 'emails.db'),
}; };
const proc = isServiceUser const proc = isServiceUser
@@ -183,6 +193,8 @@ export async function spawnClaudeStreaming(
const homeDir = getHomeDir(email); const homeDir = getHomeDir(email);
const workDir = cwd ?? homeDir; const workDir = cwd ?? homeDir;
refreshClaudeMd(email);
const existingSession = getClaudeSession(sessionKey); const existingSession = getClaudeSession(sessionKey);
const isResume = !!existingSession; const isResume = !!existingSession;
@@ -215,6 +227,7 @@ export async function spawnClaudeStreaming(
...authEnv, ...authEnv,
PATH: cleanEnv.PATH ?? '', PATH: cleanEnv.PATH ?? '',
TERM: 'xterm-256color', TERM: 'xterm-256color',
OFFICER_EMAIL_DB: join(DATA_PATH, email, 'emails.db'),
}; };
const proc = isServiceUser const proc = isServiceUser