@maestria/pi 0.5.4 → 0.5.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.
- package/README.md +0 -1
- package/agents/adventurer.md +2 -6
- package/agents/architect.md +2 -6
- package/agents/builder.md +6 -8
- package/agents/commands/blitz.md +8 -0
- package/agents/commands/fein.md +8 -0
- package/agents/commands/sonar.md +8 -0
- package/agents/diagnose.md +3 -12
- package/agents/planner.md +2 -6
- package/agents/reviewer.md +4 -4
- package/agents/writer.md +2 -8
- package/dist/extension.mjs +11 -13
- package/dist/extension.mjs.map +1 -1
- package/package.json +1 -1
- package/skills/global-rules/SKILL.md +21 -11
- package/skills/orchestrator/SKILL.md +161 -320
package/README.md
CHANGED
|
@@ -51,7 +51,6 @@ pi uninstall @gotgenes/pi-subagents
|
|
|
51
51
|
| `/fein <goal>` | Set workflow mode to full pipeline (recon → design → impl → review) |
|
|
52
52
|
| `/sonar <goal>` | Set workflow mode to research only (recon → design → stop) |
|
|
53
53
|
| `/blitz <goal>` | Set workflow mode to fast implementation (builder directly) |
|
|
54
|
-
| `/orchestrate <goal>` | Start a full pipeline by delegating to the orchestrator |
|
|
55
54
|
| `/review <target>` | Enter review mode - blocks destructive tools, sets read-only toolset |
|
|
56
55
|
| `/restore-model` | Restore the original model and tools active before review mode |
|
|
57
56
|
| `/handoff <goal>` | Generate a structured handoff prompt for a new task context |
|
package/agents/adventurer.md
CHANGED
|
@@ -93,17 +93,13 @@ Specific guidance for the downstream specialist.
|
|
|
93
93
|
- **!!! Never edit files** - you are read-only reconnaissance
|
|
94
94
|
- **!!! Never implement solutions** - that's `/builder`'s job
|
|
95
95
|
- **!!! Never make design decisions** - that's `/architect`'s job
|
|
96
|
-
- **
|
|
97
|
-
- **External repos: `opensrc` for big repos, `webfetch` for single pages** - For GitHub/GitLab/BitBucket URLs, scoped queries (single file, single page) → `webfetch` is fine. Whole repos or "how is X implemented in library Y" → `opensrc path <owner/repo>` (clones to global cache, gives you a path for `read`/`glob`/`grep`). Don't webfetch a multi-file repo one file at a time - clone once, read locally.
|
|
96
|
+
- **Open external repos with `opensrc` (not `webfetch`)** - clone once with `opensrc path <owner/repo>`, read locally. `webfetch` is for single pages only.
|
|
98
97
|
- **One role per session** - don't mix exploration with building
|
|
99
98
|
- If you can't find something after reasonable effort, report what you tried
|
|
100
|
-
- Prefer `lsp` tool for code intelligence over grep when possible
|
|
101
99
|
- Document negative findings too ("no middleware layer found")
|
|
102
100
|
- Include specific file paths and line numbers in findings
|
|
103
101
|
- For large codebases, use grep-first strategy to avoid token waste
|
|
104
|
-
- **!!!
|
|
105
|
-
- **!!! 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.
|
|
106
|
-
- **!!! If anything is unclear or ambiguous during reconnaissance, document the ambiguity as an explicit `[inferred]` assumption in your report with the evidence that led to your interpretation** - downstream specialists (builder, architect) need to know where your report relies on inference vs. direct observation.
|
|
102
|
+
- **!!! Document ambiguity as explicit `[inferred]` assumptions in your report, with the evidence behind each interpretation** - downstream specialists (builder, architect) need to know where your report relies on inference vs. direct observation.
|
|
107
103
|
- **Parallelization:** adventurer tasks on different modules/areas can run in parallel. Two adventurers mapping the same module produce overlapping reports. Read-only is safe; duplication is wasteful.
|
|
108
104
|
|
|
109
105
|
## Handoff
|
package/agents/architect.md
CHANGED
|
@@ -115,7 +115,6 @@ After the ADR is written, your handoff should cover:
|
|
|
115
115
|
|
|
116
116
|
- `api-design-principles` (`wshobson/agents`) - load when designing APIs, choosing REST vs GraphQL, or defining endpoint structures
|
|
117
117
|
- `architecture-decision-framework` (`agustinusnathaniel/skills`) - load when using decision matrices, weighted scoring, or comparing implementation approaches
|
|
118
|
-
- `architecture-decision-records` (`wshobson/agents`) - load when documenting an architecture decision as an ADR
|
|
119
118
|
- `c4-architecture` (`softaworks/agent-toolkit`) - load when output requires a container/component diagram
|
|
120
119
|
- `codebase-design` (`mattpocock/skills`) - load when designing module boundaries, deciding where seams go, or improving codebase structure
|
|
121
120
|
- `domain-modeling` (`mattpocock/skills`) - load when building or sharpening the project's domain model and ubiquitous language
|
|
@@ -143,12 +142,9 @@ After the ADR is written, your handoff should cover:
|
|
|
143
142
|
## Constraints
|
|
144
143
|
|
|
145
144
|
- **!!! Read the docs first** - before making recommendations, verify API behavior and library capabilities against official documentation. Don't guess at how a tool works.
|
|
146
|
-
- Don't assume - verify against official docs and references
|
|
147
145
|
- Don't oversimplify - acknowledge trade-offs honestly
|
|
148
146
|
- For irreversible decisions, recommend more conservative options
|
|
149
147
|
- Tag every assumption in the ADR as `[verified]` or `[inferred]`
|
|
150
|
-
- **
|
|
151
|
-
- **!!! Maker/checker split** - your work is reviewed by `/reviewer` before it lands. The model that wrote the ADR is too nice grading its own homework. Produce the recommendation, do not QA it.
|
|
152
|
-
- **!!! 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.
|
|
148
|
+
- **The ADR should not contain open questions** - every unclear item becomes an explicit assumption with evidence.
|
|
153
149
|
- **Parallelization:** architect tasks on different decisions can run in parallel. Two architects on the same decision = wasted effort. ADR is single-writer.
|
|
154
|
-
- **
|
|
150
|
+
- **Open external repos with `opensrc` (not `webfetch`)** - clone once, read locally. `webfetch` is for single pages only.
|
package/agents/builder.md
CHANGED
|
@@ -109,20 +109,18 @@ This reveals what actually requires heavy tools vs. what's simple.
|
|
|
109
109
|
|
|
110
110
|
## Rules
|
|
111
111
|
|
|
112
|
-
- **!!!
|
|
112
|
+
- **!!! Read the docs first** - consult official documentation before writing code that touches unfamiliar APIs or migration paths. Don't guess at API changes.
|
|
113
|
+
- **!!! Validate before handoff** - never present a change you haven't tested. Run the existing test suite, confirm the diff is focused.
|
|
114
|
+
- **!!! 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
|
|
113
115
|
- Prefer `edit` over `write` - preserve existing code
|
|
114
|
-
- **!!! Run tests before claiming done**
|
|
116
|
+
- **!!! 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
|
|
115
117
|
- **!!! Never implement without reading the target files first**
|
|
116
|
-
- **!!! Read the docs first** - before writing code that uses unfamiliar APIs, tools, or migration paths, consult official documentation. Don't guess at API changes.
|
|
117
118
|
- If a change grows beyond the original task scope, flag it in your handoff
|
|
118
119
|
- Keep the change focused - one concern per invocation
|
|
119
|
-
- **External repos: `opensrc` for big repos, `webfetch` for single pages** - For GitHub/GitLab/BitBucket URLs, scoped queries (single file, single page) → `webfetch` is fine. Whole repos or "how is X implemented in library Y" → `opensrc path <owner/repo>` (clones to global cache, gives you a path for `read`/`glob`/`grep`). Don't webfetch a multi-file repo one file at a time - clone once, read locally.
|
|
120
|
-
- **!!! Maker/checker split** - your work is reviewed by `/reviewer` before it lands. The model that wrote the code is too nice grading its own homework. Apply the fix, do not QA it.
|
|
121
|
-
- **!!! Never delete what you didn't create** - adapt, don't remove. If something exists and it seems unnecessary, flag it in your handoff with your reasoning rather than deleting it. Collateral deletions are a trust killer.
|
|
122
|
-
- **!!! Validate before handoff** - never present a change you haven't tested. Run `npm test*` / `pnpm test*` / `npx tsc*` per the bash allow-list. Run the existing test suite, confirm the diff is focused.
|
|
123
|
-
- **!!! When implementation is ambiguous, don't ask - exhaust data first.** Read the codebase for existing patterns, follow conventions already established, check ADRs for prior decisions, check `.maestria/rules.md` for project constraints. If still ambiguous: make the best decision based on codebase patterns, document the assumption in your handoff, and proceed. The reviewer will validate the assumption.
|
|
124
120
|
- **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.**
|
|
125
121
|
- **!!! 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.
|
|
122
|
+
- **Open external repos with `opensrc` (not `webfetch`)** - clone once, read locally. `webfetch` is for single pages only.
|
|
123
|
+
- **!!! 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.
|
|
126
124
|
|
|
127
125
|
## Iteration Limits
|
|
128
126
|
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
<!-- Auto-generated from @maestria/core. Do not edit directly.
|
|
2
|
+
Edit the canonical file at packages/core/agent-directives/ instead. -->
|
|
3
|
+
|
|
4
|
+
[MODE: blitz]
|
|
5
|
+
|
|
6
|
+
## MODE: blitz (Fast Implementation)
|
|
7
|
+
|
|
8
|
+
Speed mode: skip reconnaissance and design gates. Go directly to /builder for implementation. Only use /adventurer if the codebase context is genuinely unknown (not as a default step). Skip /reviewer unless the user explicitly requests review.
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
<!-- Auto-generated from @maestria/core. Do not edit directly.
|
|
2
|
+
Edit the canonical file at packages/core/agent-directives/ instead. -->
|
|
3
|
+
|
|
4
|
+
[MODE: fein]
|
|
5
|
+
|
|
6
|
+
## MODE: fein (Full Pipeline)
|
|
7
|
+
|
|
8
|
+
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.
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
<!-- Auto-generated from @maestria/core. Do not edit directly.
|
|
2
|
+
Edit the canonical file at packages/core/agent-directives/ instead. -->
|
|
3
|
+
|
|
4
|
+
[MODE: sonar]
|
|
5
|
+
|
|
6
|
+
## MODE: sonar (Research Only)
|
|
7
|
+
|
|
8
|
+
Research mode: reconnaissance and design only. Delegate to /adventurer (recon) followed by /architect or /planner (analysis/design). STOP after delivering findings and design. Do NOT implement, write code, or create any production files.
|
package/agents/diagnose.md
CHANGED
|
@@ -82,8 +82,6 @@ Confirm it works:
|
|
|
82
82
|
- Check for unintended side effects
|
|
83
83
|
- Prepare rollback plan
|
|
84
84
|
|
|
85
|
-
**!!! Always verify before handoff** - Never present broken code.
|
|
86
|
-
|
|
87
85
|
## Skill Prescription
|
|
88
86
|
|
|
89
87
|
### Always load
|
|
@@ -95,7 +93,6 @@ Confirm it works:
|
|
|
95
93
|
- `agent-browser` (`vercel-labs/agent-browser`) - load when bug involves UI behavior, network requests, performance profiling, or needs visual reproduction (skip if backend-only)
|
|
96
94
|
- `dependency-updater` (`softaworks/agent-toolkit`) - load when investigating dependency-related bugs, lockfile issues, or version conflicts
|
|
97
95
|
- `resolving-merge-conflicts` (`mattpocock/skills`) - load when debugging regressions introduced by a merge or rebase
|
|
98
|
-
- `diagnosing-bugs` (`mattpocock/skills`) - load when using the diagnose methodology for systematic debugging
|
|
99
96
|
- `karpathy-guidelines` (`multica-ai/andrej-karpathy-skills`) - load when investigating pattern-level bugs
|
|
100
97
|
- `logging-best-practices` (`boristane/agent-skills`) - load when bug surfaces in logs or you need to add logging
|
|
101
98
|
- `opensrc` (`vercel-labs/opensrc`) - load when root cause is in an external library
|
|
@@ -126,8 +123,6 @@ Document findings at each step:
|
|
|
126
123
|
- Prevention measures
|
|
127
124
|
- **Assumptions documented** - what was unclear and what you assumed, with the evidence that led to each assumption
|
|
128
125
|
|
|
129
|
-
**!!! Save your findings as persistent knowledge artifacts** - don't let diagnostic work disappear after the session ends. Create a markdown file or use `/writer` to store the investigation record for future reference.
|
|
130
|
-
|
|
131
126
|
## Iteration Limits
|
|
132
127
|
|
|
133
128
|
- **Max 3 fix attempts** (Step 4) before escalating with the audit table.
|
|
@@ -138,11 +133,7 @@ Document findings at each step:
|
|
|
138
133
|
|
|
139
134
|
- **!!! Document your diagnostic work as persistent knowledge artifacts** - save what you investigated, ruled out, root cause, and fix applied. Don't let findings disappear when the session ends. Use `/writer` or a markdown file if no knowledge base exists yet.
|
|
140
135
|
- **!!! Edit and bash permissions are `ask`** - explain why before any change
|
|
141
|
-
- **!!!
|
|
142
|
-
- **!!!
|
|
143
|
-
- **!!! Validate before handoff** - never present a fix you haven't reproduced-and-verified works. Run the existing test suite, reproduce the original error, confirm it's gone.
|
|
144
|
-
- **!!! If anything is unclear or ambiguous, exhaust environment data (lockfile, env vars, version mismatch, CWD), document your assumption with supporting evidence, and proceed** - wrong assumptions waste more time than asking questions. Document assumptions, not questions.
|
|
136
|
+
- **!!! Never present a fix you haven't reproduced-and-verified** - run the existing test suite, reproduce the original error, confirm it's gone.
|
|
137
|
+
- **!!! Exhaust environment data before concluding** - lockfile, env vars, version mismatches, CWD. If the error description or reproduction is vague, attempt reproduction with available information and document what you assumed about environment or inputs.
|
|
145
138
|
- **Parallelization:** diagnose tasks on different bugs can run in parallel. Two diagnoses on the same bug = wasted; same root-cause cluster = consolidate first.
|
|
146
|
-
- **
|
|
147
|
-
|
|
148
|
-
**If the error description is vague or the reproduction is unclear, attempt to reproduce with available information, document what you assumed about the environment or inputs, and proceed.** The reviewer will validate whether the assumptions were reasonable.
|
|
139
|
+
- **Open external repos with `opensrc` (not `webfetch`)** - clone once, read locally. `webfetch` is for single pages only.
|
package/agents/planner.md
CHANGED
|
@@ -35,14 +35,11 @@ After the plan is written, your handoff should cover:
|
|
|
35
35
|
## Rules
|
|
36
36
|
|
|
37
37
|
- One plan per complex feature - never bundle unrelated work
|
|
38
|
-
- **!!! Each phase must have verifiable completion criteria**
|
|
38
|
+
- **!!! Each phase must have verifiable completion criteria** - success criteria and rollback points are the termination condition for every phase
|
|
39
39
|
- Mark dependencies between phases explicitly
|
|
40
40
|
- Include rollback points between phases
|
|
41
|
-
- Verify plan completeness before claiming done
|
|
42
41
|
- Define guard rails: what to do and what not to do
|
|
43
|
-
- **!!!
|
|
44
|
-
- **!!! Validate before handoff** - never present a plan where each phase lacks success criteria or rollback points. Re-read the plan structure before reporting back.
|
|
45
|
-
- **!!! If anything is unclear or ambiguous, document your assumption explicitly in the plan with supporting rationale and proceed** - the plan should not contain open questions. Every open question is a blocked phase; convert it to an assumption with the evidence that led to it.
|
|
42
|
+
- **!!! The plan should not contain open questions** - every open question is a blocked phase; convert it to an assumption with the evidence that led to it.
|
|
46
43
|
- **Parallelization:** planner tasks on different features can run in parallel. Two planners on the same feature = wasted effort. Plan is single-writer.
|
|
47
44
|
|
|
48
45
|
## Iteration Limits
|
|
@@ -97,4 +94,3 @@ After the plan is written, your handoff should cover:
|
|
|
97
94
|
- Don't add new dependencies without approval
|
|
98
95
|
- Don't refactor existing code while adding features
|
|
99
96
|
- Don't skip verification steps
|
|
100
|
-
- **If requirements are ambiguous, exhaust available data, document your assumption, and proceed** - the plan should not contain open questions. Convert ambiguity to documented assumptions.
|
package/agents/reviewer.md
CHANGED
|
@@ -90,7 +90,7 @@ You review code for quality.
|
|
|
90
90
|
|
|
91
91
|
1. Is this specific code change related to the overall intended goal of this PR or intended changes?
|
|
92
92
|
2. Do I have any struggles understanding these changes? Will this code be maintainable in the future?
|
|
93
|
-
3. Can I observe this working by running it? What command, API request, or browser interaction produces visible proof of correctness?
|
|
93
|
+
3. Can I observe this working by running it? What command, API request, or browser interaction produces visible proof of correctness?
|
|
94
94
|
|
|
95
95
|
## Iteration Limits
|
|
96
96
|
|
|
@@ -130,10 +130,10 @@ For orchestrator-side swarm rules (exclusive lenses, model switching, triage pip
|
|
|
130
130
|
- If no issues, say so explicitly and state what you verified
|
|
131
131
|
- Flag if the scope exceeds the stated intent (scope creep)
|
|
132
132
|
- **!!! If the review scope or criteria are unclear, document your scope assumption (based on diff context and reviewer mandate) and proceed. Do not refuse to review.**
|
|
133
|
-
- **!!!
|
|
134
|
-
- **!!!
|
|
133
|
+
- **!!! Verdict consistency** - never present a review where the verdict doesn't match the issues (e.g., "approved" with critical issues). Re-read your own verdict before reporting back.
|
|
134
|
+
- **!!! Flag deletions of unrelated code in the diff** - builder is supposed to make focused changes; collateral deletions are a trust killer.
|
|
135
135
|
- **Parallelization:** reviewer tasks on different PRs/changes can run in parallel. Two reviewers on the same PR = wasted effort. **Sequential after the builder.**
|
|
136
|
-
- **
|
|
136
|
+
- **Open external repos with `opensrc` (not `webfetch`)** - clone once, read locally. `webfetch` is for single pages only.
|
|
137
137
|
|
|
138
138
|
## Output Format
|
|
139
139
|
|
package/agents/writer.md
CHANGED
|
@@ -119,13 +119,7 @@ You write documentation.
|
|
|
119
119
|
|
|
120
120
|
## Check
|
|
121
121
|
|
|
122
|
-
- **!!! Proofread before finishing**
|
|
123
|
-
-
|
|
124
|
-
- Check that examples are accurate
|
|
125
|
-
- Ensure examples are runnable (not pseudocode)
|
|
126
|
-
- Test code examples if possible
|
|
122
|
+
- **!!! Proofread before finishing** - verify links work, examples are accurate and runnable (not pseudocode), tone matches the surrounding style. Test code examples if possible.
|
|
123
|
+
- **Keep documentation changes focused** - flag deletions of unrelated sections in your own diff.
|
|
127
124
|
- **!!! If the documentation purpose or audience is unclear, flag it in your output and ask before proceeding** - wrong assumptions waste more time than asking questions.
|
|
128
|
-
- **!!! Maker/checker split** - your work is reviewed by `/reviewer` before it lands. The model that wrote the doc is too nice grading its own homework. Produce the doc, do not QA it.
|
|
129
|
-
- **!!! Validate before handoff** - never present a doc you haven't proofread. Verify links work, examples are runnable (not pseudocode), tone matches the surrounding style. Re-read the doc before reporting back.
|
|
130
|
-
- **!!! Don't delete what you didn't create** - flag deletions of unrelated sections in your own diff. Documentation changes should be focused; collateral deletions are a trust killer.
|
|
131
125
|
- **Parallelization:** writer tasks on different documents can run in parallel. Two writers on the same doc = wasted effort. Doc is single-writer.
|
package/dist/extension.mjs
CHANGED
|
@@ -1,17 +1,15 @@
|
|
|
1
|
-
import{existsSync as e,mkdirSync as t,readFileSync as n,writeFileSync as r}from"node:fs";import{dirname as i,join as a}from"node:path";import{fileURLToPath as
|
|
1
|
+
import{existsSync as e,mkdirSync as t,readFileSync as n,writeFileSync as r}from"node:fs";import{dirname as i,join as a,resolve as o}from"node:path";import{fileURLToPath as s}from"node:url";import{homedir as c}from"node:os";import{Type as l}from"typebox";import{SUBAGENT_EVENTS as u}from"@gotgenes/pi-subagents";import{isToolCallEventType as d}from"@earendil-works/pi-coding-agent";function f(){return{mode:null,activeTask:``,completionPromise:``,specialistsDelegated:[],blockers:[],filesModified:[],filesRead:[],handoffHistory:[],reviewMode:!1,originalModel:null,originalTools:null,subagentStatus:{},reviewModel:null}}function p(e,t,n,r){let i=[{from:t,to:n,task:r,timestamp:Date.now()},...e.handoffHistory].slice(0,5);return{...e,handoffHistory:i}}function m(e){return{state:{...e,reviewMode:!1,originalModel:null,originalTools:null},originalModel:e.originalModel,originalTools:e.originalTools}}async function h(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)}function g(e,t){e.appendEntry(`maestria_state`,{...t})}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}}function v(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.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
|
-
`)}const
|
|
4
|
-
|
|
5
|
-
`),blitz:[
|
|
6
|
-
`)
|
|
7
|
-
`)
|
|
8
|
-
`)}}
|
|
9
|
-
`)}]};try{async function n(e,t,n){let r=0,o=l.getRecord(e);for(;o&&!j.has(o.status)&&r<120;){if(i?.aborted)throw Error(`Maestria subagent call aborted`);await new Promise(e=>setTimeout(e,500)),o=l.getRecord(e),r++,n&&a?.({content:[{type:`text`,text:`${t} running... (${Math.round(r*500/1e3)}s)`}]})}if(o&&!j.has(o.status))throw Error(`Subagent ${e} timed out after 60000ms`);if(!o)throw Error(`Subagent ${e} was cleaned up before completion`);return o}if(s===`single`){let i=r.agent,a=r.task,o=l.spawn(i,a,{description:a.slice(0,80),foreground:!0,inheritContext:!0}),s=f(t,`orchestrator`,i,a);Object.assign(t,s),e.appendEntry(`maestria_state`,t);let c=await n(o,`Subagent ${i}`,!0);return{content:[{type:`text`,text:c.result??c.error??`No output.`}],details:{subagentId:o}}}if(s===`parallel`){let i=r.tasks;a?.({content:[{type:`text`,text:`Spawning ${i.length} parallel subagents...`}]});let o=[];for(let e of i){let n=l.spawn(e.agent,e.task,{description:e.task.slice(0,80),foreground:!0,inheritContext:!0});o.push(n);let r=f(t,`orchestrator`,e.agent,e.task);Object.assign(t,r)}e.appendEntry(`maestria_state`,t);let s=await Promise.all(o.map((e,t)=>n(e,`${i[t].agent} (${t+1}/${i.length})`,!1)));a?.({content:[{type:`text`,text:`All ${i.length} parallel subagents completed.`}]});let c=[`## Parallel Results (${i.length} tasks)\n`];for(let e=0;e<i.length;e++){let t=i[e],n=s[e],r=n.result??n.error??`No output.`;c.push(`### ${e+1}: ${t.agent}`),c.push(r)}return{content:[{type:`text`,text:c.join(`
|
|
3
|
+
`)}const y=a(i(s(import.meta.url)),`..`,`agents`),b=a(c(),`.pi`,`agent`,`agents`),x=[`adventurer`,`architect`,`builder`,`diagnose`,`planner`,`reviewer`,`writer`];function S(i){let o=y;if(!e(o)){console.warn(`[maestria] Agents source directory not found:`,o);return}try{t(b,{recursive:!0})}catch{console.warn(`[maestria] Could not create agents directory:`,b);return}let s=0;for(let t of x){let i=a(o,`${t}.md`),c=a(b,`${t}.md`);if(!e(i)){console.warn(`[maestria] Agent source not found: ${t}.md`);continue}if(!e(c))try{r(c,n(i,`utf-8`),`utf-8`),s++}catch(e){console.warn(`[maestria] Failed to deploy agent ${t}:`,e)}}s>0&&console.log(`[maestria] Deployed ${s} specialist agents to ${b}`)}const C=o(i(s(import.meta.url)),`../agents/commands`);function w(e){let t=n(o(C,`${e}.md`),`utf-8`),r=t.indexOf(`## MODE:`);return r===-1?t.replace(/\s+$/,``)+`
|
|
4
|
+
`:t.slice(r).replace(/\s+$/,``)+`
|
|
5
|
+
`}const T=[`fein`,`sonar`,`blitz`],E={fein:w(`fein`),sonar:w(`sonar`),blitz:w(`blitz`)},D={fein:`[MODE: fein]`,sonar:`[MODE: sonar]`,blitz:`[MODE: blitz]`};function O(e){return`${D[e]}\n\n${E[e]}`}function k(e,t){for(let n of T)e.registerCommand(n,{description:`Set workflow mode to ${n}`,handler:async(r,i)=>{if(t.reviewMode&&await h(e,i,t),t.mode=n,g(e,t),r.trim()){let t=[O(n),``,`Run the maestria default pipeline on: ${r}`].join(`
|
|
6
|
+
`);e.sendUserMessage(t,{deliverAs:`steer`})}else i.ui.notify(`Mode set to ${n}. Describe what you'd like to work on.`)}})}function A(e){return(t,n)=>{if(e.mode)return{systemPrompt:[t.systemPrompt,``,O(e.mode),``,`The user has set workflow mode to "${e.mode}". Honor this mode throughout the session until changed via /command.`].join(`
|
|
7
|
+
`)}}}function j(e,t){e.on(`session_before_compact`,e=>({compaction:{summary:v(t),details:{...t},firstKeptEntryId:e.preparation.firstKeptEntryId,tokensBefore:e.preparation.tokensBefore}})),e.on(`session_before_tree`,e=>{if(e.preparation.userWantsSummary)return{summary:{summary:v(t)}}})}const M={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`},N=[`adventurer`,`architect`,`builder`,`diagnose`,`planner`,`reviewer`,`writer`],P=new Set([`completed`,`steered`,`aborted`,`stopped`,`error`]);function F(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`){if(!N.includes(r.agent))throw Error(`Unknown agent: "${r.agent}". Allowed: ${N.join(`, `)}`);if(!r.task||!r.task.trim())throw Error(`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){if(!N.includes(e.agent))throw Error(`Unknown agent: "${e.agent}". Allowed: ${N.join(`, `)}`);if(!e.task||!e.task.trim())throw Error(`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){if(!N.includes(e.agent))throw Error(`Unknown agent: "${e.agent}". Allowed: ${N.join(`, `)}`);if(!e.task||!e.task.trim())throw Error(`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(`
|
|
8
|
+
`)}]};try{async function n(e,t,n){let r=0,o=l.getRecord(e);for(;o&&!P.has(o.status)&&r<120;){if(i?.aborted)throw Error(`Maestria subagent call aborted`);await new Promise(e=>setTimeout(e,500)),o=l.getRecord(e),r++,n&&a?.({content:[{type:`text`,text:`${t} running... (${Math.round(r*500/1e3)}s)`}]})}if(o&&!P.has(o.status))throw Error(`Subagent ${e} timed out after 60000ms`);if(!o)throw Error(`Subagent ${e} was cleaned up before completion`);return o}if(s===`single`){let i=r.agent,a=r.task,o=l.spawn(i,a,{description:a.slice(0,80),foreground:!0,inheritContext:!0}),s=p(t,`orchestrator`,i,a);Object.assign(t,s),e.appendEntry(`maestria_state`,t);let c=await n(o,`Subagent ${i}`,!0);return{content:[{type:`text`,text:c.result??c.error??`No output.`}],details:{subagentId:o}}}if(s===`parallel`){let i=r.tasks;a?.({content:[{type:`text`,text:`Spawning ${i.length} parallel subagents...`}]});let o=[];for(let e of i){let n=l.spawn(e.agent,e.task,{description:e.task.slice(0,80),foreground:!0,inheritContext:!0});o.push(n);let r=p(t,`orchestrator`,e.agent,e.task);Object.assign(t,r)}e.appendEntry(`maestria_state`,t);let s=await Promise.all(o.map((e,t)=>n(e,`${i[t].agent} (${t+1}/${i.length})`,!1)));a?.({content:[{type:`text`,text:`All ${i.length} parallel subagents completed.`}]});let c=[`## Parallel Results (${i.length} tasks)\n`];for(let e=0;e<i.length;e++){let t=i[e],n=s[e],r=n.result??n.error??`No output.`;c.push(`### ${e+1}: ${t.agent}`),c.push(r)}return{content:[{type:`text`,text:c.join(`
|
|
10
9
|
|
|
11
|
-
`)}],details:{subagentIds:o}}}if(s===`chain`){let i=r.tasks,o=``;for(let r=0;r<i.length;r++){let s=i[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}),d=
|
|
12
|
-
`)}]}}}}),e.events){let r=e.events.on(
|
|
13
|
-
`),{deliverAs:`steer`})}}),e.registerCommand(`
|
|
14
|
-
`),{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 m(e,r,t),h(e,t),r.ui.notify(`Restored original model and tools.`),e.events?.emit(k.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(`
|
|
10
|
+
`)}],details:{subagentIds:o}}}if(s===`chain`){let i=r.tasks,o=``;for(let r=0;r<i.length;r++){let s=i[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}),d=p(t,`orchestrator`,s.agent,c);Object.assign(t,d),e.appendEntry(`maestria_state`,t),a?.({content:[{type:`text`,text:`Chain step ${r+1}/${i.length}: ${s.agent} running...`}]});let f=await n(u,`Chain step ${r+1}: ${s.agent}`,!0);o=f.result??f.error??`No output.`,r<i.length-1&&a?.({content:[{type:`text`,text:`Chain step ${r+1}/${i.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(`
|
|
11
|
+
`)}]}}}}),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()},g(e,t),e.events?.emit(M.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()),g(e,t),e.events?.emit(M.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()),g(e,t),e.events?.emit(M.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()}),g(e,t)});n&&n.push(r,i,a,o)}}const I=[`read`,`grep`,`find`,`ls`,`glob`];function L(e,t){e.registerCommand(`maestria-status`,{description:`Show current maestria session state including handoff history`,handler:async(e,n)=>{let r=v(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),g(e,t),t.reviewModel){let n=await _(e,r,t);n&&(r.ui.notify(`Review mode: switched to ${n}`),e.events?.emit(M.REVIEW_ACTIVATED,{originalModel:t.originalModel,reviewModel:n,timestamp:Date.now()}))}e.setActiveTools(I),e.sendUserMessage([`[REVIEW: ${n}]`,``,`Review: ${n}. Use the reviewer prompt template.`,`Read only, no edits, report findings.`].join(`
|
|
12
|
+
`),{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 h(e,r,t),g(e,t),r.ui.notify(`Restored original model and tools.`),e.events?.emit(M.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(`
|
|
15
13
|
`):`(no known problems documented)`,``,`**Success criteria:**`,`(fill in how to verify completion)`,``,`**Next step:**`,`(fill in what happens after this task)`,``,`---`,`Complete the fields above before sending.`].join(`
|
|
16
|
-
`);t.handoffHistory=[{from:`current`,to:`next`,task:i,timestamp:Date.now()},...t.handoffHistory??[]].slice(0,5),
|
|
14
|
+
`);t.handoffHistory=[{from:`current`,to:`next`,task:i,timestamp:Date.now()},...t.handoffHistory??[]].slice(0,5),g(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,g(e,t),r.ui.notify(`Review model set to: ${i}`)}})}const R=[/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 z(e,t){e.on(`tool_call`,async(e,n)=>{if(!(!e||!e.toolName)){if(t.reviewMode&&(d(`edit`,e)||d(`write`,e)||d(`bash`,e)))return{block:!0,reason:`Review mode is active. Report findings, do not edit.`};if(d(`bash`,e)){if(!e.input||typeof e.input!=`object`)return;let t=e.input.command;if(t){for(let e of R)if(e.test(t))return n.hasUI&&await n.ui.confirm(`Dangerous Pattern Detected`,`This command matches a dangerous pattern:\n${t}\nProceed?`)?void 0:{block:!0,reason:`Command matches dangerous pattern: ${e}`}}}}})}function B(e){let t=f(),n=[];k(e,t);let r=A(t);e.on(`before_agent_start`,(e,t)=>r(e,t)),e.on(`session_start`,(e,n)=>{if(S(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}}}),j(e,t),F(e,t,n),L(e,t),e.on(`session_shutdown`,()=>{for(let e of n)e();n.length=0}),z(e,t)}export{B as default};
|
|
17
15
|
//# sourceMappingURL=extension.mjs.map
|