# Overview

> What the Skill exposes, primary slash-command vs engine paths, zero-config sources, and the shortest successful research path.

- Repository: mvanhorn/last30days-skill
- GitHub: https://github.com/mvanhorn/last30days-skill
- Human docs: https://grok-wiki.com/public/docs/mvanhorn-last30days-skill-50b5421a8cca
- Complete Markdown: https://grok-wiki.com/public/docs/mvanhorn-last30days-skill-50b5421a8cca/llms-full.txt

## Source Files

- `README.md`
- `CONCEPTS.md`
- `skills/last30days/SKILL.md`
- `skills/last30days/scripts/last30days.py`
- `AGENTS.md`
- `pyproject.toml`

---

---
title: "Overview"
description: "What the Skill exposes, primary slash-command vs engine paths, zero-config sources, and the shortest successful research path."
---

`/last30days` is an [Agent Skills](https://agentskills.io) package (`skills/last30days/`) whose runtime contract lives in `SKILL.md` (v3.3.1) and whose Python engine is `scripts/last30days.py`. The product surface is a harness-invoked slash command; the engine aggregates Reddit, Hacker News, Polymarket, GitHub, YouTube, optional social sources, and grounded web retrieval into ranked evidence the hosting model synthesizes under a fixed output contract (badge, LAWs voice rules, pass-through footer).

## Skill, engine, and harness

Three boundaries define every run:

| Layer | Artifact | Role |
|-------|----------|------|
| **Skill** | `skills/last30days/SKILL.md` + sibling `scripts/` | Tells the hosting model how to parse intent, run pre-flight (handles, subreddits, plans), invoke the engine, and format the user-facing brief |
| **Engine** | `skills/last30days/scripts/last30days.py` → `lib/pipeline.py` | Plans sub-queries, fans out parallel source retrieval, clusters/dedupes/reranks, emits `--emit` payloads |
| **Harness** | Claude Code, Codex, Cursor, Gemini CLI, Copilot, Hermes, OpenClaw, 50+ Agent Skills hosts | Loads the skill, exposes `/last30days`, and (on reasoning-model paths) acts as planner and synthesizer |

```mermaid
flowchart TB
  subgraph harness["Harness (agent runtime)"]
    SC["/last30days topic"]
    WS["WebSearch supplement"]
  end
  subgraph skill["Skill package skills/last30days/"]
    SM["SKILL.md contract"]
  end
  subgraph engine["Engine scripts/last30days.py"]
    PL["lib/pipeline.run"]
    REN["lib/render compact/md/html"]
  end
  subgraph sources["Retrieval modules lib/*"]
    RD["reddit_keyless"]
    HN["hackernews"]
    PM["polymarket"]
    GH["github"]
    YT["youtube_yt"]
    MORE["x, tiktok, grounding, …"]
  end
  SC --> SM
  SM -->|"Bash: SKILL_DIR/scripts/last30days.py"| PL
  PL --> RD & HN & PM & GH & YT & MORE
  PL --> REN
  REN -->|"stdout --emit=compact"| SM
  SM --> WS
  SM -->|"synthesis + footer pass-through"| OUT["User brief"]
```

<Note>
On a reasoning-model path, the harness model **is** the planner: named-entity topics require `--plan` written to a tmpfile (LAW 7). The engine’s internal LLM planner is for headless/cron runs without a hosting model.
</Note>

## What the skill exposes

| Surface | Entry | Typical use |
|---------|-------|-------------|
| **Slash command** | `/last30days <topic>` | Primary UX in Claude Code (`/plugin install last30days`) and Agent Skills hosts (`npx skills add mvanhorn/last30days-skill -g`) |
| **Direct CLI** | `python3 <SKILL_DIR>/scripts/last30days.py "<topic>"` | Scripting, cron, engine testing, `--diagnose`, HTML export with `--emit=html` |
| **Setup** | First run via SKILL.md Step 0 → `nux-wizard.md`, or `last30days.py setup` | Writes `~/.config/last30days/.env` with `SETUP_COMPLETE=true` |
| **Trend stack** (optional) | `--store`, `watchlist.py`, `briefing.py` | SQLite persistence and scheduled digests |

The skill frontmatter declares `user-invocable: true`, optional env keys (`SCRAPECREATORS_API_KEY`, `OPENROUTER_API_KEY`, X cookies, Bluesky app password, etc.), and required bins `node` + `python3` (Python **3.12+** enforced at engine startup).

### Slash command vs direct CLI

| Constraint | Slash command | Direct CLI |
|------------|---------------|------------|
| Shell flags/pipes | Invalid — harness does not pass `|`, `>`, or arbitrary flags through | Full `argparse` surface (`--emit`, `--plan`, `--competitors`, …) |
| Who plans | Hosting model generates `--plan` JSON for named entities | Optional `--plan` file; otherwise engine `providers.resolve_runtime` |
| Who synthesizes | Model follows SKILL.md LAWs on engine stdout | `--emit=compact` still targets model synthesis in skill flows; `html`/`json` can be consumed headlessly |
| Engine path | `SKILL_DIR` = directory of the `SKILL.md` the harness loaded | Caller supplies path (repo: `skills/last30days/scripts/last30days.py`) |

<Warning>
Treating `/last30days` as a generic “research the last 30 days” prompt and answering from WebSearch alone violates the skill contract: valid output always includes an engine run and the `✅ All agents reported back!` footer block.
</Warning>

## Zero-config and baseline sources

With no `.env` file, the engine still activates keyless or CLI-backed sources. `lib/pipeline.available_sources` always includes **Reddit** (public/keyless pipeline), **Hacker News**, and **Polymarket**. Additional sources join when tools or keys are present:

| Source | Activation without API keys in `.env` |
|--------|----------------------------------------|
| Reddit | Always (`reddit` — no `SCRAPECREATORS` required) |
| Hacker News | Always |
| Polymarket | Always |
| GitHub | `gh` on `PATH` (uses GitHub CLI auth) |
| YouTube | `yt-dlp` on `PATH` |
| Digg | `digg-pp-cli` on `PATH` |
| X / Twitter | `AUTH_TOKEN`+`CT0`, `XAI_API_KEY`, `SCRAPECREATORS_API_KEY`, `FROM_BROWSER`, or authenticated Bird/xurl |
| TikTok, Instagram, Threads | `SCRAPECREATORS_API_KEY` (+ `INCLUDE_SOURCES` where applicable) |
| Bluesky | `BSKY_HANDLE` + `BSKY_APP_PASSWORD` |
| Web grounding | `BRAVE_API_KEY`, `EXA_API_KEY`, `SERPER_API_KEY`, or `PARALLEL_API_KEY` |
| Perplexity | `OPENROUTER_API_KEY` and `INCLUDE_SOURCES` containing `perplexity` |

README’s “zero config” line matches this: Reddit, HN, Polymarket, and GitHub (with `gh`) work on first install; the first-run wizard optionally unlocks X, YouTube enrichment, TikTok, and ScrapeCreators-backed sources in one pass.

### Active source announcement

Before research, SKILL.md instructs the model to build `ACTIVE_SOURCES_LIST` from live checks (`which gh`, `which yt-dlp`, env keys, `EXCLUDE_SOURCES`) and emit a single branded line, for example:

```
/last30days - searching Reddit, Hacker News, Polymarket, and GitHub for what people are saying about {TOPIC}.
```

Only configured sources are named — the skill must not promise platforms that `--diagnose` would omit.

## Shortest successful research path

<Steps>
<Step title="Install the skill package">

<Tabs>
<Tab title="Claude Code (marketplace)">

```text
/plugin marketplace add mvanhorn/last30days-skill
/plugin install last30days
```

</Tab>
<Tab title="Agent Skills hosts">

```bash
npx skills add mvanhorn/last30days-skill -g
```

</Tab>
</Tabs>

</Step>

<Step title="Invoke with a concrete topic">

```text
/last30days OpenClaw
```

If `~/.config/last30days/.env` is missing, Step 0 runs `nux-wizard.md` once, then continues.

</Step>

<Step title="Let the contract run (automatic in skill mode)">

The hosting model should: load WebSearch (`ToolSearch select:WebSearch`), parse `QUERY_TYPE`, run Step 0.45 pre-flight, resolve handles/subreddits (Step 0.5 / 0.55), write `--plan` for named entities, and execute:

```bash
"${SKILL_DIR}/scripts/last30days.py" "<topic>" --emit=compact --plan "$QUERY_PLAN_FILE" ...
```

Stdout supplies badge + evidence blocks + footer; the model synthesizes `What I learned:` prose and passes the footer through verbatim.

</Step>

<Step title="Verify configuration (optional)">

```bash
python3 skills/last30days/scripts/last30days.py --diagnose
```

Prints JSON: `providers`, `available_sources`, `x_backend`, `native_web_backend`, `has_scrapecreators`, etc., without running a full search.

</Step>
</Steps>

### Saved artifacts

Default raw dumps land under `LAST30DAYS_MEMORY_DIR` (default `~/Documents/Last30Days/`) as `<slug>-raw.md`. The engine footer points to the saved path; HTML briefs use `--emit=html` or skill-driven save flow under the same directory.

### Query types (intent routing)

SKILL.md classifies input before retrieval shape and synthesis template:

| QUERY_TYPE | Trigger examples | Synthesis shape |
|------------|------------------|-----------------|
| GENERAL | Default topic research | Badge → `What I learned:` → KEY PATTERNS |
| NEWS | “latest on X”, “X news” | Same as GENERAL |
| RECOMMENDATIONS | “best X”, “top X” | Signal-weighted picks |
| PROMPTING | “X prompts”, “prompting for X” | Techniques + copy-paste prompts |
| COMPARISON | “X vs Y”, `--competitors` | Required `##` comparison sections + Head-to-Head table |

Depth profiles on the engine: `--quick`, default, `--deep` (maps to `DEPTH_SETTINGS` in `lib/pipeline.py`).

## Repository layout (skill product)

:::files
last30days-skill/
├── skills/last30days/
│   ├── SKILL.md          # Runtime authority for slash-command runs
│   ├── nux-wizard.md     # First-run setup (Step 0)
│   └── scripts/
│       ├── last30days.py # CLI entry
│       ├── lib/          # pipeline, sources, render, env
│       ├── watchlist.py
│       └── briefing.py
├── CONFIGURATION.md      # User-facing knobs (env, flags, paths)
├── CONCEPTS.md           # Skill / Engine / Harness vocabulary
└── pyproject.toml        # Python 3.12+, pytest suite
:::

<Info>
`AGENTS.md` states the distribution unit is the Agent Skills package, not a standalone CLI product. Engine flags without matching `SKILL.md` integration are considered incomplete for multi-harness behavior.
</Info>

## Engine output modes

<ParamField body="--emit" type="string" default="compact">
Choices: `compact`, `md`, `json`, `context`, `html`. Skill runs normally use `compact` for model synthesis; `html` produces shareable offline briefs; `json` exposes the structured `schema.Report`.
</ParamField>

<ParamField body="topic" type="string" required>
Positional words joined into the research topic. Empty topic with no `--diagnose` prints usage and exits 2.
</ParamField>

The compact emitter places ranked evidence inside `<!-- EVIDENCE FOR SYNTHESIS -->` comments; LAW 6 forbids dumping those clusters verbatim to the user.

## Related pages

<CardGroup>
<Card title="Installation" href="/installation">
Claude Code marketplace, `npx skills add`, Hermes, live-edit symlinks, and version sync.
</Card>
<Card title="Quickstart" href="/quickstart">
First invocation, setup wizard signals, saved output location, and `--diagnose`.
</Card>
<Card title="Skill, engine, and harness" href="/skill-engine-harness">
Boundaries between SKILL.md, `last30days.py`, and multi-harness runtimes.
</Card>
<Card title="Research pipeline" href="/research-pipeline">
v3 planner fan-out, fusion, clustering, dedupe, rerank, depth profiles.
</Card>
<Card title="Output contract" href="/output-contract">
Badge, LAWs, `--emit` modes, evidence blocks, footer pass-through.
</Card>
<Card title="Configure sources" href="/configure-sources">
`.env` layers, API keys, `INCLUDE_SOURCES`, setup wizard actions.
</Card>
</CardGroup>
