feat(boulder-state): add BoulderWorkState and timing fields to types
Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent) Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
This commit is contained in:
@@ -0,0 +1,78 @@
|
|||||||
|
import { describe, expect, test } from "bun:test"
|
||||||
|
import type {
|
||||||
|
BoulderSessionOrigin,
|
||||||
|
BoulderState,
|
||||||
|
BoulderTaskStatus,
|
||||||
|
BoulderWorkResumeOption,
|
||||||
|
BoulderWorkState,
|
||||||
|
BoulderWorkStatus,
|
||||||
|
PlanProgress,
|
||||||
|
TaskSessionState,
|
||||||
|
} from "./types"
|
||||||
|
|
||||||
|
describe("boulder-state types", () => {
|
||||||
|
test("keeps legacy BoulderState assignable while allowing v2 fields", () => {
|
||||||
|
// given
|
||||||
|
const legacyState: BoulderState = {
|
||||||
|
active_plan: "/tmp/plan.md",
|
||||||
|
started_at: "2026-01-01T00:00:00.000Z",
|
||||||
|
session_ids: ["ses_1"],
|
||||||
|
plan_name: "plan",
|
||||||
|
}
|
||||||
|
|
||||||
|
// when
|
||||||
|
const hasLegacyShape = legacyState.active_plan.length > 0
|
||||||
|
|
||||||
|
// then
|
||||||
|
expect(hasLegacyShape).toBe(true)
|
||||||
|
})
|
||||||
|
|
||||||
|
test("supports multi-work and timer fields", () => {
|
||||||
|
// given
|
||||||
|
const taskStatus: BoulderTaskStatus = "running"
|
||||||
|
const workStatus: BoulderWorkStatus = "active"
|
||||||
|
const origin: BoulderSessionOrigin = "direct"
|
||||||
|
|
||||||
|
const taskSession: TaskSessionState = {
|
||||||
|
task_key: "todo:1",
|
||||||
|
task_label: "1",
|
||||||
|
task_title: "Do work",
|
||||||
|
session_id: "ses_task",
|
||||||
|
started_at: "2026-01-01T00:00:00.000Z",
|
||||||
|
ended_at: "2026-01-01T00:00:01.000Z",
|
||||||
|
elapsed_ms: 1000,
|
||||||
|
status: taskStatus,
|
||||||
|
updated_at: "2026-01-01T00:00:01.000Z",
|
||||||
|
}
|
||||||
|
|
||||||
|
const work: BoulderWorkState = {
|
||||||
|
work_id: "plan-abc12345",
|
||||||
|
active_plan: "/tmp/plan.md",
|
||||||
|
plan_name: "plan",
|
||||||
|
status: workStatus,
|
||||||
|
started_at: "2026-01-01T00:00:00.000Z",
|
||||||
|
session_ids: ["ses_1"],
|
||||||
|
session_origins: { ses_1: origin },
|
||||||
|
task_sessions: { "todo:1": taskSession },
|
||||||
|
}
|
||||||
|
|
||||||
|
const progress: PlanProgress = { total: 2, completed: 1, isComplete: false }
|
||||||
|
const resumeOption: BoulderWorkResumeOption = {
|
||||||
|
work_id: work.work_id,
|
||||||
|
plan_name: work.plan_name,
|
||||||
|
active_plan: work.active_plan,
|
||||||
|
status: "paused",
|
||||||
|
started_at: work.started_at,
|
||||||
|
updated_at: "2026-01-01T00:00:02.000Z",
|
||||||
|
session_count: 1,
|
||||||
|
progress,
|
||||||
|
is_current_mirror: false,
|
||||||
|
}
|
||||||
|
|
||||||
|
// when
|
||||||
|
const combined = { taskSession, work, resumeOption }
|
||||||
|
|
||||||
|
// then
|
||||||
|
expect(combined.resumeOption.progress.total).toBe(2)
|
||||||
|
})
|
||||||
|
})
|
||||||
@@ -6,10 +6,17 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
export interface BoulderState {
|
export interface BoulderState {
|
||||||
|
schema_version?: 2
|
||||||
|
active_work_id?: string
|
||||||
|
works?: Record<string, BoulderWorkState>
|
||||||
/** Absolute path to the active plan file */
|
/** Absolute path to the active plan file */
|
||||||
active_plan: string
|
active_plan: string
|
||||||
/** ISO timestamp when work started */
|
/** ISO timestamp when work started */
|
||||||
started_at: string
|
started_at: string
|
||||||
|
ended_at?: string
|
||||||
|
elapsed_ms?: number
|
||||||
|
status?: BoulderWorkStatus
|
||||||
|
updated_at?: string
|
||||||
/** Session IDs that have worked on this plan */
|
/** Session IDs that have worked on this plan */
|
||||||
session_ids: string[]
|
session_ids: string[]
|
||||||
session_origins?: Record<string, "direct" | "appended">
|
session_origins?: Record<string, "direct" | "appended">
|
||||||
@@ -23,6 +30,26 @@ export interface BoulderState {
|
|||||||
task_sessions?: Record<string, TaskSessionState>
|
task_sessions?: Record<string, TaskSessionState>
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export type BoulderSessionOrigin = "direct" | "appended"
|
||||||
|
export type BoulderWorkStatus = "active" | "completed" | "paused" | "abandoned"
|
||||||
|
export type BoulderTaskStatus = "running" | "completed" | "cancelled"
|
||||||
|
|
||||||
|
export interface BoulderWorkState {
|
||||||
|
work_id: string
|
||||||
|
active_plan: string
|
||||||
|
plan_name: string
|
||||||
|
status?: BoulderWorkStatus
|
||||||
|
started_at: string
|
||||||
|
ended_at?: string
|
||||||
|
elapsed_ms?: number
|
||||||
|
updated_at?: string
|
||||||
|
session_ids: string[]
|
||||||
|
session_origins?: Record<string, BoulderSessionOrigin>
|
||||||
|
agent?: string
|
||||||
|
worktree_path?: string
|
||||||
|
task_sessions?: Record<string, TaskSessionState>
|
||||||
|
}
|
||||||
|
|
||||||
export interface PlanProgress {
|
export interface PlanProgress {
|
||||||
/** Total number of checkboxes */
|
/** Total number of checkboxes */
|
||||||
total: number
|
total: number
|
||||||
@@ -45,10 +72,29 @@ export interface TaskSessionState {
|
|||||||
agent?: string
|
agent?: string
|
||||||
/** Category associated with the task session, when known */
|
/** Category associated with the task session, when known */
|
||||||
category?: string
|
category?: string
|
||||||
|
started_at?: string
|
||||||
|
ended_at?: string
|
||||||
|
elapsed_ms?: number
|
||||||
|
status?: BoulderTaskStatus
|
||||||
/** Last update timestamp */
|
/** Last update timestamp */
|
||||||
updated_at: string
|
updated_at: string
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface BoulderWorkResumeOption {
|
||||||
|
work_id: string
|
||||||
|
plan_name: string
|
||||||
|
active_plan: string
|
||||||
|
worktree_path?: string
|
||||||
|
status: BoulderWorkStatus
|
||||||
|
started_at: string
|
||||||
|
updated_at: string
|
||||||
|
ended_at?: string
|
||||||
|
elapsed_ms?: number
|
||||||
|
session_count: number
|
||||||
|
progress: PlanProgress
|
||||||
|
is_current_mirror: boolean
|
||||||
|
}
|
||||||
|
|
||||||
export interface TopLevelTaskRef {
|
export interface TopLevelTaskRef {
|
||||||
/** Stable identifier for the current top-level plan task */
|
/** Stable identifier for the current top-level plan task */
|
||||||
key: string
|
key: string
|
||||||
|
|||||||
Reference in New Issue
Block a user