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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 50424fdf0088dc86fb97487d9f97f57fdeefecd21cfdb0e3986a00cb60907afa
4
- data.tar.gz: ac0121978c125fa9afad5a1fda087d7e5c2a34a3c50ca7e4f6b1ce5cd5fdcc74
3
+ metadata.gz: 9ce895f4545efb354576c1a9636f85a7e3146ce3eb25a49d2a7e0f8af44ebd15
4
+ data.tar.gz: cdc47306b0603e03c024ed34aaff62ef5015a74846977e9f2880137adf254527
5
5
  SHA512:
6
- metadata.gz: a3fdc3d50981d0822a4ab672f6e2eaffce62ab1f44529c4412494c22e9dd7fec5414b27411b786367db34477f126d128d766ca74b3849657bad6d3ba405bcee9
7
- data.tar.gz: f9e54531d9d676e41fa77f95ce6869ff42731c46e8426272d0d0bf1056aef0ad9da246de37d7e1aae5b0cc1ecbb6017833f22642d3eeac504b8ffab512965510
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 (push, pull_request, etc.)
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 - Get PR info
28
- ├── github_pr_diff - Get code changes
29
- ├── github_pr_commits - Get commit messages
30
- └── creative_retrieval_service - Get task tree
28
+ ├── github_pr_details
29
+ ├── github_pr_diff
30
+ ├── github_pr_commits
31
+ └── creative_retrieval_service
31
32
 
32
33
 
33
- Action Comment response (JSON format)
34
-
35
-
36
- User approval → Creative updates
34
+ Action Comment User approval → Creative updates
37
35
  ```
38
36
 
39
- ## MCP Tools
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
- All tools require:
52
- - `creative_id` - The Creative with GitHub integration
53
- - `repo` - Repository full name (e.g., `owner/repo`)
54
- - `pr_number` - Pull request number
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
- webhooks: serialize_webhooks(links),
21
- github_gemini_prompt: @creative.github_gemini_prompt_template
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
- @creative.github_repository_links.find_or_create_by!(
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
- @creative.github_repository_links.where(github_account: account)
163
+ @origin.github_repository_links.where(github_account: account)
162
164
  end
163
165
 
164
166
  def integration_params
165
- params.permit(:github_gemini_prompt, repositories: [])
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;">
@@ -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"
@@ -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. Use `github_pr_details` to get PR information
15
- 2. Use `github_pr_diff` to analyze code changes
16
- 3. Use `github_pr_commits` to understand the work done
17
- 4. Use `creative_retrieval_service` to see the current task tree
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, if you identify tasks to update or create, respond with an action comment.
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
- For completed tasks, suggest updating progress to 1.0:
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
- For new tasks discovered:
38
- ```json
39
- {
40
- "actions": [
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 action JSON
52
- - If no task updates are needed, just provide your analysis summary without action JSON
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
- creative_update_service
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
  )
@@ -1,3 +1,3 @@
1
1
  module CollavreGithub
2
- VERSION = "0.2.1"
2
+ VERSION = "0.3.0"
3
3
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: collavre_github
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.1
4
+ version: 0.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Collavre