@agent-native/core 0.12.24 → 0.12.27
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/dist/agent/production-agent.d.ts +9 -2
- package/dist/agent/production-agent.d.ts.map +1 -1
- package/dist/agent/production-agent.js +56 -37
- package/dist/agent/production-agent.js.map +1 -1
- package/dist/agent/thread-data-builder.d.ts +16 -1
- package/dist/agent/thread-data-builder.d.ts.map +1 -1
- package/dist/agent/thread-data-builder.js +132 -0
- package/dist/agent/thread-data-builder.js.map +1 -1
- package/dist/client/AgentTaskCard.d.ts.map +1 -1
- package/dist/client/AgentTaskCard.js +16 -3
- package/dist/client/AgentTaskCard.js.map +1 -1
- package/dist/client/AssistantChat.d.ts.map +1 -1
- package/dist/client/AssistantChat.js +22 -12
- package/dist/client/AssistantChat.js.map +1 -1
- package/dist/client/IframeEmbed.d.ts.map +1 -1
- package/dist/client/IframeEmbed.js +2 -2
- package/dist/client/IframeEmbed.js.map +1 -1
- package/dist/client/agent-chat-adapter.d.ts.map +1 -1
- package/dist/client/agent-chat-adapter.js +77 -12
- package/dist/client/agent-chat-adapter.js.map +1 -1
- package/dist/client/composer/ComposerPlusMenu.d.ts.map +1 -1
- package/dist/client/composer/ComposerPlusMenu.js +1 -1
- package/dist/client/composer/ComposerPlusMenu.js.map +1 -1
- package/dist/client/composer/PromptComposer.d.ts.map +1 -1
- package/dist/client/composer/PromptComposer.js +8 -7
- package/dist/client/composer/PromptComposer.js.map +1 -1
- package/dist/client/composer/attachment-accept.d.ts +7 -0
- package/dist/client/composer/attachment-accept.d.ts.map +1 -0
- package/dist/client/composer/attachment-accept.js +36 -0
- package/dist/client/composer/attachment-accept.js.map +1 -0
- package/dist/client/progress/RunsTray.d.ts.map +1 -1
- package/dist/client/progress/RunsTray.js +3 -1
- package/dist/client/progress/RunsTray.js.map +1 -1
- package/dist/client/sse-event-processor.d.ts.map +1 -1
- package/dist/client/sse-event-processor.js +12 -1
- package/dist/client/sse-event-processor.js.map +1 -1
- package/dist/db/client.d.ts +3 -0
- package/dist/db/client.d.ts.map +1 -1
- package/dist/db/client.js +70 -34
- package/dist/db/client.js.map +1 -1
- package/dist/db/create-get-db.d.ts.map +1 -1
- package/dist/db/create-get-db.js +30 -7
- package/dist/db/create-get-db.js.map +1 -1
- package/dist/deploy/build.js +64 -0
- package/dist/deploy/build.js.map +1 -1
- package/dist/onboarding/default-steps.d.ts.map +1 -1
- package/dist/onboarding/default-steps.js +8 -1
- package/dist/onboarding/default-steps.js.map +1 -1
- package/dist/scripts/db/exec.d.ts.map +1 -1
- package/dist/scripts/db/exec.js +3 -6
- package/dist/scripts/db/exec.js.map +1 -1
- package/dist/scripts/db/patch.d.ts.map +1 -1
- package/dist/scripts/db/patch.js +3 -6
- package/dist/scripts/db/patch.js.map +1 -1
- package/dist/scripts/db/query.d.ts.map +1 -1
- package/dist/scripts/db/query.js +3 -6
- package/dist/scripts/db/query.js.map +1 -1
- package/dist/scripts/db/schema.d.ts.map +1 -1
- package/dist/scripts/db/schema.js +3 -6
- package/dist/scripts/db/schema.js.map +1 -1
- package/dist/scripts/db/sqlite-client.d.ts +15 -0
- package/dist/scripts/db/sqlite-client.d.ts.map +1 -0
- package/dist/scripts/db/sqlite-client.js +51 -0
- package/dist/scripts/db/sqlite-client.js.map +1 -0
- package/dist/server/agent-chat-plugin.d.ts.map +1 -1
- package/dist/server/agent-chat-plugin.js +53 -2
- package/dist/server/agent-chat-plugin.js.map +1 -1
- package/dist/server/better-auth-instance.js +4 -3
- package/dist/server/better-auth-instance.js.map +1 -1
- package/dist/server/credential-provider.d.ts +2 -2
- package/dist/server/credential-provider.d.ts.map +1 -1
- package/dist/server/credential-provider.js +22 -1
- package/dist/server/credential-provider.js.map +1 -1
- package/dist/server/google-oauth.js +1 -1
- package/dist/server/google-oauth.js.map +1 -1
- package/package.json +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"query.js","sourceRoot":"","sources":["../../../src/scripts/db/query.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Core script: db-query\n *\n * Run a read-only SQL query against a SQLite or Postgres database.\n *\n * In production mode, temporary views are created to scope data to the\n * current user (AGENT_USER_EMAIL). Tables with an `owner_email` column\n * and core tables (settings, application_state, etc.) are automatically\n * filtered so queries only return the current user's data.\n *\n * Usage:\n * pnpm action db-query --sql \"SELECT * FROM forms WHERE id = ?\" [--args '[\"abc\"]'] [--db path] [--format json] [--limit N]\n */\n\nimport path from \"path\";\nimport { createClient } from \"@libsql/client\";\nimport { getDatabaseUrl, getDatabaseAuthToken } from \"../../db/client.js\";\nimport { parseArgs, fail } from \"../utils.js\";\nimport { assertNoSensitiveFrameworkTables } from \"./safety.js\";\nimport { buildScopingPostgres, buildScopingSqlite } from \"./scoping.js\";\n\nfunction isPostgresUrl(url: string): boolean {\n return url.startsWith(\"postgres://\") || url.startsWith(\"postgresql://\");\n}\n\nfunction parseSqlArgs(raw: string | undefined): unknown[] {\n if (!raw) return [];\n try {\n const parsed = JSON.parse(raw);\n if (Array.isArray(parsed)) return parsed;\n } catch {\n // Fall through to the shared error below.\n }\n fail(\"--args must be a JSON array\");\n}\n\nfunction convertQuestionMarksToPostgresParams(sql: string): string {\n let index = 0;\n let out = \"\";\n let state: \"normal\" | \"single\" | \"double\" | \"line-comment\" | \"block-comment\" =\n \"normal\";\n\n for (let i = 0; i < sql.length; i++) {\n const ch = sql[i];\n const next = sql[i + 1];\n\n if (state === \"line-comment\") {\n out += ch;\n if (ch === \"\\n\") state = \"normal\";\n continue;\n }\n\n if (state === \"block-comment\") {\n out += ch;\n if (ch === \"*\" && next === \"/\") {\n out += next;\n i++;\n state = \"normal\";\n }\n continue;\n }\n\n if (state === \"single\") {\n out += ch;\n if (ch === \"'\" && next === \"'\") {\n out += next;\n i++;\n } else if (ch === \"'\") {\n state = \"normal\";\n }\n continue;\n }\n\n if (state === \"double\") {\n out += ch;\n if (ch === '\"' && next === '\"') {\n out += next;\n i++;\n } else if (ch === '\"') {\n state = \"normal\";\n }\n continue;\n }\n\n if (ch === \"-\" && next === \"-\") {\n out += ch + next;\n i++;\n state = \"line-comment\";\n continue;\n }\n if (ch === \"/\" && next === \"*\") {\n out += ch + next;\n i++;\n state = \"block-comment\";\n continue;\n }\n if (ch === \"'\") {\n out += ch;\n state = \"single\";\n continue;\n }\n if (ch === '\"') {\n out += ch;\n state = \"double\";\n continue;\n }\n if (ch === \"?\") {\n index++;\n out += `$${index}`;\n continue;\n }\n out += ch;\n }\n\n return out;\n}\n\nfunction normalizePostgresSql(sql: string, args: unknown[]): string {\n if (args.length === 0 || /\\$\\d+\\b/.test(sql)) return sql;\n return convertQuestionMarksToPostgresParams(sql);\n}\n\nfunction printTable(\n rows: Record<string, unknown>[],\n finalSql: string,\n format?: string,\n) {\n if (format === \"json\") {\n console.log(\n JSON.stringify({ query: finalSql, rows, count: rows.length }, null, 2),\n );\n return;\n }\n\n console.log(`Query: ${finalSql}`);\n console.log(`Rows: ${rows.length}\\n`);\n\n if (rows.length === 0) {\n console.log(\"(no results)\");\n return;\n }\n\n const keys = Object.keys(rows[0]);\n const widths = keys.map((k) => {\n const maxVal = Math.max(...rows.map((r) => String(r[k] ?? \"NULL\").length));\n return Math.max(k.length, Math.min(maxVal, 60));\n });\n\n const header = keys.map((k, i) => k.padEnd(widths[i])).join(\" | \");\n console.log(header);\n console.log(widths.map((w) => \"-\".repeat(w)).join(\"-+-\"));\n\n for (const row of rows) {\n const line = keys\n .map((k, i) => {\n const val = String(row[k] ?? \"NULL\");\n return val.length > 60\n ? val.slice(0, 57) + \"...\"\n : val.padEnd(widths[i]);\n })\n .join(\" | \");\n console.log(line);\n }\n}\n\nexport default async function dbQuery(args: string[]): Promise<void> {\n const parsed = parseArgs(args);\n\n if (parsed.help === \"true\") {\n console.log(`Usage: pnpm action db-query --sql \"<query>\" [options]\n\nOptions:\n --sql <query> SQL SELECT query to run (required)\n --args <json> JSON array of positional SQL bind parameters\n --db <path> Path to SQLite database (default: data/app.db)\n --format json Output as JSON instead of a table\n --limit N Append LIMIT N if not already present\n --help Show this help message`);\n return;\n }\n\n const sql = parsed.sql;\n if (!sql) {\n fail('--sql is required. Example: --sql \"SELECT * FROM forms\"');\n }\n const sqlArgs = parseSqlArgs(parsed.args);\n\n // Safety: only allow read-only statements.\n // Strip leading SQL comments before checking the prefix.\n const stripped = sql\n .replace(/^\\s*--[^\\n]*\\n/gm, \"\")\n .replace(/\\/\\*[\\s\\S]*?\\*\\//g, \"\")\n .trim();\n const upper = stripped.toUpperCase();\n if (\n !upper.startsWith(\"SELECT\") &&\n !upper.startsWith(\"WITH\") &&\n !upper.startsWith(\"EXPLAIN\") &&\n !upper.startsWith(\"PRAGMA\")\n ) {\n fail(\n \"Only SELECT, WITH, EXPLAIN, and PRAGMA queries are allowed. Use db-exec for writes.\",\n );\n }\n assertNoSensitiveFrameworkTables(stripped, \"read\");\n\n // Resolve database URL: --db flag → DATABASE_URL env → default file path\n let url: string;\n if (parsed.db) {\n url = \"file:\" + path.resolve(parsed.db);\n } else if (getDatabaseUrl()) {\n url = getDatabaseUrl();\n } else {\n url = \"file:\" + path.resolve(process.cwd(), \"data\", \"app.db\");\n }\n\n let finalSql = sql;\n if (\n parsed.limit &&\n (upper.startsWith(\"SELECT\") || upper.startsWith(\"WITH\")) &&\n !/\\bLIMIT\\b/i.test(stripped)\n ) {\n const limitVal = parseInt(parsed.limit, 10);\n if (isNaN(limitVal) || limitVal < 1)\n fail(\"--limit must be a positive integer\");\n finalSql = `${sql} LIMIT ${limitVal}`;\n }\n\n // Postgres path\n if (isPostgresUrl(url)) {\n const { default: pg } = await import(\"postgres\");\n const pgSql = pg(url);\n try {\n const pgSqlText = normalizePostgresSql(finalSql, sqlArgs);\n let rows: Record<string, unknown>[] = [];\n await pgSql.begin(async (tx: any) => {\n // Temp views are session state. Keep setup/query/teardown on one\n // transaction-bound backend so pooled Postgres never retains them.\n const scoping = await buildScopingPostgres(tx);\n try {\n for (const stmt of scoping.setup) {\n await tx.unsafe(stmt);\n }\n\n const result =\n sqlArgs.length > 0\n ? await tx.unsafe(pgSqlText, sqlArgs as any[])\n : await tx.unsafe(pgSqlText);\n rows = Array.from(result);\n } finally {\n for (const stmt of scoping.teardown) {\n await tx.unsafe(stmt).catch(() => {});\n }\n }\n });\n const keys = rows.length > 0 ? Object.keys(rows[0]) : [];\n\n printTable(\n rows.length > 0 ? rows : keys.length > 0 ? rows : [],\n pgSqlText,\n parsed.format,\n );\n } finally {\n await pgSql.end();\n }\n return;\n }\n\n // libsql / SQLite path\n const client = createClient({\n url,\n authToken: getDatabaseAuthToken(),\n });\n\n try {\n // Set up user-scoped temp views in production\n const scoping = await buildScopingSqlite(client);\n for (const stmt of scoping.setup) {\n await client.execute(stmt);\n }\n\n const result =\n sqlArgs.length > 0\n ? await client.execute({ sql: finalSql, args: sqlArgs as any[] })\n : await client.execute(finalSql);\n const rows: Record<string, unknown>[] = result.rows.map((row) => {\n const obj: Record<string, unknown> = {};\n for (let i = 0; i < result.columns.length; i++) {\n obj[result.columns[i]] = row[i];\n }\n return obj;\n });\n\n printTable(rows, finalSql, parsed.format);\n\n // Tear down temp views\n for (const stmt of scoping.teardown) {\n await client.execute(stmt).catch(() => {});\n }\n } finally {\n client.close();\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"query.js","sourceRoot":"","sources":["../../../src/scripts/db/query.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Core script: db-query\n *\n * Run a read-only SQL query against a SQLite or Postgres database.\n *\n * In production mode, temporary views are created to scope data to the\n * current user (AGENT_USER_EMAIL). Tables with an `owner_email` column\n * and core tables (settings, application_state, etc.) are automatically\n * filtered so queries only return the current user's data.\n *\n * Usage:\n * pnpm action db-query --sql \"SELECT * FROM forms WHERE id = ?\" [--args '[\"abc\"]'] [--db path] [--format json] [--limit N]\n */\n\nimport path from \"path\";\nimport { getDatabaseUrl } from \"../../db/client.js\";\nimport { parseArgs, fail } from \"../utils.js\";\nimport { assertNoSensitiveFrameworkTables } from \"./safety.js\";\nimport { buildScopingPostgres, buildScopingSqlite } from \"./scoping.js\";\nimport { createSqliteScriptClient } from \"./sqlite-client.js\";\n\nfunction isPostgresUrl(url: string): boolean {\n return url.startsWith(\"postgres://\") || url.startsWith(\"postgresql://\");\n}\n\nfunction parseSqlArgs(raw: string | undefined): unknown[] {\n if (!raw) return [];\n try {\n const parsed = JSON.parse(raw);\n if (Array.isArray(parsed)) return parsed;\n } catch {\n // Fall through to the shared error below.\n }\n fail(\"--args must be a JSON array\");\n}\n\nfunction convertQuestionMarksToPostgresParams(sql: string): string {\n let index = 0;\n let out = \"\";\n let state: \"normal\" | \"single\" | \"double\" | \"line-comment\" | \"block-comment\" =\n \"normal\";\n\n for (let i = 0; i < sql.length; i++) {\n const ch = sql[i];\n const next = sql[i + 1];\n\n if (state === \"line-comment\") {\n out += ch;\n if (ch === \"\\n\") state = \"normal\";\n continue;\n }\n\n if (state === \"block-comment\") {\n out += ch;\n if (ch === \"*\" && next === \"/\") {\n out += next;\n i++;\n state = \"normal\";\n }\n continue;\n }\n\n if (state === \"single\") {\n out += ch;\n if (ch === \"'\" && next === \"'\") {\n out += next;\n i++;\n } else if (ch === \"'\") {\n state = \"normal\";\n }\n continue;\n }\n\n if (state === \"double\") {\n out += ch;\n if (ch === '\"' && next === '\"') {\n out += next;\n i++;\n } else if (ch === '\"') {\n state = \"normal\";\n }\n continue;\n }\n\n if (ch === \"-\" && next === \"-\") {\n out += ch + next;\n i++;\n state = \"line-comment\";\n continue;\n }\n if (ch === \"/\" && next === \"*\") {\n out += ch + next;\n i++;\n state = \"block-comment\";\n continue;\n }\n if (ch === \"'\") {\n out += ch;\n state = \"single\";\n continue;\n }\n if (ch === '\"') {\n out += ch;\n state = \"double\";\n continue;\n }\n if (ch === \"?\") {\n index++;\n out += `$${index}`;\n continue;\n }\n out += ch;\n }\n\n return out;\n}\n\nfunction normalizePostgresSql(sql: string, args: unknown[]): string {\n if (args.length === 0 || /\\$\\d+\\b/.test(sql)) return sql;\n return convertQuestionMarksToPostgresParams(sql);\n}\n\nfunction printTable(\n rows: Record<string, unknown>[],\n finalSql: string,\n format?: string,\n) {\n if (format === \"json\") {\n console.log(\n JSON.stringify({ query: finalSql, rows, count: rows.length }, null, 2),\n );\n return;\n }\n\n console.log(`Query: ${finalSql}`);\n console.log(`Rows: ${rows.length}\\n`);\n\n if (rows.length === 0) {\n console.log(\"(no results)\");\n return;\n }\n\n const keys = Object.keys(rows[0]);\n const widths = keys.map((k) => {\n const maxVal = Math.max(...rows.map((r) => String(r[k] ?? \"NULL\").length));\n return Math.max(k.length, Math.min(maxVal, 60));\n });\n\n const header = keys.map((k, i) => k.padEnd(widths[i])).join(\" | \");\n console.log(header);\n console.log(widths.map((w) => \"-\".repeat(w)).join(\"-+-\"));\n\n for (const row of rows) {\n const line = keys\n .map((k, i) => {\n const val = String(row[k] ?? \"NULL\");\n return val.length > 60\n ? val.slice(0, 57) + \"...\"\n : val.padEnd(widths[i]);\n })\n .join(\" | \");\n console.log(line);\n }\n}\n\nexport default async function dbQuery(args: string[]): Promise<void> {\n const parsed = parseArgs(args);\n\n if (parsed.help === \"true\") {\n console.log(`Usage: pnpm action db-query --sql \"<query>\" [options]\n\nOptions:\n --sql <query> SQL SELECT query to run (required)\n --args <json> JSON array of positional SQL bind parameters\n --db <path> Path to SQLite database (default: data/app.db)\n --format json Output as JSON instead of a table\n --limit N Append LIMIT N if not already present\n --help Show this help message`);\n return;\n }\n\n const sql = parsed.sql;\n if (!sql) {\n fail('--sql is required. Example: --sql \"SELECT * FROM forms\"');\n }\n const sqlArgs = parseSqlArgs(parsed.args);\n\n // Safety: only allow read-only statements.\n // Strip leading SQL comments before checking the prefix.\n const stripped = sql\n .replace(/^\\s*--[^\\n]*\\n/gm, \"\")\n .replace(/\\/\\*[\\s\\S]*?\\*\\//g, \"\")\n .trim();\n const upper = stripped.toUpperCase();\n if (\n !upper.startsWith(\"SELECT\") &&\n !upper.startsWith(\"WITH\") &&\n !upper.startsWith(\"EXPLAIN\") &&\n !upper.startsWith(\"PRAGMA\")\n ) {\n fail(\n \"Only SELECT, WITH, EXPLAIN, and PRAGMA queries are allowed. Use db-exec for writes.\",\n );\n }\n assertNoSensitiveFrameworkTables(stripped, \"read\");\n\n // Resolve database URL: --db flag → DATABASE_URL env → default file path\n let url: string;\n if (parsed.db) {\n url = \"file:\" + path.resolve(parsed.db);\n } else if (getDatabaseUrl()) {\n url = getDatabaseUrl();\n } else {\n url = \"file:\" + path.resolve(process.cwd(), \"data\", \"app.db\");\n }\n\n let finalSql = sql;\n if (\n parsed.limit &&\n (upper.startsWith(\"SELECT\") || upper.startsWith(\"WITH\")) &&\n !/\\bLIMIT\\b/i.test(stripped)\n ) {\n const limitVal = parseInt(parsed.limit, 10);\n if (isNaN(limitVal) || limitVal < 1)\n fail(\"--limit must be a positive integer\");\n finalSql = `${sql} LIMIT ${limitVal}`;\n }\n\n // Postgres path\n if (isPostgresUrl(url)) {\n const { default: pg } = await import(\"postgres\");\n const pgSql = pg(url);\n try {\n const pgSqlText = normalizePostgresSql(finalSql, sqlArgs);\n let rows: Record<string, unknown>[] = [];\n await pgSql.begin(async (tx: any) => {\n // Temp views are session state. Keep setup/query/teardown on one\n // transaction-bound backend so pooled Postgres never retains them.\n const scoping = await buildScopingPostgres(tx);\n try {\n for (const stmt of scoping.setup) {\n await tx.unsafe(stmt);\n }\n\n const result =\n sqlArgs.length > 0\n ? await tx.unsafe(pgSqlText, sqlArgs as any[])\n : await tx.unsafe(pgSqlText);\n rows = Array.from(result);\n } finally {\n for (const stmt of scoping.teardown) {\n await tx.unsafe(stmt).catch(() => {});\n }\n }\n });\n const keys = rows.length > 0 ? Object.keys(rows[0]) : [];\n\n printTable(\n rows.length > 0 ? rows : keys.length > 0 ? rows : [],\n pgSqlText,\n parsed.format,\n );\n } finally {\n await pgSql.end();\n }\n return;\n }\n\n // libsql / SQLite path\n const client = await createSqliteScriptClient(url);\n\n try {\n // Set up user-scoped temp views in production\n const scoping = await buildScopingSqlite(client);\n for (const stmt of scoping.setup) {\n await client.execute(stmt);\n }\n\n const result =\n sqlArgs.length > 0\n ? await client.execute({ sql: finalSql, args: sqlArgs as any[] })\n : await client.execute(finalSql);\n const rows: Record<string, unknown>[] = result.rows.map((row) => {\n const obj: Record<string, unknown> = {};\n for (let i = 0; i < result.columns.length; i++) {\n obj[result.columns[i]] = row[i];\n }\n return obj;\n });\n\n printTable(rows, finalSql, parsed.format);\n\n // Tear down temp views\n for (const stmt of scoping.teardown) {\n await client.execute(stmt).catch(() => {});\n }\n } finally {\n client.close();\n }\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"schema.d.ts","sourceRoot":"","sources":["../../../src/scripts/db/schema.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;
|
|
1
|
+
{"version":3,"file":"schema.d.ts","sourceRoot":"","sources":["../../../src/scripts/db/schema.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AA0NH,wBAA8B,QAAQ,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAuIpE"}
|
|
@@ -9,9 +9,9 @@
|
|
|
9
9
|
* pnpm action db-schema [--db path] [--format json]
|
|
10
10
|
*/
|
|
11
11
|
import path from "path";
|
|
12
|
-
import {
|
|
13
|
-
import { getDatabaseUrl, getDatabaseAuthToken } from "../../db/client.js";
|
|
12
|
+
import { getDatabaseUrl } from "../../db/client.js";
|
|
14
13
|
import { parseArgs } from "../utils.js";
|
|
14
|
+
import { createSqliteScriptClient, } from "./sqlite-client.js";
|
|
15
15
|
function isPostgresUrl(url) {
|
|
16
16
|
return url.startsWith("postgres://") || url.startsWith("postgresql://");
|
|
17
17
|
}
|
|
@@ -197,10 +197,7 @@ Options:
|
|
|
197
197
|
return introspectPostgres(url, parsed);
|
|
198
198
|
}
|
|
199
199
|
// SQLite / libsql path
|
|
200
|
-
const client =
|
|
201
|
-
url,
|
|
202
|
-
authToken: getDatabaseAuthToken(),
|
|
203
|
-
});
|
|
200
|
+
const client = await createSqliteScriptClient(url);
|
|
204
201
|
try {
|
|
205
202
|
const tablesResult = await client.execute(`SELECT name FROM sqlite_master WHERE type='table' AND name NOT LIKE 'sqlite_%' ORDER BY name`);
|
|
206
203
|
const tables = tablesResult.rows.map((row) => ({
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"schema.js","sourceRoot":"","sources":["../../../src/scripts/db/schema.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Core script: db-schema\n *\n * Inspects a SQLite or Postgres database and prints all tables, columns, types,\n * constraints, and foreign keys. Gives the agent full visibility\n * into the app's data model.\n *\n * Usage:\n * pnpm action db-schema [--db path] [--format json]\n */\n\nimport path from \"path\";\nimport { createClient, type Client } from \"@libsql/client\";\nimport { getDatabaseUrl, getDatabaseAuthToken } from \"../../db/client.js\";\nimport { parseArgs, fail } from \"../utils.js\";\n\ninterface ColumnInfo {\n name: string;\n type: string;\n notnull: boolean;\n pk: boolean;\n dflt_value: string | null;\n}\n\ninterface ForeignKey {\n from: string;\n table: string;\n to: string;\n}\n\ninterface TableInfo {\n name: string;\n columns: ColumnInfo[];\n foreignKeys: ForeignKey[];\n indexes: { name: string; unique: boolean; columns: string[] }[];\n}\n\nfunction isPostgresUrl(url: string): boolean {\n return url.startsWith(\"postgres://\") || url.startsWith(\"postgresql://\");\n}\n\nfunction databaseLabel(url: string): string {\n if (url.startsWith(\"file:\")) return url.slice(5);\n try {\n const parsed = new URL(url);\n const auth = parsed.username ? `${parsed.username}:***@` : \"\";\n return `${parsed.protocol}//${auth}${parsed.host}${parsed.pathname}`;\n } catch {\n return url.replace(/:\\/\\/([^:@\\s]+):([^@\\s]+)@/, \"://$1:***@\");\n }\n}\n\n/**\n * Execute a PRAGMA query and return the rows as plain objects.\n */\nasync function pragma(\n client: Client,\n pragmaQuery: string,\n): Promise<Record<string, unknown>[]> {\n const result = await client.execute(pragmaQuery);\n return result.rows.map((row) => {\n const obj: Record<string, unknown> = {};\n for (let i = 0; i < result.columns.length; i++) {\n obj[result.columns[i]] = row[i];\n }\n return obj;\n });\n}\n\n// ---------------------------------------------------------------------------\n// Postgres introspection\n// ---------------------------------------------------------------------------\n\nasync function introspectPostgres(\n url: string,\n parsed: Record<string, string>,\n): Promise<void> {\n const { default: pg } = await import(\"postgres\");\n const sql = pg(url);\n\n try {\n // List tables\n const tables: { name: string }[] = await sql`\n SELECT table_name as name\n FROM information_schema.tables\n WHERE table_schema = 'public' AND table_type = 'BASE TABLE'\n ORDER BY table_name\n `;\n\n const tableInfos: TableInfo[] = [];\n\n for (const t of tables) {\n // Columns\n const cols: any[] = await sql`\n SELECT\n column_name as name,\n data_type as type,\n CASE WHEN is_nullable = 'NO' THEN 1 ELSE 0 END as notnull,\n column_default as dflt_value\n FROM information_schema.columns\n WHERE table_name = ${t.name}\n ORDER BY ordinal_position\n `;\n\n // Primary keys\n const pks: any[] = await sql`\n SELECT kcu.column_name\n FROM information_schema.table_constraints tc\n JOIN information_schema.key_column_usage kcu\n ON tc.constraint_name = kcu.constraint_name\n AND tc.table_schema = kcu.table_schema\n WHERE tc.table_name = ${t.name}\n AND tc.constraint_type = 'PRIMARY KEY'\n `;\n const pkSet = new Set(pks.map((p) => p.column_name));\n\n // Foreign keys\n const fks: any[] = await sql`\n SELECT\n kcu.column_name as \"from\",\n ccu.table_name as \"table\",\n ccu.column_name as \"to\"\n FROM information_schema.table_constraints tc\n JOIN information_schema.key_column_usage kcu\n ON tc.constraint_name = kcu.constraint_name\n JOIN information_schema.constraint_column_usage ccu\n ON tc.constraint_name = ccu.constraint_name\n WHERE tc.table_name = ${t.name}\n AND tc.constraint_type = 'FOREIGN KEY'\n `;\n\n // Indexes\n const idxRows: any[] = await sql`\n SELECT indexname as name, indexdef\n FROM pg_indexes\n WHERE tablename = ${t.name} AND schemaname = 'public'\n `;\n const indexes = idxRows.map((idx) => {\n const unique = /\\bUNIQUE\\b/i.test(idx.indexdef);\n // Extract column list from CREATE INDEX ... (col1, col2)\n const colMatch = idx.indexdef.match(/\\(([^)]+)\\)/);\n const columns = colMatch\n ? colMatch[1].split(\",\").map((c: string) => c.trim())\n : [];\n return { name: idx.name, unique, columns };\n });\n\n tableInfos.push({\n name: t.name,\n columns: cols.map((c) => ({\n name: c.name,\n type: c.type || \"ANY\",\n notnull: c.notnull === 1,\n pk: pkSet.has(c.name),\n dflt_value: c.dflt_value as string | null,\n })),\n foreignKeys: fks.map((fk) => ({\n from: fk.from,\n table: fk.table,\n to: fk.to,\n })),\n indexes,\n });\n }\n\n if (parsed.format === \"json\") {\n console.log(\n JSON.stringify(\n { database: databaseLabel(url), tables: tableInfos },\n null,\n 2,\n ),\n );\n return;\n }\n\n // Human-readable output\n console.log(`Database: ${databaseLabel(url)}`);\n console.log(`Tables: ${tableInfos.length}\\n`);\n\n for (const table of tableInfos) {\n console.log(`Table: ${table.name} (${table.columns.length} columns)`);\n\n const fkMap = new Map<string, string>();\n for (const fk of table.foreignKeys) {\n fkMap.set(fk.from, `${fk.table}(${fk.to})`);\n }\n\n const nameWidth = Math.max(...table.columns.map((c) => c.name.length));\n const typeWidth = Math.max(...table.columns.map((c) => c.type.length));\n\n for (const col of table.columns) {\n const parts: string[] = [];\n if (col.pk) parts.push(\"PRIMARY KEY\");\n if (col.notnull && !col.pk) parts.push(\"NOT NULL\");\n if (col.dflt_value !== null) parts.push(`DEFAULT ${col.dflt_value}`);\n const fkRef = fkMap.get(col.name);\n if (fkRef) parts.push(`→ ${fkRef}`);\n\n const constraint = parts.length > 0 ? ` ${parts.join(\", \")}` : \"\";\n console.log(\n ` ${col.name.padEnd(nameWidth)} ${col.type.padEnd(typeWidth)}${constraint}`,\n );\n }\n\n if (table.indexes.length > 0) {\n console.log(` Indexes:`);\n for (const idx of table.indexes) {\n const unique = idx.unique ? \"UNIQUE \" : \"\";\n console.log(` ${unique}${idx.name} (${idx.columns.join(\", \")})`);\n }\n }\n\n console.log();\n }\n } finally {\n await sql.end();\n }\n}\n\n// ---------------------------------------------------------------------------\n// Main entry\n// ---------------------------------------------------------------------------\n\nexport default async function dbSchema(args: string[]): Promise<void> {\n const parsed = parseArgs(args);\n\n if (parsed.help === \"true\") {\n console.log(`Usage: pnpm action db-schema [--db <path>] [--format json]\n\nOptions:\n --db <path> Path to SQLite database (default: data/app.db)\n --format json Output as JSON instead of human-readable text\n --help Show this help message`);\n return;\n }\n\n // Resolve database URL: --db flag → DATABASE_URL env → default file path\n let url: string;\n if (parsed.db) {\n url = \"file:\" + path.resolve(parsed.db);\n } else if (getDatabaseUrl()) {\n url = getDatabaseUrl();\n } else {\n url = \"file:\" + path.resolve(process.cwd(), \"data\", \"app.db\");\n }\n\n // Postgres path\n if (isPostgresUrl(url)) {\n return introspectPostgres(url, parsed);\n }\n\n // SQLite / libsql path\n const client = createClient({\n url,\n authToken: getDatabaseAuthToken(),\n });\n\n try {\n const tablesResult = await client.execute(\n `SELECT name FROM sqlite_master WHERE type='table' AND name NOT LIKE 'sqlite_%' ORDER BY name`,\n );\n const tables = tablesResult.rows.map((row) => ({\n name: row[0] as string,\n }));\n\n const tableInfos: TableInfo[] = [];\n\n for (const t of tables) {\n const escaped = t.name.replace(/\"/g, '\"\"');\n\n const columns = await pragma(client, `PRAGMA table_info(\"${escaped}\")`);\n const fks = await pragma(client, `PRAGMA foreign_key_list(\"${escaped}\")`);\n const idxList = await pragma(client, `PRAGMA index_list(\"${escaped}\")`);\n\n const indexes: { name: string; unique: boolean; columns: string[] }[] =\n [];\n for (const idx of idxList) {\n const idxName = idx.name as string;\n if (idxName.startsWith(\"sqlite_\")) continue;\n const idxInfo = await pragma(\n client,\n `PRAGMA index_info(\"${idxName.replace(/\"/g, '\"\"')}\")`,\n );\n indexes.push({\n name: idxName,\n unique: idx.unique === 1,\n columns: idxInfo.map((c) => c.name as string),\n });\n }\n\n tableInfos.push({\n name: t.name,\n columns: columns.map((c) => ({\n name: c.name as string,\n type: (c.type as string) || \"ANY\",\n notnull: c.notnull === 1,\n pk: c.pk === 1,\n dflt_value: c.dflt_value as string | null,\n })),\n foreignKeys: fks.map((fk) => ({\n from: fk.from as string,\n table: fk.table as string,\n to: fk.to as string,\n })),\n indexes,\n });\n }\n\n if (parsed.format === \"json\") {\n const dbLabel = databaseLabel(url);\n console.log(\n JSON.stringify({ database: dbLabel, tables: tableInfos }, null, 2),\n );\n return;\n }\n\n // Human-readable output\n const dbLabel = databaseLabel(url);\n console.log(`Database: ${dbLabel}`);\n console.log(`Tables: ${tableInfos.length}\\n`);\n\n for (const table of tableInfos) {\n console.log(`Table: ${table.name} (${table.columns.length} columns)`);\n\n // Build FK lookup for annotation\n const fkMap = new Map<string, string>();\n for (const fk of table.foreignKeys) {\n fkMap.set(fk.from, `${fk.table}(${fk.to})`);\n }\n\n // Find max widths for alignment\n const nameWidth = Math.max(...table.columns.map((c) => c.name.length));\n const typeWidth = Math.max(...table.columns.map((c) => c.type.length));\n\n for (const col of table.columns) {\n const parts: string[] = [];\n if (col.pk) parts.push(\"PRIMARY KEY\");\n if (col.notnull && !col.pk) parts.push(\"NOT NULL\");\n if (col.dflt_value !== null) parts.push(`DEFAULT ${col.dflt_value}`);\n const fkRef = fkMap.get(col.name);\n if (fkRef) parts.push(`→ ${fkRef}`);\n\n const constraint = parts.length > 0 ? ` ${parts.join(\", \")}` : \"\";\n console.log(\n ` ${col.name.padEnd(nameWidth)} ${col.type.padEnd(typeWidth)}${constraint}`,\n );\n }\n\n if (table.indexes.length > 0) {\n console.log(` Indexes:`);\n for (const idx of table.indexes) {\n const unique = idx.unique ? \"UNIQUE \" : \"\";\n console.log(` ${unique}${idx.name} (${idx.columns.join(\", \")})`);\n }\n }\n\n console.log();\n }\n } finally {\n client.close();\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"schema.js","sourceRoot":"","sources":["../../../src/scripts/db/schema.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Core script: db-schema\n *\n * Inspects a SQLite or Postgres database and prints all tables, columns, types,\n * constraints, and foreign keys. Gives the agent full visibility\n * into the app's data model.\n *\n * Usage:\n * pnpm action db-schema [--db path] [--format json]\n */\n\nimport path from \"path\";\nimport { getDatabaseUrl } from \"../../db/client.js\";\nimport { parseArgs, fail } from \"../utils.js\";\nimport {\n createSqliteScriptClient,\n type SqliteScriptClient,\n} from \"./sqlite-client.js\";\n\ninterface ColumnInfo {\n name: string;\n type: string;\n notnull: boolean;\n pk: boolean;\n dflt_value: string | null;\n}\n\ninterface ForeignKey {\n from: string;\n table: string;\n to: string;\n}\n\ninterface TableInfo {\n name: string;\n columns: ColumnInfo[];\n foreignKeys: ForeignKey[];\n indexes: { name: string; unique: boolean; columns: string[] }[];\n}\n\nfunction isPostgresUrl(url: string): boolean {\n return url.startsWith(\"postgres://\") || url.startsWith(\"postgresql://\");\n}\n\nfunction databaseLabel(url: string): string {\n if (url.startsWith(\"file:\")) return url.slice(5);\n try {\n const parsed = new URL(url);\n const auth = parsed.username ? `${parsed.username}:***@` : \"\";\n return `${parsed.protocol}//${auth}${parsed.host}${parsed.pathname}`;\n } catch {\n return url.replace(/:\\/\\/([^:@\\s]+):([^@\\s]+)@/, \"://$1:***@\");\n }\n}\n\n/**\n * Execute a PRAGMA query and return the rows as plain objects.\n */\nasync function pragma(\n client: SqliteScriptClient,\n pragmaQuery: string,\n): Promise<Record<string, unknown>[]> {\n const result = await client.execute(pragmaQuery);\n return result.rows.map((row) => {\n const obj: Record<string, unknown> = {};\n for (let i = 0; i < result.columns.length; i++) {\n obj[result.columns[i]] = row[i];\n }\n return obj;\n });\n}\n\n// ---------------------------------------------------------------------------\n// Postgres introspection\n// ---------------------------------------------------------------------------\n\nasync function introspectPostgres(\n url: string,\n parsed: Record<string, string>,\n): Promise<void> {\n const { default: pg } = await import(\"postgres\");\n const sql = pg(url);\n\n try {\n // List tables\n const tables: { name: string }[] = await sql`\n SELECT table_name as name\n FROM information_schema.tables\n WHERE table_schema = 'public' AND table_type = 'BASE TABLE'\n ORDER BY table_name\n `;\n\n const tableInfos: TableInfo[] = [];\n\n for (const t of tables) {\n // Columns\n const cols: any[] = await sql`\n SELECT\n column_name as name,\n data_type as type,\n CASE WHEN is_nullable = 'NO' THEN 1 ELSE 0 END as notnull,\n column_default as dflt_value\n FROM information_schema.columns\n WHERE table_name = ${t.name}\n ORDER BY ordinal_position\n `;\n\n // Primary keys\n const pks: any[] = await sql`\n SELECT kcu.column_name\n FROM information_schema.table_constraints tc\n JOIN information_schema.key_column_usage kcu\n ON tc.constraint_name = kcu.constraint_name\n AND tc.table_schema = kcu.table_schema\n WHERE tc.table_name = ${t.name}\n AND tc.constraint_type = 'PRIMARY KEY'\n `;\n const pkSet = new Set(pks.map((p) => p.column_name));\n\n // Foreign keys\n const fks: any[] = await sql`\n SELECT\n kcu.column_name as \"from\",\n ccu.table_name as \"table\",\n ccu.column_name as \"to\"\n FROM information_schema.table_constraints tc\n JOIN information_schema.key_column_usage kcu\n ON tc.constraint_name = kcu.constraint_name\n JOIN information_schema.constraint_column_usage ccu\n ON tc.constraint_name = ccu.constraint_name\n WHERE tc.table_name = ${t.name}\n AND tc.constraint_type = 'FOREIGN KEY'\n `;\n\n // Indexes\n const idxRows: any[] = await sql`\n SELECT indexname as name, indexdef\n FROM pg_indexes\n WHERE tablename = ${t.name} AND schemaname = 'public'\n `;\n const indexes = idxRows.map((idx) => {\n const unique = /\\bUNIQUE\\b/i.test(idx.indexdef);\n // Extract column list from CREATE INDEX ... (col1, col2)\n const colMatch = idx.indexdef.match(/\\(([^)]+)\\)/);\n const columns = colMatch\n ? colMatch[1].split(\",\").map((c: string) => c.trim())\n : [];\n return { name: idx.name, unique, columns };\n });\n\n tableInfos.push({\n name: t.name,\n columns: cols.map((c) => ({\n name: c.name,\n type: c.type || \"ANY\",\n notnull: c.notnull === 1,\n pk: pkSet.has(c.name),\n dflt_value: c.dflt_value as string | null,\n })),\n foreignKeys: fks.map((fk) => ({\n from: fk.from,\n table: fk.table,\n to: fk.to,\n })),\n indexes,\n });\n }\n\n if (parsed.format === \"json\") {\n console.log(\n JSON.stringify(\n { database: databaseLabel(url), tables: tableInfos },\n null,\n 2,\n ),\n );\n return;\n }\n\n // Human-readable output\n console.log(`Database: ${databaseLabel(url)}`);\n console.log(`Tables: ${tableInfos.length}\\n`);\n\n for (const table of tableInfos) {\n console.log(`Table: ${table.name} (${table.columns.length} columns)`);\n\n const fkMap = new Map<string, string>();\n for (const fk of table.foreignKeys) {\n fkMap.set(fk.from, `${fk.table}(${fk.to})`);\n }\n\n const nameWidth = Math.max(...table.columns.map((c) => c.name.length));\n const typeWidth = Math.max(...table.columns.map((c) => c.type.length));\n\n for (const col of table.columns) {\n const parts: string[] = [];\n if (col.pk) parts.push(\"PRIMARY KEY\");\n if (col.notnull && !col.pk) parts.push(\"NOT NULL\");\n if (col.dflt_value !== null) parts.push(`DEFAULT ${col.dflt_value}`);\n const fkRef = fkMap.get(col.name);\n if (fkRef) parts.push(`→ ${fkRef}`);\n\n const constraint = parts.length > 0 ? ` ${parts.join(\", \")}` : \"\";\n console.log(\n ` ${col.name.padEnd(nameWidth)} ${col.type.padEnd(typeWidth)}${constraint}`,\n );\n }\n\n if (table.indexes.length > 0) {\n console.log(` Indexes:`);\n for (const idx of table.indexes) {\n const unique = idx.unique ? \"UNIQUE \" : \"\";\n console.log(` ${unique}${idx.name} (${idx.columns.join(\", \")})`);\n }\n }\n\n console.log();\n }\n } finally {\n await sql.end();\n }\n}\n\n// ---------------------------------------------------------------------------\n// Main entry\n// ---------------------------------------------------------------------------\n\nexport default async function dbSchema(args: string[]): Promise<void> {\n const parsed = parseArgs(args);\n\n if (parsed.help === \"true\") {\n console.log(`Usage: pnpm action db-schema [--db <path>] [--format json]\n\nOptions:\n --db <path> Path to SQLite database (default: data/app.db)\n --format json Output as JSON instead of human-readable text\n --help Show this help message`);\n return;\n }\n\n // Resolve database URL: --db flag → DATABASE_URL env → default file path\n let url: string;\n if (parsed.db) {\n url = \"file:\" + path.resolve(parsed.db);\n } else if (getDatabaseUrl()) {\n url = getDatabaseUrl();\n } else {\n url = \"file:\" + path.resolve(process.cwd(), \"data\", \"app.db\");\n }\n\n // Postgres path\n if (isPostgresUrl(url)) {\n return introspectPostgres(url, parsed);\n }\n\n // SQLite / libsql path\n const client = await createSqliteScriptClient(url);\n\n try {\n const tablesResult = await client.execute(\n `SELECT name FROM sqlite_master WHERE type='table' AND name NOT LIKE 'sqlite_%' ORDER BY name`,\n );\n const tables = tablesResult.rows.map((row) => ({\n name: row[0] as string,\n }));\n\n const tableInfos: TableInfo[] = [];\n\n for (const t of tables) {\n const escaped = t.name.replace(/\"/g, '\"\"');\n\n const columns = await pragma(client, `PRAGMA table_info(\"${escaped}\")`);\n const fks = await pragma(client, `PRAGMA foreign_key_list(\"${escaped}\")`);\n const idxList = await pragma(client, `PRAGMA index_list(\"${escaped}\")`);\n\n const indexes: { name: string; unique: boolean; columns: string[] }[] =\n [];\n for (const idx of idxList) {\n const idxName = idx.name as string;\n if (idxName.startsWith(\"sqlite_\")) continue;\n const idxInfo = await pragma(\n client,\n `PRAGMA index_info(\"${idxName.replace(/\"/g, '\"\"')}\")`,\n );\n indexes.push({\n name: idxName,\n unique: idx.unique === 1,\n columns: idxInfo.map((c) => c.name as string),\n });\n }\n\n tableInfos.push({\n name: t.name,\n columns: columns.map((c) => ({\n name: c.name as string,\n type: (c.type as string) || \"ANY\",\n notnull: c.notnull === 1,\n pk: c.pk === 1,\n dflt_value: c.dflt_value as string | null,\n })),\n foreignKeys: fks.map((fk) => ({\n from: fk.from as string,\n table: fk.table as string,\n to: fk.to as string,\n })),\n indexes,\n });\n }\n\n if (parsed.format === \"json\") {\n const dbLabel = databaseLabel(url);\n console.log(\n JSON.stringify({ database: dbLabel, tables: tableInfos }, null, 2),\n );\n return;\n }\n\n // Human-readable output\n const dbLabel = databaseLabel(url);\n console.log(`Database: ${dbLabel}`);\n console.log(`Tables: ${tableInfos.length}\\n`);\n\n for (const table of tableInfos) {\n console.log(`Table: ${table.name} (${table.columns.length} columns)`);\n\n // Build FK lookup for annotation\n const fkMap = new Map<string, string>();\n for (const fk of table.foreignKeys) {\n fkMap.set(fk.from, `${fk.table}(${fk.to})`);\n }\n\n // Find max widths for alignment\n const nameWidth = Math.max(...table.columns.map((c) => c.name.length));\n const typeWidth = Math.max(...table.columns.map((c) => c.type.length));\n\n for (const col of table.columns) {\n const parts: string[] = [];\n if (col.pk) parts.push(\"PRIMARY KEY\");\n if (col.notnull && !col.pk) parts.push(\"NOT NULL\");\n if (col.dflt_value !== null) parts.push(`DEFAULT ${col.dflt_value}`);\n const fkRef = fkMap.get(col.name);\n if (fkRef) parts.push(`→ ${fkRef}`);\n\n const constraint = parts.length > 0 ? ` ${parts.join(\", \")}` : \"\";\n console.log(\n ` ${col.name.padEnd(nameWidth)} ${col.type.padEnd(typeWidth)}${constraint}`,\n );\n }\n\n if (table.indexes.length > 0) {\n console.log(` Indexes:`);\n for (const idx of table.indexes) {\n const unique = idx.unique ? \"UNIQUE \" : \"\";\n console.log(` ${unique}${idx.name} (${idx.columns.join(\", \")})`);\n }\n }\n\n console.log();\n }\n } finally {\n client.close();\n }\n}\n"]}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
export interface SqliteScriptResult {
|
|
2
|
+
rows: any[];
|
|
3
|
+
columns: string[];
|
|
4
|
+
rowsAffected: number;
|
|
5
|
+
lastInsertRowid?: bigint | number;
|
|
6
|
+
}
|
|
7
|
+
export interface SqliteScriptClient {
|
|
8
|
+
execute(stmtOrSql: string | {
|
|
9
|
+
sql: string;
|
|
10
|
+
args?: any[];
|
|
11
|
+
}): Promise<SqliteScriptResult>;
|
|
12
|
+
close(): void | Promise<void>;
|
|
13
|
+
}
|
|
14
|
+
export declare function createSqliteScriptClient(url: string): Promise<SqliteScriptClient>;
|
|
15
|
+
//# sourceMappingURL=sqlite-client.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sqlite-client.d.ts","sourceRoot":"","sources":["../../../src/scripts/db/sqlite-client.ts"],"names":[],"mappings":"AAOA,MAAM,WAAW,kBAAkB;IACjC,IAAI,EAAE,GAAG,EAAE,CAAC;IACZ,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,YAAY,EAAE,MAAM,CAAC;IACrB,eAAe,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;CACnC;AAED,MAAM,WAAW,kBAAkB;IACjC,OAAO,CACL,SAAS,EAAE,MAAM,GAAG;QAAE,GAAG,EAAE,MAAM,CAAC;QAAC,IAAI,CAAC,EAAE,GAAG,EAAE,CAAA;KAAE,GAChD,OAAO,CAAC,kBAAkB,CAAC,CAAC;IAC/B,KAAK,IAAI,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CAC/B;AAcD,wBAAsB,wBAAwB,CAC5C,GAAG,EAAE,MAAM,GACV,OAAO,CAAC,kBAAkB,CAAC,CA0C7B"}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import { getDatabaseAuthToken, isLocalSqliteUrl, prepareLocalSqliteUrl, sqliteFilenameFromUrl, } from "../../db/client.js";
|
|
2
|
+
function sqliteRowsToLibsqlShape(rows) {
|
|
3
|
+
const records = rows;
|
|
4
|
+
const columns = records.length > 0 ? Object.keys(records[0]) : [];
|
|
5
|
+
return {
|
|
6
|
+
rows: records.map((row) => {
|
|
7
|
+
const values = columns.map((column) => row[column]);
|
|
8
|
+
return Object.assign(values, row);
|
|
9
|
+
}),
|
|
10
|
+
columns,
|
|
11
|
+
};
|
|
12
|
+
}
|
|
13
|
+
export async function createSqliteScriptClient(url) {
|
|
14
|
+
if (isLocalSqliteUrl(url)) {
|
|
15
|
+
const sqliteUrl = await prepareLocalSqliteUrl(url.startsWith("file:") ? url : `file:${url}`);
|
|
16
|
+
const { default: Database } = await import("better-sqlite3");
|
|
17
|
+
const sqlite = new Database(sqliteFilenameFromUrl(sqliteUrl));
|
|
18
|
+
sqlite.pragma("busy_timeout = 10000");
|
|
19
|
+
sqlite.pragma("journal_mode = WAL");
|
|
20
|
+
return {
|
|
21
|
+
async execute(stmtOrSql) {
|
|
22
|
+
const sql = typeof stmtOrSql === "string" ? stmtOrSql : stmtOrSql.sql;
|
|
23
|
+
const args = typeof stmtOrSql === "string" ? [] : (stmtOrSql.args ?? []);
|
|
24
|
+
const stmt = sqlite.prepare(sql);
|
|
25
|
+
if (stmt.reader) {
|
|
26
|
+
return {
|
|
27
|
+
...sqliteRowsToLibsqlShape(stmt.all(...args)),
|
|
28
|
+
rowsAffected: 0,
|
|
29
|
+
};
|
|
30
|
+
}
|
|
31
|
+
const result = stmt.run(...args);
|
|
32
|
+
return {
|
|
33
|
+
rows: [],
|
|
34
|
+
columns: [],
|
|
35
|
+
rowsAffected: result.changes ?? 0,
|
|
36
|
+
lastInsertRowid: result.lastInsertRowid,
|
|
37
|
+
};
|
|
38
|
+
},
|
|
39
|
+
close() {
|
|
40
|
+
sqlite.close();
|
|
41
|
+
},
|
|
42
|
+
};
|
|
43
|
+
}
|
|
44
|
+
const { createClient } = await import("@libsql/client/web");
|
|
45
|
+
const client = createClient({
|
|
46
|
+
url,
|
|
47
|
+
authToken: getDatabaseAuthToken(),
|
|
48
|
+
});
|
|
49
|
+
return client;
|
|
50
|
+
}
|
|
51
|
+
//# sourceMappingURL=sqlite-client.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sqlite-client.js","sourceRoot":"","sources":["../../../src/scripts/db/sqlite-client.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,oBAAoB,EACpB,gBAAgB,EAChB,qBAAqB,EACrB,qBAAqB,GACtB,MAAM,oBAAoB,CAAC;AAgB5B,SAAS,uBAAuB,CAAC,IAAe;IAC9C,MAAM,OAAO,GAAG,IAAiC,CAAC;IAClD,MAAM,OAAO,GAAG,OAAO,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;IAClE,OAAO;QACL,IAAI,EAAE,OAAO,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE;YACxB,MAAM,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,GAAG,CAAC,MAAM,CAAC,CAAU,CAAC;YAC7D,OAAO,MAAM,CAAC,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;QACpC,CAAC,CAAC;QACF,OAAO;KACR,CAAC;AACJ,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,wBAAwB,CAC5C,GAAW;IAEX,IAAI,gBAAgB,CAAC,GAAG,CAAC,EAAE,CAAC;QAC1B,MAAM,SAAS,GAAG,MAAM,qBAAqB,CAC3C,GAAG,CAAC,UAAU,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,QAAQ,GAAG,EAAE,CAC9C,CAAC;QACF,MAAM,EAAE,OAAO,EAAE,QAAQ,EAAE,GAAG,MAAM,MAAM,CAAC,gBAAgB,CAAC,CAAC;QAC7D,MAAM,MAAM,GAAG,IAAI,QAAQ,CAAC,qBAAqB,CAAC,SAAS,CAAC,CAAC,CAAC;QAC9D,MAAM,CAAC,MAAM,CAAC,sBAAsB,CAAC,CAAC;QACtC,MAAM,CAAC,MAAM,CAAC,oBAAoB,CAAC,CAAC;QAEpC,OAAO;YACL,KAAK,CAAC,OAAO,CAAC,SAAS;gBACrB,MAAM,GAAG,GAAG,OAAO,SAAS,KAAK,QAAQ,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC,GAAG,CAAC;gBACtE,MAAM,IAAI,GACR,OAAO,SAAS,KAAK,QAAQ,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,IAAI,IAAI,EAAE,CAAC,CAAC;gBAC9D,MAAM,IAAI,GAAG,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;gBACjC,IAAI,IAAI,CAAC,MAAM,EAAE,CAAC;oBAChB,OAAO;wBACL,GAAG,uBAAuB,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,IAAI,CAAC,CAAC;wBAC7C,YAAY,EAAE,CAAC;qBAChB,CAAC;gBACJ,CAAC;gBACD,MAAM,MAAM,GAAG,IAAI,CAAC,GAAG,CAAC,GAAG,IAAI,CAAC,CAAC;gBACjC,OAAO;oBACL,IAAI,EAAE,EAAE;oBACR,OAAO,EAAE,EAAE;oBACX,YAAY,EAAE,MAAM,CAAC,OAAO,IAAI,CAAC;oBACjC,eAAe,EAAE,MAAM,CAAC,eAAe;iBACxC,CAAC;YACJ,CAAC;YACD,KAAK;gBACH,MAAM,CAAC,KAAK,EAAE,CAAC;YACjB,CAAC;SACF,CAAC;IACJ,CAAC;IAED,MAAM,EAAE,YAAY,EAAE,GAAG,MAAM,MAAM,CAAC,oBAAoB,CAAC,CAAC;IAC5D,MAAM,MAAM,GAAG,YAAY,CAAC;QAC1B,GAAG;QACH,SAAS,EAAE,oBAAoB,EAAE;KAClC,CAAC,CAAC;IACH,OAAO,MAAuC,CAAC;AACjD,CAAC","sourcesContent":["import {\n getDatabaseAuthToken,\n isLocalSqliteUrl,\n prepareLocalSqliteUrl,\n sqliteFilenameFromUrl,\n} from \"../../db/client.js\";\n\nexport interface SqliteScriptResult {\n rows: any[];\n columns: string[];\n rowsAffected: number;\n lastInsertRowid?: bigint | number;\n}\n\nexport interface SqliteScriptClient {\n execute(\n stmtOrSql: string | { sql: string; args?: any[] },\n ): Promise<SqliteScriptResult>;\n close(): void | Promise<void>;\n}\n\nfunction sqliteRowsToLibsqlShape(rows: unknown[]) {\n const records = rows as Record<string, unknown>[];\n const columns = records.length > 0 ? Object.keys(records[0]) : [];\n return {\n rows: records.map((row) => {\n const values = columns.map((column) => row[column]) as any[];\n return Object.assign(values, row);\n }),\n columns,\n };\n}\n\nexport async function createSqliteScriptClient(\n url: string,\n): Promise<SqliteScriptClient> {\n if (isLocalSqliteUrl(url)) {\n const sqliteUrl = await prepareLocalSqliteUrl(\n url.startsWith(\"file:\") ? url : `file:${url}`,\n );\n const { default: Database } = await import(\"better-sqlite3\");\n const sqlite = new Database(sqliteFilenameFromUrl(sqliteUrl));\n sqlite.pragma(\"busy_timeout = 10000\");\n sqlite.pragma(\"journal_mode = WAL\");\n\n return {\n async execute(stmtOrSql) {\n const sql = typeof stmtOrSql === \"string\" ? stmtOrSql : stmtOrSql.sql;\n const args =\n typeof stmtOrSql === \"string\" ? [] : (stmtOrSql.args ?? []);\n const stmt = sqlite.prepare(sql);\n if (stmt.reader) {\n return {\n ...sqliteRowsToLibsqlShape(stmt.all(...args)),\n rowsAffected: 0,\n };\n }\n const result = stmt.run(...args);\n return {\n rows: [],\n columns: [],\n rowsAffected: result.changes ?? 0,\n lastInsertRowid: result.lastInsertRowid,\n };\n },\n close() {\n sqlite.close();\n },\n };\n }\n\n const { createClient } = await import(\"@libsql/client/web\");\n const client = createClient({\n url,\n authToken: getDatabaseAuthToken(),\n });\n return client as unknown as SqliteScriptClient;\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"agent-chat-plugin.d.ts","sourceRoot":"","sources":["../../src/server/agent-chat-plugin.ts"],"names":[],"mappings":"AAaA,OAAO,EAUL,KAAK,WAAW,EACjB,MAAM,8BAA8B,CAAC;AAStC,OAAO,KAAK,
|
|
1
|
+
{"version":3,"file":"agent-chat-plugin.d.ts","sourceRoot":"","sources":["../../src/server/agent-chat-plugin.ts"],"names":[],"mappings":"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"}
|
|
@@ -9,8 +9,8 @@ import { attachToolSearch } from "../agent/tool-search.js";
|
|
|
9
9
|
import { McpClientManager, loadMcpConfig, autoDetectMcpConfig, mcpToolsToActionEntries, syncMcpActionEntries, mountMcpServersRoutes, mountMcpHubRoutes, buildMergedConfig, getHubStatus, isHubServeEnabled, } from "../mcp-client/index.js";
|
|
10
10
|
import { discoverAgents } from "./agent-discovery.js";
|
|
11
11
|
import { loadSchemaPromptBlock } from "./schema-prompt.js";
|
|
12
|
-
import { buildAssistantMessage, extractThreadMeta, mergeThreadDataForClientSave, upsertAssistantMessage, } from "../agent/thread-data-builder.js";
|
|
13
|
-
import { defineEventHandler, setResponseStatus, setResponseHeader, getMethod, getQuery, getHeader, } from "h3";
|
|
12
|
+
import { buildAssistantMessage, buildUserMessage, extractThreadMeta, mergeThreadDataForClientSave, upsertAssistantMessage, upsertUserMessage, } from "../agent/thread-data-builder.js";
|
|
13
|
+
import { createError, defineEventHandler, setResponseStatus, setResponseHeader, getMethod, getQuery, getHeader, } from "h3";
|
|
14
14
|
import { getSession } from "./auth.js";
|
|
15
15
|
import { getOrigin } from "./google-oauth.js";
|
|
16
16
|
import { createThread, forkThread, getThread, listThreads, searchThreads, updateThreadData, withThreadDataLock, deleteThread, setThreadQueuedMessages, } from "../chat-threads/store.js";
|
|
@@ -2659,6 +2659,13 @@ export function createAgentChatPlugin(options) {
|
|
|
2659
2659
|
if (!thread) {
|
|
2660
2660
|
throw new Error(`Agent chat thread ${threadId} was not found while saving run ${run.runId}.`);
|
|
2661
2661
|
}
|
|
2662
|
+
const runOwner = getRequestRunContext()?.owner ?? getRequestUserEmail();
|
|
2663
|
+
if (runOwner && thread.ownerEmail !== runOwner) {
|
|
2664
|
+
throw createError({
|
|
2665
|
+
statusCode: 404,
|
|
2666
|
+
statusMessage: "Thread not found",
|
|
2667
|
+
});
|
|
2668
|
+
}
|
|
2662
2669
|
const assistantMsg = buildAssistantMessage(run.events ?? [], run.runId, { suppressInternalContinuation: true });
|
|
2663
2670
|
if (!assistantMsg) {
|
|
2664
2671
|
// No content produced — just bump timestamp
|
|
@@ -2793,6 +2800,47 @@ export function createAgentChatPlugin(options) {
|
|
|
2793
2800
|
}
|
|
2794
2801
|
})();
|
|
2795
2802
|
};
|
|
2803
|
+
const persistSubmittedUserMessage = async (details) => {
|
|
2804
|
+
const threadId = details.threadId;
|
|
2805
|
+
if (!threadId)
|
|
2806
|
+
return;
|
|
2807
|
+
const ownerEmail = getRequestRunContext()?.owner ?? getRequestUserEmail();
|
|
2808
|
+
if (!ownerEmail)
|
|
2809
|
+
return;
|
|
2810
|
+
await withThreadDataLock(threadId, async () => {
|
|
2811
|
+
let thread = await getThread(threadId);
|
|
2812
|
+
if (!thread) {
|
|
2813
|
+
try {
|
|
2814
|
+
thread = await createThread(ownerEmail, { id: threadId });
|
|
2815
|
+
}
|
|
2816
|
+
catch {
|
|
2817
|
+
thread = await getThread(threadId);
|
|
2818
|
+
}
|
|
2819
|
+
}
|
|
2820
|
+
if (!thread || thread.ownerEmail !== ownerEmail) {
|
|
2821
|
+
throw createError({
|
|
2822
|
+
statusCode: 404,
|
|
2823
|
+
statusMessage: "Thread not found",
|
|
2824
|
+
});
|
|
2825
|
+
}
|
|
2826
|
+
let repo;
|
|
2827
|
+
try {
|
|
2828
|
+
repo = JSON.parse(thread.threadData || "{}");
|
|
2829
|
+
}
|
|
2830
|
+
catch {
|
|
2831
|
+
repo = {};
|
|
2832
|
+
}
|
|
2833
|
+
repo = upsertUserMessage(repo, buildUserMessage({
|
|
2834
|
+
text: details.message,
|
|
2835
|
+
attachments: details.attachments,
|
|
2836
|
+
runId: details.runId,
|
|
2837
|
+
}));
|
|
2838
|
+
const meta = extractThreadMeta(repo);
|
|
2839
|
+
await updateThreadData(threadId, JSON.stringify(repo), meta.title || thread.title, meta.preview || thread.preview, Array.isArray(repo.messages)
|
|
2840
|
+
? repo.messages.length
|
|
2841
|
+
: thread.messageCount);
|
|
2842
|
+
});
|
|
2843
|
+
};
|
|
2796
2844
|
// ─── Agent Teams: per-run send reference ─────────────────────────
|
|
2797
2845
|
// Team tools need to emit events to the parent chat's SSE stream.
|
|
2798
2846
|
// Each run gets its own send function, keyed by threadId so concurrent
|
|
@@ -2965,6 +3013,7 @@ export function createAgentChatPlugin(options) {
|
|
|
2965
3013
|
runCtx.model = model;
|
|
2966
3014
|
}
|
|
2967
3015
|
},
|
|
3016
|
+
onRunPrepared: persistSubmittedUserMessage,
|
|
2968
3017
|
onRunStart: async (send, threadId) => {
|
|
2969
3018
|
await recordPreRunGitStatus(threadId);
|
|
2970
3019
|
_runSendByThread.set(threadId, send);
|
|
@@ -3001,6 +3050,7 @@ export function createAgentChatPlugin(options) {
|
|
|
3001
3050
|
runCtx.model = model;
|
|
3002
3051
|
}
|
|
3003
3052
|
},
|
|
3053
|
+
onRunPrepared: persistSubmittedUserMessage,
|
|
3004
3054
|
onRunStart: async (send, threadId) => {
|
|
3005
3055
|
await recordPreRunGitStatus(threadId);
|
|
3006
3056
|
_runSendByThread.set(threadId, send);
|
|
@@ -3085,6 +3135,7 @@ export function createAgentChatPlugin(options) {
|
|
|
3085
3135
|
runCtx.model = model;
|
|
3086
3136
|
}
|
|
3087
3137
|
},
|
|
3138
|
+
onRunPrepared: persistSubmittedUserMessage,
|
|
3088
3139
|
onRunStart: async (send, threadId) => {
|
|
3089
3140
|
await recordPreRunGitStatus(threadId);
|
|
3090
3141
|
_runSendByThread.set(threadId, send);
|