Skip to content
Open
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
4 changes: 4 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -148,3 +148,7 @@ CLAUDE.md

# Pnpm
.pnpm-store/

# Nix
result
.direnv/
17 changes: 17 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -144,6 +144,21 @@ Verify installation:
openspec --version
```

<details>
<summary><strong>Alternative: Install with Nix</strong> (click to expand)</summary>

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
```

</details>

#### Step 2: Initialize OpenSpec in your project

Navigate to your project directory:
Expand Down Expand Up @@ -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
61 changes: 61 additions & 0 deletions flake.lock

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

82 changes: 82 additions & 0 deletions flake.nix
Original file line number Diff line number Diff line change
@@ -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;
};
}
);
}