Multi-agent coordination CLI with SQLite message bus: - State machine: ASSIGNED -> WORKING -> IN_REVIEW -> APPROVED -> COMPLETED - Commands: spawn, start, done, approve, merge, cancel, fail, heartbeat - SQLite WAL mode, dedicated heartbeat thread, channel-based IPC - cligen for CLI, tiny_sqlite for DB, ORC memory management Design docs for branch-per-worker, state machine, message passing, and human observability patterns. Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
60 lines
1.7 KiB
Nim
60 lines
1.7 KiB
Nim
## Worker context handling
|
|
##
|
|
## Reads/writes .worker-ctx.json in worktrees for agent discovery.
|
|
|
|
import std/[os, json, times, strformat]
|
|
import ./types
|
|
|
|
proc writeContext*(worktree: string, ctx: WorkerContext) =
|
|
## Write context file to worktree
|
|
let path = worktree / ContextFileName
|
|
writeFile(path, $ctx.toJson())
|
|
|
|
proc readContext*(worktree: string = ""): WorkerContext =
|
|
## Read context from worktree. If empty, uses current directory.
|
|
let dir = if worktree != "": worktree else: getCurrentDir()
|
|
let path = dir / ContextFileName
|
|
|
|
if not fileExists(path):
|
|
raise newException(IOError, &"Context file not found: {path}")
|
|
|
|
let content = readFile(path)
|
|
let j = parseJson(content)
|
|
return WorkerContext.fromJson(j)
|
|
|
|
proc findContext*(): WorkerContext =
|
|
## Find context by walking up directory tree
|
|
var dir = getCurrentDir()
|
|
while dir != "" and dir != "/":
|
|
let path = dir / ContextFileName
|
|
if fileExists(path):
|
|
let content = readFile(path)
|
|
let j = parseJson(content)
|
|
return WorkerContext.fromJson(j)
|
|
dir = parentDir(dir)
|
|
|
|
raise newException(IOError, "No .worker-ctx.json found in directory tree")
|
|
|
|
proc isInWorktree*(): bool =
|
|
## Check if current directory is inside a worker worktree
|
|
try:
|
|
discard findContext()
|
|
return true
|
|
except IOError:
|
|
return false
|
|
|
|
proc getTaskId*(): string =
|
|
## Get task ID from context
|
|
return findContext().taskId
|
|
|
|
proc createWorkerContext*(taskId, branch, worktree, description: string): WorkerContext =
|
|
## Create a new context and write to worktree
|
|
result = WorkerContext(
|
|
taskId: taskId,
|
|
branch: branch,
|
|
worktree: worktree,
|
|
createdAt: getTime(),
|
|
description: description
|
|
)
|
|
writeContext(worktree, result)
|