aiex-cli 0.0.3-beta.8 → 0.0.4-beta.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/dist/cli.mjs +346 -251
- package/dist/{doctor-collector-DzIv90_Y.mjs → doctor-collector-xRnW5Rj3.mjs} +541 -8
- package/dist/index.mjs +1 -1
- package/dist/web/assets/AISettings-BmCr8Kj4.js +272 -0
- package/dist/web/assets/DataBrowser-IlgTMGi0.js +97 -0
- package/dist/web/assets/ExtractionViewer-0F4C26V5.js +1 -0
- package/dist/web/assets/JsonSchemaEditor-Dyl391lX.js +571 -0
- package/dist/web/assets/{api-client-BsgtGnzl.js → api-client-b4ZBXpNH.js} +1 -1
- package/dist/web/assets/{cssMode-CPThwItX.js → cssMode-BM5FOYIl.js} +1 -1
- package/dist/web/assets/dialog-CnZ7jH1l.js +109 -0
- package/dist/web/assets/dist-CElVIpns.js +1 -0
- package/dist/web/assets/{editor.main-BnOkwRFv.js → editor.main-C2Q97Dkk.js} +2 -2
- package/dist/web/assets/{freemarker2-DWDTYVJR.js → freemarker2-BqyJTCTn.js} +1 -1
- package/dist/web/assets/{handlebars-D4DzjGQ7.js → handlebars-DxRJTefg.js} +1 -1
- package/dist/web/assets/{html-DnzhKSoD.js → html-gyvgrapw.js} +1 -1
- package/dist/web/assets/{htmlMode-CR7UKfEH.js → htmlMode-CNjCRwdY.js} +1 -1
- package/dist/web/assets/{index-CPjJbU4i.js → index-CGZLSwt2.js} +38 -38
- package/dist/web/assets/{javascript-D2srszZ8.js → javascript-BK6ufvq6.js} +1 -1
- package/dist/web/assets/{jsonMode-B4jaPYEr.js → jsonMode-m2trGjkO.js} +1 -1
- package/dist/web/assets/{liquid-CIT2Wl_l.js → liquid-BtyuYqQQ.js} +1 -1
- package/dist/web/assets/{mdx-CWLaEOFy.js → mdx-C8K4EvCQ.js} +1 -1
- package/dist/web/assets/{monaco.contribution-DDv5ldfS.js → monaco.contribution-BTr-G8hO.js} +2 -2
- package/dist/web/assets/object-utils-C6FkG7fw.js +1 -0
- package/dist/web/assets/{python-6CGfpCNq.js → python-8dyH1nS_.js} +1 -1
- package/dist/web/assets/{razor-DEMMh3TD.js → razor-DtWMI74k.js} +1 -1
- package/dist/web/assets/textarea-DMpqBhjw.js +522 -0
- package/dist/web/assets/{tsMode-Cm1NtjPs.js → tsMode-Dv8YG-YK.js} +1 -1
- package/dist/web/assets/{typescript-BM9aPEFg.js → typescript-DbClKYS3.js} +1 -1
- package/dist/web/assets/vue-i18n-Du42D0vb.js +931 -0
- package/dist/web/assets/{xml-CoSbvcg5.js → xml-Bb59gjP6.js} +1 -1
- package/dist/web/assets/{yaml-56GOgy8k.js → yaml-DVMb_IfV.js} +1 -1
- package/dist/web/index.html +8 -8
- package/dist/zh-CN-DAlmQ2hb.mjs +484 -0
- package/package.json +3 -1
- package/dist/web/assets/AISettings-D6EpB8tt.js +0 -272
- package/dist/web/assets/DataBrowser-N77fBaoa.js +0 -97
- package/dist/web/assets/ExtractionViewer-BSZycwgL.js +0 -1
- package/dist/web/assets/JsonSchemaEditor-DfHs5bc0.js +0 -571
- package/dist/web/assets/button-Cdgr9Igy.js +0 -927
- package/dist/web/assets/dialog-CUkPLPNP.js +0 -109
- package/dist/web/assets/dist-9yHVMqQ0.js +0 -1
- package/dist/web/assets/object-utils-I4gWdSnS.js +0 -1
- package/dist/web/assets/runtime-dom.esm-bundler-ei_N7Xjw.js +0 -1
- package/dist/web/assets/textarea-DEQMRfG8.js +0 -522
- /package/dist/{completions-C3rmTwXZ.mjs → completions-Bh0DOngr.mjs} +0 -0
- /package/dist/web/assets/{abap-Bgec7Keq.js → abap-DiwvWnMr.js} +0 -0
- /package/dist/web/assets/{apex-VBlPwEoQ.js → apex-CmtZjKlf.js} +0 -0
- /package/dist/web/assets/{azcli-DKqrEFBx.js → azcli-DL2My_i-.js} +0 -0
- /package/dist/web/assets/{bat-DdgQWy_0.js → bat-B-nC98wG.js} +0 -0
- /package/dist/web/assets/{bicep-CRMM43EB.js → bicep-Ju5MwOgh.js} +0 -0
- /package/dist/web/assets/{cameligo-UatALtML.js → cameligo-8Eu1TyBr.js} +0 -0
- /package/dist/web/assets/{clojure-D8JU08RA.js → clojure-u-RpMkH3.js} +0 -0
- /package/dist/web/assets/{coffee-C56wu358.js → coffee-CdA7bbTe.js} +0 -0
- /package/dist/web/assets/{cpp-CyZLvhJG.js → cpp-CzNFP8ks.js} +0 -0
- /package/dist/web/assets/{csharp-BJl3ixva.js → csharp-j1LThmcE.js} +0 -0
- /package/dist/web/assets/{csp-CxEKxmO-.js → csp-CLRC61y6.js} +0 -0
- /package/dist/web/assets/{css-B0t_muXd.js → css-r6rC_7P2.js} +0 -0
- /package/dist/web/assets/{cypher-D1hqiMFD.js → cypher-CW08XVUh.js} +0 -0
- /package/dist/web/assets/{dart-Bz550Pyv.js → dart-Cs9aL5T_.js} +0 -0
- /package/dist/web/assets/{dockerfile-CIXgVAuA.js → dockerfile-BWM0M184.js} +0 -0
- /package/dist/web/assets/{ecl-D9qbvZoA.js → ecl-MJJuer5P.js} +0 -0
- /package/dist/web/assets/{editor.api-C8BHpRhn.js → editor.api-nsOUOZde.js} +0 -0
- /package/dist/web/assets/{elixir-b2M38fAy.js → elixir-D2AIuXqn.js} +0 -0
- /package/dist/web/assets/{flow9-Dq1UYMkt.js → flow9-B2H24giC.js} +0 -0
- /package/dist/web/assets/{fsharp-BaeLhgfq.js → fsharp-CFNadkg7.js} +0 -0
- /package/dist/web/assets/{go-Bd-NFKIC.js → go-dSur1iB2.js} +0 -0
- /package/dist/web/assets/{graphql-DZVerJfy.js → graphql-qyhAo11d.js} +0 -0
- /package/dist/web/assets/{hcl-CAVzrZfH.js → hcl-DFzjMyzm.js} +0 -0
- /package/dist/web/assets/{ini-CyXdX58t.js → ini-TdzA8TIl.js} +0 -0
- /package/dist/web/assets/{java-B5pNgvhy.js → java-CSGA9pkE.js} +0 -0
- /package/dist/web/assets/{julia-XRhmV3AN.js → julia-9izz5OsY.js} +0 -0
- /package/dist/web/assets/{kotlin-DOd3J5vr.js → kotlin-DuPK7AtF.js} +0 -0
- /package/dist/web/assets/{less-veZSnyw6.js → less-B8d93iCg.js} +0 -0
- /package/dist/web/assets/{lexon-QWGkuK0H.js → lexon-DWtEIyu7.js} +0 -0
- /package/dist/web/assets/{lua-CYGpjuO5.js → lua-Ciq0OGgt.js} +0 -0
- /package/dist/web/assets/{m3-yNnrZkdc.js → m3-Cki6JWj_.js} +0 -0
- /package/dist/web/assets/{markdown-BCSWEPSX.js → markdown-Cu47xwU0.js} +0 -0
- /package/dist/web/assets/{mips-OpYmcC30.js → mips-BM8ui995.js} +0 -0
- /package/dist/web/assets/{msdax-2oxoTO9Z.js → msdax-DqLio0_c.js} +0 -0
- /package/dist/web/assets/{mysql-5KlC-K_9.js → mysql-v1wbjJOq.js} +0 -0
- /package/dist/web/assets/{objective-c-CcDCgtLx.js → objective-c-CQl3PGSB.js} +0 -0
- /package/dist/web/assets/{pascal-BZGsbaEV.js → pascal-D4iW0ZtD.js} +0 -0
- /package/dist/web/assets/{pascaligo-DtD5qU3G.js → pascaligo-BdC9CZdj.js} +0 -0
- /package/dist/web/assets/{perl-C1jNNS3E.js → perl-BL10m4XD.js} +0 -0
- /package/dist/web/assets/{pgsql-CT0fhiZa.js → pgsql-Be_oqVo3.js} +0 -0
- /package/dist/web/assets/{php-D6DrXoPM.js → php-BtvXSFRI.js} +0 -0
- /package/dist/web/assets/{pla-b3-HN2pF.js → pla-B2vUy15C.js} +0 -0
- /package/dist/web/assets/{postiats-Bin2ApVS.js → postiats-CbmTTfXr.js} +0 -0
- /package/dist/web/assets/{powerquery-7ASnn-ZG.js → powerquery-DszLhJGx.js} +0 -0
- /package/dist/web/assets/{powershell-t4p7sU1H.js → powershell-B0dYktF6.js} +0 -0
- /package/dist/web/assets/{preload-helper-Dd-HcVz_.js → preload-helper-DWTEM3RW.js} +0 -0
- /package/dist/web/assets/{protobuf-BUGeWa_j.js → protobuf-CZvaj1VX.js} +0 -0
- /package/dist/web/assets/{pug-BuKcgC9s.js → pug-CPDx1B3S.js} +0 -0
- /package/dist/web/assets/{qsharp-DxLLX8mo.js → qsharp-CAxMZVjw.js} +0 -0
- /package/dist/web/assets/{r-DMlFgn7A.js → r-8DbbFX2l.js} +0 -0
- /package/dist/web/assets/{redis-cXItkC5u.js → redis-DRWj9MtJ.js} +0 -0
- /package/dist/web/assets/{redshift-BZVbW7HE.js → redshift-C6cElE_5.js} +0 -0
- /package/dist/web/assets/{restructuredtext-BzjxwS8h.js → restructuredtext-W9pS9n3m.js} +0 -0
- /package/dist/web/assets/{ruby-C5nyLV4l.js → ruby-BKnzWnk-.js} +0 -0
- /package/dist/web/assets/{rust-BcmMsHdf.js → rust-YPCclWwe.js} +0 -0
- /package/dist/web/assets/{sb-Dnb1iy6B.js → sb-BgM4DTFb.js} +0 -0
- /package/dist/web/assets/{scala-anMIFYpA.js → scala-fz1OPLMl.js} +0 -0
- /package/dist/web/assets/{scheme-BItQTe08.js → scheme-8Uz1RIbu.js} +0 -0
- /package/dist/web/assets/{scss-BOv51BJ5.js → scss-Djo3IYXr.js} +0 -0
- /package/dist/web/assets/{shell-BsRYRTNN.js → shell-CINF5Tx_.js} +0 -0
- /package/dist/web/assets/{solidity-BtuLgGDx.js → solidity-GgiNEuUm.js} +0 -0
- /package/dist/web/assets/{sophia-B0Vkc5MF.js → sophia-Culj97P9.js} +0 -0
- /package/dist/web/assets/{sparql-B7lvkZQM.js → sparql-C2ZlpxOY.js} +0 -0
- /package/dist/web/assets/{sql-DvP5MpA3.js → sql-BEf5Pg7Y.js} +0 -0
- /package/dist/web/assets/{st-GVUeyB3U.js → st-CT6UUoeH.js} +0 -0
- /package/dist/web/assets/{swift-DSPIoCjm.js → swift-B5g0xTG3.js} +0 -0
- /package/dist/web/assets/{systemverilog-Icj2-k23.js → systemverilog-CEgQz9DR.js} +0 -0
- /package/dist/web/assets/{tcl-Cd8KQcm-.js → tcl-D0qL2L0I.js} +0 -0
- /package/dist/web/assets/{twig-CBHmt8z3.js → twig-BFUAVf1E.js} +0 -0
- /package/dist/web/assets/{typespec-Ckc037mq.js → typespec-CjVVcNKm.js} +0 -0
- /package/dist/web/assets/{vb-B97GW9Wb.js → vb-CZJr-DQz.js} +0 -0
- /package/dist/web/assets/{wgsl-DIKmb3YH.js → wgsl-ivoXUo2e.js} +0 -0
package/dist/cli.mjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { C as
|
|
1
|
+
import { A as formatDoctorDiagnosticsJson, C as seedConfig, D as version, E as package_default, S as createConfig, T as name, _ as DEFAULT_MINERU_CONFIG, a as parseJsonSchema, b as PLACEHOLDER_TEXT, c as recognizeImageText, d as t, f as getDefaultAIConfig, g as DEFAULT_MARKITDOWN_CONFIG, h as DEFAULT_MARKER_CONFIG, i as JsonSchemaDefinitionSchema, k as doctorDiagnosticsTableRows, l as shouldUseImageOcrFallback, m as writeAIConfig, n as createMigrationConfig, o as toSnakeCase, p as readAIConfig, s as generateDrizzleSchema, t as collectDoctorDiagnostics, u as initI18n, v as DEFAULT_PROMPT_CONFIG, w as description, x as AIConfigSchema, y as PLACEHOLDER_SCHEMA } from "./doctor-collector-xRnW5Rj3.mjs";
|
|
2
2
|
import { createRequire } from "node:module";
|
|
3
3
|
import fs from "node:fs/promises";
|
|
4
4
|
import os from "node:os";
|
|
@@ -156,11 +156,11 @@ function generateCompletionScript(name$1, shell) {
|
|
|
156
156
|
const completionCommand = defineCommand({
|
|
157
157
|
meta: {
|
|
158
158
|
name: "completion",
|
|
159
|
-
description: "
|
|
159
|
+
description: t("command.completion.description")
|
|
160
160
|
},
|
|
161
161
|
args: { shell: {
|
|
162
162
|
type: "positional",
|
|
163
|
-
description: "
|
|
163
|
+
description: t("command.completion.args.shell"),
|
|
164
164
|
required: true
|
|
165
165
|
} },
|
|
166
166
|
async run({ args }) {
|
|
@@ -169,7 +169,7 @@ const completionCommand = defineCommand({
|
|
|
169
169
|
try {
|
|
170
170
|
process.stdout.write(generateCompletionScript(name$1, shell));
|
|
171
171
|
} catch (error) {
|
|
172
|
-
process.stderr.write(
|
|
172
|
+
process.stderr.write(`${t("command.completion.error", { error: error instanceof Error ? error.message : String(error) })}\n`);
|
|
173
173
|
process.exit(1);
|
|
174
174
|
}
|
|
175
175
|
}
|
|
@@ -180,11 +180,11 @@ const completionCommand = defineCommand({
|
|
|
180
180
|
const doctorCommand = defineCommand({
|
|
181
181
|
meta: {
|
|
182
182
|
name: "doctor",
|
|
183
|
-
description: "
|
|
183
|
+
description: t("command.doctor.description")
|
|
184
184
|
},
|
|
185
185
|
args: { json: {
|
|
186
186
|
type: "boolean",
|
|
187
|
-
description: "
|
|
187
|
+
description: t("command.doctor.args.json")
|
|
188
188
|
} },
|
|
189
189
|
async run({ args }) {
|
|
190
190
|
try {
|
|
@@ -194,15 +194,15 @@ const doctorCommand = defineCommand({
|
|
|
194
194
|
return;
|
|
195
195
|
}
|
|
196
196
|
consola.info(`${diagnostics.cli.name} ${diagnostics.cli.version}`);
|
|
197
|
-
const
|
|
198
|
-
head: ["
|
|
197
|
+
const table = new CliTable3({
|
|
198
|
+
head: [t("command.doctor.headers.0"), t("command.doctor.headers.1")],
|
|
199
199
|
colAligns: ["right", "left"],
|
|
200
200
|
style: { compact: true }
|
|
201
201
|
});
|
|
202
|
-
|
|
203
|
-
process.stdout.write(`${
|
|
202
|
+
table.push(...doctorDiagnosticsTableRows(diagnostics));
|
|
203
|
+
process.stdout.write(`${table.toString()}\n`);
|
|
204
204
|
} catch (err) {
|
|
205
|
-
consola.error(
|
|
205
|
+
consola.error(t("command.doctor.diagnosticsFailed", { error: err }));
|
|
206
206
|
}
|
|
207
207
|
}
|
|
208
208
|
});
|
|
@@ -211,7 +211,7 @@ const doctorCommand = defineCommand({
|
|
|
211
211
|
//#region src/commands/utils.ts
|
|
212
212
|
function failCommand(message) {
|
|
213
213
|
if (message) consola.error(message);
|
|
214
|
-
outro("
|
|
214
|
+
outro(t("common.failed"));
|
|
215
215
|
process.exitCode = 1;
|
|
216
216
|
}
|
|
217
217
|
|
|
@@ -12875,15 +12875,18 @@ function filterCompatible(models, inputTokens, outputTokens) {
|
|
|
12875
12875
|
}
|
|
12876
12876
|
function selectModel(input) {
|
|
12877
12877
|
const { models, isImage, fileName, inputTokens, outputTokens } = input;
|
|
12878
|
-
if (models.length === 0) throw new Error("
|
|
12878
|
+
if (models.length === 0) throw new Error(t("errors.ai.noModels"));
|
|
12879
12879
|
let candidates = filterCompatible(models, inputTokens, outputTokens);
|
|
12880
12880
|
if (candidates.length === 0) candidates = models;
|
|
12881
12881
|
if (isImage) {
|
|
12882
12882
|
const visionModel = candidates.find((m) => m.capabilities.vision);
|
|
12883
12883
|
if (!visionModel) {
|
|
12884
12884
|
const hint = fileName ? ` (${fileName})` : "";
|
|
12885
|
-
const msg = inputTokens ?
|
|
12886
|
-
|
|
12885
|
+
const msg = inputTokens ? t("errors.ai.noVisionModelContext", {
|
|
12886
|
+
tokens: inputTokens,
|
|
12887
|
+
hint
|
|
12888
|
+
}) : t("errors.ai.noVisionModel", { hint });
|
|
12889
|
+
throw new Error(msg + t("errors.ai.addSuitableModel"));
|
|
12887
12890
|
}
|
|
12888
12891
|
return {
|
|
12889
12892
|
name: visionModel.name,
|
|
@@ -13140,7 +13143,7 @@ async function extractStructuredData(input) {
|
|
|
13140
13143
|
const { config, schema, text: text$1, aiexDir, file, modelOverride } = input;
|
|
13141
13144
|
if (!config.provider.apiKey) return {
|
|
13142
13145
|
success: false,
|
|
13143
|
-
error: "
|
|
13146
|
+
error: t("errors.ai.apiKeyMissing")
|
|
13144
13147
|
};
|
|
13145
13148
|
const useFileContent = !!file;
|
|
13146
13149
|
const isImageFile = useFileContent && detectMimeType(file).startsWith("image/");
|
|
@@ -13345,7 +13348,7 @@ function insertExtractedData(db, schema, data) {
|
|
|
13345
13348
|
const [propName] = propEntry;
|
|
13346
13349
|
const nestedValue = data[propName];
|
|
13347
13350
|
if (nestedValue === null || nestedValue === void 0) continue;
|
|
13348
|
-
const nestedTable = parseResult.tables.find((t) => t.name === revRel.toTable);
|
|
13351
|
+
const nestedTable = parseResult.tables.find((t$1) => t$1.name === revRel.toTable);
|
|
13349
13352
|
if (!nestedTable) continue;
|
|
13350
13353
|
if (revRel.type === "has-one") {
|
|
13351
13354
|
const rowId = insertTableRow({
|
|
@@ -13440,7 +13443,7 @@ async function createExtractionAuditRecord(aiexDir, input) {
|
|
|
13440
13443
|
}
|
|
13441
13444
|
async function updateExtractionAuditRecord(aiexDir, id, patch) {
|
|
13442
13445
|
const current = await readExtractionAuditRecord(aiexDir, id);
|
|
13443
|
-
if (!current) throw new Error(
|
|
13446
|
+
if (!current) throw new Error(t("errors.extractionAudit.recordNotFound", { id }));
|
|
13444
13447
|
const record = {
|
|
13445
13448
|
...current,
|
|
13446
13449
|
...patch,
|
|
@@ -13473,7 +13476,7 @@ async function markStaleIfNeeded(aiexDir, record) {
|
|
|
13473
13476
|
const staleRecord = {
|
|
13474
13477
|
...record,
|
|
13475
13478
|
status: "stale",
|
|
13476
|
-
error: record.error ?? "
|
|
13479
|
+
error: record.error ?? t("errors.extractionAudit.interrupted"),
|
|
13477
13480
|
updatedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
13478
13481
|
};
|
|
13479
13482
|
await writeFile(auditPath(aiexDir, staleRecord.id), staleRecord, {
|
|
@@ -13543,7 +13546,7 @@ async function findSucceededAuditByHash(aiexDir, schemaName, fileHash) {
|
|
|
13543
13546
|
const MAX_UPLOAD_SIZE = 30 * 1024 * 1024;
|
|
13544
13547
|
const MAX_UPLOAD_SIZE_TEXT = "30MB";
|
|
13545
13548
|
const SUPPORTED_FILE_TYPES_TEXT = "images, PDF, text, markdown, CSV, JSON, HTML, XML, YAML";
|
|
13546
|
-
const MISSING_UPLOAD_FILE_TEXT = "
|
|
13549
|
+
const MISSING_UPLOAD_FILE_TEXT = t("errors.file.missingUpload");
|
|
13547
13550
|
const SUPPORTED_MIME_TYPES = new Set([
|
|
13548
13551
|
"image/png",
|
|
13549
13552
|
"image/jpeg",
|
|
@@ -13588,7 +13591,10 @@ function isAllowedMimeType(mimeType) {
|
|
|
13588
13591
|
return SUPPORTED_MIME_TYPES.has(mimeType);
|
|
13589
13592
|
}
|
|
13590
13593
|
function unsupportedFileTypeMessage(mimeType) {
|
|
13591
|
-
return
|
|
13594
|
+
return t("errors.file.unsupportedType", {
|
|
13595
|
+
type: mimeType,
|
|
13596
|
+
supported: SUPPORTED_FILE_TYPES_TEXT
|
|
13597
|
+
});
|
|
13592
13598
|
}
|
|
13593
13599
|
function isMissingUploadFileError(error) {
|
|
13594
13600
|
return !!error && typeof error === "object" && error.code === "ENOENT";
|
|
@@ -13600,8 +13606,12 @@ var FileValidationError = class extends Error {
|
|
|
13600
13606
|
}
|
|
13601
13607
|
};
|
|
13602
13608
|
function validateFileUpload(file) {
|
|
13603
|
-
if (file.size === 0) throw new FileValidationError("
|
|
13604
|
-
if (file.size > MAX_UPLOAD_SIZE) throw new FileValidationError(
|
|
13609
|
+
if (file.size === 0) throw new FileValidationError(t("errors.file.empty"));
|
|
13610
|
+
if (file.size > MAX_UPLOAD_SIZE) throw new FileValidationError(t("errors.file.sizeExceeded", {
|
|
13611
|
+
size: bytesToMB(file.size).toFixed(1),
|
|
13612
|
+
limit: MAX_UPLOAD_SIZE_TEXT,
|
|
13613
|
+
file: file.name
|
|
13614
|
+
}));
|
|
13605
13615
|
if (!isAllowedMimeType(file.type)) throw new FileValidationError(unsupportedFileTypeMessage(file.type));
|
|
13606
13616
|
}
|
|
13607
13617
|
|
|
@@ -13756,7 +13766,7 @@ function firstDataSourceId(database) {
|
|
|
13756
13766
|
}
|
|
13757
13767
|
async function resolveNotionDataSource(notion, inputId) {
|
|
13758
13768
|
const id = parseNotionDatabaseId(inputId);
|
|
13759
|
-
if (!id) throw new Error("
|
|
13769
|
+
if (!id) throw new Error(t("errors.notion.idRequired"));
|
|
13760
13770
|
try {
|
|
13761
13771
|
const dataSource$1 = await notion.dataSources.retrieve({ data_source_id: id });
|
|
13762
13772
|
if (isDataSourceResponse(dataSource$1)) return {
|
|
@@ -13768,9 +13778,9 @@ async function resolveNotionDataSource(notion, inputId) {
|
|
|
13768
13778
|
} catch {}
|
|
13769
13779
|
const database = await notion.databases.retrieve({ database_id: id });
|
|
13770
13780
|
const dataSourceId = firstDataSourceId(database);
|
|
13771
|
-
if (!dataSourceId) throw new Error("
|
|
13781
|
+
if (!dataSourceId) throw new Error(t("errors.notion.noDataSource"));
|
|
13772
13782
|
const dataSource = await notion.dataSources.retrieve({ data_source_id: dataSourceId });
|
|
13773
|
-
if (!isDataSourceResponse(dataSource)) throw new Error("
|
|
13783
|
+
if (!isDataSourceResponse(dataSource)) throw new Error(t("errors.notion.noProperties"));
|
|
13774
13784
|
return {
|
|
13775
13785
|
databaseId: database.id,
|
|
13776
13786
|
dataSourceId: dataSource.id,
|
|
@@ -13779,9 +13789,9 @@ async function resolveNotionDataSource(notion, inputId) {
|
|
|
13779
13789
|
};
|
|
13780
13790
|
}
|
|
13781
13791
|
async function inspectNotionDatabase(input) {
|
|
13782
|
-
if (!input.token.trim()) throw new Error("
|
|
13792
|
+
if (!input.token.trim()) throw new Error(t("errors.notion.tokenRequired"));
|
|
13783
13793
|
const id = parseNotionDatabaseId(input.databaseId);
|
|
13784
|
-
if (!id) throw new Error("
|
|
13794
|
+
if (!id) throw new Error(t("errors.notion.idRequired"));
|
|
13785
13795
|
const resolved = await resolveNotionDataSource(new Client({ auth: input.token }), id);
|
|
13786
13796
|
const databaseProperties = resolved.properties;
|
|
13787
13797
|
const titleProperty = findTitleProperty(databaseProperties) ?? void 0;
|
|
@@ -13797,8 +13807,8 @@ async function inspectNotionDatabase(input) {
|
|
|
13797
13807
|
};
|
|
13798
13808
|
}
|
|
13799
13809
|
function validateNotionConfig(config) {
|
|
13800
|
-
if (!config?.enabled) return "
|
|
13801
|
-
if (!config.token.trim()) return "
|
|
13810
|
+
if (!config?.enabled) return t("errors.notion.notEnabled");
|
|
13811
|
+
if (!config.token.trim()) return t("errors.notion.tokenRequired");
|
|
13802
13812
|
return null;
|
|
13803
13813
|
}
|
|
13804
13814
|
async function writeNotionPage(config, schemaName, data) {
|
|
@@ -13806,8 +13816,8 @@ async function writeNotionPage(config, schemaName, data) {
|
|
|
13806
13816
|
if (configError) throw new Error(configError);
|
|
13807
13817
|
const notionConfig = config;
|
|
13808
13818
|
const schemaConfig = notionConfig.schemas[schemaName];
|
|
13809
|
-
if (!schemaConfig) throw new Error(
|
|
13810
|
-
if (!schemaConfig.databaseId.trim()) throw new Error(
|
|
13819
|
+
if (!schemaConfig) throw new Error(t("errors.notion.noSchemaConfig", { name: schemaName }));
|
|
13820
|
+
if (!schemaConfig.databaseId.trim()) throw new Error(t("errors.notion.noDatabaseId", { name: schemaName }));
|
|
13811
13821
|
const notion = new Client({ auth: notionConfig.token });
|
|
13812
13822
|
const resolved = await resolveNotionDataSource(notion, schemaConfig.databaseId);
|
|
13813
13823
|
const databaseProperties = resolved.properties;
|
|
@@ -13825,7 +13835,7 @@ async function writeNotionPage(config, schemaName, data) {
|
|
|
13825
13835
|
}
|
|
13826
13836
|
const titleProperty = findTitleProperty(databaseProperties, schemaConfig.titleProperty);
|
|
13827
13837
|
if (titleProperty && !properties[titleProperty]) properties[titleProperty] = buildPropertyValue("title", schemaName);
|
|
13828
|
-
if (Object.keys(properties).length === 0) throw new Error("
|
|
13838
|
+
if (Object.keys(properties).length === 0) throw new Error(t("errors.notion.noFieldsMatched"));
|
|
13829
13839
|
return {
|
|
13830
13840
|
pageId: (await notion.pages.create({
|
|
13831
13841
|
parent: resolved.parent,
|
|
@@ -13962,7 +13972,10 @@ var FallbackPdfConverter = class {
|
|
|
13962
13972
|
try {
|
|
13963
13973
|
return await this.primary.convert(input, filePath);
|
|
13964
13974
|
} catch (err) {
|
|
13965
|
-
consola.warn(
|
|
13975
|
+
consola.warn(t("command.extract.file.errorProcessing", {
|
|
13976
|
+
name: this.primary.name,
|
|
13977
|
+
error: err instanceof Error ? err.message : String(err)
|
|
13978
|
+
}));
|
|
13966
13979
|
consola.info(`Falling back to ${this.fallback.name}`);
|
|
13967
13980
|
const result = await this.fallback.convert(input, filePath);
|
|
13968
13981
|
return {
|
|
@@ -13994,14 +14007,14 @@ function createPdfConverter(config) {
|
|
|
13994
14007
|
return withFallback(new ExternalCommandPdfConverter("marker", markerConfig), markerConfig);
|
|
13995
14008
|
}
|
|
13996
14009
|
if (config.converter === "external") {
|
|
13997
|
-
if (!config.external) throw new Error("
|
|
14010
|
+
if (!config.external) throw new Error(t("errors.pdf.externalNotConfigured"));
|
|
13998
14011
|
return withFallback(new ExternalCommandPdfConverter("external", config.external), config.external);
|
|
13999
14012
|
}
|
|
14000
14013
|
}
|
|
14001
14014
|
const key = typeof config === "string" ? config : "unpdf";
|
|
14002
14015
|
let instance = registry.get(key);
|
|
14003
14016
|
if (!instance) {
|
|
14004
|
-
if (key !== "unpdf") throw new Error(
|
|
14017
|
+
if (key !== "unpdf") throw new Error(t("errors.pdf.converterRequiresConfig", { name: key }));
|
|
14005
14018
|
instance = new UnpdfConverter();
|
|
14006
14019
|
registry.set(key, instance);
|
|
14007
14020
|
}
|
|
@@ -14050,7 +14063,7 @@ const PDF_EXT_RE = /\.pdf$/i;
|
|
|
14050
14063
|
const JSON_EXT_RE$1 = /\.json$/;
|
|
14051
14064
|
const SUPPORTED_FILE_PATTERN = `*.{${[...SUPPORTED_EXTENSIONS$1].join(",")}}`;
|
|
14052
14065
|
async function syncResultToNotion(aiConfig, schemaName, data) {
|
|
14053
|
-
if (!data || typeof data !== "object" || Array.isArray(data)) throw new Error("
|
|
14066
|
+
if (!data || typeof data !== "object" || Array.isArray(data)) throw new Error(t("errors.ai.extractionNotObject"));
|
|
14054
14067
|
const page = await writeNotionPage(aiConfig.notion, schemaName, data);
|
|
14055
14068
|
return [{
|
|
14056
14069
|
databaseId: page.databaseId,
|
|
@@ -14064,23 +14077,29 @@ async function ensureDatabaseReady(dbPath, schema) {
|
|
|
14064
14077
|
try {
|
|
14065
14078
|
await fs.access(dbPath);
|
|
14066
14079
|
} catch {
|
|
14067
|
-
return
|
|
14080
|
+
return t("errors.db.notFound", {
|
|
14081
|
+
path: pc.cyan(".aiex/database.db"),
|
|
14082
|
+
cmd: pc.cyan("aiex schema")
|
|
14083
|
+
});
|
|
14068
14084
|
}
|
|
14069
14085
|
try {
|
|
14070
14086
|
const result = parseJsonSchema(schema);
|
|
14071
14087
|
const db = new Database(dbPath);
|
|
14072
14088
|
try {
|
|
14073
|
-
for (const table of result.tables) if (!db.prepare(`SELECT name FROM sqlite_master WHERE type='table' AND name=?`).get(table.name)) return
|
|
14089
|
+
for (const table of result.tables) if (!db.prepare(`SELECT name FROM sqlite_master WHERE type='table' AND name=?`).get(table.name)) return t("errors.db.tableNotFound", {
|
|
14090
|
+
name: table.name,
|
|
14091
|
+
cmd: pc.cyan("aiex schema")
|
|
14092
|
+
});
|
|
14074
14093
|
} finally {
|
|
14075
14094
|
db.close();
|
|
14076
14095
|
}
|
|
14077
14096
|
} catch (e) {
|
|
14078
|
-
return
|
|
14097
|
+
return t("errors.db.cannotVerify", { error: e instanceof Error ? e.message : String(e) });
|
|
14079
14098
|
}
|
|
14080
14099
|
return null;
|
|
14081
14100
|
}
|
|
14082
14101
|
function listSupportedFiles(dir, pattern) {
|
|
14083
|
-
if (!fs$1.statSync(dir).isDirectory()) throw new Error(
|
|
14102
|
+
if (!fs$1.statSync(dir).isDirectory()) throw new Error(t("errors.file.notADirectory", { dir }));
|
|
14084
14103
|
return globSync(pattern ?? SUPPORTED_FILE_PATTERN, {
|
|
14085
14104
|
cwd: dir,
|
|
14086
14105
|
absolute: true,
|
|
@@ -14098,15 +14117,18 @@ async function loadSchema(config, schemaName) {
|
|
|
14098
14117
|
} catch (e) {
|
|
14099
14118
|
if (e instanceof ZodError) return {
|
|
14100
14119
|
schema: null,
|
|
14101
|
-
error:
|
|
14120
|
+
error: t("errors.schema.validationFailed", {
|
|
14121
|
+
name: `${schemaName}.json`,
|
|
14122
|
+
issues: e.issues.map((i) => ` - ${i.path.join(".")}: ${i.message}`).join("\n")
|
|
14123
|
+
})
|
|
14102
14124
|
};
|
|
14103
14125
|
if (e.code === "ENOENT") return {
|
|
14104
14126
|
schema: null,
|
|
14105
|
-
error:
|
|
14127
|
+
error: t("errors.schema.cannotRead", { name: `${schemaName}.json` })
|
|
14106
14128
|
};
|
|
14107
14129
|
if (e instanceof SyntaxError) return {
|
|
14108
14130
|
schema: null,
|
|
14109
|
-
error:
|
|
14131
|
+
error: t("errors.schema.invalidJson", { name: `${schemaName}.json` })
|
|
14110
14132
|
};
|
|
14111
14133
|
return {
|
|
14112
14134
|
schema: null,
|
|
@@ -14124,12 +14146,16 @@ async function listSchemas(aiexDir) {
|
|
|
14124
14146
|
}
|
|
14125
14147
|
async function readExtractFileInput(filePath, aiConfig, modelOverride) {
|
|
14126
14148
|
const stat = fs$1.statSync(filePath);
|
|
14127
|
-
if (stat.size > MAX_UPLOAD_SIZE) throw new Error(
|
|
14149
|
+
if (stat.size > MAX_UPLOAD_SIZE) throw new Error(t("errors.file.sizeExceeded", {
|
|
14150
|
+
size: bytesToMB(stat.size).toFixed(1),
|
|
14151
|
+
limit: MAX_UPLOAD_SIZE_TEXT,
|
|
14152
|
+
file: filePath
|
|
14153
|
+
}));
|
|
14128
14154
|
const ext = path.extname(filePath).toLowerCase().replace(".", "");
|
|
14129
14155
|
if (FILE_PART_EXTENSIONS.has(ext)) {
|
|
14130
14156
|
if (shouldUseImageOcrFallback(aiConfig, modelOverride)) {
|
|
14131
14157
|
const result = await recognizeImageText(filePath, aiConfig?.image);
|
|
14132
|
-
consola.info(
|
|
14158
|
+
consola.info(t("extract.file.ocrText", { confidence: (result.confidence * 100).toFixed(1) }));
|
|
14133
14159
|
return { text: result.text };
|
|
14134
14160
|
}
|
|
14135
14161
|
return {
|
|
@@ -14141,16 +14167,19 @@ async function readExtractFileInput(filePath, aiConfig, modelOverride) {
|
|
|
14141
14167
|
const buffer = await fs.readFile(filePath);
|
|
14142
14168
|
const converter = createPdfConverter(aiConfig?.pdf);
|
|
14143
14169
|
const result = await converter.convert(buffer, filePath);
|
|
14144
|
-
if (result.metadata?.fallback === "true") consola.info(
|
|
14145
|
-
else consola.info(
|
|
14170
|
+
if (result.metadata?.fallback === "true") consola.info(t("extract.file.pdfFallback", { count: result.pageCount }));
|
|
14171
|
+
else consola.info(t("extract.file.pdfConverted", {
|
|
14172
|
+
name: converter.name,
|
|
14173
|
+
count: result.pageCount
|
|
14174
|
+
}));
|
|
14146
14175
|
const mdPath = filePath.replace(PDF_EXT_RE, ".md");
|
|
14147
14176
|
try {
|
|
14148
14177
|
await fs.writeFile(mdPath, result.text);
|
|
14149
|
-
consola.info(
|
|
14178
|
+
consola.info(t("extract.file.markdownSaved", { path: mdPath }));
|
|
14150
14179
|
} catch {
|
|
14151
14180
|
const fallbackMd = path.join(os.tmpdir(), `${path.basename(filePath, ".pdf")}.md`);
|
|
14152
14181
|
await fs.writeFile(fallbackMd, result.text);
|
|
14153
|
-
consola.info(
|
|
14182
|
+
consola.info(t("extract.file.markdownSaved", { path: fallbackMd }));
|
|
14154
14183
|
}
|
|
14155
14184
|
return { text: result.text };
|
|
14156
14185
|
}
|
|
@@ -14166,7 +14195,7 @@ async function extractSingle(aiexDir, config, aiConfig, schemaName, text$1, file
|
|
|
14166
14195
|
};
|
|
14167
14196
|
}
|
|
14168
14197
|
const s = spinner();
|
|
14169
|
-
if (!options?.quiet) s.start(filePath ?
|
|
14198
|
+
if (!options?.quiet) s.start(filePath ? t("extract.file.extractedFrom", { file: path.basename(filePath) }) : t("extract.file.extracting"));
|
|
14170
14199
|
const result = await extractStructuredData({
|
|
14171
14200
|
config: aiConfig,
|
|
14172
14201
|
schema: schemaLoad.schema,
|
|
@@ -14175,28 +14204,37 @@ async function extractSingle(aiexDir, config, aiConfig, schemaName, text$1, file
|
|
|
14175
14204
|
file: filePath,
|
|
14176
14205
|
modelOverride,
|
|
14177
14206
|
onRetry(info) {
|
|
14178
|
-
if (!options?.quiet) s.message(
|
|
14207
|
+
if (!options?.quiet) s.message(t("extract.file.extractRetry", {
|
|
14208
|
+
code: info.statusCode,
|
|
14209
|
+
delay: info.delayMs / 1e3,
|
|
14210
|
+
attempt: info.attempt,
|
|
14211
|
+
max: info.maxRetries
|
|
14212
|
+
}));
|
|
14179
14213
|
}
|
|
14180
14214
|
});
|
|
14181
14215
|
if (!result.success) {
|
|
14182
14216
|
if (!options?.quiet) {
|
|
14183
|
-
s.stop("
|
|
14184
|
-
consola.error(result.error || "
|
|
14217
|
+
s.stop(t("extract.file.extractFail"));
|
|
14218
|
+
consola.error(result.error || t("common.unknownError"));
|
|
14185
14219
|
}
|
|
14186
14220
|
return {
|
|
14187
14221
|
success: false,
|
|
14188
|
-
error: result.error || "
|
|
14222
|
+
error: result.error || t("common.unknownError")
|
|
14189
14223
|
};
|
|
14190
14224
|
}
|
|
14191
|
-
if (!options?.quiet) s.stop("
|
|
14192
|
-
if (result.outputPath && !options?.quiet) consola.success(
|
|
14193
|
-
if (result.tokensUsed && !options?.quiet) consola.info(pc.gray(
|
|
14225
|
+
if (!options?.quiet) s.stop(t("extract.file.extractComplete"));
|
|
14226
|
+
if (result.outputPath && !options?.quiet) consola.success(t("extract.file.resultSaved", { path: pc.cyan(result.outputPath) }));
|
|
14227
|
+
if (result.tokensUsed && !options?.quiet) consola.info(pc.gray(t("extract.file.tokenUsage", {
|
|
14228
|
+
prompt: result.tokensUsed.prompt,
|
|
14229
|
+
completion: result.tokensUsed.completion,
|
|
14230
|
+
total: result.tokensUsed.total
|
|
14231
|
+
})));
|
|
14194
14232
|
if (result.data && options?.insert !== false) {
|
|
14195
14233
|
const s2 = spinner();
|
|
14196
|
-
if (!options?.quiet) s2.start("
|
|
14234
|
+
if (!options?.quiet) s2.start(t("extract.file.insertingDb"));
|
|
14197
14235
|
const dbError = await ensureDatabaseReady(config.databasePath, schemaLoad.schema);
|
|
14198
14236
|
if (dbError) {
|
|
14199
|
-
if (!options?.quiet) s2.stop("
|
|
14237
|
+
if (!options?.quiet) s2.stop(t("extract.file.dbNotReady"));
|
|
14200
14238
|
consola.error(dbError);
|
|
14201
14239
|
return {
|
|
14202
14240
|
success: false,
|
|
@@ -14208,7 +14246,7 @@ async function extractSingle(aiexDir, config, aiConfig, schemaName, text$1, file
|
|
|
14208
14246
|
try {
|
|
14209
14247
|
const insertResult = insertExtractedData(db, schemaLoad.schema, result.data);
|
|
14210
14248
|
if (insertResult.success) {
|
|
14211
|
-
if (!options?.quiet) s2.stop(
|
|
14249
|
+
if (!options?.quiet) s2.stop(t("extract.file.insertedTables", { count: insertResult.tablesInserted.length }));
|
|
14212
14250
|
return {
|
|
14213
14251
|
success: true,
|
|
14214
14252
|
outputPath: result.outputPath,
|
|
@@ -14217,8 +14255,8 @@ async function extractSingle(aiexDir, config, aiConfig, schemaName, text$1, file
|
|
|
14217
14255
|
tokensUsed: result.tokensUsed
|
|
14218
14256
|
};
|
|
14219
14257
|
} else {
|
|
14220
|
-
if (!options?.quiet) s2.stop("
|
|
14221
|
-
consola.error(insertResult.error || "
|
|
14258
|
+
if (!options?.quiet) s2.stop(t("extract.file.dbInsertFail"));
|
|
14259
|
+
consola.error(insertResult.error || t("common.unknownError"));
|
|
14222
14260
|
return {
|
|
14223
14261
|
success: false,
|
|
14224
14262
|
error: insertResult.error
|
|
@@ -14228,7 +14266,7 @@ async function extractSingle(aiexDir, config, aiConfig, schemaName, text$1, file
|
|
|
14228
14266
|
db.close();
|
|
14229
14267
|
}
|
|
14230
14268
|
} catch (e) {
|
|
14231
|
-
if (!options?.quiet) s2.stop("
|
|
14269
|
+
if (!options?.quiet) s2.stop(t("extract.file.dbInsertFail"));
|
|
14232
14270
|
consola.error(e instanceof Error ? e.message : String(e));
|
|
14233
14271
|
return {
|
|
14234
14272
|
success: false,
|
|
@@ -14262,12 +14300,18 @@ async function runAuditedExtraction(options) {
|
|
|
14262
14300
|
try {
|
|
14263
14301
|
fileHash = await getFileHash(source.filePath);
|
|
14264
14302
|
} catch (e) {
|
|
14265
|
-
if (!quiet) consola.warn(
|
|
14303
|
+
if (!quiet) consola.warn(t("extract.file.hashWarning", {
|
|
14304
|
+
file: path.basename(source.filePath),
|
|
14305
|
+
error: e instanceof Error ? e.message : String(e)
|
|
14306
|
+
}));
|
|
14266
14307
|
}
|
|
14267
14308
|
if (fileHash && !isPlainTextFile && !force) {
|
|
14268
14309
|
const existing = await findSucceededAuditByHash(aiexDir, schemaName, fileHash);
|
|
14269
14310
|
if (existing) {
|
|
14270
|
-
if (!quiet) consola.info(
|
|
14311
|
+
if (!quiet) consola.info(t("extract.file.alreadyProcessed", {
|
|
14312
|
+
file: pc.cyan(path.basename(source.filePath)),
|
|
14313
|
+
hash: fileHash.slice(0, 8)
|
|
14314
|
+
}));
|
|
14271
14315
|
return {
|
|
14272
14316
|
success: true,
|
|
14273
14317
|
skipped: true,
|
|
@@ -14312,7 +14356,7 @@ async function runAuditedExtraction(options) {
|
|
|
14312
14356
|
let notionPages;
|
|
14313
14357
|
if (shouldSyncNotion(aiConfig, schemaName)) try {
|
|
14314
14358
|
notionPages = await syncResultToNotion(aiConfig, schemaName, r.data);
|
|
14315
|
-
if (!quiet) consola.success(
|
|
14359
|
+
if (!quiet) consola.success(t("extract.file.notionSynced", { count: notionPages.length }));
|
|
14316
14360
|
} catch (error) {
|
|
14317
14361
|
await updateExtractionAuditRecord(aiexDir, audit.id, {
|
|
14318
14362
|
status: "failed",
|
|
@@ -14322,7 +14366,7 @@ async function runAuditedExtraction(options) {
|
|
|
14322
14366
|
tokensUsed: r.tokensUsed,
|
|
14323
14367
|
error: error instanceof Error ? error.message : String(error)
|
|
14324
14368
|
});
|
|
14325
|
-
if (!quiet) consola.error(
|
|
14369
|
+
if (!quiet) consola.error(t("extract.file.notionSyncFail", { error: error instanceof Error ? error.message : String(error) }));
|
|
14326
14370
|
return {
|
|
14327
14371
|
success: false,
|
|
14328
14372
|
error: error instanceof Error ? error.message : String(error),
|
|
@@ -14353,7 +14397,7 @@ async function runAuditedExtraction(options) {
|
|
|
14353
14397
|
status: "failed",
|
|
14354
14398
|
error: r.error || "Extraction failed"
|
|
14355
14399
|
});
|
|
14356
|
-
if (!quiet) consola.error(
|
|
14400
|
+
if (!quiet) consola.error(t("extract.file.extractionFailed", { error: r.error }));
|
|
14357
14401
|
return {
|
|
14358
14402
|
success: false,
|
|
14359
14403
|
error: r.error,
|
|
@@ -14368,7 +14412,10 @@ async function runAuditedExtraction(options) {
|
|
|
14368
14412
|
});
|
|
14369
14413
|
if (!quiet) {
|
|
14370
14414
|
const name$1 = source.type === "file" ? path.basename(source.filePath) : "text input";
|
|
14371
|
-
consola.error(
|
|
14415
|
+
consola.error(t("extract.file.errorProcessing", {
|
|
14416
|
+
name: name$1,
|
|
14417
|
+
error: e instanceof Error ? e.message : String(e)
|
|
14418
|
+
}));
|
|
14372
14419
|
}
|
|
14373
14420
|
return {
|
|
14374
14421
|
success: false,
|
|
@@ -14394,13 +14441,13 @@ async function processOneFile(aiexDir, config, aiConfig, schemaName, filePath, m
|
|
|
14394
14441
|
quiet: false
|
|
14395
14442
|
});
|
|
14396
14443
|
if (result.success) {
|
|
14397
|
-
if (!result.skipped) consola.success(
|
|
14444
|
+
if (!result.skipped) consola.success(t("extract.file.processSuccess", { file: path.basename(filePath) }));
|
|
14398
14445
|
return true;
|
|
14399
14446
|
}
|
|
14400
14447
|
return false;
|
|
14401
14448
|
}
|
|
14402
14449
|
async function runBatchExtraction(aiexDir, config, aiConfig, schemaName, dir, globPattern, modelOverride, options) {
|
|
14403
|
-
consola.info(
|
|
14450
|
+
consola.info(t("extract.batch.scanning", { dir: pc.cyan(dir) }));
|
|
14404
14451
|
let files;
|
|
14405
14452
|
try {
|
|
14406
14453
|
files = listSupportedFiles(dir, globPattern);
|
|
@@ -14409,28 +14456,36 @@ async function runBatchExtraction(aiexDir, config, aiConfig, schemaName, dir, gl
|
|
|
14409
14456
|
ok: false,
|
|
14410
14457
|
successCount: 0,
|
|
14411
14458
|
failCount: 0,
|
|
14412
|
-
error:
|
|
14459
|
+
error: t("extract.batch.errors.cannotReadDir", { dir })
|
|
14413
14460
|
};
|
|
14414
14461
|
}
|
|
14415
14462
|
if (files.length === 0) return {
|
|
14416
14463
|
ok: false,
|
|
14417
14464
|
successCount: 0,
|
|
14418
14465
|
failCount: 0,
|
|
14419
|
-
error:
|
|
14466
|
+
error: t("extract.batch.errors.noSupportedFiles", { dir })
|
|
14420
14467
|
};
|
|
14421
|
-
consola.info(
|
|
14468
|
+
consola.info(t("extract.batch.found", { count: files.length }));
|
|
14422
14469
|
let successCount = 0;
|
|
14423
14470
|
let failCount = 0;
|
|
14424
14471
|
for (let i = 0; i < files.length; i++) {
|
|
14425
14472
|
const file = files[i];
|
|
14426
|
-
consola.info(`\n
|
|
14473
|
+
consola.info(`\n${t("extract.batch.processing", {
|
|
14474
|
+
current: i + 1,
|
|
14475
|
+
total: files.length,
|
|
14476
|
+
file: pc.cyan(path.basename(file))
|
|
14477
|
+
})}`);
|
|
14427
14478
|
if (await processOneFile(aiexDir, config, aiConfig, schemaName, file, modelOverride, {
|
|
14428
14479
|
insert: options?.insert,
|
|
14429
14480
|
force: options?.force
|
|
14430
14481
|
})) successCount++;
|
|
14431
14482
|
else failCount++;
|
|
14432
14483
|
}
|
|
14433
|
-
consola.info(`\
|
|
14484
|
+
consola.info(`\n${t("extract.batch.complete", {
|
|
14485
|
+
success: pc.green(successCount),
|
|
14486
|
+
fail: pc.red(failCount),
|
|
14487
|
+
total: files.length
|
|
14488
|
+
})}`);
|
|
14434
14489
|
return {
|
|
14435
14490
|
ok: true,
|
|
14436
14491
|
successCount,
|
|
@@ -14443,34 +14498,35 @@ async function runBatchExtraction(aiexDir, config, aiConfig, schemaName, dir, gl
|
|
|
14443
14498
|
const dumpCommand = defineCommand({
|
|
14444
14499
|
meta: {
|
|
14445
14500
|
name: "dump",
|
|
14446
|
-
description: "
|
|
14501
|
+
description: t("command.dump.description")
|
|
14447
14502
|
},
|
|
14448
14503
|
args: {
|
|
14449
14504
|
table: {
|
|
14450
14505
|
type: "string",
|
|
14451
14506
|
alias: "t",
|
|
14452
|
-
description: "
|
|
14507
|
+
description: t("command.dump.args.table")
|
|
14453
14508
|
},
|
|
14454
14509
|
schema: {
|
|
14455
14510
|
type: "string",
|
|
14456
14511
|
alias: "s",
|
|
14457
|
-
description: "
|
|
14512
|
+
description: t("command.dump.args.schema")
|
|
14458
14513
|
},
|
|
14459
14514
|
format: {
|
|
14460
14515
|
type: "string",
|
|
14461
14516
|
alias: "f",
|
|
14462
|
-
description: "
|
|
14517
|
+
description: t("command.dump.args.format")
|
|
14463
14518
|
},
|
|
14464
14519
|
output: {
|
|
14465
14520
|
type: "string",
|
|
14466
14521
|
alias: "o",
|
|
14467
|
-
description: "
|
|
14522
|
+
description: t("command.dump.args.output")
|
|
14468
14523
|
}
|
|
14469
14524
|
},
|
|
14470
14525
|
async run({ args }) {
|
|
14471
14526
|
intro(pc.inverse(" aiex dump "));
|
|
14527
|
+
await initI18n();
|
|
14472
14528
|
if (!args.table && !args.schema) {
|
|
14473
|
-
failCommand(
|
|
14529
|
+
failCommand(t("command.dump.errors.tableOrSchemaRequired"));
|
|
14474
14530
|
return;
|
|
14475
14531
|
}
|
|
14476
14532
|
const cwd = process.cwd();
|
|
@@ -14481,17 +14537,20 @@ const dumpCommand = defineCommand({
|
|
|
14481
14537
|
if (args.schema) {
|
|
14482
14538
|
const schemaLoad = await loadSchema(config, args.schema);
|
|
14483
14539
|
if (!schemaLoad.schema) {
|
|
14484
|
-
failCommand(schemaLoad.error ||
|
|
14540
|
+
failCommand(schemaLoad.error || t("command.dump.errors.schemaNotFound", { name: args.schema }));
|
|
14485
14541
|
return;
|
|
14486
14542
|
}
|
|
14487
14543
|
schema = schemaLoad.schema;
|
|
14488
14544
|
const tName = schema.table?.name;
|
|
14489
14545
|
if (!tName) {
|
|
14490
|
-
failCommand(
|
|
14546
|
+
failCommand(t("command.dump.errors.noTableName", { name: args.schema }));
|
|
14491
14547
|
return;
|
|
14492
14548
|
}
|
|
14493
14549
|
if (tableName && tableName !== tName) {
|
|
14494
|
-
failCommand(
|
|
14550
|
+
failCommand(t("command.dump.errors.tableMismatch", {
|
|
14551
|
+
table: tableName,
|
|
14552
|
+
schemaTable: tName
|
|
14553
|
+
}));
|
|
14495
14554
|
return;
|
|
14496
14555
|
}
|
|
14497
14556
|
tableName = tName;
|
|
@@ -14518,16 +14577,19 @@ const dumpCommand = defineCommand({
|
|
|
14518
14577
|
}
|
|
14519
14578
|
if (!format) format = "csv";
|
|
14520
14579
|
if (format !== "csv" && format !== "xlsx") {
|
|
14521
|
-
failCommand(
|
|
14580
|
+
failCommand(t("command.dump.errors.unsupportedFormat", { format }));
|
|
14522
14581
|
return;
|
|
14523
14582
|
}
|
|
14524
14583
|
const resolvedOutput = outputPathArg ? path.resolve(outputPathArg) : path.resolve(cwd, `${tableName}.${format}`);
|
|
14525
14584
|
if (!fs$1.existsSync(config.databasePath)) {
|
|
14526
|
-
failCommand(
|
|
14585
|
+
failCommand(t("command.dump.errors.dbNotFound", {
|
|
14586
|
+
path: config.databasePath,
|
|
14587
|
+
cmd: "aiex schema"
|
|
14588
|
+
}));
|
|
14527
14589
|
return;
|
|
14528
14590
|
}
|
|
14529
14591
|
const s = spinner();
|
|
14530
|
-
s.start(
|
|
14592
|
+
s.start(t("command.dump.loading", { name: tableName }));
|
|
14531
14593
|
let columns = [];
|
|
14532
14594
|
let rows = [];
|
|
14533
14595
|
try {
|
|
@@ -14536,8 +14598,11 @@ const dumpCommand = defineCommand({
|
|
|
14536
14598
|
select name from sqlite_master
|
|
14537
14599
|
where type = 'table' and name = ?
|
|
14538
14600
|
`).get(tableName)) {
|
|
14539
|
-
s.stop("
|
|
14540
|
-
failCommand(
|
|
14601
|
+
s.stop(t("command.dump.dbQueryFailed"));
|
|
14602
|
+
failCommand(t("command.dump.errors.tableNotFound", {
|
|
14603
|
+
name: tableName,
|
|
14604
|
+
cmd: "aiex schema"
|
|
14605
|
+
}));
|
|
14541
14606
|
db.close();
|
|
14542
14607
|
return;
|
|
14543
14608
|
}
|
|
@@ -14545,16 +14610,16 @@ const dumpCommand = defineCommand({
|
|
|
14545
14610
|
rows = db.prepare(`select * from ${tableName}`).all();
|
|
14546
14611
|
db.close();
|
|
14547
14612
|
} catch (error) {
|
|
14548
|
-
s.stop("
|
|
14613
|
+
s.stop(t("command.dump.dbQueryFailed"));
|
|
14549
14614
|
failCommand(error instanceof Error ? error.message : String(error));
|
|
14550
14615
|
return;
|
|
14551
14616
|
}
|
|
14552
14617
|
if (rows.length === 0) {
|
|
14553
|
-
s.stop("
|
|
14554
|
-
consola.warn(
|
|
14555
|
-
} else s.stop(
|
|
14618
|
+
s.stop(t("command.dump.emptyTable"));
|
|
14619
|
+
consola.warn(t("command.dump.errors.tableEmpty", { name: tableName }));
|
|
14620
|
+
} else s.stop(t("command.dump.loaded", { count: rows.length }));
|
|
14556
14621
|
const s2 = spinner();
|
|
14557
|
-
s2.start("
|
|
14622
|
+
s2.start(t("command.dump.formatting"));
|
|
14558
14623
|
const formattedRows = rows.map((row) => {
|
|
14559
14624
|
const newRow = {};
|
|
14560
14625
|
columns.forEach((col) => {
|
|
@@ -14580,9 +14645,12 @@ const dumpCommand = defineCommand({
|
|
|
14580
14645
|
});
|
|
14581
14646
|
return newRow;
|
|
14582
14647
|
});
|
|
14583
|
-
s2.stop("
|
|
14648
|
+
s2.stop(t("command.dump.formatted"));
|
|
14584
14649
|
const s3 = spinner();
|
|
14585
|
-
s3.start(
|
|
14650
|
+
s3.start(t("command.dump.writing", {
|
|
14651
|
+
format: format.toUpperCase(),
|
|
14652
|
+
path: resolvedOutput
|
|
14653
|
+
}));
|
|
14586
14654
|
try {
|
|
14587
14655
|
const ws = XLSX.utils.json_to_sheet(formattedRows, { header: columns.map((col) => col.name) });
|
|
14588
14656
|
const outputDir = path.dirname(resolvedOutput);
|
|
@@ -14595,14 +14663,17 @@ const dumpCommand = defineCommand({
|
|
|
14595
14663
|
const csv = XLSX.utils.sheet_to_csv(ws);
|
|
14596
14664
|
fs$1.writeFileSync(resolvedOutput, "" + csv, "utf8");
|
|
14597
14665
|
}
|
|
14598
|
-
s3.stop("
|
|
14599
|
-
consola.success(
|
|
14666
|
+
s3.stop(t("command.dump.dumpCompleted"));
|
|
14667
|
+
consola.success(t("command.dump.successMsg", {
|
|
14668
|
+
count: rows.length,
|
|
14669
|
+
path: pc.cyan(resolvedOutput)
|
|
14670
|
+
}));
|
|
14600
14671
|
} catch (error) {
|
|
14601
|
-
s3.stop("
|
|
14672
|
+
s3.stop(t("command.dump.fileWriteFailed"));
|
|
14602
14673
|
failCommand(error instanceof Error ? error.message : String(error));
|
|
14603
14674
|
return;
|
|
14604
14675
|
}
|
|
14605
|
-
outro("
|
|
14676
|
+
outro(t("common.done"));
|
|
14606
14677
|
}
|
|
14607
14678
|
});
|
|
14608
14679
|
|
|
@@ -14628,15 +14699,15 @@ function formatSource(source) {
|
|
|
14628
14699
|
async function loadConfiguredAI(aiexDir) {
|
|
14629
14700
|
const aiConfig = await readAIConfig(aiexDir);
|
|
14630
14701
|
if (!aiConfig) {
|
|
14631
|
-
failCommand("
|
|
14702
|
+
failCommand(t("command.extract.errors.noAIConfig", { cmd: "aiex web" }));
|
|
14632
14703
|
return null;
|
|
14633
14704
|
}
|
|
14634
14705
|
if (!aiConfig.provider.apiKey) {
|
|
14635
|
-
failCommand("
|
|
14706
|
+
failCommand(t("command.extract.errors.noApiKey"));
|
|
14636
14707
|
return null;
|
|
14637
14708
|
}
|
|
14638
14709
|
if (!aiConfig.provider.models?.length) {
|
|
14639
|
-
failCommand("
|
|
14710
|
+
failCommand(t("command.extract.errors.noModels"));
|
|
14640
14711
|
return null;
|
|
14641
14712
|
}
|
|
14642
14713
|
return aiConfig;
|
|
@@ -14645,7 +14716,10 @@ function resolveModelOverride(aiConfig, modelName) {
|
|
|
14645
14716
|
if (!modelName) return void 0;
|
|
14646
14717
|
const matched = aiConfig.provider.models.find((m) => m.name === modelName);
|
|
14647
14718
|
if (!matched) {
|
|
14648
|
-
failCommand(
|
|
14719
|
+
failCommand(t("command.extract.errors.modelNotFound", {
|
|
14720
|
+
model: modelName,
|
|
14721
|
+
available: aiConfig.provider.models.map((m) => m.name).join(", ")
|
|
14722
|
+
}));
|
|
14649
14723
|
return null;
|
|
14650
14724
|
}
|
|
14651
14725
|
return matched;
|
|
@@ -14653,13 +14727,13 @@ function resolveModelOverride(aiConfig, modelName) {
|
|
|
14653
14727
|
const historyCommand = defineCommand({
|
|
14654
14728
|
meta: {
|
|
14655
14729
|
name: "history",
|
|
14656
|
-
description: "
|
|
14730
|
+
description: t("command.extract.history.description")
|
|
14657
14731
|
},
|
|
14658
14732
|
async run() {
|
|
14659
14733
|
const config = createMigrationConfig(process.cwd());
|
|
14660
14734
|
const records = await listExtractionAuditRecords(path.dirname(config.schemaPath));
|
|
14661
14735
|
if (records.length === 0) {
|
|
14662
|
-
consola.info("
|
|
14736
|
+
consola.info(t("command.extract.history.empty"));
|
|
14663
14737
|
return;
|
|
14664
14738
|
}
|
|
14665
14739
|
for (const record of records) {
|
|
@@ -14671,22 +14745,22 @@ const historyCommand = defineCommand({
|
|
|
14671
14745
|
const showCommand = defineCommand({
|
|
14672
14746
|
meta: {
|
|
14673
14747
|
name: "show",
|
|
14674
|
-
description: "
|
|
14748
|
+
description: t("command.extract.show.description")
|
|
14675
14749
|
},
|
|
14676
14750
|
args: { id: {
|
|
14677
14751
|
type: "string",
|
|
14678
|
-
description: "
|
|
14752
|
+
description: t("command.extract.show.args.id")
|
|
14679
14753
|
} },
|
|
14680
14754
|
async run({ args }) {
|
|
14681
14755
|
const id = getIdArg(args);
|
|
14682
14756
|
if (!id) {
|
|
14683
|
-
failCommand("
|
|
14757
|
+
failCommand(t("command.extract.history.errors.idRequired"));
|
|
14684
14758
|
return;
|
|
14685
14759
|
}
|
|
14686
14760
|
const config = createMigrationConfig(process.cwd());
|
|
14687
14761
|
const record = await readExtractionAuditRecord(path.dirname(config.schemaPath), id);
|
|
14688
14762
|
if (!record) {
|
|
14689
|
-
failCommand(
|
|
14763
|
+
failCommand(t("command.extract.history.errors.recordNotFound", { id }));
|
|
14690
14764
|
return;
|
|
14691
14765
|
}
|
|
14692
14766
|
consola.info(JSON.stringify(record, null, 2));
|
|
@@ -14695,31 +14769,32 @@ const showCommand = defineCommand({
|
|
|
14695
14769
|
const retryCommand = defineCommand({
|
|
14696
14770
|
meta: {
|
|
14697
14771
|
name: "retry",
|
|
14698
|
-
description: "
|
|
14772
|
+
description: t("command.extract.retry.description")
|
|
14699
14773
|
},
|
|
14700
14774
|
args: {
|
|
14701
14775
|
id: {
|
|
14702
14776
|
type: "string",
|
|
14703
|
-
description: "
|
|
14777
|
+
description: t("command.extract.retry.args.id")
|
|
14704
14778
|
},
|
|
14705
14779
|
noInsert: {
|
|
14706
14780
|
type: "boolean",
|
|
14707
|
-
description: "
|
|
14781
|
+
description: t("command.extract.retry.args.noInsert"),
|
|
14708
14782
|
default: false
|
|
14709
14783
|
}
|
|
14710
14784
|
},
|
|
14711
14785
|
async run({ args }) {
|
|
14712
14786
|
intro(pc.inverse(" aiex extract retry "));
|
|
14787
|
+
await initI18n();
|
|
14713
14788
|
const id = getIdArg(args);
|
|
14714
14789
|
if (!id) {
|
|
14715
|
-
failCommand("
|
|
14790
|
+
failCommand(t("command.extract.history.errors.idRequired"));
|
|
14716
14791
|
return;
|
|
14717
14792
|
}
|
|
14718
14793
|
const config = createMigrationConfig(process.cwd());
|
|
14719
14794
|
const aiexDir = path.dirname(config.schemaPath);
|
|
14720
14795
|
const record = await readExtractionAuditRecord(aiexDir, id);
|
|
14721
14796
|
if (!record) {
|
|
14722
|
-
failCommand(
|
|
14797
|
+
failCommand(t("command.extract.history.errors.recordNotFound", { id }));
|
|
14723
14798
|
return;
|
|
14724
14799
|
}
|
|
14725
14800
|
const aiConfig = await loadConfiguredAI(aiexDir);
|
|
@@ -14742,7 +14817,7 @@ const retryCommand = defineCommand({
|
|
|
14742
14817
|
failCommand(result.error);
|
|
14743
14818
|
return;
|
|
14744
14819
|
}
|
|
14745
|
-
outro("
|
|
14820
|
+
outro(t("common.done"));
|
|
14746
14821
|
} catch (error) {
|
|
14747
14822
|
if (isMissingUploadFileError(error)) {
|
|
14748
14823
|
failCommand(MISSING_UPLOAD_FILE_TEXT);
|
|
@@ -14755,30 +14830,30 @@ const retryCommand = defineCommand({
|
|
|
14755
14830
|
const rmCommand = defineCommand({
|
|
14756
14831
|
meta: {
|
|
14757
14832
|
name: "rm",
|
|
14758
|
-
description: "
|
|
14833
|
+
description: t("command.extract.rm.description")
|
|
14759
14834
|
},
|
|
14760
14835
|
args: { id: {
|
|
14761
14836
|
type: "string",
|
|
14762
|
-
description: "
|
|
14837
|
+
description: t("command.extract.rm.args.id")
|
|
14763
14838
|
} },
|
|
14764
14839
|
async run({ args }) {
|
|
14765
14840
|
const id = getIdArg(args);
|
|
14766
14841
|
if (!id) {
|
|
14767
|
-
failCommand("
|
|
14842
|
+
failCommand(t("command.extract.history.errors.idRequired"));
|
|
14768
14843
|
return;
|
|
14769
14844
|
}
|
|
14770
14845
|
const config = createMigrationConfig(process.cwd());
|
|
14771
14846
|
if (!await deleteExtractionAuditRecord(path.dirname(config.schemaPath), id)) {
|
|
14772
|
-
failCommand(
|
|
14847
|
+
failCommand(t("command.extract.history.errors.recordNotFound", { id }));
|
|
14773
14848
|
return;
|
|
14774
14849
|
}
|
|
14775
|
-
consola.success(
|
|
14850
|
+
consola.success(t("command.extract.history.deleted", { id }));
|
|
14776
14851
|
}
|
|
14777
14852
|
});
|
|
14778
14853
|
const extractCommand = defineCommand({
|
|
14779
14854
|
meta: {
|
|
14780
14855
|
name: "extract",
|
|
14781
|
-
description: "
|
|
14856
|
+
description: t("command.extract.description")
|
|
14782
14857
|
},
|
|
14783
14858
|
subCommands: {
|
|
14784
14859
|
history: historyCommand,
|
|
@@ -14790,46 +14865,47 @@ const extractCommand = defineCommand({
|
|
|
14790
14865
|
schema: {
|
|
14791
14866
|
type: "string",
|
|
14792
14867
|
alias: "s",
|
|
14793
|
-
description: "
|
|
14868
|
+
description: t("command.extract.args.schema")
|
|
14794
14869
|
},
|
|
14795
14870
|
file: {
|
|
14796
14871
|
type: "string",
|
|
14797
14872
|
alias: "f",
|
|
14798
|
-
description:
|
|
14873
|
+
description: t("command.extract.args.file", { types: SUPPORTED_FILE_TYPES_TEXT })
|
|
14799
14874
|
},
|
|
14800
14875
|
model: {
|
|
14801
14876
|
type: "string",
|
|
14802
14877
|
alias: "m",
|
|
14803
|
-
description: "
|
|
14878
|
+
description: t("command.extract.args.model")
|
|
14804
14879
|
},
|
|
14805
14880
|
dir: {
|
|
14806
14881
|
type: "string",
|
|
14807
14882
|
alias: "d",
|
|
14808
|
-
description: "
|
|
14883
|
+
description: t("command.extract.args.dir")
|
|
14809
14884
|
},
|
|
14810
14885
|
glob: {
|
|
14811
14886
|
type: "string",
|
|
14812
14887
|
alias: "g",
|
|
14813
|
-
description: "
|
|
14888
|
+
description: t("command.extract.args.glob")
|
|
14814
14889
|
},
|
|
14815
14890
|
noInsert: {
|
|
14816
14891
|
type: "boolean",
|
|
14817
|
-
description: "
|
|
14892
|
+
description: t("command.extract.args.noInsert"),
|
|
14818
14893
|
default: false
|
|
14819
14894
|
},
|
|
14820
14895
|
force: {
|
|
14821
14896
|
type: "boolean",
|
|
14822
|
-
description: "
|
|
14897
|
+
description: t("command.extract.args.force"),
|
|
14823
14898
|
default: false
|
|
14824
14899
|
}
|
|
14825
14900
|
},
|
|
14826
14901
|
async run({ args, rawArgs }) {
|
|
14827
14902
|
if (isExtractSubCommand(rawArgs)) return;
|
|
14828
14903
|
intro(pc.inverse(" aiex extract "));
|
|
14904
|
+
await initI18n();
|
|
14829
14905
|
const config = createMigrationConfig(process.cwd());
|
|
14830
14906
|
const aiexDir = path.dirname(config.schemaPath);
|
|
14831
14907
|
if (args.dir && args.file) {
|
|
14832
|
-
failCommand("
|
|
14908
|
+
failCommand(t("command.extract.errors.conflictFileDir"));
|
|
14833
14909
|
return;
|
|
14834
14910
|
}
|
|
14835
14911
|
const aiConfig = await loadConfiguredAI(aiexDir);
|
|
@@ -14837,12 +14913,12 @@ const extractCommand = defineCommand({
|
|
|
14837
14913
|
const modelOverride = resolveModelOverride(aiConfig, args.model);
|
|
14838
14914
|
if (modelOverride === null) return;
|
|
14839
14915
|
if (!args.schema && !args.file && !args.dir) {
|
|
14840
|
-
if (await runInteractive(aiexDir, config, aiConfig, modelOverride)) outro("
|
|
14916
|
+
if (await runInteractive(aiexDir, config, aiConfig, modelOverride)) outro(t("common.done"));
|
|
14841
14917
|
return;
|
|
14842
14918
|
}
|
|
14843
14919
|
if (args.dir) {
|
|
14844
14920
|
if (!args.schema) {
|
|
14845
|
-
failCommand(
|
|
14921
|
+
failCommand(t("command.extract.errors.schemaRequiredBatch"));
|
|
14846
14922
|
return;
|
|
14847
14923
|
}
|
|
14848
14924
|
const result$1 = await runBatchExtraction(aiexDir, config, aiConfig, args.schema, args.dir, args.glob, modelOverride, {
|
|
@@ -14854,16 +14930,16 @@ const extractCommand = defineCommand({
|
|
|
14854
14930
|
return;
|
|
14855
14931
|
}
|
|
14856
14932
|
if (result$1.failCount > 0) process.exitCode = 1;
|
|
14857
|
-
if (result$1.failCount > 0) outro(
|
|
14858
|
-
else outro("
|
|
14933
|
+
if (result$1.failCount > 0) outro(t("command.extract.batch.failSummary", { count: result$1.failCount }));
|
|
14934
|
+
else outro(t("common.done"));
|
|
14859
14935
|
return;
|
|
14860
14936
|
}
|
|
14861
14937
|
if (!args.schema) {
|
|
14862
|
-
failCommand("
|
|
14938
|
+
failCommand(t("command.extract.errors.schemaRequiredSingle"));
|
|
14863
14939
|
return;
|
|
14864
14940
|
}
|
|
14865
14941
|
if (!args.file) {
|
|
14866
|
-
failCommand("
|
|
14942
|
+
failCommand(t("command.extract.errors.fileRequiredSingle"));
|
|
14867
14943
|
return;
|
|
14868
14944
|
}
|
|
14869
14945
|
const result = await runAuditedExtraction({
|
|
@@ -14884,51 +14960,54 @@ const extractCommand = defineCommand({
|
|
|
14884
14960
|
failCommand(result.error);
|
|
14885
14961
|
return;
|
|
14886
14962
|
}
|
|
14887
|
-
outro("
|
|
14963
|
+
outro(t("common.done"));
|
|
14888
14964
|
}
|
|
14889
14965
|
});
|
|
14890
14966
|
async function runInteractive(aiexDir, config, aiConfig, modelOverride) {
|
|
14891
14967
|
const schemas = await listSchemas(aiexDir);
|
|
14892
14968
|
if (schemas.length === 0) {
|
|
14893
|
-
failCommand(
|
|
14969
|
+
failCommand(t("command.extract.errors.noSchemas", {
|
|
14970
|
+
path: pc.cyan(".aiex/schema/"),
|
|
14971
|
+
cmd: pc.cyan("aiex web")
|
|
14972
|
+
}));
|
|
14894
14973
|
return false;
|
|
14895
14974
|
}
|
|
14896
14975
|
const schemaName = await select({
|
|
14897
|
-
message: "
|
|
14976
|
+
message: t("command.extract.interactive.selectSchema"),
|
|
14898
14977
|
options: schemas.map((s) => ({
|
|
14899
14978
|
label: s,
|
|
14900
14979
|
value: s
|
|
14901
14980
|
}))
|
|
14902
14981
|
});
|
|
14903
14982
|
if (isCancel(schemaName)) {
|
|
14904
|
-
cancel("
|
|
14983
|
+
cancel(t("common.cancelled"));
|
|
14905
14984
|
return false;
|
|
14906
14985
|
}
|
|
14907
14986
|
const inputSource = await select({
|
|
14908
|
-
message: "
|
|
14987
|
+
message: t("command.extract.interactive.chooseSource"),
|
|
14909
14988
|
options: [{
|
|
14910
|
-
label: "
|
|
14989
|
+
label: t("command.extract.interactive.singleFile"),
|
|
14911
14990
|
value: "file",
|
|
14912
|
-
hint: "
|
|
14991
|
+
hint: t("command.extract.interactive.singleFileHint")
|
|
14913
14992
|
}, {
|
|
14914
|
-
label: "
|
|
14993
|
+
label: t("command.extract.interactive.batchDir"),
|
|
14915
14994
|
value: "dir",
|
|
14916
|
-
hint: "
|
|
14995
|
+
hint: t("command.extract.interactive.batchDirHint")
|
|
14917
14996
|
}]
|
|
14918
14997
|
});
|
|
14919
14998
|
if (isCancel(inputSource)) {
|
|
14920
|
-
cancel("
|
|
14999
|
+
cancel(t("common.cancelled"));
|
|
14921
15000
|
return false;
|
|
14922
15001
|
}
|
|
14923
15002
|
if (inputSource === "file") {
|
|
14924
15003
|
const filePathStr = await text({
|
|
14925
|
-
message: "
|
|
15004
|
+
message: t("command.extract.interactive.enterFilePath"),
|
|
14926
15005
|
validate(value) {
|
|
14927
|
-
if (!value || value.trim().length === 0) return "
|
|
15006
|
+
if (!value || value.trim().length === 0) return t("command.extract.interactive.filePathRequired");
|
|
14928
15007
|
}
|
|
14929
15008
|
});
|
|
14930
15009
|
if (isCancel(filePathStr)) {
|
|
14931
|
-
cancel("
|
|
15010
|
+
cancel(t("common.cancelled"));
|
|
14932
15011
|
return false;
|
|
14933
15012
|
}
|
|
14934
15013
|
return (await runAuditedExtraction({
|
|
@@ -14944,13 +15023,13 @@ async function runInteractive(aiexDir, config, aiConfig, modelOverride) {
|
|
|
14944
15023
|
})).success;
|
|
14945
15024
|
} else if (inputSource === "dir") {
|
|
14946
15025
|
const dirPath = await text({
|
|
14947
|
-
message: "
|
|
15026
|
+
message: t("command.extract.interactive.enterDirPath"),
|
|
14948
15027
|
validate(value) {
|
|
14949
|
-
if (!value || value.trim().length === 0) return "
|
|
15028
|
+
if (!value || value.trim().length === 0) return t("command.extract.interactive.dirPathRequired");
|
|
14950
15029
|
}
|
|
14951
15030
|
});
|
|
14952
15031
|
if (isCancel(dirPath)) {
|
|
14953
|
-
cancel("
|
|
15032
|
+
cancel(t("common.cancelled"));
|
|
14954
15033
|
return false;
|
|
14955
15034
|
}
|
|
14956
15035
|
const result = await runBatchExtraction(aiexDir, config, aiConfig, schemaName, dirPath, void 0, modelOverride);
|
|
@@ -14961,7 +15040,7 @@ async function runInteractive(aiexDir, config, aiConfig, modelOverride) {
|
|
|
14961
15040
|
}
|
|
14962
15041
|
function cancel(msg) {
|
|
14963
15042
|
consola.info(msg);
|
|
14964
|
-
outro("
|
|
15043
|
+
outro(t("common.cancelled"));
|
|
14965
15044
|
process.exitCode = 0;
|
|
14966
15045
|
}
|
|
14967
15046
|
|
|
@@ -15006,18 +15085,18 @@ function parseMigrationOutput(stdout, stderr) {
|
|
|
15006
15085
|
const jsonLine = stdout.trim().split("\n").find((l) => l.startsWith("{") && l.endsWith("}"));
|
|
15007
15086
|
if (!jsonLine) return {
|
|
15008
15087
|
success: false,
|
|
15009
|
-
error: "
|
|
15088
|
+
error: t("errors.schema.migrationHelperInvalidOutput")
|
|
15010
15089
|
};
|
|
15011
15090
|
const result = JSON.parse(jsonLine);
|
|
15012
15091
|
if (!result.success) return {
|
|
15013
15092
|
success: false,
|
|
15014
|
-
error: result.error || "
|
|
15093
|
+
error: result.error || t("errors.schema.migrationFailed")
|
|
15015
15094
|
};
|
|
15016
15095
|
return result;
|
|
15017
15096
|
} catch {
|
|
15018
15097
|
return {
|
|
15019
15098
|
success: false,
|
|
15020
|
-
error: stderr || stdout || "
|
|
15099
|
+
error: stderr || stdout || t("errors.schema.migrationHelperFailed")
|
|
15021
15100
|
};
|
|
15022
15101
|
}
|
|
15023
15102
|
}
|
|
@@ -15046,7 +15125,7 @@ async function runSchemaSync(config, options = {}) {
|
|
|
15046
15125
|
const schemaFiles = await listSchemaFiles(config.schemaPath);
|
|
15047
15126
|
if (schemaFiles.length === 0) return {
|
|
15048
15127
|
success: false,
|
|
15049
|
-
error: "
|
|
15128
|
+
error: t("errors.schema.noFiles"),
|
|
15050
15129
|
warnings: [],
|
|
15051
15130
|
schemaCount: 0,
|
|
15052
15131
|
tables: 0,
|
|
@@ -15085,61 +15164,65 @@ async function runSchemaSync(config, options = {}) {
|
|
|
15085
15164
|
const schemaCommand = defineCommand({
|
|
15086
15165
|
meta: {
|
|
15087
15166
|
name: "schema",
|
|
15088
|
-
description: "
|
|
15167
|
+
description: t("command.schema.description")
|
|
15089
15168
|
},
|
|
15090
15169
|
args: {
|
|
15091
15170
|
generate: {
|
|
15092
15171
|
type: "boolean",
|
|
15093
15172
|
alias: "g",
|
|
15094
|
-
description: "
|
|
15173
|
+
description: t("command.schema.args.generate"),
|
|
15095
15174
|
default: false
|
|
15096
15175
|
},
|
|
15097
15176
|
name: {
|
|
15098
15177
|
type: "string",
|
|
15099
|
-
description: "
|
|
15178
|
+
description: t("command.schema.args.name")
|
|
15100
15179
|
}
|
|
15101
15180
|
},
|
|
15102
15181
|
async run({ args }) {
|
|
15103
15182
|
intro(pc.inverse(" aiex schema "));
|
|
15183
|
+
await initI18n();
|
|
15104
15184
|
const config = createMigrationConfig(process.cwd());
|
|
15105
15185
|
const schemaFiles = await listSchemaFiles(config.schemaPath);
|
|
15106
15186
|
if (schemaFiles.length === 0) {
|
|
15107
|
-
consola.info(
|
|
15108
|
-
failCommand(
|
|
15187
|
+
consola.info(t("command.schema.runWebHint", { cmd: pc.cyan("aiex web") }));
|
|
15188
|
+
failCommand(t("command.schema.noSchemas", { path: pc.cyan(".aiex/schema/") }));
|
|
15109
15189
|
return;
|
|
15110
15190
|
}
|
|
15111
15191
|
const s1 = spinner();
|
|
15112
|
-
s1.start("
|
|
15192
|
+
s1.start(t("command.schema.generating"));
|
|
15113
15193
|
const generated = await generateSchemaFromFiles(schemaFiles, config);
|
|
15114
15194
|
for (const warning of generated.warnings) consola.warn(warning);
|
|
15115
|
-
if (generated.success) consola.success(
|
|
15195
|
+
if (generated.success) consola.success(t("command.schema.generated", {
|
|
15196
|
+
path: pc.cyan(".aiex/drizzle/schema.ts"),
|
|
15197
|
+
count: generated.schemaCount
|
|
15198
|
+
}));
|
|
15116
15199
|
else if (generated.error) consola.error(generated.error);
|
|
15117
|
-
s1.stop(generated.success ? "
|
|
15200
|
+
s1.stop(generated.success ? t("command.schema.generatedOk") : t("command.schema.generatedFail"));
|
|
15118
15201
|
if (!generated.success) {
|
|
15119
|
-
failCommand();
|
|
15202
|
+
failCommand(t("common.failed"));
|
|
15120
15203
|
return;
|
|
15121
15204
|
}
|
|
15122
15205
|
if (args.generate) {
|
|
15123
|
-
outro("
|
|
15206
|
+
outro(t("command.schema.runWithoutGenerate"));
|
|
15124
15207
|
return;
|
|
15125
15208
|
}
|
|
15126
15209
|
const s2 = spinner();
|
|
15127
|
-
s2.start("
|
|
15210
|
+
s2.start(t("command.schema.runningMigrations"));
|
|
15128
15211
|
const migration = await runSchemaMigration(config, args.name);
|
|
15129
15212
|
if (!migration.success) {
|
|
15130
|
-
consola.error("
|
|
15131
|
-
consola.error(migration.error || "
|
|
15132
|
-
} else if (migration.changes === 0) consola.info(pc.gray("
|
|
15213
|
+
consola.error(t("command.schema.migrationFailed"));
|
|
15214
|
+
consola.error(migration.error || t("command.schema.migrationFail"));
|
|
15215
|
+
} else if (migration.changes === 0) consola.info(pc.gray(t("command.schema.noChanges")));
|
|
15133
15216
|
else {
|
|
15134
|
-
consola.success(pc.green("
|
|
15135
|
-
consola.success(pc.green("
|
|
15217
|
+
consola.success(pc.green(t("command.schema.migrationFilesGenerated")));
|
|
15218
|
+
consola.success(pc.green(t("command.schema.databaseMigrated")));
|
|
15136
15219
|
}
|
|
15137
|
-
s2.stop(migration.success ? "
|
|
15220
|
+
s2.stop(migration.success ? t("command.schema.migrationsApplied") : t("command.schema.migrationFail"));
|
|
15138
15221
|
if (!migration.success) {
|
|
15139
|
-
failCommand();
|
|
15222
|
+
failCommand(t("common.failed"));
|
|
15140
15223
|
return;
|
|
15141
15224
|
}
|
|
15142
|
-
outro("
|
|
15225
|
+
outro(t("common.done"));
|
|
15143
15226
|
}
|
|
15144
15227
|
});
|
|
15145
15228
|
|
|
@@ -15208,14 +15291,14 @@ var WatchRegistry = class {
|
|
|
15208
15291
|
};
|
|
15209
15292
|
async function notifySuccess(fileName) {
|
|
15210
15293
|
if (process.platform === "darwin") try {
|
|
15211
|
-
await execa("osascript", ["-e", `display notification "
|
|
15294
|
+
await execa("osascript", ["-e", `display notification "${t("command.watch.notification.success")}" with title "${t("command.watch.notification.successTitle", { file: fileName })}"`]);
|
|
15212
15295
|
await execa("afplay", ["/System/Library/Sounds/Glass.aiff"]);
|
|
15213
15296
|
} catch {}
|
|
15214
15297
|
else process.stdout.write("\x07");
|
|
15215
15298
|
}
|
|
15216
15299
|
async function notifyFailure(fileName, errorMessage) {
|
|
15217
15300
|
if (process.platform === "darwin") try {
|
|
15218
|
-
await execa("osascript", ["-e", `display notification "${errorMessage.replace(/"/g, "\\\"")}" with title "
|
|
15301
|
+
await execa("osascript", ["-e", `display notification "${errorMessage.replace(/"/g, "\\\"")}" with title "${t("command.watch.notification.failTitle", { file: fileName })}"`]);
|
|
15219
15302
|
await execa("afplay", ["/System/Library/Sounds/Basso.aiff"]);
|
|
15220
15303
|
} catch {}
|
|
15221
15304
|
else process.stdout.write("\x07\x07");
|
|
@@ -15227,9 +15310,9 @@ function startWatcher(options) {
|
|
|
15227
15310
|
const registry$2 = new WatchRegistry(aiexDir);
|
|
15228
15311
|
fs$1.mkdirSync(queueDirActive, { recursive: true });
|
|
15229
15312
|
fs$1.mkdirSync(queueDirFailed, { recursive: true });
|
|
15230
|
-
consola.info(pc.green(
|
|
15231
|
-
consola.info(pc.green(
|
|
15232
|
-
if (modelOverride) consola.info(pc.green(
|
|
15313
|
+
consola.info(pc.green(t("command.watch.starting.watchFolder", { dir: pc.cyan(watchDir) })));
|
|
15314
|
+
consola.info(pc.green(t("command.watch.starting.schema", { name: pc.cyan(schemaName) })));
|
|
15315
|
+
if (modelOverride) consola.info(pc.green(t("command.watch.starting.modelOverride", { name: pc.cyan(modelOverride.name) })));
|
|
15233
15316
|
const watcher = chokidar.watch(watchDir, {
|
|
15234
15317
|
persistent: true,
|
|
15235
15318
|
ignoreInitial: false,
|
|
@@ -15245,15 +15328,18 @@ function startWatcher(options) {
|
|
|
15245
15328
|
if (!stat || !stat.isFile()) return;
|
|
15246
15329
|
const ext = path.extname(resolvedPath).toLowerCase().replace(".", "");
|
|
15247
15330
|
if (!SUPPORTED_EXTENSIONS.has(ext)) {
|
|
15248
|
-
consola.warn(
|
|
15331
|
+
consola.warn(t("command.watch.events.skippedUnsupported", { file: path.basename(resolvedPath) }));
|
|
15249
15332
|
return;
|
|
15250
15333
|
}
|
|
15251
15334
|
const fileName = path.basename(resolvedPath);
|
|
15252
|
-
consola.info(
|
|
15335
|
+
consola.info(t("command.watch.events.fileDetected", { file: pc.cyan(fileName) }));
|
|
15253
15336
|
try {
|
|
15254
15337
|
const hash = await getFileHash(resolvedPath);
|
|
15255
15338
|
if (await registry$2.getStatus(hash) === "succeeded") {
|
|
15256
|
-
consola.info(
|
|
15339
|
+
consola.info(t("command.watch.events.alreadyProcessed", {
|
|
15340
|
+
file: pc.cyan(fileName),
|
|
15341
|
+
hash: hash.slice(0, 8)
|
|
15342
|
+
}));
|
|
15257
15343
|
return;
|
|
15258
15344
|
}
|
|
15259
15345
|
const activeQueuePath = path.join(queueDirActive, `${hash}.${ext}`);
|
|
@@ -15262,25 +15348,28 @@ function startWatcher(options) {
|
|
|
15262
15348
|
await registry$2.markSucceeded(hash, resolvedPath);
|
|
15263
15349
|
await fs.rm(activeQueuePath, { force: true }).catch(() => {});
|
|
15264
15350
|
await fs.rm(activeQueuePath.replace(PDF_EXT_REGEXP, ".md"), { force: true }).catch(() => {});
|
|
15265
|
-
consola.success(
|
|
15351
|
+
consola.success(t("command.watch.events.processedSuccess", { file: pc.green(fileName) }));
|
|
15266
15352
|
await notifySuccess(fileName);
|
|
15267
15353
|
} else {
|
|
15268
|
-
const errorMsg = "
|
|
15354
|
+
const errorMsg = t("command.watch.events.extractionFailed");
|
|
15269
15355
|
await registry$2.markFailed(hash, resolvedPath, errorMsg);
|
|
15270
15356
|
const failedQueuePath = path.join(queueDirFailed, `${hash}-${Date.now()}.${ext}`);
|
|
15271
15357
|
await fs.rename(activeQueuePath, failedQueuePath).catch(() => {});
|
|
15272
15358
|
await fs.rm(activeQueuePath.replace(PDF_EXT_REGEXP, ".md"), { force: true }).catch(() => {});
|
|
15273
|
-
consola.error(
|
|
15359
|
+
consola.error(t("command.watch.events.processingFailed", { file: pc.red(fileName) }));
|
|
15274
15360
|
await notifyFailure(fileName, errorMsg);
|
|
15275
15361
|
}
|
|
15276
15362
|
} catch (e) {
|
|
15277
15363
|
const errorMsg = e instanceof Error ? e.message : String(e);
|
|
15278
|
-
consola.error(
|
|
15364
|
+
consola.error(t("command.watch.events.errorProcessing", {
|
|
15365
|
+
file: fileName,
|
|
15366
|
+
error: errorMsg
|
|
15367
|
+
}));
|
|
15279
15368
|
await notifyFailure(fileName, errorMsg);
|
|
15280
15369
|
}
|
|
15281
15370
|
});
|
|
15282
15371
|
watcher.on("error", (error) => {
|
|
15283
|
-
consola.error(
|
|
15372
|
+
consola.error(t("command.watch.events.watcherError", { error: error?.message || String(error) }));
|
|
15284
15373
|
});
|
|
15285
15374
|
return watcher;
|
|
15286
15375
|
}
|
|
@@ -15290,56 +15379,60 @@ function startWatcher(options) {
|
|
|
15290
15379
|
const watchCommand = defineCommand({
|
|
15291
15380
|
meta: {
|
|
15292
15381
|
name: "watch",
|
|
15293
|
-
description: "
|
|
15382
|
+
description: t("command.watch.description")
|
|
15294
15383
|
},
|
|
15295
15384
|
args: {
|
|
15296
15385
|
schema: {
|
|
15297
15386
|
type: "string",
|
|
15298
15387
|
alias: "s",
|
|
15299
|
-
description: "
|
|
15388
|
+
description: t("command.watch.args.schema")
|
|
15300
15389
|
},
|
|
15301
15390
|
dir: {
|
|
15302
15391
|
type: "string",
|
|
15303
15392
|
alias: "d",
|
|
15304
|
-
description: "
|
|
15393
|
+
description: t("command.watch.args.dir")
|
|
15305
15394
|
},
|
|
15306
15395
|
model: {
|
|
15307
15396
|
type: "string",
|
|
15308
15397
|
alias: "m",
|
|
15309
|
-
description: "
|
|
15398
|
+
description: t("command.watch.args.model")
|
|
15310
15399
|
},
|
|
15311
15400
|
noInsert: {
|
|
15312
15401
|
type: "boolean",
|
|
15313
|
-
description: "
|
|
15402
|
+
description: t("command.watch.args.noInsert"),
|
|
15314
15403
|
default: false
|
|
15315
15404
|
}
|
|
15316
15405
|
},
|
|
15317
15406
|
async run({ args }) {
|
|
15318
15407
|
intro(pc.inverse(" aiex watch "));
|
|
15408
|
+
await initI18n();
|
|
15319
15409
|
if (!args.schema) {
|
|
15320
|
-
failCommand(
|
|
15410
|
+
failCommand(t("command.watch.errors.schemaRequired"));
|
|
15321
15411
|
return;
|
|
15322
15412
|
}
|
|
15323
15413
|
if (!args.dir) {
|
|
15324
|
-
failCommand(
|
|
15414
|
+
failCommand(t("command.watch.errors.dirRequired"));
|
|
15325
15415
|
return;
|
|
15326
15416
|
}
|
|
15327
15417
|
const config = createMigrationConfig(process.cwd());
|
|
15328
15418
|
const aiexDir = path.dirname(config.schemaPath);
|
|
15329
15419
|
const schemaLoad = await loadSchema(config, args.schema);
|
|
15330
15420
|
if (!schemaLoad.schema) {
|
|
15331
|
-
failCommand(schemaLoad.error ||
|
|
15421
|
+
failCommand(schemaLoad.error || t("command.watch.errors.schemaNotFound", { name: args.schema }));
|
|
15332
15422
|
return;
|
|
15333
15423
|
}
|
|
15334
15424
|
let watchDirStat;
|
|
15335
15425
|
try {
|
|
15336
15426
|
watchDirStat = fs$1.statSync(args.dir);
|
|
15337
15427
|
} catch (e) {
|
|
15338
|
-
failCommand(
|
|
15428
|
+
failCommand(t("command.watch.errors.dirNotExist", {
|
|
15429
|
+
dir: args.dir,
|
|
15430
|
+
error: e instanceof Error ? e.message : String(e)
|
|
15431
|
+
}));
|
|
15339
15432
|
return;
|
|
15340
15433
|
}
|
|
15341
15434
|
if (!watchDirStat.isDirectory()) {
|
|
15342
|
-
failCommand(
|
|
15435
|
+
failCommand(t("command.watch.errors.notADirectory", { dir: args.dir }));
|
|
15343
15436
|
return;
|
|
15344
15437
|
}
|
|
15345
15438
|
const watchDirAbs = path.resolve(args.dir);
|
|
@@ -15357,14 +15450,14 @@ const watchCommand = defineCommand({
|
|
|
15357
15450
|
insert: !args.noInsert
|
|
15358
15451
|
});
|
|
15359
15452
|
const cleanup = async () => {
|
|
15360
|
-
consola.info("
|
|
15453
|
+
consola.info(t("command.watch.events.stopped"));
|
|
15361
15454
|
await watcher.close();
|
|
15362
|
-
consola.success("
|
|
15455
|
+
consola.success(t("command.watch.events.stoppedOk"));
|
|
15363
15456
|
process.exit(0);
|
|
15364
15457
|
};
|
|
15365
15458
|
process.on("SIGINT", cleanup);
|
|
15366
15459
|
process.on("SIGTERM", cleanup);
|
|
15367
|
-
consola.info("
|
|
15460
|
+
consola.info(t("command.watch.events.pressCtrlC"));
|
|
15368
15461
|
}
|
|
15369
15462
|
});
|
|
15370
15463
|
|
|
@@ -15430,7 +15523,7 @@ function aiRoutes(config) {
|
|
|
15430
15523
|
const schemaName = typeof body.schemaName === "string" ? body.schemaName : "";
|
|
15431
15524
|
if (!schemaName) return c.json({
|
|
15432
15525
|
success: false,
|
|
15433
|
-
error: "
|
|
15526
|
+
error: t("server.schemaRequired")
|
|
15434
15527
|
}, 400);
|
|
15435
15528
|
const result = await inspectNotionDatabase({
|
|
15436
15529
|
token,
|
|
@@ -15455,26 +15548,26 @@ function aiRoutes(config) {
|
|
|
15455
15548
|
const userTpl = body?.prompt?.userTemplate;
|
|
15456
15549
|
if (!systemTpl || !systemTpl.includes("{schema}")) return c.json({
|
|
15457
15550
|
success: false,
|
|
15458
|
-
error: "
|
|
15551
|
+
error: t("server.promptSchemaPlaceholder")
|
|
15459
15552
|
}, 400);
|
|
15460
15553
|
if (!userTpl?.includes("{text}")) return c.json({
|
|
15461
15554
|
success: false,
|
|
15462
|
-
error: "
|
|
15555
|
+
error: t("server.promptTextPlaceholder")
|
|
15463
15556
|
}, 400);
|
|
15464
15557
|
if (!body.provider?.models?.length) return c.json({
|
|
15465
15558
|
success: false,
|
|
15466
|
-
error: "
|
|
15559
|
+
error: t("server.atLeastOneModel")
|
|
15467
15560
|
}, 400);
|
|
15468
15561
|
if (body.notion?.enabled) {
|
|
15469
15562
|
if (!body.notion.token?.trim()) return c.json({
|
|
15470
15563
|
success: false,
|
|
15471
|
-
error: "
|
|
15564
|
+
error: t("server.notionTokenRequired")
|
|
15472
15565
|
}, 400);
|
|
15473
15566
|
for (const [schemaName, schemaConfig] of Object.entries(body.notion.schemas ?? {})) {
|
|
15474
15567
|
if (typeof schemaConfig.databaseId === "string") schemaConfig.databaseId = parseNotionDatabaseId(schemaConfig.databaseId);
|
|
15475
15568
|
if (!schemaConfig.databaseId?.trim()) return c.json({
|
|
15476
15569
|
success: false,
|
|
15477
|
-
error:
|
|
15570
|
+
error: t("server.notionDbIdRequired", { name: schemaName })
|
|
15478
15571
|
}, 400);
|
|
15479
15572
|
}
|
|
15480
15573
|
}
|
|
@@ -15626,21 +15719,21 @@ function dataRoutes(config) {
|
|
|
15626
15719
|
return c.json({ error: error instanceof Error ? error.message : String(error) }, 500);
|
|
15627
15720
|
}
|
|
15628
15721
|
});
|
|
15629
|
-
app.get("/data/tables/:name", zValidator("param", tableParamSchema, invalidParamResponse$1("
|
|
15722
|
+
app.get("/data/tables/:name", zValidator("param", tableParamSchema, invalidParamResponse$1(t("server.invalidTableName"))), zValidator("query", tableQuerySchema), async (c) => {
|
|
15630
15723
|
const { name: tableName } = c.req.valid("param");
|
|
15631
15724
|
const { page, pageSize, search, sortField, sortOrder, all } = c.req.valid("query");
|
|
15632
15725
|
let db;
|
|
15633
15726
|
try {
|
|
15634
15727
|
db = createReadonlyQueryDb(config.databasePath);
|
|
15635
15728
|
} catch {
|
|
15636
|
-
return c.json({ error: "
|
|
15729
|
+
return c.json({ error: t("server.dbNotFound") }, 400);
|
|
15637
15730
|
}
|
|
15638
15731
|
try {
|
|
15639
15732
|
if ((await sql`
|
|
15640
15733
|
select name
|
|
15641
15734
|
from sqlite_master
|
|
15642
15735
|
where type = 'table' and name = ${tableName}
|
|
15643
|
-
`.execute(db)).rows.length === 0) return c.json({ error:
|
|
15736
|
+
`.execute(db)).rows.length === 0) return c.json({ error: t("server.tableNotFound", { name: tableName }) }, 404);
|
|
15644
15737
|
const columns = (await sql`
|
|
15645
15738
|
pragma table_info(${sql.table(tableName)})
|
|
15646
15739
|
`.execute(db)).rows.map((col) => ({
|
|
@@ -15708,7 +15801,7 @@ function dataRoutes(config) {
|
|
|
15708
15801
|
await db.destroy();
|
|
15709
15802
|
}
|
|
15710
15803
|
});
|
|
15711
|
-
app.get("/data/:name", zValidator("param", extractionFileParamSchema, invalidParamResponse$1("
|
|
15804
|
+
app.get("/data/:name", zValidator("param", extractionFileParamSchema, invalidParamResponse$1(t("server.invalidFileName"))), async (c) => {
|
|
15712
15805
|
const { name: name$1 } = c.req.valid("param");
|
|
15713
15806
|
const filePath = path.join(extractedDir, name$1);
|
|
15714
15807
|
try {
|
|
@@ -15719,31 +15812,31 @@ function dataRoutes(config) {
|
|
|
15719
15812
|
name: name$1
|
|
15720
15813
|
});
|
|
15721
15814
|
} catch {
|
|
15722
|
-
return c.json({ error: "
|
|
15815
|
+
return c.json({ error: t("server.extractionNotFound") }, 404);
|
|
15723
15816
|
}
|
|
15724
15817
|
});
|
|
15725
|
-
app.post("/data/:name/notion/retry", zValidator("param", extractionFileParamSchema, invalidParamResponse$1("
|
|
15818
|
+
app.post("/data/:name/notion/retry", zValidator("param", extractionFileParamSchema, invalidParamResponse$1(t("server.invalidFileName"))), async (c) => {
|
|
15726
15819
|
const { name: name$1 } = c.req.valid("param");
|
|
15727
15820
|
const filePath = path.join(extractedDir, name$1);
|
|
15728
15821
|
const schemaName = schemaNameFromExtractionFile(name$1);
|
|
15729
15822
|
if (!schemaName) return c.json({
|
|
15730
15823
|
success: false,
|
|
15731
|
-
error: "
|
|
15824
|
+
error: t("server.cannotInferSchema")
|
|
15732
15825
|
}, 400);
|
|
15733
15826
|
const aiConfig = await readAIConfig(aiexDir);
|
|
15734
15827
|
if (!aiConfig?.notion?.enabled) return c.json({
|
|
15735
15828
|
success: false,
|
|
15736
|
-
error: "
|
|
15829
|
+
error: t("errors.notion.notEnabled")
|
|
15737
15830
|
}, 400);
|
|
15738
15831
|
if (!aiConfig.notion.schemas?.[schemaName]?.databaseId?.trim()) return c.json({
|
|
15739
15832
|
success: false,
|
|
15740
|
-
error:
|
|
15833
|
+
error: t("errors.notion.noSchemaConfig", { name: schemaName })
|
|
15741
15834
|
}, 400);
|
|
15742
15835
|
try {
|
|
15743
15836
|
const data = await readFile(filePath);
|
|
15744
15837
|
if (!data || typeof data !== "object" || Array.isArray(data)) return c.json({
|
|
15745
15838
|
success: false,
|
|
15746
|
-
error: "
|
|
15839
|
+
error: t("errors.ai.extractionNotObject")
|
|
15747
15840
|
}, 400);
|
|
15748
15841
|
const page = await writeNotionPage(aiConfig.notion, schemaName, data);
|
|
15749
15842
|
const notionPages = [{
|
|
@@ -15837,15 +15930,15 @@ function extractRoutes(config) {
|
|
|
15837
15930
|
const file = getFormFile(body.file);
|
|
15838
15931
|
if (!schemaName) return c.json({
|
|
15839
15932
|
success: false,
|
|
15840
|
-
error: "
|
|
15933
|
+
error: t("server.schemaRequired")
|
|
15841
15934
|
}, 400);
|
|
15842
15935
|
if (!text$1 && !file) return c.json({
|
|
15843
15936
|
success: false,
|
|
15844
|
-
error: "
|
|
15937
|
+
error: t("server.provideTextOrFile")
|
|
15845
15938
|
}, 400);
|
|
15846
15939
|
if (text$1 && file) return c.json({
|
|
15847
15940
|
success: false,
|
|
15848
|
-
error: "
|
|
15941
|
+
error: t("server.conflictTextAndFile")
|
|
15849
15942
|
}, 400);
|
|
15850
15943
|
let source;
|
|
15851
15944
|
if (file) {
|
|
@@ -15871,20 +15964,20 @@ function extractRoutes(config) {
|
|
|
15871
15964
|
const aiConfig = await readAIConfig(aiexDir);
|
|
15872
15965
|
if (!aiConfig) return c.json({
|
|
15873
15966
|
success: false,
|
|
15874
|
-
error: "
|
|
15967
|
+
error: t("server.aiConfigNotFound")
|
|
15875
15968
|
}, 400);
|
|
15876
15969
|
if (!aiConfig.provider.apiKey) return c.json({
|
|
15877
15970
|
success: false,
|
|
15878
|
-
error: "
|
|
15971
|
+
error: t("server.apiKeyNotConfigured")
|
|
15879
15972
|
}, 400);
|
|
15880
15973
|
if (!aiConfig.provider.models?.length) return c.json({
|
|
15881
15974
|
success: false,
|
|
15882
|
-
error: "
|
|
15975
|
+
error: t("server.noModelsConfigured")
|
|
15883
15976
|
}, 400);
|
|
15884
15977
|
const modelOverride = modelName ? aiConfig.provider.models.find((model) => model.name === modelName) : void 0;
|
|
15885
15978
|
if (modelName && !modelOverride) return c.json({
|
|
15886
15979
|
success: false,
|
|
15887
|
-
error:
|
|
15980
|
+
error: t("server.modelNotFound", { name: modelName })
|
|
15888
15981
|
}, 400);
|
|
15889
15982
|
const result = await runAuditedExtraction({
|
|
15890
15983
|
aiexDir,
|
|
@@ -15924,25 +16017,25 @@ function extractRoutes(config) {
|
|
|
15924
16017
|
const original = await readExtractionAuditRecord(aiexDir, c.req.param("id"));
|
|
15925
16018
|
if (!original) return c.json({
|
|
15926
16019
|
success: false,
|
|
15927
|
-
error: "
|
|
16020
|
+
error: t("server.extractionRecordNotFound")
|
|
15928
16021
|
}, 404);
|
|
15929
16022
|
const aiConfig = await readAIConfig(aiexDir);
|
|
15930
16023
|
if (!aiConfig) return c.json({
|
|
15931
16024
|
success: false,
|
|
15932
|
-
error: "
|
|
16025
|
+
error: t("server.aiConfigNotFound")
|
|
15933
16026
|
}, 400);
|
|
15934
16027
|
if (!aiConfig.provider.apiKey) return c.json({
|
|
15935
16028
|
success: false,
|
|
15936
|
-
error: "
|
|
16029
|
+
error: t("server.apiKeyNotConfigured")
|
|
15937
16030
|
}, 400);
|
|
15938
16031
|
if (!aiConfig.provider.models?.length) return c.json({
|
|
15939
16032
|
success: false,
|
|
15940
|
-
error: "
|
|
16033
|
+
error: t("server.noModelsConfigured")
|
|
15941
16034
|
}, 400);
|
|
15942
16035
|
const modelOverride = original.modelName ? aiConfig.provider.models.find((m) => m.name === original.modelName) : void 0;
|
|
15943
16036
|
if (original.modelName && !modelOverride) return c.json({
|
|
15944
16037
|
success: false,
|
|
15945
|
-
error:
|
|
16038
|
+
error: t("server.modelNotFound", { name: original.modelName })
|
|
15946
16039
|
}, 400);
|
|
15947
16040
|
const source = original.source.type === "file" && original.source.filePath ? {
|
|
15948
16041
|
type: "file",
|
|
@@ -15981,7 +16074,7 @@ function extractRoutes(config) {
|
|
|
15981
16074
|
const id = c.req.param("id");
|
|
15982
16075
|
if (!await readExtractionAuditRecord(aiexDir, id)) return c.json({
|
|
15983
16076
|
success: false,
|
|
15984
|
-
error: "
|
|
16077
|
+
error: t("server.extractionRecordNotFound")
|
|
15985
16078
|
}, 404);
|
|
15986
16079
|
await deleteExtractionAuditRecord(aiexDir, id);
|
|
15987
16080
|
return c.json({ success: true });
|
|
@@ -16010,16 +16103,16 @@ function schemaRoutes(config) {
|
|
|
16010
16103
|
const jsonFiles = (await fs.readdir(schemaDir)).filter((f) => f.endsWith(".json"));
|
|
16011
16104
|
return c.json(jsonFiles);
|
|
16012
16105
|
});
|
|
16013
|
-
app.get("/schema/:name", zValidator("param", schemaFileParamSchema, invalidParamResponse("
|
|
16106
|
+
app.get("/schema/:name", zValidator("param", schemaFileParamSchema, invalidParamResponse(t("server.invalidTableName"))), async (c) => {
|
|
16014
16107
|
const { name: name$1 } = c.req.valid("param");
|
|
16015
16108
|
const filePath = path.join(schemaDir, name$1);
|
|
16016
16109
|
try {
|
|
16017
16110
|
return c.json(await readFile(filePath));
|
|
16018
16111
|
} catch {
|
|
16019
|
-
return c.json({ error: "
|
|
16112
|
+
return c.json({ error: t("server.schemaNotFound") }, 404);
|
|
16020
16113
|
}
|
|
16021
16114
|
});
|
|
16022
|
-
app.post("/schema/:name", zValidator("param", schemaFileParamSchema, invalidParamResponse("
|
|
16115
|
+
app.post("/schema/:name", zValidator("param", schemaFileParamSchema, invalidParamResponse(t("server.invalidTableName"))), async (c) => {
|
|
16023
16116
|
const { name: name$1 } = c.req.valid("param");
|
|
16024
16117
|
const filePath = path.join(schemaDir, name$1);
|
|
16025
16118
|
try {
|
|
@@ -16035,10 +16128,10 @@ function schemaRoutes(config) {
|
|
|
16035
16128
|
} catch {}
|
|
16036
16129
|
return c.json({ success: true });
|
|
16037
16130
|
} catch {
|
|
16038
|
-
return c.json({ error: "
|
|
16131
|
+
return c.json({ error: t("server.saveSchemaFailed") }, 500);
|
|
16039
16132
|
}
|
|
16040
16133
|
});
|
|
16041
|
-
app.get("/prompt-snapshot/:name", zValidator("param", tableNameParamSchema, invalidParamResponse("
|
|
16134
|
+
app.get("/prompt-snapshot/:name", zValidator("param", tableNameParamSchema, invalidParamResponse(t("server.invalidTableName"))), async (c) => {
|
|
16042
16135
|
const { name: name$1 } = c.req.valid("param");
|
|
16043
16136
|
const aiexDir = path.dirname(schemaDir);
|
|
16044
16137
|
const snapshotPath = path.join(aiexDir, "extracted", `${name$1}.prompt.md`);
|
|
@@ -16051,11 +16144,11 @@ function schemaRoutes(config) {
|
|
|
16051
16144
|
} catch {
|
|
16052
16145
|
return c.json({
|
|
16053
16146
|
success: false,
|
|
16054
|
-
error: "
|
|
16147
|
+
error: t("server.promptSnapshotNotAvailable")
|
|
16055
16148
|
}, 404);
|
|
16056
16149
|
}
|
|
16057
16150
|
});
|
|
16058
|
-
app.delete("/schema/:name", zValidator("param", schemaFileParamSchema, invalidParamResponse("
|
|
16151
|
+
app.delete("/schema/:name", zValidator("param", schemaFileParamSchema, invalidParamResponse(t("server.invalidTableName"))), async (c) => {
|
|
16059
16152
|
const { name: name$1 } = c.req.valid("param");
|
|
16060
16153
|
const filePath = path.join(schemaDir, name$1);
|
|
16061
16154
|
try {
|
|
@@ -16071,7 +16164,7 @@ function schemaRoutes(config) {
|
|
|
16071
16164
|
await fs.unlink(filePath);
|
|
16072
16165
|
return c.json({ success: true });
|
|
16073
16166
|
} catch {
|
|
16074
|
-
return c.json({ error: "
|
|
16167
|
+
return c.json({ error: t("server.deleteSchemaFailed") }, 500);
|
|
16075
16168
|
}
|
|
16076
16169
|
});
|
|
16077
16170
|
app.post("/migrate", async (c) => {
|
|
@@ -16082,7 +16175,7 @@ function schemaRoutes(config) {
|
|
|
16082
16175
|
const status = result.schemaCount === 0 ? 400 : 500;
|
|
16083
16176
|
return c.json({
|
|
16084
16177
|
success: false,
|
|
16085
|
-
error: result.error || "
|
|
16178
|
+
error: result.error || t("server.migrationFailed")
|
|
16086
16179
|
}, status);
|
|
16087
16180
|
}
|
|
16088
16181
|
return c.json({
|
|
@@ -16123,7 +16216,7 @@ function createApp(config, staticDir) {
|
|
|
16123
16216
|
html = await fs.readFile(`${staticDir}/index.html`, "utf-8");
|
|
16124
16217
|
} catch {
|
|
16125
16218
|
html = `<!DOCTYPE html>
|
|
16126
|
-
<html lang="
|
|
16219
|
+
<html lang="en">
|
|
16127
16220
|
<head>
|
|
16128
16221
|
<meta charset="UTF-8" />
|
|
16129
16222
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
@@ -16173,31 +16266,32 @@ async function startWebServer(input) {
|
|
|
16173
16266
|
const webCommand = defineCommand({
|
|
16174
16267
|
meta: {
|
|
16175
16268
|
name: "web",
|
|
16176
|
-
description: "
|
|
16269
|
+
description: t("command.web.description")
|
|
16177
16270
|
},
|
|
16178
16271
|
args: { port: {
|
|
16179
16272
|
type: "string",
|
|
16180
16273
|
alias: "p",
|
|
16181
|
-
description: "
|
|
16274
|
+
description: t("command.web.args.port"),
|
|
16182
16275
|
default: "13000"
|
|
16183
16276
|
} },
|
|
16184
16277
|
async run({ args }) {
|
|
16278
|
+
await initI18n();
|
|
16185
16279
|
intro(pc.inverse(" aiex web "));
|
|
16186
16280
|
const cwd = process.cwd();
|
|
16187
16281
|
const port = Number(args.port) || 13e3;
|
|
16188
16282
|
const config = createMigrationConfig(cwd);
|
|
16189
16283
|
const s = spinner();
|
|
16190
|
-
s.start("
|
|
16284
|
+
s.start(t("command.web.starting"));
|
|
16191
16285
|
await startWebServer({
|
|
16192
16286
|
config,
|
|
16193
16287
|
port,
|
|
16194
16288
|
onStarted(info) {
|
|
16195
|
-
s.stop(
|
|
16196
|
-
consola.info(
|
|
16197
|
-
consola.info("
|
|
16289
|
+
s.stop(t("command.web.serverRunning", { url: pc.cyan(info.url) }));
|
|
16290
|
+
consola.info(t("command.web.schemaDir", { path: pc.dim(info.schemaPath) }));
|
|
16291
|
+
consola.info(t("command.web.pressCtrlC"));
|
|
16198
16292
|
},
|
|
16199
16293
|
onOpenFailed(url) {
|
|
16200
|
-
consola.warn(
|
|
16294
|
+
consola.warn(t("command.web.browserOpenFailed", { url }));
|
|
16201
16295
|
}
|
|
16202
16296
|
});
|
|
16203
16297
|
}
|
|
@@ -16217,6 +16311,7 @@ const subCommands = {
|
|
|
16217
16311
|
|
|
16218
16312
|
//#endregion
|
|
16219
16313
|
//#region src/cli.ts
|
|
16314
|
+
await initI18n();
|
|
16220
16315
|
seedConfig(createConfig());
|
|
16221
16316
|
updateNotifier({ pkg: package_default }).notify();
|
|
16222
16317
|
process.on("uncaughtException", (error) => {
|
|
@@ -16229,7 +16324,7 @@ process.on("unhandledRejection", (reason) => {
|
|
|
16229
16324
|
process.exit(1);
|
|
16230
16325
|
});
|
|
16231
16326
|
if (process.argv[2] === "_complete") {
|
|
16232
|
-
const { getCompletions } = await import("./completions-
|
|
16327
|
+
const { getCompletions } = await import("./completions-Bh0DOngr.mjs");
|
|
16233
16328
|
const suggestions = getCompletions(subCommands, process.argv.slice(4));
|
|
16234
16329
|
for (const s of suggestions) process.stdout.write(`${s}\n`);
|
|
16235
16330
|
process.exit(0);
|