freeturtle 0.1.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 (135) hide show
  1. package/LICENSE +190 -0
  2. package/README.md +392 -0
  3. package/dist/bin/freeturtle.d.ts +2 -0
  4. package/dist/bin/freeturtle.js +119 -0
  5. package/dist/bin/freeturtle.js.map +1 -0
  6. package/dist/src/approval.d.ts +38 -0
  7. package/dist/src/approval.js +140 -0
  8. package/dist/src/approval.js.map +1 -0
  9. package/dist/src/audit.d.ts +33 -0
  10. package/dist/src/audit.js +36 -0
  11. package/dist/src/audit.js.map +1 -0
  12. package/dist/src/channels/telegram.d.ts +10 -0
  13. package/dist/src/channels/telegram.js +41 -0
  14. package/dist/src/channels/telegram.js.map +1 -0
  15. package/dist/src/channels/terminal.d.ts +9 -0
  16. package/dist/src/channels/terminal.js +52 -0
  17. package/dist/src/channels/terminal.js.map +1 -0
  18. package/dist/src/channels/types.d.ts +6 -0
  19. package/dist/src/channels/types.js +2 -0
  20. package/dist/src/channels/types.js.map +1 -0
  21. package/dist/src/cli/approvals.d.ts +3 -0
  22. package/dist/src/cli/approvals.js +33 -0
  23. package/dist/src/cli/approvals.js.map +1 -0
  24. package/dist/src/cli/connect-farcaster.d.ts +5 -0
  25. package/dist/src/cli/connect-farcaster.js +265 -0
  26. package/dist/src/cli/connect-farcaster.js.map +1 -0
  27. package/dist/src/cli/connection-tests.d.ts +16 -0
  28. package/dist/src/cli/connection-tests.js +65 -0
  29. package/dist/src/cli/connection-tests.js.map +1 -0
  30. package/dist/src/cli/init.d.ts +1 -0
  31. package/dist/src/cli/init.js +729 -0
  32. package/dist/src/cli/init.js.map +1 -0
  33. package/dist/src/cli/install-service.d.ts +1 -0
  34. package/dist/src/cli/install-service.js +57 -0
  35. package/dist/src/cli/install-service.js.map +1 -0
  36. package/dist/src/cli/intake.d.ts +23 -0
  37. package/dist/src/cli/intake.js +68 -0
  38. package/dist/src/cli/intake.js.map +1 -0
  39. package/dist/src/cli/send.d.ts +1 -0
  40. package/dist/src/cli/send.js +16 -0
  41. package/dist/src/cli/send.js.map +1 -0
  42. package/dist/src/cli/start.d.ts +3 -0
  43. package/dist/src/cli/start.js +25 -0
  44. package/dist/src/cli/start.js.map +1 -0
  45. package/dist/src/cli/status.d.ts +2 -0
  46. package/dist/src/cli/status.js +54 -0
  47. package/dist/src/cli/status.js.map +1 -0
  48. package/dist/src/cli/update.d.ts +1 -0
  49. package/dist/src/cli/update.js +39 -0
  50. package/dist/src/cli/update.js.map +1 -0
  51. package/dist/src/config.d.ts +31 -0
  52. package/dist/src/config.js +93 -0
  53. package/dist/src/config.js.map +1 -0
  54. package/dist/src/daemon.d.ts +18 -0
  55. package/dist/src/daemon.js +272 -0
  56. package/dist/src/daemon.js.map +1 -0
  57. package/dist/src/heartbeat.d.ts +17 -0
  58. package/dist/src/heartbeat.js +60 -0
  59. package/dist/src/heartbeat.js.map +1 -0
  60. package/dist/src/llm.d.ts +29 -0
  61. package/dist/src/llm.js +225 -0
  62. package/dist/src/llm.js.map +1 -0
  63. package/dist/src/logger.d.ts +8 -0
  64. package/dist/src/logger.js +45 -0
  65. package/dist/src/logger.js.map +1 -0
  66. package/dist/src/memory.d.ts +3 -0
  67. package/dist/src/memory.js +36 -0
  68. package/dist/src/memory.js.map +1 -0
  69. package/dist/src/modules/database/client.d.ts +18 -0
  70. package/dist/src/modules/database/client.js +50 -0
  71. package/dist/src/modules/database/client.js.map +1 -0
  72. package/dist/src/modules/database/index.d.ts +9 -0
  73. package/dist/src/modules/database/index.js +32 -0
  74. package/dist/src/modules/database/index.js.map +1 -0
  75. package/dist/src/modules/database/tools.d.ts +2 -0
  76. package/dist/src/modules/database/tools.js +26 -0
  77. package/dist/src/modules/database/tools.js.map +1 -0
  78. package/dist/src/modules/farcaster/client.d.ts +43 -0
  79. package/dist/src/modules/farcaster/client.js +87 -0
  80. package/dist/src/modules/farcaster/client.js.map +1 -0
  81. package/dist/src/modules/farcaster/index.d.ts +14 -0
  82. package/dist/src/modules/farcaster/index.js +71 -0
  83. package/dist/src/modules/farcaster/index.js.map +1 -0
  84. package/dist/src/modules/farcaster/tools.d.ts +2 -0
  85. package/dist/src/modules/farcaster/tools.js +90 -0
  86. package/dist/src/modules/farcaster/tools.js.map +1 -0
  87. package/dist/src/modules/github/client.d.ts +21 -0
  88. package/dist/src/modules/github/client.js +80 -0
  89. package/dist/src/modules/github/client.js.map +1 -0
  90. package/dist/src/modules/github/index.d.ts +13 -0
  91. package/dist/src/modules/github/index.js +45 -0
  92. package/dist/src/modules/github/index.js.map +1 -0
  93. package/dist/src/modules/github/tools.d.ts +2 -0
  94. package/dist/src/modules/github/tools.js +74 -0
  95. package/dist/src/modules/github/tools.js.map +1 -0
  96. package/dist/src/modules/loader.d.ts +5 -0
  97. package/dist/src/modules/loader.js +35 -0
  98. package/dist/src/modules/loader.js.map +1 -0
  99. package/dist/src/modules/onchain/client.d.ts +8 -0
  100. package/dist/src/modules/onchain/client.js +46 -0
  101. package/dist/src/modules/onchain/client.js.map +1 -0
  102. package/dist/src/modules/onchain/index.d.ts +13 -0
  103. package/dist/src/modules/onchain/index.js +40 -0
  104. package/dist/src/modules/onchain/index.js.map +1 -0
  105. package/dist/src/modules/onchain/tools.d.ts +2 -0
  106. package/dist/src/modules/onchain/tools.js +61 -0
  107. package/dist/src/modules/onchain/tools.js.map +1 -0
  108. package/dist/src/modules/types.d.ts +24 -0
  109. package/dist/src/modules/types.js +2 -0
  110. package/dist/src/modules/types.js.map +1 -0
  111. package/dist/src/modules/xmtp/index.d.ts +8 -0
  112. package/dist/src/modules/xmtp/index.js +14 -0
  113. package/dist/src/modules/xmtp/index.js.map +1 -0
  114. package/dist/src/policy.d.ts +45 -0
  115. package/dist/src/policy.js +164 -0
  116. package/dist/src/policy.js.map +1 -0
  117. package/dist/src/redaction.d.ts +13 -0
  118. package/dist/src/redaction.js +75 -0
  119. package/dist/src/redaction.js.map +1 -0
  120. package/dist/src/reliability.d.ts +16 -0
  121. package/dist/src/reliability.js +124 -0
  122. package/dist/src/reliability.js.map +1 -0
  123. package/dist/src/runner.d.ts +37 -0
  124. package/dist/src/runner.js +257 -0
  125. package/dist/src/runner.js.map +1 -0
  126. package/dist/src/scheduler.d.ts +22 -0
  127. package/dist/src/scheduler.js +61 -0
  128. package/dist/src/scheduler.js.map +1 -0
  129. package/dist/src/setup.d.ts +8 -0
  130. package/dist/src/setup.js +179 -0
  131. package/dist/src/setup.js.map +1 -0
  132. package/dist/src/soul.d.ts +1 -0
  133. package/dist/src/soul.js +15 -0
  134. package/dist/src/soul.js.map +1 -0
  135. package/package.json +56 -0
@@ -0,0 +1,45 @@
1
+ import { appendFile, mkdir } from "node:fs/promises";
2
+ import { join } from "node:path";
3
+ import { tmpdir } from "node:os";
4
+ const LEVEL_ORDER = ["debug", "info", "warn", "error"];
5
+ export function createLogger(dir) {
6
+ const logDir = join(tmpdir(), "freeturtle");
7
+ const logPath = dir ? join(logDir, "freeturtle.log") : null;
8
+ let logFileReady = false;
9
+ function formatLine(level, msg) {
10
+ const ts = new Date().toISOString();
11
+ return `[${ts}] [${level.toUpperCase()}] ${msg}`;
12
+ }
13
+ async function writeToFile(line) {
14
+ if (!logPath)
15
+ return;
16
+ if (!logFileReady) {
17
+ await mkdir(logDir, { recursive: true });
18
+ logFileReady = true;
19
+ }
20
+ await appendFile(logPath, line + "\n", "utf-8");
21
+ }
22
+ function log(level, msg) {
23
+ const minLevel = "debug";
24
+ if (LEVEL_ORDER.indexOf(level) < LEVEL_ORDER.indexOf(minLevel))
25
+ return;
26
+ const line = formatLine(level, msg);
27
+ // Only print errors/warnings to stderr; all else goes to log file only
28
+ if (level === "error") {
29
+ console.error(line);
30
+ }
31
+ else if (level === "warn") {
32
+ console.warn(line);
33
+ }
34
+ writeToFile(line).catch(() => {
35
+ // Silently ignore log file write failures
36
+ });
37
+ }
38
+ return {
39
+ debug: (msg) => log("debug", msg),
40
+ info: (msg) => log("info", msg),
41
+ warn: (msg) => log("warn", msg),
42
+ error: (msg) => log("error", msg),
43
+ };
44
+ }
45
+ //# sourceMappingURL=logger.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"logger.js","sourceRoot":"","sources":["../../src/logger.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,KAAK,EAAE,MAAM,kBAAkB,CAAC;AACrD,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,MAAM,EAAE,MAAM,SAAS,CAAC;AAWjC,MAAM,WAAW,GAAe,CAAC,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,CAAC,CAAC;AAEnE,MAAM,UAAU,YAAY,CAAC,GAAY;IACvC,MAAM,MAAM,GAAG,IAAI,CAAC,MAAM,EAAE,EAAE,YAAY,CAAC,CAAC;IAC5C,MAAM,OAAO,GAAG,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,EAAE,gBAAgB,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;IAC5D,IAAI,YAAY,GAAG,KAAK,CAAC;IAEzB,SAAS,UAAU,CAAC,KAAe,EAAE,GAAW;QAC9C,MAAM,EAAE,GAAG,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;QACpC,OAAO,IAAI,EAAE,MAAM,KAAK,CAAC,WAAW,EAAE,KAAK,GAAG,EAAE,CAAC;IACnD,CAAC;IAED,KAAK,UAAU,WAAW,CAAC,IAAY;QACrC,IAAI,CAAC,OAAO;YAAE,OAAO;QACrB,IAAI,CAAC,YAAY,EAAE,CAAC;YAClB,MAAM,KAAK,CAAC,MAAM,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;YACzC,YAAY,GAAG,IAAI,CAAC;QACtB,CAAC;QACD,MAAM,UAAU,CAAC,OAAO,EAAE,IAAI,GAAG,IAAI,EAAE,OAAO,CAAC,CAAC;IAClD,CAAC;IAED,SAAS,GAAG,CAAC,KAAe,EAAE,GAAW;QACvC,MAAM,QAAQ,GAAa,OAAO,CAAC;QACnC,IAAI,WAAW,CAAC,OAAO,CAAC,KAAK,CAAC,GAAG,WAAW,CAAC,OAAO,CAAC,QAAQ,CAAC;YAAE,OAAO;QAEvE,MAAM,IAAI,GAAG,UAAU,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC;QAEpC,uEAAuE;QACvE,IAAI,KAAK,KAAK,OAAO,EAAE,CAAC;YACtB,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;QACtB,CAAC;aAAM,IAAI,KAAK,KAAK,MAAM,EAAE,CAAC;YAC5B,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACrB,CAAC;QAED,WAAW,CAAC,IAAI,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE;YAC3B,0CAA0C;QAC5C,CAAC,CAAC,CAAC;IACL,CAAC;IAED,OAAO;QACL,KAAK,EAAE,CAAC,GAAW,EAAE,EAAE,CAAC,GAAG,CAAC,OAAO,EAAE,GAAG,CAAC;QACzC,IAAI,EAAE,CAAC,GAAW,EAAE,EAAE,CAAC,GAAG,CAAC,MAAM,EAAE,GAAG,CAAC;QACvC,IAAI,EAAE,CAAC,GAAW,EAAE,EAAE,CAAC,GAAG,CAAC,MAAM,EAAE,GAAG,CAAC;QACvC,KAAK,EAAE,CAAC,GAAW,EAAE,EAAE,CAAC,GAAG,CAAC,OAAO,EAAE,GAAG,CAAC;KAC1C,CAAC;AACJ,CAAC"}
@@ -0,0 +1,3 @@
1
+ export declare function readMemoryFile(dir: string, filename: string): Promise<string | null>;
2
+ export declare function writeMemoryFile(dir: string, filename: string, content: string): Promise<void>;
3
+ export declare function appendToJsonArray(dir: string, filename: string, entry: unknown): Promise<void>;
@@ -0,0 +1,36 @@
1
+ import { readFile, writeFile, mkdir } from "node:fs/promises";
2
+ import { join, dirname } from "node:path";
3
+ function memoryPath(dir, filename) {
4
+ return join(dir, "workspace", "memory", filename);
5
+ }
6
+ export async function readMemoryFile(dir, filename) {
7
+ try {
8
+ return await readFile(memoryPath(dir, filename), "utf-8");
9
+ }
10
+ catch (err) {
11
+ if (err instanceof Error && "code" in err && err.code === "ENOENT") {
12
+ return null;
13
+ }
14
+ throw err;
15
+ }
16
+ }
17
+ export async function writeMemoryFile(dir, filename, content) {
18
+ const filePath = memoryPath(dir, filename);
19
+ await mkdir(dirname(filePath), { recursive: true });
20
+ await writeFile(filePath, content, "utf-8");
21
+ }
22
+ export async function appendToJsonArray(dir, filename, entry) {
23
+ const existing = await readMemoryFile(dir, filename);
24
+ let arr;
25
+ try {
26
+ arr = existing ? JSON.parse(existing) : [];
27
+ }
28
+ catch {
29
+ arr = [];
30
+ }
31
+ if (!Array.isArray(arr))
32
+ arr = [];
33
+ arr.push(entry);
34
+ await writeMemoryFile(dir, filename, JSON.stringify(arr, null, 2));
35
+ }
36
+ //# sourceMappingURL=memory.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"memory.js","sourceRoot":"","sources":["../../src/memory.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,SAAS,EAAE,KAAK,EAAE,MAAM,kBAAkB,CAAC;AAC9D,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAE1C,SAAS,UAAU,CAAC,GAAW,EAAE,QAAgB;IAC/C,OAAO,IAAI,CAAC,GAAG,EAAE,WAAW,EAAE,QAAQ,EAAE,QAAQ,CAAC,CAAC;AACpD,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,cAAc,CAAC,GAAW,EAAE,QAAgB;IAChE,IAAI,CAAC;QACH,OAAO,MAAM,QAAQ,CAAC,UAAU,CAAC,GAAG,EAAE,QAAQ,CAAC,EAAE,OAAO,CAAC,CAAC;IAC5D,CAAC;IAAC,OAAO,GAAY,EAAE,CAAC;QACtB,IAAI,GAAG,YAAY,KAAK,IAAI,MAAM,IAAI,GAAG,IAAK,GAA6B,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;YAC9F,OAAO,IAAI,CAAC;QACd,CAAC;QACD,MAAM,GAAG,CAAC;IACZ,CAAC;AACH,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,eAAe,CAAC,GAAW,EAAE,QAAgB,EAAE,OAAe;IAClF,MAAM,QAAQ,GAAG,UAAU,CAAC,GAAG,EAAE,QAAQ,CAAC,CAAC;IAC3C,MAAM,KAAK,CAAC,OAAO,CAAC,QAAQ,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IACpD,MAAM,SAAS,CAAC,QAAQ,EAAE,OAAO,EAAE,OAAO,CAAC,CAAC;AAC9C,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,iBAAiB,CAAC,GAAW,EAAE,QAAgB,EAAE,KAAc;IACnF,MAAM,QAAQ,GAAG,MAAM,cAAc,CAAC,GAAG,EAAE,QAAQ,CAAC,CAAC;IACrD,IAAI,GAAc,CAAC;IACnB,IAAI,CAAC;QACH,GAAG,GAAG,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;IAC7C,CAAC;IAAC,MAAM,CAAC;QACP,GAAG,GAAG,EAAE,CAAC;IACX,CAAC;IACD,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC;QAAE,GAAG,GAAG,EAAE,CAAC;IAClC,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IAChB,MAAM,eAAe,CAAC,GAAG,EAAE,QAAQ,EAAE,IAAI,CAAC,SAAS,CAAC,GAAG,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;AACrE,CAAC"}
@@ -0,0 +1,18 @@
1
+ export interface QueryResult {
2
+ rows: Record<string, unknown>[];
3
+ rowCount: number;
4
+ }
5
+ export interface TableInfo {
6
+ table_name: string;
7
+ columns: {
8
+ name: string;
9
+ type: string;
10
+ }[];
11
+ }
12
+ export declare class DatabaseClient {
13
+ private pool;
14
+ constructor(connectionString: string);
15
+ query(sql: string): Promise<QueryResult>;
16
+ listTables(): Promise<TableInfo[]>;
17
+ close(): Promise<void>;
18
+ }
@@ -0,0 +1,50 @@
1
+ import pg from "pg";
2
+ export class DatabaseClient {
3
+ pool;
4
+ constructor(connectionString) {
5
+ this.pool = new pg.Pool({ connectionString });
6
+ }
7
+ async query(sql) {
8
+ const client = await this.pool.connect();
9
+ try {
10
+ await client.query("BEGIN TRANSACTION READ ONLY");
11
+ const result = await client.query(sql);
12
+ await client.query("COMMIT");
13
+ return {
14
+ rows: result.rows,
15
+ rowCount: result.rowCount ?? 0,
16
+ };
17
+ }
18
+ catch (err) {
19
+ await client.query("ROLLBACK");
20
+ throw err;
21
+ }
22
+ finally {
23
+ client.release();
24
+ }
25
+ }
26
+ async listTables() {
27
+ const tablesResult = await this.query(`SELECT table_name FROM information_schema.tables
28
+ WHERE table_schema = 'public'
29
+ ORDER BY table_name`);
30
+ const tables = [];
31
+ for (const row of tablesResult.rows) {
32
+ const tableName = row.table_name;
33
+ const colsResult = await this.query(`SELECT column_name, data_type FROM information_schema.columns
34
+ WHERE table_schema = 'public' AND table_name = '${tableName.replace(/'/g, "''")}'
35
+ ORDER BY ordinal_position`);
36
+ tables.push({
37
+ table_name: tableName,
38
+ columns: colsResult.rows.map((c) => ({
39
+ name: c.column_name,
40
+ type: c.data_type,
41
+ })),
42
+ });
43
+ }
44
+ return tables;
45
+ }
46
+ async close() {
47
+ await this.pool.end();
48
+ }
49
+ }
50
+ //# sourceMappingURL=client.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"client.js","sourceRoot":"","sources":["../../../../src/modules/database/client.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,IAAI,CAAC;AAYpB,MAAM,OAAO,cAAc;IACjB,IAAI,CAAU;IAEtB,YAAY,gBAAwB;QAClC,IAAI,CAAC,IAAI,GAAG,IAAI,EAAE,CAAC,IAAI,CAAC,EAAE,gBAAgB,EAAE,CAAC,CAAC;IAChD,CAAC;IAED,KAAK,CAAC,KAAK,CAAC,GAAW;QACrB,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC;QACzC,IAAI,CAAC;YACH,MAAM,MAAM,CAAC,KAAK,CAAC,6BAA6B,CAAC,CAAC;YAClD,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;YACvC,MAAM,MAAM,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC;YAC7B,OAAO;gBACL,IAAI,EAAE,MAAM,CAAC,IAAiC;gBAC9C,QAAQ,EAAE,MAAM,CAAC,QAAQ,IAAI,CAAC;aAC/B,CAAC;QACJ,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,MAAM,MAAM,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC;YAC/B,MAAM,GAAG,CAAC;QACZ,CAAC;gBAAS,CAAC;YACT,MAAM,CAAC,OAAO,EAAE,CAAC;QACnB,CAAC;IACH,CAAC;IAED,KAAK,CAAC,UAAU;QACd,MAAM,YAAY,GAAG,MAAM,IAAI,CAAC,KAAK,CACnC;;2BAEqB,CACtB,CAAC;QAEF,MAAM,MAAM,GAAgB,EAAE,CAAC;QAC/B,KAAK,MAAM,GAAG,IAAI,YAAY,CAAC,IAAI,EAAE,CAAC;YACpC,MAAM,SAAS,GAAG,GAAG,CAAC,UAAoB,CAAC;YAC3C,MAAM,UAAU,GAAG,MAAM,IAAI,CAAC,KAAK,CACjC;2DACmD,SAAS,CAAC,OAAO,CAAC,IAAI,EAAE,IAAI,CAAC;mCACrD,CAC5B,CAAC;YACF,MAAM,CAAC,IAAI,CAAC;gBACV,UAAU,EAAE,SAAS;gBACrB,OAAO,EAAE,UAAU,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;oBACnC,IAAI,EAAE,CAAC,CAAC,WAAqB;oBAC7B,IAAI,EAAE,CAAC,CAAC,SAAmB;iBAC5B,CAAC,CAAC;aACJ,CAAC,CAAC;QACL,CAAC;QAED,OAAO,MAAM,CAAC;IAChB,CAAC;IAED,KAAK,CAAC,KAAK;QACT,MAAM,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC;IACxB,CAAC;CACF"}
@@ -0,0 +1,9 @@
1
+ import type { FreeTurtleModule, ToolDefinition } from "../types.js";
2
+ export declare class DatabaseModule implements FreeTurtleModule {
3
+ name: string;
4
+ description: string;
5
+ private client;
6
+ initialize(_config: Record<string, unknown>, env: Record<string, string>): Promise<void>;
7
+ getTools(): ToolDefinition[];
8
+ executeTool(name: string, input: Record<string, unknown>): Promise<string>;
9
+ }
@@ -0,0 +1,32 @@
1
+ import { withRetry } from "../../reliability.js";
2
+ import { DatabaseClient } from "./client.js";
3
+ import { databaseTools } from "./tools.js";
4
+ export class DatabaseModule {
5
+ name = "database";
6
+ description = "Query a PostgreSQL database (read-only).";
7
+ client;
8
+ async initialize(_config, env) {
9
+ const url = env.DATABASE_URL;
10
+ if (!url)
11
+ throw new Error("Database module requires DATABASE_URL");
12
+ this.client = new DatabaseClient(url);
13
+ }
14
+ getTools() {
15
+ return databaseTools;
16
+ }
17
+ async executeTool(name, input) {
18
+ switch (name) {
19
+ case "query_database": {
20
+ const result = await withRetry(() => this.client.query(input.sql));
21
+ return JSON.stringify({ rowCount: result.rowCount, rows: result.rows });
22
+ }
23
+ case "list_tables": {
24
+ const tables = await withRetry(() => this.client.listTables());
25
+ return JSON.stringify(tables);
26
+ }
27
+ default:
28
+ throw new Error(`Unknown database tool: ${name}`);
29
+ }
30
+ }
31
+ }
32
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../src/modules/database/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,SAAS,EAAE,MAAM,sBAAsB,CAAC;AACjD,OAAO,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAC7C,OAAO,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAE3C,MAAM,OAAO,cAAc;IACzB,IAAI,GAAG,UAAU,CAAC;IAClB,WAAW,GAAG,0CAA0C,CAAC;IAEjD,MAAM,CAAkB;IAEhC,KAAK,CAAC,UAAU,CACd,OAAgC,EAChC,GAA2B;QAE3B,MAAM,GAAG,GAAG,GAAG,CAAC,YAAY,CAAC;QAC7B,IAAI,CAAC,GAAG;YAAE,MAAM,IAAI,KAAK,CAAC,uCAAuC,CAAC,CAAC;QACnE,IAAI,CAAC,MAAM,GAAG,IAAI,cAAc,CAAC,GAAG,CAAC,CAAC;IACxC,CAAC;IAED,QAAQ;QACN,OAAO,aAAa,CAAC;IACvB,CAAC;IAED,KAAK,CAAC,WAAW,CACf,IAAY,EACZ,KAA8B;QAE9B,QAAQ,IAAI,EAAE,CAAC;YACb,KAAK,gBAAgB,CAAC,CAAC,CAAC;gBACtB,MAAM,MAAM,GAAG,MAAM,SAAS,CAAC,GAAG,EAAE,CAClC,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,GAAa,CAAC,CACvC,CAAC;gBACF,OAAO,IAAI,CAAC,SAAS,CAAC,EAAE,QAAQ,EAAE,MAAM,CAAC,QAAQ,EAAE,IAAI,EAAE,MAAM,CAAC,IAAI,EAAE,CAAC,CAAC;YAC1E,CAAC;YACD,KAAK,aAAa,CAAC,CAAC,CAAC;gBACnB,MAAM,MAAM,GAAG,MAAM,SAAS,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,MAAM,CAAC,UAAU,EAAE,CAAC,CAAC;gBAC/D,OAAO,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC;YAChC,CAAC;YACD;gBACE,MAAM,IAAI,KAAK,CAAC,0BAA0B,IAAI,EAAE,CAAC,CAAC;QACtD,CAAC;IACH,CAAC;CACF"}
@@ -0,0 +1,2 @@
1
+ import type { ToolDefinition } from "../types.js";
2
+ export declare const databaseTools: ToolDefinition[];
@@ -0,0 +1,26 @@
1
+ export const databaseTools = [
2
+ {
3
+ name: "query_database",
4
+ description: "Execute a read-only SQL query against the connected PostgreSQL database. Returns results as JSON. Only SELECT queries are allowed.",
5
+ input_schema: {
6
+ type: "object",
7
+ properties: {
8
+ sql: {
9
+ type: "string",
10
+ description: "The SQL query to execute (SELECT only)",
11
+ },
12
+ },
13
+ required: ["sql"],
14
+ },
15
+ },
16
+ {
17
+ name: "list_tables",
18
+ description: "List all tables in the database with their column names and types.",
19
+ input_schema: {
20
+ type: "object",
21
+ properties: {},
22
+ required: [],
23
+ },
24
+ },
25
+ ];
26
+ //# sourceMappingURL=tools.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tools.js","sourceRoot":"","sources":["../../../../src/modules/database/tools.ts"],"names":[],"mappings":"AAEA,MAAM,CAAC,MAAM,aAAa,GAAqB;IAC7C;QACE,IAAI,EAAE,gBAAgB;QACtB,WAAW,EACT,oIAAoI;QACtI,YAAY,EAAE;YACZ,IAAI,EAAE,QAAQ;YACd,UAAU,EAAE;gBACV,GAAG,EAAE;oBACH,IAAI,EAAE,QAAQ;oBACd,WAAW,EAAE,wCAAwC;iBACtD;aACF;YACD,QAAQ,EAAE,CAAC,KAAK,CAAC;SAClB;KACF;IACD;QACE,IAAI,EAAE,aAAa;QACnB,WAAW,EACT,oEAAoE;QACtE,YAAY,EAAE;YACZ,IAAI,EAAE,QAAQ;YACd,UAAU,EAAE,EAAE;YACd,QAAQ,EAAE,EAAE;SACb;KACF;CACF,CAAC"}
@@ -0,0 +1,43 @@
1
+ export interface CastResponse {
2
+ success: boolean;
3
+ cast: {
4
+ hash: string;
5
+ author: {
6
+ fid: number;
7
+ };
8
+ text: string;
9
+ };
10
+ }
11
+ export interface Cast {
12
+ hash: string;
13
+ text: string;
14
+ timestamp: string;
15
+ author: {
16
+ fid: number;
17
+ username: string;
18
+ display_name: string;
19
+ };
20
+ reactions: {
21
+ likes_count: number;
22
+ recasts_count: number;
23
+ };
24
+ replies: {
25
+ count: number;
26
+ };
27
+ }
28
+ export declare class NeynarClient {
29
+ private apiKey;
30
+ private signerUuid;
31
+ constructor(apiKey: string, signerUuid: string);
32
+ postCast(text: string, options?: {
33
+ channelId?: string;
34
+ parent?: string;
35
+ embeds?: string[];
36
+ }): Promise<CastResponse>;
37
+ getCasts(channelId: string, limit?: number): Promise<Cast[]>;
38
+ getMentions(fid: number, limit?: number): Promise<Cast[]>;
39
+ replyCast(parentHash: string, text: string): Promise<CastResponse>;
40
+ deleteCast(targetHash: string): Promise<{
41
+ success: boolean;
42
+ }>;
43
+ }
@@ -0,0 +1,87 @@
1
+ const BASE_URL = "https://api.neynar.com/v2/farcaster";
2
+ export class NeynarClient {
3
+ apiKey;
4
+ signerUuid;
5
+ constructor(apiKey, signerUuid) {
6
+ this.apiKey = apiKey;
7
+ this.signerUuid = signerUuid;
8
+ }
9
+ async postCast(text, options) {
10
+ const body = {
11
+ signer_uuid: this.signerUuid,
12
+ text,
13
+ };
14
+ if (options?.channelId)
15
+ body.channel_id = options.channelId;
16
+ if (options?.parent)
17
+ body.parent = options.parent;
18
+ if (options?.embeds) {
19
+ body.embeds = options.embeds.map((url) => ({ url }));
20
+ }
21
+ const res = await fetch(`${BASE_URL}/cast`, {
22
+ method: "POST",
23
+ headers: {
24
+ "Content-Type": "application/json",
25
+ "x-api-key": this.apiKey,
26
+ },
27
+ body: JSON.stringify(body),
28
+ });
29
+ if (!res.ok) {
30
+ const err = await res.text();
31
+ throw new Error(`Neynar postCast failed (${res.status}): ${err}`);
32
+ }
33
+ return (await res.json());
34
+ }
35
+ async getCasts(channelId, limit = 10) {
36
+ const params = new URLSearchParams({
37
+ channel_ids: channelId,
38
+ limit: String(limit),
39
+ });
40
+ const res = await fetch(`${BASE_URL}/feed/channels?${params}`, {
41
+ headers: { "x-api-key": this.apiKey },
42
+ });
43
+ if (!res.ok) {
44
+ const err = await res.text();
45
+ throw new Error(`Neynar getCasts failed (${res.status}): ${err}`);
46
+ }
47
+ const data = (await res.json());
48
+ return data.casts;
49
+ }
50
+ async getMentions(fid, limit = 10) {
51
+ const params = new URLSearchParams({
52
+ fid: String(fid),
53
+ limit: String(limit),
54
+ });
55
+ const res = await fetch(`${BASE_URL}/notifications?${params}`, {
56
+ headers: { "x-api-key": this.apiKey },
57
+ });
58
+ if (!res.ok) {
59
+ const err = await res.text();
60
+ throw new Error(`Neynar getMentions failed (${res.status}): ${err}`);
61
+ }
62
+ const data = (await res.json());
63
+ return data.notifications;
64
+ }
65
+ async replyCast(parentHash, text) {
66
+ return this.postCast(text, { parent: parentHash });
67
+ }
68
+ async deleteCast(targetHash) {
69
+ const res = await fetch(`${BASE_URL}/cast`, {
70
+ method: "DELETE",
71
+ headers: {
72
+ "Content-Type": "application/json",
73
+ "x-api-key": this.apiKey,
74
+ },
75
+ body: JSON.stringify({
76
+ signer_uuid: this.signerUuid,
77
+ target_hash: targetHash,
78
+ }),
79
+ });
80
+ if (!res.ok) {
81
+ const err = await res.text();
82
+ throw new Error(`Neynar deleteCast failed (${res.status}): ${err}`);
83
+ }
84
+ return { success: true };
85
+ }
86
+ }
87
+ //# sourceMappingURL=client.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"client.js","sourceRoot":"","sources":["../../../../src/modules/farcaster/client.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,14 @@
1
+ import type { FreeTurtleModule, ToolDefinition } from "../types.js";
2
+ import type { PolicyConfig } from "../../policy.js";
3
+ export declare class FarcasterModule implements FreeTurtleModule {
4
+ name: string;
5
+ description: string;
6
+ private client;
7
+ private fid;
8
+ private policy?;
9
+ initialize(_config: Record<string, unknown>, env: Record<string, string>, options?: {
10
+ policy?: PolicyConfig;
11
+ }): Promise<void>;
12
+ getTools(): ToolDefinition[];
13
+ executeTool(name: string, input: Record<string, unknown>): Promise<string>;
14
+ }
@@ -0,0 +1,71 @@
1
+ import { assertFarcasterChannelAllowed } from "../../policy.js";
2
+ import { withRetry } from "../../reliability.js";
3
+ import { NeynarClient } from "./client.js";
4
+ import { farcasterTools } from "./tools.js";
5
+ export class FarcasterModule {
6
+ name = "farcaster";
7
+ description = "Post and read casts on Farcaster via the Neynar API.";
8
+ client;
9
+ fid;
10
+ policy;
11
+ async initialize(_config, env, options) {
12
+ const apiKey = env.NEYNAR_API_KEY;
13
+ const signerUuid = env.FARCASTER_SIGNER_UUID;
14
+ const fid = env.FARCASTER_FID;
15
+ if (!apiKey)
16
+ throw new Error("Farcaster module requires NEYNAR_API_KEY");
17
+ if (!signerUuid)
18
+ throw new Error("Farcaster module requires FARCASTER_SIGNER_UUID");
19
+ this.client = new NeynarClient(apiKey, signerUuid);
20
+ this.fid = fid ? parseInt(fid, 10) : 0;
21
+ this.policy = options?.policy;
22
+ }
23
+ getTools() {
24
+ return farcasterTools;
25
+ }
26
+ async executeTool(name, input) {
27
+ // Enforce channel allowlist for channel-scoped operations
28
+ if (input.channel_id) {
29
+ assertFarcasterChannelAllowed(this.policy, input.channel_id);
30
+ }
31
+ switch (name) {
32
+ case "post_cast": {
33
+ const result = await withRetry(() => this.client.postCast(input.text, {
34
+ channelId: input.channel_id,
35
+ embeds: input.embeds,
36
+ }));
37
+ return JSON.stringify(result);
38
+ }
39
+ case "read_channel": {
40
+ const casts = await withRetry(() => this.client.getCasts(input.channel_id, input.limit ?? 10));
41
+ const summary = casts.map((c) => ({
42
+ hash: c.hash,
43
+ author: c.author.display_name || c.author.username,
44
+ text: c.text,
45
+ likes: c.reactions.likes_count,
46
+ recasts: c.reactions.recasts_count,
47
+ replies: c.replies.count,
48
+ timestamp: c.timestamp,
49
+ }));
50
+ return JSON.stringify(summary);
51
+ }
52
+ case "read_mentions": {
53
+ if (!this.fid)
54
+ return "Error: FARCASTER_FID not set, cannot read mentions.";
55
+ const mentions = await withRetry(() => this.client.getMentions(this.fid, input.limit ?? 10));
56
+ return JSON.stringify(mentions);
57
+ }
58
+ case "reply_to_cast": {
59
+ const result = await withRetry(() => this.client.replyCast(input.parent_hash, input.text));
60
+ return JSON.stringify(result);
61
+ }
62
+ case "delete_cast": {
63
+ const result = await withRetry(() => this.client.deleteCast(input.target_hash));
64
+ return JSON.stringify(result);
65
+ }
66
+ default:
67
+ throw new Error(`Unknown farcaster tool: ${name}`);
68
+ }
69
+ }
70
+ }
71
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../src/modules/farcaster/index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ import type { ToolDefinition } from "../types.js";
2
+ export declare const farcasterTools: ToolDefinition[];
@@ -0,0 +1,90 @@
1
+ export const farcasterTools = [
2
+ {
3
+ name: "post_cast",
4
+ description: "Post a cast (message) to Farcaster. Optionally post to a specific channel or include embed URLs.",
5
+ input_schema: {
6
+ type: "object",
7
+ properties: {
8
+ text: {
9
+ type: "string",
10
+ description: "The text content of the cast (max 1024 characters)",
11
+ },
12
+ channel_id: {
13
+ type: "string",
14
+ description: "Optional channel to post to (e.g. 'tortoise')",
15
+ },
16
+ embeds: {
17
+ type: "array",
18
+ items: { type: "string" },
19
+ description: "Optional list of URLs to embed (max 2)",
20
+ },
21
+ },
22
+ required: ["text"],
23
+ },
24
+ },
25
+ {
26
+ name: "read_channel",
27
+ description: "Read recent casts from a Farcaster channel. Returns the latest posts with author, text, reactions, and reply counts.",
28
+ input_schema: {
29
+ type: "object",
30
+ properties: {
31
+ channel_id: {
32
+ type: "string",
33
+ description: "The channel to read from (e.g. 'tortoise')",
34
+ },
35
+ limit: {
36
+ type: "number",
37
+ description: "Number of casts to return (default 10, max 100)",
38
+ },
39
+ },
40
+ required: ["channel_id"],
41
+ },
42
+ },
43
+ {
44
+ name: "read_mentions",
45
+ description: "Read recent notifications and mentions for the CEO's Farcaster account.",
46
+ input_schema: {
47
+ type: "object",
48
+ properties: {
49
+ limit: {
50
+ type: "number",
51
+ description: "Number of mentions to return (default 10, max 100)",
52
+ },
53
+ },
54
+ required: [],
55
+ },
56
+ },
57
+ {
58
+ name: "reply_to_cast",
59
+ description: "Reply to a specific cast on Farcaster by its hash.",
60
+ input_schema: {
61
+ type: "object",
62
+ properties: {
63
+ parent_hash: {
64
+ type: "string",
65
+ description: "The hash of the cast to reply to",
66
+ },
67
+ text: {
68
+ type: "string",
69
+ description: "The text content of the reply",
70
+ },
71
+ },
72
+ required: ["parent_hash", "text"],
73
+ },
74
+ },
75
+ {
76
+ name: "delete_cast",
77
+ description: "Delete a cast by its hash. This action requires founder approval and cannot be undone.",
78
+ input_schema: {
79
+ type: "object",
80
+ properties: {
81
+ target_hash: {
82
+ type: "string",
83
+ description: "The hash of the cast to delete",
84
+ },
85
+ },
86
+ required: ["target_hash"],
87
+ },
88
+ },
89
+ ];
90
+ //# sourceMappingURL=tools.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tools.js","sourceRoot":"","sources":["../../../../src/modules/farcaster/tools.ts"],"names":[],"mappings":"AAEA,MAAM,CAAC,MAAM,cAAc,GAAqB;IAC9C;QACE,IAAI,EAAE,WAAW;QACjB,WAAW,EACT,kGAAkG;QACpG,YAAY,EAAE;YACZ,IAAI,EAAE,QAAQ;YACd,UAAU,EAAE;gBACV,IAAI,EAAE;oBACJ,IAAI,EAAE,QAAQ;oBACd,WAAW,EAAE,oDAAoD;iBAClE;gBACD,UAAU,EAAE;oBACV,IAAI,EAAE,QAAQ;oBACd,WAAW,EAAE,+CAA+C;iBAC7D;gBACD,MAAM,EAAE;oBACN,IAAI,EAAE,OAAO;oBACb,KAAK,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE;oBACzB,WAAW,EAAE,wCAAwC;iBACtD;aACF;YACD,QAAQ,EAAE,CAAC,MAAM,CAAC;SACnB;KACF;IACD;QACE,IAAI,EAAE,cAAc;QACpB,WAAW,EACT,sHAAsH;QACxH,YAAY,EAAE;YACZ,IAAI,EAAE,QAAQ;YACd,UAAU,EAAE;gBACV,UAAU,EAAE;oBACV,IAAI,EAAE,QAAQ;oBACd,WAAW,EAAE,4CAA4C;iBAC1D;gBACD,KAAK,EAAE;oBACL,IAAI,EAAE,QAAQ;oBACd,WAAW,EAAE,iDAAiD;iBAC/D;aACF;YACD,QAAQ,EAAE,CAAC,YAAY,CAAC;SACzB;KACF;IACD;QACE,IAAI,EAAE,eAAe;QACrB,WAAW,EACT,yEAAyE;QAC3E,YAAY,EAAE;YACZ,IAAI,EAAE,QAAQ;YACd,UAAU,EAAE;gBACV,KAAK,EAAE;oBACL,IAAI,EAAE,QAAQ;oBACd,WAAW,EAAE,oDAAoD;iBAClE;aACF;YACD,QAAQ,EAAE,EAAE;SACb;KACF;IACD;QACE,IAAI,EAAE,eAAe;QACrB,WAAW,EACT,oDAAoD;QACtD,YAAY,EAAE;YACZ,IAAI,EAAE,QAAQ;YACd,UAAU,EAAE;gBACV,WAAW,EAAE;oBACX,IAAI,EAAE,QAAQ;oBACd,WAAW,EAAE,kCAAkC;iBAChD;gBACD,IAAI,EAAE;oBACJ,IAAI,EAAE,QAAQ;oBACd,WAAW,EAAE,+BAA+B;iBAC7C;aACF;YACD,QAAQ,EAAE,CAAC,aAAa,EAAE,MAAM,CAAC;SAClC;KACF;IACD;QACE,IAAI,EAAE,aAAa;QACnB,WAAW,EACT,wFAAwF;QAC1F,YAAY,EAAE;YACZ,IAAI,EAAE,QAAQ;YACd,UAAU,EAAE;gBACV,WAAW,EAAE;oBACX,IAAI,EAAE,QAAQ;oBACd,WAAW,EAAE,gCAAgC;iBAC9C;aACF;YACD,QAAQ,EAAE,CAAC,aAAa,CAAC;SAC1B;KACF;CACF,CAAC"}
@@ -0,0 +1,21 @@
1
+ export interface Issue {
2
+ number: number;
3
+ title: string;
4
+ body: string | null;
5
+ state: string;
6
+ html_url: string;
7
+ created_at: string;
8
+ user: string;
9
+ }
10
+ export interface CommitResult {
11
+ sha: string;
12
+ html_url: string;
13
+ }
14
+ export declare class GitHubClient {
15
+ private octokit;
16
+ constructor(token: string);
17
+ private parseRepo;
18
+ createIssue(repo: string, title: string, body: string): Promise<Issue>;
19
+ listIssues(repo: string, state?: "open" | "closed" | "all"): Promise<Issue[]>;
20
+ commitFile(repo: string, path: string, content: string, message: string, branch?: string): Promise<CommitResult>;
21
+ }