feat(config)!: migrate to .atomic/settings.json with global sync - #234
Conversation
Reset ralph session state (session dir, session id, task ids, todo items) on /clear and non-ralph slash commands for Copilot agent only. Guard existing ralph panel dismissal on regular messages with agentType check to prevent unintended resets for other agent types. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Tasks #6 and #7: - Remove clearContext() call before review iteration (line 684) - Remove clearContext() call before fix-spec decomposition (line 734) - Update test to remove assertion on clearContext() being called - Maintains context continuity throughout Ralph workflow - All workflow-commands tests passing (14 tests, 32 assertions)
- Add test for workflow completion returning stateUpdate with workflowActive: false - Add test for waitForUserInput presence in CommandContext interface - Add test for mock waitForUserInput resolving with a string - Add test verifying clearContext is not called during workflow execution - Add test for interrupted step1 returning stateUpdate to deactivate workflow All tests pass and typecheck succeeds.
- Test #16: Ralph end-to-end without clearContext calls - Verifies clearContext is never called during full workflow - Tests complete workflow with review and fix cycles - Confirms stateUpdate.workflowActive is false on completion - Test #17: User prompt passthrough after Ctrl+C in workflow - Simulates Ctrl+C interruption during implementation - Verifies waitForUserInput is called to get user's follow-up prompt - Confirms user's prompt is passed to the next streamAndWait call - Test #18: Task list persists after Ctrl+C, hides on completion - Verifies setRalphSessionDir is called with non-null path at start - Confirms session dir is NOT cleared (null) during workflow - Validates stateUpdate.workflowActive is false to signal UI to hide task list
Add comprehensive E2E tests validating the complete lifecycle of the /ralph workflow in inline mode: - Test #19: Teal border lifecycle during /ralph workflow - Verifies workflowActive state drives teal border - Tracks updateWorkflowState calls throughout lifecycle - Validates border returns to normal after completion - Test #20: Ctrl+C + user prompt + workflow continuation E2E - Full lifecycle: decomposition → Ctrl+C → user input → continuation - Verifies waitForUserInput() mechanism - Validates workflow continues with user's prompt - Confirms clean completion after interruption - Test #21: Task list persistence and tasks.json maintenance - Verifies session dir creation and persistence - Validates tasks.json is written and updated correctly - Confirms task tracking through interruption - Ensures final state reflects all completed tasks All tests follow the existing E2E test pattern from background-agent-e2e.test.ts and use the same createMockContext pattern from workflow-commands.test.ts. Tests validate multiple concerns across the workflow lifecycle: - State management (workflowActive, workflowType) - User intervention handling (Ctrl+C, waitForUserInput) - Task persistence (tasks.json, session directory) - Review integration (clean review with no findings) - Cleanup behavior (stateUpdate signals UI reset) All 1426 tests pass including 3 new E2E tests. No type errors.
Fixes stale closure issue in useEffect hook that auto-hides task list panel when workflow ends. The effect references ralphSessionDir in its body but was missing it from the dependency array, causing React to use stale values. Changed line 2685 to include ralphSessionDir in dependencies: [workflowState.workflowActive, ralphSessionDir] Testing: - TypeScript compilation: ✅ Passed - All tests: ✅ Passed (1426 tests, 9410 assertions)
- Display workflow type (e.g., 'plan') instead of generic 'workflow' - Add 'shift+tab switch mode' hint for user guidance - Style label in teal accent color to match workflow theme - Show label when workflow is active and not streaming
Remove separator and 'shift+tab switch mode' hint from the workflow mode label, keeping only the workflow type indicator. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Assistant-model: GitHub Copilot
Rework Ctrl+C behavior during workflows: single Ctrl+C interrupts the current stream while keeping the workflow alive (waits for user input), double Ctrl+C cancels the workflow entirely. - Change waitForUserInputResolverRef to support reject for cancellation - Add wasCancelled flag to StreamResult interface - ESC during workflow only interrupts the stream, no longer cancels - Show streaming hints (esc/ctrl+q) in workflow mode bar when idle - Handle "Workflow cancelled" error silently in workflow catch block Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Handle interruptions consistently across planning, execution, and review loops by waiting for user input and resuming the stream. Update workflow status hints and tests to reflect cancel-versus-interrupt behavior. Assistant-model: openai/gpt-5.3-codex
Store project selections in .atomic/settings.json with local-over-global resolution, and sync bundled agent configs into ~/.atomic during install and update. Keep SCM-managed skills project-scoped via atomic init, add chat auto-init checks, and clean managed global directories on uninstall. Assistant-model: gpt-5.3-codex
Use normalizeMarkdownNewlines as a trim-only pass so markdown lists and paragraph line breaks render correctly in text and reasoning parts. Add tests to lock in newline preservation and outer-whitespace trimming behavior. Assistant-model: gpt-5.3-codex
Run global config sync from postinstall and treat partial ~/.atomic setups as missing so editable and package installs always hydrate required agent files. Assistant-model: openai/gpt-5.3-codex
Thread an optional `agent` field through Session.stream() and the UI layer so the OpenCode client can build AgentPartInput prompt parts for native sub-agent dispatch. Claude and Copilot clients ignore the option and continue using Task-tool dispatch. Assistant-model: Claude Code
7d97327 to
2911c3d
Compare
PR Review: Lavaman131/hotfix/initSummaryThis PR introduces a significant architectural change to how Atomic manages configuration files. It moves from a flat ✅ Strengths
🔍 Code Quality & Best PracticesIssue 1: Unused
|
Ensure OpenCode resolves project-scoped agents from the active working directory and handles subtask payload variants so parallel agent rows show stable, meaningful labels. Assistant-model: openai/gpt-5.3-codex
Code Review: PR #234 - feat(config)!: migrate to .atomic/settings.json with global syncSummaryThis is a well-structured PR introducing significant changes to Atomic's configuration system. The migration from ✅ Strengths1. Configuration System Architecture
2. OpenCode Native Sub-Agent Dispatch
3. Workflow Interrupt Handling
4. Test Coverage
|
Package and sync .mcp.json plus Copilot mcp-config.json into ~/.atomic so postinstall validation reflects complete global config state. Also add .vscode/mcp.json discovery and regression tests for MCP config parsing and sync coverage. Assistant-model: openai/gpt-5.3-codex
PR Review: feat(config)!: migrate to .atomic/settings.json with global syncThis is a well-structured PR that introduces significant changes to Atomic's configuration system. Here's my detailed review: ✅ Strengths
|
* fix(chat): scope ralph state reset to copilot agent type Reset ralph session state (session dir, session id, task ids, todo items) on /clear and non-ralph slash commands for Copilot agent only. Guard existing ralph panel dismissal on regular messages with agentType check to prevent unintended resets for other agent types. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * refactor(ralph): remove clearContext() calls from workflow Tasks #6 and #7: - Remove clearContext() call before review iteration (line 684) - Remove clearContext() call before fix-spec decomposition (line 734) - Update test to remove assertion on clearContext() being called - Maintains context continuity throughout Ralph workflow - All workflow-commands tests passing (14 tests, 32 assertions) * test(workflow): add unit tests for workflow inline mode changes - Add test for workflow completion returning stateUpdate with workflowActive: false - Add test for waitForUserInput presence in CommandContext interface - Add test for mock waitForUserInput resolving with a string - Add test verifying clearContext is not called during workflow execution - Add test for interrupted step1 returning stateUpdate to deactivate workflow All tests pass and typecheck succeeds. * test(workflow): add 3 integration tests for workflow inline mode - Test #16: Ralph end-to-end without clearContext calls - Verifies clearContext is never called during full workflow - Tests complete workflow with review and fix cycles - Confirms stateUpdate.workflowActive is false on completion - Test #17: User prompt passthrough after Ctrl+C in workflow - Simulates Ctrl+C interruption during implementation - Verifies waitForUserInput is called to get user's follow-up prompt - Confirms user's prompt is passed to the next streamAndWait call - Test #18: Task list persists after Ctrl+C, hides on completion - Verifies setRalphSessionDir is called with non-null path at start - Confirms session dir is NOT cleared (null) during workflow - Validates stateUpdate.workflowActive is false to signal UI to hide task list * test(workflow): add 3 E2E tests for workflow inline mode Add comprehensive E2E tests validating the complete lifecycle of the /ralph workflow in inline mode: - Test #19: Teal border lifecycle during /ralph workflow - Verifies workflowActive state drives teal border - Tracks updateWorkflowState calls throughout lifecycle - Validates border returns to normal after completion - Test #20: Ctrl+C + user prompt + workflow continuation E2E - Full lifecycle: decomposition → Ctrl+C → user input → continuation - Verifies waitForUserInput() mechanism - Validates workflow continues with user's prompt - Confirms clean completion after interruption - Test #21: Task list persistence and tasks.json maintenance - Verifies session dir creation and persistence - Validates tasks.json is written and updated correctly - Confirms task tracking through interruption - Ensures final state reflects all completed tasks All tests follow the existing E2E test pattern from background-agent-e2e.test.ts and use the same createMockContext pattern from workflow-commands.test.ts. Tests validate multiple concerns across the workflow lifecycle: - State management (workflowActive, workflowType) - User intervention handling (Ctrl+C, waitForUserInput) - Task persistence (tasks.json, session directory) - Review integration (clean review with no findings) - Cleanup behavior (stateUpdate signals UI reset) All 1426 tests pass including 3 new E2E tests. No type errors. * fix(workflow): wrap execute body in try-catch to reset workflowActive on error * fix(chat): add ralphSessionDir to useEffect dependency array Fixes stale closure issue in useEffect hook that auto-hides task list panel when workflow ends. The effect references ralphSessionDir in its body but was missing it from the dependency array, causing React to use stale values. Changed line 2685 to include ralphSessionDir in dependencies: [workflowState.workflowActive, ralphSessionDir] Testing: - TypeScript compilation: ✅ Passed - All tests: ✅ Passed (1426 tests, 9410 assertions) * feat(ui): add workflow mode label with type and keyboard hint - Display workflow type (e.g., 'plan') instead of generic 'workflow' - Add 'shift+tab switch mode' hint for user guidance - Style label in teal accent color to match workflow theme - Show label when workflow is active and not streaming * fix(ui): simplify workflow mode label Remove separator and 'shift+tab switch mode' hint from the workflow mode label, keeping only the workflow type indicator. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Assistant-model: GitHub Copilot * refactor(workflow): improve interrupt and cancellation handling Rework Ctrl+C behavior during workflows: single Ctrl+C interrupts the current stream while keeping the workflow alive (waits for user input), double Ctrl+C cancels the workflow entirely. - Change waitForUserInputResolverRef to support reject for cancellation - Add wasCancelled flag to StreamResult interface - ESC during workflow only interrupts the stream, no longer cancels - Show streaming hints (esc/ctrl+q) in workflow mode bar when idle - Handle "Workflow cancelled" error silently in workflow catch block Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * fix(workflow): recover /ralph flow after interrupted streams Handle interruptions consistently across planning, execution, and review loops by waiting for user input and resuming the stream. Update workflow status hints and tests to reflect cancel-versus-interrupt behavior. Assistant-model: openai/gpt-5.3-codex * feat(config): migrate settings and sync global agent templates Store project selections in .atomic/settings.json with local-over-global resolution, and sync bundled agent configs into ~/.atomic during install and update. Keep SCM-managed skills project-scoped via atomic init, add chat auto-init checks, and clean managed global directories on uninstall. Assistant-model: gpt-5.3-codex * fix(ui): preserve markdown newlines in part rendering Use normalizeMarkdownNewlines as a trim-only pass so markdown lists and paragraph line breaks render correctly in text and reasoning parts. Add tests to lock in newline preservation and outer-whitespace trimming behavior. Assistant-model: gpt-5.3-codex * fix(config): sync and validate global agent configs on install Run global config sync from postinstall and treat partial ~/.atomic setups as missing so editable and package installs always hydrate required agent files. Assistant-model: openai/gpt-5.3-codex * feat(sdk): add native sub-agent dispatch for OpenCode via AgentPartInput Thread an optional `agent` field through Session.stream() and the UI layer so the OpenCode client can build AgentPartInput prompt parts for native sub-agent dispatch. Claude and Copilot clients ignore the option and continue using Task-tool dispatch. Assistant-model: Claude Code * fix(opencode): normalize subagent metadata and config resolution Ensure OpenCode resolves project-scoped agents from the active working directory and handles subtask payload variants so parallel agent rows show stable, meaningful labels. Assistant-model: openai/gpt-5.3-codex * fix(config): sync MCP defaults in install and discovery Package and sync .mcp.json plus Copilot mcp-config.json into ~/.atomic so postinstall validation reflects complete global config state. Also add .vscode/mcp.json discovery and regression tests for MCP config parsing and sync coverage. Assistant-model: openai/gpt-5.3-codex --------- Co-authored-by: lavaman131 <dev@example.com> Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Summary
This PR introduces a breaking change to Atomic's configuration system, migrating from
.atomic.jsonto.atomic/settings.jsonwith local-over-global resolution, automatic global agent config synchronization (including MCP configs), and native sub-agent dispatch for OpenCode. The changes improve config management, enable better multi-project workflows, and enhance the overall user experience.Breaking Changes
Configuration File Migration
.atomic.jsonfiles will no longer be read..atomic.json→.atomic/settings.json.atomic/settings.json(project override)~/.atomic/settings.json(default fallback)atomic initin your project to regenerate settings in the new locationOld
.atomic.jsonfiles can be safely deleted after migration.Key Changes
🔧 Configuration System Overhaul
Global Config Sync
bun install)~/.atomic/.claude,~/.atomic/.opencode,~/.atomic/.copilot~/.atomic/.mcp.jsonand~/.atomic/.copilot/mcp-config.json.claude,.opencode, or.githubfolders~/.atomicsetups are treated as missing to ensure complete config hydrationMCP Config Discovery
.vscode/mcp.jsonto Copilot MCP discovery paths~/.claude/.mcp.json→.mcp.json~/.copilot/mcp-config.json→.github/mcp-config.json,.vscode/mcp.json,mcp-config.json~/.opencode/opencode.json[c]→opencode.json[c],.opencode/opencode.json[c]Auto-Initialization
src/scripts/postinstall.ts) to hydrate global configs automaticallyClean Uninstall
atomic uninstallnow removes managed global directories (~/.atomic/.claude, etc.)--keep-configflag to preserve global configs during uninstall⚡ OpenCode SDK Enhancement
Native Sub-Agent Dispatch
AgentPartInputsupport for improved performance viabuildOpenCodePromptParts()agentfield throughSession.stream()and UI layersubagent.starteventsprocess.cwd()to ensure consistent agent definition resolutionMetadata Normalization
Note: Claude and Copilot clients continue using Task-tool dispatch (no changes).
🎯 Workflow Improvements
Interrupt & Cancellation Handling
workflowActiveon errorwasCancelledtoStreamResultfor better flow controlRalph Flow Recovery
/ralphreview-fix loop recovery after interrupted streamsclearContext()calls from workflowUI/UX Enhancements
🎨 UI Fixes
Markdown Rendering
normalizeMarkdownNewlines()utility for trim-only pass (no aggressive collapsing)Part Display Components
TextPartDisplayto preserve markdown formattingReasoningPartDisplayto maintain proper spacing🧪 Comprehensive Test Coverage
E2E Tests (3 new tests)
Integration Tests (3 new tests)
Unit Tests (100+ new tests)
atomic-config.test.ts(comprehensive local/global resolution)atomic-global-config.test.ts(sync, validation, cleanup)mcp-config.test.ts(parsing and discovery regression tests)opencode-config.test.ts(config resolution)format.test.ts(newline preservation)Coverage Highlights
Migration Guide
For Users
atomic initin your project.atomic/settings.jsonexists with your agent/scm preferences.atomic.jsonfiles (optional)For Contributors
Reading Config
loadConfig(projectDir)for local-over-global resolutionWriting Config
.atomic/settings.jsonviasaveAtomicConfig()ensureAtomicGlobalAgentConfigs()Sub-Agent Dispatch
stream(message, { agent: "agent-name" })for native dispatchFiles Changed
Configuration (5 files)
src/utils/atomic-config.ts- Refactored for local-over-global resolutionsrc/utils/atomic-global-config.ts- New: Global config sync utilitiessrc/utils/opencode-config.ts- New: OpenCode-specific config helperssrc/utils/mcp-config.ts- Enhanced MCP discovery with .vscode/mcp.json supportsrc/scripts/postinstall.ts- New: Auto-hydrate global configsCommands (4 files)
src/commands/init.ts- Update to create.atomic/settings.jsonsrc/commands/chat.ts- OpenCode sub-agent dispatch integrationsrc/commands/uninstall.ts- Clean up managed global dirssrc/commands/update.ts- Sync global configs on updateSDK (3 files)
src/sdk/clients/opencode.ts- Native sub-agent dispatch viaAgentPartInputsrc/sdk/clients/opencode.events.test.ts- Event handler testssrc/sdk/types.ts- Addagentfield to stream optionsUI (10 files)
src/ui/chat.tsx- Thread sub-agent dispatch options, improve stream handlingsrc/ui/index.ts- Workflow interrupt/cancellation logicsrc/ui/commands/*.ts- Update command registry with stream optionssrc/ui/components/parts/*.tsx- Fix markdown renderingsrc/ui/components/parallel-agents-tree.tsx- Metadata display improvementssrc/ui/utils/format.ts- Newline preservation utilitiesInstall (4 files)
install.sh- Add cleanup instructions and MCP config syncinstall.ps1- Add cleanup instructions and MCP config syncpackage.json- Add postinstall script, update packaged files.github/workflows/publish.yml- Include MCP configs in releaseDocumentation (1 file)
README.md- Update config paths and uninstall instructionsTests (9 files)
src/utils/atomic-config.test.ts- 100+ config resolution testssrc/utils/atomic-global-config.test.ts- 40+ global sync testssrc/utils/mcp-config.test.ts- New: MCP parsing and discovery testssrc/utils/opencode-config.test.ts- OpenCode config testssrc/ui/utils/format.test.ts- Newline preservation testssrc/commands/chat.test.ts- Workflow mode testssrc/ui/components/parallel-agents-tree.test.ts- Metadata testsRelated Commits
99cc8b1- fix(config): sync MCP defaults in install and discovery29677f3- fix(opencode): normalize subagent metadata and config resolution2911c3d- feat(sdk): add native sub-agent dispatch for OpenCode via AgentPartInput0a5a5c0- fix(config): sync and validate global agent configs on installf4d70b0- fix(ui): preserve markdown newlines in part renderingdb8a5fb- feat(config): migrate settings and sync global agent templatesdfe647a- fix(workflow): recover /ralph flow after interrupted streamsb6e6d47- refactor(workflow): improve interrupt and cancellation handlingd305dd1- fix(ui): simplify workflow mode label14f9695- feat(ui): add workflow mode label with type and keyboard hinte7cff85- fix(chat): add ralphSessionDir to useEffect dependency array752db9e- fix(workflow): wrap execute body in try-catch to reset workflowActive on errore7eff3b- test(workflow): add 3 E2E tests for workflow inline mode97a74a4- test(workflow): add 3 integration tests for workflow inline mode14b9e9f- test(workflow): add unit tests for workflow inline mode changesc47b3a3- refactor(ralph): remove clearContext() calls from workflow1b82a03- fix(chat): scope ralph state reset to copilot agent typeTest Results
Summary: 39 files changed, 1508 insertions(+), 324 deletions(-)
All tests passing with 180+ new test cases covering: