Skip to content

Commit 90da4b2

Browse files
release: v4.0.0
Major rearchitecture: 24-tool kernel replaces the fixed 8-phase pipeline. Data preconditions replace the phase state machine; emergent consensus replaces scripted voting. Adds round/decision tools, state v14/v15, manager prompt v4 rewrite, specialist tool-visibility filtering, and an uninstall script.
1 parent bafd864 commit 90da4b2

5 files changed

Lines changed: 225 additions & 2 deletions

File tree

CHANGELOG.md

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,35 @@ All notable changes to this project will be documented in this file.
55
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
66
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
77

8+
## [4.0.0] - 2026-08-03
9+
10+
A ground-up rearchitecture. The fixed 8-phase software pipeline is gone,
11+
replaced by a flexible **24-tool kernel** that lets the Manager design
12+
the workflow for any domain. Data preconditions replace the phase state
13+
machine; emergent consensus replaces scripted voting.
14+
15+
### Removed (Breaking)
16+
- **Recipe tools and phase state machine** — deleted the journey-workshop and phase-analysis subsystems, consensus voting (`mesa_votes` exported to the audit log then dropped), verification, phase gate, `define_phases`, `delegate_task`, and the entire `requirePhase`/`requireMode` guard layer with its feeding state fields (~8,200 lines removed). Rigor profiles became circuit-breaker constants.
17+
- **`deliver_briefing`** folded into `approve_briefing` (kept as a deprecated idempotent shim).
18+
- The kernel is now **16 workflow tools + 8 peripherals** per specification D5.
19+
20+
### Added
21+
- **Kernel round and decision tools**`open_round`, `close_round`, `record_decision`, `produce_deliverable`, `approve_deliverable`. Data preconditions replace phase guards: plan-approved gate via `record_decision`, completeness checked via lexical `POSITION` blocks, `disagree` vetoes `converged`, manager-registered entries excluded from declared positions, evidence paths required, override paths audited with `planVersion`. `register_analysis` now links entries to the open round.
22+
- **State v14 → v15 migrations** — additive idempotent migration backfills `rounds[]` from legacy discussion analyses (synthetic `legacy-round-1`) and `deliverables[]` from the legacy specification; audit entries gain `planVersion`; v15 recreates the analyses `UNIQUE` constraint with `round_id`.
23+
- **Manager prompt rewritten as a v4 domain-agnostic workflow designer** — the 6 Workflow Invariants floor, `workflow-plan.md` gate 0, emergent consensus (Manager decides *whether*, never *who*), a plan-reorientation ritual, and 3 contrastive exemplars (software / delegated / academic). ~5.6k tokens (was ~10.1k).
24+
- **Specialist tool-visibility filtering** — the plugin config hook injects permission deny rules derived from the live tool registry (no hardcoded list to drift). Specialists keep only their seam tools (`register_analysis`, `get_peer_analyses`, `ask_peer`, memory, `mesa_status`), saving ~5.3k tokens per specialist session. The stale `tool.definition` suffix hook was deleted in the same commit (~1.4k tokens/session).
25+
- **Generic `mesa/specialist` subagent with prompt injection** — replaces per-persona subagents.
26+
- **Inline `<specialist-persona>` block** — a primary persona resolution path for runtimes that reject non-`ses_` task IDs.
27+
- **Legacy session resume plan gate** — migrated sessions (legacy-round-1, no approved plan) get a synthesize-and-present instruction in `mesa_status` and a matching `open_round` refusal, so the workflow agreed under the old pipeline is re-approved as a plan gate, not silently adopted.
28+
- **Uninstall script**`uninstall.sh` (with `src/setup/remove-plugin.cjs` helper) removes Mesa agents, the clone, and the `opencode.json` plugin entry.
29+
30+
### Fixed
31+
- **Agent session mappings preserved across analysis rounds.**
32+
- **Inline persona blocks no longer trigger a spurious setup error** — the inline block is validated against the catalog and passed through untouched; the setup error only fires when no persona exists anywhere.
33+
34+
### Docs
35+
- README, architecture, workflow, and troubleshooting rewritten for the kernel-shell model, emergent consensus, and state v15. Pre-flexibilization design docs marked as superseded.
36+
837
## [3.6.0] - 2026-07-18
938

1039
### Added

README.md

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
> Structured AI specialist discussions for OpenCode — produce high-quality specifications through multi-agent analysis, debate, and consensus.
44
5-
![Version](https://img.shields.io/badge/version-3.6.0-blue)
5+
![Version](https://img.shields.io/badge/version-4.0.0-blue)
66
![License](https://img.shields.io/badge/license-MIT-green)
77
![Bun](https://img.shields.io/badge/runtime-Bun-f9f1e0)
88

@@ -150,6 +150,14 @@ After restarting OpenCode, verify Mesa is loaded:
150150

151151
You should see the plugin version and the current session summary (briefing, team, plan, rounds, deliverables).
152152

153+
### Uninstall
154+
155+
```bash
156+
curl -fsSL https://raw.githubusercontent.com/hacklabr/opencode-mesa/main/uninstall.sh | bash
157+
```
158+
159+
Removes the Mesa agents (`briefing-writer`, `manager`, `mesa/specialist`), the plugin entry from `opencode.json`, and the clone at `~/.local/share/opencode-mesa`. Your `opencode.json` is preserved otherwise.
160+
153161
## Usage
154162

155163
### Briefing

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "opencode-mesa",
3-
"version": "3.6.0",
3+
"version": "4.0.0",
44
"description": "OpenCode plugin for structured discussion tables with specialized AI agents",
55
"type": "module",
66
"main": "dist/index.js",

src/setup/remove-plugin.cjs

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
const fs = require('fs')
2+
3+
const configFile = process.argv[2]
4+
5+
if (!configFile) {
6+
console.error('Usage: node remove-plugin.cjs <config-file>')
7+
process.exit(1)
8+
}
9+
10+
if (!fs.existsSync(configFile)) {
11+
process.exit(0)
12+
}
13+
14+
const raw = fs.readFileSync(configFile, 'utf-8')
15+
16+
let json = raw
17+
let prev
18+
do {
19+
prev = json
20+
json = json.replace(/,\s*([}\]])/g, '$1')
21+
} while (json !== prev)
22+
23+
const cfg = JSON.parse(json)
24+
25+
if (Array.isArray(cfg.plugin)) {
26+
const before = cfg.plugin.length
27+
cfg.plugin = cfg.plugin.filter(p => typeof p === 'string' && !p.includes('opencode-mesa'))
28+
const removed = before - cfg.plugin.length
29+
30+
fs.writeFileSync(configFile, JSON.stringify(cfg, null, 2) + '\n')
31+
32+
if (removed > 0) {
33+
console.log(`Removed ${removed} plugin entry(ies) from ${configFile}`)
34+
} else {
35+
console.log(`No plugin entries found in ${configFile}`)
36+
}
37+
} else {
38+
console.log(`No plugin array in ${configFile}`)
39+
}

uninstall.sh

Lines changed: 147 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,147 @@
1+
#!/usr/bin/env bash
2+
set -euo pipefail
3+
4+
GREEN='\033[0;32m'
5+
YELLOW='\033[1;33m'
6+
RED='\033[0;31m'
7+
DIM='\033[2m'
8+
BOLD='\033[1m'
9+
NC='\033[0m'
10+
11+
info() { printf "${GREEN}[mesa]${NC} %s\n" "$1"; }
12+
warn() { printf "${YELLOW}[mesa]${NC} %s\n" "$1"; }
13+
error() { printf "${RED}[mesa]${NC} %s\n" "$1" >&2; exit 1; }
14+
dim() { printf "${DIM}[mesa]${NC} %s\n" "$1"; }
15+
16+
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
17+
18+
# ---------------------------------------------------------------------------
19+
# Detect context: are we inside the local dev repo or a clone?
20+
# ---------------------------------------------------------------------------
21+
is_local_repo() {
22+
[ -f "$SCRIPT_DIR/package.json" ] && grep -q '"opencode-mesa"' "$SCRIPT_DIR/package.json" 2>/dev/null
23+
}
24+
25+
CLONE_DIR="$HOME/.local/share/opencode-mesa"
26+
AGENTS_DIR="$HOME/.config/opencode/agents"
27+
CONFIG_DIR="$HOME/.config/opencode"
28+
CONFIG_FILE="$CONFIG_DIR/opencode.json"
29+
30+
REMOVE_HELPER=""
31+
if is_local_repo; then
32+
REMOVE_HELPER="$SCRIPT_DIR/src/setup/remove-plugin.cjs"
33+
else
34+
# Running from a clone or elsewhere — try clone location first, then local
35+
if [ -f "$CLONE_DIR/src/setup/remove-plugin.cjs" ]; then
36+
REMOVE_HELPER="$CLONE_DIR/src/setup/remove-plugin.cjs"
37+
elif [ -f "$SCRIPT_DIR/src/setup/remove-plugin.cjs" ]; then
38+
REMOVE_HELPER="$SCRIPT_DIR/src/setup/remove-plugin.cjs"
39+
fi
40+
fi
41+
42+
# ---------------------------------------------------------------------------
43+
# Collect what will be removed
44+
# ---------------------------------------------------------------------------
45+
TO_REMOVE=()
46+
47+
BRIEFING_FILE=""
48+
MANAGER_FILE=""
49+
MESA_DIR=""
50+
PLUGIN_ENTRY=false
51+
CLONE_PATH=""
52+
53+
if [ -f "$AGENTS_DIR/briefing-writer.md" ]; then
54+
BRIEFING_FILE="$AGENTS_DIR/briefing-writer.md"
55+
TO_REMOVE+=("$BRIEFING_FILE")
56+
fi
57+
58+
if [ -f "$AGENTS_DIR/manager.md" ]; then
59+
MANAGER_FILE="$AGENTS_DIR/manager.md"
60+
TO_REMOVE+=("$MANAGER_FILE")
61+
fi
62+
63+
if [ -d "$AGENTS_DIR/mesa" ]; then
64+
MESA_DIR="$AGENTS_DIR/mesa"
65+
MESA_COUNT=$(find "$MESA_DIR" -maxdepth 1 -name "*.md" 2>/dev/null | wc -l | tr -d ' ')
66+
TO_REMOVE+=("$MESA_DIR ($MESA_COUNT files)")
67+
fi
68+
69+
if [ -f "$CONFIG_FILE" ] && grep -q "opencode-mesa" "$CONFIG_FILE" 2>/dev/null; then
70+
PLUGIN_ENTRY=true
71+
TO_REMOVE+=("plugin entry in $CONFIG_FILE")
72+
fi
73+
74+
if [ -d "$CLONE_DIR" ] && ! is_local_repo; then
75+
CLONE_PATH="$CLONE_DIR"
76+
TO_REMOVE+=("$CLONE_PATH (clone)")
77+
fi
78+
79+
# ---------------------------------------------------------------------------
80+
# Nothing to do?
81+
# ---------------------------------------------------------------------------
82+
if [ ${#TO_REMOVE[@]} -eq 0 ]; then
83+
info "Nothing to uninstall — no Mesa artifacts found."
84+
exit 0
85+
fi
86+
87+
# ---------------------------------------------------------------------------
88+
# Show summary + prompt
89+
# ---------------------------------------------------------------------------
90+
printf "\n"
91+
printf "${BOLD}[mesa]${NC} This will remove:\n"
92+
for item in "${TO_REMOVE[@]}"; do
93+
printf " ${RED}-${NC} %s\n" "$item"
94+
done
95+
printf "\n"
96+
97+
read -r -p "Continue? [y/N] " response
98+
case "$response" in
99+
[yY][eE][sS]|[yY]) ;;
100+
*)
101+
info "Aborted."
102+
exit 0
103+
;;
104+
esac
105+
106+
# ---------------------------------------------------------------------------
107+
# Execute removal
108+
# ---------------------------------------------------------------------------
109+
printf "\n"
110+
111+
if [ -n "$BRIEFING_FILE" ]; then
112+
rm -f "$BRIEFING_FILE"
113+
info "Removed $BRIEFING_FILE"
114+
fi
115+
116+
if [ -n "$MANAGER_FILE" ]; then
117+
rm -f "$MANAGER_FILE"
118+
info "Removed $MANAGER_FILE"
119+
fi
120+
121+
if [ -n "$MESA_DIR" ]; then
122+
rm -rf "$MESA_DIR"
123+
info "Removed $MESA_DIR ($MESA_COUNT files)"
124+
fi
125+
126+
if $PLUGIN_ENTRY; then
127+
if [ -n "$REMOVE_HELPER" ] && [ -f "$REMOVE_HELPER" ]; then
128+
node "$REMOVE_HELPER" "$CONFIG_FILE"
129+
else
130+
# Fallback: remove via sed (best-effort, single-line plugin entries)
131+
# This handles the common case where the plugin line is a single string entry.
132+
sed -i.bak '/"file:.*opencode-mesa/d' "$CONFIG_FILE" 2>/dev/null || true
133+
sed -i.bak '/file:\/\/.*opencode-mesa/d' "$CONFIG_FILE" 2>/dev/null || true
134+
rm -f "${CONFIG_FILE}.bak" 2>/dev/null || true
135+
info "Removed plugin entry from $CONFIG_FILE (fallback sed)"
136+
warn "Config may need manual cleanup — verify $CONFIG_FILE is valid JSON"
137+
fi
138+
fi
139+
140+
if [ -n "$CLONE_PATH" ]; then
141+
rm -rf "$CLONE_PATH"
142+
info "Removed clone at $CLONE_PATH"
143+
fi
144+
145+
printf "\n"
146+
info "${BOLD}Done.${NC} Restart opencode to fully unload the plugin."
147+
info "Note: your opencode.json config was preserved (only the Mesa plugin entry was removed)."

0 commit comments

Comments
 (0)