@axiom-lattice/local-stores 3.2.1 → 3.2.3
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/.turbo/turbo-build.log +10 -10
- package/CHANGELOG.md +24 -0
- package/dist/index.d.mts +1 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +59 -21
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +44 -6
- package/dist/index.mjs.map +1 -1
- package/package.json +3 -3
- package/src/__tests__/LocalConnectionStore.test.ts +176 -0
- package/src/stores/LocalConnectionStore.ts +46 -7
package/.turbo/turbo-build.log
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
|
|
2
|
-
> @axiom-lattice/local-stores@3.2.
|
|
2
|
+
> @axiom-lattice/local-stores@3.2.3 build /home/runner/work/agentic/agentic/packages/local-stores
|
|
3
3
|
> tsup src/index.ts --format cjs,esm --dts --sourcemap
|
|
4
4
|
|
|
5
5
|
[34mCLI[39m Building entry: src/index.ts
|
|
@@ -8,13 +8,13 @@
|
|
|
8
8
|
[34mCLI[39m Target: es2020
|
|
9
9
|
[34mCJS[39m Build start
|
|
10
10
|
[34mESM[39m Build start
|
|
11
|
-
[32mESM[39m [1mdist/index.mjs [22m[
|
|
12
|
-
[32mESM[39m [1mdist/index.mjs.map [22m[
|
|
13
|
-
[32mESM[39m ⚡️ Build success in
|
|
14
|
-
[32mCJS[39m [1mdist/index.js [22m[
|
|
15
|
-
[32mCJS[39m [1mdist/index.js.map [22m[
|
|
16
|
-
[32mCJS[39m ⚡️ Build success in
|
|
11
|
+
[32mESM[39m [1mdist/index.mjs [22m[32m239.07 KB[39m
|
|
12
|
+
[32mESM[39m [1mdist/index.mjs.map [22m[32m438.65 KB[39m
|
|
13
|
+
[32mESM[39m ⚡️ Build success in 857ms
|
|
14
|
+
[32mCJS[39m [1mdist/index.js [22m[32m243.72 KB[39m
|
|
15
|
+
[32mCJS[39m [1mdist/index.js.map [22m[32m442.40 KB[39m
|
|
16
|
+
[32mCJS[39m ⚡️ Build success in 859ms
|
|
17
17
|
[34mDTS[39m Build start
|
|
18
|
-
[32mDTS[39m ⚡️ Build success in
|
|
19
|
-
[32mDTS[39m [1mdist/index.d.ts [22m[32m44.
|
|
20
|
-
[32mDTS[39m [1mdist/index.d.mts [22m[32m44.
|
|
18
|
+
[32mDTS[39m ⚡️ Build success in 12595ms
|
|
19
|
+
[32mDTS[39m [1mdist/index.d.ts [22m[32m44.69 KB[39m
|
|
20
|
+
[32mDTS[39m [1mdist/index.d.mts [22m[32m44.69 KB[39m
|
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,29 @@
|
|
|
1
1
|
# @axiom-lattice/local-stores
|
|
2
2
|
|
|
3
|
+
## 3.2.3
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- Updated dependencies
|
|
8
|
+
- @axiom-lattice/core@6.3.3
|
|
9
|
+
|
|
10
|
+
## 3.2.2
|
|
11
|
+
|
|
12
|
+
### Patch Changes
|
|
13
|
+
|
|
14
|
+
- bb2614f: Chating composer height, plugin connection-secret encryption, and manage_task compact cards.
|
|
15
|
+
|
|
16
|
+
- react-sdk: keep the Chating composer input from collapsing after a run. In slot mode (Chating always passes an array `slotConfig`) the Sender input is a `contentEditable` whose height comes from `autoSize`; without a `minRows` the empty editor lost its placeholder-driven line box once streaming ended and collapsed to zero height on some platforms (e.g. Windows Chrome), leaving the input unreachable while the footer stayed visible. Pass `autoSize={{ minRows: 1, maxRows: 8 }}` like `ProjectRoomComposer`.
|
|
17
|
+
- protocols/core: add `ConnectionEntry.secretFields`, plus `connectionSecretFields` / `encryptConfigFields` / `decryptConfigFields`.
|
|
18
|
+
- local-stores/pg-stores: encrypt the declared secret fields on save and decrypt on read, so the API and runtime consumers always receive real values. Existing plaintext rows read unchanged and convert on their next save (PG migration v188).
|
|
19
|
+
- gateway: plugin builder self-test discovery + secret redaction.
|
|
20
|
+
- core: `manage_task` `add_activity` now returns the target task alongside the activity (`{ success, data, task }`), so UIs can show which task an activity was written to.
|
|
21
|
+
- react-sdk: every `manage_task` action renders a compact chip in the chat stream and reveals its full card on hover. Fixes `get` and `add_activity`, which previously rendered no UI at all.
|
|
22
|
+
|
|
23
|
+
- Updated dependencies [bb2614f]
|
|
24
|
+
- @axiom-lattice/protocols@4.7.1
|
|
25
|
+
- @axiom-lattice/core@6.3.2
|
|
26
|
+
|
|
3
27
|
## 3.2.1
|
|
4
28
|
|
|
5
29
|
### Patch Changes
|
package/dist/index.d.mts
CHANGED
|
@@ -467,6 +467,7 @@ declare class LocalDatabaseConfigStore implements DatabaseConfigStore {
|
|
|
467
467
|
declare class LocalConnectionStore implements ConnectionStore {
|
|
468
468
|
private db;
|
|
469
469
|
constructor(db: DatabaseWrapper);
|
|
470
|
+
private ensureColumn;
|
|
470
471
|
listByTenant(tenantId: string): Promise<ConnectionEntry[]>;
|
|
471
472
|
listByType(tenantId: string, type: string): Promise<ConnectionEntry[]>;
|
|
472
473
|
getByKey(tenantId: string, type: string, key: string): Promise<ConnectionEntry | null>;
|
package/dist/index.d.ts
CHANGED
|
@@ -467,6 +467,7 @@ declare class LocalDatabaseConfigStore implements DatabaseConfigStore {
|
|
|
467
467
|
declare class LocalConnectionStore implements ConnectionStore {
|
|
468
468
|
private db;
|
|
469
469
|
constructor(db: DatabaseWrapper);
|
|
470
|
+
private ensureColumn;
|
|
470
471
|
listByTenant(tenantId: string): Promise<ConnectionEntry[]>;
|
|
471
472
|
listByType(tenantId: string, type: string): Promise<ConnectionEntry[]>;
|
|
472
473
|
getByKey(tenantId: string, type: string, key: string): Promise<ConnectionEntry | null>;
|
package/dist/index.js
CHANGED
|
@@ -2074,6 +2074,7 @@ function encryptPasswordInConfig(config) {
|
|
|
2074
2074
|
|
|
2075
2075
|
// src/stores/LocalConnectionStore.ts
|
|
2076
2076
|
var import_uuid = require("uuid");
|
|
2077
|
+
var import_core2 = require("@axiom-lattice/core");
|
|
2077
2078
|
var DDL9 = `
|
|
2078
2079
|
CREATE TABLE IF NOT EXISTS connection_configs (
|
|
2079
2080
|
id TEXT NOT NULL,
|
|
@@ -2083,6 +2084,7 @@ CREATE TABLE IF NOT EXISTS connection_configs (
|
|
|
2083
2084
|
name TEXT NOT NULL,
|
|
2084
2085
|
description TEXT,
|
|
2085
2086
|
config TEXT NOT NULL,
|
|
2087
|
+
secret_fields TEXT,
|
|
2086
2088
|
created_at TEXT NOT NULL,
|
|
2087
2089
|
updated_at TEXT NOT NULL,
|
|
2088
2090
|
PRIMARY KEY (tenant_id, id),
|
|
@@ -2090,10 +2092,28 @@ CREATE TABLE IF NOT EXISTS connection_configs (
|
|
|
2090
2092
|
);
|
|
2091
2093
|
CREATE INDEX IF NOT EXISTS idx_conn_type ON connection_configs(tenant_id, type);
|
|
2092
2094
|
`;
|
|
2095
|
+
function parseSecretFields(raw) {
|
|
2096
|
+
if (!raw) return void 0;
|
|
2097
|
+
try {
|
|
2098
|
+
const parsed = JSON.parse(raw);
|
|
2099
|
+
if (Array.isArray(parsed) && parsed.every((v) => typeof v === "string") && parsed.length > 0) {
|
|
2100
|
+
return parsed;
|
|
2101
|
+
}
|
|
2102
|
+
} catch {
|
|
2103
|
+
}
|
|
2104
|
+
return void 0;
|
|
2105
|
+
}
|
|
2093
2106
|
var LocalConnectionStore = class {
|
|
2094
2107
|
constructor(db) {
|
|
2095
2108
|
this.db = db;
|
|
2096
2109
|
ensureTable(db, DDL9);
|
|
2110
|
+
this.ensureColumn("connection_configs", "secret_fields", "secret_fields TEXT");
|
|
2111
|
+
}
|
|
2112
|
+
ensureColumn(table, column, ddl2) {
|
|
2113
|
+
const cols = this.db.prepare(`PRAGMA table_info(${table})`).all();
|
|
2114
|
+
if (!cols.some((c) => c.name === column)) {
|
|
2115
|
+
this.db.exec(`ALTER TABLE ${table} ADD COLUMN ${ddl2}`);
|
|
2116
|
+
}
|
|
2097
2117
|
}
|
|
2098
2118
|
async listByTenant(tenantId) {
|
|
2099
2119
|
const rows2 = this.db.prepare(
|
|
@@ -2116,11 +2136,23 @@ var LocalConnectionStore = class {
|
|
|
2116
2136
|
async create(entry) {
|
|
2117
2137
|
const id = (0, import_uuid.v4)();
|
|
2118
2138
|
const now = nowISO();
|
|
2139
|
+
const secretFields = entry.secretFields?.length ? entry.secretFields : void 0;
|
|
2119
2140
|
this.db.prepare(
|
|
2120
|
-
`INSERT INTO connection_configs (id, tenant_id, type, key, name, description, config, created_at, updated_at)
|
|
2121
|
-
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)`
|
|
2122
|
-
).run(
|
|
2123
|
-
|
|
2141
|
+
`INSERT INTO connection_configs (id, tenant_id, type, key, name, description, config, secret_fields, created_at, updated_at)
|
|
2142
|
+
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`
|
|
2143
|
+
).run(
|
|
2144
|
+
id,
|
|
2145
|
+
entry.tenantId,
|
|
2146
|
+
entry.type,
|
|
2147
|
+
entry.key,
|
|
2148
|
+
entry.name,
|
|
2149
|
+
entry.description || null,
|
|
2150
|
+
JSON.stringify((0, import_core2.encryptConfigFields)(entry.config, secretFields)),
|
|
2151
|
+
secretFields ? JSON.stringify(secretFields) : null,
|
|
2152
|
+
now,
|
|
2153
|
+
now
|
|
2154
|
+
);
|
|
2155
|
+
return { id, ...entry, secretFields, createdAt: now, updatedAt: now };
|
|
2124
2156
|
}
|
|
2125
2157
|
async update(tenantId, type, key, updates) {
|
|
2126
2158
|
const existing = await this.getByKey(tenantId, type, key);
|
|
@@ -2136,8 +2168,11 @@ var LocalConnectionStore = class {
|
|
|
2136
2168
|
values.push(updates.description || null);
|
|
2137
2169
|
}
|
|
2138
2170
|
if (updates.config !== void 0) {
|
|
2171
|
+
const secretFields = updates.secretFields?.length ? updates.secretFields : existing.secretFields?.length ? existing.secretFields : void 0;
|
|
2139
2172
|
setClauses.push("config = ?");
|
|
2140
|
-
values.push(JSON.stringify(updates.config));
|
|
2173
|
+
values.push(JSON.stringify((0, import_core2.encryptConfigFields)(updates.config, secretFields)));
|
|
2174
|
+
setClauses.push("secret_fields = ?");
|
|
2175
|
+
values.push(secretFields ? JSON.stringify(secretFields) : null);
|
|
2141
2176
|
}
|
|
2142
2177
|
if (setClauses.length === 0) return existing;
|
|
2143
2178
|
const now = nowISO();
|
|
@@ -2156,6 +2191,8 @@ var LocalConnectionStore = class {
|
|
|
2156
2191
|
return result.changes > 0;
|
|
2157
2192
|
}
|
|
2158
2193
|
mapRow(row) {
|
|
2194
|
+
const secretFields = parseSecretFields(row.secret_fields);
|
|
2195
|
+
const storedConfig = JSON.parse(row.config);
|
|
2159
2196
|
return {
|
|
2160
2197
|
id: row.id,
|
|
2161
2198
|
tenantId: row.tenant_id,
|
|
@@ -2163,7 +2200,8 @@ var LocalConnectionStore = class {
|
|
|
2163
2200
|
key: row.key,
|
|
2164
2201
|
name: row.name,
|
|
2165
2202
|
description: row.description || void 0,
|
|
2166
|
-
config:
|
|
2203
|
+
config: (0, import_core2.decryptConfigFields)(storedConfig, secretFields),
|
|
2204
|
+
secretFields,
|
|
2167
2205
|
createdAt: row.created_at,
|
|
2168
2206
|
updatedAt: row.updated_at
|
|
2169
2207
|
};
|
|
@@ -2295,7 +2333,7 @@ function mapRowToEntry2(row) {
|
|
|
2295
2333
|
}
|
|
2296
2334
|
|
|
2297
2335
|
// src/stores/LocalMcpServerConfigStore.ts
|
|
2298
|
-
var
|
|
2336
|
+
var import_core3 = require("@axiom-lattice/core");
|
|
2299
2337
|
var DDL11 = `
|
|
2300
2338
|
CREATE TABLE IF NOT EXISTS lt_mcp_configs (
|
|
2301
2339
|
id TEXT NOT NULL,
|
|
@@ -2445,7 +2483,7 @@ function mapRowToEntry3(row) {
|
|
|
2445
2483
|
try {
|
|
2446
2484
|
const decryptedEnv = {};
|
|
2447
2485
|
for (const [key, value] of Object.entries(config.env)) {
|
|
2448
|
-
decryptedEnv[key] = (0,
|
|
2486
|
+
decryptedEnv[key] = (0, import_core3.decrypt)(value);
|
|
2449
2487
|
}
|
|
2450
2488
|
config.env = decryptedEnv;
|
|
2451
2489
|
} catch (error) {
|
|
@@ -2457,7 +2495,7 @@ function mapRowToEntry3(row) {
|
|
|
2457
2495
|
try {
|
|
2458
2496
|
const decryptedHeaders = {};
|
|
2459
2497
|
for (const [key, value] of Object.entries(config.headers)) {
|
|
2460
|
-
decryptedHeaders[key] = (0,
|
|
2498
|
+
decryptedHeaders[key] = (0, import_core3.decrypt)(value);
|
|
2461
2499
|
}
|
|
2462
2500
|
config.headers = decryptedHeaders;
|
|
2463
2501
|
} catch (error) {
|
|
@@ -2485,7 +2523,7 @@ function encryptEnvInConfig(config) {
|
|
|
2485
2523
|
if (configCopy.env && Object.keys(configCopy.env).length > 0) {
|
|
2486
2524
|
const encryptedEnv = {};
|
|
2487
2525
|
for (const [key, value] of Object.entries(configCopy.env)) {
|
|
2488
|
-
encryptedEnv[key] = (0,
|
|
2526
|
+
encryptedEnv[key] = (0, import_core3.encrypt)(value);
|
|
2489
2527
|
}
|
|
2490
2528
|
configCopy.env = encryptedEnv;
|
|
2491
2529
|
isEnvEncrypted = true;
|
|
@@ -2493,7 +2531,7 @@ function encryptEnvInConfig(config) {
|
|
|
2493
2531
|
if (configCopy.headers && Object.keys(configCopy.headers).length > 0) {
|
|
2494
2532
|
const encryptedHeaders = {};
|
|
2495
2533
|
for (const [key, value] of Object.entries(configCopy.headers)) {
|
|
2496
|
-
encryptedHeaders[key] = (0,
|
|
2534
|
+
encryptedHeaders[key] = (0, import_core3.encrypt)(value);
|
|
2497
2535
|
}
|
|
2498
2536
|
configCopy.headers = encryptedHeaders;
|
|
2499
2537
|
isEnvEncrypted = true;
|
|
@@ -2502,7 +2540,7 @@ function encryptEnvInConfig(config) {
|
|
|
2502
2540
|
}
|
|
2503
2541
|
|
|
2504
2542
|
// src/stores/LocalModelProviderStore.ts
|
|
2505
|
-
var
|
|
2543
|
+
var import_core4 = require("@axiom-lattice/core");
|
|
2506
2544
|
var DDL12 = `
|
|
2507
2545
|
CREATE TABLE IF NOT EXISTS lt_model_providers (
|
|
2508
2546
|
id TEXT NOT NULL,
|
|
@@ -2612,7 +2650,7 @@ var LocalModelProviderStore = class {
|
|
|
2612
2650
|
// Phase 1 pins the LLM provider (ADR-138 decision 7b)
|
|
2613
2651
|
"openai",
|
|
2614
2652
|
data.baseURL,
|
|
2615
|
-
data.apiKey ? (0,
|
|
2653
|
+
data.apiKey ? (0, import_core4.encrypt)(data.apiKey) : null,
|
|
2616
2654
|
data.apiKey ? data.apiKey.slice(-4) : null,
|
|
2617
2655
|
data.enabled === false ? 0 : 1,
|
|
2618
2656
|
now,
|
|
@@ -2647,7 +2685,7 @@ var LocalModelProviderStore = class {
|
|
|
2647
2685
|
set("api_key_enc", null);
|
|
2648
2686
|
set("api_key_hint", null);
|
|
2649
2687
|
} else if (updates.apiKey) {
|
|
2650
|
-
set("api_key_enc", (0,
|
|
2688
|
+
set("api_key_enc", (0, import_core4.encrypt)(updates.apiKey));
|
|
2651
2689
|
set("api_key_hint", updates.apiKey.slice(-4));
|
|
2652
2690
|
}
|
|
2653
2691
|
if (fields.length === 0) {
|
|
@@ -2780,7 +2818,7 @@ function mapRowToEntry4(row) {
|
|
|
2780
2818
|
let apiKey;
|
|
2781
2819
|
if (row.api_key_enc) {
|
|
2782
2820
|
try {
|
|
2783
|
-
apiKey = (0,
|
|
2821
|
+
apiKey = (0, import_core4.decrypt)(row.api_key_enc);
|
|
2784
2822
|
} catch (error) {
|
|
2785
2823
|
console.error("Failed to decrypt model provider API key:", error);
|
|
2786
2824
|
throw new Error("Failed to decrypt model provider API key");
|
|
@@ -4245,7 +4283,7 @@ function mapRow6(row) {
|
|
|
4245
4283
|
}
|
|
4246
4284
|
|
|
4247
4285
|
// src/stores/LocalA2AApiKeyStore.ts
|
|
4248
|
-
var
|
|
4286
|
+
var import_core5 = require("@axiom-lattice/core");
|
|
4249
4287
|
var import_crypto3 = require("crypto");
|
|
4250
4288
|
var DDL17 = `
|
|
4251
4289
|
CREATE TABLE IF NOT EXISTS lt_a2a_api_keys (
|
|
@@ -4316,7 +4354,7 @@ var LocalA2AApiKeyStore = class {
|
|
|
4316
4354
|
).all();
|
|
4317
4355
|
for (const row of rows2) {
|
|
4318
4356
|
try {
|
|
4319
|
-
if ((0,
|
|
4357
|
+
if ((0, import_core5.decrypt)(row.key_value) === key) return mapRowToRecord(row);
|
|
4320
4358
|
} catch {
|
|
4321
4359
|
}
|
|
4322
4360
|
}
|
|
@@ -4350,7 +4388,7 @@ var LocalA2AApiKeyStore = class {
|
|
|
4350
4388
|
this.db.prepare(
|
|
4351
4389
|
`INSERT INTO lt_a2a_api_keys (id, key_value, tenant_id, project_id, assistant_ids, grants, label, created_at, updated_at)
|
|
4352
4390
|
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)`
|
|
4353
|
-
).run(id, (0,
|
|
4391
|
+
).run(id, (0, import_core5.encrypt)(key), input.tenantId, input.projectId, input.assistantIds ? JSON.stringify(input.assistantIds) : null, input.grants ? JSON.stringify(input.grants) : null, input.label || null, now, now);
|
|
4354
4392
|
const record2 = {
|
|
4355
4393
|
id,
|
|
4356
4394
|
key,
|
|
@@ -4419,7 +4457,7 @@ var LocalA2AApiKeyStore = class {
|
|
|
4419
4457
|
const now = nowISO();
|
|
4420
4458
|
this.db.prepare(
|
|
4421
4459
|
`UPDATE lt_a2a_api_keys SET key_value = ?, updated_at = ? WHERE id = ?`
|
|
4422
|
-
).run((0,
|
|
4460
|
+
).run((0, import_core5.encrypt)(key), now, id);
|
|
4423
4461
|
const row = this.db.prepare(`SELECT * FROM lt_a2a_api_keys WHERE id = ?`).get(id);
|
|
4424
4462
|
if (!row) throw new Error(`A2A API key not found: ${id}`);
|
|
4425
4463
|
const record2 = mapRowToRecord(row);
|
|
@@ -4436,7 +4474,7 @@ var LocalA2AApiKeyStore = class {
|
|
|
4436
4474
|
const map2 = /* @__PURE__ */ new Map();
|
|
4437
4475
|
for (const row of rows2) {
|
|
4438
4476
|
try {
|
|
4439
|
-
const key = (0,
|
|
4477
|
+
const key = (0, import_core5.decrypt)(row.key_value);
|
|
4440
4478
|
map2.set(key, {
|
|
4441
4479
|
key,
|
|
4442
4480
|
tenantId: row.tenant_id,
|
|
@@ -4452,7 +4490,7 @@ var LocalA2AApiKeyStore = class {
|
|
|
4452
4490
|
function mapRowToRecord(row) {
|
|
4453
4491
|
let key = "";
|
|
4454
4492
|
try {
|
|
4455
|
-
key = (0,
|
|
4493
|
+
key = (0, import_core5.decrypt)(row.key_value);
|
|
4456
4494
|
} catch {
|
|
4457
4495
|
key = row.key_value;
|
|
4458
4496
|
}
|