@a5c-ai/babysitter-breakpoints 0.1.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/.codex/skills/babysitter-breakpoint/SKILL.md +35 -0
- package/.codex/skills/babysitter-breakpoint/references/breakpoint-api.md +57 -0
- package/README.md +123 -0
- package/api/db.js +62 -0
- package/api/routes.js +475 -0
- package/api/server.js +21 -0
- package/bin/breakpoints.js +259 -0
- package/extensions/config.js +47 -0
- package/extensions/index.js +46 -0
- package/extensions/telegram.js +605 -0
- package/package.json +26 -0
- package/worker/queue.js +85 -0
- package/worker/worker.js +50 -0
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: babysitter-breakpoint
|
|
3
|
+
description: Use the breakpoint API to communicate with users during babysitter runs (post breakpoints, poll for release, fetch feedback, and read context files). Trigger whenever a babysitter workflow needs approval, input, or status updates via breakpoints.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# babysitter-breakpoint
|
|
7
|
+
|
|
8
|
+
Use this skill to handle all user communication via the `breakpoints` CLI. Do
|
|
9
|
+
not prompt the user directly. Always post a breakpoint and poll until it is
|
|
10
|
+
released, then fetch feedback and continue.
|
|
11
|
+
|
|
12
|
+
## Workflow
|
|
13
|
+
|
|
14
|
+
1. Create a breakpoint with the required payload and `payload.context.files`.
|
|
15
|
+
2. Poll `breakpoints breakpoint wait <id> --interval 3` until `released`.
|
|
16
|
+
3. Apply feedback from the printed details and continue.
|
|
17
|
+
|
|
18
|
+
## Payload structure
|
|
19
|
+
|
|
20
|
+
Always include a `context.files` array for referenced files:
|
|
21
|
+
|
|
22
|
+
```json
|
|
23
|
+
{
|
|
24
|
+
"context": {
|
|
25
|
+
"runId": "run-...",
|
|
26
|
+
"files": [
|
|
27
|
+
{ "path": ".a5c/runs/<runId>/artifacts/process.md", "format": "markdown" },
|
|
28
|
+
{ "path": ".a5c/runs/<runId>/inputs.json", "format": "code", "language": "json" },
|
|
29
|
+
{ "path": ".a5c/runs/<runId>/code/main.js", "format": "code", "language": "javascript" }
|
|
30
|
+
]
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
See `references/breakpoint-api.md` for curl examples and endpoints.
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
# Breakpoint CLI + API
|
|
2
|
+
|
|
3
|
+
Use the `breakpoints` CLI to communicate with the user. The CLI wraps the local
|
|
4
|
+
API. Never prompt directly.
|
|
5
|
+
|
|
6
|
+
## Base URL
|
|
7
|
+
- Default: `http://localhost:3000`
|
|
8
|
+
- Override with `BREAKPOINT_API_URL` if set.
|
|
9
|
+
|
|
10
|
+
## Auth
|
|
11
|
+
- Agent token: `AGENT_TOKEN`
|
|
12
|
+
- Human token: `HUMAN_TOKEN`
|
|
13
|
+
- Use `Authorization: Bearer <token>` when set.
|
|
14
|
+
|
|
15
|
+
## Create a breakpoint (agent)
|
|
16
|
+
```bash
|
|
17
|
+
breakpoints breakpoint create \
|
|
18
|
+
--question "Approve process + inputs + main.js?" \
|
|
19
|
+
--run-id run-... \
|
|
20
|
+
--title "Approval needed" \
|
|
21
|
+
--file ".a5c/runs/<runId>/artifacts/process.md,markdown" \
|
|
22
|
+
--file ".a5c/runs/<runId>/inputs.json,code,json" \
|
|
23
|
+
--file ".a5c/runs/<runId>/code/main.js,code,javascript"
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
## Poll for status
|
|
27
|
+
```bash
|
|
28
|
+
breakpoints breakpoint status <id>
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
## Fetch full details (including feedback)
|
|
32
|
+
```bash
|
|
33
|
+
breakpoints breakpoint show <id>
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
## Wait for release (prints details)
|
|
37
|
+
```bash
|
|
38
|
+
breakpoints breakpoint wait <id> --interval 3
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
## Fetch context file content (API)
|
|
42
|
+
```bash
|
|
43
|
+
curl -s "$BREAKPOINT_API_URL/api/breakpoints/<id>/context?path=path/to/file"
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
## Release with feedback (human)
|
|
47
|
+
```bash
|
|
48
|
+
curl -s -X POST "$BREAKPOINT_API_URL/api/breakpoints/<id>/feedback" \
|
|
49
|
+
-H "Content-Type: application/json" \
|
|
50
|
+
-H "Authorization: Bearer $HUMAN_TOKEN" \
|
|
51
|
+
-d '{"author":"reviewer","comment":"approved","release":true}'
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
## Notes
|
|
55
|
+
- Poll every 2-10 seconds.
|
|
56
|
+
- Continue orchestration only after `status` becomes `released` and feedback is retrieved.
|
|
57
|
+
- Context files must be listed in the breakpoint payload and use allowlisted extensions.
|
package/README.md
ADDED
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
# Breakpoint Manager
|
|
2
|
+
|
|
3
|
+
Lightweight breakpoint manager with API, queue worker, and web UI.
|
|
4
|
+
|
|
5
|
+
## Requirements
|
|
6
|
+
- Node.js 18+
|
|
7
|
+
|
|
8
|
+
## Setup
|
|
9
|
+
```bash
|
|
10
|
+
npm install
|
|
11
|
+
npm run init:db
|
|
12
|
+
```
|
|
13
|
+
|
|
14
|
+
## Run (dev)
|
|
15
|
+
```bash
|
|
16
|
+
npm run dev
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
## Run (installed CLI)
|
|
20
|
+
```bash
|
|
21
|
+
breakpoints run
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
Or run separately:
|
|
25
|
+
```bash
|
|
26
|
+
npm run start:api
|
|
27
|
+
npm run start:worker
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
## Configuration
|
|
31
|
+
Environment variables:
|
|
32
|
+
- `PORT` (default 3000)
|
|
33
|
+
- `DB_PATH` (default `data/breakpoints.db`)
|
|
34
|
+
- `REPO_ROOT` (default repo root)
|
|
35
|
+
- `AGENT_TOKEN` (optional)
|
|
36
|
+
- `HUMAN_TOKEN` (optional)
|
|
37
|
+
- `WORKER_POLL_MS` (default 2000)
|
|
38
|
+
- `WORKER_BATCH_SIZE` (default 10)
|
|
39
|
+
|
|
40
|
+
## API Examples
|
|
41
|
+
Create breakpoint (agent):
|
|
42
|
+
```bash
|
|
43
|
+
curl -X POST http://localhost:3000/api/breakpoints \
|
|
44
|
+
-H "Content-Type: application/json" \
|
|
45
|
+
-H "Authorization: Bearer $AGENT_TOKEN" \
|
|
46
|
+
-d '{"agentId":"agent-1","title":"Need review","payload":{"summary":"check this"},"tags":["review"],"ttlSeconds":3600}'
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
Check status:
|
|
50
|
+
```bash
|
|
51
|
+
curl http://localhost:3000/api/breakpoints/<id>/status
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
Release with feedback (human):
|
|
55
|
+
```bash
|
|
56
|
+
curl -X POST http://localhost:3000/api/breakpoints/<id>/feedback \
|
|
57
|
+
-H "Content-Type: application/json" \
|
|
58
|
+
-H "Authorization: Bearer $HUMAN_TOKEN" \
|
|
59
|
+
-d '{"author":"reviewer","comment":"Looks good","release":true}'
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
## Breakpoint Context Payload
|
|
63
|
+
To enable context rendering in the UI, include a `context.files` array in the
|
|
64
|
+
breakpoint payload:
|
|
65
|
+
```json
|
|
66
|
+
{
|
|
67
|
+
"context": {
|
|
68
|
+
"runId": "run-...",
|
|
69
|
+
"files": [
|
|
70
|
+
{ "path": "docs/plan.md", "format": "markdown" },
|
|
71
|
+
{ "path": "api/routes.js", "format": "code", "language": "javascript" }
|
|
72
|
+
]
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
The API serves file content via:
|
|
78
|
+
```
|
|
79
|
+
GET /api/breakpoints/:id/context?path=path/to/file
|
|
80
|
+
```
|
|
81
|
+
Only allowlisted extensions are served, and the file must be listed in the
|
|
82
|
+
breakpoint payload.
|
|
83
|
+
|
|
84
|
+
## Web UI
|
|
85
|
+
Open `http://localhost:3000` and provide the human token in the UI.
|
|
86
|
+
|
|
87
|
+
## Install the babysitter-breakpoint skill
|
|
88
|
+
```bash
|
|
89
|
+
breakpoints install-skill
|
|
90
|
+
```
|
|
91
|
+
Defaults to global Codex install. Options:
|
|
92
|
+
```bash
|
|
93
|
+
breakpoints install-skill --target codex --scope global
|
|
94
|
+
breakpoints install-skill --target codex --scope local
|
|
95
|
+
breakpoints install-skill --target claude --scope global
|
|
96
|
+
breakpoints install-skill --target claude --scope local
|
|
97
|
+
breakpoints install-skill --target cursor --scope global
|
|
98
|
+
breakpoints install-skill --target cursor --scope local
|
|
99
|
+
```
|
|
100
|
+
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 repo root. Restart the app after install.
|
|
101
|
+
|
|
102
|
+
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`.
|
|
103
|
+
|
|
104
|
+
## Breakpoint CLI (agent-friendly)
|
|
105
|
+
Create a breakpoint:
|
|
106
|
+
```bash
|
|
107
|
+
breakpoints breakpoint create \
|
|
108
|
+
--question "Approve process + inputs + main.js?" \
|
|
109
|
+
--run-id run-123 \
|
|
110
|
+
--title "Approval needed" \
|
|
111
|
+
--file ".a5c/runs/run-123/artifacts/process.md,markdown" \
|
|
112
|
+
--file ".a5c/runs/run-123/inputs.json,code,json" \
|
|
113
|
+
--file ".a5c/runs/run-123/code/main.js,code,javascript"
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
Wait for release (prints full details when released):
|
|
117
|
+
```bash
|
|
118
|
+
breakpoints breakpoint wait <id> --interval 3
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
## Notes
|
|
122
|
+
- Tags are stored as JSON in SQLite; tag filtering uses a simple string match.
|
|
123
|
+
- The queue worker processes TTL expiration jobs; notification jobs are stubbed.
|
package/api/db.js
ADDED
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
const fs = require("fs");
|
|
4
|
+
const path = require("path");
|
|
5
|
+
const sqlite3 = require("sqlite3");
|
|
6
|
+
|
|
7
|
+
const DB_PATH =
|
|
8
|
+
process.env.DB_PATH ||
|
|
9
|
+
path.join(__dirname, "..", "data", "breakpoints.db");
|
|
10
|
+
|
|
11
|
+
function openDb() {
|
|
12
|
+
return new sqlite3.Database(DB_PATH);
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
function run(db, sql, params = []) {
|
|
16
|
+
return new Promise((resolve, reject) => {
|
|
17
|
+
db.run(sql, params, function onRun(err) {
|
|
18
|
+
if (err) return reject(err);
|
|
19
|
+
resolve(this);
|
|
20
|
+
});
|
|
21
|
+
});
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
function get(db, sql, params = []) {
|
|
25
|
+
return new Promise((resolve, reject) => {
|
|
26
|
+
db.get(sql, params, (err, row) => {
|
|
27
|
+
if (err) return reject(err);
|
|
28
|
+
resolve(row);
|
|
29
|
+
});
|
|
30
|
+
});
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
function all(db, sql, params = []) {
|
|
34
|
+
return new Promise((resolve, reject) => {
|
|
35
|
+
db.all(sql, params, (err, rows) => {
|
|
36
|
+
if (err) return reject(err);
|
|
37
|
+
resolve(rows);
|
|
38
|
+
});
|
|
39
|
+
});
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
async function initDb(db) {
|
|
43
|
+
const schemaPath = path.join(__dirname, "..", "db", "schema.sql");
|
|
44
|
+
const schema = fs.readFileSync(schemaPath, "utf8");
|
|
45
|
+
await run(db, "PRAGMA foreign_keys = ON;");
|
|
46
|
+
const statements = schema
|
|
47
|
+
.split(";")
|
|
48
|
+
.map((statement) => statement.trim())
|
|
49
|
+
.filter((statement) => statement.length);
|
|
50
|
+
for (const statement of statements) {
|
|
51
|
+
await run(db, statement);
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
module.exports = {
|
|
56
|
+
DB_PATH,
|
|
57
|
+
openDb,
|
|
58
|
+
run,
|
|
59
|
+
get,
|
|
60
|
+
all,
|
|
61
|
+
initDb,
|
|
62
|
+
};
|