Commit Graph

17 Commits

Author SHA1 Message Date
dependabot[bot]
5b1bb2f0c5 chore(deps): bump aiohttp (#6)
---
updated-dependencies:
- dependency-name: aiohttp
  dependency-version: 3.13.4
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-05-14 03:15:42 +09:00
c1061dcc71 docs(notion-search): add /notion-search slash command + CLAUDE.md section
Slash command at custom-skills/31-notion-organizer/commands/notion-search.md
documents the CLI surface and JSON output schema. CLAUDE.md gains a
Semantic Search section explaining the 4-stage pipeline and env var
requirements. requirements.txt notes the optional anthropic SDK
dependency (the skill falls back to the claude CLI if missing).

Final task of Phase 3b-i. 30 tests passing.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-28 13:53:56 +09:00
40b79962fb fix(notion-search): warn on --filter without --databases + DRY cache_kwargs
Inline code review polish:
- --filter is only meaningful in per-database mode (workspace search
  doesn't accept Notion filter objects). Previously a user passing
  --filter without --databases would have it silently parsed and
  ignored. Now emit a stderr warning and clear the filter.
- cache_kwargs dict was built twice in run_search (once for cache_get,
  once for cache_put). Build once before the rerank call.

30/30 tests still pass.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-28 13:52:11 +09:00
72d4b36943 feat(notion-search): add CLI entrypoint with argparse + output formatting
Wires together the four stages (expand → search → enrich → rerank) into
run_search(). CLI flags: --databases, --filter, --limit, --no-rerank,
--no-expand, --no-cache, --json. Terminal output renders as a numbered
table with title, relevance, properties, snippet, URL.

Cache lookup happens BEFORE rerank, with cache_put after success.
NOTION_API_KEY (or NOTION_TOKEN) env var required.

4 end-to-end pipeline tests (mocked Notion + LLM): JSON-serializable
output, --no-rerank skip, --no-expand skip, cache hit on repeat.

Total: 30 tests passing.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-28 08:07:00 +09:00
20029ecc9c feat(notion-search): add Claude Haiku rerank module
Builds a rerank prompt with title + flattened properties + excerpt for
each candidate, calls Claude, parses JSON, sorts by score descending,
takes top N. On any failure (LLM error, missing JSON, parse error,
non-list shape), falls back to candidates in input order with null
relevance/snippet.

4 tests: ordering, limit, parse-error fallback, exception fallback.
26 passing total.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-28 08:01:45 +09:00
e67209b905 fix(notion-search): drop unused _flatten_property arg + lock falsy-value behavior
Code review polish:
- Drop the unused `name` parameter from `_flatten_property` (it was
  reserved for future per-property-name special-casing but never used).
- Add a regression test pinning that checkbox=False and number=0 are
  preserved in the enriched output. The existing empty-value filter is
  `if value not in (None, [], "")` which keeps falsy-but-meaningful
  values, but the contract wasn't tested.

22/22 tests pass.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-28 07:59:49 +09:00
8aa0fa26e9 feat(notion-search): add candidate enrichment (title, properties, excerpt)
For each candidate page, extract the title, flatten common property
types (status/select/multi_select/date/checkbox/number/url/etc.) to
display values, and fetch the first text-bearing block as a 200-char
excerpt. Empty excerpt is acceptable when the page has no leading text.

4 tests: title+properties, paragraph excerpt, empty fallback,
truncation. 21 passing total.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-28 07:56:35 +09:00
a40d1f06b5 fix(notion-search): make API errors non-fatal in search_candidates
Code review caught that without exception handling around
notion.search() and notion.data_sources.query(), any transient API
hiccup (rate limit, 5xx, network blip) would crash the whole search
and lose candidates already accumulated from earlier variants/DBs.

Wrap both calls in try/except, mirror the resolver's pattern: stderr
warning + continue. Same query against another variant or another DB
still has a chance to succeed.

Also tightened response.get("results", []) → response.get("results")
or [] so a hypothetical {"results": null} response doesn't crash the
inner loop.

17/17 tests still pass.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-28 07:54:47 +09:00
a4da24b15c feat(notion-search): add Notion search execution with workspace/DB modes
For each expanded query variant: hit Notion's workspace search OR
per-database data_sources.query (when --databases is specified).
Union and dedupe by page ID, cap at 30 candidates total. Filters out
non-page objects (databases) from workspace search results.
Property filters (--filter JSON) pass through to data_sources.query
when in per-database mode.

5 tests: workspace dedup, 30-cap, DB-mode dispatch, page-only filter,
property-filter passthrough. 17 passing total.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-28 07:52:00 +09:00
5f6438ecf3 fix(notion-search): polish expand_query (warn on shape error, lint fixes)
Code review polish:
- Add stderr warning for the fourth failure path (LLM returned valid
  JSON but it's not a list-of-strings). Previously this fell back
  silently, making debugging harder when Haiku produces unexpected
  shapes.
- Drop unused f-string prefixes from two warnings (no interpolation).
- Type hint: Callable[..., str] = None → Optional[Callable[..., str]] = None
  for strict type-checker compatibility.

12/12 tests still pass.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-28 07:50:03 +09:00
fffbab201d feat(notion-search): add query expansion via Claude Haiku
Generates up to 5 query variants (synonyms + cross-language KR↔EN) so
later Notion API search can union over them. Permissive failure modes:
LLM error or non-JSON response falls back to [original] with stderr
warning. Dedupes and caps variants.

4 tests: variants list, dedup+cap, JSON-parse fallback, exception
fallback. 12 passing total.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-28 07:47:20 +09:00
6bb8e6ab3c fix(notion-search): tighten cache type hints + deterministic TTL=0
Code review polish:
- Type hints: List → List[Dict[str, Any]] for cache_get return and
  cache_put results parameter, since rerank produces dict-shaped entries.
- TTL=0 short-circuits to None deterministically. Previously the test
  for ttl_seconds=0 passed only because clock motion between cache_put
  and cache_get made `time.time() - cached_at > 0` true. Now the
  semantics match the docstring intent.

8/8 tests still pass.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-28 07:45:44 +09:00
32a1c9d538 feat(notion-search): add SHA256-keyed JSON file cache
Cache layer for rerank results. Key is SHA256 of query + sorted
candidate IDs, so changing the candidate set automatically invalidates.
1-day TTL by default; corrupted cache files are silently dropped.

5 tests cover hit, miss, different-candidates, TTL expiry, corruption.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-28 07:42:48 +09:00
89b20aef16 fix(notion-search): pin SDK model to dated ID + drop unused type alias
Code review caught that the bare alias 'claude-haiku-4-5' works in the
Claude Code CLI but may not resolve in the Anthropic SDK. Pin the
default to 'claude-haiku-4-5-20251001' (the full dated ID) via a
DEFAULT_MODEL constant so the SDK path doesn't silently break the
first time it hits the real API.

Also document the max_tokens-ignored behavior on the CLI path in the
public call_claude docstring (not just the private _call_via_cli),
and drop the unused LLMCaller type alias (dead code).

3/3 tests still pass.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-28 07:41:25 +09:00
45c68dee61 feat(notion-search): add LLM client abstraction with SDK + CLI fallback
First task of Phase 3b-i (notion semantic search). Adds _search_llm.py
that dispatches to the anthropic SDK when ANTHROPIC_API_KEY is set,
falls back to `claude -p` CLI otherwise, and raises a clear setup
error if neither works. Symlinks _notion_compat.py from 32-notion-writer
so both skills share one source of truth.

3 tests cover the three dispatch paths.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-28 07:37:42 +09:00
144a17c88d feat(notion): migrate 31+32 to API 2025-09-03 + add property writes, upsert, anchor-link fix
Phase 1 — docs alignment:
- Fix path drift in 32 CLAUDE.md (02-notion-writer → 32-notion-writer)
- Align env var to NOTION_API_KEY in 31 docs (NOTION_TOKEN still accepted)
- Document Phase 3 roadmap in 31 (metadata-aware migration, Notion-as-RAG)

Phase 2 — multi-source database support:
- New 32/scripts/_notion_compat.py: client factory, data_source resolution
  with cache, property coercion, find_existing_page (for upsert),
  explain_api_error for friendlier failure messages
- 32 notion_writer.py: drop the 2022-06-28 pin, route schema introspection
  through data_sources.retrieve, build data_source_id parent shape, accept
  arbitrary properties via --properties JSON-or-file flag, add --upsert-by
  for idempotent re-runs
- 32 markdown parser: anchor-link fix — Notion's URL validator rejects
  fragment URLs and relative paths; fragments now render as bold to preserve
  TOC nav intent, relatives drop the link, absolute URLs preserved
- 31 async_organizer.py + schema_migrator.py: same data_sources migration
  with cached resolution; pages.create now uses data_source_id parent
- 16/16 parser tests pass (was 13; +3 link-handling regression guards)

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-27 09:57:20 +09:00
b69e4b6f3a refactor: Reorganize skill numbering and update documentation
Skill Numbering Changes:
- 01-03: OurDigital core (was 30-32)
- 31-32: Notion tools (was 01-02)
- 99_archive: Renamed from _archive for sorting

New Files:
- AGENTS.md: Claude Code agent routing guide
- requirements.txt for 00-claude-code-setting, 32-notion-writer, 43-jamie-youtube-manager

Documentation Updates:
- CLAUDE.md: Updated skill inventory (23 skills)
- AUDIT_REPORT.md: Current completion status (91%)
- Archived REFACTORING_PLAN.md (most tasks complete)

Removed:
- ga-agent-skills/ (moved to separate repo ~/Project/dintel-ga4-agent)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-23 18:42:39 +07:00