Perform code optimization and document cleanup (#1)
## Summary - add repository-wide quality tooling and verification scaffolding, including CI workflows, pnpm workspace setup, ESLint/Prettier/markdown checks, and generated-output verification helpers - reorganize skill sources and generation flow by introducing canonical `_source` variants, generator/manifests, reusable helper abstractions, and shared web-automation/browser utilities - clean up and expand documentation so the root README flows into docs and skill docs, with clearer development, reviewer, installer, and workflow guidance ## Notable changes - docs flow and consistency cleanup across `README.md`, `docs/README.md`, and related docs - new scripts for `check`, docs verification, generated-file verification, shell portability, and safe directory replacement - refactors in Atlassian and web-automation skill runtimes to reduce duplication and centralize reusable code - changelog, development documentation, and CI surface updates ## Test Plan - [ ] `pnpm run check` - [ ] review generated/manifests and skill sync outputs - [ ] smoke-check docs flow from `README.md` to `docs/README.md` to skill docs ## Notes - this branch currently includes tracked `skills/web-automation/shared/node_modules` content that should be reviewed carefully as potentially noisy/accidental committed artifacts Co-authored-by: Stefano Fiorini <stefano.fiorini@firsthorizon.com> Reviewed-on: #1
This commit was merged in pull request #1.
This commit is contained in:
@@ -279,7 +279,7 @@ async function findClaudeCodeSuperpowersPluginRoots(homeDir) {
|
||||
|
||||
async function findCursorSuperpowersPluginRoots(homeDir) {
|
||||
const pluginRoot = path.join(homeDir, ".cursor", "plugins", "cache", "cursor-public", "superpowers");
|
||||
let entries = [];
|
||||
let entries;
|
||||
try {
|
||||
entries = await readdir(pluginRoot, { withFileTypes: true });
|
||||
} catch (error) {
|
||||
@@ -532,6 +532,24 @@ export async function buildOperationPlan({ selections, repoRoot = process.cwd(),
|
||||
return { operations, prompts, reportRows, assumeYes };
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove the target of an operation (skill, helper, or superpowers).
|
||||
*
|
||||
* Validates that the target is within the skills root before removing.
|
||||
* Handles both regular directories and symbolic links.
|
||||
* Idempotent: succeeds even when the target does not exist.
|
||||
*
|
||||
* @param {object} op - Operation object with at least `target` and `skillsRoot`.
|
||||
* @returns {Promise<object>} Operation with `status: "ok"`.
|
||||
*/
|
||||
export async function removeTarget(op) {
|
||||
await validateRemoveTarget(op.target, op.skillsRoot, { repoRoot: REPO_ROOT });
|
||||
const info = existsSync(op.target) ? await lstat(op.target) : null;
|
||||
if (info?.isSymbolicLink()) await unlink(op.target);
|
||||
else await rm(op.target, { recursive: true, force: true });
|
||||
return { ...op, status: "ok" };
|
||||
}
|
||||
|
||||
export async function validateRemoveTarget(target, skillsRoot, { repoRoot = process.cwd() } = {}) {
|
||||
const resolvedRoot = path.resolve(skillsRoot);
|
||||
const resolvedTarget = path.resolve(target);
|
||||
@@ -598,7 +616,8 @@ export async function executeOperation(op) {
|
||||
if (op.action === "unsupported" || op.status === "skipped") return { ...op, status: "skipped" };
|
||||
if (op.kind === "package-skill") return { ...op, status: "included" };
|
||||
if (op.kind === "sync-pi-package") {
|
||||
runCommand(path.join(op.repoRoot, "scripts", "sync-pi-package-skills.sh"), [], { cwd: op.repoRoot });
|
||||
// Use the canonical generator (pnpm run sync:pi / node scripts/generate-skills.mjs).
|
||||
runCommand(process.execPath, [path.join(op.repoRoot, "scripts", "generate-skills.mjs")], { cwd: op.repoRoot });
|
||||
return { ...op, status: "ok" };
|
||||
}
|
||||
if (op.kind === "pi-package") {
|
||||
@@ -607,33 +626,19 @@ export async function executeOperation(op) {
|
||||
return { ...op, status: "ok" };
|
||||
}
|
||||
if (op.kind === "skill") {
|
||||
if (op.action === "remove") {
|
||||
await validateRemoveTarget(op.target, op.skillsRoot, { repoRoot: REPO_ROOT });
|
||||
const info = existsSync(op.target) ? await lstat(op.target) : null;
|
||||
if (info?.isSymbolicLink()) await unlink(op.target);
|
||||
else await rm(op.target, { recursive: true, force: true });
|
||||
return { ...op, status: "ok" };
|
||||
}
|
||||
if (op.action === "remove") return removeTarget(op);
|
||||
await copyDirectoryReplacing(op.source, op.target);
|
||||
return { ...op, status: "ok" };
|
||||
}
|
||||
if (op.kind === "helper") {
|
||||
if (op.action === "remove") {
|
||||
await validateRemoveTarget(op.target, op.skillsRoot, { repoRoot: REPO_ROOT });
|
||||
const info = existsSync(op.target) ? await lstat(op.target) : null;
|
||||
if (info?.isSymbolicLink()) await unlink(op.target);
|
||||
else await rm(op.target, { recursive: true, force: true });
|
||||
return { ...op, status: "ok" };
|
||||
}
|
||||
if (op.action === "remove") return removeTarget(op);
|
||||
await installHelperAllowlist(op);
|
||||
return { ...op, status: "ok" };
|
||||
}
|
||||
if (op.kind === "superpowers") {
|
||||
if (op.action === "remove") return removeTarget(op);
|
||||
await mkdir(path.dirname(op.target), { recursive: true });
|
||||
if (op.action === "remove") {
|
||||
await validateRemoveTarget(op.target, op.skillsRoot, { repoRoot: REPO_ROOT });
|
||||
await rm(op.target, { recursive: true, force: true });
|
||||
} else if (op.mode === "copy") {
|
||||
if (op.mode === "copy") {
|
||||
await copyDirectoryReplacing(op.source, op.target);
|
||||
} else {
|
||||
await rm(op.target, { recursive: true, force: true });
|
||||
|
||||
Reference in New Issue
Block a user