clocktopus 1.1.3 → 1.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 CHANGED
@@ -150,6 +150,22 @@ Go to **System Settings > Notifications** and ensure **terminal-notifier** has n
150
150
 
151
151
  Enable **Require password immediately** in System Settings > Lock Screen.
152
152
 
153
+ ### Bun installs an old version
154
+
155
+ Bun caches registry data aggressively. Clear the cache and reinstall:
156
+
157
+ ```bash
158
+ bun pm cache rm && bun i -g clocktopus@latest
159
+ ```
160
+
161
+ ### Native addons not built (untrusted postinstall)
162
+
163
+ If `bun install -g` skips the postinstall script, the monitor will auto-build native addons on first run (requires Node.js for `npx`). Alternatively, trust the package and reinstall:
164
+
165
+ ```bash
166
+ bun pm trust clocktopus && bun i -g clocktopus
167
+ ```
168
+
153
169
  ### Linux
154
170
 
155
171
  ```bash
@@ -2,11 +2,13 @@ import { Hono } from 'hono';
2
2
  import { execSync } from 'child_process';
3
3
  import path from 'path';
4
4
  import { fileURLToPath } from 'url';
5
+ import { createRequire } from 'module';
5
6
  const __filename = fileURLToPath(import.meta.url);
6
7
  const __dirname = path.dirname(__filename);
7
8
  const SCRIPT_PATH = path.resolve(__dirname, '../../index.js');
8
9
  const isDev = SCRIPT_PATH.includes('/Projects/') || SCRIPT_PATH.includes('/src/');
9
10
  const PM2_NAME = isDev ? 'clocktopus-monitor-dev' : 'clocktopus-monitor';
11
+ const pm2Bin = path.join(path.dirname(createRequire(import.meta.url).resolve('pm2')), 'bin', 'pm2');
10
12
  const monitorRoutes = new Hono();
11
13
  function pm2Exec(command) {
12
14
  try {
@@ -20,7 +22,7 @@ function pm2Exec(command) {
20
22
  }
21
23
  monitorRoutes.get('/monitor/status', (c) => {
22
24
  try {
23
- const output = execSync('bunx pm2 jlist', { encoding: 'utf-8', timeout: 10000 });
25
+ const output = execSync('${pm2Bin} jlist', { encoding: 'utf-8', timeout: 10000 });
24
26
  const processes = JSON.parse(output);
25
27
  const proc = processes.find((p) => p.name === PM2_NAME);
26
28
  if (!proc) {
@@ -41,18 +43,18 @@ monitorRoutes.post('/monitor/start', (c) => {
41
43
  const bunPath = execSync('which bun', { encoding: 'utf-8' }).trim();
42
44
  // Delete any existing process to avoid duplicates
43
45
  try {
44
- execSync(`bunx pm2 delete ${PM2_NAME}`, { stdio: 'ignore' });
46
+ execSync(`${pm2Bin} delete ${PM2_NAME}`, { stdio: 'ignore' });
45
47
  }
46
48
  catch { }
47
- const result = pm2Exec(`bunx pm2 start ${SCRIPT_PATH} --name ${PM2_NAME} --interpreter ${bunPath} -- monitor:run`);
49
+ const result = pm2Exec(`${pm2Bin} start ${SCRIPT_PATH} --name ${PM2_NAME} --interpreter ${bunPath} -- monitor:run`);
48
50
  return c.json(result);
49
51
  });
50
52
  monitorRoutes.post('/monitor/stop', (c) => {
51
- const result = pm2Exec(`bunx pm2 stop ${PM2_NAME}`);
53
+ const result = pm2Exec(`${pm2Bin} stop ${PM2_NAME}`);
52
54
  return c.json(result);
53
55
  });
54
56
  monitorRoutes.post('/monitor/restart', (c) => {
55
- const result = pm2Exec(`bunx pm2 restart ${PM2_NAME}`);
57
+ const result = pm2Exec(`${pm2Bin} restart ${PM2_NAME}`);
56
58
  return c.json(result);
57
59
  });
58
60
  export default monitorRoutes;
package/dist/index.js CHANGED
@@ -6,6 +6,7 @@ import { Clockify } from './clockify.js';
6
6
  import * as fs from 'fs';
7
7
  import * as path from 'path';
8
8
  import { fileURLToPath } from 'url';
9
+ import { createRequire } from 'module';
9
10
  import { completeLatestSession, getLatestSession } from './lib/db.js';
10
11
  import { stopJiraTimer } from './lib/jira.js';
11
12
  import { startDashboard } from './dashboard/server.js';
@@ -287,6 +288,7 @@ program
287
288
  const isDev = __dirname.includes('/Projects/') || __dirname.includes('/src/');
288
289
  const MONITOR_PM2_NAME = isDev ? 'clocktopus-monitor-dev' : 'clocktopus-monitor';
289
290
  const DASH_PM2_NAME = isDev ? 'clocktopus-dash-dev' : 'clocktopus-dash';
291
+ const pm2Bin = path.join(path.dirname(createRequire(import.meta.url).resolve('pm2')), 'bin', 'pm2');
290
292
  program
291
293
  .command('monitor')
292
294
  .description('Start idle monitor as a background daemon.')
@@ -297,10 +299,10 @@ program
297
299
  const scriptPath = path.join(__dirname, 'index.js');
298
300
  try {
299
301
  try {
300
- execSync(`bunx pm2 delete ${MONITOR_PM2_NAME}`, { stdio: 'ignore' });
302
+ execSync(`${pm2Bin} delete ${MONITOR_PM2_NAME}`, { stdio: 'ignore' });
301
303
  }
302
304
  catch { }
303
- execSync(`bunx pm2 start ${scriptPath} --name ${MONITOR_PM2_NAME} --interpreter ${bunPath} -- monitor:run`, {
305
+ execSync(`${pm2Bin} start ${scriptPath} --name ${MONITOR_PM2_NAME} --interpreter ${bunPath} -- monitor:run`, {
304
306
  stdio: 'inherit',
305
307
  });
306
308
  console.log(chalk.green('Idle monitor started in background.'));
@@ -317,7 +319,7 @@ program
317
319
  .action(async () => {
318
320
  const { execSync } = await import('child_process');
319
321
  try {
320
- execSync(`bunx pm2 stop ${MONITOR_PM2_NAME}`, { stdio: 'inherit' });
322
+ execSync(`${pm2Bin} stop ${MONITOR_PM2_NAME}`, { stdio: 'inherit' });
321
323
  }
322
324
  catch {
323
325
  console.log(chalk.yellow('Monitor is not running.'));
@@ -329,7 +331,7 @@ program
329
331
  .action(async () => {
330
332
  const { execSync } = await import('child_process');
331
333
  try {
332
- execSync(`bunx pm2 logs ${MONITOR_PM2_NAME} --lines 50`, { stdio: 'inherit' });
334
+ execSync(`${pm2Bin} logs ${MONITOR_PM2_NAME} --lines 50`, { stdio: 'inherit' });
333
335
  }
334
336
  catch {
335
337
  console.log(chalk.yellow('Monitor is not running.'));
@@ -344,10 +346,10 @@ program
344
346
  const scriptPath = path.join(__dirname, 'index.js');
345
347
  try {
346
348
  try {
347
- execSync(`bunx pm2 delete ${DASH_PM2_NAME}`, { stdio: 'ignore' });
349
+ execSync(`${pm2Bin} delete ${DASH_PM2_NAME}`, { stdio: 'ignore' });
348
350
  }
349
351
  catch { }
350
- execSync(`bunx pm2 start ${scriptPath} --name ${DASH_PM2_NAME} --interpreter ${bunPath} -- dash`, {
352
+ execSync(`${pm2Bin} start ${scriptPath} --name ${DASH_PM2_NAME} --interpreter ${bunPath} -- dash`, {
351
353
  stdio: 'inherit',
352
354
  });
353
355
  console.log(chalk.green('Dashboard running at http://localhost:4001'));
@@ -364,7 +366,7 @@ program
364
366
  .action(async () => {
365
367
  const { execSync } = await import('child_process');
366
368
  try {
367
- execSync(`bunx pm2 stop ${DASH_PM2_NAME}`, { stdio: 'inherit' });
369
+ execSync(`${pm2Bin} stop ${DASH_PM2_NAME}`, { stdio: 'inherit' });
368
370
  }
369
371
  catch {
370
372
  console.log(chalk.yellow('Dashboard is not running.'));
@@ -376,7 +378,7 @@ program
376
378
  .action(async () => {
377
379
  const { execSync } = await import('child_process');
378
380
  try {
379
- execSync(`bunx pm2 logs ${DASH_PM2_NAME} --lines 50`, { stdio: 'inherit' });
381
+ execSync(`${pm2Bin} logs ${DASH_PM2_NAME} --lines 50`, { stdio: 'inherit' });
380
382
  }
381
383
  catch {
382
384
  console.log(chalk.yellow('Dashboard is not running.'));
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "clocktopus",
3
- "version": "1.1.3",
3
+ "version": "1.1.5",
4
4
  "type": "module",
5
5
  "main": "dist/index.js",
6
6
  "bin": {
@@ -21,9 +21,9 @@
21
21
  "clock": "bun dist/index.js",
22
22
  "monitor": "bun dist/index.js monitor",
23
23
  "monitor:stop": "bun dist/index.js monitor:stop",
24
- "monitor:restart": "bunx pm2 restart clocktopus-monitor-dev",
24
+ "monitor:restart": "node_modules/.bin/pm2 restart clocktopus-monitor-dev",
25
25
  "monitor:logs": "bun dist/index.js monitor:logs",
26
- "monitor:status": "bunx pm2 status clocktopus-monitor-dev",
26
+ "monitor:status": "node_modules/.bin/pm2 status clocktopus-monitor-dev",
27
27
  "prepare": "husky",
28
28
  "dashboard": "bun -e \"import('./dist/dashboard/server.js').then(m => m.startDashboard())\"",
29
29
  "db:cleanup": "bun dist/scripts/db-cleanup.js",