Open-source pipeline: fork, sanitize, and package private projects for safe public release. Chains 3 agents (forker, sanitizer, packager). Triggers: '/opensource', 'open source this', 'make this public', 'prepare for open source'. Use when a private project must be forked, stripped of secrets, and packaged for public release.
86%
Does it follow best practices?
Run evals on this skill
Adds up to 20 points to the overall score
Passed
No findings from the security scan
Safely open-source any project through a 3-stage pipeline: Fork (strip secrets) → Sanitize (verify clean) → Package (CLAUDE.md + setup.sh + README).
/opensource fork, /opensource verify, or /opensource package| Command | Action |
|---|---|
/opensource fork PROJECT | Full pipeline: fork + sanitize + package |
/opensource verify PROJECT | Run sanitizer on existing repo |
/opensource package PROJECT | Generate CLAUDE.md + setup.sh + README |
/opensource list | Show all staged projects |
/opensource status PROJECT | Show reports for a staged project |
Full pipeline — the main workflow.
Resolve the project path. If PROJECT contains /, treat as a path (absolute or relative). Otherwise check: current working directory, $HOME/PROJECT, then ask the user.
SOURCE_PATH="<resolved absolute path>"
STAGING_PATH="$HOME/opensource-staging/${PROJECT_NAME}"Ask the user:
gh api user -q .login)mkdir -p $HOME/opensource-staging/Spawn the opensource-forker agent:
Agent(
description="Fork {PROJECT} for open-source",
subagent_type="opensource-forker",
prompt="""
Fork project for open-source release.
Source: {SOURCE_PATH}
Target: {STAGING_PATH}
License: {chosen_license}
Follow the full forking protocol:
1. Copy files (exclude .git, node_modules, __pycache__, .venv)
2. Strip all secrets and credentials
3. Replace internal references with placeholders
4. Generate .env.example
5. Clean git history
6. Generate FORK_REPORT.md in {STAGING_PATH}/FORK_REPORT.md
"""
)Wait for completion. Read {STAGING_PATH}/FORK_REPORT.md.
The forker's single commit is only the starting point: gh repo create --push (Step 7)
publishes commits, not the working tree. Every later change (sanitizer fixes, packager output)
must be folded into that commit, so the public history is one commit that matches the tree the
sanitizer passed. The reports stay out of it. Fold changes in with:
cd "{STAGING_PATH}"
grep -qxF SANITIZATION_REPORT.md .git/info/exclude || printf '%s\n' FORK_REPORT.md SANITIZATION_REPORT.md >> .git/info/exclude
git add -A
git rm -q --cached --ignore-unmatch FORK_REPORT.md SANITIZATION_REPORT.md
git commit --amend --no-edit
git status --porcelain -uno # must print nothing
git rev-list --count HEAD # must print 1An amend leaves a secret that was removed from a file out of the new commit. A new commit on top would publish it in history.
Spawn the opensource-sanitizer agent:
Agent(
description="Verify {PROJECT} sanitization",
subagent_type="opensource-sanitizer",
prompt="""
Verify sanitization of open-source fork.
Project: {STAGING_PATH}
Source (for reference): {SOURCE_PATH}
Run ALL scan categories:
1. Secrets scan (CRITICAL)
2. PII scan (CRITICAL)
3. Internal references scan (CRITICAL)
4. Dangerous files check (CRITICAL)
5. Configuration completeness (WARNING)
6. Git history audit
7. Unreadable files (WARNING)
Generate SANITIZATION_REPORT.md inside {STAGING_PATH}/ with PASS/FAIL verdict.
"""
)Wait for completion. Read {STAGING_PATH}/SANITIZATION_REPORT.md.
If FAIL: Show findings to user. Ask: "Fix these and re-scan, or abort?"
Unreadable files. After the fix/rescan loop settles, read the report's ## Unreadable Files
section, not stdout:
unknown, or the section or the count is missing, the scan did not finish. Stop
before Step 5, as for a FAIL: show any Scan problem lines and ask the user to fix the cause and
re-scan, or abort. A missing section is never an empty one, and an unknown count cannot be
confirmed away.{STAGING_PATH}.UNREADABLE_FILES.txt, which sits beside the staging directory,
not inside it. Ask: "These were never read. Confirm you've opened them, or abort?" Ask once,
against the final report, not on each retry.wc -l on it must equal the count, and it must
not exist when the count is zero. Treat a mismatch as unknown.Most repos trip this on a logo or a font, so expect to be asked.
Continue to Step 5 only when the verdict is PASS or PASS WITH WARNINGS and the unreadable count is zero or the user has confirmed the files. A FAIL (including after the 3 retries), an unknown or missing count, or an unconfirmed list stops the pipeline here.
Spawn the opensource-packager agent:
Agent(
description="Package {PROJECT} for open-source",
subagent_type="opensource-packager",
prompt="""
Generate open-source packaging for project.
Project: {STAGING_PATH}
License: {chosen_license}
Project name: {PROJECT_NAME}
Description: {description}
GitHub repo: {github_repo}
Generate:
1. CLAUDE.md (commands, architecture, key files)
2. setup.sh (one-command bootstrap, make executable)
3. README.md (or enhance existing)
4. LICENSE
5. CONTRIBUTING.md
6. .github/ISSUE_TEMPLATE/ (bug_report.md, feature_request.md)
"""
)The packager's files are not committed yet. Fold them into the commit (see Step 3), then run the sanitizer again exactly as in Step 4, against what will be published. Apply the same gate as Step 4, including the fix loop and the unreadable-files check. A FAIL here stops the pipeline: packaging can add a personal email, a home path or a key in an example.
When the gate passes, record the commit the sanitizer scanned as {SCANNED_COMMIT}:
git -C "{STAGING_PATH}" rev-parse HEADPresent to user:
Open-Source Fork Ready: {PROJECT_NAME}
Location: {STAGING_PATH}
License: {license}
Files generated:
- CLAUDE.md
- setup.sh (executable)
- README.md
- LICENSE
- CONTRIBUTING.md
- .env.example ({N} variables)
Sanitization: {sanitization_verdict} (scanned after packaging, on the commit that will be pushed)
Next steps:
1. Review: cd {STAGING_PATH}
2. Create repo: gh repo create {github_org}/{github_repo} --public
3. Push: git remote add origin ... && git push -u origin main
Proceed with GitHub creation? (yes/no/review first)Push only the commit the sanitizer passed. If the tree or the commit changed since Step 5b (for
example the user edited files after "review first" and amended), go back to Step 5b instead of
pushing. The two generated reports may remain untracked even when a source .gitignore negates
their names. Allow only those two untracked files; a report in the index or scanned commit, or any
other worktree change, still stops publication.
cd "{STAGING_PATH}"
test -z "$(git ls-files -- FORK_REPORT.md SANITIZATION_REPORT.md)" \
&& test -z "$(git ls-tree -r --name-only HEAD -- FORK_REPORT.md SANITIZATION_REPORT.md)" \
&& test -z "$(git status --porcelain --untracked-files=all -- . ':(exclude)FORK_REPORT.md' ':(exclude)SANITIZATION_REPORT.md')" \
&& test "$(git rev-list --count HEAD)" = 1 \
&& test "$(git rev-parse HEAD)" = "{SCANNED_COMMIT}" \
|| { echo "Uncommitted changes, extra commits, or HEAD is not the scanned commit: return to Step 5b" >&2; exit 1; }
gh repo create "{github_org}/{github_repo}" --public --source=. --push --description "{description}"Run sanitizer independently. Resolve path: if PROJECT contains /, treat as a path. Otherwise check $HOME/opensource-staging/PROJECT, then $HOME/PROJECT, then current directory.
Agent(
subagent_type="opensource-sanitizer",
prompt="Verify sanitization of: {resolved_path}. Run all 7 scan categories and generate SANITIZATION_REPORT.md."
)There is no confirmation gate here. Show the user the report, including the ## Unreadable Files
count and tally. When the count is above zero, point them at {resolved_path}.UNREADABLE_FILES.txt
and do not read or print it.
Run packager independently. Ask for "License?" and "Description?", then:
Agent(
subagent_type="opensource-packager",
prompt="Package: {resolved_path} ..."
)ls -d $HOME/opensource-staging/*/Show each project with pipeline progress (FORK_REPORT.md, SANITIZATION_REPORT.md, CLAUDE.md presence).
cat $HOME/opensource-staging/${PROJECT}/SANITIZATION_REPORT.md
cat $HOME/opensource-staging/${PROJECT}/FORK_REPORT.md$HOME/opensource-staging/
my-project/
FORK_REPORT.md # From forker agent
SANITIZATION_REPORT.md # From sanitizer agent
CLAUDE.md # From packager agent
setup.sh # From packager agent
README.md # From packager agent
.env.example # From forker agent
... # Sanitized project files
my-project.UNREADABLE_FILES.txt # From sanitizer agent, only when files could not be read.env, *.pem, or credentials.json in the staging directorySee security-review for secret detection patterns used by the sanitizer.
affaan-m/ECC
25278e7
Also appears in
last in sync Jul 13, 2026
If you maintain this skill, you can claim it as your own. Once claimed, you can manage eval scenarios, bundle related skills, attach documentation or rules, and ensure cross-agent compatibility.