brainiac 0.1.5 → 0.1.6

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: e0e0e919150a76bcf0b7f289b72cfdbc8000bc0cacf94bc9103685cf49331415
4
- data.tar.gz: 58174d5dcf9d0c3641f9a96317f6d94a4dda153481d586659275e8e81623fd24
3
+ metadata.gz: 66eb8c75d924422aeb756ce7bc59dc503dc8fcab67095267b6c7940f461e6d8d
4
+ data.tar.gz: b7e22617f77bd5ee2882f3651a6622e00984e02193cd8a4554026c6e5245d6d0
5
5
  SHA512:
6
- metadata.gz: 73331c38b19e2ef1bb2d352b0a9b6cf6259d7075022e6ea529ad1203fd8dc30369d83b7d88e603c1ab04a59ec2a96856b01a59fc669a4b43c1efbba847ea2399
7
- data.tar.gz: 917ea682b6749cef4a17d76a2a40d10deabb175c30af77044dc5a3d8be7132ab7f52e8722f8881bc11689c3d597ad83039e107e336cf40d891a0a222396df405
6
+ metadata.gz: 53d31acae1ef2a57be783175db90715adbdf0d3877beda17165feefbbd2e77df3528680984844e28ada13315582942a1aea54268895c203a9d388cb76d20c78a
7
+ data.tar.gz: 8b12a7305c26ac95c3a8c5682645039cac545845efeba325860859ad0299e5b6a429e0eeac157686b648746c82198392e791e55bc102b1f0fc876fe5c2493337
data/README.md CHANGED
@@ -47,9 +47,28 @@ All four channels support inline tags in message/comment text. Tags are stripped
47
47
  | `[branch:branch-name]` | ✓ | ✓ | ✓ | Target an existing branch — reuses its worktree if a work item exists |
48
48
  | `[workitem:wi-abc123]` | ✓ | ✓ | ✓ | Target a specific work item by ID — agent works in its worktree |
49
49
  | `[plan]` | ✓ | ✓ | — | Activate planning mode — agent gathers requirements before coding |
50
+ | `[fork]` `[fork:topic]` | — | ✓ | — | Fork conversation to a new thread — starts unbound (no worktree until implementation) |
50
51
 
51
52
  Model keys come from the project's `allowed_models` config. Fizzy also supports model selection via card tags (e.g. adding an `opus` tag to the card).
52
53
 
54
+ ### Conversation Branching (Discord)
55
+
56
+ Sometimes you want to spin off a tangent without polluting the current conversation's context. Brainiac supports two ways to branch:
57
+
58
+ **🌿 Reaction** — React with 🌿 on any message to fork from that point. The message becomes the root of a new thread.
59
+
60
+ **`[fork]` Tag** — Include `[fork]` or `[fork:topic]` in your message to immediately branch:
61
+
62
+ ```
63
+ @Galen [fork:belt-bug] Hey, unrelated to what we're working on, but I think belt deploy has a bug...
64
+ ```
65
+
66
+ Both methods create a new thread that starts **unbound** — no worktree, no project lock-in. The agent can discuss, search brain, and read files across any registered project. When you ask for actual implementation work, the worktree is created at that point, scoped to the right repo.
67
+
68
+ This solves the "orphaned worktree" problem: if you notice a belt bug while working on brainiac, the branch doesn't create a useless brainiac worktree. The project is resolved when implementation starts.
69
+
70
+ The original conversation continues undisturbed. The branched thread gets its own memory file and context.
71
+
53
72
  ### Planning Mode
54
73
 
55
74
  Add a `[plan]` tag to a Discord message or a `plan` tag to a Fizzy card to activate planning mode. Instead of jumping straight into implementation, the agent:
@@ -22,6 +22,7 @@
22
22
  # fresh: true/false,
23
23
  # deploy_intent: "dev01" / :auto / nil,
24
24
  # worktree_override: "branch-name" or nil,
25
+ # fork_branch: "topic" or true or nil (fork conversation to a new thread),
25
26
  # clean_text: "the message with all tags stripped"
26
27
  # }
27
28
  def parse_inline_tags(text)
@@ -38,6 +39,7 @@ def parse_inline_tags(text)
38
39
  worktree_override: nil,
39
40
  work_item: nil,
40
41
  branch_override: nil,
42
+ fork_branch: nil,
41
43
  clean_text: text.dup
42
44
  }
43
45
 
@@ -110,7 +112,8 @@ def parse_work_item_tags(result)
110
112
  result[:clean_text].sub!(match[0], "")
111
113
  end
112
114
 
113
- # [branch:branch-name] — preferred syntax for targeting a branch/worktree
115
+ # [branch:branch-name] — preferred syntax for targeting a branch/worktree.
116
+ # Note: bare [branch] (no colon/value) is handled below as a fork request.
114
117
  if (match = result[:clean_text].match(/\[branch:([^\]]+)\]/i))
115
118
  result[:branch_override] = match[1].strip
116
119
  # Also set worktree_override for backward compat with plugins that read it
@@ -123,6 +126,21 @@ def parse_work_item_tags(result)
123
126
  result[:work_item] = match[1].strip
124
127
  result[:clean_text].sub!(match[0], "")
125
128
  end
129
+
130
+ # [fork], [fork:topic], or bare [branch] — fork the conversation into a new thread.
131
+ # The new thread starts unbound (no worktree) until implementation work begins.
132
+ # Topic becomes the thread title; without a topic, the message content is used.
133
+ # - [fork:belt-bug] → fork with "belt-bug" as the topic
134
+ # - [fork] → fork with auto-generated topic from message content
135
+ # - [branch] → alias for [fork] (bare [branch] with no value)
136
+ if (match = result[:clean_text].match(/\[fork(?::([^\]]+))?\]/i))
137
+ result[:fork_branch] = match[1]&.strip || true
138
+ result[:clean_text].sub!(match[0], "")
139
+ elsif result[:clean_text].match?(/\[branch\]/i) && !result[:branch_override]
140
+ # Bare [branch] with no value acts as a fork request
141
+ result[:fork_branch] = true
142
+ result[:clean_text].sub!(/\[branch\]/i, "")
143
+ end
126
144
  end
127
145
 
128
146
  def parse_model_tag(result)
@@ -2,5 +2,5 @@
2
2
 
3
3
  module Brainiac
4
4
  # @return [String] the current gem version
5
- VERSION = "0.1.5"
5
+ VERSION = "0.1.6"
6
6
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: brainiac
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.5
4
+ version: 0.1.6
5
5
  platform: ruby
6
6
  authors:
7
7
  - Andy Davis
@@ -117,7 +117,6 @@ extra_rdoc_files: []
117
117
  files:
118
118
  - CHANGELOG.md
119
119
  - Gemfile
120
- - Gemfile.lock
121
120
  - README.md
122
121
  - Rakefile
123
122
  - bin/brainiac
data/Gemfile.lock DELETED
@@ -1,117 +0,0 @@
1
- PATH
2
- remote: .
3
- specs:
4
- brainiac (0.1.5)
5
- puma (~> 7.2)
6
- rackup (~> 2.3)
7
- sinatra (~> 4.1)
8
-
9
- GEM
10
- remote: https://rubygems.org/
11
- specs:
12
- ast (2.4.3)
13
- base64 (0.3.0)
14
- json (2.21.2)
15
- language_server-protocol (3.17.0.6)
16
- lint_roller (1.1.0)
17
- logger (1.7.0)
18
- minitest (5.27.0)
19
- mustermann (3.1.1)
20
- nio4r (2.7.5)
21
- parallel (2.2.0)
22
- parser (3.3.12.0)
23
- ast (~> 2.4.1)
24
- racc
25
- prism (1.9.0)
26
- puma (7.2.1)
27
- nio4r (~> 2.0)
28
- racc (1.8.1)
29
- rack (3.2.7)
30
- rack-protection (4.2.1)
31
- base64 (>= 0.1.0)
32
- logger (>= 1.6.0)
33
- rack (>= 3.0.0, < 4)
34
- rack-session (2.1.2)
35
- base64 (>= 0.1.0)
36
- rack (>= 3.0.0)
37
- rackup (2.3.1)
38
- rack (>= 3)
39
- rainbow (3.1.1)
40
- rake (13.4.2)
41
- regexp_parser (2.12.0)
42
- rubocop (1.88.0)
43
- json (~> 2.3)
44
- language_server-protocol (~> 3.17.0.2)
45
- lint_roller (~> 1.1.0)
46
- parallel (>= 1.10)
47
- parser (>= 3.3.0.2)
48
- rainbow (>= 2.2.2, < 4.0)
49
- regexp_parser (>= 2.9.3, < 3.0)
50
- rubocop-ast (>= 1.49.0, < 2.0)
51
- ruby-progressbar (~> 1.7)
52
- unicode-display_width (>= 2.4.0, < 4.0)
53
- rubocop-ast (1.50.0)
54
- parser (>= 3.3.7.2)
55
- prism (~> 1.7)
56
- rubocop-performance (1.26.1)
57
- lint_roller (~> 1.1)
58
- rubocop (>= 1.75.0, < 2.0)
59
- rubocop-ast (>= 1.47.1, < 2.0)
60
- ruby-progressbar (1.13.0)
61
- sinatra (4.2.1)
62
- logger (>= 1.6.0)
63
- mustermann (~> 3.0)
64
- rack (>= 3.0.0, < 4)
65
- rack-protection (= 4.2.1)
66
- rack-session (>= 2.0.0, < 3)
67
- tilt (~> 2.0)
68
- tilt (2.9.0)
69
- unicode-display_width (3.2.0)
70
- unicode-emoji (~> 4.1)
71
- unicode-emoji (4.2.0)
72
-
73
- PLATFORMS
74
- ruby
75
- x86_64-linux
76
-
77
- DEPENDENCIES
78
- brainiac!
79
- minitest (~> 5.25)
80
- rake (~> 13.0)
81
- rubocop (~> 1.75)
82
- rubocop-performance (~> 1.25)
83
-
84
- CHECKSUMS
85
- ast (2.4.3) sha256=954615157c1d6a382bc27d690d973195e79db7f55e9765ac7c481c60bdb4d383
86
- base64 (0.3.0) sha256=27337aeabad6ffae05c265c450490628ef3ebd4b67be58257393227588f5a97b
87
- brainiac (0.1.5)
88
- json (2.21.2) sha256=1f1d3b7cf2b3ba1a69beca0bb6db13d5438b80bff3cd54cdaaa620b9b07c1c6a
89
- language_server-protocol (3.17.0.6) sha256=5ef2c0c138f8267e1bc631d3328347d354f96724b0af22f2c79516120443b7f0
90
- lint_roller (1.1.0) sha256=2c0c845b632a7d172cb849cc90c1bce937a28c5c8ccccb50dfd46a485003cc87
91
- logger (1.7.0) sha256=196edec7cc44b66cfb40f9755ce11b392f21f7967696af15d274dde7edff0203
92
- minitest (5.27.0) sha256=2d3b17f8a36fe7801c1adcffdbc38233b938eb0b4966e97a6739055a45fa77d5
93
- mustermann (3.1.1) sha256=4c6170c7234d5499c345562ba7c7dfe73e1754286dcc1abb053064d66a127198
94
- nio4r (2.7.5) sha256=6c90168e48fb5f8e768419c93abb94ba2b892a1d0602cb06eef16d8b7df1dca1
95
- parallel (2.2.0) sha256=e1059c5fd7b649558a0aec38a769f06a42942bdb40503d005a59c352fe011cd8
96
- parser (3.3.12.0) sha256=21a6d7f755d5a24dfbdc6e6b772e4e879a52e7631a88bc5a3a134606052c9828
97
- prism (1.9.0) sha256=7b530c6a9f92c24300014919c9dcbc055bf4cdf51ec30aed099b06cd6674ef85
98
- puma (7.2.1) sha256=d7bf0e9cabd532e0d401e142cd94e3ac531e993610e2d80e6fbf9c26961414b0
99
- racc (1.8.1) sha256=4a7f6929691dbec8b5209a0b373bc2614882b55fc5d2e447a21aaa691303d62f
100
- rack (3.2.7) sha256=93e13e1c24f93556671d85d2d79fa228c3485815c50d7e2f265b5330c6528fb7
101
- rack-protection (4.2.1) sha256=cf6e2842df8c55f5e4d1a4be015e603e19e9bc3a7178bae58949ccbb58558bac
102
- rack-session (2.1.2) sha256=595434f8c0c3473ae7d7ac56ecda6cc6dfd9d37c0b2b5255330aa1576967ffe8
103
- rackup (2.3.1) sha256=6c79c26753778e90983761d677a48937ee3192b3ffef6bc963c0950f94688868
104
- rainbow (3.1.1) sha256=039491aa3a89f42efa1d6dec2fc4e62ede96eb6acd95e52f1ad581182b79bc6a
105
- rake (13.4.2) sha256=cb825b2bd5f1f8e91ca37bddb4b9aaf345551b4731da62949be002fa89283701
106
- regexp_parser (2.12.0) sha256=35a916a1d63190ab5c9009457136ae5f3c0c7512d60291d0d1378ba18ce08ebb
107
- rubocop (1.88.0) sha256=e420ddf1662d0ef34bc8a2910ac4b396a7ddda0b51a708264405241734b08e0b
108
- rubocop-ast (1.50.0) sha256=b9ca88300da0803ee222ad20cdb30494c0a784eed06fdc35d254b06d662788db
109
- rubocop-performance (1.26.1) sha256=cd19b936ff196df85829d264b522fd4f98b6c89ad271fa52744a8c11b8f71834
110
- ruby-progressbar (1.13.0) sha256=80fc9c47a9b640d6834e0dc7b3c94c9df37f08cb072b7761e4a71e22cff29b33
111
- sinatra (4.2.1) sha256=b7aeb9b11d046b552972ade834f1f9be98b185fa8444480688e3627625377080
112
- tilt (2.9.0) sha256=da5735d0280bba96e9a91041bb14aee435ccad5c17b0fa519249ae543d9aa3a5
113
- unicode-display_width (3.2.0) sha256=0cdd96b5681a5949cdbc2c55e7b420facae74c4aaf9a9815eee1087cb1853c42
114
- unicode-emoji (4.2.0) sha256=519e69150f75652e40bf736106cfbc8f0f73aa3fb6a65afe62fefa7f80b0f80f
115
-
116
- BUNDLED WITH
117
- 4.0.10