
Refresh Agent Context
- 4 installs
- 491 repo stars
- Updated August 4, 2026
- solana-foundation/solana-com
Helps with ai & agent building tasks during AI-assisted development.
About
refresh-agent-context is a Claude Code skill for ai & agent building. It helps solo builders move faster with AI-assisted coding.
- refresh-agent-context
- AI & Agent Building
- AI-coding skill
Refresh Agent Context by the numbers
- 4 all-time installs (skills.sh)
- Ranked #13,348 of 16,546 AI & Agent Building skills by installs in the Skillselion catalog
- Data as of Aug 5, 2026 (Skillselion catalog sync)
npx skills add https://github.com/solana-foundation/solana-com --skill refresh-agent-contextAdd your badge
Show developers this skill is listed on Skillselion. Paste this into your README.
| Installs | 4 |
|---|---|
| repo stars | ★ 491 |
| Last updated | August 4, 2026 |
| Repository | solana-foundation/solana-com ↗ |
What it does
Helps with ai & agent building tasks during AI-assisted development.
Files
Refresh Agent Context
Use this skill to keep the repo understandable for coding agents as the Turborepo evolves.
Goal
Detect drift between the actual workspace structure and the agent-facing docs, then update the smallest set of docs that restore a fast path into the correct app or package.
Prefer updating these files, in this order:
1. root AGENTS.md 2. root README.md 3. app-level apps/*/AGENTS.md 4. package docs only when they materially help route ownership or shared-code discovery
Quick Start
From the repo root, run:
node skills/refresh-agent-context/scripts/workspace_inventory.mjsThis prints a current inventory of:
- app and package workspaces
- package names
- dev ports inferred from
package.json - asset prefixes and
NEXT_PUBLIC_APP_NAMEinferred fromnext.config.ts - whether
AGENTS.md,README.md, andCLAUDE.mdexist per app
Workflow
1. Build the current repo inventory
Run the inventory script first. Treat its output as the baseline snapshot of the current monorepo shape.
2. Audit doc coverage
Check for:
- missing root
AGENTS.md - apps missing
AGENTS.md - empty or stub-only
AGENTS.md - stale README entries for app names, ports, package names, or CMS/framework
ownership
- missing references to important shared packages such as
packages/i18n,
packages/ui-chrome, or packages/ecosystem-data
- route ownership that is not obvious from the current docs
3. Patch the minimal doc set
Prefer concise guides that answer these questions quickly:
- which workspace owns the requested feature
- which commands validate only that workspace
- which config files define routing, asset prefixes, or cross-app navigation
- which shared packages are likely involved
Do not turn the docs into a full architecture book. Keep them as jump-start guides.
4. Verify against source files
Before finalizing:
- verify package names from
package.json - verify ports from workspace scripts
- verify asset prefixes, rewrites, and
NEXT_PUBLIC_APP_NAMEfrom
next.config.ts
- verify content ownership from the actual
content/,src/, or package layout
5. Report the audit
Summarize:
- what was stale or missing
- what docs were updated
- what could not be verified automatically
Output Standards
- keep docs short and operational
- prefer tables for workspace maps and bullets for gotchas
- preserve existing OpenSpec-managed blocks in app
AGENTS.md - do not duplicate long app docs when a short pointer is enough
- if no changes are needed, say so and include the audit findings
Example Requests
- "Refresh the repo's agent docs after adding a new app"
- "Audit the Turborepo and update AGENTS.md files"
- "Rebuild agent context after changing ports and route ownership"
- "Run the periodic agent-reference refresh"
#!/usr/bin/env node
import fs from "node:fs";
import path from "node:path";
const rootDir = process.cwd();
function readJson(filePath) {
return JSON.parse(fs.readFileSync(filePath, "utf8"));
}
function readText(filePath) {
return fs.existsSync(filePath) ? fs.readFileSync(filePath, "utf8") : "";
}
function exists(relPath) {
return fs.existsSync(path.join(rootDir, relPath));
}
function listDirs(relPath) {
const abs = path.join(rootDir, relPath);
if (!fs.existsSync(abs)) return [];
return fs
.readdirSync(abs, { withFileTypes: true })
.filter((entry) => entry.isDirectory())
.map((entry) => entry.name)
.sort();
}
function inferDevPort(packageJson) {
const devScript = packageJson.scripts?.dev ?? "";
const match =
devScript.match(/--port\s+(\d+)/) ??
devScript.match(/-p\s+(\d+)/) ??
devScript.match(/PORT=(\d+)/);
if (match?.[1]) return match[1];
if (devScript.includes("next dev")) return "3000";
return "";
}
function resolveConstString(fileText, identifier) {
const escaped = identifier.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
const match = fileText.match(
new RegExp(`const\\s+${escaped}\\s*=\\s*["'\`](.+?)["'\`]`),
);
return match?.[1] ?? "";
}
function inferAssetPrefix(fileText) {
const direct = fileText.match(/assetPrefix:\s*["'`](.+?)["'`]/);
if (direct?.[1]) return direct[1];
const viaIdentifier = fileText.match(/assetPrefix:\s*([A-Za-z_$][\w$]*)/);
if (viaIdentifier?.[1]) {
return resolveConstString(fileText, viaIdentifier[1]);
}
if (/\bassetPrefix\b/.test(fileText)) {
const shorthand = resolveConstString(fileText, "assetPrefix");
if (shorthand) return shorthand;
}
return "";
}
function inferAppName(fileText) {
const match = fileText.match(/NEXT_PUBLIC_APP_NAME:\s*["'`](.+?)["'`]/);
return match?.[1] ?? "";
}
function summarizeWorkspace(kind, dirName) {
const relBase = `${kind}/${dirName}`;
const pkgPath = path.join(rootDir, relBase, "package.json");
if (!fs.existsSync(pkgPath)) {
return null;
}
const pkg = readJson(pkgPath);
const nextConfigText = readText(
path.join(rootDir, relBase, "next.config.ts"),
);
return {
name: dirName,
path: relBase,
packageName: pkg.name ?? "",
hasAgents: exists(`${relBase}/AGENTS.md`),
hasReadme: exists(`${relBase}/README.md`),
hasClaude: exists(`${relBase}/CLAUDE.md`),
devPort: inferDevPort(pkg),
assetPrefix: inferAssetPrefix(nextConfigText),
appNameEnv: inferAppName(nextConfigText),
};
}
function formatBool(value) {
return value ? "yes" : "no";
}
function printTable(headers, rows) {
console.log(`| ${headers.join(" | ")} |`);
console.log(`| ${headers.map(() => "---").join(" | ")} |`);
for (const row of rows) {
console.log(`| ${row.join(" | ")} |`);
}
console.log("");
}
const apps = listDirs("apps")
.map((name) => summarizeWorkspace("apps", name))
.filter(Boolean);
const packages = listDirs("packages")
.map((name) => summarizeWorkspace("packages", name))
.filter(Boolean);
console.log("# Workspace Inventory");
console.log("");
console.log(`Root AGENTS.md: ${formatBool(exists("AGENTS.md"))}`);
console.log(`Root README.md: ${formatBool(exists("README.md"))}`);
console.log(`turbo.json: ${formatBool(exists("turbo.json"))}`);
console.log("");
console.log("## Apps");
console.log("");
printTable(
[
"workspace",
"package",
"dev port",
"asset prefix",
"app env",
"AGENTS",
"README",
"CLAUDE",
],
apps.map((app) => [
`\`${app.path}\``,
`\`${app.packageName}\``,
app.devPort || "-",
app.assetPrefix || "-",
app.appNameEnv || "-",
formatBool(app.hasAgents),
formatBool(app.hasReadme),
formatBool(app.hasClaude),
]),
);
console.log("## Packages");
console.log("");
printTable(
["workspace", "package", "AGENTS", "README"],
packages.map((pkg) => [
`\`${pkg.path}\``,
`\`${pkg.packageName}\``,
formatBool(pkg.hasAgents),
formatBool(pkg.hasReadme),
]),
);