@caplets/core 0.28.1 → 0.29.1

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/dist/native.js CHANGED
@@ -1,4 +1,4 @@
1
- import { B as nativeCodeModeToolId, I as nativeCapletPromptGuidance, L as nativeCapletToolDescription, R as nativeCapletToolName, V as nativeCodeModeToolName, h as createSdkRemoteCapletsClient, m as RemoteNativeCapletsService, t as createNativeCapletsService, w as resolveNativeCapletsServiceOptions, z as nativeCapletsSystemGuidance } from "./service-B6YvNthO.js";
1
+ import { B as nativeCodeModeToolId, I as nativeCapletPromptGuidance, L as nativeCapletToolDescription, R as nativeCapletToolName, V as nativeCodeModeToolName, h as createSdkRemoteCapletsClient, m as RemoteNativeCapletsService, t as createNativeCapletsService, w as resolveNativeCapletsServiceOptions, z as nativeCapletsSystemGuidance } from "./service-DxPo2KUs.js";
2
2
  import { generatedToolInputJsonSchema, generatedToolInputSchema } from "./generated-tool-input-schema.js";
3
3
  //#region src/native/process-cleanup.ts
4
4
  function registerNativeCapletsProcessCleanup(service, options = {}) {
@@ -17221,6 +17221,13 @@ function defaultTelemetryNoticePath(env = process.env, home = homedir(), platfor
17221
17221
  function defaultTelemetryDeliveryHealthPath(env = process.env, home = homedir(), platform = process.platform) {
17222
17222
  return (platform === "win32" ? win32.join : posix.join)(defaultTelemetryStateDir(env, home, platform), "delivery-health.json");
17223
17223
  }
17224
+ function defaultUpdateCheckStateDir(env = process.env, home = homedir(), platform = process.platform) {
17225
+ return (platform === "win32" ? win32.join : posix.join)(defaultStateBaseDir(env, home, platform), "caplets", "update-check");
17226
+ }
17227
+ function defaultUpdateCheckCacheDir(env = process.env, home = homedir(), platform = process.platform) {
17228
+ const pathJoin = platform === "win32" ? win32.join : posix.join;
17229
+ return platform === "win32" ? pathJoin(defaultCacheBaseDir(env, home, platform), "caplets", "cache", "update-check") : pathJoin(defaultCacheBaseDir(env, home, platform), "caplets", "update-check");
17230
+ }
17224
17231
  function defaultArtifactDir(env = process.env, home = homedir(), platform = process.platform) {
17225
17232
  return (platform === "win32" ? win32.join : posix.join)(defaultStateBaseDir(env, home, platform), "caplets", "artifacts");
17226
17233
  }
@@ -17239,6 +17246,8 @@ const DEFAULT_TELEMETRY_STATE_DIR = defaultTelemetryStateDir();
17239
17246
  defaultTelemetryIdentityPath();
17240
17247
  defaultTelemetryNoticePath();
17241
17248
  defaultTelemetryDeliveryHealthPath();
17249
+ const DEFAULT_UPDATE_CHECK_STATE_DIR = defaultUpdateCheckStateDir();
17250
+ const DEFAULT_UPDATE_CHECK_CACHE_DIR = defaultUpdateCheckCacheDir();
17242
17251
  const DEFAULT_COMPLETION_CACHE_DIR = defaultCompletionCacheDir();
17243
17252
  const DEFAULT_OBSERVED_OUTPUT_SHAPE_CACHE_DIR = defaultObservedOutputShapeCacheDir();
17244
17253
  const PROJECT_CONFIG_FILE = join(".caplets", "config.json");
@@ -18173,23 +18182,33 @@ var DownstreamManager = class {
18173
18182
  const capabilities = (await this.connect(server)).client.getServerCapabilities() ?? {};
18174
18183
  const tools = await this.refreshTools(server, true);
18175
18184
  this.registry.setStatus(server.server, "available");
18185
+ const capabilitySummary = {
18186
+ tools: Boolean(capabilities.tools),
18187
+ resources: Boolean(capabilities.resources),
18188
+ resourceTemplates: Boolean(capabilities.resources),
18189
+ prompts: Boolean(capabilities.prompts),
18190
+ completions: Boolean(capabilities.completions)
18191
+ };
18176
18192
  const result = {
18177
18193
  id: server.server,
18178
18194
  status: "available",
18179
- capabilities: {
18180
- tools: Boolean(capabilities.tools),
18181
- resources: Boolean(capabilities.resources),
18182
- resourceTemplates: Boolean(capabilities.resources),
18183
- prompts: Boolean(capabilities.prompts),
18184
- completions: Boolean(capabilities.completions)
18185
- },
18195
+ capabilities: capabilitySummary,
18186
18196
  toolCount: tools.length,
18187
18197
  elapsedMs: Date.now() - startedAt
18188
18198
  };
18189
- if (capabilities.resources) Object.assign(result, {
18190
- resourceCount: (await this.listResources(server, true)).length,
18191
- resourceTemplateCount: (await this.listResourceTemplates(server, true)).length
18192
- });
18199
+ if (capabilities.resources) {
18200
+ let resourceTemplateCount = 0;
18201
+ try {
18202
+ resourceTemplateCount = (await this.listResourceTemplates(server, true)).length;
18203
+ } catch (error) {
18204
+ if (!isUnsupportedCapability$1(error)) throw error;
18205
+ capabilitySummary.resourceTemplates = false;
18206
+ }
18207
+ Object.assign(result, {
18208
+ resourceCount: (await this.listResources(server, true)).length,
18209
+ resourceTemplateCount
18210
+ });
18211
+ }
18193
18212
  if (capabilities.prompts) Object.assign(result, { promptCount: (await this.listPrompts(server, true)).length });
18194
18213
  return result;
18195
18214
  } catch (error) {
@@ -18252,11 +18271,23 @@ var DownstreamManager = class {
18252
18271
  if (!force && connection.resourceTemplates && this.isCacheFresh(connection.resourceTemplatesFetchedAt, server.toolCacheTtlMs)) return connection.resourceTemplates;
18253
18272
  const resourceTemplates = [];
18254
18273
  let cursor;
18255
- do {
18256
- const result = await connection.client.listResourceTemplates(cursor ? { cursor } : void 0, { timeout: server.startupTimeoutMs });
18257
- resourceTemplates.push(...result.resourceTemplates ?? []);
18258
- cursor = result.nextCursor;
18259
- } while (cursor);
18274
+ try {
18275
+ do {
18276
+ const result = await connection.client.listResourceTemplates(cursor ? { cursor } : void 0, { timeout: server.startupTimeoutMs });
18277
+ resourceTemplates.push(...result.resourceTemplates ?? []);
18278
+ cursor = result.nextCursor;
18279
+ } while (cursor);
18280
+ } catch (error) {
18281
+ if (isMcpMethodNotFoundError(error)) {
18282
+ connection.resourceTemplates = [];
18283
+ connection.resourceTemplatesFetchedAt = Date.now();
18284
+ throw new CapletsError("UNSUPPORTED_CAPABILITY", `${server.server} does not implement MCP resource templates`, {
18285
+ server: server.server,
18286
+ capability: "resourceTemplates"
18287
+ });
18288
+ }
18289
+ throw error;
18290
+ }
18260
18291
  connection.resourceTemplates = resourceTemplates;
18261
18292
  connection.resourceTemplatesFetchedAt = Date.now();
18262
18293
  return resourceTemplates;
@@ -18680,6 +18711,12 @@ function nearbyToolNames(tools, needle) {
18680
18711
  function isTimeoutLike(error) {
18681
18712
  return error instanceof Error && /timeout|timed out|aborted/i.test(error.message);
18682
18713
  }
18714
+ function isUnsupportedCapability$1(error) {
18715
+ return error instanceof CapletsError && error.code === "UNSUPPORTED_CAPABILITY";
18716
+ }
18717
+ function isMcpMethodNotFoundError(error) {
18718
+ return error instanceof Error && /MCP error -32601/i.test(error.message);
18719
+ }
18683
18720
  function stringifyPromptArgs(args) {
18684
18721
  const stringified = {};
18685
18722
  for (const [key, value] of Object.entries(args)) {
@@ -64478,7 +64515,7 @@ async function defaultSentryFactory(dsn) {
64478
64515
  }
64479
64516
  //#endregion
64480
64517
  //#region package.json
64481
- var version = "0.28.1";
64518
+ var version = "0.29.1";
64482
64519
  //#endregion
64483
64520
  //#region src/telemetry/runtime.ts
64484
64521
  function createRuntimeTelemetryContext(options) {
@@ -64855,7 +64892,7 @@ var CapletsEngine = class {
64855
64892
  }
64856
64893
  }
64857
64894
  async completeCliWords(words) {
64858
- const { completeCliWords } = await import("./completion-D9253pYs.js").then((n) => n.r);
64895
+ const { completeCliWords } = await import("./completion-CcNgCYzl.js").then((n) => n.r);
64859
64896
  return await completeCliWords(words, {
64860
64897
  config: this.registry.config,
64861
64898
  managers: {
@@ -82228,6 +82265,8 @@ function downstreamResourceUri$1(capletId, uri) {
82228
82265
  //#endregion
82229
82266
  //#region src/native/remote.ts
82230
82267
  const ATTACH_SESSION_UNSUPPORTED_RETRY_MS = 6e4;
82268
+ const ATTACH_SESSION_CREATE_TIMEOUT_MS = 5e3;
82269
+ const ATTACH_SESSION_CREATE_TIMED_OUT = Symbol("attach session create timed out");
82231
82270
  function createSdkRemoteCapletsClient(options) {
82232
82271
  const listeners = /* @__PURE__ */ new Set();
82233
82272
  let manifest;
@@ -82258,10 +82297,15 @@ function createSdkRemoteCapletsClient(options) {
82258
82297
  if (attachSessionsUnsupportedUntil > Date.now()) return void 0;
82259
82298
  attachSessionsUnsupportedUntil = 0;
82260
82299
  if (attachSessionId) return attachSessionId;
82261
- if (attachSessionInFlight) return await attachSessionInFlight;
82300
+ if (attachSessionInFlight) {
82301
+ const inFlightSessionId = await attachSessionInFlight;
82302
+ return inFlightSessionId === ATTACH_SESSION_CREATE_TIMED_OUT ? void 0 : inFlightSessionId;
82303
+ }
82262
82304
  attachSessionInFlight = createAttachSession(runtimeOptions.url, runtimeOptions.requestInit, fetchFor(runtimeOptions), options.attachSessionMetadata);
82263
82305
  try {
82264
- attachSessionId = await attachSessionInFlight;
82306
+ const createdSessionId = await attachSessionInFlight;
82307
+ if (createdSessionId === ATTACH_SESSION_CREATE_TIMED_OUT) return;
82308
+ attachSessionId = createdSessionId;
82265
82309
  if (!attachSessionId) attachSessionsUnsupportedUntil = Date.now() + ATTACH_SESSION_UNSUPPORTED_RETRY_MS;
82266
82310
  return attachSessionId;
82267
82311
  } finally {
@@ -82382,8 +82426,8 @@ function createSdkRemoteCapletsClient(options) {
82382
82426
  eventsAbort?.abort();
82383
82427
  eventsAbort = void 0;
82384
82428
  listeners.clear();
82385
- const pendingSessionId = await attachSessionInFlight?.catch(() => void 0);
82386
- const sessionId = attachSessionId ?? pendingSessionId;
82429
+ const pendingSessionResult = await attachSessionInFlight?.catch(() => void 0);
82430
+ const sessionId = attachSessionId ?? (typeof pendingSessionResult === "string" ? pendingSessionResult : void 0);
82387
82431
  attachSessionId = void 0;
82388
82432
  if (sessionId) await (async () => {
82389
82433
  const runtimeOptions = await resolveRuntimeOptions();
@@ -82606,12 +82650,39 @@ async function fetchAttachManifest(attachUrl, requestInit, attachSessionId, fetc
82606
82650
  async function createAttachSession(attachUrl, requestInit, fetchImpl, metadata) {
82607
82651
  const headers = new Headers(requestInit?.headers);
82608
82652
  headers.set("content-type", "application/json");
82609
- const response = await fetchImpl(new URL("sessions", slashUrl(attachUrl)), {
82653
+ let timeout;
82654
+ let timedOut = false;
82655
+ const sessionUrl = new URL("sessions", slashUrl(attachUrl));
82656
+ const timeoutReached = new Promise((resolve) => {
82657
+ timeout = setTimeout(() => {
82658
+ timedOut = true;
82659
+ resolve(ATTACH_SESSION_CREATE_TIMED_OUT);
82660
+ }, ATTACH_SESSION_CREATE_TIMEOUT_MS);
82661
+ timeout.unref?.();
82662
+ });
82663
+ const fetchSession = fetchImpl(sessionUrl, {
82610
82664
  ...requestInit,
82611
82665
  method: "POST",
82612
82666
  headers,
82613
82667
  body: JSON.stringify(metadata)
82668
+ }).catch((error) => {
82669
+ if (timedOut) return void 0;
82670
+ throw error;
82614
82671
  });
82672
+ fetchSession.then(async (response) => {
82673
+ if (!timedOut || !response?.ok) return;
82674
+ const lateSessionId = await attachSessionIdFromResponse(response).catch(() => void 0);
82675
+ if (!lateSessionId) return;
82676
+ await closeAttachSession(attachUrl, requestInit, fetchImpl, lateSessionId).catch(() => void 0);
82677
+ }).catch(() => void 0);
82678
+ let response;
82679
+ try {
82680
+ response = await Promise.race([fetchSession, timeoutReached]);
82681
+ } finally {
82682
+ if (timeout) clearTimeout(timeout);
82683
+ }
82684
+ if (response === ATTACH_SESSION_CREATE_TIMED_OUT) return ATTACH_SESSION_CREATE_TIMED_OUT;
82685
+ if (!response) return void 0;
82615
82686
  if (!response.ok) {
82616
82687
  if (response.status === 404) return void 0;
82617
82688
  let payload;
@@ -82623,9 +82694,16 @@ async function createAttachSession(attachUrl, requestInit, fetchImpl, metadata)
82623
82694
  if (response.status === 400 && isAttachSessionProjectContextRejected(payload)) return;
82624
82695
  throw new CapletsError("SERVER_UNAVAILABLE", `Caplets attach session returned HTTP ${response.status}.`);
82625
82696
  }
82697
+ return await parseAttachSessionIdResponse(response);
82698
+ }
82699
+ async function parseAttachSessionIdResponse(response) {
82700
+ const sessionId = await attachSessionIdFromResponse(response);
82701
+ if (!sessionId) throw new CapletsError("SERVER_UNAVAILABLE", "Caplets attach session response was invalid.");
82702
+ return sessionId;
82703
+ }
82704
+ async function attachSessionIdFromResponse(response) {
82626
82705
  const payload = await response.json();
82627
- if (!isPlainObject(payload) || typeof payload.sessionId !== "string") throw new CapletsError("SERVER_UNAVAILABLE", "Caplets attach session response was invalid.");
82628
- return payload.sessionId;
82706
+ return isPlainObject(payload) && typeof payload.sessionId === "string" ? payload.sessionId : void 0;
82629
82707
  }
82630
82708
  async function closeAttachSession(attachUrl, requestInit, fetchImpl, attachSessionId) {
82631
82709
  await fetchImpl(new URL(`sessions/${encodeURIComponent(attachSessionId)}`, slashUrl(attachUrl)), {
@@ -83631,10 +83709,12 @@ var FileRemoteProfileStore = class {
83631
83709
  kind: "self-hosted",
83632
83710
  hostUrl: normalizeRemoteProfileHostUrl(input.hostUrl)
83633
83711
  });
83712
+ const snapshot = await this.withMutationLock(async () => this.selfHostedRefreshSnapshot(key, input));
83713
+ if (!snapshot || !snapshot.needsRefresh) return snapshot?.result;
83634
83714
  return await this.withRefreshLock(key, async () => {
83635
- const snapshot = await this.withMutationLock(async () => this.selfHostedRefreshSnapshot(key, input));
83636
- if (!snapshot || !snapshot.needsRefresh) return snapshot?.result;
83637
- const refreshed = await input.refresh(snapshot.result.status, snapshot.result.credential);
83715
+ const lockedSnapshot = await this.withMutationLock(async () => this.selfHostedRefreshSnapshot(key, input));
83716
+ if (!lockedSnapshot || !lockedSnapshot.needsRefresh) return lockedSnapshot?.result;
83717
+ const refreshed = await input.refresh(lockedSnapshot.result.status, lockedSnapshot.result.credential);
83638
83718
  return await this.withMutationLock(async () => {
83639
83719
  const current = await this.selfHostedRefreshSnapshot(key, input);
83640
83720
  if (!current || !current.needsRefresh) return current?.result;
@@ -84282,6 +84362,7 @@ function requiredHostedCloudAttachScopes() {
84282
84362
  //#endregion
84283
84363
  //#region src/native/service.ts
84284
84364
  const REMOTE_PROJECT_BINDING_FALLBACK_WARNING = "Remote project binding unavailable; using local Caplets only. Run caplets doctor for details.\n";
84365
+ const SELF_HOSTED_PROJECT_BINDING_UNSUPPORTED_MESSAGE = "Self-hosted Project Binding sessions are not implemented by this runtime.";
84285
84366
  let hasWarnedRemoteProjectBindingFallback = false;
84286
84367
  function createNativeCapletsService(options = {}) {
84287
84368
  const resolved = resolveNativeCapletsServiceOptions(options);
@@ -85193,6 +85274,7 @@ var CompositeNativeCapletsService = class {
85193
85274
  }
85194
85275
  startPresence() {
85195
85276
  this.presence?.start().catch((error) => {
85277
+ if (isUnsupportedProjectBinding(error)) return;
85196
85278
  writeErr(this.options, `Could not start upstream Project Binding: ${errorMessage(error)}\n`);
85197
85279
  });
85198
85280
  }
@@ -85431,7 +85513,7 @@ var RemoteProjectBindingSessionManager = class {
85431
85513
  }
85432
85514
  };
85433
85515
  function isUnsupportedProjectBinding(error) {
85434
- return isRecord(error) && error.code === "UNSUPPORTED_CAPABILITY";
85516
+ return isRecord(error) && error.code === "UNSUPPORTED_CAPABILITY" && error.message === SELF_HOSTED_PROJECT_BINDING_UNSUPPORTED_MESSAGE;
85435
85517
  }
85436
85518
  function projectBindingUrl(attachUrl, ...segments) {
85437
85519
  const url = new URL(attachUrl);
@@ -85480,4 +85562,4 @@ function errorMessage(error) {
85480
85562
  return error instanceof Error ? error.message : String(error);
85481
85563
  }
85482
85564
  //#endregion
85483
- export { redactCodeModeLogText as $, getParseErrorMessage as $n, readTokenBundle as $t, resolveRemoteMode as A, GetPromptRequestSchema as An, loadProjectConfig as At, nativeCodeModeToolId as B, LoggingLevelSchema as Bn, discoverCapletFiles as Bt, CapletsCloudClient as C, CreateMessageResultSchema as Cn, ServerRegistry as Ct, normalizeRemoteProfileHostUrl as D, ElicitResultSchema as Dn, loadConfigWithSources as Dt, isCapletsCloudUrl as E, DEFAULT_NEGOTIATED_PROTOCOL_VERSION as En, loadConfig as Et, resolveCapletsServer as F, ListPromptsRequestSchema as Fn, FileVaultStore as Ft, runCodeMode as G, assertCompleteRequestPrompt as Gn, markdownStructuredContent as Gt, codeModeRunInputSchema as H, ReadResourceRequestSchema as Hn, loadCapletFilesFromMap as Ht, nativeCapletPromptGuidance as I, ListResourceTemplatesRequestSchema as In, VAULT_MAX_VALUE_BYTES as It, diagnoseCodeModeTypeScript as J, isJSONRPCErrorResponse as Jn, runOAuthFlow as Jt, CodeModeSessionManager as K, assertCompleteRequestResourceTemplate as Kn, refreshOAuthTokenBundle as Kt, nativeCapletToolDescription as L, ListResourcesRequestSchema as Ln, validateVaultKeyName as Lt, controlUrlForBase as M, InitializedNotificationSchema as Mn, vaultBootstrapResolver as Mt, isLoopbackHost as N, JSONRPCMessageSchema as Nn, vaultResolverForAuthDir as Nt, resolveCapletsRemote as O, EmptyResultSchema as On, loadGlobalConfig as Ot, parseServerBaseUrl as P, LATEST_PROTOCOL_VERSION as Pn, vaultStoreForAuthDir as Pt, CodeModeLogStore as Q, getObjectShape as Qn, isTokenBundleExpired as Qt, nativeCapletToolName as R, ListRootsResultSchema as Rn, decryptVaultValue as Rt, buildProjectSyncManifest as S, CompleteRequestSchema as Sn, handleServerTool as St, hostedCloudWorkspaceFromRemoteUrl as T, CreateTaskResultSchema as Tn, GoogleDiscoveryManager as Tt, codeModeRunParamsSchema as U, SUPPORTED_PROTOCOL_VERSIONS as Un, hasRenderableStructuredContent as Ut, nativeCodeModeToolName as V, McpError as Vn, validateCapletFile as Vt, emptyCodeModeRunMeta as W, SetLevelRequestSchema as Wn, markdownCallToolResultContent as Wt, listCodeModeCallableCaplets as X, isJSONRPCResultResponse as Xn, startOAuthFlow as Xt, createCodeModeCapletsApi as Y, isJSONRPCRequest as Yn, startGenericOAuthFlow as Yt, CodeModeJournalStore as Z, getLiteralValue as Zn, deleteTokenBundle as Zt, attachErrorResponse as _, Protocol as _n, rotateTelemetryIdentity as _t, CloudAuthStore as a, defaultConfigPath as an, safeParse as ar, version as at, invokeAttachExport$1 as b, CallToolRequestSchema as bn, findProjectRoot as bt, redactedCloudAuthStatus as c, resolveCapletsRoot as cn, buildProductTelemetryEvent as ct, projectBindingError as d, resolveProjectConfigPath as dn, maybePrintTelemetryNotice as dt, DEFAULT_AUTH_DIR as en, getSchemaDescription as er, codeModeDeclarationHash as et, projectBindingRecovery as f, ReadBuffer as fn, resolveTelemetryState as ft, CAPLETS_ATTACH_SESSION_HEADER as g, AjvJsonSchemaValidator as gn, readTelemetryNotice as gt, createSdkRemoteCapletsClient as h, assertToolsCallTaskCapability as hn, readTelemetryIdentity as ht, createRemoteProfileStore as i, defaultConfigBaseDir as in, objectFromShape as ir, CapletsEngine as it, appendBasePath as j, InitializeRequestSchema as jn, parseConfig as jt, resolveHostedCloudRemote as k, ErrorCode as kn, loadLocalOverlayConfigWithSources as kt, PROJECT_BINDING_ERROR_CODES as l, resolveConfigPath as ln, buildReliabilityTelemetryEvent as lt, RemoteNativeCapletsService as m, assertClientRequestTaskCapability as mn, readTelemetryDeliveryHealth as mt, resolveRemoteSelection as n, DEFAULT_OBSERVED_OUTPUT_SHAPE_CACHE_DIR as nn, isZ4Schema as nr, generateCodeModeRunToolDescription as nt, cloudAuthPath as o, defaultStateBaseDir as on, safeParseAsync as or, createTelemetryDispatcher as ot, CloudAuthClient as p, serializeMessage as pn, deleteTelemetryIdentity as pt, QuickJsCodeModeSandbox as q, isInitializeRequest as qn, runGenericOAuthFlow as qt, cloudCredentialsFromRemoteProfile as r, defaultCacheBaseDir as rn, normalizeObjectSchema as rr, minifyCodeModeDeclarationText as rt, migrateCredentials as s, defaultTelemetryStateDir as sn, TelemetryDebugSink as st, createNativeCapletsService as t, DEFAULT_COMPLETION_CACHE_DIR as tn, isSchemaOptional as tr, generateCodeModeDeclarations as tt, ProjectBindingError as u, resolveProjectCapletsRoot as un, durationBucket as ut, buildAttachProjection as v, mergeCapabilities as vn, resolveExposure as vt, resolveNativeCapletsServiceOptions as w, CreateMessageResultWithToolsSchema as wn, capabilityDescription as wt, invokeNativeAttachExport as x, CallToolResultSchema as xn, fingerprintProjectRoot as xt, buildNativeAttachProjection as y, toJsonSchemaCompat as yn, decodeDirectResourceUri as yt, nativeCapletsSystemGuidance as z, ListToolsRequestSchema as zn, encryptVaultValue as zt };
85565
+ export { redactCodeModeLogText as $, isJSONRPCRequest as $n, readTokenBundle as $t, resolveRemoteMode as A, DEFAULT_NEGOTIATED_PROTOCOL_VERSION as An, loadProjectConfig as At, nativeCodeModeToolId as B, ListResourceTemplatesRequestSchema as Bn, discoverCapletFiles as Bt, CapletsCloudClient as C, toJsonSchemaCompat as Cn, ServerRegistry as Ct, normalizeRemoteProfileHostUrl as D, CreateMessageResultSchema as Dn, loadConfigWithSources as Dt, isCapletsCloudUrl as E, CompleteRequestSchema as En, loadConfig as Et, resolveCapletsServer as F, InitializeRequestSchema as Fn, FileVaultStore as Ft, runCodeMode as G, McpError as Gn, markdownStructuredContent as Gt, codeModeRunInputSchema as H, ListRootsResultSchema as Hn, loadCapletFilesFromMap as Ht, nativeCapletPromptGuidance as I, InitializedNotificationSchema as In, VAULT_MAX_VALUE_BYTES as It, diagnoseCodeModeTypeScript as J, SetLevelRequestSchema as Jn, runOAuthFlow as Jt, CodeModeSessionManager as K, ReadResourceRequestSchema as Kn, refreshOAuthTokenBundle as Kt, nativeCapletToolDescription as L, JSONRPCMessageSchema as Ln, validateVaultKeyName as Lt, controlUrlForBase as M, EmptyResultSchema as Mn, vaultBootstrapResolver as Mt, isLoopbackHost as N, ErrorCode as Nn, vaultResolverForAuthDir as Nt, resolveCapletsRemote as O, CreateMessageResultWithToolsSchema as On, loadGlobalConfig as Ot, parseServerBaseUrl as P, GetPromptRequestSchema as Pn, vaultStoreForAuthDir as Pt, CodeModeLogStore as Q, isJSONRPCErrorResponse as Qn, isTokenBundleExpired as Qt, nativeCapletToolName as R, LATEST_PROTOCOL_VERSION as Rn, decryptVaultValue as Rt, buildProjectSyncManifest as S, mergeCapabilities as Sn, handleServerTool as St, hostedCloudWorkspaceFromRemoteUrl as T, CallToolResultSchema as Tn, GoogleDiscoveryManager as Tt, codeModeRunParamsSchema as U, ListToolsRequestSchema as Un, hasRenderableStructuredContent as Ut, nativeCodeModeToolName as V, ListResourcesRequestSchema as Vn, validateCapletFile as Vt, emptyCodeModeRunMeta as W, LoggingLevelSchema as Wn, markdownCallToolResultContent as Wt, listCodeModeCallableCaplets as X, assertCompleteRequestResourceTemplate as Xn, startOAuthFlow as Xt, createCodeModeCapletsApi as Y, assertCompleteRequestPrompt as Yn, startGenericOAuthFlow as Yt, CodeModeJournalStore as Z, isInitializeRequest as Zn, deleteTokenBundle as Zt, attachErrorResponse as _, serializeMessage as _n, rotateTelemetryIdentity as _t, CloudAuthStore as a, defaultCacheBaseDir as an, isSchemaOptional as ar, version as at, invokeAttachExport$1 as b, AjvJsonSchemaValidator as bn, findProjectRoot as bt, redactedCloudAuthStatus as c, defaultStateBaseDir as cn, objectFromShape as cr, buildProductTelemetryEvent as ct, projectBindingError as d, defaultUpdateCheckStateDir as dn, maybePrintTelemetryNotice as dt, DEFAULT_AUTH_DIR as en, isJSONRPCResultResponse as er, codeModeDeclarationHash as et, projectBindingRecovery as f, resolveCapletsRoot as fn, resolveTelemetryState as ft, CAPLETS_ATTACH_SESSION_HEADER as g, ReadBuffer as gn, readTelemetryNotice as gt, createSdkRemoteCapletsClient as h, resolveProjectConfigPath as hn, readTelemetryIdentity as ht, createRemoteProfileStore as i, DEFAULT_UPDATE_CHECK_STATE_DIR as in, getSchemaDescription as ir, CapletsEngine as it, appendBasePath as j, ElicitResultSchema as jn, parseConfig as jt, resolveHostedCloudRemote as k, CreateTaskResultSchema as kn, loadLocalOverlayConfigWithSources as kt, PROJECT_BINDING_ERROR_CODES as l, defaultTelemetryStateDir as ln, safeParse as lr, buildReliabilityTelemetryEvent as lt, RemoteNativeCapletsService as m, resolveProjectCapletsRoot as mn, readTelemetryDeliveryHealth as mt, resolveRemoteSelection as n, DEFAULT_OBSERVED_OUTPUT_SHAPE_CACHE_DIR as nn, getObjectShape as nr, generateCodeModeRunToolDescription as nt, cloudAuthPath as o, defaultConfigBaseDir as on, isZ4Schema as or, createTelemetryDispatcher as ot, CloudAuthClient as p, resolveConfigPath as pn, deleteTelemetryIdentity as pt, QuickJsCodeModeSandbox as q, SUPPORTED_PROTOCOL_VERSIONS as qn, runGenericOAuthFlow as qt, cloudCredentialsFromRemoteProfile as r, DEFAULT_UPDATE_CHECK_CACHE_DIR as rn, getParseErrorMessage as rr, minifyCodeModeDeclarationText as rt, migrateCredentials as s, defaultConfigPath as sn, normalizeObjectSchema as sr, TelemetryDebugSink as st, createNativeCapletsService as t, DEFAULT_COMPLETION_CACHE_DIR as tn, getLiteralValue as tr, generateCodeModeDeclarations as tt, ProjectBindingError as u, defaultUpdateCheckCacheDir as un, safeParseAsync as ur, durationBucket as ut, buildAttachProjection as v, assertClientRequestTaskCapability as vn, resolveExposure as vt, resolveNativeCapletsServiceOptions as w, CallToolRequestSchema as wn, capabilityDescription as wt, invokeNativeAttachExport as x, Protocol as xn, fingerprintProjectRoot as xt, buildNativeAttachProjection as y, assertToolsCallTaskCapability as yn, decodeDirectResourceUri as yt, nativeCapletsSystemGuidance as z, ListPromptsRequestSchema as zn, encryptVaultValue as zt };
@@ -0,0 +1,5 @@
1
+ export declare const DISABLE_UPDATE_CHECK_ENV = "CAPLETS_DISABLE_UPDATE_CHECK";
2
+ export declare const UPDATE_NOTICE_STDERR_ENV = "CAPLETS_UPDATE_NOTICE_STDERR";
3
+ export type UpdateCheckEnv = Record<string, string | undefined> | NodeJS.ProcessEnv;
4
+ export declare function isUpdateCheckDisabled(env?: UpdateCheckEnv): boolean;
5
+ export declare function isUpdateNoticeStderrOptIn(env?: UpdateCheckEnv): boolean;
@@ -0,0 +1,14 @@
1
+ import { type UpdateCheckEnv } from "./control";
2
+ export type UpdateNoticeEligibility = {
3
+ eligible: true;
4
+ command: string;
5
+ } | {
6
+ eligible: false;
7
+ reason: string;
8
+ };
9
+ export type UpdateNoticeEligibilityInput = {
10
+ args: string[];
11
+ env?: UpdateCheckEnv | undefined;
12
+ stderrIsTTY?: boolean | undefined;
13
+ };
14
+ export declare function classifyUpdateNoticeEligibility(input: UpdateNoticeEligibilityInput): UpdateNoticeEligibility;
@@ -0,0 +1,8 @@
1
+ export { isUpdateCheckDisabled, isUpdateNoticeStderrOptIn } from "./control";
2
+ export { classifyUpdateNoticeEligibility } from "./eligibility";
3
+ export { maybePrintUpdateNotice } from "./notice";
4
+ export { fetchPublicCapletsMetadata } from "./registry";
5
+ export { refreshUpdateMetadata } from "./refresh";
6
+ export { UPDATE_CHECK_ACCEPT_HEADER, UPDATE_CHECK_CACHE_TTL_MS, UPDATE_CHECK_FETCH_TIMEOUT_MS, UPDATE_CHECK_LOCK_TTL_MS, UPDATE_CHECK_MAX_RESPONSE_BYTES, UPDATE_CHECK_MAX_STALE_MS, UPDATE_CHECK_NEGATIVE_TTL_MS, UPDATE_CHECK_NOTICE_REPEAT_MS, UPDATE_CHECK_PACKAGE_NAME, UPDATE_CHECK_REGISTRY_URL, acquireUpdateRefreshLock, readUpdateMetadataCache, readUpdateNoticeState, recordUpdateNoticeShown, releaseUpdateRefreshLock, shouldShowUpdateNotice, updateCheckCacheDir, updateCheckStateDir, updateMetadataCachePath, updateNoticeStatePath, updateRefreshLockPath, writePrivateJson, writeUpdateMetadataCache, } from "./state";
7
+ export { findAvailableUpdate } from "./version";
8
+ export type { PackageVersionMetadata } from "./version";
@@ -0,0 +1,13 @@
1
+ import { type UpdateCheckPathsOptions } from "./state";
2
+ export type MaybePrintUpdateNoticeOptions = UpdateCheckPathsOptions & {
3
+ args: string[];
4
+ env?: Record<string, string | undefined> | NodeJS.ProcessEnv | undefined;
5
+ version?: string | undefined;
6
+ fetcher?: typeof fetch | undefined;
7
+ signal?: AbortSignal | undefined;
8
+ stderrIsTTY?: boolean | undefined;
9
+ writeErr?: ((value: string) => void) | undefined;
10
+ now?: number | undefined;
11
+ refreshForLater?: boolean | undefined;
12
+ };
13
+ export declare function maybePrintUpdateNotice(options: MaybePrintUpdateNoticeOptions): Promise<void>;
@@ -0,0 +1,9 @@
1
+ import { type UpdateCheckPathsOptions } from "./state";
2
+ export type RefreshUpdateMetadataOptions = UpdateCheckPathsOptions & {
3
+ fetcher?: typeof fetch | undefined;
4
+ signal?: AbortSignal | undefined;
5
+ now?: number | undefined;
6
+ timeoutMs?: number | undefined;
7
+ maxResponseBytes?: number | undefined;
8
+ };
9
+ export declare function refreshUpdateMetadata(options?: RefreshUpdateMetadataOptions): Promise<"refreshed" | "skipped" | "failed">;
@@ -0,0 +1,12 @@
1
+ import type { PackageVersionMetadata } from "./version";
2
+ export declare class UpdateRegistryError extends Error {
3
+ readonly reason: "http" | "timeout" | "invalid" | "network" | "too_large" | "error";
4
+ constructor(message: string, reason: "http" | "timeout" | "invalid" | "network" | "too_large" | "error");
5
+ }
6
+ export type FetchUpdateMetadataOptions = {
7
+ fetcher?: typeof fetch | undefined;
8
+ signal?: AbortSignal | undefined;
9
+ timeoutMs: number;
10
+ maxResponseBytes?: number | undefined;
11
+ };
12
+ export declare function fetchPublicCapletsMetadata(options: FetchUpdateMetadataOptions): Promise<PackageVersionMetadata>;
@@ -0,0 +1,58 @@
1
+ import type { PackageVersionMetadata } from "./version";
2
+ export declare const UPDATE_CHECK_PACKAGE_NAME = "caplets";
3
+ export declare const UPDATE_CHECK_REGISTRY_URL = "https://registry.npmjs.org/caplets";
4
+ export declare const UPDATE_CHECK_ACCEPT_HEADER = "application/vnd.npm.install-v1+json";
5
+ export declare const UPDATE_CHECK_CACHE_TTL_MS: number;
6
+ export declare const UPDATE_CHECK_MAX_STALE_MS: number;
7
+ export declare const UPDATE_CHECK_NEGATIVE_TTL_MS: number;
8
+ export declare const UPDATE_CHECK_LOCK_TTL_MS: number;
9
+ export declare const UPDATE_CHECK_FETCH_TIMEOUT_MS = 250;
10
+ export declare const UPDATE_CHECK_MAX_RESPONSE_BYTES: number;
11
+ export declare const UPDATE_CHECK_NOTICE_REPEAT_MS: number;
12
+ export type UpdateCheckPathsOptions = {
13
+ cacheDir?: string | undefined;
14
+ stateDir?: string | undefined;
15
+ };
16
+ export type UpdateMetadataCacheEntry = {
17
+ status: "positive";
18
+ fetchedAt: number;
19
+ expiresAt: number;
20
+ staleUntil: number;
21
+ source: typeof UPDATE_CHECK_REGISTRY_URL;
22
+ metadata: PackageVersionMetadata;
23
+ } | {
24
+ status: "negative";
25
+ fetchedAt: number;
26
+ expiresAt: number;
27
+ reason: "http" | "timeout" | "invalid" | "network" | "too_large" | "error";
28
+ };
29
+ export type ReadUpdateMetadataCacheEntry = UpdateMetadataCacheEntry & {
30
+ fresh: boolean;
31
+ usable: boolean;
32
+ };
33
+ export type UpdateNoticeState = {
34
+ shown: Record<string, {
35
+ shownAt: number;
36
+ }>;
37
+ };
38
+ export declare function updateCheckCacheDir(options?: UpdateCheckPathsOptions): string;
39
+ export declare function updateCheckStateDir(options?: UpdateCheckPathsOptions): string;
40
+ export declare function updateMetadataCachePath(options?: UpdateCheckPathsOptions): string;
41
+ export declare function updateRefreshLockPath(options?: UpdateCheckPathsOptions): string;
42
+ export declare function updateNoticeStatePath(options?: UpdateCheckPathsOptions): string;
43
+ export declare function readUpdateMetadataCache(options?: UpdateCheckPathsOptions & {
44
+ now?: number | undefined;
45
+ }): ReadUpdateMetadataCacheEntry | undefined;
46
+ export declare function writeUpdateMetadataCache(entry: UpdateMetadataCacheEntry, options?: UpdateCheckPathsOptions): boolean;
47
+ export declare function readUpdateNoticeState(options?: UpdateCheckPathsOptions): UpdateNoticeState;
48
+ export declare function shouldShowUpdateNotice(version: string, options?: UpdateCheckPathsOptions & {
49
+ now?: number | undefined;
50
+ }): boolean;
51
+ export declare function recordUpdateNoticeShown(version: string, options?: UpdateCheckPathsOptions & {
52
+ now?: number | undefined;
53
+ }): boolean;
54
+ export declare function acquireUpdateRefreshLock(options?: UpdateCheckPathsOptions & {
55
+ now?: number | undefined;
56
+ }): boolean;
57
+ export declare function releaseUpdateRefreshLock(options?: UpdateCheckPathsOptions): void;
58
+ export declare function writePrivateJson(path: string, value: unknown): boolean;
@@ -0,0 +1,14 @@
1
+ export type PackageVersionMetadata = {
2
+ packageName: string;
3
+ distTags: Record<string, string>;
4
+ versions: string[];
5
+ };
6
+ export type AvailableUpdate = {
7
+ available: true;
8
+ runningVersion: string;
9
+ latestVersion: string;
10
+ } | {
11
+ available: false;
12
+ reason: "invalid-running-version" | "no-eligible-version";
13
+ };
14
+ export declare function findAvailableUpdate(runningVersion: string | undefined, metadata: PackageVersionMetadata): AvailableUpdate;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@caplets/core",
3
- "version": "0.28.1",
3
+ "version": "0.29.1",
4
4
  "description": "Core runtime library for Caplets Code Mode and progressive disclosure gateways.",
5
5
  "keywords": [
6
6
  "caplets",
@@ -100,6 +100,7 @@
100
100
  "hono": "^4.12.25",
101
101
  "posthog-node": "^4.18.0",
102
102
  "quickjs-emscripten": "^0.32.0",
103
+ "semver": "^7.8.5",
103
104
  "typescript": "^6.0.3",
104
105
  "vfile": "^6.0.3",
105
106
  "vfile-matter": "^5.0.1",
@@ -110,6 +111,7 @@
110
111
  },
111
112
  "devDependencies": {
112
113
  "@types/node": "^25.9.3",
114
+ "@types/semver": "^7.7.1",
113
115
  "@typescript/native-preview": "7.0.0-dev.20260613.1",
114
116
  "rolldown": "^1.1.1",
115
117
  "vitest": "^4.1.8"