diff --git a/src/features/builtin-commands/commands.ts b/src/features/builtin-commands/commands.ts index 0802eb9aa..7973ee972 100644 --- a/src/features/builtin-commands/commands.ts +++ b/src/features/builtin-commands/commands.ts @@ -4,33 +4,40 @@ import { INIT_DEEP_TEMPLATE } from "./templates/init-deep" import { RALPH_LOOP_TEMPLATE, ULW_LOOP_TEMPLATE, CANCEL_RALPH_TEMPLATE } from "./templates/ralph-loop" import { STOP_CONTINUATION_TEMPLATE } from "./templates/stop-continuation" import { REFACTOR_TEMPLATE } from "./templates/refactor" -import { START_WORK_TEMPLATE } from "./templates/start-work" +import { createStartWorkTemplate } from "./templates/start-work" import { HANDOFF_TEMPLATE } from "./templates/handoff" -const BUILTIN_COMMAND_DEFINITIONS: Record> = { - "init-deep": { - description: "(builtin) Initialize hierarchical AGENTS.md knowledge base", - template: ` +export function loadBuiltinCommands( + disabledCommands?: BuiltinCommandName[], + startWorkConfig?: { worktree?: boolean } +): BuiltinCommands { + const disabled = new Set(disabledCommands ?? []) + const startWorkTemplate = createStartWorkTemplate({ worktreeEnabled: startWorkConfig?.worktree ?? true }) + + const definitions: Record> = { + "init-deep": { + description: "(builtin) Initialize hierarchical AGENTS.md knowledge base", + template: ` ${INIT_DEEP_TEMPLATE} $ARGUMENTS `, - argumentHint: "[--create-new] [--max-depth=N]", - }, - "ralph-loop": { - description: "(builtin) Start self-referential development loop until completion", - template: ` + argumentHint: "[--create-new] [--max-depth=N]", + }, + "ralph-loop": { + description: "(builtin) Start self-referential development loop until completion", + template: ` ${RALPH_LOOP_TEMPLATE} $ARGUMENTS `, - argumentHint: '"task description" [--completion-promise=TEXT] [--max-iterations=N] [--strategy=reset|continue]', - }, - "ulw-loop": { + argumentHint: '"task description" [--completion-promise=TEXT] [--max-iterations=N] [--strategy=reset|continue]', + }, + "ulw-loop": { description: "(builtin) Start ultrawork loop - continues until completion with ultrawork mode", template: ` ${ULW_LOOP_TEMPLATE} @@ -41,25 +48,25 @@ $ARGUMENTS `, argumentHint: '"task description" [--completion-promise=TEXT] [--strategy=reset|continue]', }, - "cancel-ralph": { - description: "(builtin) Cancel active Ralph Loop", - template: ` + "cancel-ralph": { + description: "(builtin) Cancel active Ralph Loop", + template: ` ${CANCEL_RALPH_TEMPLATE} `, - }, - refactor: { - description: - "(builtin) Intelligent refactoring command with LSP, AST-grep, architecture analysis, codemap, and TDD verification.", - template: ` + }, + refactor: { + description: + "(builtin) Intelligent refactoring command with LSP, AST-grep, architecture analysis, codemap, and TDD verification.", + template: ` ${REFACTOR_TEMPLATE} `, - argumentHint: " [--scope=] [--strategy=]", - }, - "start-work": { - description: "(builtin) Start Sisyphus work session from Prometheus plan", - agent: "atlas", - template: ` -${START_WORK_TEMPLATE} + argumentHint: " [--scope=] [--strategy=]", + }, + "start-work": { + description: "(builtin) Start Sisyphus work session from Prometheus plan", + agent: "atlas", + template: ` +${startWorkTemplate} @@ -70,17 +77,17 @@ Timestamp: $TIMESTAMP $ARGUMENTS `, - argumentHint: "[plan-name]", - }, - "stop-continuation": { - description: "(builtin) Stop all continuation mechanisms (ralph loop, todo continuation, boulder) for this session", - template: ` + argumentHint: "[plan-name]", + }, + "stop-continuation": { + description: "(builtin) Stop all continuation mechanisms (ralph loop, todo continuation, boulder) for this session", + template: ` ${STOP_CONTINUATION_TEMPLATE} `, - }, - handoff: { - description: "(builtin) Create a detailed context summary for continuing work in a new session", - template: ` + }, + handoff: { + description: "(builtin) Create a detailed context summary for continuing work in a new session", + template: ` ${HANDOFF_TEMPLATE} @@ -92,17 +99,13 @@ Timestamp: $TIMESTAMP $ARGUMENTS `, - argumentHint: "[goal]", - }, -} + argumentHint: "[goal]", + }, + } -export function loadBuiltinCommands( - disabledCommands?: BuiltinCommandName[] -): BuiltinCommands { - const disabled = new Set(disabledCommands ?? []) const commands: BuiltinCommands = {} - for (const [name, definition] of Object.entries(BUILTIN_COMMAND_DEFINITIONS)) { + for (const [name, definition] of Object.entries(definitions)) { if (!disabled.has(name as BuiltinCommandName)) { const { argumentHint: _argumentHint, ...openCodeCompatible } = definition commands[name] = { ...openCodeCompatible, name } as CommandDefinition diff --git a/src/features/builtin-commands/templates/start-work.ts b/src/features/builtin-commands/templates/start-work.ts index 98ffd1e21..0e4ea02ca 100644 --- a/src/features/builtin-commands/templates/start-work.ts +++ b/src/features/builtin-commands/templates/start-work.ts @@ -1,13 +1,47 @@ -export const START_WORK_TEMPLATE = `You are starting a Sisyphus work session. +export function createStartWorkTemplate(options?: { worktreeEnabled?: boolean }): string { + const worktreeEnabled = options?.worktreeEnabled ?? true -## ARGUMENTS - -- \`/start-work [plan-name] [--worktree ]\` + const argumentsSection = worktreeEnabled + ? `- \`/start-work [plan-name] [--worktree ]\` - \`plan-name\` (optional): name or partial match of the plan to start - \`--worktree \` (optional): absolute path to an existing git worktree to work in - If specified and valid: hook pre-sets worktree_path in boulder.json - If specified but invalid: you must run \`git worktree add \` first - - If omitted: you MUST choose or create a worktree (see Worktree Setup below) + - If omitted: you MUST choose or create a worktree (see Worktree Setup below)` + : `- \`/start-work [plan-name]\` + - \`plan-name\` (optional): name or partial match of the plan to start` + + const worktreeSetupSection = worktreeEnabled + ? ` +4. **Worktree Setup** (when \`worktree_path\` not already set in boulder.json): + 1. \`git worktree list --porcelain\` — see available worktrees + 2. Create: \`git worktree add \` + 3. Update boulder.json to add \`"worktree_path": ""\` + 4. All work happens inside that worktree directory +` + : `` + + const boulderJsonWorktreeLine = worktreeEnabled + ? ` "worktree_path": "/absolute/path/to/git/worktree"\n` + : `` + + const resumingWorktreeLine = worktreeEnabled + ? `Worktree: {worktree_path}\n` + : `` + + const startingWorktreeLine = worktreeEnabled + ? `Worktree: {worktree_path}\n` + : `` + + const worktreeCritical = worktreeEnabled + ? `- Always set worktree_path in boulder.json before executing any tasks\n` + : `` + + return `You are starting a Sisyphus work session. + +## ARGUMENTS + +${argumentsSection} ## WHAT TO DO @@ -23,25 +57,18 @@ export const START_WORK_TEMPLATE = `You are starting a Sisyphus work session. - List available plan files - If ONE plan: auto-select it - If MULTIPLE plans: show list with timestamps, ask user to select - -4. **Worktree Setup** (when \`worktree_path\` not already set in boulder.json): - 1. \`git worktree list --porcelain\` — see available worktrees - 2. Create: \`git worktree add \` - 3. Update boulder.json to add \`"worktree_path": ""\` - 4. All work happens inside that worktree directory - -5. **Create/Update boulder.json**: +${worktreeSetupSection} +${worktreeEnabled ? "5" : "4"}. **Create/Update boulder.json**: \`\`\`json { "active_plan": "/absolute/path/to/plan.md", "started_at": "ISO_TIMESTAMP", "session_ids": ["session_id_1", "session_id_2"], - "plan_name": "plan-name", - "worktree_path": "/absolute/path/to/git/worktree" + "plan_name": "plan-name"${worktreeEnabled ? `,\n "worktree_path": "/absolute/path/to/git/worktree"` : ""} } \`\`\` -6. **Read the plan file** and start executing tasks according to atlas workflow +${worktreeEnabled ? "6" : "5"}. **Read the plan file** and start executing tasks according to atlas workflow ## OUTPUT FORMAT @@ -65,8 +92,7 @@ Resuming Work Session Active Plan: {plan-name} Progress: {completed}/{total} tasks Sessions: {count} (appending current session) -Worktree: {worktree_path} - +${resumingWorktreeLine} Reading plan and continuing from last incomplete task... \`\`\` @@ -77,8 +103,7 @@ Starting Work Session Plan: {plan-name} Session ID: {session_id} Started: {timestamp} -Worktree: {worktree_path} - +${startingWorktreeLine} Reading plan and beginning execution... \`\`\` @@ -86,6 +111,8 @@ Reading plan and beginning execution... - The session_id is injected by the hook - use it directly - Always update boulder.json BEFORE starting work -- Always set worktree_path in boulder.json before executing any tasks -- Read the FULL plan file before delegating any tasks +${worktreeCritical}- Read the FULL plan file before delegating any tasks - Follow atlas delegation protocols (7-section format)` +} + +export const START_WORK_TEMPLATE = createStartWorkTemplate() diff --git a/src/plugin-handlers/command-config-handler.ts b/src/plugin-handlers/command-config-handler.ts index a5cb0e946..a1c3a196d 100644 --- a/src/plugin-handlers/command-config-handler.ts +++ b/src/plugin-handlers/command-config-handler.ts @@ -23,7 +23,10 @@ export async function applyCommandConfig(params: { ctx: { directory: string }; pluginComponents: PluginComponents; }): Promise { - const builtinCommands = loadBuiltinCommands(params.pluginConfig.disabled_commands); + const builtinCommands = loadBuiltinCommands( + params.pluginConfig.disabled_commands, + params.pluginConfig.start_work + ); const systemCommands = (params.config.command as Record) ?? {}; const includeClaudeCommands = params.pluginConfig.claude_code?.commands ?? true;