feat(openclaw): add repair function for ClawX-only bootstrap files an… (#180)
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
import { existsSync, readFileSync, writeFileSync, readdirSync, mkdirSync } from 'fs';
|
||||
import { existsSync, readFileSync, writeFileSync, readdirSync, mkdirSync, unlinkSync } from 'fs';
|
||||
import { join } from 'path';
|
||||
import { homedir } from 'os';
|
||||
import { logger } from './logger';
|
||||
@@ -22,6 +22,49 @@ export function mergeClawXSection(existing: string, section: string): string {
|
||||
return existing.trimEnd() + '\n\n' + wrapped + '\n';
|
||||
}
|
||||
|
||||
/**
|
||||
* Detect and remove bootstrap .md files that contain only ClawX markers
|
||||
* with no meaningful OpenClaw content outside them. This repairs a race
|
||||
* condition where ensureClawXContext() created the file before the gateway
|
||||
* could seed the full template. Deleting the hollow file lets the gateway
|
||||
* re-seed the complete template on next start.
|
||||
*/
|
||||
export function repairClawXOnlyBootstrapFiles(): void {
|
||||
const workspaceDirs = resolveAllWorkspaceDirs();
|
||||
for (const workspaceDir of workspaceDirs) {
|
||||
if (!existsSync(workspaceDir)) continue;
|
||||
let entries: string[];
|
||||
try {
|
||||
entries = readdirSync(workspaceDir).filter((f) => f.endsWith('.md'));
|
||||
} catch {
|
||||
continue;
|
||||
}
|
||||
for (const file of entries) {
|
||||
const filePath = join(workspaceDir, file);
|
||||
let content: string;
|
||||
try {
|
||||
content = readFileSync(filePath, 'utf-8');
|
||||
} catch {
|
||||
continue;
|
||||
}
|
||||
const beginIdx = content.indexOf(CLAWX_BEGIN);
|
||||
const endIdx = content.indexOf(CLAWX_END);
|
||||
if (beginIdx === -1 || endIdx === -1) continue;
|
||||
|
||||
const before = content.slice(0, beginIdx).trim();
|
||||
const after = content.slice(endIdx + CLAWX_END.length).trim();
|
||||
if (before === '' && after === '') {
|
||||
try {
|
||||
unlinkSync(filePath);
|
||||
logger.info(`Removed ClawX-only bootstrap file for re-seeding: ${file} (${workspaceDir})`);
|
||||
} catch {
|
||||
logger.warn(`Failed to remove ClawX-only bootstrap file: ${filePath}`);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Collect all unique workspace directories from the openclaw config:
|
||||
* the defaults workspace, each agent's workspace, and any workspace-*
|
||||
@@ -105,13 +148,15 @@ export function ensureClawXContext(): void {
|
||||
for (const file of files) {
|
||||
const targetName = file.replace('.clawx.md', '.md');
|
||||
const targetPath = join(workspaceDir, targetName);
|
||||
const section = readFileSync(join(contextDir, file), 'utf-8');
|
||||
|
||||
let existing = '';
|
||||
if (existsSync(targetPath)) {
|
||||
existing = readFileSync(targetPath, 'utf-8');
|
||||
if (!existsSync(targetPath)) {
|
||||
logger.debug(`Skipping ${targetName} in ${workspaceDir} (file does not exist yet, will be seeded by gateway)`);
|
||||
continue;
|
||||
}
|
||||
|
||||
const section = readFileSync(join(contextDir, file), 'utf-8');
|
||||
const existing = readFileSync(targetPath, 'utf-8');
|
||||
|
||||
const merged = mergeClawXSection(existing, section);
|
||||
if (merged !== existing) {
|
||||
writeFileSync(targetPath, merged, 'utf-8');
|
||||
|
||||
Reference in New Issue
Block a user