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
48 changes: 48 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
.PHONY: help build dev build-dev test run clean clean-workspace rebuild rebuild-dev nix-build nix-build-dev nix-develop

NODE ?= node
NIX ?= nix
BUILD_SCRIPT := scripts/build-cli.mjs
DIST_ENTRY := dist/cli.js
PREPARED_MARKER := .cache/workspace/.prepared.json

help: ## Show available workflow targets
@printf "Available targets:\n"
@awk 'BEGIN {FS = ":.*## "}; /^[a-zA-Z0-9_-]+:.*## / {printf " %-14s %s\n", $$1, $$2}' $(MAKEFILE_LIST)

build: ## Build the production bundle with the flake-managed Node/Bun toolchain
$(NIX) run path:.#build

dev: ## Build an unminified development bundle with the flake-managed toolchain
$(NIX) run path:.#build-dev

build-dev: ## Alias for the development build
$(NIX) run path:.#build-dev

test: build ## Build and smoke-test the generated CLI
test -f $(DIST_ENTRY)
$(NIX) develop path:. --command node $(DIST_ENTRY) --help >/dev/null

run: ## Run the built CLI from dist/cli.js with the local Node binary
$(NODE) $(DIST_ENTRY)

clean: ## Remove build output
rm -rf dist

clean-workspace: ## Remove cached extracted workspace and output
rm -rf .cache/workspace dist

rebuild: clean build ## Clean dist and rebuild production bundle

rebuild-dev: ## Force workspace regeneration and rebuild unminified bundle
rm -f $(PREPARED_MARKER)
$(NIX) run path:.#build-dev

nix-build: ## Build through the flake app
$(NIX) run path:.#build

nix-build-dev: ## Development build through the flake app
$(NIX) run path:.#build-dev

nix-develop: ## Enter the flake dev shell
$(NIX) develop path:.
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.

84 changes: 84 additions & 0 deletions flake.nix
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
{
description = "Nix flake for building the Claude Code source build";

inputs = {
nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable";
flake-utils.url = "github:numtide/flake-utils";
};

outputs = { self, nixpkgs, flake-utils }:
flake-utils.lib.eachDefaultSystem (system:
let
pkgs = import nixpkgs {
inherit system;
};

nodejs = pkgs.nodejs_22;

buildCli = pkgs.writeShellApplication {
name = "build-claude-code";
runtimeInputs = [
nodejs
pkgs.bun
];
text = ''
set -euo pipefail

if [ ! -f ./scripts/build-cli.mjs ]; then
echo "Run this from the repository root so ./scripts/build-cli.mjs is available." >&2
exit 1
fi

exec node ./scripts/build-cli.mjs "$@"
'';
};
in
{
packages.default = buildCli;
packages.build-cli = buildCli;

apps.default = {
type = "app";
program = "${buildCli}/bin/build-claude-code";
};

apps.build = {
type = "app";
program = "${buildCli}/bin/build-claude-code";
};

apps.build-dev = {
type = "app";
program = "${pkgs.writeShellApplication {
name = "build-claude-code-dev";
runtimeInputs = [
nodejs
pkgs.bun
];
text = ''
set -euo pipefail

if [ ! -f ./scripts/build-cli.mjs ]; then
echo "Run this from the repository root so ./scripts/build-cli.mjs is available." >&2
exit 1
fi

exec node ./scripts/build-cli.mjs --no-minify "$@"
'';
}}/bin/build-claude-code-dev";
};

devShells.default = pkgs.mkShell {
packages = [
nodejs
pkgs.bun
];

shellHook = ''
echo "Tooling loaded: node $(node --version), npm $(npm --version), bun $(bun --version)"
echo "Build with: node scripts/build-cli.mjs"
echo "Or via flake app: nix run .#build"
'';
};
});
}
17 changes: 13 additions & 4 deletions scripts/build-cli.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -190,15 +190,24 @@ function main() {
generateWorkspaceAugmentations();

const buildResult = runBunBuild();
if (buildResult.error) {
const message = buildResult.error.message || String(buildResult.error);
console.error(`Failed to start bun: ${message}`);
process.exit(buildResult.status ?? 1);
}
if (buildResult.status === 0) {
finalizeBuild();
return;
}

const changed = reconcileBuildErrors(buildResult.stderr);
const changed = reconcileBuildErrors(buildResult.stderr ?? '');
if (!changed) {
process.stdout.write(buildResult.stdout);
process.stderr.write(buildResult.stderr);
if (buildResult.stdout) {
process.stdout.write(buildResult.stdout);
}
if (buildResult.stderr) {
process.stderr.write(buildResult.stderr);
}
process.exit(buildResult.status ?? 1);
}
}
Expand Down Expand Up @@ -689,7 +698,7 @@ function finalizeBuild() {
}


function reconcileBuildErrors(stderrText) {
function reconcileBuildErrors(stderrText = '') {
let changed = false;

for (const match of stderrText.matchAll(
Expand Down