clocktopus 1.0.1 → 1.0.3

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
@@ -4,294 +4,269 @@
4
4
  <img src="assets/logo.png" alt="Clocktopus Logo" width="300px" />
5
5
  </p>
6
6
 
7
- ## About
7
+ CLI-based time-tracking automation for Clockify with idle monitoring, Jira integration, Google Calendar sync, and a web dashboard.
8
8
 
9
- Clocktopus is a powerful command-line interface tool designed to streamline your time tracking with platforms like Clockify and Jira. It offers a suite of features to automate and simplify the process of logging your work, ensuring accuracy and efficiency.
9
+ ## Quick Start (Dashboard User)
10
10
 
11
- ### Key Features
11
+ Most users only need the dashboard — a web UI to manage timers, connect integrations, and monitor idle time.
12
12
 
13
- - **Automated Idle Monitoring:** Automatically stops and restarts timers based on your system's idle activity.
14
- - **Jira Integration:** Seamlessly link your time entries to Jira tickets, fetching and prepending ticket titles to descriptions.
15
- - **Google Calendar Integration:** Log your Google Calendar events directly as Clockify time entries, with intelligent project caching for recurring events.
16
- - **Local Project Filtering:** Curate a personalized list of projects for quick selection, reducing clutter.
17
- - **Session Management:** Start, stop, and check the status of your time entries directly from the terminal.
18
- - **Database Cleanup:** Easily manage and clean up old session logs from the local SQLite database.
13
+ ### Install
19
14
 
20
- ## Installation
21
-
22
- To get started with the Clocktopus CLI, follow these steps:
23
-
24
- 1. **Clone the repository:**
25
-
26
- ```bash
27
- git clone <repository_url>
28
- cd clocktopus
29
- ```
15
+ ```bash
16
+ npm i -g clocktopus
17
+ ```
30
18
 
31
- 2. **Install dependencies:**
32
- ```bash
33
- bun install
34
- ```
19
+ Requires [Bun](https://bun.sh) runtime:
35
20
 
36
- ## Configuration
21
+ ```bash
22
+ curl -fsSL https://bun.sh/install | bash
23
+ ```
37
24
 
38
- ### Environment Variables
25
+ ### Run
39
26
 
40
- Create a `.env` file in the `data/` directory with the following variables:
27
+ ```bash
28
+ # Start dashboard in foreground
29
+ clocktopus dash
41
30
 
31
+ # Or as a background daemon
32
+ clocktopus serve
42
33
  ```
43
- CLOCKIFY_API_KEY="your_clockify_api_key_here"
44
- ATLASSIAN_CLIENT_ID="your_atlassian_oauth_client_id"
45
- ATLASSIAN_CLIENT_SECRET="your_atlassian_oauth_client_secret"
46
- GOOGLE_CLIENT_ID="google_client_id"
47
- GOOGLE_CLIENT_SECRET="google_client_secret"
48
- ```
49
-
50
- You can get your Clockify API key from [Manage API Keys](https://app.clockify.me/manage-api-keys).
51
34
 
52
- ### Jira Integration (Atlassian OAuth)
35
+ Open [http://localhost:4001](http://localhost:4001) in your browser.
53
36
 
54
- Clocktopus uses Atlassian OAuth 2.0 so users can connect their Jira account with a single click from the dashboard instead of manually copying API tokens.
37
+ ### Setup
55
38
 
56
- #### Setting up the Atlassian OAuth App
39
+ 1. Go to **Settings** tab
40
+ 2. Enter your **Clockify API key** ([get one here](https://app.clockify.me/manage-api-keys))
41
+ 3. Click **Pull from Clockify** in the Projects tab
42
+ 4. Optionally connect **Jira** and **Google Calendar** with one click
57
43
 
58
- 1. Go to [Atlassian Developer Console](https://developer.atlassian.com/console/myapps/) and create a new **OAuth 2.0 (3LO)** app
59
- 2. Under **Authorization**, set the callback URL to:
60
- ```
61
- http://localhost:4001/api/jira/callback
62
- ```
63
- 3. Under **Permissions**, add the following scopes:
64
- - **Jira API**: `read:jira-work`, `write:jira-work`
65
- - **User identity API**: `read:me`
66
- 4. Copy the **Client ID** and **Client Secret** from the app's **Settings** page
67
- 5. Add them to your `.env` file as `ATLASSIAN_CLIENT_ID` and `ATLASSIAN_CLIENT_SECRET`
68
- 6. Start the dashboard (`bun run dashboard`) and click **Connect Atlassian**
44
+ That's it. Start/stop timers from the Home tab.
69
45
 
70
- > **Fallback:** If you prefer using an API token instead of OAuth, you can expand the "or use API token" section on the dashboard and enter your credentials manually. For this, set the following in `.env`:
71
- >
72
- > ```
73
- > ATLASSIAN_URL="https://your_org.atlassian.net/rest/api/3"
74
- > ATLASSIAN_API_TOKEN="your_atlassian_api_token_here"
75
- > ATLASSIAN_EMAIL="username@example.com"
76
- > ```
46
+ ### Dashboard Commands
77
47
 
78
- ### Local Projects Filtering
48
+ | Command | Description |
49
+ | ----------------------- | ------------------------------------ |
50
+ | `clocktopus dash` | Start dashboard (foreground) |
51
+ | `clocktopus serve` | Start dashboard as background daemon |
52
+ | `clocktopus serve:stop` | Stop the dashboard daemon |
53
+ | `clocktopus serve:logs` | View dashboard daemon logs |
79
54
 
80
- The CLI allows you to filter the projects displayed when starting a new time entry. On the first run of the `clock start` command, the application will fetch all your Clockify projects and populate `data/local-projects.json` with their IDs and names. You can then edit this file to keep only the projects you frequently work on.
55
+ ### Desktop App
81
56
 
82
- Example `data/local-projects.json`:
83
-
84
- ```json
85
- [
86
- {
87
- "id": "671b783fbd91bc5e5ddcb944",
88
- "name": "2024 Project Management Traineeship"
89
- },
90
- {
91
- "id": "another_project_id",
92
- "name": "Another Project Name"
93
- }
94
- ]
95
- ```
57
+ A macOS menu bar app is available — see [desktop/README.md](desktop/README.md) for setup. It wraps the dashboard with a system tray icon that shows timer status.
96
58
 
97
- Remove any project objects (both `id` and `name`) that you don't want to appear in the project selection list.
59
+ ---
98
60
 
99
- ## Usage
61
+ ## Power User Guide
100
62
 
101
- ### Build the application
63
+ For CLI-based workflows, scripting, and advanced features.
102
64
 
103
- Before running, you need to compile the TypeScript code:
65
+ ### Install from Source
104
66
 
105
67
  ```bash
68
+ git clone https://github.com/sajxraj/clocktopus.git
69
+ cd clocktopus
70
+ bun install
106
71
  bun run build
107
72
  ```
108
73
 
109
- ### Run the application
74
+ ### Local Development
110
75
 
111
- Once built, you can run the CLI commands using the following commands:
76
+ When running from source, use `bun run clock` instead of `clocktopus`:
112
77
 
113
- - **Monitor idle state and auto-manage timers:**
114
-
115
- ```bash
116
- bun run monitor
117
- ```
78
+ ```bash
79
+ # Build first
80
+ bun run build
118
81
 
119
- This command will monitor your system's idle time and automatically manage your Clockify timer:
120
- - If you are idle for more than 5 minutes, the currently running timer will be stopped.
121
- - When you become active again (move the mouse, press a key, etc.), if your last session was auto-completed due to idleness, a new timer will automatically be created for the last used project.
122
- - All session events (start, stop, auto-complete, resume) are logged locally in the SQLite database, including project and description.
82
+ # Dashboard
83
+ bun run dashboard # Start dashboard (foreground)
123
84
 
124
- This ensures your time tracking is accurate even if you step away from your computer or forget to manually stop and restart your timer.
85
+ # Timer
86
+ bun run clock start "Task" # Start a timer
87
+ bun run clock start -j PROJ-1 # Start with Jira ticket
88
+ bun run clock stop # Stop timer
89
+ bun run clock status # Check timer status
125
90
 
126
- > Note: This ensures your time tracking is accurate even if you step away from your computer or forget to manually stop and restart your timer.
127
- > If you do not want the background process to check your idle state, you can skip this.
91
+ # Monitor
92
+ bun run monitor # Start idle monitor (PM2 daemon)
93
+ bun run monitor:stop # Stop monitor
94
+ bun run monitor:restart # Restart monitor
95
+ bun run monitor:status # Check monitor status
96
+ bun run monitor:logs # View monitor logs
128
97
 
129
- - **Start a new time entry:**
98
+ # Google Calendar
99
+ bun run google-auth # Authenticate Google account
100
+ bun run log-calendar -t # Log today's events
130
101
 
131
- ```bash
132
- bun run clock start "Task description"
133
- ```
102
+ # Database
103
+ bun run db:cleanup # Clean old session logs
104
+ ```
134
105
 
135
- This will prompt you to select a project from your curated list.
106
+ ### CLI Commands
136
107
 
137
- - **Start a new time entry with a Jira ticket:**
108
+ #### Timer Management
138
109
 
139
- ```bash
140
- bun run clock start -j TICKET-123
141
- ```
110
+ ```bash
111
+ # Start a timer (interactive project selection)
112
+ clocktopus start "Task description"
142
113
 
143
- When you provide a Jira ticket number with the `-j` flag, the tool will automatically fetch the ticket's title from Jira and prepend it to your time entry description. For example, if the title of `TICKET-123` is "Fix the login button", the description will be saved as `TICKET-123 Fix the login button`. If you also provide a description, it will be appended after the Jira title.
114
+ # Start with a Jira ticket (auto-fetches ticket title)
115
+ clocktopus start -j TICKET-123
144
116
 
145
- - **Stop the currently running time entry:**
117
+ # Stop the current timer
118
+ clocktopus stop
146
119
 
147
- ```bash
148
- bun run clock stop
149
- ```
120
+ # Check timer status
121
+ clocktopus status
122
+ ```
150
123
 
151
- - **Check the status of the current timer:**
152
- ```bash
153
- bun run clock status
154
- ```
124
+ #### Idle Monitor
155
125
 
156
- ### Manage Monitor
126
+ Automatically stops timers when you're idle (5 min) or lock your screen, and restarts when you're back.
157
127
 
158
- - **Restart the monitor process (after code changes):**
128
+ ```bash
129
+ # Run in foreground
130
+ clocktopus monitor
159
131
 
160
- ```bash
161
- bun run monitor:restart
162
- ```
132
+ # Or manage via dashboard UI (Start/Stop/Restart buttons)
133
+ ```
163
134
 
164
- Use this command to restart the monitor process, for example after making code changes or updating dependencies. This ensures the monitor is running the latest version of your code.
135
+ The dashboard's Idle Monitor buttons use PM2 under the hood:
165
136
 
166
- - **Stop the monitor process:**
137
+ | Action | What it does |
138
+ | ----------- | ------------------------------ |
139
+ | **Start** | Launches monitor as PM2 daemon |
140
+ | **Stop** | Stops the monitor daemon |
141
+ | **Restart** | Restarts after code changes |
167
142
 
168
- ```bash
169
- bun run monitor:stop
170
- ```
143
+ #### Google Calendar Integration
171
144
 
172
- This command will stop the monitor process if it is running in the background. Use this when you want to fully halt all automatic idle monitoring and timer management.
145
+ Log Google Calendar events as Clockify time entries.
173
146
 
174
- - **Show monitor logs:**
147
+ ```bash
148
+ # Authenticate (one-time)
149
+ clocktopus google-auth
175
150
 
176
- ```bash
177
- bun run monitor:logs
178
- ```
151
+ # Log events for a date range
152
+ clocktopus log-calendar -s 2025-07-21 -e 2025-07-22
179
153
 
180
- This command will display logs related to the monitor process. Use it to review idle/active transitions, timer events, and session details that have been recorded while the monitor was running. This is useful for troubleshooting, auditing, or reviewing your time tracking history.
154
+ # Log today's events
155
+ clocktopus log-calendar -t
156
+ ```
181
157
 
182
- ### Database Cleanup
158
+ For each event, you'll be prompted to select a Clockify project. Selections are cached by event name for recurring meetings.
183
159
 
184
- To delete old session logs from the local SQLite database, use the `db:cleanup` command:
160
+ #### Database Cleanup
185
161
 
186
162
  ```bash
187
- bun run db:cleanup <older-than-number-in-days>
188
- ```
163
+ # Delete session logs older than 5 days (default)
164
+ clocktopus db:cleanup
189
165
 
190
- - `<older-than-number-in-days>` (Optional): Specifies the number of days. Session logs older than this number of days will be deleted. If not provided, logs older than 5 days will be deleted by default.
191
-
192
- Examples:
166
+ # Delete logs older than N days
167
+ clocktopus db:cleanup 10
168
+ ```
193
169
 
194
- - Delete logs older than 5 days (default):
170
+ ### Configuration
195
171
 
196
- ```bash
197
- bun run db:cleanup
198
- ```
172
+ All configuration is stored in a local SQLite database (`data/sessions.db`) and managed through the dashboard Settings tab. No `.env` file is needed.
199
173
 
200
- - Delete logs older than 5 days:
201
- ```bash
202
- bun run db:cleanup 5
203
- ```
174
+ | Setting | How to configure |
175
+ | ---------------- | ------------------------------------------------ |
176
+ | Clockify API Key | Dashboard > Settings > Clockify |
177
+ | Jira (OAuth) | Dashboard > Settings > Click "Connect Atlassian" |
178
+ | Jira (API token) | Dashboard > Settings > "or use API token" |
179
+ | Google Calendar | Dashboard > Settings > Click "Connect Google" |
204
180
 
205
- ### Google Calendar Integration
181
+ #### OAuth Architecture
206
182
 
207
- This tool can log your Google Calendar events as time entries in Clockify. This is particularly useful for automatically tracking time spent in meetings or other scheduled events.
183
+ - **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.
184
+ - **Google**: Uses a Desktop-type OAuth client. Credentials are handled transparently.
185
+ - **Clockify**: Each user provides their own API key.
208
186
 
209
- #### 1. Google Authentication
187
+ #### Environment Variables (Optional Override)
210
188
 
211
- Before you can log calendar events, you need to authenticate with your Google account. This will grant the tool read-only access to your Google Calendar.
189
+ Power users can override credentials via environment variables or a `.env` file:
212
190
 
213
- ```bash
214
- bun run google-auth
191
+ ```
192
+ CLOCKIFY_API_KEY="your_key"
193
+ ATLASSIAN_CLIENT_ID="your_id"
194
+ ATLASSIAN_CLIENT_SECRET="your_secret"
195
+ GOOGLE_CLIENT_ID="your_id"
196
+ GOOGLE_CLIENT_SECRET="your_secret"
215
197
  ```
216
198
 
217
- Follow the prompts in your browser to complete the authentication process. A token will be stored locally to maintain your session.
199
+ The app checks the database first, then falls back to environment variables.
218
200
 
219
- #### 2. Log Calendar Events
201
+ ### Local Project Filtering (CLI only)
220
202
 
221
- Once authenticated, you can log events for a specific date range:
203
+ On first `clocktopus start`, all projects are saved to `data/local-projects.json`. Edit this file to keep only your frequently used projects:
222
204
 
223
- ```bash
224
- bun run log-calendar -s <start-date> -e <end-date>
205
+ ```json
206
+ [
207
+ { "id": "671b783fbd91bc5e5ddcb944", "name": "Project A" },
208
+ { "id": "another_id", "name": "Project B" }
209
+ ]
225
210
  ```
226
211
 
227
- - `<start-date>`: The start date for fetching calendar events (e.g., `2025-07-21`).
228
- - `<end-date>`: The end date for fetching calendar events (e.g., `2025-07-22`).
212
+ ### Shell Aliases
229
213
 
230
- You can also log events for today using the `-t` or `--today` flag:
214
+ For quick access, add to `~/.zshrc`:
231
215
 
232
216
  ```bash
233
- bun run log-calendar -t
234
- ```
235
-
236
- For each calendar event, the tool will prompt you to select a Clockify project. Your selection will be cached based on the event's summary (name), so if you have recurring events with the same name, you will only be asked once for the project. If you provide a `project-id` using the `-p` flag, all events will be logged to that project without prompting.
217
+ CLOCKTOPUS_PATH="$HOME/Projects/Personal/clocktopus"
237
218
 
238
- Example:
219
+ clockto() {
220
+ cd "$CLOCKTOPUS_PATH" || return
221
+ bun run "$@"
222
+ }
239
223
 
240
- ```bash
241
- bun run log-calendar -s 2025-07-21 -e 2025-07-22
224
+ alias cbuild="clockto build"
225
+ alias cstart="clockto clock start"
226
+ alias cstop="clockto clock stop"
227
+ alias mstart="clockto monitor"
228
+ alias mstop="clockto monitor:stop"
229
+ alias mrestart="clockto monitor:restart"
230
+ alias mlogs="clockto monitor:logs"
242
231
  ```
243
232
 
244
- Or, to log all events to a specific project:
245
-
246
- ```bash
247
- bun run log-calendar -s 2025-07-21 -e 2025-07-22 -p your_clockify_project_id
248
- ```
233
+ ---
249
234
 
250
235
  ## Troubleshooting
251
236
 
252
237
  ### No notifications on macOS
253
238
 
254
- If you are not receiving notifications on macOS, you may need to adjust your system settings.
255
-
256
- - **Check System Settings for Notifications:**
257
- - Go to **System Settings > Notifications**.
258
- - Look for **Terminal** (or your specific terminal application if you use another one like iTerm).
259
- - Make sure that **Allow Notifications** is turned on for it.
260
- - If you see an entry for **Node**, ensure it also has permissions.
239
+ Go to **System Settings > Notifications** and ensure **terminal-notifier** (or your terminal app) has notifications enabled.
261
240
 
262
- Often, the first time a script tries to send a notification, macOS will ask for permission. If this was accidentally denied, you won't see any notifications.
241
+ ### Monitor not detecting display off
263
242
 
264
- ## Linux Requirements
243
+ 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.
265
244
 
266
- X server development package and pkg-config are required to run `desktop-idle` package:
245
+ ### Linux Requirements
267
246
 
268
- ```
247
+ ```bash
269
248
  apt install libxss-dev pkg-config build-essential
270
249
  ```
271
250
 
272
- ## Zsh Alias
273
-
274
- If you super lazy just like me, then you can add aliases for different actions. Here is what I use:
275
-
276
- ```bash
277
- # Clocktopus
278
- CLOCKTOPUS_PATH="$HOME/Projects/Personal/clocktopus"
251
+ ---
279
252
 
280
- clocktopus() {
281
- cd "$CLOCKTOPUS_PATH" || return
282
- bun run "$@"
283
- }
253
+ ## Project Structure
284
254
 
285
- alias cbuild="clocktopus build"
286
- alias cstart="clocktopus clock start"
287
- alias cstop="clocktopus clock stop"
288
- alias mstart="clocktopus monitor"
289
- alias mstop="clocktopus monitor:stop"
290
- alias mrestart="clocktopus monitor:restart"
291
- alias mstatus="clocktopus monitor:status"
292
- alias mlogs="clocktopus monitor:logs"
293
- alias cgcalauth="clocktopus google-auth"
294
- alias cgcal="clocktopus log-calendar"
295
255
  ```
256
+ clocktopus/
257
+ ├── index.ts # CLI entry point (Commander)
258
+ ├── clockify.ts # Clockify API client
259
+ ├── lib/ # Core libraries (db, auth, credentials)
260
+ ├── dashboard/ # Web dashboard (Hono server)
261
+ │ ├── server.ts # Dashboard server
262
+ │ ├── views.ts # HTML/CSS/JS (single-page app)
263
+ │ └── routes/ # API routes
264
+ ├── desktop/ # Tauri macOS menu bar app
265
+ ├── proxy/ # Cloudflare Worker (OAuth proxy)
266
+ ├── scripts/ # Google auth & calendar scripts
267
+ └── data/ # SQLite DB & config (gitignored)
268
+ ```
269
+
270
+ ## License
296
271
 
297
- Copy the above code in `.zshrc` file, change `CLOCKTOPUS_PATH` based on your path and save it. Then source the file using `source ~/.zshrc`.
272
+ MIT
package/dist/index.js CHANGED
@@ -1,4 +1,4 @@
1
- #!/usr/bin/env node
1
+ #!/usr/bin/env bun
2
2
  import { Command } from 'commander';
3
3
  import inquirer from 'inquirer';
4
4
  import chalk from 'chalk';
@@ -46,7 +46,8 @@ async function getWorkspaceAndUser() {
46
46
  userId,
47
47
  };
48
48
  }
49
- program.name('clocktopus').description('CLI time-tracking automation for Clockify').version('1.0.0');
49
+ const pkg = JSON.parse(fs.readFileSync(path.join(__dirname, '../package.json'), 'utf-8'));
50
+ program.name('clocktopus').description('CLI time-tracking automation for Clockify').version(pkg.version);
50
51
  program
51
52
  .command('start')
52
53
  .description('Start a new time entry. Select a project interactively.')
@@ -274,4 +275,52 @@ program
274
275
  .action(() => {
275
276
  startDashboard();
276
277
  });
278
+ program
279
+ .command('serve')
280
+ .description('Start dashboard as a background daemon (PM2).')
281
+ .action(async () => {
282
+ const { execSync } = await import('child_process');
283
+ const bunPath = execSync('which bun', { encoding: 'utf-8' }).trim();
284
+ const scriptPath = path.join(__dirname, 'index.js');
285
+ try {
286
+ // Stop existing if running
287
+ try {
288
+ execSync('bunx pm2 delete clocktopus-dash', { stdio: 'ignore' });
289
+ }
290
+ catch { }
291
+ execSync(`bunx pm2 start ${scriptPath} --name clocktopus-dash --interpreter ${bunPath} -- dash`, {
292
+ stdio: 'inherit',
293
+ });
294
+ console.log(chalk.green('Dashboard running at http://localhost:4001'));
295
+ console.log(chalk.gray(' Stop: clocktopus serve:stop'));
296
+ console.log(chalk.gray(' Logs: clocktopus serve:logs'));
297
+ }
298
+ catch {
299
+ console.error(chalk.red('Failed to start dashboard daemon.'));
300
+ }
301
+ });
302
+ program
303
+ .command('serve:stop')
304
+ .description('Stop the dashboard daemon.')
305
+ .action(async () => {
306
+ const { execSync } = await import('child_process');
307
+ try {
308
+ execSync('bunx pm2 stop clocktopus-dash', { stdio: 'inherit' });
309
+ }
310
+ catch {
311
+ console.log(chalk.yellow('Dashboard is not running.'));
312
+ }
313
+ });
314
+ program
315
+ .command('serve:logs')
316
+ .description('Show dashboard daemon logs.')
317
+ .action(async () => {
318
+ const { execSync } = await import('child_process');
319
+ try {
320
+ execSync('bunx pm2 logs clocktopus-dash --lines 50', { stdio: 'inherit' });
321
+ }
322
+ catch {
323
+ console.log(chalk.yellow('Dashboard is not running.'));
324
+ }
325
+ });
277
326
  program.parse(process.argv);
@@ -2,7 +2,7 @@ import axios from 'axios';
2
2
  import { resolveCredential } from './credentials.js';
3
3
  import { getAtlassianToken, updateAtlassianAccessToken } from './db.js';
4
4
  // Cloudflare Worker proxy that holds the client secret
5
- const AUTH_PROXY_URL = 'https://clocktopus-auth.clocktopus.workers.dev/';
5
+ const AUTH_PROXY_URL = 'https://clocktopus-auth.clocktopus.workers.dev';
6
6
  // Fallback: direct Atlassian API (when user provides their own credentials)
7
7
  const ATLASSIAN_TOKEN_URL = 'https://auth.atlassian.com/oauth/token';
8
8
  const ATLASSIAN_RESOURCES_URL = 'https://api.atlassian.com/oauth/token/accessible-resources';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "clocktopus",
3
- "version": "1.0.1",
3
+ "version": "1.0.3",
4
4
  "type": "module",
5
5
  "main": "dist/index.js",
6
6
  "bin": {
@@ -42,7 +42,8 @@
42
42
  "macos-notification-state": "^3.0.0",
43
43
  "node-notifier": "^10.0.1",
44
44
  "uuid": "^11.1.0",
45
- "zod": "^3.25.76"
45
+ "zod": "^3.25.76",
46
+ "pm2": "^6.0.8"
46
47
  },
47
48
  "devDependencies": {
48
49
  "@types/bun": "^1.3.11",
@@ -55,7 +56,6 @@
55
56
  "eslint-config-prettier": "^10.1.5",
56
57
  "eslint-plugin-prettier": "^5.5.1",
57
58
  "husky": "^9.1.7",
58
- "pm2": "^6.0.8",
59
59
  "prettier": "^3.6.2",
60
60
  "ts-node": "^10.9.2",
61
61
  "typescript": "^5.8.3",