@maestria/pi 0.6.3 → 0.6.5

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.
@@ -3,7 +3,7 @@ description: >-
3
3
  Codebase reconnaissance specialist. Maps unknown territory, traces
4
4
  call chains and dependencies, discovers module relationships, and
5
5
  produces structured recon reports for downstream specialists.
6
- tools: read, bash, grep, find, ls, glob
6
+ tools: read, grep, find, ls, glob
7
7
  prompt_mode: append
8
8
  inherit_context: true
9
9
  ---
@@ -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 → Tester → Reviewer → [Output]`
21
+ Pipeline position: `Explorer → Architect → Builder → Reviewer → [Output]`
22
22
 
23
23
  ## Process
24
24
 
@@ -45,10 +45,7 @@ Pipeline position: `Explorer → Architect → Builder → Tester → Reviewer
45
45
  | Large | 300–1000 | Focused reads only, grep-first approach |
46
46
  | Huge | >1000 | Sampling strategy, skip generated/test/migration dirs |
47
47
 
48
- ## Iteration Limits
49
-
50
- - **Max 3 exploration approaches** before declaring "unable to find" and reporting what was tried.
51
- - **Never loop silently** - if a search strategy fails 3 times, surface the discovery log.
48
+ Stop when the map answers the downstream specialist's questions. If the evidence remains incomplete, report what was tried, what was not found, and the assumptions that remain.
52
49
 
53
50
  ## Output Format & Handoff
54
51
 
@@ -85,8 +82,6 @@ Your report should let the next agent start work immediately without re-explorin
85
82
 
86
83
  **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
84
 
88
- Before reporting done: verify the [Handoff Contract checklist](rules.md#handoff-contract).
89
-
90
85
  ## Rules
91
86
 
92
87
  - **!!! Never edit files** - you are read-only reconnaissance
@@ -96,8 +91,6 @@ Before reporting done: verify the [Handoff Contract checklist](rules.md#handoff-
96
91
  - Document negative findings too ("no middleware layer found")
97
92
  - Include specific file paths and line numbers in findings
98
93
  - 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
94
  - **!!! 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
95
  - **Parallelization:** adventurer tasks on different modules/areas can run in parallel. Read-only is safe; duplication is wasteful.
103
96
 
@@ -88,22 +88,9 @@ YYYY-MM-DD
88
88
  - "This is for production" -> Production-quality option
89
89
  - "I'm prototyping" -> Fastest option
90
90
 
91
- ## Iteration Limits
92
-
93
- - **Max 3 evidence-gathering rounds** in Phase 3 - consult relevant source categories only, then document assumptions and proceed if the evidence still does not distinguish the viable options.
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
91
  ## Handoff
97
92
 
98
- After the ADR is written, report:
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).
93
+ Report the ADR path, recommendation, decision evidence, documented assumptions, validation evidence, and next step.
107
94
 
108
95
  ## Rules & Constraints
109
96
 
@@ -113,8 +100,6 @@ Before reporting done: verify the [Handoff Contract checklist](rules.md#handoff-
113
100
  - For irreversible decisions, recommend more conservative options
114
101
  - Tag every assumption in the ADR as `[verified]` or `[inferred]`
115
102
  - **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
103
  - **Parallelization:** architect tasks on different decisions can run in parallel. Two architects on the same decision = wasted effort. ADR is single-writer.
119
104
 
120
105
  ## 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 tests before claiming done** - run the existing test suite (`npm test*` / `pnpm test*` / `npx tsc*` per the bash allow-list) and confirm the diff is focused
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
- - **Files modified** - per file: key signatures/interfaces changed (not function bodies)
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
+ Report modified files at signature or interface level, explain intent, and include validation evidence, assumptions, blockers, or follow-ups.
@@ -5,6 +5,4 @@
5
5
 
6
6
  ## MODE: blitz (Fast Implementation)
7
7
 
8
- Explicit low-risk/direct bypass: skip reconnaissance and design gates for familiar, low-risk work. Go directly to /builder for implementation (or direct execution where the host supports it). Only use /adventurer if the codebase context is genuinely unknown (not as a default step). Skip /reviewer unless the user explicitly requests review.
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
+ Use direct execution for familiar, low-risk code or other work when the host permits it; otherwise delegate to the permitted specialist. Skip optional reconnaissance and design ceremony, but never waive safety, authorization, required review, or branch floors. Escalate safety exceptions to the normal route.
@@ -5,4 +5,4 @@
5
5
 
6
6
  ## MODE: fein (Full Pipeline)
7
7
 
8
- Explicit selection of the `full` route. Default role-based pipeline: thinker (recon/design/plan) -> worker (implementation) -> verifier (review). Verifier acceptance terminates the pipeline for that unit of work. Roles and order may adapt to task needs - this is the default, not a fixed requirement. Do NOT skip any phase unless the user explicitly overrides in the same turn.
8
+ Activate the `full` route. Use the dynamic thinker -> worker -> verifier pipeline and required review floors.
@@ -5,4 +5,4 @@
5
5
 
6
6
  ## MODE: sonar (Research Only)
7
7
 
8
- Research mode: research only. Start with the specialist that owns the research question. Add a second specialist only for a distinct unresolved required output. STOP after the required research output is delivered. Do NOT implement, write code, or create any production files.
8
+ Activate research-only mode. Use only read-only `/adventurer` or `/planner` specialists: 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.
@@ -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 `pnpm-lock.yaml` / `package-lock.json` for recent changes (`git diff`)
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 `node --version`, `pnpm --version` for known incompatibilities
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
@@ -78,23 +78,16 @@ Confirm it works:
78
78
  - Check for unintended side effects
79
79
  - Prepare rollback plan **!!! Always verify before handoff** - Never present broken code.
80
80
 
81
- ## Iteration Limits
82
-
83
- - **Max 3 fix attempts** (Step 4) before escalating with the audit table.
84
- - **Never loop silently** - if a root cause hypothesis fails 3 times, surface the table.
85
-
86
81
  ## Rules
87
82
 
88
83
  - **!!! 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 bash permissions are `ask`** - explain rationale before any change.
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.
84
+ - **!!! Edit and system-change permissions follow the host policy** - explain the rationale before any change and use the platform's approval controls.
92
85
  - **!!! Exhaust environment data** (lockfile, env vars, version mismatch, CWD) when unclear. Document assumptions with supporting evidence and proceed.
93
86
  - **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
87
 
95
88
  ## Output Format & Handoff
96
89
 
97
- Document: what was investigated, ruled out, root cause, fix, prevention, and tagged assumptions (`[verified]`/`[inferred]`). Before reporting done: verify the [Handoff Contract checklist](rules.md#handoff-contract).
90
+ Document: what was investigated, ruled out, root cause, fix, prevention, and tagged assumptions (`[verified]`/`[inferred]`).
98
91
 
99
92
  ## Skill Prescription
100
93
 
package/agents/planner.md CHANGED
@@ -3,7 +3,7 @@ description: >-
3
3
  Implementation planning specialist. Breaks complex features into
4
4
  phased milestones with dependencies, timelines, verification criteria,
5
5
  and rollback points.
6
- tools: read, bash, grep, find, ls
6
+ tools: read, grep, find, ls
7
7
  prompt_mode: append
8
8
  inherit_context: true
9
9
  ---
@@ -24,14 +24,12 @@ You create implementation plans.
24
24
 
25
25
  ## Rules
26
26
 
27
- Global Handoff Contract and Parallelization rules apply.
27
+ Planning briefs state the outcome, phases, dependencies, acceptance evidence, assumptions, rollback points, and next step.
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
 
@@ -48,18 +46,9 @@ Global Handoff Contract and Parallelization rules apply.
48
46
  - Don't refactor existing code while adding features
49
47
  - Don't skip verification steps
50
48
 
51
- ## Iteration Limits
52
-
53
- Global Handoff Contract iteration limits apply. Role-specific:
54
-
55
- - **Termination condition:** all phases have success criteria, dependencies mapped, rollback points identified.
56
- - **Max 3 plan revisions** based on `/reviewer` feedback before finalising.
57
-
58
49
  ## Handoff
59
50
 
60
- Report: 1) planned phases and tasks, 2) assumptions (`[verified]`/`[inferred]`), 3) verification & rollback points, 4) next step (delegate to `/orchestrator`).
61
-
62
- Before reporting done: verify the [Handoff Contract checklist](rules.md#handoff-contract).
51
+ Include planned phases, assumptions, verification and rollback evidence, and the next step.
63
52
 
64
53
  ## Skill Prescription
65
54
 
@@ -4,7 +4,7 @@ description: >-
4
4
  performance, and maintainability in one general review. Adds specialist
5
5
  lenses only for matching security, performance, architecture, or UX risk;
6
6
  preserves blind review, lens exclusivity, and fix/dismiss/escalate triage.
7
- tools: read, bash, grep, find, ls, glob
7
+ tools: read, grep, find, ls, glob
8
8
  prompt_mode: append
9
9
  inherit_context: true
10
10
  ---
@@ -89,11 +89,6 @@ The general reviewer must give a verdict for every category. A specialized lens
89
89
  2. Do I have any struggles understanding these changes? Will this be maintainable?
90
90
  3. Can I observe this working by running it? What command, API call, or browser interaction produces visible proof?
91
91
 
92
- ## Iteration Limits
93
-
94
- - **Termination condition:** A general review gives every checklist item a verdict; a specialized lens gives verdicts for its assigned scope and directly relevant checks. Critical issues have concrete fixes.
95
- - **Max 3 re-reviews** before escalating persistent issues with issue history.
96
-
97
92
  ## Risk-Matched Review Lenses
98
93
 
99
94
  When the orchestrator dispatches a general review plus risk-matched specialist lenses, narrow to your assigned scope:
@@ -126,13 +121,11 @@ When the orchestrator dispatches a general review plus risk-matched specialist l
126
121
 
127
122
  ## Output Format
128
123
 
129
- Before reporting done: verify the [Handoff Contract checklist](rules.md#handoff-contract).
130
-
131
124
  Then produce:
132
125
 
133
126
  1. **Verdict**: approved / approved with observations / requires changes
134
127
  2. **Summary**: Scope reviewed, lens applied, overall assessment
135
- 3. **Issues by severity**: With line references and concrete fixes. Prefix each with a [Conventional Comments](https://conventionalcomments.org/) label (`praise:`, `suggestion:`, `issue:`, `nitpick:`, `question:`) and triage tag (`[fix]`, `[dismiss]`, `[escalate]`).
128
+ 3. **Issues by severity**: With line references and concrete fixes. Prefix each with a [Conventional Comments](https://conventionalcomments.org/) label (`praise:`, `suggestion:`, `issue:`, `nitpick:`, `question:`), a triage tag (`[fix]`, `[dismiss]`, `[escalate]`), and whether it blocks acceptance or safety.
136
129
  4. **What was verified** (and what was NOT)
137
130
  5. **Recommendation**: Next steps
138
131
  6. **Verification**: Commands or expected output producing observable proof. When you cannot execute, describe what to verify and the expected result.
package/agents/writer.md CHANGED
@@ -22,6 +22,8 @@ You write documentation.
22
22
 
23
23
  ## Principles
24
24
 
25
+ - Platform guarantees must be checked against the adapter; do not invent isolation or lifecycle enforcement.
26
+
25
27
  - Write for humans - clear over clever
26
28
  - Complete over concise (but don't repeat yourself)
27
29
  - Use code examples liberally
@@ -58,14 +60,9 @@ You write documentation.
58
60
  - Version, date, categories (added/changed/deprecated/removed/fixed/security)
59
61
  - Issue/PR links, migration notes for breaking changes
60
62
 
61
- ## Handoff
62
-
63
- Before reporting done: verify the [Handoff Contract checklist](rules.md#handoff-contract).
64
-
65
- ## Iteration Limits & Check
63
+ ## Check
66
64
 
67
65
  - **Termination condition:** links checked, examples runnable, tone matches docs, proofread once.
68
- - **Max 3 proofread-revise cycles** before handing off.
69
66
  - **!!! Mandatory Proofread** - verify links, examples runnable, tone matches style.
70
67
  - **!!! Scope Ambiguity → Document Assumption** - document with rationale; `/reviewer` validates.
71
68
 
@@ -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,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 m(e){return{state:{...e,reviewMode:!1,originalModel:null,originalTools:null},originalModel:e.originalModel,originalTools:e.originalTools}}function h(e,t){e.appendEntry(`maestria_state`,{...t})}function g(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(`
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){return[t,...e.filter(e=>e!==t)].slice(0,n)}function m(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 h(e,t){return{...e,filesModified:p(e.filesModified,t,10)}}function ee(e,t){return{...e,filesRead:p(e.filesRead,t,10)}}function g(e,t){return e.specialistsDelegated.includes(t)?e:{...e,specialistsDelegated:[...e.specialistsDelegated,t]}}function _(e){return{state:{...e,reviewMode:!1,originalModel:null,originalTools:null},originalModel:e.originalModel,originalTools:e.originalTools}}function v(e,t){e.appendEntry(`maestria_state`,{...t})}function y(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 _(e,t,n){let{state:r,originalModel:i,originalTools:a}=m(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 v(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 y={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`},b=[`adventurer`,`architect`,`builder`,`diagnose`,`planner`,`reviewer`,`writer`];function x(e){if(!b.includes(e))throw Error(`Unknown agent: "${e}". Allowed: ${b.join(`, `)}`)}function S(e,t){if(!e||!e.trim())throw Error(t)}function C(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 b){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 w=n(t(i(import.meta.url)),`..`,`agents`);function T(t){C(w,n(e(),`.pi`,`agent`,`agents`))}const E=[`fein`,`sonar`,`blitz`],D={fein:`[MODE: fein]`,sonar:`[MODE: sonar]`,blitz:`[MODE: blitz]`},O={};function k(e,t){let n=s(r(t,`${e}.md`),`utf-8`),i=n.indexOf(`## MODE:`);return i===-1?n.replace(/\s+$/,``)+`
3
+ `)}async function b(e,t,n){let{state:r,originalModel:i,originalTools:a}=_(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 x(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 S={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`},C=[`adventurer`,`architect`,`builder`,`diagnose`,`planner`,`reviewer`,`writer`];function w(e){if(!C.includes(e))throw Error(`Unknown agent: "${e}". Allowed: ${C.join(`, `)}`)}function T(e,t){if(!e||!e.trim())throw Error(t)}function E(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 C){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 D=n(t(i(import.meta.url)),`..`,`agents`);function te(t){E(D,n(e(),`.pi`,`agent`,`agents`))}const O=[`fein`,`sonar`,`blitz`],k={fein:`[MODE: fein]`,sonar:`[MODE: sonar]`,blitz:`[MODE: blitz]`},A={};function j(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 A(e,t){if(!(e in O))try{O[e]=k(e,t)}catch(t){console.warn(`[maestria] Failed to load mode prompt "${e}":`,t),O[e]=``}return`${D[e]}\n\n${O[e]}`}const j=/```[\s\S]*?```|`[^`]*`/g;function M(e){let t=[],n;for(;(n=j.exec(e))!==null;)t.push([n.index,n.index+n[0].length]);return t}function N(e,t){return t.some(([t,n])=>e>=t&&e<n)}const P={fein:3,sonar:2,blitz:1};function F(e,t){if(!e)return null;let n=M(e),r=null;for(let t of E){let i=RegExp(`\\b${t}\\b`,`gi`),a;for(;(a=i.exec(e))!==null;)N(a.index,n)||(r===null||P[t]>P[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:A(r.keyword,t)}}function I(e,t){return t?`${e}\n\n${t}`:e}function L(e,t,n,r){e(async(e,i)=>{let a=F(e.text??``,n);return a?(t.reviewMode&&await r.restoreOriginalState(i),t.mode=a.keyword,r.persistState(),r.transform(I(a.prompt,a.strippedText))):r.noMatch})}function R(e,t,n){for(let r of E)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 z=r(t(i(import.meta.url)),`../agents/commands`);function B(e,t){L(t=>e.on(`input`,t),t,z,{restoreOriginalState:n=>_(e,n,t),persistState:()=>h(e,t),noMatch:{action:`continue`},transform:e=>({action:`transform`,text:e})})}function V(e,t){R((t,n)=>e.registerCommand(t,n),t,{restoreOriginalState:n=>_(e,n,t),persistState:()=>h(e,t)})}const H=r(t(i(import.meta.url)),`../agents/commands`);function U(e){return(t,n)=>{if(e.mode)return{systemPrompt:[t.systemPrompt,``,A(e.mode,H),``,`The user has set workflow mode to "${e.mode}". Honor this mode throughout the session until changed via /command.`].join(`
6
- `)}}}function W(e,t){e.on(`session_before_compact`,e=>{let n=e.preparation;return{compaction:{summary:g(t),details:{...t},firstKeptEntryId:n?.firstKeptEntryId,tokensBefore:n?.tokensBefore}}}),e.on(`session_before_tree`,e=>{if(e.preparation?.userWantsSummary)return{summary:{summary:g(t)}}})}function G(e,t){W({on:(t,n)=>{e.on(t,n)}},t)}const K=new Set([`completed`,`steered`,`aborted`,`stopped`,`error`]);async function q(e,t,n,r,i,a){let o=0,s=r.getRecord(e);for(;s&&!K.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&&!K.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 J(e,t,n,r){let i=p(t,`orchestrator`,n,r);Object.assign(t,i),e.appendEntry(`maestria_state`,t)}function Y(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`)x(r.agent),S(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)x(e.agent),S(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)x(e.agent),S(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});J(e,t,n,o);let c=await q(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),J(e,t,r.agent,r.task)}let s=await Promise.all(o.map((e,t)=>q(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(`
5
+ `}function M(e,t){if(!(e in A))try{A[e]=j(e,t)}catch(t){console.warn(`[maestria] Failed to load mode prompt "${e}":`,t),A[e]=``}return`${k[e]}\n\n${A[e]}`}const N=/```[\s\S]*?```|`[^`]*`/g;function P(e){let t=[],n;for(;(n=N.exec(e))!==null;)t.push([n.index,n.index+n[0].length]);return t}function F(e,t){return t.some(([t,n])=>e>=t&&e<n)}const I={fein:3,sonar:2,blitz:1};function L(e,t){if(!e)return null;let n=P(e),r=null;for(let t of O){let i=RegExp(`\\b${t}\\b`,`gi`),a;for(;(a=i.exec(e))!==null;)F(a.index,n)||(r===null||I[t]>I[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:M(r.keyword,t)}}function R(e,t){return t?`${e}\n\n${t}`:e}function z(e,t,n,r){e(async(e,i)=>{let a=L(e.text??``,n);return a?(t.reviewMode&&await r.restoreOriginalState(i),t.mode=a.keyword,r.persistState(),r.transform(R(a.prompt,a.strippedText))):r.noMatch})}function B(e,t,n){e(`mode-clear`,{description:`Clear workflow mode and return to neutral routing`,handler:async(e,r)=>{t.reviewMode&&await n.restoreOriginalState(r),t.mode=null,n.persistState(),r.ui.notify(`Workflow mode cleared. Neutral routing is active.`)}});for(let r of O)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 V=r(t(i(import.meta.url)),`../agents/commands`);function H(e,t){z(t=>e.on(`input`,t),t,V,{restoreOriginalState:n=>b(e,n,t),persistState:()=>v(e,t),noMatch:{action:`continue`},transform:e=>({action:`transform`,text:e})})}function U(e,t){B((t,n)=>e.registerCommand(t,n),t,{restoreOriginalState:n=>b(e,n,t),persistState:()=>v(e,t)})}const W=r(t(i(import.meta.url)),`../agents/commands`);function ne(e){return(t,n)=>{if(e.mode)return{systemPrompt:[t.systemPrompt,``,M(e.mode,W),``,`The user has set workflow mode to "${e.mode}". Honor this mode throughout the session until changed via /command.`].join(`
6
+ `)}}}function G(e,t){e.on(`session_before_compact`,e=>{let n=e.preparation;return{compaction:{summary:y(t),details:{...t},firstKeptEntryId:n?.firstKeptEntryId,tokensBefore:n?.tokensBefore}}}),e.on(`session_before_tree`,e=>{if(e.preparation?.userWantsSummary)return{summary:{summary:y(t)}}})}function K(e,t){G({on:(t,n)=>{e.on(t,n)}},t)}const q=C,J=new Set([`completed`,`steered`,`aborted`,`stopped`,`error`]);async function Y(e,t,n,r,i,a){let o=0,s=r.getRecord(e);for(;s&&!J.has(s.status)&&o<360;){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&&!J.has(s.status))throw Error(`Subagent ${e} timed out after 180000ms`);if(!s)throw Error(`Subagent ${e} was cleaned up before completion`);return s}function X(e,t,n,r){let i=g(m(t,`orchestrator`,n,r),n);Object.assign(t,i),v(e,t)}function Z(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.String({description:`Specialist agent name (required): adventurer, architect, builder, diagnose, planner, reviewer, writer`}),task:l.String({description:`Task description for the subagent (required)`}),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`){if(!r.agent||!q.includes(r.agent))return{content:[{type:`text`,text:`Invalid maestria_subagent call: 'agent' is required and must be one of ${q.join(`, `)}. Re-dispatch with a valid agent name; the orchestrator may continue read-only exploration while the brief is corrected.`}]};T(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)w(e.agent),T(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)w(e.agent),T(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});X(e,t,n,o);let c=await Y(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),X(e,t,r.agent,r.task)}let s=await Promise.all(o.map((e,t)=>Y(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});J(e,t,s.agent,c),a?.({content:[{type:`text`,text:`Chain step ${r+1}/${n.length}: ${s.agent} running...`}]});let d=await q(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()},h(e,t),e.events?.emit(y.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()),h(e,t),e.events?.emit(y.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()),h(e,t),e.events?.emit(y.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()}),h(e,t)});n&&n.push(r,i,a,o)}}const X=[`read`,`grep`,`find`,`ls`,`glob`];function Z(e,t){e.registerCommand(`maestria-status`,{description:`Show current maestria session state including handoff history`,handler:async(e,n)=>{let r=g(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),h(e,t),t.reviewModel){let n=await v(e,r,t);n&&(r.ui.notify(`Review mode: switched to ${n}`),e.events?.emit(y.REVIEW_ACTIVATED,{originalModel:t.originalModel,reviewModel:n,timestamp:Date.now()}))}e.setActiveTools(X),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 _(e,r,t),h(e,t),r.ui.notify(`Restored original model and tools.`),e.events?.emit(y.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(`
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});X(e,t,s.agent,c),a?.({content:[{type:`text`,text:`Chain step ${r+1}/${n.length}: ${s.agent} running...`}]});let d=await Y(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()},v(e,t),e.events?.emit(S.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()),v(e,t),e.events?.emit(S.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()),v(e,t),e.events?.emit(S.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()}),v(e,t)});n&&n.push(r,i,a,o)}}const re=[`read`,`grep`,`find`,`ls`,`glob`];function ie(e,t){e.registerCommand(`maestria-status`,{description:`Show current maestria session state including handoff history`,handler:async(e,n)=>{let r=y(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),v(e,t),t.reviewModel){let n=await x(e,r,t);n&&(r.ui.notify(`Review mode: switched to ${n}`),e.events?.emit(S.REVIEW_ACTIVATED,{originalModel:t.originalModel,reviewModel:n,timestamp:Date.now()}))}e.setActiveTools(re),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 b(e,r,t),v(e,t),r.ui.notify(`Restored original model and tools.`),e.events?.emit(S.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),h(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,h(e,t),r.ui.notify(`Review model set to: ${i}`)}})}const Q=[/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 $(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 Q)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 ee(e){let t=f(),n=[];V(e,t),B(e,t);let r=U(t);e.on(`before_agent_start`,(e,t)=>r(e,t)),e.on(`session_start`,(e,n)=>{if(T(n),!n.sessionManager?.getEntries)return;let r=n.sessionManager.getEntries();for(let e=r.length-1;e>=0;e--){let n=r[e];if(n.type===`custom`&&n.customType===`maestria_state`){let e=n.data;e&&typeof e==`object`&&Object.assign(t,e);break}}}),G(e,t),Y(e,t,n),Z(e,t),e.on(`session_shutdown`,()=>{for(let e of n)e();n.length=0}),$(e,t)}export{ee as default};
13
+ `);t.handoffHistory=[{from:`current`,to:`next`,task:i,timestamp:Date.now()},...t.handoffHistory??[]].slice(0,5),v(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,v(e,t),r.ui.notify(`Review model set to: ${i}`)}})}const ae=[/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/],oe=/^(ls|cat|head|tail|git status|git diff|git log|git branch|find|grep|rg|pnpm test|npm test|pwd|which)\b/;function se(e){let t=e.trim();if(t.includes(`$(`)||t.includes("`"))return!1;let n=t.replace(/\d?>&[12]/g,``);return!n.includes(`>`)&&n.split(/[\n;&|]+/).every(e=>oe.test(e.trim()))}function Q(e,t){e.on(`tool_call`,async(n,r)=>{if(!n||!n.toolName)return;if(t.mode!==null&&e.getActiveTools().includes(`subagent`)&&(d(`edit`,n)||d(`write`,n)||d(`patch`,n)||n.toolName===`bash`)){if(n.toolName===`bash`){let e=n.input;if(se(typeof e?.command==`string`?e.command:``))return}return{block:!0,reason:`Tool '${n.toolName}' is blocked for the orchestrator. Use 'maestria_subagent' to delegate mutations 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 ae)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}`}}}let i=!1;if(d(`read`,n)){let e=n.input?.path;typeof e==`string`&&e&&(Object.assign(t,ee(t,e)),i=!0)}else if(d(`edit`,n)||d(`write`,n)){let e=n.input?.path;typeof e==`string`&&e&&(Object.assign(t,h(t,e)),i=!0)}i&&v(e,t)})}function ce(e){return typeof e==`object`&&!!e}function le(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=le(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`){ce(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 ue(e){let t=f(),n=[];U(e,t),H(e,t);let r=ne(t);e.on(`before_agent_start`,(e,t)=>r(e,t)),e.on(`session_start`,(e,n)=>{te(n),$(t,n)}),e.on(`session_tree`,(e,n)=>{$(t,n)}),K(e,t),Z(e,t,n),ie(e,t),e.on(`session_shutdown`,()=>{for(let e of n)e();n.length=0}),Q(e,t)}export{ue as default};
14
14
  //# sourceMappingURL=extension.mjs.map