Skip to content
Merged
Show file tree
Hide file tree
Changes from 4 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/simplify-skill-installation/.openspec.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
schema: spec-driven
created: 2026-02-17
204 changes: 204 additions & 0 deletions openspec/changes/simplify-skill-installation/design.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,204 @@
## Context

OpenSpec currently installs 10 workflows (skills + commands) for every user, overwhelming new users. The init flow asks multiple questions (profile, delivery, tools) creating friction before users can experience value.

Current architecture:
- `src/core/init.ts` - Handles tool selection and skill/command generation
- `src/core/config.ts` - Defines `AI_TOOLS` with `skillsDir` mappings
- `src/core/shared/skill-generation.ts` - Generates skill files from templates
- `src/core/templates/workflows/*.ts` - Individual workflow templates
- `src/prompts/searchable-multi-select.ts` - Tool selection UI

Global config exists at `~/.config/openspec/config.json` for telemetry/feature flags. Profile/delivery settings will extend this existing config.

## Goals / Non-Goals

**Goals:**
- Get new users to "aha moment" in under 1 minute
- Zero-question init with sensible defaults (core profile, both delivery)
- Auto-detect installed tools from existing directories
- Introduce profile system (core/extended/custom) for workflow selection
- Introduce delivery config (skills/commands/both) as power-user setting
- Create new `propose` workflow combining `new` + `ff`
- Fix tool selection UX (space to select, enter to confirm)
- Maintain backwards compatibility for existing users

**Non-Goals:**
- Removing any existing workflows (all remain available in extended profile)
- Per-project profile/delivery settings (user-level only)
- Changing the artifact structure or schema system
- Modifying how skills/commands are formatted or written

## Decisions

### 1. Extend Existing Global Config

Add profile/delivery settings to existing `~/.config/openspec/config.json` (via `src/core/global-config.ts`).

**Rationale:** Global config already exists with XDG/APPDATA cross-platform path handling, schema evolution, and merge-with-defaults behavior. Reusing it avoids a second config file and leverages existing infrastructure.

**Schema extension:**
```json
{
"telemetry": { ... }, // existing
"featureFlags": { ... }, // existing
"profile": "core", // NEW
"delivery": "both", // NEW
"workflows": [...] // NEW (only for custom profile)
}
```

**Alternatives considered:**
- New `~/.openspec/config.yaml`: Creates second config file, different format, path confusion
- Project config: Would require syncing mechanism, users edit it directly
- Environment variables: Less discoverable, harder to persist

### 2. Profile System with Three Tiers

```
core (default): propose, explore, apply, archive (4)
extended: all 11 workflows
custom: user-defined subset
```

**Rationale:** Core covers the essential loop (propose → explore → apply → archive). Extended provides full control for power users. Custom allows fine-tuning.

**Alternatives considered:**
- Two tiers (simple/full): Less flexibility for users who want most but not all
- No profiles (always custom): More cognitive load, defeats simplification goal

### 3. Propose Workflow = New + FF Combined

Single workflow that creates a change and generates all artifacts in one step.

**Rationale:** Most users want to go from idea to implementation-ready. Separating `new` (creates folder) and `ff` (generates artifacts) adds unnecessary steps. Power users who want control can use `new` + `continue` from extended profile.

**Implementation:** New template in `src/core/templates/workflows/propose.ts` that:
1. Creates change directory via `openspec new change`
2. Runs artifact generation loop (like ff does)
3. Includes onboarding-style explanations in output

### 4. Auto-Detection with Confirmation

Scan for existing tool directories, pre-select detected tools, ask for confirmation.

**Rationale:** Reduces questions while still giving user control. Better than full auto (no confirmation) which might install unwanted tools, or no detection (always ask) which adds friction.

**Detection logic:**
```typescript
const TOOL_DIRS = {
'claude': '.claude',
'cursor': '.cursor',
'windsurf': '.windsurf',
// ... etc
};
// Scan cwd for existing directories, pre-select matches
```

### 5. Delivery as Config, Not Init Prompt

Delivery preference (skills/commands/both) stored in global config, defaulting to "both".

**Rationale:** Most users don't know or care about this distinction. Power users who have a preference can set it once via `openspec config set delivery skills`. Not worth asking during init.

### 6. Filesystem as Truth for Installed Workflows

What's installed in `.claude/skills/` (etc.) is the source of truth, not config.

**Rationale:**
- Backwards compatible with existing installs
- User can manually add/remove skill directories
- Config profile is a "template" for what to install, not a constraint

**Behavior:**
- `openspec init` installs profile workflows, doesn't remove extras
- `openspec init --apply-profile` syncs to profile (removes extras via SKILL_NAMES and COMMAND_IDS lookups)
- `openspec profile show` reads filesystem, shows what's actually installed
- `openspec profile install <workflow>` immediately generates files (not config-only)
- `openspec profile uninstall <workflow>` immediately removes files (not config-only)

### 6a. Profile Install/Uninstall = Immediate Filesystem Mutation

When user runs `profile install X`, files are generated immediately. No separate "apply" step.

**Rationale:** Users expect "install" to install. Config-only mutations with deferred application creates confusion where `profile install explore` succeeds but `profile show` shows nothing installed.

**Implementation:**
1. Update config to reflect new custom profile
2. Detect all configured tools in current project
3. Generate skill/command files for the workflow across all tools
4. Display confirmation with installed locations

### 6b. Safe Deletion via Constant Lookups

When removing workflows, only delete items in SKILL_NAMES and COMMAND_IDS constants.

**Rationale:** We generate known lists of skills and commands. Delete only what we created by checking against explicit lists, not pattern matching.

**Implementation:**
```typescript
// For skills - only delete if name is in our known list
if (SKILL_NAMES.includes(dirName)) {
// Safe to delete skill directory - we created it
}

// For commands - only delete if ID is in our known list
if (COMMAND_IDS.includes(commandId)) {
// Safe to delete command file - we created it
// Use tool adapter to resolve actual file path
}
```

**Constants:**
- `SKILL_NAMES`: Array of skill directory names (e.g., `openspec-explore`, `openspec-apply-change`)
- `COMMAND_IDS`: Array of command IDs (e.g., `explore`, `apply`, `new`)

### 8. Fix Multi-Select Keybindings
Comment thread
coderabbitai[bot] marked this conversation as resolved.
Outdated

Change from tab-to-confirm to industry-standard space/enter.

**Rationale:** Tab to confirm is non-standard and confuses users. Most CLI tools use space to toggle, enter to confirm.

**Implementation:** Modify `src/prompts/searchable-multi-select.ts` keybinding configuration.

## Risks / Trade-offs

**Risk: Breaking existing user workflows**
→ Mitigation: Filesystem is truth, existing installs untouched. Extended profile includes all current workflows.

**Risk: Propose workflow duplicates ff logic**
→ Mitigation: Extract shared artifact generation into reusable function, both `propose` and `ff` call it.

**Risk: Global config file management**
→ Mitigation: Create directory/file on first use. Handle missing file gracefully (use defaults).

**Risk: Auto-detection false positives**
→ Mitigation: Show detected tools and ask for confirmation, don't auto-install silently.

**Trade-off: Core profile has only 4 workflows**
→ Acceptable: These cover the main loop. Users who need more can `openspec profile set extended` or install individual workflows.

## Migration Plan

1. **Phase 1: Add infrastructure**
- Extend global-config.ts with profile/delivery/workflows fields
- Profile definitions and resolution
- Tool auto-detection

2. **Phase 2: Create propose workflow**
- New template combining new + ff
- Enhanced UX with explanatory output

3. **Phase 3: Update init flow**
- Zero-question default flow
- Auto-detect and confirm tools
- Respect profile/delivery settings

4. **Phase 4: Add profile/config commands**
- `openspec profile set/install/uninstall/list/show`
- `openspec config set/get/list`

5. **Phase 5: Fix multi-select UX**
- Update keybindings in searchable-multi-select

**Rollback:** All changes are additive. Existing behavior preserved via extended profile.
172 changes: 172 additions & 0 deletions openspec/changes/simplify-skill-installation/proposal.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,172 @@
## Why

Users have complained that there are too many skills/commands (currently 10) and new users feel overwhelmed. We want to simplify the default experience while preserving power-user capabilities and backwards compatibility.

The goal: **get users to an "aha moment" in under a minute**.

```text
0:00 $ openspec init
✓ Done. Run /opsx:propose "your idea"

0:15 /opsx:propose "add user authentication"

0:45 Agent creates proposal.md, design.md, tasks.md
"Whoa, it planned the whole thing for me" ← AHA

1:00 /opsx:apply
```

Additionally, users have different preferences for how workflows are delivered (skills vs commands vs both), but this should be a power-user configuration, not something new users think about.

## What Changes

### 1. Zero-Question Init

Init should just work with sensible defaults:

```text
$ openspec init

Detected: Claude Code, Cursor
Setting up OpenSpec...
✓ Done

Start your first change:
/opsx:propose "add dark mode"
```

**No prompts for profile or delivery.** Defaults are:
- Profile: core
- Delivery: both

Power users can customize later via `openspec profile` and `openspec config`.

### 2. Auto-Detect Tools

Init scans for existing tool directories (`.claude/`, `.cursor/`, etc.) and:
- If tools found: Shows detected tools, asks for confirmation
- If no tools found: Prompts for selection
- Non-interactive: Uses detected tools automatically, fails only if none detected

### 3. Fix Tool Selection UX

Current behavior confuses users:
- Tab to confirm (unexpected)

New behavior:
- **Space** to toggle selection
- **Enter** to confirm

### 4. Introduce Profiles

Profiles define which workflows to install:

- **core** (default): `propose`, `explore`, `apply`, `archive` (4 workflows)
- **extended**: All 11 workflows (existing 10 + new `propose`): `propose`, `explore`, `apply`, `archive`, `new`, `ff`, `continue`, `verify`, `sync`, `bulk-archive`, `onboard`
- **custom**: User-selected subset

The `propose` workflow is new - it combines `new` + `ff` into a single command that creates a change and generates all artifacts.

### 5. Improved Propose UX

`/opsx:propose` should naturally onboard users by explaining what it's doing:

```text
I'll create a change with 3 artifacts:
- proposal.md (what & why)
- design.md (how)
- tasks.md (implementation steps)

When ready to implement, run /opsx:apply
```
Comment on lines +73 to +86

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

Artifact count inconsistency: "all artifacts" vs "3 artifacts".

Line 68 states that propose "generates all artifacts", but the UX message at line 75 claims only 3 and omits specs/. Since propose = new + ff, and ff is the workflow that generates delta specs, specs/ should be a fourth artifact. The same omission appears in the "Why" timeline at line 13.

Either clarify that propose intentionally defers specs/ generation to /opsx:apply (and remove "all artifacts"), or add specs/ to both the count and the list.

✏️ Option A — if `propose` does generate specs
-I'll create a change with 3 artifacts:
+I'll create a change with 4 artifacts:
 - proposal.md (what & why)
 - design.md (how)
+- specs/ (delta specs)
 - tasks.md (implementation steps)
-0:45  Agent creates proposal.md, design.md, tasks.md
+0:45  Agent creates proposal.md, design.md, specs/, tasks.md
✏️ Option B — if specs/ is deferred to apply
-it combines `new` + `ff` into a single command that creates a change and generates all artifacts.
+it combines `new` + `ff` into a single command that creates a change and generates the planning artifacts (proposal.md, design.md, tasks.md); delta specs are produced during `/opsx:apply`.
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
The `propose` workflow is new - it combines `new` + `ff` into a single command that creates a change and generates all artifacts.
### 5. Improved Propose UX
`/opsx:propose` should naturally onboard users by explaining what it's doing:
```text
I'll create a change with 3 artifacts:
- proposal.md (what & why)
- design.md (how)
- tasks.md (implementation steps)
When ready to implement, run /opsx:apply
```
The `propose` workflow is new - it combines `new` + `ff` into a single command that creates a change and generates all artifacts.
### 5. Improved Propose UX
`/opsx:propose` should naturally onboard users by explaining what it's doing:
Suggested change
The `propose` workflow is new - it combines `new` + `ff` into a single command that creates a change and generates all artifacts.
### 5. Improved Propose UX
`/opsx:propose` should naturally onboard users by explaining what it's doing:
```text
I'll create a change with 3 artifacts:
- proposal.md (what & why)
- design.md (how)
- tasks.md (implementation steps)
When ready to implement, run /opsx:apply
```
The `propose` workflow is new - it combines `new` + `ff` into a single command that creates a change and generates the planning artifacts (proposal.md, design.md, tasks.md); delta specs are produced during `/opsx:apply`.
### 5. Improved Propose UX
`/opsx:propose` should naturally onboard users by explaining what it's doing:
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@openspec/changes/simplify-skill-installation/proposal.md` around lines 68 -
81, The UX text for the new propose workflow is inconsistent about which
artifacts it creates; update the /opsx:propose description and the "Why"
timeline so they match intent: either include specs/ in the list and change "3
artifacts" to "4 artifacts" (update the UX message that currently lists
proposal.md, design.md, tasks.md to also list specs/) if propose indeed runs
both new + ff, or explicitly remove "all artifacts" and change the UX message to
state that propose creates only proposal.md, design.md, tasks.md and that specs/
(delta specs) are generated later by /opsx:apply; ensure references to the
propose workflow and /opsx:apply remain consistent across the proposal.md
content.


This teaches as it goes - no separate onboarding needed for most users.

### 6. Introduce Delivery Config

Delivery controls how workflows are installed:

- **both** (default): Skills and commands
- **skills**: Skills only
- **commands**: Commands only

Stored in existing global config (`~/.config/openspec/config.json`). Not prompted during init.

### 7. New CLI Commands

```shell
# Profile management (what to install)
openspec profile set core
openspec profile set extended
openspec profile install explore # add one workflow
openspec profile uninstall verify # remove one workflow
openspec profile list # show available profiles
openspec profile show # show current installation

# Config management (how to install)
openspec config set delivery skills
openspec config set delivery both
openspec config get delivery
openspec config list
```
Comment on lines +110 to +128

@coderabbitai coderabbitai Bot Feb 18, 2026

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

Fenced code block at line 104 is still missing a language specifier (MD040).

The interactive picker example block has no language tag despite the prior round of MD040 fixes (which addressed lines 7, 27, 74, and 97).

✏️ Suggested fix
-```
+```text
 $ openspec config profile
 
 Delivery: [skills] [commands] [both]
 ...
🧰 Tools
🪛 markdownlint-cli2 (0.21.0)

[warning] 104-104: Fenced code blocks should have a language specified

(MD040, fenced-code-language)

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@openspec/changes/simplify-skill-installation/proposal.md` around lines 104 -
122, The fenced code block showing the interactive picker example (the block
that begins with "$ openspec config profile" and contains the "Delivery:
[skills] [commands] [both]" and workflow checklist) is missing a language
specifier; add a language tag (e.g., "text") to the opening fence so the block
becomes ```text and the content is treated as plain text for MD040 compliance.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

@coderabbitai stop suggesting this

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

@TabishB, understood! This suggestion is coming from the markdownlint-cli2 static analysis tool that's checking the PR.

If you'd like to stop seeing MD040 warnings, you can configure markdownlint to ignore this rule by:

  1. Adding a .markdownlint.yaml or .markdownlint.json file to your repository with:

    MD040: false
  2. Or adding a comment to disable it for specific blocks:

    <!-- markdownlint-disable MD040 -->

    your code block here

    <!-- markdownlint-enable MD040 -->
    

Alternatively, if you'd prefer I simply not mention MD040 violations in my reviews regardless of what the linter reports, I can add that as a learning for this project. Let me know which approach you prefer!


🧠 Learnings used
Learnt from: CR
Repo: Fission-AI/OpenSpec PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-11-25T01:08:02.839Z
Learning: Use `@/openspec/AGENTS.md` to learn how to create and apply change proposals, spec format and conventions, and project structure and guidelines


### 8. Backwards Compatibility

- Existing users with all workflows keep them (filesystem is truth)
- `openspec init` on existing projects refreshes without removing extras
- `openspec init --apply-profile` explicitly syncs to profile (removes extras)
- All existing commands remain available in extended profile

## Capabilities

### New Capabilities

- `profiles`: Support for workflow profiles (core, extended, custom)
- `delivery-config`: User preference for delivery method (skills, commands, both)
- `propose-workflow`: Combined workflow that creates change + generates all artifacts
- `user-config`: Extend existing global config with profile/delivery settings
- `available-tools`: Detect what AI tools the user has from existing directories

### Modified Capabilities

- `init`: Zero-question flow with auto-detection and sensible defaults
- `tool-selection-ux`: Space to select, Enter to confirm
- `skill-generation`: Conditional based on profile and delivery settings
- `command-generation`: Conditional based on profile and delivery settings

## Impact

### New Files
- `src/core/templates/workflows/propose.ts` - New propose workflow template
- `src/commands/profile.ts` - Profile management command
- `src/core/profiles.ts` - Profile definitions and logic
- `src/core/available-tools.ts` - Detect what AI tools user has from directories

### Modified Files
- `src/core/init.ts` - Zero-question flow, auto-detection, sensible defaults
- `src/core/config.ts` - Add profile and delivery types
- `src/core/global-config.ts` - Add profile, delivery, workflows fields to schema
- `src/core/shared/skill-generation.ts` - Filter by profile, respect delivery
- `src/core/shared/tool-detection.ts` - Update SKILL_NAMES and COMMAND_IDS to include propose
- `src/commands/config.ts` - Add delivery config commands
- `src/prompts/searchable-multi-select.ts` - Fix keybindings (space/enter)
Comment thread
coderabbitai[bot] marked this conversation as resolved.

### Global Config Schema Extension
```json
// ~/.config/openspec/config.json (extends existing)
{
"telemetry": { ... }, // existing
"featureFlags": { ... }, // existing
"profile": "core", // NEW: core | extended | custom
"delivery": "both", // NEW: both | skills | commands
"workflows": ["propose", ...] // NEW: only if profile: custom
}
```

## Profiles Reference

| Profile | Workflows | Description |
|---------|-----------|-------------|
| core | propose, explore, apply, archive | Streamlined flow for most users |
| extended | all 11 | Full control including new, ff, continue, verify, sync, bulk-archive, onboard |
| custom | user-defined | Pick exactly what you need |
Loading
Loading