pantheon-opencode 1.5.0-beta.17 → 1.5.0-beta.18

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/CHANGELOG.md CHANGED
@@ -18,6 +18,26 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/).
18
18
 
19
19
  ## ✅ Closed Issues
20
20
 
21
+ ## [v1.5.0-beta.18] - 2026-09-16
22
+
23
+ <!-- Add new changes here. Running `node scripts/versioning.mjs apply` will
24
+ move this section to a versioned entry and reset the template below. -->
25
+
26
+ ## 🐞 Fixed
27
+
28
+ - **Painel Delegations voltou a funcionar (crítico):** o canal
29
+ `session.children` da TUI chamava a API com a shape v1 (`{ path: { id } }`)
30
+ num cliente **v2** que espera `{ sessionID }`; o placeholder não era
31
+ substituído (`/session/%7BsessionID%7D/children`), o host rejeitava cada
32
+ poll (~181k erros/s) e o painel ficava vazio ("No delegations"). Corrigido
33
+ `safeSessionPath`/`buildChildrenPath` para `{ sessionID }`, removidos os
34
+ `as any` que escondiam o mismatch, + teste de regressão exato. Auditoria
35
+ confirmou que só a TUI (v2) estava errada (o `plugin.ts` usa SDK v1 de
36
+ propósito).
37
+ - **Higiene de testes:** testes que importam o plugin sem isolamento agora
38
+ fazem `chdir` para um projeto temporário antes do import — não criam mais
39
+ entradas no board real (fim dos estados fantasma em desenvolvimento).
40
+
21
41
  ## [v1.5.0-beta.17] - 2026-09-15
22
42
 
23
43
  <!-- Add new changes here. Running `node scripts/versioning.mjs apply` will
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pantheon-opencode",
3
- "version": "1.5.0-beta.17",
3
+ "version": "1.5.0-beta.18",
4
4
  "description": "Multi-agent orchestration for OpenCode — 14 specialized agents, TDD, Themis review gates.",
5
5
  "type": "module",
6
6
  "publishConfig": {
package/plugin.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "pantheon",
3
3
  "publisher": "ils15",
4
- "version": "1.5.0-beta.17",
4
+ "version": "1.5.0-beta.18",
5
5
  "displayName": "Pantheon",
6
6
  "description": "Conductor-Delegate orchestration platform with 14 specialized agents, 21 skills, and OpenCode support.",
7
7
  "agents": "./src/agents",
package/pyproject.toml CHANGED
@@ -4,7 +4,7 @@ build-backend = "setuptools.backends._legacy:_Backend"
4
4
 
5
5
  [project]
6
6
  name = "pantheon"
7
- version = "1.5.0-beta.17"
7
+ version = "1.5.0-beta.18"
8
8
  description = "Multi-agent orchestration framework"
9
9
  requires-python = ">=3.11"
10
10
  dependencies = []
@@ -326,25 +326,26 @@ type TuiSessionSources = {
326
326
  * fetch (empty panel, zero errors). Pure — no I/O, no runtime required. */
327
327
  declare function resolveCurrentSessionID(sources: TuiSessionSources): string | null;
328
328
  /** THE single choke point for every `session.children` / session-API path.
329
- * Returns `{ path: { id } }` ONLY for a server-valid session id; returns
330
- * null for anything else (placeholder, empty, foreign id) so the caller
331
- * skips the call entirely instead of sending an unsubstituted placeholder
332
- * (the "%7BsessionID%7D" regression). Every session-API call site MUST go
333
- * through this function (enforced by the source-scan test in
334
- * tests/pantheon/tui-delegations.test.ts). */
329
+ * Returns the v2 SDK parameter shape `{ sessionID }` ONLY for a
330
+ * server-valid session id; returns null for anything else (placeholder,
331
+ * empty, foreign id) so the caller skips the call entirely instead of
332
+ * sending an unsubstituted placeholder (the "%7BsessionID%7D" regression).
333
+ * The TUI client is `@opencode-ai/sdk/v2`, whose session methods take a
334
+ * FLAT parameter object (`{ sessionID }`), NOT the v1 `{ path: { id } }`
335
+ * envelope — passing the v1 shape left the v2 `{sessionID}` URL template
336
+ * unsubstituted (`/session/%7BsessionID%7D/children`). Every session-API
337
+ * call site MUST go through this function (enforced by the source-scan
338
+ * test in tests/pantheon/tui-delegations.test.ts). */
335
339
  declare function safeSessionPath(id: unknown): {
336
- path: {
337
- id: string;
338
- };
340
+ sessionID: string;
339
341
  } | null;
340
- /** Build the `session.children` path ONLY from a validated session id.
342
+ /** Build the `session.children` parameters ONLY from a validated session id.
341
343
  * Delegates to {@link safeSessionPath} — the single choke point. Returns
342
- * null for null/invalid ids so the caller skips the fetch instead of
343
- * sending an unsubstituted placeholder (the "%7BsessionID%7D" regression). */
344
+ * the v2 SDK shape `{ sessionID }`; null for null/invalid ids so the caller
345
+ * skips the fetch instead of sending an unsubstituted placeholder (the
346
+ * "%7BsessionID%7D" regression). */
344
347
  declare function buildChildrenPath(id: string | null | undefined): {
345
- path: {
346
- id: string;
347
- };
348
+ sessionID: string;
348
349
  } | null;
349
350
  /** Duck-typed subset of a child Session (+ its live status type). */
350
351
  type ChildDelegationLike = {
@@ -1 +1 @@
1
- {"version":3,"file":"tui.d.ts","names":[],"sources":["../src/index.tsx"],"mappings":"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"}
1
+ {"version":3,"file":"tui.d.ts","names":[],"sources":["../src/index.tsx"],"mappings":"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"}
@@ -165,7 +165,7 @@ async function detectVersion(api) {
165
165
  if (ver) return ver;
166
166
  }
167
167
  } catch {}
168
- return "1.5.0-beta.17";
168
+ return "1.5.0-beta.18";
169
169
  }
170
170
  /**
171
171
  * usage-bar — AI subscription usage gauge for the opencode TUI.
@@ -1428,20 +1428,25 @@ function resolveCurrentSessionID(sources) {
1428
1428
  return null;
1429
1429
  }
1430
1430
  /** THE single choke point for every `session.children` / session-API path.
1431
- * Returns `{ path: { id } }` ONLY for a server-valid session id; returns
1432
- * null for anything else (placeholder, empty, foreign id) so the caller
1433
- * skips the call entirely instead of sending an unsubstituted placeholder
1434
- * (the "%7BsessionID%7D" regression). Every session-API call site MUST go
1435
- * through this function (enforced by the source-scan test in
1436
- * tests/pantheon/tui-delegations.test.ts). */
1431
+ * Returns the v2 SDK parameter shape `{ sessionID }` ONLY for a
1432
+ * server-valid session id; returns null for anything else (placeholder,
1433
+ * empty, foreign id) so the caller skips the call entirely instead of
1434
+ * sending an unsubstituted placeholder (the "%7BsessionID%7D" regression).
1435
+ * The TUI client is `@opencode-ai/sdk/v2`, whose session methods take a
1436
+ * FLAT parameter object (`{ sessionID }`), NOT the v1 `{ path: { id } }`
1437
+ * envelope — passing the v1 shape left the v2 `{sessionID}` URL template
1438
+ * unsubstituted (`/session/%7BsessionID%7D/children`). Every session-API
1439
+ * call site MUST go through this function (enforced by the source-scan
1440
+ * test in tests/pantheon/tui-delegations.test.ts). */
1437
1441
  function safeSessionPath(id) {
1438
1442
  if (!isValidSessionId(id)) return null;
1439
- return { path: { id } };
1443
+ return { sessionID: id };
1440
1444
  }
1441
- /** Build the `session.children` path ONLY from a validated session id.
1445
+ /** Build the `session.children` parameters ONLY from a validated session id.
1442
1446
  * Delegates to {@link safeSessionPath} — the single choke point. Returns
1443
- * null for null/invalid ids so the caller skips the fetch instead of
1444
- * sending an unsubstituted placeholder (the "%7BsessionID%7D" regression). */
1447
+ * the v2 SDK shape `{ sessionID }`; null for null/invalid ids so the caller
1448
+ * skips the fetch instead of sending an unsubstituted placeholder (the
1449
+ * "%7BsessionID%7D" regression). */
1445
1450
  function buildChildrenPath(id) {
1446
1451
  return safeSessionPath(id);
1447
1452
  }
@@ -1898,7 +1903,8 @@ function View(props) {
1898
1903
  }
1899
1904
  let children = [];
1900
1905
  try {
1901
- const result = await props.api.client?.session?.children?.(buildChildrenPath(sessionID));
1906
+ const childrenPath = buildChildrenPath(sessionID);
1907
+ const result = childrenPath ? await props.api.client.session.children(childrenPath) : void 0;
1902
1908
  const data = result?.data ?? result;
1903
1909
  children = Array.isArray(data) ? data : [];
1904
1910
  } catch (err) {
@@ -1908,7 +1914,7 @@ function View(props) {
1908
1914
  const resolveStatus = (childID) => {
1909
1915
  if (!isValidSessionId(childID)) return void 0;
1910
1916
  try {
1911
- return state?.session?.status?.(childID)?.type;
1917
+ return state.session.status(childID)?.type;
1912
1918
  } catch {
1913
1919
  return;
1914
1920
  }
@@ -1,12 +1,12 @@
1
1
  {
2
2
  "name": "pantheon-tui",
3
- "version": "1.5.0-beta.17",
3
+ "version": "1.5.0-beta.18",
4
4
  "lockfileVersion": 3,
5
5
  "requires": true,
6
6
  "packages": {
7
7
  "": {
8
8
  "name": "pantheon-tui",
9
- "version": "1.5.0-beta.17",
9
+ "version": "1.5.0-beta.18",
10
10
  "license": "MIT",
11
11
  "dependencies": {
12
12
  "@opencode-ai/plugin": ">=1.14.0",
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "pantheon-tui",
3
3
  "type": "module",
4
- "version": "1.5.0-beta.17",
4
+ "version": "1.5.0-beta.18",
5
5
  "description": "Pantheon TUI plugin — sidebar (version, preset, sessions, real-time delegations) + AI subscription usage gauges incl. OpenCode Go/Zen dollar limits (vendored, MIT)",
6
6
  "license": "MIT",
7
7
  "exports": {
@@ -2034,7 +2034,7 @@ export function filterDelegationsToSession(
2034
2034
 
2035
2035
  /* ─── Current-session resolution + path guard (placeholder regression) ──
2036
2036
  * The sidebar forwarded `props.session_id` verbatim into
2037
- * `session.children({ path: { id } })`. When the TUI runtime renders the
2037
+ * `session.children({ sessionID })`. When the TUI runtime renders the
2038
2038
  * sidebar without a focused session it leaves the route template
2039
2039
  * UNSUBSTITUTED — the literal "{sessionID}" string — which opencode's server
2040
2040
  * rejected every poll (SchemaError: Expected a string starting with "ses",
@@ -2098,22 +2098,27 @@ export function resolveCurrentSessionID(sources: TuiSessionSources): string | nu
2098
2098
  }
2099
2099
 
2100
2100
  /** THE single choke point for every `session.children` / session-API path.
2101
- * Returns `{ path: { id } }` ONLY for a server-valid session id; returns
2102
- * null for anything else (placeholder, empty, foreign id) so the caller
2103
- * skips the call entirely instead of sending an unsubstituted placeholder
2104
- * (the "%7BsessionID%7D" regression). Every session-API call site MUST go
2105
- * through this function (enforced by the source-scan test in
2106
- * tests/pantheon/tui-delegations.test.ts). */
2107
- export function safeSessionPath(id: unknown): { path: { id: string } } | null {
2101
+ * Returns the v2 SDK parameter shape `{ sessionID }` ONLY for a
2102
+ * server-valid session id; returns null for anything else (placeholder,
2103
+ * empty, foreign id) so the caller skips the call entirely instead of
2104
+ * sending an unsubstituted placeholder (the "%7BsessionID%7D" regression).
2105
+ * The TUI client is `@opencode-ai/sdk/v2`, whose session methods take a
2106
+ * FLAT parameter object (`{ sessionID }`), NOT the v1 `{ path: { id } }`
2107
+ * envelope — passing the v1 shape left the v2 `{sessionID}` URL template
2108
+ * unsubstituted (`/session/%7BsessionID%7D/children`). Every session-API
2109
+ * call site MUST go through this function (enforced by the source-scan
2110
+ * test in tests/pantheon/tui-delegations.test.ts). */
2111
+ export function safeSessionPath(id: unknown): { sessionID: string } | null {
2108
2112
  if (!isValidSessionId(id)) return null
2109
- return { path: { id } }
2113
+ return { sessionID: id }
2110
2114
  }
2111
2115
 
2112
- /** Build the `session.children` path ONLY from a validated session id.
2116
+ /** Build the `session.children` parameters ONLY from a validated session id.
2113
2117
  * Delegates to {@link safeSessionPath} — the single choke point. Returns
2114
- * null for null/invalid ids so the caller skips the fetch instead of
2115
- * sending an unsubstituted placeholder (the "%7BsessionID%7D" regression). */
2116
- export function buildChildrenPath(id: string | null | undefined): { path: { id: string } } | null {
2118
+ * the v2 SDK shape `{ sessionID }`; null for null/invalid ids so the caller
2119
+ * skips the fetch instead of sending an unsubstituted placeholder (the
2120
+ * "%7BsessionID%7D" regression). */
2121
+ export function buildChildrenPath(id: string | null | undefined): { sessionID: string } | null {
2117
2122
  return safeSessionPath(id)
2118
2123
  }
2119
2124
 
@@ -2786,7 +2791,9 @@ function View(props: {
2786
2791
  if (delegationsInflight !== null) return delegationsInflight
2787
2792
  delegationsInflight = (async () => {
2788
2793
  try {
2789
- const state = props.api.state as any
2794
+ // Typed (no `as any`): TuiState.session.status is a v2 sync accessor
2795
+ // taking the session id directly — same shape as the client call.
2796
+ const state = props.api.state
2790
2797
  // 0. md reports from EVERY session under .pantheon/delegations — the
2791
2798
  // ENRICHMENT channel. Read unfiltered (taskID match supplies alias/
2792
2799
  // agent/description/terminal state); the active-session filter after
@@ -2817,13 +2824,18 @@ function View(props: {
2817
2824
  return
2818
2825
  }
2819
2826
  // 2. children — PRIMARY source (SDK: api.client.session.children).
2827
+ // v2 SDK: `children` takes a FLAT `{ sessionID }` parameter object.
2828
+ // The v1 `{ path: { id } }` envelope is NOT understood by the v2
2829
+ // client — it left the URL template unsubstituted and the server
2830
+ // rejected every poll ("%7BsessionID%7D" regression).
2820
2831
  let children: ChildDelegationLike[] = []
2821
2832
  try {
2822
2833
  // buildChildrenPath re-validates: with sessionID !== null it is
2823
2834
  // never null, so no placeholder can reach the wire.
2824
- const result = await (props.api.client as any)?.session?.children?.(
2825
- buildChildrenPath(sessionID),
2826
- )
2835
+ const childrenPath = buildChildrenPath(sessionID)
2836
+ const result = childrenPath
2837
+ ? await props.api.client.session.children(childrenPath)
2838
+ : undefined
2827
2839
  const data = (result?.data ?? result) as unknown
2828
2840
  children = Array.isArray(data) ? (data as ChildDelegationLike[]) : []
2829
2841
  } catch (err) {
@@ -2837,7 +2849,7 @@ function View(props: {
2837
2849
  // path — "%7BsessionID%7D").
2838
2850
  if (!isValidSessionId(childID)) return undefined
2839
2851
  try {
2840
- return state?.session?.status?.(childID)?.type as string | undefined
2852
+ return state.session.status(childID)?.type
2841
2853
  } catch {
2842
2854
  return undefined // status API unavailable — child state fallback
2843
2855
  }