@bytespell/shella 0.1.3 → 0.1.4
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.
- package/README.md +1 -1
- package/bin/cli.js +153 -82
- package/dev/cli.tsx +26 -0
- package/dist/config/openai-codex-models.json +205 -0
- package/dist/server/index.d.ts +4 -2
- package/dist/server/index.js +66 -8
- package/dist/server/lib/opencode-client.d.ts +14 -0
- package/dist/server/lib/opencode-client.js +17 -0
- package/dist/server/lib/opencode-config.d.ts +14 -0
- package/dist/server/lib/opencode-config.js +25 -0
- package/dist/server/routes/config.d.ts +12 -0
- package/dist/server/routes/config.js +207 -0
- package/dist/server/routes/init.d.ts +4 -3
- package/dist/server/routes/init.js +23 -9
- package/dist/server/routes/local-llm.d.ts +8 -0
- package/dist/server/routes/local-llm.js +255 -0
- package/dist/server/routes/logs.js +35 -11
- package/dist/server/routes/prompt.d.ts +16 -0
- package/dist/server/routes/prompt.js +173 -0
- package/dist/server/routes/session.d.ts +8 -0
- package/dist/server/routes/session.js +63 -0
- package/dist/server/routes/status.d.ts +9 -0
- package/dist/server/routes/status.js +54 -0
- package/dist/server/routes/usage.d.ts +12 -0
- package/dist/server/routes/usage.js +60 -0
- package/dist/server/routes/windows.js +4 -4
- package/dist/server/schema.d.ts +47 -16
- package/dist/server/schema.js +8 -1
- package/dist/server/services/database.d.ts +10 -1
- package/dist/server/services/database.js +19 -6
- package/dist/web/assets/{_baseUniq-BXqY9Mam.js → _baseUniq-6T01QAux.js} +1 -1
- package/dist/web/assets/{arc-Bn6tUpO_.js → arc-BkH3TPJb.js} +1 -1
- package/dist/web/assets/{architectureDiagram-VXUJARFQ-C7FAApUY.js → architectureDiagram-VXUJARFQ-BSi6BLCC.js} +1 -1
- package/dist/web/assets/{blockDiagram-VD42YOAC-C2fdaEWa.js → blockDiagram-VD42YOAC-QSPUbinO.js} +1 -1
- package/dist/web/assets/{c4Diagram-YG6GDRKO-FEVzhARQ.js → c4Diagram-YG6GDRKO-Cya_BihR.js} +1 -1
- package/dist/web/assets/channel-DGAtS-pa.js +1 -0
- package/dist/web/assets/{chunk-4BX2VUAB-DLekcSAU.js → chunk-4BX2VUAB-DIL6eizv.js} +1 -1
- package/dist/web/assets/{chunk-55IACEB6-8hFRjyTP.js → chunk-55IACEB6-CgwejoZz.js} +1 -1
- package/dist/web/assets/{chunk-B4BG7PRW-DULC9-MQ.js → chunk-B4BG7PRW-9mIPqoGe.js} +1 -1
- package/dist/web/assets/{chunk-DI55MBZ5-DuOE5RH1.js → chunk-DI55MBZ5-BRbyRfgT.js} +1 -1
- package/dist/web/assets/{chunk-FMBD7UC4-DaDNiCk7.js → chunk-FMBD7UC4-CVBT25Fj.js} +1 -1
- package/dist/web/assets/{chunk-QN33PNHL-CKshfIHj.js → chunk-QN33PNHL-rTj-WT2G.js} +1 -1
- package/dist/web/assets/{chunk-QZHKN3VN-D2Qy0tdi.js → chunk-QZHKN3VN-BaUBiHya.js} +1 -1
- package/dist/web/assets/{chunk-TZMSLE5B-SPxkj-lp.js → chunk-TZMSLE5B-C4_O5TI-.js} +1 -1
- package/dist/web/assets/classDiagram-2ON5EDUG-DLvlUUJq.js +1 -0
- package/dist/web/assets/classDiagram-v2-WZHVMYZB-DLvlUUJq.js +1 -0
- package/dist/web/assets/clone-BZW2JABw.js +1 -0
- package/dist/web/assets/{code-block-QI2IAROF-BZdAQmZ2.js → code-block-QI2IAROF-Bj_2OIYt.js} +1 -1
- package/dist/web/assets/{cose-bilkent-S5V4N54A-DbasixUk.js → cose-bilkent-S5V4N54A-T7a1luWi.js} +1 -1
- package/dist/web/assets/{dagre-6UL2VRFP-CStyjTc9.js → dagre-6UL2VRFP-CeH5ZsdW.js} +1 -1
- package/dist/web/assets/{diagram-PSM6KHXK-Crk93U8d.js → diagram-PSM6KHXK-Cdod2Lna.js} +1 -1
- package/dist/web/assets/{diagram-QEK2KX5R-DiW6RNbg.js → diagram-QEK2KX5R-CYks2r54.js} +1 -1
- package/dist/web/assets/{diagram-S2PKOQOG-CKksz_qL.js → diagram-S2PKOQOG-DCmy0g7p.js} +1 -1
- package/dist/web/assets/{erDiagram-Q2GNP2WA-CisACqqq.js → erDiagram-Q2GNP2WA-Dlz1bNvI.js} +1 -1
- package/dist/web/assets/{flowDiagram-NV44I4VS-BBp_5zAe.js → flowDiagram-NV44I4VS-Di5Iit1B.js} +1 -1
- package/dist/web/assets/{ganttDiagram-JELNMOA3-BKZ30gLA.js → ganttDiagram-JELNMOA3-9i1dugg-.js} +1 -1
- package/dist/web/assets/{gitGraphDiagram-NY62KEGX-ClizxUXq.js → gitGraphDiagram-NY62KEGX-BORbMVri.js} +1 -1
- package/dist/web/assets/{graph-DqhaNOTU.js → graph-C0SCKxbQ.js} +1 -1
- package/dist/web/assets/index-CYVJT8rN.js +1 -0
- package/dist/web/assets/index-CcAJUkQw.css +1 -0
- package/dist/web/assets/index-CcDdxbB-.js +1719 -0
- package/dist/web/assets/{infoDiagram-WHAUD3N6-BQwNR0md.js → infoDiagram-WHAUD3N6-7ohMQFLY.js} +1 -1
- package/dist/web/assets/{journeyDiagram-XKPGCS4Q-YOqPPID4.js → journeyDiagram-XKPGCS4Q-DZp7Z7wE.js} +1 -1
- package/dist/web/assets/{kanban-definition-3W4ZIXB7-Dtu8bvBx.js → kanban-definition-3W4ZIXB7-BCNLCm54.js} +1 -1
- package/dist/web/assets/{layout-Cc1ESzTe.js → layout-AUnZuY21.js} +1 -1
- package/dist/web/assets/{linear-BwI2ANFG.js → linear-B0bfAqGt.js} +1 -1
- package/dist/web/assets/{mermaid.core-npIGP8NS.js → mermaid.core-D5fXNCxA.js} +5 -5
- package/dist/web/assets/{min--MKscDc6.js → min-BZUFOEEw.js} +1 -1
- package/dist/web/assets/{mindmap-definition-VGOIOE7T-Cr39Vhym.js → mindmap-definition-VGOIOE7T-hEGJLJ8N.js} +1 -1
- package/dist/web/assets/{pieDiagram-ADFJNKIX-Cv8ke00t.js → pieDiagram-ADFJNKIX-BRpCTJIO.js} +1 -1
- package/dist/web/assets/{quadrantDiagram-AYHSOK5B-BPhHaTg8.js → quadrantDiagram-AYHSOK5B-m7jaiHQb.js} +1 -1
- package/dist/web/assets/{requirementDiagram-UZGBJVZJ-Cc42SoK0.js → requirementDiagram-UZGBJVZJ-Coh9g9Sp.js} +1 -1
- package/dist/web/assets/{sankeyDiagram-TZEHDZUN-CtgBuq8T.js → sankeyDiagram-TZEHDZUN-CrD_kUGR.js} +1 -1
- package/dist/web/assets/{sequenceDiagram-WL72ISMW-B9lNGN6V.js → sequenceDiagram-WL72ISMW-C04yD1EI.js} +1 -1
- package/dist/web/assets/{stateDiagram-FKZM4ZOC-C3dRTOMb.js → stateDiagram-FKZM4ZOC-DhP-DMZW.js} +1 -1
- package/dist/web/assets/stateDiagram-v2-4FDKWEC3-DWi5vrD6.js +1 -0
- package/dist/web/assets/{timeline-definition-IT6M3QCI-CXhSuTlt.js → timeline-definition-IT6M3QCI-40iW2p_5.js} +1 -1
- package/dist/web/assets/{treemap-KMMF4GRG-Csy25Uov.js → treemap-KMMF4GRG-BnxWQbzt.js} +1 -1
- package/dist/web/assets/welcome-screen-test-CLeWuIqq.js +1 -0
- package/dist/web/assets/{xychartDiagram-PRI3JC2R-CxEERqse.js → xychartDiagram-PRI3JC2R-D6lcJDCc.js} +1 -1
- package/dist/web/index.html +3 -3
- package/package.json +14 -5
- package/dist/web/assets/channel-CxjnQtV7.js +0 -1
- package/dist/web/assets/classDiagram-2ON5EDUG-CVG91-fs.js +0 -1
- package/dist/web/assets/classDiagram-v2-WZHVMYZB-CVG91-fs.js +0 -1
- package/dist/web/assets/clone-C7jxvixc.js +0 -1
- package/dist/web/assets/index-B0jWvqrS.css +0 -1
- package/dist/web/assets/index-Dnmavb3d.js +0 -1716
- package/dist/web/assets/stateDiagram-v2-4FDKWEC3-oHTO1yj_.js +0 -1
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Usage Limits API Routes
|
|
3
|
+
*
|
|
4
|
+
* Fetches AI provider usage data.
|
|
5
|
+
* Uses @bytespell/model-provider-usage-limits for the heavy lifting.
|
|
6
|
+
*
|
|
7
|
+
* Note: Routing is now handled server-side in prompt.ts.
|
|
8
|
+
* Usage data is also included in the config response.
|
|
9
|
+
* This endpoint is kept for debugging/manual refresh.
|
|
10
|
+
*/
|
|
11
|
+
import { Router } from 'express';
|
|
12
|
+
import { getUsage, detectAuthTokens } from '@bytespell/model-provider-usage-limits';
|
|
13
|
+
const router = Router();
|
|
14
|
+
/**
|
|
15
|
+
* GET /usage
|
|
16
|
+
*
|
|
17
|
+
* Fetch usage data for all authenticated providers.
|
|
18
|
+
* Auto-detects tokens from OpenCode's auth.json.
|
|
19
|
+
*
|
|
20
|
+
* Query params:
|
|
21
|
+
* - bypass_cache: "true" to skip cache
|
|
22
|
+
*/
|
|
23
|
+
router.get('/usage', async (req, res) => {
|
|
24
|
+
const bypassCache = req.query.bypass_cache === 'true';
|
|
25
|
+
console.log(`[usage] GET /usage (bypass_cache=${bypassCache})`);
|
|
26
|
+
try {
|
|
27
|
+
// Check what tokens are available (for logging)
|
|
28
|
+
const tokens = detectAuthTokens();
|
|
29
|
+
const tokenProviders = Object.keys(tokens);
|
|
30
|
+
console.log(`[usage] Detected tokens for: ${tokenProviders.join(', ') || 'none'}`);
|
|
31
|
+
if (tokenProviders.length === 0) {
|
|
32
|
+
console.log(`[usage] No provider tokens available`);
|
|
33
|
+
res.json({ providers: {}, message: 'No authenticated providers found' });
|
|
34
|
+
return;
|
|
35
|
+
}
|
|
36
|
+
const results = await getUsage({
|
|
37
|
+
autoDetectAuthTokens: true,
|
|
38
|
+
bypassCache,
|
|
39
|
+
});
|
|
40
|
+
const providerCount = Object.keys(results).length;
|
|
41
|
+
console.log(`[usage] Fetched usage for ${providerCount} provider(s)`);
|
|
42
|
+
// Log summary for each provider
|
|
43
|
+
for (const [provider, result] of Object.entries(results)) {
|
|
44
|
+
if (result?.data?.primary) {
|
|
45
|
+
const { usedPercent, paceDelta, window } = result.data.primary;
|
|
46
|
+
console.log(`[usage] ${provider}: ${usedPercent.toFixed(1)}% used (${window}), pace: ${paceDelta ?? 'n/a'}%`);
|
|
47
|
+
}
|
|
48
|
+
else if (result?.error) {
|
|
49
|
+
console.log(`[usage] ${provider}: error - ${result.error.message}`);
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
res.json({ providers: results });
|
|
53
|
+
}
|
|
54
|
+
catch (error) {
|
|
55
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
56
|
+
console.error(`[usage] Error fetching usage:`, message);
|
|
57
|
+
res.status(500).json({ error: message });
|
|
58
|
+
}
|
|
59
|
+
});
|
|
60
|
+
export default router;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { Router } from 'express';
|
|
2
2
|
import { eq } from 'drizzle-orm';
|
|
3
|
-
import { getDatabase } from '../services/database.js';
|
|
3
|
+
import { getDatabase, saveDatabase } from '../services/database.js';
|
|
4
4
|
import { windows } from '../schema.js';
|
|
5
5
|
import { setupSSE, sendSSE, addWindowClient, removeWindowClient, broadcastWindowEvent, } from '../services/sse-manager.js';
|
|
6
6
|
const router = Router();
|
|
@@ -38,7 +38,6 @@ router.post('/windows', async (req, res) => {
|
|
|
38
38
|
id: body.id,
|
|
39
39
|
directoryId: body.directoryId,
|
|
40
40
|
rootSessionId: body.rootSessionId ?? null,
|
|
41
|
-
activeSessionId: body.activeSessionId ?? null,
|
|
42
41
|
lastActiveAt: body.lastActiveAt ?? body.createdAt, // Default to createdAt
|
|
43
42
|
agent: body.agent ?? null,
|
|
44
43
|
modelProvider: body.modelProvider ?? null,
|
|
@@ -47,6 +46,7 @@ router.post('/windows', async (req, res) => {
|
|
|
47
46
|
createdAt: body.createdAt,
|
|
48
47
|
};
|
|
49
48
|
db.insert(windows).values(newWindow).run();
|
|
49
|
+
saveDatabase(); // Persist immediately to avoid data loss on restart
|
|
50
50
|
const created = db.select().from(windows).where(eq(windows.id, body.id)).get();
|
|
51
51
|
broadcastWindowEvent({ type: 'window:created', window: created, sourceClientId: clientId });
|
|
52
52
|
res.json(created);
|
|
@@ -78,8 +78,6 @@ router.patch('/windows/:id', async (req, res) => {
|
|
|
78
78
|
const updates = {};
|
|
79
79
|
if (body.rootSessionId !== undefined)
|
|
80
80
|
updates.rootSessionId = body.rootSessionId;
|
|
81
|
-
if (body.activeSessionId !== undefined)
|
|
82
|
-
updates.activeSessionId = body.activeSessionId;
|
|
83
81
|
if (body.lastActiveAt !== undefined)
|
|
84
82
|
updates.lastActiveAt = body.lastActiveAt;
|
|
85
83
|
if (body.agent !== undefined)
|
|
@@ -92,6 +90,7 @@ router.patch('/windows/:id', async (req, res) => {
|
|
|
92
90
|
updates.label = body.label;
|
|
93
91
|
if (Object.keys(updates).length > 0) {
|
|
94
92
|
db.update(windows).set(updates).where(eq(windows.id, windowId)).run();
|
|
93
|
+
saveDatabase(); // Persist immediately to avoid data loss on restart
|
|
95
94
|
}
|
|
96
95
|
const updated = db.select().from(windows).where(eq(windows.id, windowId)).get();
|
|
97
96
|
broadcastWindowEvent({ type: 'window:updated', window: updated, sourceClientId: clientId });
|
|
@@ -114,6 +113,7 @@ router.delete('/windows/:id', async (req, res) => {
|
|
|
114
113
|
return;
|
|
115
114
|
}
|
|
116
115
|
db.delete(windows).where(eq(windows.id, windowId)).run();
|
|
116
|
+
saveDatabase(); // Persist immediately to avoid data loss on restart
|
|
117
117
|
broadcastWindowEvent({ type: 'window:deleted', windowId, sourceClientId: clientId });
|
|
118
118
|
res.json({ ok: true });
|
|
119
119
|
}
|
package/dist/server/schema.d.ts
CHANGED
|
@@ -64,8 +64,8 @@ export declare const windows: import("drizzle-orm/sqlite-core").SQLiteTableWithC
|
|
|
64
64
|
}, {}, {
|
|
65
65
|
length: number | undefined;
|
|
66
66
|
}>;
|
|
67
|
-
|
|
68
|
-
name: "
|
|
67
|
+
lastActiveAt: import("drizzle-orm/sqlite-core").SQLiteColumn<{
|
|
68
|
+
name: "last_active_at";
|
|
69
69
|
tableName: "windows";
|
|
70
70
|
dataType: "string";
|
|
71
71
|
columnType: "SQLiteText";
|
|
@@ -83,8 +83,8 @@ export declare const windows: import("drizzle-orm/sqlite-core").SQLiteTableWithC
|
|
|
83
83
|
}, {}, {
|
|
84
84
|
length: number | undefined;
|
|
85
85
|
}>;
|
|
86
|
-
|
|
87
|
-
name: "
|
|
86
|
+
agent: import("drizzle-orm/sqlite-core").SQLiteColumn<{
|
|
87
|
+
name: "agent";
|
|
88
88
|
tableName: "windows";
|
|
89
89
|
dataType: "string";
|
|
90
90
|
columnType: "SQLiteText";
|
|
@@ -102,8 +102,8 @@ export declare const windows: import("drizzle-orm/sqlite-core").SQLiteTableWithC
|
|
|
102
102
|
}, {}, {
|
|
103
103
|
length: number | undefined;
|
|
104
104
|
}>;
|
|
105
|
-
|
|
106
|
-
name: "
|
|
105
|
+
modelProvider: import("drizzle-orm/sqlite-core").SQLiteColumn<{
|
|
106
|
+
name: "model_provider";
|
|
107
107
|
tableName: "windows";
|
|
108
108
|
dataType: "string";
|
|
109
109
|
columnType: "SQLiteText";
|
|
@@ -121,8 +121,8 @@ export declare const windows: import("drizzle-orm/sqlite-core").SQLiteTableWithC
|
|
|
121
121
|
}, {}, {
|
|
122
122
|
length: number | undefined;
|
|
123
123
|
}>;
|
|
124
|
-
|
|
125
|
-
name: "
|
|
124
|
+
modelId: import("drizzle-orm/sqlite-core").SQLiteColumn<{
|
|
125
|
+
name: "model_id";
|
|
126
126
|
tableName: "windows";
|
|
127
127
|
dataType: "string";
|
|
128
128
|
columnType: "SQLiteText";
|
|
@@ -140,8 +140,8 @@ export declare const windows: import("drizzle-orm/sqlite-core").SQLiteTableWithC
|
|
|
140
140
|
}, {}, {
|
|
141
141
|
length: number | undefined;
|
|
142
142
|
}>;
|
|
143
|
-
|
|
144
|
-
name: "
|
|
143
|
+
label: import("drizzle-orm/sqlite-core").SQLiteColumn<{
|
|
144
|
+
name: "label";
|
|
145
145
|
tableName: "windows";
|
|
146
146
|
dataType: "string";
|
|
147
147
|
columnType: "SQLiteText";
|
|
@@ -159,14 +159,14 @@ export declare const windows: import("drizzle-orm/sqlite-core").SQLiteTableWithC
|
|
|
159
159
|
}, {}, {
|
|
160
160
|
length: number | undefined;
|
|
161
161
|
}>;
|
|
162
|
-
|
|
163
|
-
name: "
|
|
162
|
+
createdAt: import("drizzle-orm/sqlite-core").SQLiteColumn<{
|
|
163
|
+
name: "created_at";
|
|
164
164
|
tableName: "windows";
|
|
165
165
|
dataType: "string";
|
|
166
166
|
columnType: "SQLiteText";
|
|
167
167
|
data: string;
|
|
168
168
|
driverParam: string;
|
|
169
|
-
notNull:
|
|
169
|
+
notNull: true;
|
|
170
170
|
hasDefault: false;
|
|
171
171
|
isPrimaryKey: false;
|
|
172
172
|
isAutoincrement: false;
|
|
@@ -178,9 +178,39 @@ export declare const windows: import("drizzle-orm/sqlite-core").SQLiteTableWithC
|
|
|
178
178
|
}, {}, {
|
|
179
179
|
length: number | undefined;
|
|
180
180
|
}>;
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
181
|
+
};
|
|
182
|
+
dialect: "sqlite";
|
|
183
|
+
}>;
|
|
184
|
+
/**
|
|
185
|
+
* Settings table - simple key-value store for app-level settings.
|
|
186
|
+
* Used for tracking server configuration state (e.g., has user completed onboarding).
|
|
187
|
+
*/
|
|
188
|
+
export declare const settings: import("drizzle-orm/sqlite-core").SQLiteTableWithColumns<{
|
|
189
|
+
name: "settings";
|
|
190
|
+
schema: undefined;
|
|
191
|
+
columns: {
|
|
192
|
+
key: import("drizzle-orm/sqlite-core").SQLiteColumn<{
|
|
193
|
+
name: "key";
|
|
194
|
+
tableName: "settings";
|
|
195
|
+
dataType: "string";
|
|
196
|
+
columnType: "SQLiteText";
|
|
197
|
+
data: string;
|
|
198
|
+
driverParam: string;
|
|
199
|
+
notNull: true;
|
|
200
|
+
hasDefault: false;
|
|
201
|
+
isPrimaryKey: true;
|
|
202
|
+
isAutoincrement: false;
|
|
203
|
+
hasRuntimeDefault: false;
|
|
204
|
+
enumValues: [string, ...string[]];
|
|
205
|
+
baseColumn: never;
|
|
206
|
+
identity: undefined;
|
|
207
|
+
generated: undefined;
|
|
208
|
+
}, {}, {
|
|
209
|
+
length: number | undefined;
|
|
210
|
+
}>;
|
|
211
|
+
value: import("drizzle-orm/sqlite-core").SQLiteColumn<{
|
|
212
|
+
name: "value";
|
|
213
|
+
tableName: "settings";
|
|
184
214
|
dataType: "string";
|
|
185
215
|
columnType: "SQLiteText";
|
|
186
216
|
data: string;
|
|
@@ -202,3 +232,4 @@ export declare const windows: import("drizzle-orm/sqlite-core").SQLiteTableWithC
|
|
|
202
232
|
}>;
|
|
203
233
|
export type Window = typeof windows.$inferSelect;
|
|
204
234
|
export type NewWindow = typeof windows.$inferInsert;
|
|
235
|
+
export type Setting = typeof settings.$inferSelect;
|
package/dist/server/schema.js
CHANGED
|
@@ -8,7 +8,6 @@ export const windows = sqliteTable('windows', {
|
|
|
8
8
|
id: text('id').primaryKey(),
|
|
9
9
|
directoryId: text('directory_id').notNull(),
|
|
10
10
|
rootSessionId: text('root_session_id'), // The topmost session (never a subagent)
|
|
11
|
-
activeSessionId: text('active_session_id'), // Currently viewed session (root or subagent)
|
|
12
11
|
lastActiveAt: text('last_active_at'), // Timestamp for cross-device active window sync
|
|
13
12
|
agent: text('agent'),
|
|
14
13
|
modelProvider: text('model_provider'),
|
|
@@ -16,3 +15,11 @@ export const windows = sqliteTable('windows', {
|
|
|
16
15
|
label: text('label'),
|
|
17
16
|
createdAt: text('created_at').notNull(),
|
|
18
17
|
});
|
|
18
|
+
/**
|
|
19
|
+
* Settings table - simple key-value store for app-level settings.
|
|
20
|
+
* Used for tracking server configuration state (e.g., has user completed onboarding).
|
|
21
|
+
*/
|
|
22
|
+
export const settings = sqliteTable('settings', {
|
|
23
|
+
key: text('key').primaryKey(),
|
|
24
|
+
value: text('value').notNull(),
|
|
25
|
+
});
|
|
@@ -1,5 +1,14 @@
|
|
|
1
1
|
declare const CONFIG_DIR: string;
|
|
2
2
|
declare const STATE_DIR: string;
|
|
3
|
+
/**
|
|
4
|
+
* Save the in-memory database to disk.
|
|
5
|
+
* sql.js is in-memory, so we need to manually persist.
|
|
6
|
+
*/
|
|
7
|
+
declare function saveDatabase(): void;
|
|
3
8
|
export declare function getDatabase(): Promise<import("drizzle-orm/sql-js").SQLJsDatabase<Record<string, unknown>>>;
|
|
4
9
|
export declare function getDatabaseSync(): import("drizzle-orm/sql-js").SQLJsDatabase<Record<string, unknown>>;
|
|
5
|
-
|
|
10
|
+
/**
|
|
11
|
+
* Force an immediate save to disk.
|
|
12
|
+
* Call this after mutations to ensure durability.
|
|
13
|
+
*/
|
|
14
|
+
export { saveDatabase, STATE_DIR, CONFIG_DIR };
|
|
@@ -3,9 +3,12 @@ import fs from 'fs';
|
|
|
3
3
|
import os from 'os';
|
|
4
4
|
import initSqlJs from 'sql.js';
|
|
5
5
|
import { drizzle } from 'drizzle-orm/sql-js';
|
|
6
|
-
import { windows } from '../schema.js';
|
|
7
|
-
// Database location: ~/.config/shella/
|
|
8
|
-
|
|
6
|
+
import { windows, settings } from '../schema.js';
|
|
7
|
+
// Database location: SHELLA_DATA_DIR env var, or ~/.config/shella/ by default
|
|
8
|
+
// Read env directly to avoid circular dependency with server/index.ts
|
|
9
|
+
const CONFIG_DIR = process.env.SHELLA_DATA_DIR
|
|
10
|
+
? path.resolve(process.env.SHELLA_DATA_DIR)
|
|
11
|
+
: path.join(os.homedir(), '.config', 'shella');
|
|
9
12
|
const STATE_DIR = CONFIG_DIR;
|
|
10
13
|
const DB_FILE = path.join(STATE_DIR, 'shella.db');
|
|
11
14
|
// Singleton database instance
|
|
@@ -64,7 +67,7 @@ async function initDatabase() {
|
|
|
64
67
|
// Load existing database or create new one
|
|
65
68
|
const fileBuffer = fs.existsSync(DB_FILE) ? fs.readFileSync(DB_FILE) : undefined;
|
|
66
69
|
sqlite = new SQL.Database(fileBuffer);
|
|
67
|
-
// Create
|
|
70
|
+
// Create tables if not exist
|
|
68
71
|
sqlite.run(`
|
|
69
72
|
CREATE TABLE IF NOT EXISTS windows (
|
|
70
73
|
id TEXT PRIMARY KEY,
|
|
@@ -78,12 +81,18 @@ async function initDatabase() {
|
|
|
78
81
|
label TEXT,
|
|
79
82
|
created_at TEXT NOT NULL
|
|
80
83
|
)
|
|
84
|
+
`);
|
|
85
|
+
sqlite.run(`
|
|
86
|
+
CREATE TABLE IF NOT EXISTS settings (
|
|
87
|
+
key TEXT PRIMARY KEY,
|
|
88
|
+
value TEXT NOT NULL
|
|
89
|
+
)
|
|
81
90
|
`);
|
|
82
91
|
// Set up periodic persistence
|
|
83
92
|
setupPersistence();
|
|
84
93
|
// Save immediately
|
|
85
94
|
saveDatabase();
|
|
86
|
-
return drizzle(sqlite, { schema: { windows } });
|
|
95
|
+
return drizzle(sqlite, { schema: { windows, settings } });
|
|
87
96
|
}
|
|
88
97
|
// Promise to track initialization
|
|
89
98
|
let initPromise = null;
|
|
@@ -107,4 +116,8 @@ export function getDatabaseSync() {
|
|
|
107
116
|
}
|
|
108
117
|
return db;
|
|
109
118
|
}
|
|
110
|
-
|
|
119
|
+
/**
|
|
120
|
+
* Force an immediate save to disk.
|
|
121
|
+
* Call this after mutations to ensure durability.
|
|
122
|
+
*/
|
|
123
|
+
export { saveDatabase, STATE_DIR, CONFIG_DIR };
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{aU as L,bi as ln,aE as A,aS as v,bj as gn,bk as dn,aD as W,bl as hn,bm as z,bn as pn,bo as An,bp as m,aV as N,a_ as U,b1 as T,bq as _n,aY as on,br as wn,bs as On,aF as V,bt as Pn,bu as I}from"./mermaid.core-
|
|
1
|
+
import{aU as L,bi as ln,aE as A,aS as v,bj as gn,bk as dn,aD as W,bl as hn,bm as z,bn as pn,bo as An,bp as m,aV as N,a_ as U,b1 as T,bq as _n,aY as on,br as wn,bs as On,aF as V,bt as Pn,bu as I}from"./mermaid.core-D5fXNCxA.js";var vn="[object Symbol]";function x(n){return typeof n=="symbol"||L(n)&&ln(n)==vn}function yn(n,r){for(var e=-1,i=n==null?0:n.length,f=Array(i);++e<i;)f[e]=r(n[e],e,n);return f}var B=v?v.prototype:void 0,K=B?B.toString:void 0;function k(n){if(typeof n=="string")return n;if(A(n))return yn(n,k)+"";if(x(n))return K?K.call(n):"";var r=n+"";return r=="0"&&1/n==-1/0?"-0":r}function En(){}function bn(n,r){for(var e=-1,i=n==null?0:n.length;++e<i&&r(n[e],e,n)!==!1;);return n}function cn(n,r,e,i){for(var f=n.length,t=e+-1;++t<f;)if(r(n[t],t,n))return t;return-1}function Tn(n){return n!==n}function Rn(n,r,e){for(var i=e-1,f=n.length;++i<f;)if(n[i]===r)return i;return-1}function In(n,r,e){return r===r?Rn(n,r,e):cn(n,Tn,e)}function Sn(n,r){var e=n==null?0:n.length;return!!e&&In(n,r,0)>-1}function M(n){return W(n)?gn(n):dn(n)}var Ln=/\.|\[(?:[^[\]]*|(["'])(?:(?!\1)[^\\]|\\.)*?\1)\]/,xn=/^\w*$/;function $(n,r){if(A(n))return!1;var e=typeof n;return e=="number"||e=="symbol"||e=="boolean"||n==null||x(n)?!0:xn.test(n)||!Ln.test(n)||r!=null&&n in Object(r)}var Mn=500;function $n(n){var r=hn(n,function(i){return e.size===Mn&&e.clear(),i}),e=r.cache;return r}var Cn=/[^.[\]]+|\[(?:(-?\d+(?:\.\d+)?)|(["'])((?:(?!\2)[^\\]|\\.)*?)\2)\]|(?=(?:\.|\[\])(?:\.|\[\]|$))/g,Dn=/\\(\\)?/g,Fn=$n(function(n){var r=[];return n.charCodeAt(0)===46&&r.push(""),n.replace(Cn,function(e,i,f,t){r.push(f?t.replace(Dn,"$1"):i||e)}),r});function Gn(n){return n==null?"":k(n)}function j(n,r){return A(n)?n:$(n,r)?[n]:Fn(Gn(n))}function R(n){if(typeof n=="string"||x(n))return n;var r=n+"";return r=="0"&&1/n==-1/0?"-0":r}function nn(n,r){r=j(r,n);for(var e=0,i=r.length;n!=null&&e<i;)n=n[R(r[e++])];return e&&e==i?n:void 0}function mn(n,r,e){var i=n==null?void 0:nn(n,r);return i===void 0?e:i}function rn(n,r){for(var e=-1,i=r.length,f=n.length;++e<i;)n[f+e]=r[e];return n}var H=v?v.isConcatSpreadable:void 0;function Nn(n){return A(n)||z(n)||!!(H&&n&&n[H])}function Hr(n,r,e,i,f){var t=-1,s=n.length;for(e||(e=Nn),f||(f=[]);++t<s;){var u=n[t];e(u)?rn(f,u):i||(f[f.length]=u)}return f}function Un(n,r,e,i){var f=-1,t=n==null?0:n.length;for(i&&t&&(e=n[++f]);++f<t;)e=r(e,n[f],f,n);return e}function en(n,r){for(var e=-1,i=n==null?0:n.length,f=0,t=[];++e<i;){var s=n[e];r(s,e,n)&&(t[f++]=s)}return t}function Bn(){return[]}var Kn=Object.prototype,Hn=Kn.propertyIsEnumerable,q=Object.getOwnPropertySymbols,qn=q?function(n){return n==null?[]:(n=Object(n),en(q(n),function(r){return Hn.call(n,r)}))}:Bn;function Yn(n,r,e){var i=r(n);return A(n)?i:rn(i,e(n))}function Y(n){return Yn(n,M,qn)}var Zn="__lodash_hash_undefined__";function Xn(n){return this.__data__.set(n,Zn),this}function Jn(n){return this.__data__.has(n)}function y(n){var r=-1,e=n==null?0:n.length;for(this.__data__=new pn;++r<e;)this.add(n[r])}y.prototype.add=y.prototype.push=Xn;y.prototype.has=Jn;function Qn(n,r){for(var e=-1,i=n==null?0:n.length;++e<i;)if(r(n[e],e,n))return!0;return!1}function tn(n,r){return n.has(r)}var Wn=1,zn=2;function fn(n,r,e,i,f,t){var s=e&Wn,u=n.length,a=r.length;if(u!=a&&!(s&&a>u))return!1;var h=t.get(n),g=t.get(r);if(h&&g)return h==r&&g==n;var l=-1,d=!0,o=e&zn?new y:void 0;for(t.set(n,r),t.set(r,n);++l<u;){var p=n[l],_=r[l];if(i)var w=s?i(_,p,l,r,n,t):i(p,_,l,n,r,t);if(w!==void 0){if(w)continue;d=!1;break}if(o){if(!Qn(r,function(O,P){if(!tn(o,P)&&(p===O||f(p,O,e,i,t)))return o.push(P)})){d=!1;break}}else if(!(p===_||f(p,_,e,i,t))){d=!1;break}}return t.delete(n),t.delete(r),d}function Vn(n){var r=-1,e=Array(n.size);return n.forEach(function(i,f){e[++r]=[f,i]}),e}function C(n){var r=-1,e=Array(n.size);return n.forEach(function(i){e[++r]=i}),e}var kn=1,jn=2,nr="[object Boolean]",rr="[object Date]",er="[object Error]",ir="[object Map]",tr="[object Number]",fr="[object RegExp]",sr="[object Set]",ur="[object String]",ar="[object Symbol]",lr="[object ArrayBuffer]",gr="[object DataView]",Z=v?v.prototype:void 0,S=Z?Z.valueOf:void 0;function dr(n,r,e,i,f,t,s){switch(e){case gr:if(n.byteLength!=r.byteLength||n.byteOffset!=r.byteOffset)return!1;n=n.buffer,r=r.buffer;case lr:return!(n.byteLength!=r.byteLength||!t(new m(n),new m(r)));case nr:case rr:case tr:return An(+n,+r);case er:return n.name==r.name&&n.message==r.message;case fr:case ur:return n==r+"";case ir:var u=Vn;case sr:var a=i&kn;if(u||(u=C),n.size!=r.size&&!a)return!1;var h=s.get(n);if(h)return h==r;i|=jn,s.set(n,r);var g=fn(u(n),u(r),i,f,t,s);return s.delete(n),g;case ar:if(S)return S.call(n)==S.call(r)}return!1}var hr=1,pr=Object.prototype,Ar=pr.hasOwnProperty;function _r(n,r,e,i,f,t){var s=e&hr,u=Y(n),a=u.length,h=Y(r),g=h.length;if(a!=g&&!s)return!1;for(var l=a;l--;){var d=u[l];if(!(s?d in r:Ar.call(r,d)))return!1}var o=t.get(n),p=t.get(r);if(o&&p)return o==r&&p==n;var _=!0;t.set(n,r),t.set(r,n);for(var w=s;++l<a;){d=u[l];var O=n[d],P=r[d];if(i)var G=s?i(P,O,d,r,n,t):i(O,P,d,n,r,t);if(!(G===void 0?O===P||f(O,P,e,i,t):G)){_=!1;break}w||(w=d=="constructor")}if(_&&!w){var E=n.constructor,b=r.constructor;E!=b&&"constructor"in n&&"constructor"in r&&!(typeof E=="function"&&E instanceof E&&typeof b=="function"&&b instanceof b)&&(_=!1)}return t.delete(n),t.delete(r),_}var or=1,X="[object Arguments]",J="[object Array]",c="[object Object]",wr=Object.prototype,Q=wr.hasOwnProperty;function Or(n,r,e,i,f,t){var s=A(n),u=A(r),a=s?J:N(n),h=u?J:N(r);a=a==X?c:a,h=h==X?c:h;var g=a==c,l=h==c,d=a==h;if(d&&U(n)){if(!U(r))return!1;s=!0,g=!1}if(d&&!g)return t||(t=new T),s||_n(n)?fn(n,r,e,i,f,t):dr(n,r,a,e,i,f,t);if(!(e&or)){var o=g&&Q.call(n,"__wrapped__"),p=l&&Q.call(r,"__wrapped__");if(o||p){var _=o?n.value():n,w=p?r.value():r;return t||(t=new T),f(_,w,e,i,t)}}return d?(t||(t=new T),_r(n,r,e,i,f,t)):!1}function D(n,r,e,i,f){return n===r?!0:n==null||r==null||!L(n)&&!L(r)?n!==n&&r!==r:Or(n,r,e,i,D,f)}var Pr=1,vr=2;function yr(n,r,e,i){var f=e.length,t=f;if(n==null)return!t;for(n=Object(n);f--;){var s=e[f];if(s[2]?s[1]!==n[s[0]]:!(s[0]in n))return!1}for(;++f<t;){s=e[f];var u=s[0],a=n[u],h=s[1];if(s[2]){if(a===void 0&&!(u in n))return!1}else{var g=new T,l;if(!(l===void 0?D(h,a,Pr|vr,i,g):l))return!1}}return!0}function sn(n){return n===n&&!on(n)}function Er(n){for(var r=M(n),e=r.length;e--;){var i=r[e],f=n[i];r[e]=[i,f,sn(f)]}return r}function un(n,r){return function(e){return e==null?!1:e[n]===r&&(r!==void 0||n in Object(e))}}function br(n){var r=Er(n);return r.length==1&&r[0][2]?un(r[0][0],r[0][1]):function(e){return e===n||yr(e,n,r)}}function cr(n,r){return n!=null&&r in Object(n)}function Tr(n,r,e){r=j(r,n);for(var i=-1,f=r.length,t=!1;++i<f;){var s=R(r[i]);if(!(t=n!=null&&e(n,s)))break;n=n[s]}return t||++i!=f?t:(f=n==null?0:n.length,!!f&&wn(f)&&On(s,f)&&(A(n)||z(n)))}function Rr(n,r){return n!=null&&Tr(n,r,cr)}var Ir=1,Sr=2;function Lr(n,r){return $(n)&&sn(r)?un(R(n),r):function(e){var i=mn(e,n);return i===void 0&&i===r?Rr(e,n):D(r,i,Ir|Sr)}}function xr(n){return function(r){return r?.[n]}}function Mr(n){return function(r){return nn(r,n)}}function $r(n){return $(n)?xr(R(n)):Mr(n)}function an(n){return typeof n=="function"?n:n==null?V:typeof n=="object"?A(n)?Lr(n[0],n[1]):br(n):$r(n)}function Cr(n,r){return n&&Pn(n,r,M)}function Dr(n,r){return function(e,i){if(e==null)return e;if(!W(e))return n(e,i);for(var f=e.length,t=-1,s=Object(e);++t<f&&i(s[t],t,s)!==!1;);return e}}var F=Dr(Cr);function Fr(n){return typeof n=="function"?n:V}function qr(n,r){var e=A(n)?bn:F;return e(n,Fr(r))}function Gr(n,r){var e=[];return F(n,function(i,f,t){r(i,f,t)&&e.push(i)}),e}function Yr(n,r){var e=A(n)?en:Gr;return e(n,an(r))}function mr(n,r,e,i,f){return f(n,function(t,s,u){e=i?(i=!1,t):r(e,t,s,u)}),e}function Zr(n,r,e){var i=A(n)?Un:mr,f=arguments.length<3;return i(n,an(r),e,f,F)}var Nr=1/0,Ur=I&&1/C(new I([,-0]))[1]==Nr?function(n){return new I(n)}:En,Br=200;function Xr(n,r,e){var i=-1,f=Sn,t=n.length,s=!0,u=[],a=u;if(t>=Br){var h=r?null:Ur(n);if(h)return C(h);s=!1,f=tn,a=new y}else a=r?[]:u;n:for(;++i<t;){var g=n[i],l=r?r(g):g;if(g=g!==0?g:0,s&&l===l){for(var d=a.length;d--;)if(a[d]===l)continue n;r&&a.push(l),u.push(g)}else f(a,l,e)||(a!==u&&a.push(l),u.push(g))}return u}export{F as a,Hr as b,yn as c,an as d,rn as e,Yn as f,qn as g,Y as h,x as i,bn as j,M as k,Xr as l,Yr as m,qr as n,cn as o,Fr as p,Cr as q,Zr as r,Bn as s,Tr as t,j as u,R as v,nn as w,Rr as x,Gn as y};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{M as ln,N as an,O as Y,P as O,Q,R as un,S as y,T as tn,V as j,W as _,X as rn,Y as o,Z as sn,$ as on,a0 as fn}from"./mermaid.core-
|
|
1
|
+
import{M as ln,N as an,O as Y,P as O,Q,R as un,S as y,T as tn,V as j,W as _,X as rn,Y as o,Z as sn,$ as on,a0 as fn}from"./mermaid.core-D5fXNCxA.js";function cn(l){return l.innerRadius}function yn(l){return l.outerRadius}function gn(l){return l.startAngle}function dn(l){return l.endAngle}function mn(l){return l&&l.padAngle}function pn(l,h,D,S,v,R,V,a){var E=D-l,i=S-h,n=V-v,d=a-R,u=d*E-n*i;if(!(u*u<y))return u=(n*(h-R)-d*(l-v))/u,[l+u*E,h+u*i]}function H(l,h,D,S,v,R,V){var a=l-D,E=h-S,i=(V?R:-R)/j(a*a+E*E),n=i*E,d=-i*a,u=l+n,s=h+d,f=D+n,c=S+d,W=(u+f)/2,t=(s+c)/2,m=f-u,g=c-s,A=m*m+g*g,T=v-R,P=u*c-f*s,I=(g<0?-1:1)*j(on(0,T*T*A-P*P)),M=(P*g-m*I)/A,N=(-P*m-g*I)/A,w=(P*g+m*I)/A,p=(-P*m+g*I)/A,x=M-W,e=N-t,r=w-W,X=p-t;return x*x+e*e>r*r+X*X&&(M=w,N=p),{cx:M,cy:N,x01:-n,y01:-d,x11:M*(v/T-1),y11:N*(v/T-1)}}function hn(){var l=cn,h=yn,D=Q(0),S=null,v=gn,R=dn,V=mn,a=null,E=ln(i);function i(){var n,d,u=+l.apply(this,arguments),s=+h.apply(this,arguments),f=v.apply(this,arguments)-un,c=R.apply(this,arguments)-un,W=rn(c-f),t=c>f;if(a||(a=n=E()),s<u&&(d=s,s=u,u=d),!(s>y))a.moveTo(0,0);else if(W>tn-y)a.moveTo(s*Y(f),s*O(f)),a.arc(0,0,s,f,c,!t),u>y&&(a.moveTo(u*Y(c),u*O(c)),a.arc(0,0,u,c,f,t));else{var m=f,g=c,A=f,T=c,P=W,I=W,M=V.apply(this,arguments)/2,N=M>y&&(S?+S.apply(this,arguments):j(u*u+s*s)),w=_(rn(s-u)/2,+D.apply(this,arguments)),p=w,x=w,e,r;if(N>y){var X=sn(N/u*O(M)),z=sn(N/s*O(M));(P-=X*2)>y?(X*=t?1:-1,A+=X,T-=X):(P=0,A=T=(f+c)/2),(I-=z*2)>y?(z*=t?1:-1,m+=z,g-=z):(I=0,m=g=(f+c)/2)}var Z=s*Y(m),$=s*O(m),B=u*Y(T),C=u*O(T);if(w>y){var F=s*Y(g),G=s*O(g),J=u*Y(A),K=u*O(A),q;if(W<an)if(q=pn(Z,$,J,K,F,G,B,C)){var L=Z-q[0],U=$-q[1],k=F-q[0],b=G-q[1],nn=1/O(fn((L*k+U*b)/(j(L*L+U*U)*j(k*k+b*b)))/2),en=j(q[0]*q[0]+q[1]*q[1]);p=_(w,(u-en)/(nn-1)),x=_(w,(s-en)/(nn+1))}else p=x=0}I>y?x>y?(e=H(J,K,Z,$,s,x,t),r=H(F,G,B,C,s,x,t),a.moveTo(e.cx+e.x01,e.cy+e.y01),x<w?a.arc(e.cx,e.cy,x,o(e.y01,e.x01),o(r.y01,r.x01),!t):(a.arc(e.cx,e.cy,x,o(e.y01,e.x01),o(e.y11,e.x11),!t),a.arc(0,0,s,o(e.cy+e.y11,e.cx+e.x11),o(r.cy+r.y11,r.cx+r.x11),!t),a.arc(r.cx,r.cy,x,o(r.y11,r.x11),o(r.y01,r.x01),!t))):(a.moveTo(Z,$),a.arc(0,0,s,m,g,!t)):a.moveTo(Z,$),!(u>y)||!(P>y)?a.lineTo(B,C):p>y?(e=H(B,C,F,G,u,-p,t),r=H(Z,$,J,K,u,-p,t),a.lineTo(e.cx+e.x01,e.cy+e.y01),p<w?a.arc(e.cx,e.cy,p,o(e.y01,e.x01),o(r.y01,r.x01),!t):(a.arc(e.cx,e.cy,p,o(e.y01,e.x01),o(e.y11,e.x11),!t),a.arc(0,0,u,o(e.cy+e.y11,e.cx+e.x11),o(r.cy+r.y11,r.cx+r.x11),t),a.arc(r.cx,r.cy,p,o(r.y11,r.x11),o(r.y01,r.x01),!t))):a.arc(0,0,u,T,A,t)}if(a.closePath(),n)return a=null,n+""||null}return i.centroid=function(){var n=(+l.apply(this,arguments)+ +h.apply(this,arguments))/2,d=(+v.apply(this,arguments)+ +R.apply(this,arguments))/2-an/2;return[Y(d)*n,O(d)*n]},i.innerRadius=function(n){return arguments.length?(l=typeof n=="function"?n:Q(+n),i):l},i.outerRadius=function(n){return arguments.length?(h=typeof n=="function"?n:Q(+n),i):h},i.cornerRadius=function(n){return arguments.length?(D=typeof n=="function"?n:Q(+n),i):D},i.padRadius=function(n){return arguments.length?(S=n==null?null:typeof n=="function"?n:Q(+n),i):S},i.startAngle=function(n){return arguments.length?(v=typeof n=="function"?n:Q(+n),i):v},i.endAngle=function(n){return arguments.length?(R=typeof n=="function"?n:Q(+n),i):R},i.padAngle=function(n){return arguments.length?(V=typeof n=="function"?n:Q(+n),i):V},i.context=function(n){return arguments.length?(a=n??null,i):a},i}export{hn as d};
|