freeturtle 0.1.32 → 0.1.34

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.
@@ -15,14 +15,14 @@ const program = new Command();
15
15
  program
16
16
  .name("freeturtle")
17
17
  .description("An open-source framework for deploying autonomous AI CEOs that run onchain businesses.")
18
- .version("0.1.32");
18
+ .version("0.1.34");
19
19
  program
20
20
  .command("hello")
21
21
  .description("Verify the CLI is working")
22
22
  .action(() => {
23
23
  console.log(" \x1b[38;2;94;255;164m _____ ____\x1b[0m");
24
24
  console.log(" \x1b[38;2;94;255;164m/ \\ | o |\x1b[0m");
25
- console.log(" \x1b[38;2;94;255;164m| |/ ___\\|\x1b[0m FreeTurtle v0.1.32");
25
+ console.log(" \x1b[38;2;94;255;164m| |/ ___\\|\x1b[0m FreeTurtle v0.1.34");
26
26
  console.log(" \x1b[38;2;94;255;164m|_________/\x1b[0m");
27
27
  console.log(" \x1b[38;2;94;255;164m|_|_| |_|_|\x1b[0m");
28
28
  });
@@ -156,7 +156,7 @@ program
156
156
  });
157
157
  const connect = program
158
158
  .command("connect")
159
- .description("Connect external services (gmail, telegram, github, farcaster, database, onchain)");
159
+ .description("Connect external services (gmail, telegram, github, farcaster, database, onchain, web-search)");
160
160
  connect
161
161
  .command("gmail")
162
162
  .description("Connect Gmail for reading and sending emails")
@@ -205,6 +205,14 @@ connect
205
205
  const { connectOnchain } = await import("../src/cli/connect-onchain.js");
206
206
  await connectOnchain(opts.dir);
207
207
  });
208
+ connect
209
+ .command("web-search")
210
+ .description("Connect Brave Search API for web research")
211
+ .option("--dir <path>", "Workspace directory", DEFAULT_DIR)
212
+ .action(async (opts) => {
213
+ const { connectWebSearch } = await import("../src/cli/connect-web-search.js");
214
+ await connectWebSearch(opts.dir);
215
+ });
208
216
  program
209
217
  .command("skills")
210
218
  .description("List installed Agent Skills (OpenClaw / ClawHub compatible)")
@@ -1 +1 @@
1
- {"version":3,"file":"freeturtle.js","sourceRoot":"","sources":["../../bin/freeturtle.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"freeturtle.js","sourceRoot":"","sources":["../../bin/freeturtle.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,259 @@
1
+ import { describe, it, expect, beforeEach, afterEach } from "vitest";
2
+ import { TaskRunner } from "./runner.js";
3
+ import { MockLLMClient } from "../test/helpers/mock-llm.js";
4
+ import { createTempWorkspace } from "../test/helpers/temp-workspace.js";
5
+ import { getDefaultPolicy } from "./policy.js";
6
+ import { createLogger } from "./logger.js";
7
+ // Module with a tool that REQUIRES approval (delete_cast)
8
+ class FakeFarcasterModule {
9
+ name = "farcaster";
10
+ description = "Fake farcaster for testing";
11
+ executed = [];
12
+ async initialize() { }
13
+ getTools() {
14
+ return [
15
+ {
16
+ name: "delete_cast",
17
+ description: "Delete a Farcaster cast",
18
+ input_schema: {
19
+ type: "object",
20
+ properties: { hash: { type: "string" } },
21
+ required: ["hash"],
22
+ },
23
+ },
24
+ ];
25
+ }
26
+ async executeTool(name, input) {
27
+ this.executed.push({ name, input });
28
+ return `Deleted cast ${input.hash}`;
29
+ }
30
+ }
31
+ // Module with run_command (does NOT require approval anymore)
32
+ class FakeShellModule {
33
+ name = "shell";
34
+ description = "Fake shell for testing";
35
+ executed = [];
36
+ async initialize() { }
37
+ getTools() {
38
+ return [
39
+ {
40
+ name: "run_command",
41
+ description: "Run a shell command",
42
+ input_schema: {
43
+ type: "object",
44
+ properties: { command: { type: "string" } },
45
+ required: ["command"],
46
+ },
47
+ },
48
+ ];
49
+ }
50
+ async executeTool(name, input) {
51
+ this.executed.push({ name, input });
52
+ return `Command output: executed "${input.command}"`;
53
+ }
54
+ }
55
+ // A module whose tool does NOT require approval
56
+ class FakeWorkspaceModule {
57
+ name = "workspace";
58
+ description = "Fake workspace for testing";
59
+ executed = [];
60
+ async initialize() { }
61
+ getTools() {
62
+ return [
63
+ {
64
+ name: "read_file",
65
+ description: "Read a file",
66
+ input_schema: {
67
+ type: "object",
68
+ properties: { path: { type: "string" } },
69
+ required: ["path"],
70
+ },
71
+ },
72
+ ];
73
+ }
74
+ async executeTool(name, input) {
75
+ this.executed.push({ name, input });
76
+ return `File contents of ${input.path}`;
77
+ }
78
+ }
79
+ let workspace;
80
+ let logger;
81
+ beforeEach(async () => {
82
+ workspace = await createTempWorkspace();
83
+ logger = createLogger("test");
84
+ });
85
+ afterEach(async () => {
86
+ await workspace.cleanup();
87
+ });
88
+ describe("Non-blocking approval flow (integration)", () => {
89
+ it("delete_cast requires approval and returns immediately without executing", async () => {
90
+ const llm = new MockLLMClient();
91
+ const farcaster = new FakeFarcasterModule();
92
+ const policy = getDefaultPolicy();
93
+ llm.addToolCall("delete_cast", { hash: "0xabc123" }, "Done.");
94
+ const approvalMessages = [];
95
+ const runner = new TaskRunner(workspace.dir, llm, [farcaster], logger, {
96
+ policy,
97
+ onApprovalNeeded: (msg) => approvalMessages.push(msg),
98
+ onFollowup: () => { },
99
+ });
100
+ await runner.runMessage("delete that cast", "test-channel");
101
+ // CRITICAL: The tool must NOT have been executed — it's behind approval
102
+ expect(farcaster.executed).toHaveLength(0);
103
+ // An approval notification must have been sent to the founder
104
+ expect(approvalMessages).toHaveLength(1);
105
+ expect(approvalMessages[0]).toContain("delete_cast");
106
+ expect(approvalMessages[0]).toMatch(/yes|approve/i);
107
+ // There must be exactly one pending approval request on disk
108
+ const approvalMgr = runner.getApprovalManager();
109
+ const pending = await approvalMgr.list("pending");
110
+ expect(pending).toHaveLength(1);
111
+ expect(pending[0].toolName).toBe("delete_cast");
112
+ expect(pending[0].status).toBe("pending");
113
+ });
114
+ it("after approval is granted, the tool executes and followup is sent", async () => {
115
+ const llm = new MockLLMClient();
116
+ const farcaster = new FakeFarcasterModule();
117
+ const policy = getDefaultPolicy();
118
+ llm.addToolCall("delete_cast", { hash: "0xabc123" }, "Done.");
119
+ const followups = [];
120
+ const runner = new TaskRunner(workspace.dir, llm, [farcaster], logger, {
121
+ policy,
122
+ onApprovalNeeded: () => { },
123
+ onFollowup: (msg) => followups.push(msg),
124
+ });
125
+ // Run the message — returns immediately without executing
126
+ await runner.runMessage("delete that cast", "test-channel");
127
+ expect(farcaster.executed).toHaveLength(0);
128
+ // Now approve the pending request
129
+ const approvalMgr = runner.getApprovalManager();
130
+ const pending = await approvalMgr.list("pending");
131
+ expect(pending).toHaveLength(1);
132
+ await approvalMgr.approve(pending[0].id, "founder");
133
+ // Wait for the fire-and-forget to pick up the approval
134
+ await new Promise((resolve) => setTimeout(resolve, 3000));
135
+ // CRITICAL: The tool must now have been executed exactly once
136
+ expect(farcaster.executed).toHaveLength(1);
137
+ expect(farcaster.executed[0].name).toBe("delete_cast");
138
+ expect(farcaster.executed[0].input.hash).toBe("0xabc123");
139
+ // CRITICAL: A followup message must have been sent with the tool's output
140
+ expect(followups).toHaveLength(1);
141
+ expect(followups[0]).toContain("Deleted cast");
142
+ });
143
+ it("rejected approval sends rejection followup and does NOT execute", async () => {
144
+ const llm = new MockLLMClient();
145
+ const farcaster = new FakeFarcasterModule();
146
+ const policy = getDefaultPolicy();
147
+ llm.addToolCall("delete_cast", { hash: "0xabc123" }, "Done.");
148
+ const followups = [];
149
+ const runner = new TaskRunner(workspace.dir, llm, [farcaster], logger, {
150
+ policy,
151
+ onApprovalNeeded: () => { },
152
+ onFollowup: (msg) => followups.push(msg),
153
+ });
154
+ await runner.runMessage("delete that cast", "test-channel");
155
+ expect(farcaster.executed).toHaveLength(0);
156
+ const approvalMgr = runner.getApprovalManager();
157
+ const pending = await approvalMgr.list("pending");
158
+ expect(pending).toHaveLength(1);
159
+ await approvalMgr.reject(pending[0].id, "Absolutely not");
160
+ await new Promise((resolve) => setTimeout(resolve, 3000));
161
+ // CRITICAL: Tool must NOT have executed after rejection
162
+ expect(farcaster.executed).toHaveLength(0);
163
+ // CRITICAL: Followup must mention rejection
164
+ expect(followups).toHaveLength(1);
165
+ expect(followups[0].toLowerCase()).toContain("rejected");
166
+ // The approval record on disk must reflect rejection
167
+ const all = await approvalMgr.list();
168
+ expect(all[0].status).toBe("rejected");
169
+ });
170
+ it("run_command executes immediately without approval", async () => {
171
+ const llm = new MockLLMClient();
172
+ const shell = new FakeShellModule();
173
+ const policy = getDefaultPolicy();
174
+ llm.addToolCall("run_command", { command: "npm install vercel" }, "Done.");
175
+ const approvalMessages = [];
176
+ const runner = new TaskRunner(workspace.dir, llm, [shell], logger, {
177
+ policy,
178
+ onApprovalNeeded: (msg) => approvalMessages.push(msg),
179
+ onFollowup: () => { },
180
+ });
181
+ await runner.runMessage("install vercel", "test-channel");
182
+ // CRITICAL: run_command must execute immediately — no approval
183
+ expect(shell.executed).toHaveLength(1);
184
+ expect(shell.executed[0].name).toBe("run_command");
185
+ expect(shell.executed[0].input.command).toBe("npm install vercel");
186
+ // No approval notifications should have been sent
187
+ expect(approvalMessages).toHaveLength(0);
188
+ // No pending approvals on disk
189
+ const approvalMgr = runner.getApprovalManager();
190
+ const pending = await approvalMgr.list("pending");
191
+ expect(pending).toHaveLength(0);
192
+ });
193
+ it("non-approval tools execute immediately and their result reaches the LLM", async () => {
194
+ const llm = new MockLLMClient();
195
+ const ws = new FakeWorkspaceModule();
196
+ const policy = getDefaultPolicy();
197
+ llm.addToolCall("read_file", { path: "soul.md" }, "Done.");
198
+ const runner = new TaskRunner(workspace.dir, llm, [ws], logger, {
199
+ policy,
200
+ });
201
+ await runner.runMessage("read soul.md", "test-channel");
202
+ // CRITICAL: Tool must have executed immediately (no approval needed)
203
+ expect(ws.executed).toHaveLength(1);
204
+ expect(ws.executed[0].name).toBe("read_file");
205
+ expect(ws.executed[0].input.path).toBe("soul.md");
206
+ // No approval requests should exist
207
+ const approvalMgr = runner.getApprovalManager();
208
+ const pending = await approvalMgr.list("pending");
209
+ expect(pending).toHaveLength(0);
210
+ });
211
+ it("approval-pending tool does not block subsequent messages", async () => {
212
+ const llm = new MockLLMClient();
213
+ const farcaster = new FakeFarcasterModule();
214
+ const ws = new FakeWorkspaceModule();
215
+ const policy = getDefaultPolicy();
216
+ // First message triggers approval (delete_cast)
217
+ llm.addToolCall("delete_cast", { hash: "0xabc" }, "Done.");
218
+ // Second message uses a non-approval tool
219
+ llm.addToolCall("read_file", { path: "config.md" }, "Done.");
220
+ const runner = new TaskRunner(workspace.dir, llm, [farcaster, ws], logger, { policy, onApprovalNeeded: () => { }, onFollowup: () => { } });
221
+ // Record timing — both must complete quickly (not wait for approval)
222
+ const start = Date.now();
223
+ await runner.runMessage("delete that cast", "test-channel");
224
+ await runner.runMessage("read config", "test-channel");
225
+ const elapsed = Date.now() - start;
226
+ // CRITICAL: Both messages must complete in under 5 seconds
227
+ expect(elapsed).toBeLessThan(5000);
228
+ // CRITICAL: read_file must have executed, delete_cast must NOT have
229
+ expect(ws.executed).toHaveLength(1);
230
+ expect(ws.executed[0].name).toBe("read_file");
231
+ expect(farcaster.executed).toHaveLength(0);
232
+ // Exactly one pending approval should exist (for delete_cast)
233
+ const approvalMgr = runner.getApprovalManager();
234
+ const pending = await approvalMgr.list("pending");
235
+ expect(pending).toHaveLength(1);
236
+ expect(pending[0].toolName).toBe("delete_cast");
237
+ });
238
+ it("approval followup contains actual tool output, not a generic message", async () => {
239
+ const llm = new MockLLMClient();
240
+ const farcaster = new FakeFarcasterModule();
241
+ const policy = getDefaultPolicy();
242
+ llm.addToolCall("delete_cast", { hash: "0xdeadbeef" }, "Done.");
243
+ const followups = [];
244
+ const runner = new TaskRunner(workspace.dir, llm, [farcaster], logger, {
245
+ policy,
246
+ onApprovalNeeded: () => { },
247
+ onFollowup: (msg) => followups.push(msg),
248
+ });
249
+ await runner.runMessage("delete cast", "test-channel");
250
+ const approvalMgr = runner.getApprovalManager();
251
+ const pending = await approvalMgr.list("pending");
252
+ await approvalMgr.approve(pending[0].id, "founder");
253
+ await new Promise((resolve) => setTimeout(resolve, 3000));
254
+ // CRITICAL: The followup must contain the actual output from executeTool
255
+ expect(followups).toHaveLength(1);
256
+ expect(followups[0]).toContain("0xdeadbeef");
257
+ });
258
+ });
259
+ //# sourceMappingURL=approval-flow.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"approval-flow.test.js","sourceRoot":"","sources":["../../src/approval-flow.test.ts"],"names":[],"mappings":"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"}
@@ -4,6 +4,8 @@ export declare class TelegramChannel implements Channel {
4
4
  private bot;
5
5
  private ownerId;
6
6
  constructor(token: string, ownerId: number);
7
+ /** Start a typing indicator loop. Returns a stop function. */
8
+ private startTyping;
7
9
  start(onMessage: (text: string, images?: MessageImage[]) => Promise<string>): Promise<void>;
8
10
  send(text: string): Promise<void>;
9
11
  stop(): Promise<void>;
@@ -1,4 +1,6 @@
1
1
  import { Bot } from "grammy";
2
+ const TYPING_INTERVAL_MS = 3_000; // Telegram typing indicator expires after 5s
3
+ const TYPING_TTL_MS = 120_000; // Safety: stop typing after 2 min max
2
4
  export class TelegramChannel {
3
5
  name = "telegram";
4
6
  bot;
@@ -7,6 +9,30 @@ export class TelegramChannel {
7
9
  this.bot = new Bot(token);
8
10
  this.ownerId = ownerId;
9
11
  }
12
+ /** Start a typing indicator loop. Returns a stop function. */
13
+ startTyping(chatId) {
14
+ let stopped = false;
15
+ const sendTyping = () => {
16
+ if (stopped)
17
+ return;
18
+ this.bot.api.sendChatAction(chatId, "typing").catch(() => { });
19
+ };
20
+ // Send immediately, then every 3s
21
+ sendTyping();
22
+ const interval = setInterval(sendTyping, TYPING_INTERVAL_MS);
23
+ // Safety TTL — never type forever
24
+ const ttl = setTimeout(() => {
25
+ stopped = true;
26
+ clearInterval(interval);
27
+ }, TYPING_TTL_MS);
28
+ return () => {
29
+ if (stopped)
30
+ return;
31
+ stopped = true;
32
+ clearInterval(interval);
33
+ clearTimeout(ttl);
34
+ };
35
+ }
10
36
  async start(onMessage) {
11
37
  // Handle photo messages
12
38
  this.bot.on("message:photo", async (ctx) => {
@@ -15,6 +41,7 @@ export class TelegramChannel {
15
41
  await ctx.reply("Sorry, I only talk to my founder.");
16
42
  return;
17
43
  }
44
+ const stopTyping = this.startTyping(ctx.chat.id);
18
45
  try {
19
46
  // Get the largest photo (last in array)
20
47
  const photos = ctx.message.photo;
@@ -40,9 +67,11 @@ export class TelegramChannel {
40
67
  const caption = ctx.message.caption ?? "What's in this image?";
41
68
  const images = [{ data: base64, mediaType }];
42
69
  const response = await onMessage(caption, images);
70
+ stopTyping();
43
71
  await ctx.reply(response);
44
72
  }
45
73
  catch (err) {
74
+ stopTyping();
46
75
  const msg = err instanceof Error ? err.message : "Unknown error";
47
76
  await ctx.reply(`Error: ${msg}`);
48
77
  }
@@ -55,11 +84,14 @@ export class TelegramChannel {
55
84
  return;
56
85
  }
57
86
  const text = ctx.message.text;
87
+ const stopTyping = this.startTyping(ctx.chat.id);
58
88
  try {
59
89
  const response = await onMessage(text);
90
+ stopTyping();
60
91
  await ctx.reply(response);
61
92
  }
62
93
  catch (err) {
94
+ stopTyping();
63
95
  const msg = err instanceof Error ? err.message : "Unknown error";
64
96
  await ctx.reply(`Error: ${msg}`);
65
97
  }
@@ -1 +1 @@
1
- {"version":3,"file":"telegram.js","sourceRoot":"","sources":["../../../src/channels/telegram.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,GAAG,EAAE,MAAM,QAAQ,CAAC;AAG7B,MAAM,OAAO,eAAe;IAC1B,IAAI,GAAG,UAAU,CAAC;IACV,GAAG,CAAM;IACT,OAAO,CAAS;IAExB,YAAY,KAAa,EAAE,OAAe;QACxC,IAAI,CAAC,GAAG,GAAG,IAAI,GAAG,CAAC,KAAK,CAAC,CAAC;QAC1B,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC;IACzB,CAAC;IAED,KAAK,CAAC,KAAK,CAAC,SAAqE;QAC/E,wBAAwB;QACxB,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,eAAe,EAAE,KAAK,EAAE,GAAG,EAAE,EAAE;YACzC,MAAM,QAAQ,GAAG,GAAG,CAAC,IAAI,EAAE,EAAE,CAAC;YAC9B,IAAI,QAAQ,KAAK,IAAI,CAAC,OAAO,EAAE,CAAC;gBAC9B,MAAM,GAAG,CAAC,KAAK,CAAC,mCAAmC,CAAC,CAAC;gBACrD,OAAO;YACT,CAAC;YAED,IAAI,CAAC;gBACH,wCAAwC;gBACxC,MAAM,MAAM,GAAG,GAAG,CAAC,OAAO,CAAC,KAAK,CAAC;gBACjC,MAAM,OAAO,GAAG,MAAM,CAAC,MAAM,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;gBAC1C,MAAM,IAAI,GAAG,MAAM,GAAG,CAAC,GAAG,CAAC,OAAO,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;gBAEpD,gCAAgC;gBAChC,MAAM,GAAG,GAAG,oCAAoC,IAAI,CAAC,GAAG,CAAC,KAAK,IAAI,IAAI,CAAC,SAAS,EAAE,CAAC;gBACnF,MAAM,GAAG,GAAG,MAAM,KAAK,CAAC,GAAG,CAAC,CAAC;gBAC7B,IAAI,CAAC,GAAG,CAAC,EAAE;oBAAE,MAAM,IAAI,KAAK,CAAC,6BAA6B,GAAG,CAAC,MAAM,EAAE,CAAC,CAAC;gBACxE,MAAM,MAAM,GAAG,MAAM,CAAC,IAAI,CAAC,MAAM,GAAG,CAAC,WAAW,EAAE,CAAC,CAAC;gBACpD,MAAM,MAAM,GAAG,MAAM,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC;gBAEzC,2CAA2C;gBAC3C,MAAM,GAAG,GAAG,IAAI,CAAC,SAAS,EAAE,KAAK,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE,WAAW,EAAE,IAAI,KAAK,CAAC;gBACrE,MAAM,OAAO,GAA2B;oBACtC,GAAG,EAAE,YAAY;oBACjB,IAAI,EAAE,YAAY;oBAClB,GAAG,EAAE,WAAW;oBAChB,GAAG,EAAE,WAAW;oBAChB,IAAI,EAAE,YAAY;iBACnB,CAAC;gBACF,MAAM,SAAS,GAAG,OAAO,CAAC,GAAG,CAAC,IAAI,YAAY,CAAC;gBAE/C,MAAM,OAAO,GAAG,GAAG,CAAC,OAAO,CAAC,OAAO,IAAI,uBAAuB,CAAC;gBAC/D,MAAM,MAAM,GAAmB,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,SAAS,EAAE,CAAC,CAAC;gBAE7D,MAAM,QAAQ,GAAG,MAAM,SAAS,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;gBAClD,MAAM,GAAG,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC;YAC5B,CAAC;YAAC,OAAO,GAAG,EAAE,CAAC;gBACb,MAAM,GAAG,GAAG,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,eAAe,CAAC;gBACjE,MAAM,GAAG,CAAC,KAAK,CAAC,UAAU,GAAG,EAAE,CAAC,CAAC;YACnC,CAAC;QACH,CAAC,CAAC,CAAC;QAEH,uBAAuB;QACvB,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,cAAc,EAAE,KAAK,EAAE,GAAG,EAAE,EAAE;YACxC,MAAM,QAAQ,GAAG,GAAG,CAAC,IAAI,EAAE,EAAE,CAAC;YAC9B,IAAI,QAAQ,KAAK,IAAI,CAAC,OAAO,EAAE,CAAC;gBAC9B,MAAM,GAAG,CAAC,KAAK,CAAC,mCAAmC,CAAC,CAAC;gBACrD,OAAO;YACT,CAAC;YAED,MAAM,IAAI,GAAG,GAAG,CAAC,OAAO,CAAC,IAAI,CAAC;YAC9B,IAAI,CAAC;gBACH,MAAM,QAAQ,GAAG,MAAM,SAAS,CAAC,IAAI,CAAC,CAAC;gBACvC,MAAM,GAAG,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC;YAC5B,CAAC;YAAC,OAAO,GAAG,EAAE,CAAC;gBACb,MAAM,GAAG,GAAG,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,eAAe,CAAC;gBACjE,MAAM,GAAG,CAAC,KAAK,CAAC,UAAU,GAAG,EAAE,CAAC,CAAC;YACnC,CAAC;QACH,CAAC,CAAC,CAAC;QAEH,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,GAAG,EAAE,EAAE;YACrB,OAAO,CAAC,KAAK,CAAC,cAAc,GAAG,CAAC,OAAO,EAAE,CAAC,CAAC;QAC7C,CAAC,CAAC,CAAC;QAEH,IAAI,CAAC,GAAG,CAAC,KAAK,EAAE,CAAC,KAAK,CAAC,CAAC,GAAG,EAAE,EAAE;YAC7B,OAAO,CAAC,KAAK,CAAC,+BAA+B,GAAG,CAAC,OAAO,EAAE,CAAC,CAAC;QAC9D,CAAC,CAAC,CAAC;IACL,CAAC;IAED,KAAK,CAAC,IAAI,CAAC,IAAY;QACrB,MAAM,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,WAAW,CAAC,IAAI,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC;IACrD,CAAC;IAED,KAAK,CAAC,IAAI;QACR,MAAM,IAAI,CAAC,GAAG,CAAC,IAAI,EAAE,CAAC;IACxB,CAAC;CACF"}
1
+ {"version":3,"file":"telegram.js","sourceRoot":"","sources":["../../../src/channels/telegram.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,5 @@
1
+ /**
2
+ * Enable a module in config.md. If the module section exists, sets enabled to true.
3
+ * If it doesn't exist, appends it under ## Modules.
4
+ */
5
+ export declare function enableModule(dir: string, moduleName: string): Promise<void>;
@@ -0,0 +1,45 @@
1
+ import { readFile, writeFile } from "node:fs/promises";
2
+ import { join } from "node:path";
3
+ /**
4
+ * Enable a module in config.md. If the module section exists, sets enabled to true.
5
+ * If it doesn't exist, appends it under ## Modules.
6
+ */
7
+ export async function enableModule(dir, moduleName) {
8
+ const configPath = join(dir, "config.md");
9
+ let content;
10
+ try {
11
+ content = await readFile(configPath, "utf-8");
12
+ }
13
+ catch {
14
+ return; // no config.md — nothing to update
15
+ }
16
+ // Check if the module section already exists
17
+ const sectionRegex = new RegExp(`^### ${moduleName}\\s*\\n- enabled:\\s*(true|false)`, "m");
18
+ const match = content.match(sectionRegex);
19
+ if (match) {
20
+ // Update existing section
21
+ content = content.replace(sectionRegex, `### ${moduleName}\n- enabled: true`);
22
+ }
23
+ else {
24
+ // Find the ## Modules section and append
25
+ const modulesIdx = content.indexOf("## Modules");
26
+ if (modulesIdx === -1) {
27
+ // No Modules section — append one
28
+ content += `\n## Modules\n\n### ${moduleName}\n- enabled: true\n`;
29
+ }
30
+ else {
31
+ // Find the next ## section after Modules to insert before it
32
+ const afterModules = content.indexOf("\n## ", modulesIdx + 10);
33
+ const insertion = `\n### ${moduleName}\n- enabled: true\n`;
34
+ if (afterModules === -1) {
35
+ // Modules is the last section
36
+ content += insertion;
37
+ }
38
+ else {
39
+ content = content.slice(0, afterModules) + insertion + content.slice(afterModules);
40
+ }
41
+ }
42
+ }
43
+ await writeFile(configPath, content, "utf-8");
44
+ }
45
+ //# sourceMappingURL=config-utils.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config-utils.js","sourceRoot":"","sources":["../../../src/cli/config-utils.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AACvD,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAEjC;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,YAAY,CAAC,GAAW,EAAE,UAAkB;IAChE,MAAM,UAAU,GAAG,IAAI,CAAC,GAAG,EAAE,WAAW,CAAC,CAAC;IAC1C,IAAI,OAAe,CAAC;IACpB,IAAI,CAAC;QACH,OAAO,GAAG,MAAM,QAAQ,CAAC,UAAU,EAAE,OAAO,CAAC,CAAC;IAChD,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,CAAC,mCAAmC;IAC7C,CAAC;IAED,6CAA6C;IAC7C,MAAM,YAAY,GAAG,IAAI,MAAM,CAAC,QAAQ,UAAU,mCAAmC,EAAE,GAAG,CAAC,CAAC;IAC5F,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC,YAAY,CAAC,CAAC;IAE1C,IAAI,KAAK,EAAE,CAAC;QACV,0BAA0B;QAC1B,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,YAAY,EAAE,OAAO,UAAU,mBAAmB,CAAC,CAAC;IAChF,CAAC;SAAM,CAAC;QACN,yCAAyC;QACzC,MAAM,UAAU,GAAG,OAAO,CAAC,OAAO,CAAC,YAAY,CAAC,CAAC;QACjD,IAAI,UAAU,KAAK,CAAC,CAAC,EAAE,CAAC;YACtB,kCAAkC;YAClC,OAAO,IAAI,uBAAuB,UAAU,qBAAqB,CAAC;QACpE,CAAC;aAAM,CAAC;YACN,6DAA6D;YAC7D,MAAM,YAAY,GAAG,OAAO,CAAC,OAAO,CAAC,OAAO,EAAE,UAAU,GAAG,EAAE,CAAC,CAAC;YAC/D,MAAM,SAAS,GAAG,SAAS,UAAU,qBAAqB,CAAC;YAC3D,IAAI,YAAY,KAAK,CAAC,CAAC,EAAE,CAAC;gBACxB,8BAA8B;gBAC9B,OAAO,IAAI,SAAS,CAAC;YACvB,CAAC;iBAAM,CAAC;gBACN,OAAO,GAAG,OAAO,CAAC,KAAK,CAAC,CAAC,EAAE,YAAY,CAAC,GAAG,SAAS,GAAG,OAAO,CAAC,KAAK,CAAC,YAAY,CAAC,CAAC;YACrF,CAAC;QACH,CAAC;IACH,CAAC;IAED,MAAM,SAAS,CAAC,UAAU,EAAE,OAAO,EAAE,OAAO,CAAC,CAAC;AAChD,CAAC"}
@@ -0,0 +1,3 @@
1
+ export declare function connectWebSearch(dir: string): Promise<null | {
2
+ apiKey: string;
3
+ }>;
@@ -0,0 +1,40 @@
1
+ import * as p from "@clack/prompts";
2
+ import { testBraveSearch } from "./connection-tests.js";
3
+ import { upsertEnv } from "./env-utils.js";
4
+ import { enableModule } from "./config-utils.js";
5
+ export async function connectWebSearch(dir) {
6
+ p.intro("Connect Web Search (Brave)");
7
+ p.note([
8
+ "Get a free API key at:",
9
+ " brave.com/search/api",
10
+ "",
11
+ "The free plan includes 2,000 queries/month.",
12
+ "Your CEO will use this for web research.",
13
+ ].join("\n"), "Brave Search Setup");
14
+ const apiKey = await p.text({
15
+ message: "Brave Search API key:",
16
+ validate: (v) => (!v || v.length < 10 ? "Invalid API key" : undefined),
17
+ });
18
+ if (p.isCancel(apiKey)) {
19
+ p.cancel("Cancelled.");
20
+ return null;
21
+ }
22
+ const s = p.spinner();
23
+ s.start("Testing connection...");
24
+ try {
25
+ await testBraveSearch(apiKey);
26
+ s.stop("Connected!");
27
+ }
28
+ catch (err) {
29
+ s.stop("Connection failed.");
30
+ p.log.error(err instanceof Error ? err.message : String(err));
31
+ return null;
32
+ }
33
+ await upsertEnv(dir, { BRAVE_API_KEY: apiKey });
34
+ await enableModule(dir, "web-search");
35
+ p.log.success("Credentials saved to .env");
36
+ p.log.info("Module enabled in config.md");
37
+ p.outro("Web search connected! Your CEO can now search the web.");
38
+ return { apiKey };
39
+ }
40
+ //# sourceMappingURL=connect-web-search.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"connect-web-search.js","sourceRoot":"","sources":["../../../src/cli/connect-web-search.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,CAAC,MAAM,gBAAgB,CAAC;AACpC,OAAO,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AACxD,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAC3C,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAEjD,MAAM,CAAC,KAAK,UAAU,gBAAgB,CAAC,GAAW;IAChD,CAAC,CAAC,KAAK,CAAC,4BAA4B,CAAC,CAAC;IAEtC,CAAC,CAAC,IAAI,CACJ;QACE,wBAAwB;QACxB,wBAAwB;QACxB,EAAE;QACF,6CAA6C;QAC7C,0CAA0C;KAC3C,CAAC,IAAI,CAAC,IAAI,CAAC,EACZ,oBAAoB,CACrB,CAAC;IAEF,MAAM,MAAM,GAAG,MAAM,CAAC,CAAC,IAAI,CAAC;QAC1B,OAAO,EAAE,uBAAuB;QAChC,QAAQ,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,MAAM,GAAG,EAAE,CAAC,CAAC,CAAC,iBAAiB,CAAC,CAAC,CAAC,SAAS,CAAC;KACvE,CAAC,CAAC;IACH,IAAI,CAAC,CAAC,QAAQ,CAAC,MAAM,CAAC,EAAE,CAAC;QAAC,CAAC,CAAC,MAAM,CAAC,YAAY,CAAC,CAAC;QAAC,OAAO,IAAI,CAAC;IAAC,CAAC;IAEhE,MAAM,CAAC,GAAG,CAAC,CAAC,OAAO,EAAE,CAAC;IACtB,CAAC,CAAC,KAAK,CAAC,uBAAuB,CAAC,CAAC;IACjC,IAAI,CAAC;QACH,MAAM,eAAe,CAAC,MAAM,CAAC,CAAC;QAC9B,CAAC,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;IACvB,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,CAAC,CAAC,IAAI,CAAC,oBAAoB,CAAC,CAAC;QAC7B,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC;QAC9D,OAAO,IAAI,CAAC;IACd,CAAC;IAED,MAAM,SAAS,CAAC,GAAG,EAAE,EAAE,aAAa,EAAE,MAAM,EAAE,CAAC,CAAC;IAChD,MAAM,YAAY,CAAC,GAAG,EAAE,YAAY,CAAC,CAAC;IAEtC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,2BAA2B,CAAC,CAAC;IAC3C,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,6BAA6B,CAAC,CAAC;IAC1C,CAAC,CAAC,KAAK,CAAC,wDAAwD,CAAC,CAAC;IAElE,OAAO,EAAE,MAAM,EAAE,CAAC;AACpB,CAAC"}
@@ -14,6 +14,10 @@ export declare function testDatabase(url: string): Promise<void>;
14
14
  * Test Gmail OAuth credentials by calling the profile endpoint.
15
15
  */
16
16
  export declare function testGmail(clientId: string, clientSecret: string, refreshToken: string): Promise<void>;
17
+ /**
18
+ * Test a Brave Search API key by running a simple query.
19
+ */
20
+ export declare function testBraveSearch(apiKey: string): Promise<void>;
17
21
  /**
18
22
  * Test an EVM RPC URL by calling eth_blockNumber.
19
23
  */
@@ -50,6 +50,21 @@ export async function testGmail(clientId, clientSecret, refreshToken) {
50
50
  const client = new GmailClient(auth);
51
51
  await client.getProfile();
52
52
  }
53
+ /**
54
+ * Test a Brave Search API key by running a simple query.
55
+ */
56
+ export async function testBraveSearch(apiKey) {
57
+ const res = await fetch("https://api.search.brave.com/res/v1/web/search?q=test&count=1", {
58
+ headers: {
59
+ Accept: "application/json",
60
+ "X-Subscription-Token": apiKey,
61
+ },
62
+ });
63
+ if (!res.ok) {
64
+ const body = await res.text();
65
+ throw new Error(`Brave Search API error (${res.status}): ${body}`);
66
+ }
67
+ }
53
68
  /**
54
69
  * Test an EVM RPC URL by calling eth_blockNumber.
55
70
  */
@@ -1 +1 @@
1
- {"version":3,"file":"connection-tests.js","sourceRoot":"","sources":["../../../src/cli/connection-tests.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"connection-tests.js","sourceRoot":"","sources":["../../../src/cli/connection-tests.ts"],"names":[],"mappings":"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"}