chore(catalog): remove plugins that are no longer published
Remove claude-design from the marketplace manifest and its catalog
README entry, and remove the playground-design-system entry from the
README. The catalog now lists 11 plugins.
Add scripts/check-public-links.mjs: fails when README.md or the
manifest links to an open/<name> repository missing from a tracked
PUBLIC_REPOS list. Chosen over the local retired-terms list because
that gate scans every tracked file, and historical docs plus
CONVENTIONS.md (which keep naming these repos on purpose) would hold
it red; a live visibility check could not be red before the repos
change visibility. Red on 5ba4a7a (6 hits), green after (0 of 36).
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
parent
5ba4a7a735
commit
d0bc696da3
5 changed files with 172 additions and 37 deletions
85
scripts/check-public-links.mjs
Normal file
85
scripts/check-public-links.mjs
Normal file
|
|
@ -0,0 +1,85 @@
|
|||
#!/usr/bin/env node
|
||||
// Public-link gate: fails when the catalog's public surface (README.md, the marketplace
|
||||
// manifest) links to an org repository that is not on the tracked list of public repos
|
||||
// below. A repository that is made private or removed turns every link to it into a dead
|
||||
// link — and a manifest entry into a broken install — so the catalog may only point at
|
||||
// repositories that are deliberately listed as public here.
|
||||
//
|
||||
// Usage: node scripts/check-public-links.mjs [repo-root]
|
||||
// exit 0 = checked, 0 hits · exit 1 = hit(s), or 0 links found (verified nothing)
|
||||
//
|
||||
// Adding a plugin to the catalog means adding its repository to PUBLIC_REPOS in the same
|
||||
// commit; removing one means taking it out of both.
|
||||
import { existsSync, readFileSync } from 'node:fs';
|
||||
import { dirname, join } from 'node:path';
|
||||
import { fileURLToPath } from 'node:url';
|
||||
|
||||
const HERE = dirname(fileURLToPath(import.meta.url));
|
||||
|
||||
// Org repositories the catalog may link to — the published plugins plus this catalog.
|
||||
export const PUBLIC_REPOS = [
|
||||
'ai-psychosis',
|
||||
'config-audit',
|
||||
'graceful-handoff',
|
||||
'human-friendly-style',
|
||||
'ktg-plugin-marketplace',
|
||||
'linkedin-studio',
|
||||
'llm-security',
|
||||
'ms-ai-architect',
|
||||
'okr',
|
||||
'repo-mailbox',
|
||||
'repo-standard',
|
||||
'voyage',
|
||||
];
|
||||
|
||||
// The files a reader or an installer reaches from the catalog.
|
||||
export const SURFACE_FILES = ['README.md', '.claude-plugin/marketplace.json'];
|
||||
|
||||
const LINK = /git\.fromaitochitta\.com\/open\/([A-Za-z0-9._-]+)/g;
|
||||
|
||||
// Returns one { line, repo } per org-repo link in `content`; a trailing `.git` is dropped.
|
||||
export function extractRepoLinks(content) {
|
||||
const links = [];
|
||||
content.split('\n').forEach((text, i) => {
|
||||
for (const m of text.matchAll(LINK)) links.push({ line: i + 1, repo: m[1].replace(/\.git$/, '') });
|
||||
});
|
||||
return links;
|
||||
}
|
||||
|
||||
// files: [{ path, content }]. Returns every link plus the ones not on the public list.
|
||||
export function scanFiles(files, publicRepos = PUBLIC_REPOS) {
|
||||
const links = [];
|
||||
for (const { path, content } of files) {
|
||||
for (const l of extractRepoLinks(content)) links.push({ path, ...l });
|
||||
}
|
||||
return { links, findings: links.filter((l) => !publicRepos.includes(l.repo)) };
|
||||
}
|
||||
|
||||
export function runCheck(root) {
|
||||
const files = SURFACE_FILES.filter((p) => existsSync(join(root, p))).map((path) => ({
|
||||
path,
|
||||
content: readFileSync(join(root, path), 'utf8'),
|
||||
}));
|
||||
return { files: files.length, ...scanFiles(files) };
|
||||
}
|
||||
|
||||
function main(argv) {
|
||||
const root = argv[0] ?? join(HERE, '..');
|
||||
const { files, links, findings } = runCheck(root);
|
||||
for (const f of findings) {
|
||||
console.log(`[ERROR] link to a repository not listed as public — ${f.path}:${f.line}: open/${f.repo}`);
|
||||
}
|
||||
console.log(
|
||||
`check-public-links: ${links.length} org-repo links in ${files}/${SURFACE_FILES.length} files, ` +
|
||||
`${PUBLIC_REPOS.length} public repos listed — ${findings.length} hit(s)`,
|
||||
);
|
||||
if (links.length === 0) {
|
||||
console.log('check-public-links: 0 links found — verified nothing');
|
||||
return 1;
|
||||
}
|
||||
return findings.length > 0 ? 1 : 0;
|
||||
}
|
||||
|
||||
if (process.argv[1] && fileURLToPath(import.meta.url) === process.argv[1]) {
|
||||
process.exit(main(process.argv.slice(2)));
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue