clocktopus 1.0.7 → 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 +12 -10
- package/dist/dashboard/routes/monitor.js +3 -2
- package/dist/index.js +56 -7
- package/dist/lib/db.js +9 -1
- package/package.json +6 -7
package/README.md
CHANGED
|
@@ -47,16 +47,18 @@ That's it. Start/stop timers from the Home tab.
|
|
|
47
47
|
|
|
48
48
|
### Commands
|
|
49
49
|
|
|
50
|
-
| Command
|
|
51
|
-
|
|
|
52
|
-
| `clocktopus dash`
|
|
53
|
-
| `clocktopus serve`
|
|
54
|
-
| `clocktopus serve:stop`
|
|
55
|
-
| `clocktopus serve:logs`
|
|
56
|
-
| `clocktopus start`
|
|
57
|
-
| `clocktopus stop`
|
|
58
|
-
| `clocktopus status`
|
|
59
|
-
| `clocktopus monitor`
|
|
50
|
+
| Command | Description |
|
|
51
|
+
| ------------------------- | --------------------------------------- |
|
|
52
|
+
| `clocktopus dash` | Start dashboard (foreground) |
|
|
53
|
+
| `clocktopus serve` | Start dashboard as background daemon |
|
|
54
|
+
| `clocktopus serve:stop` | Stop the dashboard daemon |
|
|
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 as background daemon |
|
|
60
|
+
| `clocktopus monitor:stop` | Stop the idle monitor |
|
|
61
|
+
| `clocktopus monitor:logs` | View idle monitor logs |
|
|
60
62
|
|
|
61
63
|
### Desktop App (macOS)
|
|
62
64
|
|
|
@@ -5,7 +5,8 @@ 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
|
|
8
|
+
const isDev = SCRIPT_PATH.includes('/Projects/') || SCRIPT_PATH.includes('/src/');
|
|
9
|
+
const PM2_NAME = isDev ? 'clocktopus-monitor-dev' : 'clocktopus-monitor';
|
|
9
10
|
const monitorRoutes = new Hono();
|
|
10
11
|
function pm2Exec(command) {
|
|
11
12
|
try {
|
|
@@ -43,7 +44,7 @@ monitorRoutes.post('/monitor/start', (c) => {
|
|
|
43
44
|
execSync(`bunx pm2 delete ${PM2_NAME}`, { stdio: 'ignore' });
|
|
44
45
|
}
|
|
45
46
|
catch { }
|
|
46
|
-
const result = pm2Exec(`bunx pm2 start ${SCRIPT_PATH} --name ${PM2_NAME} --interpreter ${bunPath} -- monitor`);
|
|
47
|
+
const result = pm2Exec(`bunx pm2 start ${SCRIPT_PATH} --name ${PM2_NAME} --interpreter ${bunPath} -- monitor:run`);
|
|
47
48
|
return c.json(result);
|
|
48
49
|
});
|
|
49
50
|
monitorRoutes.post('/monitor/stop', (c) => {
|
package/dist/index.js
CHANGED
|
@@ -137,8 +137,8 @@ function sleep(ms) {
|
|
|
137
137
|
return new Promise((res) => setTimeout(res, ms));
|
|
138
138
|
}
|
|
139
139
|
program
|
|
140
|
-
.command('monitor')
|
|
141
|
-
.description('
|
|
140
|
+
.command('monitor:run', { hidden: true })
|
|
141
|
+
.description('Run monitor in foreground (used by PM2).')
|
|
142
142
|
.action(async () => {
|
|
143
143
|
const { workspaceId, userId } = await getWorkspaceAndUser();
|
|
144
144
|
async function stopTimerAndLog(reason) {
|
|
@@ -275,6 +275,56 @@ program
|
|
|
275
275
|
.action(() => {
|
|
276
276
|
startDashboard();
|
|
277
277
|
});
|
|
278
|
+
const isDev = __dirname.includes('/Projects/') || __dirname.includes('/src/');
|
|
279
|
+
const MONITOR_PM2_NAME = isDev ? 'clocktopus-monitor-dev' : 'clocktopus-monitor';
|
|
280
|
+
const DASH_PM2_NAME = isDev ? 'clocktopus-dash-dev' : 'clocktopus-dash';
|
|
281
|
+
program
|
|
282
|
+
.command('monitor')
|
|
283
|
+
.description('Start idle monitor as a background daemon.')
|
|
284
|
+
.action(async () => {
|
|
285
|
+
const { execSync } = await import('child_process');
|
|
286
|
+
const bunPath = execSync('which bun', { encoding: 'utf-8' }).trim();
|
|
287
|
+
const scriptPath = path.join(__dirname, 'index.js');
|
|
288
|
+
try {
|
|
289
|
+
try {
|
|
290
|
+
execSync(`bunx pm2 delete ${MONITOR_PM2_NAME}`, { stdio: 'ignore' });
|
|
291
|
+
}
|
|
292
|
+
catch { }
|
|
293
|
+
execSync(`bunx pm2 start ${scriptPath} --name ${MONITOR_PM2_NAME} --interpreter ${bunPath} -- monitor:run`, {
|
|
294
|
+
stdio: 'inherit',
|
|
295
|
+
});
|
|
296
|
+
console.log(chalk.green('Idle monitor started in background.'));
|
|
297
|
+
console.log(chalk.gray(' Stop: clocktopus monitor:stop'));
|
|
298
|
+
console.log(chalk.gray(' Logs: clocktopus monitor:logs'));
|
|
299
|
+
}
|
|
300
|
+
catch {
|
|
301
|
+
console.error(chalk.red('Failed to start monitor.'));
|
|
302
|
+
}
|
|
303
|
+
});
|
|
304
|
+
program
|
|
305
|
+
.command('monitor:stop')
|
|
306
|
+
.description('Stop the idle monitor daemon.')
|
|
307
|
+
.action(async () => {
|
|
308
|
+
const { execSync } = await import('child_process');
|
|
309
|
+
try {
|
|
310
|
+
execSync(`bunx pm2 stop ${MONITOR_PM2_NAME}`, { stdio: 'inherit' });
|
|
311
|
+
}
|
|
312
|
+
catch {
|
|
313
|
+
console.log(chalk.yellow('Monitor is not running.'));
|
|
314
|
+
}
|
|
315
|
+
});
|
|
316
|
+
program
|
|
317
|
+
.command('monitor:logs')
|
|
318
|
+
.description('Show idle monitor logs.')
|
|
319
|
+
.action(async () => {
|
|
320
|
+
const { execSync } = await import('child_process');
|
|
321
|
+
try {
|
|
322
|
+
execSync(`bunx pm2 logs ${MONITOR_PM2_NAME} --lines 50`, { stdio: 'inherit' });
|
|
323
|
+
}
|
|
324
|
+
catch {
|
|
325
|
+
console.log(chalk.yellow('Monitor is not running.'));
|
|
326
|
+
}
|
|
327
|
+
});
|
|
278
328
|
program
|
|
279
329
|
.command('serve')
|
|
280
330
|
.description('Start dashboard as a background daemon (PM2).')
|
|
@@ -283,12 +333,11 @@ program
|
|
|
283
333
|
const bunPath = execSync('which bun', { encoding: 'utf-8' }).trim();
|
|
284
334
|
const scriptPath = path.join(__dirname, 'index.js');
|
|
285
335
|
try {
|
|
286
|
-
// Stop existing if running
|
|
287
336
|
try {
|
|
288
|
-
execSync(
|
|
337
|
+
execSync(`bunx pm2 delete ${DASH_PM2_NAME}`, { stdio: 'ignore' });
|
|
289
338
|
}
|
|
290
339
|
catch { }
|
|
291
|
-
execSync(`bunx pm2 start ${scriptPath} --name
|
|
340
|
+
execSync(`bunx pm2 start ${scriptPath} --name ${DASH_PM2_NAME} --interpreter ${bunPath} -- dash`, {
|
|
292
341
|
stdio: 'inherit',
|
|
293
342
|
});
|
|
294
343
|
console.log(chalk.green('Dashboard running at http://localhost:4001'));
|
|
@@ -305,7 +354,7 @@ program
|
|
|
305
354
|
.action(async () => {
|
|
306
355
|
const { execSync } = await import('child_process');
|
|
307
356
|
try {
|
|
308
|
-
execSync(
|
|
357
|
+
execSync(`bunx pm2 stop ${DASH_PM2_NAME}`, { stdio: 'inherit' });
|
|
309
358
|
}
|
|
310
359
|
catch {
|
|
311
360
|
console.log(chalk.yellow('Dashboard is not running.'));
|
|
@@ -317,7 +366,7 @@ program
|
|
|
317
366
|
.action(async () => {
|
|
318
367
|
const { execSync } = await import('child_process');
|
|
319
368
|
try {
|
|
320
|
-
execSync(
|
|
369
|
+
execSync(`bunx pm2 logs ${DASH_PM2_NAME} --lines 50`, { stdio: 'inherit' });
|
|
321
370
|
}
|
|
322
371
|
catch {
|
|
323
372
|
console.log(chalk.yellow('Dashboard is not running.'));
|
package/dist/lib/db.js
CHANGED
|
@@ -2,7 +2,15 @@ import * as fs from 'fs';
|
|
|
2
2
|
import * as path from 'path';
|
|
3
3
|
import { Database } from 'bun:sqlite';
|
|
4
4
|
import { z } from 'zod';
|
|
5
|
-
|
|
5
|
+
function getDataDir() {
|
|
6
|
+
const scriptDir = path.dirname(new URL(import.meta.url).pathname);
|
|
7
|
+
const isDev = scriptDir.includes('/Projects/') || scriptDir.includes('/src/');
|
|
8
|
+
if (isDev) {
|
|
9
|
+
return path.join(process.cwd(), 'data/db');
|
|
10
|
+
}
|
|
11
|
+
return path.join(process.env.HOME || '~', '.clocktopus', 'data');
|
|
12
|
+
}
|
|
13
|
+
const DB_DIR = getDataDir();
|
|
6
14
|
const DB_PATH = path.join(DB_DIR, 'sessions.db');
|
|
7
15
|
if (!fs.existsSync(DB_DIR)) {
|
|
8
16
|
fs.mkdirSync(DB_DIR, { recursive: true });
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "clocktopus",
|
|
3
|
-
"version": "1.0
|
|
3
|
+
"version": "1.1.0",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"bin": {
|
|
@@ -18,12 +18,11 @@
|
|
|
18
18
|
"postinstall": "cd node_modules/macos-notification-state && node-gyp rebuild 2>/dev/null; cd ../desktop-idle && node-gyp rebuild 2>/dev/null; true",
|
|
19
19
|
"lint": "eslint . --ext .ts",
|
|
20
20
|
"clock": "bun dist/index.js",
|
|
21
|
-
"
|
|
22
|
-
"monitor": "bun
|
|
23
|
-
"monitor:restart": "bunx pm2 restart clocktopus",
|
|
24
|
-
"monitor:
|
|
25
|
-
"monitor:
|
|
26
|
-
"monitor:status": "bunx pm2 status clocktopus",
|
|
21
|
+
"monitor": "bun dist/index.js monitor",
|
|
22
|
+
"monitor:stop": "bun dist/index.js monitor:stop",
|
|
23
|
+
"monitor:restart": "bunx pm2 restart clocktopus-monitor-dev",
|
|
24
|
+
"monitor:logs": "bun dist/index.js monitor:logs",
|
|
25
|
+
"monitor:status": "bunx pm2 status clocktopus-monitor-dev",
|
|
27
26
|
"prepare": "husky",
|
|
28
27
|
"dashboard": "bun -e \"import('./dist/dashboard/server.js').then(m => m.startDashboard())\"",
|
|
29
28
|
"db:cleanup": "bun dist/scripts/db-cleanup.js",
|