
Research
Shai-Hulud Descends to Hades: Miasma Worm Campaign Spreads with New PyPI Wave
Socket found 37 malicious PyPI wheels that abuse Python startup hooks to launch a Bun-powered credential stealer tied to Mini Shai-Hulud/Miasma.
@yriveiro/opencode-cache-core
Advanced tools
Git-first cache runtime and search utilities for OpenCode plugins
Git-first cache runtime and search utilities for OpenCode plugins.
@yriveiro/opencode-cache-core is for plugins that keep a local cache of external projects in Git checkouts, build optional derived artifacts from those checkouts, and search that cache locally.
import { createGitCachePlugin, defineGitCacheSpec } from "@yriveiro/opencode-cache-core";
const SPEC = defineGitCacheSpec({
schemaVersion: 1,
title: "Example Cache",
service: "example-cache",
envVar: "OPENCODE_EXAMPLE_CACHE_DIR",
defaultCacheSubdir: "example",
initMessage: "example cache plugin initialized",
updateTool: {
name: "example-cache-update",
description: "Clone or refresh the local example cache.",
failureLabel: "Failed to update example cache",
successLogMessage: "example cache update completed",
},
statusTool: {
name: "example-cache-status",
description: "Report cache freshness and search corpus status.",
},
searchTool: {
name: "example-cache-search",
description: "Search cached example content locally.",
missingMessage: "Example cache is not initialized. Run example-cache-update first.",
failureLabel: "Failed to search example cache",
},
sources: [
{
id: "repo",
url: "https://github.com/example/project.git",
branch: "main",
ready: true,
},
],
artifacts: [
{
id: "site",
source: "repo",
path: "dist/docs",
readiness: "index.html",
},
],
sections: {
docs: {
label: "Docs",
root: { kind: "source", id: "repo" },
patterns: ["docs/**/*.md", "docs/**/*.mdx"],
},
built: {
label: "Built docs",
root: { kind: "artifact", id: "site" },
patterns: ["**/*.html"],
},
},
});
export default createGitCachePlugin({
spec: SPEC,
});
cache-state.jsonsearch-index.jsontitle: title used in notificationsservice: service name used for host loggingenvVar: environment variable that overrides the cache directorydefaultCacheSubdir: default subdirectory under ~/.cache/opencode/plugins/cache-coreinitMessage: initialization log messageupdateTool: name, description, failure label, and success log messagestatusTool: name and descriptionsearchTool: name, description, missing message, failure label, and optional scope descriptionreadySource: optional source ID used to decide whether the cache is initializedEach entry in sources describes one repository checkout.
id: stable identifier used by artifacts and sectionsurl: Git repository URLbranch: branch to clone and refreshdirectory: optional directory name under the cache root; defaults to idsparse: optional sparse-checkout pathsready: optional marker used when selecting the source that gates initializationlabel: optional display name in status outputEach entry in artifacts describes a build output rooted in a source checkout.
id: stable identifier used by sectionssource: source ID that owns the artifactpath: path relative to the source directoryreadiness: optional file or directory checked by runtime.isArtifactReady()label: optional display name in status outputEach entry in sections becomes a search scope.
label: display label used in status outputroot: either { kind: "source", id: "..." } or { kind: "artifact", id: "..." }patterns: file globs included in the search index for that scopeThe cache directory resolves as:
process.env[spec.envVar], when set~/.cache/opencode/plugins/cache-core/<spec.defaultCacheSubdir>Inside that directory, the runtime writes:
<cacheDir>/
<source.directory ?? source.id>/
<source.directory ?? source.id>/<artifact.path>/
cache-state.json
search-index.json
cache-state.json contains:
updatedAt and indexedAtsearch-index.json contains:
The update tool:
cache-state.jsonsearch-index.jsonIf the ready source is already present and the cache is still fresh, the tool returns the current cache summary unless force is set.
The status tool reports:
extendStatus(runtime) can append package-specific lines.
The generated search tool supports:
queryscoperegexcase_sensitivelimitIt loads the persisted index on demand, runs a scoped search, formats hits as text, and sends the same result back to the session as a notification.
The lower-level searchGitCacheIndex() helper returns structured search results when a plugin needs the raw data instead of the formatted tool output.
The generated plugin also registers permission.ask for the resolved cache directory. It only allows external_directory requests whose title or patterns include that cache path.
extraTools(runtime) and extendStatus(runtime) receive a GitCachePluginContext.
Useful properties and methods:
cacheDirstateFileindexFilereadState()writeState()updateState()loadIndex()refreshIndex()formatIndexCounts()getSourceDir()getArtifactDir()getArtifactReadinessPath()isSourceReady()isArtifactReady()getSourceRevision()syncSources()notify()log()runCommand()formatCommandFailure()Typical downstream uses:
Public root exports:
defineGitCacheSpeccreateGitCachePluginbuildGitCacheSearchIndexsearchGitCacheIndexThe package keeps lower-level helpers internal. Package tests import implementation files directly, but downstream packages should use the root plugin API only.
Run the core checks with Bun:
bun run typecheck
bun test
bun run build
README.md: package guidedocs/index.html: browsable docs page using the same content modeltests/git-cache-core.test.ts: focused tests for spec validation, paths, freshness, search, and permission handlingFAQs
Git-first cache runtime and search utilities for OpenCode plugins
We found that @yriveiro/opencode-cache-core demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Research
Socket found 37 malicious PyPI wheels that abuse Python startup hooks to launch a Bun-powered credential stealer tied to Mini Shai-Hulud/Miasma.

Security News
RubyGems and Bundler 4.0.13 introduced an opt-in cooldown feature that delays newly published gems during dependency resolution.

Security News
pnpm 11.5 now recognizes npm staged publish approvals in release metadata, preventing those releases from being mistaken for lower-trust package publishes.