Chapter 6: Update, Remove, and Clean Lifecycle
April 13, 2026 · View on GitHub
Welcome to Chapter 6: Update, Remove, and Clean Lifecycle. In this part of OpenSrc Tutorial: Deep Source Context for Coding Agents, you will build an intuitive mental model first, then move into concrete implementation details and practical production tradeoffs.
OpenSrc includes commands for incremental refresh and cleanup of source caches.
Lifecycle Commands
opensrc zod # refresh source for package
opensrc remove zod # remove package source
opensrc remove owner/repo # remove repository source
opensrc clean # remove all tracked sources
opensrc clean --npm # remove only npm package sources
Maintenance Strategy
- re-run fetch for packages tied to updated lockfiles
- remove stale imports to reduce local noise
- use targeted clean modes per ecosystem when needed
Source References
Summary
You now have operational control over source import lifecycle and cache hygiene.
Next: Chapter 7: Reliability, Rate Limits, and Version Fallbacks
Source Code Walkthrough
src/commands/list.ts
The listCommand function in src/commands/list.ts handles a key part of this chapter's functionality:
* List all fetched package sources
*/
export async function listCommand(options: ListOptions = {}): Promise<void> {
const cwd = options.cwd || process.cwd();
const sources = await listSources(cwd);
const totalCount = sources.packages.length + sources.repos.length;
if (totalCount === 0) {
console.log("No sources fetched yet.");
console.log(
"\nUse `opensrc <package>` to fetch source code for a package.",
);
console.log("Use `opensrc <owner>/<repo>` to fetch a GitHub repository.");
console.log("\nSupported registries:");
console.log(" • npm: opensrc zod, opensrc npm:react");
console.log(" • PyPI: opensrc pypi:requests");
console.log(" • crates: opensrc crates:serde");
return;
}
if (options.json) {
console.log(JSON.stringify(sources, null, 2));
return;
}
// Group packages by registry for display
const packagesByRegistry: Record<Registry, typeof sources.packages> = {
npm: [],
pypi: [],
crates: [],
};
This function is important because it defines how OpenSrc Tutorial: Deep Source Context for Coding Agents implements the patterns covered in this chapter.
src/commands/list.ts
The ListOptions interface in src/commands/list.ts handles a key part of this chapter's functionality:
import type { Registry } from "../types.js";
export interface ListOptions {
cwd?: string;
json?: boolean;
}
const REGISTRY_LABELS: Record<Registry, string> = {
npm: "npm",
pypi: "PyPI",
crates: "crates.io",
};
/**
* List all fetched package sources
*/
export async function listCommand(options: ListOptions = {}): Promise<void> {
const cwd = options.cwd || process.cwd();
const sources = await listSources(cwd);
const totalCount = sources.packages.length + sources.repos.length;
if (totalCount === 0) {
console.log("No sources fetched yet.");
console.log(
"\nUse `opensrc <package>` to fetch source code for a package.",
);
console.log("Use `opensrc <owner>/<repo>` to fetch a GitHub repository.");
console.log("\nSupported registries:");
console.log(" • npm: opensrc zod, opensrc npm:react");
console.log(" • PyPI: opensrc pypi:requests");
console.log(" • crates: opensrc crates:serde");
This interface is important because it defines how OpenSrc Tutorial: Deep Source Context for Coding Agents implements the patterns covered in this chapter.
src/lib/agents.ts
The getSectionContent function in src/lib/agents.ts handles a key part of this chapter's functionality:
* Get the section content (without leading newline for comparison)
*/
function getSectionContent(): string {
return `${SECTION_MARKER}
${SECTION_START}
Source code for dependencies is available in \`opensrc/\` for deeper understanding of implementation details.
See \`opensrc/sources.json\` for the list of available packages and their versions.
Use this source code when you need to understand how a package works internally, not just its types/interface.
### Fetching Additional Source Code
To fetch source code for a package or repository you need to understand, run:
\`\`\`bash
npx opensrc <package> # npm package (e.g., npx opensrc zod)
npx opensrc pypi:<package> # Python package (e.g., npx opensrc pypi:requests)
npx opensrc crates:<package> # Rust crate (e.g., npx opensrc crates:serde)
npx opensrc <owner>/<repo> # GitHub repo (e.g., npx opensrc vercel/ai)
\`\`\`
${SECTION_END_MARKER}`;
}
export interface PackageEntry {
name: string;
version: string;
registry: Registry;
path: string;
This function is important because it defines how OpenSrc Tutorial: Deep Source Context for Coding Agents implements the patterns covered in this chapter.
src/lib/agents.ts
The updatePackageIndex function in src/lib/agents.ts handles a key part of this chapter's functionality:
* Update the sources.json file in opensrc/
*/
export async function updatePackageIndex(
sources: {
packages: PackageEntry[];
repos: RepoEntry[];
},
cwd: string = process.cwd(),
): Promise<void> {
const opensrcDir = join(cwd, OPENSRC_DIR);
const sourcesPath = join(opensrcDir, SOURCES_FILE);
if (sources.packages.length === 0 && sources.repos.length === 0) {
// Remove index file if no sources
if (existsSync(sourcesPath)) {
const { rm } = await import("fs/promises");
await rm(sourcesPath, { force: true });
}
return;
}
const index: SourcesIndex = {
updatedAt: new Date().toISOString(),
};
if (sources.packages.length > 0) {
index.packages = sources.packages.map((p) => ({
name: p.name,
version: p.version,
registry: p.registry,
path: p.path,
fetchedAt: p.fetchedAt,
This function is important because it defines how OpenSrc Tutorial: Deep Source Context for Coding Agents implements the patterns covered in this chapter.
How These Components Connect
flowchart TD
A[listCommand]
B[ListOptions]
C[getSectionContent]
D[updatePackageIndex]
E[hasOpensrcSection]
A --> B
B --> C
C --> D
D --> E