Skip to content

Commit d6f2581

Browse files
Merge pull request #31 from CodeWithJuber/claude/whitepaper-implementation-plan-x8f7bh
release: v0.5.0 — seams closed, one-click releases, measured benchmarks, security hardening
2 parents eb68ea9 + 2ed5059 commit d6f2581

48 files changed

Lines changed: 3237 additions & 113 deletions

Some content is hidden

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

.claude-plugin/plugin.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
"$schema": "https://json.schemastore.org/claude-code-plugin-manifest.json",
33
"name": "forgekit",
44
"displayName": "Forge",
5-
"version": "0.4.0",
5+
"version": "0.5.0",
66
"description": "One config, every AI coding tool — cognitive substrate, tools, crew, guards, atlas, lean, recall from one source.",
77
"author": { "name": "CodeWithJuber" },
88
"license": "MIT",

.codex-plugin/plugin.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "forgekit",
3-
"version": "0.4.0",
3+
"version": "0.5.0",
44
"description": "One config, every AI coding tool — cognitive substrate, MCP tools, guards, atlas, recall, and routing from one source.",
55
"author": { "name": "CodeWithJuber", "url": "https://github.com/CodeWithJuber" },
66
"homepage": "https://github.com/CodeWithJuber/forgekit#readme",

.github/workflows/bump.yml

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
# One-click release kickoff: Actions -> "Bump version" -> Run workflow.
2+
# Runs the tests, bumps every version field via scripts/bump.mjs (package.json,
3+
# package-lock.json, both plugin manifests, CITATION.cff, landing page, CHANGELOG
4+
# rotation), commits "chore(release): vX.Y.Z", tags vX.Y.Z, and pushes commit + tag.
5+
#
6+
# Pushing the v* tag is what normally triggers release.yml — but pushes made with
7+
# the default GITHUB_TOKEN deliberately do NOT trigger other workflows (GitHub's
8+
# recursion guard). So this workflow also dispatches release.yml on the new tag
9+
# explicitly, which needs `actions: write` (granted below). No PAT required.
10+
name: Bump version
11+
12+
on:
13+
workflow_dispatch:
14+
inputs:
15+
bump:
16+
description: "Bump type (auto = conventional commits since last tag: BREAKING -> major, feat -> minor, else patch)"
17+
type: choice
18+
default: auto
19+
options:
20+
- auto
21+
- patch
22+
- minor
23+
- major
24+
25+
permissions:
26+
contents: write # push the release commit + tag
27+
actions: write # dispatch release.yml on the new tag
28+
29+
concurrency:
30+
group: bump
31+
cancel-in-progress: false
32+
33+
jobs:
34+
bump:
35+
runs-on: ubuntu-latest
36+
steps:
37+
- uses: actions/checkout@v7
38+
with:
39+
fetch-depth: 0 # full history + tags so "auto" can read commits since the last tag
40+
- uses: actions/setup-node@v6
41+
with:
42+
node-version: 22
43+
cache: npm
44+
- run: npm ci
45+
- run: npm test # never tag a broken tree
46+
- name: Bump version fields + rotate CHANGELOG
47+
id: bump
48+
env:
49+
BUMP: ${{ inputs.bump }}
50+
run: |
51+
VERSION="$(node scripts/bump.mjs "$BUMP")"
52+
echo "version=$VERSION" >> "$GITHUB_OUTPUT"
53+
- name: Commit, tag, push
54+
env:
55+
VERSION: ${{ steps.bump.outputs.version }}
56+
run: |
57+
git config user.name "github-actions[bot]"
58+
git config user.email "41898282+github-actions[bot]@users.noreply.github.com"
59+
git add -A
60+
git commit -m "chore(release): v$VERSION"
61+
git tag -a "v$VERSION" -m "v$VERSION"
62+
git push origin HEAD "v$VERSION"
63+
- name: Trigger the release workflow on the new tag
64+
env:
65+
GH_TOKEN: ${{ github.token }}
66+
VERSION: ${{ steps.bump.outputs.version }}
67+
run: gh workflow run release.yml --ref "v$VERSION"

.github/workflows/ci.yml

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
1-
# CI gate for every push and PR: test matrix (Node 18/20/22), Biome lint+format, ShellCheck,
2-
# the zero-runtime-dependency assertion, and dependency review. All must pass to merge.
1+
# CI gate for every push and PR: test matrix (Node 20/22 — matches the ">=20" engines
2+
# field; 18 is EOL), Biome lint+format, ShellCheck, the zero-runtime-dependency assertion,
3+
# the version-drift guard, and dependency review. All must pass to merge.
34
name: CI
45

56
on:
@@ -17,7 +18,7 @@ jobs:
1718
strategy:
1819
fail-fast: false
1920
matrix:
20-
node: [18, 20, 22]
21+
node: [20, 22]
2122
steps:
2223
- uses: actions/checkout@v7
2324
- uses: actions/setup-node@v6
@@ -58,6 +59,15 @@ jobs:
5859
- run: node -e "process.exit(Object.keys(require('./package.json').dependencies||{}).length)"
5960
- run: npm pack --dry-run
6061

62+
version-drift:
63+
name: Version fields agree
64+
runs-on: ubuntu-latest
65+
steps:
66+
- uses: actions/checkout@v7
67+
# package.json, package-lock.json, .claude-plugin/plugin.json, .codex-plugin/plugin.json,
68+
# and CITATION.cff must all carry the same version (scripts/bump.mjs keeps them in sync).
69+
- run: node scripts/bump.mjs check
70+
6171
dependency-review:
6272
name: Dependency review
6373
runs-on: ubuntu-latest

.github/workflows/codeql.yml

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
# CodeQL static analysis for the JavaScript sources (src/, hooks/, test/). Findings land
2+
# in Security -> Code scanning. This is CodeQL "advanced setup": if the repo ever had
3+
# "default setup" enabled (Settings -> Code security), disable it there so the two don't
4+
# fight over the same analysis slot.
5+
name: CodeQL
6+
7+
on:
8+
push:
9+
branches: [main, master]
10+
pull_request:
11+
schedule:
12+
- cron: "23 4 * * 1" # weekly, Monday 04:23 UTC — catches new queries, not just new code
13+
14+
permissions:
15+
contents: read
16+
17+
jobs:
18+
analyze:
19+
name: Analyze (javascript-typescript)
20+
runs-on: ubuntu-latest
21+
permissions:
22+
contents: read
23+
security-events: write # upload SARIF results to code scanning
24+
steps:
25+
- uses: actions/checkout@v7
26+
- uses: github/codeql-action/init@v4
27+
with:
28+
languages: javascript-typescript
29+
build-mode: none # interpreted — nothing to compile
30+
- uses: github/codeql-action/analyze@v4
31+
with:
32+
category: "/language:javascript-typescript"

.github/workflows/release.yml

Lines changed: 33 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,17 @@
1-
# Push a v* tag -> test -> publish to public npm (with provenance) -> cut a GitHub Release.
2-
# Requires one repo secret: NPM_TOKEN (an npm "Automation" token). See docs/RELEASING.md.
1+
# Runs on a v* tag push, or via workflow_dispatch ON A TAG REF (bump.yml uses the
2+
# dispatch path because pushes made with the default GITHUB_TOKEN never trigger
3+
# other workflows). Flow: test -> assert tag == package.json version -> publish to
4+
# public npm (with provenance) -> cut a GitHub Release.
5+
#
6+
# npm publish is SKIPPED with a warning — not failed — when the NPM_TOKEN secret is
7+
# missing, so the GitHub Release is still created. Add an npm "Automation" token as
8+
# the NPM_TOKEN repo secret to enable publishing. See docs/RELEASING.md.
39
name: Release
410

511
on:
612
push:
713
tags: ["v*"]
14+
workflow_dispatch: # dispatched by bump.yml with --ref vX.Y.Z; must target a tag
815

916
permissions:
1017
contents: read
@@ -15,7 +22,15 @@ jobs:
1522
permissions:
1623
contents: write # create the GitHub Release
1724
id-token: write # npm provenance (supply-chain attestation)
25+
env:
26+
# secrets are not directly usable in step `if:`, so surface presence here.
27+
HAS_NPM_TOKEN: ${{ secrets.NPM_TOKEN != '' }}
1828
steps:
29+
- name: Assert this run targets a v* tag
30+
if: github.ref_type != 'tag'
31+
run: |
32+
echo "::error::Release must run on a v* tag ref (got '${{ github.ref }}'). Use the 'Bump version' workflow to cut one."
33+
exit 1
1934
- uses: actions/checkout@v7
2035
with:
2136
fetch-depth: 0 # full history so release notes can diff from the last tag
@@ -26,9 +41,24 @@ jobs:
2641
cache: npm
2742
- run: npm ci
2843
- run: npm test
29-
- run: npm publish --provenance --access public
44+
- name: Assert tag matches package.json version
45+
env:
46+
TAG: ${{ github.ref_name }}
47+
run: |
48+
PKG="v$(node -p "require('./package.json').version")"
49+
if [ "$TAG" != "$PKG" ]; then
50+
echo "::error::Tag $TAG does not match package.json version $PKG. Re-run the 'Bump version' workflow instead of tagging by hand."
51+
exit 1
52+
fi
53+
- name: Publish to npm (with provenance)
54+
if: env.HAS_NPM_TOKEN == 'true'
55+
run: npm publish --provenance --access public
3056
env:
3157
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
58+
- name: Skip npm publish (NPM_TOKEN not set)
59+
if: env.HAS_NPM_TOKEN != 'true'
60+
run: |
61+
echo "::warning::NPM_TOKEN secret is not set — SKIPPING npm publish. The GitHub Release is still created. To publish, add an npm Automation token as the NPM_TOKEN repo secret (Settings -> Secrets and variables -> Actions) and re-run this workflow. See docs/RELEASING.md."
3262
- name: Create GitHub Release
3363
env:
3464
GH_TOKEN: ${{ github.token }}

.github/workflows/repo-settings.yml

Lines changed: 19 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -3,15 +3,18 @@
33
#
44
# NOTE: editing repo settings needs an ADMIN-scoped token. The default GITHUB_TOKEN
55
# cannot be granted `administration`, so add a fine-grained PAT (Administration: write,
6-
# Metadata: read) as the repo secret ADMIN_TOKEN. Without it the job will 403 — in that
7-
# case just run the two `gh` commands below locally once (they need no workflow):
6+
# Metadata: read) as the repo secret ADMIN_TOKEN. Without it the job SKIPS with a
7+
# warning (soft fail) — in that case just run the two `gh` commands below locally once
8+
# (they need no workflow):
89
#
910
# gh repo edit CodeWithJuber/forgekit \
1011
# --description "One config for every AI coding agent — cross-tool config + a cognitive substrate (memory, blast-radius, guardrails) for Claude Code, Codex, Cursor, Gemini, Aider, and more." \
1112
# --homepage "https://github.com/CodeWithJuber/forgekit#readme" \
12-
# --add-topic claude-code --add-topic ai-coding --add-topic ai-agents --add-topic mcp \
13-
# --add-topic agents-md --add-topic cross-tool --add-topic cognitive-substrate \
14-
# --add-topic developer-tools --add-topic cli --add-topic codex --add-topic cursor
13+
# --add-topic ai-agents --add-topic claude-code --add-topic codex --add-topic cursor \
14+
# --add-topic developer-tools --add-topic llm --add-topic memory --add-topic mcp \
15+
# --add-topic agent-memory --add-topic cost-optimization --add-topic code-quality \
16+
# --add-topic cli --add-topic zero-dependency --add-topic crdt --add-topic team-memory \
17+
# --add-topic ai-coding --add-topic agents-md --add-topic cross-tool --add-topic cognitive-substrate
1518
# gh api --method PATCH /repos/CodeWithJuber/forgekit -F has_discussions=true
1619
name: Repo settings
1720

@@ -27,15 +30,22 @@ jobs:
2730
steps:
2831
- name: Apply About, topics, and Discussions
2932
env:
30-
GH_TOKEN: ${{ secrets.ADMIN_TOKEN || github.token }}
33+
GH_TOKEN: ${{ secrets.ADMIN_TOKEN }}
3134
REPO: ${{ github.repository }}
3235
run: |
36+
if [ -z "$GH_TOKEN" ]; then
37+
echo "::warning::ADMIN_TOKEN secret is not set — skipping. Editing repo settings needs a fine-grained PAT (Administration: write, Metadata: read) saved as the ADMIN_TOKEN repo secret; the default GITHUB_TOKEN cannot be granted 'administration'. Alternatively run the gh commands from this workflow's header comment locally."
38+
exit 0
39+
fi
3340
set -e
41+
# 19 topics (GitHub caps at 20): discoverability terms first, project-specific last.
3442
gh repo edit "$REPO" \
3543
--description "One config for every AI coding agent — cross-tool config + a cognitive substrate (memory, blast-radius, guardrails) for Claude Code, Codex, Cursor, Gemini, Aider, and more." \
3644
--homepage "https://github.com/CodeWithJuber/forgekit#readme" \
37-
--add-topic claude-code --add-topic ai-coding --add-topic ai-agents --add-topic mcp \
38-
--add-topic agents-md --add-topic cross-tool --add-topic cognitive-substrate \
39-
--add-topic developer-tools --add-topic cli --add-topic codex --add-topic cursor
45+
--add-topic ai-agents --add-topic claude-code --add-topic codex --add-topic cursor \
46+
--add-topic developer-tools --add-topic llm --add-topic memory --add-topic mcp \
47+
--add-topic agent-memory --add-topic cost-optimization --add-topic code-quality \
48+
--add-topic cli --add-topic zero-dependency --add-topic crdt --add-topic team-memory \
49+
--add-topic ai-coding --add-topic agents-md --add-topic cross-tool --add-topic cognitive-substrate
4050
gh api --method PATCH "/repos/$REPO" -F has_discussions=true
4151
echo "Applied About, topics, and Discussions for $REPO."

.github/workflows/scorecard.yml

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
# OSSF Scorecard: weekly supply-chain posture check (branch protection, token permissions,
2+
# pinned dependencies, ...). publish_results feeds the public viewer/API at
3+
# https://scorecard.dev/viewer/?uri=github.com/CodeWithJuber/forgekit — required for the
4+
# Scorecard badge. Results also land in Security -> Code scanning as SARIF.
5+
# Scorecard itself will flag tag-pinned actions; this repo pins to major tags and lets
6+
# Dependabot track them (see .github/dependabot.yml) — accepted trade-off, documented here.
7+
name: Scorecard
8+
9+
on:
10+
push:
11+
branches: [master] # default branch only — publish_results requires it
12+
schedule:
13+
- cron: "30 5 * * 1" # weekly, Monday 05:30 UTC
14+
15+
permissions: read-all
16+
17+
jobs:
18+
analysis:
19+
name: Scorecard analysis
20+
runs-on: ubuntu-latest
21+
permissions:
22+
security-events: write # upload SARIF to code scanning
23+
id-token: write # sign results so scorecard.dev will publish them
24+
steps:
25+
- uses: actions/checkout@v7
26+
with:
27+
persist-credentials: false # scorecard checks for exactly this
28+
- uses: ossf/scorecard-action@v2
29+
with:
30+
results_file: results.sarif
31+
results_format: sarif
32+
publish_results: true
33+
- uses: github/codeql-action/upload-sarif@v4
34+
with:
35+
sarif_file: results.sarif

.github/workflows/security.yml

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
# Secret scanning gate: gitleaks over the FULL git history on every push and PR.
2+
# Deliberately blocking — a real credential in the tree or history should fail the build,
3+
# not warn. (Rotate first, then rewrite/land; a red X is the cheap part of a leak.)
4+
#
5+
# Why this passes on our own redaction tests: test/_fixtures.js assembles secret-LOOKING
6+
# strings at RUNTIME via .join() precisely so no secret-format literal exists in any blob
7+
# for a scanner to match. Verified clean with gitleaks 8.16 across the whole history and
8+
# working tree before this workflow was added — no .gitleaks.toml allowlist is needed.
9+
name: Security
10+
11+
on:
12+
push:
13+
branches: [main, master]
14+
pull_request:
15+
16+
permissions:
17+
contents: read
18+
19+
jobs:
20+
gitleaks:
21+
name: Secret scan (gitleaks)
22+
runs-on: ubuntu-latest
23+
steps:
24+
- uses: actions/checkout@v7
25+
with:
26+
fetch-depth: 0 # gitleaks scans commit history, not just the checkout
27+
- uses: gitleaks/gitleaks-action@v2
28+
env:
29+
GITHUB_TOKEN: ${{ github.token }} # PR comments / job summary
30+
# GITLEAKS_LICENSE is only required for ORG-owned repos; this repo is user-owned.

.github/workflows/stale.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ name: Stale
55
on:
66
schedule:
77
- cron: "0 3 * * *"
8+
workflow_dispatch: # allow a manual run to test the config
89

910
permissions:
1011
issues: write

0 commit comments

Comments
 (0)