merge: integrate origin/main (406 commits) into live branch
Merge upstream's paired-room stabilization, dedicated message-runtime-loop, outbound delivery refactor (ipc-outbound-delivery / deliverFormattedCanonicalMessage), discord module split, dashboard rework, and migrations 015-018 into our branch. Conflict policy: prefer upstream for the heavily-refactored paired-room / message-runtime / db cluster (it supersedes our earlier loop band-aids), keep only orthogonal unique fixes: - codex bundled-JS launcher fix (codex-warmup.ts) - slot-aligned Claude+Codex usage primer (usage-primer.ts) re-wired into index.ts - MemoryHigh=3G cgroup bound, discord perms diagnostic, prompt docs - progress null-race + silent-failure publish guards (message-turn-controller.ts) Dropped (superseded by upstream or unwired): reviewer STEP_DONE/TASK_DONE loop band-aids, router markdown-escape override, register tribunal-default+git-init, restart-context rewindToSeq (unwired). Verified: typecheck clean, build clean, vitest shows zero new regressions vs the origin/main baseline (only pre-existing env-config failures remain).
This commit is contained in:
@@ -155,7 +155,7 @@ function getStoredRoomRoleOverrideRows(
|
||||
agent_config_json: string | null;
|
||||
created_at: string;
|
||||
updated_at: string;
|
||||
}> = [];
|
||||
}>;
|
||||
try {
|
||||
rows = database
|
||||
.prepare(
|
||||
|
||||
@@ -191,7 +191,7 @@ export function ensureLinuxReadonlySandboxAppArmorSupport(options?: {
|
||||
const sysctlContents =
|
||||
'# Managed by EJClaw setup to allow bubblewrap readonly sandboxing.\n' +
|
||||
'kernel.apparmor_restrict_unprivileged_userns=0\n';
|
||||
let existingContents: string | null = null;
|
||||
let existingContents: string | null;
|
||||
|
||||
try {
|
||||
existingContents = readFileSyncFn(sysctlPath, 'utf-8');
|
||||
|
||||
@@ -3,7 +3,6 @@
|
||||
*
|
||||
* EJClaw is Discord-only, so registrations must target Discord channel IDs.
|
||||
*/
|
||||
import { execFileSync } from 'child_process';
|
||||
import fs from 'fs';
|
||||
import path from 'path';
|
||||
|
||||
@@ -13,45 +12,6 @@ import { isValidGroupFolder } from '../src/group-folder.js';
|
||||
import { logger } from '../src/logger.js';
|
||||
import { emitStatus } from './status.js';
|
||||
|
||||
/**
|
||||
* Resolve a usable git-repo work_dir for a new tribunal room.
|
||||
* Order: <folder> if .git exists, else <folder>/repo if .git exists,
|
||||
* else `git init` <folder> (with an empty initial commit) and use it.
|
||||
* Returns the absolute work_dir path.
|
||||
*/
|
||||
function ensureWorkDirForFolder(folderName: string): string {
|
||||
const folderPath = path.join(GROUPS_DIR, folderName);
|
||||
fs.mkdirSync(folderPath, { recursive: true });
|
||||
|
||||
if (fs.existsSync(path.join(folderPath, '.git'))) {
|
||||
return folderPath;
|
||||
}
|
||||
const repoSub = path.join(folderPath, 'repo');
|
||||
if (fs.existsSync(path.join(repoSub, '.git'))) {
|
||||
return repoSub;
|
||||
}
|
||||
|
||||
// No git repo found anywhere — initialize at the folder root.
|
||||
const gitEnv = {
|
||||
...process.env,
|
||||
GIT_AUTHOR_NAME: 'ejclaw',
|
||||
GIT_AUTHOR_EMAIL: 'ejclaw@local',
|
||||
GIT_COMMITTER_NAME: 'ejclaw',
|
||||
GIT_COMMITTER_EMAIL: 'ejclaw@local',
|
||||
};
|
||||
execFileSync('git', ['init', '-q'], { cwd: folderPath, env: gitEnv });
|
||||
execFileSync(
|
||||
'git',
|
||||
['commit', '-q', '--allow-empty', '-m', `init ${folderName} workspace`],
|
||||
{ cwd: folderPath, env: gitEnv },
|
||||
);
|
||||
logger.info(
|
||||
{ folder: folderName, workDir: folderPath },
|
||||
'Initialized git repository for tribunal workspace',
|
||||
);
|
||||
return folderPath;
|
||||
}
|
||||
|
||||
interface RegisterArgs {
|
||||
jid: string;
|
||||
name: string;
|
||||
@@ -142,20 +102,10 @@ export async function run(args: string[]): Promise<void> {
|
||||
logger.info(parsed, 'Registering channel');
|
||||
|
||||
initDatabase();
|
||||
|
||||
// Defaults for newly registered rooms:
|
||||
// roomMode = tribunal, owner = claude-code, reviewer = codex
|
||||
// Tribunal rooms also require a git-backed work_dir; auto-init if missing.
|
||||
const workDir = ensureWorkDirForFolder(parsed.folder);
|
||||
|
||||
assignRoom(parsed.jid, {
|
||||
name: parsed.name,
|
||||
folder: parsed.folder,
|
||||
isMain: parsed.isMain,
|
||||
roomMode: 'tribunal',
|
||||
ownerAgentType: 'claude-code',
|
||||
reviewerAgentType: 'codex',
|
||||
workDir,
|
||||
});
|
||||
logger.info('Assigned room through canonical room service');
|
||||
|
||||
|
||||
@@ -99,7 +99,9 @@ export function restartStackServices(
|
||||
throw error;
|
||||
}
|
||||
if (managedServiceCaller) {
|
||||
throw new Error(MANAGED_SERVICE_CALLER_FALLBACK_MESSAGE);
|
||||
throw new Error(MANAGED_SERVICE_CALLER_FALLBACK_MESSAGE, {
|
||||
cause: error,
|
||||
});
|
||||
}
|
||||
|
||||
return restartStackServicesDirect(projectRoot, deps);
|
||||
|
||||
@@ -15,7 +15,6 @@ import {
|
||||
ensureLinuxReadonlySandboxAppArmorSupport,
|
||||
getPlatform,
|
||||
getNodePath,
|
||||
getServiceManager,
|
||||
} from './platform.js';
|
||||
import { getServiceDefs } from './service-defs.js';
|
||||
import { setupLaunchd, setupLinux } from './service-installers.js';
|
||||
@@ -30,7 +29,6 @@ export async function run(_args: string[]): Promise<void> {
|
||||
const platform = getPlatform();
|
||||
const nodePath = getNodePath();
|
||||
const homeDir = os.homedir();
|
||||
const serviceManager = getServiceManager();
|
||||
|
||||
logger.info({ platform, nodePath, projectRoot }, 'Setting up service');
|
||||
|
||||
|
||||
Reference in New Issue
Block a user