Commit Graph

327 Commits

Author SHA1 Message Date
Bryan Tegomoh 9d037786f2 fix(cli): restore --days alias compatibility 2026-04-13 09:18:18 -05:00
Matt Van Horn 01812ec185 fix(sync): skip OpenClaw variant branch when variants/open is absent (#222)
Makes the `variants/open/` sync steps in `scripts/sync.sh` conditional on
the directory actually existing in the source tree. The script is shared
between the public and private repos of last30days-skill, but the OpenClaw
variant only lives in the private repo (it's sanitized via
`strip_for_openclaw.py` and published separately to ClawhHub). When the
script runs from a checkout of the public repo, the variants/open paths
don't exist and the unconditional `rsync` and `sync_target` calls error
out immediately.

Changes:

- `sync_target()` now only creates `variants/open/references` and rsyncs
  `variants/open/` when `$SRC/variants/open` exists.
- The trailing `sync_target "$OPENCLAW_TARGET" ...` call is now gated by
  the same check, with an explanatory skip message when the directory is
  absent.

No behavior change when running from the private repo (which has
`variants/open/`). When running from the public repo, the script now
completes its COMMON_TARGETS loop without erroring.

This also closes out the confusion from PR #211, where a contributor saw
the broken `variants/open/` reference and tried to add the variant back
to the public repo. The real fix was making the script tolerate the
absence, not recreating the directory.

Co-authored-by: Matt Van Horn <455140+mvanhorn@users.noreply.github.com>
2026-04-11 11:37:27 -04:00
Matt Van Horn 86b2b9dd69 docs(v3): drop redundant What's New list and remove stale @steipete credit (#221)
release-notes.md:
- Drop the "What's New" section entirely. It repeated the same items
  as the Headline features section above it in bulleted form, a
  holdover from the old v2.9 release notes pattern. CHANGELOG.md is
  the canonical Added/Changed/Fixed list; release notes is marketing
  copy and shouldn't duplicate it. Added a one-line pointer to
  CHANGELOG.md [3.0.0] for anyone looking for the detail.
- Rename "Credits" to "Earlier contributors" and note they are from
  the v1 and v2 lineage, so readers don't confuse them with v3
  contributors.
- Remove @steipete credit (did not actually contribute to this repo).

CHANGELOG.md [2.1.0] Credits:
- Remove @steipete credit (did not actually contribute to this repo).

Co-authored-by: Matt Van Horn <455140+mvanhorn@users.noreply.github.com>
2026-04-11 09:33:43 -04:00
Matt Van Horn 6e7c0ba7aa docs(v3): prep CHANGELOG and release notes for v3.0.0 (#220)
Rewrites release-notes.md from its stale v2.9.1 focus into the v3
story: intelligent pre-research as the killer feature, fun judge /
Best Takes, cross-source cluster merging, single-pass comparisons,
GitHub person-mode and project-mode, 13+ sources, ELI5 mode. Credits
@j-sperling as the v3 engine architect in the hero section and
updates the install instructions from `git clone` to the real install
paths for Claude Code, OpenClaw, and OpenAI Codex CLI.

Also extends the CHANGELOG [3.0.0] entry with a Fixed section covering
the two post-merge prep fixes that landed just before release:

- #214 resolved a duplicate `name: last30days` collision in
  skills/last30days/SKILL.md that caused strict marketplace validators
  to reject the plugin (reported by @Cody-Coyote in #204)
- #219 added the real Codex CLI integration at
  .agents/skills/last30days/SKILL.md (regular file, since Codex's
  loader skips symlinked files) plus .codex-plugin/plugin.json as the
  namespace marker (inspired by @Jah-yee in #153 and @dannyshmueli
  on X)

Bumps the [3.0.0] date from `2026-04` to `2026-04-11` to match the
actual release date, and adds @Cody-Coyote and @Jah-yee to the
[3.0.0] Contributors list.

No code changes. Pure docs prep for the v3.0.0 GitHub release.

Co-authored-by: Matt Van Horn <455140+mvanhorn@users.noreply.github.com>
v3.0.0
2026-04-11 09:27:35 -04:00
Matt Van Horn 71e0492840 feat: make skill discoverable by OpenAI Codex CLI (#219)
Adds a Codex CLI skill integration by creating the two files Codex's real
loader actually reads:

- .agents/skills/last30days/SKILL.md (real file, not a symlink - Codex's
  loader skips symlinked files per codex-rs/core-skills/src/loader.rs)
- .codex-plugin/plugin.json with {"name": "last30days"} as a namespace
  marker, per codex-rs/utils/plugins/src/plugin_namespace.rs

When Codex CLI runs in a checkout of this repo, it walks .agents/skills/
from CWD up to the project root, picks up .agents/skills/last30days/SKILL.md,
and walks ancestors looking for .codex-plugin/plugin.json to resolve the
plugin namespace. The skill registers as last30days:last30days.

The SKILL.md is a verbatim copy of the root SKILL.md at this point to
avoid content drift during the rollout. A future PR can slim the Codex copy
or introduce a sync mechanism.

Verified against Codex CLI's own source by running codex exec from the
repo CWD and having it trace the loader logic.

Replaces PR #153, which used a fake $schema URL
(https://openai.com/codex/plugin.schema.json returns 404) and put a
misunderstanding of Codex's plugin manifest (Codex only reads the `name`
field - all other fields like version, description, author, skills[] are
silently ignored).

This contribution was developed with AI assistance (Codex + Claude Code).

Co-authored-by: Matt Van Horn <455140+mvanhorn@users.noreply.github.com>
2026-04-11 09:02:28 -04:00
Matt Van Horn 99b167d03a fix: resolve duplicate skill name causing marketplace validation failure (#204) (#214)
Two SKILL.md files declared `name: last30days` with `user-invocable: true`,
which caused strict marketplace validators to reject the plugin with "Some
plugins in this marketplace have validation errors":

- ./SKILL.md (canonical, also reachable via skills/last30days-nux/ symlink)
- ./skills/last30days/SKILL.md (v3 architecture spec, real file)

In v2.9.6, skills/last30days/SKILL.md was a symlink to ../../SKILL.md so
only one skill existed. Commit 0a9ff16 (v3.0.0) added a new real file at
skills/last30days-v3/SKILL.md, and commit 9be0780 then renamed that
directory to skills/last30days/, replacing the original symlink with a
different real file. The collision has been live since v3.0.0 shipped.

This change:
- Renames skills/last30days/SKILL.md to name: last30days-v3-spec and sets
  user-invocable: false. The file stays in place as internal architecture
  documentation, but it no longer competes with the canonical skill.
- Fixes README.md link that pointed to the deleted skills/last30days-v3/
  path (left over from the rename).
- Removes a stale variants/open/SKILL.md reference (variants/open was
  deleted in v3.0.0).

After the change, only one canonical name=last30days user-invocable=true
skill exists (the root SKILL.md, also reachable via the
skills/last30days-nux/ symlink, same inode).

Closes #204.

This contribution was developed with AI assistance (Codex).

Co-authored-by: Matt Van Horn <455140+mvanhorn@users.noreply.github.com>
2026-04-11 02:36:55 -04:00
Matt Van Horn 86e1d77ad7 Merge pull request #186 from pejmanjohn/contrib/mvanhorn-last30days-skill-99-fix-plugin-directory-name
fix: rename skills/last30days-v3 directory so plugin install resolves correctly
2026-04-09 23:18:18 -07:00
Matt Van Horn ac692e85bc Merge pull request #201 from tmchow/fix/90-store-sql-column-whitelist
fix(store): validate updatable columns in update_run and update_finding
2026-04-09 23:15:38 -07:00
Matt Van Horn 5196bf68a7 Merge pull request #202 from tmchow/fix/92-bluesky-token-refresh
fix(bluesky): add token expiry handling to session cache
2026-04-09 23:15:36 -07:00
Matt Van Horn 6bbb4300f5 Merge pull request #203 from tmchow/fix/marketplace-plugin-name
fix: correct plugin name and version in marketplace.json
2026-04-09 23:15:33 -07:00
Trevin Chow 62584631bb fix: correct plugin name and version in marketplace.json
marketplace.json had stale v3 rename artifacts: plugin name was
"last30days-3" (should be "last30days" to match plugin.json) and
version was "3.0.0-alpha" (should be "3.0.0" to match the stable
release).
2026-04-09 22:05:25 -07:00
Trevin Chow 43c8d6c29c fix(bluesky): add token expiry handling to session cache
The module-level _cached_token was set once and never refreshed. AT
Protocol tokens expire after ~2 hours, causing silent 401 errors in
long-running watchlist cron sessions. Adds a 90-minute expiry check
using time.monotonic() and logs re-authentication.

Fixes #92
2026-04-09 21:44:33 -07:00
Trevin Chow ccd2a4065d fix(store): validate updatable columns in update_run and update_finding
Add column whitelists to prevent SQL injection via kwargs keys in
dynamic UPDATE queries. Values were already parameterized but column
names were string-interpolated directly from kwargs.

Fixes #90
2026-04-09 21:40:53 -07:00
Pejman Pour-Moezzi bb7c956db5 fix: drop stale last30days-v3 argument hint 2026-04-09 21:37:36 -07:00
Pejman Pour-Moezzi 9be0780c46 fix: rename skills/last30days-v3 directory so plugin install resolves correctly 2026-04-09 21:37:00 -07:00
Matt Van Horn 341da37218 Merge pull request #182 from ziperlee/codex/bluesky-refresh-token
fix: refresh expired bluesky sessions
2026-04-09 21:20:58 -07:00
Matt Van Horn 4b3458776b Merge pull request #191 from kriptoburak/feat/add-xquik-source
feat: add Xquik as X/Twitter search source
2026-04-09 21:19:18 -07:00
Matt Van Horn 6436290cc1 Merge pull request #183 from zl190/claim-contributor-entry
docs: claim @zl190 contributor entry
2026-04-09 21:18:04 -07:00
Matt Van Horn 5316d92fc6 Merge pull request #185 from hnshah/hnshah-claim-contrib
docs: claim hnshah contributor entry
2026-04-09 21:18:02 -07:00
Matt Van Horn 1f350d2b30 Merge pull request #189 from pejmanjohn/contrib/mvanhorn-last30days-skill-102-claim-contributors-entry
docs: claim @pejmanjohn CONTRIBUTORS.md entry
2026-04-09 21:17:04 -07:00
Matt Van Horn 474cc4ad7a Merge pull request #188 from pejmanjohn/contrib/mvanhorn-last30days-skill-101-readme-update-command
docs: add plugin update command to README
2026-04-09 21:17:01 -07:00
Matt Van Horn 80892d31c6 Merge pull request #187 from pejmanjohn/contrib/mvanhorn-last30days-skill-100-fix-nux-argument-hint
fix: update argument-hint in root SKILL.md from last30days-3 to last30days
2026-04-09 21:16:59 -07:00
Matt Van Horn 5c4383d661 Merge pull request #192 from tmchow/fix/remove-orphaned-exa-test
fix(tests): remove orphaned test_exa_search.py
2026-04-09 21:06:44 -07:00
Matt Van Horn 101c4724f4 Merge pull request #193 from tmchow/fix/evaluator-test-env-isolation
fix(tests): isolate env in resolve_google_judge_api_key test
2026-04-09 21:06:42 -07:00
Matt Van Horn c09ca59747 Merge pull request #194 from tmchow/fix/bump-version-metadata-v3
fix: bump gemini-extension and v3 skill version to 3.0.0
2026-04-09 21:06:40 -07:00
Matt Van Horn dad97f1b05 Merge pull request #198 from iliaal/perf/pipeline-optimizations
perf: optimize dedup, parallelize handle searches and enrichment
2026-04-09 21:00:37 -07:00
Ilia Alshanetsky eef3547c37 perf: optimize dedup, parallelize handle searches and enrichment
The dedup hot path recomputed normalize_text() 4 times per comparison
and recomputed item_text() on every inner-loop iteration. Pre-computing
n-gram sets and token sets into a _PreparedText cache cuts dedup time
by 6x (2.16s to 0.39s on 300 unique items).

Bird handle searches spawned one Node process per handle sequentially.
Now uses ThreadPoolExecutor so N handles run concurrently. Same pattern
applied to YouTube comment enrichment (was serial, Reddit was already
parallel) and the retry-thin-sources phase in the pipeline.

Clustering now pre-computes candidate text and uses prepared_similarity
for the O(n^2) grouping and MMR representative selection loops.

Minor: _is_wsl() cached with lru_cache, Bundle.add_items() uses
extend() instead of list concatenation.

End-to-end: 5.2s -> 3.7s (29% faster) on a typical 4-source query.
2026-04-09 19:00:30 -04:00
Ilia Alshanetsky 252c8222f1 feat: add WSL2 Windows Firefox cookie extraction for X auth
On WSL2, native Linux Firefox typically has no x.com cookies since users
browse in Windows. Chromium browsers (Edge, Chrome, Brave) encrypt cookies
with DPAPI/app-bound encryption, making them inaccessible without admin
privileges. Windows Firefox stores cookies unencrypted in SQLite, readable
directly through the /mnt/c mount.

The cookie extractor now detects WSL2 via /proc/version, locates Windows
Firefox profiles under /mnt/c/Users/*/AppData/Roaming/Mozilla/Firefox,
and falls back to them when Linux Firefox yields no results. Reports
source as "firefox-wsl" to distinguish from native.

Also fixes profile resolution priority: Install* sections (Firefox >= 67)
now take precedence over the legacy Default=1 flag, which could select a
stale profile on multi-profile installations.
2026-04-09 18:36:02 -04:00
Trevin Chow 6a4071a9fd fix: bump gemini-extension and v3 skill version to 3.0.0
gemini-extension.json still referenced v2.9.5 and
skills/last30days-v3/SKILL.md still said 3.0.0-alpha.
Both now match pyproject.toml's canonical 3.0.0 version.

Addresses items from #190. Structural decisions (SKILL.md
consolidation, SKILL-original.md cleanup) left for maintainer.

This contribution was developed with AI assistance (Claude Code).
2026-04-09 13:00:08 -07:00
Trevin Chow 5896c9582b fix(tests): isolate env in resolve_google_judge_api_key test
The second assertion in test_resolve_google_judge_api_key_prefers_google_key
ran outside the mock.patch.dict context. When GOOGLE_API_KEY or GEMINI_API_KEY
is set in the real environment, os.environ takes precedence over the config
dict fallback and the test fails.

Wrap the assertion in its own mock.patch.dict scope that clears the three
relevant env vars so the test passes regardless of the developer's env.

This contribution was developed with AI assistance (Claude Code).
2026-04-09 12:56:34 -07:00
Trevin Chow 718fe9547b fix(tests): remove orphaned test_exa_search.py
lib/exa_search.py was removed during the v3 refactor but
tests/test_exa_search.py still imports from it. This causes
an ImportError that blocks pytest -x from running any tests.

This contribution was developed with AI assistance (Claude Code).
2026-04-09 12:52:25 -07:00
Burak Bayır 6b3de9170e feat: add Xquik as X/Twitter search source
Add Xquik (xquik.com) as a new X/Twitter search source that uses a REST
API with full engagement metrics (likes, retweets, replies, quotes,
views, bookmarks). Uses stdlib urllib only -- no new dependencies.

- scripts/lib/xquik.py: source module with search, parse, query expansion
- tests/test_xquik.py: 32 unit tests covering all functions
- env.py: XQUIK_API_KEY config and availability check
- pipeline.py: source registration and retrieve dispatch
- normalize.py: reuses _normalize_x (same item format as Bird)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-09 22:44:10 +03:00
Pejman Pour-Moezzi ca4ffb9633 docs: claim @pejmanjohn CONTRIBUTORS.md entry 2026-04-09 12:20:18 -07:00
Pejman Pour-Moezzi 79a5c3ea94 docs: add plugin update command to README 2026-04-09 12:16:25 -07:00
Pejman Pour-Moezzi a41bf5d8e7 fix: update argument-hint in root SKILL.md from last30days-3 to last30days 2026-04-09 12:12:16 -07:00
Hiten Shah 319ec796bd docs: claim hnshah contributor entry 2026-04-09 11:26:51 -07:00
jason-zl190 86df1e7d4b docs: claim @zl190 contributor entry
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-10 04:04:44 +10:00
Matt Van Horn 45f596ca0c docs: add v3 community contributors section to release notes 2026-04-09 10:56:21 -07:00
Matt Van Horn 4fab23a357 feat: add CONTRIBUTORS.md crediting v3 community inspiration 2026-04-09 10:55:03 -07:00
ziperlee 9405aa3fb4 fix: refresh expired bluesky sessions 2026-04-09 23:03:47 +08:00
ziperlee 2020156591 fix: write briefing files as utf-8 2026-04-09 23:01:17 +08:00
Matt Van Horn b6d97a571d Merge pull request #179 from pejmanjohn/contrib/mvanhorn-last30days-skill-46-prompt-injection-hardening
fix: harden rerank prompts and assistant-facing digests against scraped prompt injection
2026-04-09 06:29:20 -07:00
Matt Van Horn 0e5faa7a82 Merge pull request #175 from ziperlee/codex/readme-v3-alignment
docs: align README with v3 runtime
2026-04-09 06:25:00 -07:00
Matt Van Horn 9de2398106 Merge pull request #173 from pejmanjohn/contrib/mvanhorn-last30days-skill-44-bird-sweet-cookie-runtime
last30days: lazy-load sweet-cookie so vendored Bird works on fresh installs
2026-04-09 06:20:39 -07:00
Matt Van Horn fd6ec55f07 Merge pull request #180 from tmchow/fix/bird-x-list-response
fix(bird_x): normalize list responses from Bird search
2026-04-09 06:10:34 -07:00
Trevin Chow 65399eb4eb fix(bird_x): normalize list responses from Bird search to dict format
When Bird's JSON response is a raw array instead of an object,
json.loads returns a list. All callers use .get('items') which raises
AttributeError on lists. Wrap list responses in {"items": parsed} so
callers always receive a dict.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-09 01:26:14 -07:00
Pejman Pour-Moezzi b7d1a38ff6 Fix Bird cookie helper lazy-loading 2026-04-08 19:30:39 -07:00
Pejman Pour-Moezzi 89e6ee29fd last30days: harden rerank and render prompts 2026-04-08 19:23:25 -07:00
Matt Van Horn dedf615114 Merge PR #174: last30days: require Python 3.12+ in OpenClaw setup and CLI entrypoints
last30days: require Python 3.12+ in OpenClaw setup and CLI entrypoints
2026-04-08 19:05:47 -07:00
zipee f926d6507a docs: point skill metadata at public repo 2026-04-09 08:40:14 +08:00