pantheon-opencode 1.6.0-beta.8 → 1.6.0-beta.9

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.
@@ -1,19 +1,23 @@
1
1
  {
2
2
  "name": "pantheon-tui",
3
3
  "type": "module",
4
- "version": "1.6.0-beta.8",
5
- "description": "Pantheon TUI plugin — sidebar (version, preset, sessions, real-time delegations) + AI subscription usage gauges incl. OpenCode Go/Zen dollar limits (vendored, MIT)",
4
+ "version": "1.6.0-beta.9",
5
+ "description": "Pantheon TUI plugin — V1 rich sidebar and usage gauges; native V2 status, session and delegation sidebar",
6
6
  "license": "MIT",
7
7
  "engines": {
8
8
  "node": "^22.22.2 || ^24.15.0 || >=26.0.0"
9
9
  },
10
10
  "exports": {
11
11
  "./tui": "./dist/tui.js",
12
+ "./tui-v2": "./dist/tui-v2.js",
12
13
  "./server": "./dist/server.js"
13
14
  },
14
15
  "files": [
15
16
  "dist",
16
- "src"
17
+ "src",
18
+ "tui.ts",
19
+ "tui-v2.ts",
20
+ "index-v2.ts"
17
21
  ],
18
22
  "scripts": {
19
23
  "build": "tsdown",
@@ -22,8 +26,6 @@
22
26
  "peerDependencies": {
23
27
  "@opencode-ai/plugin": "1.18.33",
24
28
  "@opencode-ai/sdk": "1.18.33",
25
- "@opentui/core": "0.5.10",
26
- "@opentui/solid": "0.5.10",
27
29
  "solid-js": "1.9.12"
28
30
  },
29
31
  "devDependencies": {
@@ -39,8 +41,9 @@
39
41
  "//overrides": "TUI production advisory fixes: Babel >=7.29.6 and Seroval >=1.6.3; Solid stays at 1.9.12 to satisfy OpenTUI's exact peer. Remove only after upstream ranges include fixed versions; Seroval compatibility is covered by the Solid serializer regression test.",
40
42
  "dependencies": {
41
43
  "@opencode-ai/plugin": "1.18.33",
42
- "@opentui/core": "0.5.10",
43
- "@opentui/solid": "0.5.10",
44
+ "@opencode/plugin": "2.0.26",
45
+ "@opentui/core": "0.5.17",
46
+ "@opentui/solid": "0.5.17",
44
47
  "solid-js": "1.9.12"
45
48
  }
46
49
  }
@@ -0,0 +1,108 @@
1
+ // biome-ignore-all lint/suspicious/noExplicitAny: OpenCode V2 exposes its TUI API at runtime.
2
+ /** @jsxImportSource @opentui/solid */
3
+
4
+ import { Plugin } from '@opencode/plugin/tui'
5
+ import { createMemo, createSignal, For, onCleanup, onMount, Show } from 'solid-js'
6
+
7
+ const SINGLETON = Symbol.for('pantheon.tui.v2.loaded')
8
+
9
+ function Sidebar(props: { context: any; sessionID?: string }) {
10
+ const { context } = props
11
+ const [revision, setRevision] = createSignal(0)
12
+ const location = context.location ?? context.data.location.default()
13
+
14
+ const session = createMemo(() => {
15
+ revision()
16
+ return props.sessionID ? context.data.session.get(props.sessionID) : undefined
17
+ })
18
+ const branch = createMemo(() => {
19
+ revision()
20
+ const info = context.data.location.vcs.info(location)
21
+ return info?.branch?.current ?? null
22
+ })
23
+ const delegations = createMemo(() => {
24
+ revision()
25
+ const id = props.sessionID
26
+ if (!id) return []
27
+ const family: string[] = context.data.session.family(id) ?? []
28
+ return family
29
+ .filter((childID) => childID !== id)
30
+ .map((childID) => context.data.session.get(childID))
31
+ .filter((child: any) => child?.parentID === id)
32
+ .slice(0, 6)
33
+ })
34
+
35
+ onMount(() => {
36
+ const stop: Array<() => void> = []
37
+ for (const type of [
38
+ 'session.created',
39
+ 'session.updated',
40
+ 'session.status',
41
+ 'session.deleted',
42
+ ]) {
43
+ try {
44
+ stop.push(context.data.on(type, () => setRevision((value) => value + 1)))
45
+ } catch {
46
+ // Sidebar remains useful with the initial cached state if an event is unavailable.
47
+ }
48
+ }
49
+ if (props.sessionID) {
50
+ void context.data.session.sync(props.sessionID).then(() => setRevision((value) => value + 1))
51
+ }
52
+ void context.data.location.vcs.sync(location).then(() => setRevision((value) => value + 1))
53
+ onCleanup(() => {
54
+ for (const unsubscribe of stop) unsubscribe()
55
+ })
56
+ })
57
+
58
+ const text = () => context.theme.text?.base
59
+ const muted = () => context.theme.text?.muted ?? text()
60
+
61
+ return (
62
+ <box flexDirection="column" width="100%" padding={1}>
63
+ <text fg={text()} attributes={1}>{`Pantheon v${__PANTHEON_VERSION__}`}</text>
64
+ <text fg={muted()}>OpenCode V2 · plugin TUI ativo</text>
65
+ <Show when={branch()}>{(value) => <text fg={muted()}>{`Branch: ${value()}`}</text>}</Show>
66
+ <Show when={session()} fallback={<text fg={muted()}>Nenhuma sessão selecionada</text>}>
67
+ {(current) => (
68
+ <>
69
+ <text fg={text()}>{`Sessão: ${current().title || current().id}`}</text>
70
+ <Show when={current().agent}>
71
+ <text fg={muted()}>{`Agente: ${current().agent}`}</text>
72
+ </Show>
73
+ </>
74
+ )}
75
+ </Show>
76
+ <Show when={delegations().length > 0}>
77
+ <text fg={text()} attributes={1}>
78
+ Delegações
79
+ </text>
80
+ <For each={delegations()}>
81
+ {(child: any) => <text fg={muted()}>{`· ${child.title || child.id}`}</text>}
82
+ </For>
83
+ </Show>
84
+ </box>
85
+ )
86
+ }
87
+
88
+ const plugin = Plugin.define({
89
+ id: 'pantheon.tui',
90
+ setup(context: any) {
91
+ const globalState = globalThis as unknown as Record<PropertyKey, unknown>
92
+ if (globalState[SINGLETON]) return
93
+ globalState[SINGLETON] = true
94
+
95
+ const unregister = context.ui.slot({
96
+ append: 'sidebar.content',
97
+ render: ({ sessionID }: { sessionID?: string }) => (
98
+ <Sidebar context={context} sessionID={sessionID} />
99
+ ),
100
+ })
101
+ return () => {
102
+ if (typeof unregister === 'function') unregister()
103
+ delete globalState[SINGLETON]
104
+ }
105
+ },
106
+ })
107
+
108
+ export default plugin
@@ -5,9 +5,9 @@
5
5
  /**
6
6
  * pantheon-tui — Pantheon TUI plugin for opencode.
7
7
  *
8
- * Bundled entry: `tsdown` emits `dist/tui.js`, and the package `exports`
9
- * (`./tui` → ./dist/tui.js, `./server` → ./dist/server.js) is the ONLY load
10
- * path — no raw TSX copy is shipped. Because the bundle inlines relative
8
+ * V1 bundle: `tsdown` emits `dist/tui.js`, re-exported by root `tui.ts`.
9
+ * OpenCode V2 uses the separate `src/index-v2.tsx` entry and native CLI plugin
10
+ * API. No raw TSX implementation is shipped. Because the bundle inlines relative
11
11
  * imports, this entry may be split into modules without breaking the loader.
12
12
  *
13
13
  * Slots:
@@ -0,0 +1,13 @@
1
+ declare module '@opencode/plugin/tui' {
2
+ export const Plugin: {
3
+ define<T>(plugin: T): T
4
+ }
5
+ }
6
+
7
+ declare module '@opencode/plugin' {
8
+ export const Plugin: {
9
+ define<T>(plugin: T): T
10
+ }
11
+ }
12
+
13
+ declare const __PANTHEON_VERSION__: string
@@ -26,7 +26,7 @@ async function ensureDistArtifactsEndWithNewline(): Promise<void> {
26
26
  }
27
27
 
28
28
  export default defineConfig({
29
- entry: { tui: 'src/index.tsx', server: 'src/server.ts' },
29
+ entry: { tui: 'src/index.tsx', 'tui-v2': 'src/index-v2.tsx', server: 'src/server.ts' },
30
30
  format: ['esm'],
31
31
  platform: 'node',
32
32
  outDir: 'dist',
@@ -47,7 +47,7 @@ export default defineConfig({
47
47
  }),
48
48
  ],
49
49
  deps: {
50
- neverBundle: [/^@opencode-ai\//, /^@opentui\//, /^solid-js/],
50
+ neverBundle: [/^@opencode-ai\//, /^@opencode\//, /^@opentui\//, /^solid-js/],
51
51
  },
52
52
  onSuccess: ensureDistArtifactsEndWithNewline,
53
53
  })
@@ -0,0 +1,2 @@
1
+ // OpenCode V2's CLI loader resolves this root-level TUI entrypoint.
2
+ export { default } from './dist/tui-v2.js'
@@ -0,0 +1,3 @@
1
+ // OpenCode V1 compatibility entrypoint. The V2 installer copies tui-v2.ts as
2
+ // the installed root tui.ts instead.
3
+ export { default } from './dist/tui.js'
@@ -14,10 +14,10 @@ Use this skill to pin a session objective at the start of a long or complex sess
14
14
 
15
15
  ## Usage
16
16
 
17
- Invoke via the `/focus` command:
17
+ Invoke via the `/pantheon-focus` command (a conversation-only goal anchor):
18
18
 
19
19
  ```
20
- /focus Implement JWT authentication with refresh token rotation
20
+ /pantheon-focus Implement JWT authentication with refresh token rotation
21
21
  ```
22
22
 
23
23
  Or state it explicitly at the start of a session:
@@ -70,9 +70,18 @@ Before each major delegation or decision, run this quick check:
70
70
 
71
71
  ---
72
72
 
73
- ## Cross-Session Persistence
73
+ ## Cross-Session Continuity
74
74
 
75
- For goals that span multiple sessions, write the goal to `/memories/session/`:
75
+ V2 does not provide durable goal tools. `/pantheon-focus` only anchors the current
76
+ conversation and must not be described as surviving compaction or a new
77
+ session. For multi-phase work that needs persistent checkpoints, use
78
+ `/pantheon-deepwork`; otherwise ask before writing a goal to a project file.
79
+
80
+ In V1, use the implemented goal tools when they are available and explicitly
81
+ authorized. Do not infer that their presence in one host generation means they
82
+ exist in V2.
83
+
84
+ Historical path example (not a V2 runtime command):
76
85
 
77
86
  ```
78
87
  /memories/session/current-goal.md
@@ -84,7 +93,7 @@ Status: Phase 2 of 3 (backend done, frontend in progress)
84
93
  Next: POST /auth/refresh endpoint
85
94
  ```
86
95
 
87
- This ensures the goal survives context compaction and session restarts.
96
+ This file-based approach requires explicit authorization and is not automatic.
88
97
 
89
98
  ---
90
99