@vellumai/cli 0.12.3-staging.1 → 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",
@@ -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
+ }
@@ -222,13 +222,6 @@ function defaultPorts(env: Record<string, string | undefined>): {
222
222
  };
223
223
  }
224
224
 
225
- function defaultInstanceDir(
226
- env: Record<string, string | undefined>,
227
- assistantId: string,
228
- ): string {
229
- return resolveInstanceDir(env, assistantId);
230
- }
231
-
232
225
  function firstString(...values: unknown[]): string | undefined {
233
226
  for (const value of values) {
234
227
  if (typeof value === "string" && value.length > 0) return value;
@@ -302,7 +295,7 @@ export function resolveLockfileInstanceDir(
302
295
  ok: true,
303
296
  instanceDir:
304
297
  lockfileInstanceDir(entry, rawEntry) ??
305
- defaultInstanceDir(env, assistantId),
298
+ resolveInstanceDir(env, assistantId),
306
299
  };
307
300
  } catch {
308
301
  return { ok: true };
@@ -320,7 +313,7 @@ function resolveStatusResources(
320
313
  const ports = defaultPorts(env);
321
314
  const instanceDir =
322
315
  lockfileInstanceDir(entry, rawEntry) ??
323
- defaultInstanceDir(env, entry.assistantId);
316
+ resolveInstanceDir(env, entry.assistantId);
324
317
  return {
325
318
  instanceDir,
326
319
  daemonPort:
@@ -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",
@@ -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
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vellumai/cli",
3
- "version": "0.12.3-staging.1",
3
+ "version": "0.12.3-staging.2",
4
4
  "description": "CLI tools for vellum-assistant",
5
5
  "type": "module",
6
6
  "exports": {
@@ -21,13 +21,20 @@ function printUsage(): void {
21
21
  console.log(" upvote <slug>");
22
22
  console.log(" unvote <slug>");
23
23
  console.log("");
24
+ console.log(
25
+ "update: --status and --tag are staff-only. Anyone else can edit only the",
26
+ );
27
+ console.log(
28
+ "title and description of an item they filed, while it is still open.",
29
+ );
30
+ console.log("");
24
31
  console.log("Examples:");
25
32
  console.log(' $ vellum roadmap list --query "dark mode"');
26
33
  console.log(" $ vellum roadmap list --status planned --sort upvotes");
27
34
  console.log(" $ vellum roadmap get my-feature-slug");
28
35
  console.log(' $ vellum roadmap create --title "Add dark mode"');
29
36
  console.log(
30
- " $ vellum roadmap update my-feature --status planned --tag integrations",
37
+ ' $ vellum roadmap update my-feature --description "Follow the OS setting"',
31
38
  );
32
39
  console.log(" $ vellum roadmap upvote my-feature-slug");
33
40
  }
package/src/lib/local.ts CHANGED
@@ -1181,14 +1181,6 @@ export async function startCes(
1181
1181
  }
1182
1182
  }
1183
1183
 
1184
- /**
1185
- * Check if the daemon is responsive by hitting its HTTP `/healthz` endpoint.
1186
- * This replaces the socket-based `isSocketResponsive()` check.
1187
- */
1188
- async function isDaemonResponsive(daemonPort: number): Promise<boolean> {
1189
- return httpHealthCheck(daemonPort);
1190
- }
1191
-
1192
1184
  /**
1193
1185
  * Find the PID of the process listening on the given TCP port.
1194
1186
  * Uses `lsof` on macOS/Linux. Returns undefined if no listener is found
@@ -1284,7 +1276,7 @@ async function checkOrphanedDaemon(
1284
1276
  pidFile: string,
1285
1277
  daemonPort: number,
1286
1278
  ): Promise<boolean> {
1287
- if (!(await isDaemonResponsive(daemonPort))) return false;
1279
+ if (!(await httpHealthCheck(daemonPort))) return false;
1288
1280
 
1289
1281
  const recoveredPid = recoverPidFile(pidFile, daemonPort);
1290
1282
  if (recoveredPid) {
@@ -1682,7 +1674,7 @@ export async function startLocalDaemon(
1682
1674
  const daemonSpawnEnv = envWithCompiledRuntimeNodePath(daemonEnv);
1683
1675
 
1684
1676
  // Write a sentinel PID file before spawning so concurrent hatch() calls
1685
- // see the file and fall through to the isDaemonResponsive() port check
1677
+ // see the file and fall through to the httpHealthCheck() port check
1686
1678
  // instead of racing to spawn a duplicate daemon.
1687
1679
  writeFileSync(pidFile, "starting", "utf-8");
1688
1680
 
@@ -77,7 +77,7 @@ const PROVIDER_LABELS: Record<LlmProviderId, string> = {
77
77
  opencode: "OpenCode",
78
78
  baseten: "Baseten",
79
79
  poolside: "Poolside",
80
- jev: "Jev",
80
+ typesafe: "TypeSafe",
81
81
  };
82
82
 
83
83
  // litellm and opencode are deliberately excluded: they have no fixed default
@@ -248,7 +248,7 @@ export function inferProviderFromModel(model: string): string | undefined {
248
248
  return "poolside";
249
249
  }
250
250
  if (model === "jev-latest" || model.startsWith("jev-")) {
251
- return "jev";
251
+ return "typesafe";
252
252
  }
253
253
  if (model === "qwen/qwen3-8b") {
254
254
  // The only qwen/* ID the Vellum hosted provider carries; the rest are
@@ -34,7 +34,7 @@ export const LLM_PROVIDER_ENV_VAR_NAMES: Record<string, string> = {
34
34
  opencode: "OPENCODE_API_KEY",
35
35
  baseten: "BASETEN_API_KEY",
36
36
  poolside: "POOLSIDE_API_KEY",
37
- jev: "TYPESAFE_API_KEY",
37
+ typesafe: "TYPESAFE_API_KEY",
38
38
  };
39
39
 
40
40
  /** Search-provider env var names. Mirrors `SEARCH_PROVIDER_CATALOG` BYOK entries. */
@@ -45,6 +45,8 @@ export const SEARCH_PROVIDER_ENV_VAR_NAMES: Record<string, string> = {
45
45
  firecrawl: "FIRECRAWL_API_KEY",
46
46
  keenable: "KEENABLE_API_KEY",
47
47
  fastcrw: "FASTCRW_API_KEY",
48
+ searxng: "SEARXNG_API_KEY",
49
+ tinyfish: "TINYFISH_API_KEY",
48
50
  };
49
51
 
50
52
  /**