@vellumai/credential-executor 0.12.2 → 0.12.3-staging.2

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.
@@ -27,7 +27,8 @@
27
27
  "./reactions": "./src/reactions.ts",
28
28
  "./guardian-requests": "./src/guardian-requests.ts",
29
29
  "./platform-credential": "./src/platform-credential.ts",
30
- "./plan-credit": "./src/plan-credit.ts"
30
+ "./plan-credit": "./src/plan-credit.ts",
31
+ "./integration-categories": "./src/integration-categories.ts"
31
32
  },
32
33
  "scripts": {
33
34
  "typecheck": "bunx tsc --noEmit",
@@ -63,6 +63,7 @@ const FIXTURES: Record<string, string> = {
63
63
  "Perplexity API Key": `pplx-${filler(40)}`,
64
64
  "Tavily API Key": `tvly-${filler(20)}`,
65
65
  "Firecrawl API Key": `fc-${filler(20)}`,
66
+ "Resend API Key": `re_${filler(8)}_${filler(24)}`,
66
67
  };
67
68
 
68
69
  describe("subpath export", () => {
@@ -29,6 +29,7 @@ export * from "./trust-rules.js";
29
29
  export * from "./ingress.js";
30
30
  export * from "./no-response.js";
31
31
  export * from "./plan-credit.js";
32
+ export * from "./integration-categories.js";
32
33
  export * from "./platform-credential.js";
33
34
  export * from "./remote-web-pairing.js";
34
35
  export * from "./twilio-ingress.js";
@@ -0,0 +1,36 @@
1
+ /**
2
+ * Category vocabulary for the integrations catalog, shared by the assistant
3
+ * daemon (which stamps it on OAuth providers and marketplace MCP entries) and
4
+ * the clients (which draw the category filter from it).
5
+ *
6
+ * The order here is the order clients show the categories in. The slug is the
7
+ * wire value; the user-facing label is the client's, so it can be translated.
8
+ */
9
+ export const INTEGRATION_CATEGORIES = [
10
+ "productivity",
11
+ "communication",
12
+ "meetings",
13
+ "sales",
14
+ "marketing",
15
+ "finance",
16
+ "commerce",
17
+ "engineering",
18
+ "knowledge",
19
+ "recruiting",
20
+ ] as const;
21
+
22
+ export type IntegrationCategory = (typeof INTEGRATION_CATEGORIES)[number];
23
+
24
+ const INTEGRATION_CATEGORY_SET: ReadonlySet<string> = new Set(
25
+ INTEGRATION_CATEGORIES,
26
+ );
27
+
28
+ /**
29
+ * Whether `value` names a category this build knows. A client reading a newer
30
+ * catalog treats an unknown slug as uncategorized rather than failing.
31
+ */
32
+ export function isIntegrationCategory(
33
+ value: unknown,
34
+ ): value is IntegrationCategory {
35
+ return typeof value === "string" && INTEGRATION_CATEGORY_SET.has(value);
36
+ }
@@ -230,6 +230,9 @@ export const PREFIX_PATTERNS: SecretPrefixPattern[] = [
230
230
 
231
231
  // -- Firecrawl --
232
232
  { label: "Firecrawl API Key", regex: /fc-[A-Za-z0-9]{20,}/ },
233
+ // Resend documents only the `re_` prefix; the segment shape is the observed
234
+ // key format. Strict on purpose: bare `re_` prefixes ordinary identifiers.
235
+ { label: "Resend API Key", regex: /re_[A-Za-z0-9]{8}_[A-Za-z0-9]{24,}/ },
233
236
  ];
234
237
 
235
238
  /**
@@ -362,7 +365,7 @@ export function isPlaceholderValue(value: string): boolean {
362
365
  // Strip known prefixes to isolate the variable part
363
366
  const variablePart = value
364
367
  .replace(
365
- /^(?:AKIA|gh[pousr]_|github_pat_|glpat-|sk_live_|rk_live_|xoxb-|xoxp-|xapp-|sk-ant-|sk-proj-|sk-or-v1-|AIza|GOCSPX-|SK|SG\.|npm_|pypi-|key-|lin_api_|ntn_|fw_|pplx-|-----BEGIN [A-Z ]*PRIVATE KEY-----)/,
368
+ /^(?:AKIA|gh[pousr]_|github_pat_|glpat-|sk_live_|rk_live_|xoxb-|xoxp-|xapp-|sk-ant-|sk-proj-|sk-or-v1-|AIza|GOCSPX-|SK|SG\.|npm_|pypi-|key-|lin_api_|ntn_|fw_|pplx-|re_|-----BEGIN [A-Z ]*PRIVATE KEY-----)/,
366
369
  "",
367
370
  )
368
371
  .replace(/[^A-Za-z0-9]/g, "");
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vellumai/credential-executor",
3
- "version": "0.12.2",
3
+ "version": "0.12.3-staging.2",
4
4
  "license": "MIT",
5
5
  "type": "module",
6
6
  "exports": {
@@ -18,6 +18,8 @@ import { existsSync, mkdirSync, mkdtempSync, rmSync } from "node:fs";
18
18
  import { tmpdir } from "node:os";
19
19
  import { join, resolve } from "node:path";
20
20
 
21
+ import { resolveIpcEndpoint } from "@vellumai/ipc-server-utils";
22
+
21
23
  import {
22
24
  CES_PROTOCOL_VERSION,
23
25
  CesRpcMethod,
@@ -136,24 +138,29 @@ afterEach(async () => {
136
138
  describe("local CES standalone sibling (real entrypoint)", () => {
137
139
  test("serves over a socket with no stdio parent, survives disconnect, exits on SIGTERM", async () => {
138
140
  tmpDir = mkdtempSync(join(tmpdir(), "ces-standalone-"));
139
- const socketPath = join(tmpDir, "ces.sock");
140
141
  const securityDir = join(tmpDir, "protected");
141
142
  const workspaceDir = join(tmpDir, "workspace");
143
+ const bootstrapDir = join(securityDir, "credential-executor");
142
144
  mkdirSync(securityDir, { recursive: true });
143
145
  mkdirSync(workspaceDir, { recursive: true });
146
+ mkdirSync(bootstrapDir, { recursive: true });
147
+ const socketPath = resolveIpcEndpoint("ces", {
148
+ workspaceDir: bootstrapDir,
149
+ }).path;
144
150
 
145
151
  const localMain = resolve(__dirname, "..", "main.ts");
152
+ const env: Record<string, string | undefined> = {
153
+ ...process.env,
154
+ CREDENTIAL_SECURITY_DIR: securityDir,
155
+ VELLUM_WORKSPACE_DIR: workspaceDir,
156
+ CES_BOOTSTRAP_SOCKET_DIR: bootstrapDir,
157
+ };
146
158
 
147
159
  // stdin closed is how the CLI launches the sibling — CES serves over a
148
160
  // Unix socket, not stdio.
149
161
  proc = Bun.spawn({
150
162
  cmd: [process.execPath, localMain],
151
- env: {
152
- ...process.env,
153
- CES_LOCAL_SOCKET: socketPath,
154
- CREDENTIAL_SECURITY_DIR: securityDir,
155
- VELLUM_WORKSPACE_DIR: workspaceDir,
156
- },
163
+ env,
157
164
  stdin: "ignore",
158
165
  stdout: "ignore",
159
166
  stderr: "ignore",
@@ -54,7 +54,6 @@ import { createLocalSecureKeyBackend } from "../materializers/local-secure-key-b
54
54
  const SAVED_ENV_KEYS = [
55
55
  "CES_DATA_DIR",
56
56
  "CES_BOOTSTRAP_SOCKET_DIR",
57
- "CES_BOOTSTRAP_SOCKET",
58
57
  "CES_HEALTH_PORT",
59
58
  "CES_MODE",
60
59
  "CREDENTIAL_SECURITY_DIR",
@@ -17,6 +17,7 @@ import { existsSync, mkdirSync, mkdtempSync, rmSync } from "node:fs";
17
17
  import { tmpdir } from "node:os";
18
18
  import { join, resolve } from "node:path";
19
19
 
20
+ import { resolveIpcEndpoint } from "@vellumai/ipc-server-utils";
20
21
  import {
21
22
  CES_PROTOCOL_VERSION,
22
23
  type HandshakeAck,
@@ -172,7 +173,9 @@ describe("managed CES reconnection (real entrypoint)", () => {
172
173
  tmpDir = mkdtempSync(join(tmpdir(), "ces-reconnect-"));
173
174
  const dataDir = join(tmpDir, "ces-data");
174
175
  const socketDir = join(tmpDir, "bootstrap");
175
- const socketPath = join(socketDir, "ces.sock");
176
+ const socketPath = resolveIpcEndpoint("ces", {
177
+ workspaceDir: socketDir,
178
+ }).path;
176
179
  const assistantDataMount = join(tmpDir, "assistant-data-ro");
177
180
  mkdirSync(dataDir, { recursive: true });
178
181
  mkdirSync(socketDir, { recursive: true });
@@ -187,7 +190,7 @@ describe("managed CES reconnection (real entrypoint)", () => {
187
190
  ...process.env,
188
191
  CES_MODE: "managed",
189
192
  CES_DATA_DIR: dataDir,
190
- CES_BOOTSTRAP_SOCKET: socketPath,
193
+ CES_BOOTSTRAP_SOCKET_DIR: socketDir,
191
194
  CES_HEALTH_PORT: String(healthPort),
192
195
  CES_ASSISTANT_DATA_MOUNT: assistantDataMount,
193
196
  },
@@ -17,6 +17,7 @@ import { readFileSync } from "node:fs";
17
17
  import { resolve } from "node:path";
18
18
  import { PassThrough } from "node:stream";
19
19
 
20
+ import { resolveIpcEndpoint } from "@vellumai/ipc-server-utils";
20
21
  import {
21
22
  CES_PROTOCOL_VERSION,
22
23
  type HandshakeAck,
@@ -399,36 +400,49 @@ describe("CES data paths", () => {
399
400
  expect(root).not.toMatch(/workspace/);
400
401
  });
401
402
 
402
- test("getBootstrapSocketPath defaults to /run/ces-bootstrap/ces.sock", () => {
403
- const saved = process.env["CES_BOOTSTRAP_SOCKET"];
404
- delete process.env["CES_BOOTSTRAP_SOCKET"];
403
+ test("getBootstrapSocketPath defaults to /run/ces-bootstrap", () => {
404
+ const savedDir = process.env["CES_BOOTSTRAP_SOCKET_DIR"];
405
+ delete process.env["CES_BOOTSTRAP_SOCKET_DIR"];
405
406
  try {
406
- expect(getBootstrapSocketPath()).toBe("/run/ces-bootstrap/ces.sock");
407
+ expect(getBootstrapSocketPath()).toBe(
408
+ resolveIpcEndpoint("ces", {
409
+ workspaceDir: "/run/ces-bootstrap",
410
+ }).path,
411
+ );
407
412
  } finally {
408
- if (saved !== undefined) process.env["CES_BOOTSTRAP_SOCKET"] = saved;
413
+ if (savedDir !== undefined) {
414
+ process.env["CES_BOOTSTRAP_SOCKET_DIR"] = savedDir;
415
+ } else {
416
+ delete process.env["CES_BOOTSTRAP_SOCKET_DIR"];
417
+ }
409
418
  }
410
419
  });
411
420
 
412
- test("getBootstrapSocketPath respects CES_BOOTSTRAP_SOCKET env var", () => {
413
- const savedSocket = process.env["CES_BOOTSTRAP_SOCKET"];
421
+ test("getBootstrapSocketPath uses CES_BOOTSTRAP_SOCKET_DIR via resolveIpcEndpoint", () => {
414
422
  const savedDir = process.env["CES_BOOTSTRAP_SOCKET_DIR"];
415
- // CES_BOOTSTRAP_SOCKET_DIR takes precedence; clear it so the
416
- // CES_BOOTSTRAP_SOCKET fallback is actually exercised.
417
- delete process.env["CES_BOOTSTRAP_SOCKET_DIR"];
418
- process.env["CES_BOOTSTRAP_SOCKET"] = "/tmp/test-ces.sock";
423
+ const savedWorkspace = process.env["VELLUM_WORKSPACE_DIR"];
424
+ process.env["CES_BOOTSTRAP_SOCKET_DIR"] = "/tmp/ces-bootstrap";
425
+ process.env["VELLUM_WORKSPACE_DIR"] = "/tmp/ces-ws";
419
426
  try {
420
- expect(getBootstrapSocketPath()).toBe("/tmp/test-ces.sock");
427
+ expect(getBootstrapSocketPath()).toBe(
428
+ resolveIpcEndpoint("ces", {
429
+ workspaceDir: "/tmp/ces-bootstrap",
430
+ }).path,
431
+ );
432
+ expect(getBootstrapSocketPath()).not.toBe(
433
+ resolveIpcEndpoint("ces", { workspaceDir: "/tmp/ces-ws" }).path,
434
+ );
421
435
  } finally {
422
- if (savedSocket !== undefined) {
423
- process.env["CES_BOOTSTRAP_SOCKET"] = savedSocket;
424
- } else {
425
- delete process.env["CES_BOOTSTRAP_SOCKET"];
426
- }
427
436
  if (savedDir !== undefined) {
428
437
  process.env["CES_BOOTSTRAP_SOCKET_DIR"] = savedDir;
429
438
  } else {
430
439
  delete process.env["CES_BOOTSTRAP_SOCKET_DIR"];
431
440
  }
441
+ if (savedWorkspace !== undefined) {
442
+ process.env["VELLUM_WORKSPACE_DIR"] = savedWorkspace;
443
+ } else {
444
+ delete process.env["VELLUM_WORKSPACE_DIR"];
445
+ }
432
446
  }
433
447
  });
434
448
  });
package/src/main.ts CHANGED
@@ -41,7 +41,6 @@ import {
41
41
  getCesLogDir,
42
42
  getCesMode,
43
43
  getHealthPort,
44
- getLocalSocketPath,
45
44
  getSecurityDir,
46
45
  type CesMode,
47
46
  } from "./paths.js";
@@ -399,8 +398,7 @@ async function main(): Promise<void> {
399
398
  }
400
399
 
401
400
  // -- Socket server ---------------------------------------------------------
402
- const socketPath =
403
- mode === "managed" ? getBootstrapSocketPath() : getLocalSocketPath();
401
+ const socketPath = getBootstrapSocketPath();
404
402
 
405
403
  const rpcLog = getLogger("rpc");
406
404
  const rpcLogger = {
package/src/paths.ts CHANGED
@@ -22,6 +22,8 @@
22
22
  import { join } from "node:path";
23
23
  import { homedir } from "node:os";
24
24
 
25
+ import { resolveIpcEndpoint } from "@vellumai/ipc-server-utils";
26
+
25
27
  // ---------------------------------------------------------------------------
26
28
  // Mode detection
27
29
  // ---------------------------------------------------------------------------
@@ -90,65 +92,28 @@ export function getCesLogDir(mode?: CesMode): string {
90
92
  }
91
93
 
92
94
  // ---------------------------------------------------------------------------
93
- // Bootstrap socket path (managed mode only)
95
+ // CES socket path (local sibling and managed sidecar)
94
96
  // ---------------------------------------------------------------------------
95
97
 
96
- /** Default directory for the bootstrap Unix socket shared volume. */
98
+ /** Default directory for the CES Unix socket. */
97
99
  const BOOTSTRAP_SOCKET_DIR = "/run/ces-bootstrap";
98
100
 
99
- /** Default bootstrap socket filename. */
100
- const BOOTSTRAP_SOCKET_NAME = "ces.sock";
101
-
102
101
  /**
103
- * Return the path to the bootstrap Unix socket.
102
+ * Return the path to the CES Unix socket used in every environment.
104
103
  *
105
- * In managed mode, CES listens on this socket for exactly one assistant
106
- * connection, then unlinks it. The path is on a shared `emptyDir` volume
107
- * visible to both containers.
104
+ * Local siblings and managed sidecars share this resolver. The assistant
105
+ * dials the same path CES binds.
108
106
  *
109
- * Priority:
110
- * 1. `CES_BOOTSTRAP_SOCKET_DIR` env var (directory) — appends `ces.sock`
111
- * 2. `CES_BOOTSTRAP_SOCKET` env var (full file path override)
112
- * 3. Hardcoded default: `/run/ces-bootstrap/ces.sock`
107
+ * Uses `CES_BOOTSTRAP_SOCKET_DIR` when set, otherwise `/run/ces-bootstrap`.
108
+ * `ces.sock` is resolved through `resolveIpcEndpoint` so macOS AF_UNIX
109
+ * limits and Windows named pipes stay consistent.
113
110
  *
114
- * The pod template exports `CES_BOOTSTRAP_SOCKET_DIR`; the full-path
115
- * override is kept for local testing convenience.
111
+ * The pod template and local CLI export `CES_BOOTSTRAP_SOCKET_DIR`.
116
112
  */
117
113
  export function getBootstrapSocketPath(): string {
118
- const dir = process.env["CES_BOOTSTRAP_SOCKET_DIR"];
119
- if (dir) {
120
- return join(dir, BOOTSTRAP_SOCKET_NAME);
121
- }
122
- return (
123
- process.env["CES_BOOTSTRAP_SOCKET"] ??
124
- join(BOOTSTRAP_SOCKET_DIR, BOOTSTRAP_SOCKET_NAME)
125
- );
126
- }
127
-
128
- // ---------------------------------------------------------------------------
129
- // Local-mode CES socket
130
- // ---------------------------------------------------------------------------
131
-
132
- /** Default local-mode CES socket filename (under the local data root). */
133
- const LOCAL_SOCKET_NAME = "ces.sock";
134
-
135
- /**
136
- * Return the path to the local-mode CES Unix socket.
137
- *
138
- * Used when local CES runs as a CLI-launched sibling process. The socket
139
- * lives under the CES-private local data root, whose directory permissions
140
- * are the access boundary.
141
- *
142
- * Priority:
143
- * 1. `CES_LOCAL_SOCKET` env var (full file path override; the CLI sets this
144
- * when launching the sibling).
145
- * 2. Default: `<localDataRoot>/ces.sock`.
146
- */
147
- export function getLocalSocketPath(): string {
148
- return (
149
- process.env["CES_LOCAL_SOCKET"] ??
150
- join(getCesDataRoot("local"), LOCAL_SOCKET_NAME)
151
- );
114
+ const dir =
115
+ process.env["CES_BOOTSTRAP_SOCKET_DIR"]?.trim() || BOOTSTRAP_SOCKET_DIR;
116
+ return resolveIpcEndpoint("ces", { workspaceDir: dir }).path;
152
117
  }
153
118
 
154
119
  // ---------------------------------------------------------------------------