ccsidekick 1.0.0 → 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/README.md +47 -9
- package/dist/ccsidekick-render.js +33 -34
- package/dist/ccsidekick.js +1209 -2425
- package/package.json +7 -7
package/README.md
CHANGED
|
@@ -9,20 +9,58 @@ path and disableable.
|
|
|
9
9
|
npx ccsidekick
|
|
10
10
|
```
|
|
11
11
|
|
|
12
|
-
Running `ccsidekick` in a terminal opens the setup
|
|
13
|
-
|
|
14
|
-
|
|
12
|
+
Running `ccsidekick` in a terminal opens the setup UI: a first run walks you through a short guided
|
|
13
|
+
wizard (character, theme, comments), a later run opens the full dashboard. Either way it picks a
|
|
14
|
+
Claude config dir and wires the status line and the tool-call hooks into your `settings.json`.
|
|
15
|
+
Remove it with `npx ccsidekick uninstall`.
|
|
16
|
+
|
|
17
|
+
## Non-interactive setup (for scripts and AI agents)
|
|
18
|
+
|
|
19
|
+
No TTY required. `ccsidekick setup` configures and wires everything from flags, so an agent can
|
|
20
|
+
install it in one command:
|
|
21
|
+
|
|
22
|
+
```bash
|
|
23
|
+
ccsidekick setup --character batman --theme houston --mode fixed
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
Only the flags you pass are applied (a partial patch onto the existing config, or the defaults on a
|
|
27
|
+
fresh install), then it writes `config.toml` and wires `settings.json` exactly like the TUI.
|
|
28
|
+
|
|
29
|
+
| Flag | Sets |
|
|
30
|
+
| ------------------------ | --------------------------------------------------------------- |
|
|
31
|
+
| `--character <name>` | the fixed character |
|
|
32
|
+
| `--mode <fixed\|random>` | fixed one character, or rotate the roster |
|
|
33
|
+
| `--roster <a,b,c>` | the random-mode roster |
|
|
34
|
+
| `--theme <name>` | a theme, or `character` (the default) to match the character |
|
|
35
|
+
| `--currency <code>` | statusline currency, e.g. `USD` |
|
|
36
|
+
| `--budget <usd>` | monthly budget |
|
|
37
|
+
| `--comments <on\|off>` | the character's comment line |
|
|
38
|
+
| `--helpful <on\|off>` | the helpful-tip line |
|
|
39
|
+
| `--min-severity <sev>` | `low\|medium\|high\|critical` |
|
|
40
|
+
| `--widgets <a,b,c>` | statusline widgets to enable (others turn off) |
|
|
41
|
+
| `--global` / `--local` | save target (default global) |
|
|
42
|
+
| `--config-dir <path>` | Claude config dir (default `$CLAUDE_CONFIG_DIR` or `~/.claude`) |
|
|
43
|
+
|
|
44
|
+
Discover valid values for scripting, and see every flag:
|
|
45
|
+
|
|
46
|
+
```bash
|
|
47
|
+
ccsidekick list characters # also: themes, widgets
|
|
48
|
+
ccsidekick setup --help
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
An unknown value (e.g. a misspelled theme) exits non-zero and prints the valid set — it never
|
|
52
|
+
silently falls back.
|
|
15
53
|
|
|
16
54
|
## The two binaries
|
|
17
55
|
|
|
18
56
|
- **`ccsidekick-render`** is the hot path. Claude Code calls `ccsidekick-render render` on every
|
|
19
|
-
status-line tick and `ccsidekick-render classify` on every tool call. It loads no UI and runs
|
|
20
|
-
plain Node.
|
|
21
|
-
- **`ccsidekick`** is the
|
|
22
|
-
interface.
|
|
57
|
+
status-line tick and `ccsidekick-render classify` on every tool call. It loads no UI and runs
|
|
58
|
+
under plain Node.
|
|
59
|
+
- **`ccsidekick`** is the user-facing entry: the setup UI, plus `setup`, `list`, and `uninstall`.
|
|
60
|
+
Only the TUI loads the Ink interface; `setup`/`list`/`uninstall` run under plain Node.
|
|
23
61
|
|
|
24
|
-
|
|
25
|
-
|
|
62
|
+
Every character ships bundled as a runtime dependency, so a fresh install has them all — there is no
|
|
63
|
+
download or install step, and no network to pick a character.
|
|
26
64
|
|
|
27
65
|
For the full feature tour, configuration reference, and contributor docs, see the
|
|
28
66
|
[repository README](https://github.com/krayong/ccsidekick#readme).
|
|
@@ -2428,11 +2428,10 @@ var DEFAULT_WIDGETS = {
|
|
|
2428
2428
|
var DEFAULT_CONFIG = {
|
|
2429
2429
|
schema_version: 1,
|
|
2430
2430
|
character: { enabled: true, mode: "random", name: "batman", roster: [] },
|
|
2431
|
-
|
|
2432
|
-
|
|
2433
|
-
|
|
2434
|
-
|
|
2435
|
-
network: { fx_refresh: true, usage_fetch: true, balance_path: "" }
|
|
2431
|
+
theme: { name: "character", banding: "solid", mood_shift: false, icons: {} },
|
|
2432
|
+
comments: { character: true, helpful: true, min_severity: "low" },
|
|
2433
|
+
network: { fx_refresh: true, usage_fetch: true, balance_path: "" },
|
|
2434
|
+
statusline: { currency: defaultCurrency(), widgets: DEFAULT_WIDGETS }
|
|
2436
2435
|
};
|
|
2437
2436
|
var obj = (v) => v !== null && typeof v === "object" ? v : {};
|
|
2438
2437
|
var bool = (v, d) => typeof v === "boolean" ? v : d;
|
|
@@ -2475,10 +2474,9 @@ function loadConfig(globalToml = "", projectToml = "") {
|
|
|
2475
2474
|
const p = safeParse(projectToml);
|
|
2476
2475
|
const character = section(g, p, "character");
|
|
2477
2476
|
const comments = section(g, p, "comments");
|
|
2478
|
-
const helpful = section(g, p, "helpful");
|
|
2479
|
-
const line = section(g, p, "line");
|
|
2480
2477
|
const theme = section(g, p, "theme");
|
|
2481
2478
|
const network = section(g, p, "network");
|
|
2479
|
+
const statusline = section(g, p, "statusline");
|
|
2482
2480
|
const d = DEFAULT_CONFIG;
|
|
2483
2481
|
return {
|
|
2484
2482
|
schema_version: numv(p["schema_version"] ?? g["schema_version"], d.schema_version),
|
|
@@ -2488,21 +2486,6 @@ function loadConfig(globalToml = "", projectToml = "") {
|
|
|
2488
2486
|
name: str(character["name"], d.character.name),
|
|
2489
2487
|
roster: stringArray(character["roster"], d.character.roster)
|
|
2490
2488
|
},
|
|
2491
|
-
comments: {
|
|
2492
|
-
enabled: bool(comments["enabled"], d.comments.enabled)
|
|
2493
|
-
},
|
|
2494
|
-
helpful: {
|
|
2495
|
-
enabled: bool(helpful["enabled"], d.helpful.enabled),
|
|
2496
|
-
min_severity: oneOf(helpful["min_severity"], ["low", "medium", "high", "critical"], d.helpful.min_severity)
|
|
2497
|
-
},
|
|
2498
|
-
line: {
|
|
2499
|
-
currency: str(line["currency"], d.line.currency),
|
|
2500
|
-
...typeof line["budget"] === "number" ? { budget: line["budget"] } : {},
|
|
2501
|
-
widgets: mergeWidgets({
|
|
2502
|
-
...obj(obj(g["line"])["widgets"]),
|
|
2503
|
-
...obj(obj(p["line"])["widgets"])
|
|
2504
|
-
})
|
|
2505
|
-
},
|
|
2506
2489
|
theme: {
|
|
2507
2490
|
name: str(theme["name"], d.theme.name),
|
|
2508
2491
|
...typeof theme["statusline"] === "string" ? { statusline: theme["statusline"] } : {},
|
|
@@ -2515,10 +2498,23 @@ function loadConfig(globalToml = "", projectToml = "") {
|
|
|
2515
2498
|
...obj(obj(p["theme"])["icons"])
|
|
2516
2499
|
})
|
|
2517
2500
|
},
|
|
2501
|
+
comments: {
|
|
2502
|
+
character: bool(comments["character"], d.comments.character),
|
|
2503
|
+
helpful: bool(comments["helpful"], d.comments.helpful),
|
|
2504
|
+
min_severity: oneOf(comments["min_severity"], ["low", "medium", "high", "critical"], d.comments.min_severity)
|
|
2505
|
+
},
|
|
2518
2506
|
network: {
|
|
2519
2507
|
fx_refresh: bool(network["fx_refresh"], d.network.fx_refresh),
|
|
2520
2508
|
usage_fetch: bool(network["usage_fetch"], d.network.usage_fetch),
|
|
2521
2509
|
balance_path: str(network["balance_path"], d.network.balance_path)
|
|
2510
|
+
},
|
|
2511
|
+
statusline: {
|
|
2512
|
+
currency: str(statusline["currency"], d.statusline.currency),
|
|
2513
|
+
...typeof statusline["budget"] === "number" ? { budget: statusline["budget"] } : {},
|
|
2514
|
+
widgets: mergeWidgets({
|
|
2515
|
+
...obj(obj(g["statusline"])["widgets"]),
|
|
2516
|
+
...obj(obj(p["statusline"])["widgets"])
|
|
2517
|
+
})
|
|
2522
2518
|
}
|
|
2523
2519
|
};
|
|
2524
2520
|
}
|
|
@@ -6490,22 +6486,22 @@ var HELPFUL_CATALOG = [
|
|
|
6490
6486
|
render: (i) => `Large diff: +${i.git?.insertions ?? 0}/-${i.git?.deletions ?? 0}. Review in chunks.`
|
|
6491
6487
|
},
|
|
6492
6488
|
{
|
|
6493
|
-
id: "
|
|
6489
|
+
id: "diverged",
|
|
6494
6490
|
severity: "medium",
|
|
6495
6491
|
category: "git",
|
|
6496
6492
|
momentary: false,
|
|
6497
|
-
template: "{
|
|
6498
|
-
test: (i) => behind(i.git) > 0,
|
|
6499
|
-
render: (i) =>
|
|
6493
|
+
template: "Diverged {ahead}↑ {behind}↓. `git pull --rebase` keeps history linear.",
|
|
6494
|
+
test: (i) => ahead(i.git) > 0 && behind(i.git) > 0,
|
|
6495
|
+
render: (i) => `Diverged ${ahead(i.git)}↑ ${behind(i.git)}↓. \`git pull --rebase\` keeps history linear.`
|
|
6500
6496
|
},
|
|
6501
6497
|
{
|
|
6502
|
-
id: "
|
|
6498
|
+
id: "behind_upstream",
|
|
6503
6499
|
severity: "medium",
|
|
6504
6500
|
category: "git",
|
|
6505
6501
|
momentary: false,
|
|
6506
|
-
template: "
|
|
6507
|
-
test: (i) =>
|
|
6508
|
-
render: (i) =>
|
|
6502
|
+
template: "{behind} behind upstream. Pull before your next commit knots the merge.",
|
|
6503
|
+
test: (i) => behind(i.git) > 0,
|
|
6504
|
+
render: (i) => `${behind(i.git)} behind upstream. Pull before your next commit knots the merge.`
|
|
6509
6505
|
},
|
|
6510
6506
|
{
|
|
6511
6507
|
id: "dirty_default_branch",
|
|
@@ -7185,8 +7181,11 @@ function build(stdin, env, term, clock, overrides) {
|
|
|
7185
7181
|
git,
|
|
7186
7182
|
payload,
|
|
7187
7183
|
scan,
|
|
7188
|
-
widgets: config.
|
|
7189
|
-
currency: {
|
|
7184
|
+
widgets: config.statusline.widgets,
|
|
7185
|
+
currency: {
|
|
7186
|
+
code: config.statusline.currency,
|
|
7187
|
+
rate: fxTable[config.statusline.currency] ?? 0
|
|
7188
|
+
},
|
|
7190
7189
|
homeDir: env["HOME"] ?? ""
|
|
7191
7190
|
};
|
|
7192
7191
|
const composed = composeStatusline(composeInputs);
|
|
@@ -7204,7 +7203,7 @@ function build(stdin, env, term, clock, overrides) {
|
|
|
7204
7203
|
creds,
|
|
7205
7204
|
balance
|
|
7206
7205
|
};
|
|
7207
|
-
const helpfulResult = config.helpful
|
|
7206
|
+
const helpfulResult = config.comments.helpful ? resolveHelpful(helpfulInputs, sessionState, clock, config.comments.min_severity) : { comment: null, nextHelpful: sessionState.helpful };
|
|
7208
7207
|
const helpful = helpfulResult.comment;
|
|
7209
7208
|
const pending = pendingMilestones(familiarity, clock);
|
|
7210
7209
|
const charBase = {
|
|
@@ -7225,7 +7224,7 @@ function build(stdin, env, term, clock, overrides) {
|
|
|
7225
7224
|
state: sessionState,
|
|
7226
7225
|
clock,
|
|
7227
7226
|
session,
|
|
7228
|
-
config: { enabled: config.comments.
|
|
7227
|
+
config: { enabled: config.comments.character }
|
|
7229
7228
|
});
|
|
7230
7229
|
} catch {
|
|
7231
7230
|
charResult = { comment: null, nextState: charBase };
|