@jmylchreest/aide-plugin 0.0.39 → 0.0.40

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.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@jmylchreest/aide-plugin",
3
- "version": "0.0.39",
3
+ "version": "0.0.40",
4
4
  "description": "aide plugin for OpenCode — multi-agent orchestration, memory, skills, and persistence",
5
5
  "type": "module",
6
6
  "main": "./src/opencode/index.ts",
@@ -86,6 +86,18 @@ Is the code indexed?
86
86
  → Returns: file count, symbol count, reference count
87
87
  ```
88
88
 
89
+ ### 6. Search Findings (`mcp__plugin_aide_aide__findings_search`)
90
+
91
+ Search static analysis findings (complexity hotspots, secrets, code clones, coupling issues).
92
+
93
+ **Example usage:**
94
+
95
+ ```
96
+ Any complexity issues in src/auth?
97
+ → Uses findings_search tool with query "auth" or file filter
98
+ → Returns: findings with file, line, severity, description
99
+ ```
100
+
89
101
  ## Workflow
90
102
 
91
103
  1. **First, check if codebase is indexed:**
@@ -156,6 +156,16 @@ git worktree list | grep <worktree-path>
156
156
  git branch -a | grep <branch-name>
157
157
  ```
158
158
 
159
+ ## Change Context with Findings
160
+
161
+ When reviewing diffs or preparing commits, use findings tools to understand the quality context of changed code:
162
+
163
+ - `mcp__plugin_aide_aide__findings_search` — Search for known issues (complexity, secrets, clones) in changed files
164
+ - `mcp__plugin_aide_aide__findings_list` — List all findings for a specific file to understand its health
165
+ - `mcp__plugin_aide_aide__findings_stats` — Quick overview of finding counts across the project
166
+
167
+ This helps surface pre-existing issues in files you're touching, and can inform whether a commit should also address nearby problems.
168
+
159
169
  ## Parallel Work Pattern
160
170
 
161
171
  For swarm mode or parallel features:
@@ -52,25 +52,31 @@ Use the `./.aide/bin/aide memory add` CLI command via Bash:
52
52
  ### Simple preference (global - injected at session start)
53
53
 
54
54
  ```bash
55
- ./.aide/bin/aide memory add --category=learning --tags=preferences,colour,scope:global "User's favourite colour is blue"
55
+ ./.aide/bin/aide memory add --category=learning --tags=preferences,colour,scope:global,source:user "User's favourite colour is blue"
56
56
  ```
57
57
 
58
- ### Technical learning (project-specific)
58
+ ### Technical learning (project-specific, verified)
59
59
 
60
60
  ```bash
61
- ./.aide/bin/aide memory add --category=learning --tags=testing,vitest,project:myapp,session:abc12345 "Vitest requires .js extensions for ESM imports even for .ts files. Configure moduleResolution: NodeNext in tsconfig."
61
+ ./.aide/bin/aide memory add --category=learning --tags=testing,vitest,project:myapp,session:abc12345,source:discovered,verified:true "Vitest requires .js extensions for ESM imports even for .ts files. Configure moduleResolution: NodeNext in tsconfig."
62
62
  ```
63
63
 
64
64
  ### Session summary
65
65
 
66
66
  ```bash
67
- ./.aide/bin/aide memory add --category=session --tags=auth,api,project:myapp,session:abc12345 "Implemented JWT auth with 15min access tokens, 7day refresh tokens in httpOnly cookies. Files: src/auth/jwt.ts, src/middleware/auth.ts, src/routes/auth.ts"
67
+ ./.aide/bin/aide memory add --category=session --tags=auth,api,project:myapp,session:abc12345,source:discovered "Implemented JWT auth with 15min access tokens, 7day refresh tokens in httpOnly cookies. Files: src/auth/jwt.ts, src/middleware/auth.ts, src/routes/auth.ts"
68
68
  ```
69
69
 
70
70
  ### Gotcha (global - applies everywhere)
71
71
 
72
72
  ```bash
73
- ./.aide/bin/aide memory add --category=gotcha --tags=hooks,claude-code,scope:global "Hooks must not write to stderr - Claude Code interprets any stderr as error. Debug logging must go to files only."
73
+ ./.aide/bin/aide memory add --category=gotcha --tags=hooks,claude-code,scope:global,source:discovered,verified:true "Hooks must not write to stderr - Claude Code interprets any stderr as error. Debug logging must go to files only."
74
+ ```
75
+
76
+ ### Unverified external claim
77
+
78
+ ```bash
79
+ ./.aide/bin/aide memory add --category=learning --tags=api,stripe,project:myapp,source:user,verified:false "Stripe webhook signatures use HMAC-SHA256 with the whsec_ prefix."
74
80
  ```
75
81
 
76
82
  ## Instructions
@@ -78,18 +84,90 @@ Use the `./.aide/bin/aide memory add` CLI command via Bash:
78
84
  When the user invokes `/aide:memorise <something>`:
79
85
 
80
86
  1. Parse what they want to remember
81
- 2. Determine the scope:
87
+ 2. **Verify factual claims before storing** (see [Verification Before Storage](#verification-before-storage-anti-poison) below)
88
+ 3. Determine the scope:
82
89
  - **User preference** (colour, style, etc.) → add `scope:global`
83
90
  - **Project-specific learning** → add `project:<project-name>,session:${CLAUDE_SESSION_ID:0:8}`
84
91
  - **Session summary** → add `project:<project-name>,session:${CLAUDE_SESSION_ID:0:8}`
85
- 3. Choose appropriate category and descriptive tags
86
- 4. Format the content concisely but completely
87
- 5. Call `./.aide/bin/aide memory add` via Bash to store it
88
- 6. **Verify success** - check exit code is 0 and output contains the memory ID
89
- 7. Confirm what was stored
92
+ 4. Choose appropriate category and descriptive tags
93
+ 5. **Add provenance tags** (see [Provenance Tags](#provenance-tags) below)
94
+ 6. Format the content concisely but completely
95
+ 7. Call `./.aide/bin/aide memory add` via Bash to store it
96
+ 8. **Verify success** - check exit code is 0 and output contains the memory ID
97
+ 9. Confirm what was stored, including verification outcome
90
98
 
91
99
  Keep content concise - aim for 1-3 sentences unless it's a complex session summary.
92
100
 
101
+ ## Verification Before Storage (Anti-Poison)
102
+
103
+ Memories persist across sessions and influence future behaviour. Storing incorrect information is **worse than storing nothing** — it creates compounding errors. Before storing any memory, verify its claims.
104
+
105
+ ### What to Verify
106
+
107
+ | Claim Type | Verification Method | Example |
108
+ | ------------------------- | ----------------------------------------------------- | ---------------------------------------------- |
109
+ | **File exists** | Use Glob or Read to confirm | "Config is in src/config.ts" |
110
+ | **Function/class exists** | Use Grep or code search | "Use `parseToken()` from auth.ts" |
111
+ | **Function signature** | Read the file, check the actual signature | "parseToken takes a string and returns Claims" |
112
+ | **API behaviour** | Check the implementation or tests | "The /users endpoint requires auth" |
113
+ | **Dependency/version** | Check package.json, go.mod, etc. | "Project uses Vitest v2" |
114
+ | **Build/test command** | Confirm the script exists in package.json or Makefile | "Run `npm run test:e2e` for integration tests" |
115
+
116
+ ### What Does NOT Need Verification
117
+
118
+ - **User preferences** — The user is the authority ("I prefer tabs over spaces")
119
+ - **Session summaries** — Recap of what just happened in the current session
120
+ - **Opinions/decisions** — Architectural choices made by the user ("We chose Postgres")
121
+ - **External facts** — Things not checkable against the codebase ("React 19 uses...")
122
+
123
+ ### Verification Workflow
124
+
125
+ ```
126
+ Is it a codebase claim (file, function, path, command, behaviour)?
127
+ ├── No → Store directly with source:user or source:stated
128
+ └── Yes → Can you verify it right now?
129
+ ├── Yes → Verify it
130
+ │ ├── Correct → Store with verified:true
131
+ │ └── Wrong → Inform user, do NOT store. Offer corrected version.
132
+ └── No (e.g., external service, runtime behaviour)
133
+ → Store with verified:false, note unverified
134
+ ```
135
+
136
+ ### Verification Rules
137
+
138
+ 1. **NEVER store a codebase claim without checking** — If the user says "the auth middleware is in src/middleware/auth.ts", confirm the file exists before memorising.
139
+ 2. **If verification fails, do NOT store** — Tell the user what you found instead and offer to store the corrected version.
140
+ 3. **If you cannot verify** (e.g., claim about runtime behaviour, external API), store it but tag with `verified:false`.
141
+ 4. **Err on the side of not storing** — A missing memory is recoverable; a wrong memory causes future errors.
142
+
143
+ ### Example: Verified vs Rejected
144
+
145
+ **User says:** "Remember that the database schema is defined in db/schema.sql"
146
+
147
+ **Verification steps:**
148
+
149
+ 1. Check: does `db/schema.sql` exist? → Use Glob to search
150
+ 2. If yes → Store with `verified:true`
151
+ 3. If no → "I checked and `db/schema.sql` doesn't exist. I found `database/migrations/` instead. Would you like me to store that instead?"
152
+
153
+ ## Provenance Tags
154
+
155
+ Always include provenance tags to track the origin and verification status of memories:
156
+
157
+ | Tag | Meaning | When to Use |
158
+ | ------------------- | ---------------------------------------- | ------------------------------------------------ |
159
+ | `source:user` | User explicitly stated this | User preferences, direct instructions |
160
+ | `source:discovered` | Agent discovered this by examining code | File paths, function signatures, patterns found |
161
+ | `source:inferred` | Agent inferred this from context | Behaviour deduced from code, not directly stated |
162
+ | `verified:true` | Codebase claim was checked and confirmed | After successful verification |
163
+ | `verified:false` | Claim could not be verified against code | External facts, runtime behaviour |
164
+
165
+ ### Provenance Rules
166
+
167
+ - Every memory MUST have exactly one `source:` tag
168
+ - Codebase claims MUST have a `verified:` tag
169
+ - User preferences and opinions do NOT need `verified:` tags (user is authoritative)
170
+
93
171
  ## Failure Handling
94
172
 
95
173
  If `./.aide/bin/aide memory add` fails:
@@ -0,0 +1,177 @@
1
+ ---
2
+ name: patterns
3
+ description: Analyze codebase patterns, detect anti-patterns, and surface static analysis findings
4
+ triggers:
5
+ - find patterns
6
+ - anti-patterns
7
+ - code smells
8
+ - complexity
9
+ - duplicated code
10
+ - clones
11
+ - secrets
12
+ - coupling
13
+ - findings
14
+ - static analysis
15
+ - code health
16
+ ---
17
+
18
+ # Pattern Analysis
19
+
20
+ **Recommended model tier:** balanced (sonnet) - this skill combines search with structured analysis
21
+
22
+ Analyze codebase patterns using static analysis findings. Surface complexity hotspots, code
23
+ duplication, coupling issues, and potential secrets. Use this skill to understand code health
24
+ and identify areas that need attention.
25
+
26
+ ## Prerequisites
27
+
28
+ Findings must be generated first by running analyzers via the CLI:
29
+
30
+ ```bash
31
+ # Run all analyzers
32
+ ./.aide/bin/aide findings run --path .
33
+
34
+ # Run specific analyzers
35
+ ./.aide/bin/aide findings run --path . --analyzer complexity
36
+ ./.aide/bin/aide findings run --path . --analyzer coupling
37
+ ./.aide/bin/aide findings run --path . --analyzer secrets
38
+ ./.aide/bin/aide findings run --path . --analyzer clones
39
+ ```
40
+
41
+ **Binary location:** The aide binary is at `.aide/bin/aide`. If it's on your `$PATH`, you can use `aide` directly.
42
+
43
+ ## Available Tools
44
+
45
+ ### 1. Search Findings (`mcp__plugin_aide_aide__findings_search`)
46
+
47
+ Full-text search across all findings. Supports Bleve query syntax for advanced searches.
48
+
49
+ **Parameters:**
50
+ - `query` (required) — Search term or Bleve query
51
+ - `analyzer` (optional) — Filter to one analyzer: `complexity`, `coupling`, `secrets`, `clones`
52
+ - `severity` (optional) — Filter by severity: `info`, `warning`, `critical`
53
+ - `file` (optional) — Filter by file path substring
54
+ - `limit` (optional) — Max results (default 20)
55
+
56
+ **Example usage:**
57
+
58
+ ```
59
+ Search for: "high complexity"
60
+ -> findings_search query="complexity" severity="warning"
61
+ -> Returns: functions with high cyclomatic complexity, with file:line
62
+ ```
63
+
64
+ ### 2. List Findings (`mcp__plugin_aide_aide__findings_list`)
65
+
66
+ List findings with filters. Use when you want to browse rather than search.
67
+
68
+ **Parameters:**
69
+ - `analyzer` (optional) — Filter to one analyzer
70
+ - `severity` (optional) — Filter by severity
71
+ - `file` (optional) — Filter by file path substring
72
+ - `limit` (optional) — Max results (default 20)
73
+ - `offset` (optional) — Pagination offset
74
+
75
+ **Example usage:**
76
+
77
+ ```
78
+ List all critical findings
79
+ -> findings_list severity="critical"
80
+ -> Returns: all critical-severity findings across all analyzers
81
+ ```
82
+
83
+ ### 3. Findings Statistics (`mcp__plugin_aide_aide__findings_stats`)
84
+
85
+ Get aggregate counts by analyzer and severity. Use as a starting point to understand overall
86
+ code health before drilling into specifics.
87
+
88
+ **Example usage:**
89
+
90
+ ```
91
+ How healthy is the codebase?
92
+ -> findings_stats
93
+ -> Returns: counts per analyzer, counts per severity, total findings
94
+ ```
95
+
96
+ ## Workflow
97
+
98
+ ### Quick Health Check
99
+
100
+ 1. **Get overview** — Use `findings_stats` to see counts by analyzer and severity
101
+ 2. **Triage critical** — Use `findings_list severity="critical"` to review highest-priority items
102
+ 3. **Drill into areas** — Use `findings_search` with file or query filters for specific concerns
103
+
104
+ ### Complexity Analysis
105
+
106
+ 1. Run `findings_search analyzer="complexity" severity="critical"` to find the most complex functions
107
+ 2. Use `code_outline` on flagged files to understand structure
108
+ 3. Use `Read` with offset/limit to examine the specific functions
109
+ 4. Recommend decomposition strategies
110
+
111
+ ### Duplication Analysis
112
+
113
+ 1. Run `findings_list analyzer="clones"` to see detected code clones
114
+ 2. Each finding includes the clone pair — both file locations and line ranges
115
+ 3. Use `Read` to compare the duplicated sections
116
+ 4. Recommend extraction into shared functions or modules
117
+
118
+ ### Coupling Analysis
119
+
120
+ 1. Run `findings_search analyzer="coupling"` to see import fan-out/fan-in issues
121
+ 2. High fan-out means a file imports too many things (potential god module)
122
+ 3. High fan-in means many files depend on one (fragile dependency)
123
+ 4. Cycle findings indicate circular dependency chains
124
+
125
+ ### Secret Detection
126
+
127
+ 1. Run `findings_list analyzer="secrets" severity="critical"` for confirmed secrets
128
+ 2. Run `findings_list analyzer="secrets"` for all potential secrets (including unverified)
129
+ 3. Each finding includes the secret category (e.g., AWS, GitHub, generic API key)
130
+ 4. Snippets are redacted for safety — use `Read` to examine context around the finding
131
+
132
+ ## Anti-Pattern Identification
133
+
134
+ Beyond the automated analyzers, look for these patterns using findings as starting points:
135
+
136
+ | Finding | Likely Anti-Pattern | Action |
137
+ |---------|-------------------|--------|
138
+ | Complexity > 20 | God function | Decompose into smaller functions |
139
+ | Fan-out > 15 | Kitchen sink module | Split responsibilities |
140
+ | Fan-in > 20 | Fragile dependency | Consider interface/abstraction |
141
+ | Multiple clones | Copy-paste programming | Extract shared utility |
142
+ | Import cycle | Circular dependency | Restructure module boundaries |
143
+
144
+ ## Output Format
145
+
146
+ ```markdown
147
+ ## Code Health Report
148
+
149
+ ### Overview
150
+ - Total findings: X (Y critical, Z warnings)
151
+ - Top concern: [area/file with most issues]
152
+
153
+ ### Hotspots
154
+ 1. **`file:line`** - [description] (severity)
155
+ - Impact: [why this matters]
156
+ - Recommendation: [what to do]
157
+
158
+ ### Patterns Detected
159
+ - [List of anti-patterns found with evidence]
160
+
161
+ ### Recommendations
162
+ 1. [Prioritized action items]
163
+ ```
164
+
165
+ ## Failure Handling
166
+
167
+ 1. **No findings data** — Tell user to run analyzers first: `./.aide/bin/aide findings run --path .`
168
+ 2. **Stale findings** — Findings reflect the state at last analyzer run; recommend re-running if code changed significantly
169
+ 3. **False positives** — Secret detection may flag test fixtures or example configs; note when findings appear to be in test/example code
170
+
171
+ ## Verification Criteria
172
+
173
+ - [ ] Checked `findings_stats` for overall picture
174
+ - [ ] Reviewed critical findings
175
+ - [ ] Cross-referenced findings with actual code (used `Read` or `code_outline`)
176
+ - [ ] Provided actionable recommendations with file:line references
177
+ - [ ] Noted any false positives or findings that need manual verification
@@ -113,6 +113,11 @@ Output a structured story list. Each story must be:
113
113
 
114
114
  4. **Instruct the user**: Run `/aide:swarm` to execute the plan
115
115
 
116
+ **Note on task materialization:** The plan is stored as a decision, not as tasks. The `/aide:swarm` skill reads the plan and materializes tasks at execution time:
117
+
118
+ - **Claude Code**: Each story agent creates native tasks (`TaskCreate`) with `blockedBy` dependency chaining for SDLC stages.
119
+ - **OpenCode**: The orchestrator creates aide tasks (`task_create` MCP tool) for all SDLC stages upfront, and story agents claim them.
120
+
116
121
  ## Output Format
117
122
 
118
123
  The stored `swarm-plan` decision should be a JSON object:
@@ -34,6 +34,15 @@ You are now in **Ralph Wiggum mode** - an iterative development methodology that
34
34
 
35
35
  All state is managed through aide. Use MCP tools for reads, CLI for writes:
36
36
 
37
+ ### Task System Roles
38
+
39
+ | System | Role | How |
40
+ | --------------------------- | ------------------------------------------------------- | --------------------------------------------------------------------- |
41
+ | **aide tasks** (MCP or CLI) | Durable task backlog, claiming, persistence enforcement | `task_create`/`task_claim`/`task_complete` (MCP) or `aide task` (CLI) |
42
+ | **Native todowrite** | Personal progress tracking within current iteration | `todowrite` tool — tracks sub-steps of current task |
43
+
44
+ aide tasks are the source of truth for ralph — they survive session restarts and are checked by persistence hooks to block premature stopping. Use native `todowrite` for your own step-by-step checklist within each task iteration.
45
+
37
46
  ### Reads (MCP Tools)
38
47
 
39
48
  | Tool | Purpose |
@@ -43,14 +52,18 @@ All state is managed through aide. Use MCP tools for reads, CLI for writes:
43
52
  | `mcp__plugin_aide_aide__decision_get` | Get decisions |
44
53
  | `mcp__plugin_aide_aide__decision_list` | List all decisions |
45
54
  | `mcp__plugin_aide_aide__memory_search` | Search discoveries |
55
+ | `task_list` | List aide tasks |
56
+ | `task_get` | Get task by ID |
46
57
 
47
- ### Writes (CLI via Bash)
58
+ ### Writes (CLI via Bash or MCP)
48
59
 
49
60
  ```bash
50
61
  # Phase tracking
51
62
  ./.aide/bin/aide state set ralph:phase planning # or "building"
52
63
 
53
- # Task management (use Claude's native TaskCreate/TaskUpdate/TaskList)
64
+ # Task management use aide tasks (persistent, claimable)
65
+ # Via MCP: task_create, task_claim, task_complete
66
+ # Via CLI: ./.aide/bin/aide task create/claim/complete
54
67
 
55
68
  # Decisions
56
69
  ./.aide/bin/aide decision set <topic> "<decision>" --rationale="<why>"
@@ -168,12 +181,6 @@ Claim it:
168
181
  ./.aide/bin/aide task claim <task-id> --agent=ralph
169
182
  ```
170
183
 
171
- Claim it:
172
-
173
- ```bash
174
- ./.aide/bin/aide task claim <task-id> --agent=ralph
175
- ```
176
-
177
184
  #### 3. Verify Gap Still Exists (Don't Assume!)
178
185
 
179
186
  Before implementing, RE-VERIFY:
@@ -88,6 +88,9 @@ Use these tools during review:
88
88
  - `mcp__plugin_aide_aide__code_symbols` - List all symbols in a file being reviewed
89
89
  - `mcp__plugin_aide_aide__code_references` - Find all callers/usages of a modified symbol
90
90
  - `mcp__plugin_aide_aide__memory_search` - Check for related past decisions or issues
91
+ - `mcp__plugin_aide_aide__findings_search` - Search static analysis findings (complexity, secrets, clones) related to changed code
92
+ - `mcp__plugin_aide_aide__findings_list` - List findings filtered by file, severity, or analyzer
93
+ - `mcp__plugin_aide_aide__findings_stats` - Overview of finding counts by analyzer and severity
91
94
 
92
95
  ## Output Format
93
96
 
@@ -432,43 +432,90 @@ message_ack: message_id=42, agent_id="agent-auth"
432
432
  ./.aide/bin/aide memory add --category=discovery "User model needs email validation"
433
433
  ```
434
434
 
435
- **Memory** (shared discoveries):
435
+ ## OpenCode Mode
436
436
 
437
- ```bash
438
- ./.aide/bin/aide memory add --category=discovery "User model needs email validation"
439
- ```
437
+ OpenCode has native `todowrite`/`todoread` for per-agent progress tracking, and a `task` tool for spawning subagents. However, OpenCode's todos are **session-private** — they are NOT shared across agents. For multi-agent coordination, use **aide tasks** (MCP tools) as the shared task system.
440
438
 
441
- ## OpenCode Mode
439
+ ### Task System Roles (OpenCode)
442
440
 
443
- OpenCode does not have native subagent support. For multi-agent swarms with OpenCode:
441
+ | System | Role | Scope |
442
+ | ------------------------------------------------------------------------------- | --------------------------------------------------- | -------------------------- |
443
+ | **aide tasks** (MCP: `task_create`, `task_list`, `task_claim`, `task_complete`) | Shared coordination — all agents see the same board | Cross-session, persistent |
444
+ | **todowrite** (native) | Personal progress tracking within each agent | Session-private, per-agent |
445
+ | **aide messages** (MCP: `message_send`, `message_list`) | Real-time coordination, status broadcasts, blockers | Cross-session |
444
446
 
445
- **Setup:**
447
+ ### Setup
446
448
 
447
449
  1. Create worktrees as normal (one per story)
448
450
  2. Launch separate OpenCode terminal sessions, one per story
449
451
  3. Each session works in its assigned worktree directory
450
452
 
451
- **Coordination:**
453
+ ### Orchestrator Workflow
452
454
 
453
- - **No TaskList** OpenCode sessions don't share a task system
454
- - **Use aide messages** as the primary coordination mechanism:
455
- - Each session uses `message_send` to report status, blockers, and completion
456
- - Check `message_list` at each stage transition
457
- - The orchestrator monitors all agents via `message_list` with their own agent_id
458
- - **Use aide state** for progress tracking:
459
- ```bash
460
- ./.aide/bin/aide state set "agent-auth:stage" "TEST"
461
- ./.aide/bin/aide state set "agent-auth:status" "running"
462
- ```
463
- - Monitor all agents: `mcp__plugin_aide_aide__state_list`
464
-
465
- **Orchestrator role (human or primary session):**
455
+ The orchestrator (human or primary session):
466
456
 
467
457
  1. Decompose stories (use `/aide:plan-swarm` first)
468
458
  2. Create worktrees
469
- 3. Launch terminal sessions with instructions
470
- 4. Monitor via `message_list` and `state_list`
471
- 5. When all sessions report `completion`, run `/aide:worktree-resolve`
459
+ 3. Create aide tasks for all SDLC stages upfront:
460
+ ```
461
+ task_create: title="[story-auth][DESIGN] Design auth module"
462
+ task_create: title="[story-auth][TEST] Write auth tests"
463
+ task_create: title="[story-auth][DEV] Implement auth"
464
+ task_create: title="[story-auth][VERIFY] Verify auth"
465
+ task_create: title="[story-auth][DOCS] Document auth"
466
+ ```
467
+ 4. Launch terminal sessions with instructions (include agent ID and story assignment)
468
+ 5. Monitor progress via `task_list` (MCP tool) or `./.aide/bin/aide task list` (CLI)
469
+ 6. When all tasks show `done`, run `/aide:worktree-resolve`
470
+
471
+ ### Story Agent Workflow (OpenCode)
472
+
473
+ Each story agent follows the same SDLC pipeline. Use aide tasks for shared tracking and native `todowrite` for personal step-by-step progress:
474
+
475
+ ```
476
+ ## Per SDLC Stage:
477
+
478
+ 1. Claim the stage task:
479
+ task_claim: task_id=<id>, agent_id=agent-auth
480
+
481
+ 2. Use todowrite for personal tracking:
482
+ todowrite: [{"content": "Design interfaces for auth", "status": "in_progress", "priority": "high"}]
483
+
484
+ 3. Execute the stage (use appropriate /aide: skill)
485
+
486
+ 4. Complete the aide task:
487
+ task_complete: task_id=<id>, result="Designed JWT auth with refresh tokens"
488
+
489
+ 5. Send status message:
490
+ message_send: from="agent-auth", type="status", content="[DESIGN] complete"
491
+
492
+ 6. Check for messages from other agents:
493
+ message_list: agent_id="agent-auth"
494
+ ```
495
+
496
+ **Note:** aide tasks do not have `blockedBy` dependency chaining like Claude Code native tasks. Stage ordering is enforced by the SDLC pipeline instructions — each agent processes stages sequentially (DESIGN → TEST → DEV → VERIFY → DOCS).
497
+
498
+ ### Coordination (OpenCode)
499
+
500
+ ```
501
+ # Shared task board — all agents see the same tasks
502
+ task_list # View all tasks
503
+ task_list: status="pending" # View unclaimed work
504
+
505
+ # Messages — real-time coordination
506
+ message_send: from="agent-auth", type="status", content="[DESIGN] complete, starting TEST"
507
+ message_send: from="agent-auth", to="agent-payments", type="request", content="Need payment API schema"
508
+ message_list: agent_id="agent-auth"
509
+ message_ack: message_id=42, agent_id="agent-auth"
510
+
511
+ # State — supplementary progress tracking
512
+ ./.aide/bin/aide state set "agent-auth:stage" "TEST"
513
+
514
+ # Decisions and discoveries — shared knowledge
515
+ mcp__plugin_aide_aide__decision_get with topic="auth-strategy"
516
+ ./.aide/bin/aide decision set "auth-strategy" "JWT with refresh tokens"
517
+ ./.aide/bin/aide memory add --category=discovery "User model needs email validation"
518
+ ```
472
519
 
473
520
  ## Completion (MANDATORY STEPS)
474
521
 
@@ -477,7 +524,11 @@ Swarm completion checklist - ALL REQUIRED:
477
524
  ### Step 1: Verify All Stories Complete
478
525
 
479
526
  ```
527
+ # Claude Code:
480
528
  TaskList # All story tasks must show [completed]
529
+
530
+ # OpenCode:
531
+ task_list # All aide tasks must show [done]
481
532
  ```
482
533
 
483
534
  - Every story must have completed all 5 SDLC stages
@@ -74,17 +74,23 @@ export function buildReinforcement(
74
74
  * Returns null if stop is allowed, or { reason } if stop should be blocked.
75
75
  * When a persistence mode is active and todos exist, the reinforcement
76
76
  * message includes the specific incomplete tasks.
77
+ *
78
+ * When agentId is provided, only tasks claimed by that agent are considered
79
+ * for blocking. This prevents subagents from being blocked by tasks that
80
+ * belong to other agents. Global (unclaimed) tasks still count for all agents.
77
81
  */
78
82
  export function checkPersistence(
79
83
  binary: string,
80
84
  cwd: string,
85
+ agentId?: string,
81
86
  ): { reason: string } | null {
82
87
  const mode = getActiveMode(binary, cwd);
83
88
  if (!mode) return null;
84
89
 
85
- // Get and increment iteration counter
90
+ // Get and increment iteration counter (guard against NaN from corrupted state)
86
91
  const iterStr = getState(binary, cwd, `${mode}_iterations`) || "0";
87
- const iteration = parseInt(iterStr, 10) + 1;
92
+ const parsed = parseInt(iterStr, 10);
93
+ const iteration = (Number.isNaN(parsed) ? 0 : parsed) + 1;
88
94
  setState(binary, cwd, `${mode}_iterations`, String(iteration));
89
95
 
90
96
  if (iteration > MAX_PERSISTENCE_ITERATIONS) {
@@ -94,21 +100,37 @@ export function checkPersistence(
94
100
  return null;
95
101
  }
96
102
 
97
- // Fetch todos and build a specific continuation message if incomplete tasks exist
103
+ // Fetch todos and build a specific continuation message if incomplete tasks exist.
104
+ // If all tasks are complete (or no tasks exist), auto-release: allow stop.
98
105
  let todoSummary: string | undefined;
106
+ let allTasksComplete = false;
99
107
  try {
100
108
  const todos = fetchTodosFromAide(binary, cwd);
101
- const todoResult = checkTodos(todos);
109
+ const todoResult = checkTodos(todos, agentId);
102
110
  if (todoResult.hasIncomplete) {
103
111
  todoSummary = todoResult.message;
104
112
  debug(
105
113
  SOURCE,
106
114
  `Found ${todoResult.incompleteCount} incomplete todos for persistence reinforcement`,
107
115
  );
116
+ } else if (todoResult.totalCount > 0) {
117
+ // All tasks exist and are in terminal states — work is done
118
+ allTasksComplete = true;
119
+ debug(
120
+ SOURCE,
121
+ `All ${todoResult.totalCount} tasks complete — auto-releasing ${mode} mode`,
122
+ );
108
123
  }
109
124
  } catch (err) {
110
125
  debug(SOURCE, `Failed to fetch todos for persistence (non-fatal): ${err}`);
111
126
  }
112
127
 
128
+ // Auto-release: if tasks exist and all are complete, allow stop
129
+ if (allTasksComplete) {
130
+ setState(binary, cwd, "mode", "");
131
+ setState(binary, cwd, `${mode}_iterations`, "0");
132
+ return null;
133
+ }
134
+
113
135
  return { reason: buildReinforcement(mode, iteration, todoSummary) };
114
136
  }
@@ -1,17 +1,18 @@
1
1
  /**
2
2
  * Todo continuation checker — platform-agnostic.
3
3
  *
4
- * Reads the agent's todo list and checks for incomplete items.
4
+ * Reads aide tasks (`aide task list`) and checks for incomplete items.
5
5
  * Used to enhance persistence-logic.ts with precise todo-aware blocking:
6
6
  * instead of a generic "verify your work is complete", we list the
7
- * specific incomplete todos.
7
+ * specific incomplete tasks.
8
8
  *
9
- * For Claude Code: reads todos from the transcript (TodoWrite tool outputs)
10
- * or from aide task list.
11
- * For OpenCode: reads todos via client.session.todo() API.
9
+ * Only checks aide tasks (persistent, cross-session). Native todos
10
+ * (Claude Code TodoWrite, OpenCode todowrite) are session-scoped
11
+ * personal tracking and are intentionally not checked here — neither
12
+ * platform exposes an API for reading them from hooks.
12
13
  *
13
14
  * This module provides the platform-agnostic core. Platform hooks
14
- * call it with however they obtained the todo list.
15
+ * call it via persistence-logic.ts.
15
16
  */
16
17
 
17
18
  import { runAide } from "./aide-client.js";
@@ -19,10 +20,24 @@ import { debug } from "../lib/logger.js";
19
20
 
20
21
  const SOURCE = "todo-checker";
21
22
 
23
+ /**
24
+ * Known terminal statuses — tasks in these states are considered "done".
25
+ * Any status NOT in this set is treated as incomplete (including unknown
26
+ * statuses from future aide versions), which is the safe default for
27
+ * persistence enforcement.
28
+ *
29
+ * Covers both aide backend statuses (done) and any legacy/alias statuses
30
+ * (completed, cancelled) for forward/backward compatibility.
31
+ */
32
+ export const TERMINAL_STATUSES = new Set(["done", "completed", "cancelled"]);
33
+
22
34
  export interface TodoItem {
23
35
  id: string;
24
36
  content: string;
25
- status: "pending" | "in_progress" | "completed" | "cancelled";
37
+ /** Raw status string from aide may be any value, not just known ones. */
38
+ status: string;
39
+ /** Agent that claimed this task, if any. */
40
+ claimedBy?: string;
26
41
  priority?: string;
27
42
  }
28
43
 
@@ -41,8 +56,16 @@ export interface TodoCheckResult {
41
56
 
42
57
  /**
43
58
  * Check a list of todos for incomplete items and build a continuation message.
59
+ *
60
+ * When agentId is provided, only tasks relevant to this agent are considered:
61
+ * - Unclaimed tasks (pending, blocked) — everyone's responsibility
62
+ * - Tasks claimed by this agent — this agent's responsibility
63
+ * Tasks claimed by other agents are filtered out.
44
64
  */
45
- export function checkTodos(todos: TodoItem[]): TodoCheckResult {
65
+ export function checkTodos(
66
+ todos: TodoItem[],
67
+ agentId?: string,
68
+ ): TodoCheckResult {
46
69
  if (!todos || todos.length === 0) {
47
70
  return {
48
71
  hasIncomplete: false,
@@ -53,29 +76,34 @@ export function checkTodos(todos: TodoItem[]): TodoCheckResult {
53
76
  };
54
77
  }
55
78
 
56
- const incomplete = todos.filter(
57
- (t) => t.status !== "completed" && t.status !== "cancelled",
58
- );
79
+ // When scoped to a specific agent, filter out tasks claimed by other agents.
80
+ // Unclaimed tasks (no claimedBy) are considered everyone's responsibility.
81
+ const relevant = agentId
82
+ ? todos.filter((t) => !t.claimedBy || t.claimedBy === agentId)
83
+ : todos;
84
+
85
+ const incomplete = relevant.filter((t) => !TERMINAL_STATUSES.has(t.status));
59
86
 
60
87
  if (incomplete.length === 0) {
61
88
  return {
62
89
  hasIncomplete: false,
63
90
  incompleteCount: 0,
64
- totalCount: todos.length,
91
+ totalCount: relevant.length,
65
92
  incompleteItems: [],
66
93
  message: "",
67
94
  };
68
95
  }
69
96
 
70
- const completedCount = todos.length - incomplete.length;
97
+ const completedCount = relevant.length - incomplete.length;
71
98
  const lines: string[] = [
72
- `**TODO CONTINUATION** — ${incomplete.length} of ${todos.length} tasks incomplete (${completedCount} done)`,
99
+ `**TODO CONTINUATION** — ${incomplete.length} of ${relevant.length} tasks incomplete (${completedCount} done)`,
73
100
  "",
74
101
  "Remaining tasks:",
75
102
  ];
76
103
 
77
104
  for (const item of incomplete) {
78
- const statusIcon = item.status === "in_progress" ? ">" : " ";
105
+ const statusIcon =
106
+ item.status === "in_progress" || item.status === "claimed" ? ">" : " ";
79
107
  lines.push(` [${statusIcon}] ${item.content}`);
80
108
  }
81
109
 
@@ -87,7 +115,7 @@ export function checkTodos(todos: TodoItem[]): TodoCheckResult {
87
115
  return {
88
116
  hasIncomplete: true,
89
117
  incompleteCount: incomplete.length,
90
- totalCount: todos.length,
118
+ totalCount: relevant.length,
91
119
  incompleteItems: incomplete,
92
120
  message: lines.join("\n"),
93
121
  };
@@ -99,6 +127,12 @@ export function checkTodos(todos: TodoItem[]): TodoCheckResult {
99
127
  * Output format from `aide task list`:
100
128
  * [status] id: content
101
129
  * e.g.: [pending] abc123: Implement feature X
130
+ * [claimed] task-def: Deploy service
131
+ *
132
+ * The regex accepts any alphanumeric/underscore status to handle
133
+ * current statuses (pending, claimed, done, blocked) and any future
134
+ * additions without code changes. Unknown statuses are treated as
135
+ * incomplete by checkTodos().
102
136
  */
103
137
  export function parseTodosFromAide(output: string): TodoItem[] {
104
138
  const todos: TodoItem[] = [];
@@ -106,13 +140,14 @@ export function parseTodosFromAide(output: string): TodoItem[] {
106
140
 
107
141
  for (const line of lines) {
108
142
  const match = line.match(
109
- /\[(pending|in_progress|completed|cancelled)\]\s+(\S+):\s+(.+)/,
143
+ /\[(\w+)\]\s+(\S+):\s+(.+?)(?:\s+\(agent:(\S+)\))?$/,
110
144
  );
111
145
  if (match) {
112
146
  todos.push({
113
- status: match[1] as TodoItem["status"],
147
+ status: match[1],
114
148
  id: match[2],
115
149
  content: match[3].trim(),
150
+ claimedBy: match[4] || undefined,
116
151
  });
117
152
  }
118
153
  }
package/src/core/types.ts CHANGED
@@ -15,6 +15,27 @@ export interface AideConfig {
15
15
  /** Auto-export on session end (default: false) */
16
16
  autoExport?: boolean;
17
17
  };
18
+ findings?: {
19
+ /** Complexity analyser settings */
20
+ complexity?: {
21
+ /** Cyclomatic complexity threshold (default: 10) */
22
+ threshold?: number;
23
+ };
24
+ /** Import coupling analyser settings */
25
+ coupling?: {
26
+ /** Fan-out threshold — max outgoing imports (default: 15) */
27
+ fanOut?: number;
28
+ /** Fan-in threshold — max incoming imports (default: 20) */
29
+ fanIn?: number;
30
+ };
31
+ /** Code clone detection settings */
32
+ clones?: {
33
+ /** Sliding window size in tokens (default: 50) */
34
+ windowSize?: number;
35
+ /** Minimum clone size in lines (default: 6) */
36
+ minLines?: number;
37
+ };
38
+ };
18
39
  }
19
40
 
20
41
  export const DEFAULT_CONFIG: AideConfig = {};
@@ -427,7 +427,11 @@ async function handleSessionIdle(
427
427
  // Check persistence: if ralph/autopilot mode is active, re-prompt the session
428
428
  if (state.binary) {
429
429
  try {
430
- const persistResult = checkPersistence(state.binary, state.cwd);
430
+ const persistResult = checkPersistence(
431
+ state.binary,
432
+ state.cwd,
433
+ sessionId,
434
+ );
431
435
  if (persistResult) {
432
436
  const activeMode = getActiveMode(state.binary, state.cwd);
433
437
  debug(