{"id":47607302,"url":"https://github.com/jkaloger/lazyspec","last_synced_at":"2026-04-01T19:35:30.502Z","repository":{"id":342215661,"uuid":"1172616873","full_name":"jkaloger/lazyspec","owner":"jkaloger","description":"A little TUI for project documentation. ","archived":false,"fork":false,"pushed_at":"2026-03-28T06:05:25.000Z","size":1779,"stargazers_count":6,"open_issues_count":3,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-03-28T11:15:20.026Z","etag":null,"topics":["ai","cli","sdd","spec-driven","tui"],"latest_commit_sha":null,"homepage":"","language":"Rust","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/jkaloger.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-03-04T14:09:08.000Z","updated_at":"2026-03-27T01:30:50.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/jkaloger/lazyspec","commit_stats":null,"previous_names":["jkaloger/lazyspec"],"tags_count":6,"template":false,"template_full_name":null,"purl":"pkg:github/jkaloger/lazyspec","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jkaloger%2Flazyspec","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jkaloger%2Flazyspec/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jkaloger%2Flazyspec/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jkaloger%2Flazyspec/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/jkaloger","download_url":"https://codeload.github.com/jkaloger/lazyspec/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jkaloger%2Flazyspec/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":31291151,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-01T13:12:26.723Z","status":"ssl_error","status_checked_at":"2026-04-01T13:12:25.102Z","response_time":53,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["ai","cli","sdd","spec-driven","tui"],"created_at":"2026-04-01T19:35:30.031Z","updated_at":"2026-04-01T19:35:30.494Z","avatar_url":"https://github.com/jkaloger.png","language":"Rust","funding_links":[],"categories":[],"sub_categories":[],"readme":"\u003ch1 align=\"center\"\u003e\n  🤖\n  \u003cbr\u003elazyspec\n\u003c/h1\u003e\n\u003cp align=\"center\"\u003e\n    A little TUI \u0026 CLI for project documentation.\n\u003c/p\u003e\n\n\u003cp align=\"center\"\u003e\n  \u003ca href=\"https://github.com/jkaloger/lazyspec/actions/workflows/ci.yml\"\u003e\u003cimg src=\"https://github.com/jkaloger/lazyspec/actions/workflows/ci.yml/badge.svg?branch=main\" alt=\"CI\"\u003e\u003c/a\u003e\n  \u003cimg src=\"https://img.shields.io/badge/rust-2021-orange?logo=rust\u0026logoColor=white\" alt=\"Rust 2021\"\u003e\n  \u003cimg src=\"https://img.shields.io/badge/status-experimental-blueviolet\" alt=\"Status: Experimental\"\u003e\n  \u003cimg src=\"https://img.shields.io/github/v/tag/jkaloger/lazyspec?label=version\u0026color=blue\" alt=\"Version\"\u003e\n  \u003ca href=\"https://github.com/jkaloger/lazyspec/commits/main\"\u003e\u003cimg src=\"https://img.shields.io/github/last-commit/jkaloger/lazyspec?logo=git\u0026logoColor=white\" alt=\"Last commit\"\u003e\u003c/a\u003e\n  \u003ca href=\"https://github.com/jkaloger/lazyspec/blob/main/flake.nix\"\u003e\u003cimg src=\"https://img.shields.io/badge/nix-flake-5277C3?logo=nixos\u0026logoColor=white\" alt=\"Nix Flake\"\u003e\u003c/a\u003e\n\u003c/p\u003e\n\n\u003cimg width=\"1864\" height=\"1147\" alt=\"screenshot of a terminal interface displaying codebase documentation, categorised by type\" src=\"https://github.com/user-attachments/assets/91f308d1-8d03-4815-b2ec-fa445159c563\" /\u003e\n\n\u003e [!WARNING]\n\u003e Lazyspec is experimental. APIs and CLI interfaces will change frequently and without notice.\n\n## Features\n\nLazyspec manages project documentation as version-controlled markdown files with YAML frontmatter. Documents live in your repo, so agents and humans read from the same source of truth.\n\n- Create, update, link, and validate documents. Typed relationships (`implements`, `supersedes`, `blocks`, `related-to`) keep the chain explicit.\n- Catch broken links, orphaned documents, and incomplete frontmatter before they rot. `lazyspec validate` exits non-zero on errors, so it slots into CI.\n- Embed `@ref` directives in your specs to point at source code. Lazyspec expands them inline using `git show`, with symbol-level extraction for Rust and TypeScript.\n- Fuzzy search, markdown preview, live file watching, and document creation without leaving the terminal.\n- Every command supports `--json` output for automation and agent integration.\n- Define your own types, templates, and directory layout in `.lazyspec.toml`.\n\n## Install\n\n### Nix\n\n```sh\nnix profile install github:jkaloger/lazyspec\n```\n\nOr run without installing:\n\n```sh\nnix run github:jkaloger/lazyspec\n```\n\n### Cargo\n\n```sh\ncargo install --git https://github.com/jkaloger/lazyspec\n```\n\n### From Source\n\n```sh\ngit clone https://github.com/jkaloger/lazyspec\ncd lazyspec\ncargo install --path .\n```\n\n### Shell Completions\n\nGenerate and source a completion script for your shell:\n\n```sh\n# zsh\nsource \u003c(lazyspec completions zsh)\n\n# bash\nsource \u003c(lazyspec completions bash)\n\n# fish\nlazyspec completions fish | source\n```\n\nAdd the appropriate line to your shell profile (`~/.zshrc`, `~/.bashrc`, etc.) to load completions on startup. Completions include subcommands, flags, document IDs, and relationship types.\n\n## Skills\n\nLazyspec includes a set of agent skills that enforce its workflow:\n\n| Skill              | Purpose                                                              |\n| ------------------ | -------------------------------------------------------------------- |\n| `plan-work`        | Detect existing artifacts and determine the right entry point       |\n| `write-rfc`        | Propose a design with intent, interface sketches, and identify stories |\n| `create-story`     | Create stories with acceptance criteria linked to an RFC             |\n| `resolve-context`  | Gather full document chain (RFC -\u003e Story -\u003e Iteration) before work  |\n| `create-iteration` | Plan an iteration with task breakdown and test plan                 |\n| `build`            | Implement tasks from an iteration with subagent dispatch             |\n| `review-iteration` | Two-stage review -- AC compliance first, then code quality           |\n| `create-audit`     | Criteria-based review (health check, security, accessibility, etc.)  |\n\n\n## Usage\n\n### Quick Start\n\nInitialise a new project, then launch the TUI:\n\n```sh\nlazyspec init\nlazyspec\n```\n\n\u003e [!TIP]\n\u003e Check the `examples/` directory for a complete project setup including config, templates, and agent skill definitions you can use as a starting point.\n\u003e This repo dogfoods lazyspec, so you can also check out the `docs/` directory or run `lazyspec` from this repo.\n\n### TUI\n\nRunning `lazyspec` with no subcommand opens the interactive dashboard. It provides fuzzy search, markdown preview, document creation, and live file watching -- documents update automatically when changed on disk.\n\n\u003cdetails\u003e\n\u003csummary\u003e\u003ch3\u003eCLI\u003c/h3\u003e\u003c/summary\u003e\n\nAll document management is available as subcommands. Most accept `--json` for machine-readable output.\n\n| Command                              | Description                                                           |\n| ------------------------------------ | --------------------------------------------------------------------- |\n| `init`                               | Initialise lazyspec in the current project                            |\n| `create \u003ctype\u003e \u003ctitle\u003e [--author X]` | Create a document (rfc, adr, story, iteration)                        |\n| `list [type] [--status X]`           | List documents with optional filters                                  |\n| `show \u003cid\u003e [-e]`                     | Display a document by path or shorthand ID (e.g. `RFC-001`)           |\n| `update \u003cpath\u003e --status X --title X` | Update document frontmatter                                           |\n| `delete \u003cpath\u003e`                      | Delete a document                                                     |\n| `link \u003cfrom\u003e \u003crel\u003e \u003cto\u003e`             | Add a typed relationship (implements, supersedes, blocks, related-to) |\n| `unlink \u003cfrom\u003e \u003crel\u003e \u003cto\u003e`           | Remove a relationship between documents                               |\n| `search \u003cquery\u003e [--doc-type X]`      | Full-text search across all documents                                 |\n| `context \u003cid\u003e`                       | Show the full document chain (RFC -\u003e Story -\u003e Iteration)              |\n| `status`                             | Show full project status with all documents and validation            |\n| `ignore \u003cpath\u003e`                      | Mark a document to skip validation                                    |\n| `unignore \u003cpath\u003e`                    | Remove validation skip from a document                                |\n| `validate [--warnings]`              | Check document integrity and link consistency                         |\n| `fix [paths] [--dry-run]`            | Fix documents with broken or incomplete frontmatter                   |\n| `pin \u003cid\u003e`                           | Pin blob hashes onto `@ref` directives in a document                  |\n| `reservations list`                  | Show all reservation refs on the remote                               |\n| `reservations prune [--dry-run]`     | Remove refs for documents that already exist locally                  |\n\n#### `show` Flags\n\n| Flag                        | Description                                      |\n| --------------------------- | ------------------------------------------------ |\n| `-e`, `--expand-references` | Expand `@ref` directives into fenced code blocks |\n| `--max-ref-lines N`         | Max lines per expanded ref (default: 25)         |\n\n\u003c/details\u003e\n\n\u003cdetails\u003e\n\u003csummary\u003e\u003ch3\u003e\u003ccode\u003e@ref\u003c/code\u003e Syntax\u003c/h3\u003e\u003c/summary\u003e\n\nDocuments can embed references to source code using `@ref` directives. By default, `lazyspec show` renders them as-is. Pass `-e` to expand them inline.\n\n```\n@ref \u003cpath\u003e                    # entire file\n@ref \u003cpath\u003e#\u003csymbol\u003e           # specific type or struct\n@ref \u003cpath\u003e#\u003csymbol\u003e@\u003csha\u003e     # symbol at a specific git commit\n@ref \u003cpath\u003e#123                # line 123\n@ref \u003cpath\u003e#123@\u003csha\u003e          # line 123 at a specific git commit\n```\n\nExpansion resolves content via `git show` (committed state, not working tree). Supported languages for symbol extraction are TypeScript (`.ts`/`.tsx`) and Rust (`.rs`).\n\nEach expanded ref includes a caption line showing the file path, short git SHA, and symbol or line info. Expanded blocks are truncated to 25 lines by default; when truncated, a trailing comment shows how many lines were omitted. Use `--max-ref-lines` to adjust the limit.\n\n**Example**\n\nA document containing:\n\n```\n@ref src/engine/store.rs#Store\n```\n\nRenders as:\n\n````\n```rust\npub struct Store { ... }\n```\n````\n\nUnresolvable refs render as:\n\n```\n\u003e [unresolved: src/engine/store.rs#Store]\n```\n\n\u003c/details\u003e\n\n\u003cdetails\u003e\n\u003csummary\u003e\u003ch2\u003eConfiguration\u003c/h2\u003e\u003c/summary\u003e\n\n`lazyspec init` creates a `.lazyspec.toml` in your project root with four built-in document types:\n\n```toml\n[directories]\nrfcs = \"docs/rfcs\"\nadrs = \"docs/adrs\"\nstories = \"docs/stories\"\niterations = \"docs/iterations\"\n\n[templates]\ndir = \".lazyspec/templates\"\n\n[naming]\npattern = \"{type}-{n:03}-{title}.md\"\n```\n\n### Custom Types\n\nInstead of `[directories]`, you can define types explicitly with `[[types]]`. This lets you rename the defaults, add new types, or set custom prefixes and icons used in the TUI.\n\n```toml\n[[types]]\nname = \"rfc\"\nplural = \"rfcs\"\ndir = \"docs/rfcs\"\nprefix = \"RFC\"\nicon = \"●\"\n\n[[types]]\nname = \"spec\"\nplural = \"specs\"\ndir = \"docs/specs\"\nprefix = \"SPEC\"\nicon = \"◆\"\n```\n\n### Validation Rules\n\nValidation rules define structural constraints between document types. Two shapes are supported:\n\n- `parent-child` -- the child type must link to a parent type via a given relationship.\n- `relation-existence` -- documents of a given type must have at least one relationship.\n\n```toml\n[[rules]]\nshape = \"parent-child\"\nname = \"stories-need-rfcs\"\nchild = \"story\"\nparent = \"rfc\"\nlink = \"implements\"\nseverity = \"warning\"\n\n[[rules]]\nshape = \"relation-existence\"\nname = \"adrs-need-relations\"\ntype = \"adr\"\nrequire = \"any-relation\"\nseverity = \"error\"\n```\n\n### Numbering\n\nDocument numbers are assigned automatically during `create`. Three strategies are available per type:\n\n| Strategy      | Behaviour |\n|---------------|-----------|\n| `incremental` | Next sequential integer from existing files (default) |\n| `sqids`       | Short hash-like IDs derived from a timestamp, configured via `[numbering.sqids]` |\n| `reserved`    | Reserves numbers on a git remote before creating files, preventing distributed collisions |\n\nReserved numbering uses git custom refs (`refs/reservations/*`) to coordinate across branches. It wraps either incremental or sqids formatting with an atomic push-based lock, so two people never get the same number.\n\n```toml\n[[types]]\nname = \"rfc\"\nprefix = \"RFC\"\nnumbering = \"reserved\"\n\n[numbering.reserved]\nremote = \"origin\"        # default\nformat = \"incremental\"   # or \"sqids\"\nmax_retries = 5          # push retry attempts before failing\n```\n\nIf the remote is unreachable, `create` fails rather than silently falling back. Use `lazyspec reservations prune` to clean up refs for documents that have been created.\n\n### Templates\n\nPlace markdown templates in the templates directory (`.lazyspec/templates/` by default). When creating a document, lazyspec uses the template matching the document type name (e.g. `rfc.md`, `story.md`).\n\n\u003c/details\u003e\n\n## Development\n\n### Nix (recommended)\n\nThe repo includes a Nix flake that provides the full toolchain. With [direnv](https://direnv.net/) installed:\n\n```sh\ndirenv allow\n```\n\nOr enter the dev shell manually:\n\n```sh\nnix develop\n```\n\nThis gives you cargo, clippy, rustfmt, and rust-analyzer at pinned versions.\n\nTo run all checks (clippy, tests, formatting):\n\n```sh\nnix flake check\n```\n\n### Without Nix\n\n```sh\ncargo build\ncargo test\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjkaloger%2Flazyspec","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fjkaloger%2Flazyspec","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjkaloger%2Flazyspec/lists"}