Skip to content

Conversation

@TabishB
Copy link
Contributor

@TabishB TabishB commented Jan 20, 2026

Summary

  • Adds openspec schema command group for managing workflow schemas
  • schema which shows where a schema resolves from with shadow detection
  • schema validate validates schema structure, templates, and dependency graph
  • schema fork copies an existing schema to project for customization
  • schema init creates a new project-local schema with interactive or CLI-driven configuration

Implements the schema-management-cli change proposal.

Test plan

  • All 1018 existing tests pass
  • 22 new tests for schema commands pass
  • Manual testing of all four subcommands
  • JSON output format verified for all commands
  • Shell completion registry updated with schema-name positional type

🤖 Generated with Claude Code

Summary by CodeRabbit

Release Notes

  • New Features

    • Added schema management command with subcommands for discovering, validating, forking, and initializing workflows schemas. Includes support for JSON output across all operations.
  • Tests

    • Added comprehensive test suite covering schema discovery, validation, fork workflows, and initialization flows.

✏️ Tip: You can customize this high-level summary in your review settings.

Add `openspec schema` command group with subcommands for managing
workflow schemas:

- `schema which [name]` - Show where a schema resolves from with
  shadow detection across project/user/package locations
- `schema validate [name]` - Validate schema structure, templates,
  and dependency graph
- `schema fork <source> [name]` - Copy an existing schema to project
  for customization
- `schema init <name>` - Create a new project-local schema with
  interactive or CLI-driven configuration

All commands support `--json` output for scripting. The init command
supports interactive prompts for description and artifact selection.

Implements the schema-management-cli change proposal.
@coderabbitai
Copy link
Contributor

coderabbitai bot commented Jan 20, 2026

📝 Walkthrough

Walkthrough

This PR introduces a comprehensive schema management CLI command module with subcommands for discovering, validating, forking, and initializing schemas. It includes schema resolution utilities, validation logic, template handling, directory operations, and extensive test coverage. Task documentation is marked complete.

Changes

Cohort / File(s) Summary
Schema Command Implementation
src/commands/schema.ts
New 1000-line module implementing four subcommands: which (discover schemas across project/user/package), validate (YAML parsing, template verification, dependency validation), fork (copy schema with conflict handling), and init (create new schemas in interactive/non-interactive modes). Includes internal utilities for schema resolution, shadowing detection, kebab-case validation, and default template generation. Supports JSON and human-readable output.
CLI Integration & Registration
src/cli/index.ts, src/core/completions/command-registry.ts
Added import and dual registration of registerSchemaCommand in CLI entry point; expanded COMMAND_REGISTRY with "schema" command entry and four subcommands (which, validate, fork, init) with associated flags (json, all, verbose, force, description, artifacts, default, no-default).
Type System Extension
src/core/completions/types.ts
Extended CommandDefinition.positionalType union to include 'schema-name' as valid positional completion type.
Test Suite
test/commands/schema.test.ts
New 467-line comprehensive test suite covering schema discovery, validation (valid/invalid scenarios, circular dependencies), fork workflow, init flow with artifact selection, JSON output validation, name format validation, and command registry integrity checks. Uses temporary directories and XDG path stubbing.
Documentation Status
openspec/changes/schema-management-cli/tasks.md
All pending task items across setup, commands, schema operations, testing, and polish sections marked as completed.

Sequence Diagrams

sequenceDiagram
    actor User
    participant CLI as CLI (index.ts)
    participant SchemaCmd as Schema Command
    participant Resolver as Schema Resolver
    participant Parser as YAML Parser
    participant FS as Filesystem
    
    User->>CLI: schema validate my-schema
    CLI->>SchemaCmd: registerSchemaCommand()
    SchemaCmd->>Resolver: resolveSchema('my-schema')
    Resolver->>FS: search project/user/package dirs
    FS-->>Resolver: schema.yaml path
    Resolver-->>SchemaCmd: SchemaInfo
    SchemaCmd->>Parser: parse schema.yaml
    Parser-->>SchemaCmd: parsed schema object
    SchemaCmd->>SchemaCmd: validate dependencies
    SchemaCmd->>FS: check template existence
    FS-->>SchemaCmd: template status
    SchemaCmd->>CLI: return validation results
    CLI-->>User: display results (JSON/human)
Loading
sequenceDiagram
    actor User
    participant CLI as CLI (index.ts)
    participant SchemaCmd as Schema Command
    participant Resolver as Schema Resolver
    participant FS as Filesystem
    participant Config as Config File
    
    User->>CLI: schema init --description "My Schema"
    CLI->>SchemaCmd: registerSchemaCommand()
    SchemaCmd->>SchemaCmd: prompt for schema name (if interactive)
    SchemaCmd->>SchemaCmd: validate name (kebab-case)
    SchemaCmd->>Resolver: getProjectSchemasDir()
    Resolver-->>SchemaCmd: project schema directory
    SchemaCmd->>FS: check destination exists
    FS-->>SchemaCmd: exists/not exists
    User->>SchemaCmd: select artifacts
    SchemaCmd->>SchemaCmd: wire artifact dependencies
    SchemaCmd->>FS: create schema directory
    SchemaCmd->>FS: write schema.yaml with metadata
    SchemaCmd->>FS: generate default templates
    alt Set as Default
        SchemaCmd->>Config: update config (if --default flag)
    end
    SchemaCmd->>CLI: return init results
    CLI-->>User: display results (JSON/human)
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~50 minutes

Possibly related PRs

Poem

🐰 hop hop Schema order, clear and bright,
CLI commands that organize just right,
Validate, fork, and init with glee,
From package to project, schemas run free,
Management made simple, logical delight! ✨

🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately describes the main change: adding schema management commands to the CLI, which is the core of this PR.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing touches
  • 📝 Generate docstrings

Warning

There were issues while running some tools. Please review the errors and either fix the tool's configuration or disable the tool if it's a critical failure.

🔧 markdownlint-cli2 (0.18.1)
openspec/changes/schema-management-cli/tasks.md

markdownlint-cli2 v0.18.1 (markdownlint v0.38.0)
Finding: openspec/changes/schema-management-cli/tasks.md
Linting: 1 file(s)
Summary: 0 error(s)
Error: EACCES: permission denied, open '/markdownlint-cli2-results.json'
at async open (node:internal/fs/promises:640:25)
at async Object.writeFile (node:internal/fs/promises:1214:14)
at async Promise.all (index 0)
at async outputSummary (file:///usr/local/lib/node_modules/markdownlint-cli2/markdownlint-cli2.mjs:877:5)
at async main (file:///usr/local/lib/node_modules/markdownlint-cli2/markdownlint-cli2.mjs:1053:25)
at async file:///usr/local/lib/node_modules/markdownlint-cli2/markdownlint-cli2-bin.mjs:12:22 {
errno: -13,
code: 'EACCES',
syscall: 'open',
path: '/markdownlint-cli2-results.json'
}


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@greptile-apps
Copy link

greptile-apps bot commented Jan 20, 2026

Greptile Summary

Adds comprehensive schema management CLI with four subcommands for inspecting, validating, forking, and creating workflow schemas.

Key Changes:

  • schema which - Shows schema resolution order (project → user → package) with shadow detection when multiple versions exist
  • schema validate - Validates schema structure, template file existence, and dependency graph for cycles
  • schema fork - Copies existing schemas to project directory for customization with automatic name field updates
  • schema init - Creates new project-local schemas with interactive artifact selection and optional default schema configuration
  • All commands support --json output for programmatic use
  • Shell completion registry updated with new schema-name positional type for tab completion
  • 22 comprehensive tests covering all commands, error cases, and JSON output formats

Implementation Quality:

  • Clean separation of concerns with helper functions for resolution, validation, and file operations
  • Consistent error handling with descriptive messages and proper exit codes
  • Interactive prompts use @inquirer/prompts for better UX when creating schemas
  • Template location flexibility supporting both root and templates/ subdirectory
  • Proper dependency chain setup in schema init (proposal → specs → design → tasks)

Confidence Score: 5/5

  • Safe to merge - well-tested feature addition with no breaking changes
  • All 1018 existing tests pass, 22 new tests provide comprehensive coverage, implementation follows established patterns in the codebase, and the change is purely additive
  • No files require special attention

Important Files Changed

Filename Overview
src/commands/schema.ts New file adding four schema management subcommands (which, validate, fork, init) with comprehensive error handling, JSON output support, and interactive prompts
src/cli/index.ts Imports and registers the new schema command group with the CLI program
test/commands/schema.test.ts Comprehensive test suite with 22 tests covering all schema commands, validation logic, shadowing detection, and JSON output formats
src/core/completions/command-registry.ts Adds schema command with four subcommands to shell completion registry, including all flags and new schema-name positional type

Sequence Diagram

sequenceDiagram
    participant User
    participant CLI as CLI (index.ts)
    participant SchemaCmd as Schema Command
    participant Resolver as resolver.ts
    participant Parser as schema.ts
    participant FS as File System

    Note over User,FS: Schema Which Command
    User->>CLI: openspec schema which <name>
    CLI->>SchemaCmd: Execute which action
    SchemaCmd->>Resolver: checkAllLocations(name, projectRoot)
    Resolver->>FS: Check project/schemas/<name>/schema.yaml
    FS-->>Resolver: exists/not exists
    Resolver->>FS: Check user/schemas/<name>/schema.yaml
    FS-->>Resolver: exists/not exists
    Resolver->>FS: Check package/schemas/<name>/schema.yaml
    FS-->>Resolver: exists/not exists
    Resolver-->>SchemaCmd: Return locations array
    SchemaCmd->>SchemaCmd: Build resolution with shadow info
    SchemaCmd-->>User: Display source, path, shadows

    Note over User,FS: Schema Validate Command
    User->>CLI: openspec schema validate <name>
    CLI->>SchemaCmd: Execute validate action
    SchemaCmd->>Resolver: getSchemaDir(name, projectRoot)
    Resolver-->>SchemaCmd: Return schema directory path
    SchemaCmd->>FS: Read schema.yaml
    FS-->>SchemaCmd: YAML content
    SchemaCmd->>Parser: parseSchema(content)
    Parser->>Parser: Validate structure & dependencies
    Parser-->>SchemaCmd: Schema object or throw error
    SchemaCmd->>FS: Check template files exist
    FS-->>SchemaCmd: exists/not exists for each
    SchemaCmd->>SchemaCmd: Collect validation issues
    SchemaCmd-->>User: Display valid/invalid with issues

    Note over User,FS: Schema Fork Command
    User->>CLI: openspec schema fork <source> [name]
    CLI->>SchemaCmd: Execute fork action
    SchemaCmd->>SchemaCmd: Validate destination name (kebab-case)
    SchemaCmd->>Resolver: getSchemaDir(source, projectRoot)
    Resolver-->>SchemaCmd: Source schema directory
    SchemaCmd->>FS: Check destination exists
    FS-->>SchemaCmd: exists check result
    alt Destination exists and --force
        SchemaCmd->>FS: Remove existing destination
    end
    SchemaCmd->>FS: Copy directory recursively
    SchemaCmd->>FS: Read copied schema.yaml
    FS-->>SchemaCmd: Schema content
    SchemaCmd->>Parser: parseSchema(content)
    Parser-->>SchemaCmd: Schema object
    SchemaCmd->>SchemaCmd: Update name field
    SchemaCmd->>FS: Write updated schema.yaml
    SchemaCmd-->>User: Display source and destination paths

    Note over User,FS: Schema Init Command
    User->>CLI: openspec schema init <name>
    CLI->>SchemaCmd: Execute init action
    SchemaCmd->>SchemaCmd: Validate name (kebab-case)
    alt Interactive mode
        SchemaCmd->>User: Prompt for description
        User-->>SchemaCmd: Enter description
        SchemaCmd->>User: Prompt for artifacts (multi-select)
        User-->>SchemaCmd: Select artifacts
        SchemaCmd->>User: Set as default schema?
        User-->>SchemaCmd: Yes/No
    end
    SchemaCmd->>SchemaCmd: Build schema with dependencies
    SchemaCmd->>FS: Create schema directory
    SchemaCmd->>FS: Write schema.yaml
    SchemaCmd->>FS: Create template files in templates/
    alt Set as default
        SchemaCmd->>FS: Update openspec/config.yaml
    end
    SchemaCmd-->>User: Display created path and next steps
Loading

@vibe-kanban-cloud
Copy link

Review Complete

Your review story is ready!

View Story

Comment !reviewfast on this PR to re-generate the story.

@TabishB TabishB merged commit 3cdcdfc into main Jan 20, 2026
9 of 10 checks passed
@TabishB TabishB deleted the feat/schema-management-cli branch January 20, 2026 03:42
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🤖 Fix all issues with AI agents
In `@src/commands/schema.ts`:
- Around line 986-992: The returned template in the switch case 'tasks'
currently uses plain bullet entries; update the returned multi-line string in
the case 'tasks' (the return that begins with "## Implementation Tasks") to use
the numbered checklist format required for tasks.md by replacing each "- [ ]
Task X" line with "- [ ] X.Y Description" entries (e.g., "- [ ] 1.1 …", "- [ ]
1.2 …", "- [ ] 1.3 …") so the checklist follows the X.Y numeric pattern while
preserving the header and overall string return in that case branch.
- Around line 459-464: When outputting JSON in the validation flow (the branch
that checks options?.json and the other JSON branch around the later block), set
process.exitCode = 1 when anyInvalid is true so callers can detect failures;
update the blocks that currently console.log(JSON.stringify({ valid:
!anyInvalid, schemas: schemaResults }, null, 2)) to also set process.exitCode =
1 when anyInvalid is truthy, keeping the same JSON payload and existing control
flow for valid cases.

Comment on lines +459 to +464
if (options?.json) {
console.log(JSON.stringify({
valid: !anyInvalid,
schemas: schemaResults,
}, null, 2));
} else {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

Set non‑zero exit codes on validation failures even with --json.

Right now the JSON branches return without setting process.exitCode, so scripted usage can’t detect invalid schemas by exit status.

✅ Proposed fix
          if (options?.json) {
            console.log(JSON.stringify({
              valid: !anyInvalid,
              schemas: schemaResults,
            }, null, 2));
+           if (anyInvalid) {
+             process.exitCode = 1;
+           }
          } else {
        if (options?.json) {
          console.log(JSON.stringify({
            name,
            path: schemaDir,
            valid: result.valid,
            issues: result.issues,
          }, null, 2));
+         if (!result.valid) {
+           process.exitCode = 1;
+         }
        } else {

Also applies to: 511-517

🤖 Prompt for AI Agents
In `@src/commands/schema.ts` around lines 459 - 464, When outputting JSON in the
validation flow (the branch that checks options?.json and the other JSON branch
around the later block), set process.exitCode = 1 when anyInvalid is true so
callers can detect failures; update the blocks that currently
console.log(JSON.stringify({ valid: !anyInvalid, schemas: schemaResults }, null,
2)) to also set process.exitCode = 1 when anyInvalid is truthy, keeping the same
JSON payload and existing control flow for valid cases.

Comment on lines +986 to +992
case 'tasks':
return `## Implementation Tasks
- [ ] Task 1
- [ ] Task 2
- [ ] Task 3
`;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Align the default tasks template with the required numbered checklist format.

The template currently uses generic bullet tasks, which conflicts with the required “X.Y” checkbox format for tasks.md.

✅ Proposed fix
     case 'tasks':
-      return `## Implementation Tasks
-
-- [ ] Task 1
-- [ ] Task 2
-- [ ] Task 3
-`;
+      return `## 1. Implementation Tasks
+
+- [ ] 1.1 Task description
+- [ ] 1.2 Task description
+- [ ] 1.3 Task description
+`;

As per coding guidelines, tasks.md should use numbered - [ ] X.Y entries.

🤖 Prompt for AI Agents
In `@src/commands/schema.ts` around lines 986 - 992, The returned template in the
switch case 'tasks' currently uses plain bullet entries; update the returned
multi-line string in the case 'tasks' (the return that begins with "##
Implementation Tasks") to use the numbered checklist format required for
tasks.md by replacing each "- [ ] Task X" line with "- [ ] X.Y Description"
entries (e.g., "- [ ] 1.1 …", "- [ ] 1.2 …", "- [ ] 1.3 …") so the checklist
follows the X.Y numeric pattern while preserving the header and overall string
return in that case branch.

TabishB added a commit that referenced this pull request Jan 20, 2026
Update documentation to reflect implemented schema management features:
- Document schema CLI commands (which, validate, fork, init)
- Update gap summary to show completed phases (PR #522, #525)
- Improve custom schema examples with actual CLI usage
- Update resolution order documentation
TabishB added a commit that referenced this pull request Jan 20, 2026
Update documentation to reflect implemented schema management features:
- Document schema CLI commands (which, validate, fork, init)
- Update gap summary to show completed phases (PR #522, #525)
- Improve custom schema examples with actual CLI usage
- Update resolution order documentation
TabishB added a commit that referenced this pull request Jan 20, 2026
…526)

* docs: update workflow docs for schema management CLI

Update documentation to reflect implemented schema management features:
- Document schema CLI commands (which, validate, fork, init)
- Update gap summary to show completed phases (PR #522, #525)
- Improve custom schema examples with actual CLI usage
- Update resolution order documentation

* feat(cli): mark schema commands as experimental

Add [experimental] tag to help description and runtime warning
for schema management commands to indicate they may change.
StrayDragon pushed a commit to StrayDragon/OpenSpec that referenced this pull request Jan 20, 2026
Add `openspec schema` command group with subcommands for managing
workflow schemas:

- `schema which [name]` - Show where a schema resolves from with
  shadow detection across project/user/package locations
- `schema validate [name]` - Validate schema structure, templates,
  and dependency graph
- `schema fork <source> [name]` - Copy an existing schema to project
  for customization
- `schema init <name>` - Create a new project-local schema with
  interactive or CLI-driven configuration

All commands support `--json` output for scripting. The init command
supports interactive prompts for description and artifact selection.

Implements the schema-management-cli change proposal.
StrayDragon pushed a commit to StrayDragon/OpenSpec that referenced this pull request Jan 20, 2026
…ission-AI#526)

* docs: update workflow docs for schema management CLI

Update documentation to reflect implemented schema management features:
- Document schema CLI commands (which, validate, fork, init)
- Update gap summary to show completed phases (PR Fission-AI#522, Fission-AI#525)
- Improve custom schema examples with actual CLI usage
- Update resolution order documentation

* feat(cli): mark schema commands as experimental

Add [experimental] tag to help description and runtime warning
for schema management commands to indicate they may change.
harikrishnan83 added a commit to intent-driven-dev/OpenSpec that referenced this pull request Jan 21, 2026
# By Tabish Bidiwale (57) and others
# Via GitHub
* main: (67 commits)
  fix(ci): use workflow_dispatch for polish release notes (Fission-AI#533)
  fix(changelog): convert markdown headers to bold text for proper formatting (Fission-AI#532)
  Version Packages (Fission-AI#531)
  Add changeset for project config and schema commands (Fission-AI#530)
  fix(config): handle null rules field in project config (Fission-AI#529)
  docs: update workflow docs and mark schema commands as experimental (Fission-AI#526)
  feat(cli): add schema management commands (Fission-AI#525)
  fix: Windows path compatibility in resolver tests (Fission-AI#524)
  change(schema-management-cli): proposal for schema management commands (Fission-AI#523)
  feat(resolver): add project-local schema support (Fission-AI#522)
  docs: add project-config demo guide (Fission-AI#521)
  feat(config): add project-level configuration via openspec/config.yaml (Fission-AI#499)
  fix: auto-trigger polish release notes on release publish (Fission-AI#519)
  perf: add path filtering to Nix validation CI job (Fission-AI#518)
  Version Packages (Fission-AI#517)
  Add changeset for v0.21 release (Fission-AI#516)
  fix: prevent implementation during explore mode (Fission-AI#515)
  OPSX apply: infer target change (Fission-AI#513)
  Refine opsx archive sync assessment (Fission-AI#514)
  feat: add nix flake support (sorry for this duplicate) (Fission-AI#459)
  ...

# Conflicts:
#	src/core/templates/slash-command-templates.ts
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants