Skip to content

ExtensionContext

PropertyTypeDescription
cache?ExtensionCacheA best-effort key/value cache that outlives a single run. Optional, and absent is normal — a host may provide no cache at all, so read it as ctx.cache?.get(...) and treat a miss and an absent cache the same way. Never the source of truth: anything here must be re-derivable from the upstream, because it can vanish between runs.
fetchFetchLikeBehaves like the standard fetch, and is the ONLY way out. In Trove’s cloud every request is routed through an egress worker that permits https alone, matches the manifest’s declared hosts exactly, and refuses private and link-local addresses even when allowlisted. On the Mac it adds per-source timeouts, retry and rate-limit handling. Prefer it over global fetch everywhere: the global one is unguarded where it exists at all, and absent where it does not.
logLogChannelWhere an extension says what it is doing. Surfaced in the run transcript.
now(): Date;

The current wall-clock time.

Injected rather than read from a global so a run is deterministic under test, and so a replayed fixture means the same thing tomorrow.

Date


requireSecret(name: string): Promise<string>;

secret, for a credential the extension genuinely cannot proceed without: rejects, naming the credential, rather than resolving undefined.

Prefer it to if (!(await ctx.secret(n))) throw — the failure message is the useful half, and the host writes a better one than each extension will.

ParameterType
namestring

Promise<string>


secret(name: string): Promise<string | undefined>;

A credential the manifest declared, by name — undefined when it is not set.

Resolves whether the value was pasted by the user or is a token Trove refreshed a moment ago — the extension cannot tell, and must not need to. That is what keeps delegated authorization out of every author’s code. Async for the same reason: resolving may be a vault read or a refresh.

This is the reader for a credential the extension can work without — an optional API key that raises a rate limit, an OAuth client secret a public client does not have. When the extension cannot proceed without the value, use requireSecret and let it raise.

Until 3.3.0 this rejected, and requireSecret was documented as behaving “identically; the name is the documentation” — so there were two names for one behaviour and no way at all to read an optional credential. The two sources that had one reached around the whole mechanism into the legacy ctx.credentials bag instead.

ParameterType
namestring

Promise<string | undefined>