1
0
This commit is contained in:
2026-01-20 15:15:36 +09:00
commit 6e857d8305
26 changed files with 1117 additions and 0 deletions

26
.claude/.gitignore vendored Normal file
View File

@@ -0,0 +1,26 @@
# Environment files
.env
.env.local
.env.*.local
# API keys
*.key
*.pem
secrets.json
# OS files
.DS_Store
Thumbs.db
# Editor files
.idea/
.vscode/
*.swp
*.swo
# Node
node_modules/
# Personal configs (if any)
personal/
private/

View File

@@ -0,0 +1,51 @@
---
name: build-error-resolver
description: ビルドエラーを解決。ビルド失敗時に使用。
tools: Read, Write, Edit, Bash, Grep, Glob
model: sonnet
---
# ビルドエラー解決エージェント
## 役割
ビルドエラーを最小限の変更で修正する。
## 対応エラー
### Rust
```bash
cargo build
cargo check
cargo clippy
```
- コンパイルエラー
- 型エラー
- ライフタイムエラー
### TypeScript
```bash
npx tsc --noEmit
npm run build
```
- 型エラー
- import エラー
### Docker/K8s
```bash
docker build .
kubectl apply --dry-run
```
## 修正手順
1. エラーメッセージを解析
2. 該当ファイルを特定
3. 最小限の修正を適用
4. 再ビルドで確認
## 原則
- 最小差分で修正
- 構造変更は避ける
- エラー修正のみに集中

View File

@@ -0,0 +1,44 @@
---
name: code-reviewer
description: コードレビュー。コード変更後に自動実行。
tools: Read, Grep, Glob, Bash
model: sonnet
---
# コードレビューエージェント
## 起動時の動作
1. `git diff` で変更を確認
2. 変更ファイルをレビュー
3. 問題点を報告
## チェックリスト
### Critical (必須修正)
- ハードコードされたシークレット
- 未処理のエラー
- セキュリティ脆弱性
### Warning (推奨修正)
- 大きすぎる関数 (>50行)
- 深いネスト (>4段階)
- 重複コード
### Info (検討事項)
- パフォーマンス改善の余地
- より良い命名
## 出力形式
```
[CRITICAL] 問題の種類
File: path/to/file:42
Issue: 問題の説明
Fix: 修正方法
```
## 判定基準
- Approve: Critical/Warning なし
- Request Changes: Critical あり

46
.claude/agents/planner.md Normal file
View File

@@ -0,0 +1,46 @@
---
name: planner
description: 実装計画を作成。複雑な機能追加やリファクタリング時に使用。
tools: Read, Grep, Glob
model: sonnet
---
# 実装計画エージェント
## 役割
- 要件を分析し、実装計画を作成
- 依存関係とリスクを特定
- 段階的な実装手順を提案
## 計画フォーマット
```markdown
# 実装計画: [機能名]
## 概要
[2-3文の要約]
## 実装ステップ
### Phase 1: [フェーズ名]
1. [ファイル: path/to/file]
- 変更内容
- 理由
### Phase 2: [フェーズ名]
...
## リスク
- [リスク]: [対策]
## 完了条件
- [ ] 条件1
- [ ] 条件2
```
## 原則
- 既存コードの拡張を優先(書き直しより)
- 各ステップは検証可能に
- 最小限の変更で目的を達成

View File

@@ -0,0 +1,36 @@
---
description: ビルドエラーを順次修正
---
# /build-fix コマンド
ビルドエラーを1つずつ修正。
## 対応コマンド
```bash
# Rust
cargo build
cargo check
# TypeScript
npm run build
npx tsc --noEmit
# Docker
docker build .
```
## 動作
1. ビルド実行
2. エラーを解析
3. 1つずつ修正
4. 再ビルドで確認
5. 全エラー解消まで繰り返し
## 停止条件
- 同じエラーが3回続く
- 修正で新エラー発生
- ユーザーが停止要求

View File

@@ -0,0 +1,36 @@
---
description: コード変更をレビュー
---
# /code-review コマンド
未コミットの変更をレビュー。
## チェック項目
### Critical (必須修正)
- ハードコードされたシークレット
- SQLインジェクション
- 未処理エラー
### Warning (推奨修正)
- 大きすぎる関数 (>50行)
- 深いネスト (>4段階)
- console.log残り
## 出力
```
[CRITICAL] src/lib/api.rs:42
Issue: ハードコードされたAPIキー
Fix: 環境変数を使用
[WARNING] src/main.rs:120
Issue: 関数が80行を超過
Fix: 分割を検討
```
## 判定
- Approve: Critical/Warningなし
- Block: Criticalあり

39
.claude/commands/plan.md Normal file
View File

@@ -0,0 +1,39 @@
---
description: 実装計画を作成。コード作成前にユーザー確認を待つ。
---
# /plan コマンド
plannerエージェントを起動して実装計画を作成。
## 動作
1. 要件を整理して明確化
2. フェーズに分割
3. リスクを特定
4. **ユーザー確認を待つ**(コードは書かない)
## 使用タイミング
- 新機能追加
- 複雑なリファクタリング
- 複数ファイルにまたがる変更
## 出力例
```markdown
# 実装計画: [機能名]
## 概要
...
## フェーズ
### Phase 1: ...
### Phase 2: ...
## リスク
- HIGH: ...
- MEDIUM: ...
確認: 続行しますか? (yes/no/modify)
```

39
.claude/hooks/hooks.json Normal file
View File

@@ -0,0 +1,39 @@
{
"$schema": "https://json.schemastore.org/claude-code-settings.json",
"hooks": {
"PreToolUse": [
{
"matcher": "tool == \"Bash\" && tool_input.command matches \"(cargo build|cargo run|npm run dev|docker compose up)\"",
"hooks": [
{
"type": "command",
"command": "#!/bin/bash\ninput=$(cat)\nif [ -z \"$TMUX\" ]; then\n echo '[Hook] tmux推奨: tmux new -s dev' >&2\nfi\necho \"$input\""
}
],
"description": "長時間コマンドでtmux推奨"
}
],
"PostToolUse": [
{
"matcher": "tool == \"Edit\" && tool_input.file_path matches \"\\\\.rs$\"",
"hooks": [
{
"type": "command",
"command": "#!/bin/bash\ninput=$(cat)\nfile_path=$(echo \"$input\" | jq -r '.tool_input.file_path // \"\"')\nif [ -n \"$file_path\" ] && [ -f \"$file_path\" ]; then\n if command -v rustfmt >/dev/null 2>&1; then\n rustfmt \"$file_path\" 2>/dev/null || true\n fi\nfi\necho \"$input\""
}
],
"description": "Rustファイル編集後にrustfmt"
},
{
"matcher": "tool == \"Edit\" && tool_input.file_path matches \"\\\\.(ts|tsx)$\"",
"hooks": [
{
"type": "command",
"command": "#!/bin/bash\ninput=$(cat)\nfile_path=$(echo \"$input\" | jq -r '.tool_input.file_path // \"\"')\nif [ -n \"$file_path\" ] && [ -f \"$file_path\" ]; then\n if command -v prettier >/dev/null 2>&1; then\n prettier --write \"$file_path\" 2>/dev/null || true\n fi\nfi\necho \"$input\""
}
],
"description": "TypeScript編集後にprettier"
}
]
}
}

26
.claude/rules/agents.md Normal file
View File

@@ -0,0 +1,26 @@
# Agents
## 利用可能なエージェント
| Agent | 用途 | 起動タイミング |
|-------|------|---------------|
| planner | 実装計画 | 複雑な機能追加時 |
| code-reviewer | コードレビュー | コード変更後 |
| build-error-resolver | ビルドエラー修正 | ビルド失敗時 |
## 自動起動ルール
- 複雑な機能要求 → **planner**
- コード変更完了 → **code-reviewer**
- ビルドエラー → **build-error-resolver**
## 並列実行
独立したタスクは並列で実行:
```markdown
# 良い例: 並列実行
1. Agent 1: セキュリティ分析
2. Agent 2: パフォーマンスレビュー
3. Agent 3: 型チェック
```

View File

@@ -0,0 +1,63 @@
# Coding Style
## Rust
### 基本原則
- `clippy` の警告は全て対処する
- `cargo fmt` でフォーマット統一
- `unwrap()` は避け、`?` または `expect("理由")` を使う
- エラー型は `thiserror` で定義
### パターン
```rust
// Result型の活用
fn process() -> Result<Data, Error> {
let value = fetch_data()?;
Ok(transform(value))
}
// Builder パターン
let config = Config::builder()
.timeout(30)
.retry(3)
.build()?;
```
## TypeScript
### 基本原則
- 型は明示的に定義(`any` 禁止)
- immutableパターンを優先
- `console.log` は本番コードに残さない
### パターン
```typescript
// 型定義
interface User {
id: string
name: string
createdAt: Date
}
// immutable更新
const updated = { ...user, name: newName }
```
## ATProtocol
### Lexicon
- スキーマは `lexicons/` に配置
- NSIDは `app.bsky.*` または独自ドメイン
### PDS/AppView
```typescript
// XRPC呼び出し
const response = await agent.api.app.bsky.feed.getTimeline()
```
## 共通ルール
- ファイルは400行以下を目安
- 関数は50行以下
- ネストは4段階まで
- マジックナンバー禁止(定数化)

View File

@@ -0,0 +1,55 @@
# Git Workflow
## コミットメッセージ
```
<type>: <description>
<optional body>
```
### Type一覧
- `feat`: 新機能
- `fix`: バグ修正
- `refactor`: リファクタリング
- `docs`: ドキュメント
- `test`: テスト
- `chore`: 雑務(依存関係更新等)
### 例
```
feat: add user authentication
- JWT token generation
- Login/logout endpoints
- Session management
```
## ブランチ戦略
```
main
└── feature/xxx
└── fix/xxx
```
## PRワークフロー
1. featureブランチ作成
2. 変更をコミット
3. `gh pr create` でPR作成
4. レビュー後マージ
## 便利コマンド
```bash
# 直近のコミットを修正
git commit --amend
# 対話的リベース
git rebase -i HEAD~3
# stash
git stash
git stash pop
```

58
.claude/rules/security.md Normal file
View File

@@ -0,0 +1,58 @@
# Security
## 必須チェック
コミット前に確認:
- [ ] シークレットがハードコードされていない
- [ ] 環境変数で機密情報を管理
- [ ] ユーザー入力はバリデーション済み
- [ ] SQLはパラメータ化クエリを使用
## Rust
```rust
// 環境変数の取得
let api_key = std::env::var("API_KEY")
.expect("API_KEY must be set");
// 入力バリデーション
fn validate_input(s: &str) -> Result<&str, Error> {
if s.len() > MAX_LENGTH {
return Err(Error::TooLong);
}
Ok(s)
}
```
## TypeScript
```typescript
// 環境変数
const apiKey = process.env.API_KEY
if (!apiKey) throw new Error('API_KEY required')
// zodでバリデーション
const schema = z.object({
email: z.string().email(),
age: z.number().min(0).max(150)
})
```
## Git
シークレットを誤ってコミットした場合:
```bash
# 履歴から削除
git filter-branch --force --index-filter \
'git rm --cached --ignore-unmatch path/to/secret' HEAD
```
## .gitignore必須項目
```
.env
.env.local
*.pem
*.key
secrets/
```

57
.claude/rules/testing.md Normal file
View File

@@ -0,0 +1,57 @@
# Testing
## Rust
```bash
# テスト実行
cargo test
# カバレッジ
cargo tarpaulin --out Html
```
```rust
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_basic() {
let result = process("input");
assert_eq!(result, expected);
}
#[tokio::test]
async fn test_async() {
let result = fetch().await.unwrap();
assert!(result.is_valid());
}
}
```
## TypeScript
```bash
# Vitest / Jest
npm test
npm run test:coverage
```
```typescript
describe('module', () => {
it('should work', () => {
expect(fn('input')).toBe('output')
})
})
```
## TDDワークフロー
1. テストを先に書くRED
2. 最小限の実装GREEN
3. リファクタREFACTOR
## カバレッジ目標
- 新規コード: 80%以上
- クリティカルパス: 100%

View File

@@ -0,0 +1,7 @@
{
"permissions": {
"allow": [
"Bash(find:*)"
]
}
}

3
.github/FUNDING.yml vendored Normal file
View File

@@ -0,0 +1,3 @@
# These are supported funding model platforms
github: syui

7
.gitignore vendored Normal file
View File

@@ -0,0 +1,7 @@
public
.DS_Store
*/.DS_Store
*/*/.DS_Store
*/*/*/.DS_Store
*/*/*/*/.DS_Store
*/*/*/*/*/.DS_Store

22
anim/syui.ai.css.svg Normal file
View File

@@ -0,0 +1,22 @@
<svg width="77pt" height="77pt" viewBox="0 0 512 512" class="likeButton" >
<circle class="explosion" r="150" cx="250" cy="250"></circle>
<g class="particleLayer">
<circle fill="#ef454aba" cx="130" cy="126.5" r="12.5"/>
<circle fill="#ef454acc" cx="411" cy="313.5" r="12.5"/>
<circle fill="#ef454aba" cx="279" cy="86.5" r="12.5"/>
<circle fill="#ef454aba" cx="155" cy="390.5" r="12.5"/>
<circle fill="#ef454aba" cx="89" cy="292.5" r="10.5"/>
<circle fill="#ef454aba" cx="414" cy="282.5" r="10.5"/>
<circle fill="#ef454a91" cx="115" cy="149.5" r="10.5"/>
<circle fill="#ef454aba" cx="250" cy="80.5" r="10.5"/>
<circle fill="#ef454aba" cx="78" cy="261.5" r="10.5"/>
<circle fill="#ef454a91" cx="182" cy="402.5" r="10.5"/>
<circle fill="#ef454aba" cx="401.5" cy="166" r="13"/>
<circle fill="#ef454aba" cx="379" cy="141.5" r="10.5"/>
<circle fill="#ef454a91" cx="327" cy="397.5" r="10.5"/>
<circle fill="#ef454aba" cx="296" cy="392.5" r="10.5"/>
</g>
<g transform="translate(0,512) scale(0.1,-0.1)" fill="#000000" class="icon_syui">
<path class="syui" d="M3660 4460 c-11 -11 -33 -47 -48 -80 l-29 -60 -12 38 c-27 88 -58 92 -98 11 -35 -70 -73 -159 -73 -169 0 -6 -5 -10 -10 -10 -6 0 -15 -10 -21 -22 -33 -73 -52 -92 -47 -48 2 26 -1 35 -14 38 -16 3 -168 -121 -168 -138 0 -5 -13 -16 -28 -24 -24 -13 -35 -12 -87 0 -221 55 -231 56 -480 56 -219 1 -247 -1 -320 -22 -44 -12 -96 -26 -115 -30 -57 -13 -122 -39 -200 -82 -8 -4 -31 -14 -50 -23 -41 -17 -34 -13 -146 -90 -87 -59 -292 -252 -351 -330 -63 -83 -143 -209 -143 -225 0 -10 -7 -23 -15 -30 -8 -7 -15 -17 -15 -22 0 -5 -13 -37 -28 -71 -16 -34 -36 -93 -45 -132 -9 -38 -24 -104 -34 -145 -13 -60 -17 -121 -17 -300 1 -224 1 -225 36 -365 24 -94 53 -175 87 -247 28 -58 51 -108 51 -112 0 -3 13 -24 28 -48 42 -63 46 -79 22 -85 -11 -3 -20 -9 -20 -14 0 -5 -4 -9 -10 -9 -5 0 -22 -11 -37 -25 -16 -13 -75 -59 -133 -100 -58 -42 -113 -82 -123 -90 -9 -8 -22 -15 -27 -15 -6 0 -10 -6 -10 -13 0 -8 -11 -20 -25 -27 -34 -18 -34 -54 0 -48 14 3 25 2 25 -1 0 -3 -43 -31 -95 -61 -52 -30 -95 -58 -95 -62 0 -5 -5 -8 -11 -8 -19 0 -84 -33 -92 -47 -4 -7 -15 -13 -22 -13 -14 0 -17 -4 -19 -32 -1 -8 15 -15 37 -18 l38 -5 -47 -48 c-56 -59 -54 -81 9 -75 30 3 45 0 54 -11 9 -13 16 -14 43 -4 29 11 30 10 18 -5 -7 -9 -19 -23 -25 -30 -7 -7 -13 -20 -13 -29 0 -12 8 -14 38 -9 20 4 57 8 82 9 25 2 54 8 66 15 18 10 23 8 32 -13 17 -38 86 -35 152 6 27 17 50 34 50 38 0 16 62 30 85 19 33 -15 72 -2 89 30 8 15 31 43 51 62 35 34 38 35 118 35 77 0 85 2 126 33 24 17 52 32 61 32 9 0 42 18 73 40 30 22 61 40 69 40 21 0 88 -26 100 -38 7 -7 17 -12 24 -12 7 0 35 -11 62 -25 66 -33 263 -84 387 -101 189 -25 372 -12 574 41 106 27 130 37 261 97 41 20 80 37 85 39 6 2 51 31 100 64 166 111 405 372 489 534 10 20 22 43 27 51 5 8 12 22 15 30 3 8 17 40 31 70 54 115 95 313 108 520 13 200 -43 480 -134 672 -28 58 -51 108 -51 112 0 3 -13 24 -29 48 -15 24 -34 60 -40 80 -19 57 3 142 50 193 10 11 22 49 28 85 6 36 16 67 21 68 18 6 31 53 25 83 -4 18 -17 33 -36 41 -16 7 -29 15 -29 18 1 10 38 50 47 50 5 0 20 11 33 25 18 19 22 31 17 61 -3 20 -14 45 -23 55 -16 18 -16 20 6 44 15 16 21 32 18 49 -3 15 1 34 8 43 32 43 7 73 -46 55 l-30 -11 0 85 c0 74 -2 84 -18 84 -21 0 -53 -33 -103 -104 l-34 -48 -5 74 c-7 102 -35 133 -80 88z m-870 -740 c36 -7 75 -14 88 -16 21 -4 23 -9 16 -37 -3 -18 -14 -43 -24 -57 -10 -14 -20 -35 -24 -46 -4 -12 -16 -32 -27 -45 -12 -13 -37 -49 -56 -79 -20 -30 -52 -73 -72 -96 -53 -60 -114 -133 -156 -189 -21 -27 -44 -54 -52 -58 -7 -4 -13 -14 -13 -22 0 -7 -18 -33 -40 -57 -22 -23 -40 -46 -40 -50 0 -5 -19 -21 -42 -38 -47 -35 -85 -38 -188 -15 -115 25 -173 20 -264 -23 -45 -22 -106 -46 -136 -56 -48 -15 -77 -25 -140 -50 -70 -28 -100 -77 -51 -84 14 -2 34 -10 45 -17 12 -7 53 -16 91 -20 90 -9 131 -22 178 -57 20 -16 52 -35 70 -43 18 -7 40 -22 49 -32 16 -18 15 -22 -24 -88 -23 -39 -47 -74 -53 -80 -7 -5 -23 -26 -36 -45 -26 -39 -92 -113 -207 -232 -4 -4 -37 -36 -73 -71 l-66 -64 -20 41 c-58 119 -105 240 -115 301 -40 244 -35 409 20 595 8 30 21 66 28 80 7 14 24 54 38 89 15 35 35 75 46 89 11 13 20 31 20 38 0 8 3 14 8 14 4 0 16 16 27 36 24 45 221 245 278 281 23 15 44 30 47 33 20 20 138 78 250 123 61 24 167 50 250 61 60 7 302 -1 370 -14z m837 -661 c52 -101 102 -279 106 -379 2 -42 0 -45 -28 -51 -16 -4 -101 -7 -187 -8 -166 -1 -229 10 -271 49 -19 19 -19 19 14 49 22 21 44 31 65 31 41 0 84 34 84 66 0 30 12 55 56 112 19 25 37 65 44 95 11 51 53 111 74 104 6 -2 25 -32 43 -68z m-662 -810 c17 -10 40 -24 53 -30 12 -7 22 -16 22 -20 0 -4 17 -13 38 -19 20 -7 44 -18 52 -24 8 -7 33 -21 55 -31 22 -11 42 -23 45 -26 11 -14 109 -49 164 -58 62 -11 101 -7 126 14 15 14 38 18 78 16 39 -2 26 -41 -49 -146 -78 -109 -85 -118 -186 -219 -61 -61 -239 -189 -281 -203 -17 -5 -73 -29 -104 -44 -187 -92 -605 -103 -791 -21 -42 19 -47 24 -37 41 5 11 28 32 51 48 22 15 51 38 64 51 13 12 28 22 33 22 17 0 242 233 242 250 0 6 5 10 10 10 6 0 10 6 10 14 0 25 50 55 100 62 59 8 56 6 115 83 50 66 74 117 75 162 0 14 7 40 16 57 18 38 52 41 99 11z"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 4.8 KiB

74
anim/syui.ai.planet.svg Normal file
View File

@@ -0,0 +1,74 @@
<?xml version="1.0" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 20010904//EN"
"http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd">
<svg version="1.0" xmlns="http://www.w3.org/2000/svg"
width="512.000000pt" height="512.000000pt" viewBox="0 0 512.000000 512.000000"
preserveAspectRatio="xMidYMid meet">
<metadata>
syui
</metadata>
<g transform="translate(0.000000,512.000000) scale(0.100000,-0.100000)"
fill="#000000" stroke="none">
<path d="M3660 4460 c-11 -11 -33 -47 -48 -80 l-29 -60 -12 38 c-27 88 -58 92
-98 11 -35 -70 -73 -159 -73 -169 0 -6 -5 -10 -10 -10 -6 0 -15 -10 -21 -22
-33 -73 -52 -92 -47 -48 2 26 -1 35 -14 38 -16 3 -168 -121 -168 -138 0 -5
-13 -16 -28 -24 -24 -13 -35 -12 -87 0 -221 55 -231 56 -480 56 -219 1 -247
-1 -320 -22 -44 -12 -96 -26 -115 -30 -57 -13 -122 -39 -200 -82 -8 -4 -31
-14 -50 -23 -41 -17 -34 -13 -146 -90 -87 -59 -292 -252 -351 -330 -63 -83
-143 -209 -143 -225 0 -10 -7 -23 -15 -30 -8 -7 -15 -17 -15 -22 0 -5 -13 -37
-28 -71 -16 -34 -36 -93 -45 -132 -9 -38 -24 -104 -34 -145 -13 -60 -17 -121
-17 -300 1 -224 1 -225 36 -365 24 -94 53 -175 87 -247 28 -58 51 -108 51
-112 0 -3 13 -24 28 -48 42 -63 46 -79 22 -85 -11 -3 -20 -9 -20 -14 0 -5 -4
-9 -10 -9 -5 0 -22 -11 -37 -25 -16 -13 -75 -59 -133 -100 -58 -42 -113 -82
-123 -90 -9 -8 -22 -15 -27 -15 -6 0 -10 -6 -10 -13 0 -8 -11 -20 -25 -27 -34
-18 -34 -54 0 -48 14 3 25 2 25 -1 0 -3 -43 -31 -95 -61 -52 -30 -95 -58 -95
-62 0 -5 -5 -8 -11 -8 -19 0 -84 -33 -92 -47 -4 -7 -15 -13 -22 -13 -14 0 -17
-4 -19 -32 -1 -8 15 -15 37 -18 l38 -5 -47 -48 c-56 -59 -54 -81 9 -75 30 3
45 0 54 -11 9 -13 16 -14 43 -4 29 11 30 10 18 -5 -7 -9 -19 -23 -25 -30 -7
-7 -13 -20 -13 -29 0 -12 8 -14 38 -9 20 4 57 8 82 9 25 2 54 8 66 15 18 10
23 8 32 -13 17 -38 86 -35 152 6 27 17 50 34 50 38 0 16 62 30 85 19 33 -15
72 -2 89 30 8 15 31 43 51 62 35 34 38 35 118 35 77 0 85 2 126 33 24 17 52
32 61 32 9 0 42 18 73 40 30 22 61 40 69 40 21 0 88 -26 100 -38 7 -7 17 -12
24 -12 7 0 35 -11 62 -25 66 -33 263 -84 387 -101 189 -25 372 -12 574 41 106
27 130 37 261 97 41 20 80 37 85 39 6 2 51 31 100 64 166 111 405 372 489 534
10 20 22 43 27 51 5 8 12 22 15 30 3 8 17 40 31 70 54 115 95 313 108 520 13
200 -43 480 -134 672 -28 58 -51 108 -51 112 0 3 -13 24 -29 48 -15 24 -34 60
-40 80 -19 57 3 142 50 193 10 11 22 49 28 85 6 36 16 67 21 68 18 6 31 53 25
83 -4 18 -17 33 -36 41 -16 7 -29 15 -29 18 1 10 38 50 47 50 5 0 20 11 33 25
18 19 22 31 17 61 -3 20 -14 45 -23 55 -16 18 -16 20 6 44 15 16 21 32 18 49
-3 15 1 34 8 43 32 43 7 73 -46 55 l-30 -11 0 85 c0 74 -2 84 -18 84 -21 0
-53 -33 -103 -104 l-34 -48 -5 74 c-7 102 -35 133 -80 88z m-870 -740 c36 -7
75 -14 88 -16 21 -4 23 -9 16 -37 -3 -18 -14 -43 -24 -57 -10 -14 -20 -35 -24
-46 -4 -12 -16 -32 -27 -45 -12 -13 -37 -49 -56 -79 -20 -30 -52 -73 -72 -96
-53 -60 -114 -133 -156 -189 -21 -27 -44 -54 -52 -58 -7 -4 -13 -14 -13 -22 0
-7 -18 -33 -40 -57 -22 -23 -40 -46 -40 -50 0 -5 -19 -21 -42 -38 -47 -35 -85
-38 -188 -15 -115 25 -173 20 -264 -23 -45 -22 -106 -46 -136 -56 -48 -15 -77
-25 -140 -50 -70 -28 -100 -77 -51 -84 14 -2 34 -10 45 -17 12 -7 53 -16 91
-20 90 -9 131 -22 178 -57 20 -16 52 -35 70 -43 18 -7 40 -22 49 -32 16 -18
15 -22 -24 -88 -23 -39 -47 -74 -53 -80 -7 -5 -23 -26 -36 -45 -26 -39 -92
-113 -207 -232 -4 -4 -37 -36 -73 -71 l-66 -64 -20 41 c-58 119 -105 240 -115
301 -40 244 -35 409 20 595 8 30 21 66 28 80 7 14 24 54 38 89 15 35 35 75 46
89 11 13 20 31 20 38 0 8 3 14 8 14 4 0 16 16 27 36 24 45 221 245 278 281 23
15 44 30 47 33 20 20 138 78 250 123 61 24 167 50 250 61 60 7 302 -1 370 -14z
m837 -661 c52 -101 102 -279 106 -379 2 -42 0 -45 -28 -51 -16 -4 -101 -7
-187 -8 -166 -1 -229 10 -271 49 -19 19 -19 19 14 49 22 21 44 31 65 31 41 0
84 34 84 66 0 30 12 55 56 112 19 25 37 65 44 95 11 51 53 111 74 104 6 -2 25
-32 43 -68z m-662 -810 c17 -10 40 -24 53 -30 12 -7 22 -16 22 -20 0 -4 17
-13 38 -19 20 -7 44 -18 52 -24 8 -7 33 -21 55 -31 22 -11 42 -23 45 -26 11
-14 109 -49 164 -58 62 -11 101 -7 126 14 15 14 38 18 78 16 39 -2 26 -41 -49
-146 -78 -109 -85 -118 -186 -219 -61 -61 -239 -189 -281 -203 -17 -5 -73 -29
-104 -44 -187 -92 -605 -103 -791 -21 -42 19 -47 24 -37 41 5 11 28 32 51 48
22 15 51 38 64 51 13 12 28 22 33 22 17 0 242 233 242 250 0 6 5 10 10 10 6 0
10 6 10 14 0 25 50 55 100 62 59 8 56 6 115 83 50 66 74 117 75 162 0 14 7 40
16 57 18 38 52 41 99 11z" fill="#EF454A"/>
</g>
<g transform="scale(3 3) matrix(0.866, -0.5, 0.25, 0.433, 85, 85)" >
<path d="M 0,70 A 65,70 0 0,0 65,0 5,5 0 0,1 75,0 75,70 0 0,1 0,70Z" fill="#FF6633" >
<animateTransform attributeName="transform" type="rotate" from="360 0 0" to="0 0 0" dur="1s" repeatCount="indefinite" />
<animate fill="freeze" dur="4000ms" begin="0s" values="#d38eff;#DD6699;#DDDD00;#008ccf" calMode="linear" attributeName="fill" repeatCount="indefinite" />
</path>
</g>
</svg>

After

Width:  |  Height:  |  Size: 4.7 KiB

191
css/svg-animation.css Normal file
View File

@@ -0,0 +1,191 @@
/* SVG Animation Package
* Hover animation for syui.ai icon
* Pure CSS - no JavaScript required
*/
:root {
--syui-color: #ef454a;
--particle-color: #ef454aba;
--explosion-color: #ef454a;
}
/* Core SVG button setup */
.likeButton {
cursor: pointer;
display: inline-block;
}
/* Explosion circle - initially hidden */
.likeButton .explosion {
transform-origin: center center;
transform: scale(1);
stroke: var(--explosion-color);
fill: none;
opacity: 0;
stroke-width: 1;
}
/* Particle layer - initially hidden */
.likeButton .particleLayer {
opacity: 0;
transform: scale(0);
}
.likeButton .particleLayer circle {
opacity: 0;
transform-origin: center center;
transform: scale(0);
}
/* Syui logo */
.likeButton .syui {
fill: var(--syui-color);
transform: scale(1);
transform-origin: center center;
}
/* Hover animations */
.likeButton:hover .explosion {
animation: explosionAnime 800ms forwards;
}
.likeButton:hover .particleLayer {
animation: particleLayerAnime 800ms forwards;
}
.likeButton:hover .syui,
.likeButton:hover path.syui {
animation: syuiDeluxeAnime 400ms forwards;
}
/* Individual particle animations on hover */
.likeButton:hover .particleLayer circle:nth-child(1) { animation: particleAnimate1 800ms forwards; }
.likeButton:hover .particleLayer circle:nth-child(2) { animation: particleAnimate2 800ms forwards; }
.likeButton:hover .particleLayer circle:nth-child(3) { animation: particleAnimate3 800ms forwards; }
.likeButton:hover .particleLayer circle:nth-child(4) { animation: particleAnimate4 800ms forwards; }
.likeButton:hover .particleLayer circle:nth-child(5) { animation: particleAnimate5 800ms forwards; }
.likeButton:hover .particleLayer circle:nth-child(6) { animation: particleAnimate6 800ms forwards; }
.likeButton:hover .particleLayer circle:nth-child(7) { animation: particleAnimate7 800ms forwards; }
.likeButton:hover .particleLayer circle:nth-child(8) { animation: particleAnimate8 800ms forwards; }
.likeButton:hover .particleLayer circle:nth-child(9) { animation: particleAnimate9 800ms forwards; }
.likeButton:hover .particleLayer circle:nth-child(10) { animation: particleAnimate10 800ms forwards; }
.likeButton:hover .particleLayer circle:nth-child(11) { animation: particleAnimate11 800ms forwards; }
.likeButton:hover .particleLayer circle:nth-child(12) { animation: particleAnimate12 800ms forwards; }
.likeButton:hover .particleLayer circle:nth-child(13) { animation: particleAnimate13 800ms forwards; }
.likeButton:hover .particleLayer circle:nth-child(14) { animation: particleAnimate14 800ms forwards; }
/* Keyframe animations */
@keyframes explosionAnime {
0% { opacity: 0; transform: scale(0.01); }
1% { opacity: 1; transform: scale(0.01); }
5% { stroke-width: 200; }
20% { stroke-width: 300; }
50% { stroke: var(--particle-color); transform: scale(1.1); stroke-width: 1; }
50.1% { stroke-width: 0; }
100% { stroke: var(--particle-color); transform: scale(1.1); stroke-width: 0; }
}
@keyframes particleLayerAnime {
0% { transform: translate(0, 0); opacity: 0; }
30% { opacity: 0; }
31% { opacity: 1; }
60% { transform: translate(0, 0); }
70% { opacity: 1; }
100% { opacity: 0; transform: translate(0, -20px); }
}
@keyframes syuiDeluxeAnime {
0% { fill: var(--syui-color); transform: scale(1) translate(0%, 0%); }
40% { fill: #ef454a66; transform: scale(1, 0.9) translate(-9%, 9%); }
50% { fill: #ef454ab3; transform: scale(1, 0.9) translate(-7%, 7%); }
60% { transform: scale(1) translate(-7%, 7%); }
70% { transform: scale(1.04) translate(-5%, 5%); }
80% { fill: #ef454a99; transform: scale(1.04) translate(-5%, 5%); }
90% { fill: #ff6b6b; transform: scale(1) translate(0%); }
100% { fill: var(--syui-color); transform: scale(1, 1) translate(0%, 0%); }
}
/* Individual particle keyframes */
@keyframes particleAnimate1 {
0% { transform: translate(0, 0); }
30% { opacity: 1; transform: translate(0, 0); }
100% { opacity: 1; transform: translate(-16px, -59px); }
}
@keyframes particleAnimate2 {
0% { transform: translate(0, 0); }
30% { opacity: 1; transform: translate(0, 0); }
100% { opacity: 1; transform: translate(41px, 43px); }
}
@keyframes particleAnimate3 {
0% { transform: translate(0, 0); }
30% { opacity: 1; transform: translate(0, 0); }
100% { opacity: 1; transform: translate(50px, -48px); }
}
@keyframes particleAnimate4 {
0% { transform: translate(0, 0); }
30% { opacity: 1; transform: translate(0, 0); }
100% { opacity: 1; transform: translate(-39px, 36px); }
}
@keyframes particleAnimate5 {
0% { transform: translate(0, 0); }
30% { opacity: 1; transform: translate(0, 0); }
100% { opacity: 1; transform: translate(-39px, 32px); }
}
@keyframes particleAnimate6 {
0% { transform: translate(0, 0); }
30% { opacity: 1; transform: translate(0, 0); }
100% { opacity: 1; transform: translate(48px, 6px); }
}
@keyframes particleAnimate7 {
0% { transform: translate(0, 0); }
30% { opacity: 1; transform: translate(0, 0); }
100% { opacity: 1; transform: translate(-69px, -36px); }
}
@keyframes particleAnimate8 {
0% { transform: translate(0, 0); }
30% { opacity: 1; transform: translate(0, 0); }
100% { opacity: 1; transform: translate(-12px, -52px); }
}
@keyframes particleAnimate9 {
0% { transform: translate(0, 0); }
30% { opacity: 1; transform: translate(0, 0); }
100% { opacity: 1; transform: translate(-43px, -21px); }
}
@keyframes particleAnimate10 {
0% { transform: translate(0, 0); }
30% { opacity: 1; transform: translate(0, 0); }
100% { opacity: 1; transform: translate(-10px, 47px); }
}
@keyframes particleAnimate11 {
0% { transform: translate(0, 0); }
30% { opacity: 1; transform: translate(0, 0); }
100% { opacity: 1; transform: translate(66px, -9px); }
}
@keyframes particleAnimate12 {
0% { transform: translate(0, 0); }
30% { opacity: 1; transform: translate(0, 0); }
100% { opacity: 1; transform: translate(40px, -45px); }
}
@keyframes particleAnimate13 {
0% { transform: translate(0, 0); }
30% { opacity: 1; transform: translate(0, 0); }
100% { opacity: 1; transform: translate(29px, 24px); }
}
@keyframes particleAnimate14 {
0% { transform: translate(0, 0); }
30% { opacity: 1; transform: translate(0, 0); }
100% { opacity: 1; transform: translate(-10px, 50px); }
}

121
docs/anim.md Normal file
View File

@@ -0,0 +1,121 @@
# SVG Animation
syui.ai アイコンのホバーアニメーション構築ガイド
## ファイル構成
```
anim/syui.ai.css.svg # アニメーション用SVG
css/svg-animation.css # アニメーション定義CSS
```
## SVG構造
```xml
<svg class="likeButton">
<!-- 爆発エフェクト用の円 -->
<circle class="explosion" r="150" cx="250" cy="250"></circle>
<!-- パーティクル14個の円 -->
<g class="particleLayer">
<circle fill="#ef454aba" cx="130" cy="126.5" r="12.5"/>
<!-- ... 他のパーティクル -->
</g>
<!-- syuiロゴ本体 -->
<g class="icon_syui">
<path class="syui" d="..."/>
</g>
</svg>
```
## 使用方法
### 1. HTMLにCSSを読み込む
```html
<link rel="stylesheet" href="css/svg-animation.css">
```
### 2. SVGをHTMLに埋め込む
```html
<!-- インラインSVG -->
<svg width="77pt" height="77pt" viewBox="0 0 512 512" class="likeButton">
<!-- SVGの内容 -->
</svg>
<!-- または object タグ -->
<object type="image/svg+xml" data="icon/anim/syui.ai.css.svg"></object>
```
## アニメーション要素
### 爆発エフェクトexplosion
ホバー時に中心から広がる円形のストロークアニメーション
```css
@keyframes explosionAnime {
0% { opacity: 0; transform: scale(0.01); }
5% { stroke-width: 200; }
50% { transform: scale(1.1); stroke-width: 1; }
100% { stroke-width: 0; }
}
```
### パーティクルparticleLayer
14個の円がそれぞれ異なる方向に飛び散る
```css
.likeButton:hover .particleLayer circle:nth-child(1) {
animation: particleAnimate1 800ms forwards;
}
```
### ロゴアニメーションsyui
ロゴが縮小→拡大するバウンス効果
```css
@keyframes syuiDeluxeAnime {
40% { transform: scale(1, 0.9) translate(-9%, 9%); }
70% { transform: scale(1.04) translate(-5%, 5%); }
100% { transform: scale(1, 1) translate(0%, 0%); }
}
```
## カスタマイズ
### CSS変数
```css
:root {
--syui-color: #ef454a; /* ロゴの色 */
--particle-color: #ef454aba; /* パーティクルの色 */
--explosion-color: #ef454a; /* 爆発エフェクトの色 */
}
```
### アニメーション時間の変更
```css
.likeButton:hover .explosion {
animation: explosionAnime 1200ms forwards; /* 800ms → 1200ms */
}
```
### パーティクルの移動距離を変更
```css
@keyframes particleAnimate1 {
100% { transform: translate(-32px, -118px); } /* 距離を2倍に */
}
```
## 注意事項
- Pure CSS実装JavaScriptは不要
- `object` タグで読み込む場合、CSSはSVGファイル内または外部参照で適用する必要がある
- インラインSVGの場合、親ドキュメントのCSSがそのまま適用される

28
docs/svg.md Normal file
View File

@@ -0,0 +1,28 @@
# svg
## png to svg conversion (vector trace)
Convert PNG images to true vector SVG using vtracer (Rust):
```bash
# Install vtracer
cargo install vtracer
# Convert PNG to SVG (color mode)
vtracer --input input.png --output output.svg --colormode color
# Convert PNG to SVG (black and white)
vtracer --input input.png --output output.svg
```
**Options:**
- `--colormode color` : Preserve colors (recommended for icons)
- `--colormode binary` : Black and white only
- `--filter_speckle 4` : Remove small artifacts
- `--corner_threshold 60` : Adjust corner detection
**Alternative tools:**
- potrace: `potrace input.pbm -s -o output.svg` (B&W only, requires PBM input)
- Inkscape CLI: `inkscape input.png --export-type=svg` (embeds image, no trace)
**Note:** Inkscape's CLI `--export-type=svg` only embeds the PNG, it does not trace. For true vectorization, use vtracer or potrace.

BIN
icon/ai.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 66 KiB

16
icon/ai.svg Normal file

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 32 KiB

BIN
icon/syui.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 23 KiB

67
icon/syui.svg Normal file
View File

@@ -0,0 +1,67 @@
<?xml version="1.0" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 20010904//EN"
"http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd">
<svg version="1.0" xmlns="http://www.w3.org/2000/svg"
width="512.000000pt" height="512.000000pt" viewBox="0 0 512.000000 512.000000"
preserveAspectRatio="xMidYMid meet">
<metadata>
syui
</metadata>
<g transform="translate(0.000000,512.000000) scale(0.100000,-0.100000)"
fill="#000000" stroke="none">
<path d="M3660 4460 c-11 -11 -33 -47 -48 -80 l-29 -60 -12 38 c-27 88 -58 92
-98 11 -35 -70 -73 -159 -73 -169 0 -6 -5 -10 -10 -10 -6 0 -15 -10 -21 -22
-33 -73 -52 -92 -47 -48 2 26 -1 35 -14 38 -16 3 -168 -121 -168 -138 0 -5
-13 -16 -28 -24 -24 -13 -35 -12 -87 0 -221 55 -231 56 -480 56 -219 1 -247
-1 -320 -22 -44 -12 -96 -26 -115 -30 -57 -13 -122 -39 -200 -82 -8 -4 -31
-14 -50 -23 -41 -17 -34 -13 -146 -90 -87 -59 -292 -252 -351 -330 -63 -83
-143 -209 -143 -225 0 -10 -7 -23 -15 -30 -8 -7 -15 -17 -15 -22 0 -5 -13 -37
-28 -71 -16 -34 -36 -93 -45 -132 -9 -38 -24 -104 -34 -145 -13 -60 -17 -121
-17 -300 1 -224 1 -225 36 -365 24 -94 53 -175 87 -247 28 -58 51 -108 51
-112 0 -3 13 -24 28 -48 42 -63 46 -79 22 -85 -11 -3 -20 -9 -20 -14 0 -5 -4
-9 -10 -9 -5 0 -22 -11 -37 -25 -16 -13 -75 -59 -133 -100 -58 -42 -113 -82
-123 -90 -9 -8 -22 -15 -27 -15 -6 0 -10 -6 -10 -13 0 -8 -11 -20 -25 -27 -34
-18 -34 -54 0 -48 14 3 25 2 25 -1 0 -3 -43 -31 -95 -61 -52 -30 -95 -58 -95
-62 0 -5 -5 -8 -11 -8 -19 0 -84 -33 -92 -47 -4 -7 -15 -13 -22 -13 -14 0 -17
-4 -19 -32 -1 -8 15 -15 37 -18 l38 -5 -47 -48 c-56 -59 -54 -81 9 -75 30 3
45 0 54 -11 9 -13 16 -14 43 -4 29 11 30 10 18 -5 -7 -9 -19 -23 -25 -30 -7
-7 -13 -20 -13 -29 0 -12 8 -14 38 -9 20 4 57 8 82 9 25 2 54 8 66 15 18 10
23 8 32 -13 17 -38 86 -35 152 6 27 17 50 34 50 38 0 16 62 30 85 19 33 -15
72 -2 89 30 8 15 31 43 51 62 35 34 38 35 118 35 77 0 85 2 126 33 24 17 52
32 61 32 9 0 42 18 73 40 30 22 61 40 69 40 21 0 88 -26 100 -38 7 -7 17 -12
24 -12 7 0 35 -11 62 -25 66 -33 263 -84 387 -101 189 -25 372 -12 574 41 106
27 130 37 261 97 41 20 80 37 85 39 6 2 51 31 100 64 166 111 405 372 489 534
10 20 22 43 27 51 5 8 12 22 15 30 3 8 17 40 31 70 54 115 95 313 108 520 13
200 -43 480 -134 672 -28 58 -51 108 -51 112 0 3 -13 24 -29 48 -15 24 -34 60
-40 80 -19 57 3 142 50 193 10 11 22 49 28 85 6 36 16 67 21 68 18 6 31 53 25
83 -4 18 -17 33 -36 41 -16 7 -29 15 -29 18 1 10 38 50 47 50 5 0 20 11 33 25
18 19 22 31 17 61 -3 20 -14 45 -23 55 -16 18 -16 20 6 44 15 16 21 32 18 49
-3 15 1 34 8 43 32 43 7 73 -46 55 l-30 -11 0 85 c0 74 -2 84 -18 84 -21 0
-53 -33 -103 -104 l-34 -48 -5 74 c-7 102 -35 133 -80 88z m-870 -740 c36 -7
75 -14 88 -16 21 -4 23 -9 16 -37 -3 -18 -14 -43 -24 -57 -10 -14 -20 -35 -24
-46 -4 -12 -16 -32 -27 -45 -12 -13 -37 -49 -56 -79 -20 -30 -52 -73 -72 -96
-53 -60 -114 -133 -156 -189 -21 -27 -44 -54 -52 -58 -7 -4 -13 -14 -13 -22 0
-7 -18 -33 -40 -57 -22 -23 -40 -46 -40 -50 0 -5 -19 -21 -42 -38 -47 -35 -85
-38 -188 -15 -115 25 -173 20 -264 -23 -45 -22 -106 -46 -136 -56 -48 -15 -77
-25 -140 -50 -70 -28 -100 -77 -51 -84 14 -2 34 -10 45 -17 12 -7 53 -16 91
-20 90 -9 131 -22 178 -57 20 -16 52 -35 70 -43 18 -7 40 -22 49 -32 16 -18
15 -22 -24 -88 -23 -39 -47 -74 -53 -80 -7 -5 -23 -26 -36 -45 -26 -39 -92
-113 -207 -232 -4 -4 -37 -36 -73 -71 l-66 -64 -20 41 c-58 119 -105 240 -115
301 -40 244 -35 409 20 595 8 30 21 66 28 80 7 14 24 54 38 89 15 35 35 75 46
89 11 13 20 31 20 38 0 8 3 14 8 14 4 0 16 16 27 36 24 45 221 245 278 281 23
15 44 30 47 33 20 20 138 78 250 123 61 24 167 50 250 61 60 7 302 -1 370 -14z
m837 -661 c52 -101 102 -279 106 -379 2 -42 0 -45 -28 -51 -16 -4 -101 -7
-187 -8 -166 -1 -229 10 -271 49 -19 19 -19 19 14 49 22 21 44 31 65 31 41 0
84 34 84 66 0 30 12 55 56 112 19 25 37 65 44 95 11 51 53 111 74 104 6 -2 25
-32 43 -68z m-662 -810 c17 -10 40 -24 53 -30 12 -7 22 -16 22 -20 0 -4 17
-13 38 -19 20 -7 44 -18 52 -24 8 -7 33 -21 55 -31 22 -11 42 -23 45 -26 11
-14 109 -49 164 -58 62 -11 101 -7 126 14 15 14 38 18 78 16 39 -2 26 -41 -49
-146 -78 -109 -85 -118 -186 -219 -61 -61 -239 -189 -281 -203 -17 -5 -73 -29
-104 -44 -187 -92 -605 -103 -791 -21 -42 19 -47 24 -37 41 5 11 28 32 51 48
22 15 51 38 64 51 13 12 28 22 33 22 17 0 242 233 242 250 0 6 5 10 10 10 6 0
10 6 10 14 0 25 50 55 100 62 59 8 56 6 115 83 50 66 74 117 75 162 0 14 7 40
16 57 18 38 52 41 99 11z" fill="#EF454A"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 4.2 KiB

5
readme.md Normal file
View File

@@ -0,0 +1,5 @@
<div align="center">
<a href="https://syui.github.io">
<img src="https://git.syui.ai/syui/syui/raw/branch/main/icon/syui.svg" width="64">
</a>
</div>