@carllee1983/dbcli 1.43.0 → 1.44.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/.claude-plugin/plugin.json +1 -1
- package/.codex-plugin/plugin.json +1 -1
- package/.cursor-plugin/plugin.json +1 -1
- package/CHANGELOG.md +20 -0
- package/dist/agent-core.d.ts +12 -2
- package/dist/agent-core.mjs +16 -5
- package/dist/cli.mjs +31 -22
- package/dist/core.mjs +12 -4
- package/gemini-extension.json +1 -1
- package/package.json +1 -1
- package/plugins/dbcli-agent/.codex-plugin/plugin.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -5,6 +5,26 @@ All notable changes to dbcli are documented here.
|
|
|
5
5
|
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
|
6
6
|
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
7
7
|
|
|
8
|
+
## [1.44.1] - 2026-08-02 - `agent-core` 的 `loadEnvFile` 改用 node:fs,可在 Node 執行
|
|
9
|
+
|
|
10
|
+
### Fixed
|
|
11
|
+
|
|
12
|
+
- **`loadEnvFile` 不再依賴 `Bun.file`。** `./agent-core` 存在的理由是給下游 agent CLI 共用,而那些工具不一定跑在 Bun 上;`loadEnvFile` 內部呼叫 `Bun.file()`,在 Node 下直接 `ReferenceError: Bun is not defined`,使整個匯出對第一個 Node 消費者(logq)不可用。改以 `node:fs/promises` 讀檔,解析與「不覆寫既有 `process.env`」的行為完全不變;檔案不存在仍拋 `ConfigError`。其餘五個匯出本來就沒有 runtime 相依,不受影響。
|
|
13
|
+
|
|
14
|
+
### Added
|
|
15
|
+
|
|
16
|
+
- **Node runtime 契約測試。** 本 repo 的測試全部跑在 Bun 上,所以 agent-core 裡的 Bun-only 呼叫對它們是隱形的 —— 這正是這個 bug 得以發布的原因。新增的契約測試會 spawn 真正的 `node` 行程去 import 建置後的 `dist/agent-core.mjs`,逐一呼叫每個匯出。還原修正後此測試會失敗(已驗證),因此這個失敗模式不會再次出貨。
|
|
17
|
+
|
|
18
|
+
### Changed
|
|
19
|
+
|
|
20
|
+
- **同步跨平台發版 metadata。** npm package、Codex/Claude/Cursor plugin、packaged Codex plugin 與 Gemini extension 統一為 `1.44.1`。
|
|
21
|
+
|
|
22
|
+
## [1.44.0] - 2026-08-02 - agent-core 補上錯誤型別與 env reference 型別
|
|
23
|
+
|
|
24
|
+
### Added
|
|
25
|
+
|
|
26
|
+
- **`./agent-core` 匯出 `ConfigError` 與 `EnvReference`。** 下游工具原本無法用 `instanceof` 判別 env reference 解析失敗,只能比對錯誤訊息字串;也無法引用 `{ $env: string }` 的型別名稱,只能各自重複定義一個結構相同的介面。兩者都是既有模組早已匯出、只是沒有出現在 `public.ts` 的疏漏。runtime interface 因此從五項變六項,型別從三項變四項,皆為加法變更。
|
|
27
|
+
|
|
8
28
|
## [1.43.0] - 2026-08-02 - Agent Core、查詢完整性與跨平台修復
|
|
9
29
|
|
|
10
30
|
### Added
|
package/dist/agent-core.d.ts
CHANGED
|
@@ -1,6 +1,12 @@
|
|
|
1
1
|
// Generated by dts-bundle-generator v9.5.1
|
|
2
2
|
|
|
3
|
-
/**
|
|
3
|
+
/**
|
|
4
|
+
* Load a file into process.env without overwriting existing values.
|
|
5
|
+
*
|
|
6
|
+
* Uses `node:fs` rather than `Bun.file` on purpose: `agent-core` is the public
|
|
7
|
+
* surface downstream tools consume, and those tools do not necessarily run on
|
|
8
|
+
* Bun. A Bun-only builtin here makes the whole export unusable for them.
|
|
9
|
+
*/
|
|
4
10
|
export declare function loadEnvFile(filePath: string): Promise<void>;
|
|
5
11
|
export interface AppliedLimitMetadata {
|
|
6
12
|
/** True only when the caller fetched and removed an additional row. */
|
|
@@ -23,10 +29,14 @@ export interface ConnectionSelectorInputs {
|
|
|
23
29
|
export declare function resolveConnectionSelector(inputs: ConnectionSelectorInputs): string | undefined;
|
|
24
30
|
/** Parse a comma-separated selector into ordered, unique names. */
|
|
25
31
|
export declare function parseConnectionNames(selector: string): string[];
|
|
26
|
-
interface EnvReference {
|
|
32
|
+
export interface EnvReference {
|
|
27
33
|
$env: string;
|
|
28
34
|
}
|
|
29
35
|
/** Resolve a literal or environment reference with a field-specific error. */
|
|
30
36
|
export declare function resolveEnvRef(value: string | EnvReference, fieldName: string, env?: Record<string, string | undefined>): string;
|
|
37
|
+
/** Configuration error shared by agent-facing command-line tools. */
|
|
38
|
+
export declare class ConfigError extends Error {
|
|
39
|
+
constructor(message: string);
|
|
40
|
+
}
|
|
31
41
|
|
|
32
42
|
export {};
|
package/dist/agent-core.mjs
CHANGED
|
@@ -1,4 +1,7 @@
|
|
|
1
1
|
// @bun
|
|
2
|
+
// src/agent-core/env-loader.ts
|
|
3
|
+
import { readFile } from "fs/promises";
|
|
4
|
+
|
|
2
5
|
// src/agent-core/errors.ts
|
|
3
6
|
class ConfigError extends Error {
|
|
4
7
|
constructor(message) {
|
|
@@ -30,10 +33,17 @@ function parseEnvContent(content) {
|
|
|
30
33
|
return entries;
|
|
31
34
|
}
|
|
32
35
|
async function loadEnvFile(filePath) {
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
36
|
+
let content;
|
|
37
|
+
try {
|
|
38
|
+
content = await readFile(filePath, "utf8");
|
|
39
|
+
} catch (cause) {
|
|
40
|
+
const code = cause.code;
|
|
41
|
+
if (code === "ENOENT" || code === "EISDIR") {
|
|
42
|
+
throw new ConfigError(`\u627E\u4E0D\u5230 env \u6A94\u6848\uFF1A${filePath}`);
|
|
43
|
+
}
|
|
44
|
+
throw cause;
|
|
45
|
+
}
|
|
46
|
+
for (const [key, value] of parseEnvContent(content)) {
|
|
37
47
|
if (process.env[key] === undefined)
|
|
38
48
|
process.env[key] = value;
|
|
39
49
|
}
|
|
@@ -88,5 +98,6 @@ export {
|
|
|
88
98
|
resolveEnvRef,
|
|
89
99
|
resolveConnectionSelector,
|
|
90
100
|
parseConnectionNames,
|
|
91
|
-
loadEnvFile
|
|
101
|
+
loadEnvFile,
|
|
102
|
+
ConfigError
|
|
92
103
|
};
|
package/dist/cli.mjs
CHANGED
|
@@ -52,7 +52,7 @@ var package_default;
|
|
|
52
52
|
var init_package = __esm(() => {
|
|
53
53
|
package_default = {
|
|
54
54
|
name: "@carllee1983/dbcli",
|
|
55
|
-
version: "1.
|
|
55
|
+
version: "1.44.1",
|
|
56
56
|
description: "Database CLI for AI agents",
|
|
57
57
|
type: "module",
|
|
58
58
|
publishConfig: {
|
|
@@ -7284,6 +7284,7 @@ var init_errors3 = __esm(() => {
|
|
|
7284
7284
|
});
|
|
7285
7285
|
|
|
7286
7286
|
// src/agent-core/env-loader.ts
|
|
7287
|
+
import { readFile } from "fs/promises";
|
|
7287
7288
|
function parseEnvContent(content) {
|
|
7288
7289
|
const entries = [];
|
|
7289
7290
|
for (const line of content.split(`
|
|
@@ -7304,10 +7305,17 @@ function parseEnvContent(content) {
|
|
|
7304
7305
|
return entries;
|
|
7305
7306
|
}
|
|
7306
7307
|
async function loadEnvFile(filePath) {
|
|
7307
|
-
|
|
7308
|
-
|
|
7309
|
-
|
|
7310
|
-
|
|
7308
|
+
let content;
|
|
7309
|
+
try {
|
|
7310
|
+
content = await readFile(filePath, "utf8");
|
|
7311
|
+
} catch (cause) {
|
|
7312
|
+
const code = cause.code;
|
|
7313
|
+
if (code === "ENOENT" || code === "EISDIR") {
|
|
7314
|
+
throw new ConfigError(`\u627E\u4E0D\u5230 env \u6A94\u6848\uFF1A${filePath}`);
|
|
7315
|
+
}
|
|
7316
|
+
throw cause;
|
|
7317
|
+
}
|
|
7318
|
+
for (const [key, value] of parseEnvContent(content)) {
|
|
7311
7319
|
if (process.env[key] === undefined)
|
|
7312
7320
|
process.env[key] = value;
|
|
7313
7321
|
}
|
|
@@ -7517,6 +7525,7 @@ var init_env_ref = __esm(() => {
|
|
|
7517
7525
|
var init_public = __esm(() => {
|
|
7518
7526
|
init_env_loader();
|
|
7519
7527
|
init_env_ref();
|
|
7528
|
+
init_errors2();
|
|
7520
7529
|
});
|
|
7521
7530
|
|
|
7522
7531
|
// node_modules/lru-cache/dist/esm/node/index.min.js
|
|
@@ -18703,7 +18712,7 @@ var init_assert_artifact = __esm(() => {
|
|
|
18703
18712
|
});
|
|
18704
18713
|
|
|
18705
18714
|
// src/core/verification/reader.ts
|
|
18706
|
-
import { lstat, readdir as readdir2, readFile } from "fs/promises";
|
|
18715
|
+
import { lstat, readdir as readdir2, readFile as readFile2 } from "fs/promises";
|
|
18707
18716
|
import { join as join15, isAbsolute, resolve as resolve3, sep as sep2 } from "path";
|
|
18708
18717
|
function isArtifactFilename(name2) {
|
|
18709
18718
|
return /^verification-.*\.json$/.test(name2);
|
|
@@ -18807,7 +18816,7 @@ async function readVerificationArtifacts(storageRoot) {
|
|
|
18807
18816
|
if (!stats.isFile()) {
|
|
18808
18817
|
throw new Error("artifact path is not a regular file");
|
|
18809
18818
|
}
|
|
18810
|
-
const raw = await
|
|
18819
|
+
const raw = await readFile2(path4, "utf8");
|
|
18811
18820
|
const parsed = JSON.parse(raw);
|
|
18812
18821
|
const artifact = validateVerificationArtifact(parsed);
|
|
18813
18822
|
artifacts.push({ path: path4, filename, artifact });
|
|
@@ -19393,7 +19402,7 @@ var init_rotation = __esm(() => {
|
|
|
19393
19402
|
});
|
|
19394
19403
|
|
|
19395
19404
|
// src/core/audit/logger.ts
|
|
19396
|
-
import { appendFile, mkdir as mkdir7, readFile as
|
|
19405
|
+
import { appendFile, mkdir as mkdir7, readFile as readFile3, stat } from "fs/promises";
|
|
19397
19406
|
import { join as join16 } from "path";
|
|
19398
19407
|
import { randomUUID } from "crypto";
|
|
19399
19408
|
|
|
@@ -19521,7 +19530,7 @@ class AuditLogger {
|
|
|
19521
19530
|
try {
|
|
19522
19531
|
const s = await stat(this.auditFilePath);
|
|
19523
19532
|
this.currentSizeBytes = s.size;
|
|
19524
|
-
const raw = await
|
|
19533
|
+
const raw = await readFile3(this.auditFilePath, "utf8");
|
|
19525
19534
|
this.currentEntryCount = raw.split(`
|
|
19526
19535
|
`).filter(Boolean).length;
|
|
19527
19536
|
} catch {
|
|
@@ -19547,7 +19556,7 @@ var init_logger2 = __esm(() => {
|
|
|
19547
19556
|
});
|
|
19548
19557
|
|
|
19549
19558
|
// src/core/audit/session-id.ts
|
|
19550
|
-
import { mkdir as mkdir8, readFile as
|
|
19559
|
+
import { mkdir as mkdir8, readFile as readFile4, rename as rename3, stat as stat2, writeFile as writeFile2 } from "fs/promises";
|
|
19551
19560
|
import { randomBytes as randomBytes2 } from "crypto";
|
|
19552
19561
|
import { dirname as dirname4, join as join17 } from "path";
|
|
19553
19562
|
function generateSessionId(pid, nowMs) {
|
|
@@ -19562,7 +19571,7 @@ async function readSessionIdFile(storagePath) {
|
|
|
19562
19571
|
return null;
|
|
19563
19572
|
}
|
|
19564
19573
|
try {
|
|
19565
|
-
const raw = await
|
|
19574
|
+
const raw = await readFile4(target, "utf8");
|
|
19566
19575
|
const parsed = JSON.parse(raw);
|
|
19567
19576
|
if (parsed && typeof parsed.sessionId === "string" && typeof parsed.pid === "number" && typeof parsed.createdAt === "string") {
|
|
19568
19577
|
return {
|
|
@@ -21347,7 +21356,7 @@ var init_render_markdown = __esm(() => {
|
|
|
21347
21356
|
});
|
|
21348
21357
|
|
|
21349
21358
|
// src/core/recovery/last-envelope.ts
|
|
21350
|
-
import { writeFile as writeFile3, readFile as
|
|
21359
|
+
import { writeFile as writeFile3, readFile as readFile5, rename as rename4, mkdir as mkdir9, stat as stat3 } from "fs/promises";
|
|
21351
21360
|
import { dirname as dirname5, join as join18 } from "path";
|
|
21352
21361
|
import { randomUUID as randomUUID2 } from "crypto";
|
|
21353
21362
|
function sanitizeCommandSummary(argv) {
|
|
@@ -21379,7 +21388,7 @@ async function readLastEnvelope(cwd) {
|
|
|
21379
21388
|
return null;
|
|
21380
21389
|
}
|
|
21381
21390
|
try {
|
|
21382
|
-
const raw = await
|
|
21391
|
+
const raw = await readFile5(target, "utf8");
|
|
21383
21392
|
return JSON.parse(raw);
|
|
21384
21393
|
} catch {
|
|
21385
21394
|
return null;
|
|
@@ -21394,7 +21403,7 @@ async function readLastEnvelopeRaw(cwd) {
|
|
|
21394
21403
|
}
|
|
21395
21404
|
let raw;
|
|
21396
21405
|
try {
|
|
21397
|
-
raw = await
|
|
21406
|
+
raw = await readFile5(target, "utf8");
|
|
21398
21407
|
} catch {
|
|
21399
21408
|
return null;
|
|
21400
21409
|
}
|
|
@@ -81720,11 +81729,11 @@ var init_suggest_commands = __esm(() => {
|
|
|
81720
81729
|
});
|
|
81721
81730
|
|
|
81722
81731
|
// src/core/audit/reader.ts
|
|
81723
|
-
import { readFile as
|
|
81732
|
+
import { readFile as readFile6, readdir as readdir4 } from "fs/promises";
|
|
81724
81733
|
async function readSingle(path4) {
|
|
81725
81734
|
let raw;
|
|
81726
81735
|
try {
|
|
81727
|
-
raw = await
|
|
81736
|
+
raw = await readFile6(path4, "utf8");
|
|
81728
81737
|
} catch (err) {
|
|
81729
81738
|
if (err.code === "ENOENT")
|
|
81730
81739
|
return [];
|
|
@@ -83948,7 +83957,7 @@ var init_guide_missing_index = __esm(() => {
|
|
|
83948
83957
|
});
|
|
83949
83958
|
|
|
83950
83959
|
// src/core/explain/bulk-runner.ts
|
|
83951
|
-
import { readFile as
|
|
83960
|
+
import { readFile as readFile7 } from "fs/promises";
|
|
83952
83961
|
import path4 from "path";
|
|
83953
83962
|
import { existsSync } from "fs";
|
|
83954
83963
|
async function resolveBulkInputs(inputs, deps) {
|
|
@@ -83991,7 +84000,7 @@ async function resolveBulkInputs(inputs, deps) {
|
|
|
83991
84000
|
if (!existsSync(ref)) {
|
|
83992
84001
|
throw new Error(`No such file or saved query: '${ref}'`);
|
|
83993
84002
|
}
|
|
83994
|
-
appendFileInputs(out, ref, await
|
|
84003
|
+
appendFileInputs(out, ref, await readFile7(ref, "utf-8"));
|
|
83995
84004
|
}
|
|
83996
84005
|
return out;
|
|
83997
84006
|
}
|
|
@@ -92872,7 +92881,7 @@ var init_sql_metadata = __esm(() => {
|
|
|
92872
92881
|
});
|
|
92873
92882
|
|
|
92874
92883
|
// src/proxy/events.ts
|
|
92875
|
-
import { appendFile as appendFile2, mkdir as mkdir15, readFile as
|
|
92884
|
+
import { appendFile as appendFile2, mkdir as mkdir15, readFile as readFile8, stat as stat8 } from "fs/promises";
|
|
92876
92885
|
import { dirname as dirname11 } from "path";
|
|
92877
92886
|
function hasSql(e) {
|
|
92878
92887
|
return e.type === "query_observed" || e.type === "query_completed" || e.type === "query_errored";
|
|
@@ -92936,7 +92945,7 @@ class EventWriter {
|
|
|
92936
92945
|
try {
|
|
92937
92946
|
const s = await stat8(this.path);
|
|
92938
92947
|
this.currentSizeBytes = s.size;
|
|
92939
|
-
const raw = await
|
|
92948
|
+
const raw = await readFile8(this.path, "utf8");
|
|
92940
92949
|
this.currentEntryCount = raw.split(`
|
|
92941
92950
|
`).filter(Boolean).length;
|
|
92942
92951
|
} catch {
|
|
@@ -93533,7 +93542,7 @@ var init_server = __esm(() => {
|
|
|
93533
93542
|
});
|
|
93534
93543
|
|
|
93535
93544
|
// src/proxy/event-reader.ts
|
|
93536
|
-
import { readFile as
|
|
93545
|
+
import { readFile as readFile9 } from "fs/promises";
|
|
93537
93546
|
async function readEvents(path5, opts) {
|
|
93538
93547
|
const candidates = opts.includeRotated ? [path5, `${path5}.1`] : [path5];
|
|
93539
93548
|
const files = [];
|
|
@@ -93542,7 +93551,7 @@ async function readEvents(path5, opts) {
|
|
|
93542
93551
|
for (const file of candidates) {
|
|
93543
93552
|
let raw;
|
|
93544
93553
|
try {
|
|
93545
|
-
raw = await
|
|
93554
|
+
raw = await readFile9(file, "utf8");
|
|
93546
93555
|
} catch (err) {
|
|
93547
93556
|
if (err.code !== "ENOENT")
|
|
93548
93557
|
throw err;
|
package/dist/core.mjs
CHANGED
|
@@ -21714,6 +21714,7 @@ class ConfigError extends Error {
|
|
|
21714
21714
|
}
|
|
21715
21715
|
}
|
|
21716
21716
|
// src/agent-core/env-loader.ts
|
|
21717
|
+
import { readFile as readFile3 } from "fs/promises";
|
|
21717
21718
|
function parseEnvContent(content) {
|
|
21718
21719
|
const entries = [];
|
|
21719
21720
|
for (const line of content.split(`
|
|
@@ -21734,10 +21735,17 @@ function parseEnvContent(content) {
|
|
|
21734
21735
|
return entries;
|
|
21735
21736
|
}
|
|
21736
21737
|
async function loadEnvFile(filePath) {
|
|
21737
|
-
|
|
21738
|
-
|
|
21739
|
-
|
|
21740
|
-
|
|
21738
|
+
let content;
|
|
21739
|
+
try {
|
|
21740
|
+
content = await readFile3(filePath, "utf8");
|
|
21741
|
+
} catch (cause) {
|
|
21742
|
+
const code = cause.code;
|
|
21743
|
+
if (code === "ENOENT" || code === "EISDIR") {
|
|
21744
|
+
throw new ConfigError(`\u627E\u4E0D\u5230 env \u6A94\u6848\uFF1A${filePath}`);
|
|
21745
|
+
}
|
|
21746
|
+
throw cause;
|
|
21747
|
+
}
|
|
21748
|
+
for (const [key, value] of parseEnvContent(content)) {
|
|
21741
21749
|
if (process.env[key] === undefined)
|
|
21742
21750
|
process.env[key] = value;
|
|
21743
21751
|
}
|
package/gemini-extension.json
CHANGED
package/package.json
CHANGED