sparkecoder 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 +2 -2
- package/dist/agent/index.d.ts +3 -2
- package/dist/agent/index.js +653 -574
- package/dist/agent/index.js.map +1 -1
- package/dist/bash-CGAqW7HR.d.ts +80 -0
- package/dist/cli.js +2912 -1374
- package/dist/cli.js.map +1 -1
- package/dist/db/index.d.ts +16 -3
- package/dist/db/index.js +68 -13
- package/dist/db/index.js.map +1 -1
- package/dist/{index-BxpkHy7X.d.ts → index-DkR9Ln_7.d.ts} +18 -2
- package/dist/index.d.ts +117 -79
- package/dist/index.js +2402 -1242
- package/dist/index.js.map +1 -1
- package/dist/{schema-EPbMMFza.d.ts → schema-cUDLVN-b.d.ts} +127 -5
- package/dist/server/index.d.ts +9 -2
- package/dist/server/index.js +2390 -1245
- package/dist/server/index.js.map +1 -1
- package/dist/tools/index.d.ts +4 -138
- package/dist/tools/index.js +483 -558
- package/dist/tools/index.js.map +1 -1
- package/package.json +4 -2
package/dist/db/index.d.ts
CHANGED
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import * as drizzle_orm_better_sqlite3 from 'drizzle-orm/better-sqlite3';
|
|
2
2
|
import Database from 'better-sqlite3';
|
|
3
|
-
import { s as schema, M as ModelMessage, a as Message, N as NewSession, S as Session, L as LoadedSkill,
|
|
4
|
-
export { g as SessionConfig } from '../schema-EPbMMFza.js';
|
|
3
|
+
import { s as schema, M as ModelMessage, a as Message, N as NewSession, S as Session, b as SessionConfig, L as LoadedSkill, c as NewTodoItem, T as TodoItem, d as NewToolExecution, e as ToolExecution, A as ActiveStream, f as NewTerminal, g as Terminal } from '../schema-cUDLVN-b.js';
|
|
5
4
|
import 'drizzle-orm/sqlite-core';
|
|
6
5
|
|
|
7
6
|
declare function initDatabase(dbPath: string): drizzle_orm_better_sqlite3.BetterSQLite3Database<typeof schema> & {
|
|
@@ -16,6 +15,12 @@ declare const sessionQueries: {
|
|
|
16
15
|
getById(id: string): Session | undefined;
|
|
17
16
|
list(limit?: number, offset?: number): Session[];
|
|
18
17
|
updateStatus(id: string, status: Session["status"]): Session | undefined;
|
|
18
|
+
updateModel(id: string, model: string): Session | undefined;
|
|
19
|
+
update(id: string, updates: {
|
|
20
|
+
model?: string;
|
|
21
|
+
name?: string;
|
|
22
|
+
config?: SessionConfig;
|
|
23
|
+
}): Session | undefined;
|
|
19
24
|
delete(id: string): boolean;
|
|
20
25
|
};
|
|
21
26
|
declare const messageQueries: {
|
|
@@ -81,5 +86,13 @@ declare const terminalQueries: {
|
|
|
81
86
|
delete(id: string): boolean;
|
|
82
87
|
deleteBySession(sessionId: string): number;
|
|
83
88
|
};
|
|
89
|
+
declare const activeStreamQueries: {
|
|
90
|
+
create(sessionId: string, streamId: string): ActiveStream;
|
|
91
|
+
getBySessionId(sessionId: string): ActiveStream | undefined;
|
|
92
|
+
getByStreamId(streamId: string): ActiveStream | undefined;
|
|
93
|
+
finish(streamId: string): ActiveStream | undefined;
|
|
94
|
+
markError(streamId: string): ActiveStream | undefined;
|
|
95
|
+
deleteBySession(sessionId: string): number;
|
|
96
|
+
};
|
|
84
97
|
|
|
85
|
-
export { Message, ModelMessage, Session, Terminal, TodoItem, ToolExecution, closeDatabase, getDb, initDatabase, messageQueries, sessionQueries, skillQueries, terminalQueries, todoQueries, toolExecutionQueries };
|
|
98
|
+
export { ActiveStream, Message, ModelMessage, Session, SessionConfig, Terminal, TodoItem, ToolExecution, activeStreamQueries, closeDatabase, getDb, initDatabase, messageQueries, sessionQueries, skillQueries, terminalQueries, todoQueries, toolExecutionQueries };
|
package/dist/db/index.js
CHANGED
|
@@ -13,6 +13,7 @@ import { nanoid } from "nanoid";
|
|
|
13
13
|
// src/db/schema.ts
|
|
14
14
|
var schema_exports = {};
|
|
15
15
|
__export(schema_exports, {
|
|
16
|
+
activeStreams: () => activeStreams,
|
|
16
17
|
loadedSkills: () => loadedSkills,
|
|
17
18
|
messages: () => messages,
|
|
18
19
|
sessions: () => sessions,
|
|
@@ -88,6 +89,15 @@ var terminals = sqliteTable("terminals", {
|
|
|
88
89
|
createdAt: integer("created_at", { mode: "timestamp" }).notNull().$defaultFn(() => /* @__PURE__ */ new Date()),
|
|
89
90
|
stoppedAt: integer("stopped_at", { mode: "timestamp" })
|
|
90
91
|
});
|
|
92
|
+
var activeStreams = sqliteTable("active_streams", {
|
|
93
|
+
id: text("id").primaryKey(),
|
|
94
|
+
sessionId: text("session_id").notNull().references(() => sessions.id, { onDelete: "cascade" }),
|
|
95
|
+
streamId: text("stream_id").notNull().unique(),
|
|
96
|
+
// Unique stream identifier
|
|
97
|
+
status: text("status", { enum: ["active", "finished", "error"] }).notNull().default("active"),
|
|
98
|
+
createdAt: integer("created_at", { mode: "timestamp" }).notNull().$defaultFn(() => /* @__PURE__ */ new Date()),
|
|
99
|
+
finishedAt: integer("finished_at", { mode: "timestamp" })
|
|
100
|
+
});
|
|
91
101
|
|
|
92
102
|
// src/db/index.ts
|
|
93
103
|
var db = null;
|
|
@@ -97,14 +107,7 @@ function initDatabase(dbPath) {
|
|
|
97
107
|
sqlite.pragma("journal_mode = WAL");
|
|
98
108
|
db = drizzle(sqlite, { schema: schema_exports });
|
|
99
109
|
sqlite.exec(`
|
|
100
|
-
|
|
101
|
-
DROP TABLE IF EXISTS loaded_skills;
|
|
102
|
-
DROP TABLE IF EXISTS todo_items;
|
|
103
|
-
DROP TABLE IF EXISTS tool_executions;
|
|
104
|
-
DROP TABLE IF EXISTS messages;
|
|
105
|
-
DROP TABLE IF EXISTS sessions;
|
|
106
|
-
|
|
107
|
-
CREATE TABLE sessions (
|
|
110
|
+
CREATE TABLE IF NOT EXISTS sessions (
|
|
108
111
|
id TEXT PRIMARY KEY,
|
|
109
112
|
name TEXT,
|
|
110
113
|
working_directory TEXT NOT NULL,
|
|
@@ -115,7 +118,7 @@ function initDatabase(dbPath) {
|
|
|
115
118
|
updated_at INTEGER NOT NULL
|
|
116
119
|
);
|
|
117
120
|
|
|
118
|
-
CREATE TABLE messages (
|
|
121
|
+
CREATE TABLE IF NOT EXISTS messages (
|
|
119
122
|
id TEXT PRIMARY KEY,
|
|
120
123
|
session_id TEXT NOT NULL REFERENCES sessions(id) ON DELETE CASCADE,
|
|
121
124
|
model_message TEXT NOT NULL,
|
|
@@ -123,7 +126,7 @@ function initDatabase(dbPath) {
|
|
|
123
126
|
created_at INTEGER NOT NULL
|
|
124
127
|
);
|
|
125
128
|
|
|
126
|
-
CREATE TABLE tool_executions (
|
|
129
|
+
CREATE TABLE IF NOT EXISTS tool_executions (
|
|
127
130
|
id TEXT PRIMARY KEY,
|
|
128
131
|
session_id TEXT NOT NULL REFERENCES sessions(id) ON DELETE CASCADE,
|
|
129
132
|
message_id TEXT REFERENCES messages(id) ON DELETE CASCADE,
|
|
@@ -138,7 +141,7 @@ function initDatabase(dbPath) {
|
|
|
138
141
|
completed_at INTEGER
|
|
139
142
|
);
|
|
140
143
|
|
|
141
|
-
CREATE TABLE todo_items (
|
|
144
|
+
CREATE TABLE IF NOT EXISTS todo_items (
|
|
142
145
|
id TEXT PRIMARY KEY,
|
|
143
146
|
session_id TEXT NOT NULL REFERENCES sessions(id) ON DELETE CASCADE,
|
|
144
147
|
content TEXT NOT NULL,
|
|
@@ -148,14 +151,14 @@ function initDatabase(dbPath) {
|
|
|
148
151
|
updated_at INTEGER NOT NULL
|
|
149
152
|
);
|
|
150
153
|
|
|
151
|
-
CREATE TABLE loaded_skills (
|
|
154
|
+
CREATE TABLE IF NOT EXISTS loaded_skills (
|
|
152
155
|
id TEXT PRIMARY KEY,
|
|
153
156
|
session_id TEXT NOT NULL REFERENCES sessions(id) ON DELETE CASCADE,
|
|
154
157
|
skill_name TEXT NOT NULL,
|
|
155
158
|
loaded_at INTEGER NOT NULL
|
|
156
159
|
);
|
|
157
160
|
|
|
158
|
-
CREATE TABLE terminals (
|
|
161
|
+
CREATE TABLE IF NOT EXISTS terminals (
|
|
159
162
|
id TEXT PRIMARY KEY,
|
|
160
163
|
session_id TEXT NOT NULL REFERENCES sessions(id) ON DELETE CASCADE,
|
|
161
164
|
name TEXT,
|
|
@@ -169,11 +172,22 @@ function initDatabase(dbPath) {
|
|
|
169
172
|
stopped_at INTEGER
|
|
170
173
|
);
|
|
171
174
|
|
|
175
|
+
-- Table for tracking active streams (for resumable streams)
|
|
176
|
+
CREATE TABLE IF NOT EXISTS active_streams (
|
|
177
|
+
id TEXT PRIMARY KEY,
|
|
178
|
+
session_id TEXT NOT NULL REFERENCES sessions(id) ON DELETE CASCADE,
|
|
179
|
+
stream_id TEXT NOT NULL UNIQUE,
|
|
180
|
+
status TEXT NOT NULL DEFAULT 'active',
|
|
181
|
+
created_at INTEGER NOT NULL,
|
|
182
|
+
finished_at INTEGER
|
|
183
|
+
);
|
|
184
|
+
|
|
172
185
|
CREATE INDEX IF NOT EXISTS idx_messages_session ON messages(session_id);
|
|
173
186
|
CREATE INDEX IF NOT EXISTS idx_tool_executions_session ON tool_executions(session_id);
|
|
174
187
|
CREATE INDEX IF NOT EXISTS idx_todo_items_session ON todo_items(session_id);
|
|
175
188
|
CREATE INDEX IF NOT EXISTS idx_loaded_skills_session ON loaded_skills(session_id);
|
|
176
189
|
CREATE INDEX IF NOT EXISTS idx_terminals_session ON terminals(session_id);
|
|
190
|
+
CREATE INDEX IF NOT EXISTS idx_active_streams_session ON active_streams(session_id);
|
|
177
191
|
`);
|
|
178
192
|
return db;
|
|
179
193
|
}
|
|
@@ -211,6 +225,12 @@ var sessionQueries = {
|
|
|
211
225
|
updateStatus(id, status) {
|
|
212
226
|
return getDb().update(sessions).set({ status, updatedAt: /* @__PURE__ */ new Date() }).where(eq(sessions.id, id)).returning().get();
|
|
213
227
|
},
|
|
228
|
+
updateModel(id, model) {
|
|
229
|
+
return getDb().update(sessions).set({ model, updatedAt: /* @__PURE__ */ new Date() }).where(eq(sessions.id, id)).returning().get();
|
|
230
|
+
},
|
|
231
|
+
update(id, updates) {
|
|
232
|
+
return getDb().update(sessions).set({ ...updates, updatedAt: /* @__PURE__ */ new Date() }).where(eq(sessions.id, id)).returning().get();
|
|
233
|
+
},
|
|
214
234
|
delete(id) {
|
|
215
235
|
const result = getDb().delete(sessions).where(eq(sessions.id, id)).run();
|
|
216
236
|
return result.changes > 0;
|
|
@@ -436,7 +456,42 @@ var terminalQueries = {
|
|
|
436
456
|
return result.changes;
|
|
437
457
|
}
|
|
438
458
|
};
|
|
459
|
+
var activeStreamQueries = {
|
|
460
|
+
create(sessionId, streamId) {
|
|
461
|
+
const id = nanoid();
|
|
462
|
+
const result = getDb().insert(activeStreams).values({
|
|
463
|
+
id,
|
|
464
|
+
sessionId,
|
|
465
|
+
streamId,
|
|
466
|
+
status: "active",
|
|
467
|
+
createdAt: /* @__PURE__ */ new Date()
|
|
468
|
+
}).returning().get();
|
|
469
|
+
return result;
|
|
470
|
+
},
|
|
471
|
+
getBySessionId(sessionId) {
|
|
472
|
+
return getDb().select().from(activeStreams).where(
|
|
473
|
+
and(
|
|
474
|
+
eq(activeStreams.sessionId, sessionId),
|
|
475
|
+
eq(activeStreams.status, "active")
|
|
476
|
+
)
|
|
477
|
+
).get();
|
|
478
|
+
},
|
|
479
|
+
getByStreamId(streamId) {
|
|
480
|
+
return getDb().select().from(activeStreams).where(eq(activeStreams.streamId, streamId)).get();
|
|
481
|
+
},
|
|
482
|
+
finish(streamId) {
|
|
483
|
+
return getDb().update(activeStreams).set({ status: "finished", finishedAt: /* @__PURE__ */ new Date() }).where(eq(activeStreams.streamId, streamId)).returning().get();
|
|
484
|
+
},
|
|
485
|
+
markError(streamId) {
|
|
486
|
+
return getDb().update(activeStreams).set({ status: "error", finishedAt: /* @__PURE__ */ new Date() }).where(eq(activeStreams.streamId, streamId)).returning().get();
|
|
487
|
+
},
|
|
488
|
+
deleteBySession(sessionId) {
|
|
489
|
+
const result = getDb().delete(activeStreams).where(eq(activeStreams.sessionId, sessionId)).run();
|
|
490
|
+
return result.changes;
|
|
491
|
+
}
|
|
492
|
+
};
|
|
439
493
|
export {
|
|
494
|
+
activeStreamQueries,
|
|
440
495
|
closeDatabase,
|
|
441
496
|
getDb,
|
|
442
497
|
initDatabase,
|
package/dist/db/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/db/index.ts","../../src/db/schema.ts"],"sourcesContent":["import Database from 'better-sqlite3';\nimport { drizzle } from 'drizzle-orm/better-sqlite3';\nimport { eq, desc, and, sql } from 'drizzle-orm';\nimport { nanoid } from 'nanoid';\nimport * as schema from './schema.js';\nimport type {\n Session,\n NewSession,\n Message,\n NewMessage,\n ToolExecution,\n NewToolExecution,\n TodoItem,\n NewTodoItem,\n SessionConfig,\n ModelMessage,\n Terminal,\n NewTerminal,\n} from './schema.js';\n\nlet db: ReturnType<typeof drizzle<typeof schema>> | null = null;\nlet sqlite: Database.Database | null = null;\n\nexport function initDatabase(dbPath: string) {\n sqlite = new Database(dbPath);\n sqlite.pragma('journal_mode = WAL');\n db = drizzle(sqlite, { schema });\n\n // Drop and recreate tables with new schema\n sqlite.exec(`\n DROP TABLE IF EXISTS terminals;\n DROP TABLE IF EXISTS loaded_skills;\n DROP TABLE IF EXISTS todo_items;\n DROP TABLE IF EXISTS tool_executions;\n DROP TABLE IF EXISTS messages;\n DROP TABLE IF EXISTS sessions;\n\n CREATE TABLE sessions (\n id TEXT PRIMARY KEY,\n name TEXT,\n working_directory TEXT NOT NULL,\n model TEXT NOT NULL,\n status TEXT NOT NULL DEFAULT 'active',\n config TEXT,\n created_at INTEGER NOT NULL,\n updated_at INTEGER NOT NULL\n );\n\n CREATE TABLE messages (\n id TEXT PRIMARY KEY,\n session_id TEXT NOT NULL REFERENCES sessions(id) ON DELETE CASCADE,\n model_message TEXT NOT NULL,\n sequence INTEGER NOT NULL DEFAULT 0,\n created_at INTEGER NOT NULL\n );\n\n CREATE TABLE tool_executions (\n id TEXT PRIMARY KEY,\n session_id TEXT NOT NULL REFERENCES sessions(id) ON DELETE CASCADE,\n message_id TEXT REFERENCES messages(id) ON DELETE CASCADE,\n tool_name TEXT NOT NULL,\n tool_call_id TEXT NOT NULL,\n input TEXT,\n output TEXT,\n status TEXT NOT NULL DEFAULT 'pending',\n requires_approval INTEGER NOT NULL DEFAULT 0,\n error TEXT,\n started_at INTEGER NOT NULL,\n completed_at INTEGER\n );\n\n CREATE TABLE todo_items (\n id TEXT PRIMARY KEY,\n session_id TEXT NOT NULL REFERENCES sessions(id) ON DELETE CASCADE,\n content TEXT NOT NULL,\n status TEXT NOT NULL DEFAULT 'pending',\n \"order\" INTEGER NOT NULL DEFAULT 0,\n created_at INTEGER NOT NULL,\n updated_at INTEGER NOT NULL\n );\n\n CREATE TABLE loaded_skills (\n id TEXT PRIMARY KEY,\n session_id TEXT NOT NULL REFERENCES sessions(id) ON DELETE CASCADE,\n skill_name TEXT NOT NULL,\n loaded_at INTEGER NOT NULL\n );\n\n CREATE TABLE terminals (\n id TEXT PRIMARY KEY,\n session_id TEXT NOT NULL REFERENCES sessions(id) ON DELETE CASCADE,\n name TEXT,\n command TEXT NOT NULL,\n cwd TEXT NOT NULL,\n pid INTEGER,\n status TEXT NOT NULL DEFAULT 'running',\n exit_code INTEGER,\n error TEXT,\n created_at INTEGER NOT NULL,\n stopped_at INTEGER\n );\n\n CREATE INDEX IF NOT EXISTS idx_messages_session ON messages(session_id);\n CREATE INDEX IF NOT EXISTS idx_tool_executions_session ON tool_executions(session_id);\n CREATE INDEX IF NOT EXISTS idx_todo_items_session ON todo_items(session_id);\n CREATE INDEX IF NOT EXISTS idx_loaded_skills_session ON loaded_skills(session_id);\n CREATE INDEX IF NOT EXISTS idx_terminals_session ON terminals(session_id);\n `);\n\n return db;\n}\n\nexport function getDb() {\n if (!db) {\n throw new Error('Database not initialized. Call initDatabase first.');\n }\n return db;\n}\n\nexport function closeDatabase() {\n if (sqlite) {\n sqlite.close();\n sqlite = null;\n db = null;\n }\n}\n\n// Session queries\nexport const sessionQueries = {\n create(data: Omit<NewSession, 'id' | 'createdAt' | 'updatedAt'>): Session {\n const id = nanoid();\n const now = new Date();\n const result = getDb()\n .insert(schema.sessions)\n .values({\n id,\n ...data,\n createdAt: now,\n updatedAt: now,\n })\n .returning()\n .get();\n return result;\n },\n\n getById(id: string): Session | undefined {\n return getDb().select().from(schema.sessions).where(eq(schema.sessions.id, id)).get();\n },\n\n list(limit = 50, offset = 0): Session[] {\n return getDb()\n .select()\n .from(schema.sessions)\n .orderBy(desc(schema.sessions.createdAt))\n .limit(limit)\n .offset(offset)\n .all();\n },\n\n updateStatus(id: string, status: Session['status']): Session | undefined {\n return getDb()\n .update(schema.sessions)\n .set({ status, updatedAt: new Date() })\n .where(eq(schema.sessions.id, id))\n .returning()\n .get();\n },\n\n delete(id: string): boolean {\n const result = getDb().delete(schema.sessions).where(eq(schema.sessions.id, id)).run();\n return result.changes > 0;\n },\n};\n\n// Message queries - stores AI SDK ModelMessage directly\nexport const messageQueries = {\n /**\n * Get the next sequence number for a session\n */\n getNextSequence(sessionId: string): number {\n const result = getDb()\n .select({ maxSeq: sql<number>`COALESCE(MAX(sequence), -1)` })\n .from(schema.messages)\n .where(eq(schema.messages.sessionId, sessionId))\n .get();\n return (result?.maxSeq ?? -1) + 1;\n },\n\n /**\n * Create a single message from a ModelMessage\n */\n create(sessionId: string, modelMessage: ModelMessage): Message {\n const id = nanoid();\n const sequence = this.getNextSequence(sessionId);\n const result = getDb()\n .insert(schema.messages)\n .values({\n id,\n sessionId,\n modelMessage,\n sequence,\n createdAt: new Date(),\n })\n .returning()\n .get();\n return result;\n },\n\n /**\n * Add multiple ModelMessages at once (from response.messages)\n * Maintains insertion order via sequence numbers\n */\n addMany(sessionId: string, modelMessages: ModelMessage[]): Message[] {\n const results: Message[] = [];\n let sequence = this.getNextSequence(sessionId);\n for (const msg of modelMessages) {\n const id = nanoid();\n const result = getDb()\n .insert(schema.messages)\n .values({\n id,\n sessionId,\n modelMessage: msg,\n sequence,\n createdAt: new Date(),\n })\n .returning()\n .get();\n results.push(result);\n sequence++;\n }\n return results;\n },\n\n /**\n * Get all messages for a session as ModelMessage[]\n * Ordered by sequence to maintain exact insertion order\n */\n getBySession(sessionId: string): Message[] {\n return getDb()\n .select()\n .from(schema.messages)\n .where(eq(schema.messages.sessionId, sessionId))\n .orderBy(schema.messages.sequence)\n .all();\n },\n\n /**\n * Get ModelMessages directly (for passing to AI SDK)\n */\n getModelMessages(sessionId: string): ModelMessage[] {\n const messages = this.getBySession(sessionId);\n return messages.map(m => m.modelMessage);\n },\n\n getRecentBySession(sessionId: string, limit = 50): Message[] {\n return getDb()\n .select()\n .from(schema.messages)\n .where(eq(schema.messages.sessionId, sessionId))\n .orderBy(desc(schema.messages.sequence))\n .limit(limit)\n .all()\n .reverse();\n },\n\n countBySession(sessionId: string): number {\n const result = getDb()\n .select({ count: sql<number>`count(*)` })\n .from(schema.messages)\n .where(eq(schema.messages.sessionId, sessionId))\n .get();\n return result?.count ?? 0;\n },\n\n deleteBySession(sessionId: string): number {\n const result = getDb()\n .delete(schema.messages)\n .where(eq(schema.messages.sessionId, sessionId))\n .run();\n return result.changes;\n },\n};\n\n// Tool execution queries\nexport const toolExecutionQueries = {\n create(data: Omit<NewToolExecution, 'id' | 'startedAt'>): ToolExecution {\n const id = nanoid();\n const result = getDb()\n .insert(schema.toolExecutions)\n .values({\n id,\n ...data,\n startedAt: new Date(),\n })\n .returning()\n .get();\n return result;\n },\n\n getById(id: string): ToolExecution | undefined {\n return getDb()\n .select()\n .from(schema.toolExecutions)\n .where(eq(schema.toolExecutions.id, id))\n .get();\n },\n\n getByToolCallId(toolCallId: string): ToolExecution | undefined {\n return getDb()\n .select()\n .from(schema.toolExecutions)\n .where(eq(schema.toolExecutions.toolCallId, toolCallId))\n .get();\n },\n\n getPendingApprovals(sessionId: string): ToolExecution[] {\n return getDb()\n .select()\n .from(schema.toolExecutions)\n .where(\n and(\n eq(schema.toolExecutions.sessionId, sessionId),\n eq(schema.toolExecutions.status, 'pending'),\n eq(schema.toolExecutions.requiresApproval, true)\n )\n )\n .all();\n },\n\n approve(id: string): ToolExecution | undefined {\n return getDb()\n .update(schema.toolExecutions)\n .set({ status: 'approved' })\n .where(eq(schema.toolExecutions.id, id))\n .returning()\n .get();\n },\n\n reject(id: string): ToolExecution | undefined {\n return getDb()\n .update(schema.toolExecutions)\n .set({ status: 'rejected' })\n .where(eq(schema.toolExecutions.id, id))\n .returning()\n .get();\n },\n\n complete(\n id: string,\n output: unknown,\n error?: string\n ): ToolExecution | undefined {\n return getDb()\n .update(schema.toolExecutions)\n .set({\n status: error ? 'error' : 'completed',\n output: output as any,\n error,\n completedAt: new Date(),\n })\n .where(eq(schema.toolExecutions.id, id))\n .returning()\n .get();\n },\n\n getBySession(sessionId: string): ToolExecution[] {\n return getDb()\n .select()\n .from(schema.toolExecutions)\n .where(eq(schema.toolExecutions.sessionId, sessionId))\n .orderBy(schema.toolExecutions.startedAt)\n .all();\n },\n};\n\n// Todo item queries\nexport const todoQueries = {\n create(data: Omit<NewTodoItem, 'id' | 'createdAt' | 'updatedAt'>): TodoItem {\n const id = nanoid();\n const now = new Date();\n const result = getDb()\n .insert(schema.todoItems)\n .values({\n id,\n ...data,\n createdAt: now,\n updatedAt: now,\n })\n .returning()\n .get();\n return result;\n },\n\n createMany(\n sessionId: string,\n items: Array<{ content: string; order?: number }>\n ): TodoItem[] {\n const now = new Date();\n const values = items.map((item, index) => ({\n id: nanoid(),\n sessionId,\n content: item.content,\n order: item.order ?? index,\n createdAt: now,\n updatedAt: now,\n }));\n\n return getDb().insert(schema.todoItems).values(values).returning().all();\n },\n\n getBySession(sessionId: string): TodoItem[] {\n return getDb()\n .select()\n .from(schema.todoItems)\n .where(eq(schema.todoItems.sessionId, sessionId))\n .orderBy(schema.todoItems.order)\n .all();\n },\n\n updateStatus(\n id: string,\n status: TodoItem['status']\n ): TodoItem | undefined {\n return getDb()\n .update(schema.todoItems)\n .set({ status, updatedAt: new Date() })\n .where(eq(schema.todoItems.id, id))\n .returning()\n .get();\n },\n\n delete(id: string): boolean {\n const result = getDb()\n .delete(schema.todoItems)\n .where(eq(schema.todoItems.id, id))\n .run();\n return result.changes > 0;\n },\n\n clearSession(sessionId: string): number {\n const result = getDb()\n .delete(schema.todoItems)\n .where(eq(schema.todoItems.sessionId, sessionId))\n .run();\n return result.changes;\n },\n};\n\n// Loaded skills queries\nexport const skillQueries = {\n load(sessionId: string, skillName: string): schema.LoadedSkill {\n const id = nanoid();\n const result = getDb()\n .insert(schema.loadedSkills)\n .values({\n id,\n sessionId,\n skillName,\n loadedAt: new Date(),\n })\n .returning()\n .get();\n return result;\n },\n\n getBySession(sessionId: string): schema.LoadedSkill[] {\n return getDb()\n .select()\n .from(schema.loadedSkills)\n .where(eq(schema.loadedSkills.sessionId, sessionId))\n .orderBy(schema.loadedSkills.loadedAt)\n .all();\n },\n\n isLoaded(sessionId: string, skillName: string): boolean {\n const result = getDb()\n .select()\n .from(schema.loadedSkills)\n .where(\n and(\n eq(schema.loadedSkills.sessionId, sessionId),\n eq(schema.loadedSkills.skillName, skillName)\n )\n )\n .get();\n return !!result;\n },\n};\n\n// Terminal queries\nexport const terminalQueries = {\n create(data: Omit<NewTerminal, 'id' | 'createdAt'>): Terminal {\n const id = nanoid();\n const result = getDb()\n .insert(schema.terminals)\n .values({\n id,\n ...data,\n createdAt: new Date(),\n })\n .returning()\n .get();\n return result;\n },\n\n getById(id: string): Terminal | undefined {\n return getDb()\n .select()\n .from(schema.terminals)\n .where(eq(schema.terminals.id, id))\n .get();\n },\n\n getBySession(sessionId: string): Terminal[] {\n return getDb()\n .select()\n .from(schema.terminals)\n .where(eq(schema.terminals.sessionId, sessionId))\n .orderBy(desc(schema.terminals.createdAt))\n .all();\n },\n\n getRunning(sessionId: string): Terminal[] {\n return getDb()\n .select()\n .from(schema.terminals)\n .where(\n and(\n eq(schema.terminals.sessionId, sessionId),\n eq(schema.terminals.status, 'running')\n )\n )\n .all();\n },\n\n updateStatus(\n id: string,\n status: Terminal['status'],\n exitCode?: number,\n error?: string\n ): Terminal | undefined {\n return getDb()\n .update(schema.terminals)\n .set({\n status,\n exitCode,\n error,\n stoppedAt: status !== 'running' ? new Date() : undefined,\n })\n .where(eq(schema.terminals.id, id))\n .returning()\n .get();\n },\n\n updatePid(id: string, pid: number): Terminal | undefined {\n return getDb()\n .update(schema.terminals)\n .set({ pid })\n .where(eq(schema.terminals.id, id))\n .returning()\n .get();\n },\n\n delete(id: string): boolean {\n const result = getDb()\n .delete(schema.terminals)\n .where(eq(schema.terminals.id, id))\n .run();\n return result.changes > 0;\n },\n\n deleteBySession(sessionId: string): number {\n const result = getDb()\n .delete(schema.terminals)\n .where(eq(schema.terminals.sessionId, sessionId))\n .run();\n return result.changes;\n },\n};\n\nexport type { \n Session, \n Message, \n ToolExecution, \n TodoItem, \n SessionConfig, \n ModelMessage,\n Terminal,\n};\n","import { sqliteTable, text, integer } from 'drizzle-orm/sqlite-core';\n\n// Sessions table - represents an agent session/thread\nexport const sessions = sqliteTable('sessions', {\n id: text('id').primaryKey(),\n name: text('name'),\n workingDirectory: text('working_directory').notNull(),\n model: text('model').notNull(),\n status: text('status', { enum: ['active', 'waiting', 'completed', 'error'] })\n .notNull()\n .default('active'),\n config: text('config', { mode: 'json' }).$type<SessionConfig>(),\n createdAt: integer('created_at', { mode: 'timestamp' })\n .notNull()\n .$defaultFn(() => new Date()),\n updatedAt: integer('updated_at', { mode: 'timestamp' })\n .notNull()\n .$defaultFn(() => new Date()),\n});\n\n// Messages table - stores AI SDK ModelMessage directly\nexport const messages = sqliteTable('messages', {\n id: text('id').primaryKey(),\n sessionId: text('session_id')\n .notNull()\n .references(() => sessions.id, { onDelete: 'cascade' }),\n // Store the entire ModelMessage as JSON (role + content)\n modelMessage: text('model_message', { mode: 'json' }).$type<ModelMessage>().notNull(),\n // Sequence number within session to maintain exact ordering\n sequence: integer('sequence').notNull().default(0),\n createdAt: integer('created_at', { mode: 'timestamp' })\n .notNull()\n .$defaultFn(() => new Date()),\n});\n\n// Tool executions - tracks all tool calls and their results\nexport const toolExecutions = sqliteTable('tool_executions', {\n id: text('id').primaryKey(),\n sessionId: text('session_id')\n .notNull()\n .references(() => sessions.id, { onDelete: 'cascade' }),\n messageId: text('message_id').references(() => messages.id, { onDelete: 'cascade' }),\n toolName: text('tool_name').notNull(),\n toolCallId: text('tool_call_id').notNull(),\n input: text('input', { mode: 'json' }),\n output: text('output', { mode: 'json' }),\n status: text('status', { enum: ['pending', 'approved', 'rejected', 'completed', 'error'] })\n .notNull()\n .default('pending'),\n requiresApproval: integer('requires_approval', { mode: 'boolean' }).notNull().default(false),\n error: text('error'),\n startedAt: integer('started_at', { mode: 'timestamp' })\n .notNull()\n .$defaultFn(() => new Date()),\n completedAt: integer('completed_at', { mode: 'timestamp' }),\n});\n\n// Todo items for the planning tool\nexport const todoItems = sqliteTable('todo_items', {\n id: text('id').primaryKey(),\n sessionId: text('session_id')\n .notNull()\n .references(() => sessions.id, { onDelete: 'cascade' }),\n content: text('content').notNull(),\n status: text('status', { enum: ['pending', 'in_progress', 'completed', 'cancelled'] })\n .notNull()\n .default('pending'),\n order: integer('order').notNull().default(0),\n createdAt: integer('created_at', { mode: 'timestamp' })\n .notNull()\n .$defaultFn(() => new Date()),\n updatedAt: integer('updated_at', { mode: 'timestamp' })\n .notNull()\n .$defaultFn(() => new Date()),\n});\n\n// Skills loaded into sessions\nexport const loadedSkills = sqliteTable('loaded_skills', {\n id: text('id').primaryKey(),\n sessionId: text('session_id')\n .notNull()\n .references(() => sessions.id, { onDelete: 'cascade' }),\n skillName: text('skill_name').notNull(),\n loadedAt: integer('loaded_at', { mode: 'timestamp' })\n .notNull()\n .$defaultFn(() => new Date()),\n});\n\n// Terminal sessions - background processes managed by agents\nexport const terminals = sqliteTable('terminals', {\n id: text('id').primaryKey(),\n sessionId: text('session_id')\n .notNull()\n .references(() => sessions.id, { onDelete: 'cascade' }),\n name: text('name'), // Optional friendly name (e.g., \"dev-server\")\n command: text('command').notNull(), // The command that was run\n cwd: text('cwd').notNull(), // Working directory\n pid: integer('pid'), // Process ID (null if not running)\n status: text('status', { enum: ['running', 'stopped', 'error'] })\n .notNull()\n .default('running'),\n exitCode: integer('exit_code'), // Exit code if stopped\n error: text('error'), // Error message if status is 'error'\n createdAt: integer('created_at', { mode: 'timestamp' })\n .notNull()\n .$defaultFn(() => new Date()),\n stoppedAt: integer('stopped_at', { mode: 'timestamp' }),\n});\n\n// Types for JSON columns\nexport interface SessionConfig {\n toolApprovals?: Record<string, boolean>;\n approvalWebhook?: string;\n skillsDirectory?: string;\n maxContextChars?: number;\n}\n\n// AI SDK ModelMessage types - stored directly for accurate context passing\n// These match the exact format from AI SDK's response.messages\nexport type ModelMessage = \n | SystemModelMessage\n | UserModelMessage\n | AssistantModelMessage\n | ToolModelMessage;\n\nexport interface SystemModelMessage {\n role: 'system';\n content: string;\n}\n\nexport interface UserModelMessage {\n role: 'user';\n content: string;\n}\n\nexport interface AssistantModelMessage {\n role: 'assistant';\n content: string | AssistantContentPart[];\n}\n\nexport interface ToolModelMessage {\n role: 'tool';\n content: ToolResultPart[];\n}\n\nexport interface AssistantContentPart {\n type: 'text' | 'tool-call';\n text?: string;\n toolCallId?: string;\n toolName?: string;\n input?: unknown;\n}\n\nexport interface ToolResultPart {\n type: 'tool-result';\n toolCallId: string;\n toolName: string;\n output: unknown;\n}\n\n// Type exports for queries\nexport type Session = typeof sessions.$inferSelect;\nexport type NewSession = typeof sessions.$inferInsert;\nexport type Message = typeof messages.$inferSelect;\nexport type NewMessage = typeof messages.$inferInsert;\nexport type ToolExecution = typeof toolExecutions.$inferSelect;\nexport type NewToolExecution = typeof toolExecutions.$inferInsert;\nexport type TodoItem = typeof todoItems.$inferSelect;\nexport type NewTodoItem = typeof todoItems.$inferInsert;\nexport type LoadedSkill = typeof loadedSkills.$inferSelect;\nexport type Terminal = typeof terminals.$inferSelect;\nexport type NewTerminal = typeof terminals.$inferInsert;"],"mappings":"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","names":["messages"]}
|
|
1
|
+
{"version":3,"sources":["../../src/db/index.ts","../../src/db/schema.ts"],"sourcesContent":["import Database from 'better-sqlite3';\nimport { drizzle } from 'drizzle-orm/better-sqlite3';\nimport { eq, desc, and, sql } from 'drizzle-orm';\nimport { nanoid } from 'nanoid';\nimport * as schema from './schema.js';\nimport type {\n Session,\n NewSession,\n Message,\n NewMessage,\n ToolExecution,\n NewToolExecution,\n TodoItem,\n NewTodoItem,\n SessionConfig,\n ModelMessage,\n Terminal,\n NewTerminal,\n ActiveStream,\n NewActiveStream,\n} from './schema.js';\n\nlet db: ReturnType<typeof drizzle<typeof schema>> | null = null;\nlet sqlite: Database.Database | null = null;\n\nexport function initDatabase(dbPath: string) {\n sqlite = new Database(dbPath);\n sqlite.pragma('journal_mode = WAL');\n db = drizzle(sqlite, { schema });\n\n // Create tables if they don't exist (preserves existing data)\n sqlite.exec(`\n CREATE TABLE IF NOT EXISTS sessions (\n id TEXT PRIMARY KEY,\n name TEXT,\n working_directory TEXT NOT NULL,\n model TEXT NOT NULL,\n status TEXT NOT NULL DEFAULT 'active',\n config TEXT,\n created_at INTEGER NOT NULL,\n updated_at INTEGER NOT NULL\n );\n\n CREATE TABLE IF NOT EXISTS messages (\n id TEXT PRIMARY KEY,\n session_id TEXT NOT NULL REFERENCES sessions(id) ON DELETE CASCADE,\n model_message TEXT NOT NULL,\n sequence INTEGER NOT NULL DEFAULT 0,\n created_at INTEGER NOT NULL\n );\n\n CREATE TABLE IF NOT EXISTS tool_executions (\n id TEXT PRIMARY KEY,\n session_id TEXT NOT NULL REFERENCES sessions(id) ON DELETE CASCADE,\n message_id TEXT REFERENCES messages(id) ON DELETE CASCADE,\n tool_name TEXT NOT NULL,\n tool_call_id TEXT NOT NULL,\n input TEXT,\n output TEXT,\n status TEXT NOT NULL DEFAULT 'pending',\n requires_approval INTEGER NOT NULL DEFAULT 0,\n error TEXT,\n started_at INTEGER NOT NULL,\n completed_at INTEGER\n );\n\n CREATE TABLE IF NOT EXISTS todo_items (\n id TEXT PRIMARY KEY,\n session_id TEXT NOT NULL REFERENCES sessions(id) ON DELETE CASCADE,\n content TEXT NOT NULL,\n status TEXT NOT NULL DEFAULT 'pending',\n \"order\" INTEGER NOT NULL DEFAULT 0,\n created_at INTEGER NOT NULL,\n updated_at INTEGER NOT NULL\n );\n\n CREATE TABLE IF NOT EXISTS loaded_skills (\n id TEXT PRIMARY KEY,\n session_id TEXT NOT NULL REFERENCES sessions(id) ON DELETE CASCADE,\n skill_name TEXT NOT NULL,\n loaded_at INTEGER NOT NULL\n );\n\n CREATE TABLE IF NOT EXISTS terminals (\n id TEXT PRIMARY KEY,\n session_id TEXT NOT NULL REFERENCES sessions(id) ON DELETE CASCADE,\n name TEXT,\n command TEXT NOT NULL,\n cwd TEXT NOT NULL,\n pid INTEGER,\n status TEXT NOT NULL DEFAULT 'running',\n exit_code INTEGER,\n error TEXT,\n created_at INTEGER NOT NULL,\n stopped_at INTEGER\n );\n\n -- Table for tracking active streams (for resumable streams)\n CREATE TABLE IF NOT EXISTS active_streams (\n id TEXT PRIMARY KEY,\n session_id TEXT NOT NULL REFERENCES sessions(id) ON DELETE CASCADE,\n stream_id TEXT NOT NULL UNIQUE,\n status TEXT NOT NULL DEFAULT 'active',\n created_at INTEGER NOT NULL,\n finished_at INTEGER\n );\n\n CREATE INDEX IF NOT EXISTS idx_messages_session ON messages(session_id);\n CREATE INDEX IF NOT EXISTS idx_tool_executions_session ON tool_executions(session_id);\n CREATE INDEX IF NOT EXISTS idx_todo_items_session ON todo_items(session_id);\n CREATE INDEX IF NOT EXISTS idx_loaded_skills_session ON loaded_skills(session_id);\n CREATE INDEX IF NOT EXISTS idx_terminals_session ON terminals(session_id);\n CREATE INDEX IF NOT EXISTS idx_active_streams_session ON active_streams(session_id);\n `);\n\n return db;\n}\n\nexport function getDb() {\n if (!db) {\n throw new Error('Database not initialized. Call initDatabase first.');\n }\n return db;\n}\n\nexport function closeDatabase() {\n if (sqlite) {\n sqlite.close();\n sqlite = null;\n db = null;\n }\n}\n\n// Session queries\nexport const sessionQueries = {\n create(data: Omit<NewSession, 'id' | 'createdAt' | 'updatedAt'>): Session {\n const id = nanoid();\n const now = new Date();\n const result = getDb()\n .insert(schema.sessions)\n .values({\n id,\n ...data,\n createdAt: now,\n updatedAt: now,\n })\n .returning()\n .get();\n return result;\n },\n\n getById(id: string): Session | undefined {\n return getDb().select().from(schema.sessions).where(eq(schema.sessions.id, id)).get();\n },\n\n list(limit = 50, offset = 0): Session[] {\n return getDb()\n .select()\n .from(schema.sessions)\n .orderBy(desc(schema.sessions.createdAt))\n .limit(limit)\n .offset(offset)\n .all();\n },\n\n updateStatus(id: string, status: Session['status']): Session | undefined {\n return getDb()\n .update(schema.sessions)\n .set({ status, updatedAt: new Date() })\n .where(eq(schema.sessions.id, id))\n .returning()\n .get();\n },\n\n updateModel(id: string, model: string): Session | undefined {\n return getDb()\n .update(schema.sessions)\n .set({ model, updatedAt: new Date() })\n .where(eq(schema.sessions.id, id))\n .returning()\n .get();\n },\n\n update(id: string, updates: { model?: string; name?: string; config?: SessionConfig }): Session | undefined {\n return getDb()\n .update(schema.sessions)\n .set({ ...updates, updatedAt: new Date() })\n .where(eq(schema.sessions.id, id))\n .returning()\n .get();\n },\n\n delete(id: string): boolean {\n const result = getDb().delete(schema.sessions).where(eq(schema.sessions.id, id)).run();\n return result.changes > 0;\n },\n};\n\n// Message queries - stores AI SDK ModelMessage directly\nexport const messageQueries = {\n /**\n * Get the next sequence number for a session\n */\n getNextSequence(sessionId: string): number {\n const result = getDb()\n .select({ maxSeq: sql<number>`COALESCE(MAX(sequence), -1)` })\n .from(schema.messages)\n .where(eq(schema.messages.sessionId, sessionId))\n .get();\n return (result?.maxSeq ?? -1) + 1;\n },\n\n /**\n * Create a single message from a ModelMessage\n */\n create(sessionId: string, modelMessage: ModelMessage): Message {\n const id = nanoid();\n const sequence = this.getNextSequence(sessionId);\n const result = getDb()\n .insert(schema.messages)\n .values({\n id,\n sessionId,\n modelMessage,\n sequence,\n createdAt: new Date(),\n })\n .returning()\n .get();\n return result;\n },\n\n /**\n * Add multiple ModelMessages at once (from response.messages)\n * Maintains insertion order via sequence numbers\n */\n addMany(sessionId: string, modelMessages: ModelMessage[]): Message[] {\n const results: Message[] = [];\n let sequence = this.getNextSequence(sessionId);\n for (const msg of modelMessages) {\n const id = nanoid();\n const result = getDb()\n .insert(schema.messages)\n .values({\n id,\n sessionId,\n modelMessage: msg,\n sequence,\n createdAt: new Date(),\n })\n .returning()\n .get();\n results.push(result);\n sequence++;\n }\n return results;\n },\n\n /**\n * Get all messages for a session as ModelMessage[]\n * Ordered by sequence to maintain exact insertion order\n */\n getBySession(sessionId: string): Message[] {\n return getDb()\n .select()\n .from(schema.messages)\n .where(eq(schema.messages.sessionId, sessionId))\n .orderBy(schema.messages.sequence)\n .all();\n },\n\n /**\n * Get ModelMessages directly (for passing to AI SDK)\n */\n getModelMessages(sessionId: string): ModelMessage[] {\n const messages = this.getBySession(sessionId);\n return messages.map(m => m.modelMessage);\n },\n\n getRecentBySession(sessionId: string, limit = 50): Message[] {\n return getDb()\n .select()\n .from(schema.messages)\n .where(eq(schema.messages.sessionId, sessionId))\n .orderBy(desc(schema.messages.sequence))\n .limit(limit)\n .all()\n .reverse();\n },\n\n countBySession(sessionId: string): number {\n const result = getDb()\n .select({ count: sql<number>`count(*)` })\n .from(schema.messages)\n .where(eq(schema.messages.sessionId, sessionId))\n .get();\n return result?.count ?? 0;\n },\n\n deleteBySession(sessionId: string): number {\n const result = getDb()\n .delete(schema.messages)\n .where(eq(schema.messages.sessionId, sessionId))\n .run();\n return result.changes;\n },\n};\n\n// Tool execution queries\nexport const toolExecutionQueries = {\n create(data: Omit<NewToolExecution, 'id' | 'startedAt'>): ToolExecution {\n const id = nanoid();\n const result = getDb()\n .insert(schema.toolExecutions)\n .values({\n id,\n ...data,\n startedAt: new Date(),\n })\n .returning()\n .get();\n return result;\n },\n\n getById(id: string): ToolExecution | undefined {\n return getDb()\n .select()\n .from(schema.toolExecutions)\n .where(eq(schema.toolExecutions.id, id))\n .get();\n },\n\n getByToolCallId(toolCallId: string): ToolExecution | undefined {\n return getDb()\n .select()\n .from(schema.toolExecutions)\n .where(eq(schema.toolExecutions.toolCallId, toolCallId))\n .get();\n },\n\n getPendingApprovals(sessionId: string): ToolExecution[] {\n return getDb()\n .select()\n .from(schema.toolExecutions)\n .where(\n and(\n eq(schema.toolExecutions.sessionId, sessionId),\n eq(schema.toolExecutions.status, 'pending'),\n eq(schema.toolExecutions.requiresApproval, true)\n )\n )\n .all();\n },\n\n approve(id: string): ToolExecution | undefined {\n return getDb()\n .update(schema.toolExecutions)\n .set({ status: 'approved' })\n .where(eq(schema.toolExecutions.id, id))\n .returning()\n .get();\n },\n\n reject(id: string): ToolExecution | undefined {\n return getDb()\n .update(schema.toolExecutions)\n .set({ status: 'rejected' })\n .where(eq(schema.toolExecutions.id, id))\n .returning()\n .get();\n },\n\n complete(\n id: string,\n output: unknown,\n error?: string\n ): ToolExecution | undefined {\n return getDb()\n .update(schema.toolExecutions)\n .set({\n status: error ? 'error' : 'completed',\n output: output as any,\n error,\n completedAt: new Date(),\n })\n .where(eq(schema.toolExecutions.id, id))\n .returning()\n .get();\n },\n\n getBySession(sessionId: string): ToolExecution[] {\n return getDb()\n .select()\n .from(schema.toolExecutions)\n .where(eq(schema.toolExecutions.sessionId, sessionId))\n .orderBy(schema.toolExecutions.startedAt)\n .all();\n },\n};\n\n// Todo item queries\nexport const todoQueries = {\n create(data: Omit<NewTodoItem, 'id' | 'createdAt' | 'updatedAt'>): TodoItem {\n const id = nanoid();\n const now = new Date();\n const result = getDb()\n .insert(schema.todoItems)\n .values({\n id,\n ...data,\n createdAt: now,\n updatedAt: now,\n })\n .returning()\n .get();\n return result;\n },\n\n createMany(\n sessionId: string,\n items: Array<{ content: string; order?: number }>\n ): TodoItem[] {\n const now = new Date();\n const values = items.map((item, index) => ({\n id: nanoid(),\n sessionId,\n content: item.content,\n order: item.order ?? index,\n createdAt: now,\n updatedAt: now,\n }));\n\n return getDb().insert(schema.todoItems).values(values).returning().all();\n },\n\n getBySession(sessionId: string): TodoItem[] {\n return getDb()\n .select()\n .from(schema.todoItems)\n .where(eq(schema.todoItems.sessionId, sessionId))\n .orderBy(schema.todoItems.order)\n .all();\n },\n\n updateStatus(\n id: string,\n status: TodoItem['status']\n ): TodoItem | undefined {\n return getDb()\n .update(schema.todoItems)\n .set({ status, updatedAt: new Date() })\n .where(eq(schema.todoItems.id, id))\n .returning()\n .get();\n },\n\n delete(id: string): boolean {\n const result = getDb()\n .delete(schema.todoItems)\n .where(eq(schema.todoItems.id, id))\n .run();\n return result.changes > 0;\n },\n\n clearSession(sessionId: string): number {\n const result = getDb()\n .delete(schema.todoItems)\n .where(eq(schema.todoItems.sessionId, sessionId))\n .run();\n return result.changes;\n },\n};\n\n// Loaded skills queries\nexport const skillQueries = {\n load(sessionId: string, skillName: string): schema.LoadedSkill {\n const id = nanoid();\n const result = getDb()\n .insert(schema.loadedSkills)\n .values({\n id,\n sessionId,\n skillName,\n loadedAt: new Date(),\n })\n .returning()\n .get();\n return result;\n },\n\n getBySession(sessionId: string): schema.LoadedSkill[] {\n return getDb()\n .select()\n .from(schema.loadedSkills)\n .where(eq(schema.loadedSkills.sessionId, sessionId))\n .orderBy(schema.loadedSkills.loadedAt)\n .all();\n },\n\n isLoaded(sessionId: string, skillName: string): boolean {\n const result = getDb()\n .select()\n .from(schema.loadedSkills)\n .where(\n and(\n eq(schema.loadedSkills.sessionId, sessionId),\n eq(schema.loadedSkills.skillName, skillName)\n )\n )\n .get();\n return !!result;\n },\n};\n\n// Terminal queries\nexport const terminalQueries = {\n create(data: Omit<NewTerminal, 'id' | 'createdAt'>): Terminal {\n const id = nanoid();\n const result = getDb()\n .insert(schema.terminals)\n .values({\n id,\n ...data,\n createdAt: new Date(),\n })\n .returning()\n .get();\n return result;\n },\n\n getById(id: string): Terminal | undefined {\n return getDb()\n .select()\n .from(schema.terminals)\n .where(eq(schema.terminals.id, id))\n .get();\n },\n\n getBySession(sessionId: string): Terminal[] {\n return getDb()\n .select()\n .from(schema.terminals)\n .where(eq(schema.terminals.sessionId, sessionId))\n .orderBy(desc(schema.terminals.createdAt))\n .all();\n },\n\n getRunning(sessionId: string): Terminal[] {\n return getDb()\n .select()\n .from(schema.terminals)\n .where(\n and(\n eq(schema.terminals.sessionId, sessionId),\n eq(schema.terminals.status, 'running')\n )\n )\n .all();\n },\n\n updateStatus(\n id: string,\n status: Terminal['status'],\n exitCode?: number,\n error?: string\n ): Terminal | undefined {\n return getDb()\n .update(schema.terminals)\n .set({\n status,\n exitCode,\n error,\n stoppedAt: status !== 'running' ? new Date() : undefined,\n })\n .where(eq(schema.terminals.id, id))\n .returning()\n .get();\n },\n\n updatePid(id: string, pid: number): Terminal | undefined {\n return getDb()\n .update(schema.terminals)\n .set({ pid })\n .where(eq(schema.terminals.id, id))\n .returning()\n .get();\n },\n\n delete(id: string): boolean {\n const result = getDb()\n .delete(schema.terminals)\n .where(eq(schema.terminals.id, id))\n .run();\n return result.changes > 0;\n },\n\n deleteBySession(sessionId: string): number {\n const result = getDb()\n .delete(schema.terminals)\n .where(eq(schema.terminals.sessionId, sessionId))\n .run();\n return result.changes;\n },\n};\n\n// Active stream queries - for resumable streams\nexport const activeStreamQueries = {\n create(sessionId: string, streamId: string): ActiveStream {\n const id = nanoid();\n const result = getDb()\n .insert(schema.activeStreams)\n .values({\n id,\n sessionId,\n streamId,\n status: 'active',\n createdAt: new Date(),\n })\n .returning()\n .get();\n return result;\n },\n\n getBySessionId(sessionId: string): ActiveStream | undefined {\n return getDb()\n .select()\n .from(schema.activeStreams)\n .where(\n and(\n eq(schema.activeStreams.sessionId, sessionId),\n eq(schema.activeStreams.status, 'active')\n )\n )\n .get();\n },\n\n getByStreamId(streamId: string): ActiveStream | undefined {\n return getDb()\n .select()\n .from(schema.activeStreams)\n .where(eq(schema.activeStreams.streamId, streamId))\n .get();\n },\n\n finish(streamId: string): ActiveStream | undefined {\n return getDb()\n .update(schema.activeStreams)\n .set({ status: 'finished', finishedAt: new Date() })\n .where(eq(schema.activeStreams.streamId, streamId))\n .returning()\n .get();\n },\n\n markError(streamId: string): ActiveStream | undefined {\n return getDb()\n .update(schema.activeStreams)\n .set({ status: 'error', finishedAt: new Date() })\n .where(eq(schema.activeStreams.streamId, streamId))\n .returning()\n .get();\n },\n\n deleteBySession(sessionId: string): number {\n const result = getDb()\n .delete(schema.activeStreams)\n .where(eq(schema.activeStreams.sessionId, sessionId))\n .run();\n return result.changes;\n },\n};\n\nexport type { \n Session, \n Message, \n ToolExecution, \n TodoItem, \n SessionConfig, \n ModelMessage,\n Terminal,\n ActiveStream,\n};\n","import { sqliteTable, text, integer } from 'drizzle-orm/sqlite-core';\n\n// Sessions table - represents an agent session/thread\nexport const sessions = sqliteTable('sessions', {\n id: text('id').primaryKey(),\n name: text('name'),\n workingDirectory: text('working_directory').notNull(),\n model: text('model').notNull(),\n status: text('status', { enum: ['active', 'waiting', 'completed', 'error'] })\n .notNull()\n .default('active'),\n config: text('config', { mode: 'json' }).$type<SessionConfig>(),\n createdAt: integer('created_at', { mode: 'timestamp' })\n .notNull()\n .$defaultFn(() => new Date()),\n updatedAt: integer('updated_at', { mode: 'timestamp' })\n .notNull()\n .$defaultFn(() => new Date()),\n});\n\n// Messages table - stores AI SDK ModelMessage directly\nexport const messages = sqliteTable('messages', {\n id: text('id').primaryKey(),\n sessionId: text('session_id')\n .notNull()\n .references(() => sessions.id, { onDelete: 'cascade' }),\n // Store the entire ModelMessage as JSON (role + content)\n modelMessage: text('model_message', { mode: 'json' }).$type<ModelMessage>().notNull(),\n // Sequence number within session to maintain exact ordering\n sequence: integer('sequence').notNull().default(0),\n createdAt: integer('created_at', { mode: 'timestamp' })\n .notNull()\n .$defaultFn(() => new Date()),\n});\n\n// Tool executions - tracks all tool calls and their results\nexport const toolExecutions = sqliteTable('tool_executions', {\n id: text('id').primaryKey(),\n sessionId: text('session_id')\n .notNull()\n .references(() => sessions.id, { onDelete: 'cascade' }),\n messageId: text('message_id').references(() => messages.id, { onDelete: 'cascade' }),\n toolName: text('tool_name').notNull(),\n toolCallId: text('tool_call_id').notNull(),\n input: text('input', { mode: 'json' }),\n output: text('output', { mode: 'json' }),\n status: text('status', { enum: ['pending', 'approved', 'rejected', 'completed', 'error'] })\n .notNull()\n .default('pending'),\n requiresApproval: integer('requires_approval', { mode: 'boolean' }).notNull().default(false),\n error: text('error'),\n startedAt: integer('started_at', { mode: 'timestamp' })\n .notNull()\n .$defaultFn(() => new Date()),\n completedAt: integer('completed_at', { mode: 'timestamp' }),\n});\n\n// Todo items for the planning tool\nexport const todoItems = sqliteTable('todo_items', {\n id: text('id').primaryKey(),\n sessionId: text('session_id')\n .notNull()\n .references(() => sessions.id, { onDelete: 'cascade' }),\n content: text('content').notNull(),\n status: text('status', { enum: ['pending', 'in_progress', 'completed', 'cancelled'] })\n .notNull()\n .default('pending'),\n order: integer('order').notNull().default(0),\n createdAt: integer('created_at', { mode: 'timestamp' })\n .notNull()\n .$defaultFn(() => new Date()),\n updatedAt: integer('updated_at', { mode: 'timestamp' })\n .notNull()\n .$defaultFn(() => new Date()),\n});\n\n// Skills loaded into sessions\nexport const loadedSkills = sqliteTable('loaded_skills', {\n id: text('id').primaryKey(),\n sessionId: text('session_id')\n .notNull()\n .references(() => sessions.id, { onDelete: 'cascade' }),\n skillName: text('skill_name').notNull(),\n loadedAt: integer('loaded_at', { mode: 'timestamp' })\n .notNull()\n .$defaultFn(() => new Date()),\n});\n\n// Terminal sessions - background processes managed by agents\nexport const terminals = sqliteTable('terminals', {\n id: text('id').primaryKey(),\n sessionId: text('session_id')\n .notNull()\n .references(() => sessions.id, { onDelete: 'cascade' }),\n name: text('name'), // Optional friendly name (e.g., \"dev-server\")\n command: text('command').notNull(), // The command that was run\n cwd: text('cwd').notNull(), // Working directory\n pid: integer('pid'), // Process ID (null if not running)\n status: text('status', { enum: ['running', 'stopped', 'error'] })\n .notNull()\n .default('running'),\n exitCode: integer('exit_code'), // Exit code if stopped\n error: text('error'), // Error message if status is 'error'\n createdAt: integer('created_at', { mode: 'timestamp' })\n .notNull()\n .$defaultFn(() => new Date()),\n stoppedAt: integer('stopped_at', { mode: 'timestamp' }),\n});\n\n// Active streams - tracks resumable stream sessions for multi-client sync\nexport const activeStreams = sqliteTable('active_streams', {\n id: text('id').primaryKey(),\n sessionId: text('session_id')\n .notNull()\n .references(() => sessions.id, { onDelete: 'cascade' }),\n streamId: text('stream_id').notNull().unique(), // Unique stream identifier\n status: text('status', { enum: ['active', 'finished', 'error'] })\n .notNull()\n .default('active'),\n createdAt: integer('created_at', { mode: 'timestamp' })\n .notNull()\n .$defaultFn(() => new Date()),\n finishedAt: integer('finished_at', { mode: 'timestamp' }),\n});\n\n// Types for JSON columns\nexport interface SessionConfig {\n toolApprovals?: Record<string, boolean>;\n approvalWebhook?: string;\n skillsDirectory?: string;\n maxContextChars?: number;\n}\n\n// AI SDK ModelMessage types - stored directly for accurate context passing\n// These match the exact format from AI SDK's response.messages\nexport type ModelMessage = \n | SystemModelMessage\n | UserModelMessage\n | AssistantModelMessage\n | ToolModelMessage;\n\nexport interface SystemModelMessage {\n role: 'system';\n content: string;\n}\n\nexport interface UserModelMessage {\n role: 'user';\n content: string;\n}\n\nexport interface AssistantModelMessage {\n role: 'assistant';\n content: string | AssistantContentPart[];\n}\n\nexport interface ToolModelMessage {\n role: 'tool';\n content: ToolResultPart[];\n}\n\nexport interface AssistantContentPart {\n type: 'text' | 'tool-call' | 'reasoning';\n text?: string;\n toolCallId?: string;\n toolName?: string;\n input?: unknown;\n}\n\nexport interface ToolResultPart {\n type: 'tool-result';\n toolCallId: string;\n toolName: string;\n output: unknown;\n}\n\n// Type exports for queries\nexport type Session = typeof sessions.$inferSelect;\nexport type NewSession = typeof sessions.$inferInsert;\nexport type Message = typeof messages.$inferSelect;\nexport type NewMessage = typeof messages.$inferInsert;\nexport type ToolExecution = typeof toolExecutions.$inferSelect;\nexport type NewToolExecution = typeof toolExecutions.$inferInsert;\nexport type TodoItem = typeof todoItems.$inferSelect;\nexport type NewTodoItem = typeof todoItems.$inferInsert;\nexport type LoadedSkill = typeof loadedSkills.$inferSelect;\nexport type Terminal = typeof terminals.$inferSelect;\nexport type NewTerminal = typeof terminals.$inferInsert;\nexport type ActiveStream = typeof activeStreams.$inferSelect;\nexport type NewActiveStream = typeof activeStreams.$inferInsert;"],"mappings":"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","names":["messages"]}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { ModelMessage, streamText } from 'ai';
|
|
2
|
-
import { S as Session,
|
|
2
|
+
import { S as Session, e as ToolExecution } from './schema-cUDLVN-b.js';
|
|
3
3
|
import { z } from 'zod';
|
|
4
|
+
import { B as BashToolProgress } from './bash-CGAqW7HR.js';
|
|
4
5
|
|
|
5
6
|
declare const ToolApprovalConfigSchema: z.ZodObject<{
|
|
6
7
|
bash: z.ZodDefault<z.ZodOptional<z.ZodBoolean>>;
|
|
@@ -228,6 +229,9 @@ interface AgentOptions {
|
|
|
228
229
|
}
|
|
229
230
|
interface AgentRunOptions {
|
|
230
231
|
prompt: string;
|
|
232
|
+
abortSignal?: AbortSignal;
|
|
233
|
+
/** Skip saving user message (if already saved externally) */
|
|
234
|
+
skipSaveUserMessage?: boolean;
|
|
231
235
|
onText?: (text: string) => void;
|
|
232
236
|
onToolCall?: (toolCall: {
|
|
233
237
|
toolCallId: string;
|
|
@@ -245,6 +249,14 @@ interface AgentRunOptions {
|
|
|
245
249
|
toolCalls?: unknown[];
|
|
246
250
|
usage?: unknown;
|
|
247
251
|
}) => void;
|
|
252
|
+
onAbort?: (info: {
|
|
253
|
+
steps: unknown[];
|
|
254
|
+
}) => void;
|
|
255
|
+
/** Called when a tool (like bash) has progress to report (e.g., terminal started) */
|
|
256
|
+
onToolProgress?: (progress: {
|
|
257
|
+
toolName: string;
|
|
258
|
+
data: BashToolProgress;
|
|
259
|
+
}) => void;
|
|
248
260
|
}
|
|
249
261
|
interface AgentStreamResult {
|
|
250
262
|
sessionId: string;
|
|
@@ -259,9 +271,13 @@ interface AgentStreamResult {
|
|
|
259
271
|
declare class Agent {
|
|
260
272
|
private session;
|
|
261
273
|
private context;
|
|
262
|
-
private
|
|
274
|
+
private baseTools;
|
|
263
275
|
private pendingApprovals;
|
|
264
276
|
private constructor();
|
|
277
|
+
/**
|
|
278
|
+
* Create tools with optional progress callbacks
|
|
279
|
+
*/
|
|
280
|
+
private createToolsWithCallbacks;
|
|
265
281
|
/**
|
|
266
282
|
* Create or resume an agent session
|
|
267
283
|
*/
|
package/dist/index.d.ts
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
import { R as ResolvedConfig } from './index-
|
|
2
|
-
export { A as Agent, a as AgentOptions, b as AgentRunOptions, c as AgentStreamResult, S as SparkcoderConfig, T as ToolApprovalConfig } from './index-
|
|
1
|
+
import { R as ResolvedConfig } from './index-DkR9Ln_7.js';
|
|
2
|
+
export { A as Agent, a as AgentOptions, b as AgentRunOptions, c as AgentStreamResult, S as SparkcoderConfig, T as ToolApprovalConfig } from './index-DkR9Ln_7.js';
|
|
3
3
|
export { ServerOptions, createApp, startServer, stopServer } from './server/index.js';
|
|
4
|
-
export { closeDatabase, getDb, initDatabase, messageQueries, sessionQueries, skillQueries,
|
|
5
|
-
export { a as Message, M as ModelMessage, S as Session,
|
|
6
|
-
export {
|
|
7
|
-
|
|
4
|
+
export { closeDatabase, getDb, initDatabase, messageQueries, sessionQueries, skillQueries, todoQueries, toolExecutionQueries } from './db/index.js';
|
|
5
|
+
export { a as Message, M as ModelMessage, S as Session, b as SessionConfig, g as Terminal, T as TodoItem, e as ToolExecution } from './schema-cUDLVN-b.js';
|
|
6
|
+
export { createLoadSkillTool, createReadFileTool, createTodoTool, createTools, createWriteFileTool } from './tools/index.js';
|
|
7
|
+
export { c as createBashTool } from './bash-CGAqW7HR.js';
|
|
8
8
|
import 'ai';
|
|
9
9
|
import 'zod';
|
|
10
10
|
import 'hono/types';
|
|
@@ -18,90 +18,128 @@ import 'drizzle-orm/sqlite-core';
|
|
|
18
18
|
*/
|
|
19
19
|
declare function loadConfig(configPath?: string, workingDirectory?: string): ResolvedConfig;
|
|
20
20
|
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
21
|
+
/**
|
|
22
|
+
* tmux wrapper for terminal session management
|
|
23
|
+
*
|
|
24
|
+
* Provides a thin abstraction over tmux commands for:
|
|
25
|
+
* - Session creation and management
|
|
26
|
+
* - Output capture and logging
|
|
27
|
+
* - Process lifecycle management
|
|
28
|
+
*/
|
|
29
|
+
interface TerminalMeta {
|
|
29
30
|
id: string;
|
|
30
|
-
name: string | null;
|
|
31
31
|
command: string;
|
|
32
32
|
cwd: string;
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
error: string | null;
|
|
37
|
-
createdAt: Date;
|
|
38
|
-
stoppedAt: Date | null;
|
|
33
|
+
createdAt: string;
|
|
34
|
+
sessionId: string;
|
|
35
|
+
background: boolean;
|
|
39
36
|
}
|
|
37
|
+
interface TerminalResult {
|
|
38
|
+
id: string;
|
|
39
|
+
output: string;
|
|
40
|
+
exitCode: number;
|
|
41
|
+
status: 'completed' | 'running' | 'stopped' | 'error';
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* Check if tmux is installed and available
|
|
45
|
+
*/
|
|
46
|
+
declare function isTmuxAvailable(): Promise<boolean>;
|
|
47
|
+
/**
|
|
48
|
+
* Generate a unique terminal ID
|
|
49
|
+
* Ensure it starts with a letter (tmux session names work better this way)
|
|
50
|
+
*/
|
|
51
|
+
declare function generateTerminalId(): string;
|
|
52
|
+
/**
|
|
53
|
+
* Get the tmux session name for a terminal ID
|
|
54
|
+
*/
|
|
55
|
+
declare function getSessionName(terminalId: string): string;
|
|
56
|
+
/**
|
|
57
|
+
* Get the log directory for a terminal (session-scoped)
|
|
58
|
+
*/
|
|
59
|
+
declare function getLogDir(terminalId: string, workingDirectory: string, sessionId?: string): string;
|
|
60
|
+
/**
|
|
61
|
+
* Run a command synchronously in tmux (waits for completion)
|
|
62
|
+
*/
|
|
63
|
+
declare function runSync(command: string, workingDirectory: string, options: {
|
|
64
|
+
sessionId: string;
|
|
65
|
+
timeout?: number;
|
|
66
|
+
terminalId?: string;
|
|
67
|
+
}): Promise<TerminalResult>;
|
|
40
68
|
/**
|
|
41
|
-
*
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
69
|
+
* Run a command in the background (returns immediately)
|
|
70
|
+
*/
|
|
71
|
+
declare function runBackground(command: string, workingDirectory: string, options: {
|
|
72
|
+
sessionId: string;
|
|
73
|
+
terminalId?: string;
|
|
74
|
+
}): Promise<TerminalResult>;
|
|
75
|
+
/**
|
|
76
|
+
* Get logs from a terminal
|
|
77
|
+
*/
|
|
78
|
+
declare function getLogs(terminalId: string, workingDirectory: string, options?: {
|
|
79
|
+
tail?: number;
|
|
80
|
+
sessionId?: string;
|
|
81
|
+
}): Promise<{
|
|
82
|
+
output: string;
|
|
83
|
+
status: 'running' | 'stopped' | 'unknown';
|
|
84
|
+
}>;
|
|
85
|
+
/**
|
|
86
|
+
* Check if a terminal is running
|
|
87
|
+
*/
|
|
88
|
+
declare function isRunning(terminalId: string): Promise<boolean>;
|
|
89
|
+
/**
|
|
90
|
+
* Kill a terminal session
|
|
91
|
+
*/
|
|
92
|
+
declare function killTerminal(terminalId: string): Promise<boolean>;
|
|
93
|
+
/**
|
|
94
|
+
* List all sparkecoder terminal sessions
|
|
95
|
+
*/
|
|
96
|
+
declare function listSessions(): Promise<string[]>;
|
|
97
|
+
/**
|
|
98
|
+
* Get metadata for a terminal
|
|
99
|
+
*/
|
|
100
|
+
declare function getMeta(terminalId: string, workingDirectory: string, sessionId?: string): Promise<TerminalMeta | null>;
|
|
101
|
+
/**
|
|
102
|
+
* List all terminals for a session
|
|
103
|
+
*/
|
|
104
|
+
declare function listSessionTerminals(sessionId: string, workingDirectory: string): Promise<TerminalMeta[]>;
|
|
105
|
+
/**
|
|
106
|
+
* Send input (keystrokes) to a running terminal
|
|
107
|
+
* Use this to respond to interactive prompts
|
|
108
|
+
*/
|
|
109
|
+
declare function sendInput(terminalId: string, input: string, options?: {
|
|
110
|
+
pressEnter?: boolean;
|
|
111
|
+
}): Promise<boolean>;
|
|
112
|
+
/**
|
|
113
|
+
* Send special keys to a terminal (like arrow keys, escape, etc.)
|
|
114
|
+
*/
|
|
115
|
+
declare function sendKey(terminalId: string, key: 'Enter' | 'Escape' | 'Up' | 'Down' | 'Left' | 'Right' | 'Tab' | 'C-c' | 'C-d' | 'y' | 'n'): Promise<boolean>;
|
|
116
|
+
|
|
117
|
+
type tmux_TerminalMeta = TerminalMeta;
|
|
118
|
+
type tmux_TerminalResult = TerminalResult;
|
|
119
|
+
declare const tmux_generateTerminalId: typeof generateTerminalId;
|
|
120
|
+
declare const tmux_getLogDir: typeof getLogDir;
|
|
121
|
+
declare const tmux_getLogs: typeof getLogs;
|
|
122
|
+
declare const tmux_getMeta: typeof getMeta;
|
|
123
|
+
declare const tmux_getSessionName: typeof getSessionName;
|
|
124
|
+
declare const tmux_isRunning: typeof isRunning;
|
|
125
|
+
declare const tmux_isTmuxAvailable: typeof isTmuxAvailable;
|
|
126
|
+
declare const tmux_killTerminal: typeof killTerminal;
|
|
127
|
+
declare const tmux_listSessionTerminals: typeof listSessionTerminals;
|
|
128
|
+
declare const tmux_listSessions: typeof listSessions;
|
|
129
|
+
declare const tmux_runBackground: typeof runBackground;
|
|
130
|
+
declare const tmux_runSync: typeof runSync;
|
|
131
|
+
declare const tmux_sendInput: typeof sendInput;
|
|
132
|
+
declare const tmux_sendKey: typeof sendKey;
|
|
133
|
+
declare namespace tmux {
|
|
134
|
+
export { type tmux_TerminalMeta as TerminalMeta, type tmux_TerminalResult as TerminalResult, tmux_generateTerminalId as generateTerminalId, tmux_getLogDir as getLogDir, tmux_getLogs as getLogs, tmux_getMeta as getMeta, tmux_getSessionName as getSessionName, tmux_isRunning as isRunning, tmux_isTmuxAvailable as isTmuxAvailable, tmux_killTerminal as killTerminal, tmux_listSessionTerminals as listSessionTerminals, tmux_listSessions as listSessions, tmux_runBackground as runBackground, tmux_runSync as runSync, tmux_sendInput as sendInput, tmux_sendKey as sendKey };
|
|
96
135
|
}
|
|
97
|
-
declare function getTerminalManager(): TerminalManager;
|
|
98
136
|
|
|
99
137
|
/**
|
|
100
|
-
*
|
|
138
|
+
* SparkECoder - A powerful coding agent CLI with HTTP API
|
|
101
139
|
*
|
|
102
140
|
* @packageDocumentation
|
|
103
141
|
*/
|
|
104
142
|
|
|
105
143
|
declare const VERSION = "0.1.0";
|
|
106
144
|
|
|
107
|
-
export { ResolvedConfig,
|
|
145
|
+
export { ResolvedConfig, VERSION, loadConfig, tmux };
|