Commit Graph

25 Commits

Author SHA1 Message Date
Kazuki Yamada 523fb07111 feat(website): Add Cloudflare Turnstile verification to /api/pack
intent(pack-defense): Repomix を「コード抽出 API」として大量に叩く匿名クローラ対策。GA + Cloud Run logs の調査で 2026-04 末に 21K+ unique GitHub repos を 7 日で系統列挙されたインシデントが確認された。IP ベースの rate limit (3/min, 30/day) は機能していたが residential proxy + Tencent Cloud SG で 2,256+ unique IPs に分散され実質無力化されていた。
decision(turnstile-vs-asn): Turnstile (JS challenge) を採用。ASN ブロックは residential proxy で無力、daily limit 強化は IP 数で水増し可能。invisible JS challenge は residential proxy 経由でも通せないので一番 cost asymmetric。
constraint(scope): /api/pack のみ。docs / health / ホームページ閲覧は無関係 — Googlebot / GPTBot / ClaudeBot 等は GET HTML しか叩かないので SEO/LLMO に影響なし。
decision(fail-policy): TURNSTILE_SECRET_KEY 未設定なら fail-open(dev/preview を壊さない、警告ログは出す)。設定済みでトークン欠落・siteverify 失敗・ネットワーク失敗は全て fail-closed の 403。
decision(token-transport): X-Turnstile-Token ヘッダで送信。FormData フィールドにすると packRequestSchema (valibot) を汚染するため、cross-cutting concern として layer を分離。
decision(client-widget): invisible 不可視ウィジェットを TryIt.vue マウント時にレンダ、submit 直前に turnstile.execute() で 1-shot トークン取得。トークンは 5 分有効・1 回限りなので毎 pack で reset → execute。
rejected(form-field-token): cfTurnstileToken を FormData に入れる案 — packRequestSchema が strict object のため新フィールド追加が必要、ビジネスロジックと認証が混ざる。
rejected(asn-block): Tencent Cloud SG (AS132203) WAF ブロック — バルク部分には効くが residential proxy 部分(家庭 ISP・モバイル・大学ネット)が世界中に散らばっており ASN 単位で弾けない、正規ユーザを巻き込むリスク。
rejected(daily-limit-tightening): 30 → 10/day per IP — IP 数で水増しできる相手には無意味、人間ユーザの体験のみ悪化。
constraint(observability): outcome="turnstile_failed" として既存の pack_completed イベントに乗せる。新 metric 不要、既存ダッシュボードに自動で reject reason として現れる。
learned(rate-limit-effectiveness): スパイク期間中の SG pack 成功率は 0.15% (32/21,501)。app-level rate limit は処理は止めていたが入口の負荷(TCP/TLS/Upstash check)は受けていた。Turnstile は CDN 層に近く、より早く弾ける利点がある。

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-03 21:41:04 +09:00
Kazuki Yamada 902f87d353 feat(website): Stream pack progress via NDJSON
Add real-time progress streaming to the pack endpoint using Hono's
stream() helper with NDJSON format. Users now see stage-specific
messages during processing instead of a static "Processing repository..."

Server changes:
- packAction uses Hono stream() with NDJSON (one JSON per line)
- processRemoteRepo split into git clone + runDefaultAction for
  separate cloning/processing stages
- processZipFile reports extracting/processing stages
- Content-Encoding: identity skips compress for real-time delivery

Client changes:
- packRepository parses NDJSON stream with onProgress callback
- TryItLoading displays stage messages (Checking cache, Cloning
  repository, Processing files, etc.)
- message field prepared for future detailed progress from pack()

Progress stages:
- URL: cache-check → cloning → processing → result
- ZIP: extracting → processing → result

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-06 22:08:48 +09:00
Kazuki Yamada 7ea89f7fd0 fix(website): Remove Vue dependency from cliCommand utility to fix CI
Define CliCommandPackOptions interface locally in cliCommand.ts instead of
importing PackOptions from usePackOptions.ts which depends on Vue module.
This prevents tsc from following the import chain to Vue in CI.
2026-02-03 00:06:09 +09:00
Kazuki Yamada 62280a6870 fix(website): Add shell escaping and ZIP upload handling to CLI command generator
Address PR review comments:
- Add shell escaping for user-controlled values (repositoryUrl, includePatterns, ignorePatterns)
  to prevent command injection when users copy-paste the generated command
- Skip --remote flag for uploaded file names by validating with isValidRemoteValue
- Add unit tests for generateCliCommand covering all option combinations
2026-02-02 00:21:16 +09:00
Kazuki Yamada a7bbf13172 feat(website): Add CLI command banner to result page
Display equivalent CLI command in result page to encourage npm usage.
The banner shows the npx command with all selected options, allowing
users to easily copy and run the same pack locally.

- Add generateCliCommand utility for consistent command generation
- Share command generation logic between result and error pages
- Style as prominent banner with gradient background
2026-02-02 00:18:26 +09:00
Kazuki Yamada 12ea47b472 refactor(website): address PR review feedback for type safety and code quality
Improve type safety and code quality based on PR review comments:
- Convert PackButton.vue to TypeScript with proper type definitions
- Fix AbortSignal.reason comparison using strict equality instead of String()
- Extract magic number constant for API timeout in server configuration

These changes enhance type safety, improve code robustness, and increase
maintainability as suggested by automated code reviewers.
2025-09-23 22:04:20 +09:00
Kazuki Yamada d9e141ec65 feat(website): add cancel functionality for pack requests
Implement cancel button for pack requests with improved user experience.
The button now shows "Cancel" on hover during processing and allows users
to abort ongoing requests. Also improved error messages for better clarity.

- Add cancel functionality to PackButton with hover state
- Implement request cancellation using AbortController
- Improve error messages for remote repository processing failures
- Update timeout handling and server configuration
- Add proper event handling to prevent form submission conflicts
2025-09-23 19:52:10 +09:00
Kazuki Yamada b6a4174c93 feat(website): improve timeout handling with warning display
- Add onAbort callback to distinguish timeouts from errors
- Implement errorType system to differentiate warnings from errors
- Update TryItResultErrorContent to show warning styling for timeouts
- Change timeout message to suggest using Include/Ignore Patterns
- Timeout now displays with yellow warning icon instead of red error
2025-09-23 18:37:57 +09:00
Kazuki Yamada b7fe6f25c5 fix(lint): resolve all oxlint warnings for code quality
- Remove unused imports across 67 files (RepomixConfigMerged, QueryCapture, etc.)
- Fix unused parameters by prefixing with underscore (_context, _index, etc.)
- Remove unused catch parameters using modern JavaScript syntax
- Fix require-yield warnings in generator functions
- Remove unused variables and interface declarations
- Add oxlint configuration to ignore integration test fixtures

Resolves 144 linting warnings while preserving all functionality.
All 743 tests continue to pass. Code quality significantly improved.
2025-08-24 18:25:08 +09:00
Kazuki Yamada 3fe7ed6fd6 feat(linter): integrate oxlint into lint pipeline
- Add oxlint as dev dependency and integrate into npm run lint
- Create oxlint configuration with warning levels for gradual adoption
- Add oxlint CI job to GitHub Actions
- Fix regex patterns flagged by oxlint:
  - Remove unnecessary escape characters in file regex patterns
  - Fix regex patterns in website validation and PHP test files
- Update lint script order: biome -> oxlint -> ts -> secretlint

oxlint provides 50-100x faster linting with 500+ rules from ESLint ecosystem.
Current warnings are configured as non-blocking to allow gradual improvement.
2025-08-24 18:25:08 +09:00
Kazuki Yamada b4aece2499 fix: use optional chaining for navigator.canShare
Apply Biome lint fix to use optional chaining instead of logical AND for safer navigation method access.

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-05-30 23:53:45 +09:00
Kazuki Yamada 4aa26539ef refactor: share files without title or text for cleaner sharing
Remove title and text properties from shareData to share only the file content, providing a cleaner sharing experience for mobile apps.

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-05-30 23:42:16 +09:00
Kazuki Yamada 521d71024f feat: revert to file-based sharing for better mobile app integration
- Restore file sharing capability using Web Share API with File objects
- Implement proper feature detection with navigator.canShare
- Use appropriate MIME types for markdown, XML, and plain text files
- Generate descriptive filenames based on repository and format

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-05-30 23:38:19 +09:00
Kazuki Yamada 0131a96101 refactor: address code review feedback for Web Share API
- Rename canShareFiles to canShareText for accuracy
- Add console logging for failed share attempts
- Improve function naming to reflect text-only sharing capability

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-05-30 23:23:22 +09:00
Kazuki Yamada f472793492 refactor: simplify Web Share API to text-only sharing
- Change from file sharing to text content sharing for better compatibility
- Simplify feature detection to check navigator.share existence only
- Improve button layout with flex-wrap and proper line break on mobile
- Update package.json lint scripts in client and server

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-05-30 22:57:49 +09:00
Kazuki Yamada 8e044257b0 feat: improve Web Share API implementation based on PR feedback
- Test actual file sharing capability with dummy file in canShareFiles()
- Use format-specific MIME types (text/markdown, application/xml)
- Add fallback to text-only sharing when file sharing is not supported
- Enhance compatibility across different platforms and browsers

Addresses feedback from Gemini Code Assist and Copilot reviewers

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-05-30 22:47:26 +09:00
Kazuki Yamada 1af025a97a feat: improve Web Share API implementation with mobile-only display
- Restrict share button to mobile devices only using CSS media queries
- Add robust feature detection with canShareFiles() function
- Implement user feedback with "Shared\!" state and visual styling
- Improve API validation using navigator.canShare() before sharing
- Enhance error handling and code organization
- Rename shareWithApp to shareResult for better consistency

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-05-30 22:04:18 +09:00
Kazuki Yamada 5109f3529d feat(website): implement compress functionality on website 2025-04-02 23:23:34 +09:00
yamadashy 86f7e526d9 feat(website): Include repository name in the file name to download the output 2025-02-23 16:38:14 +09:00
paperboardofficial 87d7204be0 lint changes 2025-02-19 00:04:27 +09:00
paperboardofficial 9dd7407b88 added zip file processing feature 2025-02-19 00:04:27 +09:00
Yamada Dev 9d2df19334 refactor(website): Split TryIt.vue as it is getting bloated 2025-01-25 22:31:00 +09:00
Yamada Dev 14aaf980c6 feat(website): Improve performance of large repository output using Ace Editor 2025-01-25 17:17:31 +09:00
Yamada Dev 34301ebda0 feat(website): Add parsableStyle option 2025-01-20 22:30:37 +09:00
Kazuki Yamada 6a3704363d refact(website): Changed folder structure for multi-language support in documentation 2025-01-14 00:05:30 +09:00