aiex-cli 0.0.1-beta.27 → 0.0.1-beta.29
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 +13 -3
- package/dist/cli.mjs +819 -351
- package/dist/core/schema-sqlite/migrate-helper.mjs +16 -29
- package/dist/{doctor-IvHYLDX6.mjs → doctor-collector-j2dG7dG1.mjs} +270 -231
- package/dist/index.d.mts +14 -15
- package/dist/index.mjs +1 -1
- package/dist/web/assets/AISettings-Dn58ZHhM.js +339 -0
- package/dist/web/assets/DataBrowser-B6WECCZM.js +6 -0
- package/dist/web/assets/{ExtractionViewer-WMUdXeyU.js → ExtractionViewer-CTS1RXzc.js} +1 -1
- package/dist/web/assets/JsonSchemaEditor-Dpgu6HPz.js +570 -0
- package/dist/web/assets/api-client-CbQEkaKT.js +1 -0
- package/dist/web/assets/dialog-CUkPLPNP.js +109 -0
- package/dist/web/assets/{index-CuOQk7nB.js → index-g2pWXPQZ.js} +38 -38
- package/dist/web/assets/object-utils-DPPzLQjH.js +1 -0
- package/dist/web/assets/select-DyjIzt-v.js +439 -0
- package/dist/web/index.html +5 -5
- package/package.json +7 -1
- package/src/core/schema-sqlite/migrate-helper.ts +15 -40
- package/dist/web/assets/AISettings-DFi-nXIi.js +0 -334
- package/dist/web/assets/DataBrowser-BWSX8O2h.js +0 -5
- package/dist/web/assets/JsonSchemaEditor-B57coz1O.js +0 -929
- package/dist/web/assets/api-client-By2rWtpv.js +0 -1
- package/dist/web/assets/dialog-dMXSeJQQ.js +0 -108
- package/dist/web/assets/overlayeventbus-CRKW6UCj.js +0 -80
- package/dist/web/assets/table-schema-C90NJyfq.js +0 -2
- /package/dist/web/assets/{runtime-dom.esm-bundler-DmdkgxQM.js → runtime-dom.esm-bundler-ei_N7Xjw.js} +0 -0
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
import { createRequire } from "node:module";
|
|
2
|
+
import fs from "node:fs/promises";
|
|
2
3
|
import path from "node:path";
|
|
3
4
|
import process from "node:process";
|
|
4
5
|
import { fileURLToPath } from "node:url";
|
|
5
|
-
import fs from "node:fs/promises";
|
|
6
6
|
import Database from "better-sqlite3";
|
|
7
7
|
import * as esbuild from "esbuild";
|
|
8
|
+
import lockfile from "proper-lockfile";
|
|
8
9
|
|
|
9
10
|
//#region src/core/schema-sqlite/migration-name.ts
|
|
10
11
|
function sanitizeMigrationName(name) {
|
|
@@ -119,35 +120,22 @@ function applyMigrationWithTransaction(dbPath, sqlStatements) {
|
|
|
119
120
|
}
|
|
120
121
|
}
|
|
121
122
|
const LOCK_FILE = ".migrate.lock";
|
|
122
|
-
async function
|
|
123
|
-
const lockPath = path.join(aiexDir, LOCK_FILE);
|
|
123
|
+
async function acquireMigrationLock(aiexDir) {
|
|
124
124
|
await fs.mkdir(aiexDir, { recursive: true });
|
|
125
125
|
try {
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
return acquireLock(aiexDir);
|
|
138
|
-
}
|
|
139
|
-
throw new Error(`Migration is already running (PID ${lockPid}, started ${Math.round(lockAge / 1e3)}s ago). Wait for it to complete or remove ${lockPath} if stale.`);
|
|
140
|
-
} catch {
|
|
141
|
-
await fs.unlink(lockPath).catch(() => {});
|
|
142
|
-
return acquireLock(aiexDir);
|
|
143
|
-
}
|
|
144
|
-
throw e;
|
|
126
|
+
return await lockfile.lock(aiexDir, {
|
|
127
|
+
lockfilePath: path.join(aiexDir, LOCK_FILE),
|
|
128
|
+
realpath: false,
|
|
129
|
+
stale: 3e5,
|
|
130
|
+
update: 1e4,
|
|
131
|
+
retries: 0
|
|
132
|
+
});
|
|
133
|
+
} catch (error) {
|
|
134
|
+
const lockPath = path.join(aiexDir, LOCK_FILE);
|
|
135
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
136
|
+
throw new Error(`Migration is already running or the lock could not be acquired. Wait for it to complete or remove ${lockPath} if stale. ${message}`);
|
|
145
137
|
}
|
|
146
138
|
}
|
|
147
|
-
async function releaseLock(aiexDir) {
|
|
148
|
-
const lockPath = path.join(aiexDir, LOCK_FILE);
|
|
149
|
-
await fs.unlink(lockPath).catch(() => {});
|
|
150
|
-
}
|
|
151
139
|
async function main() {
|
|
152
140
|
const args = process.argv.slice(2);
|
|
153
141
|
const schemaPath = args[0];
|
|
@@ -159,8 +147,7 @@ async function main() {
|
|
|
159
147
|
process.exit(1);
|
|
160
148
|
}
|
|
161
149
|
try {
|
|
162
|
-
const
|
|
163
|
-
await acquireLock(aiexDir);
|
|
150
|
+
const releaseLock = await acquireMigrationLock(path.dirname(path.dirname(migrationsPath)));
|
|
164
151
|
try {
|
|
165
152
|
const exports = await loadSchemaExports(schemaPath);
|
|
166
153
|
let dbMissing = false;
|
|
@@ -188,7 +175,7 @@ async function main() {
|
|
|
188
175
|
tag
|
|
189
176
|
}));
|
|
190
177
|
} finally {
|
|
191
|
-
await releaseLock(
|
|
178
|
+
await releaseLock();
|
|
192
179
|
}
|
|
193
180
|
} catch (error) {
|
|
194
181
|
const message = error instanceof Error ? error.message : String(error);
|
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import path from "node:path";
|
|
2
|
-
import process from "node:process";
|
|
3
|
-
import { z } from "zod";
|
|
4
1
|
import fs from "node:fs/promises";
|
|
5
2
|
import os from "node:os";
|
|
3
|
+
import path from "node:path";
|
|
4
|
+
import process from "node:process";
|
|
6
5
|
import Conf from "conf";
|
|
6
|
+
import { z } from "zod";
|
|
7
7
|
|
|
8
8
|
//#region src/core/doctor.ts
|
|
9
9
|
function buildDoctorDiagnostics(input) {
|
|
@@ -61,6 +61,271 @@ function doctorDiagnosticsTableRows(d) {
|
|
|
61
61
|
return rows;
|
|
62
62
|
}
|
|
63
63
|
|
|
64
|
+
//#endregion
|
|
65
|
+
//#region package.json
|
|
66
|
+
var name = "aiex-cli";
|
|
67
|
+
var version = "0.0.1-beta.29";
|
|
68
|
+
var description = "JSON Schema → SQLite with AI-powered data extraction";
|
|
69
|
+
var package_default = {
|
|
70
|
+
name,
|
|
71
|
+
type: "module",
|
|
72
|
+
version,
|
|
73
|
+
description,
|
|
74
|
+
author: "OSpoon <zxin088@gmail.com>",
|
|
75
|
+
license: "MIT",
|
|
76
|
+
homepage: "https://github.com/OSpoon/aiex-cli#readme",
|
|
77
|
+
repository: {
|
|
78
|
+
"type": "git",
|
|
79
|
+
"url": "git+https://github.com/OSpoon/aiex-cli.git"
|
|
80
|
+
},
|
|
81
|
+
bugs: "https://github.com/OSpoon/aiex-cli/issues",
|
|
82
|
+
keywords: [
|
|
83
|
+
"json-schema",
|
|
84
|
+
"sqlite",
|
|
85
|
+
"drizzle",
|
|
86
|
+
"orm",
|
|
87
|
+
"ai-extraction",
|
|
88
|
+
"cli",
|
|
89
|
+
"database-migration",
|
|
90
|
+
"schema-editor",
|
|
91
|
+
"code-generation",
|
|
92
|
+
"structured-output"
|
|
93
|
+
],
|
|
94
|
+
sideEffects: false,
|
|
95
|
+
exports: {
|
|
96
|
+
".": "./dist/index.mjs",
|
|
97
|
+
"./cli": "./dist/cli.mjs",
|
|
98
|
+
"./core/schema-sqlite/migrate-helper": "./dist/core/schema-sqlite/migrate-helper.mjs",
|
|
99
|
+
"./package.json": "./package.json"
|
|
100
|
+
},
|
|
101
|
+
main: "./dist/index.mjs",
|
|
102
|
+
module: "./dist/index.mjs",
|
|
103
|
+
types: "./dist/index.d.mts",
|
|
104
|
+
bin: { "aiex": "./bin/cli.mjs" },
|
|
105
|
+
files: [
|
|
106
|
+
"bin",
|
|
107
|
+
"dist",
|
|
108
|
+
"src/core/schema-sqlite/migrate-helper.ts",
|
|
109
|
+
"src/core/schema-sqlite/migration-name.ts"
|
|
110
|
+
],
|
|
111
|
+
scripts: {
|
|
112
|
+
"build": "tsdown && pnpm --filter aiex-web build",
|
|
113
|
+
"dev": "tsdown --watch",
|
|
114
|
+
"start": "tsx src/index.ts",
|
|
115
|
+
"test": "vitest",
|
|
116
|
+
"coverage": "vitest --coverage",
|
|
117
|
+
"typecheck": "tsc",
|
|
118
|
+
"lint": "eslint .",
|
|
119
|
+
"prepack": "cp ../../README.md .",
|
|
120
|
+
"postpack": "rm -f README.md",
|
|
121
|
+
"prepublishOnly": "pnpm run build"
|
|
122
|
+
},
|
|
123
|
+
dependencies: {
|
|
124
|
+
"@ai-sdk/openai-compatible": "catalog:",
|
|
125
|
+
"@clack/prompts": "catalog:",
|
|
126
|
+
"@hono/node-server": "catalog:",
|
|
127
|
+
"@langfuse/otel": "catalog:",
|
|
128
|
+
"@opentelemetry/sdk-trace-node": "catalog:",
|
|
129
|
+
"ai": "catalog:",
|
|
130
|
+
"better-sqlite3": "catalog:",
|
|
131
|
+
"citty": "catalog:",
|
|
132
|
+
"cli-table3": "catalog:",
|
|
133
|
+
"conf": "catalog:",
|
|
134
|
+
"consola": "catalog:",
|
|
135
|
+
"date-fns": "catalog:",
|
|
136
|
+
"drizzle-kit": "catalog:cli",
|
|
137
|
+
"drizzle-orm": "catalog:",
|
|
138
|
+
"es-toolkit": "catalog:",
|
|
139
|
+
"esbuild": "catalog:",
|
|
140
|
+
"execa": "catalog:",
|
|
141
|
+
"hono": "catalog:",
|
|
142
|
+
"p-retry": "catalog:",
|
|
143
|
+
"picocolors": "catalog:",
|
|
144
|
+
"picomatch": "catalog:",
|
|
145
|
+
"proper-lockfile": "catalog:",
|
|
146
|
+
"tsx": "catalog:cli",
|
|
147
|
+
"unpdf": "catalog:",
|
|
148
|
+
"update-notifier": "catalog:",
|
|
149
|
+
"zod": "catalog:"
|
|
150
|
+
},
|
|
151
|
+
devDependencies: {
|
|
152
|
+
"@antfu/eslint-config": "catalog:cli",
|
|
153
|
+
"@antfu/ni": "catalog:cli",
|
|
154
|
+
"@types/better-sqlite3": "catalog:types",
|
|
155
|
+
"@types/node": "catalog:types",
|
|
156
|
+
"@types/picomatch": "catalog:",
|
|
157
|
+
"@types/proper-lockfile": "catalog:",
|
|
158
|
+
"@types/update-notifier": "catalog:",
|
|
159
|
+
"@vitest/coverage-v8": "catalog:testing",
|
|
160
|
+
"eslint": "catalog:cli",
|
|
161
|
+
"publint": "catalog:cli",
|
|
162
|
+
"tsdown": "catalog:cli",
|
|
163
|
+
"tsnapi": "catalog:testing",
|
|
164
|
+
"typescript": "catalog:cli",
|
|
165
|
+
"vitest": "catalog:testing"
|
|
166
|
+
}
|
|
167
|
+
};
|
|
168
|
+
|
|
169
|
+
//#endregion
|
|
170
|
+
//#region src/config.ts
|
|
171
|
+
function createConfig() {
|
|
172
|
+
return new Conf({
|
|
173
|
+
cwd: process.env.CLI_CONFIG_DIR,
|
|
174
|
+
projectName: process.env.CLI_CONFIG_PROJECT_NAME || name
|
|
175
|
+
});
|
|
176
|
+
}
|
|
177
|
+
function seedConfig(config = createConfig()) {
|
|
178
|
+
if (!config.has("name")) config.set("name", name);
|
|
179
|
+
if (!config.has("version")) config.set("version", version);
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
//#endregion
|
|
183
|
+
//#region src/core/ai-extraction/schemas.ts
|
|
184
|
+
const ModelCapabilitiesSchema = z.object({
|
|
185
|
+
vision: z.boolean(),
|
|
186
|
+
structuredOutput: z.boolean(),
|
|
187
|
+
maxTokens: z.number().int().positive().optional(),
|
|
188
|
+
maxOutputTokens: z.number().int().positive().optional()
|
|
189
|
+
});
|
|
190
|
+
const AIModelConfigSchema = z.object({
|
|
191
|
+
name: z.string().min(1),
|
|
192
|
+
capabilities: ModelCapabilitiesSchema
|
|
193
|
+
});
|
|
194
|
+
const AIProviderConfigSchema = z.object({
|
|
195
|
+
baseURL: z.string().min(1),
|
|
196
|
+
apiKey: z.string(),
|
|
197
|
+
models: z.array(AIModelConfigSchema).min(1),
|
|
198
|
+
timeout: z.number().int().positive().default(300).optional()
|
|
199
|
+
});
|
|
200
|
+
const PromptConfigSchema = z.object({
|
|
201
|
+
systemTemplate: z.string().min(1),
|
|
202
|
+
userTemplate: z.string().min(1)
|
|
203
|
+
});
|
|
204
|
+
const ExtractionConfigSchema = z.object({ outputDir: z.string().min(1) });
|
|
205
|
+
const ExternalPdfConverterConfigSchema = z.object({
|
|
206
|
+
command: z.string().min(1),
|
|
207
|
+
args: z.array(z.string()),
|
|
208
|
+
outputFile: z.string().min(1).optional(),
|
|
209
|
+
timeout: z.number().int().positive().default(600).optional(),
|
|
210
|
+
fallbackToUnpdf: z.boolean().optional()
|
|
211
|
+
});
|
|
212
|
+
const PdfConfigSchema = z.object({
|
|
213
|
+
converter: z.enum([
|
|
214
|
+
"unpdf",
|
|
215
|
+
"mineru",
|
|
216
|
+
"external"
|
|
217
|
+
]),
|
|
218
|
+
mineru: ExternalPdfConverterConfigSchema.optional(),
|
|
219
|
+
external: ExternalPdfConverterConfigSchema.optional()
|
|
220
|
+
});
|
|
221
|
+
const LangfuseConfigSchema = z.object({
|
|
222
|
+
publicKey: z.string(),
|
|
223
|
+
secretKey: z.string(),
|
|
224
|
+
host: z.string().optional()
|
|
225
|
+
});
|
|
226
|
+
const AIConfigSchema = z.object({
|
|
227
|
+
provider: AIProviderConfigSchema,
|
|
228
|
+
prompt: PromptConfigSchema,
|
|
229
|
+
extraction: ExtractionConfigSchema,
|
|
230
|
+
pdf: PdfConfigSchema.optional(),
|
|
231
|
+
langfuse: LangfuseConfigSchema.optional()
|
|
232
|
+
});
|
|
233
|
+
|
|
234
|
+
//#endregion
|
|
235
|
+
//#region src/core/ai-extraction/types.ts
|
|
236
|
+
const PLACEHOLDER_SCHEMA = "{schema}";
|
|
237
|
+
const PLACEHOLDER_TEXT = "{text}";
|
|
238
|
+
const DEFAULT_MODELS = [{
|
|
239
|
+
name: "qwen-plus",
|
|
240
|
+
capabilities: {
|
|
241
|
+
vision: false,
|
|
242
|
+
structuredOutput: true
|
|
243
|
+
}
|
|
244
|
+
}, {
|
|
245
|
+
name: "qwen-vl-plus",
|
|
246
|
+
capabilities: {
|
|
247
|
+
vision: true,
|
|
248
|
+
structuredOutput: true
|
|
249
|
+
}
|
|
250
|
+
}];
|
|
251
|
+
const DEFAULT_PROVIDER_CONFIG = {
|
|
252
|
+
baseURL: "https://dashscope.aliyuncs.com/compatible-mode/v1",
|
|
253
|
+
apiKey: "",
|
|
254
|
+
models: [...DEFAULT_MODELS],
|
|
255
|
+
timeout: 300
|
|
256
|
+
};
|
|
257
|
+
const DEFAULT_PROMPT_CONFIG = {
|
|
258
|
+
systemTemplate: `You are a professional data extraction assistant. Your task is to extract structured data from text and return a JSON object based on the data structure definition provided below.
|
|
259
|
+
|
|
260
|
+
{schema}
|
|
261
|
+
|
|
262
|
+
Extraction requirements:
|
|
263
|
+
1. Extract strictly according to the field names and types defined in the structure
|
|
264
|
+
2. If the text lacks information for a field, set that field to null
|
|
265
|
+
3. Do not add fields that do not exist in the structure definition
|
|
266
|
+
4. Maintain data accuracy and completeness`,
|
|
267
|
+
userTemplate: `Please extract data from the following text:
|
|
268
|
+
{text}`
|
|
269
|
+
};
|
|
270
|
+
const DEFAULT_EXTRACTION_CONFIG = { outputDir: ".aiex/extracted" };
|
|
271
|
+
const DEFAULT_MINERU_CONFIG = {
|
|
272
|
+
command: "mineru",
|
|
273
|
+
args: [
|
|
274
|
+
"-p",
|
|
275
|
+
"{input}",
|
|
276
|
+
"-o",
|
|
277
|
+
"{outputDir}"
|
|
278
|
+
],
|
|
279
|
+
timeout: 600,
|
|
280
|
+
fallbackToUnpdf: true
|
|
281
|
+
};
|
|
282
|
+
const DEFAULT_PDF_CONFIG = {
|
|
283
|
+
converter: "unpdf",
|
|
284
|
+
mineru: DEFAULT_MINERU_CONFIG
|
|
285
|
+
};
|
|
286
|
+
const DEFAULT_AI_CONFIG = {
|
|
287
|
+
provider: DEFAULT_PROVIDER_CONFIG,
|
|
288
|
+
prompt: DEFAULT_PROMPT_CONFIG,
|
|
289
|
+
extraction: DEFAULT_EXTRACTION_CONFIG,
|
|
290
|
+
pdf: DEFAULT_PDF_CONFIG
|
|
291
|
+
};
|
|
292
|
+
|
|
293
|
+
//#endregion
|
|
294
|
+
//#region src/core/ai-extraction/config.ts
|
|
295
|
+
const CONFIG_FILE_NAME = "ai-config.json";
|
|
296
|
+
const GITIGNORE_FILE = ".gitignore";
|
|
297
|
+
async function readAIConfig(aiexDir) {
|
|
298
|
+
const configPath = path.join(aiexDir, CONFIG_FILE_NAME);
|
|
299
|
+
try {
|
|
300
|
+
const content = await fs.readFile(configPath, "utf-8");
|
|
301
|
+
const parsed = JSON.parse(content);
|
|
302
|
+
return AIConfigSchema.parse(parsed);
|
|
303
|
+
} catch {
|
|
304
|
+
return null;
|
|
305
|
+
}
|
|
306
|
+
}
|
|
307
|
+
async function writeAIConfig(aiexDir, config) {
|
|
308
|
+
const configPath = path.join(aiexDir, CONFIG_FILE_NAME);
|
|
309
|
+
await fs.mkdir(aiexDir, { recursive: true });
|
|
310
|
+
await fs.writeFile(configPath, `${JSON.stringify(config, null, 2)}\n`);
|
|
311
|
+
await addToGitignore(aiexDir, CONFIG_FILE_NAME);
|
|
312
|
+
}
|
|
313
|
+
function getDefaultAIConfig() {
|
|
314
|
+
return structuredClone(DEFAULT_AI_CONFIG);
|
|
315
|
+
}
|
|
316
|
+
async function addToGitignore(aiexDir, fileName) {
|
|
317
|
+
const projectRoot = path.dirname(aiexDir);
|
|
318
|
+
const gitignorePath = path.join(projectRoot, GITIGNORE_FILE);
|
|
319
|
+
try {
|
|
320
|
+
const content = await fs.readFile(gitignorePath, "utf-8");
|
|
321
|
+
if (content.split("\n").some((line) => line.trim() === fileName || line.includes(".aiex/"))) return;
|
|
322
|
+
const newContent = content.endsWith("\n") ? `${content}${fileName}\n` : `${content}\n${fileName}\n`;
|
|
323
|
+
await fs.writeFile(gitignorePath, newContent);
|
|
324
|
+
} catch {
|
|
325
|
+
await fs.writeFile(gitignorePath, `${fileName}\n`);
|
|
326
|
+
}
|
|
327
|
+
}
|
|
328
|
+
|
|
64
329
|
//#endregion
|
|
65
330
|
//#region src/core/schema-sqlite/generator.ts
|
|
66
331
|
function generateColumnDefinition(column) {
|
|
@@ -410,233 +675,7 @@ function generateDrizzleConfig() {
|
|
|
410
675
|
}
|
|
411
676
|
|
|
412
677
|
//#endregion
|
|
413
|
-
//#region
|
|
414
|
-
var name = "aiex-cli";
|
|
415
|
-
var version = "0.0.1-beta.27";
|
|
416
|
-
var description = "JSON Schema → SQLite with AI-powered data extraction";
|
|
417
|
-
var package_default = {
|
|
418
|
-
name,
|
|
419
|
-
type: "module",
|
|
420
|
-
version,
|
|
421
|
-
description,
|
|
422
|
-
author: "OSpoon <zxin088@gmail.com>",
|
|
423
|
-
license: "MIT",
|
|
424
|
-
homepage: "https://github.com/OSpoon/aiex-cli#readme",
|
|
425
|
-
repository: {
|
|
426
|
-
"type": "git",
|
|
427
|
-
"url": "git+https://github.com/OSpoon/aiex-cli.git"
|
|
428
|
-
},
|
|
429
|
-
bugs: "https://github.com/OSpoon/aiex-cli/issues",
|
|
430
|
-
keywords: [
|
|
431
|
-
"json-schema",
|
|
432
|
-
"sqlite",
|
|
433
|
-
"drizzle",
|
|
434
|
-
"orm",
|
|
435
|
-
"ai-extraction",
|
|
436
|
-
"cli",
|
|
437
|
-
"database-migration",
|
|
438
|
-
"schema-editor",
|
|
439
|
-
"code-generation",
|
|
440
|
-
"structured-output"
|
|
441
|
-
],
|
|
442
|
-
sideEffects: false,
|
|
443
|
-
exports: {
|
|
444
|
-
".": "./dist/index.mjs",
|
|
445
|
-
"./cli": "./dist/cli.mjs",
|
|
446
|
-
"./core/schema-sqlite/migrate-helper": "./dist/core/schema-sqlite/migrate-helper.mjs",
|
|
447
|
-
"./package.json": "./package.json"
|
|
448
|
-
},
|
|
449
|
-
main: "./dist/index.mjs",
|
|
450
|
-
module: "./dist/index.mjs",
|
|
451
|
-
types: "./dist/index.d.mts",
|
|
452
|
-
bin: { "aiex": "./bin/cli.mjs" },
|
|
453
|
-
files: [
|
|
454
|
-
"bin",
|
|
455
|
-
"dist",
|
|
456
|
-
"src/core/schema-sqlite/migrate-helper.ts",
|
|
457
|
-
"src/core/schema-sqlite/migration-name.ts"
|
|
458
|
-
],
|
|
459
|
-
scripts: {
|
|
460
|
-
"build": "tsdown && pnpm --filter aiex-web build",
|
|
461
|
-
"dev": "tsdown --watch",
|
|
462
|
-
"start": "tsx src/index.ts",
|
|
463
|
-
"test": "vitest",
|
|
464
|
-
"coverage": "vitest --coverage",
|
|
465
|
-
"typecheck": "tsc",
|
|
466
|
-
"lint": "eslint .",
|
|
467
|
-
"prepack": "cp ../../README.md .",
|
|
468
|
-
"postpack": "rm -f README.md",
|
|
469
|
-
"prepublishOnly": "pnpm run build"
|
|
470
|
-
},
|
|
471
|
-
dependencies: {
|
|
472
|
-
"@ai-sdk/openai-compatible": "catalog:",
|
|
473
|
-
"@clack/prompts": "catalog:",
|
|
474
|
-
"@hono/node-server": "catalog:",
|
|
475
|
-
"@langfuse/otel": "catalog:",
|
|
476
|
-
"@opentelemetry/sdk-trace-node": "catalog:",
|
|
477
|
-
"ai": "catalog:",
|
|
478
|
-
"better-sqlite3": "catalog:",
|
|
479
|
-
"citty": "catalog:",
|
|
480
|
-
"cli-table3": "catalog:",
|
|
481
|
-
"conf": "catalog:",
|
|
482
|
-
"consola": "catalog:",
|
|
483
|
-
"date-fns": "catalog:",
|
|
484
|
-
"drizzle-kit": "catalog:cli",
|
|
485
|
-
"drizzle-orm": "catalog:",
|
|
486
|
-
"es-toolkit": "catalog:",
|
|
487
|
-
"esbuild": "catalog:",
|
|
488
|
-
"hono": "catalog:",
|
|
489
|
-
"picocolors": "catalog:",
|
|
490
|
-
"tsx": "catalog:cli",
|
|
491
|
-
"unpdf": "catalog:",
|
|
492
|
-
"update-notifier": "catalog:",
|
|
493
|
-
"zod": "catalog:"
|
|
494
|
-
},
|
|
495
|
-
devDependencies: {
|
|
496
|
-
"@antfu/eslint-config": "catalog:cli",
|
|
497
|
-
"@antfu/ni": "catalog:cli",
|
|
498
|
-
"@types/better-sqlite3": "catalog:types",
|
|
499
|
-
"@types/node": "catalog:types",
|
|
500
|
-
"@types/update-notifier": "catalog:",
|
|
501
|
-
"@vitest/coverage-v8": "catalog:testing",
|
|
502
|
-
"eslint": "catalog:cli",
|
|
503
|
-
"publint": "catalog:cli",
|
|
504
|
-
"tsdown": "catalog:cli",
|
|
505
|
-
"tsnapi": "catalog:testing",
|
|
506
|
-
"typescript": "catalog:cli",
|
|
507
|
-
"vitest": "catalog:testing"
|
|
508
|
-
}
|
|
509
|
-
};
|
|
510
|
-
|
|
511
|
-
//#endregion
|
|
512
|
-
//#region src/config.ts
|
|
513
|
-
function createConfig() {
|
|
514
|
-
return new Conf({
|
|
515
|
-
cwd: process.env.CLI_CONFIG_DIR,
|
|
516
|
-
projectName: process.env.CLI_CONFIG_PROJECT_NAME || name
|
|
517
|
-
});
|
|
518
|
-
}
|
|
519
|
-
function seedConfig(config = createConfig()) {
|
|
520
|
-
if (!config.has("name")) config.set("name", name);
|
|
521
|
-
if (!config.has("version")) config.set("version", version);
|
|
522
|
-
}
|
|
523
|
-
|
|
524
|
-
//#endregion
|
|
525
|
-
//#region src/core/ai-extraction/schemas.ts
|
|
526
|
-
const ModelCapabilitiesSchema = z.object({
|
|
527
|
-
vision: z.boolean(),
|
|
528
|
-
structuredOutput: z.boolean(),
|
|
529
|
-
maxTokens: z.number().int().positive().optional(),
|
|
530
|
-
maxOutputTokens: z.number().int().positive().optional()
|
|
531
|
-
});
|
|
532
|
-
const AIModelConfigSchema = z.object({
|
|
533
|
-
name: z.string().min(1),
|
|
534
|
-
capabilities: ModelCapabilitiesSchema
|
|
535
|
-
});
|
|
536
|
-
const AIProviderConfigSchema = z.object({
|
|
537
|
-
baseURL: z.string().min(1),
|
|
538
|
-
apiKey: z.string(),
|
|
539
|
-
models: z.array(AIModelConfigSchema).min(1),
|
|
540
|
-
timeout: z.number().int().positive().default(300).optional()
|
|
541
|
-
});
|
|
542
|
-
const PromptConfigSchema = z.object({
|
|
543
|
-
systemTemplate: z.string().min(1),
|
|
544
|
-
userTemplate: z.string().min(1)
|
|
545
|
-
});
|
|
546
|
-
const ExtractionConfigSchema = z.object({ outputDir: z.string().min(1) });
|
|
547
|
-
const LangfuseConfigSchema = z.object({
|
|
548
|
-
publicKey: z.string(),
|
|
549
|
-
secretKey: z.string(),
|
|
550
|
-
host: z.string().optional()
|
|
551
|
-
});
|
|
552
|
-
const AIConfigSchema = z.object({
|
|
553
|
-
provider: AIProviderConfigSchema,
|
|
554
|
-
prompt: PromptConfigSchema,
|
|
555
|
-
extraction: ExtractionConfigSchema,
|
|
556
|
-
langfuse: LangfuseConfigSchema.optional()
|
|
557
|
-
});
|
|
558
|
-
|
|
559
|
-
//#endregion
|
|
560
|
-
//#region src/core/ai-extraction/types.ts
|
|
561
|
-
const PLACEHOLDER_SCHEMA = "{schema}";
|
|
562
|
-
const PLACEHOLDER_TEXT = "{text}";
|
|
563
|
-
const DEFAULT_MODELS = [{
|
|
564
|
-
name: "qwen-plus",
|
|
565
|
-
capabilities: {
|
|
566
|
-
vision: false,
|
|
567
|
-
structuredOutput: true
|
|
568
|
-
}
|
|
569
|
-
}, {
|
|
570
|
-
name: "qwen-vl-plus",
|
|
571
|
-
capabilities: {
|
|
572
|
-
vision: true,
|
|
573
|
-
structuredOutput: true
|
|
574
|
-
}
|
|
575
|
-
}];
|
|
576
|
-
const DEFAULT_PROVIDER_CONFIG = {
|
|
577
|
-
baseURL: "https://dashscope.aliyuncs.com/compatible-mode/v1",
|
|
578
|
-
apiKey: "",
|
|
579
|
-
models: [...DEFAULT_MODELS],
|
|
580
|
-
timeout: 300
|
|
581
|
-
};
|
|
582
|
-
const DEFAULT_PROMPT_CONFIG = {
|
|
583
|
-
systemTemplate: `You are a professional data extraction assistant. Your task is to extract structured data from text and return a JSON object based on the data structure definition provided below.
|
|
584
|
-
|
|
585
|
-
{schema}
|
|
586
|
-
|
|
587
|
-
Extraction requirements:
|
|
588
|
-
1. Extract strictly according to the field names and types defined in the structure
|
|
589
|
-
2. If the text lacks information for a field, set that field to null
|
|
590
|
-
3. Do not add fields that do not exist in the structure definition
|
|
591
|
-
4. Maintain data accuracy and completeness`,
|
|
592
|
-
userTemplate: `Please extract data from the following text:
|
|
593
|
-
{text}`
|
|
594
|
-
};
|
|
595
|
-
const DEFAULT_EXTRACTION_CONFIG = { outputDir: ".aiex/extracted" };
|
|
596
|
-
const DEFAULT_AI_CONFIG = {
|
|
597
|
-
provider: DEFAULT_PROVIDER_CONFIG,
|
|
598
|
-
prompt: DEFAULT_PROMPT_CONFIG,
|
|
599
|
-
extraction: DEFAULT_EXTRACTION_CONFIG
|
|
600
|
-
};
|
|
601
|
-
|
|
602
|
-
//#endregion
|
|
603
|
-
//#region src/core/ai-extraction/config.ts
|
|
604
|
-
const CONFIG_FILE_NAME = "ai-config.json";
|
|
605
|
-
const GITIGNORE_FILE = ".gitignore";
|
|
606
|
-
async function readAIConfig(aiexDir) {
|
|
607
|
-
const configPath = path.join(aiexDir, CONFIG_FILE_NAME);
|
|
608
|
-
try {
|
|
609
|
-
const content = await fs.readFile(configPath, "utf-8");
|
|
610
|
-
const parsed = JSON.parse(content);
|
|
611
|
-
return AIConfigSchema.parse(parsed);
|
|
612
|
-
} catch {
|
|
613
|
-
return null;
|
|
614
|
-
}
|
|
615
|
-
}
|
|
616
|
-
async function writeAIConfig(aiexDir, config) {
|
|
617
|
-
const configPath = path.join(aiexDir, CONFIG_FILE_NAME);
|
|
618
|
-
await fs.mkdir(aiexDir, { recursive: true });
|
|
619
|
-
await fs.writeFile(configPath, `${JSON.stringify(config, null, 2)}\n`);
|
|
620
|
-
await addToGitignore(aiexDir, CONFIG_FILE_NAME);
|
|
621
|
-
}
|
|
622
|
-
function getDefaultAIConfig() {
|
|
623
|
-
return { ...DEFAULT_AI_CONFIG };
|
|
624
|
-
}
|
|
625
|
-
async function addToGitignore(aiexDir, fileName) {
|
|
626
|
-
const projectRoot = path.dirname(aiexDir);
|
|
627
|
-
const gitignorePath = path.join(projectRoot, GITIGNORE_FILE);
|
|
628
|
-
try {
|
|
629
|
-
const content = await fs.readFile(gitignorePath, "utf-8");
|
|
630
|
-
if (content.split("\n").some((line) => line.trim() === fileName || line.includes(".aiex/"))) return;
|
|
631
|
-
const newContent = content.endsWith("\n") ? `${content}${fileName}\n` : `${content}\n${fileName}\n`;
|
|
632
|
-
await fs.writeFile(gitignorePath, newContent);
|
|
633
|
-
} catch {
|
|
634
|
-
await fs.writeFile(gitignorePath, `${fileName}\n`);
|
|
635
|
-
}
|
|
636
|
-
}
|
|
637
|
-
|
|
638
|
-
//#endregion
|
|
639
|
-
//#region src/doctor.ts
|
|
678
|
+
//#region src/core/doctor-collector.ts
|
|
640
679
|
const V1_SUFFIX_RE = /\/v1\/?$/;
|
|
641
680
|
async function checkConnection(baseURL) {
|
|
642
681
|
try {
|
|
@@ -722,4 +761,4 @@ async function collectDoctorDiagnostics(options = {}) {
|
|
|
722
761
|
}
|
|
723
762
|
|
|
724
763
|
//#endregion
|
|
725
|
-
export {
|
|
764
|
+
export { doctorDiagnosticsTableRows as C, buildDoctorDiagnostics as S, seedConfig as _, parseJsonSchema as a, package_default as b, getDefaultAIConfig as c, DEFAULT_MINERU_CONFIG as d, DEFAULT_PROMPT_CONFIG as f, createConfig as g, AIConfigSchema as h, JsonSchemaDefinitionSchema as i, readAIConfig as l, PLACEHOLDER_TEXT as m, createMigrationConfig as n, toSnakeCase as o, PLACEHOLDER_SCHEMA as p, generateDrizzleConfig as r, generateDrizzleSchema as s, collectDoctorDiagnostics as t, writeAIConfig as u, description as v, formatDoctorDiagnosticsJson as w, version as x, name as y };
|
package/dist/index.d.mts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { ZodError, z } from "zod";
|
|
2
1
|
import Conf from "conf";
|
|
2
|
+
import { ZodError, z } from "zod";
|
|
3
3
|
|
|
4
4
|
//#region src/core/doctor.d.ts
|
|
5
5
|
interface DoctorDiagnostics {
|
|
@@ -60,6 +60,19 @@ declare function buildDoctorDiagnostics(input: {
|
|
|
60
60
|
declare function formatDoctorDiagnosticsJson(d: DoctorDiagnostics): string;
|
|
61
61
|
declare function doctorDiagnosticsTableRows(d: DoctorDiagnostics): [string, string][];
|
|
62
62
|
//#endregion
|
|
63
|
+
//#region src/config.d.ts
|
|
64
|
+
interface AppConfig {
|
|
65
|
+
name?: string;
|
|
66
|
+
version?: string;
|
|
67
|
+
}
|
|
68
|
+
declare function createConfig(): Conf<AppConfig>;
|
|
69
|
+
//#endregion
|
|
70
|
+
//#region src/core/doctor-collector.d.ts
|
|
71
|
+
interface CollectDoctorDiagnosticsOptions {
|
|
72
|
+
config?: ReturnType<typeof createConfig>;
|
|
73
|
+
}
|
|
74
|
+
declare function collectDoctorDiagnostics(options?: CollectDoctorDiagnosticsOptions): Promise<DoctorDiagnostics>;
|
|
75
|
+
//#endregion
|
|
63
76
|
//#region src/core/schema-sqlite/types.d.ts
|
|
64
77
|
interface ParsedColumn {
|
|
65
78
|
name: string;
|
|
@@ -114,7 +127,6 @@ declare function createMigrationConfig(cwd: string): MigrationConfig;
|
|
|
114
127
|
declare function generateDrizzleConfig(): string;
|
|
115
128
|
//#endregion
|
|
116
129
|
//#region src/core/schema-sqlite/schemas.d.ts
|
|
117
|
-
|
|
118
130
|
declare const JsonSchemaDefinitionSchema: z.ZodEffects<z.ZodEffects<z.ZodEffects<z.ZodObject<{
|
|
119
131
|
$schema: z.ZodOptional<z.ZodString>;
|
|
120
132
|
title: z.ZodString;
|
|
@@ -266,17 +278,4 @@ type JsonSchemaDefinition = z.infer<typeof JsonSchemaDefinitionSchema>;
|
|
|
266
278
|
//#region src/core/schema-sqlite/parser.d.ts
|
|
267
279
|
declare function parseJsonSchema(schema: JsonSchemaDefinition): ParseResult;
|
|
268
280
|
//#endregion
|
|
269
|
-
//#region src/config.d.ts
|
|
270
|
-
interface AppConfig {
|
|
271
|
-
name?: string;
|
|
272
|
-
version?: string;
|
|
273
|
-
}
|
|
274
|
-
declare function createConfig(): Conf<AppConfig>;
|
|
275
|
-
//#endregion
|
|
276
|
-
//#region src/doctor.d.ts
|
|
277
|
-
interface CollectDoctorDiagnosticsOptions {
|
|
278
|
-
config?: ReturnType<typeof createConfig>;
|
|
279
|
-
}
|
|
280
|
-
declare function collectDoctorDiagnostics(options?: CollectDoctorDiagnosticsOptions): Promise<DoctorDiagnostics>;
|
|
281
|
-
//#endregion
|
|
282
281
|
export { type DoctorDiagnostics, type JsonSchemaDefinition, JsonSchemaDefinitionSchema, type JsonSchemaProperty, type MigrationConfig, type ParseResult, type ParsedColumn, type ParsedRelation, type ParsedTable, buildDoctorDiagnostics, collectDoctorDiagnostics, createMigrationConfig, doctorDiagnosticsTableRows, formatDoctorDiagnosticsJson, generateDrizzleConfig, generateDrizzleSchema, parseJsonSchema };
|
package/dist/index.mjs
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import { C as
|
|
1
|
+
import { C as doctorDiagnosticsTableRows, S as buildDoctorDiagnostics, a as parseJsonSchema, i as JsonSchemaDefinitionSchema, n as createMigrationConfig, r as generateDrizzleConfig, s as generateDrizzleSchema, t as collectDoctorDiagnostics, w as formatDoctorDiagnosticsJson } from "./doctor-collector-j2dG7dG1.mjs";
|
|
2
2
|
|
|
3
3
|
export { JsonSchemaDefinitionSchema, buildDoctorDiagnostics, collectDoctorDiagnostics, createMigrationConfig, doctorDiagnosticsTableRows, formatDoctorDiagnosticsJson, generateDrizzleConfig, generateDrizzleSchema, parseJsonSchema };
|