fix: add CI, GitHub API auth, and better YAML parse errors - #1
fix: add CI, GitHub API auth, and better YAML parse errors#1okokkoko4414 wants to merge 1 commit into
Conversation
- Add .github/workflows/ci.yml for typecheck + build verification - Support GITHUB_TOKEN env var in GitHub API calls to avoid rate limits - Improve parse error messages when SKILL.md frontmatter is invalid
📝 WalkthroughWalkthroughThe pull request adds GitHub Actions checks for type checking and builds. It also adds optional GitHub API authentication, detailed fetch errors, and warnings for invalid skill metadata. ChangesCI validation
GitHub sync diagnostics
Estimated code review effort: 3 (Moderate) | ~20 minutes 🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 3
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In @.github/workflows/ci.yml:
- Around line 9-11: Add a top-level permissions block before jobs in the
workflow, granting only read access to repository contents via contents: read;
leave the existing typecheck job unchanged.
- Line 13: Update both actions/checkout@v4 steps in the build and typecheck jobs
to set persist-credentials to false, ensuring neither checkout retains Git
credentials for later workflow steps.
In `@src/sync/github-sync.ts`:
- Around line 121-122: Update fetchTree() and fetchRawContent() to use a shared
bounded response-body helper that reads at most 200 bytes from res.body, cancels
the stream reader, and returns the truncated text. Replace both direct
res.text() calls in the non-2xx error paths while preserving the existing
status-specific error messages.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro Plus
Run ID: 211e47ef-ad2e-4583-86de-86c3ce357ac3
📒 Files selected for processing (2)
.github/workflows/ci.ymlsrc/sync/github-sync.ts
| jobs: | ||
| typecheck: | ||
| runs-on: ubuntu-latest |
There was a problem hiding this comment.
🔒 Security & Privacy | 🟠 Major | ⚡ Quick win
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
set -euo pipefail
echo "== workflow files =="
git ls-files .github/workflows || true
echo "== ci.yml outline =="
wc -l .github/workflows/ci.yml 2>/dev/null || true
cat -n .github/workflows/ci.yml 2>/dev/null | sed -n '1,220p'
echo "== permissions in workflows =="
rg -n '^\s*permissions:|^\s*pull_request:|uses:|run:|chmod|git (push|commit|create)' .github/workflows || true
echo "== repo default permissions references =="
rg -n 'GITHUB_TOKEN|contents:|pull_request_target|pull_request:' -S .github/workflows . 2>/dev/null | head -200 || trueRepository: leeknowsai/paperclip-plugin-superpowers
Length of output: 2117
Declare read-only GITHUB_TOKEN permissions.
Add a top-level permissions block before jobs because this workflow lacks an explicit permission grant. Without it, repository or organization defaults can grant write access, even though this workflow only needs contents read access for checkout and reviewable repository code.
Proposed fix
on:
push:
branches: [main]
pull_request:
branches: [main]
+permissions:
+ contents: read
+
jobs:🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In @.github/workflows/ci.yml around lines 9 - 11, Add a top-level permissions
block before jobs in the workflow, granting only read access to repository
contents via contents: read; leave the existing typecheck job unchanged.
Source: Linters/SAST tools
| typecheck: | ||
| runs-on: ubuntu-latest | ||
| steps: | ||
| - uses: actions/checkout@v4 |
There was a problem hiding this comment.
🔒 Security & Privacy | 🟡 Minor | ⚡ Quick win
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
set -euo pipefail
echo "== workflow files =="
git ls-files .github/workflows || true
echo
echo "== ci.yml =="
if [ -f .github/workflows/ci.yml ]; then
cat -n .github/workflows/ci.yml | sed -n '1,80p'
fi
echo
echo "== package build script =="
if [ -f package.json ]; then
node -e "const p=require('./package.json'); console.log(JSON.stringify(p.scripts, null, 2))" 2>/dev/null || cat -n package.json | sed -n '1,40p'
fi
echo
echo "== build-ui script =="
for f in scripts/build-ui.mjs scripts/build-ui.js scripts/build-ui.ts; do
if [ -f "$f" ]; then
echo "-- $f --"
cat -n "$f" | sed -n '1,220p'
fi
done
echo
echo "== checkout occurrences =="
rg -n "actions/checkout|persist-credentials|pnpm build|build-ui|GITHUB_TOKEN|process\.env\." .github package.json scripts 2>/dev/null || trueRepository: leeknowsai/paperclip-plugin-superpowers
Length of output: 2433
🌐 Web query:
actions/checkout v4 README persist-credentials default true
💡 Result:
In the actions/checkout v4 action, the persist-credentials input defaults to true [1][2]. When set to true (the default), the action configures the authentication token or SSH key into the local git configuration [1][2]. This allows your workflow scripts to run authenticated git commands, such as git push or git pull, during the job execution [1][3]. The credentials are removed automatically during the post-job cleanup process [1][3]. If you do not want these credentials to be persisted in the local git configuration, you can explicitly set persist-credentials to false [1][4].
Citations:
- 1: https://github.com/actions/checkout/blob/v4/README.md
- 2: https://github.com/actions/checkout/blob/v4/action.yml
- 3: https://spacelift.io/blog/github-actions-checkout
- 4: https://github.com/actions/checkout/?tab=readme-ov-file
🌐 Web query:
GitHub Actions GITHUB_TOKEN environment variable persist-credentials local git config
💡 Result:
In GitHub Actions, the persist-credentials input for the actions/checkout action controls whether the repository's authentication token (typically GITHUB_TOKEN) is configured for use by local git commands [1][2]. When persist-credentials is set to true (the default), actions/checkout configures the authentication credentials to allow subsequent steps in the job to run authenticated git commands like git fetch or git push without needing to manually re-authenticate [1][3]. Key details regarding this behavior include: 1. Credential Location: In older versions of actions/checkout (v5 and earlier), these credentials were stored directly in the local .git/config file [4][5]. Starting with actions/checkout v6, the action was updated to store these credentials in a separate file located in $RUNNER_TEMP instead of directly modifying .git/config, which improves security [3][5][6]. 2. Purpose: This persistence is what allows scripts within your workflow to execute authenticated git operations seamlessly using the environment's existing identity [1][3]. 3. Disabling Persistence: If your workflow does not require running authenticated git commands, or if you want to prevent the credentials from being available to subsequent steps, you can set persist-credentials: false in your workflow step [1][7][4]. 4. Security Considerations: Because these credentials allow authenticated git operations, they are sensitive. Historically, concerns were raised that persisting them in .git/config could lead to accidental leakage (e.g., if the workspace was uploaded as an artifact) [4]. While v6+ mitigates this by moving the storage location, security best practices still recommend setting persist-credentials: false if the functionality is not explicitly required, as well as applying the principle of least privilege to the GITHUB_TOKEN permissions [8][9][4]. Note that this configuration can also cause conflicts if you are using tools like gh auth setup-git to configure different credentials, as the existing actions/checkout configuration may take precedence [7].
Citations:
- 1: https://www.github.com/actions/checkout
- 2: https://github.com/actions/checkout/blob/main/action.yml
- 3: https://github.com/actions/checkout
- 4: https://sisaku-security.github.io/lint/docs/rules/artipacked/
- 5: https://github.com/actions/checkout/tree/v6.0.2?tab=readme-ov-file
- 6: https://github.com/actions/checkout/tree/v6.0.0
- 7:
gh auth setup-gitdoes not override the git user following anactions/checkoutinvocation cli/cli#10905 - 8: Remove
persist-credentialsor change the default tofalseactions/checkout#485 - 9: [security] Escalate concerning default
persist-credentials=trueplease actions/checkout#2312
🌐 Web query:
actions/checkout github app token persist-credentials local git config v4
💡 Result:
In actions/checkout@v4, the persist-credentials input controls whether the authentication token (or SSH key) used to fetch the repository is configured in the local Git configuration [1][2]. Key details regarding this setting include: - Default Behavior: The input defaults to true [2][3]. When enabled, the action configures the Git credential (typically the GITHUB_TOKEN or a provided PAT/SSH key) into the local repository's .git/config file [2][4]. This allows subsequent steps in the same workflow job to perform authenticated Git operations (e.g., git push, git fetch) without needing to explicitly provide credentials again [1][5]. - Security Implications: Because the credentials are written to the .git/config file, they may be exposed if the workspace (including the .git directory) is handled by other processes or included in artifacts that are uploaded or shared [4]. - Opting Out: You can set persist-credentials: false to prevent the action from writing these credentials to the local Git configuration [1][3]. This is recommended as a security best practice if downstream steps do not require authenticated Git access, as it reduces the attack surface by ensuring no long-lived credentials remain in the environment's Git config [4]. - Cleanup: In actions/checkout@v4, the action includes a post-job step designed to remove these persisted credentials from the Git configuration after the job completes [1][2]. For environments requiring higher security or where credentials must not be stored on disk, persist-credentials: false is the standard configuration to ensure the runner environment remains isolated from the repository's access tokens [4][6].
Citations:
- 1: https://github.com/actions/checkout/blob/v4/README.md
- 2: https://github.com/actions/checkout/blob/v4/action.yml
- 3: https://github.com/actions/checkout/?tab=readme-ov-file
- 4: Set
persist-credentials: falseon checkout steps cli/go-gh#225 - 5: https://github.com/actions/checkout
- 6: https://spacelift.io/blog/github-actions-checkout
Disable checkout credential persistence.
Set persist-credentials: false on both checkout steps. actions/checkout@v4 persists the Git credentials by default, and this workflow does not need authenticated Git commands later.
Proposed fix
- - uses: actions/checkout@v4
+ - uses: actions/checkout@v4
+ with:
+ persist-credentials: falseThe same change applies to the checkout step in the build job and the checkout step in the typecheck job.
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| - uses: actions/checkout@v4 | |
| - uses: actions/checkout@v4 | |
| with: | |
| persist-credentials: false |
🧰 Tools
🪛 zizmor (1.28.0)
[warning] 13-13: credential persistence through GitHub Actions artifacts (artipacked): does not set persist-credentials: false
(artipacked)
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In @.github/workflows/ci.yml at line 13, Update both actions/checkout@v4 steps
in the build and typecheck jobs to set persist-credentials to false, ensuring
neither checkout retains Git credentials for later workflow steps.
Source: Linters/SAST tools
| const detail = await res.text().catch(() => ""); | ||
| throw new Error(`GitHub tree API returned ${res.status}: ${detail.slice(0, 200)}`); |
There was a problem hiding this comment.
🩺 Stability & Availability | 🟠 Major | ⚡ Quick win
🧩 Analysis chain
🏁 Script executed:
#!/usr/bin/env bash
set -euo pipefail
rg -n 'res\.text\(\)|detail\.slice\(0,\s*200\)' src/sync/github-sync.ts
node --input-type=module <<'EOF'
const size = 1024 * 1024;
const response = new Response("x".repeat(size), { status: 500 });
const body = await response.text();
if (body.length !== size) {
throw new Error("Response.text() did not consume the full body");
}
console.log("Response.text() consumes the full response body");
EOFRepository: leeknowsai/paperclip-plugin-superpowers
Length of output: 722
🏁 Script executed:
#!/usr/bin/env bash
set -euo pipefail
printf 'Outline:\n'
ast-grep outline src/sync/github-sync.ts --view compact || true
printf '\nRelevant source:\n'
sed -n '1,170p' src/sync/github-sync.tsRepository: leeknowsai/paperclip-plugin-superpowers
Length of output: 5916
Bound the error-body read before truncating it.
fetchTree() and fetchRawContent() call res.text() before using only the first 200 characters of the body. Use a bounded helper that reads at most 200 bytes from res.body, cancels the stream reader, and uses it for both non-2xx body reads.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@src/sync/github-sync.ts` around lines 121 - 122, Update fetchTree() and
fetchRawContent() to use a shared bounded response-body helper that reads at
most 200 bytes from res.body, cancels the stream reader, and returns the
truncated text. Replace both direct res.text() calls in the non-2xx error paths
while preserving the existing status-specific error messages.
Summary
This PR addresses three structural risks identified during a repository health review:
Changes
Add CI workflow (
.github/workflows/ci.yml)pnpm typecheck)pnpm build)mainand all PRsGitHub API authentication (
src/sync/github-sync.ts)fetchTree()andfetchRawContent()now readGITHUB_TOKENfrom the environmentBetter YAML parse error messages (
src/sync/github-sync.ts)parseSkillFile()now logs a warning with the skill ID when frontmatter is missing or the requirednamefield is absentnullreturn with no indication which skill failedRepository Health Review
Full review available in the paperclip issue thread. Key findings addressed:
Model Used
Reasonix (Claude-based), via Paperclip agent runtime.
Summary by CodeRabbit
Bug Fixes
Tests