+
+
+ TUI
+
+
+
+
+
+
+
+
+ handleNestedChange('tui', 'showLoops', checked)}
+ />
+
+
+
+
+ handleNestedChange('tui', 'showVersion', checked)}
+ />
+
+
{displayConfig.dataDir && (
diff --git a/packages/memory/config.jsonc b/packages/memory/config.jsonc
index d456c9ee..1927a633 100644
--- a/packages/memory/config.jsonc
+++ b/packages/memory/config.jsonc
@@ -36,5 +36,10 @@
"model": "",
"minAudits": 1,
"stallTimeoutMs": 60000
+ },
+ "tui": {
+ "sidebar": true,
+ "showLoops": true,
+ "showVersion": true
}
}
diff --git a/packages/memory/scripts/build.ts b/packages/memory/scripts/build.ts
new file mode 100644
index 00000000..a0bb37bf
--- /dev/null
+++ b/packages/memory/scripts/build.ts
@@ -0,0 +1,29 @@
+import { readFileSync, writeFileSync } from 'fs'
+import { join } from 'path'
+import { execSync } from 'child_process'
+
+const packageJsonPath = join(__dirname, '..', 'package.json')
+const versionPath = join(__dirname, '..', 'src', 'version.ts')
+
+const packageJson = JSON.parse(readFileSync(packageJsonPath, 'utf-8'))
+const version = packageJson.version as string
+
+const versionContent = `export const VERSION = '${version}'\n`
+
+writeFileSync(versionPath, versionContent, 'utf-8')
+
+console.log(`Version ${version} written to src/version.ts`)
+
+console.log('Compiling main code...')
+execSync('tsc -p tsconfig.build.json', {
+ cwd: join(__dirname, '..'),
+ stdio: 'inherit'
+})
+
+console.log('Compiling TUI plugin...')
+execSync('bun build src/tui.tsx --outdir dist --target node --external "@opentui/solid" --external "@opencode-ai/plugin/tui" --external "solid-js"', {
+ cwd: join(__dirname, '..'),
+ stdio: 'inherit'
+})
+
+console.log('Build complete!')
diff --git a/packages/memory/src/setup.ts b/packages/memory/src/setup.ts
index 431751ce..f0cb6ae9 100644
--- a/packages/memory/src/setup.ts
+++ b/packages/memory/src/setup.ts
@@ -139,6 +139,7 @@ function normalizeConfig(config: PluginConfig): PluginConfig {
executionModel: config.executionModel,
auditorModel: config.auditorModel,
loop: config.loop ?? config.ralph,
+ tui: config.tui,
}
if (config.ralph && !config.loop) {
diff --git a/packages/memory/src/tui.tsx b/packages/memory/src/tui.tsx
new file mode 100644
index 00000000..eb4845ca
--- /dev/null
+++ b/packages/memory/src/tui.tsx
@@ -0,0 +1,158 @@
+/** @jsxImportSource @opentui/solid */
+import type { TuiPlugin, TuiPluginApi, TuiPluginModule } from '@opencode-ai/plugin/tui'
+import { createMemo, createSignal, onCleanup, Show, For } from 'solid-js'
+import { VERSION } from './version'
+import { compareVersions } from './utils/upgrade'
+import { loadPluginConfig } from './setup'
+
+type TuiOptions = {
+ sidebar: boolean
+ showLoops: boolean
+ showVersion: boolean
+}
+
+type LoopInfo = {
+ name: string
+ phase: string
+ iteration: number
+ maxIterations: number
+ sessionId: string
+ status: string
+}
+
+function Sidebar(props: { api: TuiPluginApi; opts: TuiOptions }) {
+ const [open, setOpen] = createSignal(true)
+ const [loops, setLoops] = createSignal