@cc-status-line/cli 0.1.5
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 +44 -0
- package/README.md.full +248 -0
- package/bin/ccs.js +2 -0
- package/index.js +77 -0
- package/package.json +43 -0
- package/postinstall.js +36 -0
package/README.md
ADDED
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
# @cc-status-line/cli
|
|
2
|
+
|
|
3
|
+
Multi-line, mode-switchable status line for [Claude Code](https://docs.claude.com/en/docs/claude-code).
|
|
4
|
+
|
|
5
|
+
Pure Rust binary, distributed through npm so any Claude Code user can install it without a Rust toolchain.
|
|
6
|
+
|
|
7
|
+
## Quick start
|
|
8
|
+
|
|
9
|
+
```sh
|
|
10
|
+
npx -y @cc-status-line/cli --version
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
Then in `~/.claude/settings.json`:
|
|
14
|
+
|
|
15
|
+
```json
|
|
16
|
+
{
|
|
17
|
+
"statusLine": {
|
|
18
|
+
"type": "command",
|
|
19
|
+
"command": "npx -y @cc-status-line/cli render"
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
For best performance install globally so the binary is on PATH:
|
|
25
|
+
|
|
26
|
+
```sh
|
|
27
|
+
npm install -g @cc-status-line/cli
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
Then:
|
|
31
|
+
|
|
32
|
+
```json
|
|
33
|
+
{
|
|
34
|
+
"statusLine": {
|
|
35
|
+
"type": "command",
|
|
36
|
+
"command": "ccs render"
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
## Documentation
|
|
42
|
+
|
|
43
|
+
Full README, architecture, and Chinese usage guide:
|
|
44
|
+
<https://github.com/hankeGui/cc-status>
|
package/README.md.full
ADDED
|
@@ -0,0 +1,248 @@
|
|
|
1
|
+
# cc-status
|
|
2
|
+
|
|
3
|
+
> Multi-line, mode-switchable status line for [Claude Code](https://docs.claude.com/en/docs/claude-code) — written in Rust, no daemon, ~20 ms render.
|
|
4
|
+
|
|
5
|
+
```
|
|
6
|
+
~/hanke-dev/cc-status main Claude Opus 4.7 ctx 86% █████▏ 154.6k/950k
|
|
7
|
+
```
|
|
8
|
+
|
|
9
|
+
```
|
|
10
|
+
~/hanke-dev/cc-status main Claude Opus 4.7
|
|
11
|
+
ctx 86% █████▏ 154.6k/950k ↑154.6k ↓185 +687 🎯99% cache 4:47 hit 96% 🔥 32.4k/min
|
|
12
|
+
skills: jira×3 wiki×1 mcp: github×2
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
## Why
|
|
16
|
+
|
|
17
|
+
Most Claude Code status lines stop at "model name + ctx percentage." That hides what actually drives cost and behavior:
|
|
18
|
+
|
|
19
|
+
- How many tokens did the **last turn** burn, and how many were a cache hit (10× cheaper)?
|
|
20
|
+
- Is the **prompt cache** about to expire (5-min TTL)?
|
|
21
|
+
- What's my **session-wide hit rate** — and how fast am I burning tokens?
|
|
22
|
+
- Which **Skills / MCP servers** has this session called?
|
|
23
|
+
- On a 1M-context model, is my percentage actually computed against 1M, or am I about to be auto-compacted at 200k?
|
|
24
|
+
|
|
25
|
+
cc-status answers all of these in three lines and lets you switch modes with a single command.
|
|
26
|
+
|
|
27
|
+
## Install
|
|
28
|
+
|
|
29
|
+
Pick the easiest path for your machine:
|
|
30
|
+
|
|
31
|
+
### npm / npx (recommended for Claude Code users)
|
|
32
|
+
|
|
33
|
+
You already have Node.js if you use Claude Code:
|
|
34
|
+
|
|
35
|
+
```sh
|
|
36
|
+
# One-shot, no install
|
|
37
|
+
npx -y @cc-status-line/cli --version
|
|
38
|
+
|
|
39
|
+
# Or install globally so the binary is on PATH
|
|
40
|
+
npm install -g @cc-status-line/cli
|
|
41
|
+
ccs --version
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
Then in `~/.claude/settings.json`:
|
|
45
|
+
|
|
46
|
+
```json
|
|
47
|
+
{
|
|
48
|
+
"statusLine": {
|
|
49
|
+
"type": "command",
|
|
50
|
+
"command": "ccs render"
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
### Homebrew (macOS / Linux)
|
|
56
|
+
|
|
57
|
+
```sh
|
|
58
|
+
brew install hankeGui/tap/ccs
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
### curl install script
|
|
62
|
+
|
|
63
|
+
```sh
|
|
64
|
+
curl -fsSL https://raw.githubusercontent.com/hankeGui/cc-status/main/install.sh | sh
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
Installs to `~/.local/bin/ccs`. Pass `--bin-dir` or `--version` to customize.
|
|
68
|
+
|
|
69
|
+
### Manual download
|
|
70
|
+
|
|
71
|
+
Pick a tarball from [releases](https://github.com/hankeGui/cc-status/releases), unpack, drop `ccs` somewhere on PATH.
|
|
72
|
+
|
|
73
|
+
### From source (requires Rust)
|
|
74
|
+
|
|
75
|
+
```sh
|
|
76
|
+
cargo install --git https://github.com/hankeGui/cc-status --locked
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
Or clone and build:
|
|
80
|
+
|
|
81
|
+
```sh
|
|
82
|
+
git clone https://github.com/hankeGui/cc-status
|
|
83
|
+
cd cc-status
|
|
84
|
+
cargo build --release
|
|
85
|
+
cp target/release/ccs ~/.local/bin/
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
After installing, hook it into Claude Code:
|
|
89
|
+
|
|
90
|
+
```sh
|
|
91
|
+
ccs setup
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
This inspects `~/.claude/settings.json`, shows the proposed `statusLine`
|
|
95
|
+
change, asks for confirmation, and writes a backup before saving. Pass
|
|
96
|
+
`--yes` to skip the prompt or `--check` to inspect without modifying.
|
|
97
|
+
|
|
98
|
+
Or do it manually — add this to `~/.claude/settings.json`:
|
|
99
|
+
|
|
100
|
+
```json
|
|
101
|
+
{
|
|
102
|
+
"statusLine": {
|
|
103
|
+
"type": "command",
|
|
104
|
+
"command": "/absolute/path/to/ccs render"
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
Use absolute paths — Claude Code's status-line shell does not always inherit your login `PATH`.
|
|
110
|
+
|
|
111
|
+
## Three ways to interact
|
|
112
|
+
|
|
113
|
+
cc-status follows a "passive bar + on-demand panel" design. You don't need to read every metric every turn.
|
|
114
|
+
|
|
115
|
+
### 1. The status line itself
|
|
116
|
+
|
|
117
|
+
The bar at the top of every Claude Code prompt. Choose a layout:
|
|
118
|
+
|
|
119
|
+
```sh
|
|
120
|
+
ccs mode compact # one line, the basics
|
|
121
|
+
ccs mode detailed # three lines, all metrics
|
|
122
|
+
ccs mode debug # six lines, one metric per line with labels
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
Or build your own:
|
|
126
|
+
|
|
127
|
+
```sh
|
|
128
|
+
ccs segments # see all available segments
|
|
129
|
+
ccs mode add mine -l "{dir} {git} {ctx}" \
|
|
130
|
+
-l "{last_turn} {hit_rate}" # define a 2-line mode
|
|
131
|
+
ccs mode mine # switch to it
|
|
132
|
+
ccs mode list # show all modes
|
|
133
|
+
ccs mode rm mine # delete one
|
|
134
|
+
```
|
|
135
|
+
|
|
136
|
+
### 2. The detail panel (`ccs status`)
|
|
137
|
+
|
|
138
|
+
Print a self-explanatory dashboard for the *current session* — every number labeled, every unit annotated:
|
|
139
|
+
|
|
140
|
+
```sh
|
|
141
|
+
ccs status
|
|
142
|
+
```
|
|
143
|
+
|
|
144
|
+
The panel auto-locates the transcript by `cwd`, so it works from anywhere — even outside Claude Code's status-line invocation context.
|
|
145
|
+
|
|
146
|
+
### 3. The legend (`ccs explain`)
|
|
147
|
+
|
|
148
|
+
Forgot what `+865` or `🎯99%` means?
|
|
149
|
+
|
|
150
|
+
```sh
|
|
151
|
+
ccs explain
|
|
152
|
+
```
|
|
153
|
+
|
|
154
|
+
Prints a colored cheat-sheet of every segment, every color, every glyph.
|
|
155
|
+
|
|
156
|
+
## Segments
|
|
157
|
+
|
|
158
|
+
| Token | Output | Meaning |
|
|
159
|
+
|---|---|---|
|
|
160
|
+
| `{dir}` | `~/hanke-dev/cc-status` | Last 3 path components, `~` for HOME |
|
|
161
|
+
| `{git}` | `wt:NAME branch ⇡2⇣1 [+!?]` | Worktree, branch, ahead/behind, dirty flags |
|
|
162
|
+
| `{model}` | `Claude Opus 4.7` | CC's reported model |
|
|
163
|
+
| `{ctx}` | `ctx 86% █████▏ 154.6k/950k` | Remaining %, bar, used / capacity |
|
|
164
|
+
| `{ctx_tokens}` | `154.6k/950k` | Just the token numbers |
|
|
165
|
+
| `{last_turn}` | `↑12.3k ↓2.1k +865 🎯89%` | Last turn input ↑ / output ↓ / cache write + / hit rate 🎯 |
|
|
166
|
+
| `{cache_ttl}` | `cache 3:42` | Prompt-cache 5-min TTL countdown (red < 1 min) |
|
|
167
|
+
| `{hit_rate}` | `hit 96%` | Session-wide cache hit rate |
|
|
168
|
+
| `{burn}` | `🔥 32.4k/min` | Session-average token rate |
|
|
169
|
+
| `{skills}` | `skills: jira×3 wiki×1` | Skill calls, top 4 by count |
|
|
170
|
+
| `{mcp}` | `mcp: github×2` | MCP-server calls, top 4 |
|
|
171
|
+
| `{mode}` | `[detailed]` | Current mode label |
|
|
172
|
+
|
|
173
|
+
## Configuration
|
|
174
|
+
|
|
175
|
+
Lives at `$XDG_CONFIG_HOME/cc-status/config.toml` (macOS: `~/Library/Application Support/dev.hanke.cc-status/config.toml`).
|
|
176
|
+
|
|
177
|
+
```sh
|
|
178
|
+
ccs init # write defaults if missing
|
|
179
|
+
ccs init --force # overwrite existing
|
|
180
|
+
ccs config-path # print resolved path
|
|
181
|
+
```
|
|
182
|
+
|
|
183
|
+
Example:
|
|
184
|
+
|
|
185
|
+
```toml
|
|
186
|
+
current_mode = "detailed"
|
|
187
|
+
|
|
188
|
+
[modes.compact]
|
|
189
|
+
lines = ["{dir} {git} {model} {ctx}"]
|
|
190
|
+
|
|
191
|
+
[modes.detailed]
|
|
192
|
+
lines = [
|
|
193
|
+
"{dir} {git} {model}",
|
|
194
|
+
"{ctx} {last_turn} {cache_ttl} {hit_rate} {burn}",
|
|
195
|
+
"{skills} {mcp}",
|
|
196
|
+
]
|
|
197
|
+
|
|
198
|
+
[theme]
|
|
199
|
+
ctx_low = 20 # red below this remaining %
|
|
200
|
+
ctx_med = 50 # yellow below this
|
|
201
|
+
```
|
|
202
|
+
|
|
203
|
+
Add your own modes — any TOML key under `[modes.X]` becomes selectable via `ccs mode X`.
|
|
204
|
+
|
|
205
|
+
## Capacity calculation (1M context support)
|
|
206
|
+
|
|
207
|
+
`{ctx}` reports `used / capacity` where:
|
|
208
|
+
|
|
209
|
+
```
|
|
210
|
+
physical_window = used_tokens / (1 - CC_remaining_percentage / 100)
|
|
211
|
+
capacity = physical_window × CLAUDE_AUTOCOMPACT_PCT_OVERRIDE / 100
|
|
212
|
+
```
|
|
213
|
+
|
|
214
|
+
In plain English: cc-status backsolves the *real* context window from CC's reported percentage, then applies your auto-compact threshold to show the *usable* capacity — i.e., the point at which Claude Code will trigger auto-compact.
|
|
215
|
+
|
|
216
|
+
Two relevant Claude Code env vars (set in `~/.claude/settings.json` `env` block):
|
|
217
|
+
|
|
218
|
+
| Env var | Meaning | Default |
|
|
219
|
+
|---|---|---|
|
|
220
|
+
| `CLAUDE_CODE_AUTO_COMPACT_WINDOW` | Treat the window as N tokens (e.g. `1000000` for 1M-context models) | model-detected |
|
|
221
|
+
| `CLAUDE_AUTOCOMPACT_PCT_OVERRIDE` | Compact at N % of window | `95` |
|
|
222
|
+
|
|
223
|
+
cc-status reads `CLAUDE_AUTOCOMPACT_PCT_OVERRIDE` from the process env at render time, so the bar always matches Claude Code's actual compact behavior.
|
|
224
|
+
|
|
225
|
+
## Performance
|
|
226
|
+
|
|
227
|
+
- **Render latency**: ~20 ms (mostly forking `git` for status). Well under Claude Code's 300 ms status-line timeout.
|
|
228
|
+
- **Transcript parsing**: incremental — a per-session JSON cache stores the file offset and aggregated counters. Parsing 1 GB of transcript on the first run is the worst case; every subsequent render reads only newly-appended bytes.
|
|
229
|
+
- **No daemon, no socket, no IPC**: a single binary, invoked anew each render. State persists via `$XDG_CACHE_HOME/cc-status/session-*.json`.
|
|
230
|
+
|
|
231
|
+
## Documentation
|
|
232
|
+
|
|
233
|
+
- [中文使用说明](docs/USAGE.zh.md)
|
|
234
|
+
- [Architecture](docs/ARCHITECTURE.md)
|
|
235
|
+
- [Releasing](docs/RELEASING.md) — distribution setup (npm, brew, GitHub Releases)
|
|
236
|
+
- [CLAUDE.md](CLAUDE.md) — project-level context for Claude Code agents
|
|
237
|
+
|
|
238
|
+
## Roadmap
|
|
239
|
+
|
|
240
|
+
- [ ] Daemon mode (Unix socket) for sub-ms cold start
|
|
241
|
+
- [ ] Cost segment with per-model pricing
|
|
242
|
+
- [ ] Per-session colors / titles (parallel CC instances)
|
|
243
|
+
- [ ] Pace-aware quota burn warning
|
|
244
|
+
- [ ] Plugin segments (custom shell commands)
|
|
245
|
+
|
|
246
|
+
## License
|
|
247
|
+
|
|
248
|
+
MIT — see [LICENSE](LICENSE).
|
package/bin/ccs.js
ADDED
package/index.js
ADDED
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
// Resolves the platform-specific native binary and execs it, forwarding
|
|
3
|
+
// argv / stdin / stdout / stderr / exit code transparently.
|
|
4
|
+
//
|
|
5
|
+
// Critical: this must be fast. Claude Code calls `ccs render` on every
|
|
6
|
+
// status-line refresh; spawning Node + resolving + execing must stay
|
|
7
|
+
// well under 100 ms.
|
|
8
|
+
|
|
9
|
+
"use strict";
|
|
10
|
+
|
|
11
|
+
const { spawnSync } = require("child_process");
|
|
12
|
+
const path = require("path");
|
|
13
|
+
const fs = require("fs");
|
|
14
|
+
|
|
15
|
+
function resolveBinary() {
|
|
16
|
+
const platform = process.platform;
|
|
17
|
+
const arch = process.arch;
|
|
18
|
+
|
|
19
|
+
const map = {
|
|
20
|
+
"darwin-arm64": "@cc-status-line/darwin-arm64",
|
|
21
|
+
"linux-x64": "@cc-status-line/linux-x64",
|
|
22
|
+
"linux-arm64": "@cc-status-line/linux-arm64",
|
|
23
|
+
"win32-x64": "@cc-status-line/win32-x64",
|
|
24
|
+
};
|
|
25
|
+
|
|
26
|
+
const key = `${platform}-${arch}`;
|
|
27
|
+
const pkgName = map[key];
|
|
28
|
+
if (!pkgName) {
|
|
29
|
+
fail(
|
|
30
|
+
`Unsupported platform: ${platform}-${arch}.\n` +
|
|
31
|
+
`Supported: ${Object.keys(map).join(", ")}\n` +
|
|
32
|
+
`Build from source: https://github.com/hankeGui/cc-status`
|
|
33
|
+
);
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
const binName = platform === "win32" ? "ccs.exe" : "ccs";
|
|
37
|
+
|
|
38
|
+
// Resolve via require.resolve so we use Node's actual module-lookup
|
|
39
|
+
// path (handles workspaces, pnpm, yarn pnp, monorepos correctly).
|
|
40
|
+
let pkgRoot;
|
|
41
|
+
try {
|
|
42
|
+
pkgRoot = path.dirname(require.resolve(`${pkgName}/package.json`));
|
|
43
|
+
} catch (e) {
|
|
44
|
+
fail(
|
|
45
|
+
`The platform package ${pkgName} was not installed.\n` +
|
|
46
|
+
`This usually means optionalDependencies were skipped during install.\n` +
|
|
47
|
+
`Try: npm install --include=optional cc-status-line\n` +
|
|
48
|
+
`Or: npm install --force cc-status-line`
|
|
49
|
+
);
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
const binPath = path.join(pkgRoot, "bin", binName);
|
|
53
|
+
if (!fs.existsSync(binPath)) {
|
|
54
|
+
fail(`Binary not found at ${binPath}`);
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
return binPath;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
function fail(msg) {
|
|
61
|
+
process.stderr.write(`cc-status-line: ${msg}\n`);
|
|
62
|
+
process.exit(1);
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
function main() {
|
|
66
|
+
const bin = resolveBinary();
|
|
67
|
+
const result = spawnSync(bin, process.argv.slice(2), {
|
|
68
|
+
stdio: "inherit",
|
|
69
|
+
windowsHide: true,
|
|
70
|
+
});
|
|
71
|
+
if (result.error) {
|
|
72
|
+
fail(`Failed to spawn ${bin}: ${result.error.message}`);
|
|
73
|
+
}
|
|
74
|
+
process.exit(result.status ?? 1);
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
main();
|
package/package.json
ADDED
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@cc-status-line/cli",
|
|
3
|
+
"version": "0.1.5",
|
|
4
|
+
"description": "Multi-line, mode-switchable status line for Claude Code (Rust binary, npm-distributed)",
|
|
5
|
+
"keywords": [
|
|
6
|
+
"claude-code",
|
|
7
|
+
"claude",
|
|
8
|
+
"anthropic",
|
|
9
|
+
"statusline",
|
|
10
|
+
"status-line",
|
|
11
|
+
"cli",
|
|
12
|
+
"rust"
|
|
13
|
+
],
|
|
14
|
+
"homepage": "https://github.com/hankeGui/cc-status",
|
|
15
|
+
"repository": {
|
|
16
|
+
"type": "git",
|
|
17
|
+
"url": "git+https://github.com/hankeGui/cc-status.git"
|
|
18
|
+
},
|
|
19
|
+
"bugs": "https://github.com/hankeGui/cc-status/issues",
|
|
20
|
+
"license": "MIT",
|
|
21
|
+
"author": "hankeGui",
|
|
22
|
+
"bin": {
|
|
23
|
+
"ccs": "bin/ccs.js"
|
|
24
|
+
},
|
|
25
|
+
"files": [
|
|
26
|
+
"bin",
|
|
27
|
+
"index.js",
|
|
28
|
+
"postinstall.js",
|
|
29
|
+
"README.md"
|
|
30
|
+
],
|
|
31
|
+
"engines": {
|
|
32
|
+
"node": ">=14"
|
|
33
|
+
},
|
|
34
|
+
"scripts": {
|
|
35
|
+
"postinstall": "node postinstall.js || true"
|
|
36
|
+
},
|
|
37
|
+
"optionalDependencies": {
|
|
38
|
+
"@cc-status-line/darwin-arm64": "0.1.5",
|
|
39
|
+
"@cc-status-line/linux-x64": "0.1.5",
|
|
40
|
+
"@cc-status-line/linux-arm64": "0.1.5",
|
|
41
|
+
"@cc-status-line/win32-x64": "0.1.5"
|
|
42
|
+
}
|
|
43
|
+
}
|
package/postinstall.js
ADDED
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
// Friendly post-install hint. Does NOT touch ~/.claude/settings.json —
|
|
3
|
+
// users must run `ccs setup` (or set `command: "npx -y @cc-status-line/cli render"`
|
|
4
|
+
// manually) so the change is explicit and auditable.
|
|
5
|
+
|
|
6
|
+
"use strict";
|
|
7
|
+
|
|
8
|
+
if (process.env.CI || process.env.npm_config_silent) {
|
|
9
|
+
process.exit(0);
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
const dim = (s) => `\x1b[2m${s}\x1b[0m`;
|
|
13
|
+
const bold = (s) => `\x1b[1m${s}\x1b[0m`;
|
|
14
|
+
const green = (s) => `\x1b[0;32m${s}\x1b[0m`;
|
|
15
|
+
const cyan = (s) => `\x1b[1;36m${s}\x1b[0m`;
|
|
16
|
+
|
|
17
|
+
const lines = [
|
|
18
|
+
"",
|
|
19
|
+
bold("cc-status-line installed."),
|
|
20
|
+
"",
|
|
21
|
+
`Next step: wire it into Claude Code's ${cyan("~/.claude/settings.json")}.`,
|
|
22
|
+
"",
|
|
23
|
+
" " + green("ccs setup") + dim(" — interactive: shows the change, prompts for y/N"),
|
|
24
|
+
" " + green("ccs setup --yes") + dim(" — non-interactive (for scripts)"),
|
|
25
|
+
" " + green("ccs explain") + dim(" — what every status-line segment means"),
|
|
26
|
+
" " + green("ccs status") + dim(" — full session dashboard"),
|
|
27
|
+
"",
|
|
28
|
+
dim("Docs: https://github.com/hankeGui/cc-status"),
|
|
29
|
+
"",
|
|
30
|
+
];
|
|
31
|
+
|
|
32
|
+
try {
|
|
33
|
+
process.stdout.write(lines.join("\n"));
|
|
34
|
+
} catch (_e) {
|
|
35
|
+
// best-effort; never let a postinstall hint fail an install
|
|
36
|
+
}
|