vgxness 1.0.3 → 1.0.5
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.
|
@@ -4,6 +4,15 @@ import { fileURLToPath } from 'node:url';
|
|
|
4
4
|
import Database from 'better-sqlite3';
|
|
5
5
|
const migrationsDirectory = join(dirname(fileURLToPath(import.meta.url)), 'migrations');
|
|
6
6
|
export const sqliteBusyTimeoutMs = 5000;
|
|
7
|
+
const nativeBindingDiagnosticGuidance = 'Detected a likely better-sqlite3 native binding problem. Ensure npm install scripts are enabled, then rebuild or reinstall dependencies for the active Node.js version (for example: npm rebuild better-sqlite3 --ignore-scripts=false).';
|
|
8
|
+
const nativeBindingFailurePatterns = [
|
|
9
|
+
/better_sqlite3\.node/i,
|
|
10
|
+
/better-sqlite3/i,
|
|
11
|
+
/NODE_MODULE_VERSION/i,
|
|
12
|
+
/ERR_DLOPEN_FAILED/i,
|
|
13
|
+
/Could not locate the bindings file/i,
|
|
14
|
+
/compiled against a different Node\.js version/i,
|
|
15
|
+
];
|
|
7
16
|
export class MemoryDatabase {
|
|
8
17
|
connection;
|
|
9
18
|
constructor(connection) {
|
|
@@ -29,7 +38,7 @@ export class MemoryDatabase {
|
|
|
29
38
|
ok: false,
|
|
30
39
|
error: {
|
|
31
40
|
code: 'store_unavailable',
|
|
32
|
-
message:
|
|
41
|
+
message: buildMemoryStoreUnavailableMessage(options.path, cause),
|
|
33
42
|
cause,
|
|
34
43
|
},
|
|
35
44
|
};
|
|
@@ -89,9 +98,42 @@ export class MemoryDatabase {
|
|
|
89
98
|
export function openMemoryDatabase(options) {
|
|
90
99
|
return MemoryDatabase.open(options);
|
|
91
100
|
}
|
|
101
|
+
export function buildMemoryStoreUnavailableMessage(path, cause) {
|
|
102
|
+
const message = `Unable to open local memory store at ${path}`;
|
|
103
|
+
if (!isLikelyBetterSqlite3NativeBindingFailure(cause))
|
|
104
|
+
return message;
|
|
105
|
+
return `${message}. ${nativeBindingDiagnosticGuidance}`;
|
|
106
|
+
}
|
|
107
|
+
export function isLikelyBetterSqlite3NativeBindingFailure(cause) {
|
|
108
|
+
const values = collectDiagnosticValues(cause);
|
|
109
|
+
return values.some((value) => nativeBindingFailurePatterns.some((pattern) => pattern.test(value)));
|
|
110
|
+
}
|
|
92
111
|
function migrationFailure(message, cause) {
|
|
93
112
|
const error = { code: 'migration_failed', message };
|
|
94
113
|
if (cause !== undefined)
|
|
95
114
|
error.cause = cause;
|
|
96
115
|
return { ok: false, error };
|
|
97
116
|
}
|
|
117
|
+
function collectDiagnosticValues(value, seen = new Set()) {
|
|
118
|
+
if (value === undefined || value === null)
|
|
119
|
+
return [];
|
|
120
|
+
if (typeof value === 'string')
|
|
121
|
+
return [value];
|
|
122
|
+
if (typeof value === 'number' || typeof value === 'boolean' || typeof value === 'bigint' || typeof value === 'symbol')
|
|
123
|
+
return [String(value)];
|
|
124
|
+
if (typeof value !== 'object')
|
|
125
|
+
return [];
|
|
126
|
+
if (seen.has(value))
|
|
127
|
+
return [];
|
|
128
|
+
seen.add(value);
|
|
129
|
+
const diagnosticValues = [];
|
|
130
|
+
const record = value;
|
|
131
|
+
for (const key of ['code', 'message', 'stack', 'name']) {
|
|
132
|
+
const property = record[key];
|
|
133
|
+
if (property !== undefined)
|
|
134
|
+
diagnosticValues.push(...collectDiagnosticValues(property, seen));
|
|
135
|
+
}
|
|
136
|
+
if (record.cause !== undefined)
|
|
137
|
+
diagnosticValues.push(...collectDiagnosticValues(record.cause, seen));
|
|
138
|
+
return diagnosticValues;
|
|
139
|
+
}
|
|
@@ -74,7 +74,7 @@ function storeStatus(result) {
|
|
|
74
74
|
status: 'blocked',
|
|
75
75
|
path: '',
|
|
76
76
|
blocker: result.error.message,
|
|
77
|
-
recovery: 'Run `
|
|
77
|
+
recovery: 'Run `vgx doctor` and verify the configured local memory path is writable.',
|
|
78
78
|
};
|
|
79
79
|
}
|
|
80
80
|
function mcpStatus(result, storeReadiness) {
|
|
@@ -178,17 +178,17 @@ function verificationSummary(environment, project, providers, agents, mcp) {
|
|
|
178
178
|
}
|
|
179
179
|
function nextAction(store, mcp, defaults, providers, project) {
|
|
180
180
|
if (store.status !== 'ready') {
|
|
181
|
-
return { command: '
|
|
181
|
+
return { command: 'vgx doctor', reason: `Local store is blocked: ${store.blocker ?? 'local store is unavailable'}` };
|
|
182
182
|
}
|
|
183
183
|
if (defaults.status !== 'ready') {
|
|
184
184
|
if (defaults.blocker?.startsWith('No project selected') === true) {
|
|
185
185
|
return {
|
|
186
|
-
command: '
|
|
186
|
+
command: 'vgx dashboard interactive --project <project>',
|
|
187
187
|
reason: defaults.nextAction ?? 'Select a project to verify project-scoped setup checks.',
|
|
188
188
|
};
|
|
189
189
|
}
|
|
190
190
|
return {
|
|
191
|
-
command: '
|
|
191
|
+
command: 'vgx agents seed --scope project',
|
|
192
192
|
reason: `Default context is blocked: ${defaults.blocker ?? 'default context is unavailable'}`,
|
|
193
193
|
};
|
|
194
194
|
}
|
|
@@ -201,8 +201,8 @@ function nextAction(store, mcp, defaults, providers, project) {
|
|
|
201
201
|
reason: `Provider MCP status is not ready; review the Providers section for provider-specific preview/install guidance (${providerSummary}).`,
|
|
202
202
|
};
|
|
203
203
|
}
|
|
204
|
-
return { command: '
|
|
204
|
+
return { command: 'vgx runs list', reason: 'Project setup is ready; continue with normal vgxness usage.' };
|
|
205
205
|
}
|
|
206
206
|
function setupStatusCommand(project) {
|
|
207
|
-
return project === undefined ? '
|
|
207
|
+
return project === undefined ? 'vgx setup status' : `vgx setup status --project ${project}`;
|
|
208
208
|
}
|