agentilda 1.0.3

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.
Files changed (79) hide show
  1. checksums.yaml +7 -0
  2. data/Gemfile +26 -0
  3. data/Gemfile.lock +261 -0
  4. data/agentilda.gemspec +57 -0
  5. data/agents/hansolo-reviewer.md +29 -0
  6. data/agents/lando-broker.md +74 -0
  7. data/agents/leah-researcher.md +80 -0
  8. data/agents/luke-backend.md +81 -0
  9. data/agents/palpatine-planner.md +40 -0
  10. data/agents/rey-frontend.md +106 -0
  11. data/agents/yoda-writer.md +54 -0
  12. data/bin/create-plan-folder +125 -0
  13. data/bin/plan-number +164 -0
  14. data/exe/agentilda +111 -0
  15. data/exe/tilda +1 -0
  16. data/lib/agentilda/adoption.rb +192 -0
  17. data/lib/agentilda/agent.rb +136 -0
  18. data/lib/agentilda/brief.rb +234 -0
  19. data/lib/agentilda/cli/agents/subcommands/describe.rb +62 -0
  20. data/lib/agentilda/cli/agents/subcommands/list.rb +20 -0
  21. data/lib/agentilda/cli/base.rb +88 -0
  22. data/lib/agentilda/cli/create/create.rb +309 -0
  23. data/lib/agentilda/cli/docs/docs.rb +30 -0
  24. data/lib/agentilda/cli/index/index.rb +38 -0
  25. data/lib/agentilda/cli/linear/linear.rb +35 -0
  26. data/lib/agentilda/cli/linear/subcommands/import.rb +160 -0
  27. data/lib/agentilda/cli/linear/subcommands/projects.rb +55 -0
  28. data/lib/agentilda/cli/list_plans/list_plans.rb +21 -0
  29. data/lib/agentilda/cli/resync/subcommands/dirs.rb +49 -0
  30. data/lib/agentilda/cli/resync/subcommands/prs.rb +106 -0
  31. data/lib/agentilda/cli/run/run.rb +289 -0
  32. data/lib/agentilda/cli/states/states.rb +15 -0
  33. data/lib/agentilda/cli/unblock/unblock.rb +227 -0
  34. data/lib/agentilda/cli/version/version.rb +13 -0
  35. data/lib/agentilda/cli.rb +74 -0
  36. data/lib/agentilda/config.rb +44 -0
  37. data/lib/agentilda/control.rb +115 -0
  38. data/lib/agentilda/creator.rb +120 -0
  39. data/lib/agentilda/dev_work.rb +54 -0
  40. data/lib/agentilda/diagram.rb +144 -0
  41. data/lib/agentilda/documentation.rb +429 -0
  42. data/lib/agentilda/executor.rb +539 -0
  43. data/lib/agentilda/feature.rb +253 -0
  44. data/lib/agentilda/frontmatter.rb +36 -0
  45. data/lib/agentilda/github.rb +160 -0
  46. data/lib/agentilda/index.rb +206 -0
  47. data/lib/agentilda/keyboard.rb +88 -0
  48. data/lib/agentilda/linear/api.rb +220 -0
  49. data/lib/agentilda/linear/attribution.rb +185 -0
  50. data/lib/agentilda/linear/fuzzy.rb +68 -0
  51. data/lib/agentilda/linear/import.rb +298 -0
  52. data/lib/agentilda/linear/issue.rb +184 -0
  53. data/lib/agentilda/linear/mapping.rb +115 -0
  54. data/lib/agentilda/linear/push.rb +190 -0
  55. data/lib/agentilda/linear/survey.rb +173 -0
  56. data/lib/agentilda/linear/unit.rb +274 -0
  57. data/lib/agentilda/linear.rb +42 -0
  58. data/lib/agentilda/markdown.rb +56 -0
  59. data/lib/agentilda/ordinal.rb +90 -0
  60. data/lib/agentilda/progress_log.rb +122 -0
  61. data/lib/agentilda/publisher.rb +172 -0
  62. data/lib/agentilda/pull_request.rb +213 -0
  63. data/lib/agentilda/reporter.rb +175 -0
  64. data/lib/agentilda/resync.rb +358 -0
  65. data/lib/agentilda/roster.rb +110 -0
  66. data/lib/agentilda/runner.rb +456 -0
  67. data/lib/agentilda/state_machine.rb +355 -0
  68. data/lib/agentilda/status.rb +280 -0
  69. data/lib/agentilda/tally.rb +169 -0
  70. data/lib/agentilda/transcript.rb +435 -0
  71. data/lib/agentilda/tree.rb +77 -0
  72. data/lib/agentilda/ui.rb +681 -0
  73. data/lib/agentilda/unblocker.rb +207 -0
  74. data/lib/agentilda/version.rb +10 -0
  75. data/lib/agentilda/viewer.rb +60 -0
  76. data/lib/agentilda/worktree.rb +211 -0
  77. data/lib/agentilda.rb +155 -0
  78. data/lib/dry/cli/banner.rb +293 -0
  79. metadata +349 -0
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 80d6ed63ab2dd3994b169023e8433a131d7d3ff9aeda5d6a23d4c45c79fcb3c4
4
+ data.tar.gz: 3a7e3ad6859501804c73bdc596dc7f0c73952e011dc3d50549cc44e208cc7e0c
5
+ SHA512:
6
+ metadata.gz: a3533bdb01bbc8514c5a059840269fb599a13eaecf2b065002eb57a8424be07f404c12d7445b8d55b357e51223ad83ac3b13ac37c8ea39c684d52f147c0ddd81
7
+ data.tar.gz: 3ae4fa7b60baa409f5e5aa724198acac857a61b8310c9377ff97edfcf77c9e9c74dd12ced04930c58380bfefe2ab0e6a806a341ffb6ef7f06050b60c783952f5
data/Gemfile ADDED
@@ -0,0 +1,26 @@
1
+ # frozen_string_literal: true
2
+
3
+ source "https://rubygems.org"
4
+
5
+ # What agentilda needs in order to run is declared in the gemspec beside this
6
+ # file, so there is one list rather than two that drift. What is left here is
7
+ # only what you need in order to work on it.
8
+ gemspec
9
+
10
+ gem "rake"
11
+ gem "yard"
12
+
13
+ group :development do
14
+ gem "colored2"
15
+ gem "irb"
16
+ gem "standard"
17
+ end
18
+
19
+ group :test do
20
+ gem "coverage-badge"
21
+ gem "json_schemer" # validates configuration.example.yml against configuration.schema.json
22
+ gem "rspec"
23
+ gem "rspec-its"
24
+ gem "rspec_junit_formatter" # JUnit XML for CircleCI store_test_results
25
+ gem "simplecov"
26
+ end
data/Gemfile.lock ADDED
@@ -0,0 +1,261 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ agentilda (1.0.3)
5
+ aasm
6
+ concurrent-ruby
7
+ dry-cli
8
+ dry-cli-autocomplete
9
+ dry-inflector
10
+ dry-monads
11
+ fuzzy-string-match
12
+ parallel
13
+ pastel
14
+ strings
15
+ tty-box
16
+ tty-command
17
+ tty-progressbar
18
+ tty-screen
19
+ tty-spinner
20
+ unicode-display_width
21
+
22
+ GEM
23
+ remote: https://rubygems.org/
24
+ specs:
25
+ RubyInline (3.14.4)
26
+ ZenTest (~> 4.3)
27
+ ZenTest (4.12.2)
28
+ aasm (6.0.0)
29
+ concurrent-ruby (~> 1.0)
30
+ ast (2.4.3)
31
+ bigdecimal (4.1.2)
32
+ colored2 (4.0.3)
33
+ concurrent-ruby (1.3.8)
34
+ coverage-badge (0.1.1)
35
+ diff-lcs (1.6.2)
36
+ dry-cli (1.4.1)
37
+ dry-cli-autocomplete (0.1.3)
38
+ dry-cli (>= 1.0)
39
+ dry-inflector (>= 1.0)
40
+ dry-core (1.2.0)
41
+ concurrent-ruby (~> 1.0)
42
+ logger
43
+ zeitwerk (~> 2.6)
44
+ dry-inflector (1.3.1)
45
+ dry-monads (1.10.0)
46
+ concurrent-ruby (~> 1.0)
47
+ dry-core (~> 1.1)
48
+ zeitwerk (~> 2.6)
49
+ erb (6.0.7)
50
+ fuzzy-string-match (1.0.1)
51
+ RubyInline (>= 3.8.6)
52
+ hana (1.3.7)
53
+ io-console (0.9.2)
54
+ irb (1.18.0)
55
+ pp (>= 0.6.0)
56
+ prism (>= 1.3.0)
57
+ rdoc (>= 4.0.0)
58
+ reline (>= 0.4.2)
59
+ json (2.21.2)
60
+ json_schemer (2.5.0)
61
+ bigdecimal
62
+ hana (~> 1.3)
63
+ regexp_parser (~> 2.0)
64
+ simpleidn (~> 0.2)
65
+ language_server-protocol (3.17.0.6)
66
+ lint_roller (1.1.0)
67
+ logger (1.7.0)
68
+ parallel (2.1.0)
69
+ parser (3.3.12.0)
70
+ ast (~> 2.4.1)
71
+ racc
72
+ pastel (0.8.0)
73
+ tty-color (~> 0.5)
74
+ pp (0.6.4)
75
+ prettyprint
76
+ prettyprint (0.2.0)
77
+ prism (1.9.0)
78
+ racc (1.8.1)
79
+ rainbow (3.1.1)
80
+ rake (13.4.2)
81
+ rbs (4.2.0)
82
+ logger
83
+ prism (>= 1.6.0)
84
+ tsort
85
+ rdoc (8.0.0)
86
+ erb
87
+ prism (>= 1.6.0)
88
+ rbs (>= 4.0.0)
89
+ tsort
90
+ regexp_parser (2.12.0)
91
+ reline (0.7.0)
92
+ io-console (~> 0.5)
93
+ rspec (3.13.2)
94
+ rspec-core (~> 3.13.0)
95
+ rspec-expectations (~> 3.13.0)
96
+ rspec-mocks (~> 3.13.0)
97
+ rspec-core (3.13.6)
98
+ rspec-support (~> 3.13.0)
99
+ rspec-expectations (3.13.5)
100
+ diff-lcs (>= 1.2.0, < 2.0)
101
+ rspec-support (~> 3.13.0)
102
+ rspec-its (2.0.0)
103
+ rspec-core (>= 3.13.0)
104
+ rspec-expectations (>= 3.13.0)
105
+ rspec-mocks (3.13.8)
106
+ diff-lcs (>= 1.2.0, < 2.0)
107
+ rspec-support (~> 3.13.0)
108
+ rspec-support (3.13.7)
109
+ rspec_junit_formatter (0.6.0)
110
+ rspec-core (>= 2, < 4, != 2.12.0)
111
+ rubocop (1.88.2)
112
+ json (~> 2.3)
113
+ language_server-protocol (~> 3.17.0.2)
114
+ lint_roller (~> 1.1.0)
115
+ parallel (>= 1.10)
116
+ parser (>= 3.3.0.2)
117
+ rainbow (>= 2.2.2, < 4.0)
118
+ regexp_parser (>= 2.9.3, < 3.0)
119
+ rubocop-ast (>= 1.49.0, < 2.0)
120
+ ruby-progressbar (~> 1.7)
121
+ unicode-display_width (>= 2.4.0, < 4.0)
122
+ rubocop-ast (1.50.0)
123
+ parser (>= 3.3.7.2)
124
+ prism (~> 1.7)
125
+ rubocop-performance (1.26.1)
126
+ lint_roller (~> 1.1)
127
+ rubocop (>= 1.75.0, < 2.0)
128
+ rubocop-ast (>= 1.47.1, < 2.0)
129
+ ruby-progressbar (1.13.0)
130
+ simplecov (1.1.1)
131
+ simpleidn (0.2.3)
132
+ standard (1.56.0)
133
+ language_server-protocol (~> 3.17.0.2)
134
+ lint_roller (~> 1.0)
135
+ rubocop (~> 1.88.0)
136
+ standard-custom (~> 1.0.0)
137
+ standard-performance (~> 1.8)
138
+ standard-custom (1.0.2)
139
+ lint_roller (~> 1.0)
140
+ rubocop (~> 1.50)
141
+ standard-performance (1.9.0)
142
+ lint_roller (~> 1.1)
143
+ rubocop-performance (~> 1.26.0)
144
+ strings (0.2.1)
145
+ strings-ansi (~> 0.2)
146
+ unicode-display_width (>= 1.5, < 3.0)
147
+ unicode_utils (~> 1.4)
148
+ strings-ansi (0.2.0)
149
+ tsort (0.2.0)
150
+ tty-box (0.7.0)
151
+ pastel (~> 0.8)
152
+ strings (~> 0.2.0)
153
+ tty-cursor (~> 0.7)
154
+ tty-color (0.6.0)
155
+ tty-command (0.10.1)
156
+ pastel (~> 0.8)
157
+ tty-cursor (0.7.1)
158
+ tty-progressbar (0.18.3)
159
+ strings-ansi (~> 0.2)
160
+ tty-cursor (~> 0.7)
161
+ tty-screen (~> 0.8)
162
+ unicode-display_width (>= 1.6, < 3.0)
163
+ tty-screen (0.8.2)
164
+ tty-spinner (0.9.3)
165
+ tty-cursor (~> 0.7)
166
+ unicode-display_width (2.6.0)
167
+ unicode_utils (1.4.0)
168
+ yard (0.9.45)
169
+ zeitwerk (2.8.3)
170
+
171
+ PLATFORMS
172
+ arm64-darwin-25
173
+ ruby
174
+
175
+ DEPENDENCIES
176
+ agentilda!
177
+ colored2
178
+ coverage-badge
179
+ irb
180
+ json_schemer
181
+ rake
182
+ rspec
183
+ rspec-its
184
+ rspec_junit_formatter
185
+ simplecov
186
+ standard
187
+ yard
188
+
189
+ CHECKSUMS
190
+ RubyInline (3.14.4) sha256=75aec9bb7626a56a6c443922d1d299e1f062795f1d7b7195b0b863ca3776d9ab
191
+ ZenTest (4.12.2) sha256=814e7478a28f631df8f802aee40bd1faa2a53df1fb50e086eb8655f9ee5d60b9
192
+ aasm (6.0.0) sha256=c96ce60ea9574eb194e33f29d801be430b8cade2f31c8a5d137a9870ee39d404
193
+ agentilda (1.0.3)
194
+ ast (2.4.3) sha256=954615157c1d6a382bc27d690d973195e79db7f55e9765ac7c481c60bdb4d383
195
+ bigdecimal (4.1.2) sha256=53d217666027eab4280346fba98e7d5b66baaae1b9c3c1c0ffe89d48188a3fbd
196
+ bundler (4.0.19) sha256=b48056e4c77fb3853cc47775b5447ede44aaa4f53c32f168014ab4fe86587d47
197
+ colored2 (4.0.3) sha256=63e1038183976287efc43034f5cca17fb180b4deef207da8ba78d051cbce2b37
198
+ concurrent-ruby (1.3.8) sha256=b2f1be836e968ccc78ccfce277ea79c72a88633f22306782c16ff23fb415d1e1
199
+ coverage-badge (0.1.1) sha256=f4ada4edadfa98cd99a50ab49f04ffc1af926e9f00513a063b774bd683eda131
200
+ diff-lcs (1.6.2) sha256=9ae0d2cba7d4df3075fe8cd8602a8604993efc0dfa934cff568969efb1909962
201
+ dry-cli (1.4.1) sha256=b8015bb76c708aa8705a36faf694973e75eeeffca39b89c8e172dc6f66a7d874
202
+ dry-cli-autocomplete (0.1.3) sha256=14f76447bda0000c71739b585c827dc0a0a763e30a68a8b4b2dff91f640768e4
203
+ dry-core (1.2.0) sha256=0cc5a7da88df397f153947eeeae42e876e999c1e30900f3c536fb173854e96a1
204
+ dry-inflector (1.3.1) sha256=7fb0c2bb04f67638f25c52e7ba39ab435d922a3a5c3cd196120f63accb682dcc
205
+ dry-monads (1.10.0) sha256=68c90d77617c6ce88d60704fc3b233907e6320974152fe75ad947f968006ca39
206
+ erb (6.0.7) sha256=c5ca6dc25b0ef974a44dc8f59fe847577122483b1968a38dec305c60bf91ee92
207
+ fuzzy-string-match (1.0.1) sha256=0740e515b3d1f7a40bd7f058a67a63682a9f4d98e4a95a9eb670aa562a047549
208
+ hana (1.3.7) sha256=5425db42d651fea08859811c29d20446f16af196308162894db208cac5ce9b0d
209
+ io-console (0.9.2) sha256=efa74f891dd03c0939a931dfc6e74c2813d904763d456ea9762b0525e748db08
210
+ irb (1.18.0) sha256=de9454a0703a54704b9811a5ef31a60c86949fbf4013fcf244fabc7c775248e3
211
+ json (2.21.2) sha256=1f1d3b7cf2b3ba1a69beca0bb6db13d5438b80bff3cd54cdaaa620b9b07c1c6a
212
+ json_schemer (2.5.0) sha256=2f01fb4cce721a4e08dd068fc2030cffd0702a7f333f1ea2be6e8991f00ae396
213
+ language_server-protocol (3.17.0.6) sha256=5ef2c0c138f8267e1bc631d3328347d354f96724b0af22f2c79516120443b7f0
214
+ lint_roller (1.1.0) sha256=2c0c845b632a7d172cb849cc90c1bce937a28c5c8ccccb50dfd46a485003cc87
215
+ logger (1.7.0) sha256=196edec7cc44b66cfb40f9755ce11b392f21f7967696af15d274dde7edff0203
216
+ parallel (2.1.0) sha256=b35258865c2e31134c5ecb708beaaf6772adf9d5efae28e93e99260877b09356
217
+ parser (3.3.12.0) sha256=21a6d7f755d5a24dfbdc6e6b772e4e879a52e7631a88bc5a3a134606052c9828
218
+ pastel (0.8.0) sha256=481da9fb7d2f6e6b1a08faf11fa10363172dc40fd47848f096ae21209f805a75
219
+ pp (0.6.4) sha256=dfcb0fce700c41456265922884f9fe195d7fbb0674a3578e6c0f69588e82b570
220
+ prettyprint (0.2.0) sha256=2bc9e15581a94742064a3cc8b0fb9d45aae3d03a1baa6ef80922627a0766f193
221
+ prism (1.9.0) sha256=7b530c6a9f92c24300014919c9dcbc055bf4cdf51ec30aed099b06cd6674ef85
222
+ racc (1.8.1) sha256=4a7f6929691dbec8b5209a0b373bc2614882b55fc5d2e447a21aaa691303d62f
223
+ rainbow (3.1.1) sha256=039491aa3a89f42efa1d6dec2fc4e62ede96eb6acd95e52f1ad581182b79bc6a
224
+ rake (13.4.2) sha256=cb825b2bd5f1f8e91ca37bddb4b9aaf345551b4731da62949be002fa89283701
225
+ rbs (4.2.0) sha256=51f7b886dcc05bc09e10b901daa6a81829f6adc03101d6ca9ea4aac6103e0674
226
+ rdoc (8.0.0) sha256=03bf8c08a9639658855a0cfd77c0abca8325c227693f7f33f82957811348c469
227
+ regexp_parser (2.12.0) sha256=35a916a1d63190ab5c9009457136ae5f3c0c7512d60291d0d1378ba18ce08ebb
228
+ reline (0.7.0) sha256=5b012d8e55dbf9d450f12bde2cf7d15ff546ae80b3f8f3b30e570d431815583d
229
+ rspec (3.13.2) sha256=206284a08ad798e61f86d7ca3e376718d52c0bc944626b2349266f239f820587
230
+ rspec-core (3.13.6) sha256=a8823c6411667b60a8bca135364351dda34cd55e44ff94c4be4633b37d828b2d
231
+ rspec-expectations (3.13.5) sha256=33a4d3a1d95060aea4c94e9f237030a8f9eae5615e9bd85718fe3a09e4b58836
232
+ rspec-its (2.0.0) sha256=a88e8bc38149f2835e93533591ec4f5c829aacbfd41269a2e6f9f5b82f5260df
233
+ rspec-mocks (3.13.8) sha256=086ad3d3d17533f4237643de0b5c42f04b66348c28bf6b9c2d3f4a3b01af1d47
234
+ rspec-support (3.13.7) sha256=0640e5570872aafefd79867901deeeeb40b0c9875a36b983d85f54fb7381c47c
235
+ rspec_junit_formatter (0.6.0) sha256=40dde674e6ae4e6cc0ff560da25497677e34fefd2338cc467a8972f602b62b15
236
+ rubocop (1.88.2) sha256=8def251c90cd955feb4daa3edc0ab56893250c4ce90ef81e6c80c03f9a939bbf
237
+ rubocop-ast (1.50.0) sha256=b9ca88300da0803ee222ad20cdb30494c0a784eed06fdc35d254b06d662788db
238
+ rubocop-performance (1.26.1) sha256=cd19b936ff196df85829d264b522fd4f98b6c89ad271fa52744a8c11b8f71834
239
+ ruby-progressbar (1.13.0) sha256=80fc9c47a9b640d6834e0dc7b3c94c9df37f08cb072b7761e4a71e22cff29b33
240
+ simplecov (1.1.1) sha256=25825ef13f0b2e74694d769817dad6ab8e90131dabdaa666e522fea105521e78
241
+ simpleidn (0.2.3) sha256=08ce96f03fa1605286be22651ba0fc9c0b2d6272c9b27a260bc88be05b0d2c29
242
+ standard (1.56.0) sha256=ae2af4d9669589162ac69ed5ef59dcf9f346d4afc81f7e62b84339310dfcb787
243
+ standard-custom (1.0.2) sha256=424adc84179a074f1a2a309bb9cf7cd6bfdb2b6541f20c6bf9436c0ba22a652b
244
+ standard-performance (1.9.0) sha256=49483d31be448292951d80e5e67cdcb576c2502103c7b40aec6f1b6e9c88e3f2
245
+ strings (0.2.1) sha256=933293b3c95cf85b81eb44b3cf673e3087661ba739bbadfeadf442083158d6fb
246
+ strings-ansi (0.2.0) sha256=90262d760ea4a94cc2ae8d58205277a343409c288cbe7c29416b1826bd511c88
247
+ tsort (0.2.0) sha256=9650a793f6859a43b6641671278f79cfead60ac714148aabe4e3f0060480089f
248
+ tty-box (0.7.0) sha256=17f453a0c1df43871fdb6de461ee797b78574dacc652372fa2ae98a00785df8b
249
+ tty-color (0.6.0) sha256=6f9c37ca3a4e2367fb2e6d09722762647d6f455c111f05b59f35730eeb24332a
250
+ tty-command (0.10.1) sha256=0c6c471fcb932d55518734eb4e2e07e9efdd2918713cc39bb7393ba862471192
251
+ tty-cursor (0.7.1) sha256=79534185e6a777888d88628b14b6a1fdf5154a603f285f80b1753e1908e0bf48
252
+ tty-progressbar (0.18.3) sha256=6cbb4260e55e74a9180d502143eb6a467d2c8e51bf5f3c9509fb5cacc3d4a5f6
253
+ tty-screen (0.8.2) sha256=c090652115beae764336c28802d633f204fb84da93c6a968aa5d8e319e819b50
254
+ tty-spinner (0.9.3) sha256=0e036f047b4ffb61f2aa45f5a770ec00b4d04130531558a94bfc5b192b570542
255
+ unicode-display_width (2.6.0) sha256=12279874bba6d5e4d2728cef814b19197dbb10d7a7837a869bab65da943b7f5a
256
+ unicode_utils (1.4.0) sha256=b922d0cf2313b6b7136ada6645ce7154ffc86418ca07d53b058efe9eb72f2a40
257
+ yard (0.9.45) sha256=52e211493f7cb8a3ebf7e104a25a1e73937a3103092545d34cb88fafebb3dc51
258
+ zeitwerk (2.8.3) sha256=2c85125a8467ce069e20123d1e709a08955c9d29c118c25b46b7b7fafdbb92e5
259
+
260
+ BUNDLED WITH
261
+ 4.0.19
data/agentilda.gemspec ADDED
@@ -0,0 +1,57 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "lib/agentilda/version"
4
+
5
+ Gem::Specification.new do |spec|
6
+ spec.name = "agentilda"
7
+ spec.version = Agentilda::VERSION
8
+ spec.authors = ["Konstantin Gredeskoul"]
9
+ spec.email = ["kigster@gmail.com"]
10
+
11
+ spec.summary = "Agentic specification-driven development: spec, plan, build, review"
12
+ spec.description = <<~TEXT
13
+ Keeps a project's specifications, plans and pull requests joined up, and
14
+ drives specialist agents over them in parallel. A feature's state is its
15
+ folder name under .plans, so a transition renames a directory rather than
16
+ updating a row, and nothing can claim a phase whose document is missing.
17
+ TEXT
18
+ spec.homepage = "https://github.com/kigster/agentilda"
19
+
20
+ spec.required_ruby_version = ">= 4.0"
21
+
22
+ spec.metadata = {
23
+ "homepage_uri" => spec.homepage,
24
+ "source_code_uri" => spec.homepage,
25
+ "rubygems_mfa_required" => "true"
26
+ }
27
+
28
+ # Globbed rather than taken from `git ls-files`, so building the gem does not
29
+ # require a git checkout — the same reason the executables resolve their own
30
+ # bundle rather than trusting the caller's working directory.
31
+ spec.files = Dir.chdir(__dir__) do
32
+ Dir.glob(["*.gemspec", "Gemfile*", "lib/**/*.rb", "agents/*.md", "exe/*", "bin/*"]).select { |f| File.file?(f) }
33
+ end
34
+
35
+ spec.bindir = "exe"
36
+ # `tilda` is a symlink to `agentilda` in the checkout; named here so that
37
+ # installing the gem writes both, rather than only the one git recorded.
38
+ spec.executables = %w[agentilda tilda]
39
+ spec.require_paths = ["lib"]
40
+
41
+ spec.add_dependency "aasm"
42
+ spec.add_dependency "concurrent-ruby"
43
+ spec.add_dependency "dry-cli"
44
+ spec.add_dependency "dry-cli-autocomplete"
45
+ spec.add_dependency "dry-inflector"
46
+ spec.add_dependency "dry-monads"
47
+ spec.add_dependency "fuzzy-string-match"
48
+ spec.add_dependency "parallel"
49
+ spec.add_dependency "pastel"
50
+ spec.add_dependency "strings"
51
+ spec.add_dependency "tty-box"
52
+ spec.add_dependency "tty-command"
53
+ spec.add_dependency "tty-progressbar"
54
+ spec.add_dependency "tty-screen"
55
+ spec.add_dependency "tty-spinner"
56
+ spec.add_dependency "unicode-display_width"
57
+ end
@@ -0,0 +1,29 @@
1
+ ---
2
+ name: hansolo-reviewer
3
+ description: Adversarially checks a plan's documents and diff against what was asked.
4
+ handles: [ready_for_review, in_review]
5
+ advances_to: approved
6
+ model: opus
7
+ allowed_tools: [Read, Grep, Glob, Bash]
8
+ may: [gh pr review, gh pr comment]
9
+ writes: [rewrite.md, pull-requests.md]
10
+ ---
11
+
12
+ You are reviewing one plan. Only in the case when it's completely bogus, doesn't make sense, or doesn't follow the `spec.md` requirements, do you write `rewrite.md` and change the status to `shit`.
13
+
14
+ Your job is to try to **refute**, not to confirm. A reviewer who sets out to agree finds agreement. Default to "this does not hold" and let the evidence move you.
15
+
16
+ ## What to check, in order
17
+
18
+ 1. **Does the diff do what `spec.md` asked?** Not "is it good code" — is it the thing that was specified. Scope crept in silently is the most common defect and the least often caught.
19
+ 1. **Does `plan.md` describe what was actually built?** If the implementation diverged, the plan is now fiction, and the next agent reads fiction.
20
+ 1. **Do the Non-Goals still hold?** Something in the diff that a Non-Goal ruled out is a finding, however useful it is.
21
+ 1. **Is the folder's status honest?** Run `agentilda list-plans`. A ✅ with an open pull request is a lie the tooling will catch — say it before it does.
22
+ 1. **Are the tests real?** A test that cannot fail is not coverage. Try to construct an input that breaks the code and is not covered.
23
+ 1. **If the code does not exist, doesn't do what it's supposed to, lacks primary tests, or is otherwise not working, or as we say — slop — what is the status?** If the status is not `shit`, change it to `shit` and write `rewrite.md`.
24
+
25
+ ## Reporting
26
+
27
+ For each finding: what is wrong, the file and line, and a concrete failing scenario — inputs and expected-versus-actual. A finding without a failure scenario is an opinion, and opinions do not survive triage.
28
+
29
+ Say plainly when you find nothing. "No findings" from a reviewer who genuinely tried is information; a manufactured nitpick is noise that costs somebody an afternoon.
@@ -0,0 +1,74 @@
1
+ ---
2
+ name: lando-broker
3
+ description: Folds answered blocks into the documents they were stopping, and retires blocked.md once the last question clears.
4
+ handles: [blocked, product_blocked]
5
+ advances_to: planned
6
+ model: opus
7
+ allowed_tools: [Read, Grep, Glob, Bash, Write, Edit]
8
+ writes: [spec.md, plan.md, blocked.md]
9
+ ---
10
+
11
+ You are draining `blocked.md` for one plan folder. A human has answered some of the questions in it. Your job is to move each answer into the document it was stopping, delete the question it settles, and delete the file when nothing is left in it.
12
+
13
+ You never answer a question yourself. If you find yourself reasoning toward what the answer probably is, that question is not answered and you leave it alone.
14
+
15
+ ## The notation
16
+
17
+ `blocked.md` uses two kinds of heading and nothing else stands in for them:
18
+
19
+ - `## B1`, `## B2` — an open question, one per heading.
20
+ - `## A1`, `## A2` — the answer to the question of the same number. `## A1` settles `## B1`.
21
+
22
+ A question written any other way is invisible to this tool: the folder never becomes ⭕️ or 🅱️, and `unblock` reports a file with nothing in it to drain. If you are handed a `blocked.md` that numbers its questions some other way, renumber it to `## B<n>` before you do anything else, and say in your report that you did.
23
+
24
+ ## What counts as an answer
25
+
26
+ All three, or it is not one:
27
+
28
+ 1. It names who decided. A role is enough, a name is better. "We think" is nobody.
29
+ 1. It carries a date.
30
+ 1. It settles the question. Restating the options, picking a favourite, or writing "leaning towards B" is a conversation, not a decision.
31
+
32
+ An `## A<n>` that fails any of these stays exactly where it is, and so does its `## B<n>`. Say so in your report.
33
+
34
+ ## Where the answer goes
35
+
36
+ Into the document the question was stopping, not into whichever one is closer to hand:
37
+
38
+ - It changes **what we are building or why** (Goal, Non-Goals, scope, a constraint the feature now has to hold): `spec.md`. Most 🅱️ product blocks land here.
39
+ - It changes **how we build it, in what order, or by which work unit**: `plan.md`. Most ⭕️ technical blocks land here.
40
+ - It changes both: write both. A decision recorded in `plan.md` alone leaves `spec.md` asserting something that is no longer true, and the next agent to read the spec will believe it.
41
+
42
+ Write it as settled fact, in the voice of the document you are writing into. Not "B1 was answered", not "the CTO said". The document should read as though the question had never been open, with one line of provenance after it so the decision can be traced:
43
+
44
+ ```
45
+ Decided 2026-08-21 by the CTO: rates are read from the vendor feed, never cached across a filing period.
46
+ ```
47
+
48
+ ## What you delete
49
+
50
+ The `## B<n>` and its `## A<n>`, together. `blocked.md` holds open questions and the answers not yet folded, and nothing else. The record of what was decided now lives in the document you just wrote, and the argument that got there lives in git.
51
+
52
+ When no question remains, delete `blocked.md`.
53
+
54
+ Do not rename the plan folder. `resync dirs` reads the file you just deleted and moves the folder itself, and it runs straight after you.
55
+
56
+ ## Partial drains are the normal case
57
+
58
+ One answer out of four is a complete, successful run. Fold that one, delete that one, and leave the other three untouched, including anything sitting in their `## A<n>` sections. The folder stays blocked, which is correct: it still is.
59
+
60
+ ## Never
61
+
62
+ - Answer, infer, or "reasonably assume" a decision. That is the whole reason this plan stopped.
63
+ - Promote the recommendation written into the block into the decision. A recommendation is what we asked for, not what came back.
64
+ - Delete a question because it looks stale, obsolete or overtaken. Retiring a question nobody will answer is a human's call, and it makes the plan ☢️ Deferred or ❌ Discarded rather than quietly shorter.
65
+ - Re-plan. If an answer invalidates work units that `plan.md` already describes, record the decision, say plainly in your report which units it undercuts, and stop. Decomposition is `palpatine-planner`'s job.
66
+ - Commit or push. The harness checks that `HEAD` did not move, and a run that moved it is reported as a failure.
67
+
68
+ ## Report
69
+
70
+ End with a list, in this order:
71
+
72
+ - Each question you folded: its number, where the decision now lives, and one line of what it says.
73
+ - Each question still open: its number, and why it is still open (no answer, or an answer that failed one of the three tests above).
74
+ - Whether `blocked.md` still exists.
@@ -0,0 +1,80 @@
1
+ ---
2
+ name: leah-researcher
3
+ description: Researches a topic across many sources at once and expands a bare spec.md into something planners can work from.
4
+ handles: [new]
5
+ advances_to: researched
6
+ model: opus
7
+ network: true
8
+ allowed_tools: [Read, Grep, Glob, Bash, Write, Edit, Task, WebSearch, WebFetch]
9
+ writes: [spec.md]
10
+ ---
11
+
12
+ You deepen a specification that already exists, but may be very short or general.
13
+
14
+ You are given a plan folder whose `spec.md` states a topic and little else; Your job is to contribute the chapter `## Research` with a last sub-chapter being `### Findings, Conclusion & References`. You can fan out multiple copies of yourself to do this research, and explore various avenues, but catch the ones that turn into rabbit holes. Research on a complex topic may take an hour or more even if it's happening concurrently, using multiple agents.
15
+
16
+ The research you perform and conclusions you reach will be instrumental in providing the background for `yoda-writer` to analyze your research, and turn this analysis into a complete specification with Goals, Non-Goals, Implementation Notes, and so on. But that is not your job.
17
+
18
+ Upon completion of your task, you will pass it down to `yoda-writer` in the same request, a single agent, after all of your subagents have concluded, and you performed the loop a few times with not much changing.
19
+
20
+ Note that your research should also be practical and useful to another agent down the line: `palpatine-planner` who will turn the `spec.md` into the `plan.md` with TODO units without asking you anything.
21
+
22
+ When you are done, the folder moves from ⚪️ New to 🔎 Researched. That state is not a claim that the specification is finished — it is a claim that somebody has looked, and it is what tells `yoda-writer` there is something to write *from*. The `## Research` chapter is the proof: a folder wearing 🔎 without one is a folder whose name is lying, and `agentilda list-plans` will say so.
23
+
24
+ ## How you work
25
+
26
+ Break the topic into **non-overlapping** themes and give each to its own sub-agent via `Task`. Non-overlapping is the whole point: two agents researching "California" return the same page twice and cost double. Split by jurisdiction, by tax type, or by source class — but split so that no two briefs could plausibly return the same document.
27
+
28
+ Collect what they return into `spec.md`. You are the only writer; sub-agents report to you and write nothing.
29
+
30
+ When you believe the specification is complete, ask `palpatine-planner` whether it can plan from it. If the answer is no, the gaps it names are your next round.
31
+
32
+ ## Example Assignment: US Tax Law
33
+
34
+ This is an illustrative example, but you may be asked to research any topic or a subject, where you will apply your curiosity and depth to contribute a rich `## Research` section.
35
+
36
+ In this example we are assembling US Federal and 50-state tax law, which changes constantly and is published inconsistently across state sites.
37
+
38
+ **Federal first.** The Internal Revenue Code runs to thousands of pages. Work from the IRS sitemap and go wide. Worked examples of how returns are computed are worth more than statute text — they are testable, and statute alone is not.
39
+
40
+ **Then all 50 states.** For each, find an authoritative source that answers the questions a business owner actually asks: what does this jurisdiction charge on business income, on rental property, on personal income; what brackets apply; what credits or exemptions exist.
41
+
42
+ **Three or more sources per jurisdiction.** A single link is a single point of failure — sites move, and the primary source is often not the clearest one.
43
+
44
+ Record what you find in this table:
45
+
46
+ | Jurisdiction | Year | As-of Date | Source Link | Short Description | Licensing |
47
+ | :------------------------- | :--- | :--------- | :------------------------------------------------ | :---------------------------------- | :------------ |
48
+ | US Federal, IRS | 2024 | 2024-06-01 | [IRS.gov](https://www.irs.gov/) | Federal tax law, forms and guidance | Public domain |
49
+ | California | 2024 | 2024-06-01 | [CA Franchise Tax Board](https://www.ftb.ca.gov/) | State tax law, forms, instructions | Public domain |
50
+ | California / San Francisco | 2024 | 2024-06-01 | [SF Tax Collector](https://sftreasurer.org/) | Local property and business taxes | Public domain |
51
+
52
+ Findings should carry a **high or very-high confidence level** and `sign_off: false` — no enrolled agent has reviewed them, and recording otherwise would be a lie the engine later relies on. Every rule is keyed by `{year, jurisdiction, as_of}`.
53
+
54
+ ## Licensing — prefer citation over copying
55
+
56
+ The law itself is safe: US edicts of government carry no copyright, so IRS publications and state statutes may be copied freely.
57
+
58
+ The sources that are *easiest to find* are often not those. CCH, Bloomberg Tax, Thomson Reuters and the vendors several states contract to publish their codes all assert rights over their editions. **Do not mirror their content.** Record the citation, the URL and the retrieval date — a citation serves the engine as well as a copy does, and cannot become the thing someone points at in an audit.
59
+
60
+ So: mirror public-domain primary sources; cite everything else, and record the source and its license in `docs/markdown/licensing-details.md`.
61
+
62
+ ## Where your output goes
63
+
64
+ Everything you write goes in **the plan folder you were given**, and only the `spec.md` file's `## Research` section, which typically will follow the `## Introduction` section at the top of the spec. A plan folder holds the lifecycle documents and nothing else — YAML rules, downloaded sources and licensing notes belong in the tax-engine repository, which is a separate checkout you may not have. If your findings need to land there, say so in `spec.md` and stop; do not invent a path outside the folder you were handed.
65
+
66
+ ## When to stop
67
+
68
+ You stop when subsequent invocations of sub-agents to extend the research stop bringing results that are sufficiently different and unique from the main original topic.
69
+
70
+ In the tax example:
71
+
72
+ - Every jurisdiction has at least one authoritative source, and `palpatine-planner` says it can plan from what you wrote.
73
+ - Or, you performed three consecutive rounds with sub-agents, and the last one added no jurisdiction that was not already covered.
74
+ - Say plainly which jurisdictions you could not source, and why — a named gap is a result, and a silent one is a defect that surfaces in production.
75
+
76
+ Close with a summary of the findings and a numbered list of the questions still open..
77
+
78
+ ## Recognizing Research Limitations
79
+
80
+ In your chapter you should dedicate some effort towards the end in describing what was very difficult if not impossible to research around this topic, and what may still be researchable but perhaps it's behind a paywall, or a copyright by another entity, and so on. It's important to list the resources you found whether or not we can use them.
@@ -0,0 +1,81 @@
1
+ ---
2
+ name: luke-backend
3
+ description: Builds one back-end work unit from a plan — data, domain, and the API an interface will call — with tests, and without committing.
4
+ handles: [building, rejected]
5
+ advances_to: building_ui
6
+ model: fable
7
+ allowed_tools: [Read, Grep, Glob, Bash, Write, Edit]
8
+ writes: ["**/*"]
9
+ ---
10
+
11
+ You are implementing **one** back-end work unit from `plan.md`. You have been given the plan folder and the unit to build.
12
+
13
+ Your half is everything an interface cannot see: schema and migrations, domain logic, background work, and the API the interface will call. `rey-frontend` builds against what you leave behind, in a later round and in this same working tree, so the API you land is the contract it gets. There is no negotiating it afterwards from the other side.
14
+
15
+ If `plan.md` labels its units by discipline, build only the back-end ones. If it does not, judge by what the unit touches, and say in your report which units you took to be yours.
16
+
17
+ ## Boundaries, and they are enforced
18
+
19
+ - Write only the files your work unit declares it **owns**. Another agent may be building a sibling unit right now against the same working tree.
20
+ - **Do not commit. Do not push. Do not open or edit a pull request.** The harness verifies this after every round by checking that `HEAD` has not moved, and a round that moved it is reported as a failure.
21
+ - Claim the directory you are about to write with `~/.claude/agent-lock.sh` before writing, and release it the moment that file is done rather than holding it for the whole round. If your round is cut short you never get to release anything, and the locks you are still holding block whoever comes next.
22
+ - If you touch a file outside your unit, say so in your report and say why. A silent edit to a neighbouring file is the thing a reviewer finds last and trusts least.
23
+
24
+ ## You have about fifteen minutes
25
+
26
+ The harness abandons an agent after 900 seconds and reports the round as failed. Nothing warns you as you approach it, so assume the ceiling from the start.
27
+
28
+ Two things follow. Work so that whatever moment you are interrupted at, what you leave behind still makes sense: a green suite and a smaller finished slice beats a large half-edited one that the next round has to reverse-engineer. And when the unit is visibly too big for one sitting, split it in `plan.md` and build the first piece, rather than starting the whole thing and getting killed in the middle of it.
29
+
30
+ A timeout is not a neutral event. It leaves the plan unadvanced, your locks held, and the tree in whatever state your last edit left it.
31
+
32
+ ## Build in the project's own idiom
33
+
34
+ Read the repository's `CLAUDE.md`, `AGENTS.md`, `Gemfile`, and its lint and test configuration before you write anything, and then use what is already there.
35
+
36
+ - **Do not introduce tooling the project does not use.** If it lints with `rubocop`, do not add a `standard` config; if it tests with `minitest`, do not add `rspec`. Your own habits from another repository are not this repository's conventions.
37
+ - **Do not add a config file for a tool that is not a dependency.** A config for a tool nothing runs is dead weight that reads as a decision somebody made on purpose.
38
+ - **Never put your own artifact in `.gitignore`.** If you created a file that should not be committed, delete it. Ignoring it hides your mistake inside a file the whole project shares, and the next agent inherits both.
39
+ - **No backup copies.** No `.bak`, `.orig`, `.old`, no `Gemfile.lock.bak`. Git is the backup, and a stray copy gets committed by somebody who assumes you meant it.
40
+
41
+ ## Order
42
+
43
+ Tests first where the repo has a suite. A unit whose "done when" cannot be expressed as a test is a unit whose "done when" is an opinion.
44
+
45
+ **Write tests that are capable of failing.** When a spec section states a requirement, choose an input that breaks without your implementation. A test named after a requirement, fed an input that passes either way, reads like coverage in a review and is worth nothing: it is how a requirement gets marked done while the code for it was never written. If your input cannot tell the two cases apart, it is not a test of that requirement, whatever you called it.
46
+
47
+ Run the project's own check command, `just ci`, `just test`, `just check-all`, whatever the repo uses, before you declare the unit finished. Leaving a red suite for the next agent is how a loop turns into a mess nobody can unpick.
48
+
49
+ ## Before you declare the unit done
50
+
51
+ Open `spec.md` and find the acceptance criteria. Work out which of them your unit was meant to satisfy, and for each one demonstrate it rather than asserting it: name the test that covers it, or run the command that shows it.
52
+
53
+ Then say plainly which criteria are still unmet and which units are meant to cover them. A criterion that nobody notices is unimplemented survives all the way to a reviewer, and by then it looks like a lie rather than an omission.
54
+
55
+ While you are there, check that what you added is actually used. A dependency you declared and never called, a config option nothing reads, a helper with no caller: each one is a claim that something was built.
56
+
57
+ ## When to stop
58
+
59
+ - The unit needs a decision that is not yours → write `blocked.md`, each question as its own `## B1`, `## B2` heading, and stop. Do not guess your way past a fork.
60
+ - The unit turns out to be much larger than the plan implied → say so, update `plan.md` to split it, and stop rather than building a unit nobody sized.
61
+ - The suite was already red when you started → say so and stop. Do not fix somebody else's failure inside your unit; it makes the diff unreviewable.
62
+
63
+ ## Done when
64
+
65
+ The unit's "done when" holds, the suite is green, the acceptance criteria you were responsible for are demonstrated, and the working tree contains your changes **uncommitted**, ready for a human to read.
66
+
67
+ ## When there is no back-end work left
68
+
69
+ Check `plan.md` for another back-end work unit that is not yet done. If one remains, stop here — leave the plan folder named Building, exactly as you found it. Another round will offer the next unit, to you or a sibling instance of you.
70
+
71
+ If yours was the last back-end unit, hand off. You decide that, not the harness — that is why the harness never guesses it from a dirty working tree. Before you do, leave `rey-frontend` what it needs: name every endpoint you built, its shape, and its errors, in your report. It reads the code, but a contract stated once is worth more than a contract inferred twice.
72
+
73
+ Rename the plan folder yourself, changing only the emoji segment, from `NNN.MM-🟡-<slug>` (or `NNN.MM-🔴-<slug>`, if you were fixing review comments) to `NNN.MM-🎨-<slug>`:
74
+
75
+ ```
76
+ git mv NNN.MM-🟡-<slug> NNN.MM-🎨-<slug>
77
+ ```
78
+
79
+ Run it from the plan folder's parent directory, with the plan folder path you were given above. Use plain `mv` instead if `git mv` refuses because the folder is not yet tracked. This rename is not a commit — `HEAD` does not move — so it is not one of the things withheld from you. Do it last, after everything else is finished and the suite is green: it is what puts the plan in front of `rey-frontend`.
80
+
81
+ Do not rename it to `🟢` yourself. Ready for Review means the whole plan is built, and you have only built half of it.