@umang-boss/claudemon 1.4.0 → 1.5.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/bin/claudemon.js +11 -3
- package/cli/doctor.ts +52 -2
- package/cli/index.ts +26 -8
- package/cli/shared.ts +14 -9
- package/dist/award-xp.mjs +7395 -0
- package/dist/award-xp.mjs.map +7 -0
- package/dist/cli.mjs +7497 -0
- package/dist/cli.mjs.map +7 -0
- package/dist/increment-counter.mjs +6323 -0
- package/dist/increment-counter.mjs.map +7 -0
- package/dist/server.mjs +10176 -0
- package/dist/server.mjs.map +7 -0
- package/hooks/post-tool-use.sh +22 -13
- package/package.json +6 -4
- package/scripts/build.ts +64 -0
- package/skills/buddy/SKILL.md +1 -0
- package/src/engine/stats.ts +7 -6
- package/src/engine/types.ts +1 -0
- package/src/engine/version-check.ts +167 -0
- package/src/hooks/award-xp.ts +18 -0
- package/src/server/index.ts +14 -0
- package/src/server/instructions.ts +20 -10
- package/src/server/tools/display-helpers.ts +2 -2
- package/src/server/tools/settings.ts +51 -10
- package/src/server/tools/starter.ts +3 -5
- package/src/state/schemas.ts +1 -0
- package/src/state/state-manager.ts +67 -11
- package/statusline/buddy-status.sh +21 -2
- package/dist/cli/doctor.js +0 -280
- package/dist/cli/index.js +0 -40
- package/dist/cli/install.js +0 -198
- package/dist/cli/shared.js +0 -77
- package/dist/cli/uninstall.js +0 -120
- package/dist/cli/update.js +0 -265
- package/dist/src/engine/constants.js +0 -104
- package/dist/src/engine/encounter-pool.js +0 -48
- package/dist/src/engine/encounters.js +0 -282
- package/dist/src/engine/evolution-data.js +0 -454
- package/dist/src/engine/evolution.js +0 -238
- package/dist/src/engine/mood.js +0 -187
- package/dist/src/engine/pokemon-data.js +0 -1751
- package/dist/src/engine/reactions.js +0 -834
- package/dist/src/engine/starter-pool.js +0 -46
- package/dist/src/engine/stats.js +0 -79
- package/dist/src/engine/types.js +0 -78
- package/dist/src/engine/xp.js +0 -108
- package/dist/src/gamification/achievements.js +0 -176
- package/dist/src/gamification/legendary-quests.js +0 -233
- package/dist/src/gamification/milestones.js +0 -65
- package/dist/src/hooks/award-xp.js +0 -164
- package/dist/src/hooks/increment-counter.js +0 -20
- package/dist/src/server/index.js +0 -75
- package/dist/src/server/instructions.js +0 -178
- package/dist/src/server/tools/achievements.js +0 -96
- package/dist/src/server/tools/catch.js +0 -251
- package/dist/src/server/tools/display-helpers.js +0 -27
- package/dist/src/server/tools/evolve.js +0 -190
- package/dist/src/server/tools/feed.js +0 -120
- package/dist/src/server/tools/legendary.js +0 -57
- package/dist/src/server/tools/party.js +0 -205
- package/dist/src/server/tools/pet.js +0 -99
- package/dist/src/server/tools/play.js +0 -310
- package/dist/src/server/tools/pokedex.js +0 -234
- package/dist/src/server/tools/rename.js +0 -57
- package/dist/src/server/tools/settings.js +0 -80
- package/dist/src/server/tools/show.js +0 -115
- package/dist/src/server/tools/starter.js +0 -186
- package/dist/src/server/tools/stats.js +0 -96
- package/dist/src/server/tools/train.js +0 -144
- package/dist/src/server/tools/visibility.js +0 -52
- package/dist/src/sprites/index.js +0 -43
- package/dist/src/state/io.js +0 -78
- package/dist/src/state/schemas.js +0 -113
- package/dist/src/state/state-manager.js +0 -288
package/bin/claudemon.js
CHANGED
|
@@ -12,17 +12,25 @@ import { fileURLToPath } from "node:url";
|
|
|
12
12
|
const __dirname = dirname(fileURLToPath(import.meta.url));
|
|
13
13
|
const args = process.argv.slice(2);
|
|
14
14
|
|
|
15
|
-
// Try
|
|
16
|
-
const distCli = resolve(__dirname, "..", "dist", "cli
|
|
15
|
+
// Try bundled ESM first, then old tsc output, then fall back to TS with bun
|
|
16
|
+
const distCli = resolve(__dirname, "..", "dist", "cli.mjs");
|
|
17
|
+
const distCliLegacy = resolve(__dirname, "..", "dist", "cli", "index.js");
|
|
17
18
|
const srcCli = resolve(__dirname, "..", "cli", "index.ts");
|
|
18
19
|
|
|
19
20
|
if (existsSync(distCli)) {
|
|
20
|
-
// Run
|
|
21
|
+
// Run bundled ESM with node
|
|
21
22
|
const result = spawnSync("node", [distCli, ...args], {
|
|
22
23
|
stdio: "inherit",
|
|
23
24
|
env: process.env,
|
|
24
25
|
});
|
|
25
26
|
process.exit(result.status ?? 1);
|
|
27
|
+
} else if (existsSync(distCliLegacy)) {
|
|
28
|
+
// Run legacy tsc-compiled JS with node
|
|
29
|
+
const result = spawnSync("node", [distCliLegacy, ...args], {
|
|
30
|
+
stdio: "inherit",
|
|
31
|
+
env: process.env,
|
|
32
|
+
});
|
|
33
|
+
process.exit(result.status ?? 1);
|
|
26
34
|
} else {
|
|
27
35
|
// Fallback: try bun with source TS
|
|
28
36
|
const home = process.env.HOME || "";
|
package/cli/doctor.ts
CHANGED
|
@@ -6,12 +6,13 @@
|
|
|
6
6
|
*/
|
|
7
7
|
|
|
8
8
|
import { access, stat, unlink, readdir, readFile } from "node:fs/promises";
|
|
9
|
-
import { constants as fsConstants } from "node:fs";
|
|
9
|
+
import { constants as fsConstants, existsSync } from "node:fs";
|
|
10
10
|
import { resolve, dirname } from "node:path";
|
|
11
11
|
import { fileURLToPath } from "node:url";
|
|
12
12
|
import { spawnSync } from "node:child_process";
|
|
13
13
|
import { StateManager } from "../src/state/state-manager.js";
|
|
14
14
|
import { PlayerStateSchema } from "../src/state/schemas.js";
|
|
15
|
+
import { checkForUpdate, getCurrentVersion } from "../src/engine/version-check.js";
|
|
15
16
|
|
|
16
17
|
import type { ClaudeConfig, ClaudeSettings } from "./shared.js";
|
|
17
18
|
import {
|
|
@@ -32,7 +33,20 @@ const LOCK_MAX_AGE_MS = 5000;
|
|
|
32
33
|
const EXPECTED_SPRITE_COUNT = 151;
|
|
33
34
|
const __filename = fileURLToPath(import.meta.url);
|
|
34
35
|
const __dirname = dirname(__filename);
|
|
35
|
-
|
|
36
|
+
// Sprite dir: check multiple candidate paths (works from source, dist, and npm global)
|
|
37
|
+
function findColorscriptDir(): string | null {
|
|
38
|
+
const candidates = [
|
|
39
|
+
resolve(dirname(__dirname), "sprites", "colorscripts", "small"),
|
|
40
|
+
resolve(dirname(__dirname), "..", "sprites", "colorscripts", "small"),
|
|
41
|
+
resolve(__dirname, "..", "sprites", "colorscripts", "small"),
|
|
42
|
+
resolve(__dirname, "..", "..", "sprites", "colorscripts", "small"),
|
|
43
|
+
];
|
|
44
|
+
for (const c of candidates) {
|
|
45
|
+
if (existsSync(c)) return c;
|
|
46
|
+
}
|
|
47
|
+
return null;
|
|
48
|
+
}
|
|
49
|
+
const COLORSCRIPT_DIR = findColorscriptDir();
|
|
36
50
|
|
|
37
51
|
// ── Helpers ──────────────────────────────────────────────────
|
|
38
52
|
|
|
@@ -236,6 +250,9 @@ async function checkStaleLock(): Promise<CheckResult> {
|
|
|
236
250
|
|
|
237
251
|
async function checkSpriteCount(): Promise<CheckResult> {
|
|
238
252
|
try {
|
|
253
|
+
if (!COLORSCRIPT_DIR) {
|
|
254
|
+
return { label: "Sprites", passed: false, detail: "colorscripts directory not found" };
|
|
255
|
+
}
|
|
239
256
|
await access(COLORSCRIPT_DIR, fsConstants.F_OK);
|
|
240
257
|
const entries = await readdir(COLORSCRIPT_DIR);
|
|
241
258
|
const spriteFiles = entries.filter((f) => f.endsWith(".txt"));
|
|
@@ -294,6 +311,38 @@ async function checkStateValidity(): Promise<CheckResult> {
|
|
|
294
311
|
}
|
|
295
312
|
}
|
|
296
313
|
|
|
314
|
+
// ── Check 12: Version ──────────────────────────────────────────
|
|
315
|
+
|
|
316
|
+
async function checkVersion(): Promise<CheckResult> {
|
|
317
|
+
const current = getCurrentVersion();
|
|
318
|
+
if (current === "unknown") {
|
|
319
|
+
return { label: "Version", passed: false, detail: "could not determine current version" };
|
|
320
|
+
}
|
|
321
|
+
|
|
322
|
+
try {
|
|
323
|
+
const result = await checkForUpdate();
|
|
324
|
+
if (!result) {
|
|
325
|
+
return {
|
|
326
|
+
label: "Version",
|
|
327
|
+
passed: true,
|
|
328
|
+
detail: `v${current} (could not reach npm registry)`,
|
|
329
|
+
};
|
|
330
|
+
}
|
|
331
|
+
|
|
332
|
+
if (result.hasUpdate) {
|
|
333
|
+
return {
|
|
334
|
+
label: "Version",
|
|
335
|
+
passed: false,
|
|
336
|
+
detail: `v${current} (v${result.latest} available — run: npm install -g @umang-boss/claudemon)`,
|
|
337
|
+
};
|
|
338
|
+
}
|
|
339
|
+
|
|
340
|
+
return { label: "Version", passed: true, detail: `v${current} (latest)` };
|
|
341
|
+
} catch {
|
|
342
|
+
return { label: "Version", passed: true, detail: `v${current} (check skipped)` };
|
|
343
|
+
}
|
|
344
|
+
}
|
|
345
|
+
|
|
297
346
|
// ── Main ─────────────────────────────────────────────────────
|
|
298
347
|
|
|
299
348
|
export async function doctor(): Promise<void> {
|
|
@@ -303,6 +352,7 @@ export async function doctor(): Promise<void> {
|
|
|
303
352
|
console.log("");
|
|
304
353
|
|
|
305
354
|
const checks: CheckResult[] = [
|
|
355
|
+
await checkVersion(),
|
|
306
356
|
await checkBun(),
|
|
307
357
|
await checkStateDir(),
|
|
308
358
|
await checkStateFile(),
|
package/cli/index.ts
CHANGED
|
@@ -1,19 +1,36 @@
|
|
|
1
1
|
#!/usr/bin/env bun
|
|
2
2
|
/**
|
|
3
3
|
* Claudemon CLI entry point.
|
|
4
|
-
* Routes to install, uninstall, update,
|
|
5
|
-
*
|
|
6
|
-
* Usage:
|
|
7
|
-
* npx claudemon install
|
|
8
|
-
* npx claudemon uninstall
|
|
9
|
-
* npx claudemon update
|
|
10
|
-
* npx claudemon doctor
|
|
4
|
+
* Routes to install, uninstall, update, doctor, or --version.
|
|
11
5
|
*/
|
|
12
6
|
|
|
7
|
+
import { readFileSync } from "node:fs";
|
|
8
|
+
import { resolve, dirname } from "node:path";
|
|
9
|
+
import { fileURLToPath } from "node:url";
|
|
10
|
+
|
|
13
11
|
export {};
|
|
14
12
|
const command = process.argv[2];
|
|
15
13
|
|
|
16
14
|
switch (command) {
|
|
15
|
+
case "--version":
|
|
16
|
+
case "-v":
|
|
17
|
+
case "version": {
|
|
18
|
+
const __dirname = dirname(fileURLToPath(import.meta.url));
|
|
19
|
+
const pkgPaths = [
|
|
20
|
+
resolve(__dirname, "..", "package.json"),
|
|
21
|
+
resolve(__dirname, "..", "..", "package.json"),
|
|
22
|
+
];
|
|
23
|
+
for (const p of pkgPaths) {
|
|
24
|
+
try {
|
|
25
|
+
const pkg = JSON.parse(readFileSync(p, "utf-8")) as { version: string };
|
|
26
|
+
console.log(`claudemon v${pkg.version}`);
|
|
27
|
+
break;
|
|
28
|
+
} catch {
|
|
29
|
+
continue;
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
break;
|
|
33
|
+
}
|
|
17
34
|
case "install":
|
|
18
35
|
await import("./install.js");
|
|
19
36
|
break;
|
|
@@ -28,13 +45,14 @@ switch (command) {
|
|
|
28
45
|
break;
|
|
29
46
|
default:
|
|
30
47
|
console.log(`
|
|
31
|
-
Claudemon — Pokemon
|
|
48
|
+
Claudemon — Pokemon coding companion for Claude Code
|
|
32
49
|
|
|
33
50
|
Usage:
|
|
34
51
|
claudemon install Set up Claudemon (MCP server, hooks, skill, status line)
|
|
35
52
|
claudemon uninstall Remove Claudemon from Claude Code
|
|
36
53
|
claudemon update Re-register everything (preserves save data)
|
|
37
54
|
claudemon doctor Run diagnostics
|
|
55
|
+
claudemon --version Show version
|
|
38
56
|
|
|
39
57
|
After install, start a new Claude Code session and type /buddy
|
|
40
58
|
`);
|
package/cli/shared.ts
CHANGED
|
@@ -5,7 +5,8 @@
|
|
|
5
5
|
|
|
6
6
|
import { resolve, dirname } from "node:path";
|
|
7
7
|
import { fileURLToPath } from "node:url";
|
|
8
|
-
import { existsSync } from "node:fs";
|
|
8
|
+
import { existsSync, constants as fsConstants } from "node:fs";
|
|
9
|
+
import { readFile, writeFile, access as fsAccess } from "node:fs/promises";
|
|
9
10
|
|
|
10
11
|
// ── Config shape interfaces ──────────────────────────────────
|
|
11
12
|
|
|
@@ -73,11 +74,13 @@ export const STOP_HOOK_SCRIPT = `${PROJECT_DIR}/hooks/stop.sh`;
|
|
|
73
74
|
export const USER_PROMPT_HOOK_SCRIPT = `${PROJECT_DIR}/hooks/user-prompt-submit.sh`;
|
|
74
75
|
export const STATUSLINE_SCRIPT = `${PROJECT_DIR}/statusline/buddy-status.sh`;
|
|
75
76
|
export const SERVER_ENTRY_TS = `${PROJECT_DIR}/src/server/index.ts`;
|
|
76
|
-
export const SERVER_ENTRY_JS = `${PROJECT_DIR}/dist/
|
|
77
|
+
export const SERVER_ENTRY_JS = `${PROJECT_DIR}/dist/server.mjs`;
|
|
78
|
+
/** Legacy tsc output path — kept for backward compatibility */
|
|
79
|
+
export const SERVER_ENTRY_JS_LEGACY = `${PROJECT_DIR}/dist/src/server/index.js`;
|
|
77
80
|
|
|
78
|
-
/** Find the best runtime
|
|
81
|
+
/** Find the best runtime — Bun (fastest) > bundled node > legacy node */
|
|
79
82
|
export function getRuntime(): { command: string; serverEntry: string } {
|
|
80
|
-
//
|
|
83
|
+
// Prefer bun (fastest — native TS, ~120ms startup)
|
|
81
84
|
const bunCandidates = [`${HOME}/.bun/bin/bun`, "/usr/local/bin/bun", "/usr/bin/bun"];
|
|
82
85
|
for (const p of bunCandidates) {
|
|
83
86
|
if (existsSync(p)) {
|
|
@@ -85,11 +88,16 @@ export function getRuntime(): { command: string; serverEntry: string } {
|
|
|
85
88
|
}
|
|
86
89
|
}
|
|
87
90
|
|
|
88
|
-
//
|
|
91
|
+
// No bun — use bundled ESM with node (~600ms but works everywhere)
|
|
89
92
|
if (existsSync(SERVER_ENTRY_JS)) {
|
|
90
93
|
return { command: "node", serverEntry: SERVER_ENTRY_JS };
|
|
91
94
|
}
|
|
92
95
|
|
|
96
|
+
// Fall back to legacy tsc output
|
|
97
|
+
if (existsSync(SERVER_ENTRY_JS_LEGACY)) {
|
|
98
|
+
return { command: "node", serverEntry: SERVER_ENTRY_JS_LEGACY };
|
|
99
|
+
}
|
|
100
|
+
|
|
93
101
|
// Last resort: assume bun in PATH
|
|
94
102
|
return { command: "bun", serverEntry: SERVER_ENTRY_TS };
|
|
95
103
|
}
|
|
@@ -109,10 +117,8 @@ export function info(msg: string): void {
|
|
|
109
117
|
}
|
|
110
118
|
|
|
111
119
|
export async function readJson<T>(path: string): Promise<T | null> {
|
|
112
|
-
const { readFile, access } = await import("node:fs/promises");
|
|
113
|
-
const { constants } = await import("node:fs");
|
|
114
120
|
try {
|
|
115
|
-
await
|
|
121
|
+
await fsAccess(path, fsConstants.F_OK);
|
|
116
122
|
const text = await readFile(path, "utf-8");
|
|
117
123
|
return JSON.parse(text) as T;
|
|
118
124
|
} catch {
|
|
@@ -121,6 +127,5 @@ export async function readJson<T>(path: string): Promise<T | null> {
|
|
|
121
127
|
}
|
|
122
128
|
|
|
123
129
|
export async function writeJson(path: string, data: unknown): Promise<void> {
|
|
124
|
-
const { writeFile } = await import("node:fs/promises");
|
|
125
130
|
await writeFile(path, JSON.stringify(data, null, 2) + "\n", "utf-8");
|
|
126
131
|
}
|