Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions .github/CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -184,12 +184,24 @@ protect:
| `ci-packs-json` | `packs.json` matches a fresh `bin/generate-packs-json` |
| `ci-skill-category` | every `SKILL.md` declares a valid `category:` |
| `ci-capabilities-parity` | the capabilities taxonomy stays in sync |
| `ci-skill-packs` | `catalog/skill-packs.json` is well-formed **and** matches the README's Community Packs table |
| `ci-apps` | each app in `apps/**` typechecks, tests, and builds |
| `ci-tests` | the `scripts/tests/` suites pass |
| `ci-okf` | the knowledge bundle stays OKF-conformant |
| `ci-agents-md` | `AGENTS.md` is regenerated from `STRATEGY.md` |

Run the checks locally before pushing:

```bash
bash scripts/check-skill-categories.sh
bash scripts/check-capabilities-parity.sh
node scripts/validate-skill-packs.mjs # listing a community pack
```

Touching `apps/**`? Run that app's own checks — for the dashboard:

```bash
cd apps/dashboard && npm ci && npm run typecheck && npm test && npm run build
```

If `ci-skills-json`/`ci-packs-json` fails, you changed a generator input without
Expand Down
2 changes: 2 additions & 0 deletions .github/PULL_REQUEST_TEMPLATE.md
Original file line number Diff line number Diff line change
Expand Up @@ -38,13 +38,15 @@
- [ ] Pack has a `skills-pack.json` manifest at its root and a `SKILL.md` per skill
- [ ] Write / onchain / bet skills are `default_enabled: false`
- [ ] This PR adds **both** a README table row and a matching `skill-packs.json` entry
- [ ] `node scripts/validate-skill-packs.mjs` passes (registry shape + README parity, incl. the pack counter)
- [ ] No monkey-patching of Aeon internals; no private or auth-walled endpoints required to run

### Core fix (dashboard / scripts / workflows / docs)

- [ ] Change is focused — one concern, no unrelated refactor
- [ ] Touched code follows the existing pattern in the file
- [ ] Relevant CI gates pass locally (e.g. `bash scripts/check-skill-categories.sh`, `bash scripts/check-capabilities-parity.sh`)
- [ ] Touched `apps/**`? That app typechecks, tests, and builds (dashboard: `npm run typecheck && npm test && npm run build`)

---

Expand Down
16 changes: 16 additions & 0 deletions .github/dependabot.yml
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,22 @@ updates:
patterns:
- "*"

# CLI — non-interactive control of an Aeon repo; shares apps/dashboard/lib.
- package-ecosystem: "npm"
directory: "/apps/cli"
schedule:
interval: "monthly"
open-pull-requests-limit: 5
assignees:
- "aeonfun"
commit-message:
prefix: "chore(deps)"
prefix-development: "chore(deps-dev)"
groups:
cli:
patterns:
- "*"

# Cloudflare Worker that relays Telegram messages to a fork.
- package-ecosystem: "npm"
directory: "/apps/webhook"
Expand Down
142 changes: 142 additions & 0 deletions .github/workflows/ci-apps.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,142 @@
name: ci-apps

# apps/** was the largest untested surface in the repo: four shipped apps — the
# Next.js dashboard, the CLI, the MCP server, and the Telegram Worker — with no
# gate of any kind. The dashboard alone carries 156 committed unit tests
# (apps/dashboard/lib/**/*.test.ts) that nothing ran, plus a strict-mode
# TypeScript config nothing typechecked.
#
# That gap is not theoretical. Dependabot opens grouped monthly npm PRs against
# apps/dashboard, apps/mcp-server, and apps/webhook (.github/dependabot.yml) —
# every one of them landed with zero automated verification that the app still
# compiles. The TypeScript-7 pin comment in dependabot.yml records a breakage
# caught by hand: `next build` crashed while `tsc --noEmit` passed. That is why
# the dashboard job runs BOTH — a typecheck alone would have missed it.
#
# One job per app so a red X names the broken surface, and so a slow dashboard
# build never masks a fast Worker failure. The workflow-level path filter is
# `apps/**` rather than per-job filters: keeping it native (no third-party
# paths-filter action) is worth re-running a 30-second Worker job on a
# dashboard-only PR.
#
# No secrets, no network beyond the registry: `next build` is fully static here
# (every route is dynamic/server-rendered at request time) and `wrangler
# --dry-run` bundles the Worker without touching a Cloudflare account, so this
# workflow runs green on fork PRs.
#
# Run locally: see each app's README, or the same commands used below.

on:
pull_request:
paths:
- 'apps/**'
- '.github/workflows/ci-apps.yml'
push:
branches: [main]
paths:
- 'apps/**'
workflow_dispatch:

permissions:
contents: read

# A force-push mid-review shouldn't leave a stale build burning a runner.
concurrency:
group: ci-apps-${{ github.ref }}
cancel-in-progress: true

jobs:
dashboard:
name: dashboard — typecheck, test, build
runs-on: ubuntu-latest
defaults:
run:
working-directory: apps/dashboard
steps:
- uses: actions/checkout@v7
- uses: actions/setup-node@v7
with:
node-version: '22'
cache: npm
cache-dependency-path: apps/dashboard/package-lock.json
- name: Install deps
run: npm ci
- name: Typecheck (strict)
run: npm run typecheck
- name: Unit tests
run: npm test
# Kept separate from the typecheck on purpose — see the TS7 note above.
- name: Production build
run: npm run build

cli:
name: cli — typecheck
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v7
- uses: actions/setup-node@v7
with:
node-version: '22'
cache: npm
cache-dependency-path: |
apps/cli/package-lock.json
apps/dashboard/package-lock.json
# The CLI deliberately shares one source of truth with the dashboard: its
# tsconfig compiles ../dashboard/lib/**/*.ts and borrows that app's
# typescript + @types (apps/cli/tsconfig.json `typeRoots`). So the CLI
# cannot be typechecked without the dashboard's node_modules — installing
# both here is what makes `npm run typecheck` resolve at all.
- name: Install dashboard deps (CLI borrows its typescript + @types)
run: npm ci
working-directory: apps/dashboard
- name: Install CLI deps
run: npm ci
working-directory: apps/cli
- name: Typecheck (strict, includes the shared dashboard lib)
run: npm run typecheck
working-directory: apps/cli

mcp-server:
name: mcp-server — build
runs-on: ubuntu-latest
defaults:
run:
working-directory: apps/mcp-server
steps:
- uses: actions/checkout@v7
- uses: actions/setup-node@v7
with:
node-version: '22'
# No package-lock.json is committed for this app, so `npm ci` is not
# available and the install floats within the package.json ranges.
- name: Install deps
run: npm install --no-audit --no-fund
# `npm run build` (tsc, emitting to dist/) rather than a bare --noEmit:
# dist/index.js is this package's published `bin`, so a build that cannot
# emit is a broken install for anyone running `aeon-mcp`.
- name: Build
run: npm run build

webhook:
name: webhook — worker bundle
runs-on: ubuntu-latest
defaults:
run:
working-directory: apps/webhook
env:
WRANGLER_SEND_METRICS: 'false'
steps:
- uses: actions/checkout@v7
- uses: actions/setup-node@v7
with:
node-version: '22'
- name: Syntax check the Worker
run: node --check src/worker.js
# No lockfile committed for this app either — see mcp-server above.
- name: Install deps
run: npm install --no-audit --no-fund
# --dry-run validates wrangler.toml and bundles the Worker without any
# Cloudflare credentials, so a broken config or a bad import fails here
# instead of at deploy time.
- name: Bundle (wrangler --dry-run, no credentials needed)
run: npx wrangler deploy --dry-run --outdir "$RUNNER_TEMP/worker-dist"
56 changes: 56 additions & 0 deletions .github/workflows/ci-skill-packs.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
name: ci-skill-packs

# catalog/skill-packs.json is the community pack registry — and the one file in
# this repo that is routinely hand-edited by people outside it. Every listing
# arrives as an outside-contributor PR that must touch TWO surfaces in one diff
# (docs/community-skill-packs.md publishing checklist): a row in the README's
# Community Packs table and a matching registry entry. Nothing checked either.
#
# What shipping a bad edit costs: `bin/install-skill-pack --list` jq's this file
# directly, and the dashboard's community-packs panel fetches it
# (apps/dashboard/lib/packs.ts) — so one trailing comma breaks pack discovery for
# every Aeon fork, not just this repo. A README row with no registry entry is
# invisible to both. A `--path` flag that disagrees with the registry hands
# browsers a copy-paste command that installs the wrong subtree.
#
# The validator also refuses a self-declared `trust_level: trusted` that is not
# in skills/security/trusted-sources.txt: `--list` prints its trust badge from
# the registry but the installer decides the real scan bypass from the trusted
# file, so an unbacked claim advertises "security scan skipped" without earning
# it. That check is why bin/install-skill-pack and trusted-sources.txt are
# trigger paths here — the gate has to re-run when either side moves.
#
# Sibling of ci-packs-json.yml (first-party packs) and ci-skills-json.yml
# (skill catalog); this covers the third, previously ungated, registry.
#
# Run locally: node scripts/validate-skill-packs.mjs

on:
pull_request:
paths:
- 'catalog/skill-packs.json'
- '.github/README.md'
- 'bin/install-skill-pack'
- 'skills/security/trusted-sources.txt'
- 'scripts/validate-skill-packs.mjs'
- '.github/workflows/ci-skill-packs.yml'
push:
branches: [main]
paths:
- 'catalog/skill-packs.json'
- '.github/README.md'
- 'bin/install-skill-pack'
- 'skills/security/trusted-sources.txt'
- 'scripts/validate-skill-packs.mjs'
workflow_dispatch:

permissions:
contents: read

jobs:
check:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v7
- name: Validate the community pack registry and its README parity
run: node scripts/validate-skill-packs.mjs
2 changes: 2 additions & 0 deletions .github/workflows/ci-tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,8 @@ jobs:
run: bash scripts/tests/test_run_actions_summary.sh
- name: skill-pack manifest validation tests
run: bash scripts/tests/test_validate_pack.sh
- name: community pack registry validation tests
run: bash scripts/tests/test_validate_skill_packs.sh
- name: grok harness runner tests
run: bash scripts/tests/test_run_grok.sh
- name: state reducer tests
Expand Down
12 changes: 12 additions & 0 deletions apps/cli/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -95,3 +95,15 @@ Exit code is non-zero on error.
(git), `auth.ts` (auth flow), `packs.ts` (pack join). Ten routes now wrap these.
- `apps/dashboard/lib/gh.ts` honours `AEON_REPO_ROOT` so the shared lib is
location-independent (unset = the dashboard's original cwd-relative behaviour).

## Typecheck

```bash
(cd ../dashboard && npm ci) # the CLI borrows the dashboard's typescript + @types
npm ci && npm run typecheck # strict; compiles src/ plus the shared dashboard lib
```

Because `tsconfig.json` compiles `../dashboard/lib/**/*.ts` and points
`typeRoots` at that app, the CLI has no `typescript` dependency of its own and
cannot be typechecked without the dashboard's `node_modules`. CI does exactly
the two installs above — see `.github/workflows/ci-apps.yml`.
3 changes: 3 additions & 0 deletions apps/cli/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,9 @@
"bin": {
"aeon": "./aeon"
},
"scripts": {
"typecheck": "../dashboard/node_modules/.bin/tsc --noEmit -p tsconfig.json"
},
"dependencies": {
"yaml": "^2.9.0"
},
Expand Down
1 change: 1 addition & 0 deletions apps/dashboard/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
"dev": "next dev",
"build": "next build",
"start": "next start",
"typecheck": "tsc --noEmit",
"test": "node --import tsx --test 'lib/**/*.test.mjs' 'lib/**/*.test.ts'"
},
"dependencies": {
Expand Down
1 change: 1 addition & 0 deletions apps/mcp-server/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
},
"scripts": {
"build": "tsc",
"typecheck": "tsc --noEmit",
"dev": "tsc --watch",
"start": "node dist/index.js"
},
Expand Down
31 changes: 31 additions & 0 deletions docs/community-skill-packs.md
Original file line number Diff line number Diff line change
Expand Up @@ -233,6 +233,37 @@ The operator is always the trust boundary. The install script does not auto-trus

Pack maintainers update both in the same PR so the two surfaces stay in lockstep.

### CI validates both (run it before you open the PR)

`ci-skill-packs` gates every PR that touches the registry or the README:

```bash
node scripts/validate-skill-packs.mjs
```

It fails the PR on registry shape (unparseable JSON, a `repo` that isn't
`owner/repo`, an empty or duplicated `skills[]`, a `trust_level` outside
`trusted|community`, a capability outside the [locked taxonomy](CAPABILITIES.md),
a `secrets_required` entry that isn't an env var name) and on README parity (an
entry with no table row or a row with no entry, a skill count that disagrees with
`skills[]`, a `--path` flag that disagrees with the registry's `path`, and the
`N community skill packs` counter in the README's Proof of work section).

Two things to know:

- **`trust_level: trusted` must be earned.** `--list` prints its trust badge from
this registry, but the installer decides the real scan bypass from
`skills/security/trusted-sources.txt`. A `trusted` entry that isn't in that
file advertises "security scan skipped" without ever getting it, so the gate
rejects it. Community packs use `trust_level: community`.
- **A subdirectory pack needs its `--path` in the README row.** If your registry
entry sets `path`, the table row has to show the matching
(`` `--path <dir>` ``) flag — otherwise the command a reader copies out of the
README installs the wrong subtree.

Missing recommended fields (`name`, `description`, `author`) and unrecognised
fields warn rather than fail.

---

## Listed packs
Expand Down
Loading