aiex-cli 0.0.1-beta.8 → 0.0.1
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 +32 -25
- package/dist/cli.mjs +912 -572
- package/dist/{completions-ygS1okck.mjs → completions-C3rmTwXZ.mjs} +2 -2
- package/dist/core/schema-sqlite/migrate-helper.mjs +35 -37
- package/dist/{doctor-DxG7uaGR.mjs → doctor-collector-CykRm0fC.mjs} +282 -223
- package/dist/index.d.mts +15 -15
- package/dist/index.mjs +1 -1
- package/dist/table-schema.json +4 -0
- package/dist/web/assets/AISettings-CI6Lgx0p.js +339 -0
- package/dist/web/assets/DataBrowser-CwcTG80-.js +6 -0
- package/dist/web/assets/ExtractionViewer-CsdK1kKK.js +1 -0
- package/dist/web/assets/JsonSchemaEditor-D477lV5a.js +570 -0
- package/dist/web/assets/api-client-D2Y_-4JM.js +1 -0
- package/dist/web/assets/button-Cdgr9Igy.js +927 -0
- package/dist/web/assets/{cssMode-DAbG0CMn.js → cssMode-CPThwItX.js} +1 -1
- package/dist/web/assets/dialog-CUkPLPNP.js +109 -0
- package/dist/web/assets/dist-9yHVMqQ0.js +1 -0
- package/dist/web/assets/{editor.main-BqhfoHxy.js → editor.main-BnOkwRFv.js} +2 -2
- package/dist/web/assets/{freemarker2-B9_5ct2b.js → freemarker2-DWDTYVJR.js} +1 -1
- package/dist/web/assets/{handlebars-TY59WcoQ.js → handlebars-D4DzjGQ7.js} +1 -1
- package/dist/web/assets/{html-CLULsh27.js → html-DnzhKSoD.js} +1 -1
- package/dist/web/assets/{htmlMode-BvG7RNbU.js → htmlMode-CR7UKfEH.js} +1 -1
- package/dist/web/assets/index-C9N8oWt4.css +2 -0
- package/dist/web/assets/{index-BRvFRL-3.js → index-DVDVw-GK.js} +38 -38
- package/dist/web/assets/{javascript-DHrLp6gu.js → javascript-D2srszZ8.js} +1 -1
- package/dist/web/assets/{jsonMode-DBDhdzl1.js → jsonMode-B4jaPYEr.js} +1 -1
- package/dist/web/assets/{liquid-tGeb-nqF.js → liquid-CIT2Wl_l.js} +1 -1
- package/dist/web/assets/{mdx-Cmdz78VU.js → mdx-CWLaEOFy.js} +1 -1
- package/dist/web/assets/{monaco.contribution-CroYPUF5.js → monaco.contribution-DDv5ldfS.js} +2 -2
- package/dist/web/assets/object-utils-I4gWdSnS.js +1 -0
- package/dist/web/assets/{python-Dmfz4iDE.js → python-6CGfpCNq.js} +1 -1
- package/dist/web/assets/{razor-BJicZHJs.js → razor-DEMMh3TD.js} +1 -1
- package/dist/web/assets/runtime-dom.esm-bundler-ei_N7Xjw.js +1 -0
- package/dist/web/assets/select-BGex2SPs.js +439 -0
- package/dist/web/assets/{tsMode-DYqTyE66.js → tsMode-Cm1NtjPs.js} +1 -1
- package/dist/web/assets/{typescript-DLnTe9Hf.js → typescript-BM9aPEFg.js} +1 -1
- package/dist/web/assets/{xml-BIYqLORk.js → xml-CoSbvcg5.js} +1 -1
- package/dist/web/assets/{yaml-BjmulkMX.js → yaml-56GOgy8k.js} +1 -1
- package/dist/web/index.html +10 -8
- package/package.json +16 -1
- package/src/core/schema-sqlite/migrate-helper.ts +32 -46
- package/dist/web/assets/AISettings-D_AFhorO.js +0 -334
- package/dist/web/assets/DataBrowser-rznfVRaV.js +0 -3
- package/dist/web/assets/JsonSchemaEditor-C9iyQs7N.js +0 -929
- package/dist/web/assets/api-client-Dsg4WOM9.js +0 -1
- package/dist/web/assets/button-kTMweGMc.js +0 -927
- package/dist/web/assets/dialog-CWuu7WjI.js +0 -108
- package/dist/web/assets/index-DDFnprdM.css +0 -2
- package/dist/web/assets/lib-C30cIFrm.js +0 -1
- package/dist/web/assets/overlayeventbus-AtOpmI6n.js +0 -80
- package/dist/web/assets/table-schema-mJrrf9qw.js +0 -2
- /package/dist/web/assets/{abap-DrZwwXZX.js → abap-Bgec7Keq.js} +0 -0
- /package/dist/web/assets/{apex-CrCz0btt.js → apex-VBlPwEoQ.js} +0 -0
- /package/dist/web/assets/{azcli-BapzKHay.js → azcli-DKqrEFBx.js} +0 -0
- /package/dist/web/assets/{bat-C_NRAiA1.js → bat-DdgQWy_0.js} +0 -0
- /package/dist/web/assets/{bicep-C7pp2CNk.js → bicep-CRMM43EB.js} +0 -0
- /package/dist/web/assets/{cameligo-BhhK9vxZ.js → cameligo-UatALtML.js} +0 -0
- /package/dist/web/assets/{clojure-D0ujmUyE.js → clojure-D8JU08RA.js} +0 -0
- /package/dist/web/assets/{coffee-DHEl7Jbb.js → coffee-C56wu358.js} +0 -0
- /package/dist/web/assets/{cpp-Iil-3nzZ.js → cpp-CyZLvhJG.js} +0 -0
- /package/dist/web/assets/{csharp-Dh0Ee7SY.js → csharp-BJl3ixva.js} +0 -0
- /package/dist/web/assets/{csp-mwzjw0JL.js → csp-CxEKxmO-.js} +0 -0
- /package/dist/web/assets/{css-COIa8ZTR.js → css-B0t_muXd.js} +0 -0
- /package/dist/web/assets/{cypher-GVc17FC4.js → cypher-D1hqiMFD.js} +0 -0
- /package/dist/web/assets/{dart-phiCaE7_.js → dart-Bz550Pyv.js} +0 -0
- /package/dist/web/assets/{dockerfile-BMaDhdim.js → dockerfile-CIXgVAuA.js} +0 -0
- /package/dist/web/assets/{ecl-Cj47kvqp.js → ecl-D9qbvZoA.js} +0 -0
- /package/dist/web/assets/{editor.api-DLXGyrN1.js → editor.api-C8BHpRhn.js} +0 -0
- /package/dist/web/assets/{elixir-DBbstcE1.js → elixir-b2M38fAy.js} +0 -0
- /package/dist/web/assets/{flow9-ChHb1adO.js → flow9-Dq1UYMkt.js} +0 -0
- /package/dist/web/assets/{fsharp-CMk2OIJN.js → fsharp-BaeLhgfq.js} +0 -0
- /package/dist/web/assets/{go-BrMkuJg0.js → go-Bd-NFKIC.js} +0 -0
- /package/dist/web/assets/{graphql-PSR1UKGv.js → graphql-DZVerJfy.js} +0 -0
- /package/dist/web/assets/{hcl-DAQrbDOW.js → hcl-CAVzrZfH.js} +0 -0
- /package/dist/web/assets/{ini-0TG5BxW0.js → ini-CyXdX58t.js} +0 -0
- /package/dist/web/assets/{java-rgorz17v.js → java-B5pNgvhy.js} +0 -0
- /package/dist/web/assets/{julia-C8VMdHm8.js → julia-XRhmV3AN.js} +0 -0
- /package/dist/web/assets/{kotlin-CllWo3gX.js → kotlin-DOd3J5vr.js} +0 -0
- /package/dist/web/assets/{less-Cgca25AP.js → less-veZSnyw6.js} +0 -0
- /package/dist/web/assets/{lexon-D0GHdBaw.js → lexon-QWGkuK0H.js} +0 -0
- /package/dist/web/assets/{lua-DmRsNG-P.js → lua-CYGpjuO5.js} +0 -0
- /package/dist/web/assets/{m3-BgL5dNKT.js → m3-yNnrZkdc.js} +0 -0
- /package/dist/web/assets/{markdown-BuJfycGS.js → markdown-BCSWEPSX.js} +0 -0
- /package/dist/web/assets/{mips-C9m_93PR.js → mips-OpYmcC30.js} +0 -0
- /package/dist/web/assets/{msdax-CpFHC9OI.js → msdax-2oxoTO9Z.js} +0 -0
- /package/dist/web/assets/{mysql-qFvltsqN.js → mysql-5KlC-K_9.js} +0 -0
- /package/dist/web/assets/{objective-c-Bnmr858J.js → objective-c-CcDCgtLx.js} +0 -0
- /package/dist/web/assets/{pascal-WP0_D5AO.js → pascal-BZGsbaEV.js} +0 -0
- /package/dist/web/assets/{pascaligo-Blom4Rij.js → pascaligo-DtD5qU3G.js} +0 -0
- /package/dist/web/assets/{perl-B-vk8g64.js → perl-C1jNNS3E.js} +0 -0
- /package/dist/web/assets/{pgsql-Cgvz6v67.js → pgsql-CT0fhiZa.js} +0 -0
- /package/dist/web/assets/{php-8a3Lrw9m.js → php-D6DrXoPM.js} +0 -0
- /package/dist/web/assets/{pla-DuFqEZ8V.js → pla-b3-HN2pF.js} +0 -0
- /package/dist/web/assets/{postiats-DkLtSgkp.js → postiats-Bin2ApVS.js} +0 -0
- /package/dist/web/assets/{powerquery-BJ1aNepW.js → powerquery-7ASnn-ZG.js} +0 -0
- /package/dist/web/assets/{powershell-rE98k687.js → powershell-t4p7sU1H.js} +0 -0
- /package/dist/web/assets/{preload-helper-DWTEM3RW.js → preload-helper-Dd-HcVz_.js} +0 -0
- /package/dist/web/assets/{protobuf-CUheFacr.js → protobuf-BUGeWa_j.js} +0 -0
- /package/dist/web/assets/{pug-LDcAMD8w.js → pug-BuKcgC9s.js} +0 -0
- /package/dist/web/assets/{qsharp-IHfqKOfK.js → qsharp-DxLLX8mo.js} +0 -0
- /package/dist/web/assets/{r-D-QApv87.js → r-DMlFgn7A.js} +0 -0
- /package/dist/web/assets/{redis-SXdDyWR9.js → redis-cXItkC5u.js} +0 -0
- /package/dist/web/assets/{redshift-Y6lsCryn.js → redshift-BZVbW7HE.js} +0 -0
- /package/dist/web/assets/{restructuredtext-edObr9a8.js → restructuredtext-BzjxwS8h.js} +0 -0
- /package/dist/web/assets/{ruby-CNnUfF-8.js → ruby-C5nyLV4l.js} +0 -0
- /package/dist/web/assets/{rust-IHUZWzBr.js → rust-BcmMsHdf.js} +0 -0
- /package/dist/web/assets/{sb-DrUvY44N.js → sb-Dnb1iy6B.js} +0 -0
- /package/dist/web/assets/{scala-B4hbXGLM.js → scala-anMIFYpA.js} +0 -0
- /package/dist/web/assets/{scheme-BGrd12j3.js → scheme-BItQTe08.js} +0 -0
- /package/dist/web/assets/{scss-x5G1ES4U.js → scss-BOv51BJ5.js} +0 -0
- /package/dist/web/assets/{shell-DOehe2Y8.js → shell-BsRYRTNN.js} +0 -0
- /package/dist/web/assets/{solidity-BeRvcwWV.js → solidity-BtuLgGDx.js} +0 -0
- /package/dist/web/assets/{sophia-DZbkUNjy.js → sophia-B0Vkc5MF.js} +0 -0
- /package/dist/web/assets/{sparql-B7_oi5-h.js → sparql-B7lvkZQM.js} +0 -0
- /package/dist/web/assets/{sql-CTlsFWVE.js → sql-DvP5MpA3.js} +0 -0
- /package/dist/web/assets/{st-DJVEJdPE.js → st-GVUeyB3U.js} +0 -0
- /package/dist/web/assets/{swift-CwhT3fYa.js → swift-DSPIoCjm.js} +0 -0
- /package/dist/web/assets/{systemverilog-BQN63pkN.js → systemverilog-Icj2-k23.js} +0 -0
- /package/dist/web/assets/{tcl-DqwfpskA.js → tcl-Cd8KQcm-.js} +0 -0
- /package/dist/web/assets/{twig-BiyenUgc.js → twig-CBHmt8z3.js} +0 -0
- /package/dist/web/assets/{typespec-CWOJribt.js → typespec-Ckc037mq.js} +0 -0
- /package/dist/web/assets/{vb-Cq5F87m3.js → vb-B97GW9Wb.js} +0 -0
- /package/dist/web/assets/{wgsl-BAvW2lVr.js → wgsl-DIKmb3YH.js} +0 -0
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import path from "node:path";
|
|
2
2
|
import process from "node:process";
|
|
3
|
+
import { readFileSync } from "jsonfile";
|
|
3
4
|
import fs from "node:fs";
|
|
4
5
|
|
|
5
6
|
//#region src/core/completions.ts
|
|
@@ -27,8 +28,7 @@ function getFileCompletions(pattern) {
|
|
|
27
28
|
}
|
|
28
29
|
function getJsonModelNames(configPath) {
|
|
29
30
|
try {
|
|
30
|
-
const
|
|
31
|
-
const config = JSON.parse(content);
|
|
31
|
+
const config = readFileSync(configPath);
|
|
32
32
|
if (config.provider?.models) return config.provider.models.map((m) => m.name);
|
|
33
33
|
} catch {}
|
|
34
34
|
return [];
|
|
@@ -1,10 +1,12 @@
|
|
|
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";
|
|
5
|
+
import { readFile, writeFile } from "jsonfile";
|
|
4
6
|
import { fileURLToPath } from "node:url";
|
|
5
|
-
import fs from "node:fs/promises";
|
|
6
7
|
import Database from "better-sqlite3";
|
|
7
8
|
import * as esbuild from "esbuild";
|
|
9
|
+
import lockfile from "proper-lockfile";
|
|
8
10
|
|
|
9
11
|
//#region src/core/schema-sqlite/migration-name.ts
|
|
10
12
|
function sanitizeMigrationName(name) {
|
|
@@ -62,11 +64,10 @@ async function loadSchemaExports(schemaPath) {
|
|
|
62
64
|
async function loadPrevSnapshot(migrationsPath) {
|
|
63
65
|
const metaPath = path.join(migrationsPath, "meta", "_journal.json");
|
|
64
66
|
try {
|
|
65
|
-
const journal =
|
|
67
|
+
const journal = await readFile(metaPath);
|
|
66
68
|
if (!journal.entries?.length) return null;
|
|
67
69
|
const latestEntry = journal.entries[journal.entries.length - 1];
|
|
68
|
-
|
|
69
|
-
return JSON.parse(await fs.readFile(snapshotPath, "utf-8"));
|
|
70
|
+
return await readFile(path.join(migrationsPath, "meta", `${latestEntry.tag}_snapshot.json`));
|
|
70
71
|
} catch {
|
|
71
72
|
return null;
|
|
72
73
|
}
|
|
@@ -77,7 +78,7 @@ async function saveSnapshot(migrationsPath, snapshot, migrationName) {
|
|
|
77
78
|
const journalPath = path.join(metaPath, "_journal.json");
|
|
78
79
|
let journal;
|
|
79
80
|
try {
|
|
80
|
-
journal =
|
|
81
|
+
journal = await readFile(journalPath);
|
|
81
82
|
} catch {
|
|
82
83
|
journal = {
|
|
83
84
|
version: "6",
|
|
@@ -88,8 +89,10 @@ async function saveSnapshot(migrationsPath, snapshot, migrationName) {
|
|
|
88
89
|
const idx = journal.entries.length + 1;
|
|
89
90
|
const suffix = sanitizeMigrationName(migrationName) || snapshot.id.replace(/-/g, "_").substring(0, 8);
|
|
90
91
|
const tag = `${String(idx).padStart(4, "0")}_${suffix}`;
|
|
91
|
-
|
|
92
|
-
|
|
92
|
+
await writeFile(path.join(metaPath, `${tag}_snapshot.json`), snapshot, {
|
|
93
|
+
spaces: 2,
|
|
94
|
+
EOL: "\n"
|
|
95
|
+
});
|
|
93
96
|
journal.entries.push({
|
|
94
97
|
idx,
|
|
95
98
|
version: snapshot.id,
|
|
@@ -97,7 +100,10 @@ async function saveSnapshot(migrationsPath, snapshot, migrationName) {
|
|
|
97
100
|
tag,
|
|
98
101
|
breakpoints: true
|
|
99
102
|
});
|
|
100
|
-
await
|
|
103
|
+
await writeFile(journalPath, journal, {
|
|
104
|
+
spaces: 2,
|
|
105
|
+
EOL: "\n"
|
|
106
|
+
});
|
|
101
107
|
return tag;
|
|
102
108
|
}
|
|
103
109
|
async function saveMigrationFile(migrationsPath, tag, sqlStatements) {
|
|
@@ -119,35 +125,22 @@ function applyMigrationWithTransaction(dbPath, sqlStatements) {
|
|
|
119
125
|
}
|
|
120
126
|
}
|
|
121
127
|
const LOCK_FILE = ".migrate.lock";
|
|
122
|
-
async function
|
|
123
|
-
const lockPath = path.join(aiexDir, LOCK_FILE);
|
|
128
|
+
async function acquireMigrationLock(aiexDir) {
|
|
124
129
|
await fs.mkdir(aiexDir, { recursive: true });
|
|
125
130
|
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;
|
|
131
|
+
return await lockfile.lock(aiexDir, {
|
|
132
|
+
lockfilePath: path.join(aiexDir, LOCK_FILE),
|
|
133
|
+
realpath: false,
|
|
134
|
+
stale: 3e5,
|
|
135
|
+
update: 1e4,
|
|
136
|
+
retries: 0
|
|
137
|
+
});
|
|
138
|
+
} catch (error) {
|
|
139
|
+
const lockPath = path.join(aiexDir, LOCK_FILE);
|
|
140
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
141
|
+
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
142
|
}
|
|
146
143
|
}
|
|
147
|
-
async function releaseLock(aiexDir) {
|
|
148
|
-
const lockPath = path.join(aiexDir, LOCK_FILE);
|
|
149
|
-
await fs.unlink(lockPath).catch(() => {});
|
|
150
|
-
}
|
|
151
144
|
async function main() {
|
|
152
145
|
const args = process.argv.slice(2);
|
|
153
146
|
const schemaPath = args[0];
|
|
@@ -159,11 +152,16 @@ async function main() {
|
|
|
159
152
|
process.exit(1);
|
|
160
153
|
}
|
|
161
154
|
try {
|
|
162
|
-
const
|
|
163
|
-
await acquireLock(aiexDir);
|
|
155
|
+
const releaseLock = await acquireMigrationLock(path.dirname(path.dirname(migrationsPath)));
|
|
164
156
|
try {
|
|
165
157
|
const exports = await loadSchemaExports(schemaPath);
|
|
166
|
-
|
|
158
|
+
let dbMissing = false;
|
|
159
|
+
try {
|
|
160
|
+
await fs.access(dbPath);
|
|
161
|
+
} catch {
|
|
162
|
+
dbMissing = true;
|
|
163
|
+
}
|
|
164
|
+
const prevSnapshot = dbMissing ? null : await loadPrevSnapshot(migrationsPath);
|
|
167
165
|
const currentSnapshot = await generateSQLiteDrizzleJson(exports, prevSnapshot?.id);
|
|
168
166
|
const sqlStatements = await generateSQLiteMigration(prevSnapshot || EMPTY_SNAPSHOT, currentSnapshot);
|
|
169
167
|
if (sqlStatements.length === 0) {
|
|
@@ -182,7 +180,7 @@ async function main() {
|
|
|
182
180
|
tag
|
|
183
181
|
}));
|
|
184
182
|
} finally {
|
|
185
|
-
await releaseLock(
|
|
183
|
+
await releaseLock();
|
|
186
184
|
}
|
|
187
185
|
} catch (error) {
|
|
188
186
|
const message = error instanceof Error ? error.message : String(error);
|
|
@@ -1,9 +1,10 @@
|
|
|
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 { readFile, writeFile } from "jsonfile";
|
|
7
|
+
import { z } from "zod";
|
|
7
8
|
|
|
8
9
|
//#region src/core/doctor.ts
|
|
9
10
|
function buildDoctorDiagnostics(input) {
|
|
@@ -61,6 +62,281 @@ function doctorDiagnosticsTableRows(d) {
|
|
|
61
62
|
return rows;
|
|
62
63
|
}
|
|
63
64
|
|
|
65
|
+
//#endregion
|
|
66
|
+
//#region package.json
|
|
67
|
+
var name = "aiex-cli";
|
|
68
|
+
var version = "0.0.1";
|
|
69
|
+
var description = "JSON Schema → SQLite with AI-powered data extraction";
|
|
70
|
+
var package_default = {
|
|
71
|
+
name,
|
|
72
|
+
type: "module",
|
|
73
|
+
version,
|
|
74
|
+
description,
|
|
75
|
+
author: "OSpoon <zxin088@gmail.com>",
|
|
76
|
+
license: "MIT",
|
|
77
|
+
homepage: "https://github.com/OSpoon/aiex-cli#readme",
|
|
78
|
+
repository: {
|
|
79
|
+
"type": "git",
|
|
80
|
+
"url": "git+https://github.com/OSpoon/aiex-cli.git"
|
|
81
|
+
},
|
|
82
|
+
bugs: "https://github.com/OSpoon/aiex-cli/issues",
|
|
83
|
+
keywords: [
|
|
84
|
+
"json-schema",
|
|
85
|
+
"sqlite",
|
|
86
|
+
"drizzle",
|
|
87
|
+
"orm",
|
|
88
|
+
"ai-extraction",
|
|
89
|
+
"cli",
|
|
90
|
+
"database-migration",
|
|
91
|
+
"schema-editor",
|
|
92
|
+
"code-generation",
|
|
93
|
+
"structured-output"
|
|
94
|
+
],
|
|
95
|
+
sideEffects: false,
|
|
96
|
+
exports: {
|
|
97
|
+
".": "./dist/index.mjs",
|
|
98
|
+
"./cli": "./dist/cli.mjs",
|
|
99
|
+
"./core/schema-sqlite/migrate-helper": "./dist/core/schema-sqlite/migrate-helper.mjs",
|
|
100
|
+
"./package.json": "./package.json"
|
|
101
|
+
},
|
|
102
|
+
main: "./dist/index.mjs",
|
|
103
|
+
module: "./dist/index.mjs",
|
|
104
|
+
types: "./dist/index.d.mts",
|
|
105
|
+
bin: { "aiex": "./bin/cli.mjs" },
|
|
106
|
+
files: [
|
|
107
|
+
"bin",
|
|
108
|
+
"dist",
|
|
109
|
+
"src/core/schema-sqlite/migrate-helper.ts",
|
|
110
|
+
"src/core/schema-sqlite/migration-name.ts"
|
|
111
|
+
],
|
|
112
|
+
scripts: {
|
|
113
|
+
"build": "tsdown && pnpm --filter aiex-web build",
|
|
114
|
+
"dev": "tsdown --watch",
|
|
115
|
+
"start": "tsx src/index.ts",
|
|
116
|
+
"test": "vitest",
|
|
117
|
+
"coverage": "vitest --coverage",
|
|
118
|
+
"typecheck": "tsc",
|
|
119
|
+
"lint": "eslint .",
|
|
120
|
+
"prepack": "cp ../../README.md .",
|
|
121
|
+
"postpack": "rm -f README.md",
|
|
122
|
+
"prepublishOnly": "pnpm run build"
|
|
123
|
+
},
|
|
124
|
+
dependencies: {
|
|
125
|
+
"@ai-sdk/openai-compatible": "catalog:",
|
|
126
|
+
"@clack/prompts": "catalog:",
|
|
127
|
+
"@hono/node-server": "catalog:",
|
|
128
|
+
"@hono/zod-validator": "catalog:",
|
|
129
|
+
"@langfuse/otel": "catalog:",
|
|
130
|
+
"@opentelemetry/sdk-trace-node": "catalog:",
|
|
131
|
+
"ai": "catalog:",
|
|
132
|
+
"better-sqlite3": "catalog:",
|
|
133
|
+
"citty": "catalog:",
|
|
134
|
+
"cli-table3": "catalog:",
|
|
135
|
+
"conf": "catalog:",
|
|
136
|
+
"consola": "catalog:",
|
|
137
|
+
"date-fns": "catalog:",
|
|
138
|
+
"drizzle-kit": "catalog:cli",
|
|
139
|
+
"drizzle-orm": "catalog:",
|
|
140
|
+
"es-toolkit": "catalog:",
|
|
141
|
+
"esbuild": "catalog:",
|
|
142
|
+
"execa": "catalog:",
|
|
143
|
+
"hono": "catalog:",
|
|
144
|
+
"jsonfile": "catalog:",
|
|
145
|
+
"jsonrepair": "catalog:",
|
|
146
|
+
"kysely": "catalog:",
|
|
147
|
+
"mime": "catalog:",
|
|
148
|
+
"open": "catalog:",
|
|
149
|
+
"p-retry": "catalog:",
|
|
150
|
+
"picocolors": "catalog:",
|
|
151
|
+
"proper-lockfile": "catalog:",
|
|
152
|
+
"tinyglobby": "catalog:",
|
|
153
|
+
"tsx": "catalog:cli",
|
|
154
|
+
"unpdf": "catalog:",
|
|
155
|
+
"update-notifier": "catalog:",
|
|
156
|
+
"zod": "catalog:"
|
|
157
|
+
},
|
|
158
|
+
devDependencies: {
|
|
159
|
+
"@antfu/eslint-config": "catalog:cli",
|
|
160
|
+
"@antfu/ni": "catalog:cli",
|
|
161
|
+
"@types/better-sqlite3": "catalog:types",
|
|
162
|
+
"@types/jsonfile": "catalog:",
|
|
163
|
+
"@types/node": "catalog:types",
|
|
164
|
+
"@types/proper-lockfile": "catalog:",
|
|
165
|
+
"@types/update-notifier": "catalog:",
|
|
166
|
+
"@vitest/coverage-v8": "catalog:testing",
|
|
167
|
+
"eslint": "catalog:cli",
|
|
168
|
+
"publint": "catalog:cli",
|
|
169
|
+
"tsdown": "catalog:cli",
|
|
170
|
+
"tsnapi": "catalog:testing",
|
|
171
|
+
"typescript": "catalog:cli",
|
|
172
|
+
"vitest": "catalog:testing"
|
|
173
|
+
}
|
|
174
|
+
};
|
|
175
|
+
|
|
176
|
+
//#endregion
|
|
177
|
+
//#region src/config.ts
|
|
178
|
+
function createConfig() {
|
|
179
|
+
return new Conf({
|
|
180
|
+
cwd: process.env.CLI_CONFIG_DIR,
|
|
181
|
+
projectName: process.env.CLI_CONFIG_PROJECT_NAME || name
|
|
182
|
+
});
|
|
183
|
+
}
|
|
184
|
+
function seedConfig(config = createConfig()) {
|
|
185
|
+
if (!config.has("name")) config.set("name", name);
|
|
186
|
+
if (!config.has("version")) config.set("version", version);
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
//#endregion
|
|
190
|
+
//#region src/core/ai-extraction/schemas.ts
|
|
191
|
+
const ModelCapabilitiesSchema = z.object({
|
|
192
|
+
vision: z.boolean(),
|
|
193
|
+
structuredOutput: z.boolean(),
|
|
194
|
+
maxTokens: z.number().int().positive().optional(),
|
|
195
|
+
maxOutputTokens: z.number().int().positive().optional()
|
|
196
|
+
});
|
|
197
|
+
const AIModelConfigSchema = z.object({
|
|
198
|
+
name: z.string().min(1),
|
|
199
|
+
capabilities: ModelCapabilitiesSchema
|
|
200
|
+
});
|
|
201
|
+
const AIProviderConfigSchema = z.object({
|
|
202
|
+
baseURL: z.string().min(1),
|
|
203
|
+
apiKey: z.string(),
|
|
204
|
+
models: z.array(AIModelConfigSchema).min(1),
|
|
205
|
+
timeout: z.number().int().positive().default(300).optional()
|
|
206
|
+
});
|
|
207
|
+
const PromptConfigSchema = z.object({
|
|
208
|
+
systemTemplate: z.string().min(1),
|
|
209
|
+
userTemplate: z.string().min(1)
|
|
210
|
+
});
|
|
211
|
+
const ExtractionConfigSchema = z.object({ outputDir: z.string().min(1) });
|
|
212
|
+
const ExternalPdfConverterConfigSchema = z.object({
|
|
213
|
+
command: z.string().min(1),
|
|
214
|
+
args: z.array(z.string()),
|
|
215
|
+
outputFile: z.string().min(1).optional(),
|
|
216
|
+
timeout: z.number().int().positive().default(600).optional(),
|
|
217
|
+
fallbackToUnpdf: z.boolean().optional(),
|
|
218
|
+
keepOutput: z.boolean().optional()
|
|
219
|
+
});
|
|
220
|
+
const PdfConfigSchema = z.object({
|
|
221
|
+
converter: z.enum([
|
|
222
|
+
"unpdf",
|
|
223
|
+
"mineru",
|
|
224
|
+
"external"
|
|
225
|
+
]),
|
|
226
|
+
mineru: ExternalPdfConverterConfigSchema.optional(),
|
|
227
|
+
external: ExternalPdfConverterConfigSchema.optional()
|
|
228
|
+
});
|
|
229
|
+
const LangfuseConfigSchema = z.object({
|
|
230
|
+
publicKey: z.string(),
|
|
231
|
+
secretKey: z.string(),
|
|
232
|
+
host: z.string().optional()
|
|
233
|
+
});
|
|
234
|
+
const AIConfigSchema = z.object({
|
|
235
|
+
provider: AIProviderConfigSchema,
|
|
236
|
+
prompt: PromptConfigSchema,
|
|
237
|
+
extraction: ExtractionConfigSchema,
|
|
238
|
+
pdf: PdfConfigSchema.optional(),
|
|
239
|
+
langfuse: LangfuseConfigSchema.optional()
|
|
240
|
+
});
|
|
241
|
+
|
|
242
|
+
//#endregion
|
|
243
|
+
//#region src/core/ai-extraction/types.ts
|
|
244
|
+
const PLACEHOLDER_SCHEMA = "{schema}";
|
|
245
|
+
const PLACEHOLDER_TEXT = "{text}";
|
|
246
|
+
const DEFAULT_MODELS = [{
|
|
247
|
+
name: "qwen-plus",
|
|
248
|
+
capabilities: {
|
|
249
|
+
vision: false,
|
|
250
|
+
structuredOutput: true
|
|
251
|
+
}
|
|
252
|
+
}, {
|
|
253
|
+
name: "qwen-vl-plus",
|
|
254
|
+
capabilities: {
|
|
255
|
+
vision: true,
|
|
256
|
+
structuredOutput: true
|
|
257
|
+
}
|
|
258
|
+
}];
|
|
259
|
+
const DEFAULT_PROVIDER_CONFIG = {
|
|
260
|
+
baseURL: "https://dashscope.aliyuncs.com/compatible-mode/v1",
|
|
261
|
+
apiKey: "",
|
|
262
|
+
models: [...DEFAULT_MODELS],
|
|
263
|
+
timeout: 300
|
|
264
|
+
};
|
|
265
|
+
const DEFAULT_PROMPT_CONFIG = {
|
|
266
|
+
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.
|
|
267
|
+
|
|
268
|
+
{schema}
|
|
269
|
+
|
|
270
|
+
Extraction requirements:
|
|
271
|
+
1. Extract strictly according to the field names and types defined in the structure
|
|
272
|
+
2. If the text lacks information for a field, set that field to null
|
|
273
|
+
3. Do not add fields that do not exist in the structure definition
|
|
274
|
+
4. Maintain data accuracy and completeness`,
|
|
275
|
+
userTemplate: `Please extract data from the following text:
|
|
276
|
+
{text}`
|
|
277
|
+
};
|
|
278
|
+
const DEFAULT_EXTRACTION_CONFIG = { outputDir: ".aiex/extracted" };
|
|
279
|
+
const DEFAULT_MINERU_CONFIG = {
|
|
280
|
+
command: "mineru",
|
|
281
|
+
args: [
|
|
282
|
+
"-p",
|
|
283
|
+
"{input}",
|
|
284
|
+
"-o",
|
|
285
|
+
"{outputDir}"
|
|
286
|
+
],
|
|
287
|
+
timeout: 600,
|
|
288
|
+
fallbackToUnpdf: true,
|
|
289
|
+
keepOutput: true
|
|
290
|
+
};
|
|
291
|
+
const DEFAULT_PDF_CONFIG = {
|
|
292
|
+
converter: "unpdf",
|
|
293
|
+
mineru: DEFAULT_MINERU_CONFIG
|
|
294
|
+
};
|
|
295
|
+
const DEFAULT_AI_CONFIG = {
|
|
296
|
+
provider: DEFAULT_PROVIDER_CONFIG,
|
|
297
|
+
prompt: DEFAULT_PROMPT_CONFIG,
|
|
298
|
+
extraction: DEFAULT_EXTRACTION_CONFIG,
|
|
299
|
+
pdf: DEFAULT_PDF_CONFIG
|
|
300
|
+
};
|
|
301
|
+
|
|
302
|
+
//#endregion
|
|
303
|
+
//#region src/core/ai-extraction/config.ts
|
|
304
|
+
const CONFIG_FILE_NAME = "ai-config.json";
|
|
305
|
+
const GITIGNORE_FILE = ".gitignore";
|
|
306
|
+
async function readAIConfig(aiexDir) {
|
|
307
|
+
const configPath = path.join(aiexDir, CONFIG_FILE_NAME);
|
|
308
|
+
try {
|
|
309
|
+
const parsed = await readFile(configPath);
|
|
310
|
+
return AIConfigSchema.parse(parsed);
|
|
311
|
+
} catch {
|
|
312
|
+
return null;
|
|
313
|
+
}
|
|
314
|
+
}
|
|
315
|
+
async function writeAIConfig(aiexDir, config) {
|
|
316
|
+
const configPath = path.join(aiexDir, CONFIG_FILE_NAME);
|
|
317
|
+
await fs.mkdir(aiexDir, { recursive: true });
|
|
318
|
+
await writeFile(configPath, config, {
|
|
319
|
+
spaces: 2,
|
|
320
|
+
EOL: "\n"
|
|
321
|
+
});
|
|
322
|
+
await addToGitignore(aiexDir, CONFIG_FILE_NAME);
|
|
323
|
+
}
|
|
324
|
+
function getDefaultAIConfig() {
|
|
325
|
+
return structuredClone(DEFAULT_AI_CONFIG);
|
|
326
|
+
}
|
|
327
|
+
async function addToGitignore(aiexDir, fileName) {
|
|
328
|
+
const projectRoot = path.dirname(aiexDir);
|
|
329
|
+
const gitignorePath = path.join(projectRoot, GITIGNORE_FILE);
|
|
330
|
+
try {
|
|
331
|
+
const content = await fs.readFile(gitignorePath, "utf-8");
|
|
332
|
+
if (content.split("\n").some((line) => line.trim() === fileName || line.includes(".aiex/"))) return;
|
|
333
|
+
const newContent = content.endsWith("\n") ? `${content}${fileName}\n` : `${content}\n${fileName}\n`;
|
|
334
|
+
await fs.writeFile(gitignorePath, newContent);
|
|
335
|
+
} catch {
|
|
336
|
+
await fs.writeFile(gitignorePath, `${fileName}\n`);
|
|
337
|
+
}
|
|
338
|
+
}
|
|
339
|
+
|
|
64
340
|
//#endregion
|
|
65
341
|
//#region src/core/schema-sqlite/generator.ts
|
|
66
342
|
function generateColumnDefinition(column) {
|
|
@@ -334,6 +610,7 @@ const ForeignKeyRefSchema = z.object({
|
|
|
334
610
|
column: z.string().min(1)
|
|
335
611
|
});
|
|
336
612
|
const JsonSchemaPropertySchema = z.lazy(() => z.object({
|
|
613
|
+
description: z.string().optional(),
|
|
337
614
|
type: z.enum([
|
|
338
615
|
"string",
|
|
339
616
|
"integer",
|
|
@@ -409,225 +686,7 @@ function generateDrizzleConfig() {
|
|
|
409
686
|
}
|
|
410
687
|
|
|
411
688
|
//#endregion
|
|
412
|
-
//#region
|
|
413
|
-
var name = "aiex-cli";
|
|
414
|
-
var version = "0.0.1-beta.8";
|
|
415
|
-
var description = "JSON Schema → SQLite with AI-powered data extraction";
|
|
416
|
-
var package_default = {
|
|
417
|
-
name,
|
|
418
|
-
type: "module",
|
|
419
|
-
version,
|
|
420
|
-
description,
|
|
421
|
-
author: "OSpoon <zxin088@gmail.com>",
|
|
422
|
-
license: "MIT",
|
|
423
|
-
homepage: "https://github.com/OSpoon/aiex-cli#readme",
|
|
424
|
-
repository: {
|
|
425
|
-
"type": "git",
|
|
426
|
-
"url": "git+https://github.com/OSpoon/aiex-cli.git"
|
|
427
|
-
},
|
|
428
|
-
bugs: "https://github.com/OSpoon/aiex-cli/issues",
|
|
429
|
-
keywords: [
|
|
430
|
-
"json-schema",
|
|
431
|
-
"sqlite",
|
|
432
|
-
"drizzle",
|
|
433
|
-
"orm",
|
|
434
|
-
"ai-extraction",
|
|
435
|
-
"cli",
|
|
436
|
-
"database-migration",
|
|
437
|
-
"schema-editor",
|
|
438
|
-
"code-generation",
|
|
439
|
-
"structured-output"
|
|
440
|
-
],
|
|
441
|
-
sideEffects: false,
|
|
442
|
-
exports: {
|
|
443
|
-
".": "./dist/index.mjs",
|
|
444
|
-
"./cli": "./dist/cli.mjs",
|
|
445
|
-
"./core/schema-sqlite/migrate-helper": "./dist/core/schema-sqlite/migrate-helper.mjs",
|
|
446
|
-
"./package.json": "./package.json"
|
|
447
|
-
},
|
|
448
|
-
main: "./dist/index.mjs",
|
|
449
|
-
module: "./dist/index.mjs",
|
|
450
|
-
types: "./dist/index.d.mts",
|
|
451
|
-
bin: { "aiex": "./bin/cli.mjs" },
|
|
452
|
-
files: [
|
|
453
|
-
"bin",
|
|
454
|
-
"dist",
|
|
455
|
-
"src/core/schema-sqlite/migrate-helper.ts",
|
|
456
|
-
"src/core/schema-sqlite/migration-name.ts"
|
|
457
|
-
],
|
|
458
|
-
scripts: {
|
|
459
|
-
"build": "tsdown && pnpm --filter aiex-web build",
|
|
460
|
-
"dev": "tsdown --watch",
|
|
461
|
-
"start": "tsx src/index.ts",
|
|
462
|
-
"test": "vitest",
|
|
463
|
-
"coverage": "vitest --coverage",
|
|
464
|
-
"typecheck": "tsc",
|
|
465
|
-
"lint": "eslint .",
|
|
466
|
-
"prepublishOnly": "cp ../../README.md . && pnpm run build",
|
|
467
|
-
"postpublish": "rm -f README.md"
|
|
468
|
-
},
|
|
469
|
-
dependencies: {
|
|
470
|
-
"@ai-sdk/openai-compatible": "catalog:",
|
|
471
|
-
"@clack/prompts": "catalog:",
|
|
472
|
-
"@hono/node-server": "catalog:",
|
|
473
|
-
"ai": "catalog:",
|
|
474
|
-
"better-sqlite3": "catalog:",
|
|
475
|
-
"citty": "catalog:",
|
|
476
|
-
"cli-table3": "catalog:",
|
|
477
|
-
"conf": "catalog:",
|
|
478
|
-
"consola": "catalog:",
|
|
479
|
-
"date-fns": "catalog:",
|
|
480
|
-
"drizzle-kit": "catalog:cli",
|
|
481
|
-
"drizzle-orm": "catalog:",
|
|
482
|
-
"es-toolkit": "catalog:",
|
|
483
|
-
"esbuild": "catalog:",
|
|
484
|
-
"hono": "catalog:",
|
|
485
|
-
"picocolors": "catalog:",
|
|
486
|
-
"tsx": "catalog:cli",
|
|
487
|
-
"update-notifier": "catalog:",
|
|
488
|
-
"zod": "catalog:"
|
|
489
|
-
},
|
|
490
|
-
devDependencies: {
|
|
491
|
-
"@antfu/eslint-config": "catalog:cli",
|
|
492
|
-
"@antfu/ni": "catalog:cli",
|
|
493
|
-
"@types/better-sqlite3": "catalog:types",
|
|
494
|
-
"@types/node": "catalog:types",
|
|
495
|
-
"@types/update-notifier": "catalog:",
|
|
496
|
-
"@vitest/coverage-v8": "catalog:testing",
|
|
497
|
-
"eslint": "catalog:cli",
|
|
498
|
-
"publint": "catalog:cli",
|
|
499
|
-
"tsdown": "catalog:cli",
|
|
500
|
-
"tsnapi": "catalog:testing",
|
|
501
|
-
"typescript": "catalog:cli",
|
|
502
|
-
"vitest": "catalog:testing"
|
|
503
|
-
}
|
|
504
|
-
};
|
|
505
|
-
|
|
506
|
-
//#endregion
|
|
507
|
-
//#region src/config.ts
|
|
508
|
-
function createConfig() {
|
|
509
|
-
return new Conf({
|
|
510
|
-
cwd: process.env.CLI_CONFIG_DIR,
|
|
511
|
-
projectName: process.env.CLI_CONFIG_PROJECT_NAME || name
|
|
512
|
-
});
|
|
513
|
-
}
|
|
514
|
-
function seedConfig(config = createConfig()) {
|
|
515
|
-
if (!config.has("name")) config.set("name", name);
|
|
516
|
-
if (!config.has("version")) config.set("version", version);
|
|
517
|
-
}
|
|
518
|
-
|
|
519
|
-
//#endregion
|
|
520
|
-
//#region src/core/ai-extraction/schemas.ts
|
|
521
|
-
const ModelCapabilitiesSchema = z.object({
|
|
522
|
-
vision: z.boolean(),
|
|
523
|
-
structuredOutput: z.boolean(),
|
|
524
|
-
maxTokens: z.number().int().positive().optional(),
|
|
525
|
-
maxOutputTokens: z.number().int().positive().optional()
|
|
526
|
-
});
|
|
527
|
-
const AIModelConfigSchema = z.object({
|
|
528
|
-
name: z.string().min(1),
|
|
529
|
-
capabilities: ModelCapabilitiesSchema
|
|
530
|
-
});
|
|
531
|
-
const AIProviderConfigSchema = z.object({
|
|
532
|
-
baseURL: z.string().min(1),
|
|
533
|
-
apiKey: z.string(),
|
|
534
|
-
models: z.array(AIModelConfigSchema).min(1)
|
|
535
|
-
});
|
|
536
|
-
const PromptConfigSchema = z.object({
|
|
537
|
-
systemTemplate: z.string().min(1),
|
|
538
|
-
userTemplate: z.string().min(1)
|
|
539
|
-
});
|
|
540
|
-
const ExtractionConfigSchema = z.object({ outputDir: z.string().min(1) });
|
|
541
|
-
const AIConfigSchema = z.object({
|
|
542
|
-
provider: AIProviderConfigSchema,
|
|
543
|
-
prompt: PromptConfigSchema,
|
|
544
|
-
extraction: ExtractionConfigSchema
|
|
545
|
-
});
|
|
546
|
-
|
|
547
|
-
//#endregion
|
|
548
|
-
//#region src/core/ai-extraction/types.ts
|
|
549
|
-
const PLACEHOLDER_SCHEMA = "{schema}";
|
|
550
|
-
const PLACEHOLDER_TEXT = "{text}";
|
|
551
|
-
const DEFAULT_MODELS = [{
|
|
552
|
-
name: "qwen-plus",
|
|
553
|
-
capabilities: {
|
|
554
|
-
vision: false,
|
|
555
|
-
structuredOutput: true
|
|
556
|
-
}
|
|
557
|
-
}, {
|
|
558
|
-
name: "qwen-vl-plus",
|
|
559
|
-
capabilities: {
|
|
560
|
-
vision: true,
|
|
561
|
-
structuredOutput: true
|
|
562
|
-
}
|
|
563
|
-
}];
|
|
564
|
-
const DEFAULT_PROVIDER_CONFIG = {
|
|
565
|
-
baseURL: "https://dashscope.aliyuncs.com/compatible-mode/v1",
|
|
566
|
-
apiKey: "",
|
|
567
|
-
models: [...DEFAULT_MODELS]
|
|
568
|
-
};
|
|
569
|
-
const DEFAULT_PROMPT_CONFIG = {
|
|
570
|
-
systemTemplate: `You are a professional data extraction assistant. Your task is to extract structured data from text based on the data structure definition provided below.
|
|
571
|
-
|
|
572
|
-
{schema}
|
|
573
|
-
|
|
574
|
-
Extraction requirements:
|
|
575
|
-
1. Extract strictly according to the field names and types defined in the structure
|
|
576
|
-
2. If the text lacks information for a field, set that field to null
|
|
577
|
-
3. Do not add fields that do not exist in the structure definition
|
|
578
|
-
4. Maintain data accuracy and completeness`,
|
|
579
|
-
userTemplate: `Please extract data from the following text:
|
|
580
|
-
{text}`
|
|
581
|
-
};
|
|
582
|
-
const DEFAULT_EXTRACTION_CONFIG = { outputDir: ".aiex/extracted" };
|
|
583
|
-
const DEFAULT_AI_CONFIG = {
|
|
584
|
-
provider: DEFAULT_PROVIDER_CONFIG,
|
|
585
|
-
prompt: DEFAULT_PROMPT_CONFIG,
|
|
586
|
-
extraction: DEFAULT_EXTRACTION_CONFIG
|
|
587
|
-
};
|
|
588
|
-
|
|
589
|
-
//#endregion
|
|
590
|
-
//#region src/core/ai-extraction/config.ts
|
|
591
|
-
const CONFIG_FILE_NAME = "ai-config.json";
|
|
592
|
-
const GITIGNORE_FILE = ".gitignore";
|
|
593
|
-
async function readAIConfig(aiexDir) {
|
|
594
|
-
const configPath = path.join(aiexDir, CONFIG_FILE_NAME);
|
|
595
|
-
try {
|
|
596
|
-
const content = await fs.readFile(configPath, "utf-8");
|
|
597
|
-
const parsed = JSON.parse(content);
|
|
598
|
-
return AIConfigSchema.parse(parsed);
|
|
599
|
-
} catch {
|
|
600
|
-
return null;
|
|
601
|
-
}
|
|
602
|
-
}
|
|
603
|
-
async function writeAIConfig(aiexDir, config) {
|
|
604
|
-
const configPath = path.join(aiexDir, CONFIG_FILE_NAME);
|
|
605
|
-
await fs.mkdir(aiexDir, { recursive: true });
|
|
606
|
-
await fs.writeFile(configPath, `${JSON.stringify(config, null, 2)}\n`);
|
|
607
|
-
await addToGitignore(aiexDir, CONFIG_FILE_NAME);
|
|
608
|
-
}
|
|
609
|
-
function getDefaultAIConfig() {
|
|
610
|
-
return { ...DEFAULT_AI_CONFIG };
|
|
611
|
-
}
|
|
612
|
-
function maskApiKey(apiKey) {
|
|
613
|
-
if (apiKey.length <= 4) return "****";
|
|
614
|
-
return `sk-***${apiKey.slice(-4)}`;
|
|
615
|
-
}
|
|
616
|
-
async function addToGitignore(aiexDir, fileName) {
|
|
617
|
-
const projectRoot = path.dirname(aiexDir);
|
|
618
|
-
const gitignorePath = path.join(projectRoot, GITIGNORE_FILE);
|
|
619
|
-
try {
|
|
620
|
-
const content = await fs.readFile(gitignorePath, "utf-8");
|
|
621
|
-
if (content.split("\n").some((line) => line.trim() === fileName || line.includes(".aiex/"))) return;
|
|
622
|
-
const newContent = content.endsWith("\n") ? `${content}${fileName}\n` : `${content}\n${fileName}\n`;
|
|
623
|
-
await fs.writeFile(gitignorePath, newContent);
|
|
624
|
-
} catch {
|
|
625
|
-
await fs.writeFile(gitignorePath, `${fileName}\n`);
|
|
626
|
-
}
|
|
627
|
-
}
|
|
628
|
-
|
|
629
|
-
//#endregion
|
|
630
|
-
//#region src/doctor.ts
|
|
689
|
+
//#region src/core/doctor-collector.ts
|
|
631
690
|
const V1_SUFFIX_RE = /\/v1\/?$/;
|
|
632
691
|
async function checkConnection(baseURL) {
|
|
633
692
|
try {
|
|
@@ -713,4 +772,4 @@ async function collectDoctorDiagnostics(options = {}) {
|
|
|
713
772
|
}
|
|
714
773
|
|
|
715
774
|
//#endregion
|
|
716
|
-
export { doctorDiagnosticsTableRows as C, buildDoctorDiagnostics as S,
|
|
775
|
+
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 };
|