Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions openspec/changes/restructure-config-schemas/.openspec.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
schema: spec-driven
created: 2026-08-10
32 changes: 32 additions & 0 deletions openspec/changes/restructure-config-schemas/design.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
## Context

The `src/config/schemas.js` file (293 lines) is a monolith containing Zod schemas for 9+ unrelated config sections: providers, sandbox, memory, telemetry, schedules, tui, agent, lru, and persistence. Each section is independently useful but bundled together, creating a file that is difficult to navigate and test. Additionally, `mutate.js` uses a vague name that doesn't convey its purpose.

## Goals / Non-Goals

**Goals:**
- Split schemas.js into per-section files under src/config/schemas/
- Maintain backward compatibility via index.js re-exports
- Rename mutate.js → patch.js
- Evaluate DEFAULT_CONFIG redundancy

**Non-Goals:**
- Changing any Zod validation rules
- Adding new config sections
- Restructuring loader.js

## Decisions

1. **Per-section files, not per-schema:** Each config section (e.g., "memory") gets one file containing all related schemas, not one file per individual schema. This keeps the number of files manageable (~10 files) while still achieving separation of concerns.

2. **Index.js re-exports:** The existing `schemas.js` import path is preserved via `src/config/schemas/index.js`. This ensures zero breaking changes for consumers.

3. **DEFAULT_CONFIG evaluation:** We will audit all consumers before deciding. If Zod `.default()` values are identical to DEFAULT_CONFIG values, we remove DEFAULT_CONFIG. Otherwise, we keep it as a plain-object convenience.

4. **Rename mutate.js → patch.js:** "Patch" better conveys the intent of applying changes to a config object.

## Risks / Trade-offs

- **More files:** The directory gains ~10 files. Mitigation: each file is small and focused (~20-40 lines).
- **Index.js indirection:** Standard practice, low risk.
- **DEFAULT_CONFIG removal:** If any consumer relies on it as a plain object, removal would break them. Mitigation: audit all consumers first.
30 changes: 30 additions & 0 deletions openspec/changes/restructure-config-schemas/proposal.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
## Why

The `src/config/schemas.js` file at 293 lines contains Zod schemas for 9+ unrelated config sections plus a DEFAULT_CONFIG object that duplicates structure already defined by Zod `.default()` calls. This monolithic file violates single-responsibility principles, making it hard to navigate, test, and maintain. Splitting it into focused per-section files reduces cognitive load and enables independent testing of each schema.

## What Changes

- Create `src/config/schemas/` directory with per-section schema files
- Replace `src/config/schemas.js` with `src/config/schemas/index.js` that re-exports all schemas (backward compatible)
- Evaluate and potentially remove DEFAULT_CONFIG if redundant with Zod defaults
- Rename `src/config/mutate.js` → `src/config/patch.js` and update all imports

## Capabilities

### New Capabilities
- `config-schemas`: Modular schema organization with per-section Zod schemas and re-export index

### Modified Capabilities
- None — structural refactoring with no spec-level behavior changes

## Impact

- Affected code: `src/config/schemas.js`, `src/config/mutate.js`, all files importing from either
- No API changes — Zod validation behavior preserved
- No dependency changes

## Non-goals

- Adding new config sections or schemas
- Changing Zod validation rules or default values
- Restructuring `loader.js` or `patch.js` beyond the rename
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
## ADDED Requirement: Modular schema files

The system SHALL split the monolithic `src/config/schemas.js` into per-section files under `src/config/schemas/`, with each file containing schemas for a single config section.

### Requirement: Schema re-export compatibility

The system SHALL provide `src/config/schemas/index.js` that re-exports all schemas, maintaining backward compatibility with existing import paths.

#### Scenario: Existing imports continue to work
- **WHEN** a file imports from `src/config/schemas.js` or `../schemas.js`
- **THEN** the import resolves correctly via the index.js re-exports

#### Scenario: All schemas are accessible
- **WHEN** importing from `src/config/schemas/`
- **THEN** all previously exported schemas (providers, sandbox, memory, telemetry, schedules, tui, agent, lru, persistence) are available

### Requirement: DEFAULT_CONFIG evaluation

The system SHALL audit all consumers of `DEFAULT_CONFIG` and determine whether it can be removed or must be preserved.

#### Scenario: DEFAULT_CONFIG is redundant
- **WHEN** all Zod `.default()` values match DEFAULT_CONFIG values
- **THEN** DEFAULT_CONFIG is removed from the codebase

#### Scenario: DEFAULT_CONFIG is needed
- **WHEN** any consumer relies on DEFAULT_CONFIG as a plain object
- **THEN** DEFAULT_CONFIG is preserved and documented

### Requirement: mutate.js rename

The system SHALL rename `src/config/mutate.js` to `src/config/patch.js` and update all import paths.

#### Scenario: No broken imports
- **WHEN** all files that imported from `mutate.js` are updated
- **THEN** no import errors occur and all functionality is preserved

#### Scenario: No remaining references
- **WHEN** the codebase is searched for `mutate`
- **THEN** no references to `mutate.js` remain (only `patch.js`)
44 changes: 44 additions & 0 deletions openspec/changes/restructure-config-schemas/tasks.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
## 1. Create schema directory structure

- [ ] 1.1 Create `src/config/schemas/` directory
- [ ] 1.2 Audit `src/config/schemas.js` to identify all schema sections and their boundaries

## 2. Extract per-section schema files

- [ ] 2.1 Extract providers schema → `src/config/schemas/providers.js`
- [ ] 2.2 Extract sandbox schema → `src/config/schemas/sandbox.js`
- [ ] 2.3 Extract memory schema → `src/config/schemas/memory.js`
- [ ] 2.4 Extract telemetry schema → `src/config/schemas/telemetry.js`
- [ ] 2.5 Extract schedules schema → `src/config/schemas/schedules.js`
- [ ] 2.6 Extract tui schema → `src/config/schemas/tui.js`
- [ ] 2.7 Extract agent schema → `src/config/schemas/agent.js`
- [ ] 2.8 Extract lru schema → `src/config/schemas/lru.js`
- [ ] 2.9 Extract persistence schema → `src/config/schemas/persistence.js`

## 3. Create index.js re-exports

- [ ] 3.1 Create `src/config/schemas/index.js` re-exporting all schemas
- [ ] 3.2 Verify all existing import patterns still resolve correctly

## 4. Evaluate DEFAULT_CONFIG

- [ ] 4.1 Find all consumers of DEFAULT_CONFIG using grep
- [ ] 4.2 Compare DEFAULT_CONFIG values against Zod `.default()` values
- [ ] 4.3 Remove DEFAULT_CONFIG if redundant, or preserve if needed

## 5. Rename mutate.js → patch.js

- [ ] 5.1 Rename `src/config/mutate.js` → `src/config/patch.js` using `git mv`
- [ ] 5.2 Find and update all import paths referencing `mutate.js`
- [ ] 5.3 Verify no remaining references to `mutate` in import statements

## 6. Remove old schemas.js

- [ ] 6.1 Remove `src/config/schemas.js` (replaced by schemas/ directory)
- [ ] 6.2 Verify no remaining imports reference the old file

## 7. Verify and test

- [ ] 7.1 Run `npm test` to verify all tests pass
- [ ] 7.2 Run `npm start` with timeout to verify application starts
- [ ] 7.3 Verify config loading works with new structure