natroc 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (183) hide show
  1. package/AGENTS.md +494 -0
  2. package/LICENSE +7 -0
  3. package/README.md +0 -0
  4. package/install.ps1 +109 -0
  5. package/install.sh +132 -0
  6. package/package.json +77 -0
  7. package/server/dist/agent/agent-loop.d.ts +71 -0
  8. package/server/dist/agent/agent-loop.js +171 -0
  9. package/server/dist/agent/agent-loop.js.map +1 -0
  10. package/server/dist/agent/home-context.d.ts +29 -0
  11. package/server/dist/agent/home-context.js +134 -0
  12. package/server/dist/agent/home-context.js.map +1 -0
  13. package/server/dist/agent/improvement-engine.d.ts +23 -0
  14. package/server/dist/agent/improvement-engine.js +107 -0
  15. package/server/dist/agent/improvement-engine.js.map +1 -0
  16. package/server/dist/agent/tools/index.d.ts +14 -0
  17. package/server/dist/agent/tools/index.js +85 -0
  18. package/server/dist/agent/tools/index.js.map +1 -0
  19. package/server/dist/agent/tools/list-directory.d.ts +2 -0
  20. package/server/dist/agent/tools/list-directory.js +27 -0
  21. package/server/dist/agent/tools/list-directory.js.map +1 -0
  22. package/server/dist/agent/tools/read-file.d.ts +2 -0
  23. package/server/dist/agent/tools/read-file.js +30 -0
  24. package/server/dist/agent/tools/read-file.js.map +1 -0
  25. package/server/dist/agent/tools/run-command.d.ts +2 -0
  26. package/server/dist/agent/tools/run-command.js +72 -0
  27. package/server/dist/agent/tools/run-command.js.map +1 -0
  28. package/server/dist/agent/tools/system-info.d.ts +2 -0
  29. package/server/dist/agent/tools/system-info.js +28 -0
  30. package/server/dist/agent/tools/system-info.js.map +1 -0
  31. package/server/dist/agent/tools/types.d.ts +18 -0
  32. package/server/dist/agent/tools/types.js +2 -0
  33. package/server/dist/agent/tools/types.js.map +1 -0
  34. package/server/dist/agent/tools/util.d.ts +7 -0
  35. package/server/dist/agent/tools/util.js +24 -0
  36. package/server/dist/agent/tools/util.js.map +1 -0
  37. package/server/dist/agent/tools/write-file.d.ts +2 -0
  38. package/server/dist/agent/tools/write-file.js +25 -0
  39. package/server/dist/agent/tools/write-file.js.map +1 -0
  40. package/server/dist/app.d.ts +8 -0
  41. package/server/dist/app.js +39 -0
  42. package/server/dist/app.js.map +1 -0
  43. package/server/dist/auth/password.d.ts +7 -0
  44. package/server/dist/auth/password.js +20 -0
  45. package/server/dist/auth/password.js.map +1 -0
  46. package/server/dist/channels/channel-runtime.d.ts +32 -0
  47. package/server/dist/channels/channel-runtime.js +484 -0
  48. package/server/dist/channels/channel-runtime.js.map +1 -0
  49. package/server/dist/cli/agent-deliver.d.ts +14 -0
  50. package/server/dist/cli/agent-deliver.js +183 -0
  51. package/server/dist/cli/agent-deliver.js.map +1 -0
  52. package/server/dist/cli/args.d.ts +11 -0
  53. package/server/dist/cli/args.js +57 -0
  54. package/server/dist/cli/args.js.map +1 -0
  55. package/server/dist/cli/cli-token.d.ts +1 -0
  56. package/server/dist/cli/cli-token.js +22 -0
  57. package/server/dist/cli/cli-token.js.map +1 -0
  58. package/server/dist/cli/daemon.d.ts +2 -0
  59. package/server/dist/cli/daemon.js +252 -0
  60. package/server/dist/cli/daemon.js.map +1 -0
  61. package/server/dist/cli.d.ts +2 -0
  62. package/server/dist/cli.js +416 -0
  63. package/server/dist/cli.js.map +1 -0
  64. package/server/dist/config/natroc-home.d.ts +13 -0
  65. package/server/dist/config/natroc-home.js +730 -0
  66. package/server/dist/config/natroc-home.js.map +1 -0
  67. package/server/dist/gateway/agent-service.d.ts +16 -0
  68. package/server/dist/gateway/agent-service.js +261 -0
  69. package/server/dist/gateway/agent-service.js.map +1 -0
  70. package/server/dist/gateway/connection.d.ts +38 -0
  71. package/server/dist/gateway/connection.js +254 -0
  72. package/server/dist/gateway/connection.js.map +1 -0
  73. package/server/dist/gateway/gateway.d.ts +79 -0
  74. package/server/dist/gateway/gateway.js +150 -0
  75. package/server/dist/gateway/gateway.js.map +1 -0
  76. package/server/dist/gateway/index.d.ts +8 -0
  77. package/server/dist/gateway/index.js +26 -0
  78. package/server/dist/gateway/index.js.map +1 -0
  79. package/server/dist/gateway/protocol.d.ts +102 -0
  80. package/server/dist/gateway/protocol.js +63 -0
  81. package/server/dist/gateway/protocol.js.map +1 -0
  82. package/server/dist/gateway/rpc/agent.d.ts +3 -0
  83. package/server/dist/gateway/rpc/agent.js +174 -0
  84. package/server/dist/gateway/rpc/agent.js.map +1 -0
  85. package/server/dist/gateway/rpc/agents.d.ts +2 -0
  86. package/server/dist/gateway/rpc/agents.js +68 -0
  87. package/server/dist/gateway/rpc/agents.js.map +1 -0
  88. package/server/dist/gateway/rpc/auth.d.ts +3 -0
  89. package/server/dist/gateway/rpc/auth.js +180 -0
  90. package/server/dist/gateway/rpc/auth.js.map +1 -0
  91. package/server/dist/gateway/rpc/channels.d.ts +2 -0
  92. package/server/dist/gateway/rpc/channels.js +230 -0
  93. package/server/dist/gateway/rpc/channels.js.map +1 -0
  94. package/server/dist/gateway/rpc/conversations.d.ts +3 -0
  95. package/server/dist/gateway/rpc/conversations.js +36 -0
  96. package/server/dist/gateway/rpc/conversations.js.map +1 -0
  97. package/server/dist/gateway/rpc/projects.d.ts +3 -0
  98. package/server/dist/gateway/rpc/projects.js +49 -0
  99. package/server/dist/gateway/rpc/projects.js.map +1 -0
  100. package/server/dist/gateway/rpc/providers.d.ts +3 -0
  101. package/server/dist/gateway/rpc/providers.js +106 -0
  102. package/server/dist/gateway/rpc/providers.js.map +1 -0
  103. package/server/dist/gateway/rpc/usage.d.ts +2 -0
  104. package/server/dist/gateway/rpc/usage.js +41 -0
  105. package/server/dist/gateway/rpc/usage.js.map +1 -0
  106. package/server/dist/gateway/types.d.ts +43 -0
  107. package/server/dist/gateway/types.js +20 -0
  108. package/server/dist/gateway/types.js.map +1 -0
  109. package/server/dist/gateway/ws-server.d.ts +10 -0
  110. package/server/dist/gateway/ws-server.js +37 -0
  111. package/server/dist/gateway/ws-server.js.map +1 -0
  112. package/server/dist/index.d.ts +1 -0
  113. package/server/dist/index.js +9 -0
  114. package/server/dist/index.js.map +1 -0
  115. package/server/dist/local-runtime.d.ts +9 -0
  116. package/server/dist/local-runtime.js +16 -0
  117. package/server/dist/local-runtime.js.map +1 -0
  118. package/server/dist/providers/configured-adapters.d.ts +9 -0
  119. package/server/dist/providers/configured-adapters.js +34 -0
  120. package/server/dist/providers/configured-adapters.js.map +1 -0
  121. package/server/dist/providers/ollama.d.ts +23 -0
  122. package/server/dist/providers/ollama.js +164 -0
  123. package/server/dist/providers/ollama.js.map +1 -0
  124. package/server/dist/providers/openrouter.d.ts +24 -0
  125. package/server/dist/providers/openrouter.js +201 -0
  126. package/server/dist/providers/openrouter.js.map +1 -0
  127. package/server/dist/providers/thinking.d.ts +18 -0
  128. package/server/dist/providers/thinking.js +58 -0
  129. package/server/dist/providers/thinking.js.map +1 -0
  130. package/server/dist/providers/types.d.ts +55 -0
  131. package/server/dist/providers/types.js +2 -0
  132. package/server/dist/providers/types.js.map +1 -0
  133. package/server/dist/routes/schemas.d.ts +51 -0
  134. package/server/dist/routes/schemas.js +53 -0
  135. package/server/dist/routes/schemas.js.map +1 -0
  136. package/server/dist/runtime.d.ts +47 -0
  137. package/server/dist/runtime.js +29 -0
  138. package/server/dist/runtime.js.map +1 -0
  139. package/server/dist/server.d.ts +11 -0
  140. package/server/dist/server.js +19 -0
  141. package/server/dist/server.js.map +1 -0
  142. package/server/dist/storage/agent-repository.d.ts +59 -0
  143. package/server/dist/storage/agent-repository.js +192 -0
  144. package/server/dist/storage/agent-repository.js.map +1 -0
  145. package/server/dist/storage/auth-repository.d.ts +49 -0
  146. package/server/dist/storage/auth-repository.js +139 -0
  147. package/server/dist/storage/auth-repository.js.map +1 -0
  148. package/server/dist/storage/channel-repository.d.ts +152 -0
  149. package/server/dist/storage/channel-repository.js +413 -0
  150. package/server/dist/storage/channel-repository.js.map +1 -0
  151. package/server/dist/storage/conversation-repository.d.ts +63 -0
  152. package/server/dist/storage/conversation-repository.js +196 -0
  153. package/server/dist/storage/conversation-repository.js.map +1 -0
  154. package/server/dist/storage/database.d.ts +11 -0
  155. package/server/dist/storage/database.js +360 -0
  156. package/server/dist/storage/database.js.map +1 -0
  157. package/server/dist/storage/memory-repository.d.ts +70 -0
  158. package/server/dist/storage/memory-repository.js +279 -0
  159. package/server/dist/storage/memory-repository.js.map +1 -0
  160. package/server/dist/storage/project-repository.d.ts +25 -0
  161. package/server/dist/storage/project-repository.js +67 -0
  162. package/server/dist/storage/project-repository.js.map +1 -0
  163. package/server/dist/storage/provider-repository.d.ts +44 -0
  164. package/server/dist/storage/provider-repository.js +159 -0
  165. package/server/dist/storage/provider-repository.js.map +1 -0
  166. package/server/dist/storage/tool-call-repository.d.ts +35 -0
  167. package/server/dist/storage/tool-call-repository.js +83 -0
  168. package/server/dist/storage/tool-call-repository.js.map +1 -0
  169. package/server/dist/storage/usage-repository.d.ts +76 -0
  170. package/server/dist/storage/usage-repository.js +249 -0
  171. package/server/dist/storage/usage-repository.js.map +1 -0
  172. package/server/dist/storage/vault.d.ts +3 -0
  173. package/server/dist/storage/vault.js +57 -0
  174. package/server/dist/storage/vault.js.map +1 -0
  175. package/ui/README.md +0 -0
  176. package/ui/dist/assets/geist-cyrillic-ext-wght-normal-DjL33-gN.woff2 +0 -0
  177. package/ui/dist/assets/geist-cyrillic-wght-normal-BEAKL7Jp.woff2 +0 -0
  178. package/ui/dist/assets/geist-latin-ext-wght-normal-DC-KSUi6.woff2 +0 -0
  179. package/ui/dist/assets/geist-latin-wght-normal-BgDaEnEv.woff2 +0 -0
  180. package/ui/dist/assets/geist-vietnamese-wght-normal-6IgcOCM7.woff2 +0 -0
  181. package/ui/dist/assets/index-DKaFmZNO.js +114 -0
  182. package/ui/dist/assets/index-DOfPcjx3.css +2 -0
  183. package/ui/dist/index.html +14 -0
@@ -0,0 +1,279 @@
1
+ import { runInTransaction } from "./database.js";
2
+ export class MemoryRepository {
3
+ db;
4
+ constructor(db) {
5
+ this.db = db;
6
+ }
7
+ listEntries(options = {}) {
8
+ const limit = options.limit ?? 50;
9
+ const conditions = ["status = 'active'"];
10
+ const values = [];
11
+ if (options.kind) {
12
+ conditions.push("kind = ?");
13
+ values.push(options.kind);
14
+ }
15
+ if (options.userId) {
16
+ conditions.push("user_id = ?");
17
+ values.push(options.userId);
18
+ }
19
+ values.push(limit);
20
+ const rows = this.db
21
+ .prepare(`
22
+ SELECT * FROM agent_memory_entries
23
+ WHERE ${conditions.join(" AND ")}
24
+ ORDER BY updated_at DESC
25
+ LIMIT ?
26
+ `)
27
+ .all(...values);
28
+ return rows.map(mapMemoryRow);
29
+ }
30
+ searchEntries(query, limit = 20, options = {}) {
31
+ const ftsQuery = toFtsQuery(query);
32
+ if (!ftsQuery) {
33
+ return this.listEntries({ limit, userId: options.userId });
34
+ }
35
+ try {
36
+ const rows = options.userId
37
+ ? this.db
38
+ .prepare(`
39
+ SELECT agent_memory_entries.*
40
+ FROM agent_memory_entries_fts
41
+ JOIN agent_memory_entries
42
+ ON agent_memory_entries.rowid = agent_memory_entries_fts.rowid
43
+ WHERE agent_memory_entries_fts MATCH ?
44
+ AND agent_memory_entries.status = 'active'
45
+ AND agent_memory_entries.user_id = ?
46
+ ORDER BY bm25(agent_memory_entries_fts)
47
+ LIMIT ?
48
+ `)
49
+ .all(ftsQuery, options.userId, limit)
50
+ : this.db
51
+ .prepare(`
52
+ SELECT agent_memory_entries.*
53
+ FROM agent_memory_entries_fts
54
+ JOIN agent_memory_entries
55
+ ON agent_memory_entries.rowid = agent_memory_entries_fts.rowid
56
+ WHERE agent_memory_entries_fts MATCH ?
57
+ AND agent_memory_entries.status = 'active'
58
+ ORDER BY bm25(agent_memory_entries_fts)
59
+ LIMIT ?
60
+ `)
61
+ .all(ftsQuery, limit);
62
+ return rows.map(mapMemoryRow);
63
+ }
64
+ catch {
65
+ const likeQuery = `%${query.trim()}%`;
66
+ const rows = options.userId
67
+ ? this.db
68
+ .prepare(`
69
+ SELECT * FROM agent_memory_entries
70
+ WHERE status = 'active'
71
+ AND user_id = ?
72
+ AND (title LIKE ? OR content LIKE ?)
73
+ ORDER BY updated_at DESC
74
+ LIMIT ?
75
+ `)
76
+ .all(options.userId, likeQuery, likeQuery, limit)
77
+ : this.db
78
+ .prepare(`
79
+ SELECT * FROM agent_memory_entries
80
+ WHERE status = 'active'
81
+ AND (title LIKE ? OR content LIKE ?)
82
+ ORDER BY updated_at DESC
83
+ LIMIT ?
84
+ `)
85
+ .all(likeQuery, likeQuery, limit);
86
+ return rows.map(mapMemoryRow);
87
+ }
88
+ }
89
+ countEntries(options = {}) {
90
+ const row = options.userId
91
+ ? this.db
92
+ .prepare("SELECT COUNT(*) AS count FROM agent_memory_entries WHERE status = 'active' AND user_id = ?")
93
+ .get(options.userId)
94
+ : this.db
95
+ .prepare("SELECT COUNT(*) AS count FROM agent_memory_entries WHERE status = 'active'")
96
+ .get();
97
+ return row.count;
98
+ }
99
+ createProposal(input) {
100
+ const now = new Date().toISOString();
101
+ const id = crypto.randomUUID();
102
+ const title = normalizeTitle(input.title);
103
+ const content = input.content.trim();
104
+ const reason = input.reason.trim();
105
+ if (!content) {
106
+ throw new Error("Improvement proposal content cannot be empty.");
107
+ }
108
+ this.db
109
+ .prepare(`
110
+ INSERT INTO improvement_proposals (
111
+ id,
112
+ user_id,
113
+ kind,
114
+ title,
115
+ content,
116
+ reason,
117
+ source_conversation_id,
118
+ status,
119
+ created_at,
120
+ updated_at,
121
+ decided_at
122
+ )
123
+ VALUES (?, ?, ?, ?, ?, ?, ?, 'pending', ?, ?, NULL)
124
+ `)
125
+ .run(id, input.userId ?? null, input.kind, title, content, reason || "Generated from agent activity.", input.sourceConversationId ?? null, now, now);
126
+ return this.getProposal(id) ?? failPersisted("Improvement proposal");
127
+ }
128
+ listProposals(options = {}) {
129
+ const limit = options.limit ?? 50;
130
+ const conditions = [];
131
+ const values = [];
132
+ if (options.status) {
133
+ conditions.push("status = ?");
134
+ values.push(options.status);
135
+ }
136
+ if (options.userId) {
137
+ conditions.push("user_id = ?");
138
+ values.push(options.userId);
139
+ }
140
+ values.push(limit);
141
+ const where = conditions.length ? `WHERE ${conditions.join(" AND ")}` : "";
142
+ const rows = this.db
143
+ .prepare(`
144
+ SELECT * FROM improvement_proposals
145
+ ${where}
146
+ ORDER BY updated_at DESC
147
+ LIMIT ?
148
+ `)
149
+ .all(...values);
150
+ return rows.map(mapProposalRow);
151
+ }
152
+ countPendingProposals(options = {}) {
153
+ const row = options.userId
154
+ ? this.db
155
+ .prepare("SELECT COUNT(*) AS count FROM improvement_proposals WHERE status = 'pending' AND user_id = ?")
156
+ .get(options.userId)
157
+ : this.db
158
+ .prepare("SELECT COUNT(*) AS count FROM improvement_proposals WHERE status = 'pending'")
159
+ .get();
160
+ return row.count;
161
+ }
162
+ getProposal(id, options = {}) {
163
+ const row = options.userId
164
+ ? this.db
165
+ .prepare("SELECT * FROM improvement_proposals WHERE id = ? AND user_id = ?")
166
+ .get(id, options.userId)
167
+ : this.db
168
+ .prepare("SELECT * FROM improvement_proposals WHERE id = ?")
169
+ .get(id);
170
+ return row ? mapProposalRow(row) : null;
171
+ }
172
+ approveProposal(id, options = {}) {
173
+ const proposal = this.getProposal(id, options);
174
+ if (!proposal) {
175
+ throw new Error("Improvement proposal not found.");
176
+ }
177
+ if (proposal.status !== "pending") {
178
+ throw new Error("Only pending improvement proposals can be approved.");
179
+ }
180
+ const now = new Date().toISOString();
181
+ const entryId = crypto.randomUUID();
182
+ runInTransaction(this.db, () => {
183
+ this.db
184
+ .prepare(`
185
+ INSERT INTO agent_memory_entries (
186
+ id,
187
+ user_id,
188
+ kind,
189
+ title,
190
+ content,
191
+ source_conversation_id,
192
+ status,
193
+ created_at,
194
+ updated_at
195
+ )
196
+ VALUES (?, ?, ?, ?, ?, ?, 'active', ?, ?)
197
+ `)
198
+ .run(entryId, proposal.userId, proposal.kind, proposal.title, proposal.content, proposal.sourceConversationId, now, now);
199
+ this.db
200
+ .prepare(`
201
+ UPDATE improvement_proposals
202
+ SET status = 'approved', updated_at = ?, decided_at = ?
203
+ WHERE id = ?
204
+ `)
205
+ .run(now, now, id);
206
+ });
207
+ return this.getEntry(entryId, options) ?? failPersisted("Memory entry");
208
+ }
209
+ rejectProposal(id, options = {}) {
210
+ const proposal = this.getProposal(id, options);
211
+ if (!proposal) {
212
+ throw new Error("Improvement proposal not found.");
213
+ }
214
+ if (proposal.status !== "pending") {
215
+ throw new Error("Only pending improvement proposals can be rejected.");
216
+ }
217
+ const now = new Date().toISOString();
218
+ this.db
219
+ .prepare(`
220
+ UPDATE improvement_proposals
221
+ SET status = 'rejected', updated_at = ?, decided_at = ?
222
+ WHERE id = ?
223
+ `)
224
+ .run(now, now, id);
225
+ return this.getProposal(id, options) ?? failPersisted("Improvement proposal");
226
+ }
227
+ getEntry(id, options = {}) {
228
+ const row = options.userId
229
+ ? this.db
230
+ .prepare("SELECT * FROM agent_memory_entries WHERE id = ? AND user_id = ?")
231
+ .get(id, options.userId)
232
+ : this.db
233
+ .prepare("SELECT * FROM agent_memory_entries WHERE id = ?")
234
+ .get(id);
235
+ return row ? mapMemoryRow(row) : null;
236
+ }
237
+ }
238
+ function normalizeTitle(value) {
239
+ return value.trim().replace(/\s+/g, " ").slice(0, 80) || "Untitled";
240
+ }
241
+ function toFtsQuery(query) {
242
+ const tokens = query
243
+ .toLowerCase()
244
+ .match(/[\p{L}\p{N}_-]+/gu)
245
+ ?.slice(0, 8);
246
+ return tokens?.length ? tokens.map((token) => `"${token}"`).join(" OR ") : "";
247
+ }
248
+ function failPersisted(entity) {
249
+ throw new Error(`${entity} was not persisted.`);
250
+ }
251
+ function mapMemoryRow(row) {
252
+ return {
253
+ id: row.id,
254
+ userId: row.user_id,
255
+ kind: row.kind,
256
+ title: row.title,
257
+ content: row.content,
258
+ sourceConversationId: row.source_conversation_id,
259
+ status: row.status,
260
+ createdAt: row.created_at,
261
+ updatedAt: row.updated_at
262
+ };
263
+ }
264
+ function mapProposalRow(row) {
265
+ return {
266
+ id: row.id,
267
+ userId: row.user_id,
268
+ kind: row.kind,
269
+ title: row.title,
270
+ content: row.content,
271
+ reason: row.reason,
272
+ sourceConversationId: row.source_conversation_id,
273
+ status: row.status,
274
+ createdAt: row.created_at,
275
+ updatedAt: row.updated_at,
276
+ decidedAt: row.decided_at
277
+ };
278
+ }
279
+ //# sourceMappingURL=memory-repository.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"memory-repository.js","sourceRoot":"","sources":["../../src/storage/memory-repository.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,25 @@
1
+ import type { DatabaseConnection } from "./database.js";
2
+ export type ProjectRecord = {
3
+ id: string;
4
+ name: string;
5
+ description: string;
6
+ createdAt: string;
7
+ updatedAt: string;
8
+ };
9
+ export type CreateProjectInput = {
10
+ name: string;
11
+ description?: string;
12
+ };
13
+ export type UpdateProjectInput = {
14
+ name?: string;
15
+ description?: string;
16
+ };
17
+ export declare class ProjectRepository {
18
+ private readonly db;
19
+ constructor(db: DatabaseConnection);
20
+ listProjects(): ProjectRecord[];
21
+ getProject(id: string): ProjectRecord | null;
22
+ createProject(input: CreateProjectInput): ProjectRecord;
23
+ updateProject(id: string, input: UpdateProjectInput): ProjectRecord | null;
24
+ deleteProject(id: string): boolean;
25
+ }
@@ -0,0 +1,67 @@
1
+ export class ProjectRepository {
2
+ db;
3
+ constructor(db) {
4
+ this.db = db;
5
+ }
6
+ listProjects() {
7
+ const rows = this.db
8
+ .prepare("SELECT * FROM projects ORDER BY updated_at DESC")
9
+ .all();
10
+ return rows.map(mapProjectRow);
11
+ }
12
+ getProject(id) {
13
+ const row = this.db
14
+ .prepare("SELECT * FROM projects WHERE id = ?")
15
+ .get(id);
16
+ return row ? mapProjectRow(row) : null;
17
+ }
18
+ createProject(input) {
19
+ const id = crypto.randomUUID();
20
+ const now = new Date().toISOString();
21
+ const name = input.name.trim();
22
+ const description = (input.description ?? "").trim();
23
+ this.db
24
+ .prepare(`
25
+ INSERT INTO projects (id, name, description, created_at, updated_at)
26
+ VALUES (?, ?, ?, ?, ?)
27
+ `)
28
+ .run(id, name, description, now, now);
29
+ return { id, name, description, createdAt: now, updatedAt: now };
30
+ }
31
+ updateProject(id, input) {
32
+ const existing = this.getProject(id);
33
+ if (!existing)
34
+ return null;
35
+ const now = new Date().toISOString();
36
+ const name = input.name?.trim() || existing.name;
37
+ const description = input.description !== undefined
38
+ ? input.description.trim()
39
+ : existing.description;
40
+ this.db
41
+ .prepare("UPDATE projects SET name = ?, description = ?, updated_at = ? WHERE id = ?")
42
+ .run(name, description, now, id);
43
+ return {
44
+ id,
45
+ name,
46
+ description,
47
+ createdAt: existing.createdAt,
48
+ updatedAt: now,
49
+ };
50
+ }
51
+ deleteProject(id) {
52
+ const result = this.db
53
+ .prepare("DELETE FROM projects WHERE id = ?")
54
+ .run(id);
55
+ return Number(result.changes) > 0;
56
+ }
57
+ }
58
+ function mapProjectRow(row) {
59
+ return {
60
+ id: row.id,
61
+ name: row.name,
62
+ description: row.description,
63
+ createdAt: row.created_at,
64
+ updatedAt: row.updated_at,
65
+ };
66
+ }
67
+ //# sourceMappingURL=project-repository.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"project-repository.js","sourceRoot":"","sources":["../../src/storage/project-repository.ts"],"names":[],"mappings":"AA4BA,MAAM,OAAO,iBAAiB;IACC;IAA7B,YAA6B,EAAsB;QAAtB,OAAE,GAAF,EAAE,CAAoB;IAAG,CAAC;IAEvD,YAAY;QACV,MAAM,IAAI,GAAG,IAAI,CAAC,EAAE;aACjB,OAAO,CAAC,iDAAiD,CAAC;aAC1D,GAAG,EAAkB,CAAA;QAExB,OAAO,IAAI,CAAC,GAAG,CAAC,aAAa,CAAC,CAAA;IAChC,CAAC;IAED,UAAU,CAAC,EAAU;QACnB,MAAM,GAAG,GAAG,IAAI,CAAC,EAAE;aAChB,OAAO,CAAC,qCAAqC,CAAC;aAC9C,GAAG,CAAC,EAAE,CAA2B,CAAA;QAEpC,OAAO,GAAG,CAAC,CAAC,CAAC,aAAa,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAA;IACxC,CAAC;IAED,aAAa,CAAC,KAAyB;QACrC,MAAM,EAAE,GAAG,MAAM,CAAC,UAAU,EAAE,CAAA;QAC9B,MAAM,GAAG,GAAG,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,CAAA;QACpC,MAAM,IAAI,GAAG,KAAK,CAAC,IAAI,CAAC,IAAI,EAAE,CAAA;QAC9B,MAAM,WAAW,GAAG,CAAC,KAAK,CAAC,WAAW,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,CAAA;QAEpD,IAAI,CAAC,EAAE;aACJ,OAAO,CACN;;;OAGD,CACA;aACA,GAAG,CAAC,EAAE,EAAE,IAAI,EAAE,WAAW,EAAE,GAAG,EAAE,GAAG,CAAC,CAAA;QAEvC,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,WAAW,EAAE,SAAS,EAAE,GAAG,EAAE,SAAS,EAAE,GAAG,EAAE,CAAA;IAClE,CAAC;IAED,aAAa,CAAC,EAAU,EAAE,KAAyB;QACjD,MAAM,QAAQ,GAAG,IAAI,CAAC,UAAU,CAAC,EAAE,CAAC,CAAA;QACpC,IAAI,CAAC,QAAQ;YAAE,OAAO,IAAI,CAAA;QAE1B,MAAM,GAAG,GAAG,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,CAAA;QACpC,MAAM,IAAI,GAAG,KAAK,CAAC,IAAI,EAAE,IAAI,EAAE,IAAI,QAAQ,CAAC,IAAI,CAAA;QAChD,MAAM,WAAW,GACf,KAAK,CAAC,WAAW,KAAK,SAAS;YAC7B,CAAC,CAAC,KAAK,CAAC,WAAW,CAAC,IAAI,EAAE;YAC1B,CAAC,CAAC,QAAQ,CAAC,WAAW,CAAA;QAE1B,IAAI,CAAC,EAAE;aACJ,OAAO,CACN,4EAA4E,CAC7E;aACA,GAAG,CAAC,IAAI,EAAE,WAAW,EAAE,GAAG,EAAE,EAAE,CAAC,CAAA;QAElC,OAAO;YACL,EAAE;YACF,IAAI;YACJ,WAAW;YACX,SAAS,EAAE,QAAQ,CAAC,SAAS;YAC7B,SAAS,EAAE,GAAG;SACf,CAAA;IACH,CAAC;IAED,aAAa,CAAC,EAAU;QACtB,MAAM,MAAM,GAAG,IAAI,CAAC,EAAE;aACnB,OAAO,CAAC,mCAAmC,CAAC;aAC5C,GAAG,CAAC,EAAE,CAAC,CAAA;QAEV,OAAO,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,CAAA;IACnC,CAAC;CACF;AAED,SAAS,aAAa,CAAC,GAAe;IACpC,OAAO;QACL,EAAE,EAAE,GAAG,CAAC,EAAE;QACV,IAAI,EAAE,GAAG,CAAC,IAAI;QACd,WAAW,EAAE,GAAG,CAAC,WAAW;QAC5B,SAAS,EAAE,GAAG,CAAC,UAAU;QACzB,SAAS,EAAE,GAAG,CAAC,UAAU;KAC1B,CAAA;AACH,CAAC"}
@@ -0,0 +1,44 @@
1
+ import { type DatabaseConnection } from "./database.js";
2
+ import type { ProviderName } from "../providers/types.js";
3
+ export type ProviderRecord = {
4
+ id: string;
5
+ userId: string | null;
6
+ provider: ProviderName;
7
+ displayName: string;
8
+ baseUrl: string | null;
9
+ defaultModel: string | null;
10
+ secretRef: string | null;
11
+ isActive: boolean;
12
+ createdAt: string;
13
+ updatedAt: string;
14
+ };
15
+ export type ProviderInput = {
16
+ userId?: string | null;
17
+ provider: ProviderName;
18
+ displayName: string;
19
+ baseUrl: string | null;
20
+ defaultModel: string | null;
21
+ secretRef: string | null;
22
+ };
23
+ export declare class ProviderRepository {
24
+ private readonly db;
25
+ constructor(db: DatabaseConnection);
26
+ listProviders(options?: {
27
+ userId?: string;
28
+ }): ProviderRecord[];
29
+ getByProvider(provider: ProviderName, options?: {
30
+ userId?: string;
31
+ }): ProviderRecord | null;
32
+ getById(id: string, options?: {
33
+ userId?: string;
34
+ }): ProviderRecord | null;
35
+ getActiveProvider(options?: {
36
+ userId?: string;
37
+ }): ProviderRecord | null;
38
+ upsertProvider(input: ProviderInput): ProviderRecord;
39
+ setActiveProvider(id: string): ProviderRecord;
40
+ setSecret(secretRef: string, provider: ProviderName, encryptedValue: string, options?: {
41
+ userId?: string | null;
42
+ }): void;
43
+ getSecret(secretRef: string): string | null;
44
+ }
@@ -0,0 +1,159 @@
1
+ import { runInTransaction } from "./database.js";
2
+ export class ProviderRepository {
3
+ db;
4
+ constructor(db) {
5
+ this.db = db;
6
+ }
7
+ listProviders(options = {}) {
8
+ const rows = options.userId
9
+ ? this.db
10
+ .prepare("SELECT * FROM provider_connections WHERE user_id = ? ORDER BY rowid ASC")
11
+ .all(options.userId)
12
+ : this.db
13
+ .prepare("SELECT * FROM provider_connections ORDER BY rowid ASC")
14
+ .all();
15
+ return rows.map(mapProviderRow);
16
+ }
17
+ getByProvider(provider, options = {}) {
18
+ const row = options.userId
19
+ ? this.db
20
+ .prepare("SELECT * FROM provider_connections WHERE provider = ? AND user_id = ?")
21
+ .get(provider, options.userId)
22
+ : this.db
23
+ .prepare("SELECT * FROM provider_connections WHERE provider = ? AND user_id IS NULL ORDER BY rowid ASC LIMIT 1")
24
+ .get(provider);
25
+ return row ? mapProviderRow(row) : null;
26
+ }
27
+ getById(id, options = {}) {
28
+ const row = options.userId
29
+ ? this.db
30
+ .prepare("SELECT * FROM provider_connections WHERE id = ? AND user_id = ?")
31
+ .get(id, options.userId)
32
+ : this.db
33
+ .prepare("SELECT * FROM provider_connections WHERE id = ?")
34
+ .get(id);
35
+ return row ? mapProviderRow(row) : null;
36
+ }
37
+ getActiveProvider(options = {}) {
38
+ const row = options.userId
39
+ ? this.db
40
+ .prepare("SELECT * FROM provider_connections WHERE is_active = 1 AND user_id = ? LIMIT 1")
41
+ .get(options.userId)
42
+ : this.db
43
+ .prepare("SELECT * FROM provider_connections WHERE is_active = 1 LIMIT 1")
44
+ .get();
45
+ return row ? mapProviderRow(row) : null;
46
+ }
47
+ upsertProvider(input) {
48
+ const userId = input.userId ?? null;
49
+ const existing = this.getByProvider(input.provider, userId ? { userId } : {});
50
+ const now = new Date().toISOString();
51
+ const id = existing?.id ?? crypto.randomUUID();
52
+ if (existing) {
53
+ this.db
54
+ .prepare(`
55
+ UPDATE provider_connections
56
+ SET
57
+ display_name = ?,
58
+ base_url = ?,
59
+ default_model = ?,
60
+ secret_ref = ?,
61
+ updated_at = ?
62
+ WHERE id = ?
63
+ `)
64
+ .run(input.displayName, input.baseUrl, input.defaultModel, input.secretRef, now, id);
65
+ }
66
+ else {
67
+ this.db
68
+ .prepare(`
69
+ INSERT INTO provider_connections (
70
+ id,
71
+ user_id,
72
+ provider,
73
+ display_name,
74
+ base_url,
75
+ default_model,
76
+ secret_ref,
77
+ is_active,
78
+ created_at,
79
+ updated_at
80
+ )
81
+ VALUES (?, ?, ?, ?, ?, ?, ?, 0, ?, ?)
82
+ `)
83
+ .run(id, userId, input.provider, input.displayName, input.baseUrl, input.defaultModel, input.secretRef, now, now);
84
+ }
85
+ const provider = this.getById(id);
86
+ if (!provider) {
87
+ throw new Error("Provider was not persisted");
88
+ }
89
+ return provider;
90
+ }
91
+ setActiveProvider(id) {
92
+ const provider = this.getById(id);
93
+ if (!provider) {
94
+ throw new Error("Provider not found");
95
+ }
96
+ const now = new Date().toISOString();
97
+ runInTransaction(this.db, () => {
98
+ if (provider.userId) {
99
+ this.db
100
+ .prepare("UPDATE provider_connections SET is_active = 0, updated_at = ? WHERE user_id = ?")
101
+ .run(now, provider.userId);
102
+ }
103
+ else {
104
+ this.db
105
+ .prepare("UPDATE provider_connections SET is_active = 0, updated_at = ?")
106
+ .run(now);
107
+ }
108
+ this.db
109
+ .prepare("UPDATE provider_connections SET is_active = 1, updated_at = ? WHERE id = ?")
110
+ .run(now, id);
111
+ });
112
+ const activeProvider = this.getById(id);
113
+ if (!activeProvider) {
114
+ throw new Error("Provider not found after activation");
115
+ }
116
+ return activeProvider;
117
+ }
118
+ setSecret(secretRef, provider, encryptedValue, options = {}) {
119
+ const now = new Date().toISOString();
120
+ this.db
121
+ .prepare(`
122
+ INSERT INTO provider_secrets (
123
+ secret_ref,
124
+ user_id,
125
+ provider,
126
+ encrypted_value,
127
+ created_at,
128
+ updated_at
129
+ )
130
+ VALUES (?, ?, ?, ?, ?, ?)
131
+ ON CONFLICT(secret_ref) DO UPDATE SET
132
+ user_id = excluded.user_id,
133
+ encrypted_value = excluded.encrypted_value,
134
+ updated_at = excluded.updated_at
135
+ `)
136
+ .run(secretRef, options.userId ?? null, provider, encryptedValue, now, now);
137
+ }
138
+ getSecret(secretRef) {
139
+ const row = this.db
140
+ .prepare("SELECT encrypted_value FROM provider_secrets WHERE secret_ref = ?")
141
+ .get(secretRef);
142
+ return row?.encrypted_value ?? null;
143
+ }
144
+ }
145
+ function mapProviderRow(row) {
146
+ return {
147
+ id: row.id,
148
+ userId: row.user_id,
149
+ provider: row.provider,
150
+ displayName: row.display_name,
151
+ baseUrl: row.base_url,
152
+ defaultModel: row.default_model,
153
+ secretRef: row.secret_ref,
154
+ isActive: row.is_active === 1,
155
+ createdAt: row.created_at,
156
+ updatedAt: row.updated_at,
157
+ };
158
+ }
159
+ //# sourceMappingURL=provider-repository.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"provider-repository.js","sourceRoot":"","sources":["../../src/storage/provider-repository.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,35 @@
1
+ import type { DatabaseConnection } from "./database.js";
2
+ export type ToolCallStatus = "ok" | "error";
3
+ export type ToolCallRisk = "low" | "high";
4
+ export type ToolCallRecord = {
5
+ id: string;
6
+ userId: string | null;
7
+ conversationId: string;
8
+ toolName: string;
9
+ args: Record<string, unknown>;
10
+ output: string;
11
+ status: ToolCallStatus;
12
+ risk: ToolCallRisk;
13
+ createdAt: string;
14
+ };
15
+ export type CreateToolCallInput = {
16
+ id?: string;
17
+ userId?: string | null;
18
+ conversationId: string;
19
+ toolName: string;
20
+ args: Record<string, unknown>;
21
+ output: string;
22
+ status: ToolCallStatus;
23
+ risk: ToolCallRisk;
24
+ };
25
+ export declare class ToolCallRepository {
26
+ private readonly db;
27
+ constructor(db: DatabaseConnection);
28
+ create(input: CreateToolCallInput): ToolCallRecord;
29
+ listByConversation(conversationId: string, options?: {
30
+ userId?: string;
31
+ }): ToolCallRecord[];
32
+ countAll(options?: {
33
+ userId?: string;
34
+ }): number;
35
+ }