- @ocas/core and @ocas/fs upgraded from ^0.2.2 to ^0.3.0
- agent-hermes: replace better-sqlite3 with node:sqlite (DatabaseSync)
- Remove better-sqlite3 and @types/better-sqlite3 dependencies
- Fix remaining bun references in cli test helpers (execFileSync)
Refs #28
- Add missing await on store.cas.put() in run.ts:192
- Replace #!/usr/bin/env bun → #!/usr/bin/env node in all CLI bins
- Update issue-551 test to assert node shebang
- Update issue-551 test: assert bun engines removed (not present)
- Migrate session-detail tests from bun:sqlite to better-sqlite3 API
(db.exec for DDL, db.prepare().run() for inserts)
Refs #26
Remove migrateStorageIfNeeded() which created symlinks from
~/.uncaged/workflow → ~/.uwf and ~/.uncaged/json-cas → ~/.ocas.
This was temporary migration support. Users who still have old paths
can run a one-time copy manually.
Zero 'uncaged' references remain in active codebase.
createAgentStore was calling getCasDir(storageRoot) which resolves to
~/.uwf/cas/, but since Phase 3 all CAS data lives in ~/.ocas/.
getActiveThreadEntry already used getGlobalCasDir() correctly, causing
a split where thread lookup succeeded but CAS node reads failed.
Found during e2e walkthrough after Phase 0-5 migration.
- Remove entire 'uwf cas' command group from CLI
- Delete commands/cas.ts (only used by CLI + tests)
- Delete cas.test.ts and cas-exit-code.test.ts
- Update workflow YAMLs: uwf cas get/has/refs/walk → ocas
- Update e2e-walkthrough script to use ocas
- Update docs and reference files
- Keep store-global-cas.test.ts (internal CAS store tests)
CAS operations now go through 'ocas' CLI exclusively.
Agent text storage handled internally by uwf pipeline.
Closes#10
- thread list: suspended threads show [suspended] marker via statusDisplay
- thread show: displays suspendedRole, suspendMessage, and resume hint
- New ThreadShowOutput type with hint field
- Tests: 3 cases for display formatting
Closes#591
- Add GraphPseudoRole type ($END | $SUSPEND) to workflow-protocol
- Add 'suspended' to ThreadStatus
- evaluate() returns EvaluateSuspendResult for $SUSPEND targets
- Thread show/list derive suspended status from moderator evaluation
- validate-semantic treats $SUSPEND like $END (valid target, no outgoing edges)
- Tests: routing to $SUSPEND, mustache rendering, thread status display
Closes#588
- Add !include custom YAML tag for referencing external files (Fixes#582)
- .md/.txt files included as strings
- .json files parsed as JSON objects
- .yaml/.yml files parsed as YAML objects
- Paths resolved relative to the workflow YAML file
- Support foo/index.yaml as alternative to foo.yaml (Fixes#583)
- Updated discoverProjectWorkflows(), findWorkflowInDir()
- Updated workflowNameFromPath() for index.yaml detection
- Flat files take priority over folder layout
- Added tests for both features
Fixes hallucination issues observed in thread 06F7FSTXQGY3D5CY5YPQFK2Y3W:
1. Developer self-verification (critical): Added step 12 requiring
mandatory verification of branch, file existence, and git status
before reporting done status. Prevents hallucinated completions
without actual tool execution.
2. Reviewer hard-check enforcement (critical): Added critical warning
and step 0 requiring cd/pwd verification before review. Prevents
false rejections based on assumptions without actual path checks.
3. Test debugging escalation (medium): Added structured debugging
guidance with escalation path after 3 test cycles. Prevents
infinite retry loops by providing strategy and fail-fast guidance.
Also added 3 test cases to verify the new procedure steps exist.
Based on change plan 9EVZPDTS16PMG analyzing execution anomalies
that resulted in 58% waste (13 of 23 minutes).
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Handle the case where Claude Code exits without producing a result line
(timeout, OOM, signal kill). Previously returned null and threw an error;
now returns incomplete result with best-effort output extraction.
Changes:
- Add "incomplete" as new ClaudeCodeResultSubtype value
- Extract output from last assistant turn when no result line exists
- Enhanced error messages distinguish incomplete vs unparseable output
- Store incomplete results in CAS with appropriate metadata
- Add 10 comprehensive test cases for incomplete result handling
Fixes#574
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This resolves issue #573 by moving uwf's CAS directory from
~/.uncaged/workflow/cas/ to the shared ~/.uncaged/json-cas/ location.
Changes:
- Added getGlobalCasDir() function with UNCAGED_CAS_DIR support
- Updated createUwfStore() to use global CAS directory
- Added comprehensive test coverage (11 new tests)
- Updated all existing tests for environment isolation
- Updated documentation (CLAUDE.md, README.md)
Benefits:
- Cross-tool visibility: json-cas CLI can read uwf-created nodes
- Schema sharing: both tools access same schema registry
- Future-proofing: enables json-cas render/verbose for uwf data
Fixes#573
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This resolves issue #573 by moving uwf's CAS directory from
~/.uncaged/workflow/cas/ to the shared ~/.uncaged/json-cas/ location.
Changes:
- Added getGlobalCasDir() function that respects UNCAGED_CAS_DIR env var
- Updated createUwfStore() to use the global CAS directory
- Updated all tests to set UNCAGED_CAS_DIR for test isolation
- Added comprehensive test suite for global CAS functionality
- Updated documentation (CLAUDE.md, README.md) to reflect new architecture
Benefits:
- Cross-tool visibility: json-cas CLI can now read uwf-created nodes
- Schema sharing: both tools access the same schema registry
- Future-proofing: enables json-cas render/verbose features for uwf data
Workflow metadata (threads.yaml, registry.yaml, history.jsonl) remains in
~/.uncaged/workflow/ as intended.
All tests pass. No breaking changes to existing functionality.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Store the fully assembled prompt sent to each agent in CAS as a text
node, referenced from StepNodePayload.assembledPrompt. This enables
exact reproduction of what the agent received for debugging hallucinations.
Changes:
- workflow-protocol: StepRecord + STEP_NODE_SCHEMA add assembledPrompt field
- workflow-util-agent: AgentRunResult includes assembledPrompt, run.ts stores it
- workflow-util-agent: schemas register TEXT_SCHEMA for prompt storage
- workflow-agent-claude-code: return assembled prompt from buildClaudeCodePrompt
- workflow-agent-hermes: return assembled prompt from buildHermesPrompt
- workflow-agent-builtin: return empty prompt (no prompt assembly)
- cli-workflow: step read --prompt renders the stored prompt
- All test fixtures updated for new field
Legacy steps without assembledPrompt show 'Prompt not recorded' message.
小橘 🍊
- Enhanced Biome config with test file override for noConsole
- Applied Biome auto-fixes (8 files: formatting, template literals, optional chains)
- Updated all package repository URLs to git.shazhou.work/uncaged/workflow.git
- Added workflow-agent-claude-code to publish order in scripts/publish-all.mjs
- Added --ignore-scripts flag to publish command to bypass prepublishOnly guard
- Installed vitest in root devDependencies for test infrastructure
- Created vitest.config.ts for all 8 packages with passWithNoTests: true
- Fixed 3 test files to use vitest imports instead of bun:test
- Added test and test:ci scripts to packages missing them
- Added missing build step to .gitea/workflows/ci.yml
- Renamed CI job from 'test' to 'check' for clarity
- Created workflows/solve-issue.yaml with TDD-driven issue resolution workflow
- Registered solve-issue workflow with uwf (hash: 084YVM60BR8G6)
- Added packageManager: bun@1.3.14 to root package.json
- Added preinstall guard to block npm/pnpm/yarn
- Added prepublishOnly guard to root and all 7 public packages
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
When mustache variables in edge prompts resolve to empty strings (because
upstream output lacks the fields), the engine now returns a Result.error
instead of passing an empty --prompt to the agent.
- evaluate.ts: check rendered prompt is non-empty after mustache.render()
- run.ts: improve parseArgv error message for empty --prompt
- Export parseArgv for testability
- Add 7 tests covering all cases from the spec
Add comprehensive tests verifying that `uwf step show` produces valid
JSON output even when step detail nodes contain control characters
(newlines, tabs, carriage returns, etc.) in tool call args and content
fields.
Tests cover:
- Basic control characters (newlines, tabs, CR+LF)
- Backslashes and quotes
- Unicode control characters (U+0001-U+001F)
- Nested CAS refs with control characters
- Large steps with multiple tool calls
- Empty/null values
- YAML output format (unaffected by escaping)
The tests confirm that JSON.stringify() already handles control
character escaping correctly when serializing JavaScript objects
to JSON. No code changes needed - these tests serve as regression
guards to ensure the behavior remains correct.
Fixes#557
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>