@bitmilldev/warden 1.0.1 → 1.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +1 -1
- package/scripts/postinstall.js +115 -37
package/package.json
CHANGED
package/scripts/postinstall.js
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
// Warden npm/bun postinstall — downloads the platform-specific binary
|
|
3
3
|
// to ~/.warden/bin/ and registers PATH.
|
|
4
4
|
|
|
5
|
-
const {
|
|
5
|
+
const { spawnSync } = require("child_process");
|
|
6
6
|
const fs = require("fs");
|
|
7
7
|
const path = require("path");
|
|
8
8
|
const os = require("os");
|
|
@@ -32,78 +32,156 @@ async function main() {
|
|
|
32
32
|
|
|
33
33
|
const wardenHome = path.join(os.homedir(), ".warden");
|
|
34
34
|
const binDir = path.join(wardenHome, "bin");
|
|
35
|
-
const
|
|
36
|
-
const dest = path.join(binDir,
|
|
35
|
+
const ext = os.platform() === "win32" ? ".exe" : "";
|
|
36
|
+
const dest = path.join(binDir, `warden${ext}`);
|
|
37
37
|
|
|
38
38
|
// Create directories
|
|
39
39
|
fs.mkdirSync(binDir, { recursive: true });
|
|
40
40
|
fs.mkdirSync(path.join(wardenHome, "rules"), { recursive: true });
|
|
41
41
|
fs.mkdirSync(path.join(wardenHome, "projects"), { recursive: true });
|
|
42
42
|
|
|
43
|
-
//
|
|
43
|
+
// Strategy 1: Check if warden is already installed via cargo and is current version
|
|
44
|
+
const localCargo = findCargoBinary();
|
|
45
|
+
if (localCargo) {
|
|
46
|
+
console.log(`Found cargo-installed warden at ${localCargo}`);
|
|
47
|
+
if (localCargo !== dest) {
|
|
48
|
+
fs.copyFileSync(localCargo, dest);
|
|
49
|
+
console.log(`Copied to ${dest}`);
|
|
50
|
+
}
|
|
51
|
+
copyRelay(binDir, localCargo);
|
|
52
|
+
postInstall(dest);
|
|
53
|
+
return;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
// Strategy 2: Download from GitHub Releases
|
|
44
57
|
const url = `https://github.com/${REPO}/releases/download/v${VERSION}/${binary}`;
|
|
45
58
|
console.log(`Downloading warden v${VERSION} for ${platform}...`);
|
|
46
59
|
|
|
47
60
|
try {
|
|
48
61
|
await download(url, dest);
|
|
62
|
+
const stat = fs.statSync(dest);
|
|
63
|
+
if (stat.size === 0) {
|
|
64
|
+
fs.unlinkSync(dest);
|
|
65
|
+
throw new Error("Downloaded file is empty (asset may not exist in release)");
|
|
66
|
+
}
|
|
67
|
+
|
|
49
68
|
if (os.platform() === "win32") {
|
|
50
|
-
// Remove Zone.Identifier to prevent SmartScreen "Access denied"
|
|
51
69
|
try { fs.unlinkSync(dest + ":Zone.Identifier"); } catch (e) {}
|
|
52
70
|
} else {
|
|
53
71
|
fs.chmodSync(dest, 0o755);
|
|
54
72
|
}
|
|
55
73
|
|
|
56
|
-
//
|
|
74
|
+
// Download relay binary (Windows only — prevents CMD flicker)
|
|
57
75
|
if (os.platform() === "win32") {
|
|
58
76
|
const relayBinary = binary.replace("warden-", "warden-relay-");
|
|
59
77
|
const relayDest = path.join(binDir, "warden-relay.exe");
|
|
60
78
|
const relayUrl = `https://github.com/${REPO}/releases/download/v${VERSION}/${relayBinary}`;
|
|
61
79
|
try {
|
|
62
80
|
await download(relayUrl, relayDest);
|
|
63
|
-
|
|
64
|
-
|
|
81
|
+
const relayStat = fs.statSync(relayDest);
|
|
82
|
+
if (relayStat.size === 0) {
|
|
83
|
+
fs.unlinkSync(relayDest);
|
|
84
|
+
} else {
|
|
85
|
+
try { fs.unlinkSync(relayDest + ":Zone.Identifier"); } catch (e) {}
|
|
86
|
+
console.log(`Installed relay to ${relayDest}`);
|
|
87
|
+
}
|
|
65
88
|
} catch (e) {
|
|
66
89
|
// Relay is optional — warden works without it (just has CMD flicker)
|
|
67
90
|
}
|
|
68
91
|
}
|
|
69
92
|
|
|
70
|
-
|
|
93
|
+
postInstall(dest);
|
|
94
|
+
} catch (err) {
|
|
95
|
+
// Clean up empty/partial file
|
|
96
|
+
try { if (fs.existsSync(dest) && fs.statSync(dest).size === 0) fs.unlinkSync(dest); } catch (e) {}
|
|
97
|
+
|
|
98
|
+
console.error(`Download failed: ${err.message}`);
|
|
99
|
+
console.error("");
|
|
100
|
+
console.error("Alternative install methods:");
|
|
101
|
+
console.error(" cargo install warden-ai");
|
|
102
|
+
console.error(" Download from: https://github.com/ekud12/warden/releases");
|
|
103
|
+
process.exit(0); // Don't fail npm install
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
function postInstall(dest) {
|
|
108
|
+
console.log(`Installed to ${dest}`);
|
|
109
|
+
|
|
110
|
+
// Verify binary works
|
|
111
|
+
try {
|
|
112
|
+
spawnSync(dest, ["version"], { stdio: "inherit", timeout: 5000 });
|
|
113
|
+
} catch (e) {
|
|
114
|
+
// Ignore — binary might need different setup
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
console.log("");
|
|
118
|
+
console.log("Run 'warden init' to complete setup (install CLI tools, configure hooks).");
|
|
119
|
+
console.log("Or: 'warden install claude-code' / 'warden install gemini-cli'");
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
function findCargoBinary() {
|
|
123
|
+
// Check common cargo install locations
|
|
124
|
+
const ext = os.platform() === "win32" ? ".exe" : "";
|
|
125
|
+
const candidates = [
|
|
126
|
+
path.join(os.homedir(), ".cargo", "bin", `warden${ext}`),
|
|
127
|
+
];
|
|
128
|
+
|
|
129
|
+
// Also check if there's a local build in the project (for development)
|
|
130
|
+
const envBinary = process.env.WARDEN_BINARY;
|
|
131
|
+
if (envBinary && fs.existsSync(envBinary)) {
|
|
132
|
+
return envBinary;
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
for (const candidate of candidates) {
|
|
136
|
+
if (fs.existsSync(candidate)) {
|
|
137
|
+
const stat = fs.statSync(candidate);
|
|
138
|
+
if (stat.size > 0) return candidate;
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
return null;
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
function copyRelay(binDir, sourceBinaryDir) {
|
|
145
|
+
if (os.platform() !== "win32") return;
|
|
146
|
+
|
|
147
|
+
const sourceDir = path.dirname(sourceBinaryDir);
|
|
148
|
+
const relaySource = path.join(sourceDir, "warden-relay.exe");
|
|
149
|
+
const relayDest = path.join(binDir, "warden-relay.exe");
|
|
71
150
|
|
|
72
|
-
|
|
151
|
+
if (fs.existsSync(relaySource) && relaySource !== relayDest) {
|
|
73
152
|
try {
|
|
74
|
-
|
|
153
|
+
fs.copyFileSync(relaySource, relayDest);
|
|
154
|
+
console.log(`Copied relay to ${relayDest}`);
|
|
75
155
|
} catch (e) {
|
|
76
|
-
//
|
|
156
|
+
// Non-fatal
|
|
77
157
|
}
|
|
78
|
-
|
|
79
|
-
console.log("");
|
|
80
|
-
console.log("Run 'warden init' to complete setup (install CLI tools, configure hooks).");
|
|
81
|
-
console.log(`Or: 'warden install claude-code' / 'warden install gemini-cli'`);
|
|
82
|
-
} catch (err) {
|
|
83
|
-
console.error(`Download failed: ${err.message}`);
|
|
84
|
-
console.error("Install from source: cargo install warden-ai");
|
|
85
|
-
process.exit(0); // Don't fail npm install
|
|
86
158
|
}
|
|
87
159
|
}
|
|
88
160
|
|
|
89
|
-
function download(url, dest) {
|
|
161
|
+
function download(url, dest, redirects = 0) {
|
|
162
|
+
if (redirects > 10) return Promise.reject(new Error("Too many redirects"));
|
|
90
163
|
return new Promise((resolve, reject) => {
|
|
91
|
-
const
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
164
|
+
const proto = url.startsWith("https") ? https : require("http");
|
|
165
|
+
proto.get(url, (response) => {
|
|
166
|
+
if (response.statusCode === 301 || response.statusCode === 302) {
|
|
167
|
+
response.resume();
|
|
168
|
+
return resolve(download(response.headers.location, dest, redirects + 1));
|
|
169
|
+
}
|
|
170
|
+
if (response.statusCode !== 200) {
|
|
171
|
+
response.resume();
|
|
172
|
+
return reject(new Error(`HTTP ${response.statusCode} for ${url}`));
|
|
173
|
+
}
|
|
174
|
+
const file = fs.createWriteStream(dest);
|
|
175
|
+
response.pipe(file);
|
|
176
|
+
file.on("finish", () => { file.close(); resolve(); });
|
|
177
|
+
file.on("error", (e) => {
|
|
178
|
+
try { fs.unlinkSync(dest); } catch (ignore) {}
|
|
179
|
+
reject(e);
|
|
180
|
+
});
|
|
181
|
+
}).on("error", (e) => {
|
|
182
|
+
try { fs.unlinkSync(dest); } catch (ignore) {}
|
|
183
|
+
reject(e);
|
|
184
|
+
});
|
|
107
185
|
});
|
|
108
186
|
}
|
|
109
187
|
|