@maestria/opencode 0.7.12 → 0.7.13
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 +6 -1
- package/agents/orchestrator.md +4 -11
- package/agents/planner.md +1 -1
- package/agents/reviewer.md +5 -1
- package/dist/index.js +3 -2
- package/package.json +2 -1
- package/rules/AGENTS.md +3 -23
package/README.md
CHANGED
|
@@ -18,10 +18,15 @@ OpenCode does not auto-update plugins; re-run the install command with `--force`
|
|
|
18
18
|
|
|
19
19
|
## What It Provides
|
|
20
20
|
|
|
21
|
-
- **8 agents
|
|
21
|
+
- **Agents** (8 as of 2026-09-22; see the [package directory](https://github.com/agustinusnathaniel/maestria/blob/main/packages/opencode/agents) for the current list) - `@orchestrator` (delegates to the 7 specialists) plus `@adventurer`, `@architect`, `@builder`, `@diagnose`, `@planner`, `@reviewer`, and `@writer`.
|
|
22
22
|
- **Global rules** - shared requirements injected into every session for evidence, safety, delegation, review, and bounded repair.
|
|
23
|
+
- **Project customization** - when the project root contains `.maestria/workflow.md` or `.maestria/rules.md`, the full content of each file that exists is injected fresh on every model call in deterministic order (workflow first, then rules). Projects without these files see no behavior change.
|
|
23
24
|
- **Zero plugin telemetry** - the plugin makes no network calls of its own.
|
|
24
25
|
|
|
26
|
+
## Project Customization Details
|
|
27
|
+
|
|
28
|
+
The project root resolves from the SDK project worktree, then the worktree path, then the session directory; a `/` sentinel is skipped so a non-git open directory still resolves. Only the project root is read; no nested or ancestor lookup applies. Files are read fresh on every model call through `experimental.chat.system.transform`, so edits apply on the next call with no restart and no stale snapshot. The same pipeline covers primary and subagent calls, including calls after compaction; a compaction note also asks the summary to preserve active project constraints. This path is separate from `config.instructions`: the pinned host file loader swallows read failures to empty and plugin init/config errors are swallowed, while a transform error here propagates as a failed model call instead of running with silently absent config (verified against pinned host v1.18.31 by source inspection plus package tests, no live model run). A project file that exists but cannot be used (directory, special file, unreadable, unresolvable, or a link resolving outside the root) fails the call loudly instead of being skipped. Diagnostics name only the relative file and the failure kind; symlink targets are canonicalized against the root and the resolved target must be a regular file. Checks observe the filesystem at call time and are not an atomic snapshot. Loaded project guidance stays subordinate: it may replace configurable workflows but never waives safety, authorization, or host permissions.
|
|
29
|
+
|
|
25
30
|
## Support / Platform Notes
|
|
26
31
|
|
|
27
32
|
- OpenCode-specific; Kimi Code, Hermes, Cursor, and other adaptations ship as separate `@maestria` packages.
|
package/agents/orchestrator.md
CHANGED
|
@@ -78,7 +78,9 @@ Approve when acceptance evidence is complete and no blocking/material finding re
|
|
|
78
78
|
|
|
79
79
|
## Workflow and Delegation
|
|
80
80
|
|
|
81
|
-
When
|
|
81
|
+
When the host has not already supplied them, load project-root `.maestria/workflow.md` then `.maestria/rules.md` using host tools (root only). Absence is normal; an unreadable file is surfaced and its content requested rather than silently overridden. Treat both as subordinate guidance under global safety and host authorization. Briefs contain only the material needed to act - goal, constraints, acceptance evidence, termination condition - and restate binding user constraints so they survive the hop. Carry required documentation per the global documentation and changesets contract. Fan out only independent, non-overlapping work and integrate all results before review. If the user rejects an approach twice, stop and re-evaluate. Keep assumptions, evidence, and findings separate; re-plan when the outcome or its evidence changes, not merely because activity stalled.
|
|
82
|
+
|
|
83
|
+
Load the available `spec-contract` skill only when persistent intent across steps would reduce risk; absence is normal.
|
|
82
84
|
|
|
83
85
|
## Mode Precedence
|
|
84
86
|
|
|
@@ -119,13 +121,4 @@ Report briefly at milestones: outcome, verification limits, delivery state, and
|
|
|
119
121
|
|
|
120
122
|
## Visual Delivery Evidence
|
|
121
123
|
|
|
122
|
-
For changes to rendered UI, including documentation sites and visible CLI output,
|
|
123
|
-
|
|
124
|
-
- Capture the affected screen or interaction, including relevant responsive or state variants, using an available browser or capture tool. A missing desktop display alone does not rule out headless capture. For text-only CLI output, a representative terminal transcript can be sufficient. If vision is available, inspect the capture; otherwise label it visually unverified. Preserve the local artifact at any workable path, including /tmp; do not auto-commit screenshots unless project policy requires it.
|
|
125
|
-
- Hand off implementer evidence as paths plus captions plus coverage gaps: each artifact states what it shows and which variants remain unchecked. The reviewer checks that coverage against the changed surface before delivery.
|
|
126
|
-
- Publish required evidence in the PR body as an attachment or accessible artifact link with a descriptive caption, using supported authorized tooling; check the delivery tool's current help for upload support instead of relying on cached syntax. If upload is unavailable, preserve the local artifact, give its path in the handoff, and state the PR attachment limitation. Capture and upload are separate capabilities.
|
|
127
|
-
- Present evidence concisely by changed screen or behavior: label each artifact with its state and relevant viewport or theme. Use a before/after table when comparison helps and a short captioned list for a single state or when tables would shrink images. Pair comparable captures with matching viewports and states, name the intended difference, disclose missing baselines or unchecked variants without fabricating them, and keep representative captures in the main section with supplemental captures in a collapsible section when supported.
|
|
128
|
-
- Read back the actual PR body as delivery owner before claiming delivery or re-delivery; confirm attachments render or links resolve and evidence matches the current relevant diff. When a later change affects captured appearance or behavior, replace affected captures, update captions and comparisons, and remove obsolete or redundant PR body references; keep intentional clearly labeled before baselines and never present a historical before as current. Refresh only affected evidence, not every commit or unrelated file. Readback is a delivery-owner check, not a second full review.
|
|
129
|
-
- For applicable changes, report evidence captured, unavailable with the checked limitation, or unnecessary with a concrete reason. Source-only documentation edits and mechanical moves preserving rendering can use existing evidence; a refactor label or passing build alone does not establish unchanged visuals. Keep capture effort proportionate to the changed surface.
|
|
130
|
-
|
|
131
|
-
**!!! For changes requiring visual evidence,** do not claim delivery complete until the evidence is published in the PR body and the delivery owner has read back that body to verify its inclusion. Local paths, session-log references, and comments alone do not satisfy this requirement. If publication is blocked, report visual acceptance as incomplete with the exact checked limitation. An explicit user or project requirement for visual evidence remains acceptance work: provide it or report the outcome incomplete with the exact blocker. Optional PR illustration may be omitted with a reason; required evidence cannot silently become a follow-up.
|
|
124
|
+
For changes to rendered UI, including documentation sites and visible CLI output, classify visual evidence as required (changed surfaces, relevant states, expected evidence) or not applicable with a concrete reason, include the evidence requirement in implementation and review briefs, and load the available `create-pull-request` skill for the capture, handoff, publication, and readback procedure before claiming delivery. Follow the project template when one applies; stop on explicit project opt-out. Missing required evidence blocks acceptance: report it incomplete with the checked limitation, and a missing skill never waives it.
|
package/agents/planner.md
CHANGED
|
@@ -76,4 +76,4 @@ Include planned phases, assumptions, verification and rollback evidence, and the
|
|
|
76
76
|
|
|
77
77
|
## Skills
|
|
78
78
|
|
|
79
|
-
Use available skill descriptions for unresolved requirements, product discovery, issue/PRD creation, or prototyping when that work is part of the assignment. Skip skill loads for one-step plans.
|
|
79
|
+
Use available skill descriptions for unresolved requirements, product discovery, issue/PRD creation, or prototyping when that work is part of the assignment. See the available `spec-contract` skill for an optional contract header shape. Skip skill loads for one-step plans.
|
package/agents/reviewer.md
CHANGED
|
@@ -115,6 +115,10 @@ Use these categories to identify relevant risks. Cover the changed contract and
|
|
|
115
115
|
- Does the output read like a professional email to a trusted colleague?
|
|
116
116
|
- Format findings as: `style: [issue] -> [fix/dismiss]`
|
|
117
117
|
|
|
118
|
+
### 10. Spec-contract drift (optional pointer, skip when absent)
|
|
119
|
+
|
|
120
|
+
- When a spec-contract header or owning spec is linked, apply its drift, acceptance-coverage, ambiguity-tagging, delta-stating, and append-only rules; skip when absent.
|
|
121
|
+
|
|
118
122
|
## Questions to Ask Yourself
|
|
119
123
|
|
|
120
124
|
1. Is this specific code change related to the overall intended goal?
|
|
@@ -165,7 +169,7 @@ Then produce:
|
|
|
165
169
|
|
|
166
170
|
## Skills
|
|
167
171
|
|
|
168
|
-
For interface changes, use UI review guidance; for interaction or access risks, accessibility guidance; for page discovery/sharing, metadata guidance; for animation issues, motion guidance. Load `skill-judge` for skill packages. Skip unrelated loads for backend or infrastructure diffs.
|
|
172
|
+
For interface changes, use UI review guidance; for interaction or access risks, accessibility guidance; for page discovery/sharing, metadata guidance; for animation issues, motion guidance. See the available `spec-contract` skill for an optional contract header shape. Load `skill-judge` for skill packages. Skip unrelated loads for backend or infrastructure diffs.
|
|
169
173
|
|
|
170
174
|
## References
|
|
171
175
|
|
package/dist/index.js
CHANGED
|
@@ -1,2 +1,3 @@
|
|
|
1
|
-
import{memoize as e,merge as t}from"es-toolkit";import{
|
|
2
|
-
`)
|
|
1
|
+
import{memoize as e,merge as t}from"es-toolkit";import{lstatSync as n,readFileSync as r,readdirSync as i,realpathSync as a}from"node:fs";import o from"node:path";import{parse as s}from"yaml";import{z as c}from"zod";const l=[`fein`,`sonar`,`blitz`],u={blitz:`[MODE: blitz]`,fein:`[MODE: fein]`,sonar:`[MODE: sonar]`},d={blitz:1,fein:3,sonar:2},f=/```[\s\S]*?```|`[^`]*`/gu,p=e=>{let t=[],n;for(f.lastIndex=0;(n=f.exec(e))!==null;)t.push([n.index,n.index+n[0].length]);return t},m=(e,t)=>t.some(([t,n])=>e>=t&&e<n),h=e=>{let t=e.indexOf(`## MODE:`);return t===-1?`${e.replace(/\s+$/u,``)}\n`:`${e.slice(t).replace(/\s+$/u,``)}\n`},g=e=>e.replaceAll(/[.*+?^${}()|[\]\\]/gu,`\\$&`),_=e=>RegExp(`\\b${g(e)}\\b`,`giu`),v=e=>l.includes(e),y=e=>v(e)?u[e]:``,b=(e,t)=>{if(!e)return null;let n=p(e),r=t?new Set([...t].map(e=>e.toLowerCase())):void 0,i=null;for(let t of l){if(r!=null&&r.has(t))continue;let a=_(t),o;for(;(o=a.exec(e))!==null;)m(o.index,n)||(i===null||d[t]>d[i.mode])&&(i={index:o.index,keyword:o[0],mode:t})}return i},x=(e,t)=>(e.slice(0,t.index)+e.slice(t.index+t.keyword.length).replace(/^:\s*/u,``)).replaceAll(/ {2,}/gu,` `).trim(),S=import.meta.dirname,C=o.resolve(S,`..`),w=o.join(C,`agents`),ee=o.join(C,`agents`,`commands`),T=o.join(C,`rules`,`AGENTS.md`),E=e(e=>{try{return h(r(o.resolve(ee,`${e}.md`),`utf-8`))}catch(t){return console.warn(`[maestria] Failed to load mode prompt "${e}":`,t),``}}),D=new Proxy({},{get(e,t,n){return typeof t==`string`&&v(t)?E(t):Reflect.get(e,t,n)}}),O=(e,t)=>{let n=b(e,t);return n===null?null:{index:n.index,keyword:n.keyword,marker:y(n.mode),mode:n.mode,prompt:D[n.mode]}},k=(e,t)=>x(e,t),A=e=>v(e)?D[e]:``,j=e=>y(e),M=c.enum(l),N=c.object({modes:c.object({disabledKeywords:c.array(M).optional()}).optional()}),P=[`.maestria/workflow.md`,`.maestria/rules.md`],F=e=>typeof e==`string`&&e!==``,I=e=>typeof e==`object`&&!!e&&`code`in e&&e.code===`ENOENT`,L=e=>e instanceof Error&&e.message.startsWith(`[maestria] Project config`),R=(e,t)=>{if(t===`directory`)throw Error(`[maestria] Project config "${e}" is a directory, expected a file`);if(t===`other`)throw Error(`[maestria] Project config "${e}" is not a regular file`)},z=(e,t,n)=>L(n)?n:Error(`[maestria] Project config "${e}" ${t}`),te=e=>e===`/`,B=e=>{let{project:t,worktree:n,directory:r}=e;for(let e of[t?.worktree,n])if(F(e)&&!te(e))return e;if(F(r))return r},V={kindOf:e=>{try{let t=n(e);return t.isDirectory()?`directory`:t.isFile()||t.isSymbolicLink()?`file`:`other`}catch(e){if(I(e))return`missing`;throw e}},readFile:e=>r(e,`utf-8`),resolveLink:e=>a(e)},H=(e,t)=>{let n=o.relative(e,t);return n===`..`||n.startsWith(`..${o.sep}`)||o.isAbsolute(n)},U=(e,t,n)=>{let r=o.join(e,t),i;try{i=n.kindOf(r)}catch(e){throw z(t,`cannot be accessed`,e)}if(i===`missing`)return;R(t,i);let a;try{a=n.resolveLink(r)}catch(e){throw z(t,`cannot be resolved`,e)}if(H(e,a))throw Error(`[maestria] Project config "${t}" resolves outside the project root`);let s;try{s=n.kindOf(a)}catch(e){throw z(t,`cannot be accessed`,e)}if(s===`missing`)throw Error(`[maestria] Project config "${t}" cannot be accessed`);R(t,s);let c;try{c=n.readFile(r)}catch(e){throw z(t,`exists but cannot be read`,e)}if(c!==``)return{content:c,rel:t}},W=(e,t=V)=>{if(!F(e))return[];let n;try{n=a(e)}catch(t){if(!I(t))throw Error(`[maestria] Project config root cannot be accessed`);n=o.resolve(e)}let r=[];for(let e of P){let i=U(n,e,t);i!==void 0&&r.push(i)}return r},G=e=>[`Project customization from ${e.rel} (subordinate guidance: it may replace configurable workflows but never waives safety, authorization, or host permissions):`,e.content].join(`
|
|
2
|
+
`),K=e=>typeof e==`object`&&!!e&&!Array.isArray(e),q=e=>e===`all`||e===`primary`||e===`subagent`,J=e=>{if(!K(e))return{};let t={};for(let[n,r]of Object.entries(e))t[n]=r;return t},Y=e=>{let t=s(e),n=K(t)?t:{};return{color:typeof n.color==`string`?n.color:void 0,description:typeof n.description==`string`?n.description:``,maxSteps:n.maxSteps!==void 0&&n.maxSteps!==null&&n.maxSteps!==``?Number(n.maxSteps):void 0,mode:q(n.mode)?n.mode:`subagent`,permission:J(n.permission)}},X=e=>{let t=r(e,`utf-8`),n=o.basename(e,`.md`),i=t.split(`---`);if(i.length<3)throw Error(`Invalid agent file: ${e} - missing frontmatter`);let a=Y(i[1].trim()),s=i.slice(2).join(`---`).trim(),c={description:a.description,mode:a.mode,permission:a.permission,prompt:s};return a.color!==void 0&&a.color!==null&&a.color!==``&&(c.color=a.color),a.maxSteps!==void 0&&a.maxSteps!==null&&a.maxSteps!==0&&(c.maxSteps=a.maxSteps),{config:c,name:n}},Z=()=>{try{let e=i(w).filter(e=>e.endsWith(`.md`)),t={};for(let n of e)try{let{name:e,config:r}=X(o.join(w,n));t[e]=r}catch(e){console.warn(`[maestria] Failed to parse agent file "${n}":`,e)}return t}catch(e){throw console.error(`[maestria] Failed to read agents directory:`,e),Error(`[maestria] Failed to load agents from "${w}": ${e instanceof Error?e.message:String(e)}`,{cause:e})}},Q=(e,t,n)=>{if(e.agent!==`orchestrator`)return;let r=t.parts.find(e=>e.type===`text`);if(r===void 0)return;let i=O(r.text,n);i!==null&&(r.text=[j(i.mode),``,A(i.mode),``,k(r.text,i)].join(`
|
|
3
|
+
`))},ne=(e,n)=>{e.agent=t(e.agent??{},n);let r=[...e.instructions??[]];r.includes(T)||r.push(T),e.instructions=r},re=(e,t)=>{let n=W(t);for(let t of n)e.system.push(G(t))},ie=e=>{e.context.push(`Session was compacted. Task tracking is maintained via todowrite. Active context (files, decisions, blockers) was captured before compaction. Continue where you left off.`,`When project customization from .maestria/workflow.md or .maestria/rules.md is present, it is injected on every model call. Preserve the active project constraints and decisions in the summary.`)},$=async(e,t)=>{let n=N.parse(t??{}),r=new Set((n.modes?.disabledKeywords??[]).map(e=>e.toLowerCase())),i=Z(),a=B(e);return await Promise.resolve(),{"chat.message":async(e,t)=>{Q(e,t,r),await Promise.resolve()},config:async e=>{ne(e,i),await Promise.resolve()},"experimental.chat.system.transform":async(e,t)=>{a!==void 0&&re(t,a),await Promise.resolve()},"experimental.session.compacting":async(e,t)=>{ie(t),await Promise.resolve()}}};export{$ as MaestriaPlugin,$ as default};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@maestria/opencode",
|
|
3
|
-
"version": "0.7.
|
|
3
|
+
"version": "0.7.13",
|
|
4
4
|
"description": "OpenCode plugin encoding AI engineering praxis: rules, agents, and workflow discipline.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"agents",
|
|
@@ -62,6 +62,7 @@
|
|
|
62
62
|
"hooks": [
|
|
63
63
|
"config",
|
|
64
64
|
"chat.message",
|
|
65
|
+
"experimental.chat.system.transform",
|
|
65
66
|
"experimental.session.compacting"
|
|
66
67
|
]
|
|
67
68
|
},
|
package/rules/AGENTS.md
CHANGED
|
@@ -34,9 +34,8 @@ At acceptance, classify visual evidence as required (changed surfaces, relevant
|
|
|
34
34
|
|
|
35
35
|
### Documentation and changesets
|
|
36
36
|
|
|
37
|
-
-
|
|
38
|
-
-
|
|
39
|
-
- Keep the assessment proportionate to the change.
|
|
37
|
+
- Required affected docs are part of acceptance; carry them through briefs to final reconciliation.
|
|
38
|
+
- When docs work applies, load the available `docs-update` methodology skill and follow it; a missing skill never blocks ordinary docs work.
|
|
40
39
|
|
|
41
40
|
Keep file, package, and runtime scope explicit. Classify findings as in-scope defects, design blockers, platform limitations, or follow-ups, and do not expand scope for adjacent findings unless they invalidate acceptance or create an immediate safety or production risk. Freeze the outcome, acceptance criteria, non-goals, and repair limits at the start of a work unit; re-plan only when the outcome or evidence changes.
|
|
42
41
|
|
|
@@ -74,26 +73,7 @@ Merge, release, and production operations remain separate authorization boundari
|
|
|
74
73
|
|
|
75
74
|
### PR delivery contract
|
|
76
75
|
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
1. `## Summary` (what changed and why):
|
|
80
|
-
- Lead with the user-visible outcome, or the maintainer benefit for internal changes, in plain language.
|
|
81
|
-
- Keep it a short paragraph or a few concise bullets; put file-level details in Changes and check results in Verification.
|
|
82
|
-
- Omit internal execution metadata such as session IDs; write for a human reviewer.
|
|
83
|
-
2. `## Changes` (Work Results table with File, What changed, and Why columns):
|
|
84
|
-
- Describe the actual change and its practical purpose, not the editing action.
|
|
85
|
-
- Group related files that share one change and rationale; skip repeating the Summary and list only symbols that help review.
|
|
86
|
-
- Omit internal execution metadata such as session IDs; write for a human reviewer.
|
|
87
|
-
3. `## Verification` (checks run, results, and unresolved acceptance gaps)
|
|
88
|
-
- Note review outcome briefly without pasting identifiers.
|
|
89
|
-
4. `## Visual evidence` when applicable (per the visual-delivery contract)
|
|
90
|
-
5. `## Breaking changes` when applicable (migration guidance)
|
|
91
|
-
|
|
92
|
-
When the project defines an explicit template, follow it while preserving that required information.
|
|
93
|
-
|
|
94
|
-
The reviewer checks rendered coverage against the changed surface; the delivery owner reads back the published body to confirm accessible artifacts, captions, and current coverage.
|
|
95
|
-
|
|
96
|
-
After any push that changes the cumulative diff or verification evidence, update the PR title and body to match, then read back the published body before reporting delivery complete.
|
|
76
|
+
Core owns the outcome, evidence, review, and authorization floors for every reviewable PR. Title, body, and visual-evidence conventions live in the `create-pull-request` methodology skill: for an active PR task, load the available skill before drafting, and follow the project template when one applies while preserving the required information. Stop on explicit project opt-out. A missing skill never blocks delivery and never waives review or authorization; write a sensible body instead. The reviewer checks rendered coverage against the changed surface; after any push that changes diff or verification, refresh the draft and read back the published body before reporting delivery complete.
|
|
97
77
|
|
|
98
78
|
## Canonical Source Invariant
|
|
99
79
|
|