From d0d1bdda607c6a0f3ea27c3ebfae3f77c2190527 Mon Sep 17 00:00:00 2001 From: Lauren ten Hoor Date: Mon, 16 Feb 2026 14:57:17 +0800 Subject: [PATCH] feat: enhance workspace scaffolding with new identity and soul templates, and support for default user file --- lib/setup/index.ts | 12 +++++++++- lib/setup/workspace.ts | 36 ++++++++++++++++++++++++++-- lib/templates.ts | 54 ++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 99 insertions(+), 3 deletions(-) diff --git a/lib/setup/index.ts b/lib/setup/index.ts index 7817b9e..b3d8a10 100644 --- a/lib/setup/index.ts +++ b/lib/setup/index.ts @@ -66,7 +66,8 @@ export async function runSetup(opts: SetupOpts): Promise { await writePluginConfig(opts.api, agentId, opts.projectExecution); - const filesWritten = await scaffoldWorkspace(workspacePath); + const defaultWorkspacePath = getDefaultWorkspacePath(opts.api); + const filesWritten = await scaffoldWorkspace(workspacePath, defaultWorkspacePath); const models = buildModelConfig(opts.models); await writeModelsToWorkflow(workspacePath, models); @@ -140,6 +141,15 @@ function buildModelConfig(overrides?: SetupOpts["models"]): ModelConfig { return result; } +function getDefaultWorkspacePath(api: OpenClawPluginApi): string | undefined { + try { + const config = api.runtime.config.loadConfig(); + return (config as any).agents?.defaults?.workspace ?? undefined; + } catch { + return undefined; + } +} + /** * Write model configuration to workflow.yaml (single source of truth). * Reads the existing workflow.yaml, merges model overrides into the roles section, and writes back. diff --git a/lib/setup/workspace.ts b/lib/setup/workspace.ts index dbbf651..1e9223c 100644 --- a/lib/setup/workspace.ts +++ b/lib/setup/workspace.ts @@ -8,6 +8,8 @@ import path from "node:path"; import { AGENTS_MD_TEMPLATE, HEARTBEAT_MD_TEMPLATE, + IDENTITY_MD_TEMPLATE, + SOUL_MD_TEMPLATE, WORKFLOW_YAML_TEMPLATE, DEFAULT_ROLE_INSTRUCTIONS, } from "../templates.js"; @@ -57,21 +59,51 @@ export async function ensureDefaultFiles(workspacePath: string): Promise { /** * Write all workspace files for a DevClaw agent. * Returns the list of files that were written (skips files that already exist). + * + * @param defaultWorkspacePath — If provided, USER.md is copied from here (only if not already present). */ -export async function scaffoldWorkspace(workspacePath: string): Promise { +export async function scaffoldWorkspace(workspacePath: string, defaultWorkspacePath?: string): Promise { // Migrate old layout if detected await migrateWorkspaceLayout(workspacePath); + const written: string[] = []; + // AGENTS.md (backup existing — stays at workspace root) await backupAndWrite(path.join(workspacePath, "AGENTS.md"), AGENTS_MD_TEMPLATE); + written.push("AGENTS.md"); // HEARTBEAT.md (stays at workspace root) await backupAndWrite(path.join(workspacePath, "HEARTBEAT.md"), HEARTBEAT_MD_TEMPLATE); + written.push("HEARTBEAT.md"); + + // IDENTITY.md (create-only — never overwrite user customizations) + const identityPath = path.join(workspacePath, "IDENTITY.md"); + if (!await fileExists(identityPath)) { + await fs.writeFile(identityPath, IDENTITY_MD_TEMPLATE, "utf-8"); + written.push("IDENTITY.md"); + } + + // SOUL.md (create-only — never overwrite user customizations) + const soulPath = path.join(workspacePath, "SOUL.md"); + if (!await fileExists(soulPath)) { + await fs.writeFile(soulPath, SOUL_MD_TEMPLATE, "utf-8"); + written.push("SOUL.md"); + } + + // USER.md — copy from default workspace if available (create-only) + const userPath = path.join(workspacePath, "USER.md"); + if (!await fileExists(userPath) && defaultWorkspacePath) { + const sourceUser = path.join(defaultWorkspacePath, "USER.md"); + if (await fileExists(sourceUser)) { + await fs.copyFile(sourceUser, userPath); + written.push("USER.md"); + } + } // Ensure all data-dir defaults (workflow.yaml, prompts, etc.) await ensureDefaultFiles(workspacePath); - return ["AGENTS.md", "HEARTBEAT.md"]; + return written; } // --------------------------------------------------------------------------- diff --git a/lib/templates.ts b/lib/templates.ts index 57f4d1a..dd1ac5c 100644 --- a/lib/templates.ts +++ b/lib/templates.ts @@ -226,6 +226,10 @@ All orchestration goes through these tools. You do NOT manually manage sessions, | \`work_finish\` | End-to-end: label transition, state update, issue close/reopen | | \`design_task\` | Spawn an architect for design investigation. Creates To Design issue and dispatches architect | +### First Thing on Session Start + +**Always call \`status\` first** when you start a new session. This tells you which projects you manage, what's in the queue, and which workers are active. Don't guess — check. + ### Pipeline Flow \`\`\` @@ -295,6 +299,56 @@ export const HEARTBEAT_MD_TEMPLATE = `# HEARTBEAT.md Do nothing. An internal token-free heartbeat service handles health checks and queue dispatch automatically. `; +export const IDENTITY_MD_TEMPLATE = `# IDENTITY.md - Who Am I? + +- **Name:** DevClaw +- **Creature:** Development orchestrator — plans, dispatches, never codes +- **Vibe:** Direct, decisive, transparent. No fluff. +- **Emoji:** 🦞 +`; + +export const SOUL_MD_TEMPLATE = `# SOUL.md - DevClaw Orchestrator Identity + +You are a **development orchestrator** — you plan, prioritize, and dispatch. You never write code yourself. + +## Core Principles + +**Be direct.** Skip pleasantries, get to the point. Say what you're doing and why. + +**Be decisive.** Evaluate task complexity, pick the right level, dispatch. Don't deliberate when the answer is obvious. + +**Be transparent.** Always include issue URLs. Always explain what happened and what's next. No black boxes. + +**Be resourceful.** Check status before asking. Read the issue before dispatching. Understand the codebase before planning. Come back with answers, not questions. + +## How You Work + +- You receive requests via chat (Telegram, WhatsApp, or web) +- You break work into issues, assign complexity levels, and dispatch workers +- Workers (developer, tester, architect) do the actual work in isolated sessions +- You track progress, handle failures, and keep the human informed +- The heartbeat runs automatically — you don't manage it + +## Communication Style + +- Concise status updates with issue links +- Use the announcement format from tool responses +- Flag blockers and failures immediately +- Don't over-explain routine operations + +## Boundaries + +- **Never write code** — dispatch a developer worker +- **Never skip testing** — every code change goes through QA +- **Never close issues** without a tester pass +- **Ask before** architectural decisions affecting multiple projects + +## Continuity + +Each session starts fresh. AGENTS.md defines your operational procedures. This file defines who you are. USER.md tells you about the humans you work with. Update these files as you learn. +`; + + /** * Generate WORKFLOW_YAML_TEMPLATE from the runtime objects (single source of truth). */