Commit Graph

23 Commits

Author SHA1 Message Date
478ac61975 fix(notion-writer): fail loudly on markdown image append + upsert prop update
Mirror the blocks path's error handling in the markdown engine:
- page + DB markdown two-phase image append now check append_to_page's
  return and exit(1) on failure instead of printing success silently
- markdown DB upsert guards update_page_properties return
- restore blocks-engine page progress print + replace-failure print
- move unused parent computation into the create branch

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-27 11:13:31 +09:00
5ff9b3d9f5 feat(notion-writer): --engine routing + two-phase image append
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-27 11:13:31 +09:00
cfbca6cc15 feat(notion-writer): markdown endpoint helpers + version-aware client
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-27 11:13:31 +09:00
dfbc52e531 feat(notion-writer): dialect->Notion enhanced markdown translator
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-27 11:13:31 +09:00
337f2ad6e1 feat(notion-writer): materialize local images via upload walk
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-27 11:13:31 +09:00
9fbd719048 feat(notion-writer): parse standalone images to image blocks
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-27 11:13:31 +09:00
5385f3bddd feat(notion-writer): ntn_files upload + preflight
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-27 11:13:31 +09:00
3fbce9dafb fix(notion-writer): paginate clear_page_content to handle >100 blocks
notion.blocks.children.list returns at most 100 blocks per call.
Without pagination, --replace only cleared the first 100 blocks
of a page, leaving the rest behind and producing surprising
partial-replace behavior.

Loop with next_cursor until has_more is false so the entire
page is cleared.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-24 22:34:29 +09:00
e1bd799672 docs(notion-writer): document 1Password credential handling, deprecate .env
Plaintext .env storage of NOTION_API_KEY is unnecessary risk — Notion
integration tokens grant write access to every connected page/database
and have no expiry. Document the 1Password CLI fetch pattern as the
preferred path; .env becomes a discouraged fallback for environments
without `op`.

SKILL.md adds a Credential handling section covering:
- One-shot inline fetch via `op read 'op://Development/Notion - Claude Agent/api-key'`
- Subshell-scoped export pattern for repeated use without shell-history exposure
- 1Password field-name conventions (api-key for the token)
- Anti-patterns to avoid (echo, CLI args, git commits, chat paste)
- Token rotation procedure

notion_writer.py error message updated to point at the 1Password recipe
when NOTION_API_KEY is missing, instead of telling users to create a .env.

Tested end-to-end: pushed a 22 KB markdown report (16 tables, 120 nested
checkboxes) using the inline 1Password fetch. Bot identity verified, all
markdown blocks rendered as native Notion blocks.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-28 19:14:48 +09:00
6446f00522 docs(notion-writer): document Phase 3c block coverage + bump to v1.2.0
Adds rows for callouts, toggles, columns, and page mentions in the
supported-elements and inline rich-text tables. Adds usage examples
for each. Updates version footer with changelog entry.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-27 11:38:53 +09:00
707405b940 docs(notion-writer): document mention pattern ordering and UUID format invariant
Code review flagged two implicit invariants worth pinning with comments:
- 'mention' must precede 'link' in INLINE_PATTERNS so the @[X](Y) prefix
  takes priority over plain link parsing
- format_id_with_dashes is required because the Notion mention API expects
  a dashed UUID while extract_notion_id returns dashless

32/32 tests still pass.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-27 11:37:07 +09:00
328de7d052 feat(notion-writer): add inline page mentions via @[Title](id-or-url)
Inline rich-text gets a new 'mention' pattern matching @[Title](target).
Target can be a raw 32-hex page ID, a dashed UUID, or a Notion URL —
all resolved via the existing extract_notion_id helper. Invalid targets
degrade to plain text '@Title' with no warning (avoids false-positive
spam from unrelated @[x](y) patterns).

Pattern placed BEFORE 'link' in INLINE_PATTERNS so the @ prefix takes
priority over plain link parsing.

Also widens extract_notion_id's URL regex from [^-]+- to [^/]+?- so
multi-hyphen Notion URLs (e.g. notion.so/My-Cool-Page-{id}) resolve
correctly — previous regex only matched single-segment titles.

+3 tests, 32 passing total.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-27 11:33:10 +09:00
0421a65327 feat(notion-writer): add column_list blocks via Pandoc fenced div
Pandoc-style ::: columns / ::: column / ::: blocks emit a Notion
column_list with column children. Each column's body recurses through
_parse_lines so any block type (lists, code, nested columns) works
inside. Single-column wrappers degrade to plain paragraphs because
Notion requires at least two columns.

Single-depth-counter design: depth=1 on enter, increments on `::: columns`
or `::: column`, decrements on `:::`. depth=0 closes the wrapper.

+3 tests, 29 passing total.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-27 11:26:02 +09:00
0f8d7b2df1 fix(notion-writer): use module-level sys instead of inline import in toggle warning
Code review caught a redundant `import sys as _sys` inside the unclosed-
<details> branch. The module already imports `sys` at the top, so the
inline import was dead weight. Use the module-level `sys.stderr` directly.

26/26 tests still pass.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-27 11:23:49 +09:00
aac1082bb7 feat(notion-writer): add toggle blocks via HTML5 <details>
Multi-line <details>...</details> with optional <summary> emits a Notion
toggle block. Body recurses through _parse_lines so any block type
(lists, code, nested toggles) is supported inside. Depth tracking lets
<details> nest inside <details>. Unclosed <details> at EOF degrades to
plain paragraphs with a stderr warning instead of crashing.

+4 tests, 26 passing total.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-27 11:20:21 +09:00
4e692d0e9a fix(notion-writer): add "object": "block" to create_callout_block
Code review caught that all 9 other create_*_block factories include
"object": "block" as the first key, but the new callout factory was
missing it. The Notion API accepts both forms, but the inconsistency
would compound; align with the existing convention.

22/22 tests still pass.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-27 11:17:11 +09:00
e0f93e6add feat(notion-writer): add GitHub-alert callout blocks
Adds support for > [!NOTE] / > [!TIP] / > [!IMPORTANT] / > [!WARNING] /
> [!CAUTION] callouts. Each alert type maps to a Notion callout block
with an emoji icon and matching colored background. Unknown alert types
(e.g. > [!BOGUS]) fall through to the existing quote handler with the
marker preserved.

Also restores the "must come before generic bullet match" comment on
the todo branch (load-bearing ordering note).

+6 tests, 22 passing total.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-27 11:12:50 +09:00
c318df8551 refactor(notion-writer): make markdown_to_notion_blocks reentrant
Split the entry function into a public reentrant entry that accepts
either string or List[str], and a private _parse_lines engine that
container detectors will recurse into. No behavior change for existing
callers; all 16 parser tests still pass.

Prep for Phase 3c: callout/toggle/columns/page-mention block coverage.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-27 11:07:43 +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
665fe22201 feat(notion-writer): add table blocks, inline rich-text parsing, and parser tests
Extend markdown_to_notion_blocks with GFM table support and rewrite
parse_rich_text to emit Notion annotations for bold/italic/code/link/strike
instead of dropping them as literal text. Move checkbox match ahead of the
bullet match so "- [ ]" lines become to_do blocks, not bullets.

Add test_parser.py with 13 regression tests covering rich-text spans,
block types, and table cell formatting.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-23 13:00:12 +09:00
c9772db119 fix(notion-writer): skip archived blocks when replacing page content
The --replace flag failed with "Can't edit block that is archived" when
a page contained previously archived blocks. Now skips them during clear.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-14 23:26:47 +09:00
0bc24d00b9 feat: Add OurDigital custom skills package (10 skills)
Complete implementation of OurDigital skills with dual-platform support
(Claude Desktop + Claude Code) following standardized structure.

Skills created:
- 01-ourdigital-brand-guide: Brand reference & style guidelines
- 02-ourdigital-blog: Korean blog drafts (blog.ourdigital.org)
- 03-ourdigital-journal: English essays (journal.ourdigital.org)
- 04-ourdigital-research: Research prompts & workflows
- 05-ourdigital-document: Notion-to-presentation pipeline
- 06-ourdigital-designer: Visual/image prompt generation
- 07-ourdigital-ad-manager: Ad copywriting & keyword research
- 08-ourdigital-trainer: Training materials & workshop planning
- 09-ourdigital-backoffice: Quotes, proposals, cost analysis
- 10-ourdigital-skill-creator: Meta skill for creating new skills

Features:
- YAML frontmatter with "ourdigital" or "our" prefix triggers
- Standardized directory structure (code/, desktop/, shared/, docs/)
- Shared environment setup (_ourdigital-shared/)
- Comprehensive reference documentation
- Cross-skill integration support

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-31 16:50:17 +07: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