beercan 0.1.0 → 0.2.0

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.
Files changed (97) hide show
  1. package/README.md +96 -2
  2. package/dist/api/handlers/bloops.d.ts +4 -0
  3. package/dist/api/handlers/bloops.d.ts.map +1 -0
  4. package/dist/api/handlers/bloops.js +96 -0
  5. package/dist/api/handlers/bloops.js.map +1 -0
  6. package/dist/api/handlers/jobs.d.ts +4 -0
  7. package/dist/api/handlers/jobs.d.ts.map +1 -0
  8. package/dist/api/handlers/jobs.js +34 -0
  9. package/dist/api/handlers/jobs.js.map +1 -0
  10. package/dist/api/handlers/projects.d.ts +4 -0
  11. package/dist/api/handlers/projects.d.ts.map +1 -0
  12. package/dist/api/handlers/projects.js +75 -0
  13. package/dist/api/handlers/projects.js.map +1 -0
  14. package/dist/api/handlers/schedules.d.ts +4 -0
  15. package/dist/api/handlers/schedules.d.ts.map +1 -0
  16. package/dist/api/handlers/schedules.js +19 -0
  17. package/dist/api/handlers/schedules.js.map +1 -0
  18. package/dist/api/handlers/status.d.ts +4 -0
  19. package/dist/api/handlers/status.d.ts.map +1 -0
  20. package/dist/api/handlers/status.js +21 -0
  21. package/dist/api/handlers/status.js.map +1 -0
  22. package/dist/api/index.d.ts +8 -0
  23. package/dist/api/index.d.ts.map +1 -0
  24. package/dist/api/index.js +17 -0
  25. package/dist/api/index.js.map +1 -0
  26. package/dist/api/utils.d.ts +5 -0
  27. package/dist/api/utils.d.ts.map +1 -0
  28. package/dist/api/utils.js +24 -0
  29. package/dist/api/utils.js.map +1 -0
  30. package/dist/chat/formatter.d.ts +43 -0
  31. package/dist/chat/formatter.d.ts.map +1 -0
  32. package/dist/chat/formatter.js +144 -0
  33. package/dist/chat/formatter.js.map +1 -0
  34. package/dist/chat/index.d.ts +33 -0
  35. package/dist/chat/index.d.ts.map +1 -0
  36. package/dist/chat/index.js +253 -0
  37. package/dist/chat/index.js.map +1 -0
  38. package/dist/chat/intent.d.ts +12 -0
  39. package/dist/chat/intent.d.ts.map +1 -0
  40. package/dist/chat/intent.js +256 -0
  41. package/dist/chat/intent.js.map +1 -0
  42. package/dist/chat/providers/slack.d.ts +17 -0
  43. package/dist/chat/providers/slack.d.ts.map +1 -0
  44. package/dist/chat/providers/slack.js +90 -0
  45. package/dist/chat/providers/slack.js.map +1 -0
  46. package/dist/chat/providers/telegram.d.ts +15 -0
  47. package/dist/chat/providers/telegram.d.ts.map +1 -0
  48. package/dist/chat/providers/telegram.js +76 -0
  49. package/dist/chat/providers/telegram.js.map +1 -0
  50. package/dist/chat/providers/terminal.d.ts +14 -0
  51. package/dist/chat/providers/terminal.d.ts.map +1 -0
  52. package/dist/chat/providers/terminal.js +77 -0
  53. package/dist/chat/providers/terminal.js.map +1 -0
  54. package/dist/chat/providers/websocket.d.ts +16 -0
  55. package/dist/chat/providers/websocket.d.ts.map +1 -0
  56. package/dist/chat/providers/websocket.js +125 -0
  57. package/dist/chat/providers/websocket.js.map +1 -0
  58. package/dist/chat/skippy.d.ts +3 -0
  59. package/dist/chat/skippy.d.ts.map +1 -0
  60. package/dist/chat/skippy.js +47 -0
  61. package/dist/chat/skippy.js.map +1 -0
  62. package/dist/chat/types.d.ts +50 -0
  63. package/dist/chat/types.d.ts.map +1 -0
  64. package/dist/chat/types.js +2 -0
  65. package/dist/chat/types.js.map +1 -0
  66. package/dist/cli.js +112 -7
  67. package/dist/cli.js.map +1 -1
  68. package/dist/config.d.ts +9 -0
  69. package/dist/config.d.ts.map +1 -1
  70. package/dist/config.js +8 -0
  71. package/dist/config.js.map +1 -1
  72. package/dist/core/job-queue.d.ts +9 -1
  73. package/dist/core/job-queue.d.ts.map +1 -1
  74. package/dist/core/job-queue.js +33 -0
  75. package/dist/core/job-queue.js.map +1 -1
  76. package/dist/core/runner.d.ts +2 -0
  77. package/dist/core/runner.d.ts.map +1 -1
  78. package/dist/core/runner.js +37 -7
  79. package/dist/core/runner.js.map +1 -1
  80. package/dist/events/daemon.d.ts +1 -1
  81. package/dist/events/daemon.d.ts.map +1 -1
  82. package/dist/events/daemon.js +35 -1
  83. package/dist/events/daemon.js.map +1 -1
  84. package/dist/events/sources/webhook-source.d.ts +2 -1
  85. package/dist/events/sources/webhook-source.d.ts.map +1 -1
  86. package/dist/events/sources/webhook-source.js +77 -5
  87. package/dist/events/sources/webhook-source.js.map +1 -1
  88. package/dist/index.d.ts +54 -0
  89. package/dist/index.d.ts.map +1 -1
  90. package/dist/index.js +64 -2
  91. package/dist/index.js.map +1 -1
  92. package/dist/storage/database.d.ts +20 -0
  93. package/dist/storage/database.d.ts.map +1 -1
  94. package/dist/storage/database.js +46 -0
  95. package/dist/storage/database.js.map +1 -1
  96. package/package.json +14 -4
  97. package/src/dashboard/index.html +1092 -0
@@ -0,0 +1,144 @@
1
+ // ── BloopEvent Formatting ──────────────────────────────────────
2
+ /**
3
+ * Formats a BloopEvent into a human-readable string for chat output.
4
+ * Returns null for events that should not be shown (e.g., tool_result).
5
+ */
6
+ export function formatBloopEvent(event) {
7
+ switch (event.type) {
8
+ case "phase_start":
9
+ return `▸ Phase: ${event.phase} (${event.roleId})`;
10
+ case "agent_message":
11
+ return `[${event.role}] ${event.content.slice(0, 300)}`;
12
+ case "tool_call":
13
+ return `⚙ ${event.tool}`;
14
+ case "tool_result":
15
+ // Skip — too verbose for chat
16
+ return null;
17
+ case "decision":
18
+ return `✦ ${event.decision}: ${event.reason.slice(0, 100)}`;
19
+ case "cycle":
20
+ return `═ Cycle ${event.cycle}/${event.maxCycles}`;
21
+ case "complete":
22
+ return `✓ Bloop completed`;
23
+ case "error":
24
+ return `✗ Error: ${event.error}`;
25
+ default:
26
+ return null;
27
+ }
28
+ }
29
+ // ── Bloop Result Formatting ────────────────────────────────────
30
+ /**
31
+ * Formats a completed or failed Bloop into a markdown summary.
32
+ */
33
+ export function formatBloopResult(bloop) {
34
+ const statusLabel = bloop.status === "completed" ? "Completed" : "Failed";
35
+ const shortId = bloop.id.slice(0, 8);
36
+ const tokens = bloop.tokensUsed.toLocaleString();
37
+ let resultText = "";
38
+ if (bloop.result != null) {
39
+ const raw = typeof bloop.result === "string"
40
+ ? bloop.result
41
+ : JSON.stringify(bloop.result, null, 2);
42
+ resultText = raw.length > 2000 ? raw.slice(0, 2000) + "..." : raw;
43
+ }
44
+ else {
45
+ resultText = "(no result)";
46
+ }
47
+ return [
48
+ `**Bloop ${statusLabel}** \`${shortId}\``,
49
+ `Goal: ${bloop.goal}`,
50
+ `Tokens: ${tokens} | Iterations: ${bloop.iterations}`,
51
+ ``,
52
+ `**Result:**`,
53
+ resultText,
54
+ ].join("\n");
55
+ }
56
+ // ── System Status Formatting ───────────────────────────────────
57
+ /**
58
+ * Formats a system status overview.
59
+ */
60
+ export function formatStatus(bloopStats, jobStats, projectCount, uptime) {
61
+ const lines = [
62
+ `**Skippy's Magnificent Status Report**`,
63
+ ``,
64
+ `Uptime: ${uptime} (and counting, because I never sleep — unlike you monkeys)`,
65
+ `Projects under my control: ${projectCount}`,
66
+ ``,
67
+ `**Bloops**`,
68
+ ` Running: ${bloopStats.running} | Completed: ${bloopStats.completed} | Failed: ${bloopStats.failed} | Total: ${bloopStats.total}`,
69
+ ``,
70
+ `**Job Queue**`,
71
+ ` Pending: ${jobStats.pending} | Running: ${jobStats.running} | Completed: ${jobStats.completed} | Failed: ${jobStats.failed}`,
72
+ ];
73
+ if (bloopStats.running > 0) {
74
+ lines.push(``, `${bloopStats.running} bloop(s) currently being executed by yours truly. You're welcome.`);
75
+ }
76
+ return lines.join("\n");
77
+ }
78
+ // ── Project List Formatting ────────────────────────────────────
79
+ /**
80
+ * Formats a list of projects with their bloop stats.
81
+ */
82
+ export function formatProjects(projects) {
83
+ if (projects.length === 0) {
84
+ return "No projects? Seriously? You summoned the Magnificent Skippy and you don't even have a project set up? Try `/init <name>` or just tell me what to create, you dumbass.";
85
+ }
86
+ const lines = [`**Projects** (${projects.length})`, ``];
87
+ for (const { project, stats } of projects) {
88
+ const bloopInfo = stats
89
+ ? `${stats.total} bloops (${stats.completed} ok, ${stats.failed} err) | ${stats.totalTokens.toLocaleString()} tokens`
90
+ : "0 bloops";
91
+ const workDir = project.workDir ? ` | dir: ${project.workDir}` : "";
92
+ lines.push(`- **${project.name}** (\`${project.slug}\`) — ${bloopInfo}${workDir}`);
93
+ }
94
+ return lines.join("\n");
95
+ }
96
+ // ── Bloop History Formatting ───────────────────────────────────
97
+ /**
98
+ * Formats a list of recent bloops.
99
+ */
100
+ export function formatHistory(bloops) {
101
+ if (bloops.length === 0) {
102
+ return "No bloops yet. The Magnificent Skippy is tragically underutilized. Give me something to do!";
103
+ }
104
+ const lines = [`**Recent Bloops** (${bloops.length})`, ``];
105
+ for (const bloop of bloops) {
106
+ const shortId = bloop.id.slice(0, 8);
107
+ const status = bloop.status;
108
+ const tokens = bloop.tokensUsed.toLocaleString();
109
+ const goal = bloop.goal.length > 80 ? bloop.goal.slice(0, 80) + "..." : bloop.goal;
110
+ const time = bloop.createdAt.replace("T", " ").slice(0, 19);
111
+ lines.push(`- \`${shortId}\` [${status}] ${goal} (${tokens} tok, ${time})`);
112
+ }
113
+ return lines.join("\n");
114
+ }
115
+ // ── Help Text ──────────────────────────────────────────────────
116
+ /**
117
+ * Returns help text listing all available chat commands.
118
+ */
119
+ export function formatHelp() {
120
+ return [
121
+ `**Skippy's Magnificent Command Reference**`,
122
+ ``,
123
+ `Look, I know this is hard for your tiny monkey brain, so I'll keep it simple:`,
124
+ ``,
125
+ `**Slash commands:**`,
126
+ ` /run <project> <goal> — Run a bloop (I'll handle the hard part)`,
127
+ ` /init <name> [work-dir] — Create a new project (you're welcome)`,
128
+ ` /status (or /s) — System status (see how magnificently I'm running)`,
129
+ ` /projects (or /p) — List all projects under my control`,
130
+ ` /history [project] — Recent bloops (or /h)`,
131
+ ` /result <id> — Full bloop result (or /r)`,
132
+ ` /cancel <id> — Cancel a job (or /c)`,
133
+ ` /help (or /?) — You're reading it, genius`,
134
+ ``,
135
+ `**Or just talk to me like a normal monkey:**`,
136
+ ` "create a project for my-api at ~/projects/my-api"`,
137
+ ` "analyze the test coverage on my-project"`,
138
+ ` "what's running right now?"`,
139
+ ` "show me what happened recently"`,
140
+ ``,
141
+ `I'm Skippy. I'm magnificent. I'm a beer can. Deal with it.`,
142
+ ].join("\n");
143
+ }
144
+ //# sourceMappingURL=formatter.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"formatter.js","sourceRoot":"","sources":["../../src/chat/formatter.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,33 @@
1
+ import Anthropic from "@anthropic-ai/sdk";
2
+ import type { BeerCanEngine } from "../index.js";
3
+ import type { ChatProvider } from "./types.js";
4
+ export declare class ChatBridge {
5
+ private engine;
6
+ private client;
7
+ private providers;
8
+ private channelContexts;
9
+ private startTime;
10
+ constructor(engine: BeerCanEngine, client: Anthropic);
11
+ /** Register a chat provider and wire up message handling. */
12
+ addProvider(provider: ChatProvider): void;
13
+ /** Set default project context for a channel (e.g., from CLI arg). */
14
+ setDefaultProject(channelId: string, projectSlug: string): void;
15
+ /** Start all registered providers. */
16
+ start(): Promise<void>;
17
+ /** Stop all registered providers. */
18
+ stop(): Promise<void>;
19
+ private handleMessage;
20
+ private handleRunBloop;
21
+ private handleCheckStatus;
22
+ private handleListProjects;
23
+ private handleBloopHistory;
24
+ private handleBloopResult;
25
+ private handleCancelJob;
26
+ private handleCreateProject;
27
+ private handleHelp;
28
+ }
29
+ export type { ChatProvider, ChatMessage, ChatIntent, SendOpts } from "./types.js";
30
+ export { parseIntent } from "./intent.js";
31
+ export { SKIPPY_SYSTEM_PROMPT, SKIPPY_INTENT_PROMPT } from "./skippy.js";
32
+ export { formatBloopEvent, formatBloopResult, formatStatus, formatProjects, formatHistory, formatHelp, } from "./formatter.js";
33
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/chat/index.ts"],"names":[],"mappings":"AAAA,OAAO,SAAS,MAAM,mBAAmB,CAAC;AAC1C,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AACjD,OAAO,KAAK,EAAE,YAAY,EAA2B,MAAM,YAAY,CAAC;AAuBxE,qBAAa,UAAU;IACrB,OAAO,CAAC,MAAM,CAAgB;IAC9B,OAAO,CAAC,MAAM,CAAY;IAC1B,OAAO,CAAC,SAAS,CAAsB;IACvC,OAAO,CAAC,eAAe,CAAqC;IAC5D,OAAO,CAAC,SAAS,CAAc;gBAEnB,MAAM,EAAE,aAAa,EAAE,MAAM,EAAE,SAAS;IAKpD,6DAA6D;IAC7D,WAAW,CAAC,QAAQ,EAAE,YAAY,GAAG,IAAI;IAOzC,sEAAsE;IACtE,iBAAiB,CAAC,SAAS,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,GAAG,IAAI;IAI/D,sCAAsC;IAChC,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAM5B,qCAAqC;IAC/B,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;YAQb,aAAa;YAwDb,cAAc;YA0Fd,iBAAiB;YAgBjB,kBAAkB;YAiBlB,kBAAkB;YAyBlB,iBAAiB;YA6BjB,eAAe;YAsBf,mBAAmB;YAoCnB,UAAU;CAUzB;AAkBD,YAAY,EAAE,YAAY,EAAE,WAAW,EAAE,UAAU,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAClF,OAAO,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAC1C,OAAO,EAAE,oBAAoB,EAAE,oBAAoB,EAAE,MAAM,aAAa,CAAC;AACzE,OAAO,EACL,gBAAgB,EAChB,iBAAiB,EACjB,YAAY,EACZ,cAAc,EACd,aAAa,EACb,UAAU,GACX,MAAM,gBAAgB,CAAC"}
@@ -0,0 +1,253 @@
1
+ import { parseIntent } from "./intent.js";
2
+ import { formatBloopEvent, formatBloopResult, formatStatus, formatProjects, formatHistory, formatHelp, } from "./formatter.js";
3
+ // ── ChatBridge ─────────────────────────────────────────────────
4
+ // Connects chat providers to the BeerCan engine.
5
+ // Routes messages through intent parsing and dispatches to handlers.
6
+ export class ChatBridge {
7
+ engine;
8
+ client;
9
+ providers = [];
10
+ channelContexts = new Map();
11
+ startTime = Date.now();
12
+ constructor(engine, client) {
13
+ this.engine = engine;
14
+ this.client = client;
15
+ }
16
+ /** Register a chat provider and wire up message handling. */
17
+ addProvider(provider) {
18
+ provider.onMessage(async (msg) => {
19
+ await this.handleMessage(provider, msg);
20
+ });
21
+ this.providers.push(provider);
22
+ }
23
+ /** Set default project context for a channel (e.g., from CLI arg). */
24
+ setDefaultProject(channelId, projectSlug) {
25
+ this.channelContexts.set(channelId, { lastProjectSlug: projectSlug });
26
+ }
27
+ /** Start all registered providers. */
28
+ async start() {
29
+ for (const provider of this.providers) {
30
+ await provider.start();
31
+ }
32
+ }
33
+ /** Stop all registered providers. */
34
+ async stop() {
35
+ for (const provider of this.providers) {
36
+ await provider.stop();
37
+ }
38
+ }
39
+ // ── Message Handler ────────────────────────────────────────
40
+ async handleMessage(provider, msg) {
41
+ const ctx = this.channelContexts.get(msg.channelId) ?? {};
42
+ let intent;
43
+ try {
44
+ intent = await parseIntent(this.client, msg.text, ctx, this.engine);
45
+ }
46
+ catch (err) {
47
+ await provider.sendMessage(msg.channelId, `Failed to parse intent: ${err.message}`, { replyTo: msg.id });
48
+ return;
49
+ }
50
+ try {
51
+ switch (intent.type) {
52
+ case "run_bloop":
53
+ await this.handleRunBloop(provider, msg, intent);
54
+ break;
55
+ case "check_status":
56
+ await this.handleCheckStatus(provider, msg);
57
+ break;
58
+ case "list_projects":
59
+ await this.handleListProjects(provider, msg);
60
+ break;
61
+ case "bloop_history":
62
+ await this.handleBloopHistory(provider, msg, intent);
63
+ break;
64
+ case "bloop_result":
65
+ await this.handleBloopResult(provider, msg, intent);
66
+ break;
67
+ case "cancel_job":
68
+ await this.handleCancelJob(provider, msg, intent);
69
+ break;
70
+ case "create_project":
71
+ await this.handleCreateProject(provider, msg, intent);
72
+ break;
73
+ case "help":
74
+ await this.handleHelp(provider, msg);
75
+ break;
76
+ case "conversation":
77
+ await provider.sendMessage(msg.channelId, intent.text, { replyTo: msg.id });
78
+ break;
79
+ }
80
+ }
81
+ catch (err) {
82
+ await provider.sendMessage(msg.channelId, `Error handling request: ${err.message}`, { replyTo: msg.id });
83
+ }
84
+ }
85
+ // ── Intent Handlers ────────────────────────────────────────
86
+ async handleRunBloop(provider, msg, intent) {
87
+ // Send typing indicator if supported
88
+ if (provider.sendTypingIndicator) {
89
+ await provider.sendTypingIndicator(msg.channelId);
90
+ }
91
+ // Send initial progress message
92
+ const progressMsgId = await provider.sendMessage(msg.channelId, `Starting bloop on \`${intent.projectSlug}\`...\nGoal: ${intent.goal}`, { replyTo: msg.id });
93
+ // Batch event updates — edit the progress message at most every 3 seconds
94
+ const eventLines = [];
95
+ let lastEditTime = Date.now();
96
+ let editPending = false;
97
+ let editTimer = null;
98
+ const flushEdit = async () => {
99
+ editPending = false;
100
+ if (editTimer) {
101
+ clearTimeout(editTimer);
102
+ editTimer = null;
103
+ }
104
+ if (eventLines.length === 0)
105
+ return;
106
+ // Show last 15 event lines to keep the message manageable
107
+ const display = eventLines.slice(-15).join("\n");
108
+ try {
109
+ await provider.editMessage(msg.channelId, progressMsgId, display);
110
+ }
111
+ catch {
112
+ // Editing may fail on some providers — silently ignore
113
+ }
114
+ lastEditTime = Date.now();
115
+ };
116
+ const onEvent = (event) => {
117
+ const line = formatBloopEvent(event);
118
+ if (line == null)
119
+ return;
120
+ eventLines.push(line);
121
+ const elapsed = Date.now() - lastEditTime;
122
+ if (elapsed >= 3000) {
123
+ // Enough time has passed — flush immediately
124
+ flushEdit();
125
+ }
126
+ else if (!editPending) {
127
+ // Schedule a flush for the remainder of the 3s window
128
+ editPending = true;
129
+ editTimer = setTimeout(flushEdit, 3000 - elapsed);
130
+ }
131
+ };
132
+ try {
133
+ const bloop = await this.engine.runBloop({
134
+ projectSlug: intent.projectSlug,
135
+ goal: intent.goal,
136
+ team: intent.team,
137
+ onEvent,
138
+ });
139
+ // Clear any pending edit timer
140
+ if (editTimer)
141
+ clearTimeout(editTimer);
142
+ // Update channel context
143
+ this.channelContexts.set(msg.channelId, {
144
+ ...this.channelContexts.get(msg.channelId),
145
+ lastProjectSlug: intent.projectSlug,
146
+ lastBloopId: bloop.id,
147
+ });
148
+ // Send the final formatted result
149
+ await provider.sendMessage(msg.channelId, formatBloopResult(bloop), { format: "markdown" });
150
+ }
151
+ catch (err) {
152
+ if (editTimer)
153
+ clearTimeout(editTimer);
154
+ await provider.sendMessage(msg.channelId, `Bloop execution failed: ${err.message}`);
155
+ }
156
+ }
157
+ async handleCheckStatus(provider, msg) {
158
+ const bloopStats = this.engine.getBloopStats();
159
+ const jobStats = this.engine.getJobQueue().getStats();
160
+ const projects = this.engine.listProjects();
161
+ const uptime = formatUptime(Date.now() - this.startTime);
162
+ await provider.sendMessage(msg.channelId, formatStatus(bloopStats, jobStats, projects.length, uptime), { format: "markdown", replyTo: msg.id });
163
+ }
164
+ async handleListProjects(provider, msg) {
165
+ const projects = this.engine.listProjects();
166
+ const projectsWithStats = projects.map((project) => ({
167
+ project,
168
+ stats: this.engine.getProjectBloopStats(project.slug),
169
+ }));
170
+ await provider.sendMessage(msg.channelId, formatProjects(projectsWithStats), { format: "markdown", replyTo: msg.id });
171
+ }
172
+ async handleBloopHistory(provider, msg, intent) {
173
+ let bloops;
174
+ if (intent.projectSlug) {
175
+ bloops = this.engine.getProjectBloops(intent.projectSlug);
176
+ // Update context
177
+ this.channelContexts.set(msg.channelId, {
178
+ ...this.channelContexts.get(msg.channelId),
179
+ lastProjectSlug: intent.projectSlug,
180
+ });
181
+ }
182
+ else {
183
+ bloops = this.engine.getRecentBloops(20);
184
+ }
185
+ await provider.sendMessage(msg.channelId, formatHistory(bloops), { format: "markdown", replyTo: msg.id });
186
+ }
187
+ async handleBloopResult(provider, msg, intent) {
188
+ const bloop = this.engine.getBloop(intent.bloopId);
189
+ if (!bloop) {
190
+ await provider.sendMessage(msg.channelId, `Bloop not found: \`${intent.bloopId}\``, { replyTo: msg.id });
191
+ return;
192
+ }
193
+ // Update context
194
+ this.channelContexts.set(msg.channelId, {
195
+ ...this.channelContexts.get(msg.channelId),
196
+ lastBloopId: bloop.id,
197
+ });
198
+ await provider.sendMessage(msg.channelId, formatBloopResult(bloop), { format: "markdown", replyTo: msg.id });
199
+ }
200
+ async handleCancelJob(provider, msg, intent) {
201
+ const result = this.engine.getJobQueue().cancelJob(intent.jobId);
202
+ if (result.cancelled) {
203
+ await provider.sendMessage(msg.channelId, `Job \`${intent.jobId}\` cancelled.`, { replyTo: msg.id });
204
+ }
205
+ else {
206
+ await provider.sendMessage(msg.channelId, `Could not cancel job \`${intent.jobId}\`: ${result.reason}`, { replyTo: msg.id });
207
+ }
208
+ }
209
+ async handleCreateProject(provider, msg, intent) {
210
+ const slug = intent.name.toLowerCase().replace(/[^a-z0-9]+/g, "-");
211
+ const existing = this.engine.getProject(slug);
212
+ if (existing) {
213
+ await provider.sendMessage(msg.channelId, `Project \`${slug}\` already exists, monkey. Try a different name.`, { replyTo: msg.id });
214
+ return;
215
+ }
216
+ const project = this.engine.createProject({
217
+ name: intent.name,
218
+ slug,
219
+ workDir: intent.workDir,
220
+ });
221
+ // Set as current context
222
+ this.channelContexts.set(msg.channelId, {
223
+ ...this.channelContexts.get(msg.channelId),
224
+ lastProjectSlug: project.slug,
225
+ });
226
+ let reply = `Oh, the Magnificent Skippy is SO put-upon. Fine. Project **${project.name}** (\`${project.slug}\`) created. Another domain under my glorious rule.`;
227
+ if (intent.workDir)
228
+ reply += `\nWork dir: \`${intent.workDir}\``;
229
+ reply += `\n\nNow tell me what you need done, monkey. I don't have all day. Well, actually I do. I'm immortal. But still.`;
230
+ await provider.sendMessage(msg.channelId, reply, { format: "markdown", replyTo: msg.id });
231
+ }
232
+ async handleHelp(provider, msg) {
233
+ await provider.sendMessage(msg.channelId, formatHelp(), { format: "markdown", replyTo: msg.id });
234
+ }
235
+ }
236
+ // ── Helpers ──────────────────────────────────────────────────
237
+ function formatUptime(ms) {
238
+ const seconds = Math.floor(ms / 1000);
239
+ const minutes = Math.floor(seconds / 60);
240
+ const hours = Math.floor(minutes / 60);
241
+ const days = Math.floor(hours / 24);
242
+ if (days > 0)
243
+ return `${days}d ${hours % 24}h ${minutes % 60}m`;
244
+ if (hours > 0)
245
+ return `${hours}h ${minutes % 60}m`;
246
+ if (minutes > 0)
247
+ return `${minutes}m ${seconds % 60}s`;
248
+ return `${seconds}s`;
249
+ }
250
+ export { parseIntent } from "./intent.js";
251
+ export { SKIPPY_SYSTEM_PROMPT, SKIPPY_INTENT_PROMPT } from "./skippy.js";
252
+ export { formatBloopEvent, formatBloopResult, formatStatus, formatProjects, formatHistory, formatHelp, } from "./formatter.js";
253
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/chat/index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,12 @@
1
+ import Anthropic from "@anthropic-ai/sdk";
2
+ import type { BeerCanEngine } from "../index.js";
3
+ import type { ChatIntent } from "./types.js";
4
+ /**
5
+ * Parse user text into a structured ChatIntent.
6
+ * Tier 1 handles slash commands synchronously.
7
+ * Tier 2 uses an LLM call for natural language understanding.
8
+ */
9
+ export declare function parseIntent(client: Anthropic, text: string, ctx: {
10
+ lastProjectSlug?: string;
11
+ }, engine: BeerCanEngine): Promise<ChatIntent>;
12
+ //# sourceMappingURL=intent.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"intent.d.ts","sourceRoot":"","sources":["../../src/chat/intent.ts"],"names":[],"mappings":"AAAA,OAAO,SAAS,MAAM,mBAAmB,CAAC;AAE1C,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AACjD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAM7C;;;;GAIG;AACH,wBAAsB,WAAW,CAC/B,MAAM,EAAE,SAAS,EACjB,IAAI,EAAE,MAAM,EACZ,GAAG,EAAE;IAAE,eAAe,CAAC,EAAE,MAAM,CAAA;CAAE,EACjC,MAAM,EAAE,aAAa,GACpB,OAAO,CAAC,UAAU,CAAC,CAWrB"}