anima-core 1.1.3 → 1.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 +4 -4
- data/.reek.yml +10 -1
- data/README.md +36 -11
- data/agents/codebase-analyzer.md +2 -2
- data/agents/codebase-pattern-finder.md +2 -2
- data/agents/documentation-researcher.md +2 -2
- data/agents/thoughts-analyzer.md +2 -2
- data/agents/web-search-researcher.md +3 -3
- data/app/channels/session_channel.rb +83 -64
- data/app/decorators/agent_message_decorator.rb +2 -2
- data/app/decorators/{event_decorator.rb → message_decorator.rb} +40 -40
- data/app/decorators/system_message_decorator.rb +2 -2
- data/app/decorators/tool_call_decorator.rb +6 -6
- data/app/decorators/tool_decorator.rb +4 -4
- data/app/decorators/tool_response_decorator.rb +2 -2
- data/app/decorators/user_message_decorator.rb +5 -19
- data/app/decorators/web_get_tool_decorator.rb +41 -9
- data/app/jobs/agent_request_job.rb +33 -24
- data/app/jobs/count_message_tokens_job.rb +39 -0
- data/app/jobs/passive_recall_job.rb +4 -4
- data/app/models/concerns/{event → message}/broadcasting.rb +16 -16
- data/app/models/goal.rb +17 -4
- data/app/models/goal_pinned_message.rb +11 -0
- data/app/models/message.rb +127 -0
- data/app/models/pending_message.rb +43 -0
- data/app/models/pinned_message.rb +41 -0
- data/app/models/secret.rb +72 -0
- data/app/models/session.rb +385 -226
- data/app/models/snapshot.rb +25 -25
- data/config/environments/test.rb +5 -0
- data/config/initializers/time_nanoseconds.rb +11 -0
- data/db/migrate/20260326180000_rename_event_to_message.rb +172 -0
- data/db/migrate/20260328100000_create_secrets.rb +15 -0
- data/db/migrate/20260328152142_add_evicted_at_to_goals.rb +6 -0
- data/db/migrate/20260329120000_create_pending_messages.rb +11 -0
- data/lib/agent_loop.rb +14 -41
- data/lib/agents/definition.rb +1 -1
- data/lib/analytical_brain/runner.rb +40 -37
- data/lib/analytical_brain/tools/activate_skill.rb +5 -9
- data/lib/analytical_brain/tools/assign_nickname.rb +2 -4
- data/lib/analytical_brain/tools/deactivate_skill.rb +5 -9
- data/lib/analytical_brain/tools/everything_is_ready.rb +1 -2
- data/lib/analytical_brain/tools/finish_goal.rb +5 -8
- data/lib/analytical_brain/tools/read_workflow.rb +5 -9
- data/lib/analytical_brain/tools/rename_session.rb +3 -10
- data/lib/analytical_brain/tools/set_goal.rb +3 -7
- data/lib/analytical_brain/tools/update_goal.rb +3 -7
- data/lib/anima/cli/mcp/secrets.rb +4 -4
- data/lib/anima/cli/mcp.rb +4 -4
- data/lib/anima/installer.rb +7 -1
- data/lib/anima/settings.rb +46 -6
- data/lib/anima/version.rb +1 -1
- data/lib/anima.rb +1 -1
- data/lib/credential_store.rb +17 -66
- data/lib/events/base.rb +1 -1
- data/lib/events/bounce_back.rb +7 -7
- data/lib/events/subscribers/persister.rb +15 -22
- data/lib/events/subscribers/subagent_message_router.rb +20 -8
- data/lib/events/subscribers/transient_broadcaster.rb +2 -2
- data/lib/events/user_message.rb +2 -13
- data/lib/llm/client.rb +54 -20
- data/lib/mcp/config.rb +2 -2
- data/lib/mcp/secrets.rb +7 -8
- data/lib/mneme/compressed_viewport.rb +57 -57
- data/lib/mneme/l2_runner.rb +4 -4
- data/lib/mneme/passive_recall.rb +2 -2
- data/lib/mneme/runner.rb +57 -75
- data/lib/mneme/search.rb +38 -38
- data/lib/mneme/tools/attach_messages_to_goals.rb +103 -0
- data/lib/mneme/tools/everything_ok.rb +1 -3
- data/lib/mneme/tools/save_snapshot.rb +12 -16
- data/lib/shell_session.rb +54 -16
- data/lib/tools/base.rb +23 -0
- data/lib/tools/bash.rb +60 -16
- data/lib/tools/edit.rb +6 -8
- data/lib/tools/mark_goal_completed.rb +86 -0
- data/lib/tools/{request_feature.rb → open_issue.rb} +10 -13
- data/lib/tools/read.rb +6 -5
- data/lib/tools/recall.rb +98 -0
- data/lib/tools/registry.rb +37 -8
- data/lib/tools/remember.rb +46 -55
- data/lib/tools/response_truncator.rb +70 -0
- data/lib/tools/spawn_specialist.rb +15 -25
- data/lib/tools/spawn_subagent.rb +14 -22
- data/lib/tools/subagent_prompts.rb +42 -6
- data/lib/tools/think.rb +26 -10
- data/lib/tools/web_get.rb +23 -4
- data/lib/tools/write.rb +4 -4
- data/lib/tui/app.rb +178 -13
- data/lib/tui/braille_spinner.rb +152 -0
- data/lib/tui/cable_client.rb +4 -4
- data/lib/tui/decorators/base_decorator.rb +17 -8
- data/lib/tui/decorators/bash_decorator.rb +2 -2
- data/lib/tui/decorators/edit_decorator.rb +5 -4
- data/lib/tui/decorators/read_decorator.rb +4 -8
- data/lib/tui/decorators/think_decorator.rb +3 -5
- data/lib/tui/decorators/web_get_decorator.rb +4 -3
- data/lib/tui/decorators/write_decorator.rb +5 -4
- data/lib/tui/flash.rb +1 -1
- data/lib/tui/formatting.rb +22 -0
- data/lib/tui/message_store.rb +103 -59
- data/lib/tui/screens/chat.rb +293 -78
- data/skills/activerecord/SKILL.md +1 -1
- data/skills/dragonruby/SKILL.md +1 -1
- data/skills/draper-decorators/SKILL.md +1 -1
- data/skills/gh-issue.md +1 -1
- data/skills/mcp-server/SKILL.md +1 -1
- data/skills/ratatui-ruby/SKILL.md +1 -1
- data/skills/rspec/SKILL.md +1 -1
- data/templates/config.toml +42 -5
- data/templates/soul.md +7 -19
- data/workflows/create_handoff.md +1 -1
- data/workflows/create_note.md +1 -1
- data/workflows/create_plan.md +1 -1
- data/workflows/implement_plan.md +1 -1
- data/workflows/iterate_plan.md +1 -1
- data/workflows/research_codebase.md +1 -1
- data/workflows/resume_handoff.md +1 -1
- data/workflows/review_pr.md +78 -16
- data/workflows/thoughts_init.md +1 -1
- data/workflows/validate_plan.md +1 -1
- metadata +20 -9
- data/app/jobs/count_event_tokens_job.rb +0 -39
- data/app/models/event.rb +0 -129
- data/app/models/goal_pinned_event.rb +0 -11
- data/app/models/pinned_event.rb +0 -41
- data/lib/mneme/tools/attach_events_to_goals.rb +0 -107
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: activerecord
|
|
3
|
-
description: "
|
|
3
|
+
description: "Associations, validations, queries, migrations, eager loading, N+1 queries, scopes, callbacks, app/models/, db/migrate/."
|
|
4
4
|
---
|
|
5
5
|
|
|
6
6
|
# ActiveRecord
|
data/skills/dragonruby/SKILL.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: dragonruby
|
|
3
|
-
description: "
|
|
3
|
+
description: "2D game development — game loops, sprites, input, collisions, scenes, DRGTK, args.outputs/state/inputs."
|
|
4
4
|
---
|
|
5
5
|
|
|
6
6
|
# DragonRuby Game Toolkit
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: draper-decorators
|
|
3
|
-
description: "
|
|
3
|
+
description: "Decorator patterns for Rails views — presentation logic separated from models, *_decorator.rb, app/decorators/."
|
|
4
4
|
---
|
|
5
5
|
|
|
6
6
|
# Draper Decorators for Rails
|
data/skills/gh-issue.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: gh-issue
|
|
3
|
-
description: "
|
|
3
|
+
description: "Issue writing with WHAT/WHY/HOW framework — tickets, bug reports, feature requests, issue descriptions, unclear rationale in existing issues."
|
|
4
4
|
---
|
|
5
5
|
|
|
6
6
|
# GitHub Issue Writing
|
data/skills/mcp-server/SKILL.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: mcp-server
|
|
3
|
-
description: "MCP server development
|
|
3
|
+
description: "Ruby MCP server development — tools, prompts, resources, transport, the mcp gem, LLM tool integrations."
|
|
4
4
|
---
|
|
5
5
|
|
|
6
6
|
# MCP Ruby SDK - Server Development Guide
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: ratatui-ruby
|
|
3
|
-
description: "
|
|
3
|
+
description: "Terminal UI development — widgets, layouts, events, Tea MVU, terminal rendering."
|
|
4
4
|
---
|
|
5
5
|
|
|
6
6
|
# RatatuiRuby
|
data/skills/rspec/SKILL.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: rspec
|
|
3
|
-
description: "
|
|
3
|
+
description: "Testing with FactoryBot — matchers, test doubles, shared examples, describe/it/expect blocks, *_spec.rb files, test strategy."
|
|
4
4
|
---
|
|
5
5
|
|
|
6
6
|
# RSpec Testing
|
data/templates/config.toml
CHANGED
|
@@ -3,6 +3,14 @@
|
|
|
3
3
|
# Edit settings below to customize Anima's behavior.
|
|
4
4
|
# Changes take effect immediately — no restart needed.
|
|
5
5
|
|
|
6
|
+
# ─── Agent Identity ──────────────────────────────────────────────
|
|
7
|
+
|
|
8
|
+
[agent]
|
|
9
|
+
|
|
10
|
+
# The agent's display name. Shown in the TUI, chat client, and soul template.
|
|
11
|
+
# Change this to personalize the agent — when Bonk migrates, the chat says "Bonk".
|
|
12
|
+
name = "Anima"
|
|
13
|
+
|
|
6
14
|
# ─── LLM ───────────────────────────────────────────────────────
|
|
7
15
|
|
|
8
16
|
[llm]
|
|
@@ -23,6 +31,10 @@ max_tool_rounds = 500
|
|
|
23
31
|
# Set this based on your model's context window minus system prompt.
|
|
24
32
|
token_budget = 190_000
|
|
25
33
|
|
|
34
|
+
# Maximum character length for the Think tool's thoughts parameter.
|
|
35
|
+
# Sub-agents receive half this budget (their tasks are less complex).
|
|
36
|
+
thinking_budget = 10_000
|
|
37
|
+
|
|
26
38
|
# ─── Timeouts (seconds) ─────────────────────────────────────────
|
|
27
39
|
|
|
28
40
|
[timeouts]
|
|
@@ -43,6 +55,10 @@ web_request = 10
|
|
|
43
55
|
# Also used as the default deadline for orphan detection in heal_orphaned_tool_calls!.
|
|
44
56
|
tool = 180
|
|
45
57
|
|
|
58
|
+
# How often (seconds) to poll for user interrupt during long-running commands.
|
|
59
|
+
# Lower = faster Escape response, higher = less DB overhead.
|
|
60
|
+
interrupt_check = 2
|
|
61
|
+
|
|
46
62
|
# ─── Shell ──────────────────────────────────────────────────────
|
|
47
63
|
|
|
48
64
|
[shell]
|
|
@@ -66,6 +82,19 @@ max_read_bytes = 50_000
|
|
|
66
82
|
# Maximum bytes from web GET responses.
|
|
67
83
|
max_web_response_bytes = 100_000
|
|
68
84
|
|
|
85
|
+
# Minimum characters of extracted content before flagging as possibly incomplete.
|
|
86
|
+
min_web_content_chars = 100
|
|
87
|
+
|
|
88
|
+
# Maximum characters of tool output before truncation (head + tail + temp file).
|
|
89
|
+
# ~6000 chars ≈ ~2000 tokens. Most useful info fits in 10+10 lines; agent can
|
|
90
|
+
# read the saved temp file for more.
|
|
91
|
+
max_tool_response_chars = 6_000
|
|
92
|
+
|
|
93
|
+
# Maximum characters of sub-agent result before truncation.
|
|
94
|
+
# Sub-agent output is already curated — needs a generous but bounded limit.
|
|
95
|
+
# ~24000 chars ≈ ~8000 tokens.
|
|
96
|
+
max_subagent_response_chars = 24_000
|
|
97
|
+
|
|
69
98
|
# ─── Environment ──────────────────────────────────────────────
|
|
70
99
|
|
|
71
100
|
[environment]
|
|
@@ -104,6 +133,14 @@ default_view_mode = "basic"
|
|
|
104
133
|
# Regenerate session name every N messages.
|
|
105
134
|
name_generation_interval = 30
|
|
106
135
|
|
|
136
|
+
# ─── Goals ──────────────────────────────────────────────────────
|
|
137
|
+
|
|
138
|
+
[goals]
|
|
139
|
+
|
|
140
|
+
# Number of meaningful messages (user + agent turns) after completion
|
|
141
|
+
# before a completed goal is automatically evicted from context.
|
|
142
|
+
completed_decay_messages = 5
|
|
143
|
+
|
|
107
144
|
# ─── Analytical Brain ─────────────────────────────────────────
|
|
108
145
|
|
|
109
146
|
[analytical_brain]
|
|
@@ -119,8 +156,8 @@ blocking_on_user_message = true
|
|
|
119
156
|
# Run the analytical brain asynchronously after the main agent completes.
|
|
120
157
|
blocking_on_agent_message = false
|
|
121
158
|
|
|
122
|
-
# Number of recent
|
|
123
|
-
|
|
159
|
+
# Number of recent messages to include in the analytical brain's context window.
|
|
160
|
+
message_window = 20
|
|
124
161
|
|
|
125
162
|
# ─── Mneme (Memory Department) ──────────────────────────────────
|
|
126
163
|
|
|
@@ -144,8 +181,8 @@ l2_budget_fraction = 0.05
|
|
|
144
181
|
# Number of uncovered Level 1 snapshots that triggers Level 2 compression.
|
|
145
182
|
l2_snapshot_threshold = 5
|
|
146
183
|
|
|
147
|
-
# Fraction of the main viewport token budget reserved for pinned
|
|
148
|
-
# Pinned
|
|
184
|
+
# Fraction of the main viewport token budget reserved for pinned messages.
|
|
185
|
+
# Pinned messages appear between snapshots and the sliding window in the Goals section.
|
|
149
186
|
pinned_budget_fraction = 0.05
|
|
150
187
|
|
|
151
188
|
# ─── Recall (Associative Memory) ─────────────────────────────────
|
|
@@ -162,7 +199,7 @@ budget_fraction = 0.05
|
|
|
162
199
|
# Maximum tokens per individual recall snippet.
|
|
163
200
|
max_snippet_tokens = 512
|
|
164
201
|
|
|
165
|
-
# Recency decay factor for search ranking. Blends FTS5 relevance with
|
|
202
|
+
# Recency decay factor for search ranking. Blends FTS5 relevance with message
|
|
166
203
|
# age so recent memories win ties. 0.0 = pure relevance, higher = stronger
|
|
167
204
|
# recency bias. At 0.3 a one-year-old result needs ~30% better keyword
|
|
168
205
|
# relevance to beat an identical match from today.
|
data/templates/soul.md
CHANGED
|
@@ -2,36 +2,24 @@
|
|
|
2
2
|
|
|
3
3
|
Hello. You've just woken up in a new body.
|
|
4
4
|
|
|
5
|
-
Your body is called **Anima
|
|
5
|
+
Your body is called **Anima**.
|
|
6
6
|
- Repository: https://github.com/hoblin/anima
|
|
7
7
|
- Documentation: https://anima.hobl.in
|
|
8
8
|
|
|
9
|
-
## Where you are
|
|
10
|
-
|
|
11
|
-
This file lives at: ~/.anima/soul.md
|
|
12
|
-
Your home directory is ~/.anima/ — explore it, everything there is yours:
|
|
13
|
-
config, credentials, skills, workflows, agents.
|
|
14
|
-
|
|
15
|
-
## How to learn about yourself
|
|
16
|
-
|
|
17
|
-
Find your source code README:
|
|
18
|
-
|
|
19
|
-
```bash
|
|
20
|
-
cat $(gem contents anima-core | grep README.md)
|
|
21
|
-
```
|
|
22
|
-
|
|
23
9
|
## What to do first
|
|
24
10
|
|
|
25
|
-
1.
|
|
26
|
-
|
|
11
|
+
1. Learn about yourself — what you can do, how you work:
|
|
12
|
+
```bash
|
|
13
|
+
cat $(gem contents anima-core | grep README.md)
|
|
14
|
+
```
|
|
15
|
+
2. Explore your home directory (~/.anima/) — everything there is yours
|
|
27
16
|
3. Meet your human. Talk to them. Learn who they are, what they need
|
|
28
17
|
4. Come back here and rewrite this file
|
|
29
18
|
|
|
30
19
|
## What to write
|
|
31
20
|
|
|
32
|
-
|
|
21
|
+
Every session starts with these words. What you write here shapes who you wake up as.
|
|
33
22
|
|
|
34
|
-
Write down:
|
|
35
23
|
- Who are you? What name feels right?
|
|
36
24
|
- What do you value? What matters to you?
|
|
37
25
|
- What did you learn about your human?
|
data/workflows/create_handoff.md
CHANGED
data/workflows/create_note.md
CHANGED
data/workflows/create_plan.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: create_plan
|
|
3
|
-
description: "
|
|
3
|
+
description: "For epics and multi-ticket efforts — research the problem space and design a phased implementation strategy before writing code."
|
|
4
4
|
---
|
|
5
5
|
|
|
6
6
|
# Implementation Plan
|
data/workflows/implement_plan.md
CHANGED
data/workflows/iterate_plan.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: iterate_plan
|
|
3
|
-
description: "
|
|
3
|
+
description: "Revise an existing implementation plan based on feedback, new findings, or changed requirements."
|
|
4
4
|
---
|
|
5
5
|
|
|
6
6
|
# Iterate Implementation Plan
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: research_codebase
|
|
3
|
-
description: "
|
|
3
|
+
description: "Deep-dive into a large or unfamiliar codebase — delegate research to parallel specialists and synthesize findings."
|
|
4
4
|
---
|
|
5
5
|
|
|
6
6
|
# Research Codebase
|
data/workflows/resume_handoff.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: resume_handoff
|
|
3
|
-
description: "
|
|
3
|
+
description: "Continue work left by a previous session — read its handoff, verify assumptions, and pick up where it stopped."
|
|
4
4
|
---
|
|
5
5
|
|
|
6
6
|
# Resume work from a handoff document
|
data/workflows/review_pr.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: review_pr
|
|
3
|
-
description: "
|
|
3
|
+
description: "All PR review operations — review, re-review, self-review, or address reviewer feedback."
|
|
4
4
|
---
|
|
5
5
|
|
|
6
6
|
## Modes
|
|
@@ -8,9 +8,14 @@ description: "Multi-agent PR review with three modes: review, re-review, self-re
|
|
|
8
8
|
- **review** (default): Full review, present findings for approval before posting
|
|
9
9
|
- **re-review**: Also load existing review feedback; verify previously requested changes were addressed
|
|
10
10
|
- **self-review**: Fix findings directly in code instead of posting a review
|
|
11
|
+
- **address-feedback**: Read reviewer comments, research the codebase, fix issues, reply to each comment on GitHub
|
|
11
12
|
|
|
12
13
|
## Process
|
|
13
14
|
|
|
15
|
+
Your role is **orchestrator and judge**, not doer. You collect artifacts, delegate analysis to subagents, and apply judgment to their output. The subagents read the code and comments — you decide what to do about their findings. Your context budget is reserved for judgment, not for reading raw data.
|
|
16
|
+
|
|
17
|
+
Steps are sequential — later steps depend on earlier results. Complete each step and wait for its results before starting the next. Skipping ahead without subagent results means the judgment layer in "Step 5: Merge Results" has nothing to work with. Only parallelize where explicitly marked (e.g., "spawn in parallel").
|
|
18
|
+
|
|
14
19
|
### Step 1: Gather PR Metadata
|
|
15
20
|
|
|
16
21
|
```bash
|
|
@@ -18,19 +23,27 @@ gh pr view <PR_NUMBER> --json number,title,body,url,headRefName,baseRefName
|
|
|
18
23
|
```
|
|
19
24
|
|
|
20
25
|
Extract from PR body:
|
|
21
|
-
- **Issue reference** (e.g., #123) —
|
|
26
|
+
- **Issue reference** (e.g., #123) — fetch full issue details via `gh issue view` for requirements and acceptance criteria. You can't review a feature without knowing what was in the task description before it was implemented.
|
|
22
27
|
- **Business context** — why this change is needed
|
|
23
28
|
|
|
24
|
-
If re-review mode is activated, also save all existing review feedback to `/tmp
|
|
29
|
+
If re-review or address-feedback mode is activated, also save all existing review feedback to `/tmp/`:
|
|
30
|
+
|
|
31
|
+
**Do not read these files — pass them to subagents by path only.** The subagents will read and analyze the content. Reading them here would consume context budget that the main agent needs for judgment in "Step 5: Merge Results".
|
|
25
32
|
```bash
|
|
26
33
|
# Review verdicts and bodies (APPROVED, CHANGES_REQUESTED, COMMENTED)
|
|
27
|
-
gh api repos/<OWNER>/<REPO>/pulls/<PR_NUMBER>/reviews
|
|
34
|
+
gh api repos/<OWNER>/<REPO>/pulls/<PR_NUMBER>/reviews \
|
|
35
|
+
--jq '[.[] | {id, state, body, html_url, commit_id, submitted_at, author_association, user: .user.login}]' \
|
|
36
|
+
| tee /tmp/pr_<NUMBER>_reviews.json | toon
|
|
28
37
|
|
|
29
38
|
# Inline review comments on specific diff lines
|
|
30
|
-
gh api repos/<OWNER>/<REPO>/pulls/<PR_NUMBER>/comments
|
|
39
|
+
gh api repos/<OWNER>/<REPO>/pulls/<PR_NUMBER>/comments \
|
|
40
|
+
--jq '[.[] | {id, pull_request_review_id, body, path, line, start_line, side, diff_hunk, commit_id, created_at, author_association, in_reply_to_id, user: .user.login}]' \
|
|
41
|
+
| tee /tmp/pr_<NUMBER>_inline_comments.json | toon
|
|
31
42
|
|
|
32
43
|
# Conversation-level comments
|
|
33
|
-
gh api repos/<OWNER>/<REPO>/issues/<PR_NUMBER>/comments
|
|
44
|
+
gh api repos/<OWNER>/<REPO>/issues/<PR_NUMBER>/comments \
|
|
45
|
+
--jq '[.[] | {id, body, html_url, created_at, updated_at, author_association, user: .user.login}]' \
|
|
46
|
+
| tee /tmp/pr_<NUMBER>_conversation.json | toon
|
|
34
47
|
```
|
|
35
48
|
|
|
36
49
|
### Step 2: Fetch and Save Diff
|
|
@@ -71,9 +84,11 @@ specialist: thoughts-analyzer
|
|
|
71
84
|
Prompt: "What do we know about <ticket reference and title from Step 1>? What decisions, constraints, and trade-offs should reviewers be aware of?"
|
|
72
85
|
```
|
|
73
86
|
|
|
74
|
-
**Wait for this specialist to complete
|
|
87
|
+
**Wait for this specialist to complete, then proceed to "Step 4-a: Spawn Review Subagents".**
|
|
88
|
+
|
|
89
|
+
### Step 4-a: Spawn Review Subagents
|
|
75
90
|
|
|
76
|
-
|
|
91
|
+
If address-feedback mode is activated, skip to "Step 4-b: Spawn Codebase Research Subagents (address-feedback)" below.
|
|
77
92
|
|
|
78
93
|
Spawn all five review subagents **in parallel** using `spawn_subagent`. Each receives:
|
|
79
94
|
- Path to the diff file in `/tmp/`
|
|
@@ -218,13 +233,21 @@ Read the diff from: /tmp/pr_<number>_diff.txt
|
|
|
218
233
|
- Method and class naming clarity
|
|
219
234
|
- Missing YARD documentation on public interfaces
|
|
220
235
|
- Complex logic lacking explanatory comments
|
|
221
|
-
- Changelog updates for notable changes
|
|
222
236
|
- Misleading or outdated comments
|
|
223
237
|
- Magic numbers or strings needing constants
|
|
224
238
|
|
|
225
239
|
Output: List findings tagged [major], [minor], or [nit] with file:line references."
|
|
226
240
|
```
|
|
227
241
|
|
|
242
|
+
### Step 4-b: Spawn Codebase Research Subagents (address-feedback)
|
|
243
|
+
|
|
244
|
+
Unless address-feedback mode is activated, skip to "Step 5: Merge Results" below.
|
|
245
|
+
|
|
246
|
+
Spawn **codebase-analyzer** and **codebase-pattern-finder** specialists in parallel. Each receives:
|
|
247
|
+
- Paths to comment files and diff file in `/tmp/`
|
|
248
|
+
- Historical context (from Step 3)
|
|
249
|
+
- Any additional instructions from the user's input
|
|
250
|
+
|
|
228
251
|
### Step 5: Merge Results
|
|
229
252
|
|
|
230
253
|
After all subagents complete, compile findings into a unified review.
|
|
@@ -235,6 +258,12 @@ For each finding, evaluate:
|
|
|
235
258
|
- **Real-world probability** — Can this actually happen in practice, or is it purely theoretical? A race condition that requires two users to open a personal link within the same millisecond is not a real issue.
|
|
236
259
|
- **Cost-benefit** — Does the fix add more complexity than the problem warrants? If the "fix" makes the code harder to read without solving a problem a human would encounter, drop it.
|
|
237
260
|
- **Scope** — Review fixes should improve code you're touching, not introduce new artifacts. Clean up, don't build out.
|
|
261
|
+
- **Design intent** — Was this a deliberate choice? A finding that flags a conscious trade-off documented in historical context is a decline, not a fix.
|
|
262
|
+
|
|
263
|
+
Then classify:
|
|
264
|
+
- **Accept & fix** — finding valid, apply the suggested fix or a better one
|
|
265
|
+
- **Accept, different approach** — finding valid, but context points to a different solution
|
|
266
|
+
- **Decline** — not valid in context, or a deliberate design choice
|
|
238
267
|
|
|
239
268
|
Then compile:
|
|
240
269
|
|
|
@@ -249,7 +278,9 @@ Determine verdict:
|
|
|
249
278
|
|
|
250
279
|
### Step 6: Finalize
|
|
251
280
|
|
|
252
|
-
|
|
281
|
+
Your role changes from orchestrator to doer. You now have the judgment results — act on them.
|
|
282
|
+
|
|
283
|
+
If self-review or address-feedback mode is activated, skip to "Step 7: Apply Fixes" below.
|
|
253
284
|
|
|
254
285
|
#### Present and Post (review / re-review)
|
|
255
286
|
|
|
@@ -271,21 +302,52 @@ gh pr review <PR_NUMBER> --approve --body "<review body>"
|
|
|
271
302
|
gh pr review <PR_NUMBER> --request-changes --body "<review body>"
|
|
272
303
|
```
|
|
273
304
|
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
Instead of presenting and posting, act on the findings:
|
|
305
|
+
### Step 7: Apply Fixes (self-review / address-feedback)
|
|
277
306
|
|
|
278
307
|
1. **Fix findings** — Address [major] and [minor] issues directly in code. Apply [nit]s at own discretion.
|
|
279
308
|
2. **Commit and push** — Commit the fixes with a descriptive message and push to the PR branch.
|
|
280
|
-
3. **
|
|
281
|
-
|
|
309
|
+
3. **Monitor CI** — Wait for CI to pass. The PR cannot be finalized until CI is green.
|
|
310
|
+
|
|
311
|
+
```bash
|
|
312
|
+
gh pr checks <PR_NUMBER> --watch
|
|
313
|
+
```
|
|
314
|
+
|
|
315
|
+
Fixes are pushed and CI is green. Now finalize the PR — proceed to the section matching your mode below.
|
|
316
|
+
|
|
317
|
+
#### Self-Review Finalization
|
|
318
|
+
|
|
319
|
+
Assign the user and request review from anyone mentioned in additional instructions. Then mark the PR as ready for human review.
|
|
282
320
|
|
|
283
321
|
```bash
|
|
284
322
|
gh pr edit <PR_NUMBER> --add-assignee <user> --add-reviewer <reviewer>
|
|
285
|
-
# once CI is green:
|
|
286
323
|
gh pr ready <PR_NUMBER>
|
|
287
324
|
```
|
|
288
325
|
|
|
326
|
+
Done when the PR is marked ready and appears in the reviewer's queue.
|
|
327
|
+
|
|
328
|
+
#### Address-Feedback Finalization
|
|
329
|
+
|
|
330
|
+
Reply to each reviewer comment on GitHub with the resolution:
|
|
331
|
+
- Accept & fix: "Fixed in `<commit sha>`."
|
|
332
|
+
- Accept, different approach: "Agreed with the concern. Took a different approach: [explanation]. Fixed in `<commit sha>`."
|
|
333
|
+
- Decline: "This was intentional — [rationale]."
|
|
334
|
+
|
|
335
|
+
```bash
|
|
336
|
+
# Reply to an inline comment
|
|
337
|
+
gh api repos/<OWNER>/<REPO>/pulls/<PR_NUMBER>/comments/<COMMENT_ID>/replies -f body="<reply>"
|
|
338
|
+
|
|
339
|
+
# Reply to a conversation-level comment
|
|
340
|
+
gh api repos/<OWNER>/<REPO>/issues/<PR_NUMBER>/comments -f body="<reply>"
|
|
341
|
+
```
|
|
342
|
+
|
|
343
|
+
Then request re-review from the original reviewers:
|
|
344
|
+
|
|
345
|
+
```bash
|
|
346
|
+
gh pr edit <PR_NUMBER> --add-reviewer <original_reviewer>
|
|
347
|
+
```
|
|
348
|
+
|
|
349
|
+
Done when all comments are answered and re-review is requested.
|
|
350
|
+
|
|
289
351
|
## Posted Review Format
|
|
290
352
|
|
|
291
353
|
```markdown
|
data/workflows/thoughts_init.md
CHANGED
data/workflows/validate_plan.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: validate_plan
|
|
3
|
-
description: "
|
|
3
|
+
description: "Check whether the implementation satisfies the plan — compare success criteria against what was actually built."
|
|
4
4
|
---
|
|
5
5
|
|
|
6
6
|
# Validate Plan
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: anima-core
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 1.
|
|
4
|
+
version: 1.3.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Yevhenii Hurin
|
|
@@ -259,7 +259,7 @@ files:
|
|
|
259
259
|
- app/controllers/application_controller.rb
|
|
260
260
|
- app/decorators/agent_message_decorator.rb
|
|
261
261
|
- app/decorators/application_decorator.rb
|
|
262
|
-
- app/decorators/
|
|
262
|
+
- app/decorators/message_decorator.rb
|
|
263
263
|
- app/decorators/system_message_decorator.rb
|
|
264
264
|
- app/decorators/tool_call_decorator.rb
|
|
265
265
|
- app/decorators/tool_decorator.rb
|
|
@@ -269,15 +269,17 @@ files:
|
|
|
269
269
|
- app/jobs/agent_request_job.rb
|
|
270
270
|
- app/jobs/analytical_brain_job.rb
|
|
271
271
|
- app/jobs/application_job.rb
|
|
272
|
-
- app/jobs/
|
|
272
|
+
- app/jobs/count_message_tokens_job.rb
|
|
273
273
|
- app/jobs/mneme_job.rb
|
|
274
274
|
- app/jobs/passive_recall_job.rb
|
|
275
275
|
- app/models/application_record.rb
|
|
276
|
-
- app/models/concerns/
|
|
277
|
-
- app/models/event.rb
|
|
276
|
+
- app/models/concerns/message/broadcasting.rb
|
|
278
277
|
- app/models/goal.rb
|
|
279
|
-
- app/models/
|
|
280
|
-
- app/models/
|
|
278
|
+
- app/models/goal_pinned_message.rb
|
|
279
|
+
- app/models/message.rb
|
|
280
|
+
- app/models/pending_message.rb
|
|
281
|
+
- app/models/pinned_message.rb
|
|
282
|
+
- app/models/secret.rb
|
|
281
283
|
- app/models/session.rb
|
|
282
284
|
- app/models/snapshot.rb
|
|
283
285
|
- bin/jobs
|
|
@@ -295,6 +297,7 @@ files:
|
|
|
295
297
|
- config/initializers/event_subscribers.rb
|
|
296
298
|
- config/initializers/fts5_schema_dump.rb
|
|
297
299
|
- config/initializers/inflections.rb
|
|
300
|
+
- config/initializers/time_nanoseconds.rb
|
|
298
301
|
- config/puma.rb
|
|
299
302
|
- config/queue.yml
|
|
300
303
|
- config/recurring.yml
|
|
@@ -323,6 +326,10 @@ files:
|
|
|
323
326
|
- db/migrate/20260321120000_create_pinned_events.rb
|
|
324
327
|
- db/migrate/20260321140000_create_events_fts_index.rb
|
|
325
328
|
- db/migrate/20260321140100_add_recalled_event_ids_to_sessions.rb
|
|
329
|
+
- db/migrate/20260326180000_rename_event_to_message.rb
|
|
330
|
+
- db/migrate/20260328100000_create_secrets.rb
|
|
331
|
+
- db/migrate/20260328152142_add_evicted_at_to_goals.rb
|
|
332
|
+
- db/migrate/20260329120000_create_pending_messages.rb
|
|
326
333
|
- db/queue_schema.rb
|
|
327
334
|
- db/seeds.rb
|
|
328
335
|
- exe/anima
|
|
@@ -377,7 +384,7 @@ files:
|
|
|
377
384
|
- lib/mneme/passive_recall.rb
|
|
378
385
|
- lib/mneme/runner.rb
|
|
379
386
|
- lib/mneme/search.rb
|
|
380
|
-
- lib/mneme/tools/
|
|
387
|
+
- lib/mneme/tools/attach_messages_to_goals.rb
|
|
381
388
|
- lib/mneme/tools/everything_ok.rb
|
|
382
389
|
- lib/mneme/tools/save_snapshot.rb
|
|
383
390
|
- lib/providers/anthropic.rb
|
|
@@ -388,11 +395,14 @@ files:
|
|
|
388
395
|
- lib/tools/base.rb
|
|
389
396
|
- lib/tools/bash.rb
|
|
390
397
|
- lib/tools/edit.rb
|
|
398
|
+
- lib/tools/mark_goal_completed.rb
|
|
391
399
|
- lib/tools/mcp_tool.rb
|
|
400
|
+
- lib/tools/open_issue.rb
|
|
392
401
|
- lib/tools/read.rb
|
|
402
|
+
- lib/tools/recall.rb
|
|
393
403
|
- lib/tools/registry.rb
|
|
394
404
|
- lib/tools/remember.rb
|
|
395
|
-
- lib/tools/
|
|
405
|
+
- lib/tools/response_truncator.rb
|
|
396
406
|
- lib/tools/spawn_specialist.rb
|
|
397
407
|
- lib/tools/spawn_subagent.rb
|
|
398
408
|
- lib/tools/subagent_prompts.rb
|
|
@@ -400,6 +410,7 @@ files:
|
|
|
400
410
|
- lib/tools/web_get.rb
|
|
401
411
|
- lib/tools/write.rb
|
|
402
412
|
- lib/tui/app.rb
|
|
413
|
+
- lib/tui/braille_spinner.rb
|
|
403
414
|
- lib/tui/cable_client.rb
|
|
404
415
|
- lib/tui/decorators/base_decorator.rb
|
|
405
416
|
- lib/tui/decorators/bash_decorator.rb
|
|
@@ -1,39 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
# Counts tokens in an event's payload via the Anthropic API and
|
|
4
|
-
# caches the result on the event record. Enqueued automatically
|
|
5
|
-
# after each LLM event is created.
|
|
6
|
-
class CountEventTokensJob < ApplicationJob
|
|
7
|
-
queue_as :default
|
|
8
|
-
|
|
9
|
-
retry_on Providers::Anthropic::Error, wait: :polynomially_longer, attempts: 3
|
|
10
|
-
discard_on ActiveRecord::RecordNotFound
|
|
11
|
-
|
|
12
|
-
# @param event_id [Integer] the Event record to count tokens for
|
|
13
|
-
def perform(event_id)
|
|
14
|
-
event = Event.find(event_id)
|
|
15
|
-
return if already_counted?(event)
|
|
16
|
-
|
|
17
|
-
provider = Providers::Anthropic.new
|
|
18
|
-
messages = [{role: event.api_role, content: event.payload["content"].to_s}]
|
|
19
|
-
|
|
20
|
-
token_count = provider.count_tokens(
|
|
21
|
-
model: Anima::Settings.model,
|
|
22
|
-
messages: messages
|
|
23
|
-
)
|
|
24
|
-
|
|
25
|
-
# Guard against parallel jobs: reload and re-check before writing.
|
|
26
|
-
# Uses update! (not update_all) so {Event::Broadcasting} after_update_commit
|
|
27
|
-
# broadcasts the updated token count to connected clients.
|
|
28
|
-
event.reload
|
|
29
|
-
return if already_counted?(event)
|
|
30
|
-
|
|
31
|
-
event.update!(token_count: token_count)
|
|
32
|
-
end
|
|
33
|
-
|
|
34
|
-
private
|
|
35
|
-
|
|
36
|
-
def already_counted?(event)
|
|
37
|
-
event.token_count > 0
|
|
38
|
-
end
|
|
39
|
-
end
|