@vellumai/credential-executor 0.10.7-dev.202607082034.5ac40b3 → 0.10.7-dev.202607082203.bf32263
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/Dockerfile +1 -1
- package/package.json +2 -3
- package/src/__tests__/bulk-set-credentials.test.ts +1 -1
- package/src/__tests__/managed-integration.test.ts +4 -4
- package/src/__tests__/managed-lazy-getters.test.ts +1 -1
- package/src/__tests__/managed-reconnect.test.ts +2 -2
- package/src/__tests__/managed-rejection.test.ts +1 -1
- package/src/__tests__/transport.test.ts +18 -22
- package/src/cli.ts +1 -1
- package/src/index.ts +3 -3
- package/src/main.ts +574 -182
- package/src/managed-lazy-getters.ts +1 -1
- package/src/managed-main.ts +0 -822
package/Dockerfile
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@vellumai/credential-executor",
|
|
3
|
-
"version": "0.10.7-dev.
|
|
3
|
+
"version": "0.10.7-dev.202607082203.bf32263",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"exports": {
|
|
@@ -8,12 +8,11 @@
|
|
|
8
8
|
},
|
|
9
9
|
"bin": {
|
|
10
10
|
"credential-executor": "./src/main.ts",
|
|
11
|
-
"credential-executor-managed": "./src/managed-main.ts",
|
|
12
11
|
"ces": "./src/cli.ts"
|
|
13
12
|
},
|
|
14
13
|
"scripts": {
|
|
15
14
|
"dev": "bun run src/main.ts",
|
|
16
|
-
"dev:managed": "CES_MODE=managed bun run src/
|
|
15
|
+
"dev:managed": "CES_MODE=managed bun run src/main.ts",
|
|
17
16
|
"lint": "eslint",
|
|
18
17
|
"lint:unused": "knip --include files,dependencies,unlisted",
|
|
19
18
|
"typecheck": "bunx tsc --noEmit",
|
|
@@ -16,7 +16,7 @@ import type { SecureKeyBackend } from "@vellumai/credential-storage";
|
|
|
16
16
|
|
|
17
17
|
/**
|
|
18
18
|
* Build a minimal BulkSetCredentials handler using the same logic as
|
|
19
|
-
* main.ts
|
|
19
|
+
* main.ts, backed by the given SecureKeyBackend.
|
|
20
20
|
*/
|
|
21
21
|
function buildBulkSetHandler(secureKeyBackend: SecureKeyBackend) {
|
|
22
22
|
return async (req: { credentials: Array<{ account: string; value: string }> }) => {
|
|
@@ -116,7 +116,7 @@ function buildMinimalHandlers(dataDir: string): RpcHandlerRegistry {
|
|
|
116
116
|
* Build an RPC handler registry with credential CRUD handlers backed by
|
|
117
117
|
* a real SecureKeyBackend using a temp directory for credential storage.
|
|
118
118
|
*
|
|
119
|
-
* Mirrors the handler registration in
|
|
119
|
+
* Mirrors the handler registration in main.ts.
|
|
120
120
|
*/
|
|
121
121
|
function buildCredentialHandlers(vellumRoot: string): RpcHandlerRegistry {
|
|
122
122
|
const secureKeyBackend = createLocalSecureKeyBackend(vellumRoot);
|
|
@@ -149,7 +149,7 @@ function buildCredentialHandlers(vellumRoot: string): RpcHandlerRegistry {
|
|
|
149
149
|
* Accept a single connection on a Unix socket and return
|
|
150
150
|
* readable/writable streams plus cleanup helpers.
|
|
151
151
|
*
|
|
152
|
-
* Replicates the same accept-one-connection pattern from
|
|
152
|
+
* Replicates the same accept-one-connection pattern from main.ts
|
|
153
153
|
* but in a test-friendly form.
|
|
154
154
|
*/
|
|
155
155
|
function acceptOneConnection(socketPath: string, signal: AbortSignal): Promise<{
|
|
@@ -367,7 +367,7 @@ describe("managed CES integration (real Unix socket)", () => {
|
|
|
367
367
|
|
|
368
368
|
// -- Start health server ---------------------------------------------------
|
|
369
369
|
// NOTE: This uses a local Bun.serve mock rather than the production
|
|
370
|
-
// `startHealthServer()` from
|
|
370
|
+
// `startHealthServer()` from main.ts. The production function is
|
|
371
371
|
// not exported and depends on module-level mutable state (the
|
|
372
372
|
// `rpcConnected` flag) that cannot be controlled from tests.
|
|
373
373
|
//
|
|
@@ -377,7 +377,7 @@ describe("managed CES integration (real Unix socket)", () => {
|
|
|
377
377
|
// - End-to-end socket + RPC + health plumbing in one integration flow.
|
|
378
378
|
//
|
|
379
379
|
// What this does NOT cover:
|
|
380
|
-
// - The actual `startHealthServer()` implementation in
|
|
380
|
+
// - The actual `startHealthServer()` implementation in main.ts,
|
|
381
381
|
// including the `rpcConnected` field in the /readyz response. If the
|
|
382
382
|
// production health handler drifts (changes routes, status codes, or
|
|
383
383
|
// response shape), this test will not catch it. To close that gap,
|
|
@@ -228,7 +228,7 @@ describe("managed lazy getters — lazy resolution timing", () => {
|
|
|
228
228
|
apiKeyRef,
|
|
229
229
|
});
|
|
230
230
|
|
|
231
|
-
// Build a deps object with getters, mirroring
|
|
231
|
+
// Build a deps object with getters, mirroring main.ts httpDeps
|
|
232
232
|
const httpDeps = {
|
|
233
233
|
get managedSubjectOptions() {
|
|
234
234
|
return getManagedSubjectOptions();
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Managed CES reconnection test (real entrypoint subprocess).
|
|
3
3
|
*
|
|
4
|
-
* Spawns the actual `
|
|
4
|
+
* Spawns the actual `main.ts` entrypoint and verifies that the CES
|
|
5
5
|
* sidecar survives the assistant disconnecting and accepts a reconnection,
|
|
6
6
|
* rather than shutting down when the RPC stream ends.
|
|
7
7
|
*
|
|
@@ -179,7 +179,7 @@ describe("managed CES reconnection (real entrypoint)", () => {
|
|
|
179
179
|
mkdirSync(join(assistantDataMount, ".vellum"), { recursive: true });
|
|
180
180
|
|
|
181
181
|
const healthPort = await pickFreePort();
|
|
182
|
-
const managedMain = resolve(__dirname, "..", "
|
|
182
|
+
const managedMain = resolve(__dirname, "..", "main.ts");
|
|
183
183
|
|
|
184
184
|
proc = Bun.spawn({
|
|
185
185
|
cmd: [process.execPath, managedMain],
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
* Managed-mode local_static handle rejection contract tests.
|
|
3
3
|
*
|
|
4
4
|
* Validates that the MANAGED_LOCAL_STATIC_REJECTION_ERROR constant used by
|
|
5
|
-
*
|
|
5
|
+
* main.ts contains the expected contract fragments. These tests
|
|
6
6
|
* import the actual production constant (not a test-local copy), so they
|
|
7
7
|
* will fail if the error message drifts away from the expected contract.
|
|
8
8
|
*/
|
|
@@ -125,39 +125,28 @@ function createTestServer(handlers: RpcHandlerRegistry = {}) {
|
|
|
125
125
|
// ---------------------------------------------------------------------------
|
|
126
126
|
|
|
127
127
|
describe("managed entrypoint transport isolation", () => {
|
|
128
|
-
test("
|
|
128
|
+
test("main.ts uses Bun.serve only for health probes (managed mode)", () => {
|
|
129
129
|
const src = readFileSync(
|
|
130
|
-
resolve(__dirname, "..", "
|
|
130
|
+
resolve(__dirname, "..", "main.ts"),
|
|
131
131
|
"utf-8",
|
|
132
132
|
);
|
|
133
|
-
// Bun.serve
|
|
133
|
+
// Bun.serve is used for the health server in managed mode
|
|
134
134
|
const bunServeMatches = src.match(/Bun\.serve\(/g);
|
|
135
135
|
expect(bunServeMatches).not.toBeNull();
|
|
136
136
|
// There should be exactly 1 Bun.serve call — for health probes only
|
|
137
137
|
expect(bunServeMatches!.length).toBe(1);
|
|
138
138
|
});
|
|
139
139
|
|
|
140
|
-
test("
|
|
140
|
+
test("main.ts uses createNetServer for Unix socket transport", () => {
|
|
141
141
|
const src = readFileSync(
|
|
142
|
-
resolve(__dirname, "..", "
|
|
142
|
+
resolve(__dirname, "..", "main.ts"),
|
|
143
143
|
"utf-8",
|
|
144
144
|
);
|
|
145
|
-
// Uses node:net createServer for the
|
|
145
|
+
// Uses node:net createServer for the socket transport (both modes)
|
|
146
146
|
expect(src).toMatch(/createNetServer/);
|
|
147
147
|
// The net server never listens on a TCP port (only a socket path)
|
|
148
148
|
expect(src).not.toMatch(/netServer\.listen\(\d+/);
|
|
149
149
|
});
|
|
150
|
-
|
|
151
|
-
test("managed-main.ts unlinks socket after accepting one connection", () => {
|
|
152
|
-
const src = readFileSync(
|
|
153
|
-
resolve(__dirname, "..", "managed-main.ts"),
|
|
154
|
-
"utf-8",
|
|
155
|
-
);
|
|
156
|
-
// Should unlink the socket path after connection
|
|
157
|
-
expect(src).toMatch(/unlinkSync\(socketPath\)/);
|
|
158
|
-
// Should close the net server after one connection
|
|
159
|
-
expect(src).toMatch(/netServer\.close\(\)/);
|
|
160
|
-
});
|
|
161
150
|
});
|
|
162
151
|
|
|
163
152
|
// ---------------------------------------------------------------------------
|
|
@@ -165,9 +154,9 @@ describe("managed entrypoint transport isolation", () => {
|
|
|
165
154
|
// ---------------------------------------------------------------------------
|
|
166
155
|
|
|
167
156
|
describe("health probes", () => {
|
|
168
|
-
test("
|
|
157
|
+
test("main.ts serves /healthz and /readyz in managed mode", () => {
|
|
169
158
|
const src = readFileSync(
|
|
170
|
-
resolve(__dirname, "..", "
|
|
159
|
+
resolve(__dirname, "..", "main.ts"),
|
|
171
160
|
"utf-8",
|
|
172
161
|
);
|
|
173
162
|
expect(src).toMatch(/\/healthz/);
|
|
@@ -212,9 +201,16 @@ describe("local entrypoint transport isolation", () => {
|
|
|
212
201
|
// Socket transport only — no stdio-child transport.
|
|
213
202
|
expect(src).not.toMatch(/process\.stdin/);
|
|
214
203
|
expect(src).not.toMatch(/process\.stdout/);
|
|
215
|
-
//
|
|
216
|
-
// never
|
|
217
|
-
|
|
204
|
+
// Bun.serve is only used inside the managed-mode health server block
|
|
205
|
+
// (startHealthServer), never for RPC transport. The RPC transport uses
|
|
206
|
+
// node:net createServer listening on a Unix socket path.
|
|
207
|
+
const bunServeMatches = src.match(/Bun\.serve\(/g);
|
|
208
|
+
expect(bunServeMatches).not.toBeNull();
|
|
209
|
+
expect(bunServeMatches!.length).toBe(1);
|
|
210
|
+
// The Bun.serve call must be inside the startHealthServer function, which
|
|
211
|
+
// is only invoked in managed mode.
|
|
212
|
+
expect(src).toMatch(/function startHealthServer/);
|
|
213
|
+
// Never listens on a numeric TCP port for RPC transport.
|
|
218
214
|
expect(src).not.toMatch(/\.listen\(\d+/);
|
|
219
215
|
});
|
|
220
216
|
|
package/src/cli.ts
CHANGED
|
@@ -25,7 +25,7 @@ import { homedir } from "node:os";
|
|
|
25
25
|
import { createLocalSecureKeyBackend } from "./materializers/local-secure-key-backend.js";
|
|
26
26
|
|
|
27
27
|
// ---------------------------------------------------------------------------
|
|
28
|
-
// Path resolution (mirrors managed-main.ts)
|
|
28
|
+
// Path resolution (mirrors the managed-mode path in main.ts)
|
|
29
29
|
// ---------------------------------------------------------------------------
|
|
30
30
|
|
|
31
31
|
function resolveVellumRoot(): string {
|
package/src/index.ts
CHANGED
|
@@ -8,9 +8,9 @@
|
|
|
8
8
|
* from the local credential store, executes the requested operation through
|
|
9
9
|
* the egress proxy, and returns sanitised results.
|
|
10
10
|
*
|
|
11
|
-
* This module re-exports the public API surface. For
|
|
12
|
-
*
|
|
13
|
-
*
|
|
11
|
+
* This module re-exports the public API surface. For the entrypoint see
|
|
12
|
+
* `main.ts` — unified for both local (bare-metal sibling) and managed
|
|
13
|
+
* (Kubernetes sidecar) modes, selected by `getCesMode()`.
|
|
14
14
|
*/
|
|
15
15
|
|
|
16
16
|
export {
|