@caplets/core 0.25.1 → 0.26.0

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.
@@ -10243,7 +10243,7 @@ const capletMcpServerSchema = object({
10243
10243
  path: ["url"],
10244
10244
  message: "remote servers require url"
10245
10245
  });
10246
- if (server.url && !hasEnvReference$2(server.url) && !isAllowedRemoteUrl(server.url)) ctx.addIssue({
10246
+ if (server.url && !hasInterpolationReference(server.url) && !isAllowedRemoteUrl(server.url)) ctx.addIssue({
10247
10247
  code: "custom",
10248
10248
  path: ["url"],
10249
10249
  message: "remote url must use https except loopback development urls"
@@ -10256,7 +10256,7 @@ const capletMcpServerSchema = object({
10256
10256
  "redirectUri"
10257
10257
  ]) {
10258
10258
  const value = server.auth[field];
10259
- if (value && !hasEnvReference$2(value) && !isUrl(value)) ctx.addIssue({
10259
+ if (value && !hasInterpolationReference(value) && !isUrl(value)) ctx.addIssue({
10260
10260
  code: "custom",
10261
10261
  path: ["auth", field],
10262
10262
  message: `${field} must be a URL or environment reference`
@@ -10290,12 +10290,12 @@ const capletOpenApiEndpointSchema = object({
10290
10290
  code: "custom",
10291
10291
  message: "openapiEndpoint must define exactly one spec source: specPath or specUrl"
10292
10292
  });
10293
- if (endpoint.specUrl && !hasEnvReference$2(endpoint.specUrl) && !isAllowedRemoteUrl(endpoint.specUrl)) ctx.addIssue({
10293
+ if (endpoint.specUrl && !hasInterpolationReference(endpoint.specUrl) && !isAllowedRemoteUrl(endpoint.specUrl)) ctx.addIssue({
10294
10294
  code: "custom",
10295
10295
  path: ["specUrl"],
10296
10296
  message: "OpenAPI specUrl must use https except loopback development urls"
10297
10297
  });
10298
- if (endpoint.baseUrl && !hasEnvReference$2(endpoint.baseUrl) && !isAllowedRemoteUrl(endpoint.baseUrl)) ctx.addIssue({
10298
+ if (endpoint.baseUrl && !hasInterpolationReference(endpoint.baseUrl) && !isAllowedRemoteUrl(endpoint.baseUrl)) ctx.addIssue({
10299
10299
  code: "custom",
10300
10300
  path: ["baseUrl"],
10301
10301
  message: "OpenAPI baseUrl must use https except loopback development urls"
@@ -10320,12 +10320,12 @@ const capletGoogleDiscoveryApiSchema = object({
10320
10320
  code: "custom",
10321
10321
  message: "googleDiscoveryApi must define exactly one discovery source: discoveryPath or discoveryUrl"
10322
10322
  });
10323
- if (api.discoveryUrl && !hasEnvReference$2(api.discoveryUrl) && !isAllowedRemoteUrl(api.discoveryUrl)) ctx.addIssue({
10323
+ if (api.discoveryUrl && !hasInterpolationReference(api.discoveryUrl) && !isAllowedRemoteUrl(api.discoveryUrl)) ctx.addIssue({
10324
10324
  code: "custom",
10325
10325
  path: ["discoveryUrl"],
10326
10326
  message: "Google Discovery discoveryUrl must use https except loopback development urls"
10327
10327
  });
10328
- if (api.baseUrl && !hasEnvReference$2(api.baseUrl) && !isAllowedHttpBaseUrl(api.baseUrl)) ctx.addIssue({
10328
+ if (api.baseUrl && !hasInterpolationReference(api.baseUrl) && !isAllowedHttpBaseUrl(api.baseUrl)) ctx.addIssue({
10329
10329
  code: "custom",
10330
10330
  path: ["baseUrl"],
10331
10331
  message: "Google Discovery baseUrl must use https except loopback development urls and must not include credentials, query, or fragment"
@@ -10362,12 +10362,12 @@ const capletGraphQlEndpointSchema = object({
10362
10362
  code: "custom",
10363
10363
  message: "graphqlEndpoint must define exactly one schema source: schemaPath, schemaUrl, or introspection"
10364
10364
  });
10365
- if (endpoint.endpointUrl && !hasEnvReference$2(endpoint.endpointUrl) && !isAllowedRemoteUrl(endpoint.endpointUrl)) ctx.addIssue({
10365
+ if (endpoint.endpointUrl && !hasInterpolationReference(endpoint.endpointUrl) && !isAllowedRemoteUrl(endpoint.endpointUrl)) ctx.addIssue({
10366
10366
  code: "custom",
10367
10367
  path: ["endpointUrl"],
10368
10368
  message: "GraphQL endpointUrl must use https except loopback development urls"
10369
10369
  });
10370
- if (endpoint.schemaUrl && !hasEnvReference$2(endpoint.schemaUrl) && !isAllowedRemoteUrl(endpoint.schemaUrl)) ctx.addIssue({
10370
+ if (endpoint.schemaUrl && !hasInterpolationReference(endpoint.schemaUrl) && !isAllowedRemoteUrl(endpoint.schemaUrl)) ctx.addIssue({
10371
10371
  code: "custom",
10372
10372
  path: ["schemaUrl"],
10373
10373
  message: "GraphQL schemaUrl must use https except loopback development urls"
@@ -10411,7 +10411,7 @@ const capletHttpApiSchema = object({
10411
10411
  projectBinding: capletProjectBindingSchema.optional(),
10412
10412
  runtime: capletRuntimeRequirementsSchema.optional()
10413
10413
  }).strict().superRefine((api, ctx) => {
10414
- if (api.baseUrl && !hasEnvReference$2(api.baseUrl) && !isAllowedHttpBaseUrl(api.baseUrl)) ctx.addIssue({
10414
+ if (api.baseUrl && !hasInterpolationReference(api.baseUrl) && !isAllowedHttpBaseUrl(api.baseUrl)) ctx.addIssue({
10415
10415
  code: "custom",
10416
10416
  path: ["baseUrl"],
10417
10417
  message: "HTTP API baseUrl must use https except loopback development urls and must not include credentials, query, or fragment"
@@ -10716,7 +10716,7 @@ function normalizeGraphQlOperations(operations, baseDir, normalizePath) {
10716
10716
  }]));
10717
10717
  }
10718
10718
  function normalizeBundleLocalPath(value, baseDir) {
10719
- if (!value || isMapAbsolutePath(value) || hasEnvReference$2(value)) return value;
10719
+ if (!value || isMapAbsolutePath(value) || hasInterpolationReference(value)) return value;
10720
10720
  const parts = [...baseDir ? baseDir.split("/") : [], ...value.split("/")];
10721
10721
  const normalized = [];
10722
10722
  for (const part of parts) {
@@ -10796,8 +10796,8 @@ function validateCapletId(id, path) {
10796
10796
  function errorMessage$1(error) {
10797
10797
  return error instanceof Error ? error.message : String(error);
10798
10798
  }
10799
- function hasEnvReference$2(value) {
10800
- return /\$\{[A-Za-z_][A-Za-z0-9_]*\}|\$env:[A-Za-z_][A-Za-z0-9_]*/.test(value);
10799
+ function hasInterpolationReference(value) {
10800
+ return /\$\{[A-Za-z_][A-Za-z0-9_]*\}|\$env:[A-Za-z_][A-Za-z0-9_]*|\$\{vault:[^}]+\}|\$vault:[A-Za-z0-9_-]+/.test(value);
10801
10801
  }
10802
10802
  //#endregion
10803
10803
  //#region src/config-runtime.ts
@@ -70,6 +70,7 @@ export declare function localAuthTargets(options: {
70
70
  })[];
71
71
  export declare function localAuthConfigForTarget(options: {
72
72
  serverId: string;
73
+ authDir?: string | undefined;
73
74
  configPath?: string;
74
75
  projectConfigPath?: string;
75
76
  source: Exclude<AuthSource, "remote">;
@@ -31,8 +31,9 @@ export declare const cliCommands: {
31
31
  readonly complete: "complete";
32
32
  readonly config: "config";
33
33
  readonly auth: "auth";
34
+ readonly vault: "vault";
34
35
  };
35
- export declare const topLevelCommandNames: readonly ["serve", "daemon", "code-mode", "attach", "remote", "cloud", "init", "setup", "doctor", "list", "install", "add", "inspect", "check-backend", "list-tools", "search-tools", "get-tool", "call-tool", "list-resources", "search-resources", "list-resource-templates", "read-resource", "list-prompts", "search-prompts", "get-prompt", "complete", "config", "auth", "completion"];
36
+ export declare const topLevelCommandNames: readonly ["serve", "daemon", "code-mode", "attach", "remote", "cloud", "init", "setup", "doctor", "list", "install", "add", "inspect", "check-backend", "list-tools", "search-tools", "get-tool", "call-tool", "list-resources", "search-resources", "list-resource-templates", "read-resource", "list-prompts", "search-prompts", "get-prompt", "complete", "config", "auth", "vault", "completion"];
36
37
  export declare const cliSubcommands: {
37
38
  readonly add: readonly ["cli", "mcp", "openapi", "google-discovery", "graphql", "http"];
38
39
  readonly auth: readonly ["login", "logout", "list", "refresh"];
@@ -43,11 +44,15 @@ export declare const cliSubcommands: {
43
44
  readonly config: readonly ["path", "paths"];
44
45
  readonly daemon: readonly ["install", "uninstall", "start", "restart", "stop", "status", "logs"];
45
46
  readonly setup: readonly ["codex", "claude-code", "opencode", "pi", "mcp-client"];
47
+ readonly vault: readonly ["set", "get", "list", "delete", "access"];
46
48
  };
47
49
  export declare const cliNestedSubcommands: {
48
50
  readonly remote: {
49
51
  readonly host: readonly ["pair", "clients", "revoke"];
50
52
  };
53
+ readonly vault: {
54
+ readonly access: readonly ["grant", "list", "revoke"];
55
+ };
51
56
  };
52
57
  export declare const capletIdCommands: Set<string>;
53
58
  export declare const qualifiedToolCommands: Set<string>;
@@ -17,6 +17,7 @@ export type DoctorJsonReport = {
17
17
  sync: Record<string, unknown>;
18
18
  daemon: Record<string, unknown>;
19
19
  remoteLogin: Record<string, unknown>;
20
+ vault: Record<string, unknown>;
20
21
  exposure: Record<string, unknown>;
21
22
  codeMode: Record<string, unknown>;
22
23
  };
@@ -0,0 +1,7 @@
1
+ import type { VaultAccessGrant, VaultDeleteStatus, VaultValueStatus } from "../vault";
2
+ export declare function formatVaultValueStatus(status: VaultValueStatus, json?: boolean): string;
3
+ export declare function formatVaultValueList(statuses: VaultValueStatus[], json?: boolean): string;
4
+ export declare function formatVaultDeleteStatus(status: VaultDeleteStatus, json?: boolean): string;
5
+ export declare function formatVaultAccessGrant(grant: VaultAccessGrant, json?: boolean): string;
6
+ export declare function formatVaultAccessList(grants: VaultAccessGrant[], json?: boolean): string;
7
+ export declare function formatVaultAccessRevoke(count: number, json?: boolean): string;
@@ -17,6 +17,49 @@ export type RegisterPresenceResult = {
17
17
  expiresAt: string;
18
18
  };
19
19
  export type HeartbeatPresenceResult = RegisterPresenceResult;
20
+ export type CloudVaultValueStatus = {
21
+ key: string;
22
+ present: boolean;
23
+ valueBytes?: number | undefined;
24
+ createdAt?: string | undefined;
25
+ updatedAt?: string | undefined;
26
+ };
27
+ export type CloudVaultAccessGrant = {
28
+ storedKey: string;
29
+ referenceName: string;
30
+ capletId: string;
31
+ origin?: {
32
+ kind: string;
33
+ path: string;
34
+ } | undefined;
35
+ createdAt?: string | undefined;
36
+ updatedAt?: string | undefined;
37
+ };
38
+ export type CloudVaultSetInput = {
39
+ workspace: string;
40
+ name: string;
41
+ value: string;
42
+ force?: boolean | undefined;
43
+ grant?: string | undefined;
44
+ referenceName?: string | undefined;
45
+ };
46
+ export type CloudVaultNameInput = {
47
+ workspace: string;
48
+ name: string;
49
+ };
50
+ export type CloudVaultGetInput = CloudVaultNameInput & {
51
+ reveal?: boolean | undefined;
52
+ revealContext?: "human-cli" | undefined;
53
+ };
54
+ export type CloudVaultAccessGrantInput = CloudVaultNameInput & {
55
+ capletId: string;
56
+ referenceName?: string | undefined;
57
+ };
58
+ export type CloudVaultAccessListInput = {
59
+ workspace: string;
60
+ name?: string | undefined;
61
+ capletId?: string | undefined;
62
+ };
20
63
  export declare class CapletsCloudClient {
21
64
  private readonly options;
22
65
  private readonly fetchImpl;
@@ -25,6 +68,22 @@ export declare class CapletsCloudClient {
25
68
  stopPresence(presenceId: string): Promise<void>;
26
69
  heartbeatPresence(presenceId: string): Promise<HeartbeatPresenceResult>;
27
70
  updatePresenceCaplets(presenceId: string, allowedCapletIds: string[]): Promise<void>;
71
+ setVaultValue(input: CloudVaultSetInput): Promise<CloudVaultValueStatus>;
72
+ getVaultValue(input: CloudVaultGetInput): Promise<CloudVaultValueStatus | {
73
+ key: string;
74
+ value: string;
75
+ }>;
76
+ listVaultValues(input: {
77
+ workspace: string;
78
+ }): Promise<CloudVaultValueStatus[]>;
79
+ deleteVaultValue(input: CloudVaultNameInput): Promise<{
80
+ key: string;
81
+ deleted: boolean;
82
+ grantsRetained?: number | undefined;
83
+ }>;
84
+ grantVaultAccess(input: CloudVaultAccessGrantInput): Promise<CloudVaultAccessGrant>;
85
+ listVaultAccess(input: CloudVaultAccessListInput): Promise<CloudVaultAccessGrant[]>;
86
+ revokeVaultAccess(input: CloudVaultAccessGrantInput): Promise<CloudVaultAccessGrant[]>;
28
87
  private headers;
29
88
  private endpoint;
30
89
  }
@@ -1,4 +1,4 @@
1
- import { Dt as DEFAULT_AUTH_DIR, Ft as resolveConfigPath, Lt as resolveProjectConfigPath, Nn as __exportAll, Ot as DEFAULT_COMPLETION_CACHE_DIR, Pt as resolveCapletsRoot, ct as loadConfigWithSources } from "./service-Ut6dN9M8.js";
1
+ import { Bn as __exportAll, Ft as DEFAULT_COMPLETION_CACHE_DIR, Ht as resolveConfigPath, Pt as DEFAULT_AUTH_DIR, Vt as resolveCapletsRoot, Wt as resolveProjectConfigPath, lt as loadConfigWithSources } from "./service-rvZ7z6FI.js";
2
2
  import { u as CapletsError } from "./validation-C4tYXw6G.js";
3
3
  import { mkdirSync, readFileSync, renameSync, writeFileSync } from "node:fs";
4
4
  import { dirname, join } from "node:path";
@@ -41,7 +41,8 @@ const cliCommands = {
41
41
  getPrompt: "get-prompt",
42
42
  complete: "complete",
43
43
  config: "config",
44
- auth: "auth"
44
+ auth: "auth",
45
+ vault: "vault"
45
46
  };
46
47
  const topLevelCommandNames = [
47
48
  cliCommands.serve,
@@ -72,6 +73,7 @@ const topLevelCommandNames = [
72
73
  cliCommands.complete,
73
74
  cliCommands.config,
74
75
  cliCommands.auth,
76
+ cliCommands.vault,
75
77
  cliCommands.completion
76
78
  ];
77
79
  const cliSubcommands = {
@@ -114,13 +116,27 @@ const cliSubcommands = {
114
116
  "opencode",
115
117
  "pi",
116
118
  "mcp-client"
119
+ ],
120
+ [cliCommands.vault]: [
121
+ "set",
122
+ "get",
123
+ "list",
124
+ "delete",
125
+ "access"
117
126
  ]
118
127
  };
119
- const cliNestedSubcommands = { [cliCommands.remote]: { host: [
120
- "pair",
121
- "clients",
122
- "revoke"
123
- ] } };
128
+ const cliNestedSubcommands = {
129
+ [cliCommands.remote]: { host: [
130
+ "pair",
131
+ "clients",
132
+ "revoke"
133
+ ] },
134
+ [cliCommands.vault]: { access: [
135
+ "grant",
136
+ "list",
137
+ "revoke"
138
+ ] }
139
+ };
124
140
  const capletIdCommands = /* @__PURE__ */ new Set([
125
141
  cliCommands.inspect,
126
142
  cliCommands.checkBackend,
package/dist/config.d.ts CHANGED
@@ -1,4 +1,5 @@
1
1
  import { z } from "zod";
2
+ import { FileVaultStore, type VaultConfigOrigin } from "./vault";
2
3
  export { DEFAULT_AUTH_DIR, DEFAULT_COMPLETION_CACHE_DIR, DEFAULT_CONFIG_PATH, PROJECT_CONFIG_FILE, defaultCacheBaseDir, defaultCompletionCacheDir, resolveCapletsRoot, resolveConfigPath, resolveProjectCapletsRoot, resolveProjectConfigPath, } from "./config/paths";
3
4
  export type RemoteAuthConfig = {
4
5
  type: "none";
@@ -303,6 +304,29 @@ export type LocalOverlayConfigWarning = {
303
304
  };
304
305
  export type LocalOverlayConfigWithSources = ConfigWithSources & {
305
306
  warnings: LocalOverlayConfigWarning[];
307
+ sourceFound: boolean;
308
+ };
309
+ export type ConfigVaultReference = {
310
+ referenceName: string;
311
+ capletId: string;
312
+ origin: VaultConfigOrigin;
313
+ path: string;
314
+ };
315
+ export type ConfigVaultResolution = {
316
+ storedKey: string;
317
+ value: string;
318
+ } | {
319
+ reason: "missing" | "ungranted" | "unavailable" | "invalid-key-source";
320
+ storedKey?: string | undefined;
321
+ referenceName: string;
322
+ capletId: string;
323
+ origin: VaultConfigOrigin;
324
+ };
325
+ export type ConfigVaultResolver = (reference: ConfigVaultReference) => ConfigVaultResolution;
326
+ export type ConfigParseOptions = {
327
+ sources?: Record<string, ConfigSource> | undefined;
328
+ vaultResolver?: ConfigVaultResolver | undefined;
329
+ vaultRecoveryTarget?: "global" | "remote" | undefined;
306
330
  };
307
331
  export declare const configFileSchema: z.ZodObject<{
308
332
  $schema: z.ZodOptional<z.ZodString>;
@@ -335,16 +359,25 @@ export declare const configFileSchema: z.ZodObject<{
335
359
  capletSets: z.ZodDefault<z.ZodRecord<z.ZodString, z.ZodType<unknown, unknown, z.core.$ZodTypeInternals<unknown, unknown>>>>;
336
360
  }, z.core.$strict>;
337
361
  export declare function configJsonSchema(): unknown;
338
- export declare function loadConfig(path?: string, projectPath?: string): CapletsConfig;
339
- export declare function loadConfigWithSources(path?: string, projectPath?: string): ConfigWithSources;
340
- export declare function loadGlobalConfig(path?: string): CapletsConfig;
341
- export declare function loadProjectConfig(projectPath?: string): CapletsConfig;
342
- export declare function loadLocalOverlayConfigWithSources(path?: string, projectPath?: string): LocalOverlayConfigWithSources;
362
+ export declare function loadConfig(path?: string, projectPath?: string, options?: Pick<ConfigParseOptions, "vaultResolver">): CapletsConfig;
363
+ export declare function loadConfigWithSources(path?: string, projectPath?: string, options?: Pick<ConfigParseOptions, "vaultResolver">): ConfigWithSources;
364
+ export declare function loadGlobalConfig(path?: string, options?: Pick<ConfigParseOptions, "vaultResolver">): CapletsConfig;
365
+ export declare function loadProjectConfig(projectPath?: string, options?: Pick<ConfigParseOptions, "vaultResolver">): CapletsConfig;
366
+ export declare function loadLocalOverlayConfigWithSources(path?: string, projectPath?: string, options?: Pick<ConfigParseOptions, "vaultResolver" | "vaultRecoveryTarget">): LocalOverlayConfigWithSources;
367
+ export declare function loadLocalRuntimeConfig(path?: string, projectPath?: string, options?: Pick<ConfigParseOptions, "vaultResolver" | "vaultRecoveryTarget"> & {
368
+ writeWarning?: ((warning: LocalOverlayConfigWarning) => void) | undefined;
369
+ }): CapletsConfig;
370
+ export declare function defaultVaultResolver(store?: FileVaultStore): ConfigVaultResolver;
371
+ export declare function vaultStoreForAuthDir(authDir: string | undefined): FileVaultStore;
372
+ export declare function vaultResolverForAuthDir(authDir: string | undefined): ConfigVaultResolver;
373
+ export declare const vaultBootstrapResolver: ConfigVaultResolver;
343
374
  export declare function loadIsolatedConfig(options: {
344
375
  configPath?: string;
345
376
  capletsRoot?: string;
346
377
  defaultSearchLimit: number;
347
378
  maxSearchLimit: number;
379
+ vaultResolver?: ConfigVaultResolver | undefined;
380
+ vaultRecoveryTarget?: ConfigParseOptions["vaultRecoveryTarget"];
348
381
  }): CapletsConfig;
349
- export declare function parseConfig(input: unknown): CapletsConfig;
382
+ export declare function parseConfig(input: unknown, options?: ConfigParseOptions): CapletsConfig;
350
383
  export declare function interpolateEnv(value: string): string;
package/dist/engine.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { type CapletConfig, type CapletsConfig } from "./config";
1
+ import { type CapletConfig, type CapletsConfig, type LocalOverlayConfigWarning } from "./config";
2
2
  import { type ObservedOutputShapeKey, type ObservedOutputShapeStore } from "./observed-output-shapes";
3
3
  import { type ExposureSnapshot } from "./exposure/discovery";
4
4
  export type CapletsEngineOptions = {
@@ -10,11 +10,14 @@ export type CapletsEngineOptions = {
10
10
  watchDebounceMs?: number;
11
11
  watch?: boolean;
12
12
  writeErr?: (value: string) => void;
13
- configLoader?: (configPath: string, projectConfigPath: string) => CapletsConfig;
13
+ configLoader?: (configPath: string, projectConfigPath: string, options?: {
14
+ writeWarning?: ((warning: LocalOverlayConfigWarning) => void) | undefined;
15
+ }) => CapletsConfig;
14
16
  observedOutputShapeStore?: ObservedOutputShapeStore | undefined;
15
17
  observedOutputShapeScope?: ObservedOutputShapeKey["scope"] | undefined;
16
18
  observedOutputShapeCacheDir?: string | undefined;
17
19
  projectFingerprint?: string | undefined;
20
+ vaultRecoveryTarget?: "global" | "remote" | undefined;
18
21
  };
19
22
  export type CapletsEngineReloadEvent = {
20
23
  previous: CapletsConfig;
@@ -68,6 +71,7 @@ export declare class CapletsEngine {
68
71
  private callTool;
69
72
  private optionalMcpList;
70
73
  private reloadOnce;
74
+ private loadConfigWithWarnings;
71
75
  private reloadUntilSettled;
72
76
  private emitReload;
73
77
  private invalidateChangedBackends;