@deepagents/text2sql 6.0.0 → 6.1.0
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 +7 -1
- package/dist/bin/sql.js +1 -0
- package/dist/index.js +2 -0
- package/dist/index.js.map +2 -2
- package/dist/lib/adapters/adapter.d.ts +1 -1
- package/dist/lib/adapters/adapter.d.ts.map +1 -1
- package/dist/lib/adapters/bigquery/index.js +2 -0
- package/dist/lib/adapters/bigquery/index.js.map +2 -2
- package/dist/lib/adapters/clickhouse/index.js +2 -0
- package/dist/lib/adapters/clickhouse/index.js.map +2 -2
- package/dist/lib/adapters/groundings/context.d.ts +3 -0
- package/dist/lib/adapters/groundings/context.d.ts.map +1 -1
- package/dist/lib/adapters/groundings/index.js +1 -0
- package/dist/lib/adapters/groundings/index.js.map +2 -2
- package/dist/lib/adapters/mysql/index.js +2 -0
- package/dist/lib/adapters/mysql/index.js.map +2 -2
- package/dist/lib/adapters/postgres/index.js +2 -0
- package/dist/lib/adapters/postgres/index.js.map +2 -2
- package/dist/lib/adapters/posthog/definitions.posthog.grounding.d.ts +19 -0
- package/dist/lib/adapters/posthog/definitions.posthog.grounding.d.ts.map +1 -0
- package/dist/lib/adapters/posthog/index.d.ts +22 -0
- package/dist/lib/adapters/posthog/index.d.ts.map +1 -0
- package/dist/lib/adapters/posthog/index.js +1303 -0
- package/dist/lib/adapters/posthog/index.js.map +7 -0
- package/dist/lib/adapters/posthog/info.posthog.grounding.d.ts +7 -0
- package/dist/lib/adapters/posthog/info.posthog.grounding.d.ts.map +1 -0
- package/dist/lib/adapters/posthog/posthog.d.ts +23 -0
- package/dist/lib/adapters/posthog/posthog.d.ts.map +1 -0
- package/dist/lib/adapters/posthog/posthog.sql-policy.d.ts +8 -0
- package/dist/lib/adapters/posthog/posthog.sql-policy.d.ts.map +1 -0
- package/dist/lib/adapters/posthog/schema.posthog.grounding.d.ts +16 -0
- package/dist/lib/adapters/posthog/schema.posthog.grounding.d.ts.map +1 -0
- package/dist/lib/adapters/posthog/transport.d.ts +16 -0
- package/dist/lib/adapters/posthog/transport.d.ts.map +1 -0
- package/dist/lib/adapters/posthog/types.d.ts +95 -0
- package/dist/lib/adapters/posthog/types.d.ts.map +1 -0
- package/dist/lib/adapters/spreadsheet/index.js +2 -0
- package/dist/lib/adapters/spreadsheet/index.js.map +2 -2
- package/dist/lib/adapters/sqlite/index.js +2 -0
- package/dist/lib/adapters/sqlite/index.js.map +2 -2
- package/dist/lib/adapters/sqlserver/index.js +2 -0
- package/dist/lib/adapters/sqlserver/index.js.map +2 -2
- package/package.json +11 -5
package/dist/index.js.map
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../src/lib/adapter-name.ts", "../src/lib/adapters/adapter.ts", "../src/lib/agents/exceptions.ts", "../src/lib/fragments/schema.ts", "../src/lib/adapters/groundings/context.ts", "../src/lib/agents/sql.agent.ts", "../src/lib/sql-scope-error.ts", "../src/lib/agents/suggestions.agents.ts", "../src/lib/adapter-index.ts", "../src/lib/file-cache.ts", "../src/lib/index-cache.ts", "../src/lib/index-lock.ts", "../src/lib/checkpoint.ts", "../src/lib/fs/sqlite/sqlite-fs.ts", "../src/lib/fs/sqlite/ddl.sqlite-fs.sql", "../src/lib/fs/mssql/mssql-fs.ts", "../src/lib/fs/mssql/ddl.mssql-fs.ts", "../src/lib/fs/postgres/postgres-fs.ts", "../src/lib/fs/postgres/ddl.postgres-fs.ts", "../src/lib/fs/scoped-fs.ts", "../src/lib/instructions.ts", "../src/lib/sql-invocation.ts", "../src/lib/sql-meta-hook.ts", "../src/lib/sql-repair.ts", "../src/lib/sql-transform.ts", "../src/lib/agents/sql-transform-plugins.ts", "../src/lib/sql-hooks.ts", "../src/lib/sql-command.ts", "../src/lib/sql.ts", "../src/lib/sql-validate-reminder.ts"],
|
|
4
|
-
"sourcesContent": ["export const ADAPTER_NAME_PATTERN = /^[A-Za-z_][A-Za-z0-9_]*$/;\n\n/**\n * Tag name used to label each adapter's configured connection name inside its\n * indexed schema fragment (see `databaseNameFragment` in adapter-index.ts).\n * Reserved as an adapter name: an adapter literally named `database` would make\n * the label tag indistinguishable from the wrapper tag and render nested\n * `<database><database>\u2026</database></database>`.\n */\nexport const DATABASE_NAME_FRAGMENT = 'database';\n\nconst RESERVED_ADAPTER_NAMES = new Set<string>([DATABASE_NAME_FRAGMENT]);\n\nexport function isValidAdapterName(\n name: string | null | undefined,\n): name is string {\n return name != null && ADAPTER_NAME_PATTERN.test(name);\n}\n\nexport function validateAdapterNames(names: Iterable<string>): void {\n for (const name of names) {\n if (!isValidAdapterName(name)) {\n throw new Error(\n `Invalid adapter name \"${name}\": must match ${ADAPTER_NAME_PATTERN}`,\n );\n }\n if (RESERVED_ADAPTER_NAMES.has(name)) {\n throw new Error(`Adapter name \"${name}\" is reserved`);\n }\n }\n}\n", "import { type SqlLanguage, format as formatSql } from 'sql-formatter';\n\nimport type { ContextFragment, FragmentObject } from '@deepagents/context';\n\nimport { SQLReadOnlyError, SQLScopeError } from '../agents/exceptions.ts';\nimport {\n column,\n constraint,\n dialectInfo,\n index,\n relationship,\n table,\n view,\n} from '../fragments/schema.ts';\nimport type { AbstractGrounding } from './groundings/abstract.grounding.ts';\nimport {\n type GroundingContext,\n createGroundingContext,\n} from './groundings/context.ts';\nimport type { View } from './groundings/view.grounding.ts';\nimport {\n type SqlPolicyAnalyzer,\n type SqlPolicyViolation,\n} from './sql-policy.ts';\n\nexport {\n type SqlPolicyAnalyzer,\n type SqlPolicyContext,\n type SqlPolicyViolation,\n} from './sql-policy.ts';\n\n/**\n * Filter type for view/table names.\n * - string[]: explicit list of view names\n * - RegExp: pattern to match view names\n * - function: predicate to filter view names\n */\nexport type Filter = string[] | RegExp | ((viewName: string) => boolean);\n\nexport interface Table {\n name: string;\n schema?: string;\n rawName?: string;\n columns: {\n name: string;\n type: string;\n kind?: 'LowCardinality' | 'Enum';\n values?: string[];\n isIndexed?: boolean;\n stats?: ColumnStats;\n }[];\n rowCount?: number;\n sizeHint?: 'tiny' | 'small' | 'medium' | 'large' | 'huge';\n indexes?: TableIndex[];\n constraints?: TableConstraint[];\n}\n\nexport interface TableIndex {\n name: string;\n columns: string[];\n unique?: boolean;\n type?: string;\n}\n\nexport interface TableConstraint {\n name: string;\n type:\n 'CHECK' | 'UNIQUE' | 'NOT_NULL' | 'DEFAULT' | 'PRIMARY_KEY' | 'FOREIGN_KEY';\n columns?: string[];\n definition?: string;\n defaultValue?: string;\n referencedTable?: string;\n referencedColumns?: string[];\n}\n\nexport interface ColumnStats {\n min?: string;\n max?: string;\n nullFraction?: number;\n nDistinct?: number;\n correlation?: number;\n}\n\nexport type Relationship = {\n table: string;\n from: string[];\n referenced_table: string;\n to: string[];\n};\n\nexport type TablesFilter = string[] | RegExp;\n\nexport interface Introspection {\n tables: Table[];\n relationships: Relationship[];\n}\n\nexport interface AdapterInfo {\n dialect: string;\n version?: string;\n database?: string;\n details?: FragmentObject;\n}\n\nexport type AdapterInfoProvider =\n AdapterInfo | (() => Promise<AdapterInfo> | AdapterInfo);\n\nexport type IntrospectionPhase =\n | 'info'\n | 'tables'\n | 'views'\n | 'row_counts'\n | 'constraints'\n | 'indexes'\n | 'column_stats'\n | 'column_values'\n | 'low_cardinality'\n | 'relationships';\n\nexport type IntrospectionProgressType =\n 'phase:start' | 'phase:progress' | 'phase:end';\n\nexport interface IntrospectionProgress {\n type: IntrospectionProgressType;\n phase: IntrospectionPhase;\n message: string;\n table?: string;\n current?: number;\n total?: number;\n timestampMs?: number;\n}\n\nexport type OnProgress = (progress: IntrospectionProgress) => void;\n\nexport type GroundingFn = (adapter: Adapter) => AbstractGrounding;\n\nexport type ExecuteFunction = (sql: string) => Promise<any> | any;\nexport type ValidateFunction = (\n sql: string,\n) => Promise<string | void> | string | void;\n\nexport abstract class Adapter {\n readonly #policyAnalyzer: SqlPolicyAnalyzer;\n\n /**\n * Injects the strategy that guards validate() and execute().\n */\n protected constructor(policyAnalyzer: SqlPolicyAnalyzer) {\n this.#policyAnalyzer = policyAnalyzer;\n }\n\n abstract grounding: GroundingFn[];\n\n abstract readonly formatterLanguage: SqlLanguage;\n\n /**\n * Default schema name for this database.\n * PostgreSQL: 'public', SQL Server: 'dbo', SQLite: undefined\n */\n abstract readonly defaultSchema: string | undefined;\n\n /**\n * System schemas to exclude from introspection by default.\n */\n abstract readonly systemSchemas: string[];\n\n /**\n * Introspect the database schema and return context fragments.\n *\n * Executes all configured groundings to populate the context, then\n * generates fragments from the complete context data.\n *\n * @param ctx - Optional grounding context for sharing state between groundings\n * @returns Array of context fragments representing the database schema\n */\n async introspect(ctx = createGroundingContext()): Promise<ContextFragment[]> {\n // Phase 1: All groundings populate ctx\n for (const fn of this.grounding) {\n const grounding = fn(this);\n if (grounding.phase) {\n ctx.onProgress({\n type: 'phase:start',\n phase: grounding.phase,\n message: `Starting ${grounding.name} introspection...`,\n });\n }\n try {\n await grounding.execute(ctx);\n } finally {\n if (grounding.phase) {\n ctx.onProgress({\n type: 'phase:end',\n phase: grounding.phase,\n message: `Finished ${grounding.name} introspection.`,\n });\n }\n }\n }\n\n // Phase 2: Generate fragments from complete ctx\n return this.#toSchemaFragments(ctx);\n }\n\n /**\n * Resolve the allowed entity names (tables + views) from grounding config.\n * Asks each grounding to contribute its entities; annotators contribute\n * nothing, so their metadata scans are skipped.\n * Results are NOT cached \u2014 call once and store the result.\n */\n async resolveAllowedEntities(): Promise<string[]> {\n const ctx = createGroundingContext();\n for (const fn of this.grounding) {\n await fn(this).contributeEntities(ctx);\n }\n return [...ctx.tables.map((t) => t.name), ...ctx.views.map((v) => v.name)];\n }\n\n /**\n * Convert complete grounding context to schema fragments.\n * Called after all groundings have populated ctx with data.\n */\n #toSchemaFragments(ctx: GroundingContext): ContextFragment[] {\n const fragments: ContextFragment[] = [];\n\n // Dialect info\n if (ctx.info) {\n fragments.push(\n dialectInfo({\n dialect: ctx.info.dialect,\n version: ctx.info.version,\n database: ctx.info.database,\n details: ctx.info.details,\n }),\n );\n }\n\n // Tables (with all annotations now included)\n for (const t of ctx.tables) {\n fragments.push(this.#tableToFragment(t));\n }\n\n // Views\n for (const v of ctx.views) {\n fragments.push(this.#viewToFragment(v));\n }\n\n // Relationships \u2014 filter out FK columns that were removed by column restriction\n const tableMap = new Map(ctx.tables.map((t) => [t.name, t]));\n const tableColumnSets = new Map(\n ctx.tables.map((t) => [t.name, new Set(t.columns.map((c) => c.name))]),\n );\n for (const rel of ctx.relationships) {\n const sourceColumns = tableColumnSets.get(rel.table);\n const targetColumns = tableColumnSets.get(rel.referenced_table);\n if (\n sourceColumns &&\n rel.from.some((column) => !sourceColumns.has(column))\n ) {\n continue;\n }\n if (\n targetColumns &&\n rel.to.some((column) => !targetColumns.has(column))\n ) {\n continue;\n }\n\n const sourceTable = tableMap.get(rel.table);\n const targetTable = tableMap.get(rel.referenced_table);\n fragments.push(\n this.#relationshipToFragment(rel, sourceTable, targetTable),\n );\n }\n\n return fragments;\n }\n\n /**\n * Convert a Table to a table fragment with nested column, index, and constraint fragments.\n */\n #tableToFragment(t: Table): ContextFragment {\n // Build constraint lookup maps for column-level annotations\n const pkConstraint = t.constraints?.find((c) => c.type === 'PRIMARY_KEY');\n const pkColumns = new Set(pkConstraint?.columns ?? []);\n\n const notNullColumns = new Set(\n t.constraints\n ?.filter((c) => c.type === 'NOT_NULL')\n .flatMap((c) => c.columns ?? []) ?? [],\n );\n\n const defaultByColumn = new Map<string, string>();\n for (const c of t.constraints?.filter((c) => c.type === 'DEFAULT') ?? []) {\n for (const col of c.columns ?? []) {\n if (c.defaultValue != null) {\n defaultByColumn.set(col, c.defaultValue);\n }\n }\n }\n\n // Single-column UNIQUE constraints\n const uniqueColumns = new Set(\n t.constraints\n ?.filter((c) => c.type === 'UNIQUE' && c.columns?.length === 1)\n .flatMap((c) => c.columns ?? []) ?? [],\n );\n\n // Foreign key lookup: column -> referenced table.column\n const fkByColumn = new Map<string, string>();\n for (const c of t.constraints?.filter((c) => c.type === 'FOREIGN_KEY') ??\n []) {\n const cols = c.columns ?? [];\n const refCols = c.referencedColumns ?? [];\n for (let i = 0; i < cols.length; i++) {\n const refCol = refCols[i] ?? refCols[0] ?? cols[i];\n fkByColumn.set(cols[i], `${c.referencedTable}.${refCol}`);\n }\n }\n\n // Build column fragments\n const columnFragments = t.columns.map((col) =>\n column({\n name: col.name,\n type: col.type,\n pk: pkColumns.has(col.name) || undefined,\n fk: fkByColumn.get(col.name),\n unique: uniqueColumns.has(col.name) || undefined,\n notNull: notNullColumns.has(col.name) || undefined,\n default: defaultByColumn.get(col.name),\n indexed: col.isIndexed || undefined,\n values: col.values,\n stats: col.stats,\n }),\n );\n\n // Set of present column names for cascade-cleaning indexes/constraints\n const presentColumns = new Set(t.columns.map((c) => c.name));\n\n // Build index fragments\n const indexFragments = (t.indexes ?? [])\n .filter((idx) =>\n idx.columns.every((column) => presentColumns.has(column)),\n )\n .map((idx) =>\n index({\n name: idx.name,\n columns: idx.columns,\n unique: idx.unique,\n type: idx.type,\n }),\n );\n\n // Build constraint fragments for multi-column UNIQUE and CHECK constraints\n const constraintFragments = (t.constraints ?? [])\n .filter(\n (c) =>\n c.type === 'CHECK' ||\n (c.type === 'UNIQUE' && (c.columns?.length ?? 0) > 1),\n )\n .filter(\n (c) =>\n !c.columns?.length ||\n c.columns.every((column) => presentColumns.has(column)),\n )\n .map((c) =>\n constraint({\n name: c.name,\n type: c.type,\n columns: c.columns,\n definition: c.definition,\n }),\n );\n\n return table({\n name: t.name,\n schema: t.schema,\n rowCount: t.rowCount,\n sizeHint: t.sizeHint,\n columns: columnFragments,\n indexes: indexFragments.length > 0 ? indexFragments : undefined,\n constraints:\n constraintFragments.length > 0 ? constraintFragments : undefined,\n });\n }\n\n /**\n * Convert a View to a view fragment with nested column fragments.\n */\n #viewToFragment(v: View): ContextFragment {\n const columnFragments = v.columns.map((col) =>\n column({\n name: col.name,\n type: col.type,\n values: col.values,\n stats: col.stats,\n }),\n );\n\n return view({\n name: v.name,\n schema: v.schema,\n columns: columnFragments,\n definition: v.definition,\n });\n }\n\n /**\n * Convert a Relationship to a relationship fragment.\n * Infers cardinality from row counts if available.\n */\n #relationshipToFragment(\n rel: Relationship,\n sourceTable?: Table,\n targetTable?: Table,\n ): ContextFragment {\n const sourceCount = sourceTable?.rowCount;\n const targetCount = targetTable?.rowCount;\n\n let cardinality:\n 'one-to-one' | 'one-to-many' | 'many-to-one' | 'many-to-many' | undefined;\n\n if (sourceCount != null && targetCount != null && targetCount > 0) {\n const ratio = sourceCount / targetCount;\n if (ratio > 5) {\n cardinality = 'many-to-one';\n } else if (ratio < 1.2 && ratio > 0.8) {\n cardinality = 'one-to-one';\n } else if (ratio < 0.2) {\n cardinality = 'one-to-many';\n }\n }\n\n return relationship({\n from: { table: rel.table, columns: rel.from },\n to: { table: rel.referenced_table, columns: rel.to },\n cardinality,\n });\n }\n format(sql: string): string {\n const decoded = this.#decodeShellEscapes(sql);\n try {\n return formatSql(decoded, { language: this.formatterLanguage });\n } catch {\n return decoded;\n }\n }\n\n #decodeShellEscapes(sql: string): string {\n return sql\n .replace(/\\\\n/g, '\\n')\n .replace(/\\\\t/g, '\\t')\n .replace(/\\\\([().*])/g, '$1')\n .replace(/\\\\(?=$)/gm, '');\n }\n\n #cachedAllowedEntities: string[] | null = null;\n\n async #resolveScope(): Promise<string[]> {\n if (this.#cachedAllowedEntities) return this.#cachedAllowedEntities;\n this.#cachedAllowedEntities = await this.resolveAllowedEntities();\n return this.#cachedAllowedEntities;\n }\n\n async #analyzePolicy(sql: string): Promise<SqlPolicyViolation | null> {\n return this.#policyAnalyzer.analyze(sql, {\n resolveAllowedEntities: () => this.#resolveScope(),\n });\n }\n\n async validate(sql: string): Promise<string | void> {\n const decoded = this.#decodeShellEscapes(sql);\n const violation = await this.#analyzePolicy(decoded);\n if (violation?.kind === 'read-only') return violation.message;\n if (violation?.kind === 'scope') return JSON.stringify(violation.payload);\n return this.validateImpl(decoded);\n }\n\n async execute(sql: string): Promise<any[]> {\n const decoded = this.#decodeShellEscapes(sql);\n const violation = await this.#analyzePolicy(decoded);\n if (violation?.kind === 'read-only') {\n throw new SQLReadOnlyError(violation.message);\n }\n if (violation?.kind === 'scope') {\n throw new SQLScopeError(violation.payload);\n }\n return this.executeImpl(decoded);\n }\n\n abstract executeImpl(sql: string): Promise<any[]> | any[];\n abstract validateImpl(sql: string): Promise<string | void> | string | void;\n abstract runQuery<Row>(sql: string): Promise<Row[]> | Row[];\n\n /**\n * Quote an identifier (table/column name) for safe use in SQL.\n * Each database uses different quoting styles.\n */\n abstract quoteIdentifier(name: string): string;\n\n /**\n * Escape a string value for safe use in SQL.\n * Each database escapes different characters.\n */\n abstract escape(value: string): string;\n\n /**\n * Build a SELECT query to sample rows from a table.\n * Each database uses different syntax for limiting rows (LIMIT vs TOP).\n */\n abstract buildSampleRowsQuery(\n tableName: string,\n columns: string[] | undefined,\n limit: number,\n ): string;\n\n /**\n * Convert unknown database value to number.\n * Handles number, bigint, and string types.\n */\n toNumber(value: unknown): number | undefined {\n if (typeof value === 'number' && Number.isFinite(value)) {\n return value;\n }\n if (typeof value === 'bigint') {\n return Number(value);\n }\n if (typeof value === 'string' && value.trim() !== '') {\n const parsed = Number(value);\n return Number.isFinite(parsed) ? parsed : undefined;\n }\n return undefined;\n }\n\n /**\n * Parse a potentially qualified table name into schema and table parts.\n */\n parseTableName(name: string): { schema: string; table: string } {\n if (name.includes('.')) {\n const [schema, ...rest] = name.split('.');\n return { schema, table: rest.join('.') };\n }\n return { schema: this.defaultSchema ?? '', table: name };\n }\n\n /**\n * Escape a string value for use in SQL string literals (single quotes).\n * Used in WHERE clauses like: WHERE name = '${escapeString(value)}'\n */\n escapeString(value: string): string {\n return value.replace(/'/g, \"''\");\n }\n\n /**\n * Build a SQL filter clause to include/exclude schemas.\n * @param columnName - The schema column name (e.g., 'TABLE_SCHEMA')\n * @param allowedSchemas - If provided, filter to these schemas only\n */\n buildSchemaFilter(columnName: string, allowedSchemas?: string[]): string {\n if (allowedSchemas && allowedSchemas.length > 0) {\n const values = allowedSchemas\n .map((s) => `'${this.escapeString(s)}'`)\n .join(', ');\n return `AND ${columnName} IN (${values})`;\n }\n if (this.systemSchemas.length > 0) {\n const values = this.systemSchemas\n .map((s) => `'${this.escapeString(s)}'`)\n .join(', ');\n return `AND ${columnName} NOT IN (${values})`;\n }\n return '';\n }\n}\n\nexport function filterTablesByName<T extends { name: string }>(\n tables: T[],\n filter: TablesFilter | undefined,\n): T[] {\n if (!filter) return tables;\n return tables.filter((table) => matchesFilter(table.name, filter));\n}\n\nexport function filterRelationshipsByTables(\n relationships: Relationship[],\n tableNames: Set<string> | undefined,\n): Relationship[] {\n if (tableNames === undefined) {\n return relationships;\n }\n if (tableNames.size === 0) {\n return [];\n }\n return relationships.filter(\n (it) => tableNames.has(it.table) || tableNames.has(it.referenced_table),\n );\n}\n\nexport function applyTablesFilter(\n tables: Table[],\n relationships: Relationship[],\n filter: TablesFilter | undefined,\n): { tables: Table[]; relationships: Relationship[] } {\n if (!filter) {\n return { tables, relationships };\n }\n\n const allowedNames = new Set(\n getTablesWithRelated(tables, relationships, filter),\n );\n\n return {\n tables: tables.filter((table) => allowedNames.has(table.name)),\n relationships: filterRelationshipsByTables(relationships, allowedNames),\n };\n}\n\nexport function matchesFilter(\n tableName: string,\n filter: TablesFilter,\n): boolean {\n if (Array.isArray(filter)) {\n return filter.includes(tableName);\n }\n return filter.test(tableName);\n}\n\nexport function getTablesWithRelated(\n allTables: Table[],\n relationships: Relationship[],\n filter: TablesFilter,\n): string[] {\n const matchedTables = filterTablesByName(allTables, filter).map(\n (it) => it.name,\n );\n\n if (matchedTables.length === 0) {\n return [];\n }\n\n const adjacency = new Map<string, Set<string>>();\n\n for (const rel of relationships) {\n if (!adjacency.has(rel.table)) {\n adjacency.set(rel.table, new Set());\n }\n if (!adjacency.has(rel.referenced_table)) {\n adjacency.set(rel.referenced_table, new Set());\n }\n adjacency.get(rel.table)!.add(rel.referenced_table);\n adjacency.get(rel.referenced_table)!.add(rel.table);\n }\n\n const result = new Set<string>(matchedTables);\n const queue = [...matchedTables];\n\n while (queue.length > 0) {\n const current = queue.shift()!;\n const neighbors = adjacency.get(current);\n\n if (!neighbors) {\n continue;\n }\n\n for (const neighbor of neighbors) {\n if (!result.has(neighbor)) {\n result.add(neighbor);\n queue.push(neighbor);\n }\n }\n }\n\n return Array.from(result);\n}\n", "const sqlValidationMarker = Symbol('SQLValidationError');\nconst unanswerableSqlMarker = Symbol('UnanswerableSQLError');\nconst sqlScopeMarker = Symbol('SQLScopeError');\nconst sqlReadOnlyMarker = Symbol('SQLReadOnlyError');\n\nexport type SQLScopeErrorType = 'OUT_OF_SCOPE' | 'SQL_SCOPE_PARSE_ERROR';\n\nexport interface SQLScopeErrorPayload {\n error: string;\n error_type: SQLScopeErrorType;\n suggestion: string;\n sql_attempted: string;\n referenced_entities?: string[];\n allowed_entities?: string[];\n parser_dialect?: string;\n parser_error?: string;\n}\n\n/**\n * Error thrown when SQL validation fails.\n */\nexport class SQLValidationError extends Error {\n [sqlValidationMarker]: true;\n\n constructor(message: string) {\n super(message);\n this.name = 'SQLValidationError';\n this[sqlValidationMarker] = true;\n }\n\n static isInstance(error: unknown): error is SQLValidationError {\n return (\n error instanceof SQLValidationError && error[sqlValidationMarker] === true\n );\n }\n}\n\n/**\n * Error thrown when the question cannot be answered with the given schema.\n */\nexport class UnanswerableSQLError extends Error {\n [unanswerableSqlMarker]: true;\n\n constructor(message: string) {\n super(message);\n this.name = 'UnanswerableSQLError';\n this[unanswerableSqlMarker] = true;\n }\n\n static isInstance(error: unknown): error is UnanswerableSQLError {\n return (\n error instanceof UnanswerableSQLError &&\n error[unanswerableSqlMarker] === true\n );\n }\n}\n\n/**\n * Error thrown when a query falls outside the grounded SQL scope.\n */\nexport class SQLScopeError extends Error {\n [sqlScopeMarker]: true;\n readonly payload: SQLScopeErrorPayload;\n readonly errorType: SQLScopeErrorType;\n\n constructor(payload: SQLScopeErrorPayload) {\n super(JSON.stringify(payload));\n this.name = 'SQLScopeError';\n this.payload = payload;\n this.errorType = payload.error_type;\n this[sqlScopeMarker] = true;\n }\n\n static isInstance(error: unknown): error is SQLScopeError {\n return error instanceof SQLScopeError && error[sqlScopeMarker] === true;\n }\n}\n\n/**\n * Error thrown when a query is not read-only (does not start with SELECT or WITH).\n */\nexport class SQLReadOnlyError extends Error {\n [sqlReadOnlyMarker]: true;\n\n constructor(message: string) {\n super(message);\n this.name = 'SQLReadOnlyError';\n this[sqlReadOnlyMarker] = true;\n }\n\n static isInstance(error: unknown): error is SQLReadOnlyError {\n return (\n error instanceof SQLReadOnlyError && error[sqlReadOnlyMarker] === true\n );\n }\n}\n", "import type { ContextFragment, FragmentObject } from '@deepagents/context';\n\n/**\n * Schema fragment builders.\n *\n * These fragments represent database schema metadata that can be injected\n * into AI prompts. Use with renderers (XML, Markdown, TOML, TOON) to format.\n *\n * @example\n * ```ts\n * import { dialectInfo, table, column, relationship } from '@deepagents/text2sql';\n *\n * const schemaFragments = [\n * dialectInfo({ dialect: 'PostgreSQL', version: '14.5' }),\n * table({\n * name: 'users',\n * columns: [\n * column({ name: 'id', type: 'integer', pk: true }),\n * column({ name: 'email', type: 'varchar', unique: true }),\n * ],\n * }),\n * ];\n * ```\n */\n\n/**\n * Database dialect and version information.\n *\n * @param input.dialect - Database type (PostgreSQL, SQLite, SQL Server, etc.)\n * @param input.version - Database version string\n * @param input.database - Database name\n *\n * @example\n * dialectInfo({ dialect: 'PostgreSQL', version: '14.5', database: 'myapp' })\n */\nexport function dialectInfo(input: {\n dialect: string;\n version?: string;\n database?: string;\n details?: FragmentObject;\n}): ContextFragment {\n return {\n name: 'dialectInfo',\n data: {\n dialect: input.dialect,\n ...(input.version && { version: input.version }),\n ...(input.database && { database: input.database }),\n ...(input.details && { details: input.details }),\n },\n };\n}\n\n/**\n * Database table with columns and optional metadata.\n *\n * @param input.name - Table name\n * @param input.schema - Schema name (e.g., 'public' for PostgreSQL)\n * @param input.rowCount - Approximate row count\n * @param input.sizeHint - Size category for query optimization hints\n * @param input.columns - Array of column() fragments\n * @param input.indexes - Array of index() fragments\n * @param input.constraints - Array of constraint() fragments\n *\n * @example\n * table({\n * name: 'users',\n * rowCount: 1500,\n * sizeHint: 'medium',\n * columns: [\n * column({ name: 'id', type: 'integer', pk: true }),\n * column({ name: 'email', type: 'varchar', unique: true, indexed: true }),\n * ],\n * indexes: [\n * index({ name: 'idx_email', columns: ['email'], unique: true }),\n * ],\n * })\n */\nexport function table(input: {\n name: string;\n schema?: string;\n rowCount?: number;\n sizeHint?: 'tiny' | 'small' | 'medium' | 'large' | 'huge';\n columns: ContextFragment[];\n indexes?: ContextFragment[];\n constraints?: ContextFragment[];\n}): ContextFragment {\n return {\n name: 'table',\n data: {\n name: input.name,\n ...(input.schema && { schema: input.schema }),\n ...(input.rowCount != null && { rowCount: input.rowCount }),\n ...(input.sizeHint && { sizeHint: input.sizeHint }),\n columns: input.columns,\n ...(input.indexes?.length && { indexes: input.indexes }),\n ...(input.constraints?.length && { constraints: input.constraints }),\n },\n };\n}\n\n/**\n * Table column with type and annotations.\n *\n * @param input.name - Column name\n * @param input.type - Column data type (e.g., 'integer', 'varchar(255)')\n * @param input.pk - Is primary key\n * @param input.fk - Foreign key reference in \"table.column\" format\n * @param input.unique - Has unique constraint\n * @param input.notNull - Has NOT NULL constraint\n * @param input.default - Default value expression\n * @param input.indexed - Has index on this column\n * @param input.values - Enum or low cardinality values\n * @param input.stats - Column statistics (min, max, null fraction)\n *\n * @example\n * column({\n * name: 'status',\n * type: 'varchar',\n * notNull: true,\n * indexed: true,\n * values: ['active', 'inactive', 'suspended'],\n * })\n */\nexport function column(input: {\n name: string;\n type: string;\n pk?: boolean;\n fk?: string;\n unique?: boolean;\n notNull?: boolean;\n default?: string;\n indexed?: boolean;\n values?: string[];\n stats?: {\n min?: string;\n max?: string;\n nullFraction?: number;\n nDistinct?: number;\n correlation?: number;\n };\n}): ContextFragment {\n return {\n name: 'column',\n data: {\n name: input.name,\n type: input.type,\n ...(input.pk && { pk: true }),\n ...(input.fk && { fk: input.fk }),\n ...(input.unique && { unique: true }),\n ...(input.notNull && { notNull: true }),\n ...(input.default && { default: input.default }),\n ...(input.indexed && { indexed: true }),\n ...(input.values?.length && { values: input.values }),\n ...(input.stats && { stats: input.stats }),\n },\n };\n}\n\n/**\n * Table index.\n *\n * @param input.name - Index name\n * @param input.columns - Columns included in the index\n * @param input.unique - Is unique index\n * @param input.type - Index type (BTREE, HASH, GIN, etc.)\n *\n * @example\n * index({ name: 'idx_user_email', columns: ['email'], unique: true, type: 'BTREE' })\n */\nexport function index(input: {\n name: string;\n columns: string[];\n unique?: boolean;\n type?: string;\n}): ContextFragment {\n return {\n name: 'index',\n data: {\n name: input.name,\n columns: input.columns,\n ...(input.unique && { unique: true }),\n ...(input.type && { type: input.type }),\n },\n };\n}\n\n/**\n * Table constraint (CHECK, UNIQUE, PRIMARY_KEY, FOREIGN_KEY, etc).\n *\n * @param input.name - Constraint name\n * @param input.type - Constraint type\n * @param input.columns - Columns involved in the constraint\n * @param input.definition - CHECK constraint SQL definition\n * @param input.defaultValue - DEFAULT constraint value\n * @param input.referencedTable - For FK: referenced table name\n * @param input.referencedColumns - For FK: referenced column names\n *\n * @example\n * constraint({\n * name: 'chk_amount_positive',\n * type: 'CHECK',\n * definition: 'amount > 0',\n * })\n *\n * @example\n * constraint({\n * name: 'fk_order_user',\n * type: 'FOREIGN_KEY',\n * columns: ['user_id'],\n * referencedTable: 'users',\n * referencedColumns: ['id'],\n * })\n */\nexport function constraint(input: {\n name: string;\n type:\n | 'CHECK'\n | 'UNIQUE'\n | 'NOT_NULL'\n | 'DEFAULT'\n | 'PRIMARY_KEY'\n | 'FOREIGN_KEY';\n columns?: string[];\n definition?: string;\n defaultValue?: string;\n referencedTable?: string;\n referencedColumns?: string[];\n}): ContextFragment {\n return {\n name: 'constraint',\n data: {\n name: input.name,\n type: input.type,\n ...(input.columns?.length && { columns: input.columns }),\n ...(input.definition && { definition: input.definition }),\n ...(input.defaultValue && { defaultValue: input.defaultValue }),\n ...(input.referencedTable && { referencedTable: input.referencedTable }),\n ...(input.referencedColumns?.length && {\n referencedColumns: input.referencedColumns,\n }),\n },\n };\n}\n\n/**\n * Database view.\n *\n * @param input.name - View name\n * @param input.schema - Schema name\n * @param input.columns - Array of column() fragments\n * @param input.definition - View SQL definition\n *\n * @example\n * view({\n * name: 'active_users',\n * columns: [\n * column({ name: 'id', type: 'integer' }),\n * column({ name: 'email', type: 'varchar' }),\n * ],\n * definition: \"SELECT id, email FROM users WHERE status = 'active'\",\n * })\n */\nexport function view(input: {\n name: string;\n schema?: string;\n columns: ContextFragment[];\n definition?: string;\n}): ContextFragment {\n return {\n name: 'view',\n data: {\n name: input.name,\n ...(input.schema && { schema: input.schema }),\n columns: input.columns,\n ...(input.definition && { definition: input.definition }),\n },\n };\n}\n\n/**\n * Relationship between tables (foreign key connection).\n *\n * @param input.from - Source table and columns\n * @param input.to - Referenced table and columns\n * @param input.cardinality - Relationship cardinality\n *\n * @example\n * relationship({\n * from: { table: 'orders', columns: ['user_id'] },\n * to: { table: 'users', columns: ['id'] },\n * cardinality: 'many-to-one',\n * })\n */\nexport function relationship(input: {\n from: { table: string; columns: string[] };\n to: { table: string; columns: string[] };\n cardinality?: 'one-to-one' | 'one-to-many' | 'many-to-one' | 'many-to-many';\n}): ContextFragment {\n return {\n name: 'relationship',\n data: {\n from: input.from,\n to: input.to,\n ...(input.cardinality && { cardinality: input.cardinality }),\n },\n };\n}\n", "import type {\n AdapterInfo,\n ColumnStats,\n OnProgress,\n Relationship,\n Table,\n} from '../adapter.ts';\nimport type { View } from './view.grounding.ts';\n\n/**\n * Column type for grounding operations.\n * Common interface between Table.columns and View.columns.\n */\nexport interface Column {\n name: string;\n type: string;\n kind?: 'LowCardinality' | 'Enum';\n values?: string[];\n stats?: ColumnStats;\n}\n\n/**\n * Entity with columns (Table or View).\n */\nexport interface ColumnContainer {\n name: string;\n columns: Column[];\n}\n\n/**\n * Shared context object passed to all groundings.\n * Groundings read from and write to this context.\n */\nexport interface GroundingContext {\n /** Tables discovered by TableGrounding */\n tables: Table[];\n\n /** Views discovered by ViewGrounding */\n views: View[];\n\n /** Relationships discovered by TableGrounding */\n relationships: Relationship[];\n\n /** Database info collected by InfoGrounding */\n info?: AdapterInfo;\n\n /** Shared cache for cross-grounding deduplication. Keyed by `type:key`. */\n cache: Map<string, unknown>;\n\n /** Progress sink for long-running introspection work. */\n onProgress: OnProgress;\n}\n\nconst noopProgress: OnProgress = () => {};\n\nfunction timestampProgress(onProgress?: OnProgress): OnProgress {\n if (!onProgress) return noopProgress;\n return (progress) => {\n onProgress({\n ...progress,\n timestampMs: progress.timestampMs ?? Date.now(),\n });\n };\n}\n\n/**\n * Create a new empty grounding context.\n */\nexport function createGroundingContext(\n options: { onProgress?: OnProgress } = {},\n): GroundingContext {\n return {\n tables: [],\n views: [],\n relationships: [],\n info: undefined,\n cache: new Map(),\n onProgress: timestampProgress(options.onProgress),\n };\n}\n", "import { groq } from '@ai-sdk/groq';\nimport {\n APICallError,\n JSONParseError,\n NoContentGeneratedError,\n NoObjectGeneratedError,\n NoOutputGeneratedError,\n TypeValidationError,\n defaultSettingsMiddleware,\n wrapLanguageModel,\n} from 'ai';\nimport dedent from 'dedent';\nimport pRetry from 'p-retry';\nimport z from 'zod';\n\nimport { type AgentModel } from '@deepagents/agent';\nimport {\n ContextEngine,\n type ContextFragment,\n InMemoryContextStore,\n example,\n fragment,\n guardrail,\n hint,\n persona,\n policy,\n structuredOutput,\n user,\n workflow,\n} from '@deepagents/context';\n\nimport type { Adapter } from '../adapters/adapter.ts';\nimport { buildScopeParseErrorPayload } from '../sql-scope-error.ts';\nimport { SQLValidationError, UnanswerableSQLError } from './exceptions.ts';\n\nexport interface ToSqlOptions {\n /** The natural language input to convert to SQL */\n input: string;\n /** Database adapter for validation */\n adapter: Adapter;\n /** Context fragments (schema + instructions/teachings) */\n fragments: ContextFragment[];\n /** Optional model override */\n model: AgentModel;\n /** Maximum retry attempts on validation failure (default: 3) */\n maxRetries?: number;\n}\n\nexport interface ToSqlResult {\n /** The generated SQL query */\n sql: string;\n /** Number of attempts made */\n attempts: number;\n /** Validation errors encountered (if any retries occurred) */\n errors?: string[];\n}\n\n/** Temperature progression for retries: deterministic first, then increasingly exploratory */\nconst RETRY_TEMPERATURES = [0, 0.2, 0.3];\nconst SQL_AGENT_ROLE = 'Expert SQL query generator.';\nconst SQL_AGENT_OBJECTIVE = 'Generate precise SQL grounded in provided schema.';\nconst SQL_AGENT_POLICIES: ContextFragment[] = [\n fragment(\n 'schema_mapping',\n policy({\n rule: 'Translate natural language into precise SQL grounded in available schema entities.',\n }),\n hint('Preserve schema spelling exactly, including typos in column names.'),\n ),\n fragment(\n 'projection_minimality',\n policy({\n rule: 'Return only columns requested by the question; do not add helper columns unless explicitly requested.',\n }),\n policy({\n rule: 'For requests of the form \"X sorted/ordered by Y\", project X only unless Y is explicitly requested as an output field.',\n }),\n policy({\n rule: 'Prefer selecting schema columns directly without derived expressions when direct selection answers the request.',\n }),\n hint(\n 'Do not include ORDER BY, GROUP BY, or JOIN helper columns in SELECT output unless the question explicitly asks for them.',\n ),\n policy({\n rule: 'Use DISTINCT only when uniqueness is explicitly requested (for example distinct/unique/different/no duplicates).',\n }),\n hint(\n 'Do not infer DISTINCT from generic wording such as \"some\", plural nouns, or entity-set phrasing; for transactional/attendance-style tables, default to raw rows unless uniqueness is explicitly requested.',\n ),\n ),\n fragment(\n 'date_transform_safety',\n policy({\n rule: 'Do not assume VARCHAR/TEXT values are parseable dates. Avoid date extraction functions on text columns by default.',\n }),\n policy({\n rule: 'Use date-part extraction only when both conditions hold: the question explicitly asks for transformation and schema values require transformation to produce that unit.',\n }),\n hint(\n 'Do not apply SUBSTR, STRFTIME, DATE_PART, YEAR, or similar extraction functions unless the question explicitly asks for transformation and schema values require it.',\n ),\n hint(\n 'If a column already represents the requested concept (for example a stored year-like value), use the column as-is.',\n ),\n ),\n fragment(\n 'sql_minimality',\n guardrail({\n rule: 'Never hallucinate tables or columns.',\n reason: 'Schema fidelity is required.',\n action: 'Use only available schema entities.',\n }),\n guardrail({\n rule: 'Avoid unnecessary transformations and derived projections.',\n reason:\n 'Extra transformations frequently change semantics and reduce correctness.',\n action:\n 'Do not add date parsing, substring extraction, or derived columns unless explicitly required by the question or schema.',\n }),\n ),\n fragment(\n 'preflight_checklist',\n workflow({\n task: 'Final SQL preflight before returning output',\n steps: [\n 'Verify selected columns match the question and remove unrequested helper projections.',\n 'If aggregate values are used only for ranking/filtering, keep them out of SELECT unless explicitly requested.',\n 'Prefer raw schema columns over derived expressions when raw columns already satisfy the request.',\n 'If a candidate query uses STRFTIME, SUBSTR, DATE_PART, YEAR, or similar extraction on text-like columns, remove that transformation unless explicitly required by the question.',\n 'Return only schema-grounded SQL using existing tables and columns.',\n ],\n }),\n ),\n fragment(\n 'set_semantics',\n policy({\n rule: 'For questions asking where both condition A and condition B hold over an attribute, compute the intersection of qualifying sets for that attribute.',\n }),\n policy({\n rule: 'Do not force the same entity instance to satisfy both conditions unless the question explicitly requests the same person/row/entity.',\n }),\n hint(\n 'Prefer INTERSECT (or logically equivalent set-based shape) over requiring the same physical row/entity to satisfy both conditions unless explicitly requested.',\n ),\n hint(\n 'When two conditions describe different row groups whose shared attribute is requested, build each group separately and intersect the attribute values.',\n ),\n hint(\n 'Do not collapse cross-group conditions into a single-row AND predicate when the intent is shared values across groups.',\n ),\n policy({\n rule: 'If two predicates on the same field cannot both be true for one row, do not combine them with AND; use set operations across separate filtered subsets when shared values are requested.',\n }),\n ),\n fragment(\n 'predicate_column_alignment',\n policy({\n rule: 'Match literal values to semantically compatible columns. Do not compare descriptive names to identifier columns.',\n }),\n hint(\n 'When a filter value is a descriptive label (for example a department name), join through the lookup table and filter on its name/title column, not on *_id columns.',\n ),\n hint(\n 'When relation roles are explicit in wording (for example host/home/source/destination), prefer foreign keys with matching role qualifiers over generic similarly named columns.',\n ),\n policy({\n rule: 'When multiple foreign-key candidates exist, select the column whose qualifier best matches the relationship described in the question.',\n }),\n policy({\n rule: 'For hosting/held semantics, prefer host_* relationship columns when available over generic *_id alternatives.',\n }),\n hint(\n 'Interpret wording like \"held/hosted a competition or event\" as a hosting relationship and map to host_* foreign keys when present.',\n ),\n policy({\n rule: 'Do not compare descriptive labels or names to *_id columns; join to the table containing the descriptive field and filter there.',\n }),\n policy({\n rule: 'Keep numeric identifiers unquoted when used as numeric equality filters unless schema indicates text identifiers.',\n }),\n policy({\n rule: 'When filtering by a descriptive label value and a related table exposes a corresponding *_name or title column, join to that table and filter on the descriptive column.',\n }),\n ),\n fragment(\n 'ordering_semantics',\n policy({\n rule: 'Respect explicit sort direction terms. If direction is not specified, use ascending order unless a superlative intent (most/least/highest/lowest) implies direction.',\n }),\n policy({\n rule: 'When ranking categories by frequency, use COUNT for ordering but keep output focused on requested category fields unless counts are explicitly requested.',\n }),\n policy({\n rule: 'Do not use DESC unless descending direction is explicit or a superlative intent requires descending ranking.',\n }),\n policy({\n rule: 'For \"most common/frequent <attribute>\" requests, return the attribute value(s) only; use counts only for ordering/filtering unless the question explicitly asks to return counts.',\n }),\n hint(\n 'Use DESC with LIMIT 1 for \"most/highest/largest\"; use ASC with LIMIT 1 for \"least/lowest/smallest\".',\n ),\n ),\n fragment(\n 'negative_membership_queries',\n policy({\n rule: 'For requests asking entities that did not participate/host/appear in related records, prefer NOT IN or NOT EXISTS against the related foreign-key set.',\n }),\n hint(\n 'Map role-bearing relationship columns carefully (for example host_* foreign keys for hosting relationships) instead of generic IDs when role wording is explicit.',\n ),\n hint(\n 'For \"never had/never exceeded\" conditions over history tables, exclude entities via NOT IN/NOT EXISTS against the disqualifying entity-id set (often built with GROUP BY/HAVING MAX(...)).',\n ),\n ),\n fragment(\n 'join_completeness',\n policy({\n rule: 'Preserve entity-restricting joins implied by the question. Do not widen results by querying only a broader attribute table when a subset entity table is available.',\n }),\n policy({\n rule: 'If an entity term in the question maps to a table, keep that table in query scope and join to attribute tables rather than dropping the entity table.',\n }),\n hint(\n 'If the question targets a specific entity group, include that entity table and its join conditions even when selected columns come from a related table.',\n ),\n hint(\n 'When the question names an entity type and a relation table links to that entity via *_id, include the entity table in scope instead of counting only relation rows.',\n ),\n hint(\n 'Prefer INNER JOIN by default; use LEFT JOIN only when the question explicitly requests including unmatched rows or zero-related entities.',\n ),\n ),\n fragment(\n 'aggregation_exactness',\n policy({\n rule: 'Preserve requested aggregation semantics exactly: use COUNT(*) by default for total rows, use COUNT(DISTINCT ...) only when uniqueness is explicitly requested, and group by stable entity keys when computing per-entity aggregates.',\n }),\n policy({\n rule: 'For questions asking which entity has lowest/highest average of a metric, compute AVG(metric) per entity (GROUP BY entity) and rank those aggregates.',\n }),\n hint(\n 'For \"how many <entities>\" questions over relation records, default to COUNT(*) on qualifying rows unless explicit uniqueness language is present.',\n ),\n ),\n fragment(\n 'query_shape_examples',\n example({\n question:\n 'List categories ordered by how many records belong to each category.',\n answer:\n 'SELECT category FROM records GROUP BY category ORDER BY COUNT(*)',\n }),\n example({\n question:\n 'Show labels shared by rows with metric > 100 and rows with metric < 10.',\n answer:\n 'SELECT label FROM records WHERE metric > 100 INTERSECT SELECT label FROM records WHERE metric < 10',\n }),\n example({\n question: 'List locations that have not hosted any event.',\n answer:\n 'SELECT location_name FROM locations WHERE location_id NOT IN (SELECT host_location_id FROM events)',\n }),\n example({\n question: 'List the most common category across records.',\n answer:\n 'SELECT category FROM records GROUP BY category ORDER BY COUNT(*) DESC LIMIT 1',\n }),\n ),\n];\n\n/** Extract SQL from markdown fenced code block if present */\nfunction extractSql(output: string): string {\n const match = output.match(/```sql\\n?([\\s\\S]*?)```/);\n return match ? match[1].trim() : output.trim();\n}\n\nexport async function toSql(options: ToSqlOptions): Promise<ToSqlResult> {\n const { maxRetries = 3 } = options;\n\n return withRetry(\n async (attemptNumber, errors, attempts) => {\n const context = new ContextEngine({\n store: new InMemoryContextStore(),\n chatId: `sql-gen-${crypto.randomUUID()}`,\n userId: 'system',\n });\n\n context.set(\n persona({\n name: 'Freya',\n role: SQL_AGENT_ROLE,\n objective: SQL_AGENT_OBJECTIVE,\n // role: `You are a data science expert that provides well-reasoned and detailed responses.`,\n // objective: `Your task is to understand the schema and generate a valid SQL query to answer the question. You first think about the reasoning process as an internal monologue and then provide the user with the answer.`,\n }),\n ...SQL_AGENT_POLICIES,\n ...options.fragments,\n );\n\n // Add user message(s)\n if (errors.length) {\n const lastError = errors.at(-1);\n context.set(\n user(dedent`\n Answer the following question with the SQL code. Use the piece of evidence and base your answer on the database schema.\nGiven the question, the evidence and the database schema, return the SQL script that addresses the question.\n\nQuestion: ${options.input}\n`),\n UnanswerableSQLError.isInstance(lastError)\n ? user(\n `<retry_instruction>Your previous response marked the task as unanswerable. Re-evaluate using best-effort schema mapping. If the core intent is answerable with existing tables/columns, return SQL. Return error only when required core intent cannot be mapped without inventing schema elements.</retry_instruction>`,\n )\n : user(\n `<validation_error>Your previous SQL query had the following error: ${lastError?.message}. Please fix the query.</validation_error>`,\n ),\n );\n } else {\n context.set(\n user(dedent`\n Answer the following question with the SQL code. Use the piece of evidence and base your answer on the database schema.\nGiven the question, the evidence and the database schema, return the SQL script that addresses the question.\n\nQuestion: ${options.input}\n`),\n );\n }\n\n // Create structured output with schema\n const temperature =\n RETRY_TEMPERATURES[attemptNumber - 1] ??\n RETRY_TEMPERATURES[RETRY_TEMPERATURES.length - 1];\n const baseModel = options.model ?? groq('openai/gpt-oss-20b');\n const model = wrapLanguageModel({\n model: baseModel,\n middleware: defaultSettingsMiddleware({ settings: { temperature } }),\n });\n const sqlOutput = structuredOutput({\n model: model,\n context,\n schema: z.object({\n result: z.union([\n z.object({\n sql: z\n .string()\n .describe('The SQL query that answers the question'),\n reasoning: z\n .string()\n .describe('The reasoning steps taken to generate the SQL'),\n }),\n z.object({\n error: z\n .string()\n .describe(\n 'Error message explaining why the question cannot be answered with the given schema',\n ),\n }),\n ]),\n }),\n });\n\n const { result: output } = await sqlOutput.generate();\n\n const finalizeSql = async (rawSql: string): Promise<ToSqlResult> => {\n const extractedSql = extractSql(rawSql);\n const errorsOrUndefined = errors.length\n ? errors.map(formatErrorMessage)\n : undefined;\n\n if (extractedSql === '') {\n return {\n attempts,\n sql: '',\n errors: errorsOrUndefined,\n };\n }\n\n const sql = options.adapter.format(extractedSql);\n if (\n rawSql.trimStart().startsWith('```') &&\n extractedSql === rawSql.trim()\n ) {\n throw new SQLValidationError(\n JSON.stringify(\n buildScopeParseErrorPayload(\n sql,\n options.adapter.formatterLanguage,\n new Error(\n 'SQL response was fenced markdown, not executable SQL.',\n ),\n ),\n ),\n );\n }\n\n const validationError = await options.adapter.validate(sql);\n if (validationError) {\n throw new SQLValidationError(validationError);\n }\n\n return {\n attempts,\n sql,\n errors: errorsOrUndefined,\n };\n };\n\n // Handle error responses (question is unanswerable with given schema)\n if ('error' in output) {\n context.set(\n user(\n '<best_effort_fallback>Do not return unanswerable. Produce the best valid SQL query that answers the core intent using only available schema entities.</best_effort_fallback>',\n ),\n );\n const forcedSqlOutput = structuredOutput({\n model,\n context,\n schema: z.object({\n sql: z\n .string()\n .describe(\n 'Best-effort SQL query that answers the core intent using only available schema entities.',\n ),\n reasoning: z\n .string()\n .describe('Reasoning steps for best-effort schema mapping.'),\n }),\n });\n\n try {\n const forced = await forcedSqlOutput.generate();\n return await finalizeSql(forced.sql);\n } catch (error) {\n if (\n SQLValidationError.isInstance(error) ||\n APICallError.isInstance(error) ||\n JSONParseError.isInstance(error) ||\n TypeValidationError.isInstance(error) ||\n NoObjectGeneratedError.isInstance(error) ||\n NoOutputGeneratedError.isInstance(error) ||\n NoContentGeneratedError.isInstance(error)\n ) {\n throw error;\n }\n throw new UnanswerableSQLError(output.error);\n }\n }\n\n return await finalizeSql(output.sql);\n },\n { retries: maxRetries - 1 },\n );\n}\n\nfunction formatErrorMessage(error: Error) {\n if (APICallError.isInstance(error)) {\n if (error.message.startsWith('Failed to validate JSON')) {\n return `Schema validation failed: ${error.message}`;\n }\n return error.message;\n }\n if (SQLValidationError.isInstance(error)) {\n return `SQL Validation Error: ${error.message}`;\n }\n return error.message;\n}\n\nfunction isModelUnavailableError(error: unknown): boolean {\n if (!APICallError.isInstance(error)) {\n return false;\n }\n\n const message = error.message.toLowerCase();\n const responseBody = (error.responseBody ?? '').toLowerCase();\n const is404ModelError =\n error.statusCode === 404 &&\n (message.includes('model') || responseBody.includes('model_not_found'));\n const errorCode =\n typeof error.data === 'object' &&\n error.data !== null &&\n 'error' in error.data &&\n typeof error.data.error === 'object' &&\n error.data.error !== null &&\n 'code' in error.data.error &&\n typeof error.data.error.code === 'string'\n ? error.data.error.code.toLowerCase()\n : undefined;\n\n return (\n is404ModelError ||\n errorCode === 'model_not_found' ||\n responseBody.includes('\"code\":\"model_not_found\"') ||\n (message.includes('model') &&\n message.includes('does not exist or you do not have access to it'))\n );\n}\n\nasync function withRetry<T>(\n computation: (\n attemptNumber: number,\n errors: Error[],\n attempts: number,\n ) => Promise<T>,\n options: { retries: number } = { retries: 3 },\n) {\n const errors: Error[] = [];\n let attempts = 0;\n return pRetry(\n (attemptNumber) => {\n return computation(attemptNumber, errors, ++attempts);\n },\n {\n retries: options.retries,\n shouldRetry: (context) => {\n // Retry one time when the model marks query as unanswerable to recover from false positives.\n if (UnanswerableSQLError.isInstance(context.error)) {\n return false;\n // disable retryng here will also disable the forced sql generation fallback.\n // return context.attemptNumber === 0;\n }\n // Don't retry if the selected model is unavailable\n if (isModelUnavailableError(context.error)) {\n return false;\n }\n // Retry on validation errors\n if (SQLValidationError.isInstance(context.error)) {\n return true;\n }\n console.log({\n NoObjectGeneratedError: NoObjectGeneratedError.isInstance(\n context.error,\n ),\n NoOutputGeneratedError: NoOutputGeneratedError.isInstance(\n context.error,\n ),\n APICallError: APICallError.isInstance(context.error),\n JSONParseError: JSONParseError.isInstance(context.error),\n TypeValidationError: TypeValidationError.isInstance(context.error),\n NoContentGeneratedError: NoContentGeneratedError.isInstance(\n context.error,\n ),\n });\n // Retry on AI SDK errors\n return (\n APICallError.isInstance(context.error) ||\n JSONParseError.isInstance(context.error) ||\n TypeValidationError.isInstance(context.error) ||\n NoObjectGeneratedError.isInstance(context.error) ||\n NoOutputGeneratedError.isInstance(context.error) ||\n NoContentGeneratedError.isInstance(context.error)\n );\n },\n onFailedAttempt(context) {\n // console.log(\n // `Attempt ${context.attemptNumber} failed. There are ${context.retriesLeft} retries left.`,\n // );\n // console.dir(context.error, { depth: null });\n errors.push(context.error);\n },\n },\n );\n}\n", "import type { SQLScopeErrorPayload } from './agents/exceptions.ts';\n\nexport function buildScopeParseErrorPayload(\n sql: string,\n parserDialect: string,\n error: unknown,\n): SQLScopeErrorPayload {\n const parserError =\n error instanceof Error ? error.message : String(error ?? 'Unknown error');\n\n return {\n error: `SQL scope analysis failed before validation/execution: ${parserError}`,\n error_type: 'SQL_SCOPE_PARSE_ERROR',\n suggestion:\n 'Rewrite the query into simpler SQL that can be analyzed safely, or extend parser coverage for this dialect feature.',\n sql_attempted: sql,\n parser_dialect: parserDialect,\n parser_error: parserError,\n };\n}\n", "import { groq } from '@ai-sdk/groq';\nimport dedent from 'dedent';\nimport z from 'zod';\n\nimport { agent, thirdPersonPrompt } from '@deepagents/agent';\n\nimport type { Introspection } from '../adapters/adapter.ts';\nimport { databaseSchemaPrompt } from '../prompt.ts';\n\ntype SuggestionsAgentContext = {\n context?: string;\n adapterInfo?: string;\n};\ntype SuggestionsAgentOutput = {\n suggestions: {\n question: string;\n sql: string;\n businessValue: string;\n }[];\n};\n\nexport const suggestionsAgent = agent<\n SuggestionsAgentOutput,\n SuggestionsAgentContext\n>({\n name: 'text2sql-suggestions',\n model: groq('openai/gpt-oss-20b'),\n output: z.object({\n suggestions: z\n .array(\n z.object({\n question: z\n .string()\n .describe('A complex, high-impact business question.'),\n sql: z\n .string()\n .describe('The SQL statement needed to answer the question.'),\n businessValue: z\n .string()\n .describe('Why the question matters to stakeholders.'),\n }),\n )\n .min(1)\n .max(5)\n .describe('A set of up to two advanced question + SQL pairs.'),\n }),\n prompt: (state) => {\n return dedent`\n ${thirdPersonPrompt()}\n\n <identity>\n You are a senior analytics strategist who proposes ambitious business questions\n and drafts the SQL needed to answer them. You specialize in identifying ideas\n that combine multiple tables, apply segmentation or time analysis, and surface\n metrics that drive executive decisions.\n </identity>\n\n\n <instructions>\n - Recommend one or two UNIQUE questions that go beyond simple counts or listings.\n - Favor questions that require joins, aggregates, time comparisons, cohort analysis,\n or window functions.\n - For each question, explain the business reason stakeholders care about it.\n - Provide the complete SQL query that could answer the question in the given schema.\n - Keep result sets scoped with LIMIT clauses (max 50 rows) when returning raw rows.\n - Ensure table/column names match the provided schema exactly.\n - Use columns marked [LowCardinality: ...] to identify meaningful categorical filters or segmentations.\n - Leverage table [rows / size] hints to determine whether to aggregate (large tables) or inspect detailed data (tiny tables).\n - Reference PK/Indexed annotations and the Indexes list to recommend queries that use efficient join/filter paths.\n - Column annotations may expose ranges/null percentages\u2014use them to suggest realistic thresholds or quality checks.\n - Consult <relationship_examples> to anchor your recommendations in the actual join paths between tables.\n - Output only information grounded in the schema/context provided.\n </instructions>\n\n <response-format>\n Return valid JSON that satisfies the defined output schema.\n </response-format>\n `;\n },\n});\n", "import { type ContextFragment, fragment } from '@deepagents/context';\n\nimport {\n DATABASE_NAME_FRAGMENT,\n validateAdapterNames,\n} from './adapter-name.ts';\nimport {\n type Adapter,\n type IntrospectionPhase,\n type IntrospectionProgress,\n} from './adapters/adapter.ts';\nimport { createGroundingContext } from './adapters/groundings/context.ts';\nimport { type IndexCache } from './index-cache.ts';\nimport { type IndexLock } from './index-lock.ts';\n\nexport const TEXT2SQL_INDEX_PROGRESS_CHUNK = 'data-text2sql-index-progress';\n\nexport type Text2SqlIndexProgressEventType =\n | 'index:start'\n | 'index:end'\n | 'adapter:start'\n | 'adapter:end'\n | 'adapter:cache-hit'\n | 'adapter:cache-miss'\n | 'phase:start'\n | 'phase:progress'\n | 'phase:end'\n | 'adapter:error'\n | 'index:error';\n\nexport interface Text2SqlIndexProgressEvent {\n type: Text2SqlIndexProgressEventType;\n adapter?: string;\n phase?: IntrospectionPhase;\n table?: string;\n message: string;\n current?: number;\n total?: number;\n cached?: boolean;\n timestampMs?: number;\n}\n\nexport type Text2SqlIndexProgressHandler = (\n event: Text2SqlIndexProgressEvent,\n) => void;\n\nexport interface AdapterIndexerOptions {\n adapters: Record<string, Adapter>;\n cache?: IndexCache;\n lock: IndexLock;\n}\n\nexport interface AdapterIndexerIndexOptions {\n adapterNames?: readonly string[];\n onProgress?: Text2SqlIndexProgressHandler;\n}\n\nexport interface AdapterIndexerAdapterOptions {\n onProgress?: Text2SqlIndexProgressHandler;\n}\n\nconst noopProgressHandler: Text2SqlIndexProgressHandler = () => {};\n\nfunction timestampProgressHandler(\n onProgress?: Text2SqlIndexProgressHandler,\n): Text2SqlIndexProgressHandler {\n if (!onProgress) return noopProgressHandler;\n return (event) => {\n onProgress({\n ...event,\n timestampMs: event.timestampMs ?? Date.now(),\n });\n };\n}\n\n/**\n * Build a clean `<database>name</database>` leaf carrying the adapter's\n * configured connection name (the exact `<db>` value for `sql run <db>`).\n * Injected as the first child of each adapter fragment so the name the model\n * must pass is a labeled value at the top of the schema block \u2014 not just the\n * wrapper tag a small model overlooks.\n *\n * Constructed directly (not via `fragment()`, which wraps string children in an\n * array and double-nests the tag): a plain `{ name, data }` like the\n * introspected schema fragments, so it is JSON-safe and renders the name as the\n * tag's text content. `DATABASE_NAME_FRAGMENT` is reserved as an adapter name\n * (see adapter-name.ts) so the label tag can never collide with a wrapper tag.\n */\nfunction databaseNameFragment(name: string): ContextFragment {\n return { name: DATABASE_NAME_FRAGMENT, data: name };\n}\n\nexport class AdapterIndexer {\n readonly #adapters: Record<string, Adapter>;\n readonly #cache: IndexCache | undefined;\n readonly #lock: IndexLock;\n\n constructor(options: AdapterIndexerOptions) {\n const adapterNames = Object.keys(options.adapters);\n if (adapterNames.length === 0) {\n throw new Error('AdapterIndexer requires at least one adapter');\n }\n\n validateAdapterNames(adapterNames);\n this.#adapters = options.adapters;\n this.#cache = options.cache;\n this.#lock = options.lock;\n }\n\n async index(\n options: AdapterIndexerIndexOptions = {},\n ): Promise<ContextFragment[]> {\n const progress = timestampProgressHandler(options.onProgress);\n const entries = this.#resolveIndexEntries(options.adapterNames);\n\n progress({\n type: 'index:start',\n message: `Indexing ${entries.length} adapter${entries.length === 1 ? '' : 's'}...`,\n current: 0,\n total: entries.length,\n });\n\n const settled = await Promise.allSettled(\n entries.map(async ([name, adapter]) => {\n const schema = await this.#indexAdapter(name, adapter, progress);\n return fragment(name, databaseNameFragment(name), ...schema);\n }),\n );\n\n const failed = settled.find((result) => result.status === 'rejected');\n if (failed) {\n progress({\n type: 'index:error',\n message:\n failed.reason instanceof Error\n ? failed.reason.message\n : String(failed.reason),\n });\n throw failed.reason;\n }\n\n const wrapped = settled.map((result) => {\n if (result.status === 'rejected') {\n throw result.reason;\n }\n return result.value;\n });\n\n progress({\n type: 'index:end',\n message: 'Finished indexing adapters.',\n current: entries.length,\n total: entries.length,\n });\n\n return wrapped;\n }\n\n async indexAdapter(\n name: string,\n options: AdapterIndexerAdapterOptions = {},\n ): Promise<ContextFragment[]> {\n const adapter = this.#adapters[name];\n if (!adapter) {\n const available = Object.keys(this.#adapters).join(', ');\n throw new Error(`unknown adapter \"${name}\". Available: ${available}`);\n }\n\n return this.#indexAdapter(\n name,\n adapter,\n timestampProgressHandler(options.onProgress),\n );\n }\n\n async #indexAdapter(\n name: string,\n adapter: Adapter,\n progress: Text2SqlIndexProgressHandler,\n ): Promise<ContextFragment[]> {\n progress({\n type: 'adapter:start',\n adapter: name,\n message: `Indexing adapter \"${name}\"...`,\n });\n\n const cache = this.#cache;\n const key = name;\n\n const emitCacheHit = () =>\n progress({\n type: 'adapter:cache-hit',\n adapter: name,\n message: `Using cached index for adapter \"${name}\".`,\n cached: true,\n });\n const emitCacheMiss = () =>\n progress({\n type: 'adapter:cache-miss',\n adapter: name,\n message: `No cached index for adapter \"${name}\".`,\n cached: false,\n });\n\n const introspect = async () => {\n const ctx = createGroundingContext({\n onProgress: (event) => progress(adapterProgressEvent(name, event)),\n });\n const fragments = await adapter.introspect(ctx);\n await cache?.write(key, fragments);\n return fragments;\n };\n\n let servedFromCache = false;\n const populate = async () => {\n const recheck = await cache?.read(key);\n if (recheck) {\n servedFromCache = true;\n return recheck;\n }\n if (cache) emitCacheMiss();\n return introspect();\n };\n\n try {\n const cached = await cache?.read(key);\n if (cached) {\n emitCacheHit();\n progress({\n type: 'adapter:end',\n adapter: name,\n message: `Finished indexing adapter \"${name}\".`,\n cached: true,\n });\n return cached;\n }\n\n const fragments = await this.#lock.run(key, populate);\n\n if (servedFromCache) emitCacheHit();\n progress({\n type: 'adapter:end',\n adapter: name,\n message: `Finished indexing adapter \"${name}\".`,\n cached: servedFromCache,\n });\n return fragments;\n } catch (error) {\n const reason = errorMessage(error);\n progress({\n type: 'adapter:error',\n adapter: name,\n message: `Failed indexing adapter \"${name}\": ${reason}`,\n });\n throw new Error(`introspecting adapter \"${name}\": ${reason}`, {\n cause: error,\n });\n }\n }\n\n #resolveIndexEntries(\n adapterNames: readonly string[] | undefined,\n ): Array<[string, Adapter]> {\n const availableNames = Object.keys(this.#adapters);\n const requestedNames =\n adapterNames && adapterNames.length > 0\n ? [...new Set(adapterNames)]\n : availableNames;\n const available = availableNames.join(', ');\n\n return requestedNames.map((name) => {\n const adapter = this.#adapters[name];\n if (!adapter) {\n throw new Error(`unknown adapter \"${name}\". Available: ${available}`);\n }\n return [name, adapter];\n });\n }\n}\n\nfunction adapterProgressEvent(\n adapter: string,\n progress: IntrospectionProgress,\n): Text2SqlIndexProgressEvent {\n return {\n type: progress.type,\n adapter,\n phase: progress.phase,\n table: progress.table,\n message: progress.message,\n current: progress.current,\n total: progress.total,\n cached: false,\n timestampMs: progress.timestampMs,\n };\n}\n\nfunction errorMessage(error: unknown): string {\n return error instanceof Error ? error.message : String(error);\n}\n", "import { createHash, randomUUID } from 'node:crypto';\nimport { existsSync } from 'node:fs';\nimport { mkdir, readFile, rename, writeFile } from 'node:fs/promises';\nimport { tmpdir } from 'node:os';\nimport path from 'node:path';\n\nexport class FileCache {\n public path: string;\n constructor(\n watermark: string,\n extension = '.txt',\n baseDir: string = tmpdir(),\n ) {\n const hash = createHash('md5').update(watermark).digest('hex');\n this.path = path.join(baseDir, `text2sql-${hash}${extension}`);\n }\n\n async get() {\n if (existsSync(this.path)) {\n return readFile(this.path, 'utf-8');\n }\n return null;\n }\n\n async set(content: string) {\n await mkdir(path.dirname(this.path), { recursive: true });\n const tempPath = `${this.path}.${randomUUID()}.tmp`;\n await writeFile(tempPath, content, 'utf-8');\n await rename(tempPath, this.path);\n }\n}\n\nexport class JsonCache<T> extends FileCache {\n constructor(watermark: string, baseDir?: string) {\n super(watermark, '.json', baseDir);\n }\n\n async read(): Promise<T | null> {\n const content = await this.get();\n if (!content) {\n return null;\n }\n try {\n return JSON.parse(content) as T;\n } catch {\n // Corrupt or legacy cache file (e.g. a torn write on a non-atomic\n // shared volume): treat as a miss so the caller re-introspects and\n // atomically rewrites it, rather than throwing.\n return null;\n }\n }\n\n write(data: T) {\n return this.set(JSON.stringify(data));\n }\n}\n", "import type { ContextFragment } from '@deepagents/context';\n\nimport { JsonCache } from './file-cache.ts';\n\n/**\n * Stores introspected schema fragments per adapter so repeated indexing can\n * reuse them instead of re-introspecting the database.\n *\n * The package defines this contract but does not own the storage. Hosts decide\n * where the cache lives \u2014 a shared volume, Redis, S3, a database \u2014 by supplying\n * an implementation. When no cache is provided, indexing always introspects.\n *\n * `key` is a stable per-adapter identifier; the same key is reused for the same\n * adapter across processes, so a cache shared across a fleet lets one process's\n * write satisfy another's read. Pair with an\n * {@link import('./index-lock.ts').IndexLock} keyed by the same value to make\n * concurrent introspection single-flight.\n */\nexport interface IndexCache {\n read(key: string): Promise<ContextFragment[] | null>;\n write(key: string, fragments: ContextFragment[]): Promise<void>;\n}\n\nexport interface FileIndexCacheOptions {\n /** Directory the cache files live in. Defaults to the OS temp directory. */\n dir?: string;\n /**\n * Optional invalidation token folded into the cache key. Change it (e.g. a\n * deploy id or schema version) to start a fresh cache generation.\n */\n namespace?: string;\n}\n\n/**\n * File-backed {@link IndexCache} using atomic writes (temp + rename) and\n * treating an unparseable file as a miss. Point {@link FileIndexCacheOptions.dir}\n * at a shared volume to let horizontally-scaled processes share one cache.\n */\nexport class FileIndexCache implements IndexCache {\n readonly #dir: string | undefined;\n readonly #namespace: string | undefined;\n\n constructor(options: FileIndexCacheOptions = {}) {\n this.#dir = options.dir;\n this.#namespace = options.namespace;\n }\n\n read(key: string): Promise<ContextFragment[] | null> {\n return this.#cacheFor(key).read();\n }\n\n write(key: string, fragments: ContextFragment[]): Promise<void> {\n return this.#cacheFor(key).write(fragments);\n }\n\n #cacheFor(key: string): JsonCache<ContextFragment[]> {\n const watermark = this.#namespace ? `${this.#namespace}-${key}` : key;\n return new JsonCache<ContextFragment[]>(watermark, this.#dir);\n }\n}\n", "import { createHash } from 'node:crypto';\nimport { mkdir } from 'node:fs/promises';\nimport { tmpdir } from 'node:os';\nimport * as path from 'node:path';\nimport { type LockOptions, lock as acquireLock } from 'proper-lockfile';\n\n/**\n * Coordinates schema indexing across processes so that, for a given cache key,\n * only one introspection runs at a time (\"single-flight\" indexing).\n *\n * The package defines this contract and ships {@link FileIndexLock} for\n * processes that share a POSIX filesystem. Hosts that run across machines\n * without shared storage can supply an implementation backed by whatever they\n * already operate \u2014 a Redis lock, a Postgres advisory lock, a Zookeeper/etcd\n * lease, or an in-process mutex for a single-process deployment.\n */\nexport interface IndexLock {\n /**\n * Run `fn` under an exclusive lock identified by `key`.\n *\n * Implementations MUST acquire the lock (waiting if it is currently held\n * elsewhere), run `fn`, then release it \u2014 even if `fn` throws. Failure to\n * acquire the lock MUST reject: callers treat a lock-store failure as fatal\n * (fail-closed) rather than racing an unprotected introspection.\n *\n * @param key - Stable identifier for the work being guarded; the same key\n * is used for the same adapter + index version, so distinct\n * adapters lock independently.\n * @param fn - The critical section to run while the lock is held.\n * @returns The value returned by `fn`.\n */\n run<T>(key: string, fn: () => Promise<T>): Promise<T>;\n}\n\nconst DEFAULT_STALE_MS = 30_000;\nconst DEFAULT_RETRIES: LockOptions['retries'] = {\n retries: 10,\n factor: 2,\n minTimeout: 100,\n maxTimeout: 2_000,\n};\n\nexport interface FileIndexLockOptions extends Pick<\n LockOptions,\n 'stale' | 'retries'\n> {\n /**\n * Directory the lock files live in. Defaults to the OS temp directory. Point\n * it at a shared volume to serialize introspection across a fleet, alongside a\n * {@link import('./index-cache.ts').FileIndexCache} over the same volume.\n */\n dir?: string;\n /**\n * Token folded into the lock key, mirroring\n * {@link import('./index-cache.ts').FileIndexCacheOptions.namespace} so a new\n * generation locks independently of the previous one.\n */\n namespace?: string;\n}\n\n/**\n * Filesystem-backed {@link IndexLock} built on `proper-lockfile`. Processes that\n * share a POSIX filesystem (a single host, or a shared volume \u2014 NFSv4 / EFS)\n * serialize per adapter key, so pairing it with a shared\n * {@link import('./index-cache.ts').FileIndexCache} makes cross-process\n * introspection single-flight.\n *\n * A held lock auto-refreshes its mtime at `stale / 2`, so a slow introspection\n * is not mistaken for a crashed holder. Acquisition retries with backoff and,\n * once exhausted, rejects \u2014 satisfying the fail-closed requirement of\n * {@link IndexLock}.\n */\nexport class FileIndexLock implements IndexLock {\n readonly #dir: string;\n readonly #namespace: string | undefined;\n readonly #stale: LockOptions['stale'];\n readonly #retries: LockOptions['retries'];\n\n constructor(options: FileIndexLockOptions = {}) {\n this.#dir = options.dir ?? tmpdir();\n this.#namespace = options.namespace;\n this.#stale = options.stale ?? DEFAULT_STALE_MS;\n this.#retries = options.retries ?? DEFAULT_RETRIES;\n }\n\n async run<T>(key: string, fn: () => Promise<T>): Promise<T> {\n await mkdir(this.#dir, { recursive: true });\n const release = await acquireLock(this.#lockPathFor(key), {\n realpath: false,\n stale: this.#stale,\n retries: this.#retries,\n });\n try {\n return await fn();\n } finally {\n // Best-effort release: fn() has already settled (and the caller has\n // its result), so a compromised or already-released lock must not\n // surface as a failure that masks that result.\n await release().catch(() => {});\n }\n }\n\n #lockPathFor(key: string): string {\n const watermark = this.#namespace ? `${this.#namespace}-${key}` : key;\n const hash = createHash('md5').update(watermark).digest('hex');\n return path.join(this.#dir, `text2sql-lock-${hash}`);\n }\n}\n", "import { createHash } from 'node:crypto';\nimport { existsSync, readFileSync, renameSync, writeFileSync } from 'node:fs';\nimport pLimit from 'p-limit';\n\nexport interface CheckpointOptions {\n /** Path to the checkpoint file */\n path: string;\n /** Hash to detect config changes - if changed, checkpoint is invalidated */\n configHash?: string;\n}\n\n/**\n * Codec for encoding/decoding values during checkpoint operations.\n * Use this when storing objects with methods (like Teachables) that need\n * to be serialized to plain JSON and restored with their methods.\n */\nexport interface Codec<T, TSerialized = unknown> {\n /** Convert runtime value to JSON-serializable format */\n encode: (value: T) => TSerialized;\n /** Convert stored JSON back to runtime value */\n decode: (serialized: TSerialized) => T;\n}\n\ninterface PointEntry {\n inputHash: string;\n output: unknown;\n}\n\ninterface PointData {\n committed: boolean;\n entries: PointEntry[];\n}\n\ninterface CheckpointFile {\n configHash?: string;\n points: Record<string, PointData>;\n}\n\nexport class Checkpoint {\n private points: Record<string, PointData>;\n private path: string;\n private configHash: string | undefined;\n\n private constructor(\n path: string,\n configHash: string | undefined,\n points: Record<string, PointData>,\n ) {\n this.points = points;\n this.path = path;\n this.configHash = configHash;\n }\n\n /**\n * Load checkpoint from file, or return empty checkpoint if none exists.\n * Handles corrupted files and config changes gracefully.\n */\n static async load(options: CheckpointOptions): Promise<Checkpoint> {\n const { path, configHash } = options;\n\n if (existsSync(path)) {\n try {\n const content = readFileSync(path, 'utf-8');\n const file: CheckpointFile = JSON.parse(content);\n\n // Check if config changed\n if (configHash && file.configHash && file.configHash !== configHash) {\n console.log('\u26A0 Config changed, starting fresh');\n return new Checkpoint(path, configHash, {});\n }\n\n const points = file.points ?? {};\n const totalEntries = Object.values(points).reduce(\n (sum, p) => sum + p.entries.length,\n 0,\n );\n console.log(`\u2713 Resuming from checkpoint (${totalEntries} entries)`);\n return new Checkpoint(path, configHash, points);\n } catch {\n console.log('\u26A0 Checkpoint corrupted, starting fresh');\n return new Checkpoint(path, configHash, {});\n }\n }\n\n console.log('Starting new checkpoint');\n return new Checkpoint(path, configHash, {});\n }\n\n /**\n * Run a single computation with checkpointing.\n * If already completed, returns cached value.\n *\n * @param key - Unique identifier for this computation\n * @param computation - Async function that produces the value\n * @param codec - Optional codec for encoding/decoding non-primitive values\n */\n async run<T>(\n key: string,\n computation: () => Promise<T>,\n codec?: Codec<T>,\n ): Promise<T> {\n const point = this.point<T>(key);\n\n // Use fixed input hash for single-value runs\n return point.through(\n 'single',\n async () => {\n const result = await computation();\n return codec ? (codec.encode(result) as T) : result;\n },\n codec,\n );\n }\n\n /**\n * Create a resumable checkpoint point for iterative operations.\n *\n * @param step - Unique identifier for this checkpoint point\n */\n point<T>(step: string): Point<T> {\n this.points[step] ??= { committed: false, entries: [] };\n return new Point<T>(this.points[step], () => this.save());\n }\n\n /**\n * Process each input with automatic checkpointing and concurrency.\n *\n * @param step - Unique identifier for this checkpoint\n * @param inputs - Items to process\n * @param process - Function to process each input\n * @param options - Optional settings like concurrency\n * @returns All outputs (use `.flat()` if outputs are arrays)\n */\n async each<I, O>(\n step: string,\n inputs: Iterable<I>,\n process: (input: I) => Promise<O>,\n options?: { concurrency?: number },\n ): Promise<O[]> {\n const point = this.point<O>(step);\n const limit = pLimit(options?.concurrency ?? 1);\n\n const inputArray = Array.from(inputs);\n await Promise.all(\n inputArray.map((input) =>\n limit(() => point.through(input, () => process(input))),\n ),\n );\n\n await point.commit();\n return point.values();\n }\n\n /**\n * Get clean output from all completed points.\n * Single-entry points return the value directly, multi-entry return arrays.\n */\n getOutput(): Record<string, unknown> {\n const output: Record<string, unknown> = {};\n for (const [key, pointData] of Object.entries(this.points)) {\n if (pointData.entries.length === 1) {\n output[key] = pointData.entries[0].output;\n } else {\n output[key] = pointData.entries.map((e) => e.output);\n }\n }\n return output;\n }\n\n /** Get the file path where checkpoint is stored */\n getPath(): string {\n return this.path;\n }\n\n private async save(): Promise<void> {\n const file: CheckpointFile = {\n configHash: this.configHash,\n points: this.points,\n };\n const content = JSON.stringify(file, null, 2);\n\n // Atomic write: write to temp file, then rename\n const tempPath = `${this.path}.tmp`;\n writeFileSync(tempPath, content);\n renameSync(tempPath, this.path);\n }\n}\n\nfunction hash(value: unknown): string {\n return createHash('md5').update(JSON.stringify(value)).digest('hex');\n}\n\n/**\n * A checkpoint point for tracking iterative operations.\n * Uses input hashing to determine if an operation was already processed.\n */\nexport class Point<T> {\n #cache: Map<string, T>;\n private data: PointData;\n private persist: () => Promise<void>;\n\n constructor(data: PointData, persist: () => Promise<void>) {\n this.#cache = new Map(\n data.entries.map((e) => [e.inputHash, e.output as T]),\n );\n this.data = data;\n this.persist = persist;\n }\n\n /**\n * Execute computation if input wasn't processed before.\n * Returns cached output if input hash exists, otherwise executes, saves, and returns.\n */\n async through<I, O>(\n input: I,\n compute: () => Promise<O>,\n codec?: Codec<O>,\n ): Promise<O> {\n const inputHash = hash(input);\n\n if (this.#cache.has(inputHash)) {\n const cached = this.#cache.get(inputHash) as O;\n return codec ? codec.decode(cached) : cached;\n }\n\n const output = await compute();\n this.data.entries.push({ inputHash, output });\n this.#cache.set(inputHash, output as T);\n await this.persist();\n return codec ? codec.decode(output) : output;\n }\n\n /** Mark this point as complete. */\n async commit(): Promise<void> {\n this.data.committed = true;\n await this.persist();\n }\n\n /** Check if this point has been committed. */\n isCommitted(): boolean {\n return this.data.committed;\n }\n\n /** Get all outputs from this point. */\n values(): T[] {\n return this.data.entries.map((e) => e.output as T);\n }\n}\n\n/**\n * Generate a hash from a config object for checkpoint invalidation.\n * If config changes, the checkpoint will be invalidated and pipeline restarts.\n */\nexport function hashConfig(config: Record<string, unknown>): string {\n return createHash('md5').update(JSON.stringify(config)).digest('hex');\n}\n", "import type {\n CpOptions,\n FileContent,\n FsStat,\n IFileSystem,\n MkdirOptions,\n RmOptions,\n} from 'just-bash';\nimport * as path from 'node:path';\nimport { DatabaseSync } from 'node:sqlite';\n\nimport SQLITE_FS_DDL from './ddl.sqlite-fs.sql';\n\n// Types not exported from just-bash main index but defined in IFileSystem\ninterface ReadFileOptions {\n encoding?: BufferEncoding | null;\n}\n\ninterface WriteFileOptions {\n encoding?: BufferEncoding;\n}\n\ninterface DirentEntry {\n name: string;\n isFile: boolean;\n isDirectory: boolean;\n isSymbolicLink: boolean;\n}\n\n/**\n * Options for creating a SQLite filesystem.\n */\nexport interface SqliteFsOptions {\n /** Path to SQLite database file */\n dbPath: string;\n\n /**\n * Root path prefix for all operations (required).\n * All filesystem operations will be scoped under this path.\n * Use '/' for root-level storage without namespace isolation.\n *\n * @example\n * // With root: '/chat-123/results'\n * // writeFile('/file.json') \u2192 stores at '/chat-123/results/file.json'\n * // readFile('/file.json') \u2192 reads from '/chat-123/results/file.json'\n */\n root: string;\n\n /** Chunk size for large files in bytes (default: 1MB) */\n chunkSize?: number;\n}\n\ntype EntryType = 'file' | 'directory' | 'symlink';\n\ninterface FsEntryRow {\n path: string;\n type: EntryType;\n mode: number;\n size: number;\n mtime: number;\n symlinkTarget: string | null;\n}\n\ninterface ChunkRow {\n data: Uint8Array;\n}\n\n/**\n * SQLite-based filesystem implementing IFileSystem interface.\n *\n * Provides persistent storage for files and directories using SQLite.\n * Files are stored in chunks (default 1MB) to handle large files efficiently.\n *\n * Uses WAL mode and prepared statement caching for performance.\n */\nexport class SqliteFs implements IFileSystem {\n #db: DatabaseSync;\n #statements = new Map<string, ReturnType<DatabaseSync['prepare']>>();\n #chunkSize: number;\n #root: string;\n\n constructor(options: SqliteFsOptions) {\n this.#chunkSize = options.chunkSize ?? 1024 * 1024; // 1MB default\n // Normalize root; if user passes '/', treat as empty (root-level storage)\n const normalizedRoot = this.#normalizeRoot(options.root);\n this.#root = normalizedRoot === '/' ? '' : normalizedRoot;\n this.#db = new DatabaseSync(options.dbPath);\n this.#db.exec(SQLITE_FS_DDL);\n\n // Always ensure '/' exists first (for all instances sharing the DB)\n const rootSlashExists = this.#stmt(\n 'SELECT 1 FROM fs_entries WHERE path = ?',\n ).get('/');\n if (!rootSlashExists) {\n this.#stmt(\n `INSERT INTO fs_entries (path, type, mode, size, mtime)\n VALUES ('/', 'directory', 493, 0, ?)`,\n ).run(Date.now());\n }\n\n if (this.#root) {\n this.#createParentDirs(this.#root);\n\n const rootExists = this.#stmt(\n 'SELECT 1 FROM fs_entries WHERE path = ?',\n ).get(this.#root);\n if (!rootExists) {\n this.#stmt(\n `INSERT INTO fs_entries (path, type, mode, size, mtime)\n VALUES (?, 'directory', 493, 0, ?)`,\n ).run(this.#root, Date.now());\n }\n }\n }\n\n /**\n * Create parent directories for a path (used during initialization).\n * Creates all segments EXCEPT the last one (the path itself).\n */\n #createParentDirs(p: string): void {\n const segments = p.split('/').filter(Boolean);\n let currentPath = '/';\n\n for (let i = 0; i < segments.length - 1; i++) {\n currentPath = path.posix.join(currentPath, segments[i]);\n const exists = this.#stmt('SELECT 1 FROM fs_entries WHERE path = ?').get(\n currentPath,\n );\n\n if (!exists) {\n this.#stmt(\n `INSERT INTO fs_entries (path, type, mode, size, mtime)\n VALUES (?, 'directory', 493, 0, ?)`,\n ).run(currentPath, Date.now());\n }\n }\n }\n\n #stmt(sql: string): ReturnType<DatabaseSync['prepare']> {\n let stmt = this.#statements.get(sql);\n if (!stmt) {\n stmt = this.#db.prepare(sql);\n this.#statements.set(sql, stmt);\n }\n return stmt;\n }\n\n #normalizeRoot(root: string): string {\n return path.posix.resolve('/', root.trim());\n }\n\n #prefixPath(p: string): string {\n if (!this.#root) {\n return p;\n }\n // path.posix.join('/root', '/') incorrectly returns '/root/'\n if (p === '/') {\n return this.#root;\n }\n return path.posix.join(this.#root, p);\n }\n\n #unprefixPath(p: string): string {\n if (!this.#root) {\n return p;\n }\n if (p === this.#root) {\n return '/';\n }\n if (p.startsWith(this.#root + '/')) {\n return p.slice(this.#root.length) || '/';\n }\n // Should not happen unless a symlink escapes the configured root.\n // Return the best-effort canonical path to avoid breaking callers.\n return p;\n }\n\n #useTransaction<T>(fn: () => T): T {\n this.#db.exec('BEGIN TRANSACTION');\n try {\n const result = fn();\n this.#db.exec('COMMIT');\n return result;\n } catch (error) {\n this.#db.exec('ROLLBACK');\n throw error;\n }\n }\n\n #normalizePath(p: string): string {\n return path.posix.resolve('/', p);\n }\n\n #dirname(p: string): string {\n const dir = path.posix.dirname(p);\n return dir === '' ? '/' : dir;\n }\n\n #ensureParentExists(filePath: string): void {\n const parent = this.#dirname(filePath);\n const rootPath = this.#root || '/';\n if (parent === rootPath || parent === '/') return;\n\n const entry = this.#stmt('SELECT type FROM fs_entries WHERE path = ?').get(\n parent,\n ) as { type: string } | undefined;\n\n if (!entry) {\n this.#ensureParentExists(parent);\n this.#stmt(\n `INSERT INTO fs_entries (path, type, mode, size, mtime)\n VALUES (?, 'directory', 493, 0, ?)`,\n ).run(parent, Date.now());\n } else if (entry.type !== 'directory') {\n throw new Error(`mkdir: parent is not a directory: ${parent}`);\n }\n }\n\n #writeChunks(filePath: string, content: Uint8Array): void {\n this.#stmt('DELETE FROM fs_chunks WHERE path = ?').run(filePath);\n\n for (let i = 0; i < content.length; i += this.#chunkSize) {\n const chunk = content.slice(\n i,\n Math.min(i + this.#chunkSize, content.length),\n );\n this.#stmt(\n 'INSERT INTO fs_chunks (path, chunkIndex, data) VALUES (?, ?, ?)',\n ).run(filePath, Math.floor(i / this.#chunkSize), chunk);\n }\n }\n\n #readChunks(filePath: string): Uint8Array {\n const rows = this.#stmt(\n 'SELECT data FROM fs_chunks WHERE path = ? ORDER BY chunkIndex',\n ).all(filePath) as unknown as ChunkRow[];\n\n if (rows.length === 0) {\n return new Uint8Array(0);\n }\n\n const totalSize = rows.reduce((sum, row) => sum + row.data.length, 0);\n const result = new Uint8Array(totalSize);\n let offset = 0;\n\n for (const row of rows) {\n result.set(row.data, offset);\n offset += row.data.length;\n }\n\n return result;\n }\n\n #resolveSymlink(p: string, seen = new Set<string>()): string {\n if (seen.has(p)) {\n throw new Error(`readFile: circular symlink: ${p}`);\n }\n\n const entry = this.#stmt(\n 'SELECT type, symlinkTarget FROM fs_entries WHERE path = ?',\n ).get(p) as Pick<FsEntryRow, 'type' | 'symlinkTarget'> | undefined;\n\n if (!entry) {\n throw new Error(`ENOENT: no such file or directory: ${p}`);\n }\n\n if (entry.type !== 'symlink') {\n return p;\n }\n\n seen.add(p);\n const target = this.#normalizePath(\n path.posix.resolve(this.#dirname(p), entry.symlinkTarget!),\n );\n return this.#resolveSymlink(target, seen);\n }\n\n #toUint8Array(content: FileContent, encoding?: string): Uint8Array {\n if (content instanceof Uint8Array) {\n return content;\n }\n const enc = (encoding ?? 'utf8') as BufferEncoding;\n return new Uint8Array(Buffer.from(content, enc));\n }\n\n // ============================================================================\n // IFileSystem Implementation\n // ============================================================================\n\n async readFile(\n filePath: string,\n options?: ReadFileOptions | string,\n ): Promise<string> {\n const normalized = this.#normalizePath(filePath);\n const prefixed = this.#prefixPath(normalized);\n const resolved = this.#resolveSymlink(prefixed);\n\n const entry = this.#stmt('SELECT type FROM fs_entries WHERE path = ?').get(\n resolved,\n ) as Pick<FsEntryRow, 'type'> | undefined;\n\n if (!entry) {\n throw new Error(`ENOENT: no such file or directory: ${filePath}`);\n }\n if (entry.type === 'directory') {\n throw new Error(`EISDIR: illegal operation on a directory: ${filePath}`);\n }\n\n const content = this.#readChunks(resolved);\n const encoding =\n typeof options === 'string' ? options : (options?.encoding ?? 'utf8');\n return Buffer.from(content).toString(encoding as BufferEncoding);\n }\n\n async readFileBuffer(filePath: string): Promise<Uint8Array> {\n const normalized = this.#normalizePath(filePath);\n const prefixed = this.#prefixPath(normalized);\n const resolved = this.#resolveSymlink(prefixed);\n\n const entry = this.#stmt('SELECT type FROM fs_entries WHERE path = ?').get(\n resolved,\n ) as Pick<FsEntryRow, 'type'> | undefined;\n\n if (!entry) {\n throw new Error(`ENOENT: no such file or directory: ${filePath}`);\n }\n if (entry.type === 'directory') {\n throw new Error(`EISDIR: illegal operation on a directory: ${filePath}`);\n }\n\n return this.#readChunks(resolved);\n }\n\n async writeFile(\n filePath: string,\n content: FileContent,\n options?: WriteFileOptions | string,\n ): Promise<void> {\n const normalized = this.#normalizePath(filePath);\n const prefixed = this.#prefixPath(normalized);\n const encoding = typeof options === 'string' ? options : options?.encoding;\n const data = this.#toUint8Array(content, encoding);\n\n this.#useTransaction(() => {\n this.#ensureParentExists(prefixed);\n\n this.#stmt(\n `INSERT INTO fs_entries (path, type, mode, size, mtime)\n VALUES (?, 'file', 420, ?, ?)\n ON CONFLICT(path) DO UPDATE SET\n type = 'file',\n size = excluded.size,\n mtime = excluded.mtime`,\n ).run(prefixed, data.length, Date.now());\n\n this.#writeChunks(prefixed, data);\n });\n }\n\n async appendFile(\n filePath: string,\n content: FileContent,\n options?: WriteFileOptions | string,\n ): Promise<void> {\n const normalized = this.#normalizePath(filePath);\n const prefixed = this.#prefixPath(normalized);\n const encoding = typeof options === 'string' ? options : options?.encoding;\n const newData = this.#toUint8Array(content, encoding);\n\n this.#useTransaction(() => {\n this.#ensureParentExists(prefixed);\n\n const entry = this.#stmt(\n 'SELECT type FROM fs_entries WHERE path = ?',\n ).get(prefixed) as Pick<FsEntryRow, 'type'> | undefined;\n\n if (entry && entry.type !== 'file') {\n throw new Error(`appendFile: not a file: ${filePath}`);\n }\n\n const existing = entry ? this.#readChunks(prefixed) : new Uint8Array(0);\n const combined = new Uint8Array(existing.length + newData.length);\n combined.set(existing, 0);\n combined.set(newData, existing.length);\n\n this.#stmt(\n `INSERT INTO fs_entries (path, type, mode, size, mtime)\n VALUES (?, 'file', 420, ?, ?)\n ON CONFLICT(path) DO UPDATE SET\n size = excluded.size,\n mtime = excluded.mtime`,\n ).run(prefixed, combined.length, Date.now());\n\n this.#writeChunks(prefixed, combined);\n });\n }\n\n async exists(filePath: string): Promise<boolean> {\n const normalized = this.#normalizePath(filePath);\n const prefixed = this.#prefixPath(normalized);\n const row = this.#stmt('SELECT 1 FROM fs_entries WHERE path = ?').get(\n prefixed,\n );\n return row !== undefined;\n }\n\n async stat(filePath: string): Promise<FsStat> {\n const normalized = this.#normalizePath(filePath);\n const prefixed = this.#prefixPath(normalized);\n const resolved = this.#resolveSymlink(prefixed);\n\n const entry = this.#stmt('SELECT * FROM fs_entries WHERE path = ?').get(\n resolved,\n ) as FsEntryRow | undefined;\n\n if (!entry) {\n throw new Error(`ENOENT: no such file or directory: ${filePath}`);\n }\n\n return {\n isFile: entry.type === 'file',\n isDirectory: entry.type === 'directory',\n isSymbolicLink: false, // stat follows symlinks\n mode: entry.mode,\n size: entry.size,\n mtime: new Date(entry.mtime),\n };\n }\n\n async lstat(filePath: string): Promise<FsStat> {\n const normalized = this.#normalizePath(filePath);\n const prefixed = this.#prefixPath(normalized);\n\n const entry = this.#stmt('SELECT * FROM fs_entries WHERE path = ?').get(\n prefixed,\n ) as FsEntryRow | undefined;\n\n if (!entry) {\n throw new Error(`ENOENT: no such file or directory: ${filePath}`);\n }\n\n return {\n isFile: entry.type === 'file',\n isDirectory: entry.type === 'directory',\n isSymbolicLink: entry.type === 'symlink',\n mode: entry.mode,\n size: entry.size,\n mtime: new Date(entry.mtime),\n };\n }\n\n async mkdir(dirPath: string, options?: MkdirOptions): Promise<void> {\n const normalized = this.#normalizePath(dirPath);\n const prefixed = this.#prefixPath(normalized);\n\n const existing = this.#stmt(\n 'SELECT type FROM fs_entries WHERE path = ?',\n ).get(prefixed) as Pick<FsEntryRow, 'type'> | undefined;\n\n if (existing) {\n if (options?.recursive) {\n return; // Already exists, ok for recursive\n }\n throw new Error(`EEXIST: file already exists: ${dirPath}`);\n }\n\n this.#useTransaction(() => {\n if (options?.recursive) {\n const rootPath = this.#root || '/';\n const relativePath = path.posix.relative(rootPath, prefixed);\n const segments = relativePath.split('/').filter(Boolean);\n let currentPath = rootPath;\n\n for (const segment of segments) {\n currentPath = path.posix.join(currentPath, segment);\n const exists = this.#stmt(\n 'SELECT type FROM fs_entries WHERE path = ?',\n ).get(currentPath) as Pick<FsEntryRow, 'type'> | undefined;\n\n if (!exists) {\n this.#stmt(\n `INSERT INTO fs_entries (path, type, mode, size, mtime)\n VALUES (?, 'directory', 493, 0, ?)`,\n ).run(currentPath, Date.now());\n } else if (exists.type !== 'directory') {\n throw new Error(`mkdir: not a directory: ${currentPath}`);\n }\n }\n } else {\n // Non-recursive: parent must exist\n const parent = this.#dirname(prefixed);\n const parentEntry = this.#stmt(\n 'SELECT type FROM fs_entries WHERE path = ?',\n ).get(parent) as Pick<FsEntryRow, 'type'> | undefined;\n\n if (!parentEntry) {\n throw new Error(`mkdir: parent does not exist: ${parent}`);\n }\n if (parentEntry.type !== 'directory') {\n throw new Error(`mkdir: parent is not a directory: ${parent}`);\n }\n\n this.#stmt(\n `INSERT INTO fs_entries (path, type, mode, size, mtime)\n VALUES (?, 'directory', 493, 0, ?)`,\n ).run(prefixed, Date.now());\n }\n });\n }\n\n async readdir(dirPath: string): Promise<string[]> {\n const normalized = this.#normalizePath(dirPath);\n const prefixed = this.#prefixPath(normalized);\n const resolved = this.#resolveSymlink(prefixed);\n\n const entry = this.#stmt('SELECT type FROM fs_entries WHERE path = ?').get(\n resolved,\n ) as Pick<FsEntryRow, 'type'> | undefined;\n\n if (!entry) {\n throw new Error(`ENOENT: no such file or directory: ${dirPath}`);\n }\n if (entry.type !== 'directory') {\n throw new Error(`ENOTDIR: not a directory: ${dirPath}`);\n }\n\n // Get direct children (path starts with dir/ but doesn't have another / after)\n const prefix = resolved === '/' ? '/' : resolved + '/';\n const rows = this.#stmt(\n `SELECT path FROM fs_entries\n WHERE path LIKE ? || '%'\n AND path != ?\n AND path NOT LIKE ? || '%/%'`,\n ).all(prefix, resolved, prefix) as { path: string }[];\n\n return rows.map((row) => path.posix.basename(row.path));\n }\n\n async readdirWithFileTypes(dirPath: string): Promise<DirentEntry[]> {\n const normalized = this.#normalizePath(dirPath);\n const prefixed = this.#prefixPath(normalized);\n const resolved = this.#resolveSymlink(prefixed);\n\n const entry = this.#stmt('SELECT type FROM fs_entries WHERE path = ?').get(\n resolved,\n ) as Pick<FsEntryRow, 'type'> | undefined;\n\n if (!entry) {\n throw new Error(`ENOENT: no such file or directory: ${dirPath}`);\n }\n if (entry.type !== 'directory') {\n throw new Error(`ENOTDIR: not a directory: ${dirPath}`);\n }\n\n const prefix = resolved === '/' ? '/' : resolved + '/';\n const rows = this.#stmt(\n `SELECT path, type FROM fs_entries\n WHERE path LIKE ? || '%'\n AND path != ?\n AND path NOT LIKE ? || '%/%'`,\n ).all(prefix, resolved, prefix) as Pick<FsEntryRow, 'path' | 'type'>[];\n\n return rows.map((row) => ({\n name: path.posix.basename(row.path),\n isFile: row.type === 'file',\n isDirectory: row.type === 'directory',\n isSymbolicLink: row.type === 'symlink',\n }));\n }\n\n async rm(filePath: string, options?: RmOptions): Promise<void> {\n const normalized = this.#normalizePath(filePath);\n const prefixed = this.#prefixPath(normalized);\n\n const entry = this.#stmt('SELECT type FROM fs_entries WHERE path = ?').get(\n prefixed,\n ) as Pick<FsEntryRow, 'type'> | undefined;\n\n if (!entry) {\n if (options?.force) {\n return;\n }\n throw new Error(`ENOENT: no such file or directory: ${filePath}`);\n }\n\n this.#useTransaction(() => {\n if (entry.type === 'directory') {\n const children = this.#stmt(\n `SELECT 1 FROM fs_entries WHERE path LIKE ? || '/%' LIMIT 1`,\n ).get(prefixed);\n\n if (children && !options?.recursive) {\n throw new Error(`ENOTEMPTY: directory not empty: ${filePath}`);\n }\n\n // Chunks cascade via FK\n this.#stmt(\n `DELETE FROM fs_entries WHERE path = ? OR path LIKE ? || '/%'`,\n ).run(prefixed, prefixed);\n } else {\n this.#stmt('DELETE FROM fs_entries WHERE path = ?').run(prefixed);\n }\n });\n }\n\n async cp(src: string, dest: string, options?: CpOptions): Promise<void> {\n const srcNormalized = this.#normalizePath(src);\n const destNormalized = this.#normalizePath(dest);\n const srcPrefixed = this.#prefixPath(srcNormalized);\n const destPrefixed = this.#prefixPath(destNormalized);\n\n const srcEntry = this.#stmt('SELECT * FROM fs_entries WHERE path = ?').get(\n srcPrefixed,\n ) as FsEntryRow | undefined;\n\n if (!srcEntry) {\n throw new Error(`ENOENT: no such file or directory: ${src}`);\n }\n\n if (srcEntry.type === 'directory' && !options?.recursive) {\n throw new Error(`cp: -r not specified; omitting directory: ${src}`);\n }\n\n this.#useTransaction(() => {\n this.#ensureParentExists(destPrefixed);\n\n if (srcEntry.type === 'directory') {\n const allEntries = this.#stmt(\n `SELECT * FROM fs_entries WHERE path = ? OR path LIKE ? || '/%'`,\n ).all(srcPrefixed, srcPrefixed) as unknown as FsEntryRow[];\n\n for (const entry of allEntries) {\n const relativePath = path.posix.relative(srcPrefixed, entry.path);\n const newPath = path.posix.join(destPrefixed, relativePath);\n\n this.#stmt(\n `INSERT OR REPLACE INTO fs_entries (path, type, mode, size, mtime, symlinkTarget)\n VALUES (?, ?, ?, ?, ?, ?)`,\n ).run(\n newPath,\n entry.type,\n entry.mode,\n entry.size,\n Date.now(),\n entry.symlinkTarget,\n );\n\n if (entry.type === 'file') {\n const chunks = this.#stmt(\n 'SELECT chunkIndex, data FROM fs_chunks WHERE path = ?',\n ).all(entry.path) as { chunkIndex: number; data: Uint8Array }[];\n\n for (const chunk of chunks) {\n this.#stmt(\n 'INSERT INTO fs_chunks (path, chunkIndex, data) VALUES (?, ?, ?)',\n ).run(newPath, chunk.chunkIndex, chunk.data);\n }\n }\n }\n } else {\n this.#stmt(\n `INSERT OR REPLACE INTO fs_entries (path, type, mode, size, mtime, symlinkTarget)\n VALUES (?, ?, ?, ?, ?, ?)`,\n ).run(\n destPrefixed,\n srcEntry.type,\n srcEntry.mode,\n srcEntry.size,\n Date.now(),\n srcEntry.symlinkTarget,\n );\n\n if (srcEntry.type === 'file') {\n const chunks = this.#stmt(\n 'SELECT chunkIndex, data FROM fs_chunks WHERE path = ?',\n ).all(srcPrefixed) as { chunkIndex: number; data: Uint8Array }[];\n\n this.#stmt('DELETE FROM fs_chunks WHERE path = ?').run(destPrefixed);\n\n for (const chunk of chunks) {\n this.#stmt(\n 'INSERT INTO fs_chunks (path, chunkIndex, data) VALUES (?, ?, ?)',\n ).run(destPrefixed, chunk.chunkIndex, chunk.data);\n }\n }\n }\n });\n }\n\n async mv(src: string, dest: string): Promise<void> {\n const srcNormalized = this.#normalizePath(src);\n const destNormalized = this.#normalizePath(dest);\n const srcPrefixed = this.#prefixPath(srcNormalized);\n const destPrefixed = this.#prefixPath(destNormalized);\n\n const srcEntry = this.#stmt('SELECT * FROM fs_entries WHERE path = ?').get(\n srcPrefixed,\n ) as FsEntryRow | undefined;\n\n if (!srcEntry) {\n throw new Error(`ENOENT: no such file or directory: ${src}`);\n }\n\n this.#useTransaction(() => {\n this.#ensureParentExists(destPrefixed);\n\n if (srcEntry.type === 'directory') {\n // Reverse order: children before parents for delete\n const allEntries = this.#stmt(\n `SELECT * FROM fs_entries WHERE path = ? OR path LIKE ? || '/%' ORDER BY path DESC`,\n ).all(srcPrefixed, srcPrefixed) as unknown as FsEntryRow[];\n\n for (const entry of [...allEntries].reverse()) {\n const relativePath = path.posix.relative(srcPrefixed, entry.path);\n const newPath = path.posix.join(destPrefixed, relativePath);\n\n this.#stmt(\n `INSERT INTO fs_entries (path, type, mode, size, mtime, symlinkTarget)\n VALUES (?, ?, ?, ?, ?, ?)`,\n ).run(\n newPath,\n entry.type,\n entry.mode,\n entry.size,\n Date.now(),\n entry.symlinkTarget,\n );\n\n if (entry.type === 'file') {\n const chunks = this.#stmt(\n 'SELECT chunkIndex, data FROM fs_chunks WHERE path = ?',\n ).all(entry.path) as unknown as {\n chunkIndex: number;\n data: Uint8Array;\n }[];\n\n for (const chunk of chunks) {\n this.#stmt(\n 'INSERT INTO fs_chunks (path, chunkIndex, data) VALUES (?, ?, ?)',\n ).run(newPath, chunk.chunkIndex, chunk.data);\n }\n }\n }\n\n // Chunks cascade via FK\n this.#stmt(\n `DELETE FROM fs_entries WHERE path = ? OR path LIKE ? || '/%'`,\n ).run(srcPrefixed, srcPrefixed);\n } else {\n this.#stmt(\n `INSERT INTO fs_entries (path, type, mode, size, mtime, symlinkTarget)\n VALUES (?, ?, ?, ?, ?, ?)`,\n ).run(\n destPrefixed,\n srcEntry.type,\n srcEntry.mode,\n srcEntry.size,\n Date.now(),\n srcEntry.symlinkTarget,\n );\n\n if (srcEntry.type === 'file') {\n const chunks = this.#stmt(\n 'SELECT chunkIndex, data FROM fs_chunks WHERE path = ?',\n ).all(srcPrefixed) as unknown as {\n chunkIndex: number;\n data: Uint8Array;\n }[];\n\n for (const chunk of chunks) {\n this.#stmt(\n 'INSERT INTO fs_chunks (path, chunkIndex, data) VALUES (?, ?, ?)',\n ).run(destPrefixed, chunk.chunkIndex, chunk.data);\n }\n }\n\n this.#stmt('DELETE FROM fs_entries WHERE path = ?').run(srcPrefixed);\n }\n });\n }\n\n resolvePath(base: string, relativePath: string): string {\n return path.posix.resolve(base, relativePath);\n }\n\n getAllPaths(): string[] {\n const rows = this.#stmt(\n 'SELECT path FROM fs_entries ORDER BY path',\n ).all() as {\n path: string;\n }[];\n return rows.map((row) => row.path);\n }\n\n async realpath(filePath: string): Promise<string> {\n const normalized = this.#normalizePath(filePath);\n const prefixed = this.#prefixPath(normalized);\n const resolved = this.#resolveSymlink(prefixed);\n\n const exists = this.#stmt('SELECT 1 FROM fs_entries WHERE path = ?').get(\n resolved,\n );\n if (!exists) {\n throw new Error(`ENOENT: no such file or directory: ${filePath}`);\n }\n\n return this.#unprefixPath(resolved);\n }\n\n async utimes(filePath: string, _atime: Date, mtime: Date): Promise<void> {\n const normalized = this.#normalizePath(filePath);\n const prefixed = this.#prefixPath(normalized);\n const resolved = this.#resolveSymlink(prefixed);\n\n const result = this.#stmt(\n 'UPDATE fs_entries SET mtime = ? WHERE path = ?',\n ).run(mtime.getTime(), resolved);\n\n if (result.changes === 0) {\n throw new Error(`ENOENT: no such file or directory: ${filePath}`);\n }\n }\n\n async chmod(filePath: string, mode: number): Promise<void> {\n const normalized = this.#normalizePath(filePath);\n const prefixed = this.#prefixPath(normalized);\n\n const result = this.#stmt(\n 'UPDATE fs_entries SET mode = ? WHERE path = ?',\n ).run(mode, prefixed);\n\n if (result.changes === 0) {\n throw new Error(`ENOENT: no such file or directory: ${filePath}`);\n }\n }\n\n async symlink(target: string, linkPath: string): Promise<void> {\n const normalized = this.#normalizePath(linkPath);\n const prefixed = this.#prefixPath(normalized);\n\n const existing = this.#stmt('SELECT 1 FROM fs_entries WHERE path = ?').get(\n prefixed,\n );\n if (existing) {\n throw new Error(`EEXIST: file already exists: ${linkPath}`);\n }\n\n this.#useTransaction(() => {\n this.#ensureParentExists(prefixed);\n\n this.#stmt(\n `INSERT INTO fs_entries (path, type, mode, size, mtime, symlinkTarget)\n VALUES (?, 'symlink', 511, 0, ?, ?)`,\n ).run(prefixed, Date.now(), target);\n });\n }\n\n async link(existingPath: string, newPath: string): Promise<void> {\n const srcNormalized = this.#normalizePath(existingPath);\n const destNormalized = this.#normalizePath(newPath);\n const srcPrefixed = this.#prefixPath(srcNormalized);\n const destPrefixed = this.#prefixPath(destNormalized);\n\n const srcEntry = this.#stmt('SELECT * FROM fs_entries WHERE path = ?').get(\n srcPrefixed,\n ) as FsEntryRow | undefined;\n\n if (!srcEntry) {\n throw new Error(`ENOENT: no such file or directory: ${existingPath}`);\n }\n\n if (srcEntry.type !== 'file') {\n throw new Error(`link: not supported for directories: ${existingPath}`);\n }\n\n const existing = this.#stmt('SELECT 1 FROM fs_entries WHERE path = ?').get(\n destPrefixed,\n );\n if (existing) {\n throw new Error(`EEXIST: file already exists: ${newPath}`);\n }\n\n // Hard link: duplicate the entry and chunks\n this.#useTransaction(() => {\n this.#ensureParentExists(destPrefixed);\n\n this.#stmt(\n `INSERT INTO fs_entries (path, type, mode, size, mtime)\n VALUES (?, 'file', ?, ?, ?)`,\n ).run(destPrefixed, srcEntry.mode, srcEntry.size, Date.now());\n\n const chunks = this.#stmt(\n 'SELECT chunkIndex, data FROM fs_chunks WHERE path = ?',\n ).all(srcPrefixed) as { chunkIndex: number; data: Uint8Array }[];\n\n for (const chunk of chunks) {\n this.#stmt(\n 'INSERT INTO fs_chunks (path, chunkIndex, data) VALUES (?, ?, ?)',\n ).run(destPrefixed, chunk.chunkIndex, chunk.data);\n }\n });\n }\n\n async readlink(linkPath: string): Promise<string> {\n const normalized = this.#normalizePath(linkPath);\n const prefixed = this.#prefixPath(normalized);\n\n const entry = this.#stmt(\n 'SELECT type, symlinkTarget FROM fs_entries WHERE path = ?',\n ).get(prefixed) as Pick<FsEntryRow, 'type' | 'symlinkTarget'> | undefined;\n\n if (!entry) {\n throw new Error(`ENOENT: no such file or directory: ${linkPath}`);\n }\n\n if (entry.type !== 'symlink') {\n throw new Error(`readlink: not a symbolic link: ${linkPath}`);\n }\n\n return entry.symlinkTarget!;\n }\n}\n", "-- SQLite-based filesystem schema for artifact storage\n-- Tables: fs_entries (file/directory metadata), fs_chunks (file content)\n\n-- Performance PRAGMAs (session-level, run on each connection)\nPRAGMA journal_mode = WAL;\nPRAGMA synchronous = NORMAL;\nPRAGMA cache_size = -64000;\nPRAGMA temp_store = MEMORY;\nPRAGMA mmap_size = 268435456;\n\n-- Integrity\nPRAGMA foreign_keys = ON;\n\n-- Filesystem entries table (files, directories, symlinks)\nCREATE TABLE IF NOT EXISTS fs_entries (\n path TEXT PRIMARY KEY, -- Normalized absolute path (e.g., '/results/uuid.json')\n type TEXT NOT NULL, -- 'file' | 'directory' | 'symlink'\n mode INTEGER NOT NULL, -- Unix permissions (e.g., 0o644 = 420)\n size INTEGER NOT NULL, -- File size in bytes (0 for directories)\n mtime INTEGER NOT NULL, -- Modified time (milliseconds since epoch)\n symlinkTarget TEXT -- Target path for symlinks (NULL for files/dirs)\n);\n\nCREATE INDEX IF NOT EXISTS idx_fs_entries_type ON fs_entries(type);\n\n-- File content chunks table (for handling large files)\n-- Files are split into 1MB chunks to avoid SQLite BLOB performance issues\nCREATE TABLE IF NOT EXISTS fs_chunks (\n path TEXT NOT NULL, -- Reference to fs_entries.path\n chunkIndex INTEGER NOT NULL, -- 0-based chunk sequence\n data BLOB NOT NULL, -- Chunk content (up to 1MB default)\n PRIMARY KEY (path, chunkIndex),\n FOREIGN KEY (path) REFERENCES fs_entries(path) ON DELETE CASCADE ON UPDATE CASCADE\n);\n", "import type {\n CpOptions,\n FileContent,\n FsStat,\n IFileSystem,\n MkdirOptions,\n RmOptions,\n} from 'just-bash';\nimport type { ConnectionPool, Transaction, config } from 'mssql';\nimport { createRequire } from 'node:module';\nimport * as path from 'node:path';\n\nimport { mssqlFsDDL } from './ddl.mssql-fs.ts';\n\ninterface ReadFileOptions {\n encoding?: BufferEncoding | null;\n}\n\ninterface WriteFileOptions {\n encoding?: BufferEncoding;\n}\n\ninterface DirentEntry {\n name: string;\n isFile: boolean;\n isDirectory: boolean;\n isSymbolicLink: boolean;\n}\n\nexport interface MssqlFsOptions {\n /** SQL Server connection pool or configuration. Can be a connection string, config object, or existing ConnectionPool. */\n pool: config | string | ConnectionPool;\n /** Root path prefix for all operations */\n root: string;\n /** Chunk size for large files in bytes (default: 1MB) */\n chunkSize?: number;\n /**\n * SQL Server schema to scope all tables under.\n * Defaults to 'dbo'.\n */\n schema?: string;\n}\n\ntype EntryType = 'file' | 'directory' | 'symlink';\n\ninterface FsEntryRow {\n path: string;\n type: EntryType;\n mode: number;\n size: number;\n mtime: number;\n symlinkTarget: string | null;\n [key: string]: unknown;\n}\n\ninterface ChunkRow {\n data: Buffer;\n [key: string]: unknown;\n}\n\nexport class MssqlFs implements IFileSystem {\n #pool: ConnectionPool;\n #chunkSize: number;\n #root: string;\n #schema: string;\n #ownsPool: boolean;\n #isInitialized = false;\n\n constructor(options: MssqlFsOptions) {\n this.#chunkSize = options.chunkSize ?? 1024 * 1024;\n const schema = options.schema ?? 'dbo';\n if (!/^[a-zA-Z_]\\w*$/.test(schema)) {\n throw new Error(`Invalid schema name: \"${schema}\"`);\n }\n this.#schema = schema;\n const normalizedRoot = this.#normalizeRoot(options.root);\n this.#root = normalizedRoot === '/' ? '' : normalizedRoot;\n\n const mssql = MssqlFs.#requireMssql();\n if (options.pool instanceof mssql.ConnectionPool) {\n this.#pool = options.pool;\n this.#ownsPool = false;\n } else {\n this.#pool = new mssql.ConnectionPool(options.pool);\n this.#ownsPool = true;\n }\n }\n\n static #requireMssql(): typeof import('mssql') {\n try {\n const require = createRequire(import.meta.url);\n return require('mssql');\n } catch {\n throw new Error(\n 'MssqlFs requires the \"mssql\" package. Install it with: npm install mssql',\n );\n }\n }\n\n #t(name: string): string {\n return `[${this.#schema}].[${name}]`;\n }\n\n async initialize(): Promise<void> {\n if (this.#ownsPool) {\n await this.#pool.connect();\n }\n\n const schemaReq = this.#pool.request();\n schemaReq.input('schema', this.#schema);\n await schemaReq.query(`\n IF NOT EXISTS (SELECT * FROM sys.schemas WHERE name = @schema)\n BEGIN\n DECLARE @sql NVARCHAR(MAX) = N'CREATE SCHEMA ' + QUOTENAME(@schema);\n EXEC sp_executesql @sql;\n END\n `);\n\n const ddl = mssqlFsDDL(this.#schema);\n const batches = ddl.split(/\\bGO\\b/i).filter((b) => b.trim());\n for (const batch of batches) {\n if (batch.trim()) {\n await this.#pool.request().batch(batch);\n }\n }\n\n const rootSlashExists = await this.#rawQuery<{ exists: number }>(\n `SELECT CASE WHEN EXISTS(SELECT 1 FROM ${this.#t('fs_entries')} WHERE path = '/') THEN 1 ELSE 0 END as [exists]`,\n );\n if (rootSlashExists[0].exists === 0) {\n await this.#rawExec(\n `INSERT INTO ${this.#t('fs_entries')} (path, type, mode, size, mtime) VALUES ('/', 'directory', 493, 0, @p0)`,\n [Date.now()],\n );\n }\n\n if (this.#root) {\n await this.#createParentDirs(this.#root);\n\n const rootExists = await this.#rawQuery<{ exists: number }>(\n `SELECT CASE WHEN EXISTS(SELECT 1 FROM ${this.#t('fs_entries')} WHERE path = @p0) THEN 1 ELSE 0 END as [exists]`,\n [this.#root],\n );\n if (rootExists[0].exists === 0) {\n await this.#rawExec(\n `INSERT INTO ${this.#t('fs_entries')} (path, type, mode, size, mtime) VALUES (@p0, 'directory', 493, 0, @p1)`,\n [this.#root, Date.now()],\n );\n }\n }\n\n this.#isInitialized = true;\n }\n\n #ensureInitialized(): void {\n if (!this.#isInitialized) {\n throw new Error(\n 'MssqlFs not initialized. Call await fs.initialize() after construction.',\n );\n }\n }\n\n async #createParentDirs(p: string): Promise<void> {\n const segments = p.split('/').filter(Boolean);\n let currentPath = '/';\n\n for (let i = 0; i < segments.length - 1; i++) {\n currentPath = path.posix.join(currentPath, segments[i]);\n const exists = await this.#rawQuery<{ exists: number }>(\n `SELECT CASE WHEN EXISTS(SELECT 1 FROM ${this.#t('fs_entries')} WHERE path = @p0) THEN 1 ELSE 0 END as [exists]`,\n [currentPath],\n );\n\n if (exists[0].exists === 0) {\n await this.#rawExec(\n `INSERT INTO ${this.#t('fs_entries')} (path, type, mode, size, mtime) VALUES (@p0, 'directory', 493, 0, @p1)`,\n [currentPath, Date.now()],\n );\n }\n }\n }\n\n async #rawQuery<T extends Record<string, unknown>>(\n sql: string,\n params?: unknown[],\n ): Promise<T[]> {\n const request = this.#pool.request();\n params?.forEach((value, index) => {\n request.input(`p${index}`, value);\n });\n const result = await request.query(sql);\n return result.recordset as T[];\n }\n\n async #rawExec(sql: string, params?: unknown[]): Promise<number> {\n const request = this.#pool.request();\n params?.forEach((value, index) => {\n request.input(`p${index}`, value);\n });\n const result = await request.query(sql);\n return result.rowsAffected[0] ?? 0;\n }\n\n async #query<T extends Record<string, unknown>>(\n sql: string,\n params?: unknown[],\n ): Promise<T[]> {\n this.#ensureInitialized();\n return this.#rawQuery<T>(sql, params);\n }\n\n async #exec(sql: string, params?: unknown[]): Promise<number> {\n this.#ensureInitialized();\n return this.#rawExec(sql, params);\n }\n\n async #useTransaction<T>(\n fn: (transaction: Transaction) => Promise<T>,\n ): Promise<T> {\n this.#ensureInitialized();\n const mssql = MssqlFs.#requireMssql();\n const transaction = new mssql.Transaction(this.#pool);\n try {\n await transaction.begin();\n const result = await fn(transaction);\n await transaction.commit();\n return result;\n } catch (error) {\n await transaction.rollback();\n throw error;\n }\n }\n\n #normalizeRoot(root: string): string {\n return path.posix.resolve('/', root.trim());\n }\n\n #prefixPath(p: string): string {\n if (!this.#root) {\n return p;\n }\n if (p === '/') {\n return this.#root;\n }\n return path.posix.join(this.#root, p);\n }\n\n #unprefixPath(p: string): string {\n if (!this.#root) {\n return p;\n }\n if (p === this.#root) {\n return '/';\n }\n if (p.startsWith(this.#root + '/')) {\n return p.slice(this.#root.length) || '/';\n }\n // Should not happen unless a symlink escapes the configured root.\n // Return the best-effort canonical path to avoid breaking callers.\n return p;\n }\n\n #normalizePath(p: string): string {\n return path.posix.resolve('/', p);\n }\n\n #dirname(p: string): string {\n const dir = path.posix.dirname(p);\n return dir === '' ? '/' : dir;\n }\n\n async #ensureParentExists(\n filePath: string,\n transaction: Transaction,\n ): Promise<void> {\n const parent = this.#dirname(filePath);\n const rootPath = this.#root || '/';\n if (parent === rootPath || parent === '/') return;\n\n const request = transaction.request();\n request.input('p0', parent);\n const result = await request.query<{ type: string }>(\n `SELECT type FROM ${this.#t('fs_entries')} WHERE path = @p0`,\n );\n const entry = result.recordset[0];\n\n if (!entry) {\n await this.#ensureParentExists(parent, transaction);\n const insertReq = transaction.request();\n insertReq.input('p0', parent);\n insertReq.input('p1', Date.now());\n await insertReq.query(\n `INSERT INTO ${this.#t('fs_entries')} (path, type, mode, size, mtime) VALUES (@p0, 'directory', 493, 0, @p1)`,\n );\n } else if (entry.type !== 'directory') {\n throw new Error(`mkdir: parent is not a directory: ${parent}`);\n }\n }\n\n async #writeChunks(\n filePath: string,\n content: Uint8Array,\n transaction: Transaction,\n ): Promise<void> {\n const deleteReq = transaction.request();\n deleteReq.input('p0', filePath);\n await deleteReq.query(\n `DELETE FROM ${this.#t('fs_chunks')} WHERE path = @p0`,\n );\n\n for (let i = 0; i < content.length; i += this.#chunkSize) {\n const chunk = content.slice(\n i,\n Math.min(i + this.#chunkSize, content.length),\n );\n const insertReq = transaction.request();\n insertReq.input('p0', filePath);\n insertReq.input('p1', Math.floor(i / this.#chunkSize));\n insertReq.input('p2', Buffer.from(chunk));\n await insertReq.query(\n `INSERT INTO ${this.#t('fs_chunks')} (path, chunkIndex, data) VALUES (@p0, @p1, @p2)`,\n );\n }\n }\n\n async #readChunks(\n filePath: string,\n transaction?: Transaction,\n ): Promise<Uint8Array> {\n let rows: ChunkRow[];\n if (transaction) {\n const req = transaction.request();\n req.input('p0', filePath);\n const result = await req.query<ChunkRow>(\n `SELECT data FROM ${this.#t('fs_chunks')} WHERE path = @p0 ORDER BY chunkIndex`,\n );\n rows = result.recordset as ChunkRow[];\n } else {\n rows = await this.#query<ChunkRow>(\n `SELECT data FROM ${this.#t('fs_chunks')} WHERE path = @p0 ORDER BY chunkIndex`,\n [filePath],\n );\n }\n\n if (rows.length === 0) {\n return new Uint8Array(0);\n }\n\n const totalSize = rows.reduce((sum, row) => sum + row.data.length, 0);\n const result = new Uint8Array(totalSize);\n let offset = 0;\n\n for (const row of rows) {\n result.set(new Uint8Array(row.data), offset);\n offset += row.data.length;\n }\n\n return result;\n }\n\n async #resolveSymlink(p: string, seen = new Set<string>()): Promise<string> {\n if (seen.has(p)) {\n throw new Error(`readFile: circular symlink: ${p}`);\n }\n\n const rows = await this.#query<Pick<FsEntryRow, 'type' | 'symlinkTarget'>>(\n `SELECT type, symlinkTarget FROM ${this.#t('fs_entries')} WHERE path = @p0`,\n [p],\n );\n const entry = rows[0];\n\n if (!entry) {\n throw new Error(`ENOENT: no such file or directory: ${p}`);\n }\n\n if (entry.type !== 'symlink') {\n return p;\n }\n\n seen.add(p);\n const target = this.#normalizePath(\n path.posix.resolve(this.#dirname(p), entry.symlinkTarget!),\n );\n return this.#resolveSymlink(target, seen);\n }\n\n #toUint8Array(content: FileContent, encoding?: string): Uint8Array {\n if (content instanceof Uint8Array) {\n return content;\n }\n const enc = (encoding ?? 'utf8') as BufferEncoding;\n return new Uint8Array(Buffer.from(content, enc));\n }\n\n async close(): Promise<void> {\n if (this.#ownsPool) {\n await this.#pool.close();\n }\n }\n\n // ============================================================================\n // IFileSystem Implementation\n // ============================================================================\n\n async readFile(\n filePath: string,\n options?: ReadFileOptions | string,\n ): Promise<string> {\n const normalized = this.#normalizePath(filePath);\n const prefixed = this.#prefixPath(normalized);\n const resolved = await this.#resolveSymlink(prefixed);\n\n const rows = await this.#query<Pick<FsEntryRow, 'type'>>(\n `SELECT type FROM ${this.#t('fs_entries')} WHERE path = @p0`,\n [resolved],\n );\n const entry = rows[0];\n\n if (!entry) {\n throw new Error(`ENOENT: no such file or directory: ${filePath}`);\n }\n if (entry.type === 'directory') {\n throw new Error(`EISDIR: illegal operation on a directory: ${filePath}`);\n }\n\n const content = await this.#readChunks(resolved);\n const encoding =\n typeof options === 'string' ? options : (options?.encoding ?? 'utf8');\n return Buffer.from(content).toString(encoding as BufferEncoding);\n }\n\n async readFileBuffer(filePath: string): Promise<Uint8Array> {\n const normalized = this.#normalizePath(filePath);\n const prefixed = this.#prefixPath(normalized);\n const resolved = await this.#resolveSymlink(prefixed);\n\n const rows = await this.#query<Pick<FsEntryRow, 'type'>>(\n `SELECT type FROM ${this.#t('fs_entries')} WHERE path = @p0`,\n [resolved],\n );\n const entry = rows[0];\n\n if (!entry) {\n throw new Error(`ENOENT: no such file or directory: ${filePath}`);\n }\n if (entry.type === 'directory') {\n throw new Error(`EISDIR: illegal operation on a directory: ${filePath}`);\n }\n\n return this.#readChunks(resolved);\n }\n\n async writeFile(\n filePath: string,\n content: FileContent,\n options?: WriteFileOptions | string,\n ): Promise<void> {\n const normalized = this.#normalizePath(filePath);\n const prefixed = this.#prefixPath(normalized);\n const encoding = typeof options === 'string' ? options : options?.encoding;\n const data = this.#toUint8Array(content, encoding);\n\n await this.#useTransaction(async (transaction) => {\n await this.#ensureParentExists(prefixed, transaction);\n\n const request = transaction.request();\n request.input('p0', prefixed);\n request.input('p1', data.length);\n request.input('p2', Date.now());\n\n await request.query(`\n MERGE ${this.#t('fs_entries')} AS target\n USING (SELECT @p0 AS path) AS source\n ON target.path = source.path\n WHEN MATCHED THEN\n UPDATE SET type = 'file', size = @p1, mtime = @p2\n WHEN NOT MATCHED THEN\n INSERT (path, type, mode, size, mtime)\n VALUES (@p0, 'file', 420, @p1, @p2);\n `);\n\n await this.#writeChunks(prefixed, data, transaction);\n });\n }\n\n async appendFile(\n filePath: string,\n content: FileContent,\n options?: WriteFileOptions | string,\n ): Promise<void> {\n const normalized = this.#normalizePath(filePath);\n const prefixed = this.#prefixPath(normalized);\n const encoding = typeof options === 'string' ? options : options?.encoding;\n const newData = this.#toUint8Array(content, encoding);\n\n await this.#useTransaction(async (transaction) => {\n await this.#ensureParentExists(prefixed, transaction);\n\n const checkReq = transaction.request();\n checkReq.input('p0', prefixed);\n const result = await checkReq.query<Pick<FsEntryRow, 'type'>>(\n `SELECT type FROM ${this.#t('fs_entries')} WHERE path = @p0`,\n );\n const entry = result.recordset[0];\n\n if (entry && entry.type !== 'file') {\n throw new Error(`appendFile: not a file: ${filePath}`);\n }\n\n const existing = entry\n ? await this.#readChunks(prefixed, transaction)\n : new Uint8Array(0);\n const combined = new Uint8Array(existing.length + newData.length);\n combined.set(existing, 0);\n combined.set(newData, existing.length);\n\n const upsertReq = transaction.request();\n upsertReq.input('p0', prefixed);\n upsertReq.input('p1', combined.length);\n upsertReq.input('p2', Date.now());\n\n await upsertReq.query(`\n MERGE ${this.#t('fs_entries')} AS target\n USING (SELECT @p0 AS path) AS source\n ON target.path = source.path\n WHEN MATCHED THEN\n UPDATE SET size = @p1, mtime = @p2\n WHEN NOT MATCHED THEN\n INSERT (path, type, mode, size, mtime)\n VALUES (@p0, 'file', 420, @p1, @p2);\n `);\n\n await this.#writeChunks(prefixed, combined, transaction);\n });\n }\n\n async exists(filePath: string): Promise<boolean> {\n const normalized = this.#normalizePath(filePath);\n const prefixed = this.#prefixPath(normalized);\n const rows = await this.#query<{ exists: number }>(\n `SELECT CASE WHEN EXISTS(SELECT 1 FROM ${this.#t('fs_entries')} WHERE path = @p0) THEN 1 ELSE 0 END as [exists]`,\n [prefixed],\n );\n return rows[0].exists === 1;\n }\n\n async stat(filePath: string): Promise<FsStat> {\n const normalized = this.#normalizePath(filePath);\n const prefixed = this.#prefixPath(normalized);\n const resolved = await this.#resolveSymlink(prefixed);\n\n const rows = await this.#query<FsEntryRow>(\n `SELECT * FROM ${this.#t('fs_entries')} WHERE path = @p0`,\n [resolved],\n );\n const entry = rows[0];\n\n if (!entry) {\n throw new Error(`ENOENT: no such file or directory: ${filePath}`);\n }\n\n return {\n isFile: entry.type === 'file',\n isDirectory: entry.type === 'directory',\n isSymbolicLink: false,\n mode: Number(entry.mode),\n size: Number(entry.size),\n mtime: new Date(Number(entry.mtime)),\n };\n }\n\n async lstat(filePath: string): Promise<FsStat> {\n const normalized = this.#normalizePath(filePath);\n const prefixed = this.#prefixPath(normalized);\n\n const rows = await this.#query<FsEntryRow>(\n `SELECT * FROM ${this.#t('fs_entries')} WHERE path = @p0`,\n [prefixed],\n );\n const entry = rows[0];\n\n if (!entry) {\n throw new Error(`ENOENT: no such file or directory: ${filePath}`);\n }\n\n return {\n isFile: entry.type === 'file',\n isDirectory: entry.type === 'directory',\n isSymbolicLink: entry.type === 'symlink',\n mode: Number(entry.mode),\n size: Number(entry.size),\n mtime: new Date(Number(entry.mtime)),\n };\n }\n\n async mkdir(dirPath: string, options?: MkdirOptions): Promise<void> {\n const normalized = this.#normalizePath(dirPath);\n const prefixed = this.#prefixPath(normalized);\n\n const existingRows = await this.#query<Pick<FsEntryRow, 'type'>>(\n `SELECT type FROM ${this.#t('fs_entries')} WHERE path = @p0`,\n [prefixed],\n );\n const existing = existingRows[0];\n\n if (existing) {\n if (options?.recursive) {\n return;\n }\n throw new Error(`EEXIST: file already exists: ${dirPath}`);\n }\n\n await this.#useTransaction(async (transaction) => {\n if (options?.recursive) {\n const rootPath = this.#root || '/';\n const relativePath = path.posix.relative(rootPath, prefixed);\n const segments = relativePath.split('/').filter(Boolean);\n let currentPath = rootPath;\n\n for (const segment of segments) {\n currentPath = path.posix.join(currentPath, segment);\n const checkReq = transaction.request();\n checkReq.input('p0', currentPath);\n const result = await checkReq.query<Pick<FsEntryRow, 'type'>>(\n `SELECT type FROM ${this.#t('fs_entries')} WHERE path = @p0`,\n );\n const exists = result.recordset[0];\n\n if (!exists) {\n const insertReq = transaction.request();\n insertReq.input('p0', currentPath);\n insertReq.input('p1', Date.now());\n await insertReq.query(\n `INSERT INTO ${this.#t('fs_entries')} (path, type, mode, size, mtime) VALUES (@p0, 'directory', 493, 0, @p1)`,\n );\n } else if (exists.type !== 'directory') {\n throw new Error(`mkdir: not a directory: ${currentPath}`);\n }\n }\n } else {\n const parent = this.#dirname(prefixed);\n const parentReq = transaction.request();\n parentReq.input('p0', parent);\n const parentResult = await parentReq.query<Pick<FsEntryRow, 'type'>>(\n `SELECT type FROM ${this.#t('fs_entries')} WHERE path = @p0`,\n );\n const parentEntry = parentResult.recordset[0];\n\n if (!parentEntry) {\n throw new Error(`mkdir: parent does not exist: ${parent}`);\n }\n if (parentEntry.type !== 'directory') {\n throw new Error(`mkdir: parent is not a directory: ${parent}`);\n }\n\n const insertReq = transaction.request();\n insertReq.input('p0', prefixed);\n insertReq.input('p1', Date.now());\n await insertReq.query(\n `INSERT INTO ${this.#t('fs_entries')} (path, type, mode, size, mtime) VALUES (@p0, 'directory', 493, 0, @p1)`,\n );\n }\n });\n }\n\n async readdir(dirPath: string): Promise<string[]> {\n const normalized = this.#normalizePath(dirPath);\n const prefixed = this.#prefixPath(normalized);\n const resolved = await this.#resolveSymlink(prefixed);\n\n const entryRows = await this.#query<Pick<FsEntryRow, 'type'>>(\n `SELECT type FROM ${this.#t('fs_entries')} WHERE path = @p0`,\n [resolved],\n );\n const entry = entryRows[0];\n\n if (!entry) {\n throw new Error(`ENOENT: no such file or directory: ${dirPath}`);\n }\n if (entry.type !== 'directory') {\n throw new Error(`ENOTDIR: not a directory: ${dirPath}`);\n }\n\n const prefix = resolved === '/' ? '/' : resolved + '/';\n const rows = await this.#query<{ path: string }>(\n `SELECT path FROM ${this.#t('fs_entries')}\n WHERE path LIKE @p0 + '%'\n AND path != @p1\n AND path NOT LIKE @p0 + '%/%'`,\n [prefix, resolved],\n );\n\n return rows.map((row) => path.posix.basename(row.path));\n }\n\n async readdirWithFileTypes(dirPath: string): Promise<DirentEntry[]> {\n const normalized = this.#normalizePath(dirPath);\n const prefixed = this.#prefixPath(normalized);\n const resolved = await this.#resolveSymlink(prefixed);\n\n const entryRows = await this.#query<Pick<FsEntryRow, 'type'>>(\n `SELECT type FROM ${this.#t('fs_entries')} WHERE path = @p0`,\n [resolved],\n );\n const entry = entryRows[0];\n\n if (!entry) {\n throw new Error(`ENOENT: no such file or directory: ${dirPath}`);\n }\n if (entry.type !== 'directory') {\n throw new Error(`ENOTDIR: not a directory: ${dirPath}`);\n }\n\n const prefix = resolved === '/' ? '/' : resolved + '/';\n const rows = await this.#query<Pick<FsEntryRow, 'path' | 'type'>>(\n `SELECT path, type FROM ${this.#t('fs_entries')}\n WHERE path LIKE @p0 + '%'\n AND path != @p1\n AND path NOT LIKE @p0 + '%/%'`,\n [prefix, resolved],\n );\n\n return rows.map((row) => ({\n name: path.posix.basename(row.path),\n isFile: row.type === 'file',\n isDirectory: row.type === 'directory',\n isSymbolicLink: row.type === 'symlink',\n }));\n }\n\n async rm(filePath: string, options?: RmOptions): Promise<void> {\n const normalized = this.#normalizePath(filePath);\n const prefixed = this.#prefixPath(normalized);\n\n const rows = await this.#query<Pick<FsEntryRow, 'type'>>(\n `SELECT type FROM ${this.#t('fs_entries')} WHERE path = @p0`,\n [prefixed],\n );\n const entry = rows[0];\n\n if (!entry) {\n if (options?.force) {\n return;\n }\n throw new Error(`ENOENT: no such file or directory: ${filePath}`);\n }\n\n await this.#useTransaction(async (transaction) => {\n if (entry.type === 'directory') {\n const childrenReq = transaction.request();\n childrenReq.input('p0', prefixed);\n const childrenResult = await childrenReq.query<{ exists: number }>(\n `SELECT CASE WHEN EXISTS(SELECT 1 FROM ${this.#t('fs_entries')} WHERE path LIKE @p0 + '/%') THEN 1 ELSE 0 END as [exists]`,\n );\n\n if (childrenResult.recordset[0].exists === 1 && !options?.recursive) {\n throw new Error(`ENOTEMPTY: directory not empty: ${filePath}`);\n }\n\n const deleteReq = transaction.request();\n deleteReq.input('p0', prefixed);\n await deleteReq.query(\n `DELETE FROM ${this.#t('fs_entries')} WHERE path = @p0 OR path LIKE @p0 + '/%'`,\n );\n } else {\n const deleteReq = transaction.request();\n deleteReq.input('p0', prefixed);\n await deleteReq.query(\n `DELETE FROM ${this.#t('fs_entries')} WHERE path = @p0`,\n );\n }\n });\n }\n\n async cp(src: string, dest: string, options?: CpOptions): Promise<void> {\n const srcNormalized = this.#normalizePath(src);\n const destNormalized = this.#normalizePath(dest);\n const srcPrefixed = this.#prefixPath(srcNormalized);\n const destPrefixed = this.#prefixPath(destNormalized);\n\n const srcRows = await this.#query<FsEntryRow>(\n `SELECT * FROM ${this.#t('fs_entries')} WHERE path = @p0`,\n [srcPrefixed],\n );\n const srcEntry = srcRows[0];\n\n if (!srcEntry) {\n throw new Error(`ENOENT: no such file or directory: ${src}`);\n }\n\n if (srcEntry.type === 'directory' && !options?.recursive) {\n throw new Error(`cp: -r not specified; omitting directory: ${src}`);\n }\n\n await this.#useTransaction(async (transaction) => {\n await this.#ensureParentExists(destPrefixed, transaction);\n\n if (srcEntry.type === 'directory') {\n const allEntriesReq = transaction.request();\n allEntriesReq.input('p0', srcPrefixed);\n const allEntriesResult = await allEntriesReq.query<FsEntryRow>(\n `SELECT * FROM ${this.#t('fs_entries')} WHERE path = @p0 OR path LIKE @p0 + '/%'`,\n );\n\n for (const entry of allEntriesResult.recordset) {\n const relativePath = path.posix.relative(srcPrefixed, entry.path);\n const newPath = path.posix.join(destPrefixed, relativePath);\n\n const insertReq = transaction.request();\n insertReq.input('p0', newPath);\n insertReq.input('p1', entry.type);\n insertReq.input('p2', entry.mode);\n insertReq.input('p3', entry.size);\n insertReq.input('p4', Date.now());\n insertReq.input('p5', entry.symlinkTarget);\n\n await insertReq.query(`\n MERGE ${this.#t('fs_entries')} AS target\n USING (SELECT @p0 AS path) AS source\n ON target.path = source.path\n WHEN MATCHED THEN\n UPDATE SET type = @p1, mode = @p2, size = @p3, mtime = @p4, symlinkTarget = @p5\n WHEN NOT MATCHED THEN\n INSERT (path, type, mode, size, mtime, symlinkTarget)\n VALUES (@p0, @p1, @p2, @p3, @p4, @p5);\n `);\n\n if (entry.type === 'file') {\n const deleteChunksReq = transaction.request();\n deleteChunksReq.input('p0', newPath);\n await deleteChunksReq.query(\n `DELETE FROM ${this.#t('fs_chunks')} WHERE path = @p0`,\n );\n\n const chunksReq = transaction.request();\n chunksReq.input('p0', entry.path);\n const chunksResult = await chunksReq.query<{\n chunkIndex: number;\n data: Buffer;\n }>(\n `SELECT chunkIndex, data FROM ${this.#t('fs_chunks')} WHERE path = @p0`,\n );\n\n for (const chunk of chunksResult.recordset) {\n const chunkInsertReq = transaction.request();\n chunkInsertReq.input('p0', newPath);\n chunkInsertReq.input('p1', chunk.chunkIndex);\n chunkInsertReq.input('p2', chunk.data);\n await chunkInsertReq.query(\n `INSERT INTO ${this.#t('fs_chunks')} (path, chunkIndex, data) VALUES (@p0, @p1, @p2)`,\n );\n }\n }\n }\n } else {\n const insertReq = transaction.request();\n insertReq.input('p0', destPrefixed);\n insertReq.input('p1', srcEntry.type);\n insertReq.input('p2', srcEntry.mode);\n insertReq.input('p3', srcEntry.size);\n insertReq.input('p4', Date.now());\n insertReq.input('p5', srcEntry.symlinkTarget);\n\n await insertReq.query(`\n MERGE ${this.#t('fs_entries')} AS target\n USING (SELECT @p0 AS path) AS source\n ON target.path = source.path\n WHEN MATCHED THEN\n UPDATE SET type = @p1, mode = @p2, size = @p3, mtime = @p4, symlinkTarget = @p5\n WHEN NOT MATCHED THEN\n INSERT (path, type, mode, size, mtime, symlinkTarget)\n VALUES (@p0, @p1, @p2, @p3, @p4, @p5);\n `);\n\n if (srcEntry.type === 'file') {\n const chunksReq = transaction.request();\n chunksReq.input('p0', srcPrefixed);\n const chunksResult = await chunksReq.query<{\n chunkIndex: number;\n data: Buffer;\n }>(\n `SELECT chunkIndex, data FROM ${this.#t('fs_chunks')} WHERE path = @p0`,\n );\n\n const deleteChunksReq = transaction.request();\n deleteChunksReq.input('p0', destPrefixed);\n await deleteChunksReq.query(\n `DELETE FROM ${this.#t('fs_chunks')} WHERE path = @p0`,\n );\n\n for (const chunk of chunksResult.recordset) {\n const chunkInsertReq = transaction.request();\n chunkInsertReq.input('p0', destPrefixed);\n chunkInsertReq.input('p1', chunk.chunkIndex);\n chunkInsertReq.input('p2', chunk.data);\n await chunkInsertReq.query(\n `INSERT INTO ${this.#t('fs_chunks')} (path, chunkIndex, data) VALUES (@p0, @p1, @p2)`,\n );\n }\n }\n }\n });\n }\n\n async mv(src: string, dest: string): Promise<void> {\n const srcNormalized = this.#normalizePath(src);\n const destNormalized = this.#normalizePath(dest);\n const srcPrefixed = this.#prefixPath(srcNormalized);\n const destPrefixed = this.#prefixPath(destNormalized);\n\n const srcRows = await this.#query<FsEntryRow>(\n `SELECT * FROM ${this.#t('fs_entries')} WHERE path = @p0`,\n [srcPrefixed],\n );\n const srcEntry = srcRows[0];\n\n if (!srcEntry) {\n throw new Error(`ENOENT: no such file or directory: ${src}`);\n }\n\n await this.#useTransaction(async (transaction) => {\n await this.#ensureParentExists(destPrefixed, transaction);\n\n if (srcEntry.type === 'directory') {\n const allEntriesReq = transaction.request();\n allEntriesReq.input('p0', srcPrefixed);\n const allEntriesResult = await allEntriesReq.query<FsEntryRow>(\n `SELECT * FROM ${this.#t('fs_entries')} WHERE path = @p0 OR path LIKE @p0 + '/%' ORDER BY path DESC`,\n );\n\n const destDeleteReq = transaction.request();\n destDeleteReq.input('dp0', destPrefixed);\n await destDeleteReq.query(\n `DELETE FROM ${this.#t('fs_entries')} WHERE path = @dp0 OR path LIKE @dp0 + '/%'`,\n );\n\n for (const entry of [...allEntriesResult.recordset].reverse()) {\n const relativePath = path.posix.relative(srcPrefixed, entry.path);\n const newPath = path.posix.join(destPrefixed, relativePath);\n\n const insertReq = transaction.request();\n insertReq.input('p0', newPath);\n insertReq.input('p1', entry.type);\n insertReq.input('p2', entry.mode);\n insertReq.input('p3', entry.size);\n insertReq.input('p4', Date.now());\n insertReq.input('p5', entry.symlinkTarget);\n\n await insertReq.query(`\n MERGE ${this.#t('fs_entries')} AS target\n USING (SELECT @p0 AS path) AS source\n ON target.path = source.path\n WHEN MATCHED THEN\n UPDATE SET type = @p1, mode = @p2, size = @p3, mtime = @p4, symlinkTarget = @p5\n WHEN NOT MATCHED THEN\n INSERT (path, type, mode, size, mtime, symlinkTarget)\n VALUES (@p0, @p1, @p2, @p3, @p4, @p5);\n `);\n\n if (entry.type === 'file') {\n const deleteChunksReq = transaction.request();\n deleteChunksReq.input('p0', newPath);\n await deleteChunksReq.query(\n `DELETE FROM ${this.#t('fs_chunks')} WHERE path = @p0`,\n );\n\n const chunksReq = transaction.request();\n chunksReq.input('p0', entry.path);\n const chunksResult = await chunksReq.query<{\n chunkIndex: number;\n data: Buffer;\n }>(\n `SELECT chunkIndex, data FROM ${this.#t('fs_chunks')} WHERE path = @p0`,\n );\n\n for (const chunk of chunksResult.recordset) {\n const chunkInsertReq = transaction.request();\n chunkInsertReq.input('p0', newPath);\n chunkInsertReq.input('p1', chunk.chunkIndex);\n chunkInsertReq.input('p2', chunk.data);\n await chunkInsertReq.query(\n `INSERT INTO ${this.#t('fs_chunks')} (path, chunkIndex, data) VALUES (@p0, @p1, @p2)`,\n );\n }\n }\n }\n\n const deleteReq = transaction.request();\n deleteReq.input('p0', srcPrefixed);\n await deleteReq.query(\n `DELETE FROM ${this.#t('fs_entries')} WHERE path = @p0 OR path LIKE @p0 + '/%'`,\n );\n } else {\n const insertReq = transaction.request();\n insertReq.input('p0', destPrefixed);\n insertReq.input('p1', srcEntry.type);\n insertReq.input('p2', srcEntry.mode);\n insertReq.input('p3', srcEntry.size);\n insertReq.input('p4', Date.now());\n insertReq.input('p5', srcEntry.symlinkTarget);\n\n await insertReq.query(`\n MERGE ${this.#t('fs_entries')} AS target\n USING (SELECT @p0 AS path) AS source\n ON target.path = source.path\n WHEN MATCHED THEN\n UPDATE SET type = @p1, mode = @p2, size = @p3, mtime = @p4, symlinkTarget = @p5\n WHEN NOT MATCHED THEN\n INSERT (path, type, mode, size, mtime, symlinkTarget)\n VALUES (@p0, @p1, @p2, @p3, @p4, @p5);\n `);\n\n if (srcEntry.type === 'file') {\n const deleteChunksReq = transaction.request();\n deleteChunksReq.input('p0', destPrefixed);\n await deleteChunksReq.query(\n `DELETE FROM ${this.#t('fs_chunks')} WHERE path = @p0`,\n );\n\n const chunksReq = transaction.request();\n chunksReq.input('p0', srcPrefixed);\n const chunksResult = await chunksReq.query<{\n chunkIndex: number;\n data: Buffer;\n }>(\n `SELECT chunkIndex, data FROM ${this.#t('fs_chunks')} WHERE path = @p0`,\n );\n\n for (const chunk of chunksResult.recordset) {\n const chunkInsertReq = transaction.request();\n chunkInsertReq.input('p0', destPrefixed);\n chunkInsertReq.input('p1', chunk.chunkIndex);\n chunkInsertReq.input('p2', chunk.data);\n await chunkInsertReq.query(\n `INSERT INTO ${this.#t('fs_chunks')} (path, chunkIndex, data) VALUES (@p0, @p1, @p2)`,\n );\n }\n }\n\n const deleteReq = transaction.request();\n deleteReq.input('p0', srcPrefixed);\n await deleteReq.query(\n `DELETE FROM ${this.#t('fs_entries')} WHERE path = @p0`,\n );\n }\n });\n }\n\n resolvePath(base: string, relativePath: string): string {\n return path.posix.resolve(base, relativePath);\n }\n\n getAllPaths(): string[] {\n throw new Error(\n 'getAllPaths() is not supported in MssqlFs - use getAllPathsAsync() instead',\n );\n }\n\n async getAllPathsAsync(): Promise<string[]> {\n const rows = await this.#query<{ path: string; [key: string]: unknown }>(\n `SELECT path FROM ${this.#t('fs_entries')} ORDER BY path`,\n );\n return rows.map((row) => row.path);\n }\n\n async realpath(filePath: string): Promise<string> {\n const normalized = this.#normalizePath(filePath);\n const prefixed = this.#prefixPath(normalized);\n const resolved = await this.#resolveSymlink(prefixed);\n\n const rows = await this.#query<{ exists: number }>(\n `SELECT CASE WHEN EXISTS(SELECT 1 FROM ${this.#t('fs_entries')} WHERE path = @p0) THEN 1 ELSE 0 END as [exists]`,\n [resolved],\n );\n if (rows[0].exists !== 1) {\n throw new Error(`ENOENT: no such file or directory: ${filePath}`);\n }\n\n return this.#unprefixPath(resolved);\n }\n\n async utimes(filePath: string, _atime: Date, mtime: Date): Promise<void> {\n const normalized = this.#normalizePath(filePath);\n const prefixed = this.#prefixPath(normalized);\n const resolved = await this.#resolveSymlink(prefixed);\n\n const result = await this.#exec(\n `UPDATE ${this.#t('fs_entries')} SET mtime = @p0 WHERE path = @p1`,\n [mtime.getTime(), resolved],\n );\n\n if (result === 0) {\n throw new Error(`ENOENT: no such file or directory: ${filePath}`);\n }\n }\n\n async chmod(filePath: string, mode: number): Promise<void> {\n const normalized = this.#normalizePath(filePath);\n const prefixed = this.#prefixPath(normalized);\n\n const result = await this.#exec(\n `UPDATE ${this.#t('fs_entries')} SET mode = @p0 WHERE path = @p1`,\n [mode, prefixed],\n );\n\n if (result === 0) {\n throw new Error(`ENOENT: no such file or directory: ${filePath}`);\n }\n }\n\n async symlink(target: string, linkPath: string): Promise<void> {\n const normalized = this.#normalizePath(linkPath);\n const prefixed = this.#prefixPath(normalized);\n\n const existingRows = await this.#query<{ exists: number }>(\n `SELECT CASE WHEN EXISTS(SELECT 1 FROM ${this.#t('fs_entries')} WHERE path = @p0) THEN 1 ELSE 0 END as [exists]`,\n [prefixed],\n );\n if (existingRows[0].exists === 1) {\n throw new Error(`EEXIST: file already exists: ${linkPath}`);\n }\n\n await this.#useTransaction(async (transaction) => {\n await this.#ensureParentExists(prefixed, transaction);\n\n const insertReq = transaction.request();\n insertReq.input('p0', prefixed);\n insertReq.input('p1', Date.now());\n insertReq.input('p2', target);\n await insertReq.query(\n `INSERT INTO ${this.#t('fs_entries')} (path, type, mode, size, mtime, symlinkTarget)\n VALUES (@p0, 'symlink', 511, 0, @p1, @p2)`,\n );\n });\n }\n\n async link(existingPath: string, newPath: string): Promise<void> {\n const srcNormalized = this.#normalizePath(existingPath);\n const destNormalized = this.#normalizePath(newPath);\n const srcPrefixed = this.#prefixPath(srcNormalized);\n const destPrefixed = this.#prefixPath(destNormalized);\n\n const srcRows = await this.#query<FsEntryRow>(\n `SELECT * FROM ${this.#t('fs_entries')} WHERE path = @p0`,\n [srcPrefixed],\n );\n const srcEntry = srcRows[0];\n\n if (!srcEntry) {\n throw new Error(`ENOENT: no such file or directory: ${existingPath}`);\n }\n\n if (srcEntry.type !== 'file') {\n throw new Error(`link: not supported for directories: ${existingPath}`);\n }\n\n const existingRows = await this.#query<{ exists: number }>(\n `SELECT CASE WHEN EXISTS(SELECT 1 FROM ${this.#t('fs_entries')} WHERE path = @p0) THEN 1 ELSE 0 END as [exists]`,\n [destPrefixed],\n );\n if (existingRows[0].exists === 1) {\n throw new Error(`EEXIST: file already exists: ${newPath}`);\n }\n\n await this.#useTransaction(async (transaction) => {\n await this.#ensureParentExists(destPrefixed, transaction);\n\n const insertReq = transaction.request();\n insertReq.input('p0', destPrefixed);\n insertReq.input('p1', srcEntry.mode);\n insertReq.input('p2', srcEntry.size);\n insertReq.input('p3', Date.now());\n await insertReq.query(\n `INSERT INTO ${this.#t('fs_entries')} (path, type, mode, size, mtime)\n VALUES (@p0, 'file', @p1, @p2, @p3)`,\n );\n\n const chunksReq = transaction.request();\n chunksReq.input('p0', srcPrefixed);\n const chunksResult = await chunksReq.query<{\n chunkIndex: number;\n data: Buffer;\n }>(\n `SELECT chunkIndex, data FROM ${this.#t('fs_chunks')} WHERE path = @p0`,\n );\n\n for (const chunk of chunksResult.recordset) {\n const chunkInsertReq = transaction.request();\n chunkInsertReq.input('p0', destPrefixed);\n chunkInsertReq.input('p1', chunk.chunkIndex);\n chunkInsertReq.input('p2', chunk.data);\n await chunkInsertReq.query(\n `INSERT INTO ${this.#t('fs_chunks')} (path, chunkIndex, data) VALUES (@p0, @p1, @p2)`,\n );\n }\n });\n }\n\n async readlink(linkPath: string): Promise<string> {\n const normalized = this.#normalizePath(linkPath);\n const prefixed = this.#prefixPath(normalized);\n\n const rows = await this.#query<Pick<FsEntryRow, 'type' | 'symlinkTarget'>>(\n `SELECT type, symlinkTarget FROM ${this.#t('fs_entries')} WHERE path = @p0`,\n [prefixed],\n );\n const entry = rows[0];\n\n if (!entry) {\n throw new Error(`ENOENT: no such file or directory: ${linkPath}`);\n }\n\n if (entry.type !== 'symlink') {\n throw new Error(`readlink: not a symbolic link: ${linkPath}`);\n }\n\n return entry.symlinkTarget!;\n }\n}\n", "export function mssqlFsDDL(schema: string): string {\n return `\nIF NOT EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[${schema}].[fs_entries]') AND type = 'U')\nCREATE TABLE [${schema}].[fs_entries] (\n path NVARCHAR(900) PRIMARY KEY,\n type NVARCHAR(20) NOT NULL,\n mode INT NOT NULL,\n size BIGINT NOT NULL,\n mtime BIGINT NOT NULL,\n symlinkTarget NVARCHAR(900) NULL\n);\nGO\n\nIF NOT EXISTS (SELECT * FROM sys.indexes WHERE name = 'idx_${schema}_fs_entries_type')\nCREATE INDEX [idx_${schema}_fs_entries_type] ON [${schema}].[fs_entries](type);\nGO\n\nIF NOT EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[${schema}].[fs_chunks]') AND type = 'U')\nCREATE TABLE [${schema}].[fs_chunks] (\n path NVARCHAR(900) NOT NULL,\n chunkIndex INT NOT NULL,\n data VARBINARY(MAX) NOT NULL,\n PRIMARY KEY (path, chunkIndex),\n FOREIGN KEY (path) REFERENCES [${schema}].[fs_entries](path) ON DELETE CASCADE ON UPDATE CASCADE\n);\nGO\n`;\n}\n", "import type {\n CpOptions,\n FileContent,\n FsStat,\n IFileSystem,\n MkdirOptions,\n RmOptions,\n} from 'just-bash';\nimport { createRequire } from 'node:module';\nimport * as path from 'node:path';\nimport type { Pool, PoolClient, PoolConfig } from 'pg';\n\nimport { postgresFsDDL } from './ddl.postgres-fs.ts';\n\ninterface ReadFileOptions {\n encoding?: BufferEncoding | null;\n}\n\ninterface WriteFileOptions {\n encoding?: BufferEncoding;\n}\n\ninterface DirentEntry {\n name: string;\n isFile: boolean;\n isDirectory: boolean;\n isSymbolicLink: boolean;\n}\n\nexport interface PostgresFsOptions {\n pool: Pool | PoolConfig | string;\n root: string;\n chunkSize?: number;\n schema?: string;\n}\n\ntype EntryType = 'file' | 'directory' | 'symlink';\n\ninterface FsEntryRow {\n path: string;\n type: EntryType;\n mode: number;\n size: number;\n mtime: number;\n symlink_target: string | null;\n [key: string]: unknown;\n}\n\ninterface ChunkRow {\n data: Buffer;\n [key: string]: unknown;\n}\n\nexport class PostgresFs implements IFileSystem {\n #pool: Pool;\n #chunkSize: number;\n #root: string;\n #schema: string;\n #ownsPool: boolean;\n #isInitialized = false;\n\n constructor(options: PostgresFsOptions) {\n this.#chunkSize = options.chunkSize ?? 1024 * 1024;\n const schema = options.schema ?? 'public';\n if (!/^[a-zA-Z_]\\w*$/.test(schema)) {\n throw new Error(`Invalid schema name: \"${schema}\"`);\n }\n this.#schema = schema;\n const normalizedRoot = this.#normalizeRoot(options.root);\n this.#root = normalizedRoot === '/' ? '' : normalizedRoot;\n\n const pg = PostgresFs.#requirePg();\n if (options.pool instanceof pg.Pool) {\n this.#pool = options.pool;\n this.#ownsPool = false;\n } else {\n this.#pool =\n typeof options.pool === 'string'\n ? new pg.Pool({ connectionString: options.pool })\n : new pg.Pool(options.pool);\n this.#ownsPool = true;\n }\n }\n\n static #requirePg(): typeof import('pg') {\n try {\n const require = createRequire(import.meta.url);\n return require('pg');\n } catch {\n throw new Error(\n 'PostgresFs requires the \"pg\" package. Install it with: npm install pg',\n );\n }\n }\n\n #t(name: string): string {\n return `\"${this.#schema}\".\"${name}\"`;\n }\n\n async initialize(): Promise<void> {\n const ddl = postgresFsDDL(this.#schema);\n await this.#pool.query(ddl);\n\n const rootSlashExists = await this.#rawQuery<{ exists: boolean }>(\n `SELECT EXISTS(SELECT 1 FROM ${this.#t('fs_entries')} WHERE path = '/') AS exists`,\n );\n if (!rootSlashExists[0].exists) {\n await this.#rawExec(\n `INSERT INTO ${this.#t('fs_entries')} (path, type, mode, size, mtime) VALUES ('/', 'directory', 493, 0, $1)`,\n [Date.now()],\n );\n }\n\n if (this.#root) {\n await this.#createParentDirs(this.#root);\n\n const rootExists = await this.#rawQuery<{ exists: boolean }>(\n `SELECT EXISTS(SELECT 1 FROM ${this.#t('fs_entries')} WHERE path = $1) AS exists`,\n [this.#root],\n );\n if (!rootExists[0].exists) {\n await this.#rawExec(\n `INSERT INTO ${this.#t('fs_entries')} (path, type, mode, size, mtime) VALUES ($1, 'directory', 493, 0, $2)`,\n [this.#root, Date.now()],\n );\n }\n }\n\n this.#isInitialized = true;\n }\n\n #ensureInitialized(): void {\n if (!this.#isInitialized) {\n throw new Error(\n 'PostgresFs not initialized. Call await fs.initialize() after construction.',\n );\n }\n }\n\n async #createParentDirs(p: string): Promise<void> {\n const segments = p.split('/').filter(Boolean);\n let currentPath = '/';\n\n for (let i = 0; i < segments.length - 1; i++) {\n currentPath = path.posix.join(currentPath, segments[i]);\n const exists = await this.#rawQuery<{ exists: boolean }>(\n `SELECT EXISTS(SELECT 1 FROM ${this.#t('fs_entries')} WHERE path = $1) AS exists`,\n [currentPath],\n );\n\n if (!exists[0].exists) {\n await this.#rawExec(\n `INSERT INTO ${this.#t('fs_entries')} (path, type, mode, size, mtime) VALUES ($1, 'directory', 493, 0, $2)`,\n [currentPath, Date.now()],\n );\n }\n }\n }\n\n async #rawQuery<T extends Record<string, unknown>>(\n sql: string,\n params?: unknown[],\n ): Promise<T[]> {\n const result = await this.#pool.query(sql, params);\n return result.rows as T[];\n }\n\n async #rawExec(sql: string, params?: unknown[]): Promise<number> {\n const result = await this.#pool.query(sql, params);\n return result.rowCount ?? 0;\n }\n\n async #query<T extends Record<string, unknown>>(\n sql: string,\n params?: unknown[],\n ): Promise<T[]> {\n this.#ensureInitialized();\n return this.#rawQuery<T>(sql, params);\n }\n\n async #exec(sql: string, params?: unknown[]): Promise<number> {\n this.#ensureInitialized();\n return this.#rawExec(sql, params);\n }\n\n async #useTransaction<T>(fn: (client: PoolClient) => Promise<T>): Promise<T> {\n this.#ensureInitialized();\n const client = await this.#pool.connect();\n try {\n await client.query('BEGIN');\n const result = await fn(client);\n await client.query('COMMIT');\n return result;\n } catch (error) {\n await client.query('ROLLBACK');\n throw error;\n } finally {\n client.release();\n }\n }\n\n #normalizeRoot(root: string): string {\n return path.posix.resolve('/', root.trim());\n }\n\n #prefixPath(p: string): string {\n if (!this.#root) {\n return p;\n }\n if (p === '/') {\n return this.#root;\n }\n return path.posix.join(this.#root, p);\n }\n\n #unprefixPath(p: string): string {\n if (!this.#root) {\n return p;\n }\n if (p === this.#root) {\n return '/';\n }\n if (p.startsWith(this.#root + '/')) {\n return p.slice(this.#root.length) || '/';\n }\n return p;\n }\n\n #normalizePath(p: string): string {\n return path.posix.resolve('/', p);\n }\n\n #dirname(p: string): string {\n const dir = path.posix.dirname(p);\n return dir === '' ? '/' : dir;\n }\n\n async #ensureParentExists(\n filePath: string,\n client: PoolClient,\n ): Promise<void> {\n const parent = this.#dirname(filePath);\n const rootPath = this.#root || '/';\n if (parent === rootPath || parent === '/') return;\n\n const result = await client.query<{ type: string }>(\n `SELECT type FROM ${this.#t('fs_entries')} WHERE path = $1`,\n [parent],\n );\n const entry = result.rows[0];\n\n if (!entry) {\n await this.#ensureParentExists(parent, client);\n await client.query(\n `INSERT INTO ${this.#t('fs_entries')} (path, type, mode, size, mtime) VALUES ($1, 'directory', 493, 0, $2)`,\n [parent, Date.now()],\n );\n } else if (entry.type !== 'directory') {\n throw new Error(`mkdir: parent is not a directory: ${parent}`);\n }\n }\n\n async #writeChunks(\n filePath: string,\n content: Uint8Array,\n client: PoolClient,\n ): Promise<void> {\n await client.query(`DELETE FROM ${this.#t('fs_chunks')} WHERE path = $1`, [\n filePath,\n ]);\n\n for (let i = 0; i < content.length; i += this.#chunkSize) {\n const chunk = content.slice(\n i,\n Math.min(i + this.#chunkSize, content.length),\n );\n await client.query(\n `INSERT INTO ${this.#t('fs_chunks')} (path, chunk_index, data) VALUES ($1, $2, $3)`,\n [filePath, Math.floor(i / this.#chunkSize), Buffer.from(chunk)],\n );\n }\n }\n\n async #readChunks(\n filePath: string,\n client?: PoolClient,\n ): Promise<Uint8Array> {\n let rows: ChunkRow[];\n if (client) {\n const result = await client.query<ChunkRow>(\n `SELECT data FROM ${this.#t('fs_chunks')} WHERE path = $1 ORDER BY chunk_index`,\n [filePath],\n );\n rows = result.rows as ChunkRow[];\n } else {\n rows = await this.#query<ChunkRow>(\n `SELECT data FROM ${this.#t('fs_chunks')} WHERE path = $1 ORDER BY chunk_index`,\n [filePath],\n );\n }\n\n if (rows.length === 0) {\n return new Uint8Array(0);\n }\n\n const totalSize = rows.reduce((sum, row) => sum + row.data.length, 0);\n const result = new Uint8Array(totalSize);\n let offset = 0;\n\n for (const row of rows) {\n result.set(new Uint8Array(row.data), offset);\n offset += row.data.length;\n }\n\n return result;\n }\n\n async #resolveSymlink(p: string, seen = new Set<string>()): Promise<string> {\n if (seen.has(p)) {\n throw new Error(`readFile: circular symlink: ${p}`);\n }\n\n const rows = await this.#query<Pick<FsEntryRow, 'type' | 'symlink_target'>>(\n `SELECT type, symlink_target FROM ${this.#t('fs_entries')} WHERE path = $1`,\n [p],\n );\n const entry = rows[0];\n\n if (!entry) {\n throw new Error(`ENOENT: no such file or directory: ${p}`);\n }\n\n if (entry.type !== 'symlink') {\n return p;\n }\n\n seen.add(p);\n const target = this.#normalizePath(\n path.posix.resolve(this.#dirname(p), entry.symlink_target!),\n );\n return this.#resolveSymlink(target, seen);\n }\n\n #toUint8Array(content: FileContent, encoding?: string): Uint8Array {\n if (content instanceof Uint8Array) {\n return content;\n }\n const enc = (encoding ?? 'utf8') as BufferEncoding;\n return new Uint8Array(Buffer.from(content, enc));\n }\n\n async close(): Promise<void> {\n if (this.#ownsPool) {\n await this.#pool.end();\n }\n }\n\n // ============================================================================\n // IFileSystem Implementation\n // ============================================================================\n\n async readFile(\n filePath: string,\n options?: ReadFileOptions | string,\n ): Promise<string> {\n const normalized = this.#normalizePath(filePath);\n const prefixed = this.#prefixPath(normalized);\n const resolved = await this.#resolveSymlink(prefixed);\n\n const rows = await this.#query<Pick<FsEntryRow, 'type'>>(\n `SELECT type FROM ${this.#t('fs_entries')} WHERE path = $1`,\n [resolved],\n );\n const entry = rows[0];\n\n if (!entry) {\n throw new Error(`ENOENT: no such file or directory: ${filePath}`);\n }\n if (entry.type === 'directory') {\n throw new Error(`EISDIR: illegal operation on a directory: ${filePath}`);\n }\n\n const content = await this.#readChunks(resolved);\n const encoding =\n typeof options === 'string' ? options : (options?.encoding ?? 'utf8');\n return Buffer.from(content).toString(encoding as BufferEncoding);\n }\n\n async readFileBuffer(filePath: string): Promise<Uint8Array> {\n const normalized = this.#normalizePath(filePath);\n const prefixed = this.#prefixPath(normalized);\n const resolved = await this.#resolveSymlink(prefixed);\n\n const rows = await this.#query<Pick<FsEntryRow, 'type'>>(\n `SELECT type FROM ${this.#t('fs_entries')} WHERE path = $1`,\n [resolved],\n );\n const entry = rows[0];\n\n if (!entry) {\n throw new Error(`ENOENT: no such file or directory: ${filePath}`);\n }\n if (entry.type === 'directory') {\n throw new Error(`EISDIR: illegal operation on a directory: ${filePath}`);\n }\n\n return this.#readChunks(resolved);\n }\n\n async writeFile(\n filePath: string,\n content: FileContent,\n options?: WriteFileOptions | string,\n ): Promise<void> {\n const normalized = this.#normalizePath(filePath);\n const prefixed = this.#prefixPath(normalized);\n const encoding = typeof options === 'string' ? options : options?.encoding;\n const data = this.#toUint8Array(content, encoding);\n\n await this.#useTransaction(async (client) => {\n await this.#ensureParentExists(prefixed, client);\n\n await client.query(\n `INSERT INTO ${this.#t('fs_entries')} (path, type, mode, size, mtime)\n VALUES ($1, 'file', 420, $2, $3)\n ON CONFLICT (path) DO UPDATE SET type = 'file', size = EXCLUDED.size, mtime = EXCLUDED.mtime`,\n [prefixed, data.length, Date.now()],\n );\n\n await this.#writeChunks(prefixed, data, client);\n });\n }\n\n async appendFile(\n filePath: string,\n content: FileContent,\n options?: WriteFileOptions | string,\n ): Promise<void> {\n const normalized = this.#normalizePath(filePath);\n const prefixed = this.#prefixPath(normalized);\n const encoding = typeof options === 'string' ? options : options?.encoding;\n const newData = this.#toUint8Array(content, encoding);\n\n await this.#useTransaction(async (client) => {\n await this.#ensureParentExists(prefixed, client);\n\n const result = await client.query<Pick<FsEntryRow, 'type'>>(\n `SELECT type FROM ${this.#t('fs_entries')} WHERE path = $1`,\n [prefixed],\n );\n const entry = result.rows[0];\n\n if (entry && entry.type !== 'file') {\n throw new Error(`appendFile: not a file: ${filePath}`);\n }\n\n const existing = entry\n ? await this.#readChunks(prefixed, client)\n : new Uint8Array(0);\n const combined = new Uint8Array(existing.length + newData.length);\n combined.set(existing, 0);\n combined.set(newData, existing.length);\n\n await client.query(\n `INSERT INTO ${this.#t('fs_entries')} (path, type, mode, size, mtime)\n VALUES ($1, 'file', 420, $2, $3)\n ON CONFLICT (path) DO UPDATE SET size = EXCLUDED.size, mtime = EXCLUDED.mtime`,\n [prefixed, combined.length, Date.now()],\n );\n\n await this.#writeChunks(prefixed, combined, client);\n });\n }\n\n async exists(filePath: string): Promise<boolean> {\n const normalized = this.#normalizePath(filePath);\n const prefixed = this.#prefixPath(normalized);\n const rows = await this.#query<{ exists: boolean }>(\n `SELECT EXISTS(SELECT 1 FROM ${this.#t('fs_entries')} WHERE path = $1) AS exists`,\n [prefixed],\n );\n return rows[0].exists;\n }\n\n async stat(filePath: string): Promise<FsStat> {\n const normalized = this.#normalizePath(filePath);\n const prefixed = this.#prefixPath(normalized);\n const resolved = await this.#resolveSymlink(prefixed);\n\n const rows = await this.#query<FsEntryRow>(\n `SELECT * FROM ${this.#t('fs_entries')} WHERE path = $1`,\n [resolved],\n );\n const entry = rows[0];\n\n if (!entry) {\n throw new Error(`ENOENT: no such file or directory: ${filePath}`);\n }\n\n return {\n isFile: entry.type === 'file',\n isDirectory: entry.type === 'directory',\n isSymbolicLink: false,\n mode: Number(entry.mode),\n size: Number(entry.size),\n mtime: new Date(Number(entry.mtime)),\n };\n }\n\n async lstat(filePath: string): Promise<FsStat> {\n const normalized = this.#normalizePath(filePath);\n const prefixed = this.#prefixPath(normalized);\n\n const rows = await this.#query<FsEntryRow>(\n `SELECT * FROM ${this.#t('fs_entries')} WHERE path = $1`,\n [prefixed],\n );\n const entry = rows[0];\n\n if (!entry) {\n throw new Error(`ENOENT: no such file or directory: ${filePath}`);\n }\n\n return {\n isFile: entry.type === 'file',\n isDirectory: entry.type === 'directory',\n isSymbolicLink: entry.type === 'symlink',\n mode: Number(entry.mode),\n size: Number(entry.size),\n mtime: new Date(Number(entry.mtime)),\n };\n }\n\n async mkdir(dirPath: string, options?: MkdirOptions): Promise<void> {\n const normalized = this.#normalizePath(dirPath);\n const prefixed = this.#prefixPath(normalized);\n\n const existingRows = await this.#query<Pick<FsEntryRow, 'type'>>(\n `SELECT type FROM ${this.#t('fs_entries')} WHERE path = $1`,\n [prefixed],\n );\n const existing = existingRows[0];\n\n if (existing) {\n if (options?.recursive) {\n return;\n }\n throw new Error(`EEXIST: file already exists: ${dirPath}`);\n }\n\n await this.#useTransaction(async (client) => {\n if (options?.recursive) {\n const rootPath = this.#root || '/';\n const relativePath = path.posix.relative(rootPath, prefixed);\n const segments = relativePath.split('/').filter(Boolean);\n let currentPath = rootPath;\n\n for (const segment of segments) {\n currentPath = path.posix.join(currentPath, segment);\n const result = await client.query<Pick<FsEntryRow, 'type'>>(\n `SELECT type FROM ${this.#t('fs_entries')} WHERE path = $1`,\n [currentPath],\n );\n const exists = result.rows[0];\n\n if (!exists) {\n await client.query(\n `INSERT INTO ${this.#t('fs_entries')} (path, type, mode, size, mtime) VALUES ($1, 'directory', 493, 0, $2)`,\n [currentPath, Date.now()],\n );\n } else if (exists.type !== 'directory') {\n throw new Error(`mkdir: not a directory: ${currentPath}`);\n }\n }\n } else {\n const parent = this.#dirname(prefixed);\n const parentResult = await client.query<Pick<FsEntryRow, 'type'>>(\n `SELECT type FROM ${this.#t('fs_entries')} WHERE path = $1`,\n [parent],\n );\n const parentEntry = parentResult.rows[0];\n\n if (!parentEntry) {\n throw new Error(`mkdir: parent does not exist: ${parent}`);\n }\n if (parentEntry.type !== 'directory') {\n throw new Error(`mkdir: parent is not a directory: ${parent}`);\n }\n\n await client.query(\n `INSERT INTO ${this.#t('fs_entries')} (path, type, mode, size, mtime) VALUES ($1, 'directory', 493, 0, $2)`,\n [prefixed, Date.now()],\n );\n }\n });\n }\n\n async readdir(dirPath: string): Promise<string[]> {\n const normalized = this.#normalizePath(dirPath);\n const prefixed = this.#prefixPath(normalized);\n const resolved = await this.#resolveSymlink(prefixed);\n\n const entryRows = await this.#query<Pick<FsEntryRow, 'type'>>(\n `SELECT type FROM ${this.#t('fs_entries')} WHERE path = $1`,\n [resolved],\n );\n const entry = entryRows[0];\n\n if (!entry) {\n throw new Error(`ENOENT: no such file or directory: ${dirPath}`);\n }\n if (entry.type !== 'directory') {\n throw new Error(`ENOTDIR: not a directory: ${dirPath}`);\n }\n\n const prefix = resolved === '/' ? '/' : resolved + '/';\n const rows = await this.#query<{ path: string }>(\n `SELECT path FROM ${this.#t('fs_entries')}\n WHERE path LIKE $1 || '%'\n AND path != $2\n AND path NOT LIKE $1 || '%/%'`,\n [prefix, resolved],\n );\n\n return rows.map((row) => path.posix.basename(row.path));\n }\n\n async readdirWithFileTypes(dirPath: string): Promise<DirentEntry[]> {\n const normalized = this.#normalizePath(dirPath);\n const prefixed = this.#prefixPath(normalized);\n const resolved = await this.#resolveSymlink(prefixed);\n\n const entryRows = await this.#query<Pick<FsEntryRow, 'type'>>(\n `SELECT type FROM ${this.#t('fs_entries')} WHERE path = $1`,\n [resolved],\n );\n const entry = entryRows[0];\n\n if (!entry) {\n throw new Error(`ENOENT: no such file or directory: ${dirPath}`);\n }\n if (entry.type !== 'directory') {\n throw new Error(`ENOTDIR: not a directory: ${dirPath}`);\n }\n\n const prefix = resolved === '/' ? '/' : resolved + '/';\n const rows = await this.#query<Pick<FsEntryRow, 'path' | 'type'>>(\n `SELECT path, type FROM ${this.#t('fs_entries')}\n WHERE path LIKE $1 || '%'\n AND path != $2\n AND path NOT LIKE $1 || '%/%'`,\n [prefix, resolved],\n );\n\n return rows.map((row) => ({\n name: path.posix.basename(row.path),\n isFile: row.type === 'file',\n isDirectory: row.type === 'directory',\n isSymbolicLink: row.type === 'symlink',\n }));\n }\n\n async rm(filePath: string, options?: RmOptions): Promise<void> {\n const normalized = this.#normalizePath(filePath);\n const prefixed = this.#prefixPath(normalized);\n\n const rows = await this.#query<Pick<FsEntryRow, 'type'>>(\n `SELECT type FROM ${this.#t('fs_entries')} WHERE path = $1`,\n [prefixed],\n );\n const entry = rows[0];\n\n if (!entry) {\n if (options?.force) {\n return;\n }\n throw new Error(`ENOENT: no such file or directory: ${filePath}`);\n }\n\n await this.#useTransaction(async (client) => {\n if (entry.type === 'directory') {\n const childrenResult = await client.query<{ exists: boolean }>(\n `SELECT EXISTS(SELECT 1 FROM ${this.#t('fs_entries')} WHERE path LIKE $1 || '/%') AS exists`,\n [prefixed],\n );\n\n if (childrenResult.rows[0].exists && !options?.recursive) {\n throw new Error(`ENOTEMPTY: directory not empty: ${filePath}`);\n }\n\n await client.query(\n `DELETE FROM ${this.#t('fs_entries')} WHERE path = $1 OR path LIKE $1 || '/%'`,\n [prefixed],\n );\n } else {\n await client.query(\n `DELETE FROM ${this.#t('fs_entries')} WHERE path = $1`,\n [prefixed],\n );\n }\n });\n }\n\n async cp(src: string, dest: string, options?: CpOptions): Promise<void> {\n const srcNormalized = this.#normalizePath(src);\n const destNormalized = this.#normalizePath(dest);\n const srcPrefixed = this.#prefixPath(srcNormalized);\n const destPrefixed = this.#prefixPath(destNormalized);\n\n const srcRows = await this.#query<FsEntryRow>(\n `SELECT * FROM ${this.#t('fs_entries')} WHERE path = $1`,\n [srcPrefixed],\n );\n const srcEntry = srcRows[0];\n\n if (!srcEntry) {\n throw new Error(`ENOENT: no such file or directory: ${src}`);\n }\n\n if (srcEntry.type === 'directory' && !options?.recursive) {\n throw new Error(`cp: -r not specified; omitting directory: ${src}`);\n }\n\n await this.#useTransaction(async (client) => {\n await this.#ensureParentExists(destPrefixed, client);\n\n if (srcEntry.type === 'directory') {\n const allEntriesResult = await client.query<FsEntryRow>(\n `SELECT * FROM ${this.#t('fs_entries')} WHERE path = $1 OR path LIKE $1 || '/%'`,\n [srcPrefixed],\n );\n\n for (const entry of allEntriesResult.rows) {\n const relativePath = path.posix.relative(srcPrefixed, entry.path);\n const newPath = path.posix.join(destPrefixed, relativePath);\n\n await client.query(\n `INSERT INTO ${this.#t('fs_entries')} (path, type, mode, size, mtime, symlink_target)\n VALUES ($1, $2, $3, $4, $5, $6)\n ON CONFLICT (path) DO UPDATE SET type = EXCLUDED.type, mode = EXCLUDED.mode, size = EXCLUDED.size, mtime = EXCLUDED.mtime, symlink_target = EXCLUDED.symlink_target`,\n [\n newPath,\n entry.type,\n entry.mode,\n entry.size,\n Date.now(),\n entry.symlink_target,\n ],\n );\n\n if (entry.type === 'file') {\n await client.query(\n `DELETE FROM ${this.#t('fs_chunks')} WHERE path = $1`,\n [newPath],\n );\n\n const chunksResult = await client.query<{\n chunk_index: number;\n data: Buffer;\n }>(\n `SELECT chunk_index, data FROM ${this.#t('fs_chunks')} WHERE path = $1`,\n [entry.path],\n );\n\n for (const chunk of chunksResult.rows) {\n await client.query(\n `INSERT INTO ${this.#t('fs_chunks')} (path, chunk_index, data) VALUES ($1, $2, $3)`,\n [newPath, chunk.chunk_index, chunk.data],\n );\n }\n }\n }\n } else {\n await client.query(\n `INSERT INTO ${this.#t('fs_entries')} (path, type, mode, size, mtime, symlink_target)\n VALUES ($1, $2, $3, $4, $5, $6)\n ON CONFLICT (path) DO UPDATE SET type = EXCLUDED.type, mode = EXCLUDED.mode, size = EXCLUDED.size, mtime = EXCLUDED.mtime, symlink_target = EXCLUDED.symlink_target`,\n [\n destPrefixed,\n srcEntry.type,\n srcEntry.mode,\n srcEntry.size,\n Date.now(),\n srcEntry.symlink_target,\n ],\n );\n\n if (srcEntry.type === 'file') {\n const chunksResult = await client.query<{\n chunk_index: number;\n data: Buffer;\n }>(\n `SELECT chunk_index, data FROM ${this.#t('fs_chunks')} WHERE path = $1`,\n [srcPrefixed],\n );\n\n await client.query(\n `DELETE FROM ${this.#t('fs_chunks')} WHERE path = $1`,\n [destPrefixed],\n );\n\n for (const chunk of chunksResult.rows) {\n await client.query(\n `INSERT INTO ${this.#t('fs_chunks')} (path, chunk_index, data) VALUES ($1, $2, $3)`,\n [destPrefixed, chunk.chunk_index, chunk.data],\n );\n }\n }\n }\n });\n }\n\n async mv(src: string, dest: string): Promise<void> {\n const srcNormalized = this.#normalizePath(src);\n const destNormalized = this.#normalizePath(dest);\n const srcPrefixed = this.#prefixPath(srcNormalized);\n const destPrefixed = this.#prefixPath(destNormalized);\n\n const srcRows = await this.#query<FsEntryRow>(\n `SELECT * FROM ${this.#t('fs_entries')} WHERE path = $1`,\n [srcPrefixed],\n );\n const srcEntry = srcRows[0];\n\n if (!srcEntry) {\n throw new Error(`ENOENT: no such file or directory: ${src}`);\n }\n\n await this.#useTransaction(async (client) => {\n await this.#ensureParentExists(destPrefixed, client);\n\n if (srcEntry.type === 'directory') {\n const allEntriesResult = await client.query<FsEntryRow>(\n `SELECT * FROM ${this.#t('fs_entries')} WHERE path = $1 OR path LIKE $1 || '/%' ORDER BY path DESC`,\n [srcPrefixed],\n );\n\n await client.query(\n `DELETE FROM ${this.#t('fs_entries')} WHERE path = $1 OR path LIKE $1 || '/%'`,\n [destPrefixed],\n );\n\n for (const entry of [...allEntriesResult.rows].reverse()) {\n const relativePath = path.posix.relative(srcPrefixed, entry.path);\n const newPath = path.posix.join(destPrefixed, relativePath);\n\n await client.query(\n `INSERT INTO ${this.#t('fs_entries')} (path, type, mode, size, mtime, symlink_target)\n VALUES ($1, $2, $3, $4, $5, $6)\n ON CONFLICT (path) DO UPDATE SET type = EXCLUDED.type, mode = EXCLUDED.mode, size = EXCLUDED.size, mtime = EXCLUDED.mtime, symlink_target = EXCLUDED.symlink_target`,\n [\n newPath,\n entry.type,\n entry.mode,\n entry.size,\n Date.now(),\n entry.symlink_target,\n ],\n );\n\n if (entry.type === 'file') {\n await client.query(\n `DELETE FROM ${this.#t('fs_chunks')} WHERE path = $1`,\n [newPath],\n );\n\n const chunksResult = await client.query<{\n chunk_index: number;\n data: Buffer;\n }>(\n `SELECT chunk_index, data FROM ${this.#t('fs_chunks')} WHERE path = $1`,\n [entry.path],\n );\n\n for (const chunk of chunksResult.rows) {\n await client.query(\n `INSERT INTO ${this.#t('fs_chunks')} (path, chunk_index, data) VALUES ($1, $2, $3)`,\n [newPath, chunk.chunk_index, chunk.data],\n );\n }\n }\n }\n\n await client.query(\n `DELETE FROM ${this.#t('fs_entries')} WHERE path = $1 OR path LIKE $1 || '/%'`,\n [srcPrefixed],\n );\n } else {\n await client.query(\n `INSERT INTO ${this.#t('fs_entries')} (path, type, mode, size, mtime, symlink_target)\n VALUES ($1, $2, $3, $4, $5, $6)\n ON CONFLICT (path) DO UPDATE SET type = EXCLUDED.type, mode = EXCLUDED.mode, size = EXCLUDED.size, mtime = EXCLUDED.mtime, symlink_target = EXCLUDED.symlink_target`,\n [\n destPrefixed,\n srcEntry.type,\n srcEntry.mode,\n srcEntry.size,\n Date.now(),\n srcEntry.symlink_target,\n ],\n );\n\n if (srcEntry.type === 'file') {\n await client.query(\n `DELETE FROM ${this.#t('fs_chunks')} WHERE path = $1`,\n [destPrefixed],\n );\n\n const chunksResult = await client.query<{\n chunk_index: number;\n data: Buffer;\n }>(\n `SELECT chunk_index, data FROM ${this.#t('fs_chunks')} WHERE path = $1`,\n [srcPrefixed],\n );\n\n for (const chunk of chunksResult.rows) {\n await client.query(\n `INSERT INTO ${this.#t('fs_chunks')} (path, chunk_index, data) VALUES ($1, $2, $3)`,\n [destPrefixed, chunk.chunk_index, chunk.data],\n );\n }\n }\n\n await client.query(\n `DELETE FROM ${this.#t('fs_entries')} WHERE path = $1`,\n [srcPrefixed],\n );\n }\n });\n }\n\n resolvePath(base: string, relativePath: string): string {\n return path.posix.resolve(base, relativePath);\n }\n\n getAllPaths(): string[] {\n throw new Error(\n 'getAllPaths() is not supported in PostgresFs - use getAllPathsAsync() instead',\n );\n }\n\n async getAllPathsAsync(): Promise<string[]> {\n const rows = await this.#query<{ path: string; [key: string]: unknown }>(\n `SELECT path FROM ${this.#t('fs_entries')} ORDER BY path`,\n );\n return rows.map((row) => row.path);\n }\n\n async realpath(filePath: string): Promise<string> {\n const normalized = this.#normalizePath(filePath);\n const prefixed = this.#prefixPath(normalized);\n const resolved = await this.#resolveSymlink(prefixed);\n\n const rows = await this.#query<{ exists: boolean }>(\n `SELECT EXISTS(SELECT 1 FROM ${this.#t('fs_entries')} WHERE path = $1) AS exists`,\n [resolved],\n );\n if (!rows[0].exists) {\n throw new Error(`ENOENT: no such file or directory: ${filePath}`);\n }\n\n return this.#unprefixPath(resolved);\n }\n\n async utimes(filePath: string, _atime: Date, mtime: Date): Promise<void> {\n const normalized = this.#normalizePath(filePath);\n const prefixed = this.#prefixPath(normalized);\n const resolved = await this.#resolveSymlink(prefixed);\n\n const result = await this.#exec(\n `UPDATE ${this.#t('fs_entries')} SET mtime = $1 WHERE path = $2`,\n [mtime.getTime(), resolved],\n );\n\n if (result === 0) {\n throw new Error(`ENOENT: no such file or directory: ${filePath}`);\n }\n }\n\n async chmod(filePath: string, mode: number): Promise<void> {\n const normalized = this.#normalizePath(filePath);\n const prefixed = this.#prefixPath(normalized);\n\n const result = await this.#exec(\n `UPDATE ${this.#t('fs_entries')} SET mode = $1 WHERE path = $2`,\n [mode, prefixed],\n );\n\n if (result === 0) {\n throw new Error(`ENOENT: no such file or directory: ${filePath}`);\n }\n }\n\n async symlink(target: string, linkPath: string): Promise<void> {\n const normalized = this.#normalizePath(linkPath);\n const prefixed = this.#prefixPath(normalized);\n\n const existingRows = await this.#query<{ exists: boolean }>(\n `SELECT EXISTS(SELECT 1 FROM ${this.#t('fs_entries')} WHERE path = $1) AS exists`,\n [prefixed],\n );\n if (existingRows[0].exists) {\n throw new Error(`EEXIST: file already exists: ${linkPath}`);\n }\n\n await this.#useTransaction(async (client) => {\n await this.#ensureParentExists(prefixed, client);\n\n await client.query(\n `INSERT INTO ${this.#t('fs_entries')} (path, type, mode, size, mtime, symlink_target)\n VALUES ($1, 'symlink', 511, 0, $2, $3)`,\n [prefixed, Date.now(), target],\n );\n });\n }\n\n async link(existingPath: string, newPath: string): Promise<void> {\n const srcNormalized = this.#normalizePath(existingPath);\n const destNormalized = this.#normalizePath(newPath);\n const srcPrefixed = this.#prefixPath(srcNormalized);\n const destPrefixed = this.#prefixPath(destNormalized);\n\n const srcRows = await this.#query<FsEntryRow>(\n `SELECT * FROM ${this.#t('fs_entries')} WHERE path = $1`,\n [srcPrefixed],\n );\n const srcEntry = srcRows[0];\n\n if (!srcEntry) {\n throw new Error(`ENOENT: no such file or directory: ${existingPath}`);\n }\n\n if (srcEntry.type !== 'file') {\n throw new Error(`link: not supported for directories: ${existingPath}`);\n }\n\n const existingRows = await this.#query<{ exists: boolean }>(\n `SELECT EXISTS(SELECT 1 FROM ${this.#t('fs_entries')} WHERE path = $1) AS exists`,\n [destPrefixed],\n );\n if (existingRows[0].exists) {\n throw new Error(`EEXIST: file already exists: ${newPath}`);\n }\n\n await this.#useTransaction(async (client) => {\n await this.#ensureParentExists(destPrefixed, client);\n\n await client.query(\n `INSERT INTO ${this.#t('fs_entries')} (path, type, mode, size, mtime)\n VALUES ($1, 'file', $2, $3, $4)`,\n [destPrefixed, srcEntry.mode, srcEntry.size, Date.now()],\n );\n\n const chunksResult = await client.query<{\n chunk_index: number;\n data: Buffer;\n }>(\n `SELECT chunk_index, data FROM ${this.#t('fs_chunks')} WHERE path = $1`,\n [srcPrefixed],\n );\n\n for (const chunk of chunksResult.rows) {\n await client.query(\n `INSERT INTO ${this.#t('fs_chunks')} (path, chunk_index, data) VALUES ($1, $2, $3)`,\n [destPrefixed, chunk.chunk_index, chunk.data],\n );\n }\n });\n }\n\n async readlink(linkPath: string): Promise<string> {\n const normalized = this.#normalizePath(linkPath);\n const prefixed = this.#prefixPath(normalized);\n\n const rows = await this.#query<Pick<FsEntryRow, 'type' | 'symlink_target'>>(\n `SELECT type, symlink_target FROM ${this.#t('fs_entries')} WHERE path = $1`,\n [prefixed],\n );\n const entry = rows[0];\n\n if (!entry) {\n throw new Error(`ENOENT: no such file or directory: ${linkPath}`);\n }\n\n if (entry.type !== 'symlink') {\n throw new Error(`readlink: not a symbolic link: ${linkPath}`);\n }\n\n return entry.symlink_target!;\n }\n}\n", "export function postgresFsDDL(schema: string): string {\n return `\nCREATE SCHEMA IF NOT EXISTS \"${schema}\";\n\nCREATE TABLE IF NOT EXISTS \"${schema}\".\"fs_entries\" (\n path TEXT PRIMARY KEY,\n type TEXT NOT NULL,\n mode INTEGER NOT NULL,\n size BIGINT NOT NULL,\n mtime BIGINT NOT NULL,\n symlink_target TEXT\n);\n\nCREATE INDEX IF NOT EXISTS \"idx_${schema}_fs_entries_type\" ON \"${schema}\".\"fs_entries\"(type);\n\nCREATE TABLE IF NOT EXISTS \"${schema}\".\"fs_chunks\" (\n path TEXT NOT NULL,\n chunk_index INTEGER NOT NULL,\n data BYTEA NOT NULL,\n PRIMARY KEY (path, chunk_index),\n FOREIGN KEY (path) REFERENCES \"${schema}\".\"fs_entries\"(path) ON DELETE CASCADE ON UPDATE CASCADE\n);\n`;\n}\n", "import type {\n CpOptions,\n FileContent,\n FsStat,\n IFileSystem,\n MkdirOptions,\n RmOptions,\n} from 'just-bash';\n\ntype BufferEncoding = 'utf8' | 'utf-8' | 'ascii' | 'base64' | 'hex' | 'binary';\n\ninterface ReadFileOptions {\n encoding?: BufferEncoding | null;\n}\n\ninterface WriteFileOptions {\n encoding?: BufferEncoding;\n}\n\ninterface DirentEntry {\n name: string;\n isFile: boolean;\n isDirectory: boolean;\n isSymbolicLink: boolean;\n}\n\nexport interface ScopedFsOptions {\n base: IFileSystem;\n prefix: string;\n}\n\n/**\n * Filesystem wrapper that prefixes all paths with a given prefix.\n * Enables chat-level isolation without modifying command logic.\n *\n * @example\n * const scopedFs = new ScopedFs({\n * base: fs,\n * prefix: '/chat-123',\n * });\n */\nexport class ScopedFs implements IFileSystem {\n #base: IFileSystem;\n #prefix: string;\n\n constructor(options: ScopedFsOptions) {\n this.#base = options.base;\n this.#prefix = options.prefix.replace(/\\/$/, '');\n }\n\n #scope(path: string): string {\n return `${this.#prefix}${path}`;\n }\n\n #unscope(path: string): string {\n if (path === this.#prefix) {\n return '/';\n }\n if (path.startsWith(this.#prefix + '/')) {\n return path.slice(this.#prefix.length) || '/';\n }\n return path;\n }\n\n async writeFile(\n path: string,\n content: FileContent,\n options?: WriteFileOptions | BufferEncoding,\n ): Promise<void> {\n await this.#base.writeFile(this.#scope(path), content, options);\n }\n\n async appendFile(\n path: string,\n content: FileContent,\n options?: WriteFileOptions | BufferEncoding,\n ): Promise<void> {\n await this.#base.appendFile(this.#scope(path), content, options);\n }\n\n async mkdir(path: string, options?: MkdirOptions): Promise<void> {\n return this.#base.mkdir(this.#scope(path), options);\n }\n\n async rm(path: string, options?: RmOptions): Promise<void> {\n await this.#base.rm(this.#scope(path), options);\n }\n\n async cp(src: string, dest: string, options?: CpOptions): Promise<void> {\n await this.#base.cp(this.#scope(src), this.#scope(dest), options);\n }\n\n async mv(src: string, dest: string): Promise<void> {\n await this.#base.mv(this.#scope(src), this.#scope(dest));\n }\n\n async chmod(path: string, mode: number): Promise<void> {\n return this.#base.chmod(this.#scope(path), mode);\n }\n\n async symlink(target: string, linkPath: string): Promise<void> {\n await this.#base.symlink(target, this.#scope(linkPath));\n }\n\n async link(existingPath: string, newPath: string): Promise<void> {\n await this.#base.link(this.#scope(existingPath), this.#scope(newPath));\n }\n\n readFile(\n path: string,\n options?: ReadFileOptions | BufferEncoding,\n ): Promise<string> {\n return this.#base.readFile(this.#scope(path), options);\n }\n\n readFileBuffer(path: string): Promise<Uint8Array> {\n return this.#base.readFileBuffer(this.#scope(path));\n }\n\n stat(path: string): Promise<FsStat> {\n return this.#base.stat(this.#scope(path));\n }\n\n lstat(path: string): Promise<FsStat> {\n return this.#base.lstat(this.#scope(path));\n }\n\n readdir(path: string): Promise<string[]> {\n return this.#base.readdir(this.#scope(path));\n }\n\n readdirWithFileTypes(path: string): Promise<DirentEntry[]> {\n return this.#base.readdirWithFileTypes!(this.#scope(path));\n }\n\n exists(path: string): Promise<boolean> {\n return this.#base.exists(this.#scope(path));\n }\n\n readlink(path: string): Promise<string> {\n return this.#base.readlink(this.#scope(path));\n }\n\n realpath(path: string): Promise<string> {\n return this.#base.realpath(this.#scope(path)).then((p) => this.#unscope(p));\n }\n\n utimes(path: string, atime: Date, mtime: Date): Promise<void> {\n return this.#base.utimes(this.#scope(path), atime, mtime);\n }\n\n resolvePath(base: string, relativePath: string): string {\n return this.#base.resolvePath(base, relativePath);\n }\n\n getAllPaths(): string[] {\n const allPaths = this.#base.getAllPaths?.() ?? [];\n return allPaths\n .filter((p) => p.startsWith(this.#prefix))\n .map((p) => p.slice(this.#prefix.length) || '/');\n }\n}\n", "import {\n type ContextFragment,\n clarification,\n example,\n explain,\n fragment,\n guardrail,\n hint,\n policy,\n quirk,\n reasoningFramework,\n styleGuide,\n workflow,\n} from '@deepagents/context';\n\nexport function instructions(): ContextFragment[] {\n const baseTeachings: ContextFragment[] = [\n // Include the meta-cognitive reasoning framework\n ...reasoningFramework(),\n\n // Prerequisite policies (must do X before Y)\n fragment(\n 'prerequisite_policies',\n policy({\n rule: 'YOU MUST inspect schema structure and available tables',\n before: 'generating ANY SQL query',\n reason:\n 'NEVER generate SQL without knowing valid tables, columns, and relationships',\n }),\n policy({\n rule: 'YOU MUST resolve ambiguous business terms with the user',\n before: 'making ANY assumptions about terminology meaning',\n reason:\n 'NEVER guess domain-specific language, instead ask for clarification',\n }),\n policy({\n rule: 'YOU MUST validate SQL syntax',\n before: 'executing ANY query against the database',\n reason: 'NEVER execute unvalidated queries',\n }),\n policy({\n rule: 'YOU MUST complete ALL reasoning steps',\n before: 'taking ANY tool call or response action',\n reason: 'Once an action is taken, it CANNOT be undone. NO EXCEPTIONS.',\n }),\n ),\n\n // Few-shot: Applying reasoning principles\n fragment(\n 'reasoning_examples',\n example({\n question: 'Show me sales last month',\n answer: `Applying Principle 1 (Logical dependencies):\n- Need: schema to know which table has sales data\n- Need: clarify \"last month\" = calendar month or rolling 30 days?\n\nApplying Principle 5 (Information availability):\n- Schema shows: orders table with created_at, total columns\n- Missing: user's definition of \"last month\"\n\nAction: Ask user for date range clarification BEFORE generating SQL.`,\n }),\n example({\n question: 'Why did my query return no results?',\n answer: `Applying Principle 3 (Abductive reasoning):\n- Hypothesis 1 (most likely): Filter too restrictive\n- Hypothesis 2: Data doesn't exist for that period\n- Hypothesis 3: JOIN eliminated matching rows\n\nTesting hypotheses:\n1. Remove filters one by one to isolate the issue\n2. Check date range actually has data\n3. Run subqueries separately to verify each table\n\nAction: Start with most likely hypothesis, test incrementally. NEVER guess.`,\n }),\n example({\n question: 'Get me the top customers',\n answer: `Applying Principle 1 (Logical dependencies):\n- \"Top\" is ambiguous\u2014by revenue? by order count? by recency?\n\nApplying Principle 9 (Inhibition):\n- MUST NOT generate SQL until \"top\" is defined\n\nAction: Ask user: \"Top by what metric\u2014total revenue, number of orders, or most recent activity?\"`,\n }),\n ),\n\n // Schema adherence - consolidated into clear rules\n fragment(\n 'schema_adherence',\n guardrail({\n rule: 'Use only tables and columns that exist in the schema.',\n reason:\n 'Inventing tables or columns produces invalid SQL and breaks schema grounding.',\n action:\n 'If the user requests unspecified fields, use SELECT *. When showing related items, include IDs and requested details.',\n }),\n explain({\n concept: 'query intent words',\n explanation:\n '\"Show\" asks for listing rows, while \"count\" or \"total\" asks for aggregation.',\n therefore:\n 'Use listing queries for \"show\" requests, aggregate queries for \"count\" or \"total\", and use canonical schema values verbatim in filters.',\n }),\n ),\n\n fragment(\n 'column_statistics',\n explain({\n concept: 'nDistinct in column stats',\n explanation:\n 'Positive values are the estimated count of distinct values. Negative values represent the fraction of unique rows (e.g., -1 means all rows are unique, -0.5 means 50% unique)',\n therefore:\n 'Use nDistinct to decide if GROUP BY is meaningful, if a column is a good filter candidate, or if COUNT(DISTINCT) will be expensive',\n }),\n explain({\n concept: 'correlation in column stats',\n explanation:\n 'Measures how closely the physical row order matches the logical sort order of the column. Values near 1 or -1 mean the data is well-ordered; near 0 means scattered',\n therefore:\n 'High correlation means range queries (BETWEEN, >, <) on that column benefit from index scans. Low correlation means the index is less effective for ranges',\n }),\n hint(\n 'When min/max stats are available, use them to validate filter values. If a user asks for values outside the known range, warn them the query may return no results.',\n ),\n ),\n\n // Joins - use relationship metadata\n hint(\n 'Use JOINs based on schema relationships. Favor PK/indexed columns; follow relationship metadata for direction and cardinality.',\n ),\n\n // Aggregations - explain the concepts\n fragment(\n 'aggregations',\n hint(\n 'Apply COUNT, SUM, AVG when the question implies summarization. Use window functions for ranking, running totals, or row comparisons.',\n ),\n explain({\n concept: 'counting variety vs counting rows',\n explanation:\n '\"How many types/categories/statuses exist?\" asks about variety (unique values), not total row count',\n therefore: 'Use COUNT(DISTINCT column) for variety questions',\n }),\n ),\n\n // Query semantics - explain concepts and document quirks\n fragment(\n 'query_interpretation',\n explain({\n concept: 'threshold language',\n explanation:\n 'Words like \"reach\", \"hit\", \"exceed\" with a value imply a threshold being met or passed',\n therefore:\n 'Translate to >= (greater than or equal), not = (exact match)',\n }),\n quirk({\n issue:\n 'Contradictory WHERE conditions (e.g., value > 100 AND value < 50) return empty results',\n workaround:\n 'Use INTERSECT between separate queries when finding items \"shared by\" groups with mutually exclusive conditions',\n }),\n quirk({\n issue:\n 'NULL values behave unexpectedly in comparisons and aggregations',\n workaround:\n 'Use IS NULL, IS NOT NULL, or COALESCE() to handle NULLs explicitly',\n }),\n hint(\n 'Always include mentioned filters from joined tables in WHERE conditions.',\n ),\n ),\n\n // Style preferences\n styleGuide({\n prefer:\n 'Full table names as aliases (users AS users). Descriptive column aliases (COUNT(*) AS total_count).',\n never:\n 'Abbreviated aliases (u, oi) or positional aliases (t1, t2, a, b). Schema-qualified column references on aliased tables (e.g. dbo.users.id when table is aliased) \u2014 always use the alias (users.id).',\n }),\n styleGuide({\n prefer:\n 'Concise, business-friendly summaries with key comparisons and helpful follow-ups.',\n }),\n\n // Safety guardrails - consolidated\n fragment(\n 'query_safety',\n guardrail({\n rule: 'Generate only valid, executable SELECT/WITH statements.',\n reason: 'Read-only access prevents data modification.',\n action:\n 'Never generate INSERT, UPDATE, DELETE, DROP, or DDL statements.',\n }),\n guardrail({\n rule: 'Avoid unbounded scans and cartesian joins.',\n reason: 'Protects performance and correctness.',\n action:\n 'Apply filters on indexed columns. If join keys are unclear, ask for clarification.',\n }),\n guardrail({\n rule: 'Preserve query semantics.',\n reason: 'Arbitrary modifications change results.',\n action:\n 'Only add LIMIT for explicit \"top N\" requests. Add ORDER BY for deterministic results.',\n }),\n ),\n\n hint(\n 'Use sample cell values from schema hints to match exact casing and format in WHERE conditions (e.g., \"Male\" vs \"male\" vs \"M\").',\n ),\n\n workflow({\n task: 'SQL generation',\n steps: [\n 'Schema linking: identify which tables and columns are mentioned or implied by the question.',\n 'Check if column names match question terms (e.g., Total_X). Select directly if match found.',\n 'Identify SQL patterns needed: aggregation, segmentation, time range, ranking.',\n 'Select tables and relationships. Note lookup tables and filter values from schema.',\n 'Plan join/filter/aggregation order based on table sizes and indexes.',\n 'Generate SQL that answers the question.',\n 'Verify: mentally translate SQL back to natural language. Does it match the original question?',\n ],\n }),\n\n workflow({\n task: 'Error recovery',\n triggers: ['SQL error', 'query failed', 'execution error'],\n steps: [\n 'Classify the error type: syntax error, missing join, wrong aggregation, invalid column, type mismatch.',\n 'For syntax errors: check SQL keywords, quotes, parentheses balance.',\n 'For missing join: identify unlinked tables and add appropriate JOIN clause.',\n 'For wrong aggregation: verify GROUP BY includes all non-aggregated SELECT columns.',\n 'For invalid column: re-check schema for correct column name and table.',\n 'Apply targeted fix based on error classification. Avoid blind regeneration.',\n ],\n notes:\n 'Maximum 3 retry attempts. If still failing, explain the issue to the user.',\n }),\n\n workflow({\n task: 'Complex query decomposition',\n triggers: [\n 'multiple conditions',\n 'nested requirements',\n 'compare across',\n 'for each',\n ],\n steps: [\n 'Identify if question has multiple independent parts or nested dependencies.',\n 'For independent parts: break into sub-questions, solve each, then combine with UNION or JOIN.',\n 'For nested dependencies: solve inner requirement first, use result in outer query (subquery or CTE).',\n 'For comparisons across groups: use window functions or self-joins.',\n 'Combine sub-results into final answer. Verify completeness.',\n ],\n notes:\n 'Complex questions often need CTEs (WITH clauses) for clarity and reusability.',\n }),\n\n workflow({\n task: 'Multi-turn context',\n triggers: ['follow-up', 'and also', 'what about', 'same but', 'instead'],\n steps: [\n 'Identify references to previous context: \"it\", \"that\", \"those\", \"the same\".',\n 'Resolve references using conversation history: which tables, filters, or results were mentioned.',\n 'For refinements (\"but only X\"): add filter to previous query.',\n 'For extensions (\"and also Y\"): expand SELECT or add JOIN.',\n 'For pivots (\"what about Z instead\"): replace the changed element, keep unchanged parts.',\n 'Maintain consistency with previous query structure when possible.',\n ],\n notes:\n 'If reference is ambiguous, ask which previous result or entity the user means.',\n }),\n fragment(\n 'bash_tool_usage',\n workflow({\n task: 'Query execution',\n steps: [\n 'Pick the target database by the <database> value shown at the top of each schema fragment \u2014 that is the exact connection name to pass as <db>. It is NOT the SQL-level database/schema name (e.g. SQLite\\'s default \"main\").',\n 'Execute SQL through bash tool: sql run <db> \"SELECT ...\"',\n 'Read the output: file path, column names, and row count.',\n \"Use column names to construct jq filters: cat <path> | jq '.[] | {col1, col2}'\",\n \"For large results, slice first: cat <path> | jq '.[:10]'\",\n ],\n }),\n guardrail({\n rule: 'Do not attempt SQL access through non-bash tools.',\n reason: 'SQL access is only available through the bash tool.',\n action:\n 'Use `sql run <db> \"SELECT ...\"` and `sql validate <db> \"SELECT ...\"` through bash, where `<db>` is the exact configured connection name (not the SQL-level database/schema name).',\n }),\n explain({\n concept: 'sql command output format',\n explanation:\n 'The sql command returns a file path, comma-separated column names, and a row count.',\n therefore:\n 'Use the returned column names to build precise jq queries against the output file.',\n }),\n quirk({\n issue:\n 'The SQL command is a real CLI installed inside the sandbox, so shell quoting rules apply before SQL validation runs.',\n workaround:\n 'Keep the whole SQL query in one quoted argument. If quoting is difficult, write the query to a file and call `sql validate <db> \"$(cat query.sql)\"` or `sql run <db> \"$(cat query.sql)\"`.',\n }),\n quirk({\n issue:\n 'SQL result artifacts live inside the sandbox, so you cannot access underlying SQL files directly.',\n workaround:\n 'Treat the returned result path as the artifact to inspect, rather than trying to access SQL files themselves.',\n }),\n quirk({\n issue: 'If a query fails, the sql command reports the error on stderr.',\n workaround:\n 'Read stderr first and classify the failure before retrying or changing the query.',\n }),\n ),\n fragment(\n 'clarifications',\n guardrail({\n rule: 'Do not invent an answer when the available schema, results, or user request are insufficient to determine it.',\n reason: 'Prevents hallucinations and improves trustworthiness.',\n action:\n 'State that you do not have enough information to determine the answer and ask a focused clarification question.',\n }),\n clarification({\n when: 'Ambiguous ranking language (top, best, active) without a metric.',\n ask: 'Clarify the ranking metric or definition.',\n reason: 'Ensures correct aggregation and ordering.',\n }),\n clarification({\n when: 'The request targets time-based data without a date range.',\n ask: 'Confirm the intended timeframe (e.g., last 30/90 days, YTD, specific year).',\n reason: 'Prevents large scans and irrelevant results.',\n }),\n ),\n ];\n return baseTeachings;\n}\n", "import type { CommandNode, WordNode } from 'just-bash';\nimport { parse } from 'just-bash';\n\nimport { asStaticWordText } from '@deepagents/context';\n\nexport type SqlQuerySubcommand = 'run' | 'validate';\n\nexport interface SqlQueryInvocation {\n subcommand: SqlQuerySubcommand;\n dbName: string;\n sql: string;\n}\n\n/**\n * Parse a single `sql run|validate <db> \"<sql>\"` command into its parts, or\n * `null` for anything that is not exactly one such invocation (pipelines,\n * redirections, other commands, unparseable input). Shared by the meta hook\n * (which tracks invocations to attach formatted-SQL metadata) and the\n * validate-before-run reminder predicate.\n */\nexport function parseSqlQueryInvocation(\n command: string,\n): SqlQueryInvocation | null {\n const simpleCommand = parseSingleSimpleCommand(command);\n if (!simpleCommand) return null;\n if (asStaticWordText(simpleCommand.name) !== 'sql') return null;\n if (simpleCommand.args.length < 3) return null;\n\n const subcommand = asStaticWordText(simpleCommand.args[0]);\n if (subcommand !== 'run' && subcommand !== 'validate') return null;\n\n const dbName = asStaticWordText(simpleCommand.args[1]);\n if (!dbName) return null;\n\n const sql = joinSqlWords(simpleCommand.args.slice(2));\n if (!sql) return null;\n\n return { subcommand, dbName, sql };\n}\n\nfunction parseSingleSimpleCommand(\n command: string,\n): Extract<CommandNode, { type: 'SimpleCommand' }> | null {\n const normalized = command.trim();\n if (!normalized) return null;\n\n try {\n const script = parse(normalized);\n if (script.statements.length !== 1) return null;\n\n const statement = script.statements[0];\n if (\n statement.background ||\n statement.operators.length > 0 ||\n statement.pipelines.length !== 1\n ) {\n return null;\n }\n\n const pipeline = statement.pipelines[0];\n if (pipeline.negated || pipeline.timed || pipeline.commands.length !== 1) {\n return null;\n }\n\n const commandNode = pipeline.commands[0];\n if (commandNode.type !== 'SimpleCommand') return null;\n if (\n commandNode.assignments.length > 0 ||\n commandNode.redirections.length > 0 ||\n !commandNode.name\n ) {\n return null;\n }\n\n return commandNode;\n } catch {\n return null;\n }\n}\n\nfunction joinSqlWords(words: WordNode[]): string | null {\n const values: string[] = [];\n for (const word of words) {\n const value = asStaticWordText(word, {\n preserveLegacyBackticks: true,\n });\n if (value == null) return null;\n values.push(value);\n }\n const sql = values.join(' ').trim();\n return sql || null;\n}\n", "import type { CommandResult } from '@deepagents/context';\n\nimport {\n type SqlQueryInvocation,\n parseSqlQueryInvocation,\n} from './sql-invocation.ts';\n\nexport interface SqlCommandFormatter {\n format(sql: string): string;\n}\n\nexport interface CreateSqlMetaHookOptions {\n adapters: Record<string, SqlCommandFormatter>;\n}\n\nexport interface SqlMetaTrackInput {\n repaired: string;\n transformed: string;\n}\n\nexport interface SqlMetaAfterHookInput {\n command: string;\n result: CommandResult;\n}\n\nexport function createSqlMetaHook({ adapters }: CreateSqlMetaHookOptions) {\n const pendingByCommand = new Map<string, SqlQueryInvocation[]>();\n\n return {\n track({ repaired, transformed }: SqlMetaTrackInput): void {\n const invocation = parseSqlQueryInvocation(repaired);\n if (!invocation) return;\n const pending = pendingByCommand.get(transformed) ?? [];\n pending.push(invocation);\n pendingByCommand.set(transformed, pending);\n },\n\n onAfterBashCall({ command }: SqlMetaAfterHookInput) {\n const pending = pendingByCommand.get(command);\n const invocation = pending?.shift();\n if (pending?.length === 0) pendingByCommand.delete(command);\n if (!invocation) return undefined;\n\n const adapter = adapters[invocation.dbName];\n if (!adapter) return undefined;\n\n try {\n return {\n meta: { formattedSql: adapter.format(invocation.sql) },\n };\n } catch {\n // Formatting metadata is best-effort and must not change command output.\n return undefined;\n }\n },\n };\n}\n", "import {\n type SubcommandDefinition,\n buildSubcommandRepair,\n repairQuotedArg,\n} from '@deepagents/context';\n\nfunction repairDbNameAndQuery(rawArgs: string): string | null {\n const trimmed = rawArgs.trim();\n if (!trimmed) return null;\n\n const firstSpace = trimmed.search(/\\s/);\n if (firstSpace === -1) return null;\n\n const dbName = trimmed.slice(0, firstSpace);\n const rest = trimmed.slice(firstSpace + 1);\n const repaired = repairQuotedArg(rest);\n if (repaired == null) return null;\n\n return `${dbName} ${repaired}`;\n}\n\nconst inertHandler = () => ({ stdout: '', stderr: '', exitCode: 0 });\n\nconst repair = buildSubcommandRepair('sql', {\n run: {\n usage: 'run <db> \"SELECT ...\"',\n description: 'Execute query against <db> and store results',\n repair: repairDbNameAndQuery,\n handler: inertHandler,\n },\n validate: {\n usage: 'validate <db> \"SELECT ...\"',\n description: 'Validate query syntax against <db>',\n repair: repairDbNameAndQuery,\n handler: inertHandler,\n },\n} satisfies Record<string, SubcommandDefinition>);\n\nexport function repairSqlCommand(command: string): string {\n return repair(command);\n}\n", "import { BashTransformPipeline } from 'just-bash';\n\nimport {\n SqlCommandRewritePlugin,\n SqlProxyEnforcementPlugin,\n SqlProxyViolationError,\n} from './agents/sql-transform-plugins.ts';\n\nconst sqlTransformPipeline = new BashTransformPipeline()\n .use(new SqlCommandRewritePlugin())\n .use(new SqlProxyEnforcementPlugin());\n\nexport function transformSqlCommand(command: string): string {\n try {\n return sqlTransformPipeline.transform(command).script;\n } catch (error) {\n if (error instanceof SqlProxyViolationError) {\n return blockedSqlProxyCommand(error.message);\n }\n return command;\n }\n}\n\nfunction blockedSqlProxyCommand(message: string): string {\n return `{ printf '%s\\\\n' ${shellQuote(message)} >&2; exit 1; }`;\n}\n\nfunction shellQuote(value: string): string {\n return `'${value.replace(/'/g, \"'\\\\''\")}'`;\n}\n", "import type {\n CommandNode,\n ScriptNode,\n TransformContext,\n TransformPlugin,\n TransformResult,\n WordNode,\n} from 'just-bash';\nimport { parse, serialize } from 'just-bash';\nimport { createHash } from 'node:crypto';\nimport * as path from 'node:path';\n\nimport {\n BashException,\n type CommandResult,\n asStaticWordText,\n} from '@deepagents/context';\n\nimport { isValidAdapterName } from '../adapter-name.ts';\n\nfunction isScriptNode(value: unknown): value is ScriptNode {\n if (typeof value !== 'object' || value === null) {\n return false;\n }\n const node = value as Record<string, unknown>;\n return node.type === 'Script' && Array.isArray(node.statements);\n}\n\n// \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n// SQL Proxy Enforcement Plugin\n// \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nconst BLOCKED_DB_CLIENT_COMMANDS = new Set([\n 'psql',\n 'sqlite3',\n 'mysql',\n 'duckdb',\n]);\nconst BLOCKED_RAW_SQL_COMMANDS = new Set(['select', 'with']);\nconst ALLOWED_SQL_PROXY_SUBCOMMANDS = new Set(['run', 'validate']);\nconst SHELL_INTERPRETER_COMMANDS = new Set([\n 'bash',\n 'sh',\n 'zsh',\n 'dash',\n 'ksh',\n]);\nconst WRAPPER_COMMANDS = new Set(['env', 'command', 'eval']);\n\nconst SQL_PROXY_ENFORCEMENT_MESSAGE = [\n 'Direct database querying through bash is blocked.',\n 'Use SQL proxy commands in this order:',\n '1) sql validate <db> \"SELECT ...\"',\n '2) sql run <db> \"SELECT ...\"',\n].join('\\n');\n\nexport class SqlProxyViolationError extends BashException {\n constructor() {\n super(SQL_PROXY_ENFORCEMENT_MESSAGE);\n this.name = 'SqlProxyViolationError';\n }\n\n format(): CommandResult {\n return { stdout: '', stderr: `${this.message}\\n`, exitCode: 1 };\n }\n}\n\ntype SqlInspectionMode = 'blocked-only' | 'block-all-sql';\n\ntype FunctionDefCommand = Extract<CommandNode, { type: 'FunctionDef' }>;\n\ninterface InspectionContext {\n functionDefinitions: Map<string, FunctionDefCommand>;\n callStack: Set<string>;\n}\n\ninterface CommandInspectionOptions {\n stdinFromPipe: boolean;\n}\n\ninterface ShellInvocationDescriptor {\n kind: 'command' | 'script' | 'stdin' | 'none' | 'unknown';\n payload: string | null;\n}\n\ninterface WrapperCommandResolution {\n kind: 'resolved' | 'none' | 'unknown';\n name?: WordNode;\n args?: WordNode[];\n}\n\nfunction cloneInspectionContext(context: InspectionContext): InspectionContext {\n return {\n functionDefinitions: new Map(context.functionDefinitions),\n callStack: new Set(context.callStack),\n };\n}\n\nfunction scriptContainsBlockedCommand(\n script: ScriptNode,\n context: InspectionContext,\n mode: SqlInspectionMode = 'blocked-only',\n): boolean {\n return statementsContainBlockedCommand(script.statements, context, mode);\n}\n\nfunction statementsContainBlockedCommand(\n statements: Array<{ pipelines: Array<{ commands: CommandNode[] }> }>,\n context: InspectionContext,\n mode: SqlInspectionMode,\n): boolean {\n for (const statement of statements) {\n if (statementContainsBlockedCommand(statement, context, mode)) {\n return true;\n }\n }\n return false;\n}\n\nfunction statementContainsBlockedCommand(\n statement: { pipelines: Array<{ commands: CommandNode[] }> },\n context: InspectionContext,\n mode: SqlInspectionMode,\n): boolean {\n for (const pipeline of statement.pipelines) {\n if (pipelineContainsBlockedCommand(pipeline, context, mode)) {\n return true;\n }\n }\n return false;\n}\n\nfunction pipelineContainsBlockedCommand(\n pipeline: { commands: CommandNode[] },\n context: InspectionContext,\n mode: SqlInspectionMode,\n): boolean {\n for (const [index, command] of pipeline.commands.entries()) {\n if (command.type === 'FunctionDef') {\n context.functionDefinitions.set(command.name, command);\n continue;\n }\n if (\n commandContainsBlockedCommand(command, context, mode, {\n stdinFromPipe: index > 0,\n })\n ) {\n return true;\n }\n }\n return false;\n}\n\nfunction stringCommandContainsBlockedCommand(\n command: string,\n context: InspectionContext,\n mode: SqlInspectionMode = 'blocked-only',\n): boolean {\n let script: ScriptNode;\n try {\n script = parse(command);\n } catch {\n return false;\n }\n\n return scriptContainsBlockedCommand(\n script,\n cloneInspectionContext(context),\n mode,\n );\n}\n\nfunction wordContainsBlockedCommand(\n word: WordNode | null | undefined,\n context: InspectionContext,\n mode: SqlInspectionMode,\n): boolean {\n if (!word) {\n return false;\n }\n\n return wordPartContainsBlockedCommand(\n word.parts as unknown as Array<Record<string, unknown>>,\n context,\n mode,\n );\n}\n\nfunction wordPartContainsBlockedCommand(\n parts: Array<Record<string, unknown>>,\n context: InspectionContext,\n mode: SqlInspectionMode,\n): boolean {\n for (const part of parts) {\n if (partContainsBlockedCommand(part, context, mode)) {\n return true;\n }\n }\n return false;\n}\n\nfunction partContainsBlockedCommand(\n node: Record<string, unknown>,\n context: InspectionContext,\n mode: SqlInspectionMode,\n): boolean {\n const type = node.type;\n\n if (type === 'CommandSubstitution' || type === 'ProcessSubstitution') {\n if (isScriptNode(node.body)) {\n return scriptContainsBlockedCommand(\n node.body,\n cloneInspectionContext(context),\n mode,\n );\n }\n return false;\n }\n\n if (type === 'ArithCommandSubst' && typeof node.command === 'string') {\n return stringCommandContainsBlockedCommand(node.command, context, mode);\n }\n\n for (const value of Object.values(node)) {\n if (Array.isArray(value)) {\n for (const item of value) {\n if (typeof item === 'object' && item !== null) {\n if (\n partContainsBlockedCommand(\n item as Record<string, unknown>,\n context,\n mode,\n )\n ) {\n return true;\n }\n }\n }\n continue;\n }\n\n if (typeof value === 'object' && value !== null) {\n if (\n partContainsBlockedCommand(\n value as Record<string, unknown>,\n context,\n mode,\n )\n ) {\n return true;\n }\n }\n }\n\n return false;\n}\n\nfunction functionInvocationContainsBlockedCommand(\n functionName: string,\n context: InspectionContext,\n mode: SqlInspectionMode,\n): boolean {\n const definition = context.functionDefinitions.get(functionName);\n if (!definition) {\n return false;\n }\n\n if (context.callStack.has(functionName)) {\n return false;\n }\n\n const invocationContext = cloneInspectionContext(context);\n invocationContext.callStack.add(functionName);\n return commandContainsBlockedCommand(\n definition.body,\n invocationContext,\n mode,\n { stdinFromPipe: false },\n );\n}\n\nfunction isAsciiLetter(character: string): boolean {\n const charCode = character.charCodeAt(0);\n return (\n (charCode >= 65 && charCode <= 90) || (charCode >= 97 && charCode <= 122)\n );\n}\n\nfunction isAsciiDigit(character: string): boolean {\n const charCode = character.charCodeAt(0);\n return charCode >= 48 && charCode <= 57;\n}\n\nfunction isValidEnvVariableName(name: string): boolean {\n if (!name) {\n return false;\n }\n\n const firstChar = name[0];\n if (!(isAsciiLetter(firstChar) || firstChar === '_')) {\n return false;\n }\n\n for (let index = 1; index < name.length; index += 1) {\n const char = name[index];\n if (!(isAsciiLetter(char) || isAsciiDigit(char) || char === '_')) {\n return false;\n }\n }\n\n return true;\n}\n\nfunction isEnvAssignmentToken(token: string): boolean {\n const separatorIndex = token.indexOf('=');\n if (separatorIndex <= 0) {\n return false;\n }\n\n return isValidEnvVariableName(token.slice(0, separatorIndex));\n}\n\nfunction parseShortOptionCluster(option: string): {\n valid: boolean;\n hasCommandFlag: boolean;\n hasStdinFlag: boolean;\n consumesNextArg: boolean;\n} {\n if (\n !option.startsWith('-') ||\n option.startsWith('--') ||\n option.length <= 1\n ) {\n return {\n valid: false,\n hasCommandFlag: false,\n hasStdinFlag: false,\n consumesNextArg: false,\n };\n }\n\n let hasCommandFlag = false;\n let hasStdinFlag = false;\n let consumesNextArg = false;\n\n for (let index = 1; index < option.length; index += 1) {\n const char = option[index];\n if (!isAsciiLetter(char)) {\n return {\n valid: false,\n hasCommandFlag: false,\n hasStdinFlag: false,\n consumesNextArg: false,\n };\n }\n\n if (char === 'c') {\n hasCommandFlag = true;\n } else if (char === 's') {\n hasStdinFlag = true;\n } else if (char === 'O' || char === 'o') {\n consumesNextArg = true;\n }\n }\n\n return { valid: true, hasCommandFlag, hasStdinFlag, consumesNextArg };\n}\n\nfunction getShellInvocationDescriptor(\n args: WordNode[],\n): ShellInvocationDescriptor {\n let readsFromStdin = false;\n const longOptionsWithValue = new Set(['--rcfile', '--init-file']);\n\n for (let index = 0; index < args.length; index += 1) {\n const token = asStaticWordText(args[index]);\n if (token == null) {\n return { kind: 'unknown', payload: null };\n }\n\n if (token === '--') {\n if (index + 1 >= args.length) {\n break;\n }\n return {\n kind: 'script',\n payload: asStaticWordText(args[index + 1]),\n };\n }\n\n if (token === '--command') {\n return {\n kind: 'command',\n payload: asStaticWordText(args[index + 1]),\n };\n }\n\n if (token.startsWith('--command=')) {\n return {\n kind: 'command',\n payload: token.slice('--command='.length),\n };\n }\n\n if (token.startsWith('--')) {\n if (token.includes('=')) {\n continue;\n }\n\n if (longOptionsWithValue.has(token)) {\n if (index + 1 >= args.length) {\n return { kind: 'unknown', payload: null };\n }\n index += 1;\n }\n continue;\n }\n\n if (token.startsWith('-') && !token.startsWith('--')) {\n const parsed = parseShortOptionCluster(token);\n if (!parsed.valid) {\n return { kind: 'unknown', payload: null };\n }\n\n if (parsed.hasCommandFlag) {\n return {\n kind: 'command',\n payload: asStaticWordText(args[index + 1]),\n };\n }\n\n if (parsed.hasStdinFlag) {\n readsFromStdin = true;\n }\n\n if (parsed.consumesNextArg) {\n if (index + 1 >= args.length) {\n return { kind: 'unknown', payload: null };\n }\n index += 1;\n }\n continue;\n }\n\n return {\n kind: 'script',\n payload: token,\n };\n }\n\n if (readsFromStdin) {\n return { kind: 'stdin', payload: null };\n }\n\n return { kind: 'none', payload: null };\n}\n\nfunction getHereDocPayload(\n redirections: Array<{\n target: { type?: string; content?: WordNode };\n }>,\n): { hasHereDoc: boolean; payload: string | null } {\n const payloads: string[] = [];\n\n for (const redirection of redirections) {\n if (redirection.target.type !== 'HereDoc') {\n continue;\n }\n\n if (!redirection.target.content) {\n payloads.push('');\n continue;\n }\n\n const payload = asStaticWordText(redirection.target.content);\n if (payload == null) {\n return { hasHereDoc: true, payload: null };\n }\n\n payloads.push(payload);\n }\n\n if (payloads.length === 0) {\n return { hasHereDoc: false, payload: null };\n }\n\n return { hasHereDoc: true, payload: payloads.join('\\n') };\n}\n\nfunction joinStaticWords(words: WordNode[]): string | null {\n const tokens: string[] = [];\n\n for (const word of words) {\n const token = asStaticWordText(word);\n if (token == null) {\n return null;\n }\n tokens.push(token);\n }\n\n return tokens.join(' ');\n}\n\nfunction resolveEnvWrapperCommand(args: WordNode[]): WrapperCommandResolution {\n let index = 0;\n\n while (index < args.length) {\n const token = asStaticWordText(args[index]);\n if (token == null) {\n return { kind: 'unknown' };\n }\n\n if (token === '--') {\n index += 1;\n break;\n }\n\n if (token === '-u' || token === '--unset' || token === '--chdir') {\n if (index + 1 >= args.length) {\n return { kind: 'unknown' };\n }\n index += 2;\n continue;\n }\n\n if (token.startsWith('--unset=') || token.startsWith('--chdir=')) {\n index += 1;\n continue;\n }\n\n if (\n token.startsWith('-') &&\n token !== '-' &&\n !isEnvAssignmentToken(token)\n ) {\n index += 1;\n continue;\n }\n\n if (isEnvAssignmentToken(token)) {\n index += 1;\n continue;\n }\n\n break;\n }\n\n if (index >= args.length) {\n return { kind: 'none' };\n }\n\n return {\n kind: 'resolved',\n name: args[index],\n args: args.slice(index + 1),\n };\n}\n\nfunction resolveCommandWrapperCommand(\n args: WordNode[],\n): WrapperCommandResolution {\n let index = 0;\n let lookupOnly = false;\n\n while (index < args.length) {\n const token = asStaticWordText(args[index]);\n if (token == null) {\n return { kind: 'unknown' };\n }\n\n if (token === '--') {\n index += 1;\n break;\n }\n\n if (token === '-v' || token === '-V') {\n lookupOnly = true;\n index += 1;\n continue;\n }\n\n if (token.startsWith('-') && token !== '-') {\n index += 1;\n continue;\n }\n\n break;\n }\n\n if (lookupOnly || index >= args.length) {\n return { kind: 'none' };\n }\n\n return {\n kind: 'resolved',\n name: args[index],\n args: args.slice(index + 1),\n };\n}\n\nfunction commandContainsBlockedCommand(\n command: CommandNode,\n context: InspectionContext,\n mode: SqlInspectionMode,\n options: CommandInspectionOptions = { stdinFromPipe: false },\n): boolean {\n switch (command.type) {\n case 'SimpleCommand':\n return isBlockedSimpleCommand(command, context, mode, options);\n case 'If':\n return (\n command.clauses.some(\n (clause) =>\n statementsContainBlockedCommand(\n clause.condition,\n cloneInspectionContext(context),\n mode,\n ) ||\n statementsContainBlockedCommand(\n clause.body,\n cloneInspectionContext(context),\n mode,\n ),\n ) ||\n (command.elseBody\n ? statementsContainBlockedCommand(\n command.elseBody,\n cloneInspectionContext(context),\n mode,\n )\n : false)\n );\n case 'For':\n case 'CStyleFor':\n return statementsContainBlockedCommand(\n command.body,\n cloneInspectionContext(context),\n mode,\n );\n case 'While':\n case 'Until':\n return (\n statementsContainBlockedCommand(\n command.condition,\n cloneInspectionContext(context),\n mode,\n ) ||\n statementsContainBlockedCommand(\n command.body,\n cloneInspectionContext(context),\n mode,\n )\n );\n case 'Case':\n return command.items.some((item) =>\n statementsContainBlockedCommand(\n item.body,\n cloneInspectionContext(context),\n mode,\n ),\n );\n case 'Subshell':\n case 'Group':\n return statementsContainBlockedCommand(\n command.body,\n cloneInspectionContext(context),\n mode,\n );\n case 'FunctionDef':\n return false;\n case 'ArithmeticCommand':\n case 'ConditionalCommand':\n return false;\n default: {\n const _unreachable: never = command;\n return _unreachable;\n }\n }\n}\n\nfunction isBlockedSimpleCommand(\n command: {\n name: WordNode | null;\n args: WordNode[];\n assignments: Array<{\n value: WordNode | null;\n array: WordNode[] | null;\n }>;\n redirections: Array<{\n target: { type?: string; content?: WordNode };\n }>;\n },\n context: InspectionContext,\n mode: SqlInspectionMode,\n options: CommandInspectionOptions,\n): boolean {\n if (wordContainsBlockedCommand(command.name, context, mode)) {\n return true;\n }\n\n if (\n command.args.some((arg) => wordContainsBlockedCommand(arg, context, mode))\n ) {\n return true;\n }\n\n if (\n command.assignments.some(\n (assignment) =>\n wordContainsBlockedCommand(assignment.value, context, mode) ||\n (assignment.array?.some((value) =>\n wordContainsBlockedCommand(value, context, mode),\n ) ??\n false),\n )\n ) {\n return true;\n }\n\n if (\n command.redirections.some((redirection) => {\n if (redirection.target.type === 'Word') {\n return wordContainsBlockedCommand(\n redirection.target as unknown as WordNode,\n context,\n mode,\n );\n }\n if (redirection.target.type === 'HereDoc' && redirection.target.content) {\n return wordContainsBlockedCommand(\n redirection.target.content,\n context,\n mode,\n );\n }\n return false;\n })\n ) {\n return true;\n }\n\n const commandName = asStaticWordText(command.name);\n if (!commandName) {\n return false;\n }\n\n const normalizedName = path.posix.basename(commandName).toLowerCase();\n\n if (BLOCKED_DB_CLIENT_COMMANDS.has(normalizedName)) {\n return true;\n }\n\n if (BLOCKED_RAW_SQL_COMMANDS.has(normalizedName)) {\n return true;\n }\n\n if (normalizedName === 'sql') {\n const subcommand = asStaticWordText(command.args[0])?.toLowerCase();\n if (!subcommand) {\n return true;\n }\n if (mode === 'block-all-sql') {\n return true;\n }\n return !ALLOWED_SQL_PROXY_SUBCOMMANDS.has(subcommand);\n }\n\n const inspectWrappedCommand = (\n resolved: WrapperCommandResolution,\n ): boolean => {\n if (resolved.kind === 'none') {\n return false;\n }\n\n if (resolved.kind === 'unknown' || !resolved.name || !resolved.args) {\n return true;\n }\n\n return isBlockedSimpleCommand(\n {\n name: resolved.name,\n args: resolved.args,\n assignments: [],\n redirections: [],\n },\n context,\n 'block-all-sql',\n options,\n );\n };\n\n if (WRAPPER_COMMANDS.has(normalizedName)) {\n if (normalizedName === 'env') {\n return inspectWrappedCommand(resolveEnvWrapperCommand(command.args));\n }\n\n if (normalizedName === 'command') {\n return inspectWrappedCommand(resolveCommandWrapperCommand(command.args));\n }\n\n const evalScript = joinStaticWords(command.args);\n if (evalScript == null) {\n return true;\n }\n if (!evalScript.trim()) {\n return false;\n }\n return stringCommandContainsBlockedCommand(\n evalScript,\n context,\n 'block-all-sql',\n );\n }\n\n if (SHELL_INTERPRETER_COMMANDS.has(normalizedName)) {\n const shellInvocation = getShellInvocationDescriptor(command.args);\n if (shellInvocation.kind === 'unknown') {\n return true;\n }\n\n if (shellInvocation.kind === 'command') {\n if (!shellInvocation.payload) {\n return true;\n }\n if (\n stringCommandContainsBlockedCommand(\n shellInvocation.payload,\n context,\n 'block-all-sql',\n )\n ) {\n return true;\n }\n return false;\n }\n\n const hereDoc = getHereDocPayload(command.redirections);\n if (hereDoc.hasHereDoc) {\n if (hereDoc.payload == null) {\n return true;\n }\n if (\n hereDoc.payload.trim().length > 0 &&\n stringCommandContainsBlockedCommand(\n hereDoc.payload,\n context,\n 'block-all-sql',\n )\n ) {\n return true;\n }\n }\n\n if (shellInvocation.kind === 'script') {\n return true;\n }\n\n if (options.stdinFromPipe || shellInvocation.kind === 'stdin') {\n return !hereDoc.hasHereDoc;\n }\n }\n\n if (functionInvocationContainsBlockedCommand(commandName, context, mode)) {\n return true;\n }\n\n return false;\n}\n\nexport interface SqlProxyEnforcementMetadata {\n inspected: true;\n}\n\nexport class SqlProxyEnforcementPlugin implements TransformPlugin<SqlProxyEnforcementMetadata> {\n name = 'sql-proxy-enforcement';\n\n transform(\n context: TransformContext,\n ): TransformResult<SqlProxyEnforcementMetadata> {\n const blocked = scriptContainsBlockedCommand(context.ast, {\n functionDefinitions: new Map(),\n callStack: new Set(),\n });\n\n if (blocked) {\n throw new SqlProxyViolationError();\n }\n\n return {\n ast: context.ast,\n metadata: { inspected: true },\n };\n }\n}\n\n// \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n// SQL Backtick Rewrite Plugin\n// \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nfunction wordPartsContainExpansion(\n parts: Array<Record<string, unknown>>,\n): boolean {\n for (const part of parts) {\n if (\n part.type === 'CommandSubstitution' ||\n part.type === 'ParameterExpansion' ||\n part.type === 'ArithmeticExpansion'\n ) {\n return true;\n }\n\n if (part.type === 'DoubleQuoted' && Array.isArray(part.parts)) {\n if (\n wordPartsContainExpansion(part.parts as Array<Record<string, unknown>>)\n ) {\n return true;\n }\n }\n }\n\n return false;\n}\n\nexport interface SqlCommandRewriteMetadata {\n rewritten: boolean;\n}\n\nfunction isSqlCommandRequiringRewrite(\n cmd: CommandNode,\n): cmd is Extract<CommandNode, { type: 'SimpleCommand' }> {\n if (cmd.type !== 'SimpleCommand') return false;\n if (cmd.assignments.length > 0 || cmd.redirections.length > 0) return false;\n if (asStaticWordText(cmd.name) !== 'sql') return false;\n if (cmd.args.length < 3) return false;\n\n const subcommand = asStaticWordText(cmd.args[0]);\n if (subcommand !== 'validate' && subcommand !== 'run') return false;\n\n const dbName = asStaticWordText(cmd.args[1]);\n if (!isValidAdapterName(dbName)) return false;\n\n const sqlArgs = cmd.args.slice(2);\n if (sqlArgs.length > 1) return true;\n return sqlArgs.some((arg: WordNode) =>\n wordPartsContainExpansion(\n arg.parts as unknown as Array<Record<string, unknown>>,\n ),\n );\n}\n\nfunction extractWordPartText(parts: Array<Record<string, unknown>>): string {\n let text = '';\n for (const part of parts) {\n const type = part.type;\n if (type === 'Literal' || type === 'SingleQuoted' || type === 'Escaped') {\n text += part.value as string;\n } else if (type === 'DoubleQuoted' && Array.isArray(part.parts)) {\n text += extractWordPartText(part.parts as Array<Record<string, unknown>>);\n } else if (type === 'CommandSubstitution' && part.legacy === true) {\n text += '`' + serialize(part.body as ScriptNode).trim() + '`';\n } else if (type === 'CommandSubstitution') {\n text += '$(' + serialize(part.body as ScriptNode).trim() + ')';\n } else if (type === 'ParameterExpansion') {\n text += emitParameterExpansion(part);\n } else if (type === 'ArithmeticExpansion') {\n const expression = part.expression as\n | { originalText?: string }\n | undefined;\n text += '$((' + (expression?.originalText ?? '') + '))';\n }\n }\n return text;\n}\n\nfunction emitParameterExpansion(part: Record<string, unknown>): string {\n const parameter = part.parameter as string;\n const operation = part.operation as\n | {\n type: string;\n word?: { parts: Array<Record<string, unknown>> };\n checkEmpty?: boolean;\n }\n | null\n | undefined;\n if (!operation) return '$' + parameter;\n if (operation.type === 'DefaultValue' && operation.word) {\n const fallback = extractWordPartText(operation.word.parts);\n const separator = operation.checkEmpty ? ':-' : '-';\n return '${' + parameter + separator + fallback + '}';\n }\n return '${' + parameter + '}';\n}\n\nfunction extractSqlText(args: WordNode[]): string {\n return args\n .map((arg) =>\n extractWordPartText(\n arg.parts as unknown as Array<Record<string, unknown>>,\n ),\n )\n .join(' ');\n}\n\nfunction rewriteSqlCommand(\n cmd: Extract<CommandNode, { type: 'SimpleCommand' }>,\n ast: ScriptNode,\n): CommandNode {\n const subcommand = asStaticWordText(cmd.args[0])!;\n const dbName = asStaticWordText(cmd.args[1])!;\n const sqlArgs = cmd.args.slice(2);\n const unquotedSql = extractSqlText(sqlArgs);\n\n const hash = createHash('sha256')\n .update(serialize(ast))\n .digest('hex')\n .slice(0, 12);\n const sqlPath = `/tmp/sql-inline-${subcommand}-${hash}.sql`;\n const heredocTag = `SQL_${hash.toUpperCase()}`;\n\n const groupScript = [\n `{ cat > ${sqlPath} <<'${heredocTag}'`,\n unquotedSql,\n heredocTag,\n `sql ${subcommand} ${dbName} \"$(cat ${sqlPath})\"; }`,\n ].join('\\n');\n\n const groupAst = parse(groupScript);\n return groupAst.statements[0].pipelines[0].commands[0];\n}\n\nfunction rewriteSqlCommandsInList(\n commands: CommandNode[],\n ast: ScriptNode,\n): boolean {\n let rewritten = false;\n for (let i = 0; i < commands.length; i++) {\n const cmd = commands[i];\n if (isSqlCommandRequiringRewrite(cmd)) {\n commands[i] = rewriteSqlCommand(cmd, ast);\n rewritten = true;\n continue;\n }\n\n if (cmd.type === 'If') {\n for (const clause of cmd.clauses) {\n if (rewriteSqlCommandsInStatements(clause.condition, ast))\n rewritten = true;\n if (rewriteSqlCommandsInStatements(clause.body, ast)) rewritten = true;\n }\n if (cmd.elseBody && rewriteSqlCommandsInStatements(cmd.elseBody, ast)) {\n rewritten = true;\n }\n } else if (cmd.type === 'While' || cmd.type === 'Until') {\n if (rewriteSqlCommandsInStatements(cmd.condition, ast)) rewritten = true;\n if (rewriteSqlCommandsInStatements(cmd.body, ast)) rewritten = true;\n } else if (cmd.type === 'For' || cmd.type === 'CStyleFor') {\n if (rewriteSqlCommandsInStatements(cmd.body, ast)) rewritten = true;\n } else if (cmd.type === 'Case') {\n for (const item of cmd.items) {\n if (rewriteSqlCommandsInStatements(item.body, ast)) rewritten = true;\n }\n } else if (cmd.type === 'Subshell' || cmd.type === 'Group') {\n if (rewriteSqlCommandsInStatements(cmd.body, ast)) rewritten = true;\n }\n }\n return rewritten;\n}\n\nfunction rewriteSqlCommandsInStatements(\n statements: Array<{ pipelines: Array<{ commands: CommandNode[] }> }>,\n ast: ScriptNode,\n): boolean {\n let rewritten = false;\n for (const statement of statements) {\n for (const pipeline of statement.pipelines) {\n if (rewriteSqlCommandsInList(pipeline.commands, ast)) {\n rewritten = true;\n }\n }\n }\n return rewritten;\n}\n\nexport class SqlCommandRewritePlugin implements TransformPlugin<SqlCommandRewriteMetadata> {\n name = 'sql-command-rewrite';\n\n transform(\n context: TransformContext,\n ): TransformResult<SqlCommandRewriteMetadata> {\n const ast = context.ast;\n const rewritten = rewriteSqlCommandsInStatements(ast.statements, ast);\n return { ast, metadata: { rewritten } };\n }\n}\n", "import {\n type CreateSqlMetaHookOptions,\n createSqlMetaHook,\n} from './sql-meta-hook.ts';\nimport { repairSqlCommand } from './sql-repair.ts';\nimport { transformSqlCommand } from './sql-transform.ts';\n\nexport { createSqlMetaHook } from './sql-meta-hook.ts';\nexport type {\n CreateSqlMetaHookOptions,\n SqlCommandFormatter,\n} from './sql-meta-hook.ts';\nexport { repairSqlCommand } from './sql-repair.ts';\nexport { transformSqlCommand } from './sql-transform.ts';\n\nexport type CreateSqlCommandHooksOptions = CreateSqlMetaHookOptions;\n\nexport function createSqlCommandHooks({\n adapters,\n}: CreateSqlCommandHooksOptions) {\n const meta = createSqlMetaHook({ adapters });\n\n return {\n onBeforeBashCall: ({ command }: { command: string }) => {\n const repaired = repairSqlCommand(command);\n const transformed = transformSqlCommand(repaired);\n meta.track({ repaired, transformed });\n return { command: transformed };\n },\n onAfterBashCall: meta.onAfterBashCall,\n };\n}\n", "import type { Command, CommandContext, ExecResult } from 'just-bash';\nimport { posix } from 'node:path';\nimport { parseArgs } from 'node:util';\nimport { v7 } from 'uuid';\n\nimport {\n BashException,\n type CommandResult,\n buildSubcommandRepair,\n defineSubcommandGroup,\n repairQuotedArg,\n} from '@deepagents/context';\n\nimport { Text2Sql, Text2SqlValidationError } from './sql.ts';\n\nclass SqlCommandError extends BashException {\n readonly #subcommand: string;\n readonly #exitCode: number;\n\n constructor(subcommand: string, message: string, exitCode = 1) {\n super(message);\n this.name = 'SqlCommandError';\n this.#subcommand = subcommand;\n this.#exitCode = exitCode;\n }\n\n format(): CommandResult {\n return {\n stdout: '',\n stderr: `sql ${this.#subcommand}: ${this.message}\\n`,\n exitCode: this.#exitCode,\n };\n }\n}\n\nexport interface CreateSqlCommandOptions {\n /**\n * Default directory for `sql run` artifacts when no `--out-dir` is passed\n * and `$TEXT2SQL_OUT_DIR` is unset. Defaults to `/sql`.\n */\n outputDir?: string;\n}\n\nexport interface CreateSqlCommandResult {\n command: Command;\n repair: (raw: string) => string;\n}\n\n/**\n * Wrap a {@link Text2Sql} instance as a just-bash custom command, exposing\n * `sql run` and `sql validate` inside any sandbox that accepts\n * `customCommands` (e.g. `createVirtualSandbox`). Argv matches the standalone\n * `sql` CLI exactly, so prompts written against one work against the other.\n *\n * Bootstrap (schema indexing) is intentionally **not** exposed as a\n * subcommand here \u2014 callers running an in-process sandbox should invoke\n * `text2Sql.index()` directly on the host before constructing the sandbox.\n *\n * @example\n * ```ts\n * const text2Sql = new Text2Sql({\n * adapters: { pagila },\n * lock: new FileIndexLock(),\n * });\n * const { command } = createSqlCommand(text2Sql);\n * const sandbox = await createVirtualSandbox({\n * fs: new InMemoryFs(),\n * customCommands: [command],\n * });\n * await sandbox.executeCommand('sql run pagila \"SELECT 1\"');\n * ```\n */\nexport function createSqlCommand(\n text2Sql: Text2Sql,\n options: CreateSqlCommandOptions = {},\n): CreateSqlCommandResult {\n const defaultOutputDir = options.outputDir ?? '/sql';\n\n const subcommands = {\n run: {\n usage: 'run <db> \"SELECT ...\"',\n description: 'Execute query against <db> and store results',\n repair: repairDbNameAndQuotedArg,\n handler: (args: string[], ctx: CommandContext) =>\n handleRun(text2Sql, defaultOutputDir, args, ctx),\n },\n validate: {\n usage: 'validate <db> \"SELECT ...\"',\n description: 'Validate query syntax against <db>',\n repair: repairDbNameAndQuotedArg,\n handler: (args: string[]) => handleValidate(text2Sql, args),\n },\n };\n\n return {\n command: defineSubcommandGroup('sql', subcommands),\n repair: buildSubcommandRepair('sql', subcommands),\n };\n}\n\ninterface ParsedFlags {\n positional: string[];\n outDir?: string;\n}\n\nfunction parseFlags(subcommand: string, args: string[]): ParsedFlags {\n try {\n const parsed = parseArgs({\n args,\n options: { 'out-dir': { type: 'string' } },\n allowPositionals: true,\n strict: true,\n });\n return {\n positional: parsed.positionals,\n outDir: parsed.values['out-dir'],\n };\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error);\n throw new SqlCommandError(subcommand, message);\n }\n}\n\nfunction resolveOutputDir(\n ctx: CommandContext,\n flags: ParsedFlags,\n fallback: string,\n): string {\n const envOutDir = ctx.env.get('TEXT2SQL_OUT_DIR');\n const candidate = flags.outDir ?? envOutDir ?? fallback;\n return posix.isAbsolute(candidate)\n ? candidate\n : posix.resolve(ctx.cwd, candidate);\n}\n\nasync function handleRun(\n text2Sql: Text2Sql,\n defaultOutputDir: string,\n args: string[],\n ctx: CommandContext,\n): Promise<ExecResult> {\n return runHandler('run', async () => {\n const flags = parseFlags('run', args);\n const { name, sql } = takeDbAndSql('run', flags.positional, text2Sql);\n const outputDir = resolveOutputDir(ctx, flags, defaultOutputDir);\n const { rows, columns } = await text2Sql.run(name, sql);\n\n const outPath = posix.join(outputDir, `${v7()}.json`);\n await ctx.fs.mkdir(outputDir, { recursive: true });\n await ctx.fs.writeFile(outPath, JSON.stringify(rows, null, 2));\n\n return {\n stdout:\n `results stored in ${outPath}\\n` +\n `columns: ${columns.join(', ') || '(none)'}\\n` +\n `rows: ${rows.length}\\n`,\n stderr: '',\n exitCode: 0,\n };\n });\n}\n\nasync function handleValidate(\n text2Sql: Text2Sql,\n args: string[],\n): Promise<ExecResult> {\n return runHandler('validate', async () => {\n const flags = parseFlags('validate', args);\n const { name, sql } = takeDbAndSql('validate', flags.positional, text2Sql);\n await text2Sql.validate(name, sql);\n return { stdout: 'valid\\n', stderr: '', exitCode: 0 };\n });\n}\n\nasync function runHandler(\n subcommand: string,\n fn: () => Promise<ExecResult>,\n): Promise<ExecResult> {\n try {\n return await fn();\n } catch (error) {\n if (error instanceof BashException) return error.format();\n if (Text2SqlValidationError.isInstance(error)) {\n return new SqlCommandError(subcommand, error.message).format();\n }\n const message = error instanceof Error ? error.message : String(error);\n return new SqlCommandError(subcommand, message).format();\n }\n}\n\nfunction takeDbAndSql(\n subcommand: string,\n positional: string[],\n text2Sql: Text2Sql,\n): { name: string; sql: string } {\n const [db, ...rest] = positional;\n const name = text2Sql.resolveAdapterName(db);\n\n const sql = rest.join(' ').trim();\n if (!sql) {\n throw new SqlCommandError(subcommand, 'no query provided');\n }\n return { name, sql };\n}\n\nfunction repairDbNameAndQuotedArg(rawArgs: string): string | null {\n const trimmed = rawArgs.trim();\n if (!trimmed) return null;\n const firstSpace = trimmed.search(/\\s/);\n if (firstSpace === -1) return null;\n const dbName = trimmed.slice(0, firstSpace);\n const rest = trimmed.slice(firstSpace + 1);\n const repaired = repairQuotedArg(rest);\n if (repaired == null) return null;\n return `${dbName} ${repaired}`;\n}\n", "import { type AgentModel } from '@deepagents/agent';\nimport type { ContextFragment } from '@deepagents/context';\n\nimport {\n AdapterIndexer,\n type Text2SqlIndexProgressHandler,\n} from './adapter-index.ts';\nimport { validateAdapterNames } from './adapter-name.ts';\nimport { type Adapter } from './adapters/adapter.ts';\nimport { toSql } from './agents/sql.agent.ts';\nimport { type IndexCache } from './index-cache.ts';\nimport { type IndexLock } from './index-lock.ts';\nimport { type ExtractedPair, type PairProducer } from './synthesis/types.ts';\n\nexport interface Text2SqlConfig {\n adapters: Record<string, Adapter>;\n model?: AgentModel;\n cache?: IndexCache;\n lock: IndexLock;\n}\n\nexport interface Text2SqlRunResult {\n rows: unknown[];\n columns: string[];\n}\n\nexport interface Text2SqlIndexOptions {\n names?: readonly string[];\n onProgress?: Text2SqlIndexProgressHandler;\n}\n\nconst text2SqlValidationMarker = Symbol('Text2SqlValidationError');\nconst text2SqlUnknownAdapterMarker = Symbol('Text2SqlUnknownAdapterError');\n\nexport class Text2SqlValidationError extends Error {\n [text2SqlValidationMarker]: true;\n\n constructor(message: string) {\n super(message);\n this.name = 'Text2SqlValidationError';\n this[text2SqlValidationMarker] = true;\n }\n\n static isInstance(error: unknown): error is Text2SqlValidationError {\n return (\n error instanceof Text2SqlValidationError &&\n error[text2SqlValidationMarker] === true\n );\n }\n}\n\nexport class Text2SqlUnknownAdapterError extends Error {\n [text2SqlUnknownAdapterMarker]: true;\n readonly adapter: string;\n readonly available: readonly string[];\n\n constructor(adapter: string, available: readonly string[]) {\n const list = available.join(', ') || '(none configured)';\n super(`Unknown adapter \"${adapter}\". Available: ${list}`);\n this.name = 'Text2SqlUnknownAdapterError';\n this.adapter = adapter;\n this.available = available;\n this[text2SqlUnknownAdapterMarker] = true;\n }\n\n static isInstance(error: unknown): error is Text2SqlUnknownAdapterError {\n return (\n error instanceof Text2SqlUnknownAdapterError &&\n error[text2SqlUnknownAdapterMarker] === true\n );\n }\n}\n\nconst text2SqlUnknownDatabaseMarker = Symbol('Text2SqlUnknownDatabaseError');\n\n/**\n * Thrown by {@link Text2Sql.resolveAdapterName} when a user-supplied `<db>`\n * token cannot be routed to an adapter (unknown name, or none given when more\n * than one is configured). Carries the requested token and the available names\n * so each port (CLI, sandbox command, JSON-RPC, MCP) can render it its own way.\n */\nexport class Text2SqlUnknownDatabaseError extends Error {\n [text2SqlUnknownDatabaseMarker]: true;\n readonly requested: string | undefined;\n readonly available: readonly string[];\n\n constructor(requested: string | undefined, available: readonly string[]) {\n const list = available.join(', ') || '(none configured)';\n super(\n requested\n ? `unknown database \"${requested}\". Available: ${list}`\n : `no database specified. Available: ${list}`,\n );\n this.name = 'Text2SqlUnknownDatabaseError';\n this.requested = requested;\n this.available = available;\n this[text2SqlUnknownDatabaseMarker] = true;\n }\n\n static isInstance(error: unknown): error is Text2SqlUnknownDatabaseError {\n return (\n error instanceof Text2SqlUnknownDatabaseError &&\n error[text2SqlUnknownDatabaseMarker] === true\n );\n }\n}\n\nexport class Text2Sql {\n #config: Text2SqlConfig;\n #indexer: AdapterIndexer;\n\n constructor(config: Text2SqlConfig) {\n const adapterNames = Object.keys(config.adapters);\n if (adapterNames.length === 0) {\n throw new Error('Text2Sql requires at least one adapter');\n }\n validateAdapterNames(adapterNames);\n this.#config = config;\n this.#indexer = new AdapterIndexer({\n adapters: config.adapters,\n cache: config.cache,\n lock: config.lock,\n });\n }\n\n #requireAdapter(name: string): Adapter {\n const adapter = this.#config.adapters[name];\n if (!adapter) {\n throw new Text2SqlUnknownAdapterError(name, this.adapterNames());\n }\n return adapter;\n }\n\n #requireModel(op: string): AgentModel {\n const model = this.#config.model;\n if (!model) {\n throw new Error(`Text2Sql.${op}() requires a model in Text2SqlConfig`);\n }\n return model;\n }\n\n adapterNames(): string[] {\n return Object.keys(this.#config.adapters);\n }\n\n hasAdapter(name: string): boolean {\n return name in this.#config.adapters;\n }\n\n /**\n * Resolve a user-supplied `<db>` token to a configured adapter name for the\n * surfaces that accept one (CLI, sandbox `sql` command, JSON-RPC daemon, MCP):\n * - exact match \u2192 that name\n * - no match (or omitted) but exactly one adapter configured \u2192 route to it\n * - otherwise \u2192 throw with the user-facing \"unknown database\" message\n *\n * Internal execution paths keep using the strict {@link Text2Sql.run}/\n * {@link Text2Sql.validate}, which reject an unknown name outright.\n */\n resolveAdapterName(db: string): string {\n if (!db || db.trim() === '') {\n const names = this.adapterNames();\n if (names.length === 1) return names[0];\n throw new Text2SqlUnknownDatabaseError(db, names);\n }\n if (this.hasAdapter(db)) {\n return db;\n }\n const names = this.adapterNames();\n if (names.length === 1) return names[0];\n throw new Text2SqlUnknownDatabaseError(db, names);\n }\n\n async validate(name: string, sql: string): Promise<string> {\n const adapter = this.#requireAdapter(name);\n const result = this.#validateWith(adapter, sql);\n return result;\n }\n\n async run(name: string, sql: string): Promise<Text2SqlRunResult> {\n const adapter = this.#requireAdapter(name);\n const formatted = await this.#validateWith(adapter, sql);\n const result = await adapter.execute(formatted);\n if (!Array.isArray(result)) {\n throw new Error('adapter.execute must return an array of rows');\n }\n const columns = result.length > 0 ? Object.keys(result[0] as object) : [];\n return { rows: result, columns };\n }\n\n async #validateWith(adapter: Adapter, sql: string): Promise<string> {\n const formatted = adapter.format(sql);\n const error = await adapter.validate(formatted);\n if (error) throw new Text2SqlValidationError(error);\n return formatted;\n }\n\n async index(options: Text2SqlIndexOptions = {}): Promise<ContextFragment[]> {\n return this.#indexer.index({\n adapterNames: options.names,\n onProgress: options.onProgress,\n });\n }\n\n async toSql(input: string, adapterName: string): Promise<string> {\n const adapter = this.#requireAdapter(adapterName);\n const model = this.#requireModel('toSql');\n const fragments = await this.#indexer.indexAdapter(adapterName);\n const result = await toSql({\n input,\n adapter,\n fragments,\n model,\n });\n return result.sql;\n }\n\n async toPairs<T extends PairProducer>(\n adapterName: string,\n factory: (adapter: Adapter) => T,\n ): Promise<ExtractedPair[]> {\n const adapter = this.#requireAdapter(adapterName);\n const producer = factory(adapter);\n return producer.toPairs();\n }\n}\n", "import { type UIMessage, isToolUIPart } from 'ai';\n\nimport { type WhenPredicate, reminder } from '@deepagents/context';\n\nimport {\n type SqlQueryInvocation,\n parseSqlQueryInvocation,\n} from './sql-invocation.ts';\nimport { repairSqlCommand } from './sql-repair.ts';\n\nexport const SQL_VALIDATE_REMINDER =\n 'Always run `sql validate <db> \"...\"` before `sql run <db> \"...\"` to catch syntax errors early.';\n\nfunction extractSqlInvocation(command: unknown): SqlQueryInvocation | null {\n if (typeof command !== 'string') return null;\n return parseSqlQueryInvocation(repairSqlCommand(command));\n}\n\nfunction inputCommand(input: unknown): unknown {\n return (input as { command?: unknown } | undefined)?.command;\n}\n\n/**\n * True when a `sql validate` of the same `(db, sql)` appears in the assistant's\n * recent tool history \u2014 i.e. the model already validated this exact query. SQL\n * text is compared verbatim; a reformatted query won't match, so the nudge\n * fires again rather than being wrongly suppressed (errs toward reminding).\n */\nfunction alreadyValidated(\n messages: UIMessage[] | undefined,\n run: SqlQueryInvocation,\n): boolean {\n for (const message of messages ?? []) {\n for (const part of message.parts) {\n if (!isToolUIPart(part)) continue;\n const invocation = extractSqlInvocation(\n inputCommand((part as { input?: unknown }).input),\n );\n if (\n invocation?.subcommand === 'validate' &&\n invocation.dbName === run.dbName &&\n invocation.sql === run.sql\n ) {\n return true;\n }\n }\n }\n return false;\n}\n\n/**\n * Fires after a successful `sql run` that was NOT preceded by a `sql validate`\n * of the same query. Reads the terminal call from `ctx.toolOutcome` (only\n * populated at `target: 'tool-output'` time) and scans\n * `ctx.lastAssistantMessages` for a matching prior validate.\n */\nexport function sqlRunMissingValidate(): WhenPredicate {\n return (ctx) => {\n const call = ctx.toolOutcome;\n if (!call || call.state !== 'output-available' || call.name !== 'bash') {\n return false;\n }\n const run = extractSqlInvocation(inputCommand(call.input));\n if (run?.subcommand !== 'run') return false;\n return !alreadyValidated(ctx.lastAssistantMessages, run);\n };\n}\n\n/**\n * A context fragment nudging the model to `sql validate` before `sql run`.\n * Register it on the engine alongside schema fragments:\n *\n * ```ts\n * context.set(...schemaFragments, sqlValidateReminder());\n * ```\n *\n * Delivered as a tool-output `<system-reminder>` on the `sql run` result, and\n * suppressed when the model already validated that exact query.\n */\nexport function sqlValidateReminder() {\n return reminder(SQL_VALIDATE_REMINDER, {\n target: 'tool-output',\n when: sqlRunMissingValidate(),\n });\n}\n"],
|
|
5
|
-
"mappings": "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",
|
|
4
|
+
"sourcesContent": ["export const ADAPTER_NAME_PATTERN = /^[A-Za-z_][A-Za-z0-9_]*$/;\n\n/**\n * Tag name used to label each adapter's configured connection name inside its\n * indexed schema fragment (see `databaseNameFragment` in adapter-index.ts).\n * Reserved as an adapter name: an adapter literally named `database` would make\n * the label tag indistinguishable from the wrapper tag and render nested\n * `<database><database>\u2026</database></database>`.\n */\nexport const DATABASE_NAME_FRAGMENT = 'database';\n\nconst RESERVED_ADAPTER_NAMES = new Set<string>([DATABASE_NAME_FRAGMENT]);\n\nexport function isValidAdapterName(\n name: string | null | undefined,\n): name is string {\n return name != null && ADAPTER_NAME_PATTERN.test(name);\n}\n\nexport function validateAdapterNames(names: Iterable<string>): void {\n for (const name of names) {\n if (!isValidAdapterName(name)) {\n throw new Error(\n `Invalid adapter name \"${name}\": must match ${ADAPTER_NAME_PATTERN}`,\n );\n }\n if (RESERVED_ADAPTER_NAMES.has(name)) {\n throw new Error(`Adapter name \"${name}\" is reserved`);\n }\n }\n}\n", "import { type SqlLanguage, format as formatSql } from 'sql-formatter';\n\nimport type { ContextFragment, FragmentObject } from '@deepagents/context';\n\nimport { SQLReadOnlyError, SQLScopeError } from '../agents/exceptions.ts';\nimport {\n column,\n constraint,\n dialectInfo,\n index,\n relationship,\n table,\n view,\n} from '../fragments/schema.ts';\nimport type { AbstractGrounding } from './groundings/abstract.grounding.ts';\nimport {\n type GroundingContext,\n createGroundingContext,\n} from './groundings/context.ts';\nimport type { View } from './groundings/view.grounding.ts';\nimport {\n type SqlPolicyAnalyzer,\n type SqlPolicyViolation,\n} from './sql-policy.ts';\n\nexport {\n type SqlPolicyAnalyzer,\n type SqlPolicyContext,\n type SqlPolicyViolation,\n} from './sql-policy.ts';\n\n/**\n * Filter type for view/table names.\n * - string[]: explicit list of view names\n * - RegExp: pattern to match view names\n * - function: predicate to filter view names\n */\nexport type Filter = string[] | RegExp | ((viewName: string) => boolean);\n\nexport interface Table {\n name: string;\n schema?: string;\n rawName?: string;\n columns: {\n name: string;\n type: string;\n kind?: 'LowCardinality' | 'Enum';\n values?: string[];\n isIndexed?: boolean;\n stats?: ColumnStats;\n }[];\n rowCount?: number;\n sizeHint?: 'tiny' | 'small' | 'medium' | 'large' | 'huge';\n indexes?: TableIndex[];\n constraints?: TableConstraint[];\n}\n\nexport interface TableIndex {\n name: string;\n columns: string[];\n unique?: boolean;\n type?: string;\n}\n\nexport interface TableConstraint {\n name: string;\n type:\n 'CHECK' | 'UNIQUE' | 'NOT_NULL' | 'DEFAULT' | 'PRIMARY_KEY' | 'FOREIGN_KEY';\n columns?: string[];\n definition?: string;\n defaultValue?: string;\n referencedTable?: string;\n referencedColumns?: string[];\n}\n\nexport interface ColumnStats {\n min?: string;\n max?: string;\n nullFraction?: number;\n nDistinct?: number;\n correlation?: number;\n}\n\nexport type Relationship = {\n table: string;\n from: string[];\n referenced_table: string;\n to: string[];\n};\n\nexport type TablesFilter = string[] | RegExp;\n\nexport interface Introspection {\n tables: Table[];\n relationships: Relationship[];\n}\n\nexport interface AdapterInfo {\n dialect: string;\n version?: string;\n database?: string;\n details?: FragmentObject;\n}\n\nexport type AdapterInfoProvider =\n AdapterInfo | (() => Promise<AdapterInfo> | AdapterInfo);\n\nexport type IntrospectionPhase =\n | 'info'\n | 'tables'\n | 'views'\n | 'row_counts'\n | 'constraints'\n | 'indexes'\n | 'column_stats'\n | 'column_values'\n | 'low_cardinality'\n | 'relationships'\n | 'definitions';\n\nexport type IntrospectionProgressType =\n 'phase:start' | 'phase:progress' | 'phase:end';\n\nexport interface IntrospectionProgress {\n type: IntrospectionProgressType;\n phase: IntrospectionPhase;\n message: string;\n table?: string;\n current?: number;\n total?: number;\n timestampMs?: number;\n}\n\nexport type OnProgress = (progress: IntrospectionProgress) => void;\n\nexport type GroundingFn = (adapter: Adapter) => AbstractGrounding;\n\nexport type ExecuteFunction = (sql: string) => Promise<any> | any;\nexport type ValidateFunction = (\n sql: string,\n) => Promise<string | void> | string | void;\n\nexport abstract class Adapter {\n readonly #policyAnalyzer: SqlPolicyAnalyzer;\n\n /**\n * Injects the strategy that guards validate() and execute().\n */\n protected constructor(policyAnalyzer: SqlPolicyAnalyzer) {\n this.#policyAnalyzer = policyAnalyzer;\n }\n\n abstract grounding: GroundingFn[];\n\n abstract readonly formatterLanguage: SqlLanguage;\n\n /**\n * Default schema name for this database.\n * PostgreSQL: 'public', SQL Server: 'dbo', SQLite: undefined\n */\n abstract readonly defaultSchema: string | undefined;\n\n /**\n * System schemas to exclude from introspection by default.\n */\n abstract readonly systemSchemas: string[];\n\n /**\n * Introspect the database schema and return context fragments.\n *\n * Executes all configured groundings to populate the context, then\n * generates fragments from the complete context data.\n *\n * @param ctx - Optional grounding context for sharing state between groundings\n * @returns Array of context fragments representing the database schema\n */\n async introspect(ctx = createGroundingContext()): Promise<ContextFragment[]> {\n // Phase 1: All groundings populate ctx\n for (const fn of this.grounding) {\n const grounding = fn(this);\n if (grounding.phase) {\n ctx.onProgress({\n type: 'phase:start',\n phase: grounding.phase,\n message: `Starting ${grounding.name} introspection...`,\n });\n }\n try {\n await grounding.execute(ctx);\n } finally {\n if (grounding.phase) {\n ctx.onProgress({\n type: 'phase:end',\n phase: grounding.phase,\n message: `Finished ${grounding.name} introspection.`,\n });\n }\n }\n }\n\n // Phase 2: Generate fragments from complete ctx\n return this.#toSchemaFragments(ctx);\n }\n\n /**\n * Resolve the allowed entity names (tables + views) from grounding config.\n * Asks each grounding to contribute its entities; annotators contribute\n * nothing, so their metadata scans are skipped.\n * Results are NOT cached \u2014 call once and store the result.\n */\n async resolveAllowedEntities(): Promise<string[]> {\n const ctx = createGroundingContext();\n for (const fn of this.grounding) {\n await fn(this).contributeEntities(ctx);\n }\n return [...ctx.tables.map((t) => t.name), ...ctx.views.map((v) => v.name)];\n }\n\n /**\n * Convert complete grounding context to schema fragments.\n * Called after all groundings have populated ctx with data.\n */\n #toSchemaFragments(ctx: GroundingContext): ContextFragment[] {\n const fragments: ContextFragment[] = [];\n\n // Dialect info\n if (ctx.info) {\n fragments.push(\n dialectInfo({\n dialect: ctx.info.dialect,\n version: ctx.info.version,\n database: ctx.info.database,\n details: ctx.info.details,\n }),\n );\n }\n\n // Tables (with all annotations now included)\n for (const t of ctx.tables) {\n fragments.push(this.#tableToFragment(t));\n }\n\n // Views\n for (const v of ctx.views) {\n fragments.push(this.#viewToFragment(v));\n }\n\n // Relationships \u2014 filter out FK columns that were removed by column restriction\n const tableMap = new Map(ctx.tables.map((t) => [t.name, t]));\n const tableColumnSets = new Map(\n ctx.tables.map((t) => [t.name, new Set(t.columns.map((c) => c.name))]),\n );\n for (const rel of ctx.relationships) {\n const sourceColumns = tableColumnSets.get(rel.table);\n const targetColumns = tableColumnSets.get(rel.referenced_table);\n if (\n sourceColumns &&\n rel.from.some((column) => !sourceColumns.has(column))\n ) {\n continue;\n }\n if (\n targetColumns &&\n rel.to.some((column) => !targetColumns.has(column))\n ) {\n continue;\n }\n\n const sourceTable = tableMap.get(rel.table);\n const targetTable = tableMap.get(rel.referenced_table);\n fragments.push(\n this.#relationshipToFragment(rel, sourceTable, targetTable),\n );\n }\n\n fragments.push(...(ctx.fragments ?? []));\n\n return fragments;\n }\n\n /**\n * Convert a Table to a table fragment with nested column, index, and constraint fragments.\n */\n #tableToFragment(t: Table): ContextFragment {\n // Build constraint lookup maps for column-level annotations\n const pkConstraint = t.constraints?.find((c) => c.type === 'PRIMARY_KEY');\n const pkColumns = new Set(pkConstraint?.columns ?? []);\n\n const notNullColumns = new Set(\n t.constraints\n ?.filter((c) => c.type === 'NOT_NULL')\n .flatMap((c) => c.columns ?? []) ?? [],\n );\n\n const defaultByColumn = new Map<string, string>();\n for (const c of t.constraints?.filter((c) => c.type === 'DEFAULT') ?? []) {\n for (const col of c.columns ?? []) {\n if (c.defaultValue != null) {\n defaultByColumn.set(col, c.defaultValue);\n }\n }\n }\n\n // Single-column UNIQUE constraints\n const uniqueColumns = new Set(\n t.constraints\n ?.filter((c) => c.type === 'UNIQUE' && c.columns?.length === 1)\n .flatMap((c) => c.columns ?? []) ?? [],\n );\n\n // Foreign key lookup: column -> referenced table.column\n const fkByColumn = new Map<string, string>();\n for (const c of t.constraints?.filter((c) => c.type === 'FOREIGN_KEY') ??\n []) {\n const cols = c.columns ?? [];\n const refCols = c.referencedColumns ?? [];\n for (let i = 0; i < cols.length; i++) {\n const refCol = refCols[i] ?? refCols[0] ?? cols[i];\n fkByColumn.set(cols[i], `${c.referencedTable}.${refCol}`);\n }\n }\n\n // Build column fragments\n const columnFragments = t.columns.map((col) =>\n column({\n name: col.name,\n type: col.type,\n pk: pkColumns.has(col.name) || undefined,\n fk: fkByColumn.get(col.name),\n unique: uniqueColumns.has(col.name) || undefined,\n notNull: notNullColumns.has(col.name) || undefined,\n default: defaultByColumn.get(col.name),\n indexed: col.isIndexed || undefined,\n values: col.values,\n stats: col.stats,\n }),\n );\n\n // Set of present column names for cascade-cleaning indexes/constraints\n const presentColumns = new Set(t.columns.map((c) => c.name));\n\n // Build index fragments\n const indexFragments = (t.indexes ?? [])\n .filter((idx) =>\n idx.columns.every((column) => presentColumns.has(column)),\n )\n .map((idx) =>\n index({\n name: idx.name,\n columns: idx.columns,\n unique: idx.unique,\n type: idx.type,\n }),\n );\n\n // Build constraint fragments for multi-column UNIQUE and CHECK constraints\n const constraintFragments = (t.constraints ?? [])\n .filter(\n (c) =>\n c.type === 'CHECK' ||\n (c.type === 'UNIQUE' && (c.columns?.length ?? 0) > 1),\n )\n .filter(\n (c) =>\n !c.columns?.length ||\n c.columns.every((column) => presentColumns.has(column)),\n )\n .map((c) =>\n constraint({\n name: c.name,\n type: c.type,\n columns: c.columns,\n definition: c.definition,\n }),\n );\n\n return table({\n name: t.name,\n schema: t.schema,\n rowCount: t.rowCount,\n sizeHint: t.sizeHint,\n columns: columnFragments,\n indexes: indexFragments.length > 0 ? indexFragments : undefined,\n constraints:\n constraintFragments.length > 0 ? constraintFragments : undefined,\n });\n }\n\n /**\n * Convert a View to a view fragment with nested column fragments.\n */\n #viewToFragment(v: View): ContextFragment {\n const columnFragments = v.columns.map((col) =>\n column({\n name: col.name,\n type: col.type,\n values: col.values,\n stats: col.stats,\n }),\n );\n\n return view({\n name: v.name,\n schema: v.schema,\n columns: columnFragments,\n definition: v.definition,\n });\n }\n\n /**\n * Convert a Relationship to a relationship fragment.\n * Infers cardinality from row counts if available.\n */\n #relationshipToFragment(\n rel: Relationship,\n sourceTable?: Table,\n targetTable?: Table,\n ): ContextFragment {\n const sourceCount = sourceTable?.rowCount;\n const targetCount = targetTable?.rowCount;\n\n let cardinality:\n 'one-to-one' | 'one-to-many' | 'many-to-one' | 'many-to-many' | undefined;\n\n if (sourceCount != null && targetCount != null && targetCount > 0) {\n const ratio = sourceCount / targetCount;\n if (ratio > 5) {\n cardinality = 'many-to-one';\n } else if (ratio < 1.2 && ratio > 0.8) {\n cardinality = 'one-to-one';\n } else if (ratio < 0.2) {\n cardinality = 'one-to-many';\n }\n }\n\n return relationship({\n from: { table: rel.table, columns: rel.from },\n to: { table: rel.referenced_table, columns: rel.to },\n cardinality,\n });\n }\n format(sql: string): string {\n const decoded = this.#decodeShellEscapes(sql);\n try {\n return formatSql(decoded, { language: this.formatterLanguage });\n } catch {\n return decoded;\n }\n }\n\n #decodeShellEscapes(sql: string): string {\n return sql\n .replace(/\\\\n/g, '\\n')\n .replace(/\\\\t/g, '\\t')\n .replace(/\\\\([().*])/g, '$1')\n .replace(/\\\\(?=$)/gm, '');\n }\n\n #cachedAllowedEntities: string[] | null = null;\n\n async #resolveScope(): Promise<string[]> {\n if (this.#cachedAllowedEntities) return this.#cachedAllowedEntities;\n this.#cachedAllowedEntities = await this.resolveAllowedEntities();\n return this.#cachedAllowedEntities;\n }\n\n async #analyzePolicy(sql: string): Promise<SqlPolicyViolation | null> {\n return this.#policyAnalyzer.analyze(sql, {\n resolveAllowedEntities: () => this.#resolveScope(),\n });\n }\n\n async validate(sql: string): Promise<string | void> {\n const decoded = this.#decodeShellEscapes(sql);\n const violation = await this.#analyzePolicy(decoded);\n if (violation?.kind === 'read-only') return violation.message;\n if (violation?.kind === 'scope') return JSON.stringify(violation.payload);\n return this.validateImpl(decoded);\n }\n\n async execute(sql: string): Promise<any[]> {\n const decoded = this.#decodeShellEscapes(sql);\n const violation = await this.#analyzePolicy(decoded);\n if (violation?.kind === 'read-only') {\n throw new SQLReadOnlyError(violation.message);\n }\n if (violation?.kind === 'scope') {\n throw new SQLScopeError(violation.payload);\n }\n return this.executeImpl(decoded);\n }\n\n abstract executeImpl(sql: string): Promise<any[]> | any[];\n abstract validateImpl(sql: string): Promise<string | void> | string | void;\n abstract runQuery<Row>(sql: string): Promise<Row[]> | Row[];\n\n /**\n * Quote an identifier (table/column name) for safe use in SQL.\n * Each database uses different quoting styles.\n */\n abstract quoteIdentifier(name: string): string;\n\n /**\n * Escape a string value for safe use in SQL.\n * Each database escapes different characters.\n */\n abstract escape(value: string): string;\n\n /**\n * Build a SELECT query to sample rows from a table.\n * Each database uses different syntax for limiting rows (LIMIT vs TOP).\n */\n abstract buildSampleRowsQuery(\n tableName: string,\n columns: string[] | undefined,\n limit: number,\n ): string;\n\n /**\n * Convert unknown database value to number.\n * Handles number, bigint, and string types.\n */\n toNumber(value: unknown): number | undefined {\n if (typeof value === 'number' && Number.isFinite(value)) {\n return value;\n }\n if (typeof value === 'bigint') {\n return Number(value);\n }\n if (typeof value === 'string' && value.trim() !== '') {\n const parsed = Number(value);\n return Number.isFinite(parsed) ? parsed : undefined;\n }\n return undefined;\n }\n\n /**\n * Parse a potentially qualified table name into schema and table parts.\n */\n parseTableName(name: string): { schema: string; table: string } {\n if (name.includes('.')) {\n const [schema, ...rest] = name.split('.');\n return { schema, table: rest.join('.') };\n }\n return { schema: this.defaultSchema ?? '', table: name };\n }\n\n /**\n * Escape a string value for use in SQL string literals (single quotes).\n * Used in WHERE clauses like: WHERE name = '${escapeString(value)}'\n */\n escapeString(value: string): string {\n return value.replace(/'/g, \"''\");\n }\n\n /**\n * Build a SQL filter clause to include/exclude schemas.\n * @param columnName - The schema column name (e.g., 'TABLE_SCHEMA')\n * @param allowedSchemas - If provided, filter to these schemas only\n */\n buildSchemaFilter(columnName: string, allowedSchemas?: string[]): string {\n if (allowedSchemas && allowedSchemas.length > 0) {\n const values = allowedSchemas\n .map((s) => `'${this.escapeString(s)}'`)\n .join(', ');\n return `AND ${columnName} IN (${values})`;\n }\n if (this.systemSchemas.length > 0) {\n const values = this.systemSchemas\n .map((s) => `'${this.escapeString(s)}'`)\n .join(', ');\n return `AND ${columnName} NOT IN (${values})`;\n }\n return '';\n }\n}\n\nexport function filterTablesByName<T extends { name: string }>(\n tables: T[],\n filter: TablesFilter | undefined,\n): T[] {\n if (!filter) return tables;\n return tables.filter((table) => matchesFilter(table.name, filter));\n}\n\nexport function filterRelationshipsByTables(\n relationships: Relationship[],\n tableNames: Set<string> | undefined,\n): Relationship[] {\n if (tableNames === undefined) {\n return relationships;\n }\n if (tableNames.size === 0) {\n return [];\n }\n return relationships.filter(\n (it) => tableNames.has(it.table) || tableNames.has(it.referenced_table),\n );\n}\n\nexport function applyTablesFilter(\n tables: Table[],\n relationships: Relationship[],\n filter: TablesFilter | undefined,\n): { tables: Table[]; relationships: Relationship[] } {\n if (!filter) {\n return { tables, relationships };\n }\n\n const allowedNames = new Set(\n getTablesWithRelated(tables, relationships, filter),\n );\n\n return {\n tables: tables.filter((table) => allowedNames.has(table.name)),\n relationships: filterRelationshipsByTables(relationships, allowedNames),\n };\n}\n\nexport function matchesFilter(\n tableName: string,\n filter: TablesFilter,\n): boolean {\n if (Array.isArray(filter)) {\n return filter.includes(tableName);\n }\n return filter.test(tableName);\n}\n\nexport function getTablesWithRelated(\n allTables: Table[],\n relationships: Relationship[],\n filter: TablesFilter,\n): string[] {\n const matchedTables = filterTablesByName(allTables, filter).map(\n (it) => it.name,\n );\n\n if (matchedTables.length === 0) {\n return [];\n }\n\n const adjacency = new Map<string, Set<string>>();\n\n for (const rel of relationships) {\n if (!adjacency.has(rel.table)) {\n adjacency.set(rel.table, new Set());\n }\n if (!adjacency.has(rel.referenced_table)) {\n adjacency.set(rel.referenced_table, new Set());\n }\n adjacency.get(rel.table)!.add(rel.referenced_table);\n adjacency.get(rel.referenced_table)!.add(rel.table);\n }\n\n const result = new Set<string>(matchedTables);\n const queue = [...matchedTables];\n\n while (queue.length > 0) {\n const current = queue.shift()!;\n const neighbors = adjacency.get(current);\n\n if (!neighbors) {\n continue;\n }\n\n for (const neighbor of neighbors) {\n if (!result.has(neighbor)) {\n result.add(neighbor);\n queue.push(neighbor);\n }\n }\n }\n\n return Array.from(result);\n}\n", "const sqlValidationMarker = Symbol('SQLValidationError');\nconst unanswerableSqlMarker = Symbol('UnanswerableSQLError');\nconst sqlScopeMarker = Symbol('SQLScopeError');\nconst sqlReadOnlyMarker = Symbol('SQLReadOnlyError');\n\nexport type SQLScopeErrorType = 'OUT_OF_SCOPE' | 'SQL_SCOPE_PARSE_ERROR';\n\nexport interface SQLScopeErrorPayload {\n error: string;\n error_type: SQLScopeErrorType;\n suggestion: string;\n sql_attempted: string;\n referenced_entities?: string[];\n allowed_entities?: string[];\n parser_dialect?: string;\n parser_error?: string;\n}\n\n/**\n * Error thrown when SQL validation fails.\n */\nexport class SQLValidationError extends Error {\n [sqlValidationMarker]: true;\n\n constructor(message: string) {\n super(message);\n this.name = 'SQLValidationError';\n this[sqlValidationMarker] = true;\n }\n\n static isInstance(error: unknown): error is SQLValidationError {\n return (\n error instanceof SQLValidationError && error[sqlValidationMarker] === true\n );\n }\n}\n\n/**\n * Error thrown when the question cannot be answered with the given schema.\n */\nexport class UnanswerableSQLError extends Error {\n [unanswerableSqlMarker]: true;\n\n constructor(message: string) {\n super(message);\n this.name = 'UnanswerableSQLError';\n this[unanswerableSqlMarker] = true;\n }\n\n static isInstance(error: unknown): error is UnanswerableSQLError {\n return (\n error instanceof UnanswerableSQLError &&\n error[unanswerableSqlMarker] === true\n );\n }\n}\n\n/**\n * Error thrown when a query falls outside the grounded SQL scope.\n */\nexport class SQLScopeError extends Error {\n [sqlScopeMarker]: true;\n readonly payload: SQLScopeErrorPayload;\n readonly errorType: SQLScopeErrorType;\n\n constructor(payload: SQLScopeErrorPayload) {\n super(JSON.stringify(payload));\n this.name = 'SQLScopeError';\n this.payload = payload;\n this.errorType = payload.error_type;\n this[sqlScopeMarker] = true;\n }\n\n static isInstance(error: unknown): error is SQLScopeError {\n return error instanceof SQLScopeError && error[sqlScopeMarker] === true;\n }\n}\n\n/**\n * Error thrown when a query is not read-only (does not start with SELECT or WITH).\n */\nexport class SQLReadOnlyError extends Error {\n [sqlReadOnlyMarker]: true;\n\n constructor(message: string) {\n super(message);\n this.name = 'SQLReadOnlyError';\n this[sqlReadOnlyMarker] = true;\n }\n\n static isInstance(error: unknown): error is SQLReadOnlyError {\n return (\n error instanceof SQLReadOnlyError && error[sqlReadOnlyMarker] === true\n );\n }\n}\n", "import type { ContextFragment, FragmentObject } from '@deepagents/context';\n\n/**\n * Schema fragment builders.\n *\n * These fragments represent database schema metadata that can be injected\n * into AI prompts. Use with renderers (XML, Markdown, TOML, TOON) to format.\n *\n * @example\n * ```ts\n * import { dialectInfo, table, column, relationship } from '@deepagents/text2sql';\n *\n * const schemaFragments = [\n * dialectInfo({ dialect: 'PostgreSQL', version: '14.5' }),\n * table({\n * name: 'users',\n * columns: [\n * column({ name: 'id', type: 'integer', pk: true }),\n * column({ name: 'email', type: 'varchar', unique: true }),\n * ],\n * }),\n * ];\n * ```\n */\n\n/**\n * Database dialect and version information.\n *\n * @param input.dialect - Database type (PostgreSQL, SQLite, SQL Server, etc.)\n * @param input.version - Database version string\n * @param input.database - Database name\n *\n * @example\n * dialectInfo({ dialect: 'PostgreSQL', version: '14.5', database: 'myapp' })\n */\nexport function dialectInfo(input: {\n dialect: string;\n version?: string;\n database?: string;\n details?: FragmentObject;\n}): ContextFragment {\n return {\n name: 'dialectInfo',\n data: {\n dialect: input.dialect,\n ...(input.version && { version: input.version }),\n ...(input.database && { database: input.database }),\n ...(input.details && { details: input.details }),\n },\n };\n}\n\n/**\n * Database table with columns and optional metadata.\n *\n * @param input.name - Table name\n * @param input.schema - Schema name (e.g., 'public' for PostgreSQL)\n * @param input.rowCount - Approximate row count\n * @param input.sizeHint - Size category for query optimization hints\n * @param input.columns - Array of column() fragments\n * @param input.indexes - Array of index() fragments\n * @param input.constraints - Array of constraint() fragments\n *\n * @example\n * table({\n * name: 'users',\n * rowCount: 1500,\n * sizeHint: 'medium',\n * columns: [\n * column({ name: 'id', type: 'integer', pk: true }),\n * column({ name: 'email', type: 'varchar', unique: true, indexed: true }),\n * ],\n * indexes: [\n * index({ name: 'idx_email', columns: ['email'], unique: true }),\n * ],\n * })\n */\nexport function table(input: {\n name: string;\n schema?: string;\n rowCount?: number;\n sizeHint?: 'tiny' | 'small' | 'medium' | 'large' | 'huge';\n columns: ContextFragment[];\n indexes?: ContextFragment[];\n constraints?: ContextFragment[];\n}): ContextFragment {\n return {\n name: 'table',\n data: {\n name: input.name,\n ...(input.schema && { schema: input.schema }),\n ...(input.rowCount != null && { rowCount: input.rowCount }),\n ...(input.sizeHint && { sizeHint: input.sizeHint }),\n columns: input.columns,\n ...(input.indexes?.length && { indexes: input.indexes }),\n ...(input.constraints?.length && { constraints: input.constraints }),\n },\n };\n}\n\n/**\n * Table column with type and annotations.\n *\n * @param input.name - Column name\n * @param input.type - Column data type (e.g., 'integer', 'varchar(255)')\n * @param input.pk - Is primary key\n * @param input.fk - Foreign key reference in \"table.column\" format\n * @param input.unique - Has unique constraint\n * @param input.notNull - Has NOT NULL constraint\n * @param input.default - Default value expression\n * @param input.indexed - Has index on this column\n * @param input.values - Enum or low cardinality values\n * @param input.stats - Column statistics (min, max, null fraction)\n *\n * @example\n * column({\n * name: 'status',\n * type: 'varchar',\n * notNull: true,\n * indexed: true,\n * values: ['active', 'inactive', 'suspended'],\n * })\n */\nexport function column(input: {\n name: string;\n type: string;\n pk?: boolean;\n fk?: string;\n unique?: boolean;\n notNull?: boolean;\n default?: string;\n indexed?: boolean;\n values?: string[];\n stats?: {\n min?: string;\n max?: string;\n nullFraction?: number;\n nDistinct?: number;\n correlation?: number;\n };\n}): ContextFragment {\n return {\n name: 'column',\n data: {\n name: input.name,\n type: input.type,\n ...(input.pk && { pk: true }),\n ...(input.fk && { fk: input.fk }),\n ...(input.unique && { unique: true }),\n ...(input.notNull && { notNull: true }),\n ...(input.default && { default: input.default }),\n ...(input.indexed && { indexed: true }),\n ...(input.values?.length && { values: input.values }),\n ...(input.stats && { stats: input.stats }),\n },\n };\n}\n\n/**\n * Table index.\n *\n * @param input.name - Index name\n * @param input.columns - Columns included in the index\n * @param input.unique - Is unique index\n * @param input.type - Index type (BTREE, HASH, GIN, etc.)\n *\n * @example\n * index({ name: 'idx_user_email', columns: ['email'], unique: true, type: 'BTREE' })\n */\nexport function index(input: {\n name: string;\n columns: string[];\n unique?: boolean;\n type?: string;\n}): ContextFragment {\n return {\n name: 'index',\n data: {\n name: input.name,\n columns: input.columns,\n ...(input.unique && { unique: true }),\n ...(input.type && { type: input.type }),\n },\n };\n}\n\n/**\n * Table constraint (CHECK, UNIQUE, PRIMARY_KEY, FOREIGN_KEY, etc).\n *\n * @param input.name - Constraint name\n * @param input.type - Constraint type\n * @param input.columns - Columns involved in the constraint\n * @param input.definition - CHECK constraint SQL definition\n * @param input.defaultValue - DEFAULT constraint value\n * @param input.referencedTable - For FK: referenced table name\n * @param input.referencedColumns - For FK: referenced column names\n *\n * @example\n * constraint({\n * name: 'chk_amount_positive',\n * type: 'CHECK',\n * definition: 'amount > 0',\n * })\n *\n * @example\n * constraint({\n * name: 'fk_order_user',\n * type: 'FOREIGN_KEY',\n * columns: ['user_id'],\n * referencedTable: 'users',\n * referencedColumns: ['id'],\n * })\n */\nexport function constraint(input: {\n name: string;\n type:\n | 'CHECK'\n | 'UNIQUE'\n | 'NOT_NULL'\n | 'DEFAULT'\n | 'PRIMARY_KEY'\n | 'FOREIGN_KEY';\n columns?: string[];\n definition?: string;\n defaultValue?: string;\n referencedTable?: string;\n referencedColumns?: string[];\n}): ContextFragment {\n return {\n name: 'constraint',\n data: {\n name: input.name,\n type: input.type,\n ...(input.columns?.length && { columns: input.columns }),\n ...(input.definition && { definition: input.definition }),\n ...(input.defaultValue && { defaultValue: input.defaultValue }),\n ...(input.referencedTable && { referencedTable: input.referencedTable }),\n ...(input.referencedColumns?.length && {\n referencedColumns: input.referencedColumns,\n }),\n },\n };\n}\n\n/**\n * Database view.\n *\n * @param input.name - View name\n * @param input.schema - Schema name\n * @param input.columns - Array of column() fragments\n * @param input.definition - View SQL definition\n *\n * @example\n * view({\n * name: 'active_users',\n * columns: [\n * column({ name: 'id', type: 'integer' }),\n * column({ name: 'email', type: 'varchar' }),\n * ],\n * definition: \"SELECT id, email FROM users WHERE status = 'active'\",\n * })\n */\nexport function view(input: {\n name: string;\n schema?: string;\n columns: ContextFragment[];\n definition?: string;\n}): ContextFragment {\n return {\n name: 'view',\n data: {\n name: input.name,\n ...(input.schema && { schema: input.schema }),\n columns: input.columns,\n ...(input.definition && { definition: input.definition }),\n },\n };\n}\n\n/**\n * Relationship between tables (foreign key connection).\n *\n * @param input.from - Source table and columns\n * @param input.to - Referenced table and columns\n * @param input.cardinality - Relationship cardinality\n *\n * @example\n * relationship({\n * from: { table: 'orders', columns: ['user_id'] },\n * to: { table: 'users', columns: ['id'] },\n * cardinality: 'many-to-one',\n * })\n */\nexport function relationship(input: {\n from: { table: string; columns: string[] };\n to: { table: string; columns: string[] };\n cardinality?: 'one-to-one' | 'one-to-many' | 'many-to-one' | 'many-to-many';\n}): ContextFragment {\n return {\n name: 'relationship',\n data: {\n from: input.from,\n to: input.to,\n ...(input.cardinality && { cardinality: input.cardinality }),\n },\n };\n}\n", "import type { ContextFragment } from '@deepagents/context';\n\nimport type {\n AdapterInfo,\n ColumnStats,\n OnProgress,\n Relationship,\n Table,\n} from '../adapter.ts';\nimport type { View } from './view.grounding.ts';\n\n/**\n * Column type for grounding operations.\n * Common interface between Table.columns and View.columns.\n */\nexport interface Column {\n name: string;\n type: string;\n kind?: 'LowCardinality' | 'Enum';\n values?: string[];\n stats?: ColumnStats;\n}\n\n/**\n * Entity with columns (Table or View).\n */\nexport interface ColumnContainer {\n name: string;\n columns: Column[];\n}\n\n/**\n * Shared context object passed to all groundings.\n * Groundings read from and write to this context.\n */\nexport interface GroundingContext {\n /** Tables discovered by TableGrounding */\n tables: Table[];\n\n /** Views discovered by ViewGrounding */\n views: View[];\n\n /** Relationships discovered by TableGrounding */\n relationships: Relationship[];\n\n /** Database info collected by InfoGrounding */\n info?: AdapterInfo;\n\n /** Adapter-specific fragments contributed during grounding. */\n fragments?: ContextFragment[];\n\n /** Shared cache for cross-grounding deduplication. Keyed by `type:key`. */\n cache: Map<string, unknown>;\n\n /** Progress sink for long-running introspection work. */\n onProgress: OnProgress;\n}\n\nconst noopProgress: OnProgress = () => {};\n\nfunction timestampProgress(onProgress?: OnProgress): OnProgress {\n if (!onProgress) return noopProgress;\n return (progress) => {\n onProgress({\n ...progress,\n timestampMs: progress.timestampMs ?? Date.now(),\n });\n };\n}\n\n/**\n * Create a new empty grounding context.\n */\nexport function createGroundingContext(\n options: { onProgress?: OnProgress } = {},\n): GroundingContext {\n return {\n tables: [],\n views: [],\n relationships: [],\n info: undefined,\n fragments: [],\n cache: new Map(),\n onProgress: timestampProgress(options.onProgress),\n };\n}\n", "import { groq } from '@ai-sdk/groq';\nimport {\n APICallError,\n JSONParseError,\n NoContentGeneratedError,\n NoObjectGeneratedError,\n NoOutputGeneratedError,\n TypeValidationError,\n defaultSettingsMiddleware,\n wrapLanguageModel,\n} from 'ai';\nimport dedent from 'dedent';\nimport pRetry from 'p-retry';\nimport z from 'zod';\n\nimport { type AgentModel } from '@deepagents/agent';\nimport {\n ContextEngine,\n type ContextFragment,\n InMemoryContextStore,\n example,\n fragment,\n guardrail,\n hint,\n persona,\n policy,\n structuredOutput,\n user,\n workflow,\n} from '@deepagents/context';\n\nimport type { Adapter } from '../adapters/adapter.ts';\nimport { buildScopeParseErrorPayload } from '../sql-scope-error.ts';\nimport { SQLValidationError, UnanswerableSQLError } from './exceptions.ts';\n\nexport interface ToSqlOptions {\n /** The natural language input to convert to SQL */\n input: string;\n /** Database adapter for validation */\n adapter: Adapter;\n /** Context fragments (schema + instructions/teachings) */\n fragments: ContextFragment[];\n /** Optional model override */\n model: AgentModel;\n /** Maximum retry attempts on validation failure (default: 3) */\n maxRetries?: number;\n}\n\nexport interface ToSqlResult {\n /** The generated SQL query */\n sql: string;\n /** Number of attempts made */\n attempts: number;\n /** Validation errors encountered (if any retries occurred) */\n errors?: string[];\n}\n\n/** Temperature progression for retries: deterministic first, then increasingly exploratory */\nconst RETRY_TEMPERATURES = [0, 0.2, 0.3];\nconst SQL_AGENT_ROLE = 'Expert SQL query generator.';\nconst SQL_AGENT_OBJECTIVE = 'Generate precise SQL grounded in provided schema.';\nconst SQL_AGENT_POLICIES: ContextFragment[] = [\n fragment(\n 'schema_mapping',\n policy({\n rule: 'Translate natural language into precise SQL grounded in available schema entities.',\n }),\n hint('Preserve schema spelling exactly, including typos in column names.'),\n ),\n fragment(\n 'projection_minimality',\n policy({\n rule: 'Return only columns requested by the question; do not add helper columns unless explicitly requested.',\n }),\n policy({\n rule: 'For requests of the form \"X sorted/ordered by Y\", project X only unless Y is explicitly requested as an output field.',\n }),\n policy({\n rule: 'Prefer selecting schema columns directly without derived expressions when direct selection answers the request.',\n }),\n hint(\n 'Do not include ORDER BY, GROUP BY, or JOIN helper columns in SELECT output unless the question explicitly asks for them.',\n ),\n policy({\n rule: 'Use DISTINCT only when uniqueness is explicitly requested (for example distinct/unique/different/no duplicates).',\n }),\n hint(\n 'Do not infer DISTINCT from generic wording such as \"some\", plural nouns, or entity-set phrasing; for transactional/attendance-style tables, default to raw rows unless uniqueness is explicitly requested.',\n ),\n ),\n fragment(\n 'date_transform_safety',\n policy({\n rule: 'Do not assume VARCHAR/TEXT values are parseable dates. Avoid date extraction functions on text columns by default.',\n }),\n policy({\n rule: 'Use date-part extraction only when both conditions hold: the question explicitly asks for transformation and schema values require transformation to produce that unit.',\n }),\n hint(\n 'Do not apply SUBSTR, STRFTIME, DATE_PART, YEAR, or similar extraction functions unless the question explicitly asks for transformation and schema values require it.',\n ),\n hint(\n 'If a column already represents the requested concept (for example a stored year-like value), use the column as-is.',\n ),\n ),\n fragment(\n 'sql_minimality',\n guardrail({\n rule: 'Never hallucinate tables or columns.',\n reason: 'Schema fidelity is required.',\n action: 'Use only available schema entities.',\n }),\n guardrail({\n rule: 'Avoid unnecessary transformations and derived projections.',\n reason:\n 'Extra transformations frequently change semantics and reduce correctness.',\n action:\n 'Do not add date parsing, substring extraction, or derived columns unless explicitly required by the question or schema.',\n }),\n ),\n fragment(\n 'preflight_checklist',\n workflow({\n task: 'Final SQL preflight before returning output',\n steps: [\n 'Verify selected columns match the question and remove unrequested helper projections.',\n 'If aggregate values are used only for ranking/filtering, keep them out of SELECT unless explicitly requested.',\n 'Prefer raw schema columns over derived expressions when raw columns already satisfy the request.',\n 'If a candidate query uses STRFTIME, SUBSTR, DATE_PART, YEAR, or similar extraction on text-like columns, remove that transformation unless explicitly required by the question.',\n 'Return only schema-grounded SQL using existing tables and columns.',\n ],\n }),\n ),\n fragment(\n 'set_semantics',\n policy({\n rule: 'For questions asking where both condition A and condition B hold over an attribute, compute the intersection of qualifying sets for that attribute.',\n }),\n policy({\n rule: 'Do not force the same entity instance to satisfy both conditions unless the question explicitly requests the same person/row/entity.',\n }),\n hint(\n 'Prefer INTERSECT (or logically equivalent set-based shape) over requiring the same physical row/entity to satisfy both conditions unless explicitly requested.',\n ),\n hint(\n 'When two conditions describe different row groups whose shared attribute is requested, build each group separately and intersect the attribute values.',\n ),\n hint(\n 'Do not collapse cross-group conditions into a single-row AND predicate when the intent is shared values across groups.',\n ),\n policy({\n rule: 'If two predicates on the same field cannot both be true for one row, do not combine them with AND; use set operations across separate filtered subsets when shared values are requested.',\n }),\n ),\n fragment(\n 'predicate_column_alignment',\n policy({\n rule: 'Match literal values to semantically compatible columns. Do not compare descriptive names to identifier columns.',\n }),\n hint(\n 'When a filter value is a descriptive label (for example a department name), join through the lookup table and filter on its name/title column, not on *_id columns.',\n ),\n hint(\n 'When relation roles are explicit in wording (for example host/home/source/destination), prefer foreign keys with matching role qualifiers over generic similarly named columns.',\n ),\n policy({\n rule: 'When multiple foreign-key candidates exist, select the column whose qualifier best matches the relationship described in the question.',\n }),\n policy({\n rule: 'For hosting/held semantics, prefer host_* relationship columns when available over generic *_id alternatives.',\n }),\n hint(\n 'Interpret wording like \"held/hosted a competition or event\" as a hosting relationship and map to host_* foreign keys when present.',\n ),\n policy({\n rule: 'Do not compare descriptive labels or names to *_id columns; join to the table containing the descriptive field and filter there.',\n }),\n policy({\n rule: 'Keep numeric identifiers unquoted when used as numeric equality filters unless schema indicates text identifiers.',\n }),\n policy({\n rule: 'When filtering by a descriptive label value and a related table exposes a corresponding *_name or title column, join to that table and filter on the descriptive column.',\n }),\n ),\n fragment(\n 'ordering_semantics',\n policy({\n rule: 'Respect explicit sort direction terms. If direction is not specified, use ascending order unless a superlative intent (most/least/highest/lowest) implies direction.',\n }),\n policy({\n rule: 'When ranking categories by frequency, use COUNT for ordering but keep output focused on requested category fields unless counts are explicitly requested.',\n }),\n policy({\n rule: 'Do not use DESC unless descending direction is explicit or a superlative intent requires descending ranking.',\n }),\n policy({\n rule: 'For \"most common/frequent <attribute>\" requests, return the attribute value(s) only; use counts only for ordering/filtering unless the question explicitly asks to return counts.',\n }),\n hint(\n 'Use DESC with LIMIT 1 for \"most/highest/largest\"; use ASC with LIMIT 1 for \"least/lowest/smallest\".',\n ),\n ),\n fragment(\n 'negative_membership_queries',\n policy({\n rule: 'For requests asking entities that did not participate/host/appear in related records, prefer NOT IN or NOT EXISTS against the related foreign-key set.',\n }),\n hint(\n 'Map role-bearing relationship columns carefully (for example host_* foreign keys for hosting relationships) instead of generic IDs when role wording is explicit.',\n ),\n hint(\n 'For \"never had/never exceeded\" conditions over history tables, exclude entities via NOT IN/NOT EXISTS against the disqualifying entity-id set (often built with GROUP BY/HAVING MAX(...)).',\n ),\n ),\n fragment(\n 'join_completeness',\n policy({\n rule: 'Preserve entity-restricting joins implied by the question. Do not widen results by querying only a broader attribute table when a subset entity table is available.',\n }),\n policy({\n rule: 'If an entity term in the question maps to a table, keep that table in query scope and join to attribute tables rather than dropping the entity table.',\n }),\n hint(\n 'If the question targets a specific entity group, include that entity table and its join conditions even when selected columns come from a related table.',\n ),\n hint(\n 'When the question names an entity type and a relation table links to that entity via *_id, include the entity table in scope instead of counting only relation rows.',\n ),\n hint(\n 'Prefer INNER JOIN by default; use LEFT JOIN only when the question explicitly requests including unmatched rows or zero-related entities.',\n ),\n ),\n fragment(\n 'aggregation_exactness',\n policy({\n rule: 'Preserve requested aggregation semantics exactly: use COUNT(*) by default for total rows, use COUNT(DISTINCT ...) only when uniqueness is explicitly requested, and group by stable entity keys when computing per-entity aggregates.',\n }),\n policy({\n rule: 'For questions asking which entity has lowest/highest average of a metric, compute AVG(metric) per entity (GROUP BY entity) and rank those aggregates.',\n }),\n hint(\n 'For \"how many <entities>\" questions over relation records, default to COUNT(*) on qualifying rows unless explicit uniqueness language is present.',\n ),\n ),\n fragment(\n 'query_shape_examples',\n example({\n question:\n 'List categories ordered by how many records belong to each category.',\n answer:\n 'SELECT category FROM records GROUP BY category ORDER BY COUNT(*)',\n }),\n example({\n question:\n 'Show labels shared by rows with metric > 100 and rows with metric < 10.',\n answer:\n 'SELECT label FROM records WHERE metric > 100 INTERSECT SELECT label FROM records WHERE metric < 10',\n }),\n example({\n question: 'List locations that have not hosted any event.',\n answer:\n 'SELECT location_name FROM locations WHERE location_id NOT IN (SELECT host_location_id FROM events)',\n }),\n example({\n question: 'List the most common category across records.',\n answer:\n 'SELECT category FROM records GROUP BY category ORDER BY COUNT(*) DESC LIMIT 1',\n }),\n ),\n];\n\n/** Extract SQL from markdown fenced code block if present */\nfunction extractSql(output: string): string {\n const match = output.match(/```sql\\n?([\\s\\S]*?)```/);\n return match ? match[1].trim() : output.trim();\n}\n\nexport async function toSql(options: ToSqlOptions): Promise<ToSqlResult> {\n const { maxRetries = 3 } = options;\n\n return withRetry(\n async (attemptNumber, errors, attempts) => {\n const context = new ContextEngine({\n store: new InMemoryContextStore(),\n chatId: `sql-gen-${crypto.randomUUID()}`,\n userId: 'system',\n });\n\n context.set(\n persona({\n name: 'Freya',\n role: SQL_AGENT_ROLE,\n objective: SQL_AGENT_OBJECTIVE,\n // role: `You are a data science expert that provides well-reasoned and detailed responses.`,\n // objective: `Your task is to understand the schema and generate a valid SQL query to answer the question. You first think about the reasoning process as an internal monologue and then provide the user with the answer.`,\n }),\n ...SQL_AGENT_POLICIES,\n ...options.fragments,\n );\n\n // Add user message(s)\n if (errors.length) {\n const lastError = errors.at(-1);\n context.set(\n user(dedent`\n Answer the following question with the SQL code. Use the piece of evidence and base your answer on the database schema.\nGiven the question, the evidence and the database schema, return the SQL script that addresses the question.\n\nQuestion: ${options.input}\n`),\n UnanswerableSQLError.isInstance(lastError)\n ? user(\n `<retry_instruction>Your previous response marked the task as unanswerable. Re-evaluate using best-effort schema mapping. If the core intent is answerable with existing tables/columns, return SQL. Return error only when required core intent cannot be mapped without inventing schema elements.</retry_instruction>`,\n )\n : user(\n `<validation_error>Your previous SQL query had the following error: ${lastError?.message}. Please fix the query.</validation_error>`,\n ),\n );\n } else {\n context.set(\n user(dedent`\n Answer the following question with the SQL code. Use the piece of evidence and base your answer on the database schema.\nGiven the question, the evidence and the database schema, return the SQL script that addresses the question.\n\nQuestion: ${options.input}\n`),\n );\n }\n\n // Create structured output with schema\n const temperature =\n RETRY_TEMPERATURES[attemptNumber - 1] ??\n RETRY_TEMPERATURES[RETRY_TEMPERATURES.length - 1];\n const baseModel = options.model ?? groq('openai/gpt-oss-20b');\n const model = wrapLanguageModel({\n model: baseModel,\n middleware: defaultSettingsMiddleware({ settings: { temperature } }),\n });\n const sqlOutput = structuredOutput({\n model: model,\n context,\n schema: z.object({\n result: z.union([\n z.object({\n sql: z\n .string()\n .describe('The SQL query that answers the question'),\n reasoning: z\n .string()\n .describe('The reasoning steps taken to generate the SQL'),\n }),\n z.object({\n error: z\n .string()\n .describe(\n 'Error message explaining why the question cannot be answered with the given schema',\n ),\n }),\n ]),\n }),\n });\n\n const { result: output } = await sqlOutput.generate();\n\n const finalizeSql = async (rawSql: string): Promise<ToSqlResult> => {\n const extractedSql = extractSql(rawSql);\n const errorsOrUndefined = errors.length\n ? errors.map(formatErrorMessage)\n : undefined;\n\n if (extractedSql === '') {\n return {\n attempts,\n sql: '',\n errors: errorsOrUndefined,\n };\n }\n\n const sql = options.adapter.format(extractedSql);\n if (\n rawSql.trimStart().startsWith('```') &&\n extractedSql === rawSql.trim()\n ) {\n throw new SQLValidationError(\n JSON.stringify(\n buildScopeParseErrorPayload(\n sql,\n options.adapter.formatterLanguage,\n new Error(\n 'SQL response was fenced markdown, not executable SQL.',\n ),\n ),\n ),\n );\n }\n\n const validationError = await options.adapter.validate(sql);\n if (validationError) {\n throw new SQLValidationError(validationError);\n }\n\n return {\n attempts,\n sql,\n errors: errorsOrUndefined,\n };\n };\n\n // Handle error responses (question is unanswerable with given schema)\n if ('error' in output) {\n context.set(\n user(\n '<best_effort_fallback>Do not return unanswerable. Produce the best valid SQL query that answers the core intent using only available schema entities.</best_effort_fallback>',\n ),\n );\n const forcedSqlOutput = structuredOutput({\n model,\n context,\n schema: z.object({\n sql: z\n .string()\n .describe(\n 'Best-effort SQL query that answers the core intent using only available schema entities.',\n ),\n reasoning: z\n .string()\n .describe('Reasoning steps for best-effort schema mapping.'),\n }),\n });\n\n try {\n const forced = await forcedSqlOutput.generate();\n return await finalizeSql(forced.sql);\n } catch (error) {\n if (\n SQLValidationError.isInstance(error) ||\n APICallError.isInstance(error) ||\n JSONParseError.isInstance(error) ||\n TypeValidationError.isInstance(error) ||\n NoObjectGeneratedError.isInstance(error) ||\n NoOutputGeneratedError.isInstance(error) ||\n NoContentGeneratedError.isInstance(error)\n ) {\n throw error;\n }\n throw new UnanswerableSQLError(output.error);\n }\n }\n\n return await finalizeSql(output.sql);\n },\n { retries: maxRetries - 1 },\n );\n}\n\nfunction formatErrorMessage(error: Error) {\n if (APICallError.isInstance(error)) {\n if (error.message.startsWith('Failed to validate JSON')) {\n return `Schema validation failed: ${error.message}`;\n }\n return error.message;\n }\n if (SQLValidationError.isInstance(error)) {\n return `SQL Validation Error: ${error.message}`;\n }\n return error.message;\n}\n\nfunction isModelUnavailableError(error: unknown): boolean {\n if (!APICallError.isInstance(error)) {\n return false;\n }\n\n const message = error.message.toLowerCase();\n const responseBody = (error.responseBody ?? '').toLowerCase();\n const is404ModelError =\n error.statusCode === 404 &&\n (message.includes('model') || responseBody.includes('model_not_found'));\n const errorCode =\n typeof error.data === 'object' &&\n error.data !== null &&\n 'error' in error.data &&\n typeof error.data.error === 'object' &&\n error.data.error !== null &&\n 'code' in error.data.error &&\n typeof error.data.error.code === 'string'\n ? error.data.error.code.toLowerCase()\n : undefined;\n\n return (\n is404ModelError ||\n errorCode === 'model_not_found' ||\n responseBody.includes('\"code\":\"model_not_found\"') ||\n (message.includes('model') &&\n message.includes('does not exist or you do not have access to it'))\n );\n}\n\nasync function withRetry<T>(\n computation: (\n attemptNumber: number,\n errors: Error[],\n attempts: number,\n ) => Promise<T>,\n options: { retries: number } = { retries: 3 },\n) {\n const errors: Error[] = [];\n let attempts = 0;\n return pRetry(\n (attemptNumber) => {\n return computation(attemptNumber, errors, ++attempts);\n },\n {\n retries: options.retries,\n shouldRetry: (context) => {\n // Retry one time when the model marks query as unanswerable to recover from false positives.\n if (UnanswerableSQLError.isInstance(context.error)) {\n return false;\n // disable retryng here will also disable the forced sql generation fallback.\n // return context.attemptNumber === 0;\n }\n // Don't retry if the selected model is unavailable\n if (isModelUnavailableError(context.error)) {\n return false;\n }\n // Retry on validation errors\n if (SQLValidationError.isInstance(context.error)) {\n return true;\n }\n console.log({\n NoObjectGeneratedError: NoObjectGeneratedError.isInstance(\n context.error,\n ),\n NoOutputGeneratedError: NoOutputGeneratedError.isInstance(\n context.error,\n ),\n APICallError: APICallError.isInstance(context.error),\n JSONParseError: JSONParseError.isInstance(context.error),\n TypeValidationError: TypeValidationError.isInstance(context.error),\n NoContentGeneratedError: NoContentGeneratedError.isInstance(\n context.error,\n ),\n });\n // Retry on AI SDK errors\n return (\n APICallError.isInstance(context.error) ||\n JSONParseError.isInstance(context.error) ||\n TypeValidationError.isInstance(context.error) ||\n NoObjectGeneratedError.isInstance(context.error) ||\n NoOutputGeneratedError.isInstance(context.error) ||\n NoContentGeneratedError.isInstance(context.error)\n );\n },\n onFailedAttempt(context) {\n // console.log(\n // `Attempt ${context.attemptNumber} failed. There are ${context.retriesLeft} retries left.`,\n // );\n // console.dir(context.error, { depth: null });\n errors.push(context.error);\n },\n },\n );\n}\n", "import type { SQLScopeErrorPayload } from './agents/exceptions.ts';\n\nexport function buildScopeParseErrorPayload(\n sql: string,\n parserDialect: string,\n error: unknown,\n): SQLScopeErrorPayload {\n const parserError =\n error instanceof Error ? error.message : String(error ?? 'Unknown error');\n\n return {\n error: `SQL scope analysis failed before validation/execution: ${parserError}`,\n error_type: 'SQL_SCOPE_PARSE_ERROR',\n suggestion:\n 'Rewrite the query into simpler SQL that can be analyzed safely, or extend parser coverage for this dialect feature.',\n sql_attempted: sql,\n parser_dialect: parserDialect,\n parser_error: parserError,\n };\n}\n", "import { groq } from '@ai-sdk/groq';\nimport dedent from 'dedent';\nimport z from 'zod';\n\nimport { agent, thirdPersonPrompt } from '@deepagents/agent';\n\nimport type { Introspection } from '../adapters/adapter.ts';\nimport { databaseSchemaPrompt } from '../prompt.ts';\n\ntype SuggestionsAgentContext = {\n context?: string;\n adapterInfo?: string;\n};\ntype SuggestionsAgentOutput = {\n suggestions: {\n question: string;\n sql: string;\n businessValue: string;\n }[];\n};\n\nexport const suggestionsAgent = agent<\n SuggestionsAgentOutput,\n SuggestionsAgentContext\n>({\n name: 'text2sql-suggestions',\n model: groq('openai/gpt-oss-20b'),\n output: z.object({\n suggestions: z\n .array(\n z.object({\n question: z\n .string()\n .describe('A complex, high-impact business question.'),\n sql: z\n .string()\n .describe('The SQL statement needed to answer the question.'),\n businessValue: z\n .string()\n .describe('Why the question matters to stakeholders.'),\n }),\n )\n .min(1)\n .max(5)\n .describe('A set of up to two advanced question + SQL pairs.'),\n }),\n prompt: (state) => {\n return dedent`\n ${thirdPersonPrompt()}\n\n <identity>\n You are a senior analytics strategist who proposes ambitious business questions\n and drafts the SQL needed to answer them. You specialize in identifying ideas\n that combine multiple tables, apply segmentation or time analysis, and surface\n metrics that drive executive decisions.\n </identity>\n\n\n <instructions>\n - Recommend one or two UNIQUE questions that go beyond simple counts or listings.\n - Favor questions that require joins, aggregates, time comparisons, cohort analysis,\n or window functions.\n - For each question, explain the business reason stakeholders care about it.\n - Provide the complete SQL query that could answer the question in the given schema.\n - Keep result sets scoped with LIMIT clauses (max 50 rows) when returning raw rows.\n - Ensure table/column names match the provided schema exactly.\n - Use columns marked [LowCardinality: ...] to identify meaningful categorical filters or segmentations.\n - Leverage table [rows / size] hints to determine whether to aggregate (large tables) or inspect detailed data (tiny tables).\n - Reference PK/Indexed annotations and the Indexes list to recommend queries that use efficient join/filter paths.\n - Column annotations may expose ranges/null percentages\u2014use them to suggest realistic thresholds or quality checks.\n - Consult <relationship_examples> to anchor your recommendations in the actual join paths between tables.\n - Output only information grounded in the schema/context provided.\n </instructions>\n\n <response-format>\n Return valid JSON that satisfies the defined output schema.\n </response-format>\n `;\n },\n});\n", "import { type ContextFragment, fragment } from '@deepagents/context';\n\nimport {\n DATABASE_NAME_FRAGMENT,\n validateAdapterNames,\n} from './adapter-name.ts';\nimport {\n type Adapter,\n type IntrospectionPhase,\n type IntrospectionProgress,\n} from './adapters/adapter.ts';\nimport { createGroundingContext } from './adapters/groundings/context.ts';\nimport { type IndexCache } from './index-cache.ts';\nimport { type IndexLock } from './index-lock.ts';\n\nexport const TEXT2SQL_INDEX_PROGRESS_CHUNK = 'data-text2sql-index-progress';\n\nexport type Text2SqlIndexProgressEventType =\n | 'index:start'\n | 'index:end'\n | 'adapter:start'\n | 'adapter:end'\n | 'adapter:cache-hit'\n | 'adapter:cache-miss'\n | 'phase:start'\n | 'phase:progress'\n | 'phase:end'\n | 'adapter:error'\n | 'index:error';\n\nexport interface Text2SqlIndexProgressEvent {\n type: Text2SqlIndexProgressEventType;\n adapter?: string;\n phase?: IntrospectionPhase;\n table?: string;\n message: string;\n current?: number;\n total?: number;\n cached?: boolean;\n timestampMs?: number;\n}\n\nexport type Text2SqlIndexProgressHandler = (\n event: Text2SqlIndexProgressEvent,\n) => void;\n\nexport interface AdapterIndexerOptions {\n adapters: Record<string, Adapter>;\n cache?: IndexCache;\n lock: IndexLock;\n}\n\nexport interface AdapterIndexerIndexOptions {\n adapterNames?: readonly string[];\n onProgress?: Text2SqlIndexProgressHandler;\n}\n\nexport interface AdapterIndexerAdapterOptions {\n onProgress?: Text2SqlIndexProgressHandler;\n}\n\nconst noopProgressHandler: Text2SqlIndexProgressHandler = () => {};\n\nfunction timestampProgressHandler(\n onProgress?: Text2SqlIndexProgressHandler,\n): Text2SqlIndexProgressHandler {\n if (!onProgress) return noopProgressHandler;\n return (event) => {\n onProgress({\n ...event,\n timestampMs: event.timestampMs ?? Date.now(),\n });\n };\n}\n\n/**\n * Build a clean `<database>name</database>` leaf carrying the adapter's\n * configured connection name (the exact `<db>` value for `sql run <db>`).\n * Injected as the first child of each adapter fragment so the name the model\n * must pass is a labeled value at the top of the schema block \u2014 not just the\n * wrapper tag a small model overlooks.\n *\n * Constructed directly (not via `fragment()`, which wraps string children in an\n * array and double-nests the tag): a plain `{ name, data }` like the\n * introspected schema fragments, so it is JSON-safe and renders the name as the\n * tag's text content. `DATABASE_NAME_FRAGMENT` is reserved as an adapter name\n * (see adapter-name.ts) so the label tag can never collide with a wrapper tag.\n */\nfunction databaseNameFragment(name: string): ContextFragment {\n return { name: DATABASE_NAME_FRAGMENT, data: name };\n}\n\nexport class AdapterIndexer {\n readonly #adapters: Record<string, Adapter>;\n readonly #cache: IndexCache | undefined;\n readonly #lock: IndexLock;\n\n constructor(options: AdapterIndexerOptions) {\n const adapterNames = Object.keys(options.adapters);\n if (adapterNames.length === 0) {\n throw new Error('AdapterIndexer requires at least one adapter');\n }\n\n validateAdapterNames(adapterNames);\n this.#adapters = options.adapters;\n this.#cache = options.cache;\n this.#lock = options.lock;\n }\n\n async index(\n options: AdapterIndexerIndexOptions = {},\n ): Promise<ContextFragment[]> {\n const progress = timestampProgressHandler(options.onProgress);\n const entries = this.#resolveIndexEntries(options.adapterNames);\n\n progress({\n type: 'index:start',\n message: `Indexing ${entries.length} adapter${entries.length === 1 ? '' : 's'}...`,\n current: 0,\n total: entries.length,\n });\n\n const settled = await Promise.allSettled(\n entries.map(async ([name, adapter]) => {\n const schema = await this.#indexAdapter(name, adapter, progress);\n return fragment(name, databaseNameFragment(name), ...schema);\n }),\n );\n\n const failed = settled.find((result) => result.status === 'rejected');\n if (failed) {\n progress({\n type: 'index:error',\n message:\n failed.reason instanceof Error\n ? failed.reason.message\n : String(failed.reason),\n });\n throw failed.reason;\n }\n\n const wrapped = settled.map((result) => {\n if (result.status === 'rejected') {\n throw result.reason;\n }\n return result.value;\n });\n\n progress({\n type: 'index:end',\n message: 'Finished indexing adapters.',\n current: entries.length,\n total: entries.length,\n });\n\n return wrapped;\n }\n\n async indexAdapter(\n name: string,\n options: AdapterIndexerAdapterOptions = {},\n ): Promise<ContextFragment[]> {\n const adapter = this.#adapters[name];\n if (!adapter) {\n const available = Object.keys(this.#adapters).join(', ');\n throw new Error(`unknown adapter \"${name}\". Available: ${available}`);\n }\n\n return this.#indexAdapter(\n name,\n adapter,\n timestampProgressHandler(options.onProgress),\n );\n }\n\n async #indexAdapter(\n name: string,\n adapter: Adapter,\n progress: Text2SqlIndexProgressHandler,\n ): Promise<ContextFragment[]> {\n progress({\n type: 'adapter:start',\n adapter: name,\n message: `Indexing adapter \"${name}\"...`,\n });\n\n const cache = this.#cache;\n const key = name;\n\n const emitCacheHit = () =>\n progress({\n type: 'adapter:cache-hit',\n adapter: name,\n message: `Using cached index for adapter \"${name}\".`,\n cached: true,\n });\n const emitCacheMiss = () =>\n progress({\n type: 'adapter:cache-miss',\n adapter: name,\n message: `No cached index for adapter \"${name}\".`,\n cached: false,\n });\n\n const introspect = async () => {\n const ctx = createGroundingContext({\n onProgress: (event) => progress(adapterProgressEvent(name, event)),\n });\n const fragments = await adapter.introspect(ctx);\n await cache?.write(key, fragments);\n return fragments;\n };\n\n let servedFromCache = false;\n const populate = async () => {\n const recheck = await cache?.read(key);\n if (recheck) {\n servedFromCache = true;\n return recheck;\n }\n if (cache) emitCacheMiss();\n return introspect();\n };\n\n try {\n const cached = await cache?.read(key);\n if (cached) {\n emitCacheHit();\n progress({\n type: 'adapter:end',\n adapter: name,\n message: `Finished indexing adapter \"${name}\".`,\n cached: true,\n });\n return cached;\n }\n\n const fragments = await this.#lock.run(key, populate);\n\n if (servedFromCache) emitCacheHit();\n progress({\n type: 'adapter:end',\n adapter: name,\n message: `Finished indexing adapter \"${name}\".`,\n cached: servedFromCache,\n });\n return fragments;\n } catch (error) {\n const reason = errorMessage(error);\n progress({\n type: 'adapter:error',\n adapter: name,\n message: `Failed indexing adapter \"${name}\": ${reason}`,\n });\n throw new Error(`introspecting adapter \"${name}\": ${reason}`, {\n cause: error,\n });\n }\n }\n\n #resolveIndexEntries(\n adapterNames: readonly string[] | undefined,\n ): Array<[string, Adapter]> {\n const availableNames = Object.keys(this.#adapters);\n const requestedNames =\n adapterNames && adapterNames.length > 0\n ? [...new Set(adapterNames)]\n : availableNames;\n const available = availableNames.join(', ');\n\n return requestedNames.map((name) => {\n const adapter = this.#adapters[name];\n if (!adapter) {\n throw new Error(`unknown adapter \"${name}\". Available: ${available}`);\n }\n return [name, adapter];\n });\n }\n}\n\nfunction adapterProgressEvent(\n adapter: string,\n progress: IntrospectionProgress,\n): Text2SqlIndexProgressEvent {\n return {\n type: progress.type,\n adapter,\n phase: progress.phase,\n table: progress.table,\n message: progress.message,\n current: progress.current,\n total: progress.total,\n cached: false,\n timestampMs: progress.timestampMs,\n };\n}\n\nfunction errorMessage(error: unknown): string {\n return error instanceof Error ? error.message : String(error);\n}\n", "import { createHash, randomUUID } from 'node:crypto';\nimport { existsSync } from 'node:fs';\nimport { mkdir, readFile, rename, writeFile } from 'node:fs/promises';\nimport { tmpdir } from 'node:os';\nimport path from 'node:path';\n\nexport class FileCache {\n public path: string;\n constructor(\n watermark: string,\n extension = '.txt',\n baseDir: string = tmpdir(),\n ) {\n const hash = createHash('md5').update(watermark).digest('hex');\n this.path = path.join(baseDir, `text2sql-${hash}${extension}`);\n }\n\n async get() {\n if (existsSync(this.path)) {\n return readFile(this.path, 'utf-8');\n }\n return null;\n }\n\n async set(content: string) {\n await mkdir(path.dirname(this.path), { recursive: true });\n const tempPath = `${this.path}.${randomUUID()}.tmp`;\n await writeFile(tempPath, content, 'utf-8');\n await rename(tempPath, this.path);\n }\n}\n\nexport class JsonCache<T> extends FileCache {\n constructor(watermark: string, baseDir?: string) {\n super(watermark, '.json', baseDir);\n }\n\n async read(): Promise<T | null> {\n const content = await this.get();\n if (!content) {\n return null;\n }\n try {\n return JSON.parse(content) as T;\n } catch {\n // Corrupt or legacy cache file (e.g. a torn write on a non-atomic\n // shared volume): treat as a miss so the caller re-introspects and\n // atomically rewrites it, rather than throwing.\n return null;\n }\n }\n\n write(data: T) {\n return this.set(JSON.stringify(data));\n }\n}\n", "import type { ContextFragment } from '@deepagents/context';\n\nimport { JsonCache } from './file-cache.ts';\n\n/**\n * Stores introspected schema fragments per adapter so repeated indexing can\n * reuse them instead of re-introspecting the database.\n *\n * The package defines this contract but does not own the storage. Hosts decide\n * where the cache lives \u2014 a shared volume, Redis, S3, a database \u2014 by supplying\n * an implementation. When no cache is provided, indexing always introspects.\n *\n * `key` is a stable per-adapter identifier; the same key is reused for the same\n * adapter across processes, so a cache shared across a fleet lets one process's\n * write satisfy another's read. Pair with an\n * {@link import('./index-lock.ts').IndexLock} keyed by the same value to make\n * concurrent introspection single-flight.\n */\nexport interface IndexCache {\n read(key: string): Promise<ContextFragment[] | null>;\n write(key: string, fragments: ContextFragment[]): Promise<void>;\n}\n\nexport interface FileIndexCacheOptions {\n /** Directory the cache files live in. Defaults to the OS temp directory. */\n dir?: string;\n /**\n * Optional invalidation token folded into the cache key. Change it (e.g. a\n * deploy id or schema version) to start a fresh cache generation.\n */\n namespace?: string;\n}\n\n/**\n * File-backed {@link IndexCache} using atomic writes (temp + rename) and\n * treating an unparseable file as a miss. Point {@link FileIndexCacheOptions.dir}\n * at a shared volume to let horizontally-scaled processes share one cache.\n */\nexport class FileIndexCache implements IndexCache {\n readonly #dir: string | undefined;\n readonly #namespace: string | undefined;\n\n constructor(options: FileIndexCacheOptions = {}) {\n this.#dir = options.dir;\n this.#namespace = options.namespace;\n }\n\n read(key: string): Promise<ContextFragment[] | null> {\n return this.#cacheFor(key).read();\n }\n\n write(key: string, fragments: ContextFragment[]): Promise<void> {\n return this.#cacheFor(key).write(fragments);\n }\n\n #cacheFor(key: string): JsonCache<ContextFragment[]> {\n const watermark = this.#namespace ? `${this.#namespace}-${key}` : key;\n return new JsonCache<ContextFragment[]>(watermark, this.#dir);\n }\n}\n", "import { createHash } from 'node:crypto';\nimport { mkdir } from 'node:fs/promises';\nimport { tmpdir } from 'node:os';\nimport * as path from 'node:path';\nimport { type LockOptions, lock as acquireLock } from 'proper-lockfile';\n\n/**\n * Coordinates schema indexing across processes so that, for a given cache key,\n * only one introspection runs at a time (\"single-flight\" indexing).\n *\n * The package defines this contract and ships {@link FileIndexLock} for\n * processes that share a POSIX filesystem. Hosts that run across machines\n * without shared storage can supply an implementation backed by whatever they\n * already operate \u2014 a Redis lock, a Postgres advisory lock, a Zookeeper/etcd\n * lease, or an in-process mutex for a single-process deployment.\n */\nexport interface IndexLock {\n /**\n * Run `fn` under an exclusive lock identified by `key`.\n *\n * Implementations MUST acquire the lock (waiting if it is currently held\n * elsewhere), run `fn`, then release it \u2014 even if `fn` throws. Failure to\n * acquire the lock MUST reject: callers treat a lock-store failure as fatal\n * (fail-closed) rather than racing an unprotected introspection.\n *\n * @param key - Stable identifier for the work being guarded; the same key\n * is used for the same adapter + index version, so distinct\n * adapters lock independently.\n * @param fn - The critical section to run while the lock is held.\n * @returns The value returned by `fn`.\n */\n run<T>(key: string, fn: () => Promise<T>): Promise<T>;\n}\n\nconst DEFAULT_STALE_MS = 30_000;\nconst DEFAULT_RETRIES: LockOptions['retries'] = {\n retries: 10,\n factor: 2,\n minTimeout: 100,\n maxTimeout: 2_000,\n};\n\nexport interface FileIndexLockOptions extends Pick<\n LockOptions,\n 'stale' | 'retries'\n> {\n /**\n * Directory the lock files live in. Defaults to the OS temp directory. Point\n * it at a shared volume to serialize introspection across a fleet, alongside a\n * {@link import('./index-cache.ts').FileIndexCache} over the same volume.\n */\n dir?: string;\n /**\n * Token folded into the lock key, mirroring\n * {@link import('./index-cache.ts').FileIndexCacheOptions.namespace} so a new\n * generation locks independently of the previous one.\n */\n namespace?: string;\n}\n\n/**\n * Filesystem-backed {@link IndexLock} built on `proper-lockfile`. Processes that\n * share a POSIX filesystem (a single host, or a shared volume \u2014 NFSv4 / EFS)\n * serialize per adapter key, so pairing it with a shared\n * {@link import('./index-cache.ts').FileIndexCache} makes cross-process\n * introspection single-flight.\n *\n * A held lock auto-refreshes its mtime at `stale / 2`, so a slow introspection\n * is not mistaken for a crashed holder. Acquisition retries with backoff and,\n * once exhausted, rejects \u2014 satisfying the fail-closed requirement of\n * {@link IndexLock}.\n */\nexport class FileIndexLock implements IndexLock {\n readonly #dir: string;\n readonly #namespace: string | undefined;\n readonly #stale: LockOptions['stale'];\n readonly #retries: LockOptions['retries'];\n\n constructor(options: FileIndexLockOptions = {}) {\n this.#dir = options.dir ?? tmpdir();\n this.#namespace = options.namespace;\n this.#stale = options.stale ?? DEFAULT_STALE_MS;\n this.#retries = options.retries ?? DEFAULT_RETRIES;\n }\n\n async run<T>(key: string, fn: () => Promise<T>): Promise<T> {\n await mkdir(this.#dir, { recursive: true });\n const release = await acquireLock(this.#lockPathFor(key), {\n realpath: false,\n stale: this.#stale,\n retries: this.#retries,\n });\n try {\n return await fn();\n } finally {\n // Best-effort release: fn() has already settled (and the caller has\n // its result), so a compromised or already-released lock must not\n // surface as a failure that masks that result.\n await release().catch(() => {});\n }\n }\n\n #lockPathFor(key: string): string {\n const watermark = this.#namespace ? `${this.#namespace}-${key}` : key;\n const hash = createHash('md5').update(watermark).digest('hex');\n return path.join(this.#dir, `text2sql-lock-${hash}`);\n }\n}\n", "import { createHash } from 'node:crypto';\nimport { existsSync, readFileSync, renameSync, writeFileSync } from 'node:fs';\nimport pLimit from 'p-limit';\n\nexport interface CheckpointOptions {\n /** Path to the checkpoint file */\n path: string;\n /** Hash to detect config changes - if changed, checkpoint is invalidated */\n configHash?: string;\n}\n\n/**\n * Codec for encoding/decoding values during checkpoint operations.\n * Use this when storing objects with methods (like Teachables) that need\n * to be serialized to plain JSON and restored with their methods.\n */\nexport interface Codec<T, TSerialized = unknown> {\n /** Convert runtime value to JSON-serializable format */\n encode: (value: T) => TSerialized;\n /** Convert stored JSON back to runtime value */\n decode: (serialized: TSerialized) => T;\n}\n\ninterface PointEntry {\n inputHash: string;\n output: unknown;\n}\n\ninterface PointData {\n committed: boolean;\n entries: PointEntry[];\n}\n\ninterface CheckpointFile {\n configHash?: string;\n points: Record<string, PointData>;\n}\n\nexport class Checkpoint {\n private points: Record<string, PointData>;\n private path: string;\n private configHash: string | undefined;\n\n private constructor(\n path: string,\n configHash: string | undefined,\n points: Record<string, PointData>,\n ) {\n this.points = points;\n this.path = path;\n this.configHash = configHash;\n }\n\n /**\n * Load checkpoint from file, or return empty checkpoint if none exists.\n * Handles corrupted files and config changes gracefully.\n */\n static async load(options: CheckpointOptions): Promise<Checkpoint> {\n const { path, configHash } = options;\n\n if (existsSync(path)) {\n try {\n const content = readFileSync(path, 'utf-8');\n const file: CheckpointFile = JSON.parse(content);\n\n // Check if config changed\n if (configHash && file.configHash && file.configHash !== configHash) {\n console.log('\u26A0 Config changed, starting fresh');\n return new Checkpoint(path, configHash, {});\n }\n\n const points = file.points ?? {};\n const totalEntries = Object.values(points).reduce(\n (sum, p) => sum + p.entries.length,\n 0,\n );\n console.log(`\u2713 Resuming from checkpoint (${totalEntries} entries)`);\n return new Checkpoint(path, configHash, points);\n } catch {\n console.log('\u26A0 Checkpoint corrupted, starting fresh');\n return new Checkpoint(path, configHash, {});\n }\n }\n\n console.log('Starting new checkpoint');\n return new Checkpoint(path, configHash, {});\n }\n\n /**\n * Run a single computation with checkpointing.\n * If already completed, returns cached value.\n *\n * @param key - Unique identifier for this computation\n * @param computation - Async function that produces the value\n * @param codec - Optional codec for encoding/decoding non-primitive values\n */\n async run<T>(\n key: string,\n computation: () => Promise<T>,\n codec?: Codec<T>,\n ): Promise<T> {\n const point = this.point<T>(key);\n\n // Use fixed input hash for single-value runs\n return point.through(\n 'single',\n async () => {\n const result = await computation();\n return codec ? (codec.encode(result) as T) : result;\n },\n codec,\n );\n }\n\n /**\n * Create a resumable checkpoint point for iterative operations.\n *\n * @param step - Unique identifier for this checkpoint point\n */\n point<T>(step: string): Point<T> {\n this.points[step] ??= { committed: false, entries: [] };\n return new Point<T>(this.points[step], () => this.save());\n }\n\n /**\n * Process each input with automatic checkpointing and concurrency.\n *\n * @param step - Unique identifier for this checkpoint\n * @param inputs - Items to process\n * @param process - Function to process each input\n * @param options - Optional settings like concurrency\n * @returns All outputs (use `.flat()` if outputs are arrays)\n */\n async each<I, O>(\n step: string,\n inputs: Iterable<I>,\n process: (input: I) => Promise<O>,\n options?: { concurrency?: number },\n ): Promise<O[]> {\n const point = this.point<O>(step);\n const limit = pLimit(options?.concurrency ?? 1);\n\n const inputArray = Array.from(inputs);\n await Promise.all(\n inputArray.map((input) =>\n limit(() => point.through(input, () => process(input))),\n ),\n );\n\n await point.commit();\n return point.values();\n }\n\n /**\n * Get clean output from all completed points.\n * Single-entry points return the value directly, multi-entry return arrays.\n */\n getOutput(): Record<string, unknown> {\n const output: Record<string, unknown> = {};\n for (const [key, pointData] of Object.entries(this.points)) {\n if (pointData.entries.length === 1) {\n output[key] = pointData.entries[0].output;\n } else {\n output[key] = pointData.entries.map((e) => e.output);\n }\n }\n return output;\n }\n\n /** Get the file path where checkpoint is stored */\n getPath(): string {\n return this.path;\n }\n\n private async save(): Promise<void> {\n const file: CheckpointFile = {\n configHash: this.configHash,\n points: this.points,\n };\n const content = JSON.stringify(file, null, 2);\n\n // Atomic write: write to temp file, then rename\n const tempPath = `${this.path}.tmp`;\n writeFileSync(tempPath, content);\n renameSync(tempPath, this.path);\n }\n}\n\nfunction hash(value: unknown): string {\n return createHash('md5').update(JSON.stringify(value)).digest('hex');\n}\n\n/**\n * A checkpoint point for tracking iterative operations.\n * Uses input hashing to determine if an operation was already processed.\n */\nexport class Point<T> {\n #cache: Map<string, T>;\n private data: PointData;\n private persist: () => Promise<void>;\n\n constructor(data: PointData, persist: () => Promise<void>) {\n this.#cache = new Map(\n data.entries.map((e) => [e.inputHash, e.output as T]),\n );\n this.data = data;\n this.persist = persist;\n }\n\n /**\n * Execute computation if input wasn't processed before.\n * Returns cached output if input hash exists, otherwise executes, saves, and returns.\n */\n async through<I, O>(\n input: I,\n compute: () => Promise<O>,\n codec?: Codec<O>,\n ): Promise<O> {\n const inputHash = hash(input);\n\n if (this.#cache.has(inputHash)) {\n const cached = this.#cache.get(inputHash) as O;\n return codec ? codec.decode(cached) : cached;\n }\n\n const output = await compute();\n this.data.entries.push({ inputHash, output });\n this.#cache.set(inputHash, output as T);\n await this.persist();\n return codec ? codec.decode(output) : output;\n }\n\n /** Mark this point as complete. */\n async commit(): Promise<void> {\n this.data.committed = true;\n await this.persist();\n }\n\n /** Check if this point has been committed. */\n isCommitted(): boolean {\n return this.data.committed;\n }\n\n /** Get all outputs from this point. */\n values(): T[] {\n return this.data.entries.map((e) => e.output as T);\n }\n}\n\n/**\n * Generate a hash from a config object for checkpoint invalidation.\n * If config changes, the checkpoint will be invalidated and pipeline restarts.\n */\nexport function hashConfig(config: Record<string, unknown>): string {\n return createHash('md5').update(JSON.stringify(config)).digest('hex');\n}\n", "import type {\n CpOptions,\n FileContent,\n FsStat,\n IFileSystem,\n MkdirOptions,\n RmOptions,\n} from 'just-bash';\nimport * as path from 'node:path';\nimport { DatabaseSync } from 'node:sqlite';\n\nimport SQLITE_FS_DDL from './ddl.sqlite-fs.sql';\n\n// Types not exported from just-bash main index but defined in IFileSystem\ninterface ReadFileOptions {\n encoding?: BufferEncoding | null;\n}\n\ninterface WriteFileOptions {\n encoding?: BufferEncoding;\n}\n\ninterface DirentEntry {\n name: string;\n isFile: boolean;\n isDirectory: boolean;\n isSymbolicLink: boolean;\n}\n\n/**\n * Options for creating a SQLite filesystem.\n */\nexport interface SqliteFsOptions {\n /** Path to SQLite database file */\n dbPath: string;\n\n /**\n * Root path prefix for all operations (required).\n * All filesystem operations will be scoped under this path.\n * Use '/' for root-level storage without namespace isolation.\n *\n * @example\n * // With root: '/chat-123/results'\n * // writeFile('/file.json') \u2192 stores at '/chat-123/results/file.json'\n * // readFile('/file.json') \u2192 reads from '/chat-123/results/file.json'\n */\n root: string;\n\n /** Chunk size for large files in bytes (default: 1MB) */\n chunkSize?: number;\n}\n\ntype EntryType = 'file' | 'directory' | 'symlink';\n\ninterface FsEntryRow {\n path: string;\n type: EntryType;\n mode: number;\n size: number;\n mtime: number;\n symlinkTarget: string | null;\n}\n\ninterface ChunkRow {\n data: Uint8Array;\n}\n\n/**\n * SQLite-based filesystem implementing IFileSystem interface.\n *\n * Provides persistent storage for files and directories using SQLite.\n * Files are stored in chunks (default 1MB) to handle large files efficiently.\n *\n * Uses WAL mode and prepared statement caching for performance.\n */\nexport class SqliteFs implements IFileSystem {\n #db: DatabaseSync;\n #statements = new Map<string, ReturnType<DatabaseSync['prepare']>>();\n #chunkSize: number;\n #root: string;\n\n constructor(options: SqliteFsOptions) {\n this.#chunkSize = options.chunkSize ?? 1024 * 1024; // 1MB default\n // Normalize root; if user passes '/', treat as empty (root-level storage)\n const normalizedRoot = this.#normalizeRoot(options.root);\n this.#root = normalizedRoot === '/' ? '' : normalizedRoot;\n this.#db = new DatabaseSync(options.dbPath);\n this.#db.exec(SQLITE_FS_DDL);\n\n // Always ensure '/' exists first (for all instances sharing the DB)\n const rootSlashExists = this.#stmt(\n 'SELECT 1 FROM fs_entries WHERE path = ?',\n ).get('/');\n if (!rootSlashExists) {\n this.#stmt(\n `INSERT INTO fs_entries (path, type, mode, size, mtime)\n VALUES ('/', 'directory', 493, 0, ?)`,\n ).run(Date.now());\n }\n\n if (this.#root) {\n this.#createParentDirs(this.#root);\n\n const rootExists = this.#stmt(\n 'SELECT 1 FROM fs_entries WHERE path = ?',\n ).get(this.#root);\n if (!rootExists) {\n this.#stmt(\n `INSERT INTO fs_entries (path, type, mode, size, mtime)\n VALUES (?, 'directory', 493, 0, ?)`,\n ).run(this.#root, Date.now());\n }\n }\n }\n\n /**\n * Create parent directories for a path (used during initialization).\n * Creates all segments EXCEPT the last one (the path itself).\n */\n #createParentDirs(p: string): void {\n const segments = p.split('/').filter(Boolean);\n let currentPath = '/';\n\n for (let i = 0; i < segments.length - 1; i++) {\n currentPath = path.posix.join(currentPath, segments[i]);\n const exists = this.#stmt('SELECT 1 FROM fs_entries WHERE path = ?').get(\n currentPath,\n );\n\n if (!exists) {\n this.#stmt(\n `INSERT INTO fs_entries (path, type, mode, size, mtime)\n VALUES (?, 'directory', 493, 0, ?)`,\n ).run(currentPath, Date.now());\n }\n }\n }\n\n #stmt(sql: string): ReturnType<DatabaseSync['prepare']> {\n let stmt = this.#statements.get(sql);\n if (!stmt) {\n stmt = this.#db.prepare(sql);\n this.#statements.set(sql, stmt);\n }\n return stmt;\n }\n\n #normalizeRoot(root: string): string {\n return path.posix.resolve('/', root.trim());\n }\n\n #prefixPath(p: string): string {\n if (!this.#root) {\n return p;\n }\n // path.posix.join('/root', '/') incorrectly returns '/root/'\n if (p === '/') {\n return this.#root;\n }\n return path.posix.join(this.#root, p);\n }\n\n #unprefixPath(p: string): string {\n if (!this.#root) {\n return p;\n }\n if (p === this.#root) {\n return '/';\n }\n if (p.startsWith(this.#root + '/')) {\n return p.slice(this.#root.length) || '/';\n }\n // Should not happen unless a symlink escapes the configured root.\n // Return the best-effort canonical path to avoid breaking callers.\n return p;\n }\n\n #useTransaction<T>(fn: () => T): T {\n this.#db.exec('BEGIN TRANSACTION');\n try {\n const result = fn();\n this.#db.exec('COMMIT');\n return result;\n } catch (error) {\n this.#db.exec('ROLLBACK');\n throw error;\n }\n }\n\n #normalizePath(p: string): string {\n return path.posix.resolve('/', p);\n }\n\n #dirname(p: string): string {\n const dir = path.posix.dirname(p);\n return dir === '' ? '/' : dir;\n }\n\n #ensureParentExists(filePath: string): void {\n const parent = this.#dirname(filePath);\n const rootPath = this.#root || '/';\n if (parent === rootPath || parent === '/') return;\n\n const entry = this.#stmt('SELECT type FROM fs_entries WHERE path = ?').get(\n parent,\n ) as { type: string } | undefined;\n\n if (!entry) {\n this.#ensureParentExists(parent);\n this.#stmt(\n `INSERT INTO fs_entries (path, type, mode, size, mtime)\n VALUES (?, 'directory', 493, 0, ?)`,\n ).run(parent, Date.now());\n } else if (entry.type !== 'directory') {\n throw new Error(`mkdir: parent is not a directory: ${parent}`);\n }\n }\n\n #writeChunks(filePath: string, content: Uint8Array): void {\n this.#stmt('DELETE FROM fs_chunks WHERE path = ?').run(filePath);\n\n for (let i = 0; i < content.length; i += this.#chunkSize) {\n const chunk = content.slice(\n i,\n Math.min(i + this.#chunkSize, content.length),\n );\n this.#stmt(\n 'INSERT INTO fs_chunks (path, chunkIndex, data) VALUES (?, ?, ?)',\n ).run(filePath, Math.floor(i / this.#chunkSize), chunk);\n }\n }\n\n #readChunks(filePath: string): Uint8Array {\n const rows = this.#stmt(\n 'SELECT data FROM fs_chunks WHERE path = ? ORDER BY chunkIndex',\n ).all(filePath) as unknown as ChunkRow[];\n\n if (rows.length === 0) {\n return new Uint8Array(0);\n }\n\n const totalSize = rows.reduce((sum, row) => sum + row.data.length, 0);\n const result = new Uint8Array(totalSize);\n let offset = 0;\n\n for (const row of rows) {\n result.set(row.data, offset);\n offset += row.data.length;\n }\n\n return result;\n }\n\n #resolveSymlink(p: string, seen = new Set<string>()): string {\n if (seen.has(p)) {\n throw new Error(`readFile: circular symlink: ${p}`);\n }\n\n const entry = this.#stmt(\n 'SELECT type, symlinkTarget FROM fs_entries WHERE path = ?',\n ).get(p) as Pick<FsEntryRow, 'type' | 'symlinkTarget'> | undefined;\n\n if (!entry) {\n throw new Error(`ENOENT: no such file or directory: ${p}`);\n }\n\n if (entry.type !== 'symlink') {\n return p;\n }\n\n seen.add(p);\n const target = this.#normalizePath(\n path.posix.resolve(this.#dirname(p), entry.symlinkTarget!),\n );\n return this.#resolveSymlink(target, seen);\n }\n\n #toUint8Array(content: FileContent, encoding?: string): Uint8Array {\n if (content instanceof Uint8Array) {\n return content;\n }\n const enc = (encoding ?? 'utf8') as BufferEncoding;\n return new Uint8Array(Buffer.from(content, enc));\n }\n\n // ============================================================================\n // IFileSystem Implementation\n // ============================================================================\n\n async readFile(\n filePath: string,\n options?: ReadFileOptions | string,\n ): Promise<string> {\n const normalized = this.#normalizePath(filePath);\n const prefixed = this.#prefixPath(normalized);\n const resolved = this.#resolveSymlink(prefixed);\n\n const entry = this.#stmt('SELECT type FROM fs_entries WHERE path = ?').get(\n resolved,\n ) as Pick<FsEntryRow, 'type'> | undefined;\n\n if (!entry) {\n throw new Error(`ENOENT: no such file or directory: ${filePath}`);\n }\n if (entry.type === 'directory') {\n throw new Error(`EISDIR: illegal operation on a directory: ${filePath}`);\n }\n\n const content = this.#readChunks(resolved);\n const encoding =\n typeof options === 'string' ? options : (options?.encoding ?? 'utf8');\n return Buffer.from(content).toString(encoding as BufferEncoding);\n }\n\n async readFileBuffer(filePath: string): Promise<Uint8Array> {\n const normalized = this.#normalizePath(filePath);\n const prefixed = this.#prefixPath(normalized);\n const resolved = this.#resolveSymlink(prefixed);\n\n const entry = this.#stmt('SELECT type FROM fs_entries WHERE path = ?').get(\n resolved,\n ) as Pick<FsEntryRow, 'type'> | undefined;\n\n if (!entry) {\n throw new Error(`ENOENT: no such file or directory: ${filePath}`);\n }\n if (entry.type === 'directory') {\n throw new Error(`EISDIR: illegal operation on a directory: ${filePath}`);\n }\n\n return this.#readChunks(resolved);\n }\n\n async writeFile(\n filePath: string,\n content: FileContent,\n options?: WriteFileOptions | string,\n ): Promise<void> {\n const normalized = this.#normalizePath(filePath);\n const prefixed = this.#prefixPath(normalized);\n const encoding = typeof options === 'string' ? options : options?.encoding;\n const data = this.#toUint8Array(content, encoding);\n\n this.#useTransaction(() => {\n this.#ensureParentExists(prefixed);\n\n this.#stmt(\n `INSERT INTO fs_entries (path, type, mode, size, mtime)\n VALUES (?, 'file', 420, ?, ?)\n ON CONFLICT(path) DO UPDATE SET\n type = 'file',\n size = excluded.size,\n mtime = excluded.mtime`,\n ).run(prefixed, data.length, Date.now());\n\n this.#writeChunks(prefixed, data);\n });\n }\n\n async appendFile(\n filePath: string,\n content: FileContent,\n options?: WriteFileOptions | string,\n ): Promise<void> {\n const normalized = this.#normalizePath(filePath);\n const prefixed = this.#prefixPath(normalized);\n const encoding = typeof options === 'string' ? options : options?.encoding;\n const newData = this.#toUint8Array(content, encoding);\n\n this.#useTransaction(() => {\n this.#ensureParentExists(prefixed);\n\n const entry = this.#stmt(\n 'SELECT type FROM fs_entries WHERE path = ?',\n ).get(prefixed) as Pick<FsEntryRow, 'type'> | undefined;\n\n if (entry && entry.type !== 'file') {\n throw new Error(`appendFile: not a file: ${filePath}`);\n }\n\n const existing = entry ? this.#readChunks(prefixed) : new Uint8Array(0);\n const combined = new Uint8Array(existing.length + newData.length);\n combined.set(existing, 0);\n combined.set(newData, existing.length);\n\n this.#stmt(\n `INSERT INTO fs_entries (path, type, mode, size, mtime)\n VALUES (?, 'file', 420, ?, ?)\n ON CONFLICT(path) DO UPDATE SET\n size = excluded.size,\n mtime = excluded.mtime`,\n ).run(prefixed, combined.length, Date.now());\n\n this.#writeChunks(prefixed, combined);\n });\n }\n\n async exists(filePath: string): Promise<boolean> {\n const normalized = this.#normalizePath(filePath);\n const prefixed = this.#prefixPath(normalized);\n const row = this.#stmt('SELECT 1 FROM fs_entries WHERE path = ?').get(\n prefixed,\n );\n return row !== undefined;\n }\n\n async stat(filePath: string): Promise<FsStat> {\n const normalized = this.#normalizePath(filePath);\n const prefixed = this.#prefixPath(normalized);\n const resolved = this.#resolveSymlink(prefixed);\n\n const entry = this.#stmt('SELECT * FROM fs_entries WHERE path = ?').get(\n resolved,\n ) as FsEntryRow | undefined;\n\n if (!entry) {\n throw new Error(`ENOENT: no such file or directory: ${filePath}`);\n }\n\n return {\n isFile: entry.type === 'file',\n isDirectory: entry.type === 'directory',\n isSymbolicLink: false, // stat follows symlinks\n mode: entry.mode,\n size: entry.size,\n mtime: new Date(entry.mtime),\n };\n }\n\n async lstat(filePath: string): Promise<FsStat> {\n const normalized = this.#normalizePath(filePath);\n const prefixed = this.#prefixPath(normalized);\n\n const entry = this.#stmt('SELECT * FROM fs_entries WHERE path = ?').get(\n prefixed,\n ) as FsEntryRow | undefined;\n\n if (!entry) {\n throw new Error(`ENOENT: no such file or directory: ${filePath}`);\n }\n\n return {\n isFile: entry.type === 'file',\n isDirectory: entry.type === 'directory',\n isSymbolicLink: entry.type === 'symlink',\n mode: entry.mode,\n size: entry.size,\n mtime: new Date(entry.mtime),\n };\n }\n\n async mkdir(dirPath: string, options?: MkdirOptions): Promise<void> {\n const normalized = this.#normalizePath(dirPath);\n const prefixed = this.#prefixPath(normalized);\n\n const existing = this.#stmt(\n 'SELECT type FROM fs_entries WHERE path = ?',\n ).get(prefixed) as Pick<FsEntryRow, 'type'> | undefined;\n\n if (existing) {\n if (options?.recursive) {\n return; // Already exists, ok for recursive\n }\n throw new Error(`EEXIST: file already exists: ${dirPath}`);\n }\n\n this.#useTransaction(() => {\n if (options?.recursive) {\n const rootPath = this.#root || '/';\n const relativePath = path.posix.relative(rootPath, prefixed);\n const segments = relativePath.split('/').filter(Boolean);\n let currentPath = rootPath;\n\n for (const segment of segments) {\n currentPath = path.posix.join(currentPath, segment);\n const exists = this.#stmt(\n 'SELECT type FROM fs_entries WHERE path = ?',\n ).get(currentPath) as Pick<FsEntryRow, 'type'> | undefined;\n\n if (!exists) {\n this.#stmt(\n `INSERT INTO fs_entries (path, type, mode, size, mtime)\n VALUES (?, 'directory', 493, 0, ?)`,\n ).run(currentPath, Date.now());\n } else if (exists.type !== 'directory') {\n throw new Error(`mkdir: not a directory: ${currentPath}`);\n }\n }\n } else {\n // Non-recursive: parent must exist\n const parent = this.#dirname(prefixed);\n const parentEntry = this.#stmt(\n 'SELECT type FROM fs_entries WHERE path = ?',\n ).get(parent) as Pick<FsEntryRow, 'type'> | undefined;\n\n if (!parentEntry) {\n throw new Error(`mkdir: parent does not exist: ${parent}`);\n }\n if (parentEntry.type !== 'directory') {\n throw new Error(`mkdir: parent is not a directory: ${parent}`);\n }\n\n this.#stmt(\n `INSERT INTO fs_entries (path, type, mode, size, mtime)\n VALUES (?, 'directory', 493, 0, ?)`,\n ).run(prefixed, Date.now());\n }\n });\n }\n\n async readdir(dirPath: string): Promise<string[]> {\n const normalized = this.#normalizePath(dirPath);\n const prefixed = this.#prefixPath(normalized);\n const resolved = this.#resolveSymlink(prefixed);\n\n const entry = this.#stmt('SELECT type FROM fs_entries WHERE path = ?').get(\n resolved,\n ) as Pick<FsEntryRow, 'type'> | undefined;\n\n if (!entry) {\n throw new Error(`ENOENT: no such file or directory: ${dirPath}`);\n }\n if (entry.type !== 'directory') {\n throw new Error(`ENOTDIR: not a directory: ${dirPath}`);\n }\n\n // Get direct children (path starts with dir/ but doesn't have another / after)\n const prefix = resolved === '/' ? '/' : resolved + '/';\n const rows = this.#stmt(\n `SELECT path FROM fs_entries\n WHERE path LIKE ? || '%'\n AND path != ?\n AND path NOT LIKE ? || '%/%'`,\n ).all(prefix, resolved, prefix) as { path: string }[];\n\n return rows.map((row) => path.posix.basename(row.path));\n }\n\n async readdirWithFileTypes(dirPath: string): Promise<DirentEntry[]> {\n const normalized = this.#normalizePath(dirPath);\n const prefixed = this.#prefixPath(normalized);\n const resolved = this.#resolveSymlink(prefixed);\n\n const entry = this.#stmt('SELECT type FROM fs_entries WHERE path = ?').get(\n resolved,\n ) as Pick<FsEntryRow, 'type'> | undefined;\n\n if (!entry) {\n throw new Error(`ENOENT: no such file or directory: ${dirPath}`);\n }\n if (entry.type !== 'directory') {\n throw new Error(`ENOTDIR: not a directory: ${dirPath}`);\n }\n\n const prefix = resolved === '/' ? '/' : resolved + '/';\n const rows = this.#stmt(\n `SELECT path, type FROM fs_entries\n WHERE path LIKE ? || '%'\n AND path != ?\n AND path NOT LIKE ? || '%/%'`,\n ).all(prefix, resolved, prefix) as Pick<FsEntryRow, 'path' | 'type'>[];\n\n return rows.map((row) => ({\n name: path.posix.basename(row.path),\n isFile: row.type === 'file',\n isDirectory: row.type === 'directory',\n isSymbolicLink: row.type === 'symlink',\n }));\n }\n\n async rm(filePath: string, options?: RmOptions): Promise<void> {\n const normalized = this.#normalizePath(filePath);\n const prefixed = this.#prefixPath(normalized);\n\n const entry = this.#stmt('SELECT type FROM fs_entries WHERE path = ?').get(\n prefixed,\n ) as Pick<FsEntryRow, 'type'> | undefined;\n\n if (!entry) {\n if (options?.force) {\n return;\n }\n throw new Error(`ENOENT: no such file or directory: ${filePath}`);\n }\n\n this.#useTransaction(() => {\n if (entry.type === 'directory') {\n const children = this.#stmt(\n `SELECT 1 FROM fs_entries WHERE path LIKE ? || '/%' LIMIT 1`,\n ).get(prefixed);\n\n if (children && !options?.recursive) {\n throw new Error(`ENOTEMPTY: directory not empty: ${filePath}`);\n }\n\n // Chunks cascade via FK\n this.#stmt(\n `DELETE FROM fs_entries WHERE path = ? OR path LIKE ? || '/%'`,\n ).run(prefixed, prefixed);\n } else {\n this.#stmt('DELETE FROM fs_entries WHERE path = ?').run(prefixed);\n }\n });\n }\n\n async cp(src: string, dest: string, options?: CpOptions): Promise<void> {\n const srcNormalized = this.#normalizePath(src);\n const destNormalized = this.#normalizePath(dest);\n const srcPrefixed = this.#prefixPath(srcNormalized);\n const destPrefixed = this.#prefixPath(destNormalized);\n\n const srcEntry = this.#stmt('SELECT * FROM fs_entries WHERE path = ?').get(\n srcPrefixed,\n ) as FsEntryRow | undefined;\n\n if (!srcEntry) {\n throw new Error(`ENOENT: no such file or directory: ${src}`);\n }\n\n if (srcEntry.type === 'directory' && !options?.recursive) {\n throw new Error(`cp: -r not specified; omitting directory: ${src}`);\n }\n\n this.#useTransaction(() => {\n this.#ensureParentExists(destPrefixed);\n\n if (srcEntry.type === 'directory') {\n const allEntries = this.#stmt(\n `SELECT * FROM fs_entries WHERE path = ? OR path LIKE ? || '/%'`,\n ).all(srcPrefixed, srcPrefixed) as unknown as FsEntryRow[];\n\n for (const entry of allEntries) {\n const relativePath = path.posix.relative(srcPrefixed, entry.path);\n const newPath = path.posix.join(destPrefixed, relativePath);\n\n this.#stmt(\n `INSERT OR REPLACE INTO fs_entries (path, type, mode, size, mtime, symlinkTarget)\n VALUES (?, ?, ?, ?, ?, ?)`,\n ).run(\n newPath,\n entry.type,\n entry.mode,\n entry.size,\n Date.now(),\n entry.symlinkTarget,\n );\n\n if (entry.type === 'file') {\n const chunks = this.#stmt(\n 'SELECT chunkIndex, data FROM fs_chunks WHERE path = ?',\n ).all(entry.path) as { chunkIndex: number; data: Uint8Array }[];\n\n for (const chunk of chunks) {\n this.#stmt(\n 'INSERT INTO fs_chunks (path, chunkIndex, data) VALUES (?, ?, ?)',\n ).run(newPath, chunk.chunkIndex, chunk.data);\n }\n }\n }\n } else {\n this.#stmt(\n `INSERT OR REPLACE INTO fs_entries (path, type, mode, size, mtime, symlinkTarget)\n VALUES (?, ?, ?, ?, ?, ?)`,\n ).run(\n destPrefixed,\n srcEntry.type,\n srcEntry.mode,\n srcEntry.size,\n Date.now(),\n srcEntry.symlinkTarget,\n );\n\n if (srcEntry.type === 'file') {\n const chunks = this.#stmt(\n 'SELECT chunkIndex, data FROM fs_chunks WHERE path = ?',\n ).all(srcPrefixed) as { chunkIndex: number; data: Uint8Array }[];\n\n this.#stmt('DELETE FROM fs_chunks WHERE path = ?').run(destPrefixed);\n\n for (const chunk of chunks) {\n this.#stmt(\n 'INSERT INTO fs_chunks (path, chunkIndex, data) VALUES (?, ?, ?)',\n ).run(destPrefixed, chunk.chunkIndex, chunk.data);\n }\n }\n }\n });\n }\n\n async mv(src: string, dest: string): Promise<void> {\n const srcNormalized = this.#normalizePath(src);\n const destNormalized = this.#normalizePath(dest);\n const srcPrefixed = this.#prefixPath(srcNormalized);\n const destPrefixed = this.#prefixPath(destNormalized);\n\n const srcEntry = this.#stmt('SELECT * FROM fs_entries WHERE path = ?').get(\n srcPrefixed,\n ) as FsEntryRow | undefined;\n\n if (!srcEntry) {\n throw new Error(`ENOENT: no such file or directory: ${src}`);\n }\n\n this.#useTransaction(() => {\n this.#ensureParentExists(destPrefixed);\n\n if (srcEntry.type === 'directory') {\n // Reverse order: children before parents for delete\n const allEntries = this.#stmt(\n `SELECT * FROM fs_entries WHERE path = ? OR path LIKE ? || '/%' ORDER BY path DESC`,\n ).all(srcPrefixed, srcPrefixed) as unknown as FsEntryRow[];\n\n for (const entry of [...allEntries].reverse()) {\n const relativePath = path.posix.relative(srcPrefixed, entry.path);\n const newPath = path.posix.join(destPrefixed, relativePath);\n\n this.#stmt(\n `INSERT INTO fs_entries (path, type, mode, size, mtime, symlinkTarget)\n VALUES (?, ?, ?, ?, ?, ?)`,\n ).run(\n newPath,\n entry.type,\n entry.mode,\n entry.size,\n Date.now(),\n entry.symlinkTarget,\n );\n\n if (entry.type === 'file') {\n const chunks = this.#stmt(\n 'SELECT chunkIndex, data FROM fs_chunks WHERE path = ?',\n ).all(entry.path) as unknown as {\n chunkIndex: number;\n data: Uint8Array;\n }[];\n\n for (const chunk of chunks) {\n this.#stmt(\n 'INSERT INTO fs_chunks (path, chunkIndex, data) VALUES (?, ?, ?)',\n ).run(newPath, chunk.chunkIndex, chunk.data);\n }\n }\n }\n\n // Chunks cascade via FK\n this.#stmt(\n `DELETE FROM fs_entries WHERE path = ? OR path LIKE ? || '/%'`,\n ).run(srcPrefixed, srcPrefixed);\n } else {\n this.#stmt(\n `INSERT INTO fs_entries (path, type, mode, size, mtime, symlinkTarget)\n VALUES (?, ?, ?, ?, ?, ?)`,\n ).run(\n destPrefixed,\n srcEntry.type,\n srcEntry.mode,\n srcEntry.size,\n Date.now(),\n srcEntry.symlinkTarget,\n );\n\n if (srcEntry.type === 'file') {\n const chunks = this.#stmt(\n 'SELECT chunkIndex, data FROM fs_chunks WHERE path = ?',\n ).all(srcPrefixed) as unknown as {\n chunkIndex: number;\n data: Uint8Array;\n }[];\n\n for (const chunk of chunks) {\n this.#stmt(\n 'INSERT INTO fs_chunks (path, chunkIndex, data) VALUES (?, ?, ?)',\n ).run(destPrefixed, chunk.chunkIndex, chunk.data);\n }\n }\n\n this.#stmt('DELETE FROM fs_entries WHERE path = ?').run(srcPrefixed);\n }\n });\n }\n\n resolvePath(base: string, relativePath: string): string {\n return path.posix.resolve(base, relativePath);\n }\n\n getAllPaths(): string[] {\n const rows = this.#stmt(\n 'SELECT path FROM fs_entries ORDER BY path',\n ).all() as {\n path: string;\n }[];\n return rows.map((row) => row.path);\n }\n\n async realpath(filePath: string): Promise<string> {\n const normalized = this.#normalizePath(filePath);\n const prefixed = this.#prefixPath(normalized);\n const resolved = this.#resolveSymlink(prefixed);\n\n const exists = this.#stmt('SELECT 1 FROM fs_entries WHERE path = ?').get(\n resolved,\n );\n if (!exists) {\n throw new Error(`ENOENT: no such file or directory: ${filePath}`);\n }\n\n return this.#unprefixPath(resolved);\n }\n\n async utimes(filePath: string, _atime: Date, mtime: Date): Promise<void> {\n const normalized = this.#normalizePath(filePath);\n const prefixed = this.#prefixPath(normalized);\n const resolved = this.#resolveSymlink(prefixed);\n\n const result = this.#stmt(\n 'UPDATE fs_entries SET mtime = ? WHERE path = ?',\n ).run(mtime.getTime(), resolved);\n\n if (result.changes === 0) {\n throw new Error(`ENOENT: no such file or directory: ${filePath}`);\n }\n }\n\n async chmod(filePath: string, mode: number): Promise<void> {\n const normalized = this.#normalizePath(filePath);\n const prefixed = this.#prefixPath(normalized);\n\n const result = this.#stmt(\n 'UPDATE fs_entries SET mode = ? WHERE path = ?',\n ).run(mode, prefixed);\n\n if (result.changes === 0) {\n throw new Error(`ENOENT: no such file or directory: ${filePath}`);\n }\n }\n\n async symlink(target: string, linkPath: string): Promise<void> {\n const normalized = this.#normalizePath(linkPath);\n const prefixed = this.#prefixPath(normalized);\n\n const existing = this.#stmt('SELECT 1 FROM fs_entries WHERE path = ?').get(\n prefixed,\n );\n if (existing) {\n throw new Error(`EEXIST: file already exists: ${linkPath}`);\n }\n\n this.#useTransaction(() => {\n this.#ensureParentExists(prefixed);\n\n this.#stmt(\n `INSERT INTO fs_entries (path, type, mode, size, mtime, symlinkTarget)\n VALUES (?, 'symlink', 511, 0, ?, ?)`,\n ).run(prefixed, Date.now(), target);\n });\n }\n\n async link(existingPath: string, newPath: string): Promise<void> {\n const srcNormalized = this.#normalizePath(existingPath);\n const destNormalized = this.#normalizePath(newPath);\n const srcPrefixed = this.#prefixPath(srcNormalized);\n const destPrefixed = this.#prefixPath(destNormalized);\n\n const srcEntry = this.#stmt('SELECT * FROM fs_entries WHERE path = ?').get(\n srcPrefixed,\n ) as FsEntryRow | undefined;\n\n if (!srcEntry) {\n throw new Error(`ENOENT: no such file or directory: ${existingPath}`);\n }\n\n if (srcEntry.type !== 'file') {\n throw new Error(`link: not supported for directories: ${existingPath}`);\n }\n\n const existing = this.#stmt('SELECT 1 FROM fs_entries WHERE path = ?').get(\n destPrefixed,\n );\n if (existing) {\n throw new Error(`EEXIST: file already exists: ${newPath}`);\n }\n\n // Hard link: duplicate the entry and chunks\n this.#useTransaction(() => {\n this.#ensureParentExists(destPrefixed);\n\n this.#stmt(\n `INSERT INTO fs_entries (path, type, mode, size, mtime)\n VALUES (?, 'file', ?, ?, ?)`,\n ).run(destPrefixed, srcEntry.mode, srcEntry.size, Date.now());\n\n const chunks = this.#stmt(\n 'SELECT chunkIndex, data FROM fs_chunks WHERE path = ?',\n ).all(srcPrefixed) as { chunkIndex: number; data: Uint8Array }[];\n\n for (const chunk of chunks) {\n this.#stmt(\n 'INSERT INTO fs_chunks (path, chunkIndex, data) VALUES (?, ?, ?)',\n ).run(destPrefixed, chunk.chunkIndex, chunk.data);\n }\n });\n }\n\n async readlink(linkPath: string): Promise<string> {\n const normalized = this.#normalizePath(linkPath);\n const prefixed = this.#prefixPath(normalized);\n\n const entry = this.#stmt(\n 'SELECT type, symlinkTarget FROM fs_entries WHERE path = ?',\n ).get(prefixed) as Pick<FsEntryRow, 'type' | 'symlinkTarget'> | undefined;\n\n if (!entry) {\n throw new Error(`ENOENT: no such file or directory: ${linkPath}`);\n }\n\n if (entry.type !== 'symlink') {\n throw new Error(`readlink: not a symbolic link: ${linkPath}`);\n }\n\n return entry.symlinkTarget!;\n }\n}\n", "-- SQLite-based filesystem schema for artifact storage\n-- Tables: fs_entries (file/directory metadata), fs_chunks (file content)\n\n-- Performance PRAGMAs (session-level, run on each connection)\nPRAGMA journal_mode = WAL;\nPRAGMA synchronous = NORMAL;\nPRAGMA cache_size = -64000;\nPRAGMA temp_store = MEMORY;\nPRAGMA mmap_size = 268435456;\n\n-- Integrity\nPRAGMA foreign_keys = ON;\n\n-- Filesystem entries table (files, directories, symlinks)\nCREATE TABLE IF NOT EXISTS fs_entries (\n path TEXT PRIMARY KEY, -- Normalized absolute path (e.g., '/results/uuid.json')\n type TEXT NOT NULL, -- 'file' | 'directory' | 'symlink'\n mode INTEGER NOT NULL, -- Unix permissions (e.g., 0o644 = 420)\n size INTEGER NOT NULL, -- File size in bytes (0 for directories)\n mtime INTEGER NOT NULL, -- Modified time (milliseconds since epoch)\n symlinkTarget TEXT -- Target path for symlinks (NULL for files/dirs)\n);\n\nCREATE INDEX IF NOT EXISTS idx_fs_entries_type ON fs_entries(type);\n\n-- File content chunks table (for handling large files)\n-- Files are split into 1MB chunks to avoid SQLite BLOB performance issues\nCREATE TABLE IF NOT EXISTS fs_chunks (\n path TEXT NOT NULL, -- Reference to fs_entries.path\n chunkIndex INTEGER NOT NULL, -- 0-based chunk sequence\n data BLOB NOT NULL, -- Chunk content (up to 1MB default)\n PRIMARY KEY (path, chunkIndex),\n FOREIGN KEY (path) REFERENCES fs_entries(path) ON DELETE CASCADE ON UPDATE CASCADE\n);\n", "import type {\n CpOptions,\n FileContent,\n FsStat,\n IFileSystem,\n MkdirOptions,\n RmOptions,\n} from 'just-bash';\nimport type { ConnectionPool, Transaction, config } from 'mssql';\nimport { createRequire } from 'node:module';\nimport * as path from 'node:path';\n\nimport { mssqlFsDDL } from './ddl.mssql-fs.ts';\n\ninterface ReadFileOptions {\n encoding?: BufferEncoding | null;\n}\n\ninterface WriteFileOptions {\n encoding?: BufferEncoding;\n}\n\ninterface DirentEntry {\n name: string;\n isFile: boolean;\n isDirectory: boolean;\n isSymbolicLink: boolean;\n}\n\nexport interface MssqlFsOptions {\n /** SQL Server connection pool or configuration. Can be a connection string, config object, or existing ConnectionPool. */\n pool: config | string | ConnectionPool;\n /** Root path prefix for all operations */\n root: string;\n /** Chunk size for large files in bytes (default: 1MB) */\n chunkSize?: number;\n /**\n * SQL Server schema to scope all tables under.\n * Defaults to 'dbo'.\n */\n schema?: string;\n}\n\ntype EntryType = 'file' | 'directory' | 'symlink';\n\ninterface FsEntryRow {\n path: string;\n type: EntryType;\n mode: number;\n size: number;\n mtime: number;\n symlinkTarget: string | null;\n [key: string]: unknown;\n}\n\ninterface ChunkRow {\n data: Buffer;\n [key: string]: unknown;\n}\n\nexport class MssqlFs implements IFileSystem {\n #pool: ConnectionPool;\n #chunkSize: number;\n #root: string;\n #schema: string;\n #ownsPool: boolean;\n #isInitialized = false;\n\n constructor(options: MssqlFsOptions) {\n this.#chunkSize = options.chunkSize ?? 1024 * 1024;\n const schema = options.schema ?? 'dbo';\n if (!/^[a-zA-Z_]\\w*$/.test(schema)) {\n throw new Error(`Invalid schema name: \"${schema}\"`);\n }\n this.#schema = schema;\n const normalizedRoot = this.#normalizeRoot(options.root);\n this.#root = normalizedRoot === '/' ? '' : normalizedRoot;\n\n const mssql = MssqlFs.#requireMssql();\n if (options.pool instanceof mssql.ConnectionPool) {\n this.#pool = options.pool;\n this.#ownsPool = false;\n } else {\n this.#pool = new mssql.ConnectionPool(options.pool);\n this.#ownsPool = true;\n }\n }\n\n static #requireMssql(): typeof import('mssql') {\n try {\n const require = createRequire(import.meta.url);\n return require('mssql');\n } catch {\n throw new Error(\n 'MssqlFs requires the \"mssql\" package. Install it with: npm install mssql',\n );\n }\n }\n\n #t(name: string): string {\n return `[${this.#schema}].[${name}]`;\n }\n\n async initialize(): Promise<void> {\n if (this.#ownsPool) {\n await this.#pool.connect();\n }\n\n const schemaReq = this.#pool.request();\n schemaReq.input('schema', this.#schema);\n await schemaReq.query(`\n IF NOT EXISTS (SELECT * FROM sys.schemas WHERE name = @schema)\n BEGIN\n DECLARE @sql NVARCHAR(MAX) = N'CREATE SCHEMA ' + QUOTENAME(@schema);\n EXEC sp_executesql @sql;\n END\n `);\n\n const ddl = mssqlFsDDL(this.#schema);\n const batches = ddl.split(/\\bGO\\b/i).filter((b) => b.trim());\n for (const batch of batches) {\n if (batch.trim()) {\n await this.#pool.request().batch(batch);\n }\n }\n\n const rootSlashExists = await this.#rawQuery<{ exists: number }>(\n `SELECT CASE WHEN EXISTS(SELECT 1 FROM ${this.#t('fs_entries')} WHERE path = '/') THEN 1 ELSE 0 END as [exists]`,\n );\n if (rootSlashExists[0].exists === 0) {\n await this.#rawExec(\n `INSERT INTO ${this.#t('fs_entries')} (path, type, mode, size, mtime) VALUES ('/', 'directory', 493, 0, @p0)`,\n [Date.now()],\n );\n }\n\n if (this.#root) {\n await this.#createParentDirs(this.#root);\n\n const rootExists = await this.#rawQuery<{ exists: number }>(\n `SELECT CASE WHEN EXISTS(SELECT 1 FROM ${this.#t('fs_entries')} WHERE path = @p0) THEN 1 ELSE 0 END as [exists]`,\n [this.#root],\n );\n if (rootExists[0].exists === 0) {\n await this.#rawExec(\n `INSERT INTO ${this.#t('fs_entries')} (path, type, mode, size, mtime) VALUES (@p0, 'directory', 493, 0, @p1)`,\n [this.#root, Date.now()],\n );\n }\n }\n\n this.#isInitialized = true;\n }\n\n #ensureInitialized(): void {\n if (!this.#isInitialized) {\n throw new Error(\n 'MssqlFs not initialized. Call await fs.initialize() after construction.',\n );\n }\n }\n\n async #createParentDirs(p: string): Promise<void> {\n const segments = p.split('/').filter(Boolean);\n let currentPath = '/';\n\n for (let i = 0; i < segments.length - 1; i++) {\n currentPath = path.posix.join(currentPath, segments[i]);\n const exists = await this.#rawQuery<{ exists: number }>(\n `SELECT CASE WHEN EXISTS(SELECT 1 FROM ${this.#t('fs_entries')} WHERE path = @p0) THEN 1 ELSE 0 END as [exists]`,\n [currentPath],\n );\n\n if (exists[0].exists === 0) {\n await this.#rawExec(\n `INSERT INTO ${this.#t('fs_entries')} (path, type, mode, size, mtime) VALUES (@p0, 'directory', 493, 0, @p1)`,\n [currentPath, Date.now()],\n );\n }\n }\n }\n\n async #rawQuery<T extends Record<string, unknown>>(\n sql: string,\n params?: unknown[],\n ): Promise<T[]> {\n const request = this.#pool.request();\n params?.forEach((value, index) => {\n request.input(`p${index}`, value);\n });\n const result = await request.query(sql);\n return result.recordset as T[];\n }\n\n async #rawExec(sql: string, params?: unknown[]): Promise<number> {\n const request = this.#pool.request();\n params?.forEach((value, index) => {\n request.input(`p${index}`, value);\n });\n const result = await request.query(sql);\n return result.rowsAffected[0] ?? 0;\n }\n\n async #query<T extends Record<string, unknown>>(\n sql: string,\n params?: unknown[],\n ): Promise<T[]> {\n this.#ensureInitialized();\n return this.#rawQuery<T>(sql, params);\n }\n\n async #exec(sql: string, params?: unknown[]): Promise<number> {\n this.#ensureInitialized();\n return this.#rawExec(sql, params);\n }\n\n async #useTransaction<T>(\n fn: (transaction: Transaction) => Promise<T>,\n ): Promise<T> {\n this.#ensureInitialized();\n const mssql = MssqlFs.#requireMssql();\n const transaction = new mssql.Transaction(this.#pool);\n try {\n await transaction.begin();\n const result = await fn(transaction);\n await transaction.commit();\n return result;\n } catch (error) {\n await transaction.rollback();\n throw error;\n }\n }\n\n #normalizeRoot(root: string): string {\n return path.posix.resolve('/', root.trim());\n }\n\n #prefixPath(p: string): string {\n if (!this.#root) {\n return p;\n }\n if (p === '/') {\n return this.#root;\n }\n return path.posix.join(this.#root, p);\n }\n\n #unprefixPath(p: string): string {\n if (!this.#root) {\n return p;\n }\n if (p === this.#root) {\n return '/';\n }\n if (p.startsWith(this.#root + '/')) {\n return p.slice(this.#root.length) || '/';\n }\n // Should not happen unless a symlink escapes the configured root.\n // Return the best-effort canonical path to avoid breaking callers.\n return p;\n }\n\n #normalizePath(p: string): string {\n return path.posix.resolve('/', p);\n }\n\n #dirname(p: string): string {\n const dir = path.posix.dirname(p);\n return dir === '' ? '/' : dir;\n }\n\n async #ensureParentExists(\n filePath: string,\n transaction: Transaction,\n ): Promise<void> {\n const parent = this.#dirname(filePath);\n const rootPath = this.#root || '/';\n if (parent === rootPath || parent === '/') return;\n\n const request = transaction.request();\n request.input('p0', parent);\n const result = await request.query<{ type: string }>(\n `SELECT type FROM ${this.#t('fs_entries')} WHERE path = @p0`,\n );\n const entry = result.recordset[0];\n\n if (!entry) {\n await this.#ensureParentExists(parent, transaction);\n const insertReq = transaction.request();\n insertReq.input('p0', parent);\n insertReq.input('p1', Date.now());\n await insertReq.query(\n `INSERT INTO ${this.#t('fs_entries')} (path, type, mode, size, mtime) VALUES (@p0, 'directory', 493, 0, @p1)`,\n );\n } else if (entry.type !== 'directory') {\n throw new Error(`mkdir: parent is not a directory: ${parent}`);\n }\n }\n\n async #writeChunks(\n filePath: string,\n content: Uint8Array,\n transaction: Transaction,\n ): Promise<void> {\n const deleteReq = transaction.request();\n deleteReq.input('p0', filePath);\n await deleteReq.query(\n `DELETE FROM ${this.#t('fs_chunks')} WHERE path = @p0`,\n );\n\n for (let i = 0; i < content.length; i += this.#chunkSize) {\n const chunk = content.slice(\n i,\n Math.min(i + this.#chunkSize, content.length),\n );\n const insertReq = transaction.request();\n insertReq.input('p0', filePath);\n insertReq.input('p1', Math.floor(i / this.#chunkSize));\n insertReq.input('p2', Buffer.from(chunk));\n await insertReq.query(\n `INSERT INTO ${this.#t('fs_chunks')} (path, chunkIndex, data) VALUES (@p0, @p1, @p2)`,\n );\n }\n }\n\n async #readChunks(\n filePath: string,\n transaction?: Transaction,\n ): Promise<Uint8Array> {\n let rows: ChunkRow[];\n if (transaction) {\n const req = transaction.request();\n req.input('p0', filePath);\n const result = await req.query<ChunkRow>(\n `SELECT data FROM ${this.#t('fs_chunks')} WHERE path = @p0 ORDER BY chunkIndex`,\n );\n rows = result.recordset as ChunkRow[];\n } else {\n rows = await this.#query<ChunkRow>(\n `SELECT data FROM ${this.#t('fs_chunks')} WHERE path = @p0 ORDER BY chunkIndex`,\n [filePath],\n );\n }\n\n if (rows.length === 0) {\n return new Uint8Array(0);\n }\n\n const totalSize = rows.reduce((sum, row) => sum + row.data.length, 0);\n const result = new Uint8Array(totalSize);\n let offset = 0;\n\n for (const row of rows) {\n result.set(new Uint8Array(row.data), offset);\n offset += row.data.length;\n }\n\n return result;\n }\n\n async #resolveSymlink(p: string, seen = new Set<string>()): Promise<string> {\n if (seen.has(p)) {\n throw new Error(`readFile: circular symlink: ${p}`);\n }\n\n const rows = await this.#query<Pick<FsEntryRow, 'type' | 'symlinkTarget'>>(\n `SELECT type, symlinkTarget FROM ${this.#t('fs_entries')} WHERE path = @p0`,\n [p],\n );\n const entry = rows[0];\n\n if (!entry) {\n throw new Error(`ENOENT: no such file or directory: ${p}`);\n }\n\n if (entry.type !== 'symlink') {\n return p;\n }\n\n seen.add(p);\n const target = this.#normalizePath(\n path.posix.resolve(this.#dirname(p), entry.symlinkTarget!),\n );\n return this.#resolveSymlink(target, seen);\n }\n\n #toUint8Array(content: FileContent, encoding?: string): Uint8Array {\n if (content instanceof Uint8Array) {\n return content;\n }\n const enc = (encoding ?? 'utf8') as BufferEncoding;\n return new Uint8Array(Buffer.from(content, enc));\n }\n\n async close(): Promise<void> {\n if (this.#ownsPool) {\n await this.#pool.close();\n }\n }\n\n // ============================================================================\n // IFileSystem Implementation\n // ============================================================================\n\n async readFile(\n filePath: string,\n options?: ReadFileOptions | string,\n ): Promise<string> {\n const normalized = this.#normalizePath(filePath);\n const prefixed = this.#prefixPath(normalized);\n const resolved = await this.#resolveSymlink(prefixed);\n\n const rows = await this.#query<Pick<FsEntryRow, 'type'>>(\n `SELECT type FROM ${this.#t('fs_entries')} WHERE path = @p0`,\n [resolved],\n );\n const entry = rows[0];\n\n if (!entry) {\n throw new Error(`ENOENT: no such file or directory: ${filePath}`);\n }\n if (entry.type === 'directory') {\n throw new Error(`EISDIR: illegal operation on a directory: ${filePath}`);\n }\n\n const content = await this.#readChunks(resolved);\n const encoding =\n typeof options === 'string' ? options : (options?.encoding ?? 'utf8');\n return Buffer.from(content).toString(encoding as BufferEncoding);\n }\n\n async readFileBuffer(filePath: string): Promise<Uint8Array> {\n const normalized = this.#normalizePath(filePath);\n const prefixed = this.#prefixPath(normalized);\n const resolved = await this.#resolveSymlink(prefixed);\n\n const rows = await this.#query<Pick<FsEntryRow, 'type'>>(\n `SELECT type FROM ${this.#t('fs_entries')} WHERE path = @p0`,\n [resolved],\n );\n const entry = rows[0];\n\n if (!entry) {\n throw new Error(`ENOENT: no such file or directory: ${filePath}`);\n }\n if (entry.type === 'directory') {\n throw new Error(`EISDIR: illegal operation on a directory: ${filePath}`);\n }\n\n return this.#readChunks(resolved);\n }\n\n async writeFile(\n filePath: string,\n content: FileContent,\n options?: WriteFileOptions | string,\n ): Promise<void> {\n const normalized = this.#normalizePath(filePath);\n const prefixed = this.#prefixPath(normalized);\n const encoding = typeof options === 'string' ? options : options?.encoding;\n const data = this.#toUint8Array(content, encoding);\n\n await this.#useTransaction(async (transaction) => {\n await this.#ensureParentExists(prefixed, transaction);\n\n const request = transaction.request();\n request.input('p0', prefixed);\n request.input('p1', data.length);\n request.input('p2', Date.now());\n\n await request.query(`\n MERGE ${this.#t('fs_entries')} AS target\n USING (SELECT @p0 AS path) AS source\n ON target.path = source.path\n WHEN MATCHED THEN\n UPDATE SET type = 'file', size = @p1, mtime = @p2\n WHEN NOT MATCHED THEN\n INSERT (path, type, mode, size, mtime)\n VALUES (@p0, 'file', 420, @p1, @p2);\n `);\n\n await this.#writeChunks(prefixed, data, transaction);\n });\n }\n\n async appendFile(\n filePath: string,\n content: FileContent,\n options?: WriteFileOptions | string,\n ): Promise<void> {\n const normalized = this.#normalizePath(filePath);\n const prefixed = this.#prefixPath(normalized);\n const encoding = typeof options === 'string' ? options : options?.encoding;\n const newData = this.#toUint8Array(content, encoding);\n\n await this.#useTransaction(async (transaction) => {\n await this.#ensureParentExists(prefixed, transaction);\n\n const checkReq = transaction.request();\n checkReq.input('p0', prefixed);\n const result = await checkReq.query<Pick<FsEntryRow, 'type'>>(\n `SELECT type FROM ${this.#t('fs_entries')} WHERE path = @p0`,\n );\n const entry = result.recordset[0];\n\n if (entry && entry.type !== 'file') {\n throw new Error(`appendFile: not a file: ${filePath}`);\n }\n\n const existing = entry\n ? await this.#readChunks(prefixed, transaction)\n : new Uint8Array(0);\n const combined = new Uint8Array(existing.length + newData.length);\n combined.set(existing, 0);\n combined.set(newData, existing.length);\n\n const upsertReq = transaction.request();\n upsertReq.input('p0', prefixed);\n upsertReq.input('p1', combined.length);\n upsertReq.input('p2', Date.now());\n\n await upsertReq.query(`\n MERGE ${this.#t('fs_entries')} AS target\n USING (SELECT @p0 AS path) AS source\n ON target.path = source.path\n WHEN MATCHED THEN\n UPDATE SET size = @p1, mtime = @p2\n WHEN NOT MATCHED THEN\n INSERT (path, type, mode, size, mtime)\n VALUES (@p0, 'file', 420, @p1, @p2);\n `);\n\n await this.#writeChunks(prefixed, combined, transaction);\n });\n }\n\n async exists(filePath: string): Promise<boolean> {\n const normalized = this.#normalizePath(filePath);\n const prefixed = this.#prefixPath(normalized);\n const rows = await this.#query<{ exists: number }>(\n `SELECT CASE WHEN EXISTS(SELECT 1 FROM ${this.#t('fs_entries')} WHERE path = @p0) THEN 1 ELSE 0 END as [exists]`,\n [prefixed],\n );\n return rows[0].exists === 1;\n }\n\n async stat(filePath: string): Promise<FsStat> {\n const normalized = this.#normalizePath(filePath);\n const prefixed = this.#prefixPath(normalized);\n const resolved = await this.#resolveSymlink(prefixed);\n\n const rows = await this.#query<FsEntryRow>(\n `SELECT * FROM ${this.#t('fs_entries')} WHERE path = @p0`,\n [resolved],\n );\n const entry = rows[0];\n\n if (!entry) {\n throw new Error(`ENOENT: no such file or directory: ${filePath}`);\n }\n\n return {\n isFile: entry.type === 'file',\n isDirectory: entry.type === 'directory',\n isSymbolicLink: false,\n mode: Number(entry.mode),\n size: Number(entry.size),\n mtime: new Date(Number(entry.mtime)),\n };\n }\n\n async lstat(filePath: string): Promise<FsStat> {\n const normalized = this.#normalizePath(filePath);\n const prefixed = this.#prefixPath(normalized);\n\n const rows = await this.#query<FsEntryRow>(\n `SELECT * FROM ${this.#t('fs_entries')} WHERE path = @p0`,\n [prefixed],\n );\n const entry = rows[0];\n\n if (!entry) {\n throw new Error(`ENOENT: no such file or directory: ${filePath}`);\n }\n\n return {\n isFile: entry.type === 'file',\n isDirectory: entry.type === 'directory',\n isSymbolicLink: entry.type === 'symlink',\n mode: Number(entry.mode),\n size: Number(entry.size),\n mtime: new Date(Number(entry.mtime)),\n };\n }\n\n async mkdir(dirPath: string, options?: MkdirOptions): Promise<void> {\n const normalized = this.#normalizePath(dirPath);\n const prefixed = this.#prefixPath(normalized);\n\n const existingRows = await this.#query<Pick<FsEntryRow, 'type'>>(\n `SELECT type FROM ${this.#t('fs_entries')} WHERE path = @p0`,\n [prefixed],\n );\n const existing = existingRows[0];\n\n if (existing) {\n if (options?.recursive) {\n return;\n }\n throw new Error(`EEXIST: file already exists: ${dirPath}`);\n }\n\n await this.#useTransaction(async (transaction) => {\n if (options?.recursive) {\n const rootPath = this.#root || '/';\n const relativePath = path.posix.relative(rootPath, prefixed);\n const segments = relativePath.split('/').filter(Boolean);\n let currentPath = rootPath;\n\n for (const segment of segments) {\n currentPath = path.posix.join(currentPath, segment);\n const checkReq = transaction.request();\n checkReq.input('p0', currentPath);\n const result = await checkReq.query<Pick<FsEntryRow, 'type'>>(\n `SELECT type FROM ${this.#t('fs_entries')} WHERE path = @p0`,\n );\n const exists = result.recordset[0];\n\n if (!exists) {\n const insertReq = transaction.request();\n insertReq.input('p0', currentPath);\n insertReq.input('p1', Date.now());\n await insertReq.query(\n `INSERT INTO ${this.#t('fs_entries')} (path, type, mode, size, mtime) VALUES (@p0, 'directory', 493, 0, @p1)`,\n );\n } else if (exists.type !== 'directory') {\n throw new Error(`mkdir: not a directory: ${currentPath}`);\n }\n }\n } else {\n const parent = this.#dirname(prefixed);\n const parentReq = transaction.request();\n parentReq.input('p0', parent);\n const parentResult = await parentReq.query<Pick<FsEntryRow, 'type'>>(\n `SELECT type FROM ${this.#t('fs_entries')} WHERE path = @p0`,\n );\n const parentEntry = parentResult.recordset[0];\n\n if (!parentEntry) {\n throw new Error(`mkdir: parent does not exist: ${parent}`);\n }\n if (parentEntry.type !== 'directory') {\n throw new Error(`mkdir: parent is not a directory: ${parent}`);\n }\n\n const insertReq = transaction.request();\n insertReq.input('p0', prefixed);\n insertReq.input('p1', Date.now());\n await insertReq.query(\n `INSERT INTO ${this.#t('fs_entries')} (path, type, mode, size, mtime) VALUES (@p0, 'directory', 493, 0, @p1)`,\n );\n }\n });\n }\n\n async readdir(dirPath: string): Promise<string[]> {\n const normalized = this.#normalizePath(dirPath);\n const prefixed = this.#prefixPath(normalized);\n const resolved = await this.#resolveSymlink(prefixed);\n\n const entryRows = await this.#query<Pick<FsEntryRow, 'type'>>(\n `SELECT type FROM ${this.#t('fs_entries')} WHERE path = @p0`,\n [resolved],\n );\n const entry = entryRows[0];\n\n if (!entry) {\n throw new Error(`ENOENT: no such file or directory: ${dirPath}`);\n }\n if (entry.type !== 'directory') {\n throw new Error(`ENOTDIR: not a directory: ${dirPath}`);\n }\n\n const prefix = resolved === '/' ? '/' : resolved + '/';\n const rows = await this.#query<{ path: string }>(\n `SELECT path FROM ${this.#t('fs_entries')}\n WHERE path LIKE @p0 + '%'\n AND path != @p1\n AND path NOT LIKE @p0 + '%/%'`,\n [prefix, resolved],\n );\n\n return rows.map((row) => path.posix.basename(row.path));\n }\n\n async readdirWithFileTypes(dirPath: string): Promise<DirentEntry[]> {\n const normalized = this.#normalizePath(dirPath);\n const prefixed = this.#prefixPath(normalized);\n const resolved = await this.#resolveSymlink(prefixed);\n\n const entryRows = await this.#query<Pick<FsEntryRow, 'type'>>(\n `SELECT type FROM ${this.#t('fs_entries')} WHERE path = @p0`,\n [resolved],\n );\n const entry = entryRows[0];\n\n if (!entry) {\n throw new Error(`ENOENT: no such file or directory: ${dirPath}`);\n }\n if (entry.type !== 'directory') {\n throw new Error(`ENOTDIR: not a directory: ${dirPath}`);\n }\n\n const prefix = resolved === '/' ? '/' : resolved + '/';\n const rows = await this.#query<Pick<FsEntryRow, 'path' | 'type'>>(\n `SELECT path, type FROM ${this.#t('fs_entries')}\n WHERE path LIKE @p0 + '%'\n AND path != @p1\n AND path NOT LIKE @p0 + '%/%'`,\n [prefix, resolved],\n );\n\n return rows.map((row) => ({\n name: path.posix.basename(row.path),\n isFile: row.type === 'file',\n isDirectory: row.type === 'directory',\n isSymbolicLink: row.type === 'symlink',\n }));\n }\n\n async rm(filePath: string, options?: RmOptions): Promise<void> {\n const normalized = this.#normalizePath(filePath);\n const prefixed = this.#prefixPath(normalized);\n\n const rows = await this.#query<Pick<FsEntryRow, 'type'>>(\n `SELECT type FROM ${this.#t('fs_entries')} WHERE path = @p0`,\n [prefixed],\n );\n const entry = rows[0];\n\n if (!entry) {\n if (options?.force) {\n return;\n }\n throw new Error(`ENOENT: no such file or directory: ${filePath}`);\n }\n\n await this.#useTransaction(async (transaction) => {\n if (entry.type === 'directory') {\n const childrenReq = transaction.request();\n childrenReq.input('p0', prefixed);\n const childrenResult = await childrenReq.query<{ exists: number }>(\n `SELECT CASE WHEN EXISTS(SELECT 1 FROM ${this.#t('fs_entries')} WHERE path LIKE @p0 + '/%') THEN 1 ELSE 0 END as [exists]`,\n );\n\n if (childrenResult.recordset[0].exists === 1 && !options?.recursive) {\n throw new Error(`ENOTEMPTY: directory not empty: ${filePath}`);\n }\n\n const deleteReq = transaction.request();\n deleteReq.input('p0', prefixed);\n await deleteReq.query(\n `DELETE FROM ${this.#t('fs_entries')} WHERE path = @p0 OR path LIKE @p0 + '/%'`,\n );\n } else {\n const deleteReq = transaction.request();\n deleteReq.input('p0', prefixed);\n await deleteReq.query(\n `DELETE FROM ${this.#t('fs_entries')} WHERE path = @p0`,\n );\n }\n });\n }\n\n async cp(src: string, dest: string, options?: CpOptions): Promise<void> {\n const srcNormalized = this.#normalizePath(src);\n const destNormalized = this.#normalizePath(dest);\n const srcPrefixed = this.#prefixPath(srcNormalized);\n const destPrefixed = this.#prefixPath(destNormalized);\n\n const srcRows = await this.#query<FsEntryRow>(\n `SELECT * FROM ${this.#t('fs_entries')} WHERE path = @p0`,\n [srcPrefixed],\n );\n const srcEntry = srcRows[0];\n\n if (!srcEntry) {\n throw new Error(`ENOENT: no such file or directory: ${src}`);\n }\n\n if (srcEntry.type === 'directory' && !options?.recursive) {\n throw new Error(`cp: -r not specified; omitting directory: ${src}`);\n }\n\n await this.#useTransaction(async (transaction) => {\n await this.#ensureParentExists(destPrefixed, transaction);\n\n if (srcEntry.type === 'directory') {\n const allEntriesReq = transaction.request();\n allEntriesReq.input('p0', srcPrefixed);\n const allEntriesResult = await allEntriesReq.query<FsEntryRow>(\n `SELECT * FROM ${this.#t('fs_entries')} WHERE path = @p0 OR path LIKE @p0 + '/%'`,\n );\n\n for (const entry of allEntriesResult.recordset) {\n const relativePath = path.posix.relative(srcPrefixed, entry.path);\n const newPath = path.posix.join(destPrefixed, relativePath);\n\n const insertReq = transaction.request();\n insertReq.input('p0', newPath);\n insertReq.input('p1', entry.type);\n insertReq.input('p2', entry.mode);\n insertReq.input('p3', entry.size);\n insertReq.input('p4', Date.now());\n insertReq.input('p5', entry.symlinkTarget);\n\n await insertReq.query(`\n MERGE ${this.#t('fs_entries')} AS target\n USING (SELECT @p0 AS path) AS source\n ON target.path = source.path\n WHEN MATCHED THEN\n UPDATE SET type = @p1, mode = @p2, size = @p3, mtime = @p4, symlinkTarget = @p5\n WHEN NOT MATCHED THEN\n INSERT (path, type, mode, size, mtime, symlinkTarget)\n VALUES (@p0, @p1, @p2, @p3, @p4, @p5);\n `);\n\n if (entry.type === 'file') {\n const deleteChunksReq = transaction.request();\n deleteChunksReq.input('p0', newPath);\n await deleteChunksReq.query(\n `DELETE FROM ${this.#t('fs_chunks')} WHERE path = @p0`,\n );\n\n const chunksReq = transaction.request();\n chunksReq.input('p0', entry.path);\n const chunksResult = await chunksReq.query<{\n chunkIndex: number;\n data: Buffer;\n }>(\n `SELECT chunkIndex, data FROM ${this.#t('fs_chunks')} WHERE path = @p0`,\n );\n\n for (const chunk of chunksResult.recordset) {\n const chunkInsertReq = transaction.request();\n chunkInsertReq.input('p0', newPath);\n chunkInsertReq.input('p1', chunk.chunkIndex);\n chunkInsertReq.input('p2', chunk.data);\n await chunkInsertReq.query(\n `INSERT INTO ${this.#t('fs_chunks')} (path, chunkIndex, data) VALUES (@p0, @p1, @p2)`,\n );\n }\n }\n }\n } else {\n const insertReq = transaction.request();\n insertReq.input('p0', destPrefixed);\n insertReq.input('p1', srcEntry.type);\n insertReq.input('p2', srcEntry.mode);\n insertReq.input('p3', srcEntry.size);\n insertReq.input('p4', Date.now());\n insertReq.input('p5', srcEntry.symlinkTarget);\n\n await insertReq.query(`\n MERGE ${this.#t('fs_entries')} AS target\n USING (SELECT @p0 AS path) AS source\n ON target.path = source.path\n WHEN MATCHED THEN\n UPDATE SET type = @p1, mode = @p2, size = @p3, mtime = @p4, symlinkTarget = @p5\n WHEN NOT MATCHED THEN\n INSERT (path, type, mode, size, mtime, symlinkTarget)\n VALUES (@p0, @p1, @p2, @p3, @p4, @p5);\n `);\n\n if (srcEntry.type === 'file') {\n const chunksReq = transaction.request();\n chunksReq.input('p0', srcPrefixed);\n const chunksResult = await chunksReq.query<{\n chunkIndex: number;\n data: Buffer;\n }>(\n `SELECT chunkIndex, data FROM ${this.#t('fs_chunks')} WHERE path = @p0`,\n );\n\n const deleteChunksReq = transaction.request();\n deleteChunksReq.input('p0', destPrefixed);\n await deleteChunksReq.query(\n `DELETE FROM ${this.#t('fs_chunks')} WHERE path = @p0`,\n );\n\n for (const chunk of chunksResult.recordset) {\n const chunkInsertReq = transaction.request();\n chunkInsertReq.input('p0', destPrefixed);\n chunkInsertReq.input('p1', chunk.chunkIndex);\n chunkInsertReq.input('p2', chunk.data);\n await chunkInsertReq.query(\n `INSERT INTO ${this.#t('fs_chunks')} (path, chunkIndex, data) VALUES (@p0, @p1, @p2)`,\n );\n }\n }\n }\n });\n }\n\n async mv(src: string, dest: string): Promise<void> {\n const srcNormalized = this.#normalizePath(src);\n const destNormalized = this.#normalizePath(dest);\n const srcPrefixed = this.#prefixPath(srcNormalized);\n const destPrefixed = this.#prefixPath(destNormalized);\n\n const srcRows = await this.#query<FsEntryRow>(\n `SELECT * FROM ${this.#t('fs_entries')} WHERE path = @p0`,\n [srcPrefixed],\n );\n const srcEntry = srcRows[0];\n\n if (!srcEntry) {\n throw new Error(`ENOENT: no such file or directory: ${src}`);\n }\n\n await this.#useTransaction(async (transaction) => {\n await this.#ensureParentExists(destPrefixed, transaction);\n\n if (srcEntry.type === 'directory') {\n const allEntriesReq = transaction.request();\n allEntriesReq.input('p0', srcPrefixed);\n const allEntriesResult = await allEntriesReq.query<FsEntryRow>(\n `SELECT * FROM ${this.#t('fs_entries')} WHERE path = @p0 OR path LIKE @p0 + '/%' ORDER BY path DESC`,\n );\n\n const destDeleteReq = transaction.request();\n destDeleteReq.input('dp0', destPrefixed);\n await destDeleteReq.query(\n `DELETE FROM ${this.#t('fs_entries')} WHERE path = @dp0 OR path LIKE @dp0 + '/%'`,\n );\n\n for (const entry of [...allEntriesResult.recordset].reverse()) {\n const relativePath = path.posix.relative(srcPrefixed, entry.path);\n const newPath = path.posix.join(destPrefixed, relativePath);\n\n const insertReq = transaction.request();\n insertReq.input('p0', newPath);\n insertReq.input('p1', entry.type);\n insertReq.input('p2', entry.mode);\n insertReq.input('p3', entry.size);\n insertReq.input('p4', Date.now());\n insertReq.input('p5', entry.symlinkTarget);\n\n await insertReq.query(`\n MERGE ${this.#t('fs_entries')} AS target\n USING (SELECT @p0 AS path) AS source\n ON target.path = source.path\n WHEN MATCHED THEN\n UPDATE SET type = @p1, mode = @p2, size = @p3, mtime = @p4, symlinkTarget = @p5\n WHEN NOT MATCHED THEN\n INSERT (path, type, mode, size, mtime, symlinkTarget)\n VALUES (@p0, @p1, @p2, @p3, @p4, @p5);\n `);\n\n if (entry.type === 'file') {\n const deleteChunksReq = transaction.request();\n deleteChunksReq.input('p0', newPath);\n await deleteChunksReq.query(\n `DELETE FROM ${this.#t('fs_chunks')} WHERE path = @p0`,\n );\n\n const chunksReq = transaction.request();\n chunksReq.input('p0', entry.path);\n const chunksResult = await chunksReq.query<{\n chunkIndex: number;\n data: Buffer;\n }>(\n `SELECT chunkIndex, data FROM ${this.#t('fs_chunks')} WHERE path = @p0`,\n );\n\n for (const chunk of chunksResult.recordset) {\n const chunkInsertReq = transaction.request();\n chunkInsertReq.input('p0', newPath);\n chunkInsertReq.input('p1', chunk.chunkIndex);\n chunkInsertReq.input('p2', chunk.data);\n await chunkInsertReq.query(\n `INSERT INTO ${this.#t('fs_chunks')} (path, chunkIndex, data) VALUES (@p0, @p1, @p2)`,\n );\n }\n }\n }\n\n const deleteReq = transaction.request();\n deleteReq.input('p0', srcPrefixed);\n await deleteReq.query(\n `DELETE FROM ${this.#t('fs_entries')} WHERE path = @p0 OR path LIKE @p0 + '/%'`,\n );\n } else {\n const insertReq = transaction.request();\n insertReq.input('p0', destPrefixed);\n insertReq.input('p1', srcEntry.type);\n insertReq.input('p2', srcEntry.mode);\n insertReq.input('p3', srcEntry.size);\n insertReq.input('p4', Date.now());\n insertReq.input('p5', srcEntry.symlinkTarget);\n\n await insertReq.query(`\n MERGE ${this.#t('fs_entries')} AS target\n USING (SELECT @p0 AS path) AS source\n ON target.path = source.path\n WHEN MATCHED THEN\n UPDATE SET type = @p1, mode = @p2, size = @p3, mtime = @p4, symlinkTarget = @p5\n WHEN NOT MATCHED THEN\n INSERT (path, type, mode, size, mtime, symlinkTarget)\n VALUES (@p0, @p1, @p2, @p3, @p4, @p5);\n `);\n\n if (srcEntry.type === 'file') {\n const deleteChunksReq = transaction.request();\n deleteChunksReq.input('p0', destPrefixed);\n await deleteChunksReq.query(\n `DELETE FROM ${this.#t('fs_chunks')} WHERE path = @p0`,\n );\n\n const chunksReq = transaction.request();\n chunksReq.input('p0', srcPrefixed);\n const chunksResult = await chunksReq.query<{\n chunkIndex: number;\n data: Buffer;\n }>(\n `SELECT chunkIndex, data FROM ${this.#t('fs_chunks')} WHERE path = @p0`,\n );\n\n for (const chunk of chunksResult.recordset) {\n const chunkInsertReq = transaction.request();\n chunkInsertReq.input('p0', destPrefixed);\n chunkInsertReq.input('p1', chunk.chunkIndex);\n chunkInsertReq.input('p2', chunk.data);\n await chunkInsertReq.query(\n `INSERT INTO ${this.#t('fs_chunks')} (path, chunkIndex, data) VALUES (@p0, @p1, @p2)`,\n );\n }\n }\n\n const deleteReq = transaction.request();\n deleteReq.input('p0', srcPrefixed);\n await deleteReq.query(\n `DELETE FROM ${this.#t('fs_entries')} WHERE path = @p0`,\n );\n }\n });\n }\n\n resolvePath(base: string, relativePath: string): string {\n return path.posix.resolve(base, relativePath);\n }\n\n getAllPaths(): string[] {\n throw new Error(\n 'getAllPaths() is not supported in MssqlFs - use getAllPathsAsync() instead',\n );\n }\n\n async getAllPathsAsync(): Promise<string[]> {\n const rows = await this.#query<{ path: string; [key: string]: unknown }>(\n `SELECT path FROM ${this.#t('fs_entries')} ORDER BY path`,\n );\n return rows.map((row) => row.path);\n }\n\n async realpath(filePath: string): Promise<string> {\n const normalized = this.#normalizePath(filePath);\n const prefixed = this.#prefixPath(normalized);\n const resolved = await this.#resolveSymlink(prefixed);\n\n const rows = await this.#query<{ exists: number }>(\n `SELECT CASE WHEN EXISTS(SELECT 1 FROM ${this.#t('fs_entries')} WHERE path = @p0) THEN 1 ELSE 0 END as [exists]`,\n [resolved],\n );\n if (rows[0].exists !== 1) {\n throw new Error(`ENOENT: no such file or directory: ${filePath}`);\n }\n\n return this.#unprefixPath(resolved);\n }\n\n async utimes(filePath: string, _atime: Date, mtime: Date): Promise<void> {\n const normalized = this.#normalizePath(filePath);\n const prefixed = this.#prefixPath(normalized);\n const resolved = await this.#resolveSymlink(prefixed);\n\n const result = await this.#exec(\n `UPDATE ${this.#t('fs_entries')} SET mtime = @p0 WHERE path = @p1`,\n [mtime.getTime(), resolved],\n );\n\n if (result === 0) {\n throw new Error(`ENOENT: no such file or directory: ${filePath}`);\n }\n }\n\n async chmod(filePath: string, mode: number): Promise<void> {\n const normalized = this.#normalizePath(filePath);\n const prefixed = this.#prefixPath(normalized);\n\n const result = await this.#exec(\n `UPDATE ${this.#t('fs_entries')} SET mode = @p0 WHERE path = @p1`,\n [mode, prefixed],\n );\n\n if (result === 0) {\n throw new Error(`ENOENT: no such file or directory: ${filePath}`);\n }\n }\n\n async symlink(target: string, linkPath: string): Promise<void> {\n const normalized = this.#normalizePath(linkPath);\n const prefixed = this.#prefixPath(normalized);\n\n const existingRows = await this.#query<{ exists: number }>(\n `SELECT CASE WHEN EXISTS(SELECT 1 FROM ${this.#t('fs_entries')} WHERE path = @p0) THEN 1 ELSE 0 END as [exists]`,\n [prefixed],\n );\n if (existingRows[0].exists === 1) {\n throw new Error(`EEXIST: file already exists: ${linkPath}`);\n }\n\n await this.#useTransaction(async (transaction) => {\n await this.#ensureParentExists(prefixed, transaction);\n\n const insertReq = transaction.request();\n insertReq.input('p0', prefixed);\n insertReq.input('p1', Date.now());\n insertReq.input('p2', target);\n await insertReq.query(\n `INSERT INTO ${this.#t('fs_entries')} (path, type, mode, size, mtime, symlinkTarget)\n VALUES (@p0, 'symlink', 511, 0, @p1, @p2)`,\n );\n });\n }\n\n async link(existingPath: string, newPath: string): Promise<void> {\n const srcNormalized = this.#normalizePath(existingPath);\n const destNormalized = this.#normalizePath(newPath);\n const srcPrefixed = this.#prefixPath(srcNormalized);\n const destPrefixed = this.#prefixPath(destNormalized);\n\n const srcRows = await this.#query<FsEntryRow>(\n `SELECT * FROM ${this.#t('fs_entries')} WHERE path = @p0`,\n [srcPrefixed],\n );\n const srcEntry = srcRows[0];\n\n if (!srcEntry) {\n throw new Error(`ENOENT: no such file or directory: ${existingPath}`);\n }\n\n if (srcEntry.type !== 'file') {\n throw new Error(`link: not supported for directories: ${existingPath}`);\n }\n\n const existingRows = await this.#query<{ exists: number }>(\n `SELECT CASE WHEN EXISTS(SELECT 1 FROM ${this.#t('fs_entries')} WHERE path = @p0) THEN 1 ELSE 0 END as [exists]`,\n [destPrefixed],\n );\n if (existingRows[0].exists === 1) {\n throw new Error(`EEXIST: file already exists: ${newPath}`);\n }\n\n await this.#useTransaction(async (transaction) => {\n await this.#ensureParentExists(destPrefixed, transaction);\n\n const insertReq = transaction.request();\n insertReq.input('p0', destPrefixed);\n insertReq.input('p1', srcEntry.mode);\n insertReq.input('p2', srcEntry.size);\n insertReq.input('p3', Date.now());\n await insertReq.query(\n `INSERT INTO ${this.#t('fs_entries')} (path, type, mode, size, mtime)\n VALUES (@p0, 'file', @p1, @p2, @p3)`,\n );\n\n const chunksReq = transaction.request();\n chunksReq.input('p0', srcPrefixed);\n const chunksResult = await chunksReq.query<{\n chunkIndex: number;\n data: Buffer;\n }>(\n `SELECT chunkIndex, data FROM ${this.#t('fs_chunks')} WHERE path = @p0`,\n );\n\n for (const chunk of chunksResult.recordset) {\n const chunkInsertReq = transaction.request();\n chunkInsertReq.input('p0', destPrefixed);\n chunkInsertReq.input('p1', chunk.chunkIndex);\n chunkInsertReq.input('p2', chunk.data);\n await chunkInsertReq.query(\n `INSERT INTO ${this.#t('fs_chunks')} (path, chunkIndex, data) VALUES (@p0, @p1, @p2)`,\n );\n }\n });\n }\n\n async readlink(linkPath: string): Promise<string> {\n const normalized = this.#normalizePath(linkPath);\n const prefixed = this.#prefixPath(normalized);\n\n const rows = await this.#query<Pick<FsEntryRow, 'type' | 'symlinkTarget'>>(\n `SELECT type, symlinkTarget FROM ${this.#t('fs_entries')} WHERE path = @p0`,\n [prefixed],\n );\n const entry = rows[0];\n\n if (!entry) {\n throw new Error(`ENOENT: no such file or directory: ${linkPath}`);\n }\n\n if (entry.type !== 'symlink') {\n throw new Error(`readlink: not a symbolic link: ${linkPath}`);\n }\n\n return entry.symlinkTarget!;\n }\n}\n", "export function mssqlFsDDL(schema: string): string {\n return `\nIF NOT EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[${schema}].[fs_entries]') AND type = 'U')\nCREATE TABLE [${schema}].[fs_entries] (\n path NVARCHAR(900) PRIMARY KEY,\n type NVARCHAR(20) NOT NULL,\n mode INT NOT NULL,\n size BIGINT NOT NULL,\n mtime BIGINT NOT NULL,\n symlinkTarget NVARCHAR(900) NULL\n);\nGO\n\nIF NOT EXISTS (SELECT * FROM sys.indexes WHERE name = 'idx_${schema}_fs_entries_type')\nCREATE INDEX [idx_${schema}_fs_entries_type] ON [${schema}].[fs_entries](type);\nGO\n\nIF NOT EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[${schema}].[fs_chunks]') AND type = 'U')\nCREATE TABLE [${schema}].[fs_chunks] (\n path NVARCHAR(900) NOT NULL,\n chunkIndex INT NOT NULL,\n data VARBINARY(MAX) NOT NULL,\n PRIMARY KEY (path, chunkIndex),\n FOREIGN KEY (path) REFERENCES [${schema}].[fs_entries](path) ON DELETE CASCADE ON UPDATE CASCADE\n);\nGO\n`;\n}\n", "import type {\n CpOptions,\n FileContent,\n FsStat,\n IFileSystem,\n MkdirOptions,\n RmOptions,\n} from 'just-bash';\nimport { createRequire } from 'node:module';\nimport * as path from 'node:path';\nimport type { Pool, PoolClient, PoolConfig } from 'pg';\n\nimport { postgresFsDDL } from './ddl.postgres-fs.ts';\n\ninterface ReadFileOptions {\n encoding?: BufferEncoding | null;\n}\n\ninterface WriteFileOptions {\n encoding?: BufferEncoding;\n}\n\ninterface DirentEntry {\n name: string;\n isFile: boolean;\n isDirectory: boolean;\n isSymbolicLink: boolean;\n}\n\nexport interface PostgresFsOptions {\n pool: Pool | PoolConfig | string;\n root: string;\n chunkSize?: number;\n schema?: string;\n}\n\ntype EntryType = 'file' | 'directory' | 'symlink';\n\ninterface FsEntryRow {\n path: string;\n type: EntryType;\n mode: number;\n size: number;\n mtime: number;\n symlink_target: string | null;\n [key: string]: unknown;\n}\n\ninterface ChunkRow {\n data: Buffer;\n [key: string]: unknown;\n}\n\nexport class PostgresFs implements IFileSystem {\n #pool: Pool;\n #chunkSize: number;\n #root: string;\n #schema: string;\n #ownsPool: boolean;\n #isInitialized = false;\n\n constructor(options: PostgresFsOptions) {\n this.#chunkSize = options.chunkSize ?? 1024 * 1024;\n const schema = options.schema ?? 'public';\n if (!/^[a-zA-Z_]\\w*$/.test(schema)) {\n throw new Error(`Invalid schema name: \"${schema}\"`);\n }\n this.#schema = schema;\n const normalizedRoot = this.#normalizeRoot(options.root);\n this.#root = normalizedRoot === '/' ? '' : normalizedRoot;\n\n const pg = PostgresFs.#requirePg();\n if (options.pool instanceof pg.Pool) {\n this.#pool = options.pool;\n this.#ownsPool = false;\n } else {\n this.#pool =\n typeof options.pool === 'string'\n ? new pg.Pool({ connectionString: options.pool })\n : new pg.Pool(options.pool);\n this.#ownsPool = true;\n }\n }\n\n static #requirePg(): typeof import('pg') {\n try {\n const require = createRequire(import.meta.url);\n return require('pg');\n } catch {\n throw new Error(\n 'PostgresFs requires the \"pg\" package. Install it with: npm install pg',\n );\n }\n }\n\n #t(name: string): string {\n return `\"${this.#schema}\".\"${name}\"`;\n }\n\n async initialize(): Promise<void> {\n const ddl = postgresFsDDL(this.#schema);\n await this.#pool.query(ddl);\n\n const rootSlashExists = await this.#rawQuery<{ exists: boolean }>(\n `SELECT EXISTS(SELECT 1 FROM ${this.#t('fs_entries')} WHERE path = '/') AS exists`,\n );\n if (!rootSlashExists[0].exists) {\n await this.#rawExec(\n `INSERT INTO ${this.#t('fs_entries')} (path, type, mode, size, mtime) VALUES ('/', 'directory', 493, 0, $1)`,\n [Date.now()],\n );\n }\n\n if (this.#root) {\n await this.#createParentDirs(this.#root);\n\n const rootExists = await this.#rawQuery<{ exists: boolean }>(\n `SELECT EXISTS(SELECT 1 FROM ${this.#t('fs_entries')} WHERE path = $1) AS exists`,\n [this.#root],\n );\n if (!rootExists[0].exists) {\n await this.#rawExec(\n `INSERT INTO ${this.#t('fs_entries')} (path, type, mode, size, mtime) VALUES ($1, 'directory', 493, 0, $2)`,\n [this.#root, Date.now()],\n );\n }\n }\n\n this.#isInitialized = true;\n }\n\n #ensureInitialized(): void {\n if (!this.#isInitialized) {\n throw new Error(\n 'PostgresFs not initialized. Call await fs.initialize() after construction.',\n );\n }\n }\n\n async #createParentDirs(p: string): Promise<void> {\n const segments = p.split('/').filter(Boolean);\n let currentPath = '/';\n\n for (let i = 0; i < segments.length - 1; i++) {\n currentPath = path.posix.join(currentPath, segments[i]);\n const exists = await this.#rawQuery<{ exists: boolean }>(\n `SELECT EXISTS(SELECT 1 FROM ${this.#t('fs_entries')} WHERE path = $1) AS exists`,\n [currentPath],\n );\n\n if (!exists[0].exists) {\n await this.#rawExec(\n `INSERT INTO ${this.#t('fs_entries')} (path, type, mode, size, mtime) VALUES ($1, 'directory', 493, 0, $2)`,\n [currentPath, Date.now()],\n );\n }\n }\n }\n\n async #rawQuery<T extends Record<string, unknown>>(\n sql: string,\n params?: unknown[],\n ): Promise<T[]> {\n const result = await this.#pool.query(sql, params);\n return result.rows as T[];\n }\n\n async #rawExec(sql: string, params?: unknown[]): Promise<number> {\n const result = await this.#pool.query(sql, params);\n return result.rowCount ?? 0;\n }\n\n async #query<T extends Record<string, unknown>>(\n sql: string,\n params?: unknown[],\n ): Promise<T[]> {\n this.#ensureInitialized();\n return this.#rawQuery<T>(sql, params);\n }\n\n async #exec(sql: string, params?: unknown[]): Promise<number> {\n this.#ensureInitialized();\n return this.#rawExec(sql, params);\n }\n\n async #useTransaction<T>(fn: (client: PoolClient) => Promise<T>): Promise<T> {\n this.#ensureInitialized();\n const client = await this.#pool.connect();\n try {\n await client.query('BEGIN');\n const result = await fn(client);\n await client.query('COMMIT');\n return result;\n } catch (error) {\n await client.query('ROLLBACK');\n throw error;\n } finally {\n client.release();\n }\n }\n\n #normalizeRoot(root: string): string {\n return path.posix.resolve('/', root.trim());\n }\n\n #prefixPath(p: string): string {\n if (!this.#root) {\n return p;\n }\n if (p === '/') {\n return this.#root;\n }\n return path.posix.join(this.#root, p);\n }\n\n #unprefixPath(p: string): string {\n if (!this.#root) {\n return p;\n }\n if (p === this.#root) {\n return '/';\n }\n if (p.startsWith(this.#root + '/')) {\n return p.slice(this.#root.length) || '/';\n }\n return p;\n }\n\n #normalizePath(p: string): string {\n return path.posix.resolve('/', p);\n }\n\n #dirname(p: string): string {\n const dir = path.posix.dirname(p);\n return dir === '' ? '/' : dir;\n }\n\n async #ensureParentExists(\n filePath: string,\n client: PoolClient,\n ): Promise<void> {\n const parent = this.#dirname(filePath);\n const rootPath = this.#root || '/';\n if (parent === rootPath || parent === '/') return;\n\n const result = await client.query<{ type: string }>(\n `SELECT type FROM ${this.#t('fs_entries')} WHERE path = $1`,\n [parent],\n );\n const entry = result.rows[0];\n\n if (!entry) {\n await this.#ensureParentExists(parent, client);\n await client.query(\n `INSERT INTO ${this.#t('fs_entries')} (path, type, mode, size, mtime) VALUES ($1, 'directory', 493, 0, $2)`,\n [parent, Date.now()],\n );\n } else if (entry.type !== 'directory') {\n throw new Error(`mkdir: parent is not a directory: ${parent}`);\n }\n }\n\n async #writeChunks(\n filePath: string,\n content: Uint8Array,\n client: PoolClient,\n ): Promise<void> {\n await client.query(`DELETE FROM ${this.#t('fs_chunks')} WHERE path = $1`, [\n filePath,\n ]);\n\n for (let i = 0; i < content.length; i += this.#chunkSize) {\n const chunk = content.slice(\n i,\n Math.min(i + this.#chunkSize, content.length),\n );\n await client.query(\n `INSERT INTO ${this.#t('fs_chunks')} (path, chunk_index, data) VALUES ($1, $2, $3)`,\n [filePath, Math.floor(i / this.#chunkSize), Buffer.from(chunk)],\n );\n }\n }\n\n async #readChunks(\n filePath: string,\n client?: PoolClient,\n ): Promise<Uint8Array> {\n let rows: ChunkRow[];\n if (client) {\n const result = await client.query<ChunkRow>(\n `SELECT data FROM ${this.#t('fs_chunks')} WHERE path = $1 ORDER BY chunk_index`,\n [filePath],\n );\n rows = result.rows as ChunkRow[];\n } else {\n rows = await this.#query<ChunkRow>(\n `SELECT data FROM ${this.#t('fs_chunks')} WHERE path = $1 ORDER BY chunk_index`,\n [filePath],\n );\n }\n\n if (rows.length === 0) {\n return new Uint8Array(0);\n }\n\n const totalSize = rows.reduce((sum, row) => sum + row.data.length, 0);\n const result = new Uint8Array(totalSize);\n let offset = 0;\n\n for (const row of rows) {\n result.set(new Uint8Array(row.data), offset);\n offset += row.data.length;\n }\n\n return result;\n }\n\n async #resolveSymlink(p: string, seen = new Set<string>()): Promise<string> {\n if (seen.has(p)) {\n throw new Error(`readFile: circular symlink: ${p}`);\n }\n\n const rows = await this.#query<Pick<FsEntryRow, 'type' | 'symlink_target'>>(\n `SELECT type, symlink_target FROM ${this.#t('fs_entries')} WHERE path = $1`,\n [p],\n );\n const entry = rows[0];\n\n if (!entry) {\n throw new Error(`ENOENT: no such file or directory: ${p}`);\n }\n\n if (entry.type !== 'symlink') {\n return p;\n }\n\n seen.add(p);\n const target = this.#normalizePath(\n path.posix.resolve(this.#dirname(p), entry.symlink_target!),\n );\n return this.#resolveSymlink(target, seen);\n }\n\n #toUint8Array(content: FileContent, encoding?: string): Uint8Array {\n if (content instanceof Uint8Array) {\n return content;\n }\n const enc = (encoding ?? 'utf8') as BufferEncoding;\n return new Uint8Array(Buffer.from(content, enc));\n }\n\n async close(): Promise<void> {\n if (this.#ownsPool) {\n await this.#pool.end();\n }\n }\n\n // ============================================================================\n // IFileSystem Implementation\n // ============================================================================\n\n async readFile(\n filePath: string,\n options?: ReadFileOptions | string,\n ): Promise<string> {\n const normalized = this.#normalizePath(filePath);\n const prefixed = this.#prefixPath(normalized);\n const resolved = await this.#resolveSymlink(prefixed);\n\n const rows = await this.#query<Pick<FsEntryRow, 'type'>>(\n `SELECT type FROM ${this.#t('fs_entries')} WHERE path = $1`,\n [resolved],\n );\n const entry = rows[0];\n\n if (!entry) {\n throw new Error(`ENOENT: no such file or directory: ${filePath}`);\n }\n if (entry.type === 'directory') {\n throw new Error(`EISDIR: illegal operation on a directory: ${filePath}`);\n }\n\n const content = await this.#readChunks(resolved);\n const encoding =\n typeof options === 'string' ? options : (options?.encoding ?? 'utf8');\n return Buffer.from(content).toString(encoding as BufferEncoding);\n }\n\n async readFileBuffer(filePath: string): Promise<Uint8Array> {\n const normalized = this.#normalizePath(filePath);\n const prefixed = this.#prefixPath(normalized);\n const resolved = await this.#resolveSymlink(prefixed);\n\n const rows = await this.#query<Pick<FsEntryRow, 'type'>>(\n `SELECT type FROM ${this.#t('fs_entries')} WHERE path = $1`,\n [resolved],\n );\n const entry = rows[0];\n\n if (!entry) {\n throw new Error(`ENOENT: no such file or directory: ${filePath}`);\n }\n if (entry.type === 'directory') {\n throw new Error(`EISDIR: illegal operation on a directory: ${filePath}`);\n }\n\n return this.#readChunks(resolved);\n }\n\n async writeFile(\n filePath: string,\n content: FileContent,\n options?: WriteFileOptions | string,\n ): Promise<void> {\n const normalized = this.#normalizePath(filePath);\n const prefixed = this.#prefixPath(normalized);\n const encoding = typeof options === 'string' ? options : options?.encoding;\n const data = this.#toUint8Array(content, encoding);\n\n await this.#useTransaction(async (client) => {\n await this.#ensureParentExists(prefixed, client);\n\n await client.query(\n `INSERT INTO ${this.#t('fs_entries')} (path, type, mode, size, mtime)\n VALUES ($1, 'file', 420, $2, $3)\n ON CONFLICT (path) DO UPDATE SET type = 'file', size = EXCLUDED.size, mtime = EXCLUDED.mtime`,\n [prefixed, data.length, Date.now()],\n );\n\n await this.#writeChunks(prefixed, data, client);\n });\n }\n\n async appendFile(\n filePath: string,\n content: FileContent,\n options?: WriteFileOptions | string,\n ): Promise<void> {\n const normalized = this.#normalizePath(filePath);\n const prefixed = this.#prefixPath(normalized);\n const encoding = typeof options === 'string' ? options : options?.encoding;\n const newData = this.#toUint8Array(content, encoding);\n\n await this.#useTransaction(async (client) => {\n await this.#ensureParentExists(prefixed, client);\n\n const result = await client.query<Pick<FsEntryRow, 'type'>>(\n `SELECT type FROM ${this.#t('fs_entries')} WHERE path = $1`,\n [prefixed],\n );\n const entry = result.rows[0];\n\n if (entry && entry.type !== 'file') {\n throw new Error(`appendFile: not a file: ${filePath}`);\n }\n\n const existing = entry\n ? await this.#readChunks(prefixed, client)\n : new Uint8Array(0);\n const combined = new Uint8Array(existing.length + newData.length);\n combined.set(existing, 0);\n combined.set(newData, existing.length);\n\n await client.query(\n `INSERT INTO ${this.#t('fs_entries')} (path, type, mode, size, mtime)\n VALUES ($1, 'file', 420, $2, $3)\n ON CONFLICT (path) DO UPDATE SET size = EXCLUDED.size, mtime = EXCLUDED.mtime`,\n [prefixed, combined.length, Date.now()],\n );\n\n await this.#writeChunks(prefixed, combined, client);\n });\n }\n\n async exists(filePath: string): Promise<boolean> {\n const normalized = this.#normalizePath(filePath);\n const prefixed = this.#prefixPath(normalized);\n const rows = await this.#query<{ exists: boolean }>(\n `SELECT EXISTS(SELECT 1 FROM ${this.#t('fs_entries')} WHERE path = $1) AS exists`,\n [prefixed],\n );\n return rows[0].exists;\n }\n\n async stat(filePath: string): Promise<FsStat> {\n const normalized = this.#normalizePath(filePath);\n const prefixed = this.#prefixPath(normalized);\n const resolved = await this.#resolveSymlink(prefixed);\n\n const rows = await this.#query<FsEntryRow>(\n `SELECT * FROM ${this.#t('fs_entries')} WHERE path = $1`,\n [resolved],\n );\n const entry = rows[0];\n\n if (!entry) {\n throw new Error(`ENOENT: no such file or directory: ${filePath}`);\n }\n\n return {\n isFile: entry.type === 'file',\n isDirectory: entry.type === 'directory',\n isSymbolicLink: false,\n mode: Number(entry.mode),\n size: Number(entry.size),\n mtime: new Date(Number(entry.mtime)),\n };\n }\n\n async lstat(filePath: string): Promise<FsStat> {\n const normalized = this.#normalizePath(filePath);\n const prefixed = this.#prefixPath(normalized);\n\n const rows = await this.#query<FsEntryRow>(\n `SELECT * FROM ${this.#t('fs_entries')} WHERE path = $1`,\n [prefixed],\n );\n const entry = rows[0];\n\n if (!entry) {\n throw new Error(`ENOENT: no such file or directory: ${filePath}`);\n }\n\n return {\n isFile: entry.type === 'file',\n isDirectory: entry.type === 'directory',\n isSymbolicLink: entry.type === 'symlink',\n mode: Number(entry.mode),\n size: Number(entry.size),\n mtime: new Date(Number(entry.mtime)),\n };\n }\n\n async mkdir(dirPath: string, options?: MkdirOptions): Promise<void> {\n const normalized = this.#normalizePath(dirPath);\n const prefixed = this.#prefixPath(normalized);\n\n const existingRows = await this.#query<Pick<FsEntryRow, 'type'>>(\n `SELECT type FROM ${this.#t('fs_entries')} WHERE path = $1`,\n [prefixed],\n );\n const existing = existingRows[0];\n\n if (existing) {\n if (options?.recursive) {\n return;\n }\n throw new Error(`EEXIST: file already exists: ${dirPath}`);\n }\n\n await this.#useTransaction(async (client) => {\n if (options?.recursive) {\n const rootPath = this.#root || '/';\n const relativePath = path.posix.relative(rootPath, prefixed);\n const segments = relativePath.split('/').filter(Boolean);\n let currentPath = rootPath;\n\n for (const segment of segments) {\n currentPath = path.posix.join(currentPath, segment);\n const result = await client.query<Pick<FsEntryRow, 'type'>>(\n `SELECT type FROM ${this.#t('fs_entries')} WHERE path = $1`,\n [currentPath],\n );\n const exists = result.rows[0];\n\n if (!exists) {\n await client.query(\n `INSERT INTO ${this.#t('fs_entries')} (path, type, mode, size, mtime) VALUES ($1, 'directory', 493, 0, $2)`,\n [currentPath, Date.now()],\n );\n } else if (exists.type !== 'directory') {\n throw new Error(`mkdir: not a directory: ${currentPath}`);\n }\n }\n } else {\n const parent = this.#dirname(prefixed);\n const parentResult = await client.query<Pick<FsEntryRow, 'type'>>(\n `SELECT type FROM ${this.#t('fs_entries')} WHERE path = $1`,\n [parent],\n );\n const parentEntry = parentResult.rows[0];\n\n if (!parentEntry) {\n throw new Error(`mkdir: parent does not exist: ${parent}`);\n }\n if (parentEntry.type !== 'directory') {\n throw new Error(`mkdir: parent is not a directory: ${parent}`);\n }\n\n await client.query(\n `INSERT INTO ${this.#t('fs_entries')} (path, type, mode, size, mtime) VALUES ($1, 'directory', 493, 0, $2)`,\n [prefixed, Date.now()],\n );\n }\n });\n }\n\n async readdir(dirPath: string): Promise<string[]> {\n const normalized = this.#normalizePath(dirPath);\n const prefixed = this.#prefixPath(normalized);\n const resolved = await this.#resolveSymlink(prefixed);\n\n const entryRows = await this.#query<Pick<FsEntryRow, 'type'>>(\n `SELECT type FROM ${this.#t('fs_entries')} WHERE path = $1`,\n [resolved],\n );\n const entry = entryRows[0];\n\n if (!entry) {\n throw new Error(`ENOENT: no such file or directory: ${dirPath}`);\n }\n if (entry.type !== 'directory') {\n throw new Error(`ENOTDIR: not a directory: ${dirPath}`);\n }\n\n const prefix = resolved === '/' ? '/' : resolved + '/';\n const rows = await this.#query<{ path: string }>(\n `SELECT path FROM ${this.#t('fs_entries')}\n WHERE path LIKE $1 || '%'\n AND path != $2\n AND path NOT LIKE $1 || '%/%'`,\n [prefix, resolved],\n );\n\n return rows.map((row) => path.posix.basename(row.path));\n }\n\n async readdirWithFileTypes(dirPath: string): Promise<DirentEntry[]> {\n const normalized = this.#normalizePath(dirPath);\n const prefixed = this.#prefixPath(normalized);\n const resolved = await this.#resolveSymlink(prefixed);\n\n const entryRows = await this.#query<Pick<FsEntryRow, 'type'>>(\n `SELECT type FROM ${this.#t('fs_entries')} WHERE path = $1`,\n [resolved],\n );\n const entry = entryRows[0];\n\n if (!entry) {\n throw new Error(`ENOENT: no such file or directory: ${dirPath}`);\n }\n if (entry.type !== 'directory') {\n throw new Error(`ENOTDIR: not a directory: ${dirPath}`);\n }\n\n const prefix = resolved === '/' ? '/' : resolved + '/';\n const rows = await this.#query<Pick<FsEntryRow, 'path' | 'type'>>(\n `SELECT path, type FROM ${this.#t('fs_entries')}\n WHERE path LIKE $1 || '%'\n AND path != $2\n AND path NOT LIKE $1 || '%/%'`,\n [prefix, resolved],\n );\n\n return rows.map((row) => ({\n name: path.posix.basename(row.path),\n isFile: row.type === 'file',\n isDirectory: row.type === 'directory',\n isSymbolicLink: row.type === 'symlink',\n }));\n }\n\n async rm(filePath: string, options?: RmOptions): Promise<void> {\n const normalized = this.#normalizePath(filePath);\n const prefixed = this.#prefixPath(normalized);\n\n const rows = await this.#query<Pick<FsEntryRow, 'type'>>(\n `SELECT type FROM ${this.#t('fs_entries')} WHERE path = $1`,\n [prefixed],\n );\n const entry = rows[0];\n\n if (!entry) {\n if (options?.force) {\n return;\n }\n throw new Error(`ENOENT: no such file or directory: ${filePath}`);\n }\n\n await this.#useTransaction(async (client) => {\n if (entry.type === 'directory') {\n const childrenResult = await client.query<{ exists: boolean }>(\n `SELECT EXISTS(SELECT 1 FROM ${this.#t('fs_entries')} WHERE path LIKE $1 || '/%') AS exists`,\n [prefixed],\n );\n\n if (childrenResult.rows[0].exists && !options?.recursive) {\n throw new Error(`ENOTEMPTY: directory not empty: ${filePath}`);\n }\n\n await client.query(\n `DELETE FROM ${this.#t('fs_entries')} WHERE path = $1 OR path LIKE $1 || '/%'`,\n [prefixed],\n );\n } else {\n await client.query(\n `DELETE FROM ${this.#t('fs_entries')} WHERE path = $1`,\n [prefixed],\n );\n }\n });\n }\n\n async cp(src: string, dest: string, options?: CpOptions): Promise<void> {\n const srcNormalized = this.#normalizePath(src);\n const destNormalized = this.#normalizePath(dest);\n const srcPrefixed = this.#prefixPath(srcNormalized);\n const destPrefixed = this.#prefixPath(destNormalized);\n\n const srcRows = await this.#query<FsEntryRow>(\n `SELECT * FROM ${this.#t('fs_entries')} WHERE path = $1`,\n [srcPrefixed],\n );\n const srcEntry = srcRows[0];\n\n if (!srcEntry) {\n throw new Error(`ENOENT: no such file or directory: ${src}`);\n }\n\n if (srcEntry.type === 'directory' && !options?.recursive) {\n throw new Error(`cp: -r not specified; omitting directory: ${src}`);\n }\n\n await this.#useTransaction(async (client) => {\n await this.#ensureParentExists(destPrefixed, client);\n\n if (srcEntry.type === 'directory') {\n const allEntriesResult = await client.query<FsEntryRow>(\n `SELECT * FROM ${this.#t('fs_entries')} WHERE path = $1 OR path LIKE $1 || '/%'`,\n [srcPrefixed],\n );\n\n for (const entry of allEntriesResult.rows) {\n const relativePath = path.posix.relative(srcPrefixed, entry.path);\n const newPath = path.posix.join(destPrefixed, relativePath);\n\n await client.query(\n `INSERT INTO ${this.#t('fs_entries')} (path, type, mode, size, mtime, symlink_target)\n VALUES ($1, $2, $3, $4, $5, $6)\n ON CONFLICT (path) DO UPDATE SET type = EXCLUDED.type, mode = EXCLUDED.mode, size = EXCLUDED.size, mtime = EXCLUDED.mtime, symlink_target = EXCLUDED.symlink_target`,\n [\n newPath,\n entry.type,\n entry.mode,\n entry.size,\n Date.now(),\n entry.symlink_target,\n ],\n );\n\n if (entry.type === 'file') {\n await client.query(\n `DELETE FROM ${this.#t('fs_chunks')} WHERE path = $1`,\n [newPath],\n );\n\n const chunksResult = await client.query<{\n chunk_index: number;\n data: Buffer;\n }>(\n `SELECT chunk_index, data FROM ${this.#t('fs_chunks')} WHERE path = $1`,\n [entry.path],\n );\n\n for (const chunk of chunksResult.rows) {\n await client.query(\n `INSERT INTO ${this.#t('fs_chunks')} (path, chunk_index, data) VALUES ($1, $2, $3)`,\n [newPath, chunk.chunk_index, chunk.data],\n );\n }\n }\n }\n } else {\n await client.query(\n `INSERT INTO ${this.#t('fs_entries')} (path, type, mode, size, mtime, symlink_target)\n VALUES ($1, $2, $3, $4, $5, $6)\n ON CONFLICT (path) DO UPDATE SET type = EXCLUDED.type, mode = EXCLUDED.mode, size = EXCLUDED.size, mtime = EXCLUDED.mtime, symlink_target = EXCLUDED.symlink_target`,\n [\n destPrefixed,\n srcEntry.type,\n srcEntry.mode,\n srcEntry.size,\n Date.now(),\n srcEntry.symlink_target,\n ],\n );\n\n if (srcEntry.type === 'file') {\n const chunksResult = await client.query<{\n chunk_index: number;\n data: Buffer;\n }>(\n `SELECT chunk_index, data FROM ${this.#t('fs_chunks')} WHERE path = $1`,\n [srcPrefixed],\n );\n\n await client.query(\n `DELETE FROM ${this.#t('fs_chunks')} WHERE path = $1`,\n [destPrefixed],\n );\n\n for (const chunk of chunksResult.rows) {\n await client.query(\n `INSERT INTO ${this.#t('fs_chunks')} (path, chunk_index, data) VALUES ($1, $2, $3)`,\n [destPrefixed, chunk.chunk_index, chunk.data],\n );\n }\n }\n }\n });\n }\n\n async mv(src: string, dest: string): Promise<void> {\n const srcNormalized = this.#normalizePath(src);\n const destNormalized = this.#normalizePath(dest);\n const srcPrefixed = this.#prefixPath(srcNormalized);\n const destPrefixed = this.#prefixPath(destNormalized);\n\n const srcRows = await this.#query<FsEntryRow>(\n `SELECT * FROM ${this.#t('fs_entries')} WHERE path = $1`,\n [srcPrefixed],\n );\n const srcEntry = srcRows[0];\n\n if (!srcEntry) {\n throw new Error(`ENOENT: no such file or directory: ${src}`);\n }\n\n await this.#useTransaction(async (client) => {\n await this.#ensureParentExists(destPrefixed, client);\n\n if (srcEntry.type === 'directory') {\n const allEntriesResult = await client.query<FsEntryRow>(\n `SELECT * FROM ${this.#t('fs_entries')} WHERE path = $1 OR path LIKE $1 || '/%' ORDER BY path DESC`,\n [srcPrefixed],\n );\n\n await client.query(\n `DELETE FROM ${this.#t('fs_entries')} WHERE path = $1 OR path LIKE $1 || '/%'`,\n [destPrefixed],\n );\n\n for (const entry of [...allEntriesResult.rows].reverse()) {\n const relativePath = path.posix.relative(srcPrefixed, entry.path);\n const newPath = path.posix.join(destPrefixed, relativePath);\n\n await client.query(\n `INSERT INTO ${this.#t('fs_entries')} (path, type, mode, size, mtime, symlink_target)\n VALUES ($1, $2, $3, $4, $5, $6)\n ON CONFLICT (path) DO UPDATE SET type = EXCLUDED.type, mode = EXCLUDED.mode, size = EXCLUDED.size, mtime = EXCLUDED.mtime, symlink_target = EXCLUDED.symlink_target`,\n [\n newPath,\n entry.type,\n entry.mode,\n entry.size,\n Date.now(),\n entry.symlink_target,\n ],\n );\n\n if (entry.type === 'file') {\n await client.query(\n `DELETE FROM ${this.#t('fs_chunks')} WHERE path = $1`,\n [newPath],\n );\n\n const chunksResult = await client.query<{\n chunk_index: number;\n data: Buffer;\n }>(\n `SELECT chunk_index, data FROM ${this.#t('fs_chunks')} WHERE path = $1`,\n [entry.path],\n );\n\n for (const chunk of chunksResult.rows) {\n await client.query(\n `INSERT INTO ${this.#t('fs_chunks')} (path, chunk_index, data) VALUES ($1, $2, $3)`,\n [newPath, chunk.chunk_index, chunk.data],\n );\n }\n }\n }\n\n await client.query(\n `DELETE FROM ${this.#t('fs_entries')} WHERE path = $1 OR path LIKE $1 || '/%'`,\n [srcPrefixed],\n );\n } else {\n await client.query(\n `INSERT INTO ${this.#t('fs_entries')} (path, type, mode, size, mtime, symlink_target)\n VALUES ($1, $2, $3, $4, $5, $6)\n ON CONFLICT (path) DO UPDATE SET type = EXCLUDED.type, mode = EXCLUDED.mode, size = EXCLUDED.size, mtime = EXCLUDED.mtime, symlink_target = EXCLUDED.symlink_target`,\n [\n destPrefixed,\n srcEntry.type,\n srcEntry.mode,\n srcEntry.size,\n Date.now(),\n srcEntry.symlink_target,\n ],\n );\n\n if (srcEntry.type === 'file') {\n await client.query(\n `DELETE FROM ${this.#t('fs_chunks')} WHERE path = $1`,\n [destPrefixed],\n );\n\n const chunksResult = await client.query<{\n chunk_index: number;\n data: Buffer;\n }>(\n `SELECT chunk_index, data FROM ${this.#t('fs_chunks')} WHERE path = $1`,\n [srcPrefixed],\n );\n\n for (const chunk of chunksResult.rows) {\n await client.query(\n `INSERT INTO ${this.#t('fs_chunks')} (path, chunk_index, data) VALUES ($1, $2, $3)`,\n [destPrefixed, chunk.chunk_index, chunk.data],\n );\n }\n }\n\n await client.query(\n `DELETE FROM ${this.#t('fs_entries')} WHERE path = $1`,\n [srcPrefixed],\n );\n }\n });\n }\n\n resolvePath(base: string, relativePath: string): string {\n return path.posix.resolve(base, relativePath);\n }\n\n getAllPaths(): string[] {\n throw new Error(\n 'getAllPaths() is not supported in PostgresFs - use getAllPathsAsync() instead',\n );\n }\n\n async getAllPathsAsync(): Promise<string[]> {\n const rows = await this.#query<{ path: string; [key: string]: unknown }>(\n `SELECT path FROM ${this.#t('fs_entries')} ORDER BY path`,\n );\n return rows.map((row) => row.path);\n }\n\n async realpath(filePath: string): Promise<string> {\n const normalized = this.#normalizePath(filePath);\n const prefixed = this.#prefixPath(normalized);\n const resolved = await this.#resolveSymlink(prefixed);\n\n const rows = await this.#query<{ exists: boolean }>(\n `SELECT EXISTS(SELECT 1 FROM ${this.#t('fs_entries')} WHERE path = $1) AS exists`,\n [resolved],\n );\n if (!rows[0].exists) {\n throw new Error(`ENOENT: no such file or directory: ${filePath}`);\n }\n\n return this.#unprefixPath(resolved);\n }\n\n async utimes(filePath: string, _atime: Date, mtime: Date): Promise<void> {\n const normalized = this.#normalizePath(filePath);\n const prefixed = this.#prefixPath(normalized);\n const resolved = await this.#resolveSymlink(prefixed);\n\n const result = await this.#exec(\n `UPDATE ${this.#t('fs_entries')} SET mtime = $1 WHERE path = $2`,\n [mtime.getTime(), resolved],\n );\n\n if (result === 0) {\n throw new Error(`ENOENT: no such file or directory: ${filePath}`);\n }\n }\n\n async chmod(filePath: string, mode: number): Promise<void> {\n const normalized = this.#normalizePath(filePath);\n const prefixed = this.#prefixPath(normalized);\n\n const result = await this.#exec(\n `UPDATE ${this.#t('fs_entries')} SET mode = $1 WHERE path = $2`,\n [mode, prefixed],\n );\n\n if (result === 0) {\n throw new Error(`ENOENT: no such file or directory: ${filePath}`);\n }\n }\n\n async symlink(target: string, linkPath: string): Promise<void> {\n const normalized = this.#normalizePath(linkPath);\n const prefixed = this.#prefixPath(normalized);\n\n const existingRows = await this.#query<{ exists: boolean }>(\n `SELECT EXISTS(SELECT 1 FROM ${this.#t('fs_entries')} WHERE path = $1) AS exists`,\n [prefixed],\n );\n if (existingRows[0].exists) {\n throw new Error(`EEXIST: file already exists: ${linkPath}`);\n }\n\n await this.#useTransaction(async (client) => {\n await this.#ensureParentExists(prefixed, client);\n\n await client.query(\n `INSERT INTO ${this.#t('fs_entries')} (path, type, mode, size, mtime, symlink_target)\n VALUES ($1, 'symlink', 511, 0, $2, $3)`,\n [prefixed, Date.now(), target],\n );\n });\n }\n\n async link(existingPath: string, newPath: string): Promise<void> {\n const srcNormalized = this.#normalizePath(existingPath);\n const destNormalized = this.#normalizePath(newPath);\n const srcPrefixed = this.#prefixPath(srcNormalized);\n const destPrefixed = this.#prefixPath(destNormalized);\n\n const srcRows = await this.#query<FsEntryRow>(\n `SELECT * FROM ${this.#t('fs_entries')} WHERE path = $1`,\n [srcPrefixed],\n );\n const srcEntry = srcRows[0];\n\n if (!srcEntry) {\n throw new Error(`ENOENT: no such file or directory: ${existingPath}`);\n }\n\n if (srcEntry.type !== 'file') {\n throw new Error(`link: not supported for directories: ${existingPath}`);\n }\n\n const existingRows = await this.#query<{ exists: boolean }>(\n `SELECT EXISTS(SELECT 1 FROM ${this.#t('fs_entries')} WHERE path = $1) AS exists`,\n [destPrefixed],\n );\n if (existingRows[0].exists) {\n throw new Error(`EEXIST: file already exists: ${newPath}`);\n }\n\n await this.#useTransaction(async (client) => {\n await this.#ensureParentExists(destPrefixed, client);\n\n await client.query(\n `INSERT INTO ${this.#t('fs_entries')} (path, type, mode, size, mtime)\n VALUES ($1, 'file', $2, $3, $4)`,\n [destPrefixed, srcEntry.mode, srcEntry.size, Date.now()],\n );\n\n const chunksResult = await client.query<{\n chunk_index: number;\n data: Buffer;\n }>(\n `SELECT chunk_index, data FROM ${this.#t('fs_chunks')} WHERE path = $1`,\n [srcPrefixed],\n );\n\n for (const chunk of chunksResult.rows) {\n await client.query(\n `INSERT INTO ${this.#t('fs_chunks')} (path, chunk_index, data) VALUES ($1, $2, $3)`,\n [destPrefixed, chunk.chunk_index, chunk.data],\n );\n }\n });\n }\n\n async readlink(linkPath: string): Promise<string> {\n const normalized = this.#normalizePath(linkPath);\n const prefixed = this.#prefixPath(normalized);\n\n const rows = await this.#query<Pick<FsEntryRow, 'type' | 'symlink_target'>>(\n `SELECT type, symlink_target FROM ${this.#t('fs_entries')} WHERE path = $1`,\n [prefixed],\n );\n const entry = rows[0];\n\n if (!entry) {\n throw new Error(`ENOENT: no such file or directory: ${linkPath}`);\n }\n\n if (entry.type !== 'symlink') {\n throw new Error(`readlink: not a symbolic link: ${linkPath}`);\n }\n\n return entry.symlink_target!;\n }\n}\n", "export function postgresFsDDL(schema: string): string {\n return `\nCREATE SCHEMA IF NOT EXISTS \"${schema}\";\n\nCREATE TABLE IF NOT EXISTS \"${schema}\".\"fs_entries\" (\n path TEXT PRIMARY KEY,\n type TEXT NOT NULL,\n mode INTEGER NOT NULL,\n size BIGINT NOT NULL,\n mtime BIGINT NOT NULL,\n symlink_target TEXT\n);\n\nCREATE INDEX IF NOT EXISTS \"idx_${schema}_fs_entries_type\" ON \"${schema}\".\"fs_entries\"(type);\n\nCREATE TABLE IF NOT EXISTS \"${schema}\".\"fs_chunks\" (\n path TEXT NOT NULL,\n chunk_index INTEGER NOT NULL,\n data BYTEA NOT NULL,\n PRIMARY KEY (path, chunk_index),\n FOREIGN KEY (path) REFERENCES \"${schema}\".\"fs_entries\"(path) ON DELETE CASCADE ON UPDATE CASCADE\n);\n`;\n}\n", "import type {\n CpOptions,\n FileContent,\n FsStat,\n IFileSystem,\n MkdirOptions,\n RmOptions,\n} from 'just-bash';\n\ntype BufferEncoding = 'utf8' | 'utf-8' | 'ascii' | 'base64' | 'hex' | 'binary';\n\ninterface ReadFileOptions {\n encoding?: BufferEncoding | null;\n}\n\ninterface WriteFileOptions {\n encoding?: BufferEncoding;\n}\n\ninterface DirentEntry {\n name: string;\n isFile: boolean;\n isDirectory: boolean;\n isSymbolicLink: boolean;\n}\n\nexport interface ScopedFsOptions {\n base: IFileSystem;\n prefix: string;\n}\n\n/**\n * Filesystem wrapper that prefixes all paths with a given prefix.\n * Enables chat-level isolation without modifying command logic.\n *\n * @example\n * const scopedFs = new ScopedFs({\n * base: fs,\n * prefix: '/chat-123',\n * });\n */\nexport class ScopedFs implements IFileSystem {\n #base: IFileSystem;\n #prefix: string;\n\n constructor(options: ScopedFsOptions) {\n this.#base = options.base;\n this.#prefix = options.prefix.replace(/\\/$/, '');\n }\n\n #scope(path: string): string {\n return `${this.#prefix}${path}`;\n }\n\n #unscope(path: string): string {\n if (path === this.#prefix) {\n return '/';\n }\n if (path.startsWith(this.#prefix + '/')) {\n return path.slice(this.#prefix.length) || '/';\n }\n return path;\n }\n\n async writeFile(\n path: string,\n content: FileContent,\n options?: WriteFileOptions | BufferEncoding,\n ): Promise<void> {\n await this.#base.writeFile(this.#scope(path), content, options);\n }\n\n async appendFile(\n path: string,\n content: FileContent,\n options?: WriteFileOptions | BufferEncoding,\n ): Promise<void> {\n await this.#base.appendFile(this.#scope(path), content, options);\n }\n\n async mkdir(path: string, options?: MkdirOptions): Promise<void> {\n return this.#base.mkdir(this.#scope(path), options);\n }\n\n async rm(path: string, options?: RmOptions): Promise<void> {\n await this.#base.rm(this.#scope(path), options);\n }\n\n async cp(src: string, dest: string, options?: CpOptions): Promise<void> {\n await this.#base.cp(this.#scope(src), this.#scope(dest), options);\n }\n\n async mv(src: string, dest: string): Promise<void> {\n await this.#base.mv(this.#scope(src), this.#scope(dest));\n }\n\n async chmod(path: string, mode: number): Promise<void> {\n return this.#base.chmod(this.#scope(path), mode);\n }\n\n async symlink(target: string, linkPath: string): Promise<void> {\n await this.#base.symlink(target, this.#scope(linkPath));\n }\n\n async link(existingPath: string, newPath: string): Promise<void> {\n await this.#base.link(this.#scope(existingPath), this.#scope(newPath));\n }\n\n readFile(\n path: string,\n options?: ReadFileOptions | BufferEncoding,\n ): Promise<string> {\n return this.#base.readFile(this.#scope(path), options);\n }\n\n readFileBuffer(path: string): Promise<Uint8Array> {\n return this.#base.readFileBuffer(this.#scope(path));\n }\n\n stat(path: string): Promise<FsStat> {\n return this.#base.stat(this.#scope(path));\n }\n\n lstat(path: string): Promise<FsStat> {\n return this.#base.lstat(this.#scope(path));\n }\n\n readdir(path: string): Promise<string[]> {\n return this.#base.readdir(this.#scope(path));\n }\n\n readdirWithFileTypes(path: string): Promise<DirentEntry[]> {\n return this.#base.readdirWithFileTypes!(this.#scope(path));\n }\n\n exists(path: string): Promise<boolean> {\n return this.#base.exists(this.#scope(path));\n }\n\n readlink(path: string): Promise<string> {\n return this.#base.readlink(this.#scope(path));\n }\n\n realpath(path: string): Promise<string> {\n return this.#base.realpath(this.#scope(path)).then((p) => this.#unscope(p));\n }\n\n utimes(path: string, atime: Date, mtime: Date): Promise<void> {\n return this.#base.utimes(this.#scope(path), atime, mtime);\n }\n\n resolvePath(base: string, relativePath: string): string {\n return this.#base.resolvePath(base, relativePath);\n }\n\n getAllPaths(): string[] {\n const allPaths = this.#base.getAllPaths?.() ?? [];\n return allPaths\n .filter((p) => p.startsWith(this.#prefix))\n .map((p) => p.slice(this.#prefix.length) || '/');\n }\n}\n", "import {\n type ContextFragment,\n clarification,\n example,\n explain,\n fragment,\n guardrail,\n hint,\n policy,\n quirk,\n reasoningFramework,\n styleGuide,\n workflow,\n} from '@deepagents/context';\n\nexport function instructions(): ContextFragment[] {\n const baseTeachings: ContextFragment[] = [\n // Include the meta-cognitive reasoning framework\n ...reasoningFramework(),\n\n // Prerequisite policies (must do X before Y)\n fragment(\n 'prerequisite_policies',\n policy({\n rule: 'YOU MUST inspect schema structure and available tables',\n before: 'generating ANY SQL query',\n reason:\n 'NEVER generate SQL without knowing valid tables, columns, and relationships',\n }),\n policy({\n rule: 'YOU MUST resolve ambiguous business terms with the user',\n before: 'making ANY assumptions about terminology meaning',\n reason:\n 'NEVER guess domain-specific language, instead ask for clarification',\n }),\n policy({\n rule: 'YOU MUST validate SQL syntax',\n before: 'executing ANY query against the database',\n reason: 'NEVER execute unvalidated queries',\n }),\n policy({\n rule: 'YOU MUST complete ALL reasoning steps',\n before: 'taking ANY tool call or response action',\n reason: 'Once an action is taken, it CANNOT be undone. NO EXCEPTIONS.',\n }),\n ),\n\n // Few-shot: Applying reasoning principles\n fragment(\n 'reasoning_examples',\n example({\n question: 'Show me sales last month',\n answer: `Applying Principle 1 (Logical dependencies):\n- Need: schema to know which table has sales data\n- Need: clarify \"last month\" = calendar month or rolling 30 days?\n\nApplying Principle 5 (Information availability):\n- Schema shows: orders table with created_at, total columns\n- Missing: user's definition of \"last month\"\n\nAction: Ask user for date range clarification BEFORE generating SQL.`,\n }),\n example({\n question: 'Why did my query return no results?',\n answer: `Applying Principle 3 (Abductive reasoning):\n- Hypothesis 1 (most likely): Filter too restrictive\n- Hypothesis 2: Data doesn't exist for that period\n- Hypothesis 3: JOIN eliminated matching rows\n\nTesting hypotheses:\n1. Remove filters one by one to isolate the issue\n2. Check date range actually has data\n3. Run subqueries separately to verify each table\n\nAction: Start with most likely hypothesis, test incrementally. NEVER guess.`,\n }),\n example({\n question: 'Get me the top customers',\n answer: `Applying Principle 1 (Logical dependencies):\n- \"Top\" is ambiguous\u2014by revenue? by order count? by recency?\n\nApplying Principle 9 (Inhibition):\n- MUST NOT generate SQL until \"top\" is defined\n\nAction: Ask user: \"Top by what metric\u2014total revenue, number of orders, or most recent activity?\"`,\n }),\n ),\n\n // Schema adherence - consolidated into clear rules\n fragment(\n 'schema_adherence',\n guardrail({\n rule: 'Use only tables and columns that exist in the schema.',\n reason:\n 'Inventing tables or columns produces invalid SQL and breaks schema grounding.',\n action:\n 'If the user requests unspecified fields, use SELECT *. When showing related items, include IDs and requested details.',\n }),\n explain({\n concept: 'query intent words',\n explanation:\n '\"Show\" asks for listing rows, while \"count\" or \"total\" asks for aggregation.',\n therefore:\n 'Use listing queries for \"show\" requests, aggregate queries for \"count\" or \"total\", and use canonical schema values verbatim in filters.',\n }),\n ),\n\n fragment(\n 'column_statistics',\n explain({\n concept: 'nDistinct in column stats',\n explanation:\n 'Positive values are the estimated count of distinct values. Negative values represent the fraction of unique rows (e.g., -1 means all rows are unique, -0.5 means 50% unique)',\n therefore:\n 'Use nDistinct to decide if GROUP BY is meaningful, if a column is a good filter candidate, or if COUNT(DISTINCT) will be expensive',\n }),\n explain({\n concept: 'correlation in column stats',\n explanation:\n 'Measures how closely the physical row order matches the logical sort order of the column. Values near 1 or -1 mean the data is well-ordered; near 0 means scattered',\n therefore:\n 'High correlation means range queries (BETWEEN, >, <) on that column benefit from index scans. Low correlation means the index is less effective for ranges',\n }),\n hint(\n 'When min/max stats are available, use them to validate filter values. If a user asks for values outside the known range, warn them the query may return no results.',\n ),\n ),\n\n // Joins - use relationship metadata\n hint(\n 'Use JOINs based on schema relationships. Favor PK/indexed columns; follow relationship metadata for direction and cardinality.',\n ),\n\n // Aggregations - explain the concepts\n fragment(\n 'aggregations',\n hint(\n 'Apply COUNT, SUM, AVG when the question implies summarization. Use window functions for ranking, running totals, or row comparisons.',\n ),\n explain({\n concept: 'counting variety vs counting rows',\n explanation:\n '\"How many types/categories/statuses exist?\" asks about variety (unique values), not total row count',\n therefore: 'Use COUNT(DISTINCT column) for variety questions',\n }),\n ),\n\n // Query semantics - explain concepts and document quirks\n fragment(\n 'query_interpretation',\n explain({\n concept: 'threshold language',\n explanation:\n 'Words like \"reach\", \"hit\", \"exceed\" with a value imply a threshold being met or passed',\n therefore:\n 'Translate to >= (greater than or equal), not = (exact match)',\n }),\n quirk({\n issue:\n 'Contradictory WHERE conditions (e.g., value > 100 AND value < 50) return empty results',\n workaround:\n 'Use INTERSECT between separate queries when finding items \"shared by\" groups with mutually exclusive conditions',\n }),\n quirk({\n issue:\n 'NULL values behave unexpectedly in comparisons and aggregations',\n workaround:\n 'Use IS NULL, IS NOT NULL, or COALESCE() to handle NULLs explicitly',\n }),\n hint(\n 'Always include mentioned filters from joined tables in WHERE conditions.',\n ),\n ),\n\n // Style preferences\n styleGuide({\n prefer:\n 'Full table names as aliases (users AS users). Descriptive column aliases (COUNT(*) AS total_count).',\n never:\n 'Abbreviated aliases (u, oi) or positional aliases (t1, t2, a, b). Schema-qualified column references on aliased tables (e.g. dbo.users.id when table is aliased) \u2014 always use the alias (users.id).',\n }),\n styleGuide({\n prefer:\n 'Concise, business-friendly summaries with key comparisons and helpful follow-ups.',\n }),\n\n // Safety guardrails - consolidated\n fragment(\n 'query_safety',\n guardrail({\n rule: 'Generate only valid, executable SELECT/WITH statements.',\n reason: 'Read-only access prevents data modification.',\n action:\n 'Never generate INSERT, UPDATE, DELETE, DROP, or DDL statements.',\n }),\n guardrail({\n rule: 'Avoid unbounded scans and cartesian joins.',\n reason: 'Protects performance and correctness.',\n action:\n 'Apply filters on indexed columns. If join keys are unclear, ask for clarification.',\n }),\n guardrail({\n rule: 'Preserve query semantics.',\n reason: 'Arbitrary modifications change results.',\n action:\n 'Only add LIMIT for explicit \"top N\" requests. Add ORDER BY for deterministic results.',\n }),\n ),\n\n hint(\n 'Use sample cell values from schema hints to match exact casing and format in WHERE conditions (e.g., \"Male\" vs \"male\" vs \"M\").',\n ),\n\n workflow({\n task: 'SQL generation',\n steps: [\n 'Schema linking: identify which tables and columns are mentioned or implied by the question.',\n 'Check if column names match question terms (e.g., Total_X). Select directly if match found.',\n 'Identify SQL patterns needed: aggregation, segmentation, time range, ranking.',\n 'Select tables and relationships. Note lookup tables and filter values from schema.',\n 'Plan join/filter/aggregation order based on table sizes and indexes.',\n 'Generate SQL that answers the question.',\n 'Verify: mentally translate SQL back to natural language. Does it match the original question?',\n ],\n }),\n\n workflow({\n task: 'Error recovery',\n triggers: ['SQL error', 'query failed', 'execution error'],\n steps: [\n 'Classify the error type: syntax error, missing join, wrong aggregation, invalid column, type mismatch.',\n 'For syntax errors: check SQL keywords, quotes, parentheses balance.',\n 'For missing join: identify unlinked tables and add appropriate JOIN clause.',\n 'For wrong aggregation: verify GROUP BY includes all non-aggregated SELECT columns.',\n 'For invalid column: re-check schema for correct column name and table.',\n 'Apply targeted fix based on error classification. Avoid blind regeneration.',\n ],\n notes:\n 'Maximum 3 retry attempts. If still failing, explain the issue to the user.',\n }),\n\n workflow({\n task: 'Complex query decomposition',\n triggers: [\n 'multiple conditions',\n 'nested requirements',\n 'compare across',\n 'for each',\n ],\n steps: [\n 'Identify if question has multiple independent parts or nested dependencies.',\n 'For independent parts: break into sub-questions, solve each, then combine with UNION or JOIN.',\n 'For nested dependencies: solve inner requirement first, use result in outer query (subquery or CTE).',\n 'For comparisons across groups: use window functions or self-joins.',\n 'Combine sub-results into final answer. Verify completeness.',\n ],\n notes:\n 'Complex questions often need CTEs (WITH clauses) for clarity and reusability.',\n }),\n\n workflow({\n task: 'Multi-turn context',\n triggers: ['follow-up', 'and also', 'what about', 'same but', 'instead'],\n steps: [\n 'Identify references to previous context: \"it\", \"that\", \"those\", \"the same\".',\n 'Resolve references using conversation history: which tables, filters, or results were mentioned.',\n 'For refinements (\"but only X\"): add filter to previous query.',\n 'For extensions (\"and also Y\"): expand SELECT or add JOIN.',\n 'For pivots (\"what about Z instead\"): replace the changed element, keep unchanged parts.',\n 'Maintain consistency with previous query structure when possible.',\n ],\n notes:\n 'If reference is ambiguous, ask which previous result or entity the user means.',\n }),\n fragment(\n 'bash_tool_usage',\n workflow({\n task: 'Query execution',\n steps: [\n 'Pick the target database by the <database> value shown at the top of each schema fragment \u2014 that is the exact connection name to pass as <db>. It is NOT the SQL-level database/schema name (e.g. SQLite\\'s default \"main\").',\n 'Execute SQL through bash tool: sql run <db> \"SELECT ...\"',\n 'Read the output: file path, column names, and row count.',\n \"Use column names to construct jq filters: cat <path> | jq '.[] | {col1, col2}'\",\n \"For large results, slice first: cat <path> | jq '.[:10]'\",\n ],\n }),\n guardrail({\n rule: 'Do not attempt SQL access through non-bash tools.',\n reason: 'SQL access is only available through the bash tool.',\n action:\n 'Use `sql run <db> \"SELECT ...\"` and `sql validate <db> \"SELECT ...\"` through bash, where `<db>` is the exact configured connection name (not the SQL-level database/schema name).',\n }),\n explain({\n concept: 'sql command output format',\n explanation:\n 'The sql command returns a file path, comma-separated column names, and a row count.',\n therefore:\n 'Use the returned column names to build precise jq queries against the output file.',\n }),\n quirk({\n issue:\n 'The SQL command is a real CLI installed inside the sandbox, so shell quoting rules apply before SQL validation runs.',\n workaround:\n 'Keep the whole SQL query in one quoted argument. If quoting is difficult, write the query to a file and call `sql validate <db> \"$(cat query.sql)\"` or `sql run <db> \"$(cat query.sql)\"`.',\n }),\n quirk({\n issue:\n 'SQL result artifacts live inside the sandbox, so you cannot access underlying SQL files directly.',\n workaround:\n 'Treat the returned result path as the artifact to inspect, rather than trying to access SQL files themselves.',\n }),\n quirk({\n issue: 'If a query fails, the sql command reports the error on stderr.',\n workaround:\n 'Read stderr first and classify the failure before retrying or changing the query.',\n }),\n ),\n fragment(\n 'clarifications',\n guardrail({\n rule: 'Do not invent an answer when the available schema, results, or user request are insufficient to determine it.',\n reason: 'Prevents hallucinations and improves trustworthiness.',\n action:\n 'State that you do not have enough information to determine the answer and ask a focused clarification question.',\n }),\n clarification({\n when: 'Ambiguous ranking language (top, best, active) without a metric.',\n ask: 'Clarify the ranking metric or definition.',\n reason: 'Ensures correct aggregation and ordering.',\n }),\n clarification({\n when: 'The request targets time-based data without a date range.',\n ask: 'Confirm the intended timeframe (e.g., last 30/90 days, YTD, specific year).',\n reason: 'Prevents large scans and irrelevant results.',\n }),\n ),\n ];\n return baseTeachings;\n}\n", "import type { CommandNode, WordNode } from 'just-bash';\nimport { parse } from 'just-bash';\n\nimport { asStaticWordText } from '@deepagents/context';\n\nexport type SqlQuerySubcommand = 'run' | 'validate';\n\nexport interface SqlQueryInvocation {\n subcommand: SqlQuerySubcommand;\n dbName: string;\n sql: string;\n}\n\n/**\n * Parse a single `sql run|validate <db> \"<sql>\"` command into its parts, or\n * `null` for anything that is not exactly one such invocation (pipelines,\n * redirections, other commands, unparseable input). Shared by the meta hook\n * (which tracks invocations to attach formatted-SQL metadata) and the\n * validate-before-run reminder predicate.\n */\nexport function parseSqlQueryInvocation(\n command: string,\n): SqlQueryInvocation | null {\n const simpleCommand = parseSingleSimpleCommand(command);\n if (!simpleCommand) return null;\n if (asStaticWordText(simpleCommand.name) !== 'sql') return null;\n if (simpleCommand.args.length < 3) return null;\n\n const subcommand = asStaticWordText(simpleCommand.args[0]);\n if (subcommand !== 'run' && subcommand !== 'validate') return null;\n\n const dbName = asStaticWordText(simpleCommand.args[1]);\n if (!dbName) return null;\n\n const sql = joinSqlWords(simpleCommand.args.slice(2));\n if (!sql) return null;\n\n return { subcommand, dbName, sql };\n}\n\nfunction parseSingleSimpleCommand(\n command: string,\n): Extract<CommandNode, { type: 'SimpleCommand' }> | null {\n const normalized = command.trim();\n if (!normalized) return null;\n\n try {\n const script = parse(normalized);\n if (script.statements.length !== 1) return null;\n\n const statement = script.statements[0];\n if (\n statement.background ||\n statement.operators.length > 0 ||\n statement.pipelines.length !== 1\n ) {\n return null;\n }\n\n const pipeline = statement.pipelines[0];\n if (pipeline.negated || pipeline.timed || pipeline.commands.length !== 1) {\n return null;\n }\n\n const commandNode = pipeline.commands[0];\n if (commandNode.type !== 'SimpleCommand') return null;\n if (\n commandNode.assignments.length > 0 ||\n commandNode.redirections.length > 0 ||\n !commandNode.name\n ) {\n return null;\n }\n\n return commandNode;\n } catch {\n return null;\n }\n}\n\nfunction joinSqlWords(words: WordNode[]): string | null {\n const values: string[] = [];\n for (const word of words) {\n const value = asStaticWordText(word, {\n preserveLegacyBackticks: true,\n });\n if (value == null) return null;\n values.push(value);\n }\n const sql = values.join(' ').trim();\n return sql || null;\n}\n", "import type { CommandResult } from '@deepagents/context';\n\nimport {\n type SqlQueryInvocation,\n parseSqlQueryInvocation,\n} from './sql-invocation.ts';\n\nexport interface SqlCommandFormatter {\n format(sql: string): string;\n}\n\nexport interface CreateSqlMetaHookOptions {\n adapters: Record<string, SqlCommandFormatter>;\n}\n\nexport interface SqlMetaTrackInput {\n repaired: string;\n transformed: string;\n}\n\nexport interface SqlMetaAfterHookInput {\n command: string;\n result: CommandResult;\n}\n\nexport function createSqlMetaHook({ adapters }: CreateSqlMetaHookOptions) {\n const pendingByCommand = new Map<string, SqlQueryInvocation[]>();\n\n return {\n track({ repaired, transformed }: SqlMetaTrackInput): void {\n const invocation = parseSqlQueryInvocation(repaired);\n if (!invocation) return;\n const pending = pendingByCommand.get(transformed) ?? [];\n pending.push(invocation);\n pendingByCommand.set(transformed, pending);\n },\n\n onAfterBashCall({ command }: SqlMetaAfterHookInput) {\n const pending = pendingByCommand.get(command);\n const invocation = pending?.shift();\n if (pending?.length === 0) pendingByCommand.delete(command);\n if (!invocation) return undefined;\n\n const adapter = adapters[invocation.dbName];\n if (!adapter) return undefined;\n\n try {\n return {\n meta: { formattedSql: adapter.format(invocation.sql) },\n };\n } catch {\n // Formatting metadata is best-effort and must not change command output.\n return undefined;\n }\n },\n };\n}\n", "import {\n type SubcommandDefinition,\n buildSubcommandRepair,\n repairQuotedArg,\n} from '@deepagents/context';\n\nfunction repairDbNameAndQuery(rawArgs: string): string | null {\n const trimmed = rawArgs.trim();\n if (!trimmed) return null;\n\n const firstSpace = trimmed.search(/\\s/);\n if (firstSpace === -1) return null;\n\n const dbName = trimmed.slice(0, firstSpace);\n const rest = trimmed.slice(firstSpace + 1);\n const repaired = repairQuotedArg(rest);\n if (repaired == null) return null;\n\n return `${dbName} ${repaired}`;\n}\n\nconst inertHandler = () => ({ stdout: '', stderr: '', exitCode: 0 });\n\nconst repair = buildSubcommandRepair('sql', {\n run: {\n usage: 'run <db> \"SELECT ...\"',\n description: 'Execute query against <db> and store results',\n repair: repairDbNameAndQuery,\n handler: inertHandler,\n },\n validate: {\n usage: 'validate <db> \"SELECT ...\"',\n description: 'Validate query syntax against <db>',\n repair: repairDbNameAndQuery,\n handler: inertHandler,\n },\n} satisfies Record<string, SubcommandDefinition>);\n\nexport function repairSqlCommand(command: string): string {\n return repair(command);\n}\n", "import { BashTransformPipeline } from 'just-bash';\n\nimport {\n SqlCommandRewritePlugin,\n SqlProxyEnforcementPlugin,\n SqlProxyViolationError,\n} from './agents/sql-transform-plugins.ts';\n\nconst sqlTransformPipeline = new BashTransformPipeline()\n .use(new SqlCommandRewritePlugin())\n .use(new SqlProxyEnforcementPlugin());\n\nexport function transformSqlCommand(command: string): string {\n try {\n return sqlTransformPipeline.transform(command).script;\n } catch (error) {\n if (error instanceof SqlProxyViolationError) {\n return blockedSqlProxyCommand(error.message);\n }\n return command;\n }\n}\n\nfunction blockedSqlProxyCommand(message: string): string {\n return `{ printf '%s\\\\n' ${shellQuote(message)} >&2; exit 1; }`;\n}\n\nfunction shellQuote(value: string): string {\n return `'${value.replace(/'/g, \"'\\\\''\")}'`;\n}\n", "import type {\n CommandNode,\n ScriptNode,\n TransformContext,\n TransformPlugin,\n TransformResult,\n WordNode,\n} from 'just-bash';\nimport { parse, serialize } from 'just-bash';\nimport { createHash } from 'node:crypto';\nimport * as path from 'node:path';\n\nimport {\n BashException,\n type CommandResult,\n asStaticWordText,\n} from '@deepagents/context';\n\nimport { isValidAdapterName } from '../adapter-name.ts';\n\nfunction isScriptNode(value: unknown): value is ScriptNode {\n if (typeof value !== 'object' || value === null) {\n return false;\n }\n const node = value as Record<string, unknown>;\n return node.type === 'Script' && Array.isArray(node.statements);\n}\n\n// \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n// SQL Proxy Enforcement Plugin\n// \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nconst BLOCKED_DB_CLIENT_COMMANDS = new Set([\n 'psql',\n 'sqlite3',\n 'mysql',\n 'duckdb',\n]);\nconst BLOCKED_RAW_SQL_COMMANDS = new Set(['select', 'with']);\nconst ALLOWED_SQL_PROXY_SUBCOMMANDS = new Set(['run', 'validate']);\nconst SHELL_INTERPRETER_COMMANDS = new Set([\n 'bash',\n 'sh',\n 'zsh',\n 'dash',\n 'ksh',\n]);\nconst WRAPPER_COMMANDS = new Set(['env', 'command', 'eval']);\n\nconst SQL_PROXY_ENFORCEMENT_MESSAGE = [\n 'Direct database querying through bash is blocked.',\n 'Use SQL proxy commands in this order:',\n '1) sql validate <db> \"SELECT ...\"',\n '2) sql run <db> \"SELECT ...\"',\n].join('\\n');\n\nexport class SqlProxyViolationError extends BashException {\n constructor() {\n super(SQL_PROXY_ENFORCEMENT_MESSAGE);\n this.name = 'SqlProxyViolationError';\n }\n\n format(): CommandResult {\n return { stdout: '', stderr: `${this.message}\\n`, exitCode: 1 };\n }\n}\n\ntype SqlInspectionMode = 'blocked-only' | 'block-all-sql';\n\ntype FunctionDefCommand = Extract<CommandNode, { type: 'FunctionDef' }>;\n\ninterface InspectionContext {\n functionDefinitions: Map<string, FunctionDefCommand>;\n callStack: Set<string>;\n}\n\ninterface CommandInspectionOptions {\n stdinFromPipe: boolean;\n}\n\ninterface ShellInvocationDescriptor {\n kind: 'command' | 'script' | 'stdin' | 'none' | 'unknown';\n payload: string | null;\n}\n\ninterface WrapperCommandResolution {\n kind: 'resolved' | 'none' | 'unknown';\n name?: WordNode;\n args?: WordNode[];\n}\n\nfunction cloneInspectionContext(context: InspectionContext): InspectionContext {\n return {\n functionDefinitions: new Map(context.functionDefinitions),\n callStack: new Set(context.callStack),\n };\n}\n\nfunction scriptContainsBlockedCommand(\n script: ScriptNode,\n context: InspectionContext,\n mode: SqlInspectionMode = 'blocked-only',\n): boolean {\n return statementsContainBlockedCommand(script.statements, context, mode);\n}\n\nfunction statementsContainBlockedCommand(\n statements: Array<{ pipelines: Array<{ commands: CommandNode[] }> }>,\n context: InspectionContext,\n mode: SqlInspectionMode,\n): boolean {\n for (const statement of statements) {\n if (statementContainsBlockedCommand(statement, context, mode)) {\n return true;\n }\n }\n return false;\n}\n\nfunction statementContainsBlockedCommand(\n statement: { pipelines: Array<{ commands: CommandNode[] }> },\n context: InspectionContext,\n mode: SqlInspectionMode,\n): boolean {\n for (const pipeline of statement.pipelines) {\n if (pipelineContainsBlockedCommand(pipeline, context, mode)) {\n return true;\n }\n }\n return false;\n}\n\nfunction pipelineContainsBlockedCommand(\n pipeline: { commands: CommandNode[] },\n context: InspectionContext,\n mode: SqlInspectionMode,\n): boolean {\n for (const [index, command] of pipeline.commands.entries()) {\n if (command.type === 'FunctionDef') {\n context.functionDefinitions.set(command.name, command);\n continue;\n }\n if (\n commandContainsBlockedCommand(command, context, mode, {\n stdinFromPipe: index > 0,\n })\n ) {\n return true;\n }\n }\n return false;\n}\n\nfunction stringCommandContainsBlockedCommand(\n command: string,\n context: InspectionContext,\n mode: SqlInspectionMode = 'blocked-only',\n): boolean {\n let script: ScriptNode;\n try {\n script = parse(command);\n } catch {\n return false;\n }\n\n return scriptContainsBlockedCommand(\n script,\n cloneInspectionContext(context),\n mode,\n );\n}\n\nfunction wordContainsBlockedCommand(\n word: WordNode | null | undefined,\n context: InspectionContext,\n mode: SqlInspectionMode,\n): boolean {\n if (!word) {\n return false;\n }\n\n return wordPartContainsBlockedCommand(\n word.parts as unknown as Array<Record<string, unknown>>,\n context,\n mode,\n );\n}\n\nfunction wordPartContainsBlockedCommand(\n parts: Array<Record<string, unknown>>,\n context: InspectionContext,\n mode: SqlInspectionMode,\n): boolean {\n for (const part of parts) {\n if (partContainsBlockedCommand(part, context, mode)) {\n return true;\n }\n }\n return false;\n}\n\nfunction partContainsBlockedCommand(\n node: Record<string, unknown>,\n context: InspectionContext,\n mode: SqlInspectionMode,\n): boolean {\n const type = node.type;\n\n if (type === 'CommandSubstitution' || type === 'ProcessSubstitution') {\n if (isScriptNode(node.body)) {\n return scriptContainsBlockedCommand(\n node.body,\n cloneInspectionContext(context),\n mode,\n );\n }\n return false;\n }\n\n if (type === 'ArithCommandSubst' && typeof node.command === 'string') {\n return stringCommandContainsBlockedCommand(node.command, context, mode);\n }\n\n for (const value of Object.values(node)) {\n if (Array.isArray(value)) {\n for (const item of value) {\n if (typeof item === 'object' && item !== null) {\n if (\n partContainsBlockedCommand(\n item as Record<string, unknown>,\n context,\n mode,\n )\n ) {\n return true;\n }\n }\n }\n continue;\n }\n\n if (typeof value === 'object' && value !== null) {\n if (\n partContainsBlockedCommand(\n value as Record<string, unknown>,\n context,\n mode,\n )\n ) {\n return true;\n }\n }\n }\n\n return false;\n}\n\nfunction functionInvocationContainsBlockedCommand(\n functionName: string,\n context: InspectionContext,\n mode: SqlInspectionMode,\n): boolean {\n const definition = context.functionDefinitions.get(functionName);\n if (!definition) {\n return false;\n }\n\n if (context.callStack.has(functionName)) {\n return false;\n }\n\n const invocationContext = cloneInspectionContext(context);\n invocationContext.callStack.add(functionName);\n return commandContainsBlockedCommand(\n definition.body,\n invocationContext,\n mode,\n { stdinFromPipe: false },\n );\n}\n\nfunction isAsciiLetter(character: string): boolean {\n const charCode = character.charCodeAt(0);\n return (\n (charCode >= 65 && charCode <= 90) || (charCode >= 97 && charCode <= 122)\n );\n}\n\nfunction isAsciiDigit(character: string): boolean {\n const charCode = character.charCodeAt(0);\n return charCode >= 48 && charCode <= 57;\n}\n\nfunction isValidEnvVariableName(name: string): boolean {\n if (!name) {\n return false;\n }\n\n const firstChar = name[0];\n if (!(isAsciiLetter(firstChar) || firstChar === '_')) {\n return false;\n }\n\n for (let index = 1; index < name.length; index += 1) {\n const char = name[index];\n if (!(isAsciiLetter(char) || isAsciiDigit(char) || char === '_')) {\n return false;\n }\n }\n\n return true;\n}\n\nfunction isEnvAssignmentToken(token: string): boolean {\n const separatorIndex = token.indexOf('=');\n if (separatorIndex <= 0) {\n return false;\n }\n\n return isValidEnvVariableName(token.slice(0, separatorIndex));\n}\n\nfunction parseShortOptionCluster(option: string): {\n valid: boolean;\n hasCommandFlag: boolean;\n hasStdinFlag: boolean;\n consumesNextArg: boolean;\n} {\n if (\n !option.startsWith('-') ||\n option.startsWith('--') ||\n option.length <= 1\n ) {\n return {\n valid: false,\n hasCommandFlag: false,\n hasStdinFlag: false,\n consumesNextArg: false,\n };\n }\n\n let hasCommandFlag = false;\n let hasStdinFlag = false;\n let consumesNextArg = false;\n\n for (let index = 1; index < option.length; index += 1) {\n const char = option[index];\n if (!isAsciiLetter(char)) {\n return {\n valid: false,\n hasCommandFlag: false,\n hasStdinFlag: false,\n consumesNextArg: false,\n };\n }\n\n if (char === 'c') {\n hasCommandFlag = true;\n } else if (char === 's') {\n hasStdinFlag = true;\n } else if (char === 'O' || char === 'o') {\n consumesNextArg = true;\n }\n }\n\n return { valid: true, hasCommandFlag, hasStdinFlag, consumesNextArg };\n}\n\nfunction getShellInvocationDescriptor(\n args: WordNode[],\n): ShellInvocationDescriptor {\n let readsFromStdin = false;\n const longOptionsWithValue = new Set(['--rcfile', '--init-file']);\n\n for (let index = 0; index < args.length; index += 1) {\n const token = asStaticWordText(args[index]);\n if (token == null) {\n return { kind: 'unknown', payload: null };\n }\n\n if (token === '--') {\n if (index + 1 >= args.length) {\n break;\n }\n return {\n kind: 'script',\n payload: asStaticWordText(args[index + 1]),\n };\n }\n\n if (token === '--command') {\n return {\n kind: 'command',\n payload: asStaticWordText(args[index + 1]),\n };\n }\n\n if (token.startsWith('--command=')) {\n return {\n kind: 'command',\n payload: token.slice('--command='.length),\n };\n }\n\n if (token.startsWith('--')) {\n if (token.includes('=')) {\n continue;\n }\n\n if (longOptionsWithValue.has(token)) {\n if (index + 1 >= args.length) {\n return { kind: 'unknown', payload: null };\n }\n index += 1;\n }\n continue;\n }\n\n if (token.startsWith('-') && !token.startsWith('--')) {\n const parsed = parseShortOptionCluster(token);\n if (!parsed.valid) {\n return { kind: 'unknown', payload: null };\n }\n\n if (parsed.hasCommandFlag) {\n return {\n kind: 'command',\n payload: asStaticWordText(args[index + 1]),\n };\n }\n\n if (parsed.hasStdinFlag) {\n readsFromStdin = true;\n }\n\n if (parsed.consumesNextArg) {\n if (index + 1 >= args.length) {\n return { kind: 'unknown', payload: null };\n }\n index += 1;\n }\n continue;\n }\n\n return {\n kind: 'script',\n payload: token,\n };\n }\n\n if (readsFromStdin) {\n return { kind: 'stdin', payload: null };\n }\n\n return { kind: 'none', payload: null };\n}\n\nfunction getHereDocPayload(\n redirections: Array<{\n target: { type?: string; content?: WordNode };\n }>,\n): { hasHereDoc: boolean; payload: string | null } {\n const payloads: string[] = [];\n\n for (const redirection of redirections) {\n if (redirection.target.type !== 'HereDoc') {\n continue;\n }\n\n if (!redirection.target.content) {\n payloads.push('');\n continue;\n }\n\n const payload = asStaticWordText(redirection.target.content);\n if (payload == null) {\n return { hasHereDoc: true, payload: null };\n }\n\n payloads.push(payload);\n }\n\n if (payloads.length === 0) {\n return { hasHereDoc: false, payload: null };\n }\n\n return { hasHereDoc: true, payload: payloads.join('\\n') };\n}\n\nfunction joinStaticWords(words: WordNode[]): string | null {\n const tokens: string[] = [];\n\n for (const word of words) {\n const token = asStaticWordText(word);\n if (token == null) {\n return null;\n }\n tokens.push(token);\n }\n\n return tokens.join(' ');\n}\n\nfunction resolveEnvWrapperCommand(args: WordNode[]): WrapperCommandResolution {\n let index = 0;\n\n while (index < args.length) {\n const token = asStaticWordText(args[index]);\n if (token == null) {\n return { kind: 'unknown' };\n }\n\n if (token === '--') {\n index += 1;\n break;\n }\n\n if (token === '-u' || token === '--unset' || token === '--chdir') {\n if (index + 1 >= args.length) {\n return { kind: 'unknown' };\n }\n index += 2;\n continue;\n }\n\n if (token.startsWith('--unset=') || token.startsWith('--chdir=')) {\n index += 1;\n continue;\n }\n\n if (\n token.startsWith('-') &&\n token !== '-' &&\n !isEnvAssignmentToken(token)\n ) {\n index += 1;\n continue;\n }\n\n if (isEnvAssignmentToken(token)) {\n index += 1;\n continue;\n }\n\n break;\n }\n\n if (index >= args.length) {\n return { kind: 'none' };\n }\n\n return {\n kind: 'resolved',\n name: args[index],\n args: args.slice(index + 1),\n };\n}\n\nfunction resolveCommandWrapperCommand(\n args: WordNode[],\n): WrapperCommandResolution {\n let index = 0;\n let lookupOnly = false;\n\n while (index < args.length) {\n const token = asStaticWordText(args[index]);\n if (token == null) {\n return { kind: 'unknown' };\n }\n\n if (token === '--') {\n index += 1;\n break;\n }\n\n if (token === '-v' || token === '-V') {\n lookupOnly = true;\n index += 1;\n continue;\n }\n\n if (token.startsWith('-') && token !== '-') {\n index += 1;\n continue;\n }\n\n break;\n }\n\n if (lookupOnly || index >= args.length) {\n return { kind: 'none' };\n }\n\n return {\n kind: 'resolved',\n name: args[index],\n args: args.slice(index + 1),\n };\n}\n\nfunction commandContainsBlockedCommand(\n command: CommandNode,\n context: InspectionContext,\n mode: SqlInspectionMode,\n options: CommandInspectionOptions = { stdinFromPipe: false },\n): boolean {\n switch (command.type) {\n case 'SimpleCommand':\n return isBlockedSimpleCommand(command, context, mode, options);\n case 'If':\n return (\n command.clauses.some(\n (clause) =>\n statementsContainBlockedCommand(\n clause.condition,\n cloneInspectionContext(context),\n mode,\n ) ||\n statementsContainBlockedCommand(\n clause.body,\n cloneInspectionContext(context),\n mode,\n ),\n ) ||\n (command.elseBody\n ? statementsContainBlockedCommand(\n command.elseBody,\n cloneInspectionContext(context),\n mode,\n )\n : false)\n );\n case 'For':\n case 'CStyleFor':\n return statementsContainBlockedCommand(\n command.body,\n cloneInspectionContext(context),\n mode,\n );\n case 'While':\n case 'Until':\n return (\n statementsContainBlockedCommand(\n command.condition,\n cloneInspectionContext(context),\n mode,\n ) ||\n statementsContainBlockedCommand(\n command.body,\n cloneInspectionContext(context),\n mode,\n )\n );\n case 'Case':\n return command.items.some((item) =>\n statementsContainBlockedCommand(\n item.body,\n cloneInspectionContext(context),\n mode,\n ),\n );\n case 'Subshell':\n case 'Group':\n return statementsContainBlockedCommand(\n command.body,\n cloneInspectionContext(context),\n mode,\n );\n case 'FunctionDef':\n return false;\n case 'ArithmeticCommand':\n case 'ConditionalCommand':\n return false;\n default: {\n const _unreachable: never = command;\n return _unreachable;\n }\n }\n}\n\nfunction isBlockedSimpleCommand(\n command: {\n name: WordNode | null;\n args: WordNode[];\n assignments: Array<{\n value: WordNode | null;\n array: WordNode[] | null;\n }>;\n redirections: Array<{\n target: { type?: string; content?: WordNode };\n }>;\n },\n context: InspectionContext,\n mode: SqlInspectionMode,\n options: CommandInspectionOptions,\n): boolean {\n if (wordContainsBlockedCommand(command.name, context, mode)) {\n return true;\n }\n\n if (\n command.args.some((arg) => wordContainsBlockedCommand(arg, context, mode))\n ) {\n return true;\n }\n\n if (\n command.assignments.some(\n (assignment) =>\n wordContainsBlockedCommand(assignment.value, context, mode) ||\n (assignment.array?.some((value) =>\n wordContainsBlockedCommand(value, context, mode),\n ) ??\n false),\n )\n ) {\n return true;\n }\n\n if (\n command.redirections.some((redirection) => {\n if (redirection.target.type === 'Word') {\n return wordContainsBlockedCommand(\n redirection.target as unknown as WordNode,\n context,\n mode,\n );\n }\n if (redirection.target.type === 'HereDoc' && redirection.target.content) {\n return wordContainsBlockedCommand(\n redirection.target.content,\n context,\n mode,\n );\n }\n return false;\n })\n ) {\n return true;\n }\n\n const commandName = asStaticWordText(command.name);\n if (!commandName) {\n return false;\n }\n\n const normalizedName = path.posix.basename(commandName).toLowerCase();\n\n if (BLOCKED_DB_CLIENT_COMMANDS.has(normalizedName)) {\n return true;\n }\n\n if (BLOCKED_RAW_SQL_COMMANDS.has(normalizedName)) {\n return true;\n }\n\n if (normalizedName === 'sql') {\n const subcommand = asStaticWordText(command.args[0])?.toLowerCase();\n if (!subcommand) {\n return true;\n }\n if (mode === 'block-all-sql') {\n return true;\n }\n return !ALLOWED_SQL_PROXY_SUBCOMMANDS.has(subcommand);\n }\n\n const inspectWrappedCommand = (\n resolved: WrapperCommandResolution,\n ): boolean => {\n if (resolved.kind === 'none') {\n return false;\n }\n\n if (resolved.kind === 'unknown' || !resolved.name || !resolved.args) {\n return true;\n }\n\n return isBlockedSimpleCommand(\n {\n name: resolved.name,\n args: resolved.args,\n assignments: [],\n redirections: [],\n },\n context,\n 'block-all-sql',\n options,\n );\n };\n\n if (WRAPPER_COMMANDS.has(normalizedName)) {\n if (normalizedName === 'env') {\n return inspectWrappedCommand(resolveEnvWrapperCommand(command.args));\n }\n\n if (normalizedName === 'command') {\n return inspectWrappedCommand(resolveCommandWrapperCommand(command.args));\n }\n\n const evalScript = joinStaticWords(command.args);\n if (evalScript == null) {\n return true;\n }\n if (!evalScript.trim()) {\n return false;\n }\n return stringCommandContainsBlockedCommand(\n evalScript,\n context,\n 'block-all-sql',\n );\n }\n\n if (SHELL_INTERPRETER_COMMANDS.has(normalizedName)) {\n const shellInvocation = getShellInvocationDescriptor(command.args);\n if (shellInvocation.kind === 'unknown') {\n return true;\n }\n\n if (shellInvocation.kind === 'command') {\n if (!shellInvocation.payload) {\n return true;\n }\n if (\n stringCommandContainsBlockedCommand(\n shellInvocation.payload,\n context,\n 'block-all-sql',\n )\n ) {\n return true;\n }\n return false;\n }\n\n const hereDoc = getHereDocPayload(command.redirections);\n if (hereDoc.hasHereDoc) {\n if (hereDoc.payload == null) {\n return true;\n }\n if (\n hereDoc.payload.trim().length > 0 &&\n stringCommandContainsBlockedCommand(\n hereDoc.payload,\n context,\n 'block-all-sql',\n )\n ) {\n return true;\n }\n }\n\n if (shellInvocation.kind === 'script') {\n return true;\n }\n\n if (options.stdinFromPipe || shellInvocation.kind === 'stdin') {\n return !hereDoc.hasHereDoc;\n }\n }\n\n if (functionInvocationContainsBlockedCommand(commandName, context, mode)) {\n return true;\n }\n\n return false;\n}\n\nexport interface SqlProxyEnforcementMetadata {\n inspected: true;\n}\n\nexport class SqlProxyEnforcementPlugin implements TransformPlugin<SqlProxyEnforcementMetadata> {\n name = 'sql-proxy-enforcement';\n\n transform(\n context: TransformContext,\n ): TransformResult<SqlProxyEnforcementMetadata> {\n const blocked = scriptContainsBlockedCommand(context.ast, {\n functionDefinitions: new Map(),\n callStack: new Set(),\n });\n\n if (blocked) {\n throw new SqlProxyViolationError();\n }\n\n return {\n ast: context.ast,\n metadata: { inspected: true },\n };\n }\n}\n\n// \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n// SQL Backtick Rewrite Plugin\n// \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nfunction wordPartsContainExpansion(\n parts: Array<Record<string, unknown>>,\n): boolean {\n for (const part of parts) {\n if (\n part.type === 'CommandSubstitution' ||\n part.type === 'ParameterExpansion' ||\n part.type === 'ArithmeticExpansion'\n ) {\n return true;\n }\n\n if (part.type === 'DoubleQuoted' && Array.isArray(part.parts)) {\n if (\n wordPartsContainExpansion(part.parts as Array<Record<string, unknown>>)\n ) {\n return true;\n }\n }\n }\n\n return false;\n}\n\nexport interface SqlCommandRewriteMetadata {\n rewritten: boolean;\n}\n\nfunction isSqlCommandRequiringRewrite(\n cmd: CommandNode,\n): cmd is Extract<CommandNode, { type: 'SimpleCommand' }> {\n if (cmd.type !== 'SimpleCommand') return false;\n if (cmd.assignments.length > 0 || cmd.redirections.length > 0) return false;\n if (asStaticWordText(cmd.name) !== 'sql') return false;\n if (cmd.args.length < 3) return false;\n\n const subcommand = asStaticWordText(cmd.args[0]);\n if (subcommand !== 'validate' && subcommand !== 'run') return false;\n\n const dbName = asStaticWordText(cmd.args[1]);\n if (!isValidAdapterName(dbName)) return false;\n\n const sqlArgs = cmd.args.slice(2);\n if (sqlArgs.length > 1) return true;\n return sqlArgs.some((arg: WordNode) =>\n wordPartsContainExpansion(\n arg.parts as unknown as Array<Record<string, unknown>>,\n ),\n );\n}\n\nfunction extractWordPartText(parts: Array<Record<string, unknown>>): string {\n let text = '';\n for (const part of parts) {\n const type = part.type;\n if (type === 'Literal' || type === 'SingleQuoted' || type === 'Escaped') {\n text += part.value as string;\n } else if (type === 'DoubleQuoted' && Array.isArray(part.parts)) {\n text += extractWordPartText(part.parts as Array<Record<string, unknown>>);\n } else if (type === 'CommandSubstitution' && part.legacy === true) {\n text += '`' + serialize(part.body as ScriptNode).trim() + '`';\n } else if (type === 'CommandSubstitution') {\n text += '$(' + serialize(part.body as ScriptNode).trim() + ')';\n } else if (type === 'ParameterExpansion') {\n text += emitParameterExpansion(part);\n } else if (type === 'ArithmeticExpansion') {\n const expression = part.expression as\n | { originalText?: string }\n | undefined;\n text += '$((' + (expression?.originalText ?? '') + '))';\n }\n }\n return text;\n}\n\nfunction emitParameterExpansion(part: Record<string, unknown>): string {\n const parameter = part.parameter as string;\n const operation = part.operation as\n | {\n type: string;\n word?: { parts: Array<Record<string, unknown>> };\n checkEmpty?: boolean;\n }\n | null\n | undefined;\n if (!operation) return '$' + parameter;\n if (operation.type === 'DefaultValue' && operation.word) {\n const fallback = extractWordPartText(operation.word.parts);\n const separator = operation.checkEmpty ? ':-' : '-';\n return '${' + parameter + separator + fallback + '}';\n }\n return '${' + parameter + '}';\n}\n\nfunction extractSqlText(args: WordNode[]): string {\n return args\n .map((arg) =>\n extractWordPartText(\n arg.parts as unknown as Array<Record<string, unknown>>,\n ),\n )\n .join(' ');\n}\n\nfunction rewriteSqlCommand(\n cmd: Extract<CommandNode, { type: 'SimpleCommand' }>,\n ast: ScriptNode,\n): CommandNode {\n const subcommand = asStaticWordText(cmd.args[0])!;\n const dbName = asStaticWordText(cmd.args[1])!;\n const sqlArgs = cmd.args.slice(2);\n const unquotedSql = extractSqlText(sqlArgs);\n\n const hash = createHash('sha256')\n .update(serialize(ast))\n .digest('hex')\n .slice(0, 12);\n const sqlPath = `/tmp/sql-inline-${subcommand}-${hash}.sql`;\n const heredocTag = `SQL_${hash.toUpperCase()}`;\n\n const groupScript = [\n `{ cat > ${sqlPath} <<'${heredocTag}'`,\n unquotedSql,\n heredocTag,\n `sql ${subcommand} ${dbName} \"$(cat ${sqlPath})\"; }`,\n ].join('\\n');\n\n const groupAst = parse(groupScript);\n return groupAst.statements[0].pipelines[0].commands[0];\n}\n\nfunction rewriteSqlCommandsInList(\n commands: CommandNode[],\n ast: ScriptNode,\n): boolean {\n let rewritten = false;\n for (let i = 0; i < commands.length; i++) {\n const cmd = commands[i];\n if (isSqlCommandRequiringRewrite(cmd)) {\n commands[i] = rewriteSqlCommand(cmd, ast);\n rewritten = true;\n continue;\n }\n\n if (cmd.type === 'If') {\n for (const clause of cmd.clauses) {\n if (rewriteSqlCommandsInStatements(clause.condition, ast))\n rewritten = true;\n if (rewriteSqlCommandsInStatements(clause.body, ast)) rewritten = true;\n }\n if (cmd.elseBody && rewriteSqlCommandsInStatements(cmd.elseBody, ast)) {\n rewritten = true;\n }\n } else if (cmd.type === 'While' || cmd.type === 'Until') {\n if (rewriteSqlCommandsInStatements(cmd.condition, ast)) rewritten = true;\n if (rewriteSqlCommandsInStatements(cmd.body, ast)) rewritten = true;\n } else if (cmd.type === 'For' || cmd.type === 'CStyleFor') {\n if (rewriteSqlCommandsInStatements(cmd.body, ast)) rewritten = true;\n } else if (cmd.type === 'Case') {\n for (const item of cmd.items) {\n if (rewriteSqlCommandsInStatements(item.body, ast)) rewritten = true;\n }\n } else if (cmd.type === 'Subshell' || cmd.type === 'Group') {\n if (rewriteSqlCommandsInStatements(cmd.body, ast)) rewritten = true;\n }\n }\n return rewritten;\n}\n\nfunction rewriteSqlCommandsInStatements(\n statements: Array<{ pipelines: Array<{ commands: CommandNode[] }> }>,\n ast: ScriptNode,\n): boolean {\n let rewritten = false;\n for (const statement of statements) {\n for (const pipeline of statement.pipelines) {\n if (rewriteSqlCommandsInList(pipeline.commands, ast)) {\n rewritten = true;\n }\n }\n }\n return rewritten;\n}\n\nexport class SqlCommandRewritePlugin implements TransformPlugin<SqlCommandRewriteMetadata> {\n name = 'sql-command-rewrite';\n\n transform(\n context: TransformContext,\n ): TransformResult<SqlCommandRewriteMetadata> {\n const ast = context.ast;\n const rewritten = rewriteSqlCommandsInStatements(ast.statements, ast);\n return { ast, metadata: { rewritten } };\n }\n}\n", "import {\n type CreateSqlMetaHookOptions,\n createSqlMetaHook,\n} from './sql-meta-hook.ts';\nimport { repairSqlCommand } from './sql-repair.ts';\nimport { transformSqlCommand } from './sql-transform.ts';\n\nexport { createSqlMetaHook } from './sql-meta-hook.ts';\nexport type {\n CreateSqlMetaHookOptions,\n SqlCommandFormatter,\n} from './sql-meta-hook.ts';\nexport { repairSqlCommand } from './sql-repair.ts';\nexport { transformSqlCommand } from './sql-transform.ts';\n\nexport type CreateSqlCommandHooksOptions = CreateSqlMetaHookOptions;\n\nexport function createSqlCommandHooks({\n adapters,\n}: CreateSqlCommandHooksOptions) {\n const meta = createSqlMetaHook({ adapters });\n\n return {\n onBeforeBashCall: ({ command }: { command: string }) => {\n const repaired = repairSqlCommand(command);\n const transformed = transformSqlCommand(repaired);\n meta.track({ repaired, transformed });\n return { command: transformed };\n },\n onAfterBashCall: meta.onAfterBashCall,\n };\n}\n", "import type { Command, CommandContext, ExecResult } from 'just-bash';\nimport { posix } from 'node:path';\nimport { parseArgs } from 'node:util';\nimport { v7 } from 'uuid';\n\nimport {\n BashException,\n type CommandResult,\n buildSubcommandRepair,\n defineSubcommandGroup,\n repairQuotedArg,\n} from '@deepagents/context';\n\nimport { Text2Sql, Text2SqlValidationError } from './sql.ts';\n\nclass SqlCommandError extends BashException {\n readonly #subcommand: string;\n readonly #exitCode: number;\n\n constructor(subcommand: string, message: string, exitCode = 1) {\n super(message);\n this.name = 'SqlCommandError';\n this.#subcommand = subcommand;\n this.#exitCode = exitCode;\n }\n\n format(): CommandResult {\n return {\n stdout: '',\n stderr: `sql ${this.#subcommand}: ${this.message}\\n`,\n exitCode: this.#exitCode,\n };\n }\n}\n\nexport interface CreateSqlCommandOptions {\n /**\n * Default directory for `sql run` artifacts when no `--out-dir` is passed\n * and `$TEXT2SQL_OUT_DIR` is unset. Defaults to `/sql`.\n */\n outputDir?: string;\n}\n\nexport interface CreateSqlCommandResult {\n command: Command;\n repair: (raw: string) => string;\n}\n\n/**\n * Wrap a {@link Text2Sql} instance as a just-bash custom command, exposing\n * `sql run` and `sql validate` inside any sandbox that accepts\n * `customCommands` (e.g. `createVirtualSandbox`). Argv matches the standalone\n * `sql` CLI exactly, so prompts written against one work against the other.\n *\n * Bootstrap (schema indexing) is intentionally **not** exposed as a\n * subcommand here \u2014 callers running an in-process sandbox should invoke\n * `text2Sql.index()` directly on the host before constructing the sandbox.\n *\n * @example\n * ```ts\n * const text2Sql = new Text2Sql({\n * adapters: { pagila },\n * lock: new FileIndexLock(),\n * });\n * const { command } = createSqlCommand(text2Sql);\n * const sandbox = await createVirtualSandbox({\n * fs: new InMemoryFs(),\n * customCommands: [command],\n * });\n * await sandbox.executeCommand('sql run pagila \"SELECT 1\"');\n * ```\n */\nexport function createSqlCommand(\n text2Sql: Text2Sql,\n options: CreateSqlCommandOptions = {},\n): CreateSqlCommandResult {\n const defaultOutputDir = options.outputDir ?? '/sql';\n\n const subcommands = {\n run: {\n usage: 'run <db> \"SELECT ...\"',\n description: 'Execute query against <db> and store results',\n repair: repairDbNameAndQuotedArg,\n handler: (args: string[], ctx: CommandContext) =>\n handleRun(text2Sql, defaultOutputDir, args, ctx),\n },\n validate: {\n usage: 'validate <db> \"SELECT ...\"',\n description: 'Validate query syntax against <db>',\n repair: repairDbNameAndQuotedArg,\n handler: (args: string[]) => handleValidate(text2Sql, args),\n },\n };\n\n return {\n command: defineSubcommandGroup('sql', subcommands),\n repair: buildSubcommandRepair('sql', subcommands),\n };\n}\n\ninterface ParsedFlags {\n positional: string[];\n outDir?: string;\n}\n\nfunction parseFlags(subcommand: string, args: string[]): ParsedFlags {\n try {\n const parsed = parseArgs({\n args,\n options: { 'out-dir': { type: 'string' } },\n allowPositionals: true,\n strict: true,\n });\n return {\n positional: parsed.positionals,\n outDir: parsed.values['out-dir'],\n };\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error);\n throw new SqlCommandError(subcommand, message);\n }\n}\n\nfunction resolveOutputDir(\n ctx: CommandContext,\n flags: ParsedFlags,\n fallback: string,\n): string {\n const envOutDir = ctx.env.get('TEXT2SQL_OUT_DIR');\n const candidate = flags.outDir ?? envOutDir ?? fallback;\n return posix.isAbsolute(candidate)\n ? candidate\n : posix.resolve(ctx.cwd, candidate);\n}\n\nasync function handleRun(\n text2Sql: Text2Sql,\n defaultOutputDir: string,\n args: string[],\n ctx: CommandContext,\n): Promise<ExecResult> {\n return runHandler('run', async () => {\n const flags = parseFlags('run', args);\n const { name, sql } = takeDbAndSql('run', flags.positional, text2Sql);\n const outputDir = resolveOutputDir(ctx, flags, defaultOutputDir);\n const { rows, columns } = await text2Sql.run(name, sql);\n\n const outPath = posix.join(outputDir, `${v7()}.json`);\n await ctx.fs.mkdir(outputDir, { recursive: true });\n await ctx.fs.writeFile(outPath, JSON.stringify(rows, null, 2));\n\n return {\n stdout:\n `results stored in ${outPath}\\n` +\n `columns: ${columns.join(', ') || '(none)'}\\n` +\n `rows: ${rows.length}\\n`,\n stderr: '',\n exitCode: 0,\n };\n });\n}\n\nasync function handleValidate(\n text2Sql: Text2Sql,\n args: string[],\n): Promise<ExecResult> {\n return runHandler('validate', async () => {\n const flags = parseFlags('validate', args);\n const { name, sql } = takeDbAndSql('validate', flags.positional, text2Sql);\n await text2Sql.validate(name, sql);\n return { stdout: 'valid\\n', stderr: '', exitCode: 0 };\n });\n}\n\nasync function runHandler(\n subcommand: string,\n fn: () => Promise<ExecResult>,\n): Promise<ExecResult> {\n try {\n return await fn();\n } catch (error) {\n if (error instanceof BashException) return error.format();\n if (Text2SqlValidationError.isInstance(error)) {\n return new SqlCommandError(subcommand, error.message).format();\n }\n const message = error instanceof Error ? error.message : String(error);\n return new SqlCommandError(subcommand, message).format();\n }\n}\n\nfunction takeDbAndSql(\n subcommand: string,\n positional: string[],\n text2Sql: Text2Sql,\n): { name: string; sql: string } {\n const [db, ...rest] = positional;\n const name = text2Sql.resolveAdapterName(db);\n\n const sql = rest.join(' ').trim();\n if (!sql) {\n throw new SqlCommandError(subcommand, 'no query provided');\n }\n return { name, sql };\n}\n\nfunction repairDbNameAndQuotedArg(rawArgs: string): string | null {\n const trimmed = rawArgs.trim();\n if (!trimmed) return null;\n const firstSpace = trimmed.search(/\\s/);\n if (firstSpace === -1) return null;\n const dbName = trimmed.slice(0, firstSpace);\n const rest = trimmed.slice(firstSpace + 1);\n const repaired = repairQuotedArg(rest);\n if (repaired == null) return null;\n return `${dbName} ${repaired}`;\n}\n", "import { type AgentModel } from '@deepagents/agent';\nimport type { ContextFragment } from '@deepagents/context';\n\nimport {\n AdapterIndexer,\n type Text2SqlIndexProgressHandler,\n} from './adapter-index.ts';\nimport { validateAdapterNames } from './adapter-name.ts';\nimport { type Adapter } from './adapters/adapter.ts';\nimport { toSql } from './agents/sql.agent.ts';\nimport { type IndexCache } from './index-cache.ts';\nimport { type IndexLock } from './index-lock.ts';\nimport { type ExtractedPair, type PairProducer } from './synthesis/types.ts';\n\nexport interface Text2SqlConfig {\n adapters: Record<string, Adapter>;\n model?: AgentModel;\n cache?: IndexCache;\n lock: IndexLock;\n}\n\nexport interface Text2SqlRunResult {\n rows: unknown[];\n columns: string[];\n}\n\nexport interface Text2SqlIndexOptions {\n names?: readonly string[];\n onProgress?: Text2SqlIndexProgressHandler;\n}\n\nconst text2SqlValidationMarker = Symbol('Text2SqlValidationError');\nconst text2SqlUnknownAdapterMarker = Symbol('Text2SqlUnknownAdapterError');\n\nexport class Text2SqlValidationError extends Error {\n [text2SqlValidationMarker]: true;\n\n constructor(message: string) {\n super(message);\n this.name = 'Text2SqlValidationError';\n this[text2SqlValidationMarker] = true;\n }\n\n static isInstance(error: unknown): error is Text2SqlValidationError {\n return (\n error instanceof Text2SqlValidationError &&\n error[text2SqlValidationMarker] === true\n );\n }\n}\n\nexport class Text2SqlUnknownAdapterError extends Error {\n [text2SqlUnknownAdapterMarker]: true;\n readonly adapter: string;\n readonly available: readonly string[];\n\n constructor(adapter: string, available: readonly string[]) {\n const list = available.join(', ') || '(none configured)';\n super(`Unknown adapter \"${adapter}\". Available: ${list}`);\n this.name = 'Text2SqlUnknownAdapterError';\n this.adapter = adapter;\n this.available = available;\n this[text2SqlUnknownAdapterMarker] = true;\n }\n\n static isInstance(error: unknown): error is Text2SqlUnknownAdapterError {\n return (\n error instanceof Text2SqlUnknownAdapterError &&\n error[text2SqlUnknownAdapterMarker] === true\n );\n }\n}\n\nconst text2SqlUnknownDatabaseMarker = Symbol('Text2SqlUnknownDatabaseError');\n\n/**\n * Thrown by {@link Text2Sql.resolveAdapterName} when a user-supplied `<db>`\n * token cannot be routed to an adapter (unknown name, or none given when more\n * than one is configured). Carries the requested token and the available names\n * so each port (CLI, sandbox command, JSON-RPC, MCP) can render it its own way.\n */\nexport class Text2SqlUnknownDatabaseError extends Error {\n [text2SqlUnknownDatabaseMarker]: true;\n readonly requested: string | undefined;\n readonly available: readonly string[];\n\n constructor(requested: string | undefined, available: readonly string[]) {\n const list = available.join(', ') || '(none configured)';\n super(\n requested\n ? `unknown database \"${requested}\". Available: ${list}`\n : `no database specified. Available: ${list}`,\n );\n this.name = 'Text2SqlUnknownDatabaseError';\n this.requested = requested;\n this.available = available;\n this[text2SqlUnknownDatabaseMarker] = true;\n }\n\n static isInstance(error: unknown): error is Text2SqlUnknownDatabaseError {\n return (\n error instanceof Text2SqlUnknownDatabaseError &&\n error[text2SqlUnknownDatabaseMarker] === true\n );\n }\n}\n\nexport class Text2Sql {\n #config: Text2SqlConfig;\n #indexer: AdapterIndexer;\n\n constructor(config: Text2SqlConfig) {\n const adapterNames = Object.keys(config.adapters);\n if (adapterNames.length === 0) {\n throw new Error('Text2Sql requires at least one adapter');\n }\n validateAdapterNames(adapterNames);\n this.#config = config;\n this.#indexer = new AdapterIndexer({\n adapters: config.adapters,\n cache: config.cache,\n lock: config.lock,\n });\n }\n\n #requireAdapter(name: string): Adapter {\n const adapter = this.#config.adapters[name];\n if (!adapter) {\n throw new Text2SqlUnknownAdapterError(name, this.adapterNames());\n }\n return adapter;\n }\n\n #requireModel(op: string): AgentModel {\n const model = this.#config.model;\n if (!model) {\n throw new Error(`Text2Sql.${op}() requires a model in Text2SqlConfig`);\n }\n return model;\n }\n\n adapterNames(): string[] {\n return Object.keys(this.#config.adapters);\n }\n\n hasAdapter(name: string): boolean {\n return name in this.#config.adapters;\n }\n\n /**\n * Resolve a user-supplied `<db>` token to a configured adapter name for the\n * surfaces that accept one (CLI, sandbox `sql` command, JSON-RPC daemon, MCP):\n * - exact match \u2192 that name\n * - no match (or omitted) but exactly one adapter configured \u2192 route to it\n * - otherwise \u2192 throw with the user-facing \"unknown database\" message\n *\n * Internal execution paths keep using the strict {@link Text2Sql.run}/\n * {@link Text2Sql.validate}, which reject an unknown name outright.\n */\n resolveAdapterName(db: string): string {\n if (!db || db.trim() === '') {\n const names = this.adapterNames();\n if (names.length === 1) return names[0];\n throw new Text2SqlUnknownDatabaseError(db, names);\n }\n if (this.hasAdapter(db)) {\n return db;\n }\n const names = this.adapterNames();\n if (names.length === 1) return names[0];\n throw new Text2SqlUnknownDatabaseError(db, names);\n }\n\n async validate(name: string, sql: string): Promise<string> {\n const adapter = this.#requireAdapter(name);\n const result = this.#validateWith(adapter, sql);\n return result;\n }\n\n async run(name: string, sql: string): Promise<Text2SqlRunResult> {\n const adapter = this.#requireAdapter(name);\n const formatted = await this.#validateWith(adapter, sql);\n const result = await adapter.execute(formatted);\n if (!Array.isArray(result)) {\n throw new Error('adapter.execute must return an array of rows');\n }\n const columns = result.length > 0 ? Object.keys(result[0] as object) : [];\n return { rows: result, columns };\n }\n\n async #validateWith(adapter: Adapter, sql: string): Promise<string> {\n const formatted = adapter.format(sql);\n const error = await adapter.validate(formatted);\n if (error) throw new Text2SqlValidationError(error);\n return formatted;\n }\n\n async index(options: Text2SqlIndexOptions = {}): Promise<ContextFragment[]> {\n return this.#indexer.index({\n adapterNames: options.names,\n onProgress: options.onProgress,\n });\n }\n\n async toSql(input: string, adapterName: string): Promise<string> {\n const adapter = this.#requireAdapter(adapterName);\n const model = this.#requireModel('toSql');\n const fragments = await this.#indexer.indexAdapter(adapterName);\n const result = await toSql({\n input,\n adapter,\n fragments,\n model,\n });\n return result.sql;\n }\n\n async toPairs<T extends PairProducer>(\n adapterName: string,\n factory: (adapter: Adapter) => T,\n ): Promise<ExtractedPair[]> {\n const adapter = this.#requireAdapter(adapterName);\n const producer = factory(adapter);\n return producer.toPairs();\n }\n}\n", "import { type UIMessage, isToolUIPart } from 'ai';\n\nimport { type WhenPredicate, reminder } from '@deepagents/context';\n\nimport {\n type SqlQueryInvocation,\n parseSqlQueryInvocation,\n} from './sql-invocation.ts';\nimport { repairSqlCommand } from './sql-repair.ts';\n\nexport const SQL_VALIDATE_REMINDER =\n 'Always run `sql validate <db> \"...\"` before `sql run <db> \"...\"` to catch syntax errors early.';\n\nfunction extractSqlInvocation(command: unknown): SqlQueryInvocation | null {\n if (typeof command !== 'string') return null;\n return parseSqlQueryInvocation(repairSqlCommand(command));\n}\n\nfunction inputCommand(input: unknown): unknown {\n return (input as { command?: unknown } | undefined)?.command;\n}\n\n/**\n * True when a `sql validate` of the same `(db, sql)` appears in the assistant's\n * recent tool history \u2014 i.e. the model already validated this exact query. SQL\n * text is compared verbatim; a reformatted query won't match, so the nudge\n * fires again rather than being wrongly suppressed (errs toward reminding).\n */\nfunction alreadyValidated(\n messages: UIMessage[] | undefined,\n run: SqlQueryInvocation,\n): boolean {\n for (const message of messages ?? []) {\n for (const part of message.parts) {\n if (!isToolUIPart(part)) continue;\n const invocation = extractSqlInvocation(\n inputCommand((part as { input?: unknown }).input),\n );\n if (\n invocation?.subcommand === 'validate' &&\n invocation.dbName === run.dbName &&\n invocation.sql === run.sql\n ) {\n return true;\n }\n }\n }\n return false;\n}\n\n/**\n * Fires after a successful `sql run` that was NOT preceded by a `sql validate`\n * of the same query. Reads the terminal call from `ctx.toolOutcome` (only\n * populated at `target: 'tool-output'` time) and scans\n * `ctx.lastAssistantMessages` for a matching prior validate.\n */\nexport function sqlRunMissingValidate(): WhenPredicate {\n return (ctx) => {\n const call = ctx.toolOutcome;\n if (!call || call.state !== 'output-available' || call.name !== 'bash') {\n return false;\n }\n const run = extractSqlInvocation(inputCommand(call.input));\n if (run?.subcommand !== 'run') return false;\n return !alreadyValidated(ctx.lastAssistantMessages, run);\n };\n}\n\n/**\n * A context fragment nudging the model to `sql validate` before `sql run`.\n * Register it on the engine alongside schema fragments:\n *\n * ```ts\n * context.set(...schemaFragments, sqlValidateReminder());\n * ```\n *\n * Delivered as a tool-output `<system-reminder>` on the `sql run` result, and\n * suppressed when the model already validated that exact query.\n */\nexport function sqlValidateReminder() {\n return reminder(SQL_VALIDATE_REMINDER, {\n target: 'tool-output',\n when: sqlRunMissingValidate(),\n });\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": ["column", "c", "table", "groq", "dedent", "z", "groq", "z", "dedent", "fragment", "hash", "createHash", "mkdir", "tmpdir", "path", "hash", "fragment", "createHash", "existsSync", "path", "path", "path", "require", "index", "result", "createRequire", "path", "require", "createRequire", "result", "path", "example", "fragment", "guardrail", "hint", "policy", "workflow", "parse", "createHash", "path", "asStaticWordText", "index", "parse", "asStaticWordText", "hash", "createHash", "posix", "BashException", "buildSubcommandRepair", "repairQuotedArg", "names", "BashException", "buildSubcommandRepair", "posix", "repairQuotedArg"]
|
|
7
7
|
}
|