From 37ca05bb9b84896f028b5540da9c33ccff41c3a5 Mon Sep 17 00:00:00 2001 From: iris Date: Wed, 16 Sep 2026 09:01:58 -0300 Subject: [PATCH] chore(release): v1.5.0-beta.20 --- .zenodo.json | 6 ++-- CHANGELOG.md | 11 +++++++ CITATION.cff | 8 ++--- package-lock.json | 4 +-- package.json | 2 +- plugin.json | 2 +- pyproject.toml | 2 +- src/plugins/tui/dist/tui.d.ts.map | 2 +- src/plugins/tui/dist/tui.js | 10 ++++-- src/plugins/tui/package-lock.json | 4 +-- src/plugins/tui/package.json | 2 +- src/plugins/tui/src/index.tsx | 14 ++++++++- tests/pantheon/tui-delegations.test.ts | 42 ++++++++++++++++++++++++++ 13 files changed, 90 insertions(+), 19 deletions(-) diff --git a/.zenodo.json b/.zenodo.json index 8d6a5c83..4b2857aa 100644 --- a/.zenodo.json +++ b/.zenodo.json @@ -1,18 +1,18 @@ { "title": "Pantheon", "upload_type": "software", - "description": "Pantheon v1.5.0-beta.19 is an OpenCode plugin and installer for coordinating 14 specialized agents. The repository includes reusable skills, slash-command definitions, MCP server implementations, documentation, and tests. This release records version 1.5.0-beta.19 synchronized across package.json, package-lock.json, plugin.json, pyproject.toml, and src/plugins/tui/package.json.\n\nO Pantheon v1.5.0-beta.19 é um plugin e instalador para OpenCode que coordena 14 agentes especializados. O repositório inclui skills reutilizáveis, definições de comandos slash, implementações de servidores MCP, documentação e testes. Esta release registra a versão 1.5.0-beta.19 sincronizada em package.json, package-lock.json, plugin.json, pyproject.toml e src/plugins/tui/package.json.", + "description": "Pantheon v1.5.0-beta.20 is an OpenCode plugin and installer for coordinating 14 specialized agents. The repository includes reusable skills, slash-command definitions, MCP server implementations, documentation, and tests. This release records version 1.5.0-beta.20 synchronized across package.json, package-lock.json, plugin.json, pyproject.toml, and src/plugins/tui/package.json.\n\nO Pantheon v1.5.0-beta.20 é um plugin e instalador para OpenCode que coordena 14 agentes especializados. O repositório inclui skills reutilizáveis, definições de comandos slash, implementações de servidores MCP, documentação e testes. Esta release registra a versão 1.5.0-beta.20 sincronizada em package.json, package-lock.json, plugin.json, pyproject.toml e src/plugins/tui/package.json.", "creators": [ { "name": "Igor Leite da Silva" } ], - "version": "1.5.0-beta.19", + "version": "1.5.0-beta.20", "publication_date": "2026-09-16", "license": "MIT", "language": "eng", "keywords": ["opencode", "ai-agents", "multi-agent", "orchestration", "developer-tools"], - "url": "https://github.com/ils15/pantheon-opencode/releases/tag/v1.5.0-beta.19", + "url": "https://github.com/ils15/pantheon-opencode/releases/tag/v1.5.0-beta.20", "related_identifiers": [ { "identifier": "https://github.com/ils15/pantheon-opencode", diff --git a/CHANGELOG.md b/CHANGELOG.md index c7e6a768..c463db39 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -18,6 +18,17 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/). ## ✅ Closed Issues +## [v1.5.0-beta.20] - 2026-09-16 + +<!-- Add new changes here. Running `node scripts/versioning.mjs apply` will + move this section to a versioned entry and reset the template below. --> + +## 🐞 Fixed + +- **Fixed — painel Delegations**: children com status `busy` stale (>30min sem + atualização) agora são classificadas como `completed` (não `running`). O + opencode mantém entradas `busy` no mapa de status para sessões já concluídas; + o TUI agora detecta e marca como done. ## [v1.5.0-beta.19] - 2026-09-16 <!-- Add new changes here. Running `node scripts/versioning.mjs apply` will diff --git a/CITATION.cff b/CITATION.cff index 0dbf7cde..23548964 100644 --- a/CITATION.cff +++ b/CITATION.cff @@ -2,15 +2,15 @@ cff-version: 1.2.0 message: "If you use Pantheon, please cite this software." title: "Pantheon" abstract: >- - Pantheon v1.5.0-beta.19 is an OpenCode plugin and installer for coordinating + Pantheon v1.5.0-beta.20 is an OpenCode plugin and installer for coordinating 14 specialized agents. The repository includes reusable skills, slash-command definitions, MCP server implementations, documentation, and - tests. O Pantheon v1.5.0-beta.19 é um plugin e instalador para OpenCode que + tests. O Pantheon v1.5.0-beta.20 é um plugin e instalador para OpenCode que coordena 14 agentes especializados, com skills reutilizáveis, comandos slash, servidores MCP, documentação e testes. -version: 1.5.0-beta.19 +version: 1.5.0-beta.20 date-released: 2026-09-16 -url: https://github.com/ils15/pantheon-opencode/releases/tag/v1.5.0-beta.19 +url: https://github.com/ils15/pantheon-opencode/releases/tag/v1.5.0-beta.20 doi: 10.5281/zenodo.22306637 repository-code: https://github.com/ils15/pantheon-opencode license: MIT diff --git a/package-lock.json b/package-lock.json index 7457b07a..d377b3c7 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "pantheon-opencode", - "version": "1.5.0-beta.19", + "version": "1.5.0-beta.20", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "pantheon-opencode", - "version": "1.5.0-beta.19", + "version": "1.5.0-beta.20", "hasInstallScript": true, "license": "MIT", "dependencies": { diff --git a/package.json b/package.json index 70d9554c..6b9267a1 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "pantheon-opencode", - "version": "1.5.0-beta.19", + "version": "1.5.0-beta.20", "description": "Multi-agent orchestration for OpenCode — 14 specialized agents, TDD, Themis review gates.", "type": "module", "publishConfig": { diff --git a/plugin.json b/plugin.json index c146e0ab..1c8145d8 100644 --- a/plugin.json +++ b/plugin.json @@ -1,7 +1,7 @@ { "name": "pantheon", "publisher": "ils15", - "version": "1.5.0-beta.19", + "version": "1.5.0-beta.20", "displayName": "Pantheon", "description": "Conductor-Delegate orchestration platform with 14 specialized agents, 21 skills, and OpenCode support.", "agents": "./src/agents", diff --git a/pyproject.toml b/pyproject.toml index 0991c7c7..e57f6f66 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -4,7 +4,7 @@ build-backend = "setuptools.backends._legacy:_Backend" [project] name = "pantheon" -version = "1.5.0-beta.19" +version = "1.5.0-beta.20" description = "Multi-agent orchestration framework" requires-python = ">=3.11" dependencies = [] diff --git a/src/plugins/tui/dist/tui.d.ts.map b/src/plugins/tui/dist/tui.d.ts.map index 9ef05d5f..4a2bedbd 100644 --- a/src/plugins/tui/dist/tui.d.ts.map +++ b/src/plugins/tui/dist/tui.d.ts.map @@ -1 +1 @@ -{"version":3,"file":"tui.d.ts","names":[],"sources":["../src/index.tsx"],"mappings":"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"} +{"version":3,"file":"tui.d.ts","names":[],"sources":["../src/index.tsx"],"mappings":"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"} diff --git a/src/plugins/tui/dist/tui.js b/src/plugins/tui/dist/tui.js index b561b859..9341d50c 100644 --- a/src/plugins/tui/dist/tui.js +++ b/src/plugins/tui/dist/tui.js @@ -165,7 +165,7 @@ async function detectVersion(api) { if (ver) return ver; } } catch {} - return "1.5.0-beta.19"; + return "1.5.0-beta.20"; } /** * usage-bar — AI subscription usage gauge for the opencode TUI. @@ -1489,7 +1489,13 @@ function buildChildrenPath(id) { * Pure — no I/O. */ function childStatusToState(status, time, now = Date.now(), graceMs = DELEGATION_CHILD_STATUS_GRACE_MS) { if (status === "retry") return "retry"; - if (status === "busy") return "running"; + if (status === "busy") { + if (time) { + const lastActivity = Math.max(time.updated ?? 0, time.created ?? 0); + if (lastActivity > 0 && now - lastActivity > 18e5) return "completed"; + } + return "running"; + } if (status !== void 0) return "completed"; const lastActivity = Math.max(time?.updated ?? 0, time?.created ?? 0); if (lastActivity > 0 && now - lastActivity < graceMs) return "running"; diff --git a/src/plugins/tui/package-lock.json b/src/plugins/tui/package-lock.json index 077efdb1..e034e63b 100644 --- a/src/plugins/tui/package-lock.json +++ b/src/plugins/tui/package-lock.json @@ -1,12 +1,12 @@ { "name": "pantheon-tui", - "version": "1.5.0-beta.19", + "version": "1.5.0-beta.20", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "pantheon-tui", - "version": "1.5.0-beta.19", + "version": "1.5.0-beta.20", "license": "MIT", "dependencies": { "@opencode-ai/plugin": ">=1.14.0", diff --git a/src/plugins/tui/package.json b/src/plugins/tui/package.json index 13bceadf..8a00d3f7 100644 --- a/src/plugins/tui/package.json +++ b/src/plugins/tui/package.json @@ -1,7 +1,7 @@ { "name": "pantheon-tui", "type": "module", - "version": "1.5.0-beta.19", + "version": "1.5.0-beta.20", "description": "Pantheon TUI plugin — sidebar (version, preset, sessions, real-time delegations) + AI subscription usage gauges incl. OpenCode Go/Zen dollar limits (vendored, MIT)", "license": "MIT", "exports": { diff --git a/src/plugins/tui/src/index.tsx b/src/plugins/tui/src/index.tsx index a6d87b1c..cfb31c19 100644 --- a/src/plugins/tui/src/index.tsx +++ b/src/plugins/tui/src/index.tsx @@ -2185,7 +2185,19 @@ export function childStatusToState( graceMs = DELEGATION_CHILD_STATUS_GRACE_MS, ): 'running' | 'completed' | 'retry' { if (status === 'retry') return 'retry' - if (status === 'busy') return 'running' + if (status === 'busy') { + // A stale "busy" in the status map means the child is likely dead, not + // running. The opencode status map may retain entries for sessions that + // have already terminated. Cross-check against the child's own activity + // timestamps: if the last activity is older than the stale-running + // threshold, treat the child as completed rather than propagating the + // stale busy status as "running" (the "213 children, all active" bug). + if (time) { + const lastActivity = Math.max(time.updated ?? 0, time.created ?? 0) + if (lastActivity > 0 && now - lastActivity > STALE_RUNNING_THRESHOLD_MS) return 'completed' + } + return 'running' + } if (status !== undefined) return 'completed' // idle + any other explicit terminal // Absent status: running only while the child's last activity is fresh. const lastActivity = Math.max(time?.updated ?? 0, time?.created ?? 0) diff --git a/tests/pantheon/tui-delegations.test.ts b/tests/pantheon/tui-delegations.test.ts index b0f35ab4..5b421030 100644 --- a/tests/pantheon/tui-delegations.test.ts +++ b/tests/pantheon/tui-delegations.test.ts @@ -932,6 +932,48 @@ async function main() { 'completed', 'grace window is injectable (0 = always terminal)', ) + + // Stale "busy" in the status map: a "busy" child whose last activity is + // older than STALE_RUNNING_THRESHOLD_MS is likely dead — the status map + // retained a stale entry. Treat as completed, not running. + const STALE = 30 * 60 * 1000 + const tNow = STALE + 60_000 // enough headroom so (tNow - STALE - 1) is positive + assert.equal( + childStatusToState('busy', { created: tNow - STALE - 1 }, tNow), + 'completed', + 'stale "busy" (created past threshold) → completed', + ) + assert.equal( + childStatusToState('busy', { updated: tNow - STALE - 1 }, tNow), + 'completed', + 'stale "busy" (updated past threshold) → completed', + ) + assert.equal( + childStatusToState('busy', { created: tNow - 10_000 }, tNow), + 'running', + 'recent "busy" (within threshold) → running', + ) + assert.equal( + childStatusToState('busy', { created: tNow - 10_000, updated: tNow - STALE - 1 }, tNow), + 'running', + '"busy" with recent created + stale updated → running (max picks most recent)', + ) + assert.equal( + childStatusToState('busy', { created: tNow - STALE - 1, updated: tNow - 10_000 }, tNow), + 'running', + '"busy" with stale created + recent updated → running (max picks most recent)', + ) + assert.equal( + childStatusToState('busy', { created: tNow - STALE - 1, updated: tNow - STALE - 1 }, tNow), + 'completed', + '"busy" with both stale → completed', + ) + // Without time info, trust the status map (can't determine staleness). + assert.equal( + childStatusToState('busy'), + 'running', + '"busy" without time → running (trust status map)', + ) }, )