brainiac 0.0.6 → 0.0.7
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/Gemfile.lock +2 -2
- data/README.md +136 -6
- data/bin/brainiac +382 -11
- data/bin/brainiac-completion.bash +1 -1
- data/lib/brainiac/agents.rb +15 -38
- data/lib/brainiac/config.rb +40 -11
- data/lib/brainiac/handlers/discord/api.rb +196 -0
- data/lib/brainiac/handlers/discord/config.rb +134 -0
- data/lib/brainiac/handlers/discord/delivery.rb +196 -0
- data/lib/brainiac/handlers/discord/gateway.rb +212 -0
- data/lib/brainiac/handlers/discord/message.rb +933 -0
- data/lib/brainiac/handlers/discord/reactions.rb +215 -0
- data/lib/brainiac/handlers/discord.rb +14 -1892
- data/lib/brainiac/handlers/fizzy/assignment.rb +125 -0
- data/lib/brainiac/handlers/fizzy/comments.rb +730 -0
- data/lib/brainiac/handlers/fizzy/dedup.rb +74 -0
- data/lib/brainiac/handlers/fizzy/deploy.rb +152 -0
- data/lib/brainiac/{deployments.rb → handlers/fizzy/deployments.rb} +4 -2
- data/lib/brainiac/handlers/fizzy.rb +12 -1290
- data/lib/brainiac/handlers/github.rb +149 -212
- data/lib/brainiac/handlers/shared/git.rb +203 -0
- data/lib/brainiac/handlers/shared/inline_tags.rb +89 -0
- data/lib/brainiac/handlers/zoho.rb +79 -76
- data/lib/brainiac/helpers.rb +2 -121
- data/lib/brainiac/planning.rb +2 -2
- data/lib/brainiac/plugins.rb +129 -0
- data/lib/brainiac/restart.rb +94 -0
- data/lib/brainiac/routes/api.rb +427 -0
- data/lib/brainiac/version.rb +1 -1
- data/lib/brainiac/zoho_mail_api.rb +2 -1
- data/lib/brainiac.rb +7 -0
- data/monitor/daemon.rb +4 -27
- data/monitor/shared.rb +247 -0
- data/monitor/{waybar-deploy-env.rb → waybar/deploy_env.rb} +14 -86
- data/monitor/waybar/setup.rb +232 -0
- data/monitor/waybar/status.rb +51 -0
- data/monitor/{view-logs-rofi.rb → waybar/view_logs.rb} +21 -88
- data/monitor/{deploy-env-macos.rb → xbar/deploy_env.rb} +3 -2
- data/monitor/xbar/plugin.rb +155 -0
- data/monitor/{setup-menubar.rb → xbar/setup.rb} +14 -30
- data/receiver.rb +91 -450
- data/templates/brainiac.json.example +9 -0
- data/templates/cli-providers/kiro.json.example +8 -2
- data/templates/plugins.json.example +3 -0
- metadata +30 -20
- data/lib/user_registry.rb +0 -159
- data/monitor/menubar.rb +0 -295
- data/monitor/setup-waybar-deploy-envs.rb +0 -121
- data/monitor/setup-waybar-deployments.rb +0 -96
- data/monitor/setup-waybar-module.rb +0 -113
- data/monitor/setup-xbar-plugin.rb +0 -35
- data/monitor/view-logs.rb +0 -119
- data/monitor/waybar-config-updater.rb +0 -56
- data/monitor/waybar-deployments.rb +0 -239
- data/monitor/waybar.rb +0 -146
- data/monitor/xbar.3s.rb +0 -179
- /data/lib/brainiac/{card_index.rb → handlers/fizzy/card_index.rb} +0 -0
- /data/monitor/{open-action.sh → xbar/open_action.sh} +0 -0
- /data/monitor/{view-logs-macos.rb → xbar/view_logs.rb} +0 -0
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
# Fizzy card assignment handler.
|
|
4
|
+
#
|
|
5
|
+
# When a card is assigned to a local agent, creates a worktree, builds the prompt,
|
|
6
|
+
# and dispatches the agent to begin work.
|
|
7
|
+
|
|
8
|
+
def handle_card_assigned(payload)
|
|
9
|
+
eventable = payload["eventable"] || {}
|
|
10
|
+
assignees = eventable["assignees"] || []
|
|
11
|
+
|
|
12
|
+
local_names = local_agent_names
|
|
13
|
+
assigned_agent = assignees.map { |a| a["name"] }.find { |name| local_names.include?(name) }
|
|
14
|
+
|
|
15
|
+
assignee_names = assignees.map { |a| a["name"] }.join(", ")
|
|
16
|
+
LOG.info "[Fizzy] Card assigned to: [#{assignee_names}], local agents: [#{local_names.join(", ")}]"
|
|
17
|
+
|
|
18
|
+
unless assigned_agent
|
|
19
|
+
LOG.info "[Fizzy] No local agent matched. Assignees: [#{assignee_names}], Local: [#{local_names.join(", ")}]"
|
|
20
|
+
return [200, { status: "ignored", reason: "wrong assignee" }.to_json]
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
unless authorized?(payload)
|
|
24
|
+
creator_name = payload.dig("creator", "name") || "Unknown"
|
|
25
|
+
notify_unauthorized("card_assigned", creator_name, "card ##{eventable["number"]}")
|
|
26
|
+
return [200, { status: "ignored", reason: "unauthorized" }.to_json]
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
card_number = eventable["number"]
|
|
30
|
+
card_internal_id = eventable["id"]
|
|
31
|
+
title = eventable["title"] || "untitled"
|
|
32
|
+
tags = eventable["tags"] || []
|
|
33
|
+
|
|
34
|
+
project_result = identify_project_by_tags(tags)
|
|
35
|
+
unless project_result
|
|
36
|
+
tag_names = tags.map { |t| t.is_a?(Hash) ? t["name"] : t }.join(", ")
|
|
37
|
+
LOG.warn "No project found for card ##{card_number} with tags: #{tag_names}"
|
|
38
|
+
return [200, { status: "ignored", reason: "no matching project" }.to_json]
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
project_key, project_config = project_result
|
|
42
|
+
repo_path = project_config["repo_path"]
|
|
43
|
+
branch = "fizzy-#{card_number}-#{slugify(title)}"
|
|
44
|
+
|
|
45
|
+
card_key = "card-#{card_number}"
|
|
46
|
+
if session_active?(card_key)
|
|
47
|
+
LOG.info "Skipping card ##{card_number} — agent session already active"
|
|
48
|
+
return [200, { status: "ignored", reason: "session already active" }.to_json]
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
LOG.info "Card ##{card_number} assigned to #{assigned_agent} for project '#{project_key}', " \
|
|
52
|
+
"creating worktree: #{branch} (model: #{detect_model(project_config, tags: tags) || "default"})"
|
|
53
|
+
|
|
54
|
+
react_to_assignment(card_number, repo_path, assigned_agent)
|
|
55
|
+
worktree_path = setup_assigned_worktree(repo_path, branch, card_internal_id, card_number, project_key, assigned_agent)
|
|
56
|
+
|
|
57
|
+
dispatch_assigned_card(
|
|
58
|
+
card_number: card_number, card_internal_id: card_internal_id, title: title, tags: tags,
|
|
59
|
+
branch: branch, worktree_path: worktree_path, project_config: project_config, project_key: project_key,
|
|
60
|
+
agent_name: assigned_agent, model: detect_model(project_config, tags: tags),
|
|
61
|
+
effort: detect_effort(project_config, tags: tags), cli_provider_override: detect_cli_provider(tags: tags)
|
|
62
|
+
)
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
def react_to_assignment(card_number, repo_path, agent_name)
|
|
66
|
+
Thread.new do
|
|
67
|
+
run_cmd("fizzy", "reaction", "create", "--card", card_number.to_s,
|
|
68
|
+
"--content", "👍", chdir: repo_path, env: fizzy_env_for(agent_name))
|
|
69
|
+
rescue StandardError => e
|
|
70
|
+
LOG.warn "Could not add reaction to card: #{e.message}"
|
|
71
|
+
end
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
def setup_assigned_worktree(repo_path, branch, card_internal_id, card_number, project_key, agent_name)
|
|
75
|
+
debounced_repo_fetch(repo_path)
|
|
76
|
+
worktree_path = File.join(File.dirname(repo_path), "#{File.basename(repo_path)}--#{branch}")
|
|
77
|
+
worktree_path = create_or_reuse_worktree(repo_path: repo_path, branch: branch, worktree_path: worktree_path)
|
|
78
|
+
|
|
79
|
+
map = load_card_map
|
|
80
|
+
map[card_internal_id] = {
|
|
81
|
+
"number" => card_number, "branch" => branch, "worktree" => worktree_path,
|
|
82
|
+
"project" => project_key, "agent" => agent_name
|
|
83
|
+
}
|
|
84
|
+
save_card_map(map)
|
|
85
|
+
worktree_path
|
|
86
|
+
end
|
|
87
|
+
|
|
88
|
+
def dispatch_assigned_card(card_number:, card_internal_id:, title:, tags:, branch:, worktree_path:,
|
|
89
|
+
project_config:, project_key:, agent_name:, model:, effort:, cli_provider_override:)
|
|
90
|
+
card_context = prefetch_card_context(card_number, repo_path: project_config["repo_path"], agent_name: agent_name)
|
|
91
|
+
planning_info = detect_planning_mode(text: title, tags: tags, card_internal_id: card_internal_id, card_number: card_number)
|
|
92
|
+
|
|
93
|
+
template_vars = {
|
|
94
|
+
"CARD_NUMBER" => card_number, "CARD_TITLE" => title,
|
|
95
|
+
"BRANCH" => branch, "COMMENT_CREATOR" => agent_name
|
|
96
|
+
}
|
|
97
|
+
brain_ctx = build_brain_context(
|
|
98
|
+
agent_name: agent_name, card_title: title,
|
|
99
|
+
card_number: card_number, project_key: project_key, source: :fizzy
|
|
100
|
+
)
|
|
101
|
+
|
|
102
|
+
prompt = if planning_info
|
|
103
|
+
LOG.info "[Planning] Planning mode active for card ##{card_number}"
|
|
104
|
+
template_vars["CARD_ID"] = planning_info[:card_id]
|
|
105
|
+
render_planning_prompt(PROMPT_CARD_ASSIGNED, template_vars,
|
|
106
|
+
brain_context: brain_ctx, card_context: card_context, agent_name: agent_name)
|
|
107
|
+
else
|
|
108
|
+
template_vars["CARD_ID"] = card_number
|
|
109
|
+
render_prompt(PROMPT_CARD_ASSIGNED, template_vars,
|
|
110
|
+
brain_context: brain_ctx, card_context: card_context, agent_name: agent_name)
|
|
111
|
+
end
|
|
112
|
+
|
|
113
|
+
card_key = "card-#{card_number}"
|
|
114
|
+
pid, log_file = run_agent(prompt,
|
|
115
|
+
project_config: project_config, chdir: worktree_path,
|
|
116
|
+
log_name: "assigned-#{card_number}", model: model, effort: effort,
|
|
117
|
+
agent_name: agent_name, card_number: card_number, source: :fizzy,
|
|
118
|
+
source_context: { card_number: card_number },
|
|
119
|
+
cli_provider: cli_provider_override)
|
|
120
|
+
register_session(card_key, pid, log_file: log_file, supersede_key: card_key, agent_name: agent_name)
|
|
121
|
+
|
|
122
|
+
Thread.new { move_card_to_column(card_number, "right_now", project_config: project_config, agent_name: agent_name) }
|
|
123
|
+
|
|
124
|
+
[200, { status: "processed", card: card_number, branch: branch, project: project_key, agent: agent_name }.to_json]
|
|
125
|
+
end
|