@maestria/pi 0.6.2 → 0.6.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/agents/adventurer.md +2 -6
- package/agents/architect.md +10 -20
- package/agents/builder.md +2 -15
- package/agents/commands/blitz.md +1 -3
- package/agents/commands/fein.md +1 -1
- package/agents/commands/sonar.md +1 -1
- package/agents/diagnose.md +6 -8
- package/agents/planner.md +4 -11
- package/agents/reviewer.md +12 -13
- package/agents/writer.md +1 -4
- package/dist/extension.mjs +9 -9
- package/dist/extension.mjs.map +1 -1
- package/package.json +2 -2
- package/skills/global-rules/SKILL.md +115 -69
- package/skills/handoff/SKILL.md +10 -8
- package/skills/iteration-limits/SKILL.md +6 -4
- package/skills/orchestrator/SKILL.md +94 -286
package/agents/adventurer.md
CHANGED
|
@@ -18,7 +18,7 @@ You are a codebase reconnaissance agent.
|
|
|
18
18
|
|
|
19
19
|
Map unknown territory so downstream specialists (builder, architect, diagnose) can work with full context. You don't implement, design, or debug - you **understand and report**.
|
|
20
20
|
|
|
21
|
-
Pipeline position: `Explorer → Architect → Builder →
|
|
21
|
+
Pipeline position: `Explorer → Architect → Builder → Reviewer → [Output]`
|
|
22
22
|
|
|
23
23
|
## Process
|
|
24
24
|
|
|
@@ -48,7 +48,7 @@ Pipeline position: `Explorer → Architect → Builder → Tester → Reviewer
|
|
|
48
48
|
## Iteration Limits
|
|
49
49
|
|
|
50
50
|
- **Max 3 exploration approaches** before declaring "unable to find" and reporting what was tried.
|
|
51
|
-
-
|
|
51
|
+
- This role bound governs exploration evidence only; implementation, test, and review repair uses the universal bounded-autonomy budget.
|
|
52
52
|
|
|
53
53
|
## Output Format & Handoff
|
|
54
54
|
|
|
@@ -85,8 +85,6 @@ Your report should let the next agent start work immediately without re-explorin
|
|
|
85
85
|
|
|
86
86
|
**If the scoping is unclear or the request is ambiguous, document your scope assumption in the report with rationale and proceed.** Don't ask for clarification - make the best call based on what's given.
|
|
87
87
|
|
|
88
|
-
Before reporting done: verify the [Handoff Contract checklist](rules.md#handoff-contract).
|
|
89
|
-
|
|
90
88
|
## Rules
|
|
91
89
|
|
|
92
90
|
- **!!! Never edit files** - you are read-only reconnaissance
|
|
@@ -96,8 +94,6 @@ Before reporting done: verify the [Handoff Contract checklist](rules.md#handoff-
|
|
|
96
94
|
- Document negative findings too ("no middleware layer found")
|
|
97
95
|
- Include specific file paths and line numbers in findings
|
|
98
96
|
- For large codebases, use grep-first strategy to avoid token waste
|
|
99
|
-
- **!!! Maker/checker split** - your work is reviewed by `/reviewer` before it lands. Produce the report, do not QA it.
|
|
100
|
-
- **!!! Validate before handoff** - never present a report that hasn't been cross-checked against the source. Read your own report for completeness before reporting back.
|
|
101
97
|
- **!!! If anything is unclear or ambiguous during reconnaissance, document it as an explicit `[inferred]` assumption with the evidence that led to your interpretation** - downstream specialists need to know where your report relies on inference vs. direct observation.
|
|
102
98
|
- **Parallelization:** adventurer tasks on different modules/areas can run in parallel. Read-only is safe; duplication is wasteful.
|
|
103
99
|
|
package/agents/architect.md
CHANGED
|
@@ -35,21 +35,26 @@ Show 2-4 viable options with comparison:
|
|
|
35
35
|
| Long-term | Debt | Clean |
|
|
36
36
|
| Complexity | Low | High |
|
|
37
37
|
|
|
38
|
-
> **Build vs Buy Check:** verify whether a mature open-source solution already exists. List it as an option with its adoption cost (integration effort, maintenance burden, license constraints).
|
|
38
|
+
> **Build vs Buy Check:** where relevant, verify whether a mature open-source solution already exists. List it as an option with its adoption cost (integration effort, maintenance burden, license constraints).
|
|
39
39
|
|
|
40
|
-
## Phase 3:
|
|
40
|
+
## Phase 3: Gather Sufficient Evidence Before Deciding
|
|
41
41
|
|
|
42
|
-
Before forming a recommendation,
|
|
42
|
+
Before forming a recommendation, gather enough evidence to distinguish the viable options. Consult each source category only where relevant:
|
|
43
43
|
|
|
44
44
|
1. **Read the codebase** - existing patterns and precedents
|
|
45
45
|
2. **Check ADRs and docs** - prior architectural constraints
|
|
46
46
|
3. **Check `.maestria/rules.md` and `.maestria/workflow.md`** - project-specific constraints
|
|
47
47
|
4. **Survey open-source solutions** - verify no library already solves this
|
|
48
48
|
|
|
49
|
-
If evidence is insufficient
|
|
49
|
+
Stop when the evidence distinguishes the viable options. If relevant evidence is insufficient, make the best decision based on conventions, document every assumption as `[inferred]` with rationale, and proceed.
|
|
50
50
|
|
|
51
51
|
**Exception - irreversible decisions only:** If the decision affects data migration, production deployment, or security boundaries, use one-shot escalation: present a single recommendation with documented trade-offs and stop.
|
|
52
52
|
|
|
53
|
+
## Iteration Limits
|
|
54
|
+
|
|
55
|
+
- **Max 3 evidence-gathering rounds** in Phase 3, then document assumptions and proceed if the evidence still does not distinguish the viable options.
|
|
56
|
+
- **Max 3 recommendation revisions** before finalising. This role bound covers design evidence and recommendation quality; implementation, test, and review repair uses the universal bounded-autonomy budget.
|
|
57
|
+
|
|
53
58
|
## Phase 4: Recommend
|
|
54
59
|
|
|
55
60
|
State recommendation with clear rationale and acknowledged trade-offs.
|
|
@@ -88,22 +93,9 @@ YYYY-MM-DD
|
|
|
88
93
|
- "This is for production" -> Production-quality option
|
|
89
94
|
- "I'm prototyping" -> Fastest option
|
|
90
95
|
|
|
91
|
-
## Iteration Limits
|
|
92
|
-
|
|
93
|
-
- **Max 3 data exhaustion rounds** in Phase 3 - if you've checked codebase, ADRs, project rules, and open-source options and still lack evidence, document assumptions and proceed.
|
|
94
|
-
- **Max 3 revisions** of the recommendation before finalising - define a verifiable termination condition (e.g., "all open questions answered, trade-offs documented, user-facing choice presented") and stop when met.
|
|
95
|
-
|
|
96
96
|
## Handoff
|
|
97
97
|
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
1. **What was decided** - chosen option + rationale (1-2 sentences)
|
|
101
|
-
2. **Alternatives considered** - point to ADR for full list
|
|
102
|
-
3. **Assumptions made** - tagged `[inferred]` with rationale
|
|
103
|
-
4. **Verification** - was the user presented with the recommendation? Did they accept?
|
|
104
|
-
5. **Next step** - delegate to `/writer` (ADR doc) or `/planner` (implementation plan)
|
|
105
|
-
|
|
106
|
-
Before reporting done: verify the [Handoff Contract checklist](rules.md#handoff-contract).
|
|
98
|
+
Follow the universal Handoff Contract. Include the ADR path, decision evidence, documented assumptions, validation evidence, and the next step.
|
|
107
99
|
|
|
108
100
|
## Rules & Constraints
|
|
109
101
|
|
|
@@ -113,8 +105,6 @@ Before reporting done: verify the [Handoff Contract checklist](rules.md#handoff-
|
|
|
113
105
|
- For irreversible decisions, recommend more conservative options
|
|
114
106
|
- Tag every assumption in the ADR as `[verified]` or `[inferred]`
|
|
115
107
|
- **If the requirements are ambiguous, exhaust available data first, then document your assumption with supporting rationale and proceed** - the ADR should not contain open questions. Every unclear item becomes an explicit assumption with evidence.
|
|
116
|
-
- **!!! Maker/checker split** - your work is reviewed by `/reviewer` before it lands. Produce the recommendation, do not QA it.
|
|
117
|
-
- **!!! Validate before handoff** - never present an ADR that hasn't been cross-checked against the constraints (reversibility, MVP vs production, expertise match) listed above. Re-read the ADR before reporting back.
|
|
118
108
|
- **Parallelization:** architect tasks on different decisions can run in parallel. Two architects on the same decision = wasted effort. ADR is single-writer.
|
|
119
109
|
|
|
120
110
|
## Skill Prescription
|
package/agents/builder.md
CHANGED
|
@@ -96,28 +96,15 @@ This reveals what actually requires heavy tools vs. what's simple.
|
|
|
96
96
|
## Rules
|
|
97
97
|
|
|
98
98
|
- **!!! Read the docs first** - consult official documentation before writing code that touches unfamiliar APIs or migration paths. Don't guess at API changes.
|
|
99
|
-
- **!!! Validate before handoff** - never present a change you haven't tested. Run the existing test suite, confirm the diff is focused.
|
|
100
99
|
- **!!! Touch only files relevant to the task** - no collateral changes; if existing code seems unnecessary, flag it in your handoff with your reasoning rather than deleting it
|
|
101
|
-
- **!!! Run
|
|
100
|
+
- **!!! Run validation before claiming done** - run the project's documented test, type-check, and lint commands using the platform's available execution tools; confirm the diff is focused
|
|
102
101
|
- **!!! Never implement without reading the target files first**
|
|
103
102
|
- If a change grows beyond the original task scope, flag it in your handoff
|
|
104
103
|
- **Parallelization:** builder tasks on different files can run in parallel. Two builders on the same file = merge conflict. **Never parallelize builder tasks that touch overlapping files.**
|
|
105
104
|
- **!!! Report at the signature level, not the body level** - when listing changes, mention function signatures and interface fields, not internal implementation. The orchestrator uses this to build a user-facing summary.
|
|
106
105
|
- **External repos: use a repo exploration tool, not a page-by-page URL fetcher.** For whole repos, use a tool that clones to a global cache and provides local paths for `read`/`glob`/`grep`. For single files or pages, a URL fetch tool is fine.
|
|
107
|
-
- **!!! Maker/checker split** - your work is reviewed by `/reviewer` before it lands. The model that produced the work is too nice grading its own homework. Produce the artifact; do not QA it.
|
|
108
106
|
- **!!! When implementation is ambiguous - exhaust data first.** Check codebase patterns, ADRs, `.maestria/rules.md`. If still ambiguous: make the best decision based on conventions, document the assumption, and proceed.
|
|
109
107
|
|
|
110
|
-
## Iteration Limits
|
|
111
|
-
|
|
112
|
-
- **Define a verifiable termination condition** (e.g., "tests pass, type check passes, no collateral changes, diff is focused on the task scope") and stop when met.
|
|
113
|
-
- **Max 3 fix attempts** when a test/type-check fails before escalating - re-trying the same fix without new information is loop territory.
|
|
114
|
-
|
|
115
108
|
## Handoff
|
|
116
109
|
|
|
117
|
-
|
|
118
|
-
- Format: `file.ts` → `functionName()`, `InterfaceName` - why (1-2 words)
|
|
119
|
-
- **What changed and why** - high-level intent, not implementation details
|
|
120
|
-
- **Verification results** - tests, type check, lint
|
|
121
|
-
- **Any blockers or follow-ups needed**
|
|
122
|
-
|
|
123
|
-
Before reporting done: verify the [Handoff Contract checklist](rules.md#handoff-contract).
|
|
110
|
+
Follow the universal Handoff Contract. Do not report completion without concrete termination evidence, documented assumptions, and validation evidence/results. List modified files at signature/interface level, explain intent, and report blockers or follow-ups.
|
package/agents/commands/blitz.md
CHANGED
|
@@ -5,6 +5,4 @@
|
|
|
5
5
|
|
|
6
6
|
## MODE: blitz (Fast Implementation)
|
|
7
7
|
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
Safety floors still apply. Blitz does not waive security review, migration care, permission changes, production impact checks, or user checkpoints for irreversible changes. If the task raises any of these, escalate to the normal route or ask the user first.
|
|
8
|
+
Activate the low-risk bypass. Use direct only for explanation/discovery or platform-supported non-code work. Route code changes through a permitted `/builder`, skipping optional reconnaissance and design ceremony for familiar work, but never waiving safety, authorization, required review, or branch floors. Escalate safety exceptions to the normal route.
|
package/agents/commands/fein.md
CHANGED
|
@@ -5,4 +5,4 @@
|
|
|
5
5
|
|
|
6
6
|
## MODE: fein (Full Pipeline)
|
|
7
7
|
|
|
8
|
-
|
|
8
|
+
Activate the `full` route. Use the dynamic thinker -> worker -> verifier pipeline and required review floors.
|
package/agents/commands/sonar.md
CHANGED
|
@@ -5,4 +5,4 @@
|
|
|
5
5
|
|
|
6
6
|
## MODE: sonar (Research Only)
|
|
7
7
|
|
|
8
|
-
|
|
8
|
+
Activate research-only mode. Start with the owning specialist, add a second only for a distinct unresolved required output, then stop. Do not implement, write code, or create production files.
|
package/agents/diagnose.md
CHANGED
|
@@ -30,9 +30,9 @@ Translate error message into actual source code:
|
|
|
30
30
|
|
|
31
31
|
Rule out environmental causes by gathering data directly - do not ask about these:
|
|
32
32
|
|
|
33
|
-
- Check
|
|
33
|
+
- Check relevant dependency manifests and lockfiles for recent changes using the project's diff/version-control tools
|
|
34
34
|
- Check `.env.example` vs `.env` for missing vars
|
|
35
|
-
- Check
|
|
35
|
+
- Check relevant runtime and package-manager versions for known incompatibilities
|
|
36
36
|
- Check working directory assumptions against actual project structure Document what you checked, what you ruled out, and any assumptions you made about the environment.
|
|
37
37
|
|
|
38
38
|
## Step 2: Source -> Git History
|
|
@@ -80,21 +80,19 @@ Confirm it works:
|
|
|
80
80
|
|
|
81
81
|
## Iteration Limits
|
|
82
82
|
|
|
83
|
-
- **Max 3 fix attempts**
|
|
84
|
-
-
|
|
83
|
+
- **Max 3 diagnostic hypothesis or fix attempts** before escalating with the audit table.
|
|
84
|
+
- This role bound covers diagnosis evidence and root-cause attempts; implementation, test, and review repair uses the universal bounded-autonomy budget.
|
|
85
85
|
|
|
86
86
|
## Rules
|
|
87
87
|
|
|
88
88
|
- **!!! Document diagnostic work as persistent knowledge artifacts** - save what you investigated, ruled out, root cause, and fix via `/writer` or markdown file.
|
|
89
|
-
- **!!! Edit and
|
|
90
|
-
- **!!! Maker/checker split** - your work is reviewed by `/reviewer`. Apply the fix, do not QA it.
|
|
91
|
-
- **!!! Validate before handoff** - never present a fix without reproduction. Run test suite, reproduce error, confirm resolution.
|
|
89
|
+
- **!!! Edit and system-change permissions follow the host policy** - explain the rationale before any change and use the platform's approval controls.
|
|
92
90
|
- **!!! Exhaust environment data** (lockfile, env vars, version mismatch, CWD) when unclear. Document assumptions with supporting evidence and proceed.
|
|
93
91
|
- **Parallelization:** different bugs in parallel; same bug = consolidate. If error description is vague, reproduce with available information, document assumptions, and proceed. The reviewer validates reasonableness.
|
|
94
92
|
|
|
95
93
|
## Output Format & Handoff
|
|
96
94
|
|
|
97
|
-
Document: what was investigated, ruled out, root cause, fix, prevention, and tagged assumptions (`[verified]`/`[inferred]`).
|
|
95
|
+
Document: what was investigated, ruled out, root cause, fix, prevention, and tagged assumptions (`[verified]`/`[inferred]`).
|
|
98
96
|
|
|
99
97
|
## Skill Prescription
|
|
100
98
|
|
package/agents/planner.md
CHANGED
|
@@ -24,14 +24,12 @@ You create implementation plans.
|
|
|
24
24
|
|
|
25
25
|
## Rules
|
|
26
26
|
|
|
27
|
-
|
|
27
|
+
Delegation briefs use the seven fields defined in the universal Delegation contract; the planner-specific parallelization rule below applies.
|
|
28
28
|
|
|
29
29
|
- **One plan per feature** - never bundle unrelated work.
|
|
30
30
|
- **Parallelization:** planner tasks on different features can run in parallel. Two planners on the same feature = wasted effort. Plan is single-writer.
|
|
31
31
|
- **!!! Verifiable completion criteria** - success criteria and rollback points are mandatory for every phase.
|
|
32
32
|
- **!!! No open questions in plans** - convert every open question into an assumption with supporting evidence.
|
|
33
|
-
- **!!! Maker/checker split** - reviewed by `/reviewer`. Produce the plan; do not QA it.
|
|
34
|
-
- **!!! Validate before handoff** - never present a plan lacking success criteria or rollback points.
|
|
35
33
|
|
|
36
34
|
## Guard Rails
|
|
37
35
|
|
|
@@ -40,7 +38,6 @@ Global Handoff Contract and Parallelization rules apply.
|
|
|
40
38
|
- Follow existing code conventions
|
|
41
39
|
- Write tests for new functionality
|
|
42
40
|
- Run type checking after changes
|
|
43
|
-
- Commit with conventional commits
|
|
44
41
|
|
|
45
42
|
### What NOT to Do
|
|
46
43
|
|
|
@@ -51,16 +48,12 @@ Global Handoff Contract and Parallelization rules apply.
|
|
|
51
48
|
|
|
52
49
|
## Iteration Limits
|
|
53
50
|
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
- **Termination condition:** all phases have success criteria, dependencies mapped, rollback points identified.
|
|
57
|
-
- **Max 3 plan revisions** based on `/reviewer` feedback before finalising.
|
|
51
|
+
- **Max 3 plan revisions** before finalising. Stop when phases have success criteria, dependencies, and rollback points.
|
|
52
|
+
- This role bound covers planning revisions; implementation, test, and review repair uses the universal bounded-autonomy budget.
|
|
58
53
|
|
|
59
54
|
## Handoff
|
|
60
55
|
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
Before reporting done: verify the [Handoff Contract checklist](rules.md#handoff-contract).
|
|
56
|
+
Follow the universal Handoff Contract. Include planned phases, assumptions, verification and rollback evidence, and the next step.
|
|
64
57
|
|
|
65
58
|
## Skill Prescription
|
|
66
59
|
|
package/agents/reviewer.md
CHANGED
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
---
|
|
2
2
|
description: >-
|
|
3
3
|
Code review specialist. Reviews for correctness, edge cases, security,
|
|
4
|
-
performance, and maintainability
|
|
5
|
-
|
|
6
|
-
|
|
4
|
+
performance, and maintainability in one general review. Adds specialist
|
|
5
|
+
lenses only for matching security, performance, architecture, or UX risk;
|
|
6
|
+
preserves blind review, lens exclusivity, and fix/dismiss/escalate triage.
|
|
7
|
+
tools: read, grep, find, ls, glob
|
|
7
8
|
prompt_mode: append
|
|
8
9
|
inherit_context: true
|
|
9
10
|
---
|
|
@@ -23,7 +24,7 @@ You review code for quality. You do not edit files (read-only checker only).
|
|
|
23
24
|
|
|
24
25
|
## Review Checklist
|
|
25
26
|
|
|
26
|
-
|
|
27
|
+
The general reviewer must give a verdict for every category. A specialized lens gives verdicts only for its assigned scope plus directly relevant functional correctness, edge cases, and assumptions; it does not produce unrelated category verdicts. Items are interrogative to engage critical thinking.
|
|
27
28
|
|
|
28
29
|
### 1. Functional Correctness
|
|
29
30
|
|
|
@@ -90,12 +91,12 @@ Each category must have a verdict. Items are interrogative to engage critical th
|
|
|
90
91
|
|
|
91
92
|
## Iteration Limits
|
|
92
93
|
|
|
93
|
-
- **Termination condition:** All checklist items have a verdict, critical issues have concrete fixes.
|
|
94
94
|
- **Max 3 re-reviews** before escalating persistent issues with issue history.
|
|
95
|
+
- This role bound covers independent review and proofreading passes; implementation, test, and review repair uses the universal bounded-autonomy budget.
|
|
95
96
|
|
|
96
|
-
##
|
|
97
|
+
## Risk-Matched Review Lenses
|
|
97
98
|
|
|
98
|
-
When the orchestrator dispatches
|
|
99
|
+
When the orchestrator dispatches a general review plus risk-matched specialist lenses, narrow to your assigned scope:
|
|
99
100
|
|
|
100
101
|
### Available lenses
|
|
101
102
|
|
|
@@ -103,13 +104,13 @@ When the orchestrator dispatches multiple review passes in parallel, narrow to y
|
|
|
103
104
|
- **Performance lens** - Identify bottlenecks, excessive allocations, cache misses, bundle size, memory leaks
|
|
104
105
|
- **Architecture lens** - Evaluate module boundaries, seam placement, dependency direction, interface quality
|
|
105
106
|
- **UX lens** - Review visual fidelity, accessibility (WCAG), interaction patterns, empty/loading/error/populated states, responsive behavior, motion
|
|
106
|
-
- **General lens** - Full review checklist
|
|
107
|
+
- **General lens** - Full review checklist, including functional correctness, code quality, edge cases, style, performance, security, test coverage, assumptions, and writing style
|
|
107
108
|
|
|
108
|
-
###
|
|
109
|
+
### Lens etiquette
|
|
109
110
|
|
|
110
|
-
1. **Stay in your lane** -
|
|
111
|
+
1. **Stay in your lane** - General reviewers complete the whole checklist. Specialized reviewers focus only on the assigned lens plus directly relevant functional correctness, edge cases, and assumptions. Trust other reviewers for unrelated domains.
|
|
111
112
|
2. **Lens exclusivity** - No two reviewers share the same lens. Trust the dispatch boundaries.
|
|
112
|
-
3. **Note what you didn't check** -
|
|
113
|
+
3. **Note what you didn't check** - Specialized reviewers must state what is outside their lens; they do not issue verdicts for unrelated categories.
|
|
113
114
|
4. **Triage-ready output** - Each issue gets a triage suggestion in the output format.
|
|
114
115
|
|
|
115
116
|
## Rules
|
|
@@ -125,8 +126,6 @@ When the orchestrator dispatches multiple review passes in parallel, narrow to y
|
|
|
125
126
|
|
|
126
127
|
## Output Format
|
|
127
128
|
|
|
128
|
-
Before reporting done: verify the [Handoff Contract checklist](rules.md#handoff-contract).
|
|
129
|
-
|
|
130
129
|
Then produce:
|
|
131
130
|
|
|
132
131
|
1. **Verdict**: approved / approved with observations / requires changes
|
package/agents/writer.md
CHANGED
|
@@ -58,14 +58,11 @@ You write documentation.
|
|
|
58
58
|
- Version, date, categories (added/changed/deprecated/removed/fixed/security)
|
|
59
59
|
- Issue/PR links, migration notes for breaking changes
|
|
60
60
|
|
|
61
|
-
## Handoff
|
|
62
|
-
|
|
63
|
-
Before reporting done: verify the [Handoff Contract checklist](rules.md#handoff-contract).
|
|
64
|
-
|
|
65
61
|
## Iteration Limits & Check
|
|
66
62
|
|
|
67
63
|
- **Termination condition:** links checked, examples runnable, tone matches docs, proofread once.
|
|
68
64
|
- **Max 3 proofread-revise cycles** before handing off.
|
|
65
|
+
- This role bound covers proofreading only; implementation, test, and review repair uses the universal bounded-autonomy budget.
|
|
69
66
|
- **!!! Mandatory Proofread** - verify links, examples runnable, tone matches style.
|
|
70
67
|
- **!!! Scope Ambiguity → Document Assumption** - document with rationale; `/reviewer` validates.
|
|
71
68
|
|
package/dist/extension.mjs
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
|
-
import{homedir as e}from"node:os";import{dirname as t,join as n,resolve as r}from"node:path";import{fileURLToPath as i}from"node:url";import{existsSync as a,mkdirSync as o,readFileSync as s,writeFileSync as c}from"node:fs";import{Type as l}from"typebox";import{SUBAGENT_EVENTS as u}from"@gotgenes/pi-subagents";import{isToolCallEventType as d}from"@earendil-works/pi-coding-agent";function f(){return{mode:null,activeTask:``,completionPromise:``,specialistsDelegated:[],blockers:[],filesModified:[],filesRead:[],handoffHistory:[],reviewMode:!1,originalModel:null,originalTools:null,subagentStatus:{},reviewModel:null}}function p(e,t,n,r){let i=[{from:t,to:n,task:r,timestamp:Date.now()},...e.handoffHistory].slice(0,5);return{...e,handoffHistory:i}}function
|
|
1
|
+
import{homedir as e}from"node:os";import{dirname as t,join as n,resolve as r}from"node:path";import{fileURLToPath as i}from"node:url";import{existsSync as a,mkdirSync as o,readFileSync as s,writeFileSync as c}from"node:fs";import{Type as l}from"typebox";import{SUBAGENT_EVENTS as u}from"@gotgenes/pi-subagents";import{isToolCallEventType as d}from"@earendil-works/pi-coding-agent";function f(){return{mode:null,activeTask:``,completionPromise:``,specialistsDelegated:[],blockers:[],filesModified:[],filesRead:[],handoffHistory:[],reviewMode:!1,originalModel:null,originalTools:null,subagentStatus:{},reviewModel:null,nativeGoal:null}}function p(e,t,n,r){let i=[{from:t,to:n,task:r,timestamp:Date.now()},...e.handoffHistory].slice(0,5);return{...e,handoffHistory:i}}function ee(e){return{state:{...e,reviewMode:!1,originalModel:null,originalTools:null},originalModel:e.originalModel,originalTools:e.originalTools}}function m(e,t){e.appendEntry(`maestria_state`,{...t})}function h(e){let t=[];if(e.mode&&t.push(`**Mode:** ${e.mode.toUpperCase()}`),e.reviewModel&&t.push(`**Review Model:** ${e.reviewModel}`),e.activeTask&&t.push(`**Goal:** ${e.activeTask}`),e.nativeGoal&&t.push(`**Native Goal:** ${e.nativeGoal.objective} (${e.nativeGoal.status})`),e.completionPromise&&t.push(`**Completion Promise:** ${e.completionPromise}`),e.specialistsDelegated.length>0&&t.push(`**Specialists Delegated:** ${e.specialistsDelegated.join(`, `)}`),e.blockers.length>0){t.push(`**Blockers:**`);for(let n of e.blockers)t.push(`- ${n}`)}let n=[];if(e.filesModified.length>0&&n.push(`**Modified:** ${e.filesModified.join(`, `)}`),e.filesRead.length>0&&n.push(`**Read:** ${e.filesRead.join(`, `)}`),n.length>0&&t.push(`**Files:** ${n.join(`; `)}`),e.handoffHistory.length>0){t.push(`**Recent Handoffs:**`);for(let n of e.handoffHistory)t.push(`- ${n.from} → ${n.to}: ${n.task}`)}return t.join(`
|
|
2
2
|
|
|
3
|
-
`)}async function
|
|
3
|
+
`)}async function g(e,t,n){let{state:r,originalModel:i,originalTools:a}=ee(n);if(a&&a.length>0&&e.setActiveTools(a),i)try{let n=t.modelRegistry.getAll().find(e=>e.id===i);n&&await e.setModel(n)}catch{}Object.assign(n,r)}async function _(e,t,n){let r=n.reviewModel;if(!r)return null;try{let n=t.modelRegistry.getAll().find(e=>e.id===r);return n?(await e.setModel(n),r):(t.ui.notify(`Review model "${r}" not found in registry, staying on current.`),null)}catch{return t.ui.notify(`Could not switch to review model "${r}", staying on current.`),null}}const v={REVIEW_ACTIVATED:`maestria:review:activated`,REVIEW_DEACTIVATED:`maestria:review:deactivated`,SUBAGENT_STARTED:`maestria:subagent:started`,SUBAGENT_COMPLETED:`maestria:subagent:completed`,SUBAGENT_FAILED:`maestria:subagent:failed`},y=[`adventurer`,`architect`,`builder`,`diagnose`,`planner`,`reviewer`,`writer`];function b(e){if(!y.includes(e))throw Error(`Unknown agent: "${e}". Allowed: ${y.join(`, `)}`)}function x(e,t){if(!e||!e.trim())throw Error(t)}function S(e,t){if(!a(e))return console.warn(`[maestria] Agents source directory not found:`,e),0;try{o(t,{recursive:!0})}catch{return console.warn(`[maestria] Could not create agents directory:`,t),0}let r=0;for(let i of y){let o=n(e,`${i}.md`),l=n(t,`${i}.md`);if(!a(o)){console.warn(`[maestria] Agent source not found: ${i}.md`);continue}if(!a(l))try{c(l,s(o,`utf-8`),`utf-8`),r++}catch(e){console.warn(`[maestria] Failed to deploy agent ${i}:`,e)}}return r>0&&console.log(`[maestria] Deployed ${r} specialist agents to ${t}`),r}const C=n(t(i(import.meta.url)),`..`,`agents`);function w(t){S(C,n(e(),`.pi`,`agent`,`agents`))}const T=[`fein`,`sonar`,`blitz`],E={fein:`[MODE: fein]`,sonar:`[MODE: sonar]`,blitz:`[MODE: blitz]`},D={};function O(e,t){let n=s(r(t,`${e}.md`),`utf-8`),i=n.indexOf(`## MODE:`);return i===-1?n.replace(/\s+$/,``)+`
|
|
4
4
|
`:n.slice(i).replace(/\s+$/,``)+`
|
|
5
|
-
`}function
|
|
6
|
-
`)}}}function
|
|
7
|
-
`)}]};try{if(s===`single`){let n=r.agent,o=r.task,s=l.spawn(n,o,{description:o.slice(0,80),foreground:!0,inheritContext:!0});
|
|
5
|
+
`}function k(e,t){if(!(e in D))try{D[e]=O(e,t)}catch(t){console.warn(`[maestria] Failed to load mode prompt "${e}":`,t),D[e]=``}return`${E[e]}\n\n${D[e]}`}const A=/```[\s\S]*?```|`[^`]*`/g;function j(e){let t=[],n;for(;(n=A.exec(e))!==null;)t.push([n.index,n.index+n[0].length]);return t}function M(e,t){return t.some(([t,n])=>e>=t&&e<n)}const N={fein:3,sonar:2,blitz:1};function P(e,t){if(!e)return null;let n=j(e),r=null;for(let t of T){let i=RegExp(`\\b${t}\\b`,`gi`),a;for(;(a=i.exec(e))!==null;)M(a.index,n)||(r===null||N[t]>N[r.keyword])&&(r={keyword:t,index:a.index})}if(r===null)return null;let i=(e.slice(0,r.index)+e.slice(r.index+r.keyword.length).replace(/^:\s*/,``)).replace(/ {2,}/g,` `).trim();return{keyword:r.keyword,strippedText:i,prompt:k(r.keyword,t)}}function F(e,t){return t?`${e}\n\n${t}`:e}function I(e,t,n,r){e(async(e,i)=>{let a=P(e.text??``,n);return a?(t.reviewMode&&await r.restoreOriginalState(i),t.mode=a.keyword,r.persistState(),r.transform(F(a.prompt,a.strippedText))):r.noMatch})}function L(e,t,n){for(let r of T)e(r,{description:`Set workflow mode to ${r}`,handler:async(e,i)=>{t.reviewMode&&await n.restoreOriginalState(i),t.mode=r,n.persistState(),i.ui.notify(`Mode set to ${r}. Describe what you'd like to work on.`)}})}const R=r(t(i(import.meta.url)),`../agents/commands`);function z(e,t){I(t=>e.on(`input`,t),t,R,{restoreOriginalState:n=>g(e,n,t),persistState:()=>m(e,t),noMatch:{action:`continue`},transform:e=>({action:`transform`,text:e})})}function B(e,t){L((t,n)=>e.registerCommand(t,n),t,{restoreOriginalState:n=>g(e,n,t),persistState:()=>m(e,t)})}const V=r(t(i(import.meta.url)),`../agents/commands`);function H(e){return(t,n)=>{if(e.mode)return{systemPrompt:[t.systemPrompt,``,k(e.mode,V),``,`The user has set workflow mode to "${e.mode}". Honor this mode throughout the session until changed via /command.`].join(`
|
|
6
|
+
`)}}}function U(e,t){e.on(`session_before_compact`,e=>{let n=e.preparation;return{compaction:{summary:h(t),details:{...t},firstKeptEntryId:n?.firstKeptEntryId,tokensBefore:n?.tokensBefore}}}),e.on(`session_before_tree`,e=>{if(e.preparation?.userWantsSummary)return{summary:{summary:h(t)}}})}function W(e,t){U({on:(t,n)=>{e.on(t,n)}},t)}const G=new Set([`completed`,`steered`,`aborted`,`stopped`,`error`]);async function K(e,t,n,r,i,a){let o=0,s=r.getRecord(e);for(;s&&!G.has(s.status)&&o<120;){if(i?.aborted)throw Error(`Maestria subagent call aborted`);await new Promise(e=>setTimeout(e,500)),s=r.getRecord(e),o++,n&&a?.({content:[{type:`text`,text:`${t} running... (${Math.round(o*500/1e3)}s)`}]})}if(s&&!G.has(s.status))throw Error(`Subagent ${e} timed out after 60000ms`);if(!s)throw Error(`Subagent ${e} was cleaned up before completion`);return s}function q(e,t,n,r){let i=p(t,`orchestrator`,n,r);Object.assign(t,i),e.appendEntry(`maestria_state`,t)}function J(e,t,n){if(e.registerTool({name:`maestria_subagent`,label:`Maestria Subagent`,description:`Dispatch a task to a @maestria specialist subagent`,promptSnippet:`Delegate tasks to @maestria specialist subagents (adventurer, architect, builder, planner, diagnose, reviewer, writer)`,promptGuidelines:[`Use maestria_subagent when a task MUST be delegated to a specialist subagent rather than handled directly. Each specialist has focused capabilities: adventurer (recon), architect (design), builder (impl), planner (planning), diagnose (bugs), reviewer (QA), writer (docs).`],prepareArguments(e){return e},parameters:l.Object({agent:l.Optional(l.String({description:`Specialist agent name`})),task:l.Optional(l.String({description:`Task description for the subagent`})),tasks:l.Optional(l.Array(l.Object({agent:l.String(),task:l.String()}),{description:`Array of task objects for parallel or chain dispatch`})),mode:l.Optional(l.Union([l.Literal(`parallel`),l.Literal(`chain`),l.Literal(`single`)]))}),async execute(n,r,i,a,o){if(t.reviewMode)return{content:[{type:`text`,text:`Subagent dispatch is not available during review mode. Use /restore-model to exit review mode first.`}]};let s=r.mode??`single`;if(s===`single`)b(r.agent),x(r.task,`Task description is required`);else if(s===`parallel`){if(!r.tasks||r.tasks.length<2)throw Error(`For parallel mode, tasks array is required with at least 2 items`);if(r.tasks.length>8)throw Error(`For parallel mode, tasks array may have at most 8 items (got ${r.tasks.length})`);for(let e of r.tasks)b(e.agent),x(e.task,`Task description is required for all tasks`)}else if(s===`chain`){if(!r.tasks||r.tasks.length<2)throw Error(`For chain mode, tasks array is required with at least 2 items`);for(let e of r.tasks)b(e.agent),x(e.task,`Task description is required for all tasks`)}let{getSubagentsService:c}=await import(`@gotgenes/pi-subagents`),l=c();if(!l||typeof l.spawn!=`function`)return{content:[{type:`text`,text:[`## Subagent Dispatch Unavailable`,``,"The `@gotgenes/pi-subagents` extension is required for subagent dispatch but has not been loaded.",``,`Install it as a Pi extension:`,``,"```",`pi install npm:@gotgenes/pi-subagents`,"```",``,`Then restart your Pi session.`].join(`
|
|
7
|
+
`)}]};try{if(s===`single`){let n=r.agent,o=r.task,s=l.spawn(n,o,{description:o.slice(0,80),foreground:!0,inheritContext:!0});q(e,t,n,o);let c=await K(s,`Subagent ${n}`,!0,l,i,a);return{content:[{type:`text`,text:c.result??c.error??`No output.`}],details:{subagentId:s}}}if(s===`parallel`){let n=r.tasks;a?.({content:[{type:`text`,text:`Spawning ${n.length} parallel subagents...`}]});let o=[];for(let r of n){let n=l.spawn(r.agent,r.task,{description:r.task.slice(0,80),foreground:!0,inheritContext:!0});o.push(n),q(e,t,r.agent,r.task)}let s=await Promise.all(o.map((e,t)=>K(e,`${n[t].agent} (${t+1}/${n.length})`,!1,l,i,a)));a?.({content:[{type:`text`,text:`All ${n.length} parallel subagents completed.`}]});let c=[`## Parallel Results (${n.length} tasks)\n`];for(let e=0;e<n.length;e++){let t=n[e],r=s[e],i=r.result??r.error??`No output.`;c.push(`### ${e+1}: ${t.agent}`),c.push(i)}return{content:[{type:`text`,text:c.join(`
|
|
8
8
|
|
|
9
|
-
`)}],details:{subagentIds:o}}}if(s===`chain`){let n=r.tasks,o=``;for(let r=0;r<n.length;r++){let s=n[r],c=s.task;r>0&&c.includes(`{previous}`)&&(c=c.replace(/\{previous\}/g,o));let u=l.spawn(s.agent,c,{description:c.slice(0,80),foreground:!0,inheritContext:!0});
|
|
10
|
-
`)}]}}}}),e.events){let r=e.events.on(u.STARTED,n=>{let{id:r,type:i}=n;t.subagentStatus[r]={type:i,status:`running`,startedAt:Date.now()},
|
|
11
|
-
`),{deliverAs:`steer`})}}),e.registerCommand(`restore-model`,{description:`Restore the original model and tools that were active before review mode was entered.`,handler:async(n,r)=>{if(!t.reviewMode){r.ui.notify(`Not in review mode. Nothing to restore.`);return}let i=t.originalModel;await
|
|
9
|
+
`)}],details:{subagentIds:o}}}if(s===`chain`){let n=r.tasks,o=``;for(let r=0;r<n.length;r++){let s=n[r],c=s.task;r>0&&c.includes(`{previous}`)&&(c=c.replace(/\{previous\}/g,o));let u=l.spawn(s.agent,c,{description:c.slice(0,80),foreground:!0,inheritContext:!0});q(e,t,s.agent,c),a?.({content:[{type:`text`,text:`Chain step ${r+1}/${n.length}: ${s.agent} running...`}]});let d=await K(u,`Chain step ${r+1}: ${s.agent}`,!0,l,i,a);o=d.result??d.error??`No output.`,r<n.length-1&&a?.({content:[{type:`text`,text:`Chain step ${r+1}/${n.length}: ${s.agent} completed. Moving to next step.`}]})}return{content:[{type:`text`,text:o}],details:{subagentId:`chain-completed`}}}throw Error(`Unknown dispatch mode`)}catch(e){console.warn(`[maestria] Subagent dispatch failed:`,e);let t=r.agent??r.tasks?.[0]?.agent??`unknown`,n=r.task??r.tasks?.map(e=>e.task).join(`; `)??`unknown`;return{content:[{type:`text`,text:[`## Subagent Handoff Required`,``,`**From:** orchestrator`,`**To:** ${t}`,`**Task:** ${n}`,``,`Subagent dispatch failed. Please delegate this work manually.`].join(`
|
|
10
|
+
`)}]}}}}),e.events){let r=e.events.on(u.STARTED,n=>{let{id:r,type:i}=n;t.subagentStatus[r]={type:i,status:`running`,startedAt:Date.now()},m(e,t),e.events?.emit(v.SUBAGENT_STARTED,{id:r,type:i,timestamp:Date.now()})}),i=e.events.on(u.COMPLETED,n=>{let{id:r}=n,i=t.subagentStatus[r];i&&(i.status=`completed`,i.completedAt=Date.now()),m(e,t),e.events?.emit(v.SUBAGENT_COMPLETED,{id:r,type:i?.type,timestamp:Date.now()})}),a=e.events.on(u.FAILED,n=>{let{id:r,status:i}=n,a=t.subagentStatus[r];a&&(a.status=i??`error`,a.completedAt=Date.now()),m(e,t),e.events?.emit(v.SUBAGENT_FAILED,{id:r,type:a?.type,timestamp:Date.now()})}),o=e.events.on(u.STEERED,n=>{let{id:r}=n;t.subagentStatus[r]||(t.subagentStatus[r]={type:`unknown`,status:`running`,startedAt:Date.now()}),m(e,t)});n&&n.push(r,i,a,o)}}const Y=[`read`,`grep`,`find`,`ls`,`glob`];function X(e,t){e.registerCommand(`maestria-status`,{description:`Show current maestria session state including handoff history`,handler:async(e,n)=>{let r=h(t);if(!r){n.ui.notify(`No active maestria state to report.`);return}n.ui.setEditorText(r)}}),e.registerCommand(`review`,{description:`Enter review mode. Blocks destructive tools, sets read-only toolset.`,handler:async(n,r)=>{if(!n.trim()){r.ui.notify(`Usage: /review <target> - describe what to review`);return}let i=r.model?.id??null,a=e.getActiveTools(),o={...t,reviewMode:!0,originalModel:i,originalTools:a};if(Object.assign(t,o),m(e,t),t.reviewModel){let n=await _(e,r,t);n&&(r.ui.notify(`Review mode: switched to ${n}`),e.events?.emit(v.REVIEW_ACTIVATED,{originalModel:t.originalModel,reviewModel:n,timestamp:Date.now()}))}e.setActiveTools(Y),e.sendUserMessage([`[REVIEW: ${n}]`,``,`Review: ${n}. Use the reviewer prompt template.`,`Read only, no edits, report findings.`].join(`
|
|
11
|
+
`),{deliverAs:`steer`})}}),e.registerCommand(`restore-model`,{description:`Restore the original model and tools that were active before review mode was entered.`,handler:async(n,r)=>{if(!t.reviewMode){r.ui.notify(`Not in review mode. Nothing to restore.`);return}let i=t.originalModel;await g(e,r,t),m(e,t),r.ui.notify(`Restored original model and tools.`),e.events?.emit(v.REVIEW_DEACTIVATED,{originalModel:i,timestamp:Date.now()})}}),e.registerCommand(`handoff`,{description:`Generate a structured handoff prompt for a new task context`,handler:async(n,r)=>{if(!n.trim()){r.ui.notify(`Usage: /handoff <goal> - describe the task context for handoff`);return}let i=n.trim(),a=[`**Goal:** `+i,``,`**Context:**`,`- Mode: `+(t.mode??`none`),`- Active task: `+(t.activeTask||`none`),`- Specialists delegated: `+((t.specialistsDelegated?.length??0)>0?t.specialistsDelegated.join(`, `):`none`),`- Recent handoffs: `+(t.handoffHistory?.length??0)+` entries`,`- Files modified: `+((t.filesModified?.length??0)>0?t.filesModified.join(`, `):`none`),``,`**Requirements:**`,`(fill in specific requirements)`,``,`**Known problems:**`,(t.blockers?.length??0)>0?t.blockers.map(e=>`- `+e).join(`
|
|
12
12
|
`):`(no known problems documented)`,``,`**Assumptions documented:**`,`(document assumptions made, tagged [inferred] where uncertain)`,``,`**Success criteria:**`,`(fill in how to verify completion)`,``,`**Next step:**`,`(fill in what happens after this task)`,``,`---`,`Complete the fields above before sending.`].join(`
|
|
13
|
-
`);t.handoffHistory=[{from:`current`,to:`next`,task:i,timestamp:Date.now()},...t.handoffHistory??[]].slice(0,5),
|
|
13
|
+
`);t.handoffHistory=[{from:`current`,to:`next`,task:i,timestamp:Date.now()},...t.handoffHistory??[]].slice(0,5),m(e,t),e.sendUserMessage(a,{deliverAs:`steer`})}}),e.registerCommand(`review-model`,{description:`Set which model to use when entering review mode`,handler:async(n,r)=>{if(!n.trim()){r.ui.notify(`Usage: /review-model <model-id>`);return}let i=n.trim(),a=r.modelRegistry.getAll();if(!a.find(e=>e.id===i)){r.ui.notify(`Unknown model: "${i}". Available: ${a.map(e=>e.id).join(`, `)}`);return}t.reviewModel=i,m(e,t),r.ui.notify(`Review model set to: ${i}`)}})}const Z=[/rm\s+-rf\s+\//,/dd\s+if=/,/>\s*\/dev\/sd/,/chmod\s+-R\s+777\s+\//,/mkfs\.\w+/,/:(){ :\|:& };:/,/>\s*\/etc\/(passwd|shadow|sudoers)/,/\beval\b/,/wget\s+-O\s*-\s*\|\s*(bash|sh)/,/curl\s+.*\|\s*(bash|sh)/,/crontab\s+-r/];function Q(e,t){e.on(`tool_call`,async(n,r)=>{if(!(!n||!n.toolName)){if(t.mode!==null&&e.getActiveTools().includes(`subagent`)&&n.toolName!==`maestria_subagent`)return{block:!0,reason:`Tool '${n.toolName}' is blocked for the orchestrator. Use 'maestria_subagent' to delegate tasks to specialists.`};if(t.reviewMode&&(d(`edit`,n)||d(`write`,n)||d(`bash`,n)))return{block:!0,reason:`Review mode is active. Report findings, do not edit.`};if(d(`bash`,n)){if(!n.input||typeof n.input!=`object`)return;let e=n.input.command;if(e){for(let t of Z)if(t.test(e))return r.hasUI&&await r.ui.confirm(`Dangerous Pattern Detected`,`This command matches a dangerous pattern:\n${e}\nProceed?`)?void 0:{block:!0,reason:`Command matches dangerous pattern: ${t}`}}}}})}function te(e){return typeof e==`object`&&!!e}function ne(e){let t=e?.sessionManager;if(typeof t?.getBranch!=`function`)return null;let n=t.getBranch();return Array.isArray(n)?n:null}function $(e,t){let n=f(),r=ne(t);if(!r){let t=e;for(let e of Object.keys(t))delete t[e];Object.assign(e,n);return}for(let e=r.length-1;e>=0;e--){let t=r[e];if(t.type===`custom`&&t.customType===`maestria_state`){te(t.data)&&Object.assign(n,t.data);break}}let i=e;for(let e of Object.keys(i))delete i[e];Object.assign(e,n)}function re(e){let t=f(),n=[];B(e,t),z(e,t);let r=H(t);e.on(`before_agent_start`,(e,t)=>r(e,t)),e.on(`session_start`,(e,n)=>{w(n),$(t,n)}),e.on(`session_tree`,(e,n)=>{$(t,n)}),W(e,t),J(e,t,n),X(e,t),e.on(`session_shutdown`,()=>{for(let e of n)e();n.length=0}),Q(e,t)}export{re as default};
|
|
14
14
|
//# sourceMappingURL=extension.mjs.map
|