beercan 0.1.0 → 0.2.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.
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 +232 -8
  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 +16 -2
  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,256 @@
1
+ import { getConfig } from "../config.js";
2
+ import { SKIPPY_INTENT_PROMPT } from "./skippy.js";
3
+ // ── Intent Parser ──────────────────────────────────────────────
4
+ // Two-tier: slash commands (fast, no LLM) → natural language (Haiku).
5
+ /**
6
+ * Parse user text into a structured ChatIntent.
7
+ * Tier 1 handles slash commands synchronously.
8
+ * Tier 2 uses an LLM call for natural language understanding.
9
+ */
10
+ export async function parseIntent(client, text, ctx, engine) {
11
+ const trimmed = text.trim();
12
+ // ── Tier 1: Slash Commands ─────────────────────────────────
13
+ const slashResult = parseSlashCommand(trimmed);
14
+ if (slashResult)
15
+ return slashResult;
16
+ // ── Tier 2: Natural Language (LLM) ─────────────────────────
17
+ return classifyWithLLM(client, trimmed, ctx, engine);
18
+ }
19
+ // ── Tier 1: Slash Command Parser ─────────────────────────────
20
+ function parseSlashCommand(text) {
21
+ if (!text.startsWith("/"))
22
+ return null;
23
+ const parts = text.split(/\s+/);
24
+ const cmd = parts[0].toLowerCase();
25
+ switch (cmd) {
26
+ case "/status":
27
+ case "/s":
28
+ return { type: "check_status" };
29
+ case "/projects":
30
+ case "/p":
31
+ return { type: "list_projects" };
32
+ case "/history":
33
+ case "/h": {
34
+ const projectSlug = parts[1] || undefined;
35
+ return { type: "bloop_history", projectSlug };
36
+ }
37
+ case "/result":
38
+ case "/r": {
39
+ const bloopId = parts[1];
40
+ if (!bloopId) {
41
+ return { type: "conversation", text: "Usage: /result <bloop-id>" };
42
+ }
43
+ return { type: "bloop_result", bloopId };
44
+ }
45
+ case "/cancel":
46
+ case "/c": {
47
+ const jobId = parts[1];
48
+ if (!jobId) {
49
+ return { type: "conversation", text: "Usage: /cancel <job-id>" };
50
+ }
51
+ return { type: "cancel_job", jobId };
52
+ }
53
+ case "/run": {
54
+ if (parts.length < 3) {
55
+ return { type: "conversation", text: "Usage: /run <project> <goal>" };
56
+ }
57
+ const projectSlug = parts[1];
58
+ const goal = parts.slice(2).join(" ");
59
+ return { type: "run_bloop", projectSlug, goal };
60
+ }
61
+ case "/init": {
62
+ if (parts.length < 2) {
63
+ return { type: "conversation", text: "Usage: /init <name> [work-dir]" };
64
+ }
65
+ const name = parts[1];
66
+ const workDir = parts[2] || undefined;
67
+ return { type: "create_project", name, workDir };
68
+ }
69
+ case "/help":
70
+ case "/?":
71
+ return { type: "help" };
72
+ default:
73
+ // Unknown slash command — fall through to LLM
74
+ return null;
75
+ }
76
+ }
77
+ // ── Tier 2: LLM-based Intent Classification ─────────────────
78
+ const CLASSIFY_INTENT_TOOL = {
79
+ name: "classify_intent",
80
+ description: "Classify the user's chat message into a structured intent for the BeerCan agent system.",
81
+ input_schema: {
82
+ type: "object",
83
+ properties: {
84
+ intent_type: {
85
+ type: "string",
86
+ enum: [
87
+ "run_bloop",
88
+ "check_status",
89
+ "list_projects",
90
+ "bloop_history",
91
+ "bloop_result",
92
+ "cancel_job",
93
+ "create_project",
94
+ "help",
95
+ "conversation",
96
+ ],
97
+ description: "The classified intent type.",
98
+ },
99
+ projectName: {
100
+ type: "string",
101
+ description: "Project name for create_project intents.",
102
+ },
103
+ workDir: {
104
+ type: "string",
105
+ description: "Optional working directory path for create_project intents.",
106
+ },
107
+ projectSlug: {
108
+ type: "string",
109
+ description: "Project slug, required for run_bloop and optional for bloop_history. Use the context project if not specified.",
110
+ },
111
+ goal: {
112
+ type: "string",
113
+ description: "The goal text for run_bloop intents.",
114
+ },
115
+ team: {
116
+ type: "string",
117
+ description: "Optional team preset for run_bloop (auto, solo, code_review, managed, full_team).",
118
+ },
119
+ bloopId: {
120
+ type: "string",
121
+ description: "Bloop ID for bloop_result intents.",
122
+ },
123
+ jobId: {
124
+ type: "string",
125
+ description: "Job ID for cancel_job intents.",
126
+ },
127
+ conversationResponse: {
128
+ type: "string",
129
+ description: "A helpful response to send back for conversation intents.",
130
+ },
131
+ },
132
+ required: ["intent_type"],
133
+ },
134
+ };
135
+ async function classifyWithLLM(client, text, ctx, engine) {
136
+ const config = getConfig();
137
+ const model = config.gatekeeperModel;
138
+ // Gather available projects for context
139
+ const projects = engine.listProjects();
140
+ const projectList = projects.length > 0
141
+ ? projects.map((p) => `- ${p.slug} (${p.name})`).join("\n")
142
+ : "(no projects exist yet)";
143
+ const systemPrompt = [
144
+ SKIPPY_INTENT_PROMPT,
145
+ "",
146
+ "Available projects:",
147
+ projectList,
148
+ "",
149
+ ctx.lastProjectSlug ? `Current context project: ${ctx.lastProjectSlug}` : "No context project set.",
150
+ "",
151
+ "Intent types:",
152
+ "- run_bloop: user wants to run a task/bloop. Requires projectSlug and goal.",
153
+ "- check_status: user wants system status, uptime, stats.",
154
+ "- list_projects: user wants to see all projects.",
155
+ "- bloop_history: user wants to see past bloops, optionally for a specific project.",
156
+ "- bloop_result: user wants details about a specific bloop by ID.",
157
+ "- cancel_job: user wants to cancel a running or pending job.",
158
+ "- create_project: user wants to create a new project. Extract name and optional workDir.",
159
+ "- help: user wants help with commands.",
160
+ "- conversation: anything else — provide a helpful conversationResponse IN SKIPPY'S VOICE.",
161
+ "",
162
+ "If the user asks to run something but does not specify a project, use the context project if available.",
163
+ ].join("\n");
164
+ try {
165
+ const response = await client.messages.create({
166
+ model,
167
+ max_tokens: 512,
168
+ system: systemPrompt,
169
+ tools: [CLASSIFY_INTENT_TOOL],
170
+ tool_choice: { type: "tool", name: "classify_intent" },
171
+ messages: [{ role: "user", content: text }],
172
+ });
173
+ const toolBlock = response.content.find((b) => b.type === "tool_use" && b.name === "classify_intent");
174
+ if (!toolBlock) {
175
+ return { type: "conversation", text: "I'm not sure what you mean. Try /help for available commands." };
176
+ }
177
+ const input = toolBlock.input;
178
+ return toolInputToIntent(input, ctx, projects.length);
179
+ }
180
+ catch (err) {
181
+ // On LLM failure, return a graceful conversation response
182
+ return {
183
+ type: "conversation",
184
+ text: `I had trouble understanding that (${err.message}). Try /help for available commands.`,
185
+ };
186
+ }
187
+ }
188
+ /**
189
+ * Convert the raw LLM tool_use input into a typed ChatIntent.
190
+ */
191
+ function toolInputToIntent(input, ctx, projectCount) {
192
+ const intentType = input.intent_type;
193
+ switch (intentType) {
194
+ case "run_bloop": {
195
+ const projectSlug = input.projectSlug || ctx.lastProjectSlug;
196
+ const goal = input.goal;
197
+ if (!projectSlug || !goal) {
198
+ return {
199
+ type: "conversation",
200
+ text: "I need both a project and a goal to run a bloop. Try: /run <project> <goal>",
201
+ };
202
+ }
203
+ if (projectCount === 0) {
204
+ return {
205
+ type: "conversation",
206
+ text: "No projects yet. Create one with `beercan init <name>` first.",
207
+ };
208
+ }
209
+ return {
210
+ type: "run_bloop",
211
+ projectSlug,
212
+ goal,
213
+ team: input.team || undefined,
214
+ };
215
+ }
216
+ case "check_status":
217
+ return { type: "check_status" };
218
+ case "list_projects":
219
+ return { type: "list_projects" };
220
+ case "bloop_history":
221
+ return {
222
+ type: "bloop_history",
223
+ projectSlug: input.projectSlug || ctx.lastProjectSlug || undefined,
224
+ };
225
+ case "bloop_result": {
226
+ const bloopId = input.bloopId;
227
+ if (!bloopId) {
228
+ return { type: "conversation", text: "I need a bloop ID. Try: /result <bloop-id>" };
229
+ }
230
+ return { type: "bloop_result", bloopId };
231
+ }
232
+ case "cancel_job": {
233
+ const jobId = input.jobId;
234
+ if (!jobId) {
235
+ return { type: "conversation", text: "I need a job ID. Try: /cancel <job-id>" };
236
+ }
237
+ return { type: "cancel_job", jobId };
238
+ }
239
+ case "create_project": {
240
+ const projectName = input.projectName || input.projectSlug;
241
+ if (!projectName) {
242
+ return { type: "conversation", text: "Oh, you want me to create a project but can't even tell me its name? Try: /init <name> [work-dir]" };
243
+ }
244
+ return { type: "create_project", name: projectName, workDir: input.workDir || undefined };
245
+ }
246
+ case "help":
247
+ return { type: "help" };
248
+ case "conversation":
249
+ default:
250
+ return {
251
+ type: "conversation",
252
+ text: input.conversationResponse || "I'm not sure how to help with that. Try /help.",
253
+ };
254
+ }
255
+ }
256
+ //# sourceMappingURL=intent.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"intent.js","sourceRoot":"","sources":["../../src/chat/intent.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,17 @@
1
+ import type { ChatProvider, ChatMessage, SendOpts } from "../types.js";
2
+ export declare class SlackProvider implements ChatProvider {
3
+ private readonly token;
4
+ private readonly signingSecret;
5
+ private readonly appToken?;
6
+ readonly name = "slack";
7
+ private app;
8
+ private handler;
9
+ constructor(token: string, signingSecret: string, appToken?: string | undefined);
10
+ start(): Promise<void>;
11
+ stop(): Promise<void>;
12
+ onMessage(handler: (msg: ChatMessage) => Promise<void>): void;
13
+ sendMessage(channelId: string, text: string, _opts?: SendOpts): Promise<string>;
14
+ editMessage(channelId: string, messageId: string, text: string): Promise<void>;
15
+ sendTypingIndicator(_channelId: string): Promise<void>;
16
+ }
17
+ //# sourceMappingURL=slack.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"slack.d.ts","sourceRoot":"","sources":["../../../src/chat/providers/slack.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,YAAY,EAAE,WAAW,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AAEvE,qBAAa,aAAc,YAAW,YAAY;IAO9C,OAAO,CAAC,QAAQ,CAAC,KAAK;IACtB,OAAO,CAAC,QAAQ,CAAC,aAAa;IAC9B,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAC;IAR5B,QAAQ,CAAC,IAAI,WAAW;IAExB,OAAO,CAAC,GAAG,CAAa;IACxB,OAAO,CAAC,OAAO,CAAsD;gBAGlD,KAAK,EAAE,MAAM,EACb,aAAa,EAAE,MAAM,EACrB,QAAQ,CAAC,EAAE,MAAM,YAAA;IAG9B,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IA+CtB,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;IAO3B,SAAS,CAAC,OAAO,EAAE,CAAC,GAAG,EAAE,WAAW,KAAK,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI;IAIvD,WAAW,CACf,SAAS,EAAE,MAAM,EACjB,IAAI,EAAE,MAAM,EACZ,KAAK,CAAC,EAAE,QAAQ,GACf,OAAO,CAAC,MAAM,CAAC;IAYZ,WAAW,CACf,SAAS,EAAE,MAAM,EACjB,SAAS,EAAE,MAAM,EACjB,IAAI,EAAE,MAAM,GACX,OAAO,CAAC,IAAI,CAAC;IAYV,mBAAmB,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;CAI7D"}
@@ -0,0 +1,90 @@
1
+ import { v4 as uuid } from "uuid";
2
+ export class SlackProvider {
3
+ token;
4
+ signingSecret;
5
+ appToken;
6
+ name = "slack";
7
+ app = null;
8
+ handler = null;
9
+ constructor(token, signingSecret, appToken) {
10
+ this.token = token;
11
+ this.signingSecret = signingSecret;
12
+ this.appToken = appToken;
13
+ }
14
+ async start() {
15
+ let App;
16
+ try {
17
+ // @ts-ignore — @slack/bolt is an optional dependency
18
+ const mod = await import("@slack/bolt");
19
+ App = mod.App;
20
+ }
21
+ catch {
22
+ throw new Error('Slack provider requires the "@slack/bolt" package. Install it with: npm install @slack/bolt');
23
+ }
24
+ this.app = new App({
25
+ token: this.token,
26
+ signingSecret: this.signingSecret,
27
+ socketMode: true,
28
+ appToken: this.appToken,
29
+ });
30
+ this.app.message(async ({ message, say }) => {
31
+ if (!this.handler)
32
+ return;
33
+ if (message.subtype)
34
+ return; // ignore edits, joins, etc.
35
+ const msg = {
36
+ id: uuid(),
37
+ channelId: message.channel,
38
+ userId: message.user,
39
+ text: message.text ?? "",
40
+ timestamp: new Date(Number(message.ts) * 1000).toISOString(),
41
+ metadata: {
42
+ threadTs: message.thread_ts,
43
+ ts: message.ts,
44
+ },
45
+ };
46
+ try {
47
+ await this.handler(msg);
48
+ }
49
+ catch (err) {
50
+ await say(`Error: ${err instanceof Error ? err.message : String(err)}`);
51
+ }
52
+ });
53
+ await this.app.start();
54
+ }
55
+ async stop() {
56
+ if (this.app) {
57
+ await this.app.stop();
58
+ this.app = null;
59
+ }
60
+ }
61
+ onMessage(handler) {
62
+ this.handler = handler;
63
+ }
64
+ async sendMessage(channelId, text, _opts) {
65
+ if (!this.app)
66
+ throw new Error("Slack app not started");
67
+ const result = await this.app.client.chat.postMessage({
68
+ channel: channelId,
69
+ text,
70
+ mrkdwn: true,
71
+ });
72
+ return result.ts;
73
+ }
74
+ async editMessage(channelId, messageId, text) {
75
+ if (!this.app)
76
+ return;
77
+ await this.app.client.chat
78
+ .update({
79
+ channel: channelId,
80
+ ts: messageId,
81
+ text,
82
+ })
83
+ .catch(() => { });
84
+ }
85
+ async sendTypingIndicator(_channelId) {
86
+ // Slack does not expose a direct "typing" indicator API for bots.
87
+ // This is a no-op; responses appear as normal messages.
88
+ }
89
+ }
90
+ //# sourceMappingURL=slack.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"slack.js","sourceRoot":"","sources":["../../../src/chat/providers/slack.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,15 @@
1
+ import type { ChatProvider, ChatMessage, SendOpts } from "../types.js";
2
+ export declare class TelegramProvider implements ChatProvider {
3
+ private readonly token;
4
+ readonly name = "telegram";
5
+ private bot;
6
+ private handler;
7
+ constructor(token: string);
8
+ start(): Promise<void>;
9
+ stop(): Promise<void>;
10
+ onMessage(handler: (msg: ChatMessage) => Promise<void>): void;
11
+ sendMessage(channelId: string, text: string, opts?: SendOpts): Promise<string>;
12
+ editMessage(channelId: string, messageId: string, text: string): Promise<void>;
13
+ sendTypingIndicator(channelId: string): Promise<void>;
14
+ }
15
+ //# sourceMappingURL=telegram.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"telegram.d.ts","sourceRoot":"","sources":["../../../src/chat/providers/telegram.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,YAAY,EAAE,WAAW,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AAEvE,qBAAa,gBAAiB,YAAW,YAAY;IAMvC,OAAO,CAAC,QAAQ,CAAC,KAAK;IALlC,QAAQ,CAAC,IAAI,cAAc;IAE3B,OAAO,CAAC,GAAG,CAAa;IACxB,OAAO,CAAC,OAAO,CAAsD;gBAExC,KAAK,EAAE,MAAM;IAEpC,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IA0CtB,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;IAO3B,SAAS,CAAC,OAAO,EAAE,CAAC,GAAG,EAAE,WAAW,KAAK,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI;IAIvD,WAAW,CACf,SAAS,EAAE,MAAM,EACjB,IAAI,EAAE,MAAM,EACZ,IAAI,CAAC,EAAE,QAAQ,GACd,OAAO,CAAC,MAAM,CAAC;IAcZ,WAAW,CACf,SAAS,EAAE,MAAM,EACjB,SAAS,EAAE,MAAM,EACjB,IAAI,EAAE,MAAM,GACX,OAAO,CAAC,IAAI,CAAC;IAQV,mBAAmB,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;CAO5D"}
@@ -0,0 +1,76 @@
1
+ import { v4 as uuid } from "uuid";
2
+ export class TelegramProvider {
3
+ token;
4
+ name = "telegram";
5
+ bot = null;
6
+ handler = null;
7
+ constructor(token) {
8
+ this.token = token;
9
+ }
10
+ async start() {
11
+ let Telegraf;
12
+ try {
13
+ // @ts-ignore — telegraf is an optional dependency
14
+ const mod = await import("telegraf");
15
+ Telegraf = mod.Telegraf;
16
+ }
17
+ catch {
18
+ throw new Error('Telegram provider requires the "telegraf" package. Install it with: npm install telegraf');
19
+ }
20
+ this.bot = new Telegraf(this.token);
21
+ this.bot.on("text", async (ctx) => {
22
+ if (!this.handler)
23
+ return;
24
+ const msg = {
25
+ id: uuid(),
26
+ channelId: String(ctx.message.chat.id),
27
+ userId: String(ctx.message.from.id),
28
+ text: ctx.message.text,
29
+ timestamp: new Date(ctx.message.date * 1000).toISOString(),
30
+ metadata: {
31
+ username: ctx.message.from.username,
32
+ firstName: ctx.message.from.first_name,
33
+ lastName: ctx.message.from.last_name,
34
+ },
35
+ };
36
+ try {
37
+ await this.handler(msg);
38
+ }
39
+ catch (err) {
40
+ await ctx.reply(`Error: ${err instanceof Error ? err.message : String(err)}`);
41
+ }
42
+ });
43
+ await this.bot.launch();
44
+ }
45
+ async stop() {
46
+ if (this.bot) {
47
+ this.bot.stop("SIGTERM");
48
+ this.bot = null;
49
+ }
50
+ }
51
+ onMessage(handler) {
52
+ this.handler = handler;
53
+ }
54
+ async sendMessage(channelId, text, opts) {
55
+ if (!this.bot)
56
+ throw new Error("Telegram bot not started");
57
+ const extra = opts?.format === "markdown" ? { parse_mode: "MarkdownV2" } : {};
58
+ const result = await this.bot.telegram.sendMessage(channelId, text, extra);
59
+ return String(result.message_id);
60
+ }
61
+ async editMessage(channelId, messageId, text) {
62
+ if (!this.bot)
63
+ return;
64
+ await this.bot.telegram
65
+ .editMessageText(channelId, Number(messageId), undefined, text)
66
+ .catch(() => { });
67
+ }
68
+ async sendTypingIndicator(channelId) {
69
+ if (!this.bot)
70
+ return;
71
+ await this.bot.telegram
72
+ .sendChatAction(channelId, "typing")
73
+ .catch(() => { });
74
+ }
75
+ }
76
+ //# sourceMappingURL=telegram.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"telegram.js","sourceRoot":"","sources":["../../../src/chat/providers/telegram.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,14 @@
1
+ import type { ChatProvider, ChatMessage, SendOpts } from "../types.js";
2
+ export declare class TerminalProvider implements ChatProvider {
3
+ readonly name = "terminal";
4
+ private rl;
5
+ private handler;
6
+ start(): Promise<void>;
7
+ stop(): Promise<void>;
8
+ onMessage(handler: (msg: ChatMessage) => Promise<void>): void;
9
+ sendMessage(_channelId: string, text: string, _opts?: SendOpts): Promise<string>;
10
+ editMessage(_channelId: string, _messageId: string, text: string): Promise<void>;
11
+ sendTypingIndicator(_channelId: string): Promise<void>;
12
+ private showPrompt;
13
+ }
14
+ //# sourceMappingURL=terminal.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"terminal.d.ts","sourceRoot":"","sources":["../../../src/chat/providers/terminal.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,YAAY,EAAE,WAAW,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AAEvE,qBAAa,gBAAiB,YAAW,YAAY;IACnD,QAAQ,CAAC,IAAI,cAAc;IAE3B,OAAO,CAAC,EAAE,CAAmC;IAC7C,OAAO,CAAC,OAAO,CAAsD;IAE/D,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAkDtB,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;IAO3B,SAAS,CAAC,OAAO,EAAE,CAAC,GAAG,EAAE,WAAW,KAAK,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI;IAIvD,WAAW,CACf,UAAU,EAAE,MAAM,EAClB,IAAI,EAAE,MAAM,EACZ,KAAK,CAAC,EAAE,QAAQ,GACf,OAAO,CAAC,MAAM,CAAC;IAKZ,WAAW,CACf,UAAU,EAAE,MAAM,EAClB,UAAU,EAAE,MAAM,EAClB,IAAI,EAAE,MAAM,GACX,OAAO,CAAC,IAAI,CAAC;IAKV,mBAAmB,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAI5D,OAAO,CAAC,UAAU;CAOnB"}
@@ -0,0 +1,77 @@
1
+ import readline from "readline";
2
+ import chalk from "chalk";
3
+ import { v4 as uuid } from "uuid";
4
+ export class TerminalProvider {
5
+ name = "terminal";
6
+ rl = null;
7
+ handler = null;
8
+ async start() {
9
+ this.rl = readline.createInterface({
10
+ input: process.stdin,
11
+ output: process.stdout,
12
+ prompt: chalk.yellow("skippy> "),
13
+ });
14
+ console.log(chalk.bold.yellow("\nšŸŗ Skippy the Magnificent"));
15
+ console.log(chalk.dim(" Elder AI | Beer Can | Your intellectual superior"));
16
+ console.log(chalk.dim(" Type /help if you need hand-holding. Ctrl+C to leave my presence.\n"));
17
+ this.rl.on("line", async (line) => {
18
+ const text = line.trim();
19
+ if (!text) {
20
+ this.showPrompt();
21
+ return;
22
+ }
23
+ if (!this.handler) {
24
+ this.showPrompt();
25
+ return;
26
+ }
27
+ const msg = {
28
+ id: uuid(),
29
+ channelId: "terminal",
30
+ userId: "local",
31
+ text,
32
+ timestamp: new Date().toISOString(),
33
+ };
34
+ try {
35
+ await this.handler(msg);
36
+ }
37
+ catch (err) {
38
+ console.error(chalk.red(`Error: ${err instanceof Error ? err.message : String(err)}`));
39
+ }
40
+ this.showPrompt();
41
+ });
42
+ this.rl.on("close", () => {
43
+ console.log(chalk.dim("\nFine, leave. See if I care. ...I don't."));
44
+ process.exit(0);
45
+ });
46
+ this.showPrompt();
47
+ }
48
+ async stop() {
49
+ if (this.rl) {
50
+ this.rl.close();
51
+ this.rl = null;
52
+ }
53
+ }
54
+ onMessage(handler) {
55
+ this.handler = handler;
56
+ }
57
+ async sendMessage(_channelId, text, _opts) {
58
+ console.log(text);
59
+ return uuid();
60
+ }
61
+ async editMessage(_channelId, _messageId, text) {
62
+ const lastLine = text.split("\n").pop() ?? text;
63
+ process.stdout.write(`\r${lastLine}`);
64
+ }
65
+ async sendTypingIndicator(_channelId) {
66
+ process.stdout.write(chalk.dim("thinking..."));
67
+ }
68
+ showPrompt() {
69
+ if (this.rl) {
70
+ this.rl.prompt();
71
+ }
72
+ else {
73
+ process.stdout.write(chalk.yellow("skippy> "));
74
+ }
75
+ }
76
+ }
77
+ //# sourceMappingURL=terminal.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"terminal.js","sourceRoot":"","sources":["../../../src/chat/providers/terminal.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,16 @@
1
+ import type { ChatProvider, ChatMessage, SendOpts } from "../types.js";
2
+ export declare class WebSocketProvider implements ChatProvider {
3
+ private readonly port;
4
+ readonly name = "websocket";
5
+ private wss;
6
+ private clients;
7
+ private handler;
8
+ constructor(port?: number);
9
+ start(): Promise<void>;
10
+ stop(): Promise<void>;
11
+ onMessage(handler: (msg: ChatMessage) => Promise<void>): void;
12
+ sendMessage(channelId: string, text: string, opts?: SendOpts): Promise<string>;
13
+ editMessage(channelId: string, messageId: string, text: string): Promise<void>;
14
+ sendTypingIndicator(channelId: string): Promise<void>;
15
+ }
16
+ //# sourceMappingURL=websocket.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"websocket.d.ts","sourceRoot":"","sources":["../../../src/chat/providers/websocket.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,YAAY,EAAE,WAAW,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AAEvE,qBAAa,iBAAkB,YAAW,YAAY;IAOxC,OAAO,CAAC,QAAQ,CAAC,IAAI;IANjC,QAAQ,CAAC,IAAI,eAAe;IAE5B,OAAO,CAAC,GAAG,CAAa;IACxB,OAAO,CAAC,OAAO,CAA0B;IACzC,OAAO,CAAC,OAAO,CAAsD;gBAExC,IAAI,GAAE,MAAa;IAE1C,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAyDtB,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;IAc3B,SAAS,CAAC,OAAO,EAAE,CAAC,GAAG,EAAE,WAAW,KAAK,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI;IAIvD,WAAW,CACf,SAAS,EAAE,MAAM,EACjB,IAAI,EAAE,MAAM,EACZ,IAAI,CAAC,EAAE,QAAQ,GACd,OAAO,CAAC,MAAM,CAAC;IAsBZ,WAAW,CACf,SAAS,EAAE,MAAM,EACjB,SAAS,EAAE,MAAM,EACjB,IAAI,EAAE,MAAM,GACX,OAAO,CAAC,IAAI,CAAC;IAiBV,mBAAmB,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;CAY5D"}