Breaking change: Store API keys directly in config.yaml instead of
environment variable names.
## Changes
### @uncaged/workflow-protocol
- Change ProviderConfig.apiKeyEnv: string → apiKey: string
- Update README to reflect new type
### @uncaged/workflow-util-agent
- extract.ts: Remove dotenv loading, use providerEntry.apiKey directly
- storage.ts: Update normalizeProviders to validate apiKey field
- Update error messages to reference apiKey instead of apiKeyEnv
### @uncaged/cli-workflow
- setup.ts: Write actual API key to config.yaml, not .env
- Remove apiKeyEnvName(), loadEnvFile(), saveEnvFile() functions
- Remove getEnvPath() function
- Update cmdSetup to not return envPath in result
- Update README to reflect config.yaml stores API keys
- Fix setup-validate.test.ts to not expect envPath in result
## Verification
- ✅ bun run build passes
- ✅ All tests pass (260/260 in cli-workflow, 55/55 in util-agent)
- ✅ bun run check passes (only pre-existing warnings)
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
BREAKING CHANGE: StepRecord now requires startedAtMs and completedAtMs fields.
StepEntry now requires durationMs field. Old CAS data without these fields is invalid.
- Add startedAtMs/completedAtMs to StepRecord and StepNodePayload
- Add durationMs to StepEntry (computed: completedAtMs - startedAtMs)
- Update STEP_NODE_SCHEMA to require timing fields as integers
- Record Date.now() before/after agent execution in createAgent
- Show duration in thread read headers (formatStepHeader)
- Update existing test fixtures with timing fields
When a role participates for the first time (e.g. committer), it previously
only received the system prompt + last step output, missing the full thread
history. This caused hallucination as the role had to guess what happened.
Changes:
- build-continuation-prompt.ts: detect first-time roles and include all
steps' meta + content for last 2-3 steps (within quota)
- context.ts: add isFirstVisit detection helper
- types.ts: add isFirstVisit field to AgentContext
- hermes.ts: pass isFirstVisit through to prompt builder
Fixes#473
This commit implements issue #456, adding two related capabilities to the uwf CLI:
1. **Background execution mode** for `uwf thread step` (via `--background` flag)
- Spawns agent execution in a detached background process
- Returns immediately with thread ID and background status
- Maintains marker files to track running processes
- Supports `--count` option to run multiple steps in background
- Prevents concurrent execution of the same thread
2. **Running threads query** command (`uwf thread running`)
- Lists all threads currently executing in background
- Returns thread ID, workflow, current role, PID, and start time
- Automatically filters out stale markers (dead processes)
- Empty list when no threads are running
**Key changes:**
- **workflow-protocol**: Added `RunningThreadItem`, `RunningThreadsOutput` types
Updated `StepOutput` to include `background: boolean | null` field
- **cli-workflow/background**: New module for process management
- Marker file creation/deletion (atomic operations)
- PID liveness checking
- Stale marker cleanup
- Running threads query
- **cli-workflow/commands/thread**:
- Updated `cmdThreadStep` to support `--background` and `--_background-worker` flags
- Added `cmdThreadStepBackground` for spawning detached processes
- Added `cmdThreadRunning` to list running threads
- Updated `cmdThreadKill` to terminate background processes
- **cli-workflow/cli**: Added CLI routing for new commands and flags
**Integration:**
- `uwf thread kill` now terminates background processes before archiving
- Foreground execution checks for existing background process and fails if found
- Background worker creates/cleans up marker files automatically
- Marker files stored in `~/.uncaged/workflow/running/*.json`
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- StepRecord adds edgePrompt field (backward compat: defaults to "")
- StepNode CAS schema includes edgePrompt
- writeStepNode persists ctx.edgePrompt
- buildHistory exposes edgePrompt in StepContext
- buildBuiltinMessages reconstructs multi-turn moderator↔agent conversation:
system = role prompt + output format (stable prefix)
per prior visit: user (edgePrompt + inter-step summary) + assistant (output)
current: user (edgePrompt + recent summary)
- Zero extra persistence — pure function of CAS chain
- Stable prefix for LLM prompt cache hits
- 10 builtin tests pass, all other package tests pass
Agent CLI outputs plain CAS hash (not JSON), engine parses plain hash.
StepOutput no longer carries sessionId — session info is already in CAS detail.
Keeps the valuable parts of #385: sessionId in AgentRunResult (process-internal),
continue support, and frontmatter retry loop.
Breaking changes:
- AgentRunResult now requires sessionId field
- AgentOptions now requires continue function
- Agent CLI outputs JSON {stepHash, sessionId} instead of plain CAS hash
- Engine parses JSON output (with legacy CAS hash fallback)
New features:
- Frontmatter validation retry: if agent output lacks valid frontmatter,
engine calls agent.continue() up to 2 times with correction message
- Session tracking: sessionId flows from agent → engine → StepOutput
- Hermes agent: session parse failure is now a hard error (no raw text fallback)
- Hermes agent: supports --resume for continue sessions
Closes#384
Breaking change per review:
- Remove systemPrompt from RoleDefinition entirely
- identity/prepare/execute/report are now required (string, not nullable)
- Remove all legacy fallback logic in buildRolePrompt
- Simplify validate.ts, workflow.ts materialize
- Migrate all test fixtures and example workflows
Refs #359
- Extend RoleDefinition with identity, prepare, execute, report fields
- Make systemPrompt optional (nullable) for four-phase workflows
- Update ROLE_DEFINITION JSON Schema (all new fields optional)
- Update validate.ts to accept new fields
- Update workflow.ts to strip null fields before CAS storage
- Update thread read to prefer identity over systemPrompt
- Add --version flag to uwf CLI
- Bump all packages to 0.5.0
Refs #359
Make AgentFn<Opt> always take a mandatory options argument, removing
the void conditional overload. Simplify createAgentAdapter, restore
exports needed by tests, and fix CLI test bundles to use cas.put
instead of disallowed @uncaged/* imports.
Co-authored-by: Cursor <cursoragent@cursor.com>
- Add systemPrompt to WorkflowRoleDescriptor (protocol)
- Propagate systemPrompt through buildDescriptor and validateWorkflowDescriptor
- Display system prompt as collapsible <details> in RoleCard
- Add RoleFn<T>, AdapterFn, AdapterBinding types to workflow-protocol
- Mark AgentFn, AgentFnResult, AgentBinding as @deprecated
- Refactor createWorkflow to accept AdapterBinding instead of AgentBinding
- Adapter returns typed meta directly — no more extract call in workflow loop
- Add buildThreadInput (ThreadContext-based), keep buildAgentPrompt as deprecated wrapper
- Update template bundle-entries to wrap AgentFn as AdapterFn
- Update solve-issue tests to use AdapterFn directly
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
- 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
Extract all cross-package type definitions and constructor functions
into a dedicated protocol layer. This is the foundation for the
seven-package split (RFC #143).
Contains:
- Result<T,E>, ok(), err()
- START, END constants
- CasStore, WorkflowFn, RoleOutput, WorkflowCompletion
- WorkflowDescriptor, WorkflowRoleDescriptor
- ProviderConfig, WorkflowConfig, ResolvedModel (fixes config↔registry cycle)
- RoleDefinition, Moderator, WorkflowDefinition
- AgentFn, ExtractFn, and all thread context types
Ref: #143, closes#144