feat(start-work): use getWorkResumeOptions for multi-work resume selection

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-05-11 13:40:57 +09:00
parent 29b44fffd0
commit d6f4199cab
2 changed files with 302 additions and 7 deletions
+131 -7
View File
@@ -1,13 +1,17 @@
import { statSync } from "node:fs"
import {
appendSessionId,
clearBoulderState,
addBoulderWork,
createBoulderState,
findPrometheusPlans,
getActiveWorks,
getPlanName,
getPlanProgress,
getWorkByPlanName,
getWorkResumeOptions,
readBoulderState,
resolveBoulderPlanPath,
selectActiveWork,
writeBoulderState,
} from "../../features/boulder-state"
import { log } from "../../shared/logger"
@@ -99,9 +103,73 @@ Ask the user which plan to work on.`
No incomplete plans available. Create a new plan using the Prometheus agent.`
}
function formatElapsedHuman(elapsedMs: number | undefined): string {
if (typeof elapsedMs !== "number" || elapsedMs <= 0) {
return "running"
}
const totalSeconds = Math.floor(elapsedMs / 1000)
const seconds = totalSeconds % 60
const totalMinutes = Math.floor(totalSeconds / 60)
const minutes = totalMinutes % 60
const hours = Math.floor(totalMinutes / 60)
if (hours > 0) {
return `${hours}h ${minutes}m ${seconds}s`
}
if (minutes > 0) {
return `${minutes}m ${seconds}s`
}
return `${seconds}s`
}
function buildMultipleActiveWorksContext(params: {
resumeOptions: ReturnType<typeof getWorkResumeOptions>
sessionId: string
timestamp: string
}): string {
const { resumeOptions, sessionId, timestamp } = params
const optionList = resumeOptions
.map((option, index) => `${index + 1}. ${option.plan_name} - ${option.progress.completed}/${option.progress.total} (${option.progress.total === 0 ? 0 : Math.floor((option.progress.completed / option.progress.total) * 100)}%) - elapsed: ${formatElapsedHuman(option.elapsed_ms)} - worktree: ${option.worktree_path ?? "current directory"} - sessions: ${option.session_count}`)
.join("\n")
return `
<system-reminder>
## Multiple Active Works Found
Current Time: ${timestamp}
Session ID: ${sessionId}
${optionList}
Use the Question tool to ask the user which plan to resume.
- If the user chooses one option, run /start-work {plan-name} for that plan.
- If the user chooses to start a new plan, proceed with cold-start auto-selection flow.
</system-reminder>`
}
function createNewWorkOrInitialize(params: {
directory: string
planPath: string
sessionId: string
activeAgent: string
worktreePath: string | undefined
}): void {
const { directory, planPath, sessionId, activeAgent, worktreePath } = params
const created = addBoulderWork(directory, {
planPath,
sessionId,
agent: activeAgent,
worktreePath,
})
if (!created) {
const initializedState = createBoulderState(planPath, sessionId, activeAgent, worktreePath)
writeBoulderState(directory, initializedState)
}
}
function buildExplicitPlanContext(params: {
explicitPlanName: string
existingState: ReturnType<typeof readBoulderState>
sessionId: string
timestamp: string
activeAgent: string
@@ -109,9 +177,24 @@ function buildExplicitPlanContext(params: {
worktreeBlock: string
directory: string
}): string {
const { explicitPlanName, existingState, sessionId, timestamp, activeAgent, worktreePath, worktreeBlock, directory } = params
const { explicitPlanName, sessionId, timestamp, activeAgent, worktreePath, worktreeBlock, directory } = params
log(`[${HOOK_NAME}] Explicit plan name requested: ${explicitPlanName}`, { sessionID: sessionId })
const matchedWork = getWorkByPlanName(directory, explicitPlanName, { worktreePath })
if (matchedWork) {
const selectedState = selectActiveWork(directory, matchedWork.work_id)
if (selectedState) {
return buildExistingSessionContext({
existingState: selectedState,
sessionId,
activeAgent,
worktreePath,
worktreeBlock,
directory,
})
}
}
const allPlans = findPrometheusPlans(directory)
const matchedPlan = findPlanByName(allPlans, explicitPlanName)
if (!matchedPlan) {
@@ -127,9 +210,13 @@ function buildExplicitPlanContext(params: {
All ${progress.total} tasks are done. Create a new plan using the Prometheus agent.`
}
if (existingState) {
clearBoulderState(directory)
}
createNewWorkOrInitialize({
directory,
planPath: matchedPlan,
sessionId,
activeAgent,
worktreePath,
})
return buildAutoSelectedPlanContext({
planPath: matchedPlan,
@@ -287,11 +374,48 @@ export function buildStartWorkContextInfo(params: {
}): string {
const { ctx, explicitPlanName, existingState, sessionId, timestamp, activeAgent, worktreePath, worktreeBlock } = params
const resumeOptions = getWorkResumeOptions(ctx.directory)
.filter((option) => option.status === "active" || option.status === "paused")
if (!explicitPlanName && resumeOptions.length > 1) {
return buildMultipleActiveWorksContext({
resumeOptions,
sessionId,
timestamp,
})
}
if (!explicitPlanName && resumeOptions.length === 1) {
const onlyOption = resumeOptions[0]
const selectedState = selectActiveWork(ctx.directory, onlyOption.work_id)
if (selectedState) {
return buildExistingSessionContext({
existingState: selectedState,
sessionId,
activeAgent,
worktreePath,
worktreeBlock,
directory: ctx.directory,
})
}
}
if (!explicitPlanName && resumeOptions.length === 0 && getActiveWorks(ctx.directory).length === 0) {
return buildPlanDiscoveryContext({
contextInfo: "",
sessionId,
timestamp,
activeAgent,
worktreePath,
worktreeBlock,
directory: ctx.directory,
})
}
let contextInfo = ""
if (explicitPlanName) {
contextInfo = buildExplicitPlanContext({
explicitPlanName,
existingState,
sessionId,
timestamp,
activeAgent,