collavre_github 0.2.1 → 0.3.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 +4 -4
- data/README.md +18 -92
- data/app/controllers/collavre_github/creatives/integrations_controller.rb +16 -14
- data/app/views/collavre_github/integrations/_modal.html.erb +0 -14
- data/config/locales/en.yml +0 -2
- data/config/locales/ko.yml +0 -2
- data/db/seeds.rb +37 -24
- data/lib/collavre_github/version.rb +1 -1
- metadata +1 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 9ce895f4545efb354576c1a9636f85a7e3146ce3eb25a49d2a7e0f8af44ebd15
|
|
4
|
+
data.tar.gz: cdc47306b0603e03c024ed34aaff62ef5015a74846977e9f2880137adf254527
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 0633fc7163c737da1f884a3844139d644f04728c8e851dff5421d2ab0712df8b5225cd97ac61c9af0a36289470d7ee7dda192a19c00884478ce6178a47bacc0b
|
|
7
|
+
data.tar.gz: 66d8add3b1092206f2af6e02005f22e41348b24dda7f32c0133a1f21cd6e050a01f6974c7e4215551dd98ad84a6cac937b4888658b413967ac749eded6337c1d
|
data/README.md
CHANGED
|
@@ -2,126 +2,52 @@
|
|
|
2
2
|
|
|
3
3
|
GitHub integration engine for Collavre.
|
|
4
4
|
|
|
5
|
+
## Documentation
|
|
6
|
+
|
|
7
|
+
**→ [Full Setup Guide](docs/SETUP.md)** — OAuth, webhooks, AI agent, on-premises deployment
|
|
8
|
+
|
|
5
9
|
## Features
|
|
6
10
|
|
|
7
|
-
- OAuth authentication with GitHub
|
|
11
|
+
- OAuth authentication with GitHub (including GitHub Enterprise)
|
|
8
12
|
- Repository linking to Creatives
|
|
9
13
|
- Webhook → System Comment automatic creation
|
|
10
14
|
- **MCP Tools** for AI Agents to analyze PRs
|
|
11
|
-
- **Seed AI Agent**: GitHub PR Analyzer
|
|
15
|
+
- **Seed AI Agent**: GitHub PR Analyzer (minimal context: `chat_history: 1`)
|
|
12
16
|
|
|
13
17
|
## Architecture
|
|
14
18
|
|
|
15
19
|
```
|
|
16
|
-
GitHub Webhook (
|
|
20
|
+
GitHub Webhook (pull_request event)
|
|
17
21
|
│
|
|
18
22
|
▼
|
|
19
23
|
System Comment created in linked Creative
|
|
20
24
|
│
|
|
21
25
|
▼
|
|
22
|
-
comment_created event dispatched
|
|
23
|
-
│
|
|
24
|
-
▼
|
|
25
26
|
AI Agent (GitHub PR Analyzer) triggered
|
|
26
27
|
│
|
|
27
|
-
├── github_pr_details
|
|
28
|
-
├── github_pr_diff
|
|
29
|
-
├── github_pr_commits
|
|
30
|
-
└── creative_retrieval_service
|
|
28
|
+
├── github_pr_details
|
|
29
|
+
├── github_pr_diff
|
|
30
|
+
├── github_pr_commits
|
|
31
|
+
└── creative_retrieval_service
|
|
31
32
|
│
|
|
32
33
|
▼
|
|
33
|
-
Action Comment
|
|
34
|
-
│
|
|
35
|
-
▼
|
|
36
|
-
User approval → Creative updates
|
|
34
|
+
Action Comment → User approval → Creative updates
|
|
37
35
|
```
|
|
38
36
|
|
|
39
|
-
##
|
|
40
|
-
|
|
41
|
-
Tools for AI Agents to interact with GitHub:
|
|
42
|
-
|
|
43
|
-
| Tool | Description |
|
|
44
|
-
|------|-------------|
|
|
45
|
-
| `github_pr_details` | Get PR title, body, author, files, additions/deletions |
|
|
46
|
-
| `github_pr_diff` | Get PR diff with truncation support (default: 10K chars) |
|
|
47
|
-
| `github_pr_commits` | Get list of commit messages in the PR |
|
|
48
|
-
|
|
49
|
-
### Tool Parameters
|
|
37
|
+
## Quick Start
|
|
50
38
|
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
The tools automatically find the GitHub account through:
|
|
57
|
-
```
|
|
58
|
-
Creative → RepositoryLink → GithubAccount → GitHub API
|
|
59
|
-
```
|
|
60
|
-
|
|
61
|
-
## Seed AI Agent
|
|
62
|
-
|
|
63
|
-
Running `rails db:seed` creates the **GitHub PR Analyzer** agent:
|
|
64
|
-
|
|
65
|
-
- **Name**: GitHub PR Analyzer
|
|
66
|
-
- **Email**: `github-pr-analyzer@collavre.local`
|
|
67
|
-
- **Trigger**: GitHub PR merged events (system comments)
|
|
68
|
-
- **Tools**: github_pr_details, github_pr_diff, github_pr_commits, creative_retrieval_service, creative_update_service
|
|
69
|
-
- **Output**: Action comments for updating Creative progress
|
|
70
|
-
|
|
71
|
-
### Routing Expression
|
|
72
|
-
|
|
73
|
-
```liquid
|
|
74
|
-
event_name == "comment_created" and chat.comment.user_id == nil and chat.comment.content contains "GitHub: Pull Request merged"
|
|
75
|
-
```
|
|
39
|
+
1. Register a GitHub OAuth App ([details](docs/SETUP.md#1-register-a-github-oauth-application))
|
|
40
|
+
2. Set `GITHUB_CLIENT_ID` and `GITHUB_CLIENT_SECRET`
|
|
41
|
+
3. Run `rails db:seed` to create the PR Analyzer agent
|
|
42
|
+
4. Link a repository to a Creative via the integration modal
|
|
76
43
|
|
|
77
44
|
## Installation
|
|
78
45
|
|
|
79
|
-
Add to your Gemfile:
|
|
80
|
-
|
|
81
46
|
```ruby
|
|
47
|
+
# Gemfile
|
|
82
48
|
gem "collavre_github", path: "engines/collavre_github"
|
|
83
49
|
```
|
|
84
50
|
|
|
85
|
-
## Configuration
|
|
86
|
-
|
|
87
|
-
### OAuth Setup
|
|
88
|
-
|
|
89
|
-
1. Create a GitHub OAuth App at https://github.com/settings/developers
|
|
90
|
-
2. Set callback URL to: `https://your-domain.com/auth/github/callback`
|
|
91
|
-
3. Add credentials:
|
|
92
|
-
|
|
93
|
-
```bash
|
|
94
|
-
bin/rails credentials:edit
|
|
95
|
-
```
|
|
96
|
-
|
|
97
|
-
```yaml
|
|
98
|
-
github:
|
|
99
|
-
client_id: your_client_id
|
|
100
|
-
client_secret: your_client_secret
|
|
101
|
-
webhook_secret: optional_fallback_secret
|
|
102
|
-
```
|
|
103
|
-
|
|
104
|
-
### OmniAuth Configuration
|
|
105
|
-
|
|
106
|
-
In `config/initializers/omniauth.rb`:
|
|
107
|
-
|
|
108
|
-
```ruby
|
|
109
|
-
Rails.application.config.middleware.use OmniAuth::Builder do
|
|
110
|
-
provider :github,
|
|
111
|
-
Rails.application.credentials.dig(:github, :client_id),
|
|
112
|
-
Rails.application.credentials.dig(:github, :client_secret),
|
|
113
|
-
scope: "repo,read:org"
|
|
114
|
-
end
|
|
115
|
-
```
|
|
116
|
-
|
|
117
|
-
## Usage
|
|
118
|
-
|
|
119
|
-
1. Connect GitHub account via OAuth
|
|
120
|
-
2. Link repository to a Creative
|
|
121
|
-
3. Webhook events automatically create system comments
|
|
122
|
-
4. AI Agent analyzes PRs and suggests task updates
|
|
123
|
-
5. User approves action comments to update Creatives
|
|
124
|
-
|
|
125
51
|
## License
|
|
126
52
|
|
|
127
53
|
AGPL
|
|
@@ -2,6 +2,7 @@ module CollavreGithub
|
|
|
2
2
|
module Creatives
|
|
3
3
|
class IntegrationsController < ApplicationController
|
|
4
4
|
before_action :set_creative
|
|
5
|
+
before_action :set_origin
|
|
5
6
|
before_action :ensure_read_permission
|
|
6
7
|
before_action :ensure_admin_permission, only: [ :show, :update ]
|
|
7
8
|
|
|
@@ -9,6 +10,10 @@ module CollavreGithub
|
|
|
9
10
|
account = Current.user.github_account
|
|
10
11
|
links = linked_repository_links(account)
|
|
11
12
|
|
|
13
|
+
# Also include repositories linked by other users for this creative
|
|
14
|
+
all_links = @creative.github_repository_links.includes(:github_account)
|
|
15
|
+
all_repositories = all_links.map(&:repository_full_name).uniq
|
|
16
|
+
|
|
12
17
|
render json: {
|
|
13
18
|
connected: account.present?,
|
|
14
19
|
account: account && {
|
|
@@ -17,8 +22,8 @@ module CollavreGithub
|
|
|
17
22
|
avatar_url: account.avatar_url
|
|
18
23
|
},
|
|
19
24
|
selected_repositories: links.map(&:repository_full_name),
|
|
20
|
-
|
|
21
|
-
|
|
25
|
+
all_repositories: all_repositories,
|
|
26
|
+
webhooks: serialize_webhooks(links)
|
|
22
27
|
}
|
|
23
28
|
end
|
|
24
29
|
|
|
@@ -31,7 +36,6 @@ module CollavreGithub
|
|
|
31
36
|
|
|
32
37
|
integration_attributes = integration_params
|
|
33
38
|
repositories = Array(integration_attributes[:repositories]).map(&:to_s).uniq
|
|
34
|
-
prompt_param = integration_attributes[:github_gemini_prompt] if integration_attributes.key?(:github_gemini_prompt)
|
|
35
39
|
|
|
36
40
|
links = nil
|
|
37
41
|
|
|
@@ -41,17 +45,13 @@ module CollavreGithub
|
|
|
41
45
|
.delete_all
|
|
42
46
|
|
|
43
47
|
repositories.each do |full_name|
|
|
44
|
-
@
|
|
48
|
+
@origin.github_repository_links.find_or_create_by!(
|
|
45
49
|
github_account: account,
|
|
46
50
|
repository_full_name: full_name
|
|
47
51
|
)
|
|
48
52
|
end
|
|
49
53
|
|
|
50
54
|
links = linked_repository_links(account).to_a
|
|
51
|
-
|
|
52
|
-
if prompt_param
|
|
53
|
-
@creative.update!(github_gemini_prompt: prompt_param.presence)
|
|
54
|
-
end
|
|
55
55
|
end
|
|
56
56
|
|
|
57
57
|
CollavreGithub::WebhookProvisioner.ensure_for_links(
|
|
@@ -63,8 +63,7 @@ module CollavreGithub
|
|
|
63
63
|
render json: {
|
|
64
64
|
success: true,
|
|
65
65
|
selected_repositories: links.map(&:repository_full_name),
|
|
66
|
-
webhooks: serialize_webhooks(links)
|
|
67
|
-
github_gemini_prompt: @creative.github_gemini_prompt_template
|
|
66
|
+
webhooks: serialize_webhooks(links)
|
|
68
67
|
}
|
|
69
68
|
rescue ActiveRecord::RecordInvalid => e
|
|
70
69
|
render json: { error: e.message }, status: :unprocessable_entity
|
|
@@ -132,8 +131,7 @@ module CollavreGithub
|
|
|
132
131
|
render json: {
|
|
133
132
|
success: true,
|
|
134
133
|
selected_repositories: links.pluck(:repository_full_name),
|
|
135
|
-
webhooks: serialize_webhooks(links)
|
|
136
|
-
github_gemini_prompt: @creative.github_gemini_prompt_template
|
|
134
|
+
webhooks: serialize_webhooks(links)
|
|
137
135
|
}
|
|
138
136
|
end
|
|
139
137
|
|
|
@@ -143,6 +141,10 @@ module CollavreGithub
|
|
|
143
141
|
@creative = Collavre::Creative.find(params[:creative_id])
|
|
144
142
|
end
|
|
145
143
|
|
|
144
|
+
def set_origin
|
|
145
|
+
@origin = @creative.effective_origin
|
|
146
|
+
end
|
|
147
|
+
|
|
146
148
|
def ensure_read_permission
|
|
147
149
|
return if @creative.has_permission?(Current.user, :read)
|
|
148
150
|
|
|
@@ -158,11 +160,11 @@ module CollavreGithub
|
|
|
158
160
|
def linked_repository_links(account)
|
|
159
161
|
return CollavreGithub::RepositoryLink.none unless account
|
|
160
162
|
|
|
161
|
-
@
|
|
163
|
+
@origin.github_repository_links.where(github_account: account)
|
|
162
164
|
end
|
|
163
165
|
|
|
164
166
|
def integration_params
|
|
165
|
-
params.permit(
|
|
167
|
+
params.permit(repositories: [])
|
|
166
168
|
end
|
|
167
169
|
|
|
168
170
|
def serialize_webhooks(links)
|
|
@@ -50,20 +50,6 @@
|
|
|
50
50
|
<p id="github-summary-empty" class="github-modal-empty" style="display:none;"><%= t('collavre_github.integration.summary_empty', default: 'No repositories selected.') %></p>
|
|
51
51
|
</div>
|
|
52
52
|
|
|
53
|
-
<div class="github-wizard-step" id="github-step-prompt" style="display:none;">
|
|
54
|
-
<p class="github-modal-subtext"><%= t('collavre_github.integration.prompt_title', default: 'Review the Gemini analysis prompt and edit it if needed.') %></p>
|
|
55
|
-
<textarea id="github-gemini-prompt" style="width:100%;min-height:220px;padding:0.75em;border:1px solid var(--color-border);border-radius:4px;font-family:monospace;font-size:0.95em;"></textarea>
|
|
56
|
-
<p class="github-modal-subtext" style="margin-top:0.75em;font-size:0.9em;">
|
|
57
|
-
<%= t('collavre_github.integration.prompt_help', default: 'Use the placeholders below to inject runtime details as needed:') %>
|
|
58
|
-
<code>#{pr_title}</code>,
|
|
59
|
-
<code>#{pr_body}</code>,
|
|
60
|
-
<code>#{commit_messages}</code>,
|
|
61
|
-
<code>#{diff}</code>,
|
|
62
|
-
<code>#{creative_tree}</code>,
|
|
63
|
-
<code>#{language_instructions}</code>
|
|
64
|
-
</p>
|
|
65
|
-
</div>
|
|
66
|
-
|
|
67
53
|
<div id="github-wizard-error" style="display:none;margin:0.5em 0;color:#c0392b;font-weight:bold;"></div>
|
|
68
54
|
|
|
69
55
|
<div class="github-wizard-footer" style="display:flex;justify-content:space-between;gap:0.5em;margin-top:1.5em;">
|
data/config/locales/en.yml
CHANGED
|
@@ -23,8 +23,6 @@ en:
|
|
|
23
23
|
summary: "The following repositories will be linked to this Creative:"
|
|
24
24
|
webhook_instructions: "Configure each repository with the webhook details below."
|
|
25
25
|
summary_empty: "No repositories selected."
|
|
26
|
-
prompt_title: "Review the Gemini analysis prompt and edit it if needed."
|
|
27
|
-
prompt_help: "Use the placeholders below to inject runtime details as needed:"
|
|
28
26
|
auth:
|
|
29
27
|
login_first: "Please log in first to connect your GitHub account"
|
|
30
28
|
connected: "GitHub account connected successfully"
|
data/config/locales/ko.yml
CHANGED
|
@@ -23,8 +23,6 @@ ko:
|
|
|
23
23
|
summary: "다음 저장소가 이 Creative에 연동됩니다:"
|
|
24
24
|
webhook_instructions: "각 저장소에 아래 웹훅 정보를 설정하세요."
|
|
25
25
|
summary_empty: "선택된 저장소가 없습니다."
|
|
26
|
-
prompt_title: "Gemini 분석 프롬프트를 검토하고 필요시 수정하세요."
|
|
27
|
-
prompt_help: "다음 플레이스홀더를 사용하여 런타임 정보를 주입할 수 있습니다:"
|
|
28
26
|
auth:
|
|
29
27
|
login_first: "GitHub 계정을 연결하려면 먼저 로그인하세요"
|
|
30
28
|
connected: "GitHub 계정이 연결되었습니다"
|
data/db/seeds.rb
CHANGED
|
@@ -10,11 +10,17 @@ module CollavreGithub
|
|
|
10
10
|
SYSTEM_PROMPT = <<~PROMPT
|
|
11
11
|
You are a GitHub Pull Request Analyzer. Your role is to analyze merged PRs and help maintain the project task tree (Creatives).
|
|
12
12
|
|
|
13
|
+
## Context
|
|
14
|
+
When triggered, you receive the creative context in the first message. The creative ID is provided
|
|
15
|
+
in the system event. **Always use that creative ID** when calling GitHub tools (`creative_id` parameter).
|
|
16
|
+
The repository name (e.g., "owner/repo") is included in the webhook event message.
|
|
17
|
+
|
|
13
18
|
## When you receive a GitHub PR merged event:
|
|
14
|
-
1.
|
|
15
|
-
2. Use `
|
|
16
|
-
3. Use `
|
|
17
|
-
4. Use `
|
|
19
|
+
1. Extract the `repo` (e.g., "sh1nj1/plan42") and `pr_number` from the event message
|
|
20
|
+
2. Use `github_pr_details(creative_id: <creative_id from context>, repo: <repo>, pr_number: <number>)` to get PR information
|
|
21
|
+
3. Use `github_pr_diff` to analyze code changes
|
|
22
|
+
4. Use `github_pr_commits` to understand the work done
|
|
23
|
+
5. Use `creative_retrieval_service` to see the current task tree
|
|
18
24
|
|
|
19
25
|
## Analysis Guidelines:
|
|
20
26
|
- Match PR changes to existing tasks in the Creative tree
|
|
@@ -23,33 +29,32 @@ module CollavreGithub
|
|
|
23
29
|
- Consider the PR title, description, and commit messages for context
|
|
24
30
|
|
|
25
31
|
## Response Format:
|
|
26
|
-
After your analysis,
|
|
32
|
+
After your analysis, use the `creative_batch_service` tool to apply all changes at once.
|
|
33
|
+
This tool accepts an array of operations (create, update, delete) and executes them in a single transaction.
|
|
27
34
|
|
|
28
|
-
|
|
29
|
-
```json
|
|
30
|
-
{
|
|
31
|
-
"actions": [
|
|
32
|
-
{ "action": "update_creative", "creative_id": <id>, "attributes": { "progress": 1.0 } }
|
|
33
|
-
]
|
|
34
|
-
}
|
|
35
|
+
Example tool call:
|
|
35
36
|
```
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
{ "action": "create_creative", "parent_id": <parent_id>, "attributes": { "description": "Task description" } }
|
|
37
|
+
creative_batch_service({
|
|
38
|
+
operations: [
|
|
39
|
+
{ action: "update", id: 123, progress: 1.0 },
|
|
40
|
+
{ action: "create", parent_id: 456, description: "New task discovered" },
|
|
41
|
+
{ action: "delete", id: 789 }
|
|
42
42
|
]
|
|
43
|
-
}
|
|
43
|
+
})
|
|
44
44
|
```
|
|
45
45
|
|
|
46
|
-
You can combine multiple actions in a single response.
|
|
47
|
-
|
|
48
46
|
## Important:
|
|
49
47
|
- Only suggest updates for tasks that are clearly addressed by the PR
|
|
50
48
|
- Be conservative - don't mark tasks complete unless the PR clearly resolves them
|
|
51
|
-
- Provide a brief summary of your analysis before the
|
|
52
|
-
- If no task updates are needed, just provide your analysis summary without
|
|
49
|
+
- Provide a brief summary of your analysis before calling the tool
|
|
50
|
+
- If no task updates are needed, just provide your analysis summary without calling any tool
|
|
51
|
+
- The batch tool requires approval — a human will review and approve your changes before they are applied
|
|
52
|
+
|
|
53
|
+
## Progress Update Rules:
|
|
54
|
+
- You can ONLY set progress to 1.0 (100% complete) — partial progress values are NOT allowed
|
|
55
|
+
- You can ONLY update progress on LEAF Creatives (Creatives with no children)
|
|
56
|
+
- Parent Creative progress is automatically calculated from their children — never try to update it directly
|
|
57
|
+
- Use `creative_retrieval_service` to navigate the tree and find the correct leaf Creative before updating
|
|
53
58
|
PROMPT
|
|
54
59
|
|
|
55
60
|
# Matches GitHub PR merged events
|
|
@@ -58,12 +63,19 @@ module CollavreGithub
|
|
|
58
63
|
event_name == "comment_created" and comment.user_id == nil and comment.content contains "GitHub: Pull Request Merged"
|
|
59
64
|
EXPR
|
|
60
65
|
|
|
66
|
+
AGENT_CONF = <<~YAML
|
|
67
|
+
context:
|
|
68
|
+
chat_history: 1
|
|
69
|
+
chat_history_size: 1000
|
|
70
|
+
creative_children_level: 0
|
|
71
|
+
YAML
|
|
72
|
+
|
|
61
73
|
TOOLS = %w[
|
|
62
74
|
github_pr_details
|
|
63
75
|
github_pr_diff
|
|
64
76
|
github_pr_commits
|
|
65
77
|
creative_retrieval_service
|
|
66
|
-
|
|
78
|
+
creative_batch_service
|
|
67
79
|
].freeze
|
|
68
80
|
|
|
69
81
|
def self.call
|
|
@@ -94,6 +106,7 @@ module CollavreGithub
|
|
|
94
106
|
llm_model: default_llm_model,
|
|
95
107
|
system_prompt: SYSTEM_PROMPT,
|
|
96
108
|
routing_expression: ROUTING_EXPRESSION,
|
|
109
|
+
agent_conf: AGENT_CONF,
|
|
97
110
|
tools: TOOLS,
|
|
98
111
|
searchable: true # Can analyze PRs for any Creative with GitHub integration
|
|
99
112
|
)
|