This repository has no description
3.2 kB
121 lines
1{
2 lib,
3 stdenv,
4 nodejs,
5 pnpm_10,
6 fetchPnpmDeps,
7 pnpmConfigHook,
8 makeWrapper,
9 tmux,
10 git,
11 openssh,
12 fetchFromGitHub,
13}:
14
15let
16 src = fetchFromGitHub {
17 owner = "Lassulus";
18 repo = "kanvibe";
19 rev = "6887b163b7ab36c2f4f41bd02bf6c648ebe85840";
20 hash = "sha256-FTszbYyYlTqDJxHVRPV9VMu9i+gRrdTq1du1nbzHjdA=";
21 };
22in
23stdenv.mkDerivation (finalAttrs: {
24 pname = "kanvibe";
25 version = "0.1.0";
26
27 inherit src;
28
29 nativeBuildInputs = [
30 nodejs
31 pnpm_10
32 pnpmConfigHook
33 makeWrapper
34 ];
35
36 pnpmDeps = fetchPnpmDeps {
37 pname = "kanvibe";
38 inherit (finalAttrs) version src;
39 pnpm = pnpm_10;
40 hash = "sha256-POorUzaa5JFmQygDNlGY7G4XoZOf7iW6UIyqgmF05b0=";
41 fetcherVersion = 2;
42 };
43
44 buildPhase = ''
45 runHook preBuild
46
47 export NEXT_TELEMETRY_DISABLED=1
48
49 # Set default locale to English
50 substituteInPlace src/i18n/routing.ts \
51 --replace-fail 'defaultLocale: "ko"' 'defaultLocale: "en"'
52
53 # Patch out Google Fonts (no network in sandbox)
54 substituteInPlace src/app/\[locale\]/layout.tsx \
55 --replace-fail 'import { Inter } from "next/font/google";' "" \
56 --replace-fail 'const inter = Inter({
57 variable: "--font-inter",
58 subsets: ["latin"],
59 });' 'const inter = { variable: "" };'
60
61 pnpm build
62
63 # Replace @/ path aliases with absolute paths for runtime tsx resolution
64 # (Next.js require-hook interferes with tsx's tsconfig paths resolution)
65 find . -name '*.ts' -not -path './node_modules/*' -not -path './.next/*' \
66 -exec sed -i "s|from \"@/|from \"$out/lib/kanvibe/src/|g" {} +
67 find . -name '*.ts' -not -path './node_modules/*' -not -path './.next/*' \
68 -exec sed -i "s|from '@/|from '$out/lib/kanvibe/src/|g" {} +
69
70 runHook postBuild
71 '';
72
73 installPhase = ''
74 runHook preInstall
75
76 mkdir -p $out/lib/kanvibe
77
78 # Copy the built Next.js app
79 cp -r .next $out/lib/kanvibe/.next
80
81 # Copy runtime files
82 cp boot.js $out/lib/kanvibe/
83 cp server.ts $out/lib/kanvibe/
84 cp next.config.ts $out/lib/kanvibe/
85 cp package.json $out/lib/kanvibe/
86 cp tsconfig.json $out/lib/kanvibe/
87 cp -r src $out/lib/kanvibe/src
88 cp -r messages $out/lib/kanvibe/messages
89 cp -r public $out/lib/kanvibe/public 2>/dev/null || true
90
91 # node_modules needed at runtime (tsx, typeorm, node-pty, etc.)
92 cp -r node_modules $out/lib/kanvibe/node_modules
93
94 mkdir -p $out/bin
95 # Patch boot.js to chdir to package directory so tsx finds tsconfig.json
96 substituteInPlace $out/lib/kanvibe/boot.js \
97 --replace-fail 'require("tsx/cjs");' \
98 'process.chdir(__dirname); require("tsx/cjs");'
99
100 makeWrapper ${nodejs}/bin/node $out/bin/kanvibe \
101 --add-flags "$out/lib/kanvibe/boot.js" \
102 --set NODE_ENV production \
103 --prefix PATH : ${
104 lib.makeBinPath [
105 tmux
106 git
107 openssh
108 ]
109 }
110
111 runHook postInstall
112 '';
113
114 meta = {
115 description = "AI Agent Task Management Kanban Board";
116 homepage = "https://github.com/Lassulus/kanvibe";
117 license = lib.licenses.agpl3Only;
118 mainProgram = "kanvibe";
119 platforms = lib.platforms.unix;
120 };
121})