friday-code 1.0.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.
@@ -0,0 +1,338 @@
1
+ import { tool } from 'ai';
2
+ import { z } from 'zod';
3
+ import { readFileSync, writeFileSync, existsSync, readdirSync, statSync, mkdirSync } from 'fs';
4
+ import { join, relative, resolve } from 'path';
5
+ import { execSync } from 'child_process';
6
+ import { globbySync } from 'globby';
7
+ export function createTools(workingDirectory) {
8
+ return {
9
+ readFile: tool({
10
+ description: 'Read the contents of a file at the given path relative to the working directory',
11
+ parameters: z.object({
12
+ path: z.string().describe('File path relative to working directory'),
13
+ }),
14
+ execute: async ({ path }) => {
15
+ try {
16
+ const fullPath = resolve(workingDirectory, path);
17
+ if (!fullPath.startsWith(workingDirectory)) {
18
+ return { error: 'Access denied: path outside working directory' };
19
+ }
20
+ const content = readFileSync(fullPath, 'utf-8');
21
+ return { content, path: relative(workingDirectory, fullPath) };
22
+ }
23
+ catch (e) {
24
+ return { error: e.message };
25
+ }
26
+ },
27
+ }),
28
+ writeFile: tool({
29
+ description: 'Write content to a file. Creates the file if it does not exist, overwrites if it does.',
30
+ parameters: z.object({
31
+ path: z.string().describe('File path relative to working directory'),
32
+ content: z.string().describe('Content to write to the file'),
33
+ }),
34
+ execute: async ({ path, content }) => {
35
+ try {
36
+ const fullPath = resolve(workingDirectory, path);
37
+ if (!fullPath.startsWith(workingDirectory)) {
38
+ return { error: 'Access denied: path outside working directory' };
39
+ }
40
+ const dir = join(fullPath, '..');
41
+ mkdirSync(dir, { recursive: true });
42
+ writeFileSync(fullPath, content, 'utf-8');
43
+ return { success: true, path: relative(workingDirectory, fullPath) };
44
+ }
45
+ catch (e) {
46
+ return { error: e.message };
47
+ }
48
+ },
49
+ }),
50
+ editFile: tool({
51
+ description: 'Edit a file by replacing an exact string match with new content',
52
+ parameters: z.object({
53
+ path: z.string().describe('File path relative to working directory'),
54
+ oldText: z.string().describe('Exact text to find and replace'),
55
+ newText: z.string().describe('Text to replace with'),
56
+ }),
57
+ execute: async ({ path, oldText, newText }) => {
58
+ try {
59
+ const fullPath = resolve(workingDirectory, path);
60
+ if (!fullPath.startsWith(workingDirectory)) {
61
+ return { error: 'Access denied: path outside working directory' };
62
+ }
63
+ const content = readFileSync(fullPath, 'utf-8');
64
+ if (!content.includes(oldText)) {
65
+ return { error: 'Old text not found in file' };
66
+ }
67
+ const newContent = content.replace(oldText, newText);
68
+ writeFileSync(fullPath, newContent, 'utf-8');
69
+ return { success: true, path: relative(workingDirectory, fullPath) };
70
+ }
71
+ catch (e) {
72
+ return { error: e.message };
73
+ }
74
+ },
75
+ }),
76
+ listDirectory: tool({
77
+ description: 'List files and directories at a given path',
78
+ parameters: z.object({
79
+ path: z.string().describe('Directory path relative to working directory').default('.'),
80
+ }),
81
+ execute: async ({ path }) => {
82
+ try {
83
+ const fullPath = resolve(workingDirectory, path);
84
+ if (!fullPath.startsWith(workingDirectory)) {
85
+ return { error: 'Access denied: path outside working directory' };
86
+ }
87
+ const entries = readdirSync(fullPath).map(name => {
88
+ const stat = statSync(join(fullPath, name));
89
+ return { name, type: stat.isDirectory() ? 'directory' : 'file', size: stat.size };
90
+ });
91
+ return { entries, path: relative(workingDirectory, fullPath) || '.' };
92
+ }
93
+ catch (e) {
94
+ return { error: e.message };
95
+ }
96
+ },
97
+ }),
98
+ searchFiles: tool({
99
+ description: 'Search for files matching a glob pattern in the working directory',
100
+ parameters: z.object({
101
+ pattern: z.string().describe('Glob pattern like "**/*.ts" or "src/**/*.js"'),
102
+ }),
103
+ execute: async ({ pattern }) => {
104
+ try {
105
+ const files = globbySync(pattern, { cwd: workingDirectory, gitignore: true });
106
+ return { files: files.slice(0, 100), total: files.length };
107
+ }
108
+ catch (e) {
109
+ return { error: e.message };
110
+ }
111
+ },
112
+ }),
113
+ searchContent: tool({
114
+ description: 'Search for text content within files using grep',
115
+ parameters: z.object({
116
+ query: z.string().describe('Text or regex to search for'),
117
+ glob: z.string().describe('Optional glob to narrow file search').optional(),
118
+ }),
119
+ execute: async ({ query, glob }) => {
120
+ try {
121
+ const globArg = glob ? `--include="${glob}"` : '';
122
+ const cmd = `grep -rn ${globArg} --max-count=50 "${query.replace(/"/g, '\\"')}" .`;
123
+ const result = execSync(cmd, {
124
+ cwd: workingDirectory,
125
+ encoding: 'utf-8',
126
+ timeout: 10000,
127
+ maxBuffer: 1024 * 1024,
128
+ });
129
+ const lines = result.trim().split('\n').slice(0, 30);
130
+ return { matches: lines };
131
+ }
132
+ catch {
133
+ return { matches: [] };
134
+ }
135
+ },
136
+ }),
137
+ executeCommand: tool({
138
+ description: 'Execute a shell command in the working directory. Use for running tests, builds, git commands, etc.',
139
+ parameters: z.object({
140
+ command: z.string().describe('Shell command to execute'),
141
+ }),
142
+ execute: async ({ command }) => {
143
+ try {
144
+ // Security: block dangerous commands
145
+ const blocked = ['rm -rf /', 'mkfs', 'dd if=', ':(){', 'fork bomb'];
146
+ if (blocked.some(b => command.includes(b))) {
147
+ return { error: 'Command blocked for safety' };
148
+ }
149
+ const result = execSync(command, {
150
+ cwd: workingDirectory,
151
+ encoding: 'utf-8',
152
+ timeout: 30000,
153
+ maxBuffer: 1024 * 1024 * 5,
154
+ });
155
+ return { output: result.slice(0, 10000), exitCode: 0 };
156
+ }
157
+ catch (e) {
158
+ return {
159
+ output: (e.stdout || '') + '\n' + (e.stderr || ''),
160
+ exitCode: e.status || 1,
161
+ error: e.message,
162
+ };
163
+ }
164
+ },
165
+ }),
166
+ gitStatus: tool({
167
+ description: 'Show the current git status (staged, unstaged, untracked files)',
168
+ parameters: z.object({}),
169
+ execute: async () => {
170
+ try {
171
+ const result = execSync('git status --porcelain', {
172
+ cwd: workingDirectory, encoding: 'utf-8', timeout: 10000,
173
+ });
174
+ const lines = result.trim().split('\n').filter(Boolean);
175
+ const staged = lines.filter(l => /^[MADRC]/.test(l)).map(l => l.trim());
176
+ const unstaged = lines.filter(l => /^.[MADRC]/.test(l)).map(l => l.trim());
177
+ const untracked = lines.filter(l => l.startsWith('??')).map(l => l.slice(3));
178
+ return { staged, unstaged, untracked, clean: lines.length === 0 };
179
+ }
180
+ catch (e) {
181
+ return { error: e.message };
182
+ }
183
+ },
184
+ }),
185
+ gitDiff: tool({
186
+ description: 'Show git diff for working changes or staged changes',
187
+ parameters: z.object({
188
+ staged: z.boolean().describe('Show staged changes instead of working changes').default(false),
189
+ path: z.string().describe('Optional file path to limit diff').optional(),
190
+ }),
191
+ execute: async ({ staged, path }) => {
192
+ try {
193
+ const args = staged ? '--cached' : '';
194
+ const pathArg = path ? `-- "${path}"` : '';
195
+ const result = execSync(`git diff ${args} ${pathArg}`.trim(), {
196
+ cwd: workingDirectory, encoding: 'utf-8', timeout: 10000, maxBuffer: 1024 * 1024 * 2,
197
+ });
198
+ return { diff: result.slice(0, 15000), truncated: result.length > 15000 };
199
+ }
200
+ catch (e) {
201
+ return { error: e.message };
202
+ }
203
+ },
204
+ }),
205
+ gitLog: tool({
206
+ description: 'Show recent git commit history',
207
+ parameters: z.object({
208
+ count: z.number().describe('Number of commits to show').default(10),
209
+ oneline: z.boolean().describe('Show one line per commit').default(true),
210
+ }),
211
+ execute: async ({ count, oneline }) => {
212
+ try {
213
+ const fmt = oneline ? '--oneline' : '--format=%H|%an|%ar|%s';
214
+ const result = execSync(`git log ${fmt} -n ${Math.min(count, 50)}`, {
215
+ cwd: workingDirectory, encoding: 'utf-8', timeout: 10000,
216
+ });
217
+ if (oneline) {
218
+ return { commits: result.trim().split('\n').filter(Boolean) };
219
+ }
220
+ const commits = result.trim().split('\n').filter(Boolean).map(line => {
221
+ const [hash, author, date, ...msgParts] = line.split('|');
222
+ return { hash, author, date, message: msgParts.join('|') };
223
+ });
224
+ return { commits };
225
+ }
226
+ catch (e) {
227
+ return { error: e.message };
228
+ }
229
+ },
230
+ }),
231
+ gitCommit: tool({
232
+ description: 'Stage files and create a git commit',
233
+ parameters: z.object({
234
+ message: z.string().describe('Commit message'),
235
+ files: z.array(z.string()).describe('Files to stage (use ["."] for all)').default(['.'])
236
+ }),
237
+ execute: async ({ message, files }) => {
238
+ try {
239
+ const fileArgs = files.map(f => `"${f}"`).join(' ');
240
+ execSync(`git add ${fileArgs}`, { cwd: workingDirectory, encoding: 'utf-8', timeout: 10000 });
241
+ const result = execSync(`git commit -m "${message.replace(/"/g, '\\"')}"`, {
242
+ cwd: workingDirectory, encoding: 'utf-8', timeout: 10000,
243
+ });
244
+ return { success: true, output: result.trim() };
245
+ }
246
+ catch (e) {
247
+ return { error: e.message };
248
+ }
249
+ },
250
+ }),
251
+ webFetch: tool({
252
+ description: 'Fetch content from a URL. Returns text content for analysis.',
253
+ parameters: z.object({
254
+ url: z.string().describe('URL to fetch'),
255
+ maxLength: z.number().describe('Max response length in characters').default(10000),
256
+ }),
257
+ execute: async ({ url, maxLength }) => {
258
+ try {
259
+ const response = await fetch(url, {
260
+ headers: { 'User-Agent': 'Friday-Code/1.0' },
261
+ signal: AbortSignal.timeout(15000),
262
+ });
263
+ if (!response.ok) {
264
+ return { error: `HTTP ${response.status}: ${response.statusText}` };
265
+ }
266
+ const text = await response.text();
267
+ return {
268
+ content: text.slice(0, maxLength),
269
+ contentType: response.headers.get('content-type') || 'unknown',
270
+ truncated: text.length > maxLength,
271
+ statusCode: response.status,
272
+ };
273
+ }
274
+ catch (e) {
275
+ return { error: e.message };
276
+ }
277
+ },
278
+ }),
279
+ runTests: tool({
280
+ description: 'Run the test suite. Auto-detects the test runner from package.json or common patterns.',
281
+ parameters: z.object({
282
+ command: z.string().describe('Test command to run. If empty, auto-detects from package.json scripts.').optional(),
283
+ }),
284
+ execute: async ({ command }) => {
285
+ try {
286
+ let testCmd = command;
287
+ if (!testCmd) {
288
+ const pkgPath = join(workingDirectory, 'package.json');
289
+ if (existsSync(pkgPath)) {
290
+ const pkg = JSON.parse(readFileSync(pkgPath, 'utf-8'));
291
+ if (pkg.scripts?.test)
292
+ testCmd = 'npm test';
293
+ else if (pkg.scripts?.['test:unit'])
294
+ testCmd = 'npm run test:unit';
295
+ }
296
+ if (!testCmd && existsSync(join(workingDirectory, 'Makefile'))) {
297
+ testCmd = 'make test';
298
+ }
299
+ if (!testCmd)
300
+ testCmd = 'npm test';
301
+ }
302
+ const result = execSync(testCmd, {
303
+ cwd: workingDirectory,
304
+ encoding: 'utf-8',
305
+ timeout: 120000,
306
+ maxBuffer: 1024 * 1024 * 5,
307
+ });
308
+ return { output: result.slice(0, 15000), exitCode: 0, command: testCmd };
309
+ }
310
+ catch (e) {
311
+ return {
312
+ output: ((e.stdout || '') + '\n' + (e.stderr || '')).slice(0, 15000),
313
+ exitCode: e.status || 1,
314
+ command: command || 'npm test',
315
+ error: e.message,
316
+ };
317
+ }
318
+ },
319
+ }),
320
+ };
321
+ }
322
+ /** Tool safety classification for human-in-the-loop approval */
323
+ export const TOOL_SAFETY = {
324
+ readFile: 'safe',
325
+ listDirectory: 'safe',
326
+ searchFiles: 'safe',
327
+ searchContent: 'safe',
328
+ gitStatus: 'safe',
329
+ gitDiff: 'safe',
330
+ gitLog: 'safe',
331
+ webFetch: 'safe',
332
+ writeFile: 'destructive',
333
+ editFile: 'destructive',
334
+ executeCommand: 'destructive',
335
+ gitCommit: 'destructive',
336
+ runTests: 'destructive',
337
+ };
338
+ //# sourceMappingURL=tools.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tools.js","sourceRoot":"","sources":["../../../src/core/tools/tools.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,IAAI,CAAC;AAC1B,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAE,YAAY,EAAE,aAAa,EAAE,UAAU,EAAE,WAAW,EAAE,QAAQ,EAAE,SAAS,EAAE,MAAM,IAAI,CAAC;AAC/F,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,OAAO,EAAE,MAAM,MAAM,CAAC;AAC/C,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AACzC,OAAO,EAAE,UAAU,EAAE,MAAM,QAAQ,CAAC;AAEpC,MAAM,UAAU,WAAW,CAAC,gBAAwB;IAClD,OAAO;QACL,QAAQ,EAAE,IAAI,CAAC;YACb,WAAW,EAAE,iFAAiF;YAC9F,UAAU,EAAE,CAAC,CAAC,MAAM,CAAC;gBACnB,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,yCAAyC,CAAC;aACrE,CAAC;YACF,OAAO,EAAE,KAAK,EAAE,EAAE,IAAI,EAAE,EAAE,EAAE;gBAC1B,IAAI,CAAC;oBACH,MAAM,QAAQ,GAAG,OAAO,CAAC,gBAAgB,EAAE,IAAI,CAAC,CAAC;oBACjD,IAAI,CAAC,QAAQ,CAAC,UAAU,CAAC,gBAAgB,CAAC,EAAE,CAAC;wBAC3C,OAAO,EAAE,KAAK,EAAE,+CAA+C,EAAE,CAAC;oBACpE,CAAC;oBACD,MAAM,OAAO,GAAG,YAAY,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;oBAChD,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,QAAQ,CAAC,gBAAgB,EAAE,QAAQ,CAAC,EAAE,CAAC;gBACjE,CAAC;gBAAC,OAAO,CAAM,EAAE,CAAC;oBAChB,OAAO,EAAE,KAAK,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC;gBAC9B,CAAC;YACH,CAAC;SACF,CAAC;QAEF,SAAS,EAAE,IAAI,CAAC;YACd,WAAW,EAAE,wFAAwF;YACrG,UAAU,EAAE,CAAC,CAAC,MAAM,CAAC;gBACnB,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,yCAAyC,CAAC;gBACpE,OAAO,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,8BAA8B,CAAC;aAC7D,CAAC;YACF,OAAO,EAAE,KAAK,EAAE,EAAE,IAAI,EAAE,OAAO,EAAE,EAAE,EAAE;gBACnC,IAAI,CAAC;oBACH,MAAM,QAAQ,GAAG,OAAO,CAAC,gBAAgB,EAAE,IAAI,CAAC,CAAC;oBACjD,IAAI,CAAC,QAAQ,CAAC,UAAU,CAAC,gBAAgB,CAAC,EAAE,CAAC;wBAC3C,OAAO,EAAE,KAAK,EAAE,+CAA+C,EAAE,CAAC;oBACpE,CAAC;oBACD,MAAM,GAAG,GAAG,IAAI,CAAC,QAAQ,EAAE,IAAI,CAAC,CAAC;oBACjC,SAAS,CAAC,GAAG,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;oBACpC,aAAa,CAAC,QAAQ,EAAE,OAAO,EAAE,OAAO,CAAC,CAAC;oBAC1C,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE,QAAQ,CAAC,gBAAgB,EAAE,QAAQ,CAAC,EAAE,CAAC;gBACvE,CAAC;gBAAC,OAAO,CAAM,EAAE,CAAC;oBAChB,OAAO,EAAE,KAAK,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC;gBAC9B,CAAC;YACH,CAAC;SACF,CAAC;QAEF,QAAQ,EAAE,IAAI,CAAC;YACb,WAAW,EAAE,iEAAiE;YAC9E,UAAU,EAAE,CAAC,CAAC,MAAM,CAAC;gBACnB,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,yCAAyC,CAAC;gBACpE,OAAO,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,gCAAgC,CAAC;gBAC9D,OAAO,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,sBAAsB,CAAC;aACrD,CAAC;YACF,OAAO,EAAE,KAAK,EAAE,EAAE,IAAI,EAAE,OAAO,EAAE,OAAO,EAAE,EAAE,EAAE;gBAC5C,IAAI,CAAC;oBACH,MAAM,QAAQ,GAAG,OAAO,CAAC,gBAAgB,EAAE,IAAI,CAAC,CAAC;oBACjD,IAAI,CAAC,QAAQ,CAAC,UAAU,CAAC,gBAAgB,CAAC,EAAE,CAAC;wBAC3C,OAAO,EAAE,KAAK,EAAE,+CAA+C,EAAE,CAAC;oBACpE,CAAC;oBACD,MAAM,OAAO,GAAG,YAAY,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;oBAChD,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAC,EAAE,CAAC;wBAC/B,OAAO,EAAE,KAAK,EAAE,4BAA4B,EAAE,CAAC;oBACjD,CAAC;oBACD,MAAM,UAAU,GAAG,OAAO,CAAC,OAAO,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;oBACrD,aAAa,CAAC,QAAQ,EAAE,UAAU,EAAE,OAAO,CAAC,CAAC;oBAC7C,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE,QAAQ,CAAC,gBAAgB,EAAE,QAAQ,CAAC,EAAE,CAAC;gBACvE,CAAC;gBAAC,OAAO,CAAM,EAAE,CAAC;oBAChB,OAAO,EAAE,KAAK,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC;gBAC9B,CAAC;YACH,CAAC;SACF,CAAC;QAEF,aAAa,EAAE,IAAI,CAAC;YAClB,WAAW,EAAE,4CAA4C;YACzD,UAAU,EAAE,CAAC,CAAC,MAAM,CAAC;gBACnB,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,8CAA8C,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC;aACvF,CAAC;YACF,OAAO,EAAE,KAAK,EAAE,EAAE,IAAI,EAAE,EAAE,EAAE;gBAC1B,IAAI,CAAC;oBACH,MAAM,QAAQ,GAAG,OAAO,CAAC,gBAAgB,EAAE,IAAI,CAAC,CAAC;oBACjD,IAAI,CAAC,QAAQ,CAAC,UAAU,CAAC,gBAAgB,CAAC,EAAE,CAAC;wBAC3C,OAAO,EAAE,KAAK,EAAE,+CAA+C,EAAE,CAAC;oBACpE,CAAC;oBACD,MAAM,OAAO,GAAG,WAAW,CAAC,QAAQ,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE;wBAC/C,MAAM,IAAI,GAAG,QAAQ,CAAC,IAAI,CAAC,QAAQ,EAAE,IAAI,CAAC,CAAC,CAAC;wBAC5C,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,CAAC,WAAW,EAAE,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,MAAM,EAAE,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE,CAAC;oBACpF,CAAC,CAAC,CAAC;oBACH,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,QAAQ,CAAC,gBAAgB,EAAE,QAAQ,CAAC,IAAI,GAAG,EAAE,CAAC;gBACxE,CAAC;gBAAC,OAAO,CAAM,EAAE,CAAC;oBAChB,OAAO,EAAE,KAAK,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC;gBAC9B,CAAC;YACH,CAAC;SACF,CAAC;QAEF,WAAW,EAAE,IAAI,CAAC;YAChB,WAAW,EAAE,mEAAmE;YAChF,UAAU,EAAE,CAAC,CAAC,MAAM,CAAC;gBACnB,OAAO,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,8CAA8C,CAAC;aAC7E,CAAC;YACF,OAAO,EAAE,KAAK,EAAE,EAAE,OAAO,EAAE,EAAE,EAAE;gBAC7B,IAAI,CAAC;oBACH,MAAM,KAAK,GAAG,UAAU,CAAC,OAAO,EAAE,EAAE,GAAG,EAAE,gBAAgB,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;oBAC9E,OAAO,EAAE,KAAK,EAAE,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,EAAE,KAAK,EAAE,KAAK,CAAC,MAAM,EAAE,CAAC;gBAC7D,CAAC;gBAAC,OAAO,CAAM,EAAE,CAAC;oBAChB,OAAO,EAAE,KAAK,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC;gBAC9B,CAAC;YACH,CAAC;SACF,CAAC;QAEF,aAAa,EAAE,IAAI,CAAC;YAClB,WAAW,EAAE,iDAAiD;YAC9D,UAAU,EAAE,CAAC,CAAC,MAAM,CAAC;gBACnB,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,6BAA6B,CAAC;gBACzD,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,qCAAqC,CAAC,CAAC,QAAQ,EAAE;aAC5E,CAAC;YACF,OAAO,EAAE,KAAK,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,EAAE,EAAE;gBACjC,IAAI,CAAC;oBACH,MAAM,OAAO,GAAG,IAAI,CAAC,CAAC,CAAC,cAAc,IAAI,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC;oBAClD,MAAM,GAAG,GAAG,YAAY,OAAO,oBAAoB,KAAK,CAAC,OAAO,CAAC,IAAI,EAAE,KAAK,CAAC,KAAK,CAAC;oBACnF,MAAM,MAAM,GAAG,QAAQ,CAAC,GAAG,EAAE;wBAC3B,GAAG,EAAE,gBAAgB;wBACrB,QAAQ,EAAE,OAAO;wBACjB,OAAO,EAAE,KAAK;wBACd,SAAS,EAAE,IAAI,GAAG,IAAI;qBACvB,CAAC,CAAC;oBACH,MAAM,KAAK,GAAG,MAAM,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;oBACrD,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,CAAC;gBAC5B,CAAC;gBAAC,MAAM,CAAC;oBACP,OAAO,EAAE,OAAO,EAAE,EAAE,EAAE,CAAC;gBACzB,CAAC;YACH,CAAC;SACF,CAAC;QAEF,cAAc,EAAE,IAAI,CAAC;YACnB,WAAW,EAAE,qGAAqG;YAClH,UAAU,EAAE,CAAC,CAAC,MAAM,CAAC;gBACnB,OAAO,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,0BAA0B,CAAC;aACzD,CAAC;YACF,OAAO,EAAE,KAAK,EAAE,EAAE,OAAO,EAAE,EAAE,EAAE;gBAC7B,IAAI,CAAC;oBACH,qCAAqC;oBACrC,MAAM,OAAO,GAAG,CAAC,UAAU,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,WAAW,CAAC,CAAC;oBACpE,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;wBAC3C,OAAO,EAAE,KAAK,EAAE,4BAA4B,EAAE,CAAC;oBACjD,CAAC;oBACD,MAAM,MAAM,GAAG,QAAQ,CAAC,OAAO,EAAE;wBAC/B,GAAG,EAAE,gBAAgB;wBACrB,QAAQ,EAAE,OAAO;wBACjB,OAAO,EAAE,KAAK;wBACd,SAAS,EAAE,IAAI,GAAG,IAAI,GAAG,CAAC;qBAC3B,CAAC,CAAC;oBACH,OAAO,EAAE,MAAM,EAAE,MAAM,CAAC,KAAK,CAAC,CAAC,EAAE,KAAK,CAAC,EAAE,QAAQ,EAAE,CAAC,EAAE,CAAC;gBACzD,CAAC;gBAAC,OAAO,CAAM,EAAE,CAAC;oBAChB,OAAO;wBACL,MAAM,EAAE,CAAC,CAAC,CAAC,MAAM,IAAI,EAAE,CAAC,GAAG,IAAI,GAAG,CAAC,CAAC,CAAC,MAAM,IAAI,EAAE,CAAC;wBAClD,QAAQ,EAAE,CAAC,CAAC,MAAM,IAAI,CAAC;wBACvB,KAAK,EAAE,CAAC,CAAC,OAAO;qBACjB,CAAC;gBACJ,CAAC;YACH,CAAC;SACF,CAAC;QAEF,SAAS,EAAE,IAAI,CAAC;YACd,WAAW,EAAE,iEAAiE;YAC9E,UAAU,EAAE,CAAC,CAAC,MAAM,CAAC,EAAE,CAAC;YACxB,OAAO,EAAE,KAAK,IAAI,EAAE;gBAClB,IAAI,CAAC;oBACH,MAAM,MAAM,GAAG,QAAQ,CAAC,wBAAwB,EAAE;wBAChD,GAAG,EAAE,gBAAgB,EAAE,QAAQ,EAAE,OAAO,EAAE,OAAO,EAAE,KAAK;qBACzD,CAAC,CAAC;oBACH,MAAM,KAAK,GAAG,MAAM,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;oBACxD,MAAM,MAAM,GAAG,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC;oBACxE,MAAM,QAAQ,GAAG,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC;oBAC3E,MAAM,SAAS,GAAG,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;oBAC7E,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,SAAS,EAAE,KAAK,EAAE,KAAK,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;gBACpE,CAAC;gBAAC,OAAO,CAAM,EAAE,CAAC;oBAChB,OAAO,EAAE,KAAK,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC;gBAC9B,CAAC;YACH,CAAC;SACF,CAAC;QAEF,OAAO,EAAE,IAAI,CAAC;YACZ,WAAW,EAAE,qDAAqD;YAClE,UAAU,EAAE,CAAC,CAAC,MAAM,CAAC;gBACnB,MAAM,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC,QAAQ,CAAC,gDAAgD,CAAC,CAAC,OAAO,CAAC,KAAK,CAAC;gBAC7F,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,kCAAkC,CAAC,CAAC,QAAQ,EAAE;aACzE,CAAC;YACF,OAAO,EAAE,KAAK,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,EAAE,EAAE;gBAClC,IAAI,CAAC;oBACH,MAAM,IAAI,GAAG,MAAM,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,EAAE,CAAC;oBACtC,MAAM,OAAO,GAAG,IAAI,CAAC,CAAC,CAAC,OAAO,IAAI,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC;oBAC3C,MAAM,MAAM,GAAG,QAAQ,CAAC,YAAY,IAAI,IAAI,OAAO,EAAE,CAAC,IAAI,EAAE,EAAE;wBAC5D,GAAG,EAAE,gBAAgB,EAAE,QAAQ,EAAE,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,SAAS,EAAE,IAAI,GAAG,IAAI,GAAG,CAAC;qBACrF,CAAC,CAAC;oBACH,OAAO,EAAE,IAAI,EAAE,MAAM,CAAC,KAAK,CAAC,CAAC,EAAE,KAAK,CAAC,EAAE,SAAS,EAAE,MAAM,CAAC,MAAM,GAAG,KAAK,EAAE,CAAC;gBAC5E,CAAC;gBAAC,OAAO,CAAM,EAAE,CAAC;oBAChB,OAAO,EAAE,KAAK,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC;gBAC9B,CAAC;YACH,CAAC;SACF,CAAC;QAEF,MAAM,EAAE,IAAI,CAAC;YACX,WAAW,EAAE,gCAAgC;YAC7C,UAAU,EAAE,CAAC,CAAC,MAAM,CAAC;gBACnB,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,2BAA2B,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC;gBACnE,OAAO,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC,QAAQ,CAAC,0BAA0B,CAAC,CAAC,OAAO,CAAC,IAAI,CAAC;aACxE,CAAC;YACF,OAAO,EAAE,KAAK,EAAE,EAAE,KAAK,EAAE,OAAO,EAAE,EAAE,EAAE;gBACpC,IAAI,CAAC;oBACH,MAAM,GAAG,GAAG,OAAO,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,wBAAwB,CAAC;oBAC7D,MAAM,MAAM,GAAG,QAAQ,CAAC,WAAW,GAAG,OAAO,IAAI,CAAC,GAAG,CAAC,KAAK,EAAE,EAAE,CAAC,EAAE,EAAE;wBAClE,GAAG,EAAE,gBAAgB,EAAE,QAAQ,EAAE,OAAO,EAAE,OAAO,EAAE,KAAK;qBACzD,CAAC,CAAC;oBACH,IAAI,OAAO,EAAE,CAAC;wBACZ,OAAO,EAAE,OAAO,EAAE,MAAM,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,EAAE,CAAC;oBAChE,CAAC;oBACD,MAAM,OAAO,GAAG,MAAM,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE;wBACnE,MAAM,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,GAAG,QAAQ,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;wBAC1D,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,EAAE,QAAQ,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC;oBAC7D,CAAC,CAAC,CAAC;oBACH,OAAO,EAAE,OAAO,EAAE,CAAC;gBACrB,CAAC;gBAAC,OAAO,CAAM,EAAE,CAAC;oBAChB,OAAO,EAAE,KAAK,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC;gBAC9B,CAAC;YACH,CAAC;SACF,CAAC;QAEF,SAAS,EAAE,IAAI,CAAC;YACd,WAAW,EAAE,qCAAqC;YAClD,UAAU,EAAE,CAAC,CAAC,MAAM,CAAC;gBACnB,OAAO,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,gBAAgB,CAAC;gBAC9C,KAAK,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,QAAQ,CAAC,oCAAoC,CAAC,CAAC,OAAO,CAAC,CAAC,GAAG,CAAC,CAAC;aACzF,CAAC;YACF,OAAO,EAAE,KAAK,EAAE,EAAE,OAAO,EAAE,KAAK,EAAE,EAAE,EAAE;gBACpC,IAAI,CAAC;oBACH,MAAM,QAAQ,GAAG,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;oBACpD,QAAQ,CAAC,WAAW,QAAQ,EAAE,EAAE,EAAE,GAAG,EAAE,gBAAgB,EAAE,QAAQ,EAAE,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,CAAC,CAAC;oBAC9F,MAAM,MAAM,GAAG,QAAQ,CAAC,kBAAkB,OAAO,CAAC,OAAO,CAAC,IAAI,EAAE,KAAK,CAAC,GAAG,EAAE;wBACzE,GAAG,EAAE,gBAAgB,EAAE,QAAQ,EAAE,OAAO,EAAE,OAAO,EAAE,KAAK;qBACzD,CAAC,CAAC;oBACH,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,CAAC,IAAI,EAAE,EAAE,CAAC;gBAClD,CAAC;gBAAC,OAAO,CAAM,EAAE,CAAC;oBAChB,OAAO,EAAE,KAAK,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC;gBAC9B,CAAC;YACH,CAAC;SACF,CAAC;QAEF,QAAQ,EAAE,IAAI,CAAC;YACb,WAAW,EAAE,8DAA8D;YAC3E,UAAU,EAAE,CAAC,CAAC,MAAM,CAAC;gBACnB,GAAG,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,cAAc,CAAC;gBACxC,SAAS,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,mCAAmC,CAAC,CAAC,OAAO,CAAC,KAAK,CAAC;aACnF,CAAC;YACF,OAAO,EAAE,KAAK,EAAE,EAAE,GAAG,EAAE,SAAS,EAAE,EAAE,EAAE;gBACpC,IAAI,CAAC;oBACH,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,GAAG,EAAE;wBAChC,OAAO,EAAE,EAAE,YAAY,EAAE,iBAAiB,EAAE;wBAC5C,MAAM,EAAE,WAAW,CAAC,OAAO,CAAC,KAAK,CAAC;qBACnC,CAAC,CAAC;oBACH,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE,CAAC;wBACjB,OAAO,EAAE,KAAK,EAAE,QAAQ,QAAQ,CAAC,MAAM,KAAK,QAAQ,CAAC,UAAU,EAAE,EAAE,CAAC;oBACtE,CAAC;oBACD,MAAM,IAAI,GAAG,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAC;oBACnC,OAAO;wBACL,OAAO,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,SAAS,CAAC;wBACjC,WAAW,EAAE,QAAQ,CAAC,OAAO,CAAC,GAAG,CAAC,cAAc,CAAC,IAAI,SAAS;wBAC9D,SAAS,EAAE,IAAI,CAAC,MAAM,GAAG,SAAS;wBAClC,UAAU,EAAE,QAAQ,CAAC,MAAM;qBAC5B,CAAC;gBACJ,CAAC;gBAAC,OAAO,CAAM,EAAE,CAAC;oBAChB,OAAO,EAAE,KAAK,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC;gBAC9B,CAAC;YACH,CAAC;SACF,CAAC;QAEF,QAAQ,EAAE,IAAI,CAAC;YACb,WAAW,EAAE,wFAAwF;YACrG,UAAU,EAAE,CAAC,CAAC,MAAM,CAAC;gBACnB,OAAO,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,wEAAwE,CAAC,CAAC,QAAQ,EAAE;aAClH,CAAC;YACF,OAAO,EAAE,KAAK,EAAE,EAAE,OAAO,EAAE,EAAE,EAAE;gBAC7B,IAAI,CAAC;oBACH,IAAI,OAAO,GAAG,OAAO,CAAC;oBACtB,IAAI,CAAC,OAAO,EAAE,CAAC;wBACb,MAAM,OAAO,GAAG,IAAI,CAAC,gBAAgB,EAAE,cAAc,CAAC,CAAC;wBACvD,IAAI,UAAU,CAAC,OAAO,CAAC,EAAE,CAAC;4BACxB,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC,CAAC;4BACvD,IAAI,GAAG,CAAC,OAAO,EAAE,IAAI;gCAAE,OAAO,GAAG,UAAU,CAAC;iCACvC,IAAI,GAAG,CAAC,OAAO,EAAE,CAAC,WAAW,CAAC;gCAAE,OAAO,GAAG,mBAAmB,CAAC;wBACrE,CAAC;wBACD,IAAI,CAAC,OAAO,IAAI,UAAU,CAAC,IAAI,CAAC,gBAAgB,EAAE,UAAU,CAAC,CAAC,EAAE,CAAC;4BAC/D,OAAO,GAAG,WAAW,CAAC;wBACxB,CAAC;wBACD,IAAI,CAAC,OAAO;4BAAE,OAAO,GAAG,UAAU,CAAC;oBACrC,CAAC;oBACD,MAAM,MAAM,GAAG,QAAQ,CAAC,OAAO,EAAE;wBAC/B,GAAG,EAAE,gBAAgB;wBACrB,QAAQ,EAAE,OAAO;wBACjB,OAAO,EAAE,MAAM;wBACf,SAAS,EAAE,IAAI,GAAG,IAAI,GAAG,CAAC;qBAC3B,CAAC,CAAC;oBACH,OAAO,EAAE,MAAM,EAAE,MAAM,CAAC,KAAK,CAAC,CAAC,EAAE,KAAK,CAAC,EAAE,QAAQ,EAAE,CAAC,EAAE,OAAO,EAAE,OAAO,EAAE,CAAC;gBAC3E,CAAC;gBAAC,OAAO,CAAM,EAAE,CAAC;oBAChB,OAAO;wBACL,MAAM,EAAE,CAAC,CAAC,CAAC,CAAC,MAAM,IAAI,EAAE,CAAC,GAAG,IAAI,GAAG,CAAC,CAAC,CAAC,MAAM,IAAI,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,KAAK,CAAC;wBACpE,QAAQ,EAAE,CAAC,CAAC,MAAM,IAAI,CAAC;wBACvB,OAAO,EAAE,OAAO,IAAI,UAAU;wBAC9B,KAAK,EAAE,CAAC,CAAC,OAAO;qBACjB,CAAC;gBACJ,CAAC;YACH,CAAC;SACF,CAAC;KACH,CAAC;AACJ,CAAC;AAED,gEAAgE;AAChE,MAAM,CAAC,MAAM,WAAW,GAA2C;IACjE,QAAQ,EAAE,MAAM;IAChB,aAAa,EAAE,MAAM;IACrB,WAAW,EAAE,MAAM;IACnB,aAAa,EAAE,MAAM;IACrB,SAAS,EAAE,MAAM;IACjB,OAAO,EAAE,MAAM;IACf,MAAM,EAAE,MAAM;IACd,QAAQ,EAAE,MAAM;IAChB,SAAS,EAAE,aAAa;IACxB,QAAQ,EAAE,aAAa;IACvB,cAAc,EAAE,aAAa;IAC7B,SAAS,EAAE,aAAa;IACxB,QAAQ,EAAE,aAAa;CACxB,CAAC"}
@@ -0,0 +1,10 @@
1
+ import Database from 'better-sqlite3';
2
+ import * as schema from './schema.js';
3
+ declare const DATA_DIR: string;
4
+ declare const DB_PATH: string;
5
+ export declare const db: import("drizzle-orm/better-sqlite3").BetterSQLite3Database<typeof schema> & {
6
+ $client: Database.Database;
7
+ };
8
+ export declare function initializeDatabase(): void;
9
+ export { schema };
10
+ export { DB_PATH, DATA_DIR };
@@ -0,0 +1,85 @@
1
+ import Database from 'better-sqlite3';
2
+ import { drizzle } from 'drizzle-orm/better-sqlite3';
3
+ import * as schema from './schema.js';
4
+ import { join } from 'path';
5
+ import { homedir } from 'os';
6
+ import { mkdirSync } from 'fs';
7
+ const DATA_DIR = join(homedir(), '.friday-code');
8
+ mkdirSync(DATA_DIR, { recursive: true });
9
+ const DB_PATH = join(DATA_DIR, 'friday.db');
10
+ const sqlite = new Database(DB_PATH);
11
+ sqlite.pragma('journal_mode = WAL');
12
+ sqlite.pragma('foreign_keys = ON');
13
+ export const db = drizzle(sqlite, { schema });
14
+ export function initializeDatabase() {
15
+ sqlite.exec(`
16
+ CREATE TABLE IF NOT EXISTS conversations (
17
+ id TEXT PRIMARY KEY,
18
+ title TEXT NOT NULL DEFAULT 'New Chat',
19
+ working_directory TEXT NOT NULL,
20
+ model_id TEXT,
21
+ provider_id TEXT,
22
+ created_at INTEGER NOT NULL DEFAULT (unixepoch()),
23
+ updated_at INTEGER NOT NULL DEFAULT (unixepoch())
24
+ );
25
+
26
+ CREATE TABLE IF NOT EXISTS messages (
27
+ id TEXT PRIMARY KEY,
28
+ conversation_id TEXT NOT NULL REFERENCES conversations(id) ON DELETE CASCADE,
29
+ role TEXT NOT NULL CHECK(role IN ('user', 'assistant', 'system', 'tool')),
30
+ content TEXT NOT NULL,
31
+ reasoning TEXT,
32
+ tool_calls TEXT,
33
+ tool_results TEXT,
34
+ token_usage TEXT,
35
+ finish_reason TEXT,
36
+ model_id TEXT,
37
+ created_at INTEGER NOT NULL DEFAULT (unixepoch())
38
+ );
39
+
40
+ CREATE TABLE IF NOT EXISTS providers (
41
+ id TEXT PRIMARY KEY,
42
+ name TEXT NOT NULL,
43
+ type TEXT NOT NULL CHECK(type IN ('openai', 'anthropic', 'ollama')),
44
+ api_key TEXT,
45
+ base_url TEXT,
46
+ is_enabled INTEGER NOT NULL DEFAULT 1,
47
+ created_at INTEGER NOT NULL DEFAULT (unixepoch())
48
+ );
49
+
50
+ CREATE TABLE IF NOT EXISTS models (
51
+ id TEXT PRIMARY KEY,
52
+ provider_id TEXT NOT NULL REFERENCES providers(id) ON DELETE CASCADE,
53
+ model_id TEXT NOT NULL,
54
+ name TEXT NOT NULL,
55
+ supports_streaming INTEGER DEFAULT 1,
56
+ supports_tools INTEGER DEFAULT 1,
57
+ supports_reasoning INTEGER DEFAULT 0,
58
+ context_window INTEGER,
59
+ last_fetched INTEGER NOT NULL DEFAULT (unixepoch())
60
+ );
61
+
62
+ CREATE TABLE IF NOT EXISTS settings (
63
+ key TEXT PRIMARY KEY,
64
+ value TEXT NOT NULL
65
+ );
66
+ `);
67
+ const existing = sqlite.prepare('SELECT COUNT(*) as count FROM providers').get();
68
+ if (existing.count === 0) {
69
+ sqlite.exec(`
70
+ INSERT OR IGNORE INTO providers (id, name, type, base_url) VALUES
71
+ ('openai', 'OpenAI', 'openai', 'https://api.openai.com/v1'),
72
+ ('anthropic', 'Anthropic', 'anthropic', 'https://api.anthropic.com'),
73
+ ('ollama', 'Ollama (Local)', 'ollama', 'http://localhost:11434');
74
+
75
+ INSERT OR IGNORE INTO settings (key, value) VALUES
76
+ ('active_provider', 'openai'),
77
+ ('active_model', 'gpt-4o'),
78
+ ('theme', 'default'),
79
+ ('stream_reasoning', 'true');
80
+ `);
81
+ }
82
+ }
83
+ export { schema };
84
+ export { DB_PATH, DATA_DIR };
85
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/db/index.ts"],"names":[],"mappings":"AAAA,OAAO,QAAQ,MAAM,gBAAgB,CAAC;AACtC,OAAO,EAAE,OAAO,EAAE,MAAM,4BAA4B,CAAC;AACrD,OAAO,KAAK,MAAM,MAAM,aAAa,CAAC;AAEtC,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAC5B,OAAO,EAAE,OAAO,EAAE,MAAM,IAAI,CAAC;AAC7B,OAAO,EAAE,SAAS,EAAE,MAAM,IAAI,CAAC;AAE/B,MAAM,QAAQ,GAAG,IAAI,CAAC,OAAO,EAAE,EAAE,cAAc,CAAC,CAAC;AACjD,SAAS,CAAC,QAAQ,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;AAEzC,MAAM,OAAO,GAAG,IAAI,CAAC,QAAQ,EAAE,WAAW,CAAC,CAAC;AAE5C,MAAM,MAAM,GAAG,IAAI,QAAQ,CAAC,OAAO,CAAC,CAAC;AACrC,MAAM,CAAC,MAAM,CAAC,oBAAoB,CAAC,CAAC;AACpC,MAAM,CAAC,MAAM,CAAC,mBAAmB,CAAC,CAAC;AAEnC,MAAM,CAAC,MAAM,EAAE,GAAG,OAAO,CAAC,MAAM,EAAE,EAAE,MAAM,EAAE,CAAC,CAAC;AAE9C,MAAM,UAAU,kBAAkB;IAChC,MAAM,CAAC,IAAI,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAmDX,CAAC,CAAC;IAEH,MAAM,QAAQ,GAAG,MAAM,CAAC,OAAO,CAAC,yCAAyC,CAAC,CAAC,GAAG,EAAuB,CAAC;IACtG,IAAI,QAAQ,CAAC,KAAK,KAAK,CAAC,EAAE,CAAC;QACzB,MAAM,CAAC,IAAI,CAAC;;;;;;;;;;;KAWX,CAAC,CAAC;IACL,CAAC;AACH,CAAC;AAED,OAAO,EAAE,MAAM,EAAE,CAAC;AAClB,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,CAAC"}