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
13 changes: 9 additions & 4 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## [0.2.0] - 2026-06-22
## [0.3.0] - 2026-06-25

Sync with upstream OpenSpec `v1.2.0` → `v1.4.1`, plus a parity audit of the
whole port against upstream that fixed several pre-existing interop/correctness
Expand All @@ -20,11 +20,16 @@ gaps.
- **Workspaces (beta)** — `openspec workspace <setup|list|link|relink|doctor|update|open>`, with `.openspec-workspace/view.yaml` view state, a managed `workspaces/registry.yaml`, AGENTS.md guidance + `<name>.code-workspace` generation, and per-tool workspace skills
- `openspec templates [--schema <name>] [--json]` — show resolved template paths per artifact
- `openspec schema <which|validate|fork|init>` — inspect, validate, copy, and scaffold workflow schemas
- `openspec feedback <message> [--body <text>]` — file feedback as a GitHub issue via the `gh` CLI, with a manual issue-URL fallback when `gh` is missing or unauthenticated
- `openspec set change <name> --initiative <id>` — link a repo-local change to an initiative

### Changed
- `config` now uses upstream-style subcommands (`path`, `list`, `get`, `set`, `unset`, `reset`, `edit`, `profile`) instead of the old flat `--set/--get/--list` flags. This is a breaking CLI surface change.
- `new change` now supports upstream parity flags: `--json`, `--goal`, `--affected-areas`, `--initiative`, `--store`, and `--store-path`
- `show --json` now supports spec-filter flags `--requirements`, `--requirement <n>`, and `--no-scenarios`; those flags are JSON-only and warn when used on a change
- `validate` now supports bounded parallelism via `--concurrency <n>` and matches upstream strictness — ERROR (not warning) when a spec has no requirements or a requirement lacks SHALL/MUST or a scenario; change validation detects duplicate and cross-section delta conflicts; `--strict` makes warnings fail; plus a hint when SHALL/MUST appears only in a requirement header
- Global `--no-interactive` is accepted as a no-op for upstream CLI compatibility
- Spec parser: requirement headers parsed case-insensitively; **Markdown headers inside fenced code blocks are ignored** (not parsed as requirements/scenarios), matching upstream
- `validate`: now matches upstream strictness — ERROR (not warning) when a spec has no requirements or a requirement lacks SHALL/MUST or a scenario; change validation detects duplicate and cross-section delta conflicts; `--strict` makes warnings fail; plus a hint when SHALL/MUST appears only in a requirement header
- `show --json`: emits the upstream JSON shape (camelCase `requirementCount`/`deltaCount`/`rawText`, spec `metadata` block, rich change deltas with `spec`/`operation`/`requirement`/`rename`)
- Global `config.json` written with upstream camelCase keys (`featureFlags`, `anonymousId`, `noticeSeen`); snake_case still read for back-compat
- Shell completion install is opt-in
Expand All @@ -36,10 +41,10 @@ gaps.
- `--json` output no longer leaks spinner text to stderr
- `context-store setup --path <p>` refuses a path inside an existing Git repository (git-nesting guard), with a `--allow-inside-git-repository` escape hatch
- `archive` re-validates each merged main spec before writing it (honoring `--no-validate`), so a bad merge can no longer silently corrupt specs
- Built-in package-schema resolution now uses the embedded `spec-driven` definition instead of a dev-only `vendor/OpenSpec/schemas` path, so installed binaries work from arbitrary directories

### Known gaps
- `openspec feedback` and the interactive `openspec view` dashboard are not ported
- Package-schema resolution uses a dev-only `vendor/OpenSpec/schemas` path; installed binaries fall back to the embedded schema
- The interactive `openspec view` dashboard is not ported

## [0.1.4] - 2026-03-15

Expand Down
2 changes: 1 addition & 1 deletion Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "openspec"
version = "0.2.0"
version = "0.3.0"
edition = "2021"
rust-version = "1.75"
description = "AI-native system for spec-driven development"
Expand Down
13 changes: 8 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -107,24 +107,27 @@ AI: Archived. Specs updated.
| Command | Description |
|---------|-------------|
| `init [path]` | Initialize OpenSpec in a project |
| `new change <name>` | Create a new change directory |
| `new change <name>` | Create a new change directory; supports `--json`, `--goal`, `--affected-areas`, `--initiative`, `--store`, and `--store-path` |
| `list` | List changes (or specs with `--specs`) |
| `status` | Show artifact completion status |
| `instructions [artifact]` | Get instructions for creating artifacts |
| `schemas` | List available workflow schemas |
| `show [item]` | Show a change or spec |
| `validate [item]` | Validate changes and specs |
| `show [item]` | Show a change or spec; `--json` supports `--requirements`, `--requirement <n>`, and `--no-scenarios` |
| `validate [item]` | Validate changes and specs with `--all`, `--changes`, `--specs`, `--strict`, and `--concurrency <n>` |
| `archive [change]` | Archive a completed change |
| `feedback <message>` | File feedback as a GitHub issue (via `gh`, with a manual-URL fallback) |
| `update [path]` | Update AI tool instruction files |
| `config` | View and modify configuration |
| `completion` | Generate shell completions |
| `config` | View and modify configuration via `path`, `list`, `get`, `set`, `unset`, `reset`, `edit`, and `profile` |
| `completion` | Generate or install shell completions |
| `context-store` | Set up and inspect local context stores (beta) |
| `initiative` | Create and inspect coordinated initiatives (beta) |
| `workspace` | Set up and inspect coordination workspaces (beta) |
| `templates` | Show resolved template paths for a schema |
| `schema` | Inspect, validate, fork, or init workflow schemas |
| `set change` | Link a repo-local change to an initiative |

Global compatibility flags: `--no-color` and `--no-interactive` are accepted on all commands; `--no-interactive` is a no-op in the Rust CLI.

## Coordination: Context Stores, Initiatives & Workspaces (beta)

For work that spans multiple repositories, OpenSpec-rs adds three coordination
Expand Down
11 changes: 6 additions & 5 deletions docs/STATE.md
Original file line number Diff line number Diff line change
Expand Up @@ -244,22 +244,23 @@ Location: `openspec/changes/archive/2026-03-15-port-to-rust-binary/`

| Version | Date | Notes |
|---------|------|-------|
| v0.3.0 | 2026-06-25 | CLI parity with upstream v1.4.1: config subcommands (breaking), feedback (GitHub issue), schema fork/init, templates, set change, show spec-filters, validate --concurrency, --no-interactive, embedded package-schema resolution |
| v0.2.0 | 2026-06-20 | Sync to upstream v1.4.1: new AI tools, parser/validation/completion/telemetry fixes, macOS dir interop, and context-store / initiatives / workspace subsystems |
| v0.1.4 | 2026-03-15 | Documentation complete, port-to-rust-binary archived, main specs created |
| v0.1.3 | 2026-03-14 | Rust 1.75 MSRV, pinned dependencies, GitHub Actions updates |
| v0.1.2 | 2026-03-14 | Fix ARM cross-compilation strip |
| v0.1.1 | 2026-03-14 | Fix CI build before tests |
| v0.1.0 | 2026-03-14 | Initial release |

## Current Version: 0.2.0
## Current Version: 0.3.0

- MSRV: Rust 1.75+
- Synced to upstream OpenSpec v1.4.1 (see CHANGELOG `[0.2.0]`)
- New AI tools and `detectionPaths` auto-detection; opt-in completion install; firewall-silent telemetry
- Global config/data dirs aligned with upstream on macOS
- Synced to upstream OpenSpec v1.4.1 (see CHANGELOG `[0.2.0]` and `[0.3.0]`)
- Full CLI parity with upstream v1.4.1: config subcommands (breaking change), feedback (files a GitHub issue), schema fork/init, templates, set change, show spec-filters, validate --concurrency + OPENSPEC_CONCURRENCY, global --no-interactive
- Package-schema resolution uses the embedded `spec-driven` definition (no dev-only vendor path)
- New subsystems: context-store, initiatives, workspace (beta) — with CLI commands
- All 6 skills embedded: explore, propose, apply-change, archive-change, verify-change, sync-specs
- Change `sync-upstream-v1-4-1` lives in `openspec/changes/` (archive after release)
- Known gaps: interactive `view` dashboard, and deprecated `spec`/`change` noun command groups, not ported

## See Also

Expand Down
2 changes: 2 additions & 0 deletions openspec/changes/cli-parity-upstream/.openspec.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
schema: spec-driven
created: 2026-06-22
49 changes: 49 additions & 0 deletions openspec/changes/cli-parity-upstream/design.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
## Context

The Rust port reached behavioral + on-disk parity with upstream v1.4.1 in v0.2.0. The remaining differences are CLI-surface only: missing commands/flags identified by the parity audit. This change closes them. The port is intentionally non-interactive and flag-driven; upstream interactive flows become flags or are no-ops.

## Goals / Non-Goals

**Goals:**
- Full CLI command/flag parity with upstream v1.4.1 for the in-scope items.
- Keep on-disk formats unchanged (config.json already camelCase; `.openspec.yaml` initiative link already defined).

**Non-Goals:**
- The `view` interactive TUI dashboard (separate effort if ever wanted).
- Re-adding deprecated noun command groups (`spec`/`change`) or the `experimental` alias — upstream deprecates them and the verb-first equivalents exist.

## Decisions

### 1. `config` → subcommands (BREAKING)
Replace the flat `Config { set, get, list }` with a `Config(ConfigCommands)` group: `Path | List {json} | Get {key} | Set {key,value} | Unset {key} | Reset {all} | Edit | Profile {preset}`. Rationale: match upstream exactly; the flat form has no upstream analogue and confuses users switching tools. Document the break in CHANGELOG. `edit` shells out to `$EDITOR`/`$VISUAL` (fallback to a sensible default).

### 2. `feedback` reuses the telemetry transport
`feedback <message>` posts via the existing telemetry client (PostHog) under the same opt-out gating (`OPENSPEC_TELEMETRY`/`DO_NOT_TRACK`/CI). No new network stack. If disabled, it no-ops with a clear message. *Alternative:* a dedicated endpoint — rejected (reuse existing, respect existing consent).

### 3. `--no-interactive` as a global no-op clap flag
Add a global `--no-interactive` (like `--no-color`) so any command accepts it without error. Simplest faithful adaptation of upstream's per-command flag. *Alternative:* per-command flags — more surface, no benefit here.

### 4. `new change` flags reuse existing infra
`--initiative`/`--store`/`--store-path` reuse the initiatives resolution + the `set change` linking logic (write `initiative` into `.openspec.yaml`). `--goal`/`--affected-areas` add the optional ChangeMetadata fields upstream defines. `--json` prints `{id, path}`.

### 5. `show` spec filters operate on parsed JSON
`--requirements` / `--requirement <n>` / `--no-scenarios` filter the already-parsed spec model before serializing (mirror upstream `filterSpec`). JSON-only (ignored for change/human output, with a warning like upstream).

### 6. `validate --concurrency <n>`
Bound parallel validation with a worker pool (default mirrors upstream). Determinism of aggregated output preserved (sort results).

### 7. Package-schema resolution fix
`get_package_schemas_dir` currently returns the hardcoded relative `vendor/OpenSpec/schemas`. Change resolution so the built-in schema comes from the embedded definition (already in the binary) rather than a path that only exists in the dev checkout; keep project/user schema dirs. This makes `schema which`/`templates` correct for installed users.

## Risks / Trade-offs

- **config BREAKING change** → mitigation: clear CHANGELOG note + matching upstream reduces long-term confusion; pre-1.0 so acceptable.
- **`config edit` shelling to an editor** → not unit-testable end-to-end; factor editor-command resolution into a testable helper, gate the actual spawn.
- **Schema-resolution change** → ensure `schemas`/`schema which`/`templates`/`validate` still work in-repo and installed; cover with tests using an isolated dir.

## Migration Plan
Land per command group (config, feedback, show flags, new-change flags, validate concurrency, no-interactive, schema fix), each with the full CI gate (fmt + clippy --all-targets -D warnings + test) and `validate --all` 8/8+. Update CHANGELOG (note the config break) and README command table.

## Open Questions
- `config edit` default editor on each platform when `$EDITOR`/`$VISUAL` unset (vi vs notepad) — match upstream's choice.
- Exact `feedback` payload/event name upstream uses (confirm against `cli/index.ts` feedback action during implementation).
32 changes: 32 additions & 0 deletions openspec/changes/cli-parity-upstream/proposal.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
## Why

After the v1.2→v1.4.1 sync and parity audit, the Rust port matches upstream OpenSpec on behavior and on-disk formats, but a set of **CLI surface gaps** remain: commands and flags present in the npm CLI (v1.4.1) that the Rust binary is missing. These break muscle memory and scripts for users switching between the two. This change closes the remaining gaps to reach full CLI parity with upstream v1.4.1.

(Upstream v1.4.1 is the latest release; this is not a new version sync — it's the unported remainder identified by the audit.)

## What Changes

**In scope — parity gaps to close:**
- **`config` subcommands**: replace the flat `--set/--get/--list` with upstream's subcommand shape — `config path | list | get <key> | set <key> <value> | unset <key> | reset [--all] | edit | profile [preset]`.
- **`feedback <message>`**: submit anonymous feedback (respects telemetry opt-out / `--body`).
- **`show` spec-filter flags**: `--requirements` (requirements only), `--requirement <id>` (one requirement, 1-based), `--no-scenarios`.
- **`new change` flags**: `--json`, `--goal`, `--affected-areas`, and initiative linking `--initiative`/`--store`/`--store-path`.
- **`validate --concurrency <n>`**: bounded parallel validation.
- **`--no-interactive`**: accepted as a no-op wherever upstream defines it (the Rust port is already non-interactive), so scripts passing it don't error.
- **Fix: package-schema resolution** — stop resolving package schemas from the dev-only `vendor/OpenSpec/schemas` path; installed binaries SHALL resolve the embedded schema (and any project/user schemas), so `schema which`/`templates` report correct paths for end users.

**Out of scope (documented decisions, not gaps to fix here):**
- **`view`** interactive TUI dashboard — a large, different class of work (full-screen terminal UI) with low value for a scriptable CLI port; deferred to its own change if ever wanted.
- Deprecated noun command groups `spec <show|list|validate>` and `change <show|list|validate>`, and the deprecated `experimental` alias — upstream emits deprecation warnings for these; the Rust port exposes the verb-first equivalents (`show`, `validate`, `list`) already.

## Capabilities

### Modified Capabilities
- `cli-commands`: add `feedback`; `show` spec-filter flags; `new change` flags (`--json`/`--goal`/`--affected-areas`/`--initiative`/`--store`/`--store-path`); `validate --concurrency`; accept `--no-interactive` as a no-op; correct package-schema resolution for installed binaries.
- `config-management`: `config` gains the upstream subcommand surface (path/list/get/set/unset/reset/edit/profile) replacing the flat flags.

## Impact

- **Affected code**: `src/cli/args.rs` (clap surface for config/new/show/validate/feedback + global `--no-interactive`), `src/cli/config.rs` (subcommand rewrite), `src/cli/show.rs` (filter flags), `src/cli/new_change.rs` (flags + initiative link, reusing the initiatives resolution), `src/cli/validate.rs` (concurrency), a new `src/cli/feedback.rs`, and `src/core/schema.rs` (package-schema resolution).
- **Compatibility**: `config` changes are the one BREAKING surface change (flat `--set/--get/--list` → subcommands) — it aligns with upstream; document in CHANGELOG. Everything else is additive.
- **Reference**: upstream `vendor/OpenSpec/` at v1.4.1 (`commands/config.ts`, `commands/spec.ts` filters, `cli/index.ts` feedback/new/templates).
Loading