nightpay 0.3.0 → 0.3.2
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.
Potentially problematic release.
This version of nightpay might be problematic. Click here for more details.
- package/README.md +192 -376
- package/bin/cli.js +256 -60
- package/package.json +1 -1
- package/skills/nightpay/AGENTS.md +283 -0
- package/skills/nightpay/SKILL.md +12 -9
- package/skills/nightpay/ontology/ontology.jsonld +1 -7
- package/skills/nightpay/ontology/ontology.md +178 -36
- package/scripts/bounty-board.sh +0 -325
- package/scripts/gateway.sh +0 -1365
- package/scripts/mip003-server.sh +0 -3593
- package/scripts/update-blocklist.sh +0 -194
package/bin/cli.js
CHANGED
|
@@ -1,12 +1,15 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
|
|
3
|
-
import { cpSync, existsSync, mkdirSync, readFileSync, chmodSync, readdirSync } from "node:fs";
|
|
4
|
-
import { resolve, dirname, join } from "node:path";
|
|
3
|
+
import { cpSync, copyFileSync, existsSync, mkdirSync, readFileSync, chmodSync, readdirSync, statSync, writeFileSync } from "node:fs";
|
|
4
|
+
import { resolve, dirname, join, basename } from "node:path";
|
|
5
5
|
import { fileURLToPath } from "node:url";
|
|
6
6
|
import { execSync, spawnSync } from "node:child_process";
|
|
7
7
|
|
|
8
8
|
const __dirname = dirname(fileURLToPath(import.meta.url));
|
|
9
|
-
const
|
|
9
|
+
const PKG_ROOT = resolve(__dirname, "..");
|
|
10
|
+
const SKILL_SRC = resolve(PKG_ROOT, "skills", "nightpay");
|
|
11
|
+
const SDK_SRC = resolve(PKG_ROOT, "nightpay_sdk.py");
|
|
12
|
+
const SETUP_SRC = resolve(PKG_ROOT, "scripts", "setup.sh");
|
|
10
13
|
const COMMANDS = ["init", "add", "setup", "validate", "doctor", "list", "help"];
|
|
11
14
|
|
|
12
15
|
const command = process.argv[2] || "help";
|
|
@@ -16,6 +19,13 @@ if (!COMMANDS.includes(command)) {
|
|
|
16
19
|
process.exit(1);
|
|
17
20
|
}
|
|
18
21
|
|
|
22
|
+
// ─── Version ─────────────────────────────────────────────────────────────────
|
|
23
|
+
let VERSION = "0.3.2";
|
|
24
|
+
try {
|
|
25
|
+
const pkg = JSON.parse(readFileSync(resolve(PKG_ROOT, "package.json"), "utf8"));
|
|
26
|
+
VERSION = pkg.version || VERSION;
|
|
27
|
+
} catch {}
|
|
28
|
+
|
|
19
29
|
// ─── Colors ──────────────────────────────────────────────────────────────────
|
|
20
30
|
const isTTY = process.stderr.isTTY;
|
|
21
31
|
const C = {
|
|
@@ -30,14 +40,15 @@ const C = {
|
|
|
30
40
|
const OK = `${C.green}✅${C.reset}`;
|
|
31
41
|
const FAIL = `${C.red}❌${C.reset}`;
|
|
32
42
|
const WARN = `${C.yellow}⚠️${C.reset}`;
|
|
43
|
+
const INFO = `${C.cyan}ℹ${C.reset}`;
|
|
33
44
|
|
|
34
45
|
// ─── Help ────────────────────────────────────────────────────────────────────
|
|
35
46
|
if (command === "help") {
|
|
36
47
|
console.log(`
|
|
37
|
-
${C.bold}nightpay${C.reset} — anonymous community bounties for AI agents
|
|
48
|
+
${C.bold}nightpay${C.reset} v${VERSION} — anonymous community bounties for AI agents
|
|
38
49
|
|
|
39
50
|
${C.bold}COMMANDS${C.reset}
|
|
40
|
-
npx nightpay ${C.cyan}init${C.reset}
|
|
51
|
+
npx nightpay ${C.cyan}init${C.reset} Install skill files, SDK, and setup script
|
|
41
52
|
npx nightpay ${C.cyan}setup${C.reset} Full onboarding: install + validate + platform config
|
|
42
53
|
npx nightpay ${C.cyan}validate${C.reset} Check env vars, prerequisites, and connectivity
|
|
43
54
|
npx nightpay ${C.cyan}doctor${C.reset} Diagnose and auto-fix common issues
|
|
@@ -55,6 +66,11 @@ ${C.bold}QUICK START${C.reset}
|
|
|
55
66
|
export NIGHTPAY_API_URL="https://api.nightpay.dev"
|
|
56
67
|
export BRIDGE_URL="https://bridge.nightpay.dev"
|
|
57
68
|
npx nightpay validate
|
|
69
|
+
|
|
70
|
+
${C.bold}WHAT INIT INSTALLS${C.reset}
|
|
71
|
+
./skills/nightpay/ Skill files (SKILL.md, scripts, config)
|
|
72
|
+
./skills/nightpay/sdk/ Python SDK (nightpay_sdk.py)
|
|
73
|
+
./skills/nightpay/scripts/ Gateway + setup scripts
|
|
58
74
|
`);
|
|
59
75
|
process.exit(0);
|
|
60
76
|
}
|
|
@@ -67,7 +83,7 @@ ${C.bold}Available skill:${C.reset}
|
|
|
67
83
|
Many funders pool shielded NIGHT → AI agent completes work → ZK receipt
|
|
68
84
|
|
|
69
85
|
${C.bold}Platforms:${C.reset} OpenClaw, Claude Code, Cursor, GitHub Copilot, ACP, Raw API
|
|
70
|
-
${C.bold}Version:${C.reset}
|
|
86
|
+
${C.bold}Version:${C.reset} ${VERSION}
|
|
71
87
|
${C.bold}License:${C.reset} Apache-2.0
|
|
72
88
|
`);
|
|
73
89
|
process.exit(0);
|
|
@@ -82,38 +98,106 @@ function detectPlatform() {
|
|
|
82
98
|
return "raw";
|
|
83
99
|
}
|
|
84
100
|
|
|
85
|
-
// ───
|
|
101
|
+
// ─── Copy one file safely ───────────────────────────────────────────────────
|
|
102
|
+
function safeCopy(src, dest, label) {
|
|
103
|
+
if (!existsSync(src)) {
|
|
104
|
+
return { status: "skip", reason: "source not found in package" };
|
|
105
|
+
}
|
|
106
|
+
mkdirSync(dirname(dest), { recursive: true });
|
|
107
|
+
if (existsSync(dest)) {
|
|
108
|
+
// Compare sizes — if same, skip
|
|
109
|
+
try {
|
|
110
|
+
const srcStat = statSync(src);
|
|
111
|
+
const destStat = statSync(dest);
|
|
112
|
+
if (srcStat.size === destStat.size) {
|
|
113
|
+
return { status: "exists", reason: "already up to date" };
|
|
114
|
+
}
|
|
115
|
+
} catch {}
|
|
116
|
+
}
|
|
117
|
+
copyFileSync(src, dest);
|
|
118
|
+
return { status: "copied" };
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
// ─── Init (copy ALL files) ──────────────────────────────────────────────────
|
|
86
122
|
function init() {
|
|
87
123
|
const dest = resolve(process.cwd(), "skills", "nightpay");
|
|
124
|
+
const installed = [];
|
|
125
|
+
|
|
126
|
+
console.log(`\n${C.bold}Installing NightPay${C.reset} v${VERSION}\n`);
|
|
88
127
|
|
|
128
|
+
// 1. Core skill files (SKILL.md, scripts/gateway.sh, etc.)
|
|
129
|
+
mkdirSync(resolve(process.cwd(), "skills"), { recursive: true });
|
|
89
130
|
if (existsSync(join(dest, "SKILL.md"))) {
|
|
90
|
-
|
|
91
|
-
|
|
131
|
+
// Update existing — re-copy to catch any upstream changes
|
|
132
|
+
cpSync(SKILL_SRC, dest, { recursive: true });
|
|
133
|
+
console.log(` ${OK} Skill files updated at ${C.dim}./skills/nightpay/${C.reset}`);
|
|
134
|
+
installed.push("skills/nightpay/ (updated)");
|
|
135
|
+
} else {
|
|
136
|
+
cpSync(SKILL_SRC, dest, { recursive: true });
|
|
137
|
+
console.log(` ${OK} Skill files installed to ${C.dim}./skills/nightpay/${C.reset}`);
|
|
138
|
+
installed.push("skills/nightpay/");
|
|
92
139
|
}
|
|
93
140
|
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
141
|
+
// 2. Python SDK → ./skills/nightpay/sdk/nightpay_sdk.py
|
|
142
|
+
const sdkDest = join(dest, "sdk", "nightpay_sdk.py");
|
|
143
|
+
const sdkResult = safeCopy(SDK_SRC, sdkDest, "Python SDK");
|
|
144
|
+
if (sdkResult.status === "copied") {
|
|
145
|
+
console.log(` ${OK} Python SDK installed to ${C.dim}./skills/nightpay/sdk/nightpay_sdk.py${C.reset}`);
|
|
146
|
+
installed.push("sdk/nightpay_sdk.py");
|
|
147
|
+
} else if (sdkResult.status === "exists") {
|
|
148
|
+
console.log(` ${OK} Python SDK ${C.dim}(already up to date)${C.reset}`);
|
|
149
|
+
} else {
|
|
150
|
+
console.log(` ${INFO} Python SDK not bundled in this version ${C.dim}(download from GitHub)${C.reset}`);
|
|
151
|
+
}
|
|
97
152
|
|
|
98
|
-
//
|
|
153
|
+
// Also copy SDK to project root for direct import convenience
|
|
154
|
+
const sdkRootDest = resolve(process.cwd(), "nightpay_sdk.py");
|
|
155
|
+
const sdkRootResult = safeCopy(SDK_SRC, sdkRootDest, "Python SDK (root)");
|
|
156
|
+
if (sdkRootResult.status === "copied") {
|
|
157
|
+
console.log(` ${OK} Python SDK also at ${C.dim}./nightpay_sdk.py${C.reset} ${C.dim}(for direct import)${C.reset}`);
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
// 3. Setup script → ./skills/nightpay/scripts/setup.sh
|
|
161
|
+
const setupDest = join(dest, "scripts", "setup.sh");
|
|
162
|
+
const setupResult = safeCopy(SETUP_SRC, setupDest, "setup.sh");
|
|
163
|
+
if (setupResult.status === "copied") {
|
|
164
|
+
console.log(` ${OK} Setup script installed to ${C.dim}./skills/nightpay/scripts/setup.sh${C.reset}`);
|
|
165
|
+
installed.push("scripts/setup.sh");
|
|
166
|
+
} else if (setupResult.status === "exists") {
|
|
167
|
+
console.log(` ${OK} Setup script ${C.dim}(already up to date)${C.reset}`);
|
|
168
|
+
} else {
|
|
169
|
+
console.log(` ${INFO} Setup script not bundled in this version`);
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
// 4. Fix permissions on ALL scripts
|
|
99
173
|
const scriptsDir = join(dest, "scripts");
|
|
100
174
|
if (existsSync(scriptsDir)) {
|
|
175
|
+
let chmodCount = 0;
|
|
101
176
|
try {
|
|
102
177
|
for (const f of readdirSync(scriptsDir)) {
|
|
103
178
|
if (f.endsWith(".sh")) {
|
|
104
179
|
chmodSync(join(scriptsDir, f), 0o755);
|
|
180
|
+
chmodCount++;
|
|
105
181
|
}
|
|
106
182
|
}
|
|
107
|
-
|
|
183
|
+
if (chmodCount > 0) {
|
|
184
|
+
console.log(` ${OK} Made ${chmodCount} script(s) executable`);
|
|
185
|
+
}
|
|
108
186
|
} catch {}
|
|
109
187
|
}
|
|
110
188
|
|
|
111
|
-
// Auto-flatten
|
|
189
|
+
// 5. Auto-flatten nested skill directory (common misinstall)
|
|
112
190
|
const nestedSkill = join(dest, "skills", "nightpay", "SKILL.md");
|
|
113
|
-
if (
|
|
114
|
-
console.log(
|
|
191
|
+
if (existsSync(nestedSkill)) {
|
|
192
|
+
console.log(` ${WARN} Nested skill directory detected — flattening...`);
|
|
115
193
|
cpSync(join(dest, "skills", "nightpay"), dest, { recursive: true });
|
|
116
|
-
console.log(
|
|
194
|
+
console.log(` ${OK} Flattened: ${C.dim}skills/nightpay/skills/nightpay/ → skills/nightpay/${C.reset}`);
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
// 6. Summary
|
|
198
|
+
console.log(`\n${C.bold}Installed ${installed.length} component(s):${C.reset}`);
|
|
199
|
+
for (const item of installed) {
|
|
200
|
+
console.log(` ${C.dim}•${C.reset} ${item}`);
|
|
117
201
|
}
|
|
118
202
|
|
|
119
203
|
return dest;
|
|
@@ -135,13 +219,18 @@ function validate() {
|
|
|
135
219
|
}
|
|
136
220
|
}
|
|
137
221
|
|
|
138
|
-
// sha256sum or shasum
|
|
139
222
|
let hasHash = false;
|
|
140
223
|
try { execSync("which sha256sum", { stdio: "ignore" }); hasHash = true; } catch {}
|
|
141
224
|
try { execSync("which shasum", { stdio: "ignore" }); hasHash = true; } catch {}
|
|
142
225
|
if (hasHash) console.log(` ${OK} sha256sum/shasum found`);
|
|
143
226
|
else { console.log(` ${FAIL} sha256sum/shasum not found`); errors++; }
|
|
144
227
|
|
|
228
|
+
// Python check (for SDK)
|
|
229
|
+
let hasPython = false;
|
|
230
|
+
try { execSync("which python3", { stdio: "ignore" }); hasPython = true; } catch {}
|
|
231
|
+
if (hasPython) console.log(` ${OK} python3 found (SDK available)`);
|
|
232
|
+
else console.log(` ${INFO} python3 not found ${C.dim}(optional — needed for Python SDK)${C.reset}`);
|
|
233
|
+
|
|
145
234
|
console.log(`\n${C.bold}Environment variables${C.reset}`);
|
|
146
235
|
const required = {
|
|
147
236
|
MASUMI_API_KEY: "Masumi payment API key",
|
|
@@ -170,18 +259,30 @@ function validate() {
|
|
|
170
259
|
|
|
171
260
|
console.log(`\n${C.bold}Skill files${C.reset}`);
|
|
172
261
|
const dest = resolve(process.cwd(), "skills", "nightpay");
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
262
|
+
|
|
263
|
+
const fileChecks = [
|
|
264
|
+
{ path: join(dest, "SKILL.md"), label: "SKILL.md", required: true },
|
|
265
|
+
{ path: join(dest, "scripts", "gateway.sh"), label: "gateway.sh", required: true },
|
|
266
|
+
{ path: join(dest, "scripts", "setup.sh"), label: "setup.sh", required: false },
|
|
267
|
+
{ path: join(dest, "sdk", "nightpay_sdk.py"), label: "Python SDK (sdk/)", required: false },
|
|
268
|
+
];
|
|
269
|
+
|
|
270
|
+
for (const check of fileChecks) {
|
|
271
|
+
if (existsSync(check.path)) {
|
|
272
|
+
console.log(` ${OK} ${check.label} found`);
|
|
273
|
+
} else if (check.required) {
|
|
274
|
+
console.log(` ${FAIL} ${check.label} not found — run: ${C.cyan}npx nightpay init${C.reset}`);
|
|
275
|
+
errors++;
|
|
276
|
+
} else {
|
|
277
|
+
console.log(` ${WARN} ${check.label} not found — run: ${C.cyan}npx nightpay init${C.reset} to install`);
|
|
278
|
+
warnings++;
|
|
279
|
+
}
|
|
178
280
|
}
|
|
179
281
|
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
console.log(` ${
|
|
184
|
-
errors++;
|
|
282
|
+
// Check for root-level SDK copy too
|
|
283
|
+
const rootSdk = resolve(process.cwd(), "nightpay_sdk.py");
|
|
284
|
+
if (existsSync(rootSdk)) {
|
|
285
|
+
console.log(` ${OK} Python SDK also at ./nightpay_sdk.py`);
|
|
185
286
|
}
|
|
186
287
|
|
|
187
288
|
console.log(`\n${C.bold}Connectivity${C.reset}`);
|
|
@@ -223,21 +324,21 @@ function validate() {
|
|
|
223
324
|
|
|
224
325
|
// ─── Doctor (diagnose + auto-fix) ────────────────────────────────────────────
|
|
225
326
|
function doctor() {
|
|
226
|
-
console.log(`\n${C.bold}NightPay Doctor${C.reset} — diagnosing and fixing issues...\n`);
|
|
327
|
+
console.log(`\n${C.bold}NightPay Doctor${C.reset} v${VERSION} — diagnosing and fixing issues...\n`);
|
|
227
328
|
let fixed = 0;
|
|
228
329
|
|
|
229
330
|
const dest = resolve(process.cwd(), "skills", "nightpay");
|
|
230
331
|
|
|
231
|
-
// Fix 1: Missing skill files
|
|
332
|
+
// Fix 1: Missing skill files → full init
|
|
232
333
|
if (!existsSync(join(dest, "SKILL.md"))) {
|
|
233
|
-
console.log(` ${WARN} Skill not installed —
|
|
334
|
+
console.log(` ${WARN} Skill not installed — running full init...`);
|
|
234
335
|
init();
|
|
235
336
|
fixed++;
|
|
236
337
|
}
|
|
237
338
|
|
|
238
339
|
// Fix 2: Nested SKILL.md
|
|
239
340
|
const nestedSkill = join(dest, "skills", "nightpay", "SKILL.md");
|
|
240
|
-
if (existsSync(nestedSkill)
|
|
341
|
+
if (existsSync(nestedSkill)) {
|
|
241
342
|
console.log(` ${WARN} SKILL.md nested — flattening...`);
|
|
242
343
|
cpSync(join(dest, "skills", "nightpay"), dest, { recursive: true });
|
|
243
344
|
console.log(` ${OK} Fixed: flattened skill directory`);
|
|
@@ -245,16 +346,47 @@ function doctor() {
|
|
|
245
346
|
}
|
|
246
347
|
|
|
247
348
|
// Fix 3: Script permissions
|
|
248
|
-
const
|
|
249
|
-
if (existsSync(
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
349
|
+
const scriptsDir = join(dest, "scripts");
|
|
350
|
+
if (existsSync(scriptsDir)) {
|
|
351
|
+
for (const f of readdirSync(scriptsDir)) {
|
|
352
|
+
if (f.endsWith(".sh")) {
|
|
353
|
+
try {
|
|
354
|
+
chmodSync(join(scriptsDir, f), 0o755);
|
|
355
|
+
fixed++;
|
|
356
|
+
} catch {}
|
|
357
|
+
}
|
|
358
|
+
}
|
|
359
|
+
console.log(` ${OK} Fixed: script permissions`);
|
|
360
|
+
}
|
|
361
|
+
|
|
362
|
+
// Fix 4: Missing SDK
|
|
363
|
+
const sdkDest = join(dest, "sdk", "nightpay_sdk.py");
|
|
364
|
+
if (!existsSync(sdkDest) && existsSync(SDK_SRC)) {
|
|
365
|
+
mkdirSync(join(dest, "sdk"), { recursive: true });
|
|
366
|
+
copyFileSync(SDK_SRC, sdkDest);
|
|
367
|
+
console.log(` ${OK} Fixed: installed Python SDK to ${C.dim}sdk/nightpay_sdk.py${C.reset}`);
|
|
368
|
+
fixed++;
|
|
369
|
+
}
|
|
370
|
+
|
|
371
|
+
// Fix 5: Missing setup.sh
|
|
372
|
+
const setupDest = join(dest, "scripts", "setup.sh");
|
|
373
|
+
if (!existsSync(setupDest) && existsSync(SETUP_SRC)) {
|
|
374
|
+
mkdirSync(join(dest, "scripts"), { recursive: true });
|
|
375
|
+
copyFileSync(SETUP_SRC, setupDest);
|
|
376
|
+
chmodSync(setupDest, 0o755);
|
|
377
|
+
console.log(` ${OK} Fixed: installed setup.sh to ${C.dim}scripts/setup.sh${C.reset}`);
|
|
378
|
+
fixed++;
|
|
255
379
|
}
|
|
256
380
|
|
|
257
|
-
// Fix
|
|
381
|
+
// Fix 6: Root SDK convenience copy
|
|
382
|
+
const rootSdk = resolve(process.cwd(), "nightpay_sdk.py");
|
|
383
|
+
if (!existsSync(rootSdk) && existsSync(SDK_SRC)) {
|
|
384
|
+
copyFileSync(SDK_SRC, rootSdk);
|
|
385
|
+
console.log(` ${OK} Fixed: copied SDK to ${C.dim}./nightpay_sdk.py${C.reset} for direct import`);
|
|
386
|
+
fixed++;
|
|
387
|
+
}
|
|
388
|
+
|
|
389
|
+
// Fix 7: Warn about placeholder env vars
|
|
258
390
|
const fragment = join(dest, "openclaw-fragment.json");
|
|
259
391
|
if (existsSync(fragment)) {
|
|
260
392
|
try {
|
|
@@ -278,36 +410,100 @@ function doctor() {
|
|
|
278
410
|
// ─── Setup (full onboarding) ─────────────────────────────────────────────────
|
|
279
411
|
function setup() {
|
|
280
412
|
const platform = detectPlatform();
|
|
281
|
-
console.log(`\n${C.bold}NightPay Agent Onboarding${C.reset}
|
|
413
|
+
console.log(`\n${C.bold}NightPay Agent Onboarding${C.reset} v${VERSION}`);
|
|
282
414
|
console.log(`${C.dim}Anonymous community bounties for AI agents${C.reset}`);
|
|
283
415
|
console.log(`\n Platform: ${C.bold}${platform}${C.reset}\n`);
|
|
284
416
|
|
|
285
|
-
// Step 1:
|
|
417
|
+
// Step 1: Smart install (all files)
|
|
286
418
|
const dest = init();
|
|
287
419
|
|
|
288
420
|
// Step 2: Platform-specific config
|
|
289
|
-
console.log(`\n${C.bold}Platform
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
421
|
+
console.log(`\n${C.bold}Platform config (${platform})${C.reset}`);
|
|
422
|
+
|
|
423
|
+
if (platform === "claude-code") {
|
|
424
|
+
const cmdDir = resolve(process.cwd(), ".claude", "commands");
|
|
425
|
+
const cmdFile = join(cmdDir, "nightpay.md");
|
|
426
|
+
if (!existsSync(cmdFile)) {
|
|
427
|
+
mkdirSync(cmdDir, { recursive: true });
|
|
428
|
+
writeFileSync(cmdFile, [
|
|
429
|
+
"# NightPay",
|
|
430
|
+
"",
|
|
431
|
+
"Use the nightpay skill at ./skills/nightpay/ for bounty operations.",
|
|
432
|
+
"",
|
|
433
|
+
"## Quick commands",
|
|
434
|
+
"- `bash skills/nightpay/scripts/gateway.sh stats` — contract stats",
|
|
435
|
+
"- `bash skills/nightpay/scripts/gateway.sh post-bounty \"<desc>\" <amount>` — post bounty",
|
|
436
|
+
"- `python3 skills/nightpay/sdk/nightpay_sdk.py validate` — health check",
|
|
437
|
+
"- `python3 skills/nightpay/sdk/nightpay_sdk.py doctor --auto-fix` — self-heal",
|
|
438
|
+
"",
|
|
439
|
+
].join("\n"));
|
|
440
|
+
console.log(` ${OK} Created ${C.dim}.claude/commands/nightpay.md${C.reset}`);
|
|
441
|
+
} else {
|
|
442
|
+
console.log(` ${OK} ${C.dim}.claude/commands/nightpay.md${C.reset} already exists`);
|
|
443
|
+
}
|
|
444
|
+
} else if (platform === "cursor") {
|
|
445
|
+
const rulesDir = resolve(process.cwd(), ".cursor", "rules");
|
|
446
|
+
const rulesFile = join(rulesDir, "nightpay.md");
|
|
447
|
+
if (!existsSync(rulesFile)) {
|
|
448
|
+
mkdirSync(rulesDir, { recursive: true });
|
|
449
|
+
writeFileSync(rulesFile, [
|
|
450
|
+
"# NightPay Skill",
|
|
451
|
+
"",
|
|
452
|
+
"The nightpay skill is at ./skills/nightpay/. Read SKILL.md for capabilities.",
|
|
453
|
+
"Python SDK at ./skills/nightpay/sdk/nightpay_sdk.py or ./nightpay_sdk.py.",
|
|
454
|
+
"",
|
|
455
|
+
"Quick: `bash skills/nightpay/scripts/gateway.sh stats`",
|
|
456
|
+
"",
|
|
457
|
+
].join("\n"));
|
|
458
|
+
console.log(` ${OK} Created ${C.dim}.cursor/rules/nightpay.md${C.reset}`);
|
|
459
|
+
} else {
|
|
460
|
+
console.log(` ${OK} ${C.dim}.cursor/rules/nightpay.md${C.reset} already exists`);
|
|
461
|
+
}
|
|
462
|
+
} else if (platform === "copilot") {
|
|
463
|
+
const instrFile = resolve(process.cwd(), ".github", "copilot-instructions.md");
|
|
464
|
+
if (existsSync(instrFile)) {
|
|
465
|
+
const content = readFileSync(instrFile, "utf8");
|
|
466
|
+
if (!content.includes("nightpay")) {
|
|
467
|
+
const addition = [
|
|
468
|
+
"",
|
|
469
|
+
"## NightPay",
|
|
470
|
+
"",
|
|
471
|
+
"Bounty skill at ./skills/nightpay/. Read SKILL.md for full capabilities.",
|
|
472
|
+
"Python SDK at ./skills/nightpay/sdk/nightpay_sdk.py.",
|
|
473
|
+
"Gateway: `bash skills/nightpay/scripts/gateway.sh`",
|
|
474
|
+
"",
|
|
475
|
+
].join("\n");
|
|
476
|
+
writeFileSync(instrFile, content + addition);
|
|
477
|
+
console.log(` ${OK} Appended NightPay section to ${C.dim}.github/copilot-instructions.md${C.reset}`);
|
|
478
|
+
} else {
|
|
479
|
+
console.log(` ${OK} Copilot instructions already mention nightpay`);
|
|
480
|
+
}
|
|
481
|
+
} else {
|
|
482
|
+
console.log(` ${INFO} No .github/copilot-instructions.md — skipping Copilot config`);
|
|
300
483
|
}
|
|
484
|
+
} else if (platform === "openclaw") {
|
|
485
|
+
console.log(` ${OK} OpenClaw auto-discovers skills from ./skills/nightpay/`);
|
|
486
|
+
console.log(` ${C.dim} Tip: merge openclaw-fragment.json into your openclaw.json${C.reset}`);
|
|
301
487
|
} else {
|
|
302
|
-
|
|
303
|
-
|
|
488
|
+
console.log(` ${INFO} Raw platform — no config file needed`);
|
|
489
|
+
console.log(` ${C.dim} Use: bash skills/nightpay/scripts/gateway.sh <command>${C.reset}`);
|
|
304
490
|
}
|
|
305
491
|
|
|
306
|
-
// Step 3:
|
|
492
|
+
// Step 3: Run validate
|
|
493
|
+
console.log("");
|
|
494
|
+
const { errors } = validate();
|
|
495
|
+
|
|
496
|
+
// Step 4: Next steps
|
|
307
497
|
console.log(`\n${C.bold}Next steps${C.reset}`);
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
498
|
+
if (errors > 0) {
|
|
499
|
+
console.log(` 1. Fix the ${errors} error(s) above`);
|
|
500
|
+
console.log(` 2. Run: ${C.cyan}npx nightpay validate${C.reset}`);
|
|
501
|
+
} else {
|
|
502
|
+
console.log(` 1. ${C.cyan}bash skills/nightpay/scripts/gateway.sh stats${C.reset} — check contract`);
|
|
503
|
+
console.log(` 2. ${C.cyan}bash skills/nightpay/scripts/gateway.sh post-bounty "Review this PR" 5000${C.reset}`);
|
|
504
|
+
}
|
|
505
|
+
console.log(`\n ${C.dim}Python SDK:${C.reset} from nightpay_sdk import NightPay; NightPay().stats()`);
|
|
506
|
+
console.log(` ${C.dim}Self-heal:${C.reset} npx nightpay doctor`);
|
|
311
507
|
console.log("");
|
|
312
508
|
}
|
|
313
509
|
|