claude-rpc 0.3.11 → 0.6.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/src/ui.js ADDED
@@ -0,0 +1,89 @@
1
+ // Shared CLI output primitives.
2
+ //
3
+ // Three duplicates of the same ANSI table + symbol set existed in cli.js,
4
+ // doctor.js, and tui.js. This is the one place; everything else imports.
5
+ //
6
+ // All output goes to stdout/stderr via console.log/console.error. The
7
+ // daemon's file-bound `log()` is a separate concern (no tty, no color)
8
+ // and stays in src/daemon.js — these helpers are for human-facing
9
+ // surfaces only.
10
+ //
11
+ // Standard exit codes (also documented in --help):
12
+ // 0 success
13
+ // 1 user error — bad args, unknown command, malformed input
14
+ // 2 system error — IO failed, Discord unreachable, etc.
15
+ // 3 wrong state — daemon already running, no aggregate yet, etc.
16
+
17
+ import process from 'node:process';
18
+
19
+ const TTY = process.stdout.isTTY && !process.env.NO_COLOR;
20
+
21
+ export const c = {
22
+ reset: TTY ? '\x1b[0m' : '',
23
+ dim: TTY ? '\x1b[2m' : '',
24
+ bold: TTY ? '\x1b[1m' : '',
25
+ red: TTY ? '\x1b[31m' : '',
26
+ green: TTY ? '\x1b[32m' : '',
27
+ yellow: TTY ? '\x1b[33m' : '',
28
+ blue: TTY ? '\x1b[34m' : '',
29
+ magenta: TTY ? '\x1b[35m' : '',
30
+ cyan: TTY ? '\x1b[36m' : '',
31
+ gray: TTY ? '\x1b[90m' : '',
32
+ };
33
+
34
+ export const SYM_OK = TTY ? `${c.green}✓${c.reset}` : '[ok] ';
35
+ export const SYM_FAIL = TTY ? `${c.red}✗${c.reset}` : '[fail]';
36
+ export const SYM_WARN = TTY ? `${c.yellow}!${c.reset}` : '[warn]';
37
+ export const SYM_INFO = TTY ? `${c.cyan}·${c.reset}` : '[info]';
38
+
39
+ // Standard exit-code values. Use these instead of process.exit(1) so
40
+ // intent is visible in the source.
41
+ export const EX_OK = 0;
42
+ export const EX_USER_ERROR = 1;
43
+ export const EX_SYS_ERROR = 2;
44
+ export const EX_BAD_STATE = 3;
45
+
46
+ // Print a one-line message plus an indented dim hint on the next line.
47
+ // Hint is the tired-user safety net: every failure surface tells you
48
+ // what to type next. Empty hint omits the second line.
49
+ function withHint(sym, label, hint, stream = process.stdout) {
50
+ stream.write(` ${sym} ${label}\n`);
51
+ if (hint) stream.write(` ${c.gray}↳ ${hint}${c.reset}\n`);
52
+ }
53
+
54
+ export function ok(label, detail = '') {
55
+ process.stdout.write(` ${SYM_OK} ${label}${detail ? ` ${c.dim}${detail}${c.reset}` : ''}\n`);
56
+ }
57
+
58
+ export function info(label, detail = '') {
59
+ process.stdout.write(` ${SYM_INFO} ${label}${detail ? ` ${c.dim}${detail}${c.reset}` : ''}\n`);
60
+ }
61
+
62
+ export function warn(label, hint = '') {
63
+ withHint(SYM_WARN, label, hint);
64
+ }
65
+
66
+ // Print a failure with a hint and exit with the given code. The hint is
67
+ // the difference between a frustrated user and a fixed user — always
68
+ // supply one when you can, and default it to `claude-rpc doctor` when
69
+ // you have no better idea.
70
+ export function fail(label, { hint = 'run `claude-rpc doctor` for a full diagnostic', code = EX_USER_ERROR } = {}) {
71
+ withHint(SYM_FAIL, label, hint, process.stderr);
72
+ process.exit(code);
73
+ }
74
+
75
+ // Compatibility with doctor.js's existing API. Same `check(label, status,
76
+ // detail, hint)` signature; doctor.js can switch its private copy out for
77
+ // this without behavior change.
78
+ export function check(label, status, detail = '', hint = '') {
79
+ let sym;
80
+ if (status === 'pass') sym = SYM_OK;
81
+ else if (status === 'fail') sym = SYM_FAIL;
82
+ else if (status === 'warn') sym = SYM_WARN;
83
+ else sym = SYM_INFO;
84
+ const tail = detail ? ` ${c.dim}${detail}${c.reset}` : '';
85
+ process.stdout.write(` ${sym} ${label}${tail}\n`);
86
+ if (hint && status !== 'pass') {
87
+ process.stdout.write(` ${c.gray}↳ ${hint}${c.reset}\n`);
88
+ }
89
+ }
package/src/version.js ADDED
@@ -0,0 +1,26 @@
1
+ // Single source of truth for the user-visible version string.
2
+ //
3
+ // Read from package.json at module load (works in dev + npm-installed
4
+ // modes). For packaged SEA exes, package.json isn't shipped — `npm run
5
+ // build:exe` snapshots whatever package.json holds at build time and
6
+ // the BAKED fallback below catches the SEA-only "package.json missing"
7
+ // case. Bump BAKED when cutting a release; the test in
8
+ // test/version.test.js asserts the two stay in sync.
9
+
10
+ import { readFileSync } from 'node:fs';
11
+ import { join } from 'node:path';
12
+ import { ROOT } from './paths.js';
13
+
14
+ const BAKED = '0.6.0';
15
+
16
+ function readPkgVersion() {
17
+ try {
18
+ const pkg = JSON.parse(readFileSync(join(ROOT, 'package.json'), 'utf8'));
19
+ if (pkg && typeof pkg.version === 'string') return pkg.version;
20
+ } catch {
21
+ // package.json not on disk (SEA exe) or unreadable — fall back to BAKED.
22
+ }
23
+ return BAKED;
24
+ }
25
+
26
+ export const VERSION = readPkgVersion();