modular-studio 1.0.3 → 1.0.5

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 (107) hide show
  1. package/README.md +101 -20
  2. package/dist/assets/Badge-22Ai0eyi.js +1 -0
  3. package/dist/assets/Input-Bgp734xs.js +1 -0
  4. package/dist/assets/KnowledgeTab-DABxirZh.js +4 -0
  5. package/dist/assets/MemoryTab-DZeYElIT.js +16 -0
  6. package/dist/assets/QualificationTab-Dfpy3J30.js +1 -0
  7. package/dist/assets/ReviewTab-SD8lQuCc.js +103 -0
  8. package/dist/assets/Section-DoJrmytO.js +1 -0
  9. package/dist/assets/TestTab-PDyMF8Fw.js +33 -0
  10. package/dist/assets/ToolsTab-B83qGCmG.js +1 -0
  11. package/dist/assets/conversationStore-CkfEU2eV.js +1 -0
  12. package/dist/assets/icons-C2EV-le6.js +1 -0
  13. package/dist/assets/index-DkpMAxX7.css +1 -0
  14. package/dist/assets/index-q24ug5Qs.js +143 -0
  15. package/dist/assets/{jszip.min-DByyLalk.js → jszip.min-wf-D3Ix_.js} +1 -1
  16. package/dist/assets/markdown-DWF7F0i0.js +29 -0
  17. package/dist/assets/services-BaKotDf0.js +343 -0
  18. package/dist/assets/stores-CeKWz7ou.js +1 -0
  19. package/dist/assets/vendor-D1h_O76p.js +9 -0
  20. package/dist/index.html +8 -4
  21. package/dist-server/bin/modular-mcp.js +0 -1
  22. package/dist-server/bin/modular-studio.js +0 -1
  23. package/dist-server/server/config.js +0 -1
  24. package/dist-server/server/data/mcp-tokens.json +3 -3
  25. package/dist-server/server/index.d.ts.map +1 -1
  26. package/dist-server/server/index.js +12 -1
  27. package/dist-server/server/index.js.map +1 -1
  28. package/dist-server/server/mcp/manager.js +0 -1
  29. package/dist-server/server/mcp/modular-server.js +0 -1
  30. package/dist-server/server/mcp/transport.js +0 -1
  31. package/dist-server/server/routes/agent-sdk.js +0 -1
  32. package/dist-server/server/routes/agents.d.ts +9 -5
  33. package/dist-server/server/routes/agents.d.ts.map +1 -1
  34. package/dist-server/server/routes/agents.js +81 -8
  35. package/dist-server/server/routes/auth-codex.js +0 -1
  36. package/dist-server/server/routes/capabilities.js +0 -1
  37. package/dist-server/server/routes/claude-config.js +0 -1
  38. package/dist-server/server/routes/connectors.d.ts.map +1 -1
  39. package/dist-server/server/routes/connectors.js +194 -1
  40. package/dist-server/server/routes/conversations.js +0 -1
  41. package/dist-server/server/routes/embeddings.d.ts.map +1 -1
  42. package/dist-server/server/routes/embeddings.js +16 -2
  43. package/dist-server/server/routes/embeddings.js.map +1 -1
  44. package/dist-server/server/routes/health.d.ts.map +1 -1
  45. package/dist-server/server/routes/health.js +10 -2
  46. package/dist-server/server/routes/health.js.map +1 -1
  47. package/dist-server/server/routes/knowledge.js +0 -1
  48. package/dist-server/server/routes/llm.js +0 -1
  49. package/dist-server/server/routes/mcp-oauth.js +0 -1
  50. package/dist-server/server/routes/mcp.js +0 -1
  51. package/dist-server/server/routes/memory.d.ts +3 -0
  52. package/dist-server/server/routes/memory.d.ts.map +1 -0
  53. package/dist-server/server/routes/memory.js +283 -0
  54. package/dist-server/server/routes/pipeline.js +0 -1
  55. package/dist-server/server/routes/providers.js +0 -1
  56. package/dist-server/server/routes/qualification.d.ts.map +1 -1
  57. package/dist-server/server/routes/qualification.js +382 -74
  58. package/dist-server/server/routes/repo-index.js +0 -1
  59. package/dist-server/server/routes/runtime.js +0 -1
  60. package/dist-server/server/routes/skills-search.d.ts.map +1 -1
  61. package/dist-server/server/routes/skills-search.js +44 -5
  62. package/dist-server/server/routes/skills-search.js.map +1 -1
  63. package/dist-server/server/routes/worktrees.js +0 -1
  64. package/dist-server/server/services/__tests__/embeddingService.test.js +0 -1
  65. package/dist-server/server/services/adapters/postgresAdapter.d.ts +29 -0
  66. package/dist-server/server/services/adapters/postgresAdapter.d.ts.map +1 -0
  67. package/dist-server/server/services/adapters/postgresAdapter.js +224 -0
  68. package/dist-server/server/services/adapters/sqliteAdapter.d.ts +28 -0
  69. package/dist-server/server/services/adapters/sqliteAdapter.d.ts.map +1 -0
  70. package/dist-server/server/services/adapters/sqliteAdapter.js +219 -0
  71. package/dist-server/server/services/adapters/storageAdapter.d.ts +22 -0
  72. package/dist-server/server/services/adapters/storageAdapter.d.ts.map +1 -0
  73. package/dist-server/server/services/adapters/storageAdapter.js +1 -0
  74. package/dist-server/server/services/agentRunner.js +0 -1
  75. package/dist-server/server/services/agentStore.d.ts +18 -3
  76. package/dist-server/server/services/agentStore.d.ts.map +1 -1
  77. package/dist-server/server/services/agentStore.js +116 -23
  78. package/dist-server/server/services/contentStore.js +0 -1
  79. package/dist-server/server/services/embeddingService.d.ts +2 -0
  80. package/dist-server/server/services/embeddingService.d.ts.map +1 -1
  81. package/dist-server/server/services/embeddingService.js +30 -19
  82. package/dist-server/server/services/factExtractor.js +0 -1
  83. package/dist-server/server/services/githubIndexer.js +0 -1
  84. package/dist-server/server/services/mcpOAuth.js +0 -1
  85. package/dist-server/server/services/memoryScorer.js +0 -1
  86. package/dist-server/server/services/repoIndexer.js +0 -1
  87. package/dist-server/server/services/sqliteStore.js +0 -1
  88. package/dist-server/server/services/teamRunner.js +0 -1
  89. package/dist-server/server/services/worktreeManager.js +0 -1
  90. package/dist-server/server/types.d.ts +5 -0
  91. package/dist-server/server/types.d.ts.map +1 -1
  92. package/dist-server/server/types.js +0 -1
  93. package/dist-server/server/utils/pathSecurity.js +0 -1
  94. package/dist-server/src/services/budgetAllocator.js +0 -1
  95. package/dist-server/src/services/contradictionDetector.js +0 -1
  96. package/dist-server/src/services/treeIndexer.js +0 -1
  97. package/dist-server/src/store/knowledgeBase.d.ts +10 -0
  98. package/dist-server/src/store/knowledgeBase.d.ts.map +1 -1
  99. package/dist-server/src/store/knowledgeBase.js +13 -1
  100. package/dist-server/src/store/memoryStore.d.ts +107 -0
  101. package/dist-server/src/store/memoryStore.d.ts.map +1 -0
  102. package/dist-server/src/store/memoryStore.js +263 -0
  103. package/dist-server/tsconfig.server.tsbuildinfo +1 -1
  104. package/package.json +104 -97
  105. package/dist/assets/graphPopulator-DH0qM1Fu.js +0 -1
  106. package/dist/assets/index-B0RRTCSi.css +0 -1
  107. package/dist/assets/index-LWCi_4Hu.js +0 -662
@@ -531,4 +531,3 @@ router.post('/embed', async (req, res) => {
531
531
  }
532
532
  });
533
533
  export default router;
534
- //# sourceMappingURL=knowledge.js.map
@@ -197,4 +197,3 @@ router.post('/chat-tools', async (req, res) => {
197
197
  }
198
198
  });
199
199
  export default router;
200
- //# sourceMappingURL=llm.js.map
@@ -134,4 +134,3 @@ function callbackPage(success, error, serverUrl) {
134
134
  </body>
135
135
  </html>`;
136
136
  }
137
- //# sourceMappingURL=mcp-oauth.js.map
@@ -174,4 +174,3 @@ router.get('/:id/health', (req, res) => {
174
174
  }
175
175
  });
176
176
  export default router;
177
- //# sourceMappingURL=mcp.js.map
@@ -0,0 +1,3 @@
1
+ declare const router: import("express-serve-static-core").Router;
2
+ export default router;
3
+ //# sourceMappingURL=memory.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"memory.d.ts","sourceRoot":"","sources":["../../../server/routes/memory.ts"],"names":[],"mappings":"AASA,QAAA,MAAM,MAAM,4CAAW,CAAC;AAmSxB,eAAe,MAAM,CAAC"}
@@ -0,0 +1,283 @@
1
+ import { Router } from 'express';
2
+ import { SqliteAdapter } from '../services/adapters/sqliteAdapter.js';
3
+ import { PostgresAdapter } from '../services/adapters/postgresAdapter.js';
4
+ import { extractFacts, extractFactsWithLlm } from '../services/factExtractor.js';
5
+ import { rankFacts } from '../services/memoryScorer.js';
6
+ import { readConfig, writeConfig } from '../config.js';
7
+ const router = Router();
8
+ // Global state for the current adapter
9
+ let currentAdapter = null;
10
+ let currentBackend = 'local_sqlite';
11
+ let connectionString = null;
12
+ async function getAdapter() {
13
+ if (!currentAdapter) {
14
+ const config = readConfig();
15
+ const memoryConfig = config.memory || { backend: 'local_sqlite' };
16
+ currentBackend = memoryConfig.backend || 'local_sqlite';
17
+ connectionString = memoryConfig.connectionString || null;
18
+ if (currentBackend === 'postgres' && connectionString) {
19
+ currentAdapter = new PostgresAdapter(connectionString);
20
+ }
21
+ else {
22
+ currentAdapter = new SqliteAdapter();
23
+ }
24
+ await currentAdapter.initialize();
25
+ }
26
+ return currentAdapter;
27
+ }
28
+ async function switchAdapter(backend, connStr) {
29
+ if (currentAdapter) {
30
+ await currentAdapter.close();
31
+ currentAdapter = null;
32
+ }
33
+ currentBackend = backend;
34
+ connectionString = connStr || null;
35
+ if (backend === 'postgres' && connStr) {
36
+ currentAdapter = new PostgresAdapter(connStr);
37
+ }
38
+ else {
39
+ currentAdapter = new SqliteAdapter();
40
+ }
41
+ await currentAdapter.initialize();
42
+ // Save config
43
+ const config = readConfig();
44
+ config.memory = {
45
+ ...config.memory,
46
+ backend,
47
+ ...(connStr && { connectionString: connStr })
48
+ };
49
+ writeConfig(config);
50
+ }
51
+ // GET /api/memory/facts - list facts (with pagination, domain filter)
52
+ router.get('/facts', async (req, res) => {
53
+ try {
54
+ const { domain, limit, offset } = req.query;
55
+ const adapter = await getAdapter();
56
+ const options = {};
57
+ if (domain)
58
+ options.domain = domain;
59
+ if (limit)
60
+ options.limit = parseInt(limit);
61
+ if (offset)
62
+ options.offset = parseInt(offset);
63
+ const facts = await adapter.getFacts(options);
64
+ res.json({ status: 'success', facts });
65
+ }
66
+ catch (error) {
67
+ console.error('[Memory] Failed to get facts:', error);
68
+ res.status(500).json({
69
+ status: 'error',
70
+ error: error instanceof Error ? error.message : 'Unknown error'
71
+ });
72
+ }
73
+ });
74
+ // POST /api/memory/facts - create fact
75
+ router.post('/facts', async (req, res) => {
76
+ try {
77
+ const fact = req.body;
78
+ if (!fact.id || !fact.content) {
79
+ return res.status(400).json({
80
+ status: 'error',
81
+ error: 'Missing required fields: id, content'
82
+ });
83
+ }
84
+ const adapter = await getAdapter();
85
+ await adapter.storeFact(fact);
86
+ res.json({ status: 'success' });
87
+ }
88
+ catch (error) {
89
+ console.error('[Memory] Failed to create fact:', error);
90
+ res.status(500).json({
91
+ status: 'error',
92
+ error: error instanceof Error ? error.message : 'Unknown error'
93
+ });
94
+ }
95
+ });
96
+ // PUT /api/memory/facts/:id - update fact
97
+ router.put('/facts/:id', async (req, res) => {
98
+ try {
99
+ const { id } = req.params;
100
+ const patch = req.body;
101
+ const adapter = await getAdapter();
102
+ await adapter.updateFact(id, patch);
103
+ res.json({ status: 'success' });
104
+ }
105
+ catch (error) {
106
+ console.error('[Memory] Failed to update fact:', error);
107
+ res.status(500).json({
108
+ status: 'error',
109
+ error: error instanceof Error ? error.message : 'Unknown error'
110
+ });
111
+ }
112
+ });
113
+ // DELETE /api/memory/facts/:id - delete fact
114
+ router.delete('/facts/:id', async (req, res) => {
115
+ try {
116
+ const { id } = req.params;
117
+ const adapter = await getAdapter();
118
+ await adapter.deleteFact(id);
119
+ res.json({ status: 'success' });
120
+ }
121
+ catch (error) {
122
+ console.error('[Memory] Failed to delete fact:', error);
123
+ res.status(500).json({
124
+ status: 'error',
125
+ error: error instanceof Error ? error.message : 'Unknown error'
126
+ });
127
+ }
128
+ });
129
+ // POST /api/memory/search - semantic search
130
+ router.post('/search', async (req, res) => {
131
+ try {
132
+ const { query, k } = req.body;
133
+ if (!query) {
134
+ return res.status(400).json({
135
+ status: 'error',
136
+ error: 'Missing required field: query'
137
+ });
138
+ }
139
+ const adapter = await getAdapter();
140
+ const results = await adapter.searchFacts(query, k || 5);
141
+ res.json({ status: 'success', results });
142
+ }
143
+ catch (error) {
144
+ console.error('[Memory] Failed to search facts:', error);
145
+ res.status(500).json({
146
+ status: 'error',
147
+ error: error instanceof Error ? error.message : 'Unknown error'
148
+ });
149
+ }
150
+ });
151
+ // POST /api/memory/extract - call factExtractor on input text
152
+ router.post('/extract', async (req, res) => {
153
+ try {
154
+ const { text, agentId, useLlm, providerId, model } = req.body;
155
+ if (!text || !agentId) {
156
+ return res.status(400).json({
157
+ status: 'error',
158
+ error: 'Missing required fields: text, agentId'
159
+ });
160
+ }
161
+ let facts;
162
+ if (useLlm && providerId && model) {
163
+ facts = await extractFactsWithLlm(text, agentId, providerId, model);
164
+ }
165
+ else {
166
+ facts = extractFacts(text, agentId);
167
+ }
168
+ res.json({ status: 'success', facts });
169
+ }
170
+ catch (error) {
171
+ console.error('[Memory] Failed to extract facts:', error);
172
+ res.status(500).json({
173
+ status: 'error',
174
+ error: error instanceof Error ? error.message : 'Unknown error'
175
+ });
176
+ }
177
+ });
178
+ // POST /api/memory/score - call memoryScorer on facts
179
+ router.post('/score', async (req, res) => {
180
+ try {
181
+ const { facts, query, limit } = req.body;
182
+ if (!facts || !Array.isArray(facts)) {
183
+ return res.status(400).json({
184
+ status: 'error',
185
+ error: 'Missing or invalid required field: facts (array)'
186
+ });
187
+ }
188
+ const scored = rankFacts(facts, query || '', limit);
189
+ res.json({ status: 'success', facts: scored });
190
+ }
191
+ catch (error) {
192
+ console.error('[Memory] Failed to score facts:', error);
193
+ res.status(500).json({
194
+ status: 'error',
195
+ error: error instanceof Error ? error.message : 'Unknown error'
196
+ });
197
+ }
198
+ });
199
+ // GET /api/memory/config - get current backend config
200
+ router.get('/config', (_req, res) => {
201
+ try {
202
+ const config = readConfig();
203
+ const memoryConfig = config.memory || { backend: 'local_sqlite' };
204
+ res.json({
205
+ status: 'success',
206
+ config: {
207
+ ...memoryConfig,
208
+ backend: currentBackend,
209
+ connectionString: currentBackend === 'postgres' ? connectionString : undefined
210
+ }
211
+ });
212
+ }
213
+ catch (error) {
214
+ console.error('[Memory] Failed to get config:', error);
215
+ res.status(500).json({
216
+ status: 'error',
217
+ error: error instanceof Error ? error.message : 'Unknown error'
218
+ });
219
+ }
220
+ });
221
+ // POST /api/memory/config - set backend config (store type, connection string)
222
+ router.post('/config', async (req, res) => {
223
+ try {
224
+ const { backend, connectionString: connStr } = req.body;
225
+ if (!backend) {
226
+ return res.status(400).json({
227
+ status: 'error',
228
+ error: 'Missing required field: backend'
229
+ });
230
+ }
231
+ if (backend === 'postgres' && !connStr) {
232
+ return res.status(400).json({
233
+ status: 'error',
234
+ error: 'PostgreSQL backend requires connectionString'
235
+ });
236
+ }
237
+ // Test connection before switching
238
+ let testAdapter;
239
+ if (backend === 'postgres') {
240
+ testAdapter = new PostgresAdapter(connStr);
241
+ }
242
+ else {
243
+ testAdapter = new SqliteAdapter();
244
+ }
245
+ try {
246
+ await testAdapter.initialize();
247
+ await testAdapter.getHealth();
248
+ await testAdapter.close();
249
+ }
250
+ catch (testError) {
251
+ return res.status(400).json({
252
+ status: 'error',
253
+ error: `Failed to connect to ${backend}: ${testError instanceof Error ? testError.message : 'Unknown error'}`
254
+ });
255
+ }
256
+ await switchAdapter(backend, connStr);
257
+ res.json({ status: 'success' });
258
+ }
259
+ catch (error) {
260
+ console.error('[Memory] Failed to set config:', error);
261
+ res.status(500).json({
262
+ status: 'error',
263
+ error: error instanceof Error ? error.message : 'Unknown error'
264
+ });
265
+ }
266
+ });
267
+ // GET /api/memory/health - backend health check (never 500 — always returns a health object)
268
+ router.get('/health', async (_req, res) => {
269
+ try {
270
+ const adapter = await getAdapter();
271
+ const health = await adapter.getHealth();
272
+ res.json({ status: 'success', health, backend: currentBackend });
273
+ }
274
+ catch (error) {
275
+ // Return 200 with degraded health — don't 500 or the frontend will loop
276
+ res.json({
277
+ status: 'success',
278
+ health: { status: 'unavailable', factCount: 0, error: error instanceof Error ? error.message : 'Adapter init failed' },
279
+ backend: currentBackend
280
+ });
281
+ }
282
+ });
283
+ export default router;
@@ -480,4 +480,3 @@ router.post('/assemble', async (req, res) => {
480
480
  }
481
481
  });
482
482
  export default router;
483
- //# sourceMappingURL=pipeline.js.map
@@ -201,4 +201,3 @@ router.post('/:id/test', async (req, res) => {
201
201
  }
202
202
  });
203
203
  export default router;
204
- //# sourceMappingURL=providers.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"qualification.d.ts","sourceRoot":"","sources":["../../../server/routes/qualification.ts"],"names":[],"mappings":"AAIA,QAAA,MAAM,MAAM,4CAAW,CAAC;AA2LxB,eAAe,MAAM,CAAC"}
1
+ {"version":3,"file":"qualification.d.ts","sourceRoot":"","sources":["../../../server/routes/qualification.ts"],"names":[],"mappings":"AAKA,QAAA,MAAM,MAAM,4CAAW,CAAC;AAijBxB,eAAe,MAAM,CAAC"}