chore: rebrand runtime and docs to EJClaw
This commit is contained in:
@@ -87,14 +87,14 @@ function buildBaseRunnerEnv(args: {
|
||||
: currentPath,
|
||||
TZ: TIMEZONE,
|
||||
HOME: os.homedir(),
|
||||
NANOCLAW_GROUP_DIR: args.groupDir,
|
||||
NANOCLAW_IPC_DIR: args.groupIpcDir,
|
||||
NANOCLAW_GLOBAL_DIR: args.globalDir,
|
||||
...(args.group.workDir ? { NANOCLAW_WORK_DIR: args.group.workDir } : {}),
|
||||
NANOCLAW_CHAT_JID: args.chatJid,
|
||||
NANOCLAW_GROUP_FOLDER: args.group.folder,
|
||||
NANOCLAW_IS_MAIN: args.isMain ? '1' : '0',
|
||||
NANOCLAW_AGENT_TYPE: args.agentType,
|
||||
EJCLAW_GROUP_DIR: args.groupDir,
|
||||
EJCLAW_IPC_DIR: args.groupIpcDir,
|
||||
EJCLAW_GLOBAL_DIR: args.globalDir,
|
||||
...(args.group.workDir ? { EJCLAW_WORK_DIR: args.group.workDir } : {}),
|
||||
EJCLAW_CHAT_JID: args.chatJid,
|
||||
EJCLAW_GROUP_FOLDER: args.group.folder,
|
||||
EJCLAW_IS_MAIN: args.isMain ? '1' : '0',
|
||||
EJCLAW_AGENT_TYPE: args.agentType,
|
||||
CLAUDE_CONFIG_DIR: args.groupSessionsDir,
|
||||
};
|
||||
}
|
||||
@@ -240,22 +240,22 @@ function prepareCodexSessionEnvironment(args: {
|
||||
let toml = fs.existsSync(sessionConfigPath)
|
||||
? fs.readFileSync(sessionConfigPath, 'utf-8')
|
||||
: '';
|
||||
toml = toml.replace(/\n?\[mcp_servers\.nanoclaw\][\s\S]*?(?=\n\[|$)/, '');
|
||||
toml = toml.replace(/\n?\[mcp_servers\.ejclaw\][\s\S]*?(?=\n\[|$)/, '');
|
||||
toml = toml.replace(
|
||||
/\n?\[mcp_servers\.memento-mcp\][\s\S]*?(?=\n\[|$)/,
|
||||
'',
|
||||
);
|
||||
const mcpSection = `
|
||||
[mcp_servers.nanoclaw]
|
||||
[mcp_servers.ejclaw]
|
||||
command = "node"
|
||||
args = [${JSON.stringify(mcpServerPath)}]
|
||||
|
||||
[mcp_servers.nanoclaw.env]
|
||||
NANOCLAW_IPC_DIR = ${JSON.stringify(args.env.NANOCLAW_IPC_DIR)}
|
||||
NANOCLAW_CHAT_JID = ${JSON.stringify(args.chatJid)}
|
||||
NANOCLAW_GROUP_FOLDER = ${JSON.stringify(args.group.folder)}
|
||||
NANOCLAW_IS_MAIN = ${JSON.stringify(args.isMain ? '1' : '0')}
|
||||
NANOCLAW_AGENT_TYPE = ${JSON.stringify(args.env.NANOCLAW_AGENT_TYPE)}
|
||||
[mcp_servers.ejclaw.env]
|
||||
EJCLAW_IPC_DIR = ${JSON.stringify(args.env.EJCLAW_IPC_DIR)}
|
||||
EJCLAW_CHAT_JID = ${JSON.stringify(args.chatJid)}
|
||||
EJCLAW_GROUP_FOLDER = ${JSON.stringify(args.group.folder)}
|
||||
EJCLAW_IS_MAIN = ${JSON.stringify(args.isMain ? '1' : '0')}
|
||||
EJCLAW_AGENT_TYPE = ${JSON.stringify(args.env.EJCLAW_AGENT_TYPE)}
|
||||
`;
|
||||
const mementoSseUrl =
|
||||
args.envVars.MEMENTO_MCP_SSE_URL || process.env.MEMENTO_MCP_SSE_URL;
|
||||
|
||||
@@ -5,15 +5,15 @@ import fs from 'fs';
|
||||
import { spawn } from 'child_process';
|
||||
|
||||
// Sentinel markers must match agent-runner.ts
|
||||
const OUTPUT_START_MARKER = '---NANOCLAW_OUTPUT_START---';
|
||||
const OUTPUT_END_MARKER = '---NANOCLAW_OUTPUT_END---';
|
||||
const OUTPUT_START_MARKER = '---EJCLAW_OUTPUT_START---';
|
||||
const OUTPUT_END_MARKER = '---EJCLAW_OUTPUT_END---';
|
||||
|
||||
// Mock config
|
||||
vi.mock('./config.js', () => ({
|
||||
AGENT_MAX_OUTPUT_SIZE: 10485760,
|
||||
AGENT_TIMEOUT: 1800000, // 30min
|
||||
DATA_DIR: '/tmp/nanoclaw-test-data',
|
||||
GROUPS_DIR: '/tmp/nanoclaw-test-groups',
|
||||
DATA_DIR: '/tmp/ejclaw-test-data',
|
||||
GROUPS_DIR: '/tmp/ejclaw-test-groups',
|
||||
IDLE_TIMEOUT: 1800000, // 30min
|
||||
TIMEZONE: 'America/Los_Angeles',
|
||||
}));
|
||||
@@ -287,7 +287,7 @@ describe('agent-runner timeout behavior', () => {
|
||||
const spawnEnv = vi.mocked(spawn).mock.calls[0]?.[2]?.env as
|
||||
| Record<string, string>
|
||||
| undefined;
|
||||
expect(spawnEnv?.NANOCLAW_CHAT_JID).toBe(testInput.chatJid);
|
||||
expect(spawnEnv?.EJCLAW_CHAT_JID).toBe(testInput.chatJid);
|
||||
|
||||
const tomlWrite = vi
|
||||
.mocked(fs.writeFileSync)
|
||||
@@ -295,7 +295,7 @@ describe('agent-runner timeout behavior', () => {
|
||||
String(call[0]).endsWith('/.codex/config.toml'),
|
||||
);
|
||||
expect(String(tomlWrite?.[1])).toContain(
|
||||
`NANOCLAW_CHAT_JID = ${JSON.stringify(testInput.chatJid)}`,
|
||||
`EJCLAW_CHAT_JID = ${JSON.stringify(testInput.chatJid)}`,
|
||||
);
|
||||
});
|
||||
|
||||
@@ -322,11 +322,11 @@ describe('agent-runner timeout behavior', () => {
|
||||
const spawnEnv = vi.mocked(spawn).mock.calls.at(-1)?.[2]?.env as
|
||||
| Record<string, string>
|
||||
| undefined;
|
||||
expect(spawnEnv?.NANOCLAW_IPC_DIR).toBe(
|
||||
'/tmp/nanoclaw-test-data/ipc/test-group/tasks/task-123',
|
||||
expect(spawnEnv?.EJCLAW_IPC_DIR).toBe(
|
||||
'/tmp/ejclaw-test-data/ipc/test-group/tasks/task-123',
|
||||
);
|
||||
expect(spawnEnv?.CLAUDE_CONFIG_DIR).toBe(
|
||||
'/tmp/nanoclaw-test-data/sessions/test-group/tasks/task-123/.claude',
|
||||
'/tmp/ejclaw-test-data/sessions/test-group/tasks/task-123/.claude',
|
||||
);
|
||||
});
|
||||
|
||||
@@ -353,11 +353,11 @@ describe('agent-runner timeout behavior', () => {
|
||||
const spawnEnv = vi.mocked(spawn).mock.calls.at(-1)?.[2]?.env as
|
||||
| Record<string, string>
|
||||
| undefined;
|
||||
expect(spawnEnv?.NANOCLAW_IPC_DIR).toBe(
|
||||
'/tmp/nanoclaw-test-data/ipc/test-group/tasks/task-watch-group',
|
||||
expect(spawnEnv?.EJCLAW_IPC_DIR).toBe(
|
||||
'/tmp/ejclaw-test-data/ipc/test-group/tasks/task-watch-group',
|
||||
);
|
||||
expect(spawnEnv?.CLAUDE_CONFIG_DIR).toBe(
|
||||
'/tmp/nanoclaw-test-data/sessions/test-group/.claude',
|
||||
'/tmp/ejclaw-test-data/sessions/test-group/.claude',
|
||||
);
|
||||
});
|
||||
|
||||
@@ -365,9 +365,9 @@ describe('agent-runner timeout behavior', () => {
|
||||
vi.useRealTimers();
|
||||
fakeProc = createFakeProcess();
|
||||
const overlayPath =
|
||||
'/tmp/nanoclaw-test-groups/test-group/.codex/config.toml';
|
||||
'/tmp/ejclaw-test-groups/test-group/.codex/config.toml';
|
||||
const sessionConfigPath =
|
||||
'/tmp/nanoclaw-test-data/sessions/test-group/.codex/config.toml';
|
||||
'/tmp/ejclaw-test-data/sessions/test-group/.codex/config.toml';
|
||||
let sessionToml = `model = "gpt-5.4"\n`;
|
||||
|
||||
vi.mocked(fs.existsSync).mockImplementation((p: fs.PathLike) => {
|
||||
@@ -428,7 +428,7 @@ OUROBOROS_LLM_BACKEND = "codex"
|
||||
const toml = String(tomlWrite?.[1]);
|
||||
expect(toml).toContain('[mcp_servers.ouroboros]');
|
||||
expect(toml).toContain('OUROBOROS_AGENT_RUNTIME = "codex"');
|
||||
expect(toml).toContain('[mcp_servers.nanoclaw]');
|
||||
expect(toml).toContain('[mcp_servers.ejclaw]');
|
||||
});
|
||||
|
||||
it('waits for queued streamed output before resolving an error exit', async () => {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/**
|
||||
* Agent Process Runner for NanoClaw
|
||||
* Agent Process Runner for EJClaw
|
||||
* Spawns agent execution as direct host processes and handles IPC
|
||||
*/
|
||||
import { ChildProcess, spawn } from 'child_process';
|
||||
@@ -21,8 +21,8 @@ import { logger } from './logger.js';
|
||||
import { AgentType, RegisteredGroup } from './types.js';
|
||||
|
||||
// Sentinel markers for robust output parsing (must match agent-runner)
|
||||
const OUTPUT_START_MARKER = '---NANOCLAW_OUTPUT_START---';
|
||||
const OUTPUT_END_MARKER = '---NANOCLAW_OUTPUT_END---';
|
||||
const OUTPUT_START_MARKER = '---EJCLAW_OUTPUT_START---';
|
||||
const OUTPUT_END_MARKER = '---EJCLAW_OUTPUT_END---';
|
||||
|
||||
export interface AgentInput {
|
||||
prompt: string;
|
||||
@@ -75,12 +75,12 @@ export async function runAgentProcess(
|
||||
}
|
||||
}
|
||||
if (input.runId) {
|
||||
env.NANOCLAW_RUN_ID = input.runId;
|
||||
env.EJCLAW_RUN_ID = input.runId;
|
||||
}
|
||||
|
||||
const safeName = group.folder.replace(/[^a-zA-Z0-9-]/g, '-');
|
||||
const processSuffix = input.runId || `${Date.now()}`;
|
||||
const processName = `nanoclaw-${safeName}-${processSuffix}`;
|
||||
const processName = `ejclaw-${safeName}-${processSuffix}`;
|
||||
|
||||
// Check if runner is built
|
||||
const distEntry = path.join(runnerDir, 'dist', 'index.js');
|
||||
@@ -119,7 +119,7 @@ export async function runAgentProcess(
|
||||
env,
|
||||
});
|
||||
|
||||
onProcess(proc, processName, env.NANOCLAW_IPC_DIR);
|
||||
onProcess(proc, processName, env.EJCLAW_IPC_DIR);
|
||||
|
||||
let stdout = '';
|
||||
let stderr = '';
|
||||
|
||||
@@ -12,8 +12,8 @@ vi.mock('../env.js', () => ({ readEnvFile: vi.fn(() => ({})) }));
|
||||
vi.mock('../config.js', () => ({
|
||||
ASSISTANT_NAME: 'Andy',
|
||||
TRIGGER_PATTERN: /^@Andy\b/i,
|
||||
DATA_DIR: '/tmp/nanoclaw-test-data',
|
||||
CACHE_DIR: '/tmp/nanoclaw-test-cache',
|
||||
DATA_DIR: '/tmp/ejclaw-test-data',
|
||||
CACHE_DIR: '/tmp/ejclaw-test-cache',
|
||||
}));
|
||||
|
||||
// Mock logger
|
||||
|
||||
@@ -40,17 +40,17 @@ const HOME_DIR = process.env.HOME || os.homedir();
|
||||
export const SENDER_ALLOWLIST_PATH = path.join(
|
||||
HOME_DIR,
|
||||
'.config',
|
||||
'nanoclaw',
|
||||
'ejclaw',
|
||||
'sender-allowlist.json',
|
||||
);
|
||||
export const STORE_DIR = path.resolve(
|
||||
process.env.NANOCLAW_STORE_DIR || path.join(PROJECT_ROOT, 'store'),
|
||||
process.env.EJCLAW_STORE_DIR || path.join(PROJECT_ROOT, 'store'),
|
||||
);
|
||||
export const GROUPS_DIR = path.resolve(
|
||||
process.env.NANOCLAW_GROUPS_DIR || path.join(PROJECT_ROOT, 'groups'),
|
||||
process.env.EJCLAW_GROUPS_DIR || path.join(PROJECT_ROOT, 'groups'),
|
||||
);
|
||||
export const DATA_DIR = path.resolve(
|
||||
process.env.NANOCLAW_DATA_DIR || path.join(PROJECT_ROOT, 'data'),
|
||||
process.env.EJCLAW_DATA_DIR || path.join(PROJECT_ROOT, 'data'),
|
||||
);
|
||||
// Shared cache directory (same across both services for dedup)
|
||||
export const CACHE_DIR = path.join(PROJECT_ROOT, 'cache');
|
||||
|
||||
@@ -474,7 +474,7 @@ const isDirectRun =
|
||||
|
||||
if (isDirectRun) {
|
||||
main().catch((err) => {
|
||||
logger.error({ err }, 'Failed to start NanoClaw');
|
||||
logger.error({ err }, 'Failed to start EJClaw');
|
||||
process.exit(1);
|
||||
});
|
||||
}
|
||||
|
||||
@@ -7,7 +7,7 @@ vi.mock('./agent-runner.js', () => ({
|
||||
}));
|
||||
|
||||
vi.mock('./config.js', () => ({
|
||||
DATA_DIR: '/tmp/nanoclaw-test-data',
|
||||
DATA_DIR: '/tmp/ejclaw-test-data',
|
||||
isSessionCommandSenderAllowed: vi.fn(() => false),
|
||||
}));
|
||||
|
||||
|
||||
Reference in New Issue
Block a user