@a5c-ai/babysitter-breakpoints 0.1.3 → 0.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 +36 -6
- package/api/db.js +26 -1
- package/api/server.js +12 -0
- package/bin/breakpoints.js +2 -1
- package/db/migrations/001_init.sql +56 -0
- package/db/migrations/002_extensions.sql +13 -0
- package/db/schema.sql +60 -0
- package/package.json +29 -26
- package/scripts/dev-runner.js +41 -0
- package/scripts/dev.ps1 +10 -0
- package/scripts/dev.sh +13 -0
- package/scripts/init-db.js +20 -0
- package/web/app.js +511 -0
- package/web/index.html +151 -0
- package/web/server.js +14 -0
- package/web/styles.css +431 -0
package/README.md
CHANGED
|
@@ -2,17 +2,21 @@
|
|
|
2
2
|
|
|
3
3
|
Lightweight breakpoint manager with API, queue worker, and web UI.
|
|
4
4
|
|
|
5
|
+
This package now lives at `packages/breakpoints`.
|
|
6
|
+
|
|
5
7
|
## Requirements
|
|
6
8
|
- Node.js 18+
|
|
7
9
|
|
|
8
10
|
## Setup
|
|
9
11
|
```bash
|
|
12
|
+
cd packages/breakpoints
|
|
10
13
|
npm install
|
|
11
14
|
npm run init:db
|
|
12
15
|
```
|
|
13
16
|
|
|
14
17
|
## Run (dev)
|
|
15
18
|
```bash
|
|
19
|
+
cd packages/breakpoints
|
|
16
20
|
npm run dev
|
|
17
21
|
```
|
|
18
22
|
|
|
@@ -27,12 +31,38 @@ npm run start:api
|
|
|
27
31
|
npm run start:worker
|
|
28
32
|
```
|
|
29
33
|
|
|
34
|
+
## CLI Examples
|
|
35
|
+
Start the full system (API + web UI + worker):
|
|
36
|
+
```bash
|
|
37
|
+
breakpoints start
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
Create a breakpoint (agent):
|
|
41
|
+
```bash
|
|
42
|
+
breakpoints breakpoint create --question "Need approval?" --title "Approval"
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
Check status:
|
|
46
|
+
```bash
|
|
47
|
+
breakpoints breakpoint status <id>
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
Wait for release:
|
|
51
|
+
```bash
|
|
52
|
+
breakpoints breakpoint wait <id> --interval 3
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
Install the babysitter-breakpoint skill:
|
|
56
|
+
```bash
|
|
57
|
+
breakpoints install-skill --target codex --scope global
|
|
58
|
+
```
|
|
59
|
+
|
|
30
60
|
## Configuration
|
|
31
61
|
Environment variables:
|
|
32
62
|
- `PORT` (default 3185)
|
|
33
63
|
- `WEB_PORT` (default 3184)
|
|
34
64
|
- `DB_PATH` (default `~/.a5c/breakpoints/db/breakpoints.db`)
|
|
35
|
-
- `REPO_ROOT` (default
|
|
65
|
+
- `REPO_ROOT` (default package root / current working directory)
|
|
36
66
|
- `AGENT_TOKEN` (optional)
|
|
37
67
|
- `HUMAN_TOKEN` (optional)
|
|
38
68
|
- `WORKER_POLL_MS` (default 2000)
|
|
@@ -41,7 +71,7 @@ Environment variables:
|
|
|
41
71
|
## API Examples
|
|
42
72
|
Create breakpoint (agent):
|
|
43
73
|
```bash
|
|
44
|
-
curl -X POST http://localhost:
|
|
74
|
+
curl -X POST http://localhost:3185/api/breakpoints \
|
|
45
75
|
-H "Content-Type: application/json" \
|
|
46
76
|
-H "Authorization: Bearer $AGENT_TOKEN" \
|
|
47
77
|
-d '{"agentId":"agent-1","title":"Need review","payload":{"summary":"check this"},"tags":["review"],"ttlSeconds":3600}'
|
|
@@ -49,12 +79,12 @@ curl -X POST http://localhost:3000/api/breakpoints \
|
|
|
49
79
|
|
|
50
80
|
Check status:
|
|
51
81
|
```bash
|
|
52
|
-
curl http://localhost:
|
|
82
|
+
curl http://localhost:3185/api/breakpoints/<id>/status
|
|
53
83
|
```
|
|
54
84
|
|
|
55
85
|
Release with feedback (human):
|
|
56
86
|
```bash
|
|
57
|
-
curl -X POST http://localhost:
|
|
87
|
+
curl -X POST http://localhost:3185/api/breakpoints/<id>/feedback \
|
|
58
88
|
-H "Content-Type: application/json" \
|
|
59
89
|
-H "Authorization: Bearer $HUMAN_TOKEN" \
|
|
60
90
|
-d '{"author":"reviewer","comment":"Looks good","release":true}'
|
|
@@ -83,7 +113,7 @@ Only allowlisted extensions are served, and the file must be listed in the
|
|
|
83
113
|
breakpoint payload.
|
|
84
114
|
|
|
85
115
|
## Web UI
|
|
86
|
-
Open `http://localhost:
|
|
116
|
+
Open `http://localhost:3184` and provide the human token in the UI.
|
|
87
117
|
|
|
88
118
|
## Install the babysitter-breakpoint skill
|
|
89
119
|
```bash
|
|
@@ -98,7 +128,7 @@ breakpoints install-skill --target claude --scope local
|
|
|
98
128
|
breakpoints install-skill --target cursor --scope global
|
|
99
129
|
breakpoints install-skill --target cursor --scope local
|
|
100
130
|
```
|
|
101
|
-
Global targets use `CODEX_HOME` or `~/.codex` for Codex, and `~/.claude` or `~/.cursor` for Claude/Cursor. Local installs write to `.codex/skills`, `.claude/skills`, or `.cursor/skills` under the
|
|
131
|
+
Global targets use `CODEX_HOME` or `~/.codex` for Codex, and `~/.claude` or `~/.cursor` for Claude/Cursor. Local installs write to `.codex/skills`, `.claude/skills`, or `.cursor/skills` under the package root. Restart the app after install.
|
|
102
132
|
|
|
103
133
|
When installed from npm, the skill is bundled at `.codex/skills/babysitter-breakpoint/` inside the package and copied to the target location by `breakpoints install-skill`.
|
|
104
134
|
|
package/api/db.js
CHANGED
|
@@ -10,7 +10,32 @@ function defaultDbPath() {
|
|
|
10
10
|
return path.join(home, ".a5c", "breakpoints", "db", "breakpoints.db");
|
|
11
11
|
}
|
|
12
12
|
|
|
13
|
-
|
|
13
|
+
function expandHome(value) {
|
|
14
|
+
if (!value) return value;
|
|
15
|
+
if (value === "~") return os.homedir();
|
|
16
|
+
if (value.startsWith(`~${path.sep}`)) {
|
|
17
|
+
return path.join(os.homedir(), value.slice(2));
|
|
18
|
+
}
|
|
19
|
+
if (value.startsWith("~/")) {
|
|
20
|
+
return path.join(os.homedir(), value.slice(2));
|
|
21
|
+
}
|
|
22
|
+
return value;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
function resolveDbPath(value) {
|
|
26
|
+
const expanded = expandHome(value);
|
|
27
|
+
if (!expanded) return expanded;
|
|
28
|
+
const normalized = path.normalize(expanded);
|
|
29
|
+
if (normalized.endsWith(path.sep)) {
|
|
30
|
+
return path.join(normalized, "breakpoints.db");
|
|
31
|
+
}
|
|
32
|
+
if (!path.extname(normalized)) {
|
|
33
|
+
return path.join(normalized, "breakpoints.db");
|
|
34
|
+
}
|
|
35
|
+
return normalized;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
const DB_PATH = resolveDbPath(process.env.DB_PATH || defaultDbPath());
|
|
14
39
|
|
|
15
40
|
function openDb() {
|
|
16
41
|
fs.mkdirSync(path.dirname(DB_PATH), { recursive: true });
|
package/api/server.js
CHANGED
|
@@ -8,6 +8,18 @@ const app = express();
|
|
|
8
8
|
const port = process.env.PORT || 3185;
|
|
9
9
|
|
|
10
10
|
app.use(express.json({ limit: "1mb" }));
|
|
11
|
+
app.use((req, res, next) => {
|
|
12
|
+
res.setHeader("Access-Control-Allow-Origin", "*");
|
|
13
|
+
res.setHeader(
|
|
14
|
+
"Access-Control-Allow-Headers",
|
|
15
|
+
"Content-Type, Authorization"
|
|
16
|
+
);
|
|
17
|
+
res.setHeader("Access-Control-Allow-Methods", "GET,POST,OPTIONS");
|
|
18
|
+
if (req.method === "OPTIONS") {
|
|
19
|
+
return res.sendStatus(204);
|
|
20
|
+
}
|
|
21
|
+
return next();
|
|
22
|
+
});
|
|
11
23
|
app.use("/api", routes);
|
|
12
24
|
app.use("/", express.static(path.join(__dirname, "..", "web")));
|
|
13
25
|
|
package/bin/breakpoints.js
CHANGED
|
@@ -30,7 +30,7 @@ function runCommand(command, args, options = {}) {
|
|
|
30
30
|
}
|
|
31
31
|
|
|
32
32
|
function apiBase() {
|
|
33
|
-
return process.env.BREAKPOINT_API_URL || "http://localhost:
|
|
33
|
+
return process.env.BREAKPOINT_API_URL || "http://localhost:3185";
|
|
34
34
|
}
|
|
35
35
|
|
|
36
36
|
async function httpJson(method, url, body) {
|
|
@@ -164,6 +164,7 @@ function runSystem() {
|
|
|
164
164
|
),
|
|
165
165
|
PORT: process.env.PORT || "3185",
|
|
166
166
|
WEB_PORT: process.env.WEB_PORT || "3184",
|
|
167
|
+
REPO_ROOT: process.env.REPO_ROOT || process.cwd(),
|
|
167
168
|
};
|
|
168
169
|
runCommand("node", [runner], { cwd: repoRoot, env });
|
|
169
170
|
}
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
-- Initial migration
|
|
2
|
+
|
|
3
|
+
BEGIN;
|
|
4
|
+
|
|
5
|
+
CREATE TABLE IF NOT EXISTS breakpoints (
|
|
6
|
+
id TEXT PRIMARY KEY,
|
|
7
|
+
status TEXT NOT NULL,
|
|
8
|
+
agent_id TEXT NOT NULL,
|
|
9
|
+
run_id TEXT,
|
|
10
|
+
title TEXT,
|
|
11
|
+
payload TEXT NOT NULL,
|
|
12
|
+
tags TEXT,
|
|
13
|
+
ttl_seconds INTEGER,
|
|
14
|
+
created_at TEXT NOT NULL,
|
|
15
|
+
updated_at TEXT NOT NULL,
|
|
16
|
+
released_at TEXT,
|
|
17
|
+
expired_at TEXT,
|
|
18
|
+
cancelled_at TEXT
|
|
19
|
+
);
|
|
20
|
+
|
|
21
|
+
CREATE TABLE IF NOT EXISTS feedback (
|
|
22
|
+
id TEXT PRIMARY KEY,
|
|
23
|
+
breakpoint_id TEXT NOT NULL,
|
|
24
|
+
author TEXT NOT NULL,
|
|
25
|
+
comment TEXT NOT NULL,
|
|
26
|
+
created_at TEXT NOT NULL,
|
|
27
|
+
FOREIGN KEY (breakpoint_id) REFERENCES breakpoints(id)
|
|
28
|
+
);
|
|
29
|
+
|
|
30
|
+
CREATE TABLE IF NOT EXISTS events (
|
|
31
|
+
id TEXT PRIMARY KEY,
|
|
32
|
+
breakpoint_id TEXT NOT NULL,
|
|
33
|
+
type TEXT NOT NULL,
|
|
34
|
+
actor TEXT NOT NULL,
|
|
35
|
+
timestamp TEXT NOT NULL,
|
|
36
|
+
metadata TEXT,
|
|
37
|
+
FOREIGN KEY (breakpoint_id) REFERENCES breakpoints(id)
|
|
38
|
+
);
|
|
39
|
+
|
|
40
|
+
CREATE TABLE IF NOT EXISTS jobs (
|
|
41
|
+
id TEXT PRIMARY KEY,
|
|
42
|
+
type TEXT NOT NULL,
|
|
43
|
+
status TEXT NOT NULL,
|
|
44
|
+
payload TEXT NOT NULL,
|
|
45
|
+
run_at TEXT NOT NULL,
|
|
46
|
+
attempts INTEGER NOT NULL DEFAULT 0,
|
|
47
|
+
last_error TEXT,
|
|
48
|
+
created_at TEXT NOT NULL,
|
|
49
|
+
updated_at TEXT NOT NULL
|
|
50
|
+
);
|
|
51
|
+
|
|
52
|
+
CREATE INDEX IF NOT EXISTS idx_breakpoints_status ON breakpoints(status);
|
|
53
|
+
CREATE INDEX IF NOT EXISTS idx_breakpoints_agent ON breakpoints(agent_id);
|
|
54
|
+
CREATE INDEX IF NOT EXISTS idx_jobs_status_run_at ON jobs(status, run_at);
|
|
55
|
+
|
|
56
|
+
COMMIT;
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
-- Extensions config table
|
|
2
|
+
|
|
3
|
+
BEGIN;
|
|
4
|
+
|
|
5
|
+
CREATE TABLE IF NOT EXISTS extensions_config (
|
|
6
|
+
name TEXT PRIMARY KEY,
|
|
7
|
+
enabled INTEGER NOT NULL DEFAULT 0,
|
|
8
|
+
config_json TEXT NOT NULL,
|
|
9
|
+
created_at TEXT NOT NULL,
|
|
10
|
+
updated_at TEXT NOT NULL
|
|
11
|
+
);
|
|
12
|
+
|
|
13
|
+
COMMIT;
|
package/db/schema.sql
ADDED
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
-- SQLite schema for breakpoint manager
|
|
2
|
+
|
|
3
|
+
CREATE TABLE IF NOT EXISTS breakpoints (
|
|
4
|
+
id TEXT PRIMARY KEY,
|
|
5
|
+
status TEXT NOT NULL,
|
|
6
|
+
agent_id TEXT NOT NULL,
|
|
7
|
+
run_id TEXT,
|
|
8
|
+
title TEXT,
|
|
9
|
+
payload TEXT NOT NULL,
|
|
10
|
+
tags TEXT,
|
|
11
|
+
ttl_seconds INTEGER,
|
|
12
|
+
created_at TEXT NOT NULL,
|
|
13
|
+
updated_at TEXT NOT NULL,
|
|
14
|
+
released_at TEXT,
|
|
15
|
+
expired_at TEXT,
|
|
16
|
+
cancelled_at TEXT
|
|
17
|
+
);
|
|
18
|
+
|
|
19
|
+
CREATE TABLE IF NOT EXISTS feedback (
|
|
20
|
+
id TEXT PRIMARY KEY,
|
|
21
|
+
breakpoint_id TEXT NOT NULL,
|
|
22
|
+
author TEXT NOT NULL,
|
|
23
|
+
comment TEXT NOT NULL,
|
|
24
|
+
created_at TEXT NOT NULL,
|
|
25
|
+
FOREIGN KEY (breakpoint_id) REFERENCES breakpoints(id)
|
|
26
|
+
);
|
|
27
|
+
|
|
28
|
+
CREATE TABLE IF NOT EXISTS events (
|
|
29
|
+
id TEXT PRIMARY KEY,
|
|
30
|
+
breakpoint_id TEXT NOT NULL,
|
|
31
|
+
type TEXT NOT NULL,
|
|
32
|
+
actor TEXT NOT NULL,
|
|
33
|
+
timestamp TEXT NOT NULL,
|
|
34
|
+
metadata TEXT,
|
|
35
|
+
FOREIGN KEY (breakpoint_id) REFERENCES breakpoints(id)
|
|
36
|
+
);
|
|
37
|
+
|
|
38
|
+
CREATE TABLE IF NOT EXISTS jobs (
|
|
39
|
+
id TEXT PRIMARY KEY,
|
|
40
|
+
type TEXT NOT NULL,
|
|
41
|
+
status TEXT NOT NULL,
|
|
42
|
+
payload TEXT NOT NULL,
|
|
43
|
+
run_at TEXT NOT NULL,
|
|
44
|
+
attempts INTEGER NOT NULL DEFAULT 0,
|
|
45
|
+
last_error TEXT,
|
|
46
|
+
created_at TEXT NOT NULL,
|
|
47
|
+
updated_at TEXT NOT NULL
|
|
48
|
+
);
|
|
49
|
+
|
|
50
|
+
CREATE TABLE IF NOT EXISTS extensions_config (
|
|
51
|
+
name TEXT PRIMARY KEY,
|
|
52
|
+
enabled INTEGER NOT NULL DEFAULT 0,
|
|
53
|
+
config_json TEXT NOT NULL,
|
|
54
|
+
created_at TEXT NOT NULL,
|
|
55
|
+
updated_at TEXT NOT NULL
|
|
56
|
+
);
|
|
57
|
+
|
|
58
|
+
CREATE INDEX IF NOT EXISTS idx_breakpoints_status ON breakpoints(status);
|
|
59
|
+
CREATE INDEX IF NOT EXISTS idx_breakpoints_agent ON breakpoints(agent_id);
|
|
60
|
+
CREATE INDEX IF NOT EXISTS idx_jobs_status_run_at ON jobs(status, run_at);
|
package/package.json
CHANGED
|
@@ -1,26 +1,29 @@
|
|
|
1
|
-
{
|
|
2
|
-
"name": "@a5c-ai/babysitter-breakpoints",
|
|
3
|
-
"version": "0.1.
|
|
4
|
-
"private": false,
|
|
5
|
-
"type": "commonjs",
|
|
6
|
-
"bin": {
|
|
7
|
-
"breakpoints": "bin/breakpoints.js"
|
|
8
|
-
},
|
|
9
|
-
"files": [
|
|
10
|
-
"bin/",
|
|
11
|
-
"api/",
|
|
12
|
-
"
|
|
13
|
-
"
|
|
14
|
-
"
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
"
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
"
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
"
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
1
|
+
{
|
|
2
|
+
"name": "@a5c-ai/babysitter-breakpoints",
|
|
3
|
+
"version": "0.1.5",
|
|
4
|
+
"private": false,
|
|
5
|
+
"type": "commonjs",
|
|
6
|
+
"bin": {
|
|
7
|
+
"breakpoints": "bin/breakpoints.js"
|
|
8
|
+
},
|
|
9
|
+
"files": [
|
|
10
|
+
"bin/",
|
|
11
|
+
"api/",
|
|
12
|
+
"db/",
|
|
13
|
+
"worker/",
|
|
14
|
+
"extensions/",
|
|
15
|
+
"scripts/",
|
|
16
|
+
"web/",
|
|
17
|
+
".codex/skills/babysitter-breakpoint/"
|
|
18
|
+
],
|
|
19
|
+
"scripts": {
|
|
20
|
+
"start:api": "node api/server.js",
|
|
21
|
+
"start:worker": "node worker/worker.js",
|
|
22
|
+
"dev": "node scripts/dev-runner.js",
|
|
23
|
+
"init:db": "node scripts/init-db.js"
|
|
24
|
+
},
|
|
25
|
+
"dependencies": {
|
|
26
|
+
"express": "^4.19.2",
|
|
27
|
+
"sqlite3": "^5.1.7"
|
|
28
|
+
}
|
|
29
|
+
}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
const { spawn } = require("child_process");
|
|
4
|
+
const path = require("path");
|
|
5
|
+
|
|
6
|
+
const repoRoot = path.join(__dirname, "..");
|
|
7
|
+
const defaultEnv = {
|
|
8
|
+
DB_PATH:
|
|
9
|
+
process.env.DB_PATH ||
|
|
10
|
+
path.join(
|
|
11
|
+
require("os").homedir(),
|
|
12
|
+
".a5c",
|
|
13
|
+
"breakpoints",
|
|
14
|
+
"db",
|
|
15
|
+
"breakpoints.db"
|
|
16
|
+
),
|
|
17
|
+
PORT: process.env.PORT || "3185",
|
|
18
|
+
WEB_PORT: process.env.WEB_PORT || "3184",
|
|
19
|
+
REPO_ROOT: process.env.REPO_ROOT || process.cwd(),
|
|
20
|
+
};
|
|
21
|
+
|
|
22
|
+
function run(label, command, args) {
|
|
23
|
+
const proc = spawn(command, args, {
|
|
24
|
+
stdio: "inherit",
|
|
25
|
+
env: { ...process.env, ...defaultEnv },
|
|
26
|
+
shell: true,
|
|
27
|
+
cwd: repoRoot,
|
|
28
|
+
});
|
|
29
|
+
proc.on("exit", (code) => {
|
|
30
|
+
if (code) {
|
|
31
|
+
// eslint-disable-next-line no-console
|
|
32
|
+
console.error(`${label} exited with code ${code}`);
|
|
33
|
+
process.exitCode = code;
|
|
34
|
+
}
|
|
35
|
+
});
|
|
36
|
+
return proc;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
run("api", "node", [path.join(repoRoot, "api", "server.js")]);
|
|
40
|
+
run("web", "node", [path.join(repoRoot, "web", "server.js")]);
|
|
41
|
+
run("worker", "node", [path.join(repoRoot, "worker", "worker.js")]);
|
package/scripts/dev.ps1
ADDED
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
$ErrorActionPreference = "Stop"
|
|
2
|
+
|
|
3
|
+
$repoRoot = (Resolve-Path (Join-Path $PSScriptRoot ".."))
|
|
4
|
+
|
|
5
|
+
Write-Host "Starting API and worker..."
|
|
6
|
+
Start-Process -FilePath "node" -ArgumentList (Join-Path $repoRoot "api/server.js") -NoNewWindow
|
|
7
|
+
Start-Process -FilePath "node" -ArgumentList (Join-Path $repoRoot "worker/worker.js") -NoNewWindow
|
|
8
|
+
|
|
9
|
+
Write-Host "API: http://localhost:3185"
|
|
10
|
+
Write-Host "Use Ctrl+C to stop."
|
package/scripts/dev.sh
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
#!/usr/bin/env sh
|
|
2
|
+
set -e
|
|
3
|
+
|
|
4
|
+
script_dir="$(cd "$(dirname "$0")" && pwd)"
|
|
5
|
+
repo_root="$(cd "$script_dir/.." && pwd)"
|
|
6
|
+
|
|
7
|
+
echo "Starting API and worker..."
|
|
8
|
+
node "$repo_root/api/server.js" &
|
|
9
|
+
node "$repo_root/worker/worker.js" &
|
|
10
|
+
|
|
11
|
+
echo "API: http://localhost:3185"
|
|
12
|
+
echo "Press Ctrl+C to stop."
|
|
13
|
+
wait
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
const { openDb, initDb, DB_PATH } = require("../api/db");
|
|
4
|
+
|
|
5
|
+
async function main() {
|
|
6
|
+
const db = openDb();
|
|
7
|
+
try {
|
|
8
|
+
await initDb(db);
|
|
9
|
+
// eslint-disable-next-line no-console
|
|
10
|
+
console.log(`Database initialized at ${DB_PATH}`);
|
|
11
|
+
} finally {
|
|
12
|
+
db.close();
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
main().catch((err) => {
|
|
17
|
+
// eslint-disable-next-line no-console
|
|
18
|
+
console.error(err);
|
|
19
|
+
process.exitCode = 1;
|
|
20
|
+
});
|