test(cli): add JSON escaping tests for step show output #564
Closed
xiaoju
wants to merge 0 commits from
fix/557-step-show-json-escape into main
pull from: fix/557-step-show-json-escape
merge into: uncaged:main
uncaged:main
uncaged:chore/migrate-ocas
uncaged:retrospect/fix-committer-tea
uncaged:retrospect/solve-issue-fixes
uncaged:fix/517-expand-skill
uncaged:fix/574-silent-fail-handling
uncaged:fix/573-unify-cas-store
uncaged:fix/571-current-role
uncaged:fix/567-trim-leading-whitespace
uncaged:fix/566-adapter-json-stdout
uncaged:fix/544-remove-legacy-frontmatter
uncaged:fix/553-edge-prompt-empty
uncaged:fix/559-thread-show-status
uncaged:fix/561-thread-start-cwd-option
uncaged:fix/558-thread-edge-location
uncaged:fix/531-config-mask-apikey
uncaged:fix/532-config-key-validation
uncaged:fix/533-double-prefix
uncaged:fix/551-hermes-bin-engines
uncaged:fix/549-commit-scope
uncaged:feat/541-skill-developer
uncaged:feat/539-skill-author
uncaged:feat/538-skill-user
uncaged:feat/540-skill-actor
uncaged:fix/ci-skip-integration-tests
uncaged:fix/535-sqlite-fallback
uncaged:fix/531-532-533
uncaged:fix/528-refactor-apikey
uncaged:fix/526-config-subcommand
uncaged:fix/522-cancelled-thread-status
uncaged:fix/523-bin-entry-point
uncaged:fix/519-read-session-file
uncaged:fix/enum-multi-exit-validation
uncaged:fix/remove-chinese-cli-output
uncaged:feat/424-setup-agent-discovery
uncaged:fix/hermes-integration-test-import
uncaged:fix/449-reduce-dashboard-complexity
uncaged:refactor/512-rename-packages
uncaged:chore/510-open-source-readiness
uncaged:chore/solve-issue-portable
uncaged:fix/489-step-timing
uncaged:fix/506-semantic-validation
uncaged:feat/502-oneOf-output-instruction
uncaged:feat/499-phase2-discriminated-union
uncaged:feat/499-dollar-status
uncaged:fix/497-update-docs
uncaged:feat/490-phase3-dashboard
uncaged:feat/490-phase2-yaml-migration
uncaged:feat/490-status-routing
uncaged:fix/487-refactor-step-read
uncaged:fix/484-step-read-command
uncaged:fix/480-thread-read-quota
uncaged:fix/481-cas-has-exit-code
uncaged:fix/474-tea-pr-worktree-fix
uncaged:fix/469-step-commands-completed-threads
uncaged:fix/473-first-time-role-context
uncaged:fix/471-thread-list-filters
uncaged:fix/466-continuation-prompt-content
uncaged:chore/cleanup-cli-docs
uncaged:fix/463-http-methods
uncaged:fix/464-worktree-isolation
uncaged:fix/461-per-agent-session-cache
uncaged:fix/459-xml-tag-isolation
uncaged:fix/444-biome-complexity-warnings
uncaged:fix/456-thread-step-background
uncaged:fix/448-reduce-complexity
uncaged:fix/445-reduce-setup-complexity
uncaged:fix/446-reduce-thread-complexity
uncaged:docs/sync-readme
uncaged:fix/447-reduce-loop-complexity
uncaged:fix/439-detail-merge-and-acp
uncaged:fix/440-thread-read-prompt-dedup
uncaged:fix/builtin-session-lifecycle
uncaged:debug/439-raw-ndjson-dump
uncaged:fix/428-multi-strategy-workflow-resolution
uncaged:fix/yaml-no-alias
uncaged:feat/428-workflow-resolution
uncaged:feat/turn-jsonl-session
uncaged:feat/426-builtin-session-resume
uncaged:fix/builtin-agent-system-user-split
uncaged:feat/422-claude-code-detail-enrichment
uncaged:feat/builtin-agent
uncaged:test/418-resume-e2e-repro
uncaged:chore/update-cli-reference
uncaged:fix/413-log-subcommands
uncaged:feat/411-process-logger
uncaged:feat/405-phase2-find-last-role-index
uncaged:feat/405-edge-prompt-required
uncaged:feat/402-edge-prompt-session-resume
uncaged:feat/398-hermes-acp-client
uncaged:fix/395-worktree-hygiene
uncaged:feat/391-workflow-agent-claude-code
uncaged:jshang/workflow-dashboard
uncaged:fix/394-forbid-extra-frontmatter-fields
uncaged:feat/335-setup-validate-model
uncaged:fix/389-dynamic-format-instruction
uncaged:fix/388-frontmatter-dynamic-fields
uncaged:fix/385-revert-output-protocol
uncaged:feat/384-agent-session-protocol
uncaged:feat/remove-llm-extract
uncaged:feat/cas-put-text
uncaged:fix/380-hermes-quiet-flag
uncaged:feat/373-thread-step-count
uncaged:fix/fallback-transition-validation
uncaged:feat/376-first-last-jsonata
uncaged:refactor/374-meta-to-frontmatter
uncaged:feat/370-solve-issue-workflow
uncaged:feat/369-uwf-skill-cli
uncaged:chore/ignore-legacy-biome
uncaged:feat/365-project-local-workflows
uncaged:refactor/364-rename-role-fields
uncaged:feat/359-role-four-phase
uncaged:chore/rename-uwf-to-workflow
uncaged:chore/repo-restructure
uncaged:feat/357-thread-read-content
uncaged:feat/355-uwf-frontmatter
uncaged:feat/351-phase3-prompt-focus
uncaged:feat/351-phase2-adapter-frontmatter
uncaged:feat/351-frontmatter-markdown-phase1
uncaged:feat/349-thread-read
uncaged:fix/348-session-id-stderr
uncaged:fix/342-parse-session-id
uncaged:fix/342-fork-simplify
uncaged:feat/342-thread-steps-fork
uncaged:refactor/simplify-agent-context
uncaged:refactor/pass-store-via-context
uncaged:feat/337-agent-detail-merkle
uncaged:feat/cas-reindex
uncaged:refactor/use-list-by-type
uncaged:refactor/merge-cas-get-cat
uncaged:refactor/remove-table-format
uncaged:fix/328-table-vertical
uncaged:user/jiayiyan/feat_office-agent-document-template-v2
uncaged:feat/328-format-option
uncaged:fix/319-cas-json-output
uncaged:fix/319-validate-schema-only-inline
uncaged:fix/319-schema-titles
uncaged:feat/319-uwf-cas-builtin
uncaged:user/jiayiyan/feat_office-agent-document-template
uncaged:feat/309-uwf-stateless
uncaged:feat/285-phase3-x-cas-ref
uncaged:chore/remove-old-templates
uncaged:feat/294-phase7-cli
uncaged:private/json-cas-refactor
uncaged:feat/294-phase5-react-layer
uncaged:feat/294-phase4-engine-migration
uncaged:feat/294-phase3-workflow-json
uncaged:feat/294-jsonata-moderator
uncaged:docs/architecture-cards
uncaged:feat/285-phase2-remove-extractrefs
uncaged:feat/285-cas-ref-annotation
uncaged:chore/fix-biome-complexity-warnings
uncaged:refactor/agent-fn-required-opt
uncaged:chore/audit-exports-cleanup
uncaged:chore/remove-symlink-dead-code
uncaged:chore/no-external-bundle
uncaged:feat/show-system-prompt
uncaged:chore/205-env-example
uncaged:chore/biome-fix-and-pre-push-hook
uncaged:chore/remove-parentRequired-param
uncaged:fix/265-flaky-thread-rm
uncaged:feat/workflow-detail-layout
uncaged:chore/252-remove-text-adapter
uncaged:feat/261-adapter-migration
uncaged:feat/252-agent-fn
uncaged:feat/graph-interactions
uncaged:fix/dashboard-graph-side-handles
uncaged:fix/dashboard-graph-visual-247
uncaged:fix/cursor-agent-runtime-extract
uncaged:refactor/serve-remove-http-tunnel
uncaged:chore/slim-role-output
uncaged:feat/changesets-version-management
uncaged:chore/bump-0.4.0
uncaged:chore/merge-publish-scripts
uncaged:chore/remove-link-all
uncaged:feat/merge-publish-scripts
uncaged:fix/auto-discover-publish
uncaged:refactor/dashboard-custom-spine-layout
uncaged:fix/cli-bin-path
uncaged:fix/dashboard-elk-review-feedback
uncaged:feat/dashboard-elk-layout
uncaged:fix/skill-author-pitfalls
uncaged:fix/publish-lockfile-regen
uncaged:feat/210-ws-gateway-phase2
uncaged:refactor/thread-detail-side-by-side-layout
uncaged:feat/210-ws-gateway-phase1
uncaged:feat/222-tools-smoke-test-phase3
uncaged:feat/222-react-adapter-phase2
uncaged:feat/222-adapter-fn-phase1
uncaged:fix/219-review-followup
uncaged:feat/216-setup-and-build-scripts
uncaged:fix/206-bundle-build-register
uncaged:feat/197-agent-observability
uncaged:feat/198-dashboard-workflow-graph
uncaged:feat/194-merkle-call-stack-phase2
uncaged:refactor/200-moderator-table
uncaged:feat/194-merkle-call-stack-phase1
uncaged:feat/cursor-agent-workspace-extract
uncaged:fix/191-dashboard-thread-sort
uncaged:feat/187-end-node-llm-summary
uncaged:refactor/185-remove-max-rounds
uncaged:refactor/180-simplify-extract-fn
uncaged:feat/177-gateway-route-reorg
uncaged:feat/172-declarative-moderator-table
uncaged:fix/170-thread-status-detection
uncaged:feat/164-cf-worker-gateway
uncaged:fix/161-162-cas-content-refs
uncaged:feat/155-cas-thread-phase-5
uncaged:feat/155-cas-thread-phase-4
uncaged:feat/155-cas-thread-phase-3
uncaged:feat/155-cas-thread-phase-2
uncaged:feat/155-cas-thread-phase-1
uncaged:chore/rename-dashboard-folder
uncaged:refactor/143-split-packages
uncaged:feat/139-thread-reactor
uncaged:refactor/runtime-descriptor-boundary
uncaged:fix/128-dashboard-enhancements
uncaged:fix/130-sse-incremental
uncaged:fix/120-serve-hardening
uncaged:feat/131-dashboard-sse
uncaged:refactor/thread-context-runtime
uncaged:feat/118-serve-write-sse
uncaged:feat/118-dashboard
uncaged:refactor/121-split-workflow-runtime
uncaged:feat/118-serve-api
uncaged:chore/bump-0.2.0
uncaged:feat/110-phase3-supervisor
uncaged:chore/114-remove-deprecated
uncaged:feat/110-phase2-migrate-extract
uncaged:docs/package-readmes
uncaged:feat/110-phase1-config-layer
uncaged:chore/108-cli-module-discipline
uncaged:chore/106-workflow-module-discipline
uncaged:chore/cleanup-cas-thread-id
uncaged:refactor/102-module-folders
uncaged:refactor/97-phase4-cleanup
uncaged:refactor/96-phase3-split-dispatch
uncaged:refactor/95-phase2-control-merge
uncaged:chore/remove-build-scripts
uncaged:refactor/93-phase1-directory-restructure
uncaged:feat/91-reviewer-prompt
uncaged:docs/88-readme-architecture-cleanup
uncaged:fix/85-usage-format
uncaged:fix/83-cli-ux
uncaged:feat/81-skill-topics
uncaged:fix/75-nits
uncaged:refactor/75-merge-roles-phase1
uncaged:refactor/71-auto-gen-skill-doc
uncaged:feat/63-workflow-storage-root
uncaged:feat/69-help-skill
uncaged:refactor/cli-noun-verb-grouping
uncaged:feat/59-solve-issue-refactor
uncaged:feat/37-live-command
uncaged:feat/58-develop-workflow
uncaged:feat/36-init-command
uncaged:feat/44-react-extract
uncaged:feat/43-extract-provider-config
uncaged:feat/42-thread-root-node
uncaged:feat/41-merkle-content-cas
uncaged:feat/33-workflow-as-agent
uncaged:feat/32-cas-gc
uncaged:feat/31-refs-tracking
uncaged:feat/30-global-cas
uncaged:feat/28-preparer-role
uncaged:fix/26-planner-cas-cli-prompt
uncaged:test/19-validate-workflow-descriptor
uncaged:feat/23-phase-title-in-planner-meta
uncaged:fix/21-moderator-coder-transition
uncaged:fix/review-feedback-and-typecheck
uncaged:fix/type-errors-and-tsbuildinfo
No Reviewers
Labels
No items
No Label
Milestone
No items
No Milestone
Projects
Clear projects
No project
Assignees
aobing
jiashuang (Jia Shuang)
jiayi (Jiayi)
luming
scottwei
tuanzi
xiaoju
xiaomo
xiaonuo
xingyue
Clear assignees
No Assignees
Notifications
Due Date
No due date set.
Dependencies
No dependencies set.
Reference: uncaged/workflow#564
Reference in New Issue
Block a user
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
Delete Branch "fix/557-step-show-json-escape"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
What
Add comprehensive test coverage for JSON serialization in
uwf step showoutput to verify control character escaping behavior.Why
Issue #557 reported that
uwf step showoutput contains unescaped control characters (raw newlines, tabs) in JSON output, particularly in tool call arguments from hermes/claude-code sessions. This causesJSON.parse()to fail.Changes
packages/cli-workflow/src/__tests__/step-show-json.test.ts(363 lines)\n) in bash commands\t) in heredocs\r\n) for Windows line endingsKey Finding
Investigation revealed that
JSON.stringify()already correctly escapes all control characters per RFC 8259. No production code changes were needed. The test suite serves as regression protection to ensure this behavior is maintained.Test Architecture
setupTest,createTestStep) reduce boilerplateexpandDeep()→formatOutput()→JSON.stringify()Verification
✅ All 333 existing tests pass
✅ All 9 new tests pass (189ms)
✅
bun run build- TypeScript compilation successful✅
bun run check- Biome lint + typecheck passed✅ No production code changes required
Ref
Fixes #557
Pull request closed