beercan 0.4.8 → 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 +58 -4
- package/dist/config.d.ts +30 -0
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +40 -0
- package/dist/config.js.map +1 -1
- package/dist/core/heartbeat.d.ts +57 -0
- package/dist/core/heartbeat.d.ts.map +1 -0
- package/dist/core/heartbeat.js +179 -0
- package/dist/core/heartbeat.js.map +1 -0
- package/dist/core/job-queue.d.ts +3 -0
- package/dist/core/job-queue.d.ts.map +1 -1
- package/dist/core/job-queue.js +2 -0
- package/dist/core/job-queue.js.map +1 -1
- package/dist/core/reflection.d.ts +38 -0
- package/dist/core/reflection.d.ts.map +1 -0
- package/dist/core/reflection.js +287 -0
- package/dist/core/reflection.js.map +1 -0
- package/dist/core/role-templates.d.ts.map +1 -1
- package/dist/core/role-templates.js +40 -0
- package/dist/core/role-templates.js.map +1 -1
- package/dist/core/runner.d.ts +3 -1
- package/dist/core/runner.d.ts.map +1 -1
- package/dist/core/runner.js +45 -1
- package/dist/core/runner.js.map +1 -1
- package/dist/events/daemon.d.ts.map +1 -1
- package/dist/events/daemon.js +5 -0
- package/dist/events/daemon.js.map +1 -1
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +44 -2
- package/dist/index.js.map +1 -1
- package/dist/memory/hybrid-search.d.ts +3 -2
- package/dist/memory/hybrid-search.d.ts.map +1 -1
- package/dist/memory/hybrid-search.js +13 -2
- package/dist/memory/hybrid-search.js.map +1 -1
- package/dist/memory/index.d.ts +5 -0
- package/dist/memory/index.d.ts.map +1 -1
- package/dist/memory/index.js +26 -2
- package/dist/memory/index.js.map +1 -1
- package/dist/skills/index.d.ts +4 -0
- package/dist/skills/index.d.ts.map +1 -1
- package/dist/skills/index.js +8 -0
- package/dist/skills/index.js.map +1 -1
- package/dist/storage/database.d.ts +6 -0
- package/dist/storage/database.d.ts.map +1 -1
- package/dist/storage/database.js +47 -2
- package/dist/storage/database.js.map +1 -1
- package/dist/tools/builtin/filesystem.d.ts.map +1 -1
- package/dist/tools/builtin/filesystem.js +5 -0
- package/dist/tools/builtin/filesystem.js.map +1 -1
- package/dist/tools/builtin/integration.d.ts +20 -0
- package/dist/tools/builtin/integration.d.ts.map +1 -0
- package/dist/tools/builtin/integration.js +220 -0
- package/dist/tools/builtin/integration.js.map +1 -0
- package/dist/tools/builtin/scheduling.d.ts +62 -0
- package/dist/tools/builtin/scheduling.d.ts.map +1 -0
- package/dist/tools/builtin/scheduling.js +280 -0
- package/dist/tools/builtin/scheduling.js.map +1 -0
- package/dist/tools/builtin/skills.d.ts +10 -0
- package/dist/tools/builtin/skills.d.ts.map +1 -0
- package/dist/tools/builtin/skills.js +195 -0
- package/dist/tools/builtin/skills.js.map +1 -0
- package/dist/tools/builtin/spawning.d.ts +33 -0
- package/dist/tools/builtin/spawning.d.ts.map +1 -0
- package/dist/tools/builtin/spawning.js +243 -0
- package/dist/tools/builtin/spawning.js.map +1 -0
- package/dist/tools/builtin/web.d.ts.map +1 -1
- package/dist/tools/builtin/web.js +5 -2
- package/dist/tools/builtin/web.js.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
Autonomous AI agent system — powered by Skippy the Magnificent.
|
|
4
4
|
|
|
5
|
-
Sandboxed projects, multi-agent pipelines with dynamic team composition, 4-layer hybrid RAG memory, conversational chat interface (terminal, Telegram, Slack, WebSocket), REST API with auth, and a magnificently sarcastic AI overlord.
|
|
5
|
+
Sandboxed projects, multi-agent pipelines with dynamic team composition, 4-layer hybrid RAG memory, self-spawning agents with cross-project collaboration, heartbeat awareness loops, post-bloop reflection & learning, build-verify-integrate pipelines, conversational chat interface (terminal, Telegram, Slack, WebSocket), REST API with auth, and a magnificently sarcastic AI overlord.
|
|
6
6
|
|
|
7
7
|
## Install
|
|
8
8
|
|
|
@@ -142,15 +142,15 @@ $ beercan run my-project "Add OAuth2 login with Google provider"
|
|
|
142
142
|
| `managed` | Manager → Coder → Manager | Planned execution |
|
|
143
143
|
| `full_team` | Manager → Coder → Reviewer → Tester | Production code |
|
|
144
144
|
|
|
145
|
-
##
|
|
145
|
+
## 16 Dynamic Roles
|
|
146
146
|
|
|
147
147
|
**5 built-in:** manager, coder, reviewer, tester, solo
|
|
148
148
|
|
|
149
|
-
**
|
|
149
|
+
**11 templates** (gatekeeper picks as needed): writer, researcher, analyst, data_processor, summarizer, planner, editor, devops, architect, heartbeat, verifier
|
|
150
150
|
|
|
151
151
|
The gatekeeper can also invent custom roles with LLM-generated prompts for unusual tasks.
|
|
152
152
|
|
|
153
|
-
## Built-in Tools
|
|
153
|
+
## 32 Built-in Tools
|
|
154
154
|
|
|
155
155
|
| Category | Tools |
|
|
156
156
|
|----------|-------|
|
|
@@ -158,9 +158,53 @@ The gatekeeper can also invent custom roles with LLM-generated prompts for unusu
|
|
|
158
158
|
| Web | `web_fetch` (Cloudflare Browser Rendering + native), `http_request` |
|
|
159
159
|
| Notification | `send_notification` (macOS desktop) |
|
|
160
160
|
| Memory | `memory_search`, `memory_store`, `memory_update`, `memory_link`, `memory_query_graph`, `memory_scratch` |
|
|
161
|
+
| Spawning | `spawn_bloop`, `get_bloop_result`, `list_child_bloops`, `list_projects`, `search_cross_project`, `search_previous_attempts` |
|
|
162
|
+
| Scheduling | `create_schedule`, `create_trigger`, `list_schedules`, `list_triggers`, `remove_schedule`, `remove_trigger` |
|
|
163
|
+
| Skills | `create_skill`, `update_skill`, `list_skills`, `update_project_context` |
|
|
164
|
+
| Integration | `register_tool_from_file`, `register_skill_from_bloop`, `verify_and_integrate` |
|
|
161
165
|
|
|
162
166
|
Plus custom tools from `~/.beercan/tools/` and MCP servers.
|
|
163
167
|
|
|
168
|
+
## Agentic Autonomy
|
|
169
|
+
|
|
170
|
+
BeerCan agents are self-directed, not just task-driven:
|
|
171
|
+
|
|
172
|
+
### Self-Spawning & Cross-Project
|
|
173
|
+
Agents decompose work into child bloops and delegate across projects:
|
|
174
|
+
```bash
|
|
175
|
+
# Agent can spawn sub-tasks automatically
|
|
176
|
+
beercan run my-project "Analyze codebase, spawn child bloops for each module"
|
|
177
|
+
|
|
178
|
+
# Cross-project: agents discover and leverage other projects' knowledge
|
|
179
|
+
```
|
|
180
|
+
Safety limits: max 5 children per bloop, max depth 3, cross-project access configurable per project.
|
|
181
|
+
|
|
182
|
+
### Self-Scheduling
|
|
183
|
+
Agents create their own schedules and triggers:
|
|
184
|
+
```
|
|
185
|
+
"I'll check back on this PR tomorrow" → agent creates a cron job
|
|
186
|
+
"Alert me if builds fail" → agent creates an event trigger
|
|
187
|
+
```
|
|
188
|
+
|
|
189
|
+
### Heartbeat
|
|
190
|
+
Per-project periodic awareness loops. Agent wakes up, checks a configurable checklist, surfaces findings or stays silent:
|
|
191
|
+
```bash
|
|
192
|
+
beercan heartbeat:configure my-project # Set checklist, interval, active hours
|
|
193
|
+
beercan daemon # Heartbeats run automatically
|
|
194
|
+
```
|
|
195
|
+
|
|
196
|
+
### Self-Education
|
|
197
|
+
Optional post-bloop reflection extracts lessons, patterns, and error resolutions into memory. Future bloops automatically receive relevant lessons from past work:
|
|
198
|
+
```bash
|
|
199
|
+
export BEERCAN_REFLECTION_ENABLED=true # Or set per-project
|
|
200
|
+
```
|
|
201
|
+
|
|
202
|
+
### Build-Verify-Integrate
|
|
203
|
+
Agents build tools, spawn verification bloops, and auto-register on APPROVE:
|
|
204
|
+
```
|
|
205
|
+
Agent builds csv-parser.js → spawns verifier → tests pass → tool registered → available to all future bloops
|
|
206
|
+
```
|
|
207
|
+
|
|
164
208
|
## Custom Tools
|
|
165
209
|
|
|
166
210
|
Drop a `.js` file in `~/.beercan/tools/` and it's auto-loaded on startup. Every agent gets access automatically — no template changes needed.
|
|
@@ -335,6 +379,12 @@ All providers share the same ChatBridge — slash commands and natural language
|
|
|
335
379
|
- **Conversation memory** — Skippy remembers last 20 messages per chat channel for multi-turn context
|
|
336
380
|
- **Skills system** — workflow recipes with trigger matching and context injection (`~/.beercan/skills/`)
|
|
337
381
|
- **Auto version badge** — landing page auto-fetches latest version from npm
|
|
382
|
+
- **Self-spawning agents** — agents decompose work into child bloops with depth/count limits
|
|
383
|
+
- **Cross-project collaboration** — agents search and delegate across projects
|
|
384
|
+
- **Heartbeat awareness** — per-project periodic monitoring with active hours and suppression
|
|
385
|
+
- **Post-bloop reflection** — opt-in learning from completed bloops via lightweight Haiku analysis
|
|
386
|
+
- **Build-verify-integrate** — agents build tools, verify them, and auto-register for future use
|
|
387
|
+
- **Self-scheduling** — agents create their own cron jobs and event triggers
|
|
338
388
|
|
|
339
389
|
## CLI Reference
|
|
340
390
|
|
|
@@ -408,6 +458,10 @@ Set in `.env` file:
|
|
|
408
458
|
| `BEERCAN_TELEGRAM_TOKEN` | — | Telegram bot token |
|
|
409
459
|
| `BEERCAN_SLACK_TOKEN` | — | Slack bot token |
|
|
410
460
|
| `BEERCAN_SLACK_SIGNING_SECRET` | — | Slack signing secret |
|
|
461
|
+
| `BEERCAN_MAX_CHILDREN_PER_BLOOP` | `5` | Max child bloops per parent |
|
|
462
|
+
| `BEERCAN_MAX_SPAWN_DEPTH` | `3` | Max spawn chain depth |
|
|
463
|
+
| `BEERCAN_HEARTBEAT_INTERVAL` | `30` | Default heartbeat interval (min) |
|
|
464
|
+
| `BEERCAN_REFLECTION_ENABLED` | `false` | Enable post-bloop reflection |
|
|
411
465
|
|
|
412
466
|
## Architecture
|
|
413
467
|
|
package/dist/config.d.ts
CHANGED
|
@@ -16,6 +16,16 @@ declare const ConfigSchema: z.ZodObject<{
|
|
|
16
16
|
apiKey: z.ZodOptional<z.ZodString>;
|
|
17
17
|
notifyOnComplete: z.ZodDefault<z.ZodBoolean>;
|
|
18
18
|
notifyWebhookUrl: z.ZodOptional<z.ZodString>;
|
|
19
|
+
maxChildrenPerBloop: z.ZodDefault<z.ZodNumber>;
|
|
20
|
+
maxSpawnDepth: z.ZodDefault<z.ZodNumber>;
|
|
21
|
+
maxSchedulesPerProject: z.ZodDefault<z.ZodNumber>;
|
|
22
|
+
maxTriggersPerProject: z.ZodDefault<z.ZodNumber>;
|
|
23
|
+
minCronIntervalMinutes: z.ZodDefault<z.ZodNumber>;
|
|
24
|
+
heartbeatDefaultInterval: z.ZodDefault<z.ZodNumber>;
|
|
25
|
+
heartbeatActiveHours: z.ZodDefault<z.ZodString>;
|
|
26
|
+
heartbeatMinInterval: z.ZodDefault<z.ZodNumber>;
|
|
27
|
+
reflectionEnabled: z.ZodDefault<z.ZodBoolean>;
|
|
28
|
+
reflectionModel: z.ZodOptional<z.ZodString>;
|
|
19
29
|
}, "strip", z.ZodTypeAny, {
|
|
20
30
|
anthropicApiKey: string;
|
|
21
31
|
dataDir: string;
|
|
@@ -30,9 +40,19 @@ declare const ConfigSchema: z.ZodObject<{
|
|
|
30
40
|
webhookRateLimit: number;
|
|
31
41
|
webhookMaxBodySize: number;
|
|
32
42
|
notifyOnComplete: boolean;
|
|
43
|
+
maxChildrenPerBloop: number;
|
|
44
|
+
maxSpawnDepth: number;
|
|
45
|
+
maxSchedulesPerProject: number;
|
|
46
|
+
maxTriggersPerProject: number;
|
|
47
|
+
minCronIntervalMinutes: number;
|
|
48
|
+
heartbeatDefaultInterval: number;
|
|
49
|
+
heartbeatActiveHours: string;
|
|
50
|
+
heartbeatMinInterval: number;
|
|
51
|
+
reflectionEnabled: boolean;
|
|
33
52
|
logFile?: string | undefined;
|
|
34
53
|
apiKey?: string | undefined;
|
|
35
54
|
notifyWebhookUrl?: string | undefined;
|
|
55
|
+
reflectionModel?: string | undefined;
|
|
36
56
|
}, {
|
|
37
57
|
anthropicApiKey?: string | undefined;
|
|
38
58
|
dataDir?: string | undefined;
|
|
@@ -50,6 +70,16 @@ declare const ConfigSchema: z.ZodObject<{
|
|
|
50
70
|
apiKey?: string | undefined;
|
|
51
71
|
notifyOnComplete?: boolean | undefined;
|
|
52
72
|
notifyWebhookUrl?: string | undefined;
|
|
73
|
+
maxChildrenPerBloop?: number | undefined;
|
|
74
|
+
maxSpawnDepth?: number | undefined;
|
|
75
|
+
maxSchedulesPerProject?: number | undefined;
|
|
76
|
+
maxTriggersPerProject?: number | undefined;
|
|
77
|
+
minCronIntervalMinutes?: number | undefined;
|
|
78
|
+
heartbeatDefaultInterval?: number | undefined;
|
|
79
|
+
heartbeatActiveHours?: string | undefined;
|
|
80
|
+
heartbeatMinInterval?: number | undefined;
|
|
81
|
+
reflectionEnabled?: boolean | undefined;
|
|
82
|
+
reflectionModel?: string | undefined;
|
|
53
83
|
}>;
|
|
54
84
|
export type Config = z.infer<typeof ConfigSchema>;
|
|
55
85
|
export declare function getConfig(): Config;
|
package/dist/config.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAkBxB,QAAA,MAAM,YAAY
|
|
1
|
+
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAkBxB,QAAA,MAAM,YAAY;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EA+BhB,CAAC;AAEH,MAAM,MAAM,MAAM,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,YAAY,CAAC,CAAC;AAIlD,wBAAgB,SAAS,IAAI,MAAM,CA8DlC;AAED,yCAAyC;AACzC,wBAAgB,WAAW,IAAI,IAAI,CAElC;AAED,wBAAgB,aAAa,CAAC,WAAW,EAAE,MAAM,GAAG,MAAM,CAEzD"}
|
package/dist/config.js
CHANGED
|
@@ -30,6 +30,20 @@ const ConfigSchema = z.object({
|
|
|
30
30
|
apiKey: z.string().optional(),
|
|
31
31
|
notifyOnComplete: z.boolean().default(true),
|
|
32
32
|
notifyWebhookUrl: z.string().url().optional(),
|
|
33
|
+
// Phase 1: Self-spawning limits
|
|
34
|
+
maxChildrenPerBloop: z.number().default(5),
|
|
35
|
+
maxSpawnDepth: z.number().default(3),
|
|
36
|
+
// Phase 2: Self-scheduling limits
|
|
37
|
+
maxSchedulesPerProject: z.number().default(20),
|
|
38
|
+
maxTriggersPerProject: z.number().default(20),
|
|
39
|
+
minCronIntervalMinutes: z.number().default(5),
|
|
40
|
+
// Phase 3: Heartbeat
|
|
41
|
+
heartbeatDefaultInterval: z.number().default(30),
|
|
42
|
+
heartbeatActiveHours: z.string().default("08:00-22:00"),
|
|
43
|
+
heartbeatMinInterval: z.number().default(5),
|
|
44
|
+
// Phase 4: Reflection
|
|
45
|
+
reflectionEnabled: z.boolean().default(false),
|
|
46
|
+
reflectionModel: z.string().optional(),
|
|
33
47
|
});
|
|
34
48
|
let _config = null;
|
|
35
49
|
export function getConfig() {
|
|
@@ -65,6 +79,32 @@ export function getConfig() {
|
|
|
65
79
|
? process.env.BEERCAN_NOTIFY_ON_COMPLETE !== "false"
|
|
66
80
|
: undefined,
|
|
67
81
|
notifyWebhookUrl: process.env.BEERCAN_NOTIFY_WEBHOOK_URL,
|
|
82
|
+
maxChildrenPerBloop: process.env.BEERCAN_MAX_CHILDREN_PER_BLOOP
|
|
83
|
+
? parseInt(process.env.BEERCAN_MAX_CHILDREN_PER_BLOOP)
|
|
84
|
+
: undefined,
|
|
85
|
+
maxSpawnDepth: process.env.BEERCAN_MAX_SPAWN_DEPTH
|
|
86
|
+
? parseInt(process.env.BEERCAN_MAX_SPAWN_DEPTH)
|
|
87
|
+
: undefined,
|
|
88
|
+
maxSchedulesPerProject: process.env.BEERCAN_MAX_SCHEDULES_PER_PROJECT
|
|
89
|
+
? parseInt(process.env.BEERCAN_MAX_SCHEDULES_PER_PROJECT)
|
|
90
|
+
: undefined,
|
|
91
|
+
maxTriggersPerProject: process.env.BEERCAN_MAX_TRIGGERS_PER_PROJECT
|
|
92
|
+
? parseInt(process.env.BEERCAN_MAX_TRIGGERS_PER_PROJECT)
|
|
93
|
+
: undefined,
|
|
94
|
+
minCronIntervalMinutes: process.env.BEERCAN_MIN_CRON_INTERVAL
|
|
95
|
+
? parseInt(process.env.BEERCAN_MIN_CRON_INTERVAL)
|
|
96
|
+
: undefined,
|
|
97
|
+
heartbeatDefaultInterval: process.env.BEERCAN_HEARTBEAT_INTERVAL
|
|
98
|
+
? parseInt(process.env.BEERCAN_HEARTBEAT_INTERVAL)
|
|
99
|
+
: undefined,
|
|
100
|
+
heartbeatActiveHours: process.env.BEERCAN_HEARTBEAT_HOURS,
|
|
101
|
+
heartbeatMinInterval: process.env.BEERCAN_HEARTBEAT_MIN_INTERVAL
|
|
102
|
+
? parseInt(process.env.BEERCAN_HEARTBEAT_MIN_INTERVAL)
|
|
103
|
+
: undefined,
|
|
104
|
+
reflectionEnabled: process.env.BEERCAN_REFLECTION_ENABLED
|
|
105
|
+
? process.env.BEERCAN_REFLECTION_ENABLED === "true"
|
|
106
|
+
: undefined,
|
|
107
|
+
reflectionModel: process.env.BEERCAN_REFLECTION_MODEL,
|
|
68
108
|
});
|
|
69
109
|
}
|
|
70
110
|
return _config;
|
package/dist/config.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,IAAI,OAAO,EAAE,MAAM,QAAQ,CAAC;AAC3C,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,IAAI,MAAM,MAAM,CAAC;AACxB,OAAO,EAAE,MAAM,IAAI,CAAC;AACpB,OAAO,EAAE,aAAa,EAAE,MAAM,KAAK,CAAC;AAEpC,qEAAqE;AACrE,wDAAwD;AACxD,6BAA6B;AAC7B,cAAc;AACd,MAAM,OAAO,GAAG,OAAO,CAAC,GAAG,CAAC,gBAAgB,IAAI,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,OAAO,EAAE,EAAE,UAAU,CAAC,CAAC;AACpF,OAAO,CAAC,EAAE,IAAI,EAAE,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,MAAM,CAAC,EAAE,CAAC,CAAC;AAE9C,MAAM,SAAS,GAAG,IAAI,CAAC,OAAO,CAAC,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC;AAC/D,MAAM,WAAW,GAAG,IAAI,CAAC,OAAO,CAAC,SAAS,EAAE,IAAI,CAAC,CAAC;AAClD,OAAO,CAAC,EAAE,IAAI,EAAE,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,MAAM,CAAC,EAAE,CAAC,CAAC;AAElD,OAAO,EAAE,CAAC,CAAC,WAAW;AAEtB,MAAM,YAAY,GAAG,CAAC,CAAC,MAAM,CAAC;IAC5B,eAAe,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,OAAO,CAAC,EAAE,CAAC;IACvC,OAAO,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,OAAO,EAAE,EAAE,UAAU,CAAC,CAAC;IAChE,YAAY,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,OAAO,CAAC,mBAAmB,CAAC;IACrD,UAAU,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,OAAO,CAAC,iBAAiB,CAAC;IACjD,eAAe,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,OAAO,CAAC,2BAA2B,CAAC;IAChE,kBAAkB,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,OAAO,CAAC,EAAE,CAAC;IAC1C,cAAc,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,OAAO,CAAC,OAAO,CAAC;IAC3C,aAAa,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,OAAO,CAAC,CAAC,CAAC;IACpC,kBAAkB,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,OAAO,CAAC,OAAO,CAAC;IAC/C,QAAQ,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC,OAAO,CAAC,MAAM,CAAC;IACpE,OAAO,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;IAC9B,gBAAgB,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,OAAO,CAAC,EAAE,CAAC;IACxC,kBAAkB,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,OAAO,CAAC,SAAS,CAAC;IACjD,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;IAC7B,gBAAgB,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC;IAC3C,gBAAgB,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,QAAQ,EAAE;
|
|
1
|
+
{"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import type { BeerCanDB } from "../storage/database.js";
|
|
2
|
+
import type { Project } from "../schemas.js";
|
|
3
|
+
export interface HeartbeatConfig {
|
|
4
|
+
enabled: boolean;
|
|
5
|
+
intervalMinutes: number;
|
|
6
|
+
activeHours?: {
|
|
7
|
+
start: string;
|
|
8
|
+
end: string;
|
|
9
|
+
};
|
|
10
|
+
checklist: string[];
|
|
11
|
+
suppressIfEmpty: boolean;
|
|
12
|
+
}
|
|
13
|
+
export interface HeartbeatExecutor {
|
|
14
|
+
runBloop(opts: {
|
|
15
|
+
projectSlug: string;
|
|
16
|
+
goal: string;
|
|
17
|
+
team?: string;
|
|
18
|
+
extraContext?: string;
|
|
19
|
+
}): Promise<any>;
|
|
20
|
+
}
|
|
21
|
+
export interface HeartbeatEventPublisher {
|
|
22
|
+
publish(event: {
|
|
23
|
+
type: string;
|
|
24
|
+
projectSlug: string;
|
|
25
|
+
source: string;
|
|
26
|
+
data: Record<string, unknown>;
|
|
27
|
+
timestamp: string;
|
|
28
|
+
}): void;
|
|
29
|
+
}
|
|
30
|
+
export declare class HeartbeatManager {
|
|
31
|
+
private db;
|
|
32
|
+
private executor;
|
|
33
|
+
private publisher;
|
|
34
|
+
private intervals;
|
|
35
|
+
private running;
|
|
36
|
+
constructor(db: BeerCanDB, executor: HeartbeatExecutor, publisher?: HeartbeatEventPublisher);
|
|
37
|
+
/** Load all projects and start heartbeats for those with config */
|
|
38
|
+
init(): void;
|
|
39
|
+
/** Stop all heartbeat intervals */
|
|
40
|
+
stop(): void;
|
|
41
|
+
/** Start heartbeat for a single project */
|
|
42
|
+
startProject(slug: string, config?: HeartbeatConfig): void;
|
|
43
|
+
/** Stop heartbeat for a single project */
|
|
44
|
+
stopProject(slug: string): void;
|
|
45
|
+
/** Run a single heartbeat check */
|
|
46
|
+
runHeartbeat(project: Project, config: HeartbeatConfig): Promise<void>;
|
|
47
|
+
/** Get the heartbeat config from a project's context */
|
|
48
|
+
getHeartbeatConfig(project: Project): HeartbeatConfig | null;
|
|
49
|
+
buildHeartbeatGoal(project: Project, config: HeartbeatConfig): string;
|
|
50
|
+
isInActiveHours(hours: {
|
|
51
|
+
start: string;
|
|
52
|
+
end: string;
|
|
53
|
+
}): boolean;
|
|
54
|
+
private parseTimeToMinutes;
|
|
55
|
+
private parseActiveHours;
|
|
56
|
+
}
|
|
57
|
+
//# sourceMappingURL=heartbeat.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"heartbeat.d.ts","sourceRoot":"","sources":["../../src/core/heartbeat.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,wBAAwB,CAAC;AACxD,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,eAAe,CAAC;AAI7C,MAAM,WAAW,eAAe;IAC9B,OAAO,EAAE,OAAO,CAAC;IACjB,eAAe,EAAE,MAAM,CAAC;IACxB,WAAW,CAAC,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,GAAG,EAAE,MAAM,CAAA;KAAE,CAAC;IAC7C,SAAS,EAAE,MAAM,EAAE,CAAC;IACpB,eAAe,EAAE,OAAO,CAAC;CAC1B;AAID,MAAM,WAAW,iBAAiB;IAChC,QAAQ,CAAC,IAAI,EAAE;QACb,WAAW,EAAE,MAAM,CAAC;QACpB,IAAI,EAAE,MAAM,CAAC;QACb,IAAI,CAAC,EAAE,MAAM,CAAC;QACd,YAAY,CAAC,EAAE,MAAM,CAAC;KACvB,GAAG,OAAO,CAAC,GAAG,CAAC,CAAC;CAClB;AAED,MAAM,WAAW,uBAAuB;IACtC,OAAO,CAAC,KAAK,EAAE;QACb,IAAI,EAAE,MAAM,CAAC;QACb,WAAW,EAAE,MAAM,CAAC;QACpB,MAAM,EAAE,MAAM,CAAC;QACf,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;QAC9B,SAAS,EAAE,MAAM,CAAC;KACnB,GAAG,IAAI,CAAC;CACV;AAED,qBAAa,gBAAgB;IAC3B,OAAO,CAAC,EAAE,CAAY;IACtB,OAAO,CAAC,QAAQ,CAAoB;IACpC,OAAO,CAAC,SAAS,CAAiC;IAClD,OAAO,CAAC,SAAS,CAAqD;IACtE,OAAO,CAAC,OAAO,CAAS;gBAGtB,EAAE,EAAE,SAAS,EACb,QAAQ,EAAE,iBAAiB,EAC3B,SAAS,CAAC,EAAE,uBAAuB;IAOrC,mEAAmE;IACnE,IAAI,IAAI,IAAI;IAkBZ,mCAAmC;IACnC,IAAI,IAAI,IAAI;IASZ,2CAA2C;IAC3C,YAAY,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,eAAe,GAAG,IAAI;IAqB1D,0CAA0C;IAC1C,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI;IAQ/B,mCAAmC;IAC7B,YAAY,CAAC,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,eAAe,GAAG,OAAO,CAAC,IAAI,CAAC;IA0D5E,wDAAwD;IACxD,kBAAkB,CAAC,OAAO,EAAE,OAAO,GAAG,eAAe,GAAG,IAAI;IAsB5D,kBAAkB,CAAC,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,eAAe,GAAG,MAAM;IAYrE,eAAe,CAAC,KAAK,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,GAAG,EAAE,MAAM,CAAA;KAAE,GAAG,OAAO;IAkB/D,OAAO,CAAC,kBAAkB;IAS1B,OAAO,CAAC,gBAAgB;CAKzB"}
|
|
@@ -0,0 +1,179 @@
|
|
|
1
|
+
import { getConfig } from "../config.js";
|
|
2
|
+
export class HeartbeatManager {
|
|
3
|
+
db;
|
|
4
|
+
executor;
|
|
5
|
+
publisher;
|
|
6
|
+
intervals = new Map();
|
|
7
|
+
running = false;
|
|
8
|
+
constructor(db, executor, publisher) {
|
|
9
|
+
this.db = db;
|
|
10
|
+
this.executor = executor;
|
|
11
|
+
this.publisher = publisher ?? null;
|
|
12
|
+
}
|
|
13
|
+
/** Load all projects and start heartbeats for those with config */
|
|
14
|
+
init() {
|
|
15
|
+
this.running = true;
|
|
16
|
+
const projects = this.db.listProjects();
|
|
17
|
+
let started = 0;
|
|
18
|
+
for (const project of projects) {
|
|
19
|
+
const config = this.getHeartbeatConfig(project);
|
|
20
|
+
if (config?.enabled) {
|
|
21
|
+
this.startProject(project.slug, config);
|
|
22
|
+
started++;
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
if (started > 0) {
|
|
26
|
+
console.log(`[heartbeat] Started ${started} project heartbeats`);
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
/** Stop all heartbeat intervals */
|
|
30
|
+
stop() {
|
|
31
|
+
this.running = false;
|
|
32
|
+
for (const [slug, interval] of this.intervals) {
|
|
33
|
+
clearInterval(interval);
|
|
34
|
+
this.intervals.delete(slug);
|
|
35
|
+
}
|
|
36
|
+
console.log("[heartbeat] Stopped all heartbeats");
|
|
37
|
+
}
|
|
38
|
+
/** Start heartbeat for a single project */
|
|
39
|
+
startProject(slug, config) {
|
|
40
|
+
if (this.intervals.has(slug))
|
|
41
|
+
return; // Already running
|
|
42
|
+
const project = this.db.getProjectBySlug(slug);
|
|
43
|
+
if (!project)
|
|
44
|
+
return;
|
|
45
|
+
const hbConfig = config ?? this.getHeartbeatConfig(project);
|
|
46
|
+
if (!hbConfig?.enabled)
|
|
47
|
+
return;
|
|
48
|
+
const globalConfig = getConfig();
|
|
49
|
+
const intervalMs = Math.max(hbConfig.intervalMinutes, globalConfig.heartbeatMinInterval) * 60 * 1000;
|
|
50
|
+
const interval = setInterval(() => {
|
|
51
|
+
this.runHeartbeat(project, hbConfig).catch((err) => {
|
|
52
|
+
console.error(`[heartbeat] Error for ${slug}: ${err.message}`);
|
|
53
|
+
});
|
|
54
|
+
}, intervalMs);
|
|
55
|
+
this.intervals.set(slug, interval);
|
|
56
|
+
}
|
|
57
|
+
/** Stop heartbeat for a single project */
|
|
58
|
+
stopProject(slug) {
|
|
59
|
+
const interval = this.intervals.get(slug);
|
|
60
|
+
if (interval) {
|
|
61
|
+
clearInterval(interval);
|
|
62
|
+
this.intervals.delete(slug);
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
/** Run a single heartbeat check */
|
|
66
|
+
async runHeartbeat(project, config) {
|
|
67
|
+
// Check active hours
|
|
68
|
+
if (config.activeHours && !this.isInActiveHours(config.activeHours)) {
|
|
69
|
+
return;
|
|
70
|
+
}
|
|
71
|
+
// Build goal from checklist
|
|
72
|
+
const goal = this.buildHeartbeatGoal(project, config);
|
|
73
|
+
const extraContext = [
|
|
74
|
+
"This is an automated heartbeat check. Be concise.",
|
|
75
|
+
"If you find nothing noteworthy and everything looks fine, respond exactly with: HEARTBEAT_EMPTY",
|
|
76
|
+
"If you find something worth reporting, provide a brief summary of your findings.",
|
|
77
|
+
].join("\n");
|
|
78
|
+
try {
|
|
79
|
+
const bloop = await this.executor.runBloop({
|
|
80
|
+
projectSlug: project.slug,
|
|
81
|
+
goal,
|
|
82
|
+
team: "solo",
|
|
83
|
+
extraContext,
|
|
84
|
+
});
|
|
85
|
+
// Check if result indicates nothing noteworthy
|
|
86
|
+
const resultStr = bloop.result
|
|
87
|
+
? typeof bloop.result === "string"
|
|
88
|
+
? bloop.result
|
|
89
|
+
: JSON.stringify(bloop.result)
|
|
90
|
+
: "";
|
|
91
|
+
const isEmpty = resultStr.includes("HEARTBEAT_EMPTY");
|
|
92
|
+
if (isEmpty && config.suppressIfEmpty) {
|
|
93
|
+
// Silent — don't notify
|
|
94
|
+
return;
|
|
95
|
+
}
|
|
96
|
+
// Publish heartbeat result event
|
|
97
|
+
if (this.publisher) {
|
|
98
|
+
this.publisher.publish({
|
|
99
|
+
type: "heartbeat:result",
|
|
100
|
+
projectSlug: project.slug,
|
|
101
|
+
source: "heartbeat",
|
|
102
|
+
data: {
|
|
103
|
+
bloopId: bloop.id,
|
|
104
|
+
goal,
|
|
105
|
+
result: resultStr.slice(0, 2000),
|
|
106
|
+
empty: isEmpty,
|
|
107
|
+
tokensUsed: bloop.tokensUsed,
|
|
108
|
+
},
|
|
109
|
+
timestamp: new Date().toISOString(),
|
|
110
|
+
});
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
catch (err) {
|
|
114
|
+
console.error(`[heartbeat] Failed for ${project.slug}: ${err.message}`);
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
/** Get the heartbeat config from a project's context */
|
|
118
|
+
getHeartbeatConfig(project) {
|
|
119
|
+
const ctx = project.context?.heartbeat;
|
|
120
|
+
if (!ctx || typeof ctx !== "object")
|
|
121
|
+
return null;
|
|
122
|
+
const config = getConfig();
|
|
123
|
+
const hb = ctx;
|
|
124
|
+
return {
|
|
125
|
+
enabled: hb.enabled === true,
|
|
126
|
+
intervalMinutes: typeof hb.intervalMinutes === "number"
|
|
127
|
+
? hb.intervalMinutes
|
|
128
|
+
: config.heartbeatDefaultInterval,
|
|
129
|
+
activeHours: hb.activeHours && typeof hb.activeHours === "object"
|
|
130
|
+
? hb.activeHours
|
|
131
|
+
: this.parseActiveHours(config.heartbeatActiveHours),
|
|
132
|
+
checklist: Array.isArray(hb.checklist) ? hb.checklist : [],
|
|
133
|
+
suppressIfEmpty: hb.suppressIfEmpty !== false, // default true
|
|
134
|
+
};
|
|
135
|
+
}
|
|
136
|
+
// ── Internal ──────────────────────────────────────────────
|
|
137
|
+
buildHeartbeatGoal(project, config) {
|
|
138
|
+
if (config.checklist.length === 0) {
|
|
139
|
+
return `Heartbeat check for ${project.name}: Review project health, check for any issues or pending work.`;
|
|
140
|
+
}
|
|
141
|
+
const items = config.checklist
|
|
142
|
+
.map((item, i) => `${i + 1}. ${item}`)
|
|
143
|
+
.join("; ");
|
|
144
|
+
return `Heartbeat check for ${project.name}: ${items}`;
|
|
145
|
+
}
|
|
146
|
+
isInActiveHours(hours) {
|
|
147
|
+
const now = new Date();
|
|
148
|
+
const currentMinutes = now.getHours() * 60 + now.getMinutes();
|
|
149
|
+
const startMinutes = this.parseTimeToMinutes(hours.start);
|
|
150
|
+
const endMinutes = this.parseTimeToMinutes(hours.end);
|
|
151
|
+
if (startMinutes === null || endMinutes === null)
|
|
152
|
+
return true; // Invalid → allow
|
|
153
|
+
if (startMinutes <= endMinutes) {
|
|
154
|
+
// Normal range: e.g., 08:00 - 22:00
|
|
155
|
+
return currentMinutes >= startMinutes && currentMinutes <= endMinutes;
|
|
156
|
+
}
|
|
157
|
+
else {
|
|
158
|
+
// Overnight range: e.g., 22:00 - 06:00
|
|
159
|
+
return currentMinutes >= startMinutes || currentMinutes <= endMinutes;
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
parseTimeToMinutes(time) {
|
|
163
|
+
const match = time.match(/^(\d{1,2}):(\d{2})$/);
|
|
164
|
+
if (!match)
|
|
165
|
+
return null;
|
|
166
|
+
const hours = parseInt(match[1]);
|
|
167
|
+
const minutes = parseInt(match[2]);
|
|
168
|
+
if (hours < 0 || hours > 23 || minutes < 0 || minutes > 59)
|
|
169
|
+
return null;
|
|
170
|
+
return hours * 60 + minutes;
|
|
171
|
+
}
|
|
172
|
+
parseActiveHours(str) {
|
|
173
|
+
const parts = str.split("-");
|
|
174
|
+
if (parts.length !== 2)
|
|
175
|
+
return undefined;
|
|
176
|
+
return { start: parts[0].trim(), end: parts[1].trim() };
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
//# sourceMappingURL=heartbeat.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"heartbeat.js","sourceRoot":"","sources":["../../src/core/heartbeat.ts"],"names":[],"mappings":"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"}
|
package/dist/core/job-queue.d.ts
CHANGED
|
@@ -7,6 +7,7 @@ export interface EnqueueOptions {
|
|
|
7
7
|
source?: "manual" | "cron" | "event";
|
|
8
8
|
sourceId?: string;
|
|
9
9
|
extraContext?: string;
|
|
10
|
+
parentBloopId?: string;
|
|
10
11
|
}
|
|
11
12
|
export interface Job {
|
|
12
13
|
id: string;
|
|
@@ -18,6 +19,7 @@ export interface Job {
|
|
|
18
19
|
source: string;
|
|
19
20
|
sourceId: string | null;
|
|
20
21
|
extraContext: string | null;
|
|
22
|
+
parentBloopId: string | null;
|
|
21
23
|
bloopId: string | null;
|
|
22
24
|
error: string | null;
|
|
23
25
|
createdAt: string;
|
|
@@ -43,6 +45,7 @@ export declare class JobQueue {
|
|
|
43
45
|
goal: string;
|
|
44
46
|
team: string;
|
|
45
47
|
extraContext?: string;
|
|
48
|
+
parentBloopId?: string;
|
|
46
49
|
signal?: AbortSignal;
|
|
47
50
|
}) => Promise<{
|
|
48
51
|
id: string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"job-queue.d.ts","sourceRoot":"","sources":["../../src/core/job-queue.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,wBAAwB,CAAC;AAMxD,MAAM,WAAW,cAAc;IAC7B,WAAW,EAAE,MAAM,CAAC;IACpB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,MAAM,CAAC,EAAE,QAAQ,GAAG,MAAM,GAAG,OAAO,CAAC;IACrC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,YAAY,CAAC,EAAE,MAAM,CAAC;
|
|
1
|
+
{"version":3,"file":"job-queue.d.ts","sourceRoot":"","sources":["../../src/core/job-queue.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,wBAAwB,CAAC;AAMxD,MAAM,WAAW,cAAc;IAC7B,WAAW,EAAE,MAAM,CAAC;IACpB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,MAAM,CAAC,EAAE,QAAQ,GAAG,MAAM,GAAG,OAAO,CAAC;IACrC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB;AAED,MAAM,WAAW,GAAG;IAClB,EAAE,EAAE,MAAM,CAAC;IACX,WAAW,EAAE,MAAM,CAAC;IACpB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,SAAS,GAAG,SAAS,GAAG,WAAW,GAAG,QAAQ,GAAG,SAAS,GAAG,WAAW,CAAC;IACjF,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,aAAa,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IACvB,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;CAC5B;AAED,MAAM,WAAW,QAAQ;IACvB,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,qBAAa,QAAQ;IACnB,OAAO,CAAC,OAAO,CAAoC;IACnD,OAAO,CAAC,gBAAgB,CAAsC;IAC9D,OAAO,CAAC,aAAa,CAAS;IAC9B,OAAO,CAAC,EAAE,CAAY;IACtB,OAAO,CAAC,QAAQ,CAA8L;gBAElM,EAAE,EAAE,SAAS,EAAE,aAAa,EAAE,MAAM;IAKhD,wEAAwE;IACxE,WAAW,CAAC,EAAE,EAAE,CAAC,IAAI,EAAE;QAAE,WAAW,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAC;QAAC,YAAY,CAAC,EAAE,MAAM,CAAC;QAAC,aAAa,CAAC,EAAE,MAAM,CAAC;QAAC,MAAM,CAAC,EAAE,WAAW,CAAA;KAAE,KAAK,OAAO,CAAC;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,CAAC,GAAG,IAAI;IAIlM,yCAAyC;IACzC,OAAO,CAAC,IAAI,EAAE,cAAc,GAAG,MAAM;IAiCrC,+DAA+D;IAC/D,WAAW,IAAI,IAAI;YAyBL,UAAU;IAqCxB,uCAAuC;IACvC,SAAS,CAAC,KAAK,EAAE,MAAM,GAAG;QAAE,SAAS,EAAE,OAAO,CAAC;QAAC,MAAM,CAAC,EAAE,MAAM,CAAC;QAAC,MAAM,CAAC,EAAE,MAAM,CAAA;KAAE;IA+BlF,4BAA4B;IAC5B,QAAQ,IAAI,QAAQ;IAIpB,gDAAgD;IAChD,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,EAAE,KAAK,SAAK,GAAG,GAAG,EAAE;IAI5C,yDAAyD;IACnD,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;CAmB7B"}
|
package/dist/core/job-queue.js
CHANGED
|
@@ -29,6 +29,7 @@ export class JobQueue {
|
|
|
29
29
|
source: opts.source ?? "manual",
|
|
30
30
|
sourceId: opts.sourceId ?? null,
|
|
31
31
|
extraContext: opts.extraContext ?? null,
|
|
32
|
+
parentBloopId: opts.parentBloopId ?? null,
|
|
32
33
|
bloopId: null,
|
|
33
34
|
error: null,
|
|
34
35
|
createdAt: now,
|
|
@@ -75,6 +76,7 @@ export class JobQueue {
|
|
|
75
76
|
goal: job.goal,
|
|
76
77
|
team: job.team,
|
|
77
78
|
extraContext: job.extraContext ?? undefined,
|
|
79
|
+
parentBloopId: job.parentBloopId ?? undefined,
|
|
78
80
|
signal: controller.signal,
|
|
79
81
|
});
|
|
80
82
|
this.db.updateJob(job.id, {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"job-queue.js","sourceRoot":"","sources":["../../src/core/job-queue.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,EAAE,IAAI,IAAI,EAAE,MAAM,MAAM,CAAC;AAClC,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;
|
|
1
|
+
{"version":3,"file":"job-queue.js","sourceRoot":"","sources":["../../src/core/job-queue.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import Anthropic from "@anthropic-ai/sdk";
|
|
2
|
+
import type { MemoryManager } from "../memory/index.js";
|
|
3
|
+
import type { BeerCanDB } from "../storage/database.js";
|
|
4
|
+
import type { Bloop, Project } from "../schemas.js";
|
|
5
|
+
export interface ReflectionItem {
|
|
6
|
+
title: string;
|
|
7
|
+
content: string;
|
|
8
|
+
}
|
|
9
|
+
export interface ReflectionResult {
|
|
10
|
+
lessons: ReflectionItem[];
|
|
11
|
+
patterns: ReflectionItem[];
|
|
12
|
+
errors: ReflectionItem[];
|
|
13
|
+
suggestions: string[];
|
|
14
|
+
}
|
|
15
|
+
export declare class ReflectionEngine {
|
|
16
|
+
private client;
|
|
17
|
+
private memory;
|
|
18
|
+
private db;
|
|
19
|
+
constructor(client: Anthropic, memory: MemoryManager, db: BeerCanDB);
|
|
20
|
+
/**
|
|
21
|
+
* Run a lightweight reflection on a completed/failed bloop.
|
|
22
|
+
* Single Haiku call with structured output.
|
|
23
|
+
*/
|
|
24
|
+
reflect(bloop: Bloop, projectSlug: string): Promise<ReflectionResult | null>;
|
|
25
|
+
/**
|
|
26
|
+
* Periodic consolidation: merge duplicate reflection memories,
|
|
27
|
+
* strengthen high-confidence insights, prune low-value ones.
|
|
28
|
+
*/
|
|
29
|
+
consolidate(projectSlug: string): Promise<{
|
|
30
|
+
merged: number;
|
|
31
|
+
pruned: number;
|
|
32
|
+
}>;
|
|
33
|
+
private buildReflectionSummary;
|
|
34
|
+
private storeLessons;
|
|
35
|
+
private updateKnowledgeGraph;
|
|
36
|
+
}
|
|
37
|
+
export declare function shouldReflect(bloop: Bloop, project: Project): boolean;
|
|
38
|
+
//# sourceMappingURL=reflection.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"reflection.d.ts","sourceRoot":"","sources":["../../src/core/reflection.ts"],"names":[],"mappings":"AAAA,OAAO,SAAS,MAAM,mBAAmB,CAAC;AAE1C,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AACxD,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,wBAAwB,CAAC;AACxD,OAAO,KAAK,EAAE,KAAK,EAAE,OAAO,EAAE,MAAM,eAAe,CAAC;AAIpD,MAAM,WAAW,cAAc;IAC7B,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,gBAAgB;IAC/B,OAAO,EAAE,cAAc,EAAE,CAAC;IAC1B,QAAQ,EAAE,cAAc,EAAE,CAAC;IAC3B,MAAM,EAAE,cAAc,EAAE,CAAC;IACzB,WAAW,EAAE,MAAM,EAAE,CAAC;CACvB;AA0DD,qBAAa,gBAAgB;IAC3B,OAAO,CAAC,MAAM,CAAY;IAC1B,OAAO,CAAC,MAAM,CAAgB;IAC9B,OAAO,CAAC,EAAE,CAAY;gBAEV,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,aAAa,EAAE,EAAE,EAAE,SAAS;IAMnE;;;OAGG;IACG,OAAO,CAAC,KAAK,EAAE,KAAK,EAAE,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,gBAAgB,GAAG,IAAI,CAAC;IAyClF;;;OAGG;IACG,WAAW,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC;QAAE,MAAM,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,CAAC;IAqFnF,OAAO,CAAC,sBAAsB;YAgChB,YAAY;YA6CZ,oBAAoB;CAkDnC;AAID,wBAAgB,aAAa,CAAC,KAAK,EAAE,KAAK,EAAE,OAAO,EAAE,OAAO,GAAG,OAAO,CA0BrE"}
|