n-seo 0.1.1 → 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (61) hide show
  1. package/.claude/skills/n-seo-add-site/SKILL.md +125 -0
  2. package/.claude/skills/n-seo-deploy/SKILL.md +171 -0
  3. package/.claude/skills/n-seo-review/SKILL.md +106 -0
  4. package/.claude/skills/n-seo-setup/SKILL.md +139 -0
  5. package/.claude/skills/n-seo-ship/SKILL.md +122 -0
  6. package/.claude/skills/n-seo-triage/SKILL.md +90 -0
  7. package/.claude/skills/orient/SKILL.md +54 -0
  8. package/README.md +190 -49
  9. package/bin/n-seo.mjs +177 -10
  10. package/docs/ADDING-A-SITE.md +4 -0
  11. package/docs/DEPLOY.md +4 -0
  12. package/docs/FAQ.md +46 -6
  13. package/docs/INSTANCE.md +54 -0
  14. package/docs/MCP.md +25 -9
  15. package/docs/PRD.md +29 -9
  16. package/docs/SCHEDULING.md +46 -5
  17. package/docs/SETUP-GOOGLE.md +8 -1
  18. package/ingest/__pycache__/analyze_metadata.cpython-312.pyc +0 -0
  19. package/ingest/__pycache__/google_auth.cpython-312.pyc +0 -0
  20. package/ingest/__pycache__/http_util.cpython-312.pyc +0 -0
  21. package/ingest/__pycache__/seo_config.cpython-312.pyc +0 -0
  22. package/ingest/analyze_ga4.py +2 -2
  23. package/ingest/analyze_gsc.py +2 -2
  24. package/ingest/analyze_metadata.py +2 -2
  25. package/ingest/analyze_trends.py +2 -2
  26. package/ingest/google_auth.py +53 -20
  27. package/ingest/pull_ga4.py +1 -1
  28. package/ingest/pull_gsc.py +1 -1
  29. package/ingest/pull_index_status.py +1 -1
  30. package/ingest/pull_timeseries.py +3 -3
  31. package/ingest/seo_config.py +19 -3
  32. package/ops/__pycache__/daily.cpython-312.pyc +0 -0
  33. package/ops/__pycache__/daily_diff.cpython-312.pyc +0 -0
  34. package/ops/__pycache__/demo_data.cpython-312.pyc +0 -0
  35. package/ops/__pycache__/export_static.cpython-312.pyc +0 -0
  36. package/ops/__pycache__/llm.cpython-312.pyc +0 -0
  37. package/ops/__pycache__/publish.cpython-312.pyc +0 -0
  38. package/ops/daily.py +2 -2
  39. package/ops/daily_diff.py +9 -8
  40. package/ops/demo_data.py +23 -17
  41. package/ops/doctor.py +30 -7
  42. package/ops/export_static.py +10 -5
  43. package/ops/hn_digest.py +1 -1
  44. package/ops/indexnow.py +3 -3
  45. package/ops/llm.py +23 -1
  46. package/ops/opportunity_scan.py +4 -4
  47. package/ops/py.mjs +40 -0
  48. package/ops/reddit_digest.py +1 -1
  49. package/ops/templates/n-seo-daily-task.xml +65 -0
  50. package/package.json +24 -9
  51. package/probes/__pycache__/site_probe.cpython-312.pyc +0 -0
  52. package/probes/site_probe.py +1 -1
  53. package/public/fonts/OFL.txt +105 -0
  54. package/public/fonts/montserrat-latin-var.woff2 +0 -0
  55. package/public/styles.css +18 -1
  56. package/src/actions.ts +1 -1
  57. package/src/config.ts +1 -1
  58. package/src/mcp.ts +2 -2
  59. package/src/server.tsx +22 -1
  60. package/src/settings.tsx +3 -3
  61. package/src/views.tsx +79 -15
@@ -0,0 +1,90 @@
1
+ ---
2
+ name: n-seo-triage
3
+ description: Answer "what should I work on today" from an n-seo instance — the ranked queue, the last run, and the scan proposals, with the evidence and the operating rules applied. Use for any status or what-next question.
4
+ ---
5
+
6
+ # Triage — what to do today
7
+
8
+ Read the system's outputs. **Do not re-run pulls, re-crawl sites, or
9
+ recompute trends to answer a status question** — the daily run already
10
+ produced all of it, and a re-run spends quota to reproduce a file that exists.
11
+
12
+ ```sh
13
+ E=<engine checkout>/bin/n-seo.mjs
14
+ I=<instance dir>
15
+ PORT=$(python3 -c "import json;print(json.load(open('$I/n-seo.config.json'))['port'])" 2>/dev/null || echo 4600)
16
+ ```
17
+
18
+ ## 1. Trust the data before you use it
19
+
20
+ ```sh
21
+ cat "$I/data/last-run.json" # ts, failures, per-step timing
22
+ ```
23
+
24
+ Or the MCP `ops_status` tool, which adds dataset staleness and probe results.
25
+ If `failures` is non-empty, **say so first** — the numbers below are stale in
26
+ whatever the failing step feeds. `data/daily-ops.log` has the reason.
27
+
28
+ ## 2. Read the queue
29
+
30
+ ```sh
31
+ curl -s "http://localhost:$PORT/api/actions"
32
+ ```
33
+
34
+ Or MCP `list_actions` (`status: active`, optional `host`, `tag`, `limit`),
35
+ which returns the same ranked list. If the dashboard is not running, start it
36
+ (`node $E start --instance "$I"`) or read `config/backlog.json` plus the
37
+ rule-derived cards from the MCP server.
38
+
39
+ Each action carries `impact`, `effort`, `why` (the evidence), `how`, `spec`,
40
+ `tag`, and `watching` when it has shipped. Ranking is impact ÷ effort weight.
41
+
42
+ ## 3. Read what happened lately
43
+
44
+ ```sh
45
+ tail -30 "$I/docs/daily-log.md" # or MCP daily_log
46
+ cat "$I/data/opportunity-proposals.json" # or MCP opportunity_proposals
47
+ ```
48
+
49
+ The log gives probe health, the watched pages' numbers, the conversions line
50
+ and cross-referrals. The proposals file gives rising queries no card covers,
51
+ machine proposals awaiting accept, and verdicts on watching items.
52
+
53
+ ## 4. Apply the rules before recommending
54
+
55
+ - **28-day freeze.** A page whose title or description changed inside 28 days
56
+ is off limits for another metadata change. Check `shippedWatch` in
57
+ `config/backlog.json` and the dated `watching` notes for the page.
58
+ - **≈8 metadata changes a week across all sites.** Count what has already
59
+ shipped this week from the recent `watching` notes before proposing more.
60
+ If the audit lists twenty, recommend the top few, not the list.
61
+ - **Impact orders, it does not forecast.** Never present an impact number as
62
+ an expected result. "Ranked highest" not "will earn 60 clicks."
63
+ - **Decisions ride the 90 days.** Cite the 90-day figures the cards use, not
64
+ 16-month totals.
65
+ - **Proposals are not queue items** until accepted.
66
+
67
+ ## 5. Answer
68
+
69
+ Short, ranked, evidence attached. For each recommendation:
70
+
71
+ - the move, in one line;
72
+ - the numbers behind it, from the card's `why`;
73
+ - why now (freeze expired, riser, regression, seasonal window);
74
+ - what it costs (`effort`).
75
+
76
+ Then, separately and briefly:
77
+
78
+ - **Blocked or broken** — failing steps, probe regressions, index problems.
79
+ - **Waiting on the owner** — scan proposals to accept or ignore, drafts whose
80
+ status contains `approval`.
81
+ - **Watching** — shipped work whose window is closing, and what the data says
82
+ so far. Verdicts of *succeeded* or *failed* are review triggers; hand them
83
+ to `/n-seo-review` rather than acting on them here.
84
+
85
+ ## Stay inside the lines
86
+
87
+ - Do not write to `config/backlog.json` here. Triage reads.
88
+ - Do not draft comments for Hacker News or Reddit. The digests brief; the
89
+ human writes. Point at the briefing and stop.
90
+ - Do not enable modules or change settings as part of answering.
@@ -0,0 +1,54 @@
1
+ ---
2
+ name: orient
3
+ description: Fast, cheap orientation for a fresh session on this n-seo install. Use FIRST in any new session here — reads current state from the running system instead of re-deriving it from raw data.
4
+ ---
5
+
6
+ # Orient — get current in ~4 reads, not 40
7
+
8
+ The system is self-updating; your job is to read its outputs, never to rebuild
9
+ its conclusions. Procedure, in order — stop when you have what the task needs:
10
+
11
+ 1. **The queue is the truth for "what's next"**:
12
+ `curl -s http://localhost:4600/api/actions` (the port is `port` in
13
+ `n-seo.config.json`; the MCP `list_actions` tool returns the same).
14
+ Every active and watching action with evidence and spec.
15
+ 2. **What happened lately**: the last entry of `docs/daily-log.md` (probe
16
+ health, watched-page numbers, conversions line) and `data/last-run.json`
17
+ (did the last daily run succeed, which steps failed).
18
+ 3. **Machine-proposed work awaiting the owner**:
19
+ `data/opportunity-proposals.json` — proposals and verdicts from the scan.
20
+ 4. **Recent human decisions**: `git log --oneline -10` in this repo.
21
+
22
+ ## Do NOT (wastes tokens, re-derives what the batch already did)
23
+
24
+ - Do not re-run pulls, audits, or trend analysis to answer status questions —
25
+ `ops/daily.py` refreshes everything on its schedule; its outputs are in
26
+ `data/` and `docs/daily-log.md`.
27
+ - Do not re-audit sites or re-crawl pages the probe already covers.
28
+ - Do not summarize the architecture from source — `docs/ARCHITECTURE.md` has it.
29
+ - Do not restate history — `docs/daily-log.md` and `git log` hold it.
30
+
31
+ ## Rules live in CLAUDE.md — the ones people forget
32
+
33
+ Queue edits only through accept/watch/retire or explicit approval · never
34
+ generate comment text · 28-day title freeze + ≤8 metadata changes/week ·
35
+ decisions ride the 90-day window · proposals never self-promote.
36
+
37
+ ## Then hand off to the right skill
38
+
39
+ `n-seo-triage` for "what should I do today", `n-seo-ship` to implement one
40
+ card, `n-seo-review` for the weekly pass, `n-seo-setup` and `n-seo-add-site`
41
+ for configuration. `.claude/skills/README.md` says which skills are for
42
+ operating an instance and which are for developing the engine.
43
+
44
+ ## If something is broken
45
+
46
+ - Dashboard down: `npm start` in-place, or
47
+ `node <engine>/bin/n-seo.mjs start --instance <dir>` in engine+instance
48
+ mode, or if it runs as a service,
49
+ `launchctl kickstart -k gui/$(id -u)/n-seo.dashboard`.
50
+ - Daily run failing: the Logs page (`/logs`) or `data/daily-ops.log`, then
51
+ `python3 ops/doctor.py`. 401/403 from Google means the service account
52
+ lost access or the key file moved — see `docs/SETUP-GOOGLE.md`.
53
+ - Nothing on the dashboard: no run has happened yet — `python3 ops/daily.py`
54
+ (or `python3 ops/demo_data.py` to see it populated with synthetic data).
package/README.md CHANGED
@@ -1,4 +1,4 @@
1
- # n-seo
1
+ # n-seo — En Dash SEO
2
2
 
3
3
  **An SEO, self-hosted.** Website: https://n-seo.dev/ · From the makers of [n-dx](https://n-dx.dev).
4
4
 
@@ -6,33 +6,92 @@
6
6
  [![CI](https://github.com/en-dash-consulting/n-seo/actions/workflows/ci.yml/badge.svg)](https://github.com/en-dash-consulting/n-seo/actions/workflows/ci.yml)
7
7
  [![license](https://img.shields.io/npm/l/n-seo)](LICENSE)
8
8
 
9
- A local-first control plane for growing organic traffic to your own sites —
10
- classic search (SEO), answer engines (AEO) and AI assistants that cite sources
11
- (GEO) — without paying an agency to read Search Console for you.
9
+ An agentic, local-first control plane for growing organic traffic to your own
10
+ sites — classic search (SEO), answer engines (AEO) and AI assistants that cite
11
+ sources (GEO) — without paying an agency to read Search Console for you.
12
12
 
13
13
  It pulls Search Console and GA4 into local JSON, probes your live sites for the
14
14
  things that quietly break (robots, sitemap, soft 404s, blocked AI crawlers,
15
15
  JS-only shells), and turns all of it into a **ranked queue of concrete actions**:
16
16
  which page to retitle, which query to answer, which page never got crawled.
17
- It runs on hardware you control, on a schedule, and shows you the result on a dashboard.
18
-
19
- - **Your data stays on your own hardware.** Nothing is sent anywhere except the
20
- Google APIs you authorize and, optionally, a local LLM command you choose.
21
- - **It briefs you; it never posts for you.** Community modules find threads
22
- and write a briefing. The words are always yours.
23
- - **It proposes; you ship.** No module edits your site. The queue tells you
24
- what to change and why, with the numbers; you make the change in your own
25
- repo and the next day's data tells you whether it worked.
17
+ That part is plain deterministic code. Everything that needs judgment is handed
18
+ to **a model you choose**, and everything that changes a site is handed to you.
19
+
20
+ - **Your model, whichever you pick.** Point the `llm` module at any CLI that
21
+ reads a prompt on stdin (`claude -p`, `ollama run`, a shell script) or at an
22
+ HTTP endpoint — Anthropic, or anything OpenAI-compatible. It writes the
23
+ proposals, the verdicts on shipped work, and the community briefings. No key
24
+ ships with n-seo. Leave it off and you still get the full data-derived queue.
25
+ - **Your coding agent, on the queue.** A read-only MCP server exposes the same
26
+ data the dashboard reads, so Claude Code — or any MCP client — can answer
27
+ "what should I do first this week?" and then go implement it. Seven skills
28
+ are installed into your instance, so setup, triage and shipping are things
29
+ you ask for in plain language, with the operating rules enforced rather than
30
+ merely documented.
31
+ - **It proposes; it never acts.** No module edits a site, sends an email or
32
+ posts a comment. Machine proposals wait in a holding area until you accept
33
+ them. Your data stays on your hardware: nothing leaves the host except the
34
+ Google APIs you authorize and the provider you configured yourself.
26
35
 
27
36
  ![Overview](docs/screenshots/overview.png)
28
37
 
29
38
  ## Quickstart (5 minutes, no Google setup)
30
39
 
40
+ > **n-seo is its own project — do not install it inside a website's repo.**
41
+ > It reads your sites the way Google sees them, through the Search Console and
42
+ > GA4 APIs, so it never needs a copy of their code. `n-seo init` makes one
43
+ > directory of its own and everything it writes stays there.
44
+
45
+ **✗ Inside a site's repo** — what people do by accident:
46
+
47
+ ```
48
+ ~/code/my-website/
49
+ ├── .git/
50
+ ├── package.json
51
+ ├── src/
52
+ └── my-sites/ ← init ran here
53
+ ├── n-seo.config.json committed to your website
54
+ ├── config/backlog.json committed
55
+ ├── .env committed
56
+ └── data/ rewritten every morning,
57
+ committed, then deployed
58
+ ```
59
+
60
+ **✓ Beside it** — one instance, watching every site you own:
61
+
62
+ ```
63
+ ~/
64
+ ├── code/
65
+ │ ├── my-website/ untouched
66
+ │ └── docs-site/ untouched
67
+ └── my-sites/ ← n-seo init my-sites
68
+ ├── n-seo.config.json lists both sites
69
+ ├── config/backlog.json your action queue
70
+ ├── content/ drafts, campaigns
71
+ ├── .claude/skills/ ask, don't read docs
72
+ └── data/ gitignored, regenerable
73
+ ```
74
+
75
+ `n-seo init` refuses the first layout: it stops when the target holds a
76
+ `package.json`, or when the directory it would create falls inside a git
77
+ repository that is not itself an instance, and prints the command you wanted
78
+ instead. `--force` overrides it.
79
+
80
+ **What it touches.** Your site repos: never — when you ship a fix it is you,
81
+ in your repo, on a branch. Google's APIs: read-only, through a service account
82
+ you create. Its own directory: everything it writes. Delete that directory and
83
+ nothing else on your machine changes.
84
+
31
85
  ```sh
32
- npm install -g n-seo
33
- n-seo init my-sites && cd my-sites
34
- n-seo demo # a synthetic dataset for example.com
35
- n-seo start # dashboard → http://localhost:4600
86
+ npm install -g n-seo # the engine, once — a CLI, not a dependency
87
+
88
+ cd ~ # stand somewhere that is NOT a site repo
89
+ n-seo init my-sites # creates ./my-sites: config, queue, content,
90
+ cd my-sites # .mcp.json and seven skills
91
+
92
+ n-seo demo # synthetic data, so every page has something
93
+ n-seo start # the dashboard, reading this directory
94
+ # → http://localhost:4600
36
95
  ```
37
96
 
38
97
  Open http://localhost:4600. Every page is populated from the demo data, so you
@@ -41,6 +100,29 @@ removes it.
41
100
 
42
101
  Prefer not to install globally? `npx n-seo init my-sites` works the same way.
43
102
 
103
+ ### Then talk to it
104
+
105
+ `n-seo init` installs seven skills into the new directory, so the rest of the
106
+ setup is a conversation rather than a docs crawl. Open it in Claude Code — or
107
+ any agent that reads `.claude/skills/` — and say what you want:
108
+
109
+ ```
110
+ cd my-sites && claude
111
+
112
+ "set this up for my sites" → /n-seo-setup: config, the Google service
113
+ account, both console grants, first run
114
+ "add learn-pretext.com" → /n-seo-add-site
115
+ "what should I work on today?" → /n-seo-triage: the queue, with evidence
116
+ "do the first one" → /n-seo-ship: a branch and a PR in the
117
+ site's own repo, freeze rules enforced
118
+ "how did last month go?" → /n-seo-review
119
+ ```
120
+
121
+ A read-only MCP server is registered in the generated `.mcp.json`, so the agent
122
+ reads the same queue and metrics the dashboard shows. It can propose and
123
+ implement; it cannot publish, post, or change a site behind your back. Details
124
+ in [Agentic by design](#agentic-by-design).
125
+
44
126
  <details>
45
127
  <summary>Or run it from a clone, if you want to change the engine itself</summary>
46
128
 
@@ -52,10 +134,11 @@ npm run demo
52
134
  npm start
53
135
  ```
54
136
 
55
- In this mode the config, queue and data live inside the checkout. That is the
56
- right shape for hacking on n-seo; for running it, the instance layout above
57
- keeps your files separate from the engine so upgrades are a reinstall rather
58
- than a merge. See [docs/INSTANCE.md](docs/INSTANCE.md).
137
+ In this mode the config, queue and data live inside the checkout — still a
138
+ standalone project of its own, just one you can edit. That is the right shape
139
+ for hacking on n-seo; for running it, the instance layout above keeps your
140
+ files separate from the engine so upgrades are a reinstall rather than a
141
+ merge. See [docs/INSTANCE.md](docs/INSTANCE.md).
59
142
  </details>
60
143
 
61
144
  ## Connect your real sites
@@ -84,6 +167,87 @@ Adding another site later is one entry in the config —
84
167
  Running several people's sites, or want upgrades to be a `git pull`? Keep your
85
168
  config in its own directory — see [docs/INSTANCE.md](docs/INSTANCE.md).
86
169
 
170
+ ## Agentic by design
171
+
172
+ Two things are agentic here, and they are separate. Inside n-seo, the daily run
173
+ hands its findings to a model you configure. Alongside n-seo, your own coding
174
+ agent reads the queue over MCP and does the work.
175
+
176
+ ### Your model, on your findings
177
+
178
+ The `llm` module is off by default. Turn it on and point it at a provider, and
179
+ the morning run stops being a report:
180
+
181
+ - **Proposals** — rising queries nothing in the queue covers become concrete
182
+ cards: the page to write, the section to add, with the numbers cited.
183
+ - **Verdicts** — shipped work is judged against its own success criterion:
184
+ succeeded, failed, or still cooking.
185
+ - **Briefings** — for each community thread worth joining, the gist, the
186
+ debate, and where your genuine experience connects.
187
+
188
+ Reach it two ways, in `n-seo.config.json`:
189
+
190
+ ```jsonc
191
+ // a CLI — anything that reads a prompt on stdin and prints a reply
192
+ "llm": {
193
+ "enabled": true,
194
+ "command": "claude -p --model claude-sonnet-5", // or `llm -m gpt-4o`, `ollama run llama3`, a script
195
+ "fastCommand": "claude -p --model haiku" // optional: cheaper, for the high-volume calls
196
+ }
197
+
198
+ // or an HTTP endpoint — for containers and servers with no CLI signed in
199
+ "llm": {
200
+ "enabled": true,
201
+ "http": {
202
+ "provider": "anthropic", // or "openai" for anything OpenAI-compatible
203
+ "model": "claude-sonnet-5",
204
+ "fastModel": "claude-haiku-4-5-20251001",
205
+ "apiKeyEnv": "ANTHROPIC_API_KEY", // read from the env or .env; no key ships with n-seo
206
+ "baseUrl": "" // optional: a gateway or a local server
207
+ }
208
+ }
209
+ ```
210
+
211
+ `provider: "openai"` speaks the OpenAI chat-completions shape, so it also covers
212
+ the many gateways and local servers that emulate it. `http` wins when it is
213
+ configured and its key resolves; otherwise the CLI path runs. Proposals land in
214
+ a holding area on `/actions` marked PROPOSED; accepting one into the queue is a
215
+ click a human makes. Nothing that comes back is applied automatically.
216
+
217
+ ### Your coding agent, on the queue
218
+
219
+ The repo ships an MCP server over the same data the dashboard reads, so an
220
+ agent can answer "what should I do first this week?" from the actual queue
221
+ instead of scraping pages: 16 tools and 3 doc resources, every one annotated
222
+ read-only. `.mcp.json` registers it for Claude Code automatically; Claude
223
+ Desktop, stdio and authenticated HTTP clients are covered in
224
+ [docs/MCP.md](docs/MCP.md). `CLAUDE.md` holds the operating rules an agent
225
+ working here has to follow.
226
+
227
+ Skills ship for the work itself, so the rules are enforced rather than
228
+ merely documented. `n-seo init` copies all seven into the instance's
229
+ `.claude/skills/` with this install's real paths substituted in, alongside a
230
+ `CLAUDE.md` carrying the operating rules — so an agent opened in that
231
+ directory is oriented before you type anything:
232
+
233
+ | Skill | Use it when |
234
+ |---|---|
235
+ | `n-seo-setup` | Fresh clone to first real daily run, including Google access |
236
+ | `n-seo-add-site` | Adding a site: property form, `gscHost`, GA4 id, brand regex, grants |
237
+ | `n-seo-triage` | "What should I work on today" from the queue and the last run |
238
+ | `n-seo-ship` | Implement one queue card in the site's repo, then record it as watching |
239
+ | `n-seo-review` | The weekly pass: judge watching items, retire what is done, refresh insights |
240
+ | `n-seo-deploy` | Moving n-seo off the laptop onto an always-on host, on a schedule |
241
+ | `orient` | First thing in a fresh session — get current in a few reads |
242
+
243
+ `n-seo-ship` stops rather than crossing the 28-day title freeze or the weekly
244
+ metadata budget. The engine checkout carries a second set of skills (`ndx-*`)
245
+ for developing n-seo itself with [n-dx](https://n-dx.dev); those are not
246
+ copied into an instance. `.claude/skills/README.md` explains the split.
247
+
248
+ Read-only is the point: an agent can reason over your search data all day and
249
+ still cannot bypass the freeze, the batching, or you.
250
+
87
251
  ## What you get
88
252
 
89
253
  | Page | What it shows |
@@ -122,7 +286,7 @@ on the Settings page or in `n-seo.config.json`.
122
286
  | `indexStatus` | Asks the URL Inspection API whether each sitemap URL is indexed | Search Console access | on |
123
287
  | `metadataAudit` | Fetches each ranking page's live title/description and scores them against its queries | nothing extra | on |
124
288
  | `opportunityScan` | Refreshes trend analysis; flags rising queries no queue item covers | nothing extra | on |
125
- | `llm` | Runs a local command (default: the `claude` CLI) for scan proposals and digest briefings | any CLI that reads a prompt on stdin | off |
289
+ | `llm` | Hands the run's findings to the model you choose: scan proposals, verdicts on shipped work, community briefings | a provider you configure: any stdin CLI, or an Anthropic / OpenAI-compatible endpoint | off |
126
290
  | `hackerNews` | Finds fresh HN threads in your expertise areas and briefs you | your HN username (optional) | off |
127
291
  | `reddit` | The same for subreddits | a free Reddit "script" app's credentials in `.env` | off |
128
292
  | `indexNow` | Generates a key and pings Bing/Copilot/Yandex with changed URLs | nothing (does nothing for Google) | off |
@@ -130,30 +294,6 @@ on the Settings page or in `n-seo.config.json`.
130
294
  | `gitAutoCommit` | Commits (and pushes) the daily log and export after each run | a git remote, if you want the push | off |
131
295
  | `notifications` | macOS notification when a daily step fails | macOS | off |
132
296
 
133
- ## Working with an AI agent
134
-
135
- The repo ships an MCP server over the same data the dashboard reads, so an
136
- agent can answer "what should I do first this week?" from the actual queue
137
- instead of scraping pages. `.mcp.json` registers it for Claude Code
138
- automatically; Claude Desktop and HTTP clients are covered in
139
- [docs/MCP.md](docs/MCP.md). It is read-only by design, and `CLAUDE.md` holds
140
- the operating rules an agent working here has to follow.
141
-
142
- It also ships skills for the work itself, so the rules are enforced rather
143
- than merely documented:
144
-
145
- | Skill | Use it when |
146
- |---|---|
147
- | `orient` | First thing in a fresh session — get current in a few reads |
148
- | `n-seo-setup` | Fresh clone to first real daily run, including Google access |
149
- | `n-seo-add-site` | Adding a site: property form, `gscHost`, GA4 id, brand regex, grants |
150
- | `n-seo-triage` | "What should I work on today" from the queue and the last run |
151
- | `n-seo-ship` | Implement one queue card in the site's repo, then record it as watching |
152
- | `n-seo-review` | The weekly pass: judge watching items, retire what is done, refresh insights |
153
-
154
- `.claude/skills/README.md` explains which skills operate an instance and which
155
- are contributor tooling for developing the engine with [n-dx](https://n-dx.dev).
156
-
157
297
  ## Working with n-dx
158
298
 
159
299
  The repo is wired for [n-dx](https://n-dx.dev): `docs/PRD.md` is the product
@@ -198,9 +338,10 @@ accept; community participation is human. The reasoning is in
198
338
 
199
339
  ## Requirements
200
340
 
201
- Node 20 or newer, Python 3.10 or newer, `curl`, `openssl`. macOS or Linux.
202
- Python is stdlib-only (no pip); the TypeScript app runs under `tsx` with no
203
- build step.
341
+ Node 20 or newer, Python 3.10 or newer, and `curl`. macOS, Linux or Windows
342
+ 10+, all three exercised by CI on every commit. Python is stdlib-only (no
343
+ pip); the TypeScript app runs under `tsx` with no build step. Nothing needs
344
+ `openssl`, `gcloud` or a compiler.
204
345
 
205
346
  ## Contributing and license
206
347