@shardworks/nexus-core 0.1.19 → 0.1.21

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.
@@ -0,0 +1,321 @@
1
+ /**
2
+ * Manifest — assembles an anima's identity for a session.
3
+ *
4
+ * Reads the anima's composition from the Ledger (roles, curricula, temperament),
5
+ * resolves tools by role gating and precondition checks, reads all prompt
6
+ * ingredients from disk, and assembles the composed system prompt.
7
+ *
8
+ * The manifest is the anima's *identity*: who are you, what can you do.
9
+ * The *user prompt* (commission spec, brief, conversation topic) is NOT part
10
+ * of the manifest — it comes from the caller.
11
+ *
12
+ * Absorbed from the former `engine-manifest` package. MCP config generation
13
+ * is NOT here — that's a transport detail owned by session providers.
14
+ */
15
+ var __rewriteRelativeImportExtension = (this && this.__rewriteRelativeImportExtension) || function (path, preserveJsx) {
16
+ if (typeof path === "string" && /^\.\.?\//.test(path)) {
17
+ return path.replace(/\.(tsx)$|((?:\.d)?)((?:\.[^./]+?)?)\.([cm]?)ts$/i, function (m, tsx, d, ext, cm) {
18
+ return tsx ? preserveJsx ? ".jsx" : ".js" : d && (!ext || !cm) ? m : (d + ext + "." + cm.toLowerCase() + "js");
19
+ });
20
+ }
21
+ return path;
22
+ };
23
+ import fs from 'node:fs';
24
+ import path from 'node:path';
25
+ import Database from 'better-sqlite3';
26
+ import { ledgerPath } from "./nexus-home.js";
27
+ import { readGuildConfig } from "./guild-config.js";
28
+ import { readPreconditions, checkPreconditions } from "./preconditions.js";
29
+ import { resolveToolFromExport } from "./tool.js";
30
+ /** Extract the npm package name from a package specifier that may include a subpath. */
31
+ function basePackageName(pkg) {
32
+ // Scoped: @scope/name/subpath → @scope/name
33
+ if (pkg.startsWith('@')) {
34
+ const parts = pkg.split('/');
35
+ return parts.slice(0, 2).join('/');
36
+ }
37
+ // Unscoped: name/subpath → name
38
+ return pkg.split('/')[0];
39
+ }
40
+ // ── Core Functions ─────────────────────────────────────────────────────
41
+ /**
42
+ * Read an anima's full record from the Ledger, including roles and composition.
43
+ */
44
+ export function readAnima(home, animaName) {
45
+ const db = new Database(ledgerPath(home));
46
+ db.pragma('foreign_keys = ON');
47
+ try {
48
+ // Get anima
49
+ const anima = db.prepare(`SELECT id, name, status FROM animas WHERE name = ?`).get(animaName);
50
+ if (!anima) {
51
+ throw new Error(`Anima "${animaName}" not found in the Ledger.`);
52
+ }
53
+ // Get roles
54
+ const roleRows = db.prepare(`SELECT role FROM roster WHERE anima_id = ? ORDER BY role`).all(anima.id);
55
+ const roles = roleRows.map(r => r.role);
56
+ // Get composition — now includes name/version metadata
57
+ const composition = db.prepare(`SELECT curriculum_name, curriculum_version, curriculum_snapshot,
58
+ temperament_name, temperament_version, temperament_snapshot
59
+ FROM anima_compositions WHERE anima_id = ?`).get(anima.id);
60
+ return {
61
+ id: anima.id,
62
+ name: anima.name,
63
+ status: anima.status,
64
+ roles,
65
+ curriculumName: composition?.curriculum_name ?? '',
66
+ curriculumVersion: composition?.curriculum_version ?? '',
67
+ curriculumSnapshot: composition?.curriculum_snapshot ?? '',
68
+ temperamentName: composition?.temperament_name ?? '',
69
+ temperamentVersion: composition?.temperament_version ?? '',
70
+ temperamentSnapshot: composition?.temperament_snapshot ?? '',
71
+ };
72
+ }
73
+ finally {
74
+ db.close();
75
+ }
76
+ }
77
+ /**
78
+ * Resolve the set of tools an anima has access to, based on role
79
+ * definitions and precondition checks.
80
+ *
81
+ * 1. Start with baseTools (available to all animas)
82
+ * 2. For each anima role, look up the role in guild.json.roles
83
+ * - If defined: union in that role's tools
84
+ * - If undefined: warn and skip (no tools, no instructions from that role)
85
+ * 3. Deduplicate tool names
86
+ * 4. Resolve each tool from guild.json.tools catalog
87
+ * 5. Run precondition checks — split into available and unavailable
88
+ *
89
+ * Returns available tools, unavailable tools, and any warnings.
90
+ */
91
+ export async function resolveTools(home, config, animaRoles) {
92
+ const warnings = [];
93
+ // Collect tool names: start with base, union in role-specific
94
+ const toolNames = new Set(config.baseTools ?? []);
95
+ for (const role of animaRoles) {
96
+ const roleDef = config.roles[role];
97
+ if (!roleDef) {
98
+ warnings.push(`Role "${role}" is assigned to this anima but not defined in guild.json. ` +
99
+ `No tools or instructions from this role will be available.`);
100
+ continue;
101
+ }
102
+ for (const toolName of roleDef.tools) {
103
+ toolNames.add(toolName);
104
+ }
105
+ }
106
+ // Resolve each tool from the catalog
107
+ const available = [];
108
+ const unavailable = [];
109
+ for (const name of toolNames) {
110
+ const entry = config.tools[name];
111
+ if (!entry) {
112
+ warnings.push(`Tool "${name}" is referenced by a role or baseTools but not found in guild.json.tools. Skipping.`);
113
+ continue;
114
+ }
115
+ // Resolve on-disk path
116
+ const toolPath = path.join(home, 'tools', name);
117
+ const descriptorPath = path.join(toolPath, 'nexus-tool.json');
118
+ // Check preconditions before including in the available set
119
+ const preconditions = readPreconditions(descriptorPath);
120
+ if (preconditions.length > 0) {
121
+ const results = checkPreconditions(preconditions);
122
+ const failures = results.filter(r => !r.passed).map(r => r.message);
123
+ if (failures.length > 0) {
124
+ unavailable.push({ name, reasons: failures });
125
+ continue;
126
+ }
127
+ }
128
+ // Read instructions from multiple sources, in priority order:
129
+ // 1. Descriptor file on disk (nexus-tool.json → instructions field)
130
+ // 2. Tool definition (import module → instructions or instructionsFile)
131
+ let instructions = null;
132
+ // Source 1: descriptor file on disk
133
+ if (fs.existsSync(descriptorPath)) {
134
+ try {
135
+ const descriptor = JSON.parse(fs.readFileSync(descriptorPath, 'utf-8'));
136
+ if (descriptor.instructions) {
137
+ const instructionsPath = path.join(toolPath, descriptor.instructions);
138
+ if (fs.existsSync(instructionsPath)) {
139
+ instructions = fs.readFileSync(instructionsPath, 'utf-8');
140
+ }
141
+ }
142
+ }
143
+ catch {
144
+ // If descriptor is unreadable, skip instructions from descriptor
145
+ }
146
+ }
147
+ // Source 2: tool definition (for collection packages or tools with
148
+ // inline instructions / instructionsFile in the tool() definition)
149
+ if (!instructions && entry.package) {
150
+ try {
151
+ const mod = await import(__rewriteRelativeImportExtension(entry.package));
152
+ const toolDef = resolveToolFromExport(mod.default, name);
153
+ if (toolDef) {
154
+ if (toolDef.instructions) {
155
+ // Inline instructions text
156
+ instructions = toolDef.instructions;
157
+ }
158
+ else if (toolDef.instructionsFile) {
159
+ // File path relative to the package root in node_modules.
160
+ const instrPath = path.join(home, 'node_modules', basePackageName(entry.package), toolDef.instructionsFile);
161
+ if (fs.existsSync(instrPath)) {
162
+ instructions = fs.readFileSync(instrPath, 'utf-8');
163
+ }
164
+ }
165
+ }
166
+ }
167
+ catch {
168
+ // If import fails, skip — instructions are optional
169
+ }
170
+ }
171
+ available.push({
172
+ name,
173
+ path: toolPath,
174
+ instructions,
175
+ package: entry.package ?? null,
176
+ });
177
+ }
178
+ return { available, unavailable, warnings };
179
+ }
180
+ /**
181
+ * Read codex documents from the guildhall — guild-wide policy for all animas.
182
+ *
183
+ * Reads all .md files in the codex/ directory (non-recursive top level).
184
+ */
185
+ export function readCodex(home) {
186
+ const codexDir = path.join(home, 'codex');
187
+ if (!fs.existsSync(codexDir))
188
+ return '';
189
+ const sections = [];
190
+ // Read top-level .md files (included for all animas)
191
+ for (const entry of fs.readdirSync(codexDir, { withFileTypes: true })) {
192
+ if (entry.isFile() && entry.name.endsWith('.md')) {
193
+ const content = fs.readFileSync(path.join(codexDir, entry.name), 'utf-8').trim();
194
+ if (content)
195
+ sections.push(content);
196
+ }
197
+ }
198
+ return sections.join('\n\n---\n\n');
199
+ }
200
+ /**
201
+ * Read role-specific instructions for an anima's roles.
202
+ *
203
+ * For each role the anima holds, reads the instructions file pointed to by
204
+ * the role definition in guild.json. Skips undefined roles (warning already
205
+ * emitted by resolveTools). Skips roles without instructions.
206
+ */
207
+ export function readRoleInstructions(home, config, animaRoles) {
208
+ const sections = [];
209
+ for (const role of animaRoles) {
210
+ const roleDef = config.roles[role];
211
+ if (!roleDef || !roleDef.instructions)
212
+ continue;
213
+ const instructionsPath = path.join(home, roleDef.instructions);
214
+ if (!fs.existsSync(instructionsPath))
215
+ continue;
216
+ try {
217
+ const content = fs.readFileSync(instructionsPath, 'utf-8').trim();
218
+ if (content) {
219
+ sections.push(content);
220
+ }
221
+ }
222
+ catch {
223
+ // If unreadable, skip
224
+ }
225
+ }
226
+ return sections.join('\n\n---\n\n');
227
+ }
228
+ /**
229
+ * Assemble the composed system prompt for an anima session.
230
+ *
231
+ * Sections are included in order: codex → role instructions → curricula →
232
+ * temperament → tool instructions → unavailable tools notice.
233
+ * Empty sections are omitted.
234
+ */
235
+ export function assembleSystemPrompt(codex, roleInstructions, anima, tools, unavailable = []) {
236
+ const sections = [];
237
+ // Codex — guild-wide policies and procedures
238
+ if (codex.trim()) {
239
+ sections.push(`# Codex\n\n${codex}`);
240
+ }
241
+ // Role instructions — role-specific operational guidance
242
+ if (roleInstructions.trim()) {
243
+ sections.push(`# Role Instructions\n\n${roleInstructions}`);
244
+ }
245
+ // Curricula — the anima's training content
246
+ if (anima.curriculumSnapshot.trim()) {
247
+ sections.push(`# Training\n\n${anima.curriculumSnapshot}`);
248
+ }
249
+ // Temperament — the anima's personality
250
+ if (anima.temperamentSnapshot.trim()) {
251
+ sections.push(`# Temperament\n\n${anima.temperamentSnapshot}`);
252
+ }
253
+ // Tool instructions — guidance for each tool the anima has access to
254
+ const toolInstructions = tools
255
+ .filter(t => t.instructions)
256
+ .map(t => t.instructions);
257
+ if (toolInstructions.length > 0) {
258
+ sections.push(`# Tool Instructions\n\n${toolInstructions.join('\n\n---\n\n')}`);
259
+ }
260
+ // Unavailable tools notice — tell the anima what's broken and why
261
+ if (unavailable.length > 0) {
262
+ const notices = unavailable.map(u => {
263
+ const reasons = u.reasons.map(r => ` - ${r}`).join('\n');
264
+ return `**${u.name}** — unavailable:\n${reasons}`;
265
+ });
266
+ sections.push(`# Unavailable Tools\n\n` +
267
+ `The following tools are registered for your roles but are currently ` +
268
+ `unavailable due to unmet environment requirements. Do not attempt to use them. ` +
269
+ `If a patron or operator asks you to perform work that requires these tools, ` +
270
+ `explain what is needed to make them available.\n\n` +
271
+ notices.join('\n\n'));
272
+ }
273
+ return sections.join('\n\n---\n\n');
274
+ }
275
+ /**
276
+ * Manifest an anima for a session.
277
+ *
278
+ * This is the main entry point. Reads the anima's composition, resolves
279
+ * tools by role, assembles the system prompt, and returns the full
280
+ * manifest with composition provenance.
281
+ */
282
+ export async function manifest(home, animaName) {
283
+ const config = readGuildConfig(home);
284
+ const anima = readAnima(home, animaName);
285
+ if (anima.status !== 'active') {
286
+ throw new Error(`Anima "${animaName}" is not active (status: ${anima.status}). Cannot manifest.`);
287
+ }
288
+ // Resolve tools based on role definitions + precondition checks
289
+ const { available, unavailable, warnings } = await resolveTools(home, config, anima.roles);
290
+ // Read codex (guild-wide, no role filtering)
291
+ const codex = readCodex(home);
292
+ // Read role-specific instructions
293
+ const roleInstructions = readRoleInstructions(home, config, anima.roles);
294
+ // Assemble system prompt (includes role instructions and unavailability notices)
295
+ const systemPrompt = assembleSystemPrompt(codex, roleInstructions, anima, available, unavailable);
296
+ // Build composition provenance
297
+ const curriculum = anima.curriculumName
298
+ ? { name: anima.curriculumName, version: anima.curriculumVersion, content: anima.curriculumSnapshot }
299
+ : null;
300
+ const temperament = anima.temperamentName
301
+ ? { name: anima.temperamentName, version: anima.temperamentVersion, content: anima.temperamentSnapshot }
302
+ : null;
303
+ const toolInstructions = available
304
+ .filter(t => t.instructions)
305
+ .map(t => ({ toolName: t.name, instructions: t.instructions }));
306
+ return {
307
+ anima,
308
+ systemPrompt,
309
+ composition: {
310
+ codex,
311
+ roleInstructions,
312
+ curriculum,
313
+ temperament,
314
+ toolInstructions,
315
+ },
316
+ tools: available,
317
+ unavailable,
318
+ warnings,
319
+ };
320
+ }
321
+ //# sourceMappingURL=manifest.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"manifest.js","sourceRoot":"","sources":["../src/manifest.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,63 @@
1
+ /**
2
+ * Ledger migration — applies pending SQL migrations to the guild's Ledger.
3
+ *
4
+ * Runs at guild bootstrap, before dispatch, and on demand after framework
5
+ * upgrades. Absorbed from the former `engine-ledger-migrate` package.
6
+ *
7
+ * Migrations are numbered sequentially (001-initial-schema.sql, etc.) and
8
+ * applied in order. The module tracks which migrations have been applied in
9
+ * a `_migrations` table and only runs new ones.
10
+ *
11
+ * ## Migration file naming
12
+ *
13
+ * Files must match the pattern: NNN-description.sql
14
+ * where NNN is a zero-padded sequence number.
15
+ *
16
+ * Examples:
17
+ * 001-initial-schema.sql
18
+ * 002-add-priority-to-commissions.sql
19
+ * 003-add-sessions-table.sql
20
+ */
21
+ /** A migration file discovered on disk. */
22
+ export interface MigrationFile {
23
+ /** Sequence number (e.g. 1, 2, 3). */
24
+ sequence: number;
25
+ /** Full filename (e.g. '001-initial-schema.sql'). */
26
+ filename: string;
27
+ /** Absolute path to the file. */
28
+ path: string;
29
+ }
30
+ /** Provenance metadata for migrations installed via bundles. */
31
+ export interface MigrationProvenance {
32
+ /** Bundle that delivered this migration (e.g. "@shardworks/guild-starter-kit@0.1.5"). */
33
+ bundle: string;
34
+ /** Original filename in the bundle before renumbering (e.g. "001-initial-schema.sql"). */
35
+ originalName: string;
36
+ }
37
+ /** Result of applying migrations. */
38
+ export interface MigrateResult {
39
+ /** Migrations that were applied in this run. */
40
+ applied: string[];
41
+ /** Migrations that were already applied (skipped). */
42
+ skipped: string[];
43
+ /** Total number of migrations on disk. */
44
+ total: number;
45
+ }
46
+ /**
47
+ * Discover migration files in the migrations directory, sorted by sequence.
48
+ */
49
+ export declare function discoverMigrations(migrationsDir: string): MigrationFile[];
50
+ /**
51
+ * Apply pending migrations to the Ledger.
52
+ *
53
+ * Reads migration files from the guild's nexus/migrations/ directory, compares
54
+ * against the _migrations tracking table, and applies any that haven't been
55
+ * run yet. Each migration runs in its own transaction.
56
+ *
57
+ * @param home - Absolute path to the guild root.
58
+ * @param provenance - Optional map of guild filename → bundle provenance,
59
+ * supplied by the bundle installer for migrations it copied into the guild.
60
+ * @returns Summary of what was applied and skipped.
61
+ */
62
+ export declare function applyMigrations(home: string, provenance?: Record<string, MigrationProvenance>): MigrateResult;
63
+ //# sourceMappingURL=migrate.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"migrate.d.ts","sourceRoot":"","sources":["../src/migrate.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAOH,2CAA2C;AAC3C,MAAM,WAAW,aAAa;IAC5B,sCAAsC;IACtC,QAAQ,EAAE,MAAM,CAAC;IACjB,qDAAqD;IACrD,QAAQ,EAAE,MAAM,CAAC;IACjB,iCAAiC;IACjC,IAAI,EAAE,MAAM,CAAC;CACd;AAED,gEAAgE;AAChE,MAAM,WAAW,mBAAmB;IAClC,yFAAyF;IACzF,MAAM,EAAE,MAAM,CAAC;IACf,0FAA0F;IAC1F,YAAY,EAAE,MAAM,CAAC;CACtB;AAED,qCAAqC;AACrC,MAAM,WAAW,aAAa;IAC5B,gDAAgD;IAChD,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,sDAAsD;IACtD,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,0CAA0C;IAC1C,KAAK,EAAE,MAAM,CAAC;CACf;AAkCD;;GAEG;AACH,wBAAgB,kBAAkB,CAAC,aAAa,EAAE,MAAM,GAAG,aAAa,EAAE,CAoBzE;AAYD;;;;;;;;;;;GAWG;AACH,wBAAgB,eAAe,CAC7B,IAAI,EAAE,MAAM,EACZ,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,mBAAmB,CAAC,GAC/C,aAAa,CA8Df"}
@@ -0,0 +1,141 @@
1
+ /**
2
+ * Ledger migration — applies pending SQL migrations to the guild's Ledger.
3
+ *
4
+ * Runs at guild bootstrap, before dispatch, and on demand after framework
5
+ * upgrades. Absorbed from the former `engine-ledger-migrate` package.
6
+ *
7
+ * Migrations are numbered sequentially (001-initial-schema.sql, etc.) and
8
+ * applied in order. The module tracks which migrations have been applied in
9
+ * a `_migrations` table and only runs new ones.
10
+ *
11
+ * ## Migration file naming
12
+ *
13
+ * Files must match the pattern: NNN-description.sql
14
+ * where NNN is a zero-padded sequence number.
15
+ *
16
+ * Examples:
17
+ * 001-initial-schema.sql
18
+ * 002-add-priority-to-commissions.sql
19
+ * 003-add-sessions-table.sql
20
+ */
21
+ import fs from 'node:fs';
22
+ import path from 'node:path';
23
+ import Database from 'better-sqlite3';
24
+ import { ledgerPath } from "./nexus-home.js";
25
+ /** Pattern for migration filenames: NNN-description.sql */
26
+ const MIGRATION_PATTERN = /^(\d{3})-(.+)\.sql$/;
27
+ /**
28
+ * Ensure the _migrations tracking table exists.
29
+ *
30
+ * This table is NOT part of the regular schema migrations — it's the
31
+ * module's own bookkeeping, created on first use.
32
+ */
33
+ function ensureMigrationsTable(db) {
34
+ db.exec(`
35
+ CREATE TABLE IF NOT EXISTS _migrations (
36
+ sequence INTEGER PRIMARY KEY,
37
+ filename TEXT NOT NULL,
38
+ applied_at TEXT NOT NULL DEFAULT (datetime('now')),
39
+ bundle TEXT,
40
+ original_name TEXT
41
+ );
42
+ `);
43
+ // Add provenance columns if upgrading from an older schema.
44
+ // SQLite errors on duplicate ADD COLUMN, so check first.
45
+ const cols = db.pragma('table_info(_migrations)');
46
+ const colNames = new Set(cols.map(c => c.name));
47
+ if (!colNames.has('bundle')) {
48
+ db.exec(`ALTER TABLE _migrations ADD COLUMN bundle TEXT;`);
49
+ }
50
+ if (!colNames.has('original_name')) {
51
+ db.exec(`ALTER TABLE _migrations ADD COLUMN original_name TEXT;`);
52
+ }
53
+ }
54
+ /**
55
+ * Discover migration files in the migrations directory, sorted by sequence.
56
+ */
57
+ export function discoverMigrations(migrationsDir) {
58
+ if (!fs.existsSync(migrationsDir))
59
+ return [];
60
+ const files = fs.readdirSync(migrationsDir);
61
+ const migrations = [];
62
+ for (const file of files) {
63
+ const match = file.match(MIGRATION_PATTERN);
64
+ if (!match)
65
+ continue;
66
+ migrations.push({
67
+ sequence: parseInt(match[1], 10),
68
+ filename: file,
69
+ path: path.join(migrationsDir, file),
70
+ });
71
+ }
72
+ // Sort by sequence number
73
+ migrations.sort((a, b) => a.sequence - b.sequence);
74
+ return migrations;
75
+ }
76
+ /**
77
+ * Get the set of already-applied migration sequence numbers.
78
+ */
79
+ function getAppliedSequences(db) {
80
+ const rows = db.prepare(`SELECT sequence FROM _migrations ORDER BY sequence`).all();
81
+ return new Set(rows.map(r => r.sequence));
82
+ }
83
+ /**
84
+ * Apply pending migrations to the Ledger.
85
+ *
86
+ * Reads migration files from the guild's nexus/migrations/ directory, compares
87
+ * against the _migrations tracking table, and applies any that haven't been
88
+ * run yet. Each migration runs in its own transaction.
89
+ *
90
+ * @param home - Absolute path to the guild root.
91
+ * @param provenance - Optional map of guild filename → bundle provenance,
92
+ * supplied by the bundle installer for migrations it copied into the guild.
93
+ * @returns Summary of what was applied and skipped.
94
+ */
95
+ export function applyMigrations(home, provenance) {
96
+ const migrationsDir = path.join(home, 'nexus', 'migrations');
97
+ const dbPath = ledgerPath(home);
98
+ // Discover available migrations
99
+ const migrations = discoverMigrations(migrationsDir);
100
+ if (migrations.length === 0) {
101
+ return { applied: [], skipped: [], total: 0 };
102
+ }
103
+ const db = new Database(dbPath);
104
+ db.pragma('foreign_keys = ON');
105
+ try {
106
+ ensureMigrationsTable(db);
107
+ const applied = getAppliedSequences(db);
108
+ const result = {
109
+ applied: [],
110
+ skipped: [],
111
+ total: migrations.length,
112
+ };
113
+ for (const migration of migrations) {
114
+ if (applied.has(migration.sequence)) {
115
+ result.skipped.push(migration.filename);
116
+ continue;
117
+ }
118
+ // Read and apply the migration.
119
+ // PRAGMAs can't run inside transactions, so extract them and run separately.
120
+ const sql = fs.readFileSync(migration.path, 'utf-8');
121
+ const pragmaPattern = /^\s*PRAGMA\s+[^;]+;\s*$/gmi;
122
+ const pragmas = sql.match(pragmaPattern) || [];
123
+ const body = sql.replace(pragmaPattern, '').trim();
124
+ for (const pragma of pragmas) {
125
+ db.exec(pragma);
126
+ }
127
+ const prov = provenance?.[migration.filename];
128
+ db.transaction(() => {
129
+ if (body)
130
+ db.exec(body);
131
+ db.prepare(`INSERT INTO _migrations (sequence, filename, bundle, original_name) VALUES (?, ?, ?, ?)`).run(migration.sequence, migration.filename, prov?.bundle ?? null, prov?.originalName ?? null);
132
+ })();
133
+ result.applied.push(migration.filename);
134
+ }
135
+ return result;
136
+ }
137
+ finally {
138
+ db.close();
139
+ }
140
+ }
141
+ //# sourceMappingURL=migrate.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"migrate.js","sourceRoot":"","sources":["../src/migrate.ts"],"names":[],"mappings":"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"}