soba-cli 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/.claude/commands/osoba/add-backlog.md +173 -0
- data/.claude/commands/osoba/implement.md +151 -0
- data/.claude/commands/osoba/plan.md +217 -0
- data/.claude/commands/osoba/review.md +133 -0
- data/.claude/commands/osoba/revise.md +176 -0
- data/.claude/commands/soba/implement.md +88 -0
- data/.claude/commands/soba/plan.md +93 -0
- data/.claude/commands/soba/review.md +91 -0
- data/.claude/commands/soba/revise.md +76 -0
- data/.devcontainer/.env +2 -0
- data/.devcontainer/Dockerfile +3 -0
- data/.devcontainer/LICENSE +21 -0
- data/.devcontainer/README.md +85 -0
- data/.devcontainer/bin/devcontainer-common.sh +50 -0
- data/.devcontainer/bin/down +35 -0
- data/.devcontainer/bin/rebuild +10 -0
- data/.devcontainer/bin/up +11 -0
- data/.devcontainer/compose.yaml +28 -0
- data/.devcontainer/devcontainer.json +53 -0
- data/.devcontainer/post-attach.sh +29 -0
- data/.devcontainer/post-create.sh +62 -0
- data/.devcontainer/setup/01-os-package.sh +19 -0
- data/.devcontainer/setup/02-npm-package.sh +22 -0
- data/.devcontainer/setup/03-mcp-server.sh +33 -0
- data/.devcontainer/setup/04-tool.sh +17 -0
- data/.devcontainer/setup/05-soba-setup.sh +66 -0
- data/.devcontainer/setup/scripts/functions/install_apt.sh +77 -0
- data/.devcontainer/setup/scripts/functions/install_npm.sh +71 -0
- data/.devcontainer/setup/scripts/functions/mcp_config.sh +14 -0
- data/.devcontainer/setup/scripts/functions/print_message.sh +59 -0
- data/.devcontainer/setup/scripts/setup/mcp-markdownify.sh +39 -0
- data/.devcontainer/sync-envs.sh +58 -0
- data/.envrc.sample +7 -0
- data/.rspec +4 -0
- data/.rubocop.yml +70 -0
- data/.rubocop_airbnb.yml +2 -0
- data/.rubocop_todo.yml +74 -0
- data/.tool-versions +1 -0
- data/CLAUDE.md +20 -0
- data/LICENSE +21 -0
- data/README.md +384 -0
- data/README_ja.md +384 -0
- data/Rakefile +18 -0
- data/bin/soba +120 -0
- data/config/config.yml.example +36 -0
- data/docs/business/INDEX.md +6 -0
- data/docs/business/overview.md +42 -0
- data/docs/business/workflow.md +143 -0
- data/docs/development/INDEX.md +10 -0
- data/docs/development/architecture.md +69 -0
- data/docs/development/coding-standards.md +152 -0
- data/docs/development/distribution.md +26 -0
- data/docs/development/implementation-guide.md +103 -0
- data/docs/development/testing-strategy.md +128 -0
- data/docs/development/tmux-management.md +253 -0
- data/docs/document_system.md +58 -0
- data/lib/soba/commands/config/show.rb +63 -0
- data/lib/soba/commands/init.rb +778 -0
- data/lib/soba/commands/open.rb +144 -0
- data/lib/soba/commands/start.rb +442 -0
- data/lib/soba/commands/status.rb +175 -0
- data/lib/soba/commands/stop.rb +147 -0
- data/lib/soba/config_loader.rb +32 -0
- data/lib/soba/configuration.rb +268 -0
- data/lib/soba/container.rb +48 -0
- data/lib/soba/domain/issue.rb +38 -0
- data/lib/soba/domain/phase_strategy.rb +74 -0
- data/lib/soba/infrastructure/errors.rb +23 -0
- data/lib/soba/infrastructure/github_client.rb +399 -0
- data/lib/soba/infrastructure/lock_manager.rb +129 -0
- data/lib/soba/infrastructure/tmux_client.rb +331 -0
- data/lib/soba/services/ansi_processor.rb +92 -0
- data/lib/soba/services/auto_merge_service.rb +133 -0
- data/lib/soba/services/closed_issue_window_cleaner.rb +96 -0
- data/lib/soba/services/daemon_service.rb +83 -0
- data/lib/soba/services/git_workspace_manager.rb +102 -0
- data/lib/soba/services/issue_monitor.rb +29 -0
- data/lib/soba/services/issue_processor.rb +215 -0
- data/lib/soba/services/issue_watcher.rb +193 -0
- data/lib/soba/services/pid_manager.rb +87 -0
- data/lib/soba/services/process_info.rb +58 -0
- data/lib/soba/services/queueing_service.rb +98 -0
- data/lib/soba/services/session_logger.rb +111 -0
- data/lib/soba/services/session_resolver.rb +72 -0
- data/lib/soba/services/slack_notifier.rb +121 -0
- data/lib/soba/services/status_manager.rb +74 -0
- data/lib/soba/services/test_process_manager.rb +84 -0
- data/lib/soba/services/tmux_session_manager.rb +251 -0
- data/lib/soba/services/workflow_blocking_checker.rb +73 -0
- data/lib/soba/services/workflow_executor.rb +256 -0
- data/lib/soba/services/workflow_integrity_checker.rb +151 -0
- data/lib/soba/templates/claude_commands/implement.md +88 -0
- data/lib/soba/templates/claude_commands/plan.md +93 -0
- data/lib/soba/templates/claude_commands/review.md +91 -0
- data/lib/soba/templates/claude_commands/revise.md +76 -0
- data/lib/soba/version.rb +5 -0
- data/lib/soba.rb +44 -0
- data/lib/tasks/gem.rake +75 -0
- data/soba-cli.gemspec +59 -0
- metadata +430 -0
@@ -0,0 +1,151 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative "../configuration"
|
4
|
+
|
5
|
+
module Soba
|
6
|
+
module Services
|
7
|
+
class WorkflowIntegrityChecker
|
8
|
+
ACTIVE_LABELS = %w(
|
9
|
+
soba:queued
|
10
|
+
soba:planning
|
11
|
+
soba:doing
|
12
|
+
soba:reviewing
|
13
|
+
soba:revising
|
14
|
+
).freeze
|
15
|
+
|
16
|
+
INTERMEDIATE_LABELS = %w(
|
17
|
+
soba:review-requested
|
18
|
+
soba:requires-changes
|
19
|
+
).freeze
|
20
|
+
|
21
|
+
attr_reader :github_client, :logger
|
22
|
+
|
23
|
+
def initialize(github_client:, logger: nil)
|
24
|
+
@github_client = github_client
|
25
|
+
@logger = logger || SemanticLogger["WorkflowIntegrityChecker"]
|
26
|
+
end
|
27
|
+
|
28
|
+
def check_and_fix(repository, issues:, dry_run: false)
|
29
|
+
logger.info("Checking workflow integrity for #{repository}")
|
30
|
+
|
31
|
+
violations = detect_violations(issues)
|
32
|
+
|
33
|
+
if violations.empty?
|
34
|
+
logger.info("No workflow integrity violations found")
|
35
|
+
return {
|
36
|
+
violations_found: false,
|
37
|
+
fixed_count: 0,
|
38
|
+
violations: [],
|
39
|
+
dry_run: dry_run,
|
40
|
+
}
|
41
|
+
end
|
42
|
+
|
43
|
+
logger.warn("Found #{violations.size} workflow integrity violations")
|
44
|
+
violations.each do |violation|
|
45
|
+
logger.warn(" Issue ##{violation[:issue_number]}: #{violation[:label]} (#{violation[:action]})")
|
46
|
+
end
|
47
|
+
|
48
|
+
fixed_count = 0
|
49
|
+
failed_fixes = 0
|
50
|
+
|
51
|
+
if dry_run
|
52
|
+
logger.info("Dry run mode - no fixes applied")
|
53
|
+
else
|
54
|
+
violations.each do |violation|
|
55
|
+
if fix_violation(repository, violation)
|
56
|
+
fixed_count += 1
|
57
|
+
else
|
58
|
+
failed_fixes += 1
|
59
|
+
end
|
60
|
+
end
|
61
|
+
if fixed_count > 0 || failed_fixes > 0
|
62
|
+
logger.info("Fixed #{fixed_count} violations, #{failed_fixes} failed")
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
{
|
67
|
+
violations_found: true,
|
68
|
+
fixed_count: fixed_count,
|
69
|
+
failed_fixes: failed_fixes,
|
70
|
+
violations: violations,
|
71
|
+
dry_run: dry_run,
|
72
|
+
}
|
73
|
+
end
|
74
|
+
|
75
|
+
private
|
76
|
+
|
77
|
+
def detect_violations(issues)
|
78
|
+
violations = []
|
79
|
+
|
80
|
+
# Find all issues with active or intermediate labels
|
81
|
+
active_issues = issues.select do |issue|
|
82
|
+
labels = extract_label_names(issue.labels)
|
83
|
+
(labels & (ACTIVE_LABELS + INTERMEDIATE_LABELS)).any?
|
84
|
+
end
|
85
|
+
|
86
|
+
return violations if active_issues.size <= 1
|
87
|
+
|
88
|
+
# Multiple active issues detected - keep only the newest
|
89
|
+
# Sort by created_at descending (newest first)
|
90
|
+
sorted_issues = active_issues.sort_by { |issue| issue.created_at }.reverse
|
91
|
+
newest_issue = sorted_issues.first
|
92
|
+
|
93
|
+
# Mark all others as violations
|
94
|
+
sorted_issues[1..-1].each do |issue|
|
95
|
+
labels = extract_label_names(issue.labels)
|
96
|
+
conflicting_label = labels.find { |l| (ACTIVE_LABELS + INTERMEDIATE_LABELS).include?(l) }
|
97
|
+
|
98
|
+
violations << {
|
99
|
+
issue_number: issue.number,
|
100
|
+
label: conflicting_label,
|
101
|
+
action: "removed",
|
102
|
+
reason: "Multiple active issues detected, keeping newest (Issue ##{newest_issue.number})",
|
103
|
+
}
|
104
|
+
end
|
105
|
+
|
106
|
+
violations
|
107
|
+
end
|
108
|
+
|
109
|
+
def fix_violation(repository, violation)
|
110
|
+
logger.info("Fixing violation: Issue ##{violation[:issue_number]} - removing #{violation[:label]}")
|
111
|
+
|
112
|
+
# Determine the target label based on what's being removed
|
113
|
+
target_label = determine_target_label(violation[:label])
|
114
|
+
|
115
|
+
github_client.update_issue_labels(
|
116
|
+
repository,
|
117
|
+
violation[:issue_number],
|
118
|
+
from: violation[:label],
|
119
|
+
to: target_label
|
120
|
+
)
|
121
|
+
|
122
|
+
logger.info("Successfully fixed Issue ##{violation[:issue_number]}")
|
123
|
+
true
|
124
|
+
rescue => e
|
125
|
+
logger.error("Failed to fix violation for Issue ##{violation[:issue_number]}: #{e.message}")
|
126
|
+
false
|
127
|
+
end
|
128
|
+
|
129
|
+
def determine_target_label(from_label)
|
130
|
+
# Most labels should revert to todo
|
131
|
+
# Special cases can be handled here if needed
|
132
|
+
case from_label
|
133
|
+
when "soba:review-requested", "soba:requires-changes"
|
134
|
+
"soba:ready" # Review states go back to ready
|
135
|
+
else
|
136
|
+
"soba:todo" # Active states go back to todo
|
137
|
+
end
|
138
|
+
end
|
139
|
+
|
140
|
+
def extract_label_names(labels)
|
141
|
+
labels.map do |label|
|
142
|
+
if label.is_a?(Hash)
|
143
|
+
label[:name] || label["name"]
|
144
|
+
else
|
145
|
+
label.name
|
146
|
+
end
|
147
|
+
end
|
148
|
+
end
|
149
|
+
end
|
150
|
+
end
|
151
|
+
end
|
@@ -0,0 +1,88 @@
|
|
1
|
+
---
|
2
|
+
allowed-tools: TodoRead, TodoWrite, Bash, Read, Write, Edit, MultiEdit, Grep, Glob
|
3
|
+
description: "TDDによる実装とPR作成"
|
4
|
+
---
|
5
|
+
|
6
|
+
## 概要
|
7
|
+
|
8
|
+
実装計画に基づいてTDDで開発を進め、Pull Requestを作成します。
|
9
|
+
|
10
|
+
---
|
11
|
+
|
12
|
+
## 前提条件
|
13
|
+
|
14
|
+
- Issueコメントに実装計画が存在
|
15
|
+
- ラベルは `soba:doing` の状態
|
16
|
+
|
17
|
+
---
|
18
|
+
|
19
|
+
## ルール
|
20
|
+
|
21
|
+
1. **実装計画を必ず確認し従う**
|
22
|
+
2. **TDD実践(テストファースト)**
|
23
|
+
3. **既存設計・アーキテクチャを尊重**
|
24
|
+
4. **実装完了後はPRを作成**
|
25
|
+
5. **全テストのパスが必須条件**
|
26
|
+
|
27
|
+
---
|
28
|
+
|
29
|
+
## 実行手順
|
30
|
+
|
31
|
+
1. **Issue・計画確認**
|
32
|
+
- `gh issue view <番号>` で内容確認
|
33
|
+
- `gh issue view <番号> --comments` でコメント確認
|
34
|
+
|
35
|
+
2. **テスト作成**
|
36
|
+
- 計画に基づくテストケース作成
|
37
|
+
- Red → Green → Refactor
|
38
|
+
|
39
|
+
3. **実装**
|
40
|
+
- 小さな単位でコミット
|
41
|
+
- 意味のあるコミットメッセージ
|
42
|
+
|
43
|
+
4. **テスト実行**
|
44
|
+
- 単体テスト実行
|
45
|
+
- 全体テスト実行(必須)
|
46
|
+
|
47
|
+
5. **PRテンプレート作成**
|
48
|
+
- `./.tmp/pull-request-<番号>.md` 作成
|
49
|
+
|
50
|
+
6. **PR作成**
|
51
|
+
```bash
|
52
|
+
gh pr create \
|
53
|
+
--title "feat: [機能名] (#<Issue番号>)" \
|
54
|
+
--body-file ./.tmp/pull-request-<番号>.md \
|
55
|
+
--base main
|
56
|
+
```
|
57
|
+
|
58
|
+
7. **Issueコメント**
|
59
|
+
- 「PR #<番号> を作成しました」
|
60
|
+
|
61
|
+
8. **ラベル更新**
|
62
|
+
```bash
|
63
|
+
gh issue edit <番号> \
|
64
|
+
--remove-label "soba:doing" \
|
65
|
+
--add-label "soba:review-requested"
|
66
|
+
```
|
67
|
+
|
68
|
+
---
|
69
|
+
|
70
|
+
## PRテンプレート
|
71
|
+
|
72
|
+
```markdown
|
73
|
+
## 実装完了
|
74
|
+
|
75
|
+
fixes #<番号>
|
76
|
+
|
77
|
+
### 変更内容
|
78
|
+
- [主要な変更点]
|
79
|
+
|
80
|
+
### テスト結果
|
81
|
+
- 単体テスト: ✅ パス
|
82
|
+
- 全体テスト: ✅ パス
|
83
|
+
|
84
|
+
### 確認事項
|
85
|
+
- [ ] 実装計画に沿った実装
|
86
|
+
- [ ] テストカバレッジ確保
|
87
|
+
- [ ] 既存機能への影響なし
|
88
|
+
```
|
@@ -0,0 +1,93 @@
|
|
1
|
+
---
|
2
|
+
allowed-tools: TodoWrite, TodoRead, Bash, Read, Grep, Glob
|
3
|
+
description: "GitHub Issueの実装計画を策定"
|
4
|
+
---
|
5
|
+
|
6
|
+
## 概要
|
7
|
+
|
8
|
+
GitHub Issueに対する実装計画を策定し、Issueコメントとして投稿します。
|
9
|
+
|
10
|
+
---
|
11
|
+
|
12
|
+
## 前提条件
|
13
|
+
|
14
|
+
- ラベルは `soba:planning` の状態
|
15
|
+
|
16
|
+
---
|
17
|
+
|
18
|
+
## ルール
|
19
|
+
|
20
|
+
1. **コード修正は行わず、計画策定に専念**
|
21
|
+
2. **TDDを前提とした計画設計**
|
22
|
+
3. **既存アーキテクチャに従う**
|
23
|
+
4. **実行可能な単位にステップ分割**
|
24
|
+
5. **テンプレート形式で計画作成**
|
25
|
+
6. **完了後ラベルを `soba:ready` に更新**
|
26
|
+
|
27
|
+
---
|
28
|
+
|
29
|
+
## 実行手順
|
30
|
+
|
31
|
+
1. **Issue確認**
|
32
|
+
- `gh issue view <番号>` で内容確認
|
33
|
+
- `gh issue view <番号> --comments` でコメント確認
|
34
|
+
|
35
|
+
2. **コードベース調査**
|
36
|
+
- 関連ファイル・過去実装を確認
|
37
|
+
- 影響範囲と依存関係を特定
|
38
|
+
|
39
|
+
3. **技術選定**
|
40
|
+
- 使用ライブラリ・パターンを決定
|
41
|
+
- 選定理由を明確化
|
42
|
+
|
43
|
+
4. **実装ステップ定義**
|
44
|
+
- テスト可能な単位に分割
|
45
|
+
- 関連ファイル・副作用を記載
|
46
|
+
|
47
|
+
5. **テスト・リスク・スケジュール策定**
|
48
|
+
- テスト計画(単体・統合)
|
49
|
+
- リスクと対策
|
50
|
+
- 実装期間の見積もり
|
51
|
+
|
52
|
+
6. **計画ファイル作成**
|
53
|
+
- `./.tmp/plan-[slug].md` に保存
|
54
|
+
|
55
|
+
7. **コメント投稿**
|
56
|
+
- `gh issue comment <番号> --body-file ./.tmp/plan-[slug].md`
|
57
|
+
|
58
|
+
8. **ラベル更新**
|
59
|
+
- `gh issue edit <番号> --remove-label "soba:planning" --add-label "soba:ready"`
|
60
|
+
|
61
|
+
---
|
62
|
+
|
63
|
+
## テンプレート
|
64
|
+
|
65
|
+
```markdown
|
66
|
+
# 実装計画: [タイトル]
|
67
|
+
|
68
|
+
## 要件概要
|
69
|
+
- [目的と背景]
|
70
|
+
- [機能要件]
|
71
|
+
- [受け入れ条件]
|
72
|
+
|
73
|
+
## 設計方針
|
74
|
+
- [技術選定と理由]
|
75
|
+
- [アーキテクチャ上の考慮点]
|
76
|
+
|
77
|
+
## 実装ステップ
|
78
|
+
1. [ステップ名]
|
79
|
+
- 作業内容: [詳細]
|
80
|
+
- 関連ファイル: [ファイルパス]
|
81
|
+
|
82
|
+
## テスト計画
|
83
|
+
- 単体テスト: [対象とケース]
|
84
|
+
- 統合テスト: [シナリオ]
|
85
|
+
|
86
|
+
## リスクと対策
|
87
|
+
- リスク: [内容]
|
88
|
+
対策: [方法]
|
89
|
+
|
90
|
+
## スケジュール
|
91
|
+
- 見積もり: 合計[X]時間
|
92
|
+
- ステップ別: 各[Y]時間
|
93
|
+
```
|
@@ -0,0 +1,91 @@
|
|
1
|
+
---
|
2
|
+
allowed-tools: Bash, Read, Write, Edit, MultiEdit, Grep, Glob, LS
|
3
|
+
description: "Review a Pull Request for a soba Issue"
|
4
|
+
---
|
5
|
+
|
6
|
+
# Review PR
|
7
|
+
|
8
|
+
PRレビューを実施します。
|
9
|
+
|
10
|
+
## Context
|
11
|
+
|
12
|
+
- Issue番号: $ARGUMENTS
|
13
|
+
|
14
|
+
## Workflow
|
15
|
+
|
16
|
+
### 1. Issue確認
|
17
|
+
|
18
|
+
```bash
|
19
|
+
GH_PAGER= gh issue view <issue-number>
|
20
|
+
GH_PAGER= gh issue view <issue-number> --comments
|
21
|
+
```
|
22
|
+
|
23
|
+
### 2. PR確認
|
24
|
+
|
25
|
+
```bash
|
26
|
+
GH_PAGER= gh pr view <PR-number>
|
27
|
+
GH_PAGER= gh pr view <PR-number> --json mergeable,mergeStateStatus
|
28
|
+
```
|
29
|
+
|
30
|
+
### 3. コード変更確認
|
31
|
+
|
32
|
+
```bash
|
33
|
+
GH_PAGER= gh pr diff <PR-number>
|
34
|
+
```
|
35
|
+
|
36
|
+
レビュー観点:
|
37
|
+
- コーディング規約への準拠
|
38
|
+
- テストの実装状況
|
39
|
+
- セキュリティ上の懸念
|
40
|
+
- 不要な差分の有無
|
41
|
+
|
42
|
+
### 4. CI確認(必須・完了まで待機)
|
43
|
+
|
44
|
+
```bash
|
45
|
+
gh pr checks <PR-number> --watch # Timeout 600000
|
46
|
+
```
|
47
|
+
|
48
|
+
⚠️ **重要**: CI完了前にレビュー結果を投稿しないこと
|
49
|
+
|
50
|
+
### 5. レビュー結果投稿
|
51
|
+
|
52
|
+
`./.tmp/review-result-<issue-number>.md`を作成:
|
53
|
+
|
54
|
+
```markdown
|
55
|
+
## レビュー結果
|
56
|
+
|
57
|
+
- Issue: #<issue-number>
|
58
|
+
- PR: #<PR-number>
|
59
|
+
|
60
|
+
### ✅ 判定
|
61
|
+
- [ ] 承認(LGTM)
|
62
|
+
- [ ] 修正要求
|
63
|
+
|
64
|
+
### 🔄 マージ状態
|
65
|
+
- [ ] コンフリクトなし
|
66
|
+
- [ ] コンフリクトあり(要リベース)
|
67
|
+
|
68
|
+
### 👍 良い点
|
69
|
+
- [実装の良い点]
|
70
|
+
|
71
|
+
### 🛠 改善提案
|
72
|
+
- [具体的な改善点]
|
73
|
+
```
|
74
|
+
|
75
|
+
投稿:
|
76
|
+
```bash
|
77
|
+
gh pr comment <PR-number> --body "$(cat ./.tmp/review-result-<issue-number>.md)"
|
78
|
+
```
|
79
|
+
|
80
|
+
### 6. ラベル更新
|
81
|
+
|
82
|
+
承認の場合:
|
83
|
+
```bash
|
84
|
+
gh issue edit <issue-number> --remove-label "soba:reviewing" --add-label "soba:done"
|
85
|
+
gh pr edit <PR-number> --add-label "soba:lgtm"
|
86
|
+
```
|
87
|
+
|
88
|
+
修正要求の場合:
|
89
|
+
```bash
|
90
|
+
gh issue edit <issue-number> --remove-label "soba:reviewing" --add-label "soba:requires-changes"
|
91
|
+
```
|
@@ -0,0 +1,76 @@
|
|
1
|
+
---
|
2
|
+
allowed-tools: Bash, Read, Write, Edit, MultiEdit, Grep, Glob, LS
|
3
|
+
description: "Revise implementation based on review feedback"
|
4
|
+
---
|
5
|
+
|
6
|
+
# Revise PR
|
7
|
+
|
8
|
+
レビュー指摘事項に対応します。
|
9
|
+
|
10
|
+
## Context
|
11
|
+
|
12
|
+
- Issue番号: $ARGUMENTS
|
13
|
+
|
14
|
+
## Workflow
|
15
|
+
|
16
|
+
### 1. PR確認
|
17
|
+
|
18
|
+
```bash
|
19
|
+
GH_PAGER= gh pr list --search "linked:$ARGUMENTS" --state open --json number --jq '.[0].number'
|
20
|
+
```
|
21
|
+
|
22
|
+
### 2. レビューコメント確認
|
23
|
+
|
24
|
+
```bash
|
25
|
+
GH_PAGER= gh pr view <PR-number> --comments
|
26
|
+
```
|
27
|
+
|
28
|
+
### 3. 指摘事項への対応
|
29
|
+
|
30
|
+
レビューコメントに基づいて修正を実施:
|
31
|
+
- コード品質の改善
|
32
|
+
- テストの追加・修正
|
33
|
+
- エラーハンドリングの改善
|
34
|
+
- 不要な差分の削除
|
35
|
+
|
36
|
+
### 4. テスト実行
|
37
|
+
|
38
|
+
```bash
|
39
|
+
bundle exec rspec # Timeout 600000
|
40
|
+
```
|
41
|
+
|
42
|
+
### 5. 修正内容のコミット
|
43
|
+
|
44
|
+
```bash
|
45
|
+
git add -A
|
46
|
+
git commit -m "fix: レビュー指摘事項への対応
|
47
|
+
|
48
|
+
- [修正内容の要約]
|
49
|
+
"
|
50
|
+
git push
|
51
|
+
```
|
52
|
+
|
53
|
+
### 6. 対応完了コメント
|
54
|
+
|
55
|
+
`./.tmp/revise-complete-<issue-number>.md`を作成:
|
56
|
+
|
57
|
+
```markdown
|
58
|
+
## レビュー指摘対応完了
|
59
|
+
|
60
|
+
以下の指摘事項に対応しました:
|
61
|
+
- ✅ [対応項目]
|
62
|
+
|
63
|
+
全てのテストがパスすることを確認済みです。
|
64
|
+
再レビューをお願いいたします。
|
65
|
+
```
|
66
|
+
|
67
|
+
投稿:
|
68
|
+
```bash
|
69
|
+
gh pr comment <PR-number> --body "$(cat ./.tmp/revise-complete-<issue-number>.md)"
|
70
|
+
```
|
71
|
+
|
72
|
+
### 7. ラベル更新
|
73
|
+
|
74
|
+
```bash
|
75
|
+
gh issue edit <issue-number> --remove-label "soba:revising" --add-label "soba:review-requested"
|
76
|
+
```
|
data/lib/soba/version.rb
ADDED
data/lib/soba.rb
ADDED
@@ -0,0 +1,44 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "gli"
|
4
|
+
require "dry-container"
|
5
|
+
require "dry-auto_inject"
|
6
|
+
require "faraday"
|
7
|
+
require "octokit"
|
8
|
+
require "concurrent"
|
9
|
+
require "semantic_logger"
|
10
|
+
|
11
|
+
require_relative "soba/version"
|
12
|
+
|
13
|
+
module Soba
|
14
|
+
class Error < StandardError; end
|
15
|
+
class ConfigError < Error; end
|
16
|
+
class ConfigurationError < Error; end
|
17
|
+
class GitHubError < Error; end
|
18
|
+
class CommandError < Error; end
|
19
|
+
|
20
|
+
module Domain; end
|
21
|
+
module Services; end
|
22
|
+
module Infrastructure; end
|
23
|
+
module Commands
|
24
|
+
module Issue; end
|
25
|
+
module Config; end
|
26
|
+
end
|
27
|
+
|
28
|
+
SemanticLogger.default_level = :info
|
29
|
+
SemanticLogger.add_appender(io: $stdout, formatter: :color)
|
30
|
+
|
31
|
+
def self.logger
|
32
|
+
@logger ||= SemanticLogger["Soba"]
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
require_relative "soba/configuration"
|
37
|
+
require_relative "soba/config_loader"
|
38
|
+
require_relative "soba/container"
|
39
|
+
require_relative "soba/domain/issue"
|
40
|
+
require_relative "soba/services/issue_monitor"
|
41
|
+
require_relative "soba/services/workflow_blocking_checker"
|
42
|
+
require_relative "soba/services/queueing_service"
|
43
|
+
require_relative "soba/infrastructure/errors"
|
44
|
+
require_relative "soba/infrastructure/github_client"
|
data/lib/tasks/gem.rake
ADDED
@@ -0,0 +1,75 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative "../soba/version"
|
4
|
+
|
5
|
+
namespace :gem do
|
6
|
+
desc "Build the soba-cli gem"
|
7
|
+
task :build do
|
8
|
+
puts "Building soba-cli gem..."
|
9
|
+
system("gem build soba-cli.gemspec") || abort("Failed to build gem")
|
10
|
+
puts "Gem built successfully!"
|
11
|
+
end
|
12
|
+
|
13
|
+
desc "Install the soba-cli gem locally"
|
14
|
+
task install: "gem:build" do
|
15
|
+
gem_file = Dir.glob("soba-cli-*.gem").max_by { |f| File.mtime(f) }
|
16
|
+
abort("No gem file found") unless gem_file
|
17
|
+
|
18
|
+
puts "Installing #{gem_file}..."
|
19
|
+
system("gem install #{gem_file}") || abort("Failed to install gem")
|
20
|
+
puts "Gem installed successfully!"
|
21
|
+
end
|
22
|
+
|
23
|
+
desc "Uninstall the soba-cli gem"
|
24
|
+
task :uninstall do
|
25
|
+
puts "Uninstalling soba-cli gem..."
|
26
|
+
system("gem uninstall soba-cli -x") || puts("Gem may not be installed")
|
27
|
+
puts "Gem uninstalled successfully!"
|
28
|
+
end
|
29
|
+
|
30
|
+
desc "Clean up built gem files"
|
31
|
+
task :clean do
|
32
|
+
gem_files = Dir.glob("soba-cli-*.gem")
|
33
|
+
if gem_files.any?
|
34
|
+
puts "Removing gem files: #{gem_files.join(', ')}"
|
35
|
+
gem_files.each { |f| File.delete(f) }
|
36
|
+
puts "Cleaned up gem files"
|
37
|
+
else
|
38
|
+
puts "No gem files to clean"
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
desc "Build, tag, and push gem to RubyGems.org (manual release)"
|
43
|
+
task release: "gem:build" do
|
44
|
+
puts "🚨 NOTICE: This is a manual release task."
|
45
|
+
puts "📋 For automated releases, create a GitHub Release with a tag like 'v1.2.3'"
|
46
|
+
puts "🤖 GitHub Actions will automatically build and publish the gem."
|
47
|
+
puts ""
|
48
|
+
|
49
|
+
gem_file = Dir.glob("soba-cli-*.gem").max_by { |f| File.mtime(f) }
|
50
|
+
abort("No gem file found") unless gem_file
|
51
|
+
|
52
|
+
puts "WARNING: This will push #{gem_file} to RubyGems.org!"
|
53
|
+
print "Are you sure you want to proceed with manual release? (y/N): "
|
54
|
+
input = $stdin.gets.chomp
|
55
|
+
|
56
|
+
if input.downcase == "y"
|
57
|
+
system("gem push #{gem_file}") || abort("Failed to push gem")
|
58
|
+
puts "Gem released successfully!"
|
59
|
+
|
60
|
+
# Tag the release in git
|
61
|
+
version = Soba::VERSION
|
62
|
+
system("git tag v#{version}") || abort("Failed to create git tag")
|
63
|
+
system("git push origin v#{version}") || abort("Failed to push git tag")
|
64
|
+
puts "Git tag v#{version} created and pushed"
|
65
|
+
else
|
66
|
+
puts "Release cancelled"
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
desc "Alias for gem:build"
|
72
|
+
task build: "gem:build"
|
73
|
+
|
74
|
+
desc "Alias for gem:install"
|
75
|
+
task install: "gem:install"
|
data/soba-cli.gemspec
ADDED
@@ -0,0 +1,59 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative "lib/soba/version"
|
4
|
+
|
5
|
+
Gem::Specification.new do |spec|
|
6
|
+
spec.name = "soba-cli"
|
7
|
+
spec.version = Soba::VERSION
|
8
|
+
spec.authors = ["douhashi"]
|
9
|
+
spec.email = ["douhashi@gmail.com"]
|
10
|
+
|
11
|
+
spec.summary = "Autonomous GitHub Issue-driven development CLI with Claude Code"
|
12
|
+
spec.description = "Soba is an autonomous CLI tool that fully automates GitHub Issue-driven development workflows. " \
|
13
|
+
"It monitors issues, creates implementation plans, generates code, and manages pull requests " \
|
14
|
+
"through seamless integration with Claude Code AI, enabling hands-free development cycles."
|
15
|
+
spec.homepage = "https://github.com/douhashi/soba-cli"
|
16
|
+
spec.license = "MIT"
|
17
|
+
spec.required_ruby_version = ">= 3.0.0"
|
18
|
+
|
19
|
+
spec.metadata["allowed_push_host"] = "https://rubygems.org"
|
20
|
+
spec.metadata["homepage_uri"] = spec.homepage
|
21
|
+
spec.metadata["source_code_uri"] = spec.homepage
|
22
|
+
spec.metadata["changelog_uri"] = "#{spec.homepage}/blob/main/CHANGELOG.md"
|
23
|
+
|
24
|
+
# Specify which files should be added to the gem when it is released.
|
25
|
+
# The `git ls-files -z` loads the files in the RubyGem that have been added into git.
|
26
|
+
spec.files = Dir.chdir(__dir__) do
|
27
|
+
`git ls-files -z`.split("\x0").reject do |f|
|
28
|
+
(File.expand_path(f) == __FILE__) ||
|
29
|
+
f.start_with?(*%w(test/ spec/ features/ .git .github appveyor Gemfile scripts/ .tmp/))
|
30
|
+
end
|
31
|
+
end
|
32
|
+
spec.bindir = "bin"
|
33
|
+
spec.executables = ["soba"]
|
34
|
+
spec.require_paths = ["lib"]
|
35
|
+
|
36
|
+
# Runtime dependencies
|
37
|
+
spec.add_runtime_dependency "gli", "~> 2.21"
|
38
|
+
spec.add_runtime_dependency "dry-container", "~> 0.11"
|
39
|
+
spec.add_runtime_dependency "dry-auto_inject", "~> 1.0"
|
40
|
+
spec.add_runtime_dependency "faraday", "~> 2.9"
|
41
|
+
spec.add_runtime_dependency "faraday-retry", "~> 2.2"
|
42
|
+
spec.add_runtime_dependency "octokit", "~> 10.0"
|
43
|
+
spec.add_runtime_dependency "concurrent-ruby", "~> 1.2"
|
44
|
+
spec.add_runtime_dependency "semantic_logger", "~> 4.15"
|
45
|
+
spec.add_runtime_dependency "dry-configurable", "~> 1.1"
|
46
|
+
spec.add_runtime_dependency "activesupport", "~> 8.0"
|
47
|
+
|
48
|
+
# Development dependencies
|
49
|
+
spec.add_development_dependency "rake", "~> 13.0"
|
50
|
+
spec.add_development_dependency "rspec", "~> 3.12"
|
51
|
+
spec.add_development_dependency "webmock", "~> 3.19"
|
52
|
+
spec.add_development_dependency "vcr", "~> 6.2"
|
53
|
+
spec.add_development_dependency "factory_bot", "~> 6.4"
|
54
|
+
spec.add_development_dependency "rubocop-airbnb", "~> 6.0"
|
55
|
+
spec.add_development_dependency "simplecov", "~> 0.22"
|
56
|
+
spec.add_development_dependency "bundler-audit", "~> 0.9"
|
57
|
+
spec.add_development_dependency "pry", "~> 0.14"
|
58
|
+
spec.add_development_dependency "pry-byebug", "~> 3.10"
|
59
|
+
end
|