diff --git a/.gitignore b/.gitignore index 5ecf229d..887f5a52 100644 --- a/.gitignore +++ b/.gitignore @@ -148,3 +148,7 @@ CLAUDE.md # Pnpm .pnpm-store/ + +# Nix +result +.direnv/ diff --git a/README.md b/README.md index 7b6c7354..7be2a37c 100644 --- a/README.md +++ b/README.md @@ -144,6 +144,21 @@ Verify installation: openspec --version ``` +
+Alternative: Install with Nix (click to expand) + +If you use [Nix](https://nixos.org/), you can run OpenSpec directly without global installation: + +```bash +# Run directly from the repository +nix run github:Fission-AI/OpenSpec -- --version + +# Or enter a development shell +nix develop github:Fission-AI/OpenSpec +``` + +
+ #### Step 2: Initialize OpenSpec in your project Navigate to your project directory: @@ -376,6 +391,8 @@ Run `openspec update` whenever someone switches tools so your agents pick up the - Develop CLI locally: `pnpm run dev` or `pnpm run dev:cli` - Conventional commits (one-line): `type(scope): subject` +**Nix users:** Run `nix develop` to enter a development shell with Node.js and pnpm pre-configured. + ## License MIT diff --git a/flake.lock b/flake.lock new file mode 100644 index 00000000..1dd47f9a --- /dev/null +++ b/flake.lock @@ -0,0 +1,61 @@ +{ + "nodes": { + "flake-utils": { + "inputs": { + "systems": "systems" + }, + "locked": { + "lastModified": 1731533236, + "narHash": "sha256-l0KFg5HjrsfsO/JpG+r7fRrqm12kzFHyUHqHCVpMMbI=", + "owner": "numtide", + "repo": "flake-utils", + "rev": "11707dc2f618dd54ca8739b309ec4fc024de578b", + "type": "github" + }, + "original": { + "owner": "numtide", + "repo": "flake-utils", + "type": "github" + } + }, + "nixpkgs": { + "locked": { + "lastModified": 1766736597, + "narHash": "sha256-BASnpCLodmgiVn0M1MU2Pqyoz0aHwar/0qLkp7CjvSQ=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "f560ccec6b1116b22e6ed15f4c510997d99d5852", + "type": "github" + }, + "original": { + "owner": "NixOS", + "ref": "nixos-25.11", + "repo": "nixpkgs", + "type": "github" + } + }, + "root": { + "inputs": { + "flake-utils": "flake-utils", + "nixpkgs": "nixpkgs" + } + }, + "systems": { + "locked": { + "lastModified": 1681028828, + "narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=", + "owner": "nix-systems", + "repo": "default", + "rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e", + "type": "github" + }, + "original": { + "owner": "nix-systems", + "repo": "default", + "type": "github" + } + } + }, + "root": "root", + "version": 7 +} diff --git a/flake.nix b/flake.nix new file mode 100644 index 00000000..b222d438 --- /dev/null +++ b/flake.nix @@ -0,0 +1,82 @@ +{ + description = "OpenSpec - AI-native system for spec-driven development"; + + inputs = { + nixpkgs.url = "github:NixOS/nixpkgs/nixos-25.11"; + flake-utils.url = "github:numtide/flake-utils"; + }; + + outputs = { self, nixpkgs, flake-utils }: + flake-utils.lib.eachDefaultSystem (system: + let + pkgs = nixpkgs.legacyPackages.${system}; + nodejs = pkgs.nodejs_22; + packageJson = pkgs.lib.importJSON ./package.json; + in + { + packages.default = pkgs.stdenv.mkDerivation (finalAttrs: { + pname = "openspec"; + version = packageJson.version; + + src = ./.; + + nativeBuildInputs = [ + nodejs + pkgs.pnpm + pkgs.pnpmConfigHook + pkgs.makeWrapper + ]; + + # When pnpm-lock.yaml changes, update hash by running: + # nix build 2>&1 | grep 'got:' | awk '{print $2}' + pnpmDeps = pkgs.fetchPnpmDeps { + inherit (finalAttrs) pname version src; + hash = "sha256-vAlqVFaBN7KMlyP4HKbsMkaYrA5Yf2l5a+PLCZ6KOzs="; + fetcherVersion = 3; + }; + + buildPhase = '' + runHook preBuild + pnpm run build + runHook postBuild + ''; + + installPhase = '' + runHook preInstall + + mkdir -p $out/lib/openspec + cp -r dist $out/lib/openspec/ + cp -r bin $out/lib/openspec/ + cp -r node_modules $out/lib/openspec/ + cp package.json $out/lib/openspec/ + + mkdir -p $out/bin + makeWrapper ${nodejs}/bin/node $out/bin/openspec \ + --add-flags "$out/lib/openspec/bin/openspec.js" + + runHook postInstall + ''; + + meta = with pkgs.lib; { + description = "AI-native system for spec-driven development"; + homepage = "https://github.com/Fission-AI/OpenSpec"; + license = licenses.mit; + maintainers = [ ]; + mainProgram = "openspec"; + platforms = platforms.all; + }; + }); + + devShells.default = pkgs.mkShell { + buildInputs = [ + nodejs + pkgs.pnpm + ]; + }; + + apps.default = flake-utils.lib.mkApp { + drv = self.packages.${system}.default; + }; + } + ); +}