Files
devclaw-gitea/lib/setup/workspace.ts
Lauren ten Hoor 862813e6d3 refactor: restructure workspace file organization (#121) (#122)
## Path Changes
- audit.log: memory/audit.log → log/audit.log
- projects.json: memory/projects.json → projects/projects.json
- prompts: roles/<project>/<role>.md → projects/prompts/<project>/<role>.md

## Files Updated
- lib/audit.ts - new audit log path
- lib/projects.ts - new projects.json path
- lib/dispatch.ts - new prompt instructions path
- lib/tools/project-register.ts - prompt scaffolding path
- lib/setup/workspace.ts - workspace scaffolding paths
- lib/context-guard.ts - projects.json path
- lib/tools/setup.ts - tool description
- lib/templates.ts - AGENTS.md template path references

## Documentation Updated
- README.md
- docs/ARCHITECTURE.md
- docs/ONBOARDING.md
- docs/QA_WORKFLOW.md
- docs/ROADMAP.md
- docs/TESTING.md

Addresses issue #121
2026-02-11 01:55:26 +08:00

66 lines
2.0 KiB
TypeScript

/**
* setup/workspace.ts — Workspace file scaffolding.
*
* Writes AGENTS.md, HEARTBEAT.md, default role instructions, and projects.json.
*/
import fs from "node:fs/promises";
import path from "node:path";
import {
AGENTS_MD_TEMPLATE,
HEARTBEAT_MD_TEMPLATE,
} from "../templates.js";
/**
* Write all workspace files for a DevClaw agent.
* Returns the list of files that were written (skips files that already exist).
*/
export async function scaffoldWorkspace(workspacePath: string): Promise<string[]> {
const filesWritten: string[] = [];
// AGENTS.md (backup existing)
await backupAndWrite(path.join(workspacePath, "AGENTS.md"), AGENTS_MD_TEMPLATE);
filesWritten.push("AGENTS.md");
// HEARTBEAT.md
await backupAndWrite(path.join(workspacePath, "HEARTBEAT.md"), HEARTBEAT_MD_TEMPLATE);
filesWritten.push("HEARTBEAT.md");
// projects/projects.json
const projectsDir = path.join(workspacePath, "projects");
await fs.mkdir(projectsDir, { recursive: true });
const projectsJsonPath = path.join(projectsDir, "projects.json");
if (!await fileExists(projectsJsonPath)) {
await fs.writeFile(projectsJsonPath, JSON.stringify({ projects: {} }, null, 2) + "\n", "utf-8");
filesWritten.push("projects/projects.json");
}
// log/ directory (audit.log created on first write)
const logDir = path.join(workspacePath, "log");
await fs.mkdir(logDir, { recursive: true });
return filesWritten;
}
// ---------------------------------------------------------------------------
// Private helpers
// ---------------------------------------------------------------------------
async function backupAndWrite(filePath: string, content: string): Promise<void> {
try {
await fs.access(filePath);
await fs.copyFile(filePath, filePath + ".bak");
} catch {
await fs.mkdir(path.dirname(filePath), { recursive: true });
}
await fs.writeFile(filePath, content, "utf-8");
}
async function fileExists(filePath: string): Promise<boolean> {
try {
await fs.access(filePath);
return true;
} catch {
return false;
}
}