claude-code-pulsify 1.1.1 → 1.2.1

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 CHANGED
@@ -34,6 +34,14 @@ npx claude-code-pulsify@latest --uninstall
34
34
  - **Context monitor** -- Warns at 65% and 75% context usage via PostToolUse hook
35
35
  - **Update checker** -- Background version check on session start, non-blocking
36
36
 
37
+ ## Context bar
38
+
39
+ The context bar shows **usable** context, not raw token count — it accounts for Claude's autocompact buffer (~16.5% of the window), which is reserved and unavailable to you.
40
+
41
+ - **0%** = fresh session
42
+ - **100%** = autocompact imminent (context will be compressed)
43
+ - Color thresholds: **green** (<50%) → **yellow** (50-65%) → **orange** (65-80%) → **red** (>80%)
44
+
37
45
  ## Checking your installed version
38
46
 
39
47
  ```bash
@@ -49,3 +57,8 @@ You can also check manually:
49
57
  ## Configuration
50
58
 
51
59
  Respects the `CLAUDE_CONFIG_DIR` environment variable. Defaults to `~/.claude`.
60
+
61
+ ## Future Enhancements
62
+
63
+ - Lines changed display (+added / -removed)
64
+ - Token usage counter
package/bin/install.js CHANGED
@@ -82,7 +82,17 @@ function install() {
82
82
  // 4. Patch settings.json
83
83
  const settings = readJSON(settingsPath)
84
84
 
85
- // statusLine
85
+ // statusLine — check for conflicts from other tools
86
+ const existingCmd = settings.statusLine?.command || ''
87
+ if (settings.statusLine && !existingCmd.includes('claude-code-pulsify')) {
88
+ if (!args.includes('--force')) {
89
+ console.warn(`\n ⚠ Existing statusLine detected:`)
90
+ console.warn(` ${existingCmd || JSON.stringify(settings.statusLine)}`)
91
+ console.warn(` This will be overwritten. Re-run with --force to confirm, or remove it manually.\n`)
92
+ process.exit(1)
93
+ }
94
+ console.log(` Overwriting existing statusLine (--force)`)
95
+ }
86
96
  settings.statusLine = {
87
97
  type: 'command',
88
98
  command: `node ${path.join(hooksTarget, 'statusline.js')}`,
@@ -17,11 +17,12 @@ const cacheDir = path.join(configDir, 'cache')
17
17
  const cachePath = path.join(cacheDir, 'claude-code-pulsify-update.json')
18
18
 
19
19
  async function main() {
20
- // Consume stdin (required by hook protocol)
20
+ // Consume stdin (required by hook protocol) with timeout guard
21
21
  let input = ''
22
- for await (const chunk of process.stdin) {
23
- input += chunk
24
- }
22
+ await Promise.race([
23
+ (async () => { for await (const chunk of process.stdin) input += chunk })(),
24
+ new Promise((resolve) => setTimeout(resolve, 5000)),
25
+ ])
25
26
 
26
27
  // Read installed version
27
28
  const versionFile = path.join(hooksDir, 'VERSION')
@@ -37,6 +38,7 @@ async function main() {
37
38
  const child = spawn(process.execPath, [workerPath], {
38
39
  detached: true,
39
40
  stdio: 'ignore',
41
+ windowsHide: true,
40
42
  env: {
41
43
  ...process.env,
42
44
  PULSIFY_CACHE_PATH: cachePath,
@@ -47,9 +47,10 @@ function writeState(sessionId, state) {
47
47
 
48
48
  async function main() {
49
49
  let input = ''
50
- for await (const chunk of process.stdin) {
51
- input += chunk
52
- }
50
+ await Promise.race([
51
+ (async () => { for await (const chunk of process.stdin) input += chunk })(),
52
+ new Promise((resolve) => setTimeout(resolve, 5000)),
53
+ ])
53
54
 
54
55
  let hookData
55
56
  try {
@@ -121,28 +121,13 @@ function formatCost(costUsd) {
121
121
  return `${WHITE}$${str}${RESET}`
122
122
  }
123
123
 
124
- function formatLinesChanged(added, removed) {
125
- const parts = []
126
- if (added) parts.push(`${GREEN}+${added}${RESET}`)
127
- if (removed) parts.push(`${RED}-${removed}${RESET}`)
128
- return parts.join(' ')
129
- }
130
-
131
- function formatTokenCount(input, output) {
132
- const total = (input || 0) + (output || 0)
133
- if (!total) return ''
134
- let compact
135
- if (total >= 1e6) compact = `${(total / 1e6).toFixed(1)}M`
136
- else if (total >= 1e3) compact = `${(total / 1e3).toFixed(1)}k`
137
- else compact = `${total}`
138
- return `${DIM}${compact} tok${RESET}`
139
- }
140
124
 
141
125
  async function main() {
142
126
  let input = ''
143
- for await (const chunk of process.stdin) {
144
- input += chunk
145
- }
127
+ await Promise.race([
128
+ (async () => { for await (const chunk of process.stdin) input += chunk })(),
129
+ new Promise((resolve) => setTimeout(resolve, 5000)),
130
+ ])
146
131
 
147
132
  let data
148
133
  try {
@@ -178,10 +163,6 @@ async function main() {
178
163
  const remainingPct = data.context_window?.remaining_percentage ?? 100
179
164
  const sessionId = data.session?.id || data.session_id || null
180
165
  const costUsd = data.cost?.total_cost_usd ?? 0
181
- const linesAdded = data.cost?.total_lines_added ?? 0
182
- const linesRemoved = data.cost?.total_lines_removed ?? 0
183
- const totalInputTokens = data.context_window?.total_input_tokens ?? 0
184
- const totalOutputTokens = data.context_window?.total_output_tokens ?? 0
185
166
 
186
167
  // Normalize and build bar
187
168
  const usedPct = normalizeUsage(remainingPct)
@@ -206,10 +187,8 @@ async function main() {
206
187
  model,
207
188
  })
208
189
 
209
- // Format new segments
190
+ // Format cost
210
191
  const cost = formatCost(costUsd)
211
- const lines = formatLinesChanged(linesAdded, linesRemoved)
212
- const tokenCount = formatTokenCount(totalInputTokens, totalOutputTokens)
213
192
 
214
193
  // Build segments array (only include non-empty optional segments)
215
194
  const segments = [
@@ -217,9 +196,7 @@ async function main() {
217
196
  dirLabel,
218
197
  ]
219
198
  if (cost) segments.push(cost)
220
- if (lines) segments.push(lines)
221
- const barWithTokens = tokenCount ? `${bar} ${tokenCount}` : bar
222
- segments.push(barWithTokens)
199
+ segments.push(bar)
223
200
 
224
201
  // Output statusline
225
202
  const line = segments.join(` ${SEPARATOR} `) + taskSegment + updateIndicator
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "claude-code-pulsify",
3
- "version": "1.1.1",
3
+ "version": "1.2.1",
4
4
  "description": "Context-aware statusline and context monitor for Claude Code",
5
5
  "bin": {
6
6
  "claude-code-pulsify": "bin/install.js"