clocktopus 1.0.6 → 1.0.7

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
@@ -6,7 +6,7 @@
6
6
 
7
7
  CLI-based time-tracking automation for Clockify with idle monitoring, Jira integration, Google Calendar sync, and a web dashboard.
8
8
 
9
- ## Quick Start (Dashboard User)
9
+ ## Quick Start
10
10
 
11
11
  Most users only need the dashboard — a web UI to manage timers, connect integrations, and monitor idle time.
12
12
 
@@ -45,7 +45,7 @@ Open [http://localhost:4001](http://localhost:4001) in your browser.
45
45
 
46
46
  That's it. Start/stop timers from the Home tab.
47
47
 
48
- ### Dashboard Commands
48
+ ### Commands
49
49
 
50
50
  | Command | Description |
51
51
  | ----------------------- | ------------------------------------ |
@@ -53,6 +53,10 @@ That's it. Start/stop timers from the Home tab.
53
53
  | `clocktopus serve` | Start dashboard as background daemon |
54
54
  | `clocktopus serve:stop` | Stop the dashboard daemon |
55
55
  | `clocktopus serve:logs` | View dashboard daemon logs |
56
+ | `clocktopus start` | Start a timer (interactive) |
57
+ | `clocktopus stop` | Stop the current timer |
58
+ | `clocktopus status` | Check timer status |
59
+ | `clocktopus monitor` | Start idle monitor (foreground) |
56
60
 
57
61
  ### Desktop App (macOS)
58
62
 
@@ -68,9 +72,7 @@ The dashboard server must be running (`clocktopus serve`). See [desktop/README.m
68
72
 
69
73
  ---
70
74
 
71
- ## Power User Guide
72
-
73
- For CLI-based workflows, scripting, and advanced features.
75
+ ## Development
74
76
 
75
77
  ### Install from Source
76
78
 
@@ -81,105 +83,32 @@ bun install
81
83
  bun run build
82
84
  ```
83
85
 
84
- ### Local Development
86
+ ### Local Commands
85
87
 
86
88
  When running from source, use `bun run clock` instead of `clocktopus`:
87
89
 
88
90
  ```bash
89
- # Build first
90
- bun run build
91
+ bun run build # Build TypeScript
91
92
 
92
- # Dashboard
93
93
  bun run dashboard # Start dashboard (foreground)
94
-
95
- # Timer
96
94
  bun run clock start "Task" # Start a timer
97
95
  bun run clock start -j PROJ-1 # Start with Jira ticket
98
96
  bun run clock stop # Stop timer
99
97
  bun run clock status # Check timer status
100
98
 
101
- # Monitor
102
99
  bun run monitor # Start idle monitor (PM2 daemon)
103
100
  bun run monitor:stop # Stop monitor
104
101
  bun run monitor:restart # Restart monitor
105
- bun run monitor:status # Check monitor status
106
102
  bun run monitor:logs # View monitor logs
107
103
 
108
- # Google Calendar
109
104
  bun run google-auth # Authenticate Google account
110
105
  bun run log-calendar -t # Log today's events
111
-
112
- # Database
113
106
  bun run db:cleanup # Clean old session logs
114
107
  ```
115
108
 
116
- ### CLI Commands
117
-
118
- #### Timer Management
119
-
120
- ```bash
121
- # Start a timer (interactive project selection)
122
- clocktopus start "Task description"
123
-
124
- # Start with a Jira ticket (auto-fetches ticket title)
125
- clocktopus start -j TICKET-123
126
-
127
- # Stop the current timer
128
- clocktopus stop
129
-
130
- # Check timer status
131
- clocktopus status
132
- ```
133
-
134
- #### Idle Monitor
135
-
136
- Automatically stops timers when you're idle (5 min) or lock your screen, and restarts when you're back.
137
-
138
- ```bash
139
- # Run in foreground
140
- clocktopus monitor
141
-
142
- # Or manage via dashboard UI (Start/Stop/Restart buttons)
143
- ```
144
-
145
- The dashboard's Idle Monitor buttons use PM2 under the hood:
146
-
147
- | Action | What it does |
148
- | ----------- | ------------------------------ |
149
- | **Start** | Launches monitor as PM2 daemon |
150
- | **Stop** | Stops the monitor daemon |
151
- | **Restart** | Restarts after code changes |
152
-
153
- #### Google Calendar Integration
154
-
155
- Log Google Calendar events as Clockify time entries.
156
-
157
- ```bash
158
- # Authenticate (one-time)
159
- clocktopus google-auth
160
-
161
- # Log events for a date range
162
- clocktopus log-calendar -s 2025-07-21 -e 2025-07-22
163
-
164
- # Log today's events
165
- clocktopus log-calendar -t
166
- ```
167
-
168
- For each event, you'll be prompted to select a Clockify project. Selections are cached by event name for recurring meetings.
169
-
170
- #### Database Cleanup
171
-
172
- ```bash
173
- # Delete session logs older than 5 days (default)
174
- clocktopus db:cleanup
175
-
176
- # Delete logs older than N days
177
- clocktopus db:cleanup 10
178
- ```
179
-
180
109
  ### Configuration
181
110
 
182
- All configuration is stored in a local SQLite database (`data/sessions.db`) and managed through the dashboard Settings tab. No `.env` file is needed.
111
+ All configuration is stored in a local SQLite database and managed through the dashboard Settings tab.
183
112
 
184
113
  | Setting | How to configure |
185
114
  | ---------------- | ------------------------------------------------ |
@@ -188,56 +117,23 @@ All configuration is stored in a local SQLite database (`data/sessions.db`) and
188
117
  | Jira (API token) | Dashboard > Settings > "or use API token" |
189
118
  | Google Calendar | Dashboard > Settings > Click "Connect Google" |
190
119
 
191
- #### OAuth Architecture
192
-
193
- - **Jira**: OAuth tokens are exchanged through a [Cloudflare Worker proxy](docs/atlassian-proxy-flow.md) that holds the client secret securely. Users just click Connect.
194
- - **Google**: Uses a Desktop-type OAuth client. Credentials are handled transparently.
195
- - **Clockify**: Each user provides their own API key.
120
+ OAuth for Jira and Google is handled transparently through a [Cloudflare Worker proxy](docs/atlassian-proxy-flow.md) — no client credentials needed from users.
196
121
 
197
- #### Environment Variables (Optional Override)
122
+ ### Project Structure
198
123
 
199
- Power users can override credentials via environment variables or a `.env` file:
200
-
201
- ```
202
- CLOCKIFY_API_KEY="your_key"
203
- ATLASSIAN_CLIENT_ID="your_id"
204
- ATLASSIAN_CLIENT_SECRET="your_secret"
205
- GOOGLE_CLIENT_ID="your_id"
206
- GOOGLE_CLIENT_SECRET="your_secret"
207
124
  ```
208
-
209
- The app checks the database first, then falls back to environment variables.
210
-
211
- ### Local Project Filtering (CLI only)
212
-
213
- On first `clocktopus start`, all projects are saved to `data/local-projects.json`. Edit this file to keep only your frequently used projects:
214
-
215
- ```json
216
- [
217
- { "id": "671b783fbd91bc5e5ddcb944", "name": "Project A" },
218
- { "id": "another_id", "name": "Project B" }
219
- ]
220
- ```
221
-
222
- ### Shell Aliases
223
-
224
- For quick access, add to `~/.zshrc`:
225
-
226
- ```bash
227
- CLOCKTOPUS_PATH="$HOME/Projects/Personal/clocktopus"
228
-
229
- clockto() {
230
- cd "$CLOCKTOPUS_PATH" || return
231
- bun run "$@"
232
- }
233
-
234
- alias cbuild="clockto build"
235
- alias cstart="clockto clock start"
236
- alias cstop="clockto clock stop"
237
- alias mstart="clockto monitor"
238
- alias mstop="clockto monitor:stop"
239
- alias mrestart="clockto monitor:restart"
240
- alias mlogs="clockto monitor:logs"
125
+ clocktopus/
126
+ ├── index.ts # CLI entry point (Commander)
127
+ ├── clockify.ts # Clockify API client
128
+ ├── lib/ # Core libraries (db, auth, credentials)
129
+ ├── dashboard/ # Web dashboard (Hono server)
130
+ │ ├── server.ts # Dashboard server
131
+ │ ├── views.ts # HTML/CSS/JS (single-page app)
132
+ │ └── routes/ # API routes
133
+ ├── desktop/ # Tauri macOS menu bar app
134
+ ├── proxy/ # Cloudflare Worker (OAuth proxy)
135
+ ├── scripts/ # Google auth & calendar scripts
136
+ └── data/ # SQLite DB & config (gitignored)
241
137
  ```
242
138
 
243
139
  ---
@@ -246,37 +142,18 @@ alias mlogs="clockto monitor:logs"
246
142
 
247
143
  ### No notifications on macOS
248
144
 
249
- Go to **System Settings > Notifications** and ensure **terminal-notifier** (or your terminal app) has notifications enabled.
145
+ Go to **System Settings > Notifications** and ensure **terminal-notifier** has notifications enabled.
250
146
 
251
147
  ### Monitor not detecting display off
252
148
 
253
- The idle monitor detects screen lock and system idle (5 min). If your Mac's display turns off without locking, enable **Require password immediately** in System Settings > Lock Screen.
149
+ Enable **Require password immediately** in System Settings > Lock Screen.
254
150
 
255
- ### Linux Requirements
151
+ ### Linux
256
152
 
257
153
  ```bash
258
154
  apt install libxss-dev pkg-config build-essential
259
155
  ```
260
156
 
261
- ---
262
-
263
- ## Project Structure
264
-
265
- ```
266
- clocktopus/
267
- ├── index.ts # CLI entry point (Commander)
268
- ├── clockify.ts # Clockify API client
269
- ├── lib/ # Core libraries (db, auth, credentials)
270
- ├── dashboard/ # Web dashboard (Hono server)
271
- │ ├── server.ts # Dashboard server
272
- │ ├── views.ts # HTML/CSS/JS (single-page app)
273
- │ └── routes/ # API routes
274
- ├── desktop/ # Tauri macOS menu bar app
275
- ├── proxy/ # Cloudflare Worker (OAuth proxy)
276
- ├── scripts/ # Google auth & calendar scripts
277
- └── data/ # SQLite DB & config (gitignored)
278
- ```
279
-
280
157
  ## License
281
158
 
282
159
  MIT
@@ -5,6 +5,7 @@ import { fileURLToPath } from 'url';
5
5
  const __filename = fileURLToPath(import.meta.url);
6
6
  const __dirname = path.dirname(__filename);
7
7
  const SCRIPT_PATH = path.resolve(__dirname, '../../index.js');
8
+ const PM2_NAME = 'clocktopus-monitor';
8
9
  const monitorRoutes = new Hono();
9
10
  function pm2Exec(command) {
10
11
  try {
@@ -20,15 +21,15 @@ monitorRoutes.get('/monitor/status', (c) => {
20
21
  try {
21
22
  const output = execSync('bunx pm2 jlist', { encoding: 'utf-8', timeout: 10000 });
22
23
  const processes = JSON.parse(output);
23
- const clocktopus = processes.find((p) => p.name === 'clocktopus');
24
- if (!clocktopus) {
24
+ const proc = processes.find((p) => p.name === PM2_NAME);
25
+ if (!proc) {
25
26
  return c.json({ running: false, status: 'not found' });
26
27
  }
27
28
  return c.json({
28
- running: clocktopus.pm2_env.status === 'online',
29
- status: clocktopus.pm2_env.status,
30
- uptime: clocktopus.pm2_env.pm_uptime,
31
- restarts: clocktopus.pm2_env.restart_time,
29
+ running: proc.pm2_env.status === 'online',
30
+ status: proc.pm2_env.status,
31
+ uptime: proc.pm2_env.pm_uptime,
32
+ restarts: proc.pm2_env.restart_time,
32
33
  });
33
34
  }
34
35
  catch {
@@ -37,15 +38,20 @@ monitorRoutes.get('/monitor/status', (c) => {
37
38
  });
38
39
  monitorRoutes.post('/monitor/start', (c) => {
39
40
  const bunPath = execSync('which bun', { encoding: 'utf-8' }).trim();
40
- const result = pm2Exec(`bunx pm2 start ${SCRIPT_PATH} --name clocktopus --interpreter ${bunPath} -- monitor`);
41
+ // Delete any existing process to avoid duplicates
42
+ try {
43
+ execSync(`bunx pm2 delete ${PM2_NAME}`, { stdio: 'ignore' });
44
+ }
45
+ catch { }
46
+ const result = pm2Exec(`bunx pm2 start ${SCRIPT_PATH} --name ${PM2_NAME} --interpreter ${bunPath} -- monitor`);
41
47
  return c.json(result);
42
48
  });
43
49
  monitorRoutes.post('/monitor/stop', (c) => {
44
- const result = pm2Exec('bunx pm2 stop clocktopus');
50
+ const result = pm2Exec(`bunx pm2 stop ${PM2_NAME}`);
45
51
  return c.json(result);
46
52
  });
47
53
  monitorRoutes.post('/monitor/restart', (c) => {
48
- const result = pm2Exec('bunx pm2 restart clocktopus');
54
+ const result = pm2Exec(`bunx pm2 restart ${PM2_NAME}`);
49
55
  return c.json(result);
50
56
  });
51
57
  export default monitorRoutes;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "clocktopus",
3
- "version": "1.0.6",
3
+ "version": "1.0.7",
4
4
  "type": "module",
5
5
  "main": "dist/index.js",
6
6
  "bin": {