a chat with no chosen directory runs in the caller's own home
The default was DATA_PATH/<email>/general_chat_sessions, a dedicated directory so /chat sessions formed their own Claude project group instead of cluttering the home. It is a sibling of the home, and confineUserTree makes every sibling the platform's at 0700 because the others are attachments and email_accounts. So it was unreachable for a member: the first live member turn started there and every Bash call failed on its own working directory before doing anything. A per-member copy inside each home fixed the symptom and left two rules to remember. The owner chose one rule instead — the account's own home, whoever they are — and accepted the trade knowingly: /chat sessions now share a project group with anything else run from that home, which was the reason the dedicated directory existed. Removed rather than left dangling: getGeneralChatSessionsCwd, ensureGeneralChatSessionsCwd, ensureMemberChatCwd, and general_chat_sessions from USER_DIRS so new accounts stop getting it. Existing directories are untouched and their transcripts stay where they are — Claude groups by cwd, so the owner's old /chat history remains under its own project slug rather than moving. The UI labels move with it: the default group now reads "home" rather than naming a directory that no longer has a role. ChatIdentity keeps carrying both email and home. The pairing was justified in the comment by general_chat_sessions being email-derived, which is now gone — but the distinction it encodes is real (the email says who, the home says where), so the comment explains that instead. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
@@ -29,25 +29,20 @@ import { DATA_PATH } from '../../data-path';
|
||||
// that were a property rather than an assumption. A member reaching these functions would have been handed the
|
||||
// owner's conversation list.
|
||||
//
|
||||
// So the home arrives resolved, from `resolveHomeDir(userId)`, and this file has no way to invent one. The
|
||||
// email is still passed where a path is genuinely email-derived — `general_chat_sessions` lives under
|
||||
// DATA_PATH, not under a home — which is why both travel together rather than one standing in for the other.
|
||||
// So the home arrives resolved, from `resolveHomeDir(userId)`, and this file has no way to invent one.
|
||||
//
|
||||
// The email travels alongside it rather than being derived from it, because the two answer different
|
||||
// questions: the email says WHO, the home says WHERE. They were briefly conflated in the other direction —
|
||||
// `general_chat_sessions` was an email-derived path under DATA_PATH used as a chat's working directory, and
|
||||
// because `confineUserTree` makes every sibling of a home the platform's at 0700, a member's turn started in
|
||||
// a directory it could not enter. That default is now the caller's own home; the pairing survives because the
|
||||
// distinction it encodes is real.
|
||||
export type ChatIdentity = {
|
||||
email: string;
|
||||
/** From `resolveHomeDir`. Never `getOwnerHomeDir`, which ignores its argument. */
|
||||
home: string;
|
||||
};
|
||||
|
||||
/** Dedicated working directory for /chat sessions, so they form their own Claude "project" group. */
|
||||
export const getGeneralChatSessionsCwd = (email: string): string => join(DATA_PATH, email, 'general_chat_sessions');
|
||||
|
||||
/** Same, but create the directory if it doesn't exist (call before spawning a /chat session). */
|
||||
export const ensureGeneralChatSessionsCwd = (email: string): string => {
|
||||
const dir = getGeneralChatSessionsCwd(email);
|
||||
mkdirSync(dir, { recursive: true });
|
||||
return dir;
|
||||
};
|
||||
|
||||
const claudeProjectsDir = (home: string): string => join(home, '.claude', 'projects');
|
||||
|
||||
/** Claude's folder name for a working directory. */
|
||||
@@ -767,10 +762,10 @@ function firstCwd(filePath: string): string {
|
||||
|
||||
export type ClaudePwd = { cwd: string; sessionCount: number; updatedAt: string; isDefault: boolean };
|
||||
|
||||
/** All working directories that have Claude sessions, plus the default /chat dir. Newest first. */
|
||||
/** All working directories that have Claude sessions, plus the caller's home. Newest first. */
|
||||
export function listClaudePwds(who: ChatIdentity): ClaudePwd[] {
|
||||
const projectsDir = claudeProjectsDir(who.home);
|
||||
const defaultCwd = getGeneralChatSessionsCwd(who.email);
|
||||
const defaultCwd = who.home;
|
||||
const byCwd = new Map<string, { count: number; updatedAt: string }>();
|
||||
|
||||
if (existsSync(projectsDir)) {
|
||||
|
||||
Reference in New Issue
Block a user