brainiac 0.0.3 → 0.0.4
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 +2 -2
- data/brainiac.gemspec +0 -4
- data/lib/brainiac/handlers/discord.rb +57 -1
- data/lib/brainiac/version.rb +1 -1
- metadata +2 -30
- checksums.yaml.gz.sig +0 -0
- data/certs/stowzilla.pem +0 -26
- data.tar.gz.sig +0 -1
- metadata.gz.sig +0 -0
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 3753442d24d4e39a70b7fd537ebb1e62495a826a42d2a52d16311bf300c1fc9c
|
|
4
|
+
data.tar.gz: 4e44dd38c7d78a51a8b2c73884353e5df911b8a6d28550328d6b906e432f0f5d
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 5dda943f8c6f67ff425ab6850d11e0b131c190441a5f52f1415b39cc42947a00756f19e6416b503a0b6c3f9229eb0dc4ac1cd4a987b0758d373e0be220ab5969
|
|
7
|
+
data.tar.gz: b95eae03330676be88800817be77af1c40b79edf4ab9ac574cfabeba7e0c82b8cd57318905fd150041cc3396f81d6817c4285f8188da266a43724571660f20ee
|
data/Gemfile.lock
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
PATH
|
|
2
2
|
remote: .
|
|
3
3
|
specs:
|
|
4
|
-
brainiac (0.0.
|
|
4
|
+
brainiac (0.0.4)
|
|
5
5
|
puma (~> 7.2)
|
|
6
6
|
rackup (~> 2.3)
|
|
7
7
|
sinatra (~> 4.1)
|
|
@@ -90,7 +90,7 @@ DEPENDENCIES
|
|
|
90
90
|
CHECKSUMS
|
|
91
91
|
ast (2.4.3) sha256=954615157c1d6a382bc27d690d973195e79db7f55e9765ac7c481c60bdb4d383
|
|
92
92
|
base64 (0.3.0) sha256=27337aeabad6ffae05c265c450490628ef3ebd4b67be58257393227588f5a97b
|
|
93
|
-
brainiac (0.0.
|
|
93
|
+
brainiac (0.0.4)
|
|
94
94
|
event_emitter (0.2.6) sha256=c72697bd5cce9d36594be1972c17f1c9a573236f44303a4d1d548080364e1391
|
|
95
95
|
json (2.19.9) sha256=9b9025b7cdddafa38d316eca0b2358488e42d417045c1b90d216a9fefe46b79a
|
|
96
96
|
language_server-protocol (3.17.0.5) sha256=fd1e39a51a28bf3eec959379985a72e296e9f9acfce46f6a79d31ca8760803cc
|
data/README.md
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
# Brainiac
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
Brainiac is a multi-agent orchestration layer for developer workflows. It connects your tools (Fizzy, GitHub, Discord, Zoho) to a team of autonomous AI agents. By managing personas, shared knowledge, and collaborative workflows via @mentions, Brainiac allows you to deploy and manage a unified fleet of AI experts directly from your CLI.
|
|
4
4
|
|
|
5
5
|
## How It Works
|
|
6
6
|
|
|
7
|
-
|
|
7
|
+
Brainiac listens for incoming events and automatically spawns the appropriate AI agent CLI to handle the request. Because each agent maintains its own unique persona and configuration, you can deploy a specialized team—all managed through ~/.kiro/agents/. Project tracking is handled via ~/.brainiac/projects.json, and because the system reloads configurations dynamically, you can iterate on your agent workflows in real-time without ever needing a restart.
|
|
8
8
|
|
|
9
9
|
### Events
|
|
10
10
|
|
data/brainiac.gemspec
CHANGED
|
@@ -10,10 +10,6 @@ Gem::Specification.new do |s|
|
|
|
10
10
|
s.license = "MIT"
|
|
11
11
|
s.required_ruby_version = ">= 3.4"
|
|
12
12
|
|
|
13
|
-
s.cert_chain = ["certs/stowzilla.pem"]
|
|
14
|
-
signing_key_path = File.expand_path("~/.ssh/gem-private_key.pem")
|
|
15
|
-
s.signing_key = signing_key_path if File.exist?(signing_key_path)
|
|
16
|
-
|
|
17
13
|
s.files = `git ls-files -z`.split("\x0").reject { |f| f.start_with?("test/", "tmp/", ".") }
|
|
18
14
|
s.executables = ["brainiac"]
|
|
19
15
|
|
|
@@ -742,6 +742,14 @@ def handle_discord_message(message, agent_key, bot_token, bot_user_id)
|
|
|
742
742
|
# Strip CLI provider tag (e.g. [cli:grok]) from prompt content
|
|
743
743
|
clean_content_for_prompt = clean_content_for_prompt.sub(/\[cli:\w+\]/i, "").strip
|
|
744
744
|
|
|
745
|
+
# Detect chat mode tag: [chat], [question], [?] — skips worktree, uses tmp dir instead
|
|
746
|
+
chat_mode = clean_content.match?(/\[(chat|question|\?)\]/i)
|
|
747
|
+
if chat_mode
|
|
748
|
+
clean_content = clean_content.sub(/\[(chat|question|\?)\]/i, "").strip
|
|
749
|
+
clean_content_for_prompt = clean_content_for_prompt.sub(/\[(chat|question|\?)\]/i, "").strip
|
|
750
|
+
LOG.info "[Discord:#{agent_name}] Chat mode detected — will skip worktree creation"
|
|
751
|
+
end
|
|
752
|
+
|
|
745
753
|
# Find project: inline override > channel mapping > default_project
|
|
746
754
|
if inline_project_key && PROJECTS.key?(inline_project_key)
|
|
747
755
|
project_key = inline_project_key
|
|
@@ -927,7 +935,21 @@ def handle_discord_message(message, agent_key, bot_token, bot_user_id)
|
|
|
927
935
|
thread_map = DISCORD_THREAD_MAP_MUTEX.synchronize { load_discord_thread_map }
|
|
928
936
|
existing = thread_map[thread_map_key]
|
|
929
937
|
|
|
930
|
-
if existing && existing["
|
|
938
|
+
if existing && existing["chat_mode"]
|
|
939
|
+
# Thread was started in chat mode — reuse the tmp dir, don't create a worktree
|
|
940
|
+
thread_worktree_path = existing["worktree"]
|
|
941
|
+
thread_cli_provider = existing["cli_provider"]
|
|
942
|
+
thread_model = existing["model"]
|
|
943
|
+
thread_effort = existing["effort"]
|
|
944
|
+
chat_mode = true
|
|
945
|
+
effective_provider = detect_cli_provider(text: clean_content) || thread_cli_provider
|
|
946
|
+
resolved_for_resume = resolve_project_cli_config(project_config, cli_provider_override: effective_provider, agent_name: agent_name)
|
|
947
|
+
should_resume = resolved_for_resume["resume_flag"] ? true : false
|
|
948
|
+
LOG.info "[Discord:#{agent_name}] Reusing chat mode tmp dir at #{thread_worktree_path} (resume: #{should_resume})"
|
|
949
|
+
elsif chat_mode
|
|
950
|
+
# New chat mode session — skip worktree, tmp dir will be created below
|
|
951
|
+
LOG.info "[Discord:#{agent_name}] Chat mode — skipping worktree creation"
|
|
952
|
+
elsif existing && existing["worktree"] && File.directory?(existing["worktree"])
|
|
931
953
|
# Existing worktree — resume session. Inherit tags from the thread's first dispatch.
|
|
932
954
|
thread_worktree_path = existing["worktree"]
|
|
933
955
|
thread_cli_provider = existing["cli_provider"]
|
|
@@ -989,6 +1011,31 @@ def handle_discord_message(message, agent_key, bot_token, bot_user_id)
|
|
|
989
1011
|
end
|
|
990
1012
|
end
|
|
991
1013
|
|
|
1014
|
+
# Chat mode: create a tmp directory instead of a worktree for lightweight conversational sessions
|
|
1015
|
+
if chat_mode && !thread_worktree_path && thread_map_key
|
|
1016
|
+
chat_tmp_dir = File.join(BRAINIAC_DIR, "tmp", "chat", "#{agent_key}-#{effective_thread_id}")
|
|
1017
|
+
FileUtils.mkdir_p(chat_tmp_dir)
|
|
1018
|
+
thread_worktree_path = chat_tmp_dir
|
|
1019
|
+
|
|
1020
|
+
first_cli_provider = detect_cli_provider(text: clean_content)
|
|
1021
|
+
first_model = project_config ? detect_model(project_config, text: clean_content) : nil
|
|
1022
|
+
first_effort = project_config ? detect_effort(project_config, text: clean_content) : nil
|
|
1023
|
+
thread_cli_provider = first_cli_provider
|
|
1024
|
+
thread_model = first_model
|
|
1025
|
+
thread_effort = first_effort
|
|
1026
|
+
|
|
1027
|
+
DISCORD_THREAD_MAP_MUTEX.synchronize do
|
|
1028
|
+
map = load_discord_thread_map
|
|
1029
|
+
map[thread_map_key] = { "worktree" => chat_tmp_dir, "chat_mode" => true,
|
|
1030
|
+
"project" => PROJECTS.find { |_k, v| v == project_config }&.first,
|
|
1031
|
+
"channel_id" => effective_thread_id, "cli_provider" => first_cli_provider,
|
|
1032
|
+
"model" => first_model, "effort" => first_effort,
|
|
1033
|
+
"created_at" => Time.now.iso8601 }
|
|
1034
|
+
save_discord_thread_map(map)
|
|
1035
|
+
end
|
|
1036
|
+
LOG.info "[Discord:#{agent_name}] Created chat mode tmp dir at #{chat_tmp_dir}"
|
|
1037
|
+
end
|
|
1038
|
+
|
|
992
1039
|
if should_resume && thread_worktree_path
|
|
993
1040
|
# Lean resume prompt — prior session has full context
|
|
994
1041
|
prompt = render_discord_resume_prompt(
|
|
@@ -1038,6 +1085,15 @@ def handle_discord_message(message, agent_key, bot_token, bot_user_id)
|
|
|
1038
1085
|
channel: :discord)
|
|
1039
1086
|
end
|
|
1040
1087
|
|
|
1088
|
+
# Chat mode fallback: if no thread_map_key was available (no thread created, e.g. DM or no project),
|
|
1089
|
+
# still use a tmp dir so we don't fall back to the project repo_path.
|
|
1090
|
+
if chat_mode && !thread_worktree_path
|
|
1091
|
+
chat_tmp_dir = File.join(BRAINIAC_DIR, "tmp", "chat", "#{agent_key}-#{message_id}")
|
|
1092
|
+
FileUtils.mkdir_p(chat_tmp_dir)
|
|
1093
|
+
thread_worktree_path = chat_tmp_dir
|
|
1094
|
+
LOG.info "[Discord:#{agent_name}] Chat mode fallback tmp dir at #{chat_tmp_dir}"
|
|
1095
|
+
end
|
|
1096
|
+
|
|
1041
1097
|
work_dir = thread_worktree_path || (project_config ? project_config["repo_path"] : Dir.pwd)
|
|
1042
1098
|
|
|
1043
1099
|
prompt_file = File.join(response_dir, "discord-prompt-#{timestamp}-#{agent_key}-#{message_id}.md")
|
data/lib/brainiac/version.rb
CHANGED
metadata
CHANGED
|
@@ -1,39 +1,12 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: brainiac
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.0.
|
|
4
|
+
version: 0.0.4
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Andy Davis
|
|
8
8
|
bindir: bin
|
|
9
|
-
cert_chain:
|
|
10
|
-
- |
|
|
11
|
-
-----BEGIN CERTIFICATE-----
|
|
12
|
-
MIIEdDCCAtygAwIBAgIBATANBgkqhkiG9w0BAQsFADBAMQ4wDAYDVQQDDAVhZ2Vu
|
|
13
|
-
dDEZMBcGCgmSJomT8ixkARkWCXN0b3d6aWxsYTETMBEGCgmSJomT8ixkARkWA2Nv
|
|
14
|
-
bTAeFw0yNjA2MDgxOTExNTlaFw0yNzA2MDgxOTExNTlaMEAxDjAMBgNVBAMMBWFn
|
|
15
|
-
ZW50MRkwFwYKCZImiZPyLGQBGRYJc3Rvd3ppbGxhMRMwEQYKCZImiZPyLGQBGRYD
|
|
16
|
-
Y29tMIIBojANBgkqhkiG9w0BAQEFAAOCAY8AMIIBigKCAYEAupBquKI/4WvXOgND
|
|
17
|
-
pXyqH2GllZs1wG4TWWdn/DoMg45UoCwD+AWEuGrIdInBCpPN8vEJNJWPoM/RrU+b
|
|
18
|
-
xRBZT4uUk00bnZRW2SYh5GJSqBoBR+rWc2DGkXyGfdRU2sQvkB0+is6ChgQ61WMM
|
|
19
|
-
33LE9+loBlVsZ6EVtrc18Uh2OW0mJpe0hN2nmBrxZqqOZigxC4DKRMFHvpRkxSb6
|
|
20
|
-
mD4kit1AcwX9NEWJsXxrPaetL/SB/VbXaEZX93XAvp6USaXvCWt4slkDS2mIvqtn
|
|
21
|
-
9DtGC43LFC7SDGbnsG9PVenQgVCi8UWFPUAab0PqZSlmi3Qlbhw8qTGPp5Cbv4vz
|
|
22
|
-
qjC2UGPOQigA/7lbbGRhCohMrjOVHMAQwkcgiIqtolUoYlnvPMIy+m3pdvgDv/PH
|
|
23
|
-
bsZGvXQ7i0458xsmp1vaKthZocVAR+GboHbuIiYPUnO45ccXUQ00x6365tTe7mZi
|
|
24
|
-
NvmUYdAGbQmVvFqyxF7IYA6sF74L2Lstu0knSfss557bAe1HAgMBAAGjeTB3MAkG
|
|
25
|
-
A1UdEwQCMAAwCwYDVR0PBAQDAgSwMB0GA1UdDgQWBBSnxTL/lNBCeLqpeVIX6AUY
|
|
26
|
-
kel4zjAeBgNVHREEFzAVgRNhZ2VudEBzdG93emlsbGEuY29tMB4GA1UdEgQXMBWB
|
|
27
|
-
E2FnZW50QHN0b3d6aWxsYS5jb20wDQYJKoZIhvcNAQELBQADggGBACm9Fjit/UCv
|
|
28
|
-
FxlKqeiCTIG94cIx+QrWAOJSx9knKydwUec1u04D/DbfZjTn3C2Bj227QgxeUn+6
|
|
29
|
-
if3e2v7zAk1896hLmGYzML0+nxQPb0vmtdLR7HETUlSKTVabcv1fbwLyjsuGrBvk
|
|
30
|
-
y51vOEzUEZ508a9yepLYqrQu1kOju4d57c9oA5l3H0mMKWz7av9tFj0B+STvuaWk
|
|
31
|
-
HRYDWc5HgOEVTyV+w0uFt2Kw4OCb8C42uSvC5RfYYtw78MSP+5Ru+LXJ7XOtmuN0
|
|
32
|
-
E6GVmofQ17ig9O3rgfFbMendSInrRmvPIGswvM1yivq9NOllFbdck2OJKPx6FCJF
|
|
33
|
-
7SJIkXQfc9P4B5iASIV1d1FsE0YX+g3jHXPJK/4mGL5bAyBKzpMfQB/mg6vQBzkh
|
|
34
|
-
aOKPwcreFj7TznBl89R5tNS9wZQfPVR98zgPyocddWhK18eQNMSBUnv4eeJ8PPbk
|
|
35
|
-
DovL+G8ajHDZ9fjH/+GVYHEMuiVdLarXrKJpHC1VfGTTUAp4NSEpUQ==
|
|
36
|
-
-----END CERTIFICATE-----
|
|
9
|
+
cert_chain: []
|
|
37
10
|
date: 1980-01-02 00:00:00.000000000 Z
|
|
38
11
|
dependencies:
|
|
39
12
|
- !ruby/object:Gem::Dependency
|
|
@@ -163,7 +136,6 @@ files:
|
|
|
163
136
|
- bin/brainiac
|
|
164
137
|
- bin/brainiac-completion.bash
|
|
165
138
|
- brainiac.gemspec
|
|
166
|
-
- certs/stowzilla.pem
|
|
167
139
|
- docs/waybar-config.md
|
|
168
140
|
- lib/brainiac.rb
|
|
169
141
|
- lib/brainiac/agents.rb
|
checksums.yaml.gz.sig
DELETED
|
Binary file
|
data/certs/stowzilla.pem
DELETED
|
@@ -1,26 +0,0 @@
|
|
|
1
|
-
-----BEGIN CERTIFICATE-----
|
|
2
|
-
MIIEdDCCAtygAwIBAgIBATANBgkqhkiG9w0BAQsFADBAMQ4wDAYDVQQDDAVhZ2Vu
|
|
3
|
-
dDEZMBcGCgmSJomT8ixkARkWCXN0b3d6aWxsYTETMBEGCgmSJomT8ixkARkWA2Nv
|
|
4
|
-
bTAeFw0yNjA2MDgxOTExNTlaFw0yNzA2MDgxOTExNTlaMEAxDjAMBgNVBAMMBWFn
|
|
5
|
-
ZW50MRkwFwYKCZImiZPyLGQBGRYJc3Rvd3ppbGxhMRMwEQYKCZImiZPyLGQBGRYD
|
|
6
|
-
Y29tMIIBojANBgkqhkiG9w0BAQEFAAOCAY8AMIIBigKCAYEAupBquKI/4WvXOgND
|
|
7
|
-
pXyqH2GllZs1wG4TWWdn/DoMg45UoCwD+AWEuGrIdInBCpPN8vEJNJWPoM/RrU+b
|
|
8
|
-
xRBZT4uUk00bnZRW2SYh5GJSqBoBR+rWc2DGkXyGfdRU2sQvkB0+is6ChgQ61WMM
|
|
9
|
-
33LE9+loBlVsZ6EVtrc18Uh2OW0mJpe0hN2nmBrxZqqOZigxC4DKRMFHvpRkxSb6
|
|
10
|
-
mD4kit1AcwX9NEWJsXxrPaetL/SB/VbXaEZX93XAvp6USaXvCWt4slkDS2mIvqtn
|
|
11
|
-
9DtGC43LFC7SDGbnsG9PVenQgVCi8UWFPUAab0PqZSlmi3Qlbhw8qTGPp5Cbv4vz
|
|
12
|
-
qjC2UGPOQigA/7lbbGRhCohMrjOVHMAQwkcgiIqtolUoYlnvPMIy+m3pdvgDv/PH
|
|
13
|
-
bsZGvXQ7i0458xsmp1vaKthZocVAR+GboHbuIiYPUnO45ccXUQ00x6365tTe7mZi
|
|
14
|
-
NvmUYdAGbQmVvFqyxF7IYA6sF74L2Lstu0knSfss557bAe1HAgMBAAGjeTB3MAkG
|
|
15
|
-
A1UdEwQCMAAwCwYDVR0PBAQDAgSwMB0GA1UdDgQWBBSnxTL/lNBCeLqpeVIX6AUY
|
|
16
|
-
kel4zjAeBgNVHREEFzAVgRNhZ2VudEBzdG93emlsbGEuY29tMB4GA1UdEgQXMBWB
|
|
17
|
-
E2FnZW50QHN0b3d6aWxsYS5jb20wDQYJKoZIhvcNAQELBQADggGBACm9Fjit/UCv
|
|
18
|
-
FxlKqeiCTIG94cIx+QrWAOJSx9knKydwUec1u04D/DbfZjTn3C2Bj227QgxeUn+6
|
|
19
|
-
if3e2v7zAk1896hLmGYzML0+nxQPb0vmtdLR7HETUlSKTVabcv1fbwLyjsuGrBvk
|
|
20
|
-
y51vOEzUEZ508a9yepLYqrQu1kOju4d57c9oA5l3H0mMKWz7av9tFj0B+STvuaWk
|
|
21
|
-
HRYDWc5HgOEVTyV+w0uFt2Kw4OCb8C42uSvC5RfYYtw78MSP+5Ru+LXJ7XOtmuN0
|
|
22
|
-
E6GVmofQ17ig9O3rgfFbMendSInrRmvPIGswvM1yivq9NOllFbdck2OJKPx6FCJF
|
|
23
|
-
7SJIkXQfc9P4B5iASIV1d1FsE0YX+g3jHXPJK/4mGL5bAyBKzpMfQB/mg6vQBzkh
|
|
24
|
-
aOKPwcreFj7TznBl89R5tNS9wZQfPVR98zgPyocddWhK18eQNMSBUnv4eeJ8PPbk
|
|
25
|
-
DovL+G8ajHDZ9fjH/+GVYHEMuiVdLarXrKJpHC1VfGTTUAp4NSEpUQ==
|
|
26
|
-
-----END CERTIFICATE-----
|
data.tar.gz.sig
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
U�>�ª뭌��\�~Vt�z�<!ݳ�f0���&�-֏P�K���*�Xj(����sba�"[C��_�rA��r�*�x��HR�]�[ck���ʙ�.�H�Va�&q8�xѪc�f� Y�k��O���ݨ�g�^��tkk�F�x�������B��7�K��,�Ę#���+�AA-�Nj�4�٫�b��3of_7Z(1��^�G��wWZ�z�x�w�Lv.��e.���+5��r�F=��yEC��T�Z�a{'6Z����EDa��z��T��aKQ��d�(e%JL�8{��q���1�R����,8��r�QbE��j�Bd���n��ϫ5�[)�c��P���;o~i��ц�6��^J�V�+A�I��@��+�
|
metadata.gz.sig
DELETED
|
Binary file
|