@micsushi/agent-hotline 0.5.1

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 ADDED
@@ -0,0 +1,167 @@
1
+ # Agent Hotline
2
+
3
+ Agent Hotline is a local Windows tray app that reads useful parts of Codex, Claude Code, and Antigravity replies aloud.
4
+
5
+ You keep using your coding tool like normal. Agent Hotline listens for finished responses through local hooks, skips code-heavy bits, and reads the useful prose through the desktop WebView. The full reply stays in the original chat.
6
+
7
+ ## What It Does
8
+
9
+ - Reads finished coding-agent replies aloud.
10
+ - Skips code blocks, diffs, logs, JSON, tables, and big dumps.
11
+ - Lets you save replies or auto-play them when idle.
12
+ - Gives you read, pause, resume, stop, replay, mute, and unmute controls.
13
+ - Stores settings under `%APPDATA%\Agent Hotline\`.
14
+ - Does not need model API keys or paid speech APIs for read-aloud.
15
+
16
+ ## Status
17
+
18
+ Good enough for local development use.
19
+
20
+ Still missing:
21
+
22
+ - A normal packaged installer.
23
+ - A bundled backend sidecar for production installs.
24
+ - Voice input owned by Agent Hotline.
25
+
26
+ ## Requirements
27
+
28
+ - Windows 10 or 11.
29
+ - Node.js 22 or newer.
30
+ - For terminal install only: no repo clone is needed.
31
+ - For desktop app development: Rust plus the usual Tauri Windows prerequisites.
32
+
33
+ ## Install
34
+
35
+ ### Terminal install from npm
36
+
37
+ Use this on a normal machine that should not clone this repo:
38
+
39
+ ```powershell
40
+ npx --yes @micsushi/agent-hotline install --harness all --skill all
41
+ ```
42
+
43
+ That one command downloads the Agent Hotline npm package and installs both parts:
44
+
45
+ - the hook/tool command used by Codex, Claude Code, and Antigravity
46
+ - the spoken-output skill or managed instructions
47
+
48
+ Start the local backend:
49
+
50
+ ```powershell
51
+ npx --yes @micsushi/agent-hotline run
52
+ ```
53
+
54
+ For one repo only:
55
+
56
+ ```powershell
57
+ npx --yes @micsushi/agent-hotline install --harness all --skill all --scope repo --repo C:\path\to\repo
58
+ ```
59
+
60
+ Optional: install once globally so you can use shorter commands:
61
+
62
+ ```powershell
63
+ npm install -g @micsushi/agent-hotline
64
+ agent-hotline install --harness all --skill all
65
+ agent-hotline run
66
+ ```
67
+
68
+ Useful separate commands:
69
+
70
+ ```powershell
71
+ npx --yes @micsushi/agent-hotline install-hooks --harness all
72
+ npx --yes @micsushi/agent-hotline install-skill --target all
73
+ npx --yes @micsushi/agent-hotline hook
74
+ ```
75
+
76
+ ### Local checkout install
77
+
78
+ Use this only when developing Agent Hotline from this repo:
79
+
80
+ ```powershell
81
+ npm install
82
+ npm run install-hotline -- --harness all --skill all
83
+ ```
84
+
85
+ `npm install` also grabs the local TTS assets used by the desktop app. To repair those assets:
86
+
87
+ ```powershell
88
+ npm run install:tts
89
+ ```
90
+
91
+ ## What Gets Installed
92
+
93
+ The npm package includes the CLI/backend hook tool and the spoken skill/instructions. Users do not download those separately.
94
+
95
+ The polished desktop installer is not finished yet. Until then, the desktop control panel is run from a local checkout.
96
+
97
+ ## Run Locally
98
+
99
+ From a global install, start the backend:
100
+
101
+ ```powershell
102
+ ah run
103
+ ```
104
+
105
+ From `npx`, start the backend:
106
+
107
+ ```powershell
108
+ npx --yes @micsushi/agent-hotline run
109
+ ```
110
+
111
+ From a local checkout, run it in the foreground while developing:
112
+
113
+ ```powershell
114
+ npm run dev:backend
115
+ ```
116
+
117
+ Start the desktop app:
118
+
119
+ ```powershell
120
+ npm run dev:desktop
121
+ ```
122
+
123
+ Backend URL:
124
+
125
+ ```text
126
+ http://127.0.0.1:4777
127
+ ```
128
+
129
+ ## Smoke Test
130
+
131
+ With the backend running, test the npm-installed hook:
132
+
133
+ ```powershell
134
+ '{"source":"codex","response":{"text":"Spoken:`nAgent Hotline is ready to read this aloud.`n`nDisplayed:`nSmoke test complete."}}' | npx --yes @micsushi/agent-hotline hook
135
+ ```
136
+
137
+ From a local checkout, test the local hook:
138
+
139
+ ```powershell
140
+ '{"source":"codex","response":{"text":"Spoken:`nAgent Hotline is ready to read this aloud.`n`nDisplayed:`nSmoke test complete."}}' | node packages/backend/bin/agent-hotline.js hook
141
+ ```
142
+
143
+ The sentence should show up in the Agent Hotline queue. If the backend is not running, the hook exits quietly.
144
+
145
+ ## Checks
146
+
147
+ ```powershell
148
+ npm test
149
+ npm run lint
150
+ npm run format:check
151
+ npm run check
152
+ ```
153
+
154
+ ## Docs
155
+
156
+ - [Docs index](docs/README.md)
157
+ - [Codex setup](docs/integrations/codex.md)
158
+ - [Claude Code setup](docs/integrations/claude-code.md)
159
+ - [Antigravity setup](docs/integrations/antigravity.md)
160
+
161
+ ## Repo Layout
162
+
163
+ ```text
164
+ docs/ Human setup notes
165
+ packages/backend/ Local API, queue, settings, hook command
166
+ packages/desktop/ Tauri tray app and control panel
167
+ ```
package/docs/README.md ADDED
@@ -0,0 +1,30 @@
1
+ # Agent Hotline Docs
2
+
3
+ Short setup notes for people using or hacking on Agent Hotline.
4
+
5
+ ## Setup
6
+
7
+ - [Codex](integrations/codex.md)
8
+ - [Claude Code](integrations/claude-code.md)
9
+ - [Antigravity](integrations/antigravity.md)
10
+ - [Spoken output](integrations/spoken-output.md)
11
+
12
+ ## Common Commands
13
+
14
+ ```powershell
15
+ npm run install:tts
16
+ npm run install-hotline -- --harness all --skill all
17
+ npm run dev:backend
18
+ npm run dev:desktop
19
+ ```
20
+
21
+ From npm:
22
+
23
+ ```powershell
24
+ npx --yes @micsushi/agent-hotline install --harness all --skill all
25
+ npx --yes @micsushi/agent-hotline hook
26
+ ```
27
+
28
+ ## Notes
29
+
30
+ Read-aloud playback is local. Agent Hotline talks to its local backend and uses browser/WebView text-to-speech.
@@ -0,0 +1,62 @@
1
+ # Antigravity Setup
2
+
3
+ Agent Hotline can read Antigravity replies aloud through its global hook setup. It only talks to the local Agent Hotline backend.
4
+
5
+ ## Install
6
+
7
+ Start Agent Hotline first:
8
+
9
+ ```powershell
10
+ npm install
11
+ npm run dev:backend
12
+ npm run dev:desktop
13
+ ```
14
+
15
+ Install the Antigravity hook and spoken skill:
16
+
17
+ ```powershell
18
+ npm run install-hotline -- --harness antigravity --skill antigravity
19
+ ```
20
+
21
+ For a different backend URL, set `AGENT_HOTLINE_URL` before starting Antigravity.
22
+
23
+ ## Use It
24
+
25
+ In Antigravity, say:
26
+
27
+ ```text
28
+ hotline on
29
+ ```
30
+
31
+ To stop adding read-aloud sections:
32
+
33
+ ```text
34
+ hotline off
35
+ ```
36
+
37
+ ## Test
38
+
39
+ ```powershell
40
+ @{
41
+ source = "antigravity"
42
+ hook_event_name = "Stop"
43
+ assistant_response = @{
44
+ text = "Spoken:`nAgent Hotline is ready to read Antigravity aloud.`n`nDisplayed:`nSmoke test complete."
45
+ }
46
+ } | ConvertTo-Json -Depth 8 | node packages/backend/bin/agent-hotline.js hook
47
+ ```
48
+
49
+ If Agent Hotline is running, the sentence lands in the queue.
50
+
51
+ ## Turn It Off
52
+
53
+ - Remove the `Stop` hook from `%USERPROFILE%\.gemini\config\hooks.json`.
54
+ - Or say `hotline off` in the session.
55
+ - Or turn off Antigravity playback in Agent Hotline settings.
56
+
57
+ ## Troubleshooting
58
+
59
+ - No audio: make sure the backend and desktop app are running.
60
+ - Nothing queued: say `hotline on` and try again.
61
+ - Different port: set `AGENT_HOTLINE_URL`.
62
+ - Hook diagnostics: set `AGENT_HOTLINE_HOOK_DEBUG=1`.
@@ -0,0 +1,48 @@
1
+ # Claude Code Setup
2
+
3
+ Agent Hotline can read Claude Code replies aloud through a `Stop` hook. It only talks to the local Agent Hotline backend.
4
+
5
+ ## Install
6
+
7
+ Start Agent Hotline first:
8
+
9
+ ```powershell
10
+ npm install
11
+ npm run dev:backend
12
+ npm run dev:desktop
13
+ ```
14
+
15
+ Then install the Claude Code hook and spoken-output instructions:
16
+
17
+ ```powershell
18
+ npx --yes @micsushi/agent-hotline install --harness claude-code --skill claude-code --scope global
19
+ ```
20
+
21
+ From a local checkout:
22
+
23
+ ```powershell
24
+ npm run install-hotline -- --harness claude-code --skill claude-code --scope global
25
+ ```
26
+
27
+ For a different backend URL, set `AGENT_HOTLINE_URL` before starting Claude Code.
28
+
29
+ ## Test
30
+
31
+ ```powershell
32
+ '{"source":"claude","assistant_response":{"text":"Spoken:`nAgent Hotline is ready to read Claude Code aloud.`n`nDisplayed:`nSmoke test complete."}}' | node packages/backend/bin/agent-hotline.js hook
33
+ ```
34
+
35
+ If Agent Hotline is running, the sentence lands in the queue. If not, the hook exits quietly.
36
+
37
+ ## Turn It Off
38
+
39
+ - Repo setup: remove the hook from `.claude/settings.local.json`.
40
+ - Global setup: remove it from `%USERPROFILE%\.claude\settings.json`.
41
+ - Temporary: turn off Claude playback in Agent Hotline settings.
42
+
43
+ ## Troubleshooting
44
+
45
+ - No audio: make sure the backend and desktop app are running.
46
+ - Nothing queued: the reply may have been filtered out, or Claude playback may be off.
47
+ - Different port: set `AGENT_HOTLINE_URL`.
48
+ - Hook diagnostics: set `AGENT_HOTLINE_HOOK_DEBUG=1` before starting Claude Code.
@@ -0,0 +1,48 @@
1
+ # Codex Setup
2
+
3
+ Agent Hotline can read Codex replies aloud through a Codex `Stop` hook. It only talks to the local Agent Hotline backend.
4
+
5
+ ## Install
6
+
7
+ Start Agent Hotline first:
8
+
9
+ ```powershell
10
+ npm install
11
+ npm run dev:backend
12
+ npm run dev:desktop
13
+ ```
14
+
15
+ Then install the Codex hook and spoken-output instructions:
16
+
17
+ ```powershell
18
+ npx --yes @micsushi/agent-hotline install --harness codex --skill codex --scope global
19
+ ```
20
+
21
+ From a local checkout:
22
+
23
+ ```powershell
24
+ npm run install-hotline -- --harness codex --skill codex --scope global
25
+ ```
26
+
27
+ For a different backend URL, set `AGENT_HOTLINE_URL` before starting Codex.
28
+
29
+ ## Test
30
+
31
+ ```powershell
32
+ '{"source":"codex","response":{"text":"Spoken:`nAgent Hotline is ready to read Codex aloud.`n`nDisplayed:`nSmoke test complete."}}' | node packages/backend/bin/agent-hotline.js hook
33
+ ```
34
+
35
+ If Agent Hotline is running, the sentence lands in the queue. If not, the hook exits quietly.
36
+
37
+ ## Turn It Off
38
+
39
+ - Repo setup: remove the hook from `<repo>\.codex\hooks.json`.
40
+ - Global setup: remove it from `%USERPROFILE%\.codex\hooks.json`.
41
+ - Temporary: turn off Codex playback in Agent Hotline settings.
42
+
43
+ ## Troubleshooting
44
+
45
+ - No audio: make sure the backend and desktop app are running.
46
+ - Nothing queued: the reply may have been filtered out, or Codex playback may be off.
47
+ - Different port: set `AGENT_HOTLINE_URL`.
48
+ - Hook diagnostics: set `AGENT_HOTLINE_HOOK_DEBUG=1` before starting Codex.
@@ -0,0 +1,36 @@
1
+ # Spoken Output
2
+
3
+ Agent Hotline works best when a reply has a short `Spoken:` section. It reads that part and ignores the rest.
4
+
5
+ Install the formatting instructions:
6
+
7
+ ```powershell
8
+ npm run install-skill -- --target all
9
+ ```
10
+
11
+ From npm:
12
+
13
+ ```powershell
14
+ agent-hotline install-skill --target all
15
+ ```
16
+
17
+ ## Contract
18
+
19
+ ```text
20
+ Spoken:
21
+ A short, conversational summary meant to be heard.
22
+
23
+ ==========
24
+
25
+ Displayed:
26
+ The full normal answer with code, paths, commands, and details.
27
+ ```
28
+
29
+ Keep `Spoken:` short and plain. Put everything technical in `Displayed:`.
30
+
31
+ ## Verify
32
+
33
+ 1. Start Agent Hotline.
34
+ 2. Install the hook and spoken-output instructions.
35
+ 3. Ask for a normal reply.
36
+ 4. Confirm Agent Hotline reads only the `Spoken:` text.
package/package.json ADDED
@@ -0,0 +1,62 @@
1
+ {
2
+ "name": "@micsushi/agent-hotline",
3
+ "version": "0.5.1",
4
+ "description": "Local read-aloud hooks and tray app for AI coding agents.",
5
+ "bin": {
6
+ "ah": "packages/backend/bin/agent-hotline.js",
7
+ "agent-hotline": "packages/backend/bin/agent-hotline.js",
8
+ "agent-hotline-hook": "packages/backend/bin/agent-hotline-hook.js"
9
+ },
10
+ "files": [
11
+ "README.md",
12
+ "docs/",
13
+ "packages/backend/bin/",
14
+ "packages/backend/src/",
15
+ "packages/backend/skills/",
16
+ "packages/backend/package.json"
17
+ ],
18
+ "publishConfig": {
19
+ "access": "public"
20
+ },
21
+ "engines": {
22
+ "node": ">=18"
23
+ },
24
+ "workspaces": [
25
+ "packages/*"
26
+ ],
27
+ "scripts": {
28
+ "start": "npm --prefix packages/backend start",
29
+ "dev:backend": "npm --prefix packages/backend start",
30
+ "dev:desktop": "npm --workspace @agent-hotline/desktop run dev",
31
+ "install:tts": "npm --workspace @agent-hotline/desktop run install:tts",
32
+ "install-hook": "node scripts/install-hook.js",
33
+ "install-skill": "node scripts/install-skill.js",
34
+ "install-hotline": "node packages/backend/bin/agent-hotline.js install",
35
+ "test": "npm --prefix packages/backend test && npm --workspace @agent-hotline/desktop run test",
36
+ "lint": "eslint . && npm run rust:clippy",
37
+ "lint:fix": "eslint . --fix",
38
+ "fix": "prettier . --write && npm run lint:fix && npm run rust:fmt",
39
+ "format": "prettier . --write && npm run rust:fmt",
40
+ "format:check": "prettier . --check && npm run rust:fmt:check",
41
+ "verify:eol": "node scripts/verify-ci-eol.js",
42
+ "rust:fmt": "cargo fmt --manifest-path packages/desktop/src-tauri/Cargo.toml",
43
+ "rust:fmt:check": "cargo fmt --manifest-path packages/desktop/src-tauri/Cargo.toml --check",
44
+ "rust:clippy": "cargo clippy --manifest-path packages/desktop/src-tauri/Cargo.toml --all-targets -- -D warnings",
45
+ "check": "npm test && npm run format:check && npm run lint && npm --prefix packages/backend run check && npm --workspace @agent-hotline/desktop run check",
46
+ "ci": "npm ci && npm run check"
47
+ },
48
+ "devDependencies": {
49
+ "@eslint/js": "^10.0.1",
50
+ "eslint": "^10.5.0",
51
+ "globals": "^17.6.0",
52
+ "prettier": "^3.8.4"
53
+ },
54
+ "repository": {
55
+ "type": "git",
56
+ "url": "git+https://github.com/Micsushi/agent-hotline.git"
57
+ },
58
+ "homepage": "https://github.com/Micsushi/agent-hotline#readme",
59
+ "bugs": {
60
+ "url": "https://github.com/Micsushi/agent-hotline/issues"
61
+ }
62
+ }
@@ -0,0 +1,40 @@
1
+ # Agent Hotline Backend
2
+
3
+ Local HTTP backend for Agent Hotline.
4
+
5
+ This package owns hook parsing, text filtering, the speech queue, settings, local API routes, and the `agent-hotline hook` command.
6
+
7
+ ## Run
8
+
9
+ Background mode:
10
+
11
+ ```powershell
12
+ ah run
13
+ ```
14
+
15
+ Dev mode:
16
+
17
+ ```powershell
18
+ npm run dev:backend
19
+ ```
20
+
21
+ Default URL:
22
+
23
+ ```text
24
+ http://127.0.0.1:4777
25
+ ```
26
+
27
+ Use `AGENT_HOTLINE_PORT` to change the port.
28
+
29
+ Runtime data lives in:
30
+
31
+ ```text
32
+ %APPDATA%\Agent Hotline\
33
+ ```
34
+
35
+ ## Checks
36
+
37
+ ```powershell
38
+ npm --prefix packages/backend test
39
+ npm --prefix packages/backend run check
40
+ ```
@@ -0,0 +1,11 @@
1
+ #!/usr/bin/env node
2
+
3
+ const { main } = require("../src/hook-command");
4
+
5
+ main()
6
+ .then((exitCode) => {
7
+ process.exitCode = exitCode;
8
+ })
9
+ .catch(() => {
10
+ process.exitCode = 0;
11
+ });
@@ -0,0 +1,138 @@
1
+ #!/usr/bin/env node
2
+
3
+ const { main: hookMain } = require("../src/hook-command");
4
+ const { installHooks, installSkills, npxHookCommand, parseArgs } = require("../src/installer");
5
+ const { launchBackend } = require("../src/run-command");
6
+
7
+ function printHelp() {
8
+ console.log(`Agent Hotline
9
+
10
+ Usage:
11
+ agent-hotline run
12
+ agent-hotline hook
13
+ agent-hotline install --harness codex --skill codex
14
+ agent-hotline install-hooks --harness all
15
+ agent-hotline install-skill --target all
16
+ agent-hotline install --harness all --skill all
17
+
18
+ Options:
19
+ --harness antigravity|claude-code|codex|all
20
+ --target antigravity|claude-code|codex|all
21
+ --skill antigravity|claude-code|codex|all
22
+ --scope global|repo
23
+ --repo <path>
24
+ --home <path>
25
+ --hook-command <command>
26
+ --port <port> Backend port for "run" (default: 4777)
27
+ --use-npx-hook Write hooks that call "npx --yes @micsushi/agent-hotline hook"
28
+ `);
29
+ }
30
+
31
+ function printResults(title, results) {
32
+ console.log(title);
33
+ for (const result of results) {
34
+ console.log(
35
+ ` ${result.target || result.harness} (${result.scope}): ${result.path || result.configPath}`
36
+ );
37
+ }
38
+ }
39
+
40
+ function isNpmExec() {
41
+ return (
42
+ process.env.npm_command === "exec" ||
43
+ /\bnpm exec\b/.test(process.env.npm_config_user_agent || "")
44
+ );
45
+ }
46
+
47
+ function hookCommandFromArgs(args) {
48
+ if (args["hook-command"]) return args["hook-command"];
49
+ if (args["use-npx-hook"] || isNpmExec()) return npxHookCommand();
50
+ return undefined;
51
+ }
52
+
53
+ async function main(argv = process.argv.slice(2), options = {}) {
54
+ const [command, subcommand, ...rest] = argv;
55
+
56
+ if (!command || command === "--help" || command === "-h") {
57
+ printHelp();
58
+ return 0;
59
+ }
60
+
61
+ if (command === "hook") {
62
+ return hookMain();
63
+ }
64
+
65
+ if (command === "run" || command === "start") {
66
+ const args = parseArgs([subcommand, ...rest].filter(Boolean));
67
+ const launcher = options.launchBackend || launchBackend;
68
+ const result = launcher({ port: args.port });
69
+ console.log(`Agent Hotline backend started in the background on ${result.url}.`);
70
+ if (result.pid) {
71
+ console.log(`Process id: ${result.pid}`);
72
+ }
73
+ console.log("You can close this terminal; the backend will keep running.");
74
+ return 0;
75
+ }
76
+
77
+ if (command === "install-hooks") {
78
+ const args = parseArgs([subcommand, ...rest].filter(Boolean));
79
+ const results = installHooks({
80
+ harness: args.harness || "all",
81
+ scope: args.scope || "global",
82
+ repo: args.repo,
83
+ home: args.home,
84
+ hookCommand: hookCommandFromArgs(args)
85
+ });
86
+ printResults("Installed Agent Hotline hooks:", results);
87
+ return 0;
88
+ }
89
+
90
+ if (command === "install-skill") {
91
+ const args = parseArgs([subcommand, ...rest].filter(Boolean));
92
+ const results = installSkills({
93
+ target: args.target || args.harness || "all",
94
+ scope: args.scope || "global",
95
+ repo: args.repo,
96
+ home: args.home
97
+ });
98
+ printResults("Installed Agent Hotline spoken skill/instructions:", results);
99
+ return 0;
100
+ }
101
+
102
+ if (command === "install") {
103
+ const args = parseArgs([subcommand, ...rest].filter(Boolean));
104
+ const hookResults = installHooks({
105
+ harness: args.harness || "all",
106
+ scope: args.scope || "global",
107
+ repo: args.repo,
108
+ home: args.home,
109
+ hookCommand: hookCommandFromArgs(args)
110
+ });
111
+ const skillResults = installSkills({
112
+ target: args.skill || args.target || args.harness || "all",
113
+ scope: args.scope || "global",
114
+ repo: args.repo,
115
+ home: args.home
116
+ });
117
+ printResults("Installed Agent Hotline hooks:", hookResults);
118
+ printResults("Installed Agent Hotline spoken skill/instructions:", skillResults);
119
+ return 0;
120
+ }
121
+
122
+ console.error(`Unknown command "${command}".`);
123
+ printHelp();
124
+ return 1;
125
+ }
126
+
127
+ if (require.main === module) {
128
+ main()
129
+ .then((code) => {
130
+ process.exitCode = code;
131
+ })
132
+ .catch((error) => {
133
+ console.error(error.message);
134
+ process.exitCode = 1;
135
+ });
136
+ }
137
+
138
+ module.exports = { main };
@@ -0,0 +1,20 @@
1
+ {
2
+ "name": "@agent-hotline/backend",
3
+ "version": "0.1.0",
4
+ "private": true,
5
+ "description": "Local web backend for Agent Hotline.",
6
+ "type": "commonjs",
7
+ "bin": {
8
+ "ah": "bin/agent-hotline.js",
9
+ "agent-hotline": "bin/agent-hotline.js",
10
+ "agent-hotline-hook": "bin/agent-hotline-hook.js"
11
+ },
12
+ "scripts": {
13
+ "start": "node src/server.js",
14
+ "test": "node --test test/*.test.js",
15
+ "check": "node --check src/server.js && node --check src/settings-store.js && node --check src/speech-queue-store.js && node --check src/audio-cache-store.js && node --check src/installer.js && node --check src/hook-input-parser.js && node --check src/hook-command.js && node --check src/run-command.js && node --check src/speakable-filter.js && node --check bin/agent-hotline.js && node --check bin/agent-hotline-hook.js && node --check test/settings-store.test.js && node --check test/speech-queue-store.test.js && node --check test/audio-cache-store.test.js && node --check test/audio-endpoints.test.js && node --check test/installer.test.js && node --check test/run-command.test.js && node --check test/speakable-filter.test.js && node --check test/hook-input-parser.test.js && node --check test/hook-command.test.js && node --check test/server-endpoints.test.js"
16
+ },
17
+ "engines": {
18
+ "node": ">=18"
19
+ }
20
+ }