ecosystem-entrants
**ecosystem-entrants** surfaces newly added and removed projects from ECOSYSTEM.md as a discrete weekly signal, running Monday mornings 90 seconds after ecosystem-pulse completes. Use this skill to identify new ecosystem entrants as potential co-marketing partners or integration targets before they get lost in the static curated list, especially when contribution velocity is high and new projects arrive faster than manual PR review can catch.
git clone --depth 1 https://github.com/aaronjmars/aeon /tmp/ecosystem-entrants && cp -r /tmp/ecosystem-entrants/skills/ecosystem-entrants ~/.claude/skills/ecosystem-entrantsSKILL.md
> **${var}** — Optional. `dry-run` skips notify (state still updates and article still writes). Empty = normal run.
Today is ${today}. `ECOSYSTEM.md` is the curated list of projects, agents, and products building on top of Aeon. New rows arrive in irregular bursts — two ecosystem PRs landed within 90 seconds of each other on 2026-06-02 (HivemindOS #320, EchoOracle #321). Each new entrant is a potential co-marketing partner, integration target, or community member worth following up with. Currently `ecosystem-pulse` tracks the **liveness** of projects already in `ECOSYSTEM.md`, but nothing surfaces new arrivals as a discrete weekly signal. At the current contribution velocity new projects arrive faster than a human scanning the PR queue would catch.
This skill closes that gap. It is a weekly Monday diff of `ECOSYSTEM.md` against the previous week's snapshot — what was added, what was removed, both reported as a structured digest. Read-only against `ECOSYSTEM.md`; curation stays a human PR decision per the file's own "Add your project" rules.
Read `memory/MEMORY.md` for context.
Read the last 8 days of `memory/logs/` for prior-run context.
Read `soul/SOUL.md` + `soul/STYLE.md` if populated to match voice in the notification and article.
## Why a separate skill from ecosystem-pulse
| Skill | Question answered | Cadence | Slot |
|-------|-------------------|---------|------|
| `ecosystem-pulse` | "Are listed projects shipping this week?" | Weekly (Mon 11:00 UTC) | Liveness of *existing* entries |
| **`ecosystem-entrants`** | **"What was added to ECOSYSTEM.md this week?"** | **Weekly (Mon 11:45 UTC)** | **First-touch of *new* entries** |
The two skills compose. `ecosystem-pulse` reports star/fork/last-push deltas for every entry that can be matched to a GitHub repo; `ecosystem-entrants` reports the appearance and disappearance of rows. A row that was added and immediately matched a stale repo will appear in both digests on the same Monday — that's expected and not a duplication problem (the two skills answer different questions and one mention per skill is the operator-facing artefact).
Building this layer into `ecosystem-pulse` would have entangled the diff/liveness boundaries: the entrants signal is binary (added / removed / unchanged) and unconditional on whether the project matches a GitHub repo; the liveness signal is gradated and conditional on a repo match. Keeping them separate keeps each skill structurally simple.
## Inputs
| Source | Purpose | Auth |
|--------|---------|------|
| `ECOSYSTEM.md` (repo root) | Current project list — parsed from the markdown table at the top of the file | Local file |
| `memory/topics/ecosystem-entrants-state.json` | Prior-week snapshot of the project list, keyed by canonical URL | Local file |
| `git log` (local) | Optional: when an entrant is detected, walk `ECOSYSTEM.md` history to surface the PR / merge SHA that added it | Local git |
| `gh api search/issues?q=...` | Best-effort match of "added row" to a merged PR for the notification's "added by" link | `GH_TOKEN` |
No new secrets. GitHub access uses the `gh` CLI (`GH_TOKEN`), which handles auth internally — see Sandbox note.
Writes:
- `memory/topics/ecosystem-entrants-state.json` — current parsed entries (keyed by URL) + last_run timestamp + last_status
- `articles/ecosystem-entrants-${today}.md` — digest on every non-error run (including QUIET; the article is the durable record even when the notification is suppressed)
- `memory/logs/${today}.md` — one log block per run
- Notification via `./notify` — only when ≥1 added or removed entry since the last run (see step 6)
## Row schema
`ECOSYSTEM.md` rows have a stable shape — pipe-delimited markdown with logo, name, and links columns. The skill parses each row into:
```json
{
"name": "string",
"logo_url": "https://...",
"links": [{"label": "@handle", "url": "https://x.com/handle"}, ...],
"primary_url": "https://x.com/handle",
"raw_row": "| <img ...> | Name | [@handle](https://x.com/handle) |"
}
```
`primary_url` is the **canonical key** for an entry. Resolution order:
1. First `https://github.com/{owner}/{repo}` URL in the links column.
2. Otherwise, first `https://x.com/{handle}` URL.
3. Otherwise, first non-empty URL in the row.
4. Otherwise, the lowercased project name (last-resort fallback for rows with no link at all — these are surfaced as `(no canonical URL)` in the article so the operator can fix the row).
Resolution is **deterministic and order-stable** so a row that swaps which link appears first still maps to the same entry. A row whose primary_url changes between runs (e.g. an X-only project that added a GitHub repo) is reported as an `updated` entry, not an add+remove pair (which would noisily fire two notifications for one operator action).
## State schema
`memory/topics/ecosystem-entrants-state.json`:
```json
{
"last_run": "2026-06-03",
"last_status": "OK",
"entries": {
"https://x.com/aeonbook_": {
"name": "aeonbook",
"primary_url": "https://x.com/aeonbook_",
"links": [{"label": "@aeonbook_", "url": "https://x.com/aeonbook_"}],
"logo_url": "https://...",
"first_seen": "2026-04-20",
"last_seen": "2026-06-03"
}
}
}
```
`first_seen` is the date this entry first appeared in any run — never overwritten. `last_seen` is the most recent run where the entry was present — overwritten every run that sees it. An entry whose `last_seen` is more than 28 days old is **pruned** from the state file (so a project that was added, removed, and then re-added much later is treated as a fresh entrant, not a "restored" one — the operator's question on re-add is "what is this project?" not "did it come back?"). Pruning is silent (no notify).
## Steps
### 0. Bootstrap
```bash
mkdir -p memory/topics articles
[ -f memory/topics/ecosystem-entrants-state.json ] || cat > memory/topics/ecosystem-entrants-state.json <<'EOF'
{"last_run":null,"last_status":null,"entries":{}}
EOF
```Mention/keyword sweep on social platforms for [REPLACE: KEYWORDS] — trends, sentiment, top posts
5 concrete real-life actions, leverage-scored against open loops with specificity and anti-fluff gates
Curated AI-agent tweets, clustered into narratives with insight summaries
Tracker of AI agent substitution signals — which roles, companies, and industries show real headcount displacement. Named roles + real deployments only.
Competitive-intelligence digest on the AI agent framework space — momentum, releases, breaking changes across a curated watchlist
Cross-domain market pulse from AIXBT's free grounding endpoint — crypto, macro, tradfi, geopolitics. Refreshes taxonomy references (clusters, chains) as a bonus.
Pre-batch API provider health check — detects credit exhaustion or auth failure for every configured provider key before the scheduled batch runs, giving the operator a window to act before skills degrade
List a wallet's live ERC-20 token approvals on Base and flag unlimited / risky spender grants. Keyless via Base RPC (eth_getLogs + eth_call) — no explorer key needed.