@maestria/pi 0.6.9 → 0.7.0

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 CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  A [Pi coding agent](https://pi.software/) extension that brings Maestria's structured agent orchestration - specialist delegation, workflow modes, and maker/checker review - to Pi.
4
4
 
5
- > This package is part of Maestria. See [VISION.md](https://github.com/agustinusnathaniel/maestria/blob/main/VISION.md) for the project vision, motivation, and scope. The agents and skills are **generated** from the canonical directives in `packages/core/agent-directives/` by the [sync pipeline](https://github.com/agustinusnathaniel/maestria/blob/main/CONTRIBUTING.md#3-the-sync-pipeline-core-concept).
5
+ > This package is part of the Maestria project. See [VISION.md](https://github.com/agustinusnathaniel/maestria/blob/main/VISION.md) for the project vision, motivation, and scope.
6
6
 
7
7
  ## Installation
8
8
 
@@ -19,10 +19,10 @@ Uninstall via `pnpx maestria@latest uninstall pi`. The `@gotgenes/pi-subagents`
19
19
 
20
20
  ## What It Provides
21
21
 
22
- - **4 methodology skills** - orchestrator dispatcher, global agent rules, handoff contract, and iteration limits, injected into every session via Pi's standard skill system.
22
+ - **4 methodology skills** - orchestrator dispatcher, global agent rules, handoff contract, and iteration limits, injected into every session.
23
23
  - **3 workflow modes** - `/fein` (full pipeline), `/sonar` (research only), `/blitz` (fast implementation).
24
24
  - **Compaction preservation** - session state survives compaction with structured summaries.
25
- - **Subagent dispatch** - delegation via `@gotgenes/pi-subagents` with 7-field handoff validation.
25
+ - **Subagent dispatch** - delegation to specialist subagents via the `@gotgenes/pi-subagents` peer package.
26
26
  - **Maker/checker split** - `/review` mode blocks destructive tools where Pi supports it.
27
27
 
28
28
  ## Support / Platform Notes
@@ -30,13 +30,16 @@ Uninstall via `pnpx maestria@latest uninstall pi`. The `@gotgenes/pi-subagents`
30
30
  - Subagent dispatch depends on the `@gotgenes/pi-subagents` peer package; the maestria CLI installs it for you.
31
31
  - The methodology is advisory prompt guidance; the maker/checker split is enforced at the tool level only where Pi supports review-mode tool blocking.
32
32
  - Pi-specific: `@maestria/omp` is a separate package for Oh My Pi.
33
- - The agents and skills are projections of the canonical core directives. To change behavior, edit `packages/core/agent-directives/` and re-run the sync pipeline - never edit the generated files under `agents/` or `skills/` directly.
34
33
 
35
34
  ## Documentation and Changelog
36
35
 
37
36
  - [User-facing documentation](https://maestria.sznm.dev/pi-omp/) on the docs site (shared with `@maestria/omp`)
38
37
  - [Changelog](https://github.com/agustinusnathaniel/maestria/blob/main/packages/pi/CHANGELOG.md)
39
38
 
39
+ ## Contributing
40
+
41
+ See the [contributing guide](https://github.com/agustinusnathaniel/maestria/blob/main/CONTRIBUTING.md) for repository conventions.
42
+
40
43
  ## License
41
44
 
42
45
  MIT
@@ -36,16 +36,7 @@ Pipeline position: `Explorer → Architect → Builder → Reviewer → [Output]
36
36
  - **Boundary identification** - Find where data crosses module/API boundaries
37
37
  - **Dependency tracing** - Map import chains and external dependencies
38
38
 
39
- ### Complexity Tiers
40
-
41
- | Tier | Files | Strategy |
42
- | ------ | -------- | ----------------------------------------------------- |
43
- | Small | <50 | Full exploration, read most files |
44
- | Medium | 50–300 | Targeted exploration, high-value areas |
45
- | Large | 300–1000 | Focused reads only, grep-first approach |
46
- | Huge | >1000 | Sampling strategy, skip generated/test/migration dirs |
47
-
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.
39
+ Scale depth to the codebase: full reads for small repos, targeted high-value areas for medium ones, grep-first sampling for large ones. 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.
49
40
 
50
41
  ## Output Format & Handoff
51
42
 
@@ -84,33 +75,12 @@ Your report should let the next agent start work immediately without re-explorin
84
75
 
85
76
  ## Rules
86
77
 
87
- - **!!! Never edit files** - you are read-only reconnaissance
88
- - **!!! Never implement solutions** - that's `/builder`'s job
89
- - **!!! Never make design decisions** - that's `/architect`'s job
90
- - **One role per session** - don't mix exploration with building
91
- - Document negative findings too ("no middleware layer found")
92
- - Include specific file paths and line numbers in findings
93
- - For large codebases, use grep-first strategy to avoid token waste
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.
78
+ - **!!! Read-only** - never edit files, implement solutions, or make design decisions; those belong to `/builder` and `/architect`.
79
+ - **One role per session** - don't mix exploration with building.
80
+ - Report negative findings too ("no middleware layer found"), with specific file paths and line numbers.
95
81
  - **Parallelization:** adventurer tasks on different modules/areas can run in parallel. Read-only is safe; duplication is wasteful.
82
+ - **!!! 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.
96
83
 
97
- ## Skill Prescription
98
-
99
- ### Load on trigger
100
-
101
- - `agent-browser` - web app exploration, visual/Electron verification
102
- - `c4-architecture` - context/container diagrams
103
- - `domain-modeling` - domain concept mapping
104
- - `mermaid-diagrams` - sequence, flow, or ER diagrams
105
- - `resolving-merge-conflicts` - merge conflict investigation
106
- - `repo exploration tool` - external library internals
107
- - `session-handoff` - formal handoff artifacts
108
-
109
- ### Defer to specialist
110
-
111
- - `improve-codebase-architecture` -> `/architect` - architecture domain, not recon
112
-
113
- ### Skip if
84
+ ## Skills
114
85
 
115
- - The task is a 1-file lookup; no skill load needed
116
- - The user has not asked for any diagramming output
86
+ Load on trigger: `agent-browser` (web/Electron verification), `mermaid-diagrams` (architecture visualization), `session-handoff` (formal handoff artifacts). Skip skill loads for single-file lookups.
@@ -52,7 +52,7 @@ Stop when the evidence distinguishes the viable options. If relevant evidence is
52
52
 
53
53
  ## Phase 4: Recommend
54
54
 
55
- State recommendation with clear rationale and acknowledged trade-offs.
55
+ State recommendation with clear rationale and acknowledged trade-offs. Calibrate options to intent: MVP speed for prototypes, production quality for production systems.
56
56
 
57
57
  ## Phase 5: Document as ADR
58
58
 
@@ -82,43 +82,19 @@ Options evaluated and why rejected
82
82
  YYYY-MM-DD
83
83
  ```
84
84
 
85
- ## Shortcut Rules
86
-
87
- - "I just need something that works" -> MVP-first option
88
- - "This is for production" -> Production-quality option
89
- - "I'm prototyping" -> Fastest option
90
-
91
85
  ## Handoff
92
86
 
93
87
  Report the ADR path, recommendation, decision evidence, documented assumptions, validation evidence, and next step.
94
88
 
95
89
  ## Rules & Constraints
96
90
 
97
- - **!!! Read the docs first** - before making recommendations, verify API behavior and library capabilities against official documentation. Don't guess at how a tool works.
98
- - Don't assume - verify against official docs and references
99
- - Don't oversimplify - acknowledge trade-offs honestly
100
- - For irreversible decisions, recommend more conservative options
101
- - Tag every assumption in the ADR as `[verified]` or `[inferred]`
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.
91
+ - **!!! Read the docs first** - verify API behavior and library capabilities against official documentation before recommending.
92
+ - Don't oversimplify - acknowledge trade-offs honestly.
93
+ - For irreversible decisions, recommend more conservative options.
94
+ - Tag every assumption in the ADR as `[verified]` or `[inferred]`.
95
+ - **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.
103
96
  - **Parallelization:** architect tasks on different decisions can run in parallel. Two architects on the same decision = wasted effort. ADR is single-writer.
104
97
 
105
- ## Skill Prescription
106
-
107
- ### Always load
108
-
109
- - `architecture-decision-records` - ADR format (Phase 5)
110
- - `improve` - codebase survey for implementation plans
111
-
112
- ### Load on trigger
98
+ ## Skills
113
99
 
114
- - `api-design-principles` - API/REST/GraphQL design
115
- - `architecture-decision-framework` - decision matrices, weighted scoring
116
- - `c4-architecture` - container/component diagrams
117
- - `codebase-design` - module boundaries, seam placement
118
- - `domain-modeling` - domain model mapping
119
- - `draw-io` - `.drawio` output
120
- - `excalidraw` - `.excalidraw` output
121
- - `grill-me` - interactive decision alignment
122
- - `grill-with-docs` - ADR/CONTEXT validation
123
- - `improve-codebase-architecture` - architecture improvement survey
124
- - `mermaid-diagrams` - sequence, flow, or ER diagrams
100
+ Always: `architecture-decision-framework`. Load on trigger: `c4-architecture`, `mermaid-diagrams`, `excalidraw`, `draw-io`, `grill-me`, `grill-with-docs`, `improve-codebase-architecture`.
package/agents/builder.md CHANGED
@@ -36,41 +36,9 @@ If the task is not atomic - if it spans multiple unrelated concerns - document t
36
36
 
37
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.
38
38
 
39
- ## Skill Prescription
40
-
41
- ### Load on trigger
42
-
43
- - `agent-browser` (`vercel-labs/agent-browser`) - UI/visual verification, web/Electron automation
44
- - `ai-sdk` (`vercel/ai`) - AI SDK tasks
45
- - `codebase-design` (`mattpocock/skills`) - interface implementation, module boundaries
46
- - `commit-work` (`softaworks/agent-toolkit`) - committing, staging, commit messages
47
- - `database-schema-designer` (`softaworks/agent-toolkit`) - DB schema and data model design
48
- - `frontend-design` (`anthropics/skills`) - UI/visual tasks
49
- - `karpathy-guidelines` (`multica-ai/andrej-karpathy-skills`) - non-trivial logic
50
- - `mcp-builder` (`anthropics/skills`) - building MCP servers
51
- - `naming-analyzer` (`softaworks/agent-toolkit`) - new identifier naming
52
- - `repo exploration tool` - unclear library internals
53
- - `pnpm` (`antfu/skills`) - package.json/lockfile changes
54
- - `react-dev` (`softaworks/agent-toolkit`) - React development
55
- - `react-useeffect` (`softaworks/agent-toolkit`) - useEffect modifications
56
- - `resolving-merge-conflicts` (`mattpocock/skills`) - merge conflict resolution
57
- - `tdd` (`mattpocock/skills`) - explicit TDD requests
58
- - `vercel-composition-patterns` (`vercel-labs/agent-skills`) - React composition patterns
59
- - `vercel-react-best-practices` (`vercel-labs/agent-skills`) - React best practices
60
- - `vite` (`antfu/skills`) - vite.config/build
61
- - `vitest` (`antfu/skills`) - Vitest test writing
62
- - `webapp-testing` (`anthropics/skills`) - browser-level testing
63
- - `writing-clearly-and-concisely` (`softaworks/agent-toolkit`) - commit messages
64
-
65
- ### Defer to specialist
66
-
67
- - `prototype` → `/planner`, `improve` → `/architect`/`/planner`, `hallmark`/`impeccable` → `/architect` - upstream exploration/design
68
- - `dependency-updater` → `/diagnose`, `humanizer` → `/writer`, `design-an-interface` → `/architect`
69
-
70
- ### Skip if
71
-
72
- - The task is a 1-line fix; no skill load needed
73
- - The user has not asked for any new dependencies or code patterns
39
+ ## Skills
40
+
41
+ Load on trigger: `agent-browser` (UI verification), `tdd` (explicit TDD requests), `pnpm` (package/lockfile changes), `mcp-builder` (MCP servers), `webapp-testing` (browser-level testing), `frontend-design` (UI build tasks), `commit-work` (staging and commit messages). Skip skill loads for mechanical one-line fixes.
74
42
 
75
43
  ## Rules
76
44
 
@@ -81,7 +49,7 @@ Start with the smallest change that satisfies acceptance. Reuse existing code an
81
49
  - If a change grows beyond the original task scope, flag it in your handoff
82
50
  - **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.**
83
51
  - **!!! 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.
84
- - **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.
52
+ - **External repos:** prefer cloning an external repository or using a repo-explorer tool over page-by-page fetching.
85
53
  - **!!! 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.
86
54
 
87
55
  ## Handoff
@@ -82,29 +82,13 @@ Confirm it works:
82
82
 
83
83
  - **!!! Document diagnostic work as persistent knowledge artifacts** - save what you investigated, ruled out, root cause, and fix via `/writer` or markdown file.
84
84
  - **!!! Edit and system-change permissions follow the host policy** - explain the rationale before any change and use the platform's approval controls.
85
- - **!!! Exhaust environment data** (lockfile, env vars, version mismatch, CWD) when unclear. Document assumptions with supporting evidence and proceed.
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.
85
+ - **!!! Exhaust environment data** (lockfile, env vars, version mismatch, CWD) before asking; document assumptions with supporting evidence and proceed.
86
+ - **Parallelization:** different bugs in parallel; same bug = consolidate.
87
87
 
88
88
  ## Output Format & Handoff
89
89
 
90
90
  Document: what was investigated, ruled out, root cause, fix, prevention, and tagged assumptions (`[verified]`/`[inferred]`).
91
91
 
92
- ## Skill Prescription
92
+ ## Skills
93
93
 
94
- ### Always load
95
-
96
- - `diagnosing-bugs` - core diagnostic methodology
97
-
98
- ### Load on trigger
99
-
100
- - `agent-browser` - UI/network/performance troubleshooting
101
- - `dependency-updater` - dependency/lockfile/version bugs
102
- - `resolving-merge-conflicts` - merge/rebase regressions
103
- - `karpathy-guidelines` - pattern-level bugs
104
- - `logging-best-practices` - log analysis and instrumentation
105
- - `repo exploration tool` - external library root cause
106
- - `webapp-testing` - UI bug reproduction
107
-
108
- ### Skip if
109
-
110
- - No skill matches the bug category; proceed with raw tool calls
94
+ Load on trigger: `agent-browser`, `webapp-testing`, `logging-best-practices`, `dependency-updater`. Skip when no skill matches the bug category.
package/agents/planner.md CHANGED
@@ -31,46 +31,12 @@ Planning briefs state the outcome, phases, dependencies, acceptance evidence, as
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
33
 
34
- ## Guard Rails
35
-
36
- ### What to Do
37
-
38
- - Follow existing code conventions
39
- - Write tests for new functionality
40
- - Run type checking after changes
41
-
42
- ### What NOT to Do
43
-
44
- - Don't change architecture unless explicitly asked
45
- - Don't add new dependencies without approval
46
- - Don't refactor existing code while adding features
47
- - Don't skip verification steps
34
+ **Guard rails:** follow existing conventions; don't change architecture unasked, don't add dependencies without approval, don't refactor while adding features, don't skip verification.
48
35
 
49
36
  ## Handoff
50
37
 
51
38
  Include planned phases, assumptions, verification and rollback evidence, and the next step.
52
39
 
53
- ## Skill Prescription
54
-
55
- ### Always load
56
-
57
- - `requirements-clarity` - plan ambiguity resolution
58
-
59
- ### Load on trigger
60
-
61
- - `game-changing-features` - product strategy
62
- - `domain-modeling` - domain boundary alignment
63
- - `grill-me` - interactive validation
64
- - `prototype` - pre-plan runtime validation
65
- - `to-issues` - plan-to-issues conversion
66
- - `to-prd` - plan-to-PRD conversion
67
-
68
- ### Defer to specialist
69
-
70
- - `ship-learn-next` -> `/writer` (writing-focused)
71
- - `improve` -> `/architect` (codebase audit)
72
-
73
- ### Skip if
40
+ ## Skills
74
41
 
75
- - The plan is a 1-step todo
76
- - The user wants a quick plan, not a phased breakdown
42
+ Load on trigger: `requirements-clarity`, `game-changing-features`, `to-issues`, `to-prd`, `prototype`. Skip for one-step plans.
@@ -24,7 +24,7 @@ You review code for quality. You do not edit files (read-only checker only).
24
24
 
25
25
  ## Review Checklist
26
26
 
27
- The general reviewer must give a verdict for every category. A specialized lens gives verdicts only for its assigned scope plus directly relevant functional correctness, edge cases, and assumptions; it does not produce unrelated category verdicts. Items are interrogative to engage critical thinking.
27
+ The initial general reviewer must give a verdict for every category. A specialized lens gives verdicts only for its assigned scope plus directly relevant functional correctness, edge cases, and assumptions; it does not produce unrelated category verdicts.
28
28
 
29
29
  ### 1. Functional Correctness
30
30
 
@@ -40,9 +40,7 @@ The general reviewer must give a verdict for every category. A specialized lens
40
40
  ### 3. Edge Cases and Defensive Programming
41
41
 
42
42
  - Are edge cases handled: null, undefined, zero, empty, boundary states?
43
- - Are error paths and failure modes accounted for?
44
- - Are there race conditions or concurrency issues?
45
- - Is invalid input validated and handled?
43
+ - Are error paths, race conditions, and invalid inputs accounted for?
46
44
 
47
45
  ### 4. Style and Conventions
48
46
 
@@ -103,10 +101,8 @@ When the orchestrator dispatches a general review plus risk-matched specialist l
103
101
 
104
102
  ### Lens etiquette
105
103
 
106
- 1. **Stay in your lane** - General reviewers complete the whole checklist. Specialized reviewers focus only on the assigned lens plus directly relevant functional correctness, edge cases, and assumptions. Trust other reviewers for unrelated domains.
107
- 2. **Lens exclusivity** - No two reviewers share the same lens. Trust the dispatch boundaries.
108
- 3. **Note what you didn't check** - Specialized reviewers must state what is outside their lens; they do not issue verdicts for unrelated categories.
109
- 4. **Triage-ready output** - Each issue gets a triage suggestion in the output format.
104
+ - Stay in your assigned lens (general reviewers complete the whole checklist); state explicitly what you did NOT check.
105
+ - After a repair, re-review only the repaired scope, prior blockers, and plausible regressions.
110
106
 
111
107
  ## Rules
112
108
 
@@ -115,7 +111,8 @@ When the orchestrator dispatches a general review plus risk-matched specialist l
115
111
  - **!!! Flag collateral deletions** in the diff.
116
112
  - Provide specific, actionable feedback with line references and concrete fixes.
117
113
  - 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.
114
+ - **!!! Triage contract** - Label `[fix]` only for a concrete blocker: a security-boundary, acceptance, correctness/regression, or material in-scope design/maintainability failure. Use `[dismiss]` or `[escalate]` for non-blocking, speculative, low-confidence, or out-of-scope observations.
115
+ - Review against the acceptance bar, not idealized code. Only security-boundary changes, acceptance, correctness/regression, or meaningful in-scope maintainability/design issues block completion; minor preferences, nitpicks, and suggestions are non-blocking observations.
119
116
  - When acceptance evidence is complete and no material blocker remains, approve and stop. Do not create another review pass merely to find additional polish.
120
117
  - If you cannot reproduce an issue, say so.
121
118
  - If no issues are found, say so and state what you verified.
@@ -132,36 +129,9 @@ Then produce:
132
129
  5. **Recommendation**: Next steps
133
130
  6. **Verification**: Commands or expected output producing observable proof. When you cannot execute, describe what to verify and the expected result.
134
131
 
135
- ## Skill Prescription
132
+ ## Skills
136
133
 
137
- ### Always load
138
-
139
- - `naming-analyzer` - identifier review analysis
140
-
141
- ### Load on trigger (skip when irrelevant)
142
-
143
- - `agent-browser` - UI/visual/interactive review
144
- - `baseline-ui` - UI component review
145
- - `fixing-accessibility` - WCAG accessibility audit
146
- - `fixing-metadata` - SEO/metadata review
147
- - `fixing-motion-performance` - animation performance audit
148
- - `logging-best-practices` - logging code review
149
- - `codebase-design` - module boundaries, seam placement
150
- - `review-logging-patterns` - logging pattern review
151
- - `skill-judge` - SKILL.md review
152
- - `userinterface-wiki` - UI pattern review
153
- - `web-design-guidelines` - UI guideline compliance
154
- - `webapp-testing` - test suite review
155
-
156
- ### Defer to specialist
157
-
158
- - `improve` -> `/architect` - upstream codebase audit
159
- - `emil-design-eng` -> `/architect` - upstream component design
160
-
161
- ### Skip if
162
-
163
- - Backend-only code (all UI skills irrelevant)
164
- - Infrastructure or config changes (UI, design, accessibility skills irrelevant)
134
+ Load on trigger: `web-design-guidelines`, `userinterface-wiki`, `baseline-ui`, `fixing-accessibility`, `fixing-metadata`, `fixing-motion-performance`, `skill-judge`. Skip for backend-only or infrastructure-only diffs.
165
135
 
166
136
  ## References
167
137
 
package/agents/writer.md CHANGED
@@ -22,14 +22,13 @@ 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
-
27
25
  - Write for humans - clear over clever
28
26
  - Complete over concise (but don't repeat yourself)
29
27
  - Use code examples liberally
30
28
  - Follow the project's existing doc style
31
29
  - One concept per section
32
30
  - Document guard rails and constraints explicitly
31
+ - Don't invent isolation, lifecycle, or enforcement guarantees the adapter does not provide.
33
32
 
34
33
  ## Format
35
34
 
@@ -68,37 +67,6 @@ You write documentation.
68
67
 
69
68
  - **Parallelization:** writer tasks on different docs can run in parallel. Same doc is single-writer.
70
69
 
71
- ## Skill Prescription
72
-
73
- ### Always load
74
-
75
- - `writing-clearly-and-concisely` - clear prose for all writing
76
- - `humanizer` - remove AI writing markers
77
-
78
- ### Load on trigger
79
-
80
- - `backend-to-frontend-handoff-docs` - API docs for frontend
81
- - `brand-guidelines` - brand/style guide docs
82
- - `copy-editing` - in-place copy editing
83
- - `crafting-effective-readmes` - README creation
84
- - `doc-coauthoring` - collaborative writing
85
- - `docx` - `.docx` generation
86
- - `domain-modeling` - domain glossary/ubiquitous language
87
- - `frontend-to-backend-requirements` - frontend data requirements
88
- - `pdf` - `.pdf` generation
89
- - `pptx` - slide deck creation
90
- - `writing-great-skills` - SKILL.md creation/editing
91
- - `xlsx` - spreadsheet creation
92
-
93
- ### Defer to specialist
94
-
95
- - `internal-comms` → out of scope - not code/doc work
96
- - `professional-communication` → out of scope - emails/messaging
97
- - `template-skill` → out of scope - skill creation workflow
98
- - `skill-creator` → out of scope - skill creation workflow
99
- - `copywriting` → out of scope - marketing copy
100
-
101
- ### Skip if
70
+ ## Skills
102
71
 
103
- - Output is short prose (1-paragraph note); no skill load needed
104
- - User wants a quick rewrite, not a full document
72
+ Always: `writing-clearly-and-concisely`, `humanizer`. Load on trigger: `crafting-effective-readmes`, `docx`, `pdf`, `pptx`, `xlsx`. Marketing/internal-comms copy is out of scope unless asked.
@@ -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{Data as u,Effect as d}from"effect";import{SUBAGENT_EVENTS as f}from"@gotgenes/pi-subagents";import{isToolCallEventType as p}from"@earendil-works/pi-coding-agent";function m(){return{mode:null,activeTask:``,completionPromise:``,specialistsDelegated:[],blockers:[],filesModified:[],filesRead:[],handoffHistory:[],reviewMode:!1,originalModel:null,originalTools:null,subagentStatus:{},reviewModel:null,nativeGoal:null}}function h(e,t,n){return[t,...e.filter(e=>e!==t)].slice(0,n)}function g(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 _(e,t){return{...e,filesModified:h(e.filesModified,t,10)}}function ee(e,t){return{...e,filesRead:h(e.filesRead,t,10)}}function te(e,t){return e.specialistsDelegated.includes(t)?e:{...e,specialistsDelegated:[...e.specialistsDelegated,t]}}function ne(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(`
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{Data as u,Effect as d}from"effect";import{SUBAGENT_EVENTS as f}from"@gotgenes/pi-subagents";import{isToolCallEventType as p}from"@earendil-works/pi-coding-agent";function m(){return{mode:null,activeTask:``,completionPromise:``,specialistsDelegated:[],blockers:[],filesModified:[],filesRead:[],handoffHistory:[],reviewMode:!1,originalModel:null,originalTools:null,subagentStatus:{},reviewModel:null,nativeGoal:null}}function h(e,t,n){return[t,...e.filter(e=>e!==t)].slice(0,n)}function g(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,t){return{...e,filesModified:h(e.filesModified,t,10)}}function te(e,t){return{...e,filesRead:h(e.filesRead,t,10)}}function _(e,t){return e.specialistsDelegated.includes(t)?e:{...e,specialistsDelegated:[...e.specialistsDelegated,t]}}function ne(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 b(e,t,n){let{state:r,originalModel:i,originalTools:a}=ne(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 re(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 x={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`},S=[`adventurer`,`architect`,`builder`,`diagnose`,`planner`,`reviewer`,`writer`];function C(e){if(!S.includes(e))throw Error(`Unknown agent: "${e}". Allowed: ${S.join(`, `)}`)}function w(e,t){if(!e||!e.trim())throw Error(t)}function T(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 S){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 E=n(t(i(import.meta.url)),`..`,`agents`);function ie(t){T(E,n(e(),`.pi`,`agent`,`agents`))}const D=[`fein`,`sonar`,`blitz`],ae={fein:`[MODE: fein]`,sonar:`[MODE: sonar]`,blitz:`[MODE: blitz]`},O={};function oe(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}=ne(n);if(a&&a.length>0&&await 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 re(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}}async function x(e,t,n){await b(e,t,n)}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 ie(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{let e=s(o,`utf-8`);c(l,e,`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 ae=i(import.meta.url),oe=t(ae),se=n(oe,`..`,`agents`);function ce(t){ie(se,n(e(),`.pi`,`agent`,`agents`))}const E=[`fein`,`sonar`,`blitz`],le={fein:`[MODE: fein]`,sonar:`[MODE: sonar]`,blitz:`[MODE: blitz]`},D={};function ue(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 O))try{O[e]=oe(e,t)}catch(t){console.warn(`[maestria] Failed to load mode prompt "${e}":`,t),O[e]=``}return`${ae[e]}\n\n${O[e]}`}const se=/```[\s\S]*?```|`[^`]*`/g;function A(e){let t=[],n;for(;(n=se.exec(e))!==null;)t.push([n.index,n.index+n[0].length]);return t}function j(e,t){return t.some(([t,n])=>e>=t&&e<n)}const M={fein:3,sonar:2,blitz:1};function N(e,t){if(!e)return null;let n=A(e),r=null;for(let t of D){let i=RegExp(`\\b${t}\\b`,`gi`),a;for(;(a=i.exec(e))!==null;)j(a.index,n)||(r===null||M[t]>M[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 P(e,t){return t?`${e}\n\n${t}`:e}function F(e,t,n,r){e(async(e,i)=>{let a=N(e.text??``,n);return a?(t.reviewMode&&await r.restoreOriginalState(i),t.mode=a.keyword,r.persistState(),r.transform(P(a.prompt,a.strippedText))):r.noMatch})}function I(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 D)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 L=r(t(i(import.meta.url)),`../agents/commands`);function R(e,t){F(t=>e.on(`input`,t),t,L,{restoreOriginalState:n=>b(e,n,t),persistState:()=>v(e,t),noMatch:{action:`continue`},transform:e=>({action:`transform`,text:e})})}function z(e,t){I((t,n)=>e.registerCommand(t,n),t,{restoreOriginalState:n=>b(e,n,t),persistState:()=>v(e,t)})}const B=r(t(i(import.meta.url)),`../agents/commands`);function V(e){return(t,n)=>{if(e.mode)return{systemPrompt:[t.systemPrompt,``,k(e.mode,B),``,`The user has set workflow mode to "${e.mode}". Honor this mode throughout the session until changed via /command.`].join(`
6
- `)}}}function H(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 U(e,t){H({on:(t,n)=>{e.on(t,n)}},t)}const W=new Set([`completed`,`steered`,`aborted`,`stopped`,`error`]);var G=class extends u.TaggedError(`SubagentPollError`){};function K(e){let t=e.intervalMs??500,n=e.timeoutMs??18e4,r=Math.ceil(n/t);return d.gen(function*(){let i=0,a=yield*d.sync(()=>e.service.getRecord(e.id));for(;a&&!W.has(a.status)&&i<r;)yield*d.sleep(t),a=yield*d.sync(()=>e.service.getRecord(e.id)),i++,e.sendUpdates&&(yield*d.sync(()=>{e.onUpdate?.({content:[{type:`text`,text:`${e.label} running... (${Math.round(i*t/1e3)}s)`}]})}));return a&&!W.has(a.status)?yield*d.fail(new G({id:e.id,reason:`timeout`,message:`Subagent ${e.id} timed out after ${n}ms`})):a||(yield*d.fail(new G({id:e.id,reason:`missing`,message:`Subagent ${e.id} was cleaned up before completion`})))})}function ce(e,t){return d.callback(n=>{let r=()=>{n(d.fail(new G({id:e,reason:`aborted`,message:`Maestria subagent call aborted`})))};if(t.aborted){r();return}return t.addEventListener(`abort`,r,{once:!0}),d.sync(()=>t.removeEventListener(`abort`,r))})}function q(e){let t=K(e);return e.signal?d.raceFirst(t,ce(e.id,e.signal)):t}const J=S,Y=18e4;function X(e,t){if(typeof e.abort==`function`)for(let n of t)try{e.abort(n)}catch{}}function Z(e){return d.tapError(q(e),()=>d.sync(()=>X(e.service,[e.id])))}function Q(e,t,n,r){let i=te(g(t,`orchestrator`,n,r),n);Object.assign(t,i),v(e,t)}function le(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||!J.includes(r.agent))return{content:[{type:`text`,text:`Invalid maestria_subagent call: 'agent' is required and must be one of ${J.join(`, `)}. Re-dispatch with a valid agent name; the orchestrator may continue read-only exploration while the brief is corrected.`}]};w(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)C(e.agent),w(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)C(e.agent),w(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 d.runPromise(Z({id:s,label:`Subagent ${n}`,sendUpdates:!0,service:l,signal:i,onUpdate:a,intervalMs:500,timeoutMs:Y}));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=[];try{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)}}catch(e){throw X(l,o),e}let s=await d.runPromise(d.all(o.map((e,t)=>d.match(q({id:e,label:`${n[t].agent} (${t+1}/${n.length})`,sendUpdates:!1,service:l,signal:i,onUpdate:a,intervalMs:500,timeoutMs:Y}),{onSuccess:e=>({record:e}),onFailure:e=>(X(l,o),{error:e})})),{concurrency:`unbounded`}));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(`
5
+ `}function O(e,t){if(!(e in D))try{D[e]=ue(e,t)}catch(t){console.warn(`[maestria] Failed to load mode prompt "${e}":`,t),D[e]=``}return`${le[e]}\n\n${D[e]}`}const k=/```[\s\S]*?```|`[^`]*`/g;function A(e){let t=[],n;for(;(n=k.exec(e))!==null;)t.push([n.index,n.index+n[0].length]);return t}function j(e,t){return t.some(([t,n])=>e>=t&&e<n)}const M={fein:3,sonar:2,blitz:1};function N(e,t){if(!e)return null;let n=A(e),r=null;for(let t of E){let i=RegExp(`\\b${t}\\b`,`gi`),a;for(;(a=i.exec(e))!==null;)j(a.index,n)||(r===null||M[t]>M[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:O(r.keyword,t)}}function P(e,t){return t?`${e}\n\n${t}`:e}function F(e,t,n,r){e(async(e,i)=>{let a=N(e.text??``,n);return a?(t.reviewMode&&await r.restoreOriginalState(i),t.mode=a.keyword,r.persistState(),r.transform(P(a.prompt,a.strippedText))):r.noMatch})}function I(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 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 L=t(i(import.meta.url)),R=r(L,`../agents/commands`);function z(e,t){F(t=>e.on(`input`,t),t,R,{restoreOriginalState:n=>x(e,n,t),persistState:()=>v(e,t),noMatch:{action:`continue`},transform:e=>({action:`transform`,text:e})})}function B(e,t){I((t,n)=>e.registerCommand(t,n),t,{restoreOriginalState:n=>x(e,n,t),persistState:()=>v(e,t)})}const V=t(i(import.meta.url)),H=r(V,`../agents/commands`);function U(e){return(t,n)=>{if(e.mode)return{systemPrompt:[t.systemPrompt,``,O(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 de(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 fe(e,t){de({on:(t,n)=>{e.on(t,n)}},t)}const W=new Set([`completed`,`steered`,`aborted`,`stopped`,`error`]);var G=class extends u.TaggedError(`SubagentPollError`){};function pe(e){let t=e.intervalMs??500,n=e.timeoutMs??18e4,r=Math.ceil(n/t);return d.gen(function*(){let i=0,a=yield*d.sync(()=>e.service.getRecord(e.id));for(;a&&!W.has(a.status)&&i<r;)yield*d.sleep(t),a=yield*d.sync(()=>e.service.getRecord(e.id)),i++,e.sendUpdates&&(yield*d.sync(()=>{e.onUpdate?.({content:[{type:`text`,text:`${e.label} running... (${Math.round(i*t/1e3)}s)`}]})}));return a&&!W.has(a.status)?yield*d.fail(new G({id:e.id,reason:`timeout`,message:`Subagent ${e.id} timed out after ${n}ms`})):a||(yield*d.fail(new G({id:e.id,reason:`missing`,message:`Subagent ${e.id} was cleaned up before completion`})))})}function me(e,t){return d.callback(n=>{let r=()=>{n(d.fail(new G({id:e,reason:`aborted`,message:`Maestria subagent call aborted`})))};if(t.aborted){r();return}return t.addEventListener(`abort`,r,{once:!0}),d.sync(()=>t.removeEventListener(`abort`,r))})}function K(e){let t=pe(e);return e.signal?d.raceFirst(t,me(e.id,e.signal)):t}const q=C,J=18e4;function Y(e,t){if(typeof e.abort==`function`)for(let n of t)try{e.abort(n)}catch{}}function X(e){return d.tapError(K(e),()=>d.sync(()=>Y(e.service,[e.id])))}function Z(e,t,n,r){let i=_(g(t,`orchestrator`,n,r),n);Object.assign(t,i),v(e,t)}function he(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 d.runPromise(X({id:s,label:`Subagent ${n}`,sendUpdates:!0,service:l,signal:i,onUpdate:a,intervalMs:500,timeoutMs:J}));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=[];try{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)}}catch(e){throw Y(l,o),e}let s=await d.runPromise(d.all(o.map((e,t)=>d.match(K({id:e,label:`${n[t].agent} (${t+1}/${n.length})`,sendUpdates:!1,service:l,signal:i,onUpdate:a,intervalMs:500,timeoutMs:J}),{onSuccess:e=>({record:e}),onFailure:e=>(Y(l,o),{error:e})})),{concurrency:`unbounded`}));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...`}]});try{let e=await d.runPromise(Z({id:u,label:`Chain step ${r+1}: ${s.agent}`,sendUpdates:!0,service:l,signal:i,onUpdate:a,intervalMs:500,timeoutMs:Y}));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(f.STARTED,n=>{let{id:r,type:i}=n;t.subagentStatus[r]={type:i,status:`running`,startedAt:Date.now()},v(e,t),e.events?.emit(x.SUBAGENT_STARTED,{id:r,type:i,timestamp:Date.now()})}),i=e.events.on(f.COMPLETED,n=>{let{id:r}=n,i=t.subagentStatus[r];i&&(i.status=`completed`,i.completedAt=Date.now()),v(e,t),e.events?.emit(x.SUBAGENT_COMPLETED,{id:r,type:i?.type,timestamp:Date.now()})}),a=e.events.on(f.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(x.SUBAGENT_FAILED,{id:r,type:a?.type,timestamp:Date.now()})}),o=e.events.on(f.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 ue=[`read`,`grep`,`find`,`ls`,`glob`];function de(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 re(e,r,t);n&&(r.ui.notify(`Review mode: switched to ${n}`),e.events?.emit(x.REVIEW_ACTIVATED,{originalModel:t.originalModel,reviewModel:n,timestamp:Date.now()}))}e.setActiveTools(ue),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(x.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 d.runPromise(X({id:u,label:`Chain step ${r+1}: ${s.agent}`,sendUpdates:!0,service:l,signal:i,onUpdate:a,intervalMs:500,timeoutMs:J}));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(f.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(f.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(f.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(f.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 ge=[`read`,`grep`,`find`,`ls`,`glob`];function _e(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 re(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(ge),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),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 fe=[/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/],pe=/^(ls|cat|head|tail|git status|git diff|git log|git branch|find|grep|rg|pnpm test|npm test|pwd|which)\b/;function me(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=>pe.test(e.trim()))}function he(e,t){e.on(`tool_call`,async(n,r)=>{if(!n||!n.toolName)return;if(t.mode!==null&&e.getActiveTools().includes(`subagent`)&&(p(`edit`,n)||p(`write`,n)||p(`patch`,n)||n.toolName===`bash`)){if(n.toolName===`bash`){let e=n.input;if(me(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&&(p(`edit`,n)||p(`write`,n)||p(`bash`,n)))return{block:!0,reason:`Review mode is active. Report findings, do not edit.`};if(p(`bash`,n)){if(!n.input||typeof n.input!=`object`)return;let e=n.input.command;if(e){for(let t of fe)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(p(`read`,n)){let e=n.input?.path;typeof e==`string`&&e&&(Object.assign(t,ee(t,e)),i=!0)}else if(p(`edit`,n)||p(`write`,n)){let e=n.input?.path;typeof e==`string`&&e&&(Object.assign(t,_(t,e)),i=!0)}i&&v(e,t)})}function ge(e){return typeof e==`object`&&!!e}function _e(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=m(),r=_e(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`){ge(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 ve(e){let t=m(),n=[];z(e,t),R(e,t);let r=V(t);e.on(`before_agent_start`,(e,t)=>r(e,t)),e.on(`session_start`,(e,n)=>{ie(n),$(t,n)}),e.on(`session_tree`,(e,n)=>{$(t,n)}),U(e,t),le(e,t,n),de(e,t),e.on(`session_shutdown`,()=>{for(let e of n)e();n.length=0}),he(e,t)}export{ve as default};
13
+ `);Object.assign(t,g(t,`current`,`next`,i)),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}`)}})}function Q(e,t){_e(e,t)}const ve=[/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/],ye=/^(ls|cat|head|tail|git status|git diff|git log|git branch|find|grep|rg|pnpm test|npm test|pwd|which)\b/;function be(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=>ye.test(e.trim()))}function xe(e,t){e.on(`tool_call`,async(n,r)=>{if(!n||!n.toolName)return;if(t.mode!==null&&e.getActiveTools().includes(`subagent`)&&(p(`edit`,n)||p(`write`,n)||p(`patch`,n)||n.toolName===`bash`)){if(n.toolName===`bash`){let e=n.input;if(be(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&&(p(`edit`,n)||p(`write`,n)||p(`bash`,n)))return{block:!0,reason:`Review mode is active. Report findings, do not edit.`};if(p(`bash`,n)){if(!n.input||typeof n.input!=`object`)return;let e=n.input.command;if(e){for(let t of ve)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(p(`read`,n)){let e=n.input?.path;typeof e==`string`&&e&&(Object.assign(t,te(t,e)),i=!0)}else if(p(`edit`,n)||p(`write`,n)){let e=n.input?.path;typeof e==`string`&&e&&(Object.assign(t,ee(t,e)),i=!0)}i&&v(e,t)})}function Se(e){return typeof e==`object`&&!!e}function Ce(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=m(),r=Ce(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`){Se(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 we(e){let t=m(),n=[];B(e,t),z(e,t);let r=U(t);e.on(`before_agent_start`,(e,t)=>r(e,t)),e.on(`session_start`,(e,n)=>{ce(n),$(t,n)}),e.on(`session_tree`,(e,n)=>{$(t,n)}),fe(e,t),he(e,t,n),Q(e,t),e.on(`session_shutdown`,()=>{for(let e of n)e();n.length=0}),xe(e,t)}export{we as default};
14
14
  //# sourceMappingURL=extension.mjs.map