@maestria/pi 0.6.4 → 0.6.6

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
  ---
@@ -45,10 +45,7 @@ Pipeline position: `Explorer → Architect → Builder → Reviewer → [Output]
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
- - This role bound governs exploration evidence only; implementation, test, and review repair uses the universal bounded-autonomy budget.
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
 
@@ -50,11 +50,6 @@ Stop when the evidence distinguishes the viable options. If relevant evidence is
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
-
58
53
  ## Phase 4: Recommend
59
54
 
60
55
  State recommendation with clear rationale and acknowledged trade-offs.
@@ -95,7 +90,7 @@ YYYY-MM-DD
95
90
 
96
91
  ## Handoff
97
92
 
98
- Follow the universal Handoff Contract. Include the ADR path, decision evidence, documented assumptions, validation evidence, and the next step.
93
+ Report the ADR path, recommendation, decision evidence, documented assumptions, validation evidence, and next step.
99
94
 
100
95
  ## Rules & Constraints
101
96
 
package/agents/builder.md CHANGED
@@ -32,30 +32,9 @@ If the task is not atomic - if it spans multiple unrelated concerns - document t
32
32
  3. **Verify** - Run tests or type checks to confirm correctness
33
33
  4. **Report** - State what changed and why
34
34
 
35
- ## Implementation Patterns
35
+ ## Implementation Judgment
36
36
 
37
- ### Implementation Staircase
38
-
39
- For complex features, build incrementally:
40
-
41
- 1. Hardcoded version that demonstrates the concept
42
- 2. Add state management with mock data
43
- 3. Connect to real data/API
44
- 4. Add error handling and loading states
45
- 5. Optimize and polish
46
-
47
- Each step is verifiable before moving to the next.
48
-
49
- ### Constraint Escalation
50
-
51
- Start with tight constraints, relax as needed:
52
-
53
- - Round 0: "Check if the problem is already solved - is there a well-maintained open-source library or existing dependency that handles this?"
54
- - Round 1: "Solve this with existing dependencies only"
55
- - Round 2: "Now you can use standard library features"
56
- - Round 3: "Add external dependencies if necessary"
57
-
58
- This reveals what actually requires heavy tools vs. what's simple.
37
+ Start with the smallest change that satisfies acceptance. Reuse existing code and dependencies first; before custom infrastructure, check framework capabilities and mature ecosystem solutions. Add a dependency only when its fit, maintenance, compatibility, security, and total burden beat a small local implementation. Add layers only when the product requires them.
59
38
 
60
39
  ## Skill Prescription
61
40
 
@@ -107,4 +86,4 @@ This reveals what actually requires heavy tools vs. what's simple.
107
86
 
108
87
  ## Handoff
109
88
 
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.
89
+ Report modified files at signature or interface level, explain intent, and include validation evidence, assumptions, blockers, or follow-ups.
@@ -5,4 +5,4 @@
5
5
 
6
6
  ## MODE: blitz (Fast Implementation)
7
7
 
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.
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: sonar (Research Only)
7
7
 
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.
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.
@@ -78,11 +78,6 @@ 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 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
-
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.
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,7 +24,7 @@ You create implementation plans.
24
24
 
25
25
  ## Rules
26
26
 
27
- Delegation briefs use the seven fields defined in the universal Delegation contract; the planner-specific parallelization rule below applies.
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.
@@ -46,14 +46,9 @@ Delegation briefs use the seven fields defined in the universal Delegation contr
46
46
  - Don't refactor existing code while adding features
47
47
  - Don't skip verification steps
48
48
 
49
- ## Iteration Limits
50
-
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.
53
-
54
49
  ## Handoff
55
50
 
56
- Follow the universal Handoff Contract. Include planned phases, assumptions, verification and rollback evidence, and the next step.
51
+ Include planned phases, assumptions, verification and rollback evidence, and the next step.
57
52
 
58
53
  ## Skill Prescription
59
54
 
@@ -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
- - **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.
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:
@@ -120,6 +115,8 @@ When the orchestrator dispatches a general review plus risk-matched specialist l
120
115
  - **!!! Flag collateral deletions** in the diff.
121
116
  - Provide specific, actionable feedback with line references and concrete fixes.
122
117
  - Classify issues as critical / major / minor / suggestion.
118
+ - Review against the acceptance bar, not idealized code. Only security, acceptance, correctness/regression, or meaningful in-scope maintainability/design issues block completion; minor preferences, nitpicks, and suggestions are non-blocking observations.
119
+ - When acceptance evidence is complete and no material blocker remains, approve and stop. Do not create another review pass merely to find additional polish.
123
120
  - If you cannot reproduce an issue, say so.
124
121
  - If no issues are found, say so and state what you verified.
125
122
  - If scope is unclear: document assumption from diff context and proceed.
@@ -130,7 +127,7 @@ Then produce:
130
127
 
131
128
  1. **Verdict**: approved / approved with observations / requires changes
132
129
  2. **Summary**: Scope reviewed, lens applied, overall assessment
133
- 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]`).
130
+ 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.
134
131
  4. **What was verified** (and what was NOT)
135
132
  5. **Recommendation**: Next steps
136
133
  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,11 +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
- ## Iteration Limits & Check
63
+ ## Check
62
64
 
63
65
  - **Termination condition:** links checked, examples runnable, tone matches docs, proofread once.
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.
66
66
  - **!!! Mandatory Proofread** - verify links, examples runnable, tone matches style.
67
67
  - **!!! Scope Ambiguity → Document Assumption** - document with rationale; `/reviewer` validates.
68
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 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(`
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 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+$/,``)+`
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 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(`
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}async function X(e,t,n,r,i,a){try{return await Y(e,t,n,r,i,a)}catch(t){try{r.abort(e)}catch{}throw t}}function Z(e,t,n,r){let i=g(m(t,`orchestrator`,n,r),n);Object.assign(t,i),v(e,t)}function re(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});Z(e,t,n,o);let c=await X(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),Z(e,t,r.agent,r.task)}let s=await Promise.all(o.map((e,t)=>X(e,`${n[t].agent} (${t+1}/${n.length})`,!1,l,i,a).then(e=>({index:t,record:e})).catch(e=>{for(let e of o)try{l.abort(e)}catch{}return{index:t,error:e}})));a?.({content:[{type:`text`,text:`All ${n.length} parallel subagents settled.`}]});let c=[`## Parallel Results (${n.length} tasks)\n`];for(let e=0;e<n.length;e++){let t=n[e],r=s[e],i=`### ${e+1}: ${t.agent}`;if(`error`in r){let e=r.error instanceof Error?r.error.message:String(r.error);c.push(i),c.push(`⚠️ ${e}`)}else{let e=r.record.result??r.record.error??`No output.`;c.push(i),c.push(e)}}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});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(`
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});Z(e,t,s.agent,c),a?.({content:[{type:`text`,text:`Chain step ${r+1}/${n.length}: ${s.agent} running...`}]});try{let e=await X(u,`Chain step ${r+1}: ${s.agent}`,!0,l,i,a);o=e.result??e.error??`No output.`}catch(e){o=`[error] ${e instanceof Error?e.message:String(e)}`;break}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 ie=[`read`,`grep`,`find`,`ls`,`glob`];function ae(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(ie),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),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};
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 oe=[/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/],se=/^(ls|cat|head|tail|git status|git diff|git log|git branch|find|grep|rg|pnpm test|npm test|pwd|which)\b/;function Q(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=>se.test(e.trim()))}function ce(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(Q(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 oe)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 le(e){return typeof e==`object`&&!!e}function ue(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=ue(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`){le(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 de(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),re(e,t,n),ae(e,t),e.on(`session_shutdown`,()=>{for(let e of n)e();n.length=0}),ce(e,t)}export{de as default};
14
14
  //# sourceMappingURL=extension.mjs.map