Skip to content

Commit a0c68b9

Browse files
committed
feat: v0.5.0 — CLI features, docs site overhaul, repo hardening
1 parent 627374c commit a0c68b9

61 files changed

Lines changed: 7723 additions & 207 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.github/CODEOWNERS

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,12 +9,23 @@
99

1010
# CI/CD pipelines
1111
/.github/workflows/ @SubhanshuMG
12+
/.github/CODEOWNERS @SubhanshuMG
1213

13-
# Legal and licensing
14+
# Legal, licensing, and ownership (NEVER merge without maintainer review)
1415
LICENSE @SubhanshuMG
1516
TRADEMARK.md @SubhanshuMG
1617
NOTICE @SubhanshuMG
1718
SECURITY.md @SubhanshuMG
19+
CONTRIBUTING.md @SubhanshuMG
20+
CODE_OF_CONDUCT.md @SubhanshuMG
21+
22+
# Package publishing configuration
23+
/packages/cli/package.json @SubhanshuMG
24+
/package.json @SubhanshuMG
1825

1926
# Security configuration
2027
/.gitleaks.toml @SubhanshuMG
28+
29+
# npm configuration (prevent publish hijacking)
30+
/.npmrc @SubhanshuMG
31+
/.npmignore @SubhanshuMG
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
name: Update Contributors Wall
2+
3+
on:
4+
push:
5+
branches: [main]
6+
workflow_dispatch: {}
7+
8+
permissions:
9+
contents: write
10+
11+
jobs:
12+
update-contributors:
13+
runs-on: ubuntu-latest
14+
timeout-minutes: 5
15+
steps:
16+
- name: Checkout
17+
uses: actions/checkout@v4
18+
19+
- name: Update contributor wall in README
20+
run: |
21+
# Generate the contributors section using contrib.rocks
22+
CONTRIBUTORS_IMG="<a href=\"https://github.com/SubhanshuMG/ForgeKit/graphs/contributors\"><img src=\"https://contrib.rocks/image?repo=SubhanshuMG/ForgeKit&max=100\" /></a>"
23+
24+
# Check if markers exist in README
25+
if ! grep -q "<!-- CONTRIBUTORS-START -->" README.md; then
26+
echo "::warning::Contributors markers not found in README.md. Skipping."
27+
exit 0
28+
fi
29+
30+
# Replace content between markers
31+
sed -i '/<!-- CONTRIBUTORS-START -->/,/<!-- CONTRIBUTORS-END -->/c\<!-- CONTRIBUTORS-START -->\n'"${CONTRIBUTORS_IMG}"'\n<!-- CONTRIBUTORS-END -->' README.md
32+
33+
- name: Check for changes
34+
id: check
35+
run: |
36+
if git diff --quiet README.md; then
37+
echo "changed=false" >> "$GITHUB_OUTPUT"
38+
else
39+
echo "changed=true" >> "$GITHUB_OUTPUT"
40+
fi
41+
42+
- name: Commit and push
43+
if: steps.check.outputs.changed == 'true'
44+
run: |
45+
git config user.name "github-actions[bot]"
46+
git config user.email "41898282+github-actions[bot]@users.noreply.github.com"
47+
git add README.md
48+
git commit -m "docs: update contributors wall [skip ci]"
49+
git push
Lines changed: 107 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,107 @@
1+
name: Fork Compliance Monitor
2+
3+
on:
4+
schedule:
5+
# Runs every Monday at 9:00 UTC
6+
- cron: '0 9 * * 1'
7+
workflow_dispatch:
8+
9+
permissions:
10+
contents: read
11+
issues: write
12+
13+
jobs:
14+
monitor-forks:
15+
name: Scan forks for compliance violations
16+
runs-on: ubuntu-latest
17+
timeout-minutes: 10
18+
steps:
19+
- uses: actions/checkout@v4
20+
21+
- name: Scan forks
22+
env:
23+
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
24+
run: |
25+
set -euo pipefail
26+
27+
OWNER="SubhanshuMG"
28+
REPO="ForgeKit"
29+
REPORT_FILE="fork-report.md"
30+
31+
echo "# Fork Compliance Report" > "$REPORT_FILE"
32+
echo "" >> "$REPORT_FILE"
33+
echo "Generated: $(date -u '+%Y-%m-%d %H:%M UTC')" >> "$REPORT_FILE"
34+
echo "" >> "$REPORT_FILE"
35+
36+
VIOLATIONS=0
37+
38+
# Fetch all forks (paginated, up to 300)
39+
for PAGE in 1 2 3; do
40+
FORKS=$(gh api "repos/$OWNER/$REPO/forks?per_page=100&page=$PAGE&sort=newest" --jq '.[].full_name' 2>/dev/null || echo "")
41+
[ -z "$FORKS" ] && break
42+
43+
while IFS= read -r FORK; do
44+
[ -z "$FORK" ] && continue
45+
46+
FORK_OWNER=$(echo "$FORK" | cut -d'/' -f1)
47+
FORK_NAME=$(echo "$FORK" | cut -d'/' -f2)
48+
49+
# Check 1: LICENSE file exists
50+
LICENSE_EXISTS=$(gh api "repos/$FORK/contents/LICENSE" --jq '.name' 2>/dev/null || echo "MISSING")
51+
52+
# Check 2: NOTICE file exists
53+
NOTICE_EXISTS=$(gh api "repos/$FORK/contents/NOTICE" --jq '.name' 2>/dev/null || echo "MISSING")
54+
55+
# Check 3: Fork renamed to something with "forgekit" (trademark concern)
56+
NAME_VIOLATION="NO"
57+
LOWER_NAME=$(echo "$FORK_NAME" | tr '[:upper:]' '[:lower:]')
58+
if [ "$LOWER_NAME" != "forgekit" ] && echo "$LOWER_NAME" | grep -qi "forgekit"; then
59+
NAME_VIOLATION="YES"
60+
fi
61+
62+
# Check 4: Has the fork published npm packages? (check package.json name)
63+
PKG_NAME=$(gh api "repos/$FORK/contents/packages/cli/package.json" --jq '.content' 2>/dev/null | base64 -d 2>/dev/null | python3 -c "import sys,json; print(json.load(sys.stdin).get('name',''))" 2>/dev/null || echo "")
64+
65+
NPM_VIOLATION="NO"
66+
if [ -n "$PKG_NAME" ] && echo "$PKG_NAME" | grep -qi "forgekit"; then
67+
# Only flag if they changed it to something like "forgekit-pro" etc.
68+
if [ "$PKG_NAME" != "forgekit-cli" ]; then
69+
NPM_VIOLATION="YES"
70+
fi
71+
fi
72+
73+
# Report violations
74+
if [ "$LICENSE_EXISTS" = "MISSING" ] || [ "$NOTICE_EXISTS" = "MISSING" ] || [ "$NAME_VIOLATION" = "YES" ] || [ "$NPM_VIOLATION" = "YES" ]; then
75+
VIOLATIONS=$((VIOLATIONS + 1))
76+
echo "## $FORK" >> "$REPORT_FILE"
77+
echo "" >> "$REPORT_FILE"
78+
[ "$LICENSE_EXISTS" = "MISSING" ] && echo "- LICENSE file removed (Apache 2.0 violation)" >> "$REPORT_FILE"
79+
[ "$NOTICE_EXISTS" = "MISSING" ] && echo "- NOTICE file removed (Apache 2.0 Section 4(d) violation)" >> "$REPORT_FILE"
80+
[ "$NAME_VIOLATION" = "YES" ] && echo "- Fork name contains 'forgekit' trademark: \`$FORK_NAME\`" >> "$REPORT_FILE"
81+
[ "$NPM_VIOLATION" = "YES" ] && echo "- Package name uses forgekit trademark: \`$PKG_NAME\`" >> "$REPORT_FILE"
82+
echo "- Link: https://github.com/$FORK" >> "$REPORT_FILE"
83+
echo "" >> "$REPORT_FILE"
84+
fi
85+
done <<< "$FORKS"
86+
done
87+
88+
echo "---" >> "$REPORT_FILE"
89+
echo "Total violations found: $VIOLATIONS" >> "$REPORT_FILE"
90+
91+
echo "VIOLATIONS=$VIOLATIONS" >> "$GITHUB_ENV"
92+
93+
cat "$REPORT_FILE"
94+
95+
- name: Create issue if violations found
96+
if: env.VIOLATIONS != '0'
97+
env:
98+
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
99+
run: |
100+
BODY=$(cat fork-report.md)
101+
# Ensure labels exist (no-op if they already do)
102+
gh label create "trademark-violation" --description "Potential trademark or license violation" --color "B60205" 2>/dev/null || true
103+
gh label create "automated" --description "Created by automated workflow" --color "BFDADC" 2>/dev/null || true
104+
gh issue create \
105+
--title "Fork Compliance: ${{ env.VIOLATIONS }} violation(s) detected ($(date -u '+%Y-%m-%d'))" \
106+
--body "$BODY" \
107+
--label "trademark-violation,automated"
Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
name: License & Copyright Check
2+
3+
on:
4+
pull_request:
5+
branches: [main]
6+
push:
7+
branches: [main]
8+
9+
permissions:
10+
contents: read
11+
12+
jobs:
13+
license-check:
14+
name: Verify license headers and ownership files
15+
runs-on: ubuntu-latest
16+
timeout-minutes: 5
17+
steps:
18+
- uses: actions/checkout@v4
19+
20+
- name: Check ownership files exist
21+
run: |
22+
set -euo pipefail
23+
MISSING=0
24+
25+
for FILE in LICENSE NOTICE TRADEMARK.md SECURITY.md .github/CODEOWNERS; do
26+
if [ ! -f "$FILE" ]; then
27+
echo "FAIL: $FILE is missing"
28+
MISSING=$((MISSING + 1))
29+
else
30+
echo "OK: $FILE exists"
31+
fi
32+
done
33+
34+
if [ "$MISSING" -gt 0 ]; then
35+
echo "::error::$MISSING ownership file(s) missing. These files must not be deleted."
36+
exit 1
37+
fi
38+
39+
- name: Check LICENSE has not been modified
40+
run: |
41+
# Verify the LICENSE file still contains Apache 2.0
42+
if ! grep -q "Apache License" LICENSE; then
43+
echo "::error::LICENSE file has been modified or replaced. Must remain Apache 2.0."
44+
exit 1
45+
fi
46+
echo "OK: LICENSE is Apache 2.0"
47+
48+
- name: Check NOTICE file integrity
49+
run: |
50+
# Verify NOTICE still credits the original author
51+
if ! grep -q "Subhanshu Mohan Gupta" NOTICE; then
52+
echo "::error::NOTICE file attribution has been removed or modified."
53+
exit 1
54+
fi
55+
if ! grep -q "SubhanshuMG/ForgeKit" NOTICE; then
56+
echo "::error::NOTICE file repository reference has been removed."
57+
exit 1
58+
fi
59+
echo "OK: NOTICE file intact"
60+
61+
- name: Check copyright headers in source files
62+
run: |
63+
MISSING=0
64+
CHECKED=0
65+
66+
# Check TypeScript files in packages/cli/src
67+
while IFS= read -r FILE; do
68+
CHECKED=$((CHECKED + 1))
69+
if ! head -3 "$FILE" | grep -q "Copyright.*ForgeKit"; then
70+
echo "WARN: Missing copyright header: $FILE"
71+
MISSING=$((MISSING + 1))
72+
fi
73+
done < <(find packages/cli/src -name '*.ts' -not -path '*/node_modules/*' -not -path '*/__tests__/*' 2>/dev/null || true)
74+
75+
echo "Checked $CHECKED files, $MISSING missing headers"
76+
77+
# Warn but don't fail for missing headers (test files are exempt)
78+
if [ "$MISSING" -gt 5 ]; then
79+
echo "::warning::$MISSING source files missing copyright headers"
80+
fi

.github/workflows/npm-monitor.yml

Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
name: npm Name Monitor
2+
3+
on:
4+
schedule:
5+
# Runs every Wednesday at 10:00 UTC
6+
- cron: '0 10 * * 3'
7+
workflow_dispatch:
8+
9+
permissions:
10+
contents: read
11+
issues: write
12+
13+
jobs:
14+
check-npm-squatting:
15+
name: Check for npm package squatting
16+
runs-on: ubuntu-latest
17+
timeout-minutes: 5
18+
steps:
19+
- name: Check for suspicious packages
20+
env:
21+
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
22+
run: |
23+
set -euo pipefail
24+
25+
# Package names to monitor for squatting/impersonation
26+
NAMES=(
27+
"forgekit"
28+
"forge-kit"
29+
"forgekit-core"
30+
"forgekit-pro"
31+
"forgekit-cloud"
32+
"forgekit-ai"
33+
"@forgekit/cli"
34+
"@forgekit/core"
35+
"forgekit-toolkit"
36+
"forgekit-dev"
37+
)
38+
39+
# Our official package
40+
OFFICIAL="forgekit-cli"
41+
42+
REPORT=""
43+
FOUND=0
44+
45+
for NAME in "${NAMES[@]}"; do
46+
STATUS=$(curl -s -o /dev/null -w "%{http_code}" "https://registry.npmjs.org/$NAME")
47+
if [ "$STATUS" = "200" ]; then
48+
# Package exists, check if it's ours
49+
MAINTAINER=$(curl -s "https://registry.npmjs.org/$NAME" | python3 -c "
50+
import sys, json
51+
try:
52+
data = json.load(sys.stdin)
53+
m = data.get('maintainers', [])
54+
print(','.join([x.get('name','') for x in m]))
55+
except:
56+
print('unknown')
57+
" 2>/dev/null || echo "unknown")
58+
59+
if ! echo "$MAINTAINER" | grep -qi "subhanshumg"; then
60+
FOUND=$((FOUND + 1))
61+
REPORT="$REPORT\n- **$NAME** exists on npm (maintainer: $MAINTAINER) - https://www.npmjs.com/package/$NAME"
62+
fi
63+
fi
64+
done
65+
66+
if [ "$FOUND" -gt 0 ]; then
67+
BODY="## npm Squatting Alert\n\nThe following npm packages exist and are NOT maintained by the ForgeKit team:\n$REPORT\n\n---\n\n### Action needed\n1. Check if these packages impersonate ForgeKit\n2. If so, report to npm: https://www.npmjs.com/support\n3. Reference official package: https://www.npmjs.com/package/forgekit-cli\n4. Reference TRADEMARK.md in this repo"
68+
69+
echo -e "$BODY"
70+
71+
# Ensure labels exist (no-op if they already do)
72+
gh label create "trademark-violation" --description "Potential trademark or license violation" --color "B60205" --repo "SubhanshuMG/ForgeKit" 2>/dev/null || true
73+
gh label create "automated" --description "Created by automated workflow" --color "BFDADC" --repo "SubhanshuMG/ForgeKit" 2>/dev/null || true
74+
gh issue create \
75+
--repo "SubhanshuMG/ForgeKit" \
76+
--title "npm Alert: $FOUND suspicious package(s) found ($(date -u '+%Y-%m-%d'))" \
77+
--body "$(echo -e "$BODY")" \
78+
--label "trademark-violation,automated"
79+
else
80+
echo "No suspicious packages found. All clear."
81+
fi

0 commit comments

Comments
 (0)