fix: prepare CLAUDE.md and roomRoleContext for container reviewer
Container reviewer was running without prompts because the container path in agent-runner.ts skipped prepareGroupEnvironment() entirely. This meant no CLAUDE.md (platform + paired room prompts + memory briefing) and no roomRoleContext were passed to the container. - Add prepareContainerSessionEnvironment() to write CLAUDE.md, sync skills, and ensure settings.json for the reviewer session directory - Pass roomRoleContext through ReviewerContainerInput so the runner can prepend the [ROOM_ROLE] header - Add roomRoleContext field to ReviewerContainerInput interface
This commit is contained in:
@@ -525,3 +525,60 @@ export function prepareGroupEnvironment(
|
|||||||
|
|
||||||
return { env, groupDir, runnerDir };
|
return { env, groupDir, runnerDir };
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Prepare the Claude session directory for a container-based reviewer.
|
||||||
|
*
|
||||||
|
* Writes CLAUDE.md (platform + paired room prompts + global memory + briefing),
|
||||||
|
* syncs skills, and ensures settings.json exist — the same steps that
|
||||||
|
* `prepareGroupEnvironment` does for host-mode agents, but targeted at an
|
||||||
|
* externally provided session directory (the one mounted into the container).
|
||||||
|
*/
|
||||||
|
export function prepareContainerSessionEnvironment(args: {
|
||||||
|
sessionDir: string;
|
||||||
|
chatJid: string;
|
||||||
|
isMain: boolean;
|
||||||
|
memoryBriefing?: string;
|
||||||
|
}): void {
|
||||||
|
const { sessionDir, chatJid, isMain, memoryBriefing } = args;
|
||||||
|
const projectRoot = process.cwd();
|
||||||
|
|
||||||
|
fs.mkdirSync(sessionDir, { recursive: true });
|
||||||
|
ensureClaudeSessionSettings(sessionDir);
|
||||||
|
|
||||||
|
// Sync skills from host
|
||||||
|
const skillSources = [
|
||||||
|
path.join(os.homedir(), '.claude', 'skills'),
|
||||||
|
path.join(projectRoot, 'runners', 'skills'),
|
||||||
|
];
|
||||||
|
syncDirectoryEntries(skillSources, path.join(sessionDir, 'skills'));
|
||||||
|
|
||||||
|
// Build CLAUDE.md with reviewer-appropriate prompts
|
||||||
|
const claudePlatformPrompt = readPlatformPrompt('claude-code', projectRoot);
|
||||||
|
const claudePairedRoomPrompt = isPairedRoomJid(chatJid)
|
||||||
|
? readPairedRoomPrompt('claude-code', projectRoot)
|
||||||
|
: undefined;
|
||||||
|
const globalDir = path.join(GROUPS_DIR, 'global');
|
||||||
|
const globalClaudeMdPath = path.join(globalDir, 'CLAUDE.md');
|
||||||
|
const globalClaudeMemory =
|
||||||
|
!isMain && fs.existsSync(globalClaudeMdPath)
|
||||||
|
? fs.readFileSync(globalClaudeMdPath, 'utf-8').trim()
|
||||||
|
: undefined;
|
||||||
|
|
||||||
|
const sessionClaudeMd = [
|
||||||
|
claudePlatformPrompt,
|
||||||
|
claudePairedRoomPrompt,
|
||||||
|
globalClaudeMemory,
|
||||||
|
memoryBriefing,
|
||||||
|
]
|
||||||
|
.filter((value): value is string => Boolean(value))
|
||||||
|
.join('\n\n---\n\n')
|
||||||
|
.trim();
|
||||||
|
|
||||||
|
const sessionClaudeMdPath = path.join(sessionDir, 'CLAUDE.md');
|
||||||
|
if (sessionClaudeMd) {
|
||||||
|
fs.writeFileSync(sessionClaudeMdPath, sessionClaudeMd + '\n');
|
||||||
|
} else if (fs.existsSync(sessionClaudeMdPath)) {
|
||||||
|
fs.unlinkSync(sessionClaudeMdPath);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -12,7 +12,10 @@ import {
|
|||||||
AGENT_TIMEOUT,
|
AGENT_TIMEOUT,
|
||||||
IDLE_TIMEOUT,
|
IDLE_TIMEOUT,
|
||||||
} from './config.js';
|
} from './config.js';
|
||||||
import { prepareGroupEnvironment } from './agent-runner-environment.js';
|
import {
|
||||||
|
prepareContainerSessionEnvironment,
|
||||||
|
prepareGroupEnvironment,
|
||||||
|
} from './agent-runner-environment.js';
|
||||||
import { getEnv } from './env.js';
|
import { getEnv } from './env.js';
|
||||||
export {
|
export {
|
||||||
type AvailableGroup,
|
type AvailableGroup,
|
||||||
@@ -75,6 +78,19 @@ export async function runAgentProcess(
|
|||||||
if (envOverrides?.EJCLAW_REVIEWER_RUNTIME === '1') {
|
if (envOverrides?.EJCLAW_REVIEWER_RUNTIME === '1') {
|
||||||
const ownerWorkspaceDir =
|
const ownerWorkspaceDir =
|
||||||
envOverrides?.EJCLAW_WORK_DIR || group.workDir || process.cwd();
|
envOverrides?.EJCLAW_WORK_DIR || group.workDir || process.cwd();
|
||||||
|
|
||||||
|
// Prepare session directory for the container (CLAUDE.md, skills, settings)
|
||||||
|
// so the Claude SDK inside the container has platform & paired room prompts.
|
||||||
|
const sessionDir = envOverrides?.CLAUDE_CONFIG_DIR;
|
||||||
|
if (sessionDir) {
|
||||||
|
prepareContainerSessionEnvironment({
|
||||||
|
sessionDir,
|
||||||
|
chatJid: input.chatJid,
|
||||||
|
isMain: input.isMain,
|
||||||
|
memoryBriefing: input.memoryBriefing,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
return runReviewerContainer({
|
return runReviewerContainer({
|
||||||
group,
|
group,
|
||||||
input: {
|
input: {
|
||||||
@@ -85,6 +101,7 @@ export async function runAgentProcess(
|
|||||||
runId: input.runId || `${Date.now()}`,
|
runId: input.runId || `${Date.now()}`,
|
||||||
isMain: input.isMain,
|
isMain: input.isMain,
|
||||||
assistantName: input.assistantName,
|
assistantName: input.assistantName,
|
||||||
|
roomRoleContext: input.roomRoleContext,
|
||||||
},
|
},
|
||||||
ownerWorkspaceDir,
|
ownerWorkspaceDir,
|
||||||
envOverrides,
|
envOverrides,
|
||||||
|
|||||||
@@ -58,6 +58,7 @@ export interface ReviewerContainerInput {
|
|||||||
runId: string;
|
runId: string;
|
||||||
isMain: boolean;
|
isMain: boolean;
|
||||||
assistantName?: string;
|
assistantName?: string;
|
||||||
|
roomRoleContext?: import('./types.js').RoomRoleContext;
|
||||||
}
|
}
|
||||||
|
|
||||||
interface VolumeMount {
|
interface VolumeMount {
|
||||||
|
|||||||
Reference in New Issue
Block a user