ワンクリックで
gemini2obsidian-patterns
Development patterns for the obsidian-ai-exporter Chrome Extension (CRXJS + Vite + TypeScript)
Codex または Claude でインストール この Prompt をコピーして Codex、Claude、または他のアシスタントに貼り付けると、Skill ページを確認してインストールできます。
メニュー
Development patterns for the obsidian-ai-exporter Chrome Extension (CRXJS + Vite + TypeScript)
Codex または Claude でインストール この Prompt をコピーして Codex、Claude、または他のアシスタントに貼り付けると、Skill ページを確認してインストールできます。
SOC 職業分類に基づく
Detect user-facing feature drift and update README.md + README.ja.md and the Chrome Web Store descriptions in lockstep. Use when features have shipped but the docs are stale, or before a release. Docs-only — never touches src/.
Autonomous improvement loop for code quality. Repeatedly runs QA, Fix, and Refactor cycles with test-guarded auto-revert. Use when user says "improve", "run QA loop", "fix and refactor", "code quality scan", or "autonomous improvement". Leverages SuperClaude commands for enhanced analysis. Uses MCP servers (serena, sequential-thinking, context7, tavily, playwright) for semantic analysis, documentation lookup, and multi-step reasoning.
| name | gemini2obsidian-patterns |
| description | Development patterns for the obsidian-ai-exporter Chrome Extension (CRXJS + Vite + TypeScript) |
| version | 1.0.0 |
| source | local-git-analysis |
| analyzed_commits | 134 |
Conventional Commits enforced via commitlint + husky pre-commit hook.
{type}: {description}
| Type | Purpose | release-please |
|---|---|---|
feat | New feature | minor bump |
fix | Bug fix | patch bump |
security | Security fix | patch bump |
refactor | Code refactoring | patch bump |
perf | Performance improvement | patch bump |
test | Tests only | patch bump |
chore | Maintenance | patch bump |
docs | Documentation | patch bump |
style | Code style/formatting | patch bump |
ui | UI changes | patch bump |
ci | CI configuration | no bump |
build | Build system | no bump |
revert | Revert commit | depends |
fix: description (#123)main
└── {type}/{slug} # e.g. feat/append-mode, fix/katex-math-extraction
└── squash merge only # enforced via GitHub settings
main before modifying code{type}/{descriptive-slug}src/
├── background/ # Service worker (message routing, API calls)
│ ├── index.ts # onMessage listener, handleMessage router
│ ├── validation.ts # Sender + message content validation
│ ├── obsidian-handlers.ts # Save, get, test connection
│ └── output-handlers.ts # Multi-output (obsidian, file, clipboard)
├── content/ # Content scripts (DOM extraction)
│ ├── index.ts # Init, sync handler, extractor routing
│ ├── extractors/ # Platform-specific extractors
│ │ ├── base.ts # BaseExtractor (shared utilities)
│ │ ├── gemini.ts # Gemini extractor
│ │ ├── claude.ts # Claude extractor
│ │ ├── chatgpt.ts # ChatGPT extractor
│ │ └── perplexity.ts # Perplexity extractor
│ ├── markdown.ts # Turndown HTML-to-Markdown
│ ├── markdown-rules.ts # Custom Turndown rules
│ ├── markdown-deep-research.ts # Deep Research citation handling
│ ├── markdown-formatting.ts # Message formatting
│ └── ui.ts # Sync button, toasts
├── lib/ # Shared utilities
│ ├── types.ts # All TypeScript interfaces
│ ├── constants.ts # Centralized constants
│ ├── storage.ts # chrome.storage wrapper (local + sync)
│ ├── messaging.ts # Type-safe chrome.runtime.sendMessage
│ ├── obsidian-api.ts # REST API client
│ ├── validation.ts # Input validation (URL, API key, callout)
│ ├── path-utils.ts # Path security + template resolution
│ ├── sanitize.ts # DOMPurify wrapper + KaTeX preprocessing
│ └── ... # error-utils, hash, throttle, etc.
├── offscreen/ # Clipboard operations (offscreen document)
├── popup/ # Settings UI
└── manifest.json # Chrome extension manifest v3
Strictly ordered checklist:
src/lib/types.ts (AIPlatform)PLATFORM_LABELS in src/lib/constants.tsBaseExtractor in src/content/extractors/src/content/index.ts (getExtractor())waitForConversationContainer() selectors if neededALLOWED_ORIGINS in src/lib/constants.ts (security-critical)src/manifest.json: host_permissions + content_scripts.matchestest/fixtures/dom-helpers.tstest/setup.ts (chrome API mocks)test/ (mirrors src/ structure)test/
├── setup.ts # Chrome API mocks
├── mocks/ # Shared mock utilities
├── fixtures/ # DOM helpers for each platform
├── background/index.test.ts # Background service worker tests
├── content/ # Content script tests
├── extractors/ # Extractor unit tests
│ ├── base.test.ts
│ ├── gemini.test.ts
│ ├── claude.test.ts
│ └── e2e/ # E2E snapshot tests
├── lib/ # Utility tests
└── popup/ # Popup UI tests
vi.resetModules() + vi.doMock() for modules with side effectscapturedListener pattern: capture chrome.runtime.onMessage.addListener callback for testingcreateGeminiConversationDOM(), loadFixture(), clearFixture()innerHTML encodes & as &; use Object.defineProperty to mock inHTML in regex testsnpm run test # vitest run (all tests)
npm run test:watch # vitest (watch mode)
npm run test:coverage # vitest run --coverage
npm run build # tsc --noEmit && vite build
npm run lint # eslint src/ && lint-platforms.mjs
npm run format # prettier --write
chrome.storage.local: API key (never synced to cloud)chrome.storage.sync: All other settingsvalidateSender(): Exact origin matching via url.origin against ALLOWED_ORIGINSvalidateMessageContent(): Action allowlist + content size/path validationgetSettings response: Redacted for content scripts (ContentScriptSettings with isApiKeyConfigured boolean, no raw key)sanitizeHtml() (DOMPurify) before Markdown conversioncontainsPathTraversal() (../, null bytes, URL-encoded)validateObsidianUrl() (http/https only, port range 1024-65535)escapeYamlValue()[G2O] with context: [G2O Background], [G2O Popup], [G2O Offscreen]{type}/{slug} branchmainrelease-please-config.json + .release-please-manifest.jsonFiles that always change together:
src/lib/types.ts + extractors (when adding fields)src/background/service-worker.ts + src/background/validation.ts (when adding message actions)src/manifest.json + src/lib/constants.ts (when adding platforms)src/content/extractors/*.ts + test/extractors/*.test.ts + test/fixtures/dom-helpers.ts