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,265 @@
1
+ import * as p from "@clack/prompts";
2
+ import { chmod, mkdir, readFile, writeFile } from "node:fs/promises";
3
+ import { dirname, join } from "node:path";
4
+ import { ViemLocalEip712Signer } from "@farcaster/hub-nodejs";
5
+ import { bytesToHex, hexToBytes } from "viem";
6
+ import { mnemonicToAccount } from "viem/accounts";
7
+ import qrcode from "qrcode-terminal";
8
+ const NEYNAR_BASE = "https://api.neynar.com/v2/farcaster";
9
+ async function neynarPost(path, apiKey, body) {
10
+ const res = await fetch(`${NEYNAR_BASE}${path}`, {
11
+ method: "POST",
12
+ headers: {
13
+ "Content-Type": "application/json",
14
+ "x-api-key": apiKey,
15
+ },
16
+ ...(body ? { body: JSON.stringify(body) } : {}),
17
+ });
18
+ if (!res.ok) {
19
+ const text = await res.text();
20
+ throw new Error(`Neynar API error (${res.status}): ${text}`);
21
+ }
22
+ return res.json();
23
+ }
24
+ async function neynarGet(path, apiKey) {
25
+ const res = await fetch(`${NEYNAR_BASE}${path}`, {
26
+ headers: { "x-api-key": apiKey },
27
+ });
28
+ if (!res.ok) {
29
+ const text = await res.text();
30
+ throw new Error(`Neynar API error (${res.status}): ${text}`);
31
+ }
32
+ return res.json();
33
+ }
34
+ async function lookupFidByCustodyAddress(apiKey, address) {
35
+ const data = (await neynarGet(`/user/custody-address?custody_address=${address}`, apiKey));
36
+ return data.user.fid;
37
+ }
38
+ async function pollSignerStatus(apiKey, signerUuid, maxWaitMs = 180_000) {
39
+ const start = Date.now();
40
+ while (Date.now() - start < maxWaitMs) {
41
+ const data = (await neynarGet(`/signer?signer_uuid=${signerUuid}`, apiKey));
42
+ if (data.status === "approved")
43
+ return data;
44
+ await new Promise((r) => setTimeout(r, 3000));
45
+ }
46
+ throw new Error("Timed out waiting for approval");
47
+ }
48
+ export async function connectFarcaster(dir) {
49
+ p.intro("Connect Farcaster");
50
+ // Load existing .env values
51
+ const envPath = join(dir, ".env");
52
+ const existingEnv = {};
53
+ try {
54
+ const content = await readFile(envPath, "utf-8");
55
+ for (const line of content.split("\n")) {
56
+ const match = line.match(/^([A-Z_]+)=(.+)$/);
57
+ if (match)
58
+ existingEnv[match[1]] = match[2];
59
+ }
60
+ }
61
+ catch {
62
+ // No existing .env
63
+ }
64
+ p.note([
65
+ "You'll need:",
66
+ "",
67
+ " 1. Your Neynar API key (sign up at dev.neynar.com)",
68
+ " 2. The recovery phrase for the Farcaster account",
69
+ " you want to post from",
70
+ " Farcaster app → Settings → Advanced → Recovery phrase",
71
+ "",
72
+ "The recovery phrase is used locally to authorize the signer.",
73
+ "It is never sent to any server.",
74
+ "",
75
+ "After setup, a QR code will appear in your terminal.",
76
+ "Scan it with the Farcaster app to approve.",
77
+ ].join("\n"), "What you'll need");
78
+ let apiKey;
79
+ if (existingEnv.NEYNAR_API_KEY) {
80
+ const reuse = await p.confirm({
81
+ message: `Use existing Neynar API key? (${existingEnv.NEYNAR_API_KEY.slice(0, 8)}...)`,
82
+ initialValue: true,
83
+ });
84
+ if (p.isCancel(reuse)) {
85
+ p.cancel("Cancelled.");
86
+ return null;
87
+ }
88
+ if (reuse) {
89
+ apiKey = existingEnv.NEYNAR_API_KEY;
90
+ }
91
+ else {
92
+ const result = await p.text({
93
+ message: "Neynar API key",
94
+ validate: (v) => (v?.trim() ? undefined : "Required"),
95
+ });
96
+ if (p.isCancel(result)) {
97
+ p.cancel("Cancelled.");
98
+ return null;
99
+ }
100
+ apiKey = result;
101
+ }
102
+ }
103
+ else {
104
+ const result = await p.text({
105
+ message: "Neynar API key",
106
+ validate: (v) => (v?.trim() ? undefined : "Required"),
107
+ });
108
+ if (p.isCancel(result)) {
109
+ p.cancel("Cancelled.");
110
+ return null;
111
+ }
112
+ apiKey = result;
113
+ }
114
+ const mnemonic = await p.text({
115
+ message: "Farcaster recovery phrase (12 words, space-separated)",
116
+ placeholder: "word1 word2 word3 ... word12",
117
+ validate: (v) => {
118
+ if (!v?.trim())
119
+ return "Required";
120
+ const words = v.trim().split(/\s+/);
121
+ if (words.length !== 12)
122
+ return `Expected 12 words, got ${words.length}`;
123
+ return undefined;
124
+ },
125
+ });
126
+ if (p.isCancel(mnemonic)) {
127
+ p.cancel("Cancelled.");
128
+ return null;
129
+ }
130
+ const s = p.spinner();
131
+ // Step 1: Derive custody address and look up FID
132
+ s.start("Looking up your Farcaster account");
133
+ let fid;
134
+ let account;
135
+ try {
136
+ account = mnemonicToAccount(mnemonic);
137
+ fid = await lookupFidByCustodyAddress(apiKey, account.address);
138
+ }
139
+ catch (err) {
140
+ s.stop("Failed");
141
+ const msg = err instanceof Error ? err.message : "Unknown error";
142
+ p.log.error(`Could not find Farcaster account: ${msg}`);
143
+ return null;
144
+ }
145
+ s.stop(`Found account (FID: ${fid})`);
146
+ // Step 2: Create signer
147
+ s.start("Creating signer");
148
+ let signer;
149
+ try {
150
+ signer = (await neynarPost("/signer", apiKey));
151
+ }
152
+ catch (err) {
153
+ s.stop("Failed");
154
+ const msg = err instanceof Error ? err.message : "Unknown error";
155
+ p.log.error(`Could not create signer: ${msg}`);
156
+ return null;
157
+ }
158
+ s.stop("Signer created");
159
+ // Step 3: Sign the key request locally
160
+ s.start("Authorizing signer");
161
+ let sigHex;
162
+ let deadline;
163
+ try {
164
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
165
+ const appAccountKey = new ViemLocalEip712Signer(account);
166
+ deadline = Math.floor(Date.now() / 1000) + 86400;
167
+ const keyBytes = hexToBytes(signer.public_key);
168
+ const signature = await appAccountKey.signKeyRequest({
169
+ requestFid: BigInt(fid),
170
+ key: keyBytes,
171
+ deadline: BigInt(deadline),
172
+ });
173
+ if (signature.isErr()) {
174
+ throw new Error("Signature generation failed");
175
+ }
176
+ sigHex = bytesToHex(signature.value);
177
+ }
178
+ catch (err) {
179
+ s.stop("Failed");
180
+ const msg = err instanceof Error ? err.message : "Unknown error";
181
+ p.log.error(`Could not authorize signer: ${msg}`);
182
+ return null;
183
+ }
184
+ s.stop("Signer authorized");
185
+ // Step 4: Register signed key to get approval URL
186
+ s.start("Registering with Neynar");
187
+ let registeredSigner;
188
+ try {
189
+ registeredSigner = (await neynarPost("/signer/signed_key", apiKey, {
190
+ signer_uuid: signer.signer_uuid,
191
+ app_fid: fid,
192
+ deadline,
193
+ signature: sigHex,
194
+ }));
195
+ }
196
+ catch (err) {
197
+ s.stop("Failed");
198
+ const msg = err instanceof Error ? err.message : "Unknown error";
199
+ p.log.error(`Could not register signer: ${msg}`);
200
+ return null;
201
+ }
202
+ s.stop("Registered");
203
+ if (!registeredSigner.signer_approval_url) {
204
+ p.log.error("No approval URL returned from Neynar.");
205
+ return null;
206
+ }
207
+ // Step 5: Show QR code
208
+ p.log.info("Scan this QR code with the Farcaster app to approve:\n");
209
+ await new Promise((resolve) => {
210
+ qrcode.generate(registeredSigner.signer_approval_url, { small: true }, (code) => {
211
+ console.log(code);
212
+ resolve();
213
+ });
214
+ });
215
+ console.log(`\n Or open: ${registeredSigner.signer_approval_url}\n`);
216
+ // Step 6: Poll for approval
217
+ s.start("Waiting for approval (scan the QR code above)");
218
+ let approved;
219
+ try {
220
+ approved = await pollSignerApproval(apiKey, signer.signer_uuid);
221
+ }
222
+ catch {
223
+ s.stop("Timed out");
224
+ p.log.warn("Signer not yet approved. You can re-run this command to try again.");
225
+ return null;
226
+ }
227
+ s.stop("Signer approved!");
228
+ const approvedFid = String(approved.fid ?? fid);
229
+ // Step 7: Save to .env
230
+ let envContent = "";
231
+ try {
232
+ envContent = await readFile(envPath, "utf-8");
233
+ }
234
+ catch {
235
+ // No existing .env
236
+ }
237
+ const envVars = {
238
+ NEYNAR_API_KEY: apiKey,
239
+ FARCASTER_SIGNER_UUID: signer.signer_uuid,
240
+ FARCASTER_FID: approvedFid,
241
+ };
242
+ for (const [key, value] of Object.entries(envVars)) {
243
+ const regex = new RegExp(`^${key}=.*$`, "m");
244
+ if (regex.test(envContent)) {
245
+ envContent = envContent.replace(regex, `${key}=${value}`);
246
+ }
247
+ else {
248
+ envContent += `${envContent.endsWith("\n") || envContent === "" ? "" : "\n"}${key}=${value}\n`;
249
+ }
250
+ }
251
+ await mkdir(dirname(envPath), { recursive: true });
252
+ await writeFile(envPath, envContent, "utf-8");
253
+ await chmod(envPath, 0o600);
254
+ p.log.success("Credentials saved to .env");
255
+ p.outro("Farcaster connected!");
256
+ return {
257
+ neynarKey: apiKey,
258
+ signerUuid: signer.signer_uuid,
259
+ fid: approvedFid,
260
+ };
261
+ }
262
+ async function pollSignerApproval(apiKey, signerUuid, maxWaitMs = 180_000) {
263
+ return pollSignerStatus(apiKey, signerUuid, maxWaitMs);
264
+ }
265
+ //# sourceMappingURL=connect-farcaster.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"connect-farcaster.js","sourceRoot":"","sources":["../../../src/cli/connect-farcaster.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,16 @@
1
+ /**
2
+ * Test a Telegram bot token by calling getMe.
3
+ */
4
+ export declare function testTelegram(token: string): Promise<void>;
5
+ /**
6
+ * Test a GitHub personal access token by calling /user.
7
+ */
8
+ export declare function testGitHub(token: string): Promise<void>;
9
+ /**
10
+ * Test a Postgres connection URL by connecting and immediately disconnecting.
11
+ */
12
+ export declare function testDatabase(url: string): Promise<void>;
13
+ /**
14
+ * Test an EVM RPC URL by calling eth_blockNumber.
15
+ */
16
+ export declare function testOnchain(rpcUrl: string): Promise<void>;
@@ -0,0 +1,65 @@
1
+ import pg from "pg";
2
+ /**
3
+ * Test a Telegram bot token by calling getMe.
4
+ */
5
+ export async function testTelegram(token) {
6
+ const res = await fetch(`https://api.telegram.org/bot${token}/getMe`);
7
+ if (!res.ok) {
8
+ const body = await res.text();
9
+ throw new Error(`Telegram API error (${res.status}): ${body}`);
10
+ }
11
+ const data = (await res.json());
12
+ if (!data.ok) {
13
+ throw new Error(`Telegram returned error: ${data.description ?? "unknown"}`);
14
+ }
15
+ }
16
+ /**
17
+ * Test a GitHub personal access token by calling /user.
18
+ */
19
+ export async function testGitHub(token) {
20
+ const res = await fetch("https://api.github.com/user", {
21
+ headers: {
22
+ Authorization: `Bearer ${token}`,
23
+ Accept: "application/vnd.github+json",
24
+ },
25
+ });
26
+ if (!res.ok) {
27
+ const body = await res.text();
28
+ throw new Error(`GitHub API error (${res.status}): ${body}`);
29
+ }
30
+ }
31
+ /**
32
+ * Test a Postgres connection URL by connecting and immediately disconnecting.
33
+ */
34
+ export async function testDatabase(url) {
35
+ const client = new pg.Client({ connectionString: url });
36
+ try {
37
+ await client.connect();
38
+ }
39
+ finally {
40
+ await client.end().catch(() => { });
41
+ }
42
+ }
43
+ /**
44
+ * Test an EVM RPC URL by calling eth_blockNumber.
45
+ */
46
+ export async function testOnchain(rpcUrl) {
47
+ const res = await fetch(rpcUrl, {
48
+ method: "POST",
49
+ headers: { "Content-Type": "application/json" },
50
+ body: JSON.stringify({
51
+ jsonrpc: "2.0",
52
+ method: "eth_blockNumber",
53
+ params: [],
54
+ id: 1,
55
+ }),
56
+ });
57
+ if (!res.ok) {
58
+ throw new Error(`RPC error (${res.status}): ${await res.text()}`);
59
+ }
60
+ const data = (await res.json());
61
+ if (data.error) {
62
+ throw new Error(`RPC error: ${data.error.message}`);
63
+ }
64
+ }
65
+ //# sourceMappingURL=connection-tests.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"connection-tests.js","sourceRoot":"","sources":["../../../src/cli/connection-tests.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,IAAI,CAAC;AAEpB;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,YAAY,CAAC,KAAa;IAC9C,MAAM,GAAG,GAAG,MAAM,KAAK,CAAC,+BAA+B,KAAK,QAAQ,CAAC,CAAC;IACtE,IAAI,CAAC,GAAG,CAAC,EAAE,EAAE,CAAC;QACZ,MAAM,IAAI,GAAG,MAAM,GAAG,CAAC,IAAI,EAAE,CAAC;QAC9B,MAAM,IAAI,KAAK,CAAC,uBAAuB,GAAG,CAAC,MAAM,MAAM,IAAI,EAAE,CAAC,CAAC;IACjE,CAAC;IACD,MAAM,IAAI,GAAG,CAAC,MAAM,GAAG,CAAC,IAAI,EAAE,CAA0C,CAAC;IACzE,IAAI,CAAC,IAAI,CAAC,EAAE,EAAE,CAAC;QACb,MAAM,IAAI,KAAK,CAAC,4BAA4B,IAAI,CAAC,WAAW,IAAI,SAAS,EAAE,CAAC,CAAC;IAC/E,CAAC;AACH,CAAC;AAED;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,UAAU,CAAC,KAAa;IAC5C,MAAM,GAAG,GAAG,MAAM,KAAK,CAAC,6BAA6B,EAAE;QACrD,OAAO,EAAE;YACP,aAAa,EAAE,UAAU,KAAK,EAAE;YAChC,MAAM,EAAE,6BAA6B;SACtC;KACF,CAAC,CAAC;IACH,IAAI,CAAC,GAAG,CAAC,EAAE,EAAE,CAAC;QACZ,MAAM,IAAI,GAAG,MAAM,GAAG,CAAC,IAAI,EAAE,CAAC;QAC9B,MAAM,IAAI,KAAK,CAAC,qBAAqB,GAAG,CAAC,MAAM,MAAM,IAAI,EAAE,CAAC,CAAC;IAC/D,CAAC;AACH,CAAC;AAED;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,YAAY,CAAC,GAAW;IAC5C,MAAM,MAAM,GAAG,IAAI,EAAE,CAAC,MAAM,CAAC,EAAE,gBAAgB,EAAE,GAAG,EAAE,CAAC,CAAC;IACxD,IAAI,CAAC;QACH,MAAM,MAAM,CAAC,OAAO,EAAE,CAAC;IACzB,CAAC;YAAS,CAAC;QACT,MAAM,MAAM,CAAC,GAAG,EAAE,CAAC,KAAK,CAAC,GAAG,EAAE,GAAE,CAAC,CAAC,CAAC;IACrC,CAAC;AACH,CAAC;AAED;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,WAAW,CAAC,MAAc;IAC9C,MAAM,GAAG,GAAG,MAAM,KAAK,CAAC,MAAM,EAAE;QAC9B,MAAM,EAAE,MAAM;QACd,OAAO,EAAE,EAAE,cAAc,EAAE,kBAAkB,EAAE;QAC/C,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC;YACnB,OAAO,EAAE,KAAK;YACd,MAAM,EAAE,iBAAiB;YACzB,MAAM,EAAE,EAAE;YACV,EAAE,EAAE,CAAC;SACN,CAAC;KACH,CAAC,CAAC;IACH,IAAI,CAAC,GAAG,CAAC,EAAE,EAAE,CAAC;QACZ,MAAM,IAAI,KAAK,CAAC,cAAc,GAAG,CAAC,MAAM,MAAM,MAAM,GAAG,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;IACpE,CAAC;IACD,MAAM,IAAI,GAAG,CAAC,MAAM,GAAG,CAAC,IAAI,EAAE,CAAoC,CAAC;IACnE,IAAI,IAAI,CAAC,KAAK,EAAE,CAAC;QACf,MAAM,IAAI,KAAK,CAAC,cAAc,IAAI,CAAC,KAAK,CAAC,OAAO,EAAE,CAAC,CAAC;IACtD,CAAC;AACH,CAAC"}
@@ -0,0 +1 @@
1
+ export declare function runInit(dir: string): Promise<void>;