Commit Graph

9 Commits

Author SHA1 Message Date
Maciej Lisiewski
9eab688b42 ci: ruff UP017 fixes 2026-10-09 17:34:36 +02:00
Maciej Lisiewski
d76cce4f11 ci: apply all automatic linter fixes available 2026-10-08 17:22:54 +02:00
teknium1
80512c90dc fix(website): batch the plugin stars probe at 100 repos per GraphQL request
A single request for all 317 catalog repos now exceeds GitHub's per-query
resource limit: the reply carries partial data plus an error, the script
prints 'Probed 317', and every repo past the limit keeps its stale count
(hindsight showed 26.5k stars while GitHub had 34.5k). Batch at 100; probed
live: 317/317 repos in 4 requests, no errors.
2026-09-27 03:34:56 -07:00
teknium1
e2abb460b6 fix(website): put the repo root on sys.path before importing hermes_yaml in the stars probe
The scheduled Build Skills Index run executes
`python website/scripts/fetch-plugin-stars.py --probe`, so sys.path[0] is
website/scripts and the repo-root `hermes_yaml` shim it now imports is not
importable. Every scheduled probe since 2026-09-24 died with
ModuleNotFoundError, the live plugin-stars.json froze at that date, and the
41 catalog entries added since have no star count: they sort to the bottom of
'Most starred' and show no star pill regardless of real stars.

extract-plugins.py already inserts REPO_ROOT; do the same here.
2026-09-27 03:34:56 -07:00
ethernet
c13287c915 Merge remote-tracking branch 'origin/main' into ethie/pm-clean
# Conflicts:
#	apps/desktop/electron/main.ts
#	hermes_cli/backup.py
#	hermes_cli/config.py
#	hermes_cli/plugin_catalog.py
#	hermes_cli/plugins_cmd.py
#	hermes_cli/plugins_cmd_catalog.py
#	hermes_cli/plugins_discovery.py
#	hermes_cli/profiles.py
#	hermes_cli/update_cmd_deps.py
#	pyproject.toml
#	tests/gateway/test_dm_topics.py
#	tests/hermes_cli/test_config.py
#	tests/hermes_cli/test_plugins_cmd.py
#	tests/hermes_cli/test_update_autostash.py
#	tests/tools/test_lazy_deps.py
#	tools/lazy_deps.py
#	tools/skill_ledger.py
#	utils.py
#	website/docs/user-guide/security.md
2026-09-22 05:16:50 -04:00
teknium1
c3021aff0d ci(skills-index): re-mint the App token before the catalog stars probe; keep fetched_at honest on failure
The `Probe plugin catalog stars` step reused the GitHub App installation token
minted at job start. That token lives 1 h; `build_skills_index.py` (the step
before it) has walked ClawHub for 60-85 min since Sep 17, so every scheduled
probe since Sep 18 ran on an expired token and logged
`GraphQL probe failed (HTTP Error 401: Unauthorized); keeping previous counts`.
114 of the 213 catalog repos ended up without a star count and the "Most
starred" default sort fell to alphabetical for half the catalog.

Run-log evidence (job step timestamps; `gh run view --json jobs` + job logs):
  run 35569229751 (Sep 21): mint 06:36:52Z -> probe 08:01:50Z (85 min) -> 401,
      "Probed 213 repos ... wrote 99 star counts"
  run 35426522555 (Sep 19): mint 06:24:52Z -> probe 07:39:59Z (75 min) -> 401
  run 35133575877 (Sep 16, last success): mint 18:18:39Z -> probe 18:40:12Z
      (21 min) -> "Probed 100 repos ... wrote 100 star counts"

Fix: a second `./.github/actions/get-app-token` step (`probe-token`)
immediately before the probe; the probe reads that token. Ordering stays (the
probe does not depend on the walk, but the artifact upload wants both files
and the step comment already documents the walk timing).

Freshness: `main()` stamped `fetched_at = now` whenever the written map
differed from the previous one, so a FAILED probe still moved the timestamp
forward and the catalog footer read "popularity ranking as of <today>" over
Sep-16 counts (live `plugin-stars.json`: fetched_at 2026-09-21 with Sep-16
data). `probe_stars` now returns `(stars, probed)`; `fetched_at` advances only
when GitHub actually answered, otherwise the previous timestamp is kept, a
`:⚠️:` names how many catalog repos have no count, and the summary line
says "Probe failed; wrote N cached star counts (as of <ts>)" instead of
"Probed N repos".

Local repro (3 catalog repos, cache from Sep 16 with 2 of them, GraphQL 401):
  before: fetched_at restamped to now; "Probed 3 repos ... wrote 2 star counts"
  after:  fetched_at stays 2026-09-16T18:40:16+00:00; ":⚠️:plugin star
          probe failed; reused 2 cached counts from 2026-09-16..., 1 of 3
          catalog repos have no star count"

Not taken from #118129: the per-repo REST fallback and the payload-shape
validation. The transport was never the problem (the same expired token 401s
on REST too), and one GraphQL request per run is the rate-limit rule this
script documents.

Fixes #118113
credit: @fangliquanflq #118129 (honest fetched_at on a failed probe + ::warning; slim redo)
2026-09-21 23:31:02 -07:00
ethernet
b4a294fff9 Merge origin/main; keep PM as plugin dependency owner
Reconcile plugin declarations and validation through PM's atomic generation publication; preserve external runtimes, target markers, and conflict refusal. Keep one source-update completion owner and port upstream lifecycle changes to the PM desktop/runtime paths.
2026-09-17 13:52:05 -04:00
teknium1
471d8a427a ci(plugin-catalog): probe stars only from the scheduled skills-index run, in one GraphQL request
Aligns the star ranking with the rule the skills index already follows:
GitHub is consulted only by the twice-daily skills-index.yml schedule, whose
artifact every docs deploy reuses. deploy-site.yml now runs
fetch-plugin-stars.py without --probe (reuse-only: artifact → live site copy →
disk → empty) and cannot call the API at all, so a same-day merge train adds
zero requests regardless of cache age.

The probe itself collapses from one REST call per repo (~26 today, growing
with the catalog) to a single GraphQL query with aliased repository fields,
so the scheduled run costs one request no matter how big the catalog gets. A
failed probe (rate limit, renamed repo, bad token) keeps the previous counts.
2026-09-15 04:39:38 -07:00
teknium1
3e2e2c50eb feat(plugin-catalog): rank entries by GitHub stars, probed at most once a day
Catalog entries sort official → stars desc → name, both in browse shelves and
filtered grids, with a ★ pill on each card linking to the repo's stargazers.

Rate-limit discipline is the design constraint: the docs site deploys many
times a day and shares one GitHub App API budget with every other workflow
(tonight's merge train got rate-limited on unrelated uploads). So
website/scripts/fetch-plugin-stars.py first fetches the live site's own
plugin-stars.json (a CDN GET, not the API); if that cache is under 24h old it
is reused verbatim and GitHub is never called. Only a stale cache triggers one
GET /repos/{owner}/{repo} per unique catalog repo, and a 403/429 mid-run keeps
the previous counts instead of zeroing them. extract-plugins.py merges the
cache into plugins.json (`stars`) and plugins-meta.json (`starsFetchedAt`), and
the page footnote says when the ranking was last refreshed.
2026-09-14 21:24:33 -07:00