1. Replace manual OpenAI response parsing with createThreadReactor —
workspace extraction now uses the same ReAct loop as extract/summarizer,
with a zod schema and structured tool call
2. Remove non-null assertion on llmProvider, replaced with explicit guard
3. Add structured logging (LogFn) to extraction — failures, non-absolute
paths, and successful extractions all logged with tag V3KM8QWP
4. export const run = wf is correct: createWorkflow returns WorkflowFn
directly, old bundle-entry had stale .run access + unused 3rd arg
小橘 <xiaoju@shazhou.work>
Replace 50ms setTimeout with waitUntilPredicate polling for first role
completion before issuing kill. Same pattern used by pause/resume test.
小橘 <xiaoju@shazhou.work>
- Sort threads by startedAt descending (newest first)
- completed: green (dimmed) — distinct from running (green, full opacity)
- active: accent color (blue) — was same muted gray as completed
- failed: red — unchanged
- running: green — unchanged
Fixes#191
v0.3.0 was published with workspace:* deps (npm doesn't resolve them).
Re-published as v0.3.1 with concrete version refs.
Local monorepo deps restored to workspace:*.
小橘 <xiaoju@shazhou.work>
Deduplicate CAS_GET_TOOL_DEFINITION, isRecord, toolHandler, and
structuredToolFromSchema between summarizer.ts and extract-fn.ts.
Both now use createCasReactor(provider, cas, opts) and only provide
their own systemPrompt.
小橘 <xiaoju@shazhou.work>
Instead of hardcoding 'completed: moderator returned END', the engine now
calls a summarizer (ReAct loop with cas_get tool) to produce a meaningful
summary of the workflow outcome before writing the __end__ node.
- New summarizer.ts following supervisor.ts pattern
- Uses extract scene LLM provider (falls back to raw completion.summary on failure)
- Tracks step contentHashes for summarizer context
- Schema: z.object({ summary: z.string() })
Refs #187, #188
小橘 <xiaoju@shazhou.work>
hasRoundsRemaining is now always true — supervisor controls when to
stop, not a round counter. Tests updated to expect coder retry
instead of END on exhaustion.
Refs #185
Removes maxRounds as a hard stop limit from the entire stack. The supervisor
(already configured via workflow.yaml supervisorInterval) is now the sole
termination authority.
Changes across 27 files in 11 packages:
- workflow-protocol: StartStep.meta is now empty, StartNodePayload drops maxRounds
- workflow-cas: isStartPayload no longer checks maxRounds
- workflow-execute: engine, worker, fork-thread all stripped of maxRounds plumbing
- cli-workflow: --max-rounds flag removed from CLI and HTTP API
- workflow-runtime: build-context and create-workflow no longer reference maxRounds
- workflow-dashboard: UI no longer sends maxRounds
- workflow-template-develop/solve-issue: moderator no longer checks rounds remaining
- All tests updated
Fixes#185
Address review feedback: remove unsafe `as unknown as` cast on
currentRole. CursorAgentConfig now takes workspace directly instead
of using ExtractFn to infer it from thread context.
Refs #180
- Remove root and workflow-gateway pnpm-lock.yaml (workspace mode)
- Replace startsWith auth skip with Hono route group
- Gateway management routes use GATEWAY_SECRET (per-route)
- /api/gateway/endpoints + /api/agents/* use dashboard auth
- No more global /api/* middleware with path-based exceptions
- Remove extractPrompt from RoleDefinition
- Remove ExtractContext type
- ExtractFn now takes (schema, contentHash) instead of (schema, prompt, ExtractContext)
- createExtract reads CAS content by hash, keeps ReAct loop with cas_get
- Coder schema uses .describe() for phase hash hint
- All role definitions, CLI templates, and skill output updated
Refs #180, closes#174, closes#181
Migrate workflow-template-develop and workflow-template-solve-issue
moderators to use the declarative ModeratorTable/tableToModerator
pattern. Update workflow-runtime re-exports and workflow-execute
engine to use renamed types.
Fixes#172
Add ModeratorCondition, FALLBACK, ModeratorTransition, ModeratorTable types
and tableToModerator converter function. Export from workflow-protocol and
re-export from workflow-runtime for backward compat.
Refs #172
- routes-live: check .running marker before keeping SSE open;
if thread is not running, emit existing records and close
- thread-detail: only show Live badge when connected AND not completed
小橘 <xiaoju@shazhou.work>
When .running marker exists but no __end__ in CAS chain,
check if the worker process is actually alive. Dead PID
means the worker crashed without cleanup → status 'failed'.
Fixes#170
小橘 <xiaoju@shazhou.work>
- resolveThreadListStatus() checks CAS chain for __end__ node
- Stale .running markers no longer cause false 'running' status
- Distinguish 'failed' (returnCode != 0) from 'completed'
- Worker signal handlers (SIGINT/SIGTERM) clean up .running files
- listRunningThreads filters out terminated threads with stale markers
Fixes#170
小橘 <xiaoju@shazhou.work>
- serve generates random UUID on startup
- registration sends agentToken to gateway, stored in KV
- gateway injects X-Agent-Token header when proxying to agent
- serve rejects /api/* requests without valid token
- healthz remains unauthenticated
- tunnel URL is now protected — direct access returns 401
小橘 <xiaoju@shazhou.work>
Both REST and SSE endpoints now return workflow-result with standard
fields (role, content, timestamp) instead of non-standard (summary).
Fixes 'Invalid Date' and empty content in dashboard.
小橘 <xiaoju@shazhou.work>