diff --git a/.claude/commands/spectr/apply.md b/.claude/commands/spectr/apply.md new file mode 100644 index 0000000..364d5e2 --- /dev/null +++ b/.claude/commands/spectr/apply.md @@ -0,0 +1,26 @@ +--- +description: Implement an approved Spectr change and keep tasks in sync. +--- + + + +**Guardrails** +- Favor straightforward, minimal implementations first and add complexity only when it is requested or clearly required. +- Keep changes tightly scoped to the requested outcome. +- Refer to `spectr/AGENTS.md` (located inside the `spectr/` directory—run `ls spectr` or `spectr init` if you don't see it) if you need additional Spectr conventions or clarifications. + +**Steps** +Track these steps as TODOs and complete them one by one. +1. Read `spectr/changes//proposal.md`, `design.md` (if present), and `tasks.md` to confirm scope and acceptance criteria. +2. Work through tasks sequentially, keeping edits minimal and focused on the requested change. +3. Confirm completion before updating statuses—make sure every item in `tasks.md` is finished. +4. Update the checklist after all work is done so each task is marked `- [x]` and reflects reality. +5. Reference `spectr list` when additional context is required. + +**Reference** +- Read `spectr/changes//proposal.md` for proposal details. +- Read `spectr/changes//specs//spec.md` for delta specs. + + + + diff --git a/.claude/commands/spectr/proposal.md b/.claude/commands/spectr/proposal.md new file mode 100644 index 0000000..d3f0d7c --- /dev/null +++ b/.claude/commands/spectr/proposal.md @@ -0,0 +1,30 @@ +--- +description: Scaffold a new Spectr change and validate strictly. +--- + + + +**Guardrails** +- Favor straightforward, minimal implementations first and add complexity only when it is requested or clearly required. +- Keep changes tightly scoped to the requested outcome. +- Refer to `spectr/AGENTS.md` (located inside the `spectr/` directory—run `ls spectr` or `spectr init` if you don't see it) if you need additional Spectr conventions or clarifications. +- Identify any vague or ambiguous details and ask the necessary follow-up questions before editing files. + +**Steps** +1. Review `spectr/project.md`, run `spectr list` and `spectr list --specs`, and inspect related code or docs (e.g., via `rg`/`ls`) to ground the proposal in current behaviour; note any gaps that require clarification. +2. Choose a unique verb-led `change-id` and scaffold `proposal.md`, `tasks.md`, and `design.md` (when needed) under `spectr/changes//`. +3. Map the change into concrete capabilities or requirements, breaking multi-scope efforts into distinct spec deltas with clear relationships and sequencing. +4. Capture architectural reasoning in `design.md` when the solution spans multiple systems, introduces new patterns, or demands trade-off discussion before committing to specs. +5. Draft spec deltas in `spectr/changes//specs//spec.md` (one folder per capability) using `## ADDED|MODIFIED|REMOVED Requirements` with at least one `#### Scenario:` per requirement and cross-reference related capabilities when relevant. +6. Draft `tasks.md` as an ordered list of small, verifiable work items that deliver user-visible progress, include validation (tests, tooling), and highlight dependencies or parallelizable work. +7. Validate with `spectr validate --strict` and resolve every issue before sharing the proposal. + +**Reference** +- Read delta specs directly at `spectr/changes//specs//spec.md` when validation fails. +- Read existing specs at `spectr/specs//spec.md` to understand current state. +- Search existing requirements with `rg -n "Requirement:|Scenario:" spectr/specs` before writing new ones. +- Explore the codebase with `rg `, `ls`, or direct file reads so proposals align with current implementation realities. + + + + diff --git a/.claude/commands/spectr/sync.md b/.claude/commands/spectr/sync.md new file mode 100644 index 0000000..100dc98 --- /dev/null +++ b/.claude/commands/spectr/sync.md @@ -0,0 +1,47 @@ +--- +description: Detect spec drift from code and update specs interactively. +--- + + + +### Guardrails +- Code is the source of truth—specs should reflect actual implementation. +- Only update specs after user confirms each change. +- Keep spec updates minimal and focused on actual drift. +- Create missing specs for new capabilities supported by the implementation. +- Refer to `spectr/AGENTS.md` for Spectr conventions. + +### Steps +1. Determine scope: + - If arguments specify capabilities (e.g., `auth, cli`), focus on those. + - Otherwise, ask the user which capabilities to sync, or analyze recent git changes to suggest candidates. + +2. Load current specs: + - Run `spectr list --specs` to enumerate capabilities. + - Read each relevant `spectr/specs//spec.md`. + +3. Analyze implementation: + - For each capability, identify related code (by directory name, imports, or user guidance). + - Read the implementation and understand actual behavior. + +4. Detect drift: + - Compare code behavior against spec requirements and scenarios. + - Identify: new features (to be ADDED), changed behavior (to be MODIFIED), removed features (to be REMOVED). + +5. Interactive review: + - For each drift item, present: the requirement, what code does, and proposed spec change. + - Ask user to confirm, modify, or skip each change. + +6. Apply updates: + - Edit specs directly with confirmed changes. + - Run `spectr validate --strict` to ensure validity. + - Show summary of changes made. + +### Reference +- Read `spectr/specs//spec.md` to view current spec content. +- Search code with `rg` to find implementations. +- Validate after edits with `spectr validate --strict`. + + + + diff --git a/CLAUDE.md b/CLAUDE.md new file mode 100644 index 0000000..33a8921 --- /dev/null +++ b/CLAUDE.md @@ -0,0 +1,16 @@ + +# Spectr Instructions + +These instructions are for AI assistants working in this project. + +Always open `@/spectr/AGENTS.md` when the request: +- Mentions planning or proposals (words like proposal, spec, change, plan) +- Introduces new capabilities, breaking changes, architecture shifts, or big performance/security work +- Sounds ambiguous and you need the authoritative spec before coding + +Use `@/spectr/AGENTS.md` to learn: +- How to create and apply change proposals +- Spec format and conventions +- Project structure and guidelines + + diff --git a/dictionary/markdown-claude.dict b/dictionary/markdown-claude.dict index 889b0b1..a0af179 100644 --- a/dictionary/markdown-claude.dict +++ b/dictionary/markdown-claude.dict @@ -1,3 +1,4 @@ -/openspec:proposal -/openspec:apply -/openspec:archive +/spectr:proposal +/spectr:apply +/spectr:archive +ULTRATHINK diff --git a/lua/plugins/big-file-plugin.lua b/lua/plugins/big-file-plugin.lua deleted file mode 100644 index 261ce17..0000000 --- a/lua/plugins/big-file-plugin.lua +++ /dev/null @@ -1,20 +0,0 @@ -return { - "LunarVim/bigfile.nvim", - event = "BufReadPre", - config = function() - require("bigfile").setup { - filesize = 2, -- size of the file in MiB, the plugin round file sizes to the closest MiB - pattern = { "*" }, -- autocmd pattern or function see <### Overriding the detection of big files> - features = { -- features to disable - "indent_blankline", - "illuminate", - "lsp", - "treesitter", - "syntax", - "matchparen", - "vimopts", - "filetype", - }, - } - end -} diff --git a/lua/plugins/lspconfig-plugin.lua b/lua/plugins/lspconfig-plugin.lua index 168f21f..c7937b7 100644 --- a/lua/plugins/lspconfig-plugin.lua +++ b/lua/plugins/lspconfig-plugin.lua @@ -29,6 +29,7 @@ return { servers = { -- phpactor = {}, -- volar = {}, + svelte_ls = {}, vue_ls = {}, -- harper_ls = { -- settings = { @@ -110,7 +111,16 @@ return { rust_analyzer = {}, texlab = {}, vhdl_ls = {}, - tailwindcss = {}, + tailwindcss = { + filetypes = { "templ", "astro", "javascript", "typescript", "react" }, + settings = { + tailwindCSS = { + includeLanguages = { + templ = "html", + }, + }, + }, + }, hdl_checker = {}, jsonls = {}, yamlls = {}, @@ -187,12 +197,15 @@ return { vim.lsp.buf.format, { buffer = args.buf, desc = '[C]ode [F]ormat' } ) - vim.keymap.set( - 'n', - 'ca', - vim.lsp.buf.code_action, - { buffer = args.buf, desc = '[C]ode [A]ction' } - ) + -- vim.keymap.set( + -- 'n', + -- 'ca', + -- vim.lsp.buf.code_action, + -- { buffer = args.buf, desc = '[C]ode [A]ction' } + -- ) + vim.keymap.set({ "n", "x" }, "ca", function() + require("tiny-code-action").code_action() + end, { noremap = true, silent = true }) vim.keymap.set( 'n', 'ls', diff --git a/lua/plugins/telescope-plugin.lua b/lua/plugins/telescope-plugin.lua index c6e87f3..3b7c135 100644 --- a/lua/plugins/telescope-plugin.lua +++ b/lua/plugins/telescope-plugin.lua @@ -1,7 +1,6 @@ return { 'nvim-telescope/telescope.nvim', - -- tag = '0.1.9', - ref = '84b9ba066d1860f7a586ce9cd732fd6c4f77d1d9', + tag = 'v0.2.0', event = 'BufWinEnter', dependencies = { 'nvim-telescope/telescope-media-files.nvim', diff --git a/lua/plugins/tiny-code-action-plugin.lua b/lua/plugins/tiny-code-action-plugin.lua new file mode 100644 index 0000000..c61c49d --- /dev/null +++ b/lua/plugins/tiny-code-action-plugin.lua @@ -0,0 +1,22 @@ +return { + "rachartier/tiny-code-action.nvim", + dependencies = { + { "nvim-lua/plenary.nvim" }, + + -- optional picker via telescope + { "nvim-telescope/telescope.nvim" }, + -- optional picker via fzf-lua + { "ibhagwan/fzf-lua" }, + -- .. or via snacks + { + "folke/snacks.nvim", + opts = { + terminal = {}, + } + } + }, + event = "LspAttach", + opts = { + picker = "buffer", + }, +} diff --git a/lua/plugins/tree-sitter-plugin.lua b/lua/plugins/tree-sitter-plugin.lua index 6498d79..9ebb395 100644 --- a/lua/plugins/tree-sitter-plugin.lua +++ b/lua/plugins/tree-sitter-plugin.lua @@ -1,7 +1,8 @@ return { "nvim-treesitter/nvim-treesitter", version = false, - branch = "main", + -- branch = "main", + rev = "00c906abb9550e72bc0c640545b5499b9525bb40", build = ":TSUpdate", event = { "BufReadPost", "BufNewFile" }, dependencies = { @@ -16,41 +17,37 @@ return { vim.g.load_textobjects = true end, }, - -- { - -- "nvim-treesitter/nvim-treesitter-context", - -- config = function() - -- require("treesitter-context").setup { - -- -- Enable this plugin (Can be enabled/disabled later via commands) - -- enable = true, - -- -- Enable multiwindow support. - -- multiwindow = false, - -- -- How many lines the window should span. Values <= 0 mean no limit. - -- max_lines = 8, - -- -- Minimum editor window height to enable context. Values <= 0 mean no limit. - -- min_window_height = 0, - -- line_numbers = true, - -- -- Maximum number of lines to show for a single context - -- multiline_threshold = 20, - -- -- Which context lines to discard if `max_lines` is exceeded. Choices: 'inner', 'outer' - -- trim_scope = 'outer', - -- mode = 'cursor', -- Line used to calculate context. Choices: 'cursor', 'topline' - -- -- Separator between context and content. Should be a single character string, like '-'. - -- -- When separator is set, the context will only show up when there are at least 2 lines above cursorline. - -- separator = nil, - -- -- The Z-index of the context window - -- zindex = 20, - -- -- (fun(buf: integer): boolean) return false to disable attaching - -- on_attach = nil, - -- } - -- end, - -- }, + { + "nvim-treesitter/nvim-treesitter-context", + config = function() + require("treesitter-context").setup { + -- Enable this plugin (Can be enabled/disabled later via commands) + enable = true, + -- Enable multiwindow support. + multiwindow = false, + -- How many lines the window should span. Values <= 0 mean no limit. + max_lines = 8, + -- Minimum editor window height to enable context. Values <= 0 mean no limit. + min_window_height = 0, + line_numbers = true, + -- Maximum number of lines to show for a single context + multiline_threshold = 20, + -- Which context lines to discard if `max_lines` is exceeded. Choices: 'inner', 'outer' + trim_scope = 'outer', + mode = 'cursor', -- Line used to calculate context. Choices: 'cursor', 'topline' + -- Separator between context and content. Should be a single character string, like '-'. + -- When separator is set, the context will only show up when there are at least 2 lines above cursorline. + separator = nil, + -- The Z-index of the context window + zindex = 20, + -- (fun(buf: integer): boolean) return false to disable attaching + on_attach = nil, + } + end, + }, -- { 'nvim-treesitter/playground' } }, cmd = { "TSUpdateSync" }, - keys = { - { "", desc = "Increment selection" }, - { "", desc = "Decrement selection", mode = "x" }, - }, opts = { auto_install = true, ensure_installed = { @@ -115,7 +112,18 @@ return { }, highlight = { enable = true, - additional_vim_regex_highlighting = { "markdown" }, + disable = function(lang, buf) + if lang == "rustsdf" then + return true + end + local max_filesize = 100 * 1024 -- 100 KB + local ok, stats = pcall(vim.loop.fs_stat, vim.api.nvim_buf_get_name(buf)) + if ok and stats and stats.size > max_filesize then + return true + end + end, + -- additional_vim_regex_highlighting = { "markdown" }, + additional_vim_regex_highlighting = false, }, indent = { enable = true, diff --git a/spectr/AGENTS.md b/spectr/AGENTS.md new file mode 100644 index 0000000..e3cb295 --- /dev/null +++ b/spectr/AGENTS.md @@ -0,0 +1,451 @@ +# Spectr Instructions + +Instructions for AI coding assistants using Spectr for spec-driven development. + +## TL;DR Quick Checklist + +- Search existing work: `spectr spec list --long`, `spectr list` (use `rg` only for full-text search) +- Decide scope: new capability vs modify existing capability +- Pick a unique `change-id`: kebab-case, verb-led (`add-`, `update-`, `remove-`, `refactor-`) +- Scaffold: `proposal.md`, `tasks.md`, `design.md` (only if needed), and delta specs per affected capability +- Write deltas: use `## ADDED|MODIFIED|REMOVED|RENAMED Requirements`; include at least one `#### Scenario:` per requirement +- Validate: `spectr validate [change-id] --strict` and fix issues +- Request approval: Do not start implementation until proposal is approved + +## Three-Stage Workflow + +### Stage 1: Creating Changes +Create proposal when you need to: +- Add features or functionality +- Make breaking changes (API, schema) +- Change architecture or patterns +- Optimize performance (changes behavior) +- Update security patterns + +Loose matching guidance: +- Contains one of: `proposal`, `change`, `spec` +- With one of: `create`, `plan`, `make`, `start`, `help` + +Skip proposal for: +- Bug fixes (restore intended behavior) +- Typos, formatting, comments +- Dependency updates (non-breaking) +- Configuration changes +- Tests for existing behavior + +Workflow: +1. Review `spectr/project.md`, `spectr list`, and `spectr list --specs` to understand current context. +2. Choose a unique verb-led `change-id` and scaffold `proposal.md`, `tasks.md`, optional `design.md`, and spec deltas under `spectr/changes//`. +3. Draft spec deltas using `## ADDED|MODIFIED|REMOVED Requirements` with at least one `#### Scenario:` per requirement. +4. Run `spectr validate --strict` and resolve any issues before sharing the proposal. + +### Stage 2: Implementing Changes +Track these steps as TODOs and complete them one by one. +1. Read proposal.md - Understand what's being built +2. Read design.md (if exists) - Review technical decisions +3. Read tasks.md - Get implementation checklist +4. Implement tasks sequentially - Complete in order +5. Confirm completion - Ensure every item in `tasks.md` is finished before updating statuses +6. Update checklist - After all work is done, set every task to `- [x]` so the list reflects reality +7. Approval gate - Do not start implementation until the proposal is reviewed and approved + +### Stage 3: Syncing + +When code implementation diverges from specs, sync to update specs: +1. Compare code behavior against spec requirements +2. Identify drift: new features (ADDED), changed behavior (MODIFIED), removed features (REMOVED) +3. Review each change interactively before applying +4. Edit specs directly with confirmed changes +5. Create new change proposals for undocumented code changes +6. Run `spectr validate --strict` to ensure validity + +## Before Any Task + +Context Checklist: +- [ ] Read relevant specs in `specs/[capability]/spec.md` +- [ ] Check pending changes in `changes/` for conflicts +- [ ] Read `spectr/project.md` for conventions +- [ ] Run `spectr list` to see active changes +- [ ] Run `spectr list --specs` to see existing capabilities + +Before Creating Specs: +- Always check if capability already exists +- Prefer modifying existing specs over creating duplicates +- Read `spectr/specs//spec.md` directly to review current state +- If request is ambiguous, ask 1–2 clarifying questions before scaffolding + +### Search Guidance +- Enumerate specs: `spectr spec list --long` (or `--json` for scripts) +- Enumerate changes: `spectr list` (or `spectr change list --json` - deprecated but available) +- Read details directly: + - Spec: Read `spectr/specs//spec.md` + - Change: Read `spectr/changes//proposal.md` +- Full-text search (use ripgrep): `rg -n "Requirement:|Scenario:" spectr/specs` + +## Quick Start + +### CLI Commands + +```bash +# Essential commands +spectr list # List active changes +spectr list --specs # List specifications +spectr validate [item] # Validate changes or specs + +# Project management +spectr init [path] # Initialize or update instruction files + +# Interactive mode +spectr validate # Bulk validation mode + +# Debugging +spectr validate [change] --strict +``` + +Reading Specs and Changes (for AI agents): +- Specs: Read `spectr/specs//spec.md` directly +- Changes: Read `spectr/changes//proposal.md` directly +- Tasks: Read `spectr/changes//tasks.md` directly + +### Command Flags + +- `--json` - Machine-readable output +- `--type change|spec` - Disambiguate items +- `--strict` - Comprehensive validation +- `--no-interactive` - Disable prompts + +## Directory Structure + +``` +spectr/ +├── project.md # Project conventions +├── specs/ # Current truth - what IS built +│ └── [capability]/ # Single focused capability +│ ├── spec.md # Requirements and scenarios +│ └── design.md # Technical patterns +├── changes/ # Proposals - what SHOULD change +│ ├── [change-name]/ +│ │ ├── proposal.md # Why, what, impact +│ │ ├── tasks.md # Implementation checklist +│ │ ├── design.md # Technical decisions (optional; see criteria) +│ │ └── specs/ # Delta changes +│ │ └── [capability]/ +│ │ └── spec.md # ADDED/MODIFIED/REMOVED +│ └── archive/ # Completed changes +``` + +## Creating Change Proposals + +### Decision Tree + +``` +New request? +├─ Bug fix restoring spec behavior? → Fix directly +├─ Typo/format/comment? → Fix directly +├─ New feature/capability? → Create proposal +├─ Breaking change? → Create proposal +├─ Architecture change? → Create proposal +└─ Unclear? → Create proposal (safer) +``` + +### Proposal Structure + +1. Create directory: `changes/[change-id]/` (kebab-case, verb-led, unique) + +2. Write proposal.md: +```markdown +# Change: [Brief description of change] + +## Why +[1-2 sentences on problem/opportunity] + +## What Changes +- [Bullet list of changes] +- [Mark breaking changes with BREAKING] + +## Impact +- Affected specs: [list capabilities] +- Affected code: [key files/systems] +``` + +3. Create spec deltas: `specs/[capability]/spec.md` +```markdown +## ADDED Requirements +### Requirement: New Feature +The system SHALL provide... + +#### Scenario: Success case +- WHEN user performs action +- THEN expected result + +## MODIFIED Requirements +### Requirement: Existing Feature +[Complete modified requirement] + +## REMOVED Requirements +### Requirement: Old Feature +Reason: [Why removing] +Migration: [How to handle] +``` +If multiple capabilities are affected, create multiple delta files under `changes/[change-id]/specs//spec.md`—one per capability. + +4. Create tasks.md: +```markdown +## 1. Implementation +- [ ] 1.1 Create database schema +- [ ] 1.2 Implement API endpoint +- [ ] 1.3 Add frontend component +- [ ] 1.4 Write tests +``` + +5. Create design.md when needed: +Create `design.md` if any of the following apply; otherwise omit it: +- Cross-cutting change (multiple services/modules) or a new architectural pattern +- New external dependency or significant data model changes +- Security, performance, or migration complexity +- Ambiguity that benefits from technical decisions before coding + +Minimal `design.md` skeleton: +```markdown +## Context +[Background, constraints, stakeholders] + +## Goals / Non-Goals +- Goals: [...] +- Non-Goals: [...] + +## Decisions +- Decision: [What and why] +- Alternatives considered: [Options + rationale] + +## Risks / Trade-offs +- [Risk] → Mitigation + +## Migration Plan +[Steps, rollback] + +## Open Questions +- [...] +``` + +## Spec File Format + +### Critical: Scenario Formatting + +CORRECT (use #### headers): +```markdown +#### Scenario: User login success +- WHEN valid credentials provided +- THEN return JWT token +``` + +WRONG (don't use bullets or bold): +```markdown +- Scenario: User login ❌ +Scenario: User login ❌ +### Scenario: User login ❌ +``` + +Every requirement MUST have at least one scenario. + +### Requirement Wording +- Use SHALL/MUST for normative requirements (avoid should/may unless intentionally non-normative) + +### Delta Operations + +- `## ADDED Requirements` - New capabilities +- `## MODIFIED Requirements` - Changed behavior +- `## REMOVED Requirements` - Deprecated features +- `## RENAMED Requirements` - Name changes + +Headers matched with `trim(header)` - whitespace ignored. + +#### When to use ADDED vs MODIFIED +- ADDED: Introduces a new capability or sub-capability that can stand alone as a requirement. Prefer ADDED when the change is orthogonal (e.g., adding "Slash Command Configuration") rather than altering the semantics of an existing requirement. +- MODIFIED: Changes the behavior, scope, or acceptance criteria of an existing requirement. Always paste the full, updated requirement content (header + all scenarios). The archiver will replace the entire requirement with what you provide here; partial deltas will drop previous details. +- RENAMED: Use when only the name changes. If you also change behavior, use RENAMED (name) plus MODIFIED (content) referencing the new name. + +Common pitfall: Using MODIFIED to add a new concern without including the previous text. This causes loss of detail at archive time. If you aren't explicitly changing the existing requirement, add a new requirement under ADDED instead. + +Authoring a MODIFIED requirement correctly: +1) Locate the existing requirement in `spectr/specs//spec.md`. +2) Copy the entire requirement block (from `### Requirement: ...` through its scenarios). +3) Paste it under `## MODIFIED Requirements` and edit to reflect the new behavior. +4) Ensure the header text matches exactly (whitespace-insensitive) and keep at least one `#### Scenario:`. + +Example for RENAMED: +```markdown +## RENAMED Requirements +- FROM: `### Requirement: Login` +- TO: `### Requirement: User Authentication` +``` + +## Troubleshooting + +### Common Errors + +"Change must have at least one delta" +- Check `changes/[name]/specs/` exists with .md files +- Verify files have operation prefixes (## ADDED Requirements) + +"Requirement must have at least one scenario" +- Check scenarios use `#### Scenario:` format (4 hashtags) +- Don't use bullet points or bold for scenario headers + +Silent scenario parsing failures +- Exact format required: `#### Scenario: Name` +- Debug by reading the delta spec file directly: `spectr/changes//specs//spec.md` + +### Validation Tips + +```bash +# Always use strict mode for comprehensive checks +spectr validate [change] --strict +``` + +For validation debugging: +- Read delta specs directly: `spectr/changes//specs//spec.md` +- Check spec content by reading: `spectr/specs//spec.md` + +## Happy Path Script + +```bash +# 1) Explore current state +spectr spec list --long +spectr list +# Optional full-text search: +# rg -n "Requirement:|Scenario:" spectr/specs +# rg -n "^#|Requirement:" spectr/changes + +# 2) Choose change id and scaffold +CHANGE=add-two-factor-auth +mkdir -p spectr/changes/$CHANGE/{specs/auth} +printf "## Why\\n...\\n\\n## What Changes\\n- ...\\n\\n## Impact\\n- ...\\n" > spectr/changes/$CHANGE/proposal.md +printf "## 1. Implementation\\n- [ ] 1.1 ...\\n" > spectr/changes/$CHANGE/tasks.md + +# 3) Add deltas (example) +cat > spectr/changes/$CHANGE/specs/auth/spec.md << 'EOF' +## ADDED Requirements +### Requirement: Two-Factor Authentication +Users MUST provide a second factor during login. + +#### Scenario: OTP required +- WHEN valid credentials are provided +- THEN an OTP challenge is required +EOF + +# 4) Validate +spectr validate $CHANGE --strict +``` + +## Multi-Capability Example + +``` +spectr/changes/add-2fa-notify/ +├── proposal.md +├── tasks.md +└── specs/ + ├── auth/ + │ └── spec.md # ADDED: Two-Factor Authentication + └── notifications/ + └── spec.md # ADDED: OTP email notification +``` + +auth/spec.md +```markdown +## ADDED Requirements +### Requirement: Two-Factor Authentication +... +``` + +notifications/spec.md +```markdown +## ADDED Requirements +### Requirement: OTP Email Notification +... +``` + +## Best Practices + +### Simplicity First +- Default to <100 lines of new code +- Single-file implementations until proven insufficient +- Avoid frameworks without clear justification +- Choose boring, proven patterns + +### Complexity Triggers +Only add complexity with: +- Performance data showing current solution too slow +- Concrete scale requirements (>1000 users, >100MB data) +- Multiple proven use cases requiring abstraction + +### Clear References +- Use `file.ts:42` format for code locations +- Reference specs as `specs/auth/spec.md` +- Link related changes and PRs + +### Capability Naming +- Use verb-noun: `user-auth`, `payment-capture` +- Single purpose per capability +- 10-minute understandability rule +- Split if description needs "AND" + +### Change ID Naming +- Use kebab-case, short and descriptive: `add-two-factor-auth` +- Prefer verb-led prefixes: `add-`, `update-`, `remove-`, `refactor-` +- Ensure uniqueness; if taken, append `-2`, `-3`, etc. + +## Tool Selection Guide + +| Task | Tool | Why | +|------|------|-----| +| Find files by pattern | Glob | Fast pattern matching | +| Search code content | Grep | Optimized regex search | +| Read specific files | Read | Direct file access | +| Explore unknown scope | Task | Multi-step investigation | + +## Error Recovery + +### Change Conflicts +1. Run `spectr list` to see active changes +2. Check for overlapping specs +3. Coordinate with change owners +4. Consider combining proposals + +### Validation Failures +1. Run with `--strict` flag +2. Check JSON output for details +3. Verify spec file format +4. Ensure scenarios properly formatted + +### Missing Context +1. Read project.md first +2. Check related specs +3. Review recent archives +4. Ask for clarification + +## Quick Reference + +### Stage Indicators +- `changes/` - Proposed, not yet built +- `specs/` - Built and deployed +- `archive/` - Completed changes + +### File Purposes +- `proposal.md` - Why and what +- `tasks.md` - Implementation steps +- `spec.md` - Requirements and behavior +- `design.md` - Technical decisions (optional) + +### CLI Essentials +```bash +spectr list # What's in progress? +spectr validate --strict # Is it correct? +spectr archive [--yes|-y] # Mark complete (add --yes for automation) +``` + +Reading Details (for AI agents): +- Read `spectr/specs//spec.md` for spec details +- Read `spectr/changes//proposal.md` for change details + +Remember: Specs are truth. Changes are proposals. Keep them in sync. diff --git a/spectr/project.md b/spectr/project.md new file mode 100644 index 0000000..b472ef9 --- /dev/null +++ b/spectr/project.md @@ -0,0 +1,63 @@ +# nvim Context + +## Purpose +Personal daily driver neovim configuration for polyglot development. Optimized for working across 30+ programming languages including Go, Rust, Python, TypeScript, Nix, C/C++, Zig, and many others. + +## Tech Stack +- **Neovim** - Editor (Lua-based configuration) +- **lazy.nvim** - Plugin management with lazy loading +- **nvim-lspconfig** - LSP client configuration for language servers +- **blink.cmp** - Completion engine +- **Tree-sitter** - Syntax highlighting and code analysis +- **Telescope** - Fuzzy finding and navigation +- **neotest** - Testing framework integration +- **Git integrations**: fugitive, gitsigns, signify, octo (GitHub) +- **oil.nvim** - File navigation +- **fidget.nvim** - LSP progress notifications + +## Project Conventions + +### Code Style +- **Formatter**: StyLua +- **Indentation**: Tabs (width: 2) +- **Column width**: 160 characters +- **Line endings**: Unix (LF) +- **Quote style**: Double quotes preferred +- **Leader key**: `\` (backslash) +- **Local leader**: `` + +### Architecture Patterns +- **Plugin files**: Named as `-plugin.lua` in `lua/plugins/` +- **Keymaps**: Organized by mode in `lua/keymaps/` (normal, visual, insert) +- **Core config**: `lua/conneroisu/` for options, debugger, keymaps, multigrep +- **Filetype overrides**: `after/ftplugin/` for language-specific settings +- **Lazy loading**: Plugins load on events (BufReadPost, BufNewFile) or filetypes + +### Testing Strategy +- Manual testing in neovim after changes +- `:checkhealth` for plugin/LSP diagnostics +- CI validation on push + +### Git Workflow +- **Trunk-based development**: Short-lived branches, frequent integration to main +- Commit messages should be descriptive +- Changes validated before merge + +## Domain Context +- This config is part of a larger NixOS dotfiles repository using the Denix framework +- LSP servers are typically installed via Nix, not Mason +- Format-on-save is enabled for most filetypes (Go uses vim-go instead) +- Custom filetypes registered: `templ`, `rasi`, `hyprlang` + +## Important Constraints +- **Performance focus**: Startup time and responsiveness are priorities +- **NixOS integration**: Managed via Home Manager; external tools come from Nix +- **Lazy loading**: Plugins should load lazily to minimize startup time +- **No Mason**: LSP servers managed by Nix, not neovim plugin managers + +## External Dependencies +- **Nix/NixOS**: Provides LSP servers, formatters, and external tools +- **Language servers**: gopls, rust-analyzer, lua_ls, nixd, pyrefly, ts_ls, etc. +- **Git**: Required for fugitive, gitsigns, octo integrations +- **ripgrep**: Used by Telescope for grep operations +- **fd**: Used by Telescope for file finding