fix(start-work): restore atlas-first slash discovery

Static slash-command discovery runs before agent registration, so /start-work regressed to Sisyphus even though config-time wiring still needed Atlas-aware fallback. Split builtin command resolution so discovery stays Atlas-first while command config remains availability-aware.

Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
This commit is contained in:
YeonGyu-Kim
2026-04-01 17:32:46 -07:00
parent 1fed569cab
commit 724d21b3cc
5 changed files with 65 additions and 7 deletions
+12 -2
View File
@@ -69,12 +69,22 @@ describe("loadBuiltinCommands", () => {
expect(commands.handoff.description).toContain("context summary") expect(commands.handoff.description).toContain("context summary")
}) })
test("should preassign Sisyphus as the native agent for start-work", () => { test("should default start-work to Atlas for static slash-command discovery", () => {
//#given - no disabled commands //#given - no disabled commands
//#when //#when
const commands = loadBuiltinCommands() const commands = loadBuiltinCommands()
//#then
expect(commands["start-work"].agent).toBe("atlas")
})
test("should preassign Sisyphus as the native agent for start-work when command config checks registered agents", () => {
//#given - no atlas registration
//#when
const commands = loadBuiltinCommands(undefined, { useRegisteredAgents: true })
//#then //#then
expect(commands["start-work"].agent).toBe("sisyphus") expect(commands["start-work"].agent).toBe("sisyphus")
}) })
@@ -84,7 +94,7 @@ describe("loadBuiltinCommands", () => {
registerAgentName("atlas") registerAgentName("atlas")
//#when //#when
const commands = loadBuiltinCommands() const commands = loadBuiltinCommands(undefined, { useRegisteredAgents: true })
//#then //#then
expect(commands["start-work"].agent).toBe("atlas") expect(commands["start-work"].agent).toBe("atlas")
+19 -4
View File
@@ -9,7 +9,21 @@ import { START_WORK_TEMPLATE } from "./templates/start-work"
import { HANDOFF_TEMPLATE } from "./templates/handoff" import { HANDOFF_TEMPLATE } from "./templates/handoff"
import { REMOVE_AI_SLOPS_TEMPLATE } from "./templates/remove-ai-slops" import { REMOVE_AI_SLOPS_TEMPLATE } from "./templates/remove-ai-slops"
function createBuiltinCommandDefinitions(): Record<BuiltinCommandName, Omit<CommandDefinition, "name">> { export interface LoadBuiltinCommandsOptions {
useRegisteredAgents?: boolean
}
function resolveStartWorkAgent(options?: LoadBuiltinCommandsOptions): "atlas" | "sisyphus" {
if (options?.useRegisteredAgents) {
return isAgentRegistered("atlas") ? "atlas" : "sisyphus"
}
return "atlas"
}
function createBuiltinCommandDefinitions(
options?: LoadBuiltinCommandsOptions,
): Record<BuiltinCommandName, Omit<CommandDefinition, "name">> {
return { return {
"init-deep": { "init-deep": {
description: "(builtin) Initialize hierarchical AGENTS.md knowledge base", description: "(builtin) Initialize hierarchical AGENTS.md knowledge base",
@@ -60,7 +74,7 @@ ${REFACTOR_TEMPLATE}
}, },
"start-work": { "start-work": {
description: "(builtin) Start Sisyphus work session from Prometheus plan", description: "(builtin) Start Sisyphus work session from Prometheus plan",
agent: isAgentRegistered("atlas") ? "atlas" : "sisyphus", agent: resolveStartWorkAgent(options),
template: `<command-instruction> template: `<command-instruction>
${START_WORK_TEMPLATE} ${START_WORK_TEMPLATE}
</command-instruction> </command-instruction>
@@ -111,9 +125,10 @@ $ARGUMENTS
} }
export function loadBuiltinCommands( export function loadBuiltinCommands(
disabledCommands?: BuiltinCommandName[] disabledCommands?: BuiltinCommandName[],
options?: LoadBuiltinCommandsOptions,
): BuiltinCommands { ): BuiltinCommands {
const builtinCommandDefinitions = createBuiltinCommandDefinitions() const builtinCommandDefinitions = createBuiltinCommandDefinitions(options)
const disabled = new Set(disabledCommands ?? []) const disabled = new Set(disabledCommands ?? [])
const commands: BuiltinCommands = {} const commands: BuiltinCommands = {}
@@ -192,4 +192,24 @@ describe("auto-slash command executor plugin dispatch", () => {
expect(result.replacementText).not.toContain("$ARGUMENTS") expect(result.replacementText).not.toContain("$ARGUMENTS")
expect(result.replacementText).not.toContain("${user_message}") expect(result.replacementText).not.toContain("${user_message}")
}) })
it("renders Atlas as the builtin start-work agent during slash-command execution", async () => {
// given
// when
const result = await executeSlashCommand(
{
command: "start-work",
args: "",
raw: "/start-work",
},
{
skills: [],
},
)
// then
expect(result.success).toBe(true)
expect(result.replacementText).toContain("**Agent**: atlas")
})
}) })
@@ -30,7 +30,9 @@ export async function applyCommandConfig(params: {
ctx: { directory: string }; ctx: { directory: string };
pluginComponents: PluginComponents; pluginComponents: PluginComponents;
}): Promise<void> { }): Promise<void> {
const builtinCommands = loadBuiltinCommands(params.pluginConfig.disabled_commands); const builtinCommands = loadBuiltinCommands(params.pluginConfig.disabled_commands, {
useRegisteredAgents: true,
});
const systemCommands = (params.config.command as Record<string, unknown>) ?? {}; const systemCommands = (params.config.command as Record<string, unknown>) ?? {};
const includeClaudeCommands = params.pluginConfig.claude_code?.commands ?? true; const includeClaudeCommands = params.pluginConfig.claude_code?.commands ?? true;
@@ -255,4 +255,15 @@ Use nested command.
expect(nestedCommand?.content).toContain("Use nested command.") expect(nestedCommand?.content).toContain("Use nested command.")
expect(nestedCommand?.scope).toBe("opencode-project") expect(nestedCommand?.scope).toBe("opencode-project")
}) })
it("keeps builtin start-work routed to Atlas during static discovery", () => {
// given
// when
const commands = discoverCommandsSync(projectDir)
const startWorkCommand = commands.find((command) => command.name === "start-work")
// then
expect(startWorkCommand?.metadata.agent).toBe("atlas")
})
}) })