cc-caffeine 0.2.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/.claude/settings.local.json +70 -0
- package/.claude-plugin/plugin.json +23 -0
- package/.eslintrc.json +36 -0
- package/.github/FUNDING.yml +1 -0
- package/.github/dependabot.yml +6 -0
- package/.github/workflows/build.yml +79 -0
- package/.prettierrc +11 -0
- package/CLAUDE.md +307 -0
- package/LICENSE +21 -0
- package/README.md +185 -0
- package/assets/icon-coffee-empty.png +0 -0
- package/assets/icon-coffee-empty.svg +10 -0
- package/assets/icon-coffee-full.png +0 -0
- package/assets/icon-coffee-full.svg +15 -0
- package/caffeine.js +63 -0
- package/hooks/hooks.json +67 -0
- package/package.json +57 -0
- package/src/commands.js +168 -0
- package/src/electron.js +139 -0
- package/src/pid.js +224 -0
- package/src/server.js +182 -0
- package/src/session.js +227 -0
- package/src/system-tray.js +247 -0
package/README.md
ADDED
|
@@ -0,0 +1,185 @@
|
|
|
1
|
+
# cc-caffeine ☕⚡
|
|
2
|
+
|
|
3
|
+
**Transform your 9-to-5 into 9:30-to-4:30.** Arrive 30min later, leave 30min earlier, while getting the same work done because **Claude Code stays powered in your backpack while commuting.**
|
|
4
|
+
|
|
5
|
+
Work smarter, not longer.
|
|
6
|
+
|
|
7
|
+
## 🌍 The Modern Developer's Freedom
|
|
8
|
+
|
|
9
|
+
Tired of your laptop going to sleep during that perfect coding session because you left your desk 10 minutes? Frustrated when Claude Code disconnects mid-commute because your computer decided it was "idle"?
|
|
10
|
+
|
|
11
|
+
**cc-caffeine is your personal rebellion against screen timeout.** It keeps your machine awake so you can:
|
|
12
|
+
|
|
13
|
+
- 🚇 Code on the RER between Paris and suburbs
|
|
14
|
+
- ☕ Sip a latte at Starbucks during 3-hour debugging sessions
|
|
15
|
+
- 🚴♂️ Pedal to the coworking space while maintaining your active connection
|
|
16
|
+
- 📱 Respond to your girlfriend calls during work hours, without Claude Code interruptions
|
|
17
|
+
|
|
18
|
+
## 🎯 Installation
|
|
19
|
+
|
|
20
|
+
```bash
|
|
21
|
+
/plugin marketplace add samber/cc
|
|
22
|
+
/plugin install cc-caffeine@samber
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
## 🌟 The Nomad Developer Manifesto
|
|
26
|
+
|
|
27
|
+
> "I'll never choose between coding and traveling again. With cc-caffeine, I can do both. My laptop will never sleep while I traverse cities in 5G, my Claude Code will stay connected in my backpack, and my productivity will soar. The future of mobile development is here, and it smells like coffee."
|
|
28
|
+
|
|
29
|
+
## ✨ Why It's Pure Magic
|
|
30
|
+
|
|
31
|
+
**Automatic Intelligence**: cc-caffeine knows when Claude Code is working and prevents your computer from sleeping. Period.
|
|
32
|
+
|
|
33
|
+
**System Tray Chic**: A tiny ☕️ icon in your status bar to know instantly if you're protected.
|
|
34
|
+
|
|
35
|
+
**Perfect Sessions**: Multiple simultaneous Claude Code sessions? No problem.
|
|
36
|
+
|
|
37
|
+
**Zero Configuration**: Install, run, forget. It's like coffee, but for your computer.
|
|
38
|
+
|
|
39
|
+
## 🎯 Use Cases That Will Change Your Life
|
|
40
|
+
|
|
41
|
+
### ☕ **The Coffee Shop Marathon**
|
|
42
|
+
- 3 hours of focus without ever losing your connection
|
|
43
|
+
- No more waking your screen every 5 minutes
|
|
44
|
+
- Baristas will recognize you as "the developer who never sleeps"
|
|
45
|
+
- Your productivity increases proportionally to your caffeine consumption
|
|
46
|
+
|
|
47
|
+
### 🏠 **Flexible Remote Work**
|
|
48
|
+
- Transform your balcony into an outdoor office
|
|
49
|
+
- Code from the terrace in fresh air
|
|
50
|
+
- No more choosing between "work" and "enjoy the sunshine"
|
|
51
|
+
- Your boss will think you're working 24/7 (that's an advantage, right?)
|
|
52
|
+
|
|
53
|
+
## 🛠️ Technical Features (With Style)
|
|
54
|
+
|
|
55
|
+
- **🎯 Session-Based Management**: Intelligently manages multiple simultaneous Claude Code sessions
|
|
56
|
+
- **🔄 Auto-Cleanup**: Forget to disable - sessions automatically expire after 15 minutes without tool call or user input
|
|
57
|
+
- **🚀 Headless**: Just an elegant discreet system tray icon
|
|
58
|
+
- **⚡ Native Sleep Prevention**: Electron's power management - cross-platform sleep prevention
|
|
59
|
+
- **🍎 Cross-Platform**: Works on macOS, Linux, and Windows (yes, even Windows!)
|
|
60
|
+
|
|
61
|
+
## 🎭 Claude Code Integration
|
|
62
|
+
|
|
63
|
+
Hooks will be configured automatically if you import the project as a Claude Code plugin.
|
|
64
|
+
|
|
65
|
+
Otherwise, configure your Claude Code hooks for a seamless experience:
|
|
66
|
+
|
|
67
|
+
```json
|
|
68
|
+
{
|
|
69
|
+
"UserPromptSubmit": [
|
|
70
|
+
{
|
|
71
|
+
"hooks": [
|
|
72
|
+
{
|
|
73
|
+
"type": "command",
|
|
74
|
+
"command": "npx cc-caffeine caffeinate"
|
|
75
|
+
}
|
|
76
|
+
]
|
|
77
|
+
}
|
|
78
|
+
],
|
|
79
|
+
"PreToolUse": [
|
|
80
|
+
{
|
|
81
|
+
"hooks": [
|
|
82
|
+
{
|
|
83
|
+
"type": "command",
|
|
84
|
+
"command": "npx cc-caffeine caffeinate"
|
|
85
|
+
}
|
|
86
|
+
]
|
|
87
|
+
}
|
|
88
|
+
],
|
|
89
|
+
"PostToolUse": [
|
|
90
|
+
{
|
|
91
|
+
"hooks": [
|
|
92
|
+
{
|
|
93
|
+
"type": "command",
|
|
94
|
+
"command": "npx cc-caffeine caffeinate"
|
|
95
|
+
}
|
|
96
|
+
]
|
|
97
|
+
}
|
|
98
|
+
],
|
|
99
|
+
"Notification": [
|
|
100
|
+
{
|
|
101
|
+
"hooks": [
|
|
102
|
+
{
|
|
103
|
+
"type": "command",
|
|
104
|
+
"command": "npx cc-caffeine uncaffeinate"
|
|
105
|
+
}
|
|
106
|
+
]
|
|
107
|
+
}
|
|
108
|
+
],
|
|
109
|
+
"Stop": [
|
|
110
|
+
{
|
|
111
|
+
"hooks": [
|
|
112
|
+
{
|
|
113
|
+
"type": "command",
|
|
114
|
+
"command": "npx cc-caffeine uncaffeinate"
|
|
115
|
+
}
|
|
116
|
+
]
|
|
117
|
+
}
|
|
118
|
+
],
|
|
119
|
+
"SessionEnd": [
|
|
120
|
+
{
|
|
121
|
+
"hooks": [
|
|
122
|
+
{
|
|
123
|
+
"type": "command",
|
|
124
|
+
"command": "npx cc-caffeine uncaffeinate"
|
|
125
|
+
}
|
|
126
|
+
]
|
|
127
|
+
}
|
|
128
|
+
]
|
|
129
|
+
}
|
|
130
|
+
```
|
|
131
|
+
|
|
132
|
+
## 💡 The Secret Sauce
|
|
133
|
+
|
|
134
|
+
cc-caffeine uses an intelligent client-server approach:
|
|
135
|
+
|
|
136
|
+
1. **Lightweight Client** (`caffeinate`/`uncaffeinate`) - No Electron loading, just fast JSON writes
|
|
137
|
+
2. **System Server** (`server`) - Headless Electron app that monitors sessions and manages power
|
|
138
|
+
3. **Communication** - JSON file with atomic locking for perfect coordination
|
|
139
|
+
|
|
140
|
+
## 📋 Requirements
|
|
141
|
+
|
|
142
|
+
- Node.js >= 14.0.0 (your coffee of choice)
|
|
143
|
+
- Electron (included automatically, like sugar in your espresso)
|
|
144
|
+
- A burning desire to code everywhere, all the time
|
|
145
|
+
|
|
146
|
+
## 🚀 Run without Claude Code
|
|
147
|
+
|
|
148
|
+
```bash
|
|
149
|
+
# Start server + system tray
|
|
150
|
+
# (optional - will be started automatically)
|
|
151
|
+
npx cc-caffeine server
|
|
152
|
+
|
|
153
|
+
claude -p 'Write 10 pages of "lorem ipsum"'
|
|
154
|
+
|
|
155
|
+
npx cc-caffeine status
|
|
156
|
+
```
|
|
157
|
+
|
|
158
|
+
Manual switch:
|
|
159
|
+
|
|
160
|
+
```bash
|
|
161
|
+
# Activate caffeine for your coding session
|
|
162
|
+
echo '{"session_id": "session-abcd"}' | npx cc-caffeine caffeinate
|
|
163
|
+
|
|
164
|
+
# Your session is now protected!
|
|
165
|
+
# Claude can keep working while you sip coffee
|
|
166
|
+
|
|
167
|
+
# When you're done (or after 15 minutes of auto-cleanup)
|
|
168
|
+
echo '{"session_id": "session-abcd"}' | npx cc-caffeine uncaffeinate
|
|
169
|
+
```
|
|
170
|
+
|
|
171
|
+
## 💫 Fuel the Revolution
|
|
172
|
+
|
|
173
|
+
- ⭐️ **Star this repo** - Your star powers the caffeine engine!
|
|
174
|
+
- ☕️ **Buy me a coffee** - I'll literally use it to build more features while drinking actual coffee
|
|
175
|
+
- 🚀 **Sponsor the revolution** - Help me defeat screen timeouts worldwide!
|
|
176
|
+
|
|
177
|
+
[](https://github.com/sponsors/samber)
|
|
178
|
+
|
|
179
|
+
*Every sponsor gets a virtual high-five and the knowledge that somewhere, a developer is "coding" from a ski track because of you.* ✨
|
|
180
|
+
|
|
181
|
+
**PS**: If you encounter bugs, remember that even the best coffee has some grounds sometimes. But most of the time, it works like thunder. ⚡☕
|
|
182
|
+
|
|
183
|
+
## 📄 License
|
|
184
|
+
|
|
185
|
+
MIT - Use it, modify it, share it. Like good coffee, it's meant to be shared.
|
|
Binary file
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
<svg width="32" height="32" viewBox="0 0 32 32" xmlns="http://www.w3.org/2000/svg">
|
|
2
|
+
<!-- Coffee cup outline - smaller cup with more margin -->
|
|
3
|
+
<path d="M8 10 L8 22 L10 24 L22 24 L24 22 L24 10 Z"
|
|
4
|
+
fill="none" stroke="#FF6B35" stroke-width="2" stroke-linejoin="miter"/>
|
|
5
|
+
<!-- Coffee handle - smaller handle with margin -->
|
|
6
|
+
<path d="M24 14 L28 14 L28 18 L24 18 Z"
|
|
7
|
+
fill="none" stroke="#FF6B35" stroke-width="2" stroke-linejoin="miter"/>
|
|
8
|
+
<!-- Coffee residue - smaller with more margin -->
|
|
9
|
+
<line x1="10" y1="22" x2="22" y2="22" stroke="#FF6B35" stroke-width="1" opacity="0.5"/>
|
|
10
|
+
</svg>
|
|
Binary file
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
<svg width="32" height="32" viewBox="0 0 32 32" xmlns="http://www.w3.org/2000/svg">
|
|
2
|
+
<!-- Coffee cup - smaller cup with more margin -->
|
|
3
|
+
<path d="M8 10 L8 22 L10 24 L22 24 L24 22 L24 10 Z"
|
|
4
|
+
fill="#FF6B35"/>
|
|
5
|
+
<!-- Coffee liquid - smaller liquid with margin -->
|
|
6
|
+
<path d="M10 14 L10 18 L12 20 L20 20 L22 18 L22 14 Z"
|
|
7
|
+
fill="#E55A2B"/>
|
|
8
|
+
<!-- Coffee handle - smaller handle with margin -->
|
|
9
|
+
<path d="M24 14 L28 14 L28 18 L24 18 Z"
|
|
10
|
+
fill="#FF6B35"/>
|
|
11
|
+
<!-- Steam - simple flat lines with more margin -->
|
|
12
|
+
<line x1="12" y1="6" x2="12" y2="2" stroke="#FF6B35" stroke-width="1" opacity="0.7"/>
|
|
13
|
+
<line x1="16" y1="6" x2="16" y2="2" stroke="#FF6B35" stroke-width="1" opacity="0.7"/>
|
|
14
|
+
<line x1="20" y1="6" x2="20" y2="2" stroke="#FF6B35" stroke-width="1" opacity="0.7"/>
|
|
15
|
+
</svg>
|
package/caffeine.js
ADDED
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
const path = require('path');
|
|
4
|
+
const os = require('os');
|
|
5
|
+
const fs = require('fs');
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Main entry point for CC-Caffeine application
|
|
9
|
+
*
|
|
10
|
+
* This file contains the main() function and orchestrates all modules.
|
|
11
|
+
* All functionality has been split into separate modules for better organization.
|
|
12
|
+
*/
|
|
13
|
+
|
|
14
|
+
const { handleCaffeinate, handleUncaffeinate, handleStatus, handleVersion, handleUsage } = require('./src/commands');
|
|
15
|
+
const { handleServer } = require('./src/server');
|
|
16
|
+
|
|
17
|
+
const CONFIG_DIR = path.join(os.homedir(), '.claude', 'plugins', 'cc-caffeine');
|
|
18
|
+
|
|
19
|
+
const ensureConfigDir = () => {
|
|
20
|
+
try {
|
|
21
|
+
fs.mkdirSync(CONFIG_DIR, { recursive: true });
|
|
22
|
+
} catch (error) {
|
|
23
|
+
if (error.code !== 'EEXIST') {
|
|
24
|
+
throw error;
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
};
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* Main application entry point
|
|
31
|
+
* Handles command routing and delegates to appropriate modules
|
|
32
|
+
*/
|
|
33
|
+
const main = async () => {
|
|
34
|
+
ensureConfigDir();
|
|
35
|
+
|
|
36
|
+
const command = process.argv[2];
|
|
37
|
+
|
|
38
|
+
switch (command) {
|
|
39
|
+
case 'caffeinate':
|
|
40
|
+
await handleCaffeinate();
|
|
41
|
+
break;
|
|
42
|
+
case 'uncaffeinate':
|
|
43
|
+
await handleUncaffeinate();
|
|
44
|
+
break;
|
|
45
|
+
case 'server':
|
|
46
|
+
await handleServer();
|
|
47
|
+
break;
|
|
48
|
+
case 'status':
|
|
49
|
+
await handleStatus();
|
|
50
|
+
break;
|
|
51
|
+
case 'version':
|
|
52
|
+
await handleVersion();
|
|
53
|
+
break;
|
|
54
|
+
default:
|
|
55
|
+
await handleUsage();
|
|
56
|
+
}
|
|
57
|
+
};
|
|
58
|
+
|
|
59
|
+
// Handle uncaught errors gracefully
|
|
60
|
+
main().catch(error => {
|
|
61
|
+
console.error('Fatal error:', error);
|
|
62
|
+
process.exit(1);
|
|
63
|
+
});
|
package/hooks/hooks.json
ADDED
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
{
|
|
2
|
+
"description": "Prevents your computer from sleeping while Claude Code works hard",
|
|
3
|
+
"hooks": {
|
|
4
|
+
"UserPromptSubmit": [
|
|
5
|
+
{
|
|
6
|
+
"hooks": [
|
|
7
|
+
{
|
|
8
|
+
"type": "command",
|
|
9
|
+
"command": "npx cc-caffeine caffeinate"
|
|
10
|
+
}
|
|
11
|
+
]
|
|
12
|
+
}
|
|
13
|
+
],
|
|
14
|
+
"PreToolUse": [
|
|
15
|
+
{
|
|
16
|
+
"matcher": "*",
|
|
17
|
+
"hooks": [
|
|
18
|
+
{
|
|
19
|
+
"type": "command",
|
|
20
|
+
"command": "npx cc-caffeine caffeinate"
|
|
21
|
+
}
|
|
22
|
+
]
|
|
23
|
+
}
|
|
24
|
+
],
|
|
25
|
+
"PostToolUse": [
|
|
26
|
+
{
|
|
27
|
+
"matcher": "*",
|
|
28
|
+
"hooks": [
|
|
29
|
+
{
|
|
30
|
+
"type": "command",
|
|
31
|
+
"command": "npx cc-caffeine caffeinate"
|
|
32
|
+
}
|
|
33
|
+
]
|
|
34
|
+
}
|
|
35
|
+
],
|
|
36
|
+
"Notification": [
|
|
37
|
+
{
|
|
38
|
+
"hooks": [
|
|
39
|
+
{
|
|
40
|
+
"type": "command",
|
|
41
|
+
"command": "npx cc-caffeine uncaffeinate"
|
|
42
|
+
}
|
|
43
|
+
]
|
|
44
|
+
}
|
|
45
|
+
],
|
|
46
|
+
"Stop": [
|
|
47
|
+
{
|
|
48
|
+
"hooks": [
|
|
49
|
+
{
|
|
50
|
+
"type": "command",
|
|
51
|
+
"command": "npx cc-caffeine uncaffeinate"
|
|
52
|
+
}
|
|
53
|
+
]
|
|
54
|
+
}
|
|
55
|
+
],
|
|
56
|
+
"SessionEnd": [
|
|
57
|
+
{
|
|
58
|
+
"hooks": [
|
|
59
|
+
{
|
|
60
|
+
"type": "command",
|
|
61
|
+
"command": "npx cc-caffeine uncaffeinate"
|
|
62
|
+
}
|
|
63
|
+
]
|
|
64
|
+
}
|
|
65
|
+
]
|
|
66
|
+
}
|
|
67
|
+
}
|
package/package.json
ADDED
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "cc-caffeine",
|
|
3
|
+
"version": "0.2.0",
|
|
4
|
+
"description": "Prevents your computer from sleeping while Claude Code works hard",
|
|
5
|
+
"main": "caffeine.js",
|
|
6
|
+
"bin": {
|
|
7
|
+
"cc-caffeine": "./caffeine.js"
|
|
8
|
+
},
|
|
9
|
+
"scripts": {
|
|
10
|
+
"start": "npm run server",
|
|
11
|
+
"caffeinate": "node caffeine.js caffeinate",
|
|
12
|
+
"uncaffeinate": "node caffeine.js uncaffeinate",
|
|
13
|
+
"status": "node caffeine.js status",
|
|
14
|
+
"version": "node caffeine.js version",
|
|
15
|
+
"server": "npx electron caffeine.js server",
|
|
16
|
+
"lint": "eslint --fix *.js src/*.js || echo 'eslint not installed'",
|
|
17
|
+
"format": "prettier --write *.js src/*.js || echo 'prettier not installed'"
|
|
18
|
+
},
|
|
19
|
+
"keywords": [
|
|
20
|
+
"claude-code",
|
|
21
|
+
"claude-code-plugin",
|
|
22
|
+
"plugin",
|
|
23
|
+
"nap",
|
|
24
|
+
"sleep",
|
|
25
|
+
"sleep-prevention",
|
|
26
|
+
"caffeine",
|
|
27
|
+
"caffeinate",
|
|
28
|
+
"system-tray",
|
|
29
|
+
"electron"
|
|
30
|
+
],
|
|
31
|
+
"author": {
|
|
32
|
+
"name": "Samuel Berthe",
|
|
33
|
+
"email": "hey@samuel-berthe.fr",
|
|
34
|
+
"url": "https://samuel-berthe.fr"
|
|
35
|
+
},
|
|
36
|
+
"license": "MIT",
|
|
37
|
+
"dependencies": {
|
|
38
|
+
"electron": "^38.2.2",
|
|
39
|
+
"proper-lockfile": "^4.1.2"
|
|
40
|
+
},
|
|
41
|
+
"devDependencies": {
|
|
42
|
+
"eslint": "^9.37.0",
|
|
43
|
+
"prettier": "^3.6.2"
|
|
44
|
+
},
|
|
45
|
+
"engines": {
|
|
46
|
+
"node": ">=14.0.0"
|
|
47
|
+
},
|
|
48
|
+
"repository": {
|
|
49
|
+
"type": "git",
|
|
50
|
+
"url": "https://github.com/samber/cc-caffeine.git"
|
|
51
|
+
},
|
|
52
|
+
"os": [
|
|
53
|
+
"darwin",
|
|
54
|
+
"linux",
|
|
55
|
+
"win32"
|
|
56
|
+
]
|
|
57
|
+
}
|
package/src/commands.js
ADDED
|
@@ -0,0 +1,168 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Commands module - Handles all command-line interface functionality
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
const path = require('path');
|
|
8
|
+
const fs = require('fs');
|
|
9
|
+
|
|
10
|
+
const { addSessionWithLock, removeSessionWithLock, getActiveSessionsWithLock } = require('./session');
|
|
11
|
+
const { isServerRunningWithLock } = require('./pid');
|
|
12
|
+
const { runServerProcessIfNotStarted } = require('./server');
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* Handle session commands with JSON input from Claude Code hooks
|
|
16
|
+
*/
|
|
17
|
+
const handleSessionCommand = async (action, sessionOperation) => {
|
|
18
|
+
try {
|
|
19
|
+
// Read session_id from stdin (Claude Code hook format)
|
|
20
|
+
let input = '';
|
|
21
|
+
process.stdin.setEncoding('utf8');
|
|
22
|
+
|
|
23
|
+
await new Promise((resolve, reject) => {
|
|
24
|
+
process.stdin.on('data', chunk => (input += chunk));
|
|
25
|
+
process.stdin.on('end', resolve);
|
|
26
|
+
process.stdin.on('error', reject);
|
|
27
|
+
});
|
|
28
|
+
|
|
29
|
+
const data = JSON.parse(input);
|
|
30
|
+
const sessionId = data.session_id;
|
|
31
|
+
|
|
32
|
+
if (!sessionId) {
|
|
33
|
+
console.error('Error: session_id required in JSON input');
|
|
34
|
+
process.exit(1);
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
// Execute the session operation
|
|
38
|
+
const result = await sessionOperation(sessionId);
|
|
39
|
+
|
|
40
|
+
// For caffeinate command, ensure server is running
|
|
41
|
+
if (action === 'caffeinate') {
|
|
42
|
+
await runServerProcessIfNotStarted();
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
console.error(
|
|
46
|
+
`${action === 'caffeinate' ? 'Enabled' : 'Disabled'} caffeine for session: ${sessionId}`
|
|
47
|
+
);
|
|
48
|
+
|
|
49
|
+
// Log cleanup results if any
|
|
50
|
+
if (result.cleaned_sessions > 0) {
|
|
51
|
+
console.error(`Cleaned up ${result.cleaned_sessions} expired sessions`);
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
return result;
|
|
55
|
+
} catch (error) {
|
|
56
|
+
console.error('Error:', error.message);
|
|
57
|
+
process.exit(1);
|
|
58
|
+
}
|
|
59
|
+
};
|
|
60
|
+
|
|
61
|
+
/**
|
|
62
|
+
* Handle caffeinate command
|
|
63
|
+
*/
|
|
64
|
+
const handleCaffeinate = () => {
|
|
65
|
+
return handleSessionCommand('caffeinate', addSessionWithLock);
|
|
66
|
+
};
|
|
67
|
+
|
|
68
|
+
/**
|
|
69
|
+
* Handle uncaffeinate command
|
|
70
|
+
*/
|
|
71
|
+
const handleUncaffeinate = () => {
|
|
72
|
+
return handleSessionCommand('uncaffeinate', removeSessionWithLock);
|
|
73
|
+
};
|
|
74
|
+
|
|
75
|
+
/**
|
|
76
|
+
* Handle version command - show version from package.json and plugin.json
|
|
77
|
+
*/
|
|
78
|
+
const handleVersion = () => {
|
|
79
|
+
try {
|
|
80
|
+
// Read package.json
|
|
81
|
+
const packagePath = path.join(__dirname, '..', 'package.json');
|
|
82
|
+
const packageData = JSON.parse(fs.readFileSync(packagePath, 'utf8'));
|
|
83
|
+
const packageVersion = packageData.version || 'unknown';
|
|
84
|
+
|
|
85
|
+
// Read plugin.json
|
|
86
|
+
const pluginPath = path.join(__dirname, '..', '.claude-plugin', 'plugin.json');
|
|
87
|
+
let pluginVersion = 'unknown';
|
|
88
|
+
|
|
89
|
+
try {
|
|
90
|
+
const pluginData = JSON.parse(fs.readFileSync(pluginPath, 'utf8'));
|
|
91
|
+
pluginVersion = pluginData.version || 'unknown';
|
|
92
|
+
} catch (error) {
|
|
93
|
+
pluginVersion = 'not found';
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
console.error('=== CC-Caffeine Version ===');
|
|
97
|
+
console.error(`Package version: ${packageVersion}`);
|
|
98
|
+
console.error(`Plugin version: ${pluginVersion}`);
|
|
99
|
+
|
|
100
|
+
if (packageVersion !== pluginVersion && pluginVersion !== 'not found') {
|
|
101
|
+
console.error('⚠️ Warning: Package and plugin versions do not match!');
|
|
102
|
+
}
|
|
103
|
+
} catch (error) {
|
|
104
|
+
console.error('Error getting version:', error.message);
|
|
105
|
+
process.exit(1);
|
|
106
|
+
}
|
|
107
|
+
};
|
|
108
|
+
|
|
109
|
+
/**
|
|
110
|
+
* Handle status command - show current sessions and server status
|
|
111
|
+
*/
|
|
112
|
+
const handleStatus = async () => {
|
|
113
|
+
try {
|
|
114
|
+
const serverRunning = await isServerRunningWithLock();
|
|
115
|
+
const activeSessions = await getActiveSessionsWithLock();
|
|
116
|
+
|
|
117
|
+
console.error('=== CC-Caffeine Status ===');
|
|
118
|
+
console.error(`Server Status: ${serverRunning ? '✅ Running' : '❌ Stopped'}`);
|
|
119
|
+
console.error(`Active Sessions: ${activeSessions.length}`);
|
|
120
|
+
|
|
121
|
+
if (activeSessions.length > 0) {
|
|
122
|
+
console.error('\nActive Sessions:');
|
|
123
|
+
activeSessions.forEach((session, index) => {
|
|
124
|
+
const created = new Date(session.created_at).toLocaleString();
|
|
125
|
+
const lastActivity = new Date(session.last_activity).toLocaleString();
|
|
126
|
+
console.error(` ${index + 1}. ${session.id}`);
|
|
127
|
+
console.error(` Created: ${created}`);
|
|
128
|
+
console.error(` Last Activity: ${lastActivity}`);
|
|
129
|
+
if (session.project_dir) {
|
|
130
|
+
console.error(` Project: ${session.project_dir}`);
|
|
131
|
+
}
|
|
132
|
+
});
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
console.error('\nSession timeout: 15 minutes of inactivity');
|
|
136
|
+
} catch (error) {
|
|
137
|
+
console.error('Error getting status:', error.message);
|
|
138
|
+
process.exit(1);
|
|
139
|
+
}
|
|
140
|
+
};
|
|
141
|
+
|
|
142
|
+
/**
|
|
143
|
+
* Show usage help
|
|
144
|
+
*/
|
|
145
|
+
const handleUsage = () => {
|
|
146
|
+
console.error('Usage: npx electron caffeine.js [caffeinate|uncaffeinate|server|status|version]');
|
|
147
|
+
console.error('');
|
|
148
|
+
console.error('Commands:');
|
|
149
|
+
console.error(' caffeinate [session_id] - Enable caffeine for current session');
|
|
150
|
+
console.error(' uncaffeinate [session_id] - Disable caffeine for current session');
|
|
151
|
+
console.error(' server - Start caffeine server with system tray');
|
|
152
|
+
console.error(' status - Show current status and active sessions');
|
|
153
|
+
console.error(' version - Show version information from package.json and plugin.json');
|
|
154
|
+
process.exit(1);
|
|
155
|
+
};
|
|
156
|
+
|
|
157
|
+
// Export command handlers and utilities
|
|
158
|
+
module.exports = {
|
|
159
|
+
// Command handlers
|
|
160
|
+
handleCaffeinate,
|
|
161
|
+
handleUncaffeinate,
|
|
162
|
+
handleStatus,
|
|
163
|
+
handleVersion,
|
|
164
|
+
handleUsage,
|
|
165
|
+
|
|
166
|
+
// Session operations
|
|
167
|
+
handleSessionCommand
|
|
168
|
+
};
|